mirror of https://github.com/jumpserver/jumpserver
feat: 工单添加序号
parent
25a2290804
commit
5cdc4c3c28
|
@ -0,0 +1,44 @@
|
|||
# Generated by Django 3.1.13 on 2022-01-10 07:37
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
from common.utils.timezone import as_current_tz
|
||||
|
||||
|
||||
def fill_ticket_serial_number(apps, schema_editor):
|
||||
Ticket = apps.get_model('tickets', 'Ticket')
|
||||
tickets = Ticket.objects.all().order_by('date_created')
|
||||
|
||||
curr_day = '00000000'
|
||||
curr_num = 1
|
||||
|
||||
print(f'\nFill ticket serial number ... ', end='')
|
||||
for ticket in tickets:
|
||||
# 跑这个脚本的时候,所有 ticket.serial_num == null
|
||||
date_created = as_current_tz(ticket.date_created)
|
||||
date_str = date_created.strftime('%Y%m%d')
|
||||
if date_str != curr_day:
|
||||
curr_day = date_str
|
||||
curr_num = 1
|
||||
|
||||
ticket.serial_num = curr_day + '%04d' % curr_num
|
||||
curr_num += 1
|
||||
|
||||
Ticket.objects.bulk_update(tickets, fields=('serial_num',))
|
||||
print(len(tickets), end='')
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tickets', '0012_ticketsession'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='serial_num',
|
||||
field=models.CharField(max_length=256, null=True, unique=True, verbose_name='Serial number'),
|
||||
),
|
||||
migrations.RunPython(fill_ticket_serial_number),
|
||||
]
|
|
@ -3,7 +3,11 @@
|
|||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from datetime import timedelta
|
||||
from django.db.utils import IntegrityError
|
||||
|
||||
from common.exceptions import JMSException
|
||||
from common.utils.timezone import as_current_tz
|
||||
from common.mixins.models import CommonModelMixin
|
||||
from common.db.encoder import ModelJSONFieldEncoder
|
||||
from orgs.mixins.models import OrgModelMixin
|
||||
|
@ -73,6 +77,7 @@ class Ticket(CommonModelMixin, OrgModelMixin):
|
|||
'TicketFlow', related_name='tickets', on_delete=models.SET_NULL, null=True,
|
||||
verbose_name=_("TicketFlow")
|
||||
)
|
||||
serial_num = models.CharField(max_length=256, unique=True, null=True, verbose_name=_('Serial number'))
|
||||
|
||||
class Meta:
|
||||
ordering = ('-date_created',)
|
||||
|
@ -245,3 +250,49 @@ class Ticket(CommonModelMixin, OrgModelMixin):
|
|||
def body(self):
|
||||
_body = self.handler.get_body()
|
||||
return _body
|
||||
|
||||
def get_serial_num_date(self):
|
||||
date_created = as_current_tz(self.date_created)
|
||||
date = date_created.strftime('%Y%m%d')
|
||||
return date
|
||||
|
||||
def get_last_serail_num(self):
|
||||
date_created = as_current_tz(self.date_created)
|
||||
date_prefix = date_created.strftime('%Y%m%d')
|
||||
|
||||
ticket = Ticket.objects.select_for_update().filter(
|
||||
serial_num__startswith=date_prefix
|
||||
).order_by('-date_created').first()
|
||||
|
||||
if ticket:
|
||||
# 202212010001
|
||||
num_str = ticket.serial_num[8:]
|
||||
num = int(num_str)
|
||||
return num
|
||||
return None
|
||||
|
||||
def get_next_serail_num(self):
|
||||
num = self.get_last_serail_num()
|
||||
if num is None:
|
||||
num = 0
|
||||
return '%04d' % (num + 1)
|
||||
|
||||
def construct_serial_num(self):
|
||||
date_prefix = self.get_serial_num_date()
|
||||
num_suffix = self.get_next_serail_num()
|
||||
return date_prefix + num_suffix
|
||||
|
||||
def update_serial_num_if_need(self):
|
||||
if self.serial_num:
|
||||
return
|
||||
|
||||
try:
|
||||
self.serial_num = self.construct_serial_num()
|
||||
self.save(update_fields=('serial_num',))
|
||||
except IntegrityError as e:
|
||||
if e.args[0] == 1062:
|
||||
# 虽然做了 `select_for_update` 但是每天的第一条工单仍可能造成冲突
|
||||
# 但概率小,这里只报错,用户重新提交即可
|
||||
raise JMSException(detail=_('Please try again'), code='please_try_again')
|
||||
|
||||
raise e
|
||||
|
|
|
@ -28,7 +28,8 @@ class TicketSerializer(OrgResourceModelSerializerMixin):
|
|||
fields_small = fields_mini + [
|
||||
'type', 'type_display', 'meta', 'state', 'approval_step',
|
||||
'status', 'status_display', 'applicant_display', 'process_map',
|
||||
'date_created', 'date_updated', 'comment', 'org_id', 'org_name', 'body'
|
||||
'date_created', 'date_updated', 'comment', 'org_id', 'org_name', 'body',
|
||||
'serial_num',
|
||||
]
|
||||
fields_fk = ['applicant', ]
|
||||
fields = fields_small + fields_fk
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
from django.dispatch import receiver
|
||||
|
||||
from django.db.models.signals import post_save
|
||||
from common.utils import get_logger
|
||||
from tickets.models import Ticket, ApprovalRule
|
||||
from ..signals import post_change_ticket_action, post_or_update_change_ticket_flow_approval
|
||||
from tickets.models import Ticket
|
||||
from ..signals import post_change_ticket_action
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
@ -12,3 +12,8 @@ logger = get_logger(__name__)
|
|||
@receiver(post_change_ticket_action, sender=Ticket)
|
||||
def on_post_change_ticket_action(sender, ticket, action, **kwargs):
|
||||
ticket.handler.dispatch(action)
|
||||
|
||||
|
||||
@receiver(post_save, sender=Ticket)
|
||||
def on_pre_save_ensure_serial_num(sender, instance: Ticket, **kwargs):
|
||||
instance.update_serial_num_if_need()
|
||||
|
|
Loading…
Reference in New Issue