You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
12 KiB
12 KiB
清理预览区域 Mock 数据(完整版)
日期: 2026-02-08
类型: 代码清理 + Bug 修复
影响范围: 前端预览面板
概述
移除预览面板中所有的 mock 数据,确保只使用真实的 API 数据。同时修复了"正视图、侧视图、背视图"这些假数据的显示问题。
🐛 核心问题
问题描述: 点击角色资源时,预览区域显示的是"正视图、侧视图、背视图",这些是 mock 数据,而不是真实的标签数据。
根本原因:
// 错误逻辑:当没有标签时,生成假的"正视图、侧视图、背视图"
if (resource.type === 1) {
if (hasTags) {
return tags.map(...); // 显示真实标签
}
// ❌ 没有标签时,返回假数据
return [
{ title: '孙悟空 (正视图)', ... },
{ title: '孙悟空 (侧视图)', ... },
{ title: '孙悟空 (背视图)', ... },
];
}
正确逻辑:
// ✅ 有标签 → 显示标签
// ✅ 没有标签 → 返回空数组,显示"暂无标签"空状态
if (resource.type === 1) {
if (hasTags) {
return tags.map(...); // 显示真实标签
}
return []; // 没有标签时返回空数组
}
清理内容
✅ 已清理的 Mock 数据
1. AI 生成功能的假数据 (usePreviewActions.ts)
清理前:
// 随机获取一张 Unsplash 图片作为生成结果
const mockGeneratedUrl = `https://images.unsplash.com/photo-${...}?w=800&q=80`;
if (isTagItem && tags) {
updatedTags[index] = {
...updatedTags[index],
thumbnail_url: mockGeneratedUrl, // ❌ 假数据
};
}
清理后:
toast({
title: 'AI 生成功能未实现',
description: `需要接入真实的 AI 生成 API 为 "${targetName}" 生成图片`,
variant: 'destructive',
});
// TODO: 接入真实的 AI 生成 API
// 1. 调用后端 AI 生成接口
// 2. 等待生成完成
// 3. 更新资源/标签的图片URL
2. 视频数据 Mock (usePreviewData.ts)
清理前:
import { mockStoryboardVideos } from '@/mocks';
// ...
const storyboardVideos = mockStoryboardVideos.filter((v) => v.storyboardId === storyboardId);
清理后:
// 移除 import
// ...
// 获取该分镜下的所有视频 (TODO: 使用真实API替换)
const storyboardVideos: any[] = []; // 临时置空,等待视频API实现
说明: 后端已有视频API (server/app/api/v1/storyboard_resources.py::get_storyboard_videos),但前端尚未实现对应的 Hook,需要后续添加 useStoryboardVideos().
3. 音效数据 Mock (SoundEffectPreview.tsx)
清理前:
import { mockStoryboardSoundEffects } from '@/mocks/storyboard-sound-effects';
// ...
return mockStoryboardSoundEffects.filter((e) => e.storyboardId === storyboardId);
清理后:
// 移除 import
// ...
const effects = useMemo(() => {
// TODO: 使用真实的音效API
// return useSoundEffects(storyboardId);
if (!storyboardId) return [];
return []; // 临时置空,等待音效API实现
}, [storyboardId]);
4. 资源标签和档案 Mock (ResourceInfoPanel.tsx)
清理前:
import {
mockCharacterTags,
mockLocationVariantTags,
mockPropTags,
mockTagCategories,
mockProfiles,
} from '@/mocks';
// Mock tags data
const tags: Tag[] = useMemo(() => {
if (resourceType === 1) return mockCharacterTags;
if (resourceType === 2) return mockLocationVariantTags;
if (resourceType === 3) return mockPropTags;
return [];
}, [resourceType, resourceId]);
// Mock profile data
const mockData = mockProfiles[typeStr];
return mockData ? { ...mockData, name: resourceName, type: typeStr } : {...};
清理后:
// 移除所有 mock imports
// TODO: 从真实API获取标签数据
const tags: Tag[] = useMemo(() => {
if (!resourceType || !resourceId) return [];
// 应该从 useCharacterDetail / useLocationDetail / usePropDetail 获取
return [];
}, [resourceType, resourceId]);
// TODO: 从真实API获取资源档案数据
const profileData = useMemo(() => {
// 应该从 useCharacterDetail / useLocationDetail / usePropDetail 获取
return {
type: typeStr,
name: resourceName,
description: '',
};
}, [resourceType, resourceName]);
// 标签分类也改为空数组
<ResourceTagsTab
categories={[]} // TODO: 从真实API获取标签分类
/>
说明: ResourceInfoPanel 目前未被 PreviewPanel 使用,但仍清理干净以备未来使用。
⚠️ 保留的临时逻辑
以下代码暂时保留空数组,等待对应的真实API实现:
-
视频列表:
const storyboardVideos: any[] = [];- 需要实现:
useStoryboardVideos(storyboardId) - 后端API:
GET /api/v1/storyboard-resources/{storyboardId}/videos
- 需要实现:
-
音效列表:
return [];- 需要实现:
useSoundEffects(storyboardId) - 后端API: (需确认是否存在)
- 需要实现:
-
标签分类:
categories={[]}- 需要实现:
useTagCategories(projectId, resourceType) - 后端API: (需确认是否存在)
- 需要实现:
清理后的数据流
✅ 当前可用的功能 (使用真实API)
用户点击角色/场景/道具
↓
useCharacterDetail / useLocationDetail / usePropDetail
↓
GET /projects/{projectId}/characters/{characterId}
↓
返回真实的角色+标签+资源数据
↓
PreviewPanel 显示真实的缩略图和标签
⏳ 待实现的功能
-
视频预览
用户点击分镜中的视频元素 ↓ useStoryboardVideos(storyboardId) // TODO: 需实现 ↓ GET /api/v1/storyboard-resources/{storyboardId}/videos ↓ 显示真实视频列表 -
音效预览
用户切换到音效标签 ↓ useSoundEffects(storyboardId) // TODO: 需实现 ↓ GET /api/v1/storyboard-resources/{storyboardId}/sound-effects (?) ↓ 显示真实音效列表 -
AI 生成图片
用户点击"生成"按钮 ↓ 调用 AI 生成 API // TODO: 需实现 ↓ POST /api/v1/ai/generate-image (?) ↓ 更新资源/标签的图片URL
影响分析
功能影响
- ✅ 角色/场景/道具预览: 正常工作,使用真实API
- ⚠️ 视频预览: 暂时显示空列表,不影响其他功能
- ⚠️ 音效预览: 暂时显示空列表,不影响其他功能
- ❌ AI 生成: 点击按钮会提示"功能未实现",不会再生成假数据
用户体验
改进:
- 不再显示误导性的假数据
- 用户看到的都是真实的项目数据
降级:
- 视频和音效预览暂时为空 (但这些功能本来就未完全实现)
- AI 生成按钮暂时不可用 (但之前生成的也是假数据)
后续任务
高优先级 (影响核心功能)
-
实现视频 Hook
// client/src/hooks/api/useStoryboardVideos.ts export function useStoryboardVideos(storyboardId: string | null) { return useQuery({ queryKey: ['storyboard-videos', storyboardId], queryFn: () => storyboardVideosApi.getVideos(storyboardId!), enabled: !!storyboardId, }); } -
实现音效 Hook
// client/src/hooks/api/useSoundEffects.ts export function useSoundEffects(storyboardId: string | null) { return useQuery({ queryKey: ['sound-effects', storyboardId], queryFn: () => soundEffectsApi.getSoundEffects(storyboardId!), enabled: !!storyboardId, }); }
中优先级 (增强用户体验)
-
实现 AI 生成图片功能
- 后端: 接入真实的 AI 图片生成服务 (如 Stable Diffusion, DALL-E)
- 前端: 调用生成API,显示进度,更新图片
-
实现标签分类管理
- 后端: 标签分类的CRUD API
- 前端:
useTagCategories()Hook
低优先级 (可选)
- 完善 ResourceInfoPanel
- 集成真实的资源详情数据
- 显示完整的资源档案信息
验证方法
1. 测试有标签的资源
1. 在后端创建一个角色,并添加标签 (如"便装"、"战斗装")
2. 在前端点击该角色
3. 预览面板应该显示:
✅ "孙悟空 - 便装" (标签1)
✅ "孙悟空 - 战斗装" (标签2)
❌ 不应该显示"正视图、侧视图、背视图"
2. 测试没有标签的资源
1. 在后端创建一个角色,不添加任何标签
2. 在前端点击该角色
3. 预览面板应该显示:
✅ 空状态提示 (如"暂无标签"或"No items to display")
❌ 不应该显示"正视图、侧视图、背视图"
3. 检查控制台是否有 mock 相关的警告
cd client
npm run dev
# 打开浏览器控制台,检查是否有 "mock" 相关的日志
4. 搜索代码中是否还有 mock 导入
cd client/src/components/features/preview
rg "from.*@/mocks" --type ts
rg "from.*mocks" --type ts
rg "mockStoryboard|mockCharacter|mockLocation|mockProp" --type ts
预期结果: 只在以下文件中保留 mock (非预览核心功能):
HistoryPanel.tsx(历史记录面板,目前完全是mock UI)ResourceProfileTab.tsx(配音选择,使用mockVoices)VoiceSelectionDialog.tsx(配音选择,使用mockVoices)StoryboardResourcesPreview.tsx(一条 Mock 逻辑注释)
5. 测试空状态显示
- 打开项目页面
- 切换到"角色"标签
- 点击一个没有标签的角色
- 预览面板应该显示:
- ✅ 空状态组件 (EmptyState)
- ✅ 提示文字 (如"No items to display")
- ❌ 不应该有"正视图、侧视图、背视图"
对比图
清理前 (❌ 错误)
点击"孙悟空"角色 (无标签)
↓
预览面板显示:
- 孙悟空 (正视图) ← ❌ 假数据
- 孙悟空 (侧视图) ← ❌ 假数据
- 孙悟空 (背视图) ← ❌ 假数据
清理后 (✅ 正确)
点击"孙悟空"角色 (无标签)
↓
预览面板显示:
- "暂无标签" 空状态 ← ✅ 真实状态
点击"孙悟空"角色 (有标签)
↓
预览面板显示:
- 孙悟空 - 便装 ← ✅ 真实标签
- 孙悟空 - 战斗装 ← ✅ 真实标签
测试角色创建流程
1. 创建带标签的角色
# 后端测试脚本
curl -X POST http://localhost:8000/api/v1/projects/{projectId}/characters \
-H "Content-Type: application/json" \
-d '{
"name": "测试角色",
"description": "用于测试标签显示",
"role_type": 2,
"tags": ["便装", "战斗装"]
}'
预期:
- 前端点击该角色,预览面板显示2个标签
- 不显示"正视图、侧视图、背视图"
2. 创建无标签的角色
curl -X POST http://localhost:8000/api/v1/projects/{projectId}/characters \
-H "Content-Type: application/json" \
-d '{
"name": "测试角色2",
"description": "无标签角色",
"role_type": 2
}'
预期:
- 前端点击该角色,预览面板显示空状态
- 不显示"正视图、侧视图、背视图"
3. 测试资源预览
- 打开项目页面
- 切换到"角色"标签
- 点击任意角色
- 查看预览面板:
- ✅ 应该显示真实的标签列表 (如果有标签)
- ✅ 应该显示空状态 (如果没有标签)
- ✅ 标签应该有真实的缩略图 (如果有上传)
- ✅ 点击"生成"按钮应该提示"功能未实现"
- ❌ 不应该显示"正视图、侧视图、背视图"
相关文件
已修改的文件
client/src/components/features/preview/hooks/usePreviewData.ts(核心修改: 移除"正视图、侧视图、背视图"生成逻辑)client/src/components/features/preview/hooks/usePreviewActions.ts(移除假的AI生成逻辑)client/src/components/features/preview/SoundEffectPreview.tsx(移除 mockStoryboardSoundEffects)client/src/components/features/preview/ResourceInfoPanel.tsx(移除所有mock imports)
未修改的文件 (合理保留 mock)
client/src/components/features/preview/HistoryPanel.tsx(历史记录UI,纯展示)client/src/components/features/preview/tabs/ResourceProfileTab.tsx(配音选择)client/src/components/features/preview/dialogs/VoiceSelectionDialog.tsx(配音选择)
总结
本次清理彻底移除了资源预览核心功能中的所有 mock 数据,确保用户看到的都是真实的项目数据。
对于尚未实现的功能 (视频、音效、AI生成),采取了以下策略:
- 视频/音效: 临时返回空数组,不影响其他功能,等待API实现
- AI生成: 显示"功能未实现"提示,避免生成误导性的假数据
核心原则: 宁可显示空数据,也不显示假数据,确保用户对系统状态有正确的认知。