|  | @@ -237,7 +237,7 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |              status=1
 | 
	
		
			
				|  |  |          ).first()
 | 
	
		
			
				|  |  |          if not container_detail:
 | 
	
		
			
				|  |  | -            logger.error(f"容器 {container_code} 未组盘")
 | 
	
		
			
				|  |  | +            logger.error(f"托盘 {container_code} 未组盘")
 | 
	
		
			
				|  |  |              return None
 | 
	
		
			
				|  |  |   
 | 
	
		
			
				|  |  |          batch_container = ContainerDetailModel.objects.filter(
 | 
	
	
		
			
				|  | @@ -384,6 +384,37 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |              logger.error(f"更新库位状态失败:{str(e)}")
 | 
	
		
			
				|  |  |              print(f"更新库位状态失败:{str(e)}")
 | 
	
		
			
				|  |  |              return False    
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    def update_group_status_reserved(self,location_group_list):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        更新库位组状态
 | 
	
		
			
				|  |  | +        :param location_group_list: 库位组对象列表
 | 
	
		
			
				|  |  | +        :return:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        try:
 | 
	
		
			
				|  |  | +            for location_group in location_group_list:
 | 
	
		
			
				|  |  | +                # 1. 获取库位组
 | 
	
		
			
				|  |  | +                if not location_group:
 | 
	
		
			
				|  |  | +                    print(f"库位组获取失败!")
 | 
	
		
			
				|  |  | +                    return False
 | 
	
		
			
				|  |  | +                # 2. 更新库位组状态
 | 
	
		
			
				|  |  | +                location_group_id = location_group.split('_')[1]
 | 
	
		
			
				|  |  | +                location_group_item = LocationGroupModel.objects.filter(
 | 
	
		
			
				|  |  | +                    id=location_group_id
 | 
	
		
			
				|  |  | +                ).first()
 | 
	
		
			
				|  |  | +                if not location_group_item:
 | 
	
		
			
				|  |  | +                    print(f"库位组 {location_group} 不存在")
 | 
	
		
			
				|  |  | +                    return False
 | 
	
		
			
				|  |  | +                # 3. 更新库位组状态
 | 
	
		
			
				|  |  | +                location_group_item.status = 'reserved'
 | 
	
		
			
				|  |  | +                location_group_item.save()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            return True
 | 
	
		
			
				|  |  | +        except Exception as e:       
 | 
	
		
			
				|  |  | +            logger.error(f"更新库位组状态失败:{str(e)}")
 | 
	
		
			
				|  |  | +            print(f"更新库位组状态失败:{str(e)}")
 | 
	
		
			
				|  |  | +            return False    
 | 
	
		
			
				|  |  | +    @transaction.atomic
 | 
	
		
			
				|  |  |      def update_location_group_status(self, location_code):
 | 
	
		
			
				|  |  |          """
 | 
	
		
			
				|  |  |          更新库位组状态
 | 
	
	
		
			
				|  | @@ -452,11 +483,10 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |                  status=1
 | 
	
		
			
				|  |  |              ).first()
 | 
	
		
			
				|  |  |              if not container_detail:
 | 
	
		
			
				|  |  | -                print (f"容器 {container_code} 未组盘")
 | 
	
		
			
				|  |  | -                logger.error(f"容器 {container_code} 未组盘")
 | 
	
		
			
				|  |  | +                print (f"托盘 {container_code} 未组盘")
 | 
	
		
			
				|  |  | +                logger.error(f"托盘 {container_code} 未组盘")
 | 
	
		
			
				|  |  |                  return None
 | 
	
		
			
				|  |  | -            else:
 | 
	
		
			
				|  |  | -                print (f"容器 {container_code} 已组盘")
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  |              # 3. 更新批次状态
 | 
	
		
			
				|  |  |              batch = container_detail.batch
 | 
	
		
			
				|  |  |              batch.status = status
 | 
	
	
		
			
				|  | @@ -488,11 +518,10 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |              status=1
 | 
	
		
			
				|  |  |          ).first()
 | 
	
		
			
				|  |  |          if not container_detail:
 | 
	
		
			
				|  |  | -            print (f"容器 {container_code} 未组盘")
 | 
	
		
			
				|  |  | -            logger.error(f"容器 {container_code} 未组盘")
 | 
	
		
			
				|  |  | +            print (f"托盘 {container_code} 未组盘")
 | 
	
		
			
				|  |  | +            logger.error(f"托盘 {container_code} 未组盘")
 | 
	
		
			
				|  |  |              return None
 | 
	
		
			
				|  |  | -        else:
 | 
	
		
			
				|  |  | -            print (f"容器 {container_code} 已组盘")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          batch_status = container_detail.batch.status
 | 
	
		
			
				|  |  |          return batch_status
 | 
	
		
			
				|  |  |      def get_batch(self,container_code):
 | 
	
	
		
			
				|  | @@ -516,11 +545,10 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |              status=1
 | 
	
		
			
				|  |  |          ).first()
 | 
	
		
			
				|  |  |          if not container_detail:
 | 
	
		
			
				|  |  | -            print (f"容器 {container_code} 未组盘")
 | 
	
		
			
				|  |  | -            logger.error(f"容器 {container_code} 未组盘")
 | 
	
		
			
				|  |  | +            print (f"托盘 {container_code} 未组盘")
 | 
	
		
			
				|  |  | +            logger.error(f"托盘 {container_code} 未组盘")
 | 
	
		
			
				|  |  |              return None
 | 
	
		
			
				|  |  | -        else:
 | 
	
		
			
				|  |  | -            print (f"容器 {container_code} 已组盘")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          batch = container_detail.batch.bound_number
 | 
	
		
			
				|  |  |          return batch
 | 
	
		
			
				|  |  |      @transaction.atomic
 | 
	
	
		
			
				|  | @@ -536,7 +564,7 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |          min_c_number_index=1000
 | 
	
		
			
				|  |  |           
 | 
	
		
			
				|  |  |          current_task = self.get_current_finish_task(container_code)
 | 
	
		
			
				|  |  | -        print(f"当前已完成任务: {current_task}")
 | 
	
		
			
				|  |  | +        print(f"[1]当前已完成任务: {current_task}")
 | 
	
		
			
				|  |  |          # 按压力排序
 | 
	
		
			
				|  |  |          sorted_pressure = sorted(
 | 
	
		
			
				|  |  |              [(0, current_task[0]), (1, current_task[1]), (2, current_task[2])],
 | 
	
	
		
			
				|  | @@ -544,16 +572,16 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |          )
 | 
	
		
			
				|  |  |          # 交换第一和第二个元素的位置
 | 
	
		
			
				|  |  |          sorted_pressure[0], sorted_pressure[1] = sorted_pressure[1], sorted_pressure[0]
 | 
	
		
			
				|  |  | -        print(f"任务排序: {sorted_pressure}")
 | 
	
		
			
				|  |  | -        print(f"当前选择:{sorted_pressure[0][0]+1}")
 | 
	
		
			
				|  |  | +        print(f"[2]任务排序: {sorted_pressure}")
 | 
	
		
			
				|  |  | +        print(f"[3]当前选择:{sorted_pressure[0][0]+1}")
 | 
	
		
			
				|  |  |          location_type_dict = json.loads(self.divide_solution_by_layer(location_group_list))
 | 
	
		
			
				|  |  | -        print(f"库位类型分配方案: {location_type_dict}")
 | 
	
		
			
				|  |  | +        # print(f"库位类型分配方案: {location_type_dict}")
 | 
	
		
			
				|  |  |     
 | 
	
		
			
				|  |  |          for layer, _ in sorted_pressure:
 | 
	
		
			
				|  |  |              if not location_type_dict.get(str(layer+1)):
 | 
	
		
			
				|  |  |                  continue
 | 
	
		
			
				|  |  | -            print(f"当前层: {layer+1}")
 | 
	
		
			
				|  |  | -            print(f"当前层库位组: {location_type_dict[str(layer+1)].keys()}")
 | 
	
		
			
				|  |  | +            # print(f"当前层: {layer+1}")
 | 
	
		
			
				|  |  | +            # print(f"当前层库位组: {location_type_dict[str(layer+1)].keys()}")
 | 
	
		
			
				|  |  |              for group_id in location_type_dict[str(layer+1)].keys():
 | 
	
		
			
				|  |  |                  location_group = LocationGroupModel.objects.filter(
 | 
	
		
			
				|  |  |                      id=group_id,
 | 
	
	
		
			
				|  | @@ -569,8 +597,11 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |                 # 提取所有库位的 c_number
 | 
	
		
			
				|  |  |                  c_numbers = [loc.c_number for loc in location_list]
 | 
	
		
			
				|  |  |                  print(f"当前层库位组 {location_group.group_code} 可用库位: {c_numbers}")
 | 
	
		
			
				|  |  | +                # 更新任务完成数目
 | 
	
		
			
				|  |  | +                current_task[layer] = current_task[layer] + 1
 | 
	
		
			
				|  |  | +                self.update_current_finish_task(container_code,current_task)
 | 
	
		
			
				|  |  |                  return location_list[0]
 | 
	
		
			
				|  |  | -      
 | 
	
		
			
				|  |  | +    @transaction.atomic
 | 
	
		
			
				|  |  |      def get_location_type(self, container_code):
 | 
	
		
			
				|  |  |          """
 | 
	
		
			
				|  |  |          智能库位分配核心算法
 | 
	
	
		
			
				|  | @@ -594,7 +625,7 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |              current_pressure = self.get_current_pressure()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              # 测试参数
 | 
	
		
			
				|  |  | -            total_pallets = 30
 | 
	
		
			
				|  |  | +            # total_pallets = 30
 | 
	
		
			
				|  |  |              # layer_capacity = [{'T1': 29, 'T2': 14, 'S4': 10, 'T4': 27, 'T5': 27}, {'T1': 0, 'T2': 0, 'S4': 0, 'T4': 0, 'T5': 21}, {'T1': 29, 'T2': 14, 'S4': 10, 'T4': 27, 'T5': 27}]
 | 
	
		
			
				|  |  |              # current_pressure = [1,0,0]
 | 
	
		
			
				|  |  |              print(f"[1]托盘数目: {total_pallets}")
 | 
	
	
		
			
				|  | @@ -678,7 +709,14 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |                  batch_number=batch,
 | 
	
		
			
				|  |  |                  layer_pre_type =allocation_json
 | 
	
		
			
				|  |  |              )
 | 
	
		
			
				|  |  | -            solution_pressure = base_location.objects.get(id=1)
 | 
	
		
			
				|  |  | +            solution_pressure, created = base_location.objects.get_or_create(
 | 
	
		
			
				|  |  | +                id=1,
 | 
	
		
			
				|  |  | +                defaults={
 | 
	
		
			
				|  |  | +                    'layer1_pressure': 0,
 | 
	
		
			
				|  |  | +                    'layer2_pressure': 0, 
 | 
	
		
			
				|  |  | +                    'layer3_pressure': 0
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            )
 | 
	
		
			
				|  |  |              solution_pressure.layer1_pressure = allocation[1][0]
 | 
	
		
			
				|  |  |              solution_pressure.layer2_pressure = allocation[1][1]
 | 
	
		
			
				|  |  |              solution_pressure.layer3_pressure = allocation[1][2]
 | 
	
	
		
			
				|  | @@ -686,6 +724,7 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |              solution.save()
 | 
	
		
			
				|  |  |              solution_pressure.save()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |              return [loc.split('_')[1] for loc in allocation[0]]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          except Exception as e:
 | 
	
	
		
			
				|  | @@ -742,6 +781,19 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |              return None
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          return [solution.layer1_task_finish_number,solution.layer2_task_finish_number,solution.layer3_task_finish_number]
 | 
	
		
			
				|  |  | +    def update_current_finish_task(self,container,task_finish_number):
 | 
	
		
			
				|  |  | +        batch = self.get_batch(container) 
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if not batch:
 | 
	
		
			
				|  |  | +            return None
 | 
	
		
			
				|  |  | +        solution = alloction_pre.objects.filter(batch_number=batch).first()
 | 
	
		
			
				|  |  | +        if not solution:
 | 
	
		
			
				|  |  | +            return None
 | 
	
		
			
				|  |  | +        solution.layer1_task_finish_number = task_finish_number[0]
 | 
	
		
			
				|  |  | +        solution.layer2_task_finish_number = task_finish_number[1]
 | 
	
		
			
				|  |  | +        solution.layer3_task_finish_number = task_finish_number[2]
 | 
	
		
			
				|  |  | +        solution.save()
 | 
	
		
			
				|  |  | +        return True
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @transaction.atomic
 | 
	
		
			
				|  |  |      def get_location_by_type(self, location_type_list, start_location, container_code):
 | 
	
	
		
			
				|  | @@ -761,6 +813,11 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |          :return: 符合条件的库位列表
 | 
	
		
			
				|  |  |          """
 | 
	
		
			
				|  |  |          locations = []
 | 
	
		
			
				|  |  | +        # 检查已有分配方案
 | 
	
		
			
				|  |  | +        existing_solution = alloction_pre.objects.filter(batch_number=self.get_batch(container_code)).first()
 | 
	
		
			
				|  |  | +        if existing_solution.layer_solution_type:
 | 
	
		
			
				|  |  | +            print(f"[0]已有库位分配方案:{existing_solution.layer_solution_type}")
 | 
	
		
			
				|  |  | +            return existing_solution.layer_solution_type
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          for layer, location_type_dict in location_type_list.items():
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -769,7 +826,7 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |              # 获取库位类型列表
 | 
	
		
			
				|  |  |              location_type = list(location_type_dict.keys())
 | 
	
		
			
				|  |  |              demand_number = sum(location_type_dict.values())
 | 
	
		
			
				|  |  | -            print (f"层{layer} 需求数量: {demand_number}, 库位: {location_type}")                    
 | 
	
		
			
				|  |  | +            print (f"[1]层{layer} 需求数量: {demand_number}, 库位: {location_type}")                    
 | 
	
		
			
				|  |  |              location_groups = LocationGroupModel.objects.filter(
 | 
	
		
			
				|  |  |                  group_type__in=location_type,
 | 
	
		
			
				|  |  |                  layer=layer,
 | 
	
	
		
			
				|  | @@ -791,7 +848,10 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |                      break
 | 
	
		
			
				|  |  |                  locations.append(f"{layer}_{location_group.id}")
 | 
	
		
			
				|  |  |                  number += 1
 | 
	
		
			
				|  |  | -         
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        existing_solution.layer_solution_type = locations
 | 
	
		
			
				|  |  | +        existing_solution.save()
 | 
	
		
			
				|  |  | +        print(f"[2]分配方案: {locations}")
 | 
	
		
			
				|  |  |          return locations if locations else None
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -808,14 +868,15 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |          # 
 | 
	
		
			
				|  |  |          if status == 1:
 | 
	
		
			
				|  |  |              # 2. 获取库位组
 | 
	
		
			
				|  |  | -            print (f"第一次入库")
 | 
	
		
			
				|  |  | -            self.get_location_type(container_code)
 | 
	
		
			
				|  |  | -            location_type_list = json.loads(alloction_pre.objects.filter(batch_number=self.get_batch(container_code)).first().layer_pre_type)
 | 
	
		
			
				|  |  | -            print(f"库组分配方案:{location_type_list}")
 | 
	
		
			
				|  |  | +            print(f"[1]第一次入库")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            # 重新获取最新数据
 | 
	
		
			
				|  |  | +            self.get_location_type(container_code) 
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            location_type_list = json.loads(alloction_pre.objects.filter(batch_number=self.get_batch(container_code)).first().layer_pre_type)            
 | 
	
		
			
				|  |  |              location_list = self.get_location_by_type(location_type_list,start_location,container_code)
 | 
	
		
			
				|  |  | -            print(f"库组列表:{location_list}")
 | 
	
		
			
				|  |  |              # 预定这些库组
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +            self.update_group_status_reserved(location_list)
 | 
	
		
			
				|  |  |              location_min_value = self.get_location_list_remainder(location_list,container_code)
 | 
	
		
			
				|  |  |              print(f"库位安排到第{location_min_value.c_number}个库位:{location_min_value}")
 | 
	
		
			
				|  |  |              # if not location_list[location_min_index]:
 | 
	
	
		
			
				|  | @@ -824,13 +885,15 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |              # else:
 | 
	
		
			
				|  |  |                  
 | 
	
		
			
				|  |  |              #     return location_list[location_min_index]
 | 
	
		
			
				|  |  | -            return 1
 | 
	
		
			
				|  |  | +            return location_min_value
 | 
	
		
			
				|  |  |        
 | 
	
		
			
				|  |  |          elif status == 2:
 | 
	
		
			
				|  |  |              # 3. 获取部分入库库位
 | 
	
		
			
				|  |  |              print (f"部分入库")
 | 
	
		
			
				|  |  | -            location_list = self.get_location_by_status_part(container_code,start_location)
 | 
	
		
			
				|  |  | -            print(f"库位列表:{location_list}")
 | 
	
		
			
				|  |  | +            location_list = alloction_pre.objects.filter(batch_number=self.get_batch(container_code)).first().layer_solution_type
 | 
	
		
			
				|  |  | +            location_min_value = self.get_location_list_remainder(location_list,container_code)
 | 
	
		
			
				|  |  | +            print(f"库位安排到第{location_min_value.c_number}个库位:{location_min_value}")
 | 
	
		
			
				|  |  | +            return location_min_value
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              
 | 
	
		
			
				|  |  |    
 |