Files
sionrui/openspec/changes/refactor-identify-face-hooks/proposal.md
sion123 36195ea55a feat: 重构 IdentifyFace.vue 为 Hooks 架构
- 新增 hooks/ 目录,包含三个专用 Hook:
  * useVoiceGeneration - 语音生成和校验逻辑
  * useDigitalHumanGeneration - 数字人视频生成逻辑
  * useIdentifyFaceController - 协调两个子 Hook 的控制器

- 新增 types/identify-face.ts 完整类型定义

- 重构 IdentifyFace.vue 使用 hooks 架构:
  * 视图层与业务逻辑分离
  * 状态管理清晰化
  * 模块解耦,逻辑清晰

- 遵循单一职责原则,每个 Hook 只负责一个领域
- 提升代码可测试性和可维护性
- 支持两种视频素材来源:素材库选择和直接上传
- 实现语音生成优先校验的业务规则

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-28 00:19:17 +08:00

144 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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. 移除旧代码