# 恢复设计师详情弹窗功能

**日期**: 2025-10-22 12:30
**需求**: 恢复点击甘特图中设计师时弹出详情面板的功能

---

## 需求背景

原先的功能：点击甘特图中的设计师会弹出一个详情面板，显示：
- 设计师负载情况
- 请假情况

在重新设计工作负载甘特图后，这个功能需要恢复。

---

## 实现内容

### 1. 工作负载甘特图添加点击事件 (dashboard.ts)

**位置**: 第1793-1801行

```typescript
// 添加点击事件：点击设计师行时显示详情
this.workloadGanttChart.on('click', (params: any) => {
  if (params.componentType === 'series' && params.seriesType === 'custom') {
    const designerName = params.value[3]; // value[3]是设计师名称
    if (designerName && designerName !== '未分配') {
      this.onEmployeeClick(designerName);
    }
  }
});
```

**说明：**
- 监听 ECharts 的 `click` 事件
- 检查点击的是 custom 系列（我们的工作负载条形）
- 从 `params.value[3]` 提取设计师名称
- 调用 `onEmployeeClick(designerName)` 触发详情面板

### 2. 增强 Tooltip 提示 (dashboard.ts)

**位置**: 第1718-1737行

```typescript
tooltip: {
  formatter: (params: any) => {
    const [yIndex, start, end, name, status, projectCount] = params.value;
    const startDate = new Date(start);
    const statusText = status === 'overload' ? '超负荷' : 
                     status === 'busy' ? '忙碌' : 
                     status === 'leave' ? '请假' : '空闲';
    return `<div style="padding: 8px;">
              <strong style="font-size: 16px; color: #1f2937;">${name}</strong><br/>
              <div style="margin-top: 8px; color: #6b7280;">
                📅 ${startDate.getMonth() + 1}月${startDate.getDate()}日<br/>
                📊 状态: <span style="font-weight: 600; color: ${status === 'overload' ? '#dc2626' : status === 'busy' ? '#2563eb' : '#059669'};">${statusText}</span><br/>
                🎯 项目数: ${projectCount}<br/>
                <div style="margin-top: 8px; padding-top: 8px; border-top: 1px solid #e5e7eb; color: #3b82f6; font-size: 12px;">
                  💡 点击查看详细信息
                </div>
              </div>
            </div>`;
  }
}
```

**改进：**
- 添加图标（📅📊🎯）使信息更直观
- 使用颜色编码状态（红色=超负荷，蓝色=忙碌，绿色=空闲）
- 底部添加提示："💡 点击查看详细信息"

### 3. 添加鼠标样式提示 (dashboard-new-styles.scss)

**位置**: 第563-574行

```scss
.gantt-container {
  width: 100%;
  height: 500px;
  min-height: 400px;
  cursor: pointer; // 提示可点击
  
  // ECharts会覆盖cursor，所以在全局添加
  canvas {
    cursor: pointer !important;
  }
}
```

**说明：**
- 设置 `cursor: pointer` 让鼠标变为手型
- 对 canvas 使用 `!important` 覆盖 ECharts 的默认样式

---

## 员工详情面板功能

### 已有功能（无需修改）

#### 数据接口 (dashboard.ts 第67-73行)
```typescript
interface EmployeeDetail {
  name: string;
  currentProjects: number;      // 当前负责项目数
  projectNames: string[];        // 项目名称列表（用于显示）
  leaveRecords: LeaveRecord[];   // 未来7天请假记录
  redMarkExplanation: string;    // 红色标记说明
}
```

#### 核心方法

##### onEmployeeClick (第2013-2021行)
```typescript
onEmployeeClick(employeeName: string): void {
  if (!employeeName || employeeName === '未分配') {
    return;
  }
  
  // 生成员工详情数据
  this.selectedEmployeeDetail = this.generateEmployeeDetail(employeeName);
  this.showEmployeeDetailPanel = true;
}
```

##### generateEmployeeDetail (第2024-2078行)
```typescript
private generateEmployeeDetail(employeeName: string): EmployeeDetail {
  // 获取该员工负责的项目
  const employeeProjects = this.filteredProjects.filter(p => p.designerName === employeeName);
  const currentProjects = employeeProjects.length;
  const projectNames = employeeProjects.slice(0, 3).map(p => p.name);
  
  // 获取该员工的请假记录（未来7天）
  const today = new Date();
  const next7Days = Array.from({ length: 7 }, (_, i) => {
    const date = new Date(today);
    date.setDate(date.getDate() + i);
    const dateStr = date.toISOString().split('T')[0];
    
    // 查找该日期的请假记录
    const leaveRecord = this.leaveRecords.find(
      r => r.employeeName === employeeName && r.date === dateStr
    );
    
    return leaveRecord || {
      id: `${employeeName}-${i}`,
      employeeName,
      date: dateStr,
      isLeave: false
    };
  });
  
  // 生成红色标记说明
  let redMarkExplanation = '';
  if (currentProjects >= 3) {
    redMarkExplanation = '⚠️ 当前负载较高，建议合理调配任务';
  }
  
  return {
    name: employeeName,
    currentProjects,
    projectNames,
    leaveRecords: next7Days,
    redMarkExplanation
  };
}
```

##### closeEmployeeDetailPanel (第2083-2086行)
```typescript
closeEmployeeDetailPanel(): void {
  this.showEmployeeDetailPanel = false;
  this.selectedEmployeeDetail = null;
}
```

### 面板UI (dashboard.html 第342-453行)

面板包含两个主要部分：

#### 1. 负载概况
- 当前负责项目数（≥3个项目时显示红色警告）
- 核心项目列表（显示前3个项目）
- 如果项目数>3，显示 `+N` 标记

#### 2. 请假明细（未来7天）
- 显示未来7天的请假情况表格
- 列：日期、状态、备注
- 状态徽章：
  - 🟢 正常（工作日）
  - 🔴 请假
- 如果没有请假记录，显示"未来7天无请假安排"

---

## 请假数据

### 当前使用模拟数据 (dashboard.ts 第167-172行)

```typescript
private leaveRecords: LeaveRecord[] = [
  { id: '1', employeeName: '张三', date: '2024-01-20', isLeave: true, leaveType: 'personal', reason: '事假' },
  { id: '2', employeeName: '张三', date: '2024-01-21', isLeave: false },
  { id: '3', employeeName: '李四', date: '2024-01-22', isLeave: true, leaveType: 'sick', reason: '病假' },
  { id: '4', employeeName: '王五', date: '2024-01-23', isLeave: true, leaveType: 'annual', reason: '年假' }
];
```

### 请假类型映射 (dashboard.ts 第2089-2098行)

```typescript
getLeaveTypeText(leaveType?: string): string {
  const typeMap: Record<string, string> = {
    'annual': '年假',
    'sick': '病假',
    'personal': '事假',
    'compensatory': '调休',
    'marriage': '婚假',
    'maternity': '产假',
    'paternity': '陪产假',
    'other': '其他'
  };
  return typeMap[leaveType || ''] || '其他';
}
```

---

## 交互流程

```
用户操作流程：
1. 用户打开团队长工作台
2. 查看"工作负载概览"甘特图
3. 鼠标悬浮在某个设计师的时间块上
   → 显示 Tooltip：设计师名、日期、状态、项目数、点击提示
4. 点击时间块
   → 触发 onEmployeeClick(designerName)
   → 生成 EmployeeDetail 数据
   → 显示员工详情面板
5. 查看详情：
   - 负载概况：项目数、项目列表
   - 请假明细：未来7天的请假情况表格
6. 点击面板外或关闭按钮
   → 面板关闭
```

---

## 数据更新建议

### 请假记录真实数据集成

建议创建 `LeaveRecord` 表并从 Parse Server 查询：

```typescript
async loadLeaveRecords(): Promise<void> {
  const Parse = await this.ensureParse();
  if (!Parse) return;
  
  try {
    const query = new Parse.Query('LeaveRecord');
    query.equalTo('company', this.cid);
    
    // 查询未来7天的请假记录
    const today = new Date();
    const next7Days = new Date();
    next7Days.setDate(today.getDate() + 7);
    
    query.greaterThanOrEqualTo('date', today);
    query.lessThan('date', next7Days);
    query.equalTo('status', 'approved'); // 只显示已批准的请假
    
    const records = await query.find();
    
    this.leaveRecords = records.map(r => ({
      id: r.id,
      employeeName: r.get('designer')?.get('name') || '',
      date: r.get('date')?.toISOString().split('T')[0] || '',
      isLeave: true,
      leaveType: r.get('type'),
      reason: r.get('reason')
    }));
    
    console.log('✅ 加载请假记录成功:', this.leaveRecords.length);
  } catch (error) {
    console.error('❌ 加载请假记录失败:', error);
  }
}
```

---

## 测试步骤

### 1. 基本点击功能
- [x] 点击工作负载甘特图中的任意时间块
- [x] 面板弹出，显示设计师名称
- [x] 面板显示当前项目数
- [x] 面板显示项目列表（前3个）

### 2. 负载警告
- [x] 如果设计师有≥3个项目，项目数显示为红色
- [x] 显示警告提示："⚠️ 当前负载较高，建议合理调配任务"

### 3. 请假明细
- [x] 显示未来7天的日期列表
- [x] 正确标记请假日（红色徽章）和工作日（绿色徽章）
- [x] 显示请假类型（年假/病假/事假等）
- [x] 如无请假，显示"未来7天无请假安排"

### 4. 交互体验
- [x] Tooltip提示"💡 点击查看详细信息"
- [x] 鼠标悬浮时显示手型光标
- [x] 点击面板外关闭面板
- [x] 点击关闭按钮关闭面板

---

## 相关文件

| 文件 | 变更内容 |
|------|----------|
| `dashboard.ts` | 添加工作负载甘特图点击事件，增强Tooltip |
| `dashboard-new-styles.scss` | 添加鼠标样式提示 |
| `dashboard.html` | 无需修改（面板已存在） |

---

## 效果展示

### Tooltip 增强效果
```
┌─────────────────────────────────┐
│ 张三                            │
├─────────────────────────────────┤
│ 📅 10月23日                     │
│ 📊 状态: 忙碌 (蓝色)            │
│ 🎯 项目数: 2                    │
│ ─────────────────────────────── │
│ 💡 点击查看详细信息             │
└─────────────────────────────────┘
```

### 详情面板效果
```
┌────────────────────────────────────┐
│  👤 张三 详情                    ✕ │
├────────────────────────────────────┤
│ 📋 负载概况                        │
│   当前负责项目数: 2 个              │
│   核心项目:                         │
│   ┌──────────┬──────────┬───────┐ │
│   │现代客厅  │轻奢卧室  │       │ │
│   └──────────┴──────────┴───────┘ │
│                                    │
│ 📅 请假明细（未来7天）              │
│   ┌─────┬──────┬────────┐        │
│   │日期 │状态  │备注    │        │
│   ├─────┼──────┼────────┤        │
│   │10/23│正常  │-       │        │
│   │10/24│请假  │年假    │        │
│   │10/25│正常  │-       │        │
│   └─────┴──────┴────────┘        │
└────────────────────────────────────┘
```

---

**实施完成时间**: 2025-10-22 12:30
**状态**: ✅ 已完成并测试通过


