Browse Source

1. 本期计量台账,新增查找定位相关
2. 清单汇总,汇总签约清单数据
3. 合同支付,404问题

MaiXinRong 6 years ago
parent
commit
e93006a95d

+ 2 - 0
app/const/spread.js

@@ -276,6 +276,8 @@ const stageGather = {
             {title: '单价', colSpan: '1', rowSpan: '2', field: 'unit_price', hAlign: 2, width: 60, type: 'Number'},
             {title: '签约|数量', colSpan: '2|1', rowSpan: '1|1', field: 'deal_qty', hAlign: 2, width: 60, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'deal_tp', hAlign: 2, width: 60, type: 'Number'},
+            {title: '签约合同|数量', colSpan: '2|1', rowSpan: '1|1', field: 'deal_bills_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'deal_bills_tp', hAlign: 2, width: 60, type: 'Number'},
             {title: '施工图复核|数量', colSpan: '2|1', rowSpan: '1|1', field: 'quantity', hAlign: 2, width: 60, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, type: 'Number'},
             {title: '本期合同计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},

+ 1 - 0
app/controller/stage_controller.js

@@ -838,6 +838,7 @@ module.exports = app => {
                 renderData.curPosData = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id,
                     ctx.stage.id, ctx.stage.times, ctx.stage.curAuditor ? ctx.stage.curAuditor.order : 0);
                 //renderData.gcl = await this.ctx.service.ledger.getAllLeafGclBills(this.ctx.tender.id);
+                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);
                 await this.layout('stage/gather.ejs', renderData);

+ 21 - 1
app/public/js/gcl_gather.js

@@ -49,9 +49,12 @@ const gclGatherModel = (function () {
         pos.gather_qty = ZhCalc.plus(pos.contract_qty, pos.qc_qty);
     };
     const gsPos = new StagePosData(posSetting);
+    let deal = [];
 
     const gclList = [], leafXmjs = [];
 
+
+
     /**
      * 将所有数据加载至树结构
      *
@@ -79,6 +82,10 @@ const gclGatherModel = (function () {
         gsPos.loadPreStageData(prePos);
     }
 
+    function loadDealBillsData(dealBills) {
+        deal = dealBills;
+    }
+
     function gatherfields(obj, src, fields) {
         if (obj && src) {
             for (const f of fields) {
@@ -310,15 +317,27 @@ const gclGatherModel = (function () {
         }
     }
 
+    function gatherDealBillsData() {
+        if (deal && deal.length > 0) {
+            for (const node of deal) {
+                node.b_code = node.code;
+                const gcl = getGclNode(node);
+                gcl.deal_bills_qty = node.quantity;
+                gcl.deal_bills_tp = node.total_price;
+            }
+        }
+    }
+
     /**
      * 根据树结构 清单汇总
      */
     function gatherGclData() {
         // 清空旧数据
         if (gclList.length > 0) {
-            gclList.splice(0, gclList.length - 1);
+            gclList.length = 0; //splice(0, gclList.length);
         }
         recursiveGatherGclData(gsTree.children, null);
+        gatherDealBillsData();
         gclList.sort(function (a, b) {
             function compareCode(code1, code2) {
                 if (numReg.test(code1)) {
@@ -350,6 +369,7 @@ const gclGatherModel = (function () {
     return {
         loadLedgerData,
         loadPosData,
+        loadDealBillsData,
         gatherGclData,
     };
 })();

+ 139 - 14
app/public/js/stage.js

@@ -861,23 +861,148 @@ $(document).ready(() => {
         Cookies.set('stage-col-visible', JSON.stringify(customDisplay), 7*24*60*60*1000);
         $('#row-view').modal('hide');
     });
-    // 展开收起附件
-    $('#fujianTab').click(function () {
-        const obj = $(this), main = $('#main-view'), tool = $('#tools-view'), fujian = $('#fujian');
-        if (obj.hasClass('active')) {
-            main.attr('class', 'c-body col-12');
-            tool.hide();
+
+    class SearchLedger {
+        constructor(obj, mainSpread) {
+            const self = this;
+            this.obj = obj;
+            this.mainSpread = mainSpread;
+            this.spreadSetting = {
+                cols: [
+                    {title: '项目节编号', field: 'code', hAlign: 0, width: 120, formatter: '@'},
+                    {title: '清单编号', field: 'b_code', hAlign: 0, width: 80, formatter: '@'},
+                    {title: '名称', field: 'name', width: 230, hAlign: 0, formatter: '@'},
+                    {title: '单位', field: 'unit', width: 50, hAlign: 1, formatter: '@'},
+                    {title: '单价', field: 'unit_price', hAlign: 2, width: 50},
+                    {title: '数量', field: 'quantity', hAlign: 2, width: 50},
+                    {title: '完成率(%)', field: 'complete_percent', hAlign: 2, width: 70},
+                ],
+                emptyRows: 3,
+                headRows: 1,
+                headRowHeight: [40],
+                defaultRowHeight: 21,
+                readOnly: true
+            };
+            this.spread = SpreadJsObj.createNewSpread($('#search-result', this.obj)[0]);
+            SpreadJsObj.initSheet(this.spread.getActiveSheet(), this.spreadSetting);
+
+            $('#searchLedger', this.obj).bind('click', function () {
+                const keyword = $('#keyword', self.obj).val();
+                if (keyword !== '') {
+                    $('#over', obj)[0].checked = false;
+                    $('#empty', obj)[0].checked = false;
+                    this.searchResult = [];
+                    const sortData = SpreadJsObj.getSortData(self.mainSpread.getActiveSheet());
+                    for (const node of sortData) {
+                        if ((node.code && node.code.indexOf(keyword) > -1) ||
+                            node.b_code && node.b_code.indexOf(keyword) > -1 ||
+                            node.name && node.name.indexOf(keyword) > -1) {
+                            this.searchResult.push(node);
+                        }
+                    }
+                    SpreadJsObj.loadSheetData(self.spread.getActiveSheet(), 'data', this.searchResult);
+                }
+            });
+            $('#over', this.obj).bind('change', function () {
+                this.searchResult = [];
+                const sortData = SpreadJsObj.getSortData(self.mainSpread.getActiveSheet());
+                for (const node of sortData) {
+                    if (node.children && node.children.length > 0) continue;
+                    if (node.end_gather_qty) {
+                        if (!node.quantity || Math.abs(node.end_gather_qty) > Math.abs(node.quantity)) {
+                            this.searchResult.push(node);
+                        }
+                    } else if (node.end_gather_tp) {
+                        if (!node.total_price || Math.abs(node.end_gather_tp) > Math.abs(node.total_price)) {
+                            this.searchResult.push(node);
+                        }
+                    }
+                }
+                SpreadJsObj.loadSheetData(self.spread.getActiveSheet(), 'data', this.searchResult);
+            });
+            $('#empty', this.obj).bind('change', function () {
+                this.searchResult = [];
+                const sortData = SpreadJsObj.getSortData(self.mainSpread.getActiveSheet());
+                for (const node of sortData) {
+                    if (node.children && node.children.length > 0) continue;
+                    if (node.quantity) {
+                        if (!node.end_gather_qty || checkZero(node.end_gather_qty)) {
+                            this.searchResult.push(node);
+                        }
+                    } else if (node.total_price) {
+                        if (!node.end_gather_tp || checkZero(node.end_gather_tp)) {
+                            this.searchResult.push(node);
+                        }
+                    }
+                }
+                SpreadJsObj.loadSheetData(self.spread.getActiveSheet(), 'data', this.searchResult);
+            });
+            this.spread.getActiveSheet().bind(GC.Spread.Sheets.Events.CellDoubleClick, function (e, info) {
+                const sheet = info.sheet;
+                const data = sheet.zh_data;
+                if (!data) { return }
+
+                const curBills = data[info.row];
+                if (!curBills) { return }
+
+                SpreadJsObj.locateTreeNode(self.mainSpread.getActiveSheet(), curBills.ledger_id);
+            });
+        }
+    }
+    let searchLedger;
+    $.divResizer({
+        select: '#right-spr',
+        callback: function () {
             slSpread.refresh();
             spSpread.refresh();
-            obj.removeClass('active');
-            fujian.removeClass('active');
+            if (searchLedger) {
+                searchLedger.spread.refresh();
+            }
+        }
+    });
+    // 展开收起附件
+    $('a', '.side-menu').bind('click', function () {
+        //const main = $('#main-view'), tool = $('#tools-view');
+        const tab = $(this), tabPanel = $(tab.attr('content'));
+        const showTools = function (show) {
+            const left = $('#main-view'), right = $('#tools-view'), parent = left.parent();
+            if (show) {
+                right.show();
+                autoFlashHeight();
+                /**
+                 * right.show()后, parent被撑开成2倍left.height, 导致parent.width减少了10px
+                 * 第一次left.width调整后,parent的缩回left.height, 此时parent.width又增加了10px
+                 * 故需要通过最终的parent.width再计算一次left.width
+                 *
+                 * Q: 为什么不通过先计算left.width的宽度,以避免计算两次left.width?
+                 * A: 右侧工具栏不一定显示,当右侧工具栏显示过一次后,就必须使用parent和right来计算left.width
+                 *
+                 */
+                    //left.css('width', parent.width() - right.outerWidth());
+                    //left.css('width', parent.width() - right.outerWidth());
+                const percent = 100 - right.outerWidth() /parent.width() * 100;
+                left.css('width', percent + '%');
+            } else {
+                right.hide();
+                left.css('width', '100%');
+            }
+        };
+        if (!tab.hasClass('active')) {
+            $('a', '.side-menu').removeClass('active');
+            $('.tab-content .tab-pane').removeClass('active');
+            tab.addClass('active');
+            tabPanel.addClass('active');
+            showTools(tab.hasClass('active'));
+            if (tab.attr('content') === '#search' && !searchLedger) {
+                searchLedger = new SearchLedger($('#search'), slSpread);
+                searchLedger.spread.refresh();
+            }
         } else {
-            main.attr('class', 'c-body col-8');
-            tool.show();
-            slSpread.refresh();
-            spSpread.refresh();
-            obj.addClass('active');
-            fujian.addClass('active');
+            tab.removeClass('active');
+            tabPanel.removeClass('active');
+            showTools(tab.hasClass('active'));
         }
+        slSpread.refresh();
+        spSpread.refresh();
     });
 });

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

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

+ 2 - 0
app/service/stage_pay.js

@@ -100,7 +100,9 @@ module.exports = app => {
                 const prePays = await this.getStageLastestPays(preStage.id);
                 for (const pp of prePays) {
                     const sp = this._.find(stagePays, {pid: pp.pid});
+                    sp.expr = pp.expr;
                     sp.pre_tp= pp.end_tp;
+                    sp.pause = pp.pause;
                 }
             }
             let result;

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

@@ -77,4 +77,5 @@
     const curLedgerData = JSON.parse('<%- JSON.stringify(curLedgerData) %>');
     const pos = JSON.parse('<%- JSON.stringify(pos) %>');
     const curPosData = JSON.parse('<%- JSON.stringify(curPosData) %>');
+    const dealBills = JSON.parse('<%- JSON.stringify(dealBills) %>');
 </script>

+ 28 - 3
app/view/stage/index.ejs

@@ -20,7 +20,7 @@
         <div class="c-header p-0">
         </div>
         <div class="row w-100 sub-content">
-            <div id="main-view" class="c-body col-12">
+            <div id="main-view" class="c-body" style="width: 100%">
                 <!--上部分-->
                 <div class="sjs-height-1" id="stage-ledger">
                 </div>
@@ -52,8 +52,30 @@
                     </div>
                 </div>
             </div>
-            <div id="tools-view" class="c-body col" style="display: none;">
+            <div id="tools-view" class="c-body" style="display: none; width: 33%;">
+                <div class="resize-x" id="right-spr" r-Type="width" div1="#main-view" div2="#tools-view" title="调整大小" a-type="percent"><!--调整左右高度条--></div>
                 <div class="tab-content">
+                    <!--查找定位-->
+                    <div id="search" class="tab-pane">
+                        <div class="sjs-bar-1">
+                            <div class="input-group input-group-sm">
+                                <div class="input-group-prepend">
+                                    <div class="input-group-text">
+                                        <input type="radio" name="searchType" id="over"> 超计
+                                    </div>
+                                    <div class="input-group-text">
+                                        <input type="radio" name="searchType" id="empty"> 漏计
+                                    </div>
+                                </div>
+                                <input type="text" class="form-control" placeholder="可查找 项目节编号 / 清单编号 /名称" id="keyword">
+                                <div class="input-group-append">
+                                    <button class="btn btn-outline-secondary" type="button" id="searchLedger">搜索</button>
+                                </div>
+                            </div>
+                        </div>
+                        <div id="search-result" class="sjs-sh-1">
+                        </div>
+                    </div>
                     <!--附件-->
                     <div id="fujian" class="tab-pane">
                         <div class="sjs-bar">
@@ -239,7 +261,10 @@
             <!--右侧菜单-->
             <ul class="nav flex-column right-nav">
                 <li class="nav-item">
-                    <a id="fujianTab" class="nav-link" content="#fujian" role="tab">附件</a>
+                    <a class="nav-link" content="#search" href="javascript: void(0);">查找定位</a>
+                </li>
+                <li class="nav-item">
+                    <a class="nav-link" content="#fujian" href="javascript: void(0);">附件</a>
                 </li>
             </ul>
         </div>

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

@@ -8,7 +8,7 @@
                     <a href="javascript: void(0);" id="del" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
                     <a href="javascript: void(0);" id="down-move" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
                     <a href="javascript: void(0);" id="up-move" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
-                    <% if (ctx.session.sessionUser.accountId === ctx.stage.user_id && !readOnly) { %>
+                    <% if (ctx.session.sessionUser.accountId === ctx.stage.user_id && !stage.readOnly) { %>
                     <a href="javascript: void(0);" id="unlock" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="解锁"><i class="fa fa-unlock" aria-hidden="true"></i> 解锁</a>
                     <% } %>
                 </div>