Ver código fonte

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

Tony Kang 3 anos atrás
pai
commit
db7d7cdcfb

+ 1 - 0
app/controller/change_controller.js

@@ -3564,6 +3564,7 @@ module.exports = app => {
                 ctx.redirect(ctx.request.header.referer);
             } catch (err) {
                 this.log(err);
+                console.log(err);
                 ctx.session.postError = err.toString();
                 ctx.redirect(ctx.request.header.referer);
             }

+ 50 - 0
app/controller/wap_controller.js

@@ -129,6 +129,11 @@ module.exports = app => {
             }
             // 获取待审批的变更期
             const auditChanges = await ctx.service.changeAudit.getAuditChangeByWap(ctx.session.sessionUser.accountId);
+            // 获取待审批的变更方案
+            let auditChangePlans = [];
+            if (ctx.session.sessionProject.page_show.openChangePlan) {
+                auditChangePlans = await ctx.service.changePlanAudit.getAuditChangePlanByWap(ctx.session.sessionUser.accountId);
+            }
             // 获取待审批的台账修订
             const auditRevise = await ctx.service.reviseAudit.getAuditReviseByWap(ctx.session.sessionUser.accountId);
             for (const revise of auditRevise) {
@@ -140,6 +145,7 @@ module.exports = app => {
             const renderData = {
                 auditStages,
                 auditChanges,
+                auditChangePlans,
                 auditRevise,
                 auditAdvance,
                 changeConst,
@@ -262,6 +268,15 @@ module.exports = app => {
                     c.curAuditor = await ctx.service.changeAudit.getLastUser(c.cid, c.times);
                 }
 
+                // 变更令列表
+                let changePlans = [];
+                if (ctx.session.sessionProject.page_show.openChangePlan) {
+                    changePlans = await ctx.service.changePlan.getListByStatus(tender.id, 0, 0);
+                    for (const c of changePlans) {
+                        c.curAuditor = await ctx.service.changePlanAudit.getAuditorByStatus(c.id, c.status, c.times);
+                    }
+                }
+
                 // 台账修订列表
                 const revises = await ctx.service.ledgerRevise.getReviseList(ctx.tender.id);
                 for (const lr of revises) {
@@ -281,10 +296,12 @@ module.exports = app => {
                     tender,
                     stages,
                     changes,
+                    changePlans,
                     revises,
                     advanceList,
                     auditConst: auditConst.stage,
                     auditChangeConst: auditConst.flow,
+                    auditChangePlanConst: auditConst.changePlan,
                     auditReviseConst: auditConst.revise,
                     changeConst,
                     advanceConst,
@@ -377,6 +394,39 @@ module.exports = app => {
         }
 
         /**
+         * 变更方案审批详细页
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        async changePlan(ctx) {
+            try {
+                const tender = ctx.tender.data;
+                if (!ctx.session.sessionProject.page_show.openChangePlan) {
+                    throw '该功能已关闭';
+                }
+                const change = await ctx.service.changePlan.getDataById(ctx.params.cpid);
+                const renderData = {
+                    tender,
+                    change,
+                    auditConst: auditConst.changePlan,
+                    changeConst,
+                    tpUnit: ctx.tender.info.decimal.tp,
+                };
+                const times = change.status !== auditConst.changePlan.status.checkNo ? change.times : change.times - 1;
+                renderData.change.user = await ctx.service.projectAccount.getAccountInfoById(change.uid);
+                renderData.change.auditors = await ctx.service.changePlanAudit.getAuditors(change.id, times);
+                // 获取审批流程中左边列表
+                renderData.change.auditors2 = await ctx.service.changePlanAudit.getAuditGroupByList(change.id, times);
+                await ctx.render('wap/shenpi_change_plan.ejs', renderData);
+            } catch (err) {
+                this.log(err);
+                ctx.redirect('/wap/list');
+            }
+        }
+
+
+        /**
          * 修订审批详细页
          *
          * @param {Object} ctx - egg全局变量

+ 3 - 2
app/lib/wechat.js

@@ -9,6 +9,7 @@
  */
 
 // const xmlReader = require('xmlreader');
+const _ = require('lodash');
 const moment = require('moment');
 const wxConst = require('../const/wechat_template.js');
 class WX {
@@ -69,8 +70,8 @@ class WX {
                         break;
                     case wxConst.template.change:
                         templateId = wxConst.templateId.change;
-                        url = data.type ? '' : this.ctx.protocol + '://' + this.ctx.host + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url;
-                        remark = data.status === wxConst.status.check ? (data.type ? '微信暂无法在线审批' : '微信可快速审批,如需进行详细审批') :
+                        url = data.wap_url ? this.ctx.protocol + '://' + this.ctx.host + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url : '';
+                        remark = data.status === wxConst.status.check ? (data.type && _.indexOf(['apply', 'project'], data.type) !== -1 ? '微信暂无法在线审批' : '微信可快速审批,如需进行详细审批') :
                             (data.status === wxConst.status.success ? '审批已通过,查看审批结果' :
                                 (data.status === wxConst.status.back ? '审批被退回,查看退回结果' : '审批已终止,查看终止结果'));
                         msgData = {

+ 1 - 0
app/router.js

@@ -596,6 +596,7 @@ module.exports = app => {
     app.get('/wap/tender/:id', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.tender');
     app.get('/wap/tender/:id/stage/:order', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.stage');
     app.get('/wap/tender/:id/change/:cid/info', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.change');
+    app.get('/wap/tender/:id/change/plan/:cpid/info', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.changePlan');
     app.post('/wap/tender/:id/change/approval', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.changeApproval');
     app.get('/wap/tender/:id/revise/:rid/info', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.revise');
     app.get('/wap/tender/:id/advance', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.advance');

+ 7 - 4
app/service/advance_audit.js

@@ -269,7 +269,7 @@ module.exports = app => {
             try {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
                 // 获取推送必要信息
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, advanceId, audit.audit_id);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, advanceId, audit.audit_id, checkData.opinion);
                 // 添加推送
                 const records = [{ pid, type: pushType.advance, uid: this.ctx.advance.uid, status: auditConst.status.checked, content: noticeContent }];
                 auditors.forEach(audit => {
@@ -350,7 +350,7 @@ module.exports = app => {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
 
                 // 添加到消息推送表
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, advanceId, audit.audit_id);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, advanceId, audit.audit_id, checkData.opinion);
                 const records = [{ pid, type: pushType.advance, uid: this.ctx.advance.uid, status: auditConst.status.checkNo, content: noticeContent }];
                 auditors.forEach(audit => {
                     records.push({ pid, type: pushType.advance, uid: audit.audit_id, status: auditConst.status.checkNo, content: noticeContent });
@@ -400,7 +400,7 @@ module.exports = app => {
                 return item.audit_id === audit.audit_id;
             });
             const preAuditor = auditors2[auditorIndex - 1];
-            const noticeContent = await this.getNoticeContent(pid, audit.tid, advanceId, audit.audit_id);
+            const noticeContent = await this.getNoticeContent(pid, audit.tid, advanceId, audit.audit_id, checkData.opinion);
             const transaction = await this.db.beginTransaction();
             try {
                 // 添加到消息推送表
@@ -491,7 +491,7 @@ module.exports = app => {
          * @param {Number} vid 预付款id
          * @param {Number} uid 审批人id
          */
-        async getNoticeContent(pid, tid, vid, uid) {
+        async getNoticeContent(pid, tid, vid, uid, opinion = '') {
             const noticeSql =
                 'SELECT * FROM (SELECT ' +
                 '  t.`id` As `tid`, ad.`vid`, t.`name`, m.`order`, pa.`name` As `su_name`, pa.role As `su_role`' +
@@ -511,6 +511,9 @@ module.exports = app => {
                 pid,
             ];
             const content = await this.db.query(noticeSql, noticeSqlParam);
+            if (content.length) {
+                content[0].opinion = opinion;
+            }
             return content.length ? JSON.stringify(content[0]) : '';
         }
 

+ 8 - 5
app/service/change.js

@@ -712,7 +712,7 @@ module.exports = app => {
                 // console.log('auditors', auditors);
                 // console.log('postData', postData);
                 // 添加到消息推送表
-                const noticeContent = await this.getNoticeContent(pid, changeData.tid, changeData.cid, this.ctx.session.sessionUser.accountId);
+                const noticeContent = await this.getNoticeContent(pid, changeData.tid, changeData.cid, this.ctx.session.sessionUser.accountId, postData.sdesc);
                 const records = [];
                 auditors.forEach(auditor => {
                     records.push({
@@ -896,7 +896,7 @@ module.exports = app => {
                 // 获取所有审核人列表
                 const auditors = await this.ctx.service.changeAudit.getAllAuditors(changeData.tid);
                 // 添加到消息推送表
-                const noticeContent = await this.getNoticeContent(pid, changeData.tid, changeData.cid, this.ctx.session.sessionUser.accountId);
+                const noticeContent = await this.getNoticeContent(pid, changeData.tid, changeData.cid, this.ctx.session.sessionUser.accountId, postData.sdesc);
                 const records = [];
                 auditors.forEach(auditor => {
                     records.push({
@@ -1010,7 +1010,7 @@ module.exports = app => {
                 // 获取所有审核人列表
                 const auditors = await this.ctx.service.changeAudit.getAllAuditors(changeData.tid);
                 // 添加到消息推送表
-                const noticeContent = await this.getNoticeContent(pid, changeData.tid, changeData.cid, this.ctx.session.sessionUser.accountId);
+                const noticeContent = await this.getNoticeContent(pid, changeData.tid, changeData.cid, this.ctx.session.sessionUser.accountId, postData.sdesc);
                 const records = [];
                 auditors.forEach(auditor => {
                     records.push({
@@ -1358,7 +1358,7 @@ module.exports = app => {
                 // 获取所有审核人列表
                 const auditors = await this.ctx.service.changeAudit.getAllAuditors(changeData.tid);
                 // 添加到消息推送表
-                const noticeContent = await this.getNoticeContent(pid, changeData.tid, changeData.cid, this.ctx.session.sessionUser.accountId);
+                const noticeContent = await this.getNoticeContent(pid, changeData.tid, changeData.cid, this.ctx.session.sessionUser.accountId, '发起重新审批');
                 const records = [];
                 auditors.forEach(auditor => {
                     records.push({
@@ -1601,7 +1601,7 @@ module.exports = app => {
          * @param {Number} cid 变更id
          * @param {Number} uid 审核人id
          */
-        async getNoticeContent(pid, tid, cid, uid) {
+        async getNoticeContent(pid, tid, cid, uid, opinion = '') {
             const noticeSql =
                 'SELECT * FROM (SELECT ' +
                 '  t.`id` As `tid`, t.`name`, c.`cid`, c.`code` As `c_code`, pa.`name` As `su_name`, pa.role As `su_role`' +
@@ -1611,6 +1611,9 @@ module.exports = app => {
                 '  WHERE  t.`project_id` = ? ) as new_t GROUP BY new_t.`tid`';
             const noticeSqlParam = [this.ctx.service.tender.tableName, tid, this.ctx.service.change.tableName, cid, this.ctx.service.projectAccount.tableName, uid, pid];
             const content = await this.db.query(noticeSql, noticeSqlParam);
+            if (content.length) {
+                content[0].opinion = opinion;
+            }
             return content.length ? JSON.stringify(content[0]) : '';
         }
 

+ 6 - 3
app/service/change_apply_audit.js

@@ -313,7 +313,7 @@ module.exports = app => {
          * @param {Number} caId 立项书id
          * @param {Number} uid 审批人id
          */
-        async getNoticeContent(pid, tid, caId, uid) {
+        async getNoticeContent(pid, tid, caId, uid, opinion = '') {
             const noticeSql = 'SELECT * FROM (SELECT ' +
                 '  t.`id` As `tid`, ma.`caid`, m.`code` as `c_code`, t.`name`, pa.`name` As `su_name`, pa.role As `su_role`' +
                 '  FROM (SELECT * FROM ?? WHERE `id` = ? ) As t' +
@@ -323,6 +323,9 @@ module.exports = app => {
                 '  WHERE  t.`project_id` = ? ) as new_t GROUP BY new_t.`tid`';
             const noticeSqlParam = [this.ctx.service.tender.tableName, tid, this.ctx.service.changeApply.tableName, caId, this.tableName, this.ctx.service.projectAccount.tableName, uid, pid];
             const content = await this.db.query(noticeSql, noticeSqlParam);
+            if (content.length) {
+                content[0].opinion = opinion;
+            }
             return content.length ? JSON.stringify(content[0]) : '';
         }
 
@@ -372,7 +375,7 @@ module.exports = app => {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
 
                 // 获取推送必要信息
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, caId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, caId, audit.aid, checkData.opinion);
                 // 添加推送
                 const records = [{ pid, type: pushType.changeApply, uid: this.ctx.change.uid, status: auditConst.status.checked, content: noticeContent }];
                 auditors.forEach(audit => {
@@ -448,7 +451,7 @@ module.exports = app => {
             try {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
                 // 添加到消息推送表
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, caId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, caId, audit.aid, checkData.opinion);
                 const records = [{ pid, type: pushType.changeApply, uid: this.ctx.change.uid, status: auditConst.status.checkNo, content: noticeContent }];
                 auditors.forEach(audit => {
                     records.push({ pid, type: pushType.changeApply, uid: audit.aid, status: auditConst.status.checkNo, content: noticeContent });

+ 1 - 1
app/service/change_plan.js

@@ -134,7 +134,7 @@ module.exports = app => {
             let sql = '';
             let sqlParam = '';
             if (this.ctx.tender.isTourist && status === 0) {
-                sql = 'SELECT a.*, p.name as account_name FROM ?? As a LEFT JOIN ?? AS p On a.notice_uid = p.id WHERE a.tid = ?';
+                sql = 'SELECT a.*, p.name as account_name FROM ?? As a LEFT JOIN ?? AS p On a.uid = p.id WHERE a.tid = ?';
                 sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId];
             } else {
                 switch (status) {

+ 52 - 6
app/service/change_plan_audit.js

@@ -95,7 +95,7 @@ module.exports = app => {
             switch (status) {
                 case auditConst.status.checking :
                 case auditConst.status.checked :
-                    sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cpid`, la.`aid`, la.`order` ' +
+                    sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cpid`, la.`aid`, la.`order`, la.`status` ' +
                         '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id` ' +
                         '  WHERE la.`cpid` = ? and la.`status` = ? ' +
                         '  ORDER BY la.`times` desc, la.`order` desc';
@@ -103,7 +103,7 @@ module.exports = app => {
                     auditor = await this.db.queryOne(sql, sqlParam);
                     break;
                 case auditConst.status.checkNo :
-                    sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cpid`, la.`aid`, la.`order` ' +
+                    sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cpid`, la.`aid`, la.`order`, la.`status` ' +
                         '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id`' +
                         '  WHERE la.`cpid` = ? and la.`status` = ? and la.`times` = ?' +
                         '  ORDER BY la.`times` desc, la.`order` desc';
@@ -271,8 +271,12 @@ module.exports = app => {
                     id: cpId, status: auditConst.status.checking,
                 });
                 // 微信模板通知
+                const shenpiUrl = await this.ctx.helper.urlToShort(
+                    this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + this.ctx.tender.id + '/change/plan/' + cpId + '/info#shenpi'
+                );
                 const wechatData = {
                     type: 'plan',
+                    wap_url: shenpiUrl,
                     status: wxConst.status.check,
                     tips: wxConst.tips.check,
                     code: this.ctx.session.sessionProject.code,
@@ -313,7 +317,7 @@ module.exports = app => {
          * @param {Number} cpId 方案id
          * @param {Number} uid 审批人id
          */
-        async getNoticeContent(pid, tid, cpId, uid) {
+        async getNoticeContent(pid, tid, cpId, uid, opinion = '') {
             const noticeSql = 'SELECT * FROM (SELECT ' +
                 '  t.`id` As `tid`, ma.`cpid`, m.`code` as `c_code`, t.`name`, pa.`name` As `su_name`, pa.role As `su_role`' +
                 '  FROM (SELECT * FROM ?? WHERE `id` = ? ) As t' +
@@ -323,6 +327,9 @@ module.exports = app => {
                 '  WHERE  t.`project_id` = ? ) as new_t GROUP BY new_t.`tid`';
             const noticeSqlParam = [this.ctx.service.tender.tableName, tid, this.ctx.service.changePlan.tableName, cpId, this.tableName, this.ctx.service.projectAccount.tableName, uid, pid];
             const content = await this.db.query(noticeSql, noticeSqlParam);
+            if (content.length) {
+                content[0].opinion = opinion;
+            }
             return content.length ? JSON.stringify(content[0]) : '';
         }
 
@@ -372,7 +379,7 @@ module.exports = app => {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
 
                 // 获取推送必要信息
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, cpId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, cpId, audit.aid, checkData.opinion);
                 // 添加推送
                 const records = [{ pid, type: pushType.changePlan, uid: this.ctx.change.uid, status: auditConst.status.checked, content: noticeContent }];
                 auditors.forEach(audit => {
@@ -394,8 +401,12 @@ module.exports = app => {
                     });
 
                     // 微信模板通知
+                    const shenpiUrl = await this.ctx.helper.urlToShort(
+                        this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + this.ctx.tender.id + '/change/plan/' + cpId + '/info#shenpi'
+                    );
                     const wechatData = {
                         type: 'plan',
+                        wap_url: shenpiUrl,
                         status: wxConst.status.check,
                         tips: wxConst.tips.check,
                         code: this.ctx.session.sessionProject.code,
@@ -413,8 +424,12 @@ module.exports = app => {
 
                     // 微信模板通知
                     const users = this._.uniq(this._.concat(this._.map(auditors, 'aid'), this.ctx.change.uid));
+                    const shenpiUrl = await this.ctx.helper.urlToShort(
+                        this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + this.ctx.tender.id + '/change/plan/' + cpId + '/info#shenpi'
+                    );
                     const wechatData = {
                         type: 'plan',
+                        wap_url: shenpiUrl,
                         status: wxConst.status.success,
                         tips: wxConst.tips.success,
                         code: this.ctx.session.sessionProject.code,
@@ -450,7 +465,7 @@ module.exports = app => {
             try {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
                 // 添加到消息推送表
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, cpId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, cpId, audit.aid, checkData.opinion);
                 const records = [{ pid, type: pushType.changePlan, uid: this.ctx.change.uid, status: auditConst.status.checkNo, content: noticeContent }];
                 auditors.forEach(audit => {
                     records.push({ pid, type: pushType.changePlan, uid: audit.aid, status: auditConst.status.checkNo, content: noticeContent });
@@ -467,8 +482,12 @@ module.exports = app => {
                 await this.ctx.service.changePlanList.delAuditAmount(transaction, cpId);
                 // 微信模板通知
                 const users = this._.uniq(this._.concat(this._.map(auditors, 'aid'), this.ctx.change.uid));
+                const shenpiUrl = await this.ctx.helper.urlToShort(
+                    this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + this.ctx.tender.id + '/change/plan/' + cpId + '/info#shenpi'
+                );
                 const wechatData = {
                     type: 'plan',
+                    wap_url: shenpiUrl,
                     status: wxConst.status.back,
                     tips: wxConst.tips.back,
                     code: this.ctx.session.sessionProject.code,
@@ -516,7 +535,34 @@ module.exports = app => {
             const sqlParam = [tenderId];
             return this.db.query(sql, sqlParam);
         }
-    }
 
+        /**
+         * 取待审批期列表(wap用)
+         *
+         * @param auditorId
+         * @return {Promise<*>}
+         */
+        async getAuditChangePlanByWap(auditorId) {
+            const sql =
+                'SELECT sa.`aid`, sa.`times`, sa.`begin_time`, sa.`end_time`, sa.`tid`, sa.`cpid`,' +
+                '    s.*,' +
+                '    t.`name` as `t_name`, t.`project_id`, t.`type`, t.`user_id`,' +
+                '    ti.`deal_info`, ti.`decimal` ' +
+                '  FROM ?? AS sa' +
+                '    Left Join ?? AS s On sa.`cpid` = s.`id`' +
+                '    Left Join ?? As t On sa.`tid` = t.`id`' +
+                '    Left Join ?? AS ti ON ti.`tid` = t.`id`' +
+                '  WHERE sa.`aid` = ? and sa.`status` = ?';
+            const sqlParam = [
+                this.tableName,
+                this.ctx.service.changePlan.tableName,
+                this.ctx.service.tender.tableName,
+                this.ctx.service.tenderInfo.tableName,
+                auditorId,
+                auditConst.status.checking,
+            ];
+            return await this.db.query(sql, sqlParam);
+        }
+    }
     return ChangePlanAudit;
 };

+ 7 - 4
app/service/change_project_audit.js

@@ -314,7 +314,7 @@ module.exports = app => {
          * @param {Number} cpId 立项书id
          * @param {Number} uid 审批人id
          */
-        async getNoticeContent(pid, tid, cpId, uid) {
+        async getNoticeContent(pid, tid, cpId, uid, opinion = '') {
             const noticeSql = 'SELECT * FROM (SELECT ' +
                 '  t.`id` As `tid`, ma.`cpid`, m.`code` as `c_code`, t.`name`, pa.`name` As `su_name`, pa.role As `su_role`' +
                 '  FROM (SELECT * FROM ?? WHERE `id` = ? ) As t' +
@@ -324,6 +324,9 @@ module.exports = app => {
                 '  WHERE  t.`project_id` = ? ) as new_t GROUP BY new_t.`tid`';
             const noticeSqlParam = [this.ctx.service.tender.tableName, tid, this.ctx.service.changeProject.tableName, cpId, this.tableName, this.ctx.service.projectAccount.tableName, uid, pid];
             const content = await this.db.query(noticeSql, noticeSqlParam);
+            if (content.length) {
+                content[0].opinion = opinion;
+            }
             return content.length ? JSON.stringify(content[0]) : '';
         }
 
@@ -376,7 +379,7 @@ module.exports = app => {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
 
                 // 获取推送必要信息
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, cpId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, cpId, audit.aid, checkData.opinion);
                 // 添加推送
                 const records = [{ pid, type: pushType.changeProject, uid: this.ctx.change.uid, status: auditConst.status.checked, content: noticeContent }];
                 auditors.forEach(audit => {
@@ -450,7 +453,7 @@ module.exports = app => {
             try {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
                 // 添加到消息推送表
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, cpId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, cpId, audit.aid, checkData.opinion);
                 const records = [{ pid, type: pushType.changeProject, uid: this.ctx.change.uid, status: auditConst.status.back, content: noticeContent }];
                 auditors.forEach(audit => {
                     records.push({ pid, type: pushType.changeProject, uid: audit.aid, status: auditConst.status.back, content: noticeContent });
@@ -498,7 +501,7 @@ module.exports = app => {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
 
                 // 获取推送必要信息
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, cpId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, cpId, audit.aid, checkData.opinion);
                 // 添加推送
                 const records = [{ pid, type: pushType.changeProject, uid: this.ctx.change.uid, status: auditConst.status.checkNo, content: noticeContent }];
                 auditors.forEach(audit => {

+ 5 - 2
app/service/ledger_audit.js

@@ -323,7 +323,7 @@ module.exports = app => {
                 // 获取审核人列表
                 const auditList = await this.getAuditors(tenderId, times);
                 // 添加推送
-                const noticeContent = await this.getNoticeContent(audit.tender_id, pid, audit.audit_id);
+                const noticeContent = await this.getNoticeContent(audit.tender_id, pid, audit.audit_id, opinion);
                 const records = [
                     {
                         pid,
@@ -481,7 +481,7 @@ module.exports = app => {
          * @param {Number} pid 项目id
          * @param {Number} uid 审核人id
          */
-        async getNoticeContent(id, pid, uid) {
+        async getNoticeContent(id, pid, uid, opinion = '') {
             const noticeSql =
                 'SELECT * FROM (SELECT ' +
                 '  t.`id` As `tid`, t.`name`,  pa.`name` As `su_name`, pa.role As `su_role`' +
@@ -490,6 +490,9 @@ module.exports = app => {
                 '  WHERE  t.`project_id` = ? ) as new_t GROUP BY new_t.`tid`';
             const noticeSqlParam = [this.ctx.service.tender.tableName, id, this.ctx.service.projectAccount.tableName, uid, pid];
             const content = await this.db.query(noticeSql, noticeSqlParam);
+            if (content.length) {
+                content[0].opinion = opinion;
+            }
             return content.length ? JSON.stringify(content[0]) : '';
         }
 

+ 7 - 4
app/service/material_audit.js

@@ -292,7 +292,7 @@ module.exports = app => {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
 
                 // 获取推送必要信息
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, materialId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, materialId, audit.aid, checkData.opinion);
                 // 添加推送
                 const records = [{ pid, type: pushType.material, uid: this.ctx.material.user_id, status: auditConst.status.checked, content: noticeContent }];
                 auditors.forEach(audit => {
@@ -477,7 +477,7 @@ module.exports = app => {
             try {
                 await transaction.update(this.tableName, { id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time });
                 // 添加到消息推送表
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, materialId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, materialId, audit.aid, checkData.opinion);
                 const records = [{ pid, type: pushType.material, uid: this.ctx.material.user_id, status: auditConst.status.checkNo, content: noticeContent }];
                 auditors.forEach(audit => {
                     records.push({ pid, type: pushType.material, uid: audit.aid, status: auditConst.status.checkNo, content: noticeContent });
@@ -572,7 +572,7 @@ module.exports = app => {
                 return item.aid === audit.aid;
             });
             const preAuditor = auditors2[auditorIndex - 1];
-            const noticeContent = await this.getNoticeContent(pid, audit.tid, materialId, audit.aid);
+            const noticeContent = await this.getNoticeContent(pid, audit.tid, materialId, audit.aid, checkData.opinion);
             const transaction = await this.db.beginTransaction();
             try {
                 // 添加到消息推送表
@@ -659,7 +659,7 @@ module.exports = app => {
          * @param {Number} mid 期id
          * @param {Number} uid 审批人id
          */
-        async getNoticeContent(pid, tid, mid, uid) {
+        async getNoticeContent(pid, tid, mid, uid, opinion = '') {
             const noticeSql = 'SELECT * FROM (SELECT ' +
                 '  t.`id` As `tid`, ma.`mid`, t.`name`, m.`order`, pa.`name` As `su_name`, pa.role As `su_role`' +
                 '  FROM (SELECT * FROM ?? WHERE `id` = ? ) As t' +
@@ -669,6 +669,9 @@ module.exports = app => {
                 '  WHERE  t.`project_id` = ? ) as new_t GROUP BY new_t.`tid`';
             const noticeSqlParam = [this.ctx.service.tender.tableName, tid, this.ctx.service.material.tableName, mid, this.tableName, this.ctx.service.projectAccount.tableName, uid, pid];
             const content = await this.db.query(noticeSql, noticeSqlParam);
+            if (content.length) {
+                content[0].opinion = opinion;
+            }
             return content.length ? JSON.stringify(content[0]) : '';
         }
 

+ 5 - 2
app/service/revise_audit.js

@@ -358,7 +358,7 @@ module.exports = app => {
             try {
                 const auditList = await this.getAuditors(revise.id, times);
                 // 审核通过添加到推送表
-                const noticeContent = await this.getNoticeContent(pid, audit.tender_id, audit.rid, audit.audit_id);
+                const noticeContent = await this.getNoticeContent(pid, audit.tender_id, audit.rid, audit.audit_id, opinion);
                 const records = [
                     {
                         pid,
@@ -650,7 +650,7 @@ module.exports = app => {
          * @param {Number} rid 修订id
          * @param {Number} uid 审核人id
          */
-        async getNoticeContent(pid, tid, rid, uid) {
+        async getNoticeContent(pid, tid, rid, uid, opinion = '') {
             const noticeSql =
                 'SELECT * FROM (SELECT ' +
                 '  t.`id` As `tid`, t.`name`, r.`corder`, r.`id` As rid, pa.`name` As `su_name`, pa.role As `su_role`' +
@@ -660,6 +660,9 @@ module.exports = app => {
                 '  WHERE  t.`project_id` = ? ) as new_t GROUP BY new_t.`tid`';
             const noticeSqlParam = [this.ctx.service.tender.tableName, tid, this.ctx.service.ledgerRevise.tableName, rid, this.ctx.service.projectAccount.tableName, uid, pid];
             const content = await this.db.query(noticeSql, noticeSqlParam);
+            if (content.length) {
+                content[0].opinion = opinion;
+            }
             return content.length ? JSON.stringify(content[0]) : '';
         }
 

+ 7 - 4
app/service/stage_audit.js

@@ -379,7 +379,7 @@ module.exports = app => {
             try {
                 await this._updateTender(transaction);
                 // 添加推送
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, stageId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, stageId, audit.aid, checkData.opinion);
                 const auditors = await this.getAuditGroupByListWithOwner(stageId, times);
                 const records = [];
                 auditors.forEach(audit => {
@@ -577,7 +577,7 @@ module.exports = app => {
             try {
                 await this._updateTender(transaction);
                 // 添加推送
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, stageId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, stageId, audit.aid, checkData.opinion);
                 const records = [
                     {
                         pid,
@@ -710,7 +710,7 @@ module.exports = app => {
             try {
                 await this._updateTender(transaction);
                 // 添加推送
-                const noticeContent = await this.getNoticeContent(pid, audit.tid, stageId, audit.aid);
+                const noticeContent = await this.getNoticeContent(pid, audit.tid, stageId, audit.aid, checkData.opinion);
                 const records = [
                     {
                         pid,
@@ -1077,7 +1077,7 @@ module.exports = app => {
          * @param {Number} sid 期id
          * @param {Number} uid 审核人id
          */
-        async getNoticeContent(pid, tid, sid, uid) {
+        async getNoticeContent(pid, tid, sid, uid, opinion = '') {
             const noticeSql =
                 'SELECT * FROM (SELECT ' +
                 '  t.`id` As `tid`, t.`name`, s.`order`, pa.`name` As `su_name`, pa.role As `su_role`' +
@@ -1087,6 +1087,9 @@ module.exports = app => {
                 '  WHERE  t.`project_id` = ? ) as new_t GROUP BY new_t.`tid`';
             const noticeSqlParam = [this.ctx.service.tender.tableName, tid, this.ctx.service.stage.tableName, sid, this.ctx.service.projectAccount.tableName, uid, pid];
             const content = await this.db.query(noticeSql, noticeSqlParam);
+            if (content.length) {
+                content[0].opinion = opinion;
+            }
             return content.length ? JSON.stringify(content[0]) : '';
         }
 

+ 25 - 1
app/view/wap/dashboard.ejs

@@ -9,6 +9,7 @@
     <link rel="stylesheet" href="/public/css/wap/main.css">
     <link rel="stylesheet" href="/public/css/toast.css">
     <link rel="stylesheet" href="/public/css/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/public/css/toastr.css">
     <link rel="shortcut icon" href="/public/images/favicon.ico">
     <style>
         body {
@@ -36,7 +37,7 @@
         </nav>
         <!--待审批期列表-->
         <div class="py-6">
-            <% if (auditStages.length !== 0 || auditChanges.length !== 0 || auditRevise.length !== 0 || auditAdvance.length !== 0) { %>
+            <% if (auditStages.length !== 0 || auditChanges.length !== 0 || auditRevise.length !== 0 || auditAdvance.length !== 0 || auditChangePlans.length !== 0) { %>
                 <% for (const audit of auditStages) { %>
                 <div class="card mb-3">
                     <div class="card-header d-flex justify-content-between">
@@ -110,6 +111,28 @@
                         </div>
                     </div>
                 <% } %>
+                <% for (const change of auditChangePlans) { %>
+                    <div class="card mb-3">
+                        <div class="card-header d-flex justify-content-between">
+                            <span><%- JSON.parse(change.deal_info).buildName %></span>
+                            <span class="badge badge-pill badge-danger">变更方案</span>
+                        </div>
+                        <div class="bg-light p-2 px-3"><b><%- change.t_name %></b></div>
+                        <div class="card-body">
+                            <div class="d-flex justify-content-between"><span><%- change.code %></span></div>
+                            <div class="my-2">
+                                <table class="table table-sm table-bordered">
+                                    <tr><th width="90">工程名称</th><td><%- change.name %></td></tr>
+                                    <tr><th>变更性质</th><td><%- change.quality %></td></tr>
+                                    <tr><th>变更金额</th><td class="text-right"><%- ctx.helper.roundNum(change.total_price, JSON.parse(change.decimal).tp) %></td></tr>
+                                </table>
+                            </div>
+                            <div class="">
+                                <a href="/wap/tender/<%- change.tid %>/change/plan/<%- change.id %>/info#shenpi" class="btn btn-block btn-success">审批</a>
+                            </div>
+                        </div>
+                    </div>
+                <% } %>
                 <% for (const advance of auditAdvance) { %>
                     <div class="card mb-3">
                         <div class="card-header d-flex justify-content-between">
@@ -156,6 +179,7 @@
     <script src="/public/js/popper/popper.min.js"></script>
     <script src="/public/js/bootstrap/bootstrap.min.js"></script>
     <script src="/public/js/cookies.js"></script>
+    <script src="/public/js/toastr.min.js"></script>
     <script src="/public/js/wap/global.js"></script>
 <script>
     $(function () {

+ 2 - 0
app/view/wap/list.ejs

@@ -9,6 +9,7 @@
     <link rel="stylesheet" href="/public/css/wap/main.css">
     <link rel="stylesheet" href="/public/css/toast.css">
     <link rel="stylesheet" href="/public/css/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/public/css/toastr.css">
     <link rel="shortcut icon" href="/public/images/favicon.ico">
     <style>
         html{height:100%;}
@@ -70,6 +71,7 @@
 <script src="/public/js/lodash.js"></script>
 <script src="/public/js/lz-string/lz-string.js"></script>
 <script src="/public/js/cookies.js"></script>
+<script src="/public/js/toastr.min.js"></script>
 <script src="/public/js/wap/global.js"></script>
 <script src="/public/js/decimal.min.js"></script>
 <script src="/public/js/zh_calc.js"></script>

+ 2 - 0
app/view/wap/login.ejs

@@ -9,6 +9,7 @@
     <link rel="stylesheet" href="/public/css/wap/main.css">
     <link rel="stylesheet" href="/public/css/toast.css">
     <link rel="stylesheet" href="/public/css/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/public/css/toastr.css">
     <link rel="shortcut icon" href="/public/images/favicon.ico">
     <style>
         html{height:100%;}
@@ -73,6 +74,7 @@
 <script src="/public/js/jquery/jquery-3.2.1.min.js"></script>
 <script src="/public/js/popper/popper.min.js"></script>
 <script src="/public/js/bootstrap/bootstrap.min.js"></script>
+<script src="/public/js/toastr.min.js"></script>
 <script src="/public/js/wap/global.js"></script>
 <script>
     const csrf = '<%= ctx.csrf %>'

+ 2 - 0
app/view/wap/shenpi_advance.ejs

@@ -9,6 +9,7 @@
     <link rel="stylesheet" href="/public/css/wap/main.css">
     <link rel="stylesheet" href="/public/css/toast.css">
     <link rel="stylesheet" href="/public/css/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/public/css/toastr.css">
     <script src=/public/js/echarts/echarts.min.js></script>
     <link rel="shortcut icon" href="/public/images/favicon.ico">
     <style>
@@ -127,6 +128,7 @@
 <script src="/public/js/popper/popper.min.js"></script>
 <script src="/public/js/bootstrap/bootstrap.min.js"></script>
 <script src="/public/js/cookies.js"></script>
+<script src="/public/js/toastr.min.js"></script>
 <script src="/public/js/wap/global.js"></script>
 <script>
     $(document).ready(function () {

+ 2 - 0
app/view/wap/shenpi_advance_detail.ejs

@@ -9,6 +9,7 @@
     <link rel="stylesheet" href="/public/css/wap/main.css">
     <link rel="stylesheet" href="/public/css/toast.css">
     <link rel="stylesheet" href="/public/css/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/public/css/toastr.css">
     <script src=/public/js/echarts/echarts.min.js></script>
     <link rel="shortcut icon" href="/public/images/favicon.ico">
     <style>
@@ -217,6 +218,7 @@
 <script src="/public/js/popper/popper.min.js"></script>
 <script src="/public/js/bootstrap/bootstrap.min.js"></script>
 <script src="/public/js/cookies.js"></script>
+<script src="/public/js/toastr.min.js"></script>
 <script src="/public/js/wap/global.js"></script>
 <script>
     // $(document).ready(function () {

+ 5 - 0
app/view/wap/shenpi_change.ejs

@@ -9,6 +9,7 @@
     <link rel="stylesheet" href="/public/css/wap/main.css">
     <link rel="stylesheet" href="/public/css/toast.css">
     <link rel="stylesheet" href="/public/css/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/public/css/toastr.css">
     <link rel="shortcut icon" href="/public/images/favicon.ico">
     <style>
         body {
@@ -147,6 +148,9 @@
                 </form>
             </div>
             <div class="tab-pane" id="shenpi">
+                <div class="mt-3">
+                    <h6 class="ml-1">审批金额:<%- ctx.helper.roundNum(change.total_price, ctx.tender.info.decimal.tp) %> 元 </h6>
+                </div>
                 <!--审批流程-->
                 <div class="card mt-3">
                     <ul class="list-group list-group-flush">
@@ -295,6 +299,7 @@
 <script src="/public/js/popper/popper.min.js"></script>
 <script src="/public/js/bootstrap/bootstrap.min.js"></script>
 <script src="/public/js/cookies.js"></script>
+<script src="/public/js/toastr.min.js"></script>
 <script src="/public/js/wap/global.js"></script>
 <script>
     $(document).ready(function () {

+ 249 - 0
app/view/wap/shenpi_change_plan.ejs

@@ -0,0 +1,249 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
+    <meta http-equiv="x-ua-compatible" content="ie=edge">
+    <title>标段概况-计量支付</title>
+    <link rel="stylesheet" href="/public/css/bootstrap/bootstrap.min.css">
+    <link rel="stylesheet" href="/public/css/wap/main.css">
+    <link rel="stylesheet" href="/public/css/toast.css">
+    <link rel="stylesheet" href="/public/css/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/public/css/toastr.css">
+    <link rel="shortcut icon" href="/public/images/favicon.ico">
+    <style>
+        body {
+            padding: 0;
+        }
+    </style>
+</head>
+<body>
+<div class="container">
+    <!--顶部-->
+    <nav class="fixed-top bg-dark">
+        <div class="my-2 d-flex justify-content-between">
+            <span class="text-white ml-3"><a href="/wap/tender/<%- tender.id %>#biangeng" class="mr-2 text-white show-loading"><i class="fa fa-chevron-left"></i>工程变更</a></span>
+            <a tabindex="0" href="javascript:void(0)" class="text-white text-truncate text-center"
+               style="width:150px" data-toggle="popover" data-placement="top"
+               data-content="<%- tender.name %>" data-trigger="focus"><%- tender.name %></a>
+            <div class="mr-3">
+                <div class="dropdown">
+                    <button class="btn btn-sm btn-light dropdown-toggle" type="button" data-toggle="dropdown">
+                        <%- ctx.session.sessionUser.name.substr(ctx.session.sessionUser.name.length > 2 ? ctx.session.sessionUser.name.length - 2 : 0) %>
+                    </button>
+                    <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
+                        <a class="dropdown-item" href="/wap/logout">退出登录</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </nav>
+    <!--标段概况-->
+    <div class="py-6">
+        <!--标签-->
+        <ul class="nav nav-tabs nav-fill">
+            <li class="nav-item">
+                <a class="nav-link active" data-toggle="tab" href="#info" role="tab">变更信息</a>
+            </li>
+            <li class="nav-item">
+                <a class="nav-link" data-toggle="tab" href="#shenpi" role="tab">审批</a>
+            </li>
+        </ul>
+        <div class="tab-content">
+            <div class="tab-pane active" id="info">
+                <form>
+                    <div class="form-group">
+                        <label>方案编号</label>
+                        <input class="form-control form-control-sm" value="<%- change.code %>" type="text" readonly="">
+                    </div>
+                    <div class="form-group">
+                        <label>变更工程名称</label>
+                        <input class="form-control form-control-sm" value="<%- change.name %>" type="text" readonly="">
+                    </div>
+                    <div class="form-group">
+                        <label>桩号</label>
+                        <input class="form-control form-control-sm" value="<%- change.peg %>" type="text" readonly="">
+                    </div>
+                    <div class="form-group">
+                        <label>原设计图名称</label>
+                        <input class="form-control form-control-sm" placeholder="" type="text" value="<%- change.org_name %>" readonly>
+                    </div>
+                    <div class="form-group">
+                        <label>图号</label>
+                        <input class="form-control form-control-sm" placeholder="" type="text" value="<%- change.new_code %>" readonly>
+                    </div>
+                    <div class="form-group">
+                        <label>变更设计名称</label>
+                        <input class="form-control form-control-sm" placeholder="" type="text" value="<%- change.design_name %>" readonly>
+                    </div>
+                    <div class="form-group">
+                        <label>变更图号</label>
+                        <input class="form-control form-control-sm" placeholder="" type="text" value="<%- change.c_new_code %>" readonly>
+                    </div>
+                    <div class="form-group">
+                        <label>工程变更类别</label>
+                        <input class="form-control form-control-sm" placeholder="" type="text" value="<%- change.class %>" readonly>
+                    </div>
+                    <div class="form-group">
+                        <label>工程变更性质</label>
+                        <input class="form-control form-control-sm" placeholder="" type="text" value="<%- change.quality %>" readonly>
+                    </div>
+                    <div class="form-group">
+                        <label><b class="text-danger">*&nbsp;</b>变更原因</label>
+                        <textarea class="form-control form-control-sm" rows="6" readonly=""><%- change.reason %></textarea>
+                    </div>
+                    <div class="form-group">
+                        <label>变更内容</label>
+                        <textarea class="form-control form-control-sm" rows="6" readonly=""><%- change.content %></textarea>
+                    </div>
+                    <div class="form-group">
+                        <label>方案描述</label>
+                        <textarea class="form-control form-control-sm" rows="2" readonly=""><%- change.memo %></textarea>
+                    </div>
+                    <div class="form-group">
+                        <label>工程量数量计算式</label>
+                        <textarea class="form-control form-control-sm" rows="3" readonly=""><%- change.expr %></textarea>
+                    </div>
+                </form>
+            </div>
+            <div class="tab-pane" id="shenpi">
+                <div class="mt-3">
+                    <h6 class="ml-1">审批金额:<%- ctx.helper.roundNum(change.total_price, ctx.tender.info.decimal.tp) %> 元 </h6>
+                </div>
+                <!--审批流程-->
+                <div class="card mt-3">
+                    <ul class="list-group list-group-flush">
+                        <li class="list-group-item">
+                            <% if (change.status === auditConst.status.uncheck) { %>
+                                <span class="pull-right"> 上报中</span>
+                            <% } else { %>
+                                <span class="text-success pull-right"><small><%- change.auditors[0].begin_time.toLocaleDateString() %></small> 上报</span>
+                            <% } %>
+                            <h5 class="card-title"><i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- change.user.name %><small class="text-muted"><%- change.user.role %></small></h5>
+                        </li>
+                        <% for (let iA = 0; iA < change.auditors.length; iA++) { %>
+                            <% const auditors = change.auditors; %>
+                            <li class="list-group-item">
+                                <% if (auditors[iA].status === auditConst.status.checked) { %>
+                                    <span class="text-success pull-right"><small><%- auditors[iA].end_time.toLocaleDateString() %></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></h5>
+                                    <p class="card-text"><%- auditors[iA].opinion %></p>
+                                <% } else if (auditors[iA].status == 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></h5>
+                                    <% if (auditors[iA].aid === ctx.session.sessionUser.accountId) { %>
+                                        <% audit = auditors[iA]; %>
+                                        <div class="form-group">
+                                            <div class="text-center">
+                                                <button class="btn btn-success" data-toggle="modal" data-target="#sp-done" >审批通过</button>
+                                                <button class="btn btn-warning" data-toggle="modal" data-target="#sp-back" >审批退回</button>
+                                            </div>
+                                        </div>
+                                    <% } %>
+                                <% } else if (auditors[iA].status === auditConst.status.checkNo) { %>
+                                    <span class="text-warning pull-right"><small><%- auditors[iA].end_time.toLocaleDateString() %></small>审批退回</span>
+                                    <h5 class="card-title"><i class="<%- (iA < auditors.length - 1 ? 'fa fa-chevron-circle-down text-warning' : 'fa fa-stop-circle text-warning') %>"></i> <%- auditors[iA].name %> <small class="text-muted"><%- auditors[iA].role %></small></h5>
+                                    <p class="card-text"><%- auditors[iA].opinion %></p>
+                                <% } 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></h5>
+                                <% } %>
+                            </li>
+                        <% } %>
+                    </ul>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--底栏菜单-->
+    <nav class="fixed-bottom navbar-dark bg-light border-top">
+        <ul class="nav nav-fill my-2">
+            <li class="nav-item">
+                <a class="nav-link text-muted show-loading" href="/wap/dashboard"><i class="fa fa-check-square-o"></i> 待审批</a>
+            </li>
+            <li class="nav-item">
+                <a class="nav-link active show-loading" href="/wap/list"><i class="fa fa-list-ul"></i> 项目</a>
+            </li>
+        </ul>
+    </nav>
+</div>
+<!--审批通过弹窗-->
+<div class="modal" tabindex="-1" role="dialog" id="sp-done">
+    <div class="modal-dialog" role="document">
+        <form class="modal-content" action="/tender/<%- change.tid %>/change/plan/<%- change.id %>/information/audit/check" method="post" onsubmit="return auditCheck(0);">
+            <div class="modal-header">
+                <h5 class="modal-title">审批通过</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <label>审批意见</label>
+                    <textarea class="form-control" rows="8" name="opinion">同意</textarea>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <input type="hidden" name="_csrf_j" value="<%= ctx.csrf %>" />
+                <input type="hidden" name="checkType" value="<%= auditConst.status.checked %>" />
+                <button type="submit" class="btn btn-success">审批通过</button>
+            </div>
+        </form>
+    </div>
+</div>
+<!--审批退回弹窗-->
+<div class="modal" tabindex="-1" role="dialog" id="sp-back">
+    <div class="modal-dialog" role="document">
+        <form class="modal-content" action="/tender/<%- change.tid %>/change/plan/<%- change.id %>/information/audit/check" method="post" onsubmit="return auditCheck(1);">
+            <div class="modal-header">
+                <h5 class="modal-title">审批退回</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <label>审批意见</label>
+                    <textarea class="form-control" rows="8" name="opinion">不同意</textarea>
+                </div>
+                <div class="alert alert-warning">
+                    <div class="custom-control custom-radio custom-control-inline">
+                        <input type="radio" id="customRadioInline1" name="checkType" class="custom-control-input" value="<%- auditConst.status.checkNo %>" checked>
+                        <label class="custom-control-label" for="customRadioInline1">退回原报 <%- change.user.name %></label>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <input type="hidden" name="_csrf_j" value="<%= ctx.csrf %>" />
+                <button type="submit" class="btn btn-warning">确认退回</button>
+            </div>
+        </form>
+    </div>
+</div>
+<script src="/public/js/jquery/jquery-3.2.1.min.js"></script>
+<script src="/public/js/popper/popper.min.js"></script>
+<script src="/public/js/bootstrap/bootstrap.min.js"></script>
+<script src="/public/js/cookies.js"></script>
+<script src="/public/js/toastr.min.js"></script>
+<script src="/public/js/wap/global.js"></script>
+<script>
+    $(document).ready(function () {
+        if (window.location.hash && window.location.hash === '#shenpi') {
+            $('#info').removeClass('active');
+            $('.nav-item a[href="#info"]').removeClass('active');
+
+            $('#shenpi').addClass('active');
+            $('.nav-item a[href="#shenpi"]').addClass('active');
+        }
+    });
+    // texterea换行
+    function auditCheck(i) {
+        const opinion = $('textarea[name="opinion"]').eq(i).val().replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
+        $('textarea[name="opinion"]').eq(i).val(opinion);
+        return true;
+    }
+</script>
+</body>
+
+</html>

+ 2 - 0
app/view/wap/shenpi_revise.ejs

@@ -9,6 +9,7 @@
     <link rel="stylesheet" href="/public/css/wap/main.css">
     <link rel="stylesheet" href="/public/css/toast.css">
     <link rel="stylesheet" href="/public/css/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/public/css/toastr.css">
     <script src=/public/js/echarts/echarts.min.js></script>
     <link rel="shortcut icon" href="/public/images/favicon.ico">
     <style>
@@ -183,6 +184,7 @@
 <script src="/public/js/popper/popper.min.js"></script>
 <script src="/public/js/bootstrap/bootstrap.min.js"></script>
 <script src="/public/js/cookies.js"></script>
+<script src="/public/js/toastr.min.js"></script>
 <script src="/public/js/wap/global.js"></script>
 <script>
     // $(document).ready(function () {

+ 2 - 0
app/view/wap/shenpi_stage.ejs

@@ -9,6 +9,7 @@
     <link rel="stylesheet" href="/public/css/wap/main.css">
     <link rel="stylesheet" href="/public/css/toast.css">
     <link rel="stylesheet" href="/public/css/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/public/css/toastr.css">
     <script src=/public/js/echarts/echarts.min.js></script>
     <link rel="shortcut icon" href="/public/images/favicon.ico">
     <style>
@@ -230,6 +231,7 @@
 <script src="/public/js/popper/popper.min.js"></script>
 <script src="/public/js/bootstrap/bootstrap.min.js"></script>
 <script src="/public/js/cookies.js"></script>
+<script src="/public/js/toastr.min.js"></script>
 <script src="/public/js/wap/global.js"></script>
 <script>
     $(document).ready(function () {

+ 38 - 0
app/view/wap/tender.ejs

@@ -9,6 +9,7 @@
     <link rel="stylesheet" href="/public/css/wap/main.css">
     <link rel="stylesheet" href="/public/css/toast.css">
     <link rel="stylesheet" href="/public/css/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/public/css/toastr.css">
     <script src=/public/js/echarts/echarts.min.js></script>
     <link rel="shortcut icon" href="/public/images/favicon.ico">
     <style>
@@ -205,6 +206,42 @@
             <div class="tab-pane" id="biangeng">
                 <!--工程变更-->
                 <dl class="mb-2 mt-3">
+                    <% for (const c of changePlans) { %>
+                        <dt class="bg-light p-2 d-flex justify-content-between"><span><a href="/wap/tender/<%- tender.id %>/change/plan/<%- c.id %>/info"><%- c.code %></a></span></dt>
+                        <dd>
+                            <table class="table table-hover">
+                                <tbody>
+                                <tr>
+                                    <td colspan="2">
+                                        <p class="mb-0">工程名称</p>
+                                        <%- c.name %>
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <td>
+                                        <p class="mb-0">变更性质</p>
+                                        <b><%- c.quality %></b>
+                                    </td>
+                                    <td>
+                                        <p class="mb-0">变更金额</p>
+                                        <b><%- ctx.helper.roundNum(c.total_price, tpUnit) %></b>
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <td colspan="2">
+                                        <% if (c.status === auditChangePlanConst.status.checking && c.curAuditor.aid === ctx.session.sessionUser.accountId) { %>
+                                            <a href="/wap/tender/<%- tender.id %>/change/plan/<%- c.id %>/info#shenpi" class="btn btn-block btn-success">审批变更</a>
+                                        <% } else if (c.status === auditChangePlanConst.status.uncheck) { %>
+                                            <span>待上报</span>
+                                        <% } else { %>
+                                            <span class="<%- auditChangePlanConst.auditStringClass[c.curAuditor.status] %>"><%- c.curAuditor.name %><%if (c.curAuditor.role !== '' && c.curAuditor.role !== null) { %>-<%- c.curAuditor.role %><% } %> <%- auditChangePlanConst.auditString[c.curAuditor.status] %></span>
+                                        <% } %>
+                                    </td>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </dd>
+                    <% } %>
                     <% for (const c of changes) { %>
                     <dt class="bg-light p-2 d-flex justify-content-between"><span><a href="/wap/tender/<%- tender.id %>/change/<%- c.cid %>/info"><% if (c.status !== auditChangeConst.status.checked) { %><%- c.code %><% } else { %><%- c.p_code %><% } %></a></span></dt>
                     <dd>
@@ -263,6 +300,7 @@
 <script src="/public/js/popper/popper.min.js"></script>
 <script src="/public/js/bootstrap/bootstrap.min.js"></script>
 <script src="/public/js/cookies.js"></script>
+<script src="/public/js/toastr.min.js"></script>
 <script src="/public/js/wap/global.js"></script>
 <script type="text/javascript">
     //4 标段期数计量进度//