Browse Source

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

TonyKang 4 years ago
parent
commit
6b9be8d724

+ 444 - 444
app/const/audit.js

@@ -1,444 +1,444 @@
-'use strict';
-
-/**
- *
- *
- * @author Mai
- * @date
- * @version
- */
-// 台账审批流程
-const ledger = (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';
-
-    // 标段概况页
-    // 描述文本
-    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 tiStatusString = [];
-    tiStatusString[status.uncheck] = '未上报';
-    tiStatusString[status.checking] = '审批中';
-    tiStatusString[status.checked] = '审批通过';
-    tiStatusString[status.checkNo] = '审批退回';
-    const tiStatusStringClass = [];
-    tiStatusStringClass[status.uncheck] = '';
-    tiStatusStringClass[status.checking] = 'text-warning';
-    tiStatusStringClass[status.checked] = 'text-success';
-    tiStatusStringClass[status.checkNo] = 'text-warning';
-    return { status, statusString, statusClass, auditString, auditStringClass, tiStatusString, tiStatusStringClass };
-})();
-
-// 台账修订 审批流程
-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';
-
-    // 标段概况页
-    // 描述文本
-    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 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 stage = (function() {
-    // 流程状态
-    const status = {
-        uncheck: 1, // 待上报
-        checking: 2, // 待审批|审批中
-        checked: 3, // 审批通过
-        checkNo: 4, // 审批退回原报
-        checkNoPre: 5, // 审批退回上一人
-        checkAgain: 6, // 重新审批 // 该状态仅可用于,终审退回时,修改原终审的审批状态,并同时新增一条新的终审审批中记录
-    };
-
-    // 流程状态提示
-    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 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 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 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 tiStatusString = [];
-    tiStatusString[status.uncheck] = '待上报';
-    tiStatusString[status.checking] = '审批中';
-    tiStatusString[status.checked] = '审批通过';
-    tiStatusString[status.checkNo] = '审批退回';
-    tiStatusString[status.checkNoPre] = '审批中';
-    tiStatusString[status.checkAgain] = '审批中';
-    const tiStatusStringClass = [];
-    tiStatusStringClass[status.uncheck] = '';
-    tiStatusStringClass[status.checking] = 'text-warning';
-    tiStatusStringClass[status.checked] = 'text-success';
-    tiStatusStringClass[status.checkNo] = 'text-warning';
-    tiStatusStringClass[status.checkNoPre] = 'text-warning';
-    tiStatusStringClass[status.checkAgain] = 'text-warning';
-    const backType = {
-        org: 1,
-        pre: 2,
-    };
-    return {
-        status, statusString, statusClass,
-        statusButton, statusButtonClass,
-        auditString, auditStringClass,
-        auditProgress, auditProgressClass,
-        backType,
-        timesLen: 100,
-        tiStatusString, tiStatusStringClass
-    };
-})();
-
-// 变更令状态
-const status = {
-    uncheck: 1, // 待上报
-    checking: 2, // 审批中
-    checked: 3, // 审批完成
-    // checkNo: 4,     // 审批终止
-    back: 5, // 重新上报
-    backnew: 6, // 退回
-};
-const statusButton = [];
-statusButton[status.uncheck] = '上报';
-statusButton[status.checking] = '审批';
-statusButton[status.checked] = '';
-// statusButton[status.checkNo] = '';
-statusButton[status.back] = '重新上报';
-statusButton[status.backnew] = '审批';
-
-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';
-
-const statusString = [];
-statusString[status.uncheck] = '';
-statusString[status.checking] = '审批中';
-statusString[status.checked] = '审批通过';
-// statusString[status.checkNo] = '终止';
-statusString[status.back] = '审批退回';
-statusString[status.backnew] = '审批退回';
-
-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';
-
-/* ------------------------------------------------------- */
-
-// 变更令审批人状态
-const auditStatus = {
-    uncheck: 1, // 待审批
-    checking: 2, // 审批中或者原报人待上报
-    checked: 3, // 审批通过或者原报人上报完成
-    // checkNo: 4,     // 审批终止
-    back: 5, // 退回到原报人重新上报
-    backnew: 6, // 退回到上一个审批人
-    checkAgain: 7, // 重新审批
-};
-
-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';
-// auditStatusClass[auditStatus.checkNo] = 'text-danger';
-auditStatusClass[auditStatus.back] = 'text-warning';
-auditStatusClass[auditStatus.backnew] = 'text-warning';
-auditStatusClass[auditStatus.checkAgain] = 'text-warning';
-
-/* ------------------------------------------------------- */
-
-const filter = {
-    status: {
-        pending: 1,
-        uncheck: 5,
-        checking: 2,
-        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] = '已完成';
-// filter.statusString[filter.status.checkNo] = '终止';
-
-// 材料调差审批流程
-const material = (function() {
-    const status = {
-        uncheck: 1, // 待上报
-        checking: 2, // 待审批|审批中
-        checked: 3, // 审批通过
-        checkNo: 4, // 审批退回原报
-        checkNoPre: 5, // 审批退回上一人
-        checkAgain: 6, // 终审退回  --该状态仅可用于,终审退回时,修改原终审的审批状态,并同时新增一条新的终审审批中记录
-    };
-    // 流程状态提示
-    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 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 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 advance = (function() {
-    const type = {
-        start: 0,
-        material: 1,
-    };
-
-    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] = '审批退回';
-    statusString[status.checkNoPre] = '审批退回';
-
-    const statusClass = [];
-    statusClass[status.uncheck] = '';
-    statusClass[status.checking] = 'text-warning';
-    statusClass[status.checked] = 'text-success';
-    statusClass[status.checkNo] = 'text-warning';
-    statusClass[status.checkNoPre] = '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 { type, status, statusString, statusClass, auditString, auditStringClass };
-})();
-// 推送类型
-const pushType = {
-    material: 1,
-    stage: 2,
-    change: 3,
-    revise: 4,
-    ledger: 5,
-    advance: 6,
-};
-
-module.exports = {
-    ledger,
-    stage,
-    revise,
-    material,
-    flow: {
-        status,
-        statusString,
-        statusButton,
-        statusButtonClass,
-        statusClass,
-        auditStatus,
-        auditStatusString,
-        auditStatusClass,
-    },
-    filter,
-    pushType,
-    advance,
-};
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+// 台账审批流程
+const ledger = (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';
+
+    // 标段概况页
+    // 描述文本
+    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 tiStatusString = [];
+    tiStatusString[status.uncheck] = '未上报';
+    tiStatusString[status.checking] = '审批中';
+    tiStatusString[status.checked] = '审批通过';
+    tiStatusString[status.checkNo] = '审批退回';
+    const tiStatusStringClass = [];
+    tiStatusStringClass[status.uncheck] = '';
+    tiStatusStringClass[status.checking] = 'text-warning';
+    tiStatusStringClass[status.checked] = 'text-success';
+    tiStatusStringClass[status.checkNo] = 'text-warning';
+    return { status, statusString, statusClass, auditString, auditStringClass, tiStatusString, tiStatusStringClass };
+})();
+
+// 台账修订 审批流程
+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';
+
+    // 标段概况页
+    // 描述文本
+    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 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 stage = (function() {
+    // 流程状态
+    const status = {
+        uncheck: 1, // 待上报
+        checking: 2, // 待审批|审批中
+        checked: 3, // 审批通过
+        checkNo: 4, // 审批退回原报
+        checkNoPre: 5, // 审批退回上一人
+        checkAgain: 6, // 重新审批 // 该状态仅可用于,终审退回时,修改原终审的审批状态,并同时新增一条新的终审审批中记录
+    };
+
+    // 流程状态提示
+    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 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 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 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 tiStatusString = [];
+    tiStatusString[status.uncheck] = '待上报';
+    tiStatusString[status.checking] = '审批中';
+    tiStatusString[status.checked] = '审批通过';
+    tiStatusString[status.checkNo] = '审批退回';
+    tiStatusString[status.checkNoPre] = '审批中';
+    tiStatusString[status.checkAgain] = '审批中';
+    const tiStatusStringClass = [];
+    tiStatusStringClass[status.uncheck] = '';
+    tiStatusStringClass[status.checking] = 'text-warning';
+    tiStatusStringClass[status.checked] = 'text-success';
+    tiStatusStringClass[status.checkNo] = 'text-warning';
+    tiStatusStringClass[status.checkNoPre] = 'text-warning';
+    tiStatusStringClass[status.checkAgain] = 'text-warning';
+    const backType = {
+        org: 1,
+        pre: 2,
+    };
+    return {
+        status, statusString, statusClass,
+        statusButton, statusButtonClass,
+        auditString, auditStringClass,
+        auditProgress, auditProgressClass,
+        backType,
+        timesLen: 100,
+        tiStatusString, tiStatusStringClass,
+    };
+})();
+
+// 变更令状态
+const status = {
+    uncheck: 1, // 待上报
+    checking: 2, // 审批中
+    checked: 3, // 审批完成
+    // checkNo: 4,     // 审批终止
+    back: 5, // 重新上报
+    backnew: 6, // 退回
+};
+const statusButton = [];
+statusButton[status.uncheck] = '上报';
+statusButton[status.checking] = '审批';
+statusButton[status.checked] = '';
+// statusButton[status.checkNo] = '';
+statusButton[status.back] = '重新上报';
+statusButton[status.backnew] = '审批';
+
+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';
+
+const statusString = [];
+statusString[status.uncheck] = '未上报';
+statusString[status.checking] = '审批中';
+statusString[status.checked] = '审批通过';
+// statusString[status.checkNo] = '终止';
+statusString[status.back] = '审批退回';
+statusString[status.backnew] = '审批退回';
+
+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';
+
+/* ------------------------------------------------------- */
+
+// 变更令审批人状态
+const auditStatus = {
+    uncheck: 1, // 待审批
+    checking: 2, // 审批中或者原报人待上报
+    checked: 3, // 审批通过或者原报人上报完成
+    // checkNo: 4,     // 审批终止
+    back: 5, // 退回到原报人重新上报
+    backnew: 6, // 退回到上一个审批人
+    checkAgain: 7, // 重新审批
+};
+
+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';
+// auditStatusClass[auditStatus.checkNo] = 'text-danger';
+auditStatusClass[auditStatus.back] = 'text-warning';
+auditStatusClass[auditStatus.backnew] = 'text-warning';
+auditStatusClass[auditStatus.checkAgain] = 'text-warning';
+
+/* ------------------------------------------------------- */
+
+const filter = {
+    status: {
+        pending: 1,
+        uncheck: 5,
+        checking: 2,
+        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] = '已完成';
+// filter.statusString[filter.status.checkNo] = '终止';
+
+// 材料调差审批流程
+const material = (function() {
+    const status = {
+        uncheck: 1, // 待上报
+        checking: 2, // 待审批|审批中
+        checked: 3, // 审批通过
+        checkNo: 4, // 审批退回原报
+        checkNoPre: 5, // 审批退回上一人
+        checkAgain: 6, // 终审退回  --该状态仅可用于,终审退回时,修改原终审的审批状态,并同时新增一条新的终审审批中记录
+    };
+    // 流程状态提示
+    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 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 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 advance = (function() {
+    const type = {
+        start: 0,
+        material: 1,
+    };
+
+    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] = '审批退回';
+    statusString[status.checkNoPre] = '审批退回';
+
+    const statusClass = [];
+    statusClass[status.uncheck] = '';
+    statusClass[status.checking] = 'text-warning';
+    statusClass[status.checked] = 'text-success';
+    statusClass[status.checkNo] = 'text-warning';
+    statusClass[status.checkNoPre] = '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 { type, status, statusString, statusClass, auditString, auditStringClass };
+})();
+// 推送类型
+const pushType = {
+    material: 1,
+    stage: 2,
+    change: 3,
+    revise: 4,
+    ledger: 5,
+    advance: 6,
+};
+
+module.exports = {
+    ledger,
+    stage,
+    revise,
+    material,
+    flow: {
+        status,
+        statusString,
+        statusButton,
+        statusButtonClass,
+        statusClass,
+        auditStatus,
+        auditStatusString,
+        auditStatusClass,
+    },
+    filter,
+    pushType,
+    advance,
+};

+ 29 - 0
app/controller/change_controller.js

@@ -269,6 +269,9 @@ module.exports = app => {
                 // 获取附件列表
                 const attList = await ctx.service.changeAtt.getChangeAttachment(ctx.params.cid);
 
+                // 获取其他变更令数据
+                const othersChange = await ctx.service.change.getOthersChange(ctx.params.id, ctx.params.cid);
+
                 // 根据auditStatus获取审批人列表
                 const auditList = await ctx.service.changeAudit.getListByStatus(change, auditStatus);
                 // 获取已选清单
@@ -281,6 +284,7 @@ module.exports = app => {
                     uid: ctx.session.sessionUser.accountId,
                     tender,
                     change,
+                    othersChange,
                     changeConst,
                     auditStatus,
                     auditConst: audit.flow,
@@ -968,6 +972,31 @@ module.exports = app => {
 
             ctx.body = responseData;
         }
+
+        /**
+         * 拷贝其他变更令
+         * @param {object} ctx - 全局上下文
+         */
+        async copyChange(ctx) {
+            const responseData = {
+                err: 0,
+                msg: '',
+                data: '',
+            };
+            try {
+                const cid = ctx.params.cid;
+                const copy_cid = JSON.parse(ctx.request.body.data);
+                const result = await ctx.service.change.handleCopyChange(cid, copy_cid);
+                if (!result) {
+                    responseData.err = 1;
+                    responseData.msg = '拷贝失败!';
+                }
+            } catch (error) {
+                responseData.err = 1;
+                responseData.msg = error;
+            }
+            ctx.body = responseData;
+        }
     }
 
     return ChangeController;

+ 28 - 2
app/controller/tender_controller.js

@@ -754,6 +754,7 @@ module.exports = app => {
                 const groupList = accountList.filter(item => item.account_group === idx);
                 return { groupName: item, groupList };
             });
+            // 获取固定审批流 or 固定终审
             for (const sp of shenpiConst.sp_lc) {
                 sp.status = ctx.tender.info.shenpi ? ctx.tender.info.shenpi[sp.code] : shenpiConst.sp_status.sqspr;
                 if (sp.status === shenpiConst.sp_status.gdspl) {
@@ -762,13 +763,32 @@ module.exports = app => {
                     sp.audit = await ctx.service.shenpiAudit.getAudit(ctx.tender.id, sp.type, sp.status);
                 }
             }
-            // 获取固定审批流 or 固定终审
+            const tenders = await ctx.service.tender.getList('', null, 1);
+            for (const tender of tenders) {
+                tender.shenpiInfo = await ctx.service.tenderInfo.getTenderShenpiInfo(tender.id);
+                // 获取所有的固定审批流或固定终审
+                const shenpiauditList = {};
+                for (const shenpi in tender.shenpiInfo) {
+                    if (tender.shenpiInfo[shenpi] === shenpiConst.sp_status.gdspl) {
+                        const shenpiList = await ctx.service.shenpiAudit.getAllDataByCondition({ where: { tid: tender.id, sp_type: shenpiConst.sp_type[shenpi], sp_status: tender.shenpiInfo[shenpi] } });
+                        const shenpiIdList = ctx.helper._.map(shenpiList, 'audit_id');
+                        shenpiauditList[shenpi] = shenpiIdList.length ? shenpiIdList : null;
+                    } else if (tender.shenpiInfo[shenpi] === shenpiConst.sp_status.gdzs) {
+                        const shenpiInfo = await ctx.service.shenpiAudit.getDataByCondition({ tid: tender.id, sp_type: shenpiConst.sp_type[shenpi], sp_status: tender.shenpiInfo[shenpi] });
+                        shenpiauditList[shenpi] = shenpiInfo && shenpiInfo.audit_id ? [shenpiInfo.audit_id] : null;
+                    }
+                }
+                tender.shenpiauditList = shenpiauditList;
+            }
+            const categoryData = await ctx.service.category.getAllCategory(ctx.session.sessionProject.id);
             const renderData = {
                 shenpi: shenpiConst,
                 accountList,
                 accountGroup: accountGroupList,
+                tenders,
+                categoryData,
             };
-            await this._list('tender/shenpi.ejs', renderData);
+            await this._list('tender/shenpi.ejs', renderData, 'tender/shenpi_modal.ejs');
         }
 
         async saveTenderInfoShenpi(ctx) {
@@ -829,6 +849,12 @@ module.exports = app => {
                     case 'del':
                         await ctx.service.shenpiAudit.removeAudit(data);
                         break;
+                    case 'copy2ot':
+                        await ctx.service.shenpiAudit.copyAudit2otherTender(data);
+                        break;
+                    case 'copy2os':
+                        await ctx.service.shenpiAudit.copyAudit2otherShenpi(data);
+                        break;
                     default:break;
                 }
                 ctx.body = { err: 0, msg: '' };

+ 16 - 0
app/public/js/change_detail.js

@@ -49,6 +49,22 @@ $(document).ready(() => {
             $('#bills').removeClass('first-bill-pane');
         }
     });
+
+    $('#add-bj').on('click', 'input[type="checkbox"]', function () {
+        const isCheck = $(this).prop('checked')
+        if (isCheck) {
+            $('#add-bj input[type="checkbox"]').each(function () {
+                $(this).prop('checked', false)
+            })
+            $(this).prop('checked', true)
+        }
+    })
+    $('#bg-copy').click(function() {
+        const cid = $('#add-bj input:checked').data('id')
+        postData(window.location.pathname + '/copy', cid, function () {
+            window.location.reload()
+        })
+    })
     // 上传附件
     $('#upload-file-btn').click(function () {
         const files = $('#upload-file')[0].files;

+ 30 - 29
app/public/js/revise_compare.js

@@ -58,6 +58,7 @@ $(document).ready(() => {
     }
 
     posSpreadSetting.getColor = function (sheet, data, row, col, defaultColor) {
+        if (!data || !data.differ) return defaultColor;
         // 增
         if (data.differ.indexOf('add') >= 0) return '#ffddc5';
         // 删
@@ -149,6 +150,34 @@ $(document).ready(() => {
             for (const data of tree.datas) {
                 data.differ = [];
                 data.differ_str = [];
+                for (const p of data.pos) {
+                    p.differ = [];
+                    p.differ_str = [];
+                    if (p.isNew && !p.isOrg) {
+                        p.differ.push('add');
+                        if (data.differ.indexOf('pos-add') === -1) data.differ.push('pos-add');
+                        p.differ_str.push('增');
+                    } else if (!p.isNew && p.isOrg) {
+                        p.differ.push('del');
+                        if (data.differ.indexOf('pos-del') === -1) data.differ.push('pos-del');
+                        p.differ_str.push('删');
+                    } else {
+                        const orgPosCalc = getCompare(p, compareFields.posCalc, 'org_', 0);
+                        const newPosCalc = getCompare(p, compareFields.posCalc, 'new_', 0);
+                        if (!_.isMatch(orgPosCalc, newPosCalc)) {
+                            p.differ.push('calc');
+                            if (data.differ.indexOf('pos-calc') === -1) data.differ.push('pos-calc');
+                            p.differ_str.push('量改');
+                        }
+                        const orgPosInfo = getCompare(p, compareFields.posInfo, 'org_', 0);
+                        const newPosInfo = getCompare(p, compareFields.posInfo, 'new_', 0);
+                        if (!_.isMatch(orgPosInfo, newPosInfo)) {
+                            p.differ.push('info');
+                            if (data.differ.indexOf('pos-info') === -1) data.differ.push('pos-info');
+                            p.differ_str.push('文改');
+                        }
+                    }
+                }
                 if (data.isNew && !data.isOrg) {
                     data.differ.push('add');
                     data.differ_str.push('增');
@@ -164,40 +193,12 @@ $(document).ready(() => {
                     } else {
                         const orgCalc = getCompare(data, compareFields.parentCalc, 'org_', 0);
                         const newCalc = getCompare(data, compareFields.parentCalc, 'new_', 0);
-                        if (!_.isMatch(newCalc, orgCalc)) data.push('calc');
+                        if (!_.isMatch(newCalc, orgCalc)) data.differ.push('calc');
                     }
                     const orgInfo = getCompare(data, compareFields.info, 'org_', '');
                     const newInfo = getCompare(data, compareFields.info, 'new_', '');
                     if (!_.isMatch(newInfo, orgInfo)) data.differ.push('info');
 
-                    for (const p of data.pos) {
-                        p.differ = [];
-                        p.differ_str = [];
-                        if (p.isNew && !p.isOrg) {
-                            p.differ.push('add');
-                            if (data.differ.indexOf('pos-add') === -1) data.differ.push('pos-add');
-                            p.differ_str.push('增');
-                        } else if (!p.isNew && p.isOrg) {
-                            p.differ.push('del');
-                            if (data.differ.indexOf('pos-del') === -1) data.differ.push('pos-del');
-                            p.differ_str.push('删');
-                        } else {
-                            const orgPosCalc = getCompare(p, compareFields.posCalc, 'org_', 0);
-                            const newPosCalc = getCompare(p, compareFields.posCalc, 'new_', 0);
-                            if (!_.isMatch(orgPosCalc, newPosCalc)) {
-                                p.differ.push('calc');
-                                if (data.differ.indexOf('pos-calc') === -1) data.differ.push('pos-calc');
-                                p.differ_str.push('量改');
-                            }
-                            const orgPosInfo = getCompare(p, compareFields.posInfo, 'org_', 0);
-                            const newPosInfo = getCompare(p, compareFields.posInfo, 'new_', 0);
-                            if (!_.isMatch(orgPosInfo, newPosInfo)) {
-                                p.differ.push('info');
-                                if (data.differ.indexOf('pos-info') === -1) data.differ.push('pos-info');
-                                p.differ_str.push('文改');
-                            }
-                        }
-                    }
                     if (data.differ.length > 0) data.differ_str.push('改');
                 }
             }

+ 13 - 3
app/public/js/revise_gcl_compare.js

@@ -32,6 +32,7 @@ const showTools = function (show) {
 };
 
 $(document).ready(() => {
+    let compareTag = $('input[name=compareTag]:checked').val();
     showTools(true);
     autoFlashHeight();
     const gclSpread = SpreadJsObj.createNewSpread($('#gcl-spread')[0]);
@@ -61,9 +62,14 @@ $(document).ready(() => {
             colWidth: true,
         },
         getColor: function (sheet, data, row, col, defaultColor) {
-            return data
-                ? (data.differ ? '#FFE699' : '#ffffff')
-                : '#ffffff';
+            if (!data) return '#ffffff';
+            // if ((col.field === 'deal_bills_qty' || col.field === 'deal_bills_tp') && data.deal_differ_qty)
+            //     return '#f8d7da';
+            // if ((col.field === 'org_quantity' || col.field === 'org_total_price') && data.differ_qty)
+            //     return '#f8d7da';
+            if (compareTag === 'deal' && data.deal_differ_qty) return '#f8d7da';
+            if (compareTag === 'org' && data.differ_qty) return '#f8d7da';
+            return data.differ ? '#FFE699' : '#ffffff';
         }
     };
     if (thousandth) sjsSettingObj.setTpThousandthFormat(gclSpreadSetting);
@@ -217,4 +223,8 @@ $(document).ready(() => {
             leafXmjSpread.refresh();
         }
     });
+    $('input[name=compareTag]').change(() => {
+        compareTag = $('input[name=compareTag]:checked').val();
+        SpreadJsObj.reLoadSheetData(gclSheet);
+    });
 });

+ 42 - 4
app/public/js/shares/gcl_gather_compare.js

@@ -356,6 +356,39 @@ const gclCompareModel = (function () {
         ledgerSetting = null;
     }
 
+    function compareCode(str1, str2, symbol = '-') {
+        if (!str1) {
+            return 1;
+        } else if (!str2) {
+            return -1;
+        }
+
+        function compareSubCode(code1, code2) {
+            if (numReg.test(code1)) {
+                if (numReg.test(code2)) {
+                    return parseInt(code1) - parseInt(code2);
+                } else {
+                    return -1
+                }
+            } else {
+                if (numReg.test(code2)) {
+                    return 1;
+                } else {
+                    return code1 === code2 ? 0 : (code1 < code2 ? -1 : 1); //code1.localeCompare(code2);
+                }
+            }
+        }
+        const numReg = /^[0-9]+$/;
+        const aCodes = str1.split(symbol), bCodes = str2.split(symbol);
+        for (let i = 0, iLength = Math.min(aCodes.length, bCodes.length); i < iLength; ++i) {
+            const iCompare = compareSubCode(aCodes[i], bCodes[i]);
+            if (iCompare !== 0) {
+                return iCompare;
+            }
+        }
+        return aCodes.length - bCodes.length;
+    }
+
     /**
      *
      * @param data {Array} - 签约清单数据
@@ -366,17 +399,17 @@ const gclCompareModel = (function () {
             for (const node of data) {
                 node.b_code = node.code;
                 const gcl = getGclNode(node);
-                if (!d.quantity || !d.unit_price) continue;
+                if (!node.quantity || !node.unit_price) continue;
                 gcl.deal_bills_qty = node.quantity || 0;
                 gcl.deal_bills_tp = node.total_price || 0;
 
                 for (const c of otherChapter) {
                     if (c.cType === 41 || c.cType === 11) {
-                        c.deal_bills_tp = ZhCalc.add(c.deal_bills_tp, d.total_price);
+                        c.deal_bills_tp = ZhCalc.add(c.deal_bills_tp, node.total_price);
                     }
                 }
-                const c = _getGclChapter(gclChapter, d);
-                c.deal_bills_tp = ZhCalc.add(c.deal_bills_tp, d.total_price);
+                const c = _getGclChapter(gclChapter, node);
+                c.deal_bills_tp = ZhCalc.add(c.deal_bills_tp, node.total_price);
             }
         }
     }
@@ -385,10 +418,15 @@ const gclCompareModel = (function () {
      * 检查汇总完的工程量清单中,同编号 & 不同名称/单位/单价 的清单并标记
      */
     function checkDiffer() {
+        gclList.sort((a, b) => {
+            return compareCode(a.b_code, b.b_code);
+        });
         for (const gcl of gclList) {
             gcl.differ = false;
         }
         for (const [i, gcl] of gclList.entries()) {
+            gcl.differ_qty = ZhCalc.sub(gcl.new_quantity, gcl.org_quantity, 6);
+            gcl.deal_differ_qty = ZhCalc.sub(gcl.new_quantity, gcl.deal_bills_qty, 6);
             if (i === gclList.length - 1) continue;
             const next = gclList[i+1];
             if (gcl.b_code === next.b_code) {

+ 305 - 6
app/public/js/shenpi.js

@@ -7,7 +7,208 @@
  * @date 2020/10/09
  * @version
  */
+const tenderTree = [];
+let parentId = 0;
+// 查询方法
+function findNode (key, value, arr) {
+    for (const a of arr) {
+        if (a[key] && a[key] === value) {
+            return a;
+        }
+    }
+}
+// 初始化TenderTree数据
+function initTenderTree () {
+    const levelCategory = category.filter(function (c) {
+        return c.level && c.level > 0;
+    });
+    function findCategoryNode(cid, value, array) {
+        for (const a of array) {
+            if (a.cid === cid && a.vid === value) {
+                return a;
+            }
+        }
+    }
+    function getCategoryNode(category, value, parent, i = null) {
+        const array = parent ?  parent.children : tenderTree;
+        let cate = findCategoryNode(category.id, value, array);
+        if (!cate) {
+            const cateValue = findNode('id', value, category.value);
+            if (!cateValue) return null;
+            cate = {
+                cid: category.id,
+                vid: value,
+                name: cateValue.value,
+                children: [],
+                level: i ? i : category.level,
+                sort_id: ++parentId,
+            };
+            array.push(cate);
+        }
+        return cate;
+    }
+    function loadTenderCategory (tender) {
+        let tenderCategory = null;
+        for (const [index,lc] of levelCategory.entries()) {
+            const tenderCate = findNode('cid', lc.id, tender.category);
+            if (tenderCate) {
+                tenderCategory = getCategoryNode(lc, tenderCate.value, tenderCategory);
+            } else {
+                if (index === 0 && tender.category) {
+                    for (const [i,c] of tender.category.entries()) {
+                        const cate = findNode('id', c.cid, category);
+                        tenderCategory = getCategoryNode(cate, c.value, tenderCategory, i+1);
+                    }
+                }
+                return tenderCategory;
+            }
+        }
+        return tenderCategory;
+    }
+    function calculateTender(tender) {
+        if (tender.lastStage) {
+            tender.gather_tp = ZhCalc.add(tender.lastStage.contract_tp, tender.lastStage.qc_tp);
+            tender.end_contract_tp = ZhCalc.add(tender.lastStage.pre_contract_tp, tender.lastStage.contract_tp);
+            tender.end_qc_tp = ZhCalc.add(tender.lastStage.pre_qc_tp, tender.lastStage.qc_tp);
+            tender.end_gather_tp = ZhCalc.add(tender.end_contract_tp, tender.end_qc_tp);
+            tender.pre_gather_tp = ZhCalc.add(tender.lastStage.pre_contract_tp, tender.lastStage.pre_qc_tp);
+            tender.yf_tp = ZhCalc.add(tender.lastStage.yf_tp);
+            tender.end_yf_tp = ZhCalc.add(tender.lastStage.pre_yf_tp, tender.yf_tp);
+        }
+    }
+    tenderTree.splice(0, tenderTree.length);
+    for (const t of tenders) {
+        calculateTender(t);
+        t.valid = true;
+        delete t.level;
+        if (t.category && levelCategory.length > 0) {
+            const parent = loadTenderCategory(t);
+            if (parent) {
+                t.level = parent.level + 1;
+                parent.children.push(t);
+            } else {
+                tenderTree.push(t);
+            }
+        } else {
+            tenderTree.push(t);
+        }
+    }
+}
+function recursiveGetTenderNodeHtml (node, arr, pid, this_code, this_status, aidList = []) {
+    const html = [];
+    html.push('<tr pid="' + pid + '">');
+    // 名称
+    html.push('<td class="in-' + node.level + '">');
+    if (node.cid) {
+        html.push('<i class="fa fa-folder-o"></i> ', node.name);
+    } else {
+        html.push('<span class="text-muted mr-2">');
+        html.push(arr.indexOf(node) === arr.length - 1 ? '└' : '├');
+        html.push('</span>');
+        //html.push('<a href="/tender/' + node.id + '">', node[c.field], '</a>');
+        html.push('<a href="javascript: void(0)" id="' + node.id + '">', node.name, '</a>');
+    }
+    html.push('</td>');
+    // 创建人
+    // html.push('<td>', sp_status_list[node.shenpiInfo[shenpi_type]].name, '</td>');
+    html.push('<td>');
+    if (!node.cid) {
+        let auditList = [];
+        let tender_status = 1;
+        if(cur_tenderid === node.id) {
+            html.push(sp_status_list[this_status].name);
+            auditList = aidList;
+            tender_status = this_status;
+        } else {
+            html.push(sp_status_list[node.shenpiInfo[this_code]].name);
+            auditList = node.shenpiauditList[this_code];
+            tender_status = node.shenpiInfo[this_code];
+        }
+        if(tender_status === sp_status.gdspl || tender_status === sp_status.gdzs) {
+            const nameList = [];
+            if(auditList) {
+                for (const uid of auditList) {
+                    const user = _.find(accountList, { id: uid });
+                    nameList.push(user.name);
+                }
+            }
+            html.push('<i class="fa fa-question-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" ' +
+                'data-original-title="'+ (nameList.length > 0 ? nameList.join('-') : '') +'"></i>');
+        }
+    }
+    html.push('</td>');
+    html.push('<td>');
+    if (!node.cid) {
+        html.push('<input data-tid="'+ node.id +'" type="checkbox"'+ (cur_tenderid === node.id ? ' checked disabled' : '') +'>');
+    }
+    html.push('</td>');
+    html.push('</tr>');
+    if (node.children) {
+        for (const c of node.children) {
+            html.push(recursiveGetTenderNodeHtml(c, node.children, node.sort_id, this_code, this_status, aidList));
+        }
+    }
+    return html.join('');
+}
+// 根据TenderTree数据获取Html代码
+function getTenderTreeHtml (this_code, this_status, aidList = []) {
+    if (tenderTree.length > 0) {
+        const html = [];
+        html.push('<table class="table table-hover table-bordered">');
+        html.push('<thead>', '<tr>');
+        html.push('<th>名称</th>');
+        html.push('<th width="100">审批流程</th>');
+        html.push('<th width="40">选择</th>');
+        html.push('</tr>', '</thead>');
+        parentId = 0;
+        for (const t of tenderTree) {
+            html.push(recursiveGetTenderNodeHtml(t, tenderTree, '', this_code, this_status, aidList));
+        }
+        html.push('</table>');
+        return html.join('');
+    } else {
+        return EmptyTenderHtml.join('');
+    }
+}
 
+function getShenpiHtml (this_code) {
+    const html = [];
+    html.push('<table class="table table-hover table-bordered">');
+    html.push('<thead>', '<tr>');
+    html.push('<th>名称</th>');
+    html.push('<th width="100">审批流程</th>');
+    html.push('<th width="40">选择</th>');
+    html.push('</tr>', '</thead>');
+    for (const sp of sp_lc) {
+        html.push('<tr>');
+        html.push('<td>', sp.name, '</td>');
+        html.push('<td>');
+        html.push(sp_status_list[sp.status].name);
+        const this_status = parseInt($('.' + sp.code + '_div').children('.lc-show').siblings('.form-group').find('input:checked').val());
+        if(this_status != sp_status.sqspr) {
+            const nameList = [];
+            const aid_num = $('.' + sp.code + '_div').children('.lc-show').children('ul').find('.remove-audit').length;
+            const aidList = [];
+            for (let i = 0; i < aid_num; i++) {
+                const aid = parseInt($('.' + sp.code + '_div').children('.lc-show').children('ul').find('.remove-audit').eq(i).data('id'));
+                aidList.push(aid);
+            }
+            if(aidList.length > 0) {
+                for (const uid of aidList) {
+                    const user = _.find(accountList, { id: uid });
+                    nameList.push(user.name);
+                }
+            }
+            html.push('<i class="fa fa-question-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" ' +
+                'data-original-title="'+ (nameList.length > 0 ? nameList.join('-') : '') +'"></i>');
+        }
+        html.push('</td>');
+        html.push('<td>', this_code !== sp.code ? '<input type="checkbox" data-code="'+ sp.code +'">' : '', '</td>');
+        html.push('</tr>');
+    }
+    html.push('</table>');
+    return html.join('');
+}
 $(document).ready(function () {
     let timer = null;
     let oldSearchVal = null;
@@ -86,8 +287,7 @@ $(document).ready(function () {
             status: this_status
         };
         const _self = $(this);
-        const tenderId = window.location.pathname.split('/')[2];
-        postData('/tender/' + tenderId + '/shenpi/save', prop, function (data) {
+        postData('/tender/' + cur_tenderid + '/shenpi/save', prop, function (data) {
             if (this_status === sp_status.sqspr) {
                 _self.parents('.form-group').siblings('.lc-show').html('');
             } else if (this_status === sp_status.gdspl) {
@@ -145,8 +345,7 @@ $(document).ready(function () {
                 type: 'add',
             };
             const _self = $(this);
-            const tenderId = window.location.pathname.split('/')[2];
-            postData('/tender/' + tenderId + '/shenpi/audit/save', prop, function (data) {
+            postData('/tender/' + cur_tenderid + '/shenpi/audit/save', prop, function (data) {
                 if (this_status === sp_status.gdspl) {
                     _self.parents('ul').append('<li class="pl-3"><a href="javascript:void(0);" class="add-audit"><i class="fa fa-plus"></i> 添加流程</a></li>');
                 }
@@ -168,8 +367,7 @@ $(document).ready(function () {
             type: 'del',
         };
         const _self = $(this);
-        const tenderId = window.location.pathname.split('/')[2];
-        postData('/tender/' + tenderId + '/shenpi/audit/save', prop, function (data) {
+        postData('/tender/' + cur_tenderid + '/shenpi/audit/save', prop, function (data) {
             if (this_status === sp_status.gdspl) {
                 const _selflc = _self.parents('.lc-show');
                 _self.parents('li').remove();
@@ -257,4 +455,105 @@ $(document).ready(function () {
             '                                        </li>';
         return html;
     }
+
+
+    initTenderTree();
+
+    $('.set-otherTender').on('click', function () {
+        const this_code = $(this).data('code');
+        const this_status = parseInt($(this).siblings('.lc-show').siblings('.form-group').find('input:checked').val());
+        const aid_num = $(this).siblings('.lc-show').children('ul').find('.remove-audit').length;
+        const aidList = [];
+        for (let i = 0; i < aid_num; i++) {
+            const aid = parseInt($(this).siblings('.lc-show').children('ul').find('.remove-audit').eq(i).data('id'));
+            aidList.push(aid);
+        }
+        const html = getTenderTreeHtml(this_code, this_status, aidList);
+        $('#shenpi-name').text($(this).data('name'));
+        $('#shenpi_code').val(this_code);
+        $('#shenpi_status').val(this_status);
+        $('#shenpi_auditors').val(aidList.join(','));
+        $('#tender-list').html(html);
+        setTimeout(function () { $("#tender-list [data-toggle='tooltip']").tooltip(); },800);
+    });
+
+    $('#save-other-tender').click(function () {
+        $(this).attr('disabled', true);
+        const num = $('#tender-list input:checked').length;
+        if (num < 2) {
+            toastr.warning('请选择需要设置审批同步的标段');
+            return;
+        }
+        const data = {
+            type: 'copy2ot',
+            status: parseInt($('#shenpi_status').val()),
+            code: $('#shenpi_code').val(),
+        };
+        if(data.status !== shenpi_status.gdspl) {
+            data.aidList = $('#shenpi_auditors').val();
+        }
+        // 获取已选中的标段
+        const tenderList = [];
+        for (let i = 0; i < num; i++) {
+            const tid = parseInt($('#tender-list input:checked').eq(i).data('tid'));
+            if (tid !== cur_tenderid) {
+                tenderList.push(tid);
+            }
+        }
+        data.tidList = tenderList.join(',');
+        postData('/tender/' + cur_tenderid + '/shenpi/audit/save', data, function () {
+            toastr.success('设置成功');
+            setTimeout(function () {
+                window.location.reload();
+            }, 1000)
+        })
+    });
+
+    $('.set-otherShenpi').on('click', function () {
+        const this_code = $(this).data('code');
+        const this_status = parseInt($(this).siblings('.lc-show').siblings('.form-group').find('input:checked').val());
+        const aid_num = $(this).siblings('.lc-show').children('ul').find('.remove-audit').length;
+        const aidList = [];
+        for (let i = 0; i < aid_num; i++) {
+            const aid = parseInt($(this).siblings('.lc-show').children('ul').find('.remove-audit').eq(i).data('id'));
+            aidList.push(aid);
+        }
+        const html = getShenpiHtml(this_code);
+        $('#shenpi-name2').text($(this).data('name'));
+        $('#shenpi_code2').val(this_code);
+        $('#shenpi_status2').val(this_status);
+        $('#shenpi_auditors2').val(aidList.join(','));
+        $('#shenpi-list').html(html);
+        setTimeout(function () { $("#shenpi-list [data-toggle='tooltip']").tooltip(); },800);
+    });
+
+    $('#save-other-shenpi').click(function () {
+        $(this).attr('disabled', true);
+        const num = $('#shenpi-list input:checked').length;
+        if (num < 1) {
+            toastr.warning('请选择需要设置审批同步的流程');
+            return;
+        }
+        const data = {
+            type: 'copy2os',
+            status: parseInt($('#shenpi_status2').val()),
+            code: $('#shenpi_code2').val(),
+        };
+        if(data.status !== shenpi_status.gdspl) {
+            data.aidList = $('#shenpi_auditors2').val();
+        }
+        // 获取已选中的标段
+        const shenpiList = [];
+        for (let i = 0; i < num; i++) {
+            const code = $('#shenpi-list input:checked').eq(i).data('code');
+            shenpiList.push(code);
+        }
+        data.shenpiList = shenpiList.join(',');
+        postData('/tender/' + cur_tenderid + '/shenpi/audit/save', data, function () {
+            toastr.success('设置成功');
+            setTimeout(function () {
+                window.location.reload();
+            }, 1000)
+        })
+    });
 });

+ 1 - 1
app/router.js

@@ -325,7 +325,7 @@ module.exports = app => {
     app.post('/tender/:id/change/check/again', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.checkAgain');
 
     app.post('/tender/:id/change/:cid/check/codeRepeat', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.checkCodeRepeat');
-
+    app.post('/tender/:id/change/:cid/info/copy', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.copyChange');
     // 变更单位管理
     app.post('/change/update/company', sessionAuth, 'changeController.updateCompany');
 

+ 38 - 1
app/service/change.js

@@ -11,6 +11,7 @@
 const audit = require('../const/audit');
 const fs = require('fs');
 const path = require('path');
+const changeConst = require('../const/change');
 const smsTypeConst = require('../const/sms_type');
 const SMS = require('../lib/sms');
 const SmsAliConst = require('../const/sms_alitemplate');
@@ -957,7 +958,7 @@ module.exports = app => {
          */
         async getValidChanges(tid, bills, pos) {
             const self = this;
-            const getFilterPart = function (field, value) {
+            const getFilterPart = function(field, value) {
                 return value
                     ? field + ' = ' + self.db.escape(value)
                     : self.db.format("(?? = null or ?? = '')", [field, field]);
@@ -1308,6 +1309,42 @@ module.exports = app => {
             const content = await this.db.query(noticeSql, noticeSqlParam);
             return content.length ? JSON.stringify(content[0]) : '';
         }
+
+        /**
+         * 获取当前标段其他变更令
+         * @param {Number} tid - 标段id
+         * @param {Number} cid - 当前变更令
+         */
+        async getOthersChange(tid, cid) {
+            const sql = 'SELECT * FROM ?? WHERE tid = ? AND cid != ? ORDER BY ? desc ';
+            const sqlParam = [this.tableName, tid, cid, 'in_time'];
+            const data = await this.db.query(sql, sqlParam);
+            const changeClassObj = {};
+            for (const c in changeConst.class) {
+                if (changeConst.class.hasOwnProperty(c)) {
+                    const item = changeConst.class[c];
+                    changeClassObj[item.value] = item.name;
+                }
+            }
+            for (let i = 0; i < data.length; i++) {
+                data[i].class = changeClassObj[data[i].class];
+            }
+            return data;
+        }
+
+        /**
+         * 拷贝变更令至当前变更令
+         * @param {String} cid - 当前变更令
+         * @param {String} copy_cid - 要拷贝的变更令
+         */
+        async handleCopyChange(cid, copy_cid) {
+            // const change = await this.getDataByCondition({ cid });
+            const copyChange = await this.getDataByCondition({ cid: copy_cid });
+            return await this.update({ peg: copyChange.peg, org_name: copyChange.org_name, org_code: copyChange.org_code, new_name: copyChange.new_name, content: copyChange.content, basis: copyChange.basis, expr: copyChange.expr, memo: copyChange.memo, type: copyChange.type,
+                class: copyChange.class, quality: copyChange.quality, company: copyChange.company, charge: copyChange.charge, new_code: copyChange.new_code }, {
+                cid,
+            });
+        }
     }
 
     return Change;

+ 101 - 0
app/service/shenpi_audit.js

@@ -7,6 +7,7 @@
  * @date 2017/10/25
  * @version
  */
+const shenpiConst = require('../const/shenpi');
 
 module.exports = app => {
 
@@ -57,6 +58,106 @@ module.exports = app => {
             };
             return await this.db.delete(this.tableName, delData);
         }
+
+        async copyAudit2otherTender(data) {
+            const transaction = await this.db.beginTransaction();
+            try {
+                const shenpi_status = parseInt(data.status);
+                // 1.复制修改当前审批到其他的tender_info里
+                // 2.删除其他的shenpiAudit
+                // 3.添加新的shenpiAudit(还要针对该标段是否为原报进行处理)
+                const tenderInfoUpdateList = [];
+                const tenders = [];
+                for (const tid of data.tidList.split(',')) {
+                    // 获取原报
+                    const tender = await this.ctx.service.tender.getDataById(tid);
+                    if (tender) {
+                        tenders.push({ id: parseInt(tid), user_id: tender.user_id });
+                        const shenpiInfo = await this.ctx.service.tenderInfo.getTenderShenpiInfo(tid);
+                        // 把当前期状态复制到其他标段里
+                        if (shenpiInfo[data.code] !== shenpi_status) {
+                            shenpiInfo[data.code] = shenpi_status;
+                            tenderInfoUpdateList.push({ row: { shenpi: JSON.stringify(shenpiInfo) }, where: { tid: parseInt(tid) } });
+                        }
+                    }
+                }
+                if (tenderInfoUpdateList.length > 0) await transaction.updateRows(this.ctx.service.tenderInfo.tableName, tenderInfoUpdateList);
+                const insertList = [];
+                const needYB = ['ledger', 'revise', 'change'];
+                const canYB = needYB.indexOf(data.code) !== -1;
+                for (const t of tenders) {
+                    if (shenpi_status !== shenpiConst.sp_status.sqspr) {
+                        await transaction.delete(this.tableName, { tid: t.id, sp_type: shenpiConst.sp_type[data.code], sp_status: shenpi_status });
+                        for (const aid of data.aidList.split(',')) {
+                            if (parseInt(aid) !== t.user_id || (parseInt(aid) === t.user_id && canYB)) {
+                                const insertData = {
+                                    tid: t.id,
+                                    sp_type: shenpiConst.sp_type[data.code],
+                                    sp_status: shenpi_status,
+                                    audit_id: parseInt(aid),
+                                };
+                                insertList.push(insertData);
+                            }
+                        }
+                    }
+                }
+                // console.log(tenderInfoUpdateList, insertList);
+                if (insertList.length > 0) await transaction.insert(this.tableName, insertList);
+                await transaction.commit();
+                return true;
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+        }
+
+        async copyAudit2otherShenpi(data) {
+            const transaction = await this.db.beginTransaction();
+            try {
+                const shenpi_status = parseInt(data.status);
+                // 1.修改当前审批到它的tender_info里
+                // 2.删除相同审批状态的shenpiAudit
+                // 3.添加新的shenpiAudit(还要针对该标段是否为原报进行处理)
+                const insertList = [];
+                const needYB = ['ledger', 'revise', 'change'];
+                const shenpiInfo = await this.ctx.service.tenderInfo.getTenderShenpiInfo(this.ctx.tender.id);
+                for (const code of data.shenpiList.split(',')) {
+                    // 把当前审批状态复制到其他标段里
+                    if (shenpiInfo[code] !== shenpi_status) {
+                        shenpiInfo[code] = shenpi_status;
+                    }
+                    if (shenpiInfo[code] !== shenpiConst.sp_status.sqspr) {
+                        await transaction.delete(this.tableName, { tid: this.ctx.tender.id, sp_type: shenpiConst.sp_type[code], sp_status: shenpiInfo[code] });
+                        for (const aid of data.aidList.split(',')) {
+                            if (parseInt(aid) !== this.ctx.tender.data.user_id || (parseInt(aid) === this.ctx.tender.data.user_id && needYB.indexOf(code) !== -1)) {
+                                const insertData = {
+                                    tid: this.ctx.tender.id,
+                                    sp_type: shenpiConst.sp_type[code],
+                                    sp_status: shenpi_status,
+                                    audit_id: parseInt(aid),
+                                };
+                                insertList.push(insertData);
+                            }
+                        }
+                    }
+                }
+                await transaction.update(this.ctx.service.tenderInfo.tableName,
+                    {
+                        shenpi: JSON.stringify(shenpiInfo),
+                    },
+                    {
+                        where: {
+                            tid: this.ctx.tender.id,
+                        },
+                    });
+                if (insertList.length > 0) await transaction.insert(this.tableName, insertList);
+                await transaction.commit();
+                return true;
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+        }
     }
 
     return ShenpiAudit;

+ 7 - 0
app/service/stage.js

@@ -591,6 +591,9 @@ module.exports = app => {
                         const sumGcl = await this.ctx.service.stageBills.getSumTotalPriceGclByMaterial(stage_list, '^[^0-9]*1[0-9]{2}-');
                         cb.value = this.ctx.helper.add(sumGcl.contract_tp, sumGcl.qc_tp);
                         break;
+                    case 'bqyf':
+                        cb.value = this._.sumBy(stage_list, 'yf_tp');
+                        break;
                     default:
                         cb.value = 0;
                 }
@@ -598,6 +601,10 @@ module.exports = app => {
             return calcBase;
         }
 
+        async getSumbqyfByMaterial(stage) {
+
+        }
+
         /**
          * 获取必要的stage信息调用curTimes, curOrder, id , times, curAuditor(材料调差)
          * @param stage_id_list

+ 11 - 0
app/service/tender_info.js

@@ -334,6 +334,17 @@ module.exports = app => {
                     { decimal: JSON.stringify(newDecimal) }, { where: { tid: tenderId } });
             }
         }
+
+        /**
+         * 获取标段审批相关信息 (审批设置用)
+         * @param tenderId
+         * @return {Promise<void>}
+         */
+        async getTenderShenpiInfo(tenderId) {
+            const info = await this.getDataByCondition({ tid: tenderId });
+            const shenpiInfo = !info.shenpi || info.shenpi === '' ? defaultInfo.shenpi : JSON.parse(info.shenpi);
+            return shenpiInfo;
+        }
     }
 
     return TenderInfo;

+ 11 - 1
app/view/change/info.ejs

@@ -124,7 +124,17 @@
 <div class="panel-content">
     <div class="panel-title pr-0">
         <div class="title-main d-flex justify-content-between">
-            <h2 id="info_title" class="show_title">变更信息</h2>
+            <!-- <h2 id="info_title" class="show_title">变更信息</h2> -->
+            <h2 id="info_title" class="show_title">
+                <% if(auditStatus === auditConst.status.uncheck || auditStatus === auditConst.status.back) { %>
+                    <div class="d-inline-block">
+                        <a class="btn btn-sm btn-primary" href="#add-bj" data-toggle="modal" data-target="#add-bj">拷贝其他变更令数据</a>
+                    </div>
+                <% } else { %>
+                    <span>变更信息</span>
+                <% } %>
+            </h2>
+
             <div id="bills_title" class="show_title" style="line-height:34px;display: none">
                 <div>
                     <% if (auditStatus === 1 || auditStatus === 2) { %>

+ 30 - 0
app/view/change/info_modal.ejs

@@ -999,6 +999,36 @@
         </div>
     </div>
 </div>
+
+<!--填充历史变更-->
+<div class="modal fade" id="add-bj" 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="alert alert-warning p-2">选择需要拷贝的变更令,确认后将为您自动生成变更信息</div>
+            <div style="height: 300px; overflow: scroll; overflow-x: hidden;">
+                <table class="table table-bordered" >
+                    <thead>
+                        <tr align="center"><th>申请编号/变更令号</th><th>工程名称</th><th>变更类别</th><th>变更金额</th><th>审批状态</th><th>选择</th></tr>
+                    </thead>
+                    <tbody >
+                        <% othersChange.forEach(change => { %>
+                            <tr><td><%- change.code%></td><td><%- change.name%></td><td><%- change.class%></td><td align="right"><%- change.total_price %></td><td><span class="<%- auditConst.auditStatusClass[change.status]%>"><%- auditConst.auditStatusString[change.status]%></span></td><td align="center"><input type="checkbox" data-id="<%- change.cid %>"></td></tr>
+                        <% }); %>
+                    </tbody>
+                </table>
+            </div>
+            <div class="modal-footer">
+            <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
+            <button type="button" class="btn btn-sm btn-primary" id="bg-copy">确认拷贝</button>
+            </div>
+        </div>
+    </div>
+</div>
+
 <script type="text/javascript">
     const csrf = '<%= ctx.csrf %>';
     const authMobile = '<%= authMobile %>';

+ 21 - 18
app/view/revise/compare.ejs

@@ -109,24 +109,27 @@
     };
     const billsSpreadSetting = {
         cols: [
-            {title: '', colSpan: '1', rowSpan: '3', field: 'differ_str', hAlign: 1, width: 20, formatter: '@', cellType: 'tip', getTip: function (x) {
-                if (x.differ_str.indexOf('改') >= 0) {
-                    const differ_hint = [];
-                    if (x.differ.indexOf('tree') >= 0)
-                        differ_hint.push('结构调整(原父项:' + (x.org_parent.code || '') + (x.org_parent.b_code || 0) + ')');
-                    if (x.differ.indexOf('calc') >= 0) differ_hint.push('计算项修改');
-                    if (x.differ.indexOf('info') >= 0) differ_hint.push('文字修改');
-                    const pos_hint = [];
-                    if (x.differ.indexOf('pos-add') >= 0) pos_hint.push('增');
-                    if (x.differ.indexOf('pos-del') >= 0) pos_hint.push('删');
-                    if (x.differ.indexOf('pos-info') >= 0) pos_hint.push('文改');
-                    if (x.differ.indexOf('pos-calc') >= 0) pos_hint.push('量改');
-                    if (pos_hint.length > 0) differ_hint.push('计量单元: ' + pos_hint.join(','))
-                    return differ_hint.join('<br>');
-                } else {
-                    return '';
+            {
+                title: '修\n订\n类\n型', colSpan: '1', rowSpan: '3', field: 'differ_str', hAlign: 1, width: 20, formatter: '@', cellType: 'tip',
+                getTip: function (x) {
+                    if (x.differ_str.indexOf('改') >= 0) {
+                        const differ_hint = [];
+                        if (x.differ.indexOf('tree') >= 0)
+                            differ_hint.push('结构调整(原父项:' + (x.org_parent.code || '') + (x.org_parent.b_code || '') + ')');
+                        if (x.differ.indexOf('calc') >= 0) differ_hint.push('计算项修改');
+                        if (x.differ.indexOf('info') >= 0) differ_hint.push('文字修改');
+                        const pos_hint = [];
+                        if (x.differ.indexOf('pos-add') >= 0) pos_hint.push('增');
+                        if (x.differ.indexOf('pos-del') >= 0) pos_hint.push('删');
+                        if (x.differ.indexOf('pos-info') >= 0) pos_hint.push('文改');
+                        if (x.differ.indexOf('pos-calc') >= 0) pos_hint.push('量改');
+                        if (pos_hint.length > 0) differ_hint.push('计量单元: ' + pos_hint.join(','))
+                        return differ_hint.join('<br>');
+                    } else {
+                        return '';
+                    }
                 }
-                }},
+            },
             {title: '修订台账|项目节编号', colSpan: '16|1', rowSpan: '1|2', field: 'new_code', hAlign: 0, width: 145, formatter: '@', cellType: 'tree'},
             {title: '|清单编号', colSpan: '|1', rowSpan: '|2', field: 'new_b_code', hAlign: 0, width: 70, formatter: '@'},
             {title: '|名称', colSpan: '|1', rowSpan: '|2', field: 'new_name', hAlign: 0, width: 185, formatter: '@'},
@@ -189,7 +192,7 @@
     };
     const posSpreadSetting = {
         cols: [
-            {title: '', colSpan: '1', rowSpan: '3', field: 'differ_str', hAlign: 1, width: 60, formatter: '@'},
+            {title: '修订类型', colSpan: '1', rowSpan: '3', field: 'differ_str', hAlign: 1, width: 60, formatter: '@'},
             {title: '修改台账|计量单元', colSpan: '6|1', rowSpan: '1|2', field: 'new_name', hAlign: 0, width: 230, formatter: '@'},
             {title: '|位置', colSpan: '|1', rowSpan: '|2', field: 'new_position', hAlign: 0, width: 60, formatter: '@'},
             {title: '|台账数量|设计量', colSpan: '|4|1', rowSpan: '|1|1', field: 'new_sgfh_qty', hAlign: 2, width: 100, type: 'Number'},

+ 14 - 1
app/view/revise/gcl_compare.ejs

@@ -4,7 +4,20 @@
         <div class="title-main d-flex">
             <% include ./sub_mini_menu.ejs %>
             <div>
-                工程量清单对比
+                <i class="fa fa-stop text-danger-50 border-danger-50 bg-danger-50"></i>
+                <div class="form-check d-inline-block">
+                    <input class="form-check-input" type="radio" name="compareTag" id="exampleRadios1" value="deal" checked>
+                    <label class="form-check-label" for="exampleRadios1">
+                        台账修订 ≠ 签约
+                    </label>
+                </div>
+                <div class="form-check d-inline-block">
+                    <input class="form-check-input" type="radio" name="compareTag" id="exampleRadios2" value="org">
+                    <label class="form-check-label" for="exampleRadios2">
+                        台账修订 ≠ 原台账
+                    </label>
+                </div>
+                <span class="ml-2"><i class="fa fa-stop text-warning-50 border-warning-50 bg-primary-50" style="color: #FFE699"></i> 编号相同,名称/单位/单价不同</span>
             </div>
             <div class="ml-auto">
             </div>

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

@@ -13,7 +13,9 @@
                     <div class="col-7">
                         <% for (const sp of shenpi.sp_lc) { %>
                             <div class="card mb-3">
-                                <div class="card-body">
+                                <div class="card-body <%- sp.code %>_div">
+                                    <a class="pull-right set-otherTender" data-name="<%- sp.name %>" data-code="<%- sp.code %>" href="#batch" data-toggle="modal" data-target="#batch">设置其他标段</a>
+                                    <a class="pull-right set-otherShenpi mr-3" data-name="<%- sp.name %>" data-code="<%- sp.code %>" href="#batch2" data-toggle="modal" data-target="#batch2">设置其他流程</a>
                                     <h5 class="card-title"><%- sp.name %></h5>
                                     <div class="form-group">
                                         <div class="form-group form-check">
@@ -139,12 +141,16 @@
 </div>
 <script src="/public/js/sub_menu.js"></script>
 <script>
+    const sp_lc = JSON.parse('<%- JSON.stringify(shenpi.sp_lc) %>');
     const sp_type = JSON.parse('<%- JSON.stringify(shenpi.sp_type) %>');
     const sp_status = JSON.parse('<%- JSON.stringify(shenpi.sp_status) %>');
     const sp_status_list = JSON.parse('<%- JSON.stringify(shenpi.sp_status_list) %>');
     const accountGroup = JSON.parse('<%- JSON.stringify(accountGroup) %>');
     const accountList = JSON.parse('<%- JSON.stringify(accountList) %>');
     const cur_uid = parseInt('<%- ctx.tender.data.user_id %>');
+    const cur_tenderid = parseInt('<%- ctx.tender.id %>');
+    const tenders = JSON.parse('<%- JSON.stringify(tenders) %>');
+    const category = JSON.parse('<%- JSON.stringify(categoryData) %>');
 </script>
 <script src="/public/js/shenpi.js"></script>
 <script>

+ 81 - 0
app/view/tender/shenpi_modal.ejs

@@ -0,0 +1,81 @@
+<!--设置其他标段-->
+<div class="modal fade" id="batch" 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="alert alert-warning">将「<span id="shenpi-name"></span>」设置至其他标段</div>
+                <div class="modal-height-300" id="tender-list">
+                </div>
+            </div>
+            <div class="modal-footer">
+                <input type="hidden" id="shenpi_auditors" value="">
+                <input type="hidden" id="shenpi_code" value="">
+                <input type="hidden" id="shenpi_status" value="">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
+                <button type="button" class="btn btn-sm btn-primary" id="save-other-tender">确认</button>
+            </div>
+        </div>
+    </div>
+</div>
+<!--设置其他流程-->
+<div class="modal fade" id="batch2" 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="alert alert-warning">将「<span id="shenpi-name2"></span>」设置至其他流程</div>
+                <div class="modal-height-300" id="shenpi-list">
+                    <table class="table table-hover table-bordered">
+                        <thead>
+                        <th>名称</th>
+                        <th width="100">审批流程</th>
+                        <th width="40">选择</th>
+                        </thead>
+                        <tr>
+                            <td>预付款审批</td>
+                            <td>固定流程<i class="fa fa-question-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" data-original-title="王五-张三-李四"></i></td>
+                            <td></td>
+                        </tr>
+                        <tr>
+                            <td>台帐审批</td>
+                            <td>固定流程<i class="fa fa-question-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" data-original-title="王五-张三-李四"></i></td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>台帐修订</td>
+                            <td>固定流程<i class="fa fa-question-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" data-original-title="王五-张三-李四"></i></td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>计量期审批</td>
+                            <td>固定流程<i class="fa fa-question-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" data-original-title="王五-张三-李四"></i></td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>工程变更审批</td>
+                            <td>固定流程<i class="fa fa-question-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" data-original-title="王五-张三-李四"></i></td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>材料调差审批</td>
+                            <td>固定流程<i class="fa fa-question-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" data-original-title="王五-张三-李四"></i></td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                    </table>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <input type="hidden" id="shenpi_auditors2" value="">
+                <input type="hidden" id="shenpi_code2" value="">
+                <input type="hidden" id="shenpi_status2" value="">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
+                <button type="button" class="btn btn-sm btn-primary" id="save-other-shenpi">确认</button>
+            </div>
+        </div>
+    </div>
+</div>