STAGE_NAVIGATION_LOGIC.md 9.3 KB

项目阶段导航逻辑说明

🎯 核心逻辑

两个独立的概念

  1. 项目实际阶段project.currentStage

    • 存储在数据库中
    • 代表项目真正完成到哪个阶段
    • 只能通过完成必填项后点击提交按钮来推进
    • 例如:点击"确认订单"、"确认需求"等按钮
  2. 当前查看阶段this.currentStage

    • 仅影响前端路由和显示
    • 用户可以自由切换查看任何阶段
    • 不会改变项目的实际阶段

📊 阶段状态显示

导航栏上的阶段状态始终基于项目实际阶段project.currentStage)显示:

状态 颜色 说明 可否点击
completed(已完成) 绿色 + ✓ 项目已完成该阶段 ✅ 可以点击查看
active(当前) 红色 + 脉冲 项目当前所在阶段 ✅ 可以点击查看
pending(未开始) 灰色 + 半透明 项目还未到达该阶段 ✅ 可以点击预览

🔄 阶段切换流程

1️⃣ 点击导航栏(查看模式)

// 用户点击导航栏的任何阶段
switchStage(stageId: string) {
  // ✅ 允许查看所有阶段(包括未开始的)
  // ⚠️ 仅改变路由,不改变 project.currentStage
  this.currentStage = stageId;  // 本地视图状态
  this.router.navigate([stageId]);
}

效果

  • ✅ 路由跳转到对应阶段页面
  • ✅ 可以查看该阶段的内容
  • ❌ 不会改变项目的实际阶段
  • ⚠️ 如果是未开始的阶段,可能显示空白或提示信息

2️⃣ 完成阶段任务(推进模式)

// 订单分配阶段 - 点击"确认订单"
async submitForOrder() {
  // 1️⃣ 验证必填项
  if (!this.projectInfo.title.trim()) {
    alert('请填写项目名称');
    return;
  }
  if (!this.projectInfo.projectType) {
    alert('请选择项目类型');
    return;
  }
  // ... 其他验证
  
  // 2️⃣ 保存数据
  await this.project.save();
  
  // 3️⃣ 推进到下一阶段(改变 project.currentStage)
  this.project.set('currentStage', '确认需求');
  await this.project.save();
  
  // 4️⃣ 派发事件,触发自动跳转
  document.dispatchEvent(new CustomEvent('stage:completed', {
    detail: { stage: 'order', nextStage: 'requirements' }
  }));
}

效果

  • ✅ 验证所有必填项
  • ✅ 保存数据到数据库
  • ✅ 更新 project.currentStage
  • ✅ 自动跳转到下一阶段
  • ✅ 导航栏状态更新(上一阶段变绿色,当前阶段变红色)

🎨 视觉反馈

已完成阶段(绿色)

&.completed {
  .stage-circle {
    background: linear-gradient(135deg, #2dd36f 0%, #28ba62 100%);
    border-color: var(--success-color);
    color: var(--white);
    box-shadow: 0 2px 8px rgba(45, 211, 111, 0.3);
  }
}

当前阶段(红色 + 脉冲)

&.active {
  .stage-circle {
    background: linear-gradient(135deg, #eb445a 0%, #d33850 100%);
    border-color: var(--danger-color);
    animation: pulse 2s infinite;
  }
}

未开始阶段(灰色 + 半透明)

&.pending {
  opacity: 0.7; // 提示这是预览模式
  
  &:hover {
    opacity: 1; // 悬停时变清晰
    transform: translateY(-1px);
  }
}

📝 各阶段完成条件

订单分配 → 确认需求

必填项

✅ project.title         // 项目名称
✅ project.projectType   // 项目类型(家装/工装)
✅ project.demoday       // 小图日期
✅ data.quotation.total  // 报价总额 > 0
✅ ProjectTeam 记录      // 已分配设计师
   或 data.approvalStatus === 'approved'  // 组长已审批

提交按钮确认订单stage-order.component.ts 第1192行)


确认需求 → 交付执行

必填项

✅ data.requirementsAnalysis  // 需求分析数据
   或 data.spaceRequirements   // 空间需求数据

提交按钮确认需求stage-requirements.component.ts


交付执行 → 售后归档

必填项

✅ data.deliveryStages.modeling.approvalStatus === 'approved'
✅ data.deliveryStages.softDecor.approvalStatus === 'approved'
✅ data.deliveryStages.rendering.approvalStatus === 'approved'
✅ data.deliveryStages.postProcess.approvalStatus === 'approved'

提交方式:各子阶段逐个审批通过(stage-delivery.component.ts


🔒 权限控制

查看权限(导航栏点击)

  • 所有阶段都可以点击查看
  • ✅ 包括未开始的阶段
  • ⚠️ 未开始的阶段可能显示空白或提示
  • 💡 控制台会提示"这是查看模式,项目实际阶段不会改变"

推进权限(提交按钮)

  • 必须完成当前阶段的必填项
  • ✅ 验证通过后才能推进
  • ✅ 推进后 project.currentStage 才会改变
  • ✅ 导航栏状态才会更新

🚀 路由配置

从项目列表进入

项目列表 → 点击项目
    ↓
根据 project.currentStage 自动跳转到对应阶段
    ↓
例如:currentStage = '确认需求'
    ↓
路由:/wxwork/{cid}/project/{projectId}/requirements
    ↓
导航栏显示:
  - 订单分配:✓ 绿色(已完成)
  - 确认需求:● 红色(当前)
  - 交付执行:○ 灰色(未开始)
  - 售后归档:○ 灰色(未开始)

点击导航栏切换

用户点击"交付执行"(未开始)
    ↓
switchStage('delivery')
    ↓
路由:/wxwork/{cid}/project/{projectId}/delivery
    ↓
显示:交付执行页面(可能是空白或提示)
    ↓
导航栏状态不变:
  - 订单分配:✓ 绿色(已完成)
  - 确认需求:● 红色(当前实际阶段)
  - 交付执行:○ 灰色(未开始,仅在查看)
  - 售后归档:○ 灰色(未开始)
    ↓
控制台提示:
  ⚠️ 正在查看未开始的阶段: 交付执行
  💡 这是查看模式,项目实际阶段不会改变
  💡 需要完成当前阶段的必填项才能推进到 交付执行

🔍 调试信息

查看当前状态

在浏览器控制台输入:

// 查看项目实际阶段
console.log('项目实际阶段:', project.get('currentStage'));

// 查看当前查看阶段(路由)
console.log('当前查看阶段:', this.currentStage);

// 查看各阶段状态
this.stages.forEach(stage => {
  console.log(`${stage.name}:`, this.getStageStatus(stage.id));
});

控制台日志示例

🔄 用户点击切换阶段(查看模式): delivery
  currentRoute: /wxwork/xxx/project/yyy/delivery
  currentViewStage: delivery
  projectActualStage: 确认需求

⚠️ 正在查看未开始的阶段: 交付执行
💡 提示: 这是查看模式,项目实际阶段不会改变
💡 需要完成当前阶段的必填项才能推进到 交付执行

✅ 切换到阶段视图: delivery (项目实际状态: pending)
✅ 导航成功(查看模式): delivery

✅ 验证方法

测试1:查看未开始的阶段

  1. 创建新项目(currentStage = '订单分配')
  2. 点击导航栏"交付执行"
  3. 预期结果
    • ✅ 路由跳转到 /project/{id}/delivery
    • ✅ 可以查看交付执行页面
    • ✅ 导航栏状态不变(订单分配仍然是红色当前状态)
    • ✅ 交付执行仍然显示为灰色(未开始)

测试2:推进到下一阶段

  1. 在订单分配阶段
  2. 填写所有必填项
  3. 点击"确认订单"按钮
  4. 预期结果
    • ✅ 验证通过
    • project.currentStage 更新为"确认需求"
    • ✅ 自动跳转到确认需求页面
    • ✅ 导航栏更新:订单分配变绿色,确认需求变红色

测试3:回看已完成的阶段

  1. 在确认需求阶段
  2. 点击导航栏"订单分配"
  3. 预期结果
    • ✅ 可以查看已填写的信息
    • ✅ 按钮可能显示为禁用(已完成)
    • ✅ 导航栏状态不变(确认需求仍然是红色)

📌 关键要点

  1. 查看 ≠ 推进

    • 点击导航栏只是查看
    • 点击提交按钮才是推进
  2. 状态显示基于实际阶段

    • 导航栏颜色基于 project.currentStage
    • 不受当前查看的阶段影响
  3. 必须验证后才能推进

    • 每个阶段都有必填项验证
    • 验证失败会弹出提示
    • 验证通过才会更新 project.currentStage
  4. 未开始的阶段可以预览

    • 用户可以提前查看下一阶段
    • 但不能跳过当前阶段的必填项
    • 控制台会提示这是查看模式

🎉 总结

✅ 修复完成

  1. 允许点击所有阶段查看

    • 包括未开始的阶段
    • 控制台给予友好提示
  2. 点击导航栏不改变项目阶段

    • 只改变路由和视图
    • project.currentStage 保持不变
  3. 必须完成必填项才能推进

    • 通过提交按钮验证
    • 验证通过才更新实际阶段
  4. 状态显示正确

    • 基于项目实际阶段
    • 不受当前查看影响

🔧 修改文件

  1. project-detail.component.ts - 修改 switchStage 方法
  2. project-detail.component.html - 移除禁用逻辑
  3. project-detail.component.scss - 调整pending状态样式
  4. repair-project-stages.ts - 修复TypeScript错误

📝 相关文档

  • STAGE_SWITCH_VALIDATION_FIXED.md - 之前的修复记录
  • DATA_REPAIR_STAGE_ROLLBACK.md - 数据修复方案
  • STAGE_NAVIGATION_LOGIC.md - 本文档