123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480 |
- <template>
- <div class="arbitrate">
- <div class="arbitrate-title">
- <a-button class="arbitrate-back" @click="goback">
- <template #icon><SwapLeftOutlined /> </template>后退
- </a-button>
- <div class="arbitrate-stat">
- <p class="color-success">
- <CheckCircleFilled />已处理:{{ progress.finishCount }}
- </p>
- <p class="color-error">
- <CloseCircleFilled />未处理:{{ progress.todoCount }}
- </p>
- </div>
- </div>
- <div class="arbitrate-body">
- <RecognizeImage
- v-if="curArbitrateTaskDetail"
- :img-src="curArbitrateTaskDetail.uri"
- />
- <!-- arbitrate action modal -->
- <div v-if="curArbitrateTaskDetail" class="arbitrate-modal">
- <a-row align="top" :gutter="8" class="m-b-8px">
- <a-col :span="6">
- <div class="modal-box">
- <p class="box-title">客观题</p>
- <p class="box-cont">{{ curTaskDetailName }}</p>
- </div>
- </a-col>
- <a-col :span="12">
- <div class="modal-box modal-origin"></div>
- </a-col>
- <a-col :span="6">
- <div class="modal-box" @click="changePrevTaskDetail">
- <p class="box-title">左键</p>
- <p class="box-cont">上一个</p>
- </div>
- </a-col>
- </a-row>
- <a-row align="top" :gutter="8">
- <a-col :span="3">
- <div class="modal-box">
- <p class="box-title">一评结果</p>
- <p class="box-cont">{{ curArbitrateTaskDetail.result1 }}</p>
- </div>
- </a-col>
- <a-col :span="3">
- <div class="modal-box">
- <p class="box-title">二评结果</p>
- <p class="box-cont">{{ curArbitrateTaskDetail.result2 }}</p>
- </div>
- </a-col>
- <a-col :span="12">
- <div class="modal-box modal-options">
- <a-button
- v-for="option in curArbitrateTaskDetail.options"
- :key="option"
- :type="
- curArbitrateTaskDetail.value.result.includes(option)
- ? 'primary'
- : 'default'
- "
- @click="selectOption(option)"
- >{{ option }}</a-button
- >
- </div>
- </a-col>
- <a-col :span="6">
- <div class="modal-box">
- <p class="box-title">Enter键</p>
- <p class="box-cont">下一个</p>
- </div>
- </a-col>
- </a-row>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import {
- computed,
- ref,
- reactive,
- onMounted,
- onBeforeUnmount,
- nextTick,
- } from "vue";
- import { useRoute, useRouter } from "vue-router";
- import {
- CheckCircleFilled,
- CloseCircleFilled,
- SwapLeftOutlined,
- } from "@ant-design/icons-vue";
- import { message } from "ant-design-vue";
- import RecognizeImage from "./RecognizeImage.vue";
- import {
- recognizeArbitrateTask,
- recognizeArbitrateSave,
- recognizeArbitrateProgress,
- recognizeArbitrateHistory,
- } from "@/ap/recognizeCheck";
- import {
- RecognizeArbitrateItem,
- RecognizeArbitrateTaskDetail,
- RecognizeArbitrateSavePage,
- } from "@/ap/types/recognizeCheck";
- import { parseRecogData, parseDetailSize } from "@/utils/recog/recog";
- defineOptions({
- name: "RecognizeArbitrate",
- });
- const router = useRouter();
- const route = useRoute();
- const groupId = route.params.groupId ? Number(route.params.groupId) : 0;
- // 任务进度
- const progress = ref({
- finishCount: 0,
- todoCount: 0,
- });
- async function updateProgress() {
- const res = await recognizeArbitrateProgress(groupId);
- progress.value = res || {};
- }
- const curArbitrateTaskDetails = ref([] as RecognizeArbitrateTaskDetail[]);
- const curArbitrateTaskDetailIndex = ref(0);
- const curArbitrateTaskDetail = ref<RecognizeArbitrateTaskDetail | null>(null);
- const nextArbitrateTaskDetail = computed(() => {
- return curArbitrateTaskDetails.value[curArbitrateTaskDetailIndex.value + 1];
- });
- // 下一个细分任务是否是另一个任务
- const nextDetailIsAnotherTask = computed(() => {
- return !nextArbitrateTaskDetail.value;
- });
- const curTaskDetailName = computed(() => {
- if (!curArbitrateTaskDetail.value) return "";
- if (curArbitrateTaskDetail.value.type === "question") {
- return `#${curArbitrateTaskDetail.value.index}`;
- }
- return "-";
- });
- // 获取任务
- let curTask: RecognizeArbitrateItem | null = null;
- async function getTask() {
- const res = await recognizeArbitrateTask(groupId).catch(() => false);
- curTask = res || null;
- if (!curTask) {
- return;
- }
- curArbitrateTaskDetails.value = parseDetails(curTask);
- }
- async function initData() {
- await getTask();
- curArbitrateTaskDetailIndex.value = 0;
- setCurTaskDetail();
- }
- // 解析仲裁任务详情
- function parseDetails(
- data: RecognizeArbitrateItem
- ): RecognizeArbitrateTaskDetail[] {
- const details: RecognizeArbitrateTaskDetail[] = [];
- data.pages.forEach((page) => {
- const recogData = parseRecogData(page.recogData);
- if (!recogData) return;
- // 缺考
- if (page.absent) {
- details.push({
- ...parseDetailSize(recogData.absent.fill_result[0], "absent", 0, []),
- result1: page.absent ? page.absent[0] : "",
- result2: page.absent ? page.absent[1] : "",
- pageIndex: page.index,
- groupId: groupId,
- uri: page.uri,
- });
- }
- // 违纪
- if (page.breach) {
- details.push({
- ...parseDetailSize(recogData.breach.fill_result[0], "breach", 0, []),
- result1: page.breach ? page.breach[0] : "",
- result2: page.breach ? page.breach[1] : "",
- pageIndex: page.index,
- groupId: groupId,
- uri: page.uri,
- });
- }
- // 试卷类型
- if (page.paperType) {
- details.push({
- ...parseDetailSize(
- recogData.paperType.fill_result[0],
- "paperType",
- 0,
- []
- ),
- result1: page.paperType ? page.paperType[0] : "",
- result2: page.paperType ? page.paperType[1] : "",
- pageIndex: page.index,
- groupId: groupId,
- uri: page.uri,
- });
- }
- // 试题
- let index = 0;
- recogData.question.forEach((gGroup) => {
- gGroup.fill_result.forEach((qRecog) => {
- qRecog.index = ++index;
- const questionResult = page.question[qRecog.index];
- const arbitrate = questionResult && questionResult.length >= 2;
- if (!arbitrate) return;
- details.push({
- ...parseDetailSize(qRecog, "question", qRecog.index, []),
- result1: questionResult ? questionResult[0] : "",
- result2: questionResult ? questionResult[1] : "",
- pageIndex: page.index,
- groupId: groupId,
- uri: page.uri,
- });
- });
- });
- });
- return details;
- }
- // 任务执行流程 ----------------- start>
- function setCurTaskDetail() {
- curArbitrateTaskDetail.value =
- curArbitrateTaskDetails.value[curArbitrateTaskDetailIndex.value];
- }
- const detailChanging = ref(false);
- async function changeNextTaskDetail() {
- if (detailChanging.value) return;
- detailChanging.value = true;
- if (nextDetailIsAnotherTask.value) {
- await submitCurTask().catch(() => {});
- await getNextTask().catch(() => {});
- await nextTick(() => {
- detailChanging.value = false;
- });
- return;
- }
- curArbitrateTaskDetailIndex.value++;
- setCurTaskDetail();
- setTimeout(() => {
- detailChanging.value = false;
- }, 500);
- }
- async function changePrevTaskDetail() {
- if (detailChanging.value) return;
- if (curArbitrateTaskDetailIndex.value === 0) {
- detailChanging.value = true;
- await getPrevTask().catch(() => {});
- await nextTick(() => {
- detailChanging.value = false;
- });
- return;
- }
- detailChanging.value = true;
- curArbitrateTaskDetailIndex.value--;
- setCurTaskDetail();
- setTimeout(() => {
- detailChanging.value = false;
- }, 500);
- }
- async function getPrevTask() {
- let result = true;
- const res = await recognizeArbitrateHistory({
- groupId,
- id: curTask?.id,
- }).catch(() => {
- result = false;
- });
- if (!result) {
- message.error("获取上一个任务失败!");
- return;
- }
- if (!res) {
- message.error("没有上一个任务了!");
- return;
- }
- curTask = res;
- curArbitrateTaskDetails.value = parseDetails(curTask);
- curArbitrateTaskDetailIndex.value = curArbitrateTaskDetails.value.length - 1;
- setCurTaskDetail();
- }
- async function getNextTask() {
- let result = true;
- const res = await recognizeArbitrateHistory({
- groupId,
- id: curTask?.id,
- next: true,
- }).catch(() => {
- result = false;
- });
- if (!result) {
- message.error("获取下一个任务失败!");
- return;
- }
- if (!res) {
- message.error("没有下一个任务了!");
- return;
- }
- curTask = res;
- curArbitrateTaskDetails.value = parseDetails(curTask);
- curArbitrateTaskDetailIndex.value = 0;
- setCurTaskDetail();
- }
- function selectOption(option: string) {
- if (!curArbitrateTaskDetail.value) return;
- // 单选直接赋值
- if (!curArbitrateTaskDetail.value.multiple) {
- curArbitrateTaskDetail.value.result = [option];
- return;
- }
- // 多选情况
- // 空直接赋值,空值与其他互斥
- if (option === "#") {
- curArbitrateTaskDetail.value.result = ["#"];
- return;
- }
- let result = curArbitrateTaskDetail.value.result.filter(
- (item) => item === "#"
- );
- if (result.includes(option)) {
- result = result.filter((item) => item !== option);
- } else {
- result.push(option);
- }
- // 保证result的顺序和options的顺序是一致的
- curArbitrateTaskDetail.value.result =
- curArbitrateTaskDetail.value.options.filter((item) =>
- result.includes(item)
- );
- }
- // 键盘事件
- function registKeyEvent() {
- document.addEventListener("keydown", keyEventHandle);
- }
- function removeKeyEvent() {
- document.removeEventListener("keydown", keyEventHandle);
- }
- function keyEventHandle(e: KeyboardEvent) {
- if (e.code === "Enter") {
- e.preventDefault();
- onConfirm();
- return;
- }
- }
- // 保存任务详情信息
- async function onConfirm() {
- if (!curArbitrateTaskDetail.value?.result.length) {
- message.error("请完成仲裁结果!");
- return;
- }
- await changeNextTaskDetail();
- }
- // 提交当前任务仲裁数据
- function getTaskTypeResult(
- type: "absent" | "breach" | "paperType",
- pageIndex: number
- ) {
- const taskDetail = curArbitrateTaskDetails.value.find(
- (item) => item.pageIndex === pageIndex && item.type === type
- );
- const result = taskDetail ? taskDetail.result.join() : null;
- if (type === "paperType") return result;
- return result ? result === "true" : null;
- }
- async function submitCurTask() {
- if (!curTask) return;
- const curArbitrateTaskDetailQuestionResults: Record<string, string> = {};
- curArbitrateTaskDetails.value.forEach((item) => {
- if (item.type !== "question") return;
- const k = `${item.pageIndex}-${item.index}`;
- curArbitrateTaskDetailQuestionResults[k] = item.result.join("");
- });
- const pages = curTask.pages.map((page) => {
- const absentResult = getTaskTypeResult(
- "absent",
- page.index
- ) as RecognizeArbitrateSavePage["absent"];
- const breachResult = getTaskTypeResult(
- "breach",
- page.index
- ) as RecognizeArbitrateSavePage["breach"];
- const paperTypeResult = getTaskTypeResult(
- "paperType",
- page.index
- ) as RecognizeArbitrateSavePage["paperType"];
- const questionResult: Record<number, string> = {};
- curTaskDetails.value.forEach((item) => {
- if (item.type !== "question") return;
- const k = `${item.pageIndex}-${item.index}`;
- const result = item.arbitrate
- ? curArbitrateTaskDetailQuestionResults[k]
- : item.result.join("");
- questionResult[item.index] = result;
- });
- const npage: RecognizeArbitrateSavePage = {
- index: page.index,
- absent: absentResult,
- breach: breachResult,
- paperType: paperTypeResult,
- question: questionResult,
- selective: null,
- };
- return npage;
- });
- await recognizeArbitrateSave({ id: curTask.id, pages }).catch(() => false);
- }
- // 任务执行流程 ----------------- end>
- // 返回
- function goback() {
- router.back();
- }
- onMounted(() => {
- initData();
- registKeyEvent();
- });
- onBeforeUnmount(() => {
- removeKeyEvent();
- });
- </script>
|