import { TreeNode, TreeData } from 'element-plus/es/components/tree-v2/src/types'; export type { TreeNode, TreeData }; /** * 树节点基础字段 */ export interface TreeNodeBase { /** 节点唯一标识 */ id: string | number; /** 节点显示文本 */ label: string; /** 节点数量(可选,用于显示统计) */ count?: number; /** 节点关联名称(可选,如业主姓名) */ name?: string; /** 是否禁用节点 */ disabled?: boolean; /** 是否为叶子节点 */ isLeaf?: boolean; } /** * 树节点数据结构(支持泛型扩展) * @template T - 自定义数据类型,默认为空对象 * @example * ```typescript * interface MyNodeData { * type: 'project' | 'building'; * code: string; * } * * const treeData: TreeNodeData[] = [ * { id: 1, label: '项目', type: 'project', code: 'P001' } * ]; * ``` */ export type TreeNodeData> = TreeNodeBase & T & { /** 子节点列表 */ children?: TreeNodeData[]; }; /** * 内联输入框模式 */ export type InlineInputMode = 'add' | 'edit'; /** * 内联输入框参数 */ export interface InlineInputOptions { mode?: InlineInputMode; targetNodeKey?: string | number | null; initialValue?: string; } /** * 节点重排序事件详情 * @template T - 自定义数据类型 */ export interface NodeReorderEvent> { /** 被拖拽的节点数据 */ draggedNode: TreeNodeData; /** 原始位置信息 */ from: { /** 父节点ID(null表示根层级) */ parentId: string | number | null; /** 原始索引位置 */ index: number; /** 同级的所有兄弟节点(包含被拖拽节点) */ siblings: TreeNodeData[]; }; /** 目标位置信息 */ to: { /** 父节点ID(null表示根层级) */ parentId: string | number | null; /** 新的索引位置 */ index: number; /** 同级的所有兄弟节点(拖拽后的顺序) */ siblings: TreeNodeData[]; }; /** 是否为同级拖拽 */ isSameLevel: boolean; /** 更新后的完整树数据 */ updatedTreeData: TreeNodeData[]; } /** * 节点操作项类型(联合类型) */ export type NodeAction = { /** 操作类型:普通操作项 */ type: 'action'; /** 操作显示文本 */ label: string; /** 操作代码(唯一标识) */ code: string; /** 是否禁用该操作 */ disabled?: boolean; /** 是否危险操作(如删除) */ danger?: boolean; /** 图标(预留扩展) */ icon?: string; /** 是否显示该操作(可选,用于根据节点数据动态控制显示) */ visible?: >(data: TreeNodeData) => boolean; } | { /** 操作类型:分割线 */ type: 'divider'; /** 是否显示该分割线(可选,用于根据节点数据动态控制显示) */ visible?: >(data: TreeNodeData) => boolean; }; /** * 节点操作按钮显示控制类型 * - boolean: 全局控制所有节点是否显示 * - function: 根据节点数据和节点对象动态判断是否显示 * * @example * // 所有节点显示 * showNodeActions: true * * @example * // 只在第一层显示 * showNodeActions: (data, node) => node.level === 1 * * @example * // 根据节点类型显示 * showNodeActions: (data, node) => data.type === 'project' */ export type ShowNodeActionsType> = boolean | ((data: TreeNodeData, node: TreeNode) => boolean); /** * YcPlusTree 组件 Props(支持泛型) * @template T - 树节点自定义数据类型 */ export interface YcPlusTreeProps> { /** 树形数据 */ treeData?: TreeNodeData[]; /** 默认展开的节点 key 列表 */ expandedKeys?: (string | number)[]; /** 搜索框占位符 */ placeholder?: string; /** 节点唯一标识字段名 */ nodeKey?: string; /** 是否显示节点数量统计 */ showCount?: boolean; /** 是否显示节点操作按钮(支持函数动态判断) */ showNodeActions?: ShowNodeActionsType; /** 节点操作菜单配置(点击操作按钮时显示的下拉菜单) */ nodeActions?: NodeAction[]; /** 是否高亮当前选中节点 */ highlightCurrent?: boolean; /** 自定义过滤方法 */ filterMethod?: (value: string, data: TreeNodeData, node: TreeNode) => boolean; /** 是否显示卡片边框和圆角 */ showCardStyle?: boolean; /** 是否显示复选框 */ showCheckbox?: boolean; /** 默认选中的节点 key 列表 */ defaultCheckedKeys?: (string | number)[]; /** el-tree-v2 的 props 配置(label、children 等字段映射) */ treeProps?: TreePropsConfig; /** 是否启用拖拽功能(使用 SortableJS 实现) */ draggable?: boolean; /** SortableJS 拖拽配置选项 */ sortableDragOptions?: Partial; /** 是否只允许同级拖拽(true=只能在同一层级内拖拽,false=允许跨层级拖拽) */ sameLevelDragOnly?: boolean; /** 搜索模式:local(静态搜索) | remote(远程搜索) */ searchMode?: 'local' | 'remote'; /** 远程搜索的分页加载函数(searchMode 为 remote 时使用) */ searchLoadMore?: TreeSearchLoadMoreFunction; /** 远程搜索的每页数量 */ searchPageSize?: number; /** 远程搜索选中的值变化回调 */ onSearchChange?: (value: string | number) => void; /** 卡片内边距,支持字符串(如 '20px')或数字(会自动添加 px),默认 16 */ padding?: string | number; } /** * el-tree-v2 的 props 配置类型 */ export interface TreePropsConfig { label?: string; children?: string; disabled?: string; isLeaf?: string; class?: (data: TreeNodeData, node: TreeNode) => string | { [key: string]: boolean; }; [key: string]: unknown; } /** * 节点点击事件参数(支持泛型) * @template T - 树节点自定义数据类型 */ export interface NodeClickEventParams> { /** 节点数据 */ data: TreeNodeData; /** 节点对象 */ node: TreeNode; } /** * 操作点击事件参数(支持泛型) * @template T - 树节点自定义数据类型 */ export interface ActionClickEventParams> { /** 操作代码 */ actionCode: string; /** 节点数据 */ data: TreeNodeData; /** 节点对象 */ node: TreeNode; } /** * 拖拽位置类型 * - before: 放置在目标节点之前(同级) * - after: 放置在目标节点之后(同级) * - inner: 放置为目标节点的子节点(跨层级) */ export type DropType = 'before' | 'after' | 'inner'; /** * 拖拽节点信息 */ export interface DragNodeInfo> { /** 节点对象 */ node: TreeNode; /** 节点数据 */ data: TreeNodeData; } /** * 拖拽配置选项 */ export interface DragOptions { /** 是否启用拖拽功能 */ draggable?: boolean; /** 判断节点是否可拖拽(返回 false 则不可拖拽) */ allowDrag?: (node: TreeNode) => boolean; /** 判断拖拽节点是否可放置到目标位置(返回 false 则不可放置) */ allowDrop?: (draggingNode: TreeNode, dropNode: TreeNode, type: DropType) => boolean; } /** * 拖拽事件回调类型 */ export interface DragEvents { /** 节点开始拖拽 */ onDragStart?: (node: TreeNode, event: DragEvent) => void; /** 拖拽进入其他节点 */ onDragEnter?: (draggingNode: TreeNode, dropNode: TreeNode, event: DragEvent) => void; /** 拖拽离开节点 */ onDragLeave?: (draggingNode: TreeNode, dropNode: TreeNode, event: DragEvent) => void; /** 拖拽在节点上移动 */ onDragOver?: (draggingNode: TreeNode, dropNode: TreeNode, event: DragEvent) => void; /** 拖拽结束 */ onDragEnd?: (draggingNode: TreeNode, dropNode: TreeNode, dropType: DropType, event: DragEvent) => void; /** 节点放置完成 */ onDrop?: (draggingNode: TreeNode, dropNode: TreeNode, dropType: DropType, event: DragEvent) => void; } /** * SortableJS 拖拽配置选项 */ export interface SortableDragOptions { /** 是否启用拖拽 */ enabled?: boolean; /** 拖拽动画时长(毫秒) */ animation?: number; /** 拖拽手柄选择器(如果指定,只有点击手柄才能拖拽) */ handle?: string; /** 分组名称(相同分组的元素可以互相拖拽) */ group?: string | { name: string; pull?: boolean; put?: boolean; }; /** 是否允许拖拽到其他位置 */ sort?: boolean; /** 幽灵元素的 CSS 类名 */ ghostClass?: string; /** 选中元素的 CSS 类名 */ chosenClass?: string; /** 拖拽中元素的 CSS 类名 */ dragClass?: string; /** 判断元素是否可拖拽的函数 */ filter?: string | ((evt: Event, target: HTMLElement) => boolean); /** 阻止拖拽的选择器 */ preventOnFilter?: boolean; } /** * 远程搜索分页加载函数类型 * 用于 YcPlusTree 组件的远程搜索功能 */ export type TreeSearchLoadMoreFunction = (keyword: string, page: number, pageSize: number) => Promise<{ data: Array<{ label: string; value: string | number; [key: string]: unknown; }>; total: number; }>; export type RePlusTreeProps> = YcPlusTreeProps;