Bladeren bron

1. 安全计量测试bug
2. 安全计量,添加审批人,仅查询有权限的用户
3. 工作台,显示安全计量待办
4. 待办事项,显示安全计量待办,统计安全计量审批情况,显示安全计量动态

MaiXinRong 1 week geleden
bovenliggende
commit
d2d81945b7

+ 17 - 0
app/controller/dashboard_controller.js

@@ -42,6 +42,7 @@ module.exports = app => {
             const allAuditFinancials = await ctx.service.financialPayAudit.getAuditFinancial(ctx.session.sessionUser.accountId);
             const allAuditInspections = await ctx.service.qualityInspectionAudit.getAuditInspection(ctx.session.sessionUser.accountId);
             const allAuditSafeInspections = await ctx.service.safeInspectionAudit.getAuditInspection(ctx.session.sessionUser.accountId);
+            const allAuditSafeStage = await ctx.service.safeStageAudit.getAuditStage(ctx.session.sessionUser.accountId);
             const pa = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
             const auditShenpiTenders = await ctx.service.ledgerAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
             const auditShenpiStages = await ctx.service.stageAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
@@ -56,6 +57,7 @@ module.exports = app => {
             const auditShenpiFinancial = await ctx.service.financialPayAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
             const auditShenpiInspection = await ctx.service.qualityInspectionAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
             const auditShenpiSafeInspection = await ctx.service.safeInspectionAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
+            const auditShenpiSafeStage = await ctx.service.safeStageAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
             const dashboardStatus = {
                 all: 0,
                 dashboard: 0,
@@ -75,6 +77,7 @@ module.exports = app => {
                     financial: 0,
                     inspection: 0,
                     safeInspection: 0,
+                    safeStage: 0,
                 },
             };
             let noticeList = [];
@@ -108,6 +111,8 @@ module.exports = app => {
                 noticeList.push(...ctx.helper.addKeyValue4ObjArray(spInspection, 'shenpi_type', 'inspection'));
                 const spSafeInspection = subProject.page_show.safeInspection ? ctx.helper._.filter(auditShenpiSafeInspection, { spid: subProject.id }) : [];
                 noticeList.push(...ctx.helper.addKeyValue4ObjArray(spSafeInspection, 'shenpi_type', 'safeInspection'));
+                const spSafeStage = subProject.page_show.safeInspection ? ctx.helper._.filter(auditShenpiSafeStage, { spid: subProject.id }) : [];
+                noticeList.push(...ctx.helper.addKeyValue4ObjArray(spSafeStage, 'shenpi_type', 'safeStage'));
             }
             const noticeDayList = [];
             noticeList = ctx.helper._.orderBy(noticeList, ['shenpi_time'], ['desc']);
@@ -145,6 +150,8 @@ module.exports = app => {
             dashboardShenpis.push(...auditInspections);
             const auditSafeInspections = await this.auditSet(ctx, allAuditSafeInspections, subProjects, dashboardStatus, 'safeInspection');
             dashboardShenpis.push(...auditSafeInspections);
+            const auditSafeStage = await this.auditSet(ctx, allAuditSafeStage, subProjects, dashboardStatus, 'safeStage');
+            dashboardShenpis.push(...auditSafeStage);
             // console.log(ctx.helper._.orderBy(dashboardShenpis, ['start_audit', 'shenpi_time'], ['desc', 'desc']));
             const projectData = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
             // 获取销售人员数据
@@ -176,6 +183,7 @@ module.exports = app => {
                 acChangePlan: auditConst.changeApply,
                 acFinancial: auditConst.financial,
                 acInspection: auditConst.inspection,
+                acSafeStage: auditConst.safeStage,
                 noticeList,
                 noticeDayList,
                 pushType: auditConst.pushType,
@@ -286,6 +294,10 @@ module.exports = app => {
                             if (!sp.page_show.safeInspection) closeType = true;
                             calcTime = t.status !== auditConst.inspection.status.checkNo ? t.begin_time : t.end_time;
                             break;
+                        case 'safeStage':
+                            if (!sp.page_show.safePayment) closeType = true;
+                            calcTime = t.create_time;
+                            break;
                         default:
                             closeType = true;
                     }
@@ -333,6 +345,7 @@ module.exports = app => {
             const auditFinancials = ctx.subProject.page_show.openFinancial ? await ctx.service.financialPayAudit.getAuditFinancial(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
             const auditInspections = ctx.subProject.page_show.qualityInspection ? await ctx.service.qualityInspectionAudit.getAuditInspection(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
             const auditSafeInspections = ctx.subProject.page_show.safeInspection ? await ctx.service.safeInspectionAudit.getAuditInspection(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
+            const auditSafeStage = ctx.subProject.page_show.safePayment ? await ctx.service.safeStageAudit.getAuditStage(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
             const pa = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
             const noticeList = await ctx.service.noticePush.getNotice(ctx.session.sessionProject.id, pa.id, ctx.subProject.id);
             const projectData = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
@@ -364,6 +377,7 @@ module.exports = app => {
             if (ctx.subProject.page_show.openFinancial) shenpi_count.push({ count: await ctx.service.financialPayAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '资金支付' });
             if (ctx.subProject.page_show.qualityInspection) shenpi_count.push({ count: await ctx.service.qualityInspectionAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '质量巡检' });
             if (ctx.subProject.page_show.safeInspection) shenpi_count.push({ count: await ctx.service.safeInspectionAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '安全巡检' });
+            if (ctx.subProject.page_show.safePayment) shenpi_count.push({ count: await ctx.service.safeStageAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '安全计量' });
             // shenpi_count.push({ count: await ctx.service.advanceAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '预付款' });
             const total_count = ctx.app._.sumBy(shenpi_count, 'count');
             const shenpi_lastime = [
@@ -379,6 +393,7 @@ module.exports = app => {
                 ctx.subProject.page_show.openFinancial ? await ctx.service.financialPayAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
                 ctx.subProject.page_show.qualityInspection ? await ctx.service.qualityInspectionAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
                 ctx.subProject.page_show.safeInspection ? await ctx.service.safeInspectionAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
+                ctx.subProject.page_show.safeInspection ? await ctx.service.safeStageAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
             ];
             const last_time = ctx.app._.max(shenpi_lastime);
             // console.log(ctx.app._.max(shenpi_lastime), ctx.helper.calcDayNum(last_time));
@@ -397,6 +412,7 @@ module.exports = app => {
                 auditFinancials,
                 auditInspections,
                 auditSafeInspections,
+                auditSafeStage,
                 shenpi_count,
                 total_count,
                 last_day: ctx.helper.calcDayNum(last_time),
@@ -413,6 +429,7 @@ module.exports = app => {
                 acChangePlan: auditConst.changeApply,
                 acFinancial: auditConst.financial,
                 acInspection: auditConst.inspection,
+                acSafeStage: auditConst.safeStage,
                 noticeList,
                 pushType: auditConst.pushType,
                 projectData,

+ 2 - 2
app/controller/safe_controller.js

@@ -162,7 +162,7 @@ module.exports = app => {
                 const attList = await ctx.service.paymentDetailAtt.getPaymentDetailAttachment(ctx.safeStage.id, 'desc');
                 const stdBills = await ctx.service.stdGclList.getSafeGcl();
                 // 流程审批人相关数据
-                const accountList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
+                const accountList = await ctx.service.projectAccount.getAllSubProjectAccountByPermission(ctx.subProject, 'payment_permission');
                 const unitList = await ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: ctx.session.sessionProject.id } });
                 const accountGroup = unitList.map(item => {
                     const groupList = accountList.filter(item1 => item1.company === item.name);
@@ -209,7 +209,7 @@ module.exports = app => {
                     auditType: auditConst.auditType,
                     authMobile: pa.auth_mobile,
                 };
-                await this.layout('safe_calc/compare.ejs', renderData);
+                await this.layout('safe_calc/compare.ejs', renderData, 'safe_calc/audit_modal.ejs');
             } catch (err) {
                 ctx.log(err);
                 ctx.postError(err, '读取安全生产费错误');

+ 2 - 1
app/public/js/safe_bills.js

@@ -36,7 +36,7 @@ $(document).ready(function() {
                     {title: '单价', colSpan: '1', rowSpan: '2', field: 'unit_price', hAlign: 2, width: 80, type: 'Number'},
                     {title: '本期|数量', colSpan: '2|1', rowSpan: '1|1', field: 'cur_qty', hAlign: 2, width: 80, type: 'Number'},
                     {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'cur_tp', hAlign: 2, width: 80, type: 'Number'},
-                    {title: '截止本期|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_qty', hAlign: 2, width: 80, type: 'Number'},
+                    {title: '截止本期|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_qty', hAlign: 2, width: 80, type: 'Number', readOnly: true},
                     {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_tp', hAlign: 2, width: 80, type: 'Number', readOnly: true},
                     {title: '发票号', colSpan: '1', rowSpan: '2', field: 'invoice_code', hAlign: 0, width: 100, formatter: '@'},
                     {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 120, formatter: '@', cellType: 'ellipsisAutoTip'},
@@ -668,6 +668,7 @@ $(document).ready(function() {
         page: 'paymentSafe',
         tid: getTenderId(),
         cellDoubleClick: function (updateData, stdNode, stdTree) {
+            if (readOnly) return;
             if (!stdTree || !stdNode || !stdNode.b_code) return;
 
             const mainSheet = billsObj.sheet;

+ 11 - 0
app/service/project_account.js

@@ -1054,6 +1054,17 @@ module.exports = app => {
             return await this.db.query(sql, [subProject.id]);
         }
 
+        async getAllSubProjectAccountByPermission(subProject, permission, columns) {
+            // 请勿随意修改defaultColumns
+            const defaultColumns = ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile', 'company_id'];
+            // const defaultColumns = ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile', 'company_id', 'account', 'telephone', 'permission', 'sign_path', 'stamp_path']; // 新加的字段给报表用
+            const columnsSql = columns
+                ? columns.map(x => { return 'pa.`' + x + '`'; }).join(', ')
+                : defaultColumns.map(x => { return 'pa.`' + x + '`'; }).join(', ');
+            const sql = `SELECT ${columnsSql} FROM ${this.ctx.service.subProjPermission.tableName} spp LEFT JOIN ${this.tableName} pa ON spp.uid = pa.id WHERE spp.spid = ? and pa.enable = 1 and (spp.${permission} <> "" or pa.is_admin = 1)`;
+            return await this.db.query(sql, [subProject.id]);
+        }
+
         _getFilterSql(filter) {
             const searchField = ['name', 'company', 'role', 'mobile'];
             const rstFilter = [];

+ 5 - 4
app/service/safe_stage.js

@@ -46,10 +46,11 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAllStages (tid, sort = 'ASC') {
-            const result = await this.getAllDataByCondition({
-                where: { tid: tid },
-                orders: [['stage_order', sort]],
-            });
+            // const result = await this.getAllDataByCondition({
+            //     where: { tid: tid },
+            //     orders: [['stage_order', sort]],
+            // });
+            const result = await this.db.query(`SELECT ss.*, pa.name AS user_name FROM ${this.tableName} ss LEFT JOIN ${this.ctx.service.projectAccount.tableName} pa ON ss.create_user_id = pa.id WHERE ss.tid = ? ORDER BY ss.stage_order ${sort}`, [tid])
             return result;
         }
         async getStage(id) {

+ 65 - 5
app/service/safe_stage_audit.js

@@ -13,6 +13,7 @@ const auditType = auditConst.auditType;
 const pushType = auditConst.pushType;
 const smsTypeConst = require('../const/sms_type');
 const wxConst = require('../const/wechat_template');
+const checkRelaStatus = [auditConst.common.status.checked, auditConst.common.status.checkNo, auditConst.common.status.checkNoPre];
 
 module.exports = app => {
     class SafeStageAudit extends app.BaseService {
@@ -114,6 +115,69 @@ module.exports = app => {
             const sqlParam = [tenderId];
             return this.db.query(sql, sqlParam);
         }
+        async getAuditStage(auditorId, spid = '') {
+            const spSql = spid ? ' and t.`spid` = "' + spid + '"' : '';
+            const sql =
+                'SELECT sa.`audit_id`, sa.`audit_times`, sa.`audit_order`, sa.`tid`, sa.`stage_id`,' +
+                '    s.`stage_order`, s.`stage_code`, s.`stage_date`, s.create_time,' +
+                '    t.`name`, t.`project_id`, t.`type`, t.`user_id`, t.`spid` ' +
+                `  FROM ${this.tableName} AS sa ` +
+                `    Left Join ${this.ctx.service.safeStage.tableName} AS s On sa.stage_id = s.id ` +
+                `    Left Join ${this.ctx.service.tender.tableName} As t ON sa.tid = t.id `+
+                '  WHERE sa.`audit_id` = ? and sa.`audit_status` = ?' + spSql +
+                '  ORDER BY sa.`create_time` DESC';
+            const sqlParam = [auditorId, auditConst.common.status.checking];
+            const result = await this.db.query(sql, sqlParam);
+            return result;
+        }
+        /**
+         * 获取审核人已经审核过的审批信息(包括退回,通过,重新审批等)
+         *
+         * @param auditorId
+         * @return {Promise<*>}
+         */
+        async getDonesByAudit(auditorId, spid = '') {
+            const spSql = spid ? ' and t.`spid` = "' + spid + '"' : '';
+            const sql =
+                'SELECT ssa.audit_status, ssa.audit_time AS shenpi_time, ssa.stage_id, t.id, ss.stage_code, ss.stage_order, t.name, t.spid ' +
+                `  FROM ${this.tableName} AS ssa Left Join ${this.ctx.service.tender.tableName} AS t ON ssa.tid = t.id LEFT JOIN ${this.ctx.service.safeStage.tableName} AS ss ON ssa.stage_id = ss.id` +
+                '  WHERE ssa.audit_id = ? AND ssa.audit_status in (' + this.ctx.helper.getInArrStrSqlFilter(checkRelaStatus) + ')' + spSql +
+                '  ORDER BY ssa.audit_time DESC';
+            const sqlParam = [auditorId];
+            return await this.db.query(sql, sqlParam);
+        }
+        /**
+         * 获取最近一次审批结束时间
+         *
+         * @param auditorId
+         * @return {Promise<*>}
+         */
+        async getLastEndTimeByChecked(auditorId, spid = '') {
+            const sqSql = spid ? ' AND t.`spid` = "' + spid + '"' : '';
+            const status = [auditConst.common.status.checked, auditConst.common.status.checkNo, auditConst.common.status.checkNoPre];
+            const sql = `SELECT a.audit_time FROM ${this.tableName} AS a LEFT JOIN ${this.ctx.service.tender.tableName} AS t ON a.tid = t.id WHERE a.audit_id = ? ` +
+                'AND a.`audit_status` in (' + this.ctx.helper.getInArrStrSqlFilter(checkRelaStatus) + ')' + sqSql +
+                ' ORDER BY a.`audit_time` DESC';
+            const sqlParam = [auditorId];
+            const result = await this.db.queryOne(sql, sqlParam);
+            return result ? result.audit_time : null;
+        }
+        /**
+         * 获取审核人审核的次数
+         *
+         * @param auditorId
+         * @return {Promise<*>}
+         */
+        async getCountByChecked(auditorId, spid = '') {
+            if (spid) {
+                const sql = `SELECT count(*) AS count FROM ${this.tableName} AS a LEFT JOIN ${this.ctx.service.tender.tableName} AS t ON a.tid = t.id` +
+                    ' WHERE a.audit_id = ? AND a.audit_status in (' + this.ctx.helper.getInArrStrSqlFilter(checkRelaStatus) + ') AND t.`spid` = ?';
+                const sqlParam = [auditorId, spid];
+                const result = await this.db.queryOne(sql, sqlParam);
+                return result.count ? result.count : 0;
+            }
+            return await this.db.count(this.tableName, { audit_id: auditorId, status: checkRelaStatus });
+        }
         // 获取审核比较 可查看的列表,它用不可修改
         async getViewFlow(safeStage) {
             const result = [];
@@ -355,9 +419,9 @@ module.exports = app => {
                 }
             }
 
+            const audit_time = new Date();
             const transaction = await this.db.beginTransaction();
             try {
-                const audit_time = new Date();
                 // 更新原报数据
                 await transaction.update(this.tableName, { audit_status: auditConst.safeStage.status.checked, audit_time },
                     { where: { stage_id: safeStage.id, audit_times: safeStage.audit_times, audit_order: 0 } });
@@ -887,10 +951,6 @@ module.exports = app => {
                 await transaction.updateRows(this.tableName, safeStage.curAuditors.map(x => { return {
                     id: x.id, audit_time: null, audit_status: auditConst.safeStage.status.uncheck, active_order: x.active_order + 2
                 }}));
-                // 缓存 撤回流程
-                await this._cachePreAuditData(transaction, safeStage, {
-                    audit_id: selfAuditor.audit_id, audit_times: selfAuditor.audit_times, audit_order: selfAuditor.audit_order, active_order: selfAuditor.active_order + 1
-                });
                 // todo 删除 审批提醒
                 // await this.ctx.service.noticeAgain.deleteNoticeAgain(transaction, this.tableName, this._.map(safeStage.curAuditors, 'id'));
                 // 同步 期信息

File diff suppressed because it is too large
+ 26 - 1
app/view/dashboard/index.ejs


File diff suppressed because it is too large
+ 14 - 0
app/view/dashboard/workspace.ejs


+ 3 - 3
app/view/safe_calc/audit_modal.ejs

@@ -8,7 +8,7 @@
             </div>
             <div class="modal-body">
                 <div class="dropdown text-right">
-                    <% if (ctx.tender.info.shenpi.safeStage !== shenpiConst.sp_status.gdspl && ctx.session.sessionUser.accountId === ctx.safeStage.create_user_id) { %>
+                    <% if (ctx.tender.info.shenpi.safe_payment !== shenpiConst.sp_status.gdspl && ctx.session.sessionUser.accountId === ctx.safeStage.create_user_id) { %>
                     <button class="btn btn-outline-primary btn-sm dropdown-toggle" type="button" id="dropdownMenuButton"
                             data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                         添加审批流程
@@ -57,8 +57,8 @@
                                     <% if (ctx.safeStage.auditorGroups[i][0].audit_type !== auditType.key.common) { %>
                                     <span class="badge badge-pill badge-<%- auditType.info[ctx.safeStage.auditorGroups[i][0].audit_type].class %> badge-bg-small"><small><%- auditType.info[ctx.safeStage.auditorGroups[i][0].audit_type].long%></small></span>
                                     <% } %>
-                                    <% if ((ctx.tender.info.shenpi.safeStage === shenpiConst.sp_status.sqspr ||
-                                                    (ctx.tender.info.shenpi.safeStage === shenpiConst.sp_status.gdzs && i+1 !== iLen)) && ctx.session.sessionUser.accountId === ctx.safeStage.create_user_id && !ctx.tender.isTourist) { %>
+                                    <% if ((ctx.tender.info.shenpi.safe_payment === shenpiConst.sp_status.sqspr ||
+                                                    (ctx.tender.info.shenpi.safe_payment === shenpiConst.sp_status.gdzs && i+1 !== iLen)) && ctx.session.sessionUser.accountId === ctx.safeStage.create_user_id && !ctx.tender.isTourist) { %>
                                     <a href="javascript: void(0)" class="text-danger pull-right">移除</a>
                                     <% } %>
                                 </div>

+ 2 - 3
app/view/safe_calc/stage.ejs

@@ -5,7 +5,7 @@
     <div class="scrollbar-auto">
         <div class="nav-box">
             <ul class="nav-list list-unstyled">
-                <li class="active text-center"><a href="/sp/<%- ctx.subProject.id %>/safe/<%- ctx.tender.id %>/stage" class="h3 p-0"><span>各期计量</span></a></li>
+                <li class="active text-center"><a href="/sp/<%- ctx.subProject.id %>/safe/tender/<%- ctx.tender.id %>/stage" class="h3 p-0"><span>各期计量</span></a></li>
             </ul>
         </div>
     </div>
@@ -72,7 +72,7 @@
                         <td class="text-center"><%- s.stage_date %></td>
                         <td class="text-right"><%- s.bills_tp %></td>
                         <td class="text-right"><%- s.pre_bills_tp %></td>
-                        <td class="text-right"><%- ctx.helper.add(s.bills_tp, s.end_bills_tp) %></td>
+                        <td class="text-right"><%- ctx.helper.add(s.bills_tp, s.pre_bills_tp) %></td>
                         <td class="<%- auditConst.info[s.audit_status].class %>">
                             <% if (s.audit_status === auditConst.status.checked && s.final_auditor_str) { %>
                                 <a href="#sp-list" data-toggle="modal" data-target="#sp-list" stage-order="<%- s.stage_order %>"><%- s.final_auditor_str %></a>
@@ -97,7 +97,6 @@
                             <% } else { %>
                             <span class="<%- auditConst.info[s.audit_status].class %>"><%- auditConst.info[s.audit_status].title %></span>
                             <% } %>
-                            <% if (s.can_del) { %><a href="#del-qi" class="btn btn-outline-danger btn-sm ml-1" data-toggle="modal" data-target="#del-qi">删除</a><% } %>
                         </td>
                     </tr>
                     <% } %>