OKR 绩效考核系统 — 技术设计文档
文档信息
| 项目 |
内容 |
| 文档名称 |
医梦AI OKR 绩效考核系统技术设计 |
| 版本 |
v1.0 |
| 日期 |
2026-04-15 |
| 作者 |
产品研发部 |
| 状态 |
已评审 |
1. 技术选型
| 层级 |
技术 |
版本 |
选型理由 |
| 运行时 |
JDK |
17 LTS |
企业级长期支持版本,生态成熟 |
| 后端框架 |
Spring Boot |
3.2.x |
约定优于配置,内嵌 Tomcat,适合快速交付 |
| ORM |
MyBatis-Plus |
3.5.x |
无 XML 配置、自动 CRUD、逻辑删除、分页插件,开发效率高 |
| 数据库 |
SQLite (WAL) |
3.45 |
零安装、零配置、单文件存储,适合内部小规模部署 |
| 认证 |
Spring Security + JWT |
6.x / jjwt 0.12 |
无状态认证,适合前后端分离架构 |
| 前端框架 |
Vue 3 Composition API |
3.4+ |
响应式、组合式 API、TypeScript 友好 |
| UI 组件库 |
Element Plus |
2.6+ |
企业级中后台组件丰富,中文生态好 |
| 状态管理 |
Pinia |
2.x |
Vue 3 官方推荐,类型推导好 |
| 前端构建 |
Vite |
5.x |
冷启动快、HMR 极速 |
| 后端构建 |
Maven |
3.9 |
Spring Boot 标准构建工具 |
2. 部署架构
┌─────────────────────────────────────────┐
│ okr-performance.jar │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ Spring Boot │ │ static/ │ │
│ │ (port 18080) │ │ Vue build 产物 │ │
│ │ ┌──────────┐│ │ index.html │ │
│ │ │ /api/* ││ │ assets/*.js │ │
│ │ │ REST API ││ │ assets/*.css │ │
│ │ └──────────┘│ └──────────────────┘ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────┐│ │
│ │ │ SQLite ││ │
│ │ │ (WAL) ││ │
│ │ └──────────┘│ │
│ └──────────────┘ │
└─────────────────────────────────────────┘
- 单 JAR 文件 + 1 个
.db 文件组成完整部署单元
- Spring Boot 同时提供 API 服务与静态资源服务
- 前端开发时
:5173 通过 Vite proxy 代理到后端 :18080
- SQLite WAL 模式支持读写并发
3. 后端分层架构
com.yimeng.okr
├── controller/ # REST 控制器,参数校验,调用 service
├── service/ # 业务逻辑,事务管理
├── mapper/ # MyBatis-Plus BaseMapper,无 XML
├── entity/ # 数据库实体,@TableName 映射
├── dto/ # 请求/响应对象,ApiResult<T> 统一包装
├── security/ # JwtTokenProvider, JwtAuthenticationFilter, SecurityUtils
├── config/ # SecurityConfig, DatabaseInitializer, DataInitializer, MybatisPlusConfig
├── exception/ # BusinessException + GlobalExceptionHandler
├── enums/ # 枚举:UserRole, PeriodStatus, KrStatus, Grade, ScoreType, ObjectiveType
├── schedule/ # PeriodScheduler(每日 2:00 自动推进周期状态)
└── annotation/ # @OperationLog 操作日志切面注解
3.1 API 设计规范
- Base path:
/api/*
- 统一响应体:
ApiResult<T> = code(200=成功) + message + data
- 认证方式:JWT Bearer Token,
/api/auth/** 公开,其余需认证
- 当前用户获取:
SecurityUtils.getCurrentUserId()
3.2 异常处理
- 业务异常统一抛出
BusinessException(code, message)
GlobalExceptionHandler(@RestControllerAdvice) 全局捕获
- 集成 MyBatis-Plus 逻辑删除(
deleted=0 有效,deleted=1 删除)
4. 数据库设计
4.1 ER 关系
sys_department ──┐
│ 1:N
▼
sys_user ────────► okr_objective ──► kr_key_result ──► kr_progress_log
│ │ │
│ superior_id │ period_id │ assignedTo
│ (自引用树) ▼ │ sourceKrId (自引用)
│ assessment_period ▼
│ │ kpi_config
│ ▼
└──────────────► performance_score ──► audit_correction
│
▼
performance_feedback
kpi_template assessment_dimension operation_log
4.2 核心表结构
sys_user(用户)
| 字段 |
类型 |
说明 |
| id |
INTEGER PK |
自增主键 |
| username |
VARCHAR(64) UNIQUE |
登录名 |
| password_hash |
VARCHAR(256) |
BCrypt 加密 |
| real_name |
VARCHAR(64) |
真实姓名 |
| position |
VARCHAR(128) |
岗位名称 |
| department_id |
INTEGER FK |
所属部门 |
| superior_id |
INTEGER |
直属上级 ID(自引用,构建汇报树) |
| role |
VARCHAR(20) |
EMPLOYEE / SUPER_ADMIN |
| deleted |
INTEGER |
0=有效, 1=删除 |
关键设计:superior_id 构建树形汇报关系,权限由此推导。role=SUPER_ADMIN 为超级管理员旁路标志。
assessment_period(考核周期)
| 字段 |
类型 |
说明 |
| id |
INTEGER PK |
自增 |
| name |
VARCHAR(128) |
周期名称 |
| period_type |
VARCHAR(20) |
MONTHLY / QUARTERLY / YEARLY |
| start_date |
TEXT |
开始日期 |
| end_date |
TEXT |
结束日期 |
| status |
VARCHAR(20) |
DRAFT→OKR_ALIGN→EXECUTING→ASSESSING→ARCHIVED |
okr_objective(目标 O)
| 字段 |
类型 |
说明 |
| id |
INTEGER PK |
自增 |
| period_id |
INTEGER FK |
所属周期 |
| user_id |
INTEGER FK |
所属用户 |
| title |
VARCHAR(256) |
O 标题 |
| status |
VARCHAR(20) |
DRAFT / SUBMITTED / APPROVED / REJECTED |
| aligned_objective_ids |
TEXT |
逗号分隔的对齐上级 O 的 ID 列表 |
| snapshot_json |
TEXT |
归档快照 |
| reviewed_by |
INTEGER |
审核人 |
| reviewed_at |
TEXT |
审核时间 |
kr_key_result(关键结果 KR)
| 字段 |
类型 |
说明 |
| id |
INTEGER PK |
自增 |
| objective_id |
INTEGER FK |
所属 O |
| title |
VARCHAR(256) |
KR 标题 |
| target_value |
REAL |
目标值 |
| current_value |
REAL |
当前值 |
| status |
VARCHAR(20) |
NOT_STARTED / IN_PROGRESS / COMPLETED / BLOCKED |
| weight |
INTEGER |
权重(和为 100) |
| assigned_to |
INTEGER |
@指派的下属用户 ID |
| source_kr_id |
INTEGER |
承接的上级 KR ID(引用持久化) |
关键设计:source_kr_id 持久化上下级 KR 对齐关系。员工编辑自定义标题后,此引用不丢失,确保审批链可追溯。
performance_score(绩效评分)
| 字段 |
类型 |
说明 |
| id |
INTEGER PK |
自增 |
| period_id |
INTEGER FK |
所属周期 |
| user_id |
INTEGER FK |
被评用户 |
| evaluator_id |
INTEGER FK |
评估人 |
| okr_score |
REAL |
OKR 得分(0-60) |
| kpi_score |
REAL |
工作成果得分(0-40) |
| bonus |
REAL |
加分 |
| penalty |
REAL |
扣分 |
| total |
REAL |
总分 |
| grade |
VARCHAR(2) |
S/A/B/C |
| type |
VARCHAR(20) |
SELF / SUPERIOR / FINAL |
| comments_json |
TEXT |
评分详情 JSON(维度分、KR 分、自述等) |
| confirmed_at |
TEXT |
员工确认时间 |
关键设计:type 字段区分三阶段评分。comments_json 存储维度评分明细,支持结构化的自评内容展示。
assessment_dimension(考核维度)
| 字段 |
类型 |
说明 |
| id |
INTEGER PK |
自增 |
| name |
VARCHAR(64) |
维度名称 |
| max_score |
INTEGER |
满分分值 |
| sort_order |
INTEGER |
排序 |
| deleted |
INTEGER |
0=有效, 1=删除 |
约束:所有未删除维度的 max_score 之和必须为 40,由后端 DimensionService.validateTotal() 强制校验。
其他表
| 表名 |
用途 |
| kr_progress_log |
KR 进度变更日志(旧值→新值,旧状态→新状态) |
| kpi_template |
岗位绩效模板(items_json 存储指标项列表) |
| kpi_config |
个人 KPI 配置(周期级) |
| performance_feedback |
面谈记录(亮点/改进/建议/纪要) |
| operation_log |
操作审计日志(操作人/动作/对象/数据快照) |
| audit_correction |
评分修正记录(修正前后数据 JSON) |
5. API 端点设计
5.1 Auth 模块 /api/auth
| 方法 |
路径 |
说明 |
| POST |
/login |
登录,返回 JWT accessToken + refreshToken |
| POST |
/register |
注册 |
| GET |
/me |
获取当前用户信息 |
| PUT |
/password |
修改密码 |
5.2 组织架构 /api/org
| 方法 |
路径 |
说明 |
| GET |
/departments/tree |
部门树 |
| POST |
/departments |
创建部门 |
| PUT |
/departments/:id |
更新部门 |
| DELETE |
/departments/:id |
删除部门 |
| GET |
/users |
用户列表 |
| POST |
/users |
创建用户 |
| PUT |
/users/:id |
更新用户 |
| DELETE |
/users/:id |
删除用户 |
| PUT |
/users/:id/superior |
调整上级 |
| PUT |
/users/:id/department |
调整部门 |
5.3 考核周期 /api/periods
| 方法 |
路径 |
说明 |
| GET |
/ |
周期列表 |
| POST |
/ |
创建周期 |
| PUT |
/:id |
更新周期 |
| DELETE |
/:id |
删除周期 |
| PUT |
/:id/status |
状态转换 |
5.4 OKR /api/okr
| 方法 |
路径 |
说明 |
| POST |
/submit |
提交 OKR |
| PUT |
/:id/update |
更新 OKR |
| PUT |
/:id/review |
审核(通过/驳回) |
| PUT |
/kr/:krId/progress |
更新 KR 进度 |
| GET |
/kr/:krId/history |
KR 进度历史 |
| GET |
/period/:periodId/superior |
上级 OKR(用于对齐) |
| GET |
/period/:periodId/my |
我的 OKR |
| GET |
/period/:periodId/subordinates |
下属 OKR(团队视图) |
| GET |
/period/:periodId/pending-reviews |
待审核列表 |
| GET |
/period/:periodId/all |
周期全部 OKR |
5.5 绩效评分 /api/scores
| 方法 |
路径 |
说明 |
| POST |
/self |
员工自评 |
| POST |
/superior |
上级终审评分 |
| GET |
/page |
评分详情页(含 OKR) |
| GET |
/my |
我的绩效结果 |
| POST |
/confirm |
确认终审结果 |
| GET |
/subordinates |
下属评分列表 |
5.6 考核维度 /api/dimensions
| 方法 |
路径 |
说明 |
| GET |
/ |
维度列表 |
| POST |
/ |
创建维度 |
| PUT |
/:id |
更新维度 |
| DELETE |
/:id |
删除维度 |
5.7 KPI 模板 /api/kpi
| 方法 |
路径 |
说明 |
| GET |
/templates |
模板列表 |
| POST |
/templates |
创建模板 |
| PUT |
/templates/:id |
更新模板 |
| DELETE |
/templates/:id |
删除模板 |
| GET |
/templates/by-position |
按岗位匹配模板 |
5.8 反馈 /api/feedback
| 方法 |
路径 |
说明 |
| POST |
/interview |
保存面谈记录 |
| POST |
/reply |
员工回复 |
| GET |
/page |
查询反馈详情 |
6. 前端架构
6.1 路由设计
/login # 登录/注册
/ # 主布局(侧边栏 + 顶栏 + 内容区)
├── /periods # 考核周期管理
├── /okr/my # 我的 OKR(制定/编辑/进度)
├── /okr/team # 团队 OKR(下属全景)
├── /scores/my # 我的绩效(自评 + 结果)
├── /scoring # 绩效打分列表
├── /scoring/:userId # 绩效考评详情(同屏)
├── /feedback # 绩效沟通
├── /org # 组织架构(管理员)
├── /kpi/templates # 绩效模板(管理员)
├── /system/dimensions # 考核维度配置(管理员)
└── /system/logs # 操作日志(管理员)
6.2 组件树
App.vue
├── LoginView.vue
└── MainLayout.vue (侧边栏 + 顶栏 + router-view)
├── PeriodListView.vue
├── MyOkrView.vue
├── TeamOkrView.vue
├── MyResultView.vue # 自评表单 / 结果展示(条件渲染)
├── ScoringListView.vue
├── ScoringEditView.vue # 同屏:左侧记录 + 右侧评分
├── FeedbackView.vue
├── OrgView.vue
├── KpiTemplateView.vue # 含岗位分类筛选
├── DimensionConfigView.vue
└── LogView.vue
6.3 状态管理(Pinia)
auth store: {
state: { user, accessToken, refreshToken }
getters: { isLoggedIn, isAdmin }
actions: { login, register, fetchUser, logout }
}
6.4 API 层
- Axios 实例:baseURL
/api,请求拦截注入 JWT,响应拦截统一处理 401
- 按模块导出 API 函数:
authApi, orgApi, periodApi, okrApi, scoreApi, kpiApi, feedbackApi, dimensionApi, systemApi
7. UI/UX 设计规范
7.1 主题
| 属性 |
值 |
| 主色 |
#2b1f99(深靛蓝 — 侧边栏、强调元素) |
| 辅色 |
#3ad4d8(青绿 — 高亮、CTA、进度条) |
| 侧边栏 |
220px 宽,深色渐变:#1a1560 → #2b1f99 → #1e1780 |
| 内容区背景 |
#f5f7fa |
| 顶栏高度 |
48px |
7.2 同屏布局(评分页)
┌──────────────────────────────────────────────────┐
│ 左侧(弹性宽度) │ 右侧(480px 固定) │
│ ┌────────────────────┐ │ ┌────────────────┐ │
│ │ 当期 OKR 完整记录 │ │ │ 考评打分 │ │
│ │ · O 标题 + 状态 │ │ │ · KR 逐条打分 │ │
│ │ · KR1 进度+日志 │ │ │ · 工作成果维度评分 │ │
│ │ · KR2 进度+日志 │ │ │ · 加减分 │ │
│ │ · KR3 进度+日志 │ │ │ · 总分/评级预览 │ │
│ ├────────────────────┤ │ │ · 提交按钮 │ │
│ │ 员工自评 │ │ └────────────────┘ │
│ │ · OKR 自评分 │ │ │
│ │ · 维度自评+自述 │ │ │
│ │ · 加减分 │ │ │
│ │ · 自评总分 │ │ │
│ └────────────────────┘ │ │
└──────────────────────────────────────────────────┘
- 宽屏(≥1100px):左右分栏
- 窄屏(<1100px):上下分区,面板全宽
7.3 考核周期选择器
- 进行中的周期以彩色标签固定在顶部
- 未开始/已归档周期折叠收纳
- 周期左侧色条标识状态:绿色(执行中)、橙黄(对齐中)、红色(考评中)
8. 关键技术决策
| 决策 |
方案 |
理由 |
| 单 JAR 部署 |
Vue build 输出拷贝到 static/ 打包 |
部署物单一、运维简单 |
| 软删除 |
MyBatis-Plus @TableLogic |
数据可恢复、满足审计要求 |
| 快照存档 |
snapshot_json 字段 |
归档后历史数据不受后续编辑影响 |
| 修正留痕 |
audit_correction 表 |
"不可修改"语义通过审计日志实现 |
| 树形权限 |
superior_id 自引用 |
权限随组织调整自动变化,无需单独配置 |
| KR 引用持久化 |
source_kr_id 字段 |
编辑不丢失对齐关系,确保可追溯 |
| 维度可配置 |
assessment_dimension 表 |
适配不同组织的考核侧重点 |
| 评分三阶段 |
SELF → SUPERIOR → FINAL |
自评先行、上级终审,流程清晰 |
9. 安全设计
- 密码:BCrypt 加密存储
- 认证:JWT accessToken(24h)+ refreshToken(7d)
- 接口鉴权:Spring Security Filter Chain,
/api/auth/** 放行,其余需认证
- 跨域:CORS 白名单,允许
localhost 来源
- 会话:无状态,不启用服务端 Session
- 审计:操作日志记录操作人、IP、变更前后数据