Commit 20f70078 zshaohui

1131 外仓功能提交

1 个父辈 6e7fda45
......@@ -47,6 +47,7 @@ public enum OP_STATUS {
IN_ON_LINE,
IN_ON_AGV,
OUT_ON_LINE,
OUT_ON_AGV
OUT_ON_AGV,
ERROR
;
}
......@@ -302,9 +302,9 @@ public class DataLog extends BasePo implements Serializable {
*/
public boolean needRemoveFromCache(){
if(isFinished() || isCancel()){
if(System.currentTimeMillis() - super.getUpdateDate().getTime() > 5 * 60 * 1000){
//if(System.currentTimeMillis() - super.getUpdateDate().getTime() > 5 * 60 * 1000){
return true;
}
//}
}
return false;
}
......
package com.neotel.smfcore.custom.lizhen.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author sunke
* @date 2022/9/22 4:32 PM
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Station {
/**
......@@ -19,10 +23,26 @@ public class Station {
*/
private String currentRfid = "";
/**
* 物料当前扫描数量
*/
private int reelCurrentNum = 0;
/**
* 物料总数量
*/
private int reelNum;
/**
* 料箱当前数量
*/
private int boxCurrentNum = 0;
/**
* 数量
* 料箱数量
*/
private int num;
private int boxNum;
/**
* 宽
......@@ -38,4 +58,7 @@ public class Station {
* GR标签
*/
private String grLabel;
private String lastScanBoxCode = "";
}
package com.neotel.smfcore.custom.lizhen.rest;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.ReelLockPosUtil;
import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
......@@ -10,6 +11,7 @@ import com.neotel.smfcore.core.storage.enums.DeviceType;
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.dao.IDataLogDao;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.bean.Station;
......@@ -48,6 +50,9 @@ public class AgvBoxDeviceClientController {
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private IDataLogDao dataLogDao;
/**
* 料箱锁定的目的地
*/
......@@ -62,7 +67,7 @@ public class AgvBoxDeviceClientController {
@ResponseBody
@AnonymousAccess
public ResultBean stationInfo(HttpServletRequest request) {
for (int i = 1; i < 5; i++) {
for (int i = 1; i <= 5; i++) {
String stationName = "s" + i;
String rfid = request.getParameter(stationName);
StationCacheUtil.updateCurrentRfid(stationName, rfid);
......@@ -92,10 +97,10 @@ public class AgvBoxDeviceClientController {
* 根据料箱RFID获取工位信息
*/
private String getStationByRfid(String rfid) {
String prefixRfid = rfid + "-";
//String prefixRfid = rfid + "-";
for (Station station : StationCacheUtil.getAllStations()) {
String stationRfid = station.getCurrentRfid();
if (stationRfid.startsWith(prefixRfid)) {
if (stationRfid.startsWith(rfid)) {
return station.getName();
}
}
......@@ -149,7 +154,7 @@ public class AgvBoxDeviceClientController {
DataLog opTask = null;
Collection<DataLog> tasks = taskService.getAllTasks();
for (DataLog task : tasks) {
if (!task.isFinished()) {
if (!task.isFinished() && !task.isCancel()) {
Storage storage = dataCache.getStorageById(task.getStorageId());
if (storage.isStorage(DeviceType.AGV_BOX)) {
if (isSameBarcodeTask(rfid, task)) {
......@@ -238,7 +243,9 @@ public class AgvBoxDeviceClientController {
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog task : allTasks) {
if (rfid.startsWith(task.getBarcode())) {
opTask = task;
if (!task.isCancel()) {
opTask = task;
}
break;
}
}
......@@ -277,6 +284,8 @@ public class AgvBoxDeviceClientController {
if (OP_STATUS.OUT_ON_AGV.name().equals(statusStr)) {
//从库位中取出,需要移到完成队列中,并且清理库存
outFromPos(opTask);
//清理锁定库位
ReelLockPosUtil.removeReelLockPosInfo(rfid);
}
taskService.updateFinishedTask(opTask);
......
......@@ -4,10 +4,13 @@ import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.storage.service.manager.IStorageManager;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
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;
......@@ -16,7 +19,8 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class TaskRestController{
@Slf4j
public class TaskRestController {
@Autowired
private IDataLogManager dataLogManager;
......@@ -25,12 +29,15 @@ public class TaskRestController{
private DataCache dataCache;
@Autowired
private IStorageManager storageManager;
private TaskService taskService;
@Autowired
private IStoragePosManager storagePosManager;
@RequestMapping("/putIn")
@AnonymousAccess
public ResultBean putIn(@RequestBody Map<String,String> paramMap){
public ResultBean putIn(@RequestBody Map<String, String> paramMap) {
String barcode = paramMap.get("barcode");
String posName = paramMap.get("posName");
String cid = paramMap.get("cid");
......@@ -38,12 +45,36 @@ public class TaskRestController{
DataLog dataLog = new DataLog();
dataLog.setStorageId(storage.getId());
dataLog.setPosName(posName);
dataLog.setPosId(storagePosManager.getByPosName(posName).getId());
dataLog.setCid(cid);
dataLog.setBarcode(barcode);
dataLog.setPartNumber(barcode);
dataLog.setType(1);
dataLog.setStatus(OP_STATUS.WAIT.name());
dataLogManager.save(dataLog);
taskService.addTaskToExecute(dataLog);
return ResultBean.newOkResult("");
}
@RequestMapping("/outIn")
@AnonymousAccess
public ResultBean outIn(@RequestBody Map<String, String> paramMap) {
String barcode = paramMap.get("barcode");
String posName = paramMap.get("posName");
String cid = paramMap.get("cid");
String name = paramMap.get("name");
Storage storage = dataCache.getStorage(cid);
DataLog dataLog = new DataLog();
dataLog.setStorageId(storage.getId());
dataLog.setPosName(posName);
dataLog.setPosId(storagePosManager.getByPosName(posName).getId());
dataLog.setCid(cid);
dataLog.setBarcode(barcode);
dataLog.setPartNumber(barcode);
dataLog.setType(2);
dataLog.setStatus(OP_STATUS.WAIT.name());
dataLog.setLoc(name);
log.info("工位信息--" + name);
taskService.addTaskToExecute(dataLog);
return ResultBean.newOkResult("");
}
......
package com.neotel.smfcore.custom.lizhen.rest;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.bean.ReelLockPosInfo;
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.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.bean.CodeBean;
import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.manager.IComponentManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.service.po.Component;
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.device.util.DataCache;
import com.neotel.smfcore.core.message.util.DeviceMessageUtil;
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.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.bean.Station;
import com.neotel.smfcore.custom.lizhen.util.StationCacheUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 外仓操作
*/
@Slf4j
@RestController
public class WarehouseController {
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private IComponentManager componentManager;
@Autowired
private CodeResolve codeResolve;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private TaskService taskService;
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private DataCache dataCache;
@ApiOperation("选择物料,呼叫空箱")
@RequestMapping("/chooseReel")
@AnonymousAccess
public ResultBean chooseReel(@RequestBody Map<String, String> paramMap) {
String size = paramMap.get("size"); //尺寸 "7X8"
String num = paramMap.get("num"); //数量
String name = paramMap.get("name"); //工位名称
String currentRfid = paramMap.get("currentRfid"); //当前料箱的RFID
String grLabel = paramMap.get("grLabel"); //GR标签
int platsize = getPlatsizeOrHeight(size, 0);
int height = getPlatsizeOrHeight(size, 1);
Station station = new Station();
station.setPlatsize(platsize);
station.setHeight(height);
station.setName(name);
station.setGrLabel(grLabel);
station.setCurrentRfid(currentRfid);
station.setReelNum(Integer.valueOf(num));
StationCacheUtil.updateStation(station);
return ResultBean.newOkResult("");
}
@ApiOperation("获取工位详情")
@RequestMapping("/getStation")
@AnonymousAccess
public ResultBean getStation(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name");
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1,"","{}工位不存在",new String[]{name});
}
return ResultBean.newOkResult(station);
}
@ApiOperation("操作料盒内的物料信息")
@RequestMapping(value = "/operatePos")
@AnonymousAccess
//先扫条码 再扫料箱
public ResultBean operatePos(@RequestBody Map<String, String> paramMap) {
String code = paramMap.get("code"); //条码
String name = paramMap.get("name"); //工位名称
String barcodeStr = "";
if (code.startsWith("C") && code.indexOf("-") != -1) {
barcodeStr = code.substring(0, code.indexOf("-"));
} else {
barcodeStr = code;
}
Station station = StationCacheUtil.getStation(name);
String currentRfid = station.getCurrentRfid();
if (station == null) {
throw new ValidateException("smfcore.valueNotExist", "{}工位不存在", new String[]{name});
}
//先判断是否料盒
String newCodeStr = "=" + station.getPlatsize() + "x" + station.getHeight() + "=" + barcodeStr;
CodeBean codeBean = codeResolve.resolveSingleCode(newCodeStr);
if (codeBean.isValid()) {
Barcode barcode = codeBean.getBarcode();
String partNumber = barcode.getPartNumber();
//如果是箱子的话 则取下边的
if (partNumber.equals("CS") || partNumber.equals("CM") || partNumber.equals("CB") || partNumber.equals("CN")) {
if (StringUtils.isBlank(currentRfid)) {
throw new ValidateException("", "{}不存在", new String[]{currentRfid});
} else if (!currentRfid.startsWith(barcode.getBarcode())) {
throw new ValidateException("", "{}与{}不一致", new String[]{code, currentRfid});
}
String boxCode = barcode.getBarcode();
station.setLastScanBoxCode(boxCode);
StationCacheUtil.updateStation(station);
barcodeManager.save(barcode);
} else {
String lastScanBoxCode = station.getLastScanBoxCode();
//再加个rfid判断
if (Strings.isBlank(lastScanBoxCode)) {
//提示要先扫料箱
return ResultBean.newErrorResult(-1, "", "请先扫描料箱,再扫描条码");
} else {
if (StringUtils.isBlank(currentRfid)) {
throw new ValidateException("", "{}不存在", new String[]{currentRfid});
} else if (!currentRfid.startsWith(barcode.getBarcode())) {
throw new ValidateException("", "{}与{}不一致", new String[]{code, currentRfid});
}
}
StationCacheUtil.saveReelToBoxCode(station);
finishTask(barcodeManager.findByBarcode(lastScanBoxCode), 1, null, barcode, 1);
}
}
return ResultBean.newOkResult("");
}
@ApiOperation("完成装箱并入库")
@RequestMapping("/finishBoxPutIn")
@AnonymousAccess
public ResultBean finishBoxPutIn(@RequestBody Map<String, String> paramMap) {
String code = paramMap.get("barcode"); //料箱条码
String name = paramMap.get("name"); //工位名称
String cids = paramMap.get("cids"); //料仓cid
//校验是否存在
Barcode barcode = barcodeManager.findByBarcode(code);
if (barcode == null) {
throw new ValidateException("", "{}不存在", new String[]{code});
}
Station station = StationCacheUtil.getStation(name);
if (station == null) {
throw new ValidateException("", "{}工位不存在", new String[]{name});
}
//校验rfid是否一致
String currentRfid = station.getCurrentRfid();
if (StringUtils.isBlank(currentRfid)) {
throw new ValidateException("", "{}不存在", new String[]{currentRfid});
} else if (!currentRfid.startsWith(barcode.getBarcode())) {
throw new ValidateException("", "{}与{}不一致", new String[]{code, currentRfid});
}
//先找可用料仓
if (StringUtils.isBlank(cids)) {
throw new ValidateException("", "{}不存在", new String[]{cids});
}
List<Storage> storageList = Lists.newArrayList();
List<String> cidList = Lists.newArrayList();
for (String cid : cids.split(",")) {
String notIntoCids = dataCache.getSettings().getNotIntoCids();
if (notIntoCids != null) {
if (notIntoCids.contains(cid)) {
log.info("料仓[" + cid + "]已被屏蔽入库");
continue;
}
}
Storage storage = dataCache.getStorage(cid);
if (storage != null) {
storageList.add(storage);
cidList.add(cid);
}
}
if (storageList.isEmpty()) {
throw new ValidateException("", "料仓不存在", null);
}
//判断是否有出入库任务
for (DataLog dataLog : taskService.getQueueTasks()) {
// if(!dataLog.isPackageReel()){
//已经在任务当中,返回对应的信息
if (dataLog.getBarcode().equals(barcode.getBarcode())) {
if (dataLog.isPutInTask()) {
//已有入库任务
throw new ValidateException("", "物料[" + dataLog.getBarcode() + "]已有入库任务,需继续执行入库动作", null);
} else {
//已有出库任务
throw new ValidateException("", "物料[" + dataLog.getBarcode() + "]已有出库任务,需继续执行出库动作", null);
}
}
}
//开始寻找空箱
StoragePos pos = taskService.findEmptyPosForPutIn(storageList, barcode, "", "");
if (pos == null) {
throw new ValidateException("", "[" + barcode.getBarcode() + "]未找到可用的[" + barcode.getPlateSize() + "x" + barcode.getHeight() + "]仓位", null);
}
if (pos != null) {
Storage theStorage = dataCache.getStorageById(pos.getStorageId());
ReelLockPosInfo oldLockInfo = ReelLockPosUtil.getLockPosInfoByCode(barcode.getBarcode());
if (oldLockInfo != null) {
if (!oldLockInfo.getBarcode().equals(barcode.getBarcode())) {
ReelLockPosUtil.removeReelLockPosInfo(oldLockInfo.getBarcode());
log.info("清理锁定库位:库位号[" + oldLockInfo.getLockPosName() + "]上物料[" + oldLockInfo.getBarcode() + "]锁定的库位");
}
}
ReelLockPosInfo reelLocInfo = new ReelLockPosInfo();
reelLocInfo.setBarcode(barcode.getBarcode());
reelLocInfo.setCid(theStorage.getCid());
reelLocInfo.setLockPosName(pos.getPosName());
reelLocInfo.setLockPosId(pos.getId());
reelLocInfo = ReelLockPosUtil.addReelLockPosInfo(reelLocInfo, cidList);
if (reelLocInfo == null) {
throw new ValidateException("", "[" + barcode.getBarcode() + "]库位[" + reelLocInfo.getLockPosName() + "]已被锁定,暂停入库", null);
}
}
//开始入库任务
DataLog task = new DataLog(dataCache.getStorageById(pos.getStorageId()), barcode, pos);
task.setType(OP.PUT_IN);
task.setStatus(OP_STATUS.WAIT.name());
taskService.updateQueueTask(task);
//同时清空lastScanBoxCode
station.setLastScanBoxCode(null);
StationCacheUtil.updateStation(station);
return ResultBean.newOkResult("");
}
/**
* 完成出入库任务
*
* @param pidBarcode 料箱
* @param currentTask 当前任务
* @param subBarcode 箱内物料
* @param opQty 数量
* @throws ValidateException
*/
private void finishTask(Barcode pidBarcode, int opType, DataLog currentTask, Barcode subBarcode, int opQty) throws ValidateException {
//更新barcode缓存
pidBarcode.UpdateSubCode(subBarcode);
if (opType == OP.CHECKOUT && subBarcode.getAmount() <= 0) {
//数量为0直接删除
barcodeManager.delete(subBarcode);
}
barcodeManager.saveBarcode(pidBarcode);
DataLog task = null;
//先查看是否有相同类型且库位相同的任务
if (currentTask != null) {
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (queueTask.getType() == currentTask.getType()) {
if (queueTask.getPosName().equals(pidBarcode.getBarcode())) {
task = queueTask;
break;
}
}
}
}
if (task == null) {
task = new DataLog();
}
task.setStatus(OP_STATUS.FINISHED.name());
task.setPartNumber(subBarcode.getPartNumber());
task.setBarcode(subBarcode.getBarcode());
task.setNum(opQty);
task.setType(opType);
task.setCid(pidBarcode.getPartNumber());
task.setStorageName(pidBarcode.getBarcode());
task.setPosName(pidBarcode.getBarcode());
task.setOperator(SecurityUtils.getLoginUsername());
task = dataLogManager.save(task);
taskService.moveTaskToFinished(task);
}
private int getPlatsizeOrHeight(String size, int index) {
return Integer.valueOf(size.split("X")[index]);
}
}
package com.neotel.smfcore.custom.lizhen.util;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.custom.lizhen.bean.Station;
import lombok.extern.slf4j.Slf4j;
......@@ -22,6 +23,13 @@ public class StationCacheUtil {
*/
private static Map<String, Station> stationMap = new ConcurrentHashMap<>();
public static void saveReelToBoxCode(Station station) {
int reelCurrentNum = station.getReelCurrentNum();
reelCurrentNum++;
station.setReelCurrentNum(reelCurrentNum);
StationCacheUtil.updateStation(station);
}
@PostConstruct
public void init() {
log.info("开始工位缓存信息");
......@@ -31,13 +39,13 @@ public class StationCacheUtil {
if(station == null){
station = new Station();
station.setName(stationName);
stationMap.put(stationName,station);
dataCache.updateCache(stationName, station);
}
stationMap.put(stationName,station);
dataCache.updateCache(stationName, station);
}
}
private static synchronized void updateStation(Station station){
public static synchronized void updateStation(Station station){
stationMap.put(station.getName(),station);
dataCache.updateCache(station.getName(), station);
}
......@@ -59,6 +67,11 @@ public class StationCacheUtil {
station.setCurrentRfid(rfid);
updateStation(station);
}
} else {
station = new Station();
station.setName(stationName);
station.setCurrentRfid(rfid);
updateStation(station);
}
}
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!