提交 2da7580c authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 27c2d305
...@@ -28,8 +28,6 @@ watchEffect(() => { ...@@ -28,8 +28,6 @@ watchEffect(() => {
fetchInfo() fetchInfo()
}) })
// 右侧
const LAB_URL = import.meta.env.VITE_LAB_URL
// 评分 // 评分
const dialogVisible = $ref(false) const dialogVisible = $ref(false)
</script> </script>
...@@ -82,7 +80,7 @@ const dialogVisible = $ref(false) ...@@ -82,7 +80,7 @@ const dialogVisible = $ref(false)
</el-row> </el-row>
</AppCard> </AppCard>
<div class="lab-box"> <div class="lab-box">
<iframe :src="LAB_URL" frameborder="0" class="iframe" ref="iframeRef"></iframe> <iframe :src="detail.competition_uri" frameborder="0" class="iframe" ref="iframeRef"></iframe>
</div> </div>
</div> </div>
</section> </section>
......
...@@ -8,6 +8,8 @@ const SyncExamDialog = defineAsyncComponent(() => import('../components/SyncExam ...@@ -8,6 +8,8 @@ const SyncExamDialog = defineAsyncComponent(() => import('../components/SyncExam
const ImportExamDialog = defineAsyncComponent(() => import('../components/ImportExamDialog.vue')) const ImportExamDialog = defineAsyncComponent(() => import('../components/ImportExamDialog.vue'))
const ImportScoreDialog = defineAsyncComponent(() => import('../components/ImportScoreDialog.vue')) const ImportScoreDialog = defineAsyncComponent(() => import('../components/ImportScoreDialog.vue'))
const route = useRoute()
const { competitions, schools, status } = useFilterList() const { competitions, schools, status } = useFilterList()
const appList = $ref<InstanceType<typeof AppList> | null>(null) const appList = $ref<InstanceType<typeof AppList> | null>(null)
...@@ -18,7 +20,7 @@ const listOptions = $computed(() => { ...@@ -18,7 +20,7 @@ const listOptions = $computed(() => {
remote: { remote: {
httpRequest: getCheckList, httpRequest: getCheckList,
params: { params: {
competition_id: '', competition_id: route.query.competition_id || '',
check_status: '', check_status: '',
organ_id: '', organ_id: '',
login_id: '', login_id: '',
......
...@@ -6,6 +6,8 @@ import { useFilterList } from '../composables/useFilterList' ...@@ -6,6 +6,8 @@ import { useFilterList } from '../composables/useFilterList'
const DiscussDialog = defineAsyncComponent(() => import('../components/DiscussDialog.vue')) const DiscussDialog = defineAsyncComponent(() => import('../components/DiscussDialog.vue'))
const route = useRoute()
const { competitions } = useFilterList() const { competitions } = useFilterList()
const appList = $ref<InstanceType<typeof AppList> | null>(null) const appList = $ref<InstanceType<typeof AppList> | null>(null)
...@@ -15,7 +17,7 @@ const listOptions = $computed(() => { ...@@ -15,7 +17,7 @@ const listOptions = $computed(() => {
return { return {
remote: { remote: {
httpRequest: getDiscussList, httpRequest: getDiscussList,
params: { competition_id: '', student_name: '' } params: { competition_id: route.query.competition_id || '', student_name: '' }
}, },
filters: [ filters: [
{ {
......
...@@ -49,7 +49,6 @@ const listOptions = $computed(() => { ...@@ -49,7 +49,6 @@ const listOptions = $computed(() => {
{ label: '省', prop: 'province' }, { label: '省', prop: 'province' },
{ label: '市', prop: 'city' }, { label: '市', prop: 'city' },
{ label: '区/县', prop: 'area' }, { label: '区/县', prop: 'area' },
{ label: '更新时间', prop: 'updated_time' },
{ {
label: '角色', label: '角色',
prop: 'info.role', prop: 'info.role',
...@@ -58,6 +57,7 @@ const listOptions = $computed(() => { ...@@ -58,6 +57,7 @@ const listOptions = $computed(() => {
return found?.label || row.info.role return found?.label || row.info.role
} }
}, },
{ label: '更新时间', prop: 'updated_time' },
{ label: '操作', slots: 'table-x', width: 80 } { label: '操作', slots: 'table-x', width: 80 }
], ],
data: list data: list
......
...@@ -52,8 +52,8 @@ function formatDate(timestamp: number): string { ...@@ -52,8 +52,8 @@ function formatDate(timestamp: number): string {
return dayjs(timestamp * 1000).format('YYYY-MM-DD') return dayjs(timestamp * 1000).format('YYYY-MM-DD')
} }
function formatDateTime(timestamp: number): string { function formatTime(timestamp: number): string {
return dayjs(timestamp * 1000).format('YYYY-MM-DD HH:mm:ss') return dayjs(timestamp * 1000).format('HH:mm:ss')
} }
// 评分规则 // 评分规则
const scoringRulesVisible = $ref(false) const scoringRulesVisible = $ref(false)
...@@ -86,7 +86,7 @@ const scoringRulesBookVisible = $ref(false) ...@@ -86,7 +86,7 @@ const scoringRulesBookVisible = $ref(false)
<p>赛项封面:</p> <p>赛项封面:</p>
<img :src="detail.cover" /> <img :src="detail.cover" />
</div> </div>
<el-descriptions class="descriptions-box"> <el-descriptions class="descriptions-box" :column="2">
<el-descriptions-item label="赛项名称:">{{ detail.name }}</el-descriptions-item> <el-descriptions-item label="赛项名称:">{{ detail.name }}</el-descriptions-item>
<el-descriptions-item label="赛项类型:">{{ typeText }}</el-descriptions-item> <el-descriptions-item label="赛项类型:">{{ typeText }}</el-descriptions-item>
<el-descriptions-item label="主办单位:">{{ detail.host_unit.label }}</el-descriptions-item> <el-descriptions-item label="主办单位:">{{ detail.host_unit.label }}</el-descriptions-item>
...@@ -96,10 +96,11 @@ const scoringRulesBookVisible = $ref(false) ...@@ -96,10 +96,11 @@ const scoringRulesBookVisible = $ref(false)
>{{ formatDate(detail.start_range) }} ~ {{ formatDate(detail.end_range) }}</el-descriptions-item >{{ formatDate(detail.start_range) }} ~ {{ formatDate(detail.end_range) }}</el-descriptions-item
> >
<el-descriptions-item label="技术支持单位:">{{ detail.technical_support_unit.label }}</el-descriptions-item> <el-descriptions-item label="技术支持单位:">{{ detail.technical_support_unit.label }}</el-descriptions-item>
<el-descriptions-item label="正式比赛日期:" <el-descriptions-item label="正式比赛日期:">{{ formatDate(detail.start_at) }}</el-descriptions-item>
>{{ formatDateTime(detail.start_at) }} ~ {{ formatDateTime(detail.end_at) }}</el-descriptions-item
>
<el-descriptions-item label="生效状态:">{{ statusText }}</el-descriptions-item> <el-descriptions-item label="生效状态:">{{ statusText }}</el-descriptions-item>
<el-descriptions-item label="正式比赛时间:"
>{{ formatTime(detail.start_at) }} ~ {{ formatTime(detail.end_at) }}</el-descriptions-item
>
</el-descriptions> </el-descriptions>
</div> </div>
</AppCard> </AppCard>
...@@ -130,7 +131,7 @@ const scoringRulesBookVisible = $ref(false) ...@@ -130,7 +131,7 @@ const scoringRulesBookVisible = $ref(false)
} }
} }
.top-cover { .top-cover {
width: 200px; width: 300px;
margin-right: 20px; margin-right: 20px;
p { p {
font-weight: normal; font-weight: normal;
......
...@@ -5,6 +5,7 @@ import { getContestScoreList } from '../api' ...@@ -5,6 +5,7 @@ import { getContestScoreList } from '../api'
import { useFilterList } from '../composables/useFilterList' import { useFilterList } from '../composables/useFilterList'
const ScorePublishDialog = defineAsyncComponent(() => import('../components/ScorePublishDialog.vue')) const ScorePublishDialog = defineAsyncComponent(() => import('../components/ScorePublishDialog.vue'))
const route = useRoute()
const { competitions } = useFilterList() const { competitions } = useFilterList()
...@@ -15,7 +16,7 @@ const listOptions = $computed(() => { ...@@ -15,7 +16,7 @@ const listOptions = $computed(() => {
return { return {
remote: { remote: {
httpRequest: getContestScoreList, httpRequest: getContestScoreList,
params: { competition_id: '' } params: { competition_id: route.query.competition_id || '' }
}, },
filters: [ filters: [
{ {
......
...@@ -6,11 +6,19 @@ import { useFilterList } from '../composables/useFilterList' ...@@ -6,11 +6,19 @@ import { useFilterList } from '../composables/useFilterList'
const DiscussDialog = defineAsyncComponent(() => import('../components/DiscussDialog.vue')) const DiscussDialog = defineAsyncComponent(() => import('../components/DiscussDialog.vue'))
const route = useRoute()
const { courses, experiments, specialties, classes } = useFilterList() const { courses, experiments, specialties, classes } = useFilterList()
const appList = $ref<InstanceType<typeof AppList> | null>(null) const appList = $ref<InstanceType<typeof AppList> | null>(null)
const params = reactive({ student_name: '', course_id: '', experiment_id: '', specialty_id: '', class_id: '' }) const params = reactive({
student_name: '',
course_id: '',
experiment_id: route.query.experiment_id || '',
specialty_id: '',
class_id: ''
})
const classList = $computed(() => { const classList = $computed(() => {
const specialty = specialties.value.find(item => item.id === params.specialty_id) const specialty = specialties.value.find(item => item.id === params.specialty_id)
if (specialty) { if (specialty) {
...@@ -120,8 +128,7 @@ function onUpdateSuccess() { ...@@ -120,8 +128,7 @@ function onUpdateSuccess() {
v-model="dialogVisible" v-model="dialogVisible"
:data="rowData" :data="rowData"
@update="onUpdateSuccess" @update="onUpdateSuccess"
v-if="dialogVisible && rowData" v-if="dialogVisible && rowData"></DiscussDialog>
></DiscussDialog>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
......
...@@ -14,3 +14,13 @@ export function getExperimentList() { ...@@ -14,3 +14,13 @@ export function getExperimentList() {
export function getCourseList() { export function getCourseList() {
return httpRequest.get('/api/lab/v1/student/course/all') return httpRequest.get('/api/lab/v1/student/course/all')
} }
// 获取学员已报名的赛项列表
export function getMyContestList() {
return httpRequest.get('/api/lab/v1/student/competition/my-list')
}
// 获取赛项列表
export function getContestList() {
return httpRequest.get('/api/lab/v1/expert/index/index')
}
<script setup lang="ts"> <script setup lang="ts">
import type { ExperimentItem } from '../types' import type { ContestType } from '../types'
import { getExperimentList } from '../api' import { getContestList } from '../api'
const router = useRouter() const router = useRouter()
let list = $ref<ExperimentItem[]>([]) let list = $ref<ContestType[]>([])
let leaderList = $ref<ContestType[]>([])
function fetchList() { function fetchList() {
getExperimentList().then(res => { getContestList().then(res => {
list = res.data.list list = res.data.competition
leaderList = res.data.competition_leader
}) })
} }
onMounted(() => { onMounted(() => {
...@@ -14,9 +16,11 @@ onMounted(() => { ...@@ -14,9 +16,11 @@ onMounted(() => {
}) })
function handleChange(id: string, type: number) { function handleChange(id: string, type: number) {
if (type === 1) { if (type === 1) {
router.push({ path: '/admin/lab/book', query: { experiment_id: id } }) router.push({ path: '/admin/contest/check', query: { competition_id: id } })
} else if (type === 2) { } else if (type === 2) {
router.push({ path: '/admin/lab/video', query: { experiment_id: id } }) router.push({ path: '/admin/contest/score', query: { competition_id: id } })
} else if (type === 3) {
router.push({ path: '/admin/contest/analyze/score', query: { competition_id: id } })
} }
} }
</script> </script>
...@@ -33,11 +37,11 @@ function handleChange(id: string, type: number) { ...@@ -33,11 +37,11 @@ function handleChange(id: string, type: number) {
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option> <el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
<el-select size="large" placeholder="大赛成绩发布" @change="handleChange($event, 2)"> <el-select size="large" placeholder="大赛成绩发布" @change="handleChange($event, 2)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option> <el-option v-for="item in leaderList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
<el-select size="large" placeholder="大赛成绩分析" @change="handleChange($event, 2)"> <!-- <el-select size="large" placeholder="大赛成绩分析" @change="handleChange($event, 3)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option> <el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select> -->
</div> </div>
</template> </template>
......
<script setup lang="ts"> <script setup lang="ts">
import type { CourseType } from '../types' import type { CourseType, ContestType } from '../types'
import { getCourseList } from '../api' import { getCourseList, getMyContestList } from '../api'
const router = useRouter() const router = useRouter()
let list = $ref<CourseType[]>([]) let list = $ref<CourseType[]>([])
...@@ -9,34 +9,38 @@ function fetchList() { ...@@ -9,34 +9,38 @@ function fetchList() {
list = res.data.list list = res.data.list
}) })
} }
let contestList = $ref<ContestType[]>([])
function fetchContestList() {
getMyContestList().then(res => {
contestList = res.data.list
})
}
onMounted(() => { onMounted(() => {
fetchList() fetchList()
fetchContestList()
}) })
function handleChange(id: string, type: number) { function handleChange(id: string, type: number) {
if (type === 1) { if (type === 1) {
router.push({ path: '/student/lab', query: { course_id: id } }) router.push({ path: '/student/lab', query: { course_id: id } })
} }
} }
function handleContestChange(data: ContestType) {
router.push({ path: `/student/contest/lab/${data.id}`, query: { name: data.name } })
}
</script> </script>
<template> <template>
<div class="bg"> <div class="bg">
<router-link to="/student/lab" class="link1"></router-link> <router-link to="/student/lab" class="link1"></router-link>
<router-link to="/student/lab" class="link2"></router-link> <router-link to="/student/contest/score" class="link2"></router-link>
<router-link to="/student/contest" class="link3"></router-link> <router-link to="/student/contest" class="link3"></router-link>
</div> </div>
<div class="select-group"> <div class="select-group">
<el-select size="large" placeholder="我的实验课程" @change="handleChange($event, 1)"> <el-select size="large" placeholder="我的实验课程" @change="handleChange($event, 1)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option> <el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
<!-- <el-select size="large" placeholder="我的陪练项目" @change="handleChange($event, 2)"> <el-select size="large" placeholder="我的大赛项目" value-key="id" @change="handleContestChange">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option> <el-option v-for="item in contestList" :key="item.id" :label="item.name" :value="item"></el-option>
</el-select> -->
<el-select size="large" placeholder="我的大赛项目" @change="handleChange($event, 3)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
<el-select size="large" placeholder="我的大赛成绩" @change="handleChange($event, 4)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
</div> </div>
</template> </template>
......
...@@ -17,6 +17,10 @@ function handleChange(id: string, type: number) { ...@@ -17,6 +17,10 @@ function handleChange(id: string, type: number) {
router.push({ path: '/admin/lab/book', query: { experiment_id: id } }) router.push({ path: '/admin/lab/book', query: { experiment_id: id } })
} else if (type === 2) { } else if (type === 2) {
router.push({ path: '/admin/lab/video', query: { experiment_id: id } }) router.push({ path: '/admin/lab/video', query: { experiment_id: id } })
} else if (type === 3) {
router.push({ path: '/admin/lab/discuss', query: { experiment_id: id } })
} else if (type === 4) {
router.push({ path: '/admin/lab/score', query: { experiment_id: id } })
} }
} }
</script> </script>
...@@ -35,15 +39,12 @@ function handleChange(id: string, type: number) { ...@@ -35,15 +39,12 @@ function handleChange(id: string, type: number) {
<el-select size="large" placeholder="实验视频" @change="handleChange($event, 2)"> <el-select size="large" placeholder="实验视频" @change="handleChange($event, 2)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option> <el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
<!-- <el-select size="large" placeholder="实验答疑" @change="handleChange($event, 3)"> <el-select size="large" placeholder="实验答疑" @change="handleChange($event, 3)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option> <el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
<el-select size="large" placeholder="实验成绩" @change="handleChange($event, 4)"> <el-select size="large" placeholder="实验成绩" @change="handleChange($event, 4)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option> <el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
<el-select size="large" placeholder="大赛评分" @change="handleChange($event, 5)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select> -->
</div> </div>
</template> </template>
......
import type { SystemDictionary } from '@/types'
export interface ExperimentItem { export interface ExperimentItem {
id: string id: string
name: string name: string
...@@ -16,3 +18,8 @@ export interface ExperimentType { ...@@ -16,3 +18,8 @@ export interface ExperimentType {
course_id: string course_id: string
organ_id: string organ_id: string
} }
export interface ContestType {
id: string
name: string
}
...@@ -28,7 +28,7 @@ const typeText = $computed(() => { ...@@ -28,7 +28,7 @@ const typeText = $computed(() => {
<li>参赛形式:{{ typeText }}</li> <li>参赛形式:{{ typeText }}</li>
<li>所属学校:{{ data.org_name }}</li> <li>所属学校:{{ data.org_name }}</li>
</ul> </ul>
<router-link :to="`/student/contest/lab/${data.id}`" v-if="isMy"> <router-link :to="`/student/contest/lab/${data.id}?name=${data.name}`" v-if="isMy">
<el-button round type="primary">我要训练</el-button> <el-button round type="primary">我要训练</el-button>
</router-link> </router-link>
<router-link :to="{ path: '/student/contest/join', query: { id: data.id, name: data.name } }" v-else> <router-link :to="{ path: '/student/contest/join', query: { id: data.id, name: data.name } }" v-else>
...@@ -68,7 +68,7 @@ const typeText = $computed(() => { ...@@ -68,7 +68,7 @@ const typeText = $computed(() => {
.logo { .logo {
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover; object-fit: contain;
} }
&:hover { &:hover {
.cover { .cover {
......
...@@ -99,6 +99,7 @@ function uploadPicture(url: string) { ...@@ -99,6 +99,7 @@ function uploadPicture(url: string) {
<section class="lab"> <section class="lab">
<div class="lab-left" :class="{ 'is-hidden': !leftPanelVisible }"> <div class="lab-left" :class="{ 'is-hidden': !leftPanelVisible }">
<div class="lab-left__inner"> <div class="lab-left__inner">
<h1>{{ $route.query.name }}</h1>
<el-tabs type="border-card" stretch> <el-tabs type="border-card" stretch>
<el-tab-pane label="实训指导" lazy> <el-tab-pane label="实训指导" lazy>
<Book :competition_id="id"></Book> <Book :competition_id="id"></Book>
...@@ -120,14 +121,12 @@ function uploadPicture(url: string) { ...@@ -120,14 +121,12 @@ function uploadPicture(url: string) {
<path <path
class="path-wapper" class="path-wapper"
d="M0 0l14.12 8.825A4 4 0 0116 12.217v61.566a4 4 0 01-1.88 3.392L0 86V0z" d="M0 0l14.12 8.825A4 4 0 0116 12.217v61.566a4 4 0 01-1.88 3.392L0 86V0z"
fill="#e1e4eb" fill="#e1e4eb"></path>
></path>
<path <path
class="path-arrow" class="path-arrow"
d="M10.758 48.766a.778.778 0 000-1.127L6.996 43l3.762-4.639a.778.778 0 000-1.127.85.85 0 00-1.172 0l-4.344 5.202a.78.78 0 000 1.128l4.344 5.202a.85.85 0 001.172 0z" d="M10.758 48.766a.778.778 0 000-1.127L6.996 43l3.762-4.639a.778.778 0 000-1.127.85.85 0 00-1.172 0l-4.344 5.202a.78.78 0 000 1.128l4.344 5.202a.85.85 0 001.172 0z"
fill="#8D9EA7" fill="#8D9EA7"
fill-rule="nonzero" fill-rule="nonzero"></path>
></path>
</g> </g>
</svg> </svg>
</div> </div>
...@@ -179,6 +178,9 @@ function uploadPicture(url: string) { ...@@ -179,6 +178,9 @@ function uploadPicture(url: string) {
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
h1 {
margin-bottom: 20px;
}
} }
.el-tabs { .el-tabs {
flex: 1; flex: 1;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论