|
|
|
@ -47,7 +47,7 @@ |
|
|
|
|
v-show="per == 0">重新开始</el-button> |
|
|
|
|
<el-button type="primary" |
|
|
|
|
class="submit btn" |
|
|
|
|
@click="confirmSubmit" |
|
|
|
|
@click="submit" |
|
|
|
|
:disabled="isSubmit || !projectList.length">提交</el-button> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
@ -101,13 +101,21 @@ |
|
|
|
|
width="60" |
|
|
|
|
align="center"> |
|
|
|
|
<template v-slot="scope"> |
|
|
|
|
|
|
|
|
|
<template v-if="isSubmit"> |
|
|
|
|
<template v-if="!param.competitionId"> |
|
|
|
|
<i v-if="scope.row.finishedResult" |
|
|
|
|
class="el-icon-check right"></i> |
|
|
|
|
<i v-else |
|
|
|
|
class="el-icon-close wrong"></i> |
|
|
|
|
</template> |
|
|
|
|
<div v-if="!param.competitionId" |
|
|
|
|
class="flex items-center"> |
|
|
|
|
<el-icon v-if="scope.row.finishedResult" |
|
|
|
|
color="#15d500" |
|
|
|
|
:size="16"> |
|
|
|
|
<Check /> |
|
|
|
|
</el-icon> |
|
|
|
|
<el-icon v-else |
|
|
|
|
color="#f00" |
|
|
|
|
:size="16"> |
|
|
|
|
<Close /> |
|
|
|
|
</el-icon> |
|
|
|
|
</div> |
|
|
|
|
<template v-else>-</template> |
|
|
|
|
</template> |
|
|
|
|
</template> |
|
|
|
@ -201,14 +209,16 @@ |
|
|
|
|
</template> |
|
|
|
|
<script setup lang="ts"> |
|
|
|
|
import { ref, reactive, onMounted, toRefs } from 'vue'; |
|
|
|
|
import { submitOpe } from '@/api/bank'; |
|
|
|
|
import { deleteCache } from '@/api/judgment'; |
|
|
|
|
import { pageStuAssessment, getProjectBySystemId, getProjectDetail, getDetailById, getCompetition } from '@/api/system'; |
|
|
|
|
import { useRouter, useRoute } from 'vue-router'; |
|
|
|
|
import type { Action } from 'element-plus'; |
|
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'; |
|
|
|
|
|
|
|
|
|
import { Close, Check } from '@element-plus/icons-vue'; |
|
|
|
|
import dayjs from 'dayjs'; |
|
|
|
|
import Cookies from 'js-cookie'; |
|
|
|
|
import { mavonEditor } from 'mavon-editor'; |
|
|
|
|
import util from '@/libs/util'; |
|
|
|
|
import Setting from '@/setting'; |
|
|
|
|
import 'mavon-editor/dist/css/index.css'; |
|
|
|
|
|
|
|
|
|
const router = useRouter(); |
|
|
|
@ -253,6 +263,10 @@ if (param.token) { |
|
|
|
|
param.mallId && Cookies.set('sand-mallId', param.mallId); |
|
|
|
|
param.endTime && Cookies.set('sand-referrer', param.endTime); |
|
|
|
|
param.referrer && Cookies.set('sand-referrer', param.referrer); |
|
|
|
|
param.className && Cookies.set('sand-referrer', param.className); |
|
|
|
|
param.startTime && Cookies.set('sand-referrer', param.startTime); |
|
|
|
|
param.resultsDetails && Cookies.set('sand-referrer', param.resultsDetails); |
|
|
|
|
param.resultAnnouncementTime && Cookies.set('sand-referrer', param.resultAnnouncementTime); |
|
|
|
|
} else { |
|
|
|
|
param.systemId = Cookies.get('sand-systemId'); |
|
|
|
|
param.projectId = Cookies.get('sand-projectId'); |
|
|
|
@ -264,6 +278,10 @@ if (param.token) { |
|
|
|
|
param.teamId = Cookies.get('sand-teamId'); |
|
|
|
|
param.mallId = Cookies.get('sand-mallId'); |
|
|
|
|
param.endTime = Cookies.get('sand-endTime'); |
|
|
|
|
param.className = Cookies.get('sand-className'); |
|
|
|
|
param.startTime = Cookies.get('sand-startTime'); |
|
|
|
|
param.resultsDetails = Cookies.get('sand-resultsDetails'); |
|
|
|
|
param.resultAnnouncementTime = Cookies.get('sand-resultAnnouncementTime'); |
|
|
|
|
} |
|
|
|
|
if (param.projectId) param.projectId = +param.projectId; |
|
|
|
|
onMounted(() => { |
|
|
|
@ -281,58 +299,37 @@ onMounted(() => { |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// 获取项目列表 |
|
|
|
|
const getList = async () => { |
|
|
|
|
const data = { |
|
|
|
|
systemId: param.systemId, |
|
|
|
|
cId: param.cid ?? '', |
|
|
|
|
mallId: param.mallId, |
|
|
|
|
permissions: per.value, |
|
|
|
|
}; |
|
|
|
|
const { projects } = await getProjectBySystemId(data); |
|
|
|
|
projectList.value = projects; |
|
|
|
|
if (!per.value && !param.projectId) param.projectId = projects[0]?.projectId ?? 0; // 默认取第一个项目 |
|
|
|
|
getProDetail(); |
|
|
|
|
// 倒计时 |
|
|
|
|
const timeFormat = (num: number): string | number => { |
|
|
|
|
return num < 10 ? `0${num}` : num; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 获取项目详情 |
|
|
|
|
const getProDetail = async () => { |
|
|
|
|
const res = await getProjectDetail({ |
|
|
|
|
projectId: param.projectId, |
|
|
|
|
stuAssessent: 1, |
|
|
|
|
}); |
|
|
|
|
const points = res.projectJudgmentVos; |
|
|
|
|
const project = res.projectManage; |
|
|
|
|
// 考核/竞赛 |
|
|
|
|
if (per.value) { |
|
|
|
|
projectList.value = [ |
|
|
|
|
{ |
|
|
|
|
projectId: param.projectId, |
|
|
|
|
projectName: project.projectName, |
|
|
|
|
}, |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
curReq.value = points.map((e) => e.judgmentId); // 实验要求默认全部展开,通过judgmentId来选中item |
|
|
|
|
points.value = points; |
|
|
|
|
taskList.value = points; // 实验任务 |
|
|
|
|
judgmentId.value = points[0].judgmentId; // 默认取第一个判分点 |
|
|
|
|
pd.value = project; |
|
|
|
|
hintOpen.value = project.founder ? !project.hintOpenBySchool : !project.hintOpen; // 0显示,1不显示,系统跟老师的禁用字段不一样 |
|
|
|
|
const isPrac = per.value === 0; // 是否是练习 |
|
|
|
|
text.value = isPrac ? '已用' : '剩余'; |
|
|
|
|
// 竞赛不需要 |
|
|
|
|
if (!param.competitionId) { |
|
|
|
|
countVal.value = isPrac ? 0 : (new Date(param.endTime).getTime() - Date.now()) / 1000; // 如果是考核,取考核的结束时间减去当前时间去做倒计时,练习则直接给0做计时 |
|
|
|
|
startCount(); |
|
|
|
|
} |
|
|
|
|
// 清除时间 |
|
|
|
|
const reloadCount = () => { |
|
|
|
|
clearInterval(counterTimer.value); |
|
|
|
|
countVal.value = ''; |
|
|
|
|
day.value = '00'; |
|
|
|
|
seconds.value = '00'; |
|
|
|
|
minutes.value = '00'; |
|
|
|
|
hour.value = '00'; |
|
|
|
|
}; |
|
|
|
|
// 计时器(考核是倒计时,练习是计时) |
|
|
|
|
const counter = (counterTime: number) => { |
|
|
|
|
const leave1 = counterTime % (24 * 3600); // 计算天数后剩余的毫秒数 |
|
|
|
|
const leave2 = leave1 % 3600; // 计算小时数后剩余的毫秒数 |
|
|
|
|
const leave3 = leave2 % 60; // 计算分钟数后剩余的毫秒数 |
|
|
|
|
|
|
|
|
|
// 设置isSubmit |
|
|
|
|
// setSubmit(status) { |
|
|
|
|
// this.isSubmit = status; |
|
|
|
|
// newmain.$emit('isSubmit', status); |
|
|
|
|
// Cookies.set('admin-isSubmit', status); |
|
|
|
|
// }, |
|
|
|
|
day.value = timeFormat(Math.floor(counterTime / (24 * 3600))); |
|
|
|
|
hour.value = timeFormat(Math.floor(leave1 / 3600)); |
|
|
|
|
minutes.value = timeFormat(Math.floor(leave2 / 60)); |
|
|
|
|
seconds.value = timeFormat(Math.round(leave3)); |
|
|
|
|
}; |
|
|
|
|
// 启动倒计时 |
|
|
|
|
const startCount = () => { |
|
|
|
|
clearInterval(counterTimer.value); |
|
|
|
|
counterTimer.value = setInterval(() => { |
|
|
|
|
counter(per.value ? countVal.value-- : countVal.value++); |
|
|
|
|
}, 1000); |
|
|
|
|
}; |
|
|
|
|
// 获取考核列表来查询该考核是否已经考过 |
|
|
|
|
const getAssList = async () => { |
|
|
|
|
const { list } = await pageStuAssessment({ |
|
|
|
@ -402,131 +399,131 @@ const selectProject = () => { |
|
|
|
|
countVal.value = 0; |
|
|
|
|
grade.value = '00'; |
|
|
|
|
pannelTab.value = 'first'; |
|
|
|
|
clearReport(); |
|
|
|
|
}; |
|
|
|
|
// 重新开始 |
|
|
|
|
const reload = () => { |
|
|
|
|
const reload = async () => { |
|
|
|
|
await deleteCache(param.projectId, Cookies.get('sand-level') ?? ''); |
|
|
|
|
reloadCount(); |
|
|
|
|
grade.value = '00'; |
|
|
|
|
// this.setSubmit(false); |
|
|
|
|
startCount(); |
|
|
|
|
}; |
|
|
|
|
// 提交 |
|
|
|
|
const submit = () => { |
|
|
|
|
const submit = async () => { |
|
|
|
|
if (isSubmit.value) return false; |
|
|
|
|
ElMessageBox.confirm('此操作将视为结束考试,是否继续?', '提示', { |
|
|
|
|
confirmButtonText: '确定', |
|
|
|
|
cancelButtonText: '取消', |
|
|
|
|
type: 'warning', |
|
|
|
|
}) |
|
|
|
|
.then(() => {}) |
|
|
|
|
.catch(() => {}); |
|
|
|
|
.then(async () => { |
|
|
|
|
const date = new Date(); |
|
|
|
|
const timeSum = Math.ceil((date.getTime() - entryTime.value.getTime()) / 60000); // 计算实验用时(分钟),向上取整 |
|
|
|
|
const submitTime = dayjs(date).format('YYYY-MM-DD HH:mm:ss'); |
|
|
|
|
reloadCount(); |
|
|
|
|
const { retMap } = await submitOpe({ |
|
|
|
|
classId: param.classId ? param.classId : '', |
|
|
|
|
className: param.className ? param.className : '', |
|
|
|
|
curriculumId: param.cid, |
|
|
|
|
startTime: per.value ? param.startTime : dayjs(entryTime.value).format('YYYY-MM-DD HH:mm:ss'), // 开始时间(考核:直接从职站取考核的开始时间;练习:取页面进入的时间) |
|
|
|
|
endTime: per.value ? param.endTime : submitTime, // 结束时间(考核:直接从职站取考核的结束时间;练习:取提交时间) |
|
|
|
|
submitTime, // 提交时间,即当前时间(这3个时间都是传完整的日期时间格式) |
|
|
|
|
timeSum, |
|
|
|
|
checkpointId: Cookies.get('sand-level') ?? '', |
|
|
|
|
projectId: param.projectId, |
|
|
|
|
lcId: curReq.value, |
|
|
|
|
assessmentId: param.assessmentId, |
|
|
|
|
systemId: curSystemId.value, |
|
|
|
|
purpose: pd.value.experimentTarget, // 实验目的 |
|
|
|
|
competitionId: param.competitionId, |
|
|
|
|
stageId: param.stageId, |
|
|
|
|
teamId: param.teamId, |
|
|
|
|
mallId: param.mallId, |
|
|
|
|
}); |
|
|
|
|
isSubmit.value = true; |
|
|
|
|
clearInterval(statusTimer.value); |
|
|
|
|
|
|
|
|
|
// if (isSubmit.value) return false; |
|
|
|
|
// const date = new Date(); |
|
|
|
|
// const timeSum = Math.ceil((date.getTime() - entryTime.getTime()) / 60000); // 计算实验用时(分钟),向上取整 |
|
|
|
|
// const submitTime = util.formatDate('yyyy-MM-dd hh:mm:ss', date); |
|
|
|
|
// const { projectId } = this; |
|
|
|
|
// const pro = this.projectList.find((e) => e.projectId == projectId); |
|
|
|
|
// const projectName = pro ? pro.projectName : ''; // 获取项目名称 |
|
|
|
|
// this.reloadCount(); |
|
|
|
|
// // 判分点参数 |
|
|
|
|
// const attributesReqList = []; |
|
|
|
|
// pointList.map((e) => { |
|
|
|
|
// attributesReqList.push({ |
|
|
|
|
// codeId: e.codeId, |
|
|
|
|
// bcId: e.judgmentId, |
|
|
|
|
// isSubmit: e.codeId ? 1 : 0, |
|
|
|
|
// answer: e.answer, |
|
|
|
|
// retResult: e.retResult, |
|
|
|
|
// }); |
|
|
|
|
// }); |
|
|
|
|
// const data = { |
|
|
|
|
// classId: this.classId ? this.classId : '', |
|
|
|
|
// className: this.className ? this.className : '', |
|
|
|
|
// curriculumId: this.cid, |
|
|
|
|
// startTime: this.per ? this.startTime : util.formatDate('yyyy-MM-dd hh:mm:ss', entryTime), // 开始时间(考核:直接从职站取考核的开始时间;练习:取页面进入的时间) |
|
|
|
|
// endTime: this.per ? this.endTime : submitTime, // 结束时间(考核:直接从职站取考核的结束时间;练习:取提交时间) |
|
|
|
|
// submitTime, // 提交时间,即当前时间(这3个时间都是传完整的日期时间格式) |
|
|
|
|
// timeSum, |
|
|
|
|
// projectId, |
|
|
|
|
// projectName, |
|
|
|
|
// assessmentId: this.assessmentId ? this.assessmentId : '', |
|
|
|
|
// totalScore: 100, // 判分点总分固定为100 |
|
|
|
|
// systemId: this.curSystemId, |
|
|
|
|
// purpose: this.pd.experimentTarget, // 实验目的 |
|
|
|
|
// attributesReqList, |
|
|
|
|
// competitionId: this.competitionId, |
|
|
|
|
// stageId: this.stageId, |
|
|
|
|
// teamId: this.teamId, |
|
|
|
|
// mallId: this.mallId, |
|
|
|
|
// }; |
|
|
|
|
// this.$post(this.api.submit, data) |
|
|
|
|
// .then(({ retInfo, reportId }) => { |
|
|
|
|
// localStorage.removeItem('codeCache'); |
|
|
|
|
// this.setSubmit(true); |
|
|
|
|
// clearInterval(this.statusTimer); |
|
|
|
|
// this.reportVisible = false; |
|
|
|
|
// const list = retInfo; |
|
|
|
|
// const { taskList } = this; |
|
|
|
|
// let score = 0; |
|
|
|
|
// // 给判分列表添加分数和运行结果 |
|
|
|
|
// taskList.map((e) => { |
|
|
|
|
// const item = list.find((n) => n.judgmentPointsId === e.judgmentId); |
|
|
|
|
// if (item) { |
|
|
|
|
// e.examScore = item.score; |
|
|
|
|
// e.finishedResult = item.finishedResult; // 1:正确,2:错误 |
|
|
|
|
// } else { |
|
|
|
|
// e.examScore = 0; |
|
|
|
|
// } |
|
|
|
|
// score += e.examScore; // 计算总分 |
|
|
|
|
// }); |
|
|
|
|
// this.grade = util.handleZero(score); // 前置加0(竞赛不显示分数) |
|
|
|
|
// this.reportId = reportId; |
|
|
|
|
// this.$store.commit('setReportId', reportId); |
|
|
|
|
// this.$store.commit('setTaskList', taskList); |
|
|
|
|
// this.editReport(reportId); |
|
|
|
|
// // 如果是竞赛,并且勾选了公布成绩详情的选项,则弹框提示 |
|
|
|
|
// this.competitionId && |
|
|
|
|
// this.resultsDetails == 0 && |
|
|
|
|
// this.$alert(`提交成功${this.resultAnnouncementTime != 0 ? `,成绩将在${this.resultAnnouncementTime}小时后发布,请去参赛信息模块查看` : ''}`, '提示', { |
|
|
|
|
// confirmButtonText: '确定', |
|
|
|
|
// callback: (action) => { |
|
|
|
|
// this.$parent.back(); |
|
|
|
|
// }, |
|
|
|
|
// }); |
|
|
|
|
// }) |
|
|
|
|
// .catch((err) => {}); |
|
|
|
|
}; |
|
|
|
|
// 倒计时 |
|
|
|
|
const timeFormat = (num: number): string | number => { |
|
|
|
|
return num < 10 ? `0${num}` : num; |
|
|
|
|
}; |
|
|
|
|
// 清除时间 |
|
|
|
|
const reloadCount = () => { |
|
|
|
|
clearInterval(counterTimer.value); |
|
|
|
|
countVal.value = ''; |
|
|
|
|
day.value = '00'; |
|
|
|
|
seconds.value = '00'; |
|
|
|
|
minutes.value = '00'; |
|
|
|
|
hour.value = '00'; |
|
|
|
|
let score = 0; |
|
|
|
|
// 给判分列表添加分数和运行结果 |
|
|
|
|
taskList.value.map((e) => { |
|
|
|
|
const item = retMap?.scoreInfo.find((n) => n.lcId === e.judgmentId); |
|
|
|
|
if (item) { |
|
|
|
|
e.examScore = item.questionScore; |
|
|
|
|
e.finishedResult = item.calculate; // 1:正确,2:错误 |
|
|
|
|
score += item.questionScore; // 计算总分 |
|
|
|
|
} else { |
|
|
|
|
e.examScore = 0; |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
grade.value = score < 10 ? '0' + score : score; |
|
|
|
|
reportId.value = retMap.reportId; |
|
|
|
|
// this.$store.commit('setReportId', reportId); |
|
|
|
|
// this.$store.commit('setTaskList', taskList); |
|
|
|
|
|
|
|
|
|
// 如果是竞赛,并且勾选了公布成绩详情的选项,则弹框提示 |
|
|
|
|
// param.competitionId && |
|
|
|
|
// param.resultsDetails == 0 && |
|
|
|
|
|
|
|
|
|
// ElMessageBox.alert(`提交成功${param.resultAnnouncementTime != 0 ? `,成绩将在${param.resultAnnouncementTime}小时后发布,请去参赛信息模块查看`, '提示', { |
|
|
|
|
// // if you want to disable its autofocus |
|
|
|
|
// // autofocus: false, |
|
|
|
|
// confirmButtonText: '确定', |
|
|
|
|
// callback: (action: Action) => { |
|
|
|
|
// ElMessage({ |
|
|
|
|
// type: 'info', |
|
|
|
|
// message: `action: ${action}`, |
|
|
|
|
// }) |
|
|
|
|
// }, |
|
|
|
|
// }) |
|
|
|
|
}) |
|
|
|
|
.catch(() => {}); |
|
|
|
|
}; |
|
|
|
|
// 计时器(考核是倒计时,练习是计时) |
|
|
|
|
const counter = (counterTime: number) => { |
|
|
|
|
const leave1 = counterTime % (24 * 3600); // 计算天数后剩余的毫秒数 |
|
|
|
|
const leave2 = leave1 % 3600; // 计算小时数后剩余的毫秒数 |
|
|
|
|
const leave3 = leave2 % 60; // 计算分钟数后剩余的毫秒数 |
|
|
|
|
|
|
|
|
|
day.value = timeFormat(Math.floor(counterTime / (24 * 3600))); |
|
|
|
|
hour.value = timeFormat(Math.floor(leave1 / 3600)); |
|
|
|
|
minutes.value = timeFormat(Math.floor(leave2 / 60)); |
|
|
|
|
seconds.value = timeFormat(Math.round(leave3)); |
|
|
|
|
// 获取项目详情 |
|
|
|
|
const getProDetail = async () => { |
|
|
|
|
const res = await getProjectDetail({ |
|
|
|
|
projectId: param.projectId, |
|
|
|
|
stuAssessent: 1, |
|
|
|
|
}); |
|
|
|
|
const pointsList = res.projectJudgmentVos; |
|
|
|
|
const project = res.projectManage; |
|
|
|
|
// 考核/竞赛 |
|
|
|
|
if (per.value) { |
|
|
|
|
projectList.value = [ |
|
|
|
|
{ |
|
|
|
|
projectId: param.projectId, |
|
|
|
|
projectName: project.projectName, |
|
|
|
|
}, |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
curReq.value = pointsList.map((e) => e.judgmentId); // 实验要求默认全部展开,通过judgmentId来选中item |
|
|
|
|
points.value = pointsList; |
|
|
|
|
taskList.value = pointsList; // 实验任务 |
|
|
|
|
judgmentId.value = pointsList[0].judgmentId; // 默认取第一个判分点 |
|
|
|
|
pd.value = project; |
|
|
|
|
curSystemId.value = project.systemId; |
|
|
|
|
hintOpen.value = project.founder ? !project.hintOpenBySchool : !project.hintOpen; // 0显示,1不显示,系统跟老师的禁用字段不一样 |
|
|
|
|
const isPrac = per.value === 0; // 是否是练习 |
|
|
|
|
text.value = isPrac ? '已用' : '剩余'; |
|
|
|
|
// 竞赛不需要 |
|
|
|
|
if (!param.competitionId) { |
|
|
|
|
countVal.value = isPrac ? 0 : (new Date(param.endTime).getTime() - Date.now()) / 1000; // 如果是考核,取考核的结束时间减去当前时间去做倒计时,练习则直接给0做计时 |
|
|
|
|
startCount(); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
// 启动倒计时 |
|
|
|
|
const startCount = () => { |
|
|
|
|
clearInterval(counterTimer.value); |
|
|
|
|
counterTimer.value = setInterval(() => { |
|
|
|
|
counter(per.value ? countVal.value-- : countVal.value++); |
|
|
|
|
}, 1000); |
|
|
|
|
|
|
|
|
|
// 获取项目列表 |
|
|
|
|
const getList = async () => { |
|
|
|
|
const data = { |
|
|
|
|
systemId: param.systemId, |
|
|
|
|
cId: param.cid ?? '', |
|
|
|
|
mallId: param.mallId, |
|
|
|
|
permissions: per.value, |
|
|
|
|
}; |
|
|
|
|
const { projects } = await getProjectBySystemId(data); |
|
|
|
|
projectList.value = projects; |
|
|
|
|
if (!per.value && !param.projectId) param.projectId = projects[0]?.projectId ?? 0; // 默认取第一个项目 |
|
|
|
|
getProDetail(); |
|
|
|
|
}; |
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|