guangdong_2018_import.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. 'use strict';
  2. const importXML = (() => {
  3. // 通用设置和工具
  4. const config = importXMLBase.CONFIG;
  5. const util = importXMLBase.UTIL;
  6. const {
  7. fixedFlag,
  8. billType,
  9. rationType,
  10. projectType
  11. } = commonConstants;
  12. const { AdjustType } = config;
  13. const {
  14. getValue,
  15. arrayValue,
  16. getFee,
  17. mergeFees,
  18. getFlag,
  19. getBool,
  20. getItemsRecur,
  21. } = util;
  22. //导入的文件类型,界面选的文件类型是生成项目的文件类型,这里的文件类型指的是,要导入文件的类型,
  23. //导入文件类型不同,导入数据不同
  24. let importFileKind = '';
  25. //文件类型
  26. const FileKind = {
  27. '6': 1, // 投标
  28. 'tender': 1,
  29. '4': 2, // 招标
  30. 'bid': 2,
  31. '5': 3, // 控制价
  32. 'control': 3,
  33. };
  34. const countData = {
  35. projectCount: 0, //项目数量
  36. projectGLJCount: 0, //项目人材机数量
  37. ratioCount: 0, //组成物数量
  38. unitPriceCount: 0, //单价数量
  39. unitPriceFileCount: 0, //单价文件数量
  40. };
  41. // 建设项目
  42. function extractProject(xmlObjMap) {
  43. Object.keys(countData).forEach(key => countData[key] = 0); // 清缓存
  44. countData.projectCount++;
  45. const projectXMLObj = xmlObjMap['Project.xml'];
  46. const projectSrc = getValue(projectXMLObj, ['ConstructionProject']);
  47. importFileKind = FileKind[getValue(source, ['_FileKind'])]; // 标记当前导入的文件类型
  48. const rst = {
  49. projectType: projectType.Project,
  50. name: getValue(projectSrc, ['_Name']),
  51. engs: extractEngs(projectSrc, xmlObjMap),
  52. property: {
  53. compilationIllustrationProject: getValue(projectSrc, ['_Explains'])
  54. },
  55. basicInformation: extractBasicInfo(projectSrc)
  56. };
  57. return rst;
  58. }
  59. // 从xml对象中提取基本信息相关
  60. function extractBasicInfo(projectSrc) {
  61. const projectInfo = getValue(projectSrc, ['ProjectInfo']); // 估概预算信息
  62. const tendereeInfo = getValue(projectSrc, ['TendereeInfo']); // 招标信息
  63. const bidderInfo = getValue(projectSrc, ['BidderInfo']); // 投标信息
  64. return [
  65. { key: 'projNum', value: getValue(projectSrc, ['_Number']) }, // 编码
  66. { key: 'projectCategory', value: getValue(projectSrc, ['_ProjectCategory']) }, // 工程类别
  67. { key: 'constructionType', value: getValue(projectSrc, ['_ConstructionType']) }, // 建设性质
  68. { key: 'regionalCategories', value: getValue(projectSrc, ['_AreaKind']) }, // 地区类被
  69. { key: 'projLocation', value: getValue(projectSrc, ['_ProjectSite']) }, // 工程地点
  70. { key: 'constructingUnits', value: getValue(projectSrc, ['_BulidUnit']) }, // 建设单位
  71. { key: 'constructingUnitsPerson', value: getValue(projectSrc, ['_BulidAuthorizer']) }, // 建设单位法定代表人或其授权人
  72. { key: 'rangeOfCompilation', value: getValue(projectSrc, ['_RangeOfCompilation']) }, // 建设(编制)范围
  73. { key: 'scale', value: getValue(projectSrc, ['_Scale']) }, // 建设规模
  74. { key: 'unit', value: getValue(projectSrc, ['_Unit']) }, // 建设规模单位
  75. { key: 'designUnits', value: getValue(projectInfo, ['_Designer']) }, // 设计单位
  76. { key: 'constructionUnits', value: getValue(projectInfo, ['_Contractor']) }, // 承包单位
  77. { key: 'establishUnit', value: getValue(projectInfo, ['_CompileCompany']) }, // 编制单位
  78. { key: importFileKind === FileKind.tender ? 'bidCompileDate' : 'tenderCompileDate', value: getValue(projectInfo, ['_CompileDate']) }, // 编制时间
  79. { key: 'authorizer', value: getValue(projectInfo, ['_Authorizer']) }, // 编制单位法定代表人或其授权人
  80. { key: 'tendereeName', value: getValue(tendereeInfo, ['_TendereeName']) }, // 招标人
  81. { key: 'tenderAuthorizer', value: getValue(tendereeInfo, ['_TenderAuthorizer']) }, // 招标单位法定代表人或其授权人
  82. { key: 'tenderCompiler', value: getValue(tendereeInfo, ['_TenderCompiler']) }, // 招标单位编制人
  83. { key: 'tenderCompilerCertNo', value: getValue(tendereeInfo, ['_TenderCompilerCertNo']) }, // 招标单位编制人资格证书编号
  84. { key: 'tenderCompileDate', value: getValue(tendereeInfo, ['_TenderCompileDate']) }, // 招标单位编制时间
  85. { key: 'tenderExaminer', value: getValue(tendereeInfo, ['_TenderExaminer']) }, // 招标单位审核人
  86. { key: 'tenderExaminerCertNo', value: getValue(tendereeInfo, ['_TenderExaminerCertNo']) }, // 招标单位审核人资格证书编号
  87. { key: 'tenderExamineDate', value: getValue(tendereeInfo, ['_TenderExamineDate']) }, // 招标单位审核时间
  88. { key: 'tenderApprover', value: getValue(tendereeInfo, ['_TenderApprover']) }, // 招标单位审定人
  89. { key: 'tenderApproverCertNo', value: getValue(tendereeInfo, ['_TenderApproverCertNo']) }, // 招标单位审定人资格证书编号
  90. { key: 'proxy', value: getValue(tendereeInfo, ['_Proxy']) }, // 招标代理
  91. { key: 'proxyCertNo', value: getValue(tendereeInfo, ['_ProxyCertNo']) }, // 招标代理资质证书编号
  92. { key: 'proxyAuthorizer', value: getValue(tendereeInfo, ['_ProxyAuthorizer']) }, // 招标代理法定代表人或其授权人
  93. { key: 'proxyCompiler', value: getValue(tendereeInfo, ['_ProxyCompiler']) }, // 招标代理编制人员
  94. { key: 'proxyCompilerCertNo', value: getValue(tendereeInfo, ['_ProxyCompilerCertNo']) }, // 招标代理编制人员资格证书编号
  95. { key: 'proxyCompileDate', value: getValue(tendereeInfo, ['_ProxyCompileDate']) }, // 招标代理编制时间
  96. { key: 'proxyExaminer', value: getValue(tendereeInfo, ['_ProxyExaminer']) }, // 招标代理审核人
  97. { key: 'proxyExaminerCertNo', value: getValue(tendereeInfo, ['_ProxyExaminerCertNo']) }, // 招标代理审核人资格证书编号
  98. { key: 'proxyExamineDate', value: getValue(tendereeInfo, ['_ProxyExamineDate']) }, // 招标代理审核时间
  99. { key: 'proxyApprover', value: getValue(tendereeInfo, ['_ProxyApprover']) }, // 招标代理审定人
  100. { key: 'proxyApproverCertNo', value: getValue(tendereeInfo, ['_ProxyApproverCertNo']) }, // 招标代理审定人资格证书编号
  101. { key: 'proxyApproveDate', value: getValue(tendereeInfo, ['_ProxyApproveDate']) }, // 招标代理审定时间
  102. { key: 'consultant', value: getValue(tendereeInfo, ['_Consultant']) }, // 造价咨询
  103. { key: 'consultantCertNo', value: getValue(tendereeInfo, ['_ConsultantCertNo']) }, // 造价咨询资质证书编号
  104. { key: 'consultantCompiler', value: getValue(tendereeInfo, ['_ConsultantCompiler']) }, // 造价咨询编制人
  105. { key: 'consultantCompilerCertNo', value: getValue(tendereeInfo, ['_ConsultantCompilerCertNo']) }, // 造价咨询编制人资格证书
  106. { key: 'consultantCompileDate', value: getValue(tendereeInfo, ['_ConsultantCompileDate']) }, // 造价咨询编制时间
  107. { key: 'consultantExaminer', value: getValue(tendereeInfo, ['_ConsultantExaminer']) }, // 造价咨询审核人
  108. { key: 'consultantExaminerCertNo', value: getValue(tendereeInfo, ['_ConsultantExaminerCertNo']) }, // 造价咨询审核人资格证书编号
  109. { key: 'consultantExamineDate', value: getValue(tendereeInfo, ['_ConsultantExamineDate']) }, // 造价咨询审核时间
  110. { key: 'consultantApprover', value: getValue(tendereeInfo, ['_ConsultantApprover']) }, // 造价咨询审定人
  111. { key: 'consultantApproverCertNo', value: getValue(tendereeInfo, ['_ConsultantApproverCertNo']) }, // 造价咨询审定人资格证书编号
  112. { key: 'consultantApproveDate', value: getValue(tendereeInfo, ['_ConsultantApproveDate']) }, // 造价咨询审定时间
  113. { key: 'bidName', value: getValue(bidderInfo, ['_BidName']) }, // 投标人
  114. { key: 'bidAuthorizer', value: getValue(bidderInfo, ['_BidAuthorizer']) }, // 投标单位法定代表人或其授权人
  115. { key: 'bidCompiler', value: getValue(bidderInfo, ['_BidCompiler']) }, // 投标单位编制人
  116. { key: 'bidCompilerCertNo', value: getValue(bidderInfo, ['_BidCompilerCertNo']) }, // 投标单位编制人资格证书编号
  117. { key: 'bidCompileDate', value: getValue(bidderInfo, ['_BidCompileDate']) }, // 投标单位编制时间
  118. { key: 'bidExaminer', value: getValue(bidderInfo, ['_BidExaminer']) }, // 投标单位审核人
  119. { key: 'bidExaminerCertNo', value: getValue(bidderInfo, ['_BidExaminerCertNo']) }, // 投标单位审核人资格证书编号
  120. { key: 'bidExamineDate', value: getValue(bidderInfo, ['_BidExamineDate']) }, // 投标单位审核时间
  121. { key: 'bidApprover', value: getValue(bidderInfo, ['_BidApprover']) }, // 投标单位审定人
  122. { key: 'bidApproverCertNo', value: getValue(bidderInfo, ['_BidApproverCertNo']) }, // 投标单位审定人资格证书
  123. { key: 'bidApproveDate', value: getValue(bidderInfo, ['_BidApproveDate']) }, // 投标单位审定时间
  124. ];
  125. }
  126. // 从xml对象中提取单项工程数据
  127. function extractEngs(projectSrc, xmlObjMap) {
  128. const sectionWorks = arrayValue(projectSrc, ['ProjectInstallationWorkCost', 'SectionalWorks']);
  129. return sectionWorks.map(src => {
  130. countData.projectCount++;
  131. return {
  132. projType: projectType.Engineering,
  133. name: getValue(src, ['_Name']),
  134. code: getValue(src, ['_Number']),
  135. tenders: extractTenders(src, xmlObjMap)
  136. }
  137. });
  138. }
  139. // 从xml对象中提取单位工程数据
  140. function extractTenders(sectionWorkSrc, xmlObjMap) {
  141. const unitWorks = arrayValue(sectionWorkSrc, ['UnitWorks']);
  142. return unitWorks.map(unitWorckSrc => {
  143. countData.projectCount++;
  144. countData.unitPriceFileCount++;
  145. const fileName = getValue(unitWorckSrc, ['_FileName']);
  146. const tenderXMLObj = xmlObjMap[fileName];
  147. const src = getValue(tenderXMLObj, ['UnitWorks']); // 单位工程文件的数据
  148. return {
  149. projType: projectType.Tender,
  150. name: getValue(src, ['_Name']),
  151. code: getValue(src, ['_Number']),
  152. engineering: getValue(src, ['_ProjectType']),
  153. projectFeature: extractProjectFeature(src),
  154. workSummary: extractWorkSummary(src),
  155. fbfx: extractFBFX
  156. };
  157. });
  158. }
  159. // 提取工程特征数据
  160. function extractProjectFeature(tenderSrc) {
  161. // TODO 支持嵌套子项
  162. const attrInfoItems = arrayValue(tenderSrc, ['AttrInfo', 'AttrInfoItem']);
  163. return attrInfoItems.map(item => {
  164. return { name: getValue(item, ['_Name']), value: getValue(item, ['_Value']) };
  165. });
  166. }
  167. // 提取大项费用
  168. function extractWorkSummary(tenderSrc) {
  169. const summaryList = arrayValue(tenderSrc, ['UnitWorksSummary']);
  170. return summaryList.map(src => {
  171. const item = {
  172. code: getValue(src, ['_Number']),
  173. name: getValue(src, ['_Name']),
  174. quantity: getValue(src, ['_Quantity']),
  175. calcBase: getValue(src, ['_QtyFormula']),
  176. remark: getValue(src, ['_Remark']),
  177. feeCode: getValue(src, ['_Code']) //费用字典
  178. };
  179. if (importFileKind === FileKind.tender) { // 投标
  180. item.feeRate = getValue(src, ['_Rate']);
  181. item.fees = [{
  182. fieldName: 'common', totalFee: getValue(itemSrc, ['_Total']) || '0',
  183. unitFee: getValue(src, ['_TechnicalAndEconomicIndex']) || '0'
  184. }];
  185. }
  186. });
  187. }
  188. // 从src子项的SummaryOfBasicCost中获取一部分费用
  189. function getFeesFromBasicCost(src) {
  190. const summaryCost = getValue(src, ['SummaryOfBasicCost']);
  191. if (!summaryCost) {
  192. return [];
  193. }
  194. // SummaryOfBasicCost中有用的价格只有:人工费、材料费、主材费、机械费、管理费、利润
  195. return [
  196. { fieldName: 'labour', totalFee: getValue(summaryCost, ['_Labor']) || '0' },
  197. { fieldName: 'material', totalFee: getValue(summaryCost, ['_Material']) || '0' },
  198. { fieldName: 'mainMaterial', totalFee: getValue(summaryCost, ['_MainMaterial']) || '0' },
  199. { fieldName: 'machine', totalFee: getValue(summaryCost, ['_Machine']) || '0' },
  200. { fieldName: 'manage', totalFee: getValue(summaryCost, ['_Overhead']) || '0' },
  201. { fieldName: 'profit', totalFee: getValue(summaryCost, ['_Profit']) || '0' },
  202. ];
  203. }
  204. // 提取分部分项
  205. function extractFBFX(tenderSrc) {
  206. const fbfxSrc = getValue(tenderSrc, ['DivisionalAndElementalWorks']);
  207. const fields = [['DivisionalWorks'], ['WorkElement']];
  208. const fees = getFeesFromBasicCost(fbfxSrc); // 分部分项的汇总价
  209. const items = getItemsRecur(fbfxSrc, fields, (itemSrc, curField) => {
  210. if (curField[0] === fields[0][0]) { // 分部
  211. return extractDivisionalWorks(itemSrc);
  212. } else {
  213. return extractWorkElement(itemSrc, billType.FX);
  214. }
  215. });
  216. return {
  217. fees,
  218. items
  219. };
  220. }
  221. // 提取分部
  222. function extractDivisionalWorks(divisionalSrc) {
  223. // 分部不需要基数,因此不用把基数导入
  224. const item = {
  225. type: billType.FB,
  226. code: getValue(divisionalSrc, ['_Number']),
  227. name: getValue(divisionalSrc, ['_Name']),
  228. unit: getValue(divisionalSrc, ['_Unit']),
  229. quantity: getValue(divisionalSrc, ['_Quantity']),
  230. feeCode: getValue(divisionalSrc, ['_Code']),
  231. remark: getValue(divisionalSrc, ['_Remark']),
  232. };
  233. if (importFileKind === FileKind.tender) {
  234. const summaryFees = getFeesFromBasicCost(divisionalSrc);
  235. const fees = [{ fieldName: 'common', totalFee: getValue(divisionalSrc, ['_Total']), unitFee: getValue(divisionalSrc, ['_TechnicalAndEconomicIndex']) }];
  236. item.fees = mergeFees(fees, summaryFees);
  237. }
  238. return item;
  239. }
  240. // 提取分项清单数据(包含定额、定额人材机)
  241. function extractWorkElement(workElementSrc, type) {
  242. // 分项不需要基数,因此不用把基数导入
  243. const itemCharacterText = getItemCharacterText(getValue(workElementSrc, ['_Attr']));
  244. const bills = {
  245. type: type, // 清单类型
  246. code: getValue(workElementSrc, ['_Number']),
  247. name: getValue(workElementSrc, ['_Name']),
  248. itemCharacterText,
  249. itemCharacter: getItemCharacter(itemCharacterText),
  250. jocContentText: getValue(workElementSrc, ['_WorkContent']),
  251. jobContent: getJobContent(workElementSrc),
  252. unit: getValue(workElementSrc, ['_Unit']),
  253. quantity: getValue(workElementSrc, ['_Quantity']),
  254. mainBills: getBool(getValue(workElementSrc, ['_Major'])),
  255. feeCode: getValue(workElementSrc, ['_Code']),
  256. remark: getValue(workElementSrc, ['_Remark']),
  257. };
  258. // 投标和控制价,需要导入最高限价
  259. if ([FileKind.tender, FileKind.control].includes(importFileKind)) {
  260. const maxPrice = getValue(workElementSrc, ['_PriceHigh']);
  261. //不为0才输出
  262. if (maxPrice && maxPrice !== '0') {
  263. bills.outPutMaxPrice = true;
  264. bills.maxPrice = maxPrice;
  265. }
  266. if (importFileKind === FileKind.tender) {
  267. const summaryFees = getFeesFromBasicCost(workElementSrc);
  268. const fees = [
  269. { fieldName: 'common', unitFee: getValue(workElementSrc, ['_Price']), totalFee: getValue(workElementSrc, ['_Total']) },
  270. { fieldName: 'equipment', unitFee: getValue(workElementSrc, ['_EquipmentPrice']) },
  271. ];
  272. bills.fees = mergeFees(fees, summaryFees);
  273. // 输出定额数据
  274. bills.rations = extractRations(workElementSrc);
  275. }
  276. }
  277. }
  278. // 获取项目特征文本
  279. function getItemCharacterText(attr) {
  280. const matchStrs = ['
', ';'];
  281. const matchStr = matchStrs.find(str => attr.includes(str));
  282. return attr.replace(new RegExp(matchStr, 'g'), '\n');
  283. }
  284. // 获取清单项目特征窗口数据
  285. function getItemCharacter(itemText) {
  286. const itemsList = itemText.split('\n');
  287. const reg = /\d+\.([^:]+)[::](.*)?/;
  288. const itemCharacter = [];
  289. let idx = 1;
  290. itemsList.forEach(str => {
  291. str = str.replace(/\s/g, '');
  292. const result = reg.exec(str);
  293. if (!result) {
  294. return;
  295. }
  296. const name = result[1];
  297. const value = result[2] || '';
  298. const eigenvalue = value ? [{ value, isSelected: true }] : [];
  299. itemCharacter.push({
  300. character: name,
  301. isChecked: true,
  302. serialNo: idx++,
  303. eigenvalue
  304. });
  305. });
  306. return itemCharacter;
  307. }
  308. // 获取清单工作内容窗口数据
  309. function getJobContent(workElementSrc) {
  310. return arrayValue(workElementSrc, ['WorkContent']).map((workContent, idx) => ({
  311. content: getValue(workContent, ['_Name']),
  312. serialNo: idx + 1,
  313. isChecked: true
  314. }));
  315. }
  316. // 提取定额
  317. function extractRations(workElementSrc) {
  318. // 正常情况下定额肯定是在WorkContent内的,但是也做定额不在WorkContent内的处理(外层定额)
  319. const rations = [];
  320. let serialNo = 1;
  321. const workContents = arrayValue(workElementSrc, ['WorkContent']);
  322. workContents.forEach(workContent => {
  323. const innerRationsSrc = arrayValue(workContent, ['Norm']);
  324. const jobContentText = getValue(workContent, ['_Name']);
  325. const innerRations = innerRationsSrc.map(rationSrc => extractRation(rationSrc, jobContentText));
  326. rations.push(...innerRations);
  327. });
  328. const outerRationsSrc = arrayValue(workElementSrc, ['Norm']);
  329. const outerRations = outerRationsSrc.map(rationSrc => extractRation(rationSrc, ''));
  330. rations.push(...outerRations);
  331. return rations;
  332. // 获取类型
  333. function getType(rationSrc) {
  334. const overHeightMap = {
  335. '1': true,
  336. '2': false
  337. };
  338. const isOverHeight = overHeightMap[getValue(rationSrc, ['EfficiencyKind'])];
  339. if (isOverHeight) {
  340. return rationType.overHeight;
  341. }
  342. const itemIncreaseMap = {
  343. '1': true,
  344. '2': false
  345. };
  346. const isItemIncrease = itemIncreaseMap[getValue(rationsSrc, ['IncFeeKind'])];
  347. if (isItemIncrease) {
  348. return rationType.itemIncrease;
  349. }
  350. return rationType.ration;
  351. }
  352. // 从定额的计算程序提取价格
  353. function getFeesFromCalculationOfItem(rationSrc) {
  354. const calculationOfItems = arrayValue(rationSrc, ['UnitPriceCalculationOfItem']);
  355. const fees = [];
  356. const codeFiedNameMap = {
  357. 'DEZJF': 'direct',
  358. 'RGF': 'labour',
  359. 'CLF': 'material',
  360. 'JXF': 'machine',
  361. 'ZCF': 'mainMaterial',
  362. 'SBF': 'equipment',
  363. 'LR': 'profit',
  364. 'DJ': 'common',
  365. };
  366. calculationOfItems.forEach(item => {
  367. const totalFee = +getValue(item, ['_Total']);
  368. const fieldName = codeFiedNameMap[getValue(item, ['_Code'])];
  369. if (totalFee && fieldName) {
  370. fees.push({ fieldName, totalFee });
  371. }
  372. });
  373. return fees;
  374. }
  375. // 提取定额人材机
  376. function extractRationGLJs(rationSrc) {
  377. const rationGLJsSrc = arrayValue(rationSrc, ['LabourMaterialsEquipmentsMachinesElement']);
  378. return rationGLJsSrc.map(src => ({
  379. code: getValue(src, ['_Number']),
  380. quantity: getValue(src, ['_Quantity'])
  381. }));
  382. }
  383. // TODO 目前无法确定定额的取费专业programID,暂时用专业类别Specialty
  384. function extractRation(rationSrc, jobContentText) {
  385. const ration = {
  386. serialNo: serialNo++,
  387. code: getValue(rationSrc, ['_Number']),
  388. name: getValue(rationSrc, ['_Name']),
  389. unit: getValue(rationSrc, ['_Unit']),
  390. quantity: getValue(rationSrc, ['_Quantity']),
  391. type: getType(rationSrc),
  392. programID: getValue(rationSrc, ['_Specialty']),
  393. libCode: getValue(rationSrc, ['_NormIdentity']),
  394. jobContentText,
  395. remark: getValue(rationSrc, ['_Remark'])
  396. };
  397. const fees = [{ fieldName: 'common', unitFee: getValue(rationSrc, ['_Price']), totalFee: getValue(rationSrc, ['_Total']) }]
  398. const feesFromCalcItem = getFeesFromCalculationOfItem(rationSrc);
  399. ration.fees = mergeFees(fees, feesFromCalcItem);
  400. }
  401. }
  402. /**
  403. * 解压cos、zip文件
  404. * @param {File} file - 上传的文件
  405. * @return {Object} 解压出来的xml文件名称与xml文件文本内容映射
  406. */
  407. async function unzipFile(file) {
  408. const jsZip = new JSZip();
  409. const zip = await jsZip.loadAsync(file);
  410. const map = {};
  411. for (const fileName in zip.files) {
  412. // 将二进制数据转换成字符串
  413. map[fileName] = await jsZip.file(fileName).async('string');
  414. }
  415. return map;
  416. }
  417. //从xml文件中提取数据
  418. async function extractData(file, escape = false) {
  419. const fileMap = await unzipFile(file);
  420. const projectXML = fileMap['Project.xml'];
  421. if (!projectXML) {
  422. throw '无有效数据';
  423. }
  424. const xmlObjMap = {};
  425. for (const fileName in fileMap) {
  426. const xmlStr = escape ? util.escapeXMLEntity(fileMap[fileName]) : fileMap[fileName];
  427. //将xml格式良好的字符串转换成对象
  428. const x2js = new X2JS();
  429. let xmlObj = x2js.xml_str2json(xmlStr);
  430. xmlObj = JSON.parse(util.restoreXMLEntity(JSON.stringify(xmlObj)));
  431. if (!xmlObj) {
  432. throw '无有效数据。';
  433. }
  434. xmlObjMap[fileName] = xmlObj;
  435. }
  436. //提取数据
  437. return extractProject(xmlObjMap);
  438. };
  439. // 接受上传的文件类型(不同的省份可以上传的文件不同)
  440. const accept = ['.zip', '.cos'];
  441. return {
  442. accept,
  443. extractData,
  444. }
  445. })();