| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621 |
- /*
- * @Descripttion: 导入通用代码
- * @Author: vian
- * @Date: 2020-09-09 10:45:54
- */
- const XML_RN_STR = '@-@';
- const INTERFACE_EXPORT_BASE = (() => {
- // xml字符实体
- const XMLEntity = {
- ' ': 'escape{space}',
- ' ': 'escape{simpleSpace}',
- '	': 'escape{tab}',
- '	': 'escape{simpleTab}',
- '
': 'escape{return}',
- '
': 'escape{simpleReturn}',
- '�A;': 'escape{newLine}',
- '
': 'escape{simpleNewLine}',
- '<': 'escape{less}',
- '>': 'escape{greater}',
- '&': 'escape{and}',
- '"': 'escape{quot}',
- ''': 'escape{apos}'
- };
- // 避免字符实体进行转义。原文本中含有xml字符实体,转换为其他字符。
- function escapeXMLEntity(str) {
- for (const [key, value] of Object.entries(XMLEntity)) {
- str = str.replace(new RegExp(key, 'g'), value);
- }
- return str;
- }
- // 将文本还原为字符实体
- function restoreXMLEntity(str) {
- for (const [key, value] of Object.entries(XMLEntity)) {
- str = str.replace(new RegExp(value, 'g'), key);
- }
- return str;
- }
- /*
- * 根据字段数组获得所要字段的值 eg: 要获取标段下的单项工程: ['标段', '单项工程'];
- * 属性需要加前缀:“_”
- * 节点的不需要加前缀
- * @param {Object}source 源数据
- * {Array}fields 字段数组
- * @return {String}
- * @example getValue(source, ['标段', '_文件类型'])
- * */
- function getValue(source, fields) {
- let cur = source;
- for (const field of fields) {
- if (!cur[field]) {
- return '';
- }
- cur = cur[field];
- }
- if (typeof cur === 'string') {
- cur = cur.replace(new RegExp(XML_RN_STR, 'g'), '\r\n');
- }
- return cur || '';
- }
- // 获取布尔型的数据
- function getBool(source, fields) {
- return getValue(source, fields) === 'true' ? true : false;
- }
- // 获取数据类型
- function _plainType(v) {
- return Object.prototype.toString.call(v).slice(8, -1);
- }
- /*
- * 获取某字段的值,强制返回数组,防止一些错误。如果期待返回数组,可以用此方法。
- * @param {Object}source 数据源
- * {Array}fields 取的字段
- * @return {Array}
- * @example arrayValue(source, ['标段', '单项工程'])
- * */
- function arrayValue(source, fields) {
- let target = getValue(source, fields);
- if (_plainType(target) === 'Object') {
- target = [target];
- } else if (_plainType(target) !== 'Array') {
- target = []
- }
- return target;
- }
- // 获取费用
- function getFee(fees, fields) {
- if (!Array.isArray(fees) || !fees.length) {
- return '0';
- }
- const feeData = fees.find(fee => fee.fieldName === fields[0]);
- return feeData && feeData[fields[1]] || '0';
- }
- // 合并价格
- function mergeFees(feesA, feesB) {
- if (!feesA) {
- return feesB;
- }
- if (!feesB) {
- return [];
- }
- feesB.forEach(feeB => {
- const sameKindFee = feesA.find(feeA => feeA.fieldName === feeB.fieldName);
- if (sameKindFee) {
- Object.assign(sameKindFee, feeB);
- } else {
- feesA.push(feeB);
- }
- });
- return feesA;
- }
- // 将A对象的属性赋值到B对象上
- function assignAttr(target, source, attrs) {
- if (!source || !target) {
- return;
- }
- const sourceAttrs = attrs || Object.keys(source);
- for (const attr of sourceAttrs) {
- // 如果值是undefined,则不进行赋值覆盖处理
- if (attr === 'children' || source[attr] === undefined) {
- continue;
- }
- target[attr] = attr === 'fees'
- ? mergeFees(target[attr], source[attr]) // 如果是价格,不能简单地覆盖,要合并两个对象的价格
- : source[attr];
- }
- }
- // 获取固定ID
- function getFlag(data) {
- return data.flags && data.flags[0] && data.flags[0].flag || 0;
- }
- // 设置成树结构数据
- function setTreeData(data, parent, next) {
- const defalutID = -1;
- data.ID = uuid.v1();
- data.ParentID = parent && parent.ID || defalutID;
- data.NextSiblingID = next && next.ID || defalutID;
- }
- // 递归设置树结构数据,并返回设置好的数据,递归items数组
- function mergeDataRecur(parent, items) {
- const rst = [];
- for (let i = 0; i < items.length; i++) {
- const cur = items[i];
- const next = items[i + 1];
- setTreeData(cur, parent, next);
- rst.push(cur);
- if (cur.items && cur.items.length) {
- rst.push(...mergeDataRecur(cur, cur.items));
- }
- }
- return rst;
- }
- // 递归获取相关数据,(同层可以出现不同节点)
- // fields内字段的顺序即决定了提取数据类型的顺序,如fields = [['gruop'], ['item']],则提取的数据同层中group数据在item数据之前
- function extractItemsRecur(src, fields, extractFuc) {
- const rst = [];
- for (const field of fields) {
- const itemsSrc = arrayValue(src, field);
- if (itemsSrc.length) {
- /* const items = itemsSrc.map(itemSrc => {
- const obj = extractFuc(itemSrc, field[0]);
- obj.children = extractItemsRecur(itemSrc, fields, extractFuc);
- return obj;
- }); */
- const items = [];
- itemsSrc.forEach(itemSrc => {
- const obj = extractFuc(itemSrc, field[0]);
- if (obj) {
- if (!obj.children || obj.children.length === 0) {
- obj.children = extractItemsRecur(itemSrc, fields, extractFuc);
- }
- items.push(obj);
- }
- })
- rst.push(...items);
- }
- }
- return rst;
- }
- const UTIL = Object.freeze({
- escapeXMLEntity,
- restoreXMLEntity,
- getValue,
- getBool,
- arrayValue,
- getFee,
- mergeFees,
- assignAttr,
- setTreeData,
- mergeDataRecur,
- getFlag,
- extractItemsRecur,
- });
- /**
- * 合并基本信息或工程特征
- * @param {Array} source - 提取的数据
- * @param {Array} target - 模板数据
- * @return {Array}
- */
- function mergeInfo(source, target) {
- source.forEach(item => mergeChild(item, target));
- return target;
- function mergeChild(item, target) {
- for (const child of target) {
- if (child.key === item.key) {
- child.value = item.value;
- return true;
- }
- if (child.items && child.items.length) {
- const rst = mergeChild(item, child.items);
- if (rst) {
- return true;
- }
- }
- }
- return false;
- }
- }
- const { fixedFlag, BillType } = window.commonConstants;
- // 标题类别 - flag 映射
- const titleTypeToFlag = {
- 1: fixedFlag.ONE_SEVEN_BILLS,
- 2: fixedFlag.PROVISIONAL_TOTAL,
- 3: fixedFlag.BILLS_TOTAL_WT_PROV,
- 4: fixedFlag.DAYWORK_LABOR,
- 5: fixedFlag.PROVISIONAL,
- 6: fixedFlag.TOTAL_COST,
- }
- /**
- * 将提取出来的清单合并进清单模板
- * @param {Array} source - 从xml提取出来的清单
- * @param {Array} target - 清单模板数据
- * @param {Object} parent - 匹配到模板清单的父清单
- * @param {Boolean} onlyImportMatchBills - 是否只导入文件中的清单,未匹配的模板清单不生成
- * @return {void}
- */
- function mergeBills(source, target, parent, matchedFlags) {
- source.forEach((bills, index) => {
- // 为了大项费用排序
- if (!parent) {
- bills.seq = index;
- }
- const simpleName = bills.name ? bills.name.replace(/\s/g, '') : '';
- const titleType = bills.titleType || '0';
- let matched;
- if (!parent) {
- if (titleTypeToFlag[titleType] === fixedFlag.ONE_SEVEN_BILLS || /100章.*700章|100章.*900章/.test(simpleName)) {
- matched = target.find(bills => getFlag(bills) === fixedFlag.ONE_SEVEN_BILLS);
- } else if (titleTypeToFlag[titleType] === fixedFlag.PROVISIONAL_TOTAL || /包含在清单合计中的材料、工程设备、专业工程暂估/.test(simpleName)) {
- matched = target.find(bills => getFlag(bills) === fixedFlag.PROVISIONAL_TOTAL);
- } else if (titleTypeToFlag[titleType] === fixedFlag.BILLS_TOTAL_WT_PROV || /清单合计减去材料、工程设备、专业工程暂估价/.test(simpleName)) {
- matched = target.find(bills => getFlag(bills) === fixedFlag.BILLS_TOTAL_WT_PROV);
- } else if (titleTypeToFlag[titleType] === fixedFlag.DAYWORK_LABOR || /计日工合计/.test(simpleName)) {
- matched = target.find(bills => getFlag(bills) === fixedFlag.DAYWORK_LABOR);
- } else if (titleTypeToFlag[titleType] === fixedFlag.PROVISIONAL || /暂列金额[((]不含/.test(simpleName)) {
- matched = target.find(bills => getFlag(bills) === fixedFlag.PROVISIONAL);
- } else if (titleTypeToFlag[titleType] === fixedFlag.TOTAL_COST || /报价/.test(simpleName)) {
- matched = target.find(bills => getFlag(bills) === fixedFlag.TOTAL_COST);
- }
- } else {
- const parentSimpleName = parent.name ? parent.name.replace(/\s/g, '') : '';
- if (/100章.*700章|100章.*900章/.test(parentSimpleName) && /100章总则/.test(simpleName)) {
- matched = target.find(bills => getFlag(bills) === fixedFlag.ONE_HUNDRED_BILLS);
- } else if (/计日工合计/.test(parentSimpleName) && /劳务/.test(simpleName)) {
- matched = target.find(bills => getFlag(bills) === fixedFlag.LABOUR_SERVICE);
- } else if (/计日工合计/.test(parentSimpleName) && /材料/.test(simpleName)) {
- matched = target.find(bills => getFlag(bills) === fixedFlag.MATERIAL);
- } else if (/计日工合计/.test(parentSimpleName) && /机械/.test(simpleName)) {
- matched = target.find(bills => getFlag(bills) === fixedFlag.CONSTRUCTION_MACHINE);
- }
- }
- if (matched) {
- matchedFlags.push(getFlag(matched));
- assignAttr(matched, bills);
- if (bills.children && bills.children.length) {
- mergeBills(bills.children, matched.children, matched, matchedFlags);
- }
- } else {
- target.push(bills);
- }
- });
- }
- /**
- * 处理清单
- * @param {Array} tenderBills - 从xml提取出来的清单
- * @param {Array} billsTarget - 拷贝一份的模板清单,用于合并提取清单
- * @param {Number} tenderID - 单位工程ID
- * @param {Boolean} onlyImportMatchBills - 是否只导入文件中的清单,未匹配的模板清单不生成
- * @return {Array}
- */
- function handleBills(tenderBills, billsTarget, tenderID, onlyImportMatchBills) {
- const rst = [];
- // 将提取的清单数据合并进清单模板数据
- const matchedFlags = [];
- mergeBills(tenderBills, billsTarget, null, matchedFlags);
- // 如果只导入文件中有的清单,除100-700/900章清单、报价清单外,其他未匹配到的固定清单模板,均不导入
- function removeNotMatchFlagBills(bills) {
- const rst = [];
- bills.forEach(item => {
- const flag = getFlag(item);
- if (!flag || [fixedFlag.ONE_SEVEN_BILLS, fixedFlag.TOTAL_COST].includes(flag) || matchedFlags.includes(flag)) {
- rst.push(item);
- }
- if (flag && ![fixedFlag.ONE_SEVEN_BILLS, fixedFlag.TOTAL_COST].includes(flag) && item.children && item.children.length) {
- item.children = removeNotMatchFlagBills(item.children);
- }
- });
- return rst;
- }
- if (onlyImportMatchBills) {
- billsTarget = removeNotMatchFlagBills(billsTarget)
- }
- // 大项费用按照清单标题排序
- billsTarget.sort((a, b) => a.seq - b.seq);
- // 给清单设置数据
- const rowCodeData = []; // 行号数据,用于转换行引用
- const toBeTransformBills = []; // 待转换的清单
- function setBills(bills, parentID) {
- bills.forEach((child, index) => {
- rst.push(child);
- child.projectID = tenderID;
- // 如果本身清单就有ID,那不用处理,可以减少处理清单模板的一些ID引用问题
- if (!child.ID) {
- child.ID = uuid.v1();
- }
- if (child.quantity) {
- child.quantityEXP = child.quantity;
- }
- child.ParentID = parentID;
- child.type = parentID === -1 ? BillType.DXFY : BillType.BILL;
- child.NextSiblingID = -1;
- const preChild = bills[index - 1];
- if (preChild) {
- preChild.NextSiblingID = child.ID;
- }
- if (child.rowCode) {
- const regStr = /{[^{}]+}/.test(child.rowCode) ? child.rowCode : `\\b${child.rowCode}\\b`;
- rowCodeData.push({ reg: new RegExp(regStr, 'g'), ID: child.ID, rowCode: child.rowCode });
- }
- if (child.tempCalcBase) {
- toBeTransformBills.push(child);
- }
- if (child.children && child.children.length) {
- setBills(child.children, child.ID);
- }
- });
- }
- setBills(billsTarget, -1);
- // 转换计算基数
- toBeTransformBills.forEach(bills => {
- rowCodeData.forEach(({ reg, ID, rowCode }) => {
- const rowCodeReg = new RegExp(`{${rowCode}}`);
- // 替换行号
- if (rowCodeReg.test(bills.tempCalcBase)) {
- bills.tempCalcBase = bills.tempCalcBase.replace(rowCodeReg, `@${ID}`);
- } else {
- bills.tempCalcBase = bills.tempCalcBase.replace(reg, `@${ID}`);
- }
- // 替换基数,防止其他公司的软件导出没有{}
- bills.tempCalcBase = bills.tempCalcBase.replace(/.?专项暂定合计.?/g, '{专项暂定合计}');
- bills.tempCalcBase = bills.tempCalcBase.replace(/.?各章清单合计.?/g, '{各章清单合计}');
- });
- /* 检查基数有效性,无效则使用模板的基数 */
- // 消除ID引用对基数分割的影响
- const IDs = bills.tempCalcBase.match(/@[\da-zA-Z-]{36}/g) || [];
- const bases = [...IDs];
- const str = bills.tempCalcBase.replace(/@[\da-zA-Z-]{36}/g, '');
- const otherBases = str.split(/[+-/*]/).filter(item => !!item);
- bases.push(...otherBases);
- // 判定基数有效性
- const isValid = bases.every(base => {
- if (base === '{专项暂定合计}' || base === '{各章清单合计}') {
- return true;
- }
- if (/^(\d+(\.\d+)?)%?$/.test(base)) { // 数值+%(可有可无)
- return true;
- }
- if (/[\da-zA-Z-]{36}/.test(base)) { // ID引用
- return true;
- }
- return false;
- });
- if (isValid) {
- bills.calcBase = bills.tempCalcBase;
- }
- });
- rst.forEach(bills => delete bills.children);
- return rst;
- }
- function getTemplateBillsTarget(templateBills) {
- const templateTarget = _.cloneDeep(templateBills);
- const ungroupedData = [];
- function getBillsFromChildren(billsData) {
- for (const bills of billsData) {
- ungroupedData.push(bills);
- if (bills.children && bills.children.length) {
- getBillsFromChildren(bills.children);
- }
- }
- }
- getBillsFromChildren(templateTarget);
- BILLS_UTIL.resetTreeData(ungroupedData, uuid.v1, true);
- return templateTarget;
- }
- // 处理单位工程数据
- function handleTenderData(tenders, templateData, rationValuationData, engineeringLib, areaKey, onlyImportMatchBills) {
- tenders.forEach((tender, index) => {
- tender.compilation = compilationData._id;
- tender.userID = userID;
- tender.ID = templateData.projectBeginID + index + 1;
- tender.ParentID = templateData.projectBeginID;
- tender.NextSiblingID = index === tenders.length - 1 ? -1 : templateData.projectBeginID + index + 2;
- tender.projType = projectType.tender;
- const featureTarget = _.cloneDeep(templateData.feature); // 必须拷贝出一份新数据,否则会被下一个单位工程覆盖
- if (!engineeringLib) {
- throw '不存在可用工程专业。';
- }
- const taxData = engineeringLib.lib.tax_group[0];
- const featureSource = [
- ...(tender.feature || []),
- { key: 'valuationType', value: '工程量清单' }, // 导入的时候以下项不一定有数据,但是需要自动生成
- { key: 'feeStandard', value: engineeringLib.lib.feeName },
- ];
- const needEngineering = featureTarget && featureTarget.find(item => item.key === 'engineering');
- if (needEngineering) {
- featureSource.push({ key: 'engineering', value: engineeringLib.lib.name });
- }
- tender.property = {
- areaKey,
- rootProjectID: tender.ParentID,
- region: '全省',
- engineering_id: engineeringLib.engineering_id,
- engineeringName: engineeringLib.lib.name,
- feeStandardName: engineeringLib.lib.feeName,
- engineering: engineeringLib.engineering,
- isInstall: engineeringLib.lib.isInstall,
- projectEngineering: engineeringLib.lib.projectEngineering,
- valuation: rationValuationData.id,
- valuationName: rationValuationData.name,
- valuationType: commonConstants.ValuationType.BOQ, // 必为工程量清单
- boqType: commonConstants.BOQType.BID_SUBMISSION, // 导入后必为投标
- taxType: taxData.taxType,
- projectFeature: mergeInfo(featureSource, featureTarget),
- featureLibID: engineeringLib.lib.feature_lib[0] && engineeringLib.lib.feature_lib[0].id || '',
- calcProgram: { name: taxData.program_lib.name, id: taxData.program_lib.id },
- colLibID: taxData.col_lib.id,
- templateLibID: taxData.template_lib.id,
- unitPriceFile: { name: tender.name, id: templateData.unitPriceFileBeginID + index }, // 新建单价文件
- feeFile: { name: tender.name, id: `newFeeRate@@${taxData.fee_lib.id}` } // 新建费率文件
- };
- delete tender.feature;
- const tenderDataBills = getTemplateBillsTarget(templateData.bills);
- tender.bills = handleBills(tender.bills, tenderDataBills, tender.ID, onlyImportMatchBills); // 必须要拷贝一份,否则多单位工程情况下,前单位工程的清单数据会被后单位工程的覆盖
- // 给暂估材料和评标材料设置项目数据
- const setGLJRefFunc = glj => {
- glj.ID = uuid.v1();
- glj.projectID = tender.ID;
- }
- if (tender.evaluationList && tender.evaluationList.length) {
- tender.evaluationList.forEach(setGLJRefFunc);
- }
- if (tender.bidEvaluationList && tender.bidEvaluationList.length) {
- tender.bidEvaluationList.forEach(setGLJRefFunc);
- }
- });
- }
- /**
- * 将接口中提取出来数据转换成可入库的有效数据
- * 因为无法保证这一套逻辑能不能兼容以后的所有接口,因此提取数据与标准数据模板的合并放在前端进行。
- * 当统一逻辑无法满足某一接口时,接口可以根据标准模板数据自行进行相关处理。
- * @param {Object} importData - 各接口从xml提取出来的数据
- * @param {String} areaKey - 接口地区
- * @param {Boolean} onlyImportMatchBills - 是否只导入文件中的清单,未匹配的模板清单不生成
- * @return {Promise<Object>}
- */
- async function handleImportData(importData, areaKey, onlyImportMatchBills) {
- const valuationID = compilationData.ration_valuation[0].id;
- if (!Array.isArray(importData.tenders) && !importData.tenders.length) {
- throw '导入的文件中不存在有效的标段数据。';
- }
- const projectCount = 1 + importData.tenders.length;
- // const feeName = compilationData.name === '安徽养护(2018)' ? '安徽养护' : '公路工程';
- // 一些接口需要根据导入文件,匹配工程专业库
- debugger;
- const rationValuationData = rationValuation && JSON.parse(rationValuation)[0]; // 只有工程量清单才能导入接口
- if (!rationValuationData) {
- throw '无法获取工程量清单计价数据';
- }
- const engineeringList = (rationValuationData.engineering_list || []).filter(item => item.lib.visible);
- let engineeringLib = engineeringList[0];
- if (importData.engineeringName && importData.feeName) {
- const matchLibs = engineeringList.filter(item => item.lib && item.lib.name === importData.engineeringName);
- engineeringLib = matchLibs.find(item => item.lib.feeName === importData.feeName) || matchLibs[0] || engineeringList[0];
- }
- const engineeringID = engineeringLib.engineering_id || null;
- const templateData = await ajaxPost('/pm/api/getImportTemplateData', { user_id: userID, valuationID, engineeringID, projectCount });
- if (!templateData) {
- throw '无法获取有效模板数据。';
- }
- console.log(templateData);
- // 处理建设项目数据
- // 确定建设项目的名称(不允许重复)
- /* const sameDepthProjs = getProjs(projTreeObj.tree.selected);
- const matchedProject = sameDepthProjs.find(node => node.data.name === importData.name);
- if (matchedProject) {
- alert('test');
- importData.name += `(${moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')})`;
- } */
- importData.compilation = compilationData._id;
- importData.userID = userID;
- importData.ID = templateData.projectBeginID;
- const { parentProjectID, preProjectID, nextProjectID } = projTreeObj.getRelProjectID(projTreeObj.tree.selected);
- importData.ParentID = parentProjectID;
- importData.preID = preProjectID;
- importData.NextSiblingID = nextProjectID;
- importData.projType = projectType.project;
- importData.property = {
- valuationType: commonConstants.ValuationType.BOQ, // 必为工程量清单
- boqType: commonConstants.BOQType.BID_SUBMISSION, // 导入后必为投标
- basicInformation: mergeInfo(importData.info, templateData.basicInfo) // 将提取的基本信息数据与标准基本信息数据进行合并(目前只赋值,没有匹配到的不追加)
- };
- delete importData.info;
- // 处理单位工程数据
- handleTenderData(importData.tenders, templateData, rationValuationData, engineeringLib, areaKey, onlyImportMatchBills);
- console.log(importData);
- }
- /*
- * 读取文件转换为utf-8编码的字符串
- * @param {Blob} file
- * @return {Promise}
- * */
- function readAsTextSync(file) {
- return new Promise((resolve, reject) => {
- const fr = new FileReader();
- fr.readAsText(file); // 默认utf-8,如果出现乱码,得看导入文件是什么编码
- fr.onload = function () {
- resolve(this.result);
- };
- fr.onerror = function () {
- reject('读取文件失败,请重试。');
- }
- });
- }
- /**
- *
- * @param {Function} entryFunc - 各导入接口提取导入数据方法
- * @param {File} file - 导入的文件
- * @param {String} areaKey - 地区标识,如:'安徽@马鞍山'
- * @param {Boolean} escape - 是否需要避免xml中的实体字符转换
- * @param {Boolean} onlyImportMatchBills - 是否只导入文件中的清单,未匹配的模板清单不生成
- * @return {Promise<Object>}
- */
- async function extractImportData(entryFunc, file, areaKey, escape = false, onlyImportMatchBills = false) {
- // 将二进制文件转换成字符串
- let xmlStr = await readAsTextSync(file);
- if (escape) {
- // x2js的str to json的实现方式基于DOMParser,DOMParser会自动将一些实体字符进行转换,比如 “< to <”。如果不想进行自动转换,需要进行处理。
- xmlStr = escapeXMLEntity(xmlStr);
- }
- let reg1 = new RegExp('>\r\n', 'g');
- xmlStr = xmlStr.replace(reg1, '>');
- let reg2 = new RegExp('\r\n', 'g');
- xmlStr = xmlStr.replace(reg2, XML_RN_STR);
- // reg = /(?<=子目名称).+(?=单位)/g;
- // let matchResult = xmlStr.match(reg);
- // if (matchResult.length > 0) {
- // console.log(matchResult[0]);
- // }
- // xmlStr = xmlStr.replace(new RegExp('\r\n', 'g'), XML_RN_STR);
- // 将xml格式良好的字符串转换成对象
- const x2js = new X2JS();
- let xmlObj = x2js.xml_str2json(xmlStr);
- xmlObj = JSON.parse(restoreXMLEntity(JSON.stringify(xmlObj)));
- console.log(xmlObj);
- if (!xmlObj) {
- throw '无有效数据。';
- }
- const importData = await entryFunc(areaKey, xmlObj);
- console.log(areaKey);
- await handleImportData(importData, areaKey, onlyImportMatchBills);
- return importData;
- }
- return {
- UTIL,
- extractImportData,
- }
- })();
|