Merge branch 'main' of http://182.92.169.222:3000/dlsx/ContestPortal
commit
e16e5f4cc5
18 changed files with 1029 additions and 285 deletions
@ -1,53 +1,75 @@ |
||||
import request from '@/utils/requset' |
||||
|
||||
// 获取年度比赛项目列表
|
||||
export const getRaceProjectList = (params:any) => { |
||||
return request({ |
||||
url:'/AnnualCompPoint/annualCompPoint/listStudent', |
||||
params |
||||
}) |
||||
export const getRaceProjectList = (params: any) => { |
||||
return request({ |
||||
url: '/AnnualCompPoint/annualCompPoint/listStudent', |
||||
params, |
||||
}) |
||||
} |
||||
// 获取年度比赛列表
|
||||
export const getYearRaceList = (params:any) => { |
||||
return request({ |
||||
url:'/annualcomp/annualComp/findndbswlj', |
||||
params |
||||
}) |
||||
export const getYearRaceList = (params: any) => { |
||||
return request({ |
||||
url: '/annualcomp/annualComp/findndbswlj', |
||||
params, |
||||
}) |
||||
} |
||||
// 获取比赛列表
|
||||
export const getRaceList = (params:any) => { |
||||
return request({ |
||||
url:'/comp/comp/complistnolj', |
||||
params |
||||
}) |
||||
export const getRaceList = (params: any) => { |
||||
return request({ |
||||
url: '/comp/comp/complistnolj', |
||||
params, |
||||
}) |
||||
} |
||||
// 获取比赛详细信息
|
||||
export const getRaceInfo = (params:any) => { |
||||
return request({ |
||||
url:'/comp/comp/complistnoxq', |
||||
params |
||||
}) |
||||
export const getRaceInfo = (params: any) => { |
||||
return request({ |
||||
url: '/comp/comp/complistnoxq', |
||||
params, |
||||
}) |
||||
} |
||||
// 获取院系列表
|
||||
export const getFaculties = (params:any) => { |
||||
return request({ |
||||
url:'/sys/sysDepart/queryDepartStuTreeSync', |
||||
params |
||||
}) |
||||
export const getFaculties = (params: any) => { |
||||
return request({ |
||||
url: '/sys/sysDepart/queryDepartStuTreeSync', |
||||
params, |
||||
}) |
||||
} |
||||
// 上传文件
|
||||
export const uploadFile = (data:any) => { |
||||
return request({ |
||||
url:'/sys/common/upload', |
||||
method:'POST', |
||||
data |
||||
}) |
||||
export const uploadFile = (data: any) => { |
||||
return request({ |
||||
url: '/sys/common/upload', |
||||
method: 'POST', |
||||
data, |
||||
}) |
||||
} |
||||
// 修改用户信息
|
||||
export const editUserInfoApi = (data:any) => { |
||||
return request({ |
||||
url:'/sys/user/login/setting/userEdit', |
||||
method:'POST', |
||||
data |
||||
}) |
||||
export const editUserInfoApi = (data: any) => { |
||||
return request({ |
||||
url: '/sys/user/login/setting/userEdit', |
||||
method: 'POST', |
||||
data, |
||||
}) |
||||
} |
||||
// 获取奖项
|
||||
export const getAwardslist = (params: any) => { |
||||
return request({ |
||||
url: '/awardpersion/awardPersion/list', |
||||
params, |
||||
}) |
||||
} |
||||
// 上传证书
|
||||
export const uploadFileZs = (data: any) => { |
||||
return request({ |
||||
url: '/sys/common/uploadzs', |
||||
method: 'POST', |
||||
data, |
||||
}) |
||||
} |
||||
export const saveSz = (data: any) => { |
||||
return request({ |
||||
url: 'awardpersion/awardPersion/sczs', |
||||
method: 'POST', |
||||
data, |
||||
}) |
||||
} |
@ -0,0 +1,280 @@ |
||||
<template> |
||||
<div class="login-form"> |
||||
<div class="login-title">注册</div> |
||||
<div class="form"> |
||||
<el-form :model="form" label-width="0"> |
||||
<el-form-item> |
||||
<el-col :span="11"> |
||||
<el-input |
||||
v-model="form.username" |
||||
:prefix-icon="User" |
||||
placeholder="账号" |
||||
style="height: 0.2344rem" |
||||
/> |
||||
</el-col> |
||||
<el-col :span="2" class="text-center"> |
||||
<span class="text-gray-500"></span> |
||||
</el-col> |
||||
<el-col :span="11"> |
||||
<el-input |
||||
v-model="form.realname" |
||||
:prefix-icon="User" |
||||
placeholder="姓名" |
||||
style="height: 0.2344rem" |
||||
/> |
||||
</el-col> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-input |
||||
v-model="form.workno" |
||||
placeholder="工号/学号" |
||||
:prefix-icon="Iphone" |
||||
></el-input> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<!-- <el-cascader |
||||
v-model="form.department" |
||||
placeholder="选择院系" |
||||
:options="options" |
||||
style="width: 100%; height: 0.2344rem" |
||||
/> --> |
||||
<el-cascader |
||||
:props="props" |
||||
style="width: 100%; height: 0.2344rem" |
||||
v-model="form.department" |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-input |
||||
placeholder="手机号码" |
||||
v-model="form.mobile" |
||||
:prefix-icon="Iphone" |
||||
></el-input> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-input |
||||
placeholder="密码" |
||||
v-model="form.password" |
||||
:prefix-icon="Lock" |
||||
></el-input> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-input |
||||
placeholder="确认密码" |
||||
v-model="form.confirmPassword" |
||||
:prefix-icon="Lock" |
||||
></el-input> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<!-- <el-input |
||||
placeholder="验证码" |
||||
v-model="form.smscode" |
||||
:prefix-icon="Lock" |
||||
></el-input> --> |
||||
<div class="captcha"> |
||||
<el-input |
||||
v-model="form.smscode" |
||||
style="height: 0.2344rem" |
||||
maxlength="4" |
||||
:prefix-icon="Lock" |
||||
/> |
||||
<div class="code" @click="getcodeinfo"> |
||||
<img :src="codeUrl" alt="" srcset="" /> |
||||
</div> |
||||
</div> |
||||
</el-form-item> |
||||
</el-form> |
||||
<div class="btn"> |
||||
<div @click="$emits('backLogin')">返回</div> |
||||
<div class="gradient" @click="ragistered">注册</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script lang="ts" setup> |
||||
import { onMounted, reactive, ref, toRefs, watch } from 'vue' |
||||
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' |
||||
const $emits = defineEmits(['backLogin']) |
||||
const form = reactive<any>({ |
||||
username: '', |
||||
realname: '', |
||||
workno: '', |
||||
department: '', |
||||
mobile: '', |
||||
password: '', |
||||
confirmPassword: '' /*, policy: false*/, |
||||
smscode: '', |
||||
}) |
||||
const KeyValue: any = { |
||||
username: '账号', |
||||
realname: '姓名', |
||||
workno: '学号', |
||||
department: '院系', |
||||
mobile: '手机号', |
||||
password: '密码', |
||||
confirmPassword: '确认密码' /*, policy: false*/, |
||||
smscode: '验证码', |
||||
} |
||||
|
||||
const FacultiesList = ref([]) |
||||
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) |
||||
}, |
||||
} |
||||
|
||||
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(`手机号格式不正确`) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (!(form.password === form.confirmPassword)) { |
||||
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) |
||||
} |
||||
console.log(res) |
||||
} |
||||
const codeUrl = ref('') |
||||
|
||||
// 获取验证码 |
||||
const getcodeinfo = async () => { |
||||
const res: any = await getCode(1629428467008) |
||||
codeUrl.value = res.result |
||||
console.log(codeUrl.value) |
||||
} |
||||
getcodeinfo() |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.login-form { |
||||
width: 640px; |
||||
height: 820px; |
||||
border-radius: 15px; |
||||
background-color: #ffffff1a !important; |
||||
padding: 70px 60px; |
||||
backdrop-filter: blur(10px); |
||||
box-shadow: 0 4px 8px 1px rgba(0, 0, 0, 0.2); |
||||
.login-title { |
||||
font-size: 32px; |
||||
font-weight: 700; |
||||
} |
||||
.form { |
||||
margin-top: 45px; |
||||
padding: 0 40px; |
||||
.captcha { |
||||
width: 100%; |
||||
height: 100%; |
||||
position: relative; |
||||
.code { |
||||
width: 100%; |
||||
height: 100%; |
||||
position: absolute; |
||||
top: 0; |
||||
right: 0; |
||||
width: 105px; |
||||
height: 100%; |
||||
// background-color: pink; |
||||
display: flex; |
||||
align-items: center; |
||||
img { |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
} |
||||
} |
||||
.submit { |
||||
width: 399px; |
||||
height: 50px; |
||||
text-align: center; |
||||
line-height: 50px; |
||||
font-size: 20px; |
||||
font-weight: 600; |
||||
cursor: pointer; |
||||
color: #fff; |
||||
border-radius: 10px; |
||||
margin-top: 35px; |
||||
} |
||||
} |
||||
.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: row !important; |
||||
height: 45px; |
||||
margin-top: 25px; |
||||
.el-input { |
||||
height: 100%; |
||||
} |
||||
input { |
||||
height: 100%; |
||||
} |
||||
} |
||||
</style> |
@ -1,164 +0,0 @@ |
||||
<template> |
||||
<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> |
||||
<img class="news-image" :src="newsItem.imageUrl" alt="News Image" v-default-image> |
||||
</div> |
||||
<el-divider /> |
||||
</li> |
||||
</ul> |
||||
</el-tab-pane> |
||||
</el-tabs> |
||||
</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 |
||||
} |
||||
} |
||||
} |
||||
|
||||
// 栏目新闻列表查询 |
||||
const fetchNewsList = async (categoryId) => { |
||||
try { |
||||
const response = await queryEssayListApi(categoryId) |
||||
console.log(response.success,'daaaaaaa') |
||||
console.log(response.result.records,'ddddddd') |
||||
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) => { |
||||
router.push({ |
||||
name: 'newsDetail', |
||||
params: { id: newsItem.id.toString() }, |
||||
}) |
||||
} |
||||
|
||||
</script> |
||||
|
||||
<style scoped> |
||||
.container{ |
||||
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; |
||||
} |
||||
.news-image { |
||||
width: 100px; |
||||
height: 80px; |
||||
margin-right: 30px; |
||||
} |
||||
</style> |
@ -1,12 +1,166 @@ |
||||
<template> |
||||
<div class="container"> |
||||
<router-view/> |
||||
<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> |
||||
<img class="news-image" :src="newsItem.imageUrl" alt="News Image" v-default-image> |
||||
</div> |
||||
<el-divider /> |
||||
</li> |
||||
</ul> |
||||
</el-tab-pane> |
||||
</el-tabs> |
||||
</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 |
||||
} |
||||
} |
||||
} |
||||
|
||||
// 栏目新闻列表查询 |
||||
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) => { |
||||
router.push({ |
||||
name: 'newsDetail', |
||||
params: { id: newsItem.id.toString() }, |
||||
}) |
||||
} |
||||
</script> |
||||
<style scoped> |
||||
.main{ |
||||
margin-top: 100px; |
||||
} |
||||
.container{ |
||||
margin-top:100px; |
||||
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; |
||||
} |
||||
.news-image { |
||||
width: 100px; |
||||
height: 80px; |
||||
margin-right: 30px; |
||||
} |
||||
</style> |
@ -0,0 +1,165 @@ |
||||
<template> |
||||
<!-- 比赛列表 --> |
||||
<div class="container-1420" v-if="isLoading"> |
||||
<div class="nav-title"> |
||||
<div class="top">竞赛导航</div> |
||||
<div class="bottom">30+项目登陆后报名</div> |
||||
</div> |
||||
<div class="race-list"> |
||||
<div |
||||
class="item" |
||||
v-for="item in splietArr" |
||||
: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> |
||||
<div class="page"> |
||||
<el-pagination background layout="prev, pager, next" :total="total" @change="handleSizeChange"/> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script lang="ts" setup> |
||||
import { ref } from 'vue' |
||||
import { getRaceList } from '@/api/race' |
||||
import { useRouter } from 'vue-router' |
||||
import { ElLoading } from 'element-plus' |
||||
const router = useRouter() |
||||
const reacProjectList = ref<any>([]) |
||||
const splietArr = ref<any>([]) |
||||
const isLoading = ref(false) |
||||
const total = ref<any>(0) |
||||
|
||||
const getRaceProjectListEvent = async () => { |
||||
let page = { |
||||
column: 'createTime', |
||||
order: 'desc', |
||||
pageNo: 1, |
||||
pageSize: 8, |
||||
} |
||||
const loading = ElLoading.service({ |
||||
lock: true, |
||||
text: 'Loading', |
||||
background: 'rgba(255, 255, 255, 0.7)', |
||||
}) |
||||
const res: any = await getRaceList(page) |
||||
console.log(res) |
||||
reacProjectList.value = res.result |
||||
splietArr.value = reacProjectList.value.slice(0, 8) |
||||
total.value = res.result.length |
||||
console.log(total.value, 'reacProjectList.value ') |
||||
|
||||
isLoading.value = true |
||||
loading.close() |
||||
} |
||||
getRaceProjectListEvent() |
||||
const setImageUrl = (url: string) => { |
||||
return import.meta.env.VITE_APP_BASE_API + url |
||||
} |
||||
// 前往比赛综述 |
||||
const toDetail = (id: number) => { |
||||
router.push({ |
||||
path: '/race-info', |
||||
query: { |
||||
id, |
||||
}, |
||||
}) |
||||
} |
||||
// 分页 |
||||
const handleSizeChange = (e:any) => { |
||||
console.log(e); |
||||
splietArr.value = reacProjectList.value.slice((e-1) * 8 ,(e-1) * 8 + 8) |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.race-list { |
||||
position: relative; |
||||
width: 100%; |
||||
display: grid; |
||||
grid-template-columns: repeat(4, 1fr); |
||||
grid-template-rows: repeat(2, 1fr); |
||||
// gap: 10px; |
||||
margin-top: 20px; |
||||
.item { |
||||
width: 340px; |
||||
height: 360px; |
||||
// background-color: pink; |
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.06); |
||||
cursor: pointer; |
||||
border-radius: 10px; |
||||
transition: all 0.2s; |
||||
.image { |
||||
width: 100%; |
||||
height: 194px; |
||||
img { |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
} |
||||
.reac-info { |
||||
padding: 0 8px; |
||||
.reac-title { |
||||
margin-top: 19px; |
||||
color: #c9c9c9; |
||||
font-size: 12px; |
||||
} |
||||
.reac-project { |
||||
font-size: 16px; |
||||
font-weight: 600; |
||||
color: #333333; |
||||
margin-top: 10px; |
||||
} |
||||
.time { |
||||
font-size: 14px; |
||||
color: #8c8b8b; |
||||
margin-top: 40px; |
||||
} |
||||
} |
||||
} |
||||
.item:hover { |
||||
transform: translateY(-5px); |
||||
} |
||||
.item:nth-child(n) { |
||||
margin-top: 20px; |
||||
} |
||||
.more { |
||||
position: absolute; |
||||
right: 20px; |
||||
top: -20px; |
||||
color: #0bd7c6; |
||||
cursor: pointer; |
||||
font-size: 14px; |
||||
} |
||||
} |
||||
.nav-title { |
||||
margin-top: 100px; |
||||
color: #1e2033; |
||||
.top { |
||||
font-size: 40px; |
||||
font-weight: 600; |
||||
text-align: center; |
||||
} |
||||
.bottom { |
||||
font-size: 16px; |
||||
text-align: center; |
||||
margin-top: 10px; |
||||
} |
||||
} |
||||
.page{ |
||||
display: flex; |
||||
justify-content: center; |
||||
margin-top: 25px; |
||||
} |
||||
</style> |
@ -0,0 +1,171 @@ |
||||
<template> |
||||
<el-card style="margin-top: 0.1302rem"> |
||||
<template #header> |
||||
<div style="font-size: 16px; font-weight: 600">我的奖项</div> |
||||
</template> |
||||
<el-table :data="tableData" border style="width: 100%"> |
||||
<el-table-column |
||||
align="center" |
||||
prop="annualid_dictText" |
||||
label="年度" |
||||
width="70" |
||||
/> |
||||
<el-table-column |
||||
align="center" |
||||
prop="annalComp_dictText" |
||||
label="年度比赛" |
||||
/> |
||||
<el-table-column |
||||
align="center" |
||||
prop="annualCompP_dictText" |
||||
label="年度比赛项目" |
||||
/> |
||||
<el-table-column align="center" prop="enrollCode" label="报名编号" /> |
||||
<el-table-column |
||||
align="center" |
||||
prop="awardname" |
||||
label="奖项名称" |
||||
width="90" |
||||
/> |
||||
<el-table-column align="center" prop="studentcode" label="学生学号" /> |
||||
<el-table-column |
||||
align="center" |
||||
prop="studentname" |
||||
label="学生姓名" |
||||
width="100" |
||||
/> |
||||
<el-table-column align="center" prop="sczs" label="证书"> |
||||
<template #default="{ row }"> |
||||
<el-image |
||||
:src="setImageUrl(row.sczs)" |
||||
style="width: 0.2604rem; height: 0.2604rem" |
||||
:preview-src-list="[setImageUrl(row.sczs)]" |
||||
:z-index="100" |
||||
></el-image> |
||||
<!-- <img :src="setImageUrl(row.sczs)" alt=""> --> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
prop="tj_dictText" |
||||
label="是否推荐" |
||||
width="90" |
||||
/> |
||||
<el-table-column align="center" label="操作"> |
||||
<template #default="{ row }"> |
||||
<el-button |
||||
link |
||||
type="primary" |
||||
size="small" |
||||
@click="uploadZs(row.id)" |
||||
> |
||||
上传证书 |
||||
</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</el-card> |
||||
<el-dialog |
||||
v-model="dialogVisible" |
||||
v-if="dialogVisible" |
||||
title="上传证书" |
||||
width="25%" |
||||
:before-close="handleClose" |
||||
> |
||||
<el-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> |
||||
<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' |
||||
import { getAwardslist, uploadFileZs,saveSz } from '@/api/race' |
||||
const dialogVisible = ref(false) |
||||
const tableData = ref<any>([]) |
||||
const getAwardListApi = async () => { |
||||
const data = { |
||||
column: 'createTime', |
||||
order: 'desc', |
||||
pageNo: 1, |
||||
pageSize: 10, |
||||
} |
||||
const res: any = await getAwardslist(data) |
||||
tableData.value = res.result.records |
||||
console.log(tableData.value, 'tableData.value') |
||||
} |
||||
getAwardListApi() |
||||
const setImageUrl = (url: string) => { |
||||
return import.meta.env.VITE_APP_BASE_API + '/sys/common/staticzs/' + url |
||||
} |
||||
|
||||
const fileList = ref<any>([]) |
||||
const zsUrl = ref('') |
||||
const zsId = ref(0) |
||||
const uploadZs = (id:any) => { |
||||
zsId.value = id |
||||
dialogVisible.value = true |
||||
} |
||||
const uploadFileEvent = async () => { |
||||
const fromData = new FormData() |
||||
fromData.append('file', fileList.value[0].raw) |
||||
const res: any = await uploadFileZs(fromData) |
||||
zsUrl.value = res.message |
||||
} |
||||
const submit = async () => { |
||||
await uploadFileEvent() |
||||
let data = { |
||||
id:zsId.value, |
||||
sczs:zsUrl.value |
||||
} |
||||
await saveSz(data) |
||||
getAwardListApi() |
||||
dialogVisible.value = false |
||||
fileList.value = [] |
||||
|
||||
} |
||||
const handleClose = () => { |
||||
dialogVisible.value = false |
||||
fileList.value = [] |
||||
|
||||
} |
||||
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) |
||||
} |
||||
}, |
||||
) |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
:deep(.el-image-viewer__close) { |
||||
top: 160px; |
||||
} |
||||
:deep(.el-table__cell) { |
||||
position: static !important; // 解决el-image 和 el-table冲突层级冲突问题 |
||||
} |
||||
</style> |
Loading…
Reference in new issue