from django.db import models from container.models import ContainerListModel,ContainerWCSModel,TaskModel # 库位主表(记录实时状态) class LocationModel(models.Model): LOCATION_TYPES = ( ('T5', '5货位'), # 5托盘/批次 ('T4', '4货位'), # 4托盘/批次 ('S4', '4单货位'), # 4单托盘 ('T2', '2货位'), # 2托盘/批次 ('T1', '散货位'), # 1托盘 ('M1', '通道区'), # 通道区 ('E1', '提升机'), # 提升机 ('C1', '输送机'), # 输送机 ('B1', '充电桩'), # 货架区 ) LOCATION_STATUS = ( ('available', '可用'), ('occupied', '占用'), ('disabled', '禁用'), ('reserved', '预留'), ('maintenance', '维护中'), ) warehouse_code = models.CharField(max_length=255, verbose_name="Warehouse code") warehouse_name = models.CharField(max_length=255, verbose_name="Warehouse Name") shelf_type = models.CharField(max_length=255,default = 'storage', verbose_name="Shelf Type") row = models.IntegerField(verbose_name="Row") # 位置的行号 col = models.IntegerField(verbose_name="Column") # 位置的列号 layer = models.IntegerField(verbose_name="Layer") # 位置的层号 update_time = models.DateTimeField(auto_now=True, blank=True, null=True, verbose_name="Update Time") empty_label = models.BooleanField(default=True, verbose_name="Empty Flag") location_code = models.CharField(max_length=20, unique=True, verbose_name='库位编码') location_group = models.CharField(max_length=20, verbose_name='库位组') # 示例:T1-L1C001-1 # T1-L1C001-1 代表货位类型为T1,层号为1,列号为001,货位号为1 location_type = models.CharField(max_length=3, choices=LOCATION_TYPES, verbose_name='货位类型') status = models.CharField(max_length=20, choices=LOCATION_STATUS, default='available', verbose_name='库位状态') max_capacity = models.PositiveIntegerField(verbose_name='最大容量') # 根据类型自动设置 current_quantity = models.PositiveIntegerField(default=0, verbose_name='当前数') c_number = models.IntegerField(default=1, verbose_name='库位远近排序') current_containers = models.ManyToManyField(ContainerListModel, through='LocationContainerLink', verbose_name='当前存放托盘') coordinate = models.CharField(max_length=50, verbose_name='三维坐标') # 格式:行-列-层 access_priority = models.IntegerField( default=0, verbose_name='访问优先级', help_text='值越大表示越远离主通道,应优先使用' ) is_active = models.BooleanField(default=True, verbose_name='是否有效') class Meta: db_table = 'location' verbose_name = 'Location' verbose_name_plural = "Location" ordering = ['-id'] unique_together = ( 'warehouse_code','row', 'col', 'layer') # 防止重复坐标 @classmethod def get_existing_positions(cls, warehouse_code, rows, cols, layers): """获取已存在的坐标集合""" return set( cls.objects.filter( warehouse_code=warehouse_code, row__lte=rows, col__lte=cols, layer__lte=layers ).values_list('row', 'col', 'layer') ) def get_active_containers(self): """获取当前有效的托盘列表""" from .models import LocationContainerLink active_links = LocationContainerLink.objects.filter( location=self, is_active=True ).select_related('container') # 优化查询 return [link.container for link in active_links] # 返回托盘列表 @classmethod def generate_locations(cls, warehouse_code): # 清空现有数据(新增部分) cls.objects.filter(warehouse_code=warehouse_code).delete() """根据规划图生成库位""" # 定义核心参数(根据规划图调整) MAIN_AISLES = [18, 1] # 子通道列号 SUB_AISLES = [2,8, 13] # 主通道行号 for row in range(1, 14): # 1-13行 for col in range(1, 3): # 1-19列 for layer in range(1, 4): # 1-3层 # 判断通道区 if col in MAIN_AISLES or row in SUB_AISLES: loc_type = 'M1' c_number = row # 通道 if col ==1 and row == 1: loc_type = 'T1' c_number = 1 # 判断货位类型(根据实际规划) else: if row <2: loc_type = 'T1' c_number = 1 elif row < 8: loc_type = 'T5' c_number = row-2 elif row < 13: loc_type = 'T4' c_number = row-8 else: loc_type = 'T2' c_number = 16-row # 生成唯一编码 location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}" location_group = f"{loc_type}-L{layer}C{col:03d}" # print(f"生成库位:{location_code}-{row}-{col}-{layer}") # 创建库位 cls.objects.update_or_create( warehouse_code=warehouse_code, warehouse_name="立体仓库", row=row, col=col, layer=layer, c_number=c_number, shelf_type=loc_type, defaults={ 'location_code': location_code, 'location_group': location_group, 'location_type': loc_type, 'max_capacity': { 'T5': 5, 'T4': 4, 'T2': 2, 'T1': 1, 'M1': 0, 'E1': 0, 'C1': 0 }[loc_type], 'coordinate': f"{row}-{col}-{layer}", 'is_active': True }, access_priority=c_number ) for row in range(1, 16): # 1-15行 for col in range(3, 17): # 1-16列 for layer in range(1, 4): # 1-3层 # 判断通道区 if col in MAIN_AISLES or row in SUB_AISLES: loc_type = 'M1' c_number = row # 通道 if col ==18 and row == 1: loc_type = 'T1' c_number = 1 # 判断货位类型(根据实际规划) else: if row <2: loc_type = 'T1' c_number = 1 elif row < 8: loc_type = 'T5' c_number = row-2 elif row < 13: loc_type = 'T4' c_number = row-8 else: loc_type = 'T2' c_number = 16-row # 生成唯一编码 location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}" location_group = f"{loc_type}-L{layer}C{col:03d}" # print(f"生成库位:{location_code}-{row}-{col}-{layer}") # 创建库位 cls.objects.update_or_create( warehouse_code=warehouse_code, row=row, col=col, layer=layer, c_number=c_number, shelf_type=loc_type, defaults={ 'location_code': location_code, 'location_group': location_group, 'location_type': loc_type, 'max_capacity': { 'T5': 5, 'T4': 4, 'T2': 2, 'T1': 1, 'M1': 0, 'E1': 0, 'C1': 0 }[loc_type], 'coordinate': f"{row}-{col}-{layer}", 'is_active': True }, access_priority=c_number ) # print("✅ 库位生成成功!") for row in range(1, 14): # 1-15行 for col in range(17, 20): # 1-16列 for layer in range(1, 4): # 1-3层 # 判断通道区 if col in MAIN_AISLES or row in SUB_AISLES: loc_type = 'M1' c_number = row # 通道 if col ==18 and row == 1: loc_type = 'T1' c_number = 1 # 判断货位类型(根据实际规划) else: if row <2: loc_type = 'T1' c_number = 1 elif row < 8: loc_type = 'T5' c_number = row-2 elif row < 13: loc_type = 'T4' c_number = row-8 else: loc_type = 'T2' c_number = 16-row # 生成唯一编码 location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}" location_group = f"{loc_type}-L{layer}C{col:03d}" # print(f"生成库位:{location_code}-{row}-{col}-{layer}") # 创建库位 cls.objects.update_or_create( warehouse_code=warehouse_code, row=row, col=col, layer=layer, c_number=c_number, shelf_type=loc_type, defaults={ 'location_code': location_code, 'location_group': location_group, 'location_type': loc_type, 'max_capacity': { 'T5': 5, 'T4': 4, 'T2': 2, 'T1': 1, 'M1': 0, 'E1': 0, 'C1': 0 }[loc_type], 'coordinate': f"{row}-{col}-{layer}", 'is_active': True }, access_priority=c_number ) # print("✅ 库位生成成功!") for row in range(1, 18): # 1-17行 for col in range(20, 30): # 19-29列 for layer in range(1, 4): # 1-3层 # 判断通道区 if col in MAIN_AISLES or row in SUB_AISLES: loc_type = 'M1' c_number = row # 通道 if col ==18 and row == 1: loc_type = 'T1' c_number = 1 if col ==29 and row == 1: loc_type = 'T1' c_number = 1 if col ==29 and row == 14: loc_type = 'S4' c_number = 4 if col ==29 and row == 15: loc_type = 'S4' c_number = 3 if col ==29 and row == 16: loc_type = 'S4' c_number = 2 if col ==29 and row == 17: loc_type = 'S4' c_number = 1 # 判断货位类型(根据实际规划) else: # 判断货位类型(根据实际规划) if row < 2: loc_type = 'T1' c_number = row elif row < 8: loc_type = 'T5' c_number = row-2 elif row < 13: loc_type = 'T4' c_number = row-8 else: loc_type = 'S4' c_number = 18-row # 生成唯一编码 location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}" location_group = f"{loc_type}-L{layer}C{col:03d}" # print(f"生成库位:{location_code}-{row}-{col}-{layer}") # 创建库位 cls.objects.update_or_create( warehouse_code=warehouse_code, row=row, col=col, layer=layer, c_number=c_number, shelf_type=loc_type, defaults={ 'location_code': location_code, 'location_group': location_group, 'location_type': loc_type, 'max_capacity': { 'T5': 5, 'T4': 4, 'S4': 4, 'T2': 2, 'T1': 1, 'M1': 0, 'E1': 0, 'C1': 0, 'B1': 0 }[loc_type], 'coordinate': f"{row}-{col}-{layer}", 'is_active': True }, access_priority=c_number ) # 输送机 for row in [14]: # 1-17行 for col in [1,18]: # 1-19列 for layer in range(1, 4): # 1-3层 # 判断货位类型(根据实际规划) loc_type = 'C1' c_number = 1 location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}" location_group = f"{loc_type}-L{layer}C{col:03d}" # print(f"生成库位:{location_code}-{row}-{col}-{layer}") # 创建库位 # 创建库位 cls.objects.update_or_create( warehouse_code=warehouse_code, row=row, col=col, layer=layer, c_number=c_number, shelf_type=loc_type, defaults={ 'location_code': location_code, 'location_group': location_group, 'location_type': loc_type, 'max_capacity': { 'T5': 5, 'T4': 4, 'S4': 4, 'T2': 2, 'T1': 1, 'M1': 0, 'E1': 0, 'C1': 0, 'B1': 0 }[loc_type], 'coordinate': f"{row}-{col}-{layer}", 'is_active': True }, access_priority=c_number ) for row in [16]: # 1-17行 for col in [1,18]: # 1-19列 for layer in [1]: # 1-3层 # 判断货位类型(根据实际规划) loc_type = 'C1' c_number = row location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}" location_group = f"{loc_type}-L{layer}C{col:03d}" # 创建库位 cls.objects.update_or_create( warehouse_code=warehouse_code, row=row, col=col, layer=layer, c_number=c_number, shelf_type=loc_type, defaults={ 'location_code': location_code, 'location_group': location_group, 'location_type': loc_type, 'max_capacity': { 'T5': 5, 'T4': 4, 'S4': 4, 'T2': 2, 'T1': 1, 'M1': 0, 'E1': 0, 'C1': 0, 'B1': 0 }[loc_type], 'coordinate': f"{row}-{col}-{layer}", 'is_active': True }, access_priority=c_number ) # 提升机 for row in [15]: # 1-17行 for col in [1,18]: # 1-19列 for layer in range(1, 4): # 1-3层 # 判断货位类型(根据实际规划) loc_type = 'E1' c_number = row location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}" location_group = f"{loc_type}-L{layer}C{col:03d}" # 创建库位 cls.objects.update_or_create( warehouse_code=warehouse_code, row=row, col=col, layer=layer, c_number=c_number, shelf_type=loc_type, defaults={ 'location_code': location_code, 'location_group': location_group, 'location_type': loc_type, 'max_capacity': { 'T5': 5, 'T4': 4, 'S4': 4, 'T2': 2, 'T1': 1, 'M1': 0, 'E1': 0, 'C1': 0, 'B1': 0 }[loc_type], 'coordinate': f"{row}-{col}-{layer}", 'is_active': True }, access_priority=c_number ) # 充电桩 for row in [14]: # 1-17行 for col in [2]: # 1-19列 for layer in range(1, 3): # 1-3层 # 判断货位类型(根据实际规划) loc_type = 'B1' c_number = 1 location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}" location_group = f"{loc_type}-L{layer}C{col:03d}" # 创建库位 cls.objects.update_or_create( warehouse_code=warehouse_code, row=row, col=col, layer=layer, c_number=c_number, shelf_type=loc_type, defaults={ 'location_code': location_code, 'location_group': location_group, 'location_type': loc_type, 'max_capacity': { 'T5': 5, 'T4': 4, 'S4': 4, 'T2': 2, 'T1': 1, 'M1': 0, 'E1': 0, 'C1': 0, 'B1': 0 }[loc_type], 'coordinate': f"{row}-{col}-{layer}", 'is_active': True }, access_priority=c_number ) class LocationGroupModel(models.Model): LOCATION_TYPES = ( ('T5', '5货位'), # 5托盘/批次 ('T4', '4货位'), # 4托盘/批次 ('S4', '4单货位'), # 4单托盘 ('T2', '2货位'), # 2托盘/批次 ('T1', '散货位'), # 1托盘 ) LOCATION_STATUS = ( ('available', '可用'), ('occupied', '占用'), ('full', '满'), ('disabled', '禁用'), ('reserved', '预留'), ('maintenance', '维护中'), ) warehouse_code = models.CharField(max_length=50, verbose_name='仓库编码') group_name = models.CharField(max_length=50, verbose_name='库位组名称') group_type = models.CharField(max_length=50, choices=LOCATION_TYPES, verbose_name='库位组类型') group_code = models.CharField(max_length=50, verbose_name='库位组编码') layer = models.PositiveIntegerField(verbose_name='层数') location_items = models.ManyToManyField(LocationModel, verbose_name='库位') status = models.CharField(max_length=20, choices=LOCATION_STATUS, default='available', verbose_name='库位状态') max_capacity = models.PositiveIntegerField(verbose_name='最大容量') # 根据类型自动设置 current_quantity = models.PositiveIntegerField(default=0, verbose_name='当前托盘数') current_goods_quantity = models.PositiveIntegerField(default=0, verbose_name='当前货物数') current_batch = models.CharField(max_length=50, default='', verbose_name='当前批次') current_goods_code = models.CharField(max_length=50, default='', verbose_name='当前货物编码') access_priority = models.IntegerField( default=0, verbose_name='访问优先级', help_text='值越大表示越远离主通道,应优先使用' ) left_priority = models.IntegerField( default=0, verbose_name='左侧优先级', help_text='值越大表示越靠左,应优先使用' ) right_priority = models.IntegerField( default=0, verbose_name='右侧优先级', help_text='值越大表示越靠右,应优先使用' ) is_active = models.BooleanField(default=True, verbose_name='是否有效') # create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') class Meta: db_table = 'location_group' verbose_name = 'Location Group' verbose_name_plural = "Location Group" ordering = ['-id'] unique_together = ( 'warehouse_code', 'group_code') # 防止重复组编码 @classmethod def generate_group(cls,warehouse_code): cls.objects.filter(warehouse_code=warehouse_code).delete() MAIN_AISLES = [18, 1] # 子通道列号 SUB_AISLES = [2,8, 13] # 主通道行号 for row in range(1, 14): # 1-13行 for col in range(1, 3): # 1-19列 for layer in range(1, 4): # 1-3层 # 判断通道区 if col in MAIN_AISLES or row in SUB_AISLES: loc_type = 'M1' c_number = row # 通道 if col ==1 and row == 1: loc_type = 'T1' c_number = 1 # 判断货位类型(根据实际规划) else: if row <2: loc_type = 'T1' c_number = 1 elif row < 8: loc_type = 'T5' c_number = row-2 elif row < 13: loc_type = 'T4' c_number = row-8 else: loc_type = 'T2' c_number = 16-row # 生成唯一编码 print(f"生成库组:{row}-{col}-{layer}") if loc_type == 'M1': continue # 创建库位 group_code = f"{loc_type}-L{layer}C{col:03d}" group_name = f"{loc_type}-L{layer}C{col:03d}" # 使用(row+col)*layer作为库位排序 left_priority = (abs(row-13)+abs(col-1))*layer right_priority = (abs(row-13)+abs(col-18))*layer if cls.objects.filter(warehouse_code=warehouse_code, group_code=group_code).exists(): group_item = cls.objects.get(warehouse_code=warehouse_code, group_code=group_code) group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer)) group_item.save() else: group_item = cls.objects.create( warehouse_code=warehouse_code, layer=layer, group_name=group_name, group_type=loc_type, group_code=group_code, max_capacity={ 'T5': 5, 'T4': 4, 'T2': 2, 'T1': 1, 'S4': 4, 'M1': 0, 'E1': 0, 'C1': 0 }[loc_type], current_quantity=0, status='available', access_priority=c_number, left_priority=left_priority, right_priority=right_priority, is_active=True ) group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer)) group_item.save() for row in range(1, 16): # 1-15行 for col in range(3, 17): # 1-16列 for layer in range(1, 4): # 1-3层 # 判断通道区 if col in MAIN_AISLES or row in SUB_AISLES: loc_type = 'M1' c_number = row # 通道 if col ==18 and row == 1: loc_type = 'T1' c_number = 1 # 判断货位类型(根据实际规划) else: if row <2: loc_type = 'T1' c_number = 1 elif row < 8: loc_type = 'T5' c_number = row-2 elif row < 13: loc_type = 'T4' c_number = row-8 else: loc_type = 'T2' c_number = 16-row # print(f"生成库位:{location_code}-{row}-{col}-{layer}") if loc_type == 'M1': continue # 创建库位 group_code = f"{loc_type}-L{layer}C{col:03d}" group_name = f"{loc_type}-L{layer}C{col:03d}" left_priority = (abs(row-13)+abs(col-1))*layer right_priority = (abs(row-13)+abs(col-18))*layer if cls.objects.filter(warehouse_code=warehouse_code, group_code=group_code).exists(): group_item = cls.objects.get(warehouse_code=warehouse_code, group_code=group_code) group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer)) group_item.save() else: group_item = cls.objects.create( warehouse_code=warehouse_code, layer=layer, group_name=group_name, group_type=loc_type, group_code=group_code, max_capacity={ 'T5': 5, 'T4': 4, 'T2': 2, 'T1': 1, 'S4': 4, 'M1': 0, 'E1': 0, 'C1': 0 }[loc_type], current_quantity=0, status='available', access_priority=c_number, left_priority=left_priority, right_priority=right_priority, is_active=True ) group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer)) group_item.save() for row in range(1, 14): # 1-15行 for col in range(17, 20): # 1-16列 for layer in range(1, 4): # 1-3层 # 判断通道区 if col in MAIN_AISLES or row in SUB_AISLES: loc_type = 'M1' c_number = row # 通道 if col ==18 and row == 1: loc_type = 'T1' c_number = 1 # 判断货位类型(根据实际规划) else: if row <2: loc_type = 'T1' c_number = 1 elif row < 8: loc_type = 'T5' c_number = row-2 elif row < 13: loc_type = 'T4' c_number = row-8 else: loc_type = 'T2' c_number = 16-row # print(f"生成库位:{location_code}-{row}-{col}-{layer}") if loc_type == 'M1': continue # 创建库位 group_code = f"{loc_type}-L{layer}C{col:03d}" group_name = f"{loc_type}-L{layer}C{col:03d}" left_priority = (abs(row-13)+abs(col-1))*layer right_priority = (abs(row-13)+abs(col-18))*layer if cls.objects.filter(warehouse_code=warehouse_code, group_code=group_code).exists(): group_item = cls.objects.get(warehouse_code=warehouse_code, group_code=group_code) group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer)) group_item.save() else: group_item = cls.objects.create( warehouse_code=warehouse_code, layer=layer, group_name=group_name, group_type=loc_type, group_code=group_code, max_capacity={ 'T5': 5, 'T4': 4, 'T2': 2, 'T1': 1, 'S4': 4, 'M1': 0, 'E1': 0, 'C1': 0 }[loc_type], current_quantity=0, status='available', access_priority=c_number, left_priority=left_priority, right_priority=right_priority, is_active=True ) group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer)) group_item.save() for row in range(1, 18): # 1-17行 for col in range(20, 30): # 19-29列 for layer in range(1, 4): # 1-3层 # 判断通道区 if col in MAIN_AISLES or row in SUB_AISLES: loc_type = 'M1' c_number = row # 通道 if col ==18 and row == 1: loc_type = 'T1' c_number = 1 if col ==29 and row == 1: loc_type = 'T1' c_number = 1 if col ==29 and row == 14: loc_type = 'S4' c_number = 4 if col ==29 and row == 15: loc_type = 'S4' c_number = 3 if col ==29 and row == 16: loc_type = 'S4' c_number = 2 if col ==29 and row == 17: loc_type = 'S4' c_number = 1 # 判断货位类型(根据实际规划) else: # 判断货位类型(根据实际规划) if row < 2: loc_type = 'T1' c_number = row elif row < 8: loc_type = 'T5' c_number = row-2 elif row < 13: loc_type = 'T4' c_number = row-8 else: loc_type = 'S4' c_number = 18-row # print(f"生成库位:{location_code}-{row}-{col}-{layer}") if loc_type == 'M1': continue # 创建库位 group_code = f"{loc_type}-L{layer}C{col:03d}" group_name = f"{loc_type}-L{layer}C{col:03d}" left_priority = (abs(row-13)+abs(col-1))*layer right_priority = (abs(row-13)+abs(col-18))*layer if cls.objects.filter(warehouse_code=warehouse_code, group_code=group_code).exists(): group_item = cls.objects.get(warehouse_code=warehouse_code, group_code=group_code) group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer)) group_item.save() else: group_item = cls.objects.create( warehouse_code=warehouse_code, layer=layer, group_name=group_name, group_type=loc_type, group_code=group_code, max_capacity={ 'T5': 5, 'T4': 4, 'T2': 2, 'T1': 1, 'S4': 4, 'M1': 0, 'E1': 0, 'C1': 0 }[loc_type], current_quantity=0, status='available', access_priority=c_number, left_priority=left_priority, right_priority=right_priority, is_active=True ) group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer)) group_item.save() # 库位-托盘关联表(记录实时存放关系) class LocationContainerLink(models.Model): location = models.ForeignKey( LocationModel, on_delete=models.CASCADE, related_name='container_links', verbose_name='库位' ) container = models.ForeignKey( ContainerListModel, on_delete=models.CASCADE, related_name='location_links', verbose_name='关联托盘' ) task_wcs = models.ForeignKey(ContainerWCSModel, on_delete=models.CASCADE, null=True, blank=True) task_detail = models.ForeignKey(TaskModel, on_delete=models.CASCADE, null=True, blank=True) put_time = models.DateTimeField(auto_now_add=True, verbose_name='上架时间') operator = models.CharField(max_length=50, verbose_name='操作人') is_active = models.BooleanField(default=True, verbose_name='是否有效') class Meta: db_table = 'location_container_link' verbose_name = 'Location-Container Link' verbose_name_plural = "Location-Container Link" ordering = ['-id'] unique_together = ( 'location', 'container') # 防止重复关联 class DeviceModel(models.Model): warehouse_code = models.CharField(max_length=255, verbose_name="Warehouse Code") location = models.ForeignKey(LocationModel, on_delete=models.CASCADE) device_id = models.CharField(max_length=255, verbose_name="Device ID") device_name = models.CharField(max_length=255, verbose_name="Device Name") device_type = models.CharField(max_length=255, verbose_name="Device Type") ip_address = models.CharField(max_length=255, verbose_name="IP Address") port = models.IntegerField(verbose_name="Port") mode = models.CharField(default='inbound', max_length=255, verbose_name="Mode") status = models.CharField(max_length=255, verbose_name="Status") create_time = models.DateTimeField(auto_now_add=True, verbose_name="Create Time") update_time = models.DateTimeField(auto_now=True, blank=True, null=True, verbose_name="Update Time") class Meta: db_table = 'device' verbose_name = 'Device' verbose_name_plural = "Device" ordering = ['-id'] unique_together = ( 'location', 'device_id') # 防止重复设备 @classmethod def generate_device(cls,warehouse_code): cls.objects.filter(warehouse_code=warehouse_code).delete() # 输送机 location = LocationModel.objects.get(warehouse_code=warehouse_code, row=16, col=1, layer=1) # 创建库位 cls.objects.update_or_create( warehouse_code=warehouse_code, location=location, device_id=f"203", device_name=f"203", device_type='输送机', ip_address='192.168.18.1', mode = 'inbound', port=203, status='available', ) location = LocationModel.objects.get(warehouse_code=warehouse_code, row=16, col=18, layer=1) # 创建库位 cls.objects.update_or_create( warehouse_code=warehouse_code, location=location, device_id=f"103", device_name=f"103", device_type='输送机', ip_address='192.168.18.1', mode = 'outbound', port=103, status='available', ) # 库位变更记录(历史追溯) class LocationChangeLog(models.Model): OPERATION_TYPES = ( ('put', '上架'), ('pick', '下架'), ('move_in', '移入'), ('move_out', '移出') ) location = models.ForeignKey(LocationModel, on_delete=models.CASCADE, verbose_name='库位') container = models.ForeignKey(ContainerListModel, on_delete=models.CASCADE, verbose_name='托盘') task_wcs = models.ForeignKey(ContainerWCSModel, on_delete=models.CASCADE, null=True, blank=True, verbose_name='WCS任务') task_detail = models.ForeignKey(TaskModel, on_delete=models.CASCADE, null=True, blank=True, verbose_name='批次详情') operation_type = models.CharField(max_length=10, choices=OPERATION_TYPES, verbose_name='操作类型') related_location = models.ForeignKey(LocationModel, on_delete=models.SET_NULL, null=True, related_name='related_logs', verbose_name='关联库位') # 用于移库操作 timestamp = models.DateTimeField(auto_now_add=True, verbose_name='操作时间') class Meta: db_table = 'location_change_log' verbose_name = 'Location Change Log' verbose_name_plural = "Location Change Log" ordering = ['-id'] class base_location(models.Model): layer1_pressure = models.IntegerField(default=0, verbose_name='第一层工作压力') layer2_pressure = models.IntegerField(default=0, verbose_name='第二层工作压力') layer3_pressure = models.IntegerField(default=0, verbose_name='第三层工作压力') class Meta: db_table = 'base_location' verbose_name = 'Base_location' verbose_name_plural = "Base_location" ordering = ['-id'] class alloction_pre(models.Model): batch_number = models.CharField(max_length=255, verbose_name='批次号') layer_pre_type = models.JSONField(default=list, verbose_name='预留方案') layer_solution_type = models.JSONField(default=list, verbose_name='规划方案') layer1_task_finish_number = models.IntegerField(default=0, verbose_name='第一层任务完成数') layer2_task_finish_number = models.IntegerField(default=0, verbose_name='第二层任务完成数') layer3_task_finish_number = models.IntegerField(default=0, verbose_name='第三层任务完成数') create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') class Meta: db_table = 'allocation_pre' verbose_name = 'Allocation_pre' verbose_name_plural = "Allocation_pre" ordering = ['-id'] class allocation_history(models.Model): location = models.ForeignKey(LocationModel, on_delete=models.CASCADE, verbose_name='库位') container = models.ForeignKey(ContainerListModel, on_delete=models.CASCADE, verbose_name='托盘') task_wcs = models.ForeignKey(ContainerWCSModel, on_delete=models.CASCADE, null=True, blank=True, verbose_name='WCS任务') task_detail = models.ForeignKey(TaskModel, on_delete=models.CASCADE, null=True, blank=True, verbose_name='批次详情') operation_type = models.CharField(max_length=10, verbose_name='操作类型') related_location = models.ForeignKey(LocationModel, on_delete=models.SET_NULL, null=True, related_name='related_logs_history', verbose_name='关联库位') # 用于移库操作 timestamp = models.DateTimeField(auto_now_add=True, verbose_name='操作时间') class Meta: db_table = 'allocation_history' verbose_name = 'Allocation_history' verbose_name_plural = "Allocation_history" ordering = ['-id']