Commit ee5cac00 LN

增加机器人料仓代码

1 个父辈 c483084b
......@@ -33,6 +33,14 @@ public enum OP_STATUS {
/**
* 已结束
*/
END
END,
/**
* 机器人正在移栽中
*/
INROBOT,
/**
* 已放到料仓门口
*/
BOXDOOR,
;
}
package com.neotel.smfcore.core.device.handler.impl;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
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.Constants;
import com.neotel.smfcore.common.utils.ReelLockPosUtil;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.api.IOpAuthApi;
import com.neotel.smfcore.core.device.bean.StatusBean;
import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.message.util.DeviceMessageUtil;
import com.neotel.smfcore.core.storage.enums.DeviceType;
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.IAlarmInfoDao;
import com.neotel.smfcore.core.system.service.po.AlarmInfo;
import com.neotel.smfcore.core.system.service.po.DataLog;
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.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
@Api(tags = "RobotBox: 机器人料仓(1049)")
@RestController
@Slf4j
public class RobotBoxHandler extends BaseDeviceHandler {
@Autowired
private IAlarmInfoDao alarmInfoDao;
public RobotBoxHandler(List<IOpAuthApi> apiList) {
super(apiList);
}
@Override
public StatusBean handleClientRequest(StatusBean statusBean, HttpServletRequest request) {
String cid = statusBean.getCid();
Storage storage = dataCache.getStorage(cid);
if (storage == null) {
log.error("料仓cid: [" + cid + "]不存在");
return null;
}
statusBean.setClientIp(request.getRemoteHost());
handleMsg(statusBean);
statusBean = saveAlarmAndHumidity(statusBean);
statusBean = handleInOutFinished(statusBean);
StatusBean humidityResult = handleHumidity(statusBean);
if (humidityResult != null) {
return humidityResult;
}
if (statusBean.getOp() == OP.PUT_IN) {
log.debug("入库:" + statusBean.toString());
statusBean = putInLine(storage, statusBean);
} else {
//没有入库任务时才处理出库
statusBean =taskService.checkOut(storage, statusBean);
}
return statusBean;
}
@ApiOperation("机器人料仓查找空的料格")
@PostMapping(value = "/service/store/robotBox/emptyPosForPutin")
@ResponseBody
@AnonymousAccess
public Map<String, Object> emptyPosForPutin(HttpServletRequest request) {
String code = request.getParameter("code");
String cids = request.getParameter("cids");
String rfid = request.getParameter("rfid");
String rfidLoc = request.getParameter("rfidLoc");
String lastPosId = request.getParameter("lastPosId");
String lineMsg = "";
log.info("流水线[" + cids + "]获取[" + rfid + "][" + code + "]的入库库位");
Map<String, Object> resultMap = Maps.newHashMap();
if (dataCache.getCache(Constants.CACHE_StopOut)) {
lineMsg = "系统更新中,暂停出入库";
DeviceMessageUtil.updateLineMsg(lineMsg, code, cids, "", "smfcore.linemsg.update", null);
resultMap.put("result", "100");
resultMap.put("msg", lineMsg);
return resultMap;
}
String okMsg = "";
String errorMsg = "";
if (Strings.isNullOrEmpty(cids)) {
resultMap.put("result", "101");
resultMap.put("msg", "未指定料仓 cids ");
} else {
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;
}
}
boolean hasOutTask = false;
//判断是否有正在执行的出库任务,有的话不能入库
Storage storage = dataCache.getStorage(cid);
if (!storage.isRobotBox()) {
Collection<DataLog> tasks = taskService.getQueueTasks();
for (DataLog task : tasks) {
if (task.isCheckOutTask() && task.getStorageId().equals(storage.getId())) {
if (task.isExecuting() || task.isBoxdoor() || task.isInRobot()) {
hasOutTask = true;
break;
}
}
}
}
if (storage != null && (!hasOutTask)) {
storageList.add(storage);
cidList.add(cid);
}
}
if (storageList.isEmpty()) {
resultMap.put("result", "99");
errorMsg = "无可用的料仓";
resultMap.put("msg", errorMsg);
} else {
try {
Barcode barcode = codeResolve.resolveOneValideBarcode(code);
for (DataLog dataLog : taskService.getQueueTasks()) {
// if(!dataLog.isPackageReel()){
//已经在任务当中,返回对应的信息
if (dataLog.getBarcode().equals(barcode.getBarcode())) {
if (dataLog.isPutInTask()) {
//已有入库任务
errorMsg = "物料[" + dataLog.getBarcode() + "]已有入库任务,需继续执行入库动作";
resultMap.put("pos", dataLog.getPosName());
resultMap.put("barcode", barcode.getBarcode());
resultMap.put("cid", dataLog.getCid());
return resultMap;
} else {
//已有出库任务
errorMsg = "物料[" + dataLog.getBarcode() + "]已有出库任务,需继续执行出库动作";
resultMap.put("result", "98");
resultMap.put("msg", errorMsg);
resultMap.put("posId", dataLog.getPosName());
resultMap.put("plateW", barcode.getPlateSize());
resultMap.put("plateH", barcode.getHeight());
resultMap.put("singleOut", dataLog.isSingleOut() + "");
//紧急料
resultMap.put("urgentReel", dataLog.isUrgentReel() + "");
//需要分盘,进入分盘料
resultMap.put("cutReel", dataLog.isCutReel() + "");
resultMap.put("rfid", "");
resultMap.put("realRfid", "");
resultMap.put("rfidLoc", "");
// resultMap.put("rfid", dataLog.getTempRfid());
// resultMap.put("realRfid",dataLog.getAppendInfo().getRfid());
// resultMap.put("rfidLoc", dataLog.getAppendInfo().getRfidLoc() + "");
resultMap.put("barcode", dataLog.getBarcode());
boolean smallReel = barcode.isSmallReel();
resultMap.put("smallReel", smallReel + "");
return resultMap;
}
// }
}
}
StoragePos pos = taskService.findEmptyPosForPutIn(storageList, barcode, rfid, lastPosId);
if (pos != null) {
Storage theStorage = dataCache.getStorageById(pos.getStorageId());
resultMap.put("result", "0");
resultMap.put("msg", "");
okMsg = "[" + rfid + "][" + barcode.getBarcode() + "]锁定库位[" + pos.getPosName() + "]优先级[" + pos.getPriority() + "] 上个库位号[" + lastPosId + "]";
ReelLockPosInfo oldLockInfo = ReelLockPosUtil.getLockPosInfoByCode(barcode.getBarcode());
if (oldLockInfo != null) {
if (!oldLockInfo.getBarcode().equals(barcode.getBarcode())) {
String result = "-1";
okMsg = rfid + "[" + rfidLoc + "][" + barcode.getBarcode() + "]锁定库位[" + pos.getPosName() + "],清理旧有锁定信息";
resultMap.put("result", result);
resultMap.put("msg", okMsg);
//已经锁定过库位,但不是同一个条码,需要把对应位置的锁定信息清理掉
ReelLockPosUtil.removeReelLockPosInfo(oldLockInfo.getBarcode());
log.info("清理锁定库位:库位号[" + oldLockInfo.getLockPosName() + "]上物料[" + oldLockInfo.getBarcode() + "]锁定的库位");
}
}
log.info(okMsg + oldLockInfo);
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) {
errorMsg = "[" + barcode.getBarcode() + "]库位[" + reelLocInfo.getLockPosName() + "]已被锁定,暂停入库";
lineMsg = errorMsg;
DeviceMessageUtil.updateLineMsg(lineMsg, code, cids, reelLocInfo.getLockPosName(), "smfcore.linemsg.posLock", new String[]{barcode.getBarcode(), reelLocInfo.getLockPosName()});
resultMap.put("result", "99");
resultMap.put("msg", errorMsg);
return resultMap;
} else {
resultMap.put("pos", pos.getPosName());
resultMap.put("barcode", barcode.getBarcode());
resultMap.put("cid", theStorage.getCid());
//TODO 创建入库任务,状态执行中
Storage storage = dataCache.getStorageById(pos.getStorageId());
taskService.addPutInTaskToExecute(storage, barcode, pos);
}
} else {
resultMap.put("result", "104");
errorMsg = "[" + barcode.getBarcode() + "]未找到可用的[" + barcode.getPlateSize() + "x" + barcode.getHeight() + "]仓位";
resultMap.put("msg", errorMsg);
}
} catch (ValidateException ve) {
errorMsg = ve.getMessage();
log.info("查找空库位失败:" + errorMsg);
resultMap.put("result", "105");
resultMap.put("msg", errorMsg);
} catch (Exception e) {
errorMsg = e.getMessage();
log.info("查找空库位失败,", e);
resultMap.put("result", "105");
resultMap.put("msg", errorMsg);
}
}
}
//没入成功
if (!errorMsg.isEmpty()) {
//有错误,记录日志
AlarmInfo alarmInfo = new AlarmInfo();
alarmInfo.setBoxId("0");
alarmInfo.setStorageName("流水线");
alarmInfo.setInOutStatus("1");
alarmInfo.setAlarmType("入库");
Date date = new Date();
alarmInfo.setStartTime(date);
alarmInfo.setEndTime(date);
String msg = "[" + code + "]" + errorMsg;
alarmInfo.setAlarmMsg(msg);
alarmInfoDao.save(alarmInfo);
lineMsg = errorMsg;
DeviceMessageUtil.updateLineMsg(lineMsg, code, cids, "", "", null);
} else {
lineMsg = okMsg;
}
return resultMap;
}
@ApiOperation("机器人料仓更新任务状态")
@PostMapping(value = "/service/store/robotBox/updateLocInfo")
@ResponseBody
@AnonymousAccess
public ResultBean updateLocInfo(HttpServletRequest request) {
String barcode = request.getParameter("barcode");
String statusStr = request.getParameter("status");
String locInfo = request.getParameter("locInfo");
log.debug("收到料盘[" + barcode + "]更新位置指令[" + statusStr + "]=" + locInfo);
if(ObjectUtil.isEmpty(locInfo)){
locInfo=statusStr;
}
DataLog task = taskService.findTask(barcode);
if (task == null) {
return ResultBean.newErrorResult(301, "smfcore.task.notExist", "任务不存在");
}
if (task.isFinished()) {
return ResultBean.newErrorResult(302, "smfcore.task.hasEnd", "任务已完成");
}
if (task.isCancel()) {
return ResultBean.newErrorResult(303, "smfcore.task.hasCancel", "更新状态时{0}的出库任务[{1}]已被取消", new String[]{task.getBarcode(), task.getId()});
}
statusStr = statusStr.toUpperCase();
log.info("更新料盘[" + barcode + "]的任务状态[" + task.getStatus() + "=" + task.getLocInfo() + "]为[" + statusStr + "=" + locInfo + "]");
task.setStatus(statusStr);
task.setLocInfo(locInfo);
//如果是出库任务并且放到料仓门口,需要发送任务给料仓
// if(task.isInBelt() || task.isPackageReel()){
// //已经放上皮带线
// AppendInfo appendInfo = task.getAppendInfo();
// if(org.apache.logging.log4j.util.Strings.isBlank(appendInfo.gethSerial())){
// log.info("手动出库料盘["+barcode+"]放上皮带线或包装料架,结束任务");
// task.setStatus(StorageConstants.OP_STATUS.FINISHED.name());
// }else if(appendInfo.isCheckAction()){
// log.info("盘点料盘["+barcode+"]放上皮带线或包装料架,结束任务");
// task.setStatus(StorageConstants.OP_STATUS.FINISHED.name());
// //盘点料,出到皮带线上即算完成
// int slotSeq = appendInfo.getSlotIndex();
// int sendQty = task.getNum();
// outInfoCache.incTaskFinishNum(appendInfo.gethSerial(),slotSeq, sendQty);
// }
// }
task = taskService.updateQueueTask(task);
return ResultBean.newOkResult("");
}
@ApiOperation("机器人定时获取出入库任务")
@PostMapping(value = "/service/store/robotBox/getRobotTask")
@ResponseBody
@AnonymousAccess
public ResultBean getRobotTask(HttpServletRequest request) {
//TODO 先查找是否有出库任务,在查找入库任务
Collection<DataLog> datalogs = taskService.getQueueTasks();
//先查找已在机器人的
for (DataLog task : datalogs) {
if (task.isInRobot()) {
//获取任务失败,还有未完成的任务
return ResultBean.newErrorResult(301, "smfcore.task.lastNotEnd", "上个任务未结束{0}{1}", new String[]{task.getPosName(), task.getBarcode()});
}
}
//查找出库已经到门口的
for (DataLog task : datalogs) {
if (OP.CHECKOUT == task.getType()) {
if (task.isBoxdoor()) {
Map<String, String> taskMap = new HashMap<>();
taskMap.put("cid", task.getCid());//取料位置
taskMap.put("targetPos", "out");//放料位置
taskMap.put("posId", task.getPosName());
Barcode barcode = barcodeManager.findByBarcode(task.getBarcode());
int plateW = 0;
int plateH = 0;
if (barcode != null) {
plateW = barcode.getPlateSize();
plateH = barcode.getHeight();
}
taskMap.put("plateW", plateW + "");
taskMap.put("plateH", plateH + "");
taskMap.put("barcode", task.getBarcode());
return ResultBean.newOkResult(taskMap);
}
}
}
return ResultBean.newErrorResult(-1, "", "");
}
@Override
public DeviceType getDeviceType() {
return DeviceType.ROBOT_BOX;
}
}
......@@ -7,6 +7,7 @@ import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.language.service.bean.LanguageInfo;
import com.neotel.smfcore.core.language.util.MessageUtils;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.neotel.smfcore.security.rest.bean.dto.UserDto;
import com.neotel.smfcore.security.service.po.User;
import io.swagger.annotations.Api;
......@@ -47,7 +48,8 @@ public class LanguageSetController {
@ApiOperation("获取语言列表")
@GetMapping
@PreAuthorize("@el.check('translation')")
@AnonymousAccess
// @PreAuthorize("@el.check('translation')")
public List<LanguageInfo> getList(){
return getAllLanList();
}
......
......@@ -110,6 +110,11 @@ public enum DeviceType {
NLP("storage.type.nlp"),
/**
* 18 机器人料仓
*/
ROBOT_BOX("storage.type.robotBox"),
/**
* 18 (默认料仓)
*/
DEFAULT("storage.type.default")
......@@ -134,6 +139,6 @@ public enum DeviceType {
}
public static List<DeviceType> availableTypeList(){
return Lists.newArrayList(AUTO,LINE,BATCH,SOLDERPASTE,VERTICALBOX,SMD_XL,SMD_DUO,SMD_XLC,VIRTUAL,NL,NLP);
return Lists.newArrayList(AUTO,LINE,BATCH,SOLDERPASTE,VERTICALBOX,SMD_XL,SMD_DUO,SMD_XLC,VIRTUAL,NL,NLP,ROBOT_BOX);
}
}
......@@ -239,8 +239,14 @@ public class StoragePosController {
pos.setPriority(saveDto.getPriority());
pos.setH(saveDto.getH());
pos.setW(saveDto.getW());
String enabledStr="";
if(pos.isEnabled()!= saveDto.isEnabled()){
pos.setEnabled(saveDto.isEnabled());
enabledStr=saveDto.isEnabled()?",启用库位":",禁用库位";
}
storagePosManager.save(pos);
log.info("修改库位:库位号[" + pos.getId() + "]=[" + saveDto.toString() + "]");
log.info("修改库位:库位号[" + pos.getId() + "]=[" + saveDto.toString() + "]"+enabledStr);
return new ResponseEntity<>(HttpStatus.OK);
}
......
......@@ -24,4 +24,7 @@ public class StoragePosSaveDto implements Serializable {
@ApiModelProperty("宽度")
private int w;
@ApiModelProperty("是否可用,true=可用,false=禁用")
private boolean enabled = true;
}
......@@ -179,6 +179,10 @@ public class Storage extends BasePo implements Serializable {
return DeviceType.SMD_XLC.name().equals(type);
}
public boolean isRobotBox() {
return DeviceType.ROBOT_BOX.name().equals(type);
}
public boolean isType(DeviceType[] types){
for (DeviceType str :
types) {
......
......@@ -210,6 +210,11 @@ public class DataLog extends BasePo implements Serializable {
*/
private MSDAppendInfo msdAppendInfo;
/**
* 位置信息,如料架编号,托盘编号,移栽编号,皮带线编号,机器人编号等
*/
private String locInfo = "";
public String getBarcode() {
if(barcode == null){
return "";
......@@ -252,6 +257,14 @@ public class DataLog extends BasePo implements Serializable {
return OP_STATUS.END.name().equals(status);
}
public boolean isInRobot(){
return OP_STATUS.INROBOT.name().equals(status);
}
public boolean isBoxdoor(){
return OP_STATUS.BOXDOOR.name().equals(status);
}
/**
* 是否是入库任务
......
......@@ -325,6 +325,21 @@ public class TaskService {
return false;
}
private DataLog findPutInBoxTask(Storage storage){
if(storage.isRobotBox()){
for (DataLog task : taskMap.values()) {
if (OP.PUT_IN == task.getType() && task.getCid().equals(storage.getCid())) {
if(task.isBoxdoor()){
return task;
}
}
}
}
return null;
}
/**
* 为 box 分配出库任务
*/
......@@ -393,6 +408,30 @@ public class TaskService {
*/
public StatusBean checkOut(Storage storage, StatusBean statusBean) {
try {
DataLog putInTask=findPutInBoxTask(storage);
if(putInTask!=null){
//发送入库任务到BOX
putInTask.setStatus(OP_STATUS.EXECUTING.name());
taskMap.put(putInTask.getId(), putInTask);
putInTask = dataLogDao.save(putInTask);
String posName = putInTask.getPosName();
Barcode codeObj = barcodeManager.findByBarcode(putInTask.getBarcode());
int plateW = 0;
int plateH = 0;
if (codeObj != null) {
plateW = codeObj.getPlateSize();
plateH = codeObj.getHeight();
} else {
log.warn("入库未找到条码" + storage.getName() + "[" + posName + "],条码["+putInTask.getBarcode()+"]");
}
statusBean.setOp(OP.PUT_IN);
statusBean.addPosInfo(putInTask.getBarcode(), posName, plateW, plateH, true);
log.info("入库" + storage.getName() + "[" + posName + "]物料[" + putInTask.getBarcode() + "]["+putInTask.getStatus()+"]到 " + storage.getCid());
return statusBean;
}
//准备更新暂停出入库
if (dataCache.getCache(Constants.CACHE_StopOut)) {
return statusBean;
......@@ -946,4 +985,13 @@ public class TaskService {
taskMap.remove(task.getId());
theFinishedTaskMap.put(task.getId(), task);
}
public DataLog findTask(String barcode) {
for (DataLog task : taskMap.values()) {
if (task.getBarcode().equals(barcode)) {
return task;
}
}
return null;
}
}
......@@ -103,7 +103,7 @@ public class MenuController {
List<Menu> menus=menuManager.getMenusByPid(pid);
Locale locale=servletRequest.getLocale();
for (Menu menu :menus
) {
) {
menu.UpdateTitle(locale);
}
List<MenuDto> dtos=menuMapper.toDto(menus);
......@@ -161,8 +161,8 @@ public class MenuController {
@PostMapping
@PreAuthorize("@el.check('menu:add')")
public ResponseEntity<Object> create(@Validated @RequestBody MenuDto menuDto) {
Menu resources=menuMapper.toEntity(menuDto);
menuManager.saveMenu(resources);
// Menu resources=menuMapper.toEntity(menuDto);
// menuManager.saveMenu(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
}
......@@ -184,16 +184,16 @@ public class MenuController {
@DeleteMapping
@PreAuthorize("@el.check('menu:del')")
public ResponseEntity<Object> delete(@RequestBody Set<String> ids) {
if(!SecurityUtils.getCurrentUsername().equals(Constants.SUPER_USERNAME)){
throw new ValidateException("smfcore.noAccessUpdate","没有删除菜单的权限");
}
Set<Menu> menuSet = new HashSet<>();
for (String id : ids) {
List<Menu> menuList = menuManager.getMenusByPid(id);
menuSet.add(menuManager.get(id));
menuSet = menuManager.getChildMenus(menuList, menuSet);
}
menuManager.delete(menuSet);
// if(!SecurityUtils.getCurrentUsername().equals(Constants.SUPER_USERNAME)){
// throw new ValidateException("smfcore.noAccessUpdate","没有删除菜单的权限");
// }
// Set<Menu> menuSet = new HashSet<>();
// for (String id : ids) {
// List<Menu> menuList = menuManager.getMenusByPid(id);
// menuSet.add(menuManager.get(id));
// menuSet = menuManager.getChildMenus(menuList, menuSet);
// }
// menuManager.delete(menuSet);
return new ResponseEntity<>(HttpStatus.OK);
}
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!