ソースを参照

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

# Conflicts:
#	app/view/payment/detail.ejs
Tony Kang 2 年 前
コミット
a5ca97ab9f

+ 8 - 1
app/controller/file_controller.js

@@ -257,7 +257,14 @@ module.exports = app => {
         }
         async _loadAdvanceAtt(data) {
             if (!data.stage) throw '参数错误';
-            return await this.ctx.service.advanceFile.getAllDataByCondition({ where: { vid: data.stage }, order: [['id', 'desc']]});
+            const self = this;
+            const result = await this.ctx.service.advanceFile.getAllDataByCondition({ where: { vid: data.stage }, order: [['id', 'desc']]});
+            result.forEach(x => {
+                const info = path.parse(x.filename);
+                x.filename = info.name;
+                x.filesize = self.ctx.helper.sizeToBytes(x.filesize);
+            });
+            return result;
         }
         async loadRelaFiles(ctx) {
             try {

+ 60 - 60
app/controller/payment_controller.js

@@ -243,14 +243,20 @@ module.exports = app => {
         async detail(ctx) {
             try {
                 await this._getDetailAuditViewData(ctx);
-                const report_json = JSON.parse(ctx.detail.report_json);
+                const renderData = {
+                    trInfo: ctx.trInfo,
+                    paymentConst,
+                    jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.payment.detail),
+                    auditConst,
+                    shenpiConst,
+                    preUrl: '/payment/' + ctx.tender.id + '/detail/' + ctx.detail.id,
+                    OSS_PATH: ctx.app.config.fujianOssPath,
+                };
+
+                let report_json = JSON.parse(ctx.detail.report_json);
                 const content = [];
                 // 获取当前报表人
                 const rptAudit = await ctx.service.paymentRptAudit.getDataByCondition({ td_id: ctx.detail.id, uid: ctx.session.sessionUser.accountId });
-                // 获取个人签字,单位章,个人章地址
-                const userInfo = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
-                const stampPathList = userInfo.stamp_path ? userInfo.stamp_path.split('!;!') : [];
-                const companyInfo = userInfo.company ? await ctx.service.constructionUnit.getDataByCondition({ pid: ctx.session.sessionProject.id, name: userInfo.company }) : {};
                 if (report_json.items[0].interact_cells.length > 0) {
                     for (const [i, cell] of report_json.items[0].interact_cells.entries()) {
                         const push_item = {
@@ -271,50 +277,28 @@ module.exports = app => {
                             });
                         }
                     }
-                    if (rptAudit.signature_msg) {
-                        const sign_msg = JSON.parse(rptAudit.signature_msg);
-                        // 签名签章
-                        const signCells = ctx.helper._.find(report_json.items[0].signature_cells, { signature_name: rptAudit.signature_name });
-                        if (signCells && signCells.path === null && (sign_msg.sign_path || sign_msg.company_stamp || sign_msg.stamp_path)) {
-                            const signArray = [];
-                            if (sign_msg.sign_path) signArray.push(sign_msg.sign_path);
-                            if (sign_msg.company_stamp) signArray.push(sign_msg.company_stamp);
-                            if (sign_msg.stamp_path) signArray.push(sign_msg.stamp_path);
-                            signCells.path = signArray.join('!;!');
-                        }
-                        console.log(signCells);
-                        // 日期
-                        const dateCells = ctx.helper._.find(report_json.items[0].signature_date_cells, { signature_name: rptAudit.signature_name + '_签字日期' });
-                        if (dateCells && dateCells.Value === '' && sign_msg.date) {
-                            dateCells.Value = sign_msg.date;
-                        }
-                        // 意见
-                        const contentCells = ctx.helper._.find(report_json.items[0].signature_audit_cells, { signature_name: rptAudit.signature_name + '_审核意见' });
-                        if (contentCells && contentCells.Value === '' && sign_msg.content) {
-                            contentCells.Value = sign_msg.content;
+                    if (ctx.detail.status !== auditConst.status.checked) {
+                        // 获取个人签字,单位章,个人章地址
+                        const userInfo = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
+                        const stampPathList = userInfo.stamp_path ? userInfo.stamp_path.split('!;!') : [];
+                        const companyInfo = userInfo.company ? await ctx.service.constructionUnit.getDataByCondition({ pid: ctx.session.sessionProject.id, name: userInfo.company }) : {};
+                        if (rptAudit.signature_msg) {
+                            const sign_msg = JSON.parse(rptAudit.signature_msg);
+                            report_json = await ctx.service.paymentDetail.signOneSignatureData(report_json, rptAudit.signature_name, sign_msg);
+                            rptAudit.signature_msg = sign_msg;
+                        } else {
+                            rptAudit.signature_msg = paymentConst.signature_msg;
+                            rptAudit.signature_msg.sign_path = userInfo.sign_path ? userInfo.sign_path : '';
                         }
-                        rptAudit.signature_msg = sign_msg;
-                    } else {
-                        rptAudit.signature_msg = paymentConst.signature_msg;
-                        rptAudit.signature_msg.sign_path = userInfo.sign_path ? userInfo.sign_path : '';
+                        renderData.signPath = userInfo.sign_path ? userInfo.sign_path : '';
+                        renderData.stampPathList = stampPathList;
+                        renderData.currentStamp = rptAudit && rptAudit.signature_msg.stamp_path ? rptAudit.signature_msg.stamp_path : (stampPathList.length > 0 ? stampPathList[0] : '');
+                        renderData.companyStamp = companyInfo && companyInfo.sign_path ? companyInfo.sign_path : '';
                     }
                 }
-                const renderData = {
-                    trInfo: ctx.trInfo,
-                    report_json,
-                    paymentConst,
-                    content,
-                    jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.payment.detail),
-                    rptAudit,
-                    auditConst,
-                    shenpiConst,
-                    signPath: userInfo.sign_path ? userInfo.sign_path : '',
-                    stampPathList,
-                    currentStamp: rptAudit && rptAudit.signature_msg.stamp_path ? rptAudit.signature_msg.stamp_path : (stampPathList.length > 0 ? stampPathList[0] : ''),
-                    companyStamp: companyInfo && companyInfo.sign_path ? companyInfo.sign_path : '',
-                    preUrl: '/payment/' + ctx.tender.id + '/detail/' + ctx.detail.id,
-                    OSS_PATH: ctx.app.config.fujianOssPath,
-                };
+                renderData.rptAudit = rptAudit;
+                renderData.content = content;
+                renderData.report_json = report_json;
                 if ((ctx.detail.status === auditConst.status.uncheck || ctx.detail.status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === ctx.detail.uid) {
                     // data.accountGroup = accountGroup;
                     // 获取所有项目参与者
@@ -327,6 +311,7 @@ module.exports = app => {
                         const groupList = accountList.filter(item => item.account_group === idx);
                         return { groupName: item, groupList };
                     });
+                    renderData.rptAuditList = await ctx.service.paymentRptAudit.getAllDataByCondition({ where: { td_id: ctx.detail.id } });
                 }
                 await this.layout('payment/detail.ejs', renderData, 'payment/detail_modal.ejs');
             } catch (err) {
@@ -338,26 +323,29 @@ module.exports = app => {
 
         async detailSave(ctx) {
             try {
+                const data = JSON.parse(ctx.request.body.data);
+                if (!data.type) {
+                    throw '提交数据错误';
+                }
                 // 检查权限等
-                if (ctx.detail.uid !== ctx.session.sessionUser.accountId) {
+                if (ctx.detail.uid !== ctx.session.sessionUser.accountId && data.type !== 'update_sign') {
                     throw '您无权操作';
                 }
-                if (ctx.detail.status === auditConst.status.checking || ctx.detail.status === auditConst.status.checked) {
+                if (data.type !== 'update_sign' && (ctx.detail.status === auditConst.status.checking || ctx.detail.status === auditConst.status.checked)) {
                     throw '您无权操作';
                 }
                 const responseData = {
                     err: 0, msg: '', data: {},
                 };
 
-                const data = JSON.parse(ctx.request.body.data);
-                if (!data.type) {
-                    throw '提交数据错误';
-                }
                 switch (data.type) {
                     case 'update_rpt':
                         responseData.data = await ctx.service.paymentDetail.updateReportJson(ctx.detail.id, data.report_json);
                         break;
                     case 'update_sign':
+                        if (ctx.detail.status === auditConst.status.checked) {
+                            throw '您无法操作签字/签章';
+                        }
                         responseData.data = await ctx.service.paymentRptAudit.updateSignatureMsg(ctx.detail.id, ctx.session.sessionUser.accountId, data.signature_msg);
                         break;
                     case 'add_audit':
@@ -474,7 +462,7 @@ module.exports = app => {
                 if (!auditPermission || !auditPermission.process) {
                     throw '权限不足';
                 }
-                let [tenderRptList, rptProjectList] = await this._returnRptProjectList(ctx);
+                let [tenderRptList, rptProjectList] = await this._returnRptProjectList(ctx, true);
                 tenderRptList = ctx.helper._.filter(tenderRptList, { is_const: 0, is_del: 0 });
                 // for (const tr of tenderRptList) {
                 //     if (tr.status === shenpiConst.sp_status.gdspl) {
@@ -585,18 +573,30 @@ module.exports = app => {
                         const pageRst = await ctx.service.jpcReport.getAllPreviewPagesCommon(rptTpl, 'A4');
                         renderData.rptMsg = pageRst.items[0];
                         // 判断与原有的报表审批人列表是否有区别
-                        const deffierence = ctx.helper._.differenceWith(renderData.rptMsg.signature_cells, JSON.parse(trInfo.signature_cells), ctx.helper._.isEqual);
-                        if (!ctx.helper._.isEmpty(deffierence)) {
+                        let difference = false;
+                        if (trInfo.report_items_json) {
+                            const report_items_json = JSON.parse(trInfo.report_items_json);
+                            const items = ['cells', 'signature_audit_cells', 'signature_cells', 'signature_date_cells', 'interact_cells'];
+                            for (const item of items) {
+                                if (!difference && report_items_json[item] &&
+                                    !ctx.helper._.isEmpty(ctx.helper._.differenceWith(JSON.parse(JSON.stringify(renderData.rptMsg[item])), report_items_json[item], ctx.helper._.isEqual))) {
+                                    // 因为interact_cells里存在undefind值,必须先用JSON.parse和JSON.stringify转义才能对比
+                                    difference = true;
+                                    break;
+                                }
+                            }
+                        }
+                        if (difference) {
                             // 删除rpt_audit重新配置
                             await ctx.service.paymentTenderRpt.defaultUpdate({
                                 id: trInfo.id,
-                                signature_cells: JSON.stringify(renderData.rptMsg.signature_cells),
+                                report_items_json: JSON.stringify(ctx.helper._.cloneDeep(renderData.rptMsg)),
                                 rpt_audit: null,
-                                is_first: 1,
+                                is_change: 1,
                             });
                             trInfo.rpt_audit = null;
-                            trInfo.is_first = 1;
-                            trInfo.signature_cells = renderData.rptMsg.signature_cells;
+                            trInfo.is_change = 1;
+                            trInfo.report_items_json = renderData.rptMsg;
                         }
                         if (trInfo.rpt_audit) {
                             trInfo.rpt_audit = JSON.parse(trInfo.rpt_audit);
@@ -663,7 +663,7 @@ module.exports = app => {
                 }
                 switch (data.type) {
                     case 'rpt_audit':
-                        responseData.data = await ctx.service.paymentTenderRpt.updateRptAudit(trInfo.id, data.rpt_audit);
+                        responseData.data = await ctx.service.paymentTenderRpt.updateRptAudit(trInfo, data.rpt_audit);
                         break;
                     case 'add-detail':
                         responseData.data = await ctx.service.paymentDetail.addDetail(trInfo, data.code, data.s_time);

+ 16 - 0
app/extend/helper.js

@@ -83,6 +83,22 @@ module.exports = {
         // return (bytes / Math.pow(k, i)) + ' ' + sizes[i];
         return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
     },
+    sizeToBytes(size) {
+        const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+        const sizesConverse = sizes.reverse();
+        let index, matchSize;
+        for (const [i, s] of sizesConverse.entries()) {
+            if (size.indexOf(s) > 0) {
+                matchSize = s;
+                index = sizes.length - i;
+                break;
+            }
+        }
+
+        const num = parseFloat(_.trim(size.replace(matchSize, '')));
+        const k = 1024;
+        return Math.ceil(num * Math.pow(k, index - 1));
+    },
 
     /**
      * 浮点乘法计算

+ 11 - 8
app/public/js/file_detail.js

@@ -1,4 +1,8 @@
 $(document).ready(function() {
+    autoFlashHeight();
+    console.log($(".sjs-height-0").height());
+    console.log($('#add-slibing').parent().parent().height());
+    $('#filing').height($(".sjs-height-0").height() - $('#add-slibing').parent().parent().height() - 10);
     class FilingObj {
         constructor(setting) {
             // 原始数据整理后的树结构,用来整理zTree显示
@@ -15,7 +19,7 @@ $(document).ready(function() {
             this.pageCount = 15;
             this.expandKey = 'filing-' + window.location.pathname.split('/')[2];
             const cache = getLocalCache(this.expandKey);
-            this.expandCache = cache ? cache.split(',') : [];
+            this.expandCache = cache ? _.uniq(cache.split(',')) : [];
             this.curFilingKey = 'cur-filing-' + window.location.pathname.split('/')[2];
         }
         analysisFiling(data) {
@@ -67,11 +71,11 @@ $(document).ready(function() {
         _getFileHtml(file) {
             const html = [];
             html.push(`<tr fid="${file.id}">`);
-            html.push(`<td><input type="checkbox" name="bd-check" fid="${file.id}"></td>`);
+            html.push(`<td class="text-center"><input type="checkbox" name="bd-check" fid="${file.id}"></td>`);
             html.push(`<td fid="${file.id}">${this._getFileNameHtml(file)}</td>`);
-            html.push(`<td>${file.user_name}</td>`);
-            html.push(`<td>${moment(file.create_time).format('YYYY-MM-DD HH:mm:ss')}</td>`);
-            html.push(`<td>${file.fileext_str}</td>`);
+            html.push(`<td class="text-center">${file.user_name}</td>`);
+            html.push(`<td class="text-center">${moment(file.create_time).format('YYYY-MM-DD HH:mm:ss')}</td>`);
+            html.push(`<td class="text-center">${file.fileext_str}</td>`);
             html.push('</tr>');
             return html.join('');
         }
@@ -284,8 +288,7 @@ $(document).ready(function() {
             if (expand) {
                 this.expandCache.push(node.id);
             } else{
-                const index = this.expandCache.indexOf(node.id);
-                if (index >= 0) this.expandCache.splice(index, 1);
+                this.expandCache = this.expandCache.filter(x => { return x !== node.id });
             }
             setLocalCache(this.expandKey, this.expandCache.join(','));
         }
@@ -571,7 +574,7 @@ $(document).ready(function() {
                 if (x.att) x.att.forEach(la => { la.checked = false });
                 if (x.advance) {
                     x.advance.forEach(a => {
-                        if (a.att) a.att.forEach(aa => { aa.checked = false });
+                        if (a.files) a.files.forEach(aa => { aa.checked = false });
                     });
                 }
                 if (x.stage) {

+ 4 - 3
app/public/js/global.js

@@ -1,5 +1,6 @@
 /*全局自适应高度*/
 /*全局自适应高度*/
+const postDefaultTime = 60 * 1000 * 2;
 function autoFlashHeight(){
     const select = $(".scrollbar-auto .active");
     if (select.length > 0) $(".scrollbar-auto")[0].scrollTop = select[0].offsetTop - 72;
@@ -246,7 +247,7 @@ const postData = function (url, data, successCallback, errorCallBack, showWaitin
         data: {'data': JSON.stringify(data)},
         dataType: 'json',
         cache: false,
-        timeout: 60000,
+        timeout: postDefaultTime,
         beforeSend: function(xhr) {
             let csrfToken = Cookies.get('csrfToken_j');
             xhr.setRequestHeader('x-csrf-token', csrfToken);
@@ -310,7 +311,7 @@ const postDataCompress = function (url, data, successCallback, errorCallBack, ht
         data: {'data': LZString.compressToUTF16(JSON.stringify(data))},
         dataType: 'json',
         cache: false,
-        timeout: 80000, // 导入清单Excel(10w行)预计需要时间
+        timeout: postDefaultTime,
         beforeSend: function(xhr) {
             let csrfToken = Cookies.get('csrfToken_j');
             xhr.setRequestHeader('x-csrf-token', csrfToken);
@@ -370,7 +371,7 @@ const postDataWithFile = function (url, formData, successCallback, errorCallBack
         contentType: false,
         // 告诉jQuery不要去处理发送的数据
         processData: false,
-        timeout: 60000,
+        timeout: postDefaultTime,
         beforeSend: function(xhr) {
             let csrfToken = Cookies.get('csrfToken_j');
             xhr.setRequestHeader('x-csrf-token', csrfToken);

+ 13 - 17
app/public/js/payment_detail.js

@@ -90,26 +90,23 @@ $(function () {
         rptAudit.signature_msg.content = $('#signature_content').val() ? $('#signature_content').val() : null;
         console.log(rptAudit.signature_msg);
         // 签章
-        if (rptAudit.signature_msg.sign_path || rptAudit.signature_msg.company_stamp || rptAudit.signature_msg.stamp_path) {
+        if (rptAudit.signature_msg.sign_path !== null || rptAudit.signature_msg.company_stamp !== null || rptAudit.signature_msg.stamp_path !== null) {
             const signArray = [];
-            if (rptAudit.signature_msg.sign_path) signArray.push(rptAudit.signature_msg.sign_path);
+            if (rptAudit.signature_msg.sign_path) signArray.push('/public/upload/sign/' + rptAudit.signature_msg.sign_path);
             if (rptAudit.signature_msg.company_stamp) signArray.push(rptAudit.signature_msg.company_stamp);
             if (rptAudit.signature_msg.stamp_path) signArray.push(rptAudit.signature_msg.stamp_path);
-            if (signArray.length > 0) {
-                tesRpttData.items[0].signature_cells[rptAudit.signature_index].path = signArray.length > 0 ? signArray.join('!;!') : null;
-                const date_index = _.findIndex(tesRpttData.items[0].signature_date_cells, { signature_name: rptAudit.signature_name + '_签字日期' });
-                if (date_index !== -1) {
-                    tesRpttData.items[0].signature_date_cells[date_index].Value = rptAudit.signature_msg.date ? rptAudit.signature_msg.date : '';
-                }
-                const content_index = _.findIndex(tesRpttData.items[0].signature_audit_cells, { signature_name: rptAudit.signature_name + '_审核意见' });
-                if (content_index !== -1) {
-                    tesRpttData.items[0].signature_audit_cells[content_index].Value = rptAudit.signature_msg.content ? rptAudit.signature_msg.content : '';
-                }
-                postData('/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'update_sign', signature_msg: rptAudit.signature_msg }, function (result) {
-                    auditRptPrintHelper.showPage();
-                    iniPage();
-                });
+            tesRpttData.items[0].signature_cells[rptAudit.signature_index].path = signArray.length > 0 ? signArray.join('!;!') : null;
+            const date_index = _.findIndex(tesRpttData.items[0].signature_date_cells, { signature_name: rptAudit.signature_name + '_签字日期' });
+            if (date_index !== -1) {
+                tesRpttData.items[0].signature_date_cells[date_index].Value = rptAudit.signature_msg.date ? rptAudit.signature_msg.date : '';
             }
+            const content_index = _.findIndex(tesRpttData.items[0].signature_audit_cells, { signature_name: rptAudit.signature_name + '_审核意见' });
+            if (content_index !== -1) {
+                tesRpttData.items[0].signature_audit_cells[content_index].Value = rptAudit.signature_msg.content ? rptAudit.signature_msg.content : '';
+            }
+            postData('/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'update_sign', signature_msg: rptAudit.signature_msg }, function (result) {
+                auditRptPrintHelper.showPage();
+            });
             $('#sub-sp5').modal('hide');
         } else {
             toastr.error('至少选择一个签字/签章');
@@ -125,7 +122,6 @@ $(function () {
             tesRpttData.items[0].interact_cells[index].Value = tesRpttData.items[0].interact_cells[index].Prefix ? tesRpttData.items[0].interact_cells[index].Prefix + newVal : newVal;
             postData('/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'update_rpt', report_json: tesRpttData }, function (result) {
                 auditRptPrintHelper.showPage();
-                iniPage();
             });
             clearTimeout(timer);
         }, 500);

+ 3 - 0
app/public/js/payment_detail_audit.js

@@ -89,6 +89,9 @@ $(document).ready(function () {
                         html.push(data.order + ' ');
                         html.push(data.name + ' ');
                         html.push('</span>');
+                        if (_.findIndex(rptAuditList, { uid: data.aid }) !== -1) {
+                            html.push('&nbsp;(' + _.find(rptAuditList, { uid: data.aid }).signature_name + ')');
+                        }
                         html.push('<small class="text-muted">');
                         html.push(data.role);
                         html.push('</small></li>');

+ 6 - 0
app/public/js/payment_list.js

@@ -113,6 +113,12 @@ $(function () {
 
     // 绑定表单角色
     $('#bind_rpt_audit_btn').click(function () {
+        if (!is_first) {
+            if (_.findIndex(rpt_audit, { uid: null }) !== -1) {
+                toastr.error('请绑定所有表单角色再提交');
+                return;
+            }
+        }
         postData('/payment/' + tenderId + '/list/' + trId + '/save', { type: 'rpt_audit', rpt_audit }, function (result) {
             toastr.success('设置成功');
             old_rpt_audit = _.cloneDeep(rpt_audit);

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

@@ -3801,7 +3801,7 @@ $(document).ready(() => {
             this.changeBillsSpreadSetting = {
                 cols: [
                     {title: '清单编号', colSpan: '1', rowSpan: '1', field: 'code', hAlign: 0, width: 80, formatter: '@'},
-                    {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 150, type: 'Number', cellType: 'delayTip', getTip: getTipText},
+                    {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 150, cellType: 'delayTip', getTip: getTipText},
                     {title: '单位', colSpan: '1', rowSpan: '1', field: 'unit', hAlign: 1, width: 50, formatter: '@'},
                     {title: '单价', colSpan: '1', rowSpan: '1', field: 'unit_price', hAlign: 2, width: 60, type: 'Number'},
                     {title: '数量', colSpan: '1', rowSpan: '1', field: 'qty', hAlign: 2, width: 60, formatter: '@'},
@@ -3999,6 +3999,7 @@ $(document).ready(() => {
         loadChangeDetailData() {
             const change = SpreadJsObj.getSelectObject(this.changeSheet);
             if (change) {
+                console.log(change.bills);
                 SpreadJsObj.loadSheetData(this.changeBillsSheet, SpreadJsObj.DataType.Data, change.bills);
             } else {
                 SpreadJsObj.loadSheetData(this.changeBillsSheet, SpreadJsObj.DataType.Data, []);

+ 2 - 2
app/public/js/stage_change.js

@@ -148,7 +148,7 @@ $(document).ready(() => {
                 }
             }},
             {title: '清单编号', colSpan: '1', rowSpan: '1', field: 'code', hAlign: 0, width: 80, formatter: '@', readOnly: true},
-            {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 150, type: 'Number', readOnly: true},
+            {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 150, type: '@', readOnly: true},
             {title: '单位', colSpan: '1', rowSpan: '1', field: 'unit', hAlign: 1, width: 50, formatter: '@', readOnly: true},
             {title: '单价', colSpan: '1', rowSpan: '1', field: 'unit_price', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '数量', colSpan: '1', rowSpan: '1', field: 'qty', hAlign: 2, width: 60, formatter: '@', readOnly: true},
@@ -176,7 +176,7 @@ $(document).ready(() => {
         cols: [
             {title: '相关台账|项目节编号', colSpan: '5|1', rowSpan: '1|1', field: 'leaf_xmj_code', hAlign: 0, width: 120, formatter: '@', readOnly: true},
             {title: '|名称', colSpan: '|1', rowSpan: '1', field: 'leaf_xmj_name', hAlign: 0, width: 150, formatter: '@', readOnly: true},
-            {title: '|计量单元', colSpan: '|1', rowSpan: '1', field: 'p_name', hAlign: 0, width: 150, type: 'Number', readOnly: true},
+            {title: '|计量单元', colSpan: '|1', rowSpan: '1', field: 'p_name', hAlign: 0, width: 150, type: '@', readOnly: true},
             {title: '|0号台账数量', colSpan: '|1', rowSpan: '1', field: 'f_qty', hAlign: 2, width: 80, formatter: '@', readOnly: true},
             {title: '|本期变更数量', colSpan: '|1', rowSpan: '1', field: 'qty', hAlign: 2, width: 80, type: 'Number', readOnly: true},
         ],

+ 4 - 0
app/public/report/js/rpt_custom.js

@@ -628,6 +628,10 @@ const rptCustomObj = (function () {
                 return;
             }
         }
+        if (data[sGatherSelect].tenders.length > 20) {
+            hintObj.html('您选择的标段过多,请移除部分').show();
+            return;
+        }
         hintObj.hide();
         if (resolve) {
             resolve(data);

+ 65 - 2
app/service/payment_detail.js

@@ -98,6 +98,8 @@ module.exports = app => {
                         throw '复制上一期审批流程失败';
                     }
                 }
+                // 更新is_change值
+                await transaction.update(this.ctx.service.paymentTenderRpt.tableName, { id: trInfo.id, is_change: 0 });
                 await transaction.commit();
                 return newDetail;
             } catch (err) {
@@ -110,6 +112,67 @@ module.exports = app => {
             return await this.db.update(this.tableName, { id, report_json: JSON.stringify(report_json) });
         }
 
+        async signOneSignatureData(report_json, signature_name, sign_msg) {
+            // 签名签章
+            const signCells = this._.find(report_json.items[0].signature_cells, { signature_name });
+            if (signCells && (sign_msg.sign_path || sign_msg.company_stamp || sign_msg.stamp_path)) {
+                const signArray = [];
+                if (sign_msg.sign_path) signArray.push('/public/upload/sign/' + sign_msg.sign_path);
+                if (sign_msg.company_stamp) signArray.push(sign_msg.company_stamp);
+                if (sign_msg.stamp_path) signArray.push(sign_msg.stamp_path);
+                signCells.path = signArray.join('!;!');
+            }
+            // 日期
+            const dateCells = this._.find(report_json.items[0].signature_date_cells, { signature_name: signature_name + '_签字日期' });
+            if (dateCells && sign_msg.date) {
+                dateCells.Value = sign_msg.date;
+            }
+            // 意见
+            const contentCells = this._.find(report_json.items[0].signature_audit_cells, { signature_name: signature_name + '_审核意见' });
+            if (contentCells && sign_msg.content) {
+                contentCells.Value = sign_msg.content;
+            }
+            return report_json;
+        }
+
+        async clearOneSignatureData(report_json, rptAudit) {
+            // 签名签章
+            const signCells = this._.find(report_json.items[0].signature_cells, { signature_name: rptAudit.signature_name });
+            if (signCells) {
+                signCells.path = null;
+            }
+            // 日期
+            const dateCells = this._.find(report_json.items[0].signature_date_cells, { signature_name: rptAudit.signature_name + '_签字日期' });
+            if (dateCells) {
+                dateCells.Value = '';
+            }
+            // 意见
+            const contentCells = this._.find(report_json.items[0].signature_audit_cells, { signature_name: rptAudit.signature_name + '_审核意见' });
+            if (contentCells) {
+                contentCells.Value = '';
+            }
+            return report_json;
+        }
+
+        async clearAllSignatureData(report_json) {
+            if (report_json.items[0].signature_cells.length > 0) {
+                for (const cell of report_json.items[0].signature_cells) {
+                    cell.path = null;
+                }
+            }
+            if (report_json.items[0].signature_audit_cells.length > 0) {
+                for (const cell of report_json.items[0].signature_audit_cells) {
+                    cell.Value = '';
+                }
+            }
+            if (report_json.items[0].signature_date_cells.length > 0) {
+                for (const cell of report_json.items[0].signature_date_cells) {
+                    cell.Value = '';
+                }
+            }
+            return report_json;
+        }
+
         /**
          * 删除报表表单详情
          *
@@ -143,8 +206,8 @@ module.exports = app => {
 
         async haveNotice2TenderRpt(tr_id, uid) {
             const sql = 'SELECT count(pd.`id`) as count FROM ?? as pd LEFT JOIN ?? as pda' +
-                ' ON pd.`id` = pda.`td_id` WHERE pd.`tr_id` = ? AND (pd.`uid` = ? AND (pd.`status` = ? OR pd.`status` = ?))' +
-                ' OR ((pd.`status` = ? OR pd.`status` = ?) AND pda.aid = ? AND pda.`status` = ?)';
+                ' ON pd.`id` = pda.`td_id` WHERE pd.`tr_id` = ? AND ((pd.`uid` = ? AND (pd.`status` = ? OR pd.`status` = ?))' +
+                ' OR ((pd.`status` = ? OR pd.`status` = ?) AND pda.aid = ? AND pda.`status` = ?))';
             const params = [this.tableName, this.ctx.service.paymentDetailAudit.tableName, tr_id,
                 uid, auditConst.status.uncheck, auditConst.status.checkNo,
                 auditConst.status.checking, auditConst.status.checkNoPre, uid, auditConst.status.checking];

+ 36 - 12
app/service/payment_detail_audit.js

@@ -334,21 +334,31 @@ module.exports = app => {
                 } else {
                     throw '请先选择审批人,再上报数据';
                 }
-
             }
 
             const transaction = await this.db.beginTransaction();
             try {
                 await transaction.update(this.tableName, { id: audit.id, status: auditConst.status.checking, begin_time: new Date() });
-                await transaction.update(this.ctx.service.paymentDetail.tableName, {
+                // 如果是报表角色则需要更新到detail中
+                const updateDetailData = {
                     id: detailId, status: auditConst.status.checking,
-                });
+                };
+                const rptAudit = await this.ctx.service.paymentRptAudit.getDataByCondition({ td_id: detailId, uid: this.ctx.session.sessionUser.accountId });
+                if (rptAudit && rptAudit.signature_msg) {
+                    const report_json = JSON.parse(this.ctx.detail.report_json);
+                    const sign_msg = JSON.parse(rptAudit.signature_msg);
+                    updateDetailData.report_json = JSON.stringify(await this.ctx.service.paymentDetail.signOneSignatureData(report_json, rptAudit.signature_name, sign_msg));
+                }
+                await transaction.update(this.ctx.service.paymentDetail.tableName, updateDetailData);
                 // 判断用户是否有权限查看支付审批,没有则自动加入到权限中
-                const auditList = await this.ctx.service.paymentDetailAudit.getAllDataByCondition({ where: { td_id: detailId, times } });
+                const auditList = await this.getAllDataByCondition({ where: { td_id: detailId, times } });
+                const rptAuditList = await this.ctx.service.paymentRptAudit.getAllDataByCondition({ where: { td_id: detailId } });
                 const auditIdList = this._.map(auditList, 'aid');
+                const rptAuditIdList = this._.map(rptAuditList, 'uid');
                 const permissionAuditList = await this.ctx.service.paymentPermissionAudit.getAllDataByCondition({ where: { pid: this.ctx.session.sessionProject.id } });
                 const paIdList = this._.map(permissionAuditList, 'uid');
-                const newAudits = this._.difference(auditIdList, paIdList);
+                const detailIdList = this._.union(auditIdList, rptAuditIdList);
+                const newAudits = this._.difference(detailIdList, paIdList);
                 if (newAudits.length > 0) {
                     const accountList = await this.ctx.service.projectAccount.getAllDataByCondition({
                         where: { project_id: this.ctx.session.sessionProject.id, id: newAudits },
@@ -380,22 +390,30 @@ module.exports = app => {
             try {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
 
+                // 如果是报表角色则需要更新到detail中
+                const updateDetailData = {
+                    id: detailId,
+                };
+                const rptAudit = await this.getDataByCondition({ detailId, uid: audit.aid });
+                if (rptAudit && rptAudit.signature_msg) {
+                    const report_json = JSON.parse(this.ctx.detail.report_json);
+                    const sign_msg = JSON.parse(rptAudit.signature_msg);
+                    updateDetailData.report_json = JSON.stringify(await this.ctx.service.paymentDetail.signOneSignatureData(report_json, rptAudit.signature_name, sign_msg));
+                }
+
                 // 无下一审核人表示,审核结束
                 if (nextAudit) {
                     // 流程至下一审批人
                     await transaction.update(this.tableName, { id: nextAudit.id, status: auditConst.status.checking, begin_time: time });
 
                     // 同步 期信息
-                    await transaction.update(this.ctx.service.paymentDetail.tableName, {
-                        id: detailId, status: auditConst.status.checking,
-                    });
+                    updateDetailData.status = auditConst.status.checking;
                 } else {
                     // 本期结束
                     // 同步 期信息
-                    await transaction.update(this.ctx.service.paymentDetail.tableName, {
-                        id: detailId, status: checkData.checkType,
-                    });
+                    updateDetailData.status = checkData.checkType;
                 }
+                await transaction.update(this.ctx.service.paymentDetail.tableName, updateDetailData);
                 await transaction.commit();
             } catch (err) {
                 await transaction.rollback();
@@ -410,7 +428,7 @@ module.exports = app => {
             if (!audit) {
                 throw '审核数据错误';
             }
-            const sql = 'SELECT `tid`, `tr_id`, `td_id`, `aid`, `order` FROM ?? WHERE `td_id` = ? and `times` = ? GROUP BY `aid` ORDER BY `id` ASC';
+            const sql = 'SELECT `tender_id`, `tr_id`, `td_id`, `aid`, `order` FROM ?? WHERE `td_id` = ? and `times` = ? GROUP BY `aid` ORDER BY `id` ASC';
             const sqlParam = [this.tableName, detailId, times];
             const auditors = await this.db.query(sql, sqlParam);
             let order = 1;
@@ -423,10 +441,14 @@ module.exports = app => {
             const transaction = await this.db.beginTransaction();
             try {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
+                // 清空所有签名数据
+                let report_json = JSON.parse(this.ctx.detail.report_json);
+                report_json = await this.ctx.service.paymentDetail.clearAllSignatureData(report_json);
                 // 同步期信息
                 await transaction.update(this.ctx.service.paymentDetail.tableName, {
                     id: detailId, status: checkData.checkType,
                     times: times + 1,
+                    report_json: JSON.stringify(report_json),
                 });
                 // 拷贝新一次审核流程列表
                 await transaction.insert(this.tableName, auditors);
@@ -472,6 +494,8 @@ module.exports = app => {
                     times: audit.times, order: audit.order + 2, status: auditConst.status.uncheck,
                 });
                 await transaction.insert(this.tableName, newAuditors);
+                // 清除本人的签章
+                await this.ctx.service.paymentRptAudit.clearSignatureMsg(transaction, detailId, audit.aid);
                 await transaction.commit();
             } catch (error) {
                 await transaction.rollback();

+ 44 - 1
app/service/payment_rpt_audit.js

@@ -25,7 +25,50 @@ module.exports = app => {
         }
 
         async updateSignatureMsg(td_id, uid, signature_msg) {
-            return await this.db.update(this.tableName, { sign_time: new Date(), signature_msg: JSON.stringify(signature_msg) }, { where: { td_id, uid } });
+            const transaction = await this.db.beginTransaction();
+            try {
+                // 判断是否是审批人或非它审批阶段签字签章,如果不是则需要更新到detail中
+                const rptAudit = await this.getDataByCondition({ td_id, uid });
+                if (!rptAudit) {
+                    throw '当前人不存在报表角色中';
+                }
+                if (this.ctx.detail.uid !== uid && this._.findIndex(this.ctx.detail.auditors, { aid: uid }) === -1) {
+                    let report_json = JSON.parse(this.ctx.detail.report_json);
+                    report_json = await this.ctx.service.paymentDetail.signOneSignatureData(report_json, rptAudit.signature_name, signature_msg);
+                    // 同步期信息
+                    await transaction.update(this.ctx.service.paymentDetail.tableName, {
+                        id: this.ctx.detail.id,
+                        report_json: JSON.stringify(report_json),
+                    });
+                }
+                await transaction.update(this.tableName, { sign_time: new Date(), signature_msg: JSON.stringify(signature_msg) }, { where: { td_id, uid } });
+                await transaction.commit();
+                return true;
+            } catch (error) {
+                await transaction.rollback();
+                throw error;
+            }
+        }
+
+        async clearSignatureMsg(transaction, td_id, uid) {
+            return await transaction.update(this.tableName, { sign_time: null, signature_msg: null }, { where: { td_id, uid } });
+        }
+
+        async updateAllAuditList(transaction, td_id, newRptList) {
+            const oldRptList = await this.getAllDataByCondition({ where: { td_id }, orders: [['id', 'asc']] });
+            const updateData = [];
+            for (const audit of oldRptList) {
+                const uData = {
+                    id: audit.id,
+                    signature_msg: null,
+                    sign_time: null,
+                };
+                if (audit.uid !== newRptList[audit.signature_index].uid) {
+                    uData.uid = newRptList[audit.signature_index].uid;
+                }
+                updateData.push(uData);
+            }
+            await transaction.updateRows(this.tableName, updateData);
         }
     }
 

+ 19 - 2
app/service/payment_tender_rpt.js

@@ -165,12 +165,29 @@ module.exports = app => {
             if (insertData.length > 0) await transaction.insert(this.tableName, insertData);
         }
 
-        async updateRptAudit(id, rpt_audit) {
+        async updateRptAudit(trInfo, rpt_audit) {
             const transaction = await this.db.beginTransaction();
             try {
                 // 判断是否存在null
+                if (!trInfo.is_first && this._.findIndex(rpt_audit, { uid: null }) !== -1) {
+                    throw '请绑定所有表单角色再提交';
+                }
+                // 判断是否存在待上报或者退回的详情,有则同步更新
+                const detailList = await this.ctx.service.paymentDetail.getAllDataByCondition({ where: { tr_id: trInfo.id }, orders: [['id', 'desc']] });
+                if (!trInfo.is_change && detailList.length > 0 && (detailList[0].status === auditConst.status.uncheck || detailList[0].status === auditConst.status.checkNo)) {
+                    if (this._.findIndex(rpt_audit, { uid: null }) !== -1) {
+                        throw '未配置好表单角色';
+                    }
+                    await this.ctx.service.paymentRptAudit.updateAllAuditList(transaction, detailList[0].id, rpt_audit);
+                    let report_json = JSON.parse(detailList[0].report_json);
+                    report_json = await this.ctx.service.paymentDetail.clearAllSignatureData(report_json);
+                    await transaction.update(this.ctx.service.paymentDetail.tableName, {
+                        id: detailList[0].id,
+                        report_json: JSON.stringify(report_json),
+                    });
+                }
                 const is_first = this._.findIndex(rpt_audit, { uid: null }) === -1 ? 0 : 1;
-                await transaction.update(this.tableName, { id, rpt_audit: JSON.stringify(rpt_audit), is_first });
+                await transaction.update(this.tableName, { id: trInfo.id, rpt_audit: JSON.stringify(rpt_audit), is_first });
                 await transaction.commit();
                 return { is_first };
             } catch (err) {

+ 1 - 1
app/service/tender_cache.js

@@ -230,7 +230,7 @@ module.exports = app => {
                 info.status = status;
                 data.stage_flow_cur_info = JSON.stringify(info);
             }
-            if (status === auditConst.stage.status.checked && !auditor) data.stage_complete_count = data.stage_count;
+            if (status === auditConst.stage.status.checked && !auditor) data.stage_complete_count = stage.order;
             data.stage_flow_cur_tp = JSON.stringify(tp);
             await transaction.update(this.tableName, data);
         }

+ 6 - 8
app/view/file/file.ejs

@@ -21,9 +21,7 @@
                         <div class="p-2 ml-2">分类目录</div>
                         <% } %>
                     </div>
-                    <div>
-                        <ul id="filing" class="ztree"></ul>
-                    </div>
+                    <ul id="filing" class="ztree" style="overflow: auto"></ul>
                 </div>
                 <div class="col-9" id="file-view" style="display: none">
                     <div class="d-flex flex-row">
@@ -44,11 +42,11 @@
                     <table class="table table-bordered">
                         <thead>
                         <tr class="text-center">
-                            <th>选择</th>
-                            <th width="45%">文件名称</th>
-                            <th>上传人</th>
-                            <th>上传时间</th>
-                            <th>文件类型</th>
+                            <th width="60px">选择</th>
+                            <th>文件名称</th>
+                            <th width="10%">上传人</th>
+                            <th width="20%">上传时间</th>
+                            <th width="10%">文件类型</th>
                         </tr>
                         </thead>
                         <tbody id="file-list">

+ 72 - 45
app/view/payment/audit_modal.ejs

@@ -1,59 +1,85 @@
 <% if ((ctx.detail.status === auditConst.status.uncheck || ctx.detail.status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === ctx.detail.uid) { %>
     <!--上报审批-->
     <div class="modal fade" id="sub-sp" data-backdrop="static">
-        <div class="modal-dialog" role="document">
+        <div class="modal-dialog modal-lg" role="document">
             <div class="modal-content">
                 <div class="modal-header">
                     <h5 class="modal-title">上报审批</h5>
                 </div>
                 <div class="modal-body">
-                    <div class="dropdown text-right">
-                        <% if (trInfo.sp_status !== shenpiConst.sp_status.gdspl && ctx.session.sessionUser.accountId === ctx.detail.uid) { %>
-                            <button class="btn btn-outline-primary btn-sm dropdown-toggle" type="button"
-                                    id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true"
-                                    aria-expanded="false">
-                                添加审批流程
-                            </button>
-                            <div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton"
-                                 style="width:220px">
-                                <div class="mb-2 p-2"><input class="form-control form-control-sm"
-                                                             placeholder="姓名/手机 检索" id="gr-search" autocomplete="off"></div>
-                                <dl class="list-unstyled book-list">
-                                    <% accountGroup.forEach((group, idx) => { %>
-                                        <dt><a href="javascript: void(0);" class="acc-btn" data-groupid="<%- idx %>" data-type="hide"><i class="fa fa-plus-square"></i></a> <%- group.groupName %></dt>
-                                        <div class="dd-content" data-toggleid="<%- idx %>">
-                                            <% group.groupList.forEach(item => { %>
-                                                <% if (item.id !== ctx.session.sessionUser.accountId) { %>
-                                                    <dd class="border-bottom p-2 mb-0 " data-id="<%- item.id %>" >
-                                                        <p class="mb-0 d-flex"><span class="text-primary"><%- item.name %></span><span
-                                                                    class="ml-auto"><%- item.mobile %></span></p>
-                                                        <span class="text-muted"><%- item.role %></span>
-                                                    </dd>
-                                                <% } %>
-                                            <% });%>
-                                        </div>
-                                    <% }) %>
-                                </dl>
+                    <div class="row">
+                        <div class="col-5">
+                            <% if (trInfo.sp_status !== shenpiConst.sp_status.gdspl && ctx.session.sessionUser.accountId === ctx.detail.uid) { %>
+                                <div class="dropdown text-right pt-1">&nbsp;</div>
+                            <% } %>
+                            <div class="card mt-3">
+                                <div class="card-header">
+                                    报表表单角色
+                                </div>
+                                <ul class="list-group list-group-flush">
+                                    <% for (const [index, ra] of rptAuditList.entries()) { %>
+                                        <li class="list-group-item">
+                                            <div class="row">
+                                                <span class="col-2"><%- index+1 %></span>
+                                                <span class="col-6"><%- ra.signature_name %></span>
+                                                <span class="col-4"><%- ctx.helper._.findIndex(accountList, { id: ra.uid }) !== -1 ? ctx.helper._.find(accountList, { id: ra.uid }).name : '' %></span>
+                                            </div>
+                                        </li>
+                                    <% } %>
+                                </ul>
                             </div>
-                        <% } %>
-                    </div>
-                    <div class="card mt-3">
-                        <div class="card-header">
-                            审批流程
                         </div>
-                        <div class="modal-height-500" style="overflow: auto">
-                            <ul class="list-group list-group-flush" id="auditors">
-                                <% for (let i = 0, iLen = ctx.detail.auditorList.length; i < iLen; i++) { %>
-                                    <li class="list-group-item" auditorId="<%- ctx.detail.auditorList[i].aid %>">
-                                        <% if ((trInfo.sp_status === shenpiConst.sp_status.sqspr ||
-                                                (trInfo.sp_status === shenpiConst.sp_status.gdzs && i+1 !== iLen)) && ctx.session.sessionUser.accountId === ctx.detail.uid) { %>
-                                            <a href="javascript: void(0)" class="text-danger pull-right">移除</a>
-                                        <% } %>
-                                        <span><%- ctx.detail.auditorList[i].order %> <%- ctx.detail.auditorList[i].name %></span>
-                                        <small class="text-muted"><%- ctx.detail.auditorList[i].role %></small>
-                                    </li>
+                        <div class="col-7" style="overflow: auto">
+                            <div class="dropdown text-right">
+                                <% if (trInfo.sp_status !== shenpiConst.sp_status.gdspl && ctx.session.sessionUser.accountId === ctx.detail.uid) { %>
+                                    <button class="btn btn-outline-primary btn-sm dropdown-toggle" type="button"
+                                            id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true"
+                                            aria-expanded="false">
+                                        添加审批流程
+                                    </button>
+                                    <div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton"
+                                         style="width:220px">
+                                        <div class="mb-2 p-2"><input class="form-control form-control-sm"
+                                                                     placeholder="姓名/手机 检索" id="gr-search" autocomplete="off"></div>
+                                        <dl class="list-unstyled book-list">
+                                            <% accountGroup.forEach((group, idx) => { %>
+                                                <dt><a href="javascript: void(0);" class="acc-btn" data-groupid="<%- idx %>" data-type="hide"><i class="fa fa-plus-square"></i></a> <%- group.groupName %></dt>
+                                                <div class="dd-content" data-toggleid="<%- idx %>">
+                                                    <% group.groupList.forEach(item => { %>
+                                                        <% if (item.id !== ctx.session.sessionUser.accountId) { %>
+                                                            <dd class="border-bottom p-2 mb-0 " data-id="<%- item.id %>" >
+                                                                <p class="mb-0 d-flex"><span class="text-primary"><%- item.name %></span> <% if (ctx.helper._.findIndex(rptAuditList, { uid: item.id }) !== -1) { %>&nbsp;(<%- ctx.helper._.find(rptAuditList, { uid: item.id }).signature_name %>)<% } %><span
+                                                                            class="ml-auto"><%- item.mobile %></span></p>
+                                                                <span class="text-muted"><%- item.role %></span>
+                                                            </dd>
+                                                        <% } %>
+                                                    <% });%>
+                                                </div>
+                                            <% }) %>
+                                        </dl>
+                                    </div>
                                 <% } %>
-                            </ul>
+                            </div>
+                            <div class="card mt-3">
+                                <div class="card-header">
+                                    审批流程
+                                </div>
+                                <div class="modal-height-500" style="overflow: auto">
+                                    <ul class="list-group list-group-flush" id="auditors">
+                                        <% for (let i = 0, iLen = ctx.detail.auditorList.length; i < iLen; i++) { %>
+                                            <li class="list-group-item" auditorId="<%- ctx.detail.auditorList[i].aid %>">
+                                                <% if ((trInfo.sp_status === shenpiConst.sp_status.sqspr ||
+                                                        (trInfo.sp_status === shenpiConst.sp_status.gdzs && i+1 !== iLen)) && ctx.session.sessionUser.accountId === ctx.detail.uid) { %>
+                                                    <a href="javascript: void(0)" class="text-danger pull-right">移除</a>
+                                                <% } %>
+                                                <span><%- ctx.detail.auditorList[i].order %> <%- ctx.detail.auditorList[i].name %></span>
+                                                <% if (ctx.helper._.findIndex(rptAuditList, { uid: ctx.detail.auditorList[i].aid }) !== -1) { %>&nbsp;(<%- ctx.helper._.find(rptAuditList, { uid: ctx.detail.auditorList[i].aid }).signature_name %>)<% } %>
+                                                <small class="text-muted"><%- ctx.detail.auditorList[i].role %></small>
+                                            </li>
+                                        <% } %>
+                                    </ul>
+                                </div>
+                            </div>
                         </div>
                     </div>
                 </div>
@@ -750,6 +776,7 @@
         const accountList = JSON.parse(unescape('<%- escape(JSON.stringify(accountList)) %>'));
         const shenpi_status = <%- trInfo.sp_status %>;
         const shenpiConst =  JSON.parse('<%- JSON.stringify(shenpiConst) %>');
+        const rptAuditList = JSON.parse(unescape('<%- escape(JSON.stringify(rptAuditList)) %>'));
     </script>
 <% } %>
 <script>const cur_uid = parseInt('<%- ctx.session.sessionUser.accountId %>');</script>

+ 17 - 3
app/view/payment/detail.ejs

@@ -12,10 +12,14 @@
         <div class="title-main  d-flex justify-content-between">
             <div><a href="/payment/<%- ctx.tender.id %>/list/<%- trInfo.id %>"><i class="fa fa-chevron-left mr-2"></i></a><%- ctx.tender.name %> / <%- trInfo.rpt_name %> / <%- ctx.detail.code %></div>
             <div>
+                <% if ((ctx.detail.status == auditConst.status.uncheck || ctx.detail.status == auditConst.status.checkNo) && trInfo.is_change) { %>
+                <span class="text-danger pull-right">报表内容已发生变化,请删除并重新生成详情</span>
+                <% } else { %>
                 <% include ./audit_btn.ejs %>
-                <% if (rptAudit) { %>
+                <% if (ctx.detail.status !== auditConst.status.checked && rptAudit) { %>
                 <a href="#sub-sp5" data-toggle="modal" data-target="#sub-sp5" class="btn btn-sm btn-primary pull-right mr-2">签字意见</a>
                 <% } %>
+                <% } %>
             </div>
         </div>
     </div>
@@ -23,7 +27,7 @@
         <div class="c-body">
             <div class="sjs-height-0">
                 <div class="row m-0 mt-3">
-                    <div id="rpt-form" class="col-6">
+                    <div id="rpt-form" class="col-5 mr-3">
                         <% for (const c of content) { %>
                         <div>
                             <h5><%- c.title %>内容</h5>
@@ -40,7 +44,7 @@
                         </div>
                         <% } %>
                     </div>
-                    <div class="col-6">
+                    <div class="col-6 ml-5">
                         <div class="d-flex flex-row">
                             <a href="javascript: void(0);" onclick="auditRptPrintHelper.showPage()" class="mr-2" >刷新</a>
                             <a href="javascript: void(0);" class="mr-2"  onclick="auditRptPrintHelper.directPDF()">导出pdf</a>
@@ -61,7 +65,9 @@
     const detailId = parseInt('<%- ctx.detail.id %>');
     const rptAudit = JSON.parse(unescape('<%- escape(JSON.stringify(rptAudit)) %>'));
     console.log(rptAudit);
+    <% if (ctx.detail.status !== auditConst.status.checked && rptAudit) { %>
     let currentStamp = JSON.parse(unescape('<%- escape(JSON.stringify(currentStamp)) %>'));
+    <% } %>
     let tesRpttData = JSON.parse(unescape('<%- escape(JSON.stringify(report_json)) %>'));
     console.log(tesRpttData);
     const SCREEN_DPI = [];
@@ -171,6 +177,7 @@
         auditRptPrintHelper.showPage();
         iniPage();
     });
+<<<<<<< HEAD
     
     function _getAdhocDummyCells(srcCell, rstCells) {
         if (typeof srcCell.path === 'string') {
@@ -189,6 +196,13 @@
                 }
             }
         }
+=======
+
+    function _getAdhocDummyCells(picPath) {
+        const rst = [];
+        //
+        return rst;
+>>>>>>> 8d28ec2311a15494a0f6bc4ae5392673406e890c
     }
 
     function downloadPDFReport(pageDataArr, pageSize, rpt_names, signatureRelArr, signatureRelInfo, refRptTplIds, STAGE_AUDIT) {

+ 1 - 1
app/view/payment/detail_modal.ejs

@@ -1,4 +1,4 @@
-<% if (rptAudit) { %>
+<% if (ctx.detail.status !== auditConst.status.checked && rptAudit) { %>
 <!--签字意见-->
 <div class="modal fade" id="sub-sp5" data-backdrop="static">
     <div class="modal-dialog" role="document">

+ 4 - 1
app/view/payment/list.ejs

@@ -7,8 +7,10 @@
                 <% if (trDetailList.length === 0 || trDetailList[0].status === auditConst.status.checked) { %>
                 <a href="javascript:void(0);" id="show-add-btn" class="btn btn-sm btn-primary pull-right ml-2">新建审批</a>
                 <% } %>
+                <% if (trDetailList.length === 0 || trDetailList[0].status === auditConst.status.uncheck || trDetailList[0].status === auditConst.status.checkNo) { %>
                 <a href="#set-bdjs" data-toggle="modal" data-target="#set-bdjs" class="btn btn-sm btn-primary pull-right">绑定表单角色</a>
-                <span class="text-danger pull-right" id="first_msg" <% if (trInfo.is_first === 0) { %>style="display:none;" <% } %>>未配置表单角色,请点击右侧的“绑定表单角色” &nbsp; &nbsp; </span>
+                <span class="text-danger pull-right" id="first_msg" <% if (trInfo.is_first === 0) { %>style="display:none;" <% } %>>第一次新建审批,请点击右侧的“绑定表单角色” &nbsp; &nbsp; </span>
+                <% } %>
                 <% } %>
             </div>
         </div>
@@ -86,5 +88,6 @@
     const auditConst = JSON.parse(unescape('<%- escape(JSON.stringify(auditConst)) %>'));
     let rpt_audit = JSON.parse(unescape('<%- escape(JSON.stringify(trInfo.rpt_audit)) %>'));
     let old_rpt_audit = _.cloneDeep(rpt_audit);
+    const is_first = parseInt('<%- trInfo.is_first %>');
     console.log(rpt_audit);
 </script>

+ 1 - 1
app/view/tender/shenpi.ejs

@@ -17,7 +17,7 @@
                                     <a class="pull-right set-otherTender" data-name="<%- sp.name %>" data-code="<%- sp.code %>" href="#batch" data-toggle="modal" data-target="#batch">设置其他标段</a>
                                     <a class="pull-right set-otherShenpi mr-3" data-name="<%- sp.name %>" data-code="<%- sp.code %>" href="#batch2" data-toggle="modal" data-target="#batch2">设置其他流程</a>
                                     <% if (sp.code === 'stage' && !revising && ctx.tender.data.ledger_status === auditConst.ledger.status.checked) { %>
-                                    <a class="pull-right mr-3" id="stage_cooperation" <% if (sp.status !== shenpi.sp_status.gdspl) { %>style="display: none"<% } %> data-name="<%- sp.name %>" data-code="<%- sp.code %>" href="#cooperation" data-toggle="modal" data-target="#cooperation">多人协同 <i class="fa fa-lock"></i> <span id="cooperation-num"><%- cooperationNum %></span></a>
+                                    <a class="pull-right mr-3" id="stage_cooperation" <% if (sp.status !== shenpi.sp_status.gdspl) { %>style="display: none"<% } %> data-name="<%- sp.name %>" data-code="<%- sp.code %>" href="#cooperation" data-toggle="modal" data-target="#cooperation">多人协同 <i class="fa fa-lock"></i></a>
                                     <% } %>
                                     <h5 class="card-title"><%- sp.name %></h5>
                                     <div class="form-group">