// 直接派发事件
console.log('📡 派发阶段完成事件: order');
try {
const event = new CustomEvent('stage:completed', {
detail: { stage: 'order' },
bubbles: true,
cancelable: true
});
document.dispatchEvent(event);
console.log('✅ 事件派发成功');
} catch (e) {
console.error('❌ 事件派发失败:', e);
}
问题: 如果父组件的监听器还未注册,事件会丢失
// ✨ 延迟派发事件,确保父组件监听器已注册
setTimeout(() => {
console.log('📡 派发阶段完成事件: order');
try {
const event = new CustomEvent('stage:completed', {
detail: { stage: 'order' },
bubbles: true,
cancelable: true
});
document.dispatchEvent(event);
console.log('✅ 事件派发成功');
} catch (e) {
console.error('❌ 事件派发失败:', e);
}
}, 100); // 延迟100ms,确保父组件监听器已注册
解决: 延迟100ms确保父组件初始化完成,监听器已注册
async ngOnInit() {
// 获取路由参数
this.cid = this.route.snapshot.paramMap.get('cid') || '';
// 兼容:cid 在父级路由上
if (!this.cid) {
this.cid = this.route.parent?.snapshot.paramMap.get('cid') || '';
}
this.projectId = this.route.snapshot.paramMap.get('projectId') || '';
// ... 其他初始化
}
问题: 如果路由参数中没有 cid,无法降级获取
async ngOnInit() {
// 获取路由参数
this.cid = this.route.snapshot.paramMap.get('cid') || '';
// 兼容:cid 在父级路由上
if (!this.cid) {
this.cid = this.route.parent?.snapshot.paramMap.get('cid') || '';
}
// 降级:从 localStorage 读取
if (!this.cid) {
this.cid = localStorage.getItem('company') || '';
}
this.projectId = this.route.snapshot.paramMap.get('projectId') || '';
this.groupId = this.route.snapshot.queryParamMap.get('groupId') || '';
this.profileId = this.route.snapshot.queryParamMap.get('profileId') || '';
this.chatId = this.route.snapshot.queryParamMap.get('chatId') || '';
console.log('📌 路由参数:', {
cid: this.cid,
projectId: this.projectId
});
// ... 其他初始化
}
解决: 添加 localStorage 降级方案 + 日志输出便于调试
goToStage(stageId: 'order'|'requirements'|'delivery'|'aftercare') {
console.log('🚀 [goToStage] 开始导航', {
目标阶段: stageId,
当前路由: this.router.url,
cid: this.cid,
projectId: this.projectId
});
this.currentStage = stageId;
// 优先使用绝对路径导航
if (this.cid && this.projectId) {
console.log('🚀 [goToStage] 使用绝对路径导航');
this.router.navigate(['/wxwork', this.cid, 'project', this.projectId, stageId])
.then(success => {
if (success) {
console.log('✅ [goToStage] 导航成功:', stageId);
} else {
console.error('❌ [goToStage] 导航失败,尝试相对路径');
return this.router.navigate(['../', stageId], { relativeTo: this.route });
}
})
.catch(err => {
console.error('❌ [goToStage] 导航出错:', err);
});
} else {
// 降级:使用相对路径
console.warn('⚠️ [goToStage] 缺少参数,使用相对路径', {
cid: this.cid,
projectId: this.projectId
});
this.router.navigate([stageId], { relativeTo: this.route })
.then(success => {
if (success) {
console.log('✅ [goToStage] 相对路径导航成功');
} else {
console.error('❌ [goToStage] 相对路径导航失败');
}
})
.catch(err => {
console.error('❌ [goToStage] 相对路径导航出错:', err);
});
}
}
关键改进:
/wxwork/:cid/project/:projectId/:stage[stage] 而非 ['../', stage]| 修复项 | 修改前 | 修改后 | 影响的文件 |
|---|---|---|---|
| 事件派发 | 直接派发 | setTimeout 100ms | 4个阶段组件 |
| cid 获取 | 仅从路由 | 路由 + localStorage | project-detail.component.ts |
| 日志输出 | 基础日志 | 详细调试日志 | 所有组件 |
| 路由导航 | 相对路径 | 绝对路径优先 | project-detail.component.ts |
project-detail.component.ts (2处修改)stage-order.component.ts (1处修改)stage-requirements.component.ts (1处修改)stage-delivery.component.ts (1处修改)stage-aftercare.component.ts (1处修改)总计: 5个文件,6处修改
位置: 所有 stage-*.component.ts 中的提交方法
代码模式:
// ✨ 延迟派发事件,确保父组件监听器已注册
setTimeout(() => {
console.log('📡 派发阶段完成事件: [stage-name]');
try {
const event = new CustomEvent('stage:completed', {
detail: { stage: '[stage-name]' },
bubbles: true,
cancelable: true
});
document.dispatchEvent(event);
console.log('✅ 事件派发成功');
} catch (e) {
console.error('❌ 事件派发失败:', e);
}
}, 100);
位置: project-detail.component.ts 的 ngOnInit()
代码模式:
// 降级:从 localStorage 读取
if (!this.cid) {
this.cid = localStorage.getItem('company') || '';
}
console.log('📌 路由参数:', {
cid: this.cid,
projectId: this.projectId
});
在控制台看到以下日志序列:
✅ 项目保存成功
// 等待 100ms
📡 派发阶段完成事件: order
✅ 事件派发成功
🎯 [监听器] 事件触发
时间间隔: 保存成功和派发事件之间应有约 100ms 延迟
在控制台看到:
📌 路由参数: { cid: 'cDL6R1hgSi', projectId: 'Wf2f3aFqBI' }
检查: cid 不为空字符串
在控制台看到:
🚀 [goToStage] 使用绝对路径导航
✅ [goToStage] 导航成功: requirements
检查: URL 变为 .../requirements
文档创建时间: 2025-11-04
修复状态: ✅ 全部完成
Linter 检查: ✅ 无错误