修复bug:

1. 修复移库bug, 空盘只有1深度, 不存在移库问题; 空托出库按照深度, 层数, 列数, 排数依次升序排序, 从而避免移库操作; 成品移库寻找库位时修改接口调用参数为成品枚举
This commit is contained in:
李宇奇 2025-06-03 11:12:04 +08:00
parent 2ea7816428
commit 50dff8130e
7 changed files with 148 additions and 32 deletions

View File

@ -15,4 +15,13 @@ public enum WmsLocationTypeEnums {
TYPE_PRODUCT(3, "成品");
private final Integer code;
private final String desc;
public static WmsLocationTypeEnums getEnum(Integer code) {
for (WmsLocationTypeEnums e : WmsLocationTypeEnums.values()) {
if (e.getCode().equals(code)) {
return e;
}
}
return null;
}
}

View File

@ -57,7 +57,7 @@ public class YcwmsController {
public YcwmsResponse<Object> getOutLocation(@RequestBody OrderOutReq request) {
String outLoc = ycwmsControllerService.getLocByGoodsId(request.getGoodsId());
if (StringUtils.isEmpty(outLoc)) {
return YcwmsResponse.error("查询为空", null);
return YcwmsResponse.error("查询库存为空", null);
} else {
return YcwmsResponse.success(outLoc);
}

View File

@ -0,0 +1,53 @@
package com.wms_main.repository.utils;
import com.wms_main.model.po.TAppStock;
import java.util.Comparator;
public class LocationIdComparator implements Comparator<TAppStock> {
@Override
public int compare(TAppStock s1, TAppStock s2) {
int[] parts1 = parseLocationId(s1.getLocationId());
int[] parts2 = parseLocationId(s2.getLocationId());
// 1. 深度排序 (最后一部分)
int cmp = Integer.compare(parts1[3], parts2[3]);
if (cmp != 0) return cmp;
// 2. 层数排序 (第三部分)
cmp = Integer.compare(parts1[2], parts2[2]);
if (cmp != 0) return cmp;
// 3. 列排序 (第二部分)
cmp = Integer.compare(parts1[1], parts2[1]);
if (cmp != 0) return cmp;
// 4. 排排序 (第一部分)
return Integer.compare(parts1[0], parts2[0]);
}
private int[] parseLocationId(String locationId) {
// 处理可能的空值
if (locationId == null || locationId.isEmpty()) return new int[4];
String[] parts = locationId.split("-");
int[] result = new int[4];
try {
// 处理第一部分"A03" -> 提取数字3
if (parts.length > 0) {
String p1 = parts[0].replaceAll("\\D", "");
result[0] = p1.isEmpty() ? 0 : Integer.parseInt(p1);
}
// 处理第二四部分
for (int i = 1; i <= 3; i++) {
if (parts.length > i) {
result[i] = Integer.parseInt(parts[i]);
}
}
} catch (NumberFormatException e) {
// 处理格式异常
}
return result;
}
}

View File

@ -153,21 +153,26 @@ public class YcwmsControllerServiceImpl implements IYcwmsControllerService {
if(!orderOutCheckList.isEmpty()) {
return YcwmsResponse.error("出库单已存在,请勿重复推送", null);
}
TAppOrderOut orderOut = new TAppOrderOut();
orderOut.setRecordId(UUIDUtils.getNewUUID());
orderOut.setOrderId(request.getOrderId());
orderOut.setGoodsId(request.getGoodsId());
orderOut.setBatch(request.getBatch());
orderOut.setSpecification(request.getSpecification());
orderOut.setQuantity(request.getQuantity());
orderOut.setOrderStatus(OrderStatusEnum.CREATE.getCode());
orderOut.setCreateTime(LocalDateTime.now());
orderOut.setUpdateTime(LocalDateTime.now());
orderOut.setRemark(request.getClientId());
if(!appOrderOutService.save(orderOut)) {
return YcwmsResponse.error("出库单保存失败,请稍后再试", null);
String outPoint = getLocByGoodsId(request.getGoodsId());
if (StringUtils.isEmpty(outPoint)) {
return YcwmsResponse.error("库存不足", null);
} else {
TAppOrderOut orderOut = new TAppOrderOut();
orderOut.setRecordId(UUIDUtils.getNewUUID());
orderOut.setOrderId(request.getOrderId());
orderOut.setGoodsId(request.getGoodsId());
orderOut.setBatch(request.getBatch());
orderOut.setSpecification(request.getSpecification());
orderOut.setQuantity(request.getQuantity());
orderOut.setOrderStatus(OrderStatusEnum.CREATE.getCode());
orderOut.setCreateTime(LocalDateTime.now());
orderOut.setUpdateTime(LocalDateTime.now());
orderOut.setRemark(request.getClientId());
if(!appOrderOutService.save(orderOut)) {
return YcwmsResponse.error("出库单保存失败,请稍后再试", null);
}
return YcwmsResponse.success(outPoint);
}
return YcwmsResponse.success(getLocByGoodsId(request.getGoodsId()));
}
@Override
@ -335,20 +340,21 @@ public class YcwmsControllerServiceImpl implements IYcwmsControllerService {
@Override
public String getLocByGoodsId(String goodsId) {
List<TAppStock> stocks = null;
if (goodsId.length() < 3) {
return switch (goodsId) {
case "0" -> "LK-3";
case "1" -> "LK-4";
case "2" -> "LK-5";
case "3" -> "LK-6";
case "4" -> "LK-7";
default -> "";
};
stocks = appStockService.list(
new LambdaQueryWrapper<TAppStock>()
.eq(TAppStock::getGoodsId, goodsId)
);
} else {
List<TAppStock> stocks = appStockService.list(
stocks = appStockService.list(
new LambdaQueryWrapper<TAppStock>()
.eq(TAppStock::getVehicleId, goodsId)
);
}
if (stocks == null || stocks.isEmpty()) {
return "";
} else {
return ConvertUtils.convertDestinationToPoint(stocks.getFirst().getBarCode());
}
}

View File

@ -5,10 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms_main.constant.enums.wcs.WcsApiResponseCodeEnums;
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
import com.wms_main.constant.enums.wcs.WcsStackerTaskTypeEnums;
import com.wms_main.constant.enums.wms.OrderStatusEnum;
import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums;
import com.wms_main.constant.enums.wms.WmsStockStatusEnums;
import com.wms_main.constant.enums.wms.WmsVehicleStatusEnums;
import com.wms_main.constant.enums.wms.*;
import com.wms_main.dao.*;
import com.wms_main.model.bo.wcs.WcsStackerTask;
import com.wms_main.model.dto.request.wcs.WcsStackerTaskRequest;
@ -54,6 +51,8 @@ public class WcsStackerTaskSender implements Job {
private final ITAppVehicleService appVehicleService;
private final ITAppLocationService appLocationService;
/**
* 运行定时任务
* 向Wcs发送堆垛机任务
@ -68,6 +67,12 @@ public class WcsStackerTaskSender implements Job {
.eq(TAppWcsTask::getWcsTaskType, WcsStackerTaskTypeEnums.OUT.getCode()));
for (TAppWcsTask wcsTask : appWcsTasks) {
String locationId = wcsTask.getOrigin();
TAppLocation loc = appLocationService.list(
new LambdaQueryWrapper<TAppLocation>()
.eq(TAppLocation::getLocationId, locationId)
).getFirst();
Integer locType = loc.getLocationType();
WmsLocationTypeEnums locEnum = WmsLocationTypeEnums.getEnum(locType);
String[] str_lst = locationId.split("-");
Integer equipmentId = appWcsTaskService.getEquipmentByLocation(locationId);
Integer depth = appWcsTaskService.getDepthByLocation(locationId);
@ -120,7 +125,7 @@ public class WcsStackerTaskSender implements Job {
.eq(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode()));
// 若有库存
if (preStocks != null && !preStocks.isEmpty()) {
TAppLocation preLocation = stackerTaskService.getEmptyLocation(equipmentId, null);
TAppLocation preLocation = stackerTaskService.getEmptyLocation(equipmentId, locEnum);
WcsStackerTaskRequest request = new WcsStackerTaskRequest();
request.setTaskId(UUIDUtils.getNewUUID());

View File

@ -15,6 +15,7 @@ import com.wms_main.dao.ITAppWcsTaskService;
import com.wms_main.model.po.TAppOrderOut;
import com.wms_main.model.po.TAppStock;
import com.wms_main.model.po.TAppWcsTask;
import com.wms_main.repository.utils.LocationIdComparator;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.repository.utils.UUIDUtils;
import lombok.RequiredArgsConstructor;
@ -84,6 +85,7 @@ public class YcOutExecutor implements Job {
stock.setGoodsId(orderOut.getGoodsId());
stock.setSled(orderOut.getSpecification());
List<TAppStock> stockList = stockService.getWithEntity(stock);
stockList.sort(new LocationIdComparator());
// 提取所有相关库存的载具号
List<String> vehicleIds = stockList.stream().map(TAppStock::getVehicleId).distinct().toList();
List<TAppStock> outStockList = new ArrayList<TAppStock>();

View File

@ -199,7 +199,7 @@
</template>
</el-table-column>
<!-- 修改后 -->
<el-table-column label="操作" width="180" fixed="right">
<el-table-column label="操作" width="240" fixed="right">
<template #default="scope">
<div class="action-buttons">
<el-button
@ -214,6 +214,12 @@
@click="openEditDialog(scope.row)"
class="btn-edit"
>编辑</el-button>
<el-button
type="danger"
size="small"
@click="deleteOrderInRecord(scope.row)"
class="btn-delete"
>删除</el-button>
</div>
</template>
</el-table-column>
@ -288,12 +294,12 @@
<script setup>
import {reactive, ref, onMounted, nextTick, onBeforeUnmount} from 'vue'
import {ElMessage} from 'element-plus'
import {ElMessage, ElMessageBox} from 'element-plus'
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 {submitOrderInForm, getOrderIns, updateOrderIn} from '@/api/orderIn.js'
import {submitOrderInForm, getOrderIns, updateOrderIn, deleteOrderIn} from '@/api/orderIn.js'
//
const generateOrderId = () => {
@ -567,6 +573,41 @@ const saveOrderStatus = () => {
})
}
//
const deleteOrderInRecord = (row) => {
ElMessageBox.confirm(
`确认删除入库单 ${row.orderId} 吗?此操作不可恢复!`,
'删除确认',
{
confirmButtonText: '确定删除',
cancelButtonText: '取消',
type: 'warning',
confirmButtonClass: 'el-button--danger'
}
).then(() => {
loading.open()
deleteOrderIn(row.recordId)
.then(res => {
if (res.data.code === 0) {
ElMessage.success('入库单删除成功')
//
orderInsList.value = orderInsList.value.filter(item => item.recordId !== row.recordId)
} else {
errorBox(`删除入库单失败: ${res.data.message}`)
}
})
.catch(err => {
console.error(err)
errorBox('删除入库单时发生错误')
})
.finally(() => {
loading.close()
})
}).catch(() => {
//
})
}
</script>
<style scoped>