AI 设置独立为单独页面 /settings/ai
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -47,7 +47,7 @@ const nav = [
|
|||||||
function AIConfigBadge({ configured, model }: { configured?: boolean; model?: string }) {
|
function AIConfigBadge({ configured, model }: { configured?: boolean; model?: string }) {
|
||||||
return (
|
return (
|
||||||
<NavLink
|
<NavLink
|
||||||
to="/settings?tab=ai"
|
to="/settings/ai"
|
||||||
className="mt-2 group block -mx-2.5"
|
className="mt-2 group block -mx-2.5"
|
||||||
title="AI 配置"
|
title="AI 配置"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ export function AiAnalysisDialog({ task, mode, minimized }: Props) {
|
|||||||
<div className="text-sm font-medium text-foreground">分析失败</div>
|
<div className="text-sm font-medium text-foreground">分析失败</div>
|
||||||
<div className="text-xs text-secondary text-center max-w-md px-4">{error}</div>
|
<div className="text-xs text-secondary text-center max-w-md px-4">{error}</div>
|
||||||
{error.includes('AI') && (
|
{error.includes('AI') && (
|
||||||
<button onClick={() => { window.location.href = '/settings?tab=ai' }}
|
<button onClick={() => { window.location.href = '/settings/ai' }}
|
||||||
className="mt-1 inline-flex items-center gap-1.5 h-8 px-3 rounded-lg bg-elevated border border-border text-xs text-secondary hover:text-foreground transition-colors">
|
className="mt-1 inline-flex items-center gap-1.5 h-8 px-3 rounded-lg bg-elevated border border-border text-xs text-secondary hover:text-foreground transition-colors">
|
||||||
<Settings2 className="h-3.5 w-3.5" /> 去配置 AI
|
<Settings2 className="h-3.5 w-3.5" /> 去配置 AI
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ export function StrategyBuilderDialog({ open, onClose, onSavedId, mode = 'create
|
|||||||
<div className="rounded-xl border border-amber-400/30 bg-amber-400/5 px-4 py-3 flex items-center gap-3">
|
<div className="rounded-xl border border-amber-400/30 bg-amber-400/5 px-4 py-3 flex items-center gap-3">
|
||||||
<AlertTriangle className="h-4 w-4 text-amber-400 shrink-0" />
|
<AlertTriangle className="h-4 w-4 text-amber-400 shrink-0" />
|
||||||
<div className="flex-1 text-xs text-amber-400/80">AI API Key 未配置,无法生成策略。填写的内容会自动保存。</div>
|
<div className="flex-1 text-xs text-amber-400/80">AI API Key 未配置,无法生成策略。填写的内容会自动保存。</div>
|
||||||
<button onClick={() => { persist(); window.location.href = '/settings?tab=ai' }}
|
<button onClick={() => { persist(); window.location.href = '/settings/ai' }}
|
||||||
className="h-7 px-3 rounded-lg bg-amber-400/15 border border-amber-400/30 text-amber-400 text-xs font-medium flex items-center gap-1.5 hover:bg-amber-400/20 shrink-0">
|
className="h-7 px-3 rounded-lg bg-amber-400/15 border border-amber-400/30 text-amber-400 text-xs font-medium flex items-center gap-1.5 hover:bg-amber-400/20 shrink-0">
|
||||||
<Settings2 className="h-3 w-3" />去配置
|
<Settings2 className="h-3 w-3" />去配置
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ export function StockAnalysisDialog({ task, mode, minimized }: Props) {
|
|||||||
<div className="text-sm font-medium text-foreground">分析失败</div>
|
<div className="text-sm font-medium text-foreground">分析失败</div>
|
||||||
<div className="text-xs text-secondary text-center max-w-md px-4">{error}</div>
|
<div className="text-xs text-secondary text-center max-w-md px-4">{error}</div>
|
||||||
{error.includes('AI') && (
|
{error.includes('AI') && (
|
||||||
<button onClick={() => { window.location.href = '/settings?tab=ai' }}
|
<button onClick={() => { window.location.href = '/settings/ai' }}
|
||||||
className="mt-1 inline-flex items-center gap-1.5 h-8 px-3 rounded-lg bg-elevated border border-border text-xs text-secondary hover:text-foreground transition-colors">
|
className="mt-1 inline-flex items-center gap-1.5 h-8 px-3 rounded-lg bg-elevated border border-border text-xs text-secondary hover:text-foreground transition-colors">
|
||||||
<Settings2 className="h-3.5 w-3.5" /> 去配置 AI
|
<Settings2 className="h-3.5 w-3.5" /> 去配置 AI
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { PageHeader } from '@/components/PageHeader'
|
||||||
|
import { SettingsAIPanel } from './settings/AI'
|
||||||
|
|
||||||
|
export function AiSettings() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageHeader title="AI 设置" subtitle="管理 AI 提供商连接与模型配置" />
|
||||||
|
<div className="px-8 py-6">
|
||||||
|
<SettingsAIPanel />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ import { StockAnalysis } from './pages/StockAnalysis'
|
|||||||
import { Review } from './pages/Review'
|
import { Review } from './pages/Review'
|
||||||
import { LimitUpLadder } from './pages/LimitUpLadder'
|
import { LimitUpLadder } from './pages/LimitUpLadder'
|
||||||
import { Branding } from './pages/Branding'
|
import { Branding } from './pages/Branding'
|
||||||
|
import { AiSettings } from './pages/AiSettings'
|
||||||
import { Settings } from './pages/Settings'
|
import { Settings } from './pages/Settings'
|
||||||
import { Indices } from './pages/Indices'
|
import { Indices } from './pages/Indices'
|
||||||
import { Dev } from './pages/Dev'
|
import { Dev } from './pages/Dev'
|
||||||
@@ -79,7 +80,7 @@ export const router = createBrowserRouter([
|
|||||||
{ path: 'dev', element: <Dev /> },
|
{ path: 'dev', element: <Dev /> },
|
||||||
// 旧路由兼容重定向
|
// 旧路由兼容重定向
|
||||||
{ path: 'settings/keys', element: <Navigate to="/settings?tab=account" replace /> },
|
{ path: 'settings/keys', element: <Navigate to="/settings?tab=account" replace /> },
|
||||||
{ path: 'settings/ai', element: <Navigate to="/settings?tab=ai" replace /> },
|
{ path: 'settings/ai', element: <AiSettings /> },
|
||||||
{ path: 'settings/queries', element: <Navigate to="/settings?tab=queries" replace /> },
|
{ path: 'settings/queries', element: <Navigate to="/settings?tab=queries" replace /> },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user