feat: 功能优化
This commit is contained in:
@@ -1,143 +0,0 @@
|
||||
# Change: 重构 IdentifyFace.vue 为 Hooks 架构
|
||||
|
||||
## Why
|
||||
当前 `IdentifyFace.vue` 组件存在以下问题:
|
||||
1. **代码耦合严重**: 视频处理、音频生成、数字人生成逻辑全部混合在一个800+行的组件中
|
||||
2. **状态管理混乱**: 4个不同的状态对象(videoState、identifyState、audioState、materialValidation)相互依赖,难以维护
|
||||
3. **复用性差**: 核心逻辑无法复用,测试困难
|
||||
4. **逻辑不清晰**: 业务流程分散,难以追踪和调试
|
||||
|
||||
## What Changes
|
||||
将 monolithic 组件重构为基于 Vue Composition API 的 hooks 架构:
|
||||
|
||||
### 新增 Hooks
|
||||
1. **useVoiceGeneration**
|
||||
- 封装语音生成和校验逻辑
|
||||
- 管理音频状态和验证规则
|
||||
- 响应式变量:ttsText, speechRate, selectedVoiceMeta, audioState
|
||||
|
||||
2. **useDigitalHumanGeneration**
|
||||
- 封装数字人视频生成逻辑
|
||||
- 管理视频上传、素材库选择、人脸识别
|
||||
- 响应式变量:videoState, identifyState, materialValidation
|
||||
|
||||
3. **useIdentifyFaceController**
|
||||
- 协调 useVoiceGeneration 和 useDigitalHumanGeneration
|
||||
- 实现主业务流程:视频选择 → 人脸识别 → 配音生成 → 数字人生成
|
||||
- 确保先配音校验再生成的业务规则
|
||||
|
||||
### 重构后的文件结构
|
||||
```
|
||||
frontend/app/web-gold/src/views/kling/
|
||||
├── IdentifyFace.vue # 简化后的视图层
|
||||
├── hooks/
|
||||
│ ├── useVoiceGeneration.ts # 语音生成 Hook
|
||||
│ ├── useDigitalHumanGeneration.ts # 数字人生成 Hook
|
||||
│ └── useIdentifyFaceController.ts # Controller Hook
|
||||
└── types/
|
||||
└── identify-face.ts # 类型定义
|
||||
```
|
||||
|
||||
## 架构设计
|
||||
|
||||
### 数据流架构图
|
||||
```
|
||||
┌─────────────────────┐
|
||||
│ IdentifyFace.vue │ 视图层(仅负责UI渲染和事件绑定)
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────┐
|
||||
│ useIdentifyFace │ Controller Hook(协调业务逻辑)
|
||||
│ Controller │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
├──────────────────────┬──────────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
||||
│ useVoice │ │ useDigitalHuman │ │ 外部依赖 │
|
||||
│ Generation │ │ Generation │ │ - VoiceService │
|
||||
│ │ │ │ │ - Kling API │
|
||||
│ ├─ 音频生成 │ │ ├─ 视频处理 │ │ - 文件上传 │
|
||||
│ ├─ 时长校验 │ │ ├─ 人脸识别 │ └──────────────────┘
|
||||
│ └─ 音频验证 │ │ └─ 素材校验 │
|
||||
└──────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
### 核心接口设计
|
||||
|
||||
#### useVoiceGeneration Hook
|
||||
```typescript
|
||||
interface UseVoiceGeneration {
|
||||
// 响应式状态
|
||||
ttsText: Ref<string>
|
||||
speechRate: Ref<number>
|
||||
selectedVoiceMeta: Ref<VoiceMeta | null>
|
||||
audioState: Ref<AudioState>
|
||||
|
||||
// 计算属性
|
||||
canGenerateAudio: ComputedRef<boolean>
|
||||
suggestedMaxChars: ComputedRef<number>
|
||||
|
||||
// 方法
|
||||
generateAudio: () => Promise<void>
|
||||
parseAudioDuration: (base64Data: string) => Promise<number>
|
||||
validateAudioDuration: () => boolean
|
||||
resetAudioState: () => void
|
||||
}
|
||||
```
|
||||
|
||||
#### useDigitalHumanGeneration Hook
|
||||
```typescript
|
||||
interface UseDigitalHumanGeneration {
|
||||
// 响应式状态
|
||||
videoState: Ref<VideoState>
|
||||
identifyState: Ref<IdentifyState>
|
||||
materialValidation: Ref<MaterialValidation>
|
||||
|
||||
// 计算属性
|
||||
faceDuration: ComputedRef<number>
|
||||
canGenerate: ComputedRef<boolean>
|
||||
|
||||
// 方法
|
||||
handleFileUpload: (file: File) => Promise<void>
|
||||
handleVideoSelect: (video: Video) => void
|
||||
performFaceRecognition: () => Promise<void>
|
||||
validateMaterialDuration: (videoMs: number, audioMs: number) => boolean
|
||||
resetVideoState: () => void
|
||||
}
|
||||
```
|
||||
|
||||
#### useIdentifyFaceController Hook
|
||||
```typescript
|
||||
interface UseIdentifyFaceController {
|
||||
// 组合子 Hooks
|
||||
voiceGeneration: UseVoiceGeneration
|
||||
digitalHuman: UseDigitalHumanGeneration
|
||||
|
||||
// 业务流程方法
|
||||
generateDigitalHuman: () => Promise<void>
|
||||
replaceVideo: () => void
|
||||
|
||||
// UI 辅助方法
|
||||
formatDuration: (seconds: number) => string
|
||||
formatFileSize: (bytes: number) => string
|
||||
}
|
||||
```
|
||||
|
||||
## Impact
|
||||
- **代码质量提升**: 单一职责原则,每个 hook 只负责一个领域
|
||||
- **可测试性增强**: 逻辑解耦,可以独立测试每个 hook
|
||||
- **可维护性提升**: 状态管理清晰,易于调试和修改
|
||||
- **复用性提升**: hooks 可在其它组件中复用
|
||||
|
||||
## Breaking Changes
|
||||
- 重构现有组件,新旧版本不兼容
|
||||
- 需要更新所有引用 IdentifyFace.vue 的路由和测试
|
||||
|
||||
## Migration Plan
|
||||
1. 创建新的 hooks 文件
|
||||
2. 重构 IdentifyFace.vue 使用 hooks
|
||||
3. 验证功能一致性
|
||||
4. 移除旧代码
|
||||
@@ -1,110 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: useVoiceGeneration Hook
|
||||
系统 SHALL 提供 `useVoiceGeneration` Hook,封装所有语音生成相关逻辑。
|
||||
|
||||
#### Scenario: 初始化语音生成状态
|
||||
- **GIVEN** 组件挂载时调用 useVoiceGeneration
|
||||
- **THEN** 返回响应式状态:ttsText(空字符串)、speechRate(1.0)、selectedVoiceMeta(null)、audioState(初始状态)
|
||||
|
||||
#### Scenario: 生成配音
|
||||
- **GIVEN** 用户点击生成配音按钮且 canGenerateAudio 为 true
|
||||
- **WHEN** 调用 generateAudio 方法
|
||||
- **THEN** 执行以下流程:
|
||||
1. 调用 VoiceService.synthesize 生成音频
|
||||
2. 解析音频时长
|
||||
3. 验证音频与人脸区间重合度
|
||||
4. 更新 audioState.generated 和 audioState.durationMs
|
||||
5. 返回成功或失败结果
|
||||
|
||||
#### Scenario: 音频时长校验
|
||||
- **GIVEN** 音频生成完成且有人脸识别数据
|
||||
- **WHEN** 调用 validateAudioDuration
|
||||
- **THEN** 计算音频与人脸区间的重合时长
|
||||
- **AND** 如果重合时长 >= 2000ms,设置 audioState.validationPassed = true
|
||||
- **ELSE** 设置 audioState.validationPassed = false 并显示警告消息
|
||||
|
||||
### Requirement: useDigitalHumanGeneration Hook
|
||||
系统 SHALL 提供 `useDigitalHumanGeneration` Hook,封装所有数字人生成相关逻辑。
|
||||
|
||||
#### Scenario: 处理视频文件上传
|
||||
- **GIVEN** 用户上传视频文件(MP4或MOV格式)
|
||||
- **WHEN** 调用 handleFileUpload 方法
|
||||
- **THEN** 执行以下流程:
|
||||
1. 验证文件格式
|
||||
2. 创建视频预览 URL
|
||||
3. 重置识别状态
|
||||
4. 调用 performFaceRecognition 进行人脸识别
|
||||
5. 更新 videoState 和 identifyState
|
||||
|
||||
#### Scenario: 从素材库选择视频
|
||||
- **GIVEN** 用户点击"从素材库选择"选项
|
||||
- **WHEN** 选择视频并调用 handleVideoSelect
|
||||
- **THEN** 执行以下流程:
|
||||
1. 设置 selectedVideo 到 videoState
|
||||
2. 重置识别状态
|
||||
3. 设置 videoFileId
|
||||
4. 更新 materialValidation.videoDuration
|
||||
5. 触发人脸识别
|
||||
|
||||
#### Scenario: 人脸识别
|
||||
- **GIVEN** 有视频文件或已选择视频
|
||||
- **WHEN** 调用 performFaceRecognition
|
||||
- **THEN** 根据视频来源调用对应API:
|
||||
- 如果是上传文件:调用 uploadAndIdentifyVideo
|
||||
- 如果是素材库:调用 identifyUploadedVideo
|
||||
- **AND** 更新 identifyState:sessionId、faceId、faceStartTime、faceEndTime
|
||||
- **AND** 设置 identifyState.identified = true
|
||||
|
||||
#### Scenario: 素材时长校验
|
||||
- **GIVEN** 有视频时长和音频时长数据
|
||||
- **WHEN** 调用 validateMaterialDuration(videoDurationMs, audioDurationMs)
|
||||
- **THEN** 检查 videoDurationMs > audioDurationMs
|
||||
- **AND** 更新 materialValidation:videoDuration、audioDuration、isValid
|
||||
|
||||
### Requirement: useIdentifyFaceController Hook
|
||||
系统 SHALL 提供 `useIdentifyFaceController` Hook,协调语音生成和数字人生成逻辑。
|
||||
|
||||
#### Scenario: 生成数字人视频
|
||||
- **GIVEN** 所有必需数据已准备(文案、音色、视频、配音校验通过)
|
||||
- **WHEN** 调用 generateDigitalHuman 方法
|
||||
- **THEN** 执行以下流程:
|
||||
1. 检查 canGenerate 为 true
|
||||
2. 如果未识别,先执行人脸识别
|
||||
3. 构建任务数据(taskName、videoFileId、文本、语音参数等)
|
||||
4. 如果有预生成音频,添加到 pre_generated_audio 字段
|
||||
5. 调用 createLipSyncTask 提交任务
|
||||
6. 返回成功或失败结果
|
||||
|
||||
#### Scenario: 确保配音校验顺序
|
||||
- **GIVEN** 用户尝试生成数字人视频
|
||||
- **WHEN** 还未生成配音或校验未通过
|
||||
- **THEN** 阻止生成并提示用户先完成配音生成和校验
|
||||
|
||||
#### Scenario: 更换视频
|
||||
- **GIVEN** 用户点击更换视频按钮
|
||||
- **WHEN** 调用 replaceVideo 方法
|
||||
- **THEN** 重置所有相关状态:
|
||||
- videoState(清空上传文件和选中视频)
|
||||
- identifyState(重置识别结果)
|
||||
- materialValidation(重置校验结果)
|
||||
- audioState(重置音频状态)
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: IdentifyFace.vue 组件重构
|
||||
原始的 monolithic 组件 MUST 被重构为使用 hooks 的轻量级视图层。
|
||||
|
||||
#### Scenario: 视图层职责
|
||||
- **WHEN** IdentifyFace.vue 渲染时
|
||||
- **THEN** 只负责:
|
||||
1. UI 模板渲染(接收 hooks 返回的数据和状态)
|
||||
2. 事件绑定(将用户操作转发给 hooks 的方法)
|
||||
3. 计算属性显示(使用 hooks 提供的 computed 值)
|
||||
- **AND** 不直接包含业务逻辑(全部委托给 hooks)
|
||||
|
||||
#### Scenario: 响应式数据绑定
|
||||
- **GIVEN** hooks 提供的响应式状态
|
||||
- **WHEN** 组件渲染时
|
||||
- **THEN** 通过 v-model 和响应式引用直接绑定到 UI 控件
|
||||
- **AND** 状态变化自动触发 UI 更新
|
||||
@@ -1,85 +0,0 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. 创建类型定义
|
||||
- [ ] 1.1 创建 `types/identify-face.ts` 文件
|
||||
- [ ] 定义 VideoState 接口
|
||||
- [ ] 定义 IdentifyState 接口
|
||||
- [ ] 定义 AudioState 接口
|
||||
- [ ] 定义 MaterialValidation 接口
|
||||
- [ ] 定义 VoiceMeta 接口
|
||||
- [ ] 导出所有类型
|
||||
|
||||
## 2. 实现 useVoiceGeneration Hook
|
||||
- [ ] 2.1 创建 `hooks/useVoiceGeneration.ts`
|
||||
- [ ] 2.1.1 实现响应式状态初始化
|
||||
- [ ] 2.1.2 实现 canGenerateAudio 计算属性
|
||||
- [ ] 2.1.3 实现 suggestedMaxChars 计算属性
|
||||
- [ ] 2.1.4 实现 generateAudio 方法
|
||||
- [ ] 2.1.5 实现 parseAudioDuration 辅助函数
|
||||
- [ ] 2.1.6 实现 validateAudioDuration 方法
|
||||
- [ ] 2.1.7 实现 resetAudioState 方法
|
||||
- [ ] 2.1.8 添加错误处理和用户反馈
|
||||
|
||||
## 3. 实现 useDigitalHumanGeneration Hook
|
||||
- [ ] 3.1 创建 `hooks/useDigitalHumanGeneration.ts`
|
||||
- [ ] 3.1.1 实现响应式状态初始化
|
||||
- [ ] 3.1.2 实现 faceDuration 计算属性
|
||||
- [ ] 3.1.3 实现 canGenerate 计算属性
|
||||
- [ ] 3.1.4 实现 handleFileUpload 方法
|
||||
- [ ] 3.1.5 实现 handleVideoSelect 方法
|
||||
- [ ] 3.1.6 实现 performFaceRecognition 方法
|
||||
- [ ] 3.1.7 实现 validateMaterialDuration 方法
|
||||
- [ ] 3.1.8 实现 resetVideoState 方法
|
||||
- [ ] 3.1.9 实现视频预览 URL 生成
|
||||
- [ ] 3.1.10 添加文件格式验证
|
||||
|
||||
## 4. 实现 useIdentifyFaceController Hook
|
||||
- [ ] 4.1 创建 `hooks/useIdentifyFaceController.ts`
|
||||
- [ ] 4.1.1 组合 useVoiceGeneration 和 useDigitalHumanGeneration
|
||||
- [ ] 4.1.2 实现 generateDigitalHuman 方法
|
||||
- [ ] 4.1.3 实现 replaceVideo 方法
|
||||
- [ ] 4.1.4 实现 formatDuration 辅助函数
|
||||
- [ ] 4.1.5 实现 formatFileSize 辅助函数
|
||||
- [ ] 4.1.6 确保业务流程顺序(先配音校验再生成)
|
||||
- [ ] 4.1.7 添加完整的错误处理
|
||||
|
||||
## 5. 重构 IdentifyFace.vue
|
||||
- [ ] 5.1 重构 `IdentifyFace.vue`
|
||||
- [ ] 5.1.1 简化模板,移除业务逻辑
|
||||
- [ ] 5.1.2 使用 useIdentifyFaceController hook
|
||||
- [ ] 5.1.3 绑定响应式状态到 UI
|
||||
- [ ] 5.1.4 绑定事件处理器
|
||||
- [ ] 5.1.5 保留样式(保持 UI 一致性)
|
||||
- [ ] 5.1.6 优化计算属性使用
|
||||
|
||||
## 6. 验证和测试
|
||||
- [ ] 6.1 功能验证
|
||||
- [ ] 6.1.1 测试视频上传流程
|
||||
- [ ] 6.1.2 测试素材库选择流程
|
||||
- [ ] 6.1.3 测试人脸识别流程
|
||||
- [ ] 6.1.4 测试配音生成流程
|
||||
- [ ] 6.1.5 测试时长校验逻辑
|
||||
- [ ] 6.1.6 测试数字人生成流程
|
||||
- [ ] 6.1.7 测试更换视频流程
|
||||
- [ ] 6.2 边界情况测试
|
||||
- [ ] 6.2.1 测试不支持的文件格式
|
||||
- [ ] 6.2.2 测试网络错误处理
|
||||
- [ ] 6.2.3 测试空数据场景
|
||||
- [ ] 6.2.4 测试快速连续操作
|
||||
|
||||
## 7. 清理和优化
|
||||
- [ ] 7.1 移除旧代码
|
||||
- [ ] 7.1.1 删除原有的状态管理代码
|
||||
- [ ] 7.1.2 删除原有的业务逻辑方法
|
||||
- [ ] 7.1.3 删除重复的辅助函数
|
||||
- [ ] 7.2 代码质量检查
|
||||
- [ ] 7.2.1 添加 JSDoc 注释
|
||||
- [ ] 7.2.2 优化类型定义
|
||||
- [ ] 7.2.3 统一代码风格
|
||||
- [ ] 7.2.4 检查未使用的导入
|
||||
|
||||
## 8. 文档更新
|
||||
- [ ] 8.1 更新 README 或相关文档
|
||||
- [ ] 8.1.1 说明新的架构设计
|
||||
- [ ] 8.1.2 添加 Hook 使用示例
|
||||
- [ ] 8.1.3 说明迁移注意事项
|
||||
Reference in New Issue
Block a user