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

chore: update

上级 718c4ccf
import httpRequest from '@/utils/axios'
import type { JudgeCreateParams, JudgeUpdateParams } from './types'
import type { ExpertCreateParams, ExpertUpdateParams } from './types'
// 获取评分专家列表
export function getJudgeList(params?: { name?: string; page?: number; 'per-page'?: number }) {
export function getExpertList(params?: { name?: string; page?: number; 'per-page'?: number }) {
return httpRequest.get('/api/resource/v1/backend/expert/list', { params })
}
// 获取评分专家详情
export function getJudge(params: { id: string }) {
export function getExpert(params: { id: string }) {
return httpRequest.get('/api/resource/v1/backend/expert/detail', { params })
}
// 创建评分专家
export function createJudge(data: JudgeCreateParams) {
export function createExpert(data: ExpertCreateParams) {
return httpRequest.post('/api/resource/v1/backend/expert/create', data)
}
// 修改评分专家
export function updateJudge(data: JudgeUpdateParams) {
export function updateExpert(data: ExpertUpdateParams) {
return httpRequest.post('/api/resource/v1/backend/expert/update', data)
}
// 修改评分专家
export function importJudge(data: { file: File }) {
export function importExpert(data: { file: File }) {
return httpRequest.post('/api/resource/v1/backend/expert/import-exports', data, {
headers: { 'Content-Type': 'multipart/form-data' }
})
}
// 获取评分专家赛项列表
export function getJudgeContestList(params: { id: string }) {
export function getExpertContestList(params: { id: string }) {
return httpRequest.get('/api/resource/v1/backend/expert/competitions', { params })
}
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import type { Judge, JudgeCreateParams } from '../types'
import type { Expert, ExpertCreateParams } from '../types'
import { ElMessage } from 'element-plus'
import { createJudge, updateJudge } from '../api'
import { createExpert, updateExpert } from '../api'
import { useMapStore } from '@/stores/map'
import { useArea } from '@/composables/useArea'
interface Props {
data?: Judge
data?: Expert
}
const props = defineProps<Props>()
......@@ -23,7 +23,7 @@ const genderList = useMapStore().getMapValuesByKey('system_gender')
const positionList = useMapStore().getMapValuesByKey('expert_position')
const formRef = $ref<FormInstance>()
const form = reactive<JudgeCreateParams>({
const form = reactive<ExpertCreateParams>({
name: '',
mobile: '',
company: '',
......@@ -74,7 +74,7 @@ function handleSubmit() {
}
// 新增
function handleCreate() {
createJudge(form).then(() => {
createExpert(form).then(() => {
ElMessage({ message: '创建成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
......@@ -83,7 +83,7 @@ function handleCreate() {
// 修改
function handleUpdate() {
if (!props.data?.id) return
updateJudge({ id: props.data.id, ...form }).then(() => {
updateExpert({ id: props.data.id, ...form }).then(() => {
ElMessage({ message: '修改成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
......
......@@ -3,7 +3,7 @@ import { Upload } from '@element-plus/icons-vue'
import { useFileDialog } from '@vueuse/core'
import { ElMessage } from 'element-plus'
import { importJudge } from '../api'
import { importExpert } from '../api'
const emit = defineEmits<{
(e: 'update'): void
......@@ -20,7 +20,7 @@ function handleImport() {
watchEffect(() => {
if (!files.value?.length) return
const [file] = files.value
importJudge({ file }).then(() => {
importExpert({ file }).then(() => {
ElMessage({ message: '导入成功', type: 'success' })
emit('update')
})
......
<script setup lang="ts">
import type { Judge } from '../types'
import { getJudgeContestList } from '../api'
import type { Expert } from '../types'
import { getExpertContestList } from '../api'
import { useMapStore } from '@/stores/map'
interface Props {
data: Judge
data: Expert
}
const props = defineProps<Props>()
......@@ -15,7 +15,7 @@ const roleList = useMapStore().getMapValuesByKey('expert_role')
const listOptions = {
hasPagination: false,
remote: {
httpRequest: getJudgeContestList,
httpRequest: getExpertContestList,
params: { id: props.data.id },
callback(res: any) {
return { list: res.detail.competitions }
......
......@@ -3,7 +3,7 @@ import AppLayout from '@/components/layout/Index.vue'
export const routes: Array<RouteRecordRaw> = [
{
path: '/admin/contest/judges',
path: '/admin/contest/experts',
component: AppLayout,
children: [{ path: '', component: () => import('./views/Index.vue') }]
}
......
export interface Judge {
export interface Expert {
id: string
sso_id: string
name: string
......@@ -12,20 +12,20 @@ export interface Judge {
updated_operator: string
created_time: string
updated_time: string
position: JudgePosition
competition: JudgeCompetition
position: ExpertPosition
competition: ExpertCompetition
check_count: 1
}
export interface JudgePosition {
export interface ExpertPosition {
id: string
label: string
value: string
}
export interface JudgeCompetition {
export interface ExpertCompetition {
id: string
name: string
}
export interface JudgeCreateParams {
export interface ExpertCreateParams {
name: string
mobile: string
company: string
......@@ -36,4 +36,4 @@ export interface JudgeCreateParams {
area: string
}
export type JudgeUpdateParams = JudgeCreateParams & { id: string }
export type ExpertUpdateParams = ExpertCreateParams & { id: string }
<script setup lang="ts">
import type { Judge } from '../types'
import type { Expert } from '../types'
import { CirclePlus, Upload } from '@element-plus/icons-vue'
import AppList from '@/components/base/AppList.vue'
import { getJudgeList } from '../api'
import { getExpertList } from '../api'
import { useMapStore } from '@/stores/map'
import { useGetContestList } from '@/composables/useGetContestList'
......@@ -19,7 +19,7 @@ const { contests } = useGetContestList()
const listOptions = $computed(() => {
return {
remote: {
httpRequest: getJudgeList,
httpRequest: getExpertList,
params: { competition_id: '', name: '' }
},
filters: [
......@@ -41,7 +41,7 @@ const listOptions = $computed(() => {
{
label: '性别',
prop: 'sex',
computed({ row }: { row: Judge }) {
computed({ row }: { row: Expert }) {
const found = genderList.find(item => item.value === row.sex)
return found?.label || row.sex
}
......@@ -58,11 +58,11 @@ const listOptions = $computed(() => {
})
const importVisible = $ref(false)
const rowData = ref<Judge | undefined | null>(null)
const rowData = ref<Expert | undefined | null>(null)
// 查看
let viewDialogVisible = $ref(false)
function handleView(row: Judge) {
function handleView(row: Expert) {
rowData.value = row
viewDialogVisible = true
}
......@@ -75,7 +75,7 @@ function handleAdd() {
// 编辑
let dialogVisible = $ref(false)
function handleUpdate(row: Judge) {
function handleUpdate(row: Expert) {
rowData.value = row
dialogVisible = true
}
......@@ -93,7 +93,7 @@ function onUpdateSuccess() {
<el-button type="primary" round :icon="Upload" @click="importVisible = true">批量导入</el-button>
</template>
<template #table-x="{ row }: { row: Judge }">
<template #table-x="{ row }: { row: Expert }">
<el-button type="primary" round @click="handleView(row)" v-permission="'v1-backend-experiment-view'"
>查看</el-button
>
......
......@@ -18,7 +18,6 @@ const listOptions = {
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' },
{
......
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import type { ContestItem, ContestBookItem, ContestBookUpdateParams } from '../types'
import { ElMessageBox, ElMessage } from 'element-plus'
import { pick } from 'lodash-es'
import AppUpload from '@/components/base/AppUpload.vue'
import { createContestBook, updateContestBook } from '../api'
import { useMapStore } from '@/stores/map'
interface Props {
data: ContestBookItem
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const detail = $ref<ContestItem>(inject('detail'))
// 数据状态
const status = useMapStore().getMapValuesByKey('system_status')
const formRef = $ref<FormInstance>()
const form = reactive<any>({
competition_id: detail.id,
files: [],
url: '',
type: '',
name: '',
status: '1',
protocol: false
})
watchEffect(() => {
if (!props.data) return
form.files = [JSON.parse(props.data.url)]
Object.assign(form, { protocol: true }, props.data)
})
const checkProtocol = (rule: any, value: any, callback: any) => {
if (!value) {
return callback(new Error('请阅读并同意'))
} else {
callback()
}
}
const rules = ref<FormRules>({
files: [{ type: 'array', required: true, message: '请上传评分细则' }],
name: [{ required: true, message: '请输入评分细则名称', trigger: 'blur' }],
course_id: [{ required: true, message: '请选择关联训练课程', trigger: 'change' }],
experiment_id: [{ required: true, message: '请选择关联训练', trigger: 'change' }],
protocol: [{ validator: checkProtocol, message: '请阅读并同意', trigger: 'change' }]
})
const isUpdate = $computed(() => {
return !!props.data?.id
})
function handleBeforeUpload() {
if (form.files.length) {
return ElMessageBox.confirm('系统仅支持1个评分细则,此操作将覆盖原有评分细则文件,确认上传新文件吗?', '提示')
}
return true
}
function handleUploadSuccess(file: any) {
form.name = file.name.split('.').shift()
form.type = file.raw.type || 'unknown'
}
// 提交
function handleSubmit() {
formRef?.validate().then(() => {
const [file] = form.files
const params = Object.assign({}, pick(form, ['competition_id', 'name', 'type', 'status']), {
url: JSON.stringify({ name: file.name, url: file.url, size: file.size })
})
isUpdate ? handleUpdate(params) : handleCreate(params)
})
}
// 新增
function handleCreate(params: ContestBookUpdateParams) {
createContestBook(params).then(() => {
ElMessage({ message: '创建成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
})
}
// 修改
function handleUpdate(params: ContestBookUpdateParams) {
updateContestBook(params).then(() => {
ElMessage({ message: '修改成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
})
}
</script>
<template>
<el-dialog
title="编辑评分细则"
:close-on-click-modal="false"
width="600px"
@update:modelValue="$emit('update:modelValue')"
>
<el-form ref="formRef" :model="form" :rules="rules" label-width="124px">
<el-form-item label="评分细则文件" prop="files">
<AppUpload
v-model="form.files"
:limit="1"
:beforeUpload="handleBeforeUpload"
accept=".doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,.pdf,application/pdf,.ppt,.pptx,application/vnd.ms-powerpoint,.csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
@success="handleUploadSuccess"
>
<template #tip>评分细则文件支持格式包含:doc docx xls xlsx pdf ppt pptx,大小不超过50M</template>
</AppUpload>
</el-form-item>
<el-form-item label="评分细则名称" prop="name">
<el-input v-model="form.name"></el-input>
<p class="form-tips">评分细则名称自动取值于文件名称,可以进行二次修改。</p>
</el-form-item>
<el-form-item label="关联赛项">
<el-input :value="detail.name" disabled></el-input>
</el-form-item>
<el-form-item label="有效状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio v-for="item in status" :key="item.id" :label="item.value">{{ item.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="protocol">
<el-checkbox label="我已阅读并同意" v-model="form.protocol" />
<a
href="https://view.officeapps.live.com/op/view.aspx?src=https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/%E7%B4%AB%E8%8D%86%E6%95%99%E8%82%B2%E7%94%A8%E6%88%B7%E5%85%A5%E9%A9%BB%E5%8F%8A%E7%BD%91%E7%BB%9C%E6%95%99%E5%AD%A6%E8%B5%84%E6%BA%90%E5%8D%8F%E8%AE%AE(1).docx"
target="_blank"
>《紫荆教育用户入驻及网络教学资源协议》</a
>
</el-form-item>
<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-form>
</el-dialog>
</template>
<style lang="scss" scoped>
.form-tips {
font-size: 12px;
color: #999;
}
</style>
......@@ -10,7 +10,7 @@ const emit = defineEmits<{
(e: 'update:modelValue', visible: boolean): void
}>()
const JudgeAddDialog = defineAsyncComponent(() => import('./JudgeAddDialog.vue'))
const ScoringExpertsAddDialog = defineAsyncComponent(() => import('./ScoringExpertsAddDialog.vue'))
const detail = $ref<ContestItem>(inject('detail'))
......@@ -104,6 +104,6 @@ function handleRemoveClass(index: number) {
<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>
<ScoringExpertsAddDialog v-model="dialogVisible" @add="handleAdd" v-if="dialogVisible"></ScoringExpertsAddDialog>
</el-dialog>
</template>
......@@ -6,9 +6,10 @@ import dayjs from 'dayjs'
const ViewBook = defineAsyncComponent(() => import('../components/ViewBook.vue'))
const ViewVideo = defineAsyncComponent(() => import('../components/ViewVideo.vue'))
const JudgingRulesDialog = defineAsyncComponent(() => import('../components/JudgingRulesDialog.vue'))
const JudgeDialog = defineAsyncComponent(() => import('../components/JudgeDialog.vue'))
const ScoringRulesDialog = defineAsyncComponent(() => import('../components/ScoringRulesDialog.vue'))
const ScoringExpertsDialog = defineAsyncComponent(() => import('../components/ScoringExpertsDialog.vue'))
const ContestantDialog = defineAsyncComponent(() => import('../components/ContestantDialog.vue'))
const ScoringBookDialog = defineAsyncComponent(() => import('../components/ScoringBookDialog.vue'))
interface Props {
id: string
......@@ -60,6 +61,8 @@ const judgingRulesVisible = $ref(false)
const judgeVisible = $ref(false)
// 参赛选手
const contestantVisible = $ref(false)
// 评分细则
const judgingBookVisible = $ref(false)
</script>
<template>
......@@ -68,7 +71,7 @@ const contestantVisible = $ref(false)
<el-button type="primary" @click="judgingRulesVisible = true">评分规则</el-button>
<el-button type="primary" @click="judgeVisible = true">评分专家</el-button>
<el-button type="primary" @click="contestantVisible = true">参赛选手</el-button>
<el-button type="primary">评分细则</el-button>
<el-button type="primary" @click="judgingBookVisible = true">评分细则</el-button>
</template>
<div class="top" v-if="detail">
<div class="top-cover">
......@@ -99,11 +102,13 @@ const contestantVisible = $ref(false)
<ViewVideo :id="id"></ViewVideo>
</AppCard>
<!-- 评分规则 -->
<JudgingRulesDialog v-model="judgingRulesVisible" v-if="judgingRulesVisible && detail"></JudgingRulesDialog>
<ScoringRulesDialog v-model="judgingRulesVisible" v-if="judgingRulesVisible && detail"></ScoringRulesDialog>
<!-- 评分专家 -->
<JudgeDialog v-model="judgeVisible" v-if="judgeVisible && detail"></JudgeDialog>
<ScoringExpertsDialog v-model="judgeVisible" v-if="judgeVisible && detail"></ScoringExpertsDialog>
<!-- 参赛选手 -->
<ContestantDialog v-model="contestantVisible" v-if="contestantVisible && detail"></ContestantDialog>
<!-- 评分细则 -->
<ScoringBookDialog v-model="judgingBookVisible" v-if="judgingBookVisible && detail"></ScoringBookDialog>
</template>
<style lang="scss">
......
......@@ -95,7 +95,7 @@ const adminMenus: IMenuItem[] = [
},
{
name: '评分专家管理',
path: '/admin/contest/judges'
path: '/admin/contest/experts'
}
]
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论