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 import models
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.utils.translation import ugettext_lazy as _
|
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.mixins.models import CommonModelMixin
|
||||||
from common.db.encoder import ModelJSONFieldEncoder
|
from common.db.encoder import ModelJSONFieldEncoder
|
||||||
from orgs.mixins.models import OrgModelMixin
|
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,
|
'TicketFlow', related_name='tickets', on_delete=models.SET_NULL, null=True,
|
||||||
verbose_name=_("TicketFlow")
|
verbose_name=_("TicketFlow")
|
||||||
)
|
)
|
||||||
|
serial_num = models.CharField(max_length=256, unique=True, null=True, verbose_name=_('Serial number'))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('-date_created',)
|
ordering = ('-date_created',)
|
||||||
|
@ -245,3 +250,49 @@ class Ticket(CommonModelMixin, OrgModelMixin):
|
||||||
def body(self):
|
def body(self):
|
||||||
_body = self.handler.get_body()
|
_body = self.handler.get_body()
|
||||||
return _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 + [
|
fields_small = fields_mini + [
|
||||||
'type', 'type_display', 'meta', 'state', 'approval_step',
|
'type', 'type_display', 'meta', 'state', 'approval_step',
|
||||||
'status', 'status_display', 'applicant_display', 'process_map',
|
'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_fk = ['applicant', ]
|
||||||
fields = fields_small + fields_fk
|
fields = fields_small + fields_fk
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
from django.db.models.signals import post_save
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from tickets.models import Ticket, ApprovalRule
|
from tickets.models import Ticket
|
||||||
from ..signals import post_change_ticket_action, post_or_update_change_ticket_flow_approval
|
from ..signals import post_change_ticket_action
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
@ -12,3 +12,8 @@ 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_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