'use strict'; const { CrudService } = require('naf-framework-mongoose-free/lib/service'); const template = require('../public/table-template'); const TSTemplate = require('../public/ts-template'); const _ = require('lodash'); const { ObjectId } = require('mongoose').Types; class TableService extends CrudService { constructor(ctx) { super(ctx, 'table'); this.model = this.ctx.model.Table; this.dirModel = this.ctx.model.Dir; } async query(query) { const project = _.get(query, 'project'); let dirs = []; if (project) { dirs = await this.dirModel.find({ project }, { name: 1, super: 1, project: 1, remark: 1, type: 'dir' }).lean(); } const datas = await this.model.find(query, { name: 1, name_zh: 1, project: 1, dir: 1, type: 'table' }).lean(); const newData = this.compareList(dirs, datas); return newData; } /** * 组合显示列表 * @param {Array} dirs 文件夹 * @param {Array} tables 表数据 */ compareList(dirs, tables) { const result = []; const noDirTables = tables.filter((f) => !f.dir); const firstLevelDir = dirs.filter((f) => !f.super); const inDirDirs = dirs.filter((f) => f.super); let newDir = this.makeDir(firstLevelDir, inDirDirs); this.compareTablesForDir(newDir, tables); result.push(...newDir, ...noDirTables); return result; } /** * 整理文件夹数据 * @param {Array} thisLevel 当前层级文件夹 * @param {Array} others 其他所属文件夹 */ makeDir(thisLevel, others) { for (const tl of thisLevel) { const _id = tl._id; let children = others.filter((f) => ObjectId(_id).equals(f.super)); if (children.length <= 0) continue; const newOthers = others.filter((f) => children.find((cf) => !ObjectId(cf._id).equals(f._id))); children = this.makeDir(children, newOthers); tl.children = children; } return thisLevel; } /** * 组合文件夹和表 * @param {Array} dirs 文件夹 * @param {Array} tables 表数据 */ compareTablesForDir(dirs, tables) { for (const dir of dirs) { const { _id, children = [] } = dir; const dts = tables.filter((f) => ObjectId(f.dir).equals(_id)); if (children.length <= 0) { children.push(...dts); dir.children = children; continue; } else { dir.children.push(...dts); } const othersTables = tables.filter((f) => !ObjectId(f.dir).equals(_id)); dir.children = this.compareTablesForDir(children, othersTables); } return dirs; } async toExport({ ids }) { const res = await this.model.find({ _id: { $in: ids } }); const data = {}; for (const i of res) { const d = template(i); data[i.name_zh ? i.name_zh : i.name] = d; } return data; } /** * 整理文件夹路径数组(一维) * @param {Array} dirs 递归文件夹数据 * @param {String} prefix 前缀 */ getDirPath(dirs, prefix = '', idPath = []) { const list = []; for (const dir of dirs) { const { children = [], name, _id } = dir; let path = `${prefix}/${name}`; let idp = [...idPath, ObjectId(_id).toString()]; let obj = { path, idPath: idp }; list.push(obj); if (children.length > 0) { let ml = this.getDirPath(children, path, idp); list.push(...ml); } } return list; } async toExportTS({ ids }) { const res = await this.model.find({ _id: { $in: ids } }).lean(); const project = res.find((f) => f.project && f.dir); let dirs = []; let dirPaths = []; if (project) { dirs = await this.dirModel.find({ project: project.project }).lean(); const firstLevelDir = dirs.filter((f) => !f.super); const inDirDirs = dirs.filter((f) => f.super); let newDir = this.makeDir(firstLevelDir, inDirDirs); dirPaths = this.getDirPath(newDir); } const data = {}; for (const i of res) { const { dir, name } = i; if (dir) { const dirObj = dirPaths.find((f) => _.last(f.idPath) === dir); if (dirObj) { let str = '../'; const levelNumber = dirObj.idPath.length || 0; for (let i = 0; i < levelNumber; i++) { str = `${str}../`; } i.getPath = (type) => `${str}${type}${dirObj.path}/${_.lowerFirst(name)}.${type}`; } } else i.getPath = (type) => `../${type}/${_.lowerFirst(name)}.${type}`; const d = TSTemplate(i); data[i.name_zh ? i.name_zh : i.name] = d; } return data; } } module.exports = TableService;