Forráskód Böngészése

变更固定审批组功能

ellisran 1 éve
szülő
commit
22d6decdec

+ 15 - 0
app/const/shenpi.js

@@ -45,9 +45,24 @@ sp_status_list[sp_status.sqspr] = { status: sp_status.sqspr, name: '授权审批
 sp_status_list[sp_status.gdspl] = { status: sp_status.gdspl, name: '固定审批流', msg: '审批流程固定,上报人只能按照设置好的审批流程进行' };
 sp_status_list[sp_status.gdzs] = { status: sp_status.gdzs, name: '固定终审', msg: '结束审批流为固定人,终审前的审批流程由上报人设置,即授权审批人' };
 
+const change_type = {
+    change: true,
+    changeProject: false,
+    changeApply: false,
+    changePlan: false,
+};
+const change_type_list = [
+    { code: 'change', name: '工程变更' },
+    { code: 'changeProject', name: '变更立项' },
+    { code: 'changeApply', name: '变更申请' },
+    { code: 'changePlan', name: '变更方案' },
+];
+
 module.exports = {
     sp_type,
     sp_lc,
     sp_status,
     sp_status_list,
+    change_type,
+    change_type_list,
 };

+ 19 - 1
app/controller/change_controller.js

@@ -485,6 +485,10 @@ module.exports = app => {
                         renderData.change.class = ctx.helper._.find(fun_set.change_class, { checked: true }).value;
                         await ctx.service.change.saveInfo({ class: ctx.helper._.find(fun_set.change_class, { checked: true }).value });
                     }
+                    // 获取固定审批流列表
+                    if (tender.info.shenpi.change === shenpiConst.sp_status.gdspl) {
+                        renderData.spGroupList = await ctx.service.shenpiGroup.getGroupListByChangeType(tender.id, shenpiConst.sp_type.change, 'change');
+                    }
                 } else if (change.readOnly && change.shenpiPower) {
                     renderData.changeLedgerList = await ctx.service.changeLedger.getAllDataByCondition({ where: { tender_id: ctx.tender.id } });
                     renderData.changePosList = await ctx.service.changePos.getAllDataByCondition({ where: { tid: ctx.tender.id } });
@@ -711,7 +715,21 @@ module.exports = app => {
                     throw '移除审核人失败';
                 }
 
-                const auditors = null;
+                const auditors = await ctx.service.changeAudit.getAuditorsNew(ctx.change.cid, ctx.change.times);
+                ctx.body = { err: 0, msg: '', data: auditors };
+            } catch (err) {
+                ctx.body = { err: 1, msg: err.toString(), data: null };
+            }
+        }
+
+        async changeSpGroup(ctx) {
+            try {
+                const data = JSON.parse(ctx.request.body.data);
+                const result = await ctx.service.changeAudit.changeSpGroup(ctx.change, data.sp_group);
+                if (!result) {
+                    throw '切换审批组失败';
+                }
+                const auditors = await ctx.service.changeAudit.getUserGroup(ctx.change.cid, ctx.change.times);
                 ctx.body = { err: 0, msg: '', data: auditors };
             } catch (err) {
                 ctx.body = { err: 1, msg: err.toString(), data: null };

+ 2 - 0
app/controller/setting_controller.js

@@ -25,6 +25,7 @@ const path = require('path');
 const funSet = require('../const/fun_set');
 const projectSettingConst = require('../const/project_setting');
 const SpreadConst = require('../const/spread');
+const shenpiConst = require('../const/shenpi');
 
 module.exports = app => {
 
@@ -1310,6 +1311,7 @@ module.exports = app => {
                     uid: this.ctx.session.sessionUser.accountId,
                     pid: this.ctx.session.sessionProject.id,
                     scPermission: scheduleConst.permission,
+                    change_type_list: shenpiConst.change_type_list,
                 };
                 renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
                 await this.layout('setting/manage.ejs', renderData, 'setting/manage_modal.ejs');

+ 28 - 8
app/controller/tender_controller.js

@@ -924,7 +924,16 @@ module.exports = app => {
             for (const sp of shenpiConst.sp_lc) {
                 sp.status = ctx.tender.info.shenpi ? ctx.tender.info.shenpi[sp.code] : shenpiConst.sp_status.sqspr;
                 if (sp.status === shenpiConst.sp_status.gdspl) {
-                    sp.auditGroupList = await ctx.service.shenpiAudit.getAuditGroupList(ctx.tender.id, sp.type, sp.status);
+                    sp.groupList = await ctx.service.shenpiGroup.getGroupList(ctx.tender.id, sp.type) || [];
+                    if (sp.groupList && sp.groupList.length > 0) {
+                        for (const group of sp.groupList) {
+                            if (group.change_type) group.change_type = JSON.parse(group.change_type);
+                            group.auditGroupList = await ctx.service.shenpiAudit.getAuditGroupList(ctx.tender.id, sp.type, sp.status, group.id);
+                            if (group.is_select) sp.auditGroupList = group.auditGroupList;
+                        }
+                    } else {
+                        sp.auditGroupList = await ctx.service.shenpiAudit.getAuditGroupList(ctx.tender.id, sp.type, sp.status);
+                    }
                 } else if (sp.status === shenpiConst.sp_status.gdzs) {
                     sp.audit = await ctx.service.shenpiAudit.getAudit(ctx.tender.id, sp.type, sp.status);
                 }
@@ -955,6 +964,7 @@ module.exports = app => {
                 cooperationNum,
                 jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.tender.shenpi),
                 auditType: auditConst.auditType,
+                change_type_list: shenpiConst.change_type_list,
             };
             await this.layout('tender/shenpi.ejs', renderData, 'tender/shenpi_modal.ejs');
         }
@@ -989,7 +999,8 @@ module.exports = app => {
                 await ctx.service.tenderInfo.saveTenderInfo(ctx.tender.id, { shenpi: postData });
                 let auditList = [];
                 if (data.status === shenpiConst.sp_status.gdspl) {
-                    auditList = await ctx.service.shenpiAudit.getAuditGroupList(ctx.tender.id, shenpiConst.sp_type[data.code], data.status);
+                    const group = await ctx.service.shenpiGroup.getGroupBySelect(ctx.tender.id, shenpiConst.sp_type[data.code]);
+                    auditList = await ctx.service.shenpiAudit.getAuditGroupList(ctx.tender.id, shenpiConst.sp_type[data.code], data.status, group ? group.id : null);
                 } else if (data.status === shenpiConst.sp_status.gdzs) {
                     auditList = await ctx.service.shenpiAudit.getAudit(ctx.tender.id, shenpiConst.sp_type[data.code], data.status);
                 }
@@ -1036,6 +1047,15 @@ module.exports = app => {
                     case 'audit-type':
                         await ctx.service.shenpiAudit.setAuditType(data);
                         break;
+                    case 'save-group':
+                        info = await ctx.service.shenpiGroup.saveGroup(ctx.tender.id, data);
+                        break;
+                    case 'change-group':
+                        await ctx.service.shenpiGroup.changeGroup(data);
+                        break;
+                    case 'delete-group':
+                        await ctx.service.shenpiGroup.deleteGroup(data);
+                        break;
                     default:break;
                 }
                 ctx.body = { err: 0, msg: '', data: info };
@@ -1249,7 +1269,7 @@ module.exports = app => {
                     responseData.data.tenders = tenderList;
                 } else if (data.type === 'ledger') {
                     responseData.data.tenders = tenderList.filter(x => {
-                        return x.ledger_status === auditConst.ledger.status.checked;    ``
+                        return x.ledger_status === auditConst.ledger.status.checked;
                     });
                     const history = await this.ctx.service.sumLoadHistory.getLedgerHistory(data.tid, data.lid);
                     if (history) responseData.data.history = { tenders: history.tenders, load_time: history.load_time, type: 'ledger' };
@@ -1287,7 +1307,7 @@ module.exports = app => {
                     }
                 }
                 ctx.body = responseData;
-            } catch(err) {
+            } catch (err) {
                 this.log(err);
                 this.ajaxErrorBody(err, '获取标段列表错误');
             }
@@ -1333,7 +1353,7 @@ module.exports = app => {
                     });
                 }
                 ctx.body = responseData;
-            } catch(err) {
+            } catch (err) {
                 this.log(err);
                 this.ajaxErrorBody(err, '获取标段列表错误');
             }
@@ -1376,7 +1396,7 @@ module.exports = app => {
                 const data = JSON.parse(ctx.request.body.data);
 
                 if (!data.user_id || !data.type) throw '数据错误';
-                switch(data.type) {
+                switch (data.type) {
                     case 'stage':
                         const stageAssists = await this.ctx.service.stageAuditAss.getUserAssist(ctx.stage, data.user_id);
                         ctx.body = { err: 0, msg: '', data: stageAssists };
@@ -1395,7 +1415,7 @@ module.exports = app => {
                 const data = JSON.parse(ctx.request.body.data);
 
                 if (!data.user_id || !data.ass_user_id || !data.type || data.confirm === undefined) throw '数据错误';
-                switch(data.type) {
+                switch (data.type) {
                     case 'stage':
                         const stageAss = await this.ctx.service.stageAuditAss.updateData(data);
                         ctx.body = { err: 0, msg: '', data: stageAss };
@@ -1599,7 +1619,7 @@ module.exports = app => {
                 if (!tid) throw '参数错误';
                 const tender = await this.ctx.service.tender.getTender(tid);
                 await this.ctx.service.tenderCache.refreshTenderCache(tender);
-            } catch(err) {
+            } catch (err) {
                 ctx.log(err);
             }
             ctx.redirect(ctx.request.header.referer);

+ 8 - 1
app/middleware/change_audit_check.js

@@ -43,7 +43,14 @@ module.exports = options => {
                 auditList.shift();
                 const auditIdList = _.map(auditList, 'uid');
                 if (shenpi_status === shenpiConst.sp_status.gdspl) {
-                    const shenpiList = yield this.service.shenpiAudit.getAllDataByCondition({ where: { tid: this.tender.id, sp_type: shenpiConst.sp_type.change, sp_status: shenpi_status } });
+                    // 判断并获取审批组
+                    const group = yield this.service.shenpiGroup.getSelectGroupByChangeType(this.tender.id, shenpiConst.sp_type.change, 'change', change.sp_group);
+                    if ((group && change.sp_group !== group.id) || (!group && change.sp_group !== 0)) {
+                        change.sp_group = group ? group.id : 0;
+                        yield this.service.change.defaultUpdate({ sp_group: change.sp_group }, { where: { cid: change.cid } });
+                    }
+                    const condition = { tid: this.tender.id, sp_type: shenpiConst.sp_type.change, sp_status: shenpi_status, sp_group: change.sp_group };
+                    const shenpiList = yield this.service.shenpiAudit.getAllDataByCondition({ where: condition });
                     // const shenpiIdList = _.map(shenpiList, 'audit_id');
                     // 判断2个id数组是否相同,不同则删除原审批流,切换成固定的审批流
                     let sameAudit = auditList.length === shenpiList.length;

+ 66 - 46
app/public/js/change_audit.js

@@ -86,52 +86,7 @@ $(document).ready(function () {
         const id = parseInt($(this).data('id'));
         if (id !== 0) {
             postData(getUrlPre() + '/audit/add', { auditorId: id }, (datas) => {
-                const html = [];
-                // 如果是重新上报,添加到重新上报列表中
-                const auditorshtml = [];
-                for (const [index,data] of datas.entries()) {
-                    if (index !== 0) {
-                        html.push('<li class="list-group-item d-flex" data-auditid="'+ data[0].uid +'">');
-                        html.push(`<div class="col-auto">${index}</div>`);
-                        html.push('<div class="col">');
-                        for (const auditor of data) {
-                            html.push(`<div class="d-inline-block mx-1" auditorId="${auditor.uid}"><i class="fa fa-user text-muted"></i> ${auditor.name} <small class="text-muted">${auditor.role}</small></div>`);
-                        }
-                        html.push('</div>');
-                        html.push('<div class="col-auto">');
-                        // todo 添加会签或签时
-                        if (data[0].audit_type !== auditType.key.common) {
-                            html.push(`<span class="badge badge-pill badge-${auditType.info[data[0].audit_type].class} badge-bg-small"><small>${auditType.info[data[0].audit_type].long}</small></span>`);
-                        }
-                        if (shenpi_status === shenpiConst.sp_status.sqspr || (shenpi_status === shenpiConst.sp_status.gdzs && index+1 !== datas.length)) {
-                            html.push('<a href="javascript: void(0)" class="text-danger pull-right">移除</a>');
-                        }
-                        html.push('</div>');
-                        html.push('</li>');
-                    }
-                    auditorshtml.push(`<li class="list-group-item d-flex justify-content-between align-items-center" data-auditid="${index !== 0 ? data[0].uid : ''}">`);
-                    auditorshtml.push('<span class="mr-1"><i class="fa ' + (index === 0 ? 'fa-play-circle fa-rotate-90' : index+1 === datas.length ? 'fa-stop-circle' : 'fa-chevron-circle-down') + '"></i></span>');
-                    auditorshtml.push('<span class="text-muted">');
-                    for (const auditor of data) {
-                        auditorshtml.push(`<small class="d-inline-block text-dark mx-1" title="${auditor.role}" data-auditorId="${auditor.uid}">${auditor.name}</small>`);
-                    }
-                    auditorshtml.push('</span>');
-                    auditorshtml.push('<div class="d-flex ml-auto">');
-                    if (data[0].audit_type !== auditType.key.common) {
-                        auditorshtml.push(`<span class="badge badge-pill badge-${auditType.info[data[0].audit_type].class} p-1"><small>${auditType.info[data[0].audit_type].short}</small></span>`);
-                    }
-                    if (index === 0) {
-                        auditorshtml.push('<span class="badge badge-light badge-pill ml-auto"><small>原报</small></span>');
-                    } else if (index+1 === datas.length) {
-                        auditorshtml.push('<span class="badge badge-light badge-pill"><small>终审</small></span>');
-                    } else {
-                        auditorshtml.push('<span class="badge badge-light badge-pill"><small>'+ transFormToChinese(index) +'审</small></span>');
-                    }
-                    auditorshtml.push('</div>');
-                    auditorshtml.push('</li>');
-                }
-                $('#auditList').html(html.join(''));
-                $('#auditors-list').html(auditorshtml.join(''));
+                makeSpList(datas);
             });
         }
     });
@@ -168,6 +123,22 @@ $(document).ready(function () {
         });
     });
 
+    // 切换审批组
+    $('#change-sp-group').change(function () {
+        const data = {
+            type: 'change_sp_group',
+            sp_group: parseInt($(this).val()),
+        }
+        if (!data.sp_group) {
+            toastr.error('请选择固定审批组');
+            return false;
+        }
+        console.log(data);
+        postData(getUrlPre() + '/audit/spgroup', data, (datas) => {
+            makeSpList(datas)
+        });
+    });
+
     $('a[f-target]').click(function () {
         $($(this).attr('f-target')).modal('show');
     });
@@ -176,6 +147,55 @@ $(document).ready(function () {
     $('#sp-list').on('hidden.bs.modal', function (e) {
         $(document.body).addClass('modal-open');
     });
+
+    function makeSpList(datas) {
+        const html = [];
+        // 如果是重新上报,添加到重新上报列表中
+        const auditorshtml = [];
+        for (const [index,data] of datas.entries()) {
+            if (index !== 0) {
+                html.push('<li class="list-group-item d-flex" data-auditid="'+ data[0].uid +'">');
+                html.push(`<div class="col-auto">${index}</div>`);
+                html.push('<div class="col">');
+                for (const auditor of data) {
+                    html.push(`<div class="d-inline-block mx-1" auditorId="${auditor.uid}"><i class="fa fa-user text-muted"></i> ${auditor.name} <small class="text-muted">${auditor.role}</small></div>`);
+                }
+                html.push('</div>');
+                html.push('<div class="col-auto">');
+                // todo 添加会签或签时
+                if (data[0].audit_type !== auditType.key.common) {
+                    html.push(`<span class="badge badge-pill badge-${auditType.info[data[0].audit_type].class} badge-bg-small"><small>${auditType.info[data[0].audit_type].long}</small></span>`);
+                }
+                if (shenpi_status === shenpiConst.sp_status.sqspr || (shenpi_status === shenpiConst.sp_status.gdzs && index+1 !== datas.length)) {
+                    html.push('<a href="javascript: void(0)" class="text-danger pull-right">移除</a>');
+                }
+                html.push('</div>');
+                html.push('</li>');
+            }
+            auditorshtml.push(`<li class="list-group-item d-flex justify-content-between align-items-center" data-auditid="${index !== 0 ? data[0].uid : ''}">`);
+            auditorshtml.push('<span class="mr-1"><i class="fa ' + (index === 0 ? 'fa-play-circle fa-rotate-90' : index+1 === datas.length ? 'fa-stop-circle' : 'fa-chevron-circle-down') + '"></i></span>');
+            auditorshtml.push('<span class="text-muted">');
+            for (const auditor of data) {
+                auditorshtml.push(`<small class="d-inline-block text-dark mx-1" title="${auditor.role}" data-auditorId="${auditor.uid}">${auditor.name}</small>`);
+            }
+            auditorshtml.push('</span>');
+            auditorshtml.push('<div class="d-flex ml-auto">');
+            if (data[0].audit_type !== auditType.key.common) {
+                auditorshtml.push(`<span class="badge badge-pill badge-${auditType.info[data[0].audit_type].class} p-1"><small>${auditType.info[data[0].audit_type].short}</small></span>`);
+            }
+            if (index === 0) {
+                auditorshtml.push('<span class="badge badge-light badge-pill ml-auto"><small>原报</small></span>');
+            } else if (index+1 === datas.length) {
+                auditorshtml.push('<span class="badge badge-light badge-pill"><small>终审</small></span>');
+            } else {
+                auditorshtml.push('<span class="badge badge-light badge-pill"><small>'+ transFormToChinese(index) +'审</small></span>');
+            }
+            auditorshtml.push('</div>');
+            auditorshtml.push('</li>');
+        }
+        $('#auditList').html(html.join(''));
+        $('#auditors-list').html(auditorshtml.join(''));
+    }
 });
 // texterea换行
 function auditCheck(i) {

+ 3 - 9
app/public/js/setting_manage.js

@@ -698,17 +698,11 @@ function setShenpiHtml(shenpi, tender, revising) {
             if (sp.status === sp_status.sqspr) {
                 html += ``;
             } else if (sp.status === sp_status.gdspl) {
-                let addhtml = '<ul class="list-unstyled">\n';
                 const flow = sp_lc.find(x => { return x.code === sp.code; });
                 flow.auditGroupList = sp.auditGroupList;
-                if (sp.auditGroupList && sp.auditGroupList.length !== 0) {
-                    for(const [i, auditGroup] of sp.auditGroupList.entries()) {
-                        addhtml += auditUtils.getAuditGroupHtml(sp.code, auditGroup, i + 1);
-                    }
-                    addhtml += '<li class="pl-3"><a href="javascript:void(0);" class="add-audit"><i class="fa fa-plus"></i> 添加流程</a></li>';
-                } else {
-                    addhtml += auditUtils.getAuditGroupHtml(sp.code, [], 1);
-                }
+                html += auditUtils.getGroupHtml(flow, sp.code);
+                let addhtml = '<ul class="list-unstyled">\n';
+                addhtml += auditUtils.getgdsplHtml(flow, sp.code);
                 addhtml += '</ul>\n';
                 html += addhtml;
             } else if (sp.status === sp_status.gdzs) {

+ 233 - 18
app/public/js/shenpi.js

@@ -225,7 +225,7 @@ function getShenpiHtml (this_code) {
                 'data-original-title="'+ (nameList.length > 0 ? nameList.join('-') : '') +'"></i>');
         }
         html.push('</td>');
-        html.push('<td>', this_code !== sp.code ? '<input type="checkbox" data-code="'+ sp.code +'">' : '', '</td>');
+        html.push('<td>', this_code !== sp.code ? '<input type="checkbox" data-code="'+ sp.code +'"' + (sp.groupList && sp.groupList.length > 0 ? 'disabled' : '') + '>' : '', '</td>');
         html.push('</tr>');
     }
     html.push('</table>');
@@ -250,11 +250,11 @@ $(document).ready(function () {
         getAuditTypeHtml: function(code, type) {
             const html = [];
             const hide = ['stage', 'change'].indexOf(code) === -1 ? 'style="display: none;"' : '';
-            html.push(`<span class="d-inline-block"><select class="form-control form-control-sm" ${hide} data-type="${type}">`);
+            html.push(`<span class="d-inline-block"><select class="form-control form-control-sm audit-type-key" ${hide} data-type="${type}">`);
             for (const t of auditType.types) {
                 html.push(`<option value="${t.value}" ${t.value === type ? 'selected' : ''}>${t.name}</option>`);
             }
-            html.push('</select></span>');
+            html.push('</select></span> ');
             return html.join('');
         },
         getSelectAuditHtml: function (code) {
@@ -315,6 +315,43 @@ $(document).ready(function () {
             html.push('</span></span></li>');
             return html.join('');
         },
+        getGroupHtml: function (flow, this_code) {
+            let html = '';
+            if (flow && flow.groupList.length > 0) {
+                let groupSelectHtml = '';
+                for (const group of flow.groupList) {
+                    groupSelectHtml += `<option value="${group.id}" ${group.is_select === 1 ? 'selected' : ''}>${group.name}</option>`;
+                }
+                const selectGroup = flow.groupList.find(x => { return x.is_select === 1 });
+                html += '<div class="d-flex justify-content-start align-items-center mb-3">\n' +
+                    '                                            <span class="col-auto">当前审批组:</span>\n' +
+                    '                                            <span style="width: 200px;">\n' +
+                    '                                                <select class="form-control form-control-sm group-list">\n' +
+                    groupSelectHtml +
+                    '                                                </select>\n' +
+                    '                                            </span>\n' +
+                    `                                            <span class="pl-3"><a href="javascript:void(0);" class="show-spzsave edit-spzsave" data-group="${selectGroup.id}" data-code="${this_code}"><i class="fa fa-edit"></i> 编辑审批组</a></span>\n` +
+                    `                                            <span class="pl-3"><a href="javascript:void(0);" class="show-spzsave" data-code="${this_code}"><i class="fa fa-plus"></i> 添加审批组</a></span>\n` +
+                    '                                        </div>';
+            }
+            return html;
+        },
+        getgdsplHtml(flow, this_code) {
+            let addhtml = '';
+            if (flow.auditGroupList.length !== 0) {
+                for(const [i, auditGroup] of flow.auditGroupList.entries()) {
+                    addhtml += auditUtils.getAuditGroupHtml(this_code, auditGroup, i + 1);
+                }
+                const addGroupHtml = this_code === 'change' && (!flow.groupList || (flow.groupList && flow.groupList.length === 0)) ?
+                    `<span class="pl-3"><a href="javascript:void(0);" class="show-spzsave" data-code="${this_code}"><i class="fa fa-save"></i> 存为审批组</a></span>\n` : '';
+                addhtml += '<li>\n' +
+                    '                                            <span class="pl-3"><a href="javascript:void(0);" class="add-audit" ><i class="fa fa-plus"></i> 添加流程</a></span>\n' + addGroupHtml +
+                    '                                        </li>';
+            } else {
+                addhtml += auditUtils.getAuditGroupHtml(this_code, [], 1);
+            }
+            return addhtml;
+        },
         // 以下i从0开始
         addAudit: function (code, user, i) {
             const flow = sp_lc.find(x => { return x.code === code });
@@ -420,20 +457,13 @@ $(document).ready(function () {
             if (this_status === sp_status.sqspr) {
                 _self.parents('.form-group').siblings('.lc-show').html('');
             } else if (this_status === sp_status.gdspl) {
-                let addhtml = '<ul class="list-unstyled">\n';
                 const flow = sp_lc.find(x => { return x.code === this_code; });
                 flow.auditGroupList = data;
-                if (data.length !== 0) {
-                    for(const [i, auditGroup] of data.entries()) {
-                        addhtml += auditUtils.getAuditGroupHtml(this_code, auditGroup, i + 1);
-                    }
-                    addhtml += '<li class="pl-3"><a href="javascript:void(0);" class="add-audit"><i class="fa fa-plus"></i> 添加流程</a></li>';
-                } else {
-                    addhtml += auditUtils.getAuditGroupHtml(this_code, [], 1);
-                }
+                let addhtml = auditUtils.getGroupHtml(flow, this_code);
+                addhtml += '<ul class="list-unstyled">\n';
+                addhtml += auditUtils.getgdsplHtml(flow, this_code);
                 addhtml += '</ul>\n';
                 _self.parents('.form-group').siblings('.lc-show').html(addhtml);
-
             } else if (this_status === sp_status.gdzs) {
                 let addhtml = '<ul class="list-unstyled">\n' +
                     '                                        <li class="d-flex justify-content-start mb-3">\n' +
@@ -490,7 +520,7 @@ $(document).ready(function () {
                 type: 'add',
             };
             if (this_status === sp_status.gdspl) {
-                prop.audit_type = parseInt($(this).parents('li').find('select')[0].value);
+                prop.audit_type = parseInt($(this).parents('li').find('select[class*="audit-type-key"]')[0].value);
                 prop.audit_order = $(this).parents('li').index() + 1;
             }
             const _self = $(this);
@@ -498,7 +528,12 @@ $(document).ready(function () {
                 if (this_status === sp_status.gdspl) {
                     const auditGroup = auditUtils.addAudit(this_code, { audit_id: data.audit_id, name: user.name, audit_type: data.audit_type, audit_order: data.audit_order }, prop.audit_order - 1);
                     if (_self.parents('ul').find('.add-audit').length === 0) {
-                        _self.parents('ul').append('<li class="pl-3"><a href="javascript:void(0);" class="add-audit"><i class="fa fa-plus"></i> 添加流程</a></li>');
+                        const flow = sp_lc.find(x => { return x.code === this_code; });
+                        const addGroupHtml = this_code === 'change' && (!flow.groupList || (flow.groupList && flow.groupList.length === 0)) ?
+                            `<span class="pl-3"><a href="javascript:void(0);" class="show-spzsave" data-code="${this_code}"><i class="fa fa-save"></i> 存为审批组</a></span>\n` : '';
+                        _self.parents('ul').append('<li>\n' +
+                            '                                            <span class="pl-3"><a href="javascript:void(0);" class="add-audit" ><i class="fa fa-plus"></i> 添加流程</a></span>\n' + addGroupHtml +
+                            '                                        </li>');
                     }
                     _self.parents('li').html(auditUtils.getAuditGroupInnerHtml(this_code, auditGroup, prop.audit_order));
                 } else {
@@ -586,7 +621,7 @@ $(document).ready(function () {
             const removes = $(li).find('.remove-audit');
             if (removes.length === 0) return;
 
-            const select = $(li).find('select');
+            const select = $(li).find('select[class*="audit-type-key"]');
             const audit_type = select.length > 0 ? parseInt(select.val()) : 1;
             for (const remove of removes) {
                 auditList.push({ audit_id: parseInt(remove.getAttribute('data-id')), audit_type, audit_order: i + 1 });
@@ -611,6 +646,7 @@ $(document).ready(function () {
         const num = $('#tender-list input:checked').length;
         if (num < 2) {
             toastr.warning('请选择需要设置审批同步的标段');
+            $(this).removeAttr('disabled');
             return;
         }
         const data = {
@@ -642,7 +678,7 @@ $(document).ready(function () {
         let canSetOther = true;
         const this_code = $(this).data('code');
         if (['stage', 'change'].indexOf(this_code) !== -1) {
-            const select = $(this).siblings('.lc-show').find('select');
+            const select = $(this).siblings('.lc-show').find('select[class*="audit-type-key"]');
             select.each((i, s) => {
                 if (s.value !== '1') canSetOther = false;
             });
@@ -675,6 +711,7 @@ $(document).ready(function () {
         const num = $('#shenpi-list input:checked').length;
         if (num < 1) {
             toastr.warning('请选择需要设置审批同步的流程');
+            $(this).removeAttr('disabled');
             return;
         }
         const data = {
@@ -701,7 +738,7 @@ $(document).ready(function () {
     });
 
     // 设置会签、或签
-    $('body').on('change', 'select', function() {
+    $('body').on('change', 'select[class*="audit-type-key"]', function() {
         const removes = $(this).parents('.d-flex').find('.remove-audit');
         if (removes.length === 0) return;
 
@@ -1008,6 +1045,184 @@ $(document).ready(function () {
         const X = $('#tender-list').find('.result').eq(now-1).offset().top;
         $('#tender-list').scrollTop(X - $('#tender-list').offset().top + $('#tender-list').scrollTop() -30);
     });
+
+    // 审批组
+    $('body').on('click', '.show-spzsave', function () {
+        const this_code = $(this).attr('data-code');
+        const groupId = $(this).attr('data-group') || null;
+        const flow = sp_lc.find(x => { return x.code === this_code; });
+        $('#save-code').val(this_code);
+        const group = groupId ? flow.groupList.find(x => { return x.id === parseInt(groupId); }) : null;
+        if (group) {
+            $('#save-group-id').val(group.id);
+            $('#spzsave input[name="group_name"]').val(group.name);
+            $('#show-delete-group-btn').show();
+        } else {
+            $('#save-group-id').val('');
+            $('#spzsave input[name="group_name"]').val('');
+            $('#show-delete-group-btn').hide();
+        }
+        if (this_code === 'change') {
+            if (group) {
+                $('#show-change-type input').each(function () {
+                    if (group.change_type[$(this).data('type')]) {
+                        $(this).prop('checked', true);
+                    } else {
+                        $(this).prop('checked', false);
+                    }
+                });
+            } else {
+                $('#show-change-type input').each(function () {
+                    $(this).prop('checked', false);
+                });
+                $('#show-change-type input[data-type="change"]').prop('checked', true);
+            }
+            $('#show-change-type input').removeAttr('disabled');
+            $('#show-change-type').show();
+        } else {
+            $('#show-change-type input').attr('disabled', true);
+            $('#show-change-type').hide();
+        }
+        $('#spzsave').modal('show');
+    });
+
+    $('#save-group-btn').click(function () {
+        const name = _.trim($('#spzsave input[name="group_name"]').val());
+        if (!name) {
+            toastr.error('审批组名称不能为空');
+            return false;
+        }
+        if (name.length > 50) {
+            toastr.error('审批组名称不能超过50个字符');
+            return false;
+        }
+        const code = $('#save-code').val();
+        const prop = {
+            type: 'save-group',
+            name,
+            code,
+        }
+        const groupId = $('#save-group-id').val();
+        const flow = sp_lc.find(x => { return x.code === code; });
+        if (flow.groupList && flow.groupList.length >= 0 && _.findIndex(flow.groupList, function (item) {
+            return item.name === name && item.id !== parseInt(groupId);
+        }) !== -1) {
+            toastr.error('审批组名称已存在, 请更改名称');
+            return false;
+        }
+        if (groupId) {
+            const group = groupId ? flow.groupList.find(x => { return x.id === parseInt(groupId); }) : null;
+            if (!group) {
+                toastr.error('审批组不存在');
+                return false;
+            }
+            prop.groupId = group.id;
+        }
+        if (code === 'change') {
+            const change_type = {};
+            let change_flag = false;
+            $('#show-change-type input').each(function () {
+                change_type[$(this).data('type')] = $(this).prop('checked');
+                if ($(this).prop('checked')) {
+                    change_flag = true;
+                }
+            });
+            if (!change_flag) {
+                toastr.error('请至少选择一种变更显示模块');
+                return false;
+            }
+            prop.change_type = change_type;
+        }
+        console.log(prop);
+        postData('/tender/' + cur_tenderid + '/shenpi/audit/save', prop, function (data) {
+            console.log(data);
+            sp_lc[sp_type[code]].auditGroupList = data.group.auditGroupList || [];
+            if (groupId) {
+                const index = sp_lc[sp_type[code]].groupList.findIndex(x => { return x.id === parseInt(groupId); });
+                sp_lc[sp_type[code]].groupList[index] = data.group;
+            } else {
+                for (const g of sp_lc[sp_type[code]].groupList) {
+                    g.is_select = 0;
+                }
+                if (!sp_lc[sp_type[code]].groupList) sp_lc[sp_type[code]].groupList = [];
+                sp_lc[sp_type[code]].groupList.push(data.group);
+            }
+            // 配置页面
+            let addhtml = auditUtils.getGroupHtml(sp_lc[sp_type[code]], code);
+            addhtml += '<ul class="list-unstyled">\n';
+            addhtml += auditUtils.getgdsplHtml(sp_lc[sp_type[code]], code);
+            addhtml += '</ul>\n';
+            $('.' + code + '_div').children('.lc-show').html(addhtml);
+            $('#spzsave').modal('hide');
+        });
+    });
+
+    // 切换审批组
+    $('body').on('change', '.group-list', function () {
+        const this_code = $(this).parents('.lc-show').siblings('.form-group').find('input:checked').data('code');
+        const groupId = parseInt($(this).val());
+        const _self = $(this);
+        const prop = {
+            type: 'change-group',
+            groupId,
+        }
+        postData('/tender/' + cur_tenderid + '/shenpi/audit/save', prop, function (data) {
+            sp_lc[sp_type[this_code]].groupList.forEach(function (item) {
+                item.is_select = 0;
+            });
+            const group = sp_lc[sp_type[this_code]].groupList.find(x => { return x.id === groupId; });
+            group.is_select = 1;
+            sp_lc[sp_type[this_code]].auditGroupList = group.auditGroupList;
+            const addhtml = auditUtils.getgdsplHtml(sp_lc[sp_type[this_code]], this_code);
+            _self.parents('.lc-show').children('ul').html(addhtml);
+            _self.parents('.lc-show').find('.edit-spzsave').attr('data-group', groupId);
+        });
+    });
+
+    $('#show-delete-group-btn').click(function () {
+        const code = $('#save-code').val();
+        const groupId = $('#save-group-id').val();
+        const flow = sp_lc.find(x => { return x.code === code; });
+        const group = groupId ? flow.groupList.find(x => { return x.id === parseInt(groupId); }) : null;
+        if (!group) {
+            toastr.error('该审批组不存在');
+            return false;
+        }
+        $('#delete-group-name').text(group.name);
+        $('#delete-group-id').val(group.id);
+        $('#delete-code').val(code);
+        $('#spzsave').modal('hide');
+        $('#spzdelete').modal('show');
+    });
+
+    $('#delete-group-btn').click(function () {
+        const code = $('#delete-code').val();
+        const groupId = $('#delete-group-id').val();
+        const flow = sp_lc.find(x => { return x.code === code; });
+        const group = groupId ? flow.groupList.find(x => { return x.id === parseInt(groupId); }) : null;
+        if (!group) {
+            toastr.error('该审批组不存在');
+            return false;
+        }
+        const prop = {
+            type: 'delete-group',
+            groupId: group.id,
+        }
+        console.log(prop);
+        postData('/tender/' + cur_tenderid + '/shenpi/audit/save', prop, function (data) {
+            const index = sp_lc[sp_type[code]].groupList.findIndex(x => { return x.id === group.id; });
+            sp_lc[sp_type[code]].groupList.splice(index, 1);
+            sp_lc[sp_type[code]].auditGroupList = sp_lc[sp_type[code]].groupList.length > 0 ? sp_lc[sp_type[code]].groupList[0].auditGroupList : [];
+            if (sp_lc[sp_type[code]].groupList.length > 0) sp_lc[sp_type[code]].groupList[0].is_select = 1;
+            // 配置页面
+            let addhtml = auditUtils.getGroupHtml(sp_lc[sp_type[code]], code);
+            addhtml += '<ul class="list-unstyled">\n';
+            addhtml += auditUtils.getgdsplHtml(sp_lc[sp_type[code]], code);
+            addhtml += '</ul>\n';
+            $('.' + code + '_div').children('.lc-show').html(addhtml);
+            $('#spzdelete').modal('hide');
+        });
+    });
 });
 
 // 审批流程-审批人html 生成

+ 1 - 0
app/router.js

@@ -553,6 +553,7 @@ module.exports = app => {
     app.post('/tender/:id/change/:cid/information/copy', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.copyChange');
     app.post('/tender/:id/change/:cid/information/audit/add', sessionAuth, tenderCheck, uncheckTenderCheck, changeCheck, 'changeController.addAudit');
     app.post('/tender/:id/change/:cid/information/audit/delete', sessionAuth, tenderCheck, uncheckTenderCheck, changeCheck, 'changeController.deleteAudit');
+    app.post('/tender/:id/change/:cid/information/audit/spgroup', sessionAuth, tenderCheck, uncheckTenderCheck, changeCheck, 'changeController.changeSpGroup');
     app.post('/tender/:id/change/cancel/audit', sessionAuth, tenderCheck, uncheckTenderCheck, changeCheck, 'changeController.checkAuditCancel');
     app.post('/tender/:id/change/:cid/information/audit/save', sessionAuth, tenderCheck, uncheckTenderCheck, changeCheck, 'changeController.saveAudit');
     // 变更新增部位页

+ 46 - 24
app/service/change_audit.js

@@ -340,30 +340,7 @@ module.exports = app => {
         async updateNewAuditList(change, newList) {
             const transaction = await this.db.beginTransaction();
             try {
-                // 先删除旧的审批流(除了原报),再添加新的
-                const sql = 'DELETE FROM ?? WHERE `cid`= ? AND `times` = ? AND `usite` != 0';
-                const sqlParam = [this.tableName, change.cid, change.times];
-                await transaction.query(sql, sqlParam);
-
-                const newAuditors = [];
-                // let uSort = await transaction.count(this.tableName, { cid: change.cid });
-                // let last_order = 0;
-                for (const auditor of newList) {
-                    const accountInfo = await this.ctx.service.projectAccount.getDataById(auditor.audit_id);
-                    newAuditors.push({
-                        tid: change.tid, cid: change.cid, uid: auditor.audit_id,
-                        name: accountInfo.name, jobs: accountInfo.role, company: accountInfo.company,
-                        times: change.times, usite: auditor.audit_order, usort: auditor.audit_order, status: auditConst.status.uncheck,
-                        audit_type: auditor.audit_type, audit_order: auditor.audit_order,
-                    });
-                    // if (auditor.audit_order !== last_order) {
-                    //     last_order = auditor.audit_order;
-                    //     uSort++;
-                    // }
-                }
-                if (newAuditors.length > 0) await transaction.insert(this.tableName, newAuditors);
-                // 同步设置原报为usort为0
-                await transaction.update(this.tableName, { usort: 0 }, { where: { cid: change.cid, times: change.times, usite: 0 } });
+                await this.updateNewAuditors(change, newList, transaction);
                 await transaction.commit();
             } catch (err) {
                 await transaction.rollback();
@@ -371,6 +348,33 @@ module.exports = app => {
             }
         }
 
+        async updateNewAuditors(change, newList, transaction) {
+            // 先删除旧的审批流(除了原报),再添加新的
+            const sql = 'DELETE FROM ?? WHERE `cid`= ? AND `times` = ? AND `usite` != 0';
+            const sqlParam = [this.tableName, change.cid, change.times];
+            await transaction.query(sql, sqlParam);
+
+            const newAuditors = [];
+            // let uSort = await transaction.count(this.tableName, { cid: change.cid });
+            // let last_order = 0;
+            for (const auditor of newList) {
+                const accountInfo = await this.ctx.service.projectAccount.getDataById(auditor.audit_id);
+                newAuditors.push({
+                    tid: change.tid, cid: change.cid, uid: auditor.audit_id,
+                    name: accountInfo.name, jobs: accountInfo.role, company: accountInfo.company,
+                    times: change.times, usite: auditor.audit_order, usort: auditor.audit_order, status: auditConst.status.uncheck,
+                    audit_type: auditor.audit_type, audit_order: auditor.audit_order,
+                });
+                // if (auditor.audit_order !== last_order) {
+                //     last_order = auditor.audit_order;
+                //     uSort++;
+                // }
+            }
+            if (newAuditors.length > 0) await transaction.insert(this.tableName, newAuditors);
+            // 同步设置原报为usort为0
+            await transaction.update(this.tableName, { usort: 0 }, { where: { cid: change.cid, times: change.times, usite: 0 } });
+        }
+
         async updateLastAudit(change, auditList, lastId) {
             const transaction = await this.db.beginTransaction();
             try {
@@ -727,6 +731,24 @@ module.exports = app => {
             return true;
         }
 
+        async changeSpGroup(change, sp_group) {
+            const transaction = await this.db.beginTransaction();
+            try {
+                const group = await this.ctx.service.shenpiGroup.getDataById(sp_group);
+                if (!group) {
+                    throw '该固定审批组不存在,请刷新页面重新获取';
+                }
+                const shenpiList = await this.ctx.service.shenpiAudit.getAllDataByCondition({ where: { tid: this.ctx.tender.id, sp_type: shenpiConst.sp_type.change, sp_status: shenpiConst.sp_status.gdspl, sp_group: group.id } });
+                await this.updateNewAuditors(change, shenpiList, transaction);
+                await transaction.update(this.ctx.service.change.tableName, { sp_group: group.id }, { where: { cid: change.cid } });
+                await transaction.commit();
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+            return true;
+        }
+
         /**
          * 开始审批
          * @param {Number} cid - 变更令id

+ 93 - 28
app/service/shenpi_audit.js

@@ -28,7 +28,16 @@ module.exports = app => {
             for (const sp of shenpiConst.sp_lc) {
                 sp.status = info.shenpi ? info.shenpi[sp.code] : shenpiConst.sp_status.sqspr;
                 if (sp.status === shenpiConst.sp_status.gdspl) {
-                    sp.auditGroupList = await this.getAuditGroupList(tid, sp.type, sp.status);
+                    sp.groupList = await this.ctx.service.shenpiGroup.getGroupList(tid, sp.type) || [];
+                    if (sp.groupList && sp.groupList.length > 0) {
+                        for (const group of sp.groupList) {
+                            if (group.change_type) group.change_type = JSON.parse(group.change_type);
+                            group.auditGroupList = await this.getAuditGroupList(tid, sp.type, sp.status, group.id);
+                            if (group.is_select) sp.auditGroupList = group.auditGroupList;
+                        }
+                    } else {
+                        sp.auditGroupList = await this.getAuditGroupList(tid, sp.type, sp.status);
+                    }
                 } else if (sp.status === shenpiConst.sp_status.gdzs) {
                     sp.audit = await this.getAudit(tid, sp.type, sp.status);
                 }
@@ -43,17 +52,17 @@ module.exports = app => {
             return await this.db.queryOne(sql, sqlParam);
         }
 
-        async getAuditList(tid, type, status) {
-            const sql = 'SELECT sp.audit_id, sp.audit_type, pa.name FROM ?? AS sp LEFT JOIN ?? AS pa ON sp.audit_id = pa.id' +
-                ' WHERE sp.tid = ? AND sp.sp_type = ? AND sp.sp_status = ? ORDER BY sp.audit_order ASC, sp.id ASC';
-            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tid, type, status];
+        async getAuditList(tid, type, status, group_id = 0) {
+            const sql = 'SELECT sp.id, sp.audit_id, sp.audit_type, pa.name FROM ?? AS sp LEFT JOIN ?? AS pa ON sp.audit_id = pa.id' +
+                ' WHERE sp.tid = ? AND sp.sp_type = ? AND sp.sp_status = ? AND sp.sp_group = ? ORDER BY sp.audit_order ASC, sp.id ASC';
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tid, type, status, group_id];
             return await this.db.query(sql, sqlParam);
         }
 
-        async getAuditGroupList(tid, type, status) {
-            const sql = 'SELECT sp.audit_id, sp.audit_type, sp.audit_order, pa.name FROM ?? AS sp LEFT JOIN ?? AS pa ON sp.audit_id = pa.id' +
-                ' WHERE sp.tid = ? AND sp.sp_type = ? AND sp.sp_status = ? ORDER BY sp.audit_order ASC, sp.id ASC';
-            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tid, type, status];
+        async getAuditGroupList(tid, type, status, group_id = 0) {
+            const sql = 'SELECT sp.audit_id, sp.audit_type, sp.audit_order, sp.sp_group, pa.name FROM ?? AS sp LEFT JOIN ?? AS pa ON sp.audit_id = pa.id' +
+                ' WHERE sp.tid = ? AND sp.sp_type = ? AND sp.sp_status = ? AND sp.sp_group = ? ORDER BY sp.audit_order ASC, sp.id ASC';
+            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tid, type, status, group_id];
             const audits = await this.db.query(sql, sqlParam);
             const result = [];
             for (const a of audits) {
@@ -86,11 +95,13 @@ module.exports = app => {
                     };
                     await transaction.update(this.ctx.service.ledgerCooperation.tableName, updateData, options);
                 }
+                const group = await this.ctx.service.shenpiGroup.getGroupBySelect(this.ctx.tender.id, data.code);
                 const insertData = {
                     tid: this.ctx.tender.id,
                     sp_type: data.code,
                     sp_status: data.status,
                     audit_id: data.audit_id,
+                    sp_group: group ? group.id : 0,
                 };
                 if (data.audit_type) insertData.audit_type = data.audit_type;
                 if (data.audit_order) insertData.audit_order = data.audit_order;
@@ -106,19 +117,23 @@ module.exports = app => {
         }
 
         async removeAudit(data) {
+            const group = await this.ctx.service.shenpiGroup.getGroupBySelect(this.ctx.tender.id, data.code);
             const delData = {
                 tid: this.ctx.tender.id,
                 sp_type: data.code,
                 sp_status: data.status,
                 audit_id: data.audit_id,
+                sp_group: group ? group.id : 0,
             };
             const audit = await this.getDataByCondition(delData);
-            const allAudit = await this.getAllDataByCondition({ where: { tid: this.ctx.tender.id, sp_type: data.code, sp_status: data.status } });
-            const sameOrder = allAudit.filter(x => { return x.audit_order === audit.audit_order });
+            const conditon = { tid: this.ctx.tender.id, sp_type: data.code, sp_status: data.status };
+            if (group) conditon.sp_group = group.id;
+            const allAudit = await this.getAllDataByCondition({ where: conditon });
+            const sameOrder = allAudit.filter(x => { return x.audit_order === audit.audit_order; });
             const updateData = [];
             if (sameOrder.length === 1) {
                 for (const aa of allAudit) {
-                    if (aa.audit_order > audit.audit_order) updateData.push({ id: aa.id, audit_order: aa.audit_order - 1});
+                    if (aa.audit_order > audit.audit_order) updateData.push({ id: aa.id, audit_order: aa.audit_order - 1 });
                 }
             }
             const transaction = await this.db.beginTransaction();
@@ -171,25 +186,66 @@ module.exports = app => {
                 const insertList = [];
                 const needYB = ['ledger', 'revise', 'change'];
                 const canYB = needYB.indexOf(data.code) !== -1;
+                let is_group = false;
+                let groupList = [];
+                if (shenpi_status === shenpiConst.sp_status.gdspl) {
+                    groupList = await this.ctx.service.shenpiGroup.getGroupList(this.ctx.tender.id, shenpiConst.sp_type[data.code]);
+                    if (groupList.length > 0) {
+                        is_group = true;
+                        for (const g of groupList) {
+                            g.auditList = await this.getAllDataByCondition({ where: { tid: this.ctx.tender.id, sp_type: shenpiConst.sp_type[data.code], sp_status: shenpi_status, sp_group: g.id } });
+                        }
+                    }
+                }
                 for (const t of tenders) {
                     if (shenpi_status !== shenpiConst.sp_status.sqspr) {
+                        if (shenpi_status === shenpiConst.sp_status.gdspl) {
+                            await transaction.delete(this.ctx.service.shenpiGroup.tableName, {
+                                tid: t.id, sp_type: shenpiConst.sp_type[data.code],
+                            });
+                        }
                         await transaction.delete(this.tableName, { tid: t.id, sp_type: shenpiConst.sp_type[data.code], sp_status: shenpi_status });
-                        const sourceList = data.auditList.filter(x => { return x.audit_id && (x.audit_id !== t.user_id || canYB) });
-                        sourceList.sort((a, b) => { return a.audit_order - b.audit_order; });
-                        let audit_order = 0, curAuditOrder = 0;
-                        for (const s of sourceList) {
-                            if (s.audit_order !== curAuditOrder) {
-                                curAuditOrder = s.audit_order;
-                                audit_order = audit_order + 1;
+                        if (is_group) {
+                            for (const g of groupList) {
+                                const result = await transaction.insert(this.ctx.service.shenpiGroup.tableName, {
+                                    tid: t.id,
+                                    sp_type: shenpiConst.sp_type[data.code],
+                                    name: g.name,
+                                    is_select: g.is_select,
+                                    change_type: g.change_type,
+                                    create_time: new Date(),
+                                });
+                                for (const s of g.auditList) {
+                                    insertList.push({
+                                        tid: t.id,
+                                        sp_type: shenpiConst.sp_type[data.code],
+                                        sp_status: shenpi_status,
+                                        audit_id: s.audit_id,
+                                        audit_type: s.audit_type,
+                                        audit_order: s.audit_order,
+                                        sp_group: result.insertId,
+                                    });
+                                }
+                            }
+                        } else {
+                            const sourceList = data.auditList.filter(x => { return x.audit_id && (x.audit_id !== t.user_id || canYB); });
+                            sourceList.sort((a, b) => { return a.audit_order - b.audit_order; });
+                            let audit_order = 0, curAuditOrder = 0;
+                            for (const s of sourceList) {
+                                if (s.audit_order !== curAuditOrder) {
+                                    curAuditOrder = s.audit_order;
+                                    audit_order = audit_order + 1;
+                                }
+                                insertList.push({
+                                    tid: t.id,
+                                    sp_type: shenpiConst.sp_type[data.code],
+                                    sp_status: shenpi_status,
+                                    audit_id: s.audit_id,
+                                    audit_type: s.audit_type,
+                                    audit_order: audit_order,
+                                    sp_group: 0,
+                                });
                             }
-                            insertList.push({
-                                tid: t.id,
-                                sp_type: shenpiConst.sp_type[data.code],
-                                sp_status: shenpi_status,
-                                audit_id: s.audit_id,
-                                audit_type: s.audit_type,
-                                audit_order: audit_order,
-                            });
                         }
                     }
                 }
@@ -219,6 +275,12 @@ module.exports = app => {
                         shenpiInfo[code] = shenpi_status;
                     }
                     if (shenpiInfo[code] !== shenpiConst.sp_status.sqspr) {
+                        if (shenpiInfo[code] === shenpiConst.sp_status.gdspl) {
+                            const group = await this.ctx.service.shenpiGroup.getAllDataByCondition({ where: { tid: this.ctx.tender.id, sp_type: shenpiConst.sp_type[code] } });
+                            if (group && group.length > 0) {
+                                throw '选择同步的流程中存在审批组,无法设置同步';
+                            }
+                        }
                         await transaction.delete(this.tableName, { tid: this.ctx.tender.id, sp_type: shenpiConst.sp_type[code], sp_status: shenpiInfo[code] });
                         for (const aid of data.aidList.split(',')) {
                             if (aid && parseInt(aid) !== this.ctx.tender.data.user_id || (parseInt(aid) === this.ctx.tender.data.user_id && needYB.indexOf(code) !== -1)) {
@@ -256,11 +318,13 @@ module.exports = app => {
             const conn = await this.db.beginTransaction();
             try {
                 const updateData = { audit_type: data.audit_type };
+                const group = await this.ctx.service.shenpiGroup.getGroupBySelect(this.ctx.tender.id, data.code);
                 const condition = {
                     tid: this.ctx.tender.id,
                     sp_type: data.code,
                     sp_status: data.status,
                     audit_id: data.audit_id,
+                    sp_group: group ? group.id : 0,
                 };
                 await conn.update(this.tableName, updateData, { where: condition });
                 await conn.commit();
@@ -378,7 +442,8 @@ module.exports = app => {
                     const shenpiauditList = {};
                     for (const shenpi in tender.shenpiInfo) {
                         if (tender.shenpiInfo[shenpi] === shenpiConst.sp_status.gdspl) {
-                            const shenpiList = await this.getAllDataByCondition({ where: { tid: tender.id, sp_type: shenpiConst.sp_type[shenpi], sp_status: tender.shenpiInfo[shenpi] } });
+                            const group = await this.ctx.service.shenpiGroup.getGroupBySelect(tender.id, shenpiConst.sp_type[shenpi]);
+                            const shenpiList = await this.getAuditList(tender.id, shenpiConst.sp_type[shenpi], tender.shenpiInfo[shenpi], group ? group.id : 0);
                             const shenpiIdList = this._.map(shenpiList, 'audit_id');
                             shenpiauditList[shenpi] = shenpiIdList.length ? shenpiIdList : null;
                         } else if (tender.shenpiInfo[shenpi] === shenpiConst.sp_status.gdzs) {

+ 169 - 0
app/service/shenpi_group.js

@@ -0,0 +1,169 @@
+'use strict';
+
+/**
+ * 版本数据模型
+ *
+ * @author CaiAoLin
+ * @date 2017/10/25
+ * @version
+ */
+const shenpiConst = require('../const/shenpi');
+
+module.exports = app => {
+
+    class ShenpiGroup extends app.BaseService {
+
+        /**
+         * 构造函数
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        constructor(ctx) {
+            super(ctx);
+            this.tableName = 'shenpi_group';
+        }
+
+        async getGroupList(tid, type, transaction = null) {
+            return transaction ? await transaction.select(this.tableName, { where: { tid, sp_type: type } }) : await this.getAllDataByCondition({ where: { tid, sp_type: type } });
+        }
+
+        async getOneGroup(id) {
+            const group = await this.getDataById(id);
+            if (group.change_type) group.change_type = JSON.parse(group.change_type);
+            group.auditGroupList = await this.ctx.service.shenpiAudit.getAuditGroupList(group.tid, group.sp_type, shenpiConst.sp_status.gdspl, group.id);
+            return group;
+        }
+
+        async saveGroup(tid, data) {
+            const transaction = await this.db.beginTransaction();
+            try {
+                const sp_type = shenpiConst.sp_type[data.code];
+                const groupList = await this.getGroupList(tid, sp_type);
+                if (data.groupId) {
+                    const info = await this.getDataById(data.groupId);
+                    if (!info) {
+                        throw '该审批组不存在';
+                    }
+                    if (this._.findIndex(groupList, function(item) {
+                        return item.id !== data.groupId && item.name === data.name;
+                    }) !== -1) {
+                        throw '该审批组名称已存在,请更改其它名称';
+                    }
+                    const updateData = {
+                        id: info.id,
+                        name: data.name,
+                    };
+                    if (data.code === 'change' && data.change_type) {
+                        updateData.change_type = JSON.stringify(data.change_type);
+                    }
+                    await transaction.update(this.tableName, updateData);
+                } else {
+                    const insertData = {
+                        tid, sp_type, name: data.name,
+                        is_select: 1, change_type: data.code === 'change' && data.change_type ? JSON.stringify(data.change_type) : null,
+                        create_time: new Date(),
+                    };
+                    const updateGroupData = this._.map(groupList, function(item) {
+                        return {
+                            id: item.id,
+                            is_select: 0,
+                        };
+                    });
+                    if (updateGroupData.length > 0) await transaction.updateRows(this.tableName, updateGroupData);
+                    const result = await transaction.insert(this.tableName, insertData);
+                    data.groupId = result.insertId;
+                    // 判断是否存在group_id 为 0的,则自动填写
+                    const auditList = await this.ctx.service.shenpiAudit.getAuditList(tid, sp_type, shenpiConst.sp_status.gdspl);
+                    if (auditList && auditList.length > 0) {
+                        const updateData = this._.map(auditList, function(item) {
+                            return {
+                                id: item.id,
+                                sp_group: data.groupId,
+                            };
+                        });
+                        await transaction.updateRows(this.ctx.service.shenpiAudit.tableName, updateData);
+                    }
+                }
+                await transaction.commit();
+                return { group: await this.getOneGroup(data.groupId) };
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+        }
+
+        async changeGroup(data) {
+            const info = await this.getDataById(data.groupId);
+            if (!info) {
+                throw '该审批组不存在';
+            }
+            const groupList = await this.getGroupList(info.tid, info.sp_type);
+            const updateGroupData = this._.map(groupList, function(item) {
+                return {
+                    id: item.id,
+                    is_select: item.id === info.id ? 1 : 0,
+                };
+            });
+            if (updateGroupData.length > 0) return await this.db.updateRows(this.tableName, updateGroupData);
+        }
+
+        async deleteGroup(data) {
+            const transaction = await this.db.beginTransaction();
+            try {
+                const group = await this.getDataById(data.groupId);
+                if (!group) throw '该审批组不存在';
+                // 移除审批人
+                await transaction.delete(this.ctx.service.shenpiAudit.tableName, { sp_group: group.id });
+                await transaction.delete(this.tableName, { id: group.id });
+                // 第一个审批组设置为is_select=1
+                const groupList = await this.getGroupList(group.tid, group.sp_type, transaction);
+                if (groupList && groupList.length > 0) {
+                    const updateGroupData = this._.map(groupList, function(item) {
+                        return {
+                            id: item.id,
+                            is_select: item.id === groupList[0].id ? 1 : 0,
+                        };
+                    });
+                    if (updateGroupData.length > 0) await transaction.updateRows(this.tableName, updateGroupData);
+                }
+                await transaction.commit();
+                return true;
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+        }
+
+        async getGroupBySelect(tid, sp_type) {
+            return await this.getDataByCondition({ tid, sp_type, is_select: 1 });
+        }
+
+        async getGroupListByChangeType(tid, sp_type, change_type) {
+            const sql = 'select * from ?? where tid= ? and sp_type= ? and JSON_CONTAINS(change_type, json_object(?, true)) order by id asc';
+            const sqlParam = [this.tableName, tid, sp_type, change_type];
+            return await this.db.query(sql, sqlParam);
+        }
+
+        async getSelectGroupByChangeType(tid, sp_type, change_type, group_id = 0) {
+            if (group_id !== 0) {
+                const group = await this.getDataById(group_id);
+                if (group) return group;
+            }
+            // 查找变更选中的审批组id,没有这为默认审批组或null
+            const result = await this.getGroupListByChangeType(tid, sp_type, change_type);
+            if (result && result.length > 0) {
+                const hadSelect = this._.find(result, function(item) {
+                    return item.is_select === 1;
+                });
+                if (hadSelect) {
+                    return hadSelect;
+                }
+                return result[0];
+            }
+            return null;
+        }
+    }
+
+    return ShenpiGroup;
+};

+ 6 - 0
app/service/tender_info.js

@@ -395,6 +395,12 @@ module.exports = app => {
             }
             const defaultShenpiInfo = JSON.parse(JSON.stringify(defaultInfo.shenpi));
             const shenpiInfo = !info.shenpi || info.shenpi === null || info.shenpi === '' ? defaultShenpiInfo : JSON.parse(info.shenpi);
+            // 查漏补缺
+            for (const sp in defaultShenpiInfo) {
+                if (!shenpiInfo[sp]) {
+                    shenpiInfo[sp] = defaultShenpiInfo[sp];
+                }
+            }
             return shenpiInfo;
         }
 

+ 11 - 0
app/view/change/information_modal.ejs

@@ -163,6 +163,17 @@
                                     <% }) %>
                                 </dl>
                             </div>
+                        <% } else if(spGroupList.length > 0) { %>
+                            <div class="row">
+                                <div class="col-7"></div>
+                                <div class="col-5">
+                                    <select class="form-control form-control-sm" id="change-sp-group">
+                                        <% for (const g of spGroupList) { %>
+                                            <option value="<%= g.id %>" <% if (g.id === change.sp_group) { %>selected<% } %>><%= g.name %></option>
+                                        <% } %>
+                                    </select>
+                                </div>
+                            </div>
                         <% } %>
                     </div>
                     <div class="card mt-3">

+ 56 - 0
app/view/setting/manage_modal.ejs

@@ -242,3 +242,59 @@
         </div>
     </div>
 </div>
+<!--存为审批组-->
+<div class="modal fade" id="spzsave" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">保存审批组</h5>
+            </div>
+            <div class="modal-body">
+                <div class="form-group mb-2">
+                    <label>审批组名称<b class="text-danger">*</b></label>
+                    <input class="form-control form-control-sm" name="group_name" placeholder="输入名称" type="text">
+                </div>
+                <div class="form-group" id="show-change-type" style="display: none">
+                    <label>显示模块</label>
+                    <div>
+                        <% for (const c of change_type_list) { %>
+                            <div class="form-check form-check-inline">
+                                <input class="form-check-input" type="checkbox" data-type="<%- c.code %>" name="change_type[]" id="<%- c.code %>_checkbox" disabled>
+                                <label class="form-check-label" for="<%- c.code %>_checkbox"><%- c.name %></label>
+                            </div>
+                        <% } %>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <input type="hidden" id="save-code">
+                <input type="hidden" id="save-group-id">
+                <button type="button" id="show-delete-group-btn" style="display: none;" class="btn btn-sm btn-danger mr-auto">删除审批组</button>
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-sm btn-primary" id="save-group-btn">确定</button>
+            </div>
+        </div>
+    </div>
+</div>
+<!--删除审批组-->
+<div class="modal fade" id="spzdelete" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">删除审批组</h5>
+            </div>
+            <div class="modal-body">
+                <div class="form-group mb-2">
+                    <h5>确认删除<span id="delete-group-name"></span>?</h5>
+                    <h5>删除后,该审批组已添加的人员也将一同移除,请谨慎操作。</h5>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <input type="hidden" id="delete-code">
+                <input type="hidden" id="delete-group-id">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-sm btn-danger" id="delete-group-btn">确定删除</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 25 - 4
app/view/tender/shenpi.ejs

@@ -34,6 +34,21 @@
                                     <div class="alert alert-warning"><%- shenpi.sp_status_list[sp.status].name %>:<%- shenpi.sp_status_list[sp.status].msg %></div>
                                     <div class="lc-show">
                                     <% if (sp.status === shenpi.sp_status.gdspl) { %>
+                                    <% if (sp.groupList && sp.groupList.length > 0) { %>
+                                        <!-- 切换 编辑 新建审批组-->
+                                        <div class="d-flex justify-content-start align-items-center mb-3">
+                                            <span class="col-auto">当前审批组:</span>
+                                            <span style="width: 200px;">
+                                                <select class="form-control form-control-sm group-list">
+                                                    <% for (const group of sp.groupList) { %>
+                                                        <option value="<%- group.id %>" <% if (group.is_select === 1) { %>selected<% } %>><%- group.name %></option>
+                                                    <% } %>
+                                                </select>
+                                            </span>
+                                            <span class="pl-3"><a href="javascript:void(0);" class="show-spzsave edit-spzsave" data-group="<%- sp.groupList.find(x => { return x.is_select === 1 }).id %>" data-code="<%- sp.code %>"><i class="fa fa-edit"></i> 编辑审批组</a></span>
+                                            <span class="pl-3"><a href="javascript:void(0);" class="show-spzsave" data-code="<%- sp.code %>"><i class="fa fa-plus"></i> 添加审批组</a></span>
+                                        </div>
+                                    <% } %>
                                     <ul class="list-unstyled">
                                         <% if (sp.auditGroupList.length > 0) { %>
                                         <% for (const [i, auditGroup] of sp.auditGroupList.entries()) { %>
@@ -41,7 +56,7 @@
                                             <span class="col-auto"><%- ctx.helper.transFormToChinese(i+1) %>审</span>
                                             <span class="col-7 spr-span">
                                                 <span class="d-inline-block">
-                                                    <select class="form-control form-control-sm" data-type="<%- auditGroup[0].audit_type %>" <% if (['stage', 'change'].indexOf(sp.code) === -1 ) { %> style="display: none;" <% } %>>
+                                                    <select class="form-control form-control-sm audit-type-key" data-type="<%- auditGroup[0].audit_type %>" <% if (['stage', 'change'].indexOf(sp.code) === -1 ) { %> style="display: none;" <% } %>>
                                                         <% for (const at of auditType.types) { %>
                                                         <option value="<%- at.value %>" <% if (auditGroup[0].audit_type === at.value) { %>selected<%} %>><%- at.name %></option>
                                                         <% } %>
@@ -92,13 +107,18 @@
                                             </span>
                                         </li>
                                         <% } %>
-                                        <li class="pl-3"><a href="javascript:void(0);" class="add-audit" ><i class="fa fa-plus"></i> 添加流程</a></li>
+                                        <li>
+                                            <span class="pl-3"><a href="javascript:void(0);" class="add-audit" ><i class="fa fa-plus"></i> 添加流程</a></span>
+                                            <% if (sp.code === 'change' && (!sp.groupList || (sp.groupList && sp.groupList.length === 0))) { %>
+                                            <span class="pl-3"><a href="javascript:void(0);" class="show-spzsave" data-code="<%- sp.code %>"><i class="fa fa-save"></i> 存为审批组</a></span>
+                                            <% } %>
+                                        </li>
                                         <% } else { %>
                                         <li class="d-flex justify-content-start mb-3 align-items-center">
                                             <span class="col-auto">一审</span>
                                             <span class="col-7 spr-span">
                                                 <span class="d-inline-block">
-                                                    <select class="form-control form-control-sm" data-type="<%- auditType.key.common %>" <% if (['stage', 'change'].indexOf(sp.code) === -1) { %> style="display: none;" <% } %>>
+                                                    <select class="form-control form-control-sm audit-type-key" data-type="<%- auditType.key.common %>" <% if (['stage', 'change'].indexOf(sp.code) === -1) { %> style="display: none;" <% } %>>
                                                         <% for (const at of auditType.types) { %>
                                                         <option value="<%- at.value %>" <% if (auditType.key.common === at.value) { %>selected<%} %>><%- at.name %></option>
                                                         <% } %>
@@ -209,7 +229,8 @@
     </div>
 </div>
 <script>
-    const sp_lc = JSON.parse('<%- JSON.stringify(shenpi.sp_lc) %>');
+    const sp_lc = JSON.parse(unescape('<%- escape(JSON.stringify(shenpi.sp_lc)) %>'));
+    console.log(sp_lc);
     const sp_type = JSON.parse('<%- JSON.stringify(shenpi.sp_type) %>');
     const sp_status = JSON.parse('<%- JSON.stringify(shenpi.sp_status) %>');
     const sp_status_list = JSON.parse('<%- JSON.stringify(shenpi.sp_status_list) %>');

+ 56 - 0
app/view/tender/shenpi_modal.ejs

@@ -166,3 +166,59 @@
         </div>
     </div>
 </div>
+<!--存为审批组-->
+<div class="modal fade" id="spzsave" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">保存审批组</h5>
+            </div>
+            <div class="modal-body">
+                <div class="form-group mb-2">
+                    <label>审批组名称<b class="text-danger">*</b></label>
+                    <input class="form-control form-control-sm" name="group_name" placeholder="输入名称" type="text">
+                </div>
+                <div class="form-group" id="show-change-type" style="display: none">
+                    <label>显示模块</label>
+                    <div>
+                        <% for (const c of change_type_list) { %>
+                        <div class="form-check form-check-inline">
+                            <input class="form-check-input" type="checkbox" data-type="<%- c.code %>" name="change_type[]" id="<%- c.code %>_checkbox" disabled>
+                            <label class="form-check-label" for="<%- c.code %>_checkbox"><%- c.name %></label>
+                        </div>
+                        <% } %>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <input type="hidden" id="save-code">
+                <input type="hidden" id="save-group-id">
+                <button type="button" id="show-delete-group-btn" style="display: none;" class="btn btn-sm btn-danger mr-auto">删除审批组</button>
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-sm btn-primary" id="save-group-btn">确定</button>
+            </div>
+        </div>
+    </div>
+</div>
+<!--删除审批组-->
+<div class="modal fade" id="spzdelete" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">删除审批组</h5>
+            </div>
+            <div class="modal-body">
+                <div class="form-group mb-2">
+                    <h5>确认删除<span id="delete-group-name"></span>?</h5>
+                    <h5>删除后,该审批组已添加的人员也将一同移除,请谨慎操作。</h5>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <input type="hidden" id="delete-code">
+                <input type="hidden" id="delete-group-id">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-sm btn-danger" id="delete-group-btn">确定删除</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 11 - 117
sql/update.sql

@@ -1,122 +1,16 @@
-ALTER TABLE `zh_tender_info`
-ADD COLUMN `s_type` varchar(20) NOT NULL DEFAULT '' COMMENT '标段类型(公路gl,房建fj,市政sz)' AFTER `dagl_info`;
-
-ALTER TABLE `zh_sub_project`
-ADD COLUMN `filing_template_id` varchar(36) NOT NULL DEFAULT '' COMMENT '资料归集模板id' AFTER `std_name`,
-ADD COLUMN `filing_template_name` varchar(255) NOT NULL DEFAULT '' COMMENT '资料归集模板名称' AFTER `filing_template_id`;
-
-CREATE TABLE `zh_filing_template_list`  (
-  `id` varchar(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'uuid',
-  `project_id` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '项目id',
-  `ft_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '模板类型(0默认,1新增)',
-  `user_id` int(11) UNSIGNED NOT NULL COMMENT '添加用户',
-  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
-  `memo` varchar(1000) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '备注',
-  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
-
-CREATE TABLE `zh_filing_template`  (
-  `id` varchar(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'uuid',
-  `temp_id` varchar(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'template_id(zh_filing_template_list)',
-  `tree_pid` varchar(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'uuid',
-  `tree_order` int(11) UNSIGNED NOT NULL COMMENT '树结构-同层排序',
-  `tree_level` int(11) UNSIGNED NOT NULL COMMENT '树结构-层级',
-  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '名称',
-  `add_user_id` int(11) NOT NULL DEFAULT 0 COMMENT '添加人',
-  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
-  `is_fixed` tinyint(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否为固定项',
-  `filing_type` int(11) NOT NULL COMMENT '文件类型(跟父项相关,类型为最顶层父项名称)',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
-
-CREATE TABLE `zh_account_cert`  (
-  `id` int NOT NULL AUTO_INCREMENT,
-  `pid` int NULL COMMENT '项目id',
-  `uid` int NULL COMMENT '用户id',
-  `type` tinyint(5) NULL DEFAULT NULL COMMENT '证书名称分类',
-  `name` tinyint(5) NULL DEFAULT NULL COMMENT '证书名称',
-  `code` varchar(255) NULL DEFAULT NULL COMMENT '证件编号',
-  `reg_unit` varchar(255) NULL DEFAULT NULL COMMENT '注册单位',
-  `job_title` varchar(255) NULL DEFAULT NULL COMMENT '技术职称',
-  `file_name` varchar(255) NULL COMMENT '文件名称',
-  `file_path` varchar(255) NULL COMMENT '文件下载地址',
-  `edu_json` json NULL COMMENT '继续教育json',
-  `create_time` datetime NULL COMMENT '创建时间',
-  PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT = '用户证书表';
-
-CREATE TABLE `zh_tender_cert`  (
+CREATE TABLE `zh_shenpi_group`  (
   `id` int NOT NULL AUTO_INCREMENT,
   `tid` int NULL COMMENT '标段id',
-  `uid` int NULL COMMENT '用户id',
-  `cert_id` int NULL COMMENT '个人证书id',
-  `department` varchar(255) NULL DEFAULT NULL COMMENT '所在部门',
-  `job_time` varchar(255) NULL DEFAULT NULL COMMENT '在岗时间',
-  `remark` varchar(1000) NULL DEFAULT NULL COMMENT '备注',
-  `create_time` datetime NULL COMMENT '入库时间',
+  `sp_type` tinyint(4) NULL COMMENT '审批流程类型',
+  `name` varchar(255) NULL COMMENT '审批组名称',
+  `is_select` tinyint(1) NULL DEFAULT 0 COMMENT '默认审批组',
+  `change_type` json NULL COMMENT '变更模块json',
+  `create_time` datetime NULL COMMENT '创建时间',
   PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT = '标段从业人员表';
-
-ALTER TABLE `zh_change_audit`
-ADD COLUMN `audit_type`  tinyint(4) UNSIGNED NOT NULL DEFAULT 1 COMMENT '审批类型(1个人,2会签,3或签)' AFTER `sin_time`,
-ADD COLUMN `audit_order`  tinyint(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '审批顺序' AFTER `audit_type`;
-
-ALTER TABLE `zh_change_audit`
-ADD COLUMN `begin_time` datetime NULL DEFAULT NULL COMMENT '审批开始时间' AFTER `sdesc`,
-ADD COLUMN `end_time` datetime NULL DEFAULT NULL COMMENT '审批结束时间' AFTER `begin_time`,
-MODIFY COLUMN `name` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL COMMENT '审批人名称' AFTER `uid`,
-MODIFY COLUMN `jobs` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL COMMENT '审批人职称' AFTER `name`,
-MODIFY COLUMN `company` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL COMMENT '审批人单位' AFTER `jobs`,
-MODIFY COLUMN `sin_time` datetime NULL DEFAULT NULL COMMENT '审批结束时间' AFTER `end_time`;
-
-CREATE TABLE `zh_project_spread`  (
-  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
-  `pid` int(11) NOT NULL COMMENT 'zh_project.id',
-  `code` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
-  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
-  `is_default` tinyint(4) UNSIGNED NOT NULL COMMENT '是否默认值',
-  `tz_ledger_set` json NULL COMMENT '台账-台账-设置',
-  `tz_ledger_bills_spread` json NULL COMMENT '台账-台账-清单spread',
-  `tz_ledger_pos_spread` json NULL COMMENT '台账-台账-计量单元spread',
-  `gcl_ledger_set` json NULL COMMENT '工程量清单-台账-设置',
-  `gcl_ledger_bills_spread` json NULL COMMENT '工程量清单-台账-清单spread',
-  `gcl_ledger_pos_spread` json NULL COMMENT '工程量清单-台账-计量单元spread',
-  `tz_stage_set` json NULL COMMENT '台账-期计量-设置',
-  `tz_stage_bills_spread` json NULL COMMENT '台账-期计量-清单spread',
-  `tz_stage_pos_spread` json NULL COMMENT '台账-期计量-计量单元spread',
-  `gcl_stage_set` json NULL COMMENT '工程量清单-期计量-设置',
-  `gcl_stage_bills_spread` json NULL COMMENT '工程量清单-期计量-清单spread',
-  `gcl_stage_pos_spread` json NULL COMMENT '工程量清单-期计量-计量单元spread',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
-
-CREATE TABLE `zh_project_col_set`  (
-  `id` int(11) NOT NULL COMMENT 'zh_project.id',
-  `info` json NULL COMMENT '金额概况页列设置(见/const/project_setting)',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
-
-INSERT INTO `zh_filing_template_list` (`id`, `project_id`, `ft_type`, `user_id`, `name`, `memo`, `create_time`, `update_time`) VALUES ('698e87d8-e947-4049-98e4-15aae7c5c7fc', 0, 0, 0, '建设项目档案管理规范DA_T 28-2018', '', '2024-03-22 15:04:31', '2024-03-22 15:06:07');
-
-INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('0395ade6-5fe6-4b36-9b0a-c3696b044aaf', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 1, 1, '立项文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 1);
-INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('5efafc28-fef5-46b3-be92-581a47cc454e', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 2, 1, '招标投标、合同协议文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 2);
-INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('ef7ce0ba-f503-4364-b73f-ed9a1fe8c98d', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 3, 1, '勘察、设计文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 3);
-INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('e2ac9fb4-08f7-4968-b5d1-c2487c2f3f61', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 4, 1, '征地、拆迁、移民文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 4);
-INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('da3b9fb7-646f-49fa-8522-64d1d5ee53b1', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 5, 1, '项目管理文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 5);
-INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('32be53bb-86db-4e4d-ae2d-03d3586e3965', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 6, 1, '施工文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 6);
-INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('4c759d53-50f4-40fe-8f3b-b5b6ba8d3db3', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 7, 1, '信息系统开发文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 7);
-INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('94505d98-f661-4be8-b381-2735476948b9', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 8, 1, '设备文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 8);
-INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('5aca0493-089e-4064-83fd-3ac061cc1b04', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 9, 1, '监理文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 9);
-INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('52f26ad6-bcd3-4bea-b533-283281fe6124', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 10, 1, '科研项目文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 10);
-INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('b95ecebd-fbd4-4110-abf4-7c055255d88f', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 11, 1, '生产技术准备、试运行文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 11);
-
-UPDATE zh_sub_project SET filing_template_id = "698e87d8-e947-4049-98e4-15aae7c5c7fc", filing_template_name = '建设项目档案管理规范DA_T 28-2018' WHERE management <> "";
-
-update `zh_change_audit` set `audit_order` = `usite`;
+) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT = '审批流程组表';
 
-update `zh_change_audit` set `begin_time` = `sin_time`;
-update `zh_change_audit` set `end_time` = `sin_time`;
+ALTER TABLE `zh_shenpi_audit`
+ADD COLUMN `sp_group` int(11) NULL DEFAULT 0 COMMENT '审批组id' AFTER `audit_order`;
 
+ALTER TABLE `zh_change`
+ADD COLUMN `sp_group` int(11) NULL DEFAULT 0 COMMENT '固定审批组id' AFTER `delimit`;

+ 122 - 0
sql/update20240419.sql

@@ -0,0 +1,122 @@
+ALTER TABLE `zh_tender_info`
+ADD COLUMN `s_type` varchar(20) NOT NULL DEFAULT '' COMMENT '标段类型(公路gl,房建fj,市政sz)' AFTER `dagl_info`;
+
+ALTER TABLE `zh_sub_project`
+ADD COLUMN `filing_template_id` varchar(36) NOT NULL DEFAULT '' COMMENT '资料归集模板id' AFTER `std_name`,
+ADD COLUMN `filing_template_name` varchar(255) NOT NULL DEFAULT '' COMMENT '资料归集模板名称' AFTER `filing_template_id`;
+
+CREATE TABLE `zh_filing_template_list`  (
+  `id` varchar(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'uuid',
+  `project_id` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '项目id',
+  `ft_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '模板类型(0默认,1新增)',
+  `user_id` int(11) UNSIGNED NOT NULL COMMENT '添加用户',
+  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+  `memo` varchar(1000) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '备注',
+  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
+
+CREATE TABLE `zh_filing_template`  (
+  `id` varchar(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'uuid',
+  `temp_id` varchar(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'template_id(zh_filing_template_list)',
+  `tree_pid` varchar(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'uuid',
+  `tree_order` int(11) UNSIGNED NOT NULL COMMENT '树结构-同层排序',
+  `tree_level` int(11) UNSIGNED NOT NULL COMMENT '树结构-层级',
+  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '名称',
+  `add_user_id` int(11) NOT NULL DEFAULT 0 COMMENT '添加人',
+  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
+  `is_fixed` tinyint(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否为固定项',
+  `filing_type` int(11) NOT NULL COMMENT '文件类型(跟父项相关,类型为最顶层父项名称)',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
+
+CREATE TABLE `zh_account_cert`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `pid` int NULL COMMENT '项目id',
+  `uid` int NULL COMMENT '用户id',
+  `type` tinyint(5) NULL DEFAULT NULL COMMENT '证书名称分类',
+  `name` tinyint(5) NULL DEFAULT NULL COMMENT '证书名称',
+  `code` varchar(255) NULL DEFAULT NULL COMMENT '证件编号',
+  `reg_unit` varchar(255) NULL DEFAULT NULL COMMENT '注册单位',
+  `job_title` varchar(255) NULL DEFAULT NULL COMMENT '技术职称',
+  `file_name` varchar(255) NULL COMMENT '文件名称',
+  `file_path` varchar(255) NULL COMMENT '文件下载地址',
+  `edu_json` json NULL COMMENT '继续教育json',
+  `create_time` datetime NULL COMMENT '创建时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT = '用户证书表';
+
+CREATE TABLE `zh_tender_cert`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `tid` int NULL COMMENT '标段id',
+  `uid` int NULL COMMENT '用户id',
+  `cert_id` int NULL COMMENT '个人证书id',
+  `department` varchar(255) NULL DEFAULT NULL COMMENT '所在部门',
+  `job_time` varchar(255) NULL DEFAULT NULL COMMENT '在岗时间',
+  `remark` varchar(1000) NULL DEFAULT NULL COMMENT '备注',
+  `create_time` datetime NULL COMMENT '入库时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT = '标段从业人员表';
+
+ALTER TABLE `zh_change_audit`
+ADD COLUMN `audit_type`  tinyint(4) UNSIGNED NOT NULL DEFAULT 1 COMMENT '审批类型(1个人,2会签,3或签)' AFTER `sin_time`,
+ADD COLUMN `audit_order`  tinyint(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '审批顺序' AFTER `audit_type`;
+
+ALTER TABLE `zh_change_audit`
+ADD COLUMN `begin_time` datetime NULL DEFAULT NULL COMMENT '审批开始时间' AFTER `sdesc`,
+ADD COLUMN `end_time` datetime NULL DEFAULT NULL COMMENT '审批结束时间' AFTER `begin_time`,
+MODIFY COLUMN `name` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL COMMENT '审批人名称' AFTER `uid`,
+MODIFY COLUMN `jobs` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL COMMENT '审批人职称' AFTER `name`,
+MODIFY COLUMN `company` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL COMMENT '审批人单位' AFTER `jobs`,
+MODIFY COLUMN `sin_time` datetime NULL DEFAULT NULL COMMENT '审批结束时间' AFTER `end_time`;
+
+CREATE TABLE `zh_project_spread`  (
+  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `pid` int(11) NOT NULL COMMENT 'zh_project.id',
+  `code` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
+  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
+  `is_default` tinyint(4) UNSIGNED NOT NULL COMMENT '是否默认值',
+  `tz_ledger_set` json NULL COMMENT '台账-台账-设置',
+  `tz_ledger_bills_spread` json NULL COMMENT '台账-台账-清单spread',
+  `tz_ledger_pos_spread` json NULL COMMENT '台账-台账-计量单元spread',
+  `gcl_ledger_set` json NULL COMMENT '工程量清单-台账-设置',
+  `gcl_ledger_bills_spread` json NULL COMMENT '工程量清单-台账-清单spread',
+  `gcl_ledger_pos_spread` json NULL COMMENT '工程量清单-台账-计量单元spread',
+  `tz_stage_set` json NULL COMMENT '台账-期计量-设置',
+  `tz_stage_bills_spread` json NULL COMMENT '台账-期计量-清单spread',
+  `tz_stage_pos_spread` json NULL COMMENT '台账-期计量-计量单元spread',
+  `gcl_stage_set` json NULL COMMENT '工程量清单-期计量-设置',
+  `gcl_stage_bills_spread` json NULL COMMENT '工程量清单-期计量-清单spread',
+  `gcl_stage_pos_spread` json NULL COMMENT '工程量清单-期计量-计量单元spread',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
+
+CREATE TABLE `zh_project_col_set`  (
+  `id` int(11) NOT NULL COMMENT 'zh_project.id',
+  `info` json NULL COMMENT '金额概况页列设置(见/const/project_setting)',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
+
+INSERT INTO `zh_filing_template_list` (`id`, `project_id`, `ft_type`, `user_id`, `name`, `memo`, `create_time`, `update_time`) VALUES ('698e87d8-e947-4049-98e4-15aae7c5c7fc', 0, 0, 0, '建设项目档案管理规范DA_T 28-2018', '', '2024-03-22 15:04:31', '2024-03-22 15:06:07');
+
+INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('0395ade6-5fe6-4b36-9b0a-c3696b044aaf', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 1, 1, '立项文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 1);
+INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('5efafc28-fef5-46b3-be92-581a47cc454e', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 2, 1, '招标投标、合同协议文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 2);
+INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('ef7ce0ba-f503-4364-b73f-ed9a1fe8c98d', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 3, 1, '勘察、设计文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 3);
+INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('e2ac9fb4-08f7-4968-b5d1-c2487c2f3f61', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 4, 1, '征地、拆迁、移民文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 4);
+INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('da3b9fb7-646f-49fa-8522-64d1d5ee53b1', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 5, 1, '项目管理文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 5);
+INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('32be53bb-86db-4e4d-ae2d-03d3586e3965', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 6, 1, '施工文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 6);
+INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('4c759d53-50f4-40fe-8f3b-b5b6ba8d3db3', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 7, 1, '信息系统开发文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 7);
+INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('94505d98-f661-4be8-b381-2735476948b9', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 8, 1, '设备文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 8);
+INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('5aca0493-089e-4064-83fd-3ac061cc1b04', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 9, 1, '监理文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 9);
+INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('52f26ad6-bcd3-4bea-b533-283281fe6124', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 10, 1, '科研项目文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 10);
+INSERT INTO `zh_filing_template` (`id`, `temp_id`, `tree_pid`, `tree_order`, `tree_level`, `name`, `add_user_id`, `create_time`, `update_time`, `is_fixed`, `filing_type`) VALUES ('b95ecebd-fbd4-4110-abf4-7c055255d88f', '698e87d8-e947-4049-98e4-15aae7c5c7fc', '-1', 11, 1, '生产技术准备、试运行文件', 13, '2024-03-25 17:16:46', '2024-03-25 17:16:46', 1, 11);
+
+UPDATE zh_sub_project SET filing_template_id = "698e87d8-e947-4049-98e4-15aae7c5c7fc", filing_template_name = '建设项目档案管理规范DA_T 28-2018' WHERE management <> "";
+
+update `zh_change_audit` set `audit_order` = `usite`;
+
+update `zh_change_audit` set `begin_time` = `sin_time`;
+update `zh_change_audit` set `end_time` = `sin_time`;
+