Files
qiji/docs/superpowers/specs/2026-07-12-leave-management-design.md
2026-07-12 12:48:19 +08:00

11 KiB
Raw Permalink Blame History

客户经理请假功能 — 设计文档

日期:2026-07-12 | 状态:已确认

一、需求概述

为政企周报管理系统添加客户经理请假功能。请假可由客户经理自己提交或支局长代为提交,提交即生效(无需审批)。请假期间免填报考核、免催办提醒,AI 周报摘要标注请假信息。

二、核心决策

决策项 结论
粒度 按天(start_date ~ end_date
审批 无需审批,提交即生效
类型 年假 / 事假 / 病假 / 调休 / 其他
权限 经理看自己,支局长/领导看全员
入口 PC 端仪表盘卡片 + 独立页面 + 移动端首页 + 表单页

三、数据模型

新增表 leaves

CREATE TABLE leaves (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    manager_id  UUID NOT NULL REFERENCES users(id),
    leave_type  VARCHAR(20) NOT NULL DEFAULT '事假',  -- 年假/事假/病假/调休/其他
    start_date  DATE NOT NULL,
    end_date    DATE NOT NULL,
    reason      VARCHAR(500) DEFAULT '',
    submitted_by UUID NOT NULL REFERENCES users(id),  -- 提交人(本人或支局长)
    created_at  TIMESTAMPTZ DEFAULT now(),
    updated_at  TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_leaves_manager_id ON leaves(manager_id);
CREATE INDEX idx_leaves_dates ON leaves(start_date, end_date);

设计要点

  • start_date <= end_date,应用层校验
  • 判断"今天是否请假中":start_date <= today <= end_date
  • 判断"本周是否有请假":start_date <= sunday AND end_date >= monday
  • 无 edit_log 列(请假记录简单,不追变更历史)

SQLAlchemy 模型

class Leave(Base):
    __tablename__ = "leaves"
    id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    manager_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("users.id"), index=True)
    leave_type: Mapped[str] = mapped_column(String(20), default="事假")
    start_date: Mapped[date] = mapped_column(Date)
    end_date: Mapped[date] = mapped_column(Date)
    reason: Mapped[str] = mapped_column(String(500), default="")
    submitted_by: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("users.id"))
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())

四、业务逻辑变更

4.1 填报进度判断 (get_reporting_progress)

文件: backend/app/services/dashboard.py

变更点:

  1. 查询本周所有请假记录(start_date <= sunday AND end_date >= monday
  2. 对每个经理判断今日是否在请假区间内
  3. 新增第四种状态 on_leave
# 新增返回字段
{
    "manager_id": "uuid",
    "has_reported_today": bool,
    "completed": bool,
    "on_leave": bool,           # ← 新增
    "leave_info": {              # ← 新增(仅 on_leave=True 时有值)
        "leave_type": "事假",
        "start_date": "...",
        "end_date": "..."
    } | null
}

前端三色状态扩展为四色:

状态 条件 颜色 印章
full 已填 + 完成 绿 (sage)
catching 已填 + 追赶中 黄 (gold)
missing 未填 红 (vermilion)
on_leave 请假中 蓝灰

4.2 催办提醒 (check_daily_reporting)

文件: backend/app/services/scheduler.py

变更点:

  1. 查询当天请假中的经理(start_date <= today <= end_date
  2. 从催办列表中排除这些经理
  3. 汇总消息标注"X人请假,已豁免"

4.3 仪表盘统计卡

文件: backend/app/services/dashboard.py + 前端 Dashboard.vue

新增第五张统计卡「本周请假」:

  • 数字:本周请假总人数
  • 数据来源:统计 start_date <= sunday AND end_date >= monday 的去重 manager 数
  • 点击跳转 /leaves
  • 颜色:蓝灰调

4.4 AI 摘要提示词

文件: backend/app/services/ai_summary.pybuild_summary_prompt()

新增一节注入请假数据:

## 本周请假情况
- 张三 (事假): 2026-07-13 ~ 2026-07-15 (3天)
- 李四 (年假): 2026-07-14 ~ 2026-07-17 (4天)

效果:LLM 生成的摘要会自然提及"本周张三请事假3天未参与拜访"等信息。

五、API 设计

所有接口挂载在 /api/leaves,需登录认证。

5.1 列表

GET /api/leaves?manager_id=xxx&status=active&page=1&page_size=25

权限:director/leader 看全员,manager 只返回自己的记录。 status 筛选项:active(进行中)/ upcoming(未来)/ past(已结束)/ 不传全部。 默认按 start_date DESC 排序。

5.2 新建

POST /api/leaves
{
    "manager_id": "uuid",
    "leave_type": "年假",
    "start_date": "2026-07-13",
    "end_date": "2026-07-15",
    "reason": "回老家"
}

权限:manager 只能给自己建(manager_id 必须等于自己),director 可以给任何人建。 校验:end_date >= start_date

5.3 编辑

PUT /api/leaves/{id}

请求体同新建。权限:director 可编辑任意记录,manager 仅可编辑自己提交且尚未开始的记录。

5.4 删除

DELETE /api/leaves/{id}

权限:同编辑。

5.5 概览(仪表盘用)

GET /api/leaves/overview?reference_date=2026-07-12
{
    "week_start": "2026-07-13",
    "week_end": "2026-07-19",
    "total_on_leave": 2,
    "leave_list": [
        {
            "manager_id": "uuid",
            "manager_name": "张三",
            "leave_type": "事假",
            "start_date": "2026-07-13",
            "end_date": "2026-07-15",
            "days": 3
        }
    ]
}

权限:director/leader 返回全员请假数据,manager 只返回自己。

六、前端设计

6.1 PC 端 — 仪表盘卡片

文件: frontend/src/views/desktop/Dashboard.vue

  • 新增第五张统计卡「本周请假」
  • 样式与现有四卡一致(stat-card + stat-glyph + 数字 + 标签)
  • 颜色:蓝灰色调(--slate 系列 CSS 变量)
  • 点击跳转 /leaves
  • 数据来源:GET /api/leaves/overview

6.2 PC 端 — 请假管理页

文件: 新增 frontend/src/views/desktop/Leaves.vue

路由: /leavesDesktopLayout 侧边栏「工作」分组下新增「请假管理」

页面结构:

  • 顶部汇总栏:按请假类型分组统计条数(年假X / 事假X / 病假X / 调休X / 其他X)
  • 筛选栏:按经理筛选(支局长/领导可见)、按状态筛选(进行中 / 即将开始 / 已结束)
  • 表格列:姓名 + 类型(彩色标签)+ 日期范围 + 天数 + 原因摘要 + 提交人 + 操作(编辑/删除)
  • 进行中的行蓝色左边框高亮
  • 新增/编辑弹窗(el-dialog):选择经理(支局长代填时)、请假类型 chip 按钮组、日期范围选择器、原因 textarea

参考文件:

  • 汇总栏样式:参考 WorkPlans.vue / KeyVisits.vue 的顶部汇总栏
  • 表格模式:参考 CustomerManage.vue 的 el-table + 分页
  • 表单弹窗:参考各独立工作页的 CRUD 弹窗

6.3 PC 端 — 填报进度卡片

文件: frontend/src/views/desktop/Dashboard.vue

  • 请假中的经理卡片:蓝色「假」印章水印 + 灰色进度条 + "请假中"文案
  • 不计入未填报人数统计

6.4 PC 端 — 侧边栏

文件: frontend/src/components/DesktopLayout.vue

侧边栏「工作」分组新增:

工作
  ├─ 工作计划
  ├─ 商机跟单
  ├─ 要客拜访
  └─ 请假管理   ← 新增,📋 icon

6.5 移动端 — 首页入口

文件: frontend/src/views/mobile/Home.vue

  • 在快捷按钮区域(现有「工作计划」「商机跟单」「要客拜访」旁)新增「请假」chip
  • 如果当前有进行中的请假,chip 右上角显示蓝色小圆点
  • 点击跳转 /m/leaves

6.6 移动端 — 请假列表页

文件: 新增 frontend/src/views/mobile/LeavesList.vue

路由: /m/leaves

  • 卡片流式列表(参考 Home.vue 的记录卡片风格)
  • 每条记录:类型彩色标签 + 日期范围 + 天数 + 原因
  • 进行中的卡片蓝色左边框
  • 顶部有「新建请假」按钮(ink 风格全宽按钮)

6.7 移动端 — 请假表单页

文件: 新增 frontend/src/views/mobile/LeaveForm.vue

路由: /m/leave/new + /m/leave/:id/edit(复用同一组件)

  • 沿用现有移动端表单模式(editorial header + 返回按钮 + 中文标题 + 英文副标题 + 金色装饰线)
  • 请假类型:chip 按钮组(年假/事假/病假/调休/其他),参考 VisitForm 的拜访方式 chip
  • 日期范围:开始日期 → 结束日期
  • 原因:textarea,选填
  • 提交按钮:全宽暗色按钮「提交请假」
  • 编辑模式下额外显示删除按钮(vermilion 描边)

6.8 移动端 — 路由配置

文件: frontend/src/router/index.ts

新增 3 条移动端路由:

{ path: 'leaves', component: LeavesList },           // /m/leaves
{ path: 'leave/new', component: LeaveForm },          // /m/leave/new
{ path: 'leave/:id/edit', component: LeaveForm },     // /m/leave/:id/edit

七、文件变更清单

后端新增

文件 说明
backend/app/models/leave.py Leave SQLAlchemy 模型
backend/app/schemas/leave.py Pydantic 请求/响应 schema
backend/app/api/leaves.py REST API 路由
backend/app/services/leaves.py 业务逻辑层
backend/alembic/versions/xxxx_add_leaves_table.py 数据库迁移

后端修改

文件 改动
backend/app/services/dashboard.py 填报进度 +on_leave 状态;统计卡 +请假数
backend/app/services/scheduler.py 催办过滤请假人员
backend/app/services/ai_summary.py build_summary_prompt 注入请假数据
backend/app/models/__init__.py 导入 Leave 模型
backend/app/main.py 注册 leaves 路由 + lifespan 自动建表

前端新增

文件 说明
frontend/src/views/desktop/Leaves.vue PC 端请假管理页
frontend/src/views/mobile/LeavesList.vue 移动端请假列表页
frontend/src/views/mobile/LeaveForm.vue 移动端请假表单页
frontend/src/api/leaves.ts Axios API 模块

前端修改

文件 改动
frontend/src/views/desktop/Dashboard.vue 新增请假统计卡 + 填报进度 on_leave 状态
frontend/src/components/DesktopLayout.vue 侧边栏新增请假管理入口
frontend/src/router/index.ts 新增 /leaves + /m/leaves 等路由
frontend/src/views/mobile/Home.vue 新增请假快捷入口 chip

八、验证要点

  1. 经理提交请假后,当天仪表盘填报进度显示蓝「假」状态
  2. 请假中的经理不收到催办提醒
  3. 支局长可代任意经理提交请假
  4. AI 摘要中体现请假信息
  5. 移动端可完成请假提交→列表查看→编辑→删除全流程
  6. 历史周翻看时,请假数据对应当时的日期区间