228 lines
8.3 KiB
Markdown
228 lines
8.3 KiB
Markdown
# 数据契约
|
||
|
||
<cite>
|
||
**本文档中引用的文件**
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts)
|
||
- [data_builder.py](file://backend/data_builder.py)
|
||
- [mock-data.json](file://src/mock-data.json)
|
||
- [mock-cashflow.json](file://src/mock-cashflow.json)
|
||
- [Root.tsx](file://src/Root.tsx)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [简介](#简介)
|
||
2. [项目结构](#项目结构)
|
||
3. [核心组件](#核心组件)
|
||
4. [架构概述](#架构概述)
|
||
5. [详细组件分析](#详细组件分析)
|
||
6. [依赖分析](#依赖分析)
|
||
7. [性能考虑](#性能考虑)
|
||
8. [故障排除指南](#故障排除指南)
|
||
9. [结论](#结论)
|
||
|
||
## 简介
|
||
本文件详细描述了视频渲染系统的数据契约,重点是 `render-props-types.ts` 中定义的 `RenderProps` 接口及其 Zod 验证模式。该数据契约作为 Python 后端(数据生成器)与 Remotion 前端(视频渲染器)之间的通信桥梁,确保了 `render_props.json` 文件在运行时的类型安全。文档还结合 `backend/data_builder.py` 的输出结构,说明了如何同步维护前后端的数据模型。
|
||
|
||
## 项目结构
|
||
该项目采用前后端分离架构,前端使用 Remotion 框架进行视频渲染,后端使用 Python 生成渲染所需的数据。核心数据契约定义在 `frontend/src/render-props-types.ts` 中,而后端数据生成逻辑位于 `backend/data_builder.py`。
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "前端 (Remotion)"
|
||
A[render-props-types.ts] --> B[Root.tsx]
|
||
B --> C[CashFlowChart]
|
||
B --> D[LifePlanChart]
|
||
B --> E[DualChartView]
|
||
end
|
||
subgraph "后端 (Python)"
|
||
F[data_builder.py] --> G[FinancialSimulator]
|
||
G --> H[build_chart_data]
|
||
end
|
||
F --> |生成 render_props.json| A
|
||
```
|
||
|
||
**图表来源**
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L250)
|
||
- [data_builder.py](file://backend/data_builder.py#L1-L200)
|
||
|
||
**章节来源**
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L250)
|
||
- [data_builder.py](file://backend/data_builder.py#L1-L200)
|
||
|
||
## 核心组件
|
||
`RenderProps` 接口是整个系统的核心数据模型,它定义了渲染视频所需的所有数据结构,包括元信息、图表数据、脚本和资产引用。`YearlySnapshot` 和 `CashFlowData` 是构成财务模拟数据的基础类型,而 `ScriptSegment` 和 `AssetCollection` 则用于控制视频的叙事和媒体资源。
|
||
|
||
**章节来源**
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L18-L230)
|
||
|
||
## 架构概述
|
||
系统的数据流始于后端的 `data_builder.py`。`FinancialSimulator` 类根据用户输入的财务参数(如当前年龄、退休年龄、资产、收入和支出)模拟未来每年的财务状况,生成 `YearlySnapshot` 数据。然后,`build_cashflow_data` 函数将这些数据转换为更详细的 `CashFlowData` 格式。最终,`build_chart_data` 函数将这些数据组织成 `render_props.json` 的标准格式,供前端使用。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Backend as "后端 (data_builder.py)"
|
||
participant Frontend as "前端 (Remotion)"
|
||
participant Data as "render_props.json"
|
||
Backend->>Backend : FinancialSimulator.simulate_timeline()
|
||
Backend->>Backend : build_cashflow_data()
|
||
Backend->>Backend : build_chart_data()
|
||
Backend->>Data : 生成 render_props.json
|
||
Data->>Frontend : 加载数据
|
||
Frontend->>Frontend : validateRenderProps() 验证
|
||
Frontend->>Frontend : 渲染视频
|
||
```
|
||
|
||
**图表来源**
|
||
- [data_builder.py](file://backend/data_builder.py#L15-L200)
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L237-L250)
|
||
|
||
## 详细组件分析
|
||
|
||
### RenderProps 接口分析
|
||
`RenderProps` 接口是数据契约的顶层结构,它包含四个主要部分:`meta`、`charts`、`script` 和 `assets`。
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class RenderProps {
|
||
+meta : Meta
|
||
+charts : Charts
|
||
+script : ScriptSegment[]
|
||
+assets : AssetCollection
|
||
}
|
||
class Meta {
|
||
+title : string
|
||
+currencyUnit : string
|
||
+duration : number
|
||
+clientName? : string
|
||
+generatedAt? : string
|
||
}
|
||
class Charts {
|
||
+assetDepletion : AssetDepletionChartData
|
||
+cashFlow : CashFlowChartData
|
||
}
|
||
class AssetDepletionChartData {
|
||
+timeline : YearlySnapshot[]
|
||
}
|
||
class CashFlowChartData {
|
||
+timeline : CashFlowData[]
|
||
}
|
||
class YearlySnapshot {
|
||
+currencyUnit : string
|
||
+startYear : number
|
||
}
|
||
class CashFlowData {
|
||
+currencyUnit : string
|
||
}
|
||
RenderProps --> Meta
|
||
RenderProps --> Charts
|
||
Charts --> AssetDepletionChartData
|
||
Charts --> CashFlowChartData
|
||
AssetDepletionChartData --> YearlySnapshot
|
||
CashFlowChartData --> CashFlowData
|
||
```
|
||
|
||
**图表来源**
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L117-L134)
|
||
|
||
### 核心数据类型分析
|
||
`YearlySnapshot` 和 `CashFlowData` 是系统中最核心的两个数据类型,它们分别代表了资产消耗和现金流的年度数据。
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class YearlySnapshot {
|
||
+year : number
|
||
+ages_rep : number
|
||
+ages_spouse? : number
|
||
+financials_income : number
|
||
+financials_expenditure : number
|
||
+financials_assetBalance : number
|
||
+events? : string[]
|
||
+isCritical? : boolean
|
||
}
|
||
class CashFlowData {
|
||
+year : number
|
||
+age : number
|
||
+income_total : number
|
||
+expenses_living : number
|
||
+expenses_housing : number
|
||
+expenses_education : number
|
||
+expenses_tax : number
|
||
+expenses_event : number
|
||
+totalExpense? : number
|
||
+netCashFlow? : number
|
||
+assetBalance? : number
|
||
}
|
||
YearlySnapshot --> "1" AssetDepletionChartData : "包含"
|
||
CashFlowData --> "1" CashFlowChartData : "包含"
|
||
```
|
||
|
||
**图表来源**
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L18-L49)
|
||
|
||
### 脚本与资产分析
|
||
`ScriptSegment` 定义了视频的叙事结构,而 `AssetCollection` 则管理了视频中使用的所有媒体资源。
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class ScriptSegment {
|
||
+id : number
|
||
+text : string
|
||
+duration : number
|
||
+type : ScriptSegmentType
|
||
+assetUrl? : string
|
||
+chartSync? : ChartSync
|
||
}
|
||
class ChartSync {
|
||
+chartId : "assetDepletion" | "cashFlow"
|
||
+highlightYear? : number
|
||
+animationStart? : number
|
||
}
|
||
class AssetCollection {
|
||
+broll : Record<string, string>
|
||
+videoClips : VideoClipReference[]
|
||
+ttsAudio? : string
|
||
}
|
||
class VideoClipReference {
|
||
+id : string
|
||
+sourcePath : string
|
||
+startTime : number
|
||
+duration : number
|
||
+outputPath? : string
|
||
}
|
||
ScriptSegment --> ChartSync
|
||
AssetCollection --> VideoClipReference
|
||
```
|
||
|
||
**图表来源**
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L81-L111)
|
||
|
||
## 依赖分析
|
||
该系统的关键依赖是 `zod` 库,它用于在运行时验证 `render_props.json` 的数据结构。`render-props-types.ts` 中的 `RenderPropsSchema` 确保了从后端传来的数据符合预期的格式,防止了因数据错误导致的渲染失败。
|
||
|
||
```mermaid
|
||
graph TD
|
||
A[render-props-types.ts] --> B[zod]
|
||
B --> C[RenderPropsSchema]
|
||
C --> D[validateRenderProps]
|
||
C --> E[isRenderProps]
|
||
F[data_builder.py] --> A
|
||
A --> G[Root.tsx]
|
||
```
|
||
|
||
**图表来源**
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L12-L250)
|
||
|
||
**章节来源**
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L12-L250)
|
||
|
||
## 性能考虑
|
||
Zod 的运行时验证虽然增加了少量开销,但极大地提高了系统的健壮性。对于大型数据集,可以考虑在开发环境中进行严格验证,在生产环境中使用 `isRenderProps` 进行轻量级检查,以平衡安全性和性能。
|
||
|
||
## 故障排除指南
|
||
当视频渲染失败时,最常见的原因是 `render_props.json` 数据格式错误。应首先使用 `validateRenderProps` 函数检查数据的有效性。如果验证失败,Zod 会提供详细的错误信息,指出具体是哪个字段不符合预期。
|
||
|
||
**章节来源**
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L241-L250)
|
||
|
||
## 结论
|
||
该视频渲染系统的数据契约设计清晰,通过 TypeScript 接口和 Zod 模式实现了前后端之间的强类型通信。`RenderProps` 接口及其子类型构成了一个完整、可扩展的数据模型,能够支持复杂的财务模拟和视频叙事。通过 `validateRenderProps` 和 `isRenderProps` 辅助函数,系统在运行时具备了强大的数据验证能力,确保了渲染过程的稳定性和可靠性。 |