浏览代码

变更令审批功能

laiguoran 6 年之前
父节点
当前提交
04c2d7e945

+ 2 - 2
app/const/audit.js

@@ -37,7 +37,7 @@ statusString[status.uncheck] = '';
 statusString[status.checking] = '审批中';
 statusString[status.checked] = '完成';
 statusString[status.checkNo] = '终止';
-statusString[status.back] = '';
+statusString[status.back] = '退回';
 statusString[status.backnew] = '退回';
 
 const statusClass = [];
@@ -45,7 +45,7 @@ statusClass[status.uncheck] = '';
 statusClass[status.checking] = 'text-warning';
 statusClass[status.checked] = 'text-success';
 statusClass[status.checkNo] = 'text-danger';
-statusClass[status.back] = '';
+statusClass[status.back] = 'text-warning';
 statusClass[status.backnew] = 'text-warning';
 
 /* ------------------------------------------------------- */

+ 74 - 6
app/controller/change_controller.js

@@ -63,7 +63,7 @@ module.exports = app => {
                             break;
                         case 5:
                             changeAudit = await ctx.service.changeAudit.getLastUser(c.cid, c.times - 1, status);
-                            auditStatus = 1;
+                            auditStatus = c.uid === ctx.session.sessionUser.accountId ? 1 : 0;
                             break;
                         case 6:
                             changeAudit = await ctx.service.changeAudit.getLastBackUser(c.cid, c.times);
@@ -320,7 +320,6 @@ module.exports = app => {
                 } else if (auditStatus === 3 || auditStatus === 4 || auditStatus === 5 || auditStatus === 7) {
                     // 展示页左侧审批流程列表和清单审批列表数据
                     const auditList2 = await ctx.service.changeAudit.getListGroupByTimes(change.cid, change.times);
-                    // renderData.auditList2 = auditList2;
 
                     // 展示页右侧审批流程列表
                     const auditList3 = [];
@@ -347,7 +346,6 @@ module.exports = app => {
                         const audit_amount = cl.audit_amount !== null && cl.audit_amount !== '' ? cl.audit_amount.split(',') : '';
                         auditTotalCost.push(audit_amount);
                     }
-                    console.log(auditTotalCost);
                     renderData.ototalCost = ototalCost;
                     renderData.ctotalCost = ctotalCost;
                     renderData.stotalCost = stotalCost;
@@ -363,12 +361,47 @@ module.exports = app => {
                             }
                         }
                     }
-                    console.log(auditList2);
                     renderData.auditList2 = auditList2;
                 } else if (auditStatus === 6) {
-                    console.log('ok');
-                }
+                    renderData.changeList = changeList.sort();
+                    let ototalCost = 0;
+                    let ctotalCost = 0;
+                    const auditTotalCost = [];
+                    const auditUnit = [];
+                    for (const cl of changeList) {
+                        ototalCost += parseFloat(ctx.helper.roundNum(ctx.helper.accMul(cl.unit_price, cl.oamount), renderData.tpUnit));
+                        ctotalCost += parseFloat(ctx.helper.roundNum(ctx.helper.accMul(cl.unit_price, cl.camount), renderData.tpUnit));
+                        const audit_amount = cl.audit_amount !== null && cl.audit_amount !== '' ? cl.audit_amount.split(',') : '';
+                        auditTotalCost.push(audit_amount);
+                    }
+                    renderData.ototalCost = ototalCost;
+                    renderData.ctotalCost = ctotalCost;
 
+                    // 清单表页赋值
+                    for (const [index, au] of auditList.entries()) {
+                        if (au.usite !== 0) {
+                            au.list_amount = [];
+                            au.totalCost = 0;
+                            if (au.uid === renderData.uid) {
+                                for (const [auindex, at] of auditTotalCost.entries()) {
+                                    if (at[index - 2] !== undefined) {
+                                        au.list_amount.push(at[index - 2]);
+                                        au.totalCost += parseFloat(ctx.helper.roundNum(ctx.helper.accMul(changeList[auindex].unit_price, at[index - 2]), renderData.tpUnit));
+                                    } else if (at[index - 2] === undefined) {
+                                        au.list_amount.push(changeList[auindex].camount);
+                                        au.totalCost += parseFloat(ctx.helper.roundNum(ctx.helper.accMul(changeList[auindex].unit_price, changeList[auindex].camount), renderData.tpUnit));
+                                    }
+                                }
+                            } else {
+                                for (const [auindex, at] of auditTotalCost.entries()) {
+                                    au.list_amount.push(at[index - 1]);
+                                    au.totalCost += at[index - 1] !== undefined ? parseFloat(ctx.helper.roundNum(ctx.helper.accMul(changeList[auindex].unit_price, at[index - 1]), renderData.tpUnit)) : 0;
+                                }
+                            }
+                        }
+                    }
+                }
+                renderData.auditList = auditList;
                 await this.layout('change/info.ejs', renderData, 'change/info_modal.ejs');
             } catch (err) {
                 this.log(err);
@@ -396,6 +429,41 @@ module.exports = app => {
         }
 
         /**
+         * 变更令审批
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        async approval(ctx) {
+            try {
+                console.log(ctx.request.body);
+                const status = parseInt(ctx.request.body.status);
+                let result = false;
+                switch (status) {
+                    case 3:// 审批通过
+                        result = await ctx.service.change.approvalSuccess(ctx.request.body);
+                        break;
+                    case 4:// 审批终止
+                        result = await ctx.service.change.approvalStop(ctx.request.body);
+                        break;
+                    case 5:// 审批退回到原报人
+                        result = await ctx.service.change.approvalBack(ctx.request.body);
+                        break;
+                    case 6:// 审批退回到上一个审批人
+                        result = await ctx.service.change.approvalBackNew(ctx.request.body);
+                        break;
+                    default:break;
+                }
+                if (!result) {
+                    throw '审批失败';
+                }
+                ctx.redirect('/tender/' + ctx.session.sessionUser.tenderId + '/change');
+            } catch (err) {
+                console.log(err);
+                ctx.redirect('/tender/' + ctx.session.sessionUser.tenderId + '/change/' + ctx.request.body.change_id + '/info');
+            }
+        }
+
+        /**
          * 变更公司管理
          * @param {Object} ctx - egg全局变量
          * @return {void}

+ 91 - 0
app/public/js/change_approval.js

@@ -0,0 +1,91 @@
+'use strict';
+
+/**
+ * 变更令-审批页js
+ *
+ * @author EllisRan.
+ * @date 2018/11/22
+ * @version
+ */
+
+$(document).ready(() => {
+    $('#sp-back input[name="status"]').click(function (e) {
+        if($(e.target).is('label')){
+            return;
+        }
+        if (parseInt($(this).val()) === 4) {
+            $('.change-approval-stop').show();
+            $('.change-approval-back').hide();
+        } else {
+            $('.change-approval-stop').hide();
+            $('.change-approval-back').show();
+        }
+    });
+
+    // 清单输入监控并更新
+    $('body').on('valuechange', '.clist input', function (e, previous) {
+        const amount = $(this).val();
+        const lid = $(this).parents('tr').data('lid');
+        const tr = $('#list tr[data-lid="' + lid + '"]').eq(0);
+        const unitprice = tr.children('td[data-site="4"]').text();
+        tr.children('.amount_cost').text(amount != '' ?
+            roundnum(parseFloat(unitprice).mul(parseFloat(amount)),totalPriceUnit) : '');
+
+        // 统计总金额
+        let totalcost = 0;
+        $('.clist').each(function(){
+            const utotal = $(this).find('.amount_cost').text();
+            totalcost = utotal != '' ? parseFloat(totalcost)+parseFloat(utotal) : parseFloat(totalcost);
+        });
+        $('.amount_totalcost').eq(1).text(totalcost !== 0 ? roundnum(totalcost, totalPriceUnit) : '');
+    });
+
+    // 审批提交与判断
+    $('.approval-btn').on('click', function () {
+        // 判断审批状态
+        let returnflag = true;
+        if ($(this).hasClass('btn-success')) {
+            const sdesc = $('#success-approval').find('textarea').val();
+            if (sdesc === '') {
+                toastr.error('审批意见不能为空!');
+                returnflag = false;
+            }
+            if ($('#w_code').val() === '') {
+                toastr.error('批复文号不能为空!');
+                returnflag = false;
+            } else {
+                $('input[name="w_code"]').val($('#w_code').val());
+            }
+            // 判断并提交变更清单表格数据到表单中
+            const clist = [];
+            $('.clist input').each(function(k, v){
+                const value = $(this).val();
+                const lid = $(this).parents('tr').data('lid');
+                if (value === '') {
+                    toastr.error('清单第' + (k+1) + '行审批变更数量不能为空');
+                    returnflag = false;
+                }
+                clist.push(lid+'_'+value);
+            });
+            $('#change-list-approval').val(clist.join(','));
+
+            if(returnflag) {
+                $('#success-approval').submit();
+            }
+        } else {
+            const sdesc = $('#fail-approval').find('textarea').val();
+            if (sdesc === '') {
+                toastr.error('审批意见不能为空!');
+                returnflag = false;
+            }
+            const type = $('#fail-approval').find('input[name="status"]:checked').val();
+            if (type === undefined) {
+                toastr.error('请选择退回类型!');
+                returnflag = false;
+            }
+            if(returnflag) {
+                $('#fail-approval').submit();
+            }
+        }
+    })
+});

+ 72 - 1
app/public/js/change_calculation.js

@@ -78,4 +78,75 @@ function accSub(arg1,arg2){
 Number.prototype.sub = function (arg){
     return accSub(arg,this);
 
-};
+};
+
+//四舍五入或末尾加零,实现类似php的 sprintf("%.".decimal."f", val);
+function roundnum(val,decimals){
+    if(val !== ''){
+        val = parseFloat(val);
+        if(decimals < 1){
+            val = (Math.round(val)).toString();
+        }else{
+            let num = val.toString();
+            if(num.lastIndexOf('.') == -1){
+                num += '.';
+                num += makezero(decimals);
+                val = num;
+            }else{
+                let valdecimals = num.split('.')[1].length;
+                if(parseInt(valdecimals) < parseInt(decimals)){
+                    num += makezero(parseInt(decimals)-parseInt(valdecimals));
+                    val = num;
+                }else if(parseInt(valdecimals) > parseInt(decimals)){
+                    val = parseFloat(val) != 0 ? Math.round(val.mul(makemultiple(decimals))).div(makemultiple(decimals)) : makedecimalzero(decimals);
+                    let num = val.toString();
+                    if(num.lastIndexOf('.') == -1){
+                        num += '.';
+                        num += makezero(decimals);
+                        val = num;
+                    }else {
+                        let valdecimals = num.split('.')[1].length;
+                        if (parseInt(valdecimals) < parseInt(decimals)) {
+                            num += makezero(parseInt(decimals) - parseInt(valdecimals));
+                            val = num;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return val;
+}
+
+//根据位数生成编号,3位-》001 ,5位-》00001
+function makenum(num){
+    let arr = new Array(num);
+    for(let i=0;i< num;i++){
+        if(i != num-1){
+            arr[i] = 0;
+        }else{
+            arr[i] = 1;
+        }
+    }
+    return arr.join('');
+}
+//生成num位的0
+function makezero(num){
+    let arr = new Array(num);
+    for(let i=0;i< num;i++){
+        arr[i] = 0;
+    }
+    return arr.join('');
+}
+//生成num小数位数的0.
+function makedecimalzero(num){
+    if(num < 1){
+        return '0';
+    }else{
+        return '0.'+makezero(num);
+    }
+}
+//生成num位的10倍数
+function makemultiple(num){
+    return Math.pow(10,parseInt(num));
+}

+ 0 - 71
app/public/js/change_set.js

@@ -464,77 +464,6 @@ function totalamount(decimal){
     $('.otatalamount').eq(1).text(ototalnum != 0 ? roundnum(ototalnum,decimal) : zero);
 }
 
-//四舍五入或末尾加零,实现类似php的 sprintf("%.".decimal."f", val);
-function roundnum(val,decimals){
-    if(val !== ''){
-        val = parseFloat(val);
-        if(decimals < 1){
-            val = (Math.round(val)).toString();
-        }else{
-            let num = val.toString();
-            if(num.lastIndexOf('.') == -1){
-                num += '.';
-                num += makezero(decimals);
-                val = num;
-            }else{
-                let valdecimals = num.split('.')[1].length;
-                if(parseInt(valdecimals) < parseInt(decimals)){
-                    num += makezero(parseInt(decimals)-parseInt(valdecimals));
-                    val = num;
-                }else if(parseInt(valdecimals) > parseInt(decimals)){
-                    val = parseFloat(val) != 0 ? Math.round(val.mul(makemultiple(decimals))).div(makemultiple(decimals)) : makedecimalzero(decimals);
-                    let num = val.toString();
-                    if(num.lastIndexOf('.') == -1){
-                        num += '.';
-                        num += makezero(decimals);
-                        val = num;
-                    }else {
-                        let valdecimals = num.split('.')[1].length;
-                        if (parseInt(valdecimals) < parseInt(decimals)) {
-                            num += makezero(parseInt(decimals) - parseInt(valdecimals));
-                            val = num;
-                        }
-                    }
-                }
-            }
-        }
-    }
-    return val;
-}
-
-//根据位数生成编号,3位-》001 ,5位-》00001
-function makenum(num){
-    let arr = new Array(num);
-    for(let i=0;i< num;i++){
-        if(i != num-1){
-            arr[i] = 0;
-        }else{
-            arr[i] = 1;
-        }
-    }
-    return arr.join('');
-}
-//生成num位的0
-function makezero(num){
-    let arr = new Array(num);
-    for(let i=0;i< num;i++){
-        arr[i] = 0;
-    }
-    return arr.join('');
-}
-//生成num小数位数的0.
-function makedecimalzero(num){
-    if(num < 1){
-        return '0';
-    }else{
-        return '0.'+makezero(num);
-    }
-}
-//生成num位的10倍数
-function makemultiple(num){
-    return Math.pow(10,parseInt(num));
-}
-
 // 找出单位对应的小数位数值
 function findDecimal(unit) {
     let value = 2;

+ 2 - 0
app/router.js

@@ -150,6 +150,8 @@ module.exports = app => {
 
     app.post('/change/save', sessionAuth, 'changeController.save');
 
+    app.post('/change/approval', sessionAuth, 'changeController.approval');
+
     // 变更单位管理
     app.post('/change/update/company', sessionAuth, 'changeController.updateCompany');
 

+ 281 - 2
app/service/change.js

@@ -291,7 +291,7 @@ module.exports = app => {
                 if (postData.changestatus !== undefined && parseInt(postData.changestatus) === 1) {
                     change_status = true;
                     // 更新原报人审批状态
-                    await this.transaction.update(this.ctx.service.changeAudit.tableName, { id: lastUser.id, status: 3 });
+                    await this.transaction.update(this.ctx.service.changeAudit.tableName, { id: lastUser.id, status: 3, sin_time: new Date() });
                 }
                 // 再插入postData里的变更审批人和清单
                 if (postData.changeaudit !== undefined && postData.changeaudit !== '') {
@@ -390,7 +390,286 @@ module.exports = app => {
             }
             return result;
         }
-    }
 
+        /**
+         * 审批通过
+         * @param {int} postData - 表单提交的数据
+         * @return {void}
+         */
+        async approvalSuccess(postData) {
+            // 初始化事务
+            this.transaction = await this.db.beginTransaction();
+            let result = false;
+            try {
+                // 设置审批人通过
+                const audit_update = {
+                    id: postData.audit_id,
+                    sdesc: postData.sdesc,
+                    status: 3,
+                    sin_time: new Date(),
+                };
+                const change_update = {
+                    w_code: postData.w_code,
+                    status: 2,
+                    cin_time: Date.parse(new Date()) / 1000,
+                };
+                await this.transaction.update(this.ctx.service.changeAudit.tableName, audit_update);
+                // 清单数据更新
+                const bills_list = postData.bills_list.split(',');
+                let total_price = 0;
+                for (const bl of bills_list) {
+                    const listInfo = bl.split('_');
+                    const lid = listInfo[0];
+                    const amount = listInfo[1];
+                    const changeListInfo = await this.ctx.service.changeAuditList.getDataById(lid);
+                    if (changeListInfo !== undefined) {
+                        total_price += this.ctx.helper.accMul(changeListInfo.unit_price, parseFloat(amount));
+                        const audit_amount = changeListInfo.audit_amount !== null && changeListInfo.audit_amount !== '' ? changeListInfo.audit_amount.split(',') : [];
+                        audit_amount.push(amount);
+                        const list_update = {
+                            id: lid,
+                            audit_amount: audit_amount.join(','),
+                        };
+                        if (postData.audit_next_id === undefined) {
+                            list_update.samount = amount;
+                        }
+                        await this.transaction.update(this.ctx.service.changeAuditList.tableName, list_update);
+                    }
+                }
+                if (postData.audit_next_id === undefined) {
+                    // 变更令审批完成
+                    change_update.status = 3;
+                    change_update.p_code = postData.p_code;
+                    change_update.sin_time = Date.parse(new Date()) / 1000;
+                    change_update.total_price = total_price;
+                } else {
+                    // 设置下一个审批人为审批状态
+                    const nextAudit_update = {
+                        id: postData.audit_next_id,
+                        status: 2,
+                    };
+                    await this.transaction.update(this.ctx.service.changeAudit.tableName, nextAudit_update);
+                }
+                const options = {
+                    where: {
+                        cid: postData.change_id,
+                    },
+                };
+                await this.transaction.update(this.tableName, change_update, options);
+                await this.transaction.commit();
+                result = true;
+            } catch (error) {
+                await this.transaction.rollback();
+                result = false;
+            }
+            return result;
+        }
+
+        /**
+         * 审批终止
+         * @param {int} postData - 表单提交的数据
+         * @return {void}
+         */
+        async approvalStop(postData) {
+            // 初始化事务
+            this.transaction = await this.db.beginTransaction();
+            let result = false;
+            try {
+                // 设置审批人终止
+                const audit_update = {
+                    id: postData.audit_id,
+                    sdesc: postData.sdesc,
+                    status: 4,
+                    sin_time: new Date(),
+                };
+                await this.transaction.update(this.ctx.service.changeAudit.tableName, audit_update);
+                // 设置变更令终止
+                const change_update = {
+                    w_code: postData.w_code,
+                    status: 4,
+                    cin_time: Date.parse(new Date()) / 1000,
+                };
+                const options = {
+                    where: {
+                        cid: postData.change_id,
+                    },
+                };
+                await this.transaction.update(this.tableName, change_update, options);
+                await this.transaction.commit();
+                result = true;
+            } catch (error) {
+                await this.transaction.rollback();
+                result = false;
+            }
+            return result;
+        }
+
+        /**
+         * 审批退回到原报人
+         * @param {int} postData - 表单提交的数据
+         * @return {void}
+         */
+        async approvalBack(postData) {
+            // 初始化事务
+            this.transaction = await this.db.beginTransaction();
+            let result = false;
+            try {
+                const changeInfo = await this.getDataByCondition({ cid: postData.change_id });
+                // 设置审批人退回
+                const audit_update = {
+                    id: postData.audit_id,
+                    sdesc: postData.sdesc,
+                    status: 5,
+                    sin_time: new Date(),
+                };
+                await this.transaction.update(this.ctx.service.changeAudit.tableName, audit_update);
+                // 新增新一次的审批人列表
+                // 获取当前次数审批人列表
+                const auditList = await this.ctx.service.changeAudit.getListGroupByTimes(changeInfo.cid, changeInfo.times);
+                const lastauditInfo = await this.ctx.service.changeAudit.getLastUser(changeInfo.cid, changeInfo.times, 1, 0);
+                let usort = lastauditInfo.usort + 1;
+                const newTimes = changeInfo.times + 1;
+                const insert_audit_array = [];
+                for (const al of auditList) {
+                    const insert_audit = {
+                        tid: al.tid,
+                        cid: al.cid,
+                        uid: al.uid,
+                        name: al.name,
+                        jobs: al.jobs,
+                        company: al.company,
+                        times: newTimes,
+                        usite: al.usite,
+                        usort,
+                        status: al.usite !== 0 ? 1 : 2,
+                    };
+                    insert_audit_array.push(insert_audit);
+                    usort++;
+                }
+                await this.transaction.insert(this.ctx.service.changeAudit.tableName, insert_audit_array);
+                // 设置变更令退回
+                const change_update = {
+                    w_code: postData.w_code,
+                    status: 5,
+                    times: newTimes,
+                    cin_time: Date.parse(new Date()) / 1000,
+                };
+                const options = {
+                    where: {
+                        cid: postData.change_id,
+                    },
+                };
+                await this.transaction.update(this.tableName, change_update, options);
+                await this.transaction.commit();
+                result = true;
+            } catch (error) {
+                await this.transaction.rollback();
+                result = false;
+            }
+            return result;
+        }
+
+        /**
+         * 审批退回到上一个审批人
+         * @param {int} postData - 表单提交的数据
+         * @return {void}
+         */
+        async approvalBackNew(postData) {
+            // 初始化事务
+            this.transaction = await this.db.beginTransaction();
+            let result = false;
+            try {
+                const changeInfo = await this.getDataByCondition({ cid: postData.change_id });
+                // 设置审批人退回
+                const audit_update = {
+                    id: postData.audit_id,
+                    sdesc: postData.sdesc,
+                    status: 6,
+                    sin_time: new Date(),
+                };
+                await this.transaction.update(this.ctx.service.changeAudit.tableName, audit_update);
+                // 获取当前审批人信息
+                const auditInfo = await this.ctx.service.changeAudit.getDataById(postData.audit_id);
+
+                // 获取当前次数审批人列表
+                const auditList = await this.ctx.service.changeAudit.getNextAuditList(changeInfo.cid, auditInfo.usort);
+
+                let usort = auditInfo.usort + 1;
+
+                // 获取上一个审批人信息
+                const lastauditInfo = await this.ctx.service.changeAudit.getDataById(postData.audit_last_id);
+
+                // 新增2个审批人到审批列表中
+                const insert_audit1 = {
+                    tid: lastauditInfo.tid,
+                    cid: lastauditInfo.cid,
+                    uid: lastauditInfo.uid,
+                    name: lastauditInfo.name,
+                    jobs: lastauditInfo.jobs,
+                    company: lastauditInfo.company,
+                    times: lastauditInfo.times,
+                    usite: lastauditInfo.usite,
+                    usort,
+                    status: 2,
+                };
+                await this.transaction.insert(this.ctx.service.changeAudit.tableName, insert_audit1);
+                usort++;
+                // 新增2个审批人到审批列表中
+                const insert_audit2 = {
+                    tid: auditInfo.tid,
+                    cid: auditInfo.cid,
+                    uid: auditInfo.uid,
+                    name: auditInfo.name,
+                    jobs: auditInfo.jobs,
+                    company: auditInfo.company,
+                    times: auditInfo.times,
+                    usite: auditInfo.usite,
+                    usort,
+                    status: 1,
+                };
+                await this.transaction.insert(this.ctx.service.changeAudit.tableName, insert_audit2);
+
+                // 把接下未审批的审批人排序都加2
+                for (const al of auditList) {
+                    const audit_update = {
+                        id: al.id,
+                        usort: al.usort + 2,
+                    };
+                    await this.transaction.update(this.ctx.service.changeAudit.tableName, audit_update);
+                }
+
+                // 审批列表数据也要回退
+                const changeList = await this.ctx.service.changeAuditList.getAllDataByCondition({ where: { cid: changeInfo.cid } });
+                for (const cl of changeList) {
+                    const audit_amount = cl.audit_amount.split(',');
+                    audit_amount.splice(-1, 1);
+                    const list_update = {
+                        id: cl.id,
+                        audit_amount: audit_amount.join(','),
+                    };
+                    await this.transaction.update(this.ctx.service.changeAuditList.tableName, list_update);
+                }
+
+                // 设置变更令退回
+                const change_update = {
+                    w_code: postData.w_code,
+                    status: 6,
+                    cin_time: Date.parse(new Date()) / 1000,
+                };
+                const options = {
+                    where: {
+                        cid: postData.change_id,
+                    },
+                };
+                await this.transaction.update(this.tableName, change_update, options);
+                await this.transaction.commit();
+                result = true;
+            } catch (error) {
+                await this.transaction.rollback();
+                result = false;
+            }
+            return result;
+        }
+    }
     return Change;
 };

+ 32 - 11
app/service/change_audit.js

@@ -28,9 +28,10 @@ module.exports = app => {
          * @param {int} cid - 变更令id
          * @param {int} times - 次数
          * @param {int} site - 位置
+         * @param {int} status - 状态
          * @return {void}
          */
-        async getLastUser(cid, times, site = 1) {
+        async getLastUser(cid, times, site = 1, status = 1) {
             this.initSqlBuilder();
             this.sqlBuilder.setAndWhere('cid', {
                 value: this.db.escape(cid),
@@ -40,10 +41,12 @@ module.exports = app => {
                 value: times,
                 operate: '=',
             });
-            this.sqlBuilder.setAndWhere('status', {
-                value: 1,
-                operate: '!=',
-            });
+            if (status === 1) {
+                this.sqlBuilder.setAndWhere('status', {
+                    value: 1,
+                    operate: '!=',
+                });
+            }
             if (site === 0) {
                 this.sqlBuilder.setAndWhere('usite', {
                     value: site,
@@ -95,9 +98,8 @@ module.exports = app => {
             const statusConst = audit.flow.status;
             const auditStatusConst = audit.flow.auditStatus;
             const uid = this.ctx.session.sessionUser.accountId;
-            const changeAuditInfo = await this.getAllDataByCondition({ where: { cid: change.cid, times: change.times, uid }, order: ['id', 'DESC'] });
-
-            if (changeAuditInfo === null) {
+            const changeAuditInfo = await this.getAllDataByCondition({ where: { cid: change.cid, times: change.times, uid }, orders: [['id', 'desc']], limit: 1, offset: 0 });
+            if (changeAuditInfo === null || changeAuditInfo[0].status === undefined) {
                 // 无权限查看此变更令
                 return 0;
             }
@@ -117,10 +119,10 @@ module.exports = app => {
             } else if (change.status === statusConst.checkNo) {
                 // 已终止
                 return 5;
-            } else if (change.status === statusConst.checking && changeAuditInfo.status === auditStatusConst.checking) {
+            } else if ((change.status === statusConst.checking || change.status === statusConst.backnew) && changeAuditInfo[0].status === auditStatusConst.checking) {
                 // 待你审批
                 return 6;
-            } else if (change.status === statusConst.checking && changeAuditInfo.status !== auditStatusConst.checking) {
+            } else if ((change.status === statusConst.checking || change.status === statusConst.backnew) && changeAuditInfo[0].status !== auditStatusConst.checking) {
                 // 审批中但你未到你审批或你已审批
                 return 7;
             }
@@ -154,7 +156,12 @@ module.exports = app => {
                         'cid = ? ORDER BY usort';
                     sqlParam = [this.tableName, change.cid];
                     break;
-                case 6:// 待你审批
+                case 6: // 审批中
+                    sql = 'SELECT * FROM (SELECT MAX(usort) as ust FROM ?? ' +
+                        'WHERE cid = ? and times = ? GROUP BY usite ) as b ' +
+                        'JOIN ?? as a ON a.usort = b.ust WHERE cid = ? and times = ? ORDER BY usite';
+                    sqlParam = [this.tableName, change.cid, change.times, this.tableName, change.cid, change.times];
+                    break;
                 default:// 无权限查看此变更令
                     break;
             }
@@ -202,6 +209,20 @@ module.exports = app => {
             const list = await this.db.query(sql, sqlParam);
             return list;
         }
+
+        /**
+         * 获取比sort大的审批人列表
+         * @param {Object} cid - 变更令id
+         * @param {int} usort - 排序
+         * @return {object} 返回结果
+         */
+        async getNextAuditList(cid, usort) {
+            const sql = 'SELECT * FROM ?? WHERE ' +
+                'cid = ? AND usort > ?';
+            const sqlParam = [this.tableName, cid, usort];
+            const list = await this.db.query(sql, sqlParam);
+            return list;
+        }
     }
 
     return ChangeAudit;

+ 96 - 12
app/view/change/info.ejs

@@ -134,13 +134,13 @@
             <div>
                 <a href="#sub-ap" data-category="save_change" data-toggle="modal" data-target="#sub-ap" class="btn btn-sm btn-success pull-right">保存修改</a>
                 <a href="#sub-ap" data-category="up_change" data-toggle="modal" data-target="#sub-ap" class="btn btn-primary btn-sm pull-right">上报审批</a>
-                <a href="#" class="btn btn-outline-danger btn-sm pull-right text-truncate" style="max-width: 100px;" title="删除 <%- change.code %>">删除 <%- change.code %></a>
+                <!--<a href="#" class="btn btn-outline-danger btn-sm pull-right text-truncate" style="max-width: 100px;" title="删除 <%- change.code %>">删除 <%- change.code %></a>-->
             </div>
             <% } else if (auditStatus === 2) { %>
             <div>
-                <a href="#sub-ap" data-toggle="modal" class="btn btn-sm btn-success pull-right">保存修改</a>
-                <a href="#sub-sp" data-toggle="modal" data-target="#sub-sp" class="btn btn-primary btn-sm pull-right">重新上报</a>
-                <a href="#" class="btn btn-outline-danger btn-sm pull-right text-truncate" style="max-width: 100px;" title="删除 <%- change.code %>">删除 <%- change.code %></a>
+                <a href="#sub-ap" data-category="save_change" data-toggle="modal" data-target="#sub-ap" class="btn btn-sm btn-success pull-right">保存修改</a>
+                <a href="#sub-ap" data-category="up_change" data-toggle="modal" data-target="#sub-ap" class="btn btn-primary btn-sm pull-right">重新上报</a>
+                <!--<a href="#" class="btn btn-outline-danger btn-sm pull-right text-truncate" style="max-width: 100px;" title="删除 <%- change.code %>">删除 <%- change.code %></a>-->
             </div>
             <% } else if (auditStatus === 3) { %>
             <div>
@@ -158,7 +158,6 @@
             <div>
                 <a href="#sp-done" data-toggle="modal" data-target="#sp-done" class="btn btn-success btn-sm pull-right">审批通过</a>
                 <a href="#sp-back" data-toggle="modal" data-target="#sp-back" class="btn btn-warning btn-sm pull-right">审批退回</a>
-                <a href="#sp-end" data-toggle="modal" data-target="#sp-end" class="btn btn-danger btn-sm pull-right">审批终止</a>
             </div>
             <% } else if (auditStatus === 7) { %>
             <div>
@@ -285,13 +284,11 @@
                     <form>
                         <div class="form-group">
                             <label>申请编号</label>
-                            <a href="#" class="pull-right" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="自动编号"><i class="fa fa-repeat"></i></a>
                             <input class="form-control" value="<%- change.code %>" type="text" readonly>
                         </div>
                         <% if (auditStatus === 4) { %>
                         <div class="form-group">
                             <label>批复编号</label>
-                            <a href="#" class="pull-right" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="自动编号"><i class="fa fa-repeat"></i></a>
                             <input class="form-control" value="<%- change.p_code %>" type="text" readonly>
                         </div>
                         <% } %>
@@ -324,7 +321,7 @@
                 <div class="col-md-4" style="z-index:999">
                     <form>
                         <div class="form-group">
-                            <label><b class="text-danger">*&nbsp;</b>工程变更理由及内容</label>
+                            <label>工程变更理由及内容</label>
                             <textarea class="form-control" rows="6" readonly><%- change.content %></textarea>
                         </div>
                         <div class="form-group">
@@ -395,7 +392,7 @@
                             </div>
                         </div>
                         <div class="form-group">
-                            <label><b class="text-danger">*&nbsp;</b>批复文号</label>
+                            <label>批复文号</label>
                             <input class="form-control" id="w_code" placeholder="" type="text" value="<%- change.w_code %>" <% if (auditStatus !== 6) { %>readonly<% } %>>
                         </div>
                     </form>
@@ -573,7 +570,6 @@
                             <td><%= ctx.helper.roundNum(ctx.helper.accMul(cl.unit_price, cl.camount), tpUnit) %></td>
                             <% for (const audit of auditList2) { %>
                                 <% if (audit.usite !== 0) { %>
-                                <% %>
                                 <td><%= audit.list_amount[cindex] !== undefined ? ctx.helper.roundNum(audit.list_amount[cindex], ctx.helper.findDecimal(cl.unit)) : '' %></td>
                                 <td><%= audit.list_amount[cindex] !== undefined ? ctx.helper.roundNum(ctx.helper.accMul(cl.unit_price, audit.list_amount[cindex]), tpUnit) : '' %></td>
                                 <% } %>
@@ -596,7 +592,80 @@
                     </tfoot>
                 </table>
             <% } else if (auditStatus === 6) { %>
-
+                <table class="table table-striped table-bordered nowrap qd-table table-list" id="tablelist" cellspacing="0" style="width:100%;">
+                    <thead>
+                    <tr>
+                        <th rowspan="2" class="text-center">清单编号</th>
+                        <th rowspan="2" class="text-center">名称</th>
+                        <th rowspan="2" class="text-center">变更详情</th>
+                        <th rowspan="2" class="text-center">单位</th>
+                        <th rowspan="2" class="text-center">单价</th>
+                        <th colspan="2" class="text-center">原设计</th>
+                        <th colspan="2" class="text-center">申报变更</th>
+                        <% for (const audit of auditList) { %>
+                            <% if (audit.usite !== 0) { %>
+                                <th colspan="2" class="text-center"><%= audit.name %> 审批</th>
+                            <% } %>
+                        <% } %>
+                    </tr>
+                    <tr>
+                        <th class="text-center">数量</th>
+                        <th class="text-center">金额</th>
+                        <th class="text-center">数量</th>
+                        <th class="text-center">金额</th>
+                        <% for (const audit of auditList) { %>
+                            <% if (audit.usite !== 0) { %>
+                                <th class="text-center">数量</th>
+                                <th class="text-center">金额</th>
+                            <% } %>
+                        <% } %>
+                    </tr>
+                    </thead>
+                    <tbody id="list">
+                    <% const audittotalCost = []; %>
+                    <% for (const [cindex,cl] of changeList.entries()) { %>
+                        <tr class="clist" data-lid="<%= cl.id %>">
+                            <td><%= cl.code %></td>
+                            <td><%= cl.name %></td>
+                            <td><%= cl.detail %></td>
+                            <td><%= cl.unit %></td>
+                            <td data-site="4"><%= ctx.helper.roundNum(cl.unit_price, tpUnit) %></td>
+                            <td><%= ctx.helper.roundNum(cl.oamount, ctx.helper.findDecimal(cl.unit)) %></td>
+                            <td><%= ctx.helper.roundNum(ctx.helper.accMul(cl.unit_price, cl.oamount), tpUnit) %></td>
+                            <td><%= ctx.helper.roundNum(cl.camount, ctx.helper.findDecimal(cl.unit)) %></td>
+                            <td><%= ctx.helper.roundNum(ctx.helper.accMul(cl.unit_price, cl.camount), tpUnit) %></td>
+                            <% for (const audit of auditList) { %>
+                                <% if (audit.usite !== 0) { %>
+                                    <% if (uid === audit.uid) { %>
+                                    <td>
+                                        <input class="form-control form-control-sm"  style="min-width:80px" placeholder="变更数量" type="text"
+                                               onkeyup="RegNum(this,event,<%= ctx.helper.findDecimal(cl.unit) %>)"
+                                               value="<%= audit.list_amount[cindex] !== undefined ?
+                                                       ctx.helper.roundNum(audit.list_amount[cindex], ctx.helper.findDecimal(cl.unit)) : '' %>">
+                                    </td>
+                                    <% } else { %>
+                                    <td><%= audit.list_amount[cindex] !== undefined ? ctx.helper.roundNum(audit.list_amount[cindex], ctx.helper.findDecimal(cl.unit)) : '' %></td>
+                                    <% } %>
+                                    <td<% if (uid === audit.uid) { %> class="amount_cost"<% } %>><%= audit.list_amount[cindex] !== undefined ? ctx.helper.roundNum(ctx.helper.accMul(cl.unit_price, audit.list_amount[cindex]), tpUnit) : '' %></td>
+                                <% } %>
+                            <% } %>
+                            </td>
+                        </tr>
+                    <% } %>
+                    </tbody>
+                    <tfoot>
+                    <tr class="info">
+                        <td>合计</td><td></td><td></td><td></td><td></td><td></td>
+                        <td><%= ctx.helper.roundNum(ototalCost, tpUnit) %></td><td></td>
+                        <td><%= ctx.helper.roundNum(ctotalCost, tpUnit) %></td>
+                        <% for (const audit of auditList) { %>
+                            <% if (audit.usite !== 0) { %>
+                            <td></td><td <% if (uid === audit.uid) { %>class="amount_totalcost"<% } %>><%=audit.totalCost !== 0 ? ctx.helper.roundNum(audit.totalCost, tpUnit) : '' %></td>
+                            <% } %>
+                        <% } %>
+                    </tr>
+                    </tfoot>
+                </table>
             <% } %>
         </div>
 
@@ -655,6 +724,7 @@
         };
     })
     let table = '';
+    const totalPriceUnit = '<%- tpUnit %>';
 </script>
 <script src="/public/js/datatable/jquery.dataTables.min.js"></script>
 <script src="/public/js/datatable/dataTables.bootstrap4.min.js"></script>
@@ -665,7 +735,6 @@
 <script>
     const whiteList = JSON.parse('<%- JSON.stringify(whiteList) %>');
     const changeUnits = JSON.parse('<%- JSON.stringify(changeUnits) %>');
-    const totalPriceUnit = '<%- tpUnit %>';
     const billsTable = {
         columnDefs: [
             { className: 'allwidth1', width: 100, targets: 0 },
@@ -695,5 +764,20 @@
     }
 </script>
 <script src="/public/js/change_show.js"></script>
+<% } else if (auditStatus === 6) { %>
+<script>
+    const billsTable = {
+        columnDefs: [
+            { className: 'allwidth1', width: 100, targets: 0 },
+            { className: 'allwidth2', width: 150, targets: [1,2] },
+            { className: 'allwidth5', width: 60, targets: 3 },
+            { className: 'allwidth3',width: 80, targets: '_all' }
+        ],
+        fixedColumns: {
+            leftColumns: 5
+        }
+    }
+</script>
+<script src="/public/js/change_approval.js"></script>
 <% } %>
 <script src="/public/js/change_detail.js"></script>

+ 151 - 2
app/view/change/info_modal.ejs

@@ -190,7 +190,9 @@
                             <ul class="list-group list-group-flush">
                                 <% for (const [aindex,al] of auditList3[time].entries()) { %>
                                 <li class="list-group-item">
-                                    <% if (al.usite === 0 && al.status === 3) { %>
+                                    <% if (al.usite === 0 && al.status === 2) { %>
+                                    <span class="pull-right">重新上报中</span>
+                                    <% } else if (al.usite === 0 && al.status === 3) { %>
                                     <span class="text-success pull-right">上报</span>
                                     <% } else if (al.usite !== 0 && al.status === 2) { %>
                                     <span class="pull-right">审批中</span>
@@ -202,7 +204,9 @@
                                     <span class="text-warning pull-right">审批退回 </span>
                                     <% } %>
                                     <h5 class="card-title">
-                                        <% if (al.usite === 0 ) { %>
+                                        <% if (al.usite === 0 && al.status === 2 ) { %>
+                                        <i class="fa fa-play-circle fa-rotate-90"></i>
+                                        <% } else if (al.usite === 0 && al.status === 3 ) { %>
                                         <i class="fa fa-play-circle fa-rotate-90 text-success"></i>
                                         <% } else if (al.status === 1 || al.status === 2) { %>
                                         <i class="fa <% if (aindex+1 === auditList3[time].length) { %>fa-stop-circle<% } else { %>fa-chevron-circle-down<% } %> "></i>
@@ -234,6 +238,151 @@
 </div>
 <% } %>
 
+<% if (auditStatus === 6) { %>
+    <!--审批通过-->
+    <div class="modal fade" id="sp-done" data-backdrop="static">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">审批通过</h5>
+                </div>
+                <form action="/change/approval?_csrf=<%= ctx.csrf %>" method="post" id="success-approval">
+                <div class="modal-body">
+                    <div class="card mt-3">
+                        <ul class="list-group list-group-flush">
+                            <% for (const [index,a] of auditList.entries()) { %>
+                            <li class="list-group-item">
+                                <% if (a.status === 3 && a.usort === 0) { %>
+                                <span class="text-success pull-right">上报</span>
+                                <% } else if (a.status === 3 && a.usort !== 0) { %>
+                                <span class="text-success pull-right">审批通过</span>
+                                <% } else if (a.status === 2) { %>
+                                <span class="pull-right">审批中</span>
+                                <% } %>
+                                <h5 class="card-title">
+                                    <% if (a.usort === 0) { %>
+                                    <i class="fa fa-play-circle fa-rotate-90 <% if (a.status === 3) { %>text-success<% } %>"></i>
+                                    <% } else if (a.usort !== 0 && index+1 !== auditList.length) { %>
+                                    <i class="fa fa-chevron-circle-down <% if (a.status === 3) { %>text-success<% } %>"></i>
+                                    <% } else if (a.usort !== 0 && index+1 === auditList.length) { %>
+                                    <i class="fa fa-stop-circle"></i>
+                                    <% } %>
+                                    <%= a.name %>&nbsp;<small class="text-muted"><%= a.jobs%></small>
+                                </h5>
+                                <% if (a.sin_time !== null || (a.sdesc !== '' && a.sdesc !== null)) { %>
+                                    <p class="card-text"><%= a.sdesc %>&nbsp;<%= moment(a.sin_time).format('YYYY-MM-DD') %></p>
+                                <% } %>
+                                <% if (a.status === 2) { %>
+                                    <div class="form-group">
+                                        <label>审批意见<b class="text-danger">*</b></label>
+                                        <textarea class="form-control" name="sdesc"></textarea>
+                                        <input type="hidden" name="audit_id" value="<%= a.id %>">
+                                        <% if (a.usort !== 0 && index+1 === auditList.length) { %>
+                                        <!--终审填写批复编号-->
+                                        <div class="form-group mt-3">
+                                            <label><b class="text-danger">*&nbsp;</b>批复编号</label>
+                                            <input class="form-control" value="<%= change.name %>" name="p_code" type="text">
+                                        </div>
+                                        <% } else { %>
+                                            <input type="hidden" name="audit_next_id" value="<%= auditList[index+1].id %>">
+                                        <% } %>
+                                    </div>
+                                <% } %>
+                            </li>
+                            <% } %>
+                        </ul>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <input type="hidden" name="status" value="3">
+                    <input type="hidden" name="w_code" value="">
+                    <input type="hidden" name="change_id" value="<%= change.cid %>">
+                    <input type="hidden" name="bills_list" id="change-list-approval" value="">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                    <button type="button" class="btn btn-success approval-btn">确认通过</button>
+                </div>
+                </form>
+            </div>
+        </div>
+    </div>
+    <!--审批退回-->
+    <div class="modal fade" id="sp-back" data-backdrop="static">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">审批退回</h5>
+                </div>
+                <form action="/change/approval?_csrf=<%= ctx.csrf %>" method="post" id="fail-approval">
+                <div class="modal-body">
+                    <div class="card mt-3">
+                        <ul class="list-group list-group-flush">
+                            <% for (const [index,a] of auditList.entries()) { %>
+                                <li class="list-group-item">
+                                    <% if (a.status === 3 && a.usort === 0) { %>
+                                        <span class="text-success pull-right">上报</span>
+                                    <% } else if (a.status === 3 && a.usort !== 0) { %>
+                                        <span class="text-success pull-right">审批通过</span>
+                                    <% } else if (a.status === 2) { %>
+                                        <span class="pull-right">审批中</span>
+                                    <% } %>
+                                    <h5 class="card-title">
+                                        <% if (a.usort === 0) { %>
+                                            <i class="fa fa-play-circle fa-rotate-90 <% if (a.status === 3) { %>text-success<% } %>"></i>
+                                        <% } else if (a.usort !== 0 && index+1 !== auditList.length) { %>
+                                            <i class="fa fa-chevron-circle-down <% if (a.status === 3) { %>text-success<% } %>"></i>
+                                        <% } else if (a.usort !== 0 && index+1 === auditList.length) { %>
+                                            <i class="fa fa-stop-circle"></i>
+                                        <% } %>
+                                        <%= a.name %>&nbsp;<small class="text-muted"><%= a.jobs%></small>
+                                    </h5>
+                                    <% if (a.sin_time !== null || (a.sdesc !== '' && a.sdesc !== null)) { %>
+                                        <p class="card-text"><%= a.sdesc %>&nbsp;<%= moment(a.sin_time).format('YYYY-MM-DD') %></p>
+                                    <% } %>
+                                    <% if (a.status === 2) { %>
+                                        <div class="form-group">
+                                            <label>审批意见<b class="text-danger">*</b></label>
+                                            <textarea class="form-control" name="sdesc"></textarea>
+                                            <input type="hidden" name="audit_id" value="<%= a.id %>">
+                                        </div>
+                                        <div class="alert alert-warning">
+                                            <div class="form-check form-check-inline">
+                                                <input class="form-check-input" type="radio" name="status" id="change-back" value="5">
+                                                <label class="form-check-label" for="change-back">退回上报 <%= auditList[0].name %></label>
+                                            </div>
+                                            <% if (index !== 1) { %>
+                                            <div class="form-check form-check-inline">
+                                                <input class="form-check-input" type="radio" name="status" id="chagne-backnew" value="6">
+                                                <label class="form-check-label" for="chagne-backnew">退回上一审批人 <%= auditList[index-1].name %></label>
+                                                <input type="hidden" name="audit_last_id" value="<%= auditList[index-1].id %>">
+                                            </div>
+                                            <% } %>
+                                            <div class="form-check form-check-inline">
+                                                <input class="form-check-input" type="radio" name="status" id="change-stop" value="4">
+                                                <label class="form-check-label" for="change-stop">终止</label>
+                                            </div>
+                                        </div>
+                                        <div class="alert alert-danger change-approval-stop" style="display: none">
+                                            审批终止,将结束本次审批,本条变更令作废。
+                                        </div>
+                                    <% } %>
+                                </li>
+                            <% } %>
+                        </ul>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <input type="hidden" name="w_code" value="">
+                    <input type="hidden" name="change_id" value="<%= change.cid %>">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                    <button type="button" class="btn btn-warning change-approval-back approval-btn">确认退回</button>
+                    <button type="button" class="btn btn-danger change-approval-stop approval-btn" style="display: none">确认终止</button>
+                </div>
+                </form>
+            </div>
+        </div>
+    </div>
+<% } %>
+
 <!--添加附件-->
 <div class="modal fade" tabindex="-1" role="dialog" aria-hidden="true" id="addfujian">
     <div class="modal-dialog" role="document">