Files
AIGC/demo/SINGLE_PAGE_EXPERIENCE.md
AIGC Developer 8c55f9f376 feat: 完成代码逻辑错误修复和任务清理系统实现
主要更新:
- 修复了所有主要的代码逻辑错误
- 实现了完整的任务清理系统
- 添加了系统设置页面的任务清理管理功能
- 修复了API调用认证问题
- 优化了密码加密和验证机制
- 统一了错误处理模式
- 添加了详细的文档和测试工具

新增功能:
- 任务清理管理界面
- 任务归档和清理日志
- API监控和诊断工具
- 完整的测试套件

技术改进:
- 修复了Repository方法调用错误
- 统一了模型方法调用
- 改进了类型安全性
- 优化了代码结构和可维护性
2025-10-27 10:46:49 +08:00

8.8 KiB
Raw Blame History

单页面任务执行体验优化

🎯 功能概述

根据用户需求,我们优化了任务提交后的用户体验,实现了单页面更新模式

  • 任务提交成功后,页面保持在当前页面
  • 只是中间的内容区域发生变化,显示任务进度和结果
  • 不需要跳转到其他页面

📱 用户体验流程

1. 提交前状态

  • 左侧:输入框和设置面板
  • 右侧:显示"开始创作您的第一个作品吧!"的提示

2. 任务提交后

  • 页面保持在当前页面,不跳转
  • 右侧内容区域动态更新,显示:
    • 任务状态标题(如"处理中"、"已完成"
    • 任务创建时间(如"文生视频 2025年10月17日 14:28"
    • 任务描述内容
    • 视频预览区域

3. 生成中状态

  • 显示"生成中"文字
  • 显示进度条动画
  • 提供"取消任务"按钮

4. 完成状态

  • 显示生成的视频播放器
  • 提供"做同款"和"下载视频"按钮
  • 视频可以正常播放和控制

5. 失败状态

  • 显示失败图标和提示
  • 提供"重新生成"按钮

🔧 技术实现

前端页面更新

文生视频页面 (TextToVideoCreate.vue)

<!-- 右侧预览区域 -->
<div class="right-panel">
  <div class="preview-area">
    <!-- 任务状态显示 -->
    <div class="task-status" v-if="currentTask">
      <div class="status-header">
        <h3>{{ getStatusText(taskStatus) }}</h3>
        <div class="task-id">文生视频 {{ formatDate(currentTask.createdAt) }}</div>
      </div>
      
      <!-- 任务描述 -->
      <div class="task-description">
        {{ inputText }}
      </div>
      
      <!-- 视频预览区域 -->
      <div class="video-preview-container">
        <!-- 生成中的状态 -->
        <div v-if="inProgress" class="generating-container">
          <div class="generating-placeholder">
            <div class="generating-text">生成中</div>
            <div class="progress-bar-large">
              <div class="progress-fill-large" :style="{ width: taskProgress + '%' }"></div>
            </div>
          </div>
        </div>
        
        <!-- 完成状态 -->
        <div v-else-if="taskStatus === 'COMPLETED'" class="completed-container">
          <div class="video-result">
            <video 
              v-if="currentTask.resultUrl" 
              :src="currentTask.resultUrl" 
              controls 
              class="result-video"
            ></video>
          </div>
          <div class="result-actions">
            <button class="action-btn primary" @click="createSimilar">做同款</button>
            <button class="action-btn secondary" @click="downloadVideo">下载视频</button>
          </div>
        </div>
        
        <!-- 失败状态 -->
        <div v-else-if="taskStatus === 'FAILED'" class="failed-container">
          <div class="failed-placeholder">
            <div class="failed-icon"></div>
            <div class="failed-text">生成失败</div>
            <div class="failed-desc">请检查输入内容或重试</div>
          </div>
          <div class="result-actions">
            <button class="action-btn primary" @click="retryTask">重新生成</button>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 初始状态 -->
    <div class="preview-content" v-else>
      <div class="preview-placeholder">
        <div class="placeholder-text">开始创作您的第一个作品吧!</div>
      </div>
    </div>
  </div>
</div>

图生视频页面 (ImageToVideoCreate.vue)

  • 实现了与文生视频页面相同的单页面更新体验
  • 保持了功能的一致性

JavaScript 功能方法

// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return ''
  const date = new Date(dateString)
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  return `${year}${month}${day}${hours}:${minutes}`
}

// 创建同款
const createSimilar = () => {
  // 保持当前设置,重新生成
  startGenerate()
}

// 下载视频
const downloadVideo = () => {
  if (currentTask.value && currentTask.value.resultUrl) {
    const link = document.createElement('a')
    link.href = currentTask.value.resultUrl
    link.download = `video_${currentTask.value.taskId}.mp4`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    ElMessage.success('开始下载视频')
  } else {
    ElMessage.error('视频链接不可用')
  }
}

// 重新生成
const retryTask = () => {
  // 重置状态
  currentTask.value = null
  inProgress.value = false
  taskProgress.value = 0
  taskStatus.value = ''
  
  // 重新开始生成
  startGenerate()
}

CSS 样式设计

/* 任务描述样式 */
.task-description {
  background: rgba(255, 255, 255, 0.05);
  border-radius: 8px;
  padding: 16px;
  margin: 15px 0;
  font-size: 14px;
  line-height: 1.6;
  color: #e5e7eb;
  border: 1px solid rgba(255, 255, 255, 0.1);
  max-height: 120px;
  overflow-y: auto;
}

/* 视频预览容器 */
.video-preview-container {
  background: #1a1a1a;
  border: 2px solid #2a2a2a;
  border-radius: 12px;
  min-height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 15px 0;
  overflow: hidden;
}

/* 生成中状态 */
.generating-container {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.generating-text {
  font-size: 18px;
  color: #3b82f6;
  font-weight: 600;
  margin-bottom: 20px;
}

.progress-bar-large {
  width: 200px;
  height: 8px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  overflow: hidden;
}

.progress-fill-large {
  height: 100%;
  background: linear-gradient(90deg, #3b82f6, #1d4ed8);
  border-radius: 4px;
  transition: width 0.3s ease;
}

/* 完成状态 */
.completed-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.result-video {
  max-width: 100%;
  max-height: 100%;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}

.result-actions {
  margin-top: 20px;
  display: flex;
  gap: 12px;
}

.action-btn {
  padding: 10px 20px;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
  border: none;
}

.action-btn.primary {
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  color: white;
}

.action-btn.primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}

.action-btn.secondary {
  background: rgba(255, 255, 255, 0.1);
  color: #e5e7eb;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.action-btn.secondary:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-1px);
}

🎨 界面效果

1. 提交前

  • 右侧显示"开始创作您的第一个作品吧!"提示
  • 界面简洁,引导用户开始创作

2. 生成中

  • 显示任务状态标题(如"处理中"
  • 显示任务创建时间
  • 显示任务描述内容
  • 显示"生成中"文字和进度条动画
  • 提供"取消任务"按钮

3. 生成完成

  • 显示任务状态标题(如"已完成"
  • 显示任务创建时间
  • 显示任务描述内容
  • 显示生成的视频播放器
  • 提供"做同款"和"下载视频"按钮

4. 生成失败

  • 显示失败图标和提示文字
  • 提供"重新生成"按钮

🔄 状态流转

初始状态 → 任务提交 → 生成中 → 完成/失败
    ↓         ↓        ↓       ↓
  提示页面   状态显示   进度条   结果展示

功能特性

1. 单页面体验

  • 任务提交后不跳转页面
  • 中间内容区域动态更新
  • 保持左侧设置面板不变

2. 实时状态更新

  • 任务状态实时显示
  • 进度条动画效果
  • 任务描述内容展示

3. 交互功能

  • 视频播放控制
  • 下载视频功能
  • 做同款功能
  • 重新生成功能
  • 取消任务功能

4. 视觉设计

  • 深色主题风格
  • 渐变色彩搭配
  • 动画过渡效果
  • 响应式布局

🚀 使用体验

用户现在可以享受流畅的单页面体验:

  1. 输入内容 → 在左侧面板输入文本描述
  2. 设置参数 → 选择比例、时长、画质等
  3. 提交任务 → 点击"开始生成"按钮
  4. 查看进度 → 右侧实时显示生成进度
  5. 获取结果 → 完成后直接播放和下载视频
  6. 继续创作 → 可以"做同款"或重新生成

整个流程在一个页面内完成,无需跳转,提供了更加流畅和直观的用户体验!