yangg 1 dzień temu
rodzic
commit
73e6ef8049
1 zmienionych plików z 798 dodań i 54 usunięć
  1. 798 54
      src/views/report.vue

+ 798 - 54
src/views/report.vue

@@ -17,15 +17,58 @@
             v-for="(progress, index) in progressList" 
             :key="index" 
             class="progress-item"
+            :class="{ 'completed': progress.value >= 100, 'error': progress.status === '错误' }"
           >
+            <!-- 主进度项 -->
             <div class="progress-info">
-              <span class="progress-title">{{ progress.title }}</span>
-              <span class="progress-percentage">{{ progress.value }}%</span>
+              <div class="progress-title-wrapper">
+                <span class="progress-icon">{{ getProgressIcon(progress) }}</span>
+                <span class="progress-title">{{ progress.title }}</span>
+              </div>
+              <span class="progress-percentage" :class="getProgressClass(progress)">{{ progress.value }}%</span>
             </div>
             <div class="progress-bar-container">
-              <div class="progress-bar" :style="{ width: progress.value + '%' }"></div>
+              <div class="progress-bar" :style="{ width: progress.value + '%' }" :class="getProgressBarClass(progress)"></div>
             </div>
             <div class="progress-status">{{ progress.status }}</div>
+            
+            <!-- 子进度项 -->
+            <div v-if="progress.subTasks && progress.subTasks.length > 0" class="sub-progress-list">
+              <div 
+                v-for="(subTask, subIndex) in progress.subTasks" 
+                :key="subIndex"
+                class="sub-progress-item"
+                :class="{ 'completed': subTask.value >= 100, 'active': subTask.isActive }"
+              >
+                <div class="sub-progress-info">
+                  <span class="sub-progress-icon">{{ getSubProgressIcon(subTask) }}</span>
+                  <span class="sub-progress-title">{{ subTask.title }}</span>
+                  <span class="sub-progress-percentage">{{ subTask.value }}%</span>
+                </div>
+                <div class="sub-progress-bar-container">
+                  <div class="sub-progress-bar" :style="{ width: subTask.value + '%' }"></div>
+                </div>
+                
+                <!-- 子子进度项 -->
+                <div v-if="subTask.subSubTasks && subTask.subSubTasks.length > 0" class="sub-sub-progress-list">
+                  <div 
+                    v-for="(subSubTask, subSubIndex) in subTask.subSubTasks" 
+                    :key="subSubIndex"
+                    class="sub-sub-progress-item"
+                    :class="{ 'completed': subSubTask.value >= 100, 'active': subSubTask.isActive }"
+                  >
+                    <div class="sub-sub-progress-info">
+                      <span class="sub-sub-progress-icon">{{ getSubSubProgressIcon(subSubTask) }}</span>
+                      <span class="sub-sub-progress-title">{{ subSubTask.title }}</span>
+                      <span class="sub-sub-progress-percentage">{{ subSubTask.value }}%</span>
+                    </div>
+                    <div class="sub-sub-progress-bar-container">
+                      <div class="sub-sub-progress-bar" :style="{ width: subSubTask.value + '%' }"></div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
           </div>
         </div>
       </div>
@@ -1449,30 +1492,295 @@ const handleStepClick = (step) => {
   // 显示进度条弹窗
   showProgressModal.value = true;
   
-  // 创建新的进度项
-  const newProgress = {
-    id: Date.now(),
-    title: step.description || '处理步骤',
-    value: 0,
-    status: '进行中...'
-  };
+  // 创建模拟任务数据
+  const mockTasks = [
+    {
+      id: Date.now(),
+      title: '数据分析任务',
+      value: 0,
+      status: '准备中...',
+      subTasks: [
+        { 
+          title: '数据收集', 
+          value: 0, 
+          isActive: true,
+          subSubTasks: [
+            { title: '连接数据源', value: 0, isActive: true },
+            { title: '验证数据格式', value: 0, isActive: false },
+            { title: '下载数据文件', value: 0, isActive: false }
+          ]
+        },
+        { 
+          title: '数据清洗', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '检测异常值', value: 0, isActive: false },
+            { title: '处理缺失值', value: 0, isActive: false },
+            { title: '数据标准化', value: 0, isActive: false },
+            { title: '去重处理', value: 0, isActive: false }
+          ]
+        },
+        { 
+          title: '特征提取', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '特征选择', value: 0, isActive: false },
+            { title: '特征工程', value: 0, isActive: false },
+            { title: '降维处理', value: 0, isActive: false }
+          ]
+        },
+        { 
+          title: '模型训练', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '参数初始化', value: 0, isActive: false },
+            { title: '训练迭代', value: 0, isActive: false },
+            { title: '模型验证', value: 0, isActive: false },
+            { title: '超参数调优', value: 0, isActive: false }
+          ]
+        },
+        { 
+          title: '结果验证', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '交叉验证', value: 0, isActive: false },
+            { title: '性能评估', value: 0, isActive: false },
+            { title: '结果输出', value: 0, isActive: false }
+          ]
+        }
+      ]
+    },
+    {
+      id: Date.now() + 1,
+      title: '报告生成任务',
+      value: 0,
+      status: '等待中...',
+      subTasks: [
+        { 
+          title: '模板加载', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '读取模板文件', value: 0, isActive: false },
+            { title: '解析模板结构', value: 0, isActive: false },
+            { title: '初始化变量', value: 0, isActive: false }
+          ]
+        },
+        { 
+          title: '数据填充', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '获取分析结果', value: 0, isActive: false },
+            { title: '格式化数据', value: 0, isActive: false },
+            { title: '填充模板', value: 0, isActive: false }
+          ]
+        },
+        { 
+          title: '图表生成', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '创建统计图表', value: 0, isActive: false },
+            { title: '生成趋势图', value: 0, isActive: false },
+            { title: '制作对比图', value: 0, isActive: false },
+            { title: '优化图表样式', value: 0, isActive: false }
+          ]
+        },
+        { 
+          title: '格式化处理', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '调整页面布局', value: 0, isActive: false },
+            { title: '设置字体样式', value: 0, isActive: false },
+            { title: '添加页眉页脚', value: 0, isActive: false }
+          ]
+        },
+        { 
+          title: '文件导出', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '生成PDF文件', value: 0, isActive: false },
+            { title: '创建Excel文件', value: 0, isActive: false },
+            { title: '压缩文件包', value: 0, isActive: false }
+          ]
+        }
+      ]
+    },
+    {
+      id: Date.now() + 2,
+      title: '系统优化任务',
+      value: 0,
+      status: '等待中...',
+      subTasks: [
+        { 
+          title: '性能检测', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: 'CPU使用率检测', value: 0, isActive: false },
+            { title: '内存占用分析', value: 0, isActive: false },
+            { title: '磁盘IO监控', value: 0, isActive: false },
+            { title: '网络延迟测试', value: 0, isActive: false }
+          ]
+        },
+        { 
+          title: '缓存清理', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '清理临时文件', value: 0, isActive: false },
+            { title: '清空浏览器缓存', value: 0, isActive: false },
+            { title: '清理系统缓存', value: 0, isActive: false }
+          ]
+        },
+        { 
+          title: '数据库优化', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '索引重建', value: 0, isActive: false },
+            { title: '查询优化', value: 0, isActive: false },
+            { title: '数据压缩', value: 0, isActive: false },
+            { title: '备份清理', value: 0, isActive: false }
+          ]
+        },
+        { 
+          title: '内存整理', 
+          value: 0, 
+          isActive: false,
+          subSubTasks: [
+            { title: '垃圾回收', value: 0, isActive: false },
+            { title: '内存碎片整理', value: 0, isActive: false },
+            { title: '进程优化', value: 0, isActive: false }
+          ]
+        }
+      ]
+    }
+  ];
   
   // 添加到进度列表
-  progressList.value.push(newProgress);
+  progressList.value = mockTasks;
+  
+  // 开始模拟进度
+  simulateProgress();
+};
+
+// 模拟复杂的三级进度处理
+const simulateProgress = () => {
+  let currentTaskIndex = 0;
+  let currentSubTaskIndex = 0;
+  let currentSubSubTaskIndex = 0;
   
-  // 模拟进度增长
   const progressInterval = setInterval(() => {
-    const progressIndex = progressList.value.findIndex(p => p.id === newProgress.id);
-    if (progressIndex !== -1) {
-      progressList.value[progressIndex].value += 5;
+    if (currentTaskIndex >= progressList.value.length) {
+      clearInterval(progressInterval);
+      return;
+    }
+    
+    const currentTask = progressList.value[currentTaskIndex];
+    const currentSubTask = currentTask.subTasks[currentSubTaskIndex];
+    
+    if (!currentSubTask) return;
+    
+    const currentSubSubTask = currentSubTask.subSubTasks[currentSubSubTaskIndex];
+    
+    // 更新当前子子任务状态
+    if (currentSubSubTask) {
+      currentSubSubTask.isActive = true;
+      currentSubSubTask.value = Math.min(currentSubSubTask.value + Math.random() * 20 + 10, 100);
       
-      if (progressList.value[progressIndex].value >= 100) {
-        clearInterval(progressInterval);
-        progressList.value[progressIndex].status = '完成';
-        progressList.value[progressIndex].value = 100;
+      // 更新子任务进度
+      const completedSubSubTasks = currentSubTask.subSubTasks.filter(subSub => subSub.value >= 100).length;
+      const totalSubSubTasks = currentSubTask.subSubTasks.length;
+      currentSubTask.value = Math.floor((completedSubSubTasks / totalSubSubTasks) * 100);
+      
+      // 更新主任务进度
+      const completedSubTasks = currentTask.subTasks.filter(sub => sub.value >= 100).length;
+      const totalSubTasks = currentTask.subTasks.length;
+      currentTask.value = Math.floor((completedSubTasks / totalSubTasks) * 100);
+      
+      // 更新主任务状态
+      if (currentTask.value === 0) {
+        currentTask.status = '准备中...';
+      } else if (currentTask.value < 100) {
+        currentTask.status = `进行中... (${completedSubTasks}/${totalSubTasks})`;
+      } else {
+        currentTask.status = '已完成';
+      }
+      
+      // 子子任务完成,移动到下一个
+      if (currentSubSubTask.value >= 100) {
+        currentSubSubTask.isActive = false;
+        currentSubSubTaskIndex++;
+        
+        // 当前子任务的所有子子任务完成,移动到下一个子任务
+        if (currentSubSubTaskIndex >= currentSubTask.subSubTasks.length) {
+          currentSubTask.isActive = false;
+          currentSubTaskIndex++;
+          currentSubSubTaskIndex = 0;
+          
+          // 开始下一个子任务
+          if (currentSubTaskIndex < currentTask.subTasks.length) {
+            currentTask.subTasks[currentSubTaskIndex].isActive = true;
+          } else {
+            // 当前任务的所有子任务完成,移动到下一个主任务
+            currentTaskIndex++;
+            currentSubTaskIndex = 0;
+            
+            // 开始下一个任务
+            if (currentTaskIndex < progressList.value.length) {
+              progressList.value[currentTaskIndex].status = '准备中...';
+              progressList.value[currentTaskIndex].subTasks[0].isActive = true;
+            }
+          }
+        }
       }
     }
-  }, 100);
+  }, 150);
+};
+
+// 获取进度图标
+const getProgressIcon = (progress) => {
+  if (progress.status === '错误') return '❌';
+  if (progress.value >= 100) return '✅';
+  if (progress.value > 0) return '🔄';
+  return '⏳';
+};
+
+// 获取子进度图标
+const getSubProgressIcon = (subTask) => {
+  if (subTask.value >= 100) return '✓';
+  if (subTask.isActive) return '▶';
+  return '○';
+};
+
+// 获取子子进度图标
+const getSubSubProgressIcon = (subSubTask) => {
+  if (subSubTask.value >= 100) return '●';
+  if (subSubTask.isActive) return '▸';
+  return '◦';
+};
+
+// 获取进度样式类
+const getProgressClass = (progress) => {
+  if (progress.status === '错误') return 'error';
+  if (progress.value >= 100) return 'completed';
+  if (progress.value > 0) return 'active';
+  return 'pending';
+};
+
+// 获取进度条样式类
+const getProgressBarClass = (progress) => {
+  if (progress.status === '错误') return 'error-bar';
+  if (progress.value >= 100) return 'completed-bar';
+  return 'active-bar';
 };
 
 // 关闭进度弹窗
@@ -3297,26 +3605,70 @@ const updateCollapsedState = () => {
   background-color: #f5f5f5;
 }
 
-/* 进度条弹窗样式 */
+/* 进度条弹窗样式 - 优化版本 */
 .progress-modal-overlay {
   position: fixed;
-  bottom: 200px;
-  right: 20px;
+  bottom: 180px;
+  right: 5%;
   width: auto;
   height: auto;
   background-color: transparent;
   display: block;
-  z-index: 9999;
+  z-index: 9998;
+  animation: slideInUp 0.3s ease-out;
+}
+
+/* 响应式定位 - 确保在不同屏幕尺寸下都在任务按钮上方 */
+@media (max-width: 768px) {
+  .progress-modal-overlay {
+    bottom: 160px;
+    right: 5%;
+  }
+}
+
+@media (max-width: 480px) {
+  .progress-modal-overlay {
+    bottom: 140px;
+    right: 15%;
+  }
+}
+
+/* 大屏幕优化 */
+@media (min-width: 1200px) {
+  .progress-modal-overlay {
+    bottom: 200px;
+    right: 5%;
+  }
+}
+
+/* 超宽屏幕优化 */
+@media (min-width: 1920px) {
+  .progress-modal-overlay {
+    bottom: 220px;
+    right: 5%;
+  }
+}
+
+@keyframes slideInUp {
+  from {
+    transform: translateY(100%);
+    opacity: 0;
+  }
+  to {
+    transform: translateY(0);
+    opacity: 1;
+  }
 }
 
 .progress-modal {
-  background: white;
+  background: #ffffff;
   border-radius: 12px;
-  padding: 20px;
-  min-width: 280px;
-  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
-  text-align: center;
-  border: 1px solid #e8e8e8;
+  padding: 24px;
+  min-width: 320px;
+  max-width: 400px;
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
+  text-align: left;
+  border: 1px solid #f0f0f0;
 }
 
 .progress-modal-header {
@@ -3324,94 +3676,486 @@ const updateCollapsedState = () => {
   justify-content: space-between;
   align-items: center;
   margin-bottom: 20px;
+  padding-bottom: 12px;
+  border-bottom: 1px solid #f0f0f0;
 }
 
 .progress-modal-header h3 {
   margin: 0;
-  color: #333;
+  color: #1a1a1a;
   font-size: 18px;
   font-weight: 600;
+  background: linear-gradient(135deg, #1890ff, #722ed1);
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
 }
 
 .close-btn {
-  background: none;
+  background: rgba(0, 0, 0, 0.05);
   border: none;
-  font-size: 24px;
-  color: #999;
+  font-size: 18px;
+  color: #666;
   cursor: pointer;
   padding: 0;
-  width: 24px;
-  height: 24px;
+  width: 28px;
+  height: 28px;
   display: flex;
   align-items: center;
   justify-content: center;
   border-radius: 50%;
   transition: all 0.2s ease;
+  font-weight: bold;
 }
 
 .close-btn:hover {
-  background-color: #f5f5f5;
-  color: #666;
+  background: rgba(255, 0, 0, 0.1);
+  color: #ff4d4f;
+  transform: scale(1.1);
 }
 
 .progress-list {
-  max-height: 300px;
+  max-height: 350px;
   overflow-y: auto;
+  scrollbar-width: thin;
+  scrollbar-color: #d9d9d9 transparent;
+}
+
+.progress-list::-webkit-scrollbar {
+  width: 4px;
+}
+
+.progress-list::-webkit-scrollbar-track {
+  background: transparent;
+}
+
+.progress-list::-webkit-scrollbar-thumb {
+  background: #d9d9d9;
+  border-radius: 2px;
 }
 
 .progress-item {
   margin-bottom: 16px;
-  padding: 12px;
-  border: 1px solid #f0f0f0;
-  border-radius: 8px;
-  background-color: #fafafa;
+  padding: 16px;
+  border: 1px solid rgba(0, 0, 0, 0.06);
+  border-radius: 12px;
+  background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%);
+  transition: all 0.2s ease;
+  position: relative;
+  overflow: hidden;
+}
+
+.progress-item::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 2px;
+  background: linear-gradient(90deg, #1890ff, #722ed1);
+  opacity: 0.8;
 }
 
 .progress-item:last-child {
   margin-bottom: 0;
 }
 
+.progress-item:hover {
+  transform: translateY(-2px);
+  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
+}
+
 .progress-info {
   display: flex;
   justify-content: space-between;
   align-items: center;
-  margin-bottom: 8px;
+  margin-bottom: 12px;
 }
 
 .progress-title {
   font-size: 14px;
-  color: #333;
+  color: #262626;
   font-weight: 500;
+  flex: 1;
+  margin-right: 12px;
 }
 
 .progress-percentage {
-  font-size: 12px;
-  color: #666;
+  font-size: 13px;
+  color: #1890ff;
   font-weight: 600;
+  background: rgba(24, 144, 255, 0.1);
+  padding: 2px 8px;
+  border-radius: 12px;
+  min-width: 45px;
+  text-align: center;
 }
 
 .progress-bar-container {
   width: 100%;
-  height: 6px;
-  background-color: #e8e8e8;
-  border-radius: 3px;
+  height: 8px;
+  background: linear-gradient(90deg, #f0f0f0, #e8e8e8);
+  border-radius: 4px;
   overflow: hidden;
-  margin-bottom: 8px;
+  margin-bottom: 10px;
+  position: relative;
 }
 
 .progress-bar {
   height: 100%;
-  background: linear-gradient(90deg, #1890ff, #40a9ff);
-  border-radius: 3px;
-  transition: width 0.1s ease;
+  background: linear-gradient(90deg, #1890ff 0%, #40a9ff 50%, #722ed1 100%);
+  border-radius: 4px;
+  transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+  position: relative;
+  overflow: hidden;
+}
+
+.progress-bar::after {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
+  animation: shimmer 2s infinite;
+}
+
+@keyframes shimmer {
+  0% { transform: translateX(-100%); }
+  100% { transform: translateX(100%); }
 }
 
 .progress-status {
   font-size: 12px;
+  color: #8c8c8c;
+  text-align: right;
+  font-style: italic;
+}
+
+/* 进度项状态样式 */
+.progress-item.completed {
+  background: linear-gradient(135deg, #f6ffed 0%, #f0f9ff 100%);
+  border-color: #52c41a;
+}
+
+.progress-item.error {
+  background: linear-gradient(135deg, #fff2f0 0%, #fff1f0 100%);
+  border-color: #ff4d4f;
+}
+
+.progress-title-wrapper {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.progress-icon {
+  font-size: 16px;
+  min-width: 20px;
+}
+
+/* 进度百分比状态样式 */
+.progress-percentage.completed {
+  background: rgba(82, 196, 26, 0.1);
+  color: #52c41a;
+}
+
+.progress-percentage.error {
+  background: rgba(255, 77, 79, 0.1);
+  color: #ff4d4f;
+}
+
+.progress-percentage.active {
+  background: rgba(24, 144, 255, 0.1);
+  color: #1890ff;
+}
+
+/* 进度条状态样式 */
+.progress-bar.completed-bar {
+  background: linear-gradient(90deg, #52c41a 0%, #73d13d 100%);
+}
+
+.progress-bar.error-bar {
+  background: linear-gradient(90deg, #ff4d4f 0%, #ff7875 100%);
+}
+
+/* 子进度项样式 */
+.sub-progress-list {
+  margin-top: 12px;
+  padding-left: 16px;
+  border-left: 2px solid #f0f0f0;
+}
+
+.sub-progress-item {
+  margin-bottom: 8px;
+  padding: 8px 12px;
+  background: rgba(0, 0, 0, 0.02);
+  border-radius: 6px;
+  border: 1px solid transparent;
+  transition: all 0.2s ease;
+}
+
+.sub-progress-item.active {
+  background: rgba(24, 144, 255, 0.05);
+  border-color: rgba(24, 144, 255, 0.2);
+  transform: translateX(4px);
+}
+
+.sub-progress-item.completed {
+  background: rgba(82, 196, 26, 0.05);
+  border-color: rgba(82, 196, 26, 0.2);
+}
+
+.sub-progress-item:last-child {
+  margin-bottom: 0;
+}
+
+.sub-progress-info {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  margin-bottom: 6px;
+}
+
+.sub-progress-icon {
+  font-size: 12px;
+  min-width: 16px;
+  color: #666;
+}
+
+.sub-progress-item.active .sub-progress-icon {
+  color: #1890ff;
+}
+
+.sub-progress-item.completed .sub-progress-icon {
+  color: #52c41a;
+}
+
+.sub-progress-title {
+  font-size: 12px;
+  color: #595959;
+  flex: 1;
+}
+
+.sub-progress-item.active .sub-progress-title {
+  color: #1890ff;
+  font-weight: 500;
+}
+
+.sub-progress-item.completed .sub-progress-title {
+  color: #52c41a;
+}
+
+.sub-progress-percentage {
+  font-size: 11px;
+  color: #8c8c8c;
+  font-weight: 600;
+  min-width: 35px;
+  text-align: right;
+}
+
+.sub-progress-item.active .sub-progress-percentage {
+  color: #1890ff;
+}
+
+.sub-progress-item.completed .sub-progress-percentage {
+  color: #52c41a;
+}
+
+.sub-progress-bar-container {
+  width: 100%;
+  height: 4px;
+  background: #f5f5f5;
+  border-radius: 2px;
+  overflow: hidden;
+}
+
+.sub-progress-bar {
+  height: 100%;
+  background: linear-gradient(90deg, #d9d9d9 0%, #bfbfbf 100%);
+  border-radius: 2px;
+  transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.sub-progress-item.active .sub-progress-bar {
+  background: linear-gradient(90deg, #1890ff 0%, #40a9ff 100%);
+}
+
+.sub-progress-item.completed .sub-progress-bar {
+  background: linear-gradient(90deg, #52c41a 0%, #73d13d 100%);
+}
+
+/* 子子进度项样式 */
+.sub-sub-progress-list {
+  margin-top: 8px;
+  padding-left: 12px;
+  border-left: 1px solid #e8e8e8;
+}
+
+.sub-sub-progress-item {
+  margin-bottom: 6px;
+  padding: 6px 8px;
+  background: rgba(0, 0, 0, 0.01);
+  border-radius: 4px;
+  border: 1px solid transparent;
+  transition: all 0.15s ease;
+  font-size: 11px;
+}
+
+.sub-sub-progress-item.active {
+  background: rgba(24, 144, 255, 0.03);
+  border-color: rgba(24, 144, 255, 0.15);
+  transform: translateX(2px);
+}
+
+.sub-sub-progress-item.completed {
+  background: rgba(82, 196, 26, 0.03);
+  border-color: rgba(82, 196, 26, 0.15);
+}
+
+.sub-sub-progress-item:last-child {
+  margin-bottom: 0;
+}
+
+.sub-sub-progress-info {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  margin-bottom: 4px;
+}
+
+.sub-sub-progress-icon {
+  font-size: 10px;
+  min-width: 12px;
   color: #999;
+}
+
+.sub-sub-progress-item.active .sub-sub-progress-icon {
+  color: #1890ff;
+}
+
+.sub-sub-progress-item.completed .sub-sub-progress-icon {
+  color: #52c41a;
+}
+
+.sub-sub-progress-title {
+  font-size: 11px;
+  color: #8c8c8c;
+  flex: 1;
+  line-height: 1.2;
+}
+
+.sub-sub-progress-item.active .sub-sub-progress-title {
+  color: #1890ff;
+  font-weight: 500;
+}
+
+.sub-sub-progress-item.completed .sub-sub-progress-title {
+  color: #52c41a;
+}
+
+.sub-sub-progress-percentage {
+  font-size: 10px;
+  color: #bfbfbf;
+  font-weight: 600;
+  min-width: 30px;
   text-align: right;
 }
 
+.sub-sub-progress-item.active .sub-sub-progress-percentage {
+  color: #1890ff;
+}
+
+.sub-sub-progress-item.completed .sub-sub-progress-percentage {
+  color: #52c41a;
+}
+
+.sub-sub-progress-bar-container {
+  width: 100%;
+  height: 3px;
+  background: #f8f8f8;
+  border-radius: 1.5px;
+  overflow: hidden;
+}
+
+.sub-sub-progress-bar {
+  height: 100%;
+  background: linear-gradient(90deg, #e8e8e8 0%, #d9d9d9 100%);
+  border-radius: 1.5px;
+  transition: width 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.sub-sub-progress-item.active .sub-sub-progress-bar {
+  background: linear-gradient(90deg, #69c0ff 0%, #91d5ff 100%);
+}
+
+.sub-sub-progress-item.completed .sub-sub-progress-bar {
+  background: linear-gradient(90deg, #95de64 0%, #b7eb8f 100%);
+}
+
+/* 层级缩进视觉效果 */
+.progress-item {
+  position: relative;
+}
+
+.progress-item::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 2px;
+  background: linear-gradient(90deg, #1890ff, #722ed1);
+  opacity: 0.8;
+}
+
+.sub-progress-item {
+  position: relative;
+}
+
+.sub-progress-item::before {
+  content: '';
+  position: absolute;
+  left: -16px;
+  top: 50%;
+  width: 8px;
+  height: 1px;
+  background: #d9d9d9;
+  transform: translateY(-50%);
+}
+
+.sub-progress-item.active::before {
+  background: #1890ff;
+}
+
+.sub-progress-item.completed::before {
+  background: #52c41a;
+}
+
+.sub-sub-progress-item {
+  position: relative;
+}
+
+.sub-sub-progress-item::before {
+  content: '';
+  position: absolute;
+  left: -12px;
+  top: 50%;
+  width: 6px;
+  height: 1px;
+  background: #e8e8e8;
+  transform: translateY(-50%);
+}
+
+.sub-sub-progress-item.active::before {
+  background: #69c0ff;
+}
+
+.sub-sub-progress-item.completed::before {
+  background: #95de64;
+}
+
 .dropdown-item i {
   margin-right: 8px;
   font-size: 14px;