"use client"; import { FormEvent, useCallback, useEffect, useState } from "react"; import type { AuthUser, UserRole } from "../lib/user-auth"; type ManagedUser = { id: string; username: string; role: UserRole; created_at: string; updated_at: string; }; const ROLE_LABEL: Record = { super_admin: "超级管理员", admin: "管理员", user: "普通用户", }; async function userApi(response: Response) { const result = (await response.json()) as { users?: ManagedUser[]; error?: string }; if (!response.ok) throw new Error(result.error || "操作失败"); return result.users ?? []; } export default function UsersPage({ currentUser }: { currentUser: AuthUser }) { const [users, setUsers] = useState([]); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [role, setRole] = useState<"admin" | "user">("user"); const [resetTarget, setResetTarget] = useState(null); const [resetPassword, setResetPassword] = useState(""); const [message, setMessage] = useState(""); const [working, setWorking] = useState(false); const loadUsers = useCallback(async () => { try { setUsers(await userApi(await fetch("/api/users", { cache: "no-store" }))); } catch (reason) { setMessage(reason instanceof Error ? reason.message : "加载失败"); } }, []); useEffect(() => { const timer = window.setTimeout(() => { void loadUsers(); }, 0); return () => window.clearTimeout(timer); }, [loadUsers]); const createUser = async (event: FormEvent) => { event.preventDefault(); setWorking(true); setMessage(""); try { const next = await userApi( await fetch("/api/users", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "create", username, password, role }), }), ); setUsers(next); setUsername(""); setPassword(""); setRole("user"); setMessage("账号已创建,可以把账号和密码交给用户登录"); } catch (reason) { setMessage(reason instanceof Error ? reason.message : "创建失败"); } finally { setWorking(false); } }; const resetUserPassword = async (event: FormEvent) => { event.preventDefault(); if (!resetTarget) return; setWorking(true); setMessage(""); try { const next = await userApi( await fetch("/api/users", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "reset_password", userId: resetTarget.id, password: resetPassword, }), }), ); setUsers(next); setResetTarget(null); setResetPassword(""); setMessage("密码已重置,旧登录状态已退出"); } catch (reason) { setMessage(reason instanceof Error ? reason.message : "重置失败"); } finally { setWorking(false); } }; const canReset = (item: ManagedUser) => { if (currentUser.role === "super_admin") { return item.role !== "super_admin" || item.id === currentUser.id; } return item.role === "user"; }; return (

新增登录账号

账号密码由后台统一分配,不开放注册和个人改密。

{currentUser.role === "super_admin" && ( )}
{message &&

{message}

}

账号列表

共 {users.length} 个后台账号

登录账号角色更新时间操作
{users.map((item) => (
{item.username} {ROLE_LABEL[item.role]} {new Date(item.updated_at).toLocaleDateString("zh-CN", { timeZone: "Asia/Shanghai" })} {canReset(item) ? ( ) : }
))}
{resetTarget && (
setResetTarget(null)}>
event.stopPropagation()}>

后台改密

重置 {resetTarget.username} 的密码

)}
); }