diff --git a/apps/develop/tasks.py b/apps/develop/tasks.py index 6ae73aa1..51c8c224 100755 --- a/apps/develop/tasks.py +++ b/apps/develop/tasks.py @@ -26,15 +26,16 @@ def backup_database(): def reload_server_git(): command = 'bash {}/git_server.sh'.format(SH_PATH) completed = subprocess.run(command, shell=True, capture_output=True, text=True) - return completed + if completed.returncode != 0: + return completed.stderr @shared_task def reload_web_git(): command = 'bash {}/git_web.sh'.format(SH_PATH) completed = subprocess.run(command, shell=True, capture_output=True, text=True) - return completed - + if completed.returncode != 0: + return completed.stderr @shared_task def reload_server_only(): diff --git a/apps/ecm/tasks.py b/apps/ecm/tasks.py index 0cf00cdf..66c60771 100644 --- a/apps/ecm/tasks.py +++ b/apps/ecm/tasks.py @@ -1,4 +1,5 @@ from __future__ import absolute_import, unicode_literals +from multiprocessing import Event from threading import Thread from celery import shared_task @@ -7,8 +8,10 @@ from apps.am.models import Area from apps.third.clients import xxClient from apps.third.models import TDevice from apps.third.tapis import xxapis +from django.utils import timezone +@shared_task def update_count_people(i: Area): if i.third_info.get('xx_rail', None): railId = i.third_info['xx_rail']['id'] @@ -35,4 +38,15 @@ def cal_area_count(): 计算区域内人员数量 """ for i in Area.objects.filter(type=Area.AREA_TYPE_FIX): - Thread(target=update_count_people, args=(i,)).start() + Thread(target=update_count_people, args=(i,), daemon=True).start() + + +@shared_task +def check_event_timeout(): + """判断事件处理是否超期 + """ + for i in Event.objects.filter(handle_user=None, is_timeout=False): + cate = i.cates.all().order_by('priority', 'create_time').first() + if cate.hanle_minute > 0 and (timezone.now()-i.create_time).seconds > cate.hanle_minute * 60: + i.is_timeout = True + i.save() \ No newline at end of file diff --git a/apps/opm/serializers.py b/apps/opm/serializers.py index e3f870ce..8c0cf46e 100644 --- a/apps/opm/serializers.py +++ b/apps/opm/serializers.py @@ -1,11 +1,15 @@ from apps.hrm.models import Certificate from apps.opm.models import GasCheck, Operation, Opl, OplCate, OplCert, OplWorker -from apps.system.serializers import DictSerializer, DictSimpleSerializer, UserSimpleSerializer +from apps.system.models import Dictionary +from apps.system.serializers import DeptSimpleSerializer, DictSerializer, DictSimpleSerializer, UserSimpleSerializer from apps.utils.serializers import CustomModelSerializer from apps.utils.constants import EXCLUDE_FIELDS from rest_framework import serializers from django.db import transaction from rest_framework.exceptions import ParseError +from apps.am.serializers import AreaSimpleSerializer +from apps.wf.serializers import TicketSerializer +from apps.system.serializers import FileSerializer class OplCateCreateUpdateSerializer(CustomModelSerializer): @@ -20,6 +24,7 @@ class OplCateSerializer(CustomModelSerializer): model = OplCate fields = '__all__' + class OplCateSimpleSerializer(CustomModelSerializer): class Meta: model = OplCate @@ -48,6 +53,18 @@ class OperationSerializer(CustomModelSerializer): fields = "__all__" +class OperationDetailSerializer(CustomModelSerializer): + area_ = AreaSimpleSerializer(source='area', read_only=True) + dept_ter_ = DeptSimpleSerializer(source='dept_ter', read_only=True) + dept_bus_ = DeptSimpleSerializer(source='dept_bus', read_only=True) + coordinator_ = UserSimpleSerializer(source='coordinator', read_only=True) + create_by_ = UserSimpleSerializer(source='create_by', read_only=True) + + class Meta: + model = Operation + fields = "__all__" + + class OplWorkerCreateSerializer(CustomModelSerializer): certificates = serializers.PrimaryKeyRelatedField(label='证书ID', many=True, queryset=Certificate.objects.all()) @@ -166,6 +183,47 @@ class OplSerializer(CustomModelSerializer): fields = '__all__' +class OplListSerializer(CustomModelSerializer): + cate_name = serializers.CharField(source='cate.name', read_only=True) + cate_ = OplCateSimpleSerializer(source='cate', read_only=True) + dept_do_ = DeptSimpleSerializer(source='dept_do', read_only=True) + charger_ = UserSimpleSerializer(source='charger', read_only=True) + monitor_ = UserSimpleSerializer(source='monitor', read_only=True) + ticket_ = TicketSerializer(source='ticket', read_only=True) + + class Meta: + model = Opl + fields = '__all__' + + +class OplDetailSerializer(CustomModelSerializer): + operation_ = OperationDetailSerializer(source='operation', read_only=True) + dept_do_ = DeptSimpleSerializer(source='dept_do', read_only=True) + charger_ = UserSimpleSerializer(source='charger', read_only=True) + monitor_ = UserSimpleSerializer(source='monitor', read_only=True) + ticket_ = TicketSerializer(source='ticket', read_only=True) + risks_checked_ = serializers.SerializerMethodField() + measures_checked_ = serializers.SerializerMethodField() + close_dos_ = serializers.SerializerMethodField() + create_imgs_ = FileSerializer(source='create_imgs', many=True) + close_imgs_ = FileSerializer(source='close_imgs', many=True) + + class Meta: + model = Opl + fields = '__all__' + + def get_risks_checked_(self, obj): + qs = Dictionary.objects.filter(id__in=obj.risks_checked).values('id', 'name') + return list(qs) + + def get_measures_checked_(self, obj): + qs = Dictionary.objects.filter(id__in=obj.measures_checked).values('id', 'name') + return list(qs) + + def get_close_dos_(self, obj): + qs = Dictionary.objects.filter(id__in=obj.close_dos).values('id', 'name') + return list(qs) + class OplCloseSerializer(CustomModelSerializer): class Meta: diff --git a/apps/opm/views.py b/apps/opm/views.py index 4de7a7b0..b5372778 100644 --- a/apps/opm/views.py +++ b/apps/opm/views.py @@ -1,7 +1,7 @@ from django.shortcuts import render from rest_framework.response import Response from apps.opm.models import GasCheck, Operation, Opl, OplCate, OplWorker -from apps.opm.serializers import GasCheckCreateUpdateSerializer, GasCheckSerializer, OperationCreateUpdateSerializer, OperationSerializer, OplCateCreateUpdateSerializer, OplCateDetailSerializer, OplCateSerializer, OplCreateUpdateSerializer, OplSerializer, OplWorkerCreateSerializer, OplWorkerSerializer, OplWorkerUpdateSerializer +from apps.opm.serializers import GasCheckCreateUpdateSerializer, GasCheckSerializer, OperationCreateUpdateSerializer, OperationDetailSerializer, OperationSerializer, OplCateCreateUpdateSerializer, OplCateDetailSerializer, OplCateSerializer, OplCreateUpdateSerializer, OplDetailSerializer, OplListSerializer, OplSerializer, OplWorkerCreateSerializer, OplWorkerSerializer, OplWorkerUpdateSerializer from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet from rest_framework.exceptions import ParseError from rest_framework.mixins import CreateModelMixin, ListModelMixin, DestroyModelMixin @@ -9,6 +9,8 @@ from rest_framework.decorators import action from rest_framework import serializers from django.db import transaction +from apps.wf.models import State, Ticket + # Create your views here. class OplCateViewSet(CustomModelViewSet): queryset = OplCate.objects.all() @@ -23,8 +25,10 @@ class OperationViewSet(CustomModelViewSet): queryset = Operation.objects.all() create_serializer_class = OperationCreateUpdateSerializer update_serializer_class = OperationCreateUpdateSerializer - serializer_class = OperationSerializer - filterset_fields = ['state', 'opl_operation__cate'] + serializer_class = OperationDetailSerializer + retrieve_serializer_class = OperationDetailSerializer + select_related_fields = ['area', 'dept_bus', 'dept_ter', 'coordinator'] + filterset_fields = ['state', 'opl_operation__cate', 'area'] def update(self, request, *args, **kwargs): obj = self.get_object() @@ -44,19 +48,20 @@ class OplViewSet(CustomModelViewSet): queryset = Opl.objects.all() create_serializer_class = OplCreateUpdateSerializer update_serializer_class = OplCreateUpdateSerializer - serializer_class = OplSerializer - select_related_fields = ['cate'] + serializer_class = OplListSerializer + retrieve_serializer_class = OplDetailSerializer + select_related_fields = ['cate', 'operation', 'dept_do', 'charger', 'monitor', 'ticket'] filterset_fields = ['operation', 'cate'] def destroy(self, request, *args, **kwargs): obj = self.get_object() - if obj.ticket: + if obj.ticket and obj.ticket.act_state != Ticket.TICKET_ACT_STATE_DRAFT: raise ParseError('许可证已处理不可删除') return super().destroy(request, *args, **kwargs) def update(self, request, *args, **kwargs): obj = self.get_object() - if obj.ticket: + if obj.ticket and obj.ticket.act_state != Ticket.TICKET_ACT_STATE_DRAFT: raise ParseError('许可证已处理不可编辑') return super().update(request, *args, **kwargs) diff --git a/apps/rpm/serializers.py b/apps/rpm/serializers.py index f4ebf41e..349506fb 100644 --- a/apps/rpm/serializers.py +++ b/apps/rpm/serializers.py @@ -12,6 +12,7 @@ from rest_framework.exceptions import ParseError from django.db import transaction from apps.third.clients import dhClient from apps.third.tapis import dhapis +from apps.wf.serializers import TicketSimpleSerializer class RpartyCreateUpdateSerializer(CustomModelSerializer): @@ -78,6 +79,8 @@ class RpjCreateUpdateSerializer(CustomModelSerializer): class RpjListSerializer(CustomModelSerializer): rparty_name = serializers.CharField(source='rparty.name', read_only=True) belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True) + create_by_name = serializers.CharField(source='create_by.name', read_only=True) + ticket_ = TicketSimpleSerializer(source='ticket', read_only=True) class Meta: model = Rpj diff --git a/apps/rpm/views.py b/apps/rpm/views.py index 6ac6ec59..06169670 100644 --- a/apps/rpm/views.py +++ b/apps/rpm/views.py @@ -110,7 +110,7 @@ class RpjViewSet(CustomModelViewSet): create_serializer_class = RpjCreateUpdateSerializer update_serializer_class = RpjCreateUpdateSerializer serializer_class = RpjListSerializer - select_related_fields = ['rparty', 'belong_dept'] + select_related_fields = ['rparty', 'belong_dept', 'ticket', 'ticket__state'] filterset_fields = ['rparty', 'belong_dept', 'state'] def get_queryset(self): diff --git a/apps/wf/migrations/0006_state_key.py b/apps/wf/migrations/0006_state_key.py new file mode 100644 index 00000000..07654e8d --- /dev/null +++ b/apps/wf/migrations/0006_state_key.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2022-07-22 08:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wf', '0005_alter_state_filter_dept'), + ] + + operations = [ + migrations.AddField( + model_name='state', + name='key', + field=models.CharField(blank=True, max_length=20, null=True, verbose_name='状态标识'), + ), + ] diff --git a/apps/wf/models.py b/apps/wf/models.py index b8280889..5dc9c21f 100755 --- a/apps/wf/models.py +++ b/apps/wf/models.py @@ -86,6 +86,7 @@ class State(CommonAModel): (3, '和上步处理人同属一及上级部门'), ) name = models.CharField('名称', max_length=50) + key = models.CharField('状态标识', max_length=20, null=True, blank=True) workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='所属工作流') is_hidden = models.BooleanField('是否隐藏', default=False, help_text='设置为True时,获取工单步骤api中不显示此状态(当前处于此状态时除外)') sort = models.IntegerField('状态顺序', default=0, help_text='用于工单步骤接口时,step上状态的顺序(因为存在网状情况,所以需要人为设定顺序),值越小越靠前') diff --git a/apps/wf/serializers.py b/apps/wf/serializers.py index f36cf1ba..dc55b622 100755 --- a/apps/wf/serializers.py +++ b/apps/wf/serializers.py @@ -27,7 +27,7 @@ class WorkflowSimpleSerializer(CustomModelSerializer): class StateSimpleSerializer(CustomModelSerializer): class Meta: model = State - fields = ['id', 'name', 'type', 'distribute_type', 'enable_retreat', 'enable_deliver'] + fields = ['id', 'name', 'type', 'distribute_type', 'enable_retreat', 'enable_deliver', 'key'] class TransitionSerializer(CustomModelSerializer): @@ -76,6 +76,8 @@ class CustomFieldCreateUpdateSerializer(CustomModelSerializer): class TicketSimpleSerializer(CustomModelSerializer): + state_ = StateSimpleSerializer(source='state', read_only=True) + class Meta: model = Ticket fields = '__all__'