Selaa lähdekoodia

feat: 普通模式阅卷根据评卷区展示得分

zhangjie 3 kuukautta sitten
vanhempi
commit
4ca2414f24
3 muutettua tiedostoa jossa 121 lisäystä ja 1 poistoa
  1. 9 0
      src/api/task.ts
  2. 9 0
      src/api/types/task.ts
  3. 103 1
      src/views/base/track-export/useDraw.ts

+ 9 - 0
src/api/task.ts

@@ -3,6 +3,7 @@ import {
   CardData,
   Task,
   StudentObjectiveInfo,
+  MarkArea,
   SemesterItem,
   ExamItem,
   CourseItem,
@@ -99,3 +100,11 @@ export async function studentObjectiveConfirmData(
     { params: { studentId } }
   );
 }
+/** 获取学生客观题数据 */
+export async function getMarkArea(studentId: string): Promise<MarkArea[]> {
+  return axios.post(
+    '/api/admin/mark/inspected/get_mark_area',
+    {},
+    { params: { studentId } }
+  );
+}

+ 9 - 0
src/api/types/task.ts

@@ -186,6 +186,15 @@ export type StudentObjectiveInfo = {
   success: boolean;
 };
 
+export interface MarkArea {
+  title: string;
+  mainNumber: number;
+  subNumber: number;
+  score: number;
+  picList: string;
+  splitConfig?: SplitConfig[];
+}
+
 // card --------->
 
 // page --------->

+ 103 - 1
src/views/base/track-export/useDraw.ts

@@ -2,8 +2,9 @@ import {
   getSingleStudentTaskOfStudentTrack,
   studentObjectiveConfirmData,
   getSingleStudentCardData,
+  getMarkArea,
 } from '@/api/task';
-import { Task, Track, SpecialTag, Question } from '@/api/types/task';
+import { Task, Track, SpecialTag, Question, MarkArea } from '@/api/types/task';
 import { TrackConfigType } from '@/store/modules/app/types';
 import { PictureTypeEnum, PICTURE_TYPE } from '@/constants/enumerate';
 import { calcSum, deepCopy, maxNum, strGbLen } from '@/utils/utils';
@@ -128,6 +129,7 @@ export default function useDraw(drawConfig: DrawConfig) {
 
   let answerMap = {} as AnswerMap;
   let cardData = [] as CardDataItem[];
+  let markAreaList = [] as MarkArea[];
   let recogDatas: string[] = [];
   let rawTask = {} as Task;
   let trackData = [] as TrackItemType[];
@@ -258,6 +260,16 @@ export default function useDraw(drawConfig: DrawConfig) {
             ? (JSON.parse(cardRes.content) as CardContentType)
             : { pages: [] };
         cardData = cardContent.pages;
+
+        if (cardData.length) return;
+        // 如果没有题卡信息,就查询评卷区域信息
+        const areaRes = await getMarkArea(studentId);
+        markAreaList = (areaRes || []).map((item: MarkArea) => {
+          return {
+            ...item,
+            splitConfig: item.picList ? JSON.parse(item.picList) : [],
+          };
+        });
       });
     }
 
@@ -333,6 +345,10 @@ export default function useDraw(drawConfig: DrawConfig) {
 
     const markDeailList = parseMarkDetailList(originImgs);
     const objectiveAnswerTagList = parseObjectiveAnswerTags(originImgs);
+    // 如果没有轨迹信息信息,有评卷区域信息,就在评卷区域左上角展示得分
+    const commonMarkQuestionAreaList = !trackLists.length
+      ? parseCommonMarkQuestionAreaScore(originImgs)
+      : [];
 
     for (let i = 0; i < originImgs.length; i++) {
       const img = originImgs[i];
@@ -350,6 +366,7 @@ export default function useDraw(drawConfig: DrawConfig) {
       const answerTags = paserRecogData(i);
       drawTrackList.push(...answerTags);
       drawTrackList.push(...(markDeailList[i] || []));
+      drawTrackList.push(...(commonMarkQuestionAreaList[i] || []));
       const oTags = (objectiveAnswerTagList[i] || []).map(
         (tag) => tag.trackItem
       );
@@ -799,7 +816,49 @@ export default function useDraw(drawConfig: DrawConfig) {
     return questions;
   }
 
+  // 获取题型的评卷区
   function parseQuestionAreas(questions: QuestionItem[]) {
+    if (!questions.length || !cardData?.length || !markAreaList.length)
+      return [];
+
+    return cardData.length
+      ? parseCardQuestionAreas(questions)
+      : parseMarkAreaQuestionAreas(questions);
+  }
+
+  // 获取设置的评卷获取试题评卷区
+  function parseMarkAreaQuestionAreas(questions: QuestionItem[]) {
+    if (!questions.length || !markAreaList?.length) return [];
+
+    const pictureConfigs: QuestionArea[] = [];
+    const structs = questions.map(
+      (item) => `${item.mainNumber}_${item.subNumber}`
+    );
+
+    markAreaList.forEach((markArea) => {
+      const qStruct = `${markArea.mainNumber}_${markArea.subNumber}`;
+      if (!structs.includes(qStruct)) return;
+
+      (markArea.splitConfig || []).forEach((area) => {
+        pictureConfigs.push({
+          i: area.i,
+          x: area.x,
+          y: area.y,
+          w: area.w,
+          h: area.h,
+          qStruct,
+        });
+      });
+    });
+
+    // 合并相邻区域
+    const combinePictureConfigList = combinePictureConfig(pictureConfigs);
+    // console.log(combinePictureConfigList);
+    return combinePictureConfigList;
+  }
+
+  // 通过题卡获取试题评卷区
+  function parseCardQuestionAreas(questions: QuestionItem[]) {
     if (!questions.length || !cardData?.length) return [];
 
     const pictureConfigs: QuestionArea[] = [];
@@ -842,6 +901,12 @@ export default function useDraw(drawConfig: DrawConfig) {
     // console.log(pictureConfigs);
 
     // 合并相邻区域
+    const combinePictureConfigList = combinePictureConfig(pictureConfigs);
+    // console.log(combinePictureConfigList);
+    return combinePictureConfigList;
+  }
+
+  function combinePictureConfig(pictureConfigs: QuestionArea[]) {
     pictureConfigs.sort((a, b) => {
       return a.i - b.i || a.x - b.x || a.y - b.y;
     });
@@ -1069,6 +1134,43 @@ export default function useDraw(drawConfig: DrawConfig) {
         });
       });
     });
+    return dataList;
+  }
+
+  function parseCommonMarkQuestionAreaScore(
+    images: ImageItem[]
+  ): Array<DrawTrackItem[]> {
+    if (!markAreaList.length) return [];
+
+    const dataList: DrawTrackItem[][] = [];
+    const questionScore: Record<string, string> = {};
+    (rawTask.questionList || []).forEach((q) => {
+      questionScore[`${q.mainNumber}_${q.subNumber}`] = String(q.score || '');
+    });
+
+    markAreaList.forEach((markArea) => {
+      const qStruct = `${markArea.mainNumber}_${markArea.subNumber}`;
+      const area = markArea.splitConfig && markArea.splitConfig[0];
+      if (!area) return;
+
+      const imgIndex = area.i - 1;
+      const img = images[imgIndex];
+      area.x *= img.width;
+      area.y *= img.height;
+
+      if (!dataList[imgIndex]) dataList[imgIndex] = [];
+
+      dataList[imgIndex].push({
+        type: 'text',
+        option: {
+          x: area.x,
+          y: area.y,
+          text: questionScore[qStruct] || '',
+          color: 'red',
+          fontSize: trackInfoFontSize * 3,
+        },
+      });
+    });
 
     return dataList;
   }