Sfoglia il codice sorgente

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

TonyKang 4 anni fa
parent
commit
0684bafdf8
56 ha cambiato i file con 998 aggiunte e 114 eliminazioni
  1. 0 30
      app.js
  2. 1 1
      app/const/account_permission.js
  3. 11 0
      app/const/standard.js
  4. 2 0
      app/controller/ledger_controller.js
  5. 2 0
      app/controller/revise_controller.js
  6. 65 0
      app/controller/schedule_controller.js
  7. 2 0
      app/controller/stage_controller.js
  8. 23 0
      app/public/js/category.js
  9. 34 6
      app/public/js/gcl_gather.js
  10. 1 1
      app/public/js/global.js
  11. 44 0
      app/public/js/ledger.js
  12. 2 1
      app/public/js/ledger_bwtz.js
  13. 1 1
      app/public/js/ledger_gather.js
  14. 7 3
      app/public/js/material_exponent.js
  15. 54 5
      app/public/js/revise.js
  16. 1 1
      app/public/js/revise_gcl_compare.js
  17. 92 0
      app/public/js/schedule_ledger.js
  18. 0 3
      app/public/js/shares/cs_tools.js
  19. 37 6
      app/public/js/shares/gcl_gather_compare.js
  20. 2 0
      app/public/js/shenpi.js
  21. 2 1
      app/public/js/spreadjs_rela/spreadjs_zh.js
  22. 75 3
      app/public/js/stage.js
  23. 1 1
      app/public/js/stage_gather.js
  24. 6 3
      app/public/js/tender_list.js
  25. 4 0
      app/public/js/tender_list_info.js
  26. 2 0
      app/public/js/tender_list_manage.js
  27. 2 0
      app/public/js/tender_list_progress.js
  28. 20 1
      app/public/js/tender_showhide.js
  29. 2 0
      app/public/js/wap/list.js
  30. 1 1
      app/reports/util/rpt_pdf_util.js
  31. 5 0
      app/router.js
  32. 8 3
      app/service/category.js
  33. 6 2
      app/service/category_value.js
  34. 2 1
      app/service/tender_info.js
  35. 2 2
      app/view/advance/index.ejs
  36. 5 5
      app/view/ledger/audit.ejs
  37. 6 6
      app/view/ledger/bwtz.ejs
  38. 12 12
      app/view/ledger/explode.ejs
  39. 1 0
      app/view/ledger/gather.ejs
  40. 2 2
      app/view/measure/stage.ejs
  41. 1 0
      app/view/revise/gcl_compare.ejs
  42. 1 1
      app/view/revise/history.ejs
  43. 2 2
      app/view/revise/index.ejs
  44. 323 0
      app/view/schedule/index.ejs
  45. 63 0
      app/view/schedule/ledger.ejs
  46. 21 0
      app/view/schedule/ledger_modal.ejs
  47. 1 1
      app/view/setting/category_modal.ejs
  48. 1 0
      app/view/stage/gather.ejs
  49. 10 2
      app/view/stage/index.ejs
  50. 1 1
      app/view/stage/modal.ejs
  51. 2 2
      app/view/sum/index.ejs
  52. 3 2
      app/view/tender/shenpi.ejs
  53. 2 2
      app/view/tender/shenpi_modal.ejs
  54. 18 0
      config/web.js
  55. 1 0
      package.json
  56. 3 0
      sql/update.sql

+ 0 - 30
app.js

@@ -12,8 +12,6 @@ const fs = require('fs');
 const moment = require('moment');
 const uuid = require('node-uuid');
 const _ = require('lodash');
-const crypto = require('crypto');
-//const calc = require('number-precision');
 
 const BaseService = require('./app/base/base_service');
 const BaseTreeService = require('./app/base/base_tree_service');
@@ -97,32 +95,4 @@ module.exports = app => {
             }
         }
     }
-    if (app.config.min) {
-        app.minify = (file) => {
-            const files = file instanceof Array ? file : [file];
-            for (const f of files) {
-                const fileName = app.baseDir + '/app/public/js/' + f;
-                const code = fs.readFileSync(fileName, 'utf8');
-                fs.writeFileSync(fileName.replace('.js', '.min.js'), Uglyfy.minify(code, { mangle: true }).code);
-            }
-        };
-        app.minify(['spreadjs_rela/spreadjs_zh.js', 'path_tree.js']);
-    }
-    // 设置Date对象Format函数
-    Date.prototype.Format = function(fmt) {
-        const o = {
-            'M+': this.getMonth() + 1, // 月份
-            'd+': this.getDate(), // 日
-            'h+': this.getHours(), // 小时
-            'm+': this.getMinutes(), // 分
-            's+': this.getSeconds(), // 秒
-            'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
-            'S': this.getMilliseconds(), // 毫秒
-        };
-        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
-        for (const k in o) {
-            if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
-        }
-        return fmt;
-    };
 };

+ 1 - 1
app/const/account_permission.js

@@ -28,7 +28,7 @@ const permission = {
         children: [
             { title: '创建标段', value: 1 },
             { title: '查阅所有标段', value: 2 },
-            { title: '维护签约清单', value: 3, hint: '开启该选项,台审批通过后,可上传签约清单', hintIcon: 'fa-question-circle' },
+            { title: '维护签约清单', value: 3, hint: '开启该选项,台审批通过后,可上传签约清单', hintIcon: 'fa-question-circle' },
         ],
     },
     // cooperation: {

+ 11 - 0
app/const/standard.js

@@ -26,6 +26,17 @@ const nodeType = [
     {text: '其他建安工程', value: 14},
 ];
 
+const chapterFilter = [];
+const jrg = nodeType.find(x => {
+    return x.text === '计日工';
+});
+if (jrg) {
+    chapterFilter.push({node_type: jrg.value});
+    chapterFilter.push({field: 'name', part: jrg.text});
+}
+
+
 module.exports = {
     nodeType,
+    chapterFilter,
 };

+ 2 - 0
app/controller/ledger_controller.js

@@ -27,6 +27,7 @@ const path = require('path');
 const exportExcel = require('../lib/export_excel');
 const billsPosConvert = require('../lib/bills_pos_convert');
 const xlsx = require('js-xlsx');
+const stdConst = require('../const/standard');
 
 module.exports = app => {
 
@@ -697,6 +698,7 @@ module.exports = app => {
                 const renderData = {
                     tender: ctx.tender.data,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.ledger.gather),
+                    chapterFilter: stdConst.chapterFilter,
                 };
 
                 await this.layout('ledger/gather.ejs', renderData);

+ 2 - 0
app/controller/revise_controller.js

@@ -21,6 +21,7 @@ const spreadConst = require('../const/spread');
 const shenpiConst = require('../const/shenpi');
 const fs = require('fs');
 const LzString = require('lz-string');
+const stdConst = require('../const/standard');
 
 module.exports = app => {
     class ReviseController extends app.BaseController {
@@ -1019,6 +1020,7 @@ module.exports = app => {
             const renderData = {
                 revise,
                 jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.revise.gclCompare),
+                chapterFilter: stdConst.chapterFilter,
             };
             await this.layout('revise/gcl_compare.ejs', renderData);
         }

+ 65 - 0
app/controller/schedule_controller.js

@@ -0,0 +1,65 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Ellisran
+ * @date 2020/7/2
+ * @version
+ */
+
+const moment = require('moment');
+const measureType = require('../const/tender').measureType;
+const billsPosConvert = require('../lib/bills_pos_convert');
+
+module.exports = app => {
+    class ScheduleController extends app.BaseController {
+        async index(ctx) {
+            try {
+                const renderData = {
+                    tender: ctx.tender.data,
+                    tenderMenu: this.menu.tenderMenu,
+                    preUrl: '/tender/' + ctx.tender.id,
+                };
+                await this.layout('schedule/index.ejs', renderData);
+            } catch (err) {
+                this.log(err);
+                ctx.redirect(this.menu.menu.dashboard.url);
+            }
+        }
+
+        async ledger(ctx) {
+            const tender = ctx.tender;
+            const renderData = {
+                tender: tender.data,
+                tenderInfo: tender.info,
+                measureType,
+                jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.schedule.ledger),
+            };
+            await this.layout('schedule/ledger.ejs', renderData, 'schedule/ledger_modal.ejs');
+        }
+
+        /**
+         * 获取部位明细数据(Ajax)
+         *
+         * @param ctx
+         * @return {Promise<void>}
+         */
+        async loadLedgerData(ctx) {
+            try {
+                const ledgerData = await ctx.service.ledger.getData(ctx.tender.id);
+                const posData = this.ctx.tender.data.measure_type === measureType.tz.value
+                    ? await ctx.service.pos.getPosData({ tid: ctx.tender.id }) : [];
+                const convert = new billsPosConvert(ctx);
+                convert.loadData(ledgerData, posData, []);
+                const result = await convert.convert();
+                ctx.body = { err: 0, msg: '', data: result };
+            } catch (err) {
+                this.log(err);
+                ctx.body = { err: 1, msg: err.toString(), data: [] };
+            }
+        }
+    }
+
+    return ScheduleController;
+};

+ 2 - 0
app/controller/stage_controller.js

@@ -24,6 +24,7 @@ const accountGroup = require('../const/account_group').group;
 const sendToWormhole = require('stream-wormhole');
 const billsPosConvert = require('../lib/bills_pos_convert');
 const fs = require('fs');
+const stdConst = require('../const/standard');
 
 module.exports = app => {
     class StageController extends app.BaseController {
@@ -1171,6 +1172,7 @@ module.exports = app => {
                 [renderData.gclSpread, renderData.leafXmjSpread] = this._getGatherSpreadSetting();
 
                 renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.gather);
+                renderData.chapterFilter = stdConst.chapterFilter;
                 await this.layout('stage/gather.ejs', renderData, 'stage/gather_modal.ejs');
             } catch (err) {
                 this.log(err);

+ 23 - 0
app/public/js/category.js

@@ -58,6 +58,7 @@ function getValueHtml(value) {
     const html = [];
     for (const v of value) {
         html.push('<tr name="value" vid="' + v.id + '">');
+        html.push('<td><a href="javascript:void(0);" class="up-btn mr-2" title="上移"><i class="fa fa-caret-up"></i></a><a href="javascript:void(0);" class="down-btn" title="下移"><i class="fa fa-caret-down "></i></a></td>');
         html.push('<td><input class="form-control form-control-sm" name="value" placeholder="请输入值" value="' + v.value + '" vid ="' + v.id +  '"></td>');
         html.push('<td>', v.relaTenders.length + v.newTenders.length ,'</td>');
         html.push('<td><a href="javascript: void(0);" class="text-danger" name="del-value" vid="' + v.id + '">删除</a></td>');
@@ -113,11 +114,14 @@ function bindCategoryValueControl() {
         const value = _.find(editCate.value, function (v) {
             return v.id == vid;
         });
+        const delHtml = $(this).parents('td').html();
+        const _self = $(this).parents('td');
         $(this).remove();
         if (value.delete) { return; }
 
         if (value.relaTenders.length > 0) {
             // 提示用户转移标段
+            _self.html(delHtml);
             $('#tender-count').text(value.relaTenders.length).attr('vid', vid);
             $('#tender-target').html(getValidValueHtml(vid));
             $('input[type=radio]', '#tender-target')[0].checked = true;
@@ -293,4 +297,23 @@ $(document).ready(() => {
             $('#del-cate').modal('hide');
         });
     });
+
+    // 上移值
+    $('body').on('click', '.up-btn', function () {
+        const prev = $(this).parents("tr").prev();
+        const prevIndex = parseInt($(prev).index('#value-list tr'));
+        $(this).parents("tr").insertBefore(prev);
+        // if(prevIndex === 1){
+        //     console.log('hello');
+        // }
+    });
+    // 下一值
+    $('body').on('click', '.down-btn', function () {
+        const next = $(this).parents("tr").next();
+        const nextIndex = parseInt($(next).index('#value-list tr'));
+        const nowlength = $('#value-list tr').length - 1;
+        if (nextIndex < nowlength) {
+            $(this).parents("tr").insertAfter(next);
+        }
+    });
 });

+ 34 - 6
app/public/js/gcl_gather.js

@@ -452,22 +452,50 @@ const gclGatherModel = (function () {
         }
     }
 
-    function gatherChapterData(chapter, fields) {
-        const [gclChapter, otherChapter] = _getCalcChapter(chapter);
-        for (const d of gsTree.datas) {
+    function _checkFilter(d, filter) {
+        for (const f of filter) {
+            if (f.node_type && f.node_type === d.node_type) return true;
+            if (f.field) {
+                if (f.part && d[f.field] && d[f.field].indexOf(f.part) >= 0) return true;
+                if (f.all && d[f.all] && d[f.all] === f.all) return true;
+            }
+        }
+        return false;
+    }
+
+    function gatherChapterData(chapter, fields, filter = []) {
+        const filterPath = [];
+        const checkFilterPath = function (data) {
+            for (const fp of filterPath) {
+                if (data.full_path.indexOf(fp + '-') === 0 || data.full_path === fp) return true;
+            }
+            return false;
+        };
+
+        const [gclChapter, otherChapter] = _getCalcChapter(chapter, filter);
+        for (const d of gsTree.nodes) {
+            if (_checkFilter(d, filter)) {
+                filterPath.push(d.full_path);
+            }
             if (d.children && d.children.length > 0) continue;
 
             for (const c of otherChapter) {
                 if (c.cType === 41) {
                     gatherfields(c, d, fields);
-                } else if (c.cType === 31 && (!d.b_code || d.b_code === '')) {
+                }
+                if (c.cType === 11 && (d.b_code)) {
                     gatherfields(c, d, fields);
-                } else if (c.cType === 11 && (d.b_code)) {
+                }
+                if (!checkFilterPath(d)) continue;
+                if (c.cType === 31 && (!d.b_code || d.b_code === '')) {
                     gatherfields(c, d, fields);
                 }
             }
+
             if (d.b_code) {
-                const c = _getGclChapter(gclChapter, d);
+                const c = checkFilterPath(d)
+                    ? gclChapter.find(x => { return x.cType === 21})
+                    : _getGclChapter(gclChapter, d);
                 gatherfields(c, d, fields);
             }
         }

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

@@ -33,7 +33,7 @@ function autoFlashHeight(){
     $(".sjs-sh-4").height($(window).height()-cHeader-sBar4-92+55);
     $(".sjs-sh-5").height($(window).height()-cHeader-sBar5-92+55);
     for (const sh of $('.sjs-sh')) {
-        $(sh).height($(window).height()-cHeader-getObjHeight($('.sjs-bar', sh.parentNode))-92+55);
+        $(sh).height($(window).height()-cHeader-getObjHeight($('.sjs-bar', sh.parentNode))-getObjHeight($('.sjs-bottom', sh.parentNode))-92+55);
     }
     /*工程变更添加清单高度*/
     $(".sjs-biangeng-height").height($(window).height()/3.3);

+ 44 - 0
app/public/js/ledger.js

@@ -1246,6 +1246,50 @@ $(document).ready(function() {
             return select && select.level <= 1;
         }
     };
+    billsContextMenuOptions.items.copyBlockXmj = {
+        name: '复制整块(只复制项目节)',
+        icon: 'fa-files-o',
+        callback: function (key, opt) {
+            treeOperationObj.block = [];
+            const copyBlockList = [];
+            const sheet = ledgerSpread.getActiveSheet();
+            const sel = sheet.getSelections()[0];
+            let iRow = sel.row;
+            const pid = sheet.zh_tree.nodes[iRow].ledger_pid;
+            while (iRow < sel.row + sel.rowCount) {
+                const node = sheet.zh_tree.nodes[iRow];
+                if (node.ledger_pid !== pid) {
+                    toastr.error('仅可同时选中同层节点');
+                    return;
+                }
+                const posterity = sheet.zh_tree.getPosterity(node);
+                iRow += posterity.length + 1;
+                const copyPosterity = posterity.filter(x => { return !x.b_code; });
+                copyPosterity.unshift(node);
+                const copyData = sheet.zh_tree.getDefaultData(copyPosterity);
+                for (const p of copyData) {
+                    const children = copyData.filter(y => {return y.ledger_pid === p.ledger_id}) || [];
+                    p.is_leaf = children.length === 0;
+                }
+                copyBlockList.push(copyData);
+            }
+            setLocalCache(copyBlockTag, JSON.stringify({block: copyBlockList}));
+        },
+        visible: function (key, opt) {
+            const sheet = ledgerSpread.getActiveSheet();
+            const selection = sheet.getSelections();
+            const row = selection[0].row;
+            const select = ledgerTree.nodes[row];
+            return select;
+        },
+        disabled: function (key, opt) {
+            const sheet = ledgerSpread.getActiveSheet();
+            const selection = sheet.getSelections();
+            const row = selection[0].row;
+            const select = ledgerTree.nodes[row];
+            return select && select.level <= 1;
+        }
+    };
     if (!readOnly) {
         billsContextMenuOptions.items.pasteBlock = {
             name: '粘贴整块',

+ 2 - 1
app/public/js/ledger_bwtz.js

@@ -55,6 +55,7 @@ $(document).ready(() => {
                 n.unitTree.loadDatas(n.unitTreeData);
             }
         }
+        console.log(xmjTree);
         SpreadJsObj.loadSheetData(xmjSheet, SpreadJsObj.DataType.Tree, xmjTree);
         unitTreeObj.loadCurUnitData();
     });
@@ -234,4 +235,4 @@ $(document).ready(() => {
 
         SpreadExcelObj.exportSimpleXlsxSheet(setting, data, $('.sidebar-title').attr('data-original-title') + "-部位台账.xlsx");
     });
-});
+});

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

@@ -176,7 +176,7 @@ $(document).ready(() => {
         checkCompareData();
         loadLeafXmjData(0);
 
-        const chapterData = gclGatherModel.gatherChapterData(chapter, ['total_price']);
+        const chapterData = gclGatherModel.gatherChapterData(chapter, ['total_price'], filter);
         for (const c of chapterData) {
             c.compare_tp = ZhCalc.sub(c.deal_bills_tp, c.total_price);
         }

+ 7 - 3
app/public/js/material_exponent.js

@@ -234,6 +234,8 @@ $(document).ready(() => {
             }
         },
         deletePress: function (sheet) {
+            if (!sheet.zh_setting || readOnly || sheet.zh_setting.readOnly) return;
+            // materialExponentBase.isUsed(select)
             if (sheet.zh_setting && sheet.zh_data) {
                 const sel = sheet.getSelections()[0];
                 if (!sel) return;
@@ -246,6 +248,7 @@ $(document).ready(() => {
                     for (let iCol = 0; iCol < sel.colCount; iCol++) {
                         const curCol = sel.col + iCol;
                         const colSetting = sheet.zh_setting.cols[curCol];
+                        if(colSetting.readOnly(exData)) continue;
                         if (!colSetting) continue;
                         const orgValue = sortData[iRow][colSetting.field];
                         if(orgValue === null) {
@@ -273,7 +276,6 @@ $(document).ready(() => {
                     SpreadJsObj.reLoadSheetData(sheet);
                     return;
                 }
-                // console.log(data);
                 // 更新至服务器
                 postData(window.location.pathname + '/save', { type:'paste', updateData: data }, function (result) {
                     materialExponentData = result.info;
@@ -400,14 +402,16 @@ $(document).ready(() => {
     };
     materialExponentSpreadObj.refreshActn();
     materialExponentSpread.bind(spreadNS.Events.SelectionChanged, materialExponentSpreadObj.selectionChanged);
-    materialExponentSpread.bind(spreadNS.Events.ClipboardPasted, materialExponentSpreadObj.clipboardPasted);
-    SpreadJsObj.addDeleteBind(materialExponentSpread, materialExponentSpreadObj.deletePress);
+
+
 
     if (!readOnly) {
         $('#add').click(materialExponentSpreadObj.add);
         $('#del').click(materialExponentSpreadObj.del);
         materialExponentSpread.bind(spreadNS.Events.EditEnded, materialExponentSpreadObj.editEnded);
         materialExponentSpread.bind(spreadNS.Events.ButtonClicked, materialExponentSpreadObj.buttonClicked);
+        materialExponentSpread.bind(spreadNS.Events.ClipboardPasted, materialExponentSpreadObj.clipboardPasted);
+        SpreadJsObj.addDeleteBind(materialExponentSpread, materialExponentSpreadObj.deletePress);
         // 右键菜单
         $.contextMenu({
             selector: '#material-exponent-spread',

+ 54 - 5
app/public/js/revise.js

@@ -690,6 +690,7 @@ $(document).ready(() => {
             if (!sheet.zh_setting) return;
             const sel = sheet.getSelections()[0], datas = [];
             for (let iRow = sel.row; iRow < sel.row + sel.rowCount; iRow++) {
+                let bDel = false;
                 const node = sheet.zh_tree.nodes[iRow];
                 if (sheet.zh_tree.checkNodeUsed(node, pos)) {
                     toastr.warning('"' + node.code + node.b_code + ' ' + node.name +'"已计量,请勿修改');
@@ -698,13 +699,18 @@ $(document).ready(() => {
                 const data = sheet.zh_tree.getNodeKeyData(node);
                 for (let iCol = sel.col; iCol < sel.col + sel.colCount; iCol++) {
                     const col = sheet.zh_setting.cols[iCol];
-                    data[col.field] = null;
-                    const exprInfo = getExprInfo(col.field);
-                    if (exprInfo) {
-                        data[exprInfo.expr] = '';
+
+                    const style = sheet.getStyle(iRow, iCol);
+                    if (!style.locked) {
+                        data[col.field] = null;
+                        const exprInfo = getExprInfo(col.field);
+                        if (exprInfo) {
+                            data[exprInfo.expr] = '';
+                        }
+                        bDel = true;
                     }
                 }
-                datas.push(data);
+                if (bDel) datas.push(data);
             }
             if (datas.length > 0) {
                 postData(window.location.pathname + '/update', {postType: 'update', postData: datas}, function (result) {
@@ -1069,6 +1075,49 @@ $(document).ready(() => {
             return select && select.level <= 1;
         }
     };
+    billsContextMenuOptions.items.copyBlockXmj = {
+        name: '复制整块(只复制项目节)',
+        icon: 'fa-files-o',
+        callback: function (key, opt) {
+            const copyBlockList = [];
+            const sheet = billsSheet;
+            const sel = sheet.getSelections()[0];
+            let iRow = sel.row;
+            const pid = sheet.zh_tree.nodes[iRow].ledger_pid;
+            while (iRow < sel.row + sel.rowCount) {
+                const node = sheet.zh_tree.nodes[iRow];
+                if (node.ledger_pid !== pid) {
+                    toastr.error('仅可同时选中同层节点');
+                    return;
+                }
+                const posterity = sheet.zh_tree.getPosterity(node);
+                iRow += posterity.length + 1;
+                const copyPosterity = posterity.filter(x => { return !x.b_code; });
+                copyPosterity.unshift(node);
+                const copyData = sheet.zh_tree.getDefaultData(copyPosterity);
+                for (const p of copyData) {
+                    const children = copyData.filter(y => {return y.ledger_pid === p.ledger_id}) || [];
+                    p.is_leaf = children.length === 0;
+                }
+                copyBlockList.push(copyData);
+            }
+            setLocalCache(copyBlockTag, JSON.stringify({ block: copyBlockList }));
+        },
+        visible: function (key, opt) {
+            const sheet = billsSheet;
+            const selection = sheet.getSelections();
+            const row = selection[0].row;
+            const select = billsTree.nodes[row];
+            return select;
+        },
+        disabled: function (key, opt) {
+            const sheet = billsSheet;
+            const selection = sheet.getSelections();
+            const row = selection[0].row;
+            const select = billsTree.nodes[row];
+            return select && select.level <= 1;
+        }
+    };
     if (!readOnly) {
         billsContextMenuOptions.items.pasteBlock = {
             name: '粘贴整块',

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

@@ -165,7 +165,7 @@ $(document).ready(() => {
             posFields: ['quantity'],
             chapterFields: ['total_price'],
         };
-        gclCompareModel.init(gclData, chapter);
+        gclCompareModel.init(gclData, chapter, filter);
         setting.prefix = 'new_';
         gclCompareModel.gatherLedgerData(data.reviseBills, data.revisePos, setting);
         setting.prefix = 'org_';

+ 92 - 0
app/public/js/schedule_ledger.js

@@ -0,0 +1,92 @@
+/**
+ * 进度台账相关js
+ *
+ * @author Ellisran
+ * @date 2020/11/6
+ * @version
+ */
+function getTenderId() {
+    return window.location.pathname.split('/')[2];
+}
+$(function () {
+    autoFlashHeight();
+    // 初始化台账
+    const ledgerSpread = SpreadJsObj.createNewSpread($('#ledger-spread')[0]);
+    const treeSetting = {
+        id: 'ledger_id',
+        pid: 'ledger_pid',
+        order: 'order',
+        level: 'level',
+        rootId: -1,
+        fullPath: 'full_path',
+        calcFields: ['total_price']
+        //treeCacheKey: 'ledger_bills_fold' + '_' + getTenderId(),
+        // markFoldKey: 'bills-fold',
+        // markFoldSubKey: window.location.pathname.split('/')[2],
+    };
+    treeSetting.calcFun = function (node) {
+        node.dgn_price = ZhCalc.round(ZhCalc.div(node.total_price, node.dgn_qty1), 2);
+    };
+    const ledgerTree = createNewPathTree('base', treeSetting);
+
+    const ledgerSpreadSetting = {
+        cols: [
+            {title: '', colSpan: '1', rowSpan: '2', field: 'is_select', hAlign: 1, width: 40, formatter: '@', cellType: 'checkbox'},
+            {title: '编号', colSpan: '1', rowSpan: '2', field: 'code', hAlign: 0, width: 185, formatter: '@', readOnly: true, cellType: 'tree'},
+            {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 205, formatter: '@', readOnly: true},
+            {title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 100, formatter: '@', readOnly: true},
+            {title: '经济指标', colSpan: '1', rowSpan: '2', field: 'dgn_price', hAlign: 2, width: 100, type: 'Number', readOnly: true},
+            {title: '工程量', colSpan: '1', rowSpan: '2', field: 'dgn_qty1', hAlign: 2, width: 100, type: 'Number', readOnly: true},
+            {title: '金额', colSpan: '1', rowSpan: '2', field: 'total_price', hAlign: 2, width: 100, type: 'Number', readOnly: true},
+        ],
+        emptyRows: 0,
+        headRows: 1,
+        headRowHeight: [25, 25],
+        defaultRowHeight: 21,
+        headerFont: '12px 微软雅黑',
+        font: '12px 微软雅黑',
+        readOnly: true,
+        localCache: {
+            key: 'ledger-bills',
+            colWidth: true,
+        }
+    };
+
+    sjsSettingObj.setFxTreeStyle(ledgerSpreadSetting, sjsSettingObj.FxTreeStyle.jz);
+    if (thousandth) sjsSettingObj.setTpThousandthFormat(ledgerSpreadSetting);
+    SpreadJsObj.initSheet(ledgerSpread.getActiveSheet(), ledgerSpreadSetting);
+    SpreadJsObj.selChangedRefreshBackColor(ledgerSpread.getActiveSheet());
+
+    postData(window.location.pathname + '/load', {}, function (data) {
+        ledgerTree.loadDatas(data);
+        treeCalc.calculateAll(ledgerTree);
+        SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), SpreadJsObj.DataType.Tree, ledgerTree);
+    }, null, true);
+
+    // // 显示层次
+    // (function (select, sheet) {
+    //     $(select).click(function () {
+    //         const tag = $(this).attr('tag');
+    //         const tree = sheet.zh_tree;
+    //         if (!tree) return;
+    //         switch (tag) {
+    //             case "1":
+    //             case "2":
+    //             case "3":
+    //             case "4":
+    //             case "5":
+    //                 tree.expandByLevel(parseInt(tag));
+    //                 SpreadJsObj.refreshTreeRowVisible(sheet);
+    //                 break;
+    //             case "last":
+    //                 tree.expandByCustom(() => { return true; });
+    //                 SpreadJsObj.refreshTreeRowVisible(sheet);
+    //                 break;
+    //             case "leafXmj":
+    //                 tree.expandToLeafXmj();
+    //                 SpreadJsObj.refreshTreeRowVisible(sheet);
+    //                 break;
+    //         }
+    //     });
+    // })('a[name=showLevel]', ledgerSpread.getActiveSheet());
+});

+ 0 - 3
app/public/js/shares/cs_tools.js

@@ -104,7 +104,6 @@ const showSideTools = function (show) {
             const spread = SpreadJsObj.createNewSpread($('#' + resultId)[0]);
             const sheet = spread.getActiveSheet();
             SpreadJsObj.initSheet(sheet, setting.spreadSetting);
-            SpreadJsObj.forbiddenSpreadContextMenu('#' + resultId, spread);
 
             spread.getActiveSheet().bind(spreadNS.Events.CellDoubleClick, function (e, info) {
                 const sheet = info.sheet;
@@ -258,7 +257,6 @@ const showSideTools = function (show) {
             const spread = SpreadJsObj.createNewSpread($('#' + resultId)[0]);
             const sheet = spread.getActiveSheet();
             SpreadJsObj.initSheet(sheet, setting.spreadSetting);
-            SpreadJsObj.forbiddenSpreadContextMenu('#' + resultId, spread);
 
             spread.getActiveSheet().bind(spreadNS.Events.CellDoubleClick, function (e, info) {
                 const sheet = info.sheet;
@@ -505,7 +503,6 @@ const showSideTools = function (show) {
         autoFlashHeight();
         const resultSpread = SpreadJsObj.createNewSpread($('#' + resultId)[0]);
         SpreadJsObj.initSheet(resultSpread.getActiveSheet(), setting.resultSpreadSetting);
-        SpreadJsObj.forbiddenSpreadContextMenu('#' + resultId, resultSpread);
         const searchSheet = setting.searchSpread.getActiveSheet();
         let searchResult = [];
         const search = function () {

+ 37 - 6
app/public/js/shares/gcl_gather_compare.js

@@ -11,7 +11,7 @@
 
 const gclCompareModel = (function () {
     const leafXmjs = [], mergeChar = ';';
-    let gclList, gclChapter, otherChapter;
+    let gclList, gclChapter, otherChapter, chapterfilter;
     let ledgerSetting, gsTree;
 
     function gatherfields(obj, src, fields, prefix = '') {
@@ -292,29 +292,60 @@ const gclCompareModel = (function () {
         }
     }
 
+    function _checkFilter(d, filter) {
+        for (const f of filter) {
+            if (f.node_type && f.node_type === d.node_type) return true;
+            if (f.field) {
+                if (f.part && d[f.field] && d[f.field].indexOf(f.part) >= 0) return true;
+                if (f.all && d[f.all] && d[f.all] === f.all) return true;
+            }
+        }
+        return false;
+    }
+
     function _gatherChapter() {
-        for (const d of gsTree.datas) {
+        const filterPath = [];
+        const checkFilterPath = function (data) {
+            for (const fp of filterPath) {
+                if (data.full_path.indexOf(fp + '-') === 0 || data.full_path === fp) return true;
+            }
+            return false;
+        };
+
+        for (const d of gsTree.nodes) {
+            if (_checkFilter(d, chapterfilter)) {
+                filterPath.push(d.full_path);
+            }
             if (d.children && d.children.length > 0) continue;
 
             for (const c of otherChapter) {
                 if (c.cType === 41) {
                     gatherfields(c, d, ledgerSetting.chapterFields, ledgerSetting.prefix);
-                } else if (c.cType === 31 && (!d.b_code || d.b_code === '')) {
+                }
+                if (c.cType === 11 && (d.b_code)) {
                     gatherfields(c, d, ledgerSetting.chapterFields, ledgerSetting.prefix);
-                } else if (c.cType === 11 && (d.b_code)) {
+                }
+                if (!checkFilterPath(d)) continue;
+                if (c.cType === 31 && (!d.b_code || d.b_code === '')) {
                     gatherfields(c, d, ledgerSetting.chapterFields, ledgerSetting.prefix);
                 }
             }
+            for (const fp of filterPath) {
+                if (d.full_path.indexOf(fp + '-') === 0 || d.full_path === fp) continue;
+            }
             if (d.b_code) {
-                const c = _getGclChapter(gclChapter, d);
+                const c = checkFilterPath(d)
+                    ? gclChapter.find(x => { return x.cType === 21})
+                    : _getGclChapter(gclChapter, d);
                 gatherfields(c, d, ledgerSetting.chapterFields, ledgerSetting.prefix);
             }
         }
     }
 
-    function init (gclData, chapter) {
+    function init (gclData, chapter, filter) {
         gclList = gclData;
         [gclChapter, otherChapter] = _getCalcChapter(chapter);
+        chapterfilter = filter || [];
     }
 
     /**

+ 2 - 0
app/public/js/shenpi.js

@@ -42,6 +42,7 @@ function initTenderTree () {
                 children: [],
                 level: i ? i : category.level,
                 sort_id: ++parentId,
+                sort: cateValue.sort,
             };
             array.push(cate);
         }
@@ -93,6 +94,7 @@ function initTenderTree () {
             tenderTree.push(t);
         }
     }
+    sortTenderTree();
 }
 function recursiveGetTenderNodeHtml (node, arr, pid, this_code, this_status, aidList = []) {
     const html = [];

+ 2 - 1
app/public/js/spreadjs_rela/spreadjs_zh.js

@@ -796,7 +796,8 @@ const SpreadJsObj = {
 
         this.beginMassOperation(sheet);
         try {
-            for (const iCol of cols) {
+            for (const col of cols) {
+                const iCol = sheet.zh_setting.cols.indexOf(col);
                 // 清空原单元格数据
                 sheet.clear(-1, iCol, -1, 1, spreadNS.SheetArea.viewport, spreadNS.StorageType.data);
 

+ 75 - 3
app/public/js/stage.js

@@ -185,14 +185,15 @@ $(document).ready(() => {
     // 台账树结构计算相关设置
     stageTreeSetting.updateFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil', 'used', 'contract_expr'];
     stageTreeSetting.calcFields = ['deal_tp', 'total_price', 'contract_tp', 'qc_tp', 'gather_tp',
-        'pre_contract_tp', 'pre_qc_tp', 'pre_gather_tp', 'end_contract_tp', 'end_qc_tp', 'end_gather_tp'];
+        'pre_contract_tp', 'pre_qc_tp', 'pre_gather_tp', 'end_contract_tp', 'end_qc_tp', 'end_gather_tp', 'end_correct_tp'];
     stageTreeSetting.calcFun = function (node) {
-        if (node.children && node.children.length === 0) {
+        if (!node.children || node.children.length === 0) {
             node.pre_gather_qty = ZhCalc.add(node.pre_contract_qty, node.pre_qc_qty);
             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.end_correct_tp = ZhCalc.add(node.end_qc_tp, ZhCalc.mul(node.end_contract_qty, node.unit_price, tenderInfo.decimal.tp));
         }
         node.pre_gather_tp = ZhCalc.add(node.pre_contract_tp, node.pre_qc_tp);
         node.gather_tp = ZhCalc.add(node.contract_tp, node.qc_tp);
@@ -201,6 +202,7 @@ $(document).ready(() => {
         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.end_correct_percent = ZhCalc.mul(ZhCalc.div(node.end_correct_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);
@@ -1207,7 +1209,7 @@ $(document).ready(() => {
                     const [leafUsedBills, usedPos] = stageIm.getFirstUsed(node);
                     if (leafUsedBills) {
                         if (!$('#zhongjian').hasClass('active')) {
-                            const tab = $('#zhongjian'), tabPanel = $(tab.attr('content'));
+                            const tab = $('#zhongjiantab'), tabPanel = $(tab.attr('content'));
                             $('a', '.side-menu').removeClass('active');
                             $('.tab-content .tab-select-show').removeClass('active');
                             tab.addClass('active');
@@ -3019,6 +3021,70 @@ $(document).ready(() => {
             setting.reloadObj.click(function() {
                 self.reloadChangeData();
             });
+            $.contextMenu({
+                selector: '#' + setting.changeBillsObj.attr('id'),
+                build: function ($trigger, e) {
+                    const target = SpreadJsObj.safeRightClickSelection($trigger, e, self.changeBillsSpread);
+                    return target.hitTestType === spreadNS.SheetArea.viewport || target.hitTestType === spreadNS.SheetArea.rowHeader;
+                },
+                items: {
+                    'locateZjjl': {
+                        name: '定位至台账',
+                        icon: 'fa-sign-in',
+                        callback: function (key, opt) {
+                            const checkPosMatch = function (bills, posName) {
+                                const posRange = stagePos.getLedgerPos(p.id);
+                                for (const pr of posRange) {
+                                    if (pr.name === posName) return true;
+                                }
+                                return false;
+                            };
+                            const checkBillsMatch = function (bills, checkData, posName) {
+                                if (bills.children && bills.children.length > 0) return false;
+                                const billsCheckData = {
+                                    b_code: bills.b_code || '',
+                                    name: bills.name || '',
+                                    unit: bills.unit || '',
+                                    unit_price: bills.unit_price || 0,
+                                };
+                                if (!_.isMatch(checkData, billsCheckData)) return false;
+                                return !posName || checkPosMatch(bills, posName);
+                            };
+                            const changeBills = SpreadJsObj.getSelectObject(self.changeBillsSheet);
+                            const cb = {
+                                b_code: changeBills.code || '',
+                                name: changeBills.name || '',
+                                unit: changeBills.unit || '',
+                                unit_price: changeBills.unit_price || 0,
+                            };
+                            if (changeBills.lid && changeBills.lid !== '0') {
+                                const node = stageTree.nodes.find(x => {return x.id === changeBills.lid});
+                                const posterity = stageTree.getPosterity(node) || [];
+                                posterity.unshift(node);
+                                for (const p of posterity) {
+                                    if (checkBillsMatch(p, cb, changeBills.detail)) {
+                                        SpreadJsObj.locateTreeNode(slSpread.getActiveSheet(), p.ledger_id);
+                                        stagePosSpreadObj.loadCurPosData();
+                                        return;
+                                    }
+                                }
+                            } else {
+                                for (const node of stageTree.nodes) {
+                                    if (checkBillsMatch(node, cb, changeBills.detail)) {
+                                        SpreadJsObj.locateTreeNode(slSpread.getActiveSheet(), node.ledger_id);
+                                        stagePosSpreadObj.loadCurPosData();
+                                        return;
+                                    }
+                                }
+                            }
+                        },
+                        disabled: function (key, opt) {
+                            const changeBills = SpreadJsObj.getSelectObject(self.changeBillsSheet);
+                            return !changeBills;
+                        }
+                    },
+                }
+            });
         }
         loadChangeDetailData() {
             const change = SpreadJsObj.getSelectObject(this.changeSheet);
@@ -3712,5 +3778,11 @@ $(document).ready(() => {
             return;
         }
         stageTreeSpreadObj.measureByBatch(posName, ratio, apply2sibling);
+    });
+    $('#correct_percent').click(function () {
+        const sheet = slSpread.getActiveSheet();
+        const col = sheet.zh_setting.cols.find(x => {return x.field === 'end_gather_percent' || x.field === 'end_correct_percent'});
+        col.field = this.checked ? 'end_correct_percent' : 'end_gather_percent';
+        SpreadJsObj.reLoadColsData(sheet, [col]);
     })
 });

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

@@ -126,7 +126,7 @@ $(document).ready(function () {
         SpreadJsObj.loadSheetData(gclSpread.getActiveSheet(), SpreadJsObj.DataType.Data, gclGatherData);
         loadLeafXmjData(0);
         // 章节合计
-        const chapterData = gclGatherModel.gatherChapterData(chapter, ['total_price', 'contract_tp', 'qc_tp', 'pre_contract_tp', 'pre_qc_tp']);
+        const chapterData = gclGatherModel.gatherChapterData(chapter, ['total_price', 'contract_tp', 'qc_tp', 'pre_contract_tp', 'pre_qc_tp'], filter);
         for (const c of chapterData) {
             c.gather_tp = ZhCalc.add(c.contract_tp, c.qc_tp);
             c.end_contract_tp = ZhCalc.add(c.contract_tp, c.pre_contract_tp);

+ 6 - 3
app/public/js/tender_list.js

@@ -217,6 +217,7 @@ function initTenderTree () {
                 children: [],
                 level: i ? i : category.level,
                 sort_id: ++parentId,
+                sort: cateValue.sort,
             };
             array.push(cate);
         }
@@ -268,7 +269,9 @@ function initTenderTree () {
             tenderTree.push(t);
         }
     }
+    sortTenderTree();
 }
+
 function recursiveGetTenderNodeHtml (node, arr, pid) {
     const html = [];
     html.push('<tr pid="' + pid + '">');
@@ -363,10 +366,10 @@ $(document).ready(() => {
     $('.modal-body', '#add-bd').append(getCategoryHtml());
     // 初始化标段树结构
     tenderListOrder.reOrderTenders();
-    initTenderTree();
-    $('.c-body').html(getTenderTreeHtml());
+    // initTenderTree();
+    // $('.c-body').html(getTenderTreeHtml());
     bindTenderUrl();
-    localHideList();
+    // localHideList();
 
     // 分类
     $('#cate-set').on('show.bs.modal', function () {

+ 4 - 0
app/public/js/tender_list_info.js

@@ -200,6 +200,7 @@ function calculateParent(node) {
         node.pre_gather_tp = 0;
         node.yf_tp = 0;
         node.end_yf_tp = 0;
+        node.advance_tp = 0;
         for (const c of node.children) {
             calculateParent(c);
             node.total_price = ZhCalc.add(node.total_price, c.total_price);
@@ -210,6 +211,7 @@ function calculateParent(node) {
             node.pre_gather_tp = ZhCalc.add(node.pre_gather_tp, c.pre_gather_tp);
             node.yf_tp = ZhCalc.add(node.yf_tp, c.yf_tp);
             node.end_yf_tp = ZhCalc.add(node.end_yf_tp, c.end_yf_tp);
+            node.advance_tp = ZhCalc.add(node.advance_tp, c.advance_tp);
         }
     }
 }
@@ -237,6 +239,7 @@ function initTenderTree () {
                 children: [],
                 level: i ? i : category.level,
                 sort_id: ++parentId,
+                sort: cateValue.sort,
             };
             array.push(cate);
         }
@@ -288,6 +291,7 @@ function initTenderTree () {
             tenderTree.push(t);
         }
     }
+    sortTenderTree();
     for (const t of tenderTree) {
         calculateParent(t);
     }

+ 2 - 0
app/public/js/tender_list_manage.js

@@ -215,6 +215,7 @@ function initTenderTree () {
                 children: [],
                 level: i ? i : category.level,
                 sort_id: ++parentId,
+                sort: cateValue.sort,
             };
             array.push(cate);
         }
@@ -255,6 +256,7 @@ function initTenderTree () {
             tenderTree.push(t);
         }
     }
+    sortTenderTree();
 }
 function recursiveGetTenderNodeHtml (node, arr, pid) {
     const html = [];

+ 2 - 0
app/public/js/tender_list_progress.js

@@ -234,6 +234,7 @@ function initTenderTree () {
                 children: [],
                 level: i ? i : category.level,
                 sort_id: ++parentId,
+                sort: cateValue.sort,
             };
             array.push(cate);
         }
@@ -284,6 +285,7 @@ function initTenderTree () {
             tenderTree.push(t);
         }
     }
+    sortTenderTree();
     for (const t of tenderTree) {
         calculateParent(t);
     }

+ 20 - 1
app/public/js/tender_showhide.js

@@ -29,7 +29,26 @@ function removeValueToCate(cate) {
     }
     return newCate;
 }
-
+// 根据标段类别设置排序
+function sortTenderTree(teTree = tenderTree) {
+    for (const tender of teTree) {
+        if (tender.sort) {
+            // 当前层排序
+            teTree.sort(function (a, b) {
+                if (a.sort && b.sort) {
+                    return a.sort - b.sort;
+                } else if (a.sort && !b.sort) {
+                    return -1;
+                } else if (b.sort && !a.sort) {
+                    return 1;
+                } else {
+                    return 0;
+                }
+            });
+            sortTenderTree(tender.children);
+        }
+    }
+}
 function localHideList(wap = false) {
     const pro_cate = getLocalCache('pro_'+ pid + '_category_list');
     const cate = JSON.stringify(removeValueToCate(category));

+ 2 - 0
app/public/js/wap/list.js

@@ -84,6 +84,7 @@ function initTenderTree () {
                 children: [],
                 level: i ? i : category.level,
                 sort_id: ++parentId,
+                sort: cateValue.sort,
             };
             array.push(cate);
         }
@@ -134,6 +135,7 @@ function initTenderTree () {
             tenderTree.push(t);
         }
     }
+    sortTenderTree();
     for (const t of tenderTree) {
         calculateParent(t);
     }

+ 1 - 1
app/reports/util/rpt_pdf_util.js

@@ -11,7 +11,7 @@ const fs = require('fs');
 const jpcCmnHelper = require('../rpt_component/helper/jpc_helper_common');
 const DPI = jpcCmnHelper.getScreenDPI()[0] * PDF_SCALE;
 const JV = require('../rpt_component/jpc_value_define');
-const uuidV1 = require('uuid/v1');
+const uuidV1 = require('uuid').v1;
 
 let fontUtil = require('./rpt_font_util');
 

+ 5 - 0
app/router.js

@@ -417,4 +417,9 @@ module.exports = app => {
     app.get('/wx/project', wechatAuth, 'wechatController.project');
     app.get('/wx/test', 'wechatController.testwx');
     app.get('/MP_verify_t3MkWAMqplVxPjmr.txt', 'wechatController.oauthTxt');
+
+    // 形象进度
+    app.get('/tender/:id/schedule', sessionAuth, tenderCheck, uncheckTenderCheck, 'scheduleController.index');
+    app.get('/tender/:id/schedule/ledger', sessionAuth, tenderCheck, uncheckTenderCheck, 'scheduleController.ledger');
+    app.post('/tender/:id/schedule/ledger/load', sessionAuth, tenderCheck, uncheckTenderCheck, 'scheduleController.loadLedgerData');
 };

+ 8 - 3
app/service/category.js

@@ -129,7 +129,7 @@ module.exports = app => {
          */
         async getCategory(id) {
             const data = await this.getDataByCondition({id: id});
-            data.value = await this.ctx.service.categoryValue.getAllDataByCondition({ where: {cid: id} });
+            data.value = await this.ctx.service.categoryValue.getAllDataByCondition({ where: { cid: id }, orders: [['sort', 'asc'], ['id', 'asc']] });
             return data;
         }
         /**
@@ -139,8 +139,13 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAllCategory(pid) {
-            const data = await this.getAllDataByCondition({where: {pid: pid}});
-            const values = await this.ctx.service.categoryValue.getAllDataByCondition({ where: {pid: pid} });
+            const data = await this.getAllDataByCondition({ where: { pid } });
+            const values = await this.ctx.service.categoryValue.getAllDataByCondition({
+                where: { pid },
+                orders: [['sort', 'asc'], ['id', 'asc']],
+            });
+            // values 按名称排序
+            // values.sort((a, b) => a.value.localeCompare(b.value, 'zh-Hans-CN', { sensitivity: 'accent' }));
             for (const d of data) {
                 d.value = values.filter(function (v) {
                     return v.cid === d.id;

+ 6 - 2
app/service/category_value.js

@@ -69,18 +69,22 @@ module.exports = app => {
 
             this.transaction = await this.db.beginTransaction();
             try {
+                let sort = 1;
                 for (const v of value) {
                     if (v.delete) {
                         await this.transaction.delete(this.tableName, {id: v.id});
                     } else if (v.new) {
                         const result = await this.transaction.insert(this.tableName, {
-                            cid: cid,
+                            cid,
                             pid: this.ctx.session.sessionProject.id,
                             value: v.value,
+                            sort,
                         });
                         v.id = result.insertId;
+                        sort++;
                     } else {
-                        await this.transaction.update(this.tableName, {id: v.id, value: v.value});
+                        await this.transaction.update(this.tableName, { id: v.id, value: v.value, sort });
+                        sort++;
                     }
                     if (!v.newTenders) { continue }
                     for (const nt of v.newTenders) {

+ 2 - 1
app/service/tender_info.js

@@ -346,7 +346,8 @@ module.exports = app => {
             if (!info) {
                 return false;
             }
-            const shenpiInfo = !info.shenpi || info.shenpi === null || info.shenpi === '' ? defaultInfo.shenpi : JSON.parse(info.shenpi);
+            const defaultShenpiInfo = JSON.parse(JSON.stringify(defaultInfo.shenpi));
+            const shenpiInfo = !info.shenpi || info.shenpi === null || info.shenpi === '' ? defaultShenpiInfo : JSON.parse(info.shenpi);
             return shenpiInfo;
         }
     }

+ 2 - 2
app/view/advance/index.ejs

@@ -28,11 +28,11 @@
                     </div>
                 </div>
             </div>
-            <div>
+            <div class="ml-auto">
                 <% if(showAddBtn) { %>
                     <form action="<%- preUrl %>" method="POST">
                         <input type="hidden" name="_csrf" value="<%= ctx.csrf %>">
-                        <button type="submit" class="btn btn-primary btn-sm pull-right">开始新一期</button>
+                        <button type="submit" class="btn btn-primary btn-sm">开始新一期</button>
                     </form>
                     <!-- <a id="advance_add" href="" class="btn btn-primary btn-sm pull-right"></a> -->
                 <% } %>

+ 5 - 5
app/view/ledger/audit.ejs

@@ -22,16 +22,16 @@
             <div></div>
             <div class="ml-auto">
                 <% if (tender.ledger_status === auditConst.status.checkNo) { %>
-                    <a href="#sp-list"  data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm pull-right text-dark mr-1 sp-list-btn">退回意见</a>
+                    <a href="#sp-list"  data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm text-dark mr-1 sp-list-btn">退回意见</a>
                 <% } else if (tender.ledger_status === auditConst.status.checking) { %>
                     <% if (curAuditor.audit_id === ctx.session.sessionUser.accountId) { %>
-                        <a href="#sp-done" data-toggle="modal" data-target="#sp-done" class="btn btn-success btn-sm pull-right mr-1">审批通过</a>
-                        <a href="#sp-back" data-toggle="modal" data-target="#sp-back" class="btn btn-warning btn-sm pull-right mr-1">审批退回</a>
+                        <a href="#sp-done" data-toggle="modal" data-target="#sp-done" class="btn btn-success btn-sm mr-1">审批通过</a>
+                        <a href="#sp-back" data-toggle="modal" data-target="#sp-back" class="btn btn-warning btn-sm mr-1">审批退回</a>
                     <% } else {%>
-                        <a href="#sp-list"  data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm pull-right text-dark mr-1 sp-list-btn">审批中</a>
+                        <a href="#sp-list"  data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm text-dark mr-1 sp-list-btn">审批中</a>
                     <% } %>
                 <% } else if (tender.ledger_status === auditConst.status.checked) { %>
-                <a href="#sp-list" data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-success btn-sm pull-right text-dark mr-1 sp-list-btn">审批通过</a>
+                <a href="#sp-list" data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-success btn-sm text-dark mr-1 sp-list-btn">审批通过</a>
                 <% } %>
             </div>
         </div>

+ 6 - 6
app/view/ledger/bwtz.ejs

@@ -10,12 +10,12 @@
                             <i class="fa fa-list-ol"></i> 显示层级
                         </button>
                         <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
-                            <a class="dropdown-item" name="showLevel" tag="1" href="javascirpt: void(0);">第一层</a>
-                            <a class="dropdown-item" name="showLevel" tag="2" href="javascirpt: void(0);">第二层</a>
-                            <a class="dropdown-item" name="showLevel" tag="3" href="javascirpt: void(0);">第三层</a>
-                            <a class="dropdown-item" name="showLevel" tag="4" href="javascirpt: void(0);">第四层</a>
-                            <a class="dropdown-item" name="showLevel" tag="5" href="javascirpt: void(0);">第五层</a>
-                            <a class="dropdown-item" name="showLevel" tag="last" href="javascirpt: void(0);">最底层</a>
+                            <a class="dropdown-item" name="showLevel" tag="1" href="javascript:void(0);">第一层</a>
+                            <a class="dropdown-item" name="showLevel" tag="2" href="javascript:void(0);">第二层</a>
+                            <a class="dropdown-item" name="showLevel" tag="3" href="javascript:void(0);">第三层</a>
+                            <a class="dropdown-item" name="showLevel" tag="4" href="javascript:void(0);">第四层</a>
+                            <a class="dropdown-item" name="showLevel" tag="5" href="javascript:void(0);">第五层</a>
+                            <a class="dropdown-item" name="showLevel" tag="last" href="javascript:void(0);">最底层</a>
                         </div>
                     </div>
                 </div>

+ 12 - 12
app/view/ledger/explode.ejs

@@ -10,13 +10,13 @@
                             <i class="fa fa-list-ol"></i> 显示层级
                         </button>
                         <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
-                            <a class="dropdown-item" name="showLevel" tag="1" href="javascirpt: void(0);">第一层</a>
-                            <a class="dropdown-item" name="showLevel" tag="2" href="javascirpt: void(0);">第二层</a>
-                            <a class="dropdown-item" name="showLevel" tag="3" href="javascirpt: void(0);">第三层</a>
-                            <a class="dropdown-item" name="showLevel" tag="4" href="javascirpt: void(0);">第四层</a>
-                            <a class="dropdown-item" name="showLevel" tag="5" href="javascirpt: void(0);">第五层</a>
-                            <a class="dropdown-item" name="showLevel" tag="last" href="javascirpt: void(0);">最底层</a>
-                            <a class="dropdown-item" name="showLevel" tag="leafXmj" href="javascirpt: void(0);">只显示项目节</a>
+                            <a class="dropdown-item" name="showLevel" tag="1" href="javascript:void(0);">第一层</a>
+                            <a class="dropdown-item" name="showLevel" tag="2" href="javascript:void(0);">第二层</a>
+                            <a class="dropdown-item" name="showLevel" tag="3" href="javascript:void(0);">第三层</a>
+                            <a class="dropdown-item" name="showLevel" tag="4" href="javascript:void(0);">第四层</a>
+                            <a class="dropdown-item" name="showLevel" tag="5" href="javascript:void(0);">第五层</a>
+                            <a class="dropdown-item" name="showLevel" tag="last" href="javascript:void(0);">最底层</a>
+                            <a class="dropdown-item" name="showLevel" tag="leafXmj" href="javascript:void(0);">只显示项目节</a>
                         </div>
                     </div>
                 </div>
@@ -48,17 +48,17 @@
                     <a class="btn btn-sm btn-primary mr-1" href="#ledger-check-modal" data-toggle="modal" data-target="#ledger-check-modal">数据检查</a>
                 <% } %>
                 <% if (tender.ledger_status === auditConst.status.checkNo) { %>
-                    <a href="#sp-list" data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm pull-right text-dark sp-list-btn">审批退回</a>
+                    <a href="#sp-list" data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm text-dark sp-list-btn">审批退回</a>
                 <% } else if (tender.ledger_status === auditConst.status.checking) { %>
-                    <a href="#sp-list" data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm pull-right text-dark sp-list-btn">审批中</a>
+                    <a href="#sp-list" data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm text-dark sp-list-btn">审批中</a>
                 <% } else if (tender.ledger_status === auditConst.status.checked) { %>
-                    <a href="#sp-list" data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm pull-right sp-list-btn">审批完成</a>
+                    <a href="#sp-list" data-type="hide" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm sp-list-btn">审批完成</a>
                 <% } %>
                 <% if (ctx.session.sessionUser.accountId === tender.user_id) { %>
                     <% if (tender.ledger_status === auditConst.status.uncheck) { %>
-                        <a href="#sub-sp" data-toggle="modal" data-target="#sub-sp" class="btn btn-primary btn-sm pull-right">上报审批</a>
+                        <a href="#sub-sp" data-toggle="modal" data-target="#sub-sp" class="btn btn-primary btn-sm">上报审批</a>
                     <% } else if (tender.ledger_status === auditConst.status.checkNo) { %>
-                        <a href="#sp-list" data-type="show" data-toggle="modal" data-target="#sp-list" class="btn btn-primary btn-sm pull-right sp-list-btn" style="margin-right: 5px;">重新上报</a>
+                        <a href="#sp-list" data-type="show" data-toggle="modal" data-target="#sp-list" class="btn btn-primary btn-sm sp-list-btn" style="margin-right: 5px;">重新上报</a>
                     <% } %>
                 <% } %>
             </div>

+ 1 - 0
app/view/ledger/gather.ejs

@@ -68,4 +68,5 @@
 <script>
     const chapter = JSON.parse('<%- JSON.stringify(ctx.tender.info.chapter) %>');
     const thousandth = <%- ctx.tender.info.display.thousandth %>;
+    const filter = JSON.parse('<%- JSON.stringify(chapterFilter) %>');
 </script>

+ 2 - 2
app/view/measure/stage.ejs

@@ -10,9 +10,9 @@
                 <% if (ctx.session.sessionUser.accountId === ctx.tender.data.user_id && ctx.tender.data.ledger_status === auditConst.status.checked &&
                         (stages.length === 0 || stages[0].status === auditConst.status.checked)) { %>
                 <% if (ctx.helper.checkZero(ctx.tender.info.deal_param.contractPrice) && stages.length === 0) { %>
-                    <a href="#add-qi" data-toggle="modal" data-target="#tips" class="btn btn-primary btn-sm pull-right">开始新一期</a>
+                    <a href="#add-qi" data-toggle="modal" data-target="#tips" class="btn btn-primary btn-sm">开始新一期</a>
                 <% } else { %>
-                    <a href="#add-qi" data-toggle="modal" data-target="#add-qi" class="btn btn-primary btn-sm pull-right">开始新一期</a>
+                    <a href="#add-qi" data-toggle="modal" data-target="#add-qi" class="btn btn-primary btn-sm">开始新一期</a>
                 <% } %>
                 <% } %>
             </div>

+ 1 - 0
app/view/revise/gcl_compare.ejs

@@ -76,4 +76,5 @@
 <script>
     const chapter = JSON.parse('<%- JSON.stringify(ctx.tender.info.chapter) %>');
     const thousandth = <%- ctx.tender.info.display.thousandth %>;
+    const filter = JSON.parse('<%- JSON.stringify(chapterFilter) %>');
 </script>

+ 1 - 1
app/view/revise/history.ejs

@@ -26,7 +26,7 @@
                 </div>
             </div>
             <div class="ml-auto">
-                <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm pull-right">审批完成</a>
+                <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm">审批完成</a>
             </div>
         </div>
     </div>

+ 2 - 2
app/view/revise/index.ejs

@@ -13,10 +13,10 @@
                     </div>
                 </div>
             </div>
-            <div>
+            <div class="ml-auto">
                 <% if (addValid) { %>
                 <div class="d-inline-block">
-                    <a href="#add-bg" data-toggle="modal" data-target="#add-bg" class="btn btn-primary btn-sm pull-right">新建修订</a>
+                    <a href="#add-bg" data-toggle="modal" data-target="#add-bg" class="btn btn-primary btn-sm">新建修订</a>
                 </div>
                 <% } %>
             </div>

+ 323 - 0
app/view/schedule/index.ejs

@@ -0,0 +1,323 @@
+<% include ../tender/tender_sub_menu.ejs %>
+<div class="panel-content">
+    <div class="panel-title">
+        <div class="title-main d-flex">
+            <% include ../tender/tender_sub_mini_menu.ejs %>
+            <h2>
+                计划至至 2020年12月
+            </h2>
+            <div class="ml-auto">
+                <a href="/tender/<%- ctx.tender.id %>/schedule/ledger" class="btn btn-sm btn-outline-primary">进度台帐</a>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-body">
+            <div class="sjs-height-0">
+                <div class="m-3">
+                    <!--模式切换-->
+                    <div class="col-12 mb-4">
+                        <ul class="nav nav-tabs justify-content-center">
+                            <li class="nav-item">
+                                <a class="nav-link px-5 py-2 active" href="#">金额模式</a>
+                            </li>
+                            <li class="nav-item">
+                                <a class="nav-link px-5 py-2" href="#">工程量模式</a>
+                            </li>
+                        </ul>
+                    </div>
+                    <!--金额概况-->
+                    <div class="row mx-0 mb-3 justify-content-center">
+                        <div class="col-auto p-0">
+                            <div class="card text-center">
+                                <div class="card-body">
+                                    <h5 class="card-title">163,000.00 <small class="text-danger"  data-toggle="tooltip" data-placement="bottom" title="" data-original-title="占设计比例">20%</small></h5>
+                                    <p class="card-text text-muted">计划完成金额</p>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-auto pr-0">
+                            <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="占计划比例">5%</small></h5>
+                                    <p class="card-text text-muted">已完成计划金额</p>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-auto pr-0">
+                            <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="占设计比例">15%</small></h5>
+                                    <p class="card-text text-muted">实际完成金额</p>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <!--进度条-->
+                    <div class="mb-3">
+                        计划工程量进度
+                        <div class="progress">
+                            <div class="progress-bar bg-info" style="width:24%;" data-placement="bottom" data-toggle="tooltip" data-original-title="计划完成工程量:30,000.00">24%</div>
+                            <div class="progress-bar bg-gray" style="width:76%;" data-placement="bottom" data-toggle="tooltip" data-original-title="合同未计划:930,00.00">66%</div>
+                        </div>
+                        <p class="mt-2 mb-0">实际工程量进度</p>
+                        <div class="progress">
+                            <div class="progress-bar bg-info" style="width: 18%;" data-placement="bottom" data-toggle="tooltip" data-original-title="实际完成工程量:40,000.00">18%</div>
+                            <div class="progress-bar bg-gray" style="width:82%;" data-placement="bottom" data-toggle="tooltip" data-original-title="合同未完成:930,00.00">72%</div>
+                        </div>
+                        <p class="mt-2 mb-0">计划金额进度(万元)</p>
+                        <div class="progress">
+                            <div class="progress-bar bg-success" style="width:24%;" data-placement="bottom" data-toggle="tooltip" data-original-title="计划完成金额:¥300.00">24%</div>
+                            <div class="progress-bar bg-gray" style="width:76%;" data-placement="bottom" data-toggle="tooltip" data-original-title="合同未计划:¥930.00">66%</div>
+                        </div>
+                        <p class="mt-2 mb-0">实际金额进度哦(万元)</p>
+                        <div class="progress">
+                            <div class="progress-bar bg-success" style="width: 18%;" data-placement="bottom" data-toggle="tooltip" data-original-title="实际完成金额:¥400.00">18%</div>
+                            <div class="progress-bar bg-gray" style="width:82%;" data-placement="bottom" data-toggle="tooltip" data-original-title="合同未完成:¥930.00">72%</div>
+                        </div>
+                    </div>
+                    <!--图表-->
+                    <div class="card mb-3">
+                        <div class="card-body">
+                            <h5 class="card-title">工程量进度表</h5>
+                            <div id="chartContainer3" style="height: 300px; width: 100%;">
+                            </div>
+                        </div>
+                    </div>
+                    <div class="card mb-3">
+                        <div class="card-body">
+                            <h5 class="card-title">完成金额进度表</h5>
+                            <div id="chartContainer4" style="height: 300px; width: 100%;">
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="/public/js/echarts/echarts.min.js"></script>
+<script type="text/javascript">
+    //计划进度//
+    // 基于准备好的dom,初始化echarts图表
+    var myChart = echarts.init(document.getElementById('chartContainer3'));
+    var option = {
+        color: ['#d38b70','#8fb7cf','#cd5c5c','#ffa500','#40e0d0',
+            '#17a2b8','#28a745','#e4575a','#959eac','#6699FF',
+            '#1e90ff','#ff6347','#7b68ee','#00fa9a','#ffd700',
+            '#5c616b','#ff6666','#3cb371','#b8860b','#30e0e0'],
+        title : {
+            text: ''
+        },
+        tooltip : {
+            trigger: 'axis'
+        },
+        calculable : true,
+        legend: {
+            data:['计划完成工程量','实际完成工程量','实际占设计比例']
+        },
+        dataZoom: [
+            {show: true,start: 0, end: 100}
+        ],
+        xAxis : [
+            {
+                type : 'category',
+                splitLine : {show : true},
+                data : ['2020年1月','2020年2月','2020年3月','2020年4月','2020年5月','2020年6月','2020年7月']
+            }
+        ],
+        yAxis : [
+            {
+                type : 'value',
+                name : '工程量',
+                position:'left',
+                axisLabel : {
+                    formatter: '{value}'
+                },
+                splitArea : {show : true}
+            },
+            {
+                type : 'value',
+                name:'完成度',
+                axisLabel : {
+                    formatter: '{value} %'
+                },
+                position: 'right',
+                splitArea : {show : true}
+            }
+        ],
+        series : [
+            {
+                name:'计划完成工程量',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}<br/>{a}:{c}"},
+                stack: '计划',
+                data:[320, 332, 301, 334, 390, 330, 320]
+            },
+            {
+                name:'实际完成工程量',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}<br/>{a}:{c}"},
+                stack: '实际',
+                data:[310, 330, 301, 334, 390, 330, 320]
+            },
+            {
+                name:'实际占设计比例',
+                type:'line',
+                tooltip : {trigger: 'axis',formatter: "{b}占合同比例<br/>{a}:{c} %"},
+                yAxisIndex: 1,
+                data:[10, 15, 20, 13, 11, 9, 5]
+            },
+        ]
+    };
+    // 为echarts对象加载数据
+    myChart.setOption(option);
+    //4 完成金额进度进度//
+    var myChart = echarts.init(document.getElementById('chartContainer4'));
+    var option = {
+        color: ['#e9af68','#57b7b6','#e4575a','#959eac','#6699FF',
+            '#d38b70','#8fb7cf','#cd5c5c','#ffa500','#40e0d0',
+            '#1e90ff','#ff6347','#7b68ee','#00fa9a','#ffd700',
+            '#5c616b','#ff6666','#3cb371','#b8860b','#30e0e0'],
+        title : {
+            text: ''
+        },
+        tooltip : {
+            trigger: 'axis'
+        },
+        calculable : true,
+        legend: {
+            data:['计划完成金额','实际完成金额','实际占设计比例']
+        },
+        dataZoom: [
+            {show: true,start: 0, end: 100}
+        ],
+        xAxis : [
+            {
+                type : 'category',
+                splitLine : {show : true},
+                data : ['2020年1月','2020年2月','2020年3月','2020年4月','2020年5月','2020年6月','2020年7月']
+            }
+        ],
+        yAxis : [
+            {
+                type : 'value',
+                name : '金额',
+                position:'left',
+                axisLabel : {
+                    formatter: '{value} 万元'
+                },
+                splitArea : {show : true}
+            },
+            {
+                type : 'value',
+                name:'完成度',
+                axisLabel : {
+                    formatter: '{value} %'
+                },
+                position: 'right',
+                splitArea : {show : true}
+            }
+        ],
+        series : [
+            {
+                name:'计划完成金额',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}<br/>{a}:{c}万元"},
+                stack: '计划',
+                data:[320, 332, 301, 334, 390, 330, 320]
+            },
+            {
+                name:'实际完成金额',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}<br/>{a}:{c}万元"},
+                stack: '实际',
+                data:[310, 330, 301, 334, 390, 330, 320]
+            },
+            {
+                name:'实际占合同比例',
+                type:'line',
+                tooltip : {trigger: 'axis',formatter: "{b}占合同比例<br/>{a}:{c} %"},
+                yAxisIndex: 1,
+                data:[10, 15, 20, 13, 11, 9, 5]
+            },
+        ]
+    };
+
+    // 为echarts对象加载数据
+    myChart.setOption(option);
+</script>
+<!--sjs-->
+<script>
+    $(document).ready(function () {
+        const data = [
+            {
+                单位:'稍等',
+                精度:3,
+            },{
+                单位:'km',
+                精度:3,
+            },{
+                单位:'m',
+                精度:3,
+            },{
+                单位:'m2',
+                精度:3,
+            },{
+                单位:'m3',
+                精度:3,
+            },{
+                单位:'kg',
+                精度:3,
+            },{
+                单位:'个',
+                精度:3,
+            },{
+                单位:'台',
+                精度:3,
+            },{
+                单位:'套',
+                精度:3,
+            },{
+                单位:'棵',
+                精度:3,
+            },{
+                单位:'组',
+                精度:3,
+            },{
+                单位:'总额',
+                精度:3,
+            },{
+                单位:'系统',
+                精度:3,
+            },{
+                单位:'其他未列单位',
+                精度:3,
+            }
+        ];
+        const spread = new GC.Spread.Sheets.Workbook($('#option-spread1')[0], {
+            sheetCount: 1
+        });
+        spread.getActiveSheet().setDataSource(data);
+        spread.options.tabStripVisible = false;
+    })
+</script>
+<script src="/public/js/sub_menu.js"></script>
+<script>
+    $.subMenu({
+        menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
+        toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
+        key: 'menu.1.0.0',
+        miniHint: '#sub-mini-hint', hintKey: 'menu.hint.1.0.1',
+        callback: function (info) {
+            if (info.mini) {
+                $('.panel-title').addClass('fluid');
+                $('#sub-menu').removeClass('panel-sidebar');
+            } else {
+                $('.panel-title').removeClass('fluid');
+                $('#sub-menu').addClass('panel-sidebar');
+            }
+            autoFlashHeight();
+        }
+    });
+</script>

+ 63 - 0
app/view/schedule/ledger.ejs

@@ -0,0 +1,63 @@
+<% include ../tender/tender_sub_menu.ejs %>
+<div class="panel-content">
+    <div class="panel-title">
+        <div class="title-main d-flex">
+            <% include ../tender/tender_sub_mini_menu.ejs %>
+            <div>
+                <div class="d-inline-block">
+                    <a class="btn btn-sm btn-light">
+                        <div class="custom-control custom-checkbox">
+                            <input type="checkbox" class="custom-control-input" id="customCheckDisabled" checked="">
+                            <label class="custom-control-label text-primary" for="customCheckDisabled">自动选择同级项</label>
+                        </div>
+                    </a>
+                </div>
+                <div class="d-inline-block">
+                    <a class="btn btn-sm btn-light">
+                        <div class="custom-control custom-checkbox">
+                            <input type="checkbox" class="custom-control-input" id="customCheckDisabled2">
+                            <label class="custom-control-label text-primary" for="customCheckDisabled2">跨级选择同级项</label>
+                        </div>
+                    </a>
+                </div>
+            </div>
+            <div class="ml-auto">
+                <a href="#add-qi" data-toggle="modal" data-target="#add-qi" class="btn btn-primary btn-sm pull-right">确认提交<div></div></a>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-header p-0"></div>
+        <div class="w-100 sub-content row">
+            <div class="c-body col-12">
+                <div class="sjs-height-0" style="overflow: auto;" id="ledger-spread">
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="/public/js/sub_menu.js"></script>
+<script>
+    const tender = JSON.parse('<%- JSON.stringify(tender) %>');
+    const tenderInfo = JSON.parse(unescape('<%- escape(JSON.stringify(tenderInfo)) %>'));
+    const thousandth = <%- ctx.tender.info.display.thousandth %>;
+    const measureType = JSON.parse('<%- JSON.stringify(measureType) %>');
+</script>
+<script>
+    $.subMenu({
+        menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
+        toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
+        key: 'menu.1.0.0',
+        miniHint: '#sub-mini-hint', hintKey: 'menu.hint.1.0.1',
+        callback: function (info) {
+            if (info.mini) {
+                $('.panel-title').addClass('fluid');
+                $('#sub-menu').removeClass('panel-sidebar');
+            } else {
+                $('.panel-title').removeClass('fluid');
+                $('#sub-menu').addClass('panel-sidebar');
+            }
+            autoFlashHeight();
+        }
+    });
+</script>

+ 21 - 0
app/view/schedule/ledger_modal.ejs

@@ -0,0 +1,21 @@
+<!--首次使用提示-->
+<div class="modal fade" id="first" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">进度台帐</h5>
+            </div>
+            <div class="modal-body">
+                <h5>首次使用形象进度需要进行进度台帐初始化设置</h5>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-primary" data-dismiss="modal">开始设置</button>
+            </div>
+        </div>
+    </div>
+</div>
+<script type="text/javascript">
+    $(function () {
+        // $('#first').modal('show');
+    })
+</script>

+ 1 - 1
app/view/setting/category_modal.ejs

@@ -58,7 +58,7 @@
             <div class="modal-body">
                 <table class="table table-bordered">
                     <thead>
-                    <tr><th>值</th><th>包含标段</th><th>删除</th></tr>
+                    <tr><th width="40">排序</th><th>值</th><th>包含标段</th><th>删除</th></tr>
                     </thead>
                     <tbody id="value-list">
                     </tbody>

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

@@ -103,4 +103,5 @@
     }
     const chapter = JSON.parse('<%- JSON.stringify(ctx.tender.info.chapter) %>');
     const thousandth = <%- ctx.tender.info.display.thousandth %>;
+    const filter = JSON.parse('<%- JSON.stringify(chapterFilter) %>');
 </script>

+ 10 - 2
app/view/stage/index.ejs

@@ -36,6 +36,14 @@
                     <a id="exportExcel" class="btn btn-primary btn-sm" href="javascript: void(0)">导出计量台账Excel</a>
                     <a class="btn btn-sm btn-primary" href="#ledger-check-modal" data-toggle="modal" data-target="#ledger-check-modal">数据检查</a>
                 </div>
+                <div class="d-inline-block ml-1">
+                    <a class="btn btn-sm btn-light">
+                        <div class="custom-control custom-checkbox">
+                            <input type="checkbox" class="custom-control-input" id="correct_percent">
+                            <label class="custom-control-label text-primary" for="correct_percent">使用数量矫正完成率</label>
+                        </div>
+                    </a>
+                </div>
             </div>
             <div class="ml-auto">
             </div>
@@ -528,7 +536,7 @@
                         <div class="sjs-bar">
                             <button class="btn btn-sm btn-outline-primary pull-right" href="javascript: void(0);" id="refresh-cc" hint="如果有新审批通过的变更令,请点击刷新">重新获取变更令</button>
                         </div>
-                        <div class="sjs-height-5" id="cc-spread" style="overflow:hidden">
+                        <div class="sjs-sh" id="cc-spread" style="overflow:hidden">
                         </div>
                         <div class="resize-y" id="change-spr" r-Type="height" div1="#cc-spread" div2=".sjs-bottom" title="调整大小"><!--调整上下高度条--></div>
                         <div class="sjs-bottom" id="ccb-spread">
@@ -545,7 +553,7 @@
             <!--右侧菜单-->
             <ul class="nav flex-column right-nav">
                 <li class="nav-item">
-                    <a class="nav-link" content="#zhongjian" href="javascript: void(0);">中间计量</a>
+                    <a class="nav-link" content="#zhongjian" id="zhongjiantab" href="javascript: void(0);">中间计量</a>
                 </li>
                 <li class="nav-item">
                     <a class="nav-link" content="#search" href="javascript: void(0);">查找定位</a>

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

@@ -438,7 +438,7 @@
                 </div>
                 <div class="modal-height-300">
                     <table class="table table-bordered">
-                        <thead><tr><th>序号</th><th>计量单元</th><th>台数量</th><th><input id="cbr-check-all" type="checkbox"></th></tr></thead>
+                        <thead><tr><th>序号</th><th>计量单元</th><th>台数量</th><th><input id="cbr-check-all" type="checkbox"></th></tr></thead>
                         <tbody id="cbr-pos-list"></tbody>
                     </table>
                 </div>

+ 2 - 2
app/view/sum/index.ejs

@@ -4,8 +4,8 @@
             <div>
                 计量台账
             </div>
-            <div>
-                <a href="#add-qi" data-toggle="modal" data-target="#add-qi" class="btn btn-primary btn-sm pull-right">开始新一期</a>
+            <div class="ml-auto">
+                <a href="#add-qi" data-toggle="modal" data-target="#add-qi" class="btn btn-primary btn-sm">开始新一期</a>
             </div>
         </div>
     </div>

+ 3 - 2
app/view/tender/shenpi.ejs

@@ -102,9 +102,9 @@
                                                         <button class="btn btn-outline-primary btn-sm dropdown-toggle" type="button" id="<%- sp.code %>_dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                                             选择审批人
                                                         </button>
-                                                        <div class="dropdown-menu dropdown-menu-right" aria-labelledby="<%- sp.code %>_dropdownMenuButton" style="width:220px">
+                                                        <div class="dropdown-menu dropdown-menu-right" id="<%- sp.code %>_dropdownMenu" aria-labelledby="<%- sp.code %>_dropdownMenuButton" style="width:220px">
                                                             <div class="mb-2 p-2"><input class="form-control form-control-sm gr-search"
-                                                                                         placeholder="姓名/手机 检索" autocomplete="off"></div>
+                                                                                         placeholder="姓名/手机 检索" autocomplete="off" data-code="<%- sp.code %>"></div>
                                                             <dl class="list-unstyled book-list">
                                                                 <% accountGroup.forEach((group, idx) => { %>
                                                                 <dt><a href="javascript: void(0);" class="acc-btn" data-groupid="<%- idx %>" data-type="hide"><i class="fa fa-plus-square"></i></a> <%- group.groupName %></dt>
@@ -153,6 +153,7 @@
     const category = JSON.parse('<%- JSON.stringify(categoryData) %>');
 </script>
 <script src="/public/js/shenpi.js"></script>
+<script src="/public/js/tender_showhide.js"></script>
 <script>
     $.subMenu({
         menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',

+ 2 - 2
app/view/tender/shenpi_modal.ejs

@@ -42,12 +42,12 @@
                             <td></td>
                         </tr>
                         <tr>
-                            <td>台审批</td>
+                            <td>台审批</td>
                             <td>固定流程<i class="fa fa-question-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" data-original-title="王五-张三-李四"></i></td>
                             <td><input type="checkbox"></td>
                         </tr>
                         <tr>
-                            <td>台修订</td>
+                            <td>台修订</td>
                             <td>固定流程<i class="fa fa-question-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" data-original-title="王五-张三-李四"></i></td>
                             <td><input type="checkbox"></td>
                         </tr>

+ 18 - 0
config/web.js

@@ -656,6 +656,24 @@ const JsFiles = {
                 mergeFile: 'advance_audit',
             },
         },
+        schedule: {
+            ledger: {
+                files: [
+                    '/public/js/spreadjs/sheets/v11/gc.spread.sheets.all.11.2.2.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/shares/sjs_setting.js',
+                    '/public/js/zh_calc.js',
+                    '/public/js/path_tree.js',
+                    '/public/js/schedule_ledger.js',
+                ],
+                mergeFile: 'ledger',
+            },
+        },
     },
 };
 

+ 1 - 0
package.json

@@ -42,6 +42,7 @@
         "ueditor": "^1.2.3",
         "uglify-es": "^3.3.9",
         "uglify-js": "^3.3.27",
+        "uuid": "^3.2.1",
         "xmlreader": "^0.2.3",
         "zlib": "^1.0.5"
     },

+ 3 - 0
sql/update.sql

@@ -24,3 +24,6 @@ CREATE TABLE `zh_shenpi_audit` (
   `audit_id` int(11) NOT NULL COMMENT '审批人id',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='审批流程人设置表';
+
+-- 2020/11/4 更新到uat
+-- 2020/11/5 更新到prod