import React, { useEffect, useState } from 'react'; import { Button, Card, Form, Input, InputNumber, message, Modal, Popconfirm, Space, Switch, Table, Tag, Typography, } from 'antd'; import { UserOutlined, WalletOutlined, SearchOutlined, StopOutlined, CheckCircleOutlined, } from '@ant-design/icons'; import { getAdminUsers, adjustCredits, toggleUserStatus } from '../../api'; import type { AdminUser } from '../../types'; const AdminUsers: React.FC = () => { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [search, setSearch] = useState(''); const [creditModal, setCreditModal] = useState<{ open: boolean; user: AdminUser | null }>({ open: false, user: null }); const [form] = Form.useForm(); const load = async () => { setLoading(true); const data = await getAdminUsers(search || undefined); setUsers(data); setLoading(false); }; useEffect(() => { load(); }, []); const handleSearch = () => load(); const handleAdjustCredits = async () => { try { const values = await form.validateFields(); const { user } = creditModal; if (!user) return; await adjustCredits(user.id, values.amount, values.reason); message.success(`已${values.amount > 0 ? '增加' : '扣除'} ${Math.abs(values.amount)} 积分`); setCreditModal({ open: false, user: null }); form.resetFields(); load(); } catch { /* validation */ } }; const handleToggleStatus = async (user: AdminUser) => { await toggleUserStatus(user.id, !user.isActive); message.success(user.isActive ? '已禁用该用户' : '已启用该用户'); load(); }; const columns = [ { title: '用户', key: 'user', width: 200, render: (_: any, r: AdminUser) => (
{r.username.charAt(0).toUpperCase()}
{r.username} {r.isAdmin && 管理员}
{r.email}
), }, { title: '积分余额', dataIndex: 'credits', width: 120, sorter: (a: AdminUser, b: AdminUser) => a.credits - b.credits, render: (v: number) => ( 0 ? '#10b981' : '#ef4444', fontSize: 15 }}> {v.toLocaleString()} ), }, { title: '手机号', dataIndex: 'phone', width: 130, render: (v: string) => {v || '-'}, }, { title: '状态', dataIndex: 'isActive', width: 80, render: (v: boolean) => ( {v ? '正常' : '禁用'} ), }, { title: '注册时间', dataIndex: 'createdAt', width: 120, render: (v: string) => {v}, }, { title: '最后登录', dataIndex: 'lastLoginAt', width: 140, render: (v: string) => {v || '-'}, }, { title: '操作', key: 'action', width: 200, fixed: 'right' as const, render: (_: any, r: AdminUser) => ( {!r.isAdmin && ( handleToggleStatus(r)} > )} ), }, ]; return (
{/* Search bar */}
} value={search} onChange={e => setSearch(e.target.value)} onPressEnter={handleSearch} style={{ width: 280, borderRadius: 8 }} allowClear />
`共 ${t} 个用户` }} scroll={{ x: 900 }} /> {/* Adjust Credits Modal */} 调整积分 - {creditModal.user?.username}} open={creditModal.open} onOk={handleAdjustCredits} onCancel={() => { setCreditModal({ open: false, user: null }); form.resetFields(); }} okText="确认" cancelText="取消" width={440} >
当前积分: {creditModal.user?.credits.toLocaleString()}
`${v}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} />
); }; export default AdminUsers;