Kaynağa Gözat

变更列表页调整

ellisran 1 yıl önce
ebeveyn
işleme
b766e84748

+ 1 - 1
app/const/audit.js

@@ -665,7 +665,7 @@ const change = (function() {
     auditStringClass[status.checkSkip] = 'text-success';
     // 描述文本
     const auditProgress = [];
-    auditProgress[status.uncheck] = '草稿';
+    auditProgress[status.uncheck] = '待上报';
     auditProgress[status.checking] = '审批中';
     auditProgress[status.checked] = '审批通过';
     auditProgress[status.checkNo] = '审批退回';

+ 30 - 44
app/controller/change_controller.js

@@ -60,50 +60,17 @@ module.exports = app => {
             let page_total = 0;
             const tp = await ctx.service.change.getTp(tender.id, status);
             if (changes !== null) {
-                let i = 0;
                 for (const c of changes) {
-                    page_total = ctx.helper.add(page_total, c.total_price);
-                    const status = c.status === audit.flow.status.uncheck ? 0 : 1;
-                    // 根据审批人对当前变更令的状态取不同的展示方式。
-                    let changeAudit = '';
-                    let auditStatus = 0;
-                    switch (c.status) {
-                        case 1:
-                            auditStatus = 1;
-                            break;
-                        case 2:
-                            changeAudit = await ctx.service.changeAudit.getLastUser(c.cid, c.times, status);
-                            auditStatus = changeAudit.uid === ctx.session.sessionUser.accountId ? 1 : 0;
-                            break;
-                        case 3:
-                        case 4:
-                            auditStatus = 0;
-                            changeAudit = await ctx.service.changeAudit.getLastUser(c.cid, c.times, status);
-                            break;
-                        case 5:
-                            changeAudit = await ctx.service.changeAudit.getLastUser(c.cid, c.times - 1, status);
-                            auditStatus = c.uid === ctx.session.sessionUser.accountId ? 1 : 0;
-                            const back_changeUsedData = await ctx.service.stageChange.getAllFinalUsedData(ctx.tender.id, c.cid);
-                            c.stageChangeNum = this.ctx.helper.sum(back_changeUsedData.map(x => { return Math.abs(x.qty); }));
-                            c.isSettle = await ctx.service.changeSettleList.isSettle(c.cid);
-                            break;
-                        case 6:
-                            changeAudit = await ctx.service.changeAudit.getLastBackUser(c.cid, c.times);
-                            const checkingAudit = await ctx.service.changeAudit.getLastUser(c.cid, c.times, status);
-                            auditStatus = checkingAudit.uid === ctx.session.sessionUser.accountId ? 1 : 0;
-                            break;
-                        case 9:
-                            auditStatus = c.uid === ctx.session.sessionUser.accountId ? 9 : 0;
-                            const changeUsedData = await ctx.service.stageChange.getAllFinalUsedData(ctx.tender.id, c.cid);
-                            c.stageChangeNum = this.ctx.helper.sum(changeUsedData.map(x => { return Math.abs(x.qty); }));
-                            c.isSettle = await ctx.service.changeSettleList.isSettle(c.cid);
-                            break;
-                        default:
-                            break;
+                    c.curAuditors = await ctx.service.changeAudit.getAuditorsByStatus(c.cid, c.status, c.times);
+                    if (c.status === audit.change.status.checkNoPre) {
+                        c.curAuditors2 = await ctx.service.stageAudit.getAuditorsByStatus(c.cid, audit.change.status.checking, c.times);
+                    }
+                    if (c.status === audit.change.status.checkNo || c.status === audit.change.status.revise) {
+                        const changeUsedData = await ctx.service.stageChange.getAllFinalUsedData(ctx.tender.id, c.cid);
+                        c.stageChangeNum = this.ctx.helper.sum(changeUsedData.map(x => { return Math.abs(x.qty); }));
+                        c.isSettle = await ctx.service.changeSettleList.isSettle(c.cid);
                     }
-                    changes[i].changeAudit = changeAudit;
-                    changes[i].auditStatus = auditStatus;
-                    i++;
+                    page_total = ctx.helper.add(page_total, c.total_price);
                 }
             }
 
@@ -158,7 +125,6 @@ module.exports = app => {
             const apLists = allPlanCodes.length > 0 ? ctx.app._.uniq(ctx.app._.map(allPlanCodes, 'plan_code')) : [];
 
             const renderData = {
-                uid: ctx.session.sessionUser.accountId,
                 moment,
                 tender,
                 // tenderList,
@@ -170,7 +136,7 @@ module.exports = app => {
                 status,
                 codeRule,
                 dealCode: ctx.tender.info.deal_info.dealCode,
-                auditConst: audit.flow,
+                auditConst: audit.change,
                 changeConst,
                 state,
                 ruleType: codeRuleConst.ruleType.change,
@@ -180,6 +146,7 @@ module.exports = app => {
                 tpUnit: ctx.tender.info.decimal.tp,
                 changePlanList,
                 apLists,
+                auditType,
             };
 
             if (ctx.session.sessionProject.page_show.openChangeState) {
@@ -211,6 +178,25 @@ module.exports = app => {
         }
 
         /**
+         * 审批流程(Get)
+         * @param ctx
+         * @return {Promise<void>}
+         */
+        async changeAuditors(ctx) {
+            try {
+                const cid = JSON.parse(ctx.request.body.data).cid;
+                const tenderId = ctx.params.id;
+                const changeInfo = await ctx.service.change.getDataByCondition({ cid });
+                await ctx.service.change.loadChangeUser(changeInfo);
+                await ctx.service.change.loadChangeAuditViewData(changeInfo);
+                ctx.body = { err: 0, msg: '', data: changeInfo };
+            } catch (error) {
+                this.log(error);
+                ctx.body = { err: 1, msg: error.toString(), data: null };
+            }
+        }
+
+        /**
          *
          * @param {Object} ctx - egg全局变量
          * @return {void}

+ 157 - 1
app/public/js/change.js

@@ -134,9 +134,165 @@ class codeRuleSet {
         });
     }
 }
+/**
+ * 期计量 - 期列表页面 js
+ *
+ * @author Mai
+ * @date 2018/12/7
+ * @version
+ */
+const getGroupAuditHtml = function (group) {
+    return group.map(u => { return `<small class="d-inline-block text-dark mx-1" title="${u.role}" data-auditorId="${u.aid}">${u.name}</small>`; }).join('');
+};
+
+const getAuditTypeHtml = function (type) {
+    if (type === auditType.key.common) return '';
+    return `<div class="li-subscript"><span class="badge badge-pill badge-${auditType.info[type].class} p-1 badge-bg-small"><small>${auditType.info[type].short}</small></span></div>`;
+};
 
+const getAuditTypeText = function (type) {
+    if (type === auditType.key.common) return '';
+    return `<span class="text-${auditType.info[type].class}">${auditType.info[type].long}</span>`;
+};
 $(document).ready(() => {
 
+    // 获取审批流程
+    $('a[data-target="#sp-list" ]').on('click', function () {
+        const data = {
+            cid: $(this).attr('c-id'),
+        };
+        postData('/tender/' + tenderId + '/change/auditors', data, function (result) {
+            const { auditHistory, auditors2, user } = result;
+            let auditorsHTML = [];
+            auditors2.forEach((group, idx) => {
+                if (idx === 0) {
+                    auditorsHTML.push(`<li class="list-group-item d-flex justify-content-between align-items-center">
+                    <span class="mr-1"><i class="fa fa fa-play-circle fa-rotate-90"></i></span>
+                <span class="text-muted">${getGroupAuditHtml(group)}</span>
+                <span class="badge badge-light badge-pill ml-auto"><small>原报</small></span>
+                </li>`);
+                } else if(idx === auditors2.length -1 && idx !== 0) {
+                    auditorsHTML.push(`<li class="list-group-item d-flex justify-content-between align-items-center">
+                    <span class="mr-1"><i class="fa fa fa-stop-circle fa-rotate-90"></i></span>
+                <span class="text-muted">${getGroupAuditHtml(group)}</span>
+                <div class="d-flex ml-auto">
+                ${getAuditTypeHtml(group[0].audit_type)}
+                <span class="badge badge-light badge-pill ml-auto"><small>终审</small></span>
+                </div>
+                </li>`);
+                } else {
+                    auditorsHTML.push(`<li class="list-group-item d-flex justify-content-between align-items-center">
+                    <span class="mr-1"><i class="fa fa fa-chevron-circle-down"></i></span>
+                <span class="text-muted">${getGroupAuditHtml(group)}</span>
+                <div class="d-flex ml-auto">
+                ${getAuditTypeHtml(group[0].audit_type)}
+                <span class="badge badge-light badge-pill"><small>${transFormToChinese(idx)}审</small></span>
+                </div>
+                </li>`);
+                }
+            });
+            $('#auditor-list').empty();
+            $('#auditor-list').append(auditorsHTML.join(''));
+
+            let historyHTML = [];
+            auditHistory.forEach((his, idx) => {
+                if (idx === auditHistory.length - 1 && auditHistory.length !== 1) {
+                    historyHTML.push(`<div class="text-right"><a href="javascript: void(0);" id="fold-btn" data-target="show">展开历史审批流程</a></div>`);
+                }
+                historyHTML.push(`<div class="${idx < auditHistory.length - 1 ? 'fold-card' : ''}">`);
+                historyHTML.push(`<div class="text-center text-muted">${idx+1}#</div>`);
+                historyHTML.push(`<ul class="timeline-list list-unstyled mt-2 ${ idx === auditHistory.length - 1 && auditHistory.length !== 1 ? 'last-auditor-list' : '' }">`);
+                his.forEach((group, index) => {
+                    if (index === 0) {
+                        historyHTML.push(`<li class="timeline-list-item pb-2">
+                                            <div class="timeline-item-date">
+                                                ${group.beginYear}
+                                                <span>${group.beginDate}</span>
+                                                <span>${group.beginTime}</span>
+                                            </div>
+                                            <div class="timeline-item-tail"></div>
+                                            <div class="timeline-item-icon bg-success text-light"><i class="fa fa-caret-down"></i></div>
+                                            <div class="timeline-item-content">
+                                                <div class="py-1">
+                                                    <span class="text-black-50">原报</span>
+                                                    <span class="pull-right text-success">${idx !== 0 ? '重新' : '' }上报审批</span>
+                                                </div>
+                                                <div class="card">
+                                                    <div class="card-body px-3 py-0">
+                                                        <div class="card-text p-2 py-3 row">
+                                                            <div class="col">
+                                                                <span class="h6">${user.name}</span>
+                                                                <span class="text-muted ml-1">${user.role}</span>
+                                                            </div>
+                                                            <div class="col">
+                                                                <span class="pull-right text-success"><i class="fa fa-check-circle"></i></span>
+                                                            </div>
+                                                        </div>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                        </li>`);
+                    }
+                    historyHTML.push(`<li class="timeline-list-item pb-2 ${ group.status === auditConst.status.uncheck && idx === auditHistory.length - 1 && auditHistory.length !== 1 ? 'is_uncheck' : ''}">`);
+                    if (group.endYear) {
+                        historyHTML.push(`<div class="timeline-item-date">${group.endYear}<span>${group.endDate}</span><span>${group.endTime}</span></div>`);
+                    }
+                    if (index < his.length - 1) {
+                        historyHTML.push('<div class="timeline-item-tail"></div>');
+                    }
+                    if (group.status === auditConst.status.checked || group.status === auditConst.status.cancelRevise) {
+                        historyHTML.push('<div class="timeline-item-icon bg-success text-light"><i class="fa fa-check"></i></div>');
+                    } else if (group.status === auditConst.status.checkNo || group.status === auditConst.status.checkNoPre || group.status === auditConst.status.revise || group.status === auditConst.status.checkCancel) {
+                        historyHTML.push('<div class="timeline-item-icon bg-warning text-light"><i class="fa fa-level-up"></i></div>');
+                    } else if (group.status === auditConst.status.checking) {
+                        historyHTML.push('<div class="timeline-item-icon bg-warning text-light"><i class="fa fa-ellipsis-h"></i></div>');
+                    } else if(group.status === auditConst.status.checkAgain) {
+                        historyHTML.push('<div class="timeline-item-icon bg-warning text-light"><i class="fa fa-check"></i></div>');
+                    } else {
+                        historyHTML.push('<div class="timeline-item-icon bg-secondary text-light"></div>');
+                    }
+
+                    historyHTML.push('<div class="timeline-item-content">');
+                    const statuStr = group.status !== auditConst.status.uncheck ?
+                        `<span class="pull-right ${auditConst.statusClass[group.status]}">${auditConst.statusString[group.status]}</span>` : '';
+                    historyHTML.push(`<div class="py-1">
+                        <span class="text-black-50">
+                        ${ !group.is_final ? group.audit_order + '' : '终' }审 ${getAuditTypeText(group.audit_type)}
+                        </span>
+                        ${statuStr}
+                    </div>`);
+                    historyHTML.push('<div class="card"><div class="card-body px-3 py-0">');
+                    for (const [i, auditor] of group.auditors.entries()) {
+                        historyHTML.push(`<div class="card-text p-2 py-3 row ${ ( i > 0 ? 'border-top' : '') }">`);
+                        historyHTML.push(`<div class="col"><span class="h6">${auditor.name}</span><span class="text-muted ml-1">${auditor.role}</span></div>`);
+                        historyHTML.push('<div class="col">');
+                        if (auditor.status === auditConst.status.checked || group.status === auditConst.status.cancelRevise) {
+                            historyHTML.push('<span class="pull-right text-success"><i class="fa fa-check-circle"></i></span>');
+                        } else if (auditor.status === auditConst.status.checkNo || auditor.status === auditConst.status.checkNoPre || group.status === auditConst.status.revise || auditor.status === auditConst.status.checkCancel) {
+                            historyHTML.push('<span class="pull-right text-warning"><i class="fa fa-share-square fa-rotate-270"></i></span>');
+                        } else if (auditor.status === auditConst.status.checking) {
+                            historyHTML.push('<span class="pull-right text-warning"><i class="fa fa-commenting"></i></span>');
+                        } else if (auditor.status === auditConst.status.checkAgain) {
+                            historyHTML.push('<span class="pull-right text-warning"><i class="fa fa-check"></i></span>');
+                        }
+                        historyHTML.push('</div>');
+                        if (auditor.sdesc) {
+                            historyHTML.push(`<div class="col-12 py-1 bg-light"><i class="fa fa-commenting-o mr-1"></i>${auditor.sdesc}</div>`);
+                        }
+                        historyHTML.push('</div>');
+                    }
+                    historyHTML.push('</div></div>');
+                    historyHTML.push('</div>');
+                    historyHTML.push('</li>');
+                });
+                historyHTML.push('</div>');
+                historyHTML.push('</ul>');
+            });
+            $('#audit-list').empty();
+            $('#audit-list').append(historyHTML.join(''));
+        });
+    });
+
     $("#change-table").colResizable({
         liveDrag:true,
         gripInnerHtml:"<div class='grip'></div>",
@@ -374,5 +530,5 @@ $(document).ready(() => {
             link += '&pageSize=' + getLocalCache('account-pageSize');
         }
         window.location.href = link;
-    })
+    });
 });

+ 1 - 0
app/router.js

@@ -517,6 +517,7 @@ module.exports = app => {
     // 变更管理
     app.get('/tender/:id/change', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.index');
     app.get('/tender/:id/change/status/:status', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.status');
+    app.post('/tender/:id/change/auditors', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.changeAuditors');
     app.post('/tender/:id/change/newCode', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.newCode');
     app.post('/tender/:id/change/add', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.add');
     app.post('/tender/:id/change/defaultBills', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.defaultBills');

+ 51 - 51
app/service/change.js

@@ -130,7 +130,7 @@ module.exports = app => {
 
         async add(tenderId, userId, code, plan_code, name, delimit = 100) {
             const sql = 'SELECT COUNT(*) as count FROM ?? WHERE `tid` = ? AND ((`code` = ? AND `status` != ?) OR (`p_code` = ? AND `status` = ?))';
-            const sqlParam = [this.tableName, tenderId, code, audit.flow.status.checked, code, audit.flow.status.checked];
+            const sqlParam = [this.tableName, tenderId, code, audit.change.status.checked, code, audit.change.status.checked];
             const codeCount = await this.db.queryOne(sql, sqlParam);
             const count = codeCount.count;
             if (count > 0) {
@@ -146,7 +146,7 @@ module.exports = app => {
                     cid,
                     tid: tenderId,
                     uid: userId,
-                    status: audit.flow.status.uncheck,
+                    status: audit.change.status.uncheck,
                     times: 1,
                     valid: true,
                     in_time: new Date(),
@@ -252,7 +252,7 @@ module.exports = app => {
             return await this.getAllDataByCondition({
                 tid: tenderId,
                 uid: userId,
-                status: audit.flow.status.checking,
+                status: audit.change.status.checking,
             });
         }
 
@@ -260,7 +260,7 @@ module.exports = app => {
             return await this.getAllDataByCondition({
                 tid: tenderId,
                 uid: userId,
-                status: audit.flow.status.uncheck,
+                status: audit.change.status.uncheck,
             });
         }
 
@@ -268,7 +268,7 @@ module.exports = app => {
             return await this.getAllDataByCondition({
                 tid: tenderId,
                 uid: userId,
-                status: audit.flow.status.checking,
+                status: audit.change.status.checking,
             });
         }
 
@@ -276,7 +276,7 @@ module.exports = app => {
             return await this.getAllDataByCondition({
                 tid: tenderId,
                 uid: userId,
-                status: audit.flow.status.checked,
+                status: audit.change.status.checked,
             });
         }
 
@@ -284,7 +284,7 @@ module.exports = app => {
             return await this.getAllDataByCondition({
                 tid: tenderId,
                 uid: userId,
-                status: audit.flow.status.checkNo,
+                status: audit.change.status.checkNo,
             });
         }
 
@@ -292,7 +292,7 @@ module.exports = app => {
             return await this.count({
                 tid: tenderId,
                 uid: userId,
-                status: audit.flow.status.checkNo,
+                status: audit.change.status.checkNo,
             });
         }
 
@@ -322,18 +322,18 @@ module.exports = app => {
                             this.tableName,
                             tenderId,
                             this.ctx.session.sessionUser.accountId,
-                            audit.flow.status.uncheck,
+                            audit.change.status.uncheck,
                             this.ctx.service.changeAudit.tableName,
                             this.ctx.session.sessionUser.accountId,
-                            audit.flow.status.back,
+                            audit.change.status.checkNo,
                             this.ctx.service.changeAudit.tableName,
                             this.ctx.session.sessionUser.accountId,
-                            audit.flow.status.checked,
+                            audit.change.status.checked,
                         ];
                         break;
                     case 1: // 待处理(你的)
                         sql = 'SELECT a.* FROM ?? as a WHERE cid in(SELECT b.cid FROM ?? as b WHERE tid = ? AND uid = ? AND status = ?)' + stateSql;
-                        sqlParam = [this.tableName, this.ctx.service.changeAudit.tableName, tenderId, this.ctx.session.sessionUser.accountId, audit.flow.auditStatus.checking];
+                        sqlParam = [this.tableName, this.ctx.service.changeAudit.tableName, tenderId, this.ctx.session.sessionUser.accountId, audit.change.status.checking];
                         break;
                     case 5: // 待上报(所有的)PS:取未上报,退回,修订的变更令
                         sql =
@@ -344,15 +344,15 @@ module.exports = app => {
                             ' AND (a.status = ? OR a.status = ? OR a.status = ?) AND a.tid = ?' + stateSql;
                         sqlParam = [
                             this.tableName,
-                            audit.flow.status.uncheck,
+                            audit.change.status.uncheck,
                             this.ctx.service.changeAudit.tableName,
                             this.ctx.session.sessionUser.accountId,
-                            audit.flow.status.back,
+                            audit.change.status.checkNo,
                             this.ctx.service.changeAudit.tableName,
                             this.ctx.session.sessionUser.accountId,
-                            audit.flow.status.uncheck,
-                            audit.flow.status.back,
-                            audit.flow.status.revise,
+                            audit.change.status.uncheck,
+                            audit.change.status.checkNo,
+                            audit.change.status.revise,
                             tenderId,
                         ];
                         break;
@@ -416,13 +416,13 @@ module.exports = app => {
                         this.tableName,
                         tenderId,
                         this.ctx.session.sessionUser.accountId,
-                        audit.flow.status.uncheck,
+                        audit.change.status.uncheck,
                         this.ctx.service.changeAudit.tableName,
                         this.ctx.session.sessionUser.accountId,
-                        audit.flow.status.back,
+                        audit.change.status.checkNo,
                         this.ctx.service.changeAudit.tableName,
                         this.ctx.session.sessionUser.accountId,
-                        audit.flow.status.checked,
+                        audit.change.status.checked,
                     ];
                     const result = await this.db.query(sql, sqlParam);
                     return result[0].count;
@@ -433,7 +433,7 @@ module.exports = app => {
                     //     status: 2,
                     // });
                     const sql6 = 'SELECT count(*) AS count FROM ?? as a WHERE cid in(SELECT b.cid FROM ?? as b WHERE tid = ? AND uid = ? AND status = ?)' + stateSql;
-                    const sqlParam6 = [this.tableName, this.ctx.service.changeAudit.tableName, tenderId, this.ctx.session.sessionUser.accountId, audit.flow.auditStatus.checking];
+                    const sqlParam6 = [this.tableName, this.ctx.service.changeAudit.tableName, tenderId, this.ctx.session.sessionUser.accountId, audit.change.status.checking];
                     const result6 = await this.db.query(sql6, sqlParam6);
                     return result6[0].count;
                 case 5: // 待上报(所有的)PS:取未上报,退回,修订的变更令
@@ -445,15 +445,15 @@ module.exports = app => {
                         ' AND (a.status = ? OR a.status = ? OR a.status = ?) AND a.tid = ?' + stateSql;
                     const sqlParam2 = [
                         this.tableName,
-                        audit.flow.status.uncheck,
+                        audit.change.status.uncheck,
                         this.ctx.service.changeAudit.tableName,
                         this.ctx.session.sessionUser.accountId,
-                        audit.flow.status.back,
+                        audit.change.status.checkNo,
                         this.ctx.service.changeAudit.tableName,
                         this.ctx.session.sessionUser.accountId,
-                        audit.flow.status.uncheck,
-                        audit.flow.status.back,
-                        audit.flow.status.revise,
+                        audit.change.status.uncheck,
+                        audit.change.status.checkNo,
+                        audit.change.status.revise,
                         tenderId,
                     ];
                     const result2 = await this.db.query(sql2, sqlParam2);
@@ -494,19 +494,19 @@ module.exports = app => {
                         this.tableName,
                         tenderId,
                         this.ctx.session.sessionUser.accountId,
-                        audit.flow.status.uncheck,
+                        audit.change.status.uncheck,
                         this.ctx.service.changeAudit.tableName,
                         this.ctx.session.sessionUser.accountId,
-                        audit.flow.status.back,
+                        audit.change.status.checkNo,
                         this.ctx.service.changeAudit.tableName,
                         this.ctx.session.sessionUser.accountId,
-                        audit.flow.status.checked,
+                        audit.change.status.checked,
                     ];
                     const result = await this.db.query(sql, sqlParam);
                     return result[0].total_price ? result[0].total_price : 0;
                 case 1: // 待处理(你的)
                     const sql6 = 'SELECT SUM(cast (a.total_price as decimal(18,6))) AS total_price FROM ?? as a WHERE cid in(SELECT b.cid FROM ?? as b WHERE tid = ? AND uid = ? AND status = ?)';
-                    const sqlParam6 = [this.tableName, this.ctx.service.changeAudit.tableName, tenderId, this.ctx.session.sessionUser.accountId, audit.flow.auditStatus.checking];
+                    const sqlParam6 = [this.tableName, this.ctx.service.changeAudit.tableName, tenderId, this.ctx.session.sessionUser.accountId, audit.change.status.checking];
                     const result6 = await this.db.query(sql6, sqlParam6);
                     return result6[0].total_price ? result6[0].total_price : 0;
                 case 5: // 待上报(所有的)PS:取未上报,退回,修订的变更令
@@ -518,15 +518,15 @@ module.exports = app => {
                         ' AND (a.status = ? OR a.status = ? OR a.status = ?) AND a.tid = ?';
                     const sqlParam2 = [
                         this.tableName,
-                        audit.flow.status.uncheck,
+                        audit.change.status.uncheck,
                         this.ctx.service.changeAudit.tableName,
                         this.ctx.session.sessionUser.accountId,
-                        audit.flow.status.back,
+                        audit.change.status.checkNo,
                         this.ctx.service.changeAudit.tableName,
                         this.ctx.session.sessionUser.accountId,
-                        audit.flow.status.uncheck,
-                        audit.flow.status.back,
-                        audit.flow.status.revise,
+                        audit.change.status.uncheck,
+                        audit.change.status.checkNo,
+                        audit.change.status.revise,
                         tenderId,
                     ];
                     const result2 = await this.db.query(sql2, sqlParam2);
@@ -566,16 +566,16 @@ module.exports = app => {
          * @return {void}
          */
         async getCountByStatus2(tenderId, status) {
-            if (status === audit.filter.status.uncheck) {
+            if (status === audit.change.status.uncheck) {
                 const sql =
                     'SELECT count(*) AS count FROM ?? WHERE ' +
                     'tid = ? AND (status = ? OR status = ? OR status = ?)';
                 const sqlParam = [
                     this.tableName,
                     tenderId,
-                    audit.flow.status.uncheck,
-                    audit.flow.status.back,
-                    audit.flow.status.revise,
+                    audit.change.status.uncheck,
+                    audit.change.status.checkNo,
+                    audit.change.status.revise,
                 ];
                 const result = await this.db.queryOne(sql, sqlParam);
                 return result ? result.count : 0;
@@ -607,7 +607,7 @@ module.exports = app => {
          */
         async getChangeTp(tenderId) {
             const sql = 'SELECT SUM(`total_price`) AS tp, SUM(`positive_tp`) AS p_tp, SUM(`negative_tp`) AS n_tp FROM ?? WHERE tid = ? AND status = ?';
-            const sqlParam = [this.tableName, tenderId, audit.flow.status.checked];
+            const sqlParam = [this.tableName, tenderId, audit.change.status.checked];
             const result = await this.db.queryOne(sql, sqlParam);
             return result ? [result.tp, result.p_tp, result.n_tp] : [0, 0, 0];
         }
@@ -637,7 +637,7 @@ module.exports = app => {
                     // 更新原报人审批状态
                     await this.transaction.update(this.ctx.service.changeAudit.tableName, {
                         id: lastUser.id,
-                        status: audit.flow.auditStatus.checked,
+                        status: audit.change.status.checked,
                         sin_time: new Date(),
                     });
                 }
@@ -649,7 +649,7 @@ module.exports = app => {
                     let uSort = parseInt(lastUser.usort) + 1;
                     for (const [index, ca] of changeAudit.entries()) {
                         const auditInfo = ca.split('/%/');
-                        const uStatus = change_status && index === 0 ? audit.flow.auditStatus.checking : audit.flow.auditStatus.uncheck;
+                        const uStatus = change_status && index === 0 ? audit.change.status.checking : audit.change.status.uncheck;
                         const sin_time = change_status && index === 0 ? new Date() : null;
                         const caArray = {
                             tid: tenderId,
@@ -762,7 +762,7 @@ module.exports = app => {
                 if (change_status) {
                     cArray.tp_decimal = this.ctx.tender.info.decimal.tp;
                     cArray.up_decimal = this.ctx.tender.info.decimal.up;
-                    cArray.status = audit.flow.status.checking;
+                    cArray.status = audit.change.status.checking;
                     cArray.cin_time = Date.parse(new Date()) / 1000;
                 }
                 await this.transaction.update(this.tableName, cArray, options);
@@ -1151,7 +1151,7 @@ module.exports = app => {
                         pid,
                         type: pushType.change,
                         uid: auditor.uid,
-                        status: audit.flow.status.backnew,
+                        status: audit.change.status.checkNoPre,
                         content: noticeContent,
                     });
                 });
@@ -1412,7 +1412,7 @@ module.exports = app => {
                 '  ) As scb ON cb.id = scb.cbid' +
                 '  WHERE c.tid = ? And c.status = ? And c.valid And ' + filter +
                 '  ORDER BY c.in_time';
-            const sqlParam = [tender.id, stage.order, tender.id, audit.flow.status.checked];
+            const sqlParam = [tender.id, stage.order, tender.id, audit.change.status.checked];
             let changes = await this.db.query(sql, sqlParam);
             if (noValue) {
                 if (data.noValue) {
@@ -1504,7 +1504,7 @@ module.exports = app => {
                 '  ORDER By in_time';
             // 舍入步长
             const step = parseFloat('0.' + '0000000'.substr(0, this.ctx.tender.info.decimal.tp) + '5');
-            const sqlParam = [step, this.ctx.tender.info.decimal.tp, step, this.ctx.tender.info.decimal.tp, tid, tid, audit.flow.status.checked];
+            const sqlParam = [step, this.ctx.tender.info.decimal.tp, step, this.ctx.tender.info.decimal.tp, tid, tid, audit.change.status.checked];
             const data = await this.db.query(sql, sqlParam);
             return data;
         }
@@ -1569,7 +1569,7 @@ module.exports = app => {
                         pid,
                         type: pushType.change,
                         uid: auditor.uid,
-                        status: audit.flow.status.revise,
+                        status: audit.change.status.revise,
                         content: noticeContent,
                     });
                 });
@@ -1853,14 +1853,14 @@ module.exports = app => {
          */
         async isRepeat(cid, code, tid) {
             const sql = 'SELECT COUNT(*) as count FROM ?? WHERE ((`code` = ? AND `status` != ?) OR (`p_code` = ? AND `status` = ?)) AND `cid` != ? AND `tid` = ?';
-            const sqlParam = [this.tableName, code, audit.flow.status.checked, code, audit.flow.status.checked, cid, tid];
+            const sqlParam = [this.tableName, code, audit.change.status.checked, code, audit.change.status.checked, cid, tid];
             const result = await this.db.queryOne(sql, sqlParam);
             return result.count !== 0;
         }
 
         async getAllCheckedChanges(tid) {
             return await this.getAllDataByCondition({
-                where: { tid, status: audit.flow.status.checked },
+                where: { tid, status: audit.change.status.checked },
                 orders: [['in_time', 'desc']],
             });
         }
@@ -1959,7 +1959,7 @@ module.exports = app => {
         async getListByBudgetInfo(tenders) {
             if (tenders) {
                 const sql = 'SELECT * FROM ?? WHERE `status` = ? AND `tid` in (' + this.ctx.helper.getInArrStrSqlFilter(tenders.split(',')) + ') ORDER BY `total_price` DESC LIMIT 0, 10';
-                const params = [this.tableName, audit.flow.status.checked];
+                const params = [this.tableName, audit.change.status.checked];
                 return await this.db.query(sql, params);
             }
             return [];
@@ -1968,7 +1968,7 @@ module.exports = app => {
         async getTotalTpByBudgetInfo(tenders) {
             if (tenders) {
                 const sql = 'SELECT SUM(`total_price`) AS tp FROM ?? WHERE `status` = ? AND `tid` in (' + this.ctx.helper.getInArrStrSqlFilter(tenders.split(',')) + ')';
-                const sqlParam = [this.tableName, audit.flow.status.checked];
+                const sqlParam = [this.tableName, audit.change.status.checked];
                 const result = await this.db.queryOne(sql, sqlParam);
                 return result && result.tp ? result.tp : 0;
             }

+ 44 - 0
app/service/change_audit.js

@@ -1203,6 +1203,50 @@ module.exports = app => {
             const sqlParam = [this.tableName, cid, times, status];
             return transaction ? await transaction.queryOne(sql, sqlParam) : await this.db.queryOne(sql, sqlParam);
         }
+        async getAuditorsByStatus(cid, status, times = 1) {
+            let auditor = [];
+            let sql = '';
+            let sqlParam = '';
+            let cur;
+            switch (status) {
+                case auditConst.status.checking:
+                case auditConst.status.checked:
+                case auditConst.status.checkNoPre:
+                    cur = await this.db.queryOne(`SELECT * From ${this.tableName} where cid = ? AND times = ? AND status = ? AND audit_order != 0 ORDER By times DESC, ` + '`usort` DESC', [cid, times, status]);
+                    if (!cur) return [];
+
+                    sql = 'SELECT la.`uid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cid`, la.`usort`, la.`usite`, la.audit_order, la.audit_type ' +
+                        '  FROM ?? AS la Left Join ?? AS pa On la.`uid` = pa.`id` ' +
+                        '  WHERE la.`cid` = ? and la.`usort` = ? and la.`times` = ?';
+                    sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, cid, cur.usort, times];
+                    auditor = await this.db.query(sql, sqlParam);
+                    break;
+                case auditConst.status.checkNo:
+                    cur = await this.db.queryOne(`SELECT * From ${this.tableName} where cid = ? AND times = ? AND status = ? AND audit_order != 0 ORDER By times DESC, ` + '`usort` DESC', [cid, parseInt(times) - 1, status]);
+                    if (!cur) return [];
+
+                    sql = 'SELECT la.`uid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cid`, la.`usort`, la.`usite`, la.audit_order, la.audit_type ' +
+                        '  FROM ?? AS la Left Join ?? AS pa On la.`uid` = pa.`id` ' +
+                        '  WHERE la.`cid` = ? and la.`usort` = ? and la.`times` = ?';
+                    sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, cid, cur.usort, parseInt(times) - 1];
+                    auditor = await this.db.query(sql, sqlParam);
+                    break;
+                case auditConst.status.revise:
+                    cur = await this.db.queryOne(`SELECT * From ${this.tableName} where cid = ? AND times = ? AND status = ? ORDER By times DESC, ` + '`usort` DESC', [cid, parseInt(times) - 1, status]);
+                    if (!cur) return [];
+
+                    sql = 'SELECT la.`uid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cid`, la.`usort`, la.`usite`, la.audit_order, la.audit_type ' +
+                        '  FROM ?? AS la Left Join ?? AS pa On la.`uid` = pa.`id` ' +
+                        '  WHERE la.`cid` = ? and la.`usort` = ? and la.`times` = ?';
+                    sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, cid, cur.usort, parseInt(times) - 1];
+                    auditor = await this.db.query(sql, sqlParam);
+                    break;
+                case auditConst.status.uncheck:
+                default:
+                    break;
+            }
+            return auditor;
+        }
 
         async saveAudit(cid, times, data) {
             const transaction = await this.db.beginTransaction();

+ 25 - 35
app/view/change/index.ejs

@@ -68,7 +68,7 @@
                     <span class="ml-3">本页小计:<%- page_total %>元</span><span class="ml-3">合计:<%- tp %>元</span>
                 </div>
             </div>
-            <% if (tender.user_id === uid) { %>
+            <% if (tender.user_id === ctx.session.sessionUser.accountId) { %>
             <div class="ml-auto">
                 <a href="#add-bj" data-toggle="modal" data-target="#add-bj" class="btn btn-sm btn-primary pull-right ml-1">新建变更令</a>
                 <a href="#setting" data-toggle="modal" data-target="#setting" class="btn btn-sm btn-outline-primary pull-right ml-1"><i class="fa fa-cog"></i></a>
@@ -83,13 +83,13 @@
             <input id="tenderId" value="<%= tender.id %>" type="hidden">
             <div class="sjs-height-0">
                 <table class="table table-bordered" id="change-table">
-                    <thead>
+                    <thead class="text-center">
                     <tr><th width="3%">序号</th>
                         <th width="18%" id="sort_change">申请编号/变更令号</th><th width="24%">变更工程名称</th>
                         <th width="7%">变更性质</th><% if (ctx.session.sessionProject.page_show.openChangeState) { %><th width="7%">变更令状态</th><% } %>
                         <th width="7%">变更金额</th><th width="7%">正变更金额</th>
                         <th width="7%">负变更金额</th><th width="7%">审批状态</th>
-                        <th width="14%">审批进度</th><th width="4%"></th>
+                        <th width="14%">审批进度</th><th width="4%">操作</th>
                     </tr>
                     </thead>
                     <tbody id="changeList">
@@ -111,40 +111,30 @@
                         <td style="text-align: right"><%= ctx.helper.roundNum(c.total_price, tpUnit) %></td>
                         <td style="text-align: right"><%= ctx.helper.roundNum(c.positive_tp, tpUnit) %></td>
                         <td style="text-align: right"><%= ctx.helper.roundNum(c.negative_tp, tpUnit) %></td>
-                        <% if (c.status === auditConst.status.uncheck && ctx.tender.isTourist) { %>
-                            <td>
-                                上报中
-                            </td>
-                        <% } else if (c.status === auditConst.status.revise && ctx.tender.isTourist) { %>
-                            <td>
-                                修订中
-                            </td>
-                        <% } else if (c.auditStatus) { %>
-                        <td>
-                            <a href="/tender/<%- tender.id %>/change/<%- c.cid %>/information" class="btn <%- auditConst.statusButtonClass[c.status] %> btn-sm">
-                                <%- auditConst.statusButton[c.status] %>
-                            </a>
-                        </td>
-                        <% } else {  %>
-                        <td>
-                            <span class="<%- auditConst.statusClass[c.status] %>"><%- auditConst.statusString[c.status] %></span>
-                        </td>
-                        <% } %>
-                        <% if (c.status === auditConst.status.uncheck) { %>
-                        <td>
-                            待上报
+                        <td class="text-center">
+                            <% if (c.status === auditConst.status.uncheck && c.uid === ctx.session.sessionUser.accountId) { %>
+                                <a href="<%- '/tender/' + ctx.tender.id + '/change/' + c.cid %>/information" class="btn <%- auditConst.statusButtonClass[c.status] %> btn-sm"><%- auditConst.statusButton[c.status] %></a>
+                            <% } else if ((c.status === auditConst.status.checkNo || c.status === auditConst.status.revise) && c.curAuditors && c.uid === ctx.session.sessionUser.accountId) { %>
+                                <a href="<%- '/tender/' + ctx.tender.id + '/change/' + c.cid %>/information" class="btn <%- auditConst.statusButtonClass[c.status] %> btn-sm"><%- auditConst.statusButton[c.status] %></a>
+                            <% } else if (c.status === auditConst.status.checking && c.curAuditors && c.curAuditors.findIndex(x => { return x.uid === ctx.session.sessionUser.accountId; }) >= 0) { %>
+                                <a href="<%- '/tender/' + ctx.tender.id + '/change/' + c.cid %>/information" class="btn <%- auditConst.statusButtonClass[c.status] %> btn-sm"><%- auditConst.statusButton[c.status] %></a>
+                            <% } else if (c.status === auditConst.status.checkNoPre && c.curAuditor2 && c.curAuditor2.findIndex(x => { return x.uid === ctx.session.sessionUser.accountId; }) >= 0) { %>
+                                <a href="<%- '/tender/' + ctx.tender.id + '/change/' + c.cid %>/information" class="btn <%- auditConst.statusButtonClass[c.status] %> btn-sm"><%- auditConst.statusButton[c.status] %></a>
+                            <% } else { %>
+                                <span class="<%- auditConst.auditStringClass[c.status] %>"><%- auditConst.auditString[c.status] %></span>
+                            <% } %>
                         </td>
-                        <% } else if (c.status === auditConst.status.revise) { %>
-                            <td>
-                                待修订
-                            </td>
-                        <% } else if (c.changeAudit) { %>
-                        <td>
-                            <%- c.changeAudit.name %>-<%- c.changeAudit.jobs %>
-                            <span class="<%- auditConst.auditStatusClass[c.changeAudit.status] %>"><%- auditConst.auditStatusString[c.changeAudit.status] %></span>
+                        <td class="<%- auditConst.auditProgressClass[c.status] %>">
+                            <% if (c.curAuditors.length > 0) { %>
+                                <% if (c.curAuditors[0].audit_type === auditType.key.common) { %>
+                                    <a href="#sp-list" data-toggle="modal" data-target="#sp-list" c-id="<%- c.cid %>"><%- c.curAuditors[0].name %><%if (c.curAuditors[0].role !== '' && c.curAuditors[0].role !== null) { %>-<%- c.curAuditors[0].role %><% } %></a>
+                                <% } else { %>
+                                    <a href="#sp-list" data-toggle="modal" data-target="#sp-list" c-id="<%- c.cid %>"><%- ctx.helper.transFormToChinese(c.curAuditors[0].audit_order) + '审' %></a>
+                                <% } %>
+                            <% } %>
+                            <%- auditConst.auditProgress[c.status] %>
                         </td>
-                        <% } else { %><td></td><% } %>
-                        <td><% if (c.uid === uid && (c.status === auditConst.status.uncheck || ((c.status === auditConst.status.back || c.status === auditConst.status.revise) && c.stageChangeNum === 0 && !c.isSettle))) { %><a href="#del-bg" cid="<%= c.cid %>" data-toggle="modal" data-target="#del-bg" class="btn btn-outline-danger btn-sm delete-cid-modal">删除</a><% } %></td>
+                        <td><% if (c.uid === ctx.session.sessionUser.accountId && (c.status === auditConst.status.uncheck || ((c.status === auditConst.status.checkNo || c.status === auditConst.status.revise) && c.stageChangeNum === 0 && !c.isSettle))) { %><a href="#del-bg" cid="<%= c.cid %>" data-toggle="modal" data-target="#del-bg" class="btn btn-outline-danger btn-sm delete-cid-modal">删除</a><% } %></td>
                     </tr>
                     <% } %>
                     <% } %>

+ 47 - 2
app/view/change/modal.ejs

@@ -17,8 +17,32 @@
         </div>
     </div>
 </div>
-
-<% if (tender.user_id === uid) { %>
+<!--审批流程/结果-->
+<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 modal-height-500" style="overflow: auto">
+                        <div class="card mt-3">
+                            <ul class="list-group list-group-flush" id="auditor-list">
+                            </ul>
+                        </div>
+                    </div>
+                    <div class="col-8 modal-height-500" style="overflow: auto" id="audit-list">
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
+            </div>
+        </div>
+    </div>
+</div>
+<% if (tender.user_id === ctx.session.sessionUser.accountId) { %>
 <!--弹出添加变更令-->
 <div class="modal fade" id="add-bj-modal" data-backdrop="static">
     <div class="modal-dialog" role="document">
@@ -150,6 +174,27 @@
     let codeRule = JSON.parse('<%- JSON.stringify(codeRule) %>');
     let connectorRule = '<%- tender.c_connector %>';
     let cRuleFirst = '<%- tender.c_rule_first %>';
+    const tenderId = '<%- ctx.tender.id %>';
+    const auditConst = JSON.parse(unescape('<%- escape(JSON.stringify(auditConst)) %>'));
+    const auditType = JSON.parse('<%- JSON.stringify(auditType) %>');
+
+    $('#audit-list').on('click', 'a', function() {
+        const type = $(this).data('target')
+        const auditCard = $(this).parent().parent()
+        if (type === 'show') {
+            $(this).data('target', 'hide')
+            auditCard.find('.fold-card').slideDown('swing', () => {
+                auditCard.find('#end-target').text($(this).data('idx') + '#')
+                auditCard.find('#fold-btn').text('收起历史审核记录')
+            })
+        } else {
+            $(this).data('target', 'show')
+            auditCard.find('.fold-card').slideUp('swing', () => {
+                auditCard.find('#end-target').text('1#')
+                auditCard.find('#fold-btn').text('展开历史审核记录')
+            })
+        }
+    });
 </script>
 <script src="/public/js/moment/moment.min.js"></script>