feat: 核心模块增强 — 加密 + 运行时配置 + 日志缓冲
- crypto.py: API Key 加密/解密工具 - runtime_config.py: 运行时动态配置管理 - log_buffer.py: 内存日志缓冲区 - config.py: 新增加密配置项 - http_client.py: 增强重试和错误处理
This commit is contained in:
@@ -7,7 +7,9 @@
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { NavLink, Outlet, useLocation } from 'react-router-dom'
|
||||
import { fetchAuthState, logout, UNAUTHORIZED_EVENT } from './api'
|
||||
import { fetchHealth } from './dal'
|
||||
import Login from './Login'
|
||||
|
||||
const NAV_ITEMS = [
|
||||
{ to: '/admin', label: '仪表盘', icon: '◇', end: true },
|
||||
@@ -18,6 +20,7 @@ const NAV_ITEMS = [
|
||||
{ to: '/admin/data-sources', label: '数据源', icon: '◫' },
|
||||
{ to: '/admin/llm-config', label: 'LLM 配置', icon: '◬' },
|
||||
{ to: '/admin/config', label: '系统配置', icon: '◑' },
|
||||
{ to: '/admin/logs', label: '系统日志', icon: '▤' },
|
||||
]
|
||||
|
||||
/** 报眉日期行,与前台同款式 */
|
||||
@@ -33,8 +36,32 @@ function dateLine(): string {
|
||||
export default function AdminLayout() {
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false)
|
||||
const [healthOk, setHealthOk] = useState<boolean | null>(null)
|
||||
const [authed, setAuthed] = useState<boolean | null>(null)
|
||||
const location = useLocation()
|
||||
|
||||
// 登录门禁:挂载时探测会话,收到 401 事件(会话过期)自动切回登录页
|
||||
useEffect(() => {
|
||||
let alive = true
|
||||
fetchAuthState()
|
||||
.then(s => alive && setAuthed(s.authenticated))
|
||||
.catch(() => alive && setAuthed(false))
|
||||
const onUnauthorized = () => setAuthed(false)
|
||||
window.addEventListener(UNAUTHORIZED_EVENT, onUnauthorized)
|
||||
return () => {
|
||||
alive = false
|
||||
window.removeEventListener(UNAUTHORIZED_EVENT, onUnauthorized)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleLogout = useCallback(async () => {
|
||||
try {
|
||||
await logout()
|
||||
} catch {
|
||||
/* 会话可能已失效,直接切回登录页 */
|
||||
}
|
||||
setAuthed(false)
|
||||
}, [])
|
||||
|
||||
const checkHealth = useCallback(async () => {
|
||||
try {
|
||||
const h = await fetchHealth()
|
||||
@@ -65,6 +92,18 @@ export default function AdminLayout() {
|
||||
return () => document.removeEventListener('keydown', handler)
|
||||
}, [])
|
||||
|
||||
// 登录门禁:未登录只渲染登录页,不泄露后台任何内容
|
||||
if (authed === null) {
|
||||
return (
|
||||
<div className="flex h-screen items-center justify-center bg-paper-50 text-xs text-ink-400">
|
||||
正在验证登录状态…
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (!authed) {
|
||||
return <Login onSuccess={() => setAuthed(true)} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex h-screen overflow-hidden bg-paper-50 text-ink-800">
|
||||
{/* ── 移动端遮罩层 ── */}
|
||||
@@ -177,6 +216,12 @@ export default function AdminLayout() {
|
||||
>
|
||||
前台
|
||||
</a>
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className="text-ink-500 transition-colors hover:text-press"
|
||||
>
|
||||
登出
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user