Pārlūkot izejas kodu

1. 台账分解,金额列只读
2. 台账分解,清单编辑金额时,清空数量
3. 台账分解,父项不可输入数量、金额、单价
4. 台账分解,项目节不可输入数量、单价
5. 台账分解,清单含有部位明细,数量、金额不可输入

MaiXinRong 6 gadi atpakaļ
vecāks
revīzija
681487ed8c

+ 6 - 6
app/const/spread.js

@@ -18,14 +18,14 @@ const ledgerSpread = {
         {title: '清单编号', colSpan: '1', rowSpan: '2', field: 'b_code', hAlign: 0, width: 80, formatter: '@'},
         {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 230, formatter: '@'},
         {title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 50, formatter: '@'},
-        {title: '单价', colSpan: '1', rowSpan: '2', field: 'unit_price', hAlign: 2, width: 60, type: 'Number'},
+        {title: '单价', colSpan: '1', rowSpan: '2', field: 'unit_price', hAlign: 2, width: 60, type: 'Number', readOnly: 'readOnly.unit_price'},
         {title: '设计数量|数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
         {title: '|数量2',  colSpan: '|1', rowSpan: '|1', field: 'dgn_qty2', hAlign: 2, width: 60, type: 'Number'},
-        {title: '经济指标',  colSpan: '1', rowSpan: '2', field: 'dgn_price', hAlign: 2, width: 60, type: 'Number'},
-        {title: '签约|数量', colSpan: '2|1', rowSpan: '1|1', field: 'deal_qty', hAlign: 2, width: 60, type: 'Number'},
-        {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'deal_tp', hAlign: 2, width: 60, type: 'Number'},
-        {title: '施工图复核|数量', colSpan: '2|1', rowSpan: '1|1', field: 'quantity', hAlign: 2, width: 60, type: 'Number'},
-        {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, type: 'Number'},
+        {title: '经济指标',  colSpan: '1', rowSpan: '2', field: 'dgn_price', hAlign: 2, width: 60, type: 'Number', realyOnly: true},
+        {title: '签约|数量', colSpan: '2|1', rowSpan: '1|1', field: 'deal_qty', hAlign: 2, width: 60, type: 'Number', readOnly: 'readOnly.quantity'},
+        {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'deal_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
+        {title: '施工图复核|数量', colSpan: '2|1', rowSpan: '1|1', field: 'quantity', hAlign: 2, width: 60, type: 'Number', readOnly: 'readOnly.quantity'},
+        {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, type: 'Number', readOnly: true},
         {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@'},
         {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@'}
     ],

+ 1 - 0
app/controller/ledger_controller.js

@@ -528,6 +528,7 @@ module.exports = app => {
          */
         async posUpdate(ctx) {
             try {
+                console.log(1);
                 await this.checkMeasureType(measureType.tz.value);
                 const data = JSON.parse(ctx.request.body.data);
                 const responseData = await ctx.service.pos.savePosData(data, ctx.tender.id);

+ 47 - 15
app/public/js/ledger.js

@@ -42,6 +42,7 @@ $(document).ready(function() {
     const ledgerTree = createNewPathTree('ledger', treeSetting);
     ledgerTree.loadDatas(ledger);
     treeCalc.calculateAll(ledgerTree);
+    ledgerTreeCol.initSpreadSetting(ledgerSpreadSetting);
     SpreadJsObj.initSheet(ledgerSpread.getActiveSheet(), ledgerSpreadSetting);
     // 加载台账数据到界面
     SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree);
@@ -300,13 +301,31 @@ $(document).ready(function() {
                     tender_id: node.tender_id,
                     ledger_id: node.ledger_id
                 };
+                // 未改变值则不提交
+                const orgValue = node[col.field];
+                if (orgValue == info.editingText || ((!orgValue || orgValue === '') && (info.editingText === ''))) {
+                    return;
+                }
+                // 台账模式,检查部位明细相关
+                if (checkTzMeasureType()) {
+                    if (col.field === 'quantity' || col.field === 'total_price') {
+                        if (!node.children || node.children.length ===0) {
+                            const lPos = pos.getLedgerPos(node.id);
+                            if (lPos && lPos.length > 0) {
+                                toast('清单含有部位明细,不可修改施工图复核数量', 'error');
+                                SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                                return;
+                            }
+                        }
+                    }
+                }
+                // 获取更新数据
                 if (info.editingText) {
                     data[col.field] = col.type === 'Number' ? parseFloat(info.editingText) : info.editingText.replace('\n', '');
                 } else {
                     data[col.field] = null;
                 }
-                console.log(JSON.stringify(data));
-
+                // 更新至服务器
                 info.sheet.zh_tree.update('/tender/' + getTenderId() + '/ledger/update', data, function (result) {
                     treeOperationObj.refreshTree(info.sheet, result);
                 });
@@ -359,18 +378,27 @@ $(document).ready(function() {
                 for (let iRow = sel.row; iRow < sel.row + sel.rowCount; iRow++) {
                     const node = sortData[iRow];
                     if (node) {
+                        let bDel = false;
                         const data = sheet.zh_tree.getNodeKeyData(node);
                         for (let iCol = sel.col; iCol < sel.col + sel.colCount; iCol++) {
-                            const colSetting = sheet.zh_setting.cols[iCol];
-                            data[colSetting.field] = null;
+                            const style = sheet.getStyle(iRow, iCol);
+                            if (!style.locked) {
+                                const colSetting = sheet.zh_setting.cols[iCol];
+                                data[colSetting.field] = null;
+                                bDel = true;
+                            }
+                        }
+                        if (bDel) {
+                            datas.push(data);
+                            nodes.push(node);
                         }
-                        datas.push(data);
-                        nodes.push(node);
                     }
                 }
-                sheet.zh_tree.update('/tender/' + getTenderId() + '/ledger/update', datas, function (result) {
-                    treeOperationObj.refreshTree(sheet, result);
-                });
+                if (datas.length > 0) {
+                    sheet.zh_tree.update('/tender/' + getTenderId() + '/ledger/update', datas, function (result) {
+                        treeOperationObj.refreshTree(sheet, result);
+                    });
+                }
             }
         },
         /**
@@ -598,7 +626,7 @@ $(document).ready(function() {
          */
         editEnding: function (e, info) {
             if (info.sheet.zh_setting) {
-                const orgText = info.sheet.getCell(info.row, info.row).value();
+                const orgText = info.sheet.getCell(info.row, info.col).text();
                 if (orgText === info.editingText || ((!orgText || orgText === '') && (info.editingText === ''))) {
                     return;
                 }
@@ -682,10 +710,14 @@ $(document).ready(function() {
                         posSelects.push(node);
                     }
                 }
-                sheet.zh_tree.update('/tender/' + getTenderId() + '/pos/update', datas, function (result) {
-                    pos.updateDatas(result);
-                    // todo 只加载改变项
-                    self.loadCurPosData();
+                postData('/tender/' + getTenderId() + '/pos/update', {updateType: 'update', updateData: datas}, function (result) {
+                    pos.updateDatas(result.pos);
+                    posOperationObj.loadCurPosData();
+                    ledgerTree.loadPostData(result.ledger, function (loadResult) {
+                        treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), loadResult);
+                    });
+                }, function () {
+                    posOperationObj.loadCurPosData();
                 });
             }
         },
@@ -698,7 +730,7 @@ $(document).ready(function() {
             const data = {
                 updateType: 'delete',
                 updateData: [],
-            }
+            };
             const row = selection[0].row, count = selection[0].rowCount;
             const sortData = sheet.zh_data;
             for (let iRow = 0; iRow < count; iRow++) {

+ 46 - 0
app/public/js/ledger_tree_col.js

@@ -0,0 +1,46 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+const ledgerTreeCol = {
+    readOnly: {
+        unit_price: function (node) {
+            return node.children && node.children.length > 0;
+        },
+        quantity: function (node) {
+            return (node.children && node.children.length > 0) || _.isEmpty(node.b_code);
+        },
+        total_price: function (node) {
+            return node.children && node.children.length > 0;
+        }
+    },
+    getEvent: function (eventName) {
+        const names = eventName.split('.');
+        let event = this;
+        for (let name of names) {
+            if (event[name]) {
+                event = event[name];
+            } else {
+                return null;
+            }
+        }
+        if (event && Object.prototype.toString.apply(event) !== "[object Function]") {
+            return null;
+        } else {
+            return event;
+        }
+    },
+    initSpreadSetting(setting) {
+        for (const col of setting.cols) {
+            if (col.readOnly && Object.prototype.toString.apply(col.readOnly) === "[object String]") {
+                col.readOnly = this.getEvent(col.readOnly);
+            }
+        }
+    }
+};

+ 1 - 1
app/public/js/path_tree.js

@@ -720,7 +720,7 @@ const createNewPathTree = function (type, setting) {
                         }
                     }
                 }
-                if (this.getItems(node.id) && node.children.length > 0) {
+                if (this.getItems(node.ledger_id) && node.children.length > 0) {
                     parents.push(node);
                 }
             }

+ 22 - 48
app/public/js/spreadjs_rela/spreadjs_zh.js

@@ -214,6 +214,24 @@ const SpreadJsObj = {
         sheet.getRange(0, 0, sheet.getRowCount(), sheet.getColumnCount()).locked(setting.readOnly);
         this.endMassOperation(sheet);
     },
+    _loadRowData: function (sheet, data, row) {
+        // 单元格重新写入数据
+        if (!data) { return }
+        sheet.zh_setting.cols.forEach(function (col, j) {
+            const cell = sheet.getCell(row, j);
+            if (col.field !== '' && data[col.field]) {
+                cell.value(data[col.field]);
+            }
+            if (col.readOnly && Object.prototype.toString.apply(col.readOnly) === "[object Function]") {
+                cell.locked(col.readOnly(data) || sheet.zh_setting.readOnly || false).vAlign(1).hAlign(col.hAlign);
+            } else {
+                cell.locked(col.readOnly || sheet.zh_setting.readOnly || false).vAlign(1).hAlign(col.hAlign);
+            }
+            if (col.formatter) {
+                cell.formatter(col.formatter);
+            }
+        });
+    },
     /**
      * 整个sheet重新加载数据
      * @param {GC.Spread.Sheets.Worksheet} sheet
@@ -232,14 +250,7 @@ const SpreadJsObj = {
             emptyRows.locked(sheet.zh_dataType === 'tree');
             // 单元格写入数据
             sortData.forEach(function (data, i) {
-                sheet.zh_setting.cols.forEach(function (col, j) {
-                    const cell = sheet.getCell(i, j);
-                    if (col.field !== '' && data[col.field]) {
-                        cell.value(data[col.field]).locked(col.readOnly || sheet.zh_setting.readOnly || false).vAlign(1).hAlign(col.hAlign);
-                    } else {
-                        cell.locked(col.readOnly || sheet.zh_setting.readOnly || false).vAlign(1).hAlign(col.hAlign);
-                    }
-                });
+                self._loadRowData(sheet, data, i);
                 sheet.setRowVisible(i, data.visible);
             });
             // 设置列单元格格式
@@ -271,28 +282,13 @@ const SpreadJsObj = {
             this.endMassOperation(sheet);
         }
     },
-    _loadRowData: function (sheet, data, row) {
-        // 单元格重新写入数据
-        if (!data) { return }
-        sheet.zh_setting.cols.forEach(function (col, j) {
-            const cell = sheet.getCell(row, j);
-            if (col.field !== '' && data[col.field]) {
-                cell.value(data[col.field]).locked(col.readOnly || sheet.zh_setting.readOnly || false).vAlign(1).hAlign(col.hAlign);
-            } else {
-                cell.locked(col.readOnly || sheet.zh_setting.readOnly || false).vAlign(1).hAlign(col.hAlign);
-            }
-            if (col.formatter) {
-                cell.formatter(col.formatter);
-            }
-        });
-    },
     /**
      * 重新加载部分数据行
      * @param {GC.Spread.Sheets.Worksheet} sheet
      * @param {Number} row
      * @param {Number} count
      */
-    reLoadRowData: function (sheet, row, count) {
+    reLoadRowData: function (sheet, row, count = 1) {
         //if (row < 0) { return; }
         const self = this;
         const sortData = sheet.zh_dataType === 'tree' ? sheet.zh_tree.nodes : sheet.zh_data;
@@ -304,17 +300,7 @@ const SpreadJsObj = {
             for (let i = row; i < row + count; i++) {
                 const data = sortData[i];
                 if (!data) { continue; }
-                sheet.zh_setting.cols.forEach(function (col, j) {
-                    const cell = sheet.getCell(i, j);
-                    if (col.field !== '' && data[col.field]) {
-                        cell.value(data[col.field]).locked(col.readOnly || sheet.zh_setting.readOnly || false).vAlign(1).hAlign(col.hAlign);
-                    } else {
-                        cell.locked(col.readOnly || sheet.zh_setting.readOnly || false).vAlign(1).hAlign(col.hAlign);
-                    }
-                    if (col.formatter) {
-                        cell.formatter(col.formatter);
-                    }
-                });
+                this._loadRowData(sheet, data, i);
             }
             this.endMassOperation(sheet);
         } catch (err) {
@@ -338,19 +324,7 @@ const SpreadJsObj = {
                 sheet.clear(row, -1, 1, -1, spreadNS.SheetArea.viewport, spreadNS.StorageType.data);
                 const data = sortData[row];
                 // 单元格重新写入数据
-                sheet.zh_setting.cols.forEach(function (col, j) {
-                    // 设置值
-                    const cell = sheet.getCell(row, j);
-                    if (col.field !== '' && data[col.field]) {
-                        cell.value(data[col.field]).locked(col.readOnly || sheet.zh_setting.readOnly || false).vAlign(1).hAlign(col.hAlign);
-                    } else {
-                        cell.locked(col.readOnly || sheet.zh_setting.readOnly || false).vAlign(1).hAlign(col.hAlign);
-                    }
-                    // 设置单元格格式
-                    if (col.formatter) {
-                        cell.formatter(col.formatter);
-                    }
-                });
+                this._loadRowData(sheet, data, row);
             };
             this.endMassOperation(sheet);
         } catch (err) {

+ 15 - 7
app/service/ledger.js

@@ -1309,7 +1309,7 @@ module.exports = app => {
             const result = {};
             let bChanged = false;
             for (const prop in orgData) {
-                if (newData[prop] !== orgData[prop]) {
+                if (newData[prop] && newData[prop] !== orgData[prop]) {
                     result[prop] = newData[prop];
                     bChanged = true;
                 }
@@ -1578,14 +1578,22 @@ module.exports = app => {
                     }
                     let updateData;
                     if (this._checkCalcField(row)) {
-                        const calcData = this.ctx.helper.updateObj(updateNode, row);
+                        if (!row.unit_price) {
+                            row.unit_price = updateNode.unit_price;
+                        }
                         const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, updateNode.unit);
-                        this.ctx.helper.checkFieldPrecision(calcData, qtyFields, precision.value);
-                        if (updateNode.is_leaf) {
-                            calcData.total_price = calcData.quantity * calcData.unit_price;
-                            calcData.deal_tp = calcData.deal_qty * calcData.unit_price;
+                        this.ctx.helper.checkFieldPrecision(row, qtyFields, precision.value);
+                        if (row.quantity) {
+                            row.total_price = this._.multiply(row.quantity, row.unit_price);
+                        } else if (row.total_price) {
+                            row.quantity = null;
+                        }
+                        if (row.deal_qty) {
+                            row.deal_tp = this._.multiply(row.deal_qty, row.unit_price);
+                        } else if (row.deal_tp) {
+                            row.deal_qty = null;
                         }
-                        const data1 = this._filterChangedField(updateNode, calcData);
+                        const data1 = this._filterChangedField(updateNode, row);
                         updateData = this._filterUpdateInvalidField(updateNode.id, data1);
                     } else {
                         updateData = this._filterUpdateInvalidField(updateNode.id, row);

+ 1 - 0
app/service/pos.js

@@ -51,6 +51,7 @@ module.exports = app => {
          * @returns {Promise<{ledger: {}, pos: null}>}
          */
         async savePosData(data, tid) {
+            console.log(data);
             const transaction = await this.db.beginTransaction();
             try {
                 const result = { ledger: {}, pos: null };

+ 1 - 0
config/web.js

@@ -77,6 +77,7 @@ const JsFiles = {
                 mergeFiles: [
                     "/public/js/spreadjs_rela/spreadjs_zh.js",
                     "/public/js/path_tree.js",
+                    "/public/js/ledger_tree_col.js",
                     "/public/js/ledger.js",
                 ],
                 mergeFile: 'explode',