Browse Source

Merge branch 'dev' of http://192.168.1.41:3000/maixinrong/Calculation into dev

MaiXinRong 4 năm trước cách đây
mục cha
commit
975e8f42ac

+ 67 - 0
app/controller/report_archive_controller.js

@@ -91,6 +91,43 @@ module.exports = app => {
             };
         }
 
+        async addReportArchiveEncryption(ctx) {
+            const params = JSON.parse(ctx.request.body.params);
+            const prjId = params.prjId;
+            const stgId = params.stgId;
+            const rptId = params.rptId;
+            const content = params.content;
+            const orgArchiveList = await ctx.service.rptArchiveEncryption.getPrjStgArchiveEncryption(prjId, stgId);
+            if (orgArchiveList.length > 0) {
+                const contentArr = JSON.parse(orgArchiveList[0].content);
+                let hasArchive = false;
+                for (const item of contentArr) {
+                    if (item.rpt_id === rptId) {
+                        // 考虑到报表模板的稳定性,只保留一项来记录位置就足够了,都不考虑用uuid了
+                        item.encryption = content;
+                        hasArchive = true;
+                        break;
+                    }
+                }
+                if (!hasArchive) {
+                    // 表示有新的要加
+                    contentArr.push({ rpt_id: rptId, encryption: content });
+                } else {
+                    //
+                }
+                const updatedRst = await ctx.service.rptArchiveEncryption.updateArchiveEncryption(orgArchiveList[0].id, prjId, stgId, contentArr);
+                // console.log(updatedRst);
+                ctx.body = { err: 0, msg: '', data: { addedRst: contentArr } };
+            } else {
+                // 需要增加
+                const archiveArr = [];
+                archiveArr.push({ rpt_id: rptId, encryption: content });
+                const addedRst = await ctx.service.rptArchiveEncryption.createArchiveEncryption(prjId, stgId, archiveArr);
+                // console.log(addedRst);
+                ctx.body = { err: 0, msg: '', data: { addedRst: archiveArr } };
+            }
+        }
+
         async addReportArchive(ctx) {
             try {
                 const stream = await ctx.getFileStream();
@@ -160,6 +197,11 @@ module.exports = app => {
             }
         }
 
+        async updateReportArchiveEncryption(ctx) {
+            // 在add方法中已经处理
+            await this.addReportArchiveEncryption(ctx);
+        }
+
         async updateReportArchive(ctx) {
             try {
                 const stream = await ctx.getFileStream();
@@ -214,6 +256,31 @@ module.exports = app => {
             }
         }
 
+        async removeReportArchiveEncryption(ctx) {
+            try {
+                const prjId = ctx.params.prjId;
+                const stgId = ctx.params.stgId;
+                const rptId = ctx.params.rptId;
+                const orgArchiveList = await ctx.service.rptArchiveEncryption.getPrjStgArchiveEncryption(prjId, stgId);
+                if (orgArchiveList.length > 0) {
+                    const contentArr = JSON.parse(orgArchiveList[0].content);
+                    for (let idx = 0; idx < contentArr.length; idx++) {
+                        if (contentArr[idx].rpt_id === rptId) {
+                            contentArr.splice(idx, 1);
+                            break;
+                        }
+                    }
+                    const updatedRst = await ctx.service.rptArchive.updateArchive(prjId, stgId, contentArr);
+                    ctx.body = { err: 0, msg: '', data: { updatedRst } };
+                } else {
+                    ctx.body = { err: 0, msg: '', data: { updatedRst: null } };
+                }
+            } catch (err) {
+                this.log(err);
+                ctx.body = { err: 1, msg: err.toString(), data: null };
+            }
+        }
+
         async removeReportArchive(ctx) {
             try {
                 const prjId = ctx.params.prjId;

+ 101 - 2
app/public/report/js/rpt_archive.js

@@ -256,11 +256,95 @@ let rptArchiveObj = {
         let rst = (aItem && aItem.items && aItem.items.length === 3);
         return rst;
     },
+    _getPageSignatureInfo: function(pageData, rpt_id) {
+        let psInfo = [], psInfoStr = [];
+        let offsetX = 0, offsetY = 0; //这个跟导出pdf一致,以防万一有变化
+        let controls = pageData[JV.NODE_CONTROL_COLLECTION];
+        const _getProperSignatureArea = function(cell, control) {
+            // 约定默认长宽比例是2:1,图片分辨率是600*300
+            const rst = [0, 0, 0, 0]; // left, top, right, bottom
+            if (cell && cell[JV.PROP_AREA]) {
+                let width = cell[JV.PROP_AREA][JV.PROP_RIGHT] - cell[JV.PROP_AREA][JV.PROP_LEFT],
+                    height = cell[JV.PROP_AREA][JV.PROP_BOTTOM] - cell[JV.PROP_AREA][JV.PROP_TOP];
+                if (width > height * 2) {
+                    width = height * 2;
+                } else {
+                    height = width / 2;
+                }
+                switch (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_HORIZON]]) {
+                    case 'left':
+                        rst[0] = cell[JV.PROP_AREA][JV.PROP_LEFT];
+                        rst[1] = cell[JV.PROP_AREA][JV.PROP_TOP];
+                        rst[2] = rst[0] + width;
+                        rst[3] = rst[1] + height;
+                        break;
+                    case 'right':
+                        rst[2] = cell[JV.PROP_AREA][JV.PROP_RIGHT];
+                        rst[3] = cell[JV.PROP_AREA][JV.PROP_BOTTOM];
+                        rst[0] = rst[2] - width;
+                        rst[1] = rst[3] - height;
+                        break;
+                    default:
+                        //center
+                        rst[0] = (cell[JV.PROP_AREA][JV.PROP_LEFT] + cell[JV.PROP_AREA][JV.PROP_RIGHT] - width) / 2;
+                        rst[1] = cell[JV.PROP_AREA][JV.PROP_TOP];
+                        rst[2] = rst[0] + width;
+                        rst[3] = rst[1] + height;
+                        break;
+                }
+            }
+            rst[0] = rst[0] + offsetX;
+            rst[2] = rst[2] + offsetX;
+            rst[1] = rst[1] + offsetY;
+            rst[3] = rst[3] + offsetY;
+            return rst;
+        }
+        for(let i = 0; i < pageData.items.length; i++) {
+            let page = pageData.items[i];
+            for (let sCell of page.signature_cells) {
+                let control = null;
+                if (typeof sCell[JV.PROP_CONTROL] === "string") {
+                    control = controls[sCell[JV.PROP_CONTROL]];
+                } else {
+                    control = sCell[JV.PROP_CONTROL];
+                }
+                let idx = psInfoStr.indexOf(sCell.signature_name);
+                let actSignArea = _getProperSignatureArea(sCell, control);
+                if (idx < 0) {
+                    psInfoStr.push(sCell.signature_name);
+                    let newPsInfo = {'name': sCell.signature_name, areas: []};
+                    let area = {Left: actSignArea[JV.IDX_LEFT] + offsetX, Top: actSignArea[JV.IDX_TOP] + offsetY, width: (actSignArea[JV.IDX_RIGHT] - actSignArea[JV.IDX_LEFT]), height: (actSignArea[JV.IDX_BOTTOM] - actSignArea[JV.IDX_TOP]), pages: []};
+                    area.pages.push(i + 1);
+                    newPsInfo.areas.push(area);
+                    psInfo.push(newPsInfo);
+                } else {
+                    let hasArea = false;
+                    for (let areaItem of psInfoStr[idx].areas) {
+                        if (areaItem.Left === actSignArea[JV.IDX_LEFT] + offsetX && areaItem.Top === actSignArea[JV.IDX_TOP] + offsetX &&
+                            areaItem.width === actSignArea[JV.IDX_RIGHT] - actSignArea[JV.IDX_LEFT] && areaItem.height === actSignArea[JV.IDX_BOTTOM] - actSignArea[JV.IDX_TOP]) {
+                            areaItem.pages.push(i + 1);
+                            hasArea = true;
+                            break;
+                        }
+                    }
+                    if (!hasArea) {
+                        let area = {Left: actSignArea[JV.IDX_LEFT] + offsetX, Top: actSignArea[JV.IDX_TOP] + offsetY, width: (actSignArea[JV.IDX_RIGHT] - actSignArea[JV.IDX_LEFT]), height: (actSignArea[JV.IDX_BOTTOM] - actSignArea[JV.IDX_TOP]), pages: []};
+                        area.pages.push(i + 1);
+                        psInfoStr[idx].areas.push(area);
+                    }
+                }
+                // sCell.signature_name
+            }
+        }
+        return psInfo;
+    },
     archiveCurrentReport: function(currentRptPageRst, currentNode) {
         // 归档当前报表
         if (currentRptPageRst !== null) {
             try {
                 let doc = JpcJsPDFHelper._createPdf(currentRptPageRst, rptControlObj.getCurrentPageSize(), ROLE_REL_LIST, STAGE_AUDIT);
+                let pageEncryptInfo = rptArchiveObj._getPageSignatureInfo(currentRptPageRst, currentNode.refId);
+                console.log(pageEncryptInfo);
                 let formData = new FormData();
                 formData.append('file', doc.output('blob'), 'upload.pdf'); //上传单个文件的添加方式
                 if (!rptArchiveObj._chkIfFullArchives(currentNode)) {
@@ -271,9 +355,24 @@ let rptArchiveObj = {
                             ARCHIVE_LIST = result.addedRst;
                             rptArchiveObj.showArchivedItem(currentNode);
                             zTreeOprObj.refreshNodes();
+                            //第二步:增加
+                            let params = {};
+                            params.prjId = PROJECT_ID;
+                            params.stgId = current_stage_id;
+                            params.rptId = currentNode.refId;
+                            params.content = pageEncryptInfo;
+                            CommonAjax.postXsrfEx("/tender/report_api/addArchiveEncryption", params, 10000, true, getCookie('csrfToken_j'),
+                                function(result){
+                                    //
+                                }, function(err){
+                                    //
+                                }, function(ex){
+                                    //
+                                }
+                            );
                         } else {
                             // 有冲突,需要删除
-                            CommonAjax.postXsrfEx('/tender/report_api/removeArchive/' + PROJECT_ID + '/' + current_stage_id + '/' + currentNode.refId + result.fileName, '', 3000, true, getCookie('csrfToken'),
+                            CommonAjax.postXsrfEx('/tender/report_api/removeArchive/' + PROJECT_ID + '/' + current_stage_id + '/' + currentNode.refId + result.fileName, '', 3000, true, getCookie('csrfToken_j'),
                                 function(result){
                                     //
                                 }
@@ -322,7 +421,7 @@ let rptArchiveObj = {
     }
 };
 
-function _dataURLtoFile(dataurl, filename) {
+function dataURLtoFile(dataurl, filename) {
     var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
         bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
     while(n--){

+ 6 - 6
app/public/report/js/rpt_main.js

@@ -214,18 +214,18 @@ let zTreeOprObj = {
     refreshNodes: function() {
         let me = this;
         const _set_archive_icon = function (tplNode) {
+            let hasArchive = false;
             for (let aItem of ARCHIVE_LIST) {
-                let hasArchive = false;
                 if (parseInt(aItem.rpt_id) === parseInt(tplNode.refId)) {
                     hasArchive = true;
                     tplNode.icon = "/public/css/ztree/img/diy/10.png";
                     break;
                 }
-                if (!hasArchive) {
-                    if (!tplNode.isParent) {
-                        tplNode.icon = null;
-                        tplNode.className = "button ico_docu";
-                    }
+            }
+            if (!hasArchive) {
+                if (!tplNode.isParent) {
+                    tplNode.icon = null;
+                    tplNode.className = "button ico_docu";
                 }
             }
         };

+ 5 - 0
app/router.js

@@ -332,10 +332,15 @@ module.exports = app => {
     app.post('/tender/report_api/createRoleRelationship', sessionAuth, 'signatureController.createRoleRel');
     app.post('/tender/report_api/updateCustNode', sessionAuth, 'reportController.updateCustNode');
     app.post('/report/cDefine', sessionAuth, 'reportController.setCustomDefine');
+
     app.post('/tender/report_api/addArchive/:prjId/:stgId/:rptId', sessionAuth, 'reportArchiveController.addReportArchive');
     app.post('/tender/report_api/updateArchive/:prjId/:stgId/:rptId/:orgName', sessionAuth, 'reportArchiveController.updateReportArchive');
     app.post('/tender/report_api/removeArchive/:prjId/:stgId/:rptId/:orgName', sessionAuth, 'reportArchiveController.removeReportArchive');
 
+    app.post('/tender/report_api/addArchiveEncryption', sessionAuth, 'reportArchiveController.addReportArchiveEncryption');
+    app.post('/tender/report_api/updateArchiveEncryption', sessionAuth, 'reportArchiveController.updateReportArchiveEncryption');
+    app.post('/tender/report_api/removeArchiveEncryption', sessionAuth, 'reportArchiveController.removeReportArchiveEncryption');
+
 
     // 变更管理
     app.get('/tender/:id/change', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.index');

+ 157 - 0
app/service/rpt_archive_encryption.js

@@ -0,0 +1,157 @@
+'use strict';
+
+/**
+ * Created by Tony on 2021/6/29.
+ */
+
+const BaseService = require('../base/base_service');
+
+module.exports = app => {
+
+    class RptArchiveEncryption extends BaseService {
+
+        /**
+         * 构造函数
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        constructor(ctx) {
+            super(ctx);
+            this.tableName = 'rpt_archive_encryption';
+            this.dataId = 'id';
+        }
+
+        async getArchiveEncryptionById(id) {
+            this.initSqlBuilder();
+            this.sqlBuilder.setAndWhere('id', {
+                value: id,
+                operate: '=',
+            });
+            this.sqlBuilder.columns = ['id', 'prj_id', 'stage_id', 'content'];
+            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
+            const list = await this.db.query(sql, sqlParam);
+            return list;
+        }
+
+        async getPrjStgArchiveEncryption(prjId, stgId) {
+            this.initSqlBuilder();
+            this.sqlBuilder.setAndWhere('prj_id', {
+                value: prjId,
+                operate: '=',
+            });
+            this.sqlBuilder.setAndWhere('stage_id', {
+                value: stgId,
+                operate: '=',
+            });
+            this.sqlBuilder.columns = ['id', 'prj_id', 'stage_id', 'content'];
+            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
+            const rstList = await this.db.query(sql, sqlParam);
+            return rstList;
+        }
+
+        async createArchiveEncryption(prj_id, stage_id, archiveArr) {
+            let rst = null;
+            this.transaction = await this.db.beginTransaction();
+            try {
+                const data = {
+                    prj_id,
+                    stage_id,
+                    content: JSON.stringify(archiveArr),
+                };
+                // console.log(data);
+                rst = await this.transaction.insert(this.tableName, data);
+                await this.transaction.commit();
+            } catch (ex) {
+                console.log(ex);
+                // 回滚
+                await this.transaction.rollback();
+            }
+            return rst;
+        }
+
+        async updateArchiveEncryption(id, prj_id, stage_id, archiveArr) {
+            let rst = null;
+            this.transaction = await this.db.beginTransaction();
+            try {
+                const data = {
+                    id,
+                    prj_id,
+                    stage_id,
+                    content: JSON.stringify(archiveArr),
+                };
+                // console.log(data);
+                rst = await this.transaction.update(this.tableName, data);
+                await this.transaction.commit();
+            } catch (ex) {
+                console.log(ex);
+                // 回滚
+                await this.transaction.rollback();
+            }
+            return rst;
+        }
+
+        // async addInitialStageData(tender_id, stage, preStage) {
+        //     // 在加stage的时候需要挂上这个,copy之前的签名人
+        //     const rst = [];
+        //     const preRoleRelList = await this.getRoleRptRelByTenderId(tender_id, preStage.id);
+        //     for (const rptRoleRel of preRoleRelList) {
+        //         const relList = JSON.parse(rptRoleRel.rel_content);
+        //         // const newRptRoleRel = {tender_id: tender_id, rpt_id: rptRoleRel.rpt_id, sid: stage.id, rel_content: ''};
+        //         const newRelList = [];
+        //         for (const role of relList) {
+        //             const newRole = {};
+        //             newRelList.push(newRole);
+        //             for (const key in role) {
+        //                 if (key !== 'sign_date') {
+        //                     newRole[key] = role[key];
+        //                 } else {
+        //                     newRole[key] = '';
+        //                 }
+        //             }
+        //         }
+        //         // rst.push(await this.createRoleRelationship(tender_id, rptRoleRel.rpt_id, stage.id, newRelList));
+        //         await this.createRoleRelationship(tender_id, rptRoleRel.rpt_id, stage.id, newRelList); // 暂时用不到,就先不返回结果
+        //     }
+        //     return rst;
+        // }
+
+        // async updateRoleRelationship(id, tender_id, rpt_id, sid, relArr) {
+        //     let rst = null;
+        //     if (id < 0) {
+        //         rst = await this.createRoleRelationship(tender_id, rpt_id, sid, relArr);
+        //     } else {
+        //         this.transaction = await this.db.beginTransaction();
+        //         try {
+        //             const data = { id, tender_id, rpt_id, sid, rel_content: JSON.stringify(relArr) };
+        //             rst = await this.transaction.update(this.tableName, data);
+        //             await this.transaction.commit();
+        //         } catch (ex) {
+        //             console.log(ex);
+        //             // 回滚
+        //             await this.transaction.rollback();
+        //         }
+        //     }
+        //     return rst;
+        // }
+        //
+        // async updateMultiRoleRelationship(orgParams, newRelArr) {
+        //     for (let idx = 0; idx < orgParams.length; idx++) {
+        //         const param = orgParams[idx];
+        //         const data = { tender_id: param[0], sid: param[1], rpt_id: param[2] };
+        //         this.transaction = await this.db.beginTransaction();
+        //         try {
+        //             await this.transaction.delete(this.tableName, data);
+        //             this.transaction.commit();
+        //             await this.createRoleRelationship(param[0], param[2], param[1], newRelArr);
+        //         } catch (ex) {
+        //             console.log(ex.toString());
+        //             // 回滚
+        //             await this.transaction.rollback();
+        //         }
+        //     }
+        //     return true;
+        // }
+    }
+    return RptArchiveEncryption;
+};

+ 8 - 0
sql/update.sql

@@ -0,0 +1,8 @@
+CREATE TABLE `calculation`.`zh_rpt_archive_encryption` (
+  `id` INT NOT NULL AUTO_INCREMENT,
+  `prj_id` INT NULL,
+  `stage_id` INT NULL,
+  `content` JSON NULL,
+  PRIMARY KEY (`id`),
+  INDEX `PRJ_STG` (`prj_id` ASC, `stage_id` ASC))
+COMMENT = '归档文档的需要加密签名的坐标及其他key信息(如签名角色id,签名角色名称等)';