|
|
|
@ -1,6 +1,7 @@ |
|
|
|
package com.gaotao.modules.automatedWarehouse.service.impl; |
|
|
|
|
|
|
|
import com.gaotao.modules.api.service.WcsApiService; |
|
|
|
import com.gaotao.modules.automatedWarehouse.entity.BufferZoneConfig; |
|
|
|
import com.gaotao.modules.automatedWarehouse.entity.PartPalletData; |
|
|
|
import com.gaotao.modules.automatedWarehouse.entity.WmsLabelAndPalletData; |
|
|
|
import com.gaotao.modules.automatedWarehouse.entity.WmsTransportTask; |
|
|
|
@ -14,10 +15,10 @@ import org.apache.shiro.SecurityUtils; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
import org.springframework.util.StringUtils; |
|
|
|
|
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.List; |
|
|
|
import java.util.*; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
import java.util.stream.IntStream; |
|
|
|
|
|
|
|
@ -93,4 +94,172 @@ public class WcsIntegrationServiceImpl implements WcsIntegrationService { |
|
|
|
// TODO: 这里可以调用WCS接口通知立库执行运输任务 |
|
|
|
wcsApiService.pushAgvTaskApi(saveList); |
|
|
|
} |
|
|
|
|
|
|
|
// ==================== 打托相关方法实现 - AI制作 ==================== |
|
|
|
|
|
|
|
@Override |
|
|
|
public Map<String, Object> checkPalletExists(Map<String, Object> params) throws Exception { |
|
|
|
String site = (String) params.get("site"); |
|
|
|
String palletId = (String) params.get("palletId"); |
|
|
|
|
|
|
|
if (!StringUtils.hasText(site) || !StringUtils.hasText(palletId)) { |
|
|
|
throw new Exception("参数不能为空"); |
|
|
|
} |
|
|
|
|
|
|
|
// 检查栈板是否存在 |
|
|
|
Map<String, Object> palletInfo = wcsIntegrationMapper.getPalletInfo(site, palletId); |
|
|
|
if (palletInfo == null) { |
|
|
|
throw new Exception("栈板不存在"); |
|
|
|
} |
|
|
|
|
|
|
|
// 获取栈板类型的位置信息 |
|
|
|
String palletType = (String) palletInfo.get("pallet_type"); |
|
|
|
List<String> positions = wcsIntegrationMapper.getPalletTypePositions(site, palletType); |
|
|
|
|
|
|
|
Map<String, Object> result = new HashMap<>(); |
|
|
|
result.put("positions", positions); |
|
|
|
result.put("palletType", palletType); |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public List<Map<String, Object>> getPalletDetails(Map<String, Object> params) throws Exception { |
|
|
|
String site = (String) params.get("site"); |
|
|
|
String palletId = (String) params.get("palletId"); |
|
|
|
String position = (String) params.get("position"); |
|
|
|
Integer layer = null; |
|
|
|
|
|
|
|
if (params.get("layer") != null && !params.get("layer").equals("")) { |
|
|
|
layer = Integer.valueOf(params.get("layer").toString()); |
|
|
|
} |
|
|
|
|
|
|
|
if (!StringUtils.hasText(site) || !StringUtils.hasText(palletId)) { |
|
|
|
throw new Exception("参数不能为空"); |
|
|
|
} |
|
|
|
|
|
|
|
return wcsIntegrationMapper.getPalletDetails(site, palletId, position, layer); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public List<Integer> getLayersByPosition(Map<String, Object> params) throws Exception { |
|
|
|
String site = (String) params.get("site"); |
|
|
|
String palletId = (String) params.get("palletId"); |
|
|
|
String position = (String) params.get("position"); |
|
|
|
|
|
|
|
if (!StringUtils.hasText(site) || !StringUtils.hasText(palletId) || !StringUtils.hasText(position)) { |
|
|
|
throw new Exception("参数不能为空"); |
|
|
|
} |
|
|
|
|
|
|
|
return wcsIntegrationMapper.getLayersByPosition(site, palletId, position); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
@Transactional |
|
|
|
public void savePalletDetail(Map<String, Object> params) throws Exception { |
|
|
|
String site = (String) params.get("site"); |
|
|
|
String palletId = (String) params.get("palletId"); |
|
|
|
String position = (String) params.get("position"); |
|
|
|
Integer layer = Integer.valueOf(params.get("layer").toString()); |
|
|
|
String serialNo = (String) params.get("serialNo"); |
|
|
|
|
|
|
|
if (!StringUtils.hasText(site) || !StringUtils.hasText(palletId) || |
|
|
|
!StringUtils.hasText(position) || layer == null || !StringUtils.hasText(serialNo)) { |
|
|
|
throw new Exception("参数不能为空"); |
|
|
|
} |
|
|
|
|
|
|
|
// 1. 验证标签 |
|
|
|
Map<String, Object> labelInfo = wcsIntegrationMapper.validateLabel(site, serialNo); |
|
|
|
if (labelInfo == null) { |
|
|
|
throw new Exception("标签不存在"); |
|
|
|
} |
|
|
|
|
|
|
|
String inStockFlag = (String) labelInfo.get("inStockFlag"); |
|
|
|
String warehouseId = (String) labelInfo.get("warehouseId"); |
|
|
|
String locationId = (String) labelInfo.get("locationId"); |
|
|
|
|
|
|
|
if (!"Y".equals(inStockFlag)) { |
|
|
|
throw new Exception("标签不在库状态"); |
|
|
|
} |
|
|
|
|
|
|
|
if (!BufferZoneConfig.isBufferLabel(warehouseId, locationId)) { |
|
|
|
throw new Exception("标签不在缓冲区,无法进行打托操作"); |
|
|
|
} |
|
|
|
|
|
|
|
// 2. 检查标签是否已在栈板中(当前栈板或其他栈板) |
|
|
|
Map<String, Object> existingPalletInfo = wcsIntegrationMapper.findPalletByLabel(site, serialNo); |
|
|
|
if (existingPalletInfo != null) { |
|
|
|
String existingPalletId = (String) existingPalletInfo.get("palletId"); |
|
|
|
|
|
|
|
// 如果标签在当前栈板,提示不要重复扫描 |
|
|
|
if (palletId.equals(existingPalletId)) { |
|
|
|
throw new Exception("该条码已在本栈板上,请不要重复扫描"); |
|
|
|
} |
|
|
|
|
|
|
|
// 如果标签在其他栈板,检查是否在缓冲区 |
|
|
|
if (BufferZoneConfig.isBufferLabel(warehouseId, locationId)) { |
|
|
|
wcsIntegrationMapper.deletePalletDetail(site, existingPalletId, serialNo); |
|
|
|
} else { |
|
|
|
throw new Exception("该条码不在缓冲区,请先移库"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 3. 层级校验:如果选择第N+1层,必须所有position的第N层都有数据ccl_wms |
|
|
|
if (layer > 1) { |
|
|
|
// 获取栈板类型信息 |
|
|
|
Map<String, Object> palletInfo = wcsIntegrationMapper.getPalletInfo(site, palletId); |
|
|
|
String palletType = (String) palletInfo.get("pallet_type"); |
|
|
|
|
|
|
|
// 获取栈板类型的所有位置 |
|
|
|
List<String> allPositions = wcsIntegrationMapper.getPalletTypePositions(site, palletType); |
|
|
|
|
|
|
|
// 检查前一层(layer-1)的所有位置是否都有数据 |
|
|
|
List<Map<String, Object>> prevLayerStats = wcsIntegrationMapper.getPalletLayerStatistics(site, palletId, layer - 1); |
|
|
|
|
|
|
|
// 将统计结果转换为位置映射 |
|
|
|
Set<String> prevLayerPositions = prevLayerStats.stream() |
|
|
|
.map(stat -> (String) stat.get("position")) |
|
|
|
.collect(Collectors.toSet()); |
|
|
|
|
|
|
|
// 检查是否所有位置在前一层都有数据 |
|
|
|
List<String> missingPositions = allPositions.stream() |
|
|
|
.filter(pos -> !prevLayerPositions.contains(pos)) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
|
|
|
|
if (!missingPositions.isEmpty()) { |
|
|
|
throw new Exception("第" + (layer - 1) + "层以下位置还未放满,请先放满:" + String.join(", ", missingPositions)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 4. 保存栈板明细 |
|
|
|
String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername(); |
|
|
|
String partNo = (String) labelInfo.get("partNo"); |
|
|
|
|
|
|
|
wcsIntegrationMapper.savePalletDetail(site, palletId, position, layer, serialNo, partNo, username); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
@Transactional |
|
|
|
public void deletePalletDetail(Map<String, Object> params) throws Exception { |
|
|
|
String site = (String) params.get("site"); |
|
|
|
String palletId = (String) params.get("palletId"); |
|
|
|
String serialNo = (String) params.get("serialNo"); |
|
|
|
|
|
|
|
if (!StringUtils.hasText(site) || !StringUtils.hasText(palletId) || !StringUtils.hasText(serialNo)) { |
|
|
|
throw new Exception("参数不能为空"); |
|
|
|
} |
|
|
|
|
|
|
|
// 检查标签是否在本栈板中 |
|
|
|
Map<String, Object> existingPalletInfo = wcsIntegrationMapper.findPalletByLabel(site, serialNo); |
|
|
|
if (existingPalletInfo == null) { |
|
|
|
throw new Exception("该条码不在任何栈板上"); |
|
|
|
} |
|
|
|
|
|
|
|
String existingPalletId = (String) existingPalletInfo.get("palletId"); |
|
|
|
if (!palletId.equals(existingPalletId)) { |
|
|
|
throw new Exception("该条码不在此栈板上"); |
|
|
|
} |
|
|
|
|
|
|
|
wcsIntegrationMapper.deletePalletDetail(site, palletId, serialNo); |
|
|
|
} |
|
|
|
} |