123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- <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: [],
- };
- },
- 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.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,
- };
- 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: "A3",
- 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: "A3",
- columnNumber: 2,
- columnGap: 20,
- showForbidArea: false,
- makeMethod: "SELF",
- },
- };
- 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>
|