私域操盘手 - 修复流量池页面不会自动加载状态列表选择器的问题

This commit is contained in:
柳清爽
2025-05-13 14:43:21 +08:00
parent 957d197245
commit 55ea2bf7e3
4 changed files with 66 additions and 72 deletions

View File

@@ -37,7 +37,7 @@ interface TrafficUser {
phone: string
region: string
note: string
status: "pending" | "added" | "failed"
status: number
addTime: string
source: string
assignedTo: string
@@ -48,6 +48,7 @@ interface TrafficUser {
interface StatusType {
id: number
name: string
code: string
}
interface ApiResponse<T> {
@@ -144,37 +145,43 @@ export default function TrafficPoolPage() {
const params = new URLSearchParams({
page: page.toString(),
limit: "30", // 设置每页显示30条
limit: "30",
search: debouncedSearchQuery,
category: activeCategory,
source: sourceFilter !== "all" ? sourceFilter : "",
status: statusFilter === "all" ? "" : statusFilter,
})
// 检查是否有来源参数
const sourceParam = searchParams?.get("source")
if (sourceParam) {
params.append("wechatSource", sourceParam)
}
const response = await api.get<ApiResponse<TrafficPoolResponse>>(`/v1/traffic/pool?${params.toString()}`)
const response = await api.get<ApiResponse<TrafficPoolResponse>>(`/v1/traffic/pool?${params.toString()}`, {
headers: {
Authorization: `Bearer ${localStorage.getItem('token')}`
}
} as any)
if (response.code === 200) {
const { list, pagination, statistics } = response.data
// 转换数据格式
const transformedUsers = list.map(user => ({
...user,
id: user.id.toString(),
status: getStatusFromCode(user.status),
tags: user.tags || [],
category: user.category || "potential",
avatar: user.avatar,
nickname: user.name || user.nickname || '未知用户',
wechatId: user.wechatId,
phone: user.phone,
region: user.region,
note: user.note,
status: user.status,
addTime: formatDateTime(user.createTime),
source: user.fromd || '未知来源',
nickname: user.name || user.nickname || '未知用户'
assignedTo: user.assignedTo,
category: user.category || "potential",
tags: user.tags || []
}))
// 更新用户列表
setUsers(prev => isNewSearch ? transformedUsers : [...prev, ...transformedUsers])
setCurrentPage(page)
setHasMore(list.length > 0 && page < pagination.totalPages)
@@ -207,7 +214,11 @@ export default function TrafficPoolPage() {
const fetchStatusTypes = useCallback(async () => {
try {
const response = await api.get<ApiResponse<StatusType[]>>('/v1/traffic/pool/types')
const response = await api.get<ApiResponse<StatusType[]>>('/v1/traffic/pool/types', {
headers: {
Authorization: `Bearer ${localStorage.getItem('token')}`
}
} as any)
if (response.code === 200) {
setStatusTypes(response.data)
@@ -236,9 +247,9 @@ export default function TrafficPoolPage() {
fetchUsers(1, true)
}, [fetchUsers])
// 设置 IntersectionObserver
// 初始化 IntersectionObserver
useEffect(() => {
observerRef.current = new IntersectionObserver(
const observer = new IntersectionObserver(
(entries) => {
if (entries[0].isIntersecting && hasMore && !isFetching) {
fetchUsers(currentPage + 1)
@@ -247,35 +258,30 @@ export default function TrafficPoolPage() {
{ threshold: 0.5 }
)
return () => {
if (observerRef.current) {
observerRef.current.disconnect()
}
}
}, [fetchUsers, currentPage, hasMore, isFetching])
// 观察加载指示器
useEffect(() => {
if (loadingRef.current && observerRef.current) {
observerRef.current.observe(loadingRef.current)
if (loadingRef.current) {
observer.observe(loadingRef.current)
}
return () => {
if (loadingRef.current && observerRef.current) {
observerRef.current.unobserve(loadingRef.current)
if (loadingRef.current) {
observer.unobserve(loadingRef.current)
}
}
}, [loadingRef.current, observerRef.current])
}, [hasMore, isFetching, currentPage, fetchUsers])
// 初始加载
// 初始化数据
useEffect(() => {
fetchStatusTypes()
fetchUsers(1, true)
return () => {
if (abortControllerRef.current) {
abortControllerRef.current.abort()
}
}
}, [fetchUsers])
}, [])
// 监听筛选条件变化
useEffect(() => {
setUsers([])
setCurrentPage(1)
setHasMore(true)
fetchUsers(1, true)
}, [activeCategory, sourceFilter, statusFilter, debouncedSearchQuery])
const handleUserClick = (user: TrafficUser) => {
setSelectedUser(user)
@@ -283,16 +289,8 @@ export default function TrafficPoolPage() {
}
// 添加状态码转换函数
const getStatusFromCode = (statusCode: number): "pending" | "added" | "failed" => {
const statusMap: Record<number, "pending" | "added" | "failed"> = {
1: "pending", // 待处理
2: "pending", // 处理中
3: "added", // 已添加
4: "failed", // 已拒绝
5: "failed", // 已过期
6: "failed", // 已取消
}
return statusMap[statusCode] || "pending"
const getStatusFromCode = (statusCode: number): number => {
return statusCode;
}
return (
@@ -431,14 +429,14 @@ export default function TrafficPoolPage() {
<div className="font-medium truncate">{user.nickname}</div>
<div
className={`text-xs px-2 py-1 rounded-full ${
user.status === "added"
user.status === 2
? "bg-green-100 text-green-800"
: user.status === "pending"
: user.status === 1
? "bg-yellow-100 text-yellow-800"
: "bg-red-100 text-red-800"
}`}
>
{user.status === "added" ? "已添加" : user.status === "pending" ? "待处理" : "已失败"}
{user.status === 2 ? "已添加" : user.status === 1 ? "待处理" : "已失败"}
</div>
</div>
<div className="text-sm text-gray-500">: {user.wechatId}</div>
@@ -463,19 +461,19 @@ export default function TrafficPoolPage() {
</Card>
))}
{/* 加载更多指示器 */}
{hasMore && (
<div ref={loadingRef} className="py-4 flex justify-center">
{isFetching && <RefreshCw className="h-6 w-6 animate-spin text-blue-500" />}
</div>
)}
{/* 显示加载状态和总数 */}
<div className="text-sm text-gray-500 text-center">
{stats.total > 0 && (
<span>
{users.length} / {stats.total}
</span>
{/* 加载状态显示 */}
<div ref={loadingRef} className="flex justify-center py-4">
{isFetching && (
<div className="flex items-center space-x-2">
<div className="w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin"></div>
<span className="text-gray-600">...</span>
</div>
)}
{!hasMore && users.length > 0 && (
<span className="text-gray-500"></span>
)}
{!isFetching && users.length === 0 && (
<span className="text-gray-500"></span>
)}
</div>
</>
@@ -502,18 +500,14 @@ export default function TrafficPoolPage() {
<div className="text-sm text-gray-500">{selectedUser.wechatId}</div>
<Badge
className={`mt-1 ${
selectedUser.status === "added"
selectedUser.status === 2
? "bg-green-100 text-green-800"
: selectedUser.status === "pending"
: selectedUser.status === 1
? "bg-yellow-100 text-yellow-800"
: "bg-red-100 text-red-800"
}`}
>
{selectedUser.status === "added"
? "已添加"
: selectedUser.status === "pending"
? "待处理"
: "已失败"}
{selectedUser.status === 2 ? "已添加" : selectedUser.status === 1 ? "待处理" : "已失败"}
</Badge>
</div>
</div>