deotalandAi/openspec/changes/create-disassembly-workflow/specs/preview-step/spec.md

178 lines
4.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.

# Spec: 第一步 - 内容预览功能
## ADDED Requirements
### 预览图展示
- **Requirement**: 实现左侧预览图的横排展示布局,支持点击放大功能
- **Scenario**: 用户可以看到内容审核中选定项目的预览图,点击缩略图弹出全屏预览对话框,支持缩放操作
### 3D模型展示
- **Requirement**: 实现右侧3D模型的横排展示集成现有的ModelViewer组件
- **Scenario**: 用户可以看到对应的3D模型预览模型支持旋转、缩放等交互操作使用demo/model.glb作为示例
### 拆件按钮功能
- **Requirement**: 添加拆件按钮,点击后进入第二步拆件结果展示
- **Scenario**: 用户在预览完图片和模型后,点击拆件按钮触发拆件流程,系统显示加载状态并进入下一步
### 响应式布局
- **Requirement**: 实现桌面端横排布局,平板端和移动端垂直堆叠布局
- **Scenario**: 在不同屏幕尺寸下,预览图和模型能够合理适配屏幕空间,保证可读性和交互性
## 技术实现细节
### 布局结构
```html
<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>
```
### 图片预览对话框
```javascript
const openImagePreview = () => {
previewImageVisible.value = true
}
// 使用现有的预览对话框组件
// 通过currentImage和imageScale进行控制
```
### 样式实现
```css
.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;
}
}
```
## 数据流设计
### 初始数据加载
```javascript
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'))
}
}
```
### 拆件流程启动
```javascript
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模型能够正确渲染和交互
- 拆件按钮能够正常触发流程
- 响应式布局在各种设备上正常工作
- 加载状态和错误处理完善