importBills.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Zhong
  6. * @date 2018/8/2
  7. * @version
  8. */
  9. /*
  10. * 清单导入模块,前端导入excel,进行数据提取,用lz-string进行压缩上传处理
  11. * */
  12. const importBills = (function(){
  13. //单元格数据是否存在
  14. function _isDef(data){
  15. return typeof data !== 'undefined' && data !== null && data !== '';
  16. }
  17. //去除转义字符
  18. function _deESC(data) {
  19. return _isDef(data) ? data.toString().replace(/[\r\n\s\t]/g, '') : data;
  20. }
  21. function _deNR(data) {
  22. return _isDef(data) ? data.toString().replace(/\r\r/g, '\r') : data;
  23. }
  24. //列名对应中文字符
  25. const colText = {
  26. serialNo: ['序号'],
  27. code: ['编码', '项目编码'],
  28. name: ['名称', '项目名称'],
  29. itemCharacterText: ['特征', '项目特征', '项目特征描述'],
  30. unit: ['单位', '计量单位'],
  31. quantity: ['工程量', '项目工程量'],
  32. money: ['金额'],
  33. quantityDetail: ['工程量明细'],
  34. feeDetail: ['费用明细'],
  35. summation: ['合计', '本页小计'],
  36. };
  37. //导入位置对应清单固定标记
  38. const positionFlag = {
  39. fbfx: fixedFlag.SUB_ENGINERRING,
  40. jscsxm: fixedFlag.CONSTRUCTION_TECH,
  41. zzcsxm: fixedFlag.CONSTRUCTION_ORGANIZATION,
  42. };
  43. //上传类型
  44. const uploadType = {
  45. general: 'general',
  46. lj: 'lj',
  47. gld: 'gld',
  48. };
  49. let curFileType = uploadType.general;
  50. //设置导入表内容(选择导入位置)
  51. //@param {Object}workBook
  52. function setImportSheetsInfo(sheets){
  53. let sheetNames = [];
  54. let indexMapping = {};
  55. for(let sheetName in sheets){
  56. indexMapping[sheets[sheetName]['index']] = sheetName;
  57. }
  58. let sheetsCount = Object.keys(sheets).length;
  59. for(let i = 0; i < sheetsCount; i++){
  60. sheetNames.push(indexMapping[i]);
  61. }
  62. let sheetArea = $('#uploadSheets'),
  63. sheetHeader = $('#uploadSheetsHead');
  64. $('#uploadSheets').height('');
  65. sheetArea.empty();
  66. for(let sheetName of sheetNames){
  67. let sheetDiv = $(`<div style="margin-left: 5px;margin-top: 5px;" title="${sheetName}" class="input-group form-check"><label class="form-check-label" style="width:270px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis">
  68. <input class="form-check-input" type="checkbox">${sheetName}</label></div>`);
  69. sheetDiv.find('input[type="checkbox"]').click(function () {
  70. if($('#uploadAlert').is(':visible')){
  71. $('#uploadAlert').hide();
  72. }
  73. });
  74. let sel = $(`<select style="margin-left: 5px; border-radius: .20rem;"><option value="fbfx">分部分项工程</option><option value="zzcsxm">施工组织措施项目</option><option value="jscsxm">施工技术措施项目</option></select>`);
  75. if(sheetName.includes('分部分项工程项目清单计价表')){
  76. sheetDiv.find('input[type="checkbox"]').prop('checked', true);
  77. sel.find('option:eq(0)').prop('selected', true);
  78. }
  79. else if(sheetName.includes('施工组织措施项目清单计价表')){
  80. sheetDiv.find('input[type="checkbox"]').prop('checked', true);
  81. sel.find('option:eq(1)').prop('selected', true);
  82. }
  83. else if(sheetName.includes('施工技术措施项目清单计价表')){
  84. sheetDiv.find('input[type="checkbox"]').prop('checked', true);
  85. sel.find('option:eq(2)').prop('selected', true);
  86. }
  87. sheetDiv.append(sel);
  88. sheetArea.append(sheetDiv);
  89. }
  90. if(sheetNames.length > 0){
  91. sheetArea.show();
  92. sheetHeader.show();
  93. }
  94. if($('#uploadSheets').height() > 250){
  95. sheetArea.css('overflow', 'auto');
  96. sheetArea.height(250);
  97. }
  98. else {
  99. sheetArea.css('overflow', 'hidden');
  100. }
  101. }
  102. //获得选择导入的表信息(表索引及导入位置)
  103. //@return {Object}
  104. function getImportSheetsInfo(){
  105. let rst = [];
  106. let sheetArea = $('#uploadSheets');
  107. let checkedInputs = sheetArea.find('input:checked');
  108. for(let checked of checkedInputs){
  109. rst.push({index: $(checked).parent().parent().index(), position: $(checked).parent().next().select().val()})
  110. }
  111. return rst;
  112. }
  113. function getSheetByIndex(sheets, index){
  114. for(let sheetName in sheets){
  115. let sheet = sheets[sheetName];
  116. if(sheet.index === index){
  117. return sheet;
  118. }
  119. }
  120. return null;
  121. }
  122. //提取excel表头列名与列下标映射
  123. function getColMapping(dataTable){
  124. //获取表头
  125. function getHeadRow(dataTable){
  126. const headTexts = [colText.serialNo[0], ...colText.code];
  127. for(let rowIdx in dataTable ){
  128. for(let colIdx in dataTable[rowIdx]){
  129. let cellData = dataTable[rowIdx][colIdx]['value'];
  130. if(cellData && headTexts.includes(_deESC(cellData))){
  131. return dataTable[rowIdx];
  132. }
  133. }
  134. }
  135. return {};
  136. }
  137. //获取需要的表头列与列号对应关系
  138. let colMapping = {};
  139. let headRow = getHeadRow(dataTable);
  140. for(let colIdx in headRow){
  141. let cellData = headRow[colIdx]['value'];
  142. if(!_isDef(cellData)){
  143. continue;
  144. }
  145. //序号
  146. if(colMapping.serialNo === undefined && _deESC(cellData) === colText.serialNo[0]){
  147. colMapping.serialNo = colIdx;
  148. }
  149. //编码
  150. else if(colMapping.code === undefined && (_deESC(cellData) === colText.code[0] || _deESC(cellData) === colText.code[1])){
  151. colMapping.code = colIdx;
  152. }
  153. //名称
  154. else if(colMapping.name === undefined && (_deESC(cellData) === colText.name[0] || _deESC(cellData) === colText.name[1])){
  155. colMapping.name = colIdx;
  156. }
  157. //项目特征
  158. else if(colMapping.itemCharacterText === undefined && (_deESC(cellData) === colText.itemCharacterText[0] || _deESC(cellData) === colText.itemCharacterText[1]
  159. || _deESC(cellData) === colText.itemCharacterText[2])){
  160. colMapping.itemCharacterText = colIdx;
  161. }
  162. //单位
  163. else if(colMapping.unit === undefined && (_deESC(cellData) === colText.unit[0] || _deESC(cellData) === colText.unit[1])){
  164. colMapping.unit = colIdx;
  165. }
  166. //工程量
  167. else if(colMapping.quantity === undefined && (_deESC(cellData) === colText.quantity[0] || _deESC(cellData) === colText.quantity[1])){
  168. colMapping.quantity = colIdx;
  169. }
  170. //金额
  171. else if(colMapping.money === undefined && _deESC(cellData).includes(colText.money[0])){
  172. colMapping.money = colIdx;
  173. }
  174. //工程量明细
  175. else if(colMapping.quantityDetail === undefined && _deESC(cellData) === colText.quantityDetail[0]){
  176. colMapping.quantityDetail = colIdx;
  177. }
  178. //费用明细
  179. else if(colMapping.feeDetail === undefined && _deESC(cellData) === colText.feeDetail[0]){
  180. colMapping.feeDetail = colIdx;
  181. }
  182. }
  183. return colMapping;
  184. }
  185. // 根据列设置判断从excel表上传界面,上传的具体类型是什么:自定义通用表和09表使用了同一个按钮,因此在获取列设置的时候,还要再区分general和lj
  186. function getExactlyFileType(colMapping) {
  187. // 只需要区分自定义通用表和09表
  188. return !_isDef(colMapping.serialNo) && !_isDef(colMapping.money)
  189. ? uploadType.general
  190. : uploadType.lj;
  191. }
  192. //是否是有效的表头列格式,只要含有各表需要的列就行,不严格控制多少列
  193. function isValidSheet(colMapping){
  194. function hasField(field, all){
  195. for(let i of all){
  196. if(field === i){
  197. return true;
  198. }
  199. }
  200. return false;
  201. }
  202. let needFields;
  203. if (curFileType === uploadType.general) {
  204. // 自定义通用表:项目编码 项目名称 项目特征 计量单位 工程量
  205. needFields = ['code', 'name', 'itemCharacterText', 'unit', 'quantity'];
  206. } else if(curFileType === uploadType.lj){
  207. //09表:序号、项目编码、项目名称、项目特征、计量单位、工程量、金额
  208. needFields = ['serialNo', 'code', 'name', 'money'];
  209. } else {
  210. //广联达表:序号、项目编码、项目名称、项目特征、计量单位、工程量、工程量明细、费用明细
  211. needFields = ['serialNo', 'code', 'name', 'itemCharacterText', 'unit', 'quantity', 'quantityDetail', 'feeDetail'];
  212. }
  213. let hasFieldCount = 0;
  214. for(let attr in colMapping){
  215. if(hasField(attr, needFields)){
  216. hasFieldCount++;
  217. }
  218. }
  219. return hasFieldCount === needFields.length;
  220. }
  221. //获取要无效和有效导入表
  222. //@param {Array}importSheetInfo 勾选要导入的表
  223. function getImportSheets(sheets, sheetsInfo, fileType){
  224. curFileType = fileType; // 自定义通用表和09表使用了同一个按钮,因此在获取列设置的时候,还要再区分general和lj
  225. let isGetType = false;
  226. let rst = {invalidSheets: [], validSheets: {fbfx: [], jscsxm: [], zzcsxm: []}};
  227. for(let sheetInfo of sheetsInfo){
  228. let sheet = getSheetByIndex(sheets, sheetInfo.index);
  229. if(!sheet){
  230. continue;
  231. }
  232. //没有数据
  233. if(!sheet.data.dataTable){
  234. rst.invalidSheets.push(sheet.name);
  235. continue;
  236. }
  237. //获取表的列设置确定导入的格式是否合法(通用excel、09、广联达)
  238. let colMapping = getColMapping(sheet.data.dataTable);
  239. // 以第一个有效的sheet作为类型基准
  240. if (!isGetType && fileType === uploadType.lj) {
  241. curFileType = getExactlyFileType(colMapping);
  242. }
  243. if(!isValidSheet(colMapping)){
  244. rst.invalidSheets.push(sheet.name);
  245. continue;
  246. }
  247. isGetType = true;
  248. //合法的表
  249. sheet.colMapping = colMapping;
  250. //将合法的表按导入位置分类当做一个表来处理
  251. if(rst.validSheets[sheetInfo.position] !== undefined){
  252. rst.validSheets[sheetInfo.position].push(sheet)
  253. }
  254. }
  255. return rst;
  256. }
  257. //行存在数据
  258. function rowExistData(rowData){
  259. for(let colIdx in rowData){
  260. let colData = rowData[colIdx]['value'];
  261. if(_isDef(colData)){
  262. return true;
  263. }
  264. }
  265. return false;
  266. }
  267. //提取excel表数据中的有效数据(去表头表尾,提取其中的excel数据)(根据fixedBill获取栏头占行数)
  268. function getValidImportData(colMapping, sheetData){
  269. let withingD = false;
  270. let validData = [];
  271. function isHead(rData){
  272. return curFileType === uploadType.general
  273. ? rData[colMapping.code] && colText.code.includes(_deESC(rData[colMapping.code]['value']))
  274. : rData[colMapping.serialNo] && _deESC(rData[colMapping.serialNo]['value']) === colText.serialNo[0];
  275. }
  276. function isTail(rowData){
  277. for(let colIdx in rowData){
  278. let colData = rowData[colIdx]['value'];
  279. if(colData){
  280. let trimColData= _deESC(colData);
  281. if(trimColData === colText.summation[0] || trimColData === colText.summation[1]){
  282. return true;
  283. }
  284. }
  285. }
  286. return false;
  287. }
  288. for(let rowIdx in sheetData){
  289. let rowData = sheetData[rowIdx];
  290. if(isHead(rowData)){
  291. withingD = true;
  292. continue;
  293. }
  294. else if(isTail(rowData)){
  295. withingD = false;
  296. }
  297. if(withingD && rowExistData(rowData)){
  298. validData.push(rowData);
  299. }
  300. }
  301. return validData;
  302. }
  303. //excel数据转换成清单数据
  304. function parseToBillData(validData, colMapping, flag, projectID){
  305. let rst = [];
  306. let billIdx = {};
  307. let preRootID = -1,
  308. preLeafID = -1,
  309. preID = -1;
  310. //父节点
  311. function isRoot(rData){
  312. //序号和编码去除转义字符(有的表格单元格看起来是没数据,实际含有\r,\n等数据)
  313. const code = rData[colMapping.code] ? _deESC(rData[colMapping.code]['value']) : '';
  314. const unit = rData[colMapping.unit] ? _deESC(rData[colMapping.unit]['value']) : '';
  315. if (curFileType === uploadType.general) {
  316. // 通用表:项目编码非12位或者无单位的
  317. return !_isDef(code) || !/\w{12}/.test(code) || !_isDef(unit);
  318. } else {
  319. // 09、广联达表:1.无序号 2有编码
  320. const serialNo = rData[colMapping.serialNo] ? _deESC(rData[colMapping.serialNo]['value']) : '';
  321. return !_isDef(serialNo) && _isDef(code);
  322. }
  323. }
  324. //子节点
  325. function isLeaf(rData){
  326. if (curFileType === uploadType.general) {
  327. // 通用表:项目编码12位且有单位的
  328. const code = rData[colMapping.code] ? _deESC(rData[colMapping.code]['value']) : '';
  329. const unit = rData[colMapping.unit] ? _deESC(rData[colMapping.unit]['value']) : '';
  330. return _isDef(code) && /\w{12}/.test(code) && _isDef(unit);
  331. } else {
  332. // 09、广联达表:有序号
  333. const serialNo = rData[colMapping.serialNo] ? _deESC(rData[colMapping.serialNo]['value']) : '';
  334. return _isDef(serialNo);
  335. }
  336. }
  337. //续数据:1. 前数据有效 2.无序号 3.无编码 4.有名称或特征
  338. function isExtend(preData, rData){
  339. if (curFileType === uploadType.general) {
  340. // 通用表:1. 前数据有效 2.无编码 3.无单位 4.有名称或特征
  341. let code = rData[colMapping.code] ? _deESC(rData[colMapping.code]['value']) : '';
  342. let unit = rData[colMapping.unit] ? _deESC(rData[colMapping.unit]['value']) : '';
  343. let name = rData[colMapping.name] ? _deESC(rData[colMapping.name]['value']) : '';
  344. let itemCharacterText = rData[colMapping.itemCharacterText] ? _deESC(rData[colMapping.itemCharacterText]['value']) : '';
  345. return _isDef(preData) && (isRoot(preData) || isLeaf(preData)) && !_isDef(unit) && !_isDef(code) && (_isDef(name) || _isDef(itemCharacterText));
  346. } else {
  347. // 09、广联达表:1. 前数据有效 2.无序号 3.无编码 4.有名称或特征
  348. let serialNo = rData[colMapping.serialNo] ? _deESC(rData[colMapping.serialNo]['value']) : '';
  349. let code = rData[colMapping.code] ? _deESC(rData[colMapping.code]['value']) : '';
  350. let name = rData[colMapping.name] ? _deESC(rData[colMapping.name]['value']) : '';
  351. let itemCharacterText = rData[colMapping.itemCharacterText] ? _deESC(rData[colMapping.itemCharacterText]['value']) : '';
  352. return _isDef(preData) && (isRoot(preData) || isLeaf(preData)) && !_isDef(serialNo) && !_isDef(code) && (_isDef(name) || _isDef(itemCharacterText));
  353. }
  354. }
  355. function getBillType(rData, flag){
  356. if(flag === fixedFlag.CONSTRUCTION_TECH || flag === fixedFlag.CONSTRUCTION_ORGANIZATION){
  357. return billType.BILL;
  358. }
  359. else if(flag === fixedFlag.SUB_ENGINERRING){
  360. return isLeaf(rData) ? billType.FX : billType.FB;
  361. }
  362. return null;
  363. }
  364. let preData = null;
  365. for(let r = 0; r < validData.length; r++){
  366. let rData = validData[r];
  367. if(flag == fixedFlag.CONSTRUCTION_TECH && rData[colMapping.name] && rData[colMapping.name]['value'] === '施工技术措施项目'
  368. || flag == fixedFlag.CONSTRUCTION_ORGANIZATION && rData[colMapping.name] && rData[colMapping.name]['value'] === '施工组织措施项目'){
  369. continue;
  370. }
  371. //过滤无效数据
  372. if(!isRoot(rData) && !isLeaf(rData) && !isExtend(preData, rData)){
  373. continue;
  374. }
  375. if(isExtend(preData, rData)){
  376. let preBill = billIdx[preID];
  377. if(preBill){
  378. //合并续数据
  379. preBill.code += rData[colMapping.code] && rData[colMapping.code]['value'] && _isDef(_deESC(rData[colMapping.code]['value'])) ? rData[colMapping.code]['value'] : '';
  380. preBill.name += rData[colMapping.name] && rData[colMapping.name]['value'] && _isDef(_deESC(rData[colMapping.name]['value'])) ? rData[colMapping.name]['value'] : '';
  381. preBill.itemCharacterText += rData[colMapping.itemCharacterText] && rData[colMapping.itemCharacterText]['value'] && _isDef(_deESC(rData[colMapping.itemCharacterText]['value']))
  382. ? '\n' + _deNR(rData[colMapping.itemCharacterText]['value']) : '';
  383. preBill.unit += rData[colMapping.unit] && rData[colMapping.unit]['value'] && _isDef(_deESC(rData[colMapping.unit]['value'])) ? rData[colMapping.unit]['value'] : '';
  384. preBill.quantity += rData[colMapping.quantity] && rData[colMapping.quantity]['value'] && _isDef(_deESC(rData[colMapping.quantity]['value'])) ? rData[colMapping.quantity]['value'] : '';
  385. }
  386. } else {
  387. let newID = uuid.v1();
  388. let pID = -1;
  389. let preBill = null;
  390. let preRoot = null,
  391. preLeaf = null;
  392. let nodeType = 'root';//后端以此标记来设置ParentID
  393. let preSerialBill = billIdx[preID];
  394. if(isRoot(rData)){
  395. //pID = 'fixedBillID';
  396. preBill = billIdx[preRootID];
  397. preRoot = billIdx[preRootID];
  398. } else if(isLeaf(rData)){
  399. nodeType = 'leaf';
  400. //pID = preRootID !== -1 ? preRootID : fixedBill.ID;
  401. preBill = billIdx[preLeafID];
  402. preLeaf = billIdx[preLeafID];
  403. }
  404. //set bill data
  405. billIdx[newID] = {
  406. nodeType: nodeType,
  407. ID: newID, ParentID: pID, NextSiblingID: -1,
  408. code: rData[colMapping.code] && rData[colMapping.code]['value'] ? _deESC(rData[colMapping.code]['value']) : '',
  409. name: rData[colMapping.name] && rData[colMapping.name]['value'] ? _deESC(rData[colMapping.name]['value']) : '',
  410. itemCharacterText: rData[colMapping.itemCharacterText] && rData[colMapping.itemCharacterText]['value'] ? _deNR(rData[colMapping.itemCharacterText]['value']) : '',
  411. itemCharacter: [],
  412. jobContentText: '',
  413. jobContent: [],
  414. programID: null,
  415. unit: rData[colMapping.unit] && rData[colMapping.unit]['value'] ? _deESC(rData[colMapping.unit]['value']) : '',
  416. quantity: rData[colMapping.quantity] && rData[colMapping.quantity]['value'] ? _deESC(rData[colMapping.quantity]['value']) : '',
  417. quantityEXP: rData[colMapping.quantity] && rData[colMapping.quantity]['value'] ? _deESC(rData[colMapping.quantity]['value']) : '',
  418. //安全文明
  419. flags: flag === fixedFlag.CONSTRUCTION_ORGANIZATION && (rData[colMapping.name] && (rData[colMapping.name]['value'] === '安全文明施工专项费用' || rData[colMapping.name]['value'] === '安全文明施工费')) ?
  420. [{fieldName: 'fixed', flag: fixedFlag.SAFETY_CONSTRUCTION}] : [],
  421. fees: [],
  422. projectID: projectID,
  423. type: getBillType(rData, flag)};
  424. //update preBill NextSibling
  425. if(nodeType === 'root' && preRoot){
  426. preRoot.NextSiblingID = newID;
  427. } else if(nodeType === 'leaf' && preLeaf && preSerialBill && preSerialBill.nodeType === preLeaf.nodeType){
  428. preLeaf.NextSiblingID = newID;
  429. }
  430. /* if(preBill){
  431. preBill.NextSiblingID = newID;
  432. }*/
  433. //set new preID
  434. preID = newID;
  435. preRootID = isRoot(rData) ? newID : preRootID;
  436. preLeafID = isLeaf(rData) ? newID : preLeafID;
  437. }
  438. preData = rData;
  439. }
  440. for(let i in billIdx){
  441. rst.push(billIdx[i]);
  442. }
  443. return rst;
  444. }
  445. /* function parseToBillData(validData, colMapping, flag, projectID){
  446. let rst = [];
  447. let billIdx = {};
  448. let preRootID = -1,
  449. preLeafID = -1,
  450. preID = -1;
  451. //父节点:1.无序号 2有编码
  452. function isRoot(rData){
  453. //序号和编码去除转义字符(有的表格单元格看起来是没数据,实际含有\r,\n等数据)
  454. let serialNo = rData[colMapping.serialNo] ? _deESC(rData[colMapping.serialNo]['value']) : '';
  455. let code = rData[colMapping.code] ? _deESC(rData[colMapping.code]['value']) : '';
  456. return !_isDef(serialNo) && _isDef(code);
  457. }
  458. //子节点:有序号
  459. function isLeaf(rData){
  460. let serialNo = rData[colMapping.serialNo] ? _deESC(rData[colMapping.serialNo]['value']) : '';
  461. return _isDef(serialNo);
  462. }
  463. //续数据:1. 前数据有效 2.无序号 3.无编码 4.有名称或特征
  464. function isExtend(preData, rData){
  465. let serialNo = rData[colMapping.serialNo] ? _deESC(rData[colMapping.serialNo]['value']) : '';
  466. let code = rData[colMapping.code] ? _deESC(rData[colMapping.code]['value']) : '';
  467. let name = rData[colMapping.name] ? _deESC(rData[colMapping.name]['value']) : '';
  468. let itemCharacterText = rData[colMapping.itemCharacterText] ? _deESC(rData[colMapping.itemCharacterText]['value']) : '';
  469. return _isDef(preData) && (isRoot(preData) || isLeaf(preData)) && !_isDef(serialNo) && !_isDef(code) && (_isDef(name) || _isDef(itemCharacterText));
  470. }
  471. function getBillType(rData, flag){
  472. if(flag === fixedFlag.CONSTRUCTION_TECH || flag === fixedFlag.CONSTRUCTION_ORGANIZATION){
  473. return billType.BILL;
  474. }
  475. else if(flag === fixedFlag.SUB_ENGINERRING){
  476. return isLeaf(rData) ? billType.FX : billType.FB;
  477. }
  478. return null;
  479. }
  480. let preData = null;
  481. for(let r = 0; r < validData.length; r++){
  482. let rData = validData[r];
  483. if(flag == fixedFlag.CONSTRUCTION_TECH && rData[colMapping.name] && rData[colMapping.name]['value'] === '施工技术措施项目'
  484. || flag == fixedFlag.CONSTRUCTION_ORGANIZATION && rData[colMapping.name] && rData[colMapping.name]['value'] === '施工组织措施项目'){
  485. continue;
  486. }
  487. //过滤无效数据
  488. if(!isRoot(rData) && !isLeaf(rData) && !isExtend(preData, rData)){
  489. continue;
  490. }
  491. if(isExtend(preData, rData)){
  492. let preBill = billIdx[preID];
  493. if(preBill){
  494. //合并续数据
  495. preBill.code += rData[colMapping.code] && rData[colMapping.code]['value'] && _isDef(_deESC(rData[colMapping.code]['value'])) ? rData[colMapping.code]['value'] : '';
  496. preBill.name += rData[colMapping.name] && rData[colMapping.name]['value'] && _isDef(_deESC(rData[colMapping.name]['value'])) ? rData[colMapping.name]['value'] : '';
  497. preBill.itemCharacterText += rData[colMapping.itemCharacterText] && rData[colMapping.itemCharacterText]['value'] && _isDef(_deESC(rData[colMapping.itemCharacterText]['value']))
  498. ? '\n' + _deNR(rData[colMapping.itemCharacterText]['value']) : '';
  499. preBill.unit += rData[colMapping.unit] && rData[colMapping.unit]['value'] && _isDef(_deESC(rData[colMapping.unit]['value'])) ? rData[colMapping.unit]['value'] : '';
  500. preBill.quantity += rData[colMapping.quantity] && rData[colMapping.quantity]['value'] && _isDef(_deESC(rData[colMapping.quantity]['value'])) ? rData[colMapping.quantity]['value'] : '';
  501. }
  502. }
  503. else {
  504. let newID = uuid.v1();
  505. let pID = -1;
  506. let preBill = null;
  507. let preRoot = null,
  508. preLeaf = null;
  509. let nodeType = 'root';//后端以此标记来设置ParentID
  510. let preSerialBill = billIdx[preID];
  511. if(isRoot(rData)){
  512. //pID = 'fixedBillID';
  513. preBill = billIdx[preRootID];
  514. preRoot = billIdx[preRootID];
  515. }
  516. else if(isLeaf(rData)){
  517. nodeType = 'leaf';
  518. //pID = preRootID !== -1 ? preRootID : fixedBill.ID;
  519. preBill = billIdx[preLeafID];
  520. preLeaf = billIdx[preLeafID];
  521. }
  522. //set bill data
  523. billIdx[newID] = {
  524. nodeType: nodeType,
  525. ID: newID, ParentID: pID, NextSiblingID: -1,
  526. code: rData[colMapping.code] && rData[colMapping.code]['value'] ? _deESC(rData[colMapping.code]['value']) : '',
  527. name: rData[colMapping.name] && rData[colMapping.name]['value'] ? _deESC(rData[colMapping.name]['value']) : '',
  528. itemCharacterText: rData[colMapping.itemCharacterText] && rData[colMapping.itemCharacterText]['value'] ? _deNR(rData[colMapping.itemCharacterText]['value']) : '',
  529. itemCharacter: [],
  530. jobContentText: '',
  531. jobContent: [],
  532. programID: null,
  533. unit: rData[colMapping.unit] && rData[colMapping.unit]['value'] ? _deESC(rData[colMapping.unit]['value']) : '',
  534. quantity: rData[colMapping.quantity] && rData[colMapping.quantity]['value'] ? _deESC(rData[colMapping.quantity]['value']) : '',
  535. quantityEXP: rData[colMapping.quantity] && rData[colMapping.quantity]['value'] ? _deESC(rData[colMapping.quantity]['value']) : '',
  536. //安全文明
  537. flags: flag === fixedFlag.CONSTRUCTION_ORGANIZATION && (rData[colMapping.name] && (rData[colMapping.name]['value'] === '安全文明施工专项费用' || rData[colMapping.name]['value'] === '安全文明施工费')) ?
  538. [{fieldName: 'fixed', flag: fixedFlag.SAFETY_CONSTRUCTION}] : [],
  539. fees: [],
  540. projectID: projectID,
  541. type: getBillType(rData, flag)};
  542. //update preBill NextSibling
  543. if(nodeType === 'root' && preRoot){
  544. preRoot.NextSiblingID = newID;
  545. }
  546. else if(nodeType === 'leaf' && preLeaf && preSerialBill && preSerialBill.nodeType === preLeaf.nodeType){
  547. preLeaf.NextSiblingID = newID;
  548. }
  549. //set new preID
  550. preID = newID;
  551. preRootID = isRoot(rData) ? newID : preRootID;
  552. preLeafID = isLeaf(rData) ? newID : preLeafID;
  553. }
  554. preData = rData;
  555. }
  556. for(let i in billIdx){
  557. rst.push(billIdx[i]);
  558. }
  559. return rst;
  560. } */
  561. function getImportData(validSheets, projectID){
  562. let rst = {fbfx: [], jscsxm: [], zzcsxm: []};
  563. let validSheetsDatas = [];
  564. for(let uploadPosition in validSheets){
  565. let validExcelData = [];
  566. for(let uSheet of validSheets[uploadPosition]){
  567. validExcelData = validExcelData.concat(getValidImportData(uSheet.colMapping, uSheet.data.dataTable));
  568. }
  569. if(validSheets[uploadPosition].length > 0){
  570. validSheetsDatas.push({position: uploadPosition, colMapping: validSheets[uploadPosition][0].colMapping, validExcelData: validExcelData});
  571. }
  572. }
  573. for(let validSheetData of validSheetsDatas){
  574. if(validSheetData.validExcelData.length > 0){
  575. rst[validSheetData.position] = parseToBillData(validSheetData.validExcelData, validSheetData.colMapping, positionFlag[validSheetData.position], projectID);
  576. }
  577. }
  578. return rst;
  579. }
  580. function excelHasValidBills(importBillsData){
  581. for(let i in importBillsData){
  582. if(importBillsData[i].length > 0){
  583. return true;
  584. }
  585. }
  586. return false;
  587. }
  588. return {setImportSheetsInfo, getImportSheetsInfo, getImportSheets, getImportData, excelHasValidBills}
  589. })();