table.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. 'use strict';
  2. const { CrudService } = require('naf-framework-mongoose-free/lib/service');
  3. const template = require('../public/table-template');
  4. const TSTemplate = require('../public/ts-template');
  5. const SchemaTemplate = require('../public/schema-template');
  6. const _ = require('lodash');
  7. const { ObjectId } = require('mongoose').Types;
  8. class TableService extends CrudService {
  9. constructor(ctx) {
  10. super(ctx, 'table');
  11. this.model = this.ctx.model.Table;
  12. this.dirModel = this.ctx.model.Dir;
  13. }
  14. // 导出json 模型
  15. async getSchema({ id }) {
  16. const list = await this.model.find({ project: id }, { name: 1, columns: 1 }).lean();
  17. const allSchema = SchemaTemplate(list);
  18. return allSchema;
  19. }
  20. async query(query) {
  21. const project = _.get(query, 'project');
  22. let dirs = [];
  23. if (project) {
  24. dirs = await this.dirModel.find({ project }, { name: 1, super: 1, project: 1, remark: 1, type: 'dir' }).lean();
  25. }
  26. const datas = await this.model.find(query, { name: 1, name_zh: 1, project: 1, dir: 1, type: 'table' }).lean();
  27. const newData = this.compareList(dirs, datas);
  28. return newData;
  29. }
  30. /**
  31. * 组合显示列表
  32. * @param {Array} dirs 文件夹
  33. * @param {Array} tables 表数据
  34. */
  35. compareList(dirs, tables) {
  36. const result = [];
  37. const noDirTables = tables.filter((f) => !f.dir);
  38. const firstLevelDir = dirs.filter((f) => !f.super);
  39. const inDirDirs = dirs.filter((f) => f.super);
  40. let newDir = this.makeDir(firstLevelDir, inDirDirs);
  41. this.compareTablesForDir(newDir, tables);
  42. result.push(...newDir, ...noDirTables);
  43. return result;
  44. }
  45. /**
  46. * 整理文件夹数据
  47. * @param {Array} thisLevel 当前层级文件夹
  48. * @param {Array} others 其他所属文件夹
  49. */
  50. makeDir(thisLevel, others) {
  51. for (const tl of thisLevel) {
  52. const _id = tl._id;
  53. let children = others.filter((f) => ObjectId(_id).equals(f.super));
  54. if (children.length <= 0) continue;
  55. const newOthers = others.filter((f) => children.find((cf) => !ObjectId(cf._id).equals(f._id)));
  56. children = this.makeDir(children, newOthers);
  57. tl.children = children;
  58. }
  59. return thisLevel;
  60. }
  61. /**
  62. * 组合文件夹和表
  63. * @param {Array} dirs 文件夹
  64. * @param {Array} tables 表数据
  65. */
  66. compareTablesForDir(dirs, tables) {
  67. for (const dir of dirs) {
  68. const { _id, children = [] } = dir;
  69. const dts = tables.filter((f) => ObjectId(f.dir).equals(_id));
  70. if (children.length <= 0) {
  71. children.push(...dts);
  72. dir.children = children;
  73. continue;
  74. } else {
  75. dir.children.push(...dts);
  76. }
  77. const othersTables = tables.filter((f) => !ObjectId(f.dir).equals(_id));
  78. dir.children = this.compareTablesForDir(children, othersTables);
  79. }
  80. return dirs;
  81. }
  82. async toExport({ ids }) {
  83. const res = await this.model.find({ _id: { $in: ids } });
  84. const data = {};
  85. for (const i of res) {
  86. const d = template(i);
  87. data[i.name_zh ? i.name_zh : i.name] = d;
  88. }
  89. return data;
  90. }
  91. /**
  92. * 整理文件夹路径数组(一维)
  93. * @param {Array} dirs 递归文件夹数据
  94. * @param {String} prefix 前缀
  95. */
  96. getDirPath(dirs, prefix = '', idPath = []) {
  97. const list = [];
  98. for (const dir of dirs) {
  99. const { children = [], name, _id } = dir;
  100. let path = `${prefix}/${name}`;
  101. let idp = [...idPath, ObjectId(_id).toString()];
  102. let obj = { path, idPath: idp };
  103. list.push(obj);
  104. if (children.length > 0) {
  105. let ml = this.getDirPath(children, path, idp);
  106. list.push(...ml);
  107. }
  108. }
  109. return list;
  110. }
  111. async toExportTS({ ids }) {
  112. const res = await this.model.find({ _id: { $in: ids } }).lean();
  113. const project = res.find((f) => f.project && f.dir);
  114. let dirs = [];
  115. let dirPaths = [];
  116. if (project) {
  117. dirs = await this.dirModel.find({ project: project.project }).lean();
  118. const firstLevelDir = dirs.filter((f) => !f.super);
  119. const inDirDirs = dirs.filter((f) => f.super);
  120. let newDir = this.makeDir(firstLevelDir, inDirDirs);
  121. dirPaths = this.getDirPath(newDir);
  122. }
  123. const data = {};
  124. for (const i of res) {
  125. const { dir, name } = i;
  126. if (dir) {
  127. const dirObj = dirPaths.find((f) => _.last(f.idPath) === dir);
  128. if (dirObj) {
  129. let str = '../';
  130. const levelNumber = dirObj.idPath.length || 0;
  131. for (let i = 0; i < levelNumber; i++) {
  132. str = `${str}../`;
  133. }
  134. i.getPath = (type) => `${str}${type}${dirObj.path}/${_.lowerFirst(name)}.${type}`;
  135. }
  136. } else i.getPath = (type) => `../${type}/${_.lowerFirst(name)}.${type}`;
  137. const d = TSTemplate(i);
  138. data[i.name_zh ? i.name_zh : i.name] = d;
  139. }
  140. return data;
  141. }
  142. }
  143. module.exports = TableService;