20 KiB
设计文档 - 员工月度绩效考核系统
概述
员工月度绩效考核系统是一个基于 Web 的全栈应用,采用前后端分离架构。系统集成 FastGPT AI 评分能力,实现员工绩效填报、AI 自动评分、管理层审核、数据统计分析的完整闭环。
技术栈选择
后端:
- Node.js + TypeScript
- Express.js 框架
- MySQL 数据库
- JWT 身份认证
- Axios(FastGPT API 调用)
前端:
- React + TypeScript
- Ant Design UI 组件库
- React Router(路由管理)
- Axios(HTTP 请求)
- ECharts(数据可视化)
核心设计原则
- 角色权限分离: 严格按照员工、管理层、总经理三种角色进行权限控制
- 数据安全: 敏感数据加密存储,操作日志完整记录
- 流程自动化: 绩效提交自动触发 AI 评分,审核完成自动归档
- 可扩展性: 模块化设计,便于后续功能扩展
架构设计
系统架构图
graph TB
subgraph "前端层"
A[员工端页面]
B[管理层端页面]
C[总经理端页面]
end
subgraph "API 网关层"
D[Express API Server]
E[JWT 认证中间件]
F[权限验证中间件]
end
subgraph "业务逻辑层"
G[用户服务]
H[绩效服务]
I[AI 评分服务]
J[统计分析服务]
end
subgraph "数据访问层"
K[用户 DAO]
L[绩效 DAO]
M[AI 结果 DAO]
end
subgraph "外部服务"
N[FastGPT API]
end
subgraph "数据存储层"
O[(MySQL 数据库)]
end
A --> D
B --> D
C --> D
D --> E
E --> F
F --> G
F --> H
F --> J
H --> I
I --> N
G --> K
H --> L
I --> M
K --> O
L --> O
M --> O
数据流设计
绩效提交流程:
员工填报 → 前端验证 → API 提交 → 保存数据库 → 触发 AI 评分 → 调用 FastGPT → 解析结果 → 存储 AI 结果 → 返回成功
绩效审核流程:
管理层查看 → 加载绩效+AI结果 → 调整评分 → 填写意见 → 提交审核 → 计算等级奖惩 → 归档数据 → 通知员工
组件与接口
后端核心模块
1. 用户认证模块 (AuthService)
职责: 处理用户登录、令牌生成与验证
接口:
interface AuthService {
// 用户登录
login(username: string, password: string, role: string): Promise<LoginResult>;
// 验证令牌
verifyToken(token: string): Promise<UserInfo>;
// 刷新令牌
refreshToken(token: string): Promise<string>;
}
interface LoginResult {
token: string;
userInfo: UserInfo;
}
interface UserInfo {
userId: number;
name: string;
role: 'employee' | 'manager' | 'generalManager';
department: string;
position: string;
}
2. 绩效管理模块 (PerformanceService)
职责: 处理绩效填报、查询、审核等核心业务逻辑
接口:
interface PerformanceService {
// 提交绩效(暂存或提交)
submitPerformance(data: PerformanceSubmitDTO): Promise<PerformanceResult>;
// 查询员工个人绩效
getEmployeePerformance(userId: number, month?: string, page?: PageInfo): Promise<PerformanceListResult>;
// 查询管理层下属绩效
getManagerSubordinates(managerId: number, filters: PerformanceFilter, page: PageInfo): Promise<PerformanceListResult>;
// 审核绩效
reviewPerformance(perfId: number, reviewData: ReviewDTO): Promise<void>;
// 驳回绩效
rejectPerformance(perfId: number, reason: string): Promise<void>;
// 申请修改绩效
requestModification(perfId: number, reason: string): Promise<void>;
// 批准修改申请
approveModification(perfId: number): Promise<void>;
}
interface PerformanceSubmitDTO {
userId: number;
month: string;
status: 'draft' | 'submit';
selfScore: number;
attendance: AttendanceData;
workSummary: string;
performanceItems: PerformanceItemDTO[];
}
interface PerformanceItemDTO {
itemName: string;
weight: number;
userContent: string;
selfScore: number;
evidence?: string;
}
interface AttendanceData {
leave: number;
late: number;
absent: number;
lackCard: number;
remark?: string;
}
interface ReviewDTO {
perfId: number;
managerScore: number;
reviewOpinion: string;
itemScores: ItemScoreDTO[];
}
interface ItemScoreDTO {
itemName: string;
managerScore: number;
scoreExplanation: string;
}
3. AI 评分模块 (AIEvaluationService)
职责: 调用 FastGPT API 进行自动评分和反馈生成
接口:
interface AIEvaluationService {
// 执行 AI 评分
evaluatePerformance(perfId: number): Promise<AIResult>;
// 构建 AI 请求 Prompt
buildPrompt(performance: PerformanceRecord): string;
// 解析 AI 响应
parseAIResponse(response: string): AIScoreData;
// 重试机制
retryEvaluation(perfId: number, maxRetries: number): Promise<AIResult>;
}
interface AIResult {
aiId: number;
perfId: number;
aiScoreDetail: AIScoreItem[];
aiTotalScore: number;
aiProblems: string[];
aiSuggestions: string[];
createTime: Date;
}
interface AIScoreItem {
itemName: string;
weight: number;
aiScore: number;
scoreExplanation: string;
}
4. 统计分析模块 (StatisticsService)
职责: 提供多维度数据统计和报表生成
接口:
interface StatisticsService {
// 获取团队统计
getTeamStatistics(managerId: number, month: string): Promise<TeamStats>;
// 获取全公司统计
getCompanyStatistics(month: string): Promise<CompanyStats>;
// 多维度统计
getMultiDimensionStats(filters: StatFilter): Promise<MultiDimensionStats>;
// 导出 Excel
exportToExcel(filters: ExportFilter): Promise<Buffer>;
}
interface TeamStats {
averageScore: number;
excellentCount: number;
qualifiedCount: number;
needMotivationCount: number;
totalCount: number;
}
interface CompanyStats {
departmentStats: DepartmentStat[];
positionStats: PositionStat[];
levelDistribution: LevelDistribution;
}
前端核心组件
1. 员工端组件
// 绩效填报组件
interface PerformanceFormComponent {
props: {
month: string;
userInfo: UserInfo;
};
state: {
formData: PerformanceFormData;
isDraft: boolean;
};
methods: {
handleItemChange(index: number, field: string, value: any): void;
handleSave(): Promise<void>;
handleSubmit(): Promise<void>;
uploadEvidence(file: File): Promise<string>;
};
}
// 个人绩效查看组件
interface PerformanceHistoryComponent {
props: {
userId: number;
};
state: {
performanceList: PerformanceRecord[];
selectedMonth: string;
pagination: PaginationState;
};
methods: {
loadPerformanceList(): Promise<void>;
viewDetail(perfId: number): void;
filterByMonth(month: string): void;
};
}
2. 管理层端组件
// 下属绩效列表组件
interface SubordinateListComponent {
props: {
managerId: number;
};
state: {
subordinateList: PerformanceRecord[];
filters: PerformanceFilter;
pagination: PaginationState;
};
methods: {
loadSubordinateList(): Promise<void>;
applyFilters(filters: PerformanceFilter): void;
viewDetail(perfId: number): void;
};
}
// 绩效审核组件
interface PerformanceReviewComponent {
props: {
perfId: number;
};
state: {
performanceData: PerformanceRecord;
aiResult: AIResult;
reviewForm: ReviewFormData;
};
methods: {
loadPerformanceDetail(): Promise<void>;
adjustScore(itemName: string, score: number): void;
submitReview(): Promise<void>;
rejectPerformance(reason: string): Promise<void>;
};
}
3. 总经理端组件
// 全局统计组件
interface CompanyStatisticsComponent {
props: {
month: string;
};
state: {
companyStats: CompanyStats;
chartData: ChartData;
selectedDimension: string;
};
methods: {
loadStatistics(): Promise<void>;
switchDimension(dimension: string): void;
exportData(): Promise<void>;
};
}
数据模型
数据库表设计
1. 用户表 (user)
CREATE TABLE user (
user_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID',
username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名(工号)',
password VARCHAR(255) NOT NULL COMMENT '密码(加密存储)',
name VARCHAR(50) NOT NULL COMMENT '姓名',
role ENUM('employee', 'manager', 'generalManager') NOT NULL COMMENT '角色',
department VARCHAR(50) NOT NULL COMMENT '部门',
position VARCHAR(50) NOT NULL COMMENT '岗位',
manager_id INT COMMENT '直属管理层ID',
status ENUM('active', 'inactive') DEFAULT 'active' COMMENT '状态',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_role (role),
INDEX idx_manager (manager_id),
FOREIGN KEY (manager_id) REFERENCES user(user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
2. 绩效主表 (performance_month)
CREATE TABLE performance_month (
perf_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '绩效记录ID',
user_id INT NOT NULL COMMENT '员工ID',
month VARCHAR(7) NOT NULL COMMENT '考核月份(YYYY-MM)',
status ENUM('draft', 'submitted', 'under_review', 'completed', 'rejected') NOT NULL COMMENT '状态',
self_score DECIMAL(5,2) COMMENT '员工自评总分',
ai_score DECIMAL(5,2) COMMENT 'AI评分总分',
manager_score DECIMAL(5,2) COMMENT '管理层审核总分',
total_score DECIMAL(5,2) COMMENT '最终总分',
level ENUM('excellent', 'qualified', 'need_motivation', 'unqualified') COMMENT '绩效等级',
reward_punish VARCHAR(255) COMMENT '奖惩说明',
work_summary TEXT COMMENT '工作汇总',
submit_time TIMESTAMP COMMENT '提交时间',
review_time TIMESTAMP COMMENT '审核时间',
review_opinion TEXT COMMENT '审核意见',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_user_month (user_id, month),
INDEX idx_status (status),
INDEX idx_month (month),
FOREIGN KEY (user_id) REFERENCES user(user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='绩效主表';
3. 绩效项明细表 (perf_item)
CREATE TABLE perf_item (
item_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '绩效项ID',
perf_id INT NOT NULL COMMENT '绩效记录ID',
item_name VARCHAR(100) NOT NULL COMMENT '考核项名称',
item_category ENUM('business', 'comprehensive') NOT NULL COMMENT '考核项类别',
weight INT NOT NULL COMMENT '权重(分数)',
user_content TEXT COMMENT '员工填写内容',
self_score DECIMAL(5,2) COMMENT '员工自评分',
ai_score DECIMAL(5,2) COMMENT 'AI评分',
ai_explanation TEXT COMMENT 'AI评分说明',
manager_score DECIMAL(5,2) COMMENT '管理层评分',
manager_explanation TEXT COMMENT '管理层评分说明',
evidence_url VARCHAR(500) COMMENT '佐证材料URL',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_perf (perf_id),
FOREIGN KEY (perf_id) REFERENCES performance_month(perf_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='绩效项明细表';
4. 考勤表 (attendance)
CREATE TABLE attendance (
attendance_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '考勤ID',
perf_id INT NOT NULL COMMENT '绩效记录ID',
leave_days INT DEFAULT 0 COMMENT '事假天数',
late_times INT DEFAULT 0 COMMENT '迟到次数',
absent_days INT DEFAULT 0 COMMENT '旷工天数',
lack_card_times INT DEFAULT 0 COMMENT '缺卡次数',
attendance_score DECIMAL(5,2) COMMENT '考勤得分',
remark TEXT COMMENT '备注',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_perf (perf_id),
FOREIGN KEY (perf_id) REFERENCES performance_month(perf_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考勤表';
5. AI 结果表 (ai_result)
CREATE TABLE ai_result (
ai_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'AI结果ID',
perf_id INT NOT NULL COMMENT '绩效记录ID',
ai_score_json TEXT NOT NULL COMMENT 'AI评分详情(JSON格式)',
ai_total_score DECIMAL(5,2) NOT NULL COMMENT 'AI总分',
problems TEXT COMMENT 'AI总结的问题(JSON数组)',
suggestions TEXT COMMENT 'AI改进建议(JSON数组)',
api_response TEXT COMMENT 'FastGPT原始响应',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '生成时间',
UNIQUE KEY uk_perf (perf_id),
FOREIGN KEY (perf_id) REFERENCES performance_month(perf_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='AI结果表';
6. 操作日志表 (operation_log)
CREATE TABLE operation_log (
log_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '日志ID',
user_id INT NOT NULL COMMENT '操作人ID',
operation_type VARCHAR(50) NOT NULL COMMENT '操作类型',
target_type VARCHAR(50) COMMENT '目标类型',
target_id INT COMMENT '目标ID',
operation_detail TEXT COMMENT '操作详情',
ip_address VARCHAR(50) COMMENT 'IP地址',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user (user_id),
INDEX idx_created (created_at),
FOREIGN KEY (user_id) REFERENCES user(user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志表';
数据关系图
erDiagram
USER ||--o{ PERFORMANCE_MONTH : "has"
USER ||--o{ USER : "manages"
PERFORMANCE_MONTH ||--|{ PERF_ITEM : "contains"
PERFORMANCE_MONTH ||--|| ATTENDANCE : "has"
PERFORMANCE_MONTH ||--|| AI_RESULT : "has"
USER ||--o{ OPERATION_LOG : "performs"
USER {
int user_id PK
string username
string password
string name
enum role
string department
string position
int manager_id FK
}
PERFORMANCE_MONTH {
int perf_id PK
int user_id FK
string month
enum status
decimal self_score
decimal ai_score
decimal manager_score
decimal total_score
enum level
}
PERF_ITEM {
int item_id PK
int perf_id FK
string item_name
enum item_category
int weight
text user_content
decimal self_score
decimal ai_score
decimal manager_score
}
ATTENDANCE {
int attendance_id PK
int perf_id FK
int leave_days
int late_times
int absent_days
int lack_card_times
decimal attendance_score
}
AI_RESULT {
int ai_id PK
int perf_id FK
text ai_score_json
decimal ai_total_score
text problems
text suggestions
}
正确性属性
正确性属性是系统应该在所有有效执行中保持为真的特征或行为——本质上是关于系统应该做什么的形式化陈述。属性作为人类可读规范和机器可验证正确性保证之间的桥梁。
属性 1: 认证正确性
对于任意 用户凭据(用户名、密码、角色),认证结果应与凭据有效性严格一致——有效凭据必须返回 token,无效凭据必须被拒绝,不存在中间状态。
Validates: Requirements 1.1, 1.2
属性 2: 权限隔离不变量
对于任意 员工用户,使用其 token 查询其他员工的绩效数据时,系统应始终返回 403 权限不足错误,不泄露任何数据。
Validates: Requirements 1.5
属性 3: 草稿暂存往返一致性
对于任意 绩效填报数据,暂存后再读取,返回的数据应与暂存时提交的数据完全一致(往返属性)。
Validates: Requirements 2.5
属性 4: 提交幂等性
对于任意 已提交状态的绩效记录,再次尝试提交同一用户同一月份的绩效时,系统应拒绝并返回错误,绩效记录状态保持不变。
Validates: Requirements 2.6
属性 5: 绩效等级与奖惩计算正确性
对于任意 最终总分(0-100),系统计算出的绩效等级和奖惩金额应严格符合以下规则:
- 分数 >= 90 → 优秀,奖励
- 80 <= 分数 <= 89 → 合格,扣 100 元
- 70 <= 分数 <= 79 → 合格,扣 200 元
- 60 <= 分数 <= 69 → 需激励,扣 300 元
- 分数 < 60 → 不合格,扣 600 元
Validates: Requirements 5.1, 5.2, 5.3, 5.4, 5.5
属性 6: 连续低分预警正确性
对于任意 员工,若其连续 N 个月(N >= 2)的最终总分均低于 60 分,系统应正确标记对应的预警状态(N=2 书面警告,N>=3 劝退处理)。
Validates: Requirements 5.6, 5.7
属性 7: 绩效记录查询完整性
对于任意 已提交或已完成的绩效记录,员工查询个人历史绩效时,该记录必须出现在结果列表中,且内容与提交时一致(插入/查询往返属性)。
Validates: Requirements 6.1, 6.2
属性 8: 考勤分数计算正确性
对于任意 考勤数据(事假天数、迟到次数、缺卡次数),系统计算的考勤分数应满足:
- 基础分 10 分
- 每天事假扣 5 分
- 每次迟到/缺卡扣 2 分
- 最终分数不低于 0 分(下限保护)
Validates: Requirements 11.1, 11.2, 11.3, 11.5
属性 9: AI 响应 JSON 解析往返一致性
对于任意 符合规范的 AI 评分 JSON 字符串,系统解析后再序列化,应得到语义等价的对象(解析往返属性)。
Validates: Requirements 3.6, 13.3
属性 10: AI 输出格式约束
对于任意 AI 评分结果,ai_problems 和 ai_suggestions 数组的长度应在 3 到 5 之间(含边界值)。
Validates: Requirements 3.3, 3.4
错误处理
错误码规范
| 状态码 | 含义 | 场景 |
|---|---|---|
| 200 | 成功 | 正常响应 |
| 400 | 参数错误 | 请求参数缺失或格式错误 |
| 401 | 未登录/Token 失效 | Token 过期或未携带 |
| 403 | 权限不足 | 越权访问他人数据 |
| 500 | 服务器异常 | 内部错误 |
关键错误场景处理
AI 调用失败:
- 超时(>10s):记录错误日志,绩效状态标记为
ai_failed,管理员可手动触发重试 - 返回格式异常:记录原始响应,尝试降级解析,失败则通知管理员
数据库操作失败:
- 使用事务保证绩效提交的原子性(绩效主表 + 绩效项 + 考勤数据同时写入)
- 失败时回滚并返回 500 错误
并发提交冲突:
- 利用
UNIQUE KEY uk_user_month (user_id, month)数据库约束防止重复提交 - 捕获唯一键冲突异常,返回友好提示
测试策略
双重测试方法
系统采用单元测试和属性测试相结合的方式,两者互补:
- 单元测试: 验证具体示例、边界条件和错误场景
- 属性测试: 验证跨所有输入的通用属性
属性测试配置
- 使用 fast-check(TypeScript 属性测试库)
- 每个属性测试最少运行 100 次迭代
- 每个测试用注释标注对应的设计属性编号
- 标注格式:
// Feature: employee-performance-system, Property N: <属性描述>
属性测试覆盖
| 属性编号 | 测试内容 | 测试类型 |
|---|---|---|
| 属性 1 | 认证凭据有效性 | property |
| 属性 2 | 权限隔离 | property |
| 属性 3 | 草稿暂存往返 | property |
| 属性 4 | 提交幂等性 | property |
| 属性 5 | 等级奖惩计算 | property |
| 属性 6 | 连续低分预警 | property |
| 属性 7 | 绩效记录查询 | property |
| 属性 8 | 考勤分数计算 | property |
| 属性 9 | AI JSON 解析往返 | property |
| 属性 10 | AI 输出格式约束 | property |
单元测试覆盖
- 用户登录接口(具体示例:正确凭据、错误密码、不存在用户)
- 绩效提交接口(具体示例:暂存、提交、重复提交)
- 审核流程(具体示例:通过、驳回、修改申请)
- Excel 导出格式验证
- 分页查询边界条件(第一页、最后一页、空结果)