123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- import { CARD_VERSION } from "../../enumerate";
- import { deepCopy } from "../../plugins/utils";
- const initIndex = {
- question: 1,
- absent: 1,
- paperType: 1,
- examNumber: 1,
- selective: 1,
- pageNumber: 1
- };
- let fillAreaIndex = { ...initIndex };
- const VALID_ELEMENTS_FOR_EXTERNAL = [
- "LOCATOR",
- "BARCODE",
- "FILL_QUESTION",
- "FILL_LINE",
- "FILL_NUMBER",
- "FILL_FIELD",
- "FILL_TABLE",
- "LINES",
- "GRIDS"
- ];
- function initFillAreaIndex() {
- fillAreaIndex = { ...initIndex };
- }
- function getFillAreaIndex(type) {
- return fillAreaIndex[type]++;
- }
- function getPreviewElementById(id) {
- return document.getElementById(`preview-${id}`);
- }
- function 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);
- }
- // locator: [],
- // barcode: [],
- // info_area: [],
- // fill_area: [],
- // answer_area: []
- const elementInfoFunc = {
- LOCATOR: locators => {
- const result = locators.map(locatorGroup => {
- const locatorInfos = locatorGroup.map(locator => {
- return getOffsetInfo(document.getElementById(locator.id));
- });
- return {
- top: locatorInfos[0],
- bottom: locatorInfos[1]
- };
- });
- return {
- locator: result
- };
- },
- BARCODE: element => {
- return {
- barcode: [
- {
- field: element.field,
- area: getOffsetInfo(getPreviewElementById(element.id))
- }
- ]
- };
- },
- FILL_QUESTION: element => {
- const dom = 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] = getOffsetInfo(optionItem);
- });
- listInfos[questionIndex] = {
- main_number: element.topicNo,
- sub_number: questionItem.firstChild.textContent * 1,
- options
- };
- });
- fillAreas.push({
- field: "question",
- index: getFillAreaIndex("question"),
- single,
- horizontal,
- items: listInfos
- });
- });
- return {
- fill_area: fillAreas
- };
- },
- FILL_LINE: element => {
- const dom = 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_numbers,
- area: getOffsetInfo(dom)
- }
- ]
- };
- },
- FILL_NUMBER: element => {
- let listInfos = [];
- const dom = getPreviewElementById(element.id);
- dom
- .querySelectorAll(".fill-number-list")
- .forEach((questionItem, questionIndex) => {
- let options = [];
- questionItem.childNodes.forEach((optionItem, optionIndex) => {
- options[optionIndex] = getOffsetInfo(optionItem);
- });
- listInfos[questionIndex] = {
- main_number: null,
- sub_number: null,
- options
- };
- });
- return {
- fill_area: [
- {
- field: "examNumber",
- index: getFillAreaIndex("examNumber"),
- single: true,
- horizontal: false,
- items: listInfos
- }
- ]
- };
- },
- FILL_FIELD: element => {
- const dom = getPreviewElementById(element.id);
- return {
- info_area: [getOffsetInfo(dom)]
- };
- },
- FILL_TABLE: element => {
- const dom = getPreviewElementById(element.id);
- return {
- info_area: [getOffsetInfo(dom)]
- };
- },
- LINES: element => {
- const dom = getPreviewElementById(element.id);
- return {
- answer_area: [
- {
- main_number: null,
- sub_numbers: null,
- area: getOffsetInfo(dom)
- }
- ]
- };
- },
- GRIDS: element => {
- const dom = getPreviewElementById(element.id);
- return {
- answer_area: [
- {
- main_number: null,
- sub_numbers: null,
- area: getOffsetInfo(dom)
- }
- ]
- };
- }
- };
- function getPageNumberInfo() {
- const dom = document.querySelector(".page-box-0");
- let options = [];
- dom
- .querySelector(".page-number-rect-list")
- .childNodes.forEach((item, index) => {
- options[index] = getOffsetInfo(item);
- });
- return [
- {
- field: "pageNumber",
- index: 1,
- single: true,
- horizontal: true,
- items: [
- {
- main_number: null,
- sub_number: null,
- options
- }
- ]
- }
- ];
- }
- function parsePageExchange(pages) {
- initFillAreaIndex();
- const npages = deepCopy(pages);
- const pageNumberInfo = getPageNumberInfo();
- npages.forEach((page, pindex) => {
- let exchange = {
- locator: elementInfoFunc.LOCATOR(page.locators),
- barcode: [],
- info_area: [],
- fill_area: [],
- answer_area: []
- };
- const elements = [
- page.globals,
- ...page.columns.map(column => column.elements)
- ];
- elements.forEach(elemGroup => {
- elemGroup.forEach(element => {
- if (!VALID_ELEMENTS_FOR_EXTERNAL.includes(element.type)) return;
- const info = elementInfoFunc[element.type](element);
- Object.entries(info).forEach(([key, vals]) => {
- exchange[key] = exchange[key].concat(vals);
- });
- });
- });
- if (!(pindex % 2)) {
- let pnoInfo = deepCopy(pageNumberInfo);
- pnoInfo[0].index = getFillAreaIndex("pageNumber");
- exchange.fill_area = exchange.fill_area.concat(pnoInfo);
- }
- page.exchange = exchange;
- });
- return npages;
- }
- export function getPageModel({ cardConfig, paperParams, pages }) {
- let npages = parsePageExchange(pages);
- npages.forEach(page => {
- page.exchange.page_size = cardConfig.pageSize;
- });
- return JSON.stringify(
- {
- version: CARD_VERSION,
- cardConfig,
- paperParams,
- pages: npages
- },
- (k, v) => (k.startsWith("_") ? undefined : v)
- );
- }
|