import React, {useState, useEffect, useCallback} from 'react' import {View, Text} from '@tarojs/components' import {Phone, Edit, Message} from '@nutui/icons-react-taro' import {Space, Empty, Avatar, Button} from '@nutui/nutui-react-taro' import Taro from '@tarojs/taro' import {useDealerUser} from '@/hooks/useDealerUser' import {listShopDealerReferee} from '@/api/shop/shopDealerReferee' import {pageShopDealerOrder} from '@/api/shop/shopDealerOrder' import type {ShopDealerReferee} from '@/api/shop/shopDealerReferee/model' import FixedButton from "@/components/FixedButton"; import navTo from "@/utils/common"; import {updateUser} from "@/api/system/user"; interface TeamMemberWithStats extends ShopDealerReferee { name?: string avatar?: string nickname?: string; alias?: string; phone?: string; orderCount?: number commission?: string status?: 'active' | 'inactive' subMembers?: number joinTime?: string dealerAvatar?: string; dealerName?: string; dealerPhone?: string; } // 层级信息接口 interface LevelInfo { dealerId: number dealerName?: string level: number } const DealerTeam: React.FC = () => { const [teamMembers, setTeamMembers] = useState([]) const {dealerUser} = useDealerUser() const [dealerId, setDealerId] = useState() // 层级栈,用于支持返回上一层 const [levelStack, setLevelStack] = useState([]) const [loading, setLoading] = useState(false) // 当前查看的用户名称 const [currentDealerName, setCurrentDealerName] = useState('') // 异步加载成员统计数据 const loadMemberStats = async (members: TeamMemberWithStats[]) => { // 分批处理,避免过多并发请求 const batchSize = 3 for (let i = 0; i < members.length; i += batchSize) { const batch = members.slice(i, i + batchSize) const batchStats = await Promise.all( batch.map(async (member) => { try { // 并行获取订单统计和下级成员数量 const [orderResult, subMembersResult] = await Promise.all([ pageShopDealerOrder({ page: 1, userId: member.userId }), listShopDealerReferee({ dealerId: member.userId, deleted: 0 }) ]) let orderCount = 0 let commission = '0.00' let status: 'active' | 'inactive' = 'inactive' if (orderResult?.list) { const orders = orderResult.list orderCount = orders.length commission = orders.reduce((sum, order) => { const levelCommission = member.level === 1 ? order.firstMoney : member.level === 2 ? order.secondMoney : order.thirdMoney return sum + parseFloat(levelCommission || '0') }, 0).toFixed(2) // 判断活跃状态(30天内有订单为活跃) const thirtyDaysAgo = new Date() thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30) const hasRecentOrder = orders.some(order => new Date(order.createTime || '') > thirtyDaysAgo ) status = hasRecentOrder ? 'active' : 'inactive' } return { ...member, orderCount, commission, status, subMembers: subMembersResult?.length || 0 } } catch (error) { console.error(`获取成员${member.userId}数据失败:`, error) return { ...member, orderCount: 0, commission: '0.00', status: 'inactive' as const, subMembers: 0 } } }) ) // 更新这一批成员的数据 setTeamMembers(prevMembers => { const updatedMembers = [...prevMembers] batchStats.forEach(updatedMember => { const index = updatedMembers.findIndex(m => m.userId === updatedMember.userId) if (index !== -1) { updatedMembers[index] = updatedMember } }) return updatedMembers }) // 添加小延迟,避免请求过于密集 if (i + batchSize < members.length) { await new Promise(resolve => setTimeout(resolve, 100)) } } } // 获取团队数据 const fetchTeamData = useCallback(async () => { if (!dealerUser?.userId && !dealerId) return try { setLoading(true) console.log(dealerId, 'dealerId>>>>>>>>>') // 获取团队成员关系 const refereeResult = await listShopDealerReferee({ dealerId: dealerId ? dealerId : dealerUser?.userId }) if (refereeResult) { console.log('团队成员原始数据:', refereeResult) // 处理团队成员数据 const processedMembers: TeamMemberWithStats[] = refereeResult.map(member => ({ ...member, name: `${member.userId}`, orderCount: 0, commission: '0.00', status: 'active' as const, subMembers: 0, joinTime: member.createTime })) // 先显示基础数据,然后异步加载详细统计 setTeamMembers(processedMembers) setLoading(false) // 异步加载每个成员的详细统计数据 loadMemberStats(processedMembers) } } catch (error) { console.error('获取团队数据失败:', error) Taro.showToast({ title: '获取团队数据失败', icon: 'error' }) } finally { setLoading(false) } }, [dealerUser?.userId, dealerId]) // 查看下级成员 const getNextUser = (item: TeamMemberWithStats) => { // 检查层级限制:最多只能查看2层(levelStack.length >= 1 表示已经是第2层了) if (levelStack.length >= 1) { return } // 如果没有下级成员,不允许点击 if (!item.subMembers || item.subMembers === 0) { return } console.log('点击用户:', item.userId, item.name) // 将当前层级信息推入栈中 const currentLevel: LevelInfo = { dealerId: dealerId || dealerUser?.userId || 0, dealerName: currentDealerName || (dealerId ? '上级' : dealerUser?.realName || '我'), level: levelStack.length } setLevelStack(prev => [...prev, currentLevel]) // 切换到下级 setDealerId(item.userId) setCurrentDealerName(item.nickname || item.dealerName || `用户${item.userId}`) } // 返回上一层 const goBack = () => { if (levelStack.length === 0) { // 如果栈为空,返回首页或上一页 Taro.navigateBack() return } // 从栈中弹出上一层信息 const prevLevel = levelStack[levelStack.length - 1] setLevelStack(prev => prev.slice(0, -1)) if (prevLevel.dealerId === (dealerUser?.userId || 0)) { // 返回到根层级 setDealerId(undefined) setCurrentDealerName('') } else { setDealerId(prevLevel.dealerId) setCurrentDealerName(prevLevel.dealerName || '') } } // 一键拨打 const makePhoneCall = (phone: string) => { Taro.makePhoneCall({ phoneNumber: phone, fail: () => { Taro.showToast({ title: '拨打取消', icon: 'error' }); } }); }; // 别名备注 const editAlias = (item: any, index: number) => { Taro.showModal({ title: '备注', // @ts-ignore editable: true, placeholderText: '真实姓名', content: item.alias || '', success: async (res: any) => { if (res.confirm && res.content !== undefined) { try { // 更新跟进情况 await updateUser({ userId: item.userId, alias: res.content.trim() }); teamMembers[index].alias = res.content.trim() setTeamMembers(teamMembers) } catch (error) { console.error('备注失败:', error); Taro.showToast({ title: '备注失败,请重试', icon: 'error' }); } } } }); }; // 发送消息 const sendMessage = (item: TeamMemberWithStats) => { return navTo(`/user/chat/message/add?id=${item.userId}`, true) } // 监听数据变化,获取团队数据 useEffect(() => { if (dealerUser?.userId || dealerId) { fetchTeamData().then() } }, [fetchTeamData]) // 初始化当前用户名称 useEffect(() => { if (!dealerId && dealerUser?.realName && !currentDealerName) { setCurrentDealerName(dealerUser.realName) } }, [dealerUser, dealerId, currentDealerName]) const renderMemberItem = (member: TeamMemberWithStats, index: number) => { // 判断是否可以点击:有下级成员且未达到层级限制 const canClick = member.subMembers && member.subMembers > 0 && levelStack.length < 1 // 判断是否显示手机号:只有本级(levelStack.length === 0)才显示 const showPhone = levelStack.length === 0 // 判断数据是否还在加载中(初始值都是0或'0.00') const isStatsLoading = member.orderCount === 0 && member.commission === '0.00' && member.subMembers === 0 return ( getNextUser(member)} > {member.alias ? {member.alias} : {member.nickname}} {/*别名备注*/} { e.stopPropagation() editAlias(member, index) }}/> {/*发送消息*/} { e.stopPropagation() sendMessage(member) }}/> {/* 显示手机号(仅本级可见) */} {showPhone && member.phone && ( { e.stopPropagation(); makePhoneCall(member.phone || ''); }}> {member.phone} )} UID:{member.userId} 加入时间:{member.joinTime} 订单数 {isStatsLoading ? '-' : member.orderCount} 贡献佣金 {isStatsLoading ? '-' : `¥${member.commission}`} 团队成员 {isStatsLoading ? '-' : (member.subMembers || 0)} ) } const renderOverview = () => ( 我的团队成员 成员数:{teamMembers.length} {teamMembers.map(renderMemberItem)} ) // 渲染顶部导航栏 const renderHeader = () => { if (levelStack.length === 0) return null return ( {currentDealerName}的团队成员 ) } if (!dealerUser) { return ( navTo(`/dealer/apply/add`, true)}]} /> ) } return ( <> {renderHeader()} {loading ? ( 加载中... ) : teamMembers.length > 0 ? ( renderOverview() ) : ( )} navTo(`/dealer/qrcode/index`, true)}/> ) } export default DealerTeam;