Compare commits

...

101 Commits
main ... GST006

Author SHA1 Message Date
王家东 f1ed5ca34d 前端修改 2 weeks ago
Ly 2b0bfc4af4 队员和指导老师的Dialog关闭 2 months ago
Ly 21e06cb0a5 校验队长的唯一性 2 months ago
Ly b20944f3e0 格式校验 2 months ago
Ly 6530b54e03 空白待填行问题 2 months ago
Ly ab0e8b589f 取消报名改为返回 2 months ago
Ly 9061c2b802 消息提示语 2 months ago
Ly 42b1a71d05 暂存按钮的消息提示 2 months ago
Ly ca4e7d3be2 个人赛更改比赛项目信息 2 months ago
Ly d66fa16190 暂存信息 2 months ago
Ly 97ea811694 1 2 months ago
Ly 8e4503f8fb 合并问题 2 months ago
Ly 890f2c3757 Merge branch 'GST002_admin' of http://182.92.169.222:3000/dlsx/ContestPortal into GST002_admin 2 months ago
Ly 7d29a0d42e Merge branch 'GST002_admin' of http://182.92.169.222:3000/dlsx/ContestPortal into GST002_admin 2 months ago
Ly cb75ee4f60 修改页面,删除年度比赛项目 2 months ago
喻忠伟 da0920b621 比赛问题 2 months ago
喻忠伟 f69dc882ba 比赛问题 去掉文件 2 months ago
喻忠伟 8b402b8717 Merge branch 'GST002_admin' of http://182.92.169.222:3000/dlsx/ContestPortal into GST002_admin 2 months ago
喻忠伟 44d3be5767 部署配置2 2 months ago
喻忠伟 41300c6d2f 部署配置 2 months ago
喻忠伟 8c7ed611c6 Merge branch 'GST002' of http://182.92.169.222:3000/dlsx/ContestPortal into GST002 3 months ago
JayChou 0e689d45a9 隐藏选择题目 3 months ago
喻忠伟 a38d34e276 Merge branch 'GST002' of http://182.92.169.222:3000/dlsx/ContestPortal into GST002 3 months ago
喻忠伟 822063893b 小问题 3 months ago
JayChou 5957a74fd5 修改个人报名队长增加默认值 3 months ago
JayChou 0f59d5e00a 修改上传作品提示类型 3 months ago
JayChou c64f1540d8 Merge branch 'GST002' of http://182.92.169.222:3000/dlsx/ContestPortal into GST002 3 months ago
JayChou d7cdde904b 修改注册提示问题 3 months ago
Ly bbf72a3ec7 详情页面取消暂存 3 months ago
喻忠伟 e180cfd1a2 修改作品问题 3 months ago
Ly 56a4c0f4b3 暂存 3 months ago
Ly 4b08a6e4f7 暂存按钮 3 months ago
喻忠伟 e2cb53ea4b 下载地址修改 3 months ago
Ly 1e9cebaa57 文件上传 3 months ago
喻忠伟 e27f11436a 1 3 months ago
JayChou e9c9f7aa1d 修改提交按钮状态显示 3 months ago
JayChou 7018dd3412 Merge branch 'GST002' of http://182.92.169.222:3000/dlsx/ContestPortal into GST002 3 months ago
JayChou 4bca08da4f 修改提交按钮状态 3 months ago
significative 3810ab8c3c 关于我们、服务协议等跳转 3 months ago
JayChou e127d6d6d3 修改修改报名传值id 3 months ago
JayChou 57f9af8ece Merge branch 'GST002' of http://182.92.169.222:3000/dlsx/ContestPortal into GST002 3 months ago
JayChou 71ce0b8c9c 登录增加节流 3 months ago
喻忠伟 e3f7415cbf 比赛奖项 3 months ago
JayChou 8cfec1d425 修改上传作品状态控制 3 months ago
JayChou 09be7b0592 修复登录成功仍然提示验证码错误bug 3 months ago
JayChou bac10262cc 修改新闻字体样式 3 months ago
JayChou ede5b69c7c 调整 3 months ago
JayChou 41ef0abc3e 年度比赛列表增加分页 4 months ago
JayChou 6e06564df6 修改团队赛年度名称溢出问题 4 months ago
JayChou 88ff7ed72e 修复报名后修改数据回显学号不显示问题 4 months ago
JayChou 719a91d898 修改新闻布局 4 months ago
JayChou 30b57c5569 修改年度比赛列表截取 4 months ago
JayChou 4d4151f125 修改报名传值问题 4 months ago
JayChou cc8d1a32ca 报名修改 4 months ago
JayChou 8d53a67e99 获取年度比赛项目id 4 months ago
JayChou 1af1a6e862 布局修改 4 months ago
JayChou f3cc596f96 删除样式 5 months ago
JayChou 3a6254d1cc 重构新闻列表 配置动态浏览器图标 问题修改 5 months ago
JayChou 4c504f76d4 修改返回顶部样式 6 months ago
JayChou 818816b289 修改题目字段 6 months ago
JayChou b26ab2d571 增加个人比赛修改\详情 6 months ago
JayChou 2e8d3fc21f 状态更新 报名待审核 6 months ago
JayChou a943860c7b 更新 6 months ago
JayChou 02a8c212ff 增加查看详情功能 6 months ago
JayChou 4be34ff89a 增加比赛编辑 6 months ago
JayChou 871b9b5ca2 Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
JayChou a3988ffc6b 修改问题11.29 6 months ago
喻忠伟 31e7c591a5 Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
喻忠伟 85df29b4a8 报名3 6 months ago
JayChou cf585cb6ba 修改路径 6 months ago
JayChou deb4435e71 修改下载 6 months ago
喻忠伟 04119d5c43 Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
JayChou 6997bf2b39 下载文件 6 months ago
喻忠伟 12307e731f Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
JayChou 53bf90dfb4 修改文本 6 months ago
JayChou b4e128d951 作品提交 6 months ago
喻忠伟 78fe84567f Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
JayChou 0f428a4b91 修改比赛详情结构 6 months ago
喻忠伟 7dd5d83aa2 Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
JayChou 85ab5ad7e0 修改文字 6 months ago
喻忠伟 ddabac1bad Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
JayChou d7835f2b39 个人比赛增列表加作品 6 months ago
喻忠伟 737b66205c Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
JayChou 961ccf3a8e 比赛列表增加分页 增加年度比赛title 6 months ago
喻忠伟 cfcffa21ab Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
王家东 7b2d382fa1 BUGxiugai 6 months ago
喻忠伟 594663d377 Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
JayChou b669f00d92 增加选题默认值 6 months ago
JayChou 32252167c4 增加选题 6 months ago
喻忠伟 06000e56fa Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
喻忠伟 c7da869fda 报名2 6 months ago
JayChou b6585d83d5 增加选题 6 months ago
JayChou dbe554bc83 上传作品 6 months ago
喻忠伟 f27c56436b Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
喻忠伟 472e912b05 报名 6 months ago
JayChou 64e73950e2 新增队员设置默认值 6 months ago
JayChou fa89909fa5 增加查找功能 6 months ago
JayChou d3d443bcce Merge branch 'base' of http://182.92.169.222:3000/dlsx/ContestPortal into base 6 months ago
JayChou 83fea5c94c 修改图片报错问题 6 months ago
喻忠伟 65b823719d 部署 6 months ago
JayChou 976a3911ac 删除首页列表 6 months ago
  1. 3
      .env.development
  2. 4
      .env.production
  3. 3
      index.html
  4. BIN
      public/favicon.ico
  5. 20
      src/App.vue
  6. 29
      src/Layout/footer/index.vue
  7. 43
      src/Layout/index.vue
  8. 13
      src/Layout/main/index.vue
  9. 40
      src/Layout/tabbar/index.vue
  10. 16
      src/api/news.ts
  11. 36
      src/api/oldRace.ts
  12. 4
      src/api/person.ts
  13. 48
      src/api/race.ts
  14. BIN
      src/assets/images/banner.jpg
  15. BIN
      src/assets/images/banner1.jpg
  16. BIN
      src/assets/images/jinglingtu.png
  17. BIN
      src/assets/images/news.png
  18. BIN
      src/assets/images/top1.png
  19. BIN
      src/assets/images/top2.png
  20. BIN
      src/assets/images/top3.png
  21. BIN
      src/assets/images/top4.png
  22. BIN
      src/assets/images/top5.png
  23. 3
      src/directives/defaultImage.ts
  24. 4
      src/router/module/constRouter/index.ts
  25. 19
      src/store/module/setting.ts
  26. 8
      src/styles/index.scss
  27. 3
      src/styles/reset.scss
  28. 3
      src/utils/requset.ts
  29. 58
      src/views/competition/index.vue
  30. 134
      src/views/home/index.vue
  31. 73
      src/views/login/index.vue
  32. 191
      src/views/login/registered.vue
  33. 20
      src/views/news/components/newsDetail.vue
  34. 308
      src/views/news/index.vue
  35. 39
      src/views/projectName/index.vue
  36. 261
      src/views/raceInfo/index.vue
  37. 2
      src/views/raceList/index.vue
  38. 31
      src/views/registrationGroup/components/stuDialog.vue
  39. 159
      src/views/registrationGroup/components/stuList.vue
  40. 14
      src/views/registrationGroup/components/teaDialog.vue
  41. 61
      src/views/registrationGroup/components/teaList.vue
  42. 166
      src/views/registrationGroup/index.vue
  43. 266
      src/views/registrationPersonage/index.vue
  44. 3
      src/views/userInfo/components/awardeList.vue
  45. 242
      src/views/userInfo/components/reacList.vue
  46. 100
      src/views/userInfo/index.vue
  47. 1
      vite.config.ts

@ -2,4 +2,5 @@
NODE_ENV = 'development'
VITE_APP_TITLE = '教学一体化平台'
VITE_APP_BASE_API = http://localhost:18085/jeecg-boot
# VITE_APP_BASE_API = 'http://127.0.0.1:8080'
# VITE_APP_BASE_API = 'http://127.0.0.1:8080'
VITE_APP_BASE_API_JEECG = '/student'

@ -1,5 +1,5 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
VITE_APP_TITLE = '高赛通'
VITE_APP_BASE_API = http://localhost:18085/jeecg-boot
VITE_APP_TITLE = '高赛通单项目'
VITE_APP_BASE_API = http://182.92.169.222:18088/jeecg-boot
# VITE_APP_BASE_API = 'http://127.0.0.1:8080'

@ -2,7 +2,8 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<!-- <link rel="icon" type="image/svg+xml" href="/vite.svg" /> -->
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>高赛通</title>
</head>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -3,26 +3,6 @@
</template>
<script lang="ts" setup>
import {} from 'vue'
import axios from 'axios'
const save = () => {
const data = {
insCode: 'c7c6aa3d-9d2e-40c3-8989-9f39c724eaa4',
instruType: 4,
instruList: '{}',
}
axios
.post('http://www.hniss.cn/api/service/putInstru', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
})
.then((res) => {
console.log(res)
})
}
save()
</script>
<style lang="scss" scoped></style>

@ -1,9 +1,11 @@
<template>
<div class="footer">
<div class="footer-nav">
<div class="item">关于我们</div>
<div class="item">联系我们</div>
<div class="item">服务协议</div>
<div v-for="item in NewList" :key="item.id" @click="toNewsDetail(item.id)">
<div class="item">
{{ item.title }}
</div>
</div>
</div>
<div class="copyright">源码自然版权所有@2023 湘豫CP备 19005950-1</div>
<div class="report">
@ -13,7 +15,26 @@
</template>
<script lang="ts" setup>
import {} from 'vue'
import { ref} from 'vue'
import { queryNewListApi } from '@/api/news'
import { useRouter } from 'vue-router'
const NewList = ref<any>([])
const getNewList = async () =>{
const res:any = await queryNewListApi()
console.log(res,111111111)
NewList.value = res.result
console.log(NewList.value,22222222)
}
getNewList()
const router = useRouter()
const toNewsDetail = (id: number) => {
router.push({
path: '/detail/' + id,
})
}
</script>
<style lang="scss" scoped>

@ -22,15 +22,24 @@ const scrollToTop = () => {
flog.value = true
const dom = document.querySelector('.gotop') as Element
console.log(dom)
totop.value.style.backgroundPosition = '-6px -145px'
setTimeout(() => {
totop.value.style.backgroundPosition = '-363px -78px'
totop.value.classList.add('top1');
}, 200)
setTimeout(() => {
totop.value.style.backgroundPosition = '-316px -78px'
totop.value.classList.remove('top1');
totop.value.classList.add('top5');
}, 400)
setTimeout(() => {
totop.value.style.backgroundPosition = '-6px -80px'
totop.value.classList.remove('top5');
totop.value.classList.add('top4');
totop.value.style.height = '60px'
scrollTop()
@ -88,14 +97,20 @@ onMounted(() => {
position: fixed;
bottom: 50px;
right: 50px;
background-image: url('../assets/images/jinglingtu.png');
background-position: -264px -78px;
// background-image: url('../assets/images/jinglingtu.png');
background: url('../assets/images/top3.png') no-repeat;
background-size: contain;
// background-position: -264px -78px;
transition: top 0.2s linear;
animation: show 0.5s ease-in-out;
}
.gotop:hover {
transition: background-image 0.2s ease-in;
background-position: -215px -78px;
// background-position: -215px -78px;
background: url('../assets/images/top2.png') no-repeat;
background-size: contain;
}
.bian {
animation: bian 0.1s ease-in-out;
@ -131,4 +146,18 @@ onMounted(() => {
// top: 10%;
// }
// }
.top1{
background: url('../assets/images/top1.png') no-repeat !important;
background-size: contain !important
}
.top4{
background: url('../assets/images/top4.png') no-repeat !important;
background-size: contain !important
}
.top5{
background: url('../assets/images/top5.png') no-repeat !important;
background-size: contain !important
}
</style>

@ -4,19 +4,24 @@
<router-view :key="$route.path" />
</transition>
</section> -->
<!-- <router-view></router-view> -->
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component"></component>
<keep-alive :include="cachedRoutes">
<component :is="Component"></component>
</keep-alive>
</router-view>
</template>
<script lang="ts" setup>
import {} from 'vue'
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import settingStore from '@/store/module/setting'
const $route = useRoute()
const useSettingStore = settingStore()
console.log($route)
//
const cachedRoutes = ref(['Home']) // name
useSettingStore.setLogo()
</script>
<style lang="scss" scoped></style>

@ -4,11 +4,7 @@
<div class="left">
<div class="logo-box">
<div class="lesson">
<img
:src="setImageUrl(logoUrl)"
alt=""
v-default-image="'/src/assets/images/LOGO.png'"
/>
<img :src="logoUrl" alt="" />
<!-- <img src="../../assets/images/LOGO.png" alt=""> -->
</div>
</div>
@ -30,7 +26,10 @@
</div>
</div>
<div class="right" v-if="!useUserStore.token">
<div class="registered gradient" @click="$router.push('/login')">
<div
class="registered gradient"
@click="$router.push('/login?registered=true')"
>
注册
</div>
<div class="login" @click="$router.push('/login')">登录</div>
@ -40,7 +39,7 @@
<img
:src="setImageUrl(useUserStore.userInfo.avatar)"
alt=""
v-default-image="'/src/assets/images/default.png'"
v-default-image="defaultUserAvater"
/>
</div>
<el-dropdown style="width: 0.625rem">
@ -67,11 +66,13 @@
<script lang="ts" setup>
import { constRouter } from '@/router/module/constRouter'
import { useRouter, useRoute } from 'vue-router'
import { onMounted, ref } from 'vue'
import { onMounted, ref, watch } from 'vue'
import userStore from '@/store/module/user'
import settingStore from '@/store/module/setting'
import Item from './components/item.vue'
import { getLogo } from '@/api/setting'
import defaultUserAvater from '@/assets/images/default.png'
const useUserStore = userStore()
const useSettingStore = settingStore()
const $router = useRouter()
const $route = useRoute()
const flog = ref(false)
@ -86,19 +87,27 @@ onMounted(() => {
})
const layout = async () => {
useUserStore.layOut()
$router.push('/login')
}
const setImageUrl = (url: string) => {
return import.meta.env.VITE_APP_BASE_API + '/sys/common/static/' + url
return import.meta.env.VITE_APP_BASE_API + '/' + url
}
// logo
const logoUrl = ref<string>('')
const getLogoSetting = async () => {
const res: any = await getLogo()
console.log(res, 'res')
logoUrl.value = res.result.logo
setTimeout(() => {
console.log(useSettingStore.logo, 'useSettingStore.logo')
logoUrl.value = setImageUrl(useSettingStore.logo)
}, 100)
}
getLogoSetting()
watch(
() => useSettingStore.logo,
() => {
getLogoSetting()
},
)
// getLogoSetting()
</script>
<style lang="scss" scoped>
@ -292,4 +301,7 @@ getLogoSetting()
background-color: transparent;
border-bottom: none;
}
.el-dropdown-link {
white-space: nowrap;
}
</style>

@ -6,10 +6,22 @@ export const getColumnListApi = () => {
})
}
//根据栏目id获取新闻列表
export function queryEssayListApi(columnId) {
export function queryEssayListApi(columnId:any) {
return request.get(`/cms/front/getArticleListByColumn?columnId=${columnId}`)
}
//获取关于我们,联系我们,服务协议的id
export const queryNewListApi = () => {
return request({
url: '/cms/cmsArticle/getdatainfo',
})
}
//根据点击的新闻id获取新闻详细信息
export function queryEssayApi(id) {
export function queryEssayApi(id:any) {
return request.get(`/cms/front/getByArticleTitle?id=${id}`)
}
// 获取新闻列表
export const getNewsListApi = () => {
return request({
url: '/cms/cmsArticle/getColumArt',
})
}

@ -0,0 +1,36 @@
import request from "@/utils/requset";
// 获取年度比赛和项目
export const getOldRaceList = (params:any) => {
return request({
url: '/annualcompetitionprojectregistration/annualCompetitionProjectRegistration/queryCompInfo4Stu',
method: 'get',
params
})
}
// 查询报名信息
export const getOldRaceInfo = (params:any) => {
return request({
url: '/annualcompetitionprojectregistration/annualCompetitionProjectRegistration/queryTopicById',
method: 'get',
params
})
}
// 查询团队成员列表
export const getTeamList = (params:any) => {
return request({
url: 'annualcompetitionprojectregistration/annualCompetitionProjectRegistration/queryTeamManagementByMainId',
method: 'get',
params
})
}
// 获取指导老师列表
export const getTeacherList = (params:any) => {
return request({
url: 'annualcompetitionprojectregistration/annualCompetitionProjectRegistration/queryInstructorSheetByMainId',
method: 'get',
params
})
}

@ -59,7 +59,9 @@ interface SignUpData {
entryFormat: '团队' | '个人'
id: string
instructorSheetList?: any[]
teamManagementList?: any[]
teamManagementList?: any[],
file:string
WorkName:any
}
interface MembersOrAdviser {

@ -88,3 +88,51 @@ export const getHistoryRaceList = (params: any) => {
params,
})
}
// 获取学生参加的比赛
export const getStuRaceList = (params: any) => {
return request({
url: '/annualcompetitionprojectregistration/annualCompetitionProjectRegistration/list4Stu',
params,
})
}
// 上传作品
export const uploadFileZp = (data: any) => {
return request({
url: '/upfilePersion/upfilePersion/workUpload4Stu',
method: 'POST',
data,
})
}
// 获取题目列表
export const getTopicList = (params: any) => {
return request({
url: '/topic/topic/selectList',
params,
})
}
export const sava = (data: any) => {
return request({
url: '/upfilePersion/upfilePersion/updateStatusById',
method: 'POST',
data,
})
}
// 取消比赛
export const cancelRace = (params: any) => {
return request({
url: '/annualcompetitionprojectregistration/annualCompetitionProjectRegistration/cancelRegistration',
method: 'GET',
params,
})
}
// 获取项目id
export const getProjectId = (params: any) => {
return request({
url: '/comp/comp/findanncomppid',
method: 'GET',
params,
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -1,8 +1,9 @@
import defaultImage from '@/assets/images/item.png';
export default {
mounted(el: any, binding: any) {
el.onerror = () => {
// 当图片加载失败时,设置默认图片
el.src = binding.value || '/src/assets/images/item.png' // 默认图片
el.src = binding.value || defaultImage // 默认图片
}
},
}

@ -49,7 +49,7 @@ export const constRouter: any = {
// hidden: false,
// },
// },
{
/* {
path: '/raceList',
name: 'RaceList',
component: () => import('@/views/raceList/index.vue'),
@ -58,7 +58,7 @@ export const constRouter: any = {
title: '竞赛列表',
hidden: false,
},
},
},*/
{
path: '/competition',
name: 'Competition',

@ -0,0 +1,19 @@
import { defineStore } from 'pinia'
import { getLogo } from '@/api/setting'
const settingStore = defineStore('setting', {
state: () => ({
logo: '',
}),
actions: {
setLogo() {
getLogo().then((res: any) => {
console.log(res, 'this.logo')
this.logo = res.result.logo
document.querySelector("link[rel~='icon']").href = import.meta.env.VITE_APP_BASE_API + '/' + this.logo
})
},
},
})
export default settingStore

@ -43,4 +43,12 @@
color: #6da0ff !important;
font-weight: 700;
opacity: .5;
}
img{
width: 100%;
}
.race-description{
p{
line-height: 30px;
}
}

@ -37,7 +37,6 @@
code,
del,
dfn,
em,
img,
ins,
kbd,
@ -46,14 +45,12 @@
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,

@ -19,6 +19,9 @@ server.interceptors.request.use((config) => {
})
// 创建相应拦截器
server.interceptors.response.use((response) => {
if(response.data.code === 412){
return Promise.reject(response)
}
return response.data
})

@ -2,12 +2,24 @@
<template>
<div class="fill"></div>
<div class="banner">
<img src="../../assets/images/banner2.png" alt="" />
<img src="../../assets/images/banner.jpg" alt="" />
</div>
<div class="competition" v-loading="loading">
<!-- 简介 -->
<div class="synopsis">
<div class="name">{{ yearRaceInfo.name }}</div>
<div style="display: flex;justify-content: space-between;">
<div class="name">{{ yearRaceInfo.name }}</div>
<div class="back">
<el-button
type="primary"
style="margin-top: 10px"
@click="$router.back()"
>
返回
</el-button>
</div>
</div>
<div class="content">
{{ yearRaceInfo.introduction }}
</div>
@ -19,10 +31,16 @@
<div class="left">
<div class="text-box">
<div class="title">选择项目</div>
<div class="small">300+竞赛登陆后请报名</div>
<div class="small">选择下面的项目报名参与比赛</div>
</div>
<div class="card-list">
<div
v-if="dataList.length == 0"
style="font-size: 20px; color: #828282"
>
没有项目请创建年度比赛项目
</div>
<template v-for="(o, i) in dataList" :key="o.id">
<div v-if="(i + 5) % 4 == 1" class="card" type="yellow">
<div class="top" :title="o.objName">{{ o.objName }}</div>
@ -73,14 +91,16 @@
</div>
<div class="game-list">
<div class="card-game" v-for="i in 5" :key="i">
<div class="pos">前往查看</div>
<div class="top">2023年度</div>
<div class="card-game" v-for="i in historyRaceList" :key="i.id">
<!-- <div class="pos">前往查看</div> -->
<div class="top">2024年度</div>
<div class="center">
<div class="text">河南省大学生创新创业大赛</div>
<img src="../../assets/images/编组.png" alt="" />
<div class="text">{{ i.name }}</div>
<img style="width: 35px;" src="../../assets/images/编组.png" alt="" />
</div>
<div class="bottom">
报名时间{{ i.starttime }} - {{ i.endtime }}
</div>
<div class="bottom">报名时间2023.08.23-2023.09.23</div>
</div>
</div>
</div>
@ -93,7 +113,7 @@ import { getCompetitionApi } from '@/api/person'
import { ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElLoading } from 'element-plus'
import { getYearRaceInfo } from '@/api/race'
import { getYearRaceInfo, getHistoryRaceList } from '@/api/race'
const route = useRoute()
const router = useRouter()
@ -134,6 +154,14 @@ const getYearRaceInfoEvent = async () => {
console.log(res, 'yearRaceInfo.value ')
}
getYearRaceInfoEvent()
//
const historyRaceList = ref<any>([])
const getHistoryRaceListEvent = async () => {
const res: any = await getHistoryRaceList({ id: route.query.raceId })
console.log(res)
historyRaceList.value = res.result
}
getHistoryRaceListEvent()
</script>
<style lang="scss" scoped>
@ -177,7 +205,8 @@ getYearRaceInfoEvent()
font-weight: 400;
font-size: 20px;
color: #555555;
line-height: 23px;
line-height: 35px;
text-indent: 2em;
}
.date {
@ -207,12 +236,12 @@ getYearRaceInfoEvent()
flex-wrap: wrap;
column-gap: 20px;
row-gap: 40px;
.card {
width: 260px;
height: 160px;
padding: 40px 0 0 30px;
box-shadow: 3px 2px 18px -7px rgba(0, 0, 0, 0.45);
transition: all 0.3s;
&[type='yellow'] {
background: url(../../assets/images/yellow.png) no-repeat;
background-size: cover;
@ -285,6 +314,9 @@ getYearRaceInfoEvent()
}
}
}
.card:hover {
transform: translateY(-5px);
}
}
}

@ -3,7 +3,7 @@
<div class="banner">
<div class="title">{{ reacProjectList[0].compName }}火热报名中</div>
<div class="description">
<div v-html="reacProjectList[0].compName"></div>
<div v-html="reacProjectList[0].compInfo"></div>
</div>
<div
class="application gradient"
@ -11,37 +11,19 @@
>
立即报名
</div>
<div class="nav-title">
<div class="top">竞赛导航</div>
<div class="bottom">30+项目登陆后报名</div>
</div>
</div>
<!-- 比赛列表 -->
<div class="race-list">
<div
class="item"
v-for="item in reacProjectList"
:key="item.id"
@click="toDetail(item.id)"
>
<div class="image">
<img :src="setImageUrl(item.compImg)" alt="" v-default-image />
</div>
<div class="reac-info">
<div class="reac-title">{{ item.compName }}</div>
<div class="reac-project"><div v-html="item.compName"></div></div>
<!-- <div class="time">
报名时间:{{ item.starttime }}-{{ item.endtime }}
</div> -->
</div>
</div>
<div class="more" @click="router.push('/raceList')">更多</div>
</div>
<!-- 新闻列表 -->
<div class="news-list">
<div class="news-title">
<div class="top">新闻资讯</div>
<div class="bottom">30+项目登陆后报名</div>
<div class="top">
<div>新闻资讯</div>
<div @click="router.push('/news')">
<el-icon><ArrowRightBold /></el-icon>
</div>
</div>
<!-- <div class="bottom">30+项目登陆后报名</div> -->
</div>
<div class="newa-panel">
<div class="tab">
@ -53,15 +35,17 @@
>
{{ item.name }}
</div>
<div
class="item"
@click="router.push('/news')"
>
更多
</div>
</div>
<div class="newa-main">
<div class="left">
<img
src=""
alt=""
v-default-image
style="width: 100%; height: 100%"
/>
<img src="../../assets/images/news.png" alt="" style="width: 100%; height: 100%" />
</div>
<div class="right">
<div class="title">{{ newInfo.name }}</div>
@ -70,11 +54,15 @@
</div>
<div class="newa-main-list">
<ul>
<li v-for="item in childrenNewList" :key="item.id">
<div class="time">{{ item.createTime }}</div>
<li v-for="item in childrenNewList" :key="item.id" @click="toNewsDetail(item.id)">
<div class="info">
{{ item.info }}
{{ item.title }}
</div>
<div class="time">{{ item.createTime }}</div>
<!-- <div class="name">
{{ item.createBy_dictText }}
</div> -->
</li>
</ul>
</div>
@ -86,6 +74,7 @@
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { getRaceList } from '@/api/race'
import { useRouter } from 'vue-router'
@ -131,14 +120,19 @@ const toDetail = (id: number) => {
},
})
}
const toNewsDetail = (id: number) => {
router.push({
path: '/detail/' + id,
})
}
//
const newList = ref<any>([])
const getNewsList = async () => {
const res: any = await getColumnListApi()
console.log(res)
newList.value = res.result
console.log(newList.value, 'newList.value')
// console.log(res)
newList.value = res.result.slice(0, 4)
// console.log(newList.value, 'newList.value')
newInfo.value = newList.value[0]
getNewInfo(newList.value[0].id)
}
@ -151,7 +145,7 @@ const childrenNewList = ref<any>([])
const getNewInfo = async (id: any) => {
const res: any = await queryEssayListApi(id)
childrenNewList.value = res.result.records
console.log(childrenNewList, 'childrenNewList')
// console.log(childrenNewList, 'childrenNewList')
}
// tab
@ -161,7 +155,11 @@ const toggleTab = (item: any, index: number) => {
getNewInfo(newInfo.value.id)
}
</script>
<script lang="ts">
export default {
name: 'Home', //
};
</script>
<style lang="scss" scoped>
.banner {
position: relative;
@ -189,6 +187,12 @@ const toggleTab = (item: any, index: number) => {
font-size: 20px;
color: #666;
margin-top: 37px;
line-height: 32px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.application {
width: 272px;
@ -285,6 +289,25 @@ const toggleTab = (item: any, index: number) => {
font-size: 40px;
font-weight: 600;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
div {
display: flex;
align-items: center;
justify-content: center;
margin: 0 10px;
}
div:last-child {
cursor: pointer;
transition: all 0.2s;
&:hover {
color: #0bd7c6;
transform: scale(1.2);
}
}
}
.bottom {
font-size: 16px;
@ -368,20 +391,22 @@ const toggleTab = (item: any, index: number) => {
ul {
width: 100%;
height: 100%;
display: flex;
flex-wrap: wrap;
// display: flex;
// flex-wrap: wrap;
justify-content: space-between;
// align-items: center;
li {
width: 227px;
// width: 227px;
width: 100%;
height: 65px;
cursor: pointer;
display: flex;
.time {
position: relative;
font-size: 14px;
color: #1e2033;
padding-left: 13px;
margin-left: 20px;
}
.time::before {
.info::before {
content: ' ';
display: block;
position: absolute;
@ -392,10 +417,19 @@ const toggleTab = (item: any, index: number) => {
background-color: #319245;
}
.info {
margin-top: 12px;
font-size: 12px;
position: relative;
// margin-top: 12px;
font-size: 14px;
color: #1e2033;
line-height: 18px;
// line-height: 18px;
padding-left: 13px;
}
.name{
font-size: 14px;
margin-left: 20px;
}
}
}

@ -12,6 +12,7 @@
v-model="form.password"
style="height: 0.2344rem"
type="password"
show-password
/>
</el-form-item>
<el-form-item label="验证码">
@ -27,7 +28,11 @@
</div>
</el-form-item>
</el-form>
<div class="submit gradient" @click="submit">登录</div>
<!-- <div class="submit gradient" @click="submit">登录</div> -->
<div class="btn">
<div @click="Router.push('/')">返回首页</div>
<div class="gradient" @click="submit">登录</div>
</div>
</div>
<div class="registered">
还没账号
@ -39,12 +44,13 @@
</template>
<script lang="ts" setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import { onMounted, reactive, ref, toRefs, watch,onBeforeUnmount } from 'vue'
import { getCode } from '@/api/user'
import userStore from '@/store/module/user'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
import { useRouter, useRoute } from 'vue-router'
import RegisTered from './registered.vue'
const route = useRoute()
const useUserStore = userStore()
const form = ref({
account: '',
@ -74,29 +80,43 @@ const submit = async () => {
password: form.value.password,
username: form.value.account,
}
const res = await useUserStore.login(data)
console.log(res)
if (res === 0) {
ElMessage('验证码错误')
getcodeinfo()
} else if (res === 1) {
ElMessage('账号或密码错误')
try {
const res = await useUserStore.login(data)
console.log(res)
isSubmitting.value = false
if (res === 1) {
ElMessage('账号或密码错误')
getcodeinfo()
} else {
Router.push('/')
}
} catch (error: any) {
ElMessage(error.data.message)
getcodeinfo()
} else {
Router.push('/')
}
}
onMounted(() => {
window.addEventListener('keydown', keyDown)
window.addEventListener('keyup', keyDown)
// setTimeout(() => {
// getcodeinfo()
// },6000)
if (route.query.registered) {
registered()
}
})
onBeforeUnmount(() => {
window.removeEventListener('keyup', keyDown) //
})
const isSubmitting = ref(false) //
const keyDown = (e: any) => {
//
//
if (isSubmitting.value) return
//
if (e.keyCode == 13) {
//
submit()
isSubmitting.value = true //
submit() //
}
}
@ -180,6 +200,27 @@ const backLoginEvent = () => {
}
}
}
.btn {
display: flex;
justify-content: space-between;
margin-top: 45px;
div {
width: 210px;
height: 42px;
text-align: center;
line-height: 42px;
font-size: 14px;
cursor: pointer;
border-radius: 10px;
}
div:nth-child(1) {
border: 1px solid #dbdbdb;
color: #3c3c3c;
}
div:nth-child(2) {
color: #fff;
}
}
:deep(.el-form-item) {
display: flex;
flex-direction: column;

@ -2,8 +2,8 @@
<div class="login-form">
<div class="login-title">注册</div>
<div class="form">
<el-form :model="form" label-width="0">
<el-form-item>
<el-form :model="form" ref="ruleFormRef" label-width="0" :rules="rules">
<!-- <el-form-item>
<el-col :span="11">
<el-input
v-model="form.username"
@ -23,8 +23,22 @@
style="height: 0.2344rem"
/>
</el-col>
</el-form-item> -->
<el-form-item prop="username">
<el-input
v-model="form.username"
:prefix-icon="User"
placeholder="账号"
/>
</el-form-item>
<el-form-item>
<el-form-item prop="realname">
<el-input
v-model="form.realname"
:prefix-icon="User"
placeholder="姓名"
/>
</el-form-item>
<el-form-item prop="workno">
<el-input
v-model="form.workno"
placeholder="工号/学号"
@ -42,21 +56,25 @@
:props="props"
style="width: 100%; height: 0.2344rem"
v-model="form.department"
:show-all-levels="false"
@change="handleChange"
ref="cascader"
/>
</el-form-item>
<el-form-item>
<el-form-item prop="mobile">
<el-input
placeholder="手机号码"
v-model="form.mobile"
:prefix-icon="Iphone"
></el-input>
</el-form-item>
<el-form-item>
<el-form-item prop="password">
<el-input
placeholder="密码"
v-model="form.password"
:prefix-icon="Lock"
type="password"
show-password
></el-input>
</el-form-item>
<el-form-item>
@ -65,6 +83,7 @@
v-model="form.confirmPassword"
:prefix-icon="Lock"
type="password"
show-password
></el-input>
</el-form-item>
<el-form-item>
@ -100,6 +119,7 @@ import { User, Iphone, Lock } from '@element-plus/icons-vue'
import { getFaculties } from '@/api/race'
import { ElMessage } from 'element-plus'
import { getCode, sturegister } from '@/api/user'
import { ca } from 'element-plus/es/locales.mjs'
const $emits = defineEmits(['backLogin'])
const form = reactive<any>({
username: '',
@ -121,7 +141,48 @@ const KeyValue: any = {
confirmPassword: '确认密码' /*, policy: false*/,
smscode: '验证码',
}
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 6, max: 20, message: '账号长度在6到50个字符', trigger: 'blur' },
{
pattern: /^[a-zA-Z0-9]+$/,
message: '姓名只能包含数字、英文',
trigger: 'blur',
},
],
realname: [
{ required: true, message: '请输入姓名', trigger: 'blur' },
{ min: 2, max: 20, message: '姓名长度在2到10个字符', trigger: 'blur' },
// {
// pattern: /^[a-zA-Z0-9]+$/,
// message: '',
// trigger: 'blur',
// },
],
workno: [
{ required: true, message: '请输入工号/学号', trigger: 'blur' },
{
pattern: /^[a-zA-Z0-9]{1,20}$/,
message: '工号/学号为1-20位数字或字母',
trigger: 'blur',
},
],
mobile: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' },
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 8, max: 16, message: '密码长度在8到16个字符', trigger: 'blur' },
{
pattern:
/^(?=(.*[a-zA-Z]){2,}|(?=.*[a-zA-Z])(?=.*\d)|(?=.*[a-zA-Z])(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>/?])|(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>/?]))[a-zA-Z\d!@#$%^&*()_+\-=\[\]{};':"\\|,.<>/?]{8,16}$/,
message: '密码必须包含至少两种字符类型:英文字符、数字、特殊字符',
trigger: 'blur',
},
],
}
const FacultiesList = ref([])
const getFacultiesList = async (data: any) => {
const res: any = await getFaculties(data)
@ -133,56 +194,98 @@ const props = {
lazy: true,
checkStrictly: true,
emitPath: false,
isLeaf: 'isLeaf',
async lazyLoad(node: any, resolve: any) {
// console.log(node, '1212')
// console.log(node.data.isLeaf)
// if (node.data.isLeaf) {
// console.log(1111)
// return resolve([])
// }
await getFacultiesList({
primaryKey: 'key',
pid: node.value,
})
const nodes = FacultiesList.value.map((item: any) => ({
value: item.id,
label: item.title,
}))
resolve(nodes)
if (node.level == 0 || node.level == 1) {
const nodes = FacultiesList.value.map((item: any) => ({
value: item.id,
label: item.title,
disabled: true,
leaf: item.isLeaf,
}))
resolve(nodes)
} else {
const nodes = FacultiesList.value.map((item: any) => ({
value: item.id,
label: item.title,
leaf: item.isLeaf,
}))
resolve(nodes)
}
},
}
const cascader = ref()
const handleChange = (e: any) => {
// console.log(e,cascader.value);
cascader.value.togglePopperVisible()
}
const ruleFormRef = ref<any>()
const ragistered = async () => {
for (const key in form) {
if (form[key] === '') {
ElMessage.warning(`${KeyValue[key]}不能为空`)
return console.log(KeyValue[key], '不能为空')
} else {
if (key === 'mobile') {
const phoneRegex = /^1[3-9]\d{9}$/
if (!phoneRegex.test(form[key])) {
return ElMessage.warning(`手机号格式不正确`)
try {
await ruleFormRef.value.validate()
for (const key in form) {
if (form[key] === '') {
ElMessage.warning(`${KeyValue[key]}不能为空`)
return console.log(KeyValue[key], '不能为空')
} else {
if (key === 'mobile') {
const phoneRegex = /^1[3-9]\d{9}$/
if (!phoneRegex.test(form[key])) {
return ElMessage.warning(`手机号格式不正确`)
}
}
}
}
if (!(form.password === form.confirmPassword)) {
return ElMessage.warning(`两次密码不同`)
}
console.log(form)
let data = {
checkKey: 1629428467008,
departmentid: form.department,
password: form.password,
phone: form.mobile,
realname: form.realname,
smscode: form.smscode,
username: form.username,
workno: form.workno,
}
const res: any = await sturegister(data)
if (res.code === 200) {
ElMessage.success(`注册成功`)
$emits('backLogin')
} else {
ElMessage.warning(res.message)
getcodeinfo()
}
console.log(res)
} catch (error: any) {
console.log(error, 'error')
//
if(error.hasOwnProperty('data')){
ElMessage.warning(error.data.message)
}else{
for (const key in error) {
ElMessage.warning(`${KeyValue[key]}${error[key][0].message}`)
}
}
}
if (!(form.password === form.confirmPassword)) {
return ElMessage.warning(`两次密码不同`)
}
console.log(form)
let data = {
checkKey: 1629428467008,
departmentid: form.department,
password: form.password,
phone: form.mobile,
realname: form.realname,
smscode: form.smscode,
username: form.username,
workno: form.workno,
}
const res: any = await sturegister(data)
if (res.code === 200) {
ElMessage.success(`注册成功`)
$emits('backLogin')
} else {
ElMessage.warning(res.message)
getcodeinfo()
}
console.log(res)
}
const codeUrl = ref('')

@ -9,9 +9,9 @@
<div class="center-image">
<img
class="list-image"
:src="completeImageUrl"
:src="setImageUrl(data.comimg)"
alt="News Image"
v-default-image
/>
</div>
<p class="list-time">{{ data.publishTime }}</p>
@ -34,22 +34,18 @@ queryEssayApi(route.params.id).then((res) => {
console.log(`当前id为${route.params.id}新闻详细信息`, data.value)
})
//
const completeImageUrl = computed(() => {
if (data.value.comimg) {
return new URL(data.value.comimg, 'https://localhost:18085/jeecg-boot/')
.href
}
return ''
})
const setImageUrl = (url: string) => {
return import.meta.env.VITE_APP_BASE_API + '/sys/common/static/' + url
}
</script>
<style scoped>
.container {
width: 60%;
margin: auto;
height: 98vh;
overflow-y: scroll;
/* height: 98vh; */
/* overflow-y: scroll; */
padding: 0;
display: block;
margin-top: 100px;

@ -1,183 +1,161 @@
<template>
<div class="main">
<el-tabs
v-model="activeName"
style="max-width: 70%; margin: auto"
class="container"
@tab-click="handleTabClick"
>
<el-tab-pane
v-for="category in categories"
:key="category.id"
:label="category.name"
:name="category.id"
>
<ul>
<li
v-for="newsItem in getNewsItemsForCategory(category)"
:key="newsItem.id"
>
<div class="box-list" @click.stop="handleNewsClick(newsItem)">
<div class="left-box-list">
<p class="list-title">{{ newsItem.title }}</p>
<p class="list-summary">
{{ stripHtmlTags(newsItem.summary) }}
</p>
<p class="list-time">{{ newsItem.date }}</p>
<div class="container">
<div class="news-list">
<div class="item" v-for="(item,index) in newsList" :key="item.id">
<div class="news-title" :id="index.toString()">{{ item.name }}</div>
<div class="children">
<div class="son-item" v-for="obj in item.cmsArticleList" :key="obj.id" @click="toNewsDetail(obj.id)">
<div class="left">
<div class="title">{{ obj.title }}</div>
<div class="content">
{{ obj.info }}
</div>
<img
class="news-image"
:src="newsItem.imageUrl"
alt="News Image"
v-default-image
/>
<div class="time"><div>{{ obj.publishTime }}</div> <div style="margin-left: 20px;">发布人{{ obj.createBy }}</div></div>
</div>
<el-divider />
</li>
</ul>
</el-tab-pane>
</el-tabs>
<div class="right">
<img :src="setImageUrl(obj.comimg)" alt="" v-default-image/>
</div>
</div>
<el-empty description="无新闻" v-if="item.cmsArticleList.length === 0" style="height: 200px;"/>
</div>
</div>
</div>
<!-- 右侧栏目 -->
</div>
<div class="right-coulom">
<div :class="active === index ? 'item active' : 'item' " @click="scrollById(index)" v-for="(item,index) in columnList" :key="item">{{ item }}</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { getColumnListApi, queryEssayListApi } from '@/api/news'
let categories = ref([])
let newsItems = ref({})
let activeName = ref('')
const router = useRouter()
//使html
function stripHtmlTags(html) {
return html.replace(/<[^>]*>/g, '')
}
//
const fetchColumnList = async () => {
const response = await getColumnListApi()
if (response.success && response.result) {
categories.value = response.result.filter(
(category) => category.isShow === '1',
)
//
if (categories.value.length > 0) {
await fetchNewsList(categories.value[0].id)
activeName.value = categories.value[0].id
}
}
}
import { getNewsListApi } from '@/api/news'
//
const fetchNewsList = async (categoryId) => {
try {
const response = await queryEssayListApi(categoryId)
// console.log(response.success,'')
// console.log(response.result.records,'')
if (response.success && response.result.records) {
newsItems.value[categoryId] = response.result.records.map((data) => ({
id: data.id,
title: data.title,
date: data.publishTime,
summary: data.content,
imageUrl: data.comimg ? getAbsoluteImagePath(data.comimg) : '',
}))
}
} catch (error) {
console.error('获取新闻列表失败', error)
}
}
//
const getAbsoluteImagePath = (relativePath) => {
const baseImageUrl = 'https://localhost:18085/jeecg-boot/' //
return baseImageUrl + relativePath
}
//
const getNewsItemsForCategory = (category) => {
return newsItems.value[category.id] || []
}
//
onMounted(() => {
fetchColumnList()
})
//
const handleTabClick = async (tab) => {
const categoryId = tab.props.name
if (!newsItems.value[categoryId]?.length) {
await fetchNewsList(categoryId)
}
activeName.value = categoryId
}
//
const handleNewsClick = (newsItem) => {
const router = useRouter()
const newsList = ref<any>([])
const columnList = ref<any>([])
const active = ref(0)
const getNewsListApiEvent = async () => {
const res:any = await getNewsListApi()
console.log(res, '212121')
columnList.value = res.result.map(item => item.name)
newsList.value = res.result
}
getNewsListApiEvent()
const scrollById = (index: number) => {
active.value = index
const targetPosition = (document.getElementById(index.toString()) as HTMLElement).offsetTop - 120;
window.scrollTo({
top: targetPosition,
behavior: 'smooth', //
});
}
const toNewsDetail = (id: number) => {
router.push({
name: 'newsDetail',
params: { id: newsItem.id.toString() },
path: '/detail/' + id
})
}
</script>
<style scoped>
.main {
margin-top: 100px;
const setImageUrl = (url: string) => {
return import.meta.env.VITE_APP_BASE_API + '/sys/common/static/' + url
}
</script>
<style scoped lang="scss">
.container {
width: 1200px;
margin: auto;
height: 98vh;
overflow-y: scroll;
padding: 0;
display: block;
}
.container::-webkit-scrollbar {
width: 0;
}
.box-list {
display: flex;
width: 95%;
height: 100px;
margin-left: 30px;
margin-bottom: 10px;
align-items: center;
cursor: pointer; /* 默认鼠标指针形状 */
}
.box-list:hover {
background-color: lightgrey; /* 鼠标悬停时改变背景颜色 */
}
.left-box-list {
display: flex;
flex-direction: column;
justify-content: space-between;
flex: 1;
padding-right: 10px;
}
.list-title {
font-size: 22px;
margin-left: 60px;
}
.list-summary {
font-size: 16px;
margin-left: 60px;
margin-top: 15px;
color: #999999;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis; /* 溢出部分显示为省略号 */
max-width: calc(100% - 130px); /* 减去右侧图片宽度和内边距 */
}
.list-time {
margin-left: 60px;
margin-top: 20px;
color: #999999;
margin-top: 100px;
.news-list {
width: 100%;
// height: 900px;
// background-color: #f2f3f5;
padding: 15px;
border: 1px solid #f2f3f5;
border-radius: 5px;
.item {
.news-title {
font-size: 24px;
font-weight: 700;
}
.children {
margin: 20px 0;
.son-item {
width: 100%;
height: 100px;
background-color: #fff;
padding: 15px;
display: flex;
border-bottom: 1px solid rgba(228, 230, 235, 0.5);
justify-content: space-between;
cursor: pointer;
.left {
width: 1000px;
.title {
font-size: 18px;
font-weight: 700;
color: #4f5153;
}
.content {
margin-top: 8px;
font-size: 13px;
color: #8a919f;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.time {
margin-top: 8px;
font-size: 12px;
color: #8a919f;
display: flex;
}
}
.right {
display: flex;
flex: 1;
align-items: center;
justify-content: center;
img {
width: 100%;
height: 100%;
}
}
&:hover {
background-color: #f7f8fa;
}
}
}
}
}
}
.news-image {
width: 100px;
height: 80px;
margin-right: 30px;
.right-coulom {
position: fixed;
left: 200px;
top: 100px;
z-index: 999;
width: 150px;
// height: 300px;
background-color: #f2f3f5;
padding: 10px;
border-radius: 5px;
.item {
height: 45px;
// text-align: center;
line-height: 22px;
font-size: 16px;
padding: 10px;
border-radius: 5px;
cursor: pointer;
margin: 5px 0;
&:hover {
background-color: #0bd7c628;
color: #0bd7c6;
}
}
.active {
background-color: #0bd7c628;
color: #0bd7c6;
}
}
</style>

@ -2,7 +2,7 @@
<template>
<div class="fill"></div>
<div class="banner">
<img src="../../assets/images/banner2.png" alt="" />
<img src="../../assets/images/banner.jpg" alt="" />
</div>
<div class="project-name">
@ -21,6 +21,7 @@
</el-breadcrumb-item>
</template>
</el-breadcrumb>
<!-- <div class="black"><el-button type="primary" style="margin-top: 10px;" @click="$router.back()">返回</el-button></div> -->
</div>
<div class="content">
@ -36,7 +37,11 @@
</div>
<div class="btn-box">
<el-button class="btn" @click="handleSub">立刻报名</el-button>
<el-button class="btn-back" @click="$router.back()">返回</el-button>
<el-button class="btn" style="margin-left: 60px;" @click="handleSub">立刻报名</el-button>
</div>
</div>
</template>
@ -81,7 +86,7 @@ const checked = ref(false)
function handleSub() {
if (!checked.value) {
ElMessage({
message: '请先同意',
message: '请确认您已阅读并同意比赛规则。',
type: 'warning',
})
return
@ -133,13 +138,14 @@ getData()
font-size: 18px;
color: #666666;
text-indent: 2em;
min-height: 500px;
min-height: 200px;
}
.foot {
margin: 120px 0 20px;
display: flex;
align-items: center;
justify-content: center;
gap: 110px;
}
}
@ -147,14 +153,14 @@ getData()
.btn-box {
display: flex;
justify-content: center;
margin-top: 80px;
margin-top: 50px;
.btn {
--color1: #00d0d0;
--color2: #42d9ac;
cursor: pointer;
text-align: center;
width: 470px;
width: 270px;
height: 50px;
border-radius: 45px;
border: none;
@ -168,7 +174,28 @@ getData()
&:hover {
transform: scale(1.1);
}
}
.btn-back{
--color1: #ebf0f0;
--color2: #c6d4d4;
cursor: pointer;
text-align: center;
width: 270px;
height: 50px;
border-radius: 45px;
border: none;
font-weight: bold;
font-size: 24px;
color: #ffffff;
background: linear-gradient(to right, var(--color1), var(--color2));
box-shadow: 7px 7px 22px -10px rgba(0, 0, 0, 0.22);
transition: all 0.2s;
&:hover {
transform: scale(1.1);
}
}
}
}

@ -1,59 +1,25 @@
<template>
<div class="container-1420 container">
<div class="top-image">Banner</div>
<!-- 年度比赛列表 -->
<div class="race-list">
<div
class="item"
v-for="item in reacProjectList"
:key="item.id"
@click="goToCompetition(item.id)"
>
<div class="image">
<img
:src="setImageUrl(item.image)"
alt=""
v-default-image="defaultImageUrl"
/>
</div>
<div class="reac-info">
<div class="reac-title">{{ item.name }}</div>
<div class="reac-project">{{ item.introduction }}</div>
<div class="time">
报名时间:{{ item.starttime }}-{{ item.endtime }}
</div>
</div>
</div>
</div>
<el-card v-if="reacProjectList.length === 0">
<div
style="
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
color: #aaa;
"
>
<svgIcon name="race-none" width="200px" height="200px" />
<p>没有年度比赛~</p>
</div>
</el-card>
<!-- 年度比赛详细信息 -->
<div class="year-race-info">
<div class="left-info">
<el-card>
<template #header>
<el-breadcrumb>
<el-breadcrumb-item
v-for="item in Route.matched"
:key="item.path"
:to="{ path: item.path }"
>
{{ item.meta.title }}
</el-breadcrumb-item>
</el-breadcrumb>
<div style="display: flex; justify-content: space-between">
<el-breadcrumb>
<el-breadcrumb-item
v-for="item in Route.matched"
:key="item.path"
:to="{ path: item.path }"
>
{{ item.meta.title }}
</el-breadcrumb-item>
</el-breadcrumb>
<div>
<el-button @click="Router.back()">返回</el-button>
<el-button @click="scrollToPosition">查看详情</el-button>
</div>
</div>
</template>
<div>
<!-- {{ raceInfo }} -->
@ -75,15 +41,15 @@
<div class="label">比赛名称:</div>
<div class="text">{{ raceInfo.compName }}</div>
</li>
<li>
<li style="width: 40%">
<div class="label">负责人:</div>
<div class="text">{{ raceInfo.createBy }}</div>
</li>
<li>
<li style="width: 60%">
<div class="label">负责部门:</div>
<div class="text">{{ raceInfo.comporderc }}</div>
</li>
<li style="width: 33%">
<!-- <li style="width: 33%">
<div class="label">比赛类型:</div>
<div class="text">{{ raceInfo.compTypeId }}</div>
</li>
@ -94,13 +60,14 @@
<li style="width: 33%">
<div class="label">比赛内部排名:</div>
<div class="text">{{ raceInfo.compOrder }}</div>
</li>
</li> -->
</ul>
</div>
</div>
<div class="center">
<div class="label">比赛简介:</div>
<div class="deaceiption">
<!-- <div v-html="raceInfo.compDetail"></div> -->
{{ raceInfo.compInfo }}
<!-- 亲爱的同学们老师们以及各位编程爱好者们
在这个充满创新与挑战的时代一场精彩纷呈的大学生编程大赛即将拉开帷幕
@ -112,8 +79,14 @@
</div>
<div class="label">附件:</div>
<div class="file">
<el-tag type="primary" @click="doLoadFile(raceInfo.compFile)">
{{ raceInfo.compFile }}
<el-tag
v-for="item in fileList"
:key="item"
type="primary"
@click="doLoadFile(item)"
style="margin-right: 15px"
>
{{ item }}
</el-tag>
</div>
</div>
@ -127,15 +100,15 @@
<div class="description">往年历史赛事</div>
<el-scrollbar height="650px">
<ul>
<li v-for="item in historyRaceList" :key="item.id">
<li v-for="item in historyRaceList" :key="item.id" >
<div class="year">2024年度</div>
<div class="name">{{ item.name }}</div>
<div class="time">
报名时间:{{ item.starttime }} - {{ item.endtime }}
</div>
<div class="go-to" @click="goToCompetition(item.id)">
<!-- <div class="go-to" @click="goToCompetition(item.id)">
前往查看
</div>
</div> -->
<div class="icon">
<img src="../../assets/images/编组.png" alt="" srcset="" />
</div>
@ -145,33 +118,120 @@
</el-card>
</div>
</div>
<!-- 年度比赛列表 -->
<div style="margin-top: 30px; font-size: 24px; font-weight: 600">
年度比赛项目列表:
</div>
<el-card v-if="reacProjectList.length === 0" style="margin-top: 20px">
<div
style="
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
color: #aaa;
"
>
<svgIcon name="race-none" width="200px" height="200px" />
<p>没有年度比赛~</p>
</div>
</el-card>
<el-card style="margin-top: 20px" v-else>
<div class="race-list" v-loading="loading">
<div
class="item"
v-for="item in reacProjectList"
:key="item.id"
@click="goToCompetition(item.id, item.endtime,item.isopen)"
:style="{
'background-color': isTimePassed(item.endtime) ? 'rgb(232 232 232)' : '#fff',
}"
>
<div class="image">
<img :src="setImageUrl(item.image)" alt="" v-default-image />
</div>
<div class="reac-info">
<div class="niandu">
<div>{{ item.annualname }}年度</div>
<el-button type="primary" size="small">报名</el-button>
</div>
<div
class="reac-title"
style="font-weight: 600; color: #000; font-size: 16px;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;"
>
{{ item.objName }}
</div>
<div class="reac-title">负责部门{{ item.sysOrgCode }}</div>
<!-- <div class="reac-project">{{ item.introduction }}</div> -->
<div
class="time"
style="display: flex; justify-content: space-between"
>
<div>开始时间:{{ item.applyStartTime }}</div>
结束时间:{{ item.applyEndTime }}
<div></div>
</div>
<!-- <div class="time">
</div> -->
</div>
</div>
</div>
<div style="margin-top: 20px;display: flex;justify-content: center;">
<el-pagination background layout="prev, pager, next" :total="page.total" :page-size="page.pageSize" @change="pageChange"/>
</div>
</el-card>
<h3
style="margin-top: 20px; font-size: 24px; font-weight: 700"
id="introduction"
>
比赛详情
</h3>
<div class="race-description" v-html="raceInfo.compDetail"></div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import { getYearRaceList, getRaceInfo, getHistoryRaceList } from '@/api/race'
import {
getYearRaceList,
getRaceInfo,
getHistoryRaceList,
getProjectId,
} from '@/api/race'
import { useRouter, useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
import { pa } from 'element-plus/es/locales.mjs'
const Route = useRoute()
const Router = useRouter()
console.log(Route, 'Route')
const defaultImageUrl = '/src/assets/images/item.png'
const loading = ref(false)
const reacProjectList = ref<any>([])
const getRaceProjectListEvent = async () => {
let page = {
let page = ref<any>({
id: Route.query.id,
column: 'createTime',
order: 'desc',
pageNo: 1,
pageSize: 8,
}
const res: any = await getYearRaceList(page)
total: 0
})
const getRaceProjectListEvent = async () => {
loading.value = true
const res: any = await getYearRaceList(page.value)
console.log(res)
reacProjectList.value = res.result.slice(0, 8)
reacProjectList.value = res.result.records
page.value.total = res.result.total
console.log(reacProjectList.value, 'reacProjectList.value ')
loading.value = false
}
getRaceProjectListEvent()
const pageChange = (e:any) => {
page.value.pageNo = e
getRaceProjectListEvent()
}
const setImageUrl = (url: string) => {
return import.meta.env.VITE_APP_BASE_API + '/sys/common/static/' + url
}
@ -180,15 +240,35 @@ const raceInfo = ref<any>({})
const getraceInfoEvent = async () => {
const res: any = await getRaceInfo({ id: Route.query.id })
console.log(res)
createfileLink(res.result.compFile)
raceInfo.value = res.result
}
getraceInfoEvent()
//
const goToCompetition = (id: any) => {
Router.push({ path: '/competition', query: { id } })
const goToCompetition = async (id: any, endTime: string,isOpen:string) => {
if(isOpen == '0') return ElMessage.error('比赛未开启')
if (isTimePassed(endTime)) {
return ElMessage.error('比赛已结束')
}
const projectId: any = await getProjectId({ anncmopid: id })
console.log(projectId.result)
// return
Router.push(`/projectName?id=${projectId.result}&bcId=${id}`)
// Router.push({ path: '/competition', query: { id, raceId: Route.query.id } })
}
function isTimePassed(targetTime) {
//
const now = new Date()
// Date
const target = new Date(targetTime)
//
return now > target
}
const doLoadFile = (url: any) => {
// console.log( import.meta.env.VITE_APP_BASE_API + "/sys/common/static/" + url)
window.open(import.meta.env.VITE_APP_BASE_API + '/sys/common/static/' + url)
@ -202,6 +282,24 @@ const getHistoryRaceListEvent = async () => {
historyRaceList.value = res.result
}
getHistoryRaceListEvent()
const fileList = ref<any>([])
const createfileLink = (url: any) => {
console.log(url)
const list = url.split(',')
console.log(list)
fileList.value = list
}
const scrollToPosition = () => {
const targetPosition =
(document.getElementById('introduction') as HTMLElement).offsetTop - 100
window.scrollTo({
top: targetPosition,
behavior: 'smooth', //
})
}
</script>
<style lang="scss" scoped>
@ -223,7 +321,7 @@ getHistoryRaceListEvent()
grid-template-columns: repeat(4, 1fr);
// grid-template-rows: repeat(2, 1fr);
// gap: 10px;
margin-top: 40px;
// margin-top: 10px;
.item {
width: 340px;
height: 360px;
@ -262,7 +360,16 @@ getHistoryRaceListEvent()
.time {
font-size: 14px;
color: #8c8b8b;
margin-top: 40px;
margin-top: 30px;
}
.niandu {
color: #1e2033;
font-size: 18px;
margin-top: 20px;
font-weight: 600;
display: flex;
justify-content: space-between;
align-items: center;
}
}
}
@ -408,9 +515,25 @@ getHistoryRaceListEvent()
}
}
}
.race-description {
width: 100%;
font-size: 14px;
line-height: 22px;
border: 1px solid #ccc;
padding: 20px;
margin-top: 20px;
p {
img {
width: 100%;
}
}
}
}
:deep(.el-card) {
width: 100%;
height: 100%;
}
img {
width: 100%;
}
</style>

@ -13,7 +13,7 @@
@click="toDetail(item.id)"
>
<div class="image">
<img :src="setImageUrl(item.compImg)" alt="" v-default-image />
<img :src="setImageUrl(item.compImg)" alt="" />
</div>
<div class="reac-info">
<div class="reac-title">{{ item.compName }}</div>

@ -8,8 +8,17 @@
width="800"
draggable
overflow
:close-on-click-modal="false"
:before-close="closeDialog"
>
<div class="table-box">
<div class="search">
<el-row gutter="20">
<el-col :span="8"></el-col>
<el-col :span="12"><el-input placeholder="请输入学生学号" v-model="name"></el-input></el-col>
<el-col :span="4"><el-button type="primary" @click="search" >搜索</el-button></el-col>
</el-row>
</div>
<el-table
ref="multipleTableRef"
border
@ -18,6 +27,7 @@
append-to-body
class="table"
v-loading="loading"
style="margin-top: 20px"
>
<el-table-column label="选择" width="55">
<template #default="scope">
@ -48,7 +58,7 @@
/>
</div>
<div class="dialog-footer">
<el-button @click="$emit('update:modelValue', false)">关闭</el-button>
<el-button @click="closeDialog">关闭</el-button>
<el-button
type="primary"
@click="
@ -57,7 +67,8 @@
$emit(
'selected',
tableData.find((o) => o.id === selectedRowId) || {},
)
);
selectedRowId = null; // selectedRowId
}
"
>
@ -86,6 +97,7 @@ watch(
//
const tableData = reactive<any[]>([])
const selectedRowId = ref()
// const selectedRowId = ref<number | null>(null); // 使 null
//
const total = ref(0)
@ -96,13 +108,26 @@ const params = reactive<any>({
onlRepUrlParamStr: `annualCompid=${route.query.objName}`,
entryFormat: '团队',
id: route.query.id,
name: '',
})
const name = ref('')
//
const search = () => {
params.work_no="*"+name.value+"*"
getList()
}
//
const closeDialog = ()=>{
$emit('update:modelValue', false)
$emit('selected', {});
selectedRowId.value = null
}
const loading = ref(false)
const getList = async () => {
if (!props.modelValue) return
loading.value = true
try {
// const data =
const res: any = await getMembersList(params)
tableData.length = 0
tableData.push(...res.result.records)

@ -1,6 +1,12 @@
<template>
<div>
<el-button type="primary" icon="Plus" @click="add" class="btn">
<el-button
type="primary"
icon="Plus"
@click="add"
class="btn"
:disabled="isDisable"
>
新增
</el-button>
<el-button
@ -8,7 +14,7 @@
icon="Delete"
@click="del"
class="btn"
v-show="isSele"
:disabled="isDisable"
>
删除
</el-button>
@ -35,12 +41,7 @@
<span style="margin-left: 10px">用户</span>
</template>
<template #default="{ row }">
<el-input
@click="openDialog(row)"
v-model="row.realname"
placeholder="请选择"
:prefix-icon="ClusterOutlined"
/>
<el-input v-model="row.realname" :disabled="isDisable" />
</template>
</el-table-column>
<el-table-column>
@ -51,11 +52,50 @@
<span style="margin-left: 10px">是否队长</span>
</template>
<template #default="{ row }">
<el-cascader
:modelValue="row.captain"
@update:modelValue="(arr: any[]) => (row.captain = arr[0])"
:options="options"
<el-select v-model="row.captain" @update:modelValue="(arr:any[]) => {row.captain =arr[0]
}"
@change="()=>checkUniqueness(row)"
:options="options">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column>
<template #header>
<el-icon>
<Edit />
</el-icon>
<span style="margin-left: 10px">学号</span>
</template>
<template #default="{ row }">
<el-input v-model="row.workNo" :disabled="isDisable" />
</template>
</el-table-column>
<el-table-column>
<template #header>
<el-icon>
<Edit />
</el-icon>
<span style="margin-left: 10px">手机号</span>
</template>
<template #default="{ row }">
<el-input v-model="row.phone" :disabled="isDisable" />
</template>
</el-table-column>
<el-table-column>
<template #header>
<el-icon>
<Edit />
</el-icon>
<span style="margin-left: 10px">邮箱</span>
</template>
<template #default="{ row }">
<el-input v-model="row.email" :disabled="isDisable" />
</template>
</el-table-column>
<el-table-column>
@ -66,7 +106,7 @@
<span style="margin-left: 10px">队员序号</span>
</template>
<template #default="{ row }">
<el-input v-model="row.teamSeq" />
<el-input v-model="row.teamSeq" :disabled="isDisable" />
</template>
</el-table-column>
</el-table>
@ -76,10 +116,18 @@
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import { reactive, ref, onMounted, watch } from 'vue'
import stuDialog from './stuDialog.vue'
import { ClusterOutlined } from '@ant-design/icons-vue'
import { ElMessage } from 'element-plus'
import userStore from '@/store/module/user'
import { getTeamList } from '@/api/oldRace'
import { useRoute } from 'vue-router'
const route = useRoute()
const userModel = userStore()
//
const isDisable = ref(false)
isDisable.value = route.query.info as any
const options = [
{
value: '1',
@ -90,16 +138,69 @@ const options = [
label: '否',
},
]
//
const checkUniqueness = (row:any) =>{
//tableDate
const count = tableData.filter(item => item.captain === '1').length
if(count === 2){
ElMessage({
message:'已有队长人选!',
type:'error'
})
row.captain = '0'
}else if(count === 0){
ElMessage({
message:'请选择队长人选!',
type:'error'
})
}
}
//
const tableData = reactive<any[]>([])
onMounted(() => {
if (route.query.edit) {
const getTeamListEvent = async () => {
const res: any = await getTeamList({ id: route.query.id })
console.log(res, 'res~~~')
res.result.forEach((item: any) => {
tableData.push(item)
})
}
getTeamListEvent()
return
}
if (tableData.length === 1) return
setTimeout(() => {
tableData.push({
userId: userModel.userInfo.id,
realname: userModel.userInfo.realname,
workNo: userModel.userInfo.workNo,
phone: userModel.userInfo.phone,
email: userModel.userInfo.email,
captain: '1',
teamSeq: 1,
})
}, 500)
})
// watch(()=>userModel.userInfo,()=>{
// if(tableData.length === 1) return
// tableData.push({
// userId: userModel.userInfo.id,
// realname: userModel.userInfo.realname,
// captain: '1',
// teamSeq: 1,
// })
// })
const add = () => {
const length = tableData.push({
realname: '', //
captain: '', //
teamSeq: '', //
captain: '0', //
teamSeq: tableData.length + 1, //
userId: '', // id
workNo: '',
phone: '',
email: '',
})
openDialog(tableData[length - 1])
}
@ -107,6 +208,8 @@ const add = () => {
// dialogdialog
const target = ref<any>()
const openDialog = (row: any) => {
// console.log(row,'row');
visible.value = true
target.value = row
}
@ -115,14 +218,23 @@ const visible = ref(false)
//
const handleSelected = (row: any = {}) => {
// tableData
if (Object.keys(row).length === 0) {
if (tableData.length > 0) {
tableData.pop(); //
}
}
if (tableData.some((o) => o.userId === row.id)) {
ElMessage({
message: '用户不能多选!',
message: '已有该用户,不能重复选择用户!',
type: 'error',
})
return
tableData.pop(); //
}
console.log(row, 'aqq')
target.value.workNo = row.work_no
target.value.phone = row.phone
target.value.email = row.email
target.value.realname = row.realname
target.value.userId = row.id
}
@ -135,6 +247,13 @@ const multipleTableRef = ref<any>(null)
const isSele = ref(false)
const del = () => {
const rows = multipleTableRef.value.getSelectionRows()
console.log(rows, '111')
if (rows.length === 0) {
return ElMessage({
message: '请选择要删除的成员',
type: 'error',
})
}
rows.forEach((row: any) => {
const index = tableData.indexOf(row)
if (index === -1) return

@ -9,8 +9,11 @@
width="1000"
draggable
overflow
:close-on-click-modal="false"
:before-close="closeDialog"
>
<div class="table-box">
<el-table
ref="multipleTableRef"
border
@ -52,7 +55,7 @@
<template #footer>
<div class="dialog-footer">
<el-button @click="$emit('update:modelValue', false)">关闭</el-button>
<el-button @click="closeDialog">关闭</el-button>
<el-button
type="primary"
@click="
@ -61,7 +64,8 @@
$emit(
'selected',
tableData.find((o) => o.user_id === selectedRowId) || {},
)
);
selectedRowId = null; // selectedRowId
}
"
>
@ -90,6 +94,12 @@ watch(
//
const tableData = reactive<any[]>([])
const selectedRowId = ref()
//
const closeDialog = ()=>{
$emit('update:modelValue', false)
$emit('selected', {});
selectedRowId.value = null
}
//
const total = ref(0)

@ -1,6 +1,6 @@
<template>
<div>
<el-button type="primary" icon="Plus" @click="add" class="btn">
<el-button type="primary" icon="Plus" @click="add" class="btn" :disabled="isDisable">
新增
</el-button>
<el-button
@ -8,7 +8,7 @@
icon="Delete"
@click="del"
class="btn"
v-show="isSele"
:disabled="isDisable"
>
删除
</el-button>
@ -35,6 +35,7 @@
</template>
<template #default="{ row }">
<el-cascader
:disabled="isDisable"
:modelValue="row.teacherType"
@update:modelValue="(arr: any[]) => (row.teacherType = arr[0])"
:options="options"
@ -49,12 +50,7 @@
<span style="margin-left: 10px">指导老师姓名</span>
</template>
<template #default="{ row }">
<el-input
@click="openDialog(row)"
v-model="row.teacherName"
placeholder="请选择"
:prefix-icon="ClusterOutlined"
/>
<el-input v-model="row.teacherName" placeholder="请输入指导老师姓名" :disabled="isDisable"/>
</template>
</el-table-column>
<el-table-column>
@ -65,7 +61,7 @@
<span style="margin-left: 10px">学历</span>
</template>
<template #default="{ row }">
<el-input v-model="row.teacherXl" placeholder="请输入学历" />
<el-input v-model="row.teacherXl" placeholder="请输入学历" :disabled="isDisable"/>
</template>
</el-table-column>
<el-table-column>
@ -76,7 +72,7 @@
<span style="margin-left: 10px">职称</span>
</template>
<template #default="{ row }">
<el-input v-model="row.teacherZc" placeholder="请输入职称" />
<el-input v-model="row.teacherZc" placeholder="请输入职称" :disabled="isDisable"/>
</template>
</el-table-column>
<el-table-column>
@ -87,7 +83,7 @@
<span style="margin-left: 10px">专业</span>
</template>
<template #default="{ row }">
<el-input v-model="row.teacherZy" placeholder="请输入专业" />
<el-input v-model="row.teacherZy" placeholder="请输入专业" :disabled="isDisable"/>
</template>
</el-table-column>
<el-table-column>
@ -98,7 +94,7 @@
<span style="margin-left: 10px">研究方向</span>
</template>
<template #default="{ row }">
<el-input v-model="row.teacherYjfx" placeholder="请输入研究方向" />
<el-input v-model="row.teacherYjfx" placeholder="请输入研究方向" :disabled="isDisable"/>
</template>
</el-table-column>
<el-table-column>
@ -109,7 +105,7 @@
<span style="margin-left: 10px">手机号</span>
</template>
<template #default="{ row }">
<el-input v-model="row.teacherPhone" placeholder="请输入手机号" />
<el-input v-model="row.teacherPhone" placeholder="请输入手机号" :disabled="isDisable"/>
</template>
</el-table-column>
</el-table>
@ -119,10 +115,17 @@
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import { reactive, ref ,onMounted} from 'vue'
import teaDialog from './teaDialog.vue'
import { ClusterOutlined } from '@ant-design/icons-vue'
import { ElMessage } from 'element-plus'
import {getTeacherList} from '@/api/oldRace'
import { useRoute } from 'vue-router'
const route = useRoute()
const isDisable = ref(false)
isDisable.value = route.query.info as any
const options = [
{
value: '1',
@ -136,12 +139,28 @@ const options = [
//
const tableData = reactive<any[]>([])
onMounted(async() => {
if (route.query.edit) {
const res:any = await getTeacherList({ id: route.query.id})
res.result.forEach((item: any) => {
tableData.push({
teacherName: item.teacherName,
teacherPhone: item.teacherPhone,
teacherType: item.teacherType.toString(),
teacherXl: item.teacherXl,
teacherYjfx: item.teacherYjfx,
teacherZc: item.teacherZc,
teacherZy: item.teacherZy,
teacherid: item.teacherid,
})
})
}
})
const add = () => {
const length = tableData.push({
teacherName: '',
teacherPhone: '',
teacherType: '',
teacherType: '1',
teacherXl: '',
teacherYjfx: '',
teacherZc: '',
@ -164,10 +183,16 @@ const visible = ref(false)
const handleSelected = (row: any = {}) => {
if (tableData.some((o) => o.teacherid === row.user_id)) {
ElMessage({
message: '用户不能多选!',
message: '已有该用户,不能重复选择用户!',
type: 'error',
})
return
tableData.pop(); //
}
// tableData
if (Object.keys(row).length === 0) {
if (tableData.length > 0) {
tableData.pop(); //
}
}
target.value.teacherName = row.realname
target.value.teacherXl = row.exp_title

@ -5,11 +5,7 @@
<div class="box">
<div class="title-box">
<div class="title">报名信息确认</div>
<div class="text">
请仔细核对报名信息报名成功后无法修改请仔细核对报名信息报名成功后无法修改
请仔细核对报名信息报名成功后无法修改请仔细核对报名信息报名成功后无法修改
请仔细核对报名信息报名成功后无法修改请仔细核对报名信息报名成功后无法修改
</div>
<div class="text">请仔细核对报名信息报名成功后无法修改</div>
</div>
<div class="img-box">
@ -21,20 +17,20 @@
<div class="top">
<!-- 比赛信息 -->
<el-card class="com">
<div class="title">比赛信息</div>
<div class="title">年度比赛信息</div>
<div class="content">
<div class="card-annual padding">
<div class="annual">{{ ndbs.annualid }}年度</div>
<div class="title-box">
<div class="text">{{ ndbs.name }}</div>
<img src="../../assets/images/编组.png" alt="" />
<img style="width: 35px;" src="../../assets/images/编组.png" alt="" />
</div>
</div>
<div class="right">
<div class="info-box">
<div class="name">比赛年度</div>
<div class="title">{{ ndbs.annualid }}年度</div>
<div class="name">比赛名称</div>
<div class="name">年度比赛名称</div>
<div class="title">{{ ndbs.name }}</div>
<div class="date-box">
<div class="label">开始报名时间</div>
@ -48,31 +44,6 @@
</div>
</div>
</el-card>
<!-- 项目信息 -->
<el-card class="com">
<div class="title">项目信息</div>
<div class="content track">
<div class="card-annual padding">
<p>{{ ndbsXm.objName }}</p>
</div>
<div class="right">
<div class="info-box">
<div class="name">项目名称</div>
<div class="title">{{ ndbsXm.objName }}</div>
<div class="name">要求人数</div>
<div class="title">{{ ndbsXm.workCount }}</div>
<div class="date-box">
<div class="label">开始报名时间</div>
<div class="date">{{ ndbsXm.starttime?.split(' ')[0] }}</div>
</div>
<div class="date-box">
<div class="label">开始截至时间</div>
<div class="date">{{ ndbsXm.endtime?.split(' ')[0] }}</div>
</div>
</div>
</div>
</div>
</el-card>
</div>
<el-card class="center">
<div class="personage-info">
@ -117,15 +88,25 @@
label-width="auto"
class="demo-ruleForm"
>
<el-form-item label="年度比赛项目">
<el-input v-model="ruleForm.annualCompid" type="text" disabled />
<el-form-item label="年度比赛">
<el-input v-model="ruleForm.objName" type="text" disabled />
</el-form-item>
<el-form-item label="参赛形式">
<el-input v-model="ruleForm.entryFormat" type="text" disabled />
</el-form-item>
<el-form-item label="队伍名称" prop="teamName">
<el-input v-model.number="ruleForm.teamName" />
<el-input v-model="ruleForm.teamName" maxlength="30" type="text" :disabled="isDisable"/>
</el-form-item>
<!-- <el-form-item label="选择题目" prop="topicid" v-show="false">
<el-select v-model="ruleForm.topicid" placeholder="请选择题目" :disabled="isDisable">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>-->
</el-form>
</div>
@ -144,16 +125,17 @@
</div>
</el-card>
<div class="bottom">
<el-button class="btn" @click="$router.push('/')">取消报名</el-button>
<el-button class="btn cyan" @click="submit" :loading="loading">
确认报名
<el-button class="btn" @click="$router.back()">{{ isDisable ? '返回' : isEdit ? '取消修改' : '返回' }}</el-button>
<el-button class="btn temp" @click="submit('2')" v-if="!isDisable">暂存信息</el-button>
<el-button class="btn cyan" :loading="loading" @click="submit('1')" v-if="!isDisable">
{{ isEdit ? '确认修改' : '确认报名' }}
</el-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, toRefs } from 'vue'
import { reactive, ref, toRefs, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import userStore from '@/store/module/user'
import type { FormInstance, FormRules } from 'element-plus'
@ -161,10 +143,16 @@ import { ElMessage } from 'element-plus'
import { getSignUpApi } from '@/api/person'
import stuList from './components/stuList.vue'
import teaList from './components/teaList.vue'
import { getNdbswxqList, getComppxqList } from '@/api/person'
import { getNdbswxqList } from '@/api/person'
import { getOldRaceList,getOldRaceInfo } from '@/api/oldRace'
import { getTopicList } from '@/api/race'
const user = userStore()
const route = useRoute()
const router = useRouter()
const isDisable = ref(false)
isDisable.value = route.query.info as any
const isEdit = ref(false)
isEdit.value = route.query.edit as any
//
const { userInfo: info } = toRefs(user)
@ -175,16 +163,56 @@ function pasSex(num: number) {
else return '保密'
}
//
//
const ndbs = ref<any>({})
const ndbsXm = ref<any>({})
getNdbswxqList(route.query.bcId as string).then((res: any) => {
if (res.result) ndbs.value = res.result
})
getComppxqList(route.query.id as string).then((res: any) => {
console.log(res.result, 'xm')
if (res.result) ndbsXm.value = res.result
})
console.log(route.query.edit, 'route.query.edit')
const options = ref([])
if (route.query.edit) {
const getOldRaceListEvent = async () => {
const res: any = await getOldRaceList({ id: route.query.id})
ndbs.value = res.result.annualComp
}
const getOldRaceInfoEvent = async () => {
const res: any = await getOldRaceInfo({ id: route.query.id})
// ruleForm.annualCompid = route.query.annualCompid
ruleForm.teamName = res.result.teamName
ruleForm.topicid = res.result.topicObj ? res.result.topicObj.id : ''
ruleForm.objName = res.result.annualCompPointName
options.value = res.result.topicList.map((item) => {
return {
value: item.id,
label: item.name,
}
})
}
getOldRaceListEvent()
getOldRaceInfoEvent()
} else {
getNdbswxqList(route.query.bcId as string).then((res: any) => {
if (res.result) ndbs.value = res.result
})
// const getTopicListApi = async () => {
// const res: any = await getTopicList({ annualCompid: route.query.id })
// console.log(res)
// nextTick(() => {
// if (res.result.length != 0) {
// ruleForm.topicid = res.result[0].id
// }
// })
// options.value = res.result.map((item) => {
// return {
// value: item.id,
// label: item.name,
// }
// })
// }
// getTopicListApi()
}
// members: adviser:
const activeName = ref('members')
@ -193,12 +221,13 @@ const activeName = ref('members')
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive<any>({
annualCompid: route.query.objName,
// annualCompid:'' ,
entryFormat: '团队',
id: route.query.id,
teamName: '', //
instructorSheetList: [], //
teamManagementList: [], //
objName:route.query.objName
})
const rules = reactive<FormRules<typeof ruleForm>>({})
@ -207,17 +236,33 @@ const stuRef = ref<any>(null)
const teaRef = ref<any>(null)
const loading = ref(false)
const submit = () => {
const submit = (substa:string) => {
if (!ruleForm.teamName) return ElMessage.warning('请输入队伍名称')
ruleForm.instructorSheetList = [...teaRef.value.submit()]
ruleForm.teamManagementList = [...stuRef.value.submit()]
loading.value = true
ruleForm.substa = substa
ruleForm.id = route.query.id
// ruleForm.annualCompid = route.query.id
if(route.query.edit){
ruleForm.enrollCode = route.query.enrollCode
ruleForm.id = route.query.annualCompid
}
// ruleForm.substa = "1"
getSignUpApi(ruleForm)
.then((res: any) => {
if(substa == '1'){
loading.value = true
ElMessage({
message: isEdit.value ? '修改成功' : '报名成功',
type: 'success',
})
}else{
ElMessage({
message: res?.message || '报名成功',
message: '暂存成功',
type: 'success',
})
router.push('/')
}
router.push('/user-info')
})
.catch((err) => {
ElMessage({
@ -227,6 +272,7 @@ const submit = () => {
})
.finally(() => (loading.value = false))
}
</script>
<style lang="scss" scoped>
@ -323,7 +369,7 @@ const submit = () => {
height: 300px;
.com {
width: 685px;
width: 100%;
height: 300px;
border-radius: 6px 6px 6px 6px;
padding-top: 22px;
@ -341,7 +387,6 @@ const submit = () => {
margin-bottom: 18px;
}
margin-right: 22px;
.content {
display: flex;
@ -380,13 +425,18 @@ const submit = () => {
font-size: 32px;
color: #ffffff;
line-height: 39px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; /* 限制显示的行数 */
overflow: hidden;
text-overflow: ellipsis;
}
}
}
.right {
.info-box {
width: 210px;
width: 100%;
.name {
height: 20px;
font-family:

@ -19,20 +19,20 @@
<div class="top">
<!-- 比赛信息 -->
<el-card class="com">
<div class="title">比赛信息</div>
<div class="title">年度比赛信息</div>
<div class="content">
<div class="card-annual padding">
<div class="annual">{{ ndbs.annualid }}年度</div>
<div class="title-box">
<div class="text">{{ ndbs.name }}</div>
<img src="../../assets/images/编组.png" alt="" />
<img style="width: 35px" src="../../assets/images/编组.png" alt="" />
</div>
</div>
<div class="right">
<div class="info-box">
<div class="name">比赛年度</div>
<div class="title">{{ ndbs.annualid }}年度</div>
<div class="name">比赛名称</div>
<div class="name">年度比赛名称</div>
<div class="title">{{ ndbs.name }}</div>
<div class="date-box">
<div class="label">开始报名时间</div>
@ -46,32 +46,20 @@
</div>
</div>
</el-card>
<!-- 项目信息 -->
<el-card class="com">
<div class="title">项目信息</div>
<div class="content track">
<div class="card-annual padding">
<p>{{ ndbsXm.objName }}</p>
</div>
<div class="right">
<div class="info-box">
<div class="name">项目名称</div>
<div class="title">{{ ndbsXm.objName }}</div>
<div class="name">要求人数</div>
<div class="title">{{ ndbsXm.workCount }}</div>
<div class="date-box">
<div class="label">开始报名时间</div>
<div class="date">{{ ndbsXm.starttime?.split(' ')[0] }}</div>
</div>
<div class="date-box">
<div class="label">开始截至时间</div>
<div class="date">{{ ndbsXm.endtime?.split(' ')[0] }}</div>
</div>
</div>
</div>
</div>
</el-card>
</div>
<el-card>
<div>
<el-form ref="ruleFormRef" style="max-width: 600px" :model="ruleForm" status-icon label-width="auto"
class="demo-ruleForm">
<el-form-item label="年度比赛">
<el-input v-model="ruleForm.objName" type="text" disabled />
</el-form-item>
<el-form-item label="参赛形式">
<el-input v-model="ruleForm.entryFormat" type="text" disabled />
</el-form-item>
</el-form>
</div>
</el-card>
<el-card class="center">
<div class="personage-info">
<div class="head">
@ -104,12 +92,12 @@
<div class="label">邮箱</div>
<div class="text">{{ info.email }}</div>
</div>
<div class="info-box">
<!-- <div class="info-box">
<div class="label">队伍名称</div>
<div class="text">
<el-input v-model="upData.teamName"></el-input>
</div>
</div>
</div> -->
<!-- <div class="info-box">
<div class="label">院系</div>
<div class="text">国际教育学院</div>
@ -138,30 +126,64 @@
</el-card>
<div class="bottom">
<el-button class="btn" @click="() => router.push('/')">
取消报名
<el-button class="btn" @click="() => router.back()">
{{ isDisable ? '返回' : isEdit ? '取消修改' : '返回' }}
</el-button>
<el-button class="btn cyan" :loading="subLoading" @click="submit">
确认报名
<el-button class="btn temp" @click="submit('2')" v-if="!isDisable">暂存信息</el-button>
<el-button class="btn cyan" :loading="subLoading" @click="submit('1')" v-if="!isDisable">
{{ isEdit ? '确认修改' : '确认报名' }}
</el-button>
</div>
</div>
<el-dialog v-model="dialogVisible" title="上传作品" width="500" :before-close="handleClose" v-if="dialogVisible"
:close-on-click-modal="false">
<el-form label-width="80" style="padding-right: 30px">
<el-form-item label="作品名称">
<el-input v-model="raceName" />
</el-form-item>
<el-form-item label="作品">
<el-upload ref="upload" class="upload-demo" action="#" v-model:file-list="fileList" :limit="1"
:auto-upload="false">
<template #trigger>
<el-button type="primary">选择文件</el-button>
</template>
<template #tip>
<div class="el-upload__tip text-red">作品只允许上传一个,格式为{{ndbs.uploadWorksType}}</div>
</template>
</el-upload>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="submitWork">确认</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref, toRefs } from 'vue'
import { ref, toRefs, reactive, nextTick } from 'vue'
import { getSignUpApi } from '@/api/person'
import { ElMessage } from 'element-plus'
import { useRoute, useRouter } from 'vue-router'
import userStore from '@/store/module/user'
import { getNdbswxqList, getComppxqList } from '@/api/person'
import { getOldRaceList, getOldRaceInfo } from '@/api/oldRace'
import { getTopicList, uploadFileZp, uploadFile } from '@/api/race'
const user = userStore()
const route = useRoute()
const router = useRouter()
const { userInfo: info } = toRefs(user)
const isDisable = ref(false)
isDisable.value = route.query.info as any
const isEdit = ref(false)
isEdit.value = route.query.edit as any
//
function pasSex(num: number) {
if (num == 1) return '男'
@ -173,42 +195,91 @@ function pasSex(num: number) {
const upData = ref<Parameters<typeof getSignUpApi>[0]>({
annualCompid: route.query.objName as string,
entryFormat: '个人',
id: route.query.id,
id: route.query.edit ? route.query.annualCompid : route.query.id,
instructorSheetList: [],
teamManagementList: [{ realname: '', captain: '', teamSeq: '', userId: '' }],
teamName: '',
teamManagementList: [{ realname: '', captain: '1', teamSeq: '', userId: '' }],
// WorkName:WorkName.value,
// file:fileUrl.value
})
//
//
const dialogVisible = ref(false)
const fileList = ref<any>([])
const annualCompid = ref('')
const raceName = ref<any>('')
const uploadZp = (id: any) => {
annualCompid.value = id
dialogVisible.value = true
}
const handleClose = () => {
dialogVisible.value = false
fileList.value = []
raceName.value = ''
annualCompid.value = ''
}
const WorkName = ref<string>('')
// const fileUrl = ref<string>('')
const fileUrl = ref<string[]>([]);
const submitWork = async () => {
if (!raceName.value) return ElMessage.warning('请输入作品名称')
if (!fileList.value.length) return ElMessage.warning('请上传作品')
const fromData = new FormData()
fromData.append('annualCompid', annualCompid.value)
fromData.append('file', fileList.value[0].raw)
// fileUrl.value = fileList.value[0].raw.name
fromData.append('workName', raceName.value)
const res: any = await uploadFile(fromData)
if (res && Array.isArray(res.message)) {
fileUrl.value = res.message;
} else {
fileUrl.value = [res.message];
}
WorkName.value = raceName.value;
handleClose();
};
// fromData.append('annualCompid', annualCompid.value)
// fromData.append('workName', raceName.value)
// const res: any = await uploadFileZp(fromData).then((res: any) => {
// console.log(res)
// if (res.code == 500) return ElMessage.warning(res.message)
// ElMessage.success(res.message)
// })
// console.log(res)
//
const ndbs = ref<any>({})
const ndbsXm = ref<any>({})
getNdbswxqList(route.query.bcId as string).then((res: any) => {
if (res.result) ndbs.value = res.result
})
getComppxqList(route.query.id as string).then((res: any) => {
console.log(res.result, 'xm')
if (res.result) ndbsXm.value = res.result
})
const subLoading = ref(false)
async function submit() {
async function submit(substa:string) {
upData.value.teamManagementList[0].realname = info.value.realname
upData.value.teamManagementList[0].userId = info.value.id
if (!upData.value.teamName) {
ElMessage({
message: '队伍名称不能为空',
type: 'warning',
})
return
}
upData.value.annualCompid = route.query.annualCompid
upData.value.workName = WorkName.value
upData.value.files = fileUrl.value
upData.value.substa = substa
try {
subLoading.value = true
const res: any = await getSignUpApi(upData.value)
ElMessage({
message: res?.message || res?.result || '报名成功',
type: 'success',
})
const res: any = await getSignUpApi({ ...upData.value })
if(substa == '1'){
subLoading.value = true
ElMessage({
message: isEdit.value ? '修改成功' : '报名成功',
type: 'success',
})
}else{
ElMessage({
message: '暂存成功',
type: 'success',
})
}
router.push('/user-info')
} catch (error) {
ElMessage({
// @ts-ignore
@ -219,6 +290,56 @@ async function submit() {
subLoading.value = false
}
}
// form
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive<any>({
annualCompid: '',
entryFormat: '个人',
id: route.query.id,
topicid: '',
objName: route.query.objName,
// requireUploadWorks: ndbsXm.requireUploadWorks,
raceName: WorkName.value,
fileUrl: fileUrl.value
})
const options = ref([])
if (route.query.edit) {
const getOldRaceListEvent = async () => {
const res: any = await getOldRaceList({ id: route.query.id })
ndbs.value = res.result.annualComp
}
const getOldRaceInfoEvent = async () => {
const res: any = await getOldRaceInfo({ id: route.query.id })
ruleForm.annualCompid = route.query.annualCompid
ruleForm.teamName = res.result.teamName
ruleForm.requireUploadWorks = res.result.requireUploadWorks
ruleForm.objName = res.result.annualCompPointName
}
getOldRaceListEvent()
getOldRaceInfoEvent()
} else {
getNdbswxqList(route.query.bcId as string).then((res: any) => {
if (res.result) ndbs.value = res.result
})
}
/*const getTopicListApi = async () => {
const res: any = await getTopicList({ annualCompid: route.query.id })
nextTick(() => {
if (res.result.length != 0) {
ruleForm.topicid = res.result[0].id
}
})
options.value = res.result.map((item) => {
return {
value: item.id,
label: item.name,
}
})
}
getTopicListApi()*/
</script>
<style lang="scss" scoped>
@ -285,7 +406,7 @@ async function submit() {
margin: 0 auto;
width: 1397px;
& > * {
&>* {
background: #ffffff;
}
@ -296,7 +417,7 @@ async function submit() {
height: 300px;
.com {
width: 685px;
width: 100%;
height: 300px;
border-radius: 6px 6px 6px 6px;
padding-top: 22px;
@ -314,7 +435,6 @@ async function submit() {
margin-bottom: 18px;
}
margin-right: 22px;
.content {
display: flex;
@ -353,13 +473,20 @@ async function submit() {
font-size: 32px;
color: #ffffff;
line-height: 39px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
/* 限制显示的行数 */
overflow: hidden;
text-overflow: ellipsis;
}
}
}
.right {
.info-box {
width: 210px;
width: 100%;
.name {
height: 20px;
font-family:
@ -553,6 +680,11 @@ async function submit() {
--color1: #00d0d0;
--color2: #42d9ac;
}
&.temp {
// --color1: #b9e63f;
--color2: #FFA500;
}
}
}
}

@ -95,6 +95,7 @@ const dialogVisible = ref(false)
const tableData = ref<any>([])
const getAwardListApi = async () => {
const data = {
acpid: '',
column: 'createTime',
order: 'desc',
pageNo: 1,
@ -102,7 +103,7 @@ const getAwardListApi = async () => {
}
const res: any = await getAwardslist(data)
tableData.value = res.result.records
console.log(tableData.value, 'tableData.value')
// console.log(tableData.value, 'tableData.value')
}
getAwardListApi()
const setImageUrl = (url: string) => {

@ -0,0 +1,242 @@
<template>
<div class="container">
<el-card>
<template #header>
<div style="font-size: 16px; font-weight: 600">我的比赛</div>
</template>
<el-table :data="list" v-loading="isLoading" >
<el-table-column
label="年度比赛名称"
prop="compName"
/>
<!-- <el-table-column
label="年度比赛项目名称"
prop="annualCompid_dictText"
/> -->
<el-table-column label="比赛类型" prop="entryFormat" />
<el-table-column label="报名编号" prop="enrollCode" />
<el-table-column label="比赛状态" prop="enrollStatic_dictText" />
<el-table-column label="操作" prop="fileName">
<template #default="{ row }">
<div class="action-buttons">
<el-button
link
type="primary"
size="small"
@click="saveEvent(row.enrollCode)"
v-if="row.enrollStatic == '0' || row.enrollStatic == '3'"
>
提交
</el-button>
<el-button
link
type="primary"
size="small"
@click="editEvent(row.id,row.annualCompid,row.enrollCode,row.entryFormat)"
v-if="row.enrollStatic == '0' || row.enrollStatic == '3'"
>
编辑
</el-button>
<el-button
link
type="primary"
size="small"
@click="InfoEvent(row.id,row.annualCompid,row.enrollCode,row.entryFormat)"
>
详情
</el-button>
<el-button
link
type="warning"
size="small"
v-if="row.enrollStatic == '1'"
@click="cancelEvent(row.id)"
>
取消
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination
background
layout="prev, pager, next"
@change="headerChange"
:size="page.pageSize"
:total="total"
/>
</div>
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getStuRaceList, uploadFileZp, sava ,cancelRace} from '@/api/race'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
const router = useRouter()
const list = ref<any>([])
const page = ref<any>({
pageNo: 1,
pageSize: 10,
})
const total = ref(0)
const isLoading = ref(false)
const getList = async () => {
isLoading.value = true
const res: any = await getStuRaceList(page.value)
list.value = res.result.records
total.value = res.result.total
isLoading.value = false
}
getList()
const fileList = ref<any>([])
const raceName = ref<any>('')
const dialogVisible = ref(false)
const annualCompid = ref('')
const uploadZp = (id: any, staus: any) => {
if (staus != 2) return ElMessage.warning('审核后方可上传作品')
//console.log(id)
annualCompid.value = id
dialogVisible.value = true
}
const handleClose = () => {
dialogVisible.value = false
fileList.value = []
raceName.value = ''
annualCompid.value = ''
}
const submit = async () => {
const fromData = new FormData()
fromData.append('files', fileList.value[0].raw)
fromData.append('annualCompid', annualCompid.value)
fromData.append('workName', raceName.value)
const res: any = await uploadFileZp(fromData).then((res: any) => {
if (res.code == 500) return ElMessage.warning(res.message)
ElMessage.success(res.message)
})
handleClose()
getList()
}
const headerChange = (pageNumber: any) => {
page.value.pageNo = pageNumber
getList()
}
const saveEvent = async (id: any) => {
const res: any = await sava({ applyCode: id, status: 5 })
ElMessage.success(res.message)
getList()
}
const formatstatus = (status: any) => {
if (!status) return '未上传作品'
switch (status) {
case '0':
return '待评分'
break
case '1':
return '已评分'
break
case '2':
return '待驳回'
break
case '3':
return '已驳回'
break
case '4':
return '待提交'
break
case '5':
return '已提交'
break
}
}
const editEvent = (id: any,annualCompid: any,enrollCode:any,entryFormat:any) => {
if(entryFormat == '团队'){
router.push({
path: '/registrationGroup',
query:{
id,
annualCompid,
enrollCode,
edit: true
}
})
}else{
router.push({
path: 'registrationPersonage',
query:{
id,
annualCompid,
enrollCode,
edit: true
}
})
}
}
const InfoEvent = (id: any,annualCompid: any,enrollCode:any,entryFormat:any) => {
if(entryFormat == '团队'){
router.push({
path: '/registrationGroup',
query:{
id,
annualCompid,
enrollCode,
edit: true,
info: true
}
})
}else{
router.push({
path: 'registrationPersonage',
query:{
id,
annualCompid,
enrollCode,
edit: true,
info: true
}
})
}
}
const cancelEvent = async (id: any) => {
const res: any = await cancelRace({id })
ElMessage.success(res.message)
getList()
}
</script>
<style scoped lang="scss">
.action-buttons {
display: flex;
justify-content: space-between; /* 平均分布间距 */
align-items: center;
}
.container {
margin-top: 25px;
.page {
display: flex;
margin-top: 20px;
justify-content: center;
}
}
:deep(.el-table__row) {
height: 50px;
}
:deep(.el-button){
margin-left: 0px !important;
}
</style>

@ -31,11 +31,15 @@
/>
</div>
</div>
<div class="info-box">
<div class="label">账号</div>
<div class="text">{{ useUserStore.userInfo.username }}</div>
</div>
<div class="info-box">
<div class="label">姓名</div>
<div class="text">{{ useUserStore.userInfo.realname }}</div>
</div>
<div class="info-box">
<div class="label">姓别</div>
@ -68,7 +72,7 @@
</div>
</div>
</div>
<div class="right">
<!-- <div class="right">
<div
class="personalAbilityEvaluationCollectList gradient"
@click="Router.push('/personalAbilityEvaluationCollectList')"
@ -87,10 +91,12 @@
>
个人能力报告
</div>
</div>
</div> -->
</div>
</el-card>
<reacList />
<awardeList />
</div>
<el-dialog
v-model="dialogVisible"
@ -99,7 +105,7 @@
width="35%"
:before-close="handleClose"
>
<el-form :model="form" label-width="80" style="padding-right: 30px">
<el-form :model="form":rules="rules" ref="ruleFormRef" label-width="80" style="padding-right: 30px">
<el-form-item label="头像">
<el-upload
v-model:file-list="fileList"
@ -113,6 +119,9 @@
<el-form-item label="姓名">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="学号" prop="workno">
<el-input v-model="form.workNo" />
</el-form-item>
<!-- <el-form-item label="部门">
<el-cascader
:props="props"
@ -134,10 +143,10 @@
<el-radio :value="0" size="large"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="邮箱">
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" />
</el-form-item>
<el-form-item label="手机号">
<el-form-item label="手机号" prop="phone">
<el-input v-model="form.phone" type="number" />
</el-form-item>
</el-form>
@ -152,22 +161,44 @@
<script lang="ts" setup>
import { nextTick, onMounted, reactive, ref, toRefs, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
import userStore from '@/store/module/user'
import { getFaculties, uploadFile, editUserInfoApi } from '@/api/race'
import awardeList from './components/awardeList.vue'
import reacList from './components/reacList.vue'
const useUserStore = userStore()
const userInfo = ref<any>({})
console.log(useUserStore.userInfo, 'useUserStore')
userInfo.value = useUserStore.userInfo
const Router = useRouter()
const dialogVisible = ref(false)
const ruleFormRef = ref<any>()
const rules = {
workno: [
// { required: true, message: '/', trigger: 'blur' },
{
pattern: /^[a-zA-Z0-9]{1,20}$/,
message: '工号/学号为1-20位数字或字母',
trigger: 'blur',
},
],
phone: [
// { required: true, message: '', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' },
],
email: [
// { required: true, message: '', trigger: 'blur' },
{ type: 'email', message: '请输入有效的邮箱地址', trigger: ['blur'] }
],
}
//
const editUserInfo = () => {
form.name = useUserStore.userInfo.realname
form.birthday = useUserStore.userInfo.birthday
form.sex = useUserStore.userInfo.sex
form.email = useUserStore.userInfo.email
form.workNo = useUserStore.userInfo.workNo
// form.facultiesId = useUserStore.userInfo.facultiesId
form.phone = useUserStore.userInfo.phone
dialogVisible.value = true
@ -189,6 +220,7 @@ const form = reactive({
email: '',
facultiesId: '',
phone: '',
workNo:'',
})
//
@ -203,29 +235,39 @@ const uploadFileEvent = async () => {
}
//
const submit = async () => {
if (fileList.value[0].hasOwnProperty('raw')) {
await uploadFileEvent()
}
const data: any = {
id: userInfo.value.id,
realname: form.name,
birthday: form.birthday,
sex: form.sex,
email: form.email,
facultiesId: form.facultiesId,
phone: form.phone,
avatar: avatar.value,
}
for (const key in data) {
if (data[key] === '') {
delete data[key]
//
if (!ruleFormRef.value) return
await ruleFormRef.value.validate(async (valid: boolean) => {
if (valid) {
//
if (fileList.value[0].hasOwnProperty('raw')) {
await uploadFileEvent()
}
const data: any = {
id: userInfo.value.id,
realname: form.name,
birthday: form.birthday,
sex: form.sex,
email: form.email,
facultiesId: form.facultiesId,
phone: form.phone,
avatar: avatar.value,
workNo: form.workNo
}
for (const key in data) {
if (data[key] === '') {
delete data[key]
}
}
await editUserInfoApi(data)
useUserStore.getUserInfo()
userInfo.value = useUserStore.userInfo
dialogVisible.value = false
} else {
//
ElMessage.error('表单信息填写有误,请检查后再试')
}
}
await editUserInfoApi(data)
useUserStore.getUserInfo()
userInfo.value = useUserStore.userInfo
dialogVisible.value = false
})
}
onMounted(() => {})
//
@ -481,7 +523,7 @@ const setImageUrl = (url: string) => {
width: 377.333px;
}
width: 176px;
width: 165px;
height: 80px;
display: flex;
flex-direction: column;

@ -33,6 +33,7 @@ export default defineConfig({
host: '0.0.0.0',
port: 8866,
},
base:'/gstadmin_single',
resolve: {
alias: {
'@': path.resolve('./src'), // 相对路径别名配置,使用 @ 代替 src

Loading…
Cancel
Save