Merge branch 'main' of http://182.92.169.222:3000/dlsx/ContestPortal
commit
0efbfb66fb
16 changed files with 953 additions and 86 deletions
After Width: | Height: | Size: 39 KiB |
@ -0,0 +1,174 @@ |
||||
<!-- 比赛项目名称页面 --> |
||||
<template> |
||||
<div class="fill"></div> |
||||
<div class="banner"> |
||||
<img src="../../assets/images/banner2.png" alt=""> |
||||
</div> |
||||
|
||||
<div class="project-name"> |
||||
<!-- 面包屑 --> |
||||
<div class="bread-box"> |
||||
<el-breadcrumb separator-icon="ArrowRight"> |
||||
<template v-for="r in route.matched" :key="r.path"> |
||||
<el-breadcrumb-item v-if="r.path !== '/projectName'" :to="{ path: r.path }"> |
||||
{{ r.meta.title }} |
||||
</el-breadcrumb-item> |
||||
<el-breadcrumb-item v-else> |
||||
{{ r.meta.title }} |
||||
</el-breadcrumb-item> |
||||
</template> |
||||
|
||||
</el-breadcrumb> |
||||
</div> |
||||
|
||||
<div class="content"> |
||||
<div class="title">{{ data.objName }}</div> |
||||
<div class="text" v-html="data.introduce"></div> |
||||
<div class="foot"> |
||||
<el-checkbox v-model="checked" label="我已完成阅读并全部知悉项目比赛规则" size="large" /> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="btn-box"> |
||||
<el-btutton class="btn" @click="handleSub">立刻报名</el-btutton> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup lang="ts"> |
||||
import { getCompetitionOneApi } from '@/api/person'; |
||||
import { ref, watch } from 'vue'; |
||||
import { useRoute, useRouter } from 'vue-router'; |
||||
import { ElMessage, ElLoading } from 'element-plus'; |
||||
|
||||
const route = useRoute(); |
||||
const router = useRouter(); |
||||
|
||||
// loading |
||||
const loading = ref(false); |
||||
let loadingInstance: any; |
||||
watch(loading, newVal => { |
||||
if (newVal) loadingInstance = ElLoading.service({ fullscreen: true }); |
||||
else if (loadingInstance) loadingInstance.close(); |
||||
}); |
||||
|
||||
// 获取数据 |
||||
const data = ref<Record<any, any>>({}); |
||||
async function getData() { |
||||
if (!route.query.id) return |
||||
try { |
||||
loading.value = true; |
||||
const res: any = await getCompetitionOneApi(route.query.id as string); |
||||
if (!res.result) return |
||||
data.value = res.result; |
||||
} catch (error) { |
||||
ElMessage.error('请求失败'); |
||||
} finally { |
||||
loading.value = false; |
||||
} |
||||
} |
||||
|
||||
// 是否同意 |
||||
const checked = ref(false); |
||||
|
||||
// 立刻报名 |
||||
function handleSub() { |
||||
if (!checked.value) { |
||||
ElMessage({ |
||||
message: '请先同意', |
||||
type: 'warning', |
||||
}) |
||||
return |
||||
} |
||||
router.push({ path: '/registrationPersonage', query: { id: route.query.id } }) |
||||
} |
||||
|
||||
getData(); |
||||
</script> |
||||
|
||||
|
||||
|
||||
<style lang="scss" scoped> |
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap'); |
||||
|
||||
* { |
||||
font-family: "Roboto", sans-serif; |
||||
font-weight: 300; |
||||
font-style: normal; |
||||
line-height: 2; |
||||
} |
||||
|
||||
.project-name { |
||||
margin: 0 auto; |
||||
width: $base-container-width; |
||||
|
||||
.bread-box { |
||||
margin: 40px 0; |
||||
} |
||||
|
||||
.content { |
||||
.title { |
||||
text-align: center; |
||||
font-size: 42px; |
||||
color: #333333; |
||||
margin: 20px 0; |
||||
} |
||||
|
||||
.text { |
||||
font-size: 18px; |
||||
color: #666666; |
||||
text-indent: 2em; |
||||
} |
||||
|
||||
.foot { |
||||
margin: 120px 0 20px; |
||||
display: flex; |
||||
align-items: center; |
||||
gap: 110px; |
||||
} |
||||
} |
||||
|
||||
.btn-box { |
||||
display: flex; |
||||
justify-content: center; |
||||
margin-top: 80px; |
||||
|
||||
.btn { |
||||
--color1: #00D0D0; |
||||
--color2: #42D9AC; |
||||
cursor: pointer; |
||||
text-align: center; |
||||
width: 470px; |
||||
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); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
.fill { |
||||
padding-top: 80px; |
||||
} |
||||
|
||||
.banner { |
||||
width: 100%; |
||||
height: 367px; |
||||
border-radius: 0px 0px 0px 0px; |
||||
|
||||
img { |
||||
width: 100%; |
||||
height: 100%; |
||||
object-fit: cover; |
||||
} |
||||
} |
||||
</style> |
@ -1,12 +1,587 @@ |
||||
<template> |
||||
<div class="container-1420">1</div> |
||||
<div class="top-bg"> |
||||
<h1 class="title">个人中心</h1> |
||||
<div class="desc">{{ userInfo.realname }}欢迎回来~</div> |
||||
<div class="icon"> |
||||
<SvgIcon name="荣誉资质" width="300" height="300" /> |
||||
</div> |
||||
</div> |
||||
<div class="container-1420"> |
||||
<div class="top"> |
||||
<!-- 比赛信息 --> |
||||
<el-card class="com"> |
||||
<div class="title">当前参加的比赛</div> |
||||
<div class="content"> |
||||
<div class="card-annual"> |
||||
<div class="annual">2023年度</div> |
||||
<div class="title-box"> |
||||
<div class="text">河南省大学生创新创业大赛</div> |
||||
<img src="../../assets/images/编组.png" alt="" /> |
||||
</div> |
||||
</div> |
||||
<div class="right"> |
||||
<div class="info-box"> |
||||
<div class="name">比赛年度</div> |
||||
<div class="title">2024年度</div> |
||||
<div class="name">比赛名称</div> |
||||
<div class="title">河南省大学生创新创业大赛</div> |
||||
<div class="date-box"> |
||||
<div class="label">开始报名时间:</div> |
||||
<div class="date">2323.6.1 18:00</div> |
||||
</div> |
||||
<div class="date-box"> |
||||
<div class="label">开始截至时间:</div> |
||||
<div class="date">2323.6.1 18:00</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</el-card> |
||||
<!-- 项目信息 --> |
||||
<el-card class="com"> |
||||
<div class="title">项目信息</div> |
||||
<div class="content track"> |
||||
<div class="card-annual"> |
||||
<p>红色之旅赛道</p> |
||||
</div> |
||||
<div class="right"> |
||||
<div class="info-box"> |
||||
<div class="name">项目名称</div> |
||||
<div class="title">红色之旅赛道</div> |
||||
<div class="name">要求人数</div> |
||||
<div class="title">1人</div> |
||||
<div class="date-box"> |
||||
<div class="label">开始报名时间:</div> |
||||
<div class="date">2323.6.1 18:00</div> |
||||
</div> |
||||
<div class="date-box"> |
||||
<div class="label">开始截至时间:</div> |
||||
<div class="date">2323.6.1 18:00</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</el-card> |
||||
</div> |
||||
<el-card> |
||||
<div class="user-info-main"> |
||||
<div class="left"> |
||||
<div class="personage-info"> |
||||
<div class="head"> |
||||
<div class="title">个人信息</div> |
||||
<div class="icon"> |
||||
<el-button type="primary" link @click="editUserInfo"> |
||||
编辑 |
||||
</el-button> |
||||
</div> |
||||
</div> |
||||
<div class="info-box"> |
||||
<div class="text"> |
||||
<!-- <img style="width: 75px; height:75px ;" src="../../assets/images/item.png" alt="" srcset=""> --> |
||||
<el-image |
||||
style="width: 100px; height: 100px" |
||||
:src="setImageUrl(userInfo.avatar)" |
||||
:preview-src-list="[ |
||||
setImageUrl(userInfo.avatar), |
||||
]" |
||||
/> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="info-box"> |
||||
<div class="label">姓名</div> |
||||
<div class="text">{{ userInfo.realname }}</div> |
||||
</div> |
||||
|
||||
<div class="info-box"> |
||||
<div class="label">姓别</div> |
||||
<div class="text">{{ userInfo.sex === 1 ? '男' : '女' }}</div> |
||||
</div> |
||||
|
||||
<div class="info-box"> |
||||
<div class="label">学号</div> |
||||
<div class="text">{{ userInfo.workNo }}</div> |
||||
</div> |
||||
|
||||
<div class="info-box"> |
||||
<div class="label">手机号</div> |
||||
<div class="text">{{ userInfo.phone }}</div> |
||||
</div> |
||||
|
||||
<div class="info-box"> |
||||
<div class="label">院系</div> |
||||
<div class="text">国际教育学院</div> |
||||
</div> |
||||
|
||||
<div class="info-box"> |
||||
<div class="label">邮箱</div> |
||||
<div class="text">{{ userInfo.email }}</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="right"> |
||||
<div |
||||
class="personalAbilityEvaluationCollectList gradient" |
||||
@click="Router.push('/personalAbilityEvaluationCollectList')" |
||||
> |
||||
个人积分管理 |
||||
</div> |
||||
<div |
||||
class="personalAbilityEvaluationCollectList gradient" |
||||
@click="Router.push('/personalEvaluateList')" |
||||
> |
||||
个人能力评价 |
||||
</div> |
||||
<div |
||||
class="personalAbilityEvaluationCollectList gradient" |
||||
@click="Router.push('/personalReport')" |
||||
> |
||||
个人能力报告 |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</el-card> |
||||
</div> |
||||
<el-dialog |
||||
v-model="dialogVisible" |
||||
v-if="dialogVisible" |
||||
title="编辑" |
||||
width="35%" |
||||
:before-close="handleClose" |
||||
> |
||||
<el-form :model="form" label-width="80" style="padding-right: 30px"> |
||||
<el-form-item label="头像"> |
||||
<el-upload |
||||
v-model:file-list="fileList" |
||||
action="#" |
||||
list-type="picture-card" |
||||
:auto-upload="false" |
||||
> |
||||
<el-icon><Plus /></el-icon> |
||||
</el-upload> |
||||
</el-form-item> |
||||
<el-form-item label="姓名"> |
||||
<el-input v-model="form.name" /> |
||||
</el-form-item> |
||||
<el-form-item label="部门"> |
||||
<el-cascader |
||||
:props="props" |
||||
style="width: 100%" |
||||
v-model="form.facultiesId" |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item label="生日"> |
||||
<el-date-picker |
||||
v-model="form.birthday" |
||||
type="date" |
||||
placeholder="选择日期" |
||||
style="width: 100%" |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item label="性别"> |
||||
<el-radio-group v-model="form.sex"> |
||||
<el-radio :value="1" size="large">男</el-radio> |
||||
<el-radio :value="0" size="large">女</el-radio> |
||||
</el-radio-group> |
||||
</el-form-item> |
||||
<el-form-item label="邮箱"> |
||||
<el-input v-model="form.email" /> |
||||
</el-form-item> |
||||
<el-form-item label="手机号"> |
||||
<el-input v-model="form.phone" type="number" /> |
||||
</el-form-item> |
||||
</el-form> |
||||
<template #footer> |
||||
<div class="dialog-footer"> |
||||
<el-button @click="dialogVisible = false">取消</el-button> |
||||
<el-button type="primary" @click="submit">确认</el-button> |
||||
</div> |
||||
</template> |
||||
</el-dialog> |
||||
</template> |
||||
|
||||
<script lang='ts' setup> |
||||
import { onMounted, reactive, ref, toRefs, watch } from 'vue' |
||||
<script lang="ts" setup> |
||||
import { nextTick, onMounted, reactive, ref, toRefs, watch } from 'vue' |
||||
import { useRouter } from 'vue-router' |
||||
import userStore from '@/store/module/user' |
||||
import { getFaculties, uploadFile, editUserInfoApi } from '@/api/race' |
||||
import { id } from 'element-plus/es/locale/index.mjs' |
||||
const useUserStore = userStore() |
||||
const userInfo = ref<any>({}) |
||||
console.log(useUserStore.userInfo, 'useUserStore') |
||||
userInfo.value = useUserStore.userInfo |
||||
const Router = useRouter() |
||||
const dialogVisible = ref(false) |
||||
// 修改用户信息 |
||||
const editUserInfo = () => { |
||||
form.name = userInfo.value.realname |
||||
form.birthday = userInfo.value.birthday |
||||
form.sex = userInfo.value.sex |
||||
form.email = userInfo.value.email |
||||
// form.facultiesId = userInfo.value.facultiesId |
||||
form.phone = userInfo.value.phone |
||||
dialogVisible.value = true |
||||
nextTick(() => { |
||||
fileList.value = [ |
||||
{ |
||||
url: setImageUrl(userInfo.value.avatar), |
||||
}, |
||||
] |
||||
}) |
||||
} |
||||
const handleClose = () => { |
||||
dialogVisible.value = false |
||||
} |
||||
const form = reactive({ |
||||
name: '', |
||||
birthday: '', |
||||
sex: '', |
||||
email: '', |
||||
facultiesId: '', |
||||
phone: '', |
||||
}) |
||||
|
||||
// 上传文件 |
||||
const fileList = ref<any>([]) |
||||
const avatar = ref<any>('') |
||||
const uploadFileEvent = async () => { |
||||
const fromData = new FormData() |
||||
fromData.append('file', fileList.value[0].raw) |
||||
const res: any = await uploadFile(fromData) |
||||
avatar.value = res.message |
||||
console.log(res, 'res') |
||||
} |
||||
// 确认修改 |
||||
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] |
||||
} |
||||
} |
||||
await editUserInfoApi(data) |
||||
useUserStore.getUserInfo() |
||||
dialogVisible.value = false |
||||
} |
||||
onMounted(() => {}) |
||||
// 获取院系列表 |
||||
|
||||
const FacultiesList = ref<any>([]) |
||||
|
||||
const getFacultiesList = async (data: any) => { |
||||
const res: any = await getFaculties(data) |
||||
console.log(res, 'res') |
||||
FacultiesList.value = res.result |
||||
} |
||||
// 配置部门级联选择器 |
||||
const props = { |
||||
lazy: true, |
||||
checkStrictly: true, |
||||
emitPath: false, |
||||
async lazyLoad(node: any, resolve: any) { |
||||
await getFacultiesList({ |
||||
primaryKey: 'key', |
||||
pid: node.value, |
||||
}) |
||||
const nodes = FacultiesList.value.map((item: any) => ({ |
||||
value: item.id, |
||||
label: item.title, |
||||
})) |
||||
resolve(nodes) |
||||
}, |
||||
} |
||||
watch( |
||||
() => fileList.value, |
||||
(newVal, oldVal) => { |
||||
console.log(newVal, oldVal) |
||||
if (newVal.length === 1) { |
||||
;(document.querySelector('.el-upload') as HTMLElement).style.display = |
||||
'none' |
||||
} else { |
||||
setTimeout(() => { |
||||
;(document.querySelector('.el-upload') as HTMLElement).style.display = |
||||
'flex' |
||||
}, 0) |
||||
} |
||||
}, |
||||
) |
||||
const setImageUrl = (url: string) => { |
||||
return import.meta.env.VITE_APP_BASE_API + '/sys/common/static/' + url |
||||
} |
||||
</script> |
||||
<style lang="scss" scoped> |
||||
.top-bg { |
||||
position: relative; |
||||
width: 100%; |
||||
height: 290px; |
||||
background-color: #fff; |
||||
background: linear-gradient(90deg, #ffffff 0%, #f0f8ff 100%); |
||||
margin-top: 80px; |
||||
padding: 20px 320px; |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: center; |
||||
.title { |
||||
font-size: 32px; |
||||
font-weight: 700; |
||||
} |
||||
.desc { |
||||
margin-top: 20px; |
||||
font-size: 16px; |
||||
} |
||||
.icon { |
||||
position: absolute; |
||||
right: 300px; |
||||
} |
||||
} |
||||
.top { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
margin: 25px 0; |
||||
height: 300px; |
||||
|
||||
.com { |
||||
width: 697px; |
||||
height: 300px; |
||||
border-radius: 6px 6px 6px 6px; |
||||
padding-top: 22px; |
||||
padding-left: 32px; |
||||
|
||||
.title { |
||||
height: 28px; |
||||
font-family: |
||||
Microsoft YaHei UI, |
||||
Microsoft YaHei UI; |
||||
font-weight: bold; |
||||
font-size: 20px; |
||||
color: rgba(0, 0, 0, 0.9); |
||||
line-height: 28px; |
||||
margin-bottom: 18px; |
||||
} |
||||
|
||||
// margin-right: 22px; |
||||
|
||||
.content { |
||||
display: flex; |
||||
gap: 22px; |
||||
|
||||
.card-annual { |
||||
padding: 28px 0 0 28px; |
||||
width: 340px; |
||||
height: 182px; |
||||
background: linear-gradient(90deg, #21aca5 0%, #42d9ac99 100%); |
||||
border-radius: 8px; |
||||
overflow: hidden; |
||||
|
||||
.annual { |
||||
height: 19px; |
||||
font-family: Inter, Inter; |
||||
font-weight: bold; |
||||
font-size: 16px; |
||||
color: rgba(255, 255, 255, 0.8); |
||||
line-height: 19px; |
||||
} |
||||
|
||||
.title-box { |
||||
margin-top: 13px; |
||||
display: flex; |
||||
align-items: center; |
||||
gap: 28px; |
||||
|
||||
.text { |
||||
width: 202px; |
||||
font-family: Inter, Inter; |
||||
font-weight: normal; |
||||
font-size: 32px; |
||||
color: #ffffff; |
||||
line-height: 39px; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.right { |
||||
.info-box { |
||||
.name { |
||||
height: 20px; |
||||
font-family: |
||||
Microsoft YaHei UI, |
||||
Microsoft YaHei UI; |
||||
font-weight: 400; |
||||
font-size: 14px; |
||||
color: #acacac; |
||||
line-height: 20px; |
||||
margin-bottom: 8px; |
||||
} |
||||
|
||||
.title { |
||||
height: 20px; |
||||
font-family: |
||||
Microsoft YaHei UI, |
||||
Microsoft YaHei UI; |
||||
font-weight: bold; |
||||
font-size: 20px; |
||||
color: #333333; |
||||
line-height: 20px; |
||||
margin-bottom: 12px; |
||||
} |
||||
|
||||
.date-box { |
||||
margin-bottom: 12px; |
||||
display: flex; |
||||
align-items: center; |
||||
|
||||
.label { |
||||
height: 20px; |
||||
font-family: |
||||
Microsoft YaHei UI, |
||||
Microsoft YaHei UI; |
||||
font-weight: 400; |
||||
font-size: 14px; |
||||
color: #acacac; |
||||
line-height: 20px; |
||||
} |
||||
|
||||
.date { |
||||
font-family: |
||||
Microsoft YaHei UI, |
||||
Microsoft YaHei UI; |
||||
font-weight: bold; |
||||
font-size: 18px; |
||||
color: #333333; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
.track { |
||||
.card-annual { |
||||
background: url(../../assets/images/item.png) no-repeat; |
||||
background-size: cover; |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
padding: 0; |
||||
|
||||
p { |
||||
font-family: |
||||
Microsoft YaHei UI, |
||||
Microsoft YaHei UI; |
||||
font-weight: bold; |
||||
font-size: 40px; |
||||
color: #76dae5; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.user-info-main { |
||||
width: 100%; |
||||
height: 300px; |
||||
display: flex; |
||||
.left { |
||||
flex: 1; |
||||
.personage-info { |
||||
margin: 30px 0 0 32px; |
||||
// width: 780px; |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
// justify-content: space-between; |
||||
row-gap: 32px; |
||||
|
||||
.head { |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
|
||||
.title { |
||||
height: 28px; |
||||
font-family: |
||||
Microsoft YaHei UI, |
||||
Microsoft YaHei UI; |
||||
font-weight: bold; |
||||
font-size: 20px; |
||||
color: rgba(0, 0, 0, 0.9); |
||||
line-height: 28px; |
||||
} |
||||
|
||||
.icon { |
||||
padding: 5px; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
|
||||
.info-box { |
||||
&.remark { |
||||
width: 377.333px; |
||||
} |
||||
|
||||
width: 176px; |
||||
height: 80px; |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: space-between; |
||||
|
||||
<style lang='scss' scoped> |
||||
.label { |
||||
height: 22px; |
||||
font-family: |
||||
Microsoft YaHei UI, |
||||
Microsoft YaHei UI; |
||||
font-weight: 400; |
||||
font-size: 14px; |
||||
color: rgba(0, 0, 0, 0.4); |
||||
line-height: 22px; |
||||
} |
||||
|
||||
.text { |
||||
// height: 22px; |
||||
font-family: |
||||
Microsoft YaHei UI, |
||||
Microsoft YaHei UI; |
||||
font-weight: 400; |
||||
font-size: 14px; |
||||
color: rgba(0, 0, 0, 0.9); |
||||
line-height: 22px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.right { |
||||
width: 300px; |
||||
padding: 25px; |
||||
// background-color: pink; |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: space-around; |
||||
align-items: center; |
||||
.personalAbilityEvaluationCollectList { |
||||
width: 180px; |
||||
// background-color: pink; |
||||
height: 38px; |
||||
text-align: center; |
||||
line-height: 38px; |
||||
font-size: 16px; |
||||
border-radius: 10px; |
||||
color: #fff; |
||||
cursor: pointer; |
||||
transition: all 0.2s; |
||||
} |
||||
.personalAbilityEvaluationCollectList:hover { |
||||
transform: scale(1.1); |
||||
} |
||||
} |
||||
} |
||||
</style> |
||||
|
Loading…
Reference in new issue