创建用户时默认部门为空

This commit is contained in:
caoqianming 2022-04-12 14:14:06 +08:00
parent 1e81f38343
commit b4db266dd9
9 changed files with 32 additions and 182 deletions

1
apps/hrm/errors.py Normal file
View File

@ -0,0 +1 @@
NO_NEED_LEVEL_REMARK = {"code":"no_need_level_remark", "detail":"无需填写离岗说明"}

View File

@ -2,12 +2,12 @@ from django.db import models
from django.db.models.query import QuerySet
from apps.system.models import User
from apps.utils.models import CommonADModel, CommonAModel
from apps.utils.models import CommonADModel, CommonAModel, CommonBModel
class Employee(CommonAModel):
class Employee(CommonBModel):
"""
员工信息
"""
@ -28,7 +28,7 @@ class Employee(CommonAModel):
id_number = models.CharField('身份证号', max_length=100, null=True, blank=True)
gender = models.CharField('性别', max_length=10, default='')
signature = models.CharField('签名图片', max_length=200, null=True, blank=True)
birthday = models.DateField('出生年月', null=True, blank=True)
birthday = models.DateField('出生年月', null=True, blank=True)
qualification = models.CharField('学历', max_length=50, null=True, blank=True)
job_state = models.IntegerField('在职状态', choices=jobstate_choices, default=1)
face_data = models.JSONField('人脸识别数据', null=True, blank=True)

View File

@ -2,13 +2,13 @@ from apps.system.models import User
from rest_framework.serializers import ModelSerializer
from rest_framework import serializers
from utils.mixins import DynamicFieldsSerializerMixin
from .models import ClockRecord, Employee, NotWorkRemark
from apps.system.serializers import OrganizationSimpleSerializer, UserSimpleSerializer
from apps.utils.serializers import CustomModelSerializer
class EmployeeSerializer(DynamicFieldsSerializerMixin, ModelSerializer):
name = serializers.CharField(source='user.name', read_only=True)
dept_ = OrganizationSimpleSerializer(source='user.dept', read_only=True)
from .models import ClockRecord, Employee, NotWorkRemark
from apps.system.serializers import DeptSimpleSerializer,UserSimpleSerializer
class EmployeeSerializer(CustomModelSerializer):
belong_dept_ = DeptSimpleSerializer(source='user.belong_dept', read_only=True)
class Meta:
model = Employee
exclude = ['face_data']
@ -17,13 +17,6 @@ class EmployeeNotWorkRemarkSerializer(ModelSerializer):
class Meta:
model = Employee
fields = ['not_work_remark']
class FaceLoginSerializer(serializers.Serializer):
base64 = serializers.CharField()
class FaceClockCreateSerializer(serializers.Serializer):
base64 = serializers.CharField()
class ClockRecordListSerializer(serializers.ModelSerializer):
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)

View File

@ -1,50 +0,0 @@
from django.conf import settings
import uuid
import face_recognition
import os
from apps.hrm.models import Employee
from apps.hrm.tasks import update_all_user_facedata_cache
from apps.system.models import User
from django.core.cache import cache
class HRMService:
@classmethod
def face_compare_from_base64(cls, base64_data):
filename = str(uuid.uuid4())
filepath = settings.BASE_DIR +'/temp/' + filename +'.png'
with open(filepath, 'wb') as f:
f.write(base64_data)
try:
unknown_picture = face_recognition.load_image_file(filepath)
unknown_face_encoding = face_recognition.face_encodings(unknown_picture, num_jitters=2)[0]
os.remove(filepath)
except:
os.remove(filepath)
return None, '识别失败,请调整位置'
# 匹配人脸库
face_datas = cache.get('face_datas')
if face_datas is None:
update_all_user_facedata_cache()
face_datas = cache.get('face_datas')
face_users = cache.get('face_users')
results = face_recognition.compare_faces(face_datas,
unknown_face_encoding, tolerance=0.45)
for index, value in enumerate(results):
if value:
# 识别成功
user = User.objects.get(id=face_users[index])
return user, ''
return None, '人脸未匹配,请调整位置'
@classmethod
def get_facedata_from_img(cls, img_path):
try:
photo_path = settings.BASE_DIR + img_path
picture_of_me = face_recognition.load_image_file(photo_path)
my_face_encoding = face_recognition.face_encodings(picture_of_me, num_jitters=2)[0]
face_data_list = my_face_encoding.tolist()
return face_data_list, ''
except:
return None, '人脸数据获取失败请重新上传图片'

View File

@ -2,7 +2,6 @@ from __future__ import absolute_import, unicode_literals
from celery import shared_task
from apps.hrm.models import Employee
from django.core.cache import cache
@shared_task
@ -12,19 +11,4 @@ def update_all_employee_not_atwork():
"""
Employee.objects.all().update(is_atwork=False, last_check_time = None, not_work_remark=None)
@shared_task
def update_all_user_facedata_cache():
"""
更新人脸数据缓存
"""
facedata_queyset = Employee.objects.filter(face_data__isnull=False,
user__is_active=True).values('user', 'face_data')
face_users = []
face_datas = []
for i in facedata_queyset:
face_users.append(i['user'])
face_datas.append(i['face_data'])
cache.set('face_users', face_users, timeout=None)
cache.set('face_datas', face_datas, timeout=None)

View File

@ -1,12 +1,9 @@
from django.shortcuts import render
from django.utils import timezone
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet, GenericViewSet
from rest_framework.mixins import UpdateModelMixin, RetrieveModelMixin, CreateModelMixin, ListModelMixin
from apps.hrm.errors import NO_NEED_LEVEL_REMARK
from apps.hrm.filters import ClockRecordFilterSet, EmployeeFilterSet, NotWorkRemarkFilterSet
from apps.hrm.services import HRMService
from apps.hrm.tasks import update_all_user_facedata_cache
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from apps.hrm.models import ClockRecord, Employee, NotWorkRemark
from apps.hrm.serializers import ClockRecordListSerializer, EmployeeNotWorkRemarkSerializer, EmployeeSerializer, FaceClockCreateSerializer, FaceLoginSerializer, NotWorkRemarkListSerializer
@ -20,18 +17,20 @@ from apps.system.models import User
from apps.system.serializers import UserSimpleSerializer
from rest_framework.permissions import AllowAny
from rest_framework.decorators import action
from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet
from rest_framework.exceptions import ParseError
# Create your views here.
class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMixin, ListModelMixin, RetrieveModelMixin, GenericViewSet):
class EmployeeViewSet(CustomModelViewSet):
"""
员工详细信息
员工信息管理
"""
perms_map = {'get': '*', 'put': 'employee_update'}
queryset = Employee.objects.all()
select_related_fields = ['user']
filterset_class = EmployeeFilterSet
serializer_class = EmployeeSerializer
search_fields = ['user__name', 'number', 'user__username']
search_fields = ['name', 'number', 'user__username']
ordering = ['-pk']
def update(self, request, *args, **kwargs):
@ -81,107 +80,30 @@ class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMix
instance.update_by = request.user
instance.save()
return Response()
return Response('无需填写离岗说明', status=status.HTTP_400_BAD_REQUEST)
raise ParseError(**NO_NEED_LEVEL_REMARK)
class ClockRecordViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
class ClockRecordViewSet(ListModelMixin, CustomGenericViewSet):
"""
打卡记录
"""
perms_map = {'get':'*', 'post':'*'}
authentication_classes = []
permission_classes = [AllowAny]
queryset = ClockRecord.objects.select_related('create_by').all()
queryset = ClockRecord.objects.all()
select_related_fields = ['create_by']
serializer_class = ClockRecordListSerializer
filterset_class = ClockRecordFilterSet
ordering = ['-pk']
def get_serializer_class(self):
if self.action == 'create':
return FaceClockCreateSerializer
return super().get_serializer_class()
def create(self, request, *args, **kwargs):
now = timezone.now()
now_local = timezone.localtime()
if 8<=now_local.hour<=17:
base64_data = base64.urlsafe_b64decode(tran64(
request.data.get('base64').replace(' ', '+')))
user, msg = HRMService.face_compare_from_base64(base64_data)
if user:
ins, created = ClockRecord.objects.get_or_create(
create_by = user, create_time__hour__range = [8,18],
create_time__year=now_local.year, create_time__month=now_local.month,
create_time__day=now_local.day,
defaults={
'type':ClockRecord.ClOCK_WORK1,
'create_by':user,
'create_time':now
})
if not created:
ins.update_time = now
ins.save()
# 设为在岗
Employee.objects.filter(user=user).update(is_atwork=True, last_check_time=now)
return Response(UserSimpleSerializer(instance=user).data)
return Response(msg, status=status.HTTP_400_BAD_REQUEST)
return Response('非打卡时间范围', status=status.HTTP_400_BAD_REQUEST)
class NotWorkRemarkViewSet(ListModelMixin, GenericViewSet):
class NotWorkRemarkViewSet(ListModelMixin, CustomGenericViewSet):
"""
离岗说明
"""
perms_map = {'get':'*'}
queryset = NotWorkRemark.objects.select_related('user').all()
queryset = NotWorkRemark.objects.all()
select_related_fields = ['user']
serializer_class = NotWorkRemarkListSerializer
filterset_class = NotWorkRemarkFilterSet
ordering = ['-pk']
import base64
def tran64(s):
missing_padding = len(s) % 4
if missing_padding != 0:
s = s+'='* (4 - missing_padding)
return s
class FaceLogin(CreateAPIView):
authentication_classes = []
permission_classes = []
serializer_class = FaceLoginSerializer
def create(self, request, *args, **kwargs):
"""
人脸识别登录
"""
base64_data = base64.urlsafe_b64decode(tran64(request.data.get('base64').replace(' ', '+')))
user, msg = HRMService.face_compare_from_base64(base64_data)
if user:
refresh = RefreshToken.for_user(user)
# 可设为在岗
now = timezone.now()
now_local = timezone.localtime()
if 8<=now_local.hour<=17:
ins, created = ClockRecord.objects.get_or_create(
create_by = user, create_time__hour__range = [8,18],
create_time__year=now_local.year, create_time__month=now_local.month,
create_time__day=now_local.day,
defaults={
'type':ClockRecord.ClOCK_WORK1,
'create_by':user,
'create_time':now
})
# 设为在岗
if created:
Employee.objects.filter(user=user).update(is_atwork=True, last_check_time=now)
return Response({
'refresh': str(refresh),
'access': str(refresh.access_token),
'username':user.username,
'name':user.name
})
return Response(msg, status=status.HTTP_400_BAD_REQUEST)
ordering = ['-pk']

View File

@ -12,6 +12,7 @@ from rest_framework.exceptions import ParseError, APIException
from django.db import transaction
from apps.third.tapis import dhapis
from rest_framework.validators import UniqueValidator
from django.contrib.auth.hashers import make_password
class IntervalSerializer(CustomModelSerializer):
class Meta:
@ -273,6 +274,7 @@ class UserCreateSerializer(CustomModelSerializer):
class Meta:
model = User
fields = ['username', 'name', 'avatar', 'is_active']
class PasswordChangeSerializer(serializers.Serializer):

View File

@ -305,14 +305,10 @@ class UserViewSet(CustomModelViewSet):
创建用户
"""
password = request.data.get('password', None)
if password:
password = make_password(password)
else:
password = make_password('0000')
password = make_password('0000')
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(password=password)
serializer.save(password=password, belong_dept=None)
return Response(data=serializer.data)
@action(methods=['put'], detail=False,

View File

@ -19,7 +19,9 @@ class CustomModelSerializer(DynamicFieldsMixin, serializers.ModelSerializer):
if self.request:
if getattr(self.request, 'user', None):
validated_data['create_by'] = self.request.user
if getattr(self.request.user, 'belong_dept', None):
if 'belong_dept' in validated_data: # 如果指定数据归属部门
pass
elif getattr(self.request.user, 'belong_dept', None):
validated_data['belong_dept'] = self.request.user.belong_dept
return super().create(validated_data)