4.3 KiB
4.3 KiB
Spec: 第一步 - 内容预览功能
ADDED Requirements
预览图展示
- Requirement: 实现左侧预览图的横排展示布局,支持点击放大功能
- Scenario: 用户可以看到内容审核中选定项目的预览图,点击缩略图弹出全屏预览对话框,支持缩放操作
3D模型展示
- Requirement: 实现右侧3D模型的横排展示,集成现有的ModelViewer组件
- Scenario: 用户可以看到对应的3D模型预览,模型支持旋转、缩放等交互操作,使用demo/model.glb作为示例
拆件按钮功能
- Requirement: 添加拆件按钮,点击后进入第二步拆件结果展示
- Scenario: 用户在预览完图片和模型后,点击拆件按钮触发拆件流程,系统显示加载状态并进入下一步
响应式布局
- Requirement: 实现桌面端横排布局,平板端和移动端垂直堆叠布局
- Scenario: 在不同屏幕尺寸下,预览图和模型能够合理适配屏幕空间,保证可读性和交互性
技术实现细节
布局结构
<div class="preview-step-content">
<div class="preview-layout">
<div class="preview-images">
<img
:src="previewImageUrl"
class="preview-thumbnail"
@click="openImagePreview"
alt="预览图"
/>
</div>
<div class="model-viewer-container">
<ModelViewer
:model-url="modelUrl"
:show-controls="true"
style="height: 400px; width: 100%;"
/>
</div>
</div>
<div class="step-actions">
<el-button
type="primary"
size="large"
@click="startDisassembly"
:loading="disassemblyLoading"
>
{{ t('disassembly.actions.startDisassembly') }}
</el-button>
</div>
</div>
图片预览对话框
const openImagePreview = () => {
previewImageVisible.value = true
}
// 使用现有的预览对话框组件
// 通过currentImage和imageScale进行控制
样式实现
.preview-layout {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
margin-bottom: 32px;
}
.preview-images {
display: flex;
justify-content: center;
align-items: center;
background: #f8fafc;
border-radius: 8px;
padding: 16px;
}
.preview-thumbnail {
max-width: 100%;
max-height: 400px;
border-radius: 8px;
cursor: pointer;
transition: transform 200ms ease;
}
.preview-thumbnail:hover {
transform: scale(1.02);
}
/* 平板端适配 */
@media (max-width: 1024px) {
.preview-layout {
grid-template-columns: 1fr;
gap: 16px;
}
}
/* 移动端适配 */
@media (max-width: 768px) {
.preview-layout {
margin-bottom: 24px;
}
.preview-images,
.model-viewer-container {
padding: 12px;
}
}
数据流设计
初始数据加载
const loadPreviewData = async () => {
try {
// 从路由参数获取内容ID
const contentId = route.params.id
// 加载预览图和模型数据
previewImageUrl.value = `/api/content/${contentId}/preview`
modelUrl.value = `/api/content/${contentId}/model`
// 如果没有对应内容,使用demo资源
if (!previewImageUrl.value) {
previewImageUrl.value = '/src/assets/demo/suoluetu.png'
}
if (!modelUrl.value) {
modelUrl.value = '/src/assets/demo/model.glb'
}
} catch (error) {
ElMessage.error(t('common.loadFailed'))
}
}
拆件流程启动
const startDisassembly = async () => {
try {
disassemblyLoading.value = true
// 调用拆件API(用户后续实现)
// await callDisassemblyAPI(contentId)
// 模拟加载时间
await new Promise(resolve => setTimeout(resolve, 2000))
// 更新步骤状态
updateStepStatus(1, 'completed')
updateStepStatus(2, 'current')
workflowState.currentStep = 2
// 清空第二步可能存在的数据
overrideDownstreamSteps(2)
} catch (error) {
ElMessage.error(t('disassembly.errors.disassemblyFailed'))
} finally {
disassemblyLoading.value = false
}
}
验证标准
- 预览图能够正确加载和显示
- 点击预览图能够弹出放大对话框
- 3D模型能够正确渲染和交互
- 拆件按钮能够正常触发流程
- 响应式布局在各种设备上正常工作
- 加载状态和错误处理完善