Quellcode durchsuchen

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

TonyKang vor 5 Jahren
Ursprung
Commit
81e705c84c
42 geänderte Dateien mit 682 neuen und 336 gelöschten Zeilen
  1. 7 0
      app/base/base_bills_service.js
  2. 52 1
      app/const/audit.js
  3. 15 12
      app/const/spread.js
  4. 1 1
      app/controller/deal_bills_controller.js
  5. 22 18
      app/controller/stage_controller.js
  6. 89 12
      app/controller/tender_controller.js
  7. 11 0
      app/extend/helper.js
  8. 17 13
      app/lib/pay_calc.js
  9. 5 1
      app/middleware/stage_check.js
  10. BIN
      app/public/deal_bills/签约清单示例.xlsx
  11. 33 23
      app/public/js/gcl_gather.js
  12. 51 29
      app/public/js/ledger.js
  13. 1 0
      app/public/js/ledger_audit.js
  14. 1 1
      app/public/js/profile.js
  15. 10 4
      app/public/js/stage.js
  16. 2 3
      app/public/js/stage_change.js
  17. 7 1
      app/public/js/stage_detail.js
  18. 2 2
      app/public/js/stage_gather.js
  19. 3 2
      app/public/js/stage_im.js
  20. 3 2
      app/public/js/stage_pay.js
  21. 32 14
      app/public/js/tender_list.js
  22. 1 1
      app/public/js/tender_list_manage.js
  23. 36 8
      app/public/js/tender_list_progress.js
  24. 5 1
      app/service/ledger_audit.js
  25. 1 1
      app/service/pos.js
  26. 4 0
      app/service/revise_audit.js
  27. 22 4
      app/service/stage.js
  28. 3 1
      app/service/stage_audit.js
  29. 17 2
      app/service/stage_pay.js
  30. 4 4
      app/service/tender.js
  31. 11 15
      app/service/valuation.js
  32. 1 1
      app/view/dashboard/index.ejs
  33. 1 1
      app/view/ledger/explode_modal.ejs
  34. 5 5
      app/view/stage/audit_btn.ejs
  35. 1 1
      app/view/stage/audit_modal.ejs
  36. 2 0
      app/view/stage/gather.ejs
  37. 54 20
      app/view/tender/detail.ejs
  38. 0 1
      app/view/tender/index.ejs
  39. 0 1
      app/view/tender/manage.ejs
  40. 11 0
      app/view/tender/manage_modal.ejs
  41. 0 1
      app/view/tender/progress.ejs
  42. 139 129
      config/web.js

+ 7 - 0
app/base/base_bills_service.js

@@ -422,6 +422,13 @@ class BaseBillsSerivce extends TreeService {
         return { update: await this.getDataById(ids) };
     }
 
+    // 统计方法
+    async addUp(condition) {
+        const sql = 'SELECT Sum(total_price) As total_price, Sum(deal_tp) As deal_tp' +
+            '  FROM ' + this.tableName + this.ctx.helper.whereSql(condition);
+        const result = await this.db.queryOne(sql);
+        return result;
+    }
 }
 
 module.exports = BaseBillsSerivce;

+ 52 - 1
app/const/audit.js

@@ -89,7 +89,7 @@ const stage = (function () {
         checked: 3, // 审批通过
         checkNo: 4, // 审批退回原报
         checkNoPre: 5, // 审批退回上一人
-        checkAgain: 6, // 重新审批
+        checkAgain: 6, // 重新审批 // 该状态仅可用于,终审退回时,修改原终审的审批状态,并同时新增一条新的终审审批中记录
     };
 
     // 流程状态提示
@@ -266,10 +266,61 @@ filter.statusString[filter.status.checking] = '进行中';
 filter.statusString[filter.status.checked] = '已完成';
 // filter.statusString[filter.status.checkNo] = '终止';
 
+// 材料调差审批流程
+const material = (function () {
+    const status = {
+        uncheck: 1, // 待上报
+        checking: 2, // 待审批|审批中
+        checked: 3, // 审批通过
+        checkNo: 4, // 审批退回
+    };
+    // 流程状态提示
+    const statusString = [];
+    statusString[status.uncheck] = '待上报';
+    statusString[status.checking] = '审批中';
+    statusString[status.checked] = '审批通过';
+    statusString[status.checkNo] = '审批退回';
+    // 流程状态样式
+    const statusClass = [];
+    statusClass[status.uncheck] = '';
+    statusClass[status.checking] = '';
+    statusClass[status.checked] = 'text-success';
+    statusClass[status.checkNo] = 'text-warning';
+
+    // 按钮
+    const statusButton = [];
+    statusButton[status.uncheck] = '待上报';
+    statusButton[status.checking] = '审批';
+    statusButton[status.checked] = '';
+    statusButton[status.checkNo] = '重新上报';
+
+    // 按钮样式
+    const statusButtonClass = [];
+    statusButtonClass[status.uncheck] = 'btn-primary';
+    statusButtonClass[status.checking] = 'btn-success';
+    statusButtonClass[status.checked] = '';
+    statusButtonClass[status.checkNo] = 'btn-warning';
+
+    // 描述文本
+    const auditProgress = [];
+    auditProgress[status.uncheck] = '待上报';
+    auditProgress[status.checking] = '审批中';
+    auditProgress[status.checked] = '审批通过';
+    auditProgress[status.checkNo] = '审批退回';
+    // 样式
+    const auditProgressClass = [];
+    auditProgressClass[status.uncheck] = '';
+    auditProgressClass[status.checking] = 'text-warning';
+    auditProgressClass[status.checked] = 'text-success';
+    auditProgressClass[status.checkNo] = 'text-warning';
+    return { status, statusString, statusClass, statusButton, statusButtonClass, auditProgress, auditProgressClass };
+})();
+
 module.exports = {
     ledger,
     stage,
     revise,
+    material,
     flow: {
         status,
         statusString,

+ 15 - 12
app/const/spread.js

@@ -113,8 +113,9 @@ const stageTz = {
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_contract_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '截止本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_qc_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_qc_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
-            {title: '截止本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
+            {title: '截止本期完成计量|数量', colSpan: '3|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_gather_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
+            {title: '|完成率(%)', colSpan: '1', rowSpan: '|1', field: 'end_gather_percent', hAlign: 2, width: 80, readOnly: true, type: 'Number'},
             {title: '合同|设计数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'deal_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
             {title: '|设计数量2',  colSpan: '|1', rowSpan: '|1', field: 'deal_dgn_qty2', hAlign: 2, width: 60, type: 'Number'},
             {title: '变更|设计数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'c_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
@@ -122,7 +123,7 @@ const stageTz = {
             {title: '经济指标',  colSpan: '1', rowSpan: '2', field: 'final_dgn_price', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {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: 'percent', hAlign: 0, width: 100, readOnly: true, type: 'Number'},
+            //{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', readOnly: true},
         ],
         emptyRows: 0,
@@ -171,8 +172,9 @@ const stageCl = {
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_contract_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '截止本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_qc_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_qc_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
-            {title: '截止本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
+            {title: '截止本期完成计量|数量', colSpan: '3|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_gather_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
+            {title: '|完成率(%)', colSpan: '1', rowSpan: '|1', field: 'end_gather_percent', hAlign: 2, width: 80, readOnly: true, type: 'Number'},
             {title: '合同|设计数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'deal_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
             {title: '|设计数量2',  colSpan: '|1', rowSpan: '|1', field: 'deal_dgn_qty2', hAlign: 2, width: 60, type: 'Number'},
             {title: '变更|设计数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'c_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
@@ -180,7 +182,7 @@ const stageCl = {
             {title: '经济指标',  colSpan: '1', rowSpan: '2', field: 'final_dgn_price', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {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: 'percent', hAlign: 0, width: 100, readOnly: true, type: 'Number'},
+            //{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', readOnly: true},
         ],
         emptyRows: 0,
@@ -233,8 +235,9 @@ const stageNoCl = {
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_contract_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '截止本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_qc_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_qc_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
-            {title: '截止本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
+            {title: '截止本期完成计量|数量', colSpan: '3|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_gather_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
+            {title: '|完成率(%)', colSpan: '1', rowSpan: '|1', field: 'end_gather_percent', hAlign: 2, width: 80, readOnly: true, type: 'Number'},
             {title: '合同|设计数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'deal_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
             {title: '|设计数量2',  colSpan: '|1', rowSpan: '|1', field: 'deal_dgn_qty2', hAlign: 2, width: 60, type: 'Number'},
             {title: '变更|设计数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'c_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
@@ -242,7 +245,6 @@ const stageNoCl = {
             {title: '经济指标',  colSpan: '1', rowSpan: '2', field: 'final_dgn_price', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {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: 'percent', hAlign: 0, width: 100, readOnly: true, type: 'Number'},
             {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip', readOnly: true},
         ],
         emptyRows: 0,
@@ -295,11 +297,12 @@ const stageGather = {
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_contract_tp', hAlign: 2, width: 60, type: 'Number'},
             {title: '截止本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_qc_qty', hAlign: 2, width: 60, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_qc_tp', hAlign: 2, width: 60, type: 'Number'},
-            {title: '截止本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '截止本期完成计量|数量', colSpan: '3|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_gather_tp', hAlign: 2, width: 60, type: 'Number'},
-            {title: '施工图复核+变更令|数量', colSpan: '3|1', rowSpan: '1|1', field: 'final_qty', hAlign: 2, width: 60, type: 'Number'},
-            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'final_tp', hAlign: 2, width: 60, type: 'Number'},
-            {title: '|累计完成率(%)', colSpan: '|1', rowSpan: '|1', field: 'percent', hAlign: 0, width: 100, type: 'Number'},
+            {title: '|完成率(%)', colSpan: '1', rowSpan: '|1', field: 'end_gather_percent', hAlign: 2, width: 80, readOnly: true, type: 'Number'},
+            {title: '台账+变更令|数量', colSpan: '3|1', rowSpan: '1|1', field: 'end_final_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_final_tp', hAlign: 2, width: 60, type: 'Number'},
+            //{title: '|累计完成率(%)', colSpan: '|1', rowSpan: '|1', field: 'percent', hAlign: 0, width: 100, type: 'Number'},
         ],
         emptyRows: 0,
         headRows: 2,
@@ -316,10 +319,10 @@ const stageGather = {
             {title: '本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
             {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number'},
             {title: '|完成', colSpan: '|1', rowSpan: '1|1', field: 'gather_qty', hAlign: 2, width: 60, type: 'Number'},
-            {title: '截止本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'end_contract_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '截止本期计量数量|合同', colSpan: '4|1', rowSpan: '1|1', field: 'end_contract_qty', hAlign: 2, width: 60, type: 'Number'},
             {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'end_qc_qty', hAlign: 2, width: 60, type: 'Number'},
             {title: '|完成', colSpan: '|1', rowSpan: '|1', field: 'end_gather_qty', hAlign: 2, width: 60, type: 'Number'},
-            {title: '完成率(%)', colSpan: '1', rowSpan: '2', field: 'percent', hAlign: 0, width: 100, type: 'Number'},
+            {title: '|完成率(%)', colSpan: '1', rowSpan: '|1', field: 'end_gather_percent', hAlign: 2, width: 80, readOnly: true, type: 'Number'},
             {title: '单位工程', colSpan: '1', rowSpan: '2', field: 'dwgc', hAlign: 0, width: 80, formatter: '@'},
             {title: '分部工程', colSpan: '1', rowSpan: '2', field: 'fbgc', hAlign: 0, width: 80, formatter: '@'},
             {title: '分项工程', colSpan: '1', rowSpan: '2', field: 'fxgc', hAlign: 0, width: 80, formatter: '@'},

+ 1 - 1
app/controller/deal_bills_controller.js

@@ -104,7 +104,7 @@ module.exports = app => {
                 try {
                     let fileName;
                     if (file === 'template.xls') {
-                        fileName = this.app.baseDir + '/app/public/deal_bills/deal_template.xls';
+                        fileName = this.app.baseDir + '/app/public/deal_bills/签约清单示例.xlsx';
                     } else {
                         const create_time = Date.parse(new Date()) / 1000;
                         fileName = this.app.baseDir + '/app/public/deal_bills/downloads/' + ctx.tender.id + '-' + create_time + '.xlsx';

+ 22 - 18
app/controller/stage_controller.js

@@ -569,14 +569,7 @@ module.exports = app => {
                     }
                 }
                 renderData.dealPay = dealPay;
-                // if (dealPay && dealPay.length > 0) {
-                //     renderData.dealPay = dealPay;
-                // } else {
-                //     await ctx.service.pay.addDefaultPayData(this.ctx.tender.id);
-                //     await ctx.service.stagePay.addInitialStageData(ctx.stage);
-                //     renderData.dealPay = await ctx.service.stagePay.getStagePays(ctx.stage);
-                // }
-                renderData.calcBase = await ctx.service.stage.getStagePayCalcBase();
+                renderData.calcBase = await ctx.service.stage.getStagePayCalcBase(ctx.stage, ctx.tender.info);
                 renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.pay);
                 renderData.whiteList = this.ctx.app.config.multipart.whitelist;
 
@@ -585,9 +578,11 @@ module.exports = app => {
                     (ctx.stage.status === auditConst.status.checkNoPre && ctx.session.sessionUser.accountId === ctx.stage.curAuditor.aid) ||
                     (ctx.stage.status === auditConst.status.checking && ctx.stage.curAuditor && ctx.stage.curAuditor.aid === ctx.session.sessionUser.accountId);
 
-                // 计算 本期金额
-                const payCalculator = new PayCalculator(this.ctx, this.ctx.tender.info.decimal);
-                await payCalculator.calculateAll(renderData.dealPay);
+                if (!ctx.stage.readOnly) {
+                    // 计算 本期金额
+                    const payCalculator = new PayCalculator(ctx, ctx.stage, ctx.tender.info);
+                    await payCalculator.calculateAll(renderData.dealPay);
+                }
                 await this.layout('stage/pay.ejs', renderData, 'stage/pay_modal.ejs');
             } catch (err) {
                 console.log(err);
@@ -615,7 +610,7 @@ module.exports = app => {
 
                 const data = JSON.parse(ctx.request.body.data);
                 const responseData = { err: 0, msg: '', data: {}, };
-                const payCalculator = new PayCalculator(this.ctx, this.ctx.tender.info.decimal);
+                const payCalculator = new PayCalculator(ctx, ctx.stage, ctx.tender.info);
                 switch (data.type) {
                     case 'add':
                         responseData.data = await ctx.service.pay.add();
@@ -950,12 +945,12 @@ module.exports = app => {
                     col.formatter = formatter;
                 }
             }
-            const tpFormatter = this.ctx.helper.getNumberFormatter(this.ctx.tender.info.decimal.tp);
-            const upFormatter = this.ctx.helper.getNumberFormatter(2);
+            //const tpFormatter = this.ctx.helper.getNumberFormatter(this.ctx.tender.info.decimal.tp);
+            //const upFormatter = this.ctx.helper.getNumberFormatter(2);
             const gcl = JSON.parse(JSON.stringify(spreadConst.stageGather.gcl));
-            setColFormat(gcl.cols, 'unit_price', upFormatter);
-            setColFormat(gcl.cols, 'total_price', tpFormatter);
-            setColFormat(gcl.cols, 'tp', tpFormatter);
+            //setColFormat(gcl.cols, 'unit_price', upFormatter);
+            //setColFormat(gcl.cols, 'total_price', tpFormatter);
+            //setColFormat(gcl.cols, 'tp', tpFormatter);
 
             const leafXmj = JSON.parse(JSON.stringify(spreadConst.stageGather.leafXmj));
             const tender = this.ctx.tender;
@@ -976,12 +971,21 @@ module.exports = app => {
                 [renderData.gclSpread, renderData.leafXmjSpread] = this._getGatherSpreadSetting();
                 renderData.ledger = await ctx.service.ledger.getData(ctx.tender.id);
                 renderData.curLedgerData = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder);
+                if (ctx.stage.order > 1) {
+                    renderData.preLedgerData = await ctx.service.stageBillsFinal.getFinalData(ctx.tender.data, ctx.stage.order - 1);
+                } else {
+                    renderData.preLedgerData = [];
+                }
 
                 renderData.pos = await ctx.service.pos.getPosData({tid: ctx.tender.id});
                 // todo 根据当前人,或指定对象查询数据
                 renderData.curPosData = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id,
                     ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder);
-                //renderData.gcl = await this.ctx.service.ledger.getAllLeafGclBills(this.ctx.tender.id);
+                if (ctx.stage.order > 1) {
+                    renderData.prePosData = await ctx.service.stagePosFinal.getFinalData(ctx.tender.data, ctx.stage.order - 1);
+                } else {
+                    renderData.prePosData = [];
+                }
                 renderData.dealBills = await ctx.service.dealBills.getAllDataByCondition({ where: {tender_id: this.ctx.tender.id} });
 
                 renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.gather);

+ 89 - 12
app/controller/tender_controller.js

@@ -31,16 +31,26 @@ module.exports = app => {
             ctx.showTitle = true;
         }
 
-        async _list(view, setting, modal = '', listStatus = '') {
+        async _list(view, modal = '') {
             try {
                 // 获取用户新建标段权利
                 const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId);
                 const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null;
 
-                const tenderList = await this.ctx.service.tender.getList(listStatus, userPermission);
+                const tenderList = await this.ctx.service.tender.getList('', userPermission);
                 for (const t of tenderList) {
-                    t.lastStage = await this.ctx.service.stage.getLastestStage(t.id, true);
-                    t.completeStage = await this.ctx.service.stage.getLastestCompleteStage(t.id);
+                    if (t.user_id === this.ctx.session.sessionUser.accountId && (
+                        t.ledger_status === auditConst.ledger.status.checkNo || t.ledger_status === auditConst.ledger.status.uncheck)) {
+                        const sum = await this.ctx.service.ledger.addUp({tender_id: t.id, is_leaf: true});
+                        t.total_price = sum.total_price;
+                        t.deal_tp = sum.deal_tp;
+                    }
+                    if (t.ledger_status === auditConst.ledger.status.checked) {
+                        t.lastStage = await this.ctx.service.stage.getLastestStage(t.id, true);
+                        if (t.lastStage) {
+                            await this.ctx.service.stage.checkStageGatherData(t.lastStage);
+                        }
+                    }
                 }
                 const categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id);
                 const valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id);
@@ -49,7 +59,6 @@ module.exports = app => {
                     tenderConst,
                     settingConst,
                     categoryData,
-                    tableColSetting: setting,
                     measureType: tenderConst.measureType,
                     jsFiles: this.app.jsFiles.common.concat(this.jsFiles),
                     auditConst,
@@ -58,6 +67,7 @@ module.exports = app => {
                 };
                 await this.layout(view, renderData, modal);
             } catch (err) {
+                console.log(err);
                 this.log(err);
                 this.ctx.redirect('/dashboard');
             }
@@ -71,7 +81,7 @@ module.exports = app => {
          */
         async listInfo(ctx) {
             this.jsFiles = this.app.jsFiles.tender.list;
-            await this._list('tender/index.ejs', tenderConst.infoTableCol, 'tender/modal.ejs');
+            await this._list('tender/index.ejs', 'tender/modal.ejs');
         }
 
         /**
@@ -82,7 +92,7 @@ module.exports = app => {
          */
         async listProgress(ctx) {
             this.jsFiles = this.app.jsFiles.tender.progress;
-            await this._list('tender/progress.ejs', tenderConst.progressTableCol, 'tender/modal.ejs');
+            await this._list('tender/progress.ejs', 'tender/modal.ejs');
         }
 
         /**
@@ -97,10 +107,31 @@ module.exports = app => {
             const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId);
             const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null;
             if (userPermission !== null && userPermission.tender !== undefined && userPermission.tender.indexOf('1') !== -1) {
-                this.jsFiles = this.app.jsFiles.tender.manage;
-                await this._list('tender/manage.ejs', tenderConst.manageTableCol, 'tender/manage_modal.ejs', 'manage');
+                // 获取用户新建标段权利
+                const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId);
+                const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null;
+
+                const tenderList = await this.ctx.service.tender.getList('manage', userPermission);
+                for (const t of tenderList) {
+                    t.lastStage = await this.ctx.service.stage.getLastestStage(t.id, true);
+                    t.completeStage = await this.ctx.service.stage.getLastestCompleteStage(t.id);
+                }
+                const categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id);
+                const valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id);
+                const renderData = {
+                    tenderList,
+                    tenderConst,
+                    settingConst,
+                    categoryData,
+                    measureType: tenderConst.measureType,
+                    jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.tender.manage),
+                    auditConst,
+                    userPermission,
+                    valuations,
+                };
+                await this.layout('tender/manage.ejs', renderData, 'tender/manage_modal.ejs');
             } else {
-                this.ctx.redirect('/dashboard');
+                this.ctx.redirect(ctx.request.header.referer);
             }
         }
 
@@ -196,14 +227,60 @@ module.exports = app => {
          */
         async tenderInfo(ctx) {
             try {
-                const lastStage = await ctx.service.stage.getLastestStage(ctx.tender.id);
+                const tender = ctx.tender.data;
+                if (tender.user_id === this.ctx.session.sessionUser.accountId && (
+                    tender.ledger_status === auditConst.ledger.status.checkNo || tender.ledger_status === auditConst.ledger.status.uncheck)) {
+                    const sum = await this.ctx.service.ledger.addUp({tender_id: tender.id, is_leaf: true});
+                    tender.total_price = sum.total_price;
+                    tender.deal_tp = sum.deal_tp;
+                }
+                const stages = await ctx.service.stage.getValidStages(ctx.tender.id);
+                const lastStage = stages[0]; //await ctx.service.stage.getLastestStage(ctx.tender.id);
+                if (lastStage) {
+                    await this.ctx.service.stage.checkStageGatherData(lastStage);
+                    tender.gather_tp = ctx.helper.add(lastStage.contract_tp, lastStage.qc_tp);
+                    tender.end_contract_tp = ctx.helper.add(lastStage.contract_tp, lastStage.pre_contract_tp);
+                    tender.end_qc_tp = ctx.helper.add(lastStage.qc_tp, lastStage.pre_qc_tp);
+                    tender.end_gather_tp = ctx.helper.add(tender.end_contract_tp, tender.end_qc_tp);
+                    tender.pre_gather_tp = ctx.helper.add(lastStage.pre_contract_tp, lastStage.pre_qc_tp);
+                    tender.yf_tp = lastStage.yf_tp;
+                    tender.qc_ratio = ctx.helper.mul(ctx.helper.div(tender.end_qc_tp, tender.gather_tp, 2), 100);
+                    tender.sum = ctx.helper.add(tender.total_price, tender.end_qc_tp);
+                    tender.pre_ratio = ctx.helper.mul(ctx.helper.div(tender.pre_gather_tp, tender.sum, 2), 100);
+                    tender.cur_ratio = ctx.helper.mul(ctx.helper.div(tender.gather_tp, tender.sum, 2), 100);
+                    tender.other_tp = ctx.helper.sub(ctx.helper.sub(tender.sum, tender.pre_gather_tp), tender.gather_tp);
+                    tender.other_ratio = Math.max(0, 100 - tender.pre_ratio - tender.cur_ratio);
+                }
+                const monthProgress = [];
+                for (const s of stages) {
+                    if (s.s_time) {
+                        let progress = monthProgress.find(function (x) {
+                            return x.month === s.s_time;
+                        });
+                        if (!progress) {
+                            progress = {month: s.s_time};
+                            monthProgress.push(progress);
+                        }
+                        progress.tp = ctx.helper.add(ctx.helper.add(progress.tp, s.contract_tp), s.qc_tp);
+                    }
+                }
+                monthProgress.sort(function (x, y) {
+                    return Date.parse(x.month) - Date.parse(y.month);
+                });
+                let sum = 0;
+                for (const p of monthProgress) {
+                    sum = ctx.helper.add(sum, p.tp);
+                    p.end_tp = sum;
+                }
                 const renderData = {
-                    tender: ctx.tender.data,
+                    tender: tender,
                     tenderInfo: ctx.tender.info,
                     tenderMenu: this.menu.tenderMenu,
                     preUrl: '/tender/' + ctx.tender.id,
                     cooperation: ctx.session.sessionUser.cooperation,
                     lastStage,
+                    stages: stages.reverse(),
+                    monthProgress,
                     audit: auditConst,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.tender.info),
                 };

+ 11 - 0
app/extend/helper.js

@@ -753,4 +753,15 @@ module.exports = {
         }
         return '';
     },
+    formatMoney(s, dot = ',') {
+        if (!s) return '0.00';
+        s = parseFloat((s + "").replace(/[^\d\.-]/g, "")).toFixed(2) + "";
+        var l = s.split(".")[0].split("").reverse(),
+            r = s.split(".")[1];
+        let t = "";
+        for(let i = 0; i < l.length; i ++ )   {
+            t += l[i] + ((i + 1) % 3 == 0 && (i + 1) != l.length ? dot : "");
+        }
+        return t.split("").reverse().join("") + "." + r;
+    }
 };

+ 17 - 13
app/lib/pay_calc.js

@@ -14,10 +14,12 @@ const payType = PayConst.payType;
 const deadlineType = PayConst.deadlineType;
 
 class PayCalculate {
-    constructor (ctx, decimal) {
+    constructor (ctx, stage, tenderInfo) {
         this.ctx = ctx;
+        this.stage = stage;
         this.percentReg = /[0-9]+%/g;
-        this.decimal = decimal.pay ? decimal.payTp : decimal.tp;
+        this.tenderInfo = tenderInfo;
+        this.decimal = tenderInfo.decimal.pay ? tenderInfo.decimal.payTp : tenderInfo.decimal.tp;
     }
 
     /**
@@ -26,7 +28,7 @@ class PayCalculate {
      */
     async getCalcBase () {
         if (this.bases) { return; }
-        const bases = await this.ctx.service.stage.getStagePayCalcBase();
+        const bases = await this.ctx.service.stage.getStagePayCalcBase(this.stage, this.tenderInfo);
         this.bases = bases.sort(function (a, b) {
             return a.sort - b.sort;
             // if (a && b) {
@@ -91,10 +93,10 @@ class PayCalculate {
      */
     async calculateStartRangePrice (pays) {
         await this.getCalcBase();
-        const order = this.ctx.stage.curAuditor ? this.ctx.stage.curAuditor.order : 0;
+        const order = this.stage.curOrder;
         for (const p of pays) {
             // 非本期,本次添加的合同支付项,不允许计算,其中默认添加的合同支付项,归属于第一期原报
-            if (p.csorder === this.ctx.stage.order || (p.csorder === 0 || this.ctx.stage.order === 1)) {
+            if (p.csorder === this.stage.order || (p.csorder === 0 || this.stage.order === 1)) {
                 if (p.csaorder === order) {
                     if (!p.sprice && p.sexpr && p.sexpr !== '') {
                         p.sprice = this.ctx.helper.round(this.calculateExpr(p.sexpr), this.decimal);
@@ -113,7 +115,7 @@ class PayCalculate {
     async getAddCalcRela() {
         // todo 获取截止上期数据
         const pre = null;
-        const cur = await this.ctx.service.stageBills.getSumTotalPrice(this.ctx.stage);
+        const cur = await this.ctx.service.stageBills.getSumTotalPrice(this.stage);
         const add = {};
         if (pre) {
             add.contract_tp = this.ctx.helper.add(pre.contract_tp, cur.contract_tp);
@@ -137,7 +139,7 @@ class PayCalculate {
                 return true;
             }
         } else if (pay.dl_type === deadlineType.count.value) {
-            return this.ctx.stage.order >= pay.dl_count;
+            return this.stage.order >= pay.dl_count;
         } else {
             return false;
         }
@@ -153,9 +155,7 @@ class PayCalculate {
         const yfPay = pays.find(function (p) {
             return p.ptype === payType.yf;
         });
-        if (!yfPay) {
-            throw '合同支付数据错误';
-        }
+        if (!yfPay) return false;
         yfPay.tp = 0;
         for (const p of pays) {
             if (p.ptype === payType.normal || p.ptype === payType.wc) {
@@ -165,16 +165,20 @@ class PayCalculate {
                         const value = this.ctx.helper.round(this.calculateTpExpr(p, first, addRela), this.decimal);
                         if (p.rprice) {
                             if (this.checkDeadline(p, addRela)) {
-                                p.tp = this.ctx.helper.sub(p.rprice, p.pre_total_price);
+                                p.tp = this.ctx.helper.sub(p.rprice, p.pre_tp);
                             } else {
-                                p.tp = Math.min(this.ctx.helper.sub(p.rprice, p.pre_total_price), value);
+                                p.tp = Math.min(this.ctx.helper.sub(p.rprice, p.pre_tp), value);
                             }
                         } else {
                             p.tp = value;
                         }
                     } else if (p.tp && !this.ctx.helper.checkZero(p.tp)) {
                         if (p.rprice) {
-                            p.tp = Math.min(this.ctx.helper.sub(p.rprice, p.pre_total_price), this.ctx.helper.round(p.tp, this.decimal));
+                            if (this.checkDeadline(p, addRela)) {
+                                p.tp = this.ctx.helper.sub(p.rprice, p.pre_tp);
+                            } else {
+                                p.tp = Math.min(this.ctx.helper.sub(p.rprice, p.pre_tp), this.ctx.helper.round(p.tp, this.decimal));
+                            }
                         } else {
                             p.tp = this.ctx.helper.round(p.tp, this.decimal);
                         }

+ 5 - 1
app/middleware/stage_check.js

@@ -52,7 +52,11 @@ module.exports = options => {
             // todo 校验权限 (标段参与人、分享)
             const accountId = this.session.sessionUser.accountId, auditorIds = _.map(stage.auditors, 'aid'), shareIds = [];
             if (accountId === stage.user_id) { // 原报
-                stage.readOnly = stage.status !== status.uncheck && stage.status !== status.checkNo;
+                if (stage.curAuditor) {
+                    stage.readOnly = stage.curAuditor.aid !== accountId;
+                } else {
+                    stage.readOnly = stage.status !== status.uncheck && stage.status !== status.checkNo;
+                }
                 stage.curTimes = stage.times;
                 if (stage.status === status.uncheck || stage.status === status.checkNo) {
                     stage.curOrder = 0;

BIN
app/public/deal_bills/签约清单示例.xlsx


+ 33 - 23
app/public/js/gcl_gather.js

@@ -12,9 +12,9 @@
 const gclGatherModel = (function () {
     // 需要汇总计算的字段
     const ledgerGatherFields = ['quantity', 'total_price', 'deal_qty', 'deal_tp',
-        'contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'gather_qty', 'gather_tp',
-        'end_contract_qty', 'end_contract_tp', 'end_qc_qty', 'end_qc_tp', 'end_gather_qty', 'end_gather_tp'];
-    const posGatherFields = ['quantity', 'contract_qty', 'qc_qty', 'gather_qty', 'end_contract_qty', 'end_qc_qty', 'end_gather_qty'];
+        'contract_qty', 'contract_tp', 'qc_qty', 'qc_tp',
+        'pre_contract_qty', 'pre_contract_tp', 'pre_qc_qty', 'pre_qc_tp'];
+    const posGatherFields = ['quantity', 'contract_qty', 'qc_qty', 'gather_qty', 'pre_contract_qty', 'pre_qc_qty'];
     // 初始化 清单树
     const gsTreeSetting = {
         id: 'ledger_id',
@@ -26,29 +26,12 @@ const gclGatherModel = (function () {
         stageId: 'id',
     };
     gsTreeSetting.updateFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'];
-    gsTreeSetting.calcFields = ['deal_tp', 'total_price', 'contract_tp', 'qc_tp', 'gather_tp', 'end_contract_tp', 'end_qc_tp', 'end_gather_tp'];
-    gsTreeSetting.calcFun = function (node) {
-        if (node.children && node.children.length === 0) {
-            node.gather_qty = ZhCalc.add(node.contract_qty, node.qc_qty);
-            node.end_contract_qty = ZhCalc.add(node.pre_contract_qty, node.contract_qty);
-            node.end_qc_qty = ZhCalc.add(node.pre_qc_qty, node.qc_qty);
-            node.end_gather_qty = ZhCalc.add(node.pre_gather_qty, node.gather_qty);
-        }
-        node.gather_tp = ZhCalc.add(node.contract_tp, node.qc_tp);
-        node.end_contract_tp = ZhCalc.add(node.pre_contract_tp, node.contract_tp);
-        node.end_qc_tp = ZhCalc.add(node.pre_qc_tp, node.qc_tp);
-        node.end_gather_tp = ZhCalc.add(node.pre_gather_tp, node.gather_tp);
-        node.dgn_price = ZhCalc.round(ZhCalc.div(node.total_price, node.dgn_qty1), 2);
-    };
     const gsTree = createNewPathTree('stage', gsTreeSetting);
     // 初始化 部位明细
     const posSetting = {
         id: 'id', ledgerId: 'lid',
         updateFields: ['contract_qty', 'qc_qty'],
     };
-    posSetting.calcFun = function (pos) {
-        pos.gather_qty = ZhCalc.add(pos.contract_qty, pos.qc_qty);
-    };
     const gsPos = new StagePosData(posSetting);
     let deal = [];
 
@@ -71,10 +54,10 @@ const gclGatherModel = (function () {
         if (curStage) {
             gsTree.loadCurStageData(curStage);
         }
-        // todo 加载截止上期计量数据
+        if (preStage) {
+            gsTree.loadPreStageData(preStage);
+        }
         // todo 加载变更令数据
-        // 根据设置 计算 台账树结构
-        treeCalc.calculateAll(gsTree);
     }
 
     function loadPosData(pos, curPos, prePos) {
@@ -329,6 +312,32 @@ const gclGatherModel = (function () {
         }
     }
 
+    function calculateGatherData() {
+        for (const gcl of gclList) {
+            gcl.pre_gather_qty = ZhCalc.add(gcl.pre_contract_qty, gcl.pre_qc_qty);
+            gcl.pre_gather_tp = ZhCalc.add(gcl.pre_contract_tp, gcl.pre_qc_tp);
+            gcl.gather_qty = ZhCalc.add(gcl.contract_qty, gcl.qc_qty);
+            gcl.end_contract_qty = ZhCalc.add(gcl.pre_contract_qty, gcl.contract_qty);
+            gcl.end_qc_qty = ZhCalc.add(gcl.pre_qc_qty, gcl.qc_qty);
+            gcl.end_gather_qty = ZhCalc.add(gcl.pre_gather_qty, gcl.gather_qty);
+            gcl.end_final_qty = ZhCalc.add(gcl.end_qc_qty, gcl.quantity);
+            gcl.gather_tp = ZhCalc.add(gcl.contract_tp, gcl.qc_tp);
+            gcl.end_contract_tp = ZhCalc.add(gcl.pre_contract_tp, gcl.contract_tp);
+            gcl.end_qc_tp = ZhCalc.add(gcl.pre_qc_tp, gcl.qc_tp);
+            gcl.end_gather_tp = ZhCalc.add(gcl.pre_gather_tp, gcl.gather_tp);
+            gcl.dgn_price = ZhCalc.round(ZhCalc.div(gcl.total_price, gcl.dgn_qty1), 2);
+            gcl.end_final_tp = ZhCalc.add(gcl.end_qc_tp, gcl.total_price);
+            gcl.end_gather_percent = ZhCalc.mul(ZhCalc.div(gcl.end_gather_tp, gcl.end_final_tp), 100, 2);
+            for (const xmj of gcl.leafXmjs) {
+                xmj.pre_gather_qty = ZhCalc.add(xmj.pre_contract_qty, xmj.pre_qc_qty);
+                xmj.gather_qty = ZhCalc.add(xmj.contract_qty, xmj.qc_qty);
+                xmj.end_gather_qty = ZhCalc.add(xmj.pre_gather_qty, xmj.gather_qty);
+                xmj.end_final_qty = ZhCalc.add(xmj.end_qc_qty, xmj.quantity);
+                xmj.end_gather_percent = ZhCalc.mul(ZhCalc.div(xmj.end_gather_qty, xmj.end_final_qty), 100, 2);
+            }
+        }
+    }
+
     /**
      * 根据树结构 清单汇总
      */
@@ -338,6 +347,7 @@ const gclGatherModel = (function () {
             gclList.length = 0; //splice(0, gclList.length);
         }
         recursiveGatherGclData(gsTree.children, null);
+        calculateGatherData();
         gatherDealBillsData();
         gclList.sort(function (a, b) {
             function compareCode(code1, code2) {

+ 51 - 29
app/public/js/ledger.js

@@ -440,8 +440,16 @@ $(document).ready(function() {
                                     continue;
                                 }
                             }
-                            data[colSetting.field] = value;
-                            bPaste = true;
+                            if (colSetting.type === 'Number') {
+                                const num = _.toNumber(value);
+                                if (num) {
+                                    data[colSetting.field] = num;
+                                    bPaste = true;
+                                }
+                            } else {
+                                data[colSetting.field] = value;
+                                bPaste = true;
+                            }
                         }
                         if (bPaste) {
                             datas.push(data);
@@ -659,12 +667,28 @@ $(document).ready(function() {
                     callback: function (key, opt) {
                         treeOperationObj.addNode(ledgerSpread.getActiveSheet());
                     },
-                    visible: function(key, opt){
+                    disabled: function (key, opt) {
                         const sheet = ledgerSpread.getActiveSheet();
                         const selection = sheet.getSelections();
-                        const row = selection[0].row;
-                        const select = ledgerTree.nodes[row];
-                        return select;
+                        const sel = selection ? selection[0] : sheet.getSelections()[0];
+                        const row = sel ? sel.row : -1;
+                        const tree = sheet.zh_tree;
+                        if (!tree) return true;
+                        const first = sheet.zh_tree.nodes[row];
+                        let last = first, sameParent = true;
+                        if (sel.rowCount > 1) {
+                            for (let r = 1; r < sel.rowCount; r++) {
+                                const rNode = tree.nodes[sel.row + r];
+                                if (rNode.level > first.level) continue;
+                                if ((rNode.level < first.level) || (rNode.level === first.level && rNode.pid !== first.pid)) {
+                                    sameParent = false;
+                                    break;
+                                }
+                                last = rNode;
+                            }
+                        }
+                        const valid = !sheet.zh_setting.readOnly;
+                        return !(valid && first && first.level > 1);
                     }
                 },
                 'delete': {
@@ -673,12 +697,28 @@ $(document).ready(function() {
                     callback: function (key, opt) {
                         treeOperationObj.deleteNode(ledgerSpread.getActiveSheet());
                     },
-                    visible: function (key, opt) {
+                    disabled: function (key, opt) {
                         const sheet = ledgerSpread.getActiveSheet();
                         const selection = sheet.getSelections();
-                        const row = selection[0].row;
-                        const select = ledgerTree.nodes[row];
-                        return select;
+                        const sel = selection ? selection[0] : sheet.getSelections()[0];
+                        const row = sel ? sel.row : -1;
+                        const tree = sheet.zh_tree;
+                        if (!tree) return true;
+                        const first = sheet.zh_tree.nodes[row];
+                        let last = first, sameParent = true;
+                        if (sel.rowCount > 1) {
+                            for (let r = 1; r < sel.rowCount; r++) {
+                                const rNode = tree.nodes[sel.row + r];
+                                if (rNode.level > first.level) continue;
+                                if ((rNode.level < first.level) || (rNode.level === first.level && rNode.pid !== first.pid)) {
+                                    sameParent = false;
+                                    break;
+                                }
+                                last = rNode;
+                            }
+                        }
+                        const valid = !sheet.zh_setting.readOnly;
+                        return !(valid && first && sameParent && first.level > 1 && !first.node_type);
                     }
                 },
                 'copyBlock': {
@@ -1171,7 +1211,7 @@ $(document).ready(function() {
                 if (!dealBills) {
                     dealBills = new DealBills('#deal-bills-spread', {
                         cols: [
-                            {title: '清单编号', field: 'b_code', hAlign: 0, width: 120, formatter: '@', readOnly: true},
+                            {title: '清单编号', field: 'code', hAlign: 0, width: 120, formatter: '@', readOnly: true},
                             {title: '名称', field: 'name', hAlign: 0, width: 230, formatter: '@', readOnly: true},
                             {title: '单位', field: 'unit', hAlign: 1, width: 50, formatter: '@', readOnly: true},
                             {title: '单价', field: 'unit_price', hAlign: 2, width: 50, readOnly: true},
@@ -1339,7 +1379,6 @@ $(document).ready(function() {
                     formData.append('file', file.files[0]);
                     postDataWithFile(self.url+'/upload-excel', formData, function (data) {
                         self.data = data;
-                        //self.calculateData();
                         SpreadJsObj.loadSheetData(self.spread.getActiveSheet(), 'data', data);
                         $('#upload-deal').modal('hide');
                     }, function () {
@@ -1644,23 +1683,6 @@ $(document).ready(function() {
             });
         }
     });
-    // $('#addAuditor').click(() => {
-    //     const data = {
-    //         auditorId: $('#addAuditor').attr('auditorId'),
-    //     };
-    //     postData('/tender/' + getTenderId() + '/ledger/audit/add', data, (data) => {
-    //         const html = [];
-    //         html.push('<li class="list-group-item" auditorId="'+ data.audit_id +'"><a href="javascript: void(0)" class="text-danger pull-right">移除</a>');
-    //         html.push('<span>');
-    //         html.push(data.audit_order + ' ');
-    //         html.push(data.name + ' ');
-    //         html.push('</span>');
-    //         html.push('<small class="text-muted">');
-    //         html.push(data.role);
-    //         html.push('</small></li>');
-    //         $('#auditors').append(html.join(''));
-    //     });
-    // });
     $('body').on('click', '#auditors li>a', function () {
         const li = $(this).parent();
         const data = {

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

@@ -156,6 +156,7 @@ $(document).ready(() => {
                         {title: '单位', field: 'unit', width: 50, formatter: '@', readOnly: true},
                         {title: '单价', field: 'unit_price', width: 50, readOnly: true},
                         {title: '数量', field: 'quantity', width: 50, readOnly: true},
+                        {title: '金額', field: 'total_price', width: 50, readOnly: true},
                     ],
                     emptyRows: 0,
                     headRows: 1,

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

@@ -97,7 +97,7 @@ $(document).ready(function() {
                 dataTye: 'json',
                 success: function(response) {
                     if (response.err === 0) {
-                        window.location.href = response.data.url;
+                        window.location.href = response.url;
                     } else {
                         toast(response.msg, 'error');
                     }

+ 10 - 4
app/public/js/stage.js

@@ -24,16 +24,15 @@ function customColDisplay () {
         { title: '本期完成计量', fields: ['gather_qty', 'gather_tp'], visible: true },
         { title: '截止本期计量合同', fields: ['end_contract_qty', 'end_contract_tp'], visible: true },
         { title: '截止本期数量变更', fields: ['end_qc_qty', 'end_qc_tp', 'end_qc_bgl'], visible: true },
-        { title: '截止本期完成计量', fields: ['end_gather_qty', 'end_gather_tp'], visible: true },
+        { title: '截止本期完成计量', fields: ['end_gather_qty', 'end_gather_tp', 'end_gather_percent'], visible: true },
         { title: '本期批注', fields: ['postil'], visible: true },
         { title: '图册号', fields: ['drawing_code'], visible: true },
-        { title: '累计完成率(%)', fields: ['percent'], visible: true },
         { title: '备注', fields: ['memo'], visible: true },
     ];
     if (checkTzMeasureType()) {
         defaultSetting.splice(0, 1);
     }
-    const settingStr = Cookies.get('stage-col-visible-1.0.1-' + tender.id);
+    const settingStr = Cookies.get('stage-col-visible-1.0.2-' + tender.id);
     return settingStr ? JSON.parse(settingStr) : defaultSetting;
 }
 
@@ -89,6 +88,9 @@ function initTreeColSettingEvents(setting) {
 function needCheckDetail() {
     stage.check_detail = true;
     $('#check_point').show();
+    $('#sub-sp-btn').attr('data-target', '#sub-sp3');
+    $('#sp-done-btn').attr('data-target', '#sub-sp3');
+    $('#sp-list2-btn').attr('data-target', '#sub-sp3');
 }
 
 // 生成所有附件列表
@@ -169,6 +171,8 @@ $(document).ready(() => {
         node.end_contract_tp = ZhCalc.add(node.pre_contract_tp, node.contract_tp);
         node.end_qc_tp = ZhCalc.add(node.pre_qc_tp, node.qc_tp);
         node.end_gather_tp = ZhCalc.add(node.pre_gather_tp, node.gather_tp);
+        node.end_final_tp = ZhCalc.add(node.end_qc_tp, node.total_price);
+        node.end_gather_percent = ZhCalc.mul(ZhCalc.div(node.end_gather_tp, node.end_final_tp), 100, 2);
         node.final_dgn_price = ZhCalc.round(ZhCalc.div(node.end_gather_tp, ZhCalc.add(node.deal_dgn_qty1, node.c_dgn_qty1)), tenderInfo.decimal.up);
     };
     const stageTree = createNewPathTree('stage', stageTreeSetting);
@@ -183,6 +187,8 @@ $(document).ready(() => {
         pos.end_contract_qty = ZhCalc.add(pos.pre_contract_qty, pos.contract_qty);
         pos.end_qc_qty = ZhCalc.add(pos.pre_qc_qty, pos.qc_qty);
         pos.end_gather_qty = ZhCalc.add(pos.pre_gather_qty, pos.gather_qty);
+        pos.sum = ZhCalc.add(pos.end_qc_qty, pos.quantity);
+        pos.end_gather_percent = ZhCalc.mul(ZhCalc.div(pos.end_gather_qty, pos.sum), 100, 2);
     };
     const stagePos = new StagePosData(stagePosSetting);
 
@@ -1400,7 +1406,7 @@ $(document).ready(() => {
                         }
                         if (checkEmpty) {
                             if (sd.quantity) {
-                                if (!sd.end_gather_qty || ZhCalc.sub(ZhCalc(sd.quantity, ad.end_qc_qty), sd.end_gather_qty) > 0) match = true;
+                                if (!sd.end_gather_qty || ZhCalc.sub(ZhCalc.add(sd.quantity, sd.end_qc_qty), sd.end_gather_qty) > 0) match = true;
                             }
                         }
                         if (keyword && keyword !== '' && sd.name && sd.name.indexOf(keyword) === -1) match = false;

+ 2 - 3
app/public/js/stage_change.js

@@ -34,10 +34,9 @@ class ChangeAnalysis {
         change.filterBills = false;
         change.attachments = change.detail.attachments;
         change.bills = change.detail.bills;
-        //change.bills = change.detail.addUsedBills;
         for (const b of change.bills) {
             const aub = change.detail.addUsedBills.find(function (x) {
-                return x.id = b.id;
+                return x.id === b.id;
             });
             if (aub) {
                 b.used_qty = aub.used_qty;
@@ -194,7 +193,7 @@ $(document).ready(() => {
         filterUsedBills: function (isFilter) {
             const bills = SpreadJsObj.getSortData(billsSpread.getActiveSheet());
             for (const b of bills) {
-                b.visible = !isFilter ||(b.cur_qty && !checkZero(b.cur_qty));
+                b.visible = !isFilter ||(!checkZero(b.cur_qty));
             }
             SpreadJsObj.refreshTreeRowVisible(billsSpread.getActiveSheet());
         }

+ 7 - 1
app/public/js/stage_detail.js

@@ -13,10 +13,16 @@ function needCheckDetail(check = true) {
         stage.check_detail = true;
         $('#check_point').show();
         $('#check-detail').show();
+        $('#sub-sp-btn').attr('data-target', '#sub-sp3');
+        $('#sp-done-btn').attr('data-target', '#sub-sp3');
+        $('#sp-list2-btn').attr('data-target', '#sub-sp3');
     } else {
         stage.check_detail = false;
         $('#check_point').hide();
         $('#check-detail').hide();
+        $('#sub-sp-btn').attr('data-target', '#sub-sp');
+        $('#sp-done-btn').attr('data-target', '#sp-done');
+        $('#sp-list2-btn').attr('data-target', '#sp-list2');
     }
 }
 
@@ -763,5 +769,5 @@ $(document).ready(() => {
             needCheckDetail(false);
             $('#done').modal('hide');
         })
-    })
+    });
 });

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

@@ -53,8 +53,8 @@ $(document).ready(function () {
         }
     });
     // 解析清单汇总数据
-    gclGatherModel.loadLedgerData(ledger, curLedgerData, []);
-    gclGatherModel.loadPosData(pos, curPosData);
+    gclGatherModel.loadLedgerData(ledger, curLedgerData, preLedgerData);
+    gclGatherModel.loadPosData(pos, curPosData, prePosData);
     gclGatherModel.loadDealBillsData(dealBills);
     const gclGatherData = gclGatherModel.gatherGclData();
     // 获取项目节数据

+ 3 - 2
app/public/js/stage_im.js

@@ -166,7 +166,8 @@ const stageIm = (function () {
             return im.lid === d.lid &&
                 (!im.code || im.code === d.code) &&
                 (!im.name || im.name === d.name) &&
-                (!im.unit || im.unit === d.unit);
+                (!im.unit || im.unit === d.unit) &&
+                checkZero(ZhCalc.sub(im.unit_price, d.unit_price));
         });
         if (cd) {
             _.assignInWith(im, cd, function (oV, sV, key) {
@@ -256,7 +257,7 @@ const stageIm = (function () {
             if (!p.b_code || p.b_code === '') { continue }
             if (!p.gather_qty || p.gather_qty === 0 ) { continue; }
             let im = nodeImData.find(function (d) {
-                return d.code === p.b_code && p.name === d.name && p.unit === d.unit && checkZero(p.unit_price - d.unit_price);
+                return d.code === p.b_code && p.name === d.name && p.unit === d.unit && checkZero(ZhCalc.sub(p.unit_price, d.unit_price));
             });
             if (!im) {
                 const peg = getPegNode(node);

+ 3 - 2
app/public/js/stage_pay.js

@@ -133,7 +133,7 @@ $(document).ready(() => {
                 return data.ptype !== 1;
             },
             isOld: function (data) {
-                if (data.csorder === 0) {
+                if (data.csorder === 0 && payCol.readOnly.isYB(data)) {
                     return stage.order > 1 || stage.times > 1 || stage.curOrder > 0;
                 } else {
                     return stage.order > data.csorder || stage.times > data.cstimes || stage.curOrder > data.csaorder;
@@ -208,7 +208,8 @@ $(document).ready(() => {
             const sheet = paySpread.getActiveSheet();
             const select = SpreadJsObj.getSelectObject(sheet);
             setObjEnable($('#add'), !readOnly);
-            setObjEnable($('#del'), !readOnly && select);
+            setObjEnable($('#del'), !readOnly && select && (!payCol.readOnly.isOld(select) ||
+                (!payCol.readOnly.isStarted(select) && payCol.readOnly.isYB(select))));
             setObjEnable($('#up-move'), !readOnly && select && select.ptype === 1 && dealPay.indexOf(select) > 3);
             setObjEnable($('#down-move'), !readOnly && select && select.ptype === 1 && dealPay.indexOf(select) < dealPay.length - 1);
         },

+ 32 - 14
app/public/js/tender_list.js

@@ -215,8 +215,20 @@ function initTenderTree () {
         }
         return tenderCategory;
     }
+    function calculateTender(tender) {
+        if (tender.lastStage) {
+            tender.gather_tp = ZhCalc.add(tender.lastStage.contract_tp, tender.lastStage.qc_tp);
+            tender.end_contract_tp = ZhCalc.add(tender.lastStage.pre_contract_tp, tender.lastStage.contract_tp);
+            tender.end_qc_tp = ZhCalc.add(tender.lastStage.pre_qc_tp, tender.lastStage.qc_tp);
+            tender.end_gather_tp = ZhCalc.add(tender.end_contract_tp, tender.end_qc_tp);
+            tender.pre_gather_tp = ZhCalc.add(tender.lastStage.pre_contract_tp, tender.lastStage.pre_qc_tp);
+            tender.yf_tp = ZhCalc.add(tender.lastStage.yf_tp);
+            tender.end_yf_tp = ZhCalc.add(tender.lastStage.pre_yf_tp, tender.yf_tp);
+        }
+    }
     tenderTree.splice(0, tenderTree.length);
     for (const t of tenders) {
+        calculateTender(t);
         t.valid = true;
         if (t.category && levelCategory.length > 0) {
             const parent = loadTenderCategory(t);
@@ -263,32 +275,37 @@ function recursiveGetTenderNodeHtml (node, arr) {
     html.push(node.lastStage ? auditConst.stage.statusString[node.lastStage.status] : auditConst.ledger.statusString[node.ledger_status]);
     html.push('</td>');
     // 0号台账合同
-    html.push('<td>');
-    //html.push(node[c.field] ? node[c.field] : '');
+    html.push('<td class="text-right">');
+    html.push(node.total_price);
+    console.log(node);
     html.push('</td>');
     // 本期完成
-    html.push('<td>');
-    //html.push(node[c.field] ? node[c.field] : '');
+    html.push('<td class="text-right">');
+    html.push(node.gather_tp);
     html.push('</td>');
     // 截止本期合同
-    html.push('<td>');
-    //html.push(node[c.field] ? node[c.field] : '');
+    html.push('<td class="text-right">');
+    html.push(node.end_contract_tp);
     html.push('</td>');
     // 截止本期变更
-    html.push('<td>');
-    //html.push(node[c.field] ? node[c.field] : '');
+    html.push('<td class="text-right">');
+    html.push(node.end_qc_tp);
     html.push('</td>');
     // 截止本期完成
-    html.push('<td>');
-    //html.push(node[c.field] ? node[c.field] : '');
+    html.push('<td class="text-right">');
+    html.push(node.end_gather_tp);
     html.push('</td>');
     // 截止上期完成
-    html.push('<td>');
-    //html.push(node[c.field] ? node[c.field] : '');
+    html.push('<td class="text-right">');
+    html.push(node.pre_gather_tp);
     html.push('</td>');
     // 本期应付
-    html.push('<td>');
-    //html.push(node[c.field] ? node[c.field] : '');
+    html.push('<td class="text-right">');
+    html.push(node.yf_tp);
+    html.push('</td>');
+    // 截止本期应付
+    html.push('<td class="text-right">');
+    html.push(node.end_yf_tp);
     html.push('</td>');
     html.push('</tr>');
     if (node.children) {
@@ -315,6 +332,7 @@ function getTenderTreeHtml () {
         html.push('<th>', '截止本期完成', '</th>');
         html.push('<th>', '截止上期完成', '</th>');
         html.push('<th>', '本期应付', '</th>');
+        html.push('<th>', '截止本期应付', '</th>');
         html.push('</tr>', '</thead>');
         for (const t of tenderTree) {
             html.push(recursiveGetTenderNodeHtml(t, tenderTree));

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

@@ -259,7 +259,7 @@ function recursiveGetTenderNodeHtml (node, arr) {
     html.push('<td tid="' + node.id + '">');
     if (!node.cid) {
         html.push('<a href="#javascript: void(0)" name="edit" class="btn btn-outline-primary btn-sm">编辑</a>');
-        if (node.lastStage === null) {
+        if (node.lastStage === null || node.lastStage === undefined) {
             html.push('<a href="javascript: void(0)" name="del" class="btn btn-outline-danger btn-sm ml-1">删除</a>');
         } else {
             html.push('<button class="btn btn-outline-secondary btn-sm ml-1" data-toggle="tooltip" data-placement="top" title="请先删除所有期">删除</button>');

+ 36 - 8
app/public/js/tender_list_progress.js

@@ -215,8 +215,19 @@ function initTenderTree () {
         }
         return tenderCategory;
     }
+    function calculateTender(tender) {
+        if (tender.lastStage) {
+            tender.end_qc_tp = ZhCalc.add(tender.lastStage.pre_qc_tp, tender.lastStage.qc_tp);
+            tender.pre_gather_tp = ZhCalc.add(tender.lastStage.pre_contract_tp, tender.lastStage.pre_qc_tp);
+            tender.gather_tp = ZhCalc.add(tender.lastStage.contract_tp, tender.lastStage.qc_tp);
+            tender.sum_tp = ZhCalc.add(tender.total_price, tender.end_qc_tp);
+        } else {
+            tender.sum_tp = tender.total_price;
+        }
+    }
     tenderTree.splice(0, tenderTree.length);
     for (const t of tenders) {
+        calculateTender(t);
         t.valid = true;
         if (t.category && levelCategory.length > 0) {
             const parent = loadTenderCategory(t);
@@ -231,6 +242,22 @@ function initTenderTree () {
         }
     }
 }
+function getProgressHtml(total, pre, cur) {
+    if (total !== 0) {
+        let preP = ZhCalc.mul(ZhCalc.div(pre, total, 2), 100, 0);
+        let curP = ZhCalc.mul(ZhCalc.div(cur, total, 2), 100, 0);
+        let other = Math.max(ZhCalc.div(ZhCalc.div(total, pre), cur), 0);
+        let otherP = Math.max(100 - preP - curP, 0);
+        const html = '<div class="progress">' +
+            '<div class="progress-bar bg-success" style="width: ' + preP + '%;" data-placement="bottom" data-toggle="tooltip" data-original-title="截止上期完成:¥' + pre + '">' + preP + '%</div>' +
+            '<div class="progress-bar bg-info" style="width: ' + curP + '%;" data-placement="bottom" data-toggle="tooltip" data-original-title="本期完成:¥' + cur + '">' + curP + '%</div>' +
+            '<div class="progress-bar bg-gray" style="width: ' + otherP + '%;" data-placement="bottom" data-toggle="tooltip" data-original-title="未完成:¥' + other + '">' + otherP + '%</div>' +
+            '</div>';
+        return html;
+    } else {
+        return '';
+    }
+}
 function recursiveGetTenderNodeHtml (node, arr) {
     const html = [];
     html.push('<tr>');
@@ -252,17 +279,18 @@ function recursiveGetTenderNodeHtml (node, arr) {
         html.push(node.lastStage ? '第' + node.lastStage.order + '期' : '台账');
     }
     html.push('</td>');
-    // 完成期数
-    // html.push('<td>');
-    // html.push(node.completeStage ? '第' + node.completeStage.order + '期' : '');
-    // html.push('</td>');
     // 累计合同计量
     html.push('<td>');
-    //html.push(node[c.field] ? node[c.field] : '');
+    const sum = node.lastStage ? ZhCalc.add(node.total_price, node.lastStage.end_qc_tp) : node.total_price;
+    html.push(node.sum_tp ? node.sum_tp : '');
     html.push('</td>');
     // 截止本期累计完成/本期完成/未完成
     html.push('<td>');
-    //html.push(node[c.field] ? node[c.field] : '');
+    if (node.lastStage) {
+        html.push(getProgressHtml(node.sum_tp, node.pre_gather_tp, node.gather_tp));
+    } else {
+        html.push('');
+    }
     html.push('</td>');
     html.push('</tr>');
     if (node.children) {
@@ -279,8 +307,8 @@ function getTenderTreeHtml () {
         html.push('<table class="table table-hover table-bordered">');
         html.push('<thead>', '<tr>');
         html.push('<th>', '名称', '</th>');
-        html.push('<th>', '计量期数', '</th>');
-        html.push('<th>', '累计合同计量', '</th>');
+        html.push('<th width="120">', '计量期数', '</th>');
+        html.push('<th>', '总价 <i class="fa fa-question-circle text-primary"  data-placement="bottom" data-toggle="tooltip" data-original-title="0号台账+截止本期数量变更"></i>', '</th>');
         html.push('<th>', '截止本期累计完成/本期完成/未完成', '</th>');
         html.push('</tr>', '</thead>');
         for (const t of tenderTree) {

+ 5 - 1
app/service/ledger_audit.js

@@ -180,11 +180,15 @@ module.exports = app => {
             if (!audit) {
                 throw '审核人信息错误';
             }
+            const sum = await this.ctx.service.ledger.addUp({tender_id: tenderId, is_leaf: true});
 
             const transaction = await this.db.beginTransaction();
             try {
                 await transaction.update(this.tableName, {id: audit.id, status: auditConst.status.checking, begin_time: new Date()});
-                await transaction.update(this.ctx.service.tender.tableName, {id: tenderId, ledger_status: auditConst.status.checking});
+                await transaction.update(this.ctx.service.tender.tableName, {
+                    id: tenderId, ledger_status: auditConst.status.checking,
+                    total_price: sum.total_price, deal_tp: sum.deal_tp,
+                });
 
                 // 添加短信通知-需要审批提醒功能
                 const smsUser = await this.ctx.service.projectAccount.getDataById(audit.audit_id);

+ 1 - 1
app/service/pos.js

@@ -38,7 +38,7 @@ module.exports = app => {
 
         async getPosDataByIds(ids) {
             if (ids instanceof Array && ids.length > 0) {
-                const sql = 'SELECT id, tid, lid, name, quantity, drawing_code, sgfh_qty, sjcl_qty, qtcl_qty' +
+                const sql = 'SELECT id, tid, lid, name, quantity, drawing_code, sgfh_qty, sjcl_qty, qtcl_qty, add_stage, add_times, add_user' +
                     '  FROM ' + this.tableName +
                     '  WHERE id in (' + this.ctx.helper.getInArrStrSqlFilter(ids) + ')';
                 return await this.db.query(sql, []);

+ 4 - 0
app/service/revise_audit.js

@@ -284,6 +284,10 @@ module.exports = app => {
                         await transaction.update(this.ctx.service.ledgerRevise.tableName, {id: revise.id, status: checkType, end_time: time});
                         // 拷贝修订数据至台账
                         await this._replaceLedgerByRevise(transaction, revise);
+                        const sum = await this.ctx.service.reviseBills.addUp({tender_id: revise.tid, is_leaf: true});
+                        await transaction.update(this.ctx.service.tender.tableName, {
+                            id: revise.tid, total_price: sum.total_price, deal_tp: sum.deal_tp
+                        });
 
                         // 添加短信通知-审批通过提醒功能
                         const smsUser = await this.ctx.service.projectAccount.getDataById(revise.uid);

+ 22 - 4
app/service/stage.js

@@ -94,6 +94,22 @@ module.exports = app => {
             return await this.db.query(sql, sqlParam);
         }
 
+        async checkStageGatherData(stage) {
+            // 最新一期计量(未审批完成),当前操作人的期详细数据,应实时计算
+            if (stage.status !== auditConst.status.checked) {
+                const curAuditor = await this.ctx.service.stageAudit.getCurAuditor(stage.id, stage.times);
+                const isActive = curAuditor ? curAuditor.id === this.ctx.session.sessionUser.accountId : stage.user_id === this.ctx.session.sessionUser.accountId;
+                stage.curTimes = stage.status === auditConst.status.checkNo ? stage.times - 1 : stage.times;
+                stage.curOrder = curAuditor ? curAuditor.order : 0;
+                if (isActive) {
+                    const tpData = await this.ctx.service.stageBills.getSumTotalPrice(stage);
+                    stage.contract_tp = tpData.contract_tp;
+                    stage.qc_tp = tpData.qc_tp;
+                    stage.yf_tp = await this.ctx.service.stagePay.getYfTotalPrice(stage);
+                }
+            }
+        }
+
         /**
          * 获取标段下的全部计量期,按倒序
          * @param tenderId
@@ -126,6 +142,7 @@ module.exports = app => {
                     const tpData = await this.ctx.service.stageBills.getSumTotalPrice(stage);
                     stage.contract_tp = tpData.contract_tp;
                     stage.qc_tp = tpData.qc_tp;
+                    stage.yf_tp = await this.ctx.service.stagePay.getYfTotalPrice(stage);
                     stage.tp = this.ctx.helper.add(stage.contract_tp, stage.qc_tp);
                     stage.end_tp = this.ctx.helper.add(stage.pre_tp, stage.tp);
                 }
@@ -169,6 +186,7 @@ module.exports = app => {
                 newStage.im_gather_node = preStage.im_gather_node;
                 newStage.pre_contract_tp = this.ctx.helper.add(preStage.pre_contract_tp, preStage.contract_tp);
                 newStage.pre_qc_tp = this.ctx.helper.add(preStage.pre_qc_tp, preStage.qc_tp);
+                newStage.pre_yf_tp = this.ctx.helper.add(preStage.pre_yf_tp, preStage.yf_tp);
             }
             const transaction = await this.db.beginTransaction();
             try {
@@ -239,9 +257,9 @@ module.exports = app => {
          * 获取 当期的 计算基数
          * @returns {Promise<any>}
          */
-        async getStagePayCalcBase() {
+        async getStagePayCalcBase(stage, tenderInfo) {
             const calcBase = JSON.parse(JSON.stringify(payConst.calcBase));
-            const param = this.ctx.tender.info.deal_param;
+            const param = tenderInfo.deal_param;
             for (const cb of calcBase) {
                 switch (cb.code) {
                     case 'htj':
@@ -260,11 +278,11 @@ module.exports = app => {
                         cb.value = param.materialAdvance;
                         break;
                     case 'bqwc':
-                        const sum = await this.ctx.service.stageBills.getSumTotalPrice(this.ctx.stage);
+                        const sum = await this.ctx.service.stageBills.getSumTotalPrice(stage);
                         cb.value = this.ctx.helper.add(sum.contract_tp, sum.qc_tp);
                         break;
                     case 'ybbqwc':
-                        const sumGcl = await this.ctx.service.stageBills.getSumTotalPriceGcl(this.ctx.stage, '^1[0-9]{2}-');
+                        const sumGcl = await this.ctx.service.stageBills.getSumTotalPriceGcl(stage, '^1[0-9]{2}-');
                         cb.value = this.ctx.helper.add(sumGcl.contract_tp, sumGcl.qc_tp);
                         break;
                     default:

+ 3 - 1
app/service/stage_audit.js

@@ -233,7 +233,7 @@ module.exports = app => {
             try {
                 await transaction.update(this.tableName, {id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time});
                 // 计算并合同支付最终数据
-                await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
+                const yfPay = await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
                 // 无下一审核人表示,审核结束
                 if (nextAudit) {
                     // 复制一份下一审核人数据
@@ -245,6 +245,7 @@ module.exports = app => {
                         id: stageId, status: auditConst.status.checking,
                         contract_tp: tpData.contract_tp,
                         qc_tp: tpData.qc_tp,
+                        yf_tp: yfPay.tp,
                     });
 
                     // 添加短信通知-需要审批提醒功能
@@ -272,6 +273,7 @@ module.exports = app => {
                         id: stageId, status: checkData.checkType,
                         contract_tp: tpData.contract_tp,
                         qc_tp: tpData.qc_tp,
+                        yf_tp: yfPay.tp,
                     });
 
                     // 添加短信通知-审批通过提醒功能

+ 17 - 2
app/service/stage_pay.js

@@ -9,6 +9,7 @@
  */
 
 const timesLen = require('../const/audit').stage.timesLen;
+const payConst = require('../const/deal_pay');
 
 module.exports = app => {
     class StagePay extends app.BaseService {
@@ -102,9 +103,10 @@ module.exports = app => {
                     const sp = this._.find(stagePays, {pid: pp.pid});
                     sp.name = pp.name;
                     sp.expr = pp.expr;
-                    sp.pre_tp= pp.end_tp;
+                    sp.pre_tp = pp.end_tp;
                     sp.pause = pp.pause;
                     sp.pre_used = pp.pre_used || !this.ctx.helper.checkZero(pp.tp);
+                    sp.pre_finish = pp.rprice ? pp.end_tp === pp.rprice : false;
                 }
             }
             let result;
@@ -210,7 +212,7 @@ module.exports = app => {
             }
             const stagePays = await this.getStagePays(stage);
             const PayCalculator = require('../lib/pay_calc');
-            const payCalculator = new PayCalculator(this.ctx, this.ctx.tender.info.decimal);
+            const payCalculator = new PayCalculator(this.ctx, stage, this.ctx.tender.info);
             await payCalculator.calculateAll(stagePays);
             const srUpdate = [], update = [];
             for (const sp of stagePays) {
@@ -231,6 +233,19 @@ module.exports = app => {
             if (srUpdate.length > 0) {
                 await transaction.updateRows(this.ctx.service.pay.tableName, srUpdate);
             }
+            const yf = this._.find(stagePays, {ptype: payConst.payType.yf});
+            return yf;
+        }
+
+        async getYfTotalPrice(stage) {
+            if (!stage) throw '计算数据错误';
+            const stagePays = await this.getStagePays(stage);
+            const PayCalculator = require('../lib/pay_calc');
+            const tenderInfo = await this.ctx.service.tenderInfo.getTenderInfo(stage.tid);
+            const payCalculator = new PayCalculator(this.ctx, stage, tenderInfo);
+            await payCalculator.calculateAll(stagePays);
+            const yf = this._.find(stagePays, {ptype: payConst.payType.yf});
+            return yf ? yf.tp : 0;
         }
 
         /**

+ 4 - 4
app/service/tender.js

@@ -12,7 +12,7 @@ const tenderConst = require('../const/tender');
 const auditConst = require('../const/audit');
 const fs = require('fs');
 const path = require('path');
-const commonQueryColumns = ['id', 'project_id', 'name', 'status', 'category', 'ledger_times', 'ledger_status', 'measure_type', 'user_id', 'valuation'];
+const commonQueryColumns = ['id', 'project_id', 'name', 'status', 'category', 'ledger_times', 'ledger_status', 'measure_type', 'user_id', 'valuation', 'total_price', 'deal_tp'];
 
 module.exports = app => {
 
@@ -84,7 +84,7 @@ module.exports = app => {
             let sqlParam = [];
             if (listStatus === 'manage') {
                 // 管理页面只取属于自己创建的标段
-                sql = 'SELECT t.`id`, t.`project_id`, t.`name`, t.`status`, t.`category`, t.`ledger_times`, t.`ledger_status`, t.`measure_type`, t.`user_id`, t.`create_time`, ' +
+                sql = 'SELECT t.`id`, t.`project_id`, t.`name`, t.`status`, t.`category`, t.`ledger_times`, t.`ledger_status`, t.`measure_type`, t.`user_id`, t.`create_time`, t.`total_price`, t.`deal_tp`,' +
                     '    pa.`name` As `user_name`, pa.`role` As `user_role`, pa.`company` As `user_company` ' +
                     '  FROM ?? As t ' +
                     '  Left Join ?? As pa ' +
@@ -93,7 +93,7 @@ module.exports = app => {
                 sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, session.sessionProject.id, session.sessionUser.accountId];
             } else if (permission !== null && permission.tender !== undefined && permission.tender.indexOf('2') !== -1) {
                 // 具有查看所有标段权限的用户查阅标段
-                sql = 'SELECT t.`id`, t.`project_id`, t.`name`, t.`status`, t.`category`, t.`ledger_times`, t.`ledger_status`, t.`measure_type`, t.`user_id`, t.`create_time`, ' +
+                sql = 'SELECT t.`id`, t.`project_id`, t.`name`, t.`status`, t.`category`, t.`ledger_times`, t.`ledger_status`, t.`measure_type`, t.`user_id`, t.`create_time`, t.`total_price`, t.`deal_tp`,' +
                     '    pa.`name` As `user_name`, pa.`role` As `user_role`, pa.`company` As `user_company` ' +
                     '  FROM ?? As t ' +
                     '  Left Join ?? As pa ' +
@@ -104,7 +104,7 @@ module.exports = app => {
                 // 根据用户权限查阅标段
                 // tender 163条数据,project_account 68条数据测试
                 // 查询两张表耗时0.003s,查询tender左连接project_account耗时0.002s
-                sql = 'SELECT t.`id`, t.`project_id`, t.`name`, t.`status`, t.`category`, t.`ledger_times`, t.`ledger_status`, t.`measure_type`, t.`user_id`, t.`create_time`, ' +
+                sql = 'SELECT t.`id`, t.`project_id`, t.`name`, t.`status`, t.`category`, t.`ledger_times`, t.`ledger_status`, t.`measure_type`, t.`user_id`, t.`create_time`, t.`total_price`, t.`deal_tp`,' +
                     '    pa.`name` As `user_name`, pa.`role` As `user_role`, pa.`company` As `user_company` ' +
                     // '  FROM ?? As t, ?? As pa ' +
                     // '  WHERE t.`project_id` = ? AND t.`user_id` = pa.`id` AND (' +

+ 11 - 15
app/service/valuation.js

@@ -41,24 +41,20 @@ module.exports = app => {
             const valuation = await this.getDataById(id);
             const billsId = this._.map(valuation.bill_id.split(','), this._.toInteger);
             const chaptersId = this._.map(valuation.chapter_id.split(','), this._.toInteger);
-            const billsList = await this.db.select('zh_std_gcl_list', {
-                where: {id: billsId},
-                columns: ['id', 'name'],
-            });
-            billsList.sort(function (a, b) {
-                return billsId.indexOf(a.id) - billsList.indexOf(b.id);
-            });
-            const chapterList = await this.db.select('zh_std_xmj_list', {
-                where: {id: chaptersId},
-                columns: ['id', 'name'],
-            });
-            chapterList.sort(function (a, b) {
-                return chaptersId.indexOf(a.id) - chapterList.indexOf(b.id);
-            });
+            const sql = 'SELECT `id`, `name`' +
+                '  From ?? ' +
+                '  WHERE `id` in ( ? ) ORDER BY FIELD(`id`, ?)';
+            const sqlParam = ['zh_std_gcl_list', billsId, billsId];
+            const billsList = await this.db.query(sql, sqlParam);
+            const sql2 = 'SELECT `id`, `name`' +
+                '  From ?? ' +
+                '  WHERE `id` in ( ? ) ORDER BY FIELD(`id`, ?)';
+            const sqlParam2 = ['zh_std_xmj_list', chaptersId, chaptersId];
+            const chapterList = await this.db.query(sql2, sqlParam2);
             return [billsList, chapterList];
         }
 
     }
 
     return Valuation;
-};
+};

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

@@ -24,7 +24,7 @@
                     <div class="media-body">
                         <span class="pull-right text-muted"><%- t.end_time.toLocaleString() %></span>
                         <h5 class="mt-0"><%- ctx.session.sessionUser.name %><small class="ml-3 text-muted"><%- role %></small></h5>
-                        <p><a href="/tender/<%- t.id %>"><%- t.name %></a> 台帐 需要您 <a href="/tender/<%- t.id %>/ledger/explode">重新上报</a>。</p>
+                        <p><a href="/tender/<%- t.id %>"><%- t.name %></a> 台帐 需要您 <a href="/tender/<%- t.id %>/ledger">重新上报</a>。</p>
                     </div>
                 </li>
                 <% } %>

+ 1 - 1
app/view/ledger/explode_modal.ejs

@@ -239,9 +239,9 @@
                 </div>
             </div>
             <form class="modal-footer" action="/tender/<%- tender.id %>/ledger/audit/start" method="post" onsubmit="return checkAuditorFrom()">
-                <button type="submit" class="btn btn-primary">确认上报</button>
                 <input type="hidden" name="_csrf" value="<%= ctx.csrf %>">
                 <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                <button type="submit" class="btn btn-primary">确认上报</button>
             </form>
         </div>
     </div>

+ 5 - 5
app/view/stage/audit_btn.ejs

@@ -1,13 +1,13 @@
 <div class="contarl-box">
     <% if (ctx.stage.status === auditConst.status.uncheck) { %>
         <% if (ctx.session.sessionUser.accountId === ctx.stage.user_id && ctx.stage.check_detail === 0) { %>
-            <a href="javascript: void(0);" data-toggle="modal" data-target="#sub-sp" class="btn btn-primary btn-sm btn-block">上报审批</a>
+            <a id="sub-sp-btn" href="javascript: void(0);" data-toggle="modal" data-target="#sub-sp" class="btn btn-primary btn-sm btn-block">上报审批</a>
         <% } else if (ctx.session.sessionUser.accountId === ctx.stage.user_id && ctx.stage.check_detail === 1) {%>
-            <a href="javascript: void(0);" data-toggle="modal" data-target="#sub-sp3" class="btn btn-primary btn-sm btn-block">上报审批</a>
+            <a id="sub-sp-btn" href="javascript: void(0);" data-toggle="modal" data-target="#sub-sp3" class="btn btn-primary btn-sm btn-block">上报审批</a>
         <% } %>
     <% } else if (ctx.stage.status === auditConst.status.checking) { %>
         <% if (ctx.stage.curAuditor && ctx.stage.curAuditor.aid === ctx.session.sessionUser.accountId) { %>
-            <a href="javascript: void(0);" data-toggle="modal" data-target="#sp-done" class="btn btn-success btn-sm btn-block">审批通过</a>
+            <a id="sp-done-btn" href="javascript: void(0);" data-toggle="modal" data-target="<%- (ctx.stage.check_detail === 0 ? '#sp-done' : '#sub-sp3') %>" class="btn btn-success btn-sm btn-block">审批通过</a>
             <a href="#sp-back" data-toggle="modal" data-target="#sp-back" class="btn btn-warning btn-sm btn-block">审批退回</a>
         <% } else { %>
             <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm btn-block">审批中</a>
@@ -17,12 +17,12 @@
     <% } else if (ctx.stage.status === auditConst.status.checkNo) { %>
         <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm btn-block text-muted">审批退回</a>
         <% if (ctx.session.sessionUser.accountId === ctx.stage.user_id) { %>
-            <a href="javascript: void(0);" data-toggle="modal" data-target="#sp-list2" class="btn btn-primary btn-sm btn-block">重新上报</a>
+            <a id="sp-list2-btn" href="javascript: void(0);" data-toggle="modal" data-target="<%- (ctx.stage.check_detail === 0 ? '#sp-list2' : '#sub-sp3') %>" class="btn btn-primary btn-sm btn-block">重新上报</a>
         <% } %>
     <% } else if (ctx.stage.status === auditConst.status.checkNoPre) { %>
         <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm btn-block text-muted">审批退回</a>
         <% if (ctx.session.sessionUser.accountId === ctx.stage.curAuditor.aid) { %>
-            <a href="javascript: void(0);" data-toggle="modal" data-target="#sp-done" class="btn btn-success btn-sm btn-block">审批通过</a>
+            <a id="sp-done-btn" href="javascript: void(0);" data-toggle="modal" data-target="<%- (ctx.stage.check_detail === 0 ? '#sp-done' : '#sub-sp3') %>" class="btn btn-success btn-sm btn-block">审批通过</a>
             <a href="#sp-back" data-toggle="modal" data-target="#sp-back" class="btn btn-warning btn-sm btn-block">审批退回</a>
         <% } %>
     <% } %>

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

@@ -757,8 +757,8 @@
                 </div>
                 <form class="modal-footer" method="post" action="<%- preUrl %>/audit/start" onsubmit="return checkAuditorFrom()">
                     <input type="hidden" name="_csrf" value="<%= ctx.csrf %>">
-                    <button class="btn btn-primary" type="submit">确认上报</button>
                     <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                    <button class="btn btn-primary" type="submit">确认上报</button>
                 </form>
             </div>
         </div>

+ 2 - 0
app/view/stage/gather.ejs

@@ -85,7 +85,9 @@
     const leafXmjSpreadSetting = JSON.parse('<%- JSON.stringify(leafXmjSpread) %>');
     const ledger = JSON.parse('<%- JSON.stringify(ledger) %>');
     const curLedgerData = JSON.parse('<%- JSON.stringify(curLedgerData) %>');
+    const preLedgerData = JSON.parse('<%- JSON.stringify(preLedgerData) %>');
     const pos = JSON.parse('<%- JSON.stringify(pos) %>');
     const curPosData = JSON.parse('<%- JSON.stringify(curPosData) %>');
+    const prePosData = JSON.parse('<%- JSON.stringify(prePosData) %>');
     const dealBills = JSON.parse('<%- JSON.stringify(dealBills) %>');
 </script>

+ 54 - 20
app/view/tender/detail.ejs

@@ -6,7 +6,7 @@
             <% if (tender.ledger_status !== audit.ledger.status.uncheck) { %>
             <h2>进行至
                 <% if (lastStage) { %>
-                第<%- lastStage.order %>期<small class="<%- audit.stage.auditStringClass[lastStage.status] %>">(<%- audit.stage.auditString[lastStage.status] %>)</small>
+                第<%- lastStage.order %>期<small class="<%- audit.stage.statusClass[lastStage.status] %>">(<%- audit.stage.statusString[lastStage.status] %>)</small>
                 <% } else { %>
                 台账<small class="<%- audit.ledger.auditStringClass[tender.ledger_status] %>">(<%- audit.ledger.auditString[tender.ledger_status] %>)</small>
                 <% } %>
@@ -26,7 +26,7 @@
                 <div class="col-auto">
                     <div class="card text-center">
                         <div class="card-body">
-                            <h5 class="card-title">163,000.00</h5>
+                            <h5 class="card-title"><%- ctx.helper.formatMoney(tender.total_price) %></h5>
                             <p class="card-text text-muted">0号台帐合同</p>
                         </div>
                     </div>
@@ -34,7 +34,7 @@
                 <div class="col-auto">
                     <div class="card text-center">
                         <div class="card-body">
-                            <h5 class="card-title">30,000.00</h5>
+                            <h5 class="card-title"><%- ctx.helper.formatMoney(tender.gather_tp) %></h5>
                             <p class="card-text text-muted">本期完成</p>
                         </div>
                     </div>
@@ -42,7 +42,7 @@
                 <div class="col-auto">
                     <div class="card text-center">
                         <div class="card-body">
-                            <h5 class="card-title">50,000.00 <small class="text-danger"  data-toggle="tooltip" data-placement="bottom" title="" data-original-title="占合同比例">1%</small></h5>
+                            <h5 class="card-title"><%- ctx.helper.formatMoney(tender.end_qc_tp) %><small class="text-danger"  data-toggle="tooltip" data-placement="bottom" title="" data-original-title="占合同比例"><%- tender.qc_ratio %>%</small></h5>
                             <p class="card-text text-muted">截止本期变更</p>
                         </div>
                     </div>
@@ -50,7 +50,7 @@
                 <div class="col-auto">
                     <div class="card text-center">
                         <div class="card-body">
-                            <h5 class="card-title">70,000.00</h5>
+                            <h5 class="card-title"><%- ctx.helper.formatMoney(tender.end_gather_tp) %></h5>
                             <p class="card-text text-muted">截止本期完成</p>
                         </div>
                     </div>
@@ -58,7 +58,7 @@
                 <div class="col-auto">
                     <div class="card text-center">
                         <div class="card-body">
-                            <h5 class="card-title">40,000.00</h5>
+                            <h5 class="card-title"><%- ctx.helper.formatMoney(tender.pre_gather_tp) %></h5>
                             <p class="card-text text-muted">截止上期完成</p>
                         </div>
                     </div>
@@ -66,7 +66,7 @@
                 <div class="col-auto">
                     <div class="card text-center">
                         <div class="card-body">
-                            <h5 class="card-title">30,000.00</h5>
+                            <h5 class="card-title"><%- ctx.helper.formatMoney(tender.yf_tp) %></h5>
                             <p class="card-text text-muted">本期应付</p>
                         </div>
                     </div>
@@ -75,9 +75,9 @@
             <!--进度条-->
             <div class="mb-5">
                 <div class="progress">
-                    <div class="progress-bar bg-success" style="width: 24%;" data-placement="bottom" data-toggle="tooltip" data-original-title="截止上期累计完成:¥40,000.00">24%</div>
-                    <div class="progress-bar bg-info" style="width:18%;" data-placement="bottom" data-toggle="tooltip" data-original-title="本期完成:¥30,000.00">18%</div>
-                    <div class="progress-bar bg-gray" style="width:58%;" data-placement="bottom" data-toggle="tooltip" data-original-title="未完成:¥930,00.00">58%</div>
+                    <div class="progress-bar bg-success" style="width: <%- tender.pre_ratio %>%;" data-placement="bottom" data-toggle="tooltip" data-original-title="截止上期累计完成:¥<%- ctx.helper.formatMoney(tender.end_gather_tp) %>"><%- tender.pre_ratio %>%</div>
+                    <div class="progress-bar bg-info" style="width: <%- tender.cur_ratio %>%;" data-placement="bottom" data-toggle="tooltip" data-original-title="本期完成:¥<%- ctx.helper.formatMoney(tender.gather_tp) %>"><%- tender.cur_ratio %>%</div>
+                    <div class="progress-bar bg-gray" style="width: <%- tender.other_ratio %>%;" data-placement="bottom" data-toggle="tooltip" data-original-title="未完成:¥<%- ctx.helper.formatMoney(tender.other_tp) %>"><%- tender.other_ratio %>%</div>
                 </div>
             </div>
             <ul class="nav nav-tabs">
@@ -574,7 +574,11 @@
             {
                 type : 'category',
                 splitLine : {show : true},
-                data : ['第一期','第二期','第三期','第四期','第五期','第六期','第七期']
+                data : [
+                    <% for (const s of stages) {%>
+                    '第<%- s.order %>期',
+                    <% } %>
+                ]
             }
         ],
         yAxis : [
@@ -603,35 +607,55 @@
                 type:'bar',
                 tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
                 stack: '合同',
-                data:[320, 332, 301, 334, 390, 330, 320]
+                data:[
+                    <% for (const s of stages) {%>
+                    <%- s.contract_tp %>,
+                    <% } %>
+                ]
             },
             {
                 name:'本期数量变更计量',
                 type:'bar',
                 tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
-                stack: '合同',
-                data:[320, -20, 301, 334, 390, 330, 320]
+                stack: '变更',
+                data:[
+                    <% for (const s of stages) {%>
+                    <%- s.qc_tp %>,
+                    <% } %>
+                ]
             },
             {
                 name:'截至上期累计完成',
                 type:'bar',
                 tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
                 stack: '完成',
-                data:[120, 132, 101, 134, 90, 230, 210]
+                data:[
+                    <% for (const s of stages) {%>
+                    <%- ctx.helper.mul(s.pre_contract_tp, s.pre_qc_tp) %>,
+                    <% } %>
+                ]
             },
             {
                 name:'本期完成计量',
                 type:'bar',
                 tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
                 stack: '完成',
-                data:[220, 182, 191, 234, 290, 330, 310]
+                data:[
+                    <% for (const s of stages) {%>
+                    <%- ctx.helper.mul(s.contract_tp, s.qc_tp) %>,
+                    <% } %>
+                ]
             },
             {
                 name:'完成度',
                 type:'line',
                 tooltip : {trigger: 'axis',formatter: "{b}占总标段<br/>{a}:{c} %"},
                 yAxisIndex: 1,
-                data:[10, 15, 20, 13, 11, 9, 5]
+                data:[
+                    <% for (const s of stages) {%>
+                    <%- ctx.helper.mul(ctx.helper.div(ctx.helper.mul(s.contract_tp, s.qc_tp), tender.sum, 2), 100) %>,
+                    <% } %>
+                ]
             },
         ]
     };
@@ -670,7 +694,9 @@
                 type : 'category',
                 boundaryGap : true,
                 data : [
-                    '2月','3月','4月','5月','6月','7月','8月','9月','10月'
+                    <% for (const mp of monthProgress) { %>
+                    '<%- mp.month %>',
+                    <% } %>
                 ]
             }
         ],
@@ -697,7 +723,11 @@
                         }
                     }
                 },
-                data:[10, 10, 30, 40, 50, 60, 80, 85, 100]
+                data:[
+                    <% for (const mp of monthProgress) { %>
+                    <%- mp.end_tp %>,
+                    <% } %>
+                ]
             },
             {
                 name:'本月完成',
@@ -712,7 +742,11 @@
                         }
                     }
                 },
-                data:[10, 0, 20, 10, 10, 10, 10, 5, 15]
+                data:[
+                    <% for (const mp of monthProgress) { %>
+                    <%- mp.tp %>,
+                    <% } %>
+                ]
             }
         ]
     };

+ 0 - 1
app/view/tender/index.ejs

@@ -9,7 +9,6 @@
     const tenders = JSON.parse('<%- JSON.stringify(tenderList) %>');
     const categoryType = JSON.parse('<%- JSON.stringify(settingConst.cType) %>');
     const category = JSON.parse('<%- JSON.stringify(categoryData) %>');
-    const TenderTableCol = JSON.parse('<%- JSON.stringify(tableColSetting) %>');
     const auditConst = JSON.parse('<%- JSON.stringify(auditConst) %>');
     const measureType = JSON.parse('<%- JSON.stringify(measureType) %>');
 </script>

+ 0 - 1
app/view/tender/manage.ejs

@@ -9,6 +9,5 @@
     const tenders = JSON.parse('<%- JSON.stringify(tenderList) %>');
     const categoryType = JSON.parse('<%- JSON.stringify(settingConst.cType) %>');
     const category = JSON.parse('<%- JSON.stringify(categoryData) %>');
-    const TenderTableCol = JSON.parse('<%- JSON.stringify(tableColSetting) %>');
     const auditConst = JSON.parse('<%- JSON.stringify(auditConst) %>');
 </script>

+ 11 - 0
app/view/tender/manage_modal.ejs

@@ -10,6 +10,17 @@
                     <label>标段名称<b class="text-danger">*</b></label>
                     <input class="form-control"  placeholder="输入标段名称" type="text" name="name">
                 </div>
+                <div class="form-group">
+                    <label ><b class="text-danger">*</b>计价规范</label>
+                    <div>
+                        <% for (const v of valuations) { %>
+                            <div class="form-check form-check-inline mt-2">
+                                <input class="form-check-input" name="valuation" type="radio" id="valuation<%- v.id %>" value="<%- v.id %>" checked="">
+                                <label class="form-check-label" for="valuation<%- v.id %>"><%- v.name %></label>
+                            </div>
+                        <% } %>
+                    </div>
+                </div>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>

+ 0 - 1
app/view/tender/progress.ejs

@@ -9,5 +9,4 @@
     const tenders = JSON.parse('<%- JSON.stringify(tenderList) %>');
     const categoryType = JSON.parse('<%- JSON.stringify(settingConst.cType) %>');
     const category = JSON.parse('<%- JSON.stringify(categoryData) %>');
-    const TenderTableCol = JSON.parse('<%- JSON.stringify(tableColSetting) %>');
 </script>

+ 139 - 129
config/web.js

@@ -32,119 +32,129 @@
  * @version
  */
 const JsFiles = {
-    webPath: '/public/js/web/',
+    webPath: "/public/js/web/",
     commonFiles: [
-        '/public/js/jquery/jquery-3.2.1.min.js',
-        '/public/js/jquery/jquery-ui.js',
-        '/public/js/jquery/jquery.validate.js',
-        '/public/js/messages_zh.js',
-        '/public/js/popper/popper.min.js',
-        '/public/js/bootstrap/bootstrap.min.js',
-        '/public/js/vue/vue.js',
-        '/public/js/component/input.js',
-        '/public/js/cookies.js',
-        '/public/js/jquery-contextmenu/jquery.ui.position.min.js',
-        '/public/js/jquery-contextmenu/jquery.contextMenu.min.js',
-        '/public/js/lodash.js',
-        '/public/js/lz-string/lz-string.js',
-        '/public/js/number-precision.js',
-        '/public/js/global.js',
+        "/public/js/jquery/jquery-3.2.1.min.js",
+        "/public/js/jquery/jquery-ui.js",
+        "/public/js/jquery/jquery.validate.js",
+        "/public/js/messages_zh.js",
+        "/public/js/popper/popper.min.js",
+        "/public/js/bootstrap/bootstrap.min.js",
+        "/public/js/vue/vue.js",
+        "/public/js/component/input.js",
+        "/public/js/cookies.js",
+        "/public/js/jquery-contextmenu/jquery.ui.position.min.js",
+        "/public/js/jquery-contextmenu/jquery.contextMenu.min.js",
+        "/public/js/lodash.js",
+        "/public/js/lz-string/lz-string.js",
+        "/public/js/number-precision.js",
+        "/public/js/global.js",
     ],
     controller: {
         tender: {
             list: {
                 files: [
-                    '/public/js/ztree/jquery.ztree.core.js',
-                    '/public/js/ztree/jquery.ztree.exedit.js',
+                    "/public/js/ztree/jquery.ztree.core.js",
+                    "/public/js/ztree/jquery.ztree.exedit.js",
+                    "/public/js/decimal.min.js",
                 ],
                 mergeFiles: [
-                    '/public/js/tender_list.js',
+                    "/public/js/zh_calc.js",
+                    "/public/js/tender_list.js"
                 ],
                 mergeFile: 'tender_list',
             },
             progress: {
                 files: [
-                    '/public/js/ztree/jquery.ztree.core.js',
-                    '/public/js/ztree/jquery.ztree.exedit.js',
+                    "/public/js/ztree/jquery.ztree.core.js",
+                    "/public/js/ztree/jquery.ztree.exedit.js",
+                    "/public/js/decimal.min.js",
+                ],
+                mergeFiles: [
+                    "/public/js/zh_calc.js",
+                    "/public/js/tender_list_progress.js"
                 ],
-                mergeFiles: ['/public/js/tender_list_progress.js'],
                 mergeFile: 'tender_list_progress',
             },
             manage: {
                 files: [
-                    '/public/js/ztree/jquery.ztree.core.js',
-                    '/public/js/ztree/jquery.ztree.exedit.js',
-                    '/public/js/moment/moment.min.js',
+                    "/public/js/ztree/jquery.ztree.core.js",
+                    "/public/js/ztree/jquery.ztree.exedit.js",
+                    "/public/js/moment/moment.min.js",
+                    "/public/js/decimal.min.js",
+                ],
+                mergeFiles: [
+                    "/public/js/zh_calc.js",
+                    "/public/js/tender_list_manage.js",
                 ],
-                mergeFiles: ['/public/js/tender_list_manage.js'],
                 mergeFile: 'tender_list_manage',
             },
             info: {
                 files: [
-                    '/public/js/echarts/echarts.min.js',
-                    '/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js',
+                    "/public/js/echarts/echarts.min.js",
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
                 ],
                 mergeFiles: [
-                    '/public/js/spreadjs_rela/spreadjs_zh.js',
-                    '/public/js/change_calculation.js',
-                    '/public/js/tender.js',
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/change_calculation.js",
+                    "/public/js/tender.js",
                 ],
                 mergeFile: 'tender',
-            },
+            }
         },
         ledger: {
             explode: {
                 files: [
-                    '/public/js/js-xlsx/xlsx.full.min.js',
-                    '/public/js/js-xlsx/xlsx.utils.js',
-                    '/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js',
-                    '/public/js/decimal.min.js',
+                    "/public/js/js-xlsx/xlsx.full.min.js",
+                    "/public/js/js-xlsx/xlsx.utils.js",
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                    "/public/js/decimal.min.js",
                 ],
                 mergeFiles: [
-                    '/public/js/sub_menu.js',
-                    '/public/js/div_resizer.js',
-                    '/public/js/spreadjs_rela/spreadjs_zh.js',
-                    '/public/js/ledger_search.js',
-                    '/public/js/zh_calc.js',
-                    '/public/js/path_tree.js',
-                    '/public/js/ledger_tree_col.js',
-                    '/public/js/ledger.js',
+                    "/public/js/sub_menu.js",
+                    "/public/js/div_resizer.js",
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/ledger_search.js",
+                    "/public/js/zh_calc.js",
+                    "/public/js/path_tree.js",
+                    "/public/js/ledger_tree_col.js",
+                    "/public/js/ledger.js",
                 ],
                 mergeFile: 'explode',
             },
             audit: {
                 files: [
-                    '/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js',
-                    '/public/js/decimal.min.js',
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                    "/public/js/decimal.min.js",
                 ],
                 mergeFiles: [
-                    '/public/js/sub_menu.js',
-                    '/public/js/div_resizer.js',
-                    '/public/js/spreadjs_rela/spreadjs_zh.js',
-                    '/public/js/ledger_search.js',
-                    '/public/js/zh_calc.js',
-                    '/public/js/path_tree.js',
-                    '/public/js/ledger_audit.js',
+                    "/public/js/sub_menu.js",
+                    "/public/js/div_resizer.js",
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/ledger_search.js",
+                    "/public/js/zh_calc.js",
+                    "/public/js/path_tree.js",
+                    "/public/js/ledger_audit.js",
                 ],
                 mergeFile: 'ledger_audit',
             },
             revise: {
                 files: [
-                    '/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js',
-                    '/public/js/decimal.min.js',
-                    '/public/js/toastr.min.js',
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                    "/public/js/decimal.min.js",
+                    "/public/js/toastr.min.js",
                 ],
                 mergeFiles: [
-                    '/public/js/sub_menu.js',
-                    '/public/js/div_resizer.js',
-                    '/public/js/spreadjs_rela/spreadjs_zh.js',
-                    '/public/js/ledger_search.js',
-                    '/public/js/zh_calc.js',
-                    '/public/js/path_tree.js',
-                    '/public/js/revise.js',
+                    "/public/js/sub_menu.js",
+                    "/public/js/div_resizer.js",
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/ledger_search.js",
+                    "/public/js/zh_calc.js",
+                    "/public/js/path_tree.js",
+                    "/public/js/revise.js",
                 ],
                 mergeFile: 'revise',
-            },
+            }
         },
         revise: {
             info: {
@@ -186,119 +196,119 @@ const JsFiles = {
             // 本期计量台账
             index: {
                 files: [
-                    '/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js',
-                    '/public/js/decimal.min.js',
-                    '/public/js/toastr.min.js',
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                    "/public/js/decimal.min.js",
+                    "/public/js/toastr.min.js",
                 ],
                 mergeFiles: [
-                    '/public/js/sub_menu.js',
-                    '/public/js/div_resizer.js',
-                    '/public/js/spreadjs_rela/spreadjs_zh.js',
-                    '/public/js/zh_calc.js',
-                    '/public/js/path_tree.js',
-                    '/public/js/stage.js',
-                    '/public/js/stage_audit.js',
+                    "/public/js/sub_menu.js",
+                    "/public/js/div_resizer.js",
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/zh_calc.js",
+                    "/public/js/path_tree.js",
+                    "/public/js/stage.js",
+                    "/public/js/stage_audit.js",
                 ],
                 mergeFile: 'stage',
             },
             detail: {
                 files: [
-                    '/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js',
-                    '/public/js/decimal.min.js',
-                    '/public/js/html2canvas/html2canvas.min.js',
-                    '/public/js/html2canvas/canvas2image.js',
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                    "/public/js/decimal.min.js",
+                    "/public/js/html2canvas/html2canvas.min.js",
+                    "/public/js/html2canvas/canvas2image.js",
                 ],
                 mergeFiles: [
-                    '/public/js/sub_menu.js',
-                    '/public/js/spreadjs_rela/spreadjs_zh.js',
-                    '/public/js/zh_calc.js',
-                    '/public/js/path_tree.js',
-                    '/public/js/stage_im.js',
-                    '/public/js/stage_detail.js',
-                    '/public/js/stage_audit.js',
+                    "/public/js/sub_menu.js",
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/zh_calc.js",
+                    "/public/js/path_tree.js",
+                    "/public/js/stage_im.js",
+                    "/public/js/stage_detail.js",
+                    "/public/js/stage_audit.js",
                 ],
                 mergeFile: 'stage_detail',
             },
             pay: {
                 files: [
-                    '/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js',
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
                 ],
                 mergeFiles: [
-                    '/public/js/sub_menu.js',
-                    '/public/js/spreadjs_rela/spreadjs_zh.js',
-                    '/public/js/stage_pay.js',
-                    '/public/js/stage_audit.js',
+                    "/public/js/sub_menu.js",
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/stage_pay.js",
+                    "/public/js/stage_audit.js",
                 ],
                 mergeFile: 'stage_pay',
             },
             change: {
                 files: [
-                    '/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js',
-                    '/public/js/decimal.min.js',
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                    "/public/js/decimal.min.js",
                 ],
                 mergeFiles: [
-                    '/public/js/sub_menu.js',
-                    '/public/js/div_resizer.js',
-                    '/public/js/spreadjs_rela/spreadjs_zh.js',
-                    '/public/js/zh_calc.js',
-                    '/public/js/path_tree.js',
-                    '/public/js/stage_change.js',
-                    '/public/js/stage_audit.js',
+                    "/public/js/sub_menu.js",
+                    "/public/js/div_resizer.js",
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/zh_calc.js",
+                    "/public/js/path_tree.js",
+                    "/public/js/stage_change.js",
+                    "/public/js/stage_audit.js",
                 ],
                 mergeFile: 'stage_change',
             },
             gather: {
                 files: [
-                    '/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js',
-                    '/public/js/decimal.min.js',
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                    "/public/js/decimal.min.js",
                 ],
                 mergeFiles: [
-                    '/public/js/sub_menu.js',
-                    '/public/js/div_resizer.js',
-                    '/public/js/spreadjs_rela/spreadjs_zh.js',
-                    '/public/js/zh_calc.js',
-                    '/public/js/path_tree.js',
-                    '/public/js/gcl_gather.js',
-                    '/public/js/stage_gather.js',
-                    '/public/js/stage_audit.js',
+                    "/public/js/sub_menu.js",
+                    "/public/js/div_resizer.js",
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/zh_calc.js",
+                    "/public/js/path_tree.js",
+                    "/public/js/gcl_gather.js",
+                    "/public/js/stage_gather.js",
+                    "/public/js/stage_audit.js",
                 ],
                 mergeFile: 'stage_gather',
             },
             compare: {
                 files: [
-                    '/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js',
-                    '/public/js/decimal.min.js',
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                    "/public/js/decimal.min.js",
                 ],
                 mergeFiles: [
-                    '/public/js/sub_menu.js',
-                    '/public/js/div_resizer.js',
-                    '/public/js/spreadjs_rela/spreadjs_zh.js',
-                    '/public/js/zh_calc.js',
-                    '/public/js/path_tree.js',
-                    '/public/js/stage_compare.js',
-                    '/public/js/stage_audit.js',
+                    "/public/js/sub_menu.js",
+                    "/public/js/div_resizer.js",
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/zh_calc.js",
+                    "/public/js/path_tree.js",
+                    "/public/js/stage_compare.js",
+                    "/public/js/stage_audit.js",
                 ],
                 mergeFile: 'stage_compare',
-            },
+            }
         },
         measure: {
             compare: {
                 files: [
-                    '/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js',
-                    '/public/js/decimal.min.js',
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                    "/public/js/decimal.min.js",
                 ],
                 mergeFiles: [
-                    '/public/js/sub_menu.js',
-                    '/public/js/div_resizer.js',
-                    '/public/js/spreadjs_rela/spreadjs_zh.js',
-                    '/public/js/zh_calc.js',
-                    '/public/js/path_tree.js',
-                    '/public/js/measure_compare.js',
+                    "/public/js/sub_menu.js",
+                    "/public/js/div_resizer.js",
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/zh_calc.js",
+                    "/public/js/path_tree.js",
+                    "/public/js/measure_compare.js"
                 ],
                 mergeFile: 'measure_compare',
-            },
+            }
         },
-    },
+    }
 
 };