ソースを参照

安全计量,迁移旧数据

MaiXinRong 1 ヶ月 前
コミット
b60acaf498

+ 45 - 0
app/controller/safe_controller.js

@@ -500,6 +500,51 @@ module.exports = app => {
             }
             ctx.redirect(ctx.request.header.referer);
         }
+        /**
+         * 期审批流程(POST)
+         * @param ctx
+         * @return {Promise<void>}
+         */
+        async loadAuditors(ctx) {
+            try {
+                const order = JSON.parse(ctx.request.body.data).order;
+                const tenderId = ctx.params.tid;
+                const stage = await ctx.service.safeStage.getStageByOrder(tenderId, order);
+                await ctx.service.safeStage.loadUser(stage);
+                await ctx.service.safeStage.loadAuditViewData(stage);
+                ctx.body = { err: 0, msg: '', data: stage };
+            } catch (error) {
+                ctx.log(error);
+                ctx.body = { err: 1, msg: error.toString(), data: null };
+            }
+        }
+
+        async loadPaySafeData(ctx) {
+            try {
+                // 先获取你创建的标段及参与的标段
+                const tenderList = await ctx.service.paymentTender.getAllDataByCondition({ where: { spid: ctx.subProject.id } });
+                // 获取你创建的目录及对应目录下的所有目录
+                const folderList = await ctx.service.paymentFolder.getAllDataByCondition({ where: { spid: ctx.subProject.id } });
+                for (const tender of tenderList) {
+                    tender.details = await ctx.service.paymentDetail.getAllDataByCondition({ where: { tender_id: tender.id, type: 1 } });
+                }
+                ctx.body = { err: 0, msg: '', data: { tenderList, folderList } };
+            } catch(err) {
+                ctx.log(error);
+                ctx.ajaxErrorBody(err, '获取安全生产费旧数据失败');
+            }
+        }
+        async copyPaySafeData(ctx) {
+            try {
+                const data = JSON.parse(ctx.request.body.data);
+                if (!data.tid) throw '参数错误';
+                await ctx.service.safeStage.copyPaySafeData(data.tid);
+                ctx.body = {err: 0, msg: '迁移旧数据成功', data: null };
+            } catch(err) {
+                ctx.log(err);
+                ctx.ajaxErrorBody(err, '迁移旧数据失败');
+            }
+        }
 
         async inspectionTender(ctx) {
             try {

+ 35 - 9
app/public/js/safe_stage.js

@@ -60,7 +60,7 @@ $(document).ready(() => {
             }
         });
         return auditorsHTML;
-    }
+    };
     const getAuditHistroyHtml = function (auditHistory) {
         const historyHTML = [];
         auditHistory.forEach((his, idx) => {
@@ -134,7 +134,7 @@ $(document).ready(() => {
             historyHTML.push('</ul>');
         });
         return historyHTML.join('');
-    }
+    };
     // 获取审批流程
     $('a[data-target="#sp-list" ]').on('click', function () {
         postData('stage/auditors', { order: $(this).attr('stage-order') }, function (result) {
@@ -143,6 +143,39 @@ $(document).ready(() => {
         });
     });
 
+    // 迁移旧数据
+    $('#move-his').click(function() {
+        postData('payhis', {}, function(result) {
+            const validTenders = result.tenderList.filter(x => { return x.details.length > 0});
+            if (validTenders.length === 0) {
+                toastr.warning('该项目下,无可迁移的旧数据');
+                return;
+            }
+
+            const html = [];
+            for (const vt of validTenders) {
+                html.push('<tr>', `<td class="text-center"><input type="checkbox" name="move-his-check" value="${vt.id}"></td>`, `<td>${vt.name}</td>`, `<td class="text-center">共${vt.details.length}期</td>`, '</tr>');
+            }
+            $('#mhsb-list').html(html.join(''));
+            $('#move-his-safe-bills').modal('show');
+        });
+    });
+    $('body').on('click', '[name=move-his-check]', function(){
+        const tenders = $('[name=move-his-check]');
+        for (const t of tenders) {
+            if (t !== this) t.checked = false;
+        }
+    });
+    $('#move-his-ok').click(function() {
+        if ($('[name=move-his-check]:checked').length === 0) {
+            toastr.warning('请选择需要迁移的旧标段');
+            return;
+        }
+        postData('copyPayHis', { tid: $('[name=move-his-check]:checked').val()}, function() {
+            window.location.reload();
+        });
+    });
+
     $.subMenu({
         menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
         toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
@@ -159,11 +192,4 @@ $(document).ready(() => {
             autoFlashHeight();
         }
     });
-
-    $('select[name=stage]').select2({
-        language: 'zh-CN',
-        width: '100%',
-        multiple: true,
-        maximumSelectionlength: 6,
-    });
 });

+ 3 - 1
app/router.js

@@ -513,7 +513,7 @@ module.exports = app => {
     app.post('/sp/:id/safe/tender/:tid/stage/add', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'safeController.addStage');
     app.post('/sp/:id/safe/tender/:tid/stage/delete', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'safeController.delStage');
     app.post('/sp/:id/safe/tender/:tid/stage/save', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'safeController.saveStage');
-    app.post('/sp/:id/safe/tender/:tid/stage/auditors', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'payController.loadAuditors');
+    app.post('/sp/:id/safe/tender/:tid/stage/auditors', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'safeController.loadAuditors');
     app.get('/sp/:id/safe/tender/:tid/stage/:sorder/bills', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, safeStageCheck, 'safeController.safeBills');
     app.get('/sp/:id/safe/tender/:tid/stage/:sorder/compare', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, safeStageCheck, 'safeController.safeCompare');
     app.post('/sp/:id/safe/tender/:tid/stage/:sorder/load', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, safeStageCheck, 'safeController.safeLoad');
@@ -527,6 +527,8 @@ module.exports = app => {
     app.post('/sp/:id/safe/tender/:tid/stage/:sorder/audit/check', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, safeStageCheck, 'safeController.stageAuditCheck');
     app.post('/sp/:id/safe/tender/:tid/stage/:sorder/audit/checkAgain', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, safeStageCheck, 'safeController.stageAuditCheckAgain');
     app.post('/sp/:id/safe/tender/:tid/stage/:sorder/audit/checkCancel', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, safeStageCheck, 'safeController.stageAuditCheckCancel');
+    app.post('/sp/:id/safe/tender/:tid/payhis', sessionAuth, subProjectCheck, projectManagerCheck, 'safeController.loadPaySafeData');
+    app.post('/sp/:id/safe/tender/:tid/copyPayHis', sessionAuth, subProjectCheck, tenderCheck, projectManagerCheck, 'safeController.copyPaySafeData');
     // 安全巡检
     app.get('/sp/:id/safe/inspection', sessionAuth, subProjectCheck, 'safeController.inspectionTender');
     app.get('/sp/:id/safe/tender/:tid/inspection', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'safeController.inspection');

+ 96 - 3
app/service/safe_stage.js

@@ -9,6 +9,7 @@
  */
 
 const audit = require('../const/audit').common;
+const auditType = require('../const/audit').auditType;
 const shenpiConst = require('../const/shenpi');
 
 module.exports = app => {
@@ -112,7 +113,7 @@ module.exports = app => {
                 await conn.delete(this.ctx.service.safeStageFile.tableName, { stage_id: id });
                 await conn.delete(this.ctx.service.safeStageAudit.tableName, { stage_id: id });
                 // 记录删除日志
-                // await this.ctx.service.projectLog.addProjectLog(conn, projectLogConst.type.safeStage, projectLogConst.status.delete, `第${info.phase_order}期`);
+                // await this.ctx.service.projectLog.addProjectLog(conn, projectLogConst.type.safeStage, projectLogConst.status.delete, `第${info.stage_order}期`);
                 await conn.commit();
             } catch (err) {
                 await conn.rollback();
@@ -230,7 +231,7 @@ module.exports = app => {
                     safeStage.curSort = 0;
                 } else {
                     const checkNoAudit = await this.service.safeStageAudit.getDataByCondition({
-                        phase_id: safeStage.id, audit_times: safeStage.audit_times - 1, audit_status: audit.status.checkNo,
+                        stage_id: safeStage.id, audit_times: safeStage.audit_times - 1, audit_status: audit.status.checkNo,
                     });
                     safeStage.curSort = checkNoAudit.active_order;
                 }
@@ -251,7 +252,7 @@ module.exports = app => {
             const shenpi_status = info.shenpi.safe_stage;
             if ((safeStage.audit_status === status.uncheck || safeStage.audit_status === status.checkNo) && shenpi_status !== shenpiConst.sp_status.sqspr) {
                 // 进一步比较审批流是否与审批流程设置的相同,不同则替换为固定审批流或固定的终审
-                const auditList = await this.ctx.service.safeStageAudit.getAllDataByCondition({ where: { phase_id: safeStage.id, audit_times: safeStage.audit_times }, orders: [['audit_order', 'asc']] });
+                const auditList = await this.ctx.service.safeStageAudit.getAllDataByCondition({ where: { stage_id: safeStage.id, audit_times: safeStage.audit_times }, orders: [['audit_order', 'asc']] });
                 auditList.shift();
                 if (shenpi_status === shenpiConst.sp_status.gdspl) {
                     const shenpiList = await this.ctx.service.shenpiAudit.getAllDataByCondition({ where: { tid: safeStage.tid, sp_type: shenpiConst.sp_type.safe_payment, sp_status: shenpi_status } });
@@ -284,6 +285,98 @@ module.exports = app => {
                 }
             }
         }
+
+        async _getUserInfo(id) {
+            if (!this.cacheUserInfo) this.cacheUserInfo = [];
+            const cache = this.cacheUserInfo.find(x => { return x.id === id; });
+            if (cache) return cache;
+            const user = await this.ctx.service.projectAccount.getDataById(id);
+            this.cacheUserInfo.push(user);
+            return user;
+        }
+        async copyPaySafeData(payTenderId) {
+            const details = await this.ctx.service.paymentDetail.getAllDataByCondition({ where: { tender_id: payTenderId, type: 1 } });
+            const tid = this.ctx.tender.id;
+            const conn = await this.db.beginTransaction();
+            try {
+                const insertStage = [], insertBills = [], insertAudit = [], insertFile = [];
+                for (const detail of details) {
+                    const stage = {
+                        id: this.uuid.v4(), tid, create_user_id: detail.uid, update_user_id: this.ctx.session.sessionUser.accountId,
+                        stage_order: detail.order, stage_code: detail.code, stage_date: detail.s_time,
+                        audit_times: detail.times, audit_status: detail.status,
+                        bills_decimal: detail.bills_decimal || JSON.stringify({ up: 2, tp: 2, qty: 3 }),
+                        create_time: detail.in_time, final_auditor_str: '',
+                    };
+                    insertStage.push(stage);
+                    const safeBills = await this.ctx.service.paymentSafeBills.getAllDataByCondition({ where: { detail_id: detail.id } });
+                    for (const sb of safeBills) {
+                        sb.tender_id = tid;
+                        delete sb.detail_id;
+                        sb.stage_id = stage.id;
+                        const his = sb.cur_his ? JSON.parse(sb.cur_his) : [];
+                        for (const h of his) {
+                            h.audit_times = h.times;
+                            h.active_order = h.order;
+                            delete h.times;
+                            delete h.order;
+                        }
+                        sb.cur_his = JSON.stringify(his);
+                        insertBills.push(sb);
+                    }
+                    const user = await this._getUserInfo(detail.uid);
+                    const audits = await this.ctx.service.paymentDetailAudit.getAllDataByCondition({ where: { td_id: detail.id }, orders: [['times', 'asc'], ['order', 'asc']]});
+                    if (detail.status === audit.status.checked) {
+                        const fa = await this._getUserInfo(audits[audits.length - 1].aid);
+                        stage.final_auditor_str =`${fa.name}${(fa.role ? '-' + fa.role : '')}`;
+                    }
+                    if (audits.length === 0) {
+                        insertAudit.push({
+                            tid, stage_id: stage.id, audit_id: user.id,
+                            name: user.name, company: user.company, role: user.role, mobile: user.mobile,
+                            audit_times: a.times, audit_order: 0, active_order: 0, audit_type: auditType.key.common,
+                        });
+                    }
+                    for (const a of audits) {
+                        const auditor = await this._getUserInfo(a.aid);
+                        if (a.order === 1) {
+                            insertAudit.push({
+                                tid, stage_id: stage.id, audit_id: user.id,
+                                name: user.name, company: user.company, role: user.role, mobile: user.mobile,
+                                audit_times: a.times, audit_order: 0, active_order: 0, audit_type: auditType.key.common,
+                                audit_time: a.begin_time, audit_status: audit.status.checked,
+                            });
+                        }
+                        const same = audits.filter(x => { return a.aid === x.aid && a.times === x.times; });
+                        const audit_order = this.ctx.helper._.min(same.map(x => { return x.order}));
+                        insertAudit.push({
+                           tid, stage_id: stage.id, audit_id: auditor.id,
+                           name: auditor.name, company: auditor.company, role: auditor.role, mobile: auditor.mobile,
+                           audit_times: a.times, audit_order, active_order: a.order, audit_type: auditType.key.common,
+                           audit_status: a.status, audit_time: a.end_time, opinion: a.opinion || '',
+                        });
+                    }
+                    const files = await this.ctx.service.paymentDetailAtt.getAllDataByCondition({ where: { td_id: detail.id } });
+                    for (const f of files) {
+                        const fu = await this._getUserInfo(f.uid);
+                        insertFile.push({
+                            id: this.uuid.v4(), tid, stage_id: stage.id, type: 'bills', rela_id: f.safe_id,
+                            filename: f.filename, fileext: f.fileext, filesize: f.filesize, filepath: f.filepath,
+                            user_id: fu.id, user_name: fu.name, user_company: fu.company, user_role: fu.role,
+                            create_time: fu.upload_time, update_time: fu.upload_time,
+                        });
+                    }
+                }
+                await conn.insert(this.tableName, insertStage);
+                await conn.insert(this.ctx.service.safeStageBills.tableName, insertBills);
+                await conn.insert(this.ctx.service.safeStageAudit.tableName, insertAudit);
+                if (insertFile.length > 0) await conn.insert(this.ctx.service.safeStageFile.tableName, insertFile);
+                await conn.commit();
+            } catch (err) {
+                await conn.rollback();
+                throw err;
+            }
+        }
     }
 
     return SafeStage;

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

@@ -36,7 +36,7 @@
             </div>
             <div class="ml-auto">
                 <% if (stages.length === 0 && ctx.session.sessionUser.is_admin) { %>
-                <a href="#add-qi" data-toggle="modal" data-target="#add-qi" class="btn btn-primary btn-sm">迁移旧数据</a>
+                <button class="btn btn-primary btn-sm" id="move-his">迁移旧数据</button>
                 <% } %>
                 <% if ((stages.length === 0 || stages[0].audit_status === auditConst.status.checked) && ctx.permission.safe_payment.add) { %>
                 <a href="#add-qi" data-toggle="modal" data-target="#add-qi" class="btn btn-primary btn-sm">开始新一期</a>
@@ -108,7 +108,6 @@
     </div>
 </div>
 <script>
-    const stages = JSON.parse('<%- JSON.stringify(stages) %>');
     const auditType = JSON.parse('<%- JSON.stringify(auditType) %>');
     const auditConst = JSON.parse('<%- JSON.stringify(auditConst) %>');
 </script>

+ 17 - 0
app/view/safe_calc/stage_modal.ejs

@@ -81,6 +81,23 @@
         </div>
     </div>
 </div>
+<div class="modal" id="move-his-safe-bills" data-backdrop="stativ">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header"><h5 class="modal-title">迁移旧数据</h5></div>
+            <div class="modal-body modal-height-300">
+                <table class="table table-bordered table-hover">
+                    <thead><tr class="text-center"><th>选择</th><th>名称</th><th>安全生产费</th></tr></thead>
+                    <tbody id="mhsb-list"></tbody>
+                </table>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
+                <button type="button" class="btn btn-sm btn-primary" id="move-his-ok">确定</button>
+            </div>
+        </div>
+    </div>
+</div>
 <script>
     $('.datepicker-here').datepicker({
         autoClose: true,