| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- 'use strict';
- /**
- *
- *
- * @author Zhong
- * @date 2018/8/2
- * @version
- */
- /*
- * 清单导入模块,前端导入excel,进行数据提取,用lz-string进行压缩上传处理
- * */
- const importBills = (function(){
- //单元格数据是否存在
- function _isDef(data){
- return typeof data !== 'undefined' && data !== null && data !== '';
- }
-
- //去除转义字符
- function _deESC(data) {
- return _isDef(data) ? data.toString().replace(/[\r,\n,\s,\t]/g, '') : data;
- }
- function _deNR(data) {
- return _isDef(data) ? data.toString().replace(/\r\r/g, '\r') : data;
- }
- //find 返回最后匹配
- function findLast(datas, func) {
- let filter = datas.filter(func);
- if (filter.length > 0) {
- return filter[filter.length - 1];
- }
- return null;
- }
- 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};
- }
- }
- 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 fileType.qdsl;
- }
- //提取工程量清单数据
- //层级由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);
- }
- row += 3;
- continue;
- }
- 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;
- }
- //表格内的数据
- let depth = getDepth(code);
- let data = {
- ID: uuid.v1(),
- NextSiblingID: -1,
- ParentID: -1,
- code: code,
- name: name,
- unit: unit,
- quantity: quantity,
- depth: depth,
- unitPriceAnalysis: 1,
- };
- 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;
- }
- }
- function getParents(data) {
- let rst = [];
- let parent = data.parent;
- while (parent) {
- rst.push(parent);
- parent = parent.parent;
- }
- rst.push(data);
- return rst;
- }
- //获取编号前缀: 101-1 => 101 101-1-1 => 101-1
- function getPrefix(v) {
- if (!v) {
- return null;
- }
- let reg = /(.*)-/;
- let match = reg.exec(v);
- return match ? match[1] : null;
- }
- //提取清单示例数据
- function extractSLDatas(sheetData) {
- let colMapping = {code: 0, name: 1, unit: 2, quantity: 3};
- let dataTable = sheetData.data.dataTable,
- rowCount = sheetData.rowCount;
- let rst = [];
- 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 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;
- }
- data.ParentID = parentData.ID;
- data.parent = parentData;
- let preData = findLast(parents, x => x.ParentID === data.ParentID);
- if (preData) {
- preData.NextSiblingID = data.ID;
- }
- rst.push(data);
- }
- }
- console.log(rst);
- return rst;
- }
-
- 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;
- }
- return {extactDatas}
- })();
|