ソースを参照

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

MaiXinRong 6 ヶ月 前
コミット
1adee29a6f

+ 4 - 1
app/controller/report_controller.js

@@ -1153,12 +1153,14 @@ module.exports = app => {
             let stgAudit = null,
                 stgAuditForOrg = null,
                 stageFlow = null,
-                stageList = [];
+                stageList = [],
+                ledger = [];
             if (params.stage_id > 0) {
                 stgAudit = await ctx.service.stageAudit.getStageAudit(params.stage_id, params.stage_times);
                 stgAuditForOrg = await ctx.service.stageAudit.getStageAudit(params.stage_id, 1);
                 stageList = await ctx.service.stage.getValidStagesShort(params.tender_id);
                 stageFlow = await ctx.service.stageAudit.getAuditGroupByListWithOwner(params.stage_id, params.stage_times);
+                ledger = await ctx.service.ledger.getDataOnlyByNodeId(params.tender_id);
             } else if ([-100, -200].includes(params.stage_id)) {
                 stgAudit = await ctx.service.paymentDetailAudit.getAuditors(params.detail_id, params.stage_times);
                 stgAuditForOrg = await ctx.service.paymentDetailAudit.getAuditors(params.detail_id, 1);
@@ -1204,6 +1206,7 @@ module.exports = app => {
                 debugInfo: ctx.session.sessionUser.loginStatus ? ctx.debugInfo : null,
                 customDefine: rptTpl[JV.NODE_CUSTOM_DEFINE],
                 stageFlow,
+                ledger,
                 customSelect,
                 waterMarkStr,
             };

+ 1 - 0
app/public/report/js/jpc_output_value_define.js

@@ -78,6 +78,7 @@ let JV = {
     PROP_SIGNATURE_AUDIT_CELLS: 'signature_audit_cells',
     PROP_INTERACT_CELLS: 'interact_cells',
     PAGE_SPECIAL_MERGE_POS: "page_merge_pos",
+    PROP_EXT_FLOW_OPTIONS: 'extend_flow_options',
 
     PAGES_SIZE_STR: ['A3', 'A4', 'A5', 'B4', 'B5', 'LETTER', 'LEGAL', 'EXECUTIVE', '16K'],
     PAGES_SIZE_IDX: [8, 9, 11, 12, 13, 1, 5, 7, 93],

+ 2 - 1
app/public/report/js/rpt_jsexcel.js

@@ -1286,7 +1286,8 @@ function _checkAndSetSignatureCache(pageData, signKeyArr, signPathArr, roleRel,
                 // 这里把图片的路径作为key值判断
                 if (signKeyArr.indexOf(signatureCell.signature_name) < 0) {
                     // 还得判断用户是否有选择签名输出
-                    for (const role of chkRoles) {
+                    for (const role_rel of chkRoles) {
+                        const role = getTheRightRole(role_rel, pageIdx);
                         if (signatureCell.signature_name === role.signature_name) {
                             if (!(role.signature_name.indexOf(JV.SIGNATURE_NAME_DUMMY) < 0 && role.sign_output.indexOf('normal_sign') < 0)) {
                                 if (!checkAudit || role.signature_name.indexOf(JV.SIGNATURE_NAME_DUMMY) >= 0 || rptSignatureHelper._chkIfAudit(role)) {

+ 5 - 3
app/public/report/js/rpt_main.js

@@ -509,12 +509,14 @@ let zTreeOprObj = {
                 STAGE_AUDIT = result.stageAudit || [];
                 STAGE_AUDIT_ORG = result.stageAuditOrg || [];
                 STAGE_FLOW = result.stageFlow;
+                LEDGER_LIST = result.ledger;
                 //stageAuditOrg
                 if (result.signatureRelInfo && result.signatureRelInfo.length > 0) {
                     CURRENT_ROLE_REL_ID = result.signatureRelInfo[0].id;
                     ROLE_REL_LIST = me._parseRoleRelList(result.signatureRelInfo[0].rel_content);
                     rptSignatureHelper.originalRoleRelList = me._parseRoleRelList(result.signatureRelInfo[0].rel_content);
-                    resetStampSignature(pageRst, ROLE_REL_LIST, getStageStatus() !== 3);
+                    // prepareRightFlowRoles(pageRst, ROLE_REL_LIST, STAGE_AUDIT, LEDGER_LIST);
+                    resetStampSignature(pageRst, ROLE_REL_LIST, getStageStatus() !== 3, STAGE_AUDIT, LEDGER_LIST);
                     rptSignatureHelper.mergeSignDate(pageRst, ROLE_REL_LIST, true, getStageStatus() !== 3);
                     rptSignatureHelper.mergeSignature(pageRst, ROLE_REL_LIST, true, getStageStatus() !== 3);
                     await rptSignatureHelper.resetDummySignature(pageRst, ROLE_REL_LIST, getStageStatus() !== 3); // 这里重新整理签章坐标信息(因签章大小在后台暂时获取不到,挪到前端处理)
@@ -1037,7 +1039,7 @@ let rptControlObj = {
                             const pageObj = pageDataArr[idx];
                             let singleSignatureRelArr = signatureRelArr[idx];
                             if (signatureRelInfo && signatureRelInfo.length > 0) {
-                                resetStampSignature(pageObj, singleSignatureRelArr, getStageStatus() !== 3);
+                                resetStampSignature(pageObj, singleSignatureRelArr, getStageStatus() !== 3, STAGE_AUDIT, LEDGER_LIST);
                                 rptSignatureHelper.mergeSignDate(pageObj, singleSignatureRelArr, false, getStageStatus() !== 3);
                                 // rptSignatureHelper.mergeSignature(pageObj, singleSignatureRelArr); // 这里merge的意义不大
                                 rptSignatureHelper.mergeSignAudit(pageObj, singleSignatureRelArr, STAGE_AUDIT, getStageStatus() !== 3);
@@ -1206,7 +1208,7 @@ let rptControlObj = {
                         for (let idx = 0; idx < result.data.length; idx++) {
                             const pageData = result.data[idx];
                             let singleSignatureRelArr = signatureRelArr[idx];
-                            resetStampSignature(pageData, singleSignatureRelArr, getStageStatus() !== 3);
+                            resetStampSignature(pageData, singleSignatureRelArr, getStageStatus() !== 3, STAGE_AUDIT, LEDGER_LIST);
                             await rptSignatureHelper.resetDummySignature(pageData, null); //
                             if (PAGE_SHOW.isTextSignature) {
                                 resetTextSignature(pageData, getStageStatus() !== 3);

+ 3 - 1
app/public/report/js/rpt_preview_common.js

@@ -7,6 +7,7 @@ let STAGE_AUDIT = []; //注意这个,与rpt_main.js不要混了
 let STAGE_LIST = [];
 let STAGE_FLOW = [];
 let STAGE_AUDIT_ORG = [];
+let LEDGER_LIST = [];
 let ROLE_REL_LIST = [];
 let current_stage_id = -1;
 let BGL_OBJ = null;
@@ -46,6 +47,7 @@ async function printPageLoading() {
         let refRptTplIds = JSON.parse(sessionStorage.refRptTplIds);
         STAGE_LIST = JSON.parse(sessionStorage.STAGE_LIST);
         STAGE_FLOW = JSON.parse(sessionStorage.STAGE_FLOW);
+        LEDGER_LIST = JSON.parse(sessionStorage.LEDGER_LIST);
         STAGE_AUDIT_ORG = JSON.parse(sessionStorage.STAGE_AUDIT_ORG);
         ROLE_REL_LIST = JSON.parse(sessionStorage.ROLE_REL_LIST);
         OSS_PATH = sessionStorage.OSS_PATH;
@@ -71,7 +73,7 @@ async function printPageLoading() {
                         }
                     }
                     if (result.signatureRelInfo && result.signatureRelInfo.length > 0) {
-                        resetStampSignature(result.data[idx], singleSignatureRelArr, _current_stage_status !== 3);
+                        resetStampSignature(result.data[idx], singleSignatureRelArr, _current_stage_status !== 3, STAGE_AUDIT, LEDGER_LIST);
                         if (_current_stage_status === 3) {
                             rptSignatureHelper.mergeSignDate(result.data[idx], singleSignatureRelArr, false);
                             rptSignatureHelper.mergeSignature(result.data[idx], singleSignatureRelArr, true);

+ 1 - 0
app/public/report/js/rpt_print.js

@@ -31,6 +31,7 @@ let rptPrintHelper = {
             sessionStorage.waterMarkStr = COMMON_WATER_MARK_PIC_DATA;
             sessionStorage.refRptTplIds = JSON.stringify(refRptTplIds);
             sessionStorage.STAGE_LIST = JSON.stringify(STAGE_LIST);
+            sessionStorage.LEDGER_LIST = JSON.stringify(LEDGER_LIST);
             sessionStorage.STAGE_FLOW = JSON.stringify(STAGE_FLOW);
             sessionStorage.STAGE_AUDIT_ORG = JSON.stringify(STAGE_AUDIT_ORG);
             sessionStorage.ROLE_REL_LIST = JSON.stringify(ROLE_REL_LIST);

+ 212 - 162
app/public/report/js/rpt_signature.js

@@ -172,7 +172,8 @@ let rptSignatureHelper = {
             roleRelObj.type = '流程';
             roleRelObj.flowOrder = order;
             roleRelObj.flow_name = `${assName}(协同)`;
-            roleRelObj.assFlowInfos = []; // 这里动态记录流程的协审信息(含:人名、单位、职位、签字签章、签字日期)
+            roleRelObj.assFlowInfos = []; // 这里动态记录流程的协审信息(含:人名、单位、职位、签字签章、签字日期, 其实相当于另一个完整的roleRel对象)
+            roleRelObj.sign_output = [];
             ROLE_REL_LIST.push(roleRelObj);
             STAGE_FLOW.forEach(sf => {
                 if (sf.audit_order === order) {
@@ -652,7 +653,7 @@ let rptSignatureHelper = {
                 }
             }
         }
-        resetStampSignature(zTreeOprObj.currentRptPageRst, ROLE_REL_LIST, getStageStatus() !== 3);
+        resetStampSignature(zTreeOprObj.currentRptPageRst, ROLE_REL_LIST, getStageStatus() !== 3, STAGE_AUDIT, LEDGER_LIST);
         rptSignatureHelper.mergeSignDate(zTreeOprObj.currentRptPageRst, ROLE_REL_LIST, true, getStageStatus() !== 3);
         rptSignatureHelper.mergeSignature(zTreeOprObj.currentRptPageRst, ROLE_REL_LIST, true, getStageStatus() !== 3);
         await rptSignatureHelper.resetDummySignature(zTreeOprObj.currentRptPageRst, ROLE_REL_LIST, getStageStatus() !== 3);
@@ -888,7 +889,8 @@ let rptSignatureHelper = {
         return rst;
     },
     mergeSignature: function (pageData, currRoleRelList, setPic = false, checkAudit = false) {
-        for (const page of pageData.items) {
+        for (let pageIdx = 0; pageIdx < pageData.items.length; pageIdx++) {
+            const page = pageData.items[pageIdx];
             if (page.signature_cells) {
                 // const adHocScells = [];
                 for (const sCell of page.signature_cells) {
@@ -897,38 +899,35 @@ let rptSignatureHelper = {
                         sCell.pre_path = null;
                         sCell.pic = null;
                     }
-                    for (const role_rel of currRoleRelList) {
-                        if (role_rel.type !== '流程') {
-                            if (!checkAudit || checkAudit && rptSignatureHelper._chkIfAudit(role_rel)) {
-                                // 如果签名者是在审核流程中并已审批通过(个人通过,非期通过),则也需要显示
-                                if (role_rel.signature_name === sCell.signature_name) {
-                                    // 处理签章
-                                    if (!Array.isArray(role_rel.sign_output)) {
-                                        role_rel.sign_output = [];
-                                        role_rel.sign_output.push(NORMAL_SIGN_STR);
-                                    }
-                                    for (const signType of role_rel.sign_output) {
-                                        switch (signType) {
-                                            case NORMAL_SIGN_STR:
-                                                sCell.path = role_rel.sign_path;
-                                                sCell.pre_path = role_rel.sign_path;
-                                                if (setPic) {
-                                                    sCell.pic = role_rel.sign_pic; // 有些场景(如:批量归档)需要直接设置签名数据
-                                                }
-                                                break;
-                                            case COMPANY_SIGN_STR:
-                                            case PRIVATE_SIGN_STR:
-                                                // 搬到了mergetStamp方法那去处理了
-                                            break;
-                                            default:
+                    for (const role of currRoleRelList) {
+                        const role_rel = getTheRightRole(role, pageIdx);
+                        if (!checkAudit || checkAudit && rptSignatureHelper._chkIfAudit(role_rel)) {
+                            // 如果签名者是在审核流程中并已审批通过(个人通过,非期通过),则也需要显示
+                            if (role_rel.signature_name === sCell.signature_name) {
+                                // 处理签章
+                                if (!Array.isArray(role_rel.sign_output)) {
+                                    role_rel.sign_output = [];
+                                    role_rel.sign_output.push(NORMAL_SIGN_STR);
+                                }
+                                for (const signType of role_rel.sign_output) {
+                                    switch (signType) {
+                                        case NORMAL_SIGN_STR:
+                                            sCell.path = role_rel.sign_path;
+                                            sCell.pre_path = role_rel.sign_path;
+                                            if (setPic) {
+                                                sCell.pic = role_rel.sign_pic; // 有些场景(如:批量归档)需要直接设置签名数据
+                                            }
                                             break;
-                                        }
+                                        case COMPANY_SIGN_STR:
+                                        case PRIVATE_SIGN_STR:
+                                            // 搬到了mergetStamp方法那去处理了
+                                        break;
+                                        default:
+                                        break;
                                     }
-                                    break;
                                 }
+                                break;
                             }
-                        } else {
-                            //
                         }
                     }
                 }
@@ -936,7 +935,7 @@ let rptSignatureHelper = {
             }
         }
     },
-    resetDummySignature: async function(pageData, roleRel, ifPushRoleRel = false, checkAudit = false) {
+    resetDummySignature: async function(pageData, roleRels, ifPushRoleRel = false, checkAudit = false) {
         // 备注:计算草图等其他图形需要额外做些处理
         let dummySignIdx = 0;
         const stampPicKeys = [], stampPicFeatures = [];
@@ -948,18 +947,15 @@ let rptSignatureHelper = {
                         let passAuditChk = true;
                         if (checkAudit) {
                             passAuditChk = false;
-                            if (roleRel) {
-                                for (const role_rel of roleRel) {
-                                    if (role_rel.type !== '流程') {
-                                        if (role_rel.signature_name === signatureCell.signatureName) {
-                                            // signatureName(非signature_name)是印章cell特意给的属性,还有isStamp属性
-                                            if (rptSignatureHelper._chkIfAudit(role_rel)) {
-                                                passAuditChk = true;
-                                                break;
-                                            }
+                            if (roleRels) {
+                                for (const role of roleRels) {
+                                    const role_rel = getTheRightRole(role, pageIdx);
+                                    if (role_rel.signature_name === signatureCell.signatureName) {
+                                        // signatureName(非signature_name)是印章cell特意给的属性,还有isStamp属性
+                                        if (rptSignatureHelper._chkIfAudit(role_rel)) {
+                                            passAuditChk = true;
+                                            break;
                                         }
-                                    } else {
-                                        //
                                     }
                                 }
                             }
@@ -984,7 +980,7 @@ let rptSignatureHelper = {
                                 // 如果签章信息中存在位置信息,则不执行该方法
                                 if(!signatureCell.isSaveSignature) _resetStampArea(pageData[JV.NODE_CONTROL_COLLECTION][signatureCell[JV.PROP_CONTROL]], signatureCell, roleRelItem);
                             }
-                            if (ifPushRoleRel) roleRel.push(roleRelItem);
+                            if (ifPushRoleRel) roleRels.push(roleRelItem);
                         }
                     }
                 }
@@ -998,84 +994,82 @@ let rptSignatureHelper = {
         const reg4 = new RegExp('\r', 'g');
         const reg5 = new RegExp('<br/>', 'g');
         const reg6 = new RegExp('<br>', 'g');
-        for (const page of pageData.items) {
+        for (let pageIdx = 0; pageIdx < pageData.items.length; pageIdx++) {
+            const page = pageData.items[pageIdx];
             if (page.signature_audit_cells) {
                 for (const sCell of page.signature_audit_cells) {
                     sCell.Value = ''; // 这里要先清除原有信息
-                    for (const role_rel of currRoleRelList) {
-                        if (role_rel.type !== '流程') {
-                            if (!checkAudit || checkAudit && rptSignatureHelper._chkIfAudit(role_rel)) {
-                                // 如果签名者是在审核流程中并已审批通过(个人通过,非期通过),则也需要显示
-                                if (sCell.signature_name === role_rel.signature_name + '_审核意见') {
-                                    let preDate = '';
-                                    sCell.Value = '同意'; // 只有选择了签名的,才需要初始化一个默认的意见(之前的逻辑在有多个签名,哪怕只选择了一个,其他的意见都会有默认意见)
-                                    for (const audit_rel of currAuditList) {
-                                        if (role_rel.acc_id === audit_rel.aid) {
-                                            const isOrAudit = this._chkOrAudit(role_rel.acc_id);
-                                            if (audit_rel.end_time > preDate && audit_rel.status === 3 || isOrAudit) {
-                                                sCell.Value = audit_rel.opinion;
-                                                if (typeof sCell.Value === 'string') {
-                                                    sCell.Value = sCell.Value.replace(reg1, '|').replace(reg2, '|').replace(reg3, '|').replace(reg4, '|').replace(reg5, '|').replace(reg6, '|');
-                                                }
-                                                sCell.Value = (sCell.Value === '' && isOrAudit) ? '同意' : sCell.Value;
-                                                preDate = audit_rel.end_time;
-                                            } else {
-                                                sCell.Value = ''; // 如有匹配,但又不能输出,则需要清空
+                    for (const role of currRoleRelList) {
+                        const role_rel = getTheRightRole(role, pageIdx);
+                        if (!checkAudit || checkAudit && rptSignatureHelper._chkIfAudit(role_rel)) {
+                            // 如果签名者是在审核流程中并已审批通过(个人通过,非期通过),则也需要显示
+                            if (sCell.signature_name === role_rel.signature_name + '_审核意见') {
+                                let preDate = '';
+                                sCell.Value = '同意'; // 只有选择了签名的,才需要初始化一个默认的意见(之前的逻辑在有多个签名,哪怕只选择了一个,其他的意见都会有默认意见)
+                                for (const audit_rel of currAuditList) {
+                                    if (role_rel.acc_id === audit_rel.aid) {
+                                        const isOrAudit = this._chkOrAudit(role_rel.acc_id);
+                                        if (audit_rel.end_time > preDate && audit_rel.status === 3 || isOrAudit) {
+                                            sCell.Value = audit_rel.opinion;
+                                            if (typeof sCell.Value === 'string') {
+                                                sCell.Value = sCell.Value.replace(reg1, '|').replace(reg2, '|').replace(reg3, '|').replace(reg4, '|').replace(reg5, '|').replace(reg6, '|');
                                             }
-                                            //不能break,实际会有多个审核意见,以最后一个为准
+                                            sCell.Value = (sCell.Value === '' && isOrAudit) ? '同意' : sCell.Value;
+                                            preDate = audit_rel.end_time;
+                                        } else {
+                                            sCell.Value = ''; // 如有匹配,但又不能输出,则需要清空
                                         }
+                                        //不能break,实际会有多个审核意见,以最后一个为准
                                     }
-                                    break;
                                 }
+                                break;
                             }
-                        } else {
-                            // 流程的处理还得看实际数据
                         }
                     }
                 }
             }
         }
     },
+    _setDftDate: function (role_rel, isMergeOrgAlso = false) {
+        if (role_rel.acc_id && (role_rel.sign_date === undefined || role_rel.sign_date ===  null || role_rel.sign_date ===  '')) {
+            let dftDate = _getSignDateByAllScenarios(role_rel.acc_id);
+            if (dftDate !== '' && dftDate.length >= 10) {
+                dftDate = new Date(dftDate); // 不Format,保留时分秒
+            } else if (dftDate === '') {
+                if (current_stage_id <= -300 && current_stage_id > -400 && BGL_OBJ && BGL_OBJ.currentBz && BGL_OBJ.currentBz.status === 3) {
+                    if (STAGE_AUDIT && STAGE_AUDIT.length > 0) {
+                        dftDate = new Date(STAGE_AUDIT[STAGE_AUDIT.length - 1].end_time);
+                    } else {
+                        dftDate = new Date();
+                    }
+                } else {
+                    dftDate = new Date();
+                }
+            }
+            role_rel.sign_date = dftDate;
+            if (isMergeOrgAlso) {
+                for (const orgRR of rptSignatureHelper.originalRoleRelList) {
+                    if (orgRR.signature_name === role_rel.signature_name) {
+                        orgRR.sign_date = dftDate;
+                        break;
+                    }
+                }
+                // rptSignatureHelper.originalRoleRelList[rridx].sign_date = dftDate; // 这个在实际情况下originalRoleRelList不一定与currRoleRelList一致
+                //备注:在多选导出的情况下,originalRoleRelList不需要merge
+            }
+        }
+    },
     mergeSignDate: function (pageData, currRoleRelList, isMergeOrgAlso, checkAudit = false) {
         if (currRoleRelList && currRoleRelList.length > 0 && STAGE_AUDIT && STAGE_AUDIT.length > 0) {
             for (let rridx = 0; rridx < currRoleRelList.length; rridx++) {
                 const role_rel = currRoleRelList[rridx];
                 if (role_rel.type !== '流程') {
-                    // if (role_rel.sign_date === undefined || role_rel.sign_date ===  null || role_rel.sign_date ===  '' || this._chkIfOrgRpt(role_rel.acc_id)) {
-                    // if (role_rel.sign_date === undefined || role_rel.sign_date ===  null || role_rel.sign_date ===  '') {
-                    if (role_rel.acc_id && (role_rel.sign_date === undefined || role_rel.sign_date ===  null || role_rel.sign_date ===  '')) {
-                        let dftDate = _getSignDateByAllScenarios(role_rel.acc_id);
-                        if (dftDate !== '' && dftDate.length >= 10) {
-                            dftDate = new Date(dftDate); // 不Format,保留时分秒
-                        } else if (dftDate === '') {
-                            if (current_stage_id <= -300 && current_stage_id > -400 && BGL_OBJ && BGL_OBJ.currentBz && BGL_OBJ.currentBz.status === 3) {
-                                if (STAGE_AUDIT && STAGE_AUDIT.length > 0) {
-                                    dftDate = new Date(STAGE_AUDIT[STAGE_AUDIT.length - 1].end_time);
-                                } else {
-                                    dftDate = new Date();
-                                }
-                            } else {
-                                dftDate = new Date();
-                            }
-                        }
-                        role_rel.sign_date = dftDate;
-                        if (isMergeOrgAlso) {
-                            for (const orgRR of rptSignatureHelper.originalRoleRelList) {
-                                if (orgRR.signature_name === role_rel.signature_name) {
-                                    orgRR.sign_date = dftDate;
-                                    break;
-                                }
-                            }
-                            // rptSignatureHelper.originalRoleRelList[rridx].sign_date = dftDate; // 这个在实际情况下originalRoleRelList不一定与currRoleRelList一致
-                            //备注:在多选导出的情况下,originalRoleRelList不需要merge
-                        }
-                    }
-                } else {
-                    //
+                    rptSignatureHelper._setDftDate(role_rel, isMergeOrgAlso);
                 }
             }
         }
-        for (const page of pageData.items) {
+        for (let pageIdx = 0; pageIdx < pageData.items.length; pageIdx++) {
+            const page = pageData.items[pageIdx];
             if (page.signature_date_cells) {
                 for (const sCell of page.signature_date_cells) {
                     if (typeof sCell.Value === 'string' && sCell.Value.replace(/ /g, '') === '年月日') {
@@ -1083,7 +1077,9 @@ let rptSignatureHelper = {
                     } else {
                         sCell.Value = '';
                     }
-                    for (const role_rel of currRoleRelList) {
+                    for (const role of currRoleRelList) {
+                        const role_rel = getTheRightRole(role, pageIdx);
+                        if (role.type === '流程') rptSignatureHelper._setDftDate(role_rel, false);
                         if (sCell.signature_name === role_rel.signature_name + '_签字日期') {
                             if (!checkAudit || rptSignatureHelper._chkIfAudit(role_rel)) {
                                 // 如果签名者是在审核流程中并已审批通过(个人通过,非期通过),则也需要显示
@@ -1375,7 +1371,68 @@ function _createDummyCell() {
     return rst;
 }
 
-function resetStampSignature(pageData, roleRelList, checkAudit = false) {
+function prepareRightFlowRoles(pageData, roleRelList = [], stg_audit = [], ledgerList = []) {
+    // 争取在这里一次过把所有页面的流程签名数据整理完毕,方便后面的工序能简单处理
+    const flowRole = roleRelList.find(role => { return role.type === '流程'; });
+    for (const role of roleRelList) {
+        if (role.type === '流程') role.flowAccList = []; // 这里直接清理流程签名信息
+    }
+    if (flowRole) {
+        const ledgerCache = {}; // 生成台账信息cache对象,提高查找效率
+        ledgerList.forEach(ledger => {
+            ledgerCache[ledger.id] = ledger;
+            ledgerCache[`_${ledger.ledger_id}`] = ledger;
+        })
+        const auditCache = {}; // 生成stage审核cache对象,提高查找效率
+        stg_audit.forEach(audit => {
+            if (audit.audit_type === 4) {
+                auditCache[`_${audit.aid}`] = `${audit.audit_ledger_id}`; // 统一用string类型来判断
+            }
+        });
+        pageData.items.forEach((page, index) => {
+            if (page.extend_flow_options && page.extend_flow_options !== '') {
+                for (const role of roleRelList) {
+                    if (role.type === '流程') {
+                        role.flowAccList.push(-1); // !!! 每一页都要有一个流程签名指引,-1表示没有
+                        let preLen = -1; // 
+                        for (let assIdx = 0; assIdx < role.assFlowInfos.length; assIdx++) {
+                            const assRole = role.assFlowInfos[assIdx];
+                            if (auditCache[`_${assRole.acc_id}`]) {
+                                const ledgerIdStr = `_${auditCache[`_${assRole.acc_id}`]}`;
+                                const rootLedgerPath = ledgerCache[ledgerIdStr].full_path;
+                                const thisLedgerPath = ledgerCache[page.extend_flow_options].full_path || '';
+                                // 这里用了一个取巧的判断,就是子项的code一定完整包括父项的code,且父项code是在最前。
+                                // 万一以后设计有所变化或台账改了,那么得换判断逻辑,目前先让逻辑跑通
+                                if (thisLedgerPath.indexOf(rootLedgerPath) === 0) {
+                                    role.flowAccList[role.flowAccList.length - 1] = assIdx;
+                                    if (thisLedgerPath.length > preLen) {
+                                        preLen = thisLedgerPath.length; // 还要考虑到嵌套的情况
+                                    } else break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            // role.flowAccList
+        });
+    }
+}
+
+function getTheRightRole(role, pageIdx) {
+    let rst = role;
+    if (role.type === '流程') {
+        if (role.flowAccList && role.flowAccList.length > pageIdx) {
+            if (role.flowAccList[pageIdx] !== -1) {
+                rst = role.assFlowInfos[role.flowAccList[pageIdx]];
+            }
+        }
+    }
+    return rst;
+}
+
+function resetStampSignature(pageData, roleRelList, checkAudit = false, stg_audit = [], ledgerList = []) {
+    prepareRightFlowRoles(pageData, roleRelList, stg_audit, ledgerList);
     const dupPicPaths = [];
     const _getMaxRect = function(page) {
         const rect = [100000000, 100000000, 0, 0];
@@ -1388,55 +1445,53 @@ function resetStampSignature(pageData, roleRelList, checkAudit = false) {
         return rect;
     };
 
-    for (const page of pageData.items) {
+    for (let pageIdx = 0; pageIdx < pageData.items.length; pageIdx++) {
+        const page = pageData.items[pageIdx];
         const maxRect = _getMaxRect(page);
         if (page.signature_cells) {
             const newStampCells = [];
             for (let scIdx = 0; scIdx < page.signature_cells.length; scIdx++) {
                 const sCell = page.signature_cells[scIdx];
-                for (const role_rel of roleRelList) {
-                    if (role_rel.type !== '流程') {
-                        if (!checkAudit || rptSignatureHelper._chkIfAudit(role_rel)) {
-                            if (sCell.signature_name === role_rel.signature_name) {
-                                if (Array.isArray(role_rel.sign_output) && role_rel.sign_output.length > 0) {
-                                    for (const signType of role_rel.sign_output) {
-                                        switch (signType) {
-                                            case COMPANY_SIGN_STR:
-                                            case PRIVATE_SIGN_STR:
-                                                // 创建一个新的cell
-                                                let stampPath = (signType === COMPANY_SIGN_STR) ? role_rel.company_stamp_path : role_rel.private_stamp_path;
-                                                stampPath = OSS_PATH + stampPath;
-                                                if (dupPicPaths.indexOf(stampPath) < 0) {
-                                                    dupPicPaths.push(stampPath);
-                                                }
-                                                // 签字信息中如果有签章位置信息,则直接用位置信息
-                                                let signatureArea;
-                                                if (role_rel.areaData && role_rel.areaData[signType]){
-                                                    signatureArea =  role_rel.areaData[signType]
-                                                }
-                                                const newStampCell = {
-                                                    signature_name: JV.SIGNATURE_NAME_DUMMY,
-                                                    control: sCell.control,
-                                                    style: sCell.style,
-                                                    path: stampPath,
-                                                    isStamp: true,
-                                                    maxRect,
-                                                    orgArea: sCell.area,
-                                                    area: signatureArea || {Left: sCell.area.Left, Right: sCell.area.Right, Top: sCell.area.Top, Bottom: sCell.area.Bottom},
-                                                    signatureName: role_rel.signature_name, // 节点名称
-                                                    signType, // 签章信息
-                                                    isSaveSignature: !!signatureArea, // 是否有签章位置信息
-                                                };
-                                                newStampCells.push(newStampCell);
-                                                break;
-                                            default: break;
-                                        }
+                for (const role of roleRelList) {
+                    const role_rel = getTheRightRole(role, pageIdx);
+                    if (!checkAudit || rptSignatureHelper._chkIfAudit(role_rel)) {
+                        if (sCell.signature_name === role_rel.signature_name) {
+                            if (Array.isArray(role_rel.sign_output) && role_rel.sign_output.length > 0) {
+                                for (const signType of role_rel.sign_output) {
+                                    switch (signType) {
+                                        case COMPANY_SIGN_STR:
+                                        case PRIVATE_SIGN_STR:
+                                            // 创建一个新的cell
+                                            let stampPath = (signType === COMPANY_SIGN_STR) ? role_rel.company_stamp_path : role_rel.private_stamp_path;
+                                            stampPath = OSS_PATH + stampPath;
+                                            if (dupPicPaths.indexOf(stampPath) < 0) {
+                                                dupPicPaths.push(stampPath);
+                                            }
+                                            // 签字信息中如果有签章位置信息,则直接用位置信息
+                                            let signatureArea;
+                                            if (role_rel.areaData && role_rel.areaData[signType]){
+                                                signatureArea =  role_rel.areaData[signType]
+                                            }
+                                            const newStampCell = {
+                                                signature_name: JV.SIGNATURE_NAME_DUMMY,
+                                                control: sCell.control,
+                                                style: sCell.style,
+                                                path: stampPath,
+                                                isStamp: true,
+                                                maxRect,
+                                                orgArea: sCell.area,
+                                                area: signatureArea || {Left: sCell.area.Left, Right: sCell.area.Right, Top: sCell.area.Top, Bottom: sCell.area.Bottom},
+                                                signatureName: role_rel.signature_name, // 节点名称
+                                                signType, // 签章信息
+                                                isSaveSignature: !!signatureArea, // 是否有签章位置信息
+                                            };
+                                            newStampCells.push(newStampCell);
+                                            break;
+                                        default: break;
                                     }
                                 }
                             }
                         }
-                    } else {
-                        // 流程数据不一样的判断处理
                     }
                 }
             }
@@ -1457,7 +1512,8 @@ function resetStampSignature(pageData, roleRelList, checkAudit = false) {
 }
 
 function resetTextSignature(pageData, checkAudit = false) {
-    for (const page of pageData.items) {
+    for (let pageIdx = 0; pageIdx < pageData.items.length; pageIdx++) {
+        const page = pageData.items[pageIdx];
         for (let sCell of page.signature_cells) {
             if (!sCell.isStamp) {
                 let fitCell = null;
@@ -1471,19 +1527,16 @@ function resetTextSignature(pageData, checkAudit = false) {
                 if (fitCell) {
                     fitCell.Value = '';
                     for (let role of ROLE_REL_LIST) {
-                        if (role_rel.type !== '流程') {
-                            if (!checkAudit || rptSignatureHelper._chkIfAudit(role)) {
-                                if (sCell.signature_name === role.signature_name) {
-                                    if (role.sign_output && role.sign_output.indexOf(NORMAL_SIGN_STR) >= 0) {
-                                        fitCell.Value = role.user_name;
-                                    } else {
-                                        fitCell.Value = '';
-                                    }
-                                    break;
+                        const role_rel = getTheRightRole(role, pageIdx);
+                        if (!checkAudit || rptSignatureHelper._chkIfAudit(role_rel)) {
+                            if (sCell.signature_name === role_rel.signature_name) {
+                                if (role_rel.sign_output && role_rel.sign_output.indexOf(NORMAL_SIGN_STR) >= 0) {
+                                    fitCell.Value = role_rel.user_name;
+                                } else {
+                                    fitCell.Value = '';
                                 }
+                                break;
                             }
-                        } else {
-                            //
                         }
                     }
                 } else {
@@ -1497,15 +1550,12 @@ function resetTextSignature(pageData, checkAudit = false) {
                     };
                     if (ROLE_REL_LIST) {
                         for (let role of ROLE_REL_LIST) {
-                            if (role_rel.type !== '流程') {
-                                if (!checkAudit || rptSignatureHelper._chkIfAudit(role)) {
-                                    if (sCell.signature_name === role.signature_name && role.sign_output && role.sign_output.indexOf(NORMAL_SIGN_STR) >= 0) {
-                                        newCell.Value = role.user_name;
-                                        break;
-                                    }
+                            const role_rel = getTheRightRole(role, pageIdx);
+                            if (!checkAudit || rptSignatureHelper._chkIfAudit(role_rel)) {
+                                if (sCell.signature_name === role_rel.signature_name && role_rel.sign_output && role_rel.sign_output.indexOf(NORMAL_SIGN_STR) >= 0) {
+                                    newCell.Value = role_rel.user_name;
+                                    break;
                                 }
-                            } else {
-                                //
                             }
                         }
                     }

+ 22 - 0
app/reports/rpt_component/jpc_ex.js

@@ -383,6 +383,8 @@ JpcExSrv.prototype.createNew = function() {
                     mergedBand[JV.BAND_PROP_STYLE] = band[JV.BAND_PROP_STYLE];
                     rst[JV.BAND_PROP_MERGE_BAND] = mergedBand;
                 }
+                // 这里专门为'流程'签字增加处理
+                me.setFlows(rptTpl, dataObj, rst);
             } catch (exception) {
                 console.log(exception);
             } finally {
@@ -391,6 +393,26 @@ JpcExSrv.prototype.createNew = function() {
         }
         return rst;
     };
+    JpcResult.setFlows = function(rptTpl, dataObj, allPageRst) {
+        const me = this;
+        // 专门的'流程'签字处理
+        if (rptTpl[JV.NODE_CUSTOM_DEFINE] && rptTpl[JV.NODE_CUSTOM_DEFINE][JV.NODE_CUS_OPTION]) {
+            const flowStr = rptTpl[JV.NODE_CUSTOM_DEFINE][JV.NODE_CUS_OPTION] || '';
+            if (flowStr.includes('"ledgerFieldId"')) {
+                // 得先判断是否有这个台账ID(判断是含双引号的),毕竟这个选项是通用的
+                const flowObj = JSON.parse(flowStr);
+                if (flowObj.ledgerFieldId) {
+                    const flowField = $JE.F(flowObj.ledgerFieldId, me);
+                    const flowDataField = dataObj[flowField.DataNodeName][flowField.DataSeq];
+                    if (flowDataField) {
+                        for (let pIdx = 0; pIdx < allPageRst.items.length; pIdx++) {
+                            allPageRst.items[pIdx][JV.PROP_EXT_FLOW_OPTIONS] = flowDataField[pIdx] || '';
+                        }
+                    }
+                }
+            }
+        }
+    };
     JpcResult.outputAsSimpleJSONPage = function(rptTpl, dataObj, bands, page, controls, fonts, customizeCfg) {
         const me = this;
         let rst = null;

+ 1 - 0
app/reports/rpt_component/jpc_value_define.js

@@ -328,6 +328,7 @@ module.exports = {
     PROP_SIGNATURE_AUDIT_CELLS: 'signature_audit_cells',
     PROP_INTERACT_CELLS: 'interact_cells',
     PROP_FIGURE_CELLS: 'figure_cells',
+    PROP_EXT_FLOW_OPTIONS: 'extend_flow_options',
 
     PAGING_OPTION_NORMAL: 'normal',
     PAGING_OPTION_INFINITY: 'infinity',

+ 21 - 7
app/service/ledger.js

@@ -139,6 +139,15 @@ module.exports = app => {
 
             return data;
         }
+
+        async getDataOnlyByNodeId(tenderId) {
+            // 这个方法仅仅用来处理'流程签名'用,无需那么多字段
+            const sql = 'SELECT a1.id, a1.ledger_id, a1.ledger_pid, a1.full_path, a1.code, a1.b_code FROM ?? AS a1 WHERE a1.tender_id = ? ORDER BY a1.full_path';
+            const sqlParam = [this.tableName, tenderId];
+            const rst = await this.db.query(sql, sqlParam);
+            return rst;
+        }
+
         /**
          * 根据节点Id获取数据
          * @param {Number} tenderId - 标段Id
@@ -496,7 +505,9 @@ module.exports = app => {
             const lastChild = await this.getLastChildData(tenderId, selectId);
             // 计算id
             const maxId = await this._getMaxLid(tenderId);
-            const insertBillsData = [], insertPosData = [], in_time = new Date();
+            const insertBillsData = [],
+                insertPosData = [],
+                in_time = new Date();
             const order = lastChild ? lastChild.order : 0;
             for (let i = 0, iLen = data.length; i < iLen; i++) {
                 // 合并新增数据
@@ -584,7 +595,9 @@ module.exports = app => {
             const info = this.ctx.tender.info;
             this.transaction = await this.db.beginTransaction();
 
-            const insertBillsData = [], insertPosData = [], in_time = new Date();
+            const insertBillsData = [],
+                insertPosData = [],
+                in_time = new Date();
             const maxId = await this._getMaxLid(tenderId);
             const order = selectData.order;
             for (let i = 0, iLen = data.length; i < iLen; i++) {
@@ -710,7 +723,7 @@ module.exports = app => {
             const YbpTrees = require('../lib/ybp_tree');
             const gatherTreeSetting = {
                 id: 'ledger_id', pid: 'ledger_pid', order: 'order', full_path: 'full_path', level: 'level', rootId: -1,
-                calcFields: [ 'total_price' ],
+                calcFields: ['total_price'],
                 calc(node, helper, decimal) {
                     helper.checkDgnQtyPrecision(node);
                     const precision = helper.findPrecision(tender.info.precision, node.unit);
@@ -730,7 +743,7 @@ module.exports = app => {
 
                 const ybpTree = new YbpTrees.YbpTree(ybpTreeSetting);
                 ybpTree.loadDatas(subject.bills);
-                const loadRelaFun = function (cur, node) {
+                const loadRelaFun = function(cur, node) {
                     if (node.children && node.children.length > 0) return;
 
                     const rations = subject.rations.filter(x => { return x.parentID === node.ID; });
@@ -758,7 +771,8 @@ module.exports = app => {
             gatherTree.sort(false);
             gatherTree.calculateAll();
 
-            const bills = [], glj = [];
+            const bills = [],
+                glj = [];
             for (const n of gatherTree.nodes) {
                 const billsId = this.uuid.v4();
                 const isLeaf = !n.children || n.children.length === 0;
@@ -795,7 +809,7 @@ module.exports = app => {
                         unit: g.unit || '',
                         spec: g.spec || '',
                         quantity: helper.div(g.quantity, n.quantity, 4),
-                    })
+                    });
                 }
             }
             const conn = await this.db.beginTransaction();
@@ -837,7 +851,7 @@ module.exports = app => {
                 return result;
             } catch (err) {
                 await conn.rollback();
-                throw (err.stack ? '导入工程量数据出错': err);
+                throw (err.stack ? '导入工程量数据出错' : err);
             }
         }
 

+ 2 - 2
app/service/stage_audit.js

@@ -1842,8 +1842,8 @@ module.exports = app => {
          * @return {Promise<boolean>}
          */
         async getStageAudit(stageId, times = 1) {
-            // const sql = 'SELECT a1.aid, a1.begin_time, a1.end_time, a1.status, a1.opinion, a1.audit_type, audit_order, a1.audit_ledger_id ' + 'FROM ?? AS a1 ' + 'WHERE a1.`sid` = ? and a1.`times` = ? ' + 'ORDER BY a1.order';
-            const sql = 'SELECT a1.aid, a1.begin_time, a1.end_time, a1.status, a1.opinion ' + 'FROM ?? AS a1 ' + 'WHERE a1.`sid` = ? and a1.`times` = ? ' + 'ORDER BY a1.order';
+            const sql = 'SELECT a1.aid, a1.begin_time, a1.end_time, a1.status, a1.opinion, a1.audit_type, audit_order, a1.audit_ledger_id ' + 'FROM ?? AS a1 ' + 'WHERE a1.`sid` = ? and a1.`times` = ? ' + 'ORDER BY a1.order';
+            // const sql = 'SELECT a1.aid, a1.begin_time, a1.end_time, a1.status, a1.opinion ' + 'FROM ?? AS a1 ' + 'WHERE a1.`sid` = ? and a1.`times` = ? ' + 'ORDER BY a1.order';
             const sqlParam = [this.tableName, stageId, times];
             const rst = await this.db.query(sql, sqlParam);
             return rst;

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

@@ -639,6 +639,7 @@
     let STAGE_AUDIT = [];
     let STAGE_AUDIT_ORG = [];
     let STAGE_FLOW = [];
+    let LEDGER_LIST = [];
     let ROLE_REL_LIST = [];
     let CURRENT_ROLE_REL_ID = -1;
     let current_stage_order = -1;