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

chore: update

上级 f517ef2b
...@@ -49,6 +49,11 @@ export function getProjectList(params: { organization_id?: string; project_id?: ...@@ -49,6 +49,11 @@ export function getProjectList(params: { organization_id?: string; project_id?:
return httpRequest.get('/api/resource/v1/util/members', { params }) return httpRequest.get('/api/resource/v1/util/members', { params })
} }
// 获取赛项列表
export function getContestList(params?: { name?: string }) {
return httpRequest.get('/api/resource/v1/backend/competition/menu-list', { params })
}
// 获取待办消息 // 获取待办消息
// https://gitlab.ezijing.com/root/api-documents/-/blob/master/messages/api/%E4%B8%80%E6%9C%9F%E7%AB%99%E5%86%85%E4%BF%A1%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3.md#%E8%8E%B7%E5%8F%96%E7%AB%99%E5%86%85%E4%BF%A1%E6%B6%88%E6%81%AF%E5%88%97%E8%A1%A8 // https://gitlab.ezijing.com/root/api-documents/-/blob/master/messages/api/%E4%B8%80%E6%9C%9F%E7%AB%99%E5%86%85%E4%BF%A1%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3.md#%E8%8E%B7%E5%8F%96%E7%AB%99%E5%86%85%E4%BF%A1%E6%B6%88%E6%81%AF%E5%88%97%E8%A1%A8
export function getMessages(params: { export function getMessages(params: {
......
import { getContestList } from '@/api/base'
// 赛项信息
interface ContestType {
id: string
name: string
}
const contests = ref<ContestType[]>([])
export function useGetContestList() {
!contests.value.length &&
getContestList().then((res: any) => {
contests.value = res.data.list
})
return { contests }
}
...@@ -33,7 +33,7 @@ watchEffect(() => { ...@@ -33,7 +33,7 @@ watchEffect(() => {
<el-button type="primary" round :icon="Upload" @click="handleImport">本地上传</el-button> <el-button type="primary" round :icon="Upload" @click="handleImport">本地上传</el-button>
<p> <p>
<a <a
href="https://webapp-pub.ezijing.com/project/saas-lab/%E5%AE%9E%E9%AA%8C%E6%88%90%E7%BB%A9%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx" href="https://webapp-pub.ezijing.com/project/saas-lab/%E5%8F%82%E8%B5%9B%E9%80%89%E6%89%8B%E6%A8%A1%E6%9D%BF.xlsx"
download download
>下载模板</a >下载模板</a
> >
......
...@@ -4,6 +4,7 @@ import { Upload } from '@element-plus/icons-vue' ...@@ -4,6 +4,7 @@ import { Upload } from '@element-plus/icons-vue'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import { getContestantList } from '../api' import { getContestantList } from '../api'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
import { useGetContestList } from '@/composables/useGetContestList'
const FormDialog = defineAsyncComponent(() => import('../components/FormDialog.vue')) const FormDialog = defineAsyncComponent(() => import('../components/FormDialog.vue'))
const ViewDialog = defineAsyncComponent(() => import('../components/ViewDialog.vue')) const ViewDialog = defineAsyncComponent(() => import('../components/ViewDialog.vue'))
...@@ -12,43 +13,49 @@ const ImportDialog = defineAsyncComponent(() => import('../components/ImportDial ...@@ -12,43 +13,49 @@ const ImportDialog = defineAsyncComponent(() => import('../components/ImportDial
const appList = $ref<InstanceType<typeof AppList> | null>(null) const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 性别 // 性别
const genderList = useMapStore().getMapValuesByKey('system_gender') const genderList = useMapStore().getMapValuesByKey('system_gender')
const { contests } = useGetContestList()
// 列表配置 // 列表配置
const listOptions = { const listOptions = $computed(() => {
remote: { return {
httpRequest: getContestantList, remote: {
params: { competition_id: '', student_name: '' } httpRequest: getContestantList,
}, params: { competition_id: '', student_name: '' }
filters: [
{
type: 'select',
prop: 'competition_id',
label: '赛项',
placeholder: '请选择赛项'
}, },
{ type: 'input', prop: 'student_name', label: '选手姓名', placeholder: '请输入选手姓名' } filters: [
], {
columns: [ type: 'select',
{ label: '序号', type: 'index', width: 60 }, prop: 'competition_id',
{ label: '赛项名称', prop: 'competition.name' }, label: '赛项',
{ label: '选手姓名', prop: 'student.name' }, placeholder: '请选择赛项',
{ label: '参赛ID', prop: 'login_id' }, options: contests.value,
{ valueKey: 'id',
label: '性别', labelKey: 'name'
prop: 'student.gender', },
computed({ row }: { row: Contestant }) { { type: 'input', prop: 'student_name', label: '选手姓名', placeholder: '请输入选手姓名' }
const found = genderList.find(item => item.value === row.student.gender) ],
return found?.label || row.student.gender columns: [
} { label: '序号', type: 'index', width: 60 },
}, { label: '赛项名称', prop: 'competition.name' },
{ label: '学校', prop: 'student.org.department_name' }, { label: '选手姓名', prop: 'student.name' },
{ label: '所在专业', prop: 'student.specialty.name' }, { label: '参赛ID', prop: 'login_id' },
{ label: '所在年级', prop: 'grade' }, {
{ label: '所在班级', prop: 'student.class.name' }, label: '性别',
{ label: '训练次数', prop: 'train_count' }, prop: 'student.gender',
{ label: '更新时间', prop: 'updated_time' }, computed({ row }: { row: Contestant }) {
{ label: '操作', slots: 'table-x', width: 200 } const found = genderList.find(item => item.value === row.student.gender)
] return found?.label || row.student.gender
} }
},
{ label: '学校', prop: 'student.org.department_name' },
{ label: '所在专业', prop: 'student.specialty.name' },
{ label: '所在年级', prop: 'grade' },
{ label: '所在班级', prop: 'student.class.name' },
{ label: '训练次数', prop: 'train_count' },
{ label: '更新时间', prop: 'updated_time' },
{ label: '操作', slots: 'table-x', width: 200 }
]
}
})
const importVisible = $ref(false) const importVisible = $ref(false)
let dialogVisible = $ref(false) let dialogVisible = $ref(false)
......
...@@ -78,3 +78,27 @@ export function updateContestVideo(data: ContestVideoUpdateParams) { ...@@ -78,3 +78,27 @@ export function updateContestVideo(data: ContestVideoUpdateParams) {
export function deleteContestVideo(data: { id: string }) { export function deleteContestVideo(data: { id: string }) {
return httpRequest.post('/api/resource/v1/backend/competition-video/delete', data) return httpRequest.post('/api/resource/v1/backend/competition-video/delete', data)
} }
// 获取赛项评分专家列表
export function getContestJudgeList(params: { id: string }) {
return httpRequest.get('/api/resource/v1/backend/competition/experts', { params })
}
// 获取赛项未绑定的评分专家列表
export function getContestUnbindJudgeList(params: { competition_id: string }) {
return httpRequest.get('/api/resource/v1/backend/expert/unbind-competition-list', { params })
}
// 更新赛项评分专家
export function updateContestJudge(data: { id: string; experts: Record<string, any>[] }) {
return httpRequest.post('/api/resource/v1/backend/competition/bind-experts', data, {
headers: { 'Content-Type': 'application/json' }
})
}
// 获取评分专家详情
export function getJudge(params: { id: string }) {
return httpRequest.get('/api/resource/v1/backend/expert/detail', { params })
}
// 获取赛项选手列表
export function getContestContestantList(params?: { student_name?: string; page?: number; 'per-page'?: number }) {
return httpRequest.get('/api/resource/v1/backend/competition-competitor/list', { params })
}
<script setup lang="ts">
import type { ContestItem } from '../types'
import AppList from '@/components/base/AppList.vue'
import { getContestContestantList } from '../api'
import { useMapStore } from '@/stores/map'
const detail = $ref<ContestItem>(inject('detail'))
const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 性别
const genderList = useMapStore().getMapValuesByKey('system_gender')
const listOptions = {
remote: {
httpRequest: getContestContestantList,
params: { competition_id: detail.id, student_name: '' }
},
filters: [{ type: 'input', prop: 'student_name', label: '选手姓名', placeholder: '请输入选手姓名' }],
columns: [
{ label: '序号', type: 'index', width: 60 },
{ label: '赛项名称', prop: 'competition.name' },
{ label: '选手姓名', prop: 'student.name' },
{ label: '参赛ID', prop: 'login_id' },
{
label: '性别',
prop: 'student.gender',
computed({ row }: { row: any }) {
const found = genderList.find(item => item.value === row.student.gender)
return found?.label || row.student.gender
}
},
{ label: '学校', prop: 'student.org.department_name' },
{ label: '所在专业', prop: 'student.specialty.name' },
{ label: '所在年级', prop: 'grade' },
{ label: '所在班级', prop: 'student.class.name' },
{ label: '训练次数', prop: 'train_count' },
{ label: '更新时间', prop: 'updated_time' }
]
}
</script>
<template>
<el-dialog title="参赛选手列表">
<AppList v-bind="listOptions" ref="appList"></AppList>
<el-row justify="center">
<el-button round auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button>
</el-row>
</el-dialog>
</template>
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import type { ContestItem } from '../types'
import { getContestUnbindJudgeList, getJudge } from '../api'
import { useMapStore } from '@/stores/map'
const emit = defineEmits<{
(e: 'add', data: any): void
(e: 'update:modelValue', visible: boolean): void
}>()
// 角色列表
const roleList = useMapStore().getMapValuesByKey('expert_role')
const detail = $ref<ContestItem>(inject('detail'))
let list = $ref<any>([])
function fetchList() {
getContestUnbindJudgeList({ competition_id: detail.id }).then(res => {
list = res.data.list || []
})
}
let info = $ref<any>()
function fetchInfo(id: string) {
if (id) {
getJudge({ id }).then(res => {
info = res.data.detail
})
} else {
info = undefined
}
}
onMounted(() => {
fetchList()
})
const formRef = $ref<FormInstance>()
const form = reactive({
role: '',
id: ''
})
const rules = ref<FormRules>({
role: [{ required: true, message: '请选择角色', trigger: 'change' }],
id: [{ required: true, message: '请选择专家', trigger: 'change' }]
})
// 添加
function handleSubmit() {
formRef?.validate().then(() => {
emit('add', Object.assign(info, { info: { role: form.role, id: '0' }, expert_id: form.id, id: '0' }))
emit('update:modelValue', false)
})
}
</script>
<template>
<el-dialog title="添加专家" width="500px" @update:modelValue="$emit('update:modelValue')">
<el-form ref="formRef" :model="form" :rules="rules" label-position="right" label-width="100px" label-suffix=":">
<el-form-item label="赛项名称">{{ detail.name }}</el-form-item>
<el-form-item label="角色" prop="role">
<el-select v-model="form.role" style="width: 100%">
<el-option v-for="item in roleList" :key="item.id" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="专家" prop="id">
<el-select v-model="form.id" @change="fetchInfo" style="width: 100%">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<template v-if="info">
<el-form-item label="联系电话">{{ info.mobile }}</el-form-item>
<el-form-item label="所在单位">{{ info.company }}</el-form-item>
<el-form-item label="职务">{{ info.position.label }}</el-form-item>
</template>
</el-form>
<el-row justify="center">
<el-button type="primary" round auto-insert-space @click="handleSubmit">添加</el-button>
<el-button round auto-insert-space @click="$emit('update:modelValue', false)">取消</el-button>
</el-row>
</el-dialog>
</template>
<script setup lang="ts">
import type { ContestItem } from '../types'
import { CirclePlus } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import AppList from '@/components/base/AppList.vue'
import { getContestJudgeList, updateContestJudge } from '../api'
import { useMapStore } from '@/stores/map'
const emit = defineEmits<{
(e: 'update:modelValue', visible: boolean): void
}>()
const JudgeAddDialog = defineAsyncComponent(() => import('./JudgeAddDialog.vue'))
const detail = $ref<ContestItem>(inject('detail'))
const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 性别
const genderList = useMapStore().getMapValuesByKey('system_gender')
// 角色列表
const roleList = useMapStore().getMapValuesByKey('expert_role')
let list = $ref<any>([])
function fetchList() {
getContestJudgeList({ id: detail.id }).then((res: any) => {
list = res.data.detail
})
}
onMounted(() => {
fetchList()
})
// 列表配置
const listOptions = $computed(() => {
return {
hasPagination: false,
columns: [
{ label: '序号', type: 'index', width: 60 },
{ label: '专家姓名', prop: 'name' },
{ label: '所在单位', prop: 'company' },
{
label: '性别',
prop: 'sex',
computed({ row }: { row: any }) {
const found = genderList.find(item => item.value === row.sex)
return found?.label || row.sex
}
},
{ label: '职务', prop: 'position.label' },
{ label: '省', prop: 'province' },
{ label: '市', prop: 'city' },
{ label: '区/县', prop: 'area' },
{ label: '更新时间', prop: 'updated_time' },
{
label: '角色',
prop: 'info.role',
computed({ row }: { row: any }) {
const found = roleList.find(item => item.value === row.info.role)
return found?.label || row.info.role
}
},
{ label: '操作', slots: 'table-x', width: 80 }
],
data: list
}
})
const dialogVisible = $ref(false)
function handleAdd(data: any) {
list.push(data)
}
// 保存
function handleSubmit() {
const experts = list.map((item: any) => {
return { id: item.id, expert_id: item.expert_id, role: item.info.role }
})
updateContestJudge({ id: detail.id, experts }).then(() => {
ElMessage.success('保存成功')
emit('update:modelValue', false)
})
}
// 移除
function handleRemoveClass(index: number) {
ElMessageBox.confirm('确定要移除吗?', '提示').then(() => {
list.splice(index, 1)
})
}
</script>
<template>
<el-dialog title="评分专家列表" :close-on-click-modal="false" @update:modelValue="$emit('update:modelValue')">
<AppList v-bind="listOptions" ref="appList">
<template #header-buttons>
<el-row justify="space-between">
<el-button type="primary" :icon="CirclePlus" @click="dialogVisible = true">添加专家</el-button>
<p>赛项名称: {{ detail.name }}</p>
</el-row>
</template>
<template #table-x="{ $index }">
<el-button link round type="danger" @click="handleRemoveClass($index)">移除</el-button>
</template>
</AppList>
<el-row justify="center">
<el-button type="primary" round auto-insert-space @click="handleSubmit">保存</el-button>
<el-button round auto-insert-space @click="$emit('update:modelValue', false)">取消</el-button>
</el-row>
<JudgeAddDialog v-model="dialogVisible" @add="handleAdd" v-if="dialogVisible"></JudgeAddDialog>
</el-dialog>
</template>
...@@ -7,6 +7,8 @@ import dayjs from 'dayjs' ...@@ -7,6 +7,8 @@ import dayjs from 'dayjs'
const ViewBook = defineAsyncComponent(() => import('../components/ViewBook.vue')) const ViewBook = defineAsyncComponent(() => import('../components/ViewBook.vue'))
const ViewVideo = defineAsyncComponent(() => import('../components/ViewVideo.vue')) const ViewVideo = defineAsyncComponent(() => import('../components/ViewVideo.vue'))
const JudgingRulesDialog = defineAsyncComponent(() => import('../components/JudgingRulesDialog.vue')) const JudgingRulesDialog = defineAsyncComponent(() => import('../components/JudgingRulesDialog.vue'))
const JudgeDialog = defineAsyncComponent(() => import('../components/JudgeDialog.vue'))
const ContestantDialog = defineAsyncComponent(() => import('../components/ContestantDialog.vue'))
interface Props { interface Props {
id: string id: string
...@@ -52,15 +54,20 @@ function formatDate(timestamp: number): string { ...@@ -52,15 +54,20 @@ function formatDate(timestamp: number): string {
function formatDateTime(timestamp: number): string { function formatDateTime(timestamp: number): string {
return dayjs(timestamp * 1000).format('YYYY-MM-DD HH:mm:ss') return dayjs(timestamp * 1000).format('YYYY-MM-DD HH:mm:ss')
} }
// 评分规则
const judgingRulesVisible = $ref(false) const judgingRulesVisible = $ref(false)
// 评分专家
const judgeVisible = $ref(false)
// 参赛选手
const contestantVisible = $ref(false)
</script> </script>
<template> <template>
<AppCard title="查看赛项信息"> <AppCard title="查看赛项信息">
<template #header-aside> <template #header-aside>
<el-button type="primary" @click="judgingRulesVisible = true">评分规则</el-button> <el-button type="primary" @click="judgingRulesVisible = true">评分规则</el-button>
<el-button type="primary">评分专家</el-button> <el-button type="primary" @click="judgeVisible = true">评分专家</el-button>
<el-button type="primary">参赛选手</el-button> <el-button type="primary" @click="contestantVisible = true">参赛选手</el-button>
<el-button type="primary">评分细则</el-button> <el-button type="primary">评分细则</el-button>
</template> </template>
<div class="top" v-if="detail"> <div class="top" v-if="detail">
...@@ -91,7 +98,12 @@ const judgingRulesVisible = $ref(false) ...@@ -91,7 +98,12 @@ const judgingRulesVisible = $ref(false)
<AppCard title="操作视频"> <AppCard title="操作视频">
<ViewVideo :id="id"></ViewVideo> <ViewVideo :id="id"></ViewVideo>
</AppCard> </AppCard>
<!-- 评分规则 -->
<JudgingRulesDialog v-model="judgingRulesVisible" v-if="judgingRulesVisible && detail"></JudgingRulesDialog> <JudgingRulesDialog v-model="judgingRulesVisible" v-if="judgingRulesVisible && detail"></JudgingRulesDialog>
<!-- 评分专家 -->
<JudgeDialog v-model="judgeVisible" v-if="judgeVisible && detail"></JudgeDialog>
<!-- 参赛选手 -->
<ContestantDialog v-model="contestantVisible" v-if="contestantVisible && detail"></ContestantDialog>
</template> </template>
<style lang="scss"> <style lang="scss">
......
...@@ -4,6 +4,7 @@ import { CirclePlus, Upload } from '@element-plus/icons-vue' ...@@ -4,6 +4,7 @@ import { CirclePlus, Upload } from '@element-plus/icons-vue'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import { getJudgeList } from '../api' import { getJudgeList } from '../api'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
import { useGetContestList } from '@/composables/useGetContestList'
const ViewDialog = defineAsyncComponent(() => import('../components/ViewDialog.vue')) const ViewDialog = defineAsyncComponent(() => import('../components/ViewDialog.vue'))
const FormDialog = defineAsyncComponent(() => import('../components/FormDialog.vue')) const FormDialog = defineAsyncComponent(() => import('../components/FormDialog.vue'))
...@@ -13,42 +14,48 @@ const appList = $ref<InstanceType<typeof AppList> | null>(null) ...@@ -13,42 +14,48 @@ const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 性别 // 性别
const genderList = useMapStore().getMapValuesByKey('system_gender') const genderList = useMapStore().getMapValuesByKey('system_gender')
const { contests } = useGetContestList()
// 列表配置 // 列表配置
const listOptions = { const listOptions = $computed(() => {
remote: { return {
httpRequest: getJudgeList, remote: {
params: { competition_id: '', name: '' } httpRequest: getJudgeList,
}, params: { competition_id: '', name: '' }
filters: [
{
type: 'select',
prop: 'competition_id',
label: '赛项',
placeholder: '请选择赛项'
}, },
{ type: 'input', prop: 'name', label: '专家姓名', placeholder: '请输入专家姓名' } filters: [
], {
columns: [ type: 'select',
{ label: '序号', type: 'index', width: 60 }, prop: 'competition_id',
{ label: '专家姓名', prop: 'name' }, label: '赛项',
{ label: '所在单位', prop: 'company' }, placeholder: '请选择赛项',
{ options: contests.value,
label: '性别', valueKey: 'id',
prop: 'sex', labelKey: 'name'
computed({ row }: { row: Judge }) { },
const found = genderList.find(item => item.value === row.sex) { type: 'input', prop: 'name', label: '专家姓名', placeholder: '请输入专家姓名' }
return found?.label || row.sex ],
} columns: [
}, { label: '序号', type: 'index', width: 60 },
{ label: '职务', prop: 'position.label' }, { label: '专家姓名', prop: 'name' },
{ label: '省', prop: 'province' }, { label: '所在单位', prop: 'company' },
{ label: '市', prop: 'city' }, {
{ label: '区/县', prop: 'area' }, label: '性别',
{ label: '批改次数', prop: 'check_count' }, prop: 'sex',
{ label: '更新时间', prop: 'updated_time' }, computed({ row }: { row: Judge }) {
{ label: '操作', slots: 'table-x', width: 200 } const found = genderList.find(item => item.value === row.sex)
] return found?.label || row.sex
} }
},
{ label: '职务', prop: 'position.label' },
{ label: '省', prop: 'province' },
{ label: '市', prop: 'city' },
{ label: '区/县', prop: 'area' },
{ label: '批改次数', prop: 'check_count' },
{ label: '更新时间', prop: 'updated_time' },
{ label: '操作', slots: 'table-x', width: 200 }
]
}
})
const importVisible = $ref(false) const importVisible = $ref(false)
const rowData = ref<Judge | undefined | null>(null) const rowData = ref<Judge | undefined | null>(null)
......
...@@ -5,6 +5,7 @@ import { useUserStore } from '@/stores/user' ...@@ -5,6 +5,7 @@ import { useUserStore } from '@/stores/user'
interface State { interface State {
studentMenus: IMenuItem[] studentMenus: IMenuItem[]
adminMenus: IMenuItem[] adminMenus: IMenuItem[]
teacherMenus: IMenuItem[]
} }
// 学生菜单 // 学生菜单
...@@ -13,21 +14,13 @@ const studentMenus: IMenuItem[] = [ ...@@ -13,21 +14,13 @@ const studentMenus: IMenuItem[] = [
name: '智能营销', name: '智能营销',
path: '/student/lab' path: '/student/lab'
}, },
// {
// name: '智能陪练',
// path: '/student/ai'
// },
// {
// name: '成绩分析',
// path: '/admin/contest/score'
// },
{ {
name: '技能大赛', name: '技能大赛',
path: '/student/contest' path: '/student/contest'
} }
] ]
// 教师、管理员菜单 // 教师、专家菜单
const adminMenus: IMenuItem[] = [ const teacherMenus: IMenuItem[] = [
{ {
name: '智能营销', name: '智能营销',
path: '/teacher/lab', path: '/teacher/lab',
...@@ -55,34 +48,29 @@ const adminMenus: IMenuItem[] = [ ...@@ -55,34 +48,29 @@ const adminMenus: IMenuItem[] = [
} }
] ]
}, },
// {
// name: '智能陪练',
// path: '/admin/ai'
// },
// {
// name: '成绩分析',
// path: '/admin/contest/score'
// },
{ {
name: '技能大赛', name: '技能大赛',
path: '/admin/contest', path: '/teacher/contest',
children: [ children: [
{ {
name: '赛项管理', name: '训练答疑',
path: '/admin/contest/items' path: '/teacher/contest/items'
}, },
{ {
name: '参赛选手管理', name: '大赛评分',
path: '/admin/contest/contestants' path: '/teacher/contest/contestants'
}, },
{ {
name: '评分专家管理', name: '发布成绩',
path: '/admin/contest/judges' path: '/teacher/contest/judges'
} }
] ]
}, }
]
// 管理员菜单
const adminMenus: IMenuItem[] = [
{ {
name: '系统管理', name: '智能营销',
path: '/admin/lab', path: '/admin/lab',
tag: 'v1-backend-experiment', tag: 'v1-backend-experiment',
children: [ children: [
...@@ -92,6 +80,24 @@ const adminMenus: IMenuItem[] = [ ...@@ -92,6 +80,24 @@ const adminMenus: IMenuItem[] = [
tag: 'v1-backend-experiment' tag: 'v1-backend-experiment'
} }
] ]
},
{
name: '技能大赛',
path: '/admin/contest',
children: [
{
name: '赛项管理',
path: '/admin/contest/items'
},
{
name: '参赛选手管理',
path: '/admin/contest/contestants'
},
{
name: '评分专家管理',
path: '/admin/contest/judges'
}
]
} }
] ]
...@@ -99,12 +105,19 @@ export const useMenuStore = defineStore({ ...@@ -99,12 +105,19 @@ export const useMenuStore = defineStore({
id: 'menu', id: 'menu',
state: (): State => ({ state: (): State => ({
studentMenus, studentMenus,
adminMenus adminMenus,
teacherMenus
}), }),
getters: { getters: {
menus: state => { menus: state => {
const userStore = useUserStore() const userStore = useUserStore()
return userStore.role?.id === 1 ? state.studentMenus : state.adminMenus if (userStore.role?.id === 6) {
return state.adminMenus
} else if (userStore.role?.id === 5) {
return state.teacherMenus
} else {
return state.studentMenus
}
} }
}, },
actions: {} actions: {}
......
...@@ -3,9 +3,9 @@ import { defineStore } from 'pinia' ...@@ -3,9 +3,9 @@ import { defineStore } from 'pinia'
import { getUser, logout } from '@/api/base' import { getUser, logout } from '@/api/base'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
// 角色信息(1学员;5教师) // 角色信息(1学员;5教师; 6管理员)
interface Role { interface Role {
id: 1 | 5 id: 1 | 5 | 6
name: string name: string
} }
interface State { interface State {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论