隐藏策略与 API 配置菜单入口

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-06 10:01:56 +08:00
parent db978240da
commit 1ae2102b4c
2 changed files with 0 additions and 95 deletions
-94
View File
@@ -8,17 +8,14 @@ import { AiReportBubble } from '@/components/financials/AiReportBubble'
import { StockAnalysisHost } from '@/components/stock-analysis/StockAnalysisHost' import { StockAnalysisHost } from '@/components/stock-analysis/StockAnalysisHost'
import { StockAnalysisBubble } from '@/components/stock-analysis/StockAnalysisBubble' import { StockAnalysisBubble } from '@/components/stock-analysis/StockAnalysisBubble'
import { import {
useCapabilities,
useSettings, useSettings,
usePreferences, usePreferences,
useVersion, useVersion,
} from '@/lib/useSharedQueries' } from '@/lib/useSharedQueries'
import { QK } from '@/lib/queryKeys' import { QK } from '@/lib/queryKeys'
import { import {
ScanSearch,
FileText, FileText,
Settings, Settings,
Key,
LayoutDashboard, LayoutDashboard,
Tags, Tags,
TrendingUp, TrendingUp,
@@ -38,7 +35,6 @@ const BRAND = '#8B5CF6'
const nav = [ const nav = [
{ to: '/', label: '看板', icon: LayoutDashboard }, { to: '/', label: '看板', icon: LayoutDashboard },
{ to: '/screener', label: '策略', icon: ScanSearch },
{ to: '/stock-analysis', label: '个股分析', icon: TrendingUp }, { to: '/stock-analysis', label: '个股分析', icon: TrendingUp },
{ to: '/limit-ladder', label: '连板梯队', icon: Flame }, { to: '/limit-ladder', label: '连板梯队', icon: Flame },
{ to: '/concept-analysis', label: '概念分析', icon: Layers3 }, { to: '/concept-analysis', label: '概念分析', icon: Layers3 },
@@ -48,91 +44,6 @@ const nav = [
{ to: '/indices', label: '指数', icon: BarChart3 }, { to: '/indices', label: '指数', icon: BarChart3 },
] as const ] as const
// ===== 档位卡片 =====
function TierBadge({ label, hasKey }: { label: string; hasKey?: boolean }) {
const base = label.split(' ')[0].split('+')[0].toLowerCase()
const isNone = base === 'none'
const tierConfig: Record<string, {
desc: string
tagBg: React.CSSProperties
dotStyle: React.CSSProperties
labelTextStyle: React.CSSProperties
}> = {
none: {
desc: '未配置 Key · 仅历史日K',
tagBg: { background: 'rgba(113,113,122,0.15)' },
dotStyle: { background: '#52525b' },
labelTextStyle: { color: '#71717a' },
},
free: {
desc: '基础日K · 自选实时',
tagBg: { background: 'rgba(113,113,122,0.3)' },
dotStyle: { background: '#71717a' },
labelTextStyle: { color: '#a1a1aa' },
},
starter: {
desc: '批量同步 · 行情池',
tagBg: { background: 'rgba(59,130,246,0.2)' },
dotStyle: { background: '#3b82f6' },
labelTextStyle: { color: '#60a5fa' },
},
pro: {
desc: '分钟K · 实时行情 · 盘口',
tagBg: { background: 'linear-gradient(135deg, rgba(168,85,247,0.2), rgba(124,58,237,0.15))' },
dotStyle: { background: 'linear-gradient(135deg, #a855f7, #7c3aed)' },
labelTextStyle: { background: 'linear-gradient(135deg, #c084fc, #a855f7)', WebkitBackgroundClip: 'text', backgroundClip: 'text', color: 'transparent' },
},
expert: {
desc: 'WebSocket · 财务数据',
tagBg: { background: 'linear-gradient(135deg, rgba(59,130,246,0.2), rgba(168,85,247,0.2), rgba(245,158,11,0.2))' },
dotStyle: { background: 'linear-gradient(135deg, #3b82f6, #a855f7, #f59e0b)' },
labelTextStyle: { background: 'linear-gradient(135deg, #60a5fa, #c084fc, #fbbf24)', WebkitBackgroundClip: 'text', backgroundClip: 'text', color: 'transparent' },
},
}
const t = tierConfig[base] || tierConfig.none
// none 档显示英文「None」,无 label 时也显示「None」
const displayLabel = isNone ? 'None' : (label || 'None')
return (
<NavLink
to="/settings?tab=account"
className="mt-2.5 group block -mx-2.5"
title="API 设置"
>
<div className="relative overflow-hidden rounded-lg border border-blue-400/20 bg-gradient-to-br from-blue-500/[0.12] via-surface to-surface px-3 py-2 transition-all hover:border-blue-400/35 hover:from-blue-500/[0.16]">
<div className="absolute -right-5 -top-6 h-14 w-14 rounded-full bg-blue-500/10 blur-2xl" />
<div className="relative flex items-center gap-2">
<div className="flex h-6 w-6 items-center justify-center rounded-md bg-blue-400/10 text-blue-300 ring-1 ring-blue-400/20">
<Key className="h-3.5 w-3.5" />
</div>
<div className="min-w-0 flex-1">
<div className="flex items-center gap-1.5">
<span className="text-xs font-medium text-foreground">TickFlow</span>
<span
className="h-1.5 w-1.5 rounded-full"
style={{ ...t.dotStyle, ...(base === 'expert' ? { animation: 'pulse 2s infinite' } : {}) }}
/>
</div>
<div className="mt-0.5 truncate text-[10px] leading-tight text-muted">
{isNone && !hasKey ? '配置 Key 解锁更多能力' : t.desc}
</div>
</div>
<span
className="inline-flex h-[18px] max-w-[68px] shrink-0 items-center overflow-hidden rounded px-1.5 text-[10px] font-bold font-mono leading-none"
style={t.tagBg}
>
<span className="truncate" style={t.labelTextStyle}>{displayLabel}</span>
</span>
<Settings className="h-3 w-3 shrink-0 text-muted group-hover:text-blue-300 transition-colors" />
</div>
</div>
</NavLink>
)
}
function AIConfigBadge({ configured, model }: { configured?: boolean; model?: string }) { function AIConfigBadge({ configured, model }: { configured?: boolean; model?: string }) {
return ( return (
<NavLink <NavLink
@@ -164,7 +75,6 @@ function AIConfigBadge({ configured, model }: { configured?: boolean; model?: st
export function Layout() { export function Layout() {
// ===== 共享 hooks (替代内联 useQuery) ===== // ===== 共享 hooks (替代内联 useQuery) =====
const { data: caps } = useCapabilities()
const { data: settingsState } = useSettings() const { data: settingsState } = useSettings()
const { data: versionData } = useVersion() const { data: versionData } = useVersion()
const { data: prefs } = usePreferences() const { data: prefs } = usePreferences()
@@ -226,10 +136,6 @@ export function Layout() {
style={{ background: `linear-gradient(90deg, ${BRAND}88, transparent 80%)` }} style={{ background: `linear-gradient(90deg, ${BRAND}88, transparent 80%)` }}
/> />
<TierBadge
label={caps?.label ?? ''}
hasKey={settingsState?.mode !== 'none'}
/>
<AIConfigBadge <AIConfigBadge
configured={settingsState?.ai_configured ?? settingsState?.has_ai_key} configured={settingsState?.ai_configured ?? settingsState?.has_ai_key}
model={settingsState?.ai_model} model={settingsState?.ai_model}
@@ -32,7 +32,6 @@ interface NavEntry {
const BUILTIN_PAGES: NavEntry[] = [ const BUILTIN_PAGES: NavEntry[] = [
{ id: '/', label: '看板', type: 'builtin', visible: true }, { id: '/', label: '看板', type: 'builtin', visible: true },
{ id: '/screener', label: '策略', type: 'builtin', visible: true },
{ id: '/limit-ladder', label: '连板梯队', type: 'builtin', visible: true }, { id: '/limit-ladder', label: '连板梯队', type: 'builtin', visible: true },
{ id: '/concept-analysis', label: '概念分析', type: 'builtin', visible: true }, { id: '/concept-analysis', label: '概念分析', type: 'builtin', visible: true },
{ id: '/industry-analysis', label: '行业分析', type: 'builtin', visible: true }, { id: '/industry-analysis', label: '行业分析', type: 'builtin', visible: true },