组长端设计师负载日历月份切换功能.md 9.1 KB

组长端设计师负载日历月份切换功能

功能概述

为组长端的设计师详情面板中的负载详细日历添加上月/下月切换按钮,允许组长查看设计师在不同月份的工作负载情况。

实现日期

2025年11月3日

修改的文件

1. src/app/pages/team-leader/dashboard/dashboard.html

修改位置:第441-462行(日历月份标题部分)

修改内容

  • 在月份标题左侧添加"上月"按钮
  • 在月份标题右侧添加"下月"按钮
  • 使用SVG图标展示箭头
  • 绑定点击事件到 changeEmployeeCalendarMonth() 方法

代码片段

<div class="calendar-month-header">
  <button class="btn-prev-month" 
          (click)="changeEmployeeCalendarMonth(-1)"
          title="上月">
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
      <polyline points="15 18 9 12 15 6"></polyline>
    </svg>
  </button>
  <span class="month-title">
    {{ selectedEmployeeDetail.calendarData.currentMonth | date:'yyyy年M月' }}
  </span>
  <button class="btn-next-month" 
          (click)="changeEmployeeCalendarMonth(1)"
          title="下月">
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
      <polyline points="9 18 15 12 9 6"></polyline>
    </svg>
  </button>
</div>

2. src/app/pages/team-leader/dashboard/dashboard.ts

修改1:添加员工日历相关数据属性(第207-209行)

目的:保存当前员工信息和项目数据,用于月份切换时重新生成日历

// 当前员工日历相关数据(用于切换月份)
private currentEmployeeName: string = '';
private currentEmployeeProjects: any[] = [];

修改2:修改 generateEmployeeDetail 方法(第2694-2699行)

目的:在生成员工详情时保存员工信息和项目数据

// 保存当前员工信息和项目数据(用于切换月份)
this.currentEmployeeName = employeeName;
this.currentEmployeeProjects = employeeProjects;

// 生成日历数据
const calendarData = this.generateEmployeeCalendar(employeeName, employeeProjects);

修改3:修改 generateEmployeeCalendar 方法签名(第2771行)

目的:支持传入指定月份参数

修改前

private generateEmployeeCalendar(employeeName: string, employeeProjects: any[]): EmployeeCalendarData {
  const currentMonth = new Date();

修改后

private generateEmployeeCalendar(employeeName: string, employeeProjects: any[], targetMonth?: Date): EmployeeCalendarData {
  const currentMonth = targetMonth || new Date();

修改4:添加 changeEmployeeCalendarMonth 方法(第2920-2945行)

目的:实现月份切换逻辑

/**
 * 切换员工日历月份
 * @param direction -1=上月, 1=下月
 */
changeEmployeeCalendarMonth(direction: number): void {
  if (!this.selectedEmployeeDetail?.calendarData) {
    return;
  }
  
  const currentMonth = this.selectedEmployeeDetail.calendarData.currentMonth;
  const newMonth = new Date(currentMonth);
  newMonth.setMonth(newMonth.getMonth() + direction);
  
  // 重新生成日历数据
  const newCalendarData = this.generateEmployeeCalendar(
    this.currentEmployeeName, 
    this.currentEmployeeProjects, 
    newMonth
  );
  
  // 更新员工详情中的日历数据
  this.selectedEmployeeDetail = {
    ...this.selectedEmployeeDetail,
    calendarData: newCalendarData
  };
}

3. src/app/pages/team-leader/dashboard/dashboard-calendar.scss

修改位置:第9-60行(日历月份标题样式)

修改内容

  • calendar-month-header 改为 flex 布局,支持左右布局
  • 为月份标题设置 flex: 1 居中显示
  • 添加 .btn-prev-month.btn-next-month 按钮样式
  • 添加悬停效果:渐变背景、图标颜色变化、缩放动画
  • 添加点击效果:缩小动画

关键样式

.calendar-month-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  
  .month-title {
    flex: 1;
    text-align: center;
  }
  
  .btn-prev-month,
  .btn-next-month {
    background: transparent;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    width: 32px;
    height: 32px;
    cursor: pointer;
    transition: all 0.2s ease;
    
    &:hover {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      border-color: #667eea;
      transform: scale(1.05);
      
      svg {
        stroke: white;
      }
    }
    
    &:active {
      transform: scale(0.95);
    }
  }
}

功能特性

1. 月份导航

  • ✅ 左侧按钮:切换到上一个月
  • ✅ 右侧按钮:切换到下一个月
  • ✅ 中间显示:当前月份(格式:yyyy年M月)

2. 数据同步

  • ✅ 切换月份时自动重新生成该月的日历数据
  • ✅ 保留员工信息和项目数据,确保数据一致性
  • ✅ 正确计算每天的项目数量和项目列表

3. 视觉效果

  • ✅ 按钮使用简洁的左右箭头图标
  • ✅ 悬停时按钮显示渐变紫色背景
  • ✅ 图标颜色从灰色变为白色
  • ✅ 缩放动画提供视觉反馈
  • ✅ 点击时有缩小效果,增强交互感

4. 日历数据处理

  • ✅ 自动补齐月初和月末的日期(确保从周日开始)
  • ✅ 正确标记"今天"(相对于系统当前日期)
  • ✅ 区分当前月和其他月的日期(其他月半透明显示)
  • ✅ 计算每天的项目数量
  • ✅ 高负载标记(2个及以上项目)

用户使用场景

场景1:查看历史负载

组长想要查看设计师上个月的工作负载情况:

  1. 点击某个设计师,打开详情面板
  2. 查看负载详细日历
  3. 点击左侧"上月"按钮
  4. 日历显示上个月的数据

场景2:查看未来负载

组长想要查看设计师下个月的工作安排:

  1. 在详情面板中查看日历
  2. 点击右侧"下月"按钮
  3. 日历显示下个月的数据
  4. 查看每天的项目安排

场景3:跨月对比

组长想要对比不同月份的负载情况:

  1. 查看当前月份
  2. 点击"上月"查看上月数据
  3. 点击"下月"返回当前月
  4. 继续点击"下月"查看下月数据

技术亮点

1. 灵活的参数设计

generateEmployeeCalendar 方法使用可选的 targetMonth 参数:

  • 不传参数:默认生成当前月份
  • 传入日期:生成指定月份

2. 数据缓存优化

使用 currentEmployeeNamecurrentEmployeeProjects 缓存当前员工数据:

  • 避免重复查询数据库
  • 快速切换月份
  • 保持数据一致性

3. 不可变数据更新

使用对象展开运算符更新 selectedEmployeeDetail

this.selectedEmployeeDetail = {
  ...this.selectedEmployeeDetail,
  calendarData: newCalendarData
};
  • 符合 Angular 的变更检测机制
  • 确保UI正确更新

4. 防御性编程

changeEmployeeCalendarMonth 中进行空值检查:

if (!this.selectedEmployeeDetail?.calendarData) {
  return;
}
  • 避免空指针错误
  • 提高代码健壮性

后续优化建议

1. 快速跳转

可以添加月份选择器,允许直接跳转到指定月份:

<select (change)="jumpToMonth($event)">
  <option>2024年10月</option>
  <option selected>2024年11月</option>
  <option>2024年12月</option>
</select>

2. 年份切换

当前只能切换月份,可以添加年份切换按钮:

<button (click)="changeYear(-1)">上一年</button>
<button (click)="changeYear(1)">下一年</button>

3. 键盘导航

支持键盘快捷键:

  • 左箭头键:上月
  • 右箭头键:下月
  • Home键:回到当前月

4. 加载状态

切换月份时显示加载动画,提升用户体验:

isLoadingCalendar: boolean = false;

changeEmployeeCalendarMonth(direction: number): void {
  this.isLoadingCalendar = true;
  // ... 生成日历 ...
  this.isLoadingCalendar = false;
}

5. 数据预加载

预加载前后一个月的数据,实现无缝切换:

// 缓存前后3个月的日历数据
private calendarCache: Map<string, EmployeeCalendarData> = new Map();

测试建议

功能测试

  • 点击"上月"按钮,日历显示上个月
  • 点击"下月"按钮,日历显示下个月
  • 连续点击可以跨年切换(如:2024年12月 → 2025年1月)
  • 切换月份后项目数量和项目列表正确
  • "今天"标记在非当前月份时不显示

UI测试

  • 按钮悬停时显示紫色渐变背景
  • 按钮点击时有缩放动画
  • 月份标题居中显示
  • 按钮大小和图标大小适中
  • 在不同屏幕尺寸下布局正常

边界测试

  • 未打开员工详情面板时点击按钮不报错
  • 员工没有项目时切换月份不报错
  • 从12月切换到1月,年份正确增加
  • 从1月切换到12月,年份正确减少

总结

此功能为组长端的设计师负载管理增加了重要的时间维度导航能力,使组长能够:

  • 📅 查看历史工作负载
  • 📈 预测未来工作安排
  • 📊 对比不同时期的负载情况
  • 🎯 更科学地进行任务分配

通过简洁的UI设计和流畅的交互动画,提升了用户体验,使负载管理更加高效便捷。