فهرست منبع

Merge branch 'dev' of http://192.168.1.41:3000/maixinrong/Calculation into dev

TonyKang 4 سال پیش
والد
کامیت
d9b0333e3b
3فایلهای تغییر یافته به همراه988 افزوده شده و 804 حذف شده
  1. 193 17
      app/lib/analysis_excel.js
  2. 1 1
      app/middleware/api2other_check.js
  3. 794 786
      app/service/project_account.js

+ 193 - 17
app/lib/analysis_excel.js

@@ -45,6 +45,18 @@ const aeUtils = {
     }
 };
 
+const mainReg = /^(GD*)?G?(\d\d)*\d$/i;
+const subReg = /^(GD*)?G?[A-Z]{2}(\d\d)+$/i;
+const gdXmjPartReg = /^(GD*)?G?/;
+const specCode106 = {
+    code: ['102', '103', '104'],
+    reg: /^(GD*)?G?106/i
+};
+const specCode109 = {
+    code: ['102', '103', '104', '105', '106', '107', '108'],
+    reg: /^(GD*)?G?109/i
+};
+
 class ImportBaseTree {
     /**
      * 构造函数
@@ -61,6 +73,8 @@ class ImportBaseTree {
         this.roots = [];
         this.pos = [];
         this.tempData = [];
+        // 以id为索引
+        this.nodes = {};
 
         // 缓存
         this.finalNode = null;
@@ -97,6 +111,7 @@ class ImportBaseTree {
                 this.keyNodeId = node.ledger_id + 1;
             }
             this.tempData.push(node);
+            this.nodes[node.ledger_id] = node;
         }
         for (const node of this.items) {
             node.tender_id = this.ctx.tender.id;
@@ -182,6 +197,7 @@ class ImportBaseTree {
      * @param {Object} node - 当前添加的节点
      */
     defineCacheData(node) {
+        this.nodes[node.ledger_id] = node;
         this.finalNode = node;
         this.finalPrecision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, node.unit);
         if (node.code) {
@@ -297,6 +313,128 @@ class ImportBaseTree {
     }
 }
 
+class ImportStd18Tree extends ImportBaseTree {
+
+    /**
+     * 检查是否是父项
+     * @param parent
+     * @param code
+     * @returns {boolean}
+     * @private
+     */
+    _checkParent(parent, code) {
+        if (!parent.code) return false;
+        const numberPart = parent.code.replace(gdXmjPartReg, '');
+        if (!numberPart) return false;
+        return code.indexOf(numberPart) === 0 ||
+            code.indexOf('G' + numberPart) === 0 ||
+            code.indexOf('GD' + numberPart) === 0;
+    }
+
+    /**
+     * 查找主表项目节父项
+     * @param code
+     * @returns {*}
+     */
+    findMainXmjParent(code) {
+        const numberPart = code.replace(gdXmjPartReg, '');
+        if (numberPart.length <= 1) throw '首层项目节模板中未定义,不支持导入';
+
+        let parent = this.cacheMainXmjNode;
+        while (parent) {
+            if (this._checkParent(parent, code)) return parent;
+            parent = this.nodes[parent.ledger_pid];
+        }
+        return null;
+    }
+
+    /**
+     * 查找分表项目节父项
+     * @param code
+     * @returns {*}
+     */
+    findSubXmjParent(code) {
+        let parent = this.cacheSubXmjNode;
+        while (parent && parent.code.match(subReg)) {
+            if (this._checkParent(parent, code)) return parent;
+            parent = this.nodes[parent.ledger_pid];
+        }
+        return this.cacheMainXmjNode;
+    }
+
+    /**
+     * 根据 编号 查找 父项项目节
+     * @param {String} code - 子项编号
+     * @returns {*}
+     */
+    findXmjParent(code) {
+        if (code.match(mainReg)) {
+            if (!this.cacheMainXmjNode) throw '主表项目节找不到父项';
+            return this.findMainXmjParent(code);
+        } else if (code.match(subReg)) {
+            if (!this.cacheMainXmjNode) throw '分表项目节找不到所属主表项目节';
+            return this.findSubXmjParent(code);
+        }
+    }
+
+    /**
+     * 定义缓存节点(添加工程量清单、部位明细需使用缓存定位)
+     * @param {Object} node - 当前添加的节点
+     */
+    defineCacheData(node) {
+        super.defineCacheData(node);
+        if (node.code) {
+            if (node.code.match(mainReg)) {
+                this.cacheMainXmjNode = node;
+                this.cacheSubXmjNode = null;
+            } else if (node.code.match(subReg)) {
+                this.cacheSubXmjNode = node;
+            }
+            if (node.code.match(specCode106.reg)) {
+                if (this.cacheSpecMainXmj1 && this.cacheSpecMainXmj1.code.match(specCode109.reg)) {
+                    this.cacheSpecMainXmj2 = node;
+                } else {
+                    this.cacheSpecMainXmj1 = node;
+                }
+            } else if (node.code.match(specCode109.reg)) {
+                this.cacheSpecMainXmj1 = node;
+                this.cacheSpecMainXmj2 = null;
+            }
+        }
+    }
+
+    /**
+     * 添加 项目节
+     * @param {Object} node - 项目节
+     * @returns {*}
+     */
+    addXmjNode(node) {
+        if (!node.code || (!node.code.match(mainReg) && !node.code.match(subReg))) return null;
+
+        node.id = this.ctx.app.uuid.v4();
+        node.tender_id = this.ctx.tender.id;
+        node.children = [];
+        if ((specCode106.code.indexOf(node.code) >= 0)) {
+            if (this.cacheSpecMainXmj2 && this.cacheSpecMainXmj2.code.match(specCode106.reg))
+                return this.addNodeWithParent(node, this.cacheSpecMainXmj2);
+            if (this.cacheSpecMainXmj1 && this.cacheSpecMainXmj1.code.match(specCode106.reg))
+                return this.addNodeWithParent(node, this.cacheSpecMainXmj1);
+        }
+        if ((specCode109.code.indexOf(node.code) >= 0) &&
+            (this.cacheSpecMainXmj1 && this.cacheSpecMainXmj1.code.match(specCode109.reg))) {
+            return this.addNodeWithParent(node, this.cacheSpecMainXmj1)
+        }
+        const temp = this.findTempData(node);
+        if (temp) {
+            this.defineCacheData(temp);
+            return temp;
+        } else {
+            const parent = this.findXmjParent(node.code);
+            return this.addNodeWithParent(node, parent);
+        }
+    }
+}
+
 class AnalysisExcelTree {
     /**
      * 构造函数
@@ -319,6 +457,29 @@ class AnalysisExcelTree {
         };
     }
 
+    _isMatch11(tempData) {
+        return _.find(tempData, x => {
+            return x.code.indexOf('-') > 0;
+        })
+    }
+
+    _isMatch18(tempData) {
+        return _.every(tempData, x => {
+            return !x.code || !!x.code.match(mainReg);
+        });
+    }
+
+    _getNewCacheTree(tempData) {
+        // 模板符合11编办规则,使用11编办树
+        if (this._isMatch18(tempData)) {
+            return new ImportStd18Tree(tempData, this.ctx);
+        // 反之使用11编办(未校验模板是否符合,替换注释部分即可实现)
+        // } else if (this._isMatch11(tempData)){
+        } else {
+            return new ImportBaseTree(tempData, this.ctx);
+        }
+    }
+
     /**
      * 读取项目节节点
      * @param {Array} row - excel行数据
@@ -326,23 +487,38 @@ class AnalysisExcelTree {
      * @private
      */
     _loadXmjNode(row) {
-        const node = {};
-        node.code = this.ctx.helper.replaceReturn(row[this.colsDef.code]);
-        node.name = this.ctx.helper.replaceReturn(row[this.colsDef.name]);
-        node.unit = this.ctx.helper.replaceReturn(row[this.colsDef.unit]);
-        const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, node.unit);
-        node.quantity = this.ctx.helper.round(aeUtils.toNumber(row[this.colsDef.quantity]), precision.value);
-        node.dgn_qty1 = aeUtils.toNumber(row[this.colsDef.dgn_qty1]);
-        node.dgn_qty2 = aeUtils.toNumber(row[this.colsDef.dgn_qty2]);
-        node.unit_price = aeUtils.toNumber(row[this.colsDef.unit_price]);
-        node.drawing_code = this.ctx.helper.replaceReturn(row[this.colsDef.drawing_code]);
-        node.memo = this.ctx.helper.replaceReturn(row[this.colsDef.memo]);
-        if (node.quantity && node.unit_price) {
-            node.total_price = this.ctx.helper.mul(node.quantity, node.unit_price, this.ctx.tender.info.decimal.tp);
-        } else {
-            node.total_price = null;
+        try {
+            const node = {};
+            node.code = this.ctx.helper.replaceReturn(row[this.colsDef.code]);
+            node.name = this.ctx.helper.replaceReturn(row[this.colsDef.name]);
+            node.unit = this.ctx.helper.replaceReturn(row[this.colsDef.unit]);
+            const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, node.unit);
+            node.quantity = this.ctx.helper.round(aeUtils.toNumber(row[this.colsDef.quantity]), precision.value);
+            node.dgn_qty1 = aeUtils.toNumber(row[this.colsDef.dgn_qty1]);
+            node.dgn_qty2 = aeUtils.toNumber(row[this.colsDef.dgn_qty2]);
+            node.unit_price = aeUtils.toNumber(row[this.colsDef.unit_price]);
+            node.drawing_code = this.ctx.helper.replaceReturn(row[this.colsDef.drawing_code]);
+            node.memo = this.ctx.helper.replaceReturn(row[this.colsDef.memo]);
+            if (node.quantity && node.unit_price) {
+                node.total_price = this.ctx.helper.mul(node.quantity, node.unit_price, this.ctx.tender.info.decimal.tp);
+            } else {
+                node.total_price = null;
+            }
+            return this.cacheTree.addXmjNode(node);
+        } catch (error) {
+            console.log(error);
+            if (error.stack) {
+                this.ctx.logger.error(error);
+            } else {
+                this.ctx.getLogger('fail').info(JSON.stringify({
+                    error,
+                    project: this.ctx.session.sessionProject,
+                    user: this.ctx.session.sessionUser,
+                    body: row,
+                }));
+            }
+            return null;
         }
-        return this.cacheTree.addXmjNode(node);
     }
     /**
      * 读取工程量清单数据
@@ -431,7 +607,7 @@ class AnalysisExcelTree {
      */
     analysisData(sheet, tempData) {
         this.colsDef = null;
-        this.cacheTree = new ImportBaseTree(tempData, this.ctx);
+        this.cacheTree = this._getNewCacheTree(tempData);
         this.errorData = [];
         this.loadEnd = false;
 

+ 1 - 1
app/middleware/api2other_check.js

@@ -17,7 +17,7 @@ module.exports = options => {
             if (maintainData.status === maintainConst.status.ongoing) {
                 throw '系统维护中~';
             }
-            const code = this.query.code || this.request.body.code;
+            const code = this.query.projectCode || this.request.body.projectCode;
             const sign = this.query.sign || this.request.body.sign;
             const time = this.query.time || this.request.body.time;
             if (!code || !sign || !time) {

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 794 - 786
app/service/project_account.js