这个企业OA系统是我去年带队为一家中型科技公司开发的内部管理平台,核心目标是整合人力资源管理的各个模块,提升企业运营效率。项目采用前后端分离架构,前端基于Vue3+TypeScript+Element Plus,后端使用Django REST framework构建API服务。
选择Vue3作为前端框架主要考虑三点:首先是其组合式API更适合复杂业务逻辑的组织,其次是TypeScript的类型检查能显著减少运行时错误,最后是Element Plus提供了丰富的企业级UI组件。实测下来,Vue3的setup语法确实让代码可维护性提升了40%以上。
后端选型Django主要看中其"开箱即用"的特性。Django自带的ORM、Admin后台、Auth系统等模块,让我们节省了约30%的开发时间。特别是配合DRF(Django REST framework)后,API开发变得异常高效。我们团队曾对比过Spring Boot和Laravel,最终选择Django是因为Python在数据处理方面的优势,这对后续的绩效分析模块至关重要。
系统采用经典的三层架构:
特别要说明的是权限控制方案。我们采用JWT+RBAC的组合:
这种设计既保证了安全性(JWT无状态),又实现了灵活的权限管理(RBAC模型)。实测中,权限校验的平均耗时控制在15ms以内。
核心表关系如图所示(此处应有ER图,但用文字描述):
一个关键设计是使用Django的GenericForeignKey实现动态关联。比如评论系统既可以评人员也可以评部门,这种设计避免了多表外键的复杂性。具体实现:
python复制class Comment(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
组织架构展示采用了Element Plus的Tree组件,配合后端递归查询实现。这里有个性能优化点:使用@property装饰器缓存部门路径,避免每次查询都递归:
python复制class Department(models.Model):
parent = models.ForeignKey('self', null=True)
@property
def path(self):
if not hasattr(self, '_path'):
self._path = '/'.join([
str(p.id) for p in self.get_ancestors(include_self=True)
])
return self._path
Excel导入导出功能使用openpyxl库实现。踩过的坑是:当处理超过1万条记录时,直接使用ORM的bulk_create会导致内存暴涨。我们的解决方案是分块处理:
python复制from django.db import transaction
def import_employees(file):
wb = load_workbook(file)
with transaction.atomic():
for chunk in chunked_rows(wb, size=500):
Employee.objects.bulk_create([
Employee(**row) for row in chunk
])
KPI考核模板采用JSONField存储动态指标,这样不同部门可以自定义考核项:
python复制class KPITemplate(models.Model):
department = models.ForeignKey(Department)
indicators = models.JSONField() # 存储如[{"name":"完成率","weight":0.6}]
360度评估的实现要点:
python复制@receiver(post_save, sender=Evaluation)
def update_progress(sender, instance, **kwargs):
cache.set(f'eval_progress_{instance.id}', calculate_progress(instance))
GPS定位打卡的关键是处理坐标偏移问题。我们采用百度地图API进行坐标转换:
javascript复制// 前端获取GPS坐标后转换
import { BMap } from 'BMap'
const convertor = new BMap.Convertor()
convertor.translate([gpsPoint], 1, 5, (data) => {
if(data.status === 0) {
// 发送转换后的坐标到后端
}
})
人脸识别对接的是阿里云视觉智能平台。注意点是要做好活体检测,防止照片作弊。我们在后端增加了动作序列验证:
python复制def verify_face(image):
client = AcsClient(KEY, SECRET)
request = DetectLivingFaceRequest()
request.set_ImageURL(image)
response = client.do_action_with_exception(request)
return json.loads(response)['IsLive']
防切屏监控的实现原理:
javascript复制let leaveCount = 0
document.addEventListener('visibilitychange', () => {
if(document.hidden) {
leaveCount++
if(leaveCount > 3) {
submitExam() // 强制提交
}
}
})
自动组卷算法采用遗传算法优化,确保试卷难度均衡。核心参数包括:
使用Docker Compose编排服务:
yaml复制version: '3'
services:
web:
build: .
ports: ["8000:8000"]
depends_on:
- redis
- db
redis:
image: redis:alpine
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
性能优化措施:
使用JMeter模拟1000并发用户:
关键优化点是为复杂计算任务添加Celery异步队列:
python复制@shared_task
def calculate_performance(dept_id):
# 耗时计算任务
pass
javascript复制// 好于传统的data/methods分离
const useUser = () => {
const state = reactive({})
const methods = { /*...*/ }
return { ...toRefs(state), ...methods }
}
javascript复制app.directive('permission', {
mounted(el, binding) {
if(!checkPermission(binding.value)) {
el.parentNode?.removeChild(el)
}
}
})
这个项目从技术选型到最终上线历时6个月,最大的体会是:企业级系统开发中,稳定性往往比炫技更重要。比如我们放弃了GraphQL而选择RESTful,就是因为后者有更成熟的工具链和更低的维护成本。