| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030 | from django.db import modelsfrom 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='当前批次',null=True,blank=True)    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']
 |