'use client'; import { useState, useCallback } from 'react'; import Image from 'next/image'; import Link from 'next/link'; import { toast, Button } from '@/components/common'; import { PageContainer } from '@/components/layout'; import { cn } from '@/utils/helpers'; import { formatNumber, formatRanking } from '@/utils/formatters'; import { useUsers } from '@/hooks'; import type { UserListItem } from '@/services/userService'; import styles from './users.module.scss'; // 骨架屏组件 const TableRowSkeleton = () => (
{Array.from({ length: 13 }).map((_, i) => (
))}
); // 空数据提示 const EmptyData = ({ message }: { message: string }) => (
{message}
); // 错误提示 const ErrorMessage = ({ message, onRetry }: { message: string; onRetry?: () => void }) => (
{message} {onRetry && ( )}
); /** * 用户管理页面 * 接入 admin-service 真实 API */ export default function UsersPage() { const [keyword, setKeyword] = useState(''); const [showFilters, setShowFilters] = useState(false); const [selectedRows, setSelectedRows] = useState([]); // 用户状态/认种状态筛选 // 可选值: '' (全部) | 'ACTIVE' (正常) | 'FROZEN' (冻结) | 'adopted' (已认种) | 'not_adopted' (未认种) const [statusFilter, setStatusFilter] = useState(''); const [pagination, setPagination] = useState({ current: 1, pageSize: 10, }); // 根据 statusFilter 映射为 API 查询参数 // 'ACTIVE'/'FROZEN' → status 参数(后端 DTO 校验要求大写) // 'adopted' → minAdoptions: 1(personalAdoptionCount >= 1) // 'not_adopted' → maxAdoptions: 0(personalAdoptionCount = 0) const filterParams = (() => { switch (statusFilter) { case 'ACTIVE': case 'FROZEN': return { status: statusFilter }; case 'adopted': return { minAdoptions: 1 }; case 'not_adopted': return { maxAdoptions: 0 }; default: return {}; } })(); // 使用 React Query hooks 获取用户列表 const { data: usersData, isLoading, error, refetch, } = useUsers({ keyword: keyword || undefined, ...filterParams, page: pagination.current, pageSize: pagination.pageSize, sortBy: 'registeredAt', sortOrder: 'desc', }); const users = usersData?.items ?? []; const total = usersData?.total ?? 0; const totalPages = usersData?.totalPages ?? 1; // 全选处理 const handleSelectAll = useCallback((checked: boolean) => { if (checked) { setSelectedRows(users.map((user) => user.accountId)); } else { setSelectedRows([]); } }, [users]); // 单选处理 const handleSelectRow = useCallback((accountId: string, checked: boolean) => { if (checked) { setSelectedRows((prev) => [...prev, accountId]); } else { setSelectedRows((prev) => prev.filter((id) => id !== accountId)); } }, []); // 搜索处理 const handleSearch = useCallback((value: string) => { setKeyword(value); setPagination((prev) => ({ ...prev, current: 1 })); }, []); // 导出 Excel const handleExport = useCallback(() => { toast.success('导出功能开发中'); }, []); // 生成分页按钮 const renderPaginationButtons = () => { const buttons = []; const maxVisible = 5; // 首页按钮 buttons.push( ); // 上一页按钮 buttons.push( ); // 页码按钮 let startPage = Math.max(1, pagination.current - Math.floor(maxVisible / 2)); const endPage = Math.min(totalPages, startPage + maxVisible - 1); if (endPage - startPage < maxVisible - 1) { startPage = Math.max(1, endPage - maxVisible + 1); } if (startPage > 1) { buttons.push( ); if (startPage > 2) { buttons.push( ... ); } } for (let i = startPage; i <= endPage; i++) { buttons.push( ); } if (endPage < totalPages) { if (endPage < totalPages - 1) { buttons.push( ... ); } buttons.push( ); } // 下一页按钮 buttons.push( ); // 末页按钮 buttons.push( ); return buttons; }; // 获取状态显示 const getStatusClass = (user: UserListItem) => { if (user.isOnline) return 'online'; if (user.status === 'frozen') return 'busy'; return 'offline'; }; return (
{/* 页面标题和操作按钮 */}

用户管理

{/* 主内容卡片 */}
{/* 搜索和筛选区域 */}
{/* 搜索框 */}
搜索
handleSearch(e.target.value)} />
{/* 高级筛选面板 */}
setShowFilters(!showFilters)} > 高级筛选
展开
{showFilters && (
)}
{/* 表格区域 */}
{/* 表格头部 */}
0} onChange={(e) => handleSelectAll(e.target.checked)} />
账户序号
头像
昵称
手机号
账户认种量
团队总认种量
团队本省认种量及占比
团队本市认种量及占比
推荐人序列号
龙虎榜排名
操作
{/* 表格内容 */}
{isLoading ? ( // 加载状态显示骨架屏 Array.from({ length: pagination.pageSize }).map((_, i) => ( )) ) : error ? ( // 错误状态 - 显示详细错误信息 refetch()} /> ) : users.length === 0 ? ( // 空数据状态 - 明确告知暂无数据 ) : ( // 正常显示数据 users.map((user) => (
{/* 复选框 */}
handleSelectRow(user.accountId, e.target.checked)} />
{/* 账户序号 */}
{user.accountSequence || user.accountId}
{/* 头像 */}
{/* 昵称 */}
{user.nickname || '-'}
{/* 手机号 */}
{user.phoneNumberMasked || '-'}
{/* 账户认种量 */}
{formatNumber(user.personalAdoptions)}
{/* 团队总认种量 */}
{formatNumber(user.teamAdoptions)}
{/* 团队本省认种量及占比 */}
{formatNumber(user.provincialAdoptions.count)} ({user.provincialAdoptions.percentage}%)
{/* 团队本市认种量及占比 */}
{formatNumber(user.cityAdoptions.count)} ({user.cityAdoptions.percentage}%)
{/* 推荐人序列号 */}
{user.referrerId || '-'}
{/* 龙虎榜排名 */}
{user.ranking ? formatRanking(user.ranking) : '-'}
{/* 操作 */}
查看详情
)) )}
{/* 分页区域 */}
每页显示: {total} 条记录
{renderPaginationButtons()}
); }