|
|
@@ -26,430 +26,215 @@ const importBills = (function(){
|
|
|
function _deNR(data) {
|
|
|
return _isDef(data) ? data.toString().replace(/\r\r/g, '\r') : data;
|
|
|
}
|
|
|
-
|
|
|
- //列名对应中文字符
|
|
|
- const colText = {
|
|
|
- serialNo: ['序号'],
|
|
|
- code: ['编码', '项目编码'],
|
|
|
- name: ['名称', '项目名称'],
|
|
|
- itemCharacterText: ['特征', '项目特征', '项目特征描述'],
|
|
|
- unit: ['单位', '计量单位'],
|
|
|
- quantity: ['工程量', '项目工程量'],
|
|
|
- money: ['金额'],
|
|
|
- quantityDetail: ['工程量明细'],
|
|
|
- feeDetail: ['费用明细'],
|
|
|
- summation: ['合计', '本页小计'],
|
|
|
- };
|
|
|
-
|
|
|
- //导入位置对应清单固定标记
|
|
|
- const positionFlag = {
|
|
|
- fbfx: fixedFlag.SUB_ENGINERRING,
|
|
|
- jscsxm: fixedFlag.CONSTRUCTION_TECH,
|
|
|
- zzcsxm: fixedFlag.CONSTRUCTION_ORGANIZATION,
|
|
|
- };
|
|
|
-
|
|
|
- //上传类型
|
|
|
- const uploadType = {
|
|
|
- lj: 'lj',
|
|
|
- gld: 'gld',
|
|
|
- };
|
|
|
-
|
|
|
- //设置导入表内容(选择导入位置)
|
|
|
- //@param {Object}workBook
|
|
|
- function setImportSheetsInfo(sheets){
|
|
|
- let sheetNames = [];
|
|
|
- let indexMapping = {};
|
|
|
- for(let sheetName in sheets){
|
|
|
- indexMapping[sheets[sheetName]['index']] = sheetName;
|
|
|
- }
|
|
|
- let sheetsCount = Object.keys(sheets).length;
|
|
|
- for(let i = 0; i < sheetsCount; i++){
|
|
|
- sheetNames.push(indexMapping[i]);
|
|
|
- }
|
|
|
- let sheetArea = $('#uploadSheets'),
|
|
|
- sheetHeader = $('#uploadSheetsHead');
|
|
|
- $('#uploadSheets').height('');
|
|
|
- sheetArea.empty();
|
|
|
- for(let sheetName of sheetNames){
|
|
|
- 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">
|
|
|
- <input class="form-check-input" type="checkbox">${sheetName}</label></div>`);
|
|
|
- sheetDiv.find('input[type="checkbox"]').click(function () {
|
|
|
- if($('#uploadAlert').is(':visible')){
|
|
|
- $('#uploadAlert').hide();
|
|
|
- }
|
|
|
- });
|
|
|
- let sel = $(`<select style="margin-left: 5px; border-radius: .20rem;"><option value="fbfx">分部分项工程</option><option value="zzcsxm">施工组织措施项目</option><option value="jscsxm">施工技术措施项目</option></select>`);
|
|
|
- if(sheetName.includes('分部分项工程项目清单计价表')){
|
|
|
- sheetDiv.find('input[type="checkbox"]').prop('checked', true);
|
|
|
- sel.find('option:eq(0)').prop('selected', true);
|
|
|
- }
|
|
|
- else if(sheetName.includes('施工组织措施项目清单计价表')){
|
|
|
- sheetDiv.find('input[type="checkbox"]').prop('checked', true);
|
|
|
- sel.find('option:eq(1)').prop('selected', true);
|
|
|
- }
|
|
|
- else if(sheetName.includes('施工技术措施项目清单计价表')){
|
|
|
- sheetDiv.find('input[type="checkbox"]').prop('checked', true);
|
|
|
- sel.find('option:eq(2)').prop('selected', true);
|
|
|
- }
|
|
|
- sheetDiv.append(sel);
|
|
|
- sheetArea.append(sheetDiv);
|
|
|
-
|
|
|
- }
|
|
|
- if(sheetNames.length > 0){
|
|
|
- sheetArea.show();
|
|
|
- sheetHeader.show();
|
|
|
- }
|
|
|
- if($('#uploadSheets').height() > 250){
|
|
|
- sheetArea.css('overflow', 'auto');
|
|
|
- sheetArea.height(250);
|
|
|
- }
|
|
|
- else {
|
|
|
- sheetArea.css('overflow', 'hidden');
|
|
|
+ //find 返回最后匹配
|
|
|
+ function findLast(datas, func) {
|
|
|
+ let filter = datas.filter(func);
|
|
|
+ if (filter.length > 0) {
|
|
|
+ return filter[filter.length - 1];
|
|
|
}
|
|
|
+ return null;
|
|
|
}
|
|
|
-
|
|
|
- //获得选择导入的表信息(表索引及导入位置)
|
|
|
- //@return {Object}
|
|
|
- function getImportSheetsInfo(){
|
|
|
- let rst = [];
|
|
|
- let sheetArea = $('#uploadSheets');
|
|
|
- let checkedInputs = sheetArea.find('input:checked');
|
|
|
- for(let checked of checkedInputs){
|
|
|
- rst.push({index: $(checked).parent().parent().index(), position: $(checked).parent().next().select().val()})
|
|
|
+ const fileType = {
|
|
|
+ gcl: 0, //工程量清单
|
|
|
+ qdsl: 1 //清单示例
|
|
|
+ };
|
|
|
+ //获取列字段对应
|
|
|
+ function getColMapping(type){
|
|
|
+ if (type === 0) { //工程量清单
|
|
|
+ return {code: 0, name: 1, unit: 2, quantity: 4};
|
|
|
+ } else { //清单示例表
|
|
|
+ return {code: 0, name: 1, unit: 2, quantity: 3};
|
|
|
}
|
|
|
- return rst;
|
|
|
}
|
|
|
-
|
|
|
- function getSheetByIndex(sheets, index){
|
|
|
- for(let sheetName in sheets){
|
|
|
- let sheet = sheets[sheetName];
|
|
|
- if(sheet.index === index){
|
|
|
- return sheet;
|
|
|
+ function isGCLHead(dataRow) {
|
|
|
+ let cell = dataRow[0];
|
|
|
+ return cell.value === '工程量清单';
|
|
|
+ }
|
|
|
+ //分析文件,1、工程量清单 2、清单示例表
|
|
|
+ function getFileType(sheetData) {
|
|
|
+ let dataTable = sheetData.data.dataTable,
|
|
|
+ rowCount = sheetData.rowCount;
|
|
|
+ for (let row = 0; row < rowCount; row++) {
|
|
|
+ if (isGCLHead(dataTable[row])) {
|
|
|
+ return fileType.gcl;
|
|
|
}
|
|
|
}
|
|
|
- return null;
|
|
|
+ return fileType.qdsl;
|
|
|
}
|
|
|
-
|
|
|
- //提取excel表头列名与列下标映射
|
|
|
- //@
|
|
|
- function getColMapping(dataTable){
|
|
|
- //获取表头
|
|
|
- function getHeadRow(dataTable){
|
|
|
- for(let rowIdx in dataTable ){
|
|
|
- for(let colIdx in dataTable[rowIdx]){
|
|
|
- let cellData = dataTable[rowIdx][colIdx]['value'];
|
|
|
- if(cellData && _deESC(cellData) === colText.serialNo[0]){
|
|
|
- return dataTable[rowIdx];
|
|
|
+ //提取工程量清单数据
|
|
|
+ //层级由depth确定,表格里最顶层depth为0(表头里一清单),表格内容里数据的depth为空格数+1
|
|
|
+ function extractGCLDatas(sheetData, colMapping) {
|
|
|
+ //let colMapping = {code: 0, name: 1, unit: 2, quantity: 4};
|
|
|
+ let dataTable = sheetData.data.dataTable,
|
|
|
+ rowCount = sheetData.rowCount;
|
|
|
+ let rst = [];
|
|
|
+ for (let row = 0; row < rowCount; row++) {
|
|
|
+ //表格中顶层节点
|
|
|
+ if (isGCLHead(dataTable[row])) {
|
|
|
+ let rootRow = dataTable[row + 2];
|
|
|
+ let name = rootRow[0].value;
|
|
|
+ let existsRoot = findLast(rst, x => x.name === name && x.depth === 0);
|
|
|
+ if (!existsRoot) {
|
|
|
+ let root = {ID: uuid.v1(), NextSiblingID: -1, ParentID: -1, name: name, depth: 0, parent: null};
|
|
|
+ let preData = findLast(rst, x => x.depth === root.depth);
|
|
|
+ if (preData) {
|
|
|
+ preData.NextSiblingID = root.ID;
|
|
|
}
|
|
|
+ rst.push(root);
|
|
|
}
|
|
|
- }
|
|
|
- return {};
|
|
|
- }
|
|
|
- //获取需要的表头列与列号对应关系
|
|
|
- let colMapping = {};
|
|
|
- let headRow = getHeadRow(dataTable);
|
|
|
- for(let colIdx in headRow){
|
|
|
- let cellData = headRow[colIdx]['value'];
|
|
|
- if(!_isDef(cellData)){
|
|
|
+ row += 3;
|
|
|
continue;
|
|
|
}
|
|
|
- //序号
|
|
|
- if(colMapping.serialNo === undefined && _deESC(cellData) === colText.serialNo[0]){
|
|
|
- colMapping.serialNo = colIdx;
|
|
|
- }
|
|
|
- //编码
|
|
|
- else if(colMapping.code === undefined && (_deESC(cellData) === colText.code[0] || _deESC(cellData) === colText.code[1])){
|
|
|
- colMapping.code = colIdx;
|
|
|
- }
|
|
|
- //名称
|
|
|
- else if(colMapping.name === undefined && (_deESC(cellData) === colText.name[0] || _deESC(cellData) === colText.name[1])){
|
|
|
- colMapping.name = colIdx;
|
|
|
- }
|
|
|
- //项目特征
|
|
|
- else if(colMapping.itemCharacterText === undefined && (_deESC(cellData) === colText.itemCharacterText[0] || _deESC(cellData) === colText.itemCharacterText[1]
|
|
|
- || _deESC(cellData) === colText.itemCharacterText[2])){
|
|
|
- colMapping.itemCharacterText = colIdx;
|
|
|
- }
|
|
|
- //单位
|
|
|
- else if(colMapping.unit === undefined && (_deESC(cellData) === colText.unit[0] || _deESC(cellData) === colText.unit[1])){
|
|
|
- colMapping.unit = colIdx;
|
|
|
- }
|
|
|
- //工程量
|
|
|
- else if(colMapping.quantity === undefined && (_deESC(cellData) === colText.quantity[0] || _deESC(cellData) === colText.quantity[1])){
|
|
|
- colMapping.quantity = colIdx;
|
|
|
- }
|
|
|
- //金额
|
|
|
- else if(colMapping.money === undefined && _deESC(cellData).includes(colText.money[0])){
|
|
|
- colMapping.money = colIdx;
|
|
|
- }
|
|
|
- //工程量明细
|
|
|
- else if(colMapping.quantityDetail === undefined && _deESC(cellData) === colText.quantityDetail[0]){
|
|
|
- colMapping.quantityDetail = colIdx;
|
|
|
- }
|
|
|
- //费用明细
|
|
|
- else if(colMapping.feeDetail === undefined && _deESC(cellData) === colText.feeDetail[0]){
|
|
|
- colMapping.feeDetail = colIdx;
|
|
|
- }
|
|
|
- }
|
|
|
- return colMapping;
|
|
|
- }
|
|
|
-
|
|
|
- //是否是有效的表头列格式,只要含有各表需要的列就行,不严格控制多少列
|
|
|
- function isValidSheet(colMapping, fileType){
|
|
|
- function hasField(field, all){
|
|
|
- for(let i of all){
|
|
|
- if(field === i){
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
- let needFields;
|
|
|
- if(fileType === uploadType.lj){
|
|
|
- //09表:序号、项目编码、项目名称、项目特征、计量单位、工程量、金额
|
|
|
- needFields = ['serialNo', 'code', 'name', 'money'];
|
|
|
- }
|
|
|
- else {
|
|
|
- //广联达表:序号、项目编码、项目名称、项目特征、计量单位、工程量、工程量明细、费用明细
|
|
|
- needFields = ['serialNo', 'code', 'name', 'itemCharacterText', 'unit', 'quantity', 'quantityDetail', 'feeDetail'];
|
|
|
- }
|
|
|
- let hasFieldCount = 0;
|
|
|
- for(let attr in colMapping){
|
|
|
- if(hasField(attr, needFields)){
|
|
|
- hasFieldCount++;
|
|
|
- }
|
|
|
- }
|
|
|
- return hasFieldCount === needFields.length;
|
|
|
- }
|
|
|
-
|
|
|
- //获取要无效和有效导入表
|
|
|
- //@param {Array}importSheetInfo 勾选要导入的表
|
|
|
- function getImportSheets(sheets, sheetsInfo, fileType){
|
|
|
- let rst = {invalidSheets: [], validSheets: {fbfx: [], jscsxm: [], zzcsxm: []}};
|
|
|
-
|
|
|
- for(let sheetInfo of sheetsInfo){
|
|
|
- let sheet = getSheetByIndex(sheets, sheetInfo.index);
|
|
|
- if(!sheet){
|
|
|
- continue;
|
|
|
- }
|
|
|
- //没有数据
|
|
|
- if(!sheet.data.dataTable){
|
|
|
- rst.invalidSheets.push(sheet.name);
|
|
|
+ let code = dataTable[row][colMapping.code] ? dataTable[row][colMapping.code].value : null,
|
|
|
+ name = dataTable[row][colMapping.name] ? dataTable[row][colMapping.name].value : null,
|
|
|
+ unit = dataTable[row][colMapping.unit] ? dataTable[row][colMapping.unit].value : null,
|
|
|
+ quantity = dataTable[row][colMapping.quantity] ? dataTable[row][colMapping.quantity].value : null;
|
|
|
+ if (!code && !name || /合计/.test(code)) { //过滤掉同时没有编号和名称的、过滤合计行
|
|
|
continue;
|
|
|
}
|
|
|
- //获取表的列设置确定导入的格式是否合法(09、广联达)
|
|
|
- let colMapping = getColMapping(sheet.data.dataTable);
|
|
|
- if(!isValidSheet(colMapping, fileType)){
|
|
|
- rst.invalidSheets.push(sheet.name);
|
|
|
- continue;
|
|
|
- }
|
|
|
- //合法的表
|
|
|
- sheet.colMapping = colMapping;
|
|
|
- //将合法的表按导入位置分类当做一个表来处理
|
|
|
- if(rst.validSheets[sheetInfo.position] !== undefined){
|
|
|
- rst.validSheets[sheetInfo.position].push(sheet)
|
|
|
+ //表格内的数据
|
|
|
+ let depth = getDepth(code);
|
|
|
+ let data = {ID: uuid.v1(), NextSiblingID: -1, ParentID: -1, code: code, name: name, unit: unit, quantity: quantity, depth: depth};
|
|
|
+ let lastData = rst[rst.length - 1];
|
|
|
+ //获取data的父节点链,成为兄弟节点,只能在父链里找前兄弟(不能跨父链)
|
|
|
+ let parents = getParents(lastData);
|
|
|
+ let preData = findLast(parents, x => x.depth === depth);
|
|
|
+ if (preData) {
|
|
|
+ preData.NextSiblingID = data.ID;
|
|
|
+ data.ParentID = preData.ParentID;
|
|
|
+ data.parent = preData.parent;
|
|
|
+ } else {
|
|
|
+ data.ParentID = lastData.ID;
|
|
|
+ data.parent = lastData;
|
|
|
+ }
|
|
|
+ rst.push(data);
|
|
|
+
|
|
|
+ }
|
|
|
+ console.log(rst);
|
|
|
+ return rst;
|
|
|
+ function getDepth(code) {
|
|
|
+ if (!code) {
|
|
|
+ return 1;
|
|
|
}
|
|
|
+ let match = code.match(/\s/g);
|
|
|
+ return match ? match.length + 1 : 1;
|
|
|
}
|
|
|
- return rst;
|
|
|
}
|
|
|
|
|
|
- //行存在数据
|
|
|
- function rowExistData(rowData){
|
|
|
- for(let colIdx in rowData){
|
|
|
- let colData = rowData[colIdx]['value'];
|
|
|
- if(_isDef(colData)){
|
|
|
- return true;
|
|
|
- }
|
|
|
+ function getParents(data) {
|
|
|
+ let rst = [];
|
|
|
+ let parent = data.parent;
|
|
|
+ while (parent) {
|
|
|
+ rst.push(parent);
|
|
|
+ parent = parent.parent;
|
|
|
}
|
|
|
- return false;
|
|
|
+ rst.push(data);
|
|
|
+ return rst;
|
|
|
}
|
|
|
|
|
|
- //提取excel表数据中的有效数据(去表头表尾,提取其中的excel数据)(根据fixedBill获取栏头占行数)
|
|
|
- function getValidImportData(colMapping, sheetData){
|
|
|
- let withingD = false;
|
|
|
- let validData = [];
|
|
|
- function isHead(rData){
|
|
|
- return rData[colMapping.serialNo] && _deESC(rData[colMapping.serialNo]['value']) === colText.serialNo[0];
|
|
|
- }
|
|
|
- function isTail(rowData){
|
|
|
- for(let colIdx in rowData){
|
|
|
- let colData = rowData[colIdx]['value'];
|
|
|
- if(colData){
|
|
|
- let trimColData= _deESC(colData);
|
|
|
- if(trimColData === colText.summation[0] || trimColData === colText.summation[1]){
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
- for(let rowIdx in sheetData){
|
|
|
- let rowData = sheetData[rowIdx];
|
|
|
- if(isHead(rowData)){
|
|
|
- withingD = true;
|
|
|
- continue;
|
|
|
- }
|
|
|
- else if(isTail(rowData)){
|
|
|
- withingD = false;
|
|
|
- }
|
|
|
- if(withingD && rowExistData(rowData)){
|
|
|
- validData.push(rowData);
|
|
|
- }
|
|
|
+ //获取编号前缀: 101-1 => 101 101-1-1 => 101-1
|
|
|
+ function getPrefix(v) {
|
|
|
+ if (!v) {
|
|
|
+ return null;
|
|
|
}
|
|
|
- return validData;
|
|
|
+ let reg = /(.*)-/;
|
|
|
+ let match = reg.exec(v);
|
|
|
+ return match ? match[1] : null;
|
|
|
}
|
|
|
|
|
|
- //excel数据转换成清单数据
|
|
|
- function parseToBillData(validData, colMapping, flag, projectID){
|
|
|
+ //提取清单示例数据
|
|
|
+ function extractSLDatas(sheetData) {
|
|
|
+ let colMapping = {code: 0, name: 1, unit: 2, quantity: 3};
|
|
|
+ let dataTable = sheetData.data.dataTable,
|
|
|
+ rowCount = sheetData.rowCount;
|
|
|
let rst = [];
|
|
|
- let billIdx = {};
|
|
|
- let preRootID = -1,
|
|
|
- preLeafID = -1,
|
|
|
- preID = -1;
|
|
|
- //父节点:1.无序号 2有编码
|
|
|
- function isRoot(rData){
|
|
|
- //序号和编码去除转义字符(有的表格单元格看起来是没数据,实际含有\r,\n等数据)
|
|
|
- let serialNo = rData[colMapping.serialNo] ? _deESC(rData[colMapping.serialNo]['value']) : '';
|
|
|
- let code = rData[colMapping.code] ? _deESC(rData[colMapping.code]['value']) : '';
|
|
|
- return !_isDef(serialNo) && _isDef(code);
|
|
|
- }
|
|
|
- //子节点:有序号
|
|
|
- function isLeaf(rData){
|
|
|
- let serialNo = rData[colMapping.serialNo] ? _deESC(rData[colMapping.serialNo]['value']) : '';
|
|
|
- return _isDef(serialNo);
|
|
|
- }
|
|
|
- //续数据:1. 前数据有效 2.无序号 3.无编码 4.有名称或特征
|
|
|
- function isExtend(preData, rData){
|
|
|
- let serialNo = rData[colMapping.serialNo] ? _deESC(rData[colMapping.serialNo]['value']) : '';
|
|
|
- let code = rData[colMapping.code] ? _deESC(rData[colMapping.code]['value']) : '';
|
|
|
- let name = rData[colMapping.name] ? _deESC(rData[colMapping.name]['value']) : '';
|
|
|
- let itemCharacterText = rData[colMapping.itemCharacterText] ? _deESC(rData[colMapping.itemCharacterText]['value']) : '';
|
|
|
- return _isDef(preData) && (isRoot(preData) || isLeaf(preData)) && !_isDef(serialNo) && !_isDef(code) && (_isDef(name) || _isDef(itemCharacterText));
|
|
|
- }
|
|
|
- function getBillType(rData, flag){
|
|
|
- if(flag === fixedFlag.CONSTRUCTION_TECH || flag === fixedFlag.CONSTRUCTION_ORGANIZATION){
|
|
|
- return billType.BILL;
|
|
|
- }
|
|
|
- else if(flag === fixedFlag.SUB_ENGINERRING){
|
|
|
- return isLeaf(rData) ? billType.FX : billType.FB;
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
- let preData = null;
|
|
|
- for(let r = 0; r < validData.length; r++){
|
|
|
- let rData = validData[r];
|
|
|
- if(flag == fixedFlag.CONSTRUCTION_TECH && rData[colMapping.name] && rData[colMapping.name]['value'] === '施工技术措施项目'
|
|
|
- || flag == fixedFlag.CONSTRUCTION_ORGANIZATION && rData[colMapping.name] && rData[colMapping.name]['value'] === '施工组织措施项目'){
|
|
|
- continue;
|
|
|
- }
|
|
|
- //过滤无效数据
|
|
|
- if(!isRoot(rData) && !isLeaf(rData) && !isExtend(preData, rData)){
|
|
|
- continue;
|
|
|
- }
|
|
|
- if(isExtend(preData, rData)){
|
|
|
- let preBill = billIdx[preID];
|
|
|
- if(preBill){
|
|
|
- //合并续数据
|
|
|
- preBill.code += rData[colMapping.code] && rData[colMapping.code]['value'] && _isDef(_deESC(rData[colMapping.code]['value'])) ? rData[colMapping.code]['value'] : '';
|
|
|
- preBill.name += rData[colMapping.name] && rData[colMapping.name]['value'] && _isDef(_deESC(rData[colMapping.name]['value'])) ? rData[colMapping.name]['value'] : '';
|
|
|
- preBill.itemCharacterText += rData[colMapping.itemCharacterText] && rData[colMapping.itemCharacterText]['value'] && _isDef(_deESC(rData[colMapping.itemCharacterText]['value']))
|
|
|
- ? '\n' + _deNR(rData[colMapping.itemCharacterText]['value']) : '';
|
|
|
- preBill.unit += rData[colMapping.unit] && rData[colMapping.unit]['value'] && _isDef(_deESC(rData[colMapping.unit]['value'])) ? rData[colMapping.unit]['value'] : '';
|
|
|
- preBill.quantity += rData[colMapping.quantity] && rData[colMapping.quantity]['value'] && _isDef(_deESC(rData[colMapping.quantity]['value'])) ? rData[colMapping.quantity]['value'] : '';
|
|
|
+ let curRoot = null;
|
|
|
+ for (let row = 0; row < rowCount; row++) {
|
|
|
+ let code = dataTable[row][colMapping.code] ? dataTable[row][colMapping.code].value : null,
|
|
|
+ name = dataTable[row][colMapping.name] ? dataTable[row][colMapping.name].value : null,
|
|
|
+ unit = dataTable[row][colMapping.unit] ? dataTable[row][colMapping.unit].value : null,
|
|
|
+ quantity = dataTable[row][colMapping.quantity] ? dataTable[row][colMapping.quantity].value : null;
|
|
|
+ if (!code) { //没有编号的数据,名称必须为:清单 第xx章,认为新的表根节点
|
|
|
+ if (name && /清单 第\d+章/.test(name)) {
|
|
|
+ curRoot = {code: null, name: name, ID: uuid.v1(), ParentID: -1, NextSiblingID: -1, parent: null};
|
|
|
+ rst.push(curRoot);
|
|
|
+ } else {
|
|
|
+ curRoot = null;
|
|
|
}
|
|
|
- }
|
|
|
- else {
|
|
|
- let newID = uuid.v1();
|
|
|
- let pID = -1;
|
|
|
- let preBill = null;
|
|
|
- let preRoot = null,
|
|
|
- preLeaf = null;
|
|
|
- let nodeType = 'root';//后端以此标记来设置ParentID
|
|
|
- let preSerialBill = billIdx[preID];
|
|
|
- if(isRoot(rData)){
|
|
|
- //pID = 'fixedBillID';
|
|
|
- preBill = billIdx[preRootID];
|
|
|
- preRoot = billIdx[preRootID];
|
|
|
- }
|
|
|
- else if(isLeaf(rData)){
|
|
|
- nodeType = 'leaf';
|
|
|
- //pID = preRootID !== -1 ? preRootID : fixedBill.ID;
|
|
|
- preBill = billIdx[preLeafID];
|
|
|
- preLeaf = billIdx[preLeafID];
|
|
|
- }
|
|
|
- //set bill data
|
|
|
- billIdx[newID] = {
|
|
|
- nodeType: nodeType,
|
|
|
- ID: newID, ParentID: pID, NextSiblingID: -1,
|
|
|
- code: rData[colMapping.code] && rData[colMapping.code]['value'] ? _deESC(rData[colMapping.code]['value']) : '',
|
|
|
- name: rData[colMapping.name] && rData[colMapping.name]['value'] ? _deESC(rData[colMapping.name]['value']) : '',
|
|
|
- itemCharacterText: rData[colMapping.itemCharacterText] && rData[colMapping.itemCharacterText]['value'] ? _deNR(rData[colMapping.itemCharacterText]['value']) : '',
|
|
|
- itemCharacter: [],
|
|
|
- jobContentText: '',
|
|
|
- jobContent: [],
|
|
|
- programID: null,
|
|
|
- unit: rData[colMapping.unit] && rData[colMapping.unit]['value'] ? _deESC(rData[colMapping.unit]['value']) : '',
|
|
|
- quantity: rData[colMapping.quantity] && rData[colMapping.quantity]['value'] ? _deESC(rData[colMapping.quantity]['value']) : '',
|
|
|
- quantityEXP: rData[colMapping.quantity] && rData[colMapping.quantity]['value'] ? _deESC(rData[colMapping.quantity]['value']) : '',
|
|
|
- //安全文明
|
|
|
- flags: flag === fixedFlag.CONSTRUCTION_ORGANIZATION && (rData[colMapping.name] && (rData[colMapping.name]['value'] === '安全文明施工专项费用' || rData[colMapping.name]['value'] === '安全文明施工费')) ?
|
|
|
- [{fieldName: 'fixed', flag: fixedFlag.SAFETY_CONSTRUCTION}] : [],
|
|
|
- fees: [],
|
|
|
- projectID: projectID,
|
|
|
- type: getBillType(rData, flag)};
|
|
|
- //update preBill NextSibling
|
|
|
- if(nodeType === 'root' && preRoot){
|
|
|
- preRoot.NextSiblingID = newID;
|
|
|
+ } else if (!curRoot) { //根节点为无效根节点,其下子数据全部过滤掉
|
|
|
+ continue;
|
|
|
+ } else {
|
|
|
+ //有code且有有效表根节点
|
|
|
+ let prefix = getPrefix(code);
|
|
|
+ let data = {
|
|
|
+ code: code,
|
|
|
+ name: name,
|
|
|
+ unit: unit,
|
|
|
+ quantity: quantity,
|
|
|
+ ID: uuid.v1(),
|
|
|
+ NextSiblingID: -1,
|
|
|
+ };
|
|
|
+ let lastData = rst[rst.length - 1];
|
|
|
+ let parents = getParents(lastData);
|
|
|
+ //某数据编号为此数据的前缀,则某数据为此数据的父节点
|
|
|
+ let parentData = findLast(parents, x => prefix === x.code);
|
|
|
+ if (!parentData && prefix === '') { // -x的数据,在父链上找不到编号与prefix相同的数据时,父链上-x的数据,则这两数据为兄弟节点,没有则上一行数据为其父节点
|
|
|
+ let samePrefixData = findLast(parents, x => getPrefix(x.code) === prefix);
|
|
|
+ parentData = samePrefixData ? samePrefixData.parent : lastData;
|
|
|
+ } else if (!parentData && prefix !== '') { //不是-x的数据,在父链上找不到编号与prefix相同的数据时,表根节点为其父节点
|
|
|
+ parentData = curRoot;
|
|
|
}
|
|
|
- else if(nodeType === 'leaf' && preLeaf && preSerialBill && preSerialBill.nodeType === preLeaf.nodeType){
|
|
|
- preLeaf.NextSiblingID = newID;
|
|
|
+ data.ParentID = parentData.ID;
|
|
|
+ data.parent = parentData;
|
|
|
+ let preData = findLast(parents, x => x.ParentID === data.ParentID);
|
|
|
+ if (preData) {
|
|
|
+ preData.NextSiblingID = data.ID;
|
|
|
}
|
|
|
- /* if(preBill){
|
|
|
- preBill.NextSiblingID = newID;
|
|
|
- }*/
|
|
|
- //set new preID
|
|
|
- preID = newID;
|
|
|
- preRootID = isRoot(rData) ? newID : preRootID;
|
|
|
- preLeafID = isLeaf(rData) ? newID : preLeafID;
|
|
|
+ rst.push(data);
|
|
|
}
|
|
|
- preData = rData;
|
|
|
- }
|
|
|
- for(let i in billIdx){
|
|
|
- rst.push(billIdx[i]);
|
|
|
}
|
|
|
+ console.log(rst);
|
|
|
return rst;
|
|
|
}
|
|
|
-
|
|
|
- function getImportData(validSheets, projectID){
|
|
|
- let rst = {fbfx: [], jscsxm: [], zzcsxm: []};
|
|
|
- let validSheetsDatas = [];
|
|
|
- for(let uploadPosition in validSheets){
|
|
|
- let validExcelData = [];
|
|
|
- for(let uSheet of validSheets[uploadPosition]){
|
|
|
- validExcelData = validExcelData.concat(getValidImportData(uSheet.colMapping, uSheet.data.dataTable));
|
|
|
- }
|
|
|
- if(validSheets[uploadPosition].length > 0){
|
|
|
- validSheetsDatas.push({position: uploadPosition, colMapping: validSheets[uploadPosition][0].colMapping, validExcelData: validExcelData});
|
|
|
- }
|
|
|
- }
|
|
|
- for(let validSheetData of validSheetsDatas){
|
|
|
- if(validSheetData.validExcelData.length > 0){
|
|
|
- rst[validSheetData.position] = parseToBillData(validSheetData.validExcelData, validSheetData.colMapping, positionFlag[validSheetData.position], projectID);
|
|
|
- }
|
|
|
+
|
|
|
+ function extactDatas(sheets) {
|
|
|
+ let rst = [];
|
|
|
+ for (let sheetName in sheets) {
|
|
|
+ let sheetData = sheets[sheetName];
|
|
|
+ let sheetType = getFileType(sheetData);
|
|
|
+ let colMapping = getColMapping(sheetType);
|
|
|
+ let datas = sheetType === fileType.gcl ? extractGCLDatas(sheetData, colMapping) : extractSLDatas(sheetData, colMapping);
|
|
|
+ rst = rst.concat(datas);
|
|
|
+ }
|
|
|
+ //编号去除空格 清除多余数据 设置数据
|
|
|
+ for (let data of rst) {
|
|
|
+ if (data.code && typeof data.code === 'string') {
|
|
|
+ data.code = data.code.replace(/\s/g, '');
|
|
|
+ }
|
|
|
+ if (data.unit === '㎡') {
|
|
|
+ data.unit = 'm2';
|
|
|
+ } else if (data.unit === 'm³') {
|
|
|
+ data.unit = 'm3';
|
|
|
+ }
|
|
|
+ data.projectID = projectObj.project.ID();
|
|
|
+ data.type = billType.BILL;
|
|
|
+ delete data.parent;
|
|
|
+ delete data.depth;
|
|
|
+ }
|
|
|
+ //将表根节点的ParentID设置成第100章至700章清单的ID
|
|
|
+ let fixedBill = projectObj.project.Bills.tree.roots.find(node => node.data &&
|
|
|
+ node.data.flagsIndex && node.data.flagsIndex.fixed && node.data.flagsIndex.fixed.flag === fixedFlag.ONE_SEVEN_BILLS);
|
|
|
+ let rootDatas = rst.filter(data => data.ParentID === -1);
|
|
|
+ for (let root of rootDatas) {
|
|
|
+ root.ParentID = fixedBill.data.ID;
|
|
|
+ }
|
|
|
+ //清单 第100章 总则清单需要加上固定ID
|
|
|
+ let oneHundredBills = rootDatas.find(data => data.name && /第100章/.test(data.name));
|
|
|
+ if (oneHundredBills) {
|
|
|
+ oneHundredBills.flags = [{flag: fixedFlag.ONE_HUNDRED_BILLS, fieldName: 'fixed'}];
|
|
|
}
|
|
|
return rst;
|
|
|
}
|
|
|
|
|
|
- function excelHasValidBills(importBillsData){
|
|
|
- for(let i in importBillsData){
|
|
|
- if(importBillsData[i].length > 0){
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- return {setImportSheetsInfo, getImportSheetsInfo, getImportSheets, getImportData, excelHasValidBills}
|
|
|
+ return {extactDatas}
|
|
|
})();
|