From 9a34e9d39955b05b7e37fe3cbf770b6b69a0cb2b Mon Sep 17 00:00:00 2001 From: hailin Date: Mon, 12 Jan 2026 03:55:51 -0800 Subject: [PATCH] =?UTF-8?q?feat(mining-admin-web):=20=E5=BC=95=E8=8D=90?= =?UTF-8?q?=E5=85=B3=E7=B3=BB=E6=94=B9=E4=B8=BA=E6=A0=91=E5=BD=A2=E5=8F=AF?= =?UTF-8?q?=E8=A7=86=E5=8C=96=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 仿照1.0 admin-web的树形结构 - 显示引荐人链(向上)、总部节点、当前用户 - 递归展开/收起直推下级 - 圆形+-按钮控制展开 Co-Authored-By: Claude Opus 4.5 --- .../users/components/referral-tree.tsx | 273 +++++++++--------- 1 file changed, 131 insertions(+), 142 deletions(-) diff --git a/frontend/mining-admin-web/src/features/users/components/referral-tree.tsx b/frontend/mining-admin-web/src/features/users/components/referral-tree.tsx index c3a3d817..aa78852e 100644 --- a/frontend/mining-admin-web/src/features/users/components/referral-tree.tsx +++ b/frontend/mining-admin-web/src/features/users/components/referral-tree.tsx @@ -8,8 +8,6 @@ import { formatNumber } from '@/lib/utils/format'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; -import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; -import { ChevronDown, ChevronRight, Users, TreePine, Building2 } from 'lucide-react'; import type { ReferralNode } from '@/types/user'; import { cn } from '@/lib/utils'; @@ -101,187 +99,178 @@ export function ReferralTree({ accountSequence }: ReferralTreeProps) { return ( - 引荐关系 + 引荐关系树 {treeRootUser !== accountSequence && ( )} - - {/* 向上的引荐人链 */} -
-

引荐人链 (向上)

- {(referralTree.ancestors?.length ?? 0) > 0 ? ( -
- {(referralTree.ancestors || []).map((ancestor, index) => ( -
- handleTreeNodeClick(ancestor)} - variant="ancestor" - /> - {index < (referralTree.ancestors?.length ?? 0) - 1 && ( -
- + + {/* 树形结构容器 - 仿照1.0 admin-web的样式 */} +
+ {/* 向上的引荐人链 */} +
+ + 引荐人链 (向上) + + {(referralTree.ancestors?.length ?? 0) > 0 ? ( + <> +
+ {(referralTree.ancestors || []).map((ancestor, index) => ( +
+ handleTreeNodeClick(ancestor)} + /> + {index < (referralTree.ancestors?.length ?? 0) - 1 && ( +
+ )}
- )} + ))}
- ))} -
- -
-
- ) : ( -
- - 总部 -
- )} -
- - {/* 当前用户 */} -
-

当前用户

- -
- - {/* 直推下级列表 */} - {(referralTree.directReferrals?.length ?? 0) > 0 && ( -
-

- 直推下级 ({referralTree.directReferrals?.length ?? 0}) -

-
- {(referralTree.directReferrals || []).map((child) => ( - - ))} -
+
+ + ) : ( + <> + {/* 总部节点 */} +
+ 总部 +
+
+ + )}
- )} + + {/* 当前用户节点 - 递归组件 */} +
+ +
+
); } -interface ReferralNodeCardProps { +/** + * 树节点卡片 - 单个节点的展示 + */ +interface TreeNodeCardProps { node: ReferralNode; isCurrentUser?: boolean; isHighlight?: boolean; - variant?: 'ancestor' | 'current' | 'child'; - expandedNodes?: Record; - onToggle?: (nodeSeq: string, hasChildren: boolean) => void; - onClick?: (node: ReferralNode) => void; - showExpandButton?: boolean; + onClick?: () => void; } -function ReferralNodeCard({ +function TreeNodeCard({ node, isCurrentUser, isHighlight, onClick }: TreeNodeCardProps) { + return ( + + ); +} + +/** + * 递归渲染引荐节点 - 支持展开/收起子节点 + */ +interface ReferralNodeItemProps { + node: ReferralNode; + isCurrentUser?: boolean; + isHighlight?: boolean; + expandedNodes: Record; + onToggle: (nodeSeq: string, hasChildren: boolean) => void; + onClick: (node: ReferralNode) => void; +} + +function ReferralNodeItem({ node, isCurrentUser = false, isHighlight = false, - variant, - expandedNodes = {}, + expandedNodes, onToggle, onClick, - showExpandButton = false, -}: ReferralNodeCardProps) { +}: ReferralNodeItemProps) { const hasChildren = node.directReferralCount > 0; const isExpanded = expandedNodes[node.accountSequence] !== undefined; const isLoading = expandedNodes[node.accountSequence] === null; const children = expandedNodes[node.accountSequence] || []; return ( -
-
onClick?.(node)} - > - - - {node.nickname?.charAt(0) || 'U'} - +
+ {/* 节点内容 */} +
+ onClick(node)} + /> -
-
- {node.accountSequence} - {node.nickname || '未设置'} -
-
- - - 个人: {formatNumber(node.personalAdoptions)} - - - - 团队: {formatNumber(node.teamAdoptions)} - - {node.directReferralCount > 0 && ( - 引荐: {formatNumber(node.directReferralCount)} + {/* 展开/收起按钮 */} + {hasChildren && ( +
- - {showExpandButton && hasChildren && ( - + {isLoading ? '...' : isExpanded ? '−' : '+'} + )} - - e.stopPropagation()} - > - 查看 -
- {/* 展开的子节点 */} + {/* 递归渲染子节点 */} {isExpanded && children.length > 0 && ( -
- {children.map((child) => ( - - ))} +
+
+
+ {children.map((child) => ( + + ))} +
)}