Sfoglia il codice sorgente

feat: 填空题合并处理

zhangjie 1 anno fa
parent
commit
5909afbb1b

+ 2 - 2
src/api/task.ts

@@ -55,13 +55,13 @@ export function paperNumberQuery(
 export async function trackExportListPage(
   params: TrackExportListParams
 ): Promise<TrackExportListPageRes> {
-  return axios.post('/api/admin/mark/setting/scoreList', {}, { params });
+  return axios.post('/api/admin/mark/archive/score/list', {}, { params });
 }
 // 导出科目学生明细查询列表
 export async function trackExportDetailListPage(
   params: TrackExportDetailListParams
 ): Promise<TrackExportDetailListPageRes> {
-  return axios.post('/api/admin/mark/student/score', {}, { params });
+  return axios.post('/api/admin/mark/archive/student/list', {}, { params });
 }
 
 /** 查看单个学生的试卷轨迹 */

+ 5 - 5
src/api/types/task.ts

@@ -29,6 +29,7 @@ export interface CardData {
   content: string;
 }
 
+// task --------->
 interface SplitConfig {
   /** index of sheets */
   i: number;
@@ -69,7 +70,7 @@ export interface Track {
   isByMultMark?: boolean;
 }
 
-interface Question {
+export interface Question {
   /** 分组序号 */
   groupNumber: number;
   /** 大题号 */
@@ -174,11 +175,13 @@ export type StudentObjectiveInfo = {
   success: boolean;
 };
 
+// card --------->
+
+// page --------->
 export interface TrackExportListFilter {
   semesterId: string;
   examId: string;
   courseId: string;
-  paperNumber: string;
 }
 export type TrackExportListParams = PageParams<TrackExportListFilter>;
 
@@ -188,14 +191,12 @@ export interface TrackExportItem {
   courseName: string;
   paperNumber: string;
   studentCount: number;
-  uploadCount: number;
 }
 export type TrackExportListPageRes = PageResult<TrackExportItem>;
 
 export interface TrackExportDetailListFilter {
   examId: string;
   paperNumber: string;
-  filter: number;
 }
 
 export type TrackExportDetailListParams =
@@ -205,7 +206,6 @@ export interface TrackExportDetailItem {
   studentId: string;
   courseCode: string;
   courseName: string;
-  paperNumber: string;
   studentName: string;
   studentCode: string;
 }

+ 1 - 8
src/views/base/track-export/index.vue

@@ -24,13 +24,6 @@
         placeholder="请选择"
         @change="courseChange"
       />
-      <SelectPaperNumber
-        v-model="searchModel.paperNumber"
-        :semester-id="searchModel.semesterId"
-        :exam-id="searchModel.examId"
-        :course-id="searchModel.courseId"
-        placeholder="请选择"
-      />
       <a-button type="primary" @click="toPage(1)">查询</a-button>
     </a-space>
   </div>
@@ -114,7 +107,6 @@
     semesterId: '',
     examId: '',
     courseId: '',
-    paperNumber: '',
   });
 
   const columns: TableColumnData[] = [
@@ -229,6 +221,7 @@
     await createTrackTask({
       ...searchModel,
       ...seNames,
+      paperNumber: null,
       schoolId: userStore.curSchoolInfo.id,
       pictureType: appStore.trackConfig.pictureType.join(),
       outputDir: appStore.trackConfig.curOutputDir,

+ 136 - 5
src/views/base/track-export/useDraw.ts

@@ -5,7 +5,7 @@ import {
   studentObjectiveConfirmData,
   getSingleStudentCardData,
 } from '@/api/task';
-import { Task, Track, SpecialTag } from '@/api/types/task';
+import { Task, Track, SpecialTag, Question } from '@/api/types/task';
 import { TrackConfigType } from '@/store/modules/app/types';
 import { PictureTypeEnum } from '@/constants/enumerate';
 import { calcSum, maxNum, strGbLen } from '@/utils/utils';
@@ -21,6 +21,13 @@ interface TrackItemType {
   drawTrackList: DrawTrackItem[];
 }
 
+type ElementType =
+  | 'FILL_QUESTION'
+  | 'FILL_LINE'
+  | 'EXPLAIN'
+  | 'COMPOSITION'
+  | 'TOPIC_HEAD'
+  | 'CARD_HEAD';
 interface CardDataItem {
   exchange: {
     answer_area: Array<{
@@ -29,6 +36,14 @@ interface CardDataItem {
       area: [number, number, number, number];
     }>;
   };
+  columns: Array<{
+    elements: Array<{
+      type: ElementType;
+      topicNo: number;
+      startNumber: number;
+      questionsCount: number;
+    }>;
+  }>;
 }
 
 interface CardContentType {
@@ -50,7 +65,11 @@ interface QuestionArea {
 
 type UserMapType = Record<
   string,
-  { userId: string; userName: string; scores: number[] }
+  {
+    userId: string;
+    userName: string;
+    scores: Array<{ subNumber: string; score: number }>;
+  }
 >;
 
 interface ImageItem {
@@ -419,8 +438,96 @@ export default function useDraw(winId: number) {
   // 解析各试题答题区域以及评分
   function parseMarkDetailList(images: ImageItem[]): Array<DrawTrackItem[]> {
     const dataList: Array<DrawTrackItem[]> = [];
+    const questions = rawTask.questionList || [];
+
+    const fillQues = getFillLines();
+    let fillQuestions = [] as Question[];
+    let otherQuestions = questions;
+    if (Object.keys(fillQues).length) {
+      const fillQNos = Object.values(fillQues).flat();
+      fillQuestions = questions.filter((q) =>
+        fillQNos.includes(`${q.mainNumber}_${q.subNumber}`)
+      );
+      otherQuestions = questions.filter(
+        (q) => !fillQNos.includes(`${q.mainNumber}_${q.subNumber}`)
+      );
+    }
+    // 填空题:合并所有小题为一个区域
+    Object.values(fillQues).forEach((qnos) => {
+      const groupQuestions = fillQuestions.filter((q) =>
+        qnos.includes(`${q.mainNumber}_${q.subNumber}`)
+      );
+      const areas = parseQuestionAreas(groupQuestions);
+      if (!areas.length) return;
+      const area = { ...areas[0] };
+      const imgIndex = area.i - 1;
+      if (!dataList[imgIndex]) {
+        dataList[imgIndex] = [];
+      }
+
+      const img = images[imgIndex] as ImageItem;
+      area.x *= img.width;
+      area.y *= img.height;
+      area.w *= img.width;
+
+      const dataArr = dataList[imgIndex];
+      const userMap: UserMapType = {};
+      const isDoubleMark = !groupQuestions.some((question) => {
+        const userIds = question.trackList.map((track) => track.userId);
+        const uids = new Set(userIds);
+        return uids.size === 1;
+      });
+      groupQuestions.forEach((question) => {
+        question.trackList.forEach((track) => {
+          if (!userMap[track.userId]) {
+            userMap[track.userId] = {
+              userId: track.userId,
+              userName: track.userName,
+              scores: [],
+            };
+          }
+          userMap[track.userId].scores.push({
+            score: track.score,
+            subNumber: track.subNumber,
+          });
+        });
+      });
+
+      Object.values(userMap).forEach((user, index) => {
+        const userScore = user.scores
+          .map((item) => `${item.subNumber}:${item.score}分`)
+          .join(',');
+
+        const zhs = ['一', '二', '三'];
+        const prename = isDoubleMark ? `${zhs[index] || ''}评` : '评卷员';
+        const content = `${prename}:${user.userName},评分:${userScore}`;
+        dataArr.push({
+          type: 'text',
+          option: {
+            x: area.x,
+            y: area.y + index * 20,
+            text: content,
+          },
+        });
+      });
 
-    (rawTask.questionList || []).forEach((question) => {
+      const score = calcSum(groupQuestions.map((item) => item.score || 0));
+      const maxScore = calcSum(groupQuestions.map((item) => item.maxScore));
+      const tCont = `得分:${score},满分:${maxScore}`;
+      const tContLen = strGbLen(tCont) / 2;
+      dataArr.push({
+        type: 'text',
+        option: {
+          x: area.x + area.w - Math.ceil(tContLen * 20),
+          y: area.y,
+          text: tCont,
+          fontSize: 20,
+        },
+      });
+    });
+
+    // 其他试题
+    otherQuestions.forEach((question) => {
       const areas = parseQuestionAreas([question]);
       if (!areas.length) return;
       const area = { ...areas[0] };
@@ -444,11 +551,14 @@ export default function useDraw(winId: number) {
             scores: [],
           };
         }
-        userMap[track.userId].scores.push(track.score);
+        userMap[track.userId].scores.push({
+          score: track.score,
+          subNumber: track.subNumber,
+        });
       });
 
       Object.values(userMap).forEach((user, index) => {
-        const userScore = calcSum(user.scores);
+        const userScore = calcSum(user.scores.map((item) => item.score));
         const content = `评卷员:${user.userName},评分:${userScore}`;
         dataArr.push({
           type: 'text',
@@ -475,6 +585,27 @@ export default function useDraw(winId: number) {
     return dataList;
   }
 
+  // 获取属于填空题的试题号
+  function getFillLines() {
+    const questions: Record<number, string[]> = {};
+    cardData.forEach((page) => {
+      page.columns.forEach((column) => {
+        column.elements.forEach((element) => {
+          if (element.type !== 'FILL_LINE') return;
+
+          if (!questions[element.topicNo]) questions[element.topicNo] = [];
+
+          for (let i = 0; i < element.questionsCount; i++) {
+            questions[element.topicNo].push(
+              `${element.topicNo}_${element.startNumber + i}`
+            );
+          }
+        });
+      });
+    });
+    return questions;
+  }
+
   function parseQuestionAreas(questions: QuestionItem[]) {
     if (!questions.length || !cardData?.length) return [];