diff --git a/docs/user-guide.md b/docs/user-guide.md
new file mode 100644
index 0000000..36b80ab
--- /dev/null
+++ b/docs/user-guide.md
@@ -0,0 +1,267 @@
+# 用户使用文档
+
+## 欢迎使用基本面分析系统
+
+基本面分析系统是一个专业的股票分析平台,帮助投资者通过多维度的基本面分析,做出更明智的投资决策。
+
+## 目录
+
+- [快速开始](#快速开始)
+- [主要功能](#主要功能)
+- [使用指南](#使用指南)
+- [常见问题](#常见问题)
+- [系统配置](#系统配置)
+
+## 快速开始
+
+### 1. 生成分析报告
+
+1. **访问首页**:在浏览器中打开系统首页
+2. **输入股票代码**:在输入框中输入股票代码,例如:
+ - 中国股票:`600519`(会自动识别为 600519.SH)或 `600519.SH`
+ - 美国股票:`AAPL`
+ - 香港股票:`00700.HK`
+3. **选择交易市场**:从下拉菜单中选择对应的交易市场(中国、香港、美国、日本)
+4. **生成报告**:点击"生成报告"按钮,系统将自动获取财务数据并生成分析报告
+
+### 2. 查看报告
+
+报告生成后,您将看到包含以下内容的综合报告:
+
+- **股价图表**:来自 TradingView 的实时股价图表
+- **财务数据**:多年财务指标对比,包括:
+ - 主要指标:ROE、ROA、ROIC、毛利率、净利润率等
+ - 费用指标:销售费用率、管理费用率、研发费用率等
+ - 资产占比:现金占比、库存占比、应收款占比等
+ - 周转能力:存货周转天数、应收款周转天数等
+ - 人均效率:人均创收、人均创利、人均工资等
+ - 市场表现:股价、市值、PE、PB、股东户数等
+- **AI 分析模块**:基于财务数据的智能分析,包括:
+ - 公司简介
+ - 业务分析
+ - 财务健康度评估
+ - 投资建议等
+
+### 3. 报告操作
+
+- **开始分析**:点击"开始分析"按钮,系统将按顺序生成各个分析模块
+- **停止**:在分析过程中,可以随时点击"停止"按钮中断分析
+- **继续**:停止后可以点击"继续"按钮恢复分析
+- **重新生成分析**:对任意分析模块,可以点击"重新生成分析"按钮重新生成
+
+## 主要功能
+
+### 1. 股票分析报告
+
+系统提供全面的股票基本面分析,包括:
+
+- **财务数据展示**:自动从 Tushare 等数据源获取最新的财务数据
+- **多维度分析**:涵盖盈利能力、运营效率、财务健康度等多个维度
+- **历史对比**:展示多年的财务指标变化趋势
+- **实时图表**:集成 TradingView 高级图表组件,提供专业的股价图表
+
+### 2. 智能分析模块
+
+系统使用 AI 模型(如 Google Gemini)对财务数据进行深度分析:
+
+- **自动生成**:根据财务数据自动生成业务分析和投资建议
+- **模块化设计**:不同分析模块相互独立,可按需生成
+- **依赖关系**:支持分析模块之间的依赖关系,确保分析的准确性
+- **实时进度**:显示每个分析模块的生成进度和状态
+
+### 3. 系统配置管理
+
+系统提供完善的配置管理功能:
+
+- **数据库配置**:配置 PostgreSQL 数据库连接
+- **AI 服务配置**:配置 AI 模型的 API 密钥和端点
+- **数据源配置**:配置 Tushare、Finnhub 等数据源的 API 密钥
+- **分析模块配置**:自定义分析模块的名称、模型和提示词模板
+- **配置测试**:支持测试各项配置的有效性
+- **配置导入/导出**:支持配置的备份和恢复
+
+### 4. 历史报告查询
+
+系统支持查询历史生成的报告:
+
+- **按市场和企业ID查询**:根据交易市场和企业ID查询历史报告
+- **报告列表**:查看所有历史报告及其状态
+- **报告详情**:查看完整的报告内容
+
+## 使用指南
+
+### 股票代码格式
+
+不同市场的股票代码格式:
+
+- **中国市场**:
+ - 上交所:6 位数字,如 `600519`(系统会自动添加 `.SH` 后缀)
+ - 深交所:6 位数字,如 `000001`(系统会自动添加 `.SZ` 后缀)
+ - 完整格式:`600519.SH` 或 `000001.SZ`
+- **美国市场**:直接输入股票代码,如 `AAPL`、`MSFT`
+- **香港市场**:股票代码,如 `00700`
+- **日本市场**:股票代码,如 `7203`
+
+### 财务数据解读
+
+系统展示的财务数据按以下方式组织:
+
+1. **主要指标**:核心财务指标
+ - ROE(净资产收益率):衡量股东权益的盈利能力,>12% 为优秀
+ - ROA(总资产收益率):衡量资产利用效率
+ - ROIC(投入资本回报率):衡量资本使用效率,>12% 为优秀
+ - 毛利率:反映产品或服务的盈利能力
+ - 净利润率:反映整体盈利能力
+
+2. **费用指标**:各项费用占收入的比例
+ - 销售费用率、管理费用率、研发费用率等
+ - 其他费用率:通过毛利率减去各项费用率计算得出
+
+3. **资产占比**:各项资产占总资产的比例
+ - 现金占比:反映资金充裕程度
+ - 库存占比:反映库存管理水平
+ - 应收款占比:反映应收账款风险
+ - 商誉占比:反映并购活动的影响
+
+4. **周转能力**:反映资产周转效率
+ - 存货周转天数:存货变现的速度
+ - 应收款周转天数:应收账款回收速度(>90天需注意)
+ - 应付款周转天数:应付账款支付周期
+
+5. **人均效率**:反映人力资源效率
+ - 人均创收、人均创利:衡量员工贡献
+ - 人均工资:反映员工待遇水平
+
+6. **市场表现**:股票市场的表现指标
+ - PE(市盈率)、PB(市净率):估值指标
+ - 股东户数:反映股东结构变化
+
+### 分析模块说明
+
+每个分析模块都有其特定的作用:
+
+- **公司简介**:自动生成公司的基本介绍和业务概况
+- **业务分析**:深度分析公司的业务模式和竞争优势
+- **财务分析**:评估公司的财务健康状况
+- **风险评估**:识别潜在的投资风险
+- **投资建议**:提供基于分析的投资建议
+
+分析模块会按依赖关系顺序执行,确保每个模块都能获得所需的前置分析结果。
+
+### 执行详情
+
+在报告页面的"执行详情"标签页,您可以查看:
+
+- **执行概况**:财务数据获取的耗时、API 调用次数等
+- **分析任务**:每个分析模块的执行状态、耗时、Token 消耗等
+- **总体统计**:总耗时、完成的任务数量、总 Token 消耗等
+
+这些信息有助于了解报告的生成过程和数据来源。
+
+## 常见问题
+
+### Q1: 为什么有些财务数据显示为 "-"?
+
+A: 可能是以下原因:
+- 该股票在对应年份没有数据
+- 数据源暂时不可用
+- 该指标不适用于该股票类型
+
+### Q2: 分析模块生成失败怎么办?
+
+A: 您可以:
+- 点击"重新生成分析"按钮重试
+- 检查系统配置中的 AI 服务配置是否正确
+- 查看"执行详情"中的错误信息
+
+### Q3: 如何查看历史报告?
+
+A:
+1. 访问"查询"页面(如果已启用)
+2. 选择交易市场和企业ID
+3. 点击"查询"按钮查看历史报告列表
+
+### Q4: 股票代码输入错误怎么办?
+
+A: 系统会自动识别一些常见的代码格式,但如果识别失败,请:
+- 中国市场:使用完整格式,如 `600519.SH` 或 `000001.SZ`
+- 其他市场:按照该市场的标准格式输入
+
+### Q5: 如何配置系统?
+
+A:
+1. 访问"配置"页面
+2. 在对应的标签页中配置各项设置
+3. 使用"测试"按钮验证配置是否正确
+4. 点击"保存所有配置"保存设置
+
+### Q6: 分析报告生成需要多长时间?
+
+A: 生成时间取决于:
+- 财务数据的获取速度(通常几秒钟)
+- AI 分析模块的数量和复杂度
+- AI 服务的响应速度
+
+完整的报告生成通常需要 1-5 分钟。
+
+### Q7: 可以同时分析多只股票吗?
+
+A: 目前系统每次只能分析一只股票。如需分析多只股票,请分别提交请求。
+
+### Q8: 报告数据是实时的吗?
+
+A:
+- 财务数据:来自 Tushare 等数据源,更新频率取决于数据源
+- 股价图表:TradingView 提供实时股价数据
+- AI 分析:基于当前获取的财务数据实时生成
+
+## 系统配置
+
+### 首次使用配置
+
+首次使用系统时,需要配置以下内容:
+
+1. **数据库配置**(如使用)
+ - 数据库连接 URL:`postgresql+asyncpg://user:password@host:port/database`
+ - 使用"测试连接"按钮验证连接
+
+2. **AI 服务配置**
+ - API Key:输入您的 AI 服务 API 密钥
+ - Base URL:输入 API 端点地址(如使用自建服务)
+
+3. **数据源配置**
+ - **Tushare**:输入 Tushare API Key(中国市场必需)
+ - **Finnhub**:输入 Finnhub API Key(全球市场可选)
+
+### 配置注意事项
+
+- **敏感信息保护**:API 密钥等敏感信息在输入框中不会显示,留空表示保持当前值
+- **配置验证**:保存前建议使用"测试"按钮验证各项配置
+- **配置备份**:建议定期使用"导出配置"功能备份配置
+- **配置恢复**:可使用"导入配置"功能恢复之前的配置
+
+### 分析模块配置
+
+在"配置"页面的"分析配置"标签页,您可以:
+
+- **自定义模块名称**:修改分析模块的显示名称
+- **选择 AI 模型**:为每个模块指定使用的 AI 模型
+- **编辑提示词模板**:自定义每个模块的分析提示词
+- **设置模块依赖**:配置分析模块之间的依赖关系
+
+配置修改后,点击"保存分析配置"即可生效。
+
+## 技术支持
+
+如果您在使用过程中遇到问题,可以:
+
+1. 查看"执行详情"中的错误信息
+2. 检查系统配置是否正确
+3. 查看系统日志(如果已启用)
+4. 联系系统管理员获取支持
+
+---
+
+**最后更新**:2025年1月
+
+
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 92623d0..4c5fea9 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -15,6 +15,7 @@
"@radix-ui/react-tabs": "^1.1.13",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
+ "github-markdown-css": "^5.8.1",
"lucide-react": "^0.545.0",
"next": "15.5.5",
"react": "19.1.0",
@@ -4587,6 +4588,18 @@
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
}
},
+ "node_modules/github-markdown-css": {
+ "version": "5.8.1",
+ "resolved": "https://registry.npmjs.org/github-markdown-css/-/github-markdown-css-5.8.1.tgz",
+ "integrity": "sha512-8G+PFvqigBQSWLQjyzgpa2ThD9bo7+kDsriUIidGcRhXgmcaAWUIpCZf8DavJgc+xifjbCG+GvMyWr0XMXmc7g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 26e579a..5560a36 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -4,7 +4,7 @@
"private": true,
"scripts": {
"dev": "next dev --turbopack",
- "build": "next build --turbopack",
+ "build": "next build",
"start": "next start",
"lint": "eslint"
},
@@ -16,6 +16,7 @@
"@radix-ui/react-tabs": "^1.1.13",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
+ "github-markdown-css": "^5.8.1",
"lucide-react": "^0.545.0",
"next": "15.5.5",
"react": "19.1.0",
diff --git a/frontend/src/app/docs/page.tsx b/frontend/src/app/docs/page.tsx
index 8a54fa4..909bf1e 100644
--- a/frontend/src/app/docs/page.tsx
+++ b/frontend/src/app/docs/page.tsx
@@ -6,13 +6,13 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
async function getMarkdownContent() {
// process.cwd() is the root of the Next.js project (the 'frontend' directory)
- const mdPath = path.join(process.cwd(), '..', 'docs', 'design.md');
+ const mdPath = path.join(process.cwd(), '..', 'docs', 'user-guide.md');
try {
const content = await fs.readFile(mdPath, 'utf8');
return content;
} catch (error) {
- console.error("Failed to read design.md:", error);
- return "# 文档加载失败\n\n无法读取 `docs/design.md` 文件。请检查文件是否存在以及服务器权限。";
+ console.error("Failed to read user-guide.md:", error);
+ return "# 文档加载失败\n\n无法读取 `docs/user-guide.md` 文件。请检查文件是否存在以及服务器权限。";
}
}
@@ -22,42 +22,22 @@ export default async function DocsPage() {
return (
-
+
,
- h2: ({node, ...props}) => ,
- h3: ({node, ...props}) => ,
- p: ({node, ...props}) => ,
- ul: ({node, ...props}) => ,
- ol: ({node, ...props}) =>
,
- li: ({node, ...props}) => ,
- code: ({node, inline, className, children, ...props}: any) => {
- const match = /language-(\w+)/.exec(className || '');
- return !inline ? (
-
- {children}
-
- ) : (
-
- {children}
-
- );
- },
- pre: ({children}) => {children},
- table: ({node, ...props}) => ,
- th: ({node, ...props}) => | ,
- td: ({node, ...props}) => | ,
- a: ({node, ...props}) => ,
- }}
>
{content}
diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css
index dc98be7..1dee2cd 100644
--- a/frontend/src/app/globals.css
+++ b/frontend/src/app/globals.css
@@ -1,5 +1,6 @@
@import "tailwindcss";
@import "tw-animate-css";
+@import "github-markdown-css/github-markdown.css";
@custom-variant dark (&:is(.dark *));
diff --git a/frontend/src/app/report/[symbol]/page.tsx b/frontend/src/app/report/[symbol]/page.tsx
index 8994a73..c54b6ed 100644
--- a/frontend/src/app/report/[symbol]/page.tsx
+++ b/frontend/src/app/report/[symbol]/page.tsx
@@ -1491,19 +1491,7 @@ export default function ReportPage() {
: '待开始'}
- {/* 失败时的“重新分析”按钮(兼容原逻辑) */}
- {state.error && !state.loading && (
-
- )}
- {/* 新增:始终可见的“重新生成分析”按钮 */}
+ {/* 始终可见的"重新生成分析"按钮 */}
{!state.loading && (