您描述的问题:
project-management.ts)数据来源:Project 表
关键代码:
// 第196行:查询Project表
const projects = await this.projectService.findProjects({ limit: 100 });
// 第220行:获取阶段
const rawStage = json.currentStage || json.stage || '订单分配';
// 第223行:规范化阶段名称
const normalizedStage = normalizeStage(rawStage);
// 第226行:根据阶段自动判断状态
const autoStatus = getProjectStatusByStage(rawStage, json.status);
// 第248行:使用规范化后的阶段
currentStage: normalizedStage
字段映射:
currentStage → 规范化后的阶段名称status → 根据阶段自动判断的状态project-list.ts)数据来源:Project 表
关键代码:
// 第435行:查询Project表
const ProjectQuery = new Parse.Query('Project');
const projectObjects = await ProjectQuery.find();
// 第479行:获取阶段(优先currentStage)
let rawStage = obj.get('currentStage') || obj.get('stage') || '订单分配';
// 第486-490行:统一交付执行子阶段
if (this.isDeliveryExecutionStage(rawStage)) {
finalStage = '交付执行';
}
// 第494行:根据阶段自动判断状态
const autoStatus = getProjectStatusByStage(rawStage, projectStatus);
// 第508行:使用统一后的阶段
currentStage: finalStage as ProjectStage
跳转逻辑 (第894-924行):
navigateToProject(project, columnId) {
// ❌ 问题:使用columnId而不是project.currentStage
const stagePath = stagePathMapping[columnId];
this.router.navigate(['/wxwork', cid, 'project', project.id, stagePath]);
}
dashboard.ts)数据来源:Project 表(通过DesignerService)
关键代码:
// 第551行:加载项目
const realProjects = await this.designerService.getProjects();
// 第428, 520行:获取阶段
currentStage: project.get('currentStage') || '未知阶段'
跳转逻辑 (第850-876行):
viewProjectDetails(projectId: string) {
const project = this.projects.find(p => p.id === projectId);
const currentStage = project?.currentStage || '订单分配';
// ✅ 正确:使用project.currentStage
const stagePath = stageRouteMap[currentStage] || 'order';
this.router.navigate(['/wxwork', cid, 'project', projectId, stagePath]);
}
错误代码 (project-list.ts 第894-924行):
navigateToProject(project: ProjectListItem, columnId: 'order' | 'requirements' | 'delivery' | 'aftercare') {
// ❌ 使用columnId(看板列ID),而不是project.currentStage
const stagePath = stagePathMapping[columnId];
this.router.navigate(['/wxwork', cid, 'project', project.id, stagePath]);
}
问题:
"确认需求"columnId = 'order'/project/{id}/order 而不是 /project/{id}/requirements正确方式:
navigateToProject(project: ProjectListItem) {
// ✅ 应该根据project.currentStage决定路由
const stageRouteMap = {
'订单分配': 'order',
'确认需求': 'requirements',
'交付执行': 'delivery',
'售后归档': 'aftercare'
};
const stagePath = stageRouteMap[project.currentStage] || 'order';
this.router.navigate(['/wxwork', cid, 'project', project.id, stagePath]);
}
代码位置 (project-detail.component.ts 第462-548行)
问题分析:
// 第492行:检查审批状态
const notApproved = approvalStatus !== 'approved';
if (orderStageIncomplete || notApproved) {
// ❌ 即使项目已经正常推进到确认需求,如果某些字段缺失也会回退
needRollback = true;
correctStage = '订单分配';
}
可能导致:
currentStage 已经是 "确认需求"approvalStatus 字段丢失或未同步审批通过代码 (stage-order.component.ts 第546-602行):
async approveOrder(): Promise<void> {
// 第570行:设置审批状态
data.approvalStatus = 'approved';
// 第576行:推进到确认需求
this.project.set('currentStage', '确认需求');
// 第585行:保存
await this.project.save();
// 第596-600行:刷新验证
this.project = await query.get(this.project.id);
}
可能的问题:
文件:project-list.ts 第894-924行
// 修改前
navigateToProject(project: ProjectListItem, columnId: 'order' | 'requirements' | 'delivery' | 'aftercare') {
const stagePath = stagePathMapping[columnId]; // ❌ 错误
this.router.navigate(['/wxwork', cid, 'project', project.id, stagePath]);
}
// 修改后
navigateToProject(project: ProjectListItem) {
const cid = localStorage.getItem('company') || '';
if (!cid) {
console.error('未找到公司ID');
return;
}
// ✅ 根据项目实际阶段决定路由
const stageRouteMap: Record<string, string> = {
'订单分配': 'order',
'确认需求': 'requirements',
'方案确认': 'requirements',
'方案深化': 'requirements',
'交付执行': 'delivery',
'建模': 'delivery',
'软装': 'delivery',
'渲染': 'delivery',
'后期': 'delivery',
'白模': 'delivery',
'售后归档': 'aftercare',
'尾款结算': 'aftercare',
'客户评价': 'aftercare'
};
const currentStage = project.currentStage || '订单分配';
const stagePath = stageRouteMap[currentStage] || 'order';
console.log(`🎯 项目"${project.name}"当前阶段: ${currentStage}, 跳转到: ${stagePath}`);
localStorage.setItem('enterFromCustomerService', '1');
localStorage.setItem('customerServiceMode', 'true');
this.router.navigate(['/wxwork', cid, 'project', project.id, stagePath]);
}
文件:project-detail.component.ts 第462-548行
// 修改检查逻辑,增加智能判断
if (projectStage && ['确认需求', '交付执行', '售后归档', ...].includes(projectStage)) {
const title = this.project.get('title');
const projectType = this.project.get('projectType');
const demoday = this.project.get('demoday');
const quotationTotal = data.quotation?.total || 0;
const approvalStatus = data.approvalStatus;
// 检查订单分配阶段是否完成
const orderStageIncomplete = !title || !projectType || !demoday || quotationTotal <= 0;
// ✅ 智能判断:如果有审批历史且最后一次是通过,认为已审批
const hasApprovedHistory = data.approvalHistory?.some((h: any) =>
h.stage === '订单分配' && h.status === 'approved'
);
// ⚠️ 只有在明确未审批且阶段未完成时才回退
const notApproved = approvalStatus !== 'approved' && !hasApprovedHistory;
if (orderStageIncomplete || notApproved) {
// 只有当两个条件都满足时才回退
if (orderStageIncomplete && notApproved) {
needRollback = true;
correctStage = '订单分配';
rollbackReason = `订单分配阶段未完成`;
} else {
console.warn('⚠️ 项目数据不完整但已审批,不回退');
}
}
}
文件:stage-order.component.ts 第546-602行
async approveOrder(): Promise<void> {
if (!this.project || !this.currentUser) return;
try {
const data = this.project.get('data') || {};
const approvalHistory = data.approvalHistory || [];
approvalHistory.push({
stage: '订单分配',
status: 'approved',
approver: this.currentUser.id,
approverName: this.currentUser.get('name'),
timestamp: new Date(),
comment: '组长审批通过'
});
data.approvalHistory = approvalHistory;
data.approvalStatus = 'approved'; // ✅ 明确设置
delete data.lastRejectionReason;
delete data.pendingApprovalBy;
this.project.set('data', data);
this.project.set('currentStage', '确认需求'); // ✅ 推进阶段
this.project.set('pendingApproval', false);
console.log('📝 [审批通过] 准备保存:', {
approvalStatus: data.approvalStatus,
currentStage: '确认需求'
});
await this.project.save();
// ✅ 强制刷新验证
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') || {};
console.log('✅ [审批通过] 保存后验证:', {
approvalStatus: savedData.approvalStatus, // 应该是 'approved'
currentStage: this.project.get('currentStage') // 应该是 '确认需求'
});
// ✅ 确保前端状态同步
if (savedData.approvalStatus !== 'approved') {
console.error('❌ 审批状态未正确保存!');
}
if (this.project.get('currentStage') !== '确认需求') {
console.error('❌ 项目阶段未正确推进!');
}
window?.fmode?.alert('审批通过,项目已进入确认需求阶段');
// ✅ 派发事件通知父组件刷新
document.dispatchEvent(new CustomEvent('stage:completed', {
detail: { stage: 'order', nextStage: 'requirements' }
}));
} catch (error) {
console.error('审批通过失败:', error);
window?.fmode?.alert('审批失败: ' + (error as any).message);
}
}
打开浏览器控制台,查看日志:
✅ [审批通过] 保存后验证:
approvalStatus: "approved"
currentStage: "确认需求"
刷新客服端项目列表,检查:
/project/{id}/requirements查看控制台日志:
🎯 项目"xxx"当前阶段: 确认需求, 跳转到: requirements
验证跳转:
/wxwork/{cid}/project/{id}/requirementsproject-list.ts - 修复客服端跳转逻辑project-detail.component.ts - 优化自动回退检查stage-order.component.ts - 增强审批通过后的验证1. 组长审批通过
├─ approvalStatus = 'approved'
├─ currentStage = '确认需求'
└─ 保存并验证
2. 客服端看到项目更新
├─ 项目显示在"确认需求"列
└─ currentStage = '确认需求'
3. 客服端点击项目
├─ 读取 project.currentStage = '确认需求'
├─ 映射路由: stageRouteMap['确认需求'] = 'requirements'
└─ 跳转: /wxwork/{cid}/project/{id}/requirements
4. 进入项目详情
├─ 自动回退检查
├─ 发现有审批历史且已通过
├─ 不回退
└─ 显示确认需求页面
让我现在就修复这些问题!