瀏覽代碼

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

MaiXinRong 4 年之前
父節點
當前提交
45c226200b

+ 30 - 0
app/controller/signature_controller.js

@@ -55,6 +55,36 @@ module.exports = app => {
         }
 
         /**
+         * 获取多个标段签名角色关联
+         *
+         * @param {Object} ctx - egg全局context
+         * @return {void}
+         */
+        async getMultiRoleRptRels(ctx) {
+            const params = JSON.parse(ctx.request.body.params);
+            const conParams = params.selectedTenders;
+            const rst = await ctx.service.roleRptRel.getCrossTenderRoleRptRels(conParams);
+            ctx.body = { data: rst };
+            ctx.status = 201;
+        }
+
+        /**
+         * 跨标段更新签名角色关联
+         *
+         * @param {Object} ctx - egg全局context
+         * @return {void}
+         */
+        async updateCrossTendersRoleRelationship(ctx) {
+            const params = JSON.parse(ctx.request.body.params);
+            const conParams = params.selectedTenders;
+            const roleRel = params.originalRoleRelList;
+            // updateMultiRoleRelationship
+            const rst = await ctx.service.roleRptRel.updateMultiRoleRelationship(conParams, roleRel);
+            ctx.body = { data: rst };
+            ctx.status = 201;
+        }
+
+        /**
          * 更新最近使用签名
          *
          * @param {Object} ctx - egg全局context

+ 22 - 0
app/public/js/change_information.js

@@ -216,6 +216,28 @@ $(document).ready(() => {
             $('#syfujian .check-all-file').prop('checked', false)
         }
     });
+
+    // 项目节信息获取
+    const xmjSpreadSetting = {
+        cols: [
+            {title: '项目节编号', colSpan: '1', rowSpan: '2', field: 'xmj_code', hAlign: 0, width: 80},
+            {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 120},
+            {title: '细目', colSpan: '1', rowSpan: '2', field: 'xmj_jldy', hAlign: 0, width: 100},
+            {title: '单位工程', colSpan: '1', rowSpan: '2', field: 'xmj_dwgc', hAlign: 0, width: 100},
+            {title: '分部工程', colSpan: '1', rowSpan: '2', field: 'xmj_fbgc', hAlign: 0, width: 100},
+            {title: '分项工程', colSpan: '1', rowSpan: '2', field: 'xmj_fxgc', hAlign: 0, width: 100},
+            {title: '计量单元', colSpan: '1', rowSpan: '2', field: 'bwmx', hAlign: 0, width: 100},
+            {title: '数量', colSpan: '1', rowSpan: '2', field: 'oamount', hAlign: 2, width: 80},
+        ],
+        emptyRows: 0,
+        headRows: 1,
+        headRowHeight: [25, 25],
+        defaultRowHeight: 21,
+        headerFont: '12px 微软雅黑',
+        font: '12px 微软雅黑',
+        readOnly: true,
+    };
+    SpreadJsObj.initSheet(xmjSpread.getActiveSheet(), xmjSpreadSetting);
 });
 function findDecimal(unit) {
     let value = precision.other.value;

+ 17 - 0
app/public/js/change_information_approval.js

@@ -105,6 +105,20 @@ $(document).ready(() => {
                 }
             }
         },
+        resetXmjSpread: function(data = null) {
+            const xmj = [];
+            if (data && data.lid != 0 && data.xmj_code !== '' && data.xmj_code !== null) {
+                if (data.bwmx === data.xmj_jldy) {
+                    data.bwmx = '';
+                }
+                xmj.push(data);
+            }
+            SpreadJsObj.loadSheetData(xmjSpread.getActiveSheet(), SpreadJsObj.DataType.Data, xmj);
+        },
+        selectionChanged: function (e, info) {
+            const data = SpreadJsObj.getSelectObject(info.sheet);
+            changeSpreadObj.resetXmjSpread(data);
+        },
         setRowValueAndSum: function (data, row, col) {
             for (const j in aidList) {
                 const sum = ZhCalc.round(ZhCalc.mul(data.unit_price, parseFloat(changeSpreadSheet.getValue(row, 10 + parseInt(j)*2))), totalPriceUnit);
@@ -266,6 +280,7 @@ $(document).ready(() => {
                 SpreadJsObj.loadSheetData(changeSpreadSheet, SpreadJsObj.DataType.Data, changeList);
                 changeSpreadObj.setAuditValue();
                 changeSpreadObj.makeSjsFooter();
+                changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
             }, function () {
                 SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
                 changeSpreadObj.setAuditValue();
@@ -279,10 +294,12 @@ $(document).ready(() => {
     SpreadJsObj.loadSheetData(changeSpreadSheet, SpreadJsObj.DataType.Data, changeList);
     changeSpreadObj.setAuditValue();
     changeSpreadObj.makeSjsFooter();
+    changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
     const userIndex = aidList.indexOf(parseInt(accountId));
 
     changeSpread.bind(spreadNS.Events.EditEnded, changeSpreadObj.editEnded);
     changeSpread.bind(spreadNS.Events.ClipboardPasted, changeSpreadObj.clipboardPasted);
+    changeSpread.bind(spreadNS.Events.SelectionChanged, changeSpreadObj.selectionChanged);
     SpreadJsObj.addDeleteBind(changeSpread, changeSpreadObj.deletePress);
 
 

+ 18 - 0
app/public/js/change_information_set.js

@@ -152,6 +152,7 @@ $(document).ready(() => {
                     SpreadJsObj.reLoadRowData(changeSpreadSheet, changeList.length - 1);
                     changeSpreadSheet.setStyle(changeSpreadSheet.getRowCount() - 1, -1, style1);
                     changeSpreadSheet.setSelection(changeList.length - 1, 0, 1, 1);
+                    changeSpreadObj.resetXmjSpread();
                 }
             });
         },
@@ -164,6 +165,7 @@ $(document).ready(() => {
                     changeSpreadSheet.deleteRows(index, 1);
                     const sel = changeSpreadSheet.getSelections();
                     changeSpreadSheet.setSelection(0, 0, 1, 1);
+                    changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
                     if (select.lid != 0) {
                         tableDataRemake(changeListData);
                     }
@@ -171,6 +173,16 @@ $(document).ready(() => {
                 });
             }
         },
+        resetXmjSpread: function(data = null) {
+            const xmj = [];
+            if (data && data.lid != 0 && data.xmj_code !== '' && data.xmj_code !== null) {
+                if (data.bwmx === data.xmj_jldy) {
+                    data.bwmx = '';
+                }
+                xmj.push(data);
+            }
+            SpreadJsObj.loadSheetData(xmjSpread.getActiveSheet(), SpreadJsObj.DataType.Data, xmj);
+        },
         selectionChanged: function (e, info) {
             const sel = info.sheet.getSelections()[0];
             const col = info.sheet.zh_setting.cols[sel.col];
@@ -178,6 +190,7 @@ $(document).ready(() => {
             if (col && col.field === 'del_list') {
                 changeSpreadObj.del();
             }
+            changeSpreadObj.resetXmjSpread(data);
         },
         deletePress: function (sheet) {
             return;
@@ -320,6 +333,7 @@ $(document).ready(() => {
                 changeList = result;
                 SpreadJsObj.loadSheetData(changeSpreadSheet, SpreadJsObj.DataType.Data, changeList);
                 changeSpreadObj.makeSjsFooter();
+                changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
             }, function () {
                 SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
                 return;
@@ -385,6 +399,7 @@ $(document).ready(() => {
         SpreadJsObj.initSheet(changeSpreadSheet, changeSpreadSetting);
         SpreadJsObj.loadSheetData(changeSpreadSheet, SpreadJsObj.DataType.Data, changeList);
         changeSpreadObj.makeSjsFooter();
+        changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
     });
 
     if (!readOnly) {
@@ -426,6 +441,7 @@ $(document).ready(() => {
                     disabled: function (key, opt) {
                         const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
                         const sel = changeSpreadSheet.getSelections()[0];
+                        changeSpreadObj.resetXmjSpread(select);
                         console.log(select, sel);
                         if (!readOnly && select && sel.row !== changeSpreadSheet.getRowCount() - 1) {
                             return false;
@@ -549,6 +565,8 @@ $(document).ready(() => {
             changeList = result;
             SpreadJsObj.loadSheetData(changeSpreadSheet, SpreadJsObj.DataType.Data, changeList);
             changeSpreadObj.makeSjsFooter();
+            const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
+            changeSpreadObj.resetXmjSpread(select);
             $('#addlist').modal('hide');
         }, function () {
             $('#addlist').modal('hide');

+ 16 - 0
app/public/js/change_information_show.js

@@ -97,6 +97,20 @@ $(document).ready(() => {
             changeSpreadSheet.setStyle(changeSpreadSheet.getRowCount() - 1, -1, style1);
             changeSpreadObj.countSum();
         },
+        resetXmjSpread: function(data = null) {
+            const xmj = [];
+            if (data && data.lid != 0 && data.xmj_code !== '' && data.xmj_code !== null) {
+                if (data.bwmx === data.xmj_jldy) {
+                    data.bwmx = '';
+                }
+                xmj.push(data);
+            }
+            SpreadJsObj.loadSheetData(xmjSpread.getActiveSheet(), SpreadJsObj.DataType.Data, xmj);
+        },
+        selectionChanged: function (e, info) {
+            const data = SpreadJsObj.getSelectObject(info.sheet);
+            changeSpreadObj.resetXmjSpread(data);
+        },
         setAuditValue: function () {
             const rowCount = changeSpreadSheet.getRowCount();
             // 用户的数据合计
@@ -149,6 +163,8 @@ $(document).ready(() => {
     changeSpreadObj.setAuditValue();
     changeSpreadObj.makeSjsFooter();
     changeSpreadObj.showHideAudit();
+    changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
+    changeSpread.bind(spreadNS.Events.SelectionChanged, changeSpreadObj.selectionChanged);
 
     // 审批流程展示与隐藏
     $('#show-table-detail').on('click', function (e) {

+ 130 - 15
app/public/js/schedule_plan.js

@@ -22,15 +22,11 @@ $(function () {
         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 ledgerTree = createNewPathTree('filter', treeSetting);
 
     const static_cols = [
         {title: '编号', colSpan: '1', rowSpan: '2', field: 'code', hAlign: 0, width: 145, formatter: '@', readOnly: true, cellType: 'tree'},
@@ -94,15 +90,41 @@ $(function () {
     SpreadJsObj.selChangedRefreshBackColor(ledgerSpread.getActiveSheet());
 
     postData('/tender/' + getTenderId() + '/schedule/ledger/load', {}, function (data) {
-        let treeData = [];
-        for(const sl of selectedLedgerList) {
-            const one = _.find(data, { 'ledger_id' : sl });
-            treeData.push(one);
+        // let treeData = [];
+        // for(const sl of selectedLedgerList) {
+        //     const one = _.find(data, { 'ledger_id' : sl });
+        //     treeData.push(one);
+        // }
+        // treeData = setLeafData(treeData);
+        // console.log(treeData);
+        // let treeData = data;
+        const baseLedgerTree = createNewPathTree('base', {
+            id: 'ledger_id',
+            pid: 'ledger_pid',
+            order: 'order',
+            level: 'level',
+            rootId: -1,
+            fullPath: 'full_path',
+            calcFields: ['total_price'],
+            calcFun: function (node) {
+                node.dgn_price = ZhCalc.round(ZhCalc.div(node.total_price, node.dgn_qty1), 2);
+            }
+        });
+        baseLedgerTree.loadDatas(data);
+        treeCalc.calculateAll(baseLedgerTree);
+        for (const d of baseLedgerTree.nodes) {
+            if (!d.b_code) {
+                const one = _.find(selectedLedgerList, function (item) {
+                    return item === d.ledger_id;
+                });
+                if(one) {
+                    ledgerTree.addData(d, ['ledger_id', 'ledger_pid', 'order', 'level', 'tender_id', 'full_path',
+                        'code', 'name', 'unit', 'dgn_qty1', 'dgn_qty2', 'dgn_price', 'quantity', 'total_price']);
+                }
+            }
         }
-        treeData = setLeafData(treeData);
-        ledgerTree.loadDatas(treeData);
-        treeCalc.calculateAll(ledgerTree);
-        console.log(ledgerTree);
+        ledgerTree.sortTreeNode(true);
+        // console.log(ledgerTree);
         SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), SpreadJsObj.DataType.Tree, ledgerTree);
     }, null, true);
 
@@ -171,20 +193,35 @@ $(function () {
                     SpreadJsObj.reLoadRowData(info.sheet, info.row);
                     return;
                 }
-                select[col.field] = validText;
                 const yearmonth = col.field.split('_')[0];
                 const mode = col.field.split('_')[1];
                 let plan_gcl = 0;
                 let plan_tp = 0;
+                // 判断输入位数,提示
                 if (mode === 'tp') {
+                    const reg = new RegExp('^([-]?)\\d+(\\.\\d{0,'+ parseInt(tenderInfo.decimal.tp) +'})?$');
+                    console.log(reg);
+                    console.log(reg.test(validText));
+                    if (validText !== null && (!reg.test(validText))) {
+                        toastr.error('输入金额小数位数不能大于' + tenderInfo.decimal.tp + '位');
+                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                        return;
+                    }
                     plan_gcl = select.dgn_price && select.dgn_price !== 0 ? ZhCalc.round(ZhCalc.div(validText, select.dgn_price), tenderInfo.decimal.up) : 0;
                     plan_tp = validText;
                     select[yearmonth + '_gcl'] = plan_gcl;
                 } else {
+                    const reg = new RegExp('^([-]?)\\d+(\\.\\d{0,'+ parseInt(tenderInfo.decimal.up) +'})?$');
+                    if (validText !== null && (!reg.test(validText))) {
+                        toastr.error('输入工程量小数位数不能大于' + tenderInfo.decimal.up + '位');
+                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                        return;
+                    }
                     plan_gcl = validText;
                     plan_tp = select.dgn_price && select.dgn_price !== 0 ? ZhCalc.round(ZhCalc.mul(validText, select.dgn_price), tenderInfo.decimal.tp) : 0;
                     select[yearmonth + '_tp'] = plan_tp;
                 }
+                select[col.field] = validText;
                 const updateData = {
                     lid: select.ledger_id,
                     yearmonth,
@@ -193,13 +230,91 @@ $(function () {
                 };
                 console.log(updateData);
                 // postData(window.location.pathname + '/save', {type: 'mode', postData: updateData}, function (result) {
-                //     SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                    SpreadJsObj.reLoadRowData(info.sheet, info.row);
                 // })
             }
         },
         deletePress: function (sheet) {
             return;
         },
+        clipboardPasted(e, info) {
+            const hint = {
+                cellError: {type: 'error', msg: '粘贴内容超出了表格范围'},
+                numberExpr: {type: 'error', msg: '不能粘贴其它非数字类型字符'},
+                numberCan: {type: 'error', msg: '请粘贴大于0并且小于3位小数的浮点数'},
+            };
+            const range = info.cellRange;
+            const sortData = info.sheet.zh_data || [];
+            if (info.cellRange.row + info.cellRange.rowCount > sortData.length) {
+                toastMessageUniq(hint.cellError);
+                SpreadJsObj.reLoadSheetHeader(materialMonthSpread.getActiveSheet());
+                SpreadJsObj.reLoadSheetData(materialMonthSpread.getActiveSheet());
+                return;
+            }
+            if (sortData.length > 0 && range.col + range.colCount > 4 + months.length) {
+                toastMessageUniq(hint.cellError);
+                SpreadJsObj.reLoadSheetHeader(materialMonthSpread.getActiveSheet());
+                SpreadJsObj.reLoadSheetData(materialMonthSpread.getActiveSheet());
+                return;
+            }
+            const data = [];
+            for (let iRow = 0; iRow < range.rowCount; iRow++) {
+                let bPaste = true;
+                const curRow = range.row + iRow;
+                const materialMonthData = sortData[curRow];
+                const hintRow = range.rowCount > 1 ? curRow : '';
+                let sameCol = 0;
+                for (let iCol = 0; iCol < range.colCount; iCol++) {
+                    const curCol = range.col + iCol;
+                    const colSetting = info.sheet.zh_setting.cols[curCol];
+                    if (!colSetting) continue;
+
+                    let validText = info.sheet.getText(curRow, curCol);
+                    validText = is_numeric(validText) ? parseFloat(validText) : (validText ? trimInvalidChar(validText) : null);
+                    const orgValue = sortData[curRow][colSetting.field];
+                    if (orgValue == validText || ((!orgValue || orgValue === '') && (validText === ''))) {
+                        sameCol++;
+                        if (range.colCount === sameCol)  {
+                            bPaste = false;
+                        }
+                        continue;
+                    }
+                    const num = parseFloat(validText);
+                    if (isNaN(validText)) {
+                        toastMessageUniq(getPasteHint(hint.numberExpr, hintRow));
+                        bPaste = false;
+                        continue;
+                    }
+                    if (validText !== null && (num < 0 || !/^\d+(\.\d{1,3})?$/.test(num))) {
+                        toastMessageUniq(getPasteHint(hint.numberCan, hintRow));
+                        bPaste = false;
+                        continue;
+                    }
+                    materialMonthData[colSetting.field] = validText;
+                    sortData[curRow][colSetting.field] = validText;
+                }
+                if (bPaste) {
+                    data.push(materialMonthData);
+                } else {
+                    SpreadJsObj.reLoadRowData(info.sheet, curRow);
+                }
+            }
+            if (data.length === 0) {
+                SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
+                return;
+            }
+            // // 更新至服务器
+            // postData(window.location.pathname + '/month/save', { type:'paste', updateData: data }, function (result) {
+            //     SpreadJsObj.reLoadSheetData(materialMonthSpread.getActiveSheet());
+            //     materialBillsData = result.materialBillsData;
+            //     SpreadJsObj.loadSheetData(materialSpread.getActiveSheet(), SpreadJsObj.DataType.Data, materialBillsData);
+            //     m_tp = result.m_tp;
+            //     resetTpTable();
+            // }, function () {
+            //     SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
+            //     return;
+            // });
+        },
     };
 
     ledgerSpread.bind(spreadNS.Events.EditEnded, ledgerSpreadObj.editEnded);

+ 9 - 9
app/public/js/shenpi.js

@@ -661,7 +661,7 @@ $(document).ready(function () {
                 }
             }
             if(selects.length > 0) {
-                updateByCanEdit(ledgerTree.nodes, _.filter(ledger_cooperation_list, { user_id: parseInt(uid) }), false);
+                // updateByCanEdit(ledgerTree.nodes, _.filter(ledger_cooperation_list, { user_id: parseInt(uid) }), false);
                 const refreshNode = ledgerTree.loadPostData({update: selects});
                 ledgerSpreadObj.refreshTree(ledgerSpread.getActiveSheet(), refreshNode);
                 ledgerSpreadObj.setFontColor();
@@ -783,10 +783,10 @@ $(document).ready(function () {
                     $('#cooperation-num').text(ledger_cooperation_list.length);
                     setLeftTable(ledgerTree.datas, ledger_cooperation_list, user_id, $('#stage_audits option:selected').text());
                     selects = [select];
-                    if(select) {
-                        setAllChildrenCanEdit(select, flag);
-                        // setParentCanEdit(ledgerTree.nodes, select.ledger_pid, flag);
-                    }
+                    // if(select) {
+                    //     setAllChildrenCanEdit(select, flag);
+                    //     setParentCanEdit(ledgerTree.nodes, select.ledger_pid, flag);
+                    // }
                     const refreshNode = ledgerTree.loadPostData({update: selects});
                     ledgerSpreadObj.refreshTree(info.sheet, refreshNode);
                     ledgerSpreadObj.setFontColor();
@@ -855,7 +855,7 @@ $(document).ready(function () {
                 setLeftTable(ledgerList, ledger_cooperation_list, cur_uid, yb.name + '(原报)');
                 // treeCalc.calculateAll(ledgerTree);
                 selects = [];
-                updateByCanEdit(ledgerTree.nodes, _.filter(ledger_cooperation_list, { user_id: cur_uid }), false);
+                // updateByCanEdit(ledgerTree.nodes, _.filter(ledger_cooperation_list, { user_id: cur_uid }), false);
                 ledgerTree.loadPostData({update: selects});
                 console.log(ledgerTree);
                 SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), SpreadJsObj.DataType.Tree, ledgerTree);
@@ -889,10 +889,10 @@ $(document).ready(function () {
             delete select.pwd;
             // const refreshNode = ledgerTree.loadPostData({update: select});
             selects = [select];
-            if(select) {
-                setAllChildrenCanEdit(select, true);
+            // if(select) {
+            //     setAllChildrenCanEdit(select, true);
                 // setParentCanEdit(ledgerTree.nodes, select.ledger_pid, true);
-            }
+            // }
             const refreshNode = ledgerTree.loadPostData({update: selects});
             ledgerSpreadObj.refreshTree(ledgerSpread.getActiveSheet(), refreshNode);
             ledgerSpreadObj.setFontColor();

+ 2 - 2
app/public/report/js/rpt_cfg_const.js

@@ -4,7 +4,7 @@
 
 const   TPL_TYPE_NODE = 1,
         TPL_TYPE_TEMPLATE = 2;
-let rpt_tpl_setting = {
+const rpt_tpl_setting = {
     view: {
         selectedMulti: false
     },
@@ -30,7 +30,7 @@ let rpt_tpl_setting = {
     }
 };
 
-let rpt_prj_folder_setting = {
+const rpt_prj_folder_setting = {
     view: {
         selectedMulti: false
     },

+ 1 - 1
app/public/report/js/rpt_main.js

@@ -354,7 +354,7 @@ let zTreeOprObj = {
     requestNormalReport: function (params) {
         let me = zTreeOprObj;
         $.bootstrapLoading.start();
-        CommonAjax.postXsrfEx("/tender/report_api/getReport", params, 60000, true, getCookie('csrfToken'),
+        CommonAjax.postXsrfEx("/tender/report_api/getReport", params, 300000, true, getCookie('csrfToken'),
             function(result){
                 $.bootstrapLoading.end();
                 let pageRst = result.data;

+ 111 - 60
app/public/report/js/rpt_signature.js

@@ -189,74 +189,84 @@ let rptSignatureHelper = {
     },
     resetESignature: function (pageRst, signatureDivId) {
         // let body = $('#eSignatureBodyDiv');
-        let body = $('#' + signatureDivId);
-        body.empty();
-        const signature_cells = [];
-        const singatureNameArr = [];
-        for (const page of pageRst.items) {
-            if (page.signature_cells) {
-                for (const sCell of page.signature_cells) {
-                    if (sCell.signature_name !== null && sCell.signature_name !== undefined && sCell.signature_name !== 'dummy_pic') {
-                        if (singatureNameArr.indexOf(sCell.signature_name) < 0) {
-                            signature_cells.push(sCell);
-                            singatureNameArr.push(sCell.signature_name);
+        if (pageRst !== null) {
+            let body = $('#' + signatureDivId);
+            body.empty();
+            const signature_cells = [];
+            const singatureNameArr = [];
+            for (const page of pageRst.items) {
+                if (page.signature_cells) {
+                    for (const sCell of page.signature_cells) {
+                        if (sCell.signature_name !== null && sCell.signature_name !== undefined && sCell.signature_name !== 'dummy_pic') {
+                            if (singatureNameArr.indexOf(sCell.signature_name) < 0) {
+                                signature_cells.push(sCell);
+                                singatureNameArr.push(sCell.signature_name);
+                            }
                         }
                     }
                 }
             }
-        }
-        if (signature_cells.length > 0) {
-            const elementsStrArr = [];
-            const elementsDateStrArr = [];
-            for (let scIdx = 0; scIdx < signature_cells.length; scIdx++) {
-                const sCell = signature_cells[scIdx];
-                elementsStrArr.push('<div class="form-group row">');
-                elementsStrArr.push('<label for="staticEmail" class="col-sm-3 col-form-label pr-0">' + sCell.signature_name + '</label>');
-                elementsStrArr.push('<div class="col-sm-9">');
-                elementsStrArr.push('<ul class="list-group">');
-                elementsStrArr.push('<li class="list-group-item">');
-                let hasPic = false;
-                //新需求中,即使没有审核,也可以设置签名
-                for (let idx = 0; idx < ROLE_REL_LIST.length; idx++) {
-                    const role_rel = ROLE_REL_LIST[idx];
-                    if (role_rel.signature_name === sCell.signature_name) {
-                        if (role_rel.type === '用户') {
-                            rptSignatureHelper.pushDomElementByUser(elementsStrArr, role_rel.user_name, role_rel.role);
-                        } else {
-                            //角色
-                            rptSignatureHelper.pushDomElementByRole(elementsStrArr, role_rel.role_name, role_rel.user_name);
-                        }
-                        const idSuffixStr = 'dtp_' + role_rel.signature_name;
-                        elementsStrArr.push('<div class="">');
-                        if (role_rel.sign_date !== '') {
-                            const dt = new Date(role_rel.sign_date);
-                            const dtVal = dt.Format('yyyy-MM-dd');
-                            //elementsStrArr.push('<input class="datepicker-here form-control form-control-sm mt-0" placeholder="选择签名日期" data-language="zh" type="text" value="' + (new Date(role_rel.sign_date)).Format('yyyy-M-d') + '">');
-                            // elementsStrArr.push('<input id="' + idSuffixStr + '" class="datepicker-here form-control form-control-sm mt-0" placeholder="选择签名日期" data-language="zh" type="text" readonly="true" value="' + dtVal + '"');
-                            elementsStrArr.push('<input id="' + idSuffixStr + '" class="form-control form-control-sm mt-0" placeholder="选择签名日期" type="date" value="' + dtVal + '"');
-                        } else {
-                            // elementsStrArr.push('<input id="' + idSuffixStr + '" class="datepicker-here form-control form-control-sm mt-0" placeholder="选择签名日期" data-language="zh" type="text" readonly="true"');
-                            elementsStrArr.push('<input id="' + idSuffixStr + '" class="form-control form-control-sm mt-0" placeholder="选择签名日期" type="date"');
+            if (signature_cells.length > 0) {
+                const elementsStrArr = [];
+                const elementsDateStrArr = [];
+                for (let scIdx = 0; scIdx < signature_cells.length; scIdx++) {
+                    const sCell = signature_cells[scIdx];
+                    elementsStrArr.push('<div class="form-group row">');
+                    elementsStrArr.push('<label for="staticEmail" class="col-sm-3 col-form-label pr-0">' + sCell.signature_name + '</label>');
+                    elementsStrArr.push('<div class="col-sm-9">');
+                    elementsStrArr.push('<ul class="list-group">');
+                    elementsStrArr.push('<li class="list-group-item">');
+                    let hasPic = false;
+                    //新需求中,即使没有审核,也可以设置签名
+                    for (let idx = 0; idx < ROLE_REL_LIST.length; idx++) {
+                        const role_rel = ROLE_REL_LIST[idx];
+                        if (role_rel.signature_name === sCell.signature_name) {
+                            if (role_rel.type === '用户') {
+                                rptSignatureHelper.pushDomElementByUser(elementsStrArr, role_rel.user_name, role_rel.role);
+                            } else {
+                                //角色
+                                rptSignatureHelper.pushDomElementByRole(elementsStrArr, role_rel.role_name, role_rel.user_name);
+                            }
+                            const idSuffixStr = 'dtp_' + role_rel.signature_name;
+                            elementsStrArr.push('<div class="">');
+                            if (role_rel.sign_date !== '') {
+                                const dt = new Date(role_rel.sign_date);
+                                const dtVal = dt.Format('yyyy-MM-dd');
+                                //elementsStrArr.push('<input class="datepicker-here form-control form-control-sm mt-0" placeholder="选择签名日期" data-language="zh" type="text" value="' + (new Date(role_rel.sign_date)).Format('yyyy-M-d') + '">');
+                                // elementsStrArr.push('<input id="' + idSuffixStr + '" class="datepicker-here form-control form-control-sm mt-0" placeholder="选择签名日期" data-language="zh" type="text" readonly="true" value="' + dtVal + '"');
+                                elementsStrArr.push('<input id="' + idSuffixStr + '" class="form-control form-control-sm mt-0" placeholder="选择签名日期" type="date" value="' + dtVal + '"');
+                            } else {
+                                // elementsStrArr.push('<input id="' + idSuffixStr + '" class="datepicker-here form-control form-control-sm mt-0" placeholder="选择签名日期" data-language="zh" type="text" readonly="true"');
+                                elementsStrArr.push('<input id="' + idSuffixStr + '" class="form-control form-control-sm mt-0" placeholder="选择签名日期" type="date"');
+                            }
+                            hasPic = true;
+                            break;
                         }
-                        hasPic = true;
-                        break;
                     }
+                    if (!hasPic) {
+                        // 在交互操作中,有可能实际上是没有
+                        elementsStrArr.push('<a href="#add-sign" onclick="rptSignatureHelper.currentSelectedESignAccDom = this.parentNode; rptSignatureHelper.currentSelectedESignAccName = \'' + sCell.signature_name + '\'" data-toggle="modal" data-target="#add-sign"><i class="fa fa-plus"></i> 添加签名</a>');
+                    }
+                    // if (sCell.path || sCell.pic) {
+                    // } else {
+                    //     elementsStrArr.push('<a href="#add-sign" onclick="rptSignatureHelper.currentSelectedESignAccDom = this.parentNode; rptSignatureHelper.currentSelectedESignAccName = \'' + sCell.signature_name + '\'" data-toggle="modal" data-target="#add-sign"><i class="fa fa-plus"></i> 添加签名</a>');
+                    // }
+                    elementsStrArr.push('</li>');
+                    elementsStrArr.push('</ul>');
+                    elementsStrArr.push('</div>');
+                    elementsStrArr.push('</div>');
+                    //还有签名日期(用不用得上不管,先放上去再说)
                 }
-                if (!hasPic) {
-                    // 在交互操作中,有可能实际上是没有
-                    elementsStrArr.push('<a href="#add-sign" onclick="rptSignatureHelper.currentSelectedESignAccDom = this.parentNode; rptSignatureHelper.currentSelectedESignAccName = \'' + sCell.signature_name + '\'" data-toggle="modal" data-target="#add-sign"><i class="fa fa-plus"></i> 添加签名</a>');
-                }
-                // if (sCell.path || sCell.pic) {
-                // } else {
-                //     elementsStrArr.push('<a href="#add-sign" onclick="rptSignatureHelper.currentSelectedESignAccDom = this.parentNode; rptSignatureHelper.currentSelectedESignAccName = \'' + sCell.signature_name + '\'" data-toggle="modal" data-target="#add-sign"><i class="fa fa-plus"></i> 添加签名</a>');
-                // }
-                elementsStrArr.push('</li>');
-                elementsStrArr.push('</ul>');
-                elementsStrArr.push('</div>');
-                elementsStrArr.push('</div>');
-                //还有签名日期(用不用得上不管,先放上去再说)
+                body.append(elementsStrArr.join(' '));
             }
-            body.append(elementsStrArr.join(' '));
+        }
+    },
+    checkAndShowCrossTendersESignature: function () {
+        let btnDom = $('#btn_cross_tender')[0];
+        if (zTreeOprObj.currentNode) {
+            btnDom.style.display = '';
+        } else {
+            btnDom.style.display = 'none';
         }
     },
     pushDomElementByUser: function (elementsStrArr, userName, userRole) {
@@ -397,6 +407,47 @@ let rptSignatureHelper = {
             }
         }
     },
+    setupAfterSelectMultiTenders: function (selectedTenders) {
+        //跨标段选择,有不少要注意的交互:
+        //0. 签名日期
+        rptSignatureHelper.resetSignDate();
+        rptSignatureHelper.resetSignAudit();
+        //1. 重刷page
+        if (current_stage_status === 3) {
+            for (const page of zTreeOprObj.currentRptPageRst.items) {
+                if (page.signature_cells) {
+                    for (const sCell of page.signature_cells) {
+                        if (sCell.hasOwnProperty('pre_path')) {
+                            sCell.path = sCell.pre_path;
+                            delete sCell.pre_path;
+                        }
+                    }
+                }
+            }
+            zTreeOprObj.showPage(zTreeOprObj.currentPage, zTreeOprObj.canvas);
+        }
+        //2. 集中请求
+        let params = {};
+        params.id = CURRENT_ROLE_REL_ID;
+        params.tender_id = TENDER_ID;
+        params.stage_id = getStageId();
+        params.rpt_id = zTreeOprObj.currentNode.refId;
+        params.rel_content = ROLE_REL_LIST;
+        params.selectedTenders = selectedTenders;
+        rptSignatureHelper.originalRoleRelList = JSON.parse(JSON.stringify(ROLE_REL_LIST));
+        // CommonAjax.postXsrfEx("/tender/report_api/updateMultiRoleRelationship", params, 10000, true, getCookie('csrfToken'),
+        //     function(result){
+        //         console.log(result);
+        //         if (result.data && result.data.insertId > 0) {
+        //             CURRENT_ROLE_REL_ID = result.data.insertId;
+        //         }
+        //     }, function(err){
+        //         // hintBox.unWaitBox();
+        //     }, function(ex){
+        //         // hintBox.unWaitBox();
+        //     }
+        // );
+    },
     setupAfterSelectSignature: function () {
         //0. 签名日期
         rptSignatureHelper.resetSignDate();

+ 10 - 1
app/reports/rpt_component/helper/jpc_helper_field.js

@@ -86,7 +86,16 @@ const JpcFieldHelper = {
             if (showZero && showZero === 'F') {
                 const val = parseFloat(cell[JV.PROP_VALUE]);
                 if (val === 0) {
-                    cell[JV.PROP_VALUE] = '';
+                    let chkRst = true;
+                    if (typeof cell[JV.PROP_VALUE] === 'string' && cell[JV.PROP_VALUE].length > 1) {
+                        for (let idx = 0; idx < cell[JV.PROP_VALUE].length; idx++) {
+                            if (cell[JV.PROP_VALUE][idx] !== '0' && cell[JV.PROP_VALUE][idx] !== '.') {
+                                chkRst = false;
+                                break;
+                            }
+                        }
+                    }
+                    if (chkRst) cell[JV.PROP_VALUE] = '';
                 }
             }
         }

+ 2 - 0
app/router.js

@@ -305,6 +305,8 @@ module.exports = app => {
     app.post('/tender/report_api/createSignatureRole', sessionAuth, 'signatureController.createSignatureRole');
     app.post('/tender/report_api/updateSignatureUsed', sessionAuth, datetimeFill, 'signatureController.updateSignatureUsed');
     app.post('/tender/report_api/updateRoleRelationship', sessionAuth, 'signatureController.updateRoleRel');
+    app.post('/tender/report_api/updateMultiRoleRelationship', sessionAuth, 'signatureController.updateCrossTendersRoleRelationship');
+    app.post('/tender/report_api/getMultiRoleRelationships', sessionAuth, 'signatureController.getMultiRoleRptRels');
     app.post('/tender/report_api/createRoleRelationship', sessionAuth, 'signatureController.createRoleRel');
     app.post('/tender/report_api/updateCustNode', sessionAuth, 'reportController.updateCustNode');
     app.post('/report/cDefine', sessionAuth, 'reportController.setCustomDefine');

+ 47 - 0
app/service/role_rpt_rel.js

@@ -53,6 +53,27 @@ module.exports = app => {
             return list;
         }
 
+        async getCrossTenderRoleRptRels(selectedTenders) {
+            let rst = [];
+            // 条件比较特别,需要直接写sql
+            if (selectedTenders.length > 0) {
+                let where_sql = '';
+                for (let idx = 0; idx < selectedTenders.length; idx++) {
+                    if (idx === 0) {
+                        where_sql = '(tender_id = ' + selectedTenders[idx][0] + ' AND sid = ' + selectedTenders[idx][1] + ' AND rpt_id = ' + selectedTenders[idx][2] + ')';
+                    } else {
+                        where_sql = where_sql + ' OR (tender_id = ' + selectedTenders[idx][0] + ' AND sid = ' + selectedTenders[idx][1] + ' AND rpt_id = ' + selectedTenders[idx][2] + ')';
+                    }
+                }
+                const sql = 'SELECT ?? FROM ?? WHERE ' + where_sql;
+                const columns = ['id', 'tender_id', 'rpt_id', 'sid', 'rel_content'];
+                const sqlParam = [columns, this.tableName];
+                rst = await this.db.query(sql, sqlParam);
+                console.log(rst);
+            }
+            return rst;
+        }
+
         async getRoleRptRelByDetailIds(tenderId, rptId, sid) {
             this.initSqlBuilder();
             this.sqlBuilder.setAndWhere('tender_id', {
@@ -76,6 +97,9 @@ module.exports = app => {
             });
             this.sqlBuilder.columns = ['id', 'tender_id', 'rpt_id', 'sid', 'rel_content'];
             const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
+            // console.log(sql);
+            // console.log(this.tableName);
+            // console.log(sqlParam);
             const list = await this.db.query(sql, sqlParam);
             // console.log(list);
             return list;
@@ -144,6 +168,29 @@ module.exports = app => {
             }
             return rst;
         }
+
+        async updateMultiRoleRelationship(orgParams, newRelArr) {
+            let rst = false;
+            this.transaction = await this.db.beginTransaction();
+            try {
+                // const data = { id: id, tender_id: tender_id, rpt_id: rpt_id, sid: sid, rel_content: JSON.stringify(relArr) };
+                // rst = await this.transaction.update(this.tableName, data);
+                // this.transaction.commit();
+                for (let idx = 0; idx < orgParams.length; idx++) {
+                    const param = orgParams[idx];
+                    const data = { tender_id: param[0], sid: param[1], rpt_id: param[2] };
+                    await this.transaction.delete(this.tableName, data);
+                    this.createRoleRelationship(param[0], param[2], param[0], newRelArr);
+                }
+                rst = true;
+                this.transaction.commit();
+            } catch (ex) {
+                console.log(ex.toString());
+                // 回滚
+                await this.transaction.rollback();
+            }
+            return rst;
+        }
     }
     return RoleRptRel;
 };

+ 14 - 1
app/view/change/information.ejs

@@ -352,7 +352,19 @@
                 </div>
             </div>
             <div class="c-body col-8">
-                <div class="sjs-height-0" id="change-spread">
+                <div class="sjs-height-1" id="change-spread">
+                </div>
+                <!--下半部分-->
+                <div class="bcontent-wrap">
+                    <div class="bc-bar mb-1">
+                        <ul class="nav nav-tabs">
+                            <li class="nav-item">
+                                <a class="nav-link active" href="#">所属项目节</a>
+                            </li>
+                        </ul>
+                    </div>
+                    <div class="sp-wrap" id="xmj-spread">
+                    </div>
                 </div>
             </div>
         </div>
@@ -379,6 +391,7 @@
     const readOnly = <%- change.readOnly %>;
     const changeSpread = SpreadJsObj.createNewSpread($('#change-spread')[0]);
     const changeSpreadSheet = changeSpread.getActiveSheet();
+    const xmjSpread = SpreadJsObj.createNewSpread($('#xmj-spread')[0]);
     let changeList = JSON.parse(unescape('<%- escape(JSON.stringify(changeList)) %>'));
     const style1 = new GC.Spread.Sheets.Style();
     style1.locked = true;

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

@@ -114,7 +114,7 @@
                             </div>
                             <div class="panel" id="pnl_eSignature">
                                 <div class="panel-body">
-                                    <button class="btn btn-outline-primary btn-sm" type="button" data-toggle="modal" data-target="#eSignature" onclick="rptSignatureHelper.resetESignature(zTreeOprObj.currentRptPageRst, 'eSignatureBodyDiv')">
+                                    <button class="btn btn-outline-primary btn-sm" type="button" data-toggle="modal" data-target="#eSignature" onclick="rptSignatureHelper.resetESignature(zTreeOprObj.currentRptPageRst, 'eSignatureBodyDiv'); rptSignatureHelper.checkAndShowCrossTendersESignature();">
                                         <i class="fa fa-pencil"></i><br>
                                         电子签名
                                     </button>

+ 157 - 12
app/view/report/rpt_all_popup.ejs

@@ -204,7 +204,7 @@
             </div>
             <div class="modal-footer">
                 <!--
-                <button type="button" class="btn btn-sm btn-link float-left" data-dismiss="modal" data-toggle="modal" data-target="#batch-eSignature" id="batch-setupProjSignature" onclick="rptSignatureHelper.resetESignature(zTreeOprObj.currentRptPageRst, 'batch-eSignatureBodyDiv')">批量设置其他标段</button>
+                <button type="button" id="btn_cross_tender" class="btn btn-sm btn-link float-left" data-dismiss="modal" data-toggle="modal" data-target="#batch-eSignature" id="batch-setupProjSignature" onclick="rptSignatureHelper.resetESignature(zTreeOprObj.currentRptPageRst, 'batch-eSignatureBodyDiv'); buildTendersTree();">批量设置其他标段</button>
 
                 <button type="button" class="btn btn-sm btn-link float-left" data-toggle="modal" data-target="#batch-eSignature" id="hidden_show_batch_eSignature" style="display:none"></button>
                 <button type="button" class="btn btn-sm btn-link float-left" data-dismiss="modal" onclick="setTimeout(function(){$('#hidden_show_batch_eSignature').trigger('click');}, 50);">批量设置其他标段</button>
@@ -227,7 +227,7 @@
             <div class="modal-body">
                 <div class="row">
                     <div class="col-6">
-                        <table class="table table-hover table-bordered" id="batch_projects_individual">
+                        <table class="table table-hover table-bordered" id="batch_tenders_individual">
                         </table>
                     </div>
                     <div class="col-6" id="batch-eSignatureBodyDiv"></div>
@@ -236,7 +236,7 @@
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">取消</button>
-                <a href="" class="btn btn-sm btn-primary">确定</a>
+                <a href="javascript:void(0);" onclick="rptSignatureHelper.setupAfterSelectMultiTenders(SELECTED_TENDERS)" class="btn btn-sm btn-primary">确定</a>
             </div>
         </div>
     </div>
@@ -488,10 +488,11 @@
     zTreeOprObj.iniFontCfgDom(CUST_CFG);
     buildCustRptCommon('report_cust_group_common', ORG_TOP_TREE_NODES[1], CUST_TREE_NODES.common, 'true');
     buildCustRptCommon('report_cust_group_individual', ORG_TOP_TREE_NODES[0], CUST_TREE_NODES.customize, 'false');
-    //buildTendersTree();
+    let SELECTED_TENDERS = [];
 
     function buildTendersTree() {
         let sortedCat = [];
+        SELECTED_TENDERS = [];
         for (const cat of category) {
             if (cat.level > 0) {
                 sortedCat.push(cat);
@@ -511,7 +512,8 @@
                             name: nv.value,
                             id : nv.id,
                             cid : nv.cid,
-                            items: []
+                            items: [],
+                            isParent: true
                         };
                         parentItems.push(item);
                         _createItems(item.items, grpLv + 1);
@@ -531,7 +533,7 @@
         //3. 把标段挂上去
         let tmpCacheArr = []; //这个临时用来储存相应标段节点挂接信息
         let _putTender = function (catLv, tender, parentItems) {
-            if (catLv < tender.category.length) {
+            if (catLv < tender.category.length && tender.lastStage !== undefined && tender.lastStage !== null) {
                 let isSorted = false;
                 for (let sCat of sortedCat) {
                     if (sCat.id === tender.category[catLv].cid && sCat.level > 0) {
@@ -548,13 +550,16 @@
                             } else {
                                 //就是这个了
                                 let tdItem = {
-                                    name: tender.value,
+                                    name: tender.name,
                                     id : -1,
                                     cid : -1,
-                                    prj_id: tender.id,
-                                    last_stage: -1,
-                                    signature: '',
-                                    items: []
+                                    tender_id: tender.id,
+                                    last_stage: tender.lastStage.order,
+                                    last_stage_id: tender.lastStage.id,
+                                    report_id: zTreeOprObj.currentNode.refId,
+                                    signature: '临时',
+                                    items: [],
+                                    isParent: false
                                 }; //标段节点
                                 //
                                 tmpCacheArr.push([item, tdItem]);
@@ -570,7 +575,93 @@
         for (const pairItem of tmpCacheArr) {
             pairItem[0].items.push(pairItem[1]);
         }
-        console.log(treeCache);
+        //4. 剔除空items的项
+        let _removeEmptyItems = function (parentItem) {
+            let rst = false;
+            if (parentItem.items.length === 0) {
+                if (parentItem.isParent) {
+                    rst = true;
+                }
+            } else {
+                for (let idx = parentItem.items.length - 1; idx >= 0; idx--) {
+                    if (_removeEmptyItems(parentItem.items[idx])) {
+                        parentItem.items.splice(idx, 1);
+                    }
+                }
+                rst = parentItem.items.length === 0;
+            }
+            return rst;
+        }
+        for (let idx = treeCache.length - 1; idx >= 0; idx--) {
+            if (_removeEmptyItems(treeCache[idx])) {
+                treeCache.splice(idx, 1);
+            }
+        }
+        //console.log(treeCache);
+        //还要请求各标段的原签名数据
+        let params = {};
+        params.selectedTenders = [];
+        let _getTenderRelatedInfos = function(parentItem, rstArr) {
+            if (parentItem.items.length === 0) {
+                if (!parentItem.isParent) {
+                    rstArr.push([parentItem.tender_id, parentItem.last_stage_id, parentItem.report_id]);
+                }
+            } else {
+                for (let idx = parentItem.items.length - 1; idx >= 0; idx--) {
+                    _getTenderRelatedInfos(parentItem.items[idx], rstArr);
+                }
+            }
+        };
+        let _addHint = function(parentItem, relArr) {
+            if (parentItem.items.length === 0) {
+                if (!parentItem.isParent) {
+                    for (const rel of relArr) {
+                        if (rel.tender_id === parentItem.tender_id && rel.sid === parentItem.last_stage_id && rel.rpt_id === parentItem.report_id) {
+                            let hintStr = '';
+                            if (rel.rel_content instanceof Array) {
+                                for (let idx = 0; idx < rel.rel_content.length; idx++) {
+                                    const dtlRel = rel.rel_content[idx];
+                                    if (idx > 0) {
+                                        hintStr = hintStr + '、';
+                                    }
+                                    hintStr = hintStr + '(' + dtlRel.signature_name + ')' + dtlRel.user_name;
+                                }
+                            }
+                            parentItem.signature = hintStr;
+                            break;
+                        }
+                    }
+                }
+            } else {
+                for (let idx = parentItem.items.length - 1; idx >= 0; idx--) {
+                    _getTenderRelatedInfos(parentItem.items[idx], relArr);
+                }
+            }
+        };
+        for (let idx = treeCache.length - 1; idx >= 0; idx--) {
+            _getTenderRelatedInfos(treeCache[idx], params.selectedTenders);
+        }
+        $.bootstrapLoading.start();
+        CommonAjax.postXsrfEx("/tender/report_api/getMultiRoleRelationships", params, 30000, true, getCookie('csrfToken'),
+            function(result){
+                $.bootstrapLoading.end();
+                let relArr = result.data;
+                for (const rel of relArr) {
+                    rel.rel_content = JSON.parse(rel.rel_content);
+                }
+                console.log(relArr);
+                //5. 加hint
+                for (let idx = treeCache.length - 1; idx >= 0; idx--) {
+                    _addHint(treeCache[idx], relArr);
+                }
+                //6. 建树
+                _buildTenderTree('batch_tenders_individual', treeCache);
+            }, function(err){
+                $.bootstrapLoading.end();
+            }, function(ex){
+                $.bootstrapLoading.end();
+            }
+        );
     }
 
     function searchAccount() {
@@ -579,6 +670,46 @@
         }
     }
 
+    function _buildTenderTree(tbDomId, tendersArr) {
+        let tbDom = $("#" + tbDomId);
+        tbDom.empty();
+        //tbDom.append('<tr><th>类别</th><th>包含报表</th><th>显示</th></tr>');
+        tbDom.append('<thead><tr><th>名称</th><th width="50">计量期</th><th width="40">签名</th><th width="40">选择</th></tr></thead>');
+        tbDom.append('<tbody>');
+        const _createRow = function (rowItem, lv) {
+            let tdClassStr = 'in-' + lv;
+            if (rowItem.isParent) {
+                tbDom.append('<tr><td class="' + tdClassStr + '"><i class="fa fa-folder-o"></i>&nbsp;&nbsp;' + rowItem.name + '</td><td></td><td></td><td></td></tr>');
+            } else {
+                let hrefStr = '/tender/' + rowItem.tender_id;
+                //<a href="biaoduan-panel.html" target="_blank">WWUJ-1</a>
+                let lastStgStr = '';
+                if (rowItem.last_stage === -1) {
+                    lastStgStr = '台账';
+                } else {
+                    lastStgStr = '第' + rowItem.last_stage + '期';
+                }
+                //let chgStr = 'changeCrossTender(this, SELECTED_TENDERS,' + rowItem.tender_id + ', ' + rowItem.last_stage_id + ', ' + rowItem.report_id + ')';
+                if (rowItem.signature !== undefined && rowItem.signature !== null && rowItem.signature !== '') {
+                    let hintStr = '<i class="fa fa-exclamation-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" data-original-title="' + rowItem.signature + '"></i>';
+                    tbDom.append('<tr><td class="' + tdClassStr + '"><a href="' + hrefStr + '" target="_blank">' + rowItem.name + '</a></td><td>' + lastStgStr + '</td><td>' + hintStr + '</td><td><input type="checkbox" onclick="changeCrossTender(this, SELECTED_TENDERS, ' + rowItem.tender_id + ', ' + rowItem.last_stage_id + ', ' + rowItem.report_id + ')' + '"></td></tr>');
+                } else {
+                    tbDom.append('<tr><td class="' + tdClassStr + '"><a href="' + hrefStr + '" target="_blank">' + rowItem.name + '</a></td><td>' + lastStgStr + '</td><td></td><td><input type="checkbox" onclick="changeCrossTender(this, SELECTED_TENDERS, ' + rowItem.tender_id + ', ' + rowItem.last_stage_id + ', ' + rowItem.report_id + ')' + '"></td></tr>');
+                }
+            }
+            if (rowItem.items && rowItem.items.length > 0) {
+                for (const subItem of rowItem.items) {
+                    _createRow(subItem, lv + 1);
+                }
+            }
+        }
+        let grpLv = 1;
+        for (const tItem of tendersArr) {
+            _createRow(tItem, grpLv);
+        }
+        tbDom.append('</tbody>');
+    }
+
     function buildCustRptCommon(tbDomId, topTreeNode, checkingArr, isCommonStr) {
         let tbDom = $("#" + tbDomId);
         tbDom.empty();
@@ -682,6 +813,20 @@
         buildCustRptCommon('report_cust_group_individual', ORG_TOP_TREE_NODES[0], CUST_TREE_NODES.customize, 'false');
     }
 
+    function changeCrossTender(dom, rstArr, tenderId, stageId, reportId) {
+        if (dom.checked) {
+            let item = [tenderId, stageId, reportId];
+            rstArr.push(item);
+        } else {
+            for (let idx = rstArr.length - 1; idx >= 0; idx--) {
+                if (rstArr[idx][0] === tenderId && rstArr[idx][1] === stageId && rstArr[idx][2] === reportId) {
+                    rstArr.splice(idx, 1); //删除当前标段
+                    //这里不break,防止一些冗余数据
+                }
+            }
+        }
+    }
+
     function changeFolder(dom, isCommon, parentIdStr) {
         let prop = null;
         if (isCommon) {

+ 0 - 1
app/view/schedule/plan.ejs

@@ -28,6 +28,5 @@
     const schedule = JSON.parse('<%- JSON.stringify(schedule) %>');
     const scheduleMonth = JSON.parse('<%- JSON.stringify(scheduleMonth) %>');
     const monthList = _.map(scheduleMonth, 'yearmonth');
-    console.log(monthList);
     const mode = JSON.parse('<%- JSON.stringify(mode) %>');
 </script>

+ 3 - 0
sql/update.sql

@@ -17,3 +17,6 @@ CREATE TABLE `zh_ledger_cooperation` (
   `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否调用',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='台账多人协同表';
+
+
+CREATE UNIQUE INDEX `idx_tid_sid_rid`  ON `zh_rpt_custom_define` (tid, sid, rid) COMMENT '电子签名数据索引' ALGORITHM DEFAULT LOCK DEFAULT;