perf(wf): serialize ticket sn generation by prefix

This commit is contained in:
caoqianming 2026-03-20 10:43:44 +08:00
parent 77616b37d2
commit d21e9907e9
1 changed files with 35 additions and 16 deletions

View File

@ -1,5 +1,6 @@
import importlib
from threading import Thread
from django.core.cache import cache
from apps.utils.sms import send_sms
from apps.wf.serializers import TicketSimpleSerializer
from apps.system.models import Dept, User
@ -102,11 +103,25 @@ class WfService(object):
生成工单流水号
"""
if now is None:
now = datetime.now()
today = str(now)[:10]+' 00:00:00'
ticket_day_count_new = Ticket.objects.get_queryset(all=True).filter(
create_time__gte=today, create_time__lte=now, workflow=workflow).count()
return '%s_%04d%02d%02d%04d' % (workflow.sn_prefix, now.year, now.month, now.day, ticket_day_count_new)
now = timezone.now()
if timezone.is_aware(now):
now = timezone.localtime(now)
day_start = now.replace(hour=0, minute=0, second=0, microsecond=0)
day_end = day_start + timedelta(days=1)
sn_prefix = f"{workflow.sn_prefix}_{now:%Y%m%d}"
latest_sn = Ticket.objects.get_queryset(all=True).filter(
create_time__gte=day_start,
create_time__lt=day_end,
sn__startswith=sn_prefix,
).order_by('-sn').values_list('sn', flat=True).first()
next_seq = 1
if latest_sn:
try:
next_seq = int(latest_sn[-4:]) + 1
except (TypeError, ValueError):
next_seq = 1
return f"{sn_prefix}{next_seq:04d}"
@classmethod
def get_next_state_by_transition_and_ticket_info(cls, ticket: Ticket,
@ -328,17 +343,21 @@ class WfService(object):
save_ticket_data[key] = new_ticket_data[key]
else:
save_ticket_data = new_ticket_data
ticket = Ticket.objects.create(workflow=workflow,
state=start_state,
create_by=handler,
create_time=timezone.now(),
act_state=Ticket.TICKET_ACT_STATE_DRAFT,
belong_dept=handler.belong_dept,
ticket_data=save_ticket_data, participant_type=1, participant=handler.id) # 先创建出来
sn = WfService.get_ticket_sn(ticket.workflow) # 流水号
ticket.sn = sn
ticket.save()
ticket_now = timezone.now()
lock_now = timezone.localtime(ticket_now) if timezone.is_aware(ticket_now) else ticket_now
lock_key = f"ticket_sn:{workflow.sn_prefix}:{lock_now:%Y%m%d}"
with cache.lock(lock_key, timeout=10):
sn = WfService.get_ticket_sn(workflow, now=ticket_now) # 流水号
ticket = Ticket.objects.create(workflow=workflow,
state=start_state,
create_by=handler,
create_time=ticket_now,
act_state=Ticket.TICKET_ACT_STATE_DRAFT,
belong_dept=handler.belong_dept,
ticket_data=save_ticket_data,
participant_type=1,
participant=handler.id,
sn=sn) # 先创建出来
if not transition:
return ticket
just_created = True # 刚创建的工单不需要校验权限