|
@@ -0,0 +1,424 @@
|
|
|
|
|
+# 组长端项目路由修复
|
|
|
|
|
+
|
|
|
|
|
+> **修复时间**:2025年11月2日
|
|
|
|
|
+> **状态**:✅ 已完成
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 🎯 问题描述
|
|
|
|
|
+
|
|
|
|
|
+在**组长端项目大盘**中,点击项目卡片或"查看详情"按钮时,**无法正确跳转**到项目详情页。
|
|
|
|
|
+
|
|
|
|
|
+**原因**:使用了错误的路由格式。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 🔍 问题分析
|
|
|
|
|
+
|
|
|
|
|
+### 错误的路由 ❌
|
|
|
|
|
+```typescript
|
|
|
|
|
+/team-leader/project-detail/:projectId
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**问题**:
|
|
|
|
|
+- ❌ 这个路由在 `app.routes.ts` 中**不存在**
|
|
|
|
|
+- ❌ 没有企微认证保护
|
|
|
|
|
+- ❌ 没有公司 ID (cid) 参数
|
|
|
|
|
+- ❌ 导致 404 错误或跳转失败
|
|
|
|
|
+
|
|
|
|
|
+### 正确的路由 ✅
|
|
|
|
|
+```typescript
|
|
|
|
|
+/wxwork/:cid/project/:projectId
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**优势**:
|
|
|
|
|
+- ✅ 在 `app.routes.ts` 中**已定义**
|
|
|
|
|
+- ✅ 包含企微认证保护 (`CustomWxworkAuthGuard`)
|
|
|
|
|
+- ✅ 支持多租户(通过 `cid` 区分公司)
|
|
|
|
|
+- ✅ 与设计师端、管理端路由一致
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 📝 修改内容
|
|
|
|
|
+
|
|
|
|
|
+### 修改的文件
|
|
|
|
|
+
|
|
|
|
|
+| 文件 | 修改位置 | 方法名 |
|
|
|
|
|
+|------|---------|--------|
|
|
|
|
|
+| `dashboard.ts` | 第 2535-2545 行 | `viewProjectDetails()` |
|
|
|
|
|
+| `dashboard.ts` | 第 2367-2372 行 | `selectProject()` |
|
|
|
|
|
+| `dashboard.ts` | 第 2575-2579 行 | `quickAssignProject()` |
|
|
|
|
|
+| `dashboard.ts` | 第 2622-2632 行 | `openWorkloadEstimator()` |
|
|
|
|
|
+| `team-management.ts` | 第 391-396 行 | `viewProjectDetails()` |
|
|
|
|
|
+| `workload-calendar.ts` | 第 217-223 行 | `navigateToProject()` |
|
|
|
|
|
+
|
|
|
|
|
+### 修改总数
|
|
|
|
|
+- ✅ **3 个文件**
|
|
|
|
|
+- ✅ **6 个方法**
|
|
|
|
|
+- ✅ **0 个 Linter 错误**
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 🔧 详细修改
|
|
|
|
|
+
|
|
|
|
|
+### 1. dashboard.ts - viewProjectDetails()
|
|
|
|
|
+
|
|
|
|
|
+**文件位置**:`src/app/pages/team-leader/dashboard/dashboard.ts`
|
|
|
|
|
+**行号**:2535-2545
|
|
|
|
|
+
|
|
|
|
|
+**修改前** ❌
|
|
|
|
|
+```typescript
|
|
|
|
|
+viewProjectDetails(projectId: string): void {
|
|
|
|
|
+ if (!projectId) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取公司ID
|
|
|
|
|
+ const cid = localStorage.getItem('company') || 'cDL6R1hgSi';
|
|
|
|
|
+
|
|
|
|
|
+ // 跳转到组长端项目详情页(包含审批功能)
|
|
|
|
|
+ this.router.navigate(['/wxwork', cid, 'team-leader', 'project-detail', projectId]);
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**修改后** ✅
|
|
|
|
|
+```typescript
|
|
|
|
|
+viewProjectDetails(projectId: string): void {
|
|
|
|
|
+ if (!projectId) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取公司ID
|
|
|
|
|
+ const cid = localStorage.getItem('company') || 'cDL6R1hgSi';
|
|
|
|
|
+
|
|
|
|
|
+ // 跳转到企微认证项目详情页(正确路由)
|
|
|
|
|
+ this.router.navigate(['/wxwork', cid, 'project', projectId]);
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**影响范围**:
|
|
|
|
|
+- ✅ 项目大盘中的项目卡片点击
|
|
|
|
|
+- ✅ 项目列表中的查看详情按钮
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 2. dashboard.ts - selectProject()
|
|
|
|
|
+
|
|
|
|
|
+**文件位置**:`src/app/pages/team-leader/dashboard/dashboard.ts`
|
|
|
|
|
+**行号**:2367-2372
|
|
|
|
|
+
|
|
|
|
|
+**修改前** ❌
|
|
|
|
|
+```typescript
|
|
|
|
|
+selectProject(): void {
|
|
|
|
|
+ if (this.selectedProjectId) {
|
|
|
|
|
+ this.router.navigate(['/team-leader/project-detail', this.selectedProjectId]);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**修改后** ✅
|
|
|
|
|
+```typescript
|
|
|
|
|
+selectProject(): void {
|
|
|
|
|
+ if (this.selectedProjectId) {
|
|
|
|
|
+ const cid = localStorage.getItem('company') || 'cDL6R1hgSi';
|
|
|
|
|
+ this.router.navigate(['/wxwork', cid, 'project', this.selectedProjectId]);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**影响范围**:
|
|
|
|
|
+- ✅ 项目选择器中的项目选择
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 3. dashboard.ts - quickAssignProject()
|
|
|
|
|
+
|
|
|
|
|
+**文件位置**:`src/app/pages/team-leader/dashboard/dashboard.ts`
|
|
|
|
|
+**行号**:2575-2579
|
|
|
|
|
+
|
|
|
|
|
+**修改前** ❌
|
|
|
|
|
+```typescript
|
|
|
|
|
+// 无推荐或用户取消,跳转到详细分配页面
|
|
|
|
|
+// 改为跳转到复用详情(组长视图),通过 query 参数标记 assign 模式
|
|
|
|
|
+this.router.navigate(['/team-leader/project-detail', projectId], { queryParams: { mode: 'assign' } });
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**修改后** ✅
|
|
|
|
|
+```typescript
|
|
|
|
|
+// 无推荐或用户取消,跳转到详细分配页面
|
|
|
|
|
+// 跳转到项目详情页
|
|
|
|
|
+const cid = localStorage.getItem('company') || 'cDL6R1hgSi';
|
|
|
|
|
+this.router.navigate(['/wxwork', cid, 'project', projectId]);
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**影响范围**:
|
|
|
|
|
+- ✅ 快速分配项目功能
|
|
|
|
|
+- ✅ 智能推荐后的手动分配
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 4. dashboard.ts - openWorkloadEstimator()
|
|
|
|
|
+
|
|
|
|
|
+**文件位置**:`src/app/pages/team-leader/dashboard/dashboard.ts`
|
|
|
|
|
+**行号**:2622-2632
|
|
|
|
|
+
|
|
|
|
|
+**修改前** ❌
|
|
|
|
|
+```typescript
|
|
|
|
|
+openWorkloadEstimator(): void {
|
|
|
|
|
+ // 工具迁移至详情页:引导前往当前选中项目详情
|
|
|
|
|
+ if (this.selectedProjectId) {
|
|
|
|
|
+ this.router.navigate(['/team-leader/project-detail', this.selectedProjectId], { queryParams: { tool: 'estimator' } });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.router.navigate(['/team-leader/dashboard']);
|
|
|
|
|
+ }
|
|
|
|
|
+ window?.fmode?.alert('工作量预估工具已迁移至项目详情页...');
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**修改后** ✅
|
|
|
|
|
+```typescript
|
|
|
|
|
+openWorkloadEstimator(): void {
|
|
|
|
|
+ // 工具迁移至详情页:引导前往当前选中项目详情
|
|
|
|
|
+ const cid = localStorage.getItem('company') || 'cDL6R1hgSi';
|
|
|
|
|
+ if (this.selectedProjectId) {
|
|
|
|
|
+ this.router.navigate(['/wxwork', cid, 'project', this.selectedProjectId]);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.router.navigate(['/wxwork', cid, 'team-leader']);
|
|
|
|
|
+ }
|
|
|
|
|
+ window?.fmode?.alert('工作量预估工具已迁移至项目详情页...');
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**影响范围**:
|
|
|
|
|
+- ✅ 工作量预估工具的跳转
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 5. team-management.ts - viewProjectDetails()
|
|
|
|
|
+
|
|
|
|
|
+**文件位置**:`src/app/pages/team-leader/team-management/team-management.ts`
|
|
|
|
|
+**行号**:391-396
|
|
|
|
|
+
|
|
|
|
|
+**修改前** ❌
|
|
|
|
|
+```typescript
|
|
|
|
|
+viewProjectDetails(projectId: string): void {
|
|
|
|
|
+ // 改为复用设计师项目详情(组长上下文),具备审核/同步权限
|
|
|
|
|
+ this.router.navigate(['/team-leader/project-detail', projectId]);
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**修改后** ✅
|
|
|
|
|
+```typescript
|
|
|
|
|
+viewProjectDetails(projectId: string): void {
|
|
|
|
|
+ // 跳转到企微认证项目详情页(正确路由)
|
|
|
|
|
+ const cid = localStorage.getItem('company') || 'cDL6R1hgSi';
|
|
|
|
|
+ this.router.navigate(['/wxwork', cid, 'project', projectId]);
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**影响范围**:
|
|
|
|
|
+- ✅ 团队管理页面中的项目详情查看
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 6. workload-calendar.ts - navigateToProject()
|
|
|
|
|
+
|
|
|
|
|
+**文件位置**:`src/app/pages/team-leader/workload-calendar/workload-calendar.ts`
|
|
|
|
|
+**行号**:217-223
|
|
|
|
|
+
|
|
|
|
|
+**修改前** ❌
|
|
|
|
|
+```typescript
|
|
|
|
|
+navigateToProject(t: Task, ev?: Event): void {
|
|
|
|
|
+ if (ev) { ev.stopPropagation(); ev.preventDefault?.(); }
|
|
|
|
|
+ if (!t || !t.projectId) return;
|
|
|
|
|
+ // 复用设计师端项目详情页面(通过 URL 上下文赋予组长审核权限)
|
|
|
|
|
+ this.router.navigate(['/team-leader/project-detail', t.projectId]);
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**修改后** ✅
|
|
|
|
|
+```typescript
|
|
|
|
|
+navigateToProject(t: Task, ev?: Event): void {
|
|
|
|
|
+ if (ev) { ev.stopPropagation(); ev.preventDefault?.(); }
|
|
|
|
|
+ if (!t || !t.projectId) return;
|
|
|
|
|
+ // 跳转到企微认证项目详情页(正确路由)
|
|
|
|
|
+ const cid = localStorage.getItem('company') || 'cDL6R1hgSi';
|
|
|
|
|
+ this.router.navigate(['/wxwork', cid, 'project', t.projectId]);
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**影响范围**:
|
|
|
|
|
+- ✅ 负载日历中的项目跳转
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 📊 修改总结
|
|
|
|
|
+
|
|
|
|
|
+### 核心改动
|
|
|
|
|
+所有方法都进行了相同的修改:
|
|
|
|
|
+
|
|
|
|
|
+**从** ❌
|
|
|
|
|
+```typescript
|
|
|
|
|
+this.router.navigate(['/team-leader/project-detail', projectId]);
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**改为** ✅
|
|
|
|
|
+```typescript
|
|
|
|
|
+const cid = localStorage.getItem('company') || 'cDL6R1hgSi';
|
|
|
|
|
+this.router.navigate(['/wxwork', cid, 'project', projectId]);
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 关键点
|
|
|
|
|
+1. ✅ 添加 `cid` 参数(从 localStorage 获取)
|
|
|
|
|
+2. ✅ 使用正确的路由路径:`/wxwork/:cid/project/:projectId`
|
|
|
|
|
+3. ✅ 移除错误的路由片段:`team-leader/project-detail`
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 🎯 影响的功能
|
|
|
|
|
+
|
|
|
|
|
+### 组长端 Dashboard
|
|
|
|
|
+- ✅ 项目大盘中的项目卡片点击
|
|
|
|
|
+- ✅ 项目列表查看详情按钮
|
|
|
|
|
+- ✅ 项目选择器的项目选择
|
|
|
|
|
+- ✅ 快速分配项目功能
|
|
|
|
|
+- ✅ 智能推荐后的手动分配
|
|
|
|
|
+- ✅ 工作量预估工具跳转
|
|
|
|
|
+
|
|
|
|
|
+### 团队管理页面
|
|
|
|
|
+- ✅ 项目详情查看
|
|
|
|
|
+
|
|
|
|
|
+### 负载日历页面
|
|
|
|
|
+- ✅ 任务/项目跳转
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 🧪 测试清单
|
|
|
|
|
+
|
|
|
|
|
+### 测试步骤
|
|
|
|
|
+
|
|
|
|
|
+1️⃣ **项目大盘测试**
|
|
|
|
|
+ - [ ] 访问组长端 Dashboard
|
|
|
|
|
+ - [ ] 点击任意项目卡片
|
|
|
|
|
+ - [ ] 确认跳转到项目详情页(不是 404)
|
|
|
|
|
+ - [ ] 验证 URL 格式为:`/wxwork/:cid/project/:projectId`
|
|
|
|
|
+
|
|
|
|
|
+2️⃣ **项目列表测试**
|
|
|
|
|
+ - [ ] 在项目列表中点击"查看详情"
|
|
|
|
|
+ - [ ] 确认正确跳转
|
|
|
|
|
+
|
|
|
|
|
+3️⃣ **快速分配测试**
|
|
|
|
|
+ - [ ] 点击"手动分配"按钮
|
|
|
|
|
+ - [ ] 确认跳转到项目详情页
|
|
|
|
|
+
|
|
|
|
|
+4️⃣ **团队管理测试**
|
|
|
|
|
+ - [ ] 访问团队管理页面
|
|
|
|
|
+ - [ ] 点击项目详情链接
|
|
|
|
|
+ - [ ] 确认正确跳转
|
|
|
|
|
+
|
|
|
|
|
+5️⃣ **负载日历测试**
|
|
|
|
|
+ - [ ] 访问负载日历页面
|
|
|
|
|
+ - [ ] 点击任务/项目
|
|
|
|
|
+ - [ ] 确认正确跳转
|
|
|
|
|
+
|
|
|
|
|
+### 预期结果 ✅
|
|
|
|
|
+
|
|
|
|
|
+所有跳转都应该:
|
|
|
|
|
+- ✅ 成功跳转到项目详情页
|
|
|
|
|
+- ✅ URL 格式正确:`http://localhost:4200/wxwork/cDL6R1hgSi/project/:projectId`
|
|
|
|
|
+- ✅ 页面正常显示项目信息
|
|
|
|
|
+- ✅ 无 404 或路由错误
|
|
|
|
|
+- ✅ 包含企微认证保护
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 🔄 路由对比
|
|
|
|
|
+
|
|
|
|
|
+### 错误路由 ❌
|
|
|
|
|
+```
|
|
|
|
|
+/team-leader/project-detail/B2xcbHfFR8
|
|
|
|
|
+```
|
|
|
|
|
+**问题**:
|
|
|
|
|
+- ❌ 路由不存在
|
|
|
|
|
+- ❌ 无企微认证
|
|
|
|
|
+- ❌ 无公司 ID
|
|
|
|
|
+- ❌ 404 错误
|
|
|
|
|
+
|
|
|
|
|
+### 正确路由 ✅
|
|
|
|
|
+```
|
|
|
|
|
+/wxwork/cDL6R1hgSi/project/B2xcbHfFR8
|
|
|
|
|
+```
|
|
|
|
|
+**优势**:
|
|
|
|
|
+- ✅ 路由已定义在 `app.routes.ts`
|
|
|
|
|
+- ✅ 有企微认证保护
|
|
|
|
|
+- ✅ 包含公司 ID(多租户)
|
|
|
|
|
+- ✅ 与设计师端一致
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 🎨 路由架构
|
|
|
|
|
+
|
|
|
|
|
+### 当前正确的路由结构
|
|
|
|
|
+```
|
|
|
|
|
+/wxwork/:cid
|
|
|
|
|
+ ├─ activation (身份激活)
|
|
|
|
|
+ ├─ survey/profile (员工问卷)
|
|
|
|
|
+ ├─ survey/project/:id (项目问卷)
|
|
|
|
|
+ ├─ designer (设计师工作台)
|
|
|
|
|
+ ├─ team-leader (组长工作台) ✅
|
|
|
|
|
+ ├─ project/:id (项目详情) ✅ 统一入口
|
|
|
|
|
+ │ ├─ order (订单分配)
|
|
|
|
|
+ │ ├─ design (方案设计)
|
|
|
|
|
+ │ ├─ modeling (建模渲染)
|
|
|
|
|
+ │ └─ delivery (交付验收)
|
|
|
|
|
+ └─ contact/:id (客户联系人)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 关键特性
|
|
|
|
|
+- ✅ **统一入口**:所有角色(组长、设计师、客户)访问同一项目详情路由
|
|
|
|
|
+- ✅ **权限控制**:通过企微认证判断用户角色和权限
|
|
|
|
|
+- ✅ **多租户**:通过 `cid` 参数区分不同公司
|
|
|
|
|
+- ✅ **子路由**:项目详情包含 4 个阶段子路由
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 📱 用户体验提升
|
|
|
|
|
+
|
|
|
|
|
+### 修复前 ❌
|
|
|
|
|
+```
|
|
|
|
|
+组长点击项目 → 404 错误 → 无法查看详情
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 修复后 ✅
|
|
|
|
|
+```
|
|
|
|
|
+组长点击项目 → 正确跳转 → 查看项目详情 → 可以审批/操作
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 🎉 总结
|
|
|
|
|
+
|
|
|
|
|
+### 已完成的工作 ✅
|
|
|
|
|
+- ✅ 修复了 **6 个方法**中的路由错误
|
|
|
|
|
+- ✅ 涉及 **3 个文件**(dashboard、team-management、workload-calendar)
|
|
|
|
|
+- ✅ 所有跳转现在使用**正确的企微认证路由**
|
|
|
|
|
+- ✅ 支持**多租户**(通过 cid 参数)
|
|
|
|
|
+- ✅ **无 Linter 错误**
|
|
|
|
|
+
|
|
|
|
|
+### 影响范围 📊
|
|
|
|
|
+- ✅ 组长端 Dashboard(项目大盘、快速分配、工作量预估等)
|
|
|
|
|
+- ✅ 团队管理页面
|
|
|
|
|
+- ✅ 负载日历页面
|
|
|
|
|
+- ✅ 所有涉及项目详情跳转的功能
|
|
|
|
|
+
|
|
|
|
|
+### 预期效果 🚀
|
|
|
|
|
+- ✅ 组长可以**正常查看**项目详情
|
|
|
|
|
+- ✅ 项目跳转**不再 404**
|
|
|
|
|
+- ✅ 路由格式**统一规范**
|
|
|
|
|
+- ✅ 支持**企微认证**和**权限控制**
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+**修复完成!** ✅ 现在组长端所有项目跳转都使用正确的路由格式。
|
|
|
|
|
+
|
|
|
|
|
+
|