Prechádzať zdrojové kódy

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

MaiXinRong 5 rokov pred
rodič
commit
ea1b193f84

+ 271 - 221
app/const/audit.js

@@ -1,4 +1,4 @@
-'use strict';
+'use strict'
 
 /**
  *
@@ -8,92 +8,92 @@
  * @version
  */
 // 台账审批流程
-const ledger = (function() {
+const ledger = (function () {
     const status = {
         uncheck: 1, // 待上报
         checking: 2, // 待审批|审批中
         checked: 3, // 审批通过
-        checkNo: 4, // 审批退回
-    };
+        checkNo: 4 // 审批退回
+    }
 
-    const statusString = [];
-    statusString[status.uncheck] = '';
-    statusString[status.checking] = '审批中';
-    statusString[status.checked] = '审批完成';
-    statusString[status.checkNo] = '审批退回';
+    const statusString = []
+    statusString[status.uncheck] = ''
+    statusString[status.checking] = '审批中'
+    statusString[status.checked] = '审批完成'
+    statusString[status.checkNo] = '审批退回'
 
-    const statusClass = [];
-    statusClass[status.uncheck] = '';
-    statusClass[status.checking] = '';
-    statusClass[status.checked] = 'text-success';
-    statusClass[status.checkNo] = 'text-warning';
+    const statusClass = []
+    statusClass[status.uncheck] = ''
+    statusClass[status.checking] = ''
+    statusClass[status.checked] = 'text-success'
+    statusClass[status.checkNo] = 'text-warning'
 
     // 标段概况页
     // 描述文本
-    const auditString = [];
-    auditString[status.uncheck] = '';
-    auditString[status.checking] = '审批中';
-    auditString[status.checked] = '审批完成';
-    auditString[status.checkNo] = '审批退回';
+    const auditString = []
+    auditString[status.uncheck] = ''
+    auditString[status.checking] = '审批中'
+    auditString[status.checked] = '审批通过'
+    auditString[status.checkNo] = '审批退回'
     // 文字样式
-    const auditStringClass = [];
-    auditStringClass[status.uncheck] = '';
-    auditStringClass[status.checking] = 'text-warning';
-    auditStringClass[status.checked] = 'text-success';
-    auditStringClass[status.checkNo] = 'text-warning';
-    return { status, statusString, statusClass, auditString, auditStringClass };
-})();
+    const auditStringClass = []
+    auditStringClass[status.uncheck] = ''
+    auditStringClass[status.checking] = 'text-warning'
+    auditStringClass[status.checked] = 'text-success'
+    auditStringClass[status.checkNo] = 'text-warning'
+    return { status, statusString, statusClass, auditString, auditStringClass }
+})()
 
 // 台账修订 审批流程
-const revise = (function() {
+const revise = (function () {
     const status = {
         uncheck: 1, // 待上报
         checking: 2, // 待审批|审批中
         checked: 3, // 审批通过
-        checkNo: 4, // 审批退回
-    };
-    const statusString = [];
-    statusString[status.uncheck] = '草稿';
-    statusString[status.checking] = '审批中';
-    statusString[status.checked] = '完成';
-    statusString[status.checkNo] = '退回';
-
-    const statusClass = [];
-    statusClass[status.uncheck] = '';
-    statusClass[status.checking] = '';
-    statusClass[status.checked] = 'text-success';
-    statusClass[status.checkNo] = 'text-warning';
+        checkNo: 4 // 审批退回
+    }
+    const statusString = []
+    statusString[status.uncheck] = '草稿'
+    statusString[status.checking] = '审批中'
+    statusString[status.checked] = '审批通过'
+    statusString[status.checkNo] = '审批退回'
+
+    const statusClass = []
+    statusClass[status.uncheck] = ''
+    statusClass[status.checking] = ''
+    statusClass[status.checked] = 'text-success'
+    statusClass[status.checkNo] = 'text-warning'
 
     // 标段概况页
     // 描述文本
-    const auditString = [];
-    auditString[status.uncheck] = '';
-    auditString[status.checking] = '审批中';
-    auditString[status.checked] = '审批完成';
-    auditString[status.checkNo] = '审批退回';
+    const auditString = []
+    auditString[status.uncheck] = ''
+    auditString[status.checking] = '审批中'
+    auditString[status.checked] = '审批通过'
+    auditString[status.checkNo] = '审批退回'
     // 文字样式
-    const auditStringClass = [];
-    auditStringClass[status.uncheck] = '';
-    auditStringClass[status.checking] = 'text-warning';
-    auditStringClass[status.checked] = 'text-success';
-    auditStringClass[status.checkNo] = 'text-warning';
+    const auditStringClass = []
+    auditStringClass[status.uncheck] = ''
+    auditStringClass[status.checking] = 'text-warning'
+    auditStringClass[status.checked] = 'text-success'
+    auditStringClass[status.checkNo] = 'text-warning'
     // 描述文本
-    const auditProgress = [];
-    auditProgress[status.uncheck] = '草稿';
-    auditProgress[status.checking] = '审批中';
-    auditProgress[status.checked] = '审批通过';
-    auditProgress[status.checkNo] = '审批退回';
+    const auditProgress = []
+    auditProgress[status.uncheck] = '草稿'
+    auditProgress[status.checking] = '审批中'
+    auditProgress[status.checked] = '审批通过'
+    auditProgress[status.checkNo] = '审批退回'
     // 样式
-    const auditProgressClass = [];
-    auditProgressClass[status.uncheck] = '';
-    auditProgressClass[status.checking] = 'text-warning';
-    auditProgressClass[status.checked] = 'text-success';
-    auditProgressClass[status.checkNo] = 'text-warning';
-    return { status, statusString, statusClass, auditString, auditStringClass, auditProgress, auditProgressClass };
-})();
+    const auditProgressClass = []
+    auditProgressClass[status.uncheck] = ''
+    auditProgressClass[status.checking] = 'text-warning'
+    auditProgressClass[status.checked] = 'text-success'
+    auditProgressClass[status.checkNo] = 'text-warning'
+    return { status, statusString, statusClass, auditString, auditStringClass, auditProgress, auditProgressClass }
+})()
 
 // 期审批流程
-const stage = (function() {
+const stage = (function () {
     // 流程状态
     const status = {
         uncheck: 1, // 待上报
@@ -101,92 +101,103 @@ const stage = (function() {
         checked: 3, // 审批通过
         checkNo: 4, // 审批退回原报
         checkNoPre: 5, // 审批退回上一人
-        checkAgain: 6, // 重新审批 // 该状态仅可用于,终审退回时,修改原终审的审批状态,并同时新增一条新的终审审批中记录
-    };
+        checkAgain: 6 // 重新审批 // 该状态仅可用于,终审退回时,修改原终审的审批状态,并同时新增一条新的终审审批中记录
+    }
 
     // 流程状态提示
-    const statusString = [];
-    statusString[status.uncheck] = '待上报';
-    statusString[status.checking] = '审批中';
-    statusString[status.checked] = '审批通过';
-    statusString[status.checkNo] = '审批退回';
-    statusString[status.checkNoPre] = '审批退回';
-    statusString[status.checkAgain] = '重新审批';
+    const statusString = []
+    statusString[status.uncheck] = '待上报'
+    statusString[status.checking] = '审批中'
+    statusString[status.checked] = '审批通过'
+    statusString[status.checkNo] = '审批退回'
+    statusString[status.checkNoPre] = '审批退回'
+    statusString[status.checkAgain] = '重新审批'
 
     // 流程状态样式
-    const statusClass = [];
-    statusClass[status.uncheck] = '';
-    statusClass[status.checking] = '';
-    statusClass[status.checked] = 'text-success';
-    statusClass[status.checkNo] = 'text-warning';
-    statusClass[status.checkNoPre] = 'text-warning';
-    statusClass[status.checkAgain] = 'text-warning';
+    const statusClass = []
+    statusClass[status.uncheck] = ''
+    statusClass[status.checking] = ''
+    statusClass[status.checked] = 'text-success'
+    statusClass[status.checkNo] = 'text-warning'
+    statusClass[status.checkNoPre] = 'text-warning'
+    statusClass[status.checkAgain] = 'text-warning'
 
     /**
      * 期列表,审批状态一列
-      */
+     */
     // 按钮
-    const statusButton = [];
-    statusButton[status.uncheck] = '待上报';
-    statusButton[status.checking] = '审批';
-    statusButton[status.checked] = '';
-    statusButton[status.checkNo] = '重新上报';
-    statusButton[status.checkNoPre] = '重新审批';
-    statusButton[status.checkAgain] = '重新审批';
+    const statusButton = []
+    statusButton[status.uncheck] = '待上报'
+    statusButton[status.checking] = '审批'
+    statusButton[status.checked] = ''
+    statusButton[status.checkNo] = '重新上报'
+    statusButton[status.checkNoPre] = '重新审批'
+    statusButton[status.checkAgain] = '重新审批'
     // 按钮样式
-    const statusButtonClass = [];
-    statusButtonClass[status.uncheck] = 'btn-primary';
-    statusButtonClass[status.checking] = 'btn-success';
-    statusButtonClass[status.checked] = '';
-    statusButtonClass[status.checkNo] = 'btn-warning';
-    statusButtonClass[status.checkNoPre] = 'btn-warning';
-    statusButtonClass[status.checkAgain] = 'btn-warning';
+    const statusButtonClass = []
+    statusButtonClass[status.uncheck] = 'btn-primary'
+    statusButtonClass[status.checking] = 'btn-success'
+    statusButtonClass[status.checked] = ''
+    statusButtonClass[status.checkNo] = 'btn-warning'
+    statusButtonClass[status.checkNoPre] = 'btn-warning'
+    statusButtonClass[status.checkAgain] = 'btn-warning'
     // 描述文本
-    const auditString = [];
-    auditString[status.uncheck] = '';
-    auditString[status.checking] = '审批中';
-    auditString[status.checked] = '完成';
-    auditString[status.checkNo] = '退回';
-    auditString[status.checkNoPre] = '退回';
-    auditString[status.checkAgain] = '重新审批';
+    const auditString = []
+    auditString[status.uncheck] = ''
+    auditString[status.checking] = '审批中'
+    auditString[status.checked] = '审批通过'
+    auditString[status.checkNo] = '审批退回'
+    auditString[status.checkNoPre] = '审批退回'
+    auditString[status.checkAgain] = '重新审批'
     // 文字样式
-    const auditStringClass = [];
-    auditStringClass[status.uncheck] = '';
-    auditStringClass[status.checking] = 'text-warning';
-    auditStringClass[status.checked] = 'text-success';
-    auditStringClass[status.checkNo] = 'text-warning';
-    auditStringClass[status.checkNoPre] = 'text-warning';
-    auditStringClass[status.checkAgain] = 'text-warning';
+    const auditStringClass = []
+    auditStringClass[status.uncheck] = ''
+    auditStringClass[status.checking] = 'text-warning'
+    auditStringClass[status.checked] = 'text-success'
+    auditStringClass[status.checkNo] = 'text-warning'
+    auditStringClass[status.checkNoPre] = 'text-warning'
+    auditStringClass[status.checkAgain] = 'text-warning'
     /* ------------------------------------------------------- */
 
     /**
      * 期列表,审批进度一列
-    */
+     */
     // 描述文本
-    const auditProgress = [];
-    auditProgress[status.uncheck] = '待上报';
-    auditProgress[status.checking] = '审批中';
-    auditProgress[status.checked] = '审批通过';
-    auditProgress[status.checkNo] = '审批退回';
-    auditProgress[status.checkNoPre] = '审批退回';
-    auditProgress[status.checkAgain] = '重新审批';
+    const auditProgress = []
+    auditProgress[status.uncheck] = '待上报'
+    auditProgress[status.checking] = '审批中'
+    auditProgress[status.checked] = '审批通过'
+    auditProgress[status.checkNo] = '审批退回'
+    auditProgress[status.checkNoPre] = '审批退回'
+    auditProgress[status.checkAgain] = '重新审批'
     // 样式
-    const auditProgressClass = [];
-    auditProgressClass[status.uncheck] = '';
-    auditProgressClass[status.checking] = 'text-warning';
-    auditProgressClass[status.checked] = 'text-success';
-    auditProgressClass[status.checkNo] = 'text-warning';
-    auditProgressClass[status.checkNoPre] = 'text-warning';
-    auditProgressClass[status.checkAgain] = 'text-warning';
+    const auditProgressClass = []
+    auditProgressClass[status.uncheck] = ''
+    auditProgressClass[status.checking] = 'text-warning'
+    auditProgressClass[status.checked] = 'text-success'
+    auditProgressClass[status.checkNo] = 'text-warning'
+    auditProgressClass[status.checkNoPre] = 'text-warning'
+    auditProgressClass[status.checkAgain] = 'text-warning'
     /* ------------------------------------------------------- */
 
     const backType = {
         org: 1,
-        pre: 2,
-    };
-    return { status, statusString, statusClass, statusButton, statusButtonClass, auditString, auditStringClass, auditProgress, auditProgressClass, backType, timesLen: 100 };
-})();
-
+        pre: 2
+    }
+    return {
+        status,
+        statusString,
+        statusClass,
+        statusButton,
+        statusButtonClass,
+        auditString,
+        auditStringClass,
+        auditProgress,
+        auditProgressClass,
+        backType,
+        timesLen: 100
+    }
+})()
 
 // 变更令状态
 const status = {
@@ -195,39 +206,39 @@ const status = {
     checked: 3, // 审批完成
     // checkNo: 4,     // 审批终止
     back: 5, // 重新上报
-    backnew: 6, // 退回
-};
-const statusButton = [];
-statusButton[status.uncheck] = '上报';
-statusButton[status.checking] = '审批';
-statusButton[status.checked] = '';
+    backnew: 6 // 退回
+}
+const statusButton = []
+statusButton[status.uncheck] = '上报'
+statusButton[status.checking] = '审批'
+statusButton[status.checked] = ''
 // statusButton[status.checkNo] = '';
-statusButton[status.back] = '重新上报';
-statusButton[status.backnew] = '审批';
+statusButton[status.back] = '重新上报'
+statusButton[status.backnew] = '审批'
 
-const statusButtonClass = [];
-statusButtonClass[status.uncheck] = 'btn-primary';
-statusButtonClass[status.checking] = 'btn-success';
-statusButtonClass[status.checked] = '';
+const statusButtonClass = []
+statusButtonClass[status.uncheck] = 'btn-primary'
+statusButtonClass[status.checking] = 'btn-success'
+statusButtonClass[status.checked] = ''
 // statusButtonClass[status.checkNo] = '';
-statusButtonClass[status.back] = 'btn-warning';
-statusButtonClass[status.backnew] = 'btn-success';
+statusButtonClass[status.back] = 'btn-warning'
+statusButtonClass[status.backnew] = 'btn-success'
 
-const statusString = [];
-statusString[status.uncheck] = '';
-statusString[status.checking] = '审批中';
-statusString[status.checked] = '审批完成';
+const statusString = []
+statusString[status.uncheck] = ''
+statusString[status.checking] = '审批中'
+statusString[status.checked] = '审批通过'
 // statusString[status.checkNo] = '终止';
-statusString[status.back] = '审批退回';
-statusString[status.backnew] = '退回';
+statusString[status.back] = '审批退回'
+statusString[status.backnew] = '审批退回'
 
-const statusClass = [];
-statusClass[status.uncheck] = '';
-statusClass[status.checking] = 'text-warning';
-statusClass[status.checked] = 'text-success';
+const statusClass = []
+statusClass[status.uncheck] = ''
+statusClass[status.checking] = 'text-warning'
+statusClass[status.checked] = 'text-success'
 // statusClass[status.checkNo] = 'text-danger';
-statusClass[status.back] = 'text-warning';
-statusClass[status.backnew] = 'text-warning';
+statusClass[status.back] = 'text-warning'
+statusClass[status.backnew] = 'text-warning'
 
 /* ------------------------------------------------------- */
 
@@ -239,26 +250,26 @@ const auditStatus = {
     // checkNo: 4,     // 审批终止
     back: 5, // 退回到原报人重新上报
     backnew: 6, // 退回到上一个审批人
-    checkAgain: 7, // 重新审批
-};
+    checkAgain: 7 // 重新审批
+}
 
-const auditStatusString = [];
-auditStatusString[auditStatus.uncheck] = '待上报';
-auditStatusString[auditStatus.checking] = '审批中';
-auditStatusString[auditStatus.checked] = '审批通过';
+const auditStatusString = []
+auditStatusString[auditStatus.uncheck] = '待上报'
+auditStatusString[auditStatus.checking] = '审批中'
+auditStatusString[auditStatus.checked] = '审批通过'
 // auditStatusString[auditStatus.checkNo] = '审批终止';
-auditStatusString[auditStatus.back] = '退回';
-auditStatusString[auditStatus.backnew] = '审批退回';
-auditStatusString[auditStatus.checkAgain] = '重新审批';
-
-const auditStatusClass = [];
-auditStatusClass[auditStatus.uncheck] = '';
-auditStatusClass[auditStatus.checking] = 'text-warning';
-auditStatusClass[auditStatus.checked] = 'text-success';
+auditStatusString[auditStatus.back] = '退回'
+auditStatusString[auditStatus.backnew] = '审批退回'
+auditStatusString[auditStatus.checkAgain] = '重新审批'
+
+const auditStatusClass = []
+auditStatusClass[auditStatus.uncheck] = ''
+auditStatusClass[auditStatus.checking] = 'text-warning'
+auditStatusClass[auditStatus.checked] = 'text-success'
 // auditStatusClass[auditStatus.checkNo] = 'text-danger';
-auditStatusClass[auditStatus.back] = 'text-warning';
-auditStatusClass[auditStatus.backnew] = 'text-warning';
-auditStatusClass[auditStatus.checkAgain] = 'text-warning';
+auditStatusClass[auditStatus.back] = 'text-warning'
+auditStatusClass[auditStatus.backnew] = 'text-warning'
+auditStatusClass[auditStatus.checkAgain] = 'text-warning'
 
 /* ------------------------------------------------------- */
 
@@ -267,82 +278,120 @@ const filter = {
         pending: 1,
         uncheck: 5,
         checking: 2,
-        checked: 3,
+        checked: 3
         // checkNo: 4,
     },
-    statusString: [],
-};
-filter.statusString[filter.status.pending] = '待处理';
-filter.statusString[filter.status.uncheck] = '待上报';
-filter.statusString[filter.status.checking] = '进行中';
-filter.statusString[filter.status.checked] = '已完成';
+    statusString: []
+}
+filter.statusString[filter.status.pending] = '待处理'
+filter.statusString[filter.status.uncheck] = '待上报'
+filter.statusString[filter.status.checking] = '进行中'
+filter.statusString[filter.status.checked] = '已完成'
 // filter.statusString[filter.status.checkNo] = '终止';
 
 // 材料调差审批流程
-const material = (function() {
+const material = (function () {
     const status = {
         uncheck: 1, // 待上报
         checking: 2, // 待审批|审批中
         checked: 3, // 审批通过
         checkNo: 4, // 审批退回原报
         checkNoPre: 5, // 审批退回上一人
-        checkAgain: 6, // 终审退回  --该状态仅可用于,终审退回时,修改原终审的审批状态,并同时新增一条新的终审审批中记录
-    };
+        checkAgain: 6 // 终审退回  --该状态仅可用于,终审退回时,修改原终审的审批状态,并同时新增一条新的终审审批中记录
+    }
     // 流程状态提示
-    const statusString = [];
-    statusString[status.uncheck] = '待上报';
-    statusString[status.checking] = '审批中';
-    statusString[status.checked] = '审批通过';
-    statusString[status.checkNo] = '审批退回';
-    statusString[status.checkNoPre] = '审批退回';
-    statusString[status.checkAgain] = '重新审批';
+    const statusString = []
+    statusString[status.uncheck] = '待上报'
+    statusString[status.checking] = '审批中'
+    statusString[status.checked] = '审批通过'
+    statusString[status.checkNo] = '审批退回'
+    statusString[status.checkNoPre] = '审批退回'
+    statusString[status.checkAgain] = '重新审批'
 
     // 流程状态样式
-    const statusClass = [];
-    statusClass[status.uncheck] = '';
-    statusClass[status.checking] = '';
-    statusClass[status.checked] = 'text-success';
-    statusClass[status.checkNo] = 'text-warning';
-    statusClass[status.checkNoPre] = 'text-warning';
-    statusClass[status.checkAgain] = 'text-warning';
+    const statusClass = []
+    statusClass[status.uncheck] = ''
+    statusClass[status.checking] = ''
+    statusClass[status.checked] = 'text-success'
+    statusClass[status.checkNo] = 'text-warning'
+    statusClass[status.checkNoPre] = 'text-warning'
+    statusClass[status.checkAgain] = 'text-warning'
 
     // 按钮
-    const statusButton = [];
-    statusButton[status.uncheck] = '待上报';
-    statusButton[status.checking] = '审批';
-    statusButton[status.checked] = '';
-    statusButton[status.checkNo] = '重新上报';
+    const statusButton = []
+    statusButton[status.uncheck] = '待上报'
+    statusButton[status.checking] = '审批'
+    statusButton[status.checked] = ''
+    statusButton[status.checkNo] = '重新上报'
 
     // 按钮样式
-    const statusButtonClass = [];
-    statusButtonClass[status.uncheck] = 'btn-primary';
-    statusButtonClass[status.checking] = 'btn-success';
-    statusButtonClass[status.checked] = '';
-    statusButtonClass[status.checkNo] = 'btn-warning';
+    const statusButtonClass = []
+    statusButtonClass[status.uncheck] = 'btn-primary'
+    statusButtonClass[status.checking] = 'btn-success'
+    statusButtonClass[status.checked] = ''
+    statusButtonClass[status.checkNo] = 'btn-warning'
 
     // 描述文本
-    const auditProgress = [];
-    auditProgress[status.uncheck] = '待上报';
-    auditProgress[status.checking] = '审批中';
-    auditProgress[status.checked] = '审批通过';
-    auditProgress[status.checkNo] = '审批退回';
+    const auditProgress = []
+    auditProgress[status.uncheck] = '待上报'
+    auditProgress[status.checking] = '审批中'
+    auditProgress[status.checked] = '审批通过'
+    auditProgress[status.checkNo] = '审批退回'
     // 样式
-    const auditProgressClass = [];
-    auditProgressClass[status.uncheck] = '';
-    auditProgressClass[status.checking] = 'text-warning';
-    auditProgressClass[status.checked] = 'text-success';
-    auditProgressClass[status.checkNo] = 'text-warning';
-    return { status, statusString, statusClass, statusButton, statusButtonClass, auditProgress, auditProgressClass };
-})();
+    const auditProgressClass = []
+    auditProgressClass[status.uncheck] = ''
+    auditProgressClass[status.checking] = 'text-warning'
+    auditProgressClass[status.checked] = 'text-success'
+    auditProgressClass[status.checkNo] = 'text-warning'
+    return { status, statusString, statusClass, statusButton, statusButtonClass, auditProgress, auditProgressClass }
+})()
+
+// 预付款审批流程
+// 台账审批流程
+const advance = (function () {
+    const status = {
+        uncheck: 1, // 待上报
+        checking: 2, // 待审批|审批中
+        checked: 3, // 审批通过
+        checkNo: 4, // 审批退回原报
+        checkNoPre: 5 // 审批退回上一人
+    }
 
+    const statusString = []
+    statusString[status.uncheck] = ''
+    statusString[status.checking] = '审批中'
+    statusString[status.checked] = '审批通过'
+    statusString[status.checkNo] = '审批退回'
+
+    const statusClass = []
+    statusClass[status.uncheck] = ''
+    statusClass[status.checking] = ''
+    statusClass[status.checked] = 'text-success'
+    statusClass[status.checkNo] = 'text-warning'
+
+    // 标段概况页
+    // 描述文本
+    const auditString = []
+    auditString[status.uncheck] = ''
+    auditString[status.checking] = '审批中'
+    auditString[status.checked] = '审批通过'
+    auditString[status.checkNo] = '审批退回'
+    // 文字样式
+    const auditStringClass = []
+    auditStringClass[status.uncheck] = ''
+    auditStringClass[status.checking] = 'text-warning'
+    auditStringClass[status.checked] = 'text-success'
+    auditStringClass[status.checkNo] = 'text-warning'
+    return { status, statusString, statusClass, auditString, auditStringClass }
+})()
 // 推送类型
 const pushType = {
     material: 1,
     stage: 2,
     change: 3,
     revise: 4,
-    ledger: 5,
-};
+    ledger: 5
+}
 
 module.exports = {
     ledger,
@@ -357,8 +406,9 @@ module.exports = {
         statusClass,
         auditStatus,
         auditStatusString,
-        auditStatusClass,
+        auditStatusClass
     },
     filter,
     pushType,
-};
+    advance
+}

+ 4 - 0
app/const/sms_type.js

@@ -21,6 +21,7 @@ const smsType = {
     TZ: {
         name: '台账审批',
         path: '',
+        wechat: false,
         children: [
             { title: '需要我审批', value: 1 },
             { title: '审批结果', value: 2 },
@@ -29,6 +30,7 @@ const smsType = {
     XD: {
         name: '修订审批',
         path: '',
+        wechat: false,
         children: [
             { title: '需要我审批', value: 1 },
             { title: '审批结果', value: 2 },
@@ -37,6 +39,7 @@ const smsType = {
     JL: {
         name: '计量审批',
         path: '',
+        wechat: true,
         children: [
             { title: '需要我审批', value: 1 },
             { title: '审批结果', value: 2 },
@@ -45,6 +48,7 @@ const smsType = {
     BG: {
         name: '变更管理',
         path: '',
+        wechat: true,
         children: [
             { title: '需要我审批', value: 1 },
             { title: '审批结果', value: 2 },

+ 29 - 0
app/const/wechat_template.js

@@ -0,0 +1,29 @@
+'use strict';
+
+/**
+ * 微信通知模板
+ *
+ * @author Ellisran
+ * @date 2020/8/10
+ * @version
+ */
+const template = {
+    stage: '5vU3WmR90yDajbs4LWIWH4OQhunYlS1HXTiesIGxrsk',
+    change: '',
+};
+const status = {
+    check: '待审批',
+    back: '退回',
+    success: '通过',
+};
+const tips = {
+    check: '需要您审批',
+    back: '审批退回',
+    success: '审批通过',
+};
+
+module.exports = {
+    template,
+    status,
+    tips,
+};

+ 64 - 0
app/controller/advance_controller.js

@@ -0,0 +1,64 @@
+'use strict'
+const accountGroup = require('../const/account_group').group
+
+module.exports = app => {
+    class advanceController extends app.BaseController {
+        /**
+         * 开工预付款页面(AJAX) GET
+         * @param {Object} ctx 全局上下文
+         */
+        async index(ctx) {
+            const renderData = {
+                type: 'start',
+                advancePayTotal: ctx.tender.info.deal_param.startAdvance
+            }
+            await this.layout('advance/index.ejs', renderData, 'advance/modal.ejs')
+        }
+
+        /**
+         * 材料预付款页面(AJAX) GET
+         * @param {Object} ctx 全局上下文
+         */
+        async materialInfo(ctx) {
+            const renderData = {
+                type: 'material',
+                advancePayTotal: ctx.tender.info.deal_param.materialAdvance
+            }
+            await this.layout('advance/index.ejs', renderData, 'advance/modal.ejs')
+        }
+
+        /**
+         * 预付款详情页(AJAX) GET
+         * @param {Object} ctx 全局上下文
+         */
+        async detail(ctx) {
+            const renderData = {}
+            await this.layout('advance/detail.ejs', renderData)
+        }
+
+        /**
+         * 开始新一期页面(AJAX) GET
+         * @param {Object} ctx 全局上下文
+         */
+        async createInfo(ctx) {
+            const type = ctx.params.type
+            // 获取所有项目参与者
+            const accountList = await ctx.service.projectAccount.getAllDataByCondition({
+                where: { project_id: ctx.session.sessionProject.id, enable: 1 },
+                columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group']
+            })
+            const renderData = {
+                isEdited: true,
+                accountGroup,
+                accountList
+            }
+            await this.layout('advance/detail.ejs', renderData)
+        }
+
+        /**
+         * 添加审核人
+         */
+        async add(ctx) {}
+    }
+    return advanceController
+}

+ 30 - 4
app/controller/wechat_controller.js

@@ -134,10 +134,36 @@ module.exports = app => {
             }
         }
 
-        async urlchange(ctx) {
-            // 设置用户微信登录项目,跳转到对应wap页面
-            co
-            ctx.redirect(ctx.query.url);
+        // 设置用户微信登录项目,跳转到对应wap页面
+        async url2wap(ctx) {
+            try {
+                if (!ctx.query.project || !ctx.query.url) {
+                    throw '参数有误';
+                }
+                const code = ctx.query.project;
+                // 查找项目数据
+                const projectData = await ctx.service.project.getProjectByCode(code.toString().trim());
+                if (projectData === null) {
+                    throw '不存在项目数据';
+                }
+                const pa = await ctx.service.projectAccount.getDataByCondition({ project_id: projectData.id, wx_openid: ctx.session.wechatToken.openid });
+                if (!pa) {
+                    throw '该微信号未绑定此项目';
+                }
+                if (pa.enable !== 1) {
+                    throw '该账号已被停用,请联系销售人员';
+                }
+                // 设置项目和用户session记录
+                const result = await ctx.service.projectAccount.accountLogin({ project: projectData, accountData: pa }, 3);
+                if (!result) {
+                    throw '登录出错';
+                }
+                ctx.redirect(ctx.query.url);
+            } catch (error) {
+                console.log(error);
+                ctx.body = error;
+            }
+
         }
 
         async oauthTxt(ctx) {

+ 29 - 0
app/extend/helper.js

@@ -17,6 +17,7 @@ const bc = require('../lib/base_calc.js');
 const Decimal = require('decimal.js');
 Decimal.set({ precision: 50, defaults: true });
 const SMS = require('../lib/sms');
+const WX = require('../lib/wechat');
 
 module.exports = {
     _,
@@ -977,6 +978,34 @@ module.exports = {
         }
     },
 
+
+    async sendWechat(userId, type, judge, template, data = {}) {
+        const wechats = [];
+        if (!userId || (userId instanceof Array && userId.length === 0)) return;
+        const wxUser = await this.ctx.service.projectAccount.getAllDataByCondition({ where: { id: userId } });
+        for (const user of wxUser) {
+            if (!user.wx_openid || user.wx_openid === '') continue;
+            if (!user.wx_type || user.wx_type === '') continue;
+
+            const wxType = JSON.parse(user.wx_type);
+            if (wxType[type] && wxType[type].indexOf(judge) !== -1) {
+                wechats.push(user.wx_openid);
+            }
+        }
+
+        if (wechats.length > 0) {
+            const wx = new WX(this.ctx);
+            const tenderName = await wx.contentChange(this.ctx.tender.data.name);
+            const projectName = await wx.contentChange(this.ctx.tender.info.deal_info.buildName);
+            const param = {
+                projectName,
+                tenderName,
+            };
+            const postParam = Object.assign(param, data);
+            wx.Send(wechats, template, postParam);
+        }
+    },
+
     /**
      *
      * @param setting

+ 90 - 0
app/lib/wechat.js

@@ -0,0 +1,90 @@
+'use strict';
+
+/**
+ * 微信模板信息发送相关接口
+ *
+ * @author ellisran
+ * @date 2018/1/25
+ * @version
+ */
+
+// const xmlReader = require('xmlreader');
+const wxConst = require('../const/wechat_template.js');
+class WX {
+
+    /**
+     * 构造函数
+     *
+     * @param {Object} ctx - egg全局变量
+     * @return {void}
+     */
+    constructor(ctx) {
+        this.ctx = ctx;
+    }
+
+    /**
+     * 发送微信模板
+     *
+     * @param {Array} wx_openid - 发送的微信账号
+     * @param {String} template - 模板id
+     * @param {String} wap_url - wap页面地址
+     * @param {String} tips - 状态文字说明
+     * @param {String} status - 状态
+     * @param {Object} data - 一些模板展示数据
+     * @return {Boolean} - 发送结果
+     */
+    async Send(wx_openid, template, data) {
+        let flag = false;
+        try {
+            // 解绑成功通知
+            const templateId = template;
+            const url = this.ctx.request.header.host + '/wx/url2wap?project=' + data.code + '&url=' + data.wap_url;
+            for (const openid of wx_openid) {
+                if (template === wxConst.template.stage) {
+                    const msgData = {
+                        first: {
+                            value: '您好,本期计量' + data.tips,
+                        },
+                        keyword1: {
+                            value: data.projectName,
+                        },
+                        keyword2: {
+                            value: data.tenderName,
+                        },
+                        keyword3: {
+                            value: '第' + data.qi + '期',
+                        },
+                        keyword4: {
+                            value: data.status,
+                        },
+                        remark: {
+                            value: '查看审批详情,请登录PC端系统。',
+                        },
+                    };
+                    await this.ctx.app.wechat.api.sendTemplate(openid, templateId, url, '', msgData);
+                }
+            }
+            flag = true;
+        } catch (e) {
+            console.log(e);
+            flag = false;
+        }
+        return flag;
+    }
+
+    /**
+     * 关键字转换,并限制20个字以内
+     *
+     * @param {String} content - 内容
+     * @return {Object} - 解析结果
+     */
+    async contentChange(content) {
+        let str = content.replace(/【/g, '(');
+        str = str.replace(/】/g, ')');
+        str = str.replace(/工程款/g, '***');
+        str = str.length > 20 ? str.substring(0, 17) + '...' : str;
+        return str;
+    }
+}
+
+module.exports = WX;

+ 3 - 2
app/middleware/wechat_auth.js

@@ -11,12 +11,13 @@ module.exports = (options, app) => {
         try {
             // 判断session
             if (!ctx.session.wechatToken && ctx.query.code) {
-                const token = await app.wechat.oauth.getAccessToken(ctx.query.code);
+                const token = await ctx.app.wechat.oauth.getAccessToken(ctx.query.code);
                 ctx.session.wechatToken = token.data;
             }
             const wechatToken = ctx.session.wechatToken;
             if (!wechatToken) {
-                ctx.redirect('/wx/oauth?redirect_uri=' + encodeURIComponent(ctx.request.headers.referer));
+                ctx.redirect('/wx/oauth?redirect_uri=' + encodeURIComponent(ctx.request.header.host + ctx.request.url));
+                return;
             }
             // 同步系统维护信息
             await ctx.service.maintain.syncMaintainData();

+ 61 - 0
app/public/css/main.css

@@ -61,6 +61,30 @@ font-size: .875rem;
 }
 .bs-popover-auto[x-placement^="bottom"] .arrow::after, .bs-popover-bottom .arrow::after{
   border-bottom-color:#000;
+}/*
+.btn.disabled, .btn:disabled {
+  opacity:.4
+}*/
+.btn-primary.disabled, .btn-primary:disabled {
+  color:#fff;
+  border-color:#666;
+  background: #666
+}
+.btn-outline-primary.disabled, .btn-outline-primary:disabled {
+  color:#666;
+  border-color:#666;
+  background: #ddd
+}
+.btn-outline-primary.disabled .badge, .btn-outline-primary:disabled .badge{
+  background: #999
+}
+.group-tab .btn-light{
+  color:#007bff;
+  border-color:#d3d9df;
+  cursor: pointer;
+}
+.group-tab .btn-light.active{
+  cursor: default;
 }
 /*在谷歌下移除input[number]的上下箭头*/
 input.nospin[type='number']::-webkit-outer-spin-button,
@@ -1057,4 +1081,41 @@ a.maintain-icon .fa{
 
 a.maintain-icon:hover .fa{ 
     animation-iteration-count:0
+}
+/*审批列表*/
+.timeline-list .timeline-list-item{
+  position: relative;
+}
+.timeline-list-item .timeline-item-date{
+  width:50px;
+  position:absolute;
+  left:0px;
+  text-align: center;
+  color:#ccc;
+}
+.timeline-list-item .timeline-item-date span{
+  display: block;
+  color: #333;
+  text-align: center;
+}
+.timeline-list-item .timeline-item-tail{
+  position: absolute;
+  top: 10px;
+  left: 55px;
+  height: calc(100% - 10px);
+  border-left: 1px solid #ddd ;
+}
+.timeline-list-item .timeline-item-icon{
+  width:20px;
+  height:20px;
+  position: absolute;
+  border-radius: 100px;
+  text-align: center;
+  line-height: 20px;
+  left:45px;
+}
+.timeline-list-item .timeline-item-content{
+  position: relative;
+  margin: 0 0 0 70px;
+  word-break: break-word;
 }

+ 106 - 0
app/public/js/advance_audit.js

@@ -0,0 +1,106 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author lanjianrong
+ * @date 2020/8/7
+ * @version
+ */
+
+$(document).ready(function () {
+    // 获取审核相关url
+    function getUrlPre () {
+        const path = window.location.pathname.split('/');
+        return _.take(path, 3).join('/');
+    }
+    // 审批人分组选择
+    $('#account_group').change(function () {
+        let account_html = '<option value="0">选择审批人</option>'
+        for (const account of accountList) {
+            if ((parseInt($(this).val()) === 0 || parseInt($(this).val()) === account.account_group) && account.id !== parseInt(userID)) {
+                const role = account.role !== '' ? '(' + account.role + ')' : ''
+                const company = account.company !== '' ? ' -' + account.company : ''
+                account_html += '<option value="' + account.id + '">' + account.name + role + company + '</option>'
+            }
+        }
+        $('#account_list').html(account_html)
+    });
+    // 添加到审批流程中
+    $('body').on('change', '#account_list', function () {
+        let id = $(this).val()
+        id = parseInt(id)
+        if (id !== 0) {
+            postData(getUrlPre() + '/audit/add', { auditorId: id }, (data) => {
+                const html = []
+                html.push('<li class="list-group-item" auditorId="'+ data.aid +'"><a href="javascript: void(0)" class="text-danger pull-right">移除</a>')
+                html.push('<span>')
+                html.push(data.order + ' ')
+                html.push(data.name + ' ')
+                html.push('</span>')
+                html.push('<small class="text-muted">')
+                html.push(data.role)
+                html.push('</small></li>')
+                $('#auditors').append(html.join(''))
+
+                // 如果是重新上报,添加到重新上报列表中
+                const auditorshtml = []
+                // 重新上报时。令其它的审批人流程图标转换
+                $('#auditors-list li i').removeClass('fa-stop-circle').addClass('fa-chevron-circle-down')
+                for (let i = 0; i < $('#auditors-list li').length; i++) {
+                    $('#auditors-list li').eq(i).find('.pull-right').text(transFormToChinese(i+1) + '审')
+                    $('#auditors-list2 li').eq(i).find('.pull-right').text(transFormToChinese(i+1) + '审')
+                }
+                // 添加新审批人
+                auditorshtml.push('<li class="list-group-item" data-auditid="' + data.aid + '">')
+                auditorshtml.push('<i class="fa fa-stop-circle"></i> ')
+                auditorshtml.push(data.name + ' <small class="text-muted">' + data.role + '</small>')
+                auditorshtml.push('<span class="pull-right">终审</span>')
+                auditorshtml.push('</li>')
+                $('#auditors-list').append(auditorshtml.join(''))
+
+                const auditorshtml2 = [];
+                // 重新上报时。令其它的审批人流程图标转换
+                $('#auditors-list2 li i').removeClass('fa-stop-circle').addClass('fa-chevron-circle-down')
+                // 添加新审批人
+                auditorshtml2.push('<li class="list-group-item" data-auditid="' + data.aid + '">')
+                auditorshtml2.push('<h5 class="card-title"><i class="fa fa-stop-circle"></i> ')
+                auditorshtml2.push(data.name + ' <small class="text-muted">' + data.role + '</small>')
+                auditorshtml2.push('<span class="pull-right">终审</span>')
+                auditorshtml2.push('</h5></li>');
+                $('#auditors-list2').append(auditorshtml2.join(''))
+            });
+        }
+    });
+    // 删除审批人
+    $('body').on('click', '#auditors li>a', function () {
+        const li = $(this).parent()
+        const data = {
+            auditorId: parseInt(li.attr('auditorId')),
+        };
+        postData(getUrlPre() + '/audit/delete', data, (result) => {
+            li.remove();
+            for (const rst of result) {
+                const aLi = $('li[auditorId=' + rst.aid + ']');
+                $('span', aLi).text(rst.order + ' ' + rst.name + ' ')
+            }
+
+            // 如果是重新上报
+            // 令最后一个图标转换
+            $('#auditors-list li[data-auditid="' + data.auditorId + '"]').remove()
+            if ($('#auditors-list li').length !== 0 && !$('#auditors-list li i').hasClass('fa-stop-circle')) {
+                $('#auditors-list li').eq($('#auditors-list li').length-1).children('i')
+                    .removeClass('fa-chevron-circle-down').addClass('fa-stop-circle')
+            }
+            $('#auditors-list2 li[data-auditid="' + data.auditorId + '"]').remove();
+            if ($('#auditors-list2 li').length !== 0 && !$('#auditors-list2 li i').hasClass('fa-stop-circle')) {
+                $('#auditors-list2 li').eq($('#auditors-list2 li').length-1).children('i')
+                    .removeClass('fa-chevron-circle-down').addClass('fa-stop-circle')
+            }
+            for (let i = 0; i < $('#auditors-list li').length; i++) {
+                $('#auditors-list li').eq(i).find('.pull-right').text((i+1 === $('#auditors-list li').length ? '终' : transFormToChinese(i+1)) + '审')
+                $('#auditors-list2 li').eq(i).find('.pull-right').text((i+1 === $('#auditors-list2 li').length ? '终' : transFormToChinese(i+1)) + '审')
+            }
+        })
+    })
+})

+ 281 - 256
app/router.js

@@ -1,47 +1,46 @@
-'use strict';
+'use strict'
 
 module.exports = app => {
-
     // session验证中间件
-    const sessionAuth = app.middlewares.sessionAuth();
+    const sessionAuth = app.middlewares.sessionAuth()
     // 创建时间自动填充中间件
-    const datetimeFill = app.middlewares.datetimeFill();
+    const datetimeFill = app.middlewares.datetimeFill()
     // 项目管理员判断中间件
-    const projectManagerCheck = app.middlewares.projectManagerCheck();
+    const projectManagerCheck = app.middlewares.projectManagerCheck()
     // 标段读取中间件
-    const tenderCheck = app.middlewares.tenderCheck();
+    const tenderCheck = app.middlewares.tenderCheck()
     // 期读取中间件
-    const stageCheck = app.middlewares.stageCheck();
+    const stageCheck = app.middlewares.stageCheck()
     // 材料调差读取中间件
-    const materialCheck = app.middlewares.materialCheck();
+    const materialCheck = app.middlewares.materialCheck()
     // 第三方接口认证判断中间件
-    const api2otherCheck = app.middlewares.api2otherCheck();
+    const api2otherCheck = app.middlewares.api2otherCheck()
     // 微信验证登录中间件
-    const wechatAuth = app.middlewares.wechatAuth();
+    const wechatAuth = app.middlewares.wechatAuth()
 
     // 登入登出相关
-    app.get('/login', 'loginController.index');
-    app.get('/login/port', api2otherCheck, 'loginController.port');
-    app.get('/', 'loginController.index');
-    app.get('/logout', 'loginController.logout');
-    app.post('/login', 'loginController.login');
-    app.post('/login/port', 'loginController.loginPort');
-    app.get('/project/name', 'loginController.projectName');
-
-    app.get('/sign', 'signController.index');
-    app.post('/sign/save', 'signController.save');
-    app.post('/reset/password', 'loginController.resetPassword');
+    app.get('/login', 'loginController.index')
+    app.get('/login/port', api2otherCheck, 'loginController.port')
+    app.get('/', 'loginController.index')
+    app.get('/logout', 'loginController.logout')
+    app.post('/login', 'loginController.login')
+    app.post('/login/port', 'loginController.loginPort')
+    app.get('/project/name', 'loginController.projectName')
+
+    app.get('/sign', 'signController.index')
+    app.post('/sign/save', 'signController.save')
+    app.post('/reset/password', 'loginController.resetPassword')
 
     // 用户信息初始化相关
-    app.get('/boot', sessionAuth, 'bootController.index');
-    app.post('/boot', sessionAuth, 'bootController.boot');
+    app.get('/boot', sessionAuth, 'bootController.index')
+    app.post('/boot', sessionAuth, 'bootController.boot')
 
     // 控制面板相关
-    app.get('/dashboard', sessionAuth, 'dashboardController.index');
-    app.get('/dashboard/msg/list', sessionAuth, 'dashboardController.msgList');
-    app.get('/dashboard/msg/add/:id', sessionAuth, 'dashboardController.msgAdd');
-    app.post('/dashboard/msg/set/:id', sessionAuth, datetimeFill, 'dashboardController.msgSet');
-    app.get('/dashboard/msg/del/:id', sessionAuth, 'dashboardController.msgDelete');
+    app.get('/dashboard', sessionAuth, 'dashboardController.index')
+    app.get('/dashboard/msg/list', sessionAuth, 'dashboardController.msgList')
+    app.get('/dashboard/msg/add/:id', sessionAuth, 'dashboardController.msgAdd')
+    app.post('/dashboard/msg/set/:id', sessionAuth, datetimeFill, 'dashboardController.msgSet')
+    app.get('/dashboard/msg/del/:id', sessionAuth, 'dashboardController.msgDelete')
 
     // 推送相关
     // app.post('/dashboard/push', sessionAuth, 'dashboardController.pushSet');
@@ -49,312 +48,338 @@ module.exports = app => {
      * 项目设置
      */
     // 项目信息
-    app.get('/setting/info', sessionAuth, 'settingController.info');
-    app.post('/setting/updateinfo/:id', sessionAuth, 'settingController.updateinfo');
+    app.get('/setting/info', sessionAuth, 'settingController.info')
+    app.post('/setting/updateinfo/:id', sessionAuth, 'settingController.updateinfo')
     // 账号设置
-    app.get('/setting/user', sessionAuth, 'settingController.user');
-    app.get('/setting/user/permission/set', sessionAuth, 'settingController.userPermissionSet');
+    app.get('/setting/user', sessionAuth, 'settingController.user')
+    app.get('/setting/user/permission/set', sessionAuth, 'settingController.userPermissionSet')
     // 账号停用和启用
-    app.post('/setting/user/switch', sessionAuth, 'settingController.userSwitch');
-    app.post('/setting/user/add', sessionAuth, datetimeFill, 'settingController.addUser');
-    app.post('/setting/user/update', sessionAuth, 'settingController.updateUser');
-    app.post('/setting/user/permission', sessionAuth, 'settingController.permission');
-    app.post('/setting/user/reset/password', sessionAuth, 'settingController.resetUserPassword');
-    app.post('/setting/user/exist', sessionAuth, 'settingController.accountExist');
-    app.post('/setting/user/unbind', sessionAuth, 'settingController.userUnbind');
+    app.post('/setting/user/switch', sessionAuth, 'settingController.userSwitch')
+    app.post('/setting/user/add', sessionAuth, datetimeFill, 'settingController.addUser')
+    app.post('/setting/user/update', sessionAuth, 'settingController.updateUser')
+    app.post('/setting/user/permission', sessionAuth, 'settingController.permission')
+    app.post('/setting/user/reset/password', sessionAuth, 'settingController.resetUserPassword')
+    app.post('/setting/user/exist', sessionAuth, 'settingController.accountExist')
+    app.post('/setting/user/unbind', sessionAuth, 'settingController.userUnbind')
 
     // 显示设置
-    app.get('/setting/show', sessionAuth, 'settingController.show');
-    app.post('/setting/show/update', sessionAuth, 'settingController.showListUpdate');
+    app.get('/setting/show', sessionAuth, 'settingController.show')
+    app.post('/setting/show/update', sessionAuth, 'settingController.showListUpdate')
 
     // 标段自定义类别
-    app.get('/setting/category', sessionAuth, 'settingController.category');
-    app.post('/setting/category/add', sessionAuth, 'settingController.addCategory');
-    app.post('/setting/category/del', sessionAuth, 'settingController.deleteCategory');
-    app.post('/setting/category/update', sessionAuth, 'settingController.updateCategory');
-    app.post('/setting/category/value', sessionAuth, 'settingController.setCategoryValue');
-    app.post('/setting/category/level', sessionAuth, 'settingController.resetCategoryLevel');
+    app.get('/setting/category', sessionAuth, 'settingController.category')
+    app.post('/setting/category/add', sessionAuth, 'settingController.addCategory')
+    app.post('/setting/category/del', sessionAuth, 'settingController.deleteCategory')
+    app.post('/setting/category/update', sessionAuth, 'settingController.updateCategory')
+    app.post('/setting/category/value', sessionAuth, 'settingController.setCategoryValue')
+    app.post('/setting/category/level', sessionAuth, 'settingController.resetCategoryLevel')
 
     // 项目相关
-    app.get('/project/info', sessionAuth, 'projectController.info');
-    app.get('/project/account', sessionAuth, projectManagerCheck, 'accountController.index');
-    app.post('/project/account/permission/:accountId', sessionAuth, projectManagerCheck, 'accountController.savePermission');
-    app.get('/project/account/enable/:accountId', sessionAuth, projectManagerCheck, 'accountController.enable');
-    app.get('/project/account/disable/:accountId', sessionAuth, projectManagerCheck, 'accountController.enable');
-    app.get('/project/switch/:projectId', sessionAuth, projectManagerCheck, 'projectController.switchProject');
-    app.post('/project/info', sessionAuth, 'projectController.saveInfo');
+    app.get('/project/info', sessionAuth, 'projectController.info')
+    app.get('/project/account', sessionAuth, projectManagerCheck, 'accountController.index')
+    app.post('/project/account/permission/:accountId', sessionAuth, projectManagerCheck, 'accountController.savePermission')
+    app.get('/project/account/enable/:accountId', sessionAuth, projectManagerCheck, 'accountController.enable')
+    app.get('/project/account/disable/:accountId', sessionAuth, projectManagerCheck, 'accountController.enable')
+    app.get('/project/switch/:projectId', sessionAuth, projectManagerCheck, 'projectController.switchProject')
+    app.post('/project/info', sessionAuth, 'projectController.saveInfo')
 
     /**
      * 标段管理
      */
     // 金额概况
-    app.get('/list', sessionAuth, 'tenderController.listDefault');
-    app.get('/list/info', sessionAuth, 'tenderController.listInfo');
+    app.get('/list', sessionAuth, 'tenderController.listDefault')
+    app.get('/list/info', sessionAuth, 'tenderController.listInfo')
+
     // 计量进度
-    app.get('/list/progress', sessionAuth, 'tenderController.listProgress');
+    app.get('/list/progress', sessionAuth, 'tenderController.listProgress')
+
     // 管理标段
-    app.get('/list/manage', sessionAuth, 'tenderController.listManage');
-    app.post('/list/add', sessionAuth, 'tenderController.addTender');
-    app.post('/list/update', sessionAuth, 'tenderController.updateTender');
-    app.post('/list/del', sessionAuth, 'tenderController.deleteTender');
+    app.get('/list/manage', sessionAuth, 'tenderController.listManage')
+    app.post('/list/add', sessionAuth, 'tenderController.addTender')
+    app.post('/list/update', sessionAuth, 'tenderController.updateTender')
+    app.post('/list/del', sessionAuth, 'tenderController.deleteTender')
 
     // 标段概况
-    app.get('/tender/:id', sessionAuth, tenderCheck, 'tenderController.tenderInfo');
-    app.get('/tender/:id/type', sessionAuth, 'tenderController.tenderType');
-    app.post('/tender/:id/save', sessionAuth, tenderCheck, 'tenderController.saveTenderInfo');
-    app.post('/tender/rule', sessionAuth, 'tenderController.rule');
-    app.post('/tender/:id/rule/first', sessionAuth, tenderCheck, 'tenderController.ruleFirst');
+    app.get('/tender/:id', sessionAuth, tenderCheck, 'tenderController.tenderInfo')
+    app.get('/tender/:id/type', sessionAuth, 'tenderController.tenderType')
+    app.post('/tender/:id/save', sessionAuth, tenderCheck, 'tenderController.saveTenderInfo')
+    app.post('/tender/rule', sessionAuth, 'tenderController.rule')
+    app.post('/tender/:id/rule/first', sessionAuth, tenderCheck, 'tenderController.ruleFirst')
+
+    // 预付款
+    app.get('/tender/:id/advance', sessionAuth, tenderCheck, 'advanceController.index')
+    app.get('/tender/:id/advance/material', sessionAuth, tenderCheck, 'advanceController.materialInfo')
+    app.get('/tender/:id/advance/:order/detail', sessionAuth, tenderCheck, 'advanceController.detail')
+    app.get('/tender/:id/advance/:type/create', sessionAuth, tenderCheck, 'advanceController.createInfo')
+    // app.post('/tender/:id/advance/:type/start', sessionAuth, tenderCheck, 'advanceController.start')
     // 标段协作办公
-    app.get('/tender/:id/cooperation', sessionAuth, tenderCheck, 'tenderController.tenderCooperation');
+    app.get('/tender/:id/cooperation', sessionAuth, tenderCheck, 'tenderController.tenderCooperation')
 
     // 台账管理相关
-    app.get('/tender/:id/ledger', sessionAuth, tenderCheck, 'ledgerController.explode');
-    app.post('/tender/:id/ledger/load', sessionAuth, tenderCheck, 'ledgerController.loadExplodeData');
-    app.post('/tender/:id/ledger/get-children', sessionAuth, tenderCheck, 'ledgerController.getChildren');
-    app.post('/tender/:id/ledger/update', sessionAuth, tenderCheck, 'ledgerController.update');
-    app.post('/tender/:id/ledger/upload-excel/:ueType', sessionAuth, tenderCheck, 'ledgerController.uploadExcel');
-    app.get('/tender/:id/ledger/download/:file', sessionAuth, tenderCheck, 'ledgerController.download');
-    app.post('/tender/:id/pos/update', sessionAuth, tenderCheck, 'ledgerController.posUpdate');
-    app.post('/tender/:id/pos/paste', sessionAuth, tenderCheck, 'ledgerController.posPaste');
-    app.post('/tender/:id/ledger/deal2sgfh', sessionAuth, tenderCheck, 'ledgerController.deal2sgfh');
-    app.post('/tender/:id/ledger/check', sessionAuth, tenderCheck, 'ledgerController.check');
+    app.get('/tender/:id/ledger', sessionAuth, tenderCheck, 'ledgerController.explode')
+    app.post('/tender/:id/ledger/load', sessionAuth, tenderCheck, 'ledgerController.loadExplodeData')
+    app.post('/tender/:id/ledger/get-children', sessionAuth, tenderCheck, 'ledgerController.getChildren')
+    app.post('/tender/:id/ledger/update', sessionAuth, tenderCheck, 'ledgerController.update')
+    app.post('/tender/:id/ledger/upload-excel/:ueType', sessionAuth, tenderCheck, 'ledgerController.uploadExcel')
+    app.get('/tender/:id/ledger/download/:file', sessionAuth, tenderCheck, 'ledgerController.download')
+    app.post('/tender/:id/pos/update', sessionAuth, tenderCheck, 'ledgerController.posUpdate')
+    app.post('/tender/:id/pos/paste', sessionAuth, tenderCheck, 'ledgerController.posPaste')
+    app.post('/tender/:id/ledger/deal2sgfh', sessionAuth, tenderCheck, 'ledgerController.deal2sgfh')
+    app.post('/tender/:id/ledger/check', sessionAuth, tenderCheck, 'ledgerController.check')
+
     // 台账审批相关
-    app.get('/tender/:id/ledger/audit', sessionAuth, tenderCheck, 'ledgerAuditController.index');
-    app.post('/tender/:id/ledger/audit/add', sessionAuth, tenderCheck, 'ledgerAuditController.add');
-    app.post('/tender/:id/ledger/audit/delete', sessionAuth, tenderCheck, 'ledgerAuditController.remove');
-    app.post('/tender/:id/ledger/audit/start', sessionAuth, tenderCheck, 'ledgerAuditController.start');
-    app.post('/tender/:id/ledger/audit/check', sessionAuth, tenderCheck, 'ledgerAuditController.check');
+    app.get('/tender/:id/ledger/audit', sessionAuth, tenderCheck, 'ledgerAuditController.index')
+    app.post('/tender/:id/ledger/audit/add', sessionAuth, tenderCheck, 'ledgerAuditController.add')
+    app.post('/tender/:id/ledger/audit/delete', sessionAuth, tenderCheck, 'ledgerAuditController.remove')
+    app.post('/tender/:id/ledger/audit/start', sessionAuth, tenderCheck, 'ledgerAuditController.start')
+    app.post('/tender/:id/ledger/audit/check', sessionAuth, tenderCheck, 'ledgerAuditController.check')
 
     // 部位台账
-    app.get('/tender/:id/ledger/bwtz', sessionAuth, tenderCheck, 'ledgerController.bwtz');
-    app.post('/tender/:id/ledger/bwtz/load', sessionAuth, tenderCheck, 'ledgerController.loadBwtz');
+    app.get('/tender/:id/ledger/bwtz', sessionAuth, tenderCheck, 'ledgerController.bwtz')
+    app.post('/tender/:id/ledger/bwtz/load', sessionAuth, tenderCheck, 'ledgerController.loadBwtz')
 
     // 台账对比
-    app.get('/tender/:id/ledger/gather', sessionAuth, tenderCheck, 'ledgerController.gather');
-    app.post('/tender/:id/ledger/gather/load', sessionAuth, tenderCheck, 'ledgerController.loadGatherData');
+    app.get('/tender/:id/ledger/gather', sessionAuth, tenderCheck, 'ledgerController.gather')
+    app.post('/tender/:id/ledger/gather/load', sessionAuth, tenderCheck, 'ledgerController.loadGatherData')
 
     // 台账修订
-    app.get('/tender/:id/revise', sessionAuth, tenderCheck, 'reviseController.index');
-    app.post('/tender/:id/revise/add', sessionAuth, tenderCheck, 'reviseController.add');
-    app.post('/tender/:id/revise/cancel', sessionAuth, tenderCheck, 'reviseController.cancel');
-    app.post('/tender/:id/revise/save', sessionAuth, tenderCheck, 'reviseController.save');
+    app.get('/tender/:id/revise', sessionAuth, tenderCheck, 'reviseController.index')
+    app.post('/tender/:id/revise/add', sessionAuth, tenderCheck, 'reviseController.add')
+    app.post('/tender/:id/revise/cancel', sessionAuth, tenderCheck, 'reviseController.cancel')
+    app.post('/tender/:id/revise/save', sessionAuth, tenderCheck, 'reviseController.save')
     // app.post('/tender/:id/revise/deal2sgfh', sessionAuth, tenderCheck, 'reviseController.deal2sgfh');
+
     // 台账修订页面
-    app.get('/tender/:id/revise/info', sessionAuth, tenderCheck, 'reviseController.info');
-    app.post('/tender/:id/revise/auditors', sessionAuth, tenderCheck, 'reviseController.reviseAuditors');
-    app.post('/tender/:id/revise/info/load', sessionAuth, tenderCheck, 'reviseController.loadInfoData');
-    app.post('/tender/:id/revise/info/update', sessionAuth, tenderCheck, 'reviseController.update');
-    app.post('/tender/:id/revise/info/upload-excel/:ueType', sessionAuth, tenderCheck, 'reviseController.uploadExcel');
-    app.post('/tender/:id/revise/info/check', sessionAuth, tenderCheck, 'reviseController.checkData');
+    app.get('/tender/:id/revise/info', sessionAuth, tenderCheck, 'reviseController.info')
+    app.post('/tender/:id/revise/auditors', sessionAuth, tenderCheck, 'reviseController.reviseAuditors')
+    app.post('/tender/:id/revise/info/load', sessionAuth, tenderCheck, 'reviseController.loadInfoData')
+    app.post('/tender/:id/revise/info/update', sessionAuth, tenderCheck, 'reviseController.update')
+    app.post('/tender/:id/revise/info/upload-excel/:ueType', sessionAuth, tenderCheck, 'reviseController.uploadExcel')
+    app.post('/tender/:id/revise/info/check', sessionAuth, tenderCheck, 'reviseController.checkData')
+
     // 查看修订数据
-    app.get('/tender/:id/revise/history', sessionAuth, tenderCheck, 'reviseController.history');
-    app.post('/tender/:id/revise/history/load', sessionAuth, tenderCheck, 'reviseController.loadHistoryData');
-    app.post('/tender/:id/revise/history/info', sessionAuth, tenderCheck, 'reviseController.historyInfo');
+    app.get('/tender/:id/revise/history', sessionAuth, tenderCheck, 'reviseController.history')
+    app.post('/tender/:id/revise/history/load', sessionAuth, tenderCheck, 'reviseController.loadHistoryData')
+    app.post('/tender/:id/revise/history/info', sessionAuth, tenderCheck, 'reviseController.historyInfo')
+
     // 修订审批
-    app.post('/tender/:id/revise/audit/add', sessionAuth, tenderCheck, 'reviseController.addAuditor');
-    app.post('/tender/:id/revise/audit/remove', sessionAuth, tenderCheck, 'reviseController.removeAuditor');
-    app.post('/tender/:id/revise/audit/start', sessionAuth, tenderCheck, 'reviseController.start');
-    app.post('/tender/:id/revise/audit/check', sessionAuth, tenderCheck, 'reviseController.check');
+    app.post('/tender/:id/revise/audit/add', sessionAuth, tenderCheck, 'reviseController.addAuditor')
+    app.post('/tender/:id/revise/audit/remove', sessionAuth, tenderCheck, 'reviseController.removeAuditor')
+    app.post('/tender/:id/revise/audit/start', sessionAuth, tenderCheck, 'reviseController.start')
+    app.post('/tender/:id/revise/audit/check', sessionAuth, tenderCheck, 'reviseController.check')
 
     // 签约清单
-    app.post('/tender/:id/deal/get-data', sessionAuth, tenderCheck, 'dealBillsController.getData');
-    app.post('/tender/:id/deal/upload-excel', sessionAuth, tenderCheck, 'dealBillsController.loadExcel');
-    app.get('/tender/:id/deal/download/:file', sessionAuth, tenderCheck, 'dealBillsController.download');
+    app.post('/tender/:id/deal/get-data', sessionAuth, tenderCheck, 'dealBillsController.getData')
+    app.post('/tender/:id/deal/upload-excel', sessionAuth, tenderCheck, 'dealBillsController.loadExcel')
+    app.get('/tender/:id/deal/download/:file', sessionAuth, tenderCheck, 'dealBillsController.download')
 
     // 计量台账
     // 期计量
-    app.get('/tender/:id/measure/stage', sessionAuth, tenderCheck, 'measureController.stage');
-    app.post('/tender/:id/measure/stage/auditors', sessionAuth, tenderCheck, 'measureController.stageAuditors');
-    app.post('/tender/:id/measure/add', sessionAuth, tenderCheck, 'measureController.add');
-    app.post('/tender/:id/measure/save', sessionAuth, tenderCheck, 'measureController.save');
-    app.post('/tender/:id/measure/stage/delete', sessionAuth, tenderCheck, 'measureController.delete');
+    app.get('/tender/:id/measure/stage', sessionAuth, tenderCheck, 'measureController.stage')
+    app.post('/tender/:id/measure/stage/auditors', sessionAuth, tenderCheck, 'measureController.stageAuditors')
+    app.post('/tender/:id/measure/add', sessionAuth, tenderCheck, 'measureController.add')
+    app.post('/tender/:id/measure/save', sessionAuth, tenderCheck, 'measureController.save')
+    app.post('/tender/:id/measure/stage/delete', sessionAuth, tenderCheck, 'measureController.delete')
+
     // 计量台账 -- 清单汇总
-    app.get('/tender/:id/measure/gather', sessionAuth, tenderCheck, 'measureController.gather');
+    app.get('/tender/:id/measure/gather', sessionAuth, tenderCheck, 'measureController.gather')
+
     // 计量台账 -- 审核比较
-    app.get('/tender/:id/measure/compare', sessionAuth, tenderCheck, 'measureController.compare');
-    app.post('/tender/:id/measure/compare/load', sessionAuth, tenderCheck, 'measureController.loadCompareData');
+    app.get('/tender/:id/measure/compare', sessionAuth, tenderCheck, 'measureController.compare')
+    app.post('/tender/:id/measure/compare/load', sessionAuth, tenderCheck, 'measureController.loadCompareData')
 
     // 期计量详细
     // 本期计量台账
-    app.get('/tender/:id/measure/stage/:order', sessionAuth, tenderCheck, stageCheck, 'stageController.index');
-    app.post('/tender/:id/measure/stage/:order/load', sessionAuth, tenderCheck, stageCheck, 'stageController.getStageData');
-    app.post('/tender/:id/measure/stage/:order/pos', sessionAuth, tenderCheck, stageCheck, 'stageController.getStagePosData');
-    app.post('/tender/:id/measure/stage/:order/update', sessionAuth, tenderCheck, stageCheck, 'stageController.updateStageData');
-    app.post('/tender/:id/measure/stage/:order/valid-change', sessionAuth, tenderCheck, stageCheck, 'stageController.searchValidChange');
-    app.post('/tender/:id/measure/stage/:order/use-change', sessionAuth, tenderCheck, stageCheck, 'stageController.useChange');
-    app.post('/tender/:id/measure/stage/:order/check', sessionAuth, tenderCheck, stageCheck, 'stageController.check');
+    app.get('/tender/:id/measure/stage/:order', sessionAuth, tenderCheck, stageCheck, 'stageController.index')
+    app.post('/tender/:id/measure/stage/:order/load', sessionAuth, tenderCheck, stageCheck, 'stageController.getStageData')
+    app.post('/tender/:id/measure/stage/:order/pos', sessionAuth, tenderCheck, stageCheck, 'stageController.getStagePosData')
+    app.post('/tender/:id/measure/stage/:order/update', sessionAuth, tenderCheck, stageCheck, 'stageController.updateStageData')
+    app.post('/tender/:id/measure/stage/:order/valid-change', sessionAuth, tenderCheck, stageCheck, 'stageController.searchValidChange')
+    app.post('/tender/:id/measure/stage/:order/use-change', sessionAuth, tenderCheck, stageCheck, 'stageController.useChange')
+    app.post('/tender/:id/measure/stage/:order/check', sessionAuth, tenderCheck, stageCheck, 'stageController.check')
+
     // 计量附件
-    app.post('/tender/:id/measure/stage/:order/upload/file', sessionAuth, tenderCheck, stageCheck, 'stageController.uploadFile');
-    app.get('/tender/:id/measure/stage/:order/download/file/:fid', sessionAuth, 'stageController.downloadFile');
-    app.post('/tender/:id/measure/stage/:order/delete/file', sessionAuth, tenderCheck, stageCheck, 'stageController.deleteFile');
-    app.post('/tender/:id/measure/stage/:order/save/file', sessionAuth, tenderCheck, stageCheck, 'stageController.saveFile');
-    app.post('/tender/:id/measure/stage/:order/check/file', sessionAuth, tenderCheck, stageCheck, 'stageController.checkFile');
+    app.post('/tender/:id/measure/stage/:order/upload/file', sessionAuth, tenderCheck, stageCheck, 'stageController.uploadFile')
+    app.get('/tender/:id/measure/stage/:order/download/file/:fid', sessionAuth, 'stageController.downloadFile')
+    app.post('/tender/:id/measure/stage/:order/delete/file', sessionAuth, tenderCheck, stageCheck, 'stageController.deleteFile')
+    app.post('/tender/:id/measure/stage/:order/save/file', sessionAuth, tenderCheck, stageCheck, 'stageController.saveFile')
+    app.post('/tender/:id/measure/stage/:order/check/file', sessionAuth, tenderCheck, stageCheck, 'stageController.checkFile')
+
     // 中间计量
-    app.get('/tender/:id/measure/stage/:order/detail', sessionAuth, tenderCheck, stageCheck, 'stageController.detail');
-    app.post('/tender/:id/measure/stage/:order/detail/build', sessionAuth, tenderCheck, stageCheck, 'stageController.buildDetailData');
-    app.post('/tender/:id/measure/stage/:order/detail/adv', sessionAuth, tenderCheck, stageCheck, 'stageController.setAdvancedConfig');
-    app.post('/tender/:id/measure/stage/:order/detail/load', sessionAuth, tenderCheck, stageCheck, 'stageController.loadDetailRelaData');
-    app.post('/tender/:id/measure/stage/:order/detail/save', sessionAuth, tenderCheck, stageCheck, 'stageController.saveDetailData');
-    app.post('/tender/:id/measure/stage/:order/detail/add-img', sessionAuth, tenderCheck, stageCheck, 'stageController.addCalcImage');
-    app.post('/tender/:id/measure/stage/:order/detail/merge-img', sessionAuth, tenderCheck, stageCheck, 'stageController.mergeCalcImage');
+    app.get('/tender/:id/measure/stage/:order/detail', sessionAuth, tenderCheck, stageCheck, 'stageController.detail')
+    app.post('/tender/:id/measure/stage/:order/detail/build', sessionAuth, tenderCheck, stageCheck, 'stageController.buildDetailData')
+    app.post('/tender/:id/measure/stage/:order/detail/adv', sessionAuth, tenderCheck, stageCheck, 'stageController.setAdvancedConfig')
+    app.post('/tender/:id/measure/stage/:order/detail/load', sessionAuth, tenderCheck, stageCheck, 'stageController.loadDetailRelaData')
+    app.post('/tender/:id/measure/stage/:order/detail/save', sessionAuth, tenderCheck, stageCheck, 'stageController.saveDetailData')
+    app.post('/tender/:id/measure/stage/:order/detail/add-img', sessionAuth, tenderCheck, stageCheck, 'stageController.addCalcImage')
+    app.post('/tender/:id/measure/stage/:order/detail/merge-img', sessionAuth, tenderCheck, stageCheck, 'stageController.mergeCalcImage')
+
     // 合同支付
-    app.get('/tender/:id/measure/stage/:order/pay', sessionAuth, tenderCheck, stageCheck, 'stageController.pay');
-    app.post('/tender/:id/measure/stage/:order/pay/detail', sessionAuth, tenderCheck, stageCheck, 'stageController.chapterDetail');
-    app.post('/tender/:id/measure/stage/:order/pay/save', sessionAuth, tenderCheck, stageCheck, 'stageController.savePayData');
-    app.post('/tender/:id/measure/stage/:order/pay/upload/file', sessionAuth, tenderCheck, stageCheck, 'stageController.payUploadFile');
-    app.get('/tender/:id/measure/stage/:order/pay/download/file/:pid/:index', sessionAuth, 'stageController.payDownloadFile');
-    app.post('/tender/:id/measure/stage/:order/pay/delete/file', sessionAuth, tenderCheck, stageCheck, 'stageController.payDeleteFile');
+    app.get('/tender/:id/measure/stage/:order/pay', sessionAuth, tenderCheck, stageCheck, 'stageController.pay')
+    app.post('/tender/:id/measure/stage/:order/pay/detail', sessionAuth, tenderCheck, stageCheck, 'stageController.chapterDetail')
+    app.post('/tender/:id/measure/stage/:order/pay/save', sessionAuth, tenderCheck, stageCheck, 'stageController.savePayData')
+    app.post('/tender/:id/measure/stage/:order/pay/upload/file', sessionAuth, tenderCheck, stageCheck, 'stageController.payUploadFile')
+    app.get('/tender/:id/measure/stage/:order/pay/download/file/:pid/:index', sessionAuth, 'stageController.payDownloadFile')
+    app.post('/tender/:id/measure/stage/:order/pay/delete/file', sessionAuth, tenderCheck, stageCheck, 'stageController.payDeleteFile')
+
     // 变更概况
-    app.get('/tender/:id/measure/stage/:order/change', sessionAuth, tenderCheck, stageCheck, 'stageController.change');
-    app.post('/tender/:id/measure/stage/:order/change/data', sessionAuth, tenderCheck, stageCheck, 'stageController.getChangeData');
-    app.post('/tender/:id/measure/stage/:order/change/detail', sessionAuth, tenderCheck, stageCheck, 'stageController.changeDetail');
+    app.get('/tender/:id/measure/stage/:order/change', sessionAuth, tenderCheck, stageCheck, 'stageController.change')
+    app.post('/tender/:id/measure/stage/:order/change/data', sessionAuth, tenderCheck, stageCheck, 'stageController.getChangeData')
+    app.post('/tender/:id/measure/stage/:order/change/detail', sessionAuth, tenderCheck, stageCheck, 'stageController.changeDetail')
+
     // 审批
-    app.post('/tender/:id/measure/stage/:order/audit/add', sessionAuth, tenderCheck, stageCheck, 'stageController.addAudit');
-    app.post('/tender/:id/measure/stage/:order/audit/delete', sessionAuth, tenderCheck, stageCheck, 'stageController.deleteAudit');
-    app.post('/tender/:id/measure/stage/:order/audit/start', sessionAuth, tenderCheck, stageCheck, 'stageController.startAudit');
-    app.post('/tender/:id/measure/stage/:order/audit/check', sessionAuth, tenderCheck, stageCheck, 'stageController.checkAudit');
-    app.get('/tender/:id/measure/stage/:order/audit/check/again', sessionAuth, tenderCheck, stageCheck, 'stageController.checkAuditAgain');
+    app.post('/tender/:id/measure/stage/:order/audit/add', sessionAuth, tenderCheck, stageCheck, 'stageController.addAudit')
+    app.post('/tender/:id/measure/stage/:order/audit/delete', sessionAuth, tenderCheck, stageCheck, 'stageController.deleteAudit')
+    app.post('/tender/:id/measure/stage/:order/audit/start', sessionAuth, tenderCheck, stageCheck, 'stageController.startAudit')
+    app.post('/tender/:id/measure/stage/:order/audit/check', sessionAuth, tenderCheck, stageCheck, 'stageController.checkAudit')
+    app.get('/tender/:id/measure/stage/:order/audit/check/again', sessionAuth, tenderCheck, stageCheck, 'stageController.checkAuditAgain')
+
     // 部位台账
-    app.get('/tender/:id/measure/stage/:order/bwtz', sessionAuth, tenderCheck, stageCheck, 'stageController.bwtz');
-    app.post('/tender/:id/measure/stage/:order/bwtz/load', sessionAuth, tenderCheck, stageCheck, 'stageController.loadBwtz');
+    app.get('/tender/:id/measure/stage/:order/bwtz', sessionAuth, tenderCheck, stageCheck, 'stageController.bwtz')
+    app.post('/tender/:id/measure/stage/:order/bwtz/load', sessionAuth, tenderCheck, stageCheck, 'stageController.loadBwtz')
+
     // 清单汇总
-    app.get('/tender/:id/measure/stage/:order/gather', sessionAuth, tenderCheck, stageCheck, 'stageController.gather');
+    app.get('/tender/:id/measure/stage/:order/gather', sessionAuth, tenderCheck, stageCheck, 'stageController.gather')
+
     // 审核比较
-    app.get('/tender/:id/measure/stage/:order/compare', sessionAuth, tenderCheck, stageCheck, 'stageController.compare');
-    app.post('/tender/:id/measure/stage/:order/compare/load', sessionAuth, tenderCheck, stageCheck, 'stageController.compareAuditor');
+    app.get('/tender/:id/measure/stage/:order/compare', sessionAuth, tenderCheck, stageCheck, 'stageController.compare')
+    app.post('/tender/:id/measure/stage/:order/compare/load', sessionAuth, tenderCheck, stageCheck, 'stageController.compareAuditor')
+
     // 附加功能
-    app.get('/tender/:id/measure/stage/:order/extra/jgcl', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.jgcl');
-    app.post('/tender/:id/measure/stage/:order/extra/jgcl/load', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.loadJgcl');
-    app.post('/tender/:id/measure/stage/:order/extra/jgcl/update', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.updateJgcl');
-    app.get('/tender/:id/measure/stage/:order/extra/bonus', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.bonus');
-    app.post('/tender/:id/measure/stage/:order/extra/bonus/load', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.loadBonus');
-    app.post('/tender/:id/measure/stage/:order/extra/bonus/update', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.updateBonus');
-    app.get('/tender/:id/measure/stage/:order/extra/other', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.other');
-    app.post('/tender/:id/measure/stage/:order/extra/other/load', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.loadOther');
-    app.post('/tender/:id/measure/stage/:order/extra/other/update', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.updateOther');
-    app.post('/tender/:id/measure/stage/:order/extra/upload/file', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.uploadFile');
-    app.get('/tender/:id/measure/stage/:order/extra/download/file', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.downloadFile');
-    app.post('/tender/:id/measure/stage/:order/extra/delete/file', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.deleteFile');
+    app.get('/tender/:id/measure/stage/:order/extra/jgcl', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.jgcl')
+    app.post('/tender/:id/measure/stage/:order/extra/jgcl/load', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.loadJgcl')
+    app.post('/tender/:id/measure/stage/:order/extra/jgcl/update', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.updateJgcl')
+    app.get('/tender/:id/measure/stage/:order/extra/bonus', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.bonus')
+    app.post('/tender/:id/measure/stage/:order/extra/bonus/load', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.loadBonus')
+    app.post('/tender/:id/measure/stage/:order/extra/bonus/update', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.updateBonus')
+    app.get('/tender/:id/measure/stage/:order/extra/other', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.other')
+    app.post('/tender/:id/measure/stage/:order/extra/other/load', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.loadOther')
+    app.post('/tender/:id/measure/stage/:order/extra/other/update', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.updateOther')
+    app.post('/tender/:id/measure/stage/:order/extra/upload/file', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.uploadFile')
+    app.get('/tender/:id/measure/stage/:order/extra/download/file', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.downloadFile')
+    app.post('/tender/:id/measure/stage/:order/extra/delete/file', sessionAuth, tenderCheck, stageCheck, 'stageExtraController.deleteFile')
+
     // 期审批管理
-    app.get('/tender/:id/measure/stage/:order/manager', sessionAuth, tenderCheck, stageCheck, 'stageController.manager');
-    app.post('/tender/:id/measure/stage/:order/manager/audit/delete', sessionAuth, tenderCheck, stageCheck, 'stageController.managerAuditDelete');
+    app.get('/tender/:id/measure/stage/:order/manager', sessionAuth, tenderCheck, stageCheck, 'stageController.manager')
+    app.post('/tender/:id/measure/stage/:order/manager/audit/delete', sessionAuth, tenderCheck, stageCheck, 'stageController.managerAuditDelete')
+
     // 报表
-    app.get('/tender/:id/report', sessionAuth, tenderCheck, 'reportController.index');
-    app.get('/tender/:id/measure/stage/:order/report', sessionAuth, tenderCheck, stageCheck, 'reportController.index');
-    app.get('/printReport/:size', sessionAuth, 'reportController.showPrintPage');
-    app.post('/tender/report_api/getReport', sessionAuth, 'reportController.getReport');
-    app.post('/tender/report_api/getMultiReports', sessionAuth, 'reportController.getMultiReportsEx');
-    app.post('/tender/report_api/createExcelFiles', sessionAuth, 'reportController.createExcelFilesEx');
-    app.post('/tender/report_api/createExcelFilesInOneBook', sessionAuth, 'reportController.createExcelFilesInOneBookEx');
-    app.get('/getFileByUUID/:uuid/:rptName/:suffix', sessionAuth, 'reportController.getFileByUUID');
+    app.get('/tender/:id/report', sessionAuth, tenderCheck, 'reportController.index')
+    app.get('/tender/:id/measure/stage/:order/report', sessionAuth, tenderCheck, stageCheck, 'reportController.index')
+    app.get('/printReport/:size', sessionAuth, 'reportController.showPrintPage')
+    app.post('/tender/report_api/getReport', sessionAuth, 'reportController.getReport')
+    app.post('/tender/report_api/getMultiReports', sessionAuth, 'reportController.getMultiReportsEx')
+    app.post('/tender/report_api/createExcelFiles', sessionAuth, 'reportController.createExcelFilesEx')
+    app.post('/tender/report_api/createExcelFilesInOneBook', sessionAuth, 'reportController.createExcelFilesInOneBookEx')
+    app.get('/getFileByUUID/:uuid/:rptName/:suffix', sessionAuth, 'reportController.getFileByUUID')
     // rptRouter.get('/getFileByUUID/:uuid/:rptName/:suffix', reportController.getFileByUUID);
-    app.post('/tender/report_api/createSignatureRole', sessionAuth, 'signatureController.createSignatureRole');
-    app.post('/tender/report_api/updateSignatureUsed', sessionAuth, datetimeFill, 'signatureController.updateSignatureUsed');
-    app.post('/tender/report_api/updateRoleRelationship', sessionAuth, 'signatureController.updateRoleRel');
-    app.post('/tender/report_api/createRoleRelationship', sessionAuth, 'signatureController.createRoleRel');
-    app.post('/tender/report_api/updateCustNode', sessionAuth, 'reportController.updateCustNode');
-    app.post('/report/cDefine', sessionAuth, 'reportController.setCustomDefine');
+    app.post('/tender/report_api/createSignatureRole', sessionAuth, 'signatureController.createSignatureRole')
+    app.post('/tender/report_api/updateSignatureUsed', sessionAuth, datetimeFill, 'signatureController.updateSignatureUsed')
+    app.post('/tender/report_api/updateRoleRelationship', sessionAuth, 'signatureController.updateRoleRel')
+    app.post('/tender/report_api/createRoleRelationship', sessionAuth, 'signatureController.createRoleRel')
+    app.post('/tender/report_api/updateCustNode', sessionAuth, 'reportController.updateCustNode')
+    app.post('/report/cDefine', sessionAuth, 'reportController.setCustomDefine')
 
     // 变更管理
-    app.get('/tender/:id/change', sessionAuth, tenderCheck, 'changeController.index');
-    app.get('/tender/:id/change/status/:status', sessionAuth, tenderCheck, 'changeController.status');
-    app.post('/tender/:id/change/newCode', sessionAuth, tenderCheck, 'changeController.newCode');
-    app.post('/tender/:id/change/add', sessionAuth, tenderCheck, 'changeController.add');
-    app.post('/tender/:id/change/defaultBills', sessionAuth, tenderCheck, 'changeController.defaultBills');
-    app.get('/tender/:id/change/:cid/info', sessionAuth, tenderCheck, 'changeController.info');
-    app.post('/change/upload/file', sessionAuth, 'changeController.uploadFile');
-    app.get('/change/download/file/:id', sessionAuth, 'changeController.downloadFile');
-    app.post('/change/delete/file', sessionAuth, 'changeController.deleteFile');
-    app.post('/tender/:id/change/delete', sessionAuth, tenderCheck, 'changeController.delete');
-    app.post('/tender/:id/change/bills', sessionAuth, tenderCheck, 'changeController.bills');
+    app.get('/tender/:id/change', sessionAuth, tenderCheck, 'changeController.index')
+    app.get('/tender/:id/change/status/:status', sessionAuth, tenderCheck, 'changeController.status')
+    app.post('/tender/:id/change/newCode', sessionAuth, tenderCheck, 'changeController.newCode')
+    app.post('/tender/:id/change/add', sessionAuth, tenderCheck, 'changeController.add')
+    app.post('/tender/:id/change/defaultBills', sessionAuth, tenderCheck, 'changeController.defaultBills')
+    app.get('/tender/:id/change/:cid/info', sessionAuth, tenderCheck, 'changeController.info')
+    app.post('/change/upload/file', sessionAuth, 'changeController.uploadFile')
+    app.get('/change/download/file/:id', sessionAuth, 'changeController.downloadFile')
+    app.post('/change/delete/file', sessionAuth, 'changeController.deleteFile')
+    app.post('/tender/:id/change/delete', sessionAuth, tenderCheck, 'changeController.delete')
+    app.post('/tender/:id/change/bills', sessionAuth, tenderCheck, 'changeController.bills')
 
-    app.post('/tender/:id/change/save', sessionAuth, tenderCheck, 'changeController.save');
+    app.post('/tender/:id/change/save', sessionAuth, tenderCheck, 'changeController.save')
 
-    app.post('/tender/:id/change/approval', sessionAuth, tenderCheck, 'changeController.approval');
-    app.post('/tender/:id/change/check/again', sessionAuth, tenderCheck, 'changeController.checkAgain');
+    app.post('/tender/:id/change/approval', sessionAuth, tenderCheck, 'changeController.approval')
+    app.post('/tender/:id/change/check/again', sessionAuth, tenderCheck, 'changeController.checkAgain')
 
-    app.post('/tender/:id/change/:cid/check/codeRepeat', sessionAuth, tenderCheck, 'changeController.checkCodeRepeat');
+    app.post('/tender/:id/change/:cid/check/codeRepeat', sessionAuth, tenderCheck, 'changeController.checkCodeRepeat')
 
     // 变更单位管理
-    app.post('/change/update/company', sessionAuth, 'changeController.updateCompany');
+    app.post('/change/update/company', sessionAuth, 'changeController.updateCompany')
 
     // 材料调差
-    app.get('/tender/:id/measure/material', sessionAuth, tenderCheck, 'materialController.index');
-    app.post('/tender/:id/measure/material/add', sessionAuth, tenderCheck, 'materialController.add');
-    app.post('/tender/:id/measure/material/delete', sessionAuth, tenderCheck, 'materialController.delete');
-    app.post('/tender/:id/measure/material/auditors', sessionAuth, tenderCheck, 'materialController.materialAuditors');
+    app.get('/tender/:id/measure/material', sessionAuth, tenderCheck, 'materialController.index')
+    app.post('/tender/:id/measure/material/add', sessionAuth, tenderCheck, 'materialController.add')
+    app.post('/tender/:id/measure/material/delete', sessionAuth, tenderCheck, 'materialController.delete')
+    app.post('/tender/:id/measure/material/auditors', sessionAuth, tenderCheck, 'materialController.materialAuditors')
     // 审批
-    app.post('/tender/:id/measure/material/:order/audit/add', sessionAuth, tenderCheck, materialCheck, 'materialController.addAudit');
-    app.post('/tender/:id/measure/material/:order/audit/delete', sessionAuth, tenderCheck, materialCheck, 'materialController.deleteAudit');
-    app.post('/tender/:id/measure/material/:order/audit/start', sessionAuth, tenderCheck, materialCheck, 'materialController.startAudit');
-    app.post('/tender/:id/measure/material/:order/audit/check', sessionAuth, tenderCheck, materialCheck, 'materialController.checkAudit');
+    app.post('/tender/:id/measure/material/:order/audit/add', sessionAuth, tenderCheck, materialCheck, 'materialController.addAudit')
+    app.post('/tender/:id/measure/material/:order/audit/delete', sessionAuth, tenderCheck, materialCheck, 'materialController.deleteAudit')
+    app.post('/tender/:id/measure/material/:order/audit/start', sessionAuth, tenderCheck, materialCheck, 'materialController.startAudit')
+    app.post('/tender/:id/measure/material/:order/audit/check', sessionAuth, tenderCheck, materialCheck, 'materialController.checkAudit')
     // 调差工料
-    app.get('/tender/:id/measure/material/:order', sessionAuth, tenderCheck, materialCheck, 'materialController.info');
-    app.post('/tender/:id/measure/material/:order/save', sessionAuth, tenderCheck, materialCheck, 'materialController.saveBillsData');
+    app.get('/tender/:id/measure/material/:order', sessionAuth, tenderCheck, materialCheck, 'materialController.info')
+    app.post('/tender/:id/measure/material/:order/save', sessionAuth, tenderCheck, materialCheck, 'materialController.saveBillsData')
     // 调差清单
-    app.get('/tender/:id/measure/material/:order/list', sessionAuth, tenderCheck, materialCheck, 'materialController.list');
-    app.post('/tender/:id/measure/material/:order/list/save', sessionAuth, tenderCheck, materialCheck, 'materialController.saveListsData');
+    app.get('/tender/:id/measure/material/:order/list', sessionAuth, tenderCheck, materialCheck, 'materialController.list')
+    app.post('/tender/:id/measure/material/:order/list/save', sessionAuth, tenderCheck, materialCheck, 'materialController.saveListsData')
 
     // 附件
-    app.get('/tender/:id/measure/material/:order/file', sessionAuth, tenderCheck, materialCheck, 'materialController.file');
-    app.post('/tender/:id/measure/material/:order/file/upload', sessionAuth, tenderCheck, materialCheck, 'materialController.upload');
-    app.post('/tender/:id/measure/material/:order/file/find', sessionAuth, tenderCheck, materialCheck, 'materialController.getCurMatericalFiles');
-    app.post('/tender/measure/material/file/delete', sessionAuth, 'materialController.deleteFile');
+    app.get('/tender/:id/measure/material/:order/file', sessionAuth, tenderCheck, materialCheck, 'materialController.file')
+    app.post('/tender/:id/measure/material/:order/file/upload', sessionAuth, tenderCheck, materialCheck, 'materialController.upload')
+    app.post('/tender/:id/measure/material/:order/file/find', sessionAuth, tenderCheck, materialCheck, 'materialController.getCurMatericalFiles')
+    app.post('/tender/measure/material/file/delete', sessionAuth, 'materialController.deleteFile')
 
     // 个人账号相关
-    app.get('/profile/info', sessionAuth, 'profileController.info');
-    app.get('/profile/sms', sessionAuth, 'profileController.sms');
-    app.post('/profile/sms/type', sessionAuth, 'profileController.smsType');
-    app.get('/profile/sign', sessionAuth, 'profileController.sign');
-    app.post('/profile/sign/delete', sessionAuth, 'profileController.signDelete');
-    app.post('/profile/sign/upload', sessionAuth, 'profileController.signUpload');
-    app.get('/profile/safe', sessionAuth, 'profileController.safe');
-    app.post('/profile/save', sessionAuth, 'profileController.saveBase');
-    app.post('/profile/password', sessionAuth, 'profileController.modifyPassword');
-    app.post('/profile/code', sessionAuth, 'profileController.getCode');
-    app.post('/profile/bind', sessionAuth, 'profileController.bindMobile');
-    app.get('/profile/qrCode', sessionAuth, 'profileController.qrCode');
-    app.get('/profile/wechat', sessionAuth, 'profileController.wechat');
-    app.post('/profile/wechat/remove', sessionAuth, 'profileController.removeWechat');
+    app.get('/profile/info', sessionAuth, 'profileController.info')
+    app.get('/profile/sms', sessionAuth, 'profileController.sms')
+    app.post('/profile/sms/type', sessionAuth, 'profileController.smsType')
+    app.get('/profile/sign', sessionAuth, 'profileController.sign')
+    app.post('/profile/sign/delete', sessionAuth, 'profileController.signDelete')
+    app.post('/profile/sign/upload', sessionAuth, 'profileController.signUpload')
+    app.get('/profile/safe', sessionAuth, 'profileController.safe')
+    app.post('/profile/save', sessionAuth, 'profileController.saveBase')
+    app.post('/profile/password', sessionAuth, 'profileController.modifyPassword')
+    app.post('/profile/code', sessionAuth, 'profileController.getCode')
+    app.post('/profile/bind', sessionAuth, 'profileController.bindMobile')
+    app.get('/profile/qrCode', sessionAuth, 'profileController.qrCode')
+    app.get('/profile/wechat', sessionAuth, 'profileController.wechat')
+    app.post('/profile/wechat/remove', sessionAuth, 'profileController.removeWechat')
 
     // 标准库相关
-    app.post('/std-lib/get-data', sessionAuth, 'standardLibController.getData');
+    app.post('/std-lib/get-data', sessionAuth, 'standardLibController.getData')
 
     // 查询
-    app.post('/search/user', sessionAuth, 'projectController.searchAccount');
+    app.post('/search/user', sessionAuth, 'projectController.searchAccount')
 
     // 示例
-    app.get('/template/:file', sessionAuth, 'templateController.download');
+    app.get('/template/:file', sessionAuth, 'templateController.download')
 
     // 标段对比
-    app.get('/compare/tz', sessionAuth, 'spssController.compareTz');
-    app.post('/compare/tz/load', sessionAuth, 'spssController.loadCompareTz');
-    app.get('/compare/stage', sessionAuth, 'spssController.compareStage');
-    app.post('/compare/stage/load', sessionAuth, 'spssController.loadCompareStage');
-    app.get('/gather/tz', sessionAuth, 'spssController.gatherTz');
-    app.post('/gather/tz/load', sessionAuth, 'spssController.loadGatherTz');
-    app.get('/gather/stage', sessionAuth, 'spssController.gatherStage');
-    app.post('/gather/stage/load', sessionAuth, 'spssController.loadGatherStage');
-    app.get('/tools/check-tz', sessionAuth, 'spssController.checkTz');
-    app.post('/tools/load', sessionAuth, 'spssController.loadBaseData');
+    app.get('/compare/tz', sessionAuth, 'spssController.compareTz')
+    app.post('/compare/tz/load', sessionAuth, 'spssController.loadCompareTz')
+    app.get('/compare/stage', sessionAuth, 'spssController.compareStage')
+    app.post('/compare/stage/load', sessionAuth, 'spssController.loadCompareStage')
+    app.get('/gather/tz', sessionAuth, 'spssController.gatherTz')
+    app.post('/gather/tz/load', sessionAuth, 'spssController.loadGatherTz')
+    app.get('/gather/stage', sessionAuth, 'spssController.gatherStage')
+    app.post('/gather/stage/load', sessionAuth, 'spssController.loadGatherStage')
+    app.get('/tools/check-tz', sessionAuth, 'spssController.checkTz')
+    app.post('/tools/load', sessionAuth, 'spssController.loadBaseData')
 
     // wap页面
-    app.get('/wap', 'wapController.index');
-    app.get('/wap/login', 'wapController.index');
-    app.post('/wap/login', 'wapController.login');
-    app.get('/wap/logout', 'wapController.logout');
-    app.get('/wap/dashboard', sessionAuth, 'wapController.dashboard');
-    app.get('/wap/list', sessionAuth, 'wapController.list');
-    app.get('/wap/tender/:id', sessionAuth, tenderCheck, 'wapController.tender');
-    app.get('/wap/tender/:id/stage/:order', sessionAuth, tenderCheck, 'wapController.stage');
-    app.get('/wap/tender/:id/change/:cid/info', sessionAuth, tenderCheck, 'wapController.change');
-    app.post('/wap/tender/:id/change/approval', sessionAuth, tenderCheck, 'wapController.changeApproval');
+    app.get('/wap', 'wapController.index')
+    app.get('/wap/login', 'wapController.index')
+    app.post('/wap/login', 'wapController.login')
+    app.get('/wap/logout', 'wapController.logout')
+    app.get('/wap/dashboard', sessionAuth, 'wapController.dashboard')
+    app.get('/wap/list', sessionAuth, 'wapController.list')
+    app.get('/wap/tender/:id', sessionAuth, tenderCheck, 'wapController.tender')
+    app.get('/wap/tender/:id/stage/:order', sessionAuth, tenderCheck, 'wapController.stage')
+    app.get('/wap/tender/:id/change/:cid/info', sessionAuth, tenderCheck, 'wapController.change')
+    app.post('/wap/tender/:id/change/approval', sessionAuth, tenderCheck, 'wapController.changeApproval')
 
     // 微信
-    app.get('/wx', 'wechatController.index');
-    app.get('/wx/oauth', 'wechatController.oauth');
-    app.get('/wx/bind', wechatAuth, 'wechatController.bind');
-    app.post('/wx/bindwx', wechatAuth, 'wechatController.bindwx');
-    app.get('/wx/test', wechatAuth, 'wechatController.testwx');
-    app.get('/MP_verify_t3MkWAMqplVxPjmr.txt', 'wechatController.oauthTxt');
-};
+    app.get('/wx', 'wechatController.index')
+    app.get('/wx/oauth', 'wechatController.oauth')
+    app.get('/wx/bind', wechatAuth, 'wechatController.bind')
+    app.post('/wx/bindwx', wechatAuth, 'wechatController.bindwx')
+    app.get('/wx/test', wechatAuth, 'wechatController.testwx')
+    app.get('/MP_verify_t3MkWAMqplVxPjmr.txt', 'wechatController.oauthTxt')
+}

+ 11 - 0
app/service/advance.js

@@ -0,0 +1,11 @@
+'use strict'
+
+module.exports = app => {
+    class Advance extends app.BaseService {
+        constructor(ctx) {
+            super(ctx)
+            this.tableName = 'advance_pay'
+        }
+    }
+    return Advance
+}

+ 48 - 0
app/service/advance_audit.js

@@ -0,0 +1,48 @@
+'use strict'
+
+module.exports = app => {
+    class AdvanceAudit extends app.BaseService {
+        constructor(ctx) {
+            super(ctx)
+            this.tableName = 'advance_audit'
+        }
+
+        /**
+         * 获取审核人流程列表
+         * @param {Number} vid 预付款记录id
+         * @param {Number} times 审核次数
+         */
+        async getAuditGroupByList(vid, times) {
+            const sql =
+                'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`sid`, la.`aid`, la.`order` ' +
+                'FROM ?? AS la, ?? AS pa ' +
+                'WHERE la.`sid` = ? and la.`times` = ? and la.`aid` = pa.`id` GROUP BY la.`aid` ORDER BY la.`order`'
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, vid, times]
+            return await this.db.query(sql, sqlParam)
+        }
+
+        /**
+         * 获取审核人流程列表(包括原报)
+         * @param {Number} vid 预付款记录id
+         * @param {Number} times 审核次数
+         */
+        async getAuditGroupByListWithOwner(vid, times) {
+            const result = await this.getAuditGroupByList(vid, times)
+            const sql =
+                'SELECT pa.`id` As aid, pa.`name`, pa.`company`, pa.`role`, ? As times, ? As sid, 0 As `order`' +
+                '  FROM ' +
+                this.ctx.service.advance.tableName +
+                ' As s' +
+                '  LEFT JOIN ' +
+                this.ctx.service.projectAccount.tableName +
+                ' As pa' +
+                '  ON s.user_id = pa.id' +
+                '  WHERE s.id = ?'
+            const sqlParam = [times, stageId, stageId]
+            const user = await this.db.queryOne(sql, sqlParam)
+            result.unshift(user)
+            return result
+        }
+    }
+    return AdvanceAudit
+}

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 612 - 497
app/service/change.js


+ 178 - 125
app/service/ledger_audit.js

@@ -1,4 +1,4 @@
-'use strict';
+'use strict'
 
 /**
  * 台账审批流程表
@@ -8,11 +8,11 @@
  * @version
  */
 
-const auditConst = require('../const/audit').ledger;
-const smsTypeConst = require('../const/sms_type');
-const SMS = require('../lib/sms');
-const SmsAliConst = require('../const/sms_alitemplate');
-const pushType = require('../const/audit').pushType;
+const auditConst = require('../const/audit').ledger
+const smsTypeConst = require('../const/sms_type')
+const SMS = require('../lib/sms')
+const SmsAliConst = require('../const/sms_alitemplate')
+const pushType = require('../const/audit').pushType
 
 module.exports = app => {
     class LedgerAudit extends app.BaseService {
@@ -23,8 +23,8 @@ module.exports = app => {
          * @return {void}
          */
         constructor(ctx) {
-            super(ctx);
-            this.tableName = 'ledger_audit';
+            super(ctx)
+            this.tableName = 'ledger_audit'
         }
 
         /**
@@ -36,12 +36,13 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAuditor(tenderId, auditorId, times = 1) {
-            const sql = 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
+            const sql =
+                'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
                 'FROM ?? AS la, ?? AS pa ' +
                 'WHERE la.`tender_id` = ? and la.`audit_id` = ? and la.`times` = ?' +
-                '    and la.`audit_id` = pa.`id`';
-            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditorId, times];
-            return await this.db.queryOne(sql, sqlParam);
+                '    and la.`audit_id` = pa.`id`'
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditorId, times]
+            return await this.db.queryOne(sql, sqlParam)
         }
 
         /**
@@ -53,12 +54,13 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getStatusName(tenderId, times) {
-            const sql = 'SELECT pa.`name` ' +
+            const sql =
+                'SELECT pa.`name` ' +
                 'FROM ?? AS la, ?? AS pa ' +
                 'WHERE la.`tender_id` = ?' +
-                '    and la.`audit_id` = pa.`id` and la.`status` != ? ORDER BY la.`times` DESC, la.`audit_order` DESC';
-            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditConst.status.uncheck];
-            return await this.db.queryOne(sql, sqlParam);
+                '    and la.`audit_id` = pa.`id` and la.`status` != ? ORDER BY la.`times` DESC, la.`audit_order` DESC'
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditConst.status.uncheck]
+            return await this.db.queryOne(sql, sqlParam)
         }
 
         /**
@@ -69,18 +71,19 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAuditors(tenderId, times = 1) {
-            const sql = 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, g.`sort` ' +
+            const sql =
+                'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, g.`sort` ' +
                 'FROM ?? AS la, ?? AS pa, (SELECT `audit_id`,(@i:=@i+1) as `sort` FROM ??, (select @i:=0) as it WHERE `tender_id` = ? AND `times` = ? GROUP BY `audit_id`) as g ' +
-                'WHERE la.`tender_id` = ? and la.`times` = ? and la.`audit_id` = pa.`id` and g.`audit_id` = la.`audit_id` order by la.`audit_order`';
-            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, this.tableName, tenderId, times, tenderId, times];
-            const result = await this.db.query(sql, sqlParam);
-            const sql2 = 'SELECT COUNT(a.`audit_id`) as num FROM (SELECT `audit_id` FROM ?? WHERE `tender_id` = ? AND `times` = ? GROUP BY `audit_id`) as a';
-            const sqlParam2 = [this.tableName, tenderId, times];
-            const count = await this.db.queryOne(sql2, sqlParam2);
+                'WHERE la.`tender_id` = ? and la.`times` = ? and la.`audit_id` = pa.`id` and g.`audit_id` = la.`audit_id` order by la.`audit_order`'
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, this.tableName, tenderId, times, tenderId, times]
+            const result = await this.db.query(sql, sqlParam)
+            const sql2 = 'SELECT COUNT(a.`audit_id`) as num FROM (SELECT `audit_id` FROM ?? WHERE `tender_id` = ? AND `times` = ? GROUP BY `audit_id`) as a'
+            const sqlParam2 = [this.tableName, tenderId, times]
+            const count = await this.db.queryOne(sql2, sqlParam2)
             for (const i in result) {
-                result[i].max_sort = count.num;
+                result[i].max_sort = count.num
             }
-            return result;
+            return result
         }
 
         /**
@@ -91,12 +94,13 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getCurAuditor(tenderId, times = 1) {
-            const sql = 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
+            const sql =
+                'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
                 'FROM ?? AS la, ?? AS pa ' +
                 'WHERE la.`tender_id` = ? and la.`status` = ? and la.`times` = ?' +
-                '    and la.`audit_id` = pa.`id`';
-            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditConst.status.checking, times];
-            return await this.db.queryOne(sql, sqlParam);
+                '    and la.`audit_id` = pa.`id`'
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditConst.status.checking, times]
+            return await this.db.queryOne(sql, sqlParam)
         }
 
         /**
@@ -107,10 +111,10 @@ module.exports = app => {
          * @returns {Promise<number>}
          */
         async getNewOrder(tenderId, times = 1) {
-            const sql = 'SELECT Max(??) As max_order FROM ?? Where `tender_id` = ? and `times` = ?';
-            const sqlParam = ['audit_order', this.tableName, tenderId, times];
-            const result = await this.db.queryOne(sql, sqlParam);
-            return result && result.max_order ? result.max_order + 1 : 1;
+            const sql = 'SELECT Max(??) As max_order FROM ?? Where `tender_id` = ? and `times` = ?'
+            const sqlParam = ['audit_order', this.tableName, tenderId, times]
+            const result = await this.db.queryOne(sql, sqlParam)
+            return result && result.max_order ? result.max_order + 1 : 1
         }
 
         /**
@@ -122,16 +126,16 @@ module.exports = app => {
          * @returns {Promise<number>}
          */
         async addAuditor(tenderId, auditorId, times = 1) {
-            const newOrder = await this.getNewOrder(tenderId, times);
+            const newOrder = await this.getNewOrder(tenderId, times)
             const data = {
                 tender_id: tenderId,
                 audit_id: auditorId,
-                times: times,
+                times,
                 audit_order: newOrder,
-                status: auditConst.status.uncheck,
-            };
-            const result = await this.db.insert(this.tableName, data);
-            return result.effectRows = 1;
+                status: auditConst.status.uncheck
+            }
+            const result = await this.db.insert(this.tableName, data)
+            return (result.effectRows = 1)
         }
 
         /**
@@ -144,27 +148,27 @@ module.exports = app => {
          * @private
          */
         async _syncOrderByDelete(transaction, tenderId, order, times) {
-            this.initSqlBuilder();
+            this.initSqlBuilder()
             this.sqlBuilder.setAndWhere('tender_id', {
                 value: tenderId,
                 operate: '='
-            });
+            })
             this.sqlBuilder.setAndWhere('audit_order', {
                 value: order,
-                operate: '>=',
-            });
+                operate: '>='
+            })
             this.sqlBuilder.setAndWhere('times', {
                 value: times,
-                operate: '=',
-            });
+                operate: '='
+            })
             this.sqlBuilder.setUpdateData('audit_order', {
                 value: 1,
-                selfOperate: '-',
-            });
-            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
-            const data = await transaction.query(sql, sqlParam);
+                selfOperate: '-'
+            })
+            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update')
+            const data = await transaction.query(sql, sqlParam)
 
-            return data;
+            return data
         }
 
         /**
@@ -176,21 +180,21 @@ module.exports = app => {
          * @returns {Promise<boolean>}
          */
         async deleteAuditor(tenderId, auditorId, times = 1) {
-            const transaction = await this.db.beginTransaction();
+            const transaction = await this.db.beginTransaction()
             try {
-                const condition = {tender_id: tenderId, audit_id: auditorId, times: times};
-                const auditor = await this.getDataByCondition(condition);
+                const condition = { tender_id: tenderId, audit_id: auditorId, times }
+                const auditor = await this.getDataByCondition(condition)
                 if (!auditor) {
-                    throw '该审核人不存在';
+                    throw '该审核人不存在'
                 }
-                await this._syncOrderByDelete(transaction, tenderId, auditor.audit_order, times);
-                await transaction.delete(this.tableName, condition);
-                await transaction.commit();
+                await this._syncOrderByDelete(transaction, tenderId, auditor.audit_order, times)
+                await transaction.delete(this.tableName, condition)
+                await transaction.commit()
             } catch (err) {
-                await transaction.rollback();
-                throw err;
+                await transaction.rollback()
+                throw err
             }
-            return true;
+            return true
         }
 
         /**
@@ -201,78 +205,112 @@ module.exports = app => {
          * @returns {Promise<boolean>}
          */
         async start(tenderId, times = 1) {
-            const audit = await this.getDataByCondition({tender_id: tenderId, times: times, audit_order: 1});
+            const audit = await this.getDataByCondition({ tender_id: tenderId, times, audit_order: 1 })
             if (!audit) {
-                throw '审核人信息错误';
+                throw '审核人信息错误'
             }
-            const sum = await this.ctx.service.ledger.addUp({tender_id: tenderId/*, is_leaf: true*/});
+            const sum = await this.ctx.service.ledger.addUp({ tender_id: tenderId /* , is_leaf: true*/ })
 
-            const transaction = await this.db.beginTransaction();
+            const transaction = await this.db.beginTransaction()
             try {
-                await transaction.update(this.tableName, {id: audit.id, status: auditConst.status.checking, begin_time: new Date()});
+                await transaction.update(this.tableName, {
+                    id: audit.id,
+                    status: auditConst.status.checking,
+                    begin_time: new Date()
+                })
                 await transaction.update(this.ctx.service.tender.tableName, {
-                    id: tenderId, ledger_status: auditConst.status.checking,
-                    total_price: sum.total_price, deal_tp: sum.deal_tp,
-                });
+                    id: tenderId,
+                    ledger_status: auditConst.status.checking,
+                    total_price: sum.total_price,
+                    deal_tp: sum.deal_tp
+                })
 
                 // 添加短信通知-需要审批提醒功能
                 // await this.ctx.helper.sendUserSms(audit.audit_id, smsTypeConst.const.TZ,
                 //     smsTypeConst.judge.approval.toString(), '台帐需要您审批。');
-                await this.ctx.helper.sendAliSms(audit.audit_id, smsTypeConst.const.TZ,
-                    smsTypeConst.judge.approval.toString(), SmsAliConst.template.ledger_check);
+                await this.ctx.helper.sendAliSms(audit.audit_id, smsTypeConst.const.TZ, smsTypeConst.judge.approval.toString(), SmsAliConst.template.ledger_check)
 
-                await transaction.commit();
+                await transaction.commit()
             } catch (err) {
-                await transaction.rollback();
-                throw err;
+                await transaction.rollback()
+                throw err
             }
-            return true;
+            return true
         }
 
         /**
          * 审批
          * @param {Number} tenderId - 标段id
          * @param {auditConst.status.checked|auditConst.status.checkNo} checkType - 审批结果
+         * @param {String} opinion 审批意见
          * @param {Number} times - 第几次审批
          * @returns {Promise<void>}
          */
         async check(tenderId, checkType, opinion, times = 1) {
             if (checkType !== auditConst.status.checked && checkType !== auditConst.status.checkNo) {
-                throw '提交数据错误';
+                throw '提交数据错误'
             }
-            const pid = this.ctx.session.sessionProject.id;
-            const transaction = await this.db.beginTransaction();
+            const pid = this.ctx.session.sessionProject.id
+            const transaction = await this.db.beginTransaction()
             try {
                 // 整理当前流程审核人状态更新
-                const time = new Date();
-                const audit = await this.getDataByCondition({ tender_id: tenderId, times, status: auditConst.status.checking });
+                const time = new Date()
+                const audit = await this.getDataByCondition({
+                    tender_id: tenderId,
+                    times,
+                    status: auditConst.status.checking
+                })
                 if (!audit) {
-                    throw '审核数据错误';
+                    throw '审核数据错误'
                 }
 
                 // 获取审核人列表
-                const auditList = await this.getAuditors(tenderId, times);
+                const auditList = await this.getAuditors(tenderId, times)
                 // 添加推送
                 const noticeContent = await this.getNoticeContent(audit.tender_id, pid, audit.audit_id)
-                const records = [{ pid, type: pushType.ledger, uid: this.ctx.tender.data.user_id, status: auditConst.status.checked, content: noticeContent }]
-                auditList.forEach( audit => {
-                    records.push({ pid, type: pushType.ledger, uid: audit.audit_id, status: auditConst.status.checked, content: noticeContent })
+                const records = [
+                    {
+                        pid,
+                        type: pushType.ledger,
+                        uid: this.ctx.tender.data.user_id,
+                        status: checkType,
+                        content: noticeContent
+                    }
+                ]
+                auditList.forEach(audit => {
+                    records.push({
+                        pid,
+                        type: pushType.ledger,
+                        uid: audit.audit_id,
+                        status: checkType,
+                        content: noticeContent
+                    })
                 })
-                await transaction.insert('zh_notice', records);
+                await transaction.insert('zh_notice', records)
                 // 更新当前审核流程
-                await transaction.update(this.tableName, { id: audit.id, status: checkType, opinion, end_time: time });
+                await transaction.update(this.tableName, { id: audit.id, status: checkType, opinion, end_time: time })
                 if (checkType === auditConst.status.checked) {
-                    const nextAudit = await this.getDataByCondition({ tender_id: tenderId, times, audit_order: audit.audit_order + 1 });
+                    const nextAudit = await this.getDataByCondition({
+                        tender_id: tenderId,
+                        times,
+                        audit_order: audit.audit_order + 1
+                    })
                     // 无下一审核人表示,审核结束
                     if (nextAudit) {
-                        await transaction.update(this.tableName, { id: nextAudit.id, status: auditConst.status.checking, begin_time: time });
+                        await transaction.update(this.tableName, {
+                            id: nextAudit.id,
+                            status: auditConst.status.checking,
+                            begin_time: time
+                        })
                         // await this.ctx.helper.sendUserSms(nextAudit.audit_id, smsTypeConst.const.TZ,
                         //     smsTypeConst.judge.approval.toString(), '台帐需要您审批。');
-                        await this.ctx.helper.sendAliSms(nextAudit.audit_id, smsTypeConst.const.TZ,
-                            smsTypeConst.judge.approval.toString(), SmsAliConst.template.ledger_check);
+                        await this.ctx.helper.sendAliSms(nextAudit.audit_id, smsTypeConst.const.TZ, smsTypeConst.judge.approval.toString(), SmsAliConst.template.ledger_check)
                     } else {
                         // 同步标段信息
-                        await transaction.update(this.ctx.service.tender.tableName, { id: tenderId, ledger_status: checkType });
+                        await transaction.update(this.ctx.service.tender.tableName, {
+                            id: tenderId,
+                            ledger_status: checkType
+                        })
 
                         // 添加短信通知-审批通过提醒功能
                         // const mobile_array = [];
@@ -302,25 +340,30 @@ module.exports = app => {
                         //     const content = '【纵横计量支付】' + ptmsg + '台账审批通过,请登录系统处理。';
                         //     sms.send(mobile_array, content);
                         // }
-                        const users = this._.pull(this._.map(auditList, 'audit_id'), audit.id);
+                        const users = this._.pull(this._.map(auditList, 'audit_id'), audit.id)
                         // await this.ctx.helper.sendUserSms(users, smsTypeConst.const.TZ,
                         //     smsTypeConst.judge.result.toString(), '台账审批通过,请登录系统处理。');
-                        await this.ctx.helper.sendAliSms(users, smsTypeConst.const.TZ,
-                            smsTypeConst.judge.result.toString(), SmsAliConst.template.ledger_result, { status: SmsAliConst.status.success });
+                        await this.ctx.helper.sendAliSms(users, smsTypeConst.const.TZ, smsTypeConst.judge.result.toString(), SmsAliConst.template.ledger_result, {
+                            status: SmsAliConst.status.success
+                        })
                     }
                 } else {
                     // 同步标段信息
-                    await transaction.update(this.ctx.service.tender.tableName, { id: tenderId, ledger_times: times + 1, ledger_status: checkType});
+                    await transaction.update(this.ctx.service.tender.tableName, {
+                        id: tenderId,
+                        ledger_times: times + 1,
+                        ledger_status: checkType
+                    })
                     // 拷贝新一次审核流程列表
                     const auditors = await this.getAllDataByCondition({
                         where: { tender_id: tenderId, times },
-                        columns: ['tender_id', 'audit_order', 'audit_id'],
-                    });
+                        columns: ['tender_id', 'audit_order', 'audit_id']
+                    })
                     for (const a of auditors) {
-                        a.times = times + 1;
-                        a.status = auditConst.status.uncheck;
+                        a.times = times + 1
+                        a.status = auditConst.status.uncheck
                     }
-                    await transaction.insert(this.tableName, auditors);
+                    await transaction.insert(this.tableName, auditors)
 
                     // 添加短信通知-审批退回提醒功能
                     // const mobile_array = [];
@@ -349,18 +392,18 @@ module.exports = app => {
                     //     const content = '【纵横计量支付】' + ptmsg + '台账审批退回,请登录系统处理。';
                     //     sms.send(mobile_array, content);
                     // }
-                    const users = this._.pull(this._.map(auditList, 'audit_id'), audit.id);
+                    const users = this._.pull(this._.map(auditList, 'audit_id'), audit.id)
                     // await this.ctx.helper.sendUserSms(users, smsTypeConst.const.TZ,
                     //     smsTypeConst.judge.result.toString(), '台账审批退回,请登录系统处理。');
-                    await this.ctx.helper.sendAliSms(users, smsTypeConst.const.TZ,
-                        smsTypeConst.judge.result.toString(), SmsAliConst.template.ledger_result, { status: SmsAliConst.status.back });
-
+                    await this.ctx.helper.sendAliSms(users, smsTypeConst.const.TZ, smsTypeConst.judge.result.toString(), SmsAliConst.template.ledger_result, {
+                        status: SmsAliConst.status.back
+                    })
                 }
 
-                await transaction.commit();
+                await transaction.commit()
             } catch (err) {
-                await transaction.rollback();
-                throw err;
+                await transaction.rollback()
+                throw err
             }
         }
 
@@ -371,18 +414,27 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAuditTender(auditorId) {
-            const sql = 'SELECT la.`audit_id`, la.`times`, la.`audit_order`, la.`begin_time`, la.`end_time`, t.`id`, t.`name`, t.`project_id`, t.`type`, t.`user_id`, t.`ledger_status` ' +
+            const sql =
+                'SELECT la.`audit_id`, la.`times`, la.`audit_order`, la.`begin_time`, la.`end_time`, t.`id`, t.`name`, t.`project_id`, t.`type`, t.`user_id`, t.`ledger_status` ' +
                 'FROM ?? AS la, ?? AS t ' +
                 'WHERE ((la.`audit_id` = ? and la.`status` = ?) OR (t.`user_id` = ? and t.`ledger_status` = ? and la.`status` = ? and la.`times` = (t.`ledger_times`-1)))' +
-                '    and la.`tender_id` = t.`id`';
-            const sqlParam = [this.tableName, this.ctx.service.tender.tableName, auditorId, auditConst.status.checking, auditorId, auditConst.status.checkNo, auditConst.status.checkNo];
-            return await this.db.query(sql, sqlParam);
+                '    and la.`tender_id` = t.`id`'
+            const sqlParam = [
+                this.tableName,
+                this.ctx.service.tender.tableName,
+                auditorId,
+                auditConst.status.checking,
+                auditorId,
+                auditConst.status.checkNo,
+                auditConst.status.checkNo
+            ]
+            return await this.db.query(sql, sqlParam)
         }
 
         /**
          * 获取 某时间后 审批进度 更新的台账
-         * @param {Integer} projectId - 项目id
-         * @param {Integer} auditorId - 查询人id
+         * @param {Integer} pid - 项目id
+         * @param {Integer} uid - 查询人id
          * @param {Date} noticeTime - 查询事件
          * @returns {Promise<*>}
          */
@@ -398,18 +450,18 @@ module.exports = app => {
             //     noticeTime, projectId];
             // return await this.db.query(sql, sqlParam);
 
-
-            let notice =  await this.db.select('zh_notice', {
+            let notice = await this.db.select('zh_notice', {
                 where: { pid, type: pushType.ledger, uid },
                 orders: [['create_time', 'desc']],
-                limit: 10, offset: 0
-            });
+                limit: 10,
+                offset: 0
+            })
             notice = notice.map(v => {
                 const extra = JSON.parse(v.content)
                 delete v.content
                 return { ...v, ...extra }
             })
-            return notice;
+            return notice
         }
 
         /**
@@ -419,16 +471,17 @@ module.exports = app => {
          * @param {Number} uid 审核人id
          */
         async getNoticeContent(id, pid, uid) {
-            const noticeSql = 'SELECT * FROM (SELECT ' +
+            const noticeSql =
+                'SELECT * FROM (SELECT ' +
                 '  t.`id` As `tid`, t.`name`,  pa.`name` As `su_name`, pa.role As `su_role`' +
                 '  FROM (SELECT * FROM ?? WHERE `id` = ? ) As t' +
                 '  LEFT JOIN ?? As pa ON pa.`id` = ?' +
-                '  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);
-            return content.length ? JSON.stringify(content[0]) : '';
+                '  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)
+            return content.length ? JSON.stringify(content[0]) : ''
         }
     }
 
-    return LedgerAudit;
-};
+    return LedgerAudit
+}

+ 11 - 12
app/service/notice_push.js

@@ -1,4 +1,4 @@
-'use strict';
+'use strict'
 
 /**
  * 推送表模型
@@ -9,9 +9,7 @@
  */
 
 module.exports = app => {
-
     class NoticePush extends app.BaseService {
-
         /**
          * 构造函数
          *
@@ -19,8 +17,8 @@ module.exports = app => {
          * @return {void}
          */
         constructor(ctx) {
-            super(ctx);
-            this.tableName = 'notice';
+            super(ctx)
+            this.tableName = 'notice'
         }
 
         /**
@@ -28,7 +26,7 @@ module.exports = app => {
          * @param {Number} id 推送记录id
          */
         async set(id) {
-            await this.update({ is_read: 1 }, { id });
+            await this.update({ is_read: 1 }, { id })
         }
 
         /**
@@ -37,18 +35,19 @@ module.exports = app => {
          * @param {Integer} uid - 查询人id
          */
         async getNotice(pid, uid) {
-            let notice =  await this.db.select(this.tableName, {
+            let notice = await this.db.select(this.tableName, {
                 where: { pid, uid },
                 orders: [['create_time', 'desc']],
-                limit: 10, offset: 0
-            });
+                limit: 10,
+                offset: 0
+            })
             notice = notice.map(v => {
                 const extra = JSON.parse(v.content)
                 delete v.content
                 return { ...v, ...extra }
             })
-            return notice;
+            return notice
         }
     }
-    return NoticePush;
-};
+    return NoticePush
+}

+ 1 - 1
app/service/project_account.js

@@ -100,7 +100,7 @@ module.exports = app => {
          * 账号登录
          *
          * @param {Object} data - 表单post数据
-         * @param {Number} loginType - 登录类型 1 | 2
+         * @param {Number} loginType - 登录类型 1(sso登录) | 2(正常或副密码登录) | 3(接口登录或微信登录)
          * @return {Boolean} - 返回登录结果
          */
         async accountLogin(data, loginType) {

+ 296 - 201
app/service/revise_audit.js

@@ -1,4 +1,4 @@
-'use strict';
+'use strict'
 
 /**
  *
@@ -8,10 +8,10 @@
  * @version
  */
 
-const auditConst = require('../const/audit').revise;
-const smsTypeConst = require('../const/sms_type');
-const SmsAliConst = require('../const/sms_alitemplate');
-const pushType = require('../const/audit').pushType;
+const auditConst = require('../const/audit').revise
+const smsTypeConst = require('../const/sms_type')
+const SmsAliConst = require('../const/sms_alitemplate')
+const pushType = require('../const/audit').pushType
 
 module.exports = app => {
     class ReviseAudit extends app.BaseService {
@@ -22,8 +22,8 @@ module.exports = app => {
          * @return {void}
          */
         constructor(ctx) {
-            super(ctx);
-            this.tableName = 'revise_audit';
+            super(ctx)
+            this.tableName = 'revise_audit'
         }
 
         /**
@@ -35,12 +35,13 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAuditor(reviseId, auditorId, times = 1) {
-            const sql = 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
+            const sql =
+                'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
                 'FROM ?? AS la, ?? AS pa ' +
                 'WHERE la.`rid` = ? and la.`audit_id` = ? and la.`times` = ?' +
-                '    and la.`audit_id` = pa.`id`';
-            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, reviseId, auditorId, times];
-            return await this.db.queryOne(sql, sqlParam);
+                '    and la.`audit_id` = pa.`id`'
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, reviseId, auditorId, times]
+            return await this.db.queryOne(sql, sqlParam)
         }
 
         /**
@@ -51,13 +52,18 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAuditors(reviseId, times = 1) {
-            const sql = 'SELECT la.`audit_id`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`,' +
+            const sql =
+                'SELECT la.`audit_id`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`,' +
                 '    pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`' +
-                '  FROM ' + this.tableName + ' AS la ' +
-                '  INNER JOIN ' + this.ctx.service.projectAccount.tableName + ' AS pa ON la.`rid` = ? and la.`times` = ? and la.`audit_id` = pa.`id`' +
-                '  ORDER BY la.`audit_order`';
-            const sqlParam = [reviseId, times];
-            return await this.db.query(sql, sqlParam);
+                '  FROM ' +
+                this.tableName +
+                ' AS la ' +
+                '  INNER JOIN ' +
+                this.ctx.service.projectAccount.tableName +
+                ' AS pa ON la.`rid` = ? and la.`times` = ? and la.`audit_id` = pa.`id`' +
+                '  ORDER BY la.`audit_order`'
+            const sqlParam = [reviseId, times]
+            return await this.db.query(sql, sqlParam)
         }
 
         /**
@@ -68,18 +74,19 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAuditors2ReviseList(rid, times = 1) {
-            const sql = 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, g.`sort` ' +
+            const sql =
+                'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, g.`sort` ' +
                 'FROM ?? AS la, ?? AS pa, (SELECT `audit_id`,(@i:=@i+1) as `sort` FROM ??, (select @i:=0) as it WHERE `rid` = ? AND `times` = ? GROUP BY `audit_id`) as g ' +
-                'WHERE la.`rid` = ? and la.`times` = ? and la.`audit_id` = pa.`id` and g.`audit_id` = la.`audit_id` order by la.`audit_order`';
-            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, this.tableName, rid, times, rid, times];
-            const result = await this.db.query(sql, sqlParam);
-            const sql2 = 'SELECT COUNT(a.`audit_id`) as num FROM (SELECT `audit_id` FROM ?? WHERE `rid` = ? AND `times` = ? GROUP BY `audit_id`) as a';
-            const sqlParam2 = [this.tableName, rid, times];
-            const count = await this.db.queryOne(sql2, sqlParam2);
+                'WHERE la.`rid` = ? and la.`times` = ? and la.`audit_id` = pa.`id` and g.`audit_id` = la.`audit_id` order by la.`audit_order`'
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, this.tableName, rid, times, rid, times]
+            const result = await this.db.query(sql, sqlParam)
+            const sql2 = 'SELECT COUNT(a.`audit_id`) as num FROM (SELECT `audit_id` FROM ?? WHERE `rid` = ? AND `times` = ? GROUP BY `audit_id`) as a'
+            const sqlParam2 = [this.tableName, rid, times]
+            const count = await this.db.queryOne(sql2, sqlParam2)
             for (const i in result) {
-                result[i].max_sort = count.num;
+                result[i].max_sort = count.num
             }
-            return result;
+            return result
         }
 
         /**
@@ -90,12 +97,13 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getCurAuditor(reviseId, times = 1) {
-            const sql = 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
+            const sql =
+                'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
                 'FROM ?? AS la, ?? AS pa ' +
                 'WHERE la.`rid` = ? and la.`status` = ? and la.`times` = ?' +
-                '    and la.`audit_id` = pa.`id`';
-            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, reviseId, auditConst.status.checking, times];
-            return await this.db.queryOne(sql, sqlParam);
+                '    and la.`audit_id` = pa.`id`'
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, reviseId, auditConst.status.checking, times]
+            return await this.db.queryOne(sql, sqlParam)
         }
 
         /**
@@ -106,10 +114,10 @@ module.exports = app => {
          * @returns {Promise<number>}
          */
         async getNewOrder(reviseId, times = 1) {
-            const sql = 'SELECT Max(??) As max_order FROM ?? Where `rid` = ? and `times` = ?';
-            const sqlParam = ['audit_order', this.tableName, reviseId, times];
-            const result = await this.db.queryOne(sql, sqlParam);
-            return result && result.max_order ? result.max_order + 1 : 1;
+            const sql = 'SELECT Max(??) As max_order FROM ?? Where `rid` = ? and `times` = ?'
+            const sqlParam = ['audit_order', this.tableName, reviseId, times]
+            const result = await this.db.queryOne(sql, sqlParam)
+            return result && result.max_order ? result.max_order + 1 : 1
         }
 
         /**
@@ -121,19 +129,19 @@ module.exports = app => {
          * @returns {Promise<number>}
          */
         async addAuditor(revise, auditorId) {
-            const times = revise.times ? revise.times : 1;
-            const newOrder = await this.getNewOrder(revise.id, times);
+            const times = revise.times ? revise.times : 1
+            const newOrder = await this.getNewOrder(revise.id, times)
             const data = {
                 tender_id: revise.tid,
                 audit_id: auditorId,
-                times: times,
+                times,
                 audit_order: newOrder,
                 status: auditConst.status.uncheck,
                 rid: revise.id,
-                in_time: new Date(),
-            };
-            const result = await this.db.insert(this.tableName, data);
-            return result.effectRows = 1;
+                in_time: new Date()
+            }
+            const result = await this.db.insert(this.tableName, data)
+            return (result.effectRows = 1)
         }
 
         /**
@@ -146,27 +154,27 @@ module.exports = app => {
          * @private
          */
         async _syncOrderByDelete(transaction, reviseId, order, times) {
-            this.initSqlBuilder();
+            this.initSqlBuilder()
             this.sqlBuilder.setAndWhere('rid', {
                 value: this.db.escape(reviseId),
                 operate: '='
-            });
+            })
             this.sqlBuilder.setAndWhere('audit_order', {
                 value: order,
-                operate: '>=',
-            });
+                operate: '>='
+            })
             this.sqlBuilder.setAndWhere('times', {
                 value: times,
-                operate: '=',
-            });
+                operate: '='
+            })
             this.sqlBuilder.setUpdateData('audit_order', {
                 value: 1,
-                selfOperate: '-',
-            });
-            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
-            const data = await transaction.query(sql, sqlParam);
+                selfOperate: '-'
+            })
+            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update')
+            const data = await transaction.query(sql, sqlParam)
 
-            return data;
+            return data
         }
 
         /**
@@ -178,22 +186,22 @@ module.exports = app => {
          * @returns {Promise<boolean>}
          */
         async deleteAuditor(revise, auditorId) {
-            const times = revise.times ? revise.times : 1;
-            const transaction = await this.db.beginTransaction();
+            const times = revise.times ? revise.times : 1
+            const transaction = await this.db.beginTransaction()
             try {
-                const condition = {rid: revise.id, audit_id: auditorId, times: times};
-                const auditor = await this.getDataByCondition(condition);
+                const condition = { rid: revise.id, audit_id: auditorId, times }
+                const auditor = await this.getDataByCondition(condition)
                 if (!auditor) {
-                    throw '该审核人不存在';
+                    throw '该审核人不存在'
                 }
-                await this._syncOrderByDelete(transaction, revise.id, auditor.audit_order, times);
-                await transaction.delete(this.tableName, condition);
-                await transaction.commit();
-            } catch(err) {
-                await transaction.rollback();
-                throw err;
+                await this._syncOrderByDelete(transaction, revise.id, auditor.audit_order, times)
+                await transaction.delete(this.tableName, condition)
+                await transaction.commit()
+            } catch (err) {
+                await transaction.rollback()
+                throw err
             }
-            return true;
+            return true
         }
 
         /**
@@ -204,54 +212,59 @@ module.exports = app => {
          * @returns {Promise<boolean>}
          */
         async start(revise, times = 1) {
-            const audit = await this.getDataByCondition({rid: revise.id, times: times, audit_order: 1});
-            if (!audit) throw '审核人信息错误';
-            const time = new Date();
+            const audit = await this.getDataByCondition({ rid: revise.id, times, audit_order: 1 })
+            if (!audit) throw '审核人信息错误'
+            const time = new Date()
 
             // 拷贝备份台账数据
-            const [billsHis, posHis] = await this.ctx.service.ledgerRevise.backupReviseHistoryFile(revise);
+            const [billsHis, posHis] = await this.ctx.service.ledgerRevise.backupReviseHistoryFile(revise)
 
-            const transaction = await this.db.beginTransaction();
+            const transaction = await this.db.beginTransaction()
             try {
                 await transaction.update(this.tableName, {
-                    id: audit.id, status: auditConst.status.checking, begin_time: time,
-                    bills_file: revise.bills_file, pos_file: revise.pos_file,
-                });
+                    id: audit.id,
+                    status: auditConst.status.checking,
+                    begin_time: time,
+                    bills_file: revise.bills_file,
+                    pos_file: revise.pos_file
+                })
                 const reviseData = {
-                    id: revise.id, status: auditConst.status.checking,
-                    bills_file: billsHis, pos_file: posHis,
-                };
+                    id: revise.id,
+                    status: auditConst.status.checking,
+                    bills_file: billsHis,
+                    pos_file: posHis
+                }
                 if (revise.times === 1) {
-                    reviseData.begin_time = time;
+                    reviseData.begin_time = time
                 }
-                await transaction.update(this.ctx.service.ledgerRevise.tableName, reviseData);
+                await transaction.update(this.ctx.service.ledgerRevise.tableName, reviseData)
 
                 // 添加短信通知-需要审批提醒功能
                 // 下一人
                 // await this.ctx.helper.sendUserSms(audit.audit_id, smsTypeConst.const.XD,
                 //     smsTypeConst.judge.approval.toString(), '台帐修订需要您审批,请登录系统处理。');
-                await this.ctx.helper.sendAliSms(audit.audit_id, smsTypeConst.const.XD,
-                    smsTypeConst.judge.approval.toString(), SmsAliConst.template.revise_check);
+                await this.ctx.helper.sendAliSms(audit.audit_id, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), SmsAliConst.template.revise_check)
                 // 其他参与人
-                const auditList = await this.getAuditors(revise.tid, times);
-                const users = this._.pull(this._.map(auditList, 'user_id'), audit.id);
+                const auditList = await this.getAuditors(revise.id, times)
+                const users = this._.pull(this._.map(auditList, 'user_id'), audit.id)
                 // await this.ctx.helper.sendUserSms(users, smsTypeConst.const.XD,
                 //     smsTypeConst.judge.result.toString(), '台账修订已上报。');
-                await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD,
-                    smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_report);
+                await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_report)
 
-                await transaction.commit();
+                await transaction.commit()
             } catch (err) {
-                await transaction.rollback();
-                throw err;
+                await transaction.rollback()
+                throw err
             }
-            return true;
+            return true
         }
 
         async _replaceLedgerByRevise(transaction, revise) {
-            const sqlParam = [revise.tid];
-            await transaction.delete(this.ctx.service.ledger.tableName, {tender_id: revise.tid});
-            const bSql = 'Insert Into ' + this.ctx.service.ledger.tableName +
+            const sqlParam = [revise.tid]
+            await transaction.delete(this.ctx.service.ledger.tableName, { tender_id: revise.tid })
+            const bSql =
+                'Insert Into ' +
+                this.ctx.service.ledger.tableName +
                 '  (id, code, b_code, name, unit, source, remark, ledger_id, ledger_pid, level, `order`, full_path, is_leaf,' +
                 '     quantity, total_price, unit_price, drawing_code, memo, dgn_qty1, dgn_qty2, deal_qty, deal_tp,' +
                 '     sgfh_qty, sgfh_tp, sjcl_qty, sjcl_tp, qtcl_qty, qtcl_tp, node_type, crid, tender_id, is_tp,' +
@@ -260,20 +273,24 @@ module.exports = app => {
                 '      quantity, total_price, unit_price, drawing_code, memo, dgn_qty1, dgn_qty2, deal_qty, deal_tp,' +
                 '      sgfh_qty, sgfh_tp, sjcl_qty, sjcl_tp, qtcl_qty, qtcl_tp, node_type, crid, tender_id, is_tp, ' +
                 '      sgfh_expr, sjcl_expr, qtcl_expr' +
-                '  From ' + this.ctx.service.reviseBills.tableName +
-                '  Where `tender_id` = ?';
-            await transaction.query(bSql, sqlParam);
-            await transaction.delete(this.ctx.service.pos.tableName, {tid: revise.tid});
-            const pSql = 'Insert Into ' + this.ctx.service.pos.tableName +
+                '  From ' +
+                this.ctx.service.reviseBills.tableName +
+                '  Where `tender_id` = ?'
+            await transaction.query(bSql, sqlParam)
+            await transaction.delete(this.ctx.service.pos.tableName, { tid: revise.tid })
+            const pSql =
+                'Insert Into ' +
+                this.ctx.service.pos.tableName +
                 '  (id, tid, lid, name, drawing_code, quantity, add_stage, add_times, add_user,' +
                 '     sgfh_qty, sjcl_qty, qtcl_qty, crid, porder, position, ' +
                 '     sgfh_expr, sjcl_expr, qtcl_expr)' +
                 '  Select id, tid, lid, name, drawing_code, quantity, add_stage, add_times, add_user,' +
                 '     sgfh_qty, sjcl_qty, qtcl_qty, crid, porder, position,' +
                 '     sgfh_expr, sjcl_expr, qtcl_expr' +
-                '  From ' + this.ctx.service.revisePos.tableName +
-                '  Where `tid` = ?';
-            await transaction.query(pSql, sqlParam);
+                '  From ' +
+                this.ctx.service.revisePos.tableName +
+                '  Where `tid` = ?'
+            await transaction.query(pSql, sqlParam)
         }
 
         /**
@@ -285,106 +302,163 @@ module.exports = app => {
          * @returns {Promise<void>}
          */
         async check(revise, checkType, opinion, times = 1) {
-            if (checkType !== auditConst.status.checked && checkType !== auditConst.status.checkNo) throw '提交数据错误';
-            const audit = await this.getDataByCondition({rid: revise.id, times: times, status: auditConst.status.checking});
-            if (!audit) throw '审核数据错误';
-            const pid = this.ctx.session.sessionProject.id;
-            const noticeContent = await this.getNoticeContent(pid, audit.tender_id, audit.rid)
-            const transaction = await this.db.beginTransaction();
+            if (checkType !== auditConst.status.checked && checkType !== auditConst.status.checkNo) throw '提交数据错误'
+            const audit = await this.getDataByCondition({
+                rid: revise.id,
+                times,
+                status: auditConst.status.checking
+            })
+            if (!audit) throw '审核数据错误'
+            const pid = this.ctx.session.sessionProject.id
+            const transaction = await this.db.beginTransaction()
             try {
+                const auditList = await this.getAuditors(revise.id, times)
+                // 审核通过添加到推送表
+                const noticeContent = await this.getNoticeContent(pid, audit.tender_id, audit.rid, audit.audit_id)
+                const records = [
+                    {
+                        pid,
+                        type: pushType.revise,
+                        uid: revise.uid,
+                        status: checkType,
+                        content: noticeContent
+                    }
+                ]
+                auditList.forEach(audit => {
+                    records.push({
+                        pid,
+                        type: pushType.revise,
+                        uid: audit.audit_id,
+                        status: checkType,
+                        content: noticeContent
+                    })
+                })
+                await transaction.insert('zh_notice', records)
+
                 // 整理当前流程审核人状态更新
-                const time = new Date();
+                const time = new Date()
                 // 更新当前审核流程
                 await transaction.update(this.tableName, {
-                    id: audit.id, status: checkType, opinion, end_time: time,
-                });
+                    id: audit.id,
+                    status: checkType,
+                    opinion,
+                    end_time: time
+                })
                 if (checkType === auditConst.status.checked) {
-                    const nextAudit = await this.getDataByCondition({ rid: revise.id, times, audit_order: audit.audit_order + 1 });
+                    const nextAudit = await this.getDataByCondition({
+                        rid: revise.id,
+                        times,
+                        audit_order: audit.audit_order + 1
+                    })
                     // 无下一审核人表示,审核结束
                     if (nextAudit) {
-                        await transaction.update(this.tableName, { id: nextAudit.id, status: auditConst.status.checking, begin_time: time });
+                        await transaction.update(this.tableName, {
+                            id: nextAudit.id,
+                            status: auditConst.status.checking,
+                            begin_time: time
+                        })
 
                         // 短信通知-需要审批提醒功能
                         // 下一人
                         // await this.ctx.helper.sendUserSms(nextAudit.user_id, smsTypeConst.const.XD,
                         //     smsTypeConst.judge.approval.toString(), '台帐修订需要您审批,请登录系统处理。');
-                        await this.ctx.helper.sendAliSms(nextAudit.user_id, smsTypeConst.const.XD,
-                            smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result, { status: SmsAliConst.status.success });
+                        await this.ctx.helper.sendAliSms(nextAudit.user_id, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result, {
+                            status: SmsAliConst.status.success
+                        })
                         // 其他参与人
-                        const auditList = await this.getAuditors(revise.tid, times);
-                        const users = this._.pull(this._.map(auditList, 'user_id'), audit.id);
-                        users.push(revise.uid);
+                        const users = this._.pull(this._.map(auditList, 'user_id'), audit.id)
+                        users.push(revise.uid)
                         // await this.ctx.helper.sendUserSms(users, smsTypeConst.const.XD,
                         //     smsTypeConst.judge.result.toString(), '台账修订审批通过。');
-                        await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD,
-                            smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result2, { status: SmsAliConst.status.success });
+                        await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result2, {
+                            status: SmsAliConst.status.success
+                        })
                     } else {
                         // 同步修订信息
-                        await transaction.update(this.ctx.service.ledgerRevise.tableName, { id: revise.id, status: checkType, end_time: time });
+                        await transaction.update(this.ctx.service.ledgerRevise.tableName, {
+                            id: revise.id,
+                            status: checkType,
+                            end_time: time
+                        })
                         // 最新一期跟台账相关的缓存数据应过期
-                        const lastStage = await this.ctx.service.stage.getLastestStage(revise.tid, true);
-                        const cacheTime = new Date();
-                        if (lastStage) await transaction.update(this.ctx.service.stage.tableName,
-                            {id: lastStage.id, cache_time_l: cacheTime, cache_time_r: cacheTime});
+                        const lastStage = await this.ctx.service.stage.getLastestStage(revise.tid, true)
+                        const cacheTime = new Date()
+                        if (lastStage)
+                            await transaction.update(this.ctx.service.stage.tableName, {
+                                id: lastStage.id,
+                                cache_time_l: cacheTime,
+                                cache_time_r: cacheTime
+                            })
                         // 拷贝修订数据至台账
-                        await this._replaceLedgerByRevise(transaction, revise);
-                        const sum = await this.ctx.service.reviseBills.addUp({tender_id: revise.tid/*, is_leaf: true*/});
+                        await this._replaceLedgerByRevise(transaction, revise)
+                        const sum = await this.ctx.service.reviseBills.addUp({
+                            tender_id: revise.tid /* , is_leaf: true*/
+                        })
                         await transaction.update(this.ctx.service.tender.tableName, {
-                            id: revise.tid, total_price: sum.total_price, deal_tp: sum.deal_tp
-                        });
-                        // 审核结束,将原报添加到推送表
-                        // const noticeContent = await this.getNoticeContent(pid, audit.tender_id, audit.rid)
-                        await transaction.insert('zh_notice', { pid, type: pushType.revise, uid: revise.uid, status: auditConst.status.checked, is_read: 0, content: noticeContent });
+                            id: revise.tid,
+                            total_price: sum.total_price,
+                            deal_tp: sum.deal_tp
+                        })
                         // 短信通知-审批通过提醒功能
                         // 下一人
                         // const msg = '台账修订审批通过,请登录系统处理。';
                         // await this.ctx.helper.sendUserSms(revise.uid, smsTypeConst.const.XD,
                         //     smsTypeConst.judge.result.toString(), msg);
-                        await this.ctx.helper.sendAliSms(revise.uid, smsTypeConst.const.XD,
-                            smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result, { status: SmsAliConst.status.success });
+                        await this.ctx.helper.sendAliSms(revise.uid, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result, {
+                            status: SmsAliConst.status.success
+                        })
                         // 其他参与人
-                        const auditList = await this.getAuditors(revise.tid, times);
-                        const users = this._.pull(this._.map(auditList, 'user_id'), audit.id);
+                        const users = this._.pull(this._.map(auditList, 'user_id'), audit.id)
                         // await this.ctx.helper.sendUserSms(users, smsTypeConst.const.XD,
                         //     smsTypeConst.judge.result.toString(), '台账修订审批通过。');
-                        await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD,
-                            smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result2, { status: SmsAliConst.status.success });
+                        await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result2, {
+                            status: SmsAliConst.status.success
+                        })
                     }
                 } else {
                     // 同步修订信息
-                    await transaction.update(this.ctx.service.ledgerRevise.tableName, { id: revise.id, times: times + 1, status: checkType });
+                    await transaction.update(this.ctx.service.ledgerRevise.tableName, {
+                        id: revise.id,
+                        times: times + 1,
+                        status: checkType
+                    })
                     // 拷贝新一次审核流程列表
                     const auditors = await this.getAllDataByCondition({
                         where: { rid: revise.id, times },
-                        columns: ['tender_id', 'rid', 'audit_order', 'audit_id'],
-                    });
+                        columns: ['tender_id', 'rid', 'audit_order', 'audit_id']
+                    })
                     for (const a of auditors) {
-                        a.times = times + 1;
-                        a.status = auditConst.status.uncheck;
-                        a.in_time = time;
+                        a.times = times + 1
+                        a.status = auditConst.status.uncheck
+                        a.in_time = time
                     }
-                    await transaction.insert(this.tableName, auditors);
+                    await transaction.insert(this.tableName, auditors)
 
                     // 短信通知-审批退回提醒功能
                     // 下一人
                     // await this.ctx.helper.sendUserSms(revise.uid, smsTypeConst.const.XD,
                     //     smsTypeConst.judge.result.toString(), '台账修订审批退回,请登录系统处理。');
-                    await this.ctx.helper.sendAliSms(revise.uid, smsTypeConst.const.XD,
-                        smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result, { status: SmsAliConst.status.back });
+                    await this.ctx.helper.sendAliSms(revise.uid, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result, {
+                        status: SmsAliConst.status.back
+                    })
                     // 其他参与人
                     // await this.ctx.helper.sendUserSms(this._.map(auditors, 'user_id'),
                     //     smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), '台账修订审批退回。');
-                    await this.ctx.helper.sendAliSms(this._.map(auditors, 'user_id'), smsTypeConst.const.XD,
-                        smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result2, { status: SmsAliConst.status.back });
-
-                    // 审核结束,将原报添加到推送表
-                    await transaction.insert('zh_notice', { pid, type: pushType.revise, uid: revise.uid, status: auditConst.status.checkNo, is_read: 0, content: noticeContent });
+                    await this.ctx.helper.sendAliSms(
+                        this._.map(auditors, 'user_id'),
+                        smsTypeConst.const.XD,
+                        smsTypeConst.judge.result.toString(),
+                        SmsAliConst.template.revise_result2,
+                        {
+                            status: SmsAliConst.status.back
+                        }
+                    )
                 }
 
-                await transaction.commit();
+                await transaction.commit()
             } catch (err) {
-                await transaction.rollback();
-                throw err;
+                await transaction.rollback()
+                throw err
             }
         }
 
@@ -395,18 +469,27 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAuditRevise(auditorId) {
-            const sql = 'SELECT ra.`audit_id`, ra.`times`, ra.`audit_order`, ra.`begin_time`, ra.`end_time`,' +
+            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,' +
                 '    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, ' +
                 '    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.projectAccount.tableName + ' As p On ra.audit_id = p.id' +
+                '  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.projectAccount.tableName +
+                ' As p On ra.audit_id = p.id' +
                 '  WHERE r.`valid` != 0 and ((ra.`audit_id` = ? and ra.`status` = ?) OR' +
-                '    (r.`uid` = ? and r.`status` = ? and ra.`status` = ? and ra.`times` = (r.`times`-1)))';
-            const sqlParam = [auditorId, auditConst.status.checking, auditorId, auditConst.status.checkNo, auditConst.status.checkNo];
-            return await this.db.query(sql, sqlParam);
+                '    (r.`uid` = ? and r.`status` = ? and ra.`status` = ? and ra.`times` = (r.`times`-1)))'
+            const sqlParam = [auditorId, auditConst.status.checking, auditorId, auditConst.status.checkNo, auditConst.status.checkNo]
+            return await this.db.query(sql, sqlParam)
         }
 
         /**
@@ -430,17 +513,18 @@ module.exports = app => {
             //     '  ORDER By new_t.`end_time`';
             // const sqlParam = [this.ctx.service.tender.tableName, auditorId, this.tableName, auditorId, noticeTime, projectId];
             // return await this.db.query(sql, sqlParam);
-            let notice =  await this.db.select('zh_notice', {
+            let notice = await this.db.select('zh_notice', {
                 where: { pid, type: pushType.revise, uid },
                 orders: [['create_time', 'desc']],
-                limit: 10, offset: 0
-            });
+                limit: 10,
+                offset: 0
+            })
             notice = notice.map(v => {
                 const extra = JSON.parse(v.content)
                 delete v.content
                 return { ...v, ...extra }
             })
-            return notice;
+            return notice
         }
 
         /**
@@ -448,17 +532,19 @@ module.exports = app => {
          * @param {Number} pid 项目id
          * @param {Number} tid 台账id
          * @param {Number} rid 修订id
+         * @param {Number} uid 审核人id
          */
-        async getNoticeContent(pid, tid, rid) {
-            const noticeSql = 'SELECT * FROM (SELECT ' +
+        async getNoticeContent(pid, tid, rid, uid) {
+            const noticeSql =
+                'SELECT * FROM (SELECT ' +
                 '  t.`id` As `tid`, t.`name`, r.`corder`, pa.`name` As `su_name`, pa.role As `su_role`' +
                 '  FROM (SELECT * FROM ?? WHERE `id` = ? ) As t' +
                 '  LEFT JOIN ?? As r On r.`id` = ? ' +
-                '  LEFT JOIN ?? As pa ON t.`user_id` = pa.`id`' +
-                '  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, pid];
-            const content = await this.db.query(noticeSql, noticeSqlParam);
-            return content.length ? JSON.stringify(content[0]) : '';
+                '  LEFT JOIN ?? As pa ON pa.`id` = ? ' +
+                '  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)
+            return content.length ? JSON.stringify(content[0]) : ''
         }
 
         /**
@@ -470,30 +556,33 @@ module.exports = app => {
          * @return {Promise<boolean>}
          */
         async getAuditorByStatus(rid, status, times = 1) {
-            let auditor = null;
-            let sql = '';
-            let sqlParam = '';
+            let auditor = null
+            let sql = ''
+            let sqlParam = ''
             switch (status) {
-                case auditConst.status.checking :
-                case auditConst.status.checked :
-                case auditConst.status.checkNoPre :
-                    sql = 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`rid`, la.`audit_order` ' +
+                case auditConst.status.checking:
+                case auditConst.status.checked:
+                case auditConst.status.checkNoPre:
+                    sql =
+                        'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`rid`, la.`audit_order` ' +
                         'FROM ?? AS la, ?? AS pa ' +
-                        'WHERE la.`rid` = ? and la.`status` = ? and la.`audit_id` = pa.`id` order by la.`times` desc, la.`audit_order` desc';
-                    sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, rid, status];
-                    auditor = await this.db.queryOne(sql, sqlParam);
-                    break;
-                case auditConst.status.checkNo :
-                    sql = 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`rid`, la.`audit_order` ' +
+                        'WHERE la.`rid` = ? and la.`status` = ? and la.`audit_id` = pa.`id` order by la.`times` desc, la.`audit_order` desc'
+                    sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, rid, status]
+                    auditor = await this.db.queryOne(sql, sqlParam)
+                    break
+                case auditConst.status.checkNo:
+                    sql =
+                        'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`rid`, la.`audit_order` ' +
                         'FROM ?? AS la, ?? AS pa ' +
-                        'WHERE la.`rid` = ? and la.`status` = ? and la.`times` = ? and la.`audit_id` = pa.`id` order by la.`times` desc, la.`audit_order` desc';
-                    sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, rid, auditConst.status.checkNo, parseInt(times) - 1];
-                    auditor = await this.db.queryOne(sql, sqlParam);
-                    break;
-                case auditConst.status.uncheck :
-                default:break;
+                        'WHERE la.`rid` = ? and la.`status` = ? and la.`times` = ? and la.`audit_id` = pa.`id` order by la.`times` desc, la.`audit_order` desc'
+                    sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, rid, auditConst.status.checkNo, parseInt(times) - 1]
+                    auditor = await this.db.queryOne(sql, sqlParam)
+                    break
+                case auditConst.status.uncheck:
+                default:
+                    break
             }
-            return auditor;
+            return auditor
         }
 
         /**
@@ -503,25 +592,31 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAuditGroupByList(rid, times) {
-            const sql = 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`rid`, la.`audit_order` ' +
+            const sql =
+                'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`rid`, la.`audit_order` ' +
                 'FROM ?? AS la, ?? AS pa ' +
-                'WHERE la.`rid` = ? and la.`times` = ? and la.`audit_id` = pa.`id` GROUP BY la.`audit_id` ORDER BY la.`audit_order`';
-            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, rid, times];
-            return await this.db.query(sql, sqlParam);
+                'WHERE la.`rid` = ? and la.`times` = ? and la.`audit_id` = pa.`id` GROUP BY la.`audit_id` ORDER BY la.`audit_order`'
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, rid, times]
+            return await this.db.query(sql, sqlParam)
             // const sql = 'SELECT `tid`, `sid`, `aid`, `order` FROM ?? WHERE `sid` = ? and `times` = ? GROUP BY `aid`';
             // const sqlParam = [this.tableName, stageId, times];
             // return await this.db.query(sql, sqlParam);
         }
 
         async getAllAuditors(tenderId) {
-            const sql = 'SELECT ra.audit_id, ra.tender_id FROM ' + this.tableName + ' ra' +
-                '  LEFT JOIN ' + this.ctx.service.tender.tableName + ' t On ra.tender_id = t.id' +
+            const sql =
+                'SELECT ra.audit_id, ra.tender_id FROM ' +
+                this.tableName +
+                ' ra' +
+                '  LEFT JOIN ' +
+                this.ctx.service.tender.tableName +
+                ' t On ra.tender_id = t.id' +
                 '  WHERE t.id = ?' +
-                '  GROUP BY ra.audit_id';
-            const sqlParam = [tenderId];
-            return this.db.query(sql, sqlParam);
+                '  GROUP BY ra.audit_id'
+            const sqlParam = [tenderId]
+            return this.db.query(sql, sqlParam)
         }
     }
 
-    return ReviseAudit;
-};
+    return ReviseAudit
+}

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 579 - 493
app/service/stage_audit.js


+ 273 - 0
app/view/advance/detail.ejs

@@ -0,0 +1,273 @@
+<% include ../tender/tender_sub_menu.ejs %>
+<div class="panel-content">
+    <div class="panel-title">
+        <div class="title-main d-flex justify-content-between">
+            <div>
+                <div class="d-inline-block">
+                    第3期
+                </div>
+            </div>
+            <div>
+                <a href="#sp-back" data-toggle="modal" data-target="#sp-back" class="btn btn-warning btn-sm">审批退回</a>
+                <a href="#sp-done" data-toggle="modal" data-target="#sp-done" class="btn btn-success btn-sm">审批通过</a>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-body">
+            <div class="sjs-height-0">
+                <div class="col-8 mx-auto">
+                    <h4 class="mt-3 text-center">第3期 开工预付款</h4>
+                    <table class="table table-bordered">
+                        <thead>
+                            <tr>
+                                <th colspan="4" class="text-center">
+                                    <h5>签约开工预付款:8,121,212.00 元</h5>
+                                </th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <% if(isEdited) { %>
+                                <th width="150">支付比例</th>
+                                <td class="text-right">
+                                    <div class="input-group input-group-sm"><input type="number"
+                                            class="form-control nospin text-right" value="2" max="100" min="1"
+                                            placeholder="请填写支付比例,将自动计算本期金额">
+                                        <div class="input-group-append"><span class="input-group-text">%</span></div>
+                                    </div>
+                                </td>
+                                <th width="150">本期金额</th>
+                                <td class="text-right">
+                                    <div class="input-group input-group-sm"><input type="number"
+                                            class="form-control nospin text-right" min="1" placeholder="请填写本期金额,将自动计算支付比例">
+                                        <div class="input-group-append"><span class="input-group-text">元</span></div>
+                                    </div>
+                                </td>
+                                </tr>
+                            <% } else {%>
+                                <tr>
+                                    <th width="150">支付比例</th>
+                                    <td class="text-right">
+                                        <h5>20%</h5>
+                                    </td>
+                                    <th width="150">本期金额</th>
+                                    <td class="text-right">
+                                        <h5>30000.00</h5>
+                                    </td>
+                                </tr>
+                            <% } %>
+                            <tr>
+                                <th>截止上期</th>
+                                <td class="text-right">
+                                    <h5>40000.00</h5>
+                                </td>
+                                <th>截止本期金额</th>
+                                <td class="text-right">
+                                    <h5>70000.00</h5>
+                                </td>
+                            </tr>
+                            <tr>
+                                <th>备注</th>
+                                <td colspan="3"></td>
+                            </tr>
+                        </tbody>
+                    </table>
+                    <table class="table table-bordered mt-3">
+                        <thead>
+                            <tr>
+                                <th colspan="3" class="text-center">附件</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <tr>
+                                <td width="70">1</td>
+                                <td><a href="">11212.jpg</a></td>
+                                <td width="90"><a href="#" target="_blank" title="下载"><i
+                                            class="fa fa-download "></i></a></td>
+                            </tr>
+                            <tr>
+                                <td width="70">2</td>
+                                <td><a href="">444555.jpg</a></td>
+                                <td width="90"><a href="#" target="_blank" title="下载"><i
+                                            class="fa fa-download "></i></a></td>
+                            </tr>
+                        </tbody>
+                    </table>
+                    <% if(isEdited) { %>
+                    <table class="table table-bordered mt-3">
+                        <thead>
+                            <tr>
+                                <th colspan="2" class="text-center">审批流程</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <tr>
+                                <td width="30%">
+                                    <div class="card">
+                                        <ul class="list-group list-group-flush">
+                                            <li class="list-group-item"><i
+                                                    class="fa fa fa-play-circle fa-rotate-90"></i> 布尔 <small
+                                                    class="text-muted">施工</small></li>
+                                            <li class="list-group-item"><i class="fa fa-chevron-circle-down"></i> 张三
+                                                <small class="text-muted">监理</small></li>
+                                            <li class="list-group-item"><i class="fa fa-chevron-circle-down"></i> 王五
+                                                <small class="text-muted">监理</small></li>
+                                            <li class="list-group-item"><i class="fa fa fa-stop-circle"></i> 李四 <small
+                                                    class="text-muted">监理</small></li>
+                                        </ul>
+                                    </div>
+                                </td>
+                                <td width="70%">
+                                    <div class="form-group">
+                                        <label>选择审批人</label>
+                                        <div class="input-group">
+                                            <div class="input-group-prepend">
+                                                <select class="form-control" id="account_group">
+                                                    <% for (const dw in accountGroup) { %>
+                                                        <option value="<%= dw %>"><%= accountGroup[dw] %></option>
+                                                    <% } %>
+                                                </select>
+                                            </div>
+                                            <select class="form-control" id="account_list">
+                                                <option value="0">选择审批人</option>
+                                                <% for (const account of accountList) { %>
+                                                    <% if (account.id !== ctx.session.sessionUser.accountId) { %>
+                                                        <option value="<%= account.id %>"><%= account.name %><% if (account.role !== '') { %>(<%= account.role %>)<% } %><% if (account.company !== '') { %> -<%= account.company %><% } %></option>
+                                                    <% } %>
+                                                <% } %>
+                                            </select>
+                                        </div>
+                                    </div>
+                                    <div class="card mt-3">
+                                        <div class="card-header">
+                                            审批流程
+                                        </div>
+                                        <ul class="list-group list-group-flush">
+                                            <li class="list-group-item"><a href=""
+                                                    class="text-danger pull-right">移除</a>1 张三 <small
+                                                    class="text-muted">监理</small>
+                                                <p class="m-0 ml-2"><small
+                                                        class="text-muted">中交第一公路工程局有限公司国道311线满别公路施工一分部</small></p>
+                                            </li>
+                                            <li class="list-group-item"><a href=""
+                                                    class="text-danger pull-right">移除</a>2 王五 <small
+                                                    class="text-muted">监理</small>
+                                                <p class="m-0 ml-2"><small class="text-muted">XXX单位</small></p>
+                                            </li>
+                                            <li class="list-group-item"><a href=""
+                                                    class="text-danger pull-right">移除</a>3 李四 <small
+                                                    class="text-muted">监理</small>
+                                                <p class="m-0 ml-2"><small class="text-muted">XXX单位</small></p>
+                                            </li>
+                                        </ul>
+                                    </div>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                    <% } else {%>
+                    <table class="table table-bordered mt-3">
+                        <thead>
+                            <tr>
+                                <th colspan="2" class="text-center">审批流程</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <tr>
+                                <td width="30%">
+                                    <div class="card">
+                                        <ul class="list-group list-group-flush">
+                                            <li class="list-group-item"><i
+                                                    class="fa fa fa-play-circle fa-rotate-90"></i> 布尔 <small
+                                                    class="text-muted">施工</small></li>
+                                            <li class="list-group-item"><i class="fa fa-chevron-circle-down"></i> 张三
+                                                <small class="text-muted">监理</small></li>
+                                            <li class="list-group-item"><i class="fa fa-chevron-circle-down"></i> 王五
+                                                <small class="text-muted">监理</small></li>
+                                            <li class="list-group-item"><i class="fa fa fa-stop-circle"></i> 李四 <small
+                                                    class="text-muted">监理</small></li>
+                                        </ul>
+                                    </div>
+                                </td>
+                                <td width="70%">
+                                    <div class="card mb-1">
+                                        <ul class="list-group list-group-flush">
+                                            <li class="list-group-item">
+                                                <span class="text-success pull-right">上报</span>
+                                                <h5 class="card-title"><i
+                                                        class="fa fa-play-circle fa-rotate-90 text-success"></i> 布尔
+                                                    <small class="text-muted">施工</small></h5>
+                                                <p class="card-text">2017-11-25</p>
+                                            </li>
+                                            <li class="list-group-item">
+                                                <span class="text-success pull-right">审批通过</span>
+                                                <h5 class="card-title"><i
+                                                        class="fa fa-chevron-circle-down text-success"></i> 张三 <small
+                                                        class="text-muted">监理</small></h5>
+                                                <p class="card-text">审批意见。2017-11-25</p>
+                                            </li>
+                                            <li class="list-group-item">
+                                                <span class="text-success pull-right">审批通过</span>
+                                                <h5 class="card-title"><i
+                                                        class="fa fa-chevron-circle-down text-success"></i> 王五 <small
+                                                        class="text-muted">监理</small></h5>
+                                                <p class="card-text">审批通过。2017-11-26</p>
+                                            </li>
+                                            <li class="list-group-item">
+                                                <span class="text-warning pull-right">审批退回 布尔</span>
+                                                <h5 class="card-title"><i class="fa fa-stop-circle text-warning"></i> 李四
+                                                    <small class="text-muted">监理</small></h5>
+                                                <p class="card-text">审批退回,审批意见文本。2017-11-27</p>
+                                            </li>
+                                        </ul>
+                                    </div>
+                                    <div class="card mb-1">
+                                        <ul class="list-group list-group-flush">
+                                            <li class="list-group-item">
+                                                <span class="text-success pull-right">重新上报</span>
+                                                <h5 class="card-title"><i
+                                                        class="fa fa-play-circle fa-rotate-90 text-success"></i> 布尔
+                                                    <small class="text-muted">施工</small></h5>
+                                                <p class="card-text">2017-12-01</p>
+                                            </li>
+                                            <li class="list-group-item">
+                                                <span class="text-success pull-right">审批通过</span>
+                                                <h5 class="card-title"><i
+                                                        class="fa fa-chevron-circle-down text-success"></i> 张三 <small
+                                                        class="text-muted">监理</small></h5>
+                                                <p class="card-text">审批通过 2017-12-02</p>
+                                            </li>
+                                            <li class="list-group-item">
+                                                <span class="text-warning pull-right">审批退回 张三</span>
+                                                <h5 class="card-title"><i
+                                                        class="fa fa-chevron-circle-down text-warning"></i> 王五 <small
+                                                        class="text-muted">监理</small></h5>
+                                                <p class="card-text">审批退回 2017-12-02</p>
+                                            </li>
+                                            <!--王五退回上一审批人 张三,张三重新审批-->
+                                            <li class="list-group-item">
+                                                <span class="pull-right">审批中</span>
+                                                <h5 class="card-title"><i class="fa fa-chevron-circle-down"></i> 张三
+                                                    <small class="text-muted">监理</small></h5>
+                                                <p class="card-text"></p>
+                                            </li>
+                                            <li class="list-group-item">
+                                                <h5 class="card-title"><i class="fa fa-stop-circle"></i> 李四 <small
+                                                        class="text-muted">监理</small></h5>
+                                            </li>
+                                        </ul>
+                                    </div>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                    <% } %>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script>
+    const accountGroup = JSON.parse('<%- JSON.stringify(accountGroup) %>');
+    const accountList = JSON.parse('<%- JSON.stringify(accountList) %>');
+</script>

+ 133 - 0
app/view/advance/index.ejs

@@ -0,0 +1,133 @@
+<% include ../tender/tender_sub_menu.ejs %>
+<div class="panel-content">
+    <div class="panel-title">
+        <div class="title-main d-flex justify-content-between">
+            <div>
+                <div class="d-inline-block">
+                    <div class="btn-group">
+                        <a class="btn btn-sm btn-light <%- type === 'start' ? 'active' : '' %>" href="/tender/<%- ctx.tender.id %>/advance">
+                            开工预付款(第3期)
+                        </a>
+                        <a class="btn btn-sm btn-light <%- type === 'material' ? 'active' : '' %>" href="/tender/<%- ctx.tender.id %>/advance/material">
+                            材料预付款(第5期)
+                        </a>
+                    </div>
+                </div>
+                <div class="d-inline-block ml-2">
+                    <% if(type === 'start') { %>
+                        签约开工预付款:
+                    <% } else {%>
+                        签约材料预付款:
+                    <% } %>
+                    <b><%- advancePayTotal %></b> 元
+                </div>
+                <div class="d-inline-block ml-4" style="width:300px">
+                    <div class="progress">
+                        <div class="progress-bar bg-success" style="width: 14%;" data-placement="bottom"
+                            data-toggle="tooltip" data-original-title="截止上期金额:¥40,000.00">14%</div>
+                        <div class="progress-bar bg-info" style="width:8%;" data-placement="bottom"
+                            data-toggle="tooltip" data-original-title="本期金额:¥30,000.00">8%</div>
+                        <div class="progress-bar bg-gray" style="width:78%;" data-placement="bottom"
+                            data-toggle="tooltip" data-original-title="未完成:¥930,00.00">78%</div>
+                    </div>
+                </div>
+            </div>
+            <div>
+                <a href="/tender/<%- ctx.tender.id %>/advance/<%- type %>/create" class="btn btn-primary btn-sm pull-right">开始新一期</a>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-body">
+            <div class="sjs-height-0">
+                <table class="table table-bordered">
+                    <thead>
+                        <tr>
+                            <th>期数</th>
+                            <th class="text-center" width="10%">支付比例</th>
+                            <th class="text-center" width="15%">本期金额</th>
+                            <th class="text-center" width="15%">截止上期</th>
+                            <th class="text-center" width="15%">截止本期金额</th>
+                            <th class="text-center">附件</th>
+                            <th class="text-center">进度</th>
+                            <th class="text-center" width="100">操作</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        <tr>
+                            <td><a href="yufukuan-qi-detail.html">第3期</a></td>
+                            <td>20%</td>
+                            <td class="text-right">30000.00</td>
+                            <td class="text-right">40000.00</td>
+                            <td class="text-right">70000.00</td>
+                            <td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i
+                                        class="fa fa-paperclip "></i> 3</a></td>
+                            <td>待上报</td>
+                            <td><a href="yufukuan-qi-add.html" class="btn btn-primary btn-sm">编辑</a></td>
+                        </tr>
+                        <tr>
+                            <td><a href="yufukuan-qi-detail.html">第3期</a></td>
+                            <td>20%</td>
+                            <td class="text-right">30000.00</td>
+                            <td class="text-right">40000.00</td>
+                            <td class="text-right">70000.00</td>
+                            <td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i
+                                        class="fa fa-paperclip "></i> 3</a></td>
+                            <td class="text-warning">审批退回</td>
+                            <td><a href="yufukuan-qi-add.html" class="btn btn-primary btn-sm">编辑</a></td>
+                        </tr>
+                        <tr>
+                            <td><a href="yufukuan-qi-detail.html">第3期</a></td>
+                            <td>20%</td>
+                            <td class="text-right">30000.00</td>
+                            <td class="text-right">40000.00</td>
+                            <td class="text-right">70000.00</td>
+                            <td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i
+                                        class="fa fa-paperclip "></i> 3</a></td>
+                            <td class=" text-warning"><a href="#sp-list" data-toggle="modal"
+                                    data-target="#sp-list">张三</a> 审批中</td>
+                            <td><a href="yufukuan-qi-detail.html" class="btn btn-success btn-sm">审批</a></td>
+                        </tr>
+                        <tr>
+                            <td><a href="yufukuan-qi-detail.html">第3期</a></td>
+                            <td>20%</td>
+                            <td class="text-right">30000.00</td>
+                            <td class="text-right">40000.00</td>
+                            <td class="text-right">70000.00</td>
+                            <td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i
+                                        class="fa fa-paperclip "></i> 3</a></td>
+                            <td class=" text-warning"><a href="#sp-list" data-toggle="modal"
+                                    data-target="#sp-list">张三</a> 审批中</td>
+                            <td class="text-warning">审批中</td>
+                        </tr>
+                        <tr>
+                            <td><a href="yufukuan-qi-detail.html">第2期</a></td>
+                            <td>20%</td>
+                            <td class="text-right">30000.00</td>
+                            <td class="text-right">40000.00</td>
+                            <td class="text-right">70000.00</td>
+                            <td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i
+                                        class="fa fa-paperclip "></i> 3</a></td>
+                            <td class=" text-success"><a href="#sp-list" data-toggle="modal"
+                                    data-target="#sp-list">张三</a> 审批通过</td>
+                            <td class="text-success">审批通过</td>
+                        </tr>
+                        <tr>
+                            <td><a href="yufukuan-qi-detail.html">第1期</a></td>
+                            <td>20%</td>
+                            <td class="text-right">30000.00</td>
+                            <td class="text-right">40000.00</td>
+                            <td class="text-right">70000.00</td>
+                            <td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i
+                                        class="fa fa-paperclip "></i> 3</a></td>
+                            <td class=" text-success"><a href="#sp-list" data-toggle="modal"
+                                    data-target="#sp-list">张三</a> 审批通过</td>
+                            <td class="text-success">审批通过</td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </div>
+    </div>
+</div>
+</div>

+ 187 - 0
app/view/advance/modal.ejs

@@ -0,0 +1,187 @@
+<!--弹出添加期-->
+<div class="modal fade" id="add-qi" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">添加新一期</h5>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <label>调差期</label>
+                    <input class="form-control" value="第 6 期" type="text" readonly="">
+                </div>
+                <div class="form-group">
+                    <label>本期调差,包含计量期<span class="ml-2 text-danger">第<b class="mx-2">9,10</b>期</span></label>
+                    <div class="row">
+                        <div class="col-4">
+                            <div class="custom-control custom-checkbox">
+                                <input type="checkbox" class="custom-control-input" id="customCheck9" checked="">
+                                <label class="custom-control-label" for="customCheck9">第9期</label>
+                            </div>
+                        </div>
+                        <div class="col-4">
+                            <div class="custom-control custom-checkbox">
+                                <input type="checkbox" class="custom-control-input" id="customCheck10">
+                                <label class="custom-control-label" for="customCheck10">第10期</label>
+                            </div>
+                        </div>
+                        <div class="col-4">
+                            <div class="custom-control custom-checkbox">
+                                <input type="checkbox" class="custom-control-input" id="customCheck11">
+                                <label class="custom-control-label" for="customCheck11">第11期</label>
+                            </div>
+                        </div>
+                        <div class="col-4">
+                            <div class="custom-control custom-checkbox">
+                                <input type="checkbox" class="custom-control-input" id="customCheck12">
+                                <label class="custom-control-label" for="customCheck12">第12期</label>
+                            </div>
+                        </div>
+                        <div class="col-4">
+                            <div class="custom-control custom-checkbox">
+                                <input type="checkbox" class="custom-control-input" id="customCheck3">
+                                <label class="custom-control-label" for="customCheck3">第13期</label>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                <button type="button" class="btn btn-primary">确定添加</button>
+            </div>
+        </div>
+    </div>
+</div>
+<!--附件-->
+<div class="modal fade" id="file" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">附件</h5>
+            </div>
+            <div class="modal-body">
+                <div class="modal-height-500">
+                    <table class="table table-sm table-bordered">
+                        <thead>
+                            <tr>
+                                <th>文件名</th>
+                                <th>上传时间</th>
+                                <th>操作</th>
+                            </tr>
+                        </thead>
+                        <tr>
+                            <td>XXXX.jpg</td>
+                            <td>2018-01-01</td>
+                            <td><a href="#" target="_blank" title="下载"><i class="fa fa-download "></i></a></td>
+                        </tr>
+                        <tr>
+                            <td>YYYY.jpg</td>
+                            <td>2018-01-01</td>
+                            <td><a href="#" target="_blank" title="下载"><i class="fa fa-download "></i></a></td>
+                        </tr>
+                    </table>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                <button type="button" class="btn btn-primary">确定</button>
+            </div>
+        </div>
+    </div>
+</div>
+<!--审批流程/结果-->
+<div class="modal fade" id="sp-list" data-backdrop="static">
+    <div class="modal-dialog modal-lg" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">审批流程</h5>
+            </div>
+            <div class="modal-body">
+                <div class="row">
+                    <div class="col-4">
+                        <div class="card mt-3">
+                            <ul class="list-group list-group-flush">
+                                <li class="list-group-item"><i class="fa fa fa-play-circle fa-rotate-90"></i> 布尔 <small
+                                        class="text-muted">施工</small></li>
+                                <li class="list-group-item"><i class="fa fa-chevron-circle-down"></i> 张三 <small
+                                        class="text-muted">监理</small></li>
+                                <li class="list-group-item"><i class="fa fa-chevron-circle-down"></i> 王五 <small
+                                        class="text-muted">监理</small></li>
+                                <li class="list-group-item"><i class="fa fa fa-stop-circle"></i> 李四 <small
+                                        class="text-muted">监理</small></li>
+                            </ul>
+                        </div>
+                    </div>
+                    <div class="col-8 modal-height-500" style="overflow: auto">
+                        <div class="card mt-3">
+                            <ul class="list-group list-group-flush">
+                                <li class="list-group-item">
+                                    <span class="text-success pull-right">上报</span>
+                                    <h5 class="card-title"><i class="fa fa-play-circle fa-rotate-90 text-success"></i>
+                                        布尔 <small class="text-muted">施工</small></h5>
+                                    <p class="card-text">2017-11-25</p>
+                                </li>
+                                <li class="list-group-item">
+                                    <span class="text-success pull-right">审批通过</span>
+                                    <h5 class="card-title"><i class="fa fa-chevron-circle-down text-success"></i> 张三
+                                        <small class="text-muted">监理</small></h5>
+                                    <p class="card-text">审批意见。2017-11-25</p>
+                                </li>
+                                <li class="list-group-item">
+                                    <span class="text-success pull-right">审批通过</span>
+                                    <h5 class="card-title"><i class="fa fa-chevron-circle-down text-success"></i> 王五
+                                        <small class="text-muted">监理</small></h5>
+                                    <p class="card-text">审批通过。2017-11-26</p>
+                                </li>
+                                <li class="list-group-item">
+                                    <span class="text-warning pull-right">审批退回 布尔</span>
+                                    <h5 class="card-title"><i class="fa fa-stop-circle text-warning"></i> 李四 <small
+                                            class="text-muted">监理</small></h5>
+                                    <p class="card-text">审批退回,审批意见文本。2017-11-27</p>
+                                </li>
+                            </ul>
+                        </div>
+                        <!--退回原报重新上报-->
+                        <div class="card mt-3">
+                            <ul class="list-group list-group-flush">
+                                <li class="list-group-item">
+                                    <span class="text-success pull-right">重新上报</span>
+                                    <h5 class="card-title"><i class="fa fa-play-circle fa-rotate-90 text-success"></i>
+                                        布尔 <small class="text-muted">施工</small></h5>
+                                    <p class="card-text">2017-12-01</p>
+                                </li>
+                                <li class="list-group-item">
+                                    <span class="text-success pull-right">审批通过</span>
+                                    <h5 class="card-title"><i class="fa fa-chevron-circle-down text-success"></i> 张三
+                                        <small class="text-muted">监理</small></h5>
+                                    <p class="card-text">审批通过 2017-12-02</p>
+                                </li>
+                                <li class="list-group-item">
+                                    <span class="text-warning pull-right">审批退回 张三</span>
+                                    <h5 class="card-title"><i class="fa fa-chevron-circle-down text-warning"></i> 王五
+                                        <small class="text-muted">监理</small></h5>
+                                    <p class="card-text">审批退回 2017-12-02</p>
+                                </li>
+                                <!--王五退回上一审批人 张三,张三重新审批-->
+                                <li class="list-group-item">
+                                    <span class="pull-right">审批中</span>
+                                    <h5 class="card-title"><i class="fa fa-chevron-circle-down"></i> 张三 <small
+                                            class="text-muted">监理</small></h5>
+                                    <p class="card-text"></p>
+                                </li>
+                                <li class="list-group-item">
+                                    <h5 class="card-title"><i class="fa fa-stop-circle"></i> 李四 <small
+                                            class="text-muted">监理</small></h5>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 1 - 1
app/view/dashboard/index.ejs

@@ -198,7 +198,7 @@
                                                     <div class="row">
                                                         <div class="col-auto"><span class="badge badge-info">台帐审批</span></div>
                                                         <div class="col-6">
-                                                            <a data-id="<%- notice.id %>"href="/tender/<%- notice.tid %>/ledger"><%- notice.name %></a> 台帐<%- acLedger.statusString[notice.status]%>
+                                                            <a data-id="<%- notice.id %>"href="/tender/<%- notice.tid %>/ledger"><%- notice.name %></a> <%- acLedger.statusString[notice.status]%>
                                                         </div>
                                                     </div>
                                                     <p class="mt-1 mb-0"><%- notice.su_name %><small class="ml-1 text-muted"><%- (notice.su_role ? '- ' + notice.su_role : '') %></small>

+ 2 - 0
app/view/profile/wechat.ejs

@@ -37,6 +37,7 @@
                             <input type="hidden" name="_csrf" value="<%= ctx.csrf %>">
                             <% const user_wxType = accountData.wx_type !== '' ? JSON.parse(accountData.wx_type) : null; %>
                             <% for (const s in smsType) { %>
+                            <% if (smsType[s].wechat) { %>
                             <div class="form-group row">
                                 <label class="col-auto col-form-label"><%= smsType[s].name %>
                                     <!--<a href="#sms-view" data-toggle="modal" data-target="#sms-view" class="ml-2"><i class="fa fa-info-circle"></i></a>-->
@@ -51,6 +52,7 @@
                                 </div>
                             </div>
                             <% } %>
+                            <% } %>
                             <input name="type" value="0" type="hidden">
                             <button type="submit" class="btn btn-primary btn-sm">确认修改</button>
                         </form>

+ 3 - 3
app/view/tender/sub_menu.ejs

@@ -2,15 +2,15 @@
     <div class="title-main  d-flex justify-content-between">
         <div>
             <div class="d-inline-block mr-2">
-                <button href="#cate-set" class="btn btn-sm btn-light" data-toggle="modal" data-target="#cate-set"><i class="fa fa-sitemap fa-rotate-270"></i> 分类</button>
-                <button type="button" class="btn btn-sm btn-light dropdown-toggle" data-toggle="dropdown">展开/收起</button>
+                <button href="#cate-set" class="btn btn-sm btn-light text-primary" data-toggle="modal" data-target="#cate-set"><i class="fa fa-sitemap fa-rotate-270"></i> 分类</button>
+                <button type="button" class="btn btn-sm btn-light dropdown-toggle text-primary" data-toggle="dropdown">展开/收起</button>
                 <div class="dropdown-menu">
                     <a class="dropdown-item tree-toggle" href="javascript:void(0);" data-item="open">展开所有</a>
                     <a class="dropdown-item tree-toggle" href="javascript:void(0);" data-item="hide">收起所有</a>
                 </div>
             </div>
             <div class="d-inline-block">
-                <div class="btn-group btn-group-toggle" data-toggle="buttons">
+                <div class="btn-group btn-group-toggle group-tab" data-toggle="buttons">
                     <label class="btn btn-sm btn-light <% if (ctx.url === '/list') { %>active<% } %>" onclick="window.location.href='/list'">
                         <input type="radio" name="options" id="option1" autocomplete="off"> 标段列表
                     </label>

+ 6 - 0
app/view/tender/tender_sub_menu.ejs

@@ -9,6 +9,12 @@
             </ul>
         </div>
         <div class="nav-box">
+            <ul class="nav-list list-unstyled">
+                <% const curUrl = `/tender/${ctx.tender.id}/advance` %>
+                <li <% if (ctx.url.indexOf(curUrl) !== -1) { %>class="active"<% } %>><a href="/tender/<%- ctx.tender.id %>/advance"><i class="fa fa-handshake-o"></i> <span>预付款</span></a></li>
+            </ul>
+        </div>
+        <div class="nav-box">
             <h3><i class="fa fa-list-alt"></i> 0号台帐</h3>
             <ul class="nav-list list-unstyled sub-list">
                 <li <% if (ctx.url === '/tender/' + ctx.tender.id + '/ledger') { %>class="active"<% } %>><a href="/tender/<%- ctx.tender.id %>/ledger"><span>台帐分解</span></a></li>

+ 1 - 1
config/menu.js

@@ -288,7 +288,7 @@ const profileMenu = {
     },
     wechat: {
         name: '微信通知',
-        display: true,
+        display: false,
         url: '/profile/wechat',
     },
     sign: {

+ 41 - 0
sql/update.sql

@@ -38,3 +38,44 @@ CREATE TABLE `zh_s2b_log` (
   `post_time` datetime DEFAULT NULL COMMENT '请求时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+CREATE TABLE `calculation`.`zh_advance_pay` (
+  `id` INT(11) NOT NULL,
+  `pid` INT(11) NOT NULL COMMENT '项目id',
+  `uid` INT(11) NOT NULL COMMENT '创建者id',
+  `status` INT(11) NOT NULL COMMENT '审核状态',
+  `tid` INT(11) NOT NULL COMMENT '标段id',
+  `order` INT(11) NOT NULL COMMENT '期数索引',
+  `pay_ratio` DECIMAL(3,2) NOT NULL COMMENT '支付比例',
+  `cur_amount` DECIMAL(24,8) NOT NULL COMMENT '本期金额',
+  `prev_amount` DECIMAL(24,8) NOT NULL COMMENT '截止上期金额',
+  `prev_total_amount` DECIMAL(24,8) NOT NULL COMMENT '截止本期金额',
+  `create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
+  `type` INT(1) NOT NULL DEFAULT 0 COMMENT '预付款类型,0为开工预付款,1为材料预付款',
+  PRIMARY KEY (`id`))
+COMMENT = '预付款记录';
+
+CREATE TABLE `calculation`.`zh_advance_audit` (
+  `id` INT(11) NOT NULL,
+  `vid` INT(11) NOT NULL COMMENT '预付款记录id',
+  `type` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '预付款类型,0为开工预付款,1为材料预付款',
+  `times` TINYINT(4) NULL DEFAULT NULL COMMENT '审批次数',
+  `audit_order` TINYINT(4) NULL DEFAULT NULL,
+  `audit_id` INT(11) NULL DEFAULT NULL,
+  `status` TINYINT(1) NULL DEFAULT NULL,
+  `begin_time` DATETIME NULL DEFAULT NULL,
+  `end_time` DATETIME NULL DEFAULT NULL,
+  `options` VARCHAR(1000) NULL DEFAULT NULL,
+  PRIMARY KEY (`id`))
+COMMENT = '预付款审核表';
+
+CREATE TABLE `calculation`.`zh_advance_file` (
+  `id` INT(11) NOT NULL,
+  `v_id` INT(11) NOT NULL COMMENT '预付款记录id',
+  `uid` INT(11) NOT NULL COMMENT '上传者id',
+  `in_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '上传时间',
+  `filepath` VARCHAR(255) NOT NULL COMMENT '附件路径',
+  `filesize` VARCHAR(255) NOT NULL COMMENT '附件大小',
+  `filename` VARCHAR(255) NOT NULL COMMENT '附件名字',
+  PRIMARY KEY (`id`))
+COMMENT = '预付款附件';