|
|
|
|
@ -370,6 +370,18 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
} |
|
|
|
|
agvSend = Objects.nonNull(agvSend) ? agvSend : false; // 默认不发送AGV
|
|
|
|
|
|
|
|
|
|
// 1.2 若传了结束站点编码,校验站点是否空闲可用
|
|
|
|
|
List<Station> stationArrayList = null; |
|
|
|
|
if (returnToWarehouseDto.getEndStationCode() != null && !returnToWarehouseDto.getEndStationCode().isEmpty()) { |
|
|
|
|
stationArrayList = stationService.list(new LambdaQueryWrapper<Station>() |
|
|
|
|
.ne(Station::getStatus, CONVEYOR_LINE_RECEIVE_ONLY) |
|
|
|
|
.eq(Station::getStationStatus, STATUS_FREE) |
|
|
|
|
.eq(Station::getStationCode, returnToWarehouseDto.getEndStationCode())); |
|
|
|
|
if (stationArrayList == null || stationArrayList.size() == 0) { |
|
|
|
|
return R.fail("当前结束站点码被占用或不支持运送"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 2. 初始化变量
|
|
|
|
|
String startStationCode = ""; |
|
|
|
|
String endStationCode = ""; |
|
|
|
|
@ -400,12 +412,14 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
if (returnToWarehouseDto.getStationRegion() != null) { |
|
|
|
|
task.setStationRegion(returnToWarehouseDto.getStationRegion()); |
|
|
|
|
} |
|
|
|
|
if(stationList!=null&&stationList.size()!=0){ |
|
|
|
|
Station station = stationList.get(0); |
|
|
|
|
if(stationArrayList!=null&&stationArrayList.size()!=0){ |
|
|
|
|
Station station = stationArrayList.get(0); |
|
|
|
|
station.setStationStatus(PRE_STATUS_OCCUPIED); |
|
|
|
|
stationService.updateStation(station); |
|
|
|
|
task.setStationId(station.getId()); |
|
|
|
|
task.setStationRegion(station.getStationRegion()); |
|
|
|
|
startStationCode=returnToWarehouseDto.getStartStationCode(); |
|
|
|
|
endStationCode=returnToWarehouseDto.getEndStationCode(); |
|
|
|
|
task.setWcId(stationCenterService.list(new LambdaQueryWrapper<StationCenter>().select(StationCenter::getWcId).eq(StationCenter::getStationId,station.getId())).get(0).getWcId()); |
|
|
|
|
}else if (endWcId == 0) { |
|
|
|
|
// 5.1 输送线回库:校验空箱数量
|
|
|
|
|
@ -489,8 +503,11 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
Long wcID = orderBindList.get(0).getWcID(); |
|
|
|
|
BsWorkCenterEntity workCenter = bsWorkCenterService.getById(wcID); |
|
|
|
|
|
|
|
|
|
// 3. 组装返回数据
|
|
|
|
|
LinkedHashMap<String, Object> map = new LinkedHashMap<>(); |
|
|
|
|
map.put("wcId", wcID); |
|
|
|
|
|
|
|
|
|
// 4. 区分镀后库作业中心与普通工位,获取站点区域
|
|
|
|
|
if (DistinguishRegionsEnum.includeByWcName(workCenter.getWcName())) { |
|
|
|
|
//todo:删除读取车间订单代码
|
|
|
|
|
// List<YieldOrder> list = yieldOrderService.list(new LambdaQueryWrapper<YieldOrder>().eq(YieldOrder::getCardNo, orderBindList.get(0).getCardNo()));
|
|
|
|
|
@ -630,11 +647,11 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
// }
|
|
|
|
|
log.info(String.valueOf(stationList.get(0))); |
|
|
|
|
// 校验站点是否可以发送数据
|
|
|
|
|
if (stationList.get(0).getStatus().equals(CONVEYOR_LINE_RECEIVE_ONLY) && agvSend) { |
|
|
|
|
return R.fail("起始站点站码无法当开始站点编码"); |
|
|
|
|
} else if (!stationList.get(0).getStatus().equals(STATION_RECEIVE_ONLY) && !agvSend) { |
|
|
|
|
return R.fail("起始站点站码无法当开始站点编码"); |
|
|
|
|
} |
|
|
|
|
// if (stationList.get(0).getStatus().equals(CONVEYOR_LINE_RECEIVE_ONLY) && agvSend) {
|
|
|
|
|
// return R.fail("起始站点站码无法当开始站点编码");
|
|
|
|
|
// } else if (!stationList.get(0).getStatus().equals(STATION_RECEIVE_ONLY) && !agvSend) {
|
|
|
|
|
// return R.fail("起始站点站码无法当开始站点编码");
|
|
|
|
|
// }
|
|
|
|
|
return R.data(startStationCode); |
|
|
|
|
} else { |
|
|
|
|
// 默认赋值为取料输送线
|
|
|
|
|
@ -700,19 +717,21 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
freeStationList = stationService.getStatusStationList(STATUS_FREE, true, task.getWcId(), STATION_RECEIVE_ONLY, false); |
|
|
|
|
} |
|
|
|
|
String wcName = bsWorkCenterService.getById(task.getWcId()).getWcName(); |
|
|
|
|
|
|
|
|
|
// 1.1 按区域筛选站点
|
|
|
|
|
if (freeStationList != null && freeStationList.size() != 0) { |
|
|
|
|
if (!task.getStationRegion().isEmpty()) { |
|
|
|
|
freeStationList = freeStationList.stream().filter(s -> s.getStationRegion().equals(task.getStationRegion())).toList(); |
|
|
|
|
} |
|
|
|
|
//判断是不是镀后库作业中心
|
|
|
|
|
// 判断是不是镀后库作业中心,镀后库非AGV时进一步按区域过滤
|
|
|
|
|
if (DistinguishRegionsEnum.includeByWcName(wcName) && !agvSend) { |
|
|
|
|
freeStationList = freeStationList.stream().filter(s -> s.getStationRegion().equals(task.getStationRegion())).toList(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 1.2 分配到具体站点并锁定
|
|
|
|
|
if (freeStationList != null && freeStationList.size() != 0) { |
|
|
|
|
StationVO station = null; |
|
|
|
|
station = freeStationList.get(0); |
|
|
|
|
StationVO station = freeStationList.get(0); |
|
|
|
|
task.setStationId(station.getId()); |
|
|
|
|
// 锁定站点(预占用)
|
|
|
|
|
station.setStationStatus(PRE_STATUS_OCCUPIED); |
|
|
|
|
@ -722,7 +741,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
return R.data(task); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 2. 尝试分配空闲库位
|
|
|
|
|
// 2. 尝试分配空闲库位(优先尾号为2的库位)
|
|
|
|
|
List<Location> freeLocationList = null; |
|
|
|
|
QueryWrapper<Location> wrapper2 = new QueryWrapper<Location>() |
|
|
|
|
.ne("status", ORIGINAL_RACK) |
|
|
|
|
@ -740,6 +759,8 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
.eq("location_status", STATUS_FREE) |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 2.1 分配到具体库位并锁定
|
|
|
|
|
if (!CollectionUtils.isEmpty(freeLocationList)) { |
|
|
|
|
Location location = freeLocationList.get(0); |
|
|
|
|
task.setLocationId(location.getId()); |
|
|
|
|
@ -766,8 +787,9 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
* @return R<String> 结束站点编码(成功)/错误信息(失败) |
|
|
|
|
*/ |
|
|
|
|
private R<?> validateEndStationStatus(Task task, Boolean agvSend) { |
|
|
|
|
// 1. 无站点ID时处理库位逻辑
|
|
|
|
|
if (Objects.isNull(task.getStationId())) { |
|
|
|
|
// 无站点ID:校验库位状态并返回失败
|
|
|
|
|
// 1.1 AGV模式下需要释放已占库位并删除任务
|
|
|
|
|
if (agvSend) { |
|
|
|
|
List<Location> locationList = locationService.list( |
|
|
|
|
new LambdaQueryWrapper<Location>().eq(Location::getId, task.getLocationId()) |
|
|
|
|
@ -781,15 +803,16 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
taskService.removeById(task); |
|
|
|
|
return R.fail("结束站点被占用"); |
|
|
|
|
} |
|
|
|
|
// 1.2 非AGV模式直接返回空
|
|
|
|
|
return R.data(""); |
|
|
|
|
} else { |
|
|
|
|
// 有站点ID:校验站点存在性并锁定
|
|
|
|
|
// 2. 有站点ID:校验站点存在性
|
|
|
|
|
Station station = stationService.getById(task.getStationId()); |
|
|
|
|
if (Objects.isNull(station)) { |
|
|
|
|
taskService.removeById(task); |
|
|
|
|
return R.fail("结束站点不存在"); |
|
|
|
|
} |
|
|
|
|
// 锁定站点(预占用)- 修复原代码空指针问题(先判空再更新)
|
|
|
|
|
// 2.1 锁定站点(预占用)- 修复原代码空指针问题(先判空再更新)
|
|
|
|
|
station.setStationStatus(PRE_STATUS_OCCUPIED); |
|
|
|
|
stationService.updateById(station); |
|
|
|
|
return R.data(station.getStationCode()); |
|
|
|
|
@ -804,12 +827,12 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
* @return Task 完善后的任务对象 |
|
|
|
|
*/ |
|
|
|
|
private Task completeTaskBasicInfo(Task task, ReturnToWarehouseDto dto) { |
|
|
|
|
// 基础信息
|
|
|
|
|
// 1. 设置任务基础信息(状态、创建时间、创建人)
|
|
|
|
|
task.setTaskStatus(Task.STATUS_START); |
|
|
|
|
task.setCreateTime(new Date()); |
|
|
|
|
task.setCreateUser(AuthUtil.getUserId()); |
|
|
|
|
|
|
|
|
|
// 任务重量计算
|
|
|
|
|
// 2. 任务重量计算(根据箱条码绑定的订单累加重量)
|
|
|
|
|
String boxBarcode = dto.getBoxBarcode(); |
|
|
|
|
BigDecimal taskWeight = BigDecimal.ZERO; |
|
|
|
|
if (Objects.nonNull(boxBarcode) && !boxBarcode.isBlank()) { |
|
|
|
|
@ -850,20 +873,22 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
*/ |
|
|
|
|
private R<?> sendAgvSchedulingTask(Task task, String startStationCode, String endStationCode) { |
|
|
|
|
try { |
|
|
|
|
// 获取AGV任务类型
|
|
|
|
|
// 1. 获取AGV任务类型
|
|
|
|
|
String taskType = agvTaskTypeUtil.getTaskTypeByPositions(startStationCode, endStationCode); |
|
|
|
|
// 发送调度任务
|
|
|
|
|
|
|
|
|
|
// 2. 发送AGV调度任务
|
|
|
|
|
boolean agvResult = taskExecuteRecordService.genAgvSchedulingTask( |
|
|
|
|
taskType, startStationCode, endStationCode, EQUIPMENT_TYPE_AGV, task |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// 3. 调度成功:更新任务状态为配送完成
|
|
|
|
|
if (agvResult) { |
|
|
|
|
log.info("【AGV调度】任务{}调度成功 - 类型:{}", task.getId(), taskType); |
|
|
|
|
task.setTaskStatus(Task.STATUS_CONVEYOR_END); |
|
|
|
|
taskService.updateById(task); |
|
|
|
|
return R.success(); |
|
|
|
|
} else { |
|
|
|
|
// 调度失败:回滚任务
|
|
|
|
|
// 4. 调度失败:回滚任务并释放站点
|
|
|
|
|
taskService.removeById(task); |
|
|
|
|
List<Station> stationList = stationService.list(new LambdaQueryWrapper<Station>().eq(Station::getId, task.getStationId())); |
|
|
|
|
if (stationList != null && !stationList.isEmpty()) { |
|
|
|
|
@ -874,7 +899,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
return R.fail("AGV小车调用异常"); |
|
|
|
|
} |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
// 异常处理:回滚任务
|
|
|
|
|
// 5. 异常处理:回滚任务并释放站点
|
|
|
|
|
taskService.removeById(task); |
|
|
|
|
List<Station> stationList = stationService.list(new LambdaQueryWrapper<Station>().eq(Station::getId, task.getStationId())); |
|
|
|
|
if (stationList != null && stationList.size() != 0) { |
|
|
|
|
@ -985,11 +1010,14 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
quantityLocationVO.setBoxBarcode(boxBarcode.trim()); |
|
|
|
|
quantityLocationVO.setQuantity((long) orderBindList.size()); // Long类型可直接自动装箱,无需强制转换
|
|
|
|
|
|
|
|
|
|
// 4. 查询并设置工位信息
|
|
|
|
|
BsWorkCenterEntity workCenter = bsWorkCenterService.getById(firstOrderBind.getWcID()); |
|
|
|
|
if (workCenter == null) { |
|
|
|
|
return R.fail("订单所属作业中心异常"); |
|
|
|
|
} |
|
|
|
|
quantityLocationVO.setWcName(workCenter.getWcName()); |
|
|
|
|
|
|
|
|
|
// 5. 查询站点中心并获取站点区域
|
|
|
|
|
List<StationCenter> stationCenterList = stationCenterService.list(new LambdaQueryWrapper<StationCenter>().eq(StationCenter::getWcId, firstOrderBind.getWcID())); |
|
|
|
|
if (stationCenterList == null || stationCenterList.size() == 0) { |
|
|
|
|
return R.fail("获取站点区域有问题"); |
|
|
|
|
@ -1170,22 +1198,26 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public R getStationNameBoxBarcode(String stationCode) { |
|
|
|
|
// 1. 查询站点基础信息
|
|
|
|
|
R stationR = stationService.getStationName(stationCode); |
|
|
|
|
if (!stationR.isSuccess()) { |
|
|
|
|
return stationR; |
|
|
|
|
} |
|
|
|
|
Station station = (Station) stationR.getData(); |
|
|
|
|
|
|
|
|
|
// 2. 组装VO并查询该站点最新任务
|
|
|
|
|
StationNameBoxBarcodeVO stationNameBoxBarcodeVO = new StationNameBoxBarcodeVO(); |
|
|
|
|
stationNameBoxBarcodeVO.setStation(station); |
|
|
|
|
List<Task> taskList = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getStationId, station.getId()).orderByDesc(Task::getUpdateTime)); |
|
|
|
|
if (taskList == null || taskList.size() == 0) { |
|
|
|
|
return R.data(stationNameBoxBarcodeVO); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 3. 查询最新任务关联的箱条码详情并填充VO
|
|
|
|
|
R boxbarcodeDetailsR = getBoxbarcodeDetails(taskList.get(0).getBoxBarcode()); |
|
|
|
|
if (!boxbarcodeDetailsR.isSuccess()) { |
|
|
|
|
return boxbarcodeDetailsR; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
stationNameBoxBarcodeVO.setBoxbarcodeDetailsVO((BoxbarcodeDetailsVO) boxbarcodeDetailsR.getData()); |
|
|
|
|
return R.data(stationNameBoxBarcodeVO); |
|
|
|
|
} |
|
|
|
|
@ -1198,16 +1230,23 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public R getStationRegion() { |
|
|
|
|
// 1. 查询所有空闲站点
|
|
|
|
|
List<StationVO> freeStationList = stationService.getStatusStationList(STATUS_FREE, false, null, CONVEYOR_LINE_RECEIVE_ONLY, false); |
|
|
|
|
|
|
|
|
|
// 2. 判空:无空闲站点则返回失败
|
|
|
|
|
if (freeStationList == null || freeStationList.size() == 0) { |
|
|
|
|
return R.fail("没有占用区域"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 3. 提取所有不重复的区域名称
|
|
|
|
|
List<String> stationRegionList = freeStationList.stream().map(StationVO::getStationRegion).distinct().toList(); |
|
|
|
|
|
|
|
|
|
// 4. 按区域分组组装返回数据
|
|
|
|
|
ArrayList<StationRegionVo> list = new ArrayList<>(); |
|
|
|
|
for (String stationRegion : stationRegionList) { |
|
|
|
|
StationRegionVo stationRegionVo = new StationRegionVo(); |
|
|
|
|
stationRegionVo.setStationRegion(stationRegion); |
|
|
|
|
// 过滤同区域下的站点编码并去重
|
|
|
|
|
List<String> stationList = freeStationList.stream().filter(s -> stationRegion != null && s.getStationRegion() != null && stationRegion.equals(s.getStationRegion())).map(StationVO::getStationCode).distinct().collect(Collectors.toUnmodifiableList()); |
|
|
|
|
stationRegionVo.setStationCodeList(stationList); |
|
|
|
|
list.add(stationRegionVo); |
|
|
|
|
@ -1217,12 +1256,15 @@ public class IOrderBoxServiceImpl implements IOrderBoxService { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
/** |
|
|
|
|
* 箱条码绑定主入口 |
|
|
|
|
* <p>核心流程:参数校验 → 查询已有绑定 → 作业中心一致性校验 → 区域一致性校验 → |
|
|
|
|
* 箱任务状态校验 → 订单绑定状态校验 → 重量校验 → 保存绑定关系</p> |
|
|
|
|
* |
|
|
|
|
* @param boxBinding 绑定请求参数(箱条码 + 订单卡号列表) |
|
|
|
|
* @return 绑定结果 |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public R<?> boxBinding(BoxBindingDto boxBinding) { |
|
|
|
|
log.info("【箱条码绑定】开始处理 - 绑定参数:{}", boxBinding); |
|
|
|
|
|
|
|
|
|
|