|
|
@ -225,7 +225,7 @@ |
|
|
|
import { ref, reactive, onMounted, inject, computed, watch } from 'vue'; |
|
|
|
import { ref, reactive, onMounted, inject, computed, watch } from 'vue'; |
|
|
|
import { submitOpe } from '@/api/bank'; |
|
|
|
import { submitOpe } from '@/api/bank'; |
|
|
|
import { deleteCache } from '@/api/judgment'; |
|
|
|
import { deleteCache } from '@/api/judgment'; |
|
|
|
import { pageStuAssessment, getProjectBySystemId, getProjectDetail, getDetailById, getCompetition } from '@/api/system'; |
|
|
|
import { pageStuAssessment, getProjectBySystemId, getProjectDetail, getDetailById, getCompetition, getStartTime, getCurrentTime } from '@/api/system'; |
|
|
|
import Settings from '@/settings'; |
|
|
|
import Settings from '@/settings'; |
|
|
|
import { useRouter, useRoute } from 'vue-router'; |
|
|
|
import { useRouter, useRoute } from 'vue-router'; |
|
|
|
import type { Action } from 'element-plus'; |
|
|
|
import type { Action } from 'element-plus'; |
|
|
@ -237,6 +237,7 @@ import { mavonEditor } from 'mavon-editor'; |
|
|
|
import 'mavon-editor/dist/css/index.css'; |
|
|
|
import 'mavon-editor/dist/css/index.css'; |
|
|
|
import '@vueup/vue-quill/dist/vue-quill.snow.css'; |
|
|
|
import '@vueup/vue-quill/dist/vue-quill.snow.css'; |
|
|
|
import { useDraggable } from '@vueuse/core'; |
|
|
|
import { useDraggable } from '@vueuse/core'; |
|
|
|
|
|
|
|
import { logout } from '@/store/useCurrentUser'; |
|
|
|
|
|
|
|
|
|
|
|
const router = useRouter(); |
|
|
|
const router = useRouter(); |
|
|
|
const route = useRoute(); |
|
|
|
const route = useRoute(); |
|
|
@ -263,7 +264,6 @@ const judgmentId = ref<string | number>(''); |
|
|
|
const curReq = ref<Record<string, any>[]>([]); |
|
|
|
const curReq = ref<Record<string, any>[]>([]); |
|
|
|
const taskList = ref<Record<string, any>[]>([]); |
|
|
|
const taskList = ref<Record<string, any>[]>([]); |
|
|
|
const pannelTab = ref<string>('first'); |
|
|
|
const pannelTab = ref<string>('first'); |
|
|
|
const statusTimer = ref<any>(null); |
|
|
|
|
|
|
|
const submiting = ref<boolean>(false); |
|
|
|
const submiting = ref<boolean>(false); |
|
|
|
const reportId = ref<string | number>(''); |
|
|
|
const reportId = ref<string | number>(''); |
|
|
|
const countVal = ref<any>(''); |
|
|
|
const countVal = ref<any>(''); |
|
|
@ -293,12 +293,13 @@ if (param.token) { |
|
|
|
Cookies.set('sand-stageId', param.stageId ?? ''); |
|
|
|
Cookies.set('sand-stageId', param.stageId ?? ''); |
|
|
|
Cookies.set('sand-teamId', param.teamId ?? ''); |
|
|
|
Cookies.set('sand-teamId', param.teamId ?? ''); |
|
|
|
Cookies.set('sand-mallId', param.mallId ?? ''); |
|
|
|
Cookies.set('sand-mallId', param.mallId ?? ''); |
|
|
|
Cookies.set('sand-endTime', param.endTime ?? ''); |
|
|
|
|
|
|
|
Cookies.set('sand-referrer', param.referrer ?? ''); |
|
|
|
Cookies.set('sand-referrer', param.referrer ?? ''); |
|
|
|
Cookies.set('sand-className', param.className ?? ''); |
|
|
|
Cookies.set('sand-className', param.className ?? ''); |
|
|
|
Cookies.set('sand-startTime', param.startTime ?? ''); |
|
|
|
Cookies.set('sand-startTime', param.startTime ?? ''); |
|
|
|
Cookies.set('sand-resultsDetails', param.resultsDetails ?? ''); |
|
|
|
Cookies.set('sand-resultsDetails', param.resultsDetails ?? ''); |
|
|
|
Cookies.set('sand-resultAnnouncementTime', param.resultAnnouncementTime ?? ''); |
|
|
|
Cookies.set('sand-resultAnnouncementTime', param.resultAnnouncementTime ?? ''); |
|
|
|
|
|
|
|
Cookies.set('sand-curriculumName', param.curriculumName ?? ''); |
|
|
|
|
|
|
|
Cookies.set('sand-stopTime', param.stopTime ?? ''); |
|
|
|
Cookies.set('sand-admin', param.admin ?? ''); // 从中台进来的标识 |
|
|
|
Cookies.set('sand-admin', param.admin ?? ''); // 从中台进来的标识 |
|
|
|
Cookies.remove('sand-submit'); |
|
|
|
Cookies.remove('sand-submit'); |
|
|
|
router.replace(route.path); |
|
|
|
router.replace(route.path); |
|
|
@ -312,11 +313,12 @@ if (param.token) { |
|
|
|
param.stageId = Cookies.get('sand-stageId'); |
|
|
|
param.stageId = Cookies.get('sand-stageId'); |
|
|
|
param.teamId = Cookies.get('sand-teamId'); |
|
|
|
param.teamId = Cookies.get('sand-teamId'); |
|
|
|
param.mallId = Cookies.get('sand-mallId'); |
|
|
|
param.mallId = Cookies.get('sand-mallId'); |
|
|
|
param.endTime = Cookies.get('sand-endTime'); |
|
|
|
|
|
|
|
param.className = Cookies.get('sand-className'); |
|
|
|
param.className = Cookies.get('sand-className'); |
|
|
|
param.startTime = Cookies.get('sand-startTime'); |
|
|
|
param.startTime = Cookies.get('sand-startTime'); |
|
|
|
param.resultsDetails = Cookies.get('sand-resultsDetails'); |
|
|
|
param.resultsDetails = Cookies.get('sand-resultsDetails'); |
|
|
|
param.resultAnnouncementTime = Cookies.get('sand-resultAnnouncementTime'); |
|
|
|
param.resultAnnouncementTime = Cookies.get('sand-resultAnnouncementTime'); |
|
|
|
|
|
|
|
param.curriculumName = Cookies.get('sand-curriculumName'); |
|
|
|
|
|
|
|
param.stopTime = Cookies.get('sand-stopTime'); |
|
|
|
isSubmit.value = Cookies.get('sand-submit') === 'true'; |
|
|
|
isSubmit.value = Cookies.get('sand-submit') === 'true'; |
|
|
|
} |
|
|
|
} |
|
|
|
if (param.projectId) param.projectId = +param.projectId; |
|
|
|
if (param.projectId) param.projectId = +param.projectId; |
|
|
@ -332,6 +334,23 @@ watch( |
|
|
|
}, |
|
|
|
}, |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取上次实验的时间 |
|
|
|
|
|
|
|
const getSumTime = () => { |
|
|
|
|
|
|
|
return new Promise(async (resolve, reject) => { |
|
|
|
|
|
|
|
const res = await getStartTime({ |
|
|
|
|
|
|
|
permissions: per.value, |
|
|
|
|
|
|
|
projectId: param.projectId, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
resolve(res.startTime ? new Date(res.startTime) : ''); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
// 获取当前时间 |
|
|
|
|
|
|
|
const getNow = () => { |
|
|
|
|
|
|
|
return new Promise(async (resolve, reject) => { |
|
|
|
|
|
|
|
const res = await getCurrentTime(); |
|
|
|
|
|
|
|
resolve(new Date(res.currentTime)); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}; |
|
|
|
// 倒计时 |
|
|
|
// 倒计时 |
|
|
|
const timeFormat = (num: number): string | number => { |
|
|
|
const timeFormat = (num: number): string | number => { |
|
|
|
return num < 10 ? `0${num}` : num; |
|
|
|
return num < 10 ? `0${num}` : num; |
|
|
@ -370,23 +389,22 @@ const setSubmit = (val: boolean) => { |
|
|
|
}; |
|
|
|
}; |
|
|
|
// 获取考核列表来查询该考核是否已经考过 |
|
|
|
// 获取考核列表来查询该考核是否已经考过 |
|
|
|
const getAssList = async () => { |
|
|
|
const getAssList = async () => { |
|
|
|
const { list } = await pageStuAssessment({ |
|
|
|
// const { list } = await pageStuAssessment({ |
|
|
|
pageNum: 1, |
|
|
|
// pageNum: 1, |
|
|
|
pageSize: 10000, |
|
|
|
// pageSize: 10000, |
|
|
|
}); |
|
|
|
// }); |
|
|
|
let done = false; |
|
|
|
// let done = false; |
|
|
|
// 匹配到该考核,并且已经提交过(有reportId则说明有实验记录),并且classId跟当前用户的classId相同,就提示提交了考核然后返回上一页 |
|
|
|
// // 匹配到该考核,并且已经提交过(有reportId则说明有实验记录),并且classId跟当前用户的classId相同,就提示提交了考核然后返回上一页 |
|
|
|
if (list.find((e) => e.assessmentId == param.assessmentId && e.reportId && e.classId == param.classId)) { |
|
|
|
// if (list.find((e) => e.assessmentId == param.assessmentId && e.reportId && e.classId == param.classId)) { |
|
|
|
done = true; |
|
|
|
// done = true; |
|
|
|
setSubmit(true); |
|
|
|
// setSubmit(true); |
|
|
|
ElMessage.error('你已经提交过该考核!'); |
|
|
|
// ElMessage.error('你已经提交过该考核!'); |
|
|
|
setTimeout((_) => { |
|
|
|
// setTimeout((_) => { |
|
|
|
window.history.back(); // 直接返回上一页面 |
|
|
|
// window.history.back(); // 直接返回上一页面 |
|
|
|
}, 1500); |
|
|
|
// }, 1500); |
|
|
|
} |
|
|
|
// } |
|
|
|
statusTimer.value = setInterval((_) => { |
|
|
|
getProDetail(); |
|
|
|
getAssStatus(); |
|
|
|
getAssStatus(); |
|
|
|
}, 1000); |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
// 定时查询考核状态(查到考核如果结束后,直接提交考核) |
|
|
|
// 定时查询考核状态(查到考核如果结束后,直接提交考核) |
|
|
|
const getAssStatus = async () => { |
|
|
|
const getAssStatus = async () => { |
|
|
@ -396,7 +414,6 @@ const getAssStatus = async () => { |
|
|
|
const done = data ? data.status === 2 : false; // 状态(0、待开始 1、进行中 2、已结束) |
|
|
|
const done = data ? data.status === 2 : false; // 状态(0、待开始 1、进行中 2、已结束) |
|
|
|
// 如果考核已结束,则清除查询考核状态的定时器,并且自动提交 |
|
|
|
// 如果考核已结束,则清除查询考核状态的定时器,并且自动提交 |
|
|
|
if (done) { |
|
|
|
if (done) { |
|
|
|
clearInterval(statusTimer.value); |
|
|
|
|
|
|
|
// this.$alert('考核时间已到,系统已自动交卷', '提示', { |
|
|
|
// this.$alert('考核时间已到,系统已自动交卷', '提示', { |
|
|
|
// confirmButtonText: '确定', |
|
|
|
// confirmButtonText: '确定', |
|
|
|
// }); |
|
|
|
// }); |
|
|
@ -413,18 +430,18 @@ const getCompetitionStatus = async () => { |
|
|
|
const stages = competition.competitionStage; |
|
|
|
const stages = competition.competitionStage; |
|
|
|
if (stages) { |
|
|
|
if (stages) { |
|
|
|
const stage = stages.find((e) => e.stageId == param.stageId); |
|
|
|
const stage = stages.find((e) => e.stageId == param.stageId); |
|
|
|
const endTime = new Date(stage.endTime).getTime(); |
|
|
|
const endTime = new Date(stage.endTime); |
|
|
|
const now = Date.now(); |
|
|
|
const now = await getNow(); |
|
|
|
// 如果已经结束 |
|
|
|
// 如果已经结束 |
|
|
|
if (now >= new Date(stage.endTime)) { |
|
|
|
if (now >= endTime) { |
|
|
|
clearInterval(statusTimer.value); |
|
|
|
|
|
|
|
// this.$alert('竞赛时间已到,系统已自动交卷', '提示', { |
|
|
|
// this.$alert('竞赛时间已到,系统已自动交卷', '提示', { |
|
|
|
// confirmButtonText: '确定', |
|
|
|
// confirmButtonText: '确定', |
|
|
|
// }); |
|
|
|
// }); |
|
|
|
submit(); |
|
|
|
submit(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// 没结束,则显示倒计时(竞赛才需要通过定时调接口来显示倒计时,因为中台可以修改结束时间,所以需要时刻获取最新的结束时间) |
|
|
|
// 没结束,则显示倒计时 |
|
|
|
counter((endTime - now) / 1000); |
|
|
|
countVal.value = (endTime - now) / 1000; |
|
|
|
|
|
|
|
startCount(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -476,8 +493,8 @@ const submit = async () => { |
|
|
|
classId: param.classId ? param.classId : '', |
|
|
|
classId: param.classId ? param.classId : '', |
|
|
|
className: param.className ? param.className : '', |
|
|
|
className: param.className ? param.className : '', |
|
|
|
curriculumId: param.cid, |
|
|
|
curriculumId: param.cid, |
|
|
|
startTime: per.value ? param.startTime : dayjs(entryTime.value).format('YYYY-MM-DD HH:mm:ss'), // 开始时间(考核:直接从职站取考核的开始时间;练习:取页面进入的时间) |
|
|
|
startTime: dayjs(entryTime.value).format('YYYY-MM-DD HH:mm:ss'), // 取页面进入的时间 |
|
|
|
endTime: per.value ? param.endTime : submitTime, // 结束时间(考核:直接从职站取考核的结束时间;练习:取提交时间) |
|
|
|
endTime: per.value ? param.stopTime : submitTime, // 结束时间(考核:直接从职站取考核的结束时间;练习:取提交时间) |
|
|
|
submitTime, // 提交时间,即当前时间(这3个时间都是传完整的日期时间格式) |
|
|
|
submitTime, // 提交时间,即当前时间(这3个时间都是传完整的日期时间格式) |
|
|
|
timeSum, |
|
|
|
timeSum, |
|
|
|
checkpointId: Cookies.get('sand-level') ?? '', |
|
|
|
checkpointId: Cookies.get('sand-level') ?? '', |
|
|
@ -493,13 +510,11 @@ const submit = async () => { |
|
|
|
mallId: param.mallId, |
|
|
|
mallId: param.mallId, |
|
|
|
}); |
|
|
|
}); |
|
|
|
setSubmit(true); |
|
|
|
setSubmit(true); |
|
|
|
clearInterval(statusTimer.value); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let score = 0; |
|
|
|
let score = 0; |
|
|
|
// 给判分列表添加分数和运行结果 |
|
|
|
// 给判分列表添加分数和运行结果 |
|
|
|
taskList.value.map((e) => { |
|
|
|
taskList.value.map((e) => { |
|
|
|
const item = retMap?.scoreInfo.find((n) => n.lcId === e.judgmentId); |
|
|
|
const item = retMap?.scoreInfo.find((n) => n.lcId === e.judgmentId); |
|
|
|
console.log('🚀 ~ taskList.value.map ~ item:', item); |
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
if (item) { |
|
|
|
if (item) { |
|
|
|
e.examScore = item.questionScore; |
|
|
|
e.examScore = item.questionScore; |
|
|
@ -516,16 +531,12 @@ const submit = async () => { |
|
|
|
localStorage.setItem('sand-taskList', JSON.stringify(taskList.value)); |
|
|
|
localStorage.setItem('sand-taskList', JSON.stringify(taskList.value)); |
|
|
|
submiting.value = false; |
|
|
|
submiting.value = false; |
|
|
|
|
|
|
|
|
|
|
|
// 如果是竞赛,并且勾选了公布成绩详情的选项,则弹框提示 |
|
|
|
// 非练习 |
|
|
|
param.competitionId && |
|
|
|
per.value && |
|
|
|
param.resultsDetails == 0 && |
|
|
|
ElMessageBox.alert(`提交成功${param.resultsDetails == 0 && param.resultAnnouncementTime != 0 ? ',成绩将在' + param.resultAnnouncementTime + '小时后发布,请去参赛信息模块查看' : ''}`, '提示', { |
|
|
|
ElMessageBox.alert(`提交成功${param.resultAnnouncementTime != 0 ? ',成绩将在' + param.resultAnnouncementTime + '小时后发布,请去参赛信息模块查看' : ''}`, '提示', { |
|
|
|
|
|
|
|
confirmButtonText: '确定', |
|
|
|
confirmButtonText: '确定', |
|
|
|
callback: (action: Action) => { |
|
|
|
callback: (action: Action) => { |
|
|
|
ElMessage({ |
|
|
|
logout(); |
|
|
|
type: 'info', |
|
|
|
|
|
|
|
message: `action: ${action}`, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
}); |
|
|
|
}); |
|
|
|
}) |
|
|
|
}) |
|
|
@ -563,7 +574,8 @@ const getProDetail = async () => { |
|
|
|
text.value = isPrac ? '已用' : '剩余'; |
|
|
|
text.value = isPrac ? '已用' : '剩余'; |
|
|
|
// 竞赛不需要 |
|
|
|
// 竞赛不需要 |
|
|
|
if (!param.competitionId && !isSubmit.value) { |
|
|
|
if (!param.competitionId && !isSubmit.value) { |
|
|
|
countVal.value = isPrac ? 0 : (new Date(param.endTime).getTime() - Date.now()) / 1000; // 如果是考核,取考核的结束时间减去当前时间去做倒计时,练习则直接给0做计时 |
|
|
|
const now = await getNow(); |
|
|
|
|
|
|
|
countVal.value = (isPrac ? now - entryTime.value : new Date(param.stopTime).getTime() - now) / 1000; // 如果是考核,取考核的结束时间减去当前时间去做倒计时,练习则直接取当前时间减去上次进来的时间做计时 |
|
|
|
startCount(); |
|
|
|
startCount(); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
@ -580,18 +592,24 @@ const getList = async () => { |
|
|
|
if (!per.value && !param.projectId) param.projectId = projects[0]?.projectId ?? 0; // 默认取第一个项目 |
|
|
|
if (!per.value && !param.projectId) param.projectId = projects[0]?.projectId ?? 0; // 默认取第一个项目 |
|
|
|
getProDetail(); |
|
|
|
getProDetail(); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
// 获取进入时间 |
|
|
|
|
|
|
|
const getEntryTime = async () => { |
|
|
|
|
|
|
|
let now = await getSumTime(); // 获取上次进入实验的时间,如果没有,说明是第一次进入,然后直接从服务器获取当前时间 |
|
|
|
|
|
|
|
if (!now) now = await getNow(); |
|
|
|
|
|
|
|
entryTime.value = now; |
|
|
|
|
|
|
|
}; |
|
|
|
onMounted(() => { |
|
|
|
onMounted(() => { |
|
|
|
getLevel.value = inject('getLevel'); // 关卡页面获取关卡方法 |
|
|
|
getLevel.value = inject('getLevel'); // 关卡页面获取关卡方法 |
|
|
|
per.value = param.assessmentId ? 1 : param.competitionId ? 2 : 0; |
|
|
|
per.value = param.assessmentId ? 1 : param.competitionId ? 2 : 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
param.cid && getEntryTime(); |
|
|
|
|
|
|
|
|
|
|
|
if (param.assessmentId) { |
|
|
|
if (param.assessmentId) { |
|
|
|
getAssList(); |
|
|
|
getAssList(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
param.cid && getList(); |
|
|
|
param.cid && getList(); |
|
|
|
if (param.competitionId) { |
|
|
|
if (param.competitionId) { |
|
|
|
clearInterval(statusTimer); |
|
|
|
getCompetitionStatus(); |
|
|
|
statusTimer.value = setInterval((_) => { |
|
|
|
|
|
|
|
getCompetitionStatus(); |
|
|
|
|
|
|
|
}, 1000); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|