Commit 6334ad28 hc

fix:编码的形式添加入库回滚机制添加以及代码优化

1 个父辈 2cac58d7
package com.neotel.smfcore.common.utils;
import java.io.*;
/**
* 深拷贝
*/
public class DeepCopyUtil {
public static <T extends Serializable> T deepCopy(T object) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(object);
oos.flush();
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (T) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException("深拷贝失败!", e);
}
}
}
...@@ -24,6 +24,7 @@ import com.neotel.smfcore.custom.luxsan_sp.api.bean.result.SpareInHourseDetail; ...@@ -24,6 +24,7 @@ import com.neotel.smfcore.custom.luxsan_sp.api.bean.result.SpareInHourseDetail;
import com.neotel.smfcore.custom.luxsan_sp.bean.*; import com.neotel.smfcore.custom.luxsan_sp.bean.*;
import com.neotel.smfcore.custom.luxsan_sp.service.manager.IReturnNoManager; import com.neotel.smfcore.custom.luxsan_sp.service.manager.IReturnNoManager;
import com.neotel.smfcore.custom.luxsan_sp.service.manager.ISpareNoManager; import com.neotel.smfcore.custom.luxsan_sp.service.manager.ISpareNoManager;
import com.neotel.smfcore.custom.luxsan_sp.service.manager.SpBoxPutInManager;
import com.neotel.smfcore.custom.luxsan_sp.util.*; import com.neotel.smfcore.custom.luxsan_sp.util.*;
import com.neotel.smfcore.security.annotation.AnonymousAccess; import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
...@@ -46,6 +47,8 @@ public class SpBoxPutInController { ...@@ -46,6 +47,8 @@ public class SpBoxPutInController {
private static final Logger log = LoggerFactory.getLogger(SpBoxPutInController.class); private static final Logger log = LoggerFactory.getLogger(SpBoxPutInController.class);
@Autowired @Autowired
private CodeResolve codeResolve; private CodeResolve codeResolve;
@Autowired
private SpBoxPutInManager spBoxPutInManager;
@Autowired @Autowired
private IStoragePosManager storagePosManager; private IStoragePosManager storagePosManager;
...@@ -112,198 +115,8 @@ public class SpBoxPutInController { ...@@ -112,198 +115,8 @@ public class SpBoxPutInController {
@ApiOperation("物料放入料格") @ApiOperation("物料放入料格")
@RequestMapping("/reelToBox") @RequestMapping("/reelToBox")
@AnonymousAccess @AnonymousAccess
public synchronized ResultBean reelToBox(@RequestBody Map<String, String> paramMap) { public ResultBean reelToBox(@RequestBody Map<String, String> paramMap) throws Exception {
String boxStr = paramMap.get("boxStr").trim(); return ResultBean.newOkResult(spBoxPutInManager.reelToBox(paramMap));
String rellCodeStr = paramMap.get("codeStr").trim();
String gekouCodeStr = paramMap.get("binCodeStr").trim();
log.info("reelToBox : boxStr=" + boxStr + ",codeStr=" + rellCodeStr + ",binCodeStr=" + gekouCodeStr);
// boxStr = "C0700377A";
// codeStr = "1950090020044V&&2";
// binCodeStr = "C0700377-01";
//解析料箱信息
Barcode boxBarcode = codeResolve.resolveOneValideBarcode("=2x2=" + boxStr);
if (boxBarcode == null) {
return ResultBean.newErrorResult(-1, "", boxStr + "不是有效的条码");
}
//解析料格信息
Barcode gekouBarcode = codeResolve.resolveOneValideBarcode("=2x2=" + gekouCodeStr);
if (gekouBarcode == null) {
return ResultBean.newErrorResult(-1, "", gekouCodeStr + "不是有效的条码");
}
//2.解析条码信息
CodeBarcode codeBarcode = CodeUtil.getCodeBarcode(rellCodeStr);
if (codeBarcode == null) {
return ResultBean.newErrorResult(-1, "", rellCodeStr + "不是有效的条码");
}
//1.判断料格信息与料箱信息是否匹配
if (!gekouBarcode.getBarcode().startsWith(boxBarcode.getBarcode())) {
return ResultBean.newErrorResult(-1, "", gekouCodeStr + "不是当前料箱:" + boxStr + "的格口");
}
int binCodeNum = Integer.parseInt(gekouCodeStr.split("-")[1]);
//判断格口数量是否超出
int count = SpBoxUtil.GetBoxSubCount(boxBarcode.getBarcode());
if (binCodeNum > count) {
return ResultBean.newErrorResult(-1, "", boxBarcode.getBarcode() + "最多格口数" + count + ",请扫描正确的格口码");
}
//此格口为空
if (ObjectUtil.isEmpty(gekouBarcode.getPartNumber()) || gekouBarcode.getPartNumber().equals(boxBarcode.getPartNumber())) {
// 判断物料是否在其他格口
String currP= barcodeManager.getPNCurrGeKou( codeBarcode.getPartNumber());
if (ObjectUtil.isNotEmpty(currP)&&(!currP.equals(gekouCodeStr))) {
return ResultBean.newErrorResult(-1, "", codeBarcode.getPartNumber() + "已在"+currP+"中");
}
//是新格口物料
gekouBarcode.setPartNumber(codeBarcode.getPartNumber());
gekouBarcode.setAmount(0);
gekouBarcode.setOut(false);
} else if (gekouBarcode.getPartNumber().equals(codeBarcode.getPartNumber())) {
//pn已在此格口
} else {
//不匹配,直接返回
return ResultBean.newErrorResult(-1, "", rellCodeStr + "的料号与隔口:" + gekouCodeStr + "的料号[" + gekouBarcode.getPartNumber() + "]不匹配");
}
//判断有没有正在执行入库单
SpareNo spareNo = spareNoCache.getExecutIngSpareNo();
ReturnInventoryNo returnInventoryNo = returnNoCache.getExecutingOrderNo();
BaseNo baseNo = null;
boolean isOrderPutIn = false;
if (ObjectUtil.isAllEmpty(spareNo, returnInventoryNo)) {
// return ResultBean.newErrorResult(-1,"","没有找到正在执行的入库单或者退库单");
} else {
baseNo = ObjectUtil.isEmpty(spareNo) ? returnInventoryNo : spareNo;
//判断此料箱有没有待执行的出入库任务
List<String> needInPn = new ArrayList<>();
for (Barcode barcode :
boxBarcode.getSubCodeList()) {
String inNum = barcode.getExtraData("needInNum");
if (ObjectUtil.isEmpty(inNum) || inNum.equals("0")) {
continue;
} else {
needInPn.add(barcode.getPartNumber());
isOrderPutIn = true;
}
}
if (needInPn.size() > 0 && (!needInPn.contains(codeBarcode.getPartNumber()))) {
return ResultBean.newErrorResult(-1, "", "有未完成的入库单任务,请先入入库单物料");
}
}
boolean finish = true;
//判断当前入库的是否和入库单一样
if (isOrderPutIn) {
List<SpareNoDetail> detailList = baseNo.getDetailList();
SpareNoDetail spareNoDetail = null;
for (SpareNoDetail detail : detailList) {
//如果相同的话,判断数量是否大于需求数量
if (detail.getPartno().equals(codeBarcode.getPartNumber())) {
if (detail.getAlrInQty() + codeBarcode.getQty() <= detail.getInQty()) {
spareNoDetail = detail;
break;
}
}
}
if (spareNoDetail == null) {
return ResultBean.newErrorResult(-1, "", codeBarcode.getPartNumber() + "没有入退库需求,请检查是否存在或者不符合入退库数量");
}
//数量加
spareNoDetail.setAlrInQty(spareNoDetail.getAlrInQty() + codeBarcode.getQty());
baseNo.updateDetailList(spareNoDetail);
log.info("开始判断是否完成入库单");
for (SpareNoDetail noDetail : baseNo.getDetailList()) {
if (noDetail.getInQty() > noDetail.getAlrInQty()) {
log.info("入库未完成");
finish = false;
break;
}
log.info("入料noDetail.getInQty()" + noDetail.getInQty() + "noDetail.getAlrInQty()" + noDetail.getAlrInQty());
}
}
//4.开始放入料箱
gekouBarcode.setPartNumber(codeBarcode.getPartNumber());
gekouBarcode.setAmount(gekouBarcode.getAmount() + codeBarcode.getQty());
boxBarcode.updateSubCodes(gekouBarcode);
boxBarcode.setStatus(BARCODE_STATUS.OUT_NORMAL);
//5.寻找空库位
StoragePos pos = SpBoxUtil.locOnePos(boxBarcode);
if (pos == null){
return ResultBean.newErrorResult(-1,"",boxStr+"未找到可用的库位");
}
log.info("reelToBox 入库成功 : boxStr=" + boxStr + ",codeStr=" + rellCodeStr + ",binCodeStr=" + gekouCodeStr + ",数量:" + codeBarcode.getQty()+",当前数量:"+gekouBarcode.getAmount());
//6.生成入库任务
DataLog dataLog = new DataLog();
dataLog.setBarcode(rellCodeStr);
dataLog.setPartNumber(codeBarcode.getPartNumber());
dataLog.setOperator(SecurityUtils.getLoginUsername());
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setPosName(gekouBarcode.getBarcode());
dataLog.setNum(codeBarcode.getQty());
dataLog.setType(OP.PUT_IN);
pos.setBarcode(boxBarcode);
pos.setUsed(true);
if (finish && isOrderPutIn) {
// 调用入库接口
if (baseNo.getClass().equals(SpareNo.class)) {
dataLog.setSourceId(baseNo.getId());
dataLog.setSourceName(((SpareNo) baseNo).getSpareNo());
List<SpareInHourseDetail> details = new ArrayList<>();
for (SpareNoDetail detail : baseNo.getDetailList()) {
SpareInHourseDetail spareInHourseDetail = new SpareInHourseDetail();
spareInHourseDetail.setInQty(detail.getInQty());
spareInHourseDetail.setPartno(detail.getPartno());
String location = boxStr;
// String location = SpareNostatus.LOCATION_CODE.get(baseNo.getWhCode());
spareInHourseDetail.setLocationCode(location);
// spareInHourseDetail.setLocationCode(binBarcode.getBarcode());
details.add(spareInHourseDetail);
}
LuxsanSpApi.spareInHourse(new SpareInHourseRequest(baseNo.getDeptId(), baseNo.getNo(), baseNo.getWhCode(), details));
}
}
if (isOrderPutIn) {
if (baseNo.getClass().equals(SpareNo.class)) {
spareNoCache.addToMap(spareNo);
spareNoManager.save(spareNo);
} else {
returnNoCache.addToMap(returnInventoryNo);
returnNoManager.save(returnInventoryNo);
}
}
storagePosManager.save(pos);
barcodeManager.save(gekouBarcode);
barcodeManager.save(boxBarcode);
taskService.updateFinishedTask(dataLog);
Map<String,String> res=new HashMap<>();
res.put("PN",codeBarcode.getPartNumber());
res.put("InPutNum",codeBarcode.getQty()+"");
res.put("CurrNum",gekouBarcode.getAmount()+"");
res.put("Code",gekouBarcode.getBarcode());
return ResultBean.newOkResult("",rellCodeStr+"入库成功",res);
} }
// //以料格为维度,一个料格 // //以料格为维度,一个料格
......
package com.neotel.smfcore.custom.luxsan_sp.service.manager;
import java.util.Map;
public interface SpBoxPutInManager {
Map<String,String> reelToBox(Map<String, String> paramMap) throws Exception;
}
package com.neotel.smfcore.custom.luxsan_sp.service.manager.impl;
import cn.hutool.core.util.ObjectUtil;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.DeepCopyUtil;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.core.barcode.enums.BARCODE_STATUS;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
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.enums.OP_STATUS;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
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.luxsan_sp.api.LuxsanSpApi;
import com.neotel.smfcore.custom.luxsan_sp.api.bean.request.SpareInHourseRequest;
import com.neotel.smfcore.custom.luxsan_sp.api.bean.result.SpareInHourseDetail;
import com.neotel.smfcore.custom.luxsan_sp.bean.*;
import com.neotel.smfcore.custom.luxsan_sp.service.manager.IReturnNoManager;
import com.neotel.smfcore.custom.luxsan_sp.service.manager.ISpareNoManager;
import com.neotel.smfcore.custom.luxsan_sp.service.manager.SpBoxPutInManager;
import com.neotel.smfcore.custom.luxsan_sp.util.CodeUtil;
import com.neotel.smfcore.custom.luxsan_sp.util.ReturnNoCache;
import com.neotel.smfcore.custom.luxsan_sp.util.SpBoxUtil;
import com.neotel.smfcore.custom.luxsan_sp.util.SpareNoCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
@Slf4j
@Service
public class SpBoxPutInManagerImpl implements SpBoxPutInManager {
@Autowired
private CodeResolve codeResolve;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private SpareNoCache spareNoCache;
@Autowired
private ReturnNoCache returnNoCache;
@Autowired
private ISpareNoManager spareNoManager;
@Autowired
private IReturnNoManager returnNoManager;
@Autowired
private TaskService taskService;
@Override
@Transactional(rollbackFor = Exception.class)
public synchronized Map<String, String> reelToBox(Map<String, String> paramMap) throws Exception {
try {
String boxStr = paramMap.get("boxStr").trim();
String rellCodeStr = paramMap.get("codeStr").trim();
String gekouCodeStr = paramMap.get("binCodeStr").trim();
log.info("reelToBox : boxStr=" + boxStr + ",codeStr=" + rellCodeStr + ",binCodeStr=" + gekouCodeStr);
// boxStr = "C0700377A";
// codeStr = "1950090020044V&&2";
// binCodeStr = "C0700377-01";
//解析料箱信息
Barcode boxBarcode = codeResolve.resolveOneValideBarcode("=2x2=" + boxStr);
if (boxBarcode == null) {
throw new Exception("不是有效的料箱条码");
}
addBackupObj(boxBarcode);
//解析料格信息
Barcode gekouBarcode = codeResolve.resolveOneValideBarcode("=2x2=" + gekouCodeStr);
if (gekouBarcode == null) {
throw new Exception("不是有效的料格条码");
}
addBackupObj(gekouBarcode);
//2.解析条码信息
CodeBarcode codeBarcode = CodeUtil.getCodeBarcode(rellCodeStr);
if (codeBarcode == null) {
throw new Exception("不是有效的物料条码");
}
//1.判断料格信息与料箱信息是否匹配
if (!gekouBarcode.getBarcode().startsWith(boxBarcode.getBarcode())) {
throw new Exception(gekouCodeStr + "不是当前料箱:" + boxStr + "的格口");
}
int binCodeNum = Integer.parseInt(gekouCodeStr.split("-")[1]);
//判断格口数量是否超出
int count = SpBoxUtil.GetBoxSubCount(boxBarcode.getBarcode());
if (binCodeNum > count) {
// throw new Exception(boxBarcode.getBarcode() + "最多格口数" + count + ",请扫描正确的格口码");
}
//此格口为空
if (ObjectUtil.isEmpty(gekouBarcode.getPartNumber()) || gekouBarcode.getPartNumber().equals(boxBarcode.getPartNumber())) {
// 判断物料是否在其他格口
String currP= barcodeManager.getPNCurrGeKou( codeBarcode.getPartNumber());
if (ObjectUtil.isNotEmpty(currP)&&(!currP.equals(gekouCodeStr))) {
throw new Exception(codeBarcode.getPartNumber() + "已在"+currP+"中");
}
//是新格口物料
gekouBarcode.setPartNumber(codeBarcode.getPartNumber());
gekouBarcode.setAmount(0);
gekouBarcode.setOut(false);
} else if (gekouBarcode.getPartNumber().equals(codeBarcode.getPartNumber())) {
//pn已在此格口
} else {
//不匹配,直接返回
throw new Exception(rellCodeStr + "的料号与隔口:" + gekouCodeStr + "的料号[" + gekouBarcode.getPartNumber() + "]不匹配");
}
//判断有没有正在执行入库单
SpareNo spareNo = spareNoCache.getExecutIngSpareNo();
ReturnInventoryNo returnInventoryNo = returnNoCache.getExecutingOrderNo();
BaseNo baseNo = null;
boolean isOrderPutIn = false;
if (ObjectUtil.isAllEmpty(spareNo, returnInventoryNo)) {
// return ResultBean.newErrorResult(-1,"","没有找到正在执行的入库单或者退库单");
} else {
baseNo = ObjectUtil.isEmpty(spareNo) ? returnInventoryNo : spareNo;
addBackupObj(baseNo);
//判断此料箱有没有待执行的出入库任务
List<String> needInPn = new ArrayList<>();
for (Barcode barcode :
boxBarcode.getSubCodeList()) {
String inNum = barcode.getExtraData("needInNum");
if (ObjectUtil.isEmpty(inNum) || inNum.equals("0")) {
continue;
} else {
needInPn.add(barcode.getPartNumber());
isOrderPutIn = true;
}
}
if (needInPn.size() > 0 && (!needInPn.contains(codeBarcode.getPartNumber()))) {
throw new Exception("有未完成的入库单任务,请先入入库单物料");
}
}
boolean finish = true;
//判断当前入库的是否和入库单一样
if (isOrderPutIn) {
List<SpareNoDetail> detailList = baseNo.getDetailList();
SpareNoDetail spareNoDetail = null;
for (SpareNoDetail detail : detailList) {
//如果相同的话,判断数量是否大于需求数量
if (detail.getPartno().equals(codeBarcode.getPartNumber())) {
if (detail.getAlrInQty() + codeBarcode.getQty() <= detail.getInQty()) {
spareNoDetail = detail;
break;
}
}
}
if (spareNoDetail == null) {
throw new Exception(codeBarcode.getPartNumber() + "没有入退库需求,请检查是否存在或者不符合入退库数量");
}
//数量加
spareNoDetail.setAlrInQty(spareNoDetail.getAlrInQty() + codeBarcode.getQty());
baseNo.updateDetailList(spareNoDetail);
log.info("开始判断是否完成入库单");
for (SpareNoDetail noDetail : baseNo.getDetailList()) {
if (noDetail.getInQty() > noDetail.getAlrInQty()) {
log.info("入库未完成");
finish = false;
break;
}
log.info("入料noDetail.getInQty()" + noDetail.getInQty() + "noDetail.getAlrInQty()" + noDetail.getAlrInQty());
}
}
// 寻找空库位
StoragePos pos = SpBoxUtil.locOnePos(boxBarcode);
addBackupObj(pos);
// 将给pos赋值延迟到深拷贝库位对象之后
// 开始放入料箱
gekouBarcode.setPartNumber(codeBarcode.getPartNumber());
gekouBarcode.setAmount(gekouBarcode.getAmount() + codeBarcode.getQty());
boxBarcode.updateSubCodes(gekouBarcode);
boxBarcode.setStatus(BARCODE_STATUS.OUT_NORMAL);
if (pos == null){
throw new Exception(boxStr+"未找到可用的库位");
}
log.info("reelToBox 入库成功 : boxStr=" + boxStr + ",codeStr=" + rellCodeStr + ",binCodeStr=" + gekouCodeStr + ",数量:" + codeBarcode.getQty()+",当前数量:"+gekouBarcode.getAmount());
//6.生成入库任务
DataLog dataLog = new DataLog();
dataLog.setBarcode(rellCodeStr);
dataLog.setPartNumber(codeBarcode.getPartNumber());
dataLog.setOperator(SecurityUtils.getLoginUsername());
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setPosName(gekouBarcode.getBarcode());
dataLog.setNum(codeBarcode.getQty());
dataLog.setType(OP.PUT_IN);
pos.setBarcode(boxBarcode);
pos.setUsed(true);
storagePosManager.save(pos);
barcodeManager.save(gekouBarcode);
barcodeManager.save(boxBarcode);
Map<String,String> res=new HashMap<>();
res.put("PN",codeBarcode.getPartNumber());
res.put("InPutNum",codeBarcode.getQty()+"");
res.put("CurrNum",gekouBarcode.getAmount()+"");
res.put("Code",gekouBarcode.getBarcode());
taskService.updateFinishedTask(dataLog);
if (isOrderPutIn) {
if (baseNo.getClass().equals(SpareNo.class)) {
spareNoCache.addToMap(spareNo);
spareNoManager.save(spareNo);
} else {
returnNoCache.addToMap(returnInventoryNo);
returnNoManager.save(returnInventoryNo);
}
}
int i = 1/0;
// 最后刷新不能回滚的
if (finish && isOrderPutIn) {
// 调用入库接口
if (baseNo.getClass().equals(SpareNo.class)) {
dataLog.setSourceId(baseNo.getId());
dataLog.setSourceName(((SpareNo) baseNo).getSpareNo());
List<SpareInHourseDetail> details = new ArrayList<>();
for (SpareNoDetail detail : baseNo.getDetailList()) {
SpareInHourseDetail spareInHourseDetail = new SpareInHourseDetail();
spareInHourseDetail.setInQty(detail.getInQty());
spareInHourseDetail.setPartno(detail.getPartno());
String location = boxStr;
// String location = SpareNostatus.LOCATION_CODE.get(baseNo.getWhCode());
spareInHourseDetail.setLocationCode(location);
// spareInHourseDetail.setLocationCode(binBarcode.getBarcode());
details.add(spareInHourseDetail);
}
LuxsanSpApi.spareInHourse(new SpareInHourseRequest(baseNo.getDeptId(), baseNo.getNo(), baseNo.getWhCode(), details));
}
}
return res;
}catch (Exception e) {
// 回滚
rollBack();
throw new Exception(e.getMessage());
}
}
// 入料接口使用了对象锁,可以
private List<Barcode> backupBarcodes = new ArrayList<>();
private BaseNo backupSpareNo;
private StoragePos backupPos;
public void addBackupObj(Object o) {
if (o instanceof Barcode) {
backupBarcodes.add(DeepCopyUtil.deepCopy((Barcode) o));
}else if (o instanceof BaseNo) {
backupSpareNo = DeepCopyUtil.deepCopy((SpareNo) o);
}else if (o instanceof StoragePos) {
backupPos = DeepCopyUtil.deepCopy((StoragePos) o);
}
}
public void rollBack() throws Exception {
try {
log.info("开始回滚");
if (ObjectUtil.isNotEmpty(backupBarcodes)) {
for (Barcode backupBarcode : backupBarcodes) {
barcodeManager.save(backupBarcode);
log.info(String.format("条码[%s]回滚为"+backupBarcode, backupBarcode.getBarcode()));
}
}
if (ObjectUtil.isNotNull(backupSpareNo)) {
if (backupSpareNo.getClass().equals(SpareNo.class)) {
spareNoCache.addToMap((SpareNo) backupSpareNo);
spareNoManager.save((SpareNo) backupSpareNo);
log.info(String.format("入库单[%s]回滚为"+backupSpareNo, backupSpareNo.getNo()));
} else {
returnNoCache.addToMap((ReturnInventoryNo) backupSpareNo);
returnNoManager.save((ReturnInventoryNo) backupSpareNo);
log.info(String.format("退库单[%s]回滚为"+backupSpareNo, backupSpareNo.getNo()));
}
}
if (ObjectUtil.isNotNull(backupPos)) {
storagePosManager.save(backupPos);
log.info(String.format("库位[%s]回滚为"+backupPos, backupPos.getPosName()));
}
}catch (Exception e) {
backupBarcodes = new ArrayList<>();
backupPos = null;
backupSpareNo = null;
throw new Exception("回滚失败,失败原因:"+e.getMessage());
}
}
}
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!