import { CARD_VERSION } from "../enumerate"; import { deepCopy } from "../plugins/utils"; const initIndex = { question: 1, absent: 1, paperType: 1, examNumber: 1, selective: 1, pageNumber: 1 }; /** * 格式文档:https://doc.qmth.com.cn/pages/viewpage.action?pageId=19661052 */ export default { data() { return { fillAreaIndex: { ...initIndex }, VALID_ELEMENTS_FOR_EXTERNAL: [ "LOCATOR", "BARCODE", "CARD_HEAD", "FILL_QUESTION", "FILL_LINE", "EXPLAIN", "COMPOSITION" ] }; }, methods: { getFillAreaIndex(type) { return this.fillAreaIndex[type]++; }, getElementHumpName(cont) { return cont .split("_") .map(item => item[0] + item.substr(1).toLowerCase()) .join(""); }, getPreviewElementById(id) { return document.getElementById(`preview-${id}`); }, parsePageExchange(pages) { const npages = deepCopy(pages); // 单页题卡不显示页码涂块 const pageNumberInfo = pages.length <= 2 ? null : this.getPageNumberInfo(); npages.forEach((page, pindex) => { let exchange = { card_type: 2, page_size: page.pageSize, page_image: "", locator: this.getLocatorInfo(page.locators), fill_locator: [], check_area: { black_line: [], white_line: [] }, barcode: [], qrcode: [], ocr_area: [], info_area: [], fill_area: [], answer_area: [], extension: { barcode: [], fill_area: [], ocr_area: [], qrcode: [] } }; const elements = [ page.globals, ...page.columns.map(column => column.elements) ]; elements.forEach(elemGroup => { elemGroup.forEach(element => { if (this.VALID_ELEMENTS_FOR_EXTERNAL.includes(element.type)) { const funcName = this.getElementHumpName(element.type); // console.log(funcName); const info = this[`get${funcName}Info`](element); Object.entries(info).forEach(([key, vals]) => { exchange[key] = exchange[key].concat(vals); }); } }); }); if (!(pindex % 2) && pageNumberInfo) { let pnoInfo = deepCopy(pageNumberInfo); pnoInfo[0].index = this.getFillAreaIndex("pageNumber"); exchange.fill_area = exchange.fill_area.concat(pnoInfo); } page.exchange = exchange; }); this.fillAreaIndex = { ...initIndex }; return npages; }, getPageNumberInfo() { const dom = document.querySelector(".page-box-0"); let options = []; dom .querySelector(".page-number-rect-list") .childNodes.forEach((item, index) => { console.log(item); options[index] = this.getOffsetInfo(item); }); return [ { field: "pageNumber", index: 1, single: true, horizontal: true, items: [ { main_number: null, sub_number: null, options, recog_info: [] } ] } ]; }, getLocatorInfo(locators) { const tops = locators.top.map(locator => { return this.getOffsetInfo(document.getElementById(locator.id)); }); const bottoms = locators.bottom.map(locator => { return this.getOffsetInfo(document.getElementById(locator.id)); }); return { top: tops, bottom: bottoms }; }, getCardHeadInfo(element) { const dom = this.getPreviewElementById(element.id); const headArea = this.getOffsetInfo(dom); let fill_area = []; let barcode = []; // 学生考号 if (element.examNumberStyle === "FILL") { // fill_area let listInfos = []; dom .querySelectorAll(".stdno-fill-list") .forEach((questionItem, questionIndex) => { let options = []; questionItem.childNodes.forEach((optionItem, optionIndex) => { options[optionIndex] = this.getOffsetInfo(optionItem); }); listInfos[questionIndex] = { main_number: null, sub_number: null, options, recog_info: [] }; }); fill_area.push({ field: "examNumber", index: this.getFillAreaIndex("examNumber"), single: true, horizontal: false, items: listInfos }); } else { // barcode const stdnoDom = element.columnNumber <= 2 ? dom.querySelector(".head-stdno").parentNode : dom.querySelector(".head-stdno"); barcode.push({ field: "examNumber", area: this.getOffsetInfo(stdnoDom) }); } // 缺考涂填 if (element.examAbsent && !element.isSimple) { fill_area.push({ field: "absent", index: this.getFillAreaIndex("absent"), single: true, horizontal: true, items: [ { main_number: null, sub_number: null, options: [ this.getOffsetInfo(document.getElementById("dynamic-miss-area")) ], recog_info: [] } ] }); } // A/B卷类型 if (element.aOrB && !element.isSimple) { if (element.paperType === "PRINT") { // barcode barcode.push({ field: "paperType", area: this.getOffsetInfo( document.getElementById("dynamic-aorb-barcode") ) }); } else { // fill_area let options = []; document .getElementById("head-dynamic-aorb") .querySelectorAll(".head-dynamic-rect") .forEach((optionItem, optionIndex) => { options[optionIndex] = this.getOffsetInfo(optionItem); }); fill_area.push({ field: "paperType", index: this.getFillAreaIndex("paperType"), single: true, horizontal: true, items: [ { main_number: null, sub_number: null, options, recog_info: [] } ] }); } } return { info_area: [headArea], fill_area, barcode }; }, getFillQuestionInfo(element) { const dom = this.getPreviewElementById(element.id); const single = !element.isMultiply; const horizontal = element.optionDirection === "horizontal"; let fillAreas = []; dom.querySelectorAll(".group-item").forEach(groupItem => { let listInfos = []; groupItem .querySelectorAll(".question-item") .forEach((questionItem, questionIndex) => { let options = []; questionItem.childNodes.forEach((optionItem, optionIndex) => { if (optionIndex) options[optionIndex - 1] = this.getOffsetInfo(optionItem); }); listInfos[questionIndex] = { main_number: element.topicNo, sub_number: questionItem.firstChild.textContent * 1, options, recog_info: [] }; }); fillAreas.push({ field: "question", index: this.getFillAreaIndex("question"), single, horizontal, items: listInfos }); }); return { fill_area: fillAreas }; }, getFillLineInfo(element) { const dom = this.getPreviewElementById(element.id); let sub_numbers = []; for ( let i = element.startNumber, len = element.startNumber + element.questionsCount; i < len; i++ ) { sub_numbers.push(i); } return { answer_area: [ { main_number: element.topicNo, sub_number: sub_numbers.join(), area: this.getOffsetInfo(dom) } ] }; }, getExplainInfo(element) { const dom = this.getPreviewElementById(element.id); return { answer_area: [ { main_number: element.topicNo, sub_number: element.serialNumber, area: this.getOffsetInfo(dom) } ] }; }, getCompositionInfo(element) { const dom = this.getPreviewElementById(element.id); return { answer_area: [ { main_number: element.topicNo, sub_number: null, area: this.getOffsetInfo(dom) } ] }; }, getOffsetInfo(dom) { let { offsetTop, offsetLeft } = dom; let parentNode = dom.offsetParent; while (parentNode.className.indexOf("page-box") === -1) { offsetTop += parentNode.offsetTop; offsetLeft += parentNode.offsetLeft; parentNode = parentNode.offsetParent; } const pw = parentNode.offsetWidth; const ph = parentNode.offsetHeight; const infos = [ offsetLeft / pw, offsetTop / ph, dom.offsetWidth / pw, dom.offsetHeight / ph ]; return infos.map(num => num.toFixed(10) * 1); }, getPageModel({ cardConfig, paperParams, pages }) { let npages = this.parsePageExchange(pages); return JSON.stringify( { version: CARD_VERSION, cardConfig, paperParams, pages: npages }, (k, v) => (k.startsWith("_") ? undefined : v) ); } } };