Quellcode durchsuchen

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

MaiXinRong vor 4 Jahren
Ursprung
Commit
57082a1d35

+ 20 - 0
app/const/advance.js

@@ -0,0 +1,20 @@
+'use strict';
+
+/**
+ * 预付款相关常量
+ *
+ * @author EllisRan
+ * @date 2021/6/17
+ * @version
+ */
+
+// 预付款类型
+const typeCol = [
+    { key: 'start', type: 0, name: '开工预付款' },
+    { key: 'material', type: 1, name: '材料预付款' },
+    // { key: 'safe', type: 2, name: '安全生产预付款' },
+]
+
+module.exports = {
+    typeCol,
+};

+ 1 - 1
app/controller/advance_controller.js

@@ -167,7 +167,7 @@ module.exports = app => {
                     prev_total_amount = ctx.helper.formatMoney(ctx.helper.add(cur_amount, ctx.advance.prev_amount), ',', isLimitMax ? s2.length : 2);
                 } else {
                     cur_amount = ctx.advance.cur_amount;
-                    const s2 = parseFloat(ctx.advance.prev_total_amount).toString().split('.')[1];
+                    const s2 = parseFloat(ctx.advance.prev_total_amount).toString().split('.')[1] || '';
                     prev_total_amount = ctx.helper.formatMoney(ctx.advance.prev_total_amount, ',', isLimitMax ? s2.length : 2);
                 }
 

+ 5 - 2
app/controller/report_controller.js

@@ -72,7 +72,10 @@ module.exports = app => {
         async index(ctx) {
             try {
                 await this._getStageAuditViewData(ctx);
-                const pageShow = ctx.session.sessionProject.page_show;
+                let pageShow = ctx.session.sessionProject.page_show;
+                if (pageShow === null || pageShow === undefined) {
+                    pageShow = {};
+                }
                 // console.log(pageShow);
                 pageShow.showArchive = 0;
                 const tender = ctx.tender;
@@ -464,7 +467,7 @@ module.exports = app => {
                 return;
             }
             await this._saveCustomSelects(params);
-            const pageRstArr = await getMultiRptsCommon(ctx, params, JV.OUTPUT_TYPE_NORMAL, this.app.baseDir);
+            const pageRstArr = await getMultiRptsCommon(ctx, params, JV.OUTPUT_TYPE_NORMAL, this.app.baseDir) || [];
             for (const pageRst of pageRstArr) {
                 for (const page of pageRst.items) {
                     page[JV.PROP_WATERMARK_CELLS] = [];

+ 4 - 2
app/controller/revise_controller.js

@@ -891,11 +891,13 @@ module.exports = app => {
 
                 await ctx.service.reviseAudit.check(revise, checkType, ctx.request.body.opinion, revise.times);
 
-                ctx.redirect('/tender/' + ctx.tender.id + '/revise/info');
+                // ctx.redirect('/tender/' + ctx.tender.id + '/revise/info');
+                ctx.redirect(ctx.request.headers.referer);
             } catch (err) {
                 this.log(err);
                 this.postError(err, '审批失败');
-                ctx.redirect('/tender/' + ctx.tender.id + '/revise/info');
+                // ctx.redirect('/tender/' + ctx.tender.id + '/revise/info');
+                ctx.redirect(ctx.request.headers.referer);
             }
         }
 

+ 114 - 0
app/controller/wap_controller.js

@@ -11,6 +11,7 @@ const URL = require('url');
 const maintainConst = require('../const/maintain');
 const auditConst = require('../const/audit');
 const changeConst = require('../const/change');
+const advanceConst = require('../const/advance');
 
 module.exports = app => {
 
@@ -124,10 +125,21 @@ module.exports = app => {
             }
             // 获取待审批的变更期
             const auditChanges = await ctx.service.changeAudit.getAuditChangeByWap(ctx.session.sessionUser.accountId);
+            // 获取待审批的台账修订
+            const auditRevise = await ctx.service.reviseAudit.getAuditReviseByWap(ctx.session.sessionUser.accountId);
+            for (const revise of auditRevise) {
+                const yb_audit = await ctx.service.projectAccount.getAccountInfoById(revise.audit_id);
+                revise.yb_name = yb_audit.name;
+            }
+            // 获取待审批的预付款
+            const auditAdvance = await ctx.service.advanceAudit.getAuditAdvanceByWap(ctx.session.sessionUser.accountId);
             const renderData = {
                 auditStages,
                 auditChanges,
+                auditRevise,
+                auditAdvance,
                 changeConst,
+                advanceConst,
                 tpUnit: 2,
             };
             await ctx.render('wap/dashboard.ejs', renderData);
@@ -246,13 +258,32 @@ module.exports = app => {
                     c.curAuditor = await ctx.service.changeAudit.getLastUser(c.cid, c.times);
                 }
 
+                // 台账修订列表
+                const revises = await ctx.service.ledgerRevise.getReviseList(ctx.tender.id);
+                for (const lr of revises) {
+                    if (lr.valid) {
+                        lr.curAuditor = await ctx.service.reviseAudit.getAuditorByStatus(lr.id, lr.status, lr.times);
+                    }
+                }
+
+                // 预付款期数获取
+                const advanceList = [];
+                for (const t of advanceConst.typeCol) {
+                    const advance = await ctx.service.advance.getLastestAdvance(ctx.tender.id, t.type, true);
+                    advanceList.push(advance);
+                }
+
                 const renderData = {
                     tender,
                     stages,
                     changes,
+                    revises,
+                    advanceList,
                     auditConst: auditConst.stage,
                     auditChangeConst: auditConst.flow,
+                    auditReviseConst: auditConst.revise,
                     changeConst,
+                    advanceConst,
                     tpUnit: ctx.tender.info.decimal.tp,
                     monthProgress,
                     stagesEcharts: JSON.parse(JSON.stringify(stages)).reverse(),
@@ -342,6 +373,89 @@ module.exports = app => {
         }
 
         /**
+         * 修订审批详细页
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        async revise(ctx) {
+            try {
+                const tender = ctx.tender.data;
+                const revise = await ctx.service.ledgerRevise.getDataByCondition({ id: ctx.params.rid });
+                revise.user = await ctx.service.projectAccount.getAccountInfoById(revise.uid);
+                const times = revise.status === auditConst.revise.status.checkNo ? revise.times - 1 : revise.times;
+                revise.curAuditor = await ctx.service.reviseAudit.getAuditorByStatus(revise.id, revise.status, times);
+                revise.auditors = await ctx.service.reviseAudit.getAuditors(revise.id, times);
+                console.log(times, revise.auditors);
+                const renderData = {
+                    tender,
+                    revise,
+                    auditConst: auditConst.revise,
+                };
+                await ctx.render('wap/shenpi_revise.ejs', renderData);
+            } catch (err) {
+                this.log(err);
+                ctx.redirect('/wap/list');
+            }
+        }
+
+        /**
+         * 预付款列表页
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        async advance(ctx) {
+            try {
+                const tender = ctx.tender.data;
+                const { decimal } = ctx.tender.info;
+                this.decimal = decimal.pay ? decimal.payTp : decimal.tp;
+                const advancePayTotalList = [];
+                const advanceList = [];
+                for (const t of advanceConst.typeCol) {
+                    const advancePayTotal = ctx.tender.info.deal_param[t.key + 'Advance'];
+                    advancePayTotalList.push(advancePayTotal);
+                    const advances = await ctx.service.advance.getAdvanceList(ctx.tender.id, t.type, this.decimal, advancePayTotal);
+                    advanceList.push(advances);
+                }
+                const renderData = {
+                    tender,
+                    advancePayTotalList,
+                    advanceList,
+                    auditConst: auditConst.advance,
+                    advanceConst,
+                };
+                await ctx.render('wap/shenpi_advance.ejs', renderData);
+            } catch (err) {
+                this.log(err);
+                ctx.redirect('/wap/list');
+            }
+        }
+
+        /**
+         * 预付款详情页 GET
+         * @param {Object} ctx 全局上下文
+         */
+        async advanceDetail(ctx) {
+            try {
+                const tender = ctx.tender.data;
+                ctx.advance.advancePayTotal = ctx.tender.info.deal_param[ advanceConst.typeCol[ctx.advance.type].key + 'Advance'];
+                // 获取审批流程中左边列表
+                ctx.advance.auditors2 = await ctx.service.advanceAudit.getAuditGroupByList(ctx.advance.id, ctx.advance.times);
+                const renderData = {
+                    tender,
+                    advance: ctx.advance,
+                    auditConst: auditConst.advance,
+                    advanceConst,
+                };
+                await ctx.render('wap/shenpi_advance_detail.ejs', renderData);
+            } catch (error) {
+                this.log(error);
+                ctx.redirect('/wap/tender/' + ctx.tender.id + '/advance');
+            }
+        }
+
+        /**
          * 变更令审批
          * @param {Object} ctx - egg全局变量
          * @return {void}

+ 7 - 3
app/lib/wechat.js

@@ -36,7 +36,8 @@ class WX {
         try {
             // const templateId = template;
             let templateId = '';
-            const sck = 'https://scn.ink/';
+            // const sck = 'https://scn.ink/';
+            const sck = '';
             for (const openid of wx_openid) {
                 let url = '';
                 let msgData = '';
@@ -113,7 +114,8 @@ class WX {
                         break;
                     case wxConst.template.revise:
                         templateId = wxConst.templateId.revise;
-                        remark = data.status === wxConst.status.check ? '微信暂无法在线审批' :
+                        url = this.ctx.protocol + '://' + this.ctx.host + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url;
+                        remark = data.status === wxConst.status.check ? '微信可快速审批,如需进行详细审批' :
                             (data.status === wxConst.status.success ? '审批已通过,查看审批结果' :
                                 (data.status === wxConst.status.back ? '审批被退回,查看退回结果' : '审批已上报,查看审批结果'));
                         msgData = {
@@ -136,6 +138,7 @@ class WX {
                         break;
                     case wxConst.template.material:
                         templateId = wxConst.templateId.material;
+                        url = this.ctx.protocol + '://' + this.ctx.host + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url;
                         remark = data.status === wxConst.status.check ? '微信暂无法在线审批' :
                             (data.status === wxConst.status.success ? '审批已通过,查看审批结果' : '审批被退回,查看退回结果');
                         msgData = {
@@ -164,7 +167,8 @@ class WX {
                         break;
                     case wxConst.template.advance:
                         templateId = wxConst.templateId.advance;
-                        remark = data.status === wxConst.status.check ? '微信暂无法在线审批' :
+                        url = this.ctx.protocol + '://' + this.ctx.host + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url;
+                        remark = data.status === wxConst.status.check ? '微信可快速审批,如需进行详细审批' :
                             (data.status === wxConst.status.success ? '审批已通过,查看审批结果' : '审批被退回,查看退回结果');
                         msgData = {
                             first: {

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

@@ -416,6 +416,10 @@ $(document).ready(() => {
                 return;
             });
         },
+        valueChanged(e, info) {
+            // 防止ctrl+z撤销数据
+            SpreadJsObj.reLoadRowData(info.sheet, info.row);
+        }
     };
 
     const preUrl = window.location.pathname.split('/').slice(0, 4).join('/');
@@ -520,6 +524,7 @@ $(document).ready(() => {
         changeSpread.bind(spreadNS.Events.EditEnded, changeSpreadObj.editEnded);
         changeSpread.bind(spreadNS.Events.SelectionChanged, changeSpreadObj.selectionChanged);
         changeSpread.bind(spreadNS.Events.ClipboardPasted, changeSpreadObj.clipboardPasted);
+        changeSpread.bind(spreadNS.Events.ValueChanged, changeSpreadObj.valueChanged);
         SpreadJsObj.addDeleteBind(changeSpread, changeSpreadObj.deletePress);
         changeSpreadSheet.getCell(-1, 10).foreColor('#dc3545');
 

+ 2 - 0
app/public/report/js/rpt_preview_common.js

@@ -6,6 +6,7 @@ let G_OFFSET_X = 0, G_OFFSET_Y = 0;
 let STAGE_AUDIT = []; //注意这个,与rpt_main.js不要混了
 let STAGE_LIST = [];
 let STAGE_AUDIT_ORG = [];
+let current_stage_id = -1;
 // 设置Date对象Format函数
 // -- 打印预览需要重新设置一遍 ------------------------------------------------
 Date.prototype.Format = function(fmt) {
@@ -32,6 +33,7 @@ function printPageLoading() {
     let refRptTplIds = JSON.parse(sessionStorage.refRptTplIds);
     STAGE_LIST = JSON.parse(sessionStorage.STAGE_LIST);
     STAGE_AUDIT_ORG = JSON.parse(sessionStorage.STAGE_AUDIT_ORG);
+    current_stage_id = parseInt(sessionStorage.current_stage_id);
     let scaleFactor = 1;
     CommonAjax.postXsrfEx("/tender/report_api/getMultiReports", params, 60000, true, getCookie('csrfToken_j'),
         function(result){

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

@@ -27,6 +27,7 @@ let rptPrintHelper = {
             sessionStorage.refRptTplIds = JSON.stringify(refRptTplIds);
             sessionStorage.STAGE_LIST = JSON.stringify(STAGE_LIST);
             sessionStorage.STAGE_AUDIT_ORG = JSON.stringify(STAGE_AUDIT_ORG);
+            sessionStorage.current_stage_id = getStageId();
             // sessionStorage.STAGE_AUDIT = JSON.stringify(STAGE_AUDIT);
             if (sessionStorage.pageSize === 'A3') {
                 window.open('/printReport/A3');

+ 3 - 0
app/router.js

@@ -450,6 +450,9 @@ module.exports = app => {
     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.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');
+    app.get('/wap/tender/:id/advance/:order/detail', sessionAuth, tenderCheck, uncheckTenderCheck, advanceCheck, 'wapController.advanceDetail');
 
     // 微信
     app.get('/wx', 'wechatController.index');

+ 55 - 5
app/service/advance_audit.js

@@ -5,6 +5,7 @@ const shenpiConst = require('../const/shenpi');
 const pushType = require('../const/audit').pushType;
 const smsTypeConst = require('../const/sms_type');
 const wxConst = require('../const/wechat_template.js');
+const advanceConst = require('../const/advance');
 module.exports = app => {
     class AdvanceAudit extends app.BaseService {
         constructor(ctx) {
@@ -234,11 +235,16 @@ module.exports = app => {
 
                 // 微信模板通知
                 const advanceInfo = await this.ctx.service.advance.getDataById(vid);
+                const shenpiUrl = await this.ctx.helper.urlToShort(
+                    this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + advanceInfo.tid + '/advance/' + advanceInfo.id + '/detail'
+                );
                 const wechatData = {
-                    qi: advanceInfo.type === 0 ? '开工预付款第' + advanceInfo.order + '期' : '材料预付款第' + advanceInfo.order + '期',
+                    wap_url: shenpiUrl,
+                    qi: advanceConst.typeCol[advanceInfo.type].name + '第' + advanceInfo.order + '期',
                     status: wxConst.status.check,
                     tips: wxConst.tips.check,
                     tp: parseFloat(advanceInfo.cur_amount),
+                    code: this.ctx.session.sessionProject.code,
                 };
                 await this.ctx.helper.sendWechat(audit.audit_id, smsTypeConst.const.YFK, smsTypeConst.judge.approval.toString(), wxConst.template.advance, wechatData);
                 await transaction.commit();
@@ -279,6 +285,9 @@ module.exports = app => {
                 // 无下一审核人表示,审核结束
 
                 const advanceInfo = await this.ctx.service.advance.getDataById(advanceId);
+                const shenpiUrl = await this.ctx.helper.urlToShort(
+                    this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + advanceInfo.tid + '/advance/' + advanceInfo.id + '/detail'
+                );
                 if (nextAudit) {
                     // 流程至下一审批人
                     await transaction.update(this.tableName, { id: nextAudit.id, status: auditConst.status.checking, create_time: time });
@@ -289,11 +298,14 @@ module.exports = app => {
                         status: auditConst.status.checking,
                     });
                     // 微信模板通知
+
                     const wechatData = {
-                        qi: advanceInfo.type === 0 ? '开工预付款第' + advanceInfo.order + '期' : '材料预付款第' + advanceInfo.order + '期',
+                        wap_url: shenpiUrl,
+                        qi: advanceConst.typeCol[advanceInfo.type].name + '第' + advanceInfo.order + '期',
                         status: wxConst.status.check,
                         tips: wxConst.tips.check,
                         tp: parseFloat(advanceInfo.cur_amount),
+                        code: this.ctx.session.sessionProject.code,
                     };
                     await this.ctx.helper.sendWechat(nextAudit.audit_id, smsTypeConst.const.YFK, smsTypeConst.judge.approval.toString(), wxConst.template.advance, wechatData);
                 } else {
@@ -306,10 +318,12 @@ module.exports = app => {
                     // 微信模板通知
                     const users = this._.uniq(this._.concat(this._.map(auditors, 'audit_id'), advanceInfo.uid));
                     const wechatData = {
-                        qi: advanceInfo.type === 0 ? '开工预付款第' + advanceInfo.order + '期' : '材料预付款第' + advanceInfo.order + '期',
+                        wap_url: shenpiUrl,
+                        qi: advanceConst.typeCol[advanceInfo.type].name + '第' + advanceInfo.order + '期',
                         status: wxConst.status.success,
                         tips: wxConst.tips.success,
                         tp: parseFloat(advanceInfo.cur_amount),
+                        code: this.ctx.session.sessionProject.code,
                     };
                     await this.ctx.helper.sendWechat(users, smsTypeConst.const.YFK, smsTypeConst.judge.result.toString(), wxConst.template.advance, wechatData);
                 }
@@ -358,11 +372,16 @@ module.exports = app => {
                 // 微信模板通知
                 const advanceInfo = await this.ctx.service.advance.getDataById(advanceId);
                 const users = this._.uniq(this._.concat(this._.map(auditors, 'audit_id'), advanceInfo.uid));
+                const shenpiUrl = await this.ctx.helper.urlToShort(
+                    this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + advanceInfo.tid + '/advance/' + advanceInfo.id + '/detail'
+                );
                 const wechatData = {
-                    qi: advanceInfo.type === 0 ? '开工预付款第' + advanceInfo.order + '期' : '材料预付款第' + advanceInfo.order + '期',
+                    wap_url: shenpiUrl,
+                    qi: advanceConst.typeCol[advanceInfo.type].name + '第' + advanceInfo.order + '期',
                     status: wxConst.status.back,
                     tips: wxConst.tips.back,
                     tp: parseFloat(advanceInfo.cur_amount),
+                    code: this.ctx.session.sessionProject.code,
                 };
                 await this.ctx.helper.sendWechat(users, smsTypeConst.const.YFK, smsTypeConst.judge.result.toString(), wxConst.template.advance, wechatData);
                 // 拷贝新一次审核流程列表
@@ -424,11 +443,16 @@ module.exports = app => {
                 });
                 // 微信模板通知
                 const advanceInfo = await this.ctx.service.advance.getDataById(advanceId);
+                const shenpiUrl = await this.ctx.helper.urlToShort(
+                    this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + advanceInfo.tid + '/advance/' + advanceInfo.id + '/detail'
+                );
                 const wechatData = {
-                    qi: advanceInfo.type === 0 ? '开工预付款第' + advanceInfo.order + '期' : '材料预付款第' + advanceInfo.order + '期',
+                    wap_url: shenpiUrl,
+                    qi: advanceConst.typeCol[advanceInfo.type].name + '第' + advanceInfo.order + '期',
                     status: wxConst.status.check,
                     tips: wxConst.tips.check,
                     tp: parseFloat(advanceInfo.cur_amount),
+                    code: this.ctx.session.sessionProject.code,
                 };
                 await this.ctx.helper.sendWechat(preAuditor.audit_id, smsTypeConst.const.YFK, smsTypeConst.judge.approval.toString(), wxConst.template.advance, wechatData);
                 await transaction.insert(this.tableName, newAuditors);
@@ -609,6 +633,32 @@ module.exports = app => {
                 throw err;
             }
         }
+
+        /**
+         * 取待审批期列表(wap用)
+         *
+         * @param auditorId
+         * @return {Promise<*>}
+         */
+        async getAuditAdvanceByWap(auditorId) {
+            const sql =
+                'SELECT ad.`id`, ad.`tid`, ad.`pay_ratio`, ad.`cur_amount`, ad.`prev_amount`, ad.`prev_total_amount`, ad.`type`, ad.`order`, ' +
+                // '    s.`order` As `sorder`, s.`status` As `sstatus`, s.`s_time`, s.`contract_tp`, s.`qc_tp`, s.`pre_contract_tp`, s.`pre_qc_tp`, s.`yf_tp`, s.`pre_yf_tp`, ' +
+                '    t.`name`, t.`project_id`, t.`user_id`,' +
+                '    ti.`deal_info`, ti.`deal_param` ' +
+                '  FROM ?? AS aa, ?? AS ad, ?? As t, ?? AS ti ' +
+                '  WHERE aa.`audit_id` = ? and aa.`status` = ?' +
+                '    and aa.`vid` = ad.`id` and aa.`tid` = t.`id` and ti.`tid` = t.`id`';
+            const sqlParam = [
+                this.tableName,
+                this.ctx.service.advance.tableName,
+                this.ctx.service.tender.tableName,
+                this.ctx.service.tenderInfo.tableName,
+                auditorId,
+                auditConst.status.checking,
+            ];
+            return await this.db.query(sql, sqlParam);
+        }
     }
     return AdvanceAudit;
 };

+ 1 - 1
app/service/ledger_revise.js

@@ -30,7 +30,7 @@ module.exports = app => {
          * @returns {Promise<*>} - ledger_change下所有数据,并关联 project_account(读取提交人名称、单位、公司)
          */
         async getReviseList (tid) {
-            const sql = 'SELECT lc.id, lc.tid, lc.corder, lc.in_time, lc.uid, lc.begin_time, lc.end_time, lc.times, lc.status, lc.valid,' +
+            const sql = 'SELECT lc.id, lc.tid, lc.corder, lc.in_time, lc.uid, lc.begin_time, lc.end_time, lc.times, lc.status, lc.valid, lc.content,' +
                 '    pa.name As user_name, pa.role As user_role, pa.company As user_company' +
                 '  FROM ' + this.tableName + ' As lc' +
                 '  INNER JOIN ' + this.ctx.service.projectAccount.tableName + ' As pa ON lc.uid = pa.id' +

+ 48 - 0
app/service/revise_audit.js

@@ -267,9 +267,14 @@ module.exports = app => {
                 //     smsTypeConst.judge.approval.toString(), '台账修订需要您审批,请登录系统处理。');
                 await this.ctx.helper.sendAliSms(audit.audit_id, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), SmsAliConst.template.revise_check);
                 // 微信模板通知
+                const shenpiUrl = await this.ctx.helper.urlToShort(
+                    this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + revise.tid + '/revise/' + revise.id + '/info'
+                );
                 const wechatData = {
+                    wap_url: shenpiUrl,
                     status: wxConst.status.check,
                     tips: wxConst.tips.check,
+                    code: this.ctx.session.sessionProject.code,
                     begin_time: Date.parse(time),
                 };
                 await this.ctx.helper.sendWechat(audit.audit_id, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), wxConst.template.revise, wechatData);
@@ -281,9 +286,11 @@ module.exports = app => {
                 await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_report);
                 // 微信模板通知
                 const wechatData2 = {
+                    wap_url: shenpiUrl,
                     status: wxConst.status.report,
                     tips: wxConst.tips.report,
                     begin_time: Date.parse(time),
+                    code: this.ctx.session.sessionProject.code,
                 };
                 await this.ctx.helper.sendWechat(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), wxConst.template.revise, wechatData2);
                 await transaction.commit();
@@ -403,9 +410,14 @@ module.exports = app => {
                         //     smsTypeConst.judge.approval.toString(), '台账修订需要您审批,请登录系统处理。');
                         await this.ctx.helper.sendAliSms(nextAudit.audit_id, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), SmsAliConst.template.revise_check);
                         // 微信模板通知
+                        const shenpiUrl = await this.ctx.helper.urlToShort(
+                            this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + revise.tid + '/revise/' + revise.id + '/info'
+                        );
                         const wechatData = {
+                            wap_url: shenpiUrl,
                             status: wxConst.status.check,
                             tips: wxConst.tips.check,
+                            code: this.ctx.session.sessionProject.code,
                             begin_time: Date.parse(revise.begin_time),
                         };
                         await this.ctx.helper.sendWechat(nextAudit.audit_id, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), wxConst.template.revise, wechatData);
@@ -471,10 +483,15 @@ module.exports = app => {
                         users.push(revise.uid);
 
                         // 微信模板通知
+                        const shenpiUrl = await this.ctx.helper.urlToShort(
+                            this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + revise.tid + '/revise/' + revise.id + '/info'
+                        );
                         const wechatData2 = {
+                            wap_url: shenpiUrl,
                             status: wxConst.status.success,
                             tips: wxConst.tips.success,
                             begin_time: Date.parse(revise.begin_time),
+                            code: this.ctx.session.sessionProject.code,
                         };
                         await this.ctx.helper.sendWechat(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), wxConst.template.revise, wechatData2);
                     }
@@ -505,10 +522,15 @@ module.exports = app => {
                         status: SmsAliConst.status.back,
                     });
                     // 微信模板通知
+                    const shenpiUrl = await this.ctx.helper.urlToShort(
+                        this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + revise.tid + '/revise/' + revise.id + '/info'
+                    );
                     const wechatData = {
+                        wap_url: shenpiUrl,
                         status: wxConst.status.back,
                         tips: wxConst.tips.back,
                         begin_time: Date.parse(revise.begin_time),
+                        code: this.ctx.session.sessionProject.code,
                     };
                     await this.ctx.helper.sendWechat(revise.uid, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), wxConst.template.revise, wechatData);
                     // 其他参与人
@@ -525,9 +547,11 @@ module.exports = app => {
                     );
                     // 微信模板通知
                     const wechatData2 = {
+                        wap_url: shenpiUrl,
                         status: wxConst.status.back,
                         tips: wxConst.tips.back,
                         begin_time: Date.parse(revise.begin_time),
+                        code: this.ctx.session.sessionProject.code,
                     };
                     await this.ctx.helper.sendWechat(this._.map(auditors, 'user_id'), smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), wxConst.template.revise, wechatData2);
                 }
@@ -540,6 +564,30 @@ module.exports = app => {
         }
 
         /**
+         * 取待审批修订列表(wap用)
+         *
+         * @param auditorId
+         * @return {Promise<*>}
+         */
+        async getAuditReviseByWap(auditorId) {
+            const sql =
+                'SELECT ra.`audit_id`, ra.`times`, ra.`audit_order`, ra.`begin_time`, ra.`end_time`,' +
+                '    r.id, r.corder, r.uid, r.status, r.content, r.in_time, ' +
+                '    t.id As t_id, t.`name` As t_name, t.`project_id` As t_pid, t.`type` As t_type, t.`user_id` As t_uid, t.`status` As t_status, ' +
+                '    ti.`deal_info`, ' +
+                '    p.name As audit_name, p.role As audit_role, p.company As audit_company' +
+                '  FROM ' + this.tableName + ' AS ra' +
+                '  Left Join ' + this.ctx.service.ledgerRevise.tableName + ' As r On ra.rid = r.id' +
+                '  Left Join ' + this.ctx.service.tender.tableName + ' AS t On r.tid = t.id' +
+                '  Left Join ' + this.ctx.service.tenderInfo.tableName + ' AS ti On r.tid = ti.tid' +
+                '  Left Join ' + this.ctx.service.projectAccount.tableName + ' As p On ra.audit_id = p.id' +
+                '  WHERE r.`valid` != 0 and ra.`audit_id` = ? and ra.`status` = ?' +
+                '  ORDER BY ra.`begin_time` DESC';
+            const sqlParam = [auditorId, auditConst.status.checking];
+            return await this.db.query(sql, sqlParam);
+        }
+
+        /**
          * 获取审核人需要审核的标段列表
          *
          * @param auditorId

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

@@ -36,7 +36,7 @@
         </nav>
         <!--待审批期列表-->
         <div class="py-6">
-            <% if (auditStages.length !== 0 || auditChanges.length !== 0) { %>
+            <% if (auditStages.length !== 0 || auditChanges.length !== 0 || auditRevise.length !== 0 || auditAdvance.length !== 0) { %>
                 <% for (const audit of auditStages) { %>
                 <div class="card mb-3">
                     <div class="card-header d-flex justify-content-between">
@@ -62,6 +62,28 @@
                     </div>
                 </div>
                 <% } %>
+                <% for (const revise of auditRevise) { %>
+                    <div class="card mb-3">
+                        <div class="card-header d-flex justify-content-between">
+                            <span><%- JSON.parse(revise.deal_info).buildName %></span>
+                            <span class="badge badge-pill badge-info">台帐修订</span>
+                        </div>
+                        <div class="bg-light p-2 px-3"><b><%- revise.t_name %></b></div>
+                        <div class="card-body">
+                            <div class="d-flex justify-content-between"><span>第<%- revise.corder %>次修订</span></div>
+                            <div class="my-2">
+                                <table class="table table-sm table-bordered">
+                                    <tr><th width="90">修订时间</th><td class="text-right"><%- ctx.moment(revise.in_time).format('YYYY-MM-DD') %></td></tr>
+                                    <tr><th>修订人</th><td class="text-right"><%- revise.yb_name %></td></tr>
+                                    <tr><th>修订详情</th><td class=""><% if (revise.content.length <= 22) { %><%- revise.content %><% } else { %><%- revise.content.substring(0,22) %><a class="show-content" data-content="<%- revise.content %>" href="javascript:void(0);">展开更多</a><% } %></td></tr>
+                                </table>
+                            </div>
+                            <div class="">
+                                <a href="/wap/tender/<%- revise.t_id %>/revise/<%- revise.id %>/info" class="btn btn-block btn-success">审批</a>
+                            </div>
+                        </div>
+                    </div>
+                <% } %>
                 <% for (const change of auditChanges) { %>
                     <div class="card mb-3">
                         <div class="card-header d-flex justify-content-between">
@@ -85,6 +107,30 @@
                         </div>
                     </div>
                 <% } %>
+                <% for (const advance of auditAdvance) { %>
+                    <div class="card mb-3">
+                        <div class="card-header d-flex justify-content-between">
+                            <span><%- JSON.parse(advance.deal_info).buildName %></span>
+                            <span class="badge badge-pill badge-warning">预付款</span>
+                        </div>
+                        <div class="bg-light p-2 px-3"><b><%- advance.name %></b></div>
+                        <div class="card-body">
+                            <div class="d-flex justify-content-between"><span><%- advanceConst.typeCol[advance.type].name %>-第<%- advance.order %>期</span><span></span></div>
+                            <div class="my-2">
+                                <table class="table table-sm table-bordered">
+                                    <% const advancePayTotal = JSON.parse(advance.deal_param)[advanceConst.typeCol[advance.type].key + 'Advance']; %>
+                                    <tr><th>签约预付款</th><td class="text-right"><%- ctx.helper.formatMoney(advancePayTotal, ',', parseFloat(advancePayTotal).toString().split('.')[1] && parseFloat(advancePayTotal).toString().split('.')[1].length || 0) %></td></tr>
+                                    <tr><th>本期支付比例</th><td class="text-right"><%- advance.pay_ratio %>%</td></tr>
+                                    <tr><th>本期金额</th><td class="text-right"><%- advance.cur_amount %></td></tr>
+                                    <tr><th>截止本期金额</th><td class="text-right"><%- advance.prev_total_amount %></td></tr>
+                                </table>
+                            </div>
+                            <div class="">
+                                <a href="/wap/tender/<%- advance.tid %>/advance/<%- advance.id %>/detail" class="btn btn-block btn-success">审批</a>
+                            </div>
+                        </div>
+                    </div>
+                <% } %>
             <% } else { %>
                 <h3 class="text-center text-muted">暂无待审批期计量</h3>
             <% } %>
@@ -108,6 +154,13 @@
     <script src="/public/js/bootstrap/bootstrap.min.js"></script>
     <script src="/public/js/cookies.js"></script>
     <script src="/public/js/wap/global.js"></script>
+<script>
+    $(function () {
+        $('.show-content').on('click', function () {
+            $(this).parents('td').html($(this).data('content'));
+        });
+    })
+</script>
 </body>
 
 </html>

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

@@ -0,0 +1,145 @@
+<!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">
+    <script src=/public/js/echarts/echarts.min.js></script>
+    <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 %>#yufukuan" 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">
+            <% for (const t of advanceConst.typeCol) { %>
+            <li class="nav-item">
+                <a class="px-1 nav-link <% if (t.key === advanceConst.typeCol[0].key) {  %>active<% } %>" data-toggle="tab" href="#<%- t.key %>" role="tab"><%- t.name %></a>
+            </li>
+            <% } %>
+        </ul>
+        <div class="tab-content">
+            <% for (const t of advanceConst.typeCol) { %>
+            <div class="tab-pane <% if (t.key === advanceConst.typeCol[0].key) {  %>active<% } %>" id="<%- t.key %>">
+                <dl class="mb-2 mt-3">
+                    <% for (const advance of advanceList[t.type]) { %>
+                    <dt class="bg-light p-2 d-flex justify-content-between"><span><%- t.name %>-第<%- advance.order %>期</span>
+                        <span class="<%- auditConst.statusClass[advance.status] %>">
+                            <% if (advance.curAuditor) { %>
+                                <%- advance.curAuditor.name %><%if (advance.curAuditor.role !== '' && advance.curAuditor.role !== null) { %>-<%- advance.curAuditor.role %><% } %>
+                            <% } %>
+                            <%- auditConst.statusString[advance.status] %>
+                        </span>
+                    </dt>
+                    <dd>
+                        <table class="table table-hover">
+                            <tbody>
+                            <tr>
+                                <td>
+                                    <p class="mb-0">签约预付款</p>
+                                </td>
+                                <td class="text-right">
+                                    <b><%- advancePayTotalList[t.type] %></b>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>
+                                    <p class="mb-0">本期支付比例</p>
+                                </td>
+                                <td class="text-right">
+                                    <b><%- advance.pay_ratio %>%</b>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>
+                                    <p class="mb-0">本期金额</p>
+                                </td>
+                                <td class="text-right">
+                                    <b><%- advance.cur_amount %></b>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>
+                                    <p class="mb-0">截止本期金额</p>
+                                </td>
+                                <td class="text-right">
+                                    <b><%- advance.prev_total_amount %></b>
+                                </td>
+                            </tr>
+                            <% if (advance.curAuditor && advance.status == auditConst.status.checking && advance.curAuditor.audit_id === ctx.session.sessionUser.accountId) { %>
+                            <tr>
+                                <td colspan="2">
+                                    <a class="btn btn-block btn-success" href="/wap/tender/<%- tender.id %>/advance/<%- advance.id %>/detail">审批</a>
+                                </td>
+                            </tr>
+                            <% } %>
+                            </tbody></table>
+                    </dd>
+                    <% } %>
+                </dl>
+            </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>
+<!-- JS. -->
+<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/wap/global.js"></script>
+<script>
+    $(document).ready(function () {
+        <% for (const t of advanceConst.typeCol) { %>
+        if (window.location.hash && window.location.hash === '#<%- t.key %>') {
+            $('#start').removeClass('active');
+            $('.nav-item a[href="#start"]').removeClass('active');
+
+            $('#<%- t.key %>').addClass('active');
+            $('.nav-item a[href="#<%- t.key %>"]').addClass('active');
+        }
+        <% } %>
+    });
+</script>
+</body>
+</html>

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

@@ -0,0 +1,254 @@
+<!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">
+    <script src=/public/js/echarts/echarts.min.js></script>
+    <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 %>/advance#<%- advanceConst.typeCol[advance.type].key %>" class="mr-2 text-white show-loading"><i class="fa fa-chevron-left"></i><%- advanceConst.typeCol[advance.type].name %></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">
+        <!--最新期-->
+        <% let audit = 0; %>
+        <% if (advance) { %>
+            <dl class="mb-2 mt-3">
+                <dt class="bg-light p-2 d-flex justify-content-between"><span><%- advanceConst.typeCol[advance.type].name %>-第<%- advance.order %>期</span>
+                    <span class="<%- auditConst.statusClass[advance.status] %>">
+                        <% if (advance.curAuditor) { %>
+                            <%- advance.curAuditor.name %><%if (advance.curAuditor.role !== '' && advance.curAuditor.role !== null) { %>-<%- advance.curAuditor.role %><% } %>
+                        <% } %>
+                        <%- auditConst.statusString[advance.status] %>
+                        </span>
+                </dt>
+                <dd>
+                    <table class="table table-hover">
+                        <tbody>
+                        <tr>
+                            <td>
+                                <p class="mb-0">签约预付款</p>
+                            </td>
+                            <td class="text-right">
+                                <b><%- advance.advancePayTotal %></b>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td>
+                                <p class="mb-0">本期支付比例</p>
+                            </td>
+                            <td class="text-right">
+                                <b><%- advance.pay_ratio %>%</b>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td>
+                                <p class="mb-0">本期金额</p>
+                            </td>
+                            <td class="text-right">
+                                <b><%- advance.cur_amount %></b>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td>
+                                <p class="mb-0">截止本期金额</p>
+                            </td>
+                            <td class="text-right">
+                                <b><%- advance.prev_total_amount %></b>
+                            </td>
+                        </tr>
+                        </tbody></table>
+                </dd>
+            </dl>
+            <!--审批流程-->
+            <div class="card mt-3">
+                <ul class="list-group list-group-flush">
+                    <li class="list-group-item">
+                        <% if (advance.status === auditConst.status.uncheck) { %>
+                            <span class="pull-right"> 上报中</span>
+                        <% } else { %>
+                            <span class="text-success pull-right"><small><%- advance.auditors[0].create_time.toLocaleDateString() %></small> 上报</span>
+                        <% } %>
+                        <h5 class="card-title"><i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- advance.user.name %><small class="text-muted"><%- advance.user.role %></small></h5>
+                    </li>
+                    <% for (let iA = 0; iA < advance.auditors.length; iA++) { %>
+                        <% const auditors = advance.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].audit_id === 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>
+    <!--底栏菜单-->
+    <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/<%- tender.id %>/advance/<%- advance.id %>/audit/check" method="post" id="audit-check0" onsubmit="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/<%- advance.tid %>/advance/<%- advance.id %>/audit/check" method="post" id="audit-check1" onsubmit="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 %>" <% if (audit.order === 1 || audit.audit_id === advance.auditors[0].audit_id) { %>checked<% } %>>
+                        <label class="custom-control-label" for="customRadioInline1">退回原报 <%- advance.user.name %></label>
+                    </div>
+                    <% if (audit.order > 1 && audit.audit_id !== advance.auditors[0].audit_id) { %>
+                        <% const auditorIndex = advance.auditors2.findIndex(function (item) { return item.audit_id === audit.audit_id }) %>
+                        <div class="custom-control custom-radio custom-control-inline">
+                            <input class="custom-control-input" type="radio" name="checkType" id="customRadioInline2" value="<%- auditConst.status.checkNoPre %>" checked>
+                            <label class="custom-control-label" for="customRadioInline2">退回上一审批人 <%- advance.auditors2[auditorIndex-1].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>
+<!-- JS. -->
+<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/wap/global.js"></script>
+<script>
+    // $(document).ready(function () {
+    //     $('#audit-check0').submit(function (e) {
+    //         if (auditCheck(0)) {
+    //             const data = {
+    //                 opinion: $('[name=opinion]', this).val(),
+    //                 checkType: parseInt($('[name=checkType]', this).val()),
+    //             };
+    //             postData(this.action, data, function () {
+    //                 window.location.reload();
+    //             });
+    //         }
+    //         return false;
+    //     });
+    //     $('#audit-check1').submit(function (e) {
+    //         if (auditCheck(1)) {
+    //             const data = {
+    //                 opinion: $('[name=opinion]', this).val(),
+    //                 checkType: parseInt($('[name=checkType]:checked', this).val()),
+    //             };
+    //             postData(this.action, data, function () {
+    //                 window.location.reload();
+    //             });
+    //         }
+    //         return false;
+    //     });
+    // })
+
+    // 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>

+ 1 - 1
app/view/wap/shenpi_change.ejs

@@ -21,7 +21,7 @@
     <!--顶部-->
     <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 %>" class="mr-2 text-white show-loading"><i class="fa fa-chevron-left"></i>工程变更</a></span>
+            <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>

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

@@ -0,0 +1,225 @@
+<!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">
+    <script src=/public/js/echarts/echarts.min.js></script>
+    <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 %>#tzxiuding" 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">
+        <!--最新期-->
+        <% let audit = 0; %>
+        <% if (revise) { %>
+            <dl class="mb-2 mt-3">
+                <dt class="bg-light p-2 d-flex justify-content-between"><span>第<%- revise.corder %>次修订</span>
+                    <% if (!revise.valid) {%>
+                    <span class="text-danger">
+                        作废
+                    </span>
+                    <% } else { %>
+                    <span class="<%- auditConst.auditStringClass[revise.status] %>">
+                        <% if (revise.curAuditor && revise.status !== auditConst.status.checked) { %>
+                            <%- revise.curAuditor.name %><%if (revise.curAuditor.role !== '' && revise.curAuditor.role !== null) { %>-<%- revise.curAuditor.role %><% } %>
+                        <% } %>
+                        <%- revise.status === auditConst.status.checked ? '审批完成' : auditConst.auditProgress[revise.status] %>
+                    </span>
+                    <% } %>
+                </dt>
+                <dd>
+                    <table class="table table-hover">
+                        <tr><td width="90">修订时间</td><td><%- ctx.moment(revise.in_time).format('YYYY-MM-DD') %></td></tr>
+                        <tr><td>修订人</td><td><%- revise.user.name %></td></tr>
+                        <tr><td>修订详情</td><td><%- revise.content %></td></tr>
+                    </table>
+                </dd>
+            </dl>
+            <!--审批流程-->
+            <div class="card mt-3">
+                <ul class="list-group list-group-flush">
+                    <li class="list-group-item">
+                        <% if (!revise.valid) { %>
+                            <span class="text-danger pull-right"> 作废</span>
+                        <% } else if (revise.status === auditConst.status.uncheck) { %>
+                            <span class="pull-right"> 上报中</span>
+                        <% } else { %>
+                            <span class="text-success pull-right"><small><%- revise.auditors[0].begin_time.toLocaleDateString() %></small> 上报</span>
+                        <% } %>
+                        <h5 class="card-title"><i class="fa fa-play-circle fa-rotate-90 text-success"></i> <%- revise.user.name %><small class="text-muted"><%- revise.user.role %></small></h5>
+                    </li>
+                    <% for (let iA = 0; iA < revise.auditors.length; iA++) { %>
+                        <% const auditors = revise.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].audit_id === 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>
+    <!--底栏菜单-->
+    <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/<%- tender.id %>/revise/audit/check" method="post" id="audit-check0" onsubmit="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/<%- revise.tid %>/revise/audit/check" method="post" id="audit-check1" onsubmit="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" checked class="custom-control-input" value="<%- auditConst.status.checkNo %>" <% if (audit.order === 1 || audit.audit_id === revise.auditors[0].audit_id) { %>checked<% } %>>
+                        <label class="custom-control-label" for="customRadioInline1">退回原报 <%- revise.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>
+<!-- JS. -->
+<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/wap/global.js"></script>
+<script>
+    // $(document).ready(function () {
+    //     $('#audit-check0').submit(function (e) {
+    //         if (auditCheck(0)) {
+    //             const data = {
+    //                 opinion: $('[name=opinion]', this).val(),
+    //                 checkType: parseInt($('[name=checkType]', this).val()),
+    //             };
+    //             postData(this.action, data, function () {
+    //                 window.location.reload();
+    //             });
+    //         }
+    //         return false;
+    //     });
+    //     $('#audit-check1').submit(function (e) {
+    //         if (auditCheck(1)) {
+    //             const data = {
+    //                 opinion: $('[name=opinion]', this).val(),
+    //                 checkType: parseInt($('[name=checkType]:checked', this).val()),
+    //             };
+    //             postData(this.action, data, function () {
+    //                 window.location.reload();
+    //             });
+    //         }
+    //         return false;
+    //     });
+    // })
+
+    // 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>

+ 1 - 1
app/view/wap/shenpi_stage.ejs

@@ -22,7 +22,7 @@
     <!--顶部-->
     <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 %>" class="mr-2 text-white show-loading"><i class="fa fa-chevron-left"></i>计量期</a></span>
+            <span class="text-white ml-3"><a href="/wap/tender/<%- tender.id %>#jlqi" 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>

+ 95 - 3
app/view/wap/tender.ejs

@@ -15,6 +15,15 @@
         body {
             padding: 0;
         }
+        .tab-content > .tab-pane,.pill-content > .pill-pane {
+            display: block;
+            height: 0;
+            overflow-y: hidden;
+        }
+
+        .tab-content > .active,.pill-content > .active {
+            height: auto;
+        }
     </style>
 </head>
 <body>
@@ -43,13 +52,19 @@
         <!--标签-->
         <ul class="nav nav-tabs nav-fill">
             <li class="nav-item">
-                <a class="nav-link active" data-toggle="tab" href="#gaikuang" role="tab">概况</a>
+                <a class="px-1 nav-link active" data-toggle="tab" href="#gaikuang" role="tab">概况</a>
+            </li>
+            <li class="nav-item">
+                <a class="px-1 nav-link" data-toggle="tab" href="#yufukuan" role="tab">预付款</a>
             </li>
             <li class="nav-item">
-                <a class="nav-link" data-toggle="tab" href="#jlqi" role="tab">计量期</a>
+                <a class="px-1 nav-link" data-toggle="tab" href="#tzxiuding" role="tab">台帐修订</a>
             </li>
             <li class="nav-item">
-                <a class="nav-link" data-toggle="tab" href="#biangeng" role="tab">工程变更</a>
+                <a class="px-1 nav-link" data-toggle="tab" href="#jlqi" role="tab">计量期</a>
+            </li>
+            <li class="nav-item">
+                <a class="px-1 nav-link" data-toggle="tab" href="#biangeng" role="tab">工程变更</a>
             </li>
         </ul>
         <div class="tab-content">
@@ -76,6 +91,49 @@
                     </div>
                 </div>
             </div>
+            <div class="tab-pane" id="yufukuan">
+                <% for (const t of advanceConst.typeCol) { %>
+                <div class="card my-3">
+                    <div class="card-body">
+                        <a href="/wap/tender/<%- tender.id %>/advance#<%- t.key %>"><h5 class="card-title d-flex justify-content-between"><%- t.name %><span><% if (advanceList[t.type]) { %>第<%- advanceList[t.type].order %>期<% } %></span></h5></a>
+                    </div>
+                </div>
+                <% } %>
+            </div>
+            <div class="tab-pane" id="tzxiuding">
+                <dl class="mb-2 mt-3">
+                    <% for (const lr of revises) { %>
+                    <dt class="bg-light p-2 d-flex justify-content-between"><span>第<%- lr.corder %>次修订</span>
+                        <% if (!lr.valid) {%>
+                        <span class="text-danger">
+                            作废
+                        </span>
+                        <% } else { %>
+                        <span class="<%- auditReviseConst.auditStringClass[lr.status] %>">
+                            <% if (lr.curAuditor && lr.status !== auditReviseConst.status.checked) { %>
+                                <%- lr.curAuditor.name %><%if (lr.curAuditor.role !== '' && lr.curAuditor.role !== null) { %>-<%- lr.curAuditor.role %><% } %>
+                            <% } %>
+                            <%- lr.status === auditReviseConst.status.checked ? '审批完成' : auditReviseConst.auditProgress[lr.status] %>
+                        </span>
+                        <% } %>
+                    </dt>
+                    <dd>
+                        <table class="table table-hover">
+                            <tr><td width="90">修订时间</td><td><%- ctx.moment(lr.in_time).format('YYYY-MM-DD') %></td></tr>
+                            <tr><td>修订人</td><td><%- lr.user_name %></td></tr>
+                            <tr><td>修订详情</td><td><% if (lr.content) { %><% if (lr.content.length <= 22) { %><%- lr.content %><% } else { %><%- lr.content.substring(0,22) %><a class="show-content" data-content="<%- lr.content %>" href="javascript:void(0);">展开更多</a><% } %><% } %></td></tr>
+                            <% if (lr.curAuditor && lr.status == auditReviseConst.status.checking && lr.curAuditor.audit_id === ctx.session.sessionUser.accountId) { %>
+                            <tr>
+                                <td colspan="2">
+                                    <a class="btn btn-block btn-success" href="/wap/tender/<%- tender.id %>/revise/<%- lr.id %>/info">审批</a>
+                                </td>
+                            </tr>
+                            <% } %>
+                        </table>
+                    </dd>
+                    <% } %>
+                </dl>
+            </div>
             <div class="tab-pane" id="jlqi">
                 <!--期列表-->
                 <dl class="mb-2 mt-3">
@@ -418,6 +476,40 @@
     myChart.setOption(option);
     //3 标段月进度//
 </script>
+<script>
+    $(document).ready(function () {
+        if (window.location.hash && window.location.hash === '#yufukuan') {
+            $('#gaikuang').removeClass('active');
+            $('.nav-item a[href="#gaikuang"]').removeClass('active');
+
+            $('#yufukuan').addClass('active');
+            $('.nav-item a[href="#yufukuan"]').addClass('active');
+        } else if (window.location.hash && window.location.hash === '#tzxiuding') {
+            $('#gaikuang').removeClass('active');
+            $('.nav-item a[href="#gaikuang"]').removeClass('active');
+
+            $('#tzxiuding').addClass('active');
+            $('.nav-item a[href="#tzxiuding"]').addClass('active');
+        } else if (window.location.hash && window.location.hash === '#jlqi') {
+            $('#gaikuang').removeClass('active');
+            $('.nav-item a[href="#gaikuang"]').removeClass('active');
+
+            $('#jlqi').addClass('active');
+            $('.nav-item a[href="#jlqi"]').addClass('active');
+        } else if (window.location.hash && window.location.hash === '#biangeng') {
+            $('#gaikuang').removeClass('active');
+            $('.nav-item a[href="#gaikuang"]').removeClass('active');
+
+            $('#biangeng').addClass('active');
+            $('.nav-item a[href="#biangeng"]').addClass('active');
+        }
+
+        $('.show-content').on('click', function () {
+            $(this).parents('td').html($(this).data('content'));
+        });
+
+    });
+</script>
 </body>
 
 </html>