提交 99732778 authored 作者: lhh's avatar lhh

开发评分需求

上级 0cda2ee6
...@@ -51,3 +51,8 @@ export function importScore(data: { competition_id: string; file: File }) { ...@@ -51,3 +51,8 @@ export function importScore(data: { competition_id: string; file: File }) {
export function getReportList(params: { competition_id: string; student_id: string }) { export function getReportList(params: { competition_id: string; student_id: string }) {
return httpRequest.get('/api/lab/v1/expert/report/list', { params }) return httpRequest.get('/api/lab/v1/expert/report/list', { params })
} }
// 获取学员的直播记录
export function getLiveList(params: { experiment_id: string; student_id: string }) {
return httpRequest.get('/api/lab/v1/expert/check/stu-live-practice-records', { params })
}
...@@ -53,14 +53,27 @@ function handleSubmit() { ...@@ -53,14 +53,27 @@ function handleSubmit() {
}) })
} }
const qaURL = import.meta.env.VITE_QA_CENTER_URL const qaURL = import.meta.env.VITE_QA_CENTER_URL
// 查看评分规则
const handleScoreRule = function () {
if (detail?.competition_rubric && detail?.competition_rubric?.url) {
window.open(detail?.competition_rubric?.url)
}
}
</script> </script>
<template> <template>
<el-dialog title="评分" :close-on-click-modal="false" width="700px" @update:modelValue="value => $emit('update:modelValue', value)"> <el-dialog
title="评分"
:close-on-click-modal="false"
width="700px"
@update:modelValue="value => $emit('update:modelValue', value)"
>
<el-form label-suffix=":" v-if="detail"> <el-form label-suffix=":" v-if="detail">
<el-form-item label="赛项名称">{{ detail.competition_id_name }}</el-form-item> <el-form-item label="赛项名称">{{ detail.competition_id_name }}</el-form-item>
<el-form-item label="选手姓名">{{ detail.student_name }}</el-form-item> <el-form-item label="选手姓名">{{ detail.student_name }}</el-form-item>
<el-form-item label="选手ID">{{ detail.login_id }}</el-form-item> <el-form-item label="选手ID">{{ detail.login_id }}</el-form-item>
<div style="display: flex; justify-content: space-between">
<el-form-item label="报告"> <el-form-item label="报告">
<el-dropdown> <el-dropdown>
<el-button text> <el-button text>
...@@ -75,6 +88,8 @@ const qaURL = import.meta.env.VITE_QA_CENTER_URL ...@@ -75,6 +88,8 @@ const qaURL = import.meta.env.VITE_QA_CENTER_URL
</template> </template>
</el-dropdown> </el-dropdown>
</el-form-item> </el-form-item>
<el-button type="primary" @click="handleScoreRule">查看评分规则</el-button>
</div>
</el-form> </el-form>
<el-table :data="tableList" :header-cell-style="{ background: '#ededed' }"> <el-table :data="tableList" :header-cell-style="{ background: '#ededed' }">
<el-table-column label="评分规则" prop="name" align="center"></el-table-column> <el-table-column label="评分规则" prop="name" align="center"></el-table-column>
...@@ -83,13 +98,23 @@ const qaURL = import.meta.env.VITE_QA_CENTER_URL ...@@ -83,13 +98,23 @@ const qaURL = import.meta.env.VITE_QA_CENTER_URL
<el-table-column label="占比(%)" prop="ratio" align="center"></el-table-column> <el-table-column label="占比(%)" prop="ratio" align="center"></el-table-column>
<el-table-column label="评分" prop="score" align="center"> <el-table-column label="评分" prop="score" align="center">
<template #default="{ row }"> <template #default="{ row }">
<el-input-number :controls="false" v-model="row.score" step-strictly :step="0.1" :min="0" :max="row.old_score" style="width: 100%" /> <el-input-number
:controls="false"
v-model="row.score"
step-strictly
:step="0.1"
:min="0"
:max="row.old_score"
style="width: 100%"
/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center"> <el-table-column label="操作" align="center">
<template #default="{ row }"> <template #default="{ row }">
<el-button text type="primary" v-if="row.type === '2'"> <el-button text type="primary" v-if="row.type === '2'">
<a :href="`${qaURL}/exam/markingPaper?exam_id=${row.exam_id}&id_number=${detail.id_number}`" target="_blank">查看</a> <a :href="`${qaURL}/exam/markingPaper?exam_id=${row.exam_id}&id_number=${detail.id_number}`" target="_blank"
>查看</a
>
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
......
<script setup lang="ts">
import { getLiveList } from '../api'
const props = defineProps<{ data: any }>()
defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
// 列表配置
const listOptions = $computed(() => {
return {
remote: {
httpRequest: getLiveList,
params: {
experiment_id: props.data.eid,
student_id: props.data.sid
}
},
columns: [
{ label: '序号', type: 'index', width: 60 },
{ label: '选手姓名', prop: 'student_name' },
{ label: '商品名称', prop: 'live_commodity' },
{ label: '直播时长', prop: 'live_duration' },
{ label: '文件大小(M)', prop: 'live_video_size' },
{ label: '上传时间', prop: 'live_end_time' },
{ label: '操作', slots: 'table-x', width: 130 }
]
}
})
const handleViewLive = function () {
window.open(
`https://saas-dml-pro.ezijing.com/one/live/test/view?experiment_id=${props.data.eid}&id=直播练习ID&record_id=直播记录ID&student_id=${props.data.sid}`
)
}
</script>
<template>
<el-dialog
title="查看直播录像"
:close-on-click-modal="false"
width="700px"
@update:modelValue="value => $emit('update:modelValue', value)"
>
<AppList v-bind="listOptions" ref="appList">
<template #table-count="{ row }"> {{ row.checked_count }}/{{ row.need_check_count }} </template>
<template #table-score="{ row }">
<span :class="{ 'is-info': row.score_name !== '--' }">{{ row.score_name }}</span>
</template>
<template #table-x="{ row }">
<el-button
text
type="primary"
@click="handleViewLive"
v-if="row.experiment_id !== '0' && row.experiment_id"
>观看回放</el-button
>
</template>
</AppList>
<el-row justify="center">
<el-button round auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button>
</el-row>
</el-dialog>
</template>
<style lang="scss" scoped>
.result {
padding: 40px 0;
display: flex;
align-items: center;
justify-content: center;
span {
padding: 0 10px;
font-size: 40px;
color: var(--main-color);
}
}
</style>
<script setup lang="ts"> <script setup lang="ts">
import type { ReportItem } from '../types'
import { Refresh, Upload } from '@element-plus/icons-vue' import { Refresh, Upload } from '@element-plus/icons-vue'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import { getCheckList } from '../api' import { getCheckList, getReportList, getCheckView } from '../api'
import { useFilterList } from '../composables/useFilterList' import { useFilterList } from '../composables/useFilterList'
const SyncExamDialog = defineAsyncComponent(() => import('../components/SyncExamDialog.vue')) const SyncExamDialog = defineAsyncComponent(() => import('../components/SyncExamDialog.vue'))
...@@ -9,6 +10,8 @@ const ImportExamDialog = defineAsyncComponent(() => import('../components/Import ...@@ -9,6 +10,8 @@ const ImportExamDialog = defineAsyncComponent(() => import('../components/Import
const ImportScoreDialog = defineAsyncComponent(() => import('../components/ImportScoreDialog.vue')) const ImportScoreDialog = defineAsyncComponent(() => import('../components/ImportScoreDialog.vue'))
const ScoreViewPicturesDialog = defineAsyncComponent(() => import('../components/ScoreViewPicturesDialog.vue')) const ScoreViewPicturesDialog = defineAsyncComponent(() => import('../components/ScoreViewPicturesDialog.vue'))
const ReportDialog = defineAsyncComponent(() => import('../components/ReportDialog.vue')) const ReportDialog = defineAsyncComponent(() => import('../components/ReportDialog.vue'))
const ScoreDialog = defineAsyncComponent(() => import('../components/ScoreDialog.vue'))
const ViewLiveDialog = defineAsyncComponent(() => import('../components/ViewLiveDialog.vue'))
const route = useRoute() const route = useRoute()
...@@ -117,7 +120,7 @@ const listOptions = $computed(() => { ...@@ -117,7 +120,7 @@ const listOptions = $computed(() => {
// return getModuleStatus(row, 5) // return getModuleStatus(row, 5)
// } // }
// }, // },
{ label: '操作', slots: 'table-x', width: 100 } { label: '操作', slots: 'table-x', width: 130 }
] ]
} }
}) })
...@@ -158,6 +161,35 @@ function handleViewReport(row: any) { ...@@ -158,6 +161,35 @@ function handleViewReport(row: any) {
// } // }
// return '未开始' // return '未开始'
// } // }
// 评分
let dialogVisible = $ref(false)
const reportList = ref<ReportItem[]>([])
// 左侧
let detail = $ref<any>()
provide('detail', $$(detail))
const handleScore = function (row: any) {
getCheckView({ id: row.id }).then((res: any) => {
detail = res.data
getReportList({ competition_id: res.data.competition_id, student_id: res.data.student_id }).then((r: any) => {
reportList.value = r.data.items
dialogVisible = true
})
})
}
// 直播录像
let liveDialogVisible = $ref(false)
let liveParams: any = $ref()
const handleViewLive = function (row: any) {
liveParams = {
sid: row.student_id,
eid: row.experiment_id
}
liveDialogVisible = true
}
</script> </script>
<template> <template>
...@@ -194,12 +226,32 @@ function handleViewReport(row: any) { ...@@ -194,12 +226,32 @@ function handleViewReport(row: any) {
<span :class="{ 'is-info': row.score_name !== '--' }">{{ row.score_name }}</span> <span :class="{ 'is-info': row.score_name !== '--' }">{{ row.score_name }}</span>
</template> </template>
<template #table-x="{ row }"> <template #table-x="{ row }">
<el-button text type="primary" v-if="row.publish_status === '0'" v-permission="'v1-expert-check-set-score'"> <!-- 评分从详情里移出 -->
<!-- <el-button text type="primary" v-if="row.publish_status === '0'" v-permission="'v1-expert-check-set-score'">
<router-link :to="`/admin/contest/check/${row.id}`" target="_blank">评分</router-link> <router-link :to="`/admin/contest/check/${row.id}`" target="_blank">评分</router-link>
</el-button> </el-button> -->
<el-button text type="primary" @click="handleScore(row)" v-permission="'v1-expert-check-set-score'"
>评分</el-button
>
<br /> <br />
<el-button text type="primary" @click="handleViewReport(row)">查看报告</el-button><br /> <el-button text type="primary" @click="handleViewReport(row)" v-if="row.competition_report_count !== '0'"
<el-button text type="primary" @click="handleViewPicture(row)">查看截图</el-button> >查看报告</el-button
><br />
<el-button
text
type="primary"
@click="handleViewPicture(row)"
v-if="row.competition_competitor_pictures && row.competition_competitor_pictures?.pictures"
>查看截图</el-button
>
<br />
<el-button
text
type="primary"
@click="handleViewLive(row)"
v-if="row.experiment_id !== '0' && row.experiment_id"
>查看直播录像</el-button
>
</template> </template>
</AppList> </AppList>
</AppCard> </AppCard>
...@@ -211,11 +263,16 @@ function handleViewReport(row: any) { ...@@ -211,11 +263,16 @@ function handleViewReport(row: any) {
<ImportScoreDialog <ImportScoreDialog
v-model="importScoreVisible" v-model="importScoreVisible"
@update="onUpdateSuccess" @update="onUpdateSuccess"
v-if="importScoreVisible"></ImportScoreDialog> v-if="importScoreVisible"
></ImportScoreDialog>
<!-- 查看截图 --> <!-- 查看截图 -->
<ScoreViewPicturesDialog v-model="viewPictureVisible" :data="rowData" v-if="rowData"></ScoreViewPicturesDialog> <ScoreViewPicturesDialog v-model="viewPictureVisible" :data="rowData" v-if="rowData"></ScoreViewPicturesDialog>
<!-- 查看报告 --> <!-- 查看报告 -->
<ReportDialog v-model="viewReportVisible" :data="rowData" v-if="rowData && viewReportVisible"></ReportDialog> <ReportDialog v-model="viewReportVisible" :data="rowData" v-if="rowData && viewReportVisible"></ReportDialog>
<!-- 评分弹窗 -->
<ScoreDialog v-model="dialogVisible" :reportList="reportList"></ScoreDialog>
<!-- 查看直播视频录像 -->
<ViewLiveDialog v-model="liveDialogVisible" v-if="liveDialogVisible" :data="liveParams"></ViewLiveDialog>
</template> </template>
<style lang="scss"> <style lang="scss">
......
...@@ -256,7 +256,10 @@ function handleSubmit() { ...@@ -256,7 +256,10 @@ function handleSubmit() {
const findExam = examList.find(item => item.exam_id === form.competition_platform_configs[0].exam_id) const findExam = examList.find(item => item.exam_id === form.competition_platform_configs[0].exam_id)
const examStartTime = new Date(findExam?.start_time || '').getTime() const examStartTime = new Date(findExam?.start_time || '').getTime()
const examEndTime = new Date(findExam?.end_time || '').getTime() const examEndTime = new Date(findExam?.end_time || '').getTime()
console.log(containsNumber(examStartTime, mergedForm.start_at), containsNumber(examEndTime, mergedForm.end_at)) // console.log(containsNumber(examStartTime, mergedForm.start_at), containsNumber(examEndTime, mergedForm.end_at))
const findXItem = form.competition_platform_configs.find(item => item.type === '1')
console.log(findXItem, 'findXItem', form.competition_platform_configs)
if (findXItem?.is_show === '1') {
if ( if (
containsNumber(examStartTime, mergedForm.start_at) !== true || containsNumber(examStartTime, mergedForm.start_at) !== true ||
containsNumber(examEndTime, mergedForm.end_at) !== true containsNumber(examEndTime, mergedForm.end_at) !== true
...@@ -264,6 +267,7 @@ function handleSubmit() { ...@@ -264,6 +267,7 @@ function handleSubmit() {
ElMessage({ message: `正式比赛理论答题时间与${findExam?.name}的考试时间不符`, type: 'warning' }) ElMessage({ message: `正式比赛理论答题时间与${findExam?.name}的考试时间不符`, type: 'warning' })
return false return false
} }
}
const params: ContestUpdateParams = pick(mergedForm, [ const params: ContestUpdateParams = pick(mergedForm, [
'operational_start_time', 'operational_start_time',
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论