Browse Source

perf: 工单流对应受理人懒加载

pull/7430/head
feng626 3 years ago committed by Jiangjie.Bai
parent
commit
38c870a0b5
  1. 1
      apps/tickets/api/ticket.py
  2. 17
      apps/tickets/migrations/0011_remove_approvalrule_assignees_display.py
  3. 26
      apps/tickets/models/flow.py
  4. 11
      apps/tickets/models/ticket.py
  5. 21
      apps/tickets/serializers/ticket/ticket.py
  6. 9
      apps/tickets/signals_handler/ticket.py

1
apps/tickets/api/ticket.py

@ -94,7 +94,6 @@ class TicketFlowViewSet(JMSBulkModelViewSet):
def perform_create_or_update(self, serializer): def perform_create_or_update(self, serializer):
instance = serializer.save() instance = serializer.save()
instance.save() instance.save()
instance.rules.model.change_assignees_display(instance.rules.all())
def perform_create(self, serializer): def perform_create(self, serializer):
self.perform_create_or_update(serializer) self.perform_create_or_update(serializer)

17
apps/tickets/migrations/0011_remove_approvalrule_assignees_display.py

@ -0,0 +1,17 @@
# Generated by Django 3.1.13 on 2021-12-15 09:56
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('tickets', '0010_auto_20210812_1618'),
]
operations = [
migrations.RemoveField(
model_name='approvalrule',
name='assignees_display',
),
]

26
apps/tickets/models/flow.py

@ -3,13 +3,11 @@
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from users.models import User
from common.mixins.models import CommonModelMixin from common.mixins.models import CommonModelMixin
from common.db.encoder import ModelJSONFieldEncoder
from orgs.mixins.models import OrgModelMixin from orgs.mixins.models import OrgModelMixin
from orgs.models import Organization from orgs.utils import tmp_to_root_org, tmp_to_org, get_current_org_id
from orgs.utils import tmp_to_root_org, tmp_to_org
from ..const import TicketType, TicketApprovalLevel, TicketApprovalStrategy from ..const import TicketType, TicketApprovalLevel, TicketApprovalStrategy
from ..signals import post_or_update_change_ticket_flow_approval
__all__ = ['TicketFlow', 'ApprovalRule'] __all__ = ['TicketFlow', 'ApprovalRule']
@ -29,10 +27,6 @@ class ApprovalRule(CommonModelMixin):
'users.User', related_name='assigned_ticket_flow_approval_rule', 'users.User', related_name='assigned_ticket_flow_approval_rule',
verbose_name=_("Assignees") verbose_name=_("Assignees")
) )
assignees_display = models.JSONField(
encoder=ModelJSONFieldEncoder, default=list,
verbose_name=_('Assignees display')
)
class Meta: class Meta:
verbose_name = _('Ticket flow approval rule') verbose_name = _('Ticket flow approval rule')
@ -40,9 +34,19 @@ class ApprovalRule(CommonModelMixin):
def __str__(self): def __str__(self):
return '{}({})'.format(self.id, self.level) return '{}({})'.format(self.id, self.level)
@classmethod def get_assignees(self, org_id=None):
def change_assignees_display(cls, qs): assignees = []
post_or_update_change_ticket_flow_approval.send(sender=cls, qs=qs) org_id = org_id if org_id else get_current_org_id()
with tmp_to_org(org_id):
if self.strategy == TicketApprovalStrategy.super_admin:
assignees = User.get_super_admins()
elif self.strategy == TicketApprovalStrategy.org_admin:
assignees = User.get_org_admins()
elif self.strategy == TicketApprovalStrategy.super_org_admin:
assignees = User.get_super_and_org_admins()
elif self.strategy == TicketApprovalStrategy.custom_user:
assignees = self.assignees.all()
return assignees
class TicketFlow(CommonModelMixin, OrgModelMixin): class TicketFlow(CommonModelMixin, OrgModelMixin):

11
apps/tickets/models/ticket.py

@ -140,24 +140,29 @@ class Ticket(CommonModelMixin, OrgModelMixin):
self.status = TicketStatus.closed self.status = TicketStatus.closed
def create_related_node(self): def create_related_node(self):
org_id = self.flow.org_id
approval_rule = self.get_current_ticket_flow_approve() approval_rule = self.get_current_ticket_flow_approve()
ticket_step = TicketStep.objects.create(ticket=self, level=self.approval_step) ticket_step = TicketStep.objects.create(ticket=self, level=self.approval_step)
ticket_assignees = [] ticket_assignees = []
assignees = approval_rule.assignees.all() assignees = approval_rule.get_assignees(org_id=org_id)
for assignee in assignees: for assignee in assignees:
ticket_assignees.append(TicketAssignee(step=ticket_step, assignee=assignee)) ticket_assignees.append(TicketAssignee(step=ticket_step, assignee=assignee))
TicketAssignee.objects.bulk_create(ticket_assignees) TicketAssignee.objects.bulk_create(ticket_assignees)
def create_process_map(self): def create_process_map(self):
org_id = self.flow.org_id
approval_rules = self.flow.rules.order_by('level') approval_rules = self.flow.rules.order_by('level')
nodes = list() nodes = list()
for node in approval_rules: for node in approval_rules:
assignees = node.get_assignees(org_id=org_id)
assignee_ids = [assignee.id for assignee in assignees]
assignees_display = [str(assignee) for assignee in assignees]
nodes.append( nodes.append(
{ {
'approval_level': node.level, 'approval_level': node.level,
'state': ProcessStatus.notified, 'state': ProcessStatus.notified,
'assignees': [i for i in node.assignees.values_list('id', flat=True)], 'assignees': assignee_ids,
'assignees_display': node.assignees_display 'assignees_display': assignees_display
} }
) )
return nodes return nodes

21
apps/tickets/serializers/ticket/ticket.py

@ -8,7 +8,6 @@ from orgs.mixins.serializers import OrgResourceModelSerializerMixin
from perms.models import AssetPermission from perms.models import AssetPermission
from orgs.models import Organization from orgs.models import Organization
from orgs.utils import tmp_to_org from orgs.utils import tmp_to_org
from users.models import User
from tickets.models import Ticket, TicketFlow, ApprovalRule from tickets.models import Ticket, TicketFlow, ApprovalRule
from tickets.const import TicketApprovalStrategy from tickets.const import TicketApprovalStrategy
from .meta import type_serializer_classes_mapping from .meta import type_serializer_classes_mapping
@ -139,7 +138,8 @@ class TicketApproveSerializer(TicketSerializer):
class TicketFlowApproveSerializer(serializers.ModelSerializer): class TicketFlowApproveSerializer(serializers.ModelSerializer):
strategy_display = serializers.ReadOnlyField(source='get_strategy_display', label=_('Approve strategy')) strategy_display = serializers.ReadOnlyField(source='get_strategy_display', label=_('Approve strategy'))
assignees_read_only = serializers.SerializerMethodField(label=_("Assignees")) assignees_read_only = serializers.SerializerMethodField(label=_('Assignees'))
assignees_display = serializers.SerializerMethodField(label=_('Assignees display'))
class Meta: class Meta:
model = ApprovalRule model = ApprovalRule
@ -153,6 +153,9 @@ class TicketFlowApproveSerializer(serializers.ModelSerializer):
'assignees': {'write_only': True, 'allow_empty': True, 'required': False} 'assignees': {'write_only': True, 'allow_empty': True, 'required': False}
} }
def get_assignees_display(self, obj):
return [str(assignee) for assignee in obj.get_assignees()]
def get_assignees_read_only(self, obj): def get_assignees_read_only(self, obj):
if obj.strategy == TicketApprovalStrategy.custom_user: if obj.strategy == TicketApprovalStrategy.custom_user:
return obj.assignees.values_list('id', flat=True) return obj.assignees.values_list('id', flat=True)
@ -190,7 +193,9 @@ class TicketFlowSerializer(OrgResourceModelSerializerMixin):
raise serializers.ValidationError(error) raise serializers.ValidationError(error)
return value return value
def create_or_update(self, action, validated_data, related, assignees, instance=None): def create_or_update(self, action, validated_data, instance=None):
related = 'rules'
assignees = 'assignees'
childs = validated_data.pop(related, []) childs = validated_data.pop(related, [])
if not instance: if not instance:
instance = getattr(super(), action)(validated_data) instance = getattr(super(), action)(validated_data)
@ -203,12 +208,6 @@ class TicketFlowSerializer(OrgResourceModelSerializerMixin):
for level, data in enumerate(childs, 1): for level, data in enumerate(childs, 1):
data_m2m = data.pop(assignees, None) data_m2m = data.pop(assignees, None)
child_instance = related_model.objects.create(**data, level=level) child_instance = related_model.objects.create(**data, level=level)
if child_instance.strategy == TicketApprovalStrategy.super_admin:
data_m2m = list(User.get_super_admins())
elif child_instance.strategy == TicketApprovalStrategy.org_admin:
data_m2m = list(User.get_org_admins())
elif child_instance.strategy == TicketApprovalStrategy.super_org_admin:
data_m2m = list(User.get_super_and_org_admins())
getattr(child_instance, assignees).set(data_m2m) getattr(child_instance, assignees).set(data_m2m)
child_instances.append(child_instance) child_instances.append(child_instance)
instance_related.set(child_instances) instance_related.set(child_instances)
@ -216,12 +215,12 @@ class TicketFlowSerializer(OrgResourceModelSerializerMixin):
@atomic @atomic
def create(self, validated_data): def create(self, validated_data):
return self.create_or_update('create', validated_data, 'rules', 'assignees') return self.create_or_update('create', validated_data)
@atomic @atomic
def update(self, instance, validated_data): def update(self, instance, validated_data):
if instance.org_id == Organization.ROOT_ID: if instance.org_id == Organization.ROOT_ID:
instance = self.create(validated_data) instance = self.create(validated_data)
else: else:
instance = self.create_or_update('update', validated_data, 'rules', 'assignees', instance) instance = self.create_or_update('update', validated_data, instance)
return instance return instance

9
apps/tickets/signals_handler/ticket.py

@ -12,12 +12,3 @@ logger = get_logger(__name__)
@receiver(post_change_ticket_action, sender=Ticket) @receiver(post_change_ticket_action, sender=Ticket)
def on_post_change_ticket_action(sender, ticket, action, **kwargs): def on_post_change_ticket_action(sender, ticket, action, **kwargs):
ticket.handler.dispatch(action) ticket.handler.dispatch(action)
@receiver(post_or_update_change_ticket_flow_approval, sender=ApprovalRule)
def post_or_update_change_ticket_flow_approval(sender, qs, **kwargs):
updates = []
for instance in qs:
instance.assignees_display = [str(assignee) for assignee in instance.assignees.all()]
updates.append(instance)
sender.objects.bulk_update(updates, ['assignees_display', ])

Loading…
Cancel
Save