物流改写

liweidong
绫Umbrella 2 weeks ago
parent e265ba6cb3
commit 7d52aab44b
  1. 4
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/LocationMapper.xml
  2. 88
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/IOrderBoxServiceImpl.java

@ -11,11 +11,11 @@
</select> </select>
<select id="selectByStatus" resultType="org.springblade.desk.logistics.pojo.entity.Location"> <select id="selectByStatus" resultType="org.springblade.desk.logistics.pojo.entity.Location">
select id, location_name, location_code, location_status, status, create_user, create_time, create_dept, update_user, update_time, is_deleted, remark select id, location_name, location_code, location_status, status, create_user, create_time, create_dept, update_user, update_time, is_deleted, remark
from LM_LOCATION where IS_DELETED = 0 and status = #{status} and LOCATION_STATUS = 0; from LM_LOCATION where IS_DELETED = 0 and status = #{status} and LOCATION_STATUS = 0
</select> </select>
<select id="selectByLocationCode" resultType="org.springblade.desk.logistics.pojo.entity.Location"> <select id="selectByLocationCode" resultType="org.springblade.desk.logistics.pojo.entity.Location">
select id, location_name, location_code, location_status, status, create_user, create_time, create_dept, update_user, update_time, is_deleted, remark select id, location_name, location_code, location_status, status, create_user, create_time, create_dept, update_user, update_time, is_deleted, remark
from LM_LOCATION where IS_DELETED = 0 and status = #{status} and LOCATION_CODE = #{locationCode}; from LM_LOCATION where IS_DELETED = 0 and status = #{status} and LOCATION_CODE = #{locationCode}
</select> </select>
<select id="selectLocationList" resultType="org.springblade.desk.logistics.pojo.vo.LocationVO"> <select id="selectLocationList" resultType="org.springblade.desk.logistics.pojo.vo.LocationVO">
select id, location_name, location_code, location_status, status, create_user, create_time, create_dept, update_user, update_time, is_deleted, remark select id, location_name, location_code, location_status, status, create_user, create_time, create_dept, update_user, update_time, is_deleted, remark

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

Loading…
Cancel
Save