Procházet zdrojové kódy

Merge branch 'master' of http://192.168.1.41:3000/maixinrong/Calculation

TonyKang před 5 roky
rodič
revize
77abb288bf

+ 1 - 1
app/const/deal_pay.js

@@ -15,7 +15,7 @@ const payType = {
     wc: 4
 };
 const payTemplate = [
-    {order: 1, name: '本期应付金额', ptype: payType.yf, minus: false, expr: null, sexpr: null, rexpr: null},
+    {order: 1, name: '本期应付', ptype: payType.yf, minus: false, expr: null, sexpr: null, rexpr: null},
     {order: 2, name: '本期实付', ptype: payType.sf, minus: false},
     {order: 3, name: '本期完成计量', ptype: payType.wc, minus: false, expr: 'bqwc'},
     {order: 4, name: '质量保证金', ptype: payType.normal, minus: true},

+ 7 - 4
app/const/spread.js

@@ -112,8 +112,8 @@ const stageTz = {
             {title: '台账|数量', colSpan: '2|1', rowSpan: '1|1', field: 'quantity', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '本期合同计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
-            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
-            {title: '本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number',},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number'},
+            {title: '本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'qc_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'gather_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
@@ -133,6 +133,7 @@ const stageTz = {
             {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@', readOnly: true},
             //{title: '累计完成率(%)', colSpan: '1', rowSpan: '2', field: 'percent', hAlign: 0, width: 100, readOnly: true, type: 'Number'},
             {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
+            {title: '总额计量', colSpan: '1', rowSpan: '2', field: 'is_tp', hAlign: 1, width: 60, cellType: 'checkbox'},
         ],
         emptyRows: 0,
         headRows: 2,
@@ -175,7 +176,7 @@ const stageCl = {
             {title: '台账|数量', colSpan: '2|1', rowSpan: '1|1', field: 'quantity', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '本期合同计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
-            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number'},
             {title: '本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number',},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'qc_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
@@ -196,6 +197,7 @@ const stageCl = {
             {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@', readOnly: true},
             //{title: '累计完成率(%)', colSpan: '1', rowSpan: '2', field: 'percent', hAlign: 0, width: 100, readOnly: true, type: 'Number'},
             {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
+            {title: '总额计量', colSpan: '1', rowSpan: '2', field: 'is_tp', hAlign: 1, width: 60, cellType: 'checkbox'},
         ],
         emptyRows: 0,
         headRows: 2,
@@ -242,7 +244,7 @@ const stageNoCl = {
             {title: '台账|数量', colSpan: '2|1', rowSpan: '1|1', field: 'quantity', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '本期合同计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
-            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number'},
             {title: '本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number',},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'qc_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
@@ -262,6 +264,7 @@ const stageNoCl = {
             {title: '本期批注', colSpan: '1', rowSpan: '2', field: 'postil', hAlign: 0, width: 100, formatter: '@', cellType: 'autoTip'},
             {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@', readOnly: true},
             {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
+            {title: '总额计量', colSpan: '1', rowSpan: '2', field: 'is_tp', hAlign: 1, width: 60, cellType: 'checkbox'},
         ],
         emptyRows: 0,
         headRows: 2,

+ 3 - 1
app/controller/stage_controller.js

@@ -210,7 +210,7 @@ module.exports = app => {
             }
             this.ctx.helper.assignRelaData(ledgerData, [
                 {data: curStageData, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil'], prefix: '', relaId: 'lid',},
-                {data: preStageData, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: 'pre_', relaId: 'lid',}
+                {data: preStageData, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'used'], prefix: 'pre_', relaId: 'lid',}
             ]);
             return ledgerData;
         }
@@ -347,6 +347,8 @@ module.exports = app => {
                     if (data.bills.stage) {
                         responseData.data.curStageData = await ctx.service.stageBills.updateStageData(data.bills.stage);
                     }
+                    if (data.bills.calcType) {
+                        responseData.data = await ctx.service.stageBills.updateStageBillsCalcType(data.bills.calcType);                    }
                 }
                 await ctx.service.stage.updateCheckCalcFlag(ctx.stage.id, true);
                 ctx.body = responseData;

+ 7 - 0
app/lib/pay_calc.js

@@ -163,6 +163,9 @@ class PayCalculate {
         this.yf = pays.find(function (p) {
             return p.ptype === payType.yf;
         });
+        this.sf = pays.find(function (p) {
+            return p.ptype === payType.sf;
+        });
         if (!this.yf) return false;
         await this._getAddCalcRela();
         this.yf.tp = 0;
@@ -212,6 +215,10 @@ class PayCalculate {
             p.end_tp = this.ctx.helper.round(this.ctx.helper.add(p.tp, p.pre_tp), this.decimal);
         }
         this.yf.end_tp = this.ctx.helper.add(this.yf.tp, this.yf.pre_tp);
+        if (this.sf.tp === null) {
+            this.sf.tp = this.yf.tp;
+        }
+        this.sf.end_tp = this.ctx.helper.add(this.sf.tp, this.sf.pre_tp);
     }
 
     async calculateAll(pays) {

+ 2 - 2
app/public/js/component/input.js

@@ -15,7 +15,7 @@ Vue.component('input-text', {
     '<div class="form-group" :class="{ required: required }">' +
         '<label>{{ label }}</label>' +
         '<input :type="[ password ? \'password\' : \'text\']" :id="id" :name="name" :value="value" :placeholder="placeholder" ' +
-            ':maxlength="maxlength" :readonly="readonly" :disabled="disabled" class="form-control"/>' +
+            ':maxlength="maxlength" :readonly="readonly" :disabled="disabled" class="form-control form-control-sm"/>' +
     '</div>'
 });
 
@@ -70,4 +70,4 @@ Vue.component('input-dropdown', {
         '</div>' +
         '<div class="col-lg-4"></div>' +
     '</div>'
-});
+});

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

@@ -275,7 +275,7 @@ function getQueryVariable(variable) {
 
 const zeroRange = 0.00000001;
 function checkZero(value) {
-    return _.isNumber(value) && Math.abs(value) < zeroRange;
+    return value === null || value === undefined || (_.isNumber(value) && Math.abs(value) < zeroRange);
 }
 function checkFieldChange(o, n) {
     return o == n || ((!o || o === '') && (n === ''));

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

@@ -87,7 +87,7 @@ $(document).ready(() => {
     }
 
     postData('/tender/' + getTenderId() + '/ledger/load', null, function (data) {
-        ledgerTree.loadDatas(ledger);
+        ledgerTree.loadDatas(data.bills);
         treeCalc.calculateAll(ledgerTree);
         SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree);
         SpreadJsObj.loadTopAndSelect(ledgerSpread.getActiveSheet(), ckBillsSpread);

+ 2 - 2
app/public/js/messages_zh.js

@@ -20,7 +20,7 @@ $.extend($.validator.messages, {
 	number: "请输入有效的数字",
 	digits: "只能输入数字",
 	creditcard: "请输入有效的信用卡号码",
-	equalTo: "你的输入不相同",
+	equalTo: "两次输入的密码不一致",
 	extension: "请输入有效的后缀",
 	maxlength: $.validator.format("最多可以输入 {0} 个字符"),
 	minlength: $.validator.format("最少要输入 {0} 个字符"),
@@ -30,4 +30,4 @@ $.extend($.validator.messages, {
 	min: $.validator.format("请输入不小于 {0} 的数值")
 });
 
-}));
+}));

+ 68 - 0
app/public/js/msg_box.js

@@ -0,0 +1,68 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+(function($){
+    // setting = {
+    //     id: 'calc-type',
+    //     title: '提示',
+    //     message: '切换计量模式,已计量数据会被清空。',
+    //     ok: {
+    //         caption: '确定',
+    //         //callback
+    //     },
+    //     cancel: {
+    //         caption: '取消',
+    //         //callback
+    //     }
+    // };
+    $.msgBox = function(setting) {
+        const html = [];
+        html.push('<div class="modal fade" data-backdrop="static" id="' + setting.id + '">');
+        html.push('<div class="modal-dialog " role="document" >');
+        html.push('<div class="modal-content">');
+        html.push('<div class="modal-header">', '<h5 class="modal-title">', setting.title, '</h5>','</div>');
+        html.push('<div class="modal-body">', '<h5>', setting.message, '</h5>', '</div>');
+        html.push('<div class="modal-footer">');
+        if (setting.cancel) {
+            html.push('<button type="button" class="btn btn-secondary btn-sm" id="' + setting.id + '-cancel">', setting.cancel.caption, '</button>');
+        }
+        html.push('<button type="button" class="btn btn-primary btn-sm" id="' + setting.id + '-ok">', setting.ok.caption, '</button>');
+        html.push('</div>');
+        html.push('</div>');
+        html.push('</div>');
+        html.push('</div>');
+        $('body').append(html.join(''));
+
+        const obj = $('#' + setting.id);
+        if (!obj) return;
+
+        const btnOk = $('#' + setting.id + '-ok'), btnCancel =  $('#' + setting.id + '-cancel');
+        if (btnOk) {
+            btnOk.on('click', function () {
+                if (setting.ok.callback) {
+                    setting.ok.callback();
+                }
+                obj.modal('hide');
+            });
+        }
+        if (btnCancel) {
+            btnCancel.on('click', function () {
+                if (setting.cancel.callback) {
+                    setting.cancel.callback();
+                }
+                obj.modal('hide');
+            });
+        }
+        obj.on('hidden.bs.modal', function () {
+            setTimeout(() => { obj.remove(); }, 1000);
+        });
+        obj.modal('show');
+    }
+})(jQuery);

+ 1 - 0
app/public/js/profile.js

@@ -6,6 +6,7 @@
  * @version
  */
 $(document).ready(function() {
+    autoFlashHeight();
     try {
         if (user !== '') {
             $(".title-bar h2").text(user);

+ 76 - 5
app/public/js/stage.js

@@ -32,6 +32,7 @@ function customColDisplay () {
         { title: '本期批注', fields: ['postil'], visible: true },
         { title: '图册号', fields: ['drawing_code'], visible: true },
         { title: '备注', fields: ['memo'], visible: true },
+        { title: '总额计量', fields: ['is_tp'], visible: true},
     ];
     if (checkTzMeasureType()) {
         defaultSetting.splice(0, 1);
@@ -135,7 +136,7 @@ $(document).ready(() => {
         stageId: 'id',
     };
     // 台账树结构计算相关设置
-    stageTreeSetting.updateFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil'];
+    stageTreeSetting.updateFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil', 'used'];
     stageTreeSetting.calcFields = ['deal_tp', 'total_price', 'contract_tp', 'qc_tp', 'gather_tp',
         'pre_contract_tp', 'pre_qc_tp', 'pre_gather_tp', 'end_contract_tp', 'end_qc_tp', 'end_gather_tp'];
     stageTreeSetting.calcFun = function (node) {
@@ -590,7 +591,7 @@ $(document).ready(() => {
             }
         },
         selectionChanged: function (e, info) {
-            if (!info.oldSelections[0] || info.newSelections[0].row !== info.oldSelections[0].row) {
+            if (!info.oldSelections || !info.oldSelections[0] || info.newSelections[0].row !== info.oldSelections[0].row) {
                 stagePosSpreadObj.loadCurPosData();
                 SpreadJsObj.resetTopAndSelect(spSpread.getActiveSheet());
                 if (posSearch) {
@@ -830,12 +831,84 @@ $(document).ready(() => {
         topRowChanged(e, info) {
             SpreadJsObj.saveTopAndSelect(info.sheet, ckBillsSpread);
         },
+        editStarting(e, info) {
+            if (!info.sheet.zh_setting || !info.sheet.zh_tree) return;
+            const col = info.sheet.zh_setting.cols[info.col];
+            const node = info.sheet.zh_tree.nodes[info.row];
+            switch (col.field) {
+                case 'contract_qty':
+                case 'qc_qty':
+                    info.cancel = node.is_tp;
+                    break;
+                case 'contract_tp':
+                    info.cancel = !node.is_tp;
+                    break;
+                case 'is_tp':
+                    const posRange = stagePos.getLedgerPos(node.id);
+                    info.cancel = node.pre_used || node.unit !== '总额' || (posRange && posRange.length > 0);
+                    break;
+            }
+        },
+        buttonClicked: function (e, info) {
+            if (info.sheet.zh_setting) {
+                const node = SpreadJsObj.getSelectObject(info.sheet);
+                const col = info.sheet.zh_setting.cols[info.col];
+                const posRange = stagePos.getLedgerPos(node.id);
+                if (node.pre_used || node.unit !== '总额' || (posRange && posRange.length > 0) /*|| !checkZero(node.qc_qty)*/) {
+                    SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                    return;
+                }
+
+                const postIsTp = function () {
+                    const data = { calcType: {id: node.id} };
+                    data.calcType.is_tp = info.sheet.getValue(info.row, info.col) || false;
+                    // 更新至服务器
+                    postData(window.location.pathname + '/update', {bills: data}, function (result) {
+                        const nodes = stageTree.loadPostStageData(result);
+                        stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
+                        if (detail) {
+                            detail.loadStageLedgerUpdateData(result);
+                        } else {
+                            stageIm.loadUpdateLedgerData(result);
+                        }
+                    });
+                };
+
+                if (col.field === 'is_tp') {
+                    if (info.sheet.isEditing) {
+                        info.sheet.endEdit(true);
+                    }
+
+                    if (!checkZero(node.contract_qty) || !checkZero(node.contract_tp)) {
+                        $.msgBox({
+                            id: 'calc-type',
+                            title: '提示',
+                            message: '切换计量模式,已计量数据会被清空。',
+                            ok: {
+                                caption: '确定',
+                                callback: postIsTp,
+                            },
+                            cancel: {
+                                caption: '取消',
+                                callback: function () {
+                                    SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                                }
+                            }
+                        });
+                    } else {
+                        postIsTp();
+                    }
+                }
+            }
+        },
     };
     slSpread.bind(spreadNS.Events.EditEnded, stageTreeSpreadObj.editEnded);
     slSpread.bind(spreadNS.Events.SelectionChanged, stageTreeSpreadObj.selectionChanged);
     slSpread.bind(spreadNS.Events.ClipboardPasting, stageTreeSpreadObj.clipboardPasting);
     slSpread.bind(spreadNS.Events.ClipboardPasted, stageTreeSpreadObj.clipboardPasted);
     slSpread.bind(spreadNS.Events.TopRowChanged, stageTreeSpreadObj.topRowChanged);
+    slSpread.bind(spreadNS.Events.EditStarting, stageTreeSpreadObj.editStarting);
+    slSpread.bind(spreadNS.Events.ButtonClicked, stageTreeSpreadObj.buttonClicked);
     SpreadJsObj.addDeleteBind(slSpread, stageTreeSpreadObj.deletePress);
     if (!readOnly) {
         $('#bills-expr').bind('change mouseleave', function () {
@@ -1221,9 +1294,7 @@ $(document).ready(() => {
     });
 
     // 加载计量单元数据 - 暂时统一加载,如有需要,切换成动态加载并缓存
-    console.time('loadPosFromServer');
     postData(window.location.pathname + '/load', null, function (result) {
-        console.timeEnd('loadPosFromServer');
         // 加载树结构
         stageTree.loadDatas(result.ledgerData);
         // stageTree.loadCurStageData(curStageData);
@@ -1962,7 +2033,7 @@ $(document).ready(() => {
                         $('#type-title-qc').text('本期变更计量金额');
                     } else {
                         const jlCol = self.spreadSetting.cols.find(function (x) {return x.field === 'jl'});
-                        jlCol.title = '本期计量金额';
+                        jlCol.title = '本期计量数量';
                         SpreadJsObj.reLoadSheetHeader(self.sheet);
                         $('#type-title-contract').text('本期合同计量数量');
                         $('#type-title-qc').text('本期变更计量数量');

+ 60 - 10
app/public/js/tender_list.js

@@ -45,6 +45,7 @@ const levelTreeSetting = {
 };
 const levelNodes =[];
 const tenderTree = [];
+let parentId = 0;
 function createTree() {
     const zTree = $.fn.zTree.getZTreeObj('treeLevel');
     if (zTree) {
@@ -77,7 +78,6 @@ function onDropNode(event, treeId, treeNodes, targetNode, moveType) {
     }
     resetFixNode(1);
     resetFixNode(2);
-    console.log(targetNode);
     if (targetNode.lid === 1 && treeNodes[0].children && treeNodes[0].children.length !== 0) {
         moveChildren(treeNodes[0].children, zTree.getNodeByParam('lid', 1));
     } else if (targetNode.lid !== 1) {
@@ -177,6 +177,7 @@ function getCategoryHtml() {
     }
     return html.join('');
 }
+
 // 初始化TenderTree数据
 function initTenderTree () {
     const levelCategory = category.filter(function (c) {
@@ -201,6 +202,7 @@ function initTenderTree () {
                 name: cateValue.value,
                 children: [],
                 level: category.level,
+                sort_id: ++parentId,
             };
             array.push(cate);
         }
@@ -246,13 +248,13 @@ function initTenderTree () {
         }
     }
 }
-function recursiveGetTenderNodeHtml (node, arr) {
+function recursiveGetTenderNodeHtml (node, arr, pid) {
     const html = [];
-    html.push('<tr>');
+    html.push('<tr pid="' + pid + '">');
     // 名称
     html.push('<td class="in-' + node.level + '">');
     if (node.cid) {
-        html.push('<i class="fa fa-folder-o"></i> ', node.name);
+        html.push('<span class="fold-switch mr-1" title="收起" cid="'+ node.sort_id +'"><i class="fa fa-minus-square-o"></i></span></i> <i class="fa fa-folder-o"></i> ', node.name);
     } else {
         html.push('<span class="text-muted mr-2">');
         html.push(arr.indexOf(node) === arr.length - 1 ? '└' : '├');
@@ -284,7 +286,7 @@ function recursiveGetTenderNodeHtml (node, arr) {
     html.push('</tr>');
     if (node.children) {
         for (const c of node.children) {
-            html.push(recursiveGetTenderNodeHtml(c, node.children));
+            html.push(recursiveGetTenderNodeHtml(c, node.children, node.sort_id));
         }
     }
     return html.join('');
@@ -302,7 +304,7 @@ function getTenderTreeHtml () {
         html.push('<th>', '审批状态', '</th>');
         html.push('</tr>', '</thead>');
         for (const t of tenderTree) {
-            html.push(recursiveGetTenderNodeHtml(t, tenderTree));
+            html.push(recursiveGetTenderNodeHtml(t, tenderTree, ''));
         }
         html.push('</table>');
         return html.join('');
@@ -335,6 +337,7 @@ $(document).ready(() => {
     $('.modal-body', '#add-bd').append(getCategoryHtml());
     // 初始化标段树结构
     initTenderTree();
+    console.log(tenderTree);
     $('.c-body').html(getTenderTreeHtml());
     bindTenderUrl();
     // 分类
@@ -378,11 +381,11 @@ $(document).ready(() => {
         }
         for (const c of category) {
             const cate = {cid: c.id};
-            if (c.type === categoryType.key.dropDown) {
+            // if (c.type === categoryType.key.dropDown) {
                 cate.value = parseInt($('select', '[cate-id=' + c.id + ']').val());
-            } else if (c.type === categoryType.key.radio) {
-                cate.value = parseInt($('input:checked', '[cate-id=' + c.id + ']').val());
-            }
+            // } else if (c.type === categoryType.key.radio) {
+            //     cate.value = parseInt($('input:checked', '[cate-id=' + c.id + ']').val());
+            // }
             data.category.push(cate);
         }
         $('#hide-all').show();
@@ -396,4 +399,51 @@ $(document).ready(() => {
             $('#hide-all').hide();
         });
     });
+
+    // 展开和收起
+    $('body').on('click', '.fold-switch', function () {
+        if ($(this).children('i').hasClass('fa-minus-square-o')) {
+            $(this).children('i').removeClass('fa-minus-square-o').addClass('fa-plus-square-o');
+            $(this).attr('title', '展开');
+            const cid = $(this).attr('cid');
+            const node = findTenderTreeNode(parseInt(cid), tenderTree);
+            doTrStatus(returnItem, 'hide');
+        } else {
+            $(this).children('i').removeClass('fa-plus-square-o').addClass('fa-minus-square-o');
+            $(this).attr('title', '收起');
+            const cid = $(this).attr('cid');
+            const node = findTenderTreeNode(parseInt(cid), tenderTree);
+            doTrStatus(returnItem, 'show');
+        }
+    })
 });
+
+function doTrStatus(node, status) {
+    if (status === 'show') {
+        $('.c-body').find('tr[pid="'+ node.sort_id +'"]').show();
+        $('.c-body').find('tr[pid="'+ node.sort_id +'"] .fold-switch').attr('title', '收起');
+        $('.c-body').find('tr[pid="'+ node.sort_id +'"] .fold-switch i').removeClass('fa-plus-square-o').removeClass('fa-minus-square-o').addClass('fa-minus-square-o');
+    } else {
+        $('.c-body').find('tr[pid="'+ node.sort_id +'"]').hide();
+        $('.c-body').find('tr[pid="'+ node.sort_id +'"] .fold-switch').attr('title', '展开');
+        $('.c-body').find('tr[pid="'+ node.sort_id +'"] .fold-switch i').removeClass('fa-minus-square-o').removeClass('fa-plus-square-o').addClass('fa-plus-square-o');
+
+    }
+    // 判断是否还有一层
+    if (node.children) {
+        for (const c of node.children) {
+            doTrStatus(c, status);
+        }
+    }
+}
+let returnItem;
+const findTenderTreeNode = function(sortId, tree) {
+    tree.forEach((item) => {
+        if (item.sort_id !== undefined && item.sort_id === sortId) {
+            returnItem = item;
+            return item;
+        } else if (item.children && item.children.length > 0) {
+            findTenderTreeNode(sortId, item.children);
+        }
+    });
+}

+ 2 - 0
app/service/pos.js

@@ -150,7 +150,9 @@ module.exports = app => {
 
                 const transaction = await this.db.beginTransaction();
                 try {
+                    console.log(data);
                     transaction.update(this.tableName, data);
+                    console.log(updateBills);
                     transaction.update(this.ctx.service.ledger.tableName, updateBills);
                     await transaction.commit();
                     updateBills.ledger_id = bills.ledger_id;

+ 25 - 0
app/service/stage_bills.js

@@ -328,6 +328,31 @@ module.exports = app => {
             }
         }
 
+        async updateStageBillsCalcType(data) {
+            const stageBills = await this.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, data.id);
+            const updateData = {contract_qty: null, contract_tp: null};
+
+            const transaction = await this.db.beginTransaction();
+            try {
+                await transaction.update(this.ctx.service.ledger.tableName, data);
+                if (!stageBills || stageBills.times !== this.ctx.stage.curTimes || stageBills.order !== this.ctx.stage.curOrder) {
+                    await this._insertStageBillsData(transaction, updateData, stageBills, ledgerBills);
+                } else {
+                    updateData.id = stageBills.id;
+                    await transaction.update(this.tableName, updateData);
+                }
+                await transaction.update(this.tableName, updateData);
+                await transaction.commit();
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+
+            const bills = await this.ctx.service.ledger.getDataById(data.id);
+            const curStageData = await this.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, [data.id]);
+            return {bills: [bills], curStageData: curStageData};
+        }
+
         async getSumTotalPrice(stage) {
             const sql = 'SELECT Sum(`contract_tp`) As `contract_tp`, Sum(`qc_tp`) As `qc_tp` FROM ' + this.tableName + ' As Bills ' +
                 '  INNER JOIN ( ' +

+ 0 - 2
app/view/ledger/audit.ejs

@@ -93,8 +93,6 @@
 <script type="text/javascript">
     const tender = JSON.parse('<%- JSON.stringify(tender) %>');
     const measureType = JSON.parse('<%- JSON.stringify(measureType) %>');
-    let ledger = '<%- ledger %>';
-    ledger = JSON.parse(ledger);
     let ledgerSpreadSetting = '<%- ledgerSpreadSetting %>';
     ledgerSpreadSetting = JSON.parse(ledgerSpreadSetting);
     let posSpreadSetting = JSON.parse('<%- posSpreadSetting %>');

+ 15 - 13
app/view/profile/info.ejs

@@ -7,19 +7,21 @@
     </div>
     <div class="content-wrap">
         <div class="c-body">
-            <div class="row m-0">
-                <div class="col-5 my-3">
-                    <!--账号资料-->
-                    <form action="/profile/save" method="post" id="base-form">
-                        <input-text label="账号" value="<%= accountData.account %>" readonly="readonly"></input-text>
-                        <input-text label="姓名" value="<%= accountData.name %>" placeholder="请输入姓名" name="name"></input-text>
-                        <input-text label="单位" value="<%= accountData.company %>" name="company"></input-text>
-                        <input-text label="角色/职称" value="<%= accountData.role %>" name="role"></input-text>
-                        <input-text label="手机" value="<%= accountData.mobile %>" name="mobile" maxlength="11"></input-text>
-                        <input-text label="电话" value="<%= accountData.telephone %>" name="telephone"></input-text>
-                        <input type="hidden" name="_csrf" value="<%= ctx.csrf %>">
-                        <button type="submit" class="btn btn-primary btn-sm" id="base-submit">确认修改</button>
-                    </form>
+            <div class="sjs-height-0">
+                <div class="row m-0">
+                    <div class="col-5 my-3">
+                        <!--账号资料-->
+                        <form action="/profile/save" method="post" id="base-form">
+                            <input-text label="账号" value="<%= accountData.account %>" readonly="readonly"></input-text>
+                            <input-text label="姓名" value="<%= accountData.name %>" placeholder="请输入姓名" name="name"></input-text>
+                            <input-text label="单位" value="<%= accountData.company %>" name="company"></input-text>
+                            <input-text label="角色/职称" value="<%= accountData.role %>" name="role"></input-text>
+                            <input-text label="手机" value="<%= accountData.mobile %>" name="mobile" maxlength="11"></input-text>
+                            <input-text label="电话" value="<%= accountData.telephone %>" name="telephone"></input-text>
+                            <input type="hidden" name="_csrf" value="<%= ctx.csrf %>">
+                            <button type="submit" class="btn btn-primary btn-sm" id="base-submit">确认修改</button>
+                        </form>
+                    </div>
                 </div>
             </div>
         </div>

+ 16 - 14
app/view/profile/safe.ejs

@@ -7,20 +7,22 @@
     </div>
     <div class="content-wrap">
         <div class="c-body">
-            <div class="row m-0">
-                <div class="col-5 my-3">
-                    <!--账号安全-->
-                    <form action="/profile/password" method="post" id="password-form">
-                        <% if(accountData.password !== 'SSO password') { %>
-                        <input-text label="旧密码" password="true" name="password"></input-text>
-                        <input-text label="新密码" password="true" name="new_password" id="new_password"></input-text>
-                        <input-text label="确认新密码" password="true" name="confirm_password"></input-text>
-                        <input type="hidden" name="_csrf" value="<%= ctx.csrf %>">
-                        <button type="submit" class="btn btn-primary btn-sm" id="modify-password">修改密码</button>
-                        <% } else { %>
-                        <p>SSO用户请到<a href="#">此处</a>修改密码</p>
-                        <% } %>
-                    </form>
+            <div class="sjs-height-0">
+                <div class="row m-0">
+                    <div class="col-5 my-3">
+                        <!--账号安全-->
+                        <form action="/profile/password" method="post" id="password-form">
+                            <% if(accountData.password !== 'SSO password') { %>
+                                <input-text label="旧密码" password="true" name="password"></input-text>
+                                <input-text label="新密码" password="true" name="new_password" id="new_password"></input-text>
+                                <input-text label="确认新密码" password="true" name="confirm_password"></input-text>
+                                <input type="hidden" name="_csrf" value="<%= ctx.csrf %>">
+                                <button type="submit" class="btn btn-primary btn-sm" id="modify-password">修改密码</button>
+                            <% } else { %>
+                                <p>SSO用户请到<a href="#">此处</a>修改密码</p>
+                            <% } %>
+                        </form>
+                    </div>
                 </div>
             </div>
         </div>

+ 2 - 0
app/view/profile/sign.ejs

@@ -7,6 +7,7 @@
     </div>
     <div class="content-wrap">
         <div class="c-body">
+            <div class="sjs-height-0">
             <div class="row m-0">
                 <div class="col-5 my-3">
                     <!--账号资料-->
@@ -48,6 +49,7 @@
                     </form>
                 </div>
             </div>
+            </div>
         </div>
     </div>
 </div>

+ 2 - 0
app/view/profile/sms.ejs

@@ -7,6 +7,7 @@
     </div>
     <div class="content-wrap">
         <div class="c-body">
+            <div class="sjs-height-0">
             <div class="row m-0">
                 <div class="col-5 my-3">
                     <% if (accountData.auth_mobile !== '') { %>
@@ -67,6 +68,7 @@
                     <% } %>
                 </div>
             </div>
+            </div>
         </div>
     </div>
 </div>

+ 1 - 1
app/view/stage/index.ejs

@@ -524,7 +524,7 @@
     const whiteList = JSON.parse('<%- JSON.stringify(whiteList) %>');
     let attData = JSON.parse('<%- JSON.stringify(attData) %>');
     const userID = '<%- ctx.session.sessionUser.accountId %>';
-    const ckColSetting = 'stage-col-visible-1.0.2-<%- tender.id %>';
+    const ckColSetting = 'stage-col-visible-1.0.3-<%- tender.id %>';
 </script>
 <% if (ctx.stage.status === auditConst.status.uncheck && ctx.session.sessionUser.accountId === ctx.stage.user_id) {%>
 <script>

+ 1 - 0
config/web.js

@@ -216,6 +216,7 @@ const JsFiles = {
                 mergeFiles: [
                     "/public/js/sub_menu.js",
                     "/public/js/div_resizer.js",
+                    "/public/js/msg_box.js",
                     "/public/js/spreadjs_rela/spreadjs_zh.js",
                     "/public/js/zh_calc.js",
                     "/public/js/path_tree.js",