浏览代码

1. 台账分解,添加工程量清单,仅添加选中清单
2. 台账分解,第二层节点不允许升级
3. 台账分解,部位明细,复制粘贴功能调整

MaiXinRong 6 年之前
父节点
当前提交
b673bc34f0
共有 7 个文件被更改,包括 188 次插入53 次删除
  1. 34 7
      app/controller/ledger_controller.js
  2. 16 35
      app/public/js/ledger.js
  3. 1 0
      app/router.js
  4. 46 0
      app/service/ledger.js
  5. 67 11
      app/service/pos.js
  6. 8 0
      app/service/standard_lib.js
  7. 16 0
      app/service/std_bills.js

+ 34 - 7
app/controller/ledger_controller.js

@@ -9,8 +9,9 @@
  */
 
 const stdDataAddType = {
-    self: 1,
-    withParent: 2,
+    withParent: 1,
+    child: 2,
+    next: 3,
 };
 const auditConst = require('../const/audit').flow;
 const tenderMenu = require('../../config/menu').tenderMenu;
@@ -317,28 +318,37 @@ module.exports = app => {
                 }
                 // todo 校验项目是否使用该库的权限
 
-                let stdLib;
+                let stdLib, addType;
                 switch (data.stdType) {
                     case 'chapter':
                         stdLib = ctx.service.stdChapter;
+                        addType = stdDataAddType.withParent;
                         break;
                     case 'bills':
                         stdLib = ctx.service.stdBills;
+                        const selectNode = await ctx.service.ledger.getDataByNodeId(ctx.tender.id, data.id);
+                        if (selectNode.b_code) {
+                            addType = stdDataAddType.next;
+                        } else {
+                            addType = stdDataAddType.child;
+                        }
                         break;
                     default:
                         throw '未知标准库';
                 }
                 const stdData = await stdLib.getDataByDataId(data.stdLibId, data.stdNode);
-                const addType = stdDataAddType.withParent;
                 switch (addType) {
-                    case stdDataAddType.self:
+                    case stdDataAddType.child:
+                        responseData.data = await ctx.service.ledger.addStdNodeAsChild(ctx.tender.id, data.id, stdData);
+                        break;
+                    case stdDataAddType.next:
                         responseData.data = await ctx.service.ledger.addStdNode(ctx.tender.id, data.id, stdData);
                         break;
                     case stdDataAddType.withParent:
                         responseData.data = await ctx.service.ledger.addStdNodeWithParent(ctx.tender.id, stdData, stdLib);
                         break;
                     default:
-                        throw '未知添加方';
+                        throw '未知添加方';
                 }
             } catch (err) {
                 responseData.err = 1;
@@ -511,7 +521,7 @@ module.exports = app => {
         }
 
         /**
-         * 更新部位明细数据
+         * 更新 部位明细数据
          *
          * @param ctx
          * @return {Promise<void>}
@@ -529,6 +539,23 @@ module.exports = app => {
         }
 
         /**
+         * 复制粘贴 部位明细
+         * @param ctx
+         * @returns {Promise<void>}
+         */
+        async posPaste(ctx) {
+            try {
+                await this.checkMeasureType(measureType.tz.value);
+                const data = JSON.parse(ctx.request.body.data);
+                const result = await ctx.service.pos.pastePosData(data, ctx.tender.id);
+                ctx.body = { err: 0, msg: '', data: result };
+            } catch(err) {
+                this.log(err);
+                ctx.body = { err: 1, msg: err.toString(), data: null };
+            }
+        }
+
+        /**
          * 上传 清单Excel 并导入
          * @param ctx
          * @return {Promise<void>}

+ 16 - 35
app/public/js/ledger.js

@@ -87,7 +87,7 @@ $(document).ready(function() {
             setObjEnable($('#down-move'), valid && node && !tree.isLastSibling(node));
             if (checkTzMeasureType()) {
                 const posRange = node ? pos.getLedgerPos(node.id) : [];
-                setObjEnable($('#up-level'), valid && node && tree.getParent(node) && (!posRange || posRange.length === 0));
+                setObjEnable($('#up-level'), valid && node && tree.getParent(node) && node.level > 2 && (!posRange || posRange.length === 0));
             } else {
                 setObjEnable($('#up-level'), valid && node && tree.getParent(node));
             }
@@ -729,48 +729,29 @@ $(document).ready(function() {
             }
 
             if (info.sheet.zh_setting) {
-                const data = { updateType: '', updateData: [], };
-                const sortData = info.sheet.zh_data;
-                if (sortData && (info.cellRange.row >= sortData.length)) {
-                    data.updateType = 'add';
+                const data = [];
+                const sortData = info.sheet.zh_data || [];
+                if (sortData.length === 0 || info.cellRange.row + info.cellRange.rowCount >= sortData.length) {
                     if (info.cellRange.col !== 0) {
                         toast('新增部位请先输入名称', 'warning');
                         self.loadCurPosData();
                         return;
                     }
-                    for (let iRow = 0; iRow < info.cellRange.rowCount; iRow++) {
-                        const curRow = info.cellRange.row + iRow;
-                        const newData = {};
-                        for (let iCol = 0; iCol < info.cellRange.colCount; iCol++) {
-                            const curCol = info.cellRange.col + iCol;
-                            const colSetting = info.sheet.zh_setting.cols[curCol];
-                            data[colSetting.field] = info.sheet.getText(curRow, curCol);
-                            if (colSetting.type === 'Number') {
-                                data[colSetting.field] = _.toNumber(data[colSetting.field]);
-                            }
-                        }
-                        data.updateData.push(newData);
-                    }
-                } else {
-                    data.updateType = 'update';
-                    for (let iRow = 0; iRow < info.cellRange.rowCount; iRow++) {
-                        const curRow = info.cellRange.row + iRow;
-                        const curPos = sortData[curRow];
-                        if (curPos) {
-                            const newData = {id: curPos.id};
-                            for (let iCol = 0; iCol < info.cellRange.colCount; iCol++) {
-                                const curCol = info.cellRange.col + iCol;
-                                const colSetting = info.sheet.zh_setting.cols[curCol];
-                                newData[colSetting.field] = info.sheet.getText(curRow, curCol);
-                                if (colSetting.type === 'Number') {
-                                    newData[colSetting.field] = _.toNumber(newData[colSetting.field]);
-                                }
-                            }
-                            data.updateData.push(newData);
+                }
+                for (let iRow = 0; iRow < info.cellRange.rowCount; iRow++) {
+                    const curRow = info.cellRange.row + iRow;
+                    const posData = curRow >= sortData.length ? {lid: node.id} : {id: sortData[curRow].id, lid: node.id};
+                    for (let iCol = 0; iCol < info.cellRange.colCount; iCol++) {
+                        const curCol = info.cellRange.col + iCol;
+                        const colSetting = info.sheet.zh_setting.cols[curCol];
+                        posData[colSetting.field] = info.sheet.getText(curRow, curCol);
+                        if (colSetting.type === 'Number') {
+                            posData[colSetting.field] = _.toNumber(posData[colSetting.field]);
                         }
                     }
+                    data.push(posData);
                 }
-                postData('/tender/' + getTenderId() + '/pos/update', data, function (result) {
+                postData('/tender/' + getTenderId() + '/pos/paste', data, function (result) {
                     pos.updateDatas(result.pos);
                     posOperationObj.loadCurPosData();
                     ledgerTree.loadPostData(result.ledger, function (loadResult) {

+ 1 - 0
app/router.js

@@ -82,6 +82,7 @@ module.exports = app => {
     app.get('/tender/:id/ledger/download/:file', sessionAuth, tenderCheck, 'ledgerController.download');
     app.post('/tender/:id/pos', sessionAuth, tenderCheck, 'ledgerController.pos');
     app.post('/tender/:id/pos/update', sessionAuth, tenderCheck, 'ledgerController.posUpdate');
+    app.post('/tender/:id/pos/paste', sessionAuth, tenderCheck, 'ledgerController.posPaste');
 
     app.get('/tender/:id/ledger/change', sessionAuth, tenderCheck, 'ledgerController.change');
     app.get('/tender/:id/ledger/index', sessionAuth, 'ledgerController.index');

+ 46 - 0
app/service/ledger.js

@@ -187,7 +187,13 @@ module.exports = app => {
          * @return {Promise<*>}
          */
         async getDataByIds(id) {
+            if (!id) {
+                return;
+            }
             const ids = id instanceof Array ? id : [id];
+            if (ids.length === 0) {
+                return;
+            }
             this.initSqlBuilder();
             this.sqlBuilder.setAndWhere('id', {
                 value: ids,
@@ -773,6 +779,46 @@ module.exports = app => {
             return result;
         }
 
+        async addChild(tenderId, selectId, data) {
+            if ((tenderId <= 0) || (selectId <= 0)) {
+                return [];
+            }
+            const selectData = await this.getDataByNodeId(tenderId, selectId);
+            if (!selectData) {
+                throw '新增节点数据错误';
+            }
+            const children = await this.getChildrenByParentId(tenderId, selectId);
+
+            const cacheKey = keyPre + tenderId;
+            let maxId = parseInt(await this.cache.get(cacheKey));
+            if (!maxId) {
+                maxId = await this._getMaxNodeId(tenderId);
+                this.cache.set(cacheKey, maxId, 'EX', this.ctx.app.config.cacheTime);
+            }
+
+            data.tender_id = tenderId;
+            data.ledger_id = maxId + 1;
+            data.ledger_pid = selectData.ledger_id;
+            data.level = selectData.level + 1;
+            data.order = children.length + 1;
+            data.full_path = selectData.full_path + '.' + data.ledger_id;
+            data.is_leaf = true;
+            const result = await this.db.insert(this.tableName, data);
+
+            this.cache.set(cacheKey, maxId + 1, 'EX', this.ctx.app.config.cacheTime);
+
+            // 查询应返回的结果
+            const createData = await this.getDataByNodeId(tenderId, data.ledger_id);
+            return { create: createData };
+
+        }
+
+        async addStdNodeAsChild(tenderId, selectId, stdData) {
+            const newData = this._filterStdData(stdData);
+            const result = await this.addChild(tenderId, selectId, newData);
+            return result;
+        }
+
         /**
          * 添加节点,并同步添加父节点
          * @param {Number} tenderId - 标段id

+ 67 - 11
app/service/pos.js

@@ -29,6 +29,21 @@ module.exports = app => {
             });
         }
 
+        async _insertPosData(transaction, data, tid) {
+            data.tid = tid;
+            // todo 新增期
+            data.add_stage = 0;
+            data.add_times = 0;
+            data.add_user = this.ctx.session.sessionUser.accountId;
+            if (data.quantity) {
+                const bills = await this.ctx.service.ledger.getDataById(data.lid);
+                const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, bills.unit);
+                data.quantity = this._.round(data.quantity, precision.value);
+            }
+            const addRst = await transaction.insert(this.tableName, data);
+            data.id = addRst.insertId;
+        }
+
         /**
          * 保存部位明细数据
          * @param data
@@ -41,18 +56,13 @@ module.exports = app => {
                 const result = { ledger: {}, pos: null };
                 if (data.updateType === 'add') {
                     const tender = await this.ctx.service.tender.getTender(tid);
-                    data.updateData.tid = tid;
-                    // todo 新增期
-                    data.updateData.add_stage = 0;
-                    data.updateData.add_times = 0;
-                    data.updateData.add_user = this.ctx.session.sessionUser.accountId;
-                    if (data.quantity) {
-                        const bills = await this.ctx.service.ledger.getDataById(data.lid);
-                        const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, bills.unit);
-                        data.quantity = this._.round(data.quantity, precision.value);
+                    if (data.updateData instanceof Array) {
+                        for (const d of data.updateData) {
+                            this._insertPosData(transaction, d, tid);
+                        }
+                    } else {
+                        this._insertPosData(transaction, data.updateData, tid);
                     }
-                    const addRst = await transaction.insert(this.tableName, data.updateData);
-                    data.updateData.id = addRst.insertId;
                 } else if (data.updateType === 'update') {
                     const datas = data.updateData instanceof Array ? data.updateData : [data.updateData];
                     result.ledger.update = [];
@@ -97,6 +107,52 @@ module.exports = app => {
         }
 
         /**
+         * 复制粘贴 部位明细数据
+         * @param {Array} data - 复制粘贴的数据
+         * @param {Number} tid - 标段id
+         * @returns {Promise<{ledger: {}, pos: null}>}
+         */
+        async pastePosData(data, tid) {
+            if (!(data instanceof Array)) {
+                throw '提交数据错误';
+            }
+
+            const transaction = await this.db.beginTransaction();
+            const result = { ledger: {}, pos: null }, updateLid = [];
+            try {
+                for (const d of data) {
+                    if (d.quantity) {
+                        const bills = await this.ctx.service.ledger.getDataById(d.lid);
+                        const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, bills.unit);
+                        d.quantity = this._.round(d.quantity, precision.value);
+                        console.log(updateLid);
+                        if (updateLid.indexOf(d.lid) === -1) {
+                            updateLid.push(d.lid);
+                        }
+                        console.log(updateLid);
+                    }
+                    if (d.id) {
+                        await transaction.update(this.tableName, d);
+                    } else {
+                        this._insertPosData(transaction, d, tid);
+                    }
+                    for (const lid of updateLid) {
+                        await this.ctx.service.ledger.calc(tid, lid, transaction);
+                    }
+                }
+                await transaction.commit();
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+            result.pos = data;
+            if (updateLid.length > 0) {
+                result.ledger.update = await this.ctx.service.ledger.getDataByIds(updateLid);
+            }
+            return result;
+        }
+
+        /**
          * 删除清单下部位明细数据(删除清单时调用)
          *
          * @param transaction - 事务

+ 8 - 0
app/service/standard_lib.js

@@ -25,6 +25,10 @@ class StandardLib extends BaseService {
         this.stdType = '';
     }
 
+    // 供子类继承(不同的标准库可能需要转换一下数据)
+    convertData (data) {
+    }
+
 
     /**
      * 获取数据
@@ -47,6 +51,7 @@ class StandardLib extends BaseService {
         }
         const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
         const list = await this.db.query(sql, sqlParam);
+        this.convertData(list);
 
         return list;
     }
@@ -84,6 +89,7 @@ class StandardLib extends BaseService {
         const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
         const node = await this.db.queryOne(sql, sqlParam);
         this.setSourceData(node);
+        this.convertData(node);
 
         return node;
     }
@@ -106,6 +112,7 @@ class StandardLib extends BaseService {
         const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
         const resultData = await this.db.query(sql, sqlParam);
         this.setSourceData(resultData);
+        this.convertData(resultData);
         return resultData;
     }
     /**
@@ -131,6 +138,7 @@ class StandardLib extends BaseService {
         const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
         const data = await this.db.query(sql, sqlParam);
         this.setSourceData(data);
+        this.convertData(data);
         return data;
     };
 }

+ 16 - 0
app/service/std_bills.js

@@ -25,6 +25,22 @@ module.exports = app => {
             this.stdType = 'bill';
         }
 
+        /**
+         * 查询数据后,转换数据(用于兼容项目节与清单的不同)
+         * @param data
+         */
+        convertData (data) {
+            if (data instanceof Array) {
+                for (const d of data) {
+                    d.b_code = d.code;
+                    delete d.code;
+                }
+            } else if (data.code) {
+                data.b_code = data.code;
+                delete data.code;
+            }
+        }
+
     }
 
     return StdBills;