|
@@ -1,272 +1,200 @@
|
|
|
<template>
|
|
|
- <div v-if="!dataError" class="tw-h-screen confirm-paper">
|
|
|
- <header
|
|
|
- class="tw-flex tw-gap-2 tw-justify-between tw-items-center header-container"
|
|
|
- >
|
|
|
- <div class="tw-ml-2">
|
|
|
- 进度:<span class="highlight-text">
|
|
|
- {{ currentIndex }}/{{ allIds.length }}
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- 姓名:<span class="highlight-text">{{ student?.name }}</span>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- 准考证号:<span class="highlight-text">{{ student?.examNumber }}</span>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- 学号:<span class="highlight-text">{{ student?.studentCode }}</span>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- 科目:<span class="highlight-text">
|
|
|
- {{ student?.subjectCode }}-{{ student?.subjectName }}
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- 客观分:<span class="highlight-text">{{
|
|
|
- student?.objectiveScore
|
|
|
- }}</span>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- 主观分:<span class="highlight-text">{{
|
|
|
- student?.subjectiveScore
|
|
|
- }}</span>
|
|
|
+ <div class="mark confirm-paper">
|
|
|
+ <div class="mark-header">
|
|
|
+ <div v-if="student" class="mark-header-part">
|
|
|
+ <div class="header-noun">
|
|
|
+ <span>课程名称:</span>
|
|
|
+ <span> {{ student.courseName }}({{ student.courseCode }})</span>
|
|
|
+ </div>
|
|
|
+ <div class="header-noun">
|
|
|
+ <span>试卷编号:</span>
|
|
|
+ <span>{{ student.paperNumber }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="header-noun">
|
|
|
+ <span>姓名:</span>
|
|
|
+ <span>{{ student.studentName }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="header-noun">
|
|
|
+ <span>学号:</span>
|
|
|
+ <span>{{ student?.studentCode }}</span>
|
|
|
+ </div>
|
|
|
+ <div v-if="studentIds.length > 1" class="header-noun">
|
|
|
+ <span>进度:</span>
|
|
|
+ <span> {{ currentIndex }}/{{ studentIds.length }} </span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div class="tw-flex tw-items-center tw-gap-2 tw-mx-8">
|
|
|
- <span
|
|
|
- v-for="(u, index) in student?.sheetUrls"
|
|
|
- :key="index"
|
|
|
- class="tw-cursor-pointer"
|
|
|
- :class="currentImage === index && 'highlight-text'"
|
|
|
- @click="currentImage = index"
|
|
|
- >
|
|
|
- {{ index + 1 }}
|
|
|
- </span>
|
|
|
+ <div class="mark-header-part">
|
|
|
+ <div class="paper-menu">
|
|
|
+ <span
|
|
|
+ v-for="(u, index) in student?.sheetUrls"
|
|
|
+ :key="index"
|
|
|
+ :class="{ 'is-active': currentImage === index }"
|
|
|
+ @click="currentImage = index"
|
|
|
+ >
|
|
|
+ {{ index + 1 }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </header>
|
|
|
+ </div>
|
|
|
|
|
|
- <div class="tw-flex" style="height: calc(100% - 56px)">
|
|
|
- <div
|
|
|
- style="flex: 0 1 420px; overflow: auto"
|
|
|
- class="tw-flex tw-flex-col tw-justify-between"
|
|
|
- >
|
|
|
- <div class="tw-m-2 tw-flex-1 tw-overflow-auto">
|
|
|
- <div v-if="pageType === 'DATA_CHECK'" class="tw-my-2 top-block">
|
|
|
- 是否缺考:
|
|
|
- <a-radio-group v-if="student" v-model:value="student.absent">
|
|
|
- <a-radio :value="true">是</a-radio>
|
|
|
- <a-radio :value="false">否</a-radio>
|
|
|
- </a-radio-group>
|
|
|
+ <div class="mark-main">
|
|
|
+ <div class="mark-body">
|
|
|
+ <div
|
|
|
+ v-if="student && currentImage !== 0"
|
|
|
+ class="page-action page-prev"
|
|
|
+ title="上一张"
|
|
|
+ @click="switchImageArrow({ left: true })"
|
|
|
+ >
|
|
|
+ <ArrowLeftOutlined />
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="student && currentImage !== student.sheetUrls.length - 1"
|
|
|
+ class="page-action page-next"
|
|
|
+ title="上一张"
|
|
|
+ @click="switchImageArrow({ right: true })"
|
|
|
+ >
|
|
|
+ <ArrowRightOutlined />
|
|
|
+ </div>
|
|
|
+ <div class="mark-body-container">
|
|
|
+ <div v-if="!student" class="mark-body-none">
|
|
|
+ <div>
|
|
|
+ <img src="@/assets/image-none-task.png" />
|
|
|
+ <p>暂无数据</p>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div v-if="pageType === 'DATA_CHECK'" class="tw-my-2 top-block">
|
|
|
- 试卷类型:
|
|
|
- <a-input
|
|
|
- v-if="student"
|
|
|
- v-model:value="student.paperType"
|
|
|
- class="normal-input"
|
|
|
- :maxlength="1"
|
|
|
+ <div
|
|
|
+ v-else
|
|
|
+ class="single-image-container"
|
|
|
+ :style="{ width: answerPaperScale }"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ draggable="false"
|
|
|
+ :src="curImageUrl"
|
|
|
+ :style="{
|
|
|
+ transform:
|
|
|
+ (rotateDegree ? 'translate( 0, calc(30vh))' : '') +
|
|
|
+ `rotate(${rotateDegree}deg)`,
|
|
|
+ }"
|
|
|
+ @click="switchImage"
|
|
|
+ @contextmenu="showBigImage"
|
|
|
/>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
+ <ZoomPaper v-if="student" showRotate fixed @rotateRight="rotateRight" />
|
|
|
+ </div>
|
|
|
|
|
|
- <div v-if="student?.answers" class="tw-mt-4">
|
|
|
- <div
|
|
|
- v-for="group in answersComputed"
|
|
|
- :key="group.mainNumber"
|
|
|
- class="tw-mt-2"
|
|
|
- :class="{ hide: !group.subs?.filter((s) => s.exist).length }"
|
|
|
- >
|
|
|
- <h2>
|
|
|
- {{ group.mainNumber }}、{{ group.mainTitle }} ({{
|
|
|
- group.subs.length
|
|
|
- }})
|
|
|
- </h2>
|
|
|
- <div class="tw-flex tw-flex-wrap tw-gap-2">
|
|
|
- <div
|
|
|
- v-for="question in group.subs"
|
|
|
- :key="question.subNumber"
|
|
|
- :class="{ hide: !question.exist }"
|
|
|
- >
|
|
|
- <span class="question-number">{{ question.subNumber }} </span>
|
|
|
- <!-- <a-input
|
|
|
- class="normal-input"
|
|
|
- :class="{
|
|
|
- 'long-input': question.type
|
|
|
- ? ['SINGLE', 'MULTIPLE'].includes(question.type)
|
|
|
- : group.mainTitle.match(/单选|多选|多项|不定项/),
|
|
|
- 'middle-input': question.type
|
|
|
- ? ['TRUE_OR_FALSE'].includes(question.type)
|
|
|
- : group.mainTitle.match(/判断/),
|
|
|
- }"
|
|
|
- :value="question.answer"
|
|
|
- :maxLength="
|
|
|
- (
|
|
|
- question.type
|
|
|
- ? ['MULTIPLE'].includes(question.type)
|
|
|
- : group.mainTitle.match(/多选|多项|不定项/)
|
|
|
- )
|
|
|
- ? 100
|
|
|
- : 1
|
|
|
- "
|
|
|
- @keydown="onPreventAnswerKey"
|
|
|
- @input="changeAnswer($event, question)"
|
|
|
- @blur="changeAnswer($event, question, '#')"
|
|
|
- /> -->
|
|
|
- <a-input
|
|
|
- class="normal-input"
|
|
|
- :class="{
|
|
|
- 'long-input': question.type
|
|
|
- ? !['SINGLE', 'TRUE_OR_FALSE'].includes(question.type)
|
|
|
- : !group.mainTitle.match(/单选|单项|判断/),
|
|
|
- }"
|
|
|
- :value="question.answer"
|
|
|
- :maxLength="
|
|
|
- (
|
|
|
- question.type
|
|
|
- ? ['MULTIPLE'].includes(question.type)
|
|
|
- : group.mainTitle.match(/多选|多项|不定项/)
|
|
|
- )
|
|
|
- ? 100
|
|
|
- : 1
|
|
|
- "
|
|
|
- @keydown="onPreventAnswerKey"
|
|
|
- @input="changeAnswer($event, question)"
|
|
|
- @blur="changeAnswer($event, question, '#')"
|
|
|
- />
|
|
|
- </div>
|
|
|
+ <div class="mark-board-track">
|
|
|
+ <div class="paper-topics">
|
|
|
+ <div
|
|
|
+ v-for="group in answersComputed"
|
|
|
+ :key="group.mainNumber"
|
|
|
+ class="paper-topic"
|
|
|
+ >
|
|
|
+ <h2 class="paper-topic-title">
|
|
|
+ {{ group.mainNumber }}、{{ group.mainTitle }} ({{
|
|
|
+ group.subs.length
|
|
|
+ }})
|
|
|
+ </h2>
|
|
|
+ <div class="paper-topic-body">
|
|
|
+ <div
|
|
|
+ v-for="question in group.subs"
|
|
|
+ :key="question.subNumber"
|
|
|
+ class="paper-topic-question"
|
|
|
+ >
|
|
|
+ <span class="question-number">{{ question.subNumber }} </span>
|
|
|
+ <a-input
|
|
|
+ class="normal-input"
|
|
|
+ :class="{
|
|
|
+ 'long-input': question.type
|
|
|
+ ? !['SINGLE', 'TRUE_OR_FALSE'].includes(question.type)
|
|
|
+ : !group.mainTitle.match(/单选|单项|判断/),
|
|
|
+ }"
|
|
|
+ :value="question.answer"
|
|
|
+ :maxLength="
|
|
|
+ (
|
|
|
+ question.type
|
|
|
+ ? ['MULTIPLE'].includes(question.type)
|
|
|
+ : group.mainTitle.match(/多选|多项|不定项/)
|
|
|
+ )
|
|
|
+ ? 100
|
|
|
+ : 1
|
|
|
+ "
|
|
|
+ @keydown="onPreventAnswerKey"
|
|
|
+ @input="changeAnswer($event, question)"
|
|
|
+ @blur="changeAnswer($event, question, '#')"
|
|
|
+ />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <div class="tw-flex tw-justify-between tw-bg-white tw-p-4">
|
|
|
- <a-tooltip v-if="!allViewed" placement="top">
|
|
|
- <template #title>请先浏览完该学生的所有试卷</template>
|
|
|
- <a-button
|
|
|
- :disabled="!allViewed"
|
|
|
- type="primary"
|
|
|
- shape="round"
|
|
|
- @click="saveStudentAnswer"
|
|
|
- >
|
|
|
- 保存
|
|
|
- </a-button>
|
|
|
- </a-tooltip>
|
|
|
+ <div class="board-tips">
|
|
|
+ <p v-if="!allViewed">请先浏览完该学生的所有试卷</p>
|
|
|
+ </div>
|
|
|
+ <div :class="['board-footer', { 'is-simple': !isMultiStudent }]">
|
|
|
<a-button
|
|
|
- v-else
|
|
|
- :disabled="!student?.upload"
|
|
|
+ class="board-submit"
|
|
|
+ size="medium"
|
|
|
type="primary"
|
|
|
- shape="round"
|
|
|
+ :disabled="!allViewed || !student?.upload"
|
|
|
@click="saveStudentAnswer"
|
|
|
>
|
|
|
保存
|
|
|
</a-button>
|
|
|
- <div>
|
|
|
- <a-button
|
|
|
- shape="round"
|
|
|
- :disabled="currentIndex <= 1"
|
|
|
- class="tw-mr-4"
|
|
|
- @click="getPreviousStudent"
|
|
|
- >
|
|
|
+ <div v-if="isMultiStudent" class="student-switch">
|
|
|
+ <a-button :disabled="isFirst" @click="getPreviousStudent">
|
|
|
上一份
|
|
|
</a-button>
|
|
|
- <a-button
|
|
|
- shape="round"
|
|
|
- :disabled="currentIndex === allIds.length"
|
|
|
- @click="getNextStudent"
|
|
|
- >
|
|
|
+ <a-button :disabled="isLast" @click="getNextStudent">
|
|
|
下一份
|
|
|
</a-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
- <div style="flex: 1" class="mark-body-container tw-relative">
|
|
|
- <ArrowLeftOutlined
|
|
|
- v-if="student && currentImage !== 0"
|
|
|
- class="tw-cursor-pointer tw-absolute"
|
|
|
- style="top: 45%; left: 20px; z-index: 1; font-size: 40px"
|
|
|
- title="上一张"
|
|
|
- @click="switchImageArrow({ left: true })"
|
|
|
- />
|
|
|
- <ArrowRightOutlined
|
|
|
- v-if="student && currentImage !== student.sheetUrls.length - 1"
|
|
|
- class="tw-cursor-pointer tw-absolute"
|
|
|
- style="top: 45%; right: 20px; z-index: 1; font-size: 40px"
|
|
|
- title="上一张"
|
|
|
- @click="switchImageArrow({ right: true })"
|
|
|
- />
|
|
|
- <div :style="{ width: answerPaperScale }">
|
|
|
- <img
|
|
|
- v-for="(item, index) in student?.sheetUrls"
|
|
|
- :key="item"
|
|
|
- class="tw-object-cover"
|
|
|
- :src="item"
|
|
|
- :style="{
|
|
|
- display: index === currentImage ? 'block' : 'none',
|
|
|
- transform:
|
|
|
- (rotateDegree ? 'translate( 0, calc(30vh))' : '') +
|
|
|
- `rotate(${rotateDegree}deg)`,
|
|
|
- }"
|
|
|
- @click="switchImage"
|
|
|
- @contextmenu="showBigImage"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <ZoomPaper v-if="student" fixed showRotate @rotateRight="rotateRight" />
|
|
|
- </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { httpApp } from "@/plugins/axiosApp";
|
|
|
+import {
|
|
|
+ studentObjectiveConfirmData,
|
|
|
+ saveStudentObjectiveConfirmData,
|
|
|
+} from "@/api/confirmPage";
|
|
|
import { message } from "ant-design-vue";
|
|
|
-import { onMounted, reactive, watch } from "vue";
|
|
|
-import { useRoute } from "vue-router";
|
|
|
-import { CheckSetting, StudentInfo } from "./check";
|
|
|
+import { onMounted, watch } from "vue";
|
|
|
import "viewerjs/dist/viewer.css";
|
|
|
import Viewer from "viewerjs";
|
|
|
import { store } from "@/store/store";
|
|
|
import ZoomPaper from "@/components/ZoomPaper.vue";
|
|
|
import { useTimers } from "@/setups/useTimers";
|
|
|
import { ArrowLeftOutlined, ArrowRightOutlined } from "@ant-design/icons-vue";
|
|
|
+import vls from "@/utils/storage";
|
|
|
+import { StudentObjectiveInfo } from "@/types";
|
|
|
|
|
|
const { addTimeout } = useTimers();
|
|
|
|
|
|
-const route = useRoute();
|
|
|
-// 使用 location.search 替代
|
|
|
-// const checkType = route.query.checkType;
|
|
|
-const queryId = route.query.queryId as string;
|
|
|
-let pageType: "DATA_CHECK" | "HAND_CHECK" = "HAND_CHECK";
|
|
|
-if (queryId) {
|
|
|
- pageType = "DATA_CHECK";
|
|
|
- sessionStorage.setItem(queryId, localStorage.getItem(queryId) || "[]");
|
|
|
- localStorage.removeItem(queryId);
|
|
|
-}
|
|
|
+const studentIds = $ref(vls.get("check-students", []));
|
|
|
|
|
|
onMounted(async () => {
|
|
|
- await getSetting();
|
|
|
- if (setting.studentIds.length === 0) {
|
|
|
+ if (studentIds.length === 0) {
|
|
|
void message.info("没有需要处理的考生,请返回。");
|
|
|
return;
|
|
|
}
|
|
|
await getNextStudent();
|
|
|
});
|
|
|
|
|
|
-let setting: CheckSetting = reactive({
|
|
|
- fileServer: "",
|
|
|
- studentIds: [],
|
|
|
- studentIdsDone: [],
|
|
|
-});
|
|
|
-
|
|
|
-const allIds = $computed(() => [
|
|
|
- ...setting.studentIdsDone,
|
|
|
- ...setting.studentIds,
|
|
|
-]);
|
|
|
+let currentStudentId = $ref("");
|
|
|
|
|
|
-let currentStudentId = $ref(-1);
|
|
|
+const currentIndex = $computed(() => studentIds.indexOf(currentStudentId));
|
|
|
+const isFirst = $computed(() => currentIndex === 0);
|
|
|
+const isLast = $computed(() => currentIndex === studentIds.length - 1);
|
|
|
+const isMultiStudent = $computed(() => studentIds.length > 1);
|
|
|
|
|
|
-const currentIndex = $computed(() => allIds.indexOf(currentStudentId) + 1);
|
|
|
+const curImageUrl = $computed(() =>
|
|
|
+ student ? student.sheetUrls[currentImage].url : ""
|
|
|
+);
|
|
|
|
|
|
-let student: StudentInfo | null = $ref(null);
|
|
|
+let student: StudentObjectiveInfo | null = $ref(null);
|
|
|
/** 后台数据错误,停止整个页面的流程 */
|
|
|
let dataError = $ref(false);
|
|
|
|
|
@@ -289,69 +217,37 @@ const answersComputed = $computed(() => {
|
|
|
v.subs =
|
|
|
student?.answers.filter((v2) => v2.mainNumber === v.mainNumber) ?? [];
|
|
|
});
|
|
|
- // console.log(mains);
|
|
|
return mains;
|
|
|
});
|
|
|
|
|
|
-async function getSetting() {
|
|
|
- let res: any;
|
|
|
- if (pageType === "DATA_CHECK") {
|
|
|
- const query: Array<{ name: string; value: string }> = JSON.parse(
|
|
|
- sessionStorage.getItem(queryId) || "[]"
|
|
|
- );
|
|
|
- const form = new FormData();
|
|
|
- for (const v of query) {
|
|
|
- form.append(v.name, v.value + "");
|
|
|
- }
|
|
|
- res = await httpApp.post("/api/admin/exam/check/answer/getSetting", form);
|
|
|
- } else {
|
|
|
- const form = new FormData();
|
|
|
- form.append("checkType", route.query.checkType as string);
|
|
|
- form.append("subjectCode", route.query.subjectCode as string);
|
|
|
- form.append("examSite", route.query.examSite as string);
|
|
|
- res = await httpApp.post(`/api/admin/exam/check/student/getSetting`, form);
|
|
|
- }
|
|
|
-
|
|
|
- setting.fileServer = res.data.fileServer;
|
|
|
- setting.studentIds = res.data.studentIds || [];
|
|
|
-}
|
|
|
-
|
|
|
async function getNextStudent() {
|
|
|
- const wantedIndex = allIds.indexOf(currentStudentId);
|
|
|
- if (allIds[wantedIndex + 1]) {
|
|
|
- student = await getStudent(allIds[wantedIndex + 1]);
|
|
|
- }
|
|
|
+ if (isLast) return;
|
|
|
+ student = await getStudent(studentIds[currentIndex + 1]);
|
|
|
}
|
|
|
|
|
|
async function getPreviousStudent() {
|
|
|
- const wantedIndex = allIds.indexOf(currentStudentId);
|
|
|
- student = await getStudent(allIds[wantedIndex - 1]);
|
|
|
+ if (isFirst) return;
|
|
|
+ student = await getStudent(studentIds[currentIndex - 1]);
|
|
|
}
|
|
|
|
|
|
-async function getStudent(studentId: number) {
|
|
|
- const stu: StudentInfo = await (
|
|
|
- await httpApp.get(
|
|
|
- `/api/admin/exam/check/answer/info?studentId=${studentId}`
|
|
|
- )
|
|
|
- ).data;
|
|
|
- stu?.sheetUrls.forEach((v, i, a) => (a[i] = setting.fileServer + v));
|
|
|
- currentStudentId = stu.id;
|
|
|
- currentImage = 0;
|
|
|
- browsedImageIndexes = [0];
|
|
|
- if (!stu.success) {
|
|
|
- void message.error(stu.message, 24 * 60 * 60);
|
|
|
+async function getStudent(studentId: string) {
|
|
|
+ const res = await studentObjectiveConfirmData(studentId).catch(() => {
|
|
|
dataError = true;
|
|
|
-
|
|
|
- throw new Error("取学生信息出错: " + stu.message);
|
|
|
+ });
|
|
|
+ if (dataError) {
|
|
|
+ void message.error(res.message, 24 * 60 * 60);
|
|
|
+ throw new Error("取学生信息出错: " + res.message);
|
|
|
}
|
|
|
|
|
|
- // for dev
|
|
|
- // stu.answers = [
|
|
|
- // { mainNumber: 1, subNumber: "1", answer: "A" },
|
|
|
- // { mainNumber: 1, subNumber: "2", answer: "B" },
|
|
|
- // { mainNumber: 2, subNumber: "1", answer: "#" },
|
|
|
- // ];
|
|
|
- // stu.titles = { 1: "单选题", 2: "多选题" };
|
|
|
+ const stu = res.data;
|
|
|
+ stu.sheetUrls = [
|
|
|
+ { index: 1, url: "/1-1.jpg" },
|
|
|
+ { index: 2, url: "/1-2.jpg" },
|
|
|
+ ];
|
|
|
+ currentStudentId = stu.studentId;
|
|
|
+ currentImage = 0;
|
|
|
+ browsedImageIndexes = [0];
|
|
|
+
|
|
|
return stu;
|
|
|
}
|
|
|
|
|
@@ -373,11 +269,7 @@ function onPreventAnswerKey(e: KeyboardEvent) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-function changeAnswer(
|
|
|
- event: Event,
|
|
|
- question: StudentInfo["answers"][0],
|
|
|
- defaultValue?: string
|
|
|
-) {
|
|
|
+function changeAnswer(event: Event, question: string, defaultValue?: string) {
|
|
|
const target = event.target as HTMLInputElement;
|
|
|
student.answers = student.answers.map((v) => {
|
|
|
if (
|
|
@@ -390,45 +282,30 @@ function changeAnswer(
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+let loading = false;
|
|
|
async function saveStudentAnswer() {
|
|
|
if (!student) return;
|
|
|
- const form = new FormData();
|
|
|
- form.append("studentId", student.id + "");
|
|
|
- const answers = student.answers.map((v) => v.answer || "#").join(",");
|
|
|
+
|
|
|
+ if (loading) return;
|
|
|
+ loading = true;
|
|
|
+
|
|
|
+ const data = {
|
|
|
+ studentId: student.studentId,
|
|
|
+ answers: student.answers.map((v) => v.answer || "#").join(","),
|
|
|
+ };
|
|
|
// if (!answers.match(/^(#*,*[A-Z]*)+$/g)) {
|
|
|
// void message.error("答案只能是#和大写英文字母");
|
|
|
// return;
|
|
|
// }
|
|
|
|
|
|
- form.append("answers", answers);
|
|
|
-
|
|
|
- const extra = pageType === "DATA_CHECK";
|
|
|
- extra && form.append("absent", student.absent + "");
|
|
|
- extra && form.append("paperType", student.paperType);
|
|
|
- if (extra) {
|
|
|
- if (!student.paperType.match(/^#|[A-Z]$/)) {
|
|
|
- void message.error("试卷类型只能是#和大写英文字母");
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const url = extra
|
|
|
- ? // 数据检查
|
|
|
- "/api/admin/exam/check/answer/save"
|
|
|
- : `/api/admin/exam/check/student/save`;
|
|
|
- const res = await httpApp
|
|
|
- .post(url, form)
|
|
|
- .catch(() => message.error("保存失败-接口调用失败"));
|
|
|
- if (!res.data) {
|
|
|
+ const res = await saveStudentObjectiveConfirmData(data).catch(() => false);
|
|
|
+ loading = false;
|
|
|
+ if (!res) {
|
|
|
void message.error("保存失败,请刷新页面。");
|
|
|
} else {
|
|
|
void message.success("保存成功");
|
|
|
await getNextStudent();
|
|
|
}
|
|
|
-
|
|
|
- if (setting.studentIds.length === 0) {
|
|
|
- void message.success("所有考生已处理完毕。");
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
//#region : 显示大图,供查看和翻转
|
|
@@ -442,7 +319,6 @@ watch(
|
|
|
() => currentImage,
|
|
|
() => {
|
|
|
browsedImageIndexes.push(currentImage);
|
|
|
- console.log(browsedImageIndexes);
|
|
|
}
|
|
|
);
|
|
|
function switchImageArrow({
|
|
@@ -532,79 +408,3 @@ function rotateRight() {
|
|
|
}
|
|
|
//#endregion
|
|
|
</script>
|
|
|
-
|
|
|
-<style scoped>
|
|
|
-.question-number {
|
|
|
- display: inline-block;
|
|
|
- width: 22px;
|
|
|
- text-align: right;
|
|
|
- font-size: 12px;
|
|
|
- font-weight: normal;
|
|
|
- color: #474966;
|
|
|
- line-height: 14px;
|
|
|
- margin-right: 0.5em;
|
|
|
-}
|
|
|
-.normal-input {
|
|
|
- width: 36px;
|
|
|
- height: 32px;
|
|
|
- background: #edf2fa;
|
|
|
- border-radius: 6px;
|
|
|
- border: 1px solid #c8ced8;
|
|
|
- font-size: 14px;
|
|
|
- font-weight: normal;
|
|
|
- color: #474966;
|
|
|
- text-align: center;
|
|
|
-}
|
|
|
-.normal-input.long-input {
|
|
|
- width: 94px;
|
|
|
- padding: 4px;
|
|
|
-}
|
|
|
-.normal-input.middle-input {
|
|
|
- width: 61px !important;
|
|
|
- padding: 4px;
|
|
|
-}
|
|
|
-.header-container {
|
|
|
- position: relative;
|
|
|
- height: 56px;
|
|
|
- line-height: 16px;
|
|
|
-
|
|
|
- background-color: var(--header-bg-color);
|
|
|
- color: rgba(255, 255, 255, 0.5);
|
|
|
-}
|
|
|
-.highlight-text {
|
|
|
- color: white;
|
|
|
- font-size: var(--app-title-font-size);
|
|
|
-}
|
|
|
-
|
|
|
-.mark-body-container {
|
|
|
- position: relative;
|
|
|
- min-height: calc(100vh - 56px);
|
|
|
- height: calc(100vh - 56px);
|
|
|
- overflow: auto;
|
|
|
- /* background-size: 8px 8px;
|
|
|
- background-image: linear-gradient(to right, #e7e7e7 4px, transparent 4px),
|
|
|
- linear-gradient(to bottom, transparent 4px, #e7e7e7 4px); */
|
|
|
- background-color: var(--app-container-bg-color);
|
|
|
- background-image: linear-gradient(45deg, #e0e0e0 25%, transparent 25%),
|
|
|
- linear-gradient(-45deg, #e0e0e0 25%, transparent 25%),
|
|
|
- linear-gradient(45deg, transparent 75%, #e0e0e0 75%),
|
|
|
- linear-gradient(-45deg, transparent 75%, #e0e0e0 75%);
|
|
|
- background-size: 20px 20px;
|
|
|
- background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
|
|
- transform: inherit;
|
|
|
-}
|
|
|
-
|
|
|
-.hide {
|
|
|
- display: none;
|
|
|
- visibility: hidden;
|
|
|
- opacity: 0;
|
|
|
-}
|
|
|
-.confirm-paper .top-block {
|
|
|
- background-color: #fff;
|
|
|
- height: 50px;
|
|
|
- padding: 0 20px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- border-radius: 6px;
|
|
|
-}
|
|
|
-</style>
|