更新记录

1.1.0(2024-08-28) 下载此版本

将refType和refKey补充为组合唯一键,使同一个数据集可以通过不同的refKey在不同的树中定位。

1.0.0(2024-08-26) 下载此版本

初始发布,确定数据结构、功能接口及使用流程。


平台兼容性

阿里云 腾讯云 支付宝云

云函数类插件通用教程

使用云函数类插件的前提是:使用HBuilderX 2.9+


nickw-tree

该功能的设计目的是将树形结构的处理与业务剥离,因此仅用于树形节点的管理,节点的其他信息由专门的表或数据集合处理。因此该模块的功能应为后端调用而不是前端。

该数据结构在写入性能随单颗树内数据量的增加而下降,但查询性能不受影响。

基本逻辑:对于树形数据,自最左侧叶子开始按左、右、父的方式排序,可以将树投影于数轴,因此为每个节点补充了其下最左侧子节点信息后,每个节点在数轴上的投影就由点转换为了线段。线段内的所有点都是该线段的子节点。

数据表及结构

  1. tree-node: 树形数据结构表
  2. tree-refer: 树形数据结构与扩展数据集合关系表。
  3. data-group: 扩展数据示例表

tree-node 树形数据结构

属性名 类型 说明
_id string 节点唯一标识
rid string 隶属的根节点
pid string 父节点
level int 树高
snum int 节点在树内的顺序号
lfnum int 最左侧子节点的顺序号

tree-refer 树形数据结构与扩展数据集合关系表

属性名 类型 说明
_id string 关系唯一标识
treeId string 树形数据结构表中根节点的_id
refType string 扩展数据集合名称
refKey string 扩展数据集合中关联tree-node._id的属性名称

data-group 扩展数据示例表,用于基本示例

属性名 类型 说明
_id string 关系唯一标识
treeNodeId string 关联tree-node.id
name string 数据组名称
code string 数据组的语义化标识
description string 备注信息
createTime timestamp 创建时间

API

方法名 说明
createRoot 创建树
removeRoot 删除树
addNode 增加节点
removeNode 移除节点(及子节点)
moveNode 移动节点
getNodes 节点查询
getParendNodes 父节点查询
getSharedParendNode 公共父节点查询

注: 由于任意节点的子节点数量 = snum - lfnum,因此不提供是否存在子节点类的查询接口。

创建树

参数:

  1. refType: 扩展数据集合名称
  2. refKey: 扩展数据集合中关联tree-node._id的属性名称

返回值: tree-refer 表的数据,包括:

  1. treeId: 树形数据结构表中根节点的_id的值
  2. refType: 扩展数据集合名称
  3. refKey: 扩展数据集合中关联tree-node._id的属性名称
const treeNode = await createRoot({
  refType: "data-group",
  refKey: "treeNodeId",
});

删除树

参数: 根节点的 treeId

返回值: Boolean

const treeId = "string";
const success = await removeRoot(treeId);

增加节点

参数:

  1. treeNodeId: 节点唯一标识
  2. afterNode: Boolean,是否在指定节点的右侧添加节点,默认为 true

返回值: tree-node 表的数据,包括:

  1. id: 唯一键值
  2. rid: 隶属的根节点
  3. pid: 父节点
  4. level: 树高
  5. snum: 节点在树内的顺序号
  6. lfnum: 最左侧子节点的顺序号
/** 在指定节点的右侧添加节点 */
const treeNode = await addNode({
  treeNodeId: "string",
  afterNode: true,
});

/** 为指定节点添加子节点,且新增的节点是指定节点下最左侧的子节点 */
const treeNode = await addNode({
  treeNodeId: "string",
  afterNode: false,
});

移除节点(及子节点)

参数: 节点唯一标识 返回值: [{id: string}]

const treeNodeId = "string";
const success = await removeNode(treeNodeId);

移动节点

参数:

  1. treeNodeId: 节点唯一标识,需要移动的节点
  2. targetNodeId: 参考位置节点唯一标识
  3. afterNode: Boolean,是否在参考位置节点的右侧添加节点,默认为 true,否则作为参考位置节点的最左侧子节点。

返回值: Boolean

/** 移动到指定节点的右侧 */
const modifiedList = await moveNode({
  treeNodeId: "string",
  targetNodeId: "string",
  afterNode: true,
});

/** 移动到指定节点的子级,且位于指定节点下最左侧 */
const modifiedList = await moveNode({
  treeNodeId: "string",
  targetNodeId: "string",
  afterNode: false,
});

为什么没有返回移动后的节点信息?移动节点后,其他节点的snumlfnum也会发生变化,而前端使用时通常并不需要该信息(因为展示的树已经是正确结构),因此直接返回Boolean

公共父节点查询

查询两个节点的最近的公共父节点。

/** 查询指定节点的所有公共父节点 */
const nodeList = await getSharedParendNode({
  treeNodeA: "object",
  treeNodeB: "object",
});

节点查询

参数(如果 level=0,refType,treeNodeId 都不存在则查询结果为空数组):

  1. level: 树高,可选,限制返回的节点层级,为 0 时忽略其他参数返回所有根节点。
  2. refType: 扩展数据集合名称,可选(但是 refType + refKey 和 treeNodeId 不能同时为空(level=0 的特例除外))
  3. refKey: 扩展数据集合中关联tree-node._id的属性名称,可选
  4. treeNodeId: 节点唯一标识,可选(但是 refType 和 treeNodeId 不能同时为空(level=0 的特例除外))
  5. self: Boolean,是否包含查询节点自身(或根节点)
  6. levelLimit: 节点查询的子节点层级限制,可选,最小为 2,默认会返回所有子节点。
/** 特例参数查询,指定了level为0时忽略其他条件,用于查询所有根节点(通常没有任何意义) */
const nodeList = await getNodes({
  level: 0,
});

/** 查询指定扩展类型的所有子节点,但不包括根节点 */
const nodeList = await getNodes({
  refType: "group",
  self: false,
});

/** 查询指定节点的3级以内子节点 */
const nodeList = await getNodes({
  treeNodeId: "string",
  levelLimit: 3,
});

父节点查询

参数:

  1. treeNodeId: 节点唯一标识,可选
  2. self: Boolean,是否包含查询节点自身
/** 查询指定节点的所有父节点 */
const nodeList = await getParentNodes({
  treeNodeId: "string",
  self: true,
});

节点查询的返回数据结构

泛型 T 是扩展数据集合中的数据类型。根节点对应的data为 undefined。

interface TreeNode<T = any> {
  id: "string";
  rid: "string";
  pid: "string";
  level: "number";
  snum: "number";
  lfnum: "number";
  data?: T;
}

测试

对象提供了test()方法进行功能测试,并可以作为全流程的基本使用示例。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问