修复bug:

1. 删除库位锁定, 因入库任务由场内wms下发生成, 故不存在库位竞争
2. 修改入库订单生成逻辑, 由wcs_require接口生成, 改为由ycwms接口生成, 加入FC载具号生成订单的绿色通道, 从而使场内wms的空托空盘入库任务状态闭环

新需求:
1. 修改单机出库: 先查询库存, 后勾选出库
This commit is contained in:
李宇奇 2025-05-25 21:21:16 +08:00
parent b90f03e1a6
commit 59c978231a
15 changed files with 600 additions and 420 deletions

View File

@ -48,9 +48,9 @@ public class YcwmsController {
return ycwmsControllerService.getAvailPercent(equipmentId);
}
@PostMapping("/localOut")
public YcwmsResponse<Object> localOut(@RequestBody LocalOrderReq request) {
return ycwmsControllerService.localOrderOut(request);
@PostMapping("/localQuery")
public YcwmsResponse<List<StockResp>> localQuery(@RequestBody LocalOrderReq request) {
return ycwmsControllerService.localQuery(request);
}
@PostMapping("/getOutLocation")
@ -62,4 +62,9 @@ public class YcwmsController {
return YcwmsResponse.success(outLoc);
}
}
@PostMapping("/localOut")
public YcwmsResponse<Object> localOut(@RequestBody List<String> vehicleNos) {
return ycwmsControllerService.localOut(vehicleNos);
}
}

View File

@ -1,5 +1,6 @@
package com.wms_main.model.bo.erp;
import com.wms_main.model.dto.request.ycwms.OrderInGoodsDetail;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -22,4 +23,18 @@ public class ErpGoodsDetail {
private String xsfbillno;
private Integer xsfseq;
private String neibubianhao;
public static ErpGoodsDetail of(OrderInGoodsDetail goodsDetail) {
ErpGoodsDetail erpGoodsDetail = new ErpGoodsDetail();
erpGoodsDetail.setGoodsId(goodsDetail.getGoodsId());
erpGoodsDetail.setGoodsName(goodsDetail.getGoodsName());
erpGoodsDetail.setBatch(goodsDetail.getBatch());
erpGoodsDetail.setGoodsType(goodsDetail.getGoodsType());
erpGoodsDetail.setSpecification(goodsDetail.getSpecification());
erpGoodsDetail.setQuantity(goodsDetail.getQuantity());
erpGoodsDetail.setGoodsDesc(goodsDetail.getGoodsDesc());
erpGoodsDetail.setGoodsBarcode(goodsDetail.getGoodsBarcode());
return erpGoodsDetail;
}
}

View File

@ -7,15 +7,16 @@ import lombok.Setter;
@Getter
@Setter
public class LocalOrderReq {
@JsonProperty("specification")
private String specification;
@JsonProperty("goodsType")
private String goodsType;
@JsonProperty("xsfbillno")
private String xsfbillno;
@JsonProperty("xsfseq")
private Integer xsfseq;
@JsonProperty("neibubianhao")
private String neibubianhao;
public boolean empty() {
return goodsType == null && xsfbillno == null && neibubianhao == null;
}
}

View File

@ -32,7 +32,7 @@ public interface IStackerTaskService {
* 完成堆垛机入库任务
* @param stackerInTasks 已完成的入库任务
*/
void finishStackerInTasks(List<TAppOrderIn> stackerInTasks);
void finishStackerInTasks(List<TAppOrderIn> stackerInTasks) throws InterruptedException;
/**
* 完成堆垛机入库任务---合并相同物料
@ -44,5 +44,5 @@ public interface IStackerTaskService {
* 完成堆垛机出库任务
* @param stackerOutTasks 已完成的出库任务
*/
void finishStackerOutTasks(List<TAppWcsTask> stackerOutTasks);
void finishStackerOutTasks(List<TAppWcsTask> stackerOutTasks) throws InterruptedException;
}

View File

@ -357,133 +357,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
.map(Map.Entry::getKey)
.toList();
}
/**
* 实现
*
* @param stackerInTasks 已完成的入库任务
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void finishStackerInTasks(List<TAppOrderIn> stackerInTasks) {
// 根据载具号map一下
Map<String, List<TAppOrderIn>> vehicleIdToTaskMap = stackerInTasks.stream()
.filter(orderIn -> Objects.equals(orderIn.getOrderStatus(), OrderStatusEnum.COMPLETE.getCode()))
.collect(Collectors.groupingBy(TAppOrderIn::getVehicleNo));
for (String vehicleId : vehicleIdToTaskMap.keySet()) {
List<TAppOrderIn> thisOrderInList = vehicleIdToTaskMap.get(vehicleId);
if (thisOrderInList == null || thisOrderInList.isEmpty()) {
continue;
}
String location = thisOrderInList.getFirst().getDestination();
// 新的库存信息
List<TAppStock> newStockList = null;
// 需要删除的任务id
List<String> needDeleteOrderIns = new ArrayList<>();
List<String> orderCBIds = new ArrayList<>();
Map<String, TAppStock> stockMap = new HashMap<>();
for (TAppOrderIn thisOrderIn : thisOrderInList) {
// 删除任务
needDeleteOrderIns.add(thisOrderIn.getRecordId());
orderCBIds.add(thisOrderIn.getOrderId());
// 添加库存
TAppStock newStock = new TAppStock();
newStock.setStockId(UUIDUtils.getNewUUID());
newStock.setVehicleId(vehicleId);
newStock.setLocationId(thisOrderIn.getDestination());
newStock.setStockStatus(WmsStockStatusEnums.OK.getCode());
newStock.setGoodsId(thisOrderIn.getGoodsId());
newStock.setGoodsStatus(WmsGoodsStatusEnums.OK.getCode());
newStock.setFirstInTime(thisOrderIn.getCreateTime());
newStock.setFirstInUser(thisOrderIn.getClientId());
newStock.setLastUpdateTime(LocalDateTime.now());
newStock.setLastUpdateUser(thisOrderIn.getClientId());
newStock.setTotalNum(thisOrderIn.getQuantity());
newStock.setRemainNum(thisOrderIn.getQuantity());
newStock.setRealNum(thisOrderIn.getQuantity());
newStock.setGoodsDesc(thisOrderIn.getGoodsName());
newStock.setSled(thisOrderIn.getSpecification());
newStock.setMesId(thisOrderIn.getOrderId());
newStock.setBatch(thisOrderIn.getBatch());
newStock.setGoodsType(thisOrderIn.getGoodsType());
newStock.setBarCode(thisOrderIn.getInStand());
newStock.setGoodsBarCode(thisOrderIn.getGoodsBarcode());
newStock.setXsfbillno(thisOrderIn.getXsfbillno());
newStock.setXsfseq(thisOrderIn.getXsfseq());
newStock.setNeibubianhao(thisOrderIn.getNeibubianhao());
appStockService.save(newStock);
}
// 将目标库位的工作状态设置为未工作
appLocationService.update(new LambdaUpdateWrapper<TAppLocation>()
.set(TAppLocation::getIsWorking, 0)
.set(TAppLocation::getVehicleId, vehicleId)
.eq(TAppLocation::getLocationId, location)
);
// 需要更新下当前载具下的库存其他信息
// appStockService.update(new LambdaUpdateWrapper<TAppStock>()
// .set(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode())
// .set(TAppStock::getLocationId, location)
// .eq(TAppStock::getVehicleId, vehicleId));
// 保存载具表
TAppVehicle vehicle = new TAppVehicle();
vehicle.setVehicleId(vehicleId);
vehicle.setIsEmpty(0);
vehicle.setVehicleStatus(WmsVehicleStatusEnums.ON.getCode());
vehicle.setIsLock(0);
vehicle.setVehicleType("1");
vehicle.setLocationId(location);
vehicle.setLastInTime(LocalDateTime.now());
appVehicleService.saveOrUpdate(vehicle);
TAppWcsTaskBak wcsTaskBak = new TAppWcsTaskBak();
wcsTaskBak.setWcsTaskId(UUIDUtils.getNewUUID());
wcsTaskBak.setWcsTaskStatus(100);
wcsTaskBak.setWcsTaskType(WmsTaskTypeEnums.IN.getCode());
wcsTaskBak.setTaskPriority(1);
wcsTaskBak.setVehicleId(vehicleId);
wcsTaskBak.setOrigin(thisOrderInList.getFirst().getInStand());
wcsTaskBak.setDestination(location);
wcsTaskBak.setCreateTime(LocalDateTime.now());
wcsTaskBak.setSendTime(LocalDateTime.now());
wcsTaskBak.setFinishTime(LocalDateTime.now());
wcsTaskBak.setRemark(thisOrderInList.getFirst().getClientId());
wcsTaskBak.setCount(thisOrderInList.size());
wcsTaskBak.setTotalNum(thisOrderInList.stream().mapToDouble(TAppOrderIn::getQuantity).sum());
appWcsTaskBakService.save(wcsTaskBak);
// 删除已经完成的入库单
if (!needDeleteOrderIns.isEmpty()) {
appOrderInService.removeByIds(needDeleteOrderIns);
}
// TODO 上报 亚驰 WMS 入库单完成一个载具应该对应一个入库单
orderCBIds = orderCBIds.stream().distinct().collect(Collectors.toList());
for (String orderId : orderCBIds) {
if (orderId.contains("baokai")) {
continue;
}
OrderInCBReq orderInCBReq = new OrderInCBReq();
orderInCBReq.setOrderId(orderId);
orderInCBReq.setVehicleNo(vehicleId);
orderInCBReq.setOrderStatus(OrderStatusEnum.COMPLETE.getCode());
orderInCBReq.setMessage("入库完成");
int times = 0;
YCWmsApiResponse response = null;
do {
response = externalApiService.invokeOrderInCB(orderInCBReq);
times++;
} while (!response.getState().equals("success") && times <= 3);
if (response.getState().equals("error") && times >= 3) {
log.error("上报失败");
} else {
log.info("上报成功");
}
}
}
}
/**
* 实现---这里是合并库存的部分
*
@ -701,6 +574,126 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
}
}
/**
* 实现
*
* @param stackerInTasks 已完成的入库任务
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void finishStackerInTasks(List<TAppOrderIn> stackerInTasks) throws InterruptedException {
// 根据载具号map一下
Map<String, List<TAppOrderIn>> vehicleIdToTaskMap = stackerInTasks.stream()
.filter(orderIn -> Objects.equals(orderIn.getOrderStatus(), OrderStatusEnum.COMPLETE.getCode()))
.collect(Collectors.groupingBy(TAppOrderIn::getVehicleNo));
for (String vehicleId : vehicleIdToTaskMap.keySet()) {
List<TAppOrderIn> thisOrderInList = vehicleIdToTaskMap.get(vehicleId);
if (thisOrderInList == null || thisOrderInList.isEmpty()) {
continue;
}
String location = thisOrderInList.getFirst().getDestination();
// 需要删除的任务id
List<String> needDeleteOrderIns = new ArrayList<>();
List<String> orderCBIds = new ArrayList<>();
for (TAppOrderIn thisOrderIn : thisOrderInList) {
// 删除任务
needDeleteOrderIns.add(thisOrderIn.getRecordId());
orderCBIds.add(thisOrderIn.getOrderId());
// 添加库存
TAppStock newStock = new TAppStock();
newStock.setStockId(UUIDUtils.getNewUUID());
newStock.setVehicleId(vehicleId);
newStock.setLocationId(thisOrderIn.getDestination());
newStock.setStockStatus(WmsStockStatusEnums.OK.getCode());
newStock.setGoodsId(thisOrderIn.getGoodsId());
newStock.setGoodsStatus(WmsGoodsStatusEnums.OK.getCode());
newStock.setFirstInTime(thisOrderIn.getCreateTime());
newStock.setFirstInUser(thisOrderIn.getClientId());
newStock.setLastUpdateTime(LocalDateTime.now());
newStock.setLastUpdateUser(thisOrderIn.getClientId());
newStock.setTotalNum(thisOrderIn.getQuantity());
newStock.setRemainNum(thisOrderIn.getQuantity());
newStock.setRealNum(thisOrderIn.getQuantity());
newStock.setGoodsDesc(thisOrderIn.getGoodsName());
newStock.setSled(thisOrderIn.getSpecification());
newStock.setMesId(thisOrderIn.getOrderId());
newStock.setBatch(thisOrderIn.getBatch());
newStock.setGoodsType(thisOrderIn.getGoodsType());
newStock.setBarCode(thisOrderIn.getInStand());
newStock.setGoodsBarCode(thisOrderIn.getGoodsBarcode());
newStock.setXsfbillno(thisOrderIn.getXsfbillno());
newStock.setXsfseq(thisOrderIn.getXsfseq());
newStock.setNeibubianhao(thisOrderIn.getNeibubianhao());
appStockService.save(newStock);
}
// 将目标库位的工作状态设置为未工作
appLocationService.update(new LambdaUpdateWrapper<TAppLocation>()
.set(TAppLocation::getVehicleId, vehicleId)
.set(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.OCCUPY.getCode())
.eq(TAppLocation::getLocationId, location)
);
// 保存载具表
TAppVehicle vehicle = new TAppVehicle();
vehicle.setVehicleId(vehicleId);
vehicle.setIsEmpty(0);
vehicle.setVehicleStatus(WmsVehicleStatusEnums.ON.getCode());
vehicle.setIsLock(0);
vehicle.setVehicleType("1");
vehicle.setLocationId(location);
vehicle.setLastInTime(LocalDateTime.now());
appVehicleService.saveOrUpdate(vehicle);
TAppWcsTaskBak wcsTaskBak = new TAppWcsTaskBak();
wcsTaskBak.setWcsTaskId(UUIDUtils.getNewUUID());
wcsTaskBak.setWcsTaskStatus(100);
wcsTaskBak.setWcsTaskType(WmsTaskTypeEnums.IN.getCode());
wcsTaskBak.setTaskPriority(1);
wcsTaskBak.setVehicleId(vehicleId);
wcsTaskBak.setOrigin(thisOrderInList.getFirst().getInStand());
wcsTaskBak.setDestination(location);
wcsTaskBak.setCreateTime(LocalDateTime.now());
wcsTaskBak.setSendTime(LocalDateTime.now());
wcsTaskBak.setFinishTime(LocalDateTime.now());
wcsTaskBak.setRemark(thisOrderInList.getFirst().getClientId());
wcsTaskBak.setCount(thisOrderInList.size());
wcsTaskBak.setTotalNum(thisOrderInList.stream().mapToDouble(TAppOrderIn::getQuantity).sum());
appWcsTaskBakService.save(wcsTaskBak);
// TODO 上报 亚驰 WMS 入库单完成一个载具应该对应一个入库单
orderCBIds = orderCBIds.stream().distinct().collect(Collectors.toList());
for (String orderId : orderCBIds) {
if (orderId.contains("baokai")) {
continue;
}
OrderInCBReq orderInCBReq = new OrderInCBReq();
orderInCBReq.setOrderId(orderId);
orderInCBReq.setVehicleNo(vehicleId);
orderInCBReq.setOrderStatus(OrderStatusEnum.COMPLETE.getCode());
orderInCBReq.setMessage("入库完成");
int times = 0;
YCWmsApiResponse response = null;
do {
Thread.sleep(15000L * times);
response = externalApiService.invokeOrderInCB(orderInCBReq);
times++;
} while (!response.getState().equals("success") && times <= 10);
if (response.getState().equals("error")) {
log.error("[wms]上报失败");
} else {
log.info("[wms]上报成功");
}
}
// 删除已经完成的入库单
if (!needDeleteOrderIns.isEmpty()) {
appOrderInService.removeByIds(needDeleteOrderIns);
}
}
}
/**
* 实现
*
@ -708,7 +701,7 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void finishStackerOutTasks(List<TAppWcsTask> stackerOutTasks) {
public void finishStackerOutTasks(List<TAppWcsTask> stackerOutTasks) throws InterruptedException {
// 出库完成需要完成以下事情
// 1. 更新库存状态
// 2. 更新载具状态
@ -848,11 +841,12 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
do {
response = externalApiService.invokeOrderOutCB(orderOutCBReq);
times++;
} while (!response.getState().equals("success") && times <= 3);
if (response.getState().equals("error") && times >= 3) {
log.error("上报失败");
Thread.sleep(15000L * times);
} while (!response.getState().equals("success") && times <= 10);
if (response.getState().equals("error")) {
log.error("[WMS]上报失败");
} else {
log.info("上报成功");
log.info("[WMS]上报成功");
}
}
}

View File

@ -11,6 +11,7 @@ public interface IYcwmsControllerService {
YcwmsResponse<Object> orderOut(OrderOutReq request);
YcwmsResponse<List<StockResp>> stock(StockReq request);
YcwmsResponse<Object> getAvailPercent(String equipmentId);
YcwmsResponse<Object> localOrderOut(LocalOrderReq request);
YcwmsResponse<List<StockResp>> localQuery(LocalOrderReq request);
String getLocByGoodsId(String goodsId);
YcwmsResponse<Object> localOut(List<String> vehicleNos);
}

View File

@ -1,6 +1,8 @@
package com.wms_main.service.controller.serviceImpl;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
import com.wms_main.constant.enums.wcs.WcsStackerTaskTypeEnums;
import com.wms_main.constant.enums.wms.OrderStatusEnum;
@ -25,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
@ -34,7 +37,6 @@ public class WcsControllerServiceImpl implements IWcsControllerService {
private final ITAppOrderInService orderInService;
private final IStackerTaskService stackerTaskService;
private final ITAppWcsTaskService wcsTaskService;
private final ITAppLocationService locationService;
@Override
@ -48,11 +50,6 @@ public class WcsControllerServiceImpl implements IWcsControllerService {
}
// 一号堆垛机全部存空托盘
if(point.equals("105") || point.equals("106") || point.equals("107")) {
// 选一个库位
TAppLocation targetLocation = stackerTaskService.getEmptyLocation(1, point.equals("105") ? WmsLocationTypeEnums.TYPE_600 : WmsLocationTypeEnums.TYPE_500);
if(targetLocation == null) {
return WcsApiResponse.error("没有空闲库位,请稍后再试", null);
}
String goodsId567 = "";
if (point.equals("105")) {
goodsId567 = "2";
@ -61,134 +58,136 @@ public class WcsControllerServiceImpl implements IWcsControllerService {
} else {
goodsId567 = "4";
}
String vehicleId = UUIDUtils.getNewUUID();
// 插入一条默认入库单
TAppOrderIn orderIn = new TAppOrderIn();
orderIn.setRecordId(UUIDUtils.getNewUUID());
orderIn.setOrderId(UUIDUtils.getNewUUID());
orderIn.setVehicleNo(vehicleId);
orderIn.setVehicleSize(point);
orderIn.setInStand(point);
orderIn.setDestination(targetLocation.getLocationId());
orderIn.setClientId("WCS");
orderIn.setGoodsId(goodsId567);
orderIn.setGoodsName("空托盘");
orderIn.setBatch("0");
orderIn.setGoodsType("0");
orderIn.setQuantity(4.0);
orderIn.setGoodsDesc("");
orderIn.setSpecification("empty");
orderIn.setXsfbillno(goodsId567);
orderIn.setXsfseq(0);
orderIn.setNeibubianhao("0");
orderIn.setOrderStatus(OrderStatusEnum.RUNNING.getCode());
orderIn.setCreateTime(LocalDateTime.now());
orderIn.setUpdateTime(LocalDateTime.now());
boolean saveOrderIn = orderInService.save(orderIn);
if(!saveOrderIn) {
return WcsApiResponse.error("入库单保存失败,请稍后再试", null);
List<TAppOrderIn> withOrderId = orderInService.list(
new LambdaQueryWrapper<TAppOrderIn>()
.like(TAppOrderIn::getVehicleNo, "FC")
.in(TAppOrderIn::getInStand, List.of("105", "106", "107"))
.eq(TAppOrderIn::getOrderStatus, OrderStatusEnum.CREATE.getCode())
);
if(withOrderId == null) {
return WcsApiResponse.error("数据服务异常,请稍后重试", null);
}
// 插入一条WcsTask
String taskId = UUIDUtils.getNewUUID();
TAppWcsTask wcsTask = new TAppWcsTask();
wcsTask.setWcsTaskId(taskId);
wcsTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.RUN.getCode());
wcsTask.setWcsTaskType(WcsStackerTaskTypeEnums.IN.getCode());
wcsTask.setTaskPriority(0);
wcsTask.setVehicleId(vehicleId);
wcsTask.setOrigin(point);
wcsTask.setDestination(targetLocation.getLocationId());
wcsTask.setCreateTime(LocalDateTime.now());
wcsTask.setSendTime(LocalDateTime.now());
wcsTask.setRemark("WCS");
boolean saveWcsTask = wcsTaskService.save(wcsTask);
if(!saveWcsTask) {
return WcsApiResponse.error("任务创建失败,请稍后再试", null);
if(withOrderId.isEmpty()) {
return WcsApiResponse.error("无入库订单", null);
}
// 锁定库位
boolean lockLocation = locationService.updateLocationOccupy(targetLocation.getLocationId(), 1);
if(!lockLocation) {
return WcsApiResponse.error("库位锁定失败,请稍后再试", null);
List<String> vehicleNos = withOrderId.stream().map(TAppOrderIn::getVehicleNo).toList();
for (String vehicleNo : vehicleNos) {
// 选一个库位
TAppLocation targetLocation = stackerTaskService.getEmptyLocation(1, point.equals("105") ? WmsLocationTypeEnums.TYPE_600 : WmsLocationTypeEnums.TYPE_500);
if(targetLocation == null) {
return WcsApiResponse.error("没有空闲库位,请稍后再试", null);
}
orderInService.update(
new LambdaUpdateWrapper<TAppOrderIn>()
.eq(TAppOrderIn::getVehicleNo, vehicleNo)
.set(TAppOrderIn::getOrderStatus, OrderStatusEnum.RUNNING.getCode())
.set(TAppOrderIn::getDestination, targetLocation.getLocationId())
.set(TAppOrderIn::getGoodsId, goodsId567)
.set(TAppOrderIn::getBatch, "0")
.set(TAppOrderIn::getQuantity, 4.0)
.set(TAppOrderIn::getSpecification, "empty")
.set(TAppOrderIn::getXsfbillno, goodsId567)
.set(TAppOrderIn::getXsfseq, 0)
.set(TAppOrderIn::getNeibubianhao, "0")
.set(TAppOrderIn::getUpdateTime, LocalDateTime.now())
);
// 插入一条WcsTask
String taskId = UUIDUtils.getNewUUID();
TAppWcsTask wcsTask = new TAppWcsTask();
wcsTask.setWcsTaskId(taskId);
wcsTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.RUN.getCode());
wcsTask.setWcsTaskType(WcsStackerTaskTypeEnums.IN.getCode());
wcsTask.setTaskPriority(0);
wcsTask.setVehicleId(vehicleNo);
wcsTask.setOrigin(point);
wcsTask.setDestination(targetLocation.getLocationId());
wcsTask.setCreateTime(LocalDateTime.now());
wcsTask.setSendTime(LocalDateTime.now());
wcsTask.setRemark("WCS");
boolean saveWcsTask = wcsTaskService.save(wcsTask);
if(!saveWcsTask) {
return WcsApiResponse.error("任务创建失败,请稍后再试", null);
}
InTaskResp inTaskResp = new InTaskResp();
inTaskResp.setTaskId(taskId);
inTaskResp.setUser("WMS");
inTaskResp.setVehicleNo(vehicleNo);
inTaskResp.setDestination(targetLocation.getLocationId());
inTaskResp.setSpare1("");
inTaskResp.setSpare2("");
return WcsApiResponse.success(inTaskResp);
}
InTaskResp inTaskResp = new InTaskResp();
inTaskResp.setTaskId(taskId);
inTaskResp.setUser("WMS");
inTaskResp.setVehicleNo(vehicleId);
inTaskResp.setDestination(targetLocation.getLocationId());
inTaskResp.setSpare1("");
inTaskResp.setSpare2("");
return WcsApiResponse.success(inTaskResp);
}
// 二号堆垛机一部分存空一部分存有货位置
if(point.equals("103") || point.equals("104")) {
List<String> vehicleNos = List.of(request.getVehicleNo().split(";"));
for (String vehicleNo : vehicleNos) {
if(vehicleNo.equals("0")) { // 空托盘
// 选一个库位
TAppLocation targetLocation = stackerTaskService.getEmptyLocation(2, WmsLocationTypeEnums.TYPE_EMPTY);
if(targetLocation == null) {
return WcsApiResponse.error("没有空闲库位,请稍后再试", null);
}
String goodsId34 = point.equals("103") ? "0" : "1";
String vehicleId = UUIDUtils.getNewUUID();
// 插入一条默认入库单
TAppOrderIn orderIn = new TAppOrderIn();
orderIn.setRecordId(UUIDUtils.getNewUUID());
orderIn.setOrderId(UUIDUtils.getNewUUID());
orderIn.setVehicleNo(vehicleId);
orderIn.setVehicleSize(point);
orderIn.setInStand(point);
orderIn.setDestination(targetLocation.getLocationId());
orderIn.setClientId("WCS");
orderIn.setGoodsId(goodsId34);
orderIn.setGoodsName("空托盘");
orderIn.setBatch("0");
orderIn.setGoodsType("0");
orderIn.setQuantity(1.0);
orderIn.setGoodsDesc("");
orderIn.setSpecification("empty");
orderIn.setXsfbillno(goodsId34);
orderIn.setXsfseq(0);
orderIn.setNeibubianhao("0");
orderIn.setOrderStatus(OrderStatusEnum.RUNNING.getCode());
orderIn.setCreateTime(LocalDateTime.now());
orderIn.setUpdateTime(LocalDateTime.now());
boolean saveOrderIn = orderInService.save(orderIn);
if(!saveOrderIn) {
return WcsApiResponse.error("入库单保存失败,请稍后再试", null);
List<TAppOrderIn> withOrderId = orderInService.list(
new LambdaQueryWrapper<TAppOrderIn>()
.like(TAppOrderIn::getVehicleNo, "FC")
.in(TAppOrderIn::getInStand, List.of("103", "104"))
.eq(TAppOrderIn::getOrderStatus, OrderStatusEnum.CREATE.getCode())
);
if(withOrderId == null) {
return WcsApiResponse.error("数据服务异常,请稍后重试", null);
}
// 插入一条WcsTask
String taskId = UUIDUtils.getNewUUID();
TAppWcsTask wcsTask = new TAppWcsTask();
wcsTask.setWcsTaskId(taskId);
wcsTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.RUN.getCode());
wcsTask.setWcsTaskType(WcsStackerTaskTypeEnums.IN.getCode());
wcsTask.setTaskPriority(0);
wcsTask.setVehicleId(vehicleId);
wcsTask.setOrigin(point);
wcsTask.setDestination(targetLocation.getLocationId());
wcsTask.setCreateTime(LocalDateTime.now());
wcsTask.setSendTime(LocalDateTime.now());
wcsTask.setRemark("WCS");
boolean saveWcsTask = wcsTaskService.save(wcsTask);
if(!saveWcsTask) {
return WcsApiResponse.error("任务创建失败,请稍后再试", null);
if(withOrderId.isEmpty()) {
return WcsApiResponse.error("无入库订单", null);
}
// 锁定库位
boolean lockLocation = locationService.updateLocationOccupy(targetLocation.getLocationId(), 1);
if(!lockLocation) {
return WcsApiResponse.error("库位锁定失败,请稍后再试", null);
List<String> withVehicleNos = withOrderId.stream().map(TAppOrderIn::getVehicleNo).toList();
for (String withVehicleNo : withVehicleNos) {
// 选一个库位
TAppLocation targetLocation = stackerTaskService.getEmptyLocation(2, WmsLocationTypeEnums.TYPE_EMPTY);
if(targetLocation == null) {
return WcsApiResponse.error("没有空闲库位,请稍后再试", null);
}
orderInService.update(
new LambdaUpdateWrapper<TAppOrderIn>()
.eq(TAppOrderIn::getVehicleNo, withVehicleNo)
.set(TAppOrderIn::getOrderStatus, OrderStatusEnum.RUNNING.getCode())
.set(TAppOrderIn::getDestination, targetLocation.getLocationId())
.set(TAppOrderIn::getGoodsId, goodsId34)
.set(TAppOrderIn::getBatch, "0")
.set(TAppOrderIn::getQuantity, 1.0)
.set(TAppOrderIn::getSpecification, "empty")
.set(TAppOrderIn::getXsfbillno, goodsId34)
.set(TAppOrderIn::getXsfseq, 0)
.set(TAppOrderIn::getNeibubianhao, "0")
.set(TAppOrderIn::getUpdateTime, LocalDateTime.now())
);
// 插入一条WcsTask
String taskId = UUIDUtils.getNewUUID();
TAppWcsTask wcsTask = new TAppWcsTask();
wcsTask.setWcsTaskId(taskId);
wcsTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.RUN.getCode());
wcsTask.setWcsTaskType(WcsStackerTaskTypeEnums.IN.getCode());
wcsTask.setTaskPriority(0);
wcsTask.setVehicleId(withVehicleNo);
wcsTask.setOrigin(point);
wcsTask.setDestination(targetLocation.getLocationId());
wcsTask.setCreateTime(LocalDateTime.now());
wcsTask.setSendTime(LocalDateTime.now());
wcsTask.setRemark("WCS");
boolean saveWcsTask = wcsTaskService.save(wcsTask);
if(!saveWcsTask) {
return WcsApiResponse.error("任务创建失败,请稍后再试", null);
}
InTaskResp inTaskResp = new InTaskResp();
inTaskResp.setTaskId(taskId);
inTaskResp.setUser("WMS");
inTaskResp.setVehicleNo(withVehicleNo);
inTaskResp.setDestination(targetLocation.getLocationId());
inTaskResp.setSpare1("");
inTaskResp.setSpare2("");
return WcsApiResponse.success(inTaskResp);
}
InTaskResp inTaskResp = new InTaskResp();
inTaskResp.setTaskId(taskId);
inTaskResp.setUser("WMS");
inTaskResp.setVehicleNo(vehicleId);
inTaskResp.setDestination(targetLocation.getLocationId());
inTaskResp.setSpare1("");
inTaskResp.setSpare2("");
return WcsApiResponse.success(inTaskResp);
} else { // 带料
// 选一个库位
TAppLocation targetLocation = stackerTaskService.getEmptyLocation(2, WmsLocationTypeEnums.TYPE_PRODUCT);
@ -228,11 +227,7 @@ public class WcsControllerServiceImpl implements IWcsControllerService {
if(!saveWcsTask) {
return WcsApiResponse.error("任务创建失败,请稍后再试", null);
}
// 锁定库位
boolean lockLocation = locationService.updateLocationOccupy(targetLocation.getLocationId(), 1);
if(!lockLocation) {
return WcsApiResponse.error("库位锁定失败,请稍后再试", null);
}
InTaskResp inTaskResp = new InTaskResp();
inTaskResp.setTaskId(taskId);
inTaskResp.setUser("WMS");
@ -286,11 +281,7 @@ public class WcsControllerServiceImpl implements IWcsControllerService {
if(!saveWcsTask) {
return WcsApiResponse.error("任务创建失败,请稍后再试", null);
}
// 锁定库位
boolean lockLocation = locationService.updateLocationOccupy(targetLocation.getLocationId(), 1);
if(!lockLocation) {
return WcsApiResponse.error("库位锁定失败,请稍后再试", null);
}
InTaskResp inTaskResp = new InTaskResp();
inTaskResp.setTaskId(taskId);
inTaskResp.setUser("WMS");

View File

@ -29,6 +29,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
@Slf4j
@ -95,6 +96,10 @@ public class YcwmsControllerServiceImpl implements IYcwmsControllerService {
iterator.remove();
}
}
if (request.getVehicleNo().contains("FC")) {
erpGoodsDetails = mesGoodsDetails.stream().map(ErpGoodsDetail::of).collect(Collectors.toList());
mesGoodsDetails.clear();
}
if (!mesGoodsDetails.isEmpty()) {
return YcwmsResponse.error("MES与ERP校验失败", null);
}
@ -174,12 +179,17 @@ public class YcwmsControllerServiceImpl implements IYcwmsControllerService {
if(request.empty()) {
stocks = appStockService.list();
} else {
TAppStock queryEntity = new TAppStock();
queryEntity.setGoodsId(request.getGoodsId());
queryEntity.setLocationId(request.getLocation());
queryEntity.setSled(request.getSpecification());
queryEntity.setVehicleId(request.getVehicleNo());
stocks = appStockService.getWithEntity(queryEntity);
stocks = appStockService.list(
new LambdaQueryWrapper<TAppStock>()
.eq(StringUtils.isNotEmpty(request.getGoodsId()), TAppStock::getGoodsId, request.getGoodsId())
.eq(StringUtils.isNotEmpty(request.getLocation()), TAppStock::getLocationId, request.getLocation())
.eq(StringUtils.isNotEmpty(request.getSpecification()), TAppStock::getSled, request.getSpecification())
.eq(StringUtils.isNotEmpty(request.getVehicleNo()), TAppStock::getVehicleId, request.getVehicleNo())
.eq(StringUtils.isNotEmpty(request.getXsfbillno()), TAppStock::getXsfbillno, request.getXsfbillno())
.eq(request.getXsfseq() != null, TAppStock::getXsfseq, request.getXsfseq())
.eq(StringUtils.isNotEmpty(request.getNeibubianhao()), TAppStock::getNeibubianhao, request.getNeibubianhao())
.eq(StringUtils.isNotEmpty(request.getGoodsBarCode()), TAppStock::getGoodsBarCode, request.getGoodsBarCode())
);
}
if(stocks == null) {
return YcwmsResponse.error("数据服务异常,请稍后重试", null);
@ -221,6 +231,7 @@ public class YcwmsControllerServiceImpl implements IYcwmsControllerService {
return YcwmsResponse.success(respList);
}
@Override
public YcwmsResponse<Object> getAvailPercent(String equipmentId) {
if (equipmentId == null || equipmentId.isEmpty()) {
return YcwmsResponse.error("参数错误", null);
@ -229,7 +240,7 @@ public class YcwmsControllerServiceImpl implements IYcwmsControllerService {
Integer queryId = Integer.parseInt(equipmentId);
Long locationNum500 = appLocationService.count(
new LambdaQueryWrapper<TAppLocation>()
.eq(TAppLocation::getEquipmentId, queryId)
.eq(TAppLocation::getEquipmentId, 4 - queryId)
.eq(TAppLocation::getLocationType, WmsLocationTypeEnums.TYPE_500.getCode())
.eq(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.OCCUPY.getCode())
);
@ -246,7 +257,7 @@ public class YcwmsControllerServiceImpl implements IYcwmsControllerService {
Integer queryId = Integer.parseInt(equipmentId);
Long locationNum = appLocationService.count(
new LambdaQueryWrapper<TAppLocation>()
.eq(TAppLocation::getEquipmentId, queryId)
.eq(TAppLocation::getEquipmentId, 4 - queryId)
.eq(TAppLocation::getLocationType, WmsLocationTypeEnums.TYPE_PRODUCT.getCode())
.eq(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.OCCUPY.getCode())
);
@ -256,7 +267,7 @@ public class YcwmsControllerServiceImpl implements IYcwmsControllerService {
Integer queryId = Integer.parseInt(equipmentId);
Long locationNum = appLocationService.count(
new LambdaQueryWrapper<TAppLocation>()
.eq(TAppLocation::getEquipmentId, queryId)
.eq(TAppLocation::getEquipmentId, 4 - queryId)
.eq(TAppLocation::getLocationType, WmsLocationTypeEnums.TYPE_PRODUCT.getCode())
.eq(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.OCCUPY.getCode())
);
@ -266,51 +277,63 @@ public class YcwmsControllerServiceImpl implements IYcwmsControllerService {
return YcwmsResponse.error("equipmentId无效", null);
}
public YcwmsResponse<Object> localOrderOut(LocalOrderReq request) {
log.info("亚驰单机出库单请求参数{}", JSON.toJSON(request));
@Override
public YcwmsResponse<List<StockResp>> localQuery(LocalOrderReq request) {
log.info("亚驰库存请求参数{}", JSON.toJSON(request));
if(request == null) return YcwmsResponse.error("参数错误", null);
if (StringUtils.isEmpty(request.getNeibubianhao())
|| StringUtils.isEmpty(request.getXsfbillno())
|| StringUtils.isEmpty(String.valueOf(request.getXsfseq()))
|| StringUtils.isEmpty(request.getSpecification())) {
return YcwmsResponse.error("参数错误", null);
}
List<TAppStock> stocks = appStockService.list(
new LambdaQueryWrapper<TAppStock>()
.eq(TAppStock::getNeibubianhao, request.getNeibubianhao())
.eq(TAppStock::getXsfbillno, request.getXsfbillno())
.eq(TAppStock::getXsfseq, request.getXsfseq())
.eq(TAppStock::getSled, request.getSpecification())
);
if (stocks == null || stocks.isEmpty()) {
return YcwmsResponse.error("库存不足, 出库失败", null);
}
TAppOrderOut orderOut = new TAppOrderOut();
orderOut.setRecordId(UUIDUtils.getNewUUID());
orderOut.setOrderId(UUIDUtils.getNewUUID("baokai"));
orderOut.setBatch(stocks.getFirst().getBatch());
orderOut.setSpecification(request.getSpecification());
orderOut.setOrderStatus(OrderStatusEnum.CREATE.getCode());
orderOut.setCreateTime(LocalDateTime.now());
orderOut.setUpdateTime(LocalDateTime.now());
orderOut.setRemark("Local");
String tmpGoodsId = stocks.getFirst().getGoodsId();
if (tmpGoodsId.length() < 3) {
orderOut.setGoodsId(tmpGoodsId);
int tmpGoodsNum = Integer.parseInt(tmpGoodsId);
orderOut.setQuantity((tmpGoodsNum <= 1) ? 1.0 : 4.0);
// stocks: 请求库存的当前库存
List<TAppStock> stocks = null;
if(request.empty()) {
stocks = appStockService.list();
} else {
orderOut.setGoodsId(stocks.getFirst().getVehicleId());
orderOut.setQuantity(0.0);
tmpGoodsId = stocks.getFirst().getVehicleId();
stocks = appStockService.list(
new LambdaQueryWrapper<TAppStock>()
.eq(StringUtils.isNotEmpty(request.getXsfbillno()), TAppStock::getXsfbillno, request.getXsfbillno())
.eq(StringUtils.isNotEmpty(request.getNeibubianhao()), TAppStock::getNeibubianhao, request.getNeibubianhao())
.eq(StringUtils.isNotEmpty(request.getGoodsType()), TAppStock::getGoodsType, request.getGoodsType())
);
}
if(!appOrderOutService.save(orderOut)) {
return YcwmsResponse.error("出库单保存失败,请稍后再试", null);
if(stocks == null) {
return YcwmsResponse.error("数据服务异常,请稍后重试", null);
}
return YcwmsResponse.success(getLocByGoodsId(tmpGoodsId));
List<StockResp> respList = new ArrayList<>();
// locations: 当前库存的对应库位
List<String> locations = stocks.stream().map(TAppStock::getLocationId).distinct().toList();
// 检查每个库存的库位location
for (var location : locations) {
// 库存反馈
StockResp stockResp = new StockResp();
// 查询location库位上当前有多少库存locationStocks
List<TAppStock> locationStocks = stocks.stream().filter(stock -> stock.getLocationId().equals(location)).toList();
if(locationStocks.isEmpty()) {
continue;
}
stockResp.setVehicleNo(locationStocks.getFirst().getVehicleId());
stockResp.setLocation(location);
List<StockRespGoodsDetail> goodsDetails = new ArrayList<>();
for (var stock : locationStocks) {
StockRespGoodsDetail goodsDetail = new StockRespGoodsDetail();
goodsDetail.setGoodsId(stock.getGoodsId());
goodsDetail.setGoodsName(stock.getGoodsDesc());
goodsDetail.setSpecification(stock.getSled());
goodsDetail.setQuantity(stock.getTotalNum());
goodsDetail.setGoodsDesc(stock.getGoodsDesc());
goodsDetail.setStoreTime(stock.getFirstInTime());
goodsDetail.setBatch(stock.getBatch());
goodsDetail.setGoodsType(stock.getGoodsType());
goodsDetail.setGoodsBarCode(stock.getGoodsBarCode());
goodsDetail.setXsfbillno(stock.getXsfbillno());
goodsDetail.setXsfseq(stock.getXsfseq());
goodsDetail.setNeibubianhao(stock.getNeibubianhao());
goodsDetails.add(goodsDetail);
}
stockResp.setGoodsDetail(goodsDetails);
respList.add(stockResp);
}
return YcwmsResponse.success(respList);
}
@Override
public String getLocByGoodsId(String goodsId) {
if (goodsId.length() < 3) {
return switch (goodsId) {
@ -329,4 +352,43 @@ public class YcwmsControllerServiceImpl implements IYcwmsControllerService {
return ConvertUtils.convertDestinationToPoint(stocks.getFirst().getBarCode());
}
}
@Override
public YcwmsResponse<Object> localOut(List<String> vehicleIds) {
if(vehicleIds == null || vehicleIds.isEmpty()) {
return YcwmsResponse.error("出库失败", null);
} else {
for (String vehicleId : vehicleIds.stream().distinct().toList()) {
List<TAppStock> stocks = appStockService.list(
new LambdaQueryWrapper<TAppStock>()
.eq(StringUtils.isNotEmpty(vehicleId), TAppStock::getVehicleId, vehicleId)
);
TAppOrderOut orderOut = new TAppOrderOut();
orderOut.setRecordId(UUIDUtils.getNewUUID());
orderOut.setOrderId(UUIDUtils.getNewUUID("baokai"));
orderOut.setBatch(stocks.getFirst().getBatch());
orderOut.setSpecification(stocks.getFirst().getSled());
orderOut.setOrderStatus(OrderStatusEnum.CREATE.getCode());
orderOut.setCreateTime(LocalDateTime.now());
orderOut.setUpdateTime(LocalDateTime.now());
orderOut.setRemark("Local");
String tmpGoodsId = stocks.getFirst().getGoodsId();
if (tmpGoodsId.length() < 3) {
orderOut.setGoodsId(tmpGoodsId);
int tmpGoodsNum = Integer.parseInt(tmpGoodsId);
orderOut.setQuantity((tmpGoodsNum <= 1) ? 1.0 : 4.0);
} else {
orderOut.setGoodsId(stocks.getFirst().getVehicleId());
orderOut.setQuantity(0.0);
tmpGoodsId = stocks.getFirst().getVehicleId();
}
if(!appOrderOutService.save(orderOut)) {
return YcwmsResponse.error("出库单保存失败,请稍后再试", null);
}
log.info("{} 出库成功", orderOut.getGoodsId());
}
return YcwmsResponse.success("出库成功", null);
}
}
}

View File

@ -121,15 +121,6 @@ public class WcsStackerTaskSender implements Job {
// 若有库存
if (preStocks != null && !preStocks.isEmpty()) {
TAppLocation preLocation = stackerTaskService.getEmptyLocation(equipmentId, null);
// TAppWcsTask preTask = new TAppWcsTask();
// preTask.setWcsTaskId(UUIDUtils.getNewUUID());
// preTask.setWcsTaskType(WcsStackerTaskTypeEnums.IN.getCode());
// preTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.WAIT.getCode());
// preTask.setOrigin(locationId);
// preTask.setDestination(preLocation.getLocationId());
// preTask.setVehicleId(preLocation.getVehicleId());
// preTask.setTaskPriority(2);
// preTask.setCreateTime(LocalDateTime.now());
WcsStackerTaskRequest request = new WcsStackerTaskRequest();
request.setTaskId(UUIDUtils.getNewUUID());

View File

@ -2,7 +2,7 @@ import request from "@/http/request";
const loginWithoutAuth = (params) => {
return request({
url: '/login/loginWithoutAuth',
url: '/wms/login/loginWithoutAuth',
method: 'post',
data: params
})
@ -10,7 +10,7 @@ const loginWithoutAuth = (params) => {
const loginWithAuth = (params) => {
return request({
url: '/login/loginWithAuth',
url: '/wms/login/loginWithAuth',
method: 'post',
data: params
})
@ -18,7 +18,7 @@ const loginWithAuth = (params) => {
const getUser = (params) => {
return request({
url: '/user/getUser',
url: '/wms/user/getUser',
method: 'post',
data: params
})

View File

@ -1,18 +1,7 @@
import request from "@/http/request";
import axios from "axios";
/**
* 提交入库单
*/
const _request = axios.create({
// baseURL: 'http://localhost:12315',
baseURL: 'http://10.18.58.21:12315',
timeout: 5000
})
const submitOrderInForm = (params) => {
return _request({
return request({
url: '/ycwms/orderIn',
method: 'post',
data: params
@ -24,7 +13,7 @@ const submitOrderInForm = (params) => {
*/
const getOrderIns = (params) => {
return request({
url: '/order/getOrderIns',
url: '/wms/order/getOrderIns',
method: 'post',
data: params
})
@ -33,7 +22,7 @@ const getOrderIns = (params) => {
// 修改update方法
const updateOrderIn = (recordId, orderStatus) => {
return request({
url: '/order/updateOrderIn',
url: '/wms/order/updateOrderIn',
method: 'post',
params: { // 使用params传递URL参数
recordId,

View File

@ -1,24 +1,22 @@
import request from "@/http/request";
import axios from "axios";
/**
* 提交入库单
*/
const _request = axios.create({
baseURL: 'http://localhost:12315',
// baseURL: 'http://10.18.58.21:12315',
timeout: 5000
})
const submitOrderOutForm = (params) => {
return _request({
return request({
url: '/ycwms/localOut',
method: 'post',
data: params
})
}
export {
submitOrderOutForm
const localQuery = (params) => {
return request({
url: '/ycwms/localQuery',
method: 'post',
data: params
})
}
export {
submitOrderOutForm,
localQuery
}

View File

@ -2,7 +2,7 @@ import request from "@/http/request";
const queryStocksByPage = (params) => {
return request({
url: '/stock/queryStocksByPage',
url: '/wms/stock/queryStocksByPage',
method: 'post',
data: params
})
@ -10,7 +10,7 @@ const queryStocksByPage = (params) => {
const updateStockInfo = (params) => {
return request({
url: '/stock/updateStockInfo',
url: '/wms/stock/updateStockInfo',
method: 'post',
data: params
})
@ -18,7 +18,7 @@ const updateStockInfo = (params) => {
const getStockNumByGoodsId = (params) => {
return request({
url: '/stock/getStockNumByGoodsId',
url: '/wms/stock/getStockNumByGoodsId',
method: 'post',
data: params
})
@ -26,7 +26,7 @@ const getStockNumByGoodsId = (params) => {
const getStockUpdateRecord = (params) => {
return request({
url: '/stock/getStockUpdateRecord',
url: '/wms/stock/getStockUpdateRecord',
method: 'post',
data: params
})
@ -34,7 +34,7 @@ const getStockUpdateRecord = (params) => {
const handleExceptionStock = (params) => {
return request({
url: '/stock/handleExceptionStock',
url: '/wms/stock/handleExceptionStock',
method: 'post',
data: params
})

View File

@ -1,8 +1,8 @@
import axios from 'axios'
const request = axios.create({
baseURL: 'http://10.18.58.21:12315/wms',
// baseURL: 'http://localhost:12315/wms',
baseURL: 'http://10.18.58.21:12315',
// baseURL: 'http://localhost:12315',
timeout: 5000
})

View File

@ -3,37 +3,67 @@
<el-container class="content">
<div class="work-area">
<fieldset class="main-area">
<legend>出库单信息</legend>
<el-form ref="orderOutFormRef" :model="orderOutForm" :rules="rules" label-width="70px" :label-position="labelPosition" status-icon>
<legend>物料查询</legend>
<el-form ref="queryFormRef" :model="queryForm" label-width="70px" :label-position="labelPosition">
<el-row :gutter="5" class="form-row">
<el-col :xs="24" :sm="4" :md="4" :lg="4">
<el-form-item label="内部编号" prop="neibubianhao">
<el-input v-model="orderOutForm.neibubianhao" clearable @keyup.enter="handleEnter('xsfbillno')" ref="neibubianhaoRef" class="custom-input" />
<el-form-item label="内部编号">
<el-input v-model="queryForm.neibubianhao" clearable class="custom-input" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="4" :md="4" :lg="4">
<el-form-item label="销售单号" prop="xsfbillno">
<el-input v-model="orderOutForm.xsfbillno" clearable @keyup.enter="handleEnter('xsfseq')" ref="xsfbillnoRef" class="custom-input" />
<el-form-item label="规格">
<el-input v-model="queryForm.goodsType" clearable class="custom-input" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="4" :md="4" :lg="4">
<el-form-item label="行号" prop="xsfseq">
<el-input-number v-model="orderOutForm.xsfseq" :min="0" controls-position="right" clearable @keyup.enter="handleEnter('specification')" ref="xsfseqRef" class="custom-input" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="4" :md="4" :lg="4">
<el-form-item label="规格" prop="specification">
<el-input v-model="orderOutForm.specification" placeholder="请输入规格" clearable ref="specificationRef" class="custom-input" />
<el-form-item label="销售单号">
<el-input v-model="queryForm.xsfbillno" clearable class="custom-input" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="4" :md="4" :lg="4" class="btn-col">
<el-button type="success" @click="submitOrderOut">提交</el-button>
<el-button type="warning" @click="resetForm">重置</el-button>
<el-button type="primary" @click="queryGoods">查询</el-button>
<el-button type="info" @click="resetQueryForm">重置</el-button>
</el-col>
</el-row>
</el-form>
</fieldset>
<fieldset v-if="tableData.length > 0" class="main-area">
<legend>查询结果</legend>
<div v-for="(locationItem, locationIndex) in tableData" :key="locationIndex" class="location-group">
<div class="location-header">
<h3>库位: {{ locationItem.location }} | 托盘号: {{ locationItem.vehicleNo }}</h3>
</div>
<el-table
:data="locationItem.goodsDetail"
border
stripe
style="width: 100%"
@selection-change="(selection) => handleSelectionChange(selection, locationItem.vehicleNo)"
:ref="`table_${locationIndex}`">
<el-table-column type="selection" width="55" />
<el-table-column prop="goodsId" label="物料编号" />
<el-table-column prop="goodsName" label="物料名称" />
<el-table-column prop="goodsType" label="规格" />
<el-table-column prop="specification" label="说明" />
<el-table-column prop="quantity" label="数量" />
<el-table-column prop="neibubianhao" label="内部编号" />
<el-table-column prop="xsfbillno" label="销售单号" />
<el-table-column prop="xsfseq" label="行号" />
<el-table-column prop="storeTime" label="入库时间">
<template #default="scope">
{{ scope.row.storeTime ? scope.row.storeTime.split('T')[0] + ' ' + scope.row.storeTime.split('T')[1] : '' }}
</template>
</el-table-column>
</el-table>
</div>
<div class="batch-action-bar">
<el-button type="danger" @click="batchOut" :disabled="getTotalSelectedCount() === 0">出库</el-button>
<span class="selection-info">已选择 {{ getTotalSelectedCount() }} </span>
</div>
</fieldset>
<el-dialog v-model="responseDialogVisible" title="请求结果" width="500px">
<pre>{{ responseResult }}</pre>
<template #footer>
@ -54,7 +84,7 @@ import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { loading } from '@/utils/loading.js'
import { errorBox } from '@/utils/myMessageBox.js'
import { labelPosition } from '@/constant/form'
import { submitOrderOutForm } from '@/api/orderOut.js'
import { submitOrderOutForm, localQuery } from '@/api/orderOut.js'
//
const generateOrderId = () => {
@ -75,24 +105,33 @@ const orderOutForm = reactive({
orderId: generateOrderId(),
neibubianhao: '',
xsfbillno: '',
xsfseq: null,
specification: '',
goodsType: '',
clientId: "WMS"
})
//
const queryFormRef = ref()
const queryForm = reactive({
neibubianhao: '',
goodsType: '',
xsfbillno: ''
})
//
const tableData = ref([])
const selectedItemsMap = ref(new Map()) // Map
//
const rules = reactive({
neibubianhao: [{ required: true, message: '请输入内部编号', trigger: 'blur' }],
xsfbillno: [{ required: true, message: '请输入销售单号', trigger: 'blur' }],
xsfseq: [{ required: true, message: '请输入行号', trigger: 'blur' }],
specification: [{ required: true, message: '请输入规格', trigger: 'blur' }]
goodsType: [{ required: true, message: '请输入规格', trigger: 'blur' }]
})
// DOM
const neibubianhaoRef = ref()
const xsfbillnoRef = ref()
const xsfseqRef = ref()
const specificationRef = ref()
const goodsTypeRef = ref()
//
const responseDialogVisible = ref(false)
@ -120,10 +159,9 @@ const handleEnter = (nextField) => {
const refMap = {
'neibubianhao': neibubianhaoRef,
'xsfbillno': xsfbillnoRef,
'xsfseq': xsfseqRef,
'specification': specificationRef
'goodsType': goodsTypeRef
}
if (refMap[nextField]) {
refMap[nextField].value.focus()
}
@ -139,35 +177,101 @@ const resetForm = () => {
})
}
//
const submitOrderOut = () => {
orderOutFormRef.value.validate((valid) => {
if (valid) {
//
loading.open()
submitOrderOutForm(orderOutForm)
.then(res => {
responseResult.value = res.data
responseDialogVisible.value = true
if (res.data.code === 0) {
ElMessage.success('出库单提交成功')
resetForm() //
} else {
errorBox(`出库单提交失败: ${res.data.message}`)
}
})
.catch(err => {
console.error(err)
errorBox('提交出库单时发生错误')
})
.finally(() => {
loading.close()
})
} else {
errorBox('请填写完整的出库单信息')
}
//
const resetQueryForm = () => {
queryFormRef.value.resetFields()
tableData.value = []
selectedItemsMap.value.clear()
}
//
const queryGoods = () => {
loading.open()
localQuery(queryForm)
.then(res => {
if (res.data.code === 0) {
tableData.value = res.data.returnData || []
selectedItemsMap.value.clear() //
if (tableData.value.length === 0) {
ElMessage.info('未查询到相关物料信息')
}
} else {
errorBox(`查询失败: ${res.data.message}`)
}
})
.catch(err => {
console.error(err)
errorBox('查询物料时发生错误')
})
.finally(() => {
loading.close()
})
}
//
const handleSelectionChange = (selection, vehicleNo) => {
//
if (selection.length > 0) {
selectedItemsMap.value.set(vehicleNo, selection)
} else {
selectedItemsMap.value.delete(vehicleNo)
}
}
//
const getTotalSelectedCount = () => {
let count = 0
selectedItemsMap.value.forEach(items => {
count += items.length
})
return count
}
//
const batchOut = () => {
if (getTotalSelectedCount() === 0) {
ElMessage.warning('请至少选择一项物料')
return
}
//
const selectedVehicleNos = []
selectedItemsMap.value.forEach((selectedItems, vehicleNo) => {
//
selectedItems.forEach(item => {
selectedVehicleNos.push(vehicleNo)
})
})
console.log('选中的载具号列表:', selectedVehicleNos)
if (selectedVehicleNos.length === 0) {
ElMessage.warning('无法获取选中物料的载具号')
return
}
loading.open()
submitOrderOutForm(selectedVehicleNos)
.then(res => {
responseResult.value = res.data
responseDialogVisible.value = true
if (res.data.code === 0) {
ElMessage.success(`出库成功,共处理 ${selectedVehicleNos.length} 项物料`)
//
queryGoods()
} else {
errorBox(`出库失败: ${res.data.message}`)
}
})
.catch(err => {
console.error(err)
errorBox('出库时发生错误')
})
.finally(() => {
loading.close()
})
}
</script>
@ -243,4 +347,33 @@ pre {
margin-left: 0;
height: 40px;
}
.location-group {
margin-bottom: 20px;
}
.location-header {
background-color: #f5f7fa;
padding: 8px 15px;
border-radius: 4px 4px 0 0;
margin-bottom: 5px;
}
.location-header h3 {
margin: 0;
font-size: 14px;
color: #606266;
}
.batch-action-bar {
margin-top: 15px;
display: flex;
align-items: center;
}
.selection-info {
margin-left: 15px;
color: #606266;
font-size: 14px;
}
</style>