import { useState } from "react"; import { useLocation } from "wouter"; import { ArrowLeft, Search, Trash2 } from "lucide-react"; import { toast } from "sonner"; import { trpc } from "@/lib/trpc"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; const roleNames = { super_admin: "超级管理员", admin: "管理员", user: "普通用户" } as const; type Role = keyof typeof roleNames; export default function Users() { const [, setLocation] = useLocation(); const utils = trpc.useUtils(); const [search, setSearch] = useState(""); const [draftSearch, setDraftSearch] = useState(""); const [form, setForm] = useState({ username: "", temporaryPassword: "", name: "", email: "", role: "user" as Role }); const list = trpc.users.list.useQuery(search ? { search } : {}); const refresh = () => utils.users.list.invalidate(); const onError = (error: { message: string }) => toast.error(error.message); const create = trpc.users.create.useMutation({ onSuccess: () => { toast.success("用户已创建"); setForm({ username: "", temporaryPassword: "", name: "", email: "", role: "user" }); void refresh(); }, onError }); const update = trpc.users.update.useMutation({ onSuccess: () => { toast.success("用户信息已更新"); void refresh(); }, onError }); const setActive = trpc.users.setActive.useMutation({ onSuccess: () => { toast.success("账号状态已更新"); void refresh(); }, onError }); const resetPassword = trpc.users.resetPassword.useMutation({ onSuccess: () => toast.success("临时密码已重置,旧会话已失效"), onError }); const remove = trpc.users.delete.useMutation({ onSuccess: () => { toast.success("用户已永久删除"); void refresh(); }, onError }); return (

用户管理

创建账号、分配角色并管理登录状态

新建用户

{ event.preventDefault(); create.mutate(form); }}>
setForm(v => ({ ...v, username: e.target.value }))} minLength={3} required />
setForm(v => ({ ...v, name: e.target.value }))} required />
setForm(v => ({ ...v, email: e.target.value }))} />
setForm(v => ({ ...v, temporaryPassword: e.target.value }))} required />
{ event.preventDefault(); setSearch(draftSearch.trim()); }}> setDraftSearch(e.target.value)} />
{list.data?.map(user => ( ))}
用户角色状态首次改密最后登录操作
{user.name || "未命名"}
{user.username}{user.email ? ` · ${user.email}` : ""}
{user.mustChangePassword === 1 ? "是" : "否"} {user.lastLoginAt ? new Date(user.lastLoginAt).toLocaleString() : "从未登录"}
{list.isLoading &&

正在加载…

} {list.error &&

{list.error.message}

}
); }