<template> <el-dialog class="card-build-dialog opacity-dialog" :visible.sync="modalIsShow" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false" append-to-body fullscreen @opened="initData" > <div slot="title"></div> <div slot="footer"></div> <div class="loading-tips" v-loading="loading" element-loading-text="生成题卡中" ></div> <div v-if="modalIsShow" id="card-build" class="card-build card-preview card-print" > <card-view v-if="pages.length" ref="CardView" class="preview-body" :pages="pages" :card-config="cardConfig" ></card-view> <!-- all topics --> <div v-else class="topic-list"> <div :class="['page-box', `page-box-${cardConfig.pageSize}`]"> <div class="page-main-inner"> <div :class="['page-main', `page-main-${cardConfig.columnNumber}`]" :style="{ margin: `0 -${cardConfig.columnGap / 2}px` }" > <div class="page-column" :style="{ padding: `0 ${cardConfig.columnGap / 2}px` }" > <div class="page-column-main" id="topic-column"> <div class="page-column-body"> <!-- card-head-sample --> <card-head-sample :data="cardHeadSampleData" id="simple-card-head" v-if="topics.length && cardHeadSampleData" ></card-head-sample> <!-- topic element --> <topic-element-preview class="page-column-element" v-for="element in topics" :key="element.id" :data="element" ></topic-element-preview> </div> </div> </div> </div> </div> </div> </div> </div> </el-dialog> </template> <script> import json5 from "json5"; import { mapState, mapMutations, mapActions } from "vuex"; import { saveCard, cardConfigInfos } from "../api"; import { tikuPaperDetail } from "../../exam/api"; import { getPaperJsonSimpleStructInfo } from "../autoBuild/paperStruct"; import { buildCardFromPaperSimpleStruct } from "../autoBuild/simplePaperCard"; // card components import { getCardHeadModel } from "../../../../card/elementModel"; import TopicElementPreview from "../../../../card/components/TopicElementPreview"; import CardView from "../../../../card/components/CardView.vue"; import CardHeadSample from "../../../../card/elements/card-head/CardHead"; import { deepCopy, objTypeOf } from "@/plugins/utils"; // ceshi // import paperData from "./paper.json"; export default { name: "CardBuild", components: { CardView, TopicElementPreview, CardHeadSample }, props: { presetData: { type: Object, default() { return { paperId: "", }; }, }, }, data() { return { cardId: "", loading: false, modalIsShow: false, paperInfo: {}, answers: {}, cachePages: [], sysCardSize: "", }; }, computed: { ...mapState("card", ["cardConfig", "topics", "pages"]), cardHeadSampleData() { if (!this.cardConfig["pageSize"]) return; const data = getCardHeadModel(this.cardConfig); data.isSimple = true; return data; }, }, methods: { ...mapMutations("card", [ "setCardConfig", "setTopics", "setPages", "initState", ]), ...mapActions("card", ["resetTopicSeries", "rebuildPages"]), async initData() { this.loading = true; this.sysCardSize = this.$ls.get("schoolInfo", { cardSize: this.sysCardSize, }).cardSize; this.initState(); // 题卡规则 const cardConfig = await this.getCardConfig( this.presetData.cardRuleId ).catch(() => {}); if (!cardConfig) { this.emitResult({ success: false, message: "题卡规则获取失败" }); return; } this.setCardConfig(cardConfig); // 试卷信息 const res = await tikuPaperDetail({ examId: this.presetData.examId, paperId: this.presetData.paperId, uuid: this.presetData.uuid, }).catch(() => {}); if (!res) { this.emitResult({ success: false, message: "试卷内容获取失败" }); return; } // const res = paperData; // 构建题卡 try { this.paperInfo = { uuid: this.presetData.uuid, attachmentId: res.attachmentId, paperUrl: res.paperUrl, }; const answerJson = res.answerJson ? json5.parse(res.answerJson) : { details: [] }; const paperJson = res.paperJson ? json5.parse(res.paperJson) : { details: [] }; this.rebuildPaperQuestionNumber(answerJson); this.rebuildPaperQuestionNumber(paperJson); this.parsePaperAnswers(paperJson, answerJson); const paperSimpleStruct = getPaperJsonSimpleStructInfo(paperJson); const elementTypePreSetInfo = { FILL_QUESTION: { pageSize: this.sysCardSize, columnNumber: 2, }, }; const elements = buildCardFromPaperSimpleStruct( paperSimpleStruct, elementTypePreSetInfo ); this.setTopics([getCardHeadModel(this.cardConfig), ...elements]); this.resetTopicSeries(); } catch (error) { console.dir(error); this.emitResult({ success: false, message: error.message || "数据构建错误", }); return; } this.$nextTick(() => { this.rebuildPages(); this.cachePages = deepCopy(this.pages); console.log(this.cachePages); this.updatePageField(); this.$nextTick(() => { this.buildData(); }); }); }, rebuildPaperQuestionNumber(paperJson) { // 如果一个大题有多个套题,那么套题的小题需要将强制转成为小题号连续 paperJson.details.forEach((detail) => { let qno = 1; detail.questions.forEach((question) => { if (question.subQuestions && question.subQuestions.length) { question.subQuestions.forEach((subq) => { subq.number = qno++; }); } else { question.number = qno++; } }); }); }, getObjectiveQuestionAnswer(answer) { if (objTypeOf(answer) === "boolean") { return answer ? "A" : "B"; } if (objTypeOf(answer) === "array") { const abc = "abcdefghijklmnopqrstuvwxyz".toUpperCase(); return answer.map((item) => abc[item - 1]).join(); } }, parsePaperAnswers(paperJson, answerJson) { const infos = {}; const objectiveQuestionTypes = [1, 2, 3]; paperJson.details.forEach((detail) => { detail.questions.forEach((question) => { if (question.subQuestions && question.subQuestions.length) { question.subQuestions.forEach((subq) => { const qno = `${detail.number}-${subq.number}`; if (!infos[qno]) { infos[qno] = { answer: null, score: null, objective: false, }; } infos[qno].score = subq.score; infos[qno].objective = objectiveQuestionTypes.includes( subq.structType ); }); } else { const qno = `${detail.number}-${question.number}`; if (!infos[qno]) { infos[qno] = { answer: null, score: null, objective: false }; } infos[qno].score = question.score; infos[qno].objective = objectiveQuestionTypes.includes( question.structType ); } }); }); answerJson.details.forEach((detail) => { detail.questions.forEach((question) => { if (question.subQuestions && question.subQuestions.length) { question.subQuestions.forEach((subq) => { const qno = `${detail.number}-${subq.number}`; if (infos[qno].objective) { infos[qno].answer = this.getObjectiveQuestionAnswer( subq.answer ); } }); } else { const qno = `${detail.number}-${question.number}`; if (infos[qno].objective) { infos[qno].answer = this.getObjectiveQuestionAnswer( question.answer ); } } }); }); this.answers = infos; }, async getCardConfig(cardRuleId) { const data = await cardConfigInfos(cardRuleId); if (!data) { this.$message.error("找不到题卡规则!"); return Promise.reject(); } let config = { ...data, ...{ pageSize: this.sysCardSize, columnNumber: 2, columnGap: 20, showForbidArea: false, makeMethod: "SELF", courseCodeBarcodeSrc: "${courseCodeBarcodeSrc}", courseCodeBarcodeName: "${courseCodeBarcodeName}", }, }; config.fillNumber = data.examNumberDigit; config.aOrB = false; config.requiredFields = JSON.parse(config.requiredFields); config.extendFields = JSON.parse(config.extendFields); config.cardTitle = this.getCardTitle(config.titleRule); return config; }, getCardTitle(titleRule) { const fieldMap = { courseCode: this.presetData.courseCode, courseName: this.presetData.courseName, schoolName: this.presetData.schoolName, }; Object.entries(fieldMap).forEach(([key, val]) => { titleRule = titleRule.replace("${" + key + "}", val); }); return titleRule; }, updatePageField() { const config = this.cardConfig; // 变量 let fieldInfos = {}; [...config.requiredFields, ...config.extendFields] .filter((item) => item.enable) .map((item) => { fieldInfos[item.code] = "${" + item.code + "}"; }); const isPrintExamNumber = config.examNumberStyle === "PRINT"; if (isPrintExamNumber) { fieldInfos.examNumber = "data:image/png;base64,${examNumber}"; fieldInfos.examNumberStr = "${examNumberStr}"; } if (config.aOrB && config.paperType === "PRINT") { fieldInfos.paperType = "data:image/png;base64,${paperType}"; fieldInfos.paperTypeName = "${paperTypeName}"; } const pages = this.pages.map((page, pageNo) => { if (pageNo % 2) return page; const cardHeadElement = page.columns[0].elements[0]; if (cardHeadElement.type === "CARD_HEAD") { cardHeadElement.fieldInfos = fieldInfos; } return page; }); this.setPages(pages); }, async buildData() { const model = this.$refs.CardView.getPageModel({ cardConfig: this.cardConfig, pages: this.cachePages, answers: this.answers, }); const htmlContent = this.$refs.CardView.getPreviewTemp( document.getElementById("card-build").outerHTML ); const datas = { content: model, htmlContent, title: this.presetData.paperName, status: "SUBMIT", ...this.presetData, }; const result = await saveCard(datas).catch((error) => { this.emitResult({ success: false, message: error.message || "保存题卡错误", }); }); if (!result) return; this.emitResult({ success: true, data: { ...result, ...this.paperInfo }, }); }, emitResult(data) { // console.log(data); this.initState(); this.loading = false; this.$emit("confirm", data); this.cancel(); }, cancel() { this.modalIsShow = false; }, open() { this.modalIsShow = true; }, }, }; </script>