'use client' import { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' import { KeyRound, Shield, Terminal } from 'lucide-react' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Badge } from '@/components/ui/badge' import { AdminUnauthorizedError, API_BASE, adminFetchJson, clearAdminToken } from '@/lib/admin-api' export default function SettingsPage() { const router = useRouter() const [username, setUsername] = useState('') const [tokenExp, setTokenExp] = useState(null) const [healthOk, setHealthOk] = useState(null) const [oldPassword, setOldPassword] = useState('') const [newPassword, setNewPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') const [isSaving, setIsSaving] = useState(false) const [error, setError] = useState('') const [success, setSuccess] = useState('') const fetchMe = async () => { setError('') try { const data = await adminFetchJson<{ username?: string; exp?: number }>('/api/v1/admin/me') setUsername(data.username || '') setTokenExp(typeof data.exp === 'number' ? data.exp : null) } catch (err: any) { if (err instanceof AdminUnauthorizedError) { router.replace('/login') return } setError(err?.message || '加载失败') } } const fetchHealth = async () => { try { const res = await fetch(`${API_BASE}/health`) setHealthOk(res.ok) } catch { setHealthOk(false) } } useEffect(() => { fetchMe() fetchHealth() // eslint-disable-next-line react-hooks/exhaustive-deps }, []) const handleChangePassword = async (e: React.FormEvent) => { e.preventDefault() setError('') setSuccess('') if (!oldPassword.trim() || !newPassword.trim()) { setError('请输入原密码和新密码') return } if (newPassword.trim().length < 8) { setError('新密码至少 8 位') return } if (newPassword !== confirmPassword) { setError('两次输入的新密码不一致') return } setIsSaving(true) try { await adminFetchJson('/api/v1/admin/change-password', { method: 'POST', body: JSON.stringify({ old_password: oldPassword, new_password: newPassword, }), }) setSuccess('密码已更新,请重新登录') clearAdminToken() router.replace('/login') } catch (err: any) { if (err instanceof AdminUnauthorizedError) { router.replace('/login') return } setError(err?.message || '更新失败') } finally { setIsSaving(false) } } const expText = tokenExp ? new Date(tokenExp * 1000).toLocaleString() : '未知' return (

设置

账号安全与系统信息

{(error || success) && (
{success || error}
)}
账号安全 查看登录信息并更新管理员密码
当前用户
{username || '—'}
{username && 管理员}
Token 过期时间:{expText}
setOldPassword(e.target.value)} autoComplete="current-password" />
setNewPassword(e.target.value)} autoComplete="new-password" />
至少 8 位
setConfirmPassword(e.target.value)} autoComplete="new-password" />
系统信息 当前 API Base 与健康检查
API Base URL
{API_BASE}
API 健康
{healthOk === null ? ( 未知 ) : healthOk ? ( OK ) : ( 异常 )}
若健康检查异常,请确认后端服务可访问,并检查数据库/Redis 配置。
) }