|
|
@@ -23,6 +23,121 @@ const funSet = require('../const/fun_set');
|
|
|
const defaultFunSet = funSet.defaultInfo;
|
|
|
const pageShowConst = require('../const/sp_page_show').defaultSetting;
|
|
|
|
|
|
+class DragTree {
|
|
|
+ /**
|
|
|
+ * 构造函数
|
|
|
+ */
|
|
|
+ constructor(setting) {
|
|
|
+ // 无索引
|
|
|
+ this.datas = [];
|
|
|
+ // 以key为索引indexedDB
|
|
|
+ this.items = {};
|
|
|
+ // 以排序为索引
|
|
|
+ this.nodes = [];
|
|
|
+ // 根节点
|
|
|
+ this.children = [];
|
|
|
+ // 树设置
|
|
|
+ this.setting = setting;
|
|
|
+ if (!this.setting.itemsPre) this.setting.itemsPre = 'id_';
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 树结构根据显示排序
|
|
|
+ */
|
|
|
+ sortTreeNode(isResort) {
|
|
|
+ const self = this;
|
|
|
+ const addSortNodes = function (nodes) {
|
|
|
+ if (!nodes) { return }
|
|
|
+ for (let i = 0; i < nodes.length; i++) {
|
|
|
+ self.nodes.push(nodes[i]);
|
|
|
+ nodes[i].index = self.nodes.length - 1;
|
|
|
+ if (!isResort) {
|
|
|
+ nodes[i].children = self.getChildren(nodes[i]);
|
|
|
+ } else {
|
|
|
+ nodes[i].children.sort((a, b) => { return a[self.setting.order] - b[self.setting.order]; })
|
|
|
+ }
|
|
|
+ addSortNodes(nodes[i].children);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ this.nodes = [];
|
|
|
+ if (!isResort) {
|
|
|
+ this.children = this.getChildren();
|
|
|
+ } else {
|
|
|
+ this.children.sort((a, b) => { return a[self.setting.order] - b[self.setting.order]; });
|
|
|
+ }
|
|
|
+ addSortNodes(this.children);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 加载数据(初始化), 并给数据添加部分树结构必须数据
|
|
|
+ * @param datas
|
|
|
+ */
|
|
|
+ loadDatas(datas) {
|
|
|
+ const self = this;
|
|
|
+ // 清空旧数据
|
|
|
+ this.items = {};
|
|
|
+ this.nodes = [];
|
|
|
+ this.datas = [];
|
|
|
+ this.children = [];
|
|
|
+ // 加载全部数据
|
|
|
+ datas.sort(function (a, b) {
|
|
|
+ return a[self.setting.level] - b[self.setting.level];
|
|
|
+ });
|
|
|
+ for (const data of datas) {
|
|
|
+ const keyName = this.setting.itemsPre + data[this.setting.id];
|
|
|
+ if (this.items[keyName]) continue;
|
|
|
+
|
|
|
+ const item = JSON.parse(JSON.stringify(data));
|
|
|
+ item.children = [];
|
|
|
+ item.expanded = true;
|
|
|
+ item.visible = true;
|
|
|
+ if (item[this.setting.pid] === this.setting.rootId) {
|
|
|
+ this.children.push(item);
|
|
|
+ } else {
|
|
|
+ const parent = this.getParent(item);
|
|
|
+ if (!parent) continue;
|
|
|
+ parent.children.push(item);
|
|
|
+ }
|
|
|
+ this.items[keyName] = item;
|
|
|
+ this.datas.push(item);
|
|
|
+ }
|
|
|
+ this.children.sort((a, b) => { return a[self.setting.order] - b[self.setting.order]; });
|
|
|
+ this.sortTreeNode(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ getItemsByIndex(index) {
|
|
|
+ return this.nodes[index];
|
|
|
+ }
|
|
|
+ getItems(id) {
|
|
|
+ return this.items[this.setting.itemsPre + id];
|
|
|
+ };
|
|
|
+
|
|
|
+ getParent(node) {
|
|
|
+ return this.getItems(node[this.setting.pid]);
|
|
|
+ };
|
|
|
+ getChildren(node) {
|
|
|
+ const setting = this.setting;
|
|
|
+ const pid = node ? node[setting.id] : setting.rootId;
|
|
|
+ const children = this.datas.filter(function (x) {
|
|
|
+ return x[setting.pid] === pid;
|
|
|
+ });
|
|
|
+ children.sort((a, b) => { return a[setting.order] - b[setting.order]; });
|
|
|
+ return children;
|
|
|
+ };
|
|
|
+ isLastSibling(node) {
|
|
|
+ const siblings = this.getChildren(this.getParent(node));
|
|
|
+ return (siblings && siblings.length > 0) ? node[this.setting.order] === siblings[siblings.length - 1][this.setting.order] : false;
|
|
|
+ };
|
|
|
+
|
|
|
+ recursiveFun(children, fun) {
|
|
|
+ if (!fun) return;
|
|
|
+ if (!children || children.length === 0) return;
|
|
|
+
|
|
|
+ for (const c of children) {
|
|
|
+ this.recursiveFun(c.children, fun);
|
|
|
+ fun(c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
module.exports = app => {
|
|
|
class SubProject extends app.BaseService {
|
|
|
|
|
|
@@ -97,6 +212,19 @@ module.exports = app => {
|
|
|
return admin ? result : this._filterEmptyFolder(result);
|
|
|
}
|
|
|
|
|
|
+ async getSubProjectTreeNodes(pid, uid, admin, filterFolder = false) {
|
|
|
+ const subProjects = await this.getSubProject(pid, uid, admin, filterFolder);
|
|
|
+ const subProjectsTree = new DragTree({ id: 'id', pid: 'tree_pid', level: 'tree_level', order: 'tree_order', rootId: '-1' });
|
|
|
+ subProjectsTree.loadDatas(subProjects);
|
|
|
+ const result = subProjectsTree.nodes.map(x => {
|
|
|
+ return {
|
|
|
+ id: x.id, tree_pid: x.tree_pid, tree_level: x.tree_level, is_folder: x.is_folder, name: x.name,
|
|
|
+ is_last_sibling: subProjectsTree.isLastSibling(x), has_children: x.children && x.children.length > 0,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
async getBudgetProject(pid, uid, admin) {
|
|
|
let result = await this.getAllDataByCondition({ where: { project_id: pid, is_delete: 0 } });
|
|
|
|