feat(admin): Settings 分区 tab 化 + Dashboard 改待办驱动
- Settings(496 行五块内容单页)拆为 4 个 tab:数据源/LLM/定时任务/登录认证; tab 状态写入 URL(?tab=llm)可深链;数据加载与 API 调用不变 - Dashboard 改待办驱动:死信待处理/联赛数据缺口/可结算预测, 有待办才显示,每项直达处理页;全部清零时显示状态行 - 三步工作流卡仅在库里无比赛时显示(首次引导,老用户不再占版面) - 修文案漂移:「数据源健康」卡不再引用已不存在的「数据源」页; 「运行预测」链接语义修正(预测在前台比赛详情页发起) - 数据源单源硬编码列表简化为一行;未配 Key 直达设置分区 - <a href> 全改 <Link>,不再整页刷新
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
import { useEffect, useState, useCallback } from 'react'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import {
|
||||
fetchSettings, updateSetting, clearSetting,
|
||||
testLLMConnection, fetchLLMUsageStats, fetchLLMModels,
|
||||
@@ -26,7 +27,24 @@ import AgentLLMCard from '../AgentLLMCard'
|
||||
const DATA_SOURCE_KEYS = ['BZZOIRO_KEY', 'BZZOIRO_BASE']
|
||||
const LLM_KEYS = ['LLM_API_KEY', 'LLM_BASE_URL', 'LLM_MODEL']
|
||||
|
||||
/** 设置页分区(tab)。低频/高危操作靠后:安全放最后。 */
|
||||
const TABS = [
|
||||
{ id: 'datasource', label: '数据源' },
|
||||
{ id: 'llm', label: '大语言模型' },
|
||||
{ id: 'schedules', label: '定时任务' },
|
||||
{ id: 'security', label: '登录认证' },
|
||||
] as const
|
||||
|
||||
type TabId = (typeof TABS)[number]['id']
|
||||
|
||||
export default function SettingsPage() {
|
||||
// tab 状态写入 URL(?tab=llm),可深链直达、刷新保持
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
const rawTab = searchParams.get('tab')
|
||||
const tab: TabId = TABS.some(t => t.id === rawTab) ? (rawTab as TabId) : 'datasource'
|
||||
const setTab = (id: TabId) =>
|
||||
setSearchParams(id === 'datasource' ? {} : { tab: id }, { replace: true })
|
||||
|
||||
const [allSettings, setAllSettings] = useState<DataSourceSetting[]>([])
|
||||
const [settingsLoading, setSettingsLoading] = useState(true)
|
||||
const [editingKey, setEditingKey] = useState<string | null>(null)
|
||||
@@ -229,12 +247,31 @@ export default function SettingsPage() {
|
||||
<div className="space-y-8">
|
||||
<SectionHeader
|
||||
title="系统设置"
|
||||
description="数据源、LLM、认证等全部配置。保存到数据库并立即生效,优先于 .env。"
|
||||
description="数据源、LLM、定时任务与登录认证。保存到数据库并立即生效,优先于 .env。"
|
||||
/>
|
||||
|
||||
{/* ── 分区 tab(状态在 URL 上,可深链) ── */}
|
||||
<div className="-mt-4 flex gap-5 overflow-x-auto border-b border-ink-200" role="tablist" aria-label="设置分区">
|
||||
{TABS.map(t => (
|
||||
<button
|
||||
key={t.id}
|
||||
role="tab"
|
||||
aria-selected={tab === t.id}
|
||||
onClick={() => setTab(t.id)}
|
||||
className={`-mb-px flex-shrink-0 border-b-2 pb-2 text-sm transition-colors ${
|
||||
tab === t.id
|
||||
? 'border-press font-bold text-press'
|
||||
: 'border-transparent text-ink-500 hover:text-ink-900'
|
||||
}`}
|
||||
>
|
||||
{t.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* ── 1. 数据源 ── */}
|
||||
{tab === 'datasource' && (
|
||||
<section>
|
||||
<h2 className="section-head mb-3">数据源</h2>
|
||||
<div className="grid gap-6 lg:grid-cols-2">
|
||||
<Card>
|
||||
<CardHeader
|
||||
@@ -298,10 +335,11 @@ export default function SettingsPage() {
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* ── 2. LLM ── */}
|
||||
{tab === 'llm' && (
|
||||
<section>
|
||||
<h2 className="section-head mb-3">大语言模型</h2>
|
||||
<div className="grid gap-6 lg:grid-cols-2">
|
||||
<Card>
|
||||
<CardHeader
|
||||
@@ -372,10 +410,11 @@ export default function SettingsPage() {
|
||||
<AgentLLMCard />
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* ── 3. 认证 ── */}
|
||||
{tab === 'security' && (
|
||||
<section>
|
||||
<h2 className="section-head mb-3">登录认证</h2>
|
||||
<Card>
|
||||
<CardHeader title="修改密码" description="密码即会话签名密钥,修改后所有已登录会话失效,需重新登录" />
|
||||
<CardBody>
|
||||
@@ -413,10 +452,11 @@ export default function SettingsPage() {
|
||||
</CardBody>
|
||||
</Card>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* ── 4. 定时任务 ── */}
|
||||
{tab === 'schedules' && (
|
||||
<section>
|
||||
<h2 className="section-head mb-3">定时任务</h2>
|
||||
<Card>
|
||||
<CardHeader
|
||||
title="采集调度"
|
||||
@@ -491,6 +531,7 @@ export default function SettingsPage() {
|
||||
</CardBody>
|
||||
</Card>
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user