Commit eba0d589 LN

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/main/java/com/neotel/smfcore/security/service/manager/IGroupManager.java
2 个父辈 1a64803c 8641e00b
正在显示 29 个修改的文件 包含 1158 行增加260 行删除
...@@ -149,6 +149,13 @@ ...@@ -149,6 +149,13 @@
<artifactId>mapstruct-jdk8</artifactId> <artifactId>mapstruct-jdk8</artifactId>
<version>1.4.0.Final</version> <version>1.4.0.Final</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.mina/mina-core -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies> </dependencies>
......
package com.neotel.smfcore.common.bean;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* Created by sunke on 2019/12/12.
*/
@Slf4j
public class ResultBean {
public static ResultBean newErrorResult(int code, String msg){
return newErrorResult(code, msg, true);
}
public static ResultBean newErrorResult(int code, String msg, boolean writeLog){
ResultBean result = new ResultBean();
result.setCode(code);
result.setMsg(msg);
if(writeLog){
log.info(msg);
}
return result;
}
public static ResultBean newOkResult(String msg, Object data){
ResultBean result = new ResultBean();
result.setCode(0);
result.setMsg(msg);
result.setData(data);
return result;
}
public static ResultBean newOkResult(Object data){
return newOkResult("ok", data);
}
/**
* 结果码,0为正常,其他值表示异常
*/
private int code;
/**
* 提示信息
*/
private String msg;
/**
* 数据结果
*/
private Object data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
...@@ -199,26 +199,6 @@ public class StorageConstants { ...@@ -199,26 +199,6 @@ public class StorageConstants {
} }
} }
public static class BARCODE_STATUS{
/**
*-1新建
*/
public static int NEW = -1;
/**
* 0在库
*/
public static int IN_STORE = 0;
/**
* 1已出库正常
*/
public static int OUT_NORMAL = 1;
/**
* 2已出库且已过期
*/
public static int OUT_EXPIRED = 2;
}
public static class CABINET_STEP{ public static class CABINET_STEP{
/** /**
...@@ -234,90 +214,4 @@ public class StorageConstants { ...@@ -234,90 +214,4 @@ public class StorageConstants {
*/ */
public static int WAIT_CLOSE_DOOR = 2; public static int WAIT_CLOSE_DOOR = 2;
} }
/**
* 轻工单执行状态
*/
public static class LITEORDER_STATUS{
/**新建的工单*/
public static int NEW=0;
/**首套料正在执行*/
public static int BOM=1;
/**首盘料已结束,等待出尾料*/
public static int BOM_FINISHED=2;
/**正在出尾料*/
public static int TAILS=3;
/**尾料已完成*/
public static int TAILS_FINISHED=4;
/**正在补料*/
public static int ONE=5;
/**补料已完成*/
public static int ONE_FINISHED=6;
}
private static int currentColorIndex = -1;
/**
* 工单颜色, 入库绿色,出库红色,库位检查使用黄色, 其他颜色用于工单出库颜色
*/
public enum ORDER_COLOR{
//magenta,cyan,firebrick,purple,skyblue,pink,forestgreen,lightblue,indianred,darkgreen
//洋红,青色,砖红色,紫色,天蓝色,粉色,森林绿,浅蓝色,印度红,深绿色
BLUE("0000FF"),
MAGENTA("FF00FF"),
CYAN("00FFFF"),
FIREBRICK("B22222"),
PURPLE("A020F0"),
SKYBLUE("6CA6CD"),
PINK("FF1493"),
FORESTGREEN("228B22"),
LIGHTBLUE("8470FF"),
INDIANRED("8B3A3A"),
DARKGREEN("556B2F");
private String rgb;
ORDER_COLOR(String rgb){
this.rgb = rgb;
}
public String getRgb() {
return rgb;
}
public void setRgb(String rgb) {
this.rgb = rgb;
}
public static ORDER_COLOR fromRgb(String rgb){
for (ORDER_COLOR order_color : values()) {
if(order_color.getRgb().equals(rgb)){
return order_color;
}
}
return null;
}
public static ORDER_COLOR nextColor(Collection<String> excludeColors){
ORDER_COLOR[] allColors = values();
if (excludeColors.size() >= allColors.length){
return null;
}
int nextColorIndex = (currentColorIndex + 1) % allColors.length;
for (ORDER_COLOR color : allColors) {
if(!excludeColors.contains(color.getRgb()) && color.ordinal() >= nextColorIndex){
currentColorIndex = color.ordinal();
return color;
}
}
return null;
}
}
} }
package com.neotel.smfcore.core.barcode.enums;
/**
* Created by sunke on 2021/7/19.
*/
public class BARCODE_STATUS {
/**
*-1新建
*/
public static int NEW = -1;
/**
* 0在库
*/
public static int IN_STORE = 0;
/**
* 1已出库正常
*/
public static int OUT_NORMAL = 1;
/**
* 2已出库且已过期
*/
public static int OUT_EXPIRED = 2;
}
...@@ -4,9 +4,11 @@ import com.google.common.collect.Lists; ...@@ -4,9 +4,11 @@ import com.google.common.collect.Lists;
import com.neotel.smfcore.common.base.BasePo; import com.neotel.smfcore.common.base.BasePo;
import com.neotel.smfcore.common.utils.DateUtil; import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.common.utils.StorageConstants; import com.neotel.smfcore.common.utils.StorageConstants;
import com.neotel.smfcore.core.barcode.enums.BARCODE_STATUS;
import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE; import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE;
import com.neotel.smfcore.core.barcode.enums.SOLDER_STATUS; import com.neotel.smfcore.core.barcode.enums.SOLDER_STATUS;
import lombok.Data;
import lombok.*;
import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
...@@ -39,7 +41,7 @@ public class Barcode extends BasePo implements Serializable { ...@@ -39,7 +41,7 @@ public class Barcode extends BasePo implements Serializable {
/** /**
* 过期状态,-1未入库0在库,1已出库正常,2已出库且已过期 * 过期状态,-1未入库0在库,1已出库正常,2已出库且已过期
*/ */
private int status = StorageConstants.BARCODE_STATUS.NEW; private int status = BARCODE_STATUS.NEW;
/** /**
* 锡膏状态 * 锡膏状态
...@@ -168,6 +170,16 @@ public class Barcode extends BasePo implements Serializable { ...@@ -168,6 +170,16 @@ public class Barcode extends BasePo implements Serializable {
* 锁定ID(目前只有指定批次会锁定) * 锁定ID(目前只有指定批次会锁定)
*/ */
private String lockId; private String lockId;
/**
* 锁定名
*/
private String lockName;
/**
* 原始条码
*/
private String fullCode;
/** /**
* 添加相关联条码 * 添加相关联条码
* *
...@@ -189,7 +201,7 @@ public class Barcode extends BasePo implements Serializable { ...@@ -189,7 +201,7 @@ public class Barcode extends BasePo implements Serializable {
this.putInDate = new Date(putInTime); this.putInDate = new Date(putInTime);
} }
status = StorageConstants.BARCODE_STATUS.IN_STORE; status = BARCODE_STATUS.IN_STORE;
updateExpTime(); updateExpTime();
...@@ -268,9 +280,9 @@ public class Barcode extends BasePo implements Serializable { ...@@ -268,9 +280,9 @@ public class Barcode extends BasePo implements Serializable {
updateExpTime(); updateExpTime();
if(expTime != null && checkOutDate.after(expTime)){ if(expTime != null && checkOutDate.after(expTime)){
//过期时间小于出库时间,说明出库的时候已经过期了 //过期时间小于出库时间,说明出库的时候已经过期了
status = StorageConstants.BARCODE_STATUS.OUT_EXPIRED; status = BARCODE_STATUS.OUT_EXPIRED;
}else{ }else{
status = StorageConstants.BARCODE_STATUS.OUT_NORMAL; status = BARCODE_STATUS.OUT_NORMAL;
} }
} }
} }
......
...@@ -30,6 +30,7 @@ import com.neotel.smfcore.core.system.service.po.AlarmInfo; ...@@ -30,6 +30,7 @@ import com.neotel.smfcore.core.system.service.po.AlarmInfo;
import com.neotel.smfcore.core.system.service.po.DataLog; import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.service.po.Humiture; import com.neotel.smfcore.core.system.service.po.Humiture;
import com.neotel.smfcore.core.system.util.TaskService; import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.security.service.manager.IGroupManager;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -46,7 +47,7 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -46,7 +47,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class BaseDeviceHandler implements IDeviceHandler { public class BaseDeviceHandler implements IDeviceHandler {
@Autowired @Autowired
private DataCache dataCache; protected DataCache dataCache;
@Autowired @Autowired
private IAlarmInfoDao alarmInfoDao; private IAlarmInfoDao alarmInfoDao;
...@@ -66,6 +67,10 @@ public class BaseDeviceHandler implements IDeviceHandler { ...@@ -66,6 +67,10 @@ public class BaseDeviceHandler implements IDeviceHandler {
@Autowired @Autowired
protected CodeResolve codeResolve; protected CodeResolve codeResolve;
@Autowired
protected IGroupManager groupManager;
/** /**
* 状态 map,key为 cid value 为状态 Bean * 状态 map,key为 cid value 为状态 Bean
*/ */
......
package com.neotel.smfcore.core.device.handler.impl;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.StorageConstants;
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.device.api.IOpAuthApi;
import com.neotel.smfcore.core.device.bean.StatusBean;
import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.order.enums.ORDER_COLOR;
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.po.DataLog;
import com.neotel.smfcore.security.service.po.Group;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;
/**
* 锡膏料仓
* Created by sunke on 2021/7/12.
*/
@RestController
@Slf4j
public class SensorShelfHandler extends BaseDeviceHandler {
public SensorShelfHandler(List<IOpAuthApi> apiList) {
super(apiList);
}
@Override
public StatusBean handleClientRequest(StatusBean statusBean, HttpServletRequest request) {
handleMsg(statusBean);
statusBean = saveAlarmAndHumidity(statusBean);
//亮灯
Collection<DataLog> queueTasks = taskService.getQueueTasks(statusBean.getCid());
for (DataLog queueTask : queueTasks) {
if(queueTask.isWait()){
queueTask.setStatus(OP_STATUS.EXECUTING.name());
taskService.updateQueueTask(queueTask);
String rgb = queueTask.getLightColor();
ORDER_COLOR color = ORDER_COLOR.fromRgb(rgb);
if(color == null){
if(queueTask.isPutInTask()){
color = ORDER_COLOR.DARKGREEN;
}else{
color = ORDER_COLOR.BLUE;
}
}
statusBean.addData("open",queueTask.getPosName()+"="+color.name());
log.info("库位["+queueTask.getPosName()+"]+亮灯:" + color.name());
}
}
return statusBean;
}
/**
* 客户端sensor变化
*/
@RequestMapping("/service/store/sensorShelf/sensorChange")
@ResponseBody
public ResultBean sensorChange(HttpServletRequest request, HttpSession httpSession){
String cid = request.getParameter("cid");
Storage storage = dataCache.getStorage(cid);
if(storage == null){
return ResultBean.newErrorResult(-1,cid + "对应的料架不存在");
}
String groupId = storage.getGroupId();
String groupName = "";
Group group = groupManager.get(groupId);
if(group != null){
groupName = group.getGroupName();
}
String[] hasReelPosList = request.getParameterValues("hasReelPosList");
String[] noReelPosList = request.getParameterValues("noReelPosList");
List<String> inOkList = new ArrayList<>();
List<String> inNgList = new ArrayList<>();
List<String> outOkList = new ArrayList<>();
List<String> outNgList = new ArrayList<>();
if(hasReelPosList != null){
//入库的库位列表
if(hasReelPosList.length > 1){
log.error("不可同时放入多盘物料:"+ hasReelPosList);
for (String posStr : hasReelPosList) {
inNgList.add(posStr);
}
}else{
StoragePos pos = storagePosManager.getByPosName(hasReelPosList[0]);
if(pos == null){
inNgList.add(hasReelPosList[0]);
log.error("未找到库位:"+ hasReelPosList);
}else{
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if(queueTask.isPutInTask() && queueTask.getSourceName().equals(groupName)){
queueTask.setCid(cid);
queueTask.setPosId(pos.getId());
queueTask.setPosName(pos.getPosName());
queueTask.setStorageId(pos.getStorageId());
queueTask.setStorageName(storage.getName());
try {
//入库完成,发送入库完成请求
super.finishedPutIn(cid,pos.getPosName());
inOkList.add(hasReelPosList[0]);
break;
} catch (Exception e) {
log.error("入库出错",e);
return ResultBean.newErrorResult(-1,"入库出错:" + e.getMessage());
}
}
}
if(inOkList.size() == 0){
inNgList.add(hasReelPosList[0]);
log.error("未找到["+pos.getPosName()+"]的入库任务");
}
}
}
}
if(noReelPosList != null){
//出库
for (String posName : noReelPosList) {
String outResult = "";
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if(queueTask.isCheckOutTask() && queueTask.getPosName().equals(posName)){
//出库完成
try {
outResult = posName;
super.finishedOutPos(cid,posName);
break;
} catch (Exception e) {
log.error("出库出错",e);
return ResultBean.newErrorResult(-1,"出库出错:" + e.getMessage());
}
}
}
if(outResult.isEmpty()){
log.info("未找到["+posName+"]的出库任务");
outNgList.add(posName);
}else{
outOkList.add(outResult);
}
}
}
Map<String,List<String>> dataMap = new HashMap<>();
dataMap.put("inOkList",inOkList);
dataMap.put("inNgList",inNgList);
dataMap.put("outOkList",outOkList);
dataMap.put("outNgList",outNgList);
return ResultBean.newOkResult(dataMap);
}
/**
* 获取料架的库位占用情况
*/
@RequestMapping("/service/store/sensorShelf/hasReelPosList")
@ResponseBody
public ResultBean checkAll(HttpServletRequest request){
String cid = request.getParameter("cid");
Storage storage = dataCache.getStorage(cid);
List<StoragePos> allPos = storagePosManager.findNotEmptyByStorageId(storage.getId());
List<String> posList = new ArrayList<>();
for (StoragePos pos : allPos) {
posList.add(pos.getPosName());
}
return ResultBean.newOkResult(posList);
}
@Override
public DeviceType getDeviceType() {
return DeviceType.SOLDERPASTE;
}
}
package com.neotel.smfcore.core.device.util; package com.neotel.smfcore.core.device.util;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.StorageConstants; import com.neotel.smfcore.common.utils.StorageConstants;
import com.neotel.smfcore.core.barcode.service.po.Barcode; import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.utils.CodeResolve; import com.neotel.smfcore.core.barcode.utils.CodeResolve;
...@@ -98,15 +100,15 @@ public class DataCache { ...@@ -98,15 +100,15 @@ public class DataCache {
return settings; return settings;
} }
//
// /** /**
// * 出库方式 * 出库方式
// */ */
// public CHECKOUT_TYPE getCheckOutType(){ public CHECKOUT_TYPE getCheckOutType(){
// String outType = getSettings().getOutType(); String outType = getSettings().getOutType();
// return CHECKOUT_TYPE.valueOf(outType); return CHECKOUT_TYPE.valueOf(outType);
// } }
//
public Settings updateSettings(Settings newSetting){ public Settings updateSettings(Settings newSetting){
settings = settingsDao.save(newSetting); settings = settingsDao.save(newSetting);
List<String> ruleItems = settings.getCodeRuleList(); List<String> ruleItems = settings.getCodeRuleList();
...@@ -239,78 +241,78 @@ public class DataCache { ...@@ -239,78 +241,78 @@ public class DataCache {
return null; return null;
} }
// public Storage reloadStorage(Storage storage) throws ValidateException { public Storage reloadStorage(Storage storage) throws ValidateException {
// List<PlateSizeBean> plateSizeBeanList = storagePosManager.getStoragePosUsage(storage.getId()); List<PlateSizeBean> plateSizeBeanList = storagePosManager.getStoragePosUsage(storage.getId());
// storage.initUsage(plateSizeBeanList); storage.initUsage(plateSizeBeanList);
// storage = storageManager.save(storage); storage = storageManager.save(storage);
// allStorage.put(storage.getCid(), storage); allStorage.put(storage.getCid(), storage);
// return storage; return storage;
// } }
//
//
// /** /**
// * 锁定库存 * 锁定库存
// * @param cid * @param cid
// * @param partNumber 物料编号 * @param partNumber 物料编号
// * @return 锁定结果,true 表示有足够的库存,锁定成功;false表示库存不足,锁定失败 * @return 锁定结果,true 表示有足够的库存,锁定成功;false表示库存不足,锁定失败
// */ */
// public boolean lockOneReel(String cid, String partNumber){ public boolean lockOneReel(String cid, String partNumber){
// boolean result = false; boolean result = false;
// InventoryItem inventoryItem = getStorageInventoryByPartNumber(cid, partNumber); InventoryItem inventoryItem = getStorageInventoryByPartNumber(cid, partNumber);
// if(inventoryItem != null) { if(inventoryItem != null) {
// int lockReel = inventoryItem.getLockReel(); int lockReel = inventoryItem.getLockReel();
// //理论上这里是同一个对象,不需要再显式的放入map 中 //理论上这里是同一个对象,不需要再显式的放入map 中
// result = inventoryItem.lockOne(); result = inventoryItem.lockOne();
// log.info("锁定料仓["+cid+"]物料["+partNumber+"],锁定数量["+lockReel+"]=>["+inventoryItem.getLockReel()+"],当前库存:"+inventoryItem.getStockReel()); log.info("锁定料仓["+cid+"]物料["+partNumber+"],锁定数量["+lockReel+"]=>["+inventoryItem.getLockReel()+"],当前库存:"+inventoryItem.getStockReel());
// updateStorageInventory(cid,inventoryItem); updateStorageInventory(cid,inventoryItem);
// } }
// return result; return result;
// } }
// /** /**
// * 解除锁定库存(出库任务完成或取消时调用) * 解除锁定库存(出库任务完成或取消时调用)
// */ */
// public void unLockOneReel(String cid, String partNumber){ public void unLockOneReel(String cid, String partNumber){
// InventoryItem partNumberInventory = getStorageInventoryByPartNumber(cid, partNumber); InventoryItem partNumberInventory = getStorageInventoryByPartNumber(cid, partNumber);
// if(partNumberInventory != null) { if(partNumberInventory != null) {
// int lockReel = partNumberInventory.getLockReel(); int lockReel = partNumberInventory.getLockReel();
// //理论上这里是同一个对象,不需要再显式的放入map 中 //理论上这里是同一个对象,不需要再显式的放入map 中
// partNumberInventory.unLock(1); partNumberInventory.unLock(1);
// log.info("解除锁定料仓["+cid+"]物料["+partNumber+"],锁定数量["+lockReel+"]=>["+partNumberInventory.getLockReel()+"],当前库存:"+partNumberInventory.getStockReel()); log.info("解除锁定料仓["+cid+"]物料["+partNumber+"],锁定数量["+lockReel+"]=>["+partNumberInventory.getLockReel()+"],当前库存:"+partNumberInventory.getStockReel());
// updateStorageInventory(cid,partNumberInventory); updateStorageInventory(cid,partNumberInventory);
// } }
// } }
//
// /** /**
// * 获取库存信息,key 为 PN * 获取库存信息,key 为 PN
// */ */
// public Map<String,InventoryItem> getAllInventory(){ public Map<String,InventoryItem> getAllInventory(){
// Map<String, Storage> allStorages = getAllStorage(); Map<String, Storage> allStorages = getAllStorage();
// return getInventory(allStorages.values()); return getInventory(allStorages.values());
// } }
//
// /** /**
// * 获取某些料仓的库存信息 * 获取某些料仓的库存信息
// */ */
// public Map<String,InventoryItem> getInventory(Collection<Storage> storageList){ public Map<String,InventoryItem> getInventory(Collection<Storage> storageList){
// Map<String,InventoryItem> resultMap = Maps.newHashMap(); Map<String,InventoryItem> resultMap = Maps.newHashMap();
// for (Storage storage : storageList) { for (Storage storage : storageList) {
// Map<String, InventoryItem> storageInventory = getStorageInventory(storage.getCid()); Map<String, InventoryItem> storageInventory = getStorageInventory(storage.getCid());
// for(InventoryItem storageInventoryItem : storageInventory.values()){ for(InventoryItem storageInventoryItem : storageInventory.values()){
// String partNumber = storageInventoryItem.getPartNumber(); String partNumber = storageInventoryItem.getPartNumber();
// InventoryItem pnInventoryItem = resultMap.get(storageInventoryItem.getPartNumber()); InventoryItem pnInventoryItem = resultMap.get(storageInventoryItem.getPartNumber());
// if(pnInventoryItem == null){ if(pnInventoryItem == null){
// pnInventoryItem = new InventoryItem(); pnInventoryItem = new InventoryItem();
// } }
// pnInventoryItem.setPartNumber(partNumber); pnInventoryItem.setPartNumber(partNumber);
// pnInventoryItem.setStockCount(pnInventoryItem.getStockCount() + storageInventoryItem.getStockCount()); pnInventoryItem.setStockCount(pnInventoryItem.getStockCount() + storageInventoryItem.getStockCount());
// pnInventoryItem.setLockCount(pnInventoryItem.getLockCount() + storageInventoryItem.getLockCount()); pnInventoryItem.setLockCount(pnInventoryItem.getLockCount() + storageInventoryItem.getLockCount());
// pnInventoryItem.setStockReel(pnInventoryItem.getStockReel() + storageInventoryItem.getStockReel()); pnInventoryItem.setStockReel(pnInventoryItem.getStockReel() + storageInventoryItem.getStockReel());
// pnInventoryItem.setLockReel(pnInventoryItem.getLockReel() + storageInventoryItem.getLockReel()); pnInventoryItem.setLockReel(pnInventoryItem.getLockReel() + storageInventoryItem.getLockReel());
// resultMap.put(partNumber,pnInventoryItem); resultMap.put(partNumber,pnInventoryItem);
// } }
// } }
// return resultMap; return resultMap;
// } }
/** /**
* 获取料仓的库存信息 * 获取料仓的库存信息
......
package com.neotel.smfcore.core.order.listener; package com.neotel.smfcore.core.order;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException; import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.enums.OP; 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.order.enums.ORDER_COLOR;
import com.neotel.smfcore.core.order.service.dao.ILiteOrderDao; import com.neotel.smfcore.core.order.service.dao.ILiteOrderDao;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager; import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager; import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder; import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem; import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
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.listener.ITaskListener; import com.neotel.smfcore.core.system.listener.ITaskListener;
import com.neotel.smfcore.core.system.service.po.DataLog; import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
...@@ -24,7 +31,7 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -24,7 +31,7 @@ import java.util.concurrent.ConcurrentHashMap;
*/ */
@Service @Service
@Slf4j @Slf4j
public class LiteOrderListener implements ITaskListener { public class LiteOrderCache implements ITaskListener {
@Autowired @Autowired
private ILiteOrderManager liteOrderManager; private ILiteOrderManager liteOrderManager;
...@@ -32,6 +39,15 @@ public class LiteOrderListener implements ITaskListener { ...@@ -32,6 +39,15 @@ public class LiteOrderListener implements ITaskListener {
@Autowired @Autowired
private ILiteOrderItemManager liteOrderItemManager; private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private TaskService taskService;
@Autowired
private DataCache dataCache;
@Autowired
private IStoragePosManager storagePosManager;
/** /**
* 正在执行的liteOrderMap, key 为orderNo,value 为order * 正在执行的liteOrderMap, key 为orderNo,value 为order
*/ */
...@@ -46,6 +62,47 @@ public class LiteOrderListener implements ITaskListener { ...@@ -46,6 +62,47 @@ public class LiteOrderListener implements ITaskListener {
} }
} }
public ResultBean checkOutOrders(LiteOrder liteOrder) throws ValidateException {
//设置颜色
Set<String> currentColors = new HashSet<>();
for (DataLog dataLog : taskService.getQueueTasks()) {
currentColors.add(dataLog.getLightColor());
}
ORDER_COLOR nextColor = ORDER_COLOR.nextColor(currentColors);
//其他出库模式一次性全部生成任务
List<StoragePos> lockPosList = storagePosManager.findLockPos(liteOrder.getOrderNo());
int taskReelCount = 0;
for (StoragePos lockPos : lockPosList) {
Storage storage = dataCache.getStorageById(lockPos.getStorageId());
Barcode barcode = lockPos.getBarcode();
DataLog task = new DataLog(storage,barcode,lockPos);
task.setSourceId(liteOrder.getId());
task.setSourceName(liteOrder.getOrderNo());
task.setSubSourceId(barcode.getLockName());
task.setSubSourceInfo(barcode.getLockName());
task.setType(OP.CHECKOUT);
task.setLightColor(nextColor.getRgb());
task.setStatus(OP_STATUS.WAIT.name());
taskService.addTaskToExecute(task);
taskReelCount = taskReelCount + 1;
log.info("工单[" + liteOrder.getOrderNo() + "]出库位置仓位【" + task.getPosName() + "】RI=[" + task.getBarcode() + "] PN=[" + task.getPartNumber() + "] ");
}
liteOrder.setTaskReelCount(taskReelCount);
log.info("工单[" + liteOrder.getOrderNo() + "]任务分配结束,任务数[" + taskReelCount + "]");
//有需要出库的
if (taskReelCount <= 0) {
liteOrder.finishedTasks();
}
liteOrderManager.save(liteOrder);
if (taskReelCount <= 0) {
return ResultBean.newErrorResult(-1,"No task in this order");
}
return ResultBean.newOkResult("total task is :" + taskReelCount,"");
}
/** /**
* 更新工单状态信息 * 更新工单状态信息
*/ */
......
package com.neotel.smfcore.core.order.enums;
/**
* Created by sunke on 2021/7/19.
*/
public class LITEORDER_STATUS {
/**新建的工单*/
public static int NEW=0;
/**首套料正在执行*/
public static int BOM=1;
/**首盘料已结束,等待出尾料*/
public static int BOM_FINISHED=2;
/**正在出尾料*/
public static int TAILS=3;
/**尾料已完成*/
public static int TAILS_FINISHED=4;
/**正在补料*/
public static int ONE=5;
/**补料已完成*/
public static int ONE_FINISHED=6;
}
package com.neotel.smfcore.core.order.enums;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* Created by sunke on 2021/7/19.
*/
public enum ORDER_COLOR {
//magenta,cyan,firebrick,purple,skyblue,pink,forestgreen,lightblue,indianred,darkgreen
//洋红,青色,砖红色,紫色,天蓝色,粉色,森林绿,浅蓝色,印度红,深绿色
BLUE("0000FF"),
MAGENTA("FF00FF"),
CYAN("00FFFF"),
FIREBRICK("B22222"),
PURPLE("A020F0"),
SKYBLUE("6CA6CD"),
PINK("FF1493"),
FORESTGREEN("228B22"),
LIGHTBLUE("8470FF"),
INDIANRED("8B3A3A"),
DARKGREEN("556B2F"), ;
private static int currentColorIndex = -1;
private String rgb;
ORDER_COLOR(String rgb){
this.rgb = rgb;
}
public String getRgb() {
return rgb;
}
public void setRgb(String rgb) {
this.rgb = rgb;
}
public static ORDER_COLOR fromRgb(String rgb){
for (ORDER_COLOR order_color : values()) {
if(order_color.getRgb().equals(rgb)){
return order_color;
}
}
return null;
}
public static ORDER_COLOR nextColor(Collection<String> excludeColors){
ORDER_COLOR[] allColors = values();
if (excludeColors.size() >= allColors.length){
return null;
}
int nextColorIndex = (currentColorIndex + 1) % allColors.length;
for (ORDER_COLOR color : allColors) {
if(!excludeColors.contains(color.getRgb()) && color.ordinal() >= nextColorIndex){
currentColorIndex = color.ordinal();
return color;
}
}
return null;
}
}
package com.neotel.smfcore.core.order.service.manager; package com.neotel.smfcore.core.order.service.manager;
import com.neotel.smfcore.common.base.IBaseManager; import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.core.barcode.service.po.Barcode; import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.order.service.po.LiteOrder; import com.neotel.smfcore.core.order.service.po.LiteOrder;
public interface ILiteOrderManager extends IBaseManager<LiteOrder> { public interface ILiteOrderManager extends IBaseManager<LiteOrder> {
LiteOrder findByOrderNo(String orderNo); LiteOrder findByOrderNo(String orderNo);
LiteOrder createWithItems(LiteOrder liteOrder) throws ValidateException;
} }
package com.neotel.smfcore.core.order.service.manager.impl; package com.neotel.smfcore.core.order.service.manager.impl;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.exception.ValidateException; import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.core.barcode.service.dao.IBarcodeDao; import com.neotel.smfcore.core.barcode.service.dao.IBarcodeDao;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager; import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
...@@ -9,6 +10,7 @@ import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager; ...@@ -9,6 +10,7 @@ import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager; import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder; import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem; import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
...@@ -33,26 +35,38 @@ public class LiteOrderManagerImpl implements ILiteOrderManager { ...@@ -33,26 +35,38 @@ public class LiteOrderManagerImpl implements ILiteOrderManager {
@Override @Override
public LiteOrder get(String id) { public LiteOrder get(String id) {
return null; return liteOrderDao.findOneById(id);
} }
@Override @Override
public LiteOrder save(LiteOrder object) throws ValidateException { public LiteOrder save(LiteOrder object) throws ValidateException {
return null; return liteOrderDao.save(object);
} }
@Override @Override
public void delete(LiteOrder object) throws ValidateException { public void delete(LiteOrder object) throws ValidateException {
} }
@Override
public LiteOrder createWithItems(LiteOrder liteOrder) throws ValidateException {
List<LiteOrderItem> items = Lists.newArrayList();
for (LiteOrderItem liteOrderItem : liteOrder.getOrderItems()) {
liteOrderItem.setOrderNo(liteOrder.getOrderNo());
liteOrderItem = liteOrderItemManager.save(liteOrderItem);
items.add(liteOrderItem);
}
liteOrder = save(liteOrder);
liteOrder.setOrderItems(items);
return liteOrder;
}
@Override @Override
public List<LiteOrder> findByPage(Query query, Pageable pageable) { public List<LiteOrder> findByPage(Query query, Pageable pageable) {
return null; return liteOrderDao.findByQuery(query,pageable);
} }
@Override @Override
public List<LiteOrder> findByQuery(Query query) { public List<LiteOrder> findByQuery(Query query) {
return null; return liteOrderDao.findByQuery(query);
} }
} }
...@@ -2,6 +2,7 @@ package com.neotel.smfcore.core.order.service.po; ...@@ -2,6 +2,7 @@ package com.neotel.smfcore.core.order.service.po;
import com.neotel.smfcore.common.base.BasePo; import com.neotel.smfcore.common.base.BasePo;
import com.neotel.smfcore.common.utils.StorageConstants; import com.neotel.smfcore.common.utils.StorageConstants;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import lombok.Data; import lombok.Data;
import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
...@@ -38,7 +39,7 @@ public class LiteOrder extends BasePo implements Serializable { ...@@ -38,7 +39,7 @@ public class LiteOrder extends BasePo implements Serializable {
/** /**
* 订单状态 * 订单状态
*/ */
private int status = StorageConstants.LITEORDER_STATUS.NEW; private int status = LITEORDER_STATUS.NEW;
/** /**
* 出库状态, 2表示已完成 * 出库状态, 2表示已完成
...@@ -74,11 +75,11 @@ public class LiteOrder extends BasePo implements Serializable { ...@@ -74,11 +75,11 @@ public class LiteOrder extends BasePo implements Serializable {
*/ */
public void finishedTasks(){ public void finishedTasks(){
if(isOutOne()){ if(isOutOne()){
setStatus(StorageConstants.LITEORDER_STATUS.ONE_FINISHED); setStatus(LITEORDER_STATUS.ONE_FINISHED);
}else if(isOutBom()){ }else if(isOutBom()){
setStatus(StorageConstants.LITEORDER_STATUS.BOM_FINISHED); setStatus(LITEORDER_STATUS.BOM_FINISHED);
}else if(isOutTails()){ }else if(isOutTails()){
setStatus(StorageConstants.LITEORDER_STATUS.TAILS_FINISHED); setStatus(LITEORDER_STATUS.TAILS_FINISHED);
} }
setTaskFinishedTime(System.currentTimeMillis()); setTaskFinishedTime(System.currentTimeMillis());
...@@ -89,18 +90,18 @@ public class LiteOrder extends BasePo implements Serializable { ...@@ -89,18 +90,18 @@ public class LiteOrder extends BasePo implements Serializable {
* @return * @return
*/ */
public boolean isOutBom(){ public boolean isOutBom(){
return status == StorageConstants.LITEORDER_STATUS.BOM; return status == LITEORDER_STATUS.BOM;
} }
/** /**
* 是否是未执行过的工单 * 是否是未执行过的工单
*/ */
public boolean isNew(){ public boolean isNew(){
return status == StorageConstants.LITEORDER_STATUS.NEW; return status == LITEORDER_STATUS.NEW;
} }
public boolean isOutOne(){ public boolean isOutOne(){
return status == StorageConstants.LITEORDER_STATUS.ONE; return status == LITEORDER_STATUS.ONE;
} }
/** /**
...@@ -108,21 +109,21 @@ public class LiteOrder extends BasePo implements Serializable { ...@@ -108,21 +109,21 @@ public class LiteOrder extends BasePo implements Serializable {
* @return * @return
*/ */
public boolean isOutOneFinished(){ public boolean isOutOneFinished(){
return status == StorageConstants.LITEORDER_STATUS.ONE_FINISHED; return status == LITEORDER_STATUS.ONE_FINISHED;
} }
/** /**
* 是否正在出尾料 * 是否正在出尾料
*/ */
public boolean isOutTails(){ public boolean isOutTails(){
return status == StorageConstants.LITEORDER_STATUS.TAILS; return status == LITEORDER_STATUS.TAILS;
} }
/** /**
* 任务料盘是否已出完 * 任务料盘是否已出完
*/ */
public boolean isTaskFinished(){ public boolean isTaskFinished(){
return status == StorageConstants.LITEORDER_STATUS.BOM_FINISHED || status == StorageConstants.LITEORDER_STATUS.TAILS_FINISHED || status == StorageConstants.LITEORDER_STATUS.ONE_FINISHED; return status == LITEORDER_STATUS.BOM_FINISHED || status == LITEORDER_STATUS.TAILS_FINISHED || status == LITEORDER_STATUS.ONE_FINISHED;
} }
......
...@@ -14,6 +14,11 @@ public class LiteOrderItem extends BasePo implements Serializable { ...@@ -14,6 +14,11 @@ public class LiteOrderItem extends BasePo implements Serializable {
//需求数量 //需求数量
private int needNum = 0; private int needNum = 0;
/**
* 需求料盘数
*/
private int needReelCount = 0;
//已出数量 //已出数量
private int outNum = 0; private int outNum = 0;
......
...@@ -3,8 +3,10 @@ package com.neotel.smfcore.core.storage.service.manager; ...@@ -3,8 +3,10 @@ package com.neotel.smfcore.core.storage.service.manager;
import com.neotel.smfcore.common.base.IBaseManager; import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.core.barcode.bean.PlateSizeBean; import com.neotel.smfcore.core.barcode.bean.PlateSizeBean;
import com.neotel.smfcore.core.storage.bean.InventoryItem; import com.neotel.smfcore.core.storage.bean.InventoryItem;
import com.neotel.smfcore.core.storage.enums.CHECKOUT_TYPE;
import com.neotel.smfcore.core.storage.service.po.StoragePos; import com.neotel.smfcore.core.storage.service.po.StoragePos;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -15,4 +17,10 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> { ...@@ -15,4 +17,10 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
Map<String,InventoryItem> getInventory(String id); Map<String,InventoryItem> getInventory(String id);
StoragePos getByBarcode(String barcode); StoragePos getByBarcode(String barcode);
List<StoragePos> findNotEmptyByStorageId(String storageId);
List<StoragePos> findLockPos(String lockId);
StoragePos findPartNumberInStorages(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType);
} }
package com.neotel.smfcore.core.storage.service.manager.impl; package com.neotel.smfcore.core.storage.service.manager.impl;
import com.google.common.base.Strings;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.neotel.smfcore.common.exception.ValidateException; import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.core.barcode.bean.PlateSizeBean; import com.neotel.smfcore.core.barcode.bean.PlateSizeBean;
import com.neotel.smfcore.core.storage.bean.InventoryItem; import com.neotel.smfcore.core.storage.bean.InventoryItem;
import com.neotel.smfcore.core.storage.enums.CHECKOUT_TYPE;
import com.neotel.smfcore.core.storage.service.dao.IStoragePosDao; import com.neotel.smfcore.core.storage.service.dao.IStoragePosDao;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager; import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.StoragePos; import com.neotel.smfcore.core.storage.service.po.StoragePos;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults; import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@Service @Service
@Slf4j
public class StoragePosManagerImpl implements IStoragePosManager { public class StoragePosManagerImpl implements IStoragePosManager {
@Autowired @Autowired
...@@ -173,6 +179,60 @@ public class StoragePosManagerImpl implements IStoragePosManager { ...@@ -173,6 +179,60 @@ public class StoragePosManagerImpl implements IStoragePosManager {
} }
@Override @Override
public List<StoragePos> findNotEmptyByStorageId(String storageId){
Criteria c = Criteria.where("barcode").exists(true)
.and("enabled").is(true);//可用;
if(!Strings.isNullOrEmpty(storageId)){
c = c.and("storageId").is(storageId);
}
Query query = new Query(c);
query.with(Sort.by(Sort.Direction.ASC, "updateDate"));
return storagePosDao.findByQuery(query);
}
@Override
public List<StoragePos> findLockPos(String lockId) {
Criteria c = Criteria.where("barcode.lockId").is(lockId);
return findByQuery(new Query(c));
}
@Override
public StoragePos findPartNumberInStorages(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType) {
Criteria c = Criteria.where("barcode.partNumber").is(pn)
.and("id").nin(excludePosIds)
.and("enabled").is(true)//可用
.and("barcode.lockId").is(null);//没有被锁定的仓位;
if(storageIdList != null){
c = c.and("storageId").in(storageIdList);
}
Query q = new Query(c);
Sort sort = getSortByCheckOutType(checkOutType);
q.with(sort);
log.info("使用"+checkOutType+"策略出库partNumber="+pn);
return storagePosDao.findOne(q);
}
/**
* 根据出库方式获取不同的 Sort
*/
private Sort getSortByCheckOutType(CHECKOUT_TYPE checkoutType){
Sort sort = null;
if(CHECKOUT_TYPE.EXPIRE_FIRST.equals(checkoutType)){//先过期先出
sort = Sort.by(Sort.Direction.ASC, "barcode.expTime","barcode.expireDate","canCheckOutTime");
}else if(CHECKOUT_TYPE.FIFO.equals(checkoutType)){//严格的先进先出
sort = Sort.by(Sort.Direction.ASC, "canCheckOutTime", "barcode.usedCount");
}else if(CHECKOUT_TYPE.USED_FIRST.equals(checkoutType)){//尾料优先
sort = Sort.by(Sort.Direction.ASC, "barcode.amount", "canCheckOutTime");
}else if(CHECKOUT_TYPE.PRODUCE_DATE.equals(checkoutType)){
//先生产先出
sort = Sort.by(Sort.Direction.ASC, "barcode.produceDate", "canCheckOutTime");
}else{//效率优先
sort = Sort.by(Sort.Direction.ASC, "canCheckOutTime", "createDate");
}
return sort;
}
@Override
public List<StoragePos> findByPage(Query query, Pageable pageable) { public List<StoragePos> findByPage(Query query, Pageable pageable) {
return storagePosDao.findByQuery(query,pageable); return storagePosDao.findByQuery(query,pageable);
} }
......
...@@ -56,6 +56,11 @@ public class Storage extends BasePo implements Serializable { ...@@ -56,6 +56,11 @@ public class Storage extends BasePo implements Serializable {
private boolean available = true; private boolean available = true;
/**
* 分组
*/
private String groupId = "";
/** /**
* 是否是上下层的在线料仓 * 是否是上下层的在线料仓
......
...@@ -3,8 +3,11 @@ package com.neotel.smfcore.core.system.service.po; ...@@ -3,8 +3,11 @@ package com.neotel.smfcore.core.system.service.po;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.neotel.smfcore.common.base.BasePo; import com.neotel.smfcore.common.base.BasePo;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.enums.OP; import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.enums.OP_STATUS; import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import lombok.Data; import lombok.Data;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
...@@ -15,6 +18,25 @@ import java.util.List; ...@@ -15,6 +18,25 @@ import java.util.List;
@Document @Document
public class DataLog extends BasePo implements Serializable { public class DataLog extends BasePo implements Serializable {
public DataLog(){
}
public DataLog(Storage storage, Barcode barcode, StoragePos pos) {
if (barcode != null) {
setPartNumber(barcode.getPartNumber());
setBarcode(barcode.getBarcode());
setNum(barcode.getAmount());
setMemo(barcode.getMemo());
}
setCid(storage.getCid());
setStorageId(storage.getId());
setStorageName(storage.getName());
setPosId(pos.getId());
setPosName(pos.getPosName());
}
/** /**
* 是否是单盘出库(联电指出库项目,默认为false即默认批量出库) * 是否是单盘出库(联电指出库项目,默认为false即默认批量出库)
*/ */
......
package com.neotel.smfcore.core.system.util; package com.neotel.smfcore.core.system.util;
import com.google.common.base.Strings;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.neotel.smfcore.common.exception.ValidateException; import com.neotel.smfcore.common.exception.ValidateException;
...@@ -17,10 +18,7 @@ import lombok.extern.slf4j.Slf4j; ...@@ -17,10 +18,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/** /**
* Created by sunke on 2021/7/13. * Created by sunke on 2021/7/13.
...@@ -32,6 +30,7 @@ public class TaskService { ...@@ -32,6 +30,7 @@ public class TaskService {
@Autowired @Autowired
protected IDataLogDao dataLogDao; protected IDataLogDao dataLogDao;
@Autowired
private List<ITaskListener> taskListenerList = new ArrayList<>(); private List<ITaskListener> taskListenerList = new ArrayList<>();
/** /**
...@@ -44,54 +43,55 @@ public class TaskService { ...@@ -44,54 +43,55 @@ public class TaskService {
*/ */
private static Map<String,DataLog> theFinishedTaskMap = Maps.newConcurrentMap(); private static Map<String,DataLog> theFinishedTaskMap = Maps.newConcurrentMap();
public TaskService(List<ITaskListener> listenerList){ // public TaskService(List<ITaskListener> listenerList){
for (ITaskListener taskListener: listenerList) { // for (ITaskListener taskListener: listenerList) {
taskListenerList.add(taskListener); // taskListenerList.add(taskListener);
} // }
// }
private void check(String barcode, String posName) throws ValidateException {
} }
/** /**
* 加入要执行的任务 * 条码入库,加入要执行的任务
*/ */
public synchronized DataLog addPutInTaskToExecute(Storage storage, Barcode barcode, StoragePos storagePos) throws ValidateException { public synchronized DataLog addPutInTaskToExecute(Storage storage, Barcode barcode, StoragePos storagePos) throws ValidateException {
Collection<DataLog> tasks = taskMap.values();
for (DataLog task : tasks) { DataLog task = new DataLog(storage, barcode, storagePos);
//检查 barcode task.setType(OP.PUT_IN);
if (task.getBarcode().equals(barcode.getBarcode())) { task.setStatus(OP_STATUS.EXECUTING.name());
log.info("二维码:[" + barcode.getBarcode() + "]已在操作队列中,操作失败");
throw new ValidateException("error.barcode.inQueue", new String[]{storagePos.getPosName()});
} else if (task.getPosId().equals(storagePos.getId())) {
log.info("位置:[" + storagePos.getPosName() + "]已在操作队列中,操作失败");
throw new ValidateException("error.pos.inQueue", new String[]{storagePos.getPosName()});
}
}
DataLog dataLog = new DataLog();
dataLog.setStorageId(storage.getId());
dataLog.setStorageName(storage.getName());
dataLog.setBarcode(barcode.getBarcode());
dataLog.setMemo(barcode.getMemo());
dataLog.setType(OP.PUT_IN);
dataLog.setNum(barcode.getAmount());
dataLog.setCid(storage.getCid());
//dataLog.setComponentName(barcode.getComponentName());
//TODO:上次出库时间
//dataLog.setLastOperateDate();
//操作人
String loginUser = SecurityUtils.getLoginUsername(); String loginUser = SecurityUtils.getLoginUsername();
dataLog.setOperator(loginUser); task.setOperator(loginUser);
dataLog.setPartNumber(barcode.getPartNumber()); task = updateQueueTask(task);
dataLog.setPosId(storagePos.getId()); log.info("cid:[" + storage.getCid() + "] barcode:[" + barcode.getBarcode() + "] partNumber:[" + task.getPartNumber() + "]位置[" + storagePos.getPosName() + "]的入库操作成功加入队列");
dataLog.setPosName(storagePos.getPosName()); return task;
dataLog.setStatus(OP_STATUS.EXECUTING.name()); }
//dataLog.setSourceType();
/**
dataLogDao.save(dataLog); * 库位出库
taskMap.put(dataLog.getId(), dataLog); * @param storage 料仓
log.info("cid:[" + storage.getCid() + "] barcode:[" + barcode.getBarcode() + "] partNumber:[" + dataLog.getPartNumber() + "]位置[" + storagePos.getPosName() + "]的入库操作成功加入队列"); * @param pos 库位
return dataLog; * @param isSingleOut 是否是单盘出库
* @return
* @throws ValidateException
*/
public synchronized String checkout(Storage storage, StoragePos pos, boolean isSingleOut) throws ValidateException {
if (pos.getBarcode() == null) {
String msg = "库位[" + pos.getPosName() + "]中已无物料,忽略";
log.info(msg);
throw new ValidateException("allBoxView.noReel","库位中无物料");
}
DataLog task = new DataLog(storage, pos.getBarcode(), pos);
task.setType(OP.CHECKOUT);
task.setStatus(OP_STATUS.WAIT.name());
task.setSingleOut(isSingleOut);
addTaskToExecute(task);
return "";
} }
/** /**
...@@ -104,18 +104,43 @@ public class TaskService { ...@@ -104,18 +104,43 @@ public class TaskService {
} }
} }
public void updateQueueTask(DataLog task) { /**
dataLogDao.save(task); * 更新队列中的任务状态
* @param task
*/
public DataLog updateQueueTask(DataLog task) {
task = dataLogDao.save(task);
taskMap.put(task.getId(), task); taskMap.put(task.getId(), task);
tiggerTaskChangeListener(task); tiggerTaskChangeListener(task);
return task;
} }
/**
* 更新完成列表中的任务状态
* @param task
*/
public void updateFinishedTask(DataLog task){ public void updateFinishedTask(DataLog task){
dataLogDao.save(task); dataLogDao.save(task);
theFinishedTaskMap.put(task.getId(), task); theFinishedTaskMap.put(task.getId(), task);
tiggerTaskChangeListener(task); tiggerTaskChangeListener(task);
} }
public void addTaskToExecute(DataLog taskToExecute) throws ValidateException {
Collection<DataLog> tasks = taskMap.values();
for (DataLog task : tasks) {
String barcode = taskToExecute.getBarcode();
String posName = taskToExecute.getPosName();
if (!Strings.isNullOrEmpty(barcode) && task.getBarcode().equals(barcode)) {
log.info("二维码:[" + barcode + "]已在操作队列中,操作失败");
throw new ValidateException("error.barcode.inQueue", new String[]{barcode});
} else if (task.getPosName().equals(posName)) {
log.info("位置:[" + posName + "]已在操作队列中,操作失败");
throw new ValidateException("error.pos.inQueue", new String[]{posName});
}
}
updateQueueTask(taskToExecute);
}
/** /**
* 获取所有任务队列中的任务(等待中和执行中) * 获取所有任务队列中的任务(等待中和执行中)
*/ */
......
package com.neotel.smfcore.hella.rest;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.util.DataCache;
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.hella.handler.HellaServiceHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;
/**
* 扫码料架
*/
@Controller
@Slf4j
public class HellaSensorShelfController {
@Autowired
private DataCache dataCache;
@Autowired
private HellaServiceHandler hellaServiceHandler;
@Autowired
private TaskService taskService;
@Autowired
protected IStoragePosManager storagePosManager;
@Autowired
protected IBarcodeManager barcodeManager;
}
package com.neotel.smfcore.hella.tcp;
import com.google.common.base.Strings;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.system.service.po.Settings;
import com.neotel.smfcore.hella.handler.HellaServiceHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.mina.core.filterchain.IoFilterAdapter;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.MdcInjectionFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
/**
* Created by sunke on 2019/4/17.
*/
@Slf4j
@Service
public class HellaTcpClient {
private static NioSocketConnector connector;
private static String host = "";
private static int port = 9999;
@Value("${hella.host:}")
public void setHost(String host) {
HellaTcpClient.host = host;
}
@Value("${hella.port:9999}")
public void setPort(int port) {
HellaTcpClient.port = port;
}
@Autowired
private HellaServiceHandler hellaServiceHandler;
private static IoSession theSession;
@PostConstruct
public void init(){
updateServerInfo(host, port);
start();
}
public static void updateServerInfo(String serverHost, int serverPort){
host = serverHost;
port = serverPort;
log.info("设置Tcp连接信息为["+host+":"+port+"]");
if(connector != null){
connector.dispose();
}
//connectThreadStart();
}
public void start(){
connector = new NioSocketConnector(); //创建连接客户端
connector.setConnectTimeoutMillis(30000); //设置连接超时
//断线重连回调拦截器
connector.getFilterChain().addFirst("reconnection", new IoFilterAdapter() {
@Override
public void sessionClosed(NextFilter nextFilter, IoSession ioSession) throws Exception {
log.info("执行断线重连");
connectThreadStart();
}
});
connector.getFilterChain().addLast("mdc", new MdcInjectionFilter());
TextLineCodecFactory factory = new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.CRLF,LineDelimiter.CRLF);
// factory.setDecoderMaxLineLength(10240);
// factory.setEncoderMaxLineLength(10240);
//加入解码器
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(factory));
connector.getSessionConfig().setReceiveBufferSize(10240); // 设置接收缓冲区的大小
connector.getSessionConfig().setSendBufferSize(10240);// 设置输出缓冲区的大小
connector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30000); //读写都空闲时间:30秒
connector.getSessionConfig().setIdleTime(IdleStatus.READER_IDLE, 40000);//读(接收通道)空闲时间:40秒
connector.getSessionConfig().setIdleTime(IdleStatus.WRITER_IDLE, 50000);//写(发送通道)空闲时间:50秒
//添加处理器
connector.setHandler(hellaServiceHandler);
log.info("开始连接");
connectThreadStart();
}
// 停止MINA服务
@PreDestroy
public void stop() {
try {
log.info("stopping the TCP Client");
connector.dispose();
} catch (Exception e) {
log.error("TCP Server stop error:",e);
}
}
private static boolean isConnectThreadRunning = false;
public static void connectThreadStart(){
if(isConnectThreadRunning){
return;
}
isConnectThreadRunning = true;
new Thread(new Runnable() {
public void run() {
for (;;) {
try {
Thread.sleep(5000);// 连接失败后,重连
if(!Strings.isNullOrEmpty(host)){
connector.setDefaultRemoteAddress(new InetSocketAddress(host, port));// 设置默认访问地址
ConnectFuture future = connector.connect();
// 等待连接创建成功
future.awaitUninterruptibly();
// 获取会话
IoSession ioSession = future.getSession();
if(ioSession.isConnected()){
theSession = ioSession;
log.info("连接["+ connector.getDefaultRemoteAddress().getHostName() +":"+ connector.getDefaultRemoteAddress().getPort()+"]成功");
break;
}else{
theSession = null;
}
}
} catch (Exception e) {
log.error("连接服务端" + host + ":" + port + "失败" + ",异常内容:" + e.getMessage(), e);
}
}
isConnectThreadRunning = false;
}
}).start();
}
public static ResultBean sendMsg(String msg){
if(theSession != null && theSession.isConnected()){
log.info("发送消息到Tcp Server:" + msg);
theSession.write("\02"+msg);
return ResultBean.newOkResult("");
}else{
return ResultBean.newErrorResult(-1,"no connecttion");
}
}
}
package com.neotel.smfcore.hella.tcp.command;
import java.util.Date;
/**
* Created by sunke on 2021/5/26.
*/
public class HellaCommand {
private String cmd;
private String eventId;
private Object data;
private Date date = new Date();
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public String getEventId() {
return eventId;
}
public void setEventId(String eventId) {
this.eventId = eventId;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String toReqMsg(){
return getCmd() + ";" + getEventId() + ";" + getData().toString();
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
package com.neotel.smfcore.hella.tcp.command;
/**
* Created by sunke on 2021/5/26.
*/
public class HellaReqCommand extends HellaCommand {
/**
* 来源
*/
private String groupId;
/**
* 料仓Id;
*/
private String loginUser;
/**
* 检查物料条码
* <STX>checkMaterial;eventId;scannedCode<CR><LF>
* @param eventId
* @param scannedCode
* @return
*/
public static HellaReqCommand newCheckMaterialCmd(long eventId, String scannedCode){
HellaReqCommand command = new HellaReqCommand();
command.setCmd("checkMaterial");
command.setEventId(eventId + "");
command.setData(scannedCode);
return command;
}
public boolean isCheckMaterialReq(){
return getCmd().equalsIgnoreCase("checkMaterial");
}
/**
* 入库完成通知
* <STX>loadMaterial;eventId;scannedCode;shelfNumber;shelfSlot<CR><LF>
* @param eventId
* @param scannedCode
* @return
*/
public static HellaReqCommand newLoadMaterialCmd(long eventId, String scannedCode,String shelfNumber, String shelfSlot){
HellaReqCommand command = new HellaReqCommand();
command.setCmd("loadMaterial");
command.setEventId(eventId + "");
String dataStr = scannedCode + ";" + shelfNumber+";" + shelfSlot;
command.setData(dataStr);
return command;
}
public String getLoginUser() {
return loginUser;
}
public void setLoginUser(String loginUser) {
this.loginUser = loginUser;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
}
package com.neotel.smfcore.hella.tcp.command;
/**
* Created by sunke on 2021/5/26.
*/
public class HellaRespCommand extends HellaCommand {
private String returnCode;
private String messageText;
public String getMessageText() {
return messageText;
}
public void setMessageText(String messageText) {
this.messageText = messageText;
}
public String getReturnCode() {
return returnCode;
}
public void setReturnCode(String returnCode) {
this.returnCode = returnCode;
}
public boolean isOkResp(){
return returnCode.equals("0");
}
public boolean isCheckMaterialResp(){
return getCmd().equalsIgnoreCase("checkMaterial");
}
public boolean isLoadMaterialResp(){
return getCmd().equalsIgnoreCase("loadMaterial");
}
public boolean isUnloadMaterialCmd(){
return getCmd().equalsIgnoreCase("unloadMaterial");
}
//<STX>orderMaterialExt;eventId;lineNumber;workorderNumber;currentWorkorderflag;reflowgroupNumber;numberofPartnumbers;partNumber1;numberofReels;…;partNumberN;numberofReels<CR><LF>
public boolean isOrderMaterialExtCmd(){
return getCmd().equalsIgnoreCase("orderMaterialExt");
}
//<STX>getInventory;eventId;shelfNumber<CR><LF>
public boolean isGetInventoryCmd(){
return getCmd().equalsIgnoreCase("getInventory");
}
}
...@@ -4,5 +4,4 @@ import com.neotel.smfcore.common.base.IBaseManager; ...@@ -4,5 +4,4 @@ import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.security.service.po.Group; import com.neotel.smfcore.security.service.po.Group;
public interface IGroupManager extends IBaseManager<Group> { public interface IGroupManager extends IBaseManager<Group> {
Group findOneByGroupName(String groupName);
} }
...@@ -16,6 +16,11 @@ public class GroupManagerImpl implements IGroupManager { ...@@ -16,6 +16,11 @@ public class GroupManagerImpl implements IGroupManager {
IGroupDao groupDao; IGroupDao groupDao;
@Override @Override
public Group getByGroupName(String groupName){
return groupDao.findOneByCondition(new String[]{"groupName"}, new String[]{groupName});
}
@Override
public Group get(String id) { public Group get(String id) {
return groupDao.findOneById(id); return groupDao.findOneById(id);
} }
......
server: server:
port: 8800 port: 8800
hella:
host: 192.168.1.3
port: 9900
spring: spring:
freemarker: freemarker:
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!