代码修改

liweidong
绫Umbrella 1 month ago
parent 8422f6ca0d
commit c9b50abb14
  1. 5
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/entity/Location.java
  2. 9
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/entity/Station.java
  3. 63
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/IOrderBoxServiceImpl.java
  4. 2
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/OrderBindServiceImpl.java
  5. 16
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/TaskExecuteRecordServiceImpl.java
  6. 91
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/utils/CollectionCheckUtil.java

@ -38,7 +38,10 @@ public class Location extends BaseEntity {
*/
public static final Integer STATUS_FREE = 0;
/**
* 状态常量初始架
*/
public static final Integer ORIGINAL_RACK = 1;
/**
* 库名称
*/

@ -37,6 +37,15 @@ public class Station extends BaseEntity {
*/
public static final Integer PRE_STATUS_OCCUPIED = 2;
/**
* 状态常量收发-只收
*/
public static final Integer RECEIVE_ONLY = 0;
/**
* 状态常量收发-同层
*/
public static final Integer SAME_LAYER = 2;
/**
* 取货输送线 站点类型常量
*/

@ -26,8 +26,9 @@ import java.util.*;
import java.util.stream.Collectors;
import static org.springblade.desk.logistics.constant.AgvConstant.EQUIPMENT_TYPE_AGV;
import static org.springblade.desk.logistics.pojo.entity.Location.ORIGINAL_RACK;
import static org.springblade.desk.logistics.pojo.entity.Station.*;
import static org.springblade.desk.logistics.utils.CollectionCheckUtil.findNotExistInBByStream;
import static org.springblade.desk.logistics.utils.CollectionCheckUtil.*;
/**
* 订单箱业务实现类
@ -111,6 +112,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
private final ITaskExecuteRecordService taskExecuteRecordService;
// ========================== 构造器注入 ==========================
/**
* 构造器注入依赖Spring官方推荐避免@Autowired耦合
*
@ -248,6 +250,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
log.warn("【箱条码绑定】{}", errorMsg);
return R.fail(errorMsg + ",请重新进行绑定");
}
// 6.
// 6. 保存绑定关系
return saveOrderBoxBinding(boxBarcode, new ArrayList<>(orderIdList));
@ -257,7 +260,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
* 查询回库可选工位列表
* <p>查询空闲状态的站点关联工位默认添加输送线回库选项</p>
*
* @return R<List<BsWorkCenterVO>> 工位VO列表含默认输送线选项
* @return R<List < BsWorkCenterVO>> 工位VO列表含默认输送线选项
*/
@Override
public R<List<BsWorkCenterVO>> returnToWarehouseList() {
@ -401,7 +404,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
endStationCode = DROPOFF_CONVEYOR_LINE;
} else {
// 5.2 普通工位回库:分配站点/库位
R<?> locationResult = allocateSiteOrLocation(task);
R<?> locationResult = allocateSiteOrLocation(startStationCode, task);
if (!locationResult.isSuccess()) {
return locationResult;
}
@ -518,6 +521,15 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
List<String> notExistList = findNotExistInBByStream(yieldOrderList, orderCardNoList);
return R.fail("以下订单未知:" + notExistList);
}
//判断wcid是否一致
boolean allFieldSame = isAllFieldSame(yieldOrderList, YieldOrder::getWorkCenterId);
if (!allFieldSame) {
return R.fail("订单所属的作业中心不一致");
}
if (yieldOrderList.get(0).getWorkCenterId() == null) {
return R.fail("订单所属的作业中心不能为空");
}
return R.data(yieldOrderList);
}
@ -595,7 +607,11 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
}
// 校验站点是否空闲
if (!stationList.get(0).getStationStatus().equals(STATUS_FREE)) {
return R.fail("站点非空闲状态,无法使用");
return R.fail("起始站点非空闲状态,无法使用");
}
// 校验站点是否可以发送数据
if (stationList.get(0).getStatus().equals(RECEIVE_ONLY)) {
return R.fail("起始站点站码无法当开始站点编码");
}
return R.data(startStationCode);
} else {
@ -648,18 +664,33 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
/**
* 分配站点/库位资源优先级站点 库位
*
* @param task 任务对象含工位ID
* @param startStationCode
* @param task 任务对象含工位ID
* @return R<Task> 分配后的任务对象
*/
private R<Task> allocateSiteOrLocation(Task task) {
private R<Task> allocateSiteOrLocation(String startStationCode, Task task) {
// 1. 尝试分配空闲站点
List<Station> freeStationList = stationService.list(
new LambdaQueryWrapper<Station>()
.eq(Station::getWcId, task.getWcId())
.eq(Station::getStationStatus, STATUS_FREE)
);
if (!CollectionUtils.isEmpty(freeStationList)) {
Station station = freeStationList.get(0);
Station station = null;
String stationPosition = "";
if (station.getStatus() == SAME_LAYER) {
Station startStation = stationService.list(new LambdaQueryWrapper<Station>().eq(Station::getStationCode, startStationCode)).get(0);
stationPosition = startStation.getStationPosition();
station = findByField(freeStationList, "stationPosition", stationPosition);
} else {
station = freeStationList.get(0);
}
if (station == null) {
return R.fail("当前班次" + stationPosition + "楼层库位繁忙,请空闲后再试");
}
task.setStationId(station.getId());
// 锁定站点(预占用)
station.setStationStatus(PRE_STATUS_OCCUPIED);
@ -670,7 +701,9 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
// 2. 尝试分配空闲库位
List<Location> freeLocationList = locationService.list(
new LambdaQueryWrapper<Location>().eq(Location::getLocationStatus, STATUS_FREE)
new LambdaQueryWrapper<Location>()
.ne(Location::getStatus, ORIGINAL_RACK)
.eq(Location::getLocationStatus, STATUS_FREE)
);
if (!CollectionUtils.isEmpty(freeLocationList)) {
Location location = freeLocationList.get(0);
@ -693,8 +726,8 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
/**
* 校验结束站点状态
*
* @param task 任务对象
* @param agvSend 是否发送AGV
* @param task 任务对象
* @param agvSend 是否发送AGV
* @return R<String> 结束站点编码成功/错误信息失败
*/
private R<?> validateEndStationStatus(Task task, Boolean agvSend) {
@ -710,6 +743,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
locationService.updateById(location);
log.info("【资源释放】库位{}已释放", location.getId());
}
taskService.removeById(task);
return R.fail("结束站点被占用");
}
return R.data("");
@ -717,6 +751,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
// 有站点ID:校验站点存在性并锁定
Station station = stationService.getById(task.getStationId());
if (Objects.isNull(station)) {
taskService.removeById(task);
return R.fail("结束站点不存在");
}
// 锁定站点(预占用)- 修复原代码空指针问题(先判空再更新)
@ -746,7 +781,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
List<OrderBind> bindList = orderBindService.list(
new LambdaQueryWrapper<OrderBind>()
.eq(OrderBind::getBoxBarcode, boxBarcode)
.eq(false, OrderBind::getBindingStatus, OrderBind.STATUS_UNBINDED)
.ne(OrderBind::getBindingStatus, OrderBind.STATUS_UNBINDED)
);
log.info("【任务重量计算】箱{}绑定订单列表:{}", boxBarcode, bindList);
@ -787,12 +822,18 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
} else {
// 调度失败:回滚任务
taskService.removeById(task);
List<Station> stationList = stationService.list(new LambdaQueryWrapper<Station>().eq(Station::getId, task.getStationId()));
stationList.get(0).setStationStatus(STATUS_FREE);
stationService.updateById(stationList.get(0));
log.error("【AGV调度】任务{}调度失败,已回滚", task.getId());
return R.fail("AGV小车调用异常");
}
} catch (Exception e) {
// 异常处理:回滚任务
taskService.removeById(task);
List<Station> stationList = stationService.list(new LambdaQueryWrapper<Station>().eq(Station::getId, task.getStationId()));
stationList.get(0).setStationStatus(STATUS_FREE);
stationService.updateById(stationList.get(0));
log.error("【AGV调度】任务{}调度异常,已回滚", task.getId(), e);
return R.fail("AGV小车调用异常:" + e.getMessage());
}

@ -119,7 +119,7 @@ public class OrderBindServiceImpl extends BaseServiceImpl<OrderBindMapper, Order
// 优化:查询条件优化(eq(false)改为动态条件,语义更清晰)
List<OrderBind> orderBindList = list(new LambdaQueryWrapper<OrderBind>()
.eq(OrderBind::getBoxBarcode, boxBarcode)
.eq(false,OrderBind::getBindingStatus, STATUS_UNBINDED));
.ne(OrderBind::getBindingStatus, STATUS_UNBINDED));
// 优化:提示信息更精准
if (orderBindList.isEmpty()) {

@ -151,18 +151,30 @@ public class TaskExecuteRecordServiceImpl extends BaseServiceImpl<TaskExecuteRe
//状态为暂存 需要调用
if(Task.STATUS_TEMPORARY_STORAGE.equals(task.getTaskStatus())){
//判断是否需要调用agv接口
containerToAgv(agvCallBack.getTaskCode());
boolean conAgvReturn = containerToAgv(agvCallBack.getTaskCode());
log.info("AGV小车接口调用返回值:{}",conAgvReturn);
if (!conAgvReturn) {
return R.fail("AGV小车接口调用失败");
}
}
if(Task.STATUS_CONVEYOR_END.equals(task.getTaskStatus())){
//判断是否需要调用ctu接口
containerToCtu(agvCallBack.getTaskCode());
boolean conCtuReturn =containerToCtu(agvCallBack.getTaskCode());
log.info("CTU小车接口调用返回值:{}",conCtuReturn);
if (!conCtuReturn) {
return R.fail("CTU小车接口调用失败");
}
}
}
// 回调处理成功
log.info("AGV回调成功:任务单号{}的执行记录已更新,状态为{}", agvCallBack.getTaskCode(), method);
return R.success();
R r = new R();
r.setCode(0);
r.setMsg("操作成功");
return r;
}

@ -4,10 +4,48 @@ import cn.hutool.db.sql.Order;
import org.springblade.desk.order.pojo.entity.YieldOrder;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class CollectionCheckUtil {
/**
* 通用方法判断实体集合中指定字段的值是否全部一致
* @param entityList 实体集合
* @param fieldExtractor 字段获取器用于提取要判断的字段值
* @param <T> 实体类型
* @param <V> 字段值类型
* @return true=全部一致 / false=存在不一致 / 空集合/单元素集合返回true
*/
public static <T, V> boolean isAllFieldSame(List<T> entityList, Function<T, V> fieldExtractor) {
// 1. 边界校验:空集合或单元素集合,默认一致
if (CollectionUtils.isEmpty(entityList) || entityList.size() == 1) {
return true;
}
// 2. 校验字段获取器非空
if (fieldExtractor == null) {
throw new IllegalArgumentException("字段获取器不能为空");
}
// 3. 取第一个元素的字段值作为基准
V baseValue = fieldExtractor.apply(entityList.get(0));
// 4. 遍历所有元素,对比字段值
for (T entity : entityList) {
V currentValue = fieldExtractor.apply(entity);
// Objects.equals自动处理null值对比(null == null 返回true)
if (!Objects.equals(baseValue, currentValue)) {
return false;
}
}
return true;
}
/**
* 判断指定字段的值是否存在于目标集合中
*
@ -62,4 +100,57 @@ public class CollectionCheckUtil {
.collect(Collectors.toList());
}
/**
* 从实体类集合中查找指定属性等于指定值的对象
* @param collection 实体类集合
* @param fieldName 要匹配的属性名注意区分大小写要和实体类中的属性名一致
* @param value 要匹配的属性值
* @param <T> 实体类泛型
* @return 匹配的对象未找到则返回 null
*/
public static <T> T findByField(Collection<T> collection, String fieldName, Object value) {
// 空值校验
if (collection == null || collection.isEmpty() || fieldName == null || fieldName.isEmpty()) {
return null;
}
// 遍历集合中的每个对象
for (T obj : collection) {
if (obj == null) {
continue;
}
try {
// 通过反射获取属性(包括私有属性)
Field field = obj.getClass().getDeclaredField(fieldName);
// 设置可访问私有属性
field.setAccessible(true);
// 获取对象的该属性值
Object fieldValue = field.get(obj);
// 匹配属性值(处理 null 值的情况)
if (value == null) {
if (fieldValue == null) {
return obj; // 属性值和目标值都为 null,匹配成功
}
} else {
if (value.equals(fieldValue)) {
return obj; // 属性值匹配成功,返回该对象
}
}
} catch (NoSuchFieldException e) {
// 属性名不存在,抛出明确的异常提示
throw new IllegalArgumentException("实体类中不存在属性:" + fieldName, e);
} catch (IllegalAccessException e) {
// 属性访问失败
throw new RuntimeException("无法访问属性:" + fieldName, e);
}
}
// 遍历完未找到匹配的对象,返回 null
return null;
}
}

Loading…
Cancel
Save