mirror of https://github.com/jumpserver/jumpserver
perf: 工单流对应受理人懒加载
parent
ac9e7e9b40
commit
38c870a0b5
|
@ -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)
|
||||||
|
|
|
@ -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',
|
||||||
|
),
|
||||||
|
]
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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…
Reference in New Issue