forked from gxwebsoft/mp-10550
- 新增 getNextUser函数用于切换当前用户并重新获取数据 - 优化 fetchTeamData 函数,支持根据 dealerId 或 dealerUser.userId 获取数据
195 lines
6.1 KiB
TypeScript
195 lines
6.1 KiB
TypeScript
import React, {useState, useEffect, useCallback} from 'react'
|
||
import {View, Text} from '@tarojs/components'
|
||
import {Space, Avatar, Loading} from '@nutui/nutui-react-taro'
|
||
import {User} from '@nutui/icons-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 type {ShopDealerUser} from "@/api/shop/shopDealerUser/model";
|
||
|
||
interface TeamMemberWithStats extends ShopDealerReferee {
|
||
name?: string
|
||
avatar?: string
|
||
orderCount?: number
|
||
commission?: string
|
||
status?: 'active' | 'inactive'
|
||
subMembers?: number
|
||
joinTime?: string
|
||
}
|
||
|
||
const DealerTeam: React.FC = () => {
|
||
const [teamMembers, setTeamMembers] = useState<TeamMemberWithStats[]>([])
|
||
const {dealerUser} = useDealerUser()
|
||
const [dealerId, setDealerId] = useState<number>()
|
||
|
||
// 获取团队数据
|
||
const fetchTeamData = useCallback(async () => {
|
||
if (!dealerUser?.userId && !dealerId) return
|
||
|
||
try {
|
||
console.log(dealerId, 'dealerId>>>>>>>>>')
|
||
// 获取团队成员关系
|
||
const refereeResult = await listShopDealerReferee({
|
||
dealerId: dealerId ? dealerId : dealerUser.userId
|
||
})
|
||
|
||
if (refereeResult) {
|
||
// 处理团队成员数据
|
||
const processedMembers: TeamMemberWithStats[] = refereeResult.map(member => ({
|
||
...member,
|
||
name: `用户${member.userId}`,
|
||
avatar: '',
|
||
orderCount: 0,
|
||
commission: '0.00',
|
||
status: 'active' as const,
|
||
subMembers: 0,
|
||
joinTime: member.createTime
|
||
}))
|
||
|
||
// 并行获取每个成员的订单统计
|
||
const memberStats = await Promise.all(
|
||
processedMembers.map(async (member) => {
|
||
try {
|
||
const orderResult = await pageShopDealerOrder({
|
||
page: 1,
|
||
limit: 100,
|
||
userId: member.userId
|
||
})
|
||
|
||
if (orderResult?.list) {
|
||
const orders = orderResult.list
|
||
const orderCount = orders.length
|
||
const 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
|
||
)
|
||
|
||
return {
|
||
...member,
|
||
orderCount,
|
||
commission,
|
||
status: hasRecentOrder ? 'active' as const : 'inactive' as const
|
||
}
|
||
}
|
||
return member
|
||
} catch (error) {
|
||
console.error(`获取成员${member.userId}订单失败:`, error)
|
||
return member
|
||
}
|
||
})
|
||
)
|
||
|
||
setTeamMembers(memberStats)
|
||
|
||
}
|
||
} catch (error) {
|
||
console.error('获取团队数据失败:', error)
|
||
Taro.showToast({
|
||
title: '获取团队数据失败',
|
||
icon: 'error'
|
||
})
|
||
}
|
||
}, [dealerUser?.userId])
|
||
|
||
const getNextUser = (item: ShopDealerUser) => {
|
||
setDealerId(item.userId)
|
||
fetchTeamData().then()
|
||
}
|
||
|
||
// 初始化加载数据
|
||
useEffect(() => {
|
||
if (dealerUser?.userId) {
|
||
fetchTeamData().then()
|
||
}
|
||
}, [fetchTeamData])
|
||
|
||
const renderMemberItem = (member: TeamMemberWithStats) => (
|
||
<View key={member.id} className="bg-white rounded-lg p-4 mb-3 shadow-sm" onClick={() => getNextUser(member)}>
|
||
<View className="flex items-center mb-3">
|
||
<Avatar
|
||
size="40"
|
||
src={member.avatar}
|
||
icon={<User/>}
|
||
className="mr-3"
|
||
/>
|
||
<View className="flex-1">
|
||
<View className="flex items-center mb-1">
|
||
<Text className="font-semibold text-gray-800 mr-2">
|
||
{member.name}
|
||
</Text>
|
||
{/*{getLevelIcon(Number(member.level))}*/}
|
||
{/*<Text className="text-xs text-gray-500 ml-1">*/}
|
||
{/* {member.level}级*/}
|
||
{/*</Text>*/}
|
||
</View>
|
||
<Text className="text-xs text-gray-500">
|
||
加入时间:{member.joinTime}
|
||
</Text>
|
||
</View>
|
||
{/*<View className="text-right">*/}
|
||
{/* <Tag*/}
|
||
{/* type={member.status === 'active' ? 'success' : 'default'}*/}
|
||
{/* >*/}
|
||
{/* {member.status === 'active' ? '活跃' : '沉默'}*/}
|
||
{/* </Tag>*/}
|
||
{/*</View>*/}
|
||
</View>
|
||
|
||
<View className="grid grid-cols-3 gap-4 text-center">
|
||
<Space>
|
||
<Text className="text-xs text-gray-500">订单数</Text>
|
||
<Text className="text-sm font-semibold text-blue-600">
|
||
{member.orderCount}
|
||
</Text>
|
||
</Space>
|
||
<Space>
|
||
<Text className="text-xs text-gray-500">贡献佣金</Text>
|
||
<Text className="text-sm font-semibold text-green-600">
|
||
¥{member.commission}
|
||
</Text>
|
||
</Space>
|
||
<Space>
|
||
<Text className="text-xs text-gray-500">团队成员</Text>
|
||
<Text className="text-sm font-semibold text-purple-600">
|
||
{member.subMembers}
|
||
</Text>
|
||
</Space>
|
||
</View>
|
||
</View>
|
||
)
|
||
|
||
const renderOverview = () => (
|
||
<View className="rounded-xl p-4">
|
||
{teamMembers.slice(0, 3).map(renderMemberItem)}
|
||
</View>
|
||
)
|
||
|
||
if (!dealerUser) {
|
||
return (
|
||
<View className="bg-gray-50 min-h-screen flex items-center justify-center">
|
||
<Loading/>
|
||
<Text className="text-gray-500 mt-2">加载中...</Text>
|
||
</View>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<View className="min-h-screen">
|
||
{renderOverview()}
|
||
</View>
|
||
)
|
||
}
|
||
|
||
export default DealerTeam
|