filing_template.js 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. 'use strict';
  2. class FilingTemplate {
  3. constructor(ctx) {
  4. this.ctx = ctx;
  5. }
  6. async assertEditable(id) {
  7. const ctx = this.ctx;
  8. const project = ctx.session.sessionProject;
  9. const user = ctx.session.sessionUser;
  10. if (!project || !user || !project.userAccount || user.account !== project.userAccount) throw '您没有管理资料模板的权限';
  11. if (typeof id !== 'string' || !id) throw '请选择需要修改的资料模板';
  12. const template = await ctx.service.filingTemplateList.getDataById(id);
  13. if (!template) throw '资料模板不存在';
  14. if (Number(template.ft_type) === ctx.service.filingTemplateList.FtType.org) throw '系统资料模板只能在SAAS后台维护';
  15. if (Number(template.project_id) !== Number(project.id)) throw '您无权修改其他项目的资料模板';
  16. return template;
  17. }
  18. async checkUpdate(id, data) {
  19. await this.assertEditable(id);
  20. if (!data || !['add', 'del', 'save', 'move', 'import', 'multi'].includes(data.updateType)) throw '模板操作类型错误';
  21. const rows = await this.ctx.service.filingTemplate.getData(id);
  22. const map = new Map(rows.map(row => [row.id, row]));
  23. const checkNode = nodeId => {
  24. if (typeof nodeId !== 'string' || !map.has(nodeId)) throw '分类不属于当前资料模板';
  25. return map.get(nodeId);
  26. };
  27. if (['del', 'save', 'move'].includes(data.updateType)) checkNode(data.id);
  28. if (data.updateType === 'add' || data.updateType === 'move') {
  29. const parentId = String(data.tree_pid);
  30. if (parentId !== '-1') checkNode(parentId);
  31. if (data.tree_pre_id) {
  32. const previous = checkNode(data.tree_pre_id);
  33. if (String(previous.tree_pid) !== parentId) throw '所选分类不是同级分类';
  34. }
  35. if (data.updateType === 'move') {
  36. const seen = new Set([data.id]);
  37. let current = parentId;
  38. while (current !== '-1') {
  39. if (seen.has(current)) throw '不能将分类移动到自身或其子分类中';
  40. seen.add(current);
  41. current = String(checkNode(current).tree_pid);
  42. }
  43. }
  44. }
  45. if (data.updateType === 'multi') {
  46. if (!Array.isArray(data.data) || !data.data.length) throw '请选择需要更新的分类';
  47. for (const row of data.data) checkNode(row && row.id);
  48. }
  49. }
  50. async initialize(id) {
  51. if (typeof id !== 'string' || !id) throw '请选择系统模板库';
  52. const ctx = this.ctx;
  53. const list = ctx.service.filingTemplateList;
  54. const transaction = await list.beginTransaction();
  55. try {
  56. // SAAS 的编辑、停用和删除也锁定这条模板记录;复制提交前保持锁定。
  57. const templates = await list.getAllDataForUpdate({ id, project_id: 0 }, transaction);
  58. const template = templates[0];
  59. if (!template) throw '选择的系统模板不存在';
  60. if (Number(template.is_init) !== 1) throw '该模板已停用初始化,请重新选择';
  61. const source = await ctx.service.filingTemplate.getAllDataByCondition({
  62. where: { temp_id: id },
  63. orders: [['tree_level', 'asc'], ['tree_order', 'asc'], ['id', 'asc']],
  64. }, transaction);
  65. if (!source.length) throw '选择的系统模板没有目录数据';
  66. // 模板读取和项目目录写入共用连接,由此处统一提交或回滚。
  67. const result = await ctx.service.filing.initializeDirectory(
  68. ctx.subProject.id, 'template', source, ctx.session.sessionUser.accountId, template, transaction
  69. );
  70. await transaction.commit();
  71. return result;
  72. } catch (err) {
  73. await transaction.rollback();
  74. throw err;
  75. }
  76. }
  77. }
  78. module.exports = FilingTemplate;