物流改写

liweidong
绫Umbrella 2 weeks ago
parent 955f244812
commit 36ab949f17
  1. 5
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/entity/Task.java
  2. 9
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/controller/PipelineController.java
  3. 2
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/StationMapper.java
  4. 7
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/StationMapper.xml
  5. 17
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/IOrderBoxService.java
  6. 2
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/IStationService.java
  7. 122
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/IOrderBoxServiceImpl.java
  8. 4
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/StationServiceImpl.java
  9. 3
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/StorageMonitoringServiceImpl.java

@ -119,6 +119,11 @@ public class Task extends BaseEntity {
*/
@Schema(description = "备注")
private String remark;
/**
* 站点区域
*/
@Schema(description = "站点区域")
private String stationRegion;
public static String getStatusName(Integer taskStatus) {
String name="";

@ -47,6 +47,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;
/**
@ -82,11 +84,12 @@ public class PipelineController extends BladeController {
ReturnToWarehouseDto returnToWarehouseDto = new ReturnToWarehouseDto();
returnToWarehouseDto.setBoxBarcode(boxBarcode);
R wcIdR = iOrderBoxService.getWcId(boxBarcode);
Long wcId = (Long) wcIdR.getData();
if (wcId==null) {
LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) wcIdR.getData();
if (map==null) {
return R.fail("未查询到该箱条码的作业中心");
}
returnToWarehouseDto.setEndWcId(wcId);
returnToWarehouseDto.setEndWcId((Long) map.get("wcId"));
returnToWarehouseDto.setStationRegion((String) map.get("stationRegion"));
R taskR = iOrderBoxService.saveTask(returnToWarehouseDto, false);
if (!taskR.isSuccess()) {
return taskR;

@ -16,5 +16,5 @@ public interface StationMapper extends BaseMapper<Station> {
List<StationVO> selectStationList(IPage<StationVO> page, @Param("station") Station station);
List<StationVO> getStatusStationList(@Param("stationStatus")Integer stationStatus, @Param("wcId")Long wcId,@Param("status")Integer status, @Param("include")boolean include);
List<StationVO> getStatusStationList(@Param("stationStatus")Integer stationStatus,@Param("stationStatusInclude") boolean stationStatusInclude, @Param("wcId")Long wcId, @Param("status")Integer status, @Param("include")boolean include);
}

@ -44,7 +44,12 @@
where l.IS_DELETED = 0
<if test="stationStatus != null and stationStatus != ''">
and l.STATION_STATUS = #{stationStatus}
<if test="stationStatusInclude">
and l.STATION_STATUS = #{stationStatus}
</if>
<if test="!stationStatusInclude">
and l.STATION_STATUS != #{stationStatus}
</if>
</if>
<if test="wcId != null and wcId != ''">
and r.WC_ID = #{wcId}

@ -20,11 +20,11 @@ public interface IOrderBoxService {
* 维护订单配件重量
* 功能根据卡号cardNo更新对应订单配件的实际重量信息
*
* @param cardNo 配件卡号/标识唯一标识需要更新重量的订单配件
* @param cardNo 配件卡号/标识唯一标识需要更新重量的订单配件
* @param actualWeight 实际称重的重量值精度由业务场景决定如千克/
* @return R<?> 通用返回结果
* - 成功R.success()可携带更新成功的提示信息或数据
* - 失败R.fail()携带具体的失败原因如卡号不存在重量非法等
* - 成功R.success()可携带更新成功的提示信息或数据
* - 失败R.fail()携带具体的失败原因如卡号不存在重量非法等
*/
R upholdOrderPartWeight(String cardNo, BigDecimal actualWeight);
@ -34,26 +34,27 @@ public interface IOrderBoxService {
*
* @param boxBinding 箱绑定实体类包含箱条码订单ID列表任务ID等核心绑定信息
* @return R<?> 通用返回结果
* - 成功R.success()携带绑定成功的提示或绑定记录数
* - 失败R.fail()携带失败原因如箱条码不存在订单已绑定唯一约束冲突等
* - 成功R.success()携带绑定成功的提示或绑定记录数
* - 失败R.fail()携带失败原因如箱条码不存在订单已绑定唯一约束冲突等
*/
R boxBinding(BoxBindingDto boxBinding);
R returnToWarehouseList();
R receive(String stationCode) throws BusinessException;
R saveTask(ReturnToWarehouseDto returnToWarehouseDto,Boolean agvSend);
R saveTask(ReturnToWarehouseDto returnToWarehouseDto, Boolean agvSend);
R getWcId(String boxBarcode);
R getQuantityLocation(String boxBarcode);
R getBoxbarcodeDetails(String boxBarcode);
R getStationNameBoxBarcode(String stationCode);
R getStationRegion();
}

@ -72,5 +72,5 @@ public interface IStationService extends BaseService<Station> {
*/
boolean updateStation(Station station);
List<StationVO> getStatusStationList(Integer stationStatus, Long wcId,Integer status, boolean include);
List<StationVO> getStatusStationList(Integer stationStatus, boolean stationStatusInclude, Long wcId,Integer status, boolean include);
}

@ -243,7 +243,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
// 1. 查询空闲状态的站点
List<StationVO> freeStationList = stationService.getStatusStationList(STATUS_FREE, null,CONVEYOR_LINE_RECEIVE_ONLY,false);
List<StationVO> freeStationList = stationService.getStatusStationList(STATUS_FREE, true,null, CONVEYOR_LINE_RECEIVE_ONLY, false);
// 2. 构建返回列表(默认添加输送线回库选项)
List<BsWorkCenterVO> resultList = new ArrayList<>();
BsWorkCenterVO conveyorVO = new BsWorkCenterVO();
@ -254,10 +254,10 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
// 3. 补充空闲站点关联的工位信息
if (!CollectionUtils.isEmpty(freeStationList)) {
List<Long> wcIdList = freeStationList.stream()
.map( StationVO::getWcId)
.map(StationVO::getWcId)
.distinct()
.collect(Collectors.toList());
List<BsWorkCenterVO> wcVOList = bsWorkCenterService.getByIds(wcIdList,freeStationList);
List<BsWorkCenterVO> wcVOList = bsWorkCenterService.getByIds(wcIdList, freeStationList);
if (!CollectionUtils.isEmpty(wcVOList)) {
resultList.addAll(wcVOList);
log.info("【回库工位查询】查询到{}个空闲工位", wcVOList.size());
@ -350,7 +350,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
Task task = new Task();
// 3. 处理起始站点编码
R<?> startStationResult = handleStartStationCode(returnToWarehouseDto,agvSend);
R<?> startStationResult = handleStartStationCode(returnToWarehouseDto, agvSend);
if (!startStationResult.isSuccess()) {
return startStationResult;
}
@ -371,6 +371,9 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
// 5. 设置结束工位ID并处理不同回库类型
Long endWcId = returnToWarehouseDto.getEndWcId();
task.setWcId(endWcId);
if (!returnToWarehouseDto.getStationRegion().isEmpty()) {
task.setStationRegion(returnToWarehouseDto.getStationRegion());
}
if (endWcId == 0) {
// 5.1 输送线回库:校验空箱数量
// R<?> conveyorCheckResult = checkConveyorEmptyBoxCount();
@ -381,7 +384,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
endStationCode = DROPOFF_CONVEYOR_LINE;
} else {
// 5.2 普通工位回库:分配站点/库位
R<?> locationResult = allocateSiteOrLocation(startStationCode, task,agvSend);
R<?> locationResult = allocateSiteOrLocation(returnToWarehouseDto, task, agvSend);
if (!locationResult.isSuccess()) {
return locationResult;
}
@ -408,6 +411,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
// 8. 发送AGV调度任务(可选)
if (agvSend) {
R<?> reult = sendAgvSchedulingTask(task, startStationCode, endStationCode);
if (!reult.isSuccess()) {
taskService.removeById(task);
}
@ -430,7 +434,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
* </ul>
*/
@Override
public R<Long> getWcId(String boxBarcode) {
public R<LinkedHashMap<String, Object>> getWcId(String boxBarcode) {
log.info("【工位ID查询】开始处理 - 箱条码:{}", boxBarcode);
// 1. 参数校验
@ -449,17 +453,25 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
log.warn("【工位ID查询】箱条码{}未绑定任何订单", boxBarcode);
return R.fail("该箱子没有绑定数据");
}
Long wcID = orderBindList.get(0).getWcID();
BsWorkCenterEntity workCenter = bsWorkCenterService.getById(wcID);
// 3. 查询工位ID
// Long orderId = orderBindList.get(0).getOrderId();
// Long wcId = yieldOrderService.getWcId(orderId);
// log.info("【工位ID查询】箱条码{}对应的工位ID:{}", boxBarcode, wcId);
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put("wcId",wcID);
if (DistinguishRegionsEnum.includeByWcName(workCenter.getWcName())) {
String useDept = yieldOrderService.list(new LambdaQueryWrapper<YieldOrder>().eq(YieldOrder::getCardNo, orderBindList.get(0).getCardNo())).get(0).getUseDept();
String code = DistinguishRegionsEnum.wcNameByCode(workCenter.getWcName());
String logisticsAnagementRegion = DictCache.getValue(code, useDept);
map.put("stationRegion",logisticsAnagementRegion);
return R.data(orderBindList.get(0).getWcID());
}else {
List<StationVO> statusStationList = stationService.getStatusStationList(STATUS_FREE, true,wcID, CONVEYOR_LINE_RECEIVE_ONLY, false);
map.put("stationRegion",statusStationList.get(0).getStationRegion());
}
return R.data(map);
}
// ========================== 私有工具方法 ==========================
/**
@ -537,6 +549,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* 计算订单列表总重量
* <p>累加订单的实际称重值过滤null值初始值为0</p>
@ -565,7 +578,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
* @param orderIdList 订单ID列表
* @return R<?> 保存结果
*/
private R<?> saveOrderBoxBinding(String boxBarcode, ArrayList<String> orderIdList,Long wcId) {
private R<?> saveOrderBoxBinding(String boxBarcode, ArrayList<String> orderIdList, Long wcId) {
if (CollectionUtils.isEmpty(orderIdList)) {
return R.fail("订单id不能为空");
}
@ -609,15 +622,15 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
if (CollectionUtils.isEmpty(stationList)) {
return R.fail("站点编码不存在");
}
// 校验站点是否空闲
if (!stationList.get(0).getStationStatus().equals(STATUS_FREE)) {
return R.fail("起始站点非空闲状态,无法使用");
}
// // 校验站点是否空闲
// if (!stationList.get(0).getStationStatus().equals(STATUS_FREE)) {
// return R.fail("起始站点非空闲状态,无法使用");
// }
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("起始站点站码无法当开始站点编码");
}else if (!stationList.get(0).getStatus().equals(CONVEYOR_LINE_RECEIVE_ONLY)&&!agvSend) {
} else if (!stationList.get(0).getStatus().equals(CONVEYOR_LINE_RECEIVE_ONLY) && !agvSend) {
return R.fail("起始站点站码无法当开始站点编码");
}
return R.data(startStationCode);
@ -671,26 +684,29 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
/**
* 分配站点/库位资源优先级站点 库位
*
* @param startStationCode
* @param task 任务对象含工位ID
* @param returnToWarehouseDto
* @param task 任务对象含工位ID
* @param agvSend
* @return R<Task> 分配后的任务对象
*/
private R<Task> allocateSiteOrLocation(String startStationCode, Task task, Boolean agvSend) {
private R<Task> allocateSiteOrLocation(ReturnToWarehouseDto returnToWarehouseDto, Task task, Boolean agvSend) {
// 1. 尝试分配空闲站点
// List<Station> freeStationList = stationService.list(
// new LambdaQueryWrapper<Station>()
// .eq(Station::getWcId, task.getWcId())
// .eq(Station::getStationStatus, STATUS_FREE)
// );
List<StationVO> freeStationList =null;
List<StationVO> freeStationList = null;
if (agvSend) {
freeStationList=stationService.getStatusStationList(STATUS_FREE, task.getWcId(), CONVEYOR_LINE_RECEIVE_ONLY, false);
}else {
freeStationList=stationService.getStatusStationList(STATUS_FREE, task.getWcId(), STATION_RECEIVE_ONLY, false);
}
freeStationList = stationService.getStatusStationList(STATUS_FREE, true,task.getWcId(), CONVEYOR_LINE_RECEIVE_ONLY, false);
} else {
freeStationList = stationService.getStatusStationList(STATUS_FREE, true,task.getWcId(), STATION_RECEIVE_ONLY, false);
}
String wcName = bsWorkCenterService.getById(task.getWcId()).getWcName();
if (freeStationList!=null&&freeStationList.size()!=0) {
//判断是不是镀后库作业中心
if (DistinguishRegionsEnum.includeByWcName(wcName)&&!agvSend) {
log.info("是读后库");
freeStationList=freeStationList.stream().filter(s->s.getStationRegion().equals(task.getStationRegion())).toList();
}
if (!CollectionUtils.isEmpty(freeStationList)) {
}
if (freeStationList!=null&&freeStationList.size()!=0) {
StationVO station = null;
station = freeStationList.get(0);
task.setStationId(station.getId());
@ -939,7 +955,6 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
}
@Override
public R getQuantityLocation(String boxBarcode) {
// 1. 校验箱条码非空(增加空白字符校验)
@ -969,13 +984,14 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
}
quantityLocationVO.setWcName(workCenter.getWcName());
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("获取站点区域有问题");
}
List<Station> stationList = stationService.list(new LambdaQueryWrapper<Station>().eq(Station::getId, stationCenterList.get(0).getStationId()));
quantityLocationVO.setStationRegion(stationList.get(0).getStationRegion());
return R.data(quantityLocationVO);
}
@Override
public R getBoxbarcodeDetails(String boxBarcode) {
if (StringUtils.isBlank(boxBarcode)) {
@ -1040,12 +1056,16 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
new LambdaQueryWrapper<StationCenter>().eq(StationCenter::getWcId, wcId)
);
if (stationCenterList!=null||stationCenterList.size()!=0) {
StationCenter stationCenter = stationCenterList.get(0);
Station station = stationService.getById(stationCenter.getStationId());
if (station != null) {
detailsVO.setStationRegion(station.getStationRegion());
if (stationCenterList != null || stationCenterList.size() > 0) {
// StationCenter stationCenter = stationCenterList.get(0);
// Station station = stationService.getById(stationCenter.getStationId());
List<Long> stationIdList = stationCenterList.stream().map(s -> s.getStationId()).toList();
List<Station> stationList = stationService.list(new LambdaQueryWrapper<Station>().in(Station::getId, stationIdList));
List<String> list = stationList.stream().map(s -> s.getStationRegion()).distinct().toList();
if (list.size()==1) {
detailsVO.setStationRegion(stationList.get(0).getStationRegion());
}
}
return R.data(detailsVO);
@ -1061,7 +1081,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
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) {
if (taskList == null || taskList.size() == 0) {
return R.data(stationNameBoxBarcodeVO);
}
R boxbarcodeDetailsR = getBoxbarcodeDetails(taskList.get(0).getBoxBarcode());
@ -1075,8 +1095,12 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
@Override
public R getStationRegion() {
List<StationVO> freeStationList = stationService.getStatusStationList(STATUS_FREE, null,CONVEYOR_LINE_RECEIVE_ONLY,false);
List<String> stationRegionList = freeStationList.stream().map(StationVO::getStationRegion).distinct().collect(Collectors.toUnmodifiableList());
List<StationVO> freeStationList = stationService.getStatusStationList(STATUS_FREE,false, null, CONVEYOR_LINE_RECEIVE_ONLY, false);
if (freeStationList==null||freeStationList.size()==0) {
return R.fail("没有占用区域");
}
List<String> stationRegionList = freeStationList.stream().map(StationVO::getStationRegion).distinct().toList();
ArrayList<StationRegionVo> list = new ArrayList<>();
for (String stationRegion : stationRegionList) {
StationRegionVo stationRegionVo = new StationRegionVo();
@ -1091,6 +1115,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
@Override
/**
* 箱条码绑定主入口
@ -1134,16 +1159,16 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
wcId = (Long) checkResult.getData();
}
//判断是不是镀后库作业中心
if(DistinguishRegionsEnum.includeByWcName( bsWorkCenterService.getById(wcId).getWcName())){
if (DistinguishRegionsEnum.includeByWcName(bsWorkCenterService.getById(wcId).getWcName())) {
List<String> deptList = yieldOrderService.list(new LambdaQueryWrapper<YieldOrder>().in(YieldOrder::getCardNo, orderBindList)).stream().map(s -> s.getUseDept()).toList();
String code = DistinguishRegionsEnum.wcNameByCode(bsWorkCenterService.getById(wcId).getWcName());
String stationRegion="";
String stationRegion = "";
for (String s : deptList) {
String logisticsAnagementRegion = DictCache.getValue(code, s);
if (logisticsAnagementRegion==null) {
if (logisticsAnagementRegion == null) {
return R.fail("站点区域异常");
}else if (stationRegion==null) {
stationRegion= logisticsAnagementRegion;
} else if (stationRegion == null) {
stationRegion = logisticsAnagementRegion;
}
if (!stationRegion.equals(logisticsAnagementRegion)) {
return R.fail("站点区域异常,站点区域配送不统一");
@ -1262,6 +1287,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
// 未找到任何订单
return R.fail(orderCardNo + "车间订单异常");
}
/**
* 统一校验作业中心空值校验 + 一致性校验
*/

@ -118,8 +118,8 @@ public class StationServiceImpl extends BaseServiceImpl<StationMapper, Station>
}
@Override
public List<StationVO> getStatusStationList(Integer stationStatus, Long wcId,Integer status, boolean include) {
return baseMapper.getStatusStationList(stationStatus,wcId,status,include);
public List<StationVO> getStatusStationList(Integer stationStatus, boolean stationStatusInclude, Long wcId,Integer status, boolean include) {
return baseMapper.getStatusStationList(stationStatus,stationStatusInclude,wcId,status,include);
}
}

@ -100,7 +100,7 @@ public class StorageMonitoringServiceImpl implements IStorageMonitoringService {
// new LambdaQueryWrapper<Station>()
// .eq(Station::getStationStatus, Station.STATUS_FREE) // 筛选条件:站点状态为空闲
// );
List<StationVO> stationList = stationService.getStatusStationList(Station.STATUS_FREE, null, null, false);
List<StationVO> stationList = stationService.getStatusStationList(Station.STATUS_FREE, true,null, null, false);
// 日志打印空闲站点数量,便于监控和问题排查
log.info("【仓储监控】定时任务执行 - 查询到空闲站点数量:{}", stationList == null ? 0 : stationList.size());
@ -126,6 +126,7 @@ public class StorageMonitoringServiceImpl implements IStorageMonitoringService {
new LambdaQueryWrapper<Task>()
.eq(Task::getTaskStatus, Task.STATUS_TEMPORARY_STORAGE) // 任务状态:待库位
.eq(Task::getWcId, station.getWcId()) // 匹配当前站点的工位ID
.eq(Task::getStationRegion,station.getStationRegion())
.notIn(taskIdList!=null&&taskIdList.size()!=0,Task::getId,taskIdList)
.orderByAsc(Task::getCreateTime) // 按创建时间升序,优先处理最早创建的任务
);

Loading…
Cancel
Save