企业绩效管理系统是现代企业管理中不可或缺的工具。作为一名长期从事企业信息化建设的开发者,我最近用Python Flask框架完整实现了一套绩效管理系统,今天就来分享这个项目的实战经验。
这个系统主要解决了传统纸质考核或Excel表格管理带来的效率低下、数据孤岛、统计分析困难等问题。系统上线后,某中型企业的月度考核时间从原来的3天缩短到2小时,部门主管可以实时查看团队绩效趋势,HR也能快速生成各类统计报表。
在项目启动阶段,我与客户进行了深入的需求调研,最终确定了以下核心功能模块:
为什么选择Flask而不是Django?主要基于以下几点考虑:
提示:如果项目需要快速开发且需求标准,Django的全功能特性可能更适合
python复制class Employee(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
department_id = db.Column(db.Integer, db.ForeignKey('department.id'))
position = db.Column(db.String(50))
hire_date = db.Column(db.Date)
# 其他字段...
class PerformanceMetric(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
weight = db.Column(db.Float, default=1.0)
description = db.Column(db.Text)
# 其他字段...
注意:实际项目中建议添加created_at/updated_at时间戳字段,便于数据追踪
python复制@app.route('/api/employees', methods=['POST'])
@login_required
@roles_required('admin')
def create_employee():
try:
data = request.get_json()
employee = Employee(
name=data['name'],
department_id=data['department_id'],
position=data.get('position'),
hire_date=datetime.strptime(data['hire_date'], '%Y-%m-%d')
)
db.session.add(employee)
db.session.commit()
return jsonify({'status': 'success', 'id': employee.id}), 201
except Exception as e:
db.session.rollback()
return jsonify({'status': 'error', 'message': str(e)}), 400
实现了一个基于状态机的工作流引擎:
python复制class EvaluationStatus(enum.Enum):
DRAFT = '草稿'
SELF_EVALUATED = '自评完成'
MANAGER_REVIEWED = '主管审核'
HR_CONFIRMED = 'HR确认'
ARCHIVED = '已归档'
@app.route('/api/evaluations/<int:eval_id>/submit', methods=['POST'])
def submit_evaluation(eval_id):
evaluation = Evaluation.query.get_or_404(eval_id)
if evaluation.status != EvaluationStatus.DRAFT:
abort(400, description="只能提交草稿状态的考核")
evaluation.status = EvaluationStatus.SELF_EVALUATED
db.session.commit()
# 发送通知给主管
send_notification(
recipient=evaluation.employee.manager,
message=f"{evaluation.employee.name}提交了新的考核"
)
return jsonify({'status': 'success'})
python复制from flask_principal import Principal, Permission, RoleNeed
# 初始化
principals = Principal()
admin_permission = Permission(RoleNeed('admin'))
manager_permission = Permission(RoleNeed('manager'))
@app.route('/admin/dashboard')
@admin_permission.require(http_exception=403)
def admin_dashboard():
return render_template('admin/dashboard.html')
@app.route('/department/<int:dept_id>/report')
@manager_permission.require(http_exception=403)
def department_report(dept_id):
# 验证当前用户是否是该部门主管
if current_user.department_id != dept_id:
abort(403)
# 其他逻辑...
对于普通员工,需要限制只能查看自己的数据:
python复制def get_employee_performance(employee_id):
if not current_user.has_role('admin'):
if employee_id != current_user.employee_id:
abort(403)
return Performance.query.filter_by(employee_id=employee_id).all()
python复制@app.route('/api/performance/stats')
@login_required
def performance_stats():
department_id = request.args.get('department_id')
# 基础数据查询
query = db.session.query(
Employee.department_id,
func.avg(Evaluation.total_score).label('avg_score'),
func.count(Evaluation.id).label('eval_count')
).join(Employee)
# 权限过滤
if not current_user.has_role('admin'):
query = query.filter(Employee.department_id == current_user.department_id)
elif department_id:
query = query.filter(Employee.department_id == department_id)
stats = query.group_by(Employee.department_id).all()
return jsonify({
'stats': [{
'department_id': s.department_id,
'avg_score': float(s.avg_score),
'eval_count': s.eval_count
} for s in stats]
})
使用Chart.js的示例配置:
javascript复制fetch('/api/performance/stats')
.then(response => response.json())
.then(data => {
const ctx = document.getElementById('performanceChart').getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: data.stats.map(s => `部门${s.department_id}`),
datasets: [{
label: '平均绩效分',
data: data.stats.map(s => s.avg_score),
backgroundColor: 'rgba(54, 162, 235, 0.5)'
}]
},
options: {
scales: {
y: {
beginAtZero: true,
max: 100
}
}
}
});
});
python复制class PerformanceTestCase(unittest.TestCase):
def setUp(self):
self.app = create_app('testing')
self.client = self.app.test_client()
with self.app.app_context():
db.create_all()
# 添加测试数据...
def test_employee_creation(self):
response = self.client.post('/api/employees', json={
'name': '测试员工',
'department_id': 1,
'position': '测试工程师',
'hire_date': '2023-01-01'
}, headers={'Authorization': f'Bearer {self.admin_token}'})
self.assertEqual(response.status_code, 201)
data = response.get_json()
self.assertIn('id', data)
推荐使用Gunicorn + Nginx的组合:
bash复制# 安装Gunicorn
pip install gunicorn
# 启动命令
gunicorn -w 4 -b 127.0.0.1:8000 "app:create_app()"
# Nginx配置示例
server {
listen 80;
server_name performance.example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /static {
alias /path/to/your/static/files;
}
}
性能问题:初期直接加载所有员工数据导致页面卡顿
并发冲突:多人同时修改同一考核记录
python复制@app.route('/api/evaluations/<int:eval_id>', methods=['PUT'])
def update_evaluation(eval_id):
evaluation = Evaluation.query.get_or_404(eval_id)
if evaluation.version != request.json.get('version'):
abort(409, description="数据已被他人修改,请刷新后重试")
# 其他更新逻辑...
python复制# Celery任务示例
@celery.task
def generate_performance_report(employee_id, period):
employee = Employee.query.get(employee_id)
evaluations = Evaluation.query.filter_by(
employee_id=employee_id,
period=period
).all()
# 生成PDF报告
report = create_pdf_report(employee, evaluations)
# 发送邮件
send_email(
to=employee.email,
subject=f"{period}绩效报告",
attachments=[('report.pdf', report)]
)
这个项目从设计到上线历时3个月,期间遇到了各种挑战,但最终交付的系统获得了客户的高度认可。对于想要开发类似系统的同行,我的建议是:前期一定要做好需求分析,特别是考核流程和权限控制部分;中期注重代码的可维护性;后期则要关注性能优化和用户体验。