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, FaceLoginPathSerializer, 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, request.data.get('tolerance', 0.45)) 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, request.data.get('tolerance', 0.45)) 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) class FacePathLogin(CreateAPIView): authentication_classes = [] permission_classes = [] serializer_class = FaceLoginPathSerializer def create(self, request, *args, **kwargs): """ 人脸识别登录-文件地址 """ user, msg = HRMService.face_compare_from_path(request.data.get('path'), request.data.get('tolerance', 0.45)) 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)