# 数据模型

<cite>
**本文引用的文件**
- `src-tauri/src/models/mod.rs`
- `src-tauri/src/models/financial_statements.rs`
- `src-tauri/src/models/valuation_date.rs`
- `src-tauri/src/models/project_summary.rs`
- `src-tauri/src/models/investment_financing.rs`
- `src-tauri/src/models/dlom_calculation.rs`
- `src-tauri/sql/ths_api_cache_table.sql`
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本文件系统性梳理 GSDJGXApp 的数据模型，聚焦于项目、基金、估值日期、财务报表与计算结果等核心实体，明确字段定义、数据类型与约束；解释实体间关系映射（一对一、一对多、多对多）；阐述模型验证规则（必填、格式、业务规则）；说明序列化与反序列化机制（JSON 与数据库映射）；并提供模型扩展指南（新增字段、关系调整、性能优化）与典型使用场景。

## 项目结构
后端采用 Rust + SeaORM 实体模型 + Tauri 命令层，前端通过 Tauri 命令调用后端接口。数据模型主要位于 src-tauri/src/models 下，数据库表结构位于 src-tauri/sql。

```mermaid
graph TB
subgraph "后端"
M["models 模块<br/>实体与DTO"]
SQL["SQL 表结构<br/>validation_ths_data_storage"]
end
subgraph "前端"
FE["Angular 应用"]
end
FE --> |"Tauri 命令调用"| M
M --> |"SeaORM 映射"| SQL
```

**图表来源**
- `src-tauri/src/models/mod.rs#L1-L20`
- `src-tauri/sql/ths_api_cache_table.sql#L1-L21`

**章节来源**
- `src-tauri/src/models/mod.rs#L1-L20`
- `src-tauri/sql/ths_api_cache_table.sql#L1-L21`

## 核心组件
本节概述本次文档关注的核心实体与数据结构，并给出其职责定位与典型用途。

- 项目汇总（Project Summary）
  - 职责：记录项目基础信息与资金相关信息，作为项目维度的主表之一。
  - 关键用途：作为其他实体（如财务报表、投融管理）的外键关联目标。
- 基金（Investment Financing）
  - 职责：记录单笔投资/融资事件的关键要素，含投后估值、基准日、基金持股比例等。
  - 关键用途：用于计算归属于基金的股权价值等衍生指标。
- 估值日期（Valuation Date）
  - 职责：维护估值基准日、报告日、状态等元数据。
  - 关键用途：为各类估值计算提供统一的时间锚点。
- 财务报表（Financial Statements）
  - 职责：保存某一时间点的财务报表电子表格数据（JSON 字符串），并标注报表类型。
  - 关键用途：承载利润表/资产负债表等结构化数据。
- 计算结果（DLOM Calculation Result）
  - 职责：承载某次计算的输入参数、输出结果、明细与状态。
  - 关键用途：持久化估值计算过程与结果，便于回溯与复现。

**章节来源**
- `src-tauri/src/models/project_summary.rs#L4-L18`
- `src-tauri/src/models/investment_financing.rs#L4-L26`
- `src-tauri/src/models/valuation_date.rs#L4-L18`
- `src-tauri/src/models/financial_statements.rs#L4-L20`
- `src-tauri/src/models/dlom_calculation.rs#L4-L20`

## 架构总览
下图展示核心实体之间的关系映射与交互路径。项目汇总作为“一”的一方，分别与财务报表（一对多）和投融管理（一对多）建立关联；估值日期独立存在，供计算流程引用；计算结果承载计算过程与结果，与项目与估值日期形成关联。

```mermaid
erDiagram
PROJECT_SUMMARY {
int id PK
string project_code
string project_name
float equity_ratio
float investment_amount
string fund_name
string fund_code
}
FINANCIAL_STATEMENTS {
int id PK
int project_id FK
date statement_date
string statement_type
string spreadsheet_data
}
INVESTMENT_FINANCING {
int id PK
int project_id FK
string transaction_nature
float post_investment_valuation
date valuation_benchmark_date
float fund_shareholding_ratio
float fund_equity_value
}
VALUATION_DATE {
int valuation_date_id PK
date valuation_date
date report_date
string project_manager
string auditor
string remarks
string status
}
DLOM_CALCULATION_RESULT {
int calculation_id PK
int project_id FK
int valuation_date_id FK
float restriction_time
float risk_free_rate
float average_discount
float median_discount
string selected_source
float selected_discount_value
string calculation_details
string stock_data_status
string error_message
}
PROJECT_SUMMARY ||--o{ FINANCIAL_STATEMENTS : "一对多"
PROJECT_SUMMARY ||--o{ INVESTMENT_FINANCING : "一对多"
VALUATION_DATE ||--o{ DLOM_CALCULATION_RESULT : "一对多"
PROJECT_SUMMARY ||--o{ DLOM_CALCULATION_RESULT : "一对多"
```

**图表来源**
- `src-tauri/src/models/project_summary.rs#L4-L18`
- `src-tauri/src/models/financial_statements.rs#L4-L20`
- `src-tauri/src/models/investment_financing.rs#L4-L26`
- `src-tauri/src/models/valuation_date.rs#L4-L18`
- `src-tauri/src/models/dlom_calculation.rs#L4-L20`

## 详细组件分析

### 项目汇总（Project Summary）
- 字段与类型
  - id：整型，主键
  - project_code：字符串，项目编号
  - project_name：字符串，项目名称
  - equity_ratio：浮点数，权益比例
  - investment_amount：浮点数，投资金额
  - fund_name：字符串，基金名称
  - fund_code：可空字符串，基金代码
  - created_at / updated_at：UTC 时间戳
- 约束与规则
  - 主键唯一性
  - project_code 建议唯一（业务约束）
  - equity_ratio 与 investment_amount 建议非负
- 关系映射
  - 与 FINANCIAL_STATEMENTS：一对多（一个项目可有多个报表）
  - 与 INVESTMENT_FINANCING：一对多（一个项目可有多笔投融事件）
- 序列化与反序列化
  - 使用 serde 进行 JSON 序列化/反序列化
  - DTO：CreateProjectSummaryDto、UpdateProjectSummaryDto
- 验证规则
  - 必填：project_code、project_name、equity_ratio、investment_amount、fund_name
  - 业务：equity_ratio ∈ [0,1] 或与金额逻辑一致
- 使用场景
  - 项目筛选、报表与投融事件聚合展示、计算结果关联展示

**章节来源**
- `src-tauri/src/models/project_summary.rs#L4-L18`
- `src-tauri/src/models/project_summary.rs#L25-L44`

### 基金（Investment Financing）
- 字段与类型
  - id：整型，主键
  - project_id：整型，外键，关联项目汇总
  - transaction_nature：字符串，交易性质（如增资、转让）
  - post_investment_valuation：浮点数，投后估值
  - valuation_benchmark_date：日期，估值基准日
  - fund_shareholding_ratio：浮点数，基金持股比例
  - fund_equity_value：浮点数，归属于基金的股权价值（计算字段）
  - investment_description：可空字符串，投资说明
  - created_at / updated_at：UTC 时间戳
- 约束与规则
  - 主键唯一性
  - project_id 引用项目汇总
  - post_investment_valuation、fund_shareholding_ratio 建议非负
  - fund_equity_value 可由其他字段派生（服务层计算）
- 关系映射
  - 与 PROJECT_SUMMARY：多对一
- 序列化与反序列化
  - 使用 serde 进行 JSON 序列化/反序列化
  - DTO：CreateInvestmentFinancingDto、UpdateInvestmentFinancingDto
  - 视图：InvestmentFinancingView（包含项目信息）
- 验证规则
  - 必填：project_id、transaction_nature、post_investment_valuation、valuation_benchmark_date、fund_shareholding_ratio
  - 业务：估值与比例的合理性校验
- 使用场景
  - 单笔投融事件录入、按项目聚合展示、计算归属性值

**章节来源**
- `src-tauri/src/models/investment_financing.rs#L4-L26`
- `src-tauri/src/models/investment_financing.rs#L33-L54`
- `src-tauri/src/models/investment_financing.rs#L56-L71`

### 估值日期（Valuation Date）
- 字段与类型
  - valuation_date_id：整型，主键
  - valuation_date：日期，基准日
  - report_date：可空日期，报告日
  - project_manager / auditor / remarks：可空字符串
  - status：可空字符串（如 active/inactive）
  - created_at / updated_at：UTC 时间戳
- 约束与规则
  - 主键唯一性
  - valuation_date 建议唯一（业务约束）
- 关系映射
  - 与 DLOM_CALCULATION_RESULT：一对多（一个基准日可对应多次计算）
- 序列化与反序列化
  - 使用 serde 进行 JSON 序列化/反序列化
  - DTO：CreateValuationDateDto、UpdateValuationDateDto
  - 查询参数：ValuationDateQuery（支持分页与日期范围）
- 验证规则
  - 必填：valuation_date
  - 业务：report_date ≥ valuation_date（如适用）
- 使用场景
  - 选择估值基准日、批量查询计算结果、状态管理

**章节来源**
- `src-tauri/src/models/valuation_date.rs#L4-L18`
- `src-tauri/src/models/valuation_date.rs#L25-L43`
- `src-tauri/src/models/valuation_date.rs#L45-L52`

### 财务报表（Financial Statements）
- 字段与类型
  - id：整型，主键
  - project_id：整型，外键，关联项目汇总
  - statement_date：日期，报表日期（Tab 标签）
  - statement_type：字符串，报表类型（如利润表/资产负债表）
  - spreadsheet_data：字符串，电子表格数据（JSON 字符串）
  - created_at / updated_at：UTC 时间戳
- 约束与规则
  - 主键唯一性
  - project_id 引用项目汇总
  - statement_type 建议枚举化（业务约束）
  - spreadsheet_data 建议 JSON 结构校验
- 关系映射
  - 与 PROJECT_SUMMARY：多对一
- 序列化与反序列化
  - 使用 serde 进行 JSON 序列化/反序列化
  - DTO：CreateFinancialStatementDto、UpdateFinancialStatementDto
  - 视图：FinancialStatementView（包含项目信息）
- 验证规则
  - 必填：project_id、statement_date、statement_type、spreadsheet_data
  - 业务：同一项目+报表日期+报表类型的唯一性（建议）
- 使用场景
  - 报表数据录入与展示、按项目与日期检索

**章节来源**
- `src-tauri/src/models/financial_statements.rs#L4-L20`
- `src-tauri/src/models/financial_statements.rs#L27-L42`
- `src-tauri/src/models/financial_statements.rs#L44-L56`

### 计算结果（DLOM Calculation Result）
- 字段与类型
  - calculation_id：整型，主键
  - project_id：整型，外键，关联项目汇总
  - valuation_date_id：整型，外键，关联估值日期
  - restriction_time / risk_free_rate / average_discount / median_discount：浮点数
  - selected_source：字符串，选源标识
  - selected_discount_value：浮点数，最终折扣值
  - calculation_details：可空字符串，JSON 字符串形式的明细数组
  - stock_data_status：字符串，股票数据状态
  - error_message：可空字符串，错误信息
  - created_at / updated_at：字符串（前端展示用）
- 约束与规则
  - 主键唯一性
  - 外键：project_id、valuation_date_id
  - 数值字段建议非负或在合理区间
- 关系映射
  - 与 PROJECT_SUMMARY：多对一
  - 与 VALUATION_DATE：多对一
- 序列化与反序列化
  - 使用 serde 进行 JSON 序列化/反序列化
  - 输入：DlomCalculationInput
  - 更新请求：DlomUpdateRequest
- 验证规则
  - 必填：project_id、valuation_date_id、restriction_time、risk_free_rate、average_discount、median_discount、selected_source、selected_discount_value、stock_data_status
  - 业务：折扣值与选源一致性、明细 JSON 结构校验
- 使用场景
  - 估值计算执行与结果持久化、按项目/日期检索、错误追踪

**章节来源**
- `src-tauri/src/models/dlom_calculation.rs#L4-L20`
- `src-tauri/src/models/dlom_calculation.rs#L22-L35`
- `src-tauri/src/models/dlom_calculation.rs#L37-L42`

### 数据库表结构（验证缓存）
- 表名：validation_ths_data_storage
- 字段与类型
  - id：整型，主键自增
  - query_hash：文本，唯一，查询哈希
  - query_string / query_params / result_data / metadata：文本
  - status：文本，默认 success
  - error_message：文本
  - data_valid_until：日期时间，有效期
  - created_at / updated_at：日期时间，默认当前时间
- 索引
  - query_hash 唯一索引
  - status、valid_until、created_at 等索引
- 用途
  - 缓存 THS 数据验证结果，提升重复查询性能与稳定性

**章节来源**
- `src-tauri/sql/ths_api_cache_table.sql#L1-L21`

## 依赖分析
- 组件耦合
  - PROJECT_SUMMARY 为核心枢纽，被 FINANCIAL_STATEMENTS 与 INVESTMENT_FINANCING 引用
  - VALUATION_DATE 与 DLOM_CALCULATION_RESULT 存在一对多关系
- 外部依赖
  - SeaORM 实体模型与 Relation 定义（当前模型 Relation 为空枚举）
  - serde 用于 JSON 序列化/反序列化
- 潜在循环依赖
  - 当前各模型独立，无直接循环依赖迹象
- 接口契约
  - DTO 与 Model 之间通过 serde 自动映射，保持前后端一致

```mermaid
graph LR
PS["ProjectSummary"] --> FS["FinancialStatements"]
PS --> IF["InvestmentFinancing"]
VD["ValuationDate"] --> DCR["DLOMCalculationResult"]
PS --> DCR
```

**图表来源**
- `src-tauri/src/models/project_summary.rs#L4-L18`
- `src-tauri/src/models/financial_statements.rs#L4-L20`
- `src-tauri/src/models/investment_financing.rs#L4-L26`
- `src-tauri/src/models/valuation_date.rs#L4-L18`
- `src-tauri/src/models/dlom_calculation.rs#L4-L20`

**章节来源**
- `src-tauri/src/models/mod.rs#L1-L20`

## 性能考虑
- 索引策略
  - 对常用查询字段建立索引（如项目编号、报表日期、基准日、状态等）
  - 对缓存表 validation_ths_data_storage 已有关键索引，建议结合查询模式评估是否需要复合索引
- 查询优化
  - 分页查询（ValuationDateQuery 支持分页）降低单次返回量
  - 合理使用投影字段，避免 SELECT *
- 序列化开销
  - 大体量 JSON 字段（如 spreadsheet_data、calculation_details）建议压缩或拆分存储
- 并发与事务
  - 写入密集场景建议批量提交与事务边界控制

## 故障排查指南
- 常见问题
  - 外键约束失败：确认关联实体已存在且字段值正确
  - JSON 字段解析失败：检查 spreadsheet_data 与 calculation_details 的 JSON 结构
  - 日期格式错误：确保前端传入字符串日期符合 YYYY-MM-DD
- 定位手段
  - 查看 created_at / updated_at 时间戳辅助定位
  - 利用 ValuationDateQuery 的日期范围与分页参数缩小范围
  - 对缓存表 validation_ths_data_storage 检查 status 与 error_message 字段
- 建议流程
  1) 校验必填字段与格式
  2) 校验外键与业务规则
  3) 检查 JSON 结构与索引命中
  4) 回放计算步骤与错误信息

**章节来源**
- `src-tauri/src/models/valuation_date.rs#L45-L52`
- `src-tauri/sql/ths_api_cache_table.sql#L1-L21`

## 结论
本文档从实体定义、关系映射、验证规则、序列化机制与扩展指南五个维度，系统梳理了项目、基金、估值日期、财务报表与计算结果等核心数据模型。建议在后续迭代中完善外键关系定义、引入更严格的枚举与校验、优化大体量 JSON 字段的存储与查询，并持续完善索引策略与缓存机制。

## 附录
- 扩展指南
  - 新增字段
    - 在对应 Model 结构体中添加字段，并在 DTO 中同步
    - 若为计算字段，需在服务层补充计算逻辑
  - 修改关系
    - 在 SeaORM 实体中通过 Relation 枚举声明关系
    - 更新数据库迁移脚本与索引
  - 性能优化
    - 为高频查询字段建立索引
    - 对大体量 JSON 字段进行压缩或拆分
    - 使用分页与投影减少网络与内存压力
- 使用场景示例（路径指引）
  - 项目与报表关联查询：参考 FinancialStatementView 的字段组合
  - 投资事件聚合：参考 InvestmentFinancingView 的字段组合
  - 计算结果检索：参考 ValuationDateQuery 的分页与日期范围参数