import { useMarkStore } from "@/store"; import { saveTask, doUnselectiveType } from "@/api/markPage"; import { message } from "ant-design-vue"; import { isNumber, cloneDeep } from "lodash-es"; import { h } from "vue"; import EventBus from "@/plugins/eventBus"; import type { Question, MarkResult } from "@/types"; import useStatus from "./useStatus"; import useMarkTask from "./useMarkTask"; import useTaskTips from "./useTaskTips"; import useTaskQuestion from "./useTaskQuestion"; export default function useMarkSubmit() { const markStore = useMarkStore(); const { updateStatus } = useStatus(); const { nextTask } = useMarkTask(); const { setPrevTips, registTaskChangeTips } = useTaskTips(); const { updateQuestionStatus } = useTaskQuestion(); registTaskChangeTips(); // 检查分数 const validateScore = (markResult: MarkResult) => { const errors: Array<{ question: Question; index: number; error: string }> = []; markResult.scoreList.forEach((score: number, index: number) => { if (!markStore.currentTask) return; const question = markStore.currentTask.questionList[index]!; // 如果是自评或者有问题的题目,不检查分数 if (!question.selfMark || question.problem) return; const { maxScore, minScore, mainNumber, subNumber, questionName } = question; let error; if (!isNumber(score)) { error = `${mainNumber}-${subNumber}${ questionName ? "(" + questionName + ")" : "" } 没有给分,不能提交。`; } else if (isNumber(maxScore) && score > maxScore) { error = `${mainNumber}-${subNumber}${ questionName ? "(" + questionName + ")" : "" } 给分大于最高分不能提交。`; } else if (isNumber(minScore) && score < minScore) { error = `${mainNumber}-${subNumber}${ questionName ? "(" + questionName + ")" : "" } 给分小于最低分不能提交。`; } if (error) { errors.push({ question, index, error }); } }); return errors; }; // 检查评卷任务 function checkMarkResult(markResult: MarkResult): boolean { const errors = validateScore(markResult); if (errors.length !== 0) { console.log(errors); const msg = errors.map((v) => h("div", `${v.error}`)); void message.warning({ content: h("span", ["校验失败", ...msg]), duration: 10, }); return; } const allowNullQs = markStore.currentTask.questionList .filter((q) => q.problem || !q.selfMark) .map((q, i) => i); const questions = markStore.currentTask.questionList.filter( (q) => !q.problem && q.selfMark ); const scoreList = markResult.scoreList.filter( (_, i) => !allowNullQs.includes(i) ); if ( scoreList.length !== questions.length || !scoreList.every((s) => isNumber(s)) ) { console.error({ content: "markResult格式不正确,缺少分数" }); return; } if (markStore.isTrackMode) { const trackScores = markResult.markerTrackList .map((t) => Math.round((t.score || 0) * 100)) .reduce((acc, s) => acc + s, 0) / 100; if ( trackScores !== markResult.markerScore && markResult.markerScore !== null ) { void message.error({ content: "轨迹分与总分不一致,请检查。", duration: 3, }); return; } } if (markStore.setting.forceSpecialTag) { if ( markResult.markerTrackList.length === 0 && markResult.markerTagList.length === 0 ) { void message.error({ content: "强制标记已开启,请至少使用一个标记。", duration: 5, }); return; } } return true; } // 获取保存评卷任务的数据 function getSaveTaskResult() { const datas = cloneDeep(markStore.currentTask.markResult); datas.spent = Date.now() - markStore.currentTask.__markStartTime; const allowNullQs = datas.questionList .filter((q) => !q.selfMark) .map((q, i) => i); datas.scoreList = datas.scoreList.filter( (_, i) => !allowNullQs.includes(i) ); datas.questionList = datas.questionList .filter((q) => q.selfMark) .map((q) => { q.markerTrackList = datas.markerTrackList.filter( (t) => t.mainNumber === q.mainNumber && t.subNumber === q.subNumber ); q.markerTagList = datas.markerTagList.filter( (t) => t.mainNumber === q.mainNumber && t.subNumber === q.subNumber ); q.markerScore = q.markerTrackList.reduce((acc, t) => { return acc + (t.score || 0); }, 0); return q; }) as Question[]; datas.markerTrackList = []; datas.markerTagList = []; // 单题阅模式需要告诉后台正在评卷的questionId if (markStore.isSingelQuestionModel) datas.markedQuestionId = datas.questionList[0].questionId; return datas; } // 保存评卷任务 const saveTaskToServer = async () => { if (!markStore.currentTask) return; const markResult = markStore.currentTask.markResult; if (!markResult) return; if (!checkMarkResult(markResult)) return; if (!markStore.isTrackMode) { markResult.markerTrackList = []; } console.log("save task to server"); void message.loading({ content: "保存评卷任务..." }); const res = await saveTask(getSaveTaskResult()).catch(() => false); if (!res) return; // 故意不在此处同步等待,因为不必等待 if (res.data.success && markStore.currentTask) { // 保存成功后,缓存当前评卷提示信息 // 回评不缓存 if (!markStore.historyOpen) setPrevTips(); // 单题模式下,更新当前题目的状态 if (markStore.isSingelQuestionModel) { await updateQuestionStatus(markStore.currentQuestion.questionId); } else { updateStatus().catch((e) => console.log("保存任务后获取status出错", e)); } void message.success({ content: "保存成功", duration: 2 }); if (!markStore.historyOpen) { markStore.currentTask = undefined; markStore.tasks.shift(); markStore.currentTask = markStore.tasks[0]; } else { EventBus.emit("should-reload-history"); } } else if (!res.data.success) { void message.error({ content: "提交失败,请刷新页面", duration: 10, }); return; } else if (!markStore.currentTask) { void message.warn({ content: "暂无新任务", duration: 10 }); } // 获取下一个任务 void nextTask(); }; // 全部零分提交 const allZeroSubmit = async () => { const markResult = markStore.currentTask?.markResult; if (!markResult) return; const { markerScore, scoreList, markerTrackList, markerTagList } = markResult; markResult.markerScore = 0; const ss = new Array(markStore.currentTaskEnsured.questionList.length); markResult.scoreList = ss.fill(0); markResult.markerTrackList = []; try { await saveTaskToServer(); } catch (error) { console.log("error restore"); } finally { markResult.markerScore = markerScore; markResult.scoreList = scoreList; markResult.markerTrackList = markerTrackList; markResult.markerTagList = markerTagList; } }; // 未选做提交 const unselectiveSubmit = async () => { const markResult = markStore.currentTask?.markResult; if (!markResult) return; try { const res = await doUnselectiveType(); if (res?.data.success) { void message.success({ content: "未选做处理成功", duration: 3 }); if (!markStore.historyOpen) { markStore.currentTask = undefined; markStore.tasks.shift(); markStore.currentTask = markStore.tasks[0]; } if (markStore.historyOpen) { EventBus.emit("should-reload-history"); } await updateStatus(); } else { void message.error({ content: res?.data.message || "错误", duration: 5, }); } } catch (error) { console.log("未选做处理失败", error); void message.error({ content: "网络异常", duration: 5 }); await new Promise((res) => setTimeout(res, 1500)); window.location.reload(); } }; return { saveTaskToServer, allZeroSubmit, unselectiveSubmit, }; }