新增同步 ext_data(概念/行业) 和本地化财务数据展示
- 将 ext_data 加入 SYNCABLE_PARTS,概念/行业分类数据可从 local 同步到 serve - 去掉 serve 财务分析接口的 Cap.FINANCIAL 能力门控,依赖本地 parquet 文件来展示数据 - serve 财务分析前端在无 API Key 但有同步数据时正常展示,隐藏同步按钮 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -57,42 +57,56 @@ export function Financials() {
|
||||
rememberStock(symbol, name)
|
||||
}
|
||||
|
||||
// 无 Expert 能力时: 等 status 加载完, 判断是否有从 local 同步来的数据
|
||||
if (!hasFinancial) {
|
||||
return (
|
||||
<>
|
||||
<PageHeader title="财务分析" subtitle="利润表 / 资负表 / 现金流 / 关键指标 / AI分析 · Expert" />
|
||||
<div className="px-8 py-10">
|
||||
<div className="mx-auto max-w-md rounded-card border border-warning/30 bg-warning/[0.04] p-8 text-center">
|
||||
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-warning/10">
|
||||
<Lock className="h-6 w-6 text-warning" />
|
||||
</div>
|
||||
<h3 className="mt-4 text-base font-semibold text-foreground">需要 Expert 套餐</h3>
|
||||
<p className="mt-2 text-xs leading-relaxed text-secondary">
|
||||
财务数据接口仅 Expert 套餐可用。升级后此页自动显示财务数据面板。
|
||||
</p>
|
||||
{/* 当前财务数据源(TickFlow)需付费,后续将接入免费数据源;期间欢迎在 issues 推荐免费源 */}
|
||||
<div className="mt-5 rounded-btn border border-accent/25 bg-accent/[0.05] px-3.5 py-3 text-left">
|
||||
<div className="flex items-center gap-1.5 text-xs font-medium text-accent">
|
||||
<Lightbulb className="h-3.5 w-3.5 shrink-0" />
|
||||
关于数据源
|
||||
if (isLoading) {
|
||||
return (
|
||||
<>
|
||||
<PageHeader title="财务分析" subtitle="利润表 / 资负表 / 现金流 / 关键指标 / AI分析 · Expert" />
|
||||
<div className="flex items-center justify-center py-16">
|
||||
<Loader2 className="h-5 w-5 animate-spin text-muted" />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
if (!status?.available) {
|
||||
// 既无 Expert 能力, 也无同步数据 → 锁定页
|
||||
return (
|
||||
<>
|
||||
<PageHeader title="财务分析" subtitle="利润表 / 资负表 / 现金流 / 关键指标 / AI分析 · Expert" />
|
||||
<div className="px-8 py-10">
|
||||
<div className="mx-auto max-w-md rounded-card border border-warning/30 bg-warning/[0.04] p-8 text-center">
|
||||
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-warning/10">
|
||||
<Lock className="h-6 w-6 text-warning" />
|
||||
</div>
|
||||
<p className="mt-1.5 text-[11px] leading-relaxed text-secondary">
|
||||
当前财务数据源需付费,后续会接入免费数据源。如你常用某个免费财务数据源,欢迎在 Issues 中多多推荐哈 ~
|
||||
<h3 className="mt-4 text-base font-semibold text-foreground">需要 Expert 套餐</h3>
|
||||
<p className="mt-2 text-xs leading-relaxed text-secondary">
|
||||
财务数据接口仅 Expert 套餐可用。升级后此页自动显示财务数据面板。
|
||||
</p>
|
||||
<a
|
||||
href="https://github.com/shy3130/tickflow-stock-panel/issues"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-accent hover:underline"
|
||||
>
|
||||
前往 Issues 推荐
|
||||
<ExternalLink className="h-3 w-3" />
|
||||
</a>
|
||||
<div className="mt-5 rounded-btn border border-accent/25 bg-accent/[0.05] px-3.5 py-3 text-left">
|
||||
<div className="flex items-center gap-1.5 text-xs font-medium text-accent">
|
||||
<Lightbulb className="h-3.5 w-3.5 shrink-0" />
|
||||
关于数据源
|
||||
</div>
|
||||
<p className="mt-1.5 text-[11px] leading-relaxed text-secondary">
|
||||
当前财务数据源需付费,后续会接入免费数据源。如你常用某个免费财务数据源,欢迎在 Issues 中多多推荐哈 ~
|
||||
</p>
|
||||
<a
|
||||
href="https://github.com/shy3130/tickflow-stock-panel/issues"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-accent hover:underline"
|
||||
>
|
||||
前往 Issues 推荐
|
||||
<ExternalLink className="h-3 w-3" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
</>
|
||||
)
|
||||
}
|
||||
// 有同步数据, 继续展示
|
||||
}
|
||||
|
||||
const handleSync = (table: string) => {
|
||||
@@ -171,17 +185,19 @@ export function Financials() {
|
||||
: '同步中…'}
|
||||
</span>
|
||||
)}
|
||||
<button
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-btn bg-gradient-to-r from-accent/25 to-accent/10 border border-accent/30 text-accent text-xs font-medium hover:from-accent/35 hover:to-accent/20 transition-all duration-150 disabled:opacity-40 disabled:cursor-not-allowed"
|
||||
onClick={() => handleSync('all')}
|
||||
disabled={syncing}
|
||||
title={syncing ? '正在同步,请稍候…' : '同步全部财务表'}
|
||||
>
|
||||
{syncing
|
||||
? <Loader2 className="h-3.5 w-3.5 animate-spin" />
|
||||
: <RefreshCw className="h-3.5 w-3.5" />}
|
||||
{syncing ? '同步中…' : '全部同步'}
|
||||
</button>
|
||||
{hasFinancial && (
|
||||
<button
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-btn bg-gradient-to-r from-accent/25 to-accent/10 border border-accent/30 text-accent text-xs font-medium hover:from-accent/35 hover:to-accent/20 transition-all duration-150 disabled:opacity-40 disabled:cursor-not-allowed"
|
||||
onClick={() => handleSync('all')}
|
||||
disabled={syncing}
|
||||
title={syncing ? '正在同步,请稍候…' : '同步全部财务表'}
|
||||
>
|
||||
{syncing
|
||||
? <Loader2 className="h-3.5 w-3.5 animate-spin" />
|
||||
: <RefreshCw className="h-3.5 w-3.5" />}
|
||||
{syncing ? '同步中…' : '全部同步'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
@@ -233,16 +249,20 @@ export function Financials() {
|
||||
)}
|
||||
<span className="text-xs font-medium text-foreground">{label}</span>
|
||||
</div>
|
||||
<button
|
||||
className="text-muted hover:text-accent transition-colors disabled:opacity-30 disabled:cursor-not-allowed"
|
||||
onClick={() => handleSync(key)}
|
||||
disabled={syncing}
|
||||
title={syncing ? '正在同步…' : `同步${label}`}
|
||||
>
|
||||
{syncing
|
||||
? <Loader2 className="h-3.5 w-3.5 animate-spin" />
|
||||
: <RefreshCw className="h-3.5 w-3.5" />}
|
||||
</button>
|
||||
{hasFinancial ? (
|
||||
<button
|
||||
className="text-muted hover:text-accent transition-colors disabled:opacity-30 disabled:cursor-not-allowed"
|
||||
onClick={() => handleSync(key)}
|
||||
disabled={syncing}
|
||||
title={syncing ? '正在同步…' : `同步${label}`}
|
||||
>
|
||||
{syncing
|
||||
? <Loader2 className="h-3.5 w-3.5 animate-spin" />
|
||||
: <RefreshCw className="h-3.5 w-3.5" />}
|
||||
</button>
|
||||
) : (
|
||||
<div className="h-3.5 w-3.5" />
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-2 text-xl font-semibold tabular-nums text-foreground">
|
||||
{fmtBigNum(info?.rows ?? 0)}
|
||||
|
||||
Reference in New Issue
Block a user