日期:2026-05-13
状态:设计完成,待进入实现计划
当前系统(医梦AI OKR绩效考核系统)已具备单人 OKR/KPI 双轨评分闭环,但与字节跳动飞书 OKR、Google OKR 等企业级系统相比,缺少 3 项企业上线必须补齐的能力:消息通知、多角色权限、多层级 OKR 拆解与对齐。
本设计覆盖方案 A 的 Phase 1 全部内容。
建立统一的"事件 → 通知 → 推送"管道,覆盖 7 类关键业务事件。
CREATE TABLE notification (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
type VARCHAR(32) NOT NULL,
title VARCHAR(256) NOT NULL,
content TEXT,
ref_type VARCHAR(32),
ref_id INTEGER,
is_read INTEGER DEFAULT 0,
read_at TEXT,
created_at TEXT NOT NULL
);
type 枚举: OKR_REVIEW / OKR_REVIEWED / SCORE_CONFIRM / SCORE_CONFIRMED / PERIOD_DEADLINE / KR_LAGGING / FEEDBACK_NOTIFY
ref_type 枚举: period / objective / score / feedback
| 事件 | 接收人 | 触发时机 |
|---|---|---|
| OKR_REVIEW | 上级 | 下级提交 OKR |
| OKR_REVIEWED | 下级 | 上级审核 OKR(通过/驳回) |
| SCORE_CONFIRM | 下级 | 上级完成评分 |
| SCORE_CONFIRMED | 上级 | 下级确认评分 |
| PERIOD_DEADLINE | 周期内全员 | 周期结束前 3 天(由 PeriodScheduler 触发) |
| KR_LAGGING | OKR 负责人 | KR 进度落后于时间线(每日检查) |
| FEEDBACK_NOTIFY | 下级 | 上级发起/更新面谈记录 |
NotificationEvent 事件类,各 Service 在关键动作完成后通过 ApplicationEventPublisher.publishEvent() 发布NotificationListener(@Async + @EventListener)异步消费事件,写入 notification 表GET /api/notifications/unread-count — 未读数(前端 60s 轮询)GET /api/notifications?page=&size= — 通知分页列表PUT /api/notifications/{id}/read — 标记已读PUT /api/notifications/read-all — 全部已读/notifications):分页、已读/未读筛选、类型筛选从"SUPER_ADMIN + 上下级树推导"升级到 5 级标准角色 + 声明式权限 + 数据范围控制。
| 角色 | 权限范围 | 授予对象 |
|---|---|---|
SUPER_ADMIN |
全局 | 系统管理员 |
HR_ADMIN |
全部人员数据 + 考核配置 + 报表 | HRBP |
DEPT_LEADER |
本部门及下级部门 + 评分审批 | 部门负责人 |
TEAM_LEADER |
直属下级 | 团队主管 |
EMPLOYEE |
仅自己 | 普通员工 |
-- role 字段已有 VARCHAR(20),值域扩展为上述 5 种
-- 新增数据范围字段
ALTER TABLE sys_user ADD COLUMN scopes TEXT DEFAULT '[]';
scopes 为 JSON 数组,格式: ["dept:3", "dept:5"],表示该角色可见的部门范围。DEPT_LEADER 自动获得本部门 scope。
| API 操作 | SUPER_ADMIN | HR_ADMIN | DEPT_LEADER | TEAM_LEADER | EMPLOYEE |
|---|---|---|---|---|---|
| 组织管理 CRUD | Y | Y | N | N | N |
| 考核周期管理 | Y | Y | N | N | N |
| 查看本部门全部 OKR | Y | Y | Y | N | N |
| 查看下级 OKR | Y | Y | Y | Y | N |
| 打分下级 | Y | Y | Y | Y | N |
| 自己的 OKR/分数 | Y | Y | Y | Y | Y |
| 导出报表 | Y | Y | Y | N | N |
| 操作日志 | Y | Y | N | N | N |
新增 @RequireRole 注解:
@RequireRole({UserRole.SUPER_ADMIN, UserRole.HR_ADMIN})
AOP 切面 RoleAspect 在 Controller 方法执行前校验角色,无权限返回 403
SecurityUtils 新增方法:
hasRole(UserRole role) — 角色判断getDataScopes() — 获取当前用户数据范围hasSubordinate(Long userId) — 保留现有上下级树逻辑数据范围过滤:Mapper 层查询时拼接 AND (dept_id IN (?) OR user_id = ?) 条件
支持四层 OKR(公司 → 部门 → 团队 → 个人)的逐级拆解与对齐,新增对齐可视化视图。
ALTER TABLE okr_objective ADD COLUMN level VARCHAR(16) NOT NULL DEFAULT 'INDIVIDUAL';
ALTER TABLE okr_objective ADD COLUMN parent_objective_id INTEGER DEFAULT NULL;
ALTER TABLE okr_objective ADD COLUMN sort_order INTEGER DEFAULT 0;
ALTER TABLE okr_objective ADD COLUMN progress REAL DEFAULT 0;
level 取值: COMPANY / DEPARTMENT / TEAM / INDIVIDUAL
| 层级 | 创建权限 | 可视范围 | 每周期建议数量 |
|---|---|---|---|
| COMPANY | SUPER_ADMIN / HR_ADMIN | 全员 | 3-5 |
| DEPARTMENT | DEPT_LEADER / HR_ADMIN | 本部门及下级 | 3-5 |
| TEAM | TEAM_LEADER | 本团队 | 1-3 |
| INDIVIDUAL | 本人 | 汇报链内 | 3-5 |
周期 DRAFT → OKR_ALIGN 阶段:
1. 管理员创建 COMPANY 级 O + KR(全员可见,作为对齐参照)
2. DEPT_LEADER 创建部门 O,选择对齐到某一公司 O
3. 员工创建个人 O,对齐到上级 O 或公司 O
4. 上级审核对齐关系,标记孤立/错位目标
| 端点 | 说明 |
|---|---|
GET /api/okr/period/{periodId}/tree |
OKR 对齐树(全层级) |
GET /api/okr/period/{periodId}/orphans |
未对齐的个人 OKR |
POST /api/okr/{id}/align |
设置/修改 parent_objective_id |
GET /api/okr/{id}/children |
获取对齐到该目标的下级 O |
/okr/alignment?periodId=X):
MainLayout.vue 子路由中注册,侧边栏自动展示