Переглянути джерело

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

MaiXinRong 5 роки тому
батько
коміт
51648a7cc0

+ 64 - 6
app/controller/report_controller.js

@@ -27,7 +27,7 @@ module.exports = app => {
                 const tender = ctx.tender;
                 const stage = ctx.stage;
                 // console.log(tender.data);
-                // console.log(stage);
+                // console.log(tender.info);
                 let stage_id = -1;
                 let stage_order = -1;
                 let stage_times = -1;
@@ -55,6 +55,7 @@ module.exports = app => {
                     cust_cfg: JSON.stringify(custCfg),
                     project_id: tender.data.project_id,
                     tender_id: tender.id,
+                    tender_name: tender.data.name,
                     stg_id: stage_id,
                     stg_order: stage_order,
                     stg_times: stage_times,
@@ -154,9 +155,6 @@ module.exports = app => {
             const params = JSON.parse(ctx.request.body.params);
             const baseDir = this.app.baseDir;
             function getExcelByPageData(pageRst, rpt_name, innerRoleRel) {
-                // console.log('in getExcelByPageData!');
-                // console.log(innerRoleRel);
-                // console.log('rpt_name: ' + rpt_name);
                 return new Promise(function(resolve, reject) {
                     rpt_xl_util.exportExcel(pageRst, params.pageSize, rpt_name, params.isOneSheet, null, null, baseDir, innerRoleRel,
                         (err, uuidName) => {
@@ -179,7 +177,7 @@ module.exports = app => {
                     }
                 }
                 // console.log('roleRel.rel_content: ' + roleRel.rel_content);
-                fsUtil.writeObjToFile(pageRstArr, 'D:/GitHome/temp/testBuiltPageResult.jsp');
+                // fsUtil.writeObjToFile(pageRstArr, 'D:/GitHome/temp/testBuiltPageResult.jsp');
                 runnableRst.push(getExcelByPageData(pageRstArr[idx], params.rpt_names[idx], roleRel));
             }
             const uuidRst = await Promise.all(runnableRst);
@@ -187,6 +185,66 @@ module.exports = app => {
             ctx.status = 201;
         }
 
+        async createExcelFilesInOneBookEx(ctx) {
+            const params = JSON.parse(ctx.request.body.params);
+            const baseDir = this.app.baseDir;
+            function getExcelByPageData(pageRstArr, rpt_name, innerRoleRel) {
+                return new Promise(function(resolve, reject) {
+                    rpt_xl_util.exportExcelInOneBook(pageRstArr, params.pageSize, rpt_name, baseDir, innerRoleRel,
+                        (err, uuidName) => {
+                            if (err) return reject(err);
+                            const fileRst = { uuid: uuidName, reportName: rpt_name };
+                            resolve(fileRst);
+                        }
+                    );
+                });
+            }
+            const roleRelArr = await ctx.service.roleRptRel.getRoleRptRelByDetailIds(params.tender_id, params.rpt_ids);
+            const pageRstArr = await getMultiRptsCommon(ctx, params, JV.OUTPUT_TYPE_NORMAL);
+            const runnableRst = [];
+            let rptRoleRelArr = [];
+            const reAssignSignatureName = function(pageData, roleRel, rpt_name_key) {
+                const keyMap = {};
+                for (const pageItem of pageData.items) {
+                    for (const signCell of pageItem[JV.PROP_SIGNATURE_CELLS]) {
+                        if (!keyMap.hasOwnProperty(signCell.signature_name)) {
+                            keyMap[signCell.signature_name] = rpt_name_key + '_' + signCell.signature_name;
+                        }
+                    }
+                }
+                for (const pageItem of pageData.items) {
+                    for (const signCell of pageItem[JV.PROP_SIGNATURE_CELLS]) {
+                        if (keyMap.hasOwnProperty(signCell.signature_name)) {
+                            signCell.signature_name = keyMap[signCell.signature_name];
+                        }
+                    }
+                }
+                for (const roleSign of roleRel) {
+                    if (keyMap.hasOwnProperty(roleSign.signature_name)) {
+                        roleSign.signature_name = keyMap[roleSign.signature_name];
+                    }
+                }
+                // console.log('keyMap of : ' + rpt_name_key);
+                // console.log(keyMap);
+            };
+            for (let idx = 0; idx < pageRstArr.length; idx++) {
+                let roleRel = null;
+                for (const roleR of roleRelArr) {
+                    if (roleR.rpt_id === params.rpt_ids[idx]) {
+                        roleRel = JSON.parse(roleR.rel_content);
+                        // 这里要做些电子签名的signature_name转换,以防重名
+                        reAssignSignatureName(pageRstArr[idx], roleRel, params.rpt_names[idx]);
+                        rptRoleRelArr = rptRoleRelArr.concat(roleRel);
+                        break;
+                    }
+                }
+            }
+            runnableRst.push(getExcelByPageData(pageRstArr, params.rptName, rptRoleRelArr));
+            const uuidRst = await Promise.all(runnableRst);
+            ctx.body = { data: uuidRst };
+            ctx.status = 201;
+        }
+
         async getFileByUUID(ctx) {
             // console.log('downloading : ' + ctx.params.uuid);
             const uuid = ctx.params.uuid;
@@ -318,7 +376,7 @@ async function getMultiRptsCommon(ctx, params, outputType) {
     for (let idx = 0; idx < params.rpt_ids.length; idx++) {
         params.rpt_ids[idx] = parseInt(params.rpt_ids[idx]); // 转换一下,以防万一
     }
-    const rptTpls = await ctx.service.rptTpl.getTplById(params.rpt_ids);
+    const rptTpls = await ctx.service.rptTpl.getAllTplByIds(params.rpt_ids);
     // console.log(rptTpls);
     for (let rtIdx = 0; rtIdx < rptTpls.length; rtIdx++) {
         rptTpls[rtIdx] = JSON.parse(rptTpls[rtIdx].rpt_content);

+ 31 - 24
app/public/js/measure_material.js

@@ -19,12 +19,12 @@ $(function () {
             const auditHistory = result.auditHistory;
             // 生成左边列表流程
             const lefthtml = [];
-            lefthtml.push('<li class="list-group-item"><i class="fa fa fa-play-circle fa-rotate-90"></i> '+ materialAuditor.name +'  <small class="text-muted">'+ materialAuditor.role +'</small></li>');
+            lefthtml.push('<li class="list-group-item"><i class="fa fa fa-play-circle fa-rotate-90"></i> '+ materialAuditor.name +'  <small class="text-muted">'+ materialAuditor.role +'</small><span class="pull-right">原报</span></li>');
             for (const [index,a] of auditors.entries()) {
                 if (index+1 === auditors.length) {
-                    lefthtml.push('<li class="list-group-item"><i class="fa fa-stop-circle"></i> '+ a.name +'  <small class="text-muted">'+ a.role +'</small></li>');
+                    lefthtml.push('<li class="list-group-item"><i class="fa fa-stop-circle"></i> '+ a.name +'  <small class="text-muted">'+ a.role +'</small><span class="pull-right">终审</span></li>');
                 } else {
-                    lefthtml.push('<li class="list-group-item"><i class="fa fa-chevron-circle-down"></i> '+ a.name +'  <small class="text-muted">'+ a.role +'</small></li>');
+                    lefthtml.push('<li class="list-group-item"><i class="fa fa-chevron-circle-down"></i> '+ a.name +'  <small class="text-muted">'+ a.role +'</small><span class="pull-right">' + transFormToChinese(index+1) + '审</span></li>');
                 }
             }
             $('#auditor-list').html(lefthtml.join(''));
@@ -36,41 +36,48 @@ $(function () {
                 for (let iA = 0; iA < ah.length; iA++) {
                     if (iA === 0) {
                         righthtml.push('<li class="list-group-item">');
-                        righthtml.push('<span class="text-success pull-right">'+ (auditHistory.indexOf(ah) > 0 ? '重新' : '') +'上报</span>');
                         righthtml.push('<h5 class="card-title">');
-                        righthtml.push('<i class="fa fa-play-circle fa-rotate-90 text-success"></i> '+ materialAuditor.name +' <small class="text-muted">'+ materialAuditor.role +'</small></h5>');
-                        righthtml.push('<p class="card-text"><small class="text-muted">' + (ah[iA].begin_time ? moment(ah[iA].begin_time).format('YYYY-MM-DD') : '') + '</small></p></li>');
+                        righthtml.push('<i class="fa fa-play-circle fa-rotate-90 text-success"></i> '+ materialAuditor.name +' <small class="text-muted">'+ materialAuditor.role +'</small><span class="pull-right">原报</span></h5>');
+                        righthtml.push('<div class="ml-3">');
+                        righthtml.push('<span class="text-success"><small>' + (ah[iA].begin_time ? moment(ah[iA].begin_time).format('YYYY-MM-DD') : '') + '</small>'+ (auditHistory.indexOf(ah) > 0 ? '重新' : '') + '上报</span>');
+                        righthtml.push('</div></li>');
                         righthtml.push('<li class="list-group-item">');
+                        righthtml.push('<h5 class="card-title"><i class="fa '+ (iA === ah.length - 1 ? 'fa-stop-circle ' : 'fa-chevron-circle-down ') + auditConst.statusClass[ah[iA].status] +'"></i> '+ ah[iA].name +' <small class="text-muted">'+ ah[iA].role +'</small><span class="pull-right">' + (ah[iA].sort === ah[iA].max_sort ? '终' : transFormToChinese(ah[iA].sort)) + '审</span></h5>');
+                        righthtml.push('<div class="ml-3">');
                         if (ah[iA].status !== auditConst.status.uncheck) {
-                            righthtml.push('<span class="'+ auditConst.statusClass[ah[iA].status] +' pull-right">' + auditConst.statusString[ah[iA].status] + (ah[iA].status === auditConst.status.checkNo ? ' ' + materialAuditor.name : '') + '</span>');
-                        }
-                        righthtml.push('<h5 class="card-title"><i class="fa '+ (iA === ah.length - 1 ? 'fa-stop-circle ' : 'fa-chevron-circle-down ') + auditConst.statusClass[ah[iA].status] +'"></i> '+ ah[iA].name +' <small class="text-muted">'+ ah[iA].role +'</small></h5>');
-                        if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) {
-                            righthtml.push('<p class="card-text mb-1">'+ ah[iA].opinion +'</p>');
-                            righthtml.push('<p class="card-text"><small class="text-muted">'+ (ah[iA].end_time ? moment(ah[iA].end_time).format('YYYY-MM-DD') : '') +'</small></p>');
+                            let timeHtml = '';
+                            if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) {
+                                timeHtml = '<small>'+ (ah[iA].end_time ? moment(ah[iA].end_time).format('YYYY-MM-DD') : '') +'</small> ';
+                            }
+                            righthtml.push('<span class="'+ auditConst.statusClass[ah[iA].status] +'">' + timeHtml + auditConst.statusString[ah[iA].status] + (ah[iA].status === auditConst.status.checkNo ? ' ' + materialAuditor.name : '') + '</span>');
                         }
+                        righthtml.push('<p class="card-text">'+ (ah[iA].opinion !== null ? ah[iA].opinion : '') +'</p></div>');
                         righthtml.push('</li>');
                     } else if (iA === ah.length - 1) {
                         righthtml.push('<li class="list-group-item">');
+                        righthtml.push('<h5 class="card-title"><i class="fa fa-stop-circle '+ auditConst.statusClass[ah[iA].status] +'"></i> '+ ah[iA].name +' <small class="text-muted">'+ ah[iA].role +'</small><span class="pull-right">终审</span></h5>');
+                        righthtml.push('<div class="ml-3">');
                         if (ah[iA].status !== auditConst.status.uncheck) {
-                            righthtml.push('<span class="'+ auditConst.statusClass[ah[iA].status] +' pull-right">' + auditConst.statusString[ah[iA].status] + (ah[iA].status === auditConst.status.checkNo ? ' ' + materialAuditor.name : '') + '</span>');
-                        }
-                        righthtml.push('<h5 class="card-title"><i class="fa fa-stop-circle '+ auditConst.statusClass[ah[iA].status] +'"></i> '+ ah[iA].name +' <small class="text-muted">'+ ah[iA].role +'</small></h5>');
-                        if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) {
-                            righthtml.push('<p class="card-text mb-1">'+ ah[iA].opinion +'</p>');
-                            righthtml.push('<p class="card-text"><small class="text-muted">'+ (ah[iA].end_time ? moment(ah[iA].end_time).format('YYYY-MM-DD') : '') +'</small></p>');
+                            let timeHtml = '';
+                            if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) {
+                                timeHtml = '<small>'+ (ah[iA].end_time ? moment(ah[iA].end_time).format('YYYY-MM-DD') : '') +'</small> ';
+                            }
+                            righthtml.push('<span class="'+ auditConst.statusClass[ah[iA].status] +'">' + timeHtml + auditConst.statusString[ah[iA].status] + (ah[iA].status === auditConst.status.checkNo ? ' ' + materialAuditor.name : '') + '</span>');
                         }
+                        righthtml.push('<p class="card-text">'+ (ah[iA].opinion !== null ? ah[iA].opinion : '') +'</p></div>');
                         righthtml.push('</li>');
                     } else {
                         righthtml.push('<li class="list-group-item">');
+                        righthtml.push('<h5 class="card-title"><i class="fa '+ (iA === ah.length - 1 ? 'fa-stop-circle ' : 'fa-chevron-circle-down ') + auditConst.statusClass[ah[iA].status] +'"></i> '+ ah[iA].name +' <small class="text-muted">'+ ah[iA].role +'</small><span class="pull-right">' + (ah[iA].sort === ah[iA].max_sort ? '终' : transFormToChinese(ah[iA].sort)) + '审</span></h5>');
+                        righthtml.push('<div class="ml-3">');
                         if (ah[iA].status !== auditConst.status.uncheck) {
-                            righthtml.push('<span class="'+ auditConst.statusClass[ah[iA].status] +' pull-right">' + auditConst.statusString[ah[iA].status] + (ah[iA].status === auditConst.status.checkNo ? ' ' + materialAuditor.name : '') + '</span>');
-                        }
-                        righthtml.push('<h5 class="card-title"><i class="fa fa-chevron-circle-down '+ auditConst.statusClass[ah[iA].status] +'"></i> '+ ah[iA].name +' <small class="text-muted">'+ ah[iA].role +'</small></h5>');
-                        if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) {
-                            righthtml.push('<p class="card-text mb-1">'+ ah[iA].opinion +'</p>');
-                            righthtml.push('<p class="card-text"><small class="text-muted">'+ (ah[iA].end_time ? moment(ah[iA].end_time).format('YYYY-MM-DD') : '') +'</small></p>');
+                            let timeHtml = '';
+                            if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) {
+                                timeHtml = '<small>'+ (ah[iA].end_time ? moment(ah[iA].end_time).format('YYYY-MM-DD') : '') +'</small> ';
+                            }
+                            righthtml.push('<span class="'+ auditConst.statusClass[ah[iA].status] +'">' + timeHtml + auditConst.statusString[ah[iA].status] + (ah[iA].status === auditConst.status.checkNo ? ' ' + materialAuditor.name : '') + '</span>');
                         }
+                        righthtml.push('<p class="card-text">'+ (ah[iA].opinion !== null ? ah[iA].opinion : '') +'</p></div>');
                         righthtml.push('</li>');
                     }
                 }

+ 3 - 3
app/public/js/measure_stage.js

@@ -50,7 +50,7 @@ $('a[data-target="#sp-list" ]').on('click', function () {
                        }
                        righthtml.push('<span class="' + auditConst.statusClass[ah[iA].status] +'">'+ timeHtml + auditConst.statusString[ah[iA].status] + (ah[iA].status === auditConst.status.checkNo ? ' ' + stageAuditor.name : '') + '</span>');
                    }
-                   righthtml.push('<p class="card-text">'+ ah[iA].opinion !== null ? ah[iA].opinion : '' +'</p></div>');
+                   righthtml.push('<p class="card-text">'+ (ah[iA].opinion !== null ? ah[iA].opinion : '') +'</p></div>');
                    righthtml.push('</li>');
                } else if (iA === ah.length - 1) {
                    righthtml.push('<li class="list-group-item">');
@@ -63,7 +63,7 @@ $('a[data-target="#sp-list" ]').on('click', function () {
                        }
                        righthtml.push('<span class="' + auditConst.statusClass[ah[iA].status] +'">' + timeHtml + auditConst.statusString[ah[iA].status] + (ah[iA].status === auditConst.status.checkNo ? ' ' + stageAuditor.name : '') + '</span>');
                    }
-                   righthtml.push('<p class="card-text">'+ ah[iA].opinion !== null ? ah[iA].opinion : '' +'</p></div>');
+                   righthtml.push('<p class="card-text">'+ (ah[iA].opinion !== null ? ah[iA].opinion : '') +'</p></div>');
                    righthtml.push('</li>');
                } else {
                    righthtml.push('<li class="list-group-item">');
@@ -76,7 +76,7 @@ $('a[data-target="#sp-list" ]').on('click', function () {
                        }
                        righthtml.push('<span class="' + auditConst.statusClass[ah[iA].status] +'">'+ timeHtml + auditConst.statusString[ah[iA].status] + (ah[iA].status === auditConst.status.checkNo ? ' ' + stageAuditor.name : '') + '</span>');
                    }
-                   righthtml.push('<p class="card-text">'+ ah[iA].opinion !== null ? ah[iA].opinion : '' +'</p></div>');
+                   righthtml.push('<p class="card-text">'+ (ah[iA].opinion !== null ? ah[iA].opinion : '') +'</p></div>');
                    righthtml.push('</li>');
                }
            }

+ 16 - 39
app/public/report/js/rpt_main.js

@@ -458,45 +458,22 @@ let rptControlObj = {
     getAllInOneBook: function () {
         if (zTreeOprObj.checkedRptTplNodes && zTreeOprObj.checkedRptTplNodes.length > 0) {
             let me = rptControlObj;
-            let orgRptName = projectObj.project.projectInfo.name;
-            let refRptTplIds = [], refBillSumPrjsIds = [], refGljSumPrjsIds = [];
-            rptControlObj.getTplIdsCommon(refRptTplIds, refBillSumPrjsIds, refGljSumPrjsIds);
-            if (zTreeOprObj.selectedPrjIDs.length > 0 && (refBillSumPrjsIds.length > 0 || refGljSumPrjsIds.length > 0)) {
-                let params = rptControlObj.creatCommonExportParam(refRptTplIds, refBillSumPrjsIds, refGljSumPrjsIds);
-                params.rptName = orgRptName;
-
-                CommonAjax.postEx("report_api/createExcelFilesInOneBook", params, WAIT_TIME_EXPORT, true, function(result){
-                        if (result) {
-                            let uuIdUrls = [];
-                            let uuIdUrl =  "/report_api/getFileByUUID/" + result.uuid + "/" + stringUtil.replaceAll(result.reportName, "#", "_") + "/xlsx";
-                            uuIdUrls.push(uuIdUrl);
-                            downloadReport(uuIdUrls);
-                        } else {
-                            //
-                        }
-                    }, null, null
-                );
-            } else {
-                let params = {};
-                params.prj_id = PROJECT_ID;
-                params.rpt_ids = refRptTplIds;
-                params.rptName = orgRptName;
-                params.pageSize = me.getCurrentPageSize();
-                params.orientation = ((zTreeOprObj.checkedRptTplNodes.length > 1)?null:me.getCurrentOrientation());
-                params.custCfg = CUST_CFG;
-                params.option = "normal";
-                CommonAjax.postEx("report_api/createExcelFilesInOneBook", params, WAIT_TIME_EXPORT, true, function(result){
-                        if (result) {
-                            let uuIdUrls = [];
-                            let uuIdUrl =  "/report_api/getFileByUUID/" + result.uuid + "/" + stringUtil.replaceAll(result.reportName, "#", "_") + "/xlsx";
-                            uuIdUrls.push(uuIdUrl);
-                            downloadReport(uuIdUrls);
-                        } else {
-                            //
-                        }
-                    }, null, null
-                );
-            }
+            let refRptTplIds = [], rpt_sheet_names = [];
+            rptControlObj.getTplIdsCommon(refRptTplIds, rpt_sheet_names);
+            let params = rptControlObj.creatCommonExportParam(refRptTplIds);
+            params.rpt_names = rpt_sheet_names;
+            params.rptName = TENDER_NAME;
+            CommonAjax.postXsrfEx("/tender/report_api/createExcelFilesInOneBook", params, 60000, true, getCookie('csrfToken'), function(result){
+                    if (result) {
+                        let uuIdUrls = [];
+                        let uuIdUrl =  "/getFileByUUID/" + result.data[0].uuid + "/" + stringUtil.replaceAll(result.data[0].reportName, "#", "_") + "/xlsx";
+                        uuIdUrls.push(uuIdUrl);
+                        downloadReport(uuIdUrls);
+                    } else {
+                        //
+                    }
+                }, null, null
+            );
         }
     },
     getAllIndividualExcelBook: function () {

+ 0 - 3
app/reports/rpt_component/helper/jpc_helper_discrete.js

@@ -11,9 +11,6 @@ const JpcDiscreteHelper = {
     outputDiscreteInfo: function(discreteArray, bands, dataObj, unitFactor, pageStatus, segIdx, multiCols, multiColIdx, $CURRENT_RPT, customizeCfg, signatureRst, signatureDateRst) {
         const rst = [];
         if (discreteArray && dataObj) {
-            if (Array.isArray(signatureRst)) {
-                signatureRst.splice(0, signatureRst.length);
-            }
             for (let i = 0; i < discreteArray.length; i++) {
                 const band = bands[discreteArray[i][JV.PROP_BAND_NAME]];
                 if (band && pageStatus[band[JV.BAND_PROP_DISPLAY_TYPE]] === true) {

+ 3 - 2
app/reports/rpt_component/jpc_flow_tab.js

@@ -771,6 +771,9 @@ JpcFlowTabSrv.prototype.createNew = function() {
         const tabRstLst = [];
         const FLOW_NODE_STR = me.isEx ? JV.NODE_FLOW_INFO_EX : JV.NODE_FLOW_INFO;
         const unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
+        // 电子签名内容需要先清空
+        me.signatureRst = [];
+        me.signatureDateRst = [];
         if (me.paging_option === JV.PAGING_OPTION_INFINITY) {
             const segIdx = page - 1;
             // 1 calculate the band position
@@ -827,8 +830,6 @@ JpcFlowTabSrv.prototype.createNew = function() {
                 // 2.6 Discrete
                 if (pi === 0) {
                     tabRstLst.push(JpcDiscreteHelper.outputDiscreteInfo(rptTpl[FLOW_NODE_STR][JV.NODE_DISCRETE_INFO], bands, dataObj, unitFactor, me.pageStatusLst[actualPage - 1], segIdx, 1, pi, $CURRENT_RPT, customizeCfg, me.signatureRst, me.signatureDateRst));
-                    // console.log('current page: ' + page);
-                    // console.log(me.signatureRst);
                 }
             }
         }

+ 150 - 71
app/reports/util/rpt_excel_util.js

@@ -11,6 +11,7 @@ const DPI = jpcCmnHelper.getScreenDPI()[0];
 const fsUtil = require('../public/fsUtil');
 const dftHeadXml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
 const uuidV1 = require('uuid/v1');
+const atob = require('atob');
 
 function writeContentTypes(sheets, isSinglePage, hasSignature) {
     const rst = [];
@@ -330,7 +331,7 @@ function writeSharedString(sharedStrList) {
     }
     return rst;
 }
-function writeSheets(pageData, paperSize, sharedStrList, stylesObj, isSinglePage, custSheetMergeBands, hasSignature) {
+function writeSheets(pageData, paperSize, sharedStrList, stylesObj, isSinglePage, custSheetMergeBands, hasSignature, signSheetIdxArr) {
     const rst = [];
     const private_pushDftFont = function() {
         const font = {};
@@ -373,14 +374,14 @@ function writeSheets(pageData, paperSize, sharedStrList, stylesObj, isSinglePage
     private_buildFirstDftStyle();
     let sheetIdx = 0;
     if (isSinglePage) {
-        rst.push(writeSheet(pageData, null, paperSize, sharedStrList, stylesObj, null, hasSignature, sheetIdx));
+        rst.push(writeSheet(pageData, null, paperSize, sharedStrList, stylesObj, null, hasSignature, sheetIdx, signSheetIdxArr));
     } else {
         for (let i = 0; i < pageData.items.length; i++) {
             let appointedMergeBand = null;
             if (custSheetMergeBands && custSheetMergeBands.length > i) {
                 appointedMergeBand = custSheetMergeBands[i];
             }
-            rst.push(writeSheet(pageData, pageData.items[i], paperSize, sharedStrList, stylesObj, appointedMergeBand, hasSignature, sheetIdx));
+            rst.push(writeSheet(pageData, pageData.items[i], paperSize, sharedStrList, stylesObj, appointedMergeBand, hasSignature, sheetIdx, signSheetIdxArr));
             sheetIdx++;
         }
     }
@@ -476,7 +477,7 @@ function preAnalyzePos(pageData, sheetData, xPos, yPos, yMultiPos) {
     xPos.push(0);
     if (sheetData) {
         // current sheet data
-        console.log('preAnalyzePos not single');
+        // console.log('preAnalyzePos not single');
         yPos.push(0);
         self_analyze_sheet_pos(sheetData, xPos, yPos);
         xPos.sort(private_array_sort);
@@ -504,7 +505,7 @@ function preAnalyzePos(pageData, sheetData, xPos, yPos, yMultiPos) {
         }
     }
 }
-function writeSheet(pageData, sheetData, paperSize, sharedStrList, stylesObj, appointedMergeBand, hasSignature, sheetIdx) {
+function writeSheet(pageData, sheetData, paperSize, sharedStrList, stylesObj, appointedMergeBand, hasSignature, sheetIdx, signSheetIdxArr) {
     const rst = [];
     const xPos = [];
     const yPos = [];
@@ -706,7 +707,7 @@ function writeSheet(pageData, sheetData, paperSize, sharedStrList, stylesObj, ap
     const private_checkControl = function(cellControl, sheetControl) {
         let rst = true;
         for (let i = 0; i < JV.CONTROL_PROPS.length; i++) {
-            if (cellControl[JV.CONTROL_PROPS[i]] != sheetControl[JV.CONTROL_PROPS[i]]) {
+            if (cellControl[JV.CONTROL_PROPS[i]] !== sheetControl[JV.CONTROL_PROPS[i]]) {
                 rst = false;
                 break;
             }
@@ -783,7 +784,7 @@ function writeSheet(pageData, sheetData, paperSize, sharedStrList, stylesObj, ap
                     cnt++;
                 }
             }
-        }
+        };
         if (sheetData) {
             self_setMergedCells(sheetData, yPos, 0);
         } else {
@@ -924,17 +925,24 @@ function writeSheet(pageData, sheetData, paperSize, sharedStrList, stylesObj, ap
     }
     rst.push('<pageSetup ' + pStr + ' fitToWidth="0" fitToHeight="0" orientation="' + orientationStr + '" />');
     rst.push('<headerFooter alignWithMargins="0"/>');
-    if (hasSignature) {
-        rst.push('<drawing r:id="rId' + (sheetIdx + 1) + '"/>');
+    if (hasSignature && signSheetIdxArr[sheetIdx]) {
+        // let rIdx = 1;
+        // for (let ssIdx = 0; ssIdx < signSheetIdxArr.length; ssIdx++) {
+        //     if (signSheetIdxArr[ssIdx]) {
+        //         if (ssIdx < sheetIdx) rIdx++
+        //         else break;
+        //     }
+        // }
+        rst.push('<drawing r:id="rId1"/>');
     }
     rst.push('</worksheet>');
     return rst;
 }
-function writeWorkSheetRels(sheetIdx) {
+function writeWorkSheetRels(signSheetIdx) {
     const rst = [];
     rst.push('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
     rst.push('<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">');
-    rst.push('<Relationship Id="rId' + (sheetIdx + 1) + '" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing" Target="../drawings/drawing' + (sheetIdx + 1) + '.xml"/>');
+    rst.push('<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing" Target="../drawings/drawing' + signSheetIdx + '.xml"/>');
     rst.push('</Relationships>');
     return rst;
 }
@@ -942,26 +950,29 @@ function writeImage(path, pic, baseDir) {
     let rst = null;
     if (pic) {
         // 这里pic的数据就是base64的,不能是其他
-        rst = base64ToStream(pic);
+        rst = base64ToBuffer(pic);
+        // fs.createReadStream
     } else if (path) {
         const filePath = baseDir + '/app' + path;
         rst = fs.readFileSync(filePath);
     }
     return rst;
 }
-function writeDrawings(pageData, signKeyArr, signPathArr, isSinglePage) {
+function writeDrawings(pageData, signKeyArr, signPathArr, isSinglePage, signSheetIdxArr) {
     const rst = [];
     console.log('isSinglePage: ' + isSinglePage);
     if (isSinglePage) {
-        rst.push(writeDrawing(pageData, null, signKeyArr, signPathArr, 0));
+        rst.push(writeDrawing(pageData, null, signKeyArr[0]));
     } else {
         for (let i = 0; i < pageData.items.length; i++) {
-            rst.push(writeDrawing(pageData, pageData.items[i], signKeyArr, signPathArr, i));
+            if (signSheetIdxArr[i]) {
+                rst.push(writeDrawing(pageData, pageData.items[i], signKeyArr[i]));
+            }
         }
     }
     return rst;
 }
-function writeDrawing(pageData, sheetData, signKeyArr, signPathArr, sheetIdx) {
+function writeDrawing(pageData, sheetData, subSignKeyArr) {
     const rst = [];
     const xPos = [];
     const yPos = [];
@@ -1013,7 +1024,7 @@ function writeDrawing(pageData, sheetData, signKeyArr, signPathArr, sheetIdx) {
         // 3.2
         rst.push('<xdr:blipFill>');
         // 重点!!!
-        const picIdx = signKeyArr.indexOf(signCell.signature_name) + 1;
+        const picIdx = subSignKeyArr.indexOf(signCell.signature_name) + 1;
         // 3.2.1
         rst.push('<a:blip xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:embed="rId' + picIdx + '" cstate="print">');
         rst.push('<a:extLst>');
@@ -1036,7 +1047,7 @@ function writeDrawing(pageData, sheetData, signKeyArr, signPathArr, sheetIdx) {
         rst.push('<a:ext cx="0" cy="0"/>');
         rst.push('</a:xfrm>');
         // 3.3.2
-        rst.push('<a:prstGeom prst="rect"><a:avLst/></a:prstGeom>')
+        rst.push('<a:prstGeom prst="rect"><a:avLst/></a:prstGeom>');
         // 3.3.3
         rst.push('<a:noFill/>');
         // 3.3.4
@@ -1053,14 +1064,14 @@ function writeDrawing(pageData, sheetData, signKeyArr, signPathArr, sheetIdx) {
         // 4. client Data
         rst.push('<xdr:clientData/>');
         rst.push('</xdr:twoCellAnchor>');
-    }
+    };
     preAnalyzePos(pageData, sheetData, xPos, yPos, yMultiPos);
     rst.push('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
     rst.push('<xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">');
     if (sheetData) {
         let startPicIdx = 2;
         for (const sCell of sheetData[JV.PROP_SIGNATURE_CELLS]) {
-            if (signKeyArr.indexOf(sCell.signature_name) >= 0) {
+            if (subSignKeyArr.indexOf(sCell.signature_name) >= 0) {
                 private_setSheetDrawingCellData(sCell, yPos, startPicIdx, 0);
                 startPicIdx++;
             }
@@ -1073,7 +1084,7 @@ function writeDrawing(pageData, sheetData, signKeyArr, signPathArr, sheetIdx) {
             const tmpPos = yMultiPos[i];
             let startPicIdx = 2;
             for (const sCell of shtItemData[JV.PROP_SIGNATURE_CELLS]) {
-                if (signKeyArr.indexOf(sCell.signature_name) >= 0) {
+                if (subSignKeyArr.indexOf(sCell.signature_name) >= 0) {
                     private_setSheetDrawingCellData(sCell, tmpPos, startPicIdx, rowOffset);
                     startPicIdx++;
                 }
@@ -1084,12 +1095,12 @@ function writeDrawing(pageData, sheetData, signKeyArr, signPathArr, sheetIdx) {
     rst.push('</xdr:wsDr>');
     return rst;
 }
-function writeDrawingsRels(amt) {
+function writeDrawingsRels(amt, startIdx) {
     const rst = [];
     rst.push('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
     rst.push('<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">');
     for (let idx = 0; idx < amt; idx++) {
-        rst.push('<Relationship Id="rId' + (idx + 1) + '" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/image' + (idx + 1) + '.png"/>');
+        rst.push('<Relationship Id="rId' + (idx + 1) + '" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/image' + (startIdx + idx + 1) + '.png"/>');
     }
     rst.push('</Relationships>');
     return rst;
@@ -1110,7 +1121,7 @@ function mergeProperties(orgObj, newObj) {
         }
     }
 }
-function checkAndSetSignatureCache(pageData, signKeyArr, signPathArr, roleRel) {
+function checkAndSetSignatureCache(pageData, signKeyArr, signPathArr, roleRel, signSheetIdxArr) {
     // 备注:电子签名是以图形的方式处理,一页可以有多个签名,多页的签名基本是引用同样的图片,在这里先处理一下,后期统一引用。
     //      另:以后的图片(在电子签名(signature_cells)以外的图片)会单独处理(如计算图等)
     let rst = false;
@@ -1121,33 +1132,43 @@ function checkAndSetSignatureCache(pageData, signKeyArr, signPathArr, roleRel) {
         chkRoles.push(roleRel);
     }
     // console.log(chkRoles);
-    for (const page of pageData.items) {
+    // console.log(signKeyArr);
+    // for (const page of pageData.items) {
+    for (let pageIdx = 0; pageIdx < pageData.items.length; pageIdx++) {
+        const page = pageData.items[pageIdx];
+        signKeyArr.push([]);
+        signPathArr.push([]);
+        signSheetIdxArr[pageIdx] = false;
         if (page[JV.PROP_SIGNATURE_CELLS] && page[JV.PROP_SIGNATURE_CELLS].length > 0) {
-            // console.log('has SignatureCells!');
+            // console.log('page index: ' + pageIdx);
+            // console.log(page[JV.PROP_SIGNATURE_CELLS]);
             for (const signature of page[JV.PROP_SIGNATURE_CELLS]) {
-                if (signKeyArr.indexOf(signature.signature_name) < 0) {
+                if (signKeyArr[pageIdx].indexOf(signature.signature_name) < 0) {
                     if (signature.pic) {
                         const signPath = { path: null, pic: null };
-                        signPathArr.push(signPath);
+                        signPathArr[pageIdx].push(signPath);
                         signPath.pic = signature.pic; // 历史报表
-                        signKeyArr.push(signature.signature_name);
+                        signKeyArr[pageIdx].push(signature.signature_name);
                         rst = true;
+                        signSheetIdxArr[pageIdx] = true;
                     } else {
                         for (const role of chkRoles) {
                             if (signature.signature_name === role.signature_name) {
                                 // console.log('signature.signature_name: ' + signature.signature_name);
                                 if (role.sign_pic) {
                                     const signPath = { path: null, pic: null };
-                                    signPathArr.push(signPath);
+                                    signPathArr[pageIdx].push(signPath);
                                     signPath.pic = role.sign_pic;
-                                    signKeyArr.push(signature.signature_name);
+                                    signKeyArr[pageIdx].push(signature.signature_name);
                                     rst = true;
+                                    signSheetIdxArr[pageIdx] = true;
                                 } else if (role.sign_path) {
                                     const signPath = { path: null, pic: null };
-                                    signPathArr.push(signPath);
+                                    signPathArr[pageIdx].push(signPath);
                                     signPath.path = role.sign_path;
-                                    signKeyArr.push(signature.signature_name);
+                                    signKeyArr[pageIdx].push(signature.signature_name);
                                     rst = true;
+                                    signSheetIdxArr[pageIdx] = true;
                                 }
                                 break;
                             }
@@ -1159,19 +1180,14 @@ function checkAndSetSignatureCache(pageData, signKeyArr, signPathArr, roleRel) {
     }
     return rst;
 }
-function base64ToStream(dataurl) {
-    // 将base64转换为
+function base64ToBuffer(dataurl) {
+    // 将base64转换为buffer
     const arr = dataurl.split(',');
-    const bstr = atob(arr[1]);
-    let n = bstr.length;
-    const u8arr = new Uint8Array(n);
-    while (n--) {
-        u8arr[n] = bstr.charCodeAt(n);
-    }
-    return u8arr;
+    // console.log(arr[1]);
+    const rst = new Buffer(arr[1], 'base64');
+    return rst;
 }
 
-
 module.exports = {
     exportExcel: function(pageData, paperSize, fName, options, custSheetNames, custSheetMergeBands, baseDir, roleRel, callback) {
         const rptOptions = ({ singlePage: false, fileName: 'report' });
@@ -1182,11 +1198,14 @@ module.exports = {
         const sheets = [];
         const signKeyArr = [];
         const signPathArr = [];
+        const signSheetIdxArr = []; // 确定哪些sheet有签名(在多表导出的时候,有些表可能没有签名,但其他的表有签名)
         // console.log('in exportExcel!');
         // console.log(roleRel);
-        const hasSignature = (roleRel !== null) ? checkAndSetSignatureCache(pageData, signKeyArr, signPathArr, roleRel) : false;
+        const hasSignature = (roleRel !== null) ? checkAndSetSignatureCache(pageData, signKeyArr, signPathArr, roleRel, signSheetIdxArr) : false;
+        // console.log('signSheetIdxArr');
+        // console.log(signSheetIdxArr);
         // const hasSignature = false;
-        console.log('hasSignature: ' + hasSignature);
+        // console.log('hasSignature: ' + hasSignature);
         if (isSinglePage) {
             sheets.push({ sheetName: '全部页' });
         } else {
@@ -1233,16 +1252,24 @@ module.exports = {
         data = writeTheme();
         zip_theme.file(file, data, { compression: 'DEFLATE' });
         if (hasSignature) {
-            // 5.1
+            // 5.1 写所有的image
             const zip_media = zip_xl.folder('media');
+            let picIdx = 0;
+            // console.log(signKeyArr);
+            // console.log(signPathArr);
             for (let signIdx = 0; signIdx < signPathArr.length; signIdx++) {
-                data = writeImage(signPathArr[signIdx].path, signPathArr[signIdx].pic, baseDir);
-                file = 'image' + (signIdx + 1) + '.png';
-                zip_media.file(file, data, { compression: 'DEFLATE' });
+                if (signKeyArr[signIdx].length > 0) {
+                    for (let pathIdx = 0; pathIdx < signPathArr[signIdx].length; pathIdx++) {
+                        picIdx++;
+                        data = writeImage(signPathArr[signIdx][pathIdx].path, signPathArr[signIdx][pathIdx].pic, baseDir);
+                        file = 'image' + picIdx + '.png';
+                        zip_media.file(file, data, { compression: 'DEFLATE' });
+                    }
+                }
             }
             // 5.2
             const zip_drawings = zip_xl.folder('drawings');
-            data = writeDrawings(pageData, signKeyArr, signPathArr, isSinglePage);
+            data = writeDrawings(pageData, signKeyArr, signPathArr, isSinglePage, signSheetIdxArr);
             // console.log('isSinglePage: ' + isSinglePage);
             // console.log(data);
             for (let psIdx = 0; psIdx < data.length; psIdx++) {
@@ -1253,17 +1280,25 @@ module.exports = {
             }
             // 5.3
             const zip_drawings_rels = zip_drawings.folder('_rels');
-            data = writeDrawingsRels(signPathArr.length); // 这个一个文件搞定算了,无需多个文件
-            // console.log('drawing1.xml.rels data');
-            // console.log(data);
-            file = 'drawing1.xml.rels';
-            zip_drawings_rels.file(file, data.join(''), { compression: 'DEFLATE' });
+            let relsIdx = 0;
+            let relsImgAmt = 0;
+            for (let ssIdx = 0; ssIdx < signKeyArr.length; ssIdx++) {
+                if (signKeyArr[ssIdx].length > 0) {
+                    data = writeDrawingsRels(signKeyArr[ssIdx].length, relsImgAmt); // 一个drawingX.xml.rels文件与一个drawingX.xml对应
+                    relsIdx++;
+                    relsImgAmt += signKeyArr[ssIdx].length;
+                    // console.log('drawing1.xml.rels data');
+                    // console.log(data);
+                    file = 'drawing' + relsIdx + '.xml.rels';
+                    zip_drawings_rels.file(file, data.join(''), { compression: 'DEFLATE' });
+                }
+            }
         }
         // 6.
         const zip_xl_worksheets = zip_xl.folder('worksheets');
         const sharedStrList = [];
         const stylesObj = {};
-        data = writeSheets(pageData, paperSize, sharedStrList, stylesObj, isSinglePage, custSheetMergeBands, hasSignature);
+        data = writeSheets(pageData, paperSize, sharedStrList, stylesObj, isSinglePage, custSheetMergeBands, hasSignature, signSheetIdxArr);
         if (isSinglePage) {
             for (let i = 0; i < 1; i++) {
                 file = 'sheet' + (i + 1) + '.xml';
@@ -1279,14 +1314,18 @@ module.exports = {
         if (hasSignature) {
             const zip_xl_worksheets_rels = zip_xl_worksheets.folder('_rels');
             if (isSinglePage) {
-                data = writeWorkSheetRels(0);
+                data = writeWorkSheetRels(1);
                 file = 'sheet1.xml.rels';
                 zip_xl_worksheets_rels.file(file, data.join(''), { compression: 'DEFLATE' });
             } else {
+                let ssIdx = 0;
                 for (let i = 0; i < data.length; i++) {
-                    data = writeWorkSheetRels(i);
-                    file = 'sheet' + (i + 1) + '.xml.rels';
-                    zip_xl_worksheets_rels.file(file, data.join(''), { compression: 'DEFLATE' });
+                    if (signSheetIdxArr[i]) {
+                        ssIdx++;
+                        const ssData = writeWorkSheetRels(ssIdx);
+                        file = 'sheet' + (i + 1) + '.xml.rels';
+                        zip_xl_worksheets_rels.file(file, ssData.join(''), { compression: 'DEFLATE' });
+                    }
                 }
             }
         }
@@ -1372,17 +1411,45 @@ module.exports = {
                         mergeBand[JV.PROP_TOP].push(pageDataArray[i][JV.BAND_PROP_MERGE_BAND][JV.PROP_TOP] + offsetY);
                         mergeBand[JV.PROP_BOTTOM].push(pageDataArray[i][JV.BAND_PROP_MERGE_BAND][JV.PROP_BOTTOM] + offsetY);
                     }
-                    for (let k = 0; k < pageDataArray[i].items[j].cells.length; k++) {
-                        if (maxY < pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_BOTTOM]) {
-                            maxY = pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_BOTTOM];
+                    // 1.2.1 重新设置普通cells的Top Bottom坐标
+                    for (const cell of pageDataArray[i].items[j].cells) {
+                    // for (let k = 0; k < pageDataArray[i].items[j].cells.length; k++) {
+                        if (maxY < cell[JV.PROP_AREA][JV.PROP_BOTTOM]) {
+                            maxY = cell[JV.PROP_AREA][JV.PROP_BOTTOM];
+                        }
+                        if (minY > cell[JV.PROP_AREA][JV.PROP_TOP]) {
+                            minY = cell[JV.PROP_AREA][JV.PROP_TOP];
+                        }
+                        cell[JV.PROP_AREA][JV.PROP_BOTTOM] += offsetY;
+                        cell[JV.PROP_AREA][JV.PROP_TOP] += offsetY;
+                    }
+                    // 1.2.2 重新设置电子签名cells的Top Bottom坐标
+                    for (const cell of pageDataArray[i].items[j].signature_cells) {
+                        if (maxY < cell[JV.PROP_AREA][JV.PROP_BOTTOM]) {
+                            maxY = cell[JV.PROP_AREA][JV.PROP_BOTTOM];
+                        }
+                        if (minY > cell[JV.PROP_AREA][JV.PROP_TOP]) {
+                            minY = cell[JV.PROP_AREA][JV.PROP_TOP];
+                        }
+                        // console.log('before');
+                        // console.log(cell);
+                        cell[JV.PROP_AREA][JV.PROP_BOTTOM] += offsetY;
+                        cell[JV.PROP_AREA][JV.PROP_TOP] += offsetY;
+                        // console.log('after');
+                        // console.log(cell);
+                    }
+                    // 1.2.3 重新设置电子签名日期cells的Top Bottom坐标
+                    for (const cell of pageDataArray[i].items[j].signature_date_cells) {
+                        if (maxY < cell[JV.PROP_AREA][JV.PROP_BOTTOM]) {
+                            maxY = cell[JV.PROP_AREA][JV.PROP_BOTTOM];
                         }
-                        if (minY > pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_TOP]) {
-                            minY = pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_TOP];
+                        if (minY > cell[JV.PROP_AREA][JV.PROP_TOP]) {
+                            minY = cell[JV.PROP_AREA][JV.PROP_TOP];
                         }
-                        pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_BOTTOM] += offsetY;
-                        pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_TOP] += offsetY;
+                        cell[JV.PROP_AREA][JV.PROP_BOTTOM] += offsetY;
+                        cell[JV.PROP_AREA][JV.PROP_TOP] += offsetY;
                     }
-                    const bottomGap = Math.round( (pageDataArray[i][JV.NODE_PAGE_INFO][JV.NODE_PAGE_SIZE][1] - parseFloat(pageDataArray[i][JV.NODE_PAGE_INFO][JV.NODE_MARGINS][JV.PROP_BOTTOM]) / 2.54 ) * DPI) - maxY;
+                    const bottomGap = Math.round((pageDataArray[i][JV.NODE_PAGE_INFO][JV.NODE_PAGE_SIZE][1] - parseFloat(pageDataArray[i][JV.NODE_PAGE_INFO][JV.NODE_MARGINS][JV.PROP_BOTTOM]) / 2.54) * DPI) - maxY;
                     offsetY += (maxY - minY);
                     if (bottomGap > 10) {
                         offsetY += (bottomGap - 10);
@@ -1396,8 +1463,20 @@ module.exports = {
                 pageItem[JV.PROP_PAGE_SEQ] = i + 1;
                 pageItem[JV.PROP_CELLS] = [];
                 for (let j = 0; j < pageDataArray[i].items.length; j++) {
-                    for (let k = 0; k < pageDataArray[i].items[j].cells.length; k++) {
-                        pageItem[JV.PROP_CELLS].push(pageDataArray[i].items[j].cells[k]);
+                    for (let k = 0; k < pageDataArray[i].items[j][JV.PROP_CELLS].length; k++) {
+                        pageItem[JV.PROP_CELLS].push(pageDataArray[i].items[j][JV.PROP_CELLS][k]);
+                    }
+                }
+                pageItem[JV.PROP_SIGNATURE_CELLS] = [];
+                for (let j = 0; j < pageDataArray[i].items.length; j++) {
+                    for (let k = 0; k < pageDataArray[i].items[j][JV.PROP_SIGNATURE_CELLS].length; k++) {
+                        pageItem[JV.PROP_SIGNATURE_CELLS].push(pageDataArray[i].items[j][JV.PROP_SIGNATURE_CELLS][k]);
+                    }
+                }
+                pageItem[JV.PROP_SIGNATURE_DATE_CELLS] = [];
+                for (let j = 0; j < pageDataArray[i].items.length; j++) {
+                    for (let k = 0; k < pageDataArray[i].items[j][JV.PROP_SIGNATURE_DATE_CELLS].length; k++) {
+                        pageItem[JV.PROP_SIGNATURE_DATE_CELLS].push(pageDataArray[i].items[j][JV.PROP_SIGNATURE_DATE_CELLS][k]);
                     }
                 }
                 newPagePos[i][JV.NODE_PAGE_SIZE] = pageDataArray[i][JV.NODE_PAGE_INFO][JV.NODE_PAGE_SIZE];
@@ -1407,7 +1486,7 @@ module.exports = {
             // 3. everything is ok, then call me
             // let roleRel = null; // 未来调用的时候,这个属性要从外面给!!!
             // roleRelArr
-            me.exportExcel(newPageData, paperSize, fName, 'false', sheetNames, custMergeBands, baseDir, null, callback);
+            me.exportExcel(newPageData, paperSize, fName, 'false', sheetNames, custMergeBands, baseDir, roleRelArr, callback);
             // fsUtil.writeObjToFile(newPageData, 'D:/GitHome/ConstructionOperation/tmp/combinedHeader.js');
         } catch (e) {
             console.log(e);

+ 1 - 0
app/router.js

@@ -188,6 +188,7 @@ module.exports = app => {
     app.post('/tender/report_api/getReport', sessionAuth, 'reportController.getReport');
     app.post('/tender/report_api/getMultiReports', sessionAuth, 'reportController.getMultiReportsEx');
     app.post('/tender/report_api/createExcelFiles', sessionAuth, 'reportController.createExcelFilesEx');
+    app.post('/tender/report_api/createExcelFilesInOneBook', sessionAuth, 'reportController.createExcelFilesInOneBookEx');
     app.get('/getFileByUUID/:uuid/:rptName/:suffix', sessionAuth, 'reportController.getFileByUUID');
     // rptRouter.get('/getFileByUUID/:uuid/:rptName/:suffix', reportController.getFileByUUID);
     app.post('/tender/report_api/createSignatureRole', sessionAuth, 'signatureController.createSignatureRole');

+ 12 - 5
app/service/material_audit.js

@@ -51,11 +51,18 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAuditors(materialId, times = 1) {
-            const sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
-                'FROM ?? AS la, ?? AS pa ' +
-                'WHERE la.`mid` = ? and la.`times` = ? and la.`aid` = pa.`id` order by la.`order`';
-            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, materialId, times];
-            return await this.db.query(sql, sqlParam);
+            const sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, g.`sort` ' +
+                'FROM ?? AS la, ?? AS pa, (SELECT `aid`,(@i:=@i+1) as `sort` FROM ??, (select @i:=0) as it WHERE `mid` = ? AND `times` = ? GROUP BY `aid`) as g ' +
+                'WHERE la.`mid` = ? and la.`times` = ? and la.`aid` = pa.`id` and g.`aid` = la.`aid` order by la.`order`';
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, this.tableName, materialId, times, materialId, times];
+            const result = await this.db.query(sql, sqlParam);
+            const sql2 = 'SELECT COUNT(a.`aid`) as num FROM (SELECT `aid` FROM ?? WHERE `mid` = ? AND `times` = ? GROUP BY `aid`) as a';
+            const sqlParam2 = [this.tableName, materialId, times];
+            const count = await this.db.queryOne(sql2, sqlParam2);
+            for (const i in result) {
+                result[i].max_sort = count.num;
+            }
+            return result;
         }
 
         /**

+ 206 - 162
app/view/material/audit_modal.ejs

@@ -65,14 +65,14 @@
                         <div class="card mt-3">
                             <ul class="list-group list-group-flush">
                                 <li class="list-group-item">
-                                    <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small>
+                                    <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small><div class="pull-right">原报</div>
                                 </li>
                                 <% for (let i = 0; i < ctx.material.auditors2.length; i++) { %>
                                 <li class="list-group-item">
                                     <% if (i < ctx.material.auditors2.length - 1) { %>
-                                    <i class="fa fa-chevron-circle-down"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small>
+                                    <i class="fa fa-chevron-circle-down"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small><span class="pull-right"><%= ctx.helper.transFormToChinese(i+1) %>审</span>
                                     <% } else { %>
-                                    <i class="fa fa fa-stop-circle"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small>
+                                    <i class="fa fa fa-stop-circle"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small><span class="pull-right">终审</span>
                                     <% } %>
                                 </li>
                                 <% } %>
@@ -83,29 +83,41 @@
                         <div class="card mt-3">
                             <ul class="list-group list-group-flush">
                                 <li class="list-group-item">
-                                    <span class="text-success pull-right"><small><%- ctx.material.auditors[0].begin_time.toLocaleDateString() %></small> 上报</span>
-                                    <h5 class="card-title"><i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- ctx.material.user.name %> <small class="text-muted"><%- ctx.material.user.role %></small></h5>
+                                    <h5 class="card-title">
+                                        <i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- ctx.material.user.name %> <small class="text-muted"><%- ctx.material.user.role %></small>
+                                    </h5>
+                                    <div class="ml-3">
+                                        <span class="text-success"><small><%- ctx.material.auditors[0].begin_time.toLocaleDateString() %></small> 上报</span>
+                                    </div>
                                 </li>
                                 <% for (let iA = 0; iA < ctx.material.auditors.length; iA++) { %>
                                 <% const auditors = ctx.material.auditors; %>
                                 <li class="list-group-item">
                                     <% if (auditors[iA].status === auditConst.status.checked) { %>
-                                    <span class="text-success pull-right"><small><%- auditors[iA].end_time.toLocaleString() %></small> 审批通过</span>
                                     <h5 class="card-title">
-                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down text-success' : 'fa fa-stop-circle text-success') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small>
+                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down text-success' : 'fa fa-stop-circle text-success') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small><span class="pull-right"><%= auditors[iA].sort === auditors[iA].max_sort ? '终' : ctx.helper.transFormToChinese(auditors[iA].sort) %>审</span>
                                     </h5>
+                                    <div class="ml-3">
+                                        <span class="text-success"><small><%- auditors[iA].end_time.toLocaleDateString() %></small> 审批通过</span>
+                                        <p class="card-text"><%- auditors[iA].opinion %></p>
+                                    </div>
                                     <% } else if (auditors[iA].stauts == auditConst.status.checking) { %>
-                                    <span class="pull-right">审批中</span>
                                     <h5 class="card-title">
-                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down' : 'fa fa-stop-circle') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small>
+                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down' : 'fa fa-stop-circle') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small><span class="pull-right"><%= auditors[iA].sort === auditors[iA].max_sort ? '终' : ctx.helper.transFormToChinese(auditors[iA].sort) %>审</span>
                                     </h5>
+                                    <div class="ml-3">
+                                        <span>审批中</span>
+                                        <p class="card-text"><%- auditors[iA].opinion %></p>
+                                    </div>
                                     <% } else { %>
                                     <h5 class="card-title">
-                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down' : 'fa fa-stop-circle') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small>
+                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down' : 'fa fa-stop-circle') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small><span class="pull-right"><%= auditors[iA].sort === auditors[iA].max_sort ? '终' : ctx.helper.transFormToChinese(auditors[iA].sort) %>审</span>
                                     </h5>
+                                    <div class="ml-3">
+                                        <p class="card-text"><%- auditors[iA].opinion %></p>
+                                    </div>
                                     <% } %>
                                     <% if (auditors[iA].status === auditConst.status.checked) { %>
-                                    <p class="card-text"><%- auditors[iA].opinion %></p>
                                     <% } else if (auditors[iA].status === auditConst.status.checking) { %>
                                     <div class="form-group">
                                         <label>审批意见<b class="text-danger">*</b></label>
@@ -141,14 +153,14 @@
                         <div class="card mt-3">
                             <ul class="list-group list-group-flush">
                                 <li class="list-group-item">
-                                    <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small>
+                                    <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small><span class="pull-right">原报</span>
                                 </li>
                                 <% for (let i = 0; i < ctx.material.auditors2.length; i++) { %>
                                 <li class="list-group-item">
                                     <% if (i < ctx.material.auditors2.length - 1) { %>
-                                    <i class="fa fa-chevron-circle-down"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small>
+                                    <i class="fa fa-chevron-circle-down"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small><span class="pull-right"><%= ctx.helper.transFormToChinese(i+1) %>审</span>
                                     <% } else { %>
-                                    <i class="fa fa fa-stop-circle"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small>
+                                    <i class="fa fa fa-stop-circle"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small><span class="pull-right">终审</span>
                                     <% } %>
                                 </li>
                                 <% } %>
@@ -166,22 +178,30 @@
                                 <% const auditors = ctx.material.auditors; %>
                                 <li class="list-group-item">
                                     <% if (auditors[iA].status === auditConst.status.checked) { %>
-                                    <span class="text-success pull-right"><small><%- auditors[iA].end_time.toLocaleString() %></small> 审批通过</span>
                                     <h5 class="card-title">
-                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down text-success' : 'fa fa-stop-circle text-success') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small>
+                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down text-success' : 'fa fa-stop-circle text-success') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small><span class="pull-right"><%= auditors[iA].sort === auditors[iA].max_sort ? '终' : ctx.helper.transFormToChinese(auditors[iA].sort) %>审</span>
                                     </h5>
+                                    <div class="ml-3">
+                                        <span class="text-success"><small><%- auditors[iA].end_time.toLocaleDateString() %></small> 审批通过</span>
+                                        <p class="card-text"><%- auditors[iA].opinion %></p>
+                                    </div>
                                     <% } else if (auditors[iA].stauts == auditConst.status.checking) { %>
-                                    <span class="pull-right">审批中</span>
                                     <h5 class="card-title">
-                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down' : 'fa fa-stop-circle') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small>
+                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down' : 'fa fa-stop-circle') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small><span class="pull-right"><%= auditors[iA].sort === auditors[iA].max_sort ? '终' : ctx.helper.transFormToChinese(auditors[iA].sort) %>审</span>
                                     </h5>
+                                    <div class="ml-3">
+                                        <span>审批中</span>
+                                        <p class="card-text"><%- auditors[iA].opinion %></p>
+                                    </div>
                                     <% } else { %>
                                     <h5 class="card-title">
-                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down' : 'fa fa-stop-circle') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small>
+                                        <i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down' : 'fa fa-stop-circle') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small><span class="pull-right"><%= auditors[iA].sort === auditors[iA].max_sort ? '终' : ctx.helper.transFormToChinese(auditors[iA].sort) %>审</span>
                                     </h5>
+                                    <div class="ml-3">
+                                        <p class="card-text"><%- auditors[iA].opinion %></p>
+                                    </div>
                                     <% } %>
                                     <% if (auditors[iA].status === auditConst.status.checked) { %>
-                                    <p class="card-text"><%- auditors[iA].opinion %></p>
                                     <% } else if (auditors[iA].status === auditConst.status.checking) { %>
                                     <div class="form-group">
                                         <label>审批意见<b class="text-danger">*</b></label>
@@ -218,14 +238,14 @@
                         <div class="card mt-3">
                             <ul class="list-group list-group-flush">
                                 <li class="list-group-item">
-                                    <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small>
+                                    <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small><span class="pull-right">原报</span>
                                 </li>
                                 <% for (let i = 0; i < ctx.material.auditors2.length; i++) { %>
                                 <li class="list-group-item">
                                     <% if (i < ctx.material.auditors2.length - 1) { %>
-                                    <i class="fa fa-chevron-circle-down"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small>
+                                    <i class="fa fa-chevron-circle-down"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small><span class="pull-right"><%= ctx.helper.transFormToChinese(i+1) %>审</span>
                                     <% } else { %>
-                                    <i class="fa fa fa-stop-circle"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small>
+                                    <i class="fa fa fa-stop-circle"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small><span class="pull-right">终审</span>
                                     <% } %>
                                 </li>
                                 <% } %>
@@ -239,41 +259,47 @@
                                 <% for (let iA = 0; iA < ah.length; iA++) { %>
                                 <% if (iA === 0) { %>
                                 <li class="list-group-item">
-                                    <span class="text-success pull-right"><% if (ctx.material.auditHistory.indexOf(ah) > 0) { %>重新<% } %>上报</span>
-                                    <h5 class="card-title"><i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- ctx.material.user.name %> <small class="text-muted"><%- ctx.material.user.role %></small></h5>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].begin_time.toLocaleDateString() %></small></p>
+                                    <h5 class="card-title">
+                                        <i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- ctx.material.user.name %> <small class="text-muted"><%- ctx.material.user.role %></small><span class="pull-right">原报</span>
+                                    </h5>
+                                    <div class="ml-3">
+                                        <span class="text-success"><small><%- ah[iA].begin_time.toLocaleDateString() %></small> <% if (ctx.material.auditHistory.indexOf(ah) > 0) { %>重新<% } %>上报</span>
+                                    </div>
                                 </li>
                                 <li class="list-group-item">
-                                    <% if (ah[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[ah[iA].status] %> pull-right"><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa <%if (iA === ah.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small></h5>
-                                    <% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- ah[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].end_time.toLocaleDateString() %></small></p>
-                                    <% } %>
+                                    <h5 class="card-title">
+                                        <i class="fa <%if (iA === ah.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small><span class="pull-right"><%= ah[iA].sort === ah[iA].max_sort ? '终' : ctx.helper.transFormToChinese(ah[iA].sort) %>审</span>
+                                    </h5>
+                                    <div class="ml-3">
+                                        <% if (ah[iA].status !== auditConst.status.uncheck) { %>
+                                            <span class="<%- auditConst.statusClass[ah[iA].status] %>"><% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %><small><%- ah[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                        <% } %>
+                                        <p class="card-text"><%- ah[iA].opinion %></p>
+                                    </div>
                                 </li>
                                 <% } else if (iA === ah.length - 1) { %>
                                 <li class="list-group-item">
-                                    <% if (ah[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[ah[iA].status] %> pull-right"><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa fa-stop-circle <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small></h5>
-                                    <% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- ah[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].end_time.toLocaleDateString() %></small></p>
-                                    <% } %>
+                                    <h5 class="card-title">
+                                        <i class="fa fa-stop-circle <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small><span class="pull-right">终审</span>
+                                    </h5>
+                                    <div class="ml-3">
+                                        <% if (ah[iA].status !== auditConst.status.uncheck) { %>
+                                            <span class="<%- auditConst.statusClass[ah[iA].status] %>"><% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %><small><%- ah[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                        <% } %>
+                                        <p class="card-text"><%- ah[iA].opinion %></p>
+                                    </div>
                                 </li>
                                 <% } else { %>
                                 <li class="list-group-item">
-                                    <% if (ah[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[ah[iA].status] %> pull-right"><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa fa-chevron-circle-down <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small></h5>
-                                    <% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- ah[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].end_time.toLocaleDateString() %></small></p>
-                                    <% } %>
+                                    <h5 class="card-title">
+                                        <i class="fa <%if (iA === ah.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small><span class="pull-right"><%= ah[iA].sort === ah[iA].max_sort ? '终' : ctx.helper.transFormToChinese(ah[iA].sort) %>审</span>
+                                    </h5>
+                                    <div class="ml-3">
+                                        <% if (ah[iA].status !== auditConst.status.uncheck) { %>
+                                            <span class="<%- auditConst.statusClass[ah[iA].status] %>"><% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %><small><%- ah[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                        <% } %>
+                                        <p class="card-text"><%- ah[iA].opinion %></p>
+                                    </div>
                                 </li>
                                 <% } %>
                                 <% } %>
@@ -287,41 +313,47 @@
                                 <% for (let iA = 0; iA < auditors.length; iA++) { %>
                                 <% if (iA === 0) { %>
                                 <li class="list-group-item">
-                                    <span class="text-success pull-right"><% if (ctx.material.times > 1) { %>重新<% } %>上报</span>
-                                    <h5 class="card-title"><i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- ctx.material.user.name %> <small class="text-muted"><%- ctx.material.user.role %></small></h5>
-                                    <p class="card-text"><small class="text-muted"><%- auditors[iA].begin_time.toLocaleDateString() %></small></p>
+                                    <h5 class="card-title">
+                                        <i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- ctx.material.user.name %> <small class="text-muted"><%- ctx.material.user.role %></small><span class="pull-right">原报</span>
+                                    </h5>
+                                    <div class="ml-3">
+                                        <span class="text-success"><small><%- auditors[iA].begin_time.toLocaleDateString() %></small> <% if (ctx.material.times > 1) { %>重新<% } %>上报</span>
+                                    </div>
                                 </li>
                                 <li class="list-group-item">
-                                    <% if (auditors[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[auditors[iA].status] %> pull-right"><%- auditConst.statusString[auditors[iA].status]%><% if (auditors[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa <%if (iA === auditors.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[auditors[iA].status] %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small></h5>
-                                    <% if (auditors[iA].status === auditConst.status.checked || auditors[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- auditors[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- auditors[iA].end_time.toLocaleDateString() %></small></p>
-                                    <% } %>
+                                    <h5 class="card-title">
+                                        <i class="fa <%if (iA === auditors.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[auditors[iA].status] %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small><%- auditors[iA].sort === auditors[iA].max_sort ? '终' : ctx.helper.transFormToChinese(auditors[iA].sort) %>审</span>
+                                    </h5>
+                                    <div class="ml-3">
+                                        <% if (auditors[iA].status !== auditConst.status.uncheck) { %>
+                                            <span class="<%- auditConst.statusClass[auditors[iA].status] %>"><% if (auditors[iA].status === auditConst.status.checked || auditors[iA].status === auditConst.status.checkNo) { %><small><%- auditors[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[auditors[iA].status]%><% if (auditors[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                        <% } %>
+                                        <p class="card-text"><%- auditors[iA].opinion %></p>
+                                    </div>
                                 </li>
                                 <% } else if (iA === auditors.length - 1) { %>
                                 <li class="list-group-item">
-                                    <% if (auditors[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[auditors[iA].status] %> pull-right"><%- auditConst.statusString[auditors[iA].status]%><% if (auditors[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa fa-stop-circle <%- auditConst.statusClass[auditors[iA].status] %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small></h5>
-                                    <% if (auditors[iA].status === auditConst.status.checked || auditors[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- auditors[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- auditors[iA].end_time.toLocaleDateString() %></small></p>
-                                    <% } %>
+                                    <h5 class="card-title">
+                                        <i class="fa fa-stop-circle <%- auditConst.statusClass[auditors[iA].status] %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small><span class="pull-right">终审</span>
+                                    </h5>
+                                    <div class="ml-3">
+                                        <% if (auditors[iA].status !== auditConst.status.uncheck) { %>
+                                            <span class="<%- auditConst.statusClass[auditors[iA].status] %>"><% if (auditors[iA].status === auditConst.status.checked || auditors[iA].status === auditConst.status.checkNo) { %><small><%- auditors[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[auditors[iA].status]%><% if (auditors[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                        <% } %>
+                                        <p class="card-text"><%- auditors[iA].opinion %></p>
+                                    </div>
                                 </li>
                                 <% } else { %>
                                 <li class="list-group-item">
-                                    <% if (auditors[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[auditors[iA].status] %> pull-right"><%- auditConst.statusString[auditors[iA].status]%><% if (auditors[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa fa-chevron-circle-down <%- auditConst.statusClass[auditors[iA].status] %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small></h5>
-                                    <% if (auditors[iA].status === auditConst.status.checked || auditors[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- auditors[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- auditors[iA].end_time.toLocaleDateString() %></small></p>
-                                    <% } %>
+                                    <h5 class="card-title">
+                                        <i class="fa <%if (iA === auditors.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[auditors[iA].status] %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small><%- auditors[iA].sort === auditors[iA].max_sort ? '终' : ctx.helper.transFormToChinese(auditors[iA].sort) %>审</span>
+                                    </h5>
+                                    <div class="ml-3">
+                                        <% if (auditors[iA].status !== auditConst.status.uncheck) { %>
+                                            <span class="<%- auditConst.statusClass[auditors[iA].status] %>"><% if (auditors[iA].status === auditConst.status.checked || auditors[iA].status === auditConst.status.checkNo) { %><small><%- auditors[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[auditors[iA].status]%><% if (auditors[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                        <% } %>
+                                        <p class="card-text"><%- auditors[iA].opinion %></p>
+                                    </div>
                                 </li>
                                 <% } %>
                                 <% } %>
@@ -352,14 +384,14 @@
                         <div class="card mt-3">
                             <ul class="list-group list-group-flush">
                                 <li class="list-group-item">
-                                    <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small>
+                                    <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small><span class="pull-right">原报</span>
                                 </li>
                                 <% for (let i = 0; i < ctx.material.auditors2.length; i++) { %>
                                 <li class="list-group-item">
                                     <% if (i < ctx.material.auditors2.length - 1) { %>
-                                    <i class="fa fa-chevron-circle-down"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small>
+                                    <i class="fa fa-chevron-circle-down"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small><span class="pull-right"><%= ctx.helper.transFormToChinese(i+1) %>审</span>
                                     <% } else { %>
-                                    <i class="fa fa fa-stop-circle"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small>
+                                    <i class="fa fa fa-stop-circle"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small><span class="pull-right">终审</span>
                                     <% } %>
                                 </li>
                                 <% } %>
@@ -371,45 +403,51 @@
                         <div class="card mt-3">
                             <ul class="list-group list-group-flush">
                                 <% for (let iA = 0; iA < ah.length; iA++) { %>
-                                <% if (iA === 0) { %>
-                                <li class="list-group-item">
-                                    <span class="text-success pull-right"><% if (ctx.material.auditHistory.indexOf(ah) > 0) { %>重新<% } %>上报</span>
-                                    <h5 class="card-title"><i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- ctx.material.user.name %> <small class="text-muted"><%- ctx.material.user.role %></small></h5>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].begin_time.toLocaleDateString() %></small></p>
-                                </li>
-                                <li class="list-group-item">
-                                    <% if (ah[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[ah[iA].status] %> pull-right"><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa <%if (iA === ah.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small></h5>
-                                    <% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- ah[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].end_time.toLocaleDateString() %></small></p>
-                                    <% } %>
-                                </li>
-                                <% } else if (iA === ah.length - 1) { %>
-                                <li class="list-group-item">
-                                    <% if (ah[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[ah[iA].status] %> pull-right"><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa fa-stop-circle <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small></h5>
-                                    <% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- ah[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].end_time.toLocaleDateString() %></small></p>
-                                    <% } %>
-                                </li>
-                                <% } else { %>
-                                <li class="list-group-item">
-                                    <% if (ah[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[ah[iA].status] %> pull-right"><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa fa-chevron-circle-down <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small></h5>
-                                    <% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- ah[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].end_time.toLocaleDateString() %></small></p>
+                                    <% if (iA === 0) { %>
+                                        <li class="list-group-item">
+                                            <h5 class="card-title">
+                                                <i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- ctx.material.user.name %> <small class="text-muted"><%- ctx.material.user.role %></small><span class="pull-right">原报</span>
+                                            </h5>
+                                            <div class="ml-3">
+                                                <span class="text-success"><small><%- ah[iA].begin_time.toLocaleDateString() %></small> <% if (ctx.material.auditHistory.indexOf(ah) > 0) { %>重新<% } %>上报</span>
+                                            </div>
+                                        </li>
+                                        <li class="list-group-item">
+                                            <h5 class="card-title">
+                                                <i class="fa <%if (iA === ah.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small><span class="pull-right"><%= ah[iA].sort === ah[iA].max_sort ? '终' : ctx.helper.transFormToChinese(ah[iA].sort) %>审</span>
+                                            </h5>
+                                            <div class="ml-3">
+                                                <% if (ah[iA].status !== auditConst.status.uncheck) { %>
+                                                    <span class="<%- auditConst.statusClass[ah[iA].status] %>"><% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %><small><%- ah[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                                <% } %>
+                                                <p class="card-text"><%- ah[iA].opinion %></p>
+                                            </div>
+                                        </li>
+                                    <% } else if (iA === ah.length - 1) { %>
+                                        <li class="list-group-item">
+                                            <h5 class="card-title">
+                                                <i class="fa fa-stop-circle <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small><span class="pull-right">终审</span>
+                                            </h5>
+                                            <div class="ml-3">
+                                                <% if (ah[iA].status !== auditConst.status.uncheck) { %>
+                                                    <span class="<%- auditConst.statusClass[ah[iA].status] %>"><% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %><small><%- ah[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                                <% } %>
+                                                <p class="card-text"><%- ah[iA].opinion %></p>
+                                            </div>
+                                        </li>
+                                    <% } else { %>
+                                    <li class="list-group-item">
+                                        <h5 class="card-title">
+                                            <i class="fa <%if (iA === ah.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small><span class="pull-right"><%= ah[iA].sort === ah[iA].max_sort ? '终' : ctx.helper.transFormToChinese(ah[iA].sort) %>审</span>
+                                        </h5>
+                                        <div class="ml-3">
+                                            <% if (ah[iA].status !== auditConst.status.uncheck) { %>
+                                                <span class="<%- auditConst.statusClass[ah[iA].status] %>"><% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %><small><%- ah[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                            <% } %>
+                                            <p class="card-text"><%- ah[iA].opinion %></p>
+                                        </div>
+                                    </li>
                                     <% } %>
-                                </li>
-                                <% } %>
                                 <% } %>
                             </ul>
                         </div>
@@ -437,14 +475,14 @@
                         <div class="card mt-3">
                             <ul class="list-group list-group-flush">
                                 <li class="list-group-item">
-                                    <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small>
+                                    <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small><span class="pull-right">原报</span>
                                 </li>
                                 <% for (let i = 0; i < ctx.material.auditors2.length; i++) { %>
                                 <li class="list-group-item">
                                     <% if (i < ctx.material.auditors2.length - 1) { %>
-                                    <i class="fa fa-chevron-circle-down"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small>
+                                    <i class="fa fa-chevron-circle-down"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small><span class="pull-right"><%= ctx.helper.transFormToChinese(i+1) %>审</span>
                                     <% } else { %>
-                                    <i class="fa fa fa-stop-circle"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small>
+                                    <i class="fa fa fa-stop-circle"></i> <%- ctx.material.auditors2[i].name %>  <small class="text-muted"><%- ctx.material.auditors2[i].role %></small><span class="pull-right">终审</span>
                                     <% } %>
                                 </li>
                                 <% } %>
@@ -456,45 +494,51 @@
                         <div class="card mt-3">
                             <ul class="list-group list-group-flush">
                                 <% for (let iA = 0; iA < ah.length; iA++) { %>
-                                <% if (iA === 0) { %>
-                                <li class="list-group-item">
-                                    <span class="text-success pull-right"><% if (ctx.material.auditHistory.indexOf(ah) > 0) { %>重新<% } %>上报</span>
-                                    <h5 class="card-title"><i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- ctx.material.user.name %> <small class="text-muted"><%- ctx.material.user.role %></small></h5>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].begin_time.toLocaleDateString() %></small></p>
-                                </li>
-                                <li class="list-group-item">
-                                    <% if (ah[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[ah[iA].status] %> pull-right"><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa <%if (iA === ah.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small></h5>
-                                    <% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- ah[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].end_time.toLocaleDateString() %></small></p>
-                                    <% } %>
-                                </li>
-                                <% } else if (iA === ah.length - 1) { %>
-                                <li class="list-group-item">
-                                    <% if (ah[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[ah[iA].status] %> pull-right"><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa fa-stop-circle <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small></h5>
-                                    <% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- ah[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].end_time.toLocaleDateString() %></small></p>
-                                    <% } %>
-                                </li>
-                                <% } else { %>
-                                <li class="list-group-item">
-                                    <% if (ah[iA].status !== auditConst.status.uncheck) { %>
-                                    <span class="<%- auditConst.statusClass[ah[iA].status] %> pull-right"><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
-                                    <% } %>
-                                    <h5 class="card-title"><i class="fa fa-chevron-circle-down <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small></h5>
-                                    <% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %>
-                                    <p class="card-text mb-1"><%- ah[iA].opinion %></p>
-                                    <p class="card-text"><small class="text-muted"><%- ah[iA].end_time.toLocaleDateString() %></small></p>
+                                    <% if (iA === 0) { %>
+                                        <li class="list-group-item">
+                                            <h5 class="card-title">
+                                                <i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- ctx.material.user.name %> <small class="text-muted"><%- ctx.material.user.role %></small><span class="pull-right">原报</span>
+                                            </h5>
+                                            <div class="ml-3">
+                                                <span class="text-success"><small><%- ah[iA].begin_time.toLocaleDateString() %></small> <% if (ctx.material.auditHistory.indexOf(ah) > 0) { %>重新<% } %>上报</span>
+                                            </div>
+                                        </li>
+                                        <li class="list-group-item">
+                                            <h5 class="card-title">
+                                                <i class="fa <%if (iA === ah.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small><span class="pull-right"><%= ah[iA].sort === ah[iA].max_sort ? '终' : ctx.helper.transFormToChinese(ah[iA].sort) %>审</span>
+                                            </h5>
+                                            <div class="ml-3">
+                                                <% if (ah[iA].status !== auditConst.status.uncheck) { %>
+                                                    <span class="<%- auditConst.statusClass[ah[iA].status] %>"><% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %><small><%- ah[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                                <% } %>
+                                                <p class="card-text"><%- ah[iA].opinion %></p>
+                                            </div>
+                                        </li>
+                                    <% } else if (iA === ah.length - 1) { %>
+                                        <li class="list-group-item">
+                                            <h5 class="card-title">
+                                                <i class="fa fa-stop-circle <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small><span class="pull-right">终审</span>
+                                            </h5>
+                                            <div class="ml-3">
+                                                <% if (ah[iA].status !== auditConst.status.uncheck) { %>
+                                                    <span class="<%- auditConst.statusClass[ah[iA].status] %>"><% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %><small><%- ah[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                                <% } %>
+                                                <p class="card-text"><%- ah[iA].opinion %></p>
+                                            </div>
+                                        </li>
+                                    <% } else { %>
+                                    <li class="list-group-item">
+                                        <h5 class="card-title">
+                                            <i class="fa <%if (iA === ah.length - 1) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> <%- auditConst.statusClass[ah[iA].status] %>"></i> <%- ah[iA].name %> <small class="text-muted"><%- ah[iA].role %></small><span class="pull-right"><%= ah[iA].sort === ah[iA].max_sort ? '终' : ctx.helper.transFormToChinese(ah[iA].sort) %>审</span>
+                                        </h5>
+                                        <div class="ml-3">
+                                            <% if (ah[iA].status !== auditConst.status.uncheck) { %>
+                                                <span class="<%- auditConst.statusClass[ah[iA].status] %>"><% if (ah[iA].status === auditConst.status.checked || ah[iA].status === auditConst.status.checkNo) { %><small><%- ah[iA].end_time.toLocaleDateString() %></small> <% } %><%- auditConst.statusString[ah[iA].status]%><% if (ah[iA].status === auditConst.status.checkNo) { %> <%- ctx.material.user.name %><% } %></span>
+                                            <% } %>
+                                            <p class="card-text"><%- ah[iA].opinion %></p>
+                                        </div>
+                                    </li>
                                     <% } %>
-                                </li>
-                                <% } %>
                                 <% } %>
                             </ul>
                         </div>
@@ -523,7 +567,7 @@
                             <div class="card mt-3">
                                 <ul class="list-group list-group-flush">
                                     <li class="list-group-item">
-                                        <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small>
+                                        <i class="fa fa fa-play-circle fa-rotate-90"></i> <%- ctx.material.user.name %>  <small class="text-muted"><%- ctx.material.user.role %></small><span class="pull-right">原报</span>
                                     </li>
                                 </ul>
                                 <ul class="list-group list-group-flush" id="auditors-list">
@@ -531,9 +575,9 @@
                                     <% for (let i = 0; i < auditorList.length; i++) { %>
                                         <li class="list-group-item" data-auditid="<%- auditorList[i].aid %>">
                                             <% if (i < auditorList.length - 1) { %>
-                                                <i class="fa fa-chevron-circle-down"></i> <%- auditorList[i].name %>  <small class="text-muted"><%- auditorList[i].role %></small>
+                                                <i class="fa fa-chevron-circle-down"></i> <%- auditorList[i].name %>  <small class="text-muted"><%- auditorList[i].role %></small><span class="pull-right"><%= ctx.helper.transFormToChinese(i+1) %>审</span>
                                             <% } else { %>
-                                                <i class="fa fa fa-stop-circle"></i> <%- auditorList[i].name %>  <small class="text-muted"><%- auditorList[i].role %></small>
+                                                <i class="fa fa fa-stop-circle"></i> <%- auditorList[i].name %>  <small class="text-muted"><%- auditorList[i].role %></small><span class="pull-right">终审</span>
                                             <% } %>
                                         </li>
                                     <% } %>

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

@@ -189,6 +189,7 @@
     CUST_CFG = JSON.parse(CUST_CFG[0].cfg_content);
     const PROJECT_ID = <%- project_id %>;
     const TENDER_ID = <%- tender_id %>;
+    const TENDER_NAME = '<%- tender_name %>';
     const STAGE_ID = <%- stg_id %>;
     const STAGE_ORDER = <%- stg_order %>;
     const STAGE_TIMES = <%- stg_times %>;

Різницю між файлами не показано, бо вона завелика
+ 2837 - 2864
package-lock.json


+ 1 - 0
package.json

@@ -5,6 +5,7 @@
   "private": true,
   "dependencies": {
     "ali-rds": "^3.3.0",
+    "atob": "^2.1.2",
     "bignumber.js": "^8.1.1",
     "decimal.js": "^10.2.0",
     "egg": "^1.13.0",