You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
8.2 KiB
191 lines
8.2 KiB
from tortoise import fields, models
|
|
from tortoise.indexes import Index
|
|
from tortoise.contrib.pydantic import pydantic_model_creator, pydantic_queryset_creator
|
|
from tortoise.signals import post_save
|
|
from typing import Type
|
|
from helper.tools import genRandomStr
|
|
# from conf.setting import setting
|
|
|
|
# 最小可执行子任务
|
|
class Subtask(models.Model):
|
|
id = fields.UUIDField(pk=True)
|
|
num = fields.CharField(null=True, max_length=255, description='短编号')
|
|
orderid = fields.CharField(null=True, max_length=255, description='中控系统订单编号')
|
|
owner = fields.ForeignKeyField('models.User', on_delete=fields.CASCADE, null=True, description='订单所有人')
|
|
sequence = fields.IntField(default=0, description='管理员手动排序号')
|
|
#取预约领用的动作类型属于现场领用
|
|
action = fields.IntField(default=0, description='1: 归还, 3: 预约领用, 5: 现场领用')
|
|
ordertime = fields.DatetimeField(null=True, description='预约领用时间')
|
|
|
|
name = fields.CharField(null=True, max_length=255, description='试剂名称')
|
|
#取预约领用的任务类型属于非标标准品
|
|
typetask = fields.IntField(default=1, description='1: 标准品A, 3: 标准品B, 5: 标准品C, 7: 标准品D, 9:非标准品')
|
|
quantity = fields.IntField(default=0, description='试剂数量')
|
|
|
|
#坐标格式: 停靠点 - 层坐标 (最底下为第一层) - 试剂在托盘内的编号
|
|
coordinates = fields.CharField(null=True, max_length=255, description='试剂坐标')
|
|
traynum = fields.CharField(null=True, max_length=255, description='托盘编号')
|
|
|
|
is_canceled = fields.BooleanField(default=False, description='是否取消')
|
|
cancel_time = fields.DatetimeField(null=True, description='取消时间')
|
|
|
|
is_done = fields.BooleanField(default=False, description='是否完成')
|
|
|
|
created_at = fields.DatetimeField(auto_now_add=True)
|
|
updated_at = fields.DatetimeField(auto_now=True)
|
|
is_valid = fields.BooleanField(default=True, description='是否有效')
|
|
is_active = fields.BooleanField(default=True, description='是否删除')
|
|
|
|
|
|
class PydanticMeta:
|
|
# Let's exclude the created timestamp
|
|
exclude = ("created_at",)
|
|
|
|
class Meta:
|
|
table = 'Subtasks'
|
|
table_description = '子任务表'
|
|
#set the ordering where sequence > action > ordertime > typetask
|
|
#when passing to order_by function
|
|
ordering = ["-sequence", "-action", "ordertime"]
|
|
|
|
indexes = [
|
|
Index(fields={"num"}, name="numidx"),
|
|
Index(fields={"orderid"}, name="orderididx"),
|
|
Index(fields={"ordertime"}, name="subtask_ordertimeidx"),
|
|
Index(fields={"is_canceled"}, name="subtask_is_canceledidx"),
|
|
Index(fields={"is_done"}, name="subtask_is_doneidx"),
|
|
Index(fields={"coordinates"}, name="subtask_coordinatesidx"),
|
|
Index(fields={"traynum"}, name="subtask_traynumidx"),
|
|
Index(fields={"is_valid"}, name="is_valididx"),
|
|
Index(fields={"is_active"}, name="is_activeidx"),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f'Subtask(id={self.id} num={self.num}, name={self.name}, quantity={self.quantity}, action={self.action}, typetask={self.typetask}, created_at={self.created_at})'
|
|
|
|
def as_json(self):
|
|
return dict(id="{}".format(self.id), num=self.num, name=self.name, quantity=self.quantity, action=self.action, typetask=self.typetask, created_at="{}".format(self.created_at))
|
|
|
|
|
|
Subtask_Pydantic = pydantic_model_creator(Subtask, name="Subtask")
|
|
Subtask_Pydantic_List = pydantic_queryset_creator(Subtask)
|
|
|
|
@post_save(Subtask)
|
|
async def subtask_post_save(
|
|
sender: "Type[Subtask]",
|
|
instance: Subtask,
|
|
created,
|
|
using_db,
|
|
update_fields,
|
|
) -> None:
|
|
|
|
if not instance.num or "null" == instance.num:
|
|
# print("instance.num: ", instance.num)
|
|
# check duplicated num
|
|
async def checkNum():
|
|
num = genRandomStr(4)
|
|
# print("new num: ", num)
|
|
if await Subtask.filter(num = num).exists():
|
|
# print("num exist, ", num)
|
|
checkNum()
|
|
else:
|
|
# print("num not exist, ", num)
|
|
instance.num = num
|
|
await instance.save()
|
|
|
|
await checkNum()
|
|
|
|
|
|
|
|
# 执行任务
|
|
class Task(models.Model):
|
|
id = fields.UUIDField(pk=True)
|
|
num = fields.CharField(null=True, max_length=255, description='短编号')
|
|
orderid = fields.CharField(null=True, max_length=255, description='中控系统订单编号')
|
|
owner = fields.ForeignKeyField('models.User', on_delete=fields.CASCADE, null=True, description='订单所有人')
|
|
sequence = fields.IntField(default=0, description='管理员手动排序号')
|
|
#取预约领用的动作类型属于现场领用
|
|
action = fields.IntField(default=0, description='1: 归还, 3: 预约领用, 5: 现场领用')
|
|
ordertime = fields.DatetimeField(null=True, description='预约领用时间')
|
|
|
|
name = fields.CharField(null=True, max_length=255, description='试剂名称')
|
|
#取预约领用的任务类型属于非标标准品
|
|
typetask = fields.IntField(default=1, description='1: 标准品A, 3: 标准品B, 5: 标准品C, 7: 标准品D, 9:非准品')
|
|
quantity = fields.IntField(default=0, description='试剂数量')
|
|
|
|
#坐标格式: 停靠点 - 层坐标 (最底下为第一层) - 试剂在托盘内的编号
|
|
coordinates = fields.CharField(null=True, max_length=255, description='试剂坐标')
|
|
traynum = fields.CharField(null=True, max_length=255, description='托盘编号')
|
|
|
|
subtasks = fields.ManyToManyField('models.Subtask', related_name='tasksubtasks')
|
|
|
|
is_canceled = fields.BooleanField(default=False, description='是否取消')
|
|
cancel_time = fields.DatetimeField(null=True, description='取消时间')
|
|
|
|
is_done = fields.BooleanField(default=False, description='是否完成')
|
|
|
|
created_at = fields.DatetimeField(auto_now_add=True)
|
|
updated_at = fields.DatetimeField(auto_now=True)
|
|
is_valid = fields.BooleanField(default=True, description='是否有效')
|
|
is_active = fields.BooleanField(default=True, description='是否删除')
|
|
|
|
class PydanticMeta:
|
|
# Let's exclude the created timestamp
|
|
exclude = ("created_at",)
|
|
allow_cycles = True
|
|
max_recursion = 4
|
|
|
|
class Meta:
|
|
table = 'Tasks'
|
|
table_description = '任务表'
|
|
#set the ordering where sequence > action > ordertime > typetask
|
|
#when passing to order_by function
|
|
ordering = ["-sequence", "-action", "ordertime"]
|
|
|
|
indexes = [
|
|
Index(fields={"num"}, name="numidx"),
|
|
Index(fields={"orderid"}, name="orderididx"),
|
|
Index(fields={"ordertime"}, name="task_ordertimeidx"),
|
|
Index(fields={"is_canceled"}, name="task_is_canceledidx"),
|
|
Index(fields={"is_done"}, name="task_is_doneidx"),
|
|
Index(fields={"coordinates"}, name="task_coordinatesidx"),
|
|
Index(fields={"traynum"}, name="task_traynumidx"),
|
|
Index(fields={"is_valid"}, name="is_valididx"),
|
|
Index(fields={"is_active"}, name="is_activeidx"),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f'Task(id={self.id} num={self.num}, name={self.name}, quantity={self.quantity}, action={self.action}, typetask={self.typetask}, created_at={self.created_at})'
|
|
|
|
def as_json(self):
|
|
return dict(id="{}".format(self.id), num=self.num, name=self.name, quantity=self.quantity, action=self.action, typetask=self.typetask, created_at="{}".format(self.created_at))
|
|
|
|
Task_Pydantic = pydantic_model_creator(Task, name="Task")
|
|
Task_Pydantic_List = pydantic_queryset_creator(Task)
|
|
|
|
@post_save(Task)
|
|
async def task_post_save(
|
|
sender: "Type[Task]",
|
|
instance: Task,
|
|
created,
|
|
using_db,
|
|
update_fields,
|
|
) -> None:
|
|
|
|
if not instance.num or "null" == instance.num:
|
|
# print("instance.num: ", instance.num)
|
|
# check duplicated num
|
|
async def checkNum():
|
|
num = genRandomStr(4)
|
|
# print("new num: ", num)
|
|
if await Task.filter(num = num).exists():
|
|
# print("num exist, ", num)
|
|
checkNum()
|
|
else:
|
|
# print("num not exist, ", num)
|
|
instance.num = num
|
|
await instance.save()
|
|
|
|
await checkNum()
|
|
|