Commit b4db2d79 zshaohui

1.mes面别为空,不接收

2.看板缺料预警信息,增加缓存
3.kafka黑灯工厂提交
4.缺料预警生成工单优化
5.工单出库,去掉可执行最大工单数
1 个父辈 c4820231
...@@ -483,11 +483,11 @@ public class LiteOrderCache { ...@@ -483,11 +483,11 @@ public class LiteOrderCache {
return "smfcore.order.hasClose"; return "smfcore.order.hasClose";
} }
ORDER_COLOR nextColor = getNextColor(); /*ORDER_COLOR nextColor = getNextColor();
if (nextColor == null) { if (nextColor == null) {
log.info("执行工单[" + orderNo + "] outBom=" + outBom + "时,已达最大可执行工单数"); log.info("执行工单[" + orderNo + "] outBom=" + outBom + "时,已达最大可执行工单数");
return "smfcore.order.out.maxOrder"; return "smfcore.order.out.maxOrder";
} }*/
//先查找是否已经锁定过库位,如果已经锁定过,出锁定的库位 //先查找是否已经锁定过库位,如果已经锁定过,出锁定的库位
List<StoragePos> lockPosList = storagePosManager.findLockPos(cacheOrder.getOrderNo()); List<StoragePos> lockPosList = storagePosManager.findLockPos(cacheOrder.getOrderNo());
...@@ -617,7 +617,7 @@ public class LiteOrderCache { ...@@ -617,7 +617,7 @@ public class LiteOrderCache {
task.setType(OP.CHECKOUT); task.setType(OP.CHECKOUT);
Storage storage = dataCache.getStorageById(pos.getStorageId()); Storage storage = dataCache.getStorageById(pos.getStorageId());
task.setExtendType(ExtendType.ORDER_CHECKOUT); //工单出库 task.setExtendType(ExtendType.ORDER_CHECKOUT); //工单出库
task.setLightColor(nextColor.getRgb()); //task.setLightColor(nextColor.getRgb());
task.setStatus(OP_STATUS.WAIT.name()); task.setStatus(OP_STATUS.WAIT.name());
task.setPartNumber(pos.getBarcode().getPartNumber()); //料号 task.setPartNumber(pos.getBarcode().getPartNumber()); //料号
task.setLine(orderItem.getLine()); //线别 task.setLine(orderItem.getLine()); //线别
......
...@@ -826,8 +826,8 @@ public class StoragePosManagerImpl implements IStoragePosManager { ...@@ -826,8 +826,8 @@ public class StoragePosManagerImpl implements IStoragePosManager {
public List<StoragePos> findPartNumberListInStorages(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType, String brand) { public List<StoragePos> findPartNumberListInStorages(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType, String brand) {
Criteria c = Criteria.where("barcode.partNumber").is(pn) Criteria c = Criteria.where("barcode.partNumber").is(pn)
.and("id").nin(excludePosIds) .and("id").nin(excludePosIds)
.and("enabled").is(true)//可用 .and("enabled").is(true);//可用
.and("barcode.lockId").is(null);//没有被锁定的仓位; //.and("barcode.lockId").is(null);//没有被锁定的仓位;
if (storageIdList != null) { if (storageIdList != null) {
c = c.and("storageId").in(storageIdList); c = c.and("storageId").in(storageIdList);
} }
......
...@@ -235,6 +235,12 @@ public class LizhenController { ...@@ -235,6 +235,12 @@ public class LizhenController {
item.setPriority(Integer.valueOf(data.get("PRIORITY"))); item.setPriority(Integer.valueOf(data.get("PRIORITY")));
item.setReel(data.get("REEL")); item.setReel(data.get("REEL"));
item.setBrand(data.get("VENDOR")); item.setBrand(data.get("VENDOR"));
if (StringUtils.isBlank(item.getSide())){
log.info("缺料预警id:"+item.getItemId()+"面别为空,忽略");
return ResultBean.newErrorResult(-1,"","side为空");
}
PreWarningItemCache.addItems(Arrays.asList(item)); PreWarningItemCache.addItems(Arrays.asList(item));
return ResultBean.newOkResult(""); return ResultBean.newOkResult("");
} }
......
...@@ -94,33 +94,39 @@ public class PreWarningItemCache { ...@@ -94,33 +94,39 @@ public class PreWarningItemCache {
log.info("开始生成迈征的工单信息,line为:"+line+",side为:"+side+",trackNumber为:"+trackNumber); log.info("开始生成迈征的工单信息,line为:"+line+",side为:"+side+",trackNumber为:"+trackNumber);
for (PreWarningItem item : queueItemList) { try {
//判断产线,面别, List<PreWarningItem> itemList = new ArrayList<>(queueItemList);
if (StringUtils.isNotBlank(line) for (PreWarningItem item : itemList) {
&& StringUtils.isNotBlank(side) //判断产线,面别,
&& StringUtils.isNotBlank(trackNumber) if (StringUtils.isNotBlank(line)
) { && StringUtils.isNotBlank(side)
if (line.equals(item.getLine()) && side.equals(item.getSide()) && StringUtils.isNotBlank(trackNumber)
&& StringUtils.isNotBlank(item.getStation()) && item.getStation().endsWith(trackNumber)) { ) {
//再判断料号是否相同 if (line.equals(item.getLine()) && side.equals(item.getSide())
for (StationStatus status : stationStatusList) { && StringUtils.isNotBlank(item.getStation()) && item.getStation().endsWith(trackNumber)) {
String station = status.getSTATION(); //再判断料号是否相同
String slot = status.getSLOT(); for (StationStatus status : stationStatusList) {
String partnumber = status.getPARTNUMBER(); String station = status.getSTATION();
if (StringUtils.isNotBlank(partnumber) && StringUtils.isNotBlank(slot) && StringUtils.isNotBlank(station)) { String slot = status.getSLOT();
if (station.equals(item.getStation()) String partnumber = status.getPARTNUMBER();
&& slot.equals(item.getSlot()) if (StringUtils.isNotBlank(partnumber) && StringUtils.isNotBlank(slot) && StringUtils.isNotBlank(station)) {
&& partnumber.equals(item.getPartnumber()) if (station.equals(item.getStation())
&& line.equals(status.getLINE()) && slot.equals(item.getSlot())
&& side.equals(status.getSIDE()) && partnumber.equals(item.getPartnumber())
) { && line.equals(status.getLINE())
log.info("开始添加迈征的工单明细,station为:"+station+",slot为:"+slot+",partnumber为:"+partnumber); && side.equals(status.getSIDE())
lineItems.add(item); ) {
log.info("开始添加迈征的工单明细,station为:"+station+",slot为:"+slot+",partnumber为:"+partnumber);
lineItems.add(item);
}
} }
} }
} }
} }
} }
} catch (Exception e) {
e.printStackTrace();
log.error("生成迈征工单报错:"+e.getMessage());
} }
} }
if (lineItems != null && !lineItems.isEmpty()) { if (lineItems != null && !lineItems.isEmpty()) {
...@@ -130,7 +136,7 @@ public class PreWarningItemCache { ...@@ -130,7 +136,7 @@ public class PreWarningItemCache {
} }
log.info("开始生成其他工单");
Integer preGenerateTaskTimes = dataCache.getCache(Constants.CACHE_preGenerateTask_Times); Integer preGenerateTaskTimes = dataCache.getCache(Constants.CACHE_preGenerateTask_Times);
if (preGenerateTaskTimes == null || preGenerateTaskTimes == 0) { if (preGenerateTaskTimes == null || preGenerateTaskTimes == 0) {
preGenerateTaskTimes = 2; preGenerateTaskTimes = 2;
...@@ -141,7 +147,8 @@ public class PreWarningItemCache { ...@@ -141,7 +147,8 @@ public class PreWarningItemCache {
List<PreWarningItem> lineItems = new ArrayList<>(); List<PreWarningItem> lineItems = new ArrayList<>();
String firstItemLine = ""; String firstItemLine = "";
if (queueItemList != null && !queueItemList.isEmpty()) { if (queueItemList != null && !queueItemList.isEmpty()) {
for (PreWarningItem preWarningItem : queueItemList) { List<PreWarningItem> itemList = new ArrayList<>(queueItemList);
for (PreWarningItem preWarningItem : itemList) {
String itemLine = preWarningItem.getLine(); String itemLine = preWarningItem.getLine();
if (Strings.isNotBlank(itemLine)) { if (Strings.isNotBlank(itemLine)) {
if (firstItemLine.isEmpty()) { if (firstItemLine.isEmpty()) {
...@@ -152,13 +159,14 @@ public class PreWarningItemCache { ...@@ -152,13 +159,14 @@ public class PreWarningItemCache {
} }
//同一个线别的生成一个工单 //同一个线别的生成一个工单
if (itemLine.equals(firstItemLine)) { if (itemLine.equals(firstItemLine)) {
log.info("添加明细数据,id为:" + preWarningItem.getItemId());
lineItems.add(preWarningItem); lineItems.add(preWarningItem);
} }
} }
} }
} }
if (!lineItems.isEmpty()) { if (!lineItems.isEmpty()) {
createAndExecuteLiteOrder(lineItems, priority,false); createAndExecuteLiteOrder(lineItems, priority, false);
} }
} }
} }
......
package com.neotel.smfcore.custom.lizhen.kafka.bean; package com.neotel.smfcore.custom.lizhen.kafka.bean;
import com.alibaba.fastjson.annotation.JSONField;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
...@@ -9,26 +10,32 @@ import java.util.Date; ...@@ -9,26 +10,32 @@ import java.util.Date;
@Data @Data
public class MachineStatus { public class MachineStatus {
@ApiModelProperty("发生时间") @ApiModelProperty("发生时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS") @JSONField(name = "OccurrenceTime")
private Date OccurrenceTime; private String OccurrenceTime;
@ApiModelProperty("消息类别") @ApiModelProperty("消息类别")
@JSONField(name = "TopicType")
private String TopicType; private String TopicType;
@ApiModelProperty("机台唯一ID") @ApiModelProperty("机台唯一ID")
@JSONField(name = "MachineID")
private String MachineID; private String MachineID;
@ApiModelProperty("当前状态") @ApiModelProperty("当前状态")
//1:运行;2:等待;3:故障; //1:运行;2:等待;3:故障;
//4:未生产;5:离线;… //4:未生产;5:离线;…
@JSONField(name = "CurrentStatus")
private String CurrentStatus; private String CurrentStatus;
@ApiModelProperty("错误代码") @ApiModelProperty("错误代码")
@JSONField(name = "ErrorCode")
private String ErrorCode; private String ErrorCode;
@ApiModelProperty("错误描述") @ApiModelProperty("错误描述")
@JSONField(name = "ErrorMsg")
private String ErrorMsg; private String ErrorMsg;
@ApiModelProperty("客户端 IP") @ApiModelProperty("客户端 IP")
@JSONField(name = "ClientIP")
private String ClientIP; private String ClientIP;
} }
...@@ -2,13 +2,18 @@ package com.neotel.smfcore.custom.lizhen.kafka.service; ...@@ -2,13 +2,18 @@ package com.neotel.smfcore.custom.lizhen.kafka.service;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.neotel.smfcore.common.utils.JsonUtil; import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.device.bean.StatusBean; import com.neotel.smfcore.core.device.bean.StatusBean;
import com.neotel.smfcore.core.device.enums.BOX_STATUS;
import com.neotel.smfcore.core.device.util.DataCache; import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.storage.service.po.Storage; import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.system.util.DevicesStatusUtil; import com.neotel.smfcore.core.system.util.DevicesStatusUtil;
import com.neotel.smfcore.custom.lizhen.kafka.bean.Heartbeat; import com.neotel.smfcore.custom.lizhen.kafka.bean.Heartbeat;
import com.neotel.smfcore.custom.lizhen.kafka.bean.MachineStatus;
import com.neotel.smfcore.custom.lizhen.kafka.config.KafkaConfig; import com.neotel.smfcore.custom.lizhen.kafka.config.KafkaConfig;
import io.jsonwebtoken.impl.crypto.MacProvider;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.protocol.Message; import org.apache.kafka.common.protocol.Message;
...@@ -20,9 +25,9 @@ import org.springframework.stereotype.Component; ...@@ -20,9 +25,9 @@ import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFuture;
import java.util.Collection; import java.util.*;
import java.util.Date;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
//@Async //@Async
@Service @Service
...@@ -36,16 +41,72 @@ public class KafkaService { ...@@ -36,16 +41,72 @@ public class KafkaService {
private KafkaTemplate kafkaTemplate; private KafkaTemplate kafkaTemplate;
Map<String,String> statusMap = Maps.newConcurrentMap();
/** /**
* 设备状态发送 * 设备状态发送
*/ */
//@Scheduled(fixedRate = 1000 * 5) @Scheduled(fixedRate = 1000 * 60 * 1)
public void setMachineStatus() { public void setMachineStatus() {
Collection<Storage> storages = dataCache.getAllStorage().values(); Collection<Storage> storages = dataCache.getAllStorage().values();
for (Storage storage : storages) { List<String> machineIdList = getMachineIdList();
String cid = storage.getCid(); for (String machineId : machineIdList) {
StatusBean statusBean = DevicesStatusUtil.getStatusBean(cid);
//是否离线
boolean offline = false;
//故障
boolean fault = false;
for (Storage storage : storages) {
if (machineId.equals(storage.getMachineId())) {
StatusBean statusBean = DevicesStatusUtil.getStatusBean(storage.getCid());
if (statusBean == null) {
offline = true;
} else {
if (statusBean.timeOut()) {
offline = true;
} else {
int status = statusBean.getStatus();
if (status == BOX_STATUS.EMERGENCY || status == BOX_STATUS.PROBLEM) {
fault = true;
}
}
}
}
}
String currentStatus = "1";
if (fault) {
currentStatus = "3";
}
if (offline) {
currentStatus = "5";
}
//判断状态与上一次是否一致
String lastStatus = statusMap.get(machineId);
if (StringUtils.isNotBlank(lastStatus) && lastStatus.equals(currentStatus)) {
log.info(machineId + "与上一次通知状态相同,跳过" + currentStatus);
continue;
}
MachineStatus status = new MachineStatus();
String dateStr = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
status.setOccurrenceTime(dateStr);
status.setMachineID(machineId);
status.setTopicType(KafkaConfig.MACHINESTATUS_TOPIC);
status.setCurrentStatus(currentStatus);
status.setErrorCode("");
status.setErrorMsg("");
status.setClientIP("");
String statusStr = JSON.toJSONString(status);
log.info("主题为:" + KafkaConfig.MACHINESTATUS_TOPIC + "内容为:" + statusStr);
ListenableFuture future = kafkaTemplate.send(KafkaConfig.MACHINESTATUS_TOPIC, statusStr);
log.info("返回结果为:" + JSON.toJSONString(future));
statusMap.put(machineId,currentStatus);
} }
} }
...@@ -53,18 +114,38 @@ public class KafkaService { ...@@ -53,18 +114,38 @@ public class KafkaService {
/** /**
* 心跳数据发送 * 心跳数据发送
*/ */
//@Scheduled(fixedRate = 1000 * 60 * 5) @Scheduled(fixedRate = 1000 * 60 * 5)
//@Scheduled(fixedRate = 1000 * 5)
public void setHeartbeat() { public void setHeartbeat() {
//根据machineId,找到设备状态,是否正常
Collection<Storage> storages = dataCache.getAllStorage().values(); Collection<Storage> storages = dataCache.getAllStorage().values();
for (Storage storage : storages) { List<String> machineIdList = getMachineIdList();
String cid = storage.getCid(); for (String machineId : machineIdList) {
StatusBean statusBean = DevicesStatusUtil.getStatusBean(cid); boolean normal = true;
if (statusBean != null) { for (Storage storage : storages) {
if (machineId.equals(storage.getMachineId())) {
StatusBean statusBean = DevicesStatusUtil.getStatusBean(storage.getCid());
if (statusBean == null) {
normal = false;
} else {
if (statusBean.timeOut()) {
normal = false;
} else {
int status = statusBean.getStatus();
if (status == BOX_STATUS.EMERGENCY || status == BOX_STATUS.PROBLEM) {
normal = false;
}
}
}
}
}
//如果设备状态正常,发送kafka信息
if (normal) {
Heartbeat heartbeat = new Heartbeat(); Heartbeat heartbeat = new Heartbeat();
String dateStr = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss.SSS"); String dateStr = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
heartbeat.setOccurrenceTime(dateStr); heartbeat.setOccurrenceTime(dateStr);
heartbeat.setMachineID(cid); heartbeat.setMachineID(machineId);
heartbeat.setTopicType(KafkaConfig.HEARTBEAT_TOPIC); heartbeat.setTopicType(KafkaConfig.HEARTBEAT_TOPIC);
String heartbeatStr = JSON.toJSONString(heartbeat); String heartbeatStr = JSON.toJSONString(heartbeat);
log.info("主题为:" + KafkaConfig.HEARTBEAT_TOPIC + "内容为:" + heartbeatStr); log.info("主题为:" + KafkaConfig.HEARTBEAT_TOPIC + "内容为:" + heartbeatStr);
...@@ -74,4 +155,17 @@ public class KafkaService { ...@@ -74,4 +155,17 @@ public class KafkaService {
} }
} }
public List<String> getMachineIdList() {
//找出所有的machineId
List<String> machineIdList = new ArrayList<>();
Collection<Storage> storages = dataCache.getAllStorage().values();
for (Storage storage : storages) {
if (StringUtils.isNotBlank(storage.getMachineId())) {
machineIdList.add(storage.getMachineId());
}
}
machineIdList = machineIdList.stream().distinct().collect(Collectors.toList());
return machineIdList;
}
} }
...@@ -51,7 +51,9 @@ public class BcKanbanController { ...@@ -51,7 +51,9 @@ public class BcKanbanController {
/*@Value("${disable.export}") /*@Value("${disable.export}")
private String disableExport;*/ private String disableExport;*/
public static final Map<String, Long> expireMap = Maps.newConcurrentMap(); private static Map<String, Long> expireMap = Maps.newConcurrentMap();
private static Map<String,LackPickingDto> pickingDtoMap = Maps.newConcurrentMap();
/** /**
* 获取近7天出入库统计 * 获取近7天出入库统计
...@@ -133,15 +135,23 @@ public class BcKanbanController { ...@@ -133,15 +135,23 @@ public class BcKanbanController {
List<String> lineList = KanbanUtils.getLineByFloor("4F"); List<String> lineList = KanbanUtils.getLineByFloor("4F");
List<LackPickingDto> resultList = new ArrayList<>(); List<LackPickingDto> resultList = new ArrayList<>();
for (String line : lineList) { for (String line : lineList) {
LackPickingDto dto = new LackPickingDto(); LackPickingDto lackPickingDto = pickingDtoMap.get(line);
dto.setLine(line); if (lackPickingDto != null && System.currentTimeMillis() - lackPickingDto.getLastTime() < 1000 * 60 * 5){
//统计缺料数量 resultList.add(lackPickingDto);
dto.setTotalNeedCount(getLackPickingCount(0, line)); } else {
//统计已发数量 LackPickingDto dto = new LackPickingDto();
dto.setTotalOutCount(getLackPickingCount(-1, line)); dto.setLine(line);
//待出数量 //统计缺料数量
dto.setReadyOutCount(dto.getTotalNeedCount() - dto.getTotalOutCount()); dto.setTotalNeedCount(getLackPickingCount(0, line));
resultList.add(dto); //统计已发数量
dto.setTotalOutCount(getLackPickingCount(-1, line));
//待出数量
dto.setReadyOutCount(dto.getTotalNeedCount() - dto.getTotalOutCount());
//上一次查询时间
dto.setLastTime(System.currentTimeMillis());
pickingDtoMap.put(line, dto);
resultList.add(dto);
}
} }
return ResultBean.newOkResult(resultList); return ResultBean.newOkResult(resultList);
} }
......
...@@ -26,4 +26,9 @@ public class LackPickingDto { ...@@ -26,4 +26,9 @@ public class LackPickingDto {
* 待出数量 * 待出数量
*/ */
private int readyOutCount; private int readyOutCount;
/**
* 上一次保存时间
*/
private Long lastTime;
} }
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!