parent
aa1fbd06bd
commit
e79bded7f2
7 changed files with 300 additions and 185 deletions
@ -0,0 +1,277 @@ |
||||
package org.springblade.desk.logistics.service.impl; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springblade.core.tool.api.R; |
||||
import org.springblade.desk.logistics.pojo.entity.*; |
||||
import org.springblade.desk.logistics.service.*; |
||||
import org.springblade.desk.order.pojo.entity.YieldOrder; |
||||
import org.springblade.desk.order.service.IYieldOrderService; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.util.CollectionUtils; |
||||
|
||||
import java.math.BigDecimal; |
||||
import java.util.*; |
||||
import java.util.stream.Collectors; |
||||
|
||||
import static org.springblade.desk.logistics.pojo.entity.OrderBind.STATUS_UNBINDED; |
||||
import static org.springblade.desk.logistics.pojo.entity.Station.STATUS_OCCUPIED; |
||||
import static org.springblade.desk.logistics.pojo.entity.Task.STATUS_FINISHED; |
||||
|
||||
/** |
||||
* 订单箱子 控制器 |
||||
* |
||||
* @author qyl |
||||
* @since 2026-01-08 |
||||
*/ |
||||
@Service |
||||
@Slf4j |
||||
public class IOrderBoxServiceImpl implements IOrderBoxService { |
||||
private final IYieldOrderService iYieldOrderService; |
||||
private final ITaskService iTaskService; |
||||
private final IOrderBindService iOrderBindService; |
||||
private final IStationService iStationService; |
||||
private final ILocationService iLocationService; |
||||
|
||||
|
||||
|
||||
private static final Set<Integer> 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 IOrderBoxServiceImpl(IYieldOrderService iYieldOrderService, ITaskService iTaskService, IOrderBindService iOrderBindService, IStationService iStationService, ILocationService iLocationService) { |
||||
this.iYieldOrderService = iYieldOrderService; |
||||
this.iTaskService = iTaskService; |
||||
this.iOrderBindService = iOrderBindService; |
||||
this.iStationService = iStationService; |
||||
this.iLocationService = iLocationService; |
||||
} |
||||
|
||||
@Override |
||||
public R upholdOrderPartWeight(String cardNo, BigDecimal actualWeight) { |
||||
log.info("接收到实际重量:{},对应的流程卡号:{}",actualWeight,cardNo); |
||||
//获取流程卡号
|
||||
List<YieldOrder> list = iYieldOrderService.list(new QueryWrapper<YieldOrder>().eq("CARD_NO", cardNo).orderByDesc("UPDATE_TIME")); |
||||
|
||||
//修改重量
|
||||
list.get(0).setActualWeighing(actualWeight); |
||||
|
||||
return iYieldOrderService.updateById(list.get(0))? R.success():R.fail("实际称重维护:卡号维护失败"); |
||||
} |
||||
|
||||
@Override |
||||
public R boxBinding(BoxBinding boxBinding) { |
||||
log.info("接收到箱绑定实际参数:{}", boxBinding); |
||||
|
||||
// 1. 入参非空校验(基础防护)
|
||||
if (boxBinding == null || boxBinding.getBoxBarcode() == null) { |
||||
log.warn("箱绑定参数为空或箱条码缺失"); |
||||
return R.fail("箱条码不能为空"); |
||||
} |
||||
String boxBarcode = boxBinding.getBoxBarcode(); |
||||
|
||||
// 2. 校验箱条码是否存在运行中的任务(封装为独立方法,提升可读性)
|
||||
R taskCheckResult = checkBoxBarcodeRunningTask(boxBarcode); |
||||
if (!taskCheckResult.isSuccess()) { |
||||
return taskCheckResult; |
||||
} |
||||
|
||||
// 3. 校验订单是否已绑定(封装为独立方法)
|
||||
R orderCheckResult = checkOrderIdBoundStatus(boxBinding.getOrderIdList()); |
||||
if (!orderCheckResult.isSuccess()) { |
||||
return orderCheckResult; |
||||
} |
||||
Long wcId = boxBinding.getWcId(); |
||||
Task task = new Task(); |
||||
task.setBoxBarcode(boxBinding.getBoxBarcode()); |
||||
task.setWcId(wcId); |
||||
// 4. 获取当前站点位置
|
||||
R location = getSiteLocation(task); |
||||
if (!location.isSuccess()) { |
||||
return location; |
||||
} |
||||
// 5. 保存记录到数据库中
|
||||
task= (Task) location.getData(); |
||||
task.setTaskStatus(Task.STATUS_START); |
||||
task.setCreateTime(new Date()); |
||||
boolean orderBool = boxBinding.getOrderIdList() == null || boxBinding.getOrderIdList().size() == 0; |
||||
if (orderBool) { |
||||
task.setWeight(new BigDecimal(0)); |
||||
}else { |
||||
task.setWeight(getWeightByOrderIdList(boxBinding.getOrderIdList())); |
||||
} |
||||
if (task.getWeight().compareTo(BigDecimal.valueOf(50)) < 0) { |
||||
R.fail("箱条码绑定的订单重量过重,请重新进行绑定"); |
||||
} |
||||
if (!iTaskService.save(task)) { |
||||
R.fail("保存绑定箱条码异常"); |
||||
} |
||||
if (orderBool) { |
||||
return R.success(); |
||||
}else { |
||||
return saveOrderBindingList(task.getId(),boxBinding.getOrderIdList()); |
||||
|
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public R boxOrderUnbind(String boxBarcode) { |
||||
if (boxBarcode.isEmpty()) { |
||||
log.warn("箱绑定参数为空或箱条码缺失"); |
||||
return R.fail("箱条码不能为空"); |
||||
} |
||||
// 1. 根据箱条码查询数据
|
||||
List<Task> taskList = iTaskService.list( |
||||
new LambdaQueryWrapper<Task>().eq(Task::getBoxBarcode, boxBarcode).in(Task::getTaskStatus,RUNNING_STATUSES) |
||||
); |
||||
for (Task task : taskList) { |
||||
if (task.getStationId()!=null&&task.getStationId()!=0) { |
||||
Station station = iStationService.getById(task.getStationId()); |
||||
station.setStationStatus(STATUS_OCCUPIED); |
||||
iStationService.updateById(station); |
||||
} |
||||
if (task.getLocationId()!=null&&task.getLocationId()!=0) { |
||||
Location location = iLocationService.getById(task.getLocationId()); |
||||
location.setLocationStatus(STATUS_OCCUPIED); |
||||
iLocationService.updateById(location); |
||||
} |
||||
List<OrderBind> orderBindList = iOrderBindService.list(new LambdaQueryWrapper<OrderBind>().eq(OrderBind::getTaskId, task.getId())); |
||||
if (orderBindList!=null&&orderBindList.size()!=0) { |
||||
for (OrderBind orderBind : orderBindList) { |
||||
orderBind.setBindingStatus(STATUS_UNBINDED); |
||||
iOrderBindService.updateById(orderBind); |
||||
} |
||||
} |
||||
task.setTaskStatus(STATUS_FINISHED); |
||||
iTaskService.updateById(task); |
||||
} |
||||
|
||||
return R.success(); |
||||
} |
||||
|
||||
private R saveOrderBindingList(Long taskId, ArrayList<Long> orderIdList) { |
||||
ArrayList<OrderBind> orderBindList = new ArrayList<>(); |
||||
for (Long orderId : orderIdList) { |
||||
OrderBind orderBind = new OrderBind(); |
||||
orderBind.setBindingStatus(OrderBind.STATUS_BOUND); |
||||
orderBind.setTaskId(taskId); |
||||
orderBind.setOrderId(orderId); |
||||
orderBindList.add(orderBind); |
||||
} |
||||
if (iOrderBindService.saveBatch(orderBindList)) { |
||||
return R.success(); |
||||
}else { |
||||
iTaskService.removeById(taskId); |
||||
return R.fail("订单绑定箱条码异常"); |
||||
} |
||||
} |
||||
|
||||
private BigDecimal getWeightByOrderIdList(ArrayList<Long> orderIdList) { |
||||
List<YieldOrder> orderList = iYieldOrderService.list(new LambdaQueryWrapper<YieldOrder>().in(YieldOrder::getId, orderIdList)); |
||||
return orderList.stream() |
||||
.map(YieldOrder::getActualWeighing) |
||||
.filter(Objects::nonNull) |
||||
.reduce(BigDecimal.ZERO, BigDecimal::add); |
||||
} |
||||
|
||||
private R getSiteLocation(Task task) { |
||||
List<Station> list = iStationService.list(new LambdaQueryWrapper<Station>().eq(Station::getWcId, task.getWcId()).eq(Station::getStationStatus, STATUS_OCCUPIED)); |
||||
if (list!=null&&list.size()!=0) { |
||||
task.setStationId(list.get(0).getId()); |
||||
Station station = list.get(0); |
||||
station.setStationStatus(Station.PRE_STATUS_OCCUPIED); |
||||
iStationService.updateById(station); |
||||
return R.data(task); |
||||
} |
||||
List<Location> locationList = iLocationService.list(new LambdaQueryWrapper<Location>().eq(Location::getLocationStatus, Location.STATUS_OCCUPIED)); |
||||
if (locationList!=null&&locationList.size()!=0) { |
||||
task.setLocationId(locationList.get(0).getId()); |
||||
Location location = locationList.get(0); |
||||
location.setLocationStatus(Location.STATUS_FREE); |
||||
iLocationService.updateById(location); |
||||
return R.data(task); |
||||
} |
||||
return R.fail("当前班次库位繁忙,请空闲后再试"); |
||||
} |
||||
|
||||
/** |
||||
* 校验箱条码是否存在运行中的任务 |
||||
*/ |
||||
private R checkBoxBarcodeRunningTask(String boxBarcode) { |
||||
// 查询箱条码对应的任务(MyBatis-Plus的list方法返回空列表,非null,无需判null)
|
||||
List<Task> taskList = iTaskService.list( |
||||
new LambdaQueryWrapper<Task>().eq(Task::getBoxBarcode, boxBarcode) |
||||
); |
||||
|
||||
// 无任务数据,直接通过校验
|
||||
if (CollectionUtils.isEmpty(taskList)) { |
||||
return R.success(); |
||||
} |
||||
|
||||
// 判断是否有运行中的任务(流式操作简化,无冗余map)
|
||||
boolean hasRunningTask = taskList.stream() |
||||
.map(Task::getTaskStatus) |
||||
.filter(status -> status != null) // 过滤null状态,避免NPE
|
||||
.anyMatch(RUNNING_STATUSES::contains); |
||||
|
||||
if (hasRunningTask) { |
||||
log.warn("箱条码{}存在运行中的任务,绑定异常", boxBarcode); |
||||
return R.fail("该箱条码在运行中,箱条码异常"); |
||||
} |
||||
return R.success(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 校验订单号是否已绑定(核心优化:减少遍历次数,流式收集数据) |
||||
*/ |
||||
private R checkOrderIdBoundStatus(List<Long> orderIdList) { |
||||
// 无订单号,直接通过校验
|
||||
if (CollectionUtils.isEmpty(orderIdList)) { |
||||
return R.success(); |
||||
} |
||||
|
||||
// 查询订单绑定记录
|
||||
List<OrderBind> orderBindList = iOrderBindService.list( |
||||
new LambdaQueryWrapper<OrderBind>().in(OrderBind::getOrderId, orderIdList) |
||||
); |
||||
if (CollectionUtils.isEmpty(orderBindList)) { |
||||
return R.success(); |
||||
} |
||||
|
||||
// 步骤1:过滤出已绑定的订单ID(流式收集,替代循环)
|
||||
List<Long> boundOrderIds = orderBindList.stream() |
||||
.filter(orderBind -> OrderBind.STATUS_BOUND.equals(orderBind.getBindingStatus())) |
||||
.map(OrderBind::getOrderId) |
||||
.filter(orderId -> orderId != null) // 过滤null订单ID
|
||||
.distinct() // 去重,避免重复查询
|
||||
.collect(Collectors.toList()); |
||||
|
||||
// 无已绑定订单,直接通过
|
||||
if (CollectionUtils.isEmpty(boundOrderIds)) { |
||||
return R.success(); |
||||
} |
||||
|
||||
// 步骤2:查询已绑定订单对应的流程卡号(流式收集,替代循环)
|
||||
List<String> boundCardNos = iYieldOrderService.list( |
||||
new LambdaQueryWrapper<YieldOrder>().in(YieldOrder::getId, boundOrderIds) |
||||
).stream() |
||||
.map(YieldOrder::getCardNo) |
||||
.filter(cardNo -> cardNo != null) // 过滤null卡号
|
||||
.collect(Collectors.toList()); |
||||
|
||||
// 构造异常信息并返回
|
||||
String errorMsg = String.format("以下流程卡号处于绑定状态,绑定异常:{%s}", String.join(",", boundCardNos)); |
||||
log.warn(errorMsg); |
||||
return R.fail(errorMsg); |
||||
} |
||||
} |
||||
@ -1,173 +0,0 @@ |
||||
package org.springblade.desk.logistics.service.impl; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springblade.core.tool.api.R; |
||||
import org.springblade.desk.jobtransfer.service.ICertificateMaintenanceService; |
||||
import org.springblade.desk.logistics.pojo.entity.BoxBinding; |
||||
import org.springblade.desk.logistics.pojo.entity.OrderBind; |
||||
import org.springblade.desk.logistics.pojo.entity.Task; |
||||
import org.springblade.desk.logistics.service.OrderBindService; |
||||
import org.springblade.desk.logistics.service.OrderBoxService; |
||||
|
||||
import org.springblade.desk.logistics.service.TaskService; |
||||
import org.springblade.desk.order.pojo.entity.YieldOrder; |
||||
import org.springblade.desk.order.service.IYieldOrderService; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.util.CollectionUtils; |
||||
|
||||
import java.math.BigDecimal; |
||||
import java.util.ArrayList; |
||||
import java.util.HashSet; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* 订单箱子 控制器 |
||||
* |
||||
* @author qyl |
||||
* @since 2026-01-08 |
||||
*/ |
||||
@Service |
||||
@Slf4j |
||||
public class OrderBoxServiceImpl implements OrderBoxService { |
||||
private final IYieldOrderService yieldOrderService; |
||||
private final TaskService taskService; |
||||
private final OrderBindService orderBindService; |
||||
private final OrderBindService orderBindService; |
||||
|
||||
public OrderBoxServiceImpl(IYieldOrderService yieldOrderService, TaskService taskService, OrderBindService orderBindService) { |
||||
this.yieldOrderService = yieldOrderService; |
||||
this.taskService = taskService; |
||||
this.orderBindService = orderBindService; |
||||
} |
||||
private static final Set<Integer> RUNNING_STATUSES = new HashSet<>(); |
||||
static { |
||||
RUNNING_STATUSES.add(Task.STATUS_STATION); |
||||
RUNNING_STATUSES.add(Task.STATUS_LOCATION); |
||||
RUNNING_STATUSES.add(Task.STATUS_WAITING); |
||||
RUNNING_STATUSES.add(Task.STATUS_BACK_TO_STORAGE); |
||||
} |
||||
private static final Set<Integer> ORDER_STATUSES = new HashSet<>(); |
||||
static { |
||||
ORDER_STATUSES.add(OrderBind.STATUS_BOUND); |
||||
} |
||||
|
||||
@Override |
||||
public R upholdOrderPartWeight(String cardNo, BigDecimal actualWeight) { |
||||
log.info("接收到实际重量:{},对应的流程卡号:{}",actualWeight,cardNo); |
||||
//获取流程卡号
|
||||
List<YieldOrder> list = yieldOrderService.list(new QueryWrapper<YieldOrder>().eq("CARD_NO", cardNo).orderByDesc("UPDATE_TIME")); |
||||
|
||||
//修改重量
|
||||
list.get(0).setActualWeighing(actualWeight); |
||||
|
||||
return yieldOrderService.updateById(list.get(0))? R.success():R.fail("实际称重维护:卡号维护失败"); |
||||
} |
||||
|
||||
@Override |
||||
public R boxBinding(BoxBinding boxBinding) { |
||||
log.info("接收到箱绑定实际参数:{}", boxBinding); |
||||
|
||||
// 1. 入参非空校验(基础防护)
|
||||
if (boxBinding == null || boxBinding.getBoxBarcode() == null) { |
||||
log.warn("箱绑定参数为空或箱条码缺失"); |
||||
return R.fail("箱条码不能为空"); |
||||
} |
||||
String boxBarcode = boxBinding.getBoxBarcode(); |
||||
|
||||
// 2. 校验箱条码是否存在运行中的任务(封装为独立方法,提升可读性)
|
||||
R taskCheckResult = checkBoxBarcodeRunningTask(boxBarcode); |
||||
if (!taskCheckResult.isSuccess()) { |
||||
return taskCheckResult; |
||||
} |
||||
|
||||
// 3. 校验订单是否已绑定(封装为独立方法)
|
||||
R orderCheckResult = checkOrderIdBoundStatus(boxBinding.getOrderIdList()); |
||||
if (!orderCheckResult.isSuccess()) { |
||||
return orderCheckResult; |
||||
} |
||||
//TODO:判断班次与库位记得写
|
||||
|
||||
//5.保存记录到数据库中
|
||||
Task task = new Task(); |
||||
task.setBoxBarcode(boxBinding.getBoxBarcode()); |
||||
task.setTaskStatus(1); |
||||
|
||||
task.set |
||||
return null; |
||||
} |
||||
/** |
||||
* 校验箱条码是否存在运行中的任务 |
||||
*/ |
||||
private R checkBoxBarcodeRunningTask(String boxBarcode) { |
||||
// 查询箱条码对应的任务(MyBatis-Plus的list方法返回空列表,非null,无需判null)
|
||||
List<Task> taskList = taskService.list( |
||||
new LambdaQueryWrapper<Task>().eq(Task::getBoxBarcode, boxBarcode) |
||||
); |
||||
|
||||
// 无任务数据,直接通过校验
|
||||
if (CollectionUtils.isEmpty(taskList)) { |
||||
return R.success(); |
||||
} |
||||
|
||||
// 判断是否有运行中的任务(流式操作简化,无冗余map)
|
||||
boolean hasRunningTask = taskList.stream() |
||||
.map(Task::getTaskStatus) |
||||
.filter(status -> status != null) // 过滤null状态,避免NPE
|
||||
.anyMatch(RUNNING_STATUSES::contains); |
||||
|
||||
if (hasRunningTask) { |
||||
log.warn("箱条码{}存在运行中的任务,绑定异常", boxBarcode); |
||||
return R.fail("该箱条码在运行中,箱条码异常"); |
||||
} |
||||
return R.success(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 校验订单号是否已绑定(核心优化:减少遍历次数,流式收集数据) |
||||
*/ |
||||
private R checkOrderIdBoundStatus(List<Long> orderIdList) { |
||||
// 无订单号,直接通过校验
|
||||
if (CollectionUtils.isEmpty(orderIdList)) { |
||||
return R.success(); |
||||
} |
||||
|
||||
// 查询订单绑定记录
|
||||
List<OrderBind> orderBindList = orderBindService.list( |
||||
new LambdaQueryWrapper<OrderBind>().in(OrderBind::getOrderId, orderIdList) |
||||
); |
||||
if (CollectionUtils.isEmpty(orderBindList)) { |
||||
return R.success(); |
||||
} |
||||
|
||||
// 步骤1:过滤出已绑定的订单ID(流式收集,替代循环)
|
||||
List<Long> boundOrderIds = orderBindList.stream() |
||||
.filter(orderBind -> OrderBind.STATUS_BOUND.equals(orderBind.getBindingStatus())) |
||||
.map(OrderBind::getOrderId) |
||||
.filter(orderId -> orderId != null) // 过滤null订单ID
|
||||
.distinct() // 去重,避免重复查询
|
||||
.collect(Collectors.toList()); |
||||
|
||||
// 无已绑定订单,直接通过
|
||||
if (CollectionUtils.isEmpty(boundOrderIds)) { |
||||
return R.success(); |
||||
} |
||||
|
||||
// 步骤2:查询已绑定订单对应的流程卡号(流式收集,替代循环)
|
||||
List<String> boundCardNos = yieldOrderService.list( |
||||
new LambdaQueryWrapper<YieldOrder>().in(YieldOrder::getId, boundOrderIds) |
||||
).stream() |
||||
.map(YieldOrder::getCardNo) |
||||
.filter(cardNo -> cardNo != null) // 过滤null卡号
|
||||
.collect(Collectors.toList()); |
||||
|
||||
// 构造异常信息并返回
|
||||
String errorMsg = String.format("以下流程卡号处于绑定状态,绑定异常:{%s}", String.join(",", boundCardNos)); |
||||
log.warn(errorMsg); |
||||
return R.fail(errorMsg); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue