"use client" import { useState, useEffect, Suspense } from "react" import { Card, CardContent } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Button } from "@/components/ui/button" import { Label } from "@/components/ui/label" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { Badge } from "@/components/ui/badge" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog" import { Switch } from "@/components/ui/switch" import { Search, UserPlus, Trash2, Edit3, Key, Save, X, RefreshCw, Users, Eye } from "lucide-react" interface User { id: string open_id?: string | null phone?: string | null nickname: string password?: string | null wechat_id?: string | null avatar?: string | null is_admin?: boolean | number has_full_book?: boolean | number referral_code: string referred_by?: string | null earnings: number | string pending_earnings: number | string withdrawn_earnings?: number | string referral_count: number match_count_today?: number last_match_date?: string | null purchased_sections?: string[] | string | null created_at: string updated_at?: string | null } function UsersContent() { const [users, setUsers] = useState([]) const [searchTerm, setSearchTerm] = useState("") const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(null) const [showUserModal, setShowUserModal] = useState(false) const [showPasswordModal, setShowPasswordModal] = useState(false) const [editingUser, setEditingUser] = useState(null) const [newPassword, setNewPassword] = useState("") const [confirmPassword, setConfirmPassword] = useState("") const [isSaving, setIsSaving] = useState(false) // 绑定关系弹窗 const [showReferralsModal, setShowReferralsModal] = useState(false) const [referralsData, setReferralsData] = useState({ referrals: [], stats: {} }) const [referralsLoading, setReferralsLoading] = useState(false) const [selectedUserForReferrals, setSelectedUserForReferrals] = useState(null) // 初始表单状态 const [formData, setFormData] = useState({ phone: "", nickname: "", password: "", is_admin: false, has_full_book: false, }) // 加载用户列表 const loadUsers = async () => { setIsLoading(true) setError(null) try { const res = await fetch('/api/db/users') const data = await res.json() if (data.success) { setUsers(data.users || []) } else { setError(data.error || '加载失败') } } catch (err) { console.error('Load users error:', err) setError('网络错误,请检查连接') } finally { setIsLoading(false) } } useEffect(() => { loadUsers() }, []) const filteredUsers = users.filter((u) => u.nickname?.includes(searchTerm) || u.phone?.includes(searchTerm) ) // 删除用户 const handleDelete = async (userId: string) => { if (!confirm("确定要删除这个用户吗?")) return try { const res = await fetch(`/api/db/users?id=${userId}`, { method: 'DELETE' }) const data = await res.json() if (data.success) { loadUsers() } else { alert("删除失败: " + (data.error || "未知错误")) } } catch (error) { console.error('Delete user error:', error) alert("删除失败") } } // 打开编辑用户弹窗 const handleEditUser = (user: User) => { setEditingUser(user) setFormData({ phone: user.phone || "", nickname: user.nickname || "", password: "", is_admin: user.is_admin || false, has_full_book: user.has_full_book || false, }) setShowUserModal(true) } // 打开新建用户弹窗 const handleAddUser = () => { setEditingUser(null) setFormData({ phone: "", nickname: "", password: "", is_admin: false, has_full_book: false, }) setShowUserModal(true) } // 保存用户 const handleSaveUser = async () => { if (!formData.phone || !formData.nickname) { alert("请填写手机号和昵称") return } setIsSaving(true) try { if (editingUser) { // 更新用户 const res = await fetch('/api/db/users', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: editingUser.id, nickname: formData.nickname, is_admin: formData.is_admin, has_full_book: formData.has_full_book, ...(formData.password && { password: formData.password }), }) }) const data = await res.json() if (!data.success) { alert("更新失败: " + (data.error || "未知错误")) return } } else { // 创建用户 const res = await fetch('/api/db/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phone: formData.phone, nickname: formData.nickname, password: formData.password, is_admin: formData.is_admin, }) }) const data = await res.json() if (!data.success) { alert("创建失败: " + (data.error || "未知错误")) return } } setShowUserModal(false) loadUsers() } catch (error) { console.error('Save user error:', error) alert("保存失败") } finally { setIsSaving(false) } } // 打开修改密码弹窗 const handleChangePassword = (user: User) => { setEditingUser(user) setNewPassword("") setConfirmPassword("") setShowPasswordModal(true) } // 查看绑定关系 const handleViewReferrals = async (user: User) => { setSelectedUserForReferrals(user) setShowReferralsModal(true) setReferralsLoading(true) try { const res = await fetch(`/api/db/users/referrals?userId=${user.id}`) const data = await res.json() if (data.success) { setReferralsData(data) } else { setReferralsData({ referrals: [], stats: {} }) } } catch (err) { console.error('Load referrals error:', err) setReferralsData({ referrals: [], stats: {} }) } finally { setReferralsLoading(false) } } // 保存密码 const handleSavePassword = async () => { if (!newPassword) { alert("请输入新密码") return } if (newPassword !== confirmPassword) { alert("两次输入的密码不一致") return } if (newPassword.length < 6) { alert("密码长度不能少于6位") return } setIsSaving(true) try { const res = await fetch('/api/db/users', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: editingUser?.id, password: newPassword, }) }) const data = await res.json() if (data.success) { alert("密码修改成功") setShowPasswordModal(false) } else { alert("密码修改失败: " + (data.error || "未知错误")) } } catch (error) { console.error('Change password error:', error) alert("密码修改失败") } finally { setIsSaving(false) } } return (

用户管理

共 {users.length} 位注册用户

setSearchTerm(e.target.value)} />
{/* 用户编辑弹窗 */} {editingUser ? : } {editingUser ? "编辑用户" : "添加用户"}
setFormData({ ...formData, phone: e.target.value })} disabled={!!editingUser} />
setFormData({ ...formData, nickname: e.target.value })} />
setFormData({ ...formData, password: e.target.value })} />
setFormData({ ...formData, is_admin: checked })} />
setFormData({ ...formData, has_full_book: checked })} />
{/* 修改密码弹窗 */} 修改密码

用户:{editingUser?.nickname}

手机号:{editingUser?.phone}

setNewPassword(e.target.value)} />
setConfirmPassword(e.target.value)} />
{/* 绑定关系弹窗 */} 绑定关系详情 - {selectedUserForReferrals?.nickname}
{/* 统计信息 */}
{referralsData.stats?.total || 0}
绑定总数
{referralsData.stats?.purchased || 0}
已付费
¥{(referralsData.stats?.earnings || 0).toFixed(2)}
累计收益
¥{(referralsData.stats?.pendingEarnings || 0).toFixed(2)}
待提现
{/* 绑定用户列表 */} {referralsLoading ? (
加载中...
) : referralsData.referrals?.length > 0 ? (
{referralsData.referrals.map((ref: any) => (
{ref.nickname?.charAt(0) || "?"}
{ref.nickname}
{ref.phone || (ref.hasOpenId ? '微信用户' : '未绑定')}
{ref.status === 'vip' && ( 全书已购 )} {ref.status === 'paid' && ( 已付费{ref.purchasedSections}章 )} {ref.status === 'free' && ( 未付费 )} {ref.createdAt ? new Date(ref.createdAt).toLocaleDateString() : ''}
))}
) : (
暂无绑定用户
)}
{isLoading ? (
加载中...
) : ( 用户信息 绑定信息 购买状态 分销收益 推广码 注册时间 操作 {filteredUsers.map((user) => (
{user.avatar ? ( ) : ( user.nickname?.charAt(0) || "?" )}

{user.nickname}

{user.is_admin && ( 管理员 )} {user.open_id && !user.id?.startsWith('user_') && ( 微信 )}

{user.open_id ? user.open_id.slice(0, 12) + '...' : user.id?.slice(0, 12)}

{user.phone && (
📱 {user.phone}
)} {user.wechat_id && (
💬 {user.wechat_id}
)} {user.open_id && (
🔗 {user.open_id.slice(0, 12)}...
)} {!user.phone && !user.wechat_id && !user.open_id && ( 未绑定 )}
{user.has_full_book ? ( 全书已购 ) : ( 未购买 )}
¥{parseFloat(String(user.earnings || 0)).toFixed(2)}
{parseFloat(String(user.pending_earnings || 0)) > 0 && (
待提现: ¥{parseFloat(String(user.pending_earnings || 0)).toFixed(2)}
)}
handleViewReferrals(user)} > 绑定{user.referral_count || 0}人
{user.referral_code || '-'} {user.referred_by && (
来自: {user.referred_by.slice(0, 8)}
)}
{user.created_at ? new Date(user.created_at).toLocaleDateString() : "-"}
))} {filteredUsers.length === 0 && ( 暂无用户数据 )}
)}
) } export default function UsersPage() { return ( ) }