'use strict'; class FilingTemplate { constructor(ctx) { this.ctx = ctx; } async assertEditable(id) { const ctx = this.ctx; const project = ctx.session.sessionProject; const user = ctx.session.sessionUser; if (!project || !user || !project.userAccount || user.account !== project.userAccount) throw '您没有管理资料模板的权限'; if (typeof id !== 'string' || !id) throw '请选择需要修改的资料模板'; const template = await ctx.service.filingTemplateList.getDataById(id); if (!template) throw '资料模板不存在'; if (Number(template.ft_type) === ctx.service.filingTemplateList.FtType.org) throw '系统资料模板只能在SAAS后台维护'; if (Number(template.project_id) !== Number(project.id)) throw '您无权修改其他项目的资料模板'; return template; } async checkUpdate(id, data) { await this.assertEditable(id); if (!data || !['add', 'del', 'save', 'move', 'import', 'multi'].includes(data.updateType)) throw '模板操作类型错误'; const rows = await this.ctx.service.filingTemplate.getData(id); const map = new Map(rows.map(row => [row.id, row])); const checkNode = nodeId => { if (typeof nodeId !== 'string' || !map.has(nodeId)) throw '分类不属于当前资料模板'; return map.get(nodeId); }; if (['del', 'save', 'move'].includes(data.updateType)) checkNode(data.id); if (data.updateType === 'add' || data.updateType === 'move') { const parentId = String(data.tree_pid); if (parentId !== '-1') checkNode(parentId); if (data.tree_pre_id) { const previous = checkNode(data.tree_pre_id); if (String(previous.tree_pid) !== parentId) throw '所选分类不是同级分类'; } if (data.updateType === 'move') { const seen = new Set([data.id]); let current = parentId; while (current !== '-1') { if (seen.has(current)) throw '不能将分类移动到自身或其子分类中'; seen.add(current); current = String(checkNode(current).tree_pid); } } } if (data.updateType === 'multi') { if (!Array.isArray(data.data) || !data.data.length) throw '请选择需要更新的分类'; for (const row of data.data) checkNode(row && row.id); } } async initialize(id) { if (typeof id !== 'string' || !id) throw '请选择系统模板库'; const ctx = this.ctx; const list = ctx.service.filingTemplateList; const transaction = await list.beginTransaction(); try { // SAAS 的编辑、停用和删除也锁定这条模板记录;复制提交前保持锁定。 const templates = await list.getAllDataForUpdate({ id, project_id: 0 }, transaction); const template = templates[0]; if (!template) throw '选择的系统模板不存在'; if (Number(template.is_init) !== 1) throw '该模板已停用初始化,请重新选择'; const source = await ctx.service.filingTemplate.getAllDataByCondition({ where: { temp_id: id }, orders: [['tree_level', 'asc'], ['tree_order', 'asc'], ['id', 'asc']], }, transaction); if (!source.length) throw '选择的系统模板没有目录数据'; // 模板读取和项目目录写入共用连接,由此处统一提交或回滚。 const result = await ctx.service.filing.initializeDirectory( ctx.subProject.id, 'template', source, ctx.session.sessionUser.accountId, template, transaction ); await transaction.commit(); return result; } catch (err) { await transaction.rollback(); throw err; } } } module.exports = FilingTemplate;