Browse Source

支付审批模块设置

laiguoran 2 years ago
parent
commit
71ea5bcae1

+ 24 - 1
app/const/payment.js

@@ -30,11 +30,31 @@ const permission_value_array = [0, 1];
 // 跟随着标段同时生成的固定报表表单
 const const_rpt_list = [
     {
-        rpt_id: 666,
+        rpt_id: -1,
         rpt_name: '安全生产费',
     },
 ];
 
+const setting_modes = {
+    safe: {
+        name: '安全生产费',
+        checked: false,
+        value: 1,
+    },
+    form: {
+        name: '表单审批',
+        checked: true,
+        value: 0,
+    },
+};
+
+const modes_value = ['form', 'safe'];
+
+const modes_value_object = {
+    form: 0,
+    safe: 1,
+}
+
 const rpt_dataType = {
     intact_type_text: 'text',
     intact_type_number: 'number',
@@ -68,4 +88,7 @@ module.exports = {
     rpt_dataType,
     rpt_control,
     signature_msg,
+    setting_modes,
+    modes_value,
+    modes_value_object,
 };

+ 68 - 5
app/controller/payment_controller.js

@@ -57,10 +57,36 @@ module.exports = app => {
             } catch (err) {
                 console.log(err);
                 this.log(err);
+                ctx.session.postError = err.toString();
                 ctx.redirect(this.menu.menu.dashboard.url);
             }
         }
 
+        async setting(ctx) {
+            try {
+                if (!ctx.session.sessionUser.is_admin) {
+                    throw '您无权打开此页';
+                }
+                const projectInfo = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
+                const modes = projectInfo.payment_setting ? JSON.parse(projectInfo.payment_setting) : ctx.helper._.cloneDeep(paymentConst.setting_modes);
+                for (const m in modes) {
+                    const detailCount = await ctx.service.paymentDetail.getCountByPidType(ctx.session.sessionProject.id, modes[m].value);
+                    modes[m].can_check = !detailCount;
+                }
+                const renderData = {
+                    setting_modes: paymentConst.setting_modes,
+                    modes,
+                    jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.payment.setting),
+                };
+                await this.layout('payment/setting.ejs', renderData);
+            } catch (err) {
+                console.log(err);
+                this.log(err);
+                ctx.session.postError = err.toString();
+                ctx.redirect('/payment');
+            }
+        }
+
         async listLoad(ctx) {
             const responseData = {
                 err: 0, msg: '', data: {},
@@ -191,6 +217,31 @@ module.exports = app => {
                             await ctx.service.paymentFolder.deleteFolder(data.postData.id);
                         }
                         break;
+                    case 'mode-setting':
+                        if (!ctx.session.sessionUser.is_admin) {
+                            throw '您无权操作';
+                        }
+                        const projectInfo = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
+                        const modes = projectInfo.payment_setting ? JSON.parse(projectInfo.payment_setting) : ctx.helper._.cloneDeep(paymentConst.setting_modes);
+                        const checked = data.checked;
+                        if (modes[data.mode_type]) {
+                            const detailCount = await ctx.service.paymentDetail.getCountByPidType(ctx.session.sessionProject.id, modes[data.mode_type].value);
+                            if (detailCount > 0 && !checked) {
+                                throw '已存在对应模块的详情,无法关闭该模块';
+                            }
+                            const mode = modes[data.mode_type];
+                            if (mode.checked === checked) {
+                                throw '已选中该模块,无须重复选中';
+                            }
+                            mode.checked = checked;
+                        } else if (paymentConst.setting_modes[data.mode_type]) {
+                            modes[data.mode_type] = ctx.helper._.cloneDeep(paymentConst.setting_modes[data.mode_type]);
+                            modes[data.mode_type].checked = checked;
+                        } else {
+                            throw '该模块不存在';
+                        }
+                        await ctx.service.project.defaultUpdate({ id: ctx.session.sessionProject.id, payment_setting: JSON.stringify(modes) });
+                        break;
                     default: throw '参数有误';
                 }
                 // 先获取你创建的标段及参与的标段
@@ -319,6 +370,10 @@ module.exports = app => {
             } catch (err) {
                 console.log(err);
                 this.log(err);
+                ctx.session.postError = err.toString();
+                if (ctx.detail.tender_id && ctx.detail.tr_id) {
+                    ctx.redirect('/payment' + ctx.detail.tender_id + '/list/' + ctx.detail.tr_id);
+                }
                 ctx.redirect(this.menu.menu.dashboard.url);
             }
         }
@@ -410,6 +465,7 @@ module.exports = app => {
                 ctx.redirect('/payment/' + ctx.tender.id + '/list/' + detailInfo.tr_id);
             } catch (err) {
                 this.log(err);
+                ctx.session.postError = err.toString();
                 ctx.redirect(ctx.request.header.referer);
             }
         }
@@ -450,7 +506,7 @@ module.exports = app => {
         async _returnRptProjectList(ctx, formProcess = false) {
             // 获取报表表单列表
             if (ctx.tender.uid === ctx.session.sessionUser.accountId || formProcess) {
-                const rptProject = await ctx.service.rptTreeNode.getDataByCondition({ name: '01.支付审批报表' });
+                const rptProject = await ctx.service.rptTreeNode.getDataByCondition({ pid: ctx.session.sessionProject.id, name: '01.支付审批报表' });
                 const rptProjectList = rptProject.items ? JSON.parse(rptProject.items) : [];
                 const tenderRptList = await ctx.service.paymentTenderRpt.getProcessList(ctx.tender.id);
                 return await ctx.service.paymentTenderRpt.checkAndUpdateList(tenderRptList, rptProjectList, formProcess);
@@ -465,7 +521,7 @@ module.exports = app => {
                     throw '权限不足';
                 }
                 let [tenderRptList, rptProjectList] = await this._returnRptProjectList(ctx, true);
-                tenderRptList = ctx.helper._.filter(tenderRptList, { is_const: 0, is_del: 0 });
+                tenderRptList = ctx.helper._.filter(tenderRptList, { type: 0, is_del: 0 });
                 // for (const tr of tenderRptList) {
                 //     if (tr.status === shenpiConst.sp_status.gdspl) {
                 //         tr.auditList = await ctx.service.paymentShenpiAudit.getAuditList(ctx.tender.id, tr.id, tr.sp_status);
@@ -495,7 +551,8 @@ module.exports = app => {
             } catch (err) {
                 console.log(err);
                 this.log(err);
-                ctx.redirect(this.request.headers.referer ? this.request.headers.referer : this.menu.menu.dashboard.url);
+                ctx.session.postError = err.toString();
+                ctx.redirect(this.request.headers.referer ? this.request.headers.referer : '/payment');
             }
         }
 
@@ -542,13 +599,17 @@ module.exports = app => {
             try {
                 const tenderRptList = await this._returnRptProjectList(ctx);
                 if (tenderRptList.length === 0) {
-                    throw '当前报表表单您无权打开';
+                    throw '当前报表表单您无权打开或还没进行模块或表单审批设置';
                 }
                 for (const tr of tenderRptList) {
                     tr.have_notice = await ctx.service.paymentDetail.haveNotice2TenderRpt(tr.id, ctx.session.sessionUser.accountId);
                 }
                 const trid = ctx.params.trid ? parseInt(ctx.params.trid) : 0;
                 const trInfo = trid ? ctx.helper._.find(tenderRptList, { id: trid }) : tenderRptList[0];
+                if (!trInfo) {
+                    throw '该模块已关闭或未进行表单审批设置';
+                }
+
                 // 获取列表
                 const trDetailList = await ctx.service.paymentDetail.getValidDetails(trInfo.id);
                 for (const s of trDetailList) {
@@ -566,6 +627,7 @@ module.exports = app => {
                     auditConst,
                     accountGroup: [],
                     accountList: [],
+                    paymentConst,
                     preUrl: '/payment/' + ctx.tender.id + '/list/' + trInfo.id,
                 };
                 // 获取报表信息,新增时及设置报表角色时使用
@@ -638,7 +700,8 @@ module.exports = app => {
             } catch (err) {
                 console.log(err);
                 this.log(err);
-                ctx.redirect(this.request && this.request.headers && this.request.headers.referer ? this.request.headers.referer : this.menu.menu.dashboard.url);
+                ctx.session.postError = err.toString();
+                ctx.redirect(this.request && this.request.headers && this.request.headers.referer ? this.request.headers.referer : '/payment');
             }
         }
 

+ 8 - 0
app/middleware/payment_tender_check.js

@@ -9,6 +9,8 @@
  */
 
 const messageType = require('../const/message_type');
+const paymentConst = require('../const/payment');
+const _ = require('lodash');
 
 module.exports = options => {
     /**
@@ -25,10 +27,16 @@ module.exports = options => {
                 throw '当前未打开标段';
             }
             const tender = yield this.service.paymentTender.getDataById(this.params.id);
+            const projectInfo = yield this.service.project.getDataById(this.session.sessionProject.id);
+            const modes = projectInfo.payment_setting ? JSON.parse(projectInfo.payment_setting) : _.cloneDeep(paymentConst.setting_modes);
+            for (const m in paymentConst.setting_modes) {
+                if (!modes[m]) modes[m] = _.cloneDeep(paymentConst.setting_modes[m]);
+            }
             if (!tender) {
                 throw '标段不存在';
             }
             this.tender = tender;
+            this.project_setting = modes;
             yield next;
         } catch (err) {
             // 输出错误到日志

+ 9 - 0
app/public/js/payment_setting.js

@@ -0,0 +1,9 @@
+$(function () {
+    autoFlashHeight();
+
+    $('#mode-form input').on('click', function () {
+        postData('/payment/save', { type: 'mode-setting', mode_type: $(this).attr('mode-type'), checked: $(this).is(':checked') }, function (result) {
+            toastr.success('已配置');
+        })
+    });
+});

+ 1 - 0
app/router.js

@@ -739,6 +739,7 @@ module.exports = app => {
 
     // 支付审批
     app.get('/payment', sessionAuth, 'paymentController.index');
+    app.get('/payment/setting', sessionAuth, 'paymentController.setting');
     app.post('/payment/permission/save', sessionAuth, 'paymentController.permissionSave');
     app.get('/payment/:id/detail/:did', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.detail');
     app.post('/payment/:id/detail/:did/save', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.detailSave');

+ 7 - 0
app/service/payment_detail.js

@@ -222,6 +222,13 @@ module.exports = app => {
         async haveDetail2Tender(tid) {
             return this.count({ tender_id: tid });
         }
+
+        async getCountByPidType(pid, type = 1) {
+            const sql = 'SELECT count(pd.`id`) as count FROM ?? as pd LEFT JOIN ?? as pt ON pd.`tender_id` = pt.`id` WHERE pid = ? AND type = ?';
+            const params = [this.tableName, this.ctx.service.paymentTender.tableName, pid, type];
+            const result = await this.db.queryOne(sql, params);
+            return result ? result.count : 0;
+        }
     }
     return PaymentDetail;
 };

+ 26 - 7
app/service/payment_tender_rpt.js

@@ -18,16 +18,35 @@ module.exports = app => {
         }
 
         async getList(tid, uid) {
-            const sql = 'SELECT * FROM ?? WHERE `tender_id` = ?' +
+            const typeValues = [];
+            for (const m in this.ctx.project_setting) {
+                if (this.ctx.project_setting[m].checked) {
+                    typeValues.push(this.ctx.project_setting[m].value);
+                }
+            }
+            if (typeValues.length === 0) {
+                return [];
+            }
+            const sql = 'SELECT * FROM ?? WHERE `tender_id` = ? AND `type` IN (' + this.ctx.helper.getInArrStrSqlFilter(typeValues) + ')' +
                 ' AND (`id` in (SELECT pda.`tr_id` FROM ?? as pda LEFT JOIN ?? as pd ON pda.`tr_id` = pd.`tr_id` WHERE pd.`status` != ' + auditConst.status.uncheck + ' AND pda.`aid` = ?)' +
-                ' OR `id` in (SELECT pra.`tr_id` FROM ?? as pra LEFT JOIN ?? as pd ON pra.`tr_id` = pd.`tr_id` WHERE (pd.`status` != ' + auditConst.status.uncheck + ' OR pd.`status` != ' + auditConst.status.checkNo + ') AND pra.`uid` = ?))';
+                ' OR `id` in (SELECT pra.`tr_id` FROM ?? as pra LEFT JOIN ?? as pd ON pra.`tr_id` = pd.`tr_id` WHERE (pd.`status` != ' + auditConst.status.uncheck + ' OR pd.`status` != ' + auditConst.status.checkNo + ') AND pra.`uid` = ?))' +
+                ' ORDER BY FIELD(`type`, 1, 0), id asc';
             const params = [this.tableName, tid, this.ctx.service.paymentDetailAudit.tableName, this.ctx.service.paymentDetail.tableName, uid,
                 this.ctx.service.paymentRptAudit.tableName, this.ctx.service.paymentDetail.tableName, uid];
             return await this.db.query(sql, params);
         }
 
         async getProcessList(id) {
-            const sql = 'SELECT ptr.*, pa.name as user_name FROM ?? as ptr LEFT JOIN ?? as pa ON ptr.`uid` = pa.`id` WHERE ptr.`tender_id` = ? ';
+            const typeValues = [];
+            for (const m in this.ctx.project_setting) {
+                if (this.ctx.project_setting[m].checked) {
+                    typeValues.push(this.ctx.project_setting[m].value);
+                }
+            }
+            if (typeValues.length === 0) {
+                return [];
+            }
+            const sql = 'SELECT ptr.*, pa.name as user_name FROM ?? as ptr LEFT JOIN ?? as pa ON ptr.`uid` = pa.`id` WHERE ptr.`tender_id` = ?  AND ptr.`type` IN (' + this.ctx.helper.getInArrStrSqlFilter(typeValues) + ')';
             const params = [this.tableName, this.ctx.service.projectAccount.tableName, id];
             return await this.db.query(sql, params);
         }
@@ -39,7 +58,7 @@ module.exports = app => {
                     const updateDatas = [];
                     const delDatas = [];
                     const delRptIds = [];
-                    const noConstRptList = this._.filter(tenderRptList, { is_const: 0 });
+                    const noConstRptList = this._.filter(tenderRptList, { type: 0 });
                     for (const tr of noConstRptList) {
                         const rptInfo = this._.find(rptProjectList, { ID: tr.rpt_id });
                         // 判断是否已经新建过报表次
@@ -84,7 +103,7 @@ module.exports = app => {
         async setRpt(tid, rpt_list) {
             const transaction = await this.db.beginTransaction();
             try {
-                const originList = await this.getAllDataByCondition({ where: { tender_id: tid, is_del: 0, is_const: 0 } });
+                const originList = await this.getAllDataByCondition({ where: { tender_id: tid, is_del: 0, type: 0 } });
                 const insertData = [];
                 let deleteData = [];
                 if (originList.length === 0 && rpt_list.length !== 0) {
@@ -132,7 +151,7 @@ module.exports = app => {
                 }
                 await transaction.commit();
                 let tenderRptList = await this.getProcessList(tid);
-                tenderRptList = this._.filter(tenderRptList, { is_const: 0, is_del: 0 });
+                tenderRptList = this._.filter(tenderRptList, { type: 0, is_del: 0 });
                 return tenderRptList;
             } catch (err) {
                 await transaction.rollback();
@@ -160,7 +179,7 @@ module.exports = app => {
                     uid,
                     rpt_id: rpt.rpt_id,
                     rpt_name: rpt.rpt_name,
-                    is_const: 1,
+                    type: 1,
                     in_time: new Date(),
                 });
             }

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

@@ -1,7 +1,7 @@
 <div class="panel-content">
     <div class="panel-title fluid">
         <div class="title-main  d-flex justify-content-between">
-            <div>支付审批 <a href="payment-approval-settings.html" class="ml-1" data-toggle="tooltip" data-placement="top" title="模块配置"><i class="fa fa-cog"></i></a></div>
+            <div>支付审批 <% if (ctx.session.sessionUser.is_admin) { %><a href="/payment/setting" class="ml-1" data-toggle="tooltip" data-placement="top" title="模块配置"><i class="fa fa-cog"></i></a><% } %></div>
             <div>
                 <% if (auditPermission.tender) { %>
                 <a href="javascript:void(0);" style="display: none" id="show_new_tender_btn" class="btn btn-sm btn-primary pull-right show_new_tender_btn">新建标段</a>

+ 2 - 0
app/view/payment/list.ejs

@@ -35,6 +35,7 @@
                                 <table class="table table-bordered">
                                     <thead>
                                     <tr>
+                                        <th>期数</th>
                                         <th>编号</th>
                                         <th>创建时间</th>
                                         <th>审批进度</th>
@@ -44,6 +45,7 @@
                                     <tbody>
                                     <% for (const info of trDetailList) { %>
                                     <tr>
+                                        <td>第<%- info.order %>期</td>
                                         <td><a href="/payment/<%- info.tender_id %>/detail/<%- info.id %>"><%- info.code %></a></td>
                                         <td><%- info.s_time %></td>
                                         <td class="<%- auditConst.auditProgressClass[info.status] %>">

+ 10 - 28
app/view/payment/process.ejs

@@ -9,14 +9,19 @@
             <div class="sjs-height-0">
                 <div class="m-3">
                     <ul class="nav nav-tabs" id="myTab" role="tablist">
+                        <% if (ctx.project_setting.safe.checked) { %>
                         <li class="nav-item">
                             <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">常规审批流程</a>
                         </li>
+                        <% } %>
+                        <% if (ctx.project_setting.form.checked) { %>
                         <li class="nav-item">
-                            <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">表单审批流程</a>
+                            <a class="nav-link <% if (!ctx.project_setting.safe.checked) { %>active<% } %>" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">表单审批流程</a>
                         </li>
+                        <% } %>
                     </ul>
                     <div class="tab-content" id="myTabContent">
+                        <% if (ctx.project_setting.safe.checked) { %>
                         <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
                             <div class="row mt-3">
                                 <div class="col-8 mt-3">
@@ -54,35 +59,11 @@
                                         </div>
                                     </div>
                                 </div>
-                                <div class="col-8 mt-3">
-                                    <div class="card">
-                                        <div class="card-body">
-                                            <h5 class="card-title">安全生成费</h5>
-                                            <div class="form-group">
-                                                <div class="form-check form-check-inline">
-                                                    <input class="form-check-input" type="checkbox" id="inlineCheckbox5" value="option1">
-                                                    <label class="form-check-label" for="inlineCheckbox16">授权审批流</label>
-                                                </div>
-                                                <div class="form-check form-check-inline">
-                                                    <input class="form-check-input" type="checkbox" id="inlineCheckbox6" value="option1" checked>
-                                                    <label class="form-check-label" for="inlineCheckbox16">固定审批流</label>
-                                                </div>
-                                            </div>
-                                            <div class="alert alert-warning mb-0 mt-3" role="alert">固定终审:结束审批流为固定人,终审前的审批流程由上报人设置,即授权审批人。</div>
-                                            <div class="d-flex justify-content-start align-items-center mt-3">
-                                                <div class="mr-2"><a href="#">终审</a></div>
-                                                <div>
-                                                    <select class="form-control form-control-sm" id="exampleFormControlSelect1">
-                                                        <option>选择审批人</option>
-                                                    </select>
-                                                </div>
-                                            </div>
-                                        </div>
-                                    </div>
-                                </div>
                             </div>
                         </div>
-                        <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
+                        <% } %>
+                        <% if (ctx.project_setting.form.checked) { %>
+                        <div class="tab-pane fade <% if (!ctx.project_setting.safe.checked) { %>show active<% } %>" id="profile" role="tabpanel" aria-labelledby="profile-tab">
                             <div class="row">
                                 <div class="col-4 mt-3">
                                     <table class="table table-bordered">
@@ -145,6 +126,7 @@
                                 </div>
                             </div>
                         </div>
+                        <% } %>
                     </div>
                 </div>
             </div>

+ 32 - 0
app/view/payment/setting.ejs

@@ -0,0 +1,32 @@
+<div class="panel-content">
+    <div class="panel-title fluid">
+        <div class="title-main  d-flex justify-content-between">
+            <div>支付审批</div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-body">
+            <div class="sjs-height-0">
+                <div class="card m-3">
+                    <div class="card-body">
+                        <h5 class="card-title">模块配置</h5>
+                        <div class="form-group mb-1">
+                            <div id="mode-form">
+                                <% for (const m in setting_modes) { %>
+                                <div class="form-check">
+                                    <input class="form-check-input" type="checkbox" mode-type="<%- m %>" id="type_<%- m %>" value="<%- setting_modes[m].value %>" <% if ((!modes[m] &&setting_modes[m].checked) || (modes[m] && modes[m].checked)) { %>checked<% } %> <% if (modes[m] && !modes[m].can_check) { %>disabled<% } %>>
+                                    <label class="form-check-label" for="type_<%- m %>"><%- setting_modes[m].name %></label>
+                                </div>
+                                <% } %>
+                                <div class="alert alert-danger mt-3 mb-0" role="alert">配合标段使用的审批模块。</div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script>
+
+</script>

+ 7 - 0
config/web.js

@@ -1137,6 +1137,13 @@ const JsFiles = {
                 ],
                 mergeFile: 'payment_index',
             },
+            setting: {
+                files: [],
+                mergeFiles: [
+                    '/public/js/payment_setting.js',
+                ],
+                mergeFile: 'payment_setting',
+            },
             process: {
                 files: [],
                 mergeFiles: [