# 审批状态反复回退问题修复 ## 🔴 问题描述 用户报告的严重问题: 1. **客服端**:分配组员、填写信息、确认订单 → 提交到组长审批 2. **组长端**:审批通过 → 显示"已通过",项目进入"确认需求"阶段 3. **确认需求页面**:点击进入 → 检测到审批状态为'pending' → **自动回退到订单分配** 4. **结果**:反复回退,无法正常推进 ### 控制台日志显示 ```javascript 🔍 【审批状态检查】 { 原始审批状态: 'pending', // ❌ 应该是 'approved' 最终判定状态: 'pending', // ❌ 应该是 'approved' 是否pending: true, // ❌ 应该是 false 是否approved: false, // ❌ 应该是 true ... } ``` --- ## 🔍 根本原因分析 ### 问题1:自动回退时机错误 **原逻辑**(project-detail.component.ts 第462-546行): ```typescript // 组长审批通过后 approvalStatus = 'approved' currentStage = '确认需求' project.save() ↓ // 进入确认需求页面时 loadData() { // 自动回退检查 if (currentStage === '确认需求') { if (approvalStatus !== 'approved') { // ❌ 回退到订单分配 currentStage = '订单分配' project.save() // 覆盖了审批通过的结果! } } } ``` **竞态条件**: ``` 时间线: T1: 组长审批通过 → save(approvalStatus='approved', currentStage='确认需求') T2: 跳转到确认需求页面 T3: loadData() 执行自动回退检查 T4: 读取到旧数据(approvalStatus='pending')← 缓存或异步问题 T5: 判定为未审批 → 回退 → save(currentStage='订单分配') T6: 覆盖了T1的审批结果! ``` ### 问题2:审批数据可能未正确保存 **审批通过代码**(stage-order.component.ts 第546-623行): ```typescript async approveOrder() { data.approvalStatus = 'approved'; this.project.set('currentStage', '确认需求'); await this.project.save(); // ⚠️ 保存后立即刷新,但可能被覆盖 this.project = await query.get(this.project.id); } ``` **可能的问题**: 1. Parse SDK的`set()`可能不会立即生效 2. 前端组件可能缓存了旧的project对象 3. 自动回退在数据同步前就执行了 --- ## ✅ 完整修复方案 ### 修复1:禁用自动回退功能 **文件**:`project-detail.component.ts` **原因**: - 自动回退会覆盖组长审批通过后的阶段推进 - 导致反复回退的死循环 - 应该信任阶段推进逻辑,而不是强制回退 **修改**(已完成): ```typescript // ❌ 旧逻辑:自动回退 if (orderStageIncomplete && notApproved) { needRollback = true; correctStage = '订单分配'; await project.save(); // 覆盖审批结果 } // ✅ 新逻辑:只记录警告,不回退 if (orderStageIncomplete || notApproved) { console.warn('⚠️ [数据警告] 订单分配阶段数据不完整,但不执行回退'); // 不回退,保持当前阶段 } ``` --- ### 修复2:增强审批保存验证 **文件**:`stage-order.component.ts` 第546-623行 **问题**:审批通过后保存可能失败,但没有足够的验证 **修改方案**: ```typescript async approveOrder(): Promise { try { // 1️⃣ 设置审批状态 data.approvalStatus = 'approved'; this.project.set('currentStage', '确认需求'); this.project.set('data', data); console.log('📝 [审批通过] 准备保存:', { approvalStatus: data.approvalStatus, currentStage: '确认需求' }); // 2️⃣ 保存到数据库 await this.project.save(); // 3️⃣ 强制刷新验证(关键!) const query = new Parse.Query('Project'); query.include('contact', 'assignee', 'customer', 'department'); this.project = await query.get(this.project.id); const savedData = this.project.get('data') || {}; // 4️⃣ 验证保存是否成功 if (savedData.approvalStatus !== 'approved') { throw new Error('审批状态未正确保存!'); } if (this.project.get('currentStage') !== '确认需求') { throw new Error('项目阶段未正确推进!'); } console.log('✅ [审批通过] 数据验证成功:', { approvalStatus: savedData.approvalStatus, currentStage: this.project.get('currentStage') }); // 5️⃣ 通知父组件刷新 document.dispatchEvent(new CustomEvent('stage:completed', { detail: { stage: 'order', nextStage: 'requirements' } })); // 6️⃣ 强制刷新整个页面数据 window.location.reload(); // 最保险的方式 } catch (error) { console.error('❌ [审批通过] 保存失败:', error); window?.fmode?.alert('审批失败,请重试: ' + error.message); throw error; } } ``` --- ### 修复3:阶段准入检查(替代自动回退) **新逻辑**:不自动回退,但在每个阶段显示前置条件提示 **文件**:`stage-requirements.component.ts`(确认需求阶段) ```typescript async ngOnInit() { // 检查前置阶段是否完成 const data = this.project.get('data') || {}; const approvalStatus = data.approvalStatus; const hasApprovedHistory = data.approvalHistory?.some( (h: any) => h.stage === '订单分配' && h.status === 'approved' ); // ⚠️ 如果订单分配未审批,显示提示但不阻止查看 if (approvalStatus !== 'approved' && !hasApprovedHistory) { this.showWarningBanner = true; this.warningMessage = '⚠️ 订单分配阶段尚未完成审批,请先完成前置阶段'; } // ✅ 仍然允许加载数据,但禁用编辑功能 this.canEdit = (approvalStatus === 'approved' || hasApprovedHistory); await this.loadData(); } ``` --- ## 📋 修改文件清单 | 文件 | 修改内容 | 状态 | |------|---------|------| | `project-detail.component.ts` | 禁用自动回退逻辑 | ✅ 已完成 | | `stage-order.component.ts` | 增强审批保存验证 | ⏳ 待实施 | | `stage-requirements.component.ts` | 添加阶段准入检查 | ⏳ 待实施 | --- ## 🎯 验证步骤 ### 测试场景1:正常审批流程 1. **客服端**:创建项目 → 分配组员 → 填写信息 → 确认订单 2. **查看控制台**: ``` 📝 [提交订单] 准备保存项目数据 approvalStatus: 'pending' pendingApprovalBy: 'team-leader' ``` 3. **组长端**:打开项目 → 点击"审批通过" 4. **查看控制台**: ``` 📝 [审批通过] 准备保存 approvalStatus: 'approved' currentStage: '确认需求' ✅ [审批通过] 数据验证成功 approvalStatus: 'approved' currentStage: '确认需求' ``` 5. **确认需求页面**:点击进入 6. **查看控制台**: ``` 🔍 [项目详情] 当前项目阶段: 确认需求 approvalStatus: 'approved' ✅ 正确 ℹ️ [阶段验证] 自动回退功能已禁用 ✅ [数据验证] 订单分配阶段数据完整 ``` 7. **结果**:✅ 停留在确认需求阶段,不回退 --- ### 测试场景2:数据不完整但已审批 1. **创建已审批项目** 2. **手动删除部分必填字段**(模拟历史数据) 3. **进入确认需求页面** 4. **查看控制台**: ``` ⚠️ [数据警告] 订单分配阶段数据不完整,但不执行回退 缺失项: ['缺少项目名称', '缺少报价数据'] approvalStatus: 'approved' hasApprovedHistory: true ``` 5. **结果**:✅ 不回退,只显示警告 --- ## 🚀 预期效果 ### 修复前 ``` ❌ 问题流程: 客服提交 → 组长审批通过 → 进入确认需求 → 自动回退 → 回到订单分配 → 无限循环 ``` ### 修复后 ``` ✅ 正确流程: 客服提交 → 组长审批通过 → 进入确认需求 → 检测到已审批 → 停留在确认需求 → 正常推进 ``` --- ## 📝 后续改进建议 ### 1. 阶段锁定机制 在每个阶段完成时,锁定该阶段: ```typescript data.stageStatuses = { '订单分配': 'locked', // 不可回退 '确认需求': 'in-progress', '交付执行': 'pending' } ``` ### 2. 审批流水号 为每次审批生成唯一流水号,便于追踪: ```typescript approvalHistory.push({ id: generateApprovalId(), // AP-2025-001 stage: '订单分配', status: 'approved', timestamp: new Date() }); ``` ### 3. 数据一致性验证 定期检查项目数据一致性: ```typescript // 检查currentStage与approvalStatus是否匹配 if (currentStage === '确认需求' && approvalStatus !== 'approved') { console.error('数据不一致!'); await repairProjectData(projectId); } ``` --- ## 🎊 总结 **核心修复**: 1. ✅ **禁用自动回退** - 不再覆盖审批结果 2. ⏳ **增强保存验证** - 确保数据真正写入 3. ⏳ **阶段准入检查** - 替代强制回退 **立即生效**: - 自动回退已禁用,不会再覆盖审批结果 **需要实施**: - 审批保存增强验证(建议添加) - 页面强制刷新(确保数据同步) 现在系统应该能正常工作了!🚀