189 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Python
		
	
	
	
| from functools import update_wrapper
 | |
| from venv import create
 | |
| 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.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
 | |
| 
 | |
| 
 | |
| 
 | |
| from rest_framework.generics import CreateAPIView
 | |
| from rest_framework import status
 | |
| from rest_framework_simplejwt.tokens import RefreshToken
 | |
| from rest_framework import exceptions
 | |
| from apps.system.models import User
 | |
| from apps.system.serializers import UserSimpleSerializer
 | |
| from rest_framework.permissions import AllowAny
 | |
| from rest_framework.decorators import action
 | |
| 
 | |
| 
 | |
| # Create your views here.
 | |
| class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMixin, ListModelMixin, RetrieveModelMixin, GenericViewSet):
 | |
|     """
 | |
|     员工详细信息
 | |
|     """
 | |
|     perms_map = {'get': '*', 'put': 'employee_update'}
 | |
|     queryset = Employee.objects.all()
 | |
|     filterset_class = EmployeeFilterSet
 | |
|     serializer_class = EmployeeSerializer
 | |
|     search_fields = ['user__name', 'number', 'user__username']
 | |
|     ordering = ['-pk']
 | |
|     
 | |
|     def update(self, request, *args, **kwargs):
 | |
|         partial = kwargs.pop('partial', False)
 | |
|         instance = self.get_object()
 | |
|         data = request.data
 | |
|         serializer = self.get_serializer(instance, data=data, partial=partial)
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         photo = data.get('photo', None)
 | |
|         if instance.photo != photo:
 | |
|             f_l, msg = HRMService.get_facedata_from_img(img_path=photo)
 | |
|             if f_l:
 | |
|                 serializer.save(update_by=request.user, face_data = f_l)
 | |
|                 # 更新人脸缓存
 | |
|                 update_all_user_facedata_cache.delay()
 | |
|                 return Response()
 | |
|             return Response(msg, status=status.HTTP_400_BAD_REQUEST)
 | |
|         serializer.save(update_by=request.user)
 | |
|         return Response()
 | |
| 
 | |
|     @action(methods=['post'], detail=True, perms_map={'post': 'employee_notworkremark'}
 | |
|     , serializer_class=EmployeeNotWorkRemarkSerializer)
 | |
|     def not_work_remark(self, request, pk=None):
 | |
|         """
 | |
|         填写离岗说明
 | |
|         """
 | |
|         serializer = self.get_serializer(data=request.data)
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         obj = self.get_object()
 | |
|         if not obj.is_atwork:
 | |
|             remark = request.data.get('not_work_remark', '')
 | |
|             obj.not_work_remark = remark
 | |
|             obj.save()
 | |
|             now = timezone.now()
 | |
|             instance, created = NotWorkRemark.objects.get_or_create(
 | |
|                 not_work_date = now.date(),
 | |
|                 user = obj.user,
 | |
|                 defaults={
 | |
|                     "not_work_date":now.date(),
 | |
|                     "user":obj.user,
 | |
|                     "remark":remark,
 | |
|                     "create_by":request.user,
 | |
|                 }
 | |
|             )
 | |
|             if not created:
 | |
|                 instance.remark = remark
 | |
|                 instance.update_by = request.user
 | |
|                 instance.save()
 | |
|             return Response()
 | |
|         return Response('无需填写离岗说明', status=status.HTTP_400_BAD_REQUEST)
 | |
| 
 | |
| 
 | |
| class ClockRecordViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
 | |
|     """
 | |
|     打卡记录
 | |
|     """
 | |
|     perms_map = {'get':'*', 'post':'*'}
 | |
|     authentication_classes = []
 | |
|     permission_classes = [AllowAny]
 | |
|     queryset = ClockRecord.objects.select_related('create_by').all()
 | |
|     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):
 | |
|     """
 | |
|     离岗说明
 | |
|     """
 | |
|     perms_map = {'get':'*'}
 | |
|     queryset = NotWorkRemark.objects.select_related('user').all()
 | |
|     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) |