().eq("CARD_NO", cardNo).orderByDesc("UPDATE_TIME"));
@@ -106,7 +125,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
list.get(0).setActualWeighing(actualWeight);
// 执行更新并返回结果
- return iYieldOrderService.updateById(list.get(0))? R.success():R.fail("实际称重维护:卡号维护失败");
+ return iYieldOrderService.updateById(list.get(0)) ? R.success() : R.fail("实际称重维护:卡号维护失败");
}
/**
@@ -115,8 +134,8 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
*
* @param boxBinding 箱绑定参数(包含箱条码、订单ID列表、工位ID等)
* @return R> 绑定结果
- * - 成功:R.success()
- * - 失败:R.fail(),携带具体失败原因(如参数为空、订单已绑定、重量超限等)
+ * - 成功:R.success()
+ * - 失败:R.fail(),携带具体失败原因(如参数为空、订单已绑定、重量超限等)
*/
@Override
public R boxBinding(BoxBindingDto boxBinding) {
@@ -154,7 +173,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
}
// 6. 完善任务信息并保存
- task= (Task) location.getData();
+ task = (Task) location.getData();
task.setTaskStatus(Task.STATUS_START); // 设置任务初始状态为启动
task.setCreateTime(new Date()); // 设置任务创建时间
task.setCreateUser(AuthUtil.getUserId());
@@ -162,7 +181,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
boolean orderBool = boxBinding.getOrderIdList() == null || boxBinding.getOrderIdList().size() == 0;
if (orderBool) {
task.setWeight(new BigDecimal(0));
- }else {
+ } else {
task.setWeight(getWeightByOrderIdList(boxBinding.getOrderIdList()));
}
// 8. 重量校验(小于50kg才允许绑定,避免超重)
@@ -178,75 +197,245 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
// 10. 无订单则直接返回成功,有订单则执行订单绑定
if (orderBool) {
return R.success();
- }else {
- return saveOrderBindingList(task.getId(),boxBinding.getOrderIdList());
+ } else {
+ return saveOrderBindingList(task.getId(), boxBinding.getOrderIdList());
}
}
+
/**
- * 箱条码与订单解绑
- * 流程:参数校验 → 查询运行中任务 → 重置站点/库位状态 → 解绑订单 → 结束任务
+ * 释放站点并调用AGV小车接口
+ *
+ * 业务场景:任务结束后释放指定站点,根据终点类型触发不同的AGV小车调度逻辑
+ * 核心流程:
+ * 1. 校验入参和基础数据(站点、任务、终点信息)
+ * 2. 分两种场景处理AGV调度:
+ * - 场景1:仅指定终点名称(下料输送线)→ 直接调度AGV到下料线
+ * - 场景2:指定终点站点ID → 调度AGV到目标空闲站点
+ * 3. AGV调用失败时自动回滚站点状态,保证数据一致性
*
- * @param boxBarcode 箱条码
- * @return R> 解绑结果
- * - 成功:R.success()
- * - 失败:R.fail(),携带具体失败原因(如箱条码为空)
+ * @param returnToWarehouseDto 回库请求参数DTO
+ * @return 统一返回结果
+ * @throws IllegalArgumentException 入参无效、基础数据不存在时抛出
*/
@Override
- public R boxOrderUnbind(String boxBarcode) {
- // 1. 参数非空校验
- if (boxBarcode.isEmpty()) {
- log.warn("箱绑定参数为空或箱条码缺失");
- return R.fail("箱条码不能为空");
+ public R inventoryReturnToWarehouse(ReturnToWarehouseDto returnToWarehouseDto) {
+ // ========== 1. 入参和基础数据校验(前置校验,提前失败) ==========
+ // 校验DTO非空
+ Assert.notNull(returnToWarehouseDto, "回库请求参数不能为空");
+ String stationCode = returnToWarehouseDto.getStationCode();
+ Assert.hasText(stationCode, "站点编号不能为空");
+
+ // 查询站点信息(封装为方法,提升可读性)
+ Station targetStation = getStationByCode(stationCode);
+ // 查询有效任务列表
+ List validTaskList = getValidTaskList(stationCode);
+ // 校验站点状态
+ checkStationStatus(targetStation);
+ // 校验终点信息
+ checkEndLocationInfo(returnToWarehouseDto);
+
+ // ========== 2. 分场景处理AGV调度 ==========
+ try {
+ if (isDropoffConveyorLineScenario(returnToWarehouseDto)) {
+ // 场景1:仅指定下料输送线名称 → 调度AGV到下料线
+ return handleDropoffConveyorLineScenario(targetStation, validTaskList);
+ } else {
+ // 场景2:指定终点站点ID → 调度AGV到目标站点
+ return handleTargetStationScenario(targetStation, returnToWarehouseDto, validTaskList);
+ }
+ } catch (Exception e) {
+ log.error("库存回库-AGV调度异常,站点编号:{}", stationCode, e);
+ return R.fail("库存回库操作失败:" + e.getMessage());
}
+ }
- // 2. 查询该箱条码对应的运行中任务
- List taskList = iTaskService.list(
- new LambdaQueryWrapper().eq(Task::getBoxBarcode, boxBarcode).in(false,Task::getTaskStatus,RUNNING_STATUSES)
- );
+ /**
+ * 根据站点编号查询站点信息(不存在则抛异常)
+ */
+ private Station getStationByCode(String stationCode) {
+ LambdaQueryWrapper stationQuery = new LambdaQueryWrapper()
+ .eq(Station::getStationCode, stationCode);
+ List stationList = iStationService.list(stationQuery);
+
+ if (stationList == null || stationList.isEmpty()) {
+ log.warn("站点编号不存在,入参:{}", stationCode);
+ throw new IllegalArgumentException("输入站点编号不存在");
+ }
+ return stationList.get(0);
+ }
- // 3. 遍历任务,重置站点/库位状态 + 解绑订单 + 结束任务
- for (Task task : taskList) {
- // 3.1 重置站点状态为占用(释放站点)
- if (task.getStationId()!=null&&task.getStationId()!=0) {
- Station station = iStationService.getById(task.getStationId());
- station.setStationStatus(STATUS_OCCUPIED);
- iStationService.updateById(station);
- }
+ /**
+ * 查询有效任务列表(运行中状态,不存在则抛异常)
+ */
+ private List getValidTaskList(String stationCode) {
+ LambdaQueryWrapper taskQuery = new LambdaQueryWrapper()
+ .eq(Task::getBoxBarcode, stationCode)
+ .in(Task::getTaskStatus, RUNNING_STATUSES); // RUNNING_STATUSES建议抽取为常量
+ List taskList = iTaskService.list(taskQuery);
+
+ if (taskList == null || taskList.isEmpty()) {
+ log.warn("箱条码数据异常,站点编号:{}", stationCode);
+ throw new IllegalArgumentException("箱条码数据异常");
+ }
+ return taskList;
+ }
- // 3.2 重置库位状态为占用(释放库位)
- if (task.getLocationId()!=null&&task.getLocationId()!=0) {
- Location location = iLocationService.getById(task.getLocationId());
- location.setLocationStatus(STATUS_OCCUPIED);
- iLocationService.updateById(location);
+ /**
+ * 校验站点状态(必须为空闲)
+ */
+ private void checkStationStatus(Station station) {
+ if (!STATUS_FREE.equals(station.getStationStatus())) {
+ log.warn("站点被占用,站点编号:{},当前状态:{}", station.getStationCode(), station.getStationStatus());
+ throw new IllegalArgumentException("该站点正在被使用,请使用其他站点");
+ }
+ }
+
+ /**
+ * 校验终点信息(终点ID/名称不能为空)
+ */
+ private void checkEndLocationInfo(ReturnToWarehouseDto dto) {
+ Long endLocationId = dto.getEndLocationId();
+ String endName = dto.getEndName();
+
+ // 终点ID和名称都为空 → 异常
+ if ((endLocationId == null || endLocationId == 0) && (endName == null || endName.isBlank())) {
+ throw new IllegalArgumentException("请检查运送线终点,运送线终点为空");
+ }
+
+ // 仅终点ID为空 → 校验终点名称是否为下料线
+ if ((endLocationId == null || endLocationId == 0) && !DROPOFF_CONVEYOR_LINE_NAME.equals(endName)) {
+ throw new IllegalArgumentException("请检查运送线终点位置异常");
+ }
+ }
+
+ /**
+ * 判断是否为「下料输送线」场景
+ */
+ private boolean isDropoffConveyorLineScenario(ReturnToWarehouseDto dto) {
+ Long endLocationId = dto.getEndLocationId();
+ return endLocationId == null || endLocationId == 0;
+ }
+
+ /**
+ * 处理「下料输送线」场景的AGV调度
+ */
+ private R> handleDropoffConveyorLineScenario(Station targetStation, List taskList) {
+ String stationCode = targetStation.getStationCode();
+ // 1. 占用站点
+ updateStationStatus(targetStation, STATUS_OCCUPIED);
+
+ try {
+ // 2. 获取AGV任务类型并调用调度接口
+ String taskType = agvTaskTypeUtil.getTaskType(Integer.valueOf(targetStation.getStationPosition()), true);
+ boolean agvResult = iPipelineOrderBoxService.genAgvSchedulingTask(
+ taskType, stationCode, DROPOFF_CONVEYOR_LINE, EQUIPMENT_TYPE_AGV, taskList.get(0)
+ );
+
+ if (agvResult) {
+ log.info("AGV调度成功(下料线场景),站点编号:{}", stationCode);
+ return R.success();
+ } else {
+ throw new RuntimeException("调用AGV小车异常");
}
+ } catch (Exception e) {
+ // 3. AGV调用失败 → 回滚站点状态
+ updateStationStatus(targetStation, STATUS_FREE);
+ throw e;
+ }
+ }
- // 3.3 解绑订单(更新绑定状态为未绑定)
- List orderBindList = iOrderBindService.list(new LambdaQueryWrapper().eq(OrderBind::getTaskId, task.getId()));
- if (!CollectionUtils.isEmpty(orderBindList)) {
- for (OrderBind orderBind : orderBindList) {
- orderBind.setBindingStatus(STATUS_UNBINDED);
- iOrderBindService.updateById(orderBind);
- }
+ /**
+ * 处理「目标站点」场景的AGV调度
+ */
+ private R> handleTargetStationScenario(Station targetStation, ReturnToWarehouseDto dto, List taskList) {
+ String sourceStationCode = targetStation.getStationCode();
+ Long endLocationId = dto.getEndLocationId();
+
+ // 1. 查询终点空闲站点
+ Station endStation = getFreeStationByWcId(endLocationId);
+
+ // 2. 占用源站点 + 预占用终点站点
+ updateStationStatus(targetStation, STATUS_OCCUPIED);
+ updateStationStatus(endStation, PRE_STATUS_OCCUPIED);
+
+ try {
+ // 3. 获取AGV任务类型并调用调度接口
+ String taskType = agvTaskTypeUtil.getTaskType(Integer.valueOf(targetStation.getStationPosition()), false);
+ boolean agvResult = iPipelineOrderBoxService.genAgvSchedulingTask(
+ taskType, sourceStationCode, endStation.getStationCode(), EQUIPMENT_TYPE_AGV, taskList.get(0)
+ );
+
+ if (agvResult) {
+ log.info("AGV调度成功(目标站点场景),源站点:{},终点站点:{}", sourceStationCode, endStation.getStationCode());
+ return R.success();
+ } else {
+ throw new RuntimeException("调用AGV小车异常");
}
+ } catch (Exception e) {
+ // 4. AGV调用失败 → 回滚两个站点状态
+ updateStationStatus(targetStation, STATUS_FREE);
+ updateStationStatus(endStation, STATUS_FREE);
+ throw e;
+ }
+ }
-// // 3.4 结束任务(更新任务状态为已完成)
-// task.setTaskStatus(STATUS_FINISHED);
-// iTaskService.updateById(task);
+ /**
+ * 根据WCID查询空闲的终点站点(不存在则抛异常)
+ */
+ private Station getFreeStationByWcId(Long wcId) {
+ LambdaQueryWrapper endStationQuery = new LambdaQueryWrapper()
+ .eq(Station::getWcId, wcId)
+ .eq(Station::getStationStatus, STATUS_FREE);
+ List endStationList = iStationService.list(endStationQuery);
+
+ if (endStationList == null || endStationList.isEmpty()) {
+ log.warn("结束站点异常,WCID:{}", wcId);
+ throw new IllegalArgumentException("结束站点异常");
}
+ return endStationList.get(0);
+ }
- return R.success();
+ /**
+ * 统一更新站点状态(封装重复逻辑)
+ */
+ private void updateStationStatus(Station station, Integer newStatus) {
+ station.setStationStatus(newStatus);
+ boolean updateResult = iStationService.updateById(station);
+ if (!updateResult) {
+ log.error("站点状态更新失败,站点编号:{},目标状态:{}", station.getStationCode(), newStatus);
+ throw new RuntimeException("站点状态更新失败");
+ }
+ log.debug("站点状态更新成功,站点编号:{},状态:{}", station.getStationCode(), newStatus);
+ }
+
+ @Override
+ public R returnToWarehouseList() {
+ List stationList = iStationService.list(new LambdaQueryWrapper().eq(Station::getStationStatus, STATUS_FREE));
+ ArrayList bsWorkCenterVOList = new ArrayList<>();
+ BsWorkCenterVO bsWorkCenterVO = new BsWorkCenterVO();
+ bsWorkCenterVO.setWcName(DROPOFF_CONVEYOR_LINE_NAME);
+ bsWorkCenterVOList.add(bsWorkCenterVO);
+ if (!stationList.isEmpty()) {
+ List list = stationList.stream().map(Station::getWcId).distinct().collect(Collectors.toList());
+ List bwList = bsWorkCenterService.getByIds(list);
+ if (!bwList.isEmpty()) {
+ bwList.forEach(s->{bsWorkCenterVOList.add(s);});
+ }
+
+ }
+ return R.data(bsWorkCenterVOList);
}
/**
* 批量保存订单与任务的绑定关系
* 核心:创建订单绑定记录并批量插入,插入失败则回滚任务(删除已创建的任务)
*
- * @param taskId 任务ID(关联箱条码)
+ * @param taskId 任务ID(关联箱条码)
* @param orderIdList 订单ID列表
* @return R> 保存结果
- * - 成功:R.success()
- * - 失败:R.fail(),删除任务并返回异常信息
+ * - 成功:R.success()
+ * - 失败:R.fail(),删除任务并返回异常信息
*/
private R saveOrderBindingList(Long taskId, ArrayList orderIdList) {
ArrayList orderBindList = new ArrayList<>();
@@ -262,7 +451,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
// 批量插入绑定记录,失败则删除任务
if (iOrderBindService.saveBatch(orderBindList)) {
return R.success();
- }else {
+ } else {
iTaskService.removeById(taskId); // 回滚:删除已创建的任务
return R.fail("订单绑定箱条码异常");
}
@@ -292,8 +481,8 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
*
* @param task 任务对象(包含工位ID)
* @return R> 分配结果
- * - 成功:R.data(task),任务对象已填充站点/库位ID
- * - 失败:R.fail(),提示库位繁忙
+ * - 成功:R.data(task),任务对象已填充站点/库位ID
+ * - 失败:R.fail(),提示库位繁忙
*/
private R getSiteLocation(Task task) {
// 1. 查询当前工位可用的站点(状态为占用的站点)
@@ -328,8 +517,8 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
*
* @param boxBarcode 箱条码
* @return R> 校验结果
- * - 成功:R.success()(无运行中任务)
- * - 失败:R.fail()(存在运行中任务)
+ * - 成功:R.success()(无运行中任务)
+ * - 失败:R.fail()(存在运行中任务)
*/
private R checkBoxBarcodeRunningTask(String boxBarcode) {
// 查询箱条码对应的所有任务
@@ -361,8 +550,8 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
*
* @param orderIdList 订单ID列表
* @return R> 校验结果
- * - 成功:R.success()(无已绑定订单)
- * - 失败:R.fail()(存在已绑定订单,返回对应流程卡号)
+ * - 成功:R.success()(无已绑定订单)
+ * - 失败:R.fail()(存在已绑定订单,返回对应流程卡号)
*/
private R checkOrderIdBoundStatus(List orderIdList) {
// 无订单号,直接通过校验
diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/IPipelineOrderBoxServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/IPipelineOrderBoxServiceImpl.java
new file mode 100644
index 000000000..925c8d598
--- /dev/null
+++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/IPipelineOrderBoxServiceImpl.java
@@ -0,0 +1,123 @@
+package org.springblade.desk.logistics.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.core.tool.api.R;
+import org.springblade.desk.logistics.pojo.entity.Location;
+import org.springblade.desk.logistics.pojo.entity.OrderBind;
+import org.springblade.desk.logistics.pojo.entity.Station;
+import org.springblade.desk.logistics.pojo.entity.Task;
+import org.springblade.desk.logistics.service.*;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.springblade.desk.logistics.pojo.entity.OrderBind.STATUS_UNBINDED;
+import static org.springblade.desk.logistics.pojo.entity.Station.STATUS_OCCUPIED;
+
+@Service
+@Slf4j
+public class IPipelineOrderBoxServiceImpl implements IPipelineOrderBoxService {
+ /**
+ * 任务服务:处理箱绑定任务的创建、状态更新、删除等
+ */
+ private final ITaskService iTaskService;
+ /**
+ * 站点服务:处理站点状态(占用/空闲)管理
+ */
+ private final IStationService iStationService;
+
+ /**
+ * 库位服务:处理库位状态(占用/空闲)管理
+ */
+ private final ILocationService iLocationService;
+ /**
+ * 订单绑定服务:处理订单与任务的绑定关系维护
+ */
+ private final IOrderBindService iOrderBindService;
+
+ /**
+ * 任务运行中状态集合:包含任务从启动到待入库的所有中间状态
+ * 用于判断箱条码是否存在未完成的运行任务
+ */
+ private static final Set RUNNING_STATUSES = new HashSet<>();
+
+ static {
+ // 初始化运行中任务状态
+ RUNNING_STATUSES.add(Task.STATUS_START); // 任务启动
+ RUNNING_STATUSES.add(Task.STATUS_CONVEYOR_START); // 输送机启动
+ RUNNING_STATUSES.add(Task.STATUS_CONVEYOR_END); // 输送机结束
+ RUNNING_STATUSES.add(Task.STATUS_STATION); // 站点状态
+ RUNNING_STATUSES.add(Task.STATUS_LOCATION); // 库位状态
+ RUNNING_STATUSES.add(Task.STATUS_WAITING); // 等待状态
+ RUNNING_STATUSES.add(Task.STATUS_STATION_RECEIVE);// 站点接收
+ RUNNING_STATUSES.add(Task.STATUS_BACK_TO_STORAGE);// 返库状态
+ }
+
+ public IPipelineOrderBoxServiceImpl(ITaskService iTaskService, IStationService iStationService, ILocationService iLocationService, IOrderBindService iOrderBindService) {
+ this.iTaskService = iTaskService;
+ this.iStationService = iStationService;
+ this.iLocationService = iLocationService;
+ this.iOrderBindService = iOrderBindService;
+ }
+
+
+ /**
+ * 箱条码与订单解绑
+ * 流程:参数校验 → 查询运行中任务 → 重置站点/库位状态 → 解绑订单 → 结束任务
+ *
+ * @param boxBarcode 箱条码
+ * @return R> 解绑结果
+ * - 成功:R.success()
+ * - 失败:R.fail(),携带具体失败原因(如箱条码为空)
+ */
+ @Override
+ public R boxOrderUnbind(String boxBarcode) {
+ // 1. 参数非空校验
+ if (boxBarcode.isEmpty()) {
+ log.warn("箱绑定参数为空或箱条码缺失");
+ return R.fail("箱条码不能为空");
+ }
+
+ // 2. 查询该箱条码对应的运行中任务
+ List taskList = iTaskService.list(
+ new LambdaQueryWrapper().eq(Task::getBoxBarcode, boxBarcode).in(false, Task::getTaskStatus, RUNNING_STATUSES)
+ );
+
+ // 3. 遍历任务,重置站点/库位状态 + 解绑订单 + 结束任务
+ for (Task task : taskList) {
+ // 3.1 重置站点状态为占用(释放站点)
+ if (task.getStationId() != null && task.getStationId() != 0) {
+ Station station = iStationService.getById(task.getStationId());
+ station.setStationStatus(STATUS_OCCUPIED);
+ iStationService.updateById(station);
+ }
+
+ // 3.2 重置库位状态为占用(释放库位)
+ if (task.getLocationId() != null && task.getLocationId() != 0) {
+ Location location = iLocationService.getById(task.getLocationId());
+ location.setLocationStatus(STATUS_OCCUPIED);
+ iLocationService.updateById(location);
+ }
+
+ // 3.3 解绑订单(更新绑定状态为未绑定)
+ List orderBindList = iOrderBindService.list(new LambdaQueryWrapper().eq(OrderBind::getTaskId, task.getId()));
+ if (!CollectionUtils.isEmpty(orderBindList)) {
+ for (OrderBind orderBind : orderBindList) {
+ orderBind.setBindingStatus(STATUS_UNBINDED);
+ iOrderBindService.updateById(orderBind);
+ }
+ }
+
+// // 3.4 结束任务(更新任务状态为已完成)
+// task.setTaskStatus(STATUS_FINISHED);
+// iTaskService.updateById(task);
+ }
+
+ return R.success();
+ }
+
+}
diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/PipelineServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/PipelineServiceImpl.java
index 268179f86..b17bb2cbb 100644
--- a/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/PipelineServiceImpl.java
+++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/PipelineServiceImpl.java
@@ -24,6 +24,7 @@
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.desk.logistics.service.impl;
+import groovy.lang.Lazy;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.api.R;
import org.springblade.desk.logistics.constant.AgvConstant;
@@ -60,7 +61,8 @@ public class PipelineServiceImpl implements IPipelineService {
ILocationService locationService;
@Autowired
- IOrderBoxService orderBoxService;
+ IPipelineOrderBoxService iPipelineOrderBoxService;
+// IOrderBoxService orderBoxService;
@Autowired
ITaskExecuteRecordService taskExecuteRecordService;
@@ -80,7 +82,7 @@ public class PipelineServiceImpl implements IPipelineService {
taskService.savePipelineWeigh(boxBarcode,actualWeight, Task.STATUS_RETURNED);
// 3.超重处理,解绑
- R ret = orderBoxService.boxOrderUnbind(boxBarcode);
+ R ret = iPipelineOrderBoxService.boxOrderUnbind(boxBarcode);
if(!ret.isSuccess()){
throw new ServiceException("解绑失败: "+boxBarcode);
}
diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/utils/AgvTaskTypeUtil.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/utils/AgvTaskTypeUtil.java
index 4a9da47f3..6ca253d38 100644
--- a/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/utils/AgvTaskTypeUtil.java
+++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/utils/AgvTaskTypeUtil.java
@@ -15,7 +15,7 @@ public class AgvTaskTypeUtil {
* @param isRecycle 是否回收 (true:空箱回收, false:正常任务)
* @return 任务类型 (QM3, QM5, QM6, QM7)
*/
- public String getTaskType(Integer floor, Boolean isRecycle) {
+ public String getTaskType(Integer floor, Boolean isRecycle) {
// 参数校验
if (floor == null) {
log.error("楼层参数不能为空");
diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/utils/CollectionCheckUtil.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/utils/CollectionCheckUtil.java
new file mode 100644
index 000000000..94a32736a
--- /dev/null
+++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/utils/CollectionCheckUtil.java
@@ -0,0 +1,36 @@
+package org.springblade.desk.logistics.utils;
+
+import java.util.Collection;
+import java.util.Map;
+
+public class CollectionCheckUtil {
+ /**
+ * 判断指定字段的值是否存在于目标集合中
+ *
+ * @param fieldValue 要校验的字段参数值
+ * @param targetCollection 目标集合(List、Set、Map等)
+ * @param 字段值的类型(泛型适配任意类型)
+ * @return 存在返回true,不存在返回false
+ * @throws IllegalArgumentException 当目标集合为空或类型不支持时抛出异常
+ */
+ public static boolean isFieldInCollection(T fieldValue, Object targetCollection) {
+ // 健壮性校验
+ if (targetCollection == null) {
+ throw new IllegalArgumentException("目标集合不能为空");
+ }
+
+ // 处理Collection类型(List、Set等)
+ if (targetCollection instanceof Collection) {
+ return ((Collection>) targetCollection).contains(fieldValue);
+ }
+
+ // 处理Map类型(判断key是否存在)
+ if (targetCollection instanceof Map) {
+ return ((Map, ?>) targetCollection).containsKey(fieldValue);
+ }
+
+ // 不支持的集合类型
+ throw new IllegalArgumentException("不支持的集合类型:" + targetCollection.getClass().getName());
+ }
+
+}