Commit 85cba47b 张少辉

1.成品仓功能开发

1 个父辈 5d02d793
......@@ -219,4 +219,8 @@ public class Constants {
*/
public static final String Cache_ShelfInfo = "Cache_ShelfInfo";
/**
* 缓存的出口信息
*/
public static final String Cache_PutOutLoc_Info ="Cache_PutOutLoc_Info";
}
......@@ -102,4 +102,6 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
int getRemainPosCountByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds, String s, String f);
StoragePos getByPidBarcode(String reelId);
StoragePos findFgWarehouseForPutIn(Storage fgWarehouseStorage, Barcode barcode, Collection<String> strings, boolean heightLimited);
}
......@@ -398,6 +398,48 @@ public class StoragePosManagerImpl implements IStoragePosManager {
}
@Override
public StoragePos findFgWarehouseForPutIn(Storage storage, Barcode barcode, Collection<String> excludePosIds, boolean heightLimited) {
Criteria c = Criteria.where("storageId").is(storage.getId());
COMPATIBLE_TYPE compatibleType = storage.getCompatibleType();
if (compatibleType == COMPATIBLE_TYPE.EXACT_MATCH) {//完全匹配
c = c.and("w").is(barcode.getPlateSize()).and("h").is(barcode.getHeight());
} else if (compatibleType == COMPATIBLE_TYPE.FULLY_COMPATIBLE) {//完全兼容
c = c.and("w").gte(barcode.getPlateSize()).and("h").gte(barcode.getHeight());//宽度大于等于料盘宽度,高度大于等于料盘高度
} else if (compatibleType == COMPATIBLE_TYPE.SIZE_COMPATIBLE) {//同尺寸兼容
c = c.and("w").is(barcode.getPlateSize()).and("h").gte(barcode.getHeight());//宽度等于料盘宽度,高度大于等于料盘高度
} else if (compatibleType == COMPATIBLE_TYPE.W13_15_COMPATIBLE) {
//13/15寸兼容,如果是13寸盘,可以放15寸,其他按照同尺寸兼容
if (barcode.getPlateSize() == 13) {
c = c.and("w").in(barcode.getPlateSize(), 15).and("h").gte(barcode.getHeight());
} else {
c = c.and("w").is(barcode.getPlateSize()).and("h").gte(barcode.getHeight());//宽度等于料盘宽度,高度大于等于料盘高度
}
}
c = c.and("enabled").is(true)//可用
.and("used").is(false);//未使用
//去除的仓位
if (excludePosIds != null && !excludePosIds.isEmpty()) {
c = c.and("id").nin(excludePosIds);
}
//判断有没有限高
//判断有没有限高
if(heightLimited){
// 限高:匹配仓位编码最后以-03结尾(请确认字段名是posCode,若不是请替换)
Pattern pattern = Pattern.compile("-03$");
c = c.and("posName").regex(pattern);
} else {
// 不限高:匹配仓位编码最后不是-03结尾
Pattern pattern = Pattern.compile("^(.*(?<!-03))$");
c = c.and("posName").regex(pattern);
}
Query query = new Query(c);
//优先放入最合适的位置(根据尺寸),相同尺寸按优先级排序
query.with(Sort.by(Sort.Direction.ASC, "w").and(Sort.by(Sort.Direction.ASC, "h")).and(Sort.by(Sort.Direction.DESC, "priority")));
StoragePos pos = storagePosDao.findOne(query);
return pos;
}
@Override
public PageData<StoragePos> findByPage(Query query, Pageable pageable) {
int totalCount = storagePosDao.countByQuery(query);
List<StoragePos> list = storagePosDao.findByQuery(query, pageable);
......
package com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.bean;
/**
* 入库位置信息DTO:专门封装「实际位置+是否限高」,用于接口返回结构化数据
* 包路径可根据你的项目调整,例如:com.xxx.warehouse.dto
*/
public class PutAwayLocInfo {
// 实际位置(对应枚举的actualPosition字段)
private String actualPosition;
// 是否限高(对应枚举的heightLimited字段)
private boolean heightLimited;
// 全参构造方法(用于枚举中快速封装数据)
public PutAwayLocInfo(String actualPosition, boolean heightLimited) {
this.actualPosition = actualPosition;
this.heightLimited = heightLimited;
}
// 无参构造方法(可选,适配部分框架的反序列化需求)
public PutAwayLocInfo() {
}
// getter/setter方法(必须,接口返回时框架需通过getter序列化字段)
public String getActualPosition() {
return actualPosition;
}
public void setActualPosition(String actualPosition) {
this.actualPosition = actualPosition;
}
public boolean isHeightLimited() {
return heightLimited;
}
public void setHeightLimited(boolean heightLimited) {
this.heightLimited = heightLimited;
}
// 可选:重写toString,便于日志打印/调试查看数据
@Override
public String toString() {
return "PutAwayLocInfo{" +
"actualPosition='" + actualPosition + '\'' +
", heightLimited=" + heightLimited +
'}';
}
}
\ No newline at end of file
package com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class PutOutLocInfo {
//配置给agv使用的名称
private String name;
//实际位置
private String actualPosition;
//当前绑定的料箱号
private String currentBindBox;
}
\ No newline at end of file
package com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.controller;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.ReelLockPosUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.storage.enums.CORRESPONDING_WAREHOUSE;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.aiqingzhiyin1643.bean.CtuCheckOutTask;
import com.neotel.smfcore.custom.aiqingzhiyin1643.bean.CtuPutInTask;
import com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.util.PutOutLocInfoCache;
import com.neotel.smfcore.custom.aiqingzhiyin1643.util.BoxUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@Api(tags = "成品仓agv对接")
@Slf4j
@RequestMapping("/agvFgDevice")
@RestController
public class AgvFgDeviceController {
@Autowired
private TaskService taskService;
@Autowired
private DataCache dataCache;
@Autowired
private PutOutLocInfoCache putOutLocInfoCache;
@ApiOperation("定时获取入库任务")
@RequestMapping("/service/store/agvBox/getPutInTask")
@AnonymousAccess
public ResultBean getPutInTask(String cid) {
List<CtuPutInTask> putInTaskList = new ArrayList<>();
List<DataLog> allTasks = taskService.getAllTasks();
Storage storage = dataCache.getStorage(cid);
if (storage.getCorrespondingWarehouse() == CORRESPONDING_WAREHOUSE.FINISHED_GOODS_WAREHOUSE) {
if (storage != null) {
for (DataLog dataLog : allTasks) {
if (dataLog.isPutInTask() && !dataLog.isFinished() && !dataLog.isCancel() && storage.getId().equals(dataLog.getStorageId())) {
CtuPutInTask putInTask = new CtuPutInTask();
putInTask.setStatus(dataLog.getStatus());
putInTask.setPosName(dataLog.getPosName());
putInTask.setBarcode(dataLog.getBarcode());
putInTask.setPutInLoc(dataLog.getCurrentLoc());
putInTaskList.add(putInTask);
}
}
}
}
return ResultBean.newOkResult(putInTaskList);
}
@ApiOperation("定时获取出库库位列表")
@RequestMapping(value = "/service/store/agvBox/getOutTask")
@AnonymousAccess
public synchronized ResultBean getOutTask(HttpServletRequest request) {
List<CtuCheckOutTask> ctuCheckOutTaskList = new ArrayList<>();
String cid = request.getParameter("cid");
Storage storage = dataCache.getStorage(cid);
if (storage != null) {
if (storage.getCorrespondingWarehouse() == CORRESPONDING_WAREHOUSE.FINISHED_GOODS_WAREHOUSE) {
Collection<DataLog> queueTasks = taskService.getQueueTasks();
queueTasks = queueTasks.stream().sorted(Comparator.comparing(DataLog::getCreateDate)).collect(Collectors.toList());
for (DataLog queueTask : queueTasks) {
if (queueTask.isWait() && queueTask.isCheckOutTask()) {
CtuCheckOutTask ctuCheckOutTask = new CtuCheckOutTask();
ctuCheckOutTask.setBarcode(queueTask.getBarcode());
ctuCheckOutTask.setPosName(queueTask.getPosName());
ctuCheckOutTask.setStatus(queueTask.getStatus());
String currentLoc = queueTask.getCurrentLoc();
if (StringUtils.isEmpty(currentLoc)) {
currentLoc = putOutLocInfoCache.bindCurrentBox(queueTask.getBarcode());
}
if (StringUtils.isNotEmpty(currentLoc)) {
ctuCheckOutTask.setCheckOutLoc(currentLoc);
ctuCheckOutTaskList.add(ctuCheckOutTask);
}
}
}
}
}
return ResultBean.newOkResult(ctuCheckOutTaskList);
}
@ApiOperation("修改任务接口")
@RequestMapping(value = "/service/store/agvBox/updateLocInfo")
@AnonymousAccess
public synchronized ResultBean updateLocInfo(HttpServletRequest request) {
String rfid = request.getParameter("barcode");
String statusStr = request.getParameter("status");
String cid = request.getParameter("cid");
String loc = request.getParameter("loc"); //工位
log.info("收到料盘[" + rfid + "]更新位置指令[" + statusStr + "]"+"cid为:"+cid);
if (statusStr == null) {
return ResultBean.newErrorResult(301, "smfcore.updateLoc.status.empty", "状态不能为空");
}
if (rfid == null) {
return ResultBean.newErrorResult(302, "smfcore.updateLoc.barcode.empty", "条码不能为空");
}
Storage storage = dataCache.getStorage(cid);
if (storage == null){
return ResultBean.newErrorResult(-1,"","未找到对应的料仓信息");
}
if (storage.getCorrespondingWarehouse() != CORRESPONDING_WAREHOUSE.FINISHED_GOODS_WAREHOUSE){
return ResultBean.newErrorResult(-1, "", "请在设备管理里,配置成品仓信息");
}
DataLog opTask = null;
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog task : allTasks) {
if (rfid.startsWith(task.getBarcode()) && storage.getId().equals(task.getStorageId())) {
if (!task.isCancel() && !task.isFinished()) {
opTask = task;
break;
}
}
}
if (opTask == null) {
return ResultBean.newErrorResult(303, "smfcore.task.notExist", "任务不存在");
}
if (opTask.isFinished()) {
return ResultBean.newErrorResult(304, "smfcore.task.hasEnd", "任务已完成");
}
statusStr = statusStr.toUpperCase();
log.info("更新料箱[" + rfid + "]的任务状态[" + opTask.getStatus() + "]为[" + statusStr + "]" + "目的地信息为:" + loc);
OP_STATUS updateStatus = OP_STATUS.valueOf(statusStr);
//如果是相同状态,则不执行
if (statusStr.equals(opTask.getStatus())) {
return ResultBean.newOkResult("");
}
if (updateStatus != null) {
opTask.setStatus(statusStr);
if (opTask.isCheckOutTask()) {
if (OP_STATUS.EXECUTING.name().equals(statusStr)) {
//在执行队列中
taskService.updateQueueTask(opTask);
} else {
taskService.moveTaskToFinished(opTask);
if (!opTask.isOutFromPos()) {
//从库位中取出,需要移到完成队列中,并且清理库存
BoxUtil.outFromPos(opTask);
opTask.setOutFromPos(true);
}
taskService.updateFinishedTask(opTask);
if (!opTask.isNotifyMomo()) {
opTask.setNotifyMomo(true);
taskService.updateFinishedTask(opTask);
}
if (OP_STATUS.FINISHED.name().equals(statusStr)) {
//已完成,从完成缓存中清除
taskService.removeFinishedTask(opTask);
}
}
} else {
opTask.setStatus(statusStr);
//入库任务
if (OP_STATUS.FINISHED.name().equals(statusStr)) {
taskService.moveTaskToFinished(opTask);
BoxUtil.intoPos(opTask);
ReelLockPosUtil.removeReelLockPosInfo(opTask.getBarcode());
} else {
taskService.updateQueueTask(opTask);
}
}
} else {
log.info(rfid + "更新状态时未找到状态:" + statusStr + "");
}
return ResultBean.newOkResult("");
}
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.controller;
import com.alibaba.excel.util.StringUtils;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.ReelLockPosUtil;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.utils.CodeResolve;
import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.storage.enums.CORRESPONDING_WAREHOUSE;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.bean.PutAwayLocInfo;
import com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.enums.PutAwayLocEnum;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
@Api(tags = "上架相关")
@Slf4j
@RequestMapping("/fgWarehouse/putAway")
@RestController
public class PutAwayController {
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private TaskService taskService;
@Autowired
private CodeResolve codeResolve;
@Autowired
private DataCache dataCache;
@ApiOperation("获取入库位置及限高信息")
@RequestMapping("/getLocHeightLimitInfo")
@AnonymousAccess
public ResultBean getLocHeightLimitInfo() {
// 1. 调用枚举方法,获取封装好的「实际位置+是否限高」列表
List<PutAwayLocInfo> locInfoList = PutAwayLocEnum.getAllLocInfo();
return ResultBean.newOkResult(locInfoList);
}
// 确保Controller类添加@Slf4j(无Lombok则替换为LoggerFactory)
@ApiOperation("扫描码拖条码进行入库")
@RequestMapping("/scanDragBarcodePutaway")
@AnonymousAccess
public ResultBean scanDragBarcodePutaway(@RequestBody Map<String, String> paramMap) {
String barcodeStr = paramMap.get("barcode");
String actualPosition = paramMap.get("actualPosition");
String operator = SecurityUtils.getLoginUsername();
// 1. 基础入参(精简)
log.info("扫码入库:条码=" + barcodeStr + ",实际位置=" + actualPosition + ",操作人=" + operator);
if (StringUtils.isEmpty(barcodeStr)) {
log.warn("扫码入库失败:条码为空,操作人=" + operator);
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"码拖条码"});
}
// 判断成品仓配置
Storage fgWarehouseStorage = null;
for (Storage storage : dataCache.getAllStorage().values()) {
if (storage.getCorrespondingWarehouse() == CORRESPONDING_WAREHOUSE.FINISHED_GOODS_WAREHOUSE) {
fgWarehouseStorage = storage;
break;
}
}
if (fgWarehouseStorage == null) {
log.error("扫码入库失败:未配置成品仓,操作人=" + operator);
return ResultBean.newErrorResult(-1, "", "请在设备管理里,配置成品仓信息");
}
// 2. 成品仓核心信息(仅ID/名称)
log.info("成品仓配置:ID=" + fgWarehouseStorage.getId() + ",名称=" + fgWarehouseStorage.getName());
// 解析条码
Barcode barcode = null;
try {
barcode = codeResolve.resolveOneValideBarcode("=2x2="+barcodeStr);
// 3. 条码解析核心信息
log.info("条码解析成功:解析后条码=" + barcode.getBarcode() + ",料盘尺寸=" + barcode.getPlateSize() + ",高度=" + barcode.getHeight());
} catch (ValidateException e) {
log.error("条码解析失败:原始条码=" + barcodeStr + ",异常=" + e.getMessage());
return ResultBean.newErrorResult(-1, e.getMsgKey(), e.getMessage(), e.getMsgParam());
}
// 检查执行中任务
for (DataLog task : taskService.getAllTasks()) {
if (!task.isFinished() && !task.isCancel() && barcode.getBarcode().equals(task.getBarcode()) && fgWarehouseStorage.getId().equals(task.getStorageId())) {
log.warn("扫码入库失败:条码" + barcode.getBarcode() + "有执行中任务,任务ID=" + task.getId());
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.executing", "条码[{0}}]任务正在执行", new String[]{barcodeStr});
}
}
// 检查库位占用
StoragePos oldPos = storagePosManager.getByBarcode(barcode.getBarcode());
if (oldPos != null){
log.warn("扫码入库失败:条码" + barcode.getBarcode() + "已在库位" + oldPos.getPosName());
return ResultBean.newErrorResult(-1,"smfcore.materialBox.inPos","物料已在库位{0}中",new String[]{oldPos.getPosName()});
}
// 移除锁定库位
ReelLockPosUtil.removeReelLockPosInfo(barcode.getBarcode());
log.info("移除条码" + barcode.getBarcode() + "锁定库位信息");
// 限高+库位匹配
PutAwayLocEnum putAwayLocEnum = PutAwayLocEnum.getByActualPosition(actualPosition);
boolean heightLimited = putAwayLocEnum.isHeightLimited();
log.info("限高配置:实际位置=" + actualPosition + ",是否限高=" + heightLimited);
StoragePos pos = storagePosManager.findFgWarehouseForPutIn(fgWarehouseStorage,barcode,taskService.excludePosIds(),heightLimited);
if (pos == null){
log.error("扫码入库失败:条码" + barcodeStr + "未找到可用库位,限高=" + heightLimited);
return ResultBean.newErrorResult(-1,"","[{0}]未找到可用的库位",new String[]{barcodeStr});
}
// 4. 核心:找到的库位信息(仅ID+名称)
log.info("找到可用库位:条码=" + barcodeStr + ",库位ID=" + pos.getId() + ",库位名称=" + pos.getPosName() + ",限高=" + heightLimited);
// 生成任务
DataLog dataLog = new DataLog(fgWarehouseStorage, barcode, pos);
dataLog.setType(OP.PUT_IN);
dataLog.setOperator(operator);
dataLog.setCurrentLoc(putAwayLocEnum.name());
taskService.addTaskToExecute(dataLog);
// 5. 任务生成核心信息
log.info("入库任务生成:任务ID=" + dataLog.getId() + ",条码=" + barcode.getBarcode() + ",入库库位=" + pos.getPosName());
return ResultBean.newOkResult("");
}
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.controller;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.bean.PutOutLocInfo;
import com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.util.PutOutLocInfoCache;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@Api(tags = "下架相关")
@Slf4j
@RequestMapping("/fgWarehouse/putOut")
@RestController
public class PutOutController {
@Autowired
private TaskService taskService;
@Autowired
private PutOutLocInfoCache putOutLocInfoCache;
@ApiOperation("获取所有的出库位置")
@RequestMapping("/getAllPutOutLocInfo")
@AnonymousAccess
private ResultBean getAllPutOutLocInfo() {
Collection<PutOutLocInfo> putOutLocInfoList = putOutLocInfoCache.getAllPutOutLocInfo();
putOutLocInfoList = putOutLocInfoList.stream()
.sorted(Comparator.comparing(PutOutLocInfo::getName))
.collect(Collectors.toCollection(ArrayList::new));
return ResultBean.newOkResult(putOutLocInfoList);
}
@ApiOperation("清空当前位置信息")
@RequestMapping("/clearCurrentBindBoxInfo")
@AnonymousAccess
private synchronized ResultBean clearCurrentBindBoxInfo(String actualPosition) {
PutOutLocInfo putOutLocInfo = putOutLocInfoCache.getPutOutLocInfoByActualPosition(actualPosition);
if (putOutLocInfo != null) {
String currentBindBox = putOutLocInfo.getCurrentBindBox();
if (StringUtils.isNotEmpty(currentBindBox)) {
for (DataLog task : taskService.getAllTasks()) {
if (!task.isFinished() && !task.isCancel() && currentBindBox.equals(task.getBarcode())) {
log.warn("扫码入库失败:条码" + currentBindBox + "有执行中任务,任务ID=" + task.getId());
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.executing", "条码[{0}}]任务正在执行", new String[]{currentBindBox});
}
}
}
}
putOutLocInfoCache.removeCurrentBindBoxInfo(actualPosition);
return ResultBean.newOkResult("");
}
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.enums;
import com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.bean.PutAwayLocInfo;
import java.util.ArrayList;
import java.util.List;
/**
* 入库位置枚举类(PutAwayLocEnum)
* 包含位置标识、实际位置(默认与标识一致)、是否限高三个核心属性
*/
public enum PutAwayLocEnum {
// 枚举项:枚举名(实际位置, 是否限高)
// 默认实际位置与枚举名一致,是否限高可根据业务需求修改(true=限高,false=不限高)
inPos1("inPos1", false),
inPos2("inPos2", false),
inPos3("inPos3", false),
inPos4("inPos4", false),
inPos5("inPos5", true);
// 实际位置(默认和枚举名一致,可自定义)
private final String actualPosition;
// 是否限高(boolean类型,true=限高,false=不限高)
private final boolean heightLimited;
/**
* 枚举构造方法(必须私有,枚举构造方法不能公开)
* @param actualPosition 实际位置
* @param heightLimited 是否限高
*/
PutAwayLocEnum(String actualPosition, boolean heightLimited) {
this.actualPosition = actualPosition;
this.heightLimited = heightLimited;
}
// 核心方法:获取所有位置的「实际位置+是否限高」列表(返回DTO集合)
public static List<PutAwayLocInfo> getAllLocInfo() {
// 初始化DTO列表
List<PutAwayLocInfo> locInfoList = new ArrayList<>();
// 遍历所有枚举项,封装为DTO并加入列表
for (PutAwayLocEnum loc : PutAwayLocEnum.values()) {
PutAwayLocInfo info = new PutAwayLocInfo(
loc.getActualPosition(), // 实际位置
loc.isHeightLimited() // 是否限高
);
locInfoList.add(info);
}
return locInfoList;
}
// 实际位置的getter方法(枚举字段私有,通过getter访问)
public String getActualPosition() {
return actualPosition;
}
// 是否限高的getter方法
public boolean isHeightLimited() {
return heightLimited;
}
public static PutAwayLocEnum getByActualPosition(String actualPosition) {
for (PutAwayLocEnum position : PutAwayLocEnum.values()) {
if (position.getActualPosition().equals(actualPosition)) {
return position;
}
}
return null;
}
public static PutAwayLocEnum getByEnumName(String enumName) {
for (PutAwayLocEnum position : PutAwayLocEnum.values()) {
if (position.name().equals(enumName)) {
return position;
}
}
return null;
}
}
\ No newline at end of file
package com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.enums;
import java.util.ArrayList;
import java.util.List;
/**
* 出库位置枚举类(PutOutLocEnum)
* 仅包含出库位置标识、实际位置(默认与标识一致)核心属性
*/
public enum PutOutLocEnum {
outPos1("outPos1"),
outPos2("outPos2"),
outPos3("outPos3"),
outPos4("outPos4"),
outPos5("outPos5"),
outPos6("outPos6"),
outPos7("outPos7");
// 仅保留:实际位置(默认和枚举名一致,可自定义)
private final String actualPosition;
/**
* 枚举构造方法(仅初始化实际位置)
* @param actualPosition 实际位置
*/
PutOutLocEnum(String actualPosition) {
this.actualPosition = actualPosition;
}
// 获取实际位置
public String getActualPosition() {
return actualPosition;
}
/**
* 根据实际位置返回对应的枚举值(核心查询方法保留)
* @param actualPosition 实际位置(如outPos2)
* @return 匹配的枚举实例
* @throws IllegalArgumentException 入参为空/无匹配项时抛异常
*/
public static PutOutLocEnum getByActualPosition(String actualPosition) {
for (PutOutLocEnum loc : PutOutLocEnum.values()) {
if (actualPosition.equals(loc.getActualPosition())) {
return loc;
}
}
return null;
}
/**
* 获取所有出库位置的实际位置列表(移除限高,仅返回位置)
* @return 所有实际位置字符串列表
*/
public static List<String> getAllActualPositions() {
List<String> locList = new ArrayList<>();
for (PutOutLocEnum loc : PutOutLocEnum.values()) {
locList.add(loc.getActualPosition());
}
return locList;
}
public static List<PutOutLocEnum> getAllPutOutLoc() {
List<PutOutLocEnum> locList = new ArrayList<>();
for (PutOutLocEnum loc : PutOutLocEnum.values()) {
locList.add(loc);
}
return locList;
}
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.util;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.bean.PutOutLocInfo;
import com.neotel.smfcore.custom.aiqingzhiyin1643.finishedGoodsWarehouse.enums.PutOutLocEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class PutOutLocInfoCache {
@Autowired
private DataCache dataCache;
@PostConstruct
private void init() {
Map<String, PutOutLocInfo> cacheMap = dataCache.getCache(Constants.Cache_PutOutLoc_Info);
if (cacheMap == null) {
cacheMap = new HashMap<>();
}
List<PutOutLocEnum> putOutLocEnumList = PutOutLocEnum.getAllPutOutLoc();
for (PutOutLocEnum put : putOutLocEnumList) {
if (cacheMap.get(put.name()) == null) {
cacheMap.put(put.name(), new PutOutLocInfo(put.name(), put.getActualPosition(), ""));
}
}
dataCache.updateCache(Constants.Cache_PutOutLoc_Info, cacheMap);
}
public Collection<PutOutLocInfo> getAllPutOutLocInfo() {
Map<String, PutOutLocInfo> cacheMap = dataCache.getCache(Constants.Cache_PutOutLoc_Info);
if (cacheMap == null){
cacheMap = new HashMap<>();
}
return cacheMap.values();
}
public String bindCurrentBox(String box) {
Map<String, PutOutLocInfo> cacheMap = dataCache.getCache(Constants.Cache_PutOutLoc_Info);
if (cacheMap == null) {
cacheMap = new HashMap<>();
}
boolean bindBox = false;
String result = "";
for (String name : cacheMap.keySet()) {
PutOutLocInfo putOutLocInfo = cacheMap.get(name);
if (StringUtils.isEmpty(putOutLocInfo.getCurrentBindBox())) {
putOutLocInfo.setCurrentBindBox(box);
result = putOutLocInfo.getName();
bindBox = true;
break;
} else {
if (box.equals(putOutLocInfo.getCurrentBindBox())){
result = putOutLocInfo.getName();
break;
}
}
}
if (bindBox) {
dataCache.updateCache(Constants.Cache_PutOutLoc_Info, cacheMap);
}
return result;
}
public void removeCurrentBindBoxInfo(String actualPosition) {
Map<String, PutOutLocInfo> cacheMap = dataCache.getCache(Constants.Cache_PutOutLoc_Info);
if (cacheMap == null) {
cacheMap = new HashMap<>();
}
PutOutLocEnum putOutLocEnum = PutOutLocEnum.getByActualPosition(actualPosition);
if (putOutLocEnum != null){
PutOutLocInfo putOutLocInfo = cacheMap.get(putOutLocEnum.name());
if (putOutLocInfo == null){
putOutLocInfo = new PutOutLocInfo(putOutLocEnum.name(),putOutLocEnum.getActualPosition(),"");
}
putOutLocInfo.setCurrentBindBox("");
cacheMap.put(putOutLocEnum.name(),putOutLocInfo);
}
dataCache.updateCache(Constants.Cache_PutOutLoc_Info,cacheMap);
}
public PutOutLocInfo getPutOutLocInfoByActualPosition(String actualPosition) {
Map<String, PutOutLocInfo> cacheMap = dataCache.getCache(Constants.Cache_PutOutLoc_Info);
if (cacheMap == null) {
cacheMap = new HashMap<>();
}
PutOutLocEnum putOutLocEnum = PutOutLocEnum.getByActualPosition(actualPosition);
if (putOutLocEnum != null){
PutOutLocInfo putOutLocInfo = cacheMap.get(putOutLocEnum.name());
if (putOutLocInfo == null){
putOutLocInfo = new PutOutLocInfo(putOutLocEnum.name(),putOutLocEnum.getActualPosition(),"");
}
return putOutLocInfo;
}
return null;
}
}
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!