123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836 |
- import { ref } from 'vue';
- import {
- getSingleStudentTaskOfStudentTrack,
- studentObjectiveConfirmData,
- getSingleStudentCardData,
- } from '@/api/task';
- import { Task, Track, SpecialTag, Question } 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';
- import { useAppStore } from '@/store';
- import { DrawTrackItem } from '../../../../electron/preload/types';
- import { TrackTaskData } from '../../../../electron/db/models/trackTask';
- import { TrackTaskDetailData } from '../../../../electron/db/models/trackTaskDetail';
- type AnswerMap = Record<string, { answer: string; isRight: boolean }>;
- interface TrackItemType {
- url: string;
- width: number;
- height: number;
- drawTrackList: DrawTrackItem[];
- }
- type ElementType =
- | 'FILL_QUESTION'
- | 'FILL_LINE'
- | 'EXPLAIN'
- | 'COMPOSITION'
- | 'TOPIC_HEAD'
- | 'CARD_HEAD';
- interface CardDataItem {
- exchange: {
- answer_area: Array<{
- main_number: number;
- sub_number: number | string;
- area: [number, number, number, number];
- }>;
- };
- columns: Array<{
- elements: Array<{
- type: ElementType;
- topicNo: number;
- startNumber: number;
- questionsCount: number;
- }>;
- }>;
- }
- interface CardContentType {
- pages: CardDataItem[];
- }
- interface QuestionItem {
- mainNumber: number;
- subNumber: number | string;
- }
- interface QuestionArea {
- i: number;
- x: number;
- y: number;
- w: number;
- h: number;
- qStruct: string;
- }
- type UserMapType = Record<
- string,
- {
- userId: string;
- userName: string;
- color: string;
- scores: Array<{ subNumber: string; score: number }>;
- }
- >;
- interface ImageItem {
- url: string;
- width: number;
- height: number;
- }
- interface PaperRecogData {
- page_index: number;
- question: Array<{
- index: number;
- fill_result: Array<{
- main_number: number;
- sub_number: number;
- single: number;
- fill_option: number[];
- suspect_flag: number;
- fill_position: string[];
- fill_size: number[];
- }>;
- }>;
- }
- export default function useDraw(winId: number) {
- const curWinId = winId;
- let answerMap = {} as AnswerMap;
- let cardData = [] as CardDataItem[];
- let recogDatas: string[] = [];
- let rawTask = {} as Task;
- let trackData = [] as TrackItemType[];
- let originImgs = [] as ImageItem[];
- let isOnlyOrigin = false;
- let hasPdf = false;
- let curStudentId = '';
- const defaultColorConfig = {
- track: ['red', 'blue', 'gray'],
- head: 'green',
- };
- let colorConfig = { track: ['red', 'blue', 'gray'], head: 'green' };
- const task = ref({} as TrackTaskData);
- const taskDetail = ref({} as TrackTaskDetailData);
- const trackConfig = ref({} as TrackConfigType);
- const appStore = useAppStore();
- function updateColorConfig() {
- if (trackConfig.value.trackColorType === 'ALL_RED') {
- colorConfig.head = 'red';
- colorConfig.track = ['red', 'red', 'red'];
- } else {
- colorConfig = deepCopy(defaultColorConfig);
- }
- }
- function addLog(content: string, type?: 'info' | 'error') {
- window.api.logger(`win:${curWinId} ${content}`, type);
- }
- async function getTrackTask(schoolId: string) {
- const res = await window.db.getUnfinishTrackTask(schoolId);
- if (!res) return Promise.reject(new Error('无任务'));
- task.value = res;
- trackConfig.value = JSON.parse(res.trackConfig) as TrackConfigType;
- isOnlyOrigin = checkOnlyOrigin();
- hasPdf = trackConfig.value.pictureType.includes('pdf');
- updateColorConfig();
- return res.id;
- }
- async function getTrackTaskDetail() {
- const res = await window.db.getUnfinishTrackTaskDetail(task.value.id);
- if (!res) return null;
- taskDetail.value = res;
- return taskDetail.value;
- }
- async function runTask() {
- initData();
- curStudentId = taskDetail.value.studentId;
- addLog(`[${curStudentId}] 01-开始任务`);
- try {
- await getTaskData(curStudentId);
- addLog(`[${curStudentId}] 02-获取任务数据成功`);
- originImgs = await downloadImages(rawTask.sheetUrls);
- if (isOnlyOrigin) {
- return true;
- }
- await parseDrawList();
- addLog(`[${curStudentId}] 03-解析绘制数据成功`);
- const trackFiles = await drawTask();
- addLog(`[${curStudentId}] 04-绘制成功`);
- if (hasPdf) {
- await window.api.imagesToPdf(trackFiles, getOutputPath('pdf'));
- addLog(`[${curStudentId}] 05-生成pdf成功`);
- }
- } catch (error) {
- const e = error as Error;
- console.log(e);
- addLog(
- `[${curStudentId}-${rawTask.studentCode}] 08-任务失败,原因:${
- e.message || '未知'
- }`,
- 'error'
- );
- return Promise.reject(error);
- }
- return true;
- }
- function initData() {
- cardData = [] as CardDataItem[];
- recogDatas = [] as string[];
- rawTask = {} as Task;
- trackData = [] as TrackItemType[];
- answerMap = {} as AnswerMap;
- originImgs = [] as ImageItem[];
- curStudentId = '';
- }
- function checkOnlyOrigin() {
- return (
- trackConfig.value.pictureType.length === 1 &&
- trackConfig.value.pictureType[0] === 'origin'
- );
- }
- async function getTaskData(studentId: string) {
- rawTask = await getSingleStudentTaskOfStudentTrack(studentId);
- if (!rawTask) return;
- if (!rawTask.sheetUrls) rawTask.sheetUrls = [];
- if (isOnlyOrigin) return;
- // 获取客观题选项信息
- const objectiveData = await studentObjectiveConfirmData(studentId);
- objectiveData.answers.forEach((item) => {
- answerMap[`${item.mainNumber}_${item.subNumber}`] = {
- answer: item.answer,
- isRight: item.answer === item.standardAnswer,
- };
- });
- recogDatas = objectiveData.sheetUrls.map((item) => item.recogData);
- // 获取题卡数据
- const cardRes = await getSingleStudentCardData(studentId);
- const cardContent =
- cardRes && cardRes.content
- ? (JSON.parse(cardRes.content) as CardContentType)
- : { pages: [] };
- cardData = cardContent.pages;
- }
- /**
- * 获取文件存储路径,规则:学期/考试/课程/试卷编号/教学班/下载文件类型/学生图片
- */
- function getOutputPath(type: PictureTypeEnum, index?: number) {
- const transfromStr = (str: string) => str.replace(/[*|:?<>]/g, '');
- let filename =
- trackConfig.value.studentFileRule === 'CODE_NAME'
- ? `${rawTask.studentCode}-${rawTask.studentName}`
- : rawTask.studentCode;
- filename = transfromStr(filename);
- if (index !== undefined) {
- filename += `-${index}`;
- }
- filename += type === 'pdf' ? '.pdf' : '.jpg';
- const paths = [
- trackConfig.value.curOutputDir,
- transfromStr(task.value.semesterName),
- transfromStr(task.value.examName),
- transfromStr(`${rawTask.courseName}(${rawTask.courseCode})`),
- transfromStr(rawTask.paperNumber),
- transfromStr(taskDetail.value.className),
- PICTURE_TYPE[type],
- filename,
- ];
- return window.api.joinPath(paths);
- }
- async function downloadImages(urls: string[]) {
- const downloads: Promise<ImageItem>[] = [];
- for (let i = 0; i < urls.length; i++) {
- let url = urls[i];
- if (!url.startsWith('http://') && !url.startsWith('https://')) {
- url = `${appStore.domain}/${url}`;
- }
- downloads.push(
- window.api.downloadImage(url, getOutputPath('origin', i + 1))
- );
- }
- const images = await Promise.all(downloads).catch((error: Error) => {
- console.log(error);
- addLog(`下载图片错误:${error.toString()}`, 'error');
- });
- if (!images) {
- return Promise.reject(new Error('下载图片失败'));
- }
- return images;
- }
- async function parseDrawList() {
- trackData = [];
- const trackLists = (rawTask.questionList || [])
- .map((q) => {
- return q.headerTrack?.length
- ? addHeaderTrackColorAttr(q.headerTrack)
- : addTrackColorAttr(q.trackList);
- })
- .flat();
- const markDeailList = parseMarkDetailList(originImgs);
- for (let i = 0; i < originImgs.length; i++) {
- const img = originImgs[i];
- const drawTrackList = [] as DrawTrackItem[];
- trackLists
- .filter((item) => item.offsetIndex === i + 1)
- .forEach((item) => {
- drawTrackList.push(getDrawTrackItem(item));
- });
- (rawTask.specialTagList || [])
- .filter((item) => item.offsetIndex === i + 1)
- .forEach((item) => {
- drawTrackList.push(getDrawTagTrackItem(item));
- });
- const answerTags = paserRecogData(i);
- drawTrackList.push(...answerTags);
- drawTrackList.push(...(markDeailList[i] || []));
- drawTrackList.push(getTotalTrack(img));
- trackData[i] = {
- url: img.url,
- width: img.width,
- height: img.height,
- drawTrackList,
- };
- }
- }
- async function drawTask(): Promise<ImageItem[]> {
- if (!trackData.length) return [];
- const draw = async (item: TrackItemType, index: number) => {
- const outpath = getOutputPath('track', index);
- const url = await window.api.drawTrack(
- item.url,
- item.drawTrackList,
- outpath
- );
- return { url, width: item.width, height: item.height };
- };
- const tasks = trackData.map((item, index) => draw(item, index + 1));
- const res = await Promise.all(tasks).catch((error: Error) => {
- console.log(error);
- addLog(`绘制轨迹错误:${error.toString()}`, 'error');
- });
- if (!res) {
- return Promise.reject(new Error('绘制轨迹失败'));
- }
- return res;
- }
- // track ----- start->
- const trackTextFontSize = 30;
- const trackInfoFontSize = 20;
- const trackInfoLineHeight = 20 * 1.2;
- function getDrawTrackItem(track: Track): DrawTrackItem {
- return {
- type: 'text',
- option: {
- x: track.offsetX,
- y: track.offsetY - trackTextFontSize / 2,
- text: String(track.score),
- color: track.color,
- fontSize: trackTextFontSize,
- },
- };
- }
- function getDrawTagTrackItem(track: SpecialTag): DrawTrackItem {
- if (track.tagType === 'LINE') {
- const tagProp = JSON.parse(track.tagName) as {
- len: number;
- };
- return {
- type: 'line',
- option: {
- x0: track.offsetX,
- y0: track.offsetY,
- x1: track.offsetX + tagProp.len,
- y1: track.offsetY,
- },
- };
- }
- if (track.tagType === 'CIRCLE') {
- const tagProp = JSON.parse(track.tagName) as {
- width: number;
- height: number;
- };
- return {
- type: 'circle',
- option: {
- x0: track.offsetX,
- y0: track.offsetY,
- x1: track.offsetX + tagProp.width,
- y1: track.offsetY + tagProp.height,
- },
- };
- }
- return {
- type: 'text',
- option: {
- x: track.offsetX,
- y: track.offsetY - trackTextFontSize / 2,
- text: track.tagName,
- color: track.color,
- fontSize: trackTextFontSize,
- },
- };
- }
- function addHeaderTrackColorAttr(headerTrack: Track[]): Track[] {
- return headerTrack.map((item) => {
- item.color = colorConfig.head;
- return item;
- });
- }
- function addTrackColorAttr(tList: Track[]): Track[] {
- let markerIds: string[] = tList.map((v) => v.userId).filter((x) => !!x);
- markerIds = Array.from(new Set(markerIds));
- // markerIds.sort();
- const colorMap: Record<string, string> = {};
- for (let i = 0; i < markerIds.length; i++) {
- const mId = markerIds[i];
- if (i === 0) {
- colorMap[mId] = colorConfig.track[0];
- } else if (i === 1) {
- colorMap[mId] = colorConfig.track[1];
- } else if (i > 1) {
- colorMap[mId] = colorConfig.track[2];
- }
- }
- type ColorK = keyof typeof colorMap;
- tList = tList.map((item: Track) => {
- const k = item.userId as ColorK;
- item.color = colorMap[k] || 'red';
- item.isByMultMark = markerIds.length > 1;
- return item;
- });
- return tList;
- }
- /*
- function addTagColorAttr(tList: SpecialTag[]): SpecialTag[] {
- let markerIds: string[] = tList
- .map((v) => String(v.userId))
- .filter((x) => !!x);
- markerIds = Array.from(new Set(markerIds));
- // markerIds.sort();
- const colorMap: Record<string, string> = {};
- for (let i = 0; i < markerIds.length; i++) {
- const mId = markerIds[i];
- if (i === 0) {
- colorMap[mId] = 'red';
- } else if (i === 1) {
- colorMap[mId] = 'blue';
- } else if (i > 1) {
- colorMap[mId] = 'gray';
- }
- }
- type ColorK = keyof typeof colorMap;
- tList = tList.map((item: SpecialTag) => {
- const k = String(item.userId) as ColorK;
- item.color = colorMap[k] || 'red';
- item.isByMultMark = markerIds.length > 1;
- return item;
- });
- return tList;
- }
- */
- // track ----- end->
- // mark detail ----- start->
- // 解析各试题答题区域以及评分
- 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,
- color: track.color || '',
- scores: [],
- };
- }
- const existUserScore = userMap[track.userId].scores.find(
- (s) => s.subNumber === track.subNumber
- );
- if (existUserScore) {
- existUserScore.score += track.score;
- } else {
- userMap[track.userId].scores.push({
- score: track.score,
- subNumber: track.subNumber,
- });
- }
- });
- });
- // 填空题的打分需要自动换行,目前一行只展示最多7个评分
- let offsetY = -1 * trackInfoLineHeight;
- Object.values(userMap).forEach((user, index) => {
- const zhs = ['一', '二', '三'];
- const prename = isDoubleMark ? `${zhs[index] || ''}评` : '评卷员';
- const userScore = user.scores.map(
- (item) => `${item.subNumber}:${item.score}分`
- );
- const lineScoreCount = 10;
- const groupCount = Math.ceil(userScore.length / lineScoreCount);
- const groups: string[] = [];
- for (let i = 0; i < groupCount; i++) {
- groups.push(
- userScore
- .slice(i * lineScoreCount, (i + 1) * lineScoreCount)
- .join(',')
- );
- }
- offsetY += trackInfoLineHeight;
- dataArr.push({
- type: 'text',
- option: {
- x: area.x,
- y: area.y + offsetY,
- text: `${prename}:${user.userName},评分:`,
- fontSize: trackInfoFontSize,
- color: user.color,
- },
- });
- groups.forEach((group) => {
- offsetY += 20;
- dataArr.push({
- type: 'text',
- option: {
- x: area.x,
- y: area.y + offsetY,
- text: group,
- fontSize: trackInfoFontSize,
- color: user.color,
- },
- });
- });
- });
- 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 * 30),
- y: area.y,
- text: tCont,
- fontSize: 30,
- },
- });
- });
- // 其他试题
- otherQuestions.forEach((question) => {
- const areas = parseQuestionAreas([question]);
- 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 isArbitration = Boolean(question.headerTrack?.length);
- const tList = isArbitration
- ? (question.headerTrack as Track[])
- : question.trackList;
- tList.forEach((track) => {
- if (!userMap[track.userId]) {
- userMap[track.userId] = {
- userId: track.userId,
- userName: track.userName,
- color: track.color || '',
- scores: [],
- };
- }
- userMap[track.userId].scores.push({
- score: track.score,
- subNumber: track.subNumber,
- });
- });
- const isDoubleMark = Object.values(userMap).length > 1;
- Object.values(userMap).forEach((user, index) => {
- const zhs = ['一', '二', '三'];
- let prename = '';
- if (isArbitration) {
- prename = '仲裁';
- } else {
- prename = isDoubleMark ? `${zhs[index] || ''}评` : '评卷员';
- }
- const userScore = calcSum(user.scores.map((item) => item.score));
- const content = `${prename}:${user.userName},评分:${userScore}`;
- dataArr.push({
- type: 'text',
- option: {
- x: area.x,
- y: area.y + index * trackInfoLineHeight,
- text: content,
- fontSize: trackInfoFontSize,
- color: user.color,
- },
- });
- });
- const tCont = `得分:${question.score},满分:${question.maxScore}`;
- const tContLen = strGbLen(tCont) / 2;
- dataArr.push({
- type: 'text',
- option: {
- x: area.x + area.w - Math.ceil(tContLen * 30),
- y: area.y,
- text: tCont,
- fontSize: 30,
- },
- });
- });
- return dataList;
- }
- function getTotalTrack(image: ImageItem): DrawTrackItem {
- const totalScore = rawTask.markerScore || 0;
- const objectiveScore = rawTask.objectiveScore || 0;
- const subjectiveScore = totalScore - objectiveScore;
- return {
- type: 'text',
- option: {
- x: 0.15 * image.width,
- y: 0.01 * image.height,
- text: `总分:${totalScore},主观题得分:${subjectiveScore},客观题得分:${objectiveScore}`,
- fontSize: 40,
- },
- };
- }
- // 获取属于填空题的试题号
- 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 [];
- const pictureConfigs: QuestionArea[] = [];
- const structs = questions.map(
- (item) => `${item.mainNumber}_${item.subNumber}`
- );
- cardData.forEach((page, pindex) => {
- page.exchange.answer_area.forEach((area) => {
- const [x, y, w, h] = area.area;
- const qStruct = `${area.main_number}_${area.sub_number}`;
- const pConfig: QuestionArea = {
- i: pindex + 1,
- x,
- y,
- w,
- h,
- qStruct,
- };
- if (typeof area.sub_number === 'number') {
- if (!structs.includes(qStruct)) return;
- pictureConfigs.push(pConfig);
- return;
- }
- // 复合区域处理,比如填空题,多个小题合并为一个区域
- if (typeof area.sub_number === 'string') {
- const areaStructs = area.sub_number
- .split(',')
- .map((subNumber) => `${area.main_number}_${subNumber}`);
- if (
- structs.some((struct) => areaStructs.includes(struct)) &&
- !pictureConfigs.find((item) => item.qStruct === qStruct)
- ) {
- pictureConfigs.push(pConfig);
- }
- }
- });
- });
- // console.log(pictureConfigs);
- // 合并相邻区域
- pictureConfigs.sort((a, b) => {
- return a.i - b.i || a.x - b.x || a.y - b.y;
- });
- const combinePictureConfigList: QuestionArea[] = [];
- let prevConfig = {} as QuestionArea;
- pictureConfigs.forEach((item, index) => {
- if (!index) {
- prevConfig = { ...item };
- combinePictureConfigList.push(prevConfig);
- return;
- }
- const elasticRate = 0.01;
- if (
- prevConfig.i === item.i &&
- prevConfig.y + prevConfig.h + elasticRate >= item.y &&
- prevConfig.w === item.w &&
- prevConfig.x === item.x
- ) {
- prevConfig.h = item.y + item.h - prevConfig.y;
- } else {
- prevConfig = { ...item };
- combinePictureConfigList.push(prevConfig);
- }
- });
- // console.log(combinePictureConfigList);
- return combinePictureConfigList;
- }
- // mark detail ----- end->
- // answer tag ----- start->
- // 解析客观题答案展示位置
- function paserRecogData(imageIndex: number): DrawTrackItem[] {
- if (!recogDatas.length || !recogDatas[imageIndex]) return [];
- const recogData: PaperRecogData = JSON.parse(
- window.atob(recogDatas[imageIndex])
- );
- const answerTags: DrawTrackItem[] = [];
- recogData.question.forEach((question) => {
- question.fill_result.forEach((result) => {
- const fillPositions = result.fill_position.map((pos) => {
- return pos.split(',').map((n) => Number(n));
- });
- const offsetLt = result.fill_size.map((item) => item * 0.4);
- const tagLeft =
- maxNum(fillPositions.map((pos) => pos[0])) +
- result.fill_size[0] -
- offsetLt[0];
- const tagTop = fillPositions[0][1] - offsetLt[1];
- const { answer, isRight } =
- answerMap[`${result.main_number}_${result.sub_number}`] || {};
- answerTags.push({
- type: 'text',
- option: {
- x: tagLeft,
- y: tagTop,
- text: answer || '',
- color: isRight ? '#05b575' : '#f53f3f',
- },
- });
- });
- });
- return answerTags;
- }
- // answer tag ----- end->
- return {
- runTask,
- getTrackTask,
- getTrackTaskDetail,
- addLog,
- };
- }
|