Преглед на файлове

报表数据源,安全生产费相关

MaiXinRong преди 2 години
родител
ревизия
f8239f4da0
променени са 5 файла, в които са добавени 305 реда и са изтрити 0 реда
  1. 117 0
      app/lib/rm/base.js
  2. 120 0
      app/lib/rm/payment_safe.js
  3. 57 0
      app/service/payment_detail.js
  4. 4 0
      app/service/payment_tender.js
  5. 7 0
      app/service/report.js

+ 117 - 0
app/lib/rm/base.js

@@ -0,0 +1,117 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+class rptMemBase {
+    constructor(ctx, bindData) {
+        this.ctx = ctx;
+        // 绑定表配置 -- 绑定表指几个数据表,共用一个加载逻辑,存在任一张时,其他表均同步加载
+        this.bindData = bindData;
+    }
+
+    /**
+     * 数据表分类(普通表,绑定表)
+     * @param sourceFilters
+     * @returns {*[]}
+     */
+    getFilter(sourceFilters) {
+        const common = [], spec = [];
+        for (const sf of sourceFilters) {
+            let bSpec = false;
+            for (const key in this.bindData) {
+                const b = this.bindData[key];
+                if (b.indexOf(sf) >= 0) {
+                    bSpec = true;
+                    if (spec.indexOf(key) === -1) {
+                        spec.push(key);
+                        break;
+                    }
+                }
+            }
+            if (!bSpec) common.push(sf);
+        }
+        return [common, spec];
+    }
+
+    getFieldKeys(source, filter) {
+        const result = [];
+        for (const f of filter) {
+            if (source[f]) result.push(...source[f]);
+        }
+        return result;
+    }
+
+    /**
+     * 获取普通表数据(请在子类重构)
+     * @param params 报表基础传参
+     * @param tableName 表名
+     * @param fields 数据列名
+     * @returns {Promise<void>}
+     */
+    getCommonData(params, tableName, fields) {
+        throw '基础报表数据不可使用';
+    }
+
+    /**
+     * 获取绑定表数据(请在子类重构)
+     * @param params 报表基础传参
+     * @param key
+     * @param fields 数据列名
+     * @returns {Promise<void>}
+     */
+    async getBindData(params, key, fields) {
+        throw '基础报表数据不可使用';
+    }
+
+    /**
+     * 读取报表数据前的预加载部分,子类按需重构
+     * @returns {Promise<void>}
+     */
+    async doBeforeLoadReport(params) {
+        return;
+    }
+
+    /**
+     * 获取报表数据
+     * @param params 报表基础传参
+     * @param sourceFilters 数据表
+     * @param memFieldKeys 数据表-数据列
+     * @returns {Promise<void>}
+     */
+    async getReportData(params, sourceFilters, memFieldKeys) {
+        // 预加载部分(tenderCheck,stageCheck,paymentSafeCheck...)
+        await this.doBeforeLoadReport(params);
+
+        const rst = {};
+        // 数据表分类为普通表,绑定表
+        const [filters, bindFilters] = this.getFilter(sourceFilters);
+        // 加载普通表数据
+        const runnableRst = [];
+        const runnableKey = []; // 这个配合runnableRst用,未来考虑并行查询优化
+        for (const filter of filters) {
+            if (runnableKey.indexOf(filter) >= 0) return;
+            runnableKey.push(filter);
+            runnableRst.push(this.getCommonData(params, filter, memFieldKeys[filter]));
+        }
+        const queryRst = await Promise.all(runnableRst);
+        for (let idx = 0; idx < runnableKey.length; idx++) {
+            rst[runnableKey[idx]] = queryRst[idx];
+        }
+        // 加载绑定表数据局
+        for (const bindFilter of bindFilters) {
+            const resultData = await this.getBindData(params, this.getFieldKeys(memFieldKeys, this.bindData[bindFilter]));
+            for (const d in resultData) {
+                rst[d] = resultData[d];
+            }
+        }
+        return rst;
+    }
+}
+
+module.exports = rptMemBase;

+ 120 - 0
app/lib/rm/payment_safe.js

@@ -0,0 +1,120 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+const RptMemBase = require('./base');
+const bindData = {};
+const Ledger = require('../ledger');
+
+class rptMemPaymentSafe extends RptMemBase {
+    constructor(ctx) {
+        super(ctx, bindData);
+    }
+
+    async doCheckTender(tenderId) {
+        if (this.ctx.paymentTender) return;
+        this.ctx.paymentTender = await this.ctx.service.paymentTender.doCheckTender(tenderId);
+    }
+
+    async doCheckDetail(detailId) {
+        if (this.ctx.detail) return;
+        this.ctx.detail = await this.ctx.service.paymentDetail.doCheckDetail(detailId);
+    }
+
+    async doBeforeLoadReport(params) {
+        await this.doCheckTender(params.tender_id);
+        await this.doCheckDetail(params.detail_id);
+    }
+
+    async getSafeBills() {
+        const bills = this.ctx.detail.readOnly
+            ? await ctx.service.paymentSafeBills.getReadData(ctx.detail)
+            : await ctx.service.paymentSafeBills.getEditData(ctx.detail);
+        const setting = {
+            id: 'tree_id',
+            pid: 'tree_pid',
+            order: 'tree_order',
+            level: 'tree_level',
+            isLeaf: 'tree_is_leaf',
+            fullPath: 'tree_full_path',
+            rootId: -1,
+            calcFields: ['pre_tp', 'cur_tp', 'end_tp'],
+        };
+        const billsTree = new Ledger.billsTree(this.ctx, setting);
+        billsTree.loadDatas(bills);
+        billsTree.calculateAll();
+        return billsTree.getDefaultData();
+    }
+    _analysisCompareData(datas, roles){
+        const findHis = function (role, history) {
+            let his = null;
+            for (const h of history) {
+                if (h.times < role.times || (h.times === role.times && h.order <= role.order)) {
+                    his = h;
+                } else {
+                    break;
+                }
+            }
+            return his;
+        };
+        for (const d of datas) {
+            if (!d.tree_is_leaf) continue;
+            d.cur_his.sort((x, y) => { return x.times === y.times ? x.order - y.order : x.times - y.times; });
+            for (const r of roles) {
+                if (r.latest) {
+                    d[`qty_${r.order}`] = d.cur_qty;
+                    d[`tp_${r.order}`] = d.cur_tp;
+                } else {
+                    const rHis = findHis(r, d.cur_his);
+                    if (rHis) {
+                        d[`qty_${r.order}`] = rHis.qty;
+                        d[`tp_${r.order}`] = rHis.tp;
+                    }
+                }
+            }
+        }
+    }
+    async getSafeBillsCompare() {
+        const bills = await ctx.service.paymentSafeBills.getCompareData(ctx.detail);
+        const roles = await ctx.service.paymentDetailAudit.getViewFlow(ctx.detail);
+        this._analysisCompareData(bills, roles);
+        const setting = {
+            id: 'tree_id',
+            pid: 'tree_pid',
+            order: 'tree_order',
+            level: 'tree_level',
+            isLeaf: 'tree_is_leaf',
+            fullPath: 'tree_full_path',
+            rootId: -1,
+        };
+        setting.calcFields = roles.map(x => { return `tp_${x.order}`});
+        setting.calcFields.push('pre_tp');
+        const compareTree = new Ledger.billsTree(this.ctx, setting);
+        compareTree.loadDatas(bills);
+        compareTree.calculateAll();
+        return compareTree.getDefaultData();
+    }
+
+    getCommonData(params, tableName, fields) {
+        switch (tableName) {
+            case 'mem_payment_tender':
+                return this.ctx.paymentTender;
+            case 'mem_payment_detail':
+                return this.ctx.detail;
+            case 'mem_payment_safe_bills':
+                return this.getSafeBills();
+            case 'mem_payment_safe_bills_compare':
+                return this.getSafeBillsCompare();
+            default:
+                return [];
+        }
+    }
+}
+
+module.exports = rptMemPaymentSafe;

+ 57 - 0
app/service/payment_detail.js

@@ -336,6 +336,63 @@ module.exports = app => {
             }
             return true;
         }
+
+        async doCheckDetail(id) {
+            const accountId = this.ctx.session.sessionUser.accountId;
+            const auditPermission = await this.service.paymentPermissionAudit.getOnePermission(this.session.sessionUser.is_admin, accountId);
+            if (!auditPermission) throw '权限不足';
+
+            const detail = await this.getDataById(id);
+            if (!detail) throw '支付审批表单不存在';
+            const trInfo = await this.ctx.service.paymentTenderRpt.getDataById(detail.tr_id);
+            if (!trInfo) throw '支付审批报表不存在';
+
+            // 读取原报、审核人数据
+            detail.auditors = await this.ctx.service.paymentDetailAudit.getAuditors(detail.id, detail.times);
+            detail.curAuditor = await this.ctx.service.paymentDetailAudit.getCurAuditor(detail.id, detail.times);
+            detail.rptAudits = await this.ctx.service.paymentRptAudit.getListByDetail(detail.id);
+            const auditorIds = _.map(detail.auditors, 'aid'), rptAuditIds = _.map(detail.rptAudits, 'uid');
+
+            if (accountId === detail.uid) { // 原报
+                detail.curTimes = detail.times;
+                if (detail.status === status.uncheck || detail.status === status.checkNo) {
+                    detail.curOrder = 0;
+                } else if (detail.status === status.checked) {
+                    detail.curOrder = _.max(_.map(detail.auditors, 'order'));
+                } else {
+                    detail.curOrder = detail.curAuditor.aid === accountId ? detail.curAuditor.order : detail.curAuditor.order - 1;
+                }
+                detail.filePermission = true;
+            } else if (auditorIds.indexOf(accountId) !== -1 || rptAuditIds.indexOf(accountId) !== -1 || auditPermission.view_all) { // 审批人及签署人及查看所有权人
+                if (detail.status === status.uncheck) {
+                    throw '您无权查看该数据';
+                }
+                detail.curTimes = detail.status === status.checkNo ? detail.times - 1 : detail.times;
+                if (detail.status === status.checked) {
+                    detail.curOrder = _.max(_.map(detail.auditors, 'order'));
+                } else if (detail.status === status.checkNo) {
+                    const audit = await this.ctx.service.paymentDetailAudit.getDataByCondition({
+                        td_id: detail.id, times: detail.times, status: status.checkNo,
+                    });
+                    detail.curOrder = audit.order;
+                } else {
+                    detail.curOrder = accountId === detail.curAuditor.aid ? detail.curAuditor.order : detail.curAuditor.order - 1;
+                }
+                detail.filePermission = auditorIds.indexOf(accountId) !== -1 || rptAuditIds.indexOf(accountId) !== -1;
+            } else { // 其他不可见
+                throw '您无权查看该数据';
+            }
+
+            // 获取最新的期
+            detail.highOrder = await this.service.paymentDetail.count({ tr_id: detail.tr_id });
+            detail.readOnly = !((detail.status === status.uncheck || detail.status === status.checkNo) && accountId === detail.uid);
+            if (detail.readOnly && detail.type === paymentConst.modes_value_object.safe) {
+                if ((detail.status === status.checking || detail.status === status.checkNoPre) && detail.curAuditor && detail.curAuditor.aid === accountId) {
+                    detail.readOnly = false;
+                }
+            }
+            return detail;
+        }
     }
     return PaymentDetail;
 };

+ 4 - 0
app/service/payment_tender.js

@@ -143,6 +143,10 @@ module.exports = app => {
         // async getChildrenByParentId(parentId, transaction = null) {
         //     const list = await this.getAllDataByCondition({ where: { parent_id: parentId } });
         // }
+
+        async doCheckTender(id) {
+            return await this.service.paymentTender.getDataById(id);
+        }
     }
     return paymentTender;
 };

+ 7 - 0
app/service/report.js

@@ -493,6 +493,13 @@ module.exports = app => {
             return rst;
         }
 
+        async payment_safe(params, sourceFilters, memFieldKeys) {
+            const RptPaymentSafe = require('../lib/rm/payment_safe');
+            const rptPaymentSafe = new RptPaymentSafe(this.ctx);
+
+            return rptPaymentSafe.getReportData(params, sourceFilters, memFieldKeys);
+        }
+
         async getReportData(source_type, params, sourceFilters, memFieldKeys, customDefine, customSelect) {
             const sourceType = sourceTypeConst.sourceTypeData.find(x => { return x.id === source_type; });
             if (!sourceType && !this[sourceType.key]) return {};