"use client"; import { useCallback, useEffect, useState } from "react"; import { useRouter } from "next/navigation"; import { useAuth } from "@/features/agent/hooks/useAuth"; import { ResponsiveLayout } from "@/components/layout"; import { fetchUsers, createUser, updateUser, deleteUser, updateUserPassword, type UserSummary, type CreateUserRequest, type UpdateUserRequest, type UpdatePasswordRequest, } from "@/features/agent/services/userApi"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Badge } from "@/components/ui/badge"; import { Card } from "@/components/ui/card"; import { Label } from "@/components/ui/label"; import { toast } from "@/hooks/useToast"; import { Plus, Edit, Trash2, Lock, Search, UserPlus, Save, X, } from "lucide-react"; export default function UsersPage(props: any = {}) { const { embedded = false } = props; const router = useRouter(); const { agent } = useAuth(); const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [searchQuery, setSearchQuery] = useState(""); const [createDialogOpen, setCreateDialogOpen] = useState(false); const [editDialogOpen, setEditDialogOpen] = useState(false); const [passwordDialogOpen, setPasswordDialogOpen] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [selectedUser, setSelectedUser] = useState(null); const [submitting, setSubmitting] = useState(false); // 创建用户表单 const [createForm, setCreateForm] = useState({ username: "", password: "", role: "agent", nickname: "", email: "", }); // 编辑用户表单 const [editForm, setEditForm] = useState({ role: "agent", nickname: "", email: "", receive_ai_conversations: true, }); // 修改密码表单 const [passwordForm, setPasswordForm] = useState({ old_password: "", new_password: "", }); // 检查权限 useEffect(() => { if (agent && agent.role !== "admin") { router.push("/agent/dashboard"); } }, [agent, router]); // 加载用户列表 const loadUsers = useCallback(async () => { if (!agent?.id) { return; } setLoading(true); try { const data = await fetchUsers(agent.id); setUsers(data); } catch (error) { console.error("加载用户列表失败:", error); toast.error((error as Error).message || "加载用户列表失败"); } finally { setLoading(false); } }, [agent?.id]); // 初始加载 useEffect(() => { loadUsers(); }, [loadUsers]); // 过滤用户列表 const filteredUsers = users.filter((user) => { if (!searchQuery.trim()) { return true; } const query = searchQuery.toLowerCase(); return ( user.username.toLowerCase().includes(query) || (user.nickname && user.nickname.toLowerCase().includes(query)) || (user.email && user.email.toLowerCase().includes(query)) ); }); // 打开创建对话框 const handleOpenCreate = () => { setCreateForm({ username: "", password: "", role: "agent", nickname: "", email: "", }); setCreateDialogOpen(true); }; // 创建用户 const handleCreate = async () => { if (!agent?.id) { return; } if (!createForm.username.trim() || !createForm.password.trim()) { toast.error("用户名和密码不能为空"); return; } setSubmitting(true); try { await createUser(createForm, agent.id); setCreateDialogOpen(false); await loadUsers(); toast.success("创建成功"); } catch (error) { toast.error((error as Error).message || "创建用户失败"); } finally { setSubmitting(false); } }; // 打开编辑对话框 const handleOpenEdit = (user: UserSummary) => { setSelectedUser(user); setEditForm({ role: user.role as "admin" | "agent", nickname: user.nickname || "", email: user.email || "", receive_ai_conversations: user.receive_ai_conversations, }); setEditDialogOpen(true); }; // 更新用户 const handleUpdate = async () => { if (!agent?.id || !selectedUser) { return; } setSubmitting(true); try { await updateUser(selectedUser.id, editForm, agent.id); setEditDialogOpen(false); setSelectedUser(null); await loadUsers(); toast.success("更新成功"); } catch (error) { toast.error((error as Error).message || "更新用户失败"); } finally { setSubmitting(false); } }; // 打开修改密码对话框 const handleOpenPassword = (user: UserSummary) => { setSelectedUser(user); setPasswordForm({ old_password: "", new_password: "", }); setPasswordDialogOpen(true); }; // 更新密码 const handleUpdatePassword = async () => { if (!agent?.id || !selectedUser) { return; } if (!passwordForm.new_password.trim()) { toast.error("新密码不能为空"); return; } // 如果修改的是当前用户,需要旧密码;如果是其他用户,不需要旧密码 const isCurrentUser = selectedUser.id === agent.id; if (isCurrentUser && !passwordForm.old_password?.trim()) { toast.error("修改自己的密码需要提供旧密码"); return; } setSubmitting(true); try { await updateUserPassword( selectedUser.id, isCurrentUser ? passwordForm : { new_password: passwordForm.new_password }, agent.id ); setPasswordDialogOpen(false); setSelectedUser(null); setPasswordForm({ old_password: "", new_password: "" }); toast.success("密码更新成功"); } catch (error) { toast.error((error as Error).message || "更新密码失败"); } finally { setSubmitting(false); } }; // 打开删除对话框 const handleOpenDelete = (user: UserSummary) => { setSelectedUser(user); setDeleteDialogOpen(true); }; // 删除用户 const handleDelete = async () => { if (!agent?.id || !selectedUser) { return; } setSubmitting(true); try { await deleteUser(selectedUser.id, agent.id); setDeleteDialogOpen(false); setSelectedUser(null); await loadUsers(); toast.success("删除成功"); } catch (error) { toast.error((error as Error).message || "删除用户失败"); } finally { setSubmitting(false); } }; // 格式化时间 const formatTime = (dateStr: string) => { const date = new Date(dateStr); return date.toLocaleString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", }); }; if (!agent || agent.role !== "admin") { return null; // 或者显示"权限不足"页面 } // 构建头部内容 const headerContent = (

用户管理

{!embedded && ( )}
{/* 搜索和操作栏 */}
setSearchQuery(e.target.value)} className="pl-10" />
); // 构建主内容区 const mainContent = (
{loading ? (
加载中...
) : filteredUsers.length === 0 ? (
{searchQuery ? "没有找到匹配的用户" : "暂无用户"}
) : (
{filteredUsers.map((user) => (
{user.nickname || user.username} {user.role === "admin" ? "管理员" : "客服"}
用户名: {user.username}
{user.email &&
邮箱: {user.email}
}
创建时间: {formatTime(user.created_at)}
))}
)}
); // 如果是嵌入模式,只返回内容,不包含 ResponsiveLayout if (embedded) { return ( <>
{headerContent} {mainContent}
{/* 对话框 */} {/* 创建用户对话框 */} 创建新用户
setCreateForm({ ...createForm, username: e.target.value }) } placeholder="请输入用户名" />
setCreateForm({ ...createForm, password: e.target.value }) } placeholder="请输入密码" />
setCreateForm({ ...createForm, nickname: e.target.value }) } placeholder="请输入昵称(可选)" />
setCreateForm({ ...createForm, email: e.target.value }) } placeholder="请输入邮箱(可选)" />
{/* 编辑用户对话框 */} 编辑用户 {selectedUser && (

用户名不能修改

setEditForm({ ...editForm, nickname: e.target.value }) } placeholder="请输入昵称" />
setEditForm({ ...editForm, email: e.target.value }) } placeholder="请输入邮箱" />
setEditForm({ ...editForm, receive_ai_conversations: e.target.checked, }) } className="w-4 h-4" />
)}
{/* 修改密码对话框 */} 修改密码 {selectedUser && (
{selectedUser.id === agent?.id && (
setPasswordForm({ ...passwordForm, old_password: e.target.value, }) } placeholder="请输入旧密码" />
)}
setPasswordForm({ ...passwordForm, new_password: e.target.value, }) } placeholder="请输入新密码" />
)}
{/* 删除确认对话框 */} 删除用户 {selectedUser && (

确定要删除用户 {selectedUser.username} 吗?

此操作不可恢复,请谨慎操作。

)}
); } return ( ); }