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

4.3 KiB
Raw Blame History

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模型能够正确渲染和交互
  • 拆件按钮能够正常触发流程
  • 响应式布局在各种设备上正常工作
  • 加载状态和错误处理完善