diff --git a/apps/develop/serializers.py b/apps/develop/serializers.py index 2d28638a..ad29065b 100755 --- a/apps/develop/serializers.py +++ b/apps/develop/serializers.py @@ -14,3 +14,7 @@ class GenerateVoiceSerializer(serializers.Serializer): class TestTaskSerializer(serializers.Serializer): args = serializers.ListField(child=serializers.CharField(), label='列表参数', required=False, allow_null=True) kwargs = serializers.JSONField(label="字典参数", required=False, allow_null=True) + + +class CleanDataSerializer(serializers.Serializer): + datas = serializers.ListField(child=serializers.CharField(), label='数据分类列表', required=False, allow_null=True) diff --git a/apps/develop/views.py b/apps/develop/views.py index 54f4d19a..c2c4372b 100755 --- a/apps/develop/views.py +++ b/apps/develop/views.py @@ -4,7 +4,7 @@ from rest_framework.permissions import IsAdminUser from rest_framework.response import Response from rest_framework.serializers import Serializer from rest_framework.decorators import action -from apps.develop.serializers import GenerateVoiceSerializer, SendSmsSerializer, TestTaskSerializer +from apps.develop.serializers import CleanDataSerializer, GenerateVoiceSerializer, SendSmsSerializer, TestTaskSerializer from apps.develop.tasks import backup_database, backup_media, reload_web_git, reload_server_git, reload_server_only from rest_framework.exceptions import APIException from apps.system.tasks import show @@ -175,3 +175,33 @@ class TestViewSet(CustomGenericViewSet): # rt = requests.post(url=url, json=data).text res = wxClient.send_tem_msg(data=data) return Response(res) + + @action(methods=['post'], detail=False, serializer_class=CleanDataSerializer) + def clean_data(self, request, pk=None): + """清空数据 + + 清空数据 + """ + datas = request.data['datas'] + from apps.wf.models import Ticket + from apps.hrm.models import Employee + from apps.system.models import User, Dept + if 'visit' in datas: + # 访客 + from apps.vm.models import Visit, Visitor + Visit.objects.get_queryset(all=True).delete(soft=False) + Visitor.objects.get_queryset(all=True).delete(soft=False) + + Ticket.objects.get_queryset(all=True).filter(workflow__key='visit').delete(soft=False) + + Employee.objects.get_queryset(all=True).filter(type='visitor').delete(soft=False) + + User.objects.get_queryset(all=True).filter(type='visitor').delete(soft=False) + if 'rpm' in datas: + from apps.rpm.models import Rparty + Rparty.objects.get_queryset(all=True).delete(soft=False) + Ticket.objects.get_queryset(all=True).filter(workflow__key='rpj').delete(soft=False) + Employee.objects.get_queryset(all=True).filter(type='remployee').delete(soft=False) + User.objects.get_queryset(all=True).filter(type='remployee').delete(soft=False) + Dept.objects.get_queryset(all=True).filter(type='rparty').delete(soft=False) + return Response() diff --git a/apps/hrm/serializers.py b/apps/hrm/serializers.py index 8b6c2c03..f045c32f 100755 --- a/apps/hrm/serializers.py +++ b/apps/hrm/serializers.py @@ -67,6 +67,9 @@ class EmployeeCreateUpdateSerializer(CustomModelSerializer): old_photo = instance.photo old_job_state = instance.job_state instance = super().update(instance, validated_data) + if instance.type == 'remployee': + from apps.rpm.services import sync_to_rep + sync_to_rep(instance) if instance.job_state == 20 and instance.user: # 如果离职了关闭账户 instance.user.is_active = False instance.user.save() @@ -94,7 +97,7 @@ class EmployeeImproveSerializer(CustomModelSerializer): class Meta: model = Employee - fields = ['photo', 'id_number', 'email', 'gender', 'signature', 'photo_f', 'signature_f'] + fields = ['photo', 'id_number', 'email', 'gender', 'signature', 'photo_f', 'signature_f', 'phone'] class ChannelAuthoritySerializer(serializers.Serializer): diff --git a/apps/hrm/views.py b/apps/hrm/views.py index b893fda6..5fa78fed 100755 --- a/apps/hrm/views.py +++ b/apps/hrm/views.py @@ -78,7 +78,9 @@ class EmployeeViewSet(CustomModelViewSet): ep = user.employee serializer = EmployeeImproveSerializer(instance=ep, data=request.data) serializer.is_valid(raise_exception=True) - serializer.save() + if ep.type == 'remployee': + from apps.rpm.services import sync_to_rep + sync_to_rep(ep) return Response() @action(methods=['post'], detail=True, perms_map={'post': 'employee.notworkremark'}, diff --git a/apps/rpm/apps.py b/apps/rpm/apps.py index 7ff3a4cc..068d5522 100644 --- a/apps/rpm/apps.py +++ b/apps/rpm/apps.py @@ -4,3 +4,6 @@ from django.apps import AppConfig class RpmConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'apps.rpm' + + def ready(self): + import apps.rpm.signals \ No newline at end of file diff --git a/apps/rpm/migrations/0003_auto_20220823_1628.py b/apps/rpm/migrations/0003_auto_20220823_1628.py new file mode 100644 index 00000000..ab1ae6f0 --- /dev/null +++ b/apps/rpm/migrations/0003_auto_20220823_1628.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.12 on 2022-08-23 08:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rpm', '0002_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='remployee', + name='id_number', + field=models.CharField(blank=True, max_length=100, null=True, verbose_name='身份证号'), + ), + migrations.AlterField( + model_name='remployee', + name='photo', + field=models.CharField(blank=True, max_length=1000, null=True, verbose_name='证件照'), + ), + ] diff --git a/apps/rpm/models.py b/apps/rpm/models.py index a72c8ee9..48ceda8c 100644 --- a/apps/rpm/models.py +++ b/apps/rpm/models.py @@ -86,8 +86,8 @@ class Remployee(CommonAModel): on_delete=models.SET_NULL, null=True, blank=True) name = models.CharField('姓名', max_length=20) phone = models.CharField('手机号', max_length=11) - photo = models.CharField('证件照', max_length=1000) - id_number = models.CharField('身份证号', max_length=100) + photo = models.CharField('证件照', max_length=1000, null=True, blank=True) + id_number = models.CharField('身份证号', max_length=100, null=True, blank=True) rparty = models.ForeignKey(Rparty, verbose_name='所属相关方', on_delete=models.CASCADE) rpj = models.ForeignKey(Rpj, verbose_name='最近所属相关方项目', on_delete=models.SET_NULL, null=True, blank=True) diff --git a/apps/rpm/serializers.py b/apps/rpm/serializers.py index c89c66ed..d3238997 100644 --- a/apps/rpm/serializers.py +++ b/apps/rpm/serializers.py @@ -2,6 +2,7 @@ from apps.hrm.models import Employee from apps.rpm.models import Rcertificate, Remployee, Rfile, Rparty, Rpjcertificate, Rpjfile, Rpjmember, Rpj from apps.system.models import Dept +from apps.system.services import sync_dahua_dept from apps.utils.constants import EXCLUDE_FIELDS from apps.utils.fields import MyFilePathField from apps.utils.serializers import CustomModelSerializer @@ -25,18 +26,22 @@ class RpartyCreateUpdateSerializer(CustomModelSerializer): def create(self, validated_data): instance = super().create(validated_data) - dept = Dept.objects.create(name=instance.name, - parent=instance.belong_dept, type='rparty') + with transaction.atomic(): + dept = Dept.objects.create(name=instance.name, + parent=instance.belong_dept, type='rparty') + sync_dahua_dept(dept) instance.dept = dept instance.save() return instance def update(self, instance, validated_data): instance = super().update(instance, validated_data) - dept = instance.dept - dept.name = instance.name - dept.parent = instance.belong_dept - dept.save() + with transaction.atomic(): + dept = instance.dept + dept.name = instance.name + dept.parent = instance.belong_dept # 重新规划归属部门 + dept.save() + sync_dahua_dept(dept) return instance @@ -186,7 +191,12 @@ class RpjmemberCreateSerializer(CustomModelSerializer): if rpj.state != Rpj.RPJ_CREATE: raise ParseError('成员非创建状态不可新增') rcertificates = validated_data.pop('rcertificates') - if Rpjmember.objects.filter(remployee=validated_data['remployee'], rpj=validated_data['rpj']).exists(): + remployee = validated_data['remployee'] + if remployee.phone and remployee.photo and remployee.id_number: + pass + else: + raise ParseError('该成员信息不全请补充') + if Rpjmember.objects.filter(remployee=remployee, rpj=validated_data['rpj']).exists(): raise ParseError('该成员已选择') with transaction.atomic(): ins = super().create(validated_data) @@ -244,7 +254,8 @@ class RpjcertificateSerializer(CustomModelSerializer): class Meta: model = Rpjcertificate - fields = ['rcertificate', 'name', 'type', 'number', 'issue_date', 'expiration_date', 'review_date', 'file', 'file_f'] + fields = ['rcertificate', 'name', 'type', 'number', 'issue_date', + 'expiration_date', 'review_date', 'file', 'file_f'] class RpjmemberSerializer(CustomModelSerializer): diff --git a/apps/rpm/services.py b/apps/rpm/services.py index 11d6baf7..3dbfdb8e 100644 --- a/apps/rpm/services.py +++ b/apps/rpm/services.py @@ -4,10 +4,27 @@ from apps.hrm.services import HrmService from apps.system.models import Post, User, UserPost from apps.utils.tools import ranstr from apps.wf.models import Ticket, Transition -from apps.rpm.models import Rfile, Rpj, Rpjcertificate, Rpjfile, Rpjmember +from apps.rpm.models import Remployee, Rfile, Rparty, Rpj, Rpjcertificate, Rpjfile, Rpjmember from django.contrib.auth.hashers import make_password +def sync_to_rep(ep: Employee): + # 个人信息完善时同步到rep表 + Remployee.objects.filter(employee=ep).update(name=ep.name, phone=ep.phone, id_number=ep.id_number, photo=ep.photo) + if ep.user: + rps = Rparty.objects.filter(admin=ep.user) + # 如果是管理员账户 + for i in rps: + Remployee.objects.get_or_create(employee=ep, defaults={ + 'employee': ep, + 'name': ep.name, + 'phone': ep.phone, + 'id_number': ep.id_number, + 'photo': ep.photo, + 'rparty': i + }) + + def bind_rpj(ticket: Ticket, transition: Transition, new_ticket_data: dict): rpj = Rpj.objects.get(id=new_ticket_data['rpj']) # ticket_data = ticket.ticket_data @@ -29,6 +46,7 @@ def rpj_audit_end(ticket): # 更新入厂项目人员库 for i in Rpjmember.objects.filter(rpj=rpj): rep = i.remployee + # 尝试找到人员 ep = Employee.objects.filter(id_number=rep.id_number).first() if ep: pass @@ -53,6 +71,7 @@ def rpj_audit_end(ticket): user_e.type = 'remployee' user_e.password = make_password('0000') user_e.belong_dept = rpj_dept + user_e.post = post user_e.save() ep.user = user_e ep.save() @@ -76,6 +95,7 @@ def rpj_audit_end(ticket): pass else: ct = Certificate() + ct.employee = i.rpj_member.remployee.employee ct.name = i.name ct.number = i.number ct.type = i.type @@ -83,7 +103,6 @@ def rpj_audit_end(ticket): ct.expiration_date = i.expiration_date ct.review_date = i.review_date ct.file = i.file - ct.employee = i.rpj_member.remployee.employee ct.save() # 更新相关方资料库后续可从资料库里选择 for i in Rpjfile.objects.filter(rpj=rpj): diff --git a/apps/rpm/signals.py b/apps/rpm/signals.py new file mode 100644 index 00000000..4b598dcf --- /dev/null +++ b/apps/rpm/signals.py @@ -0,0 +1,12 @@ +from django.db.models.signals import post_save +from django.dispatch import receiver +from apps.hrm.models import Employee +from apps.rpm.models import Remployee, Rparty + + +# @receiver(post_save, sender=Employee) +# def update_remployee(sender, instance, created, **kwargs): +# if instance.user and instance.type == 'remployee': +# if created +# reps = Remployee.objects.filter(employee=instance) +# reps.update(name=instance.name, phone=instance.phone, id_number=instance.id_number, photo=instance.photo) \ No newline at end of file diff --git a/apps/rpm/views.py b/apps/rpm/views.py index 7a58051f..ac8a9610 100644 --- a/apps/rpm/views.py +++ b/apps/rpm/views.py @@ -6,6 +6,7 @@ from apps.rpm.serializers import (RcertificateCreateUpdateSerializer, RfileListSerializer, RpartySerializer, RpjListSerializer, RpjfileSerializer, RpjfileUpdateSerializer, RpjmemberCreateSerializer, RpjCreateUpdateSerializer, RpjmemberSerializer, RpjmemberUpdateSerializer) +from apps.rpm.services import sync_to_rep from apps.system.models import Dictionary, Post, UserPost from apps.system.serializers import UserCreateSerializer from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet @@ -48,6 +49,7 @@ class RpartyViewSet(CustomModelViewSet): ins = serializer.save(type='remployee', password=make_password('0000')) obj.admin = ins obj.save() + # 岗位设置为相关方岗位 UserPost.objects.get_or_create(user=ins, dept=obj.dept, defaults={ 'user': ins, @@ -60,6 +62,8 @@ class RpartyViewSet(CustomModelViewSet): ins.post = up.post ins.update_by = self.request.user ins.save() + # 同步设置rep + sync_to_rep(ins.employee) return Response() @@ -96,6 +100,11 @@ class RemployeeViewSet(CustomModelViewSet): 添加人员 """ user = self.request.user + # ep = user.employee + # if ep.id_number and ep.photo: + # pass + # else: + # raise ParseError('请先完善个人信息') serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) vdata = serializer.validated_data diff --git a/apps/system/models.py b/apps/system/models.py index 9c6fd7b4..a9cb2dba 100755 --- a/apps/system/models.py +++ b/apps/system/models.py @@ -78,7 +78,7 @@ class Role(CommonADModel): return self.name -class Post(CommonAModel): +class Post(CommonADModel): """ 职位/岗位 """ diff --git a/apps/system/serializers.py b/apps/system/serializers.py index 537b5434..1d7d4458 100755 --- a/apps/system/serializers.py +++ b/apps/system/serializers.py @@ -4,16 +4,18 @@ from rest_framework import serializers from django_celery_results.models import TaskResult from apps.hrm.errors import PHONE_EXIST from apps.system.errors import USERNAME_EXIST +from apps.system.services import sync_dahua_dept from apps.utils.fields import MyFilePathField from apps.utils.serializers import CustomModelSerializer from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE from .models import (Dictionary, DictType, File, Dept, Permission, Post, PostRole, Role, User, UserPost) -from rest_framework.exceptions import ParseError +from rest_framework.exceptions import ParseError, ValidationError from django.db import transaction from apps.third.tapis import dhapis from rest_framework.validators import UniqueValidator from django.conf import settings +from django.db.models import Q # from django_q.models import Task as QTask, Schedule as QSchedule @@ -166,6 +168,16 @@ class PostCreateUpdateSerializer(CustomModelSerializer): model = Post exclude = EXCLUDE_FIELDS + def create(self, validated_data): + if Post.objects.filter(name=validated_data['name']).exists(): + raise ValidationError('该岗位已存在') + return super().create(validated_data) + + def update(self, instance, validated_data): + if Post.objects.filter(name=validated_data['name']).exclude(id=instance.id).exists(): + raise ValidationError('该岗位已存在') + return super().update(instance, validated_data) + class PostSimpleSerializer(CustomModelSerializer): class Meta: @@ -250,42 +262,15 @@ class DeptCreateUpdateSerializer(CustomModelSerializer): @transaction.atomic def create(self, validated_data): - from apps.third.clients import dhClient - if settings.DAHUA_ENABLED: - data = { - "parentId": 1, - "name": validated_data['name'], - "service": "ehs" - } - _, res = dhClient.request(**dhapis['dept_create'], json=data) - third_info = {'dh_id': str(res['id'])} - validated_data['third_info'] = third_info - return super().create(validated_data) + ins = super().create(validated_data) + sync_dahua_dept(ins) + return ins @transaction.atomic def update(self, instance, validated_data): - from apps.third.clients import dhClient - third_info = instance.third_info - if settings.DAHUA_ENABLED and not third_info.get('dh_id', False): - # 如果dh_id 不存在 - data = { - "parentId": 1, - "name": validated_data['name'], - "service": "ehs" - } - _, res = dhClient.request(**dhapis['dept_create'], json=data) - third_info['dh_id'] = res['id'] - instance.third_info = third_info - instance.save() - elif instance.name != validated_data.get('name', ''): - if settings.DAHUA_ENABLED and instance.third_info.get('dh_id', False): - data = { - "id": instance.third_info['dh_id'], - "parentId": 1, - "name": validated_data['name'] - } - dhClient.request(**dhapis['dept_update'], json=data) - return super().update(instance, validated_data) + ins = super().update(instance, validated_data) + sync_dahua_dept(ins) + return ins class UserSimpleSerializer(CustomModelSerializer): diff --git a/apps/system/services.py b/apps/system/services.py new file mode 100644 index 00000000..88eef832 --- /dev/null +++ b/apps/system/services.py @@ -0,0 +1,27 @@ +from apps.system.models import Dept +from django.conf import settings +from apps.third.tapis import dhapis + + +def sync_dahua_dept(dept: Dept): + # 同步大华部门信息 + from apps.third.clients import dhClient + third_info = dept.third_info + if settings.DAHUA_ENABLED and not third_info.get('dh_id', False): + # 如果dh_id 不存在 + data = { + "parentId": 1, + "name": dept.name, + "service": "ehs" + } + _, res = dhClient.request(**dhapis['dept_create'], json=data) + third_info['dh_id'] = res['id'] + dept.third_info = third_info + dept.save() + elif settings.DAHUA_ENABLED and dept.third_info.get('dh_id', False): + data = { + "id": dept.third_info['dh_id'], + "parentId": 1, + "name": dept.name + } + dhClient.request(**dhapis['dept_update'], json=data) diff --git a/apps/third/views.py b/apps/third/views.py index 5442befa..3bc2db49 100755 --- a/apps/third/views.py +++ b/apps/third/views.py @@ -244,7 +244,8 @@ class DhCommonViewSet(CreateModelMixin, CustomGenericViewSet): 大华事件处理 """ - data = json.loads(request.body) + # data = json.loads(request.body) + data = request.data method = data['method'] category = data['category'] subsystem = data.get('subsystem', None)