144 lines
5.3 KiB
Markdown
144 lines
5.3 KiB
Markdown
|
|
# 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. 移除旧代码
|