227 lines
9.1 KiB
Python
227 lines
9.1 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, 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.42))
|
|
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.42))
|
|
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.42))
|
|
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) |