Commit 102bc5b0 zshaohui

1.增加虚拟仓功能

2.nexim增加用户名和密码配置
1 个父辈 47f1f5dd
正在显示 32 个修改的文件 包含 251 行增加35 行删除
......@@ -6,4 +6,6 @@ public class BARCODE_SOURCE {
//虚拟仓
public static final String VIRTUAL = "virtual";
public static final String ALL = "ALL";
}
......@@ -208,8 +208,8 @@ public class BarcodeDto implements Serializable {
private Date openTime;
@ApiModelProperty("描述")
private String describe;
//@ApiModelProperty("描述")
//private String describe;
@ApiModelProperty("器件厚度")
private String thickness="";
......
......@@ -217,7 +217,7 @@ public class Barcode extends BasePo implements Serializable {
/**
* 描述
*/
private String describe;
//private String describe;
/**
* 厚度
* 请选择
......@@ -237,6 +237,11 @@ public class Barcode extends BasePo implements Serializable {
private Map<String,Object> appendData = new HashMap<>();
/**
* 是否自动创建
*/
private boolean autoCreate = false;
/**
* 添加或更新自定义附加信息
* @param appendKey
* @param appendValue
......@@ -493,6 +498,32 @@ public class Barcode extends BasePo implements Serializable {
return null;
}
public Barcode getSubCodeByMpn(String mpn) {
if (subCodeList == null) {
return null;
}
for (Barcode barcode : subCodeList
) {
if (mpn.equals(barcode.getMpn())) {
return barcode;
}
}
return null;
}
public Barcode getSubCodeByBarcodeId(String id) {
if (subCodeList == null) {
return null;
}
for (Barcode barcode : subCodeList
) {
if (barcode.getId().equals(id)) {
return barcode;
}
}
return null;
}
public void UpdateSubCode(Barcode barcode) {
if (subCodeList == null) {
......
......@@ -5,6 +5,8 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
......@@ -51,4 +53,9 @@ public class MsgInfo implements Serializable {
* 模块
*/
private String moudle="";
/**
* 当前收到时间
*/
private long lastReceiveTime = System.currentTimeMillis();
}
......@@ -771,7 +771,7 @@ public class StatusBean {
}
if (msgArray.length == 1) {
msgList.add(new MsgInfo(msg, msgType, msgEn, msgJp, msgCode, msgParam, "", "",""));
msgList.add(new MsgInfo(msg, msgType, msgEn, msgJp, msgCode, msgParam, "", "","",System.currentTimeMillis()));
} else {
msgList.add(new MsgInfo(msg, msgType));
}
......
......@@ -123,7 +123,7 @@ public class XLCBoxHandler extends BaseDeviceHandler {
dto.setBarcode(barcode.getBarcode());
dto.setPartNumber(barcode.getPartNumber());
dto.setId(barcode.getId());
dto.setDescribe(barcode.getDescribe());
dto.setMemo(barcode.getMemo());
return dto;
}
......
......@@ -22,7 +22,7 @@ public class XLCPosBarcodeDto implements Serializable {
private int amount;
@ApiModelProperty("描述")
private String describe;
private String memo;
/**
* 料箱中的物料信息
*/
......
......@@ -476,7 +476,7 @@ public class DataCache {
/**
* 入库时增加使用库位列表
*/
private void addUsedPosList(String cid, StoragePos pos) {
public void addUsedPosList(String cid, StoragePos pos) {
Map<String,StoragePos> usedPosList = getUsedPosList(cid);
usedPosList.put(pos.getPosName(),pos);
usedPosMap.put(cid, usedPosList);
......
......@@ -322,25 +322,24 @@ public class OrderController {
for (Map<String,StoragePos> list :
allPosLists) {
for (StoragePos pos : list.values()) {
boolean isItemPos = false;
if (ObjectUtil.isNotEmpty(item.getRi())) {
if (pos.getBarcode().getBarcode().equals(item.getRi())) {
isItemPos = true;
boolean isItemPos = isItemPos(item, pos.getBarcode());
if (isItemPos) {
inventoryReelCount += 1;
inventoryQty += pos.getBarcode().getAmount();
} else {
Barcode barcode = pos.getBarcode();
if (barcode != null){
List<Barcode> subCodeList = barcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()){
for (Barcode subCode : subCodeList) {
boolean isItemBox = isItemPos(item,subCode);
if (isItemBox){
inventoryReelCount += 1;
inventoryQty += subCode.getAmount();
}
} else if (ObjectUtil.isNotEmpty(item.getPn())) {
if (ObjectUtil.isNotEmpty(pos.getBarcode().getPartNumber()) && pos.getBarcode().getPartNumber().startsWith(item.getPn())) {
isItemPos = true;
}
} else if (ObjectUtil.isNotEmpty(item.getMpn())) {
if (ObjectUtil.isNotEmpty(pos.getBarcode().getMpn()) && pos.getBarcode().getMpn().equals(item.getMpn())) {
isItemPos = true;
}
}
if (isItemPos) {
inventoryReelCount += 1;
inventoryQty += pos.getBarcode().getAmount();
}
}
}
......@@ -798,4 +797,22 @@ public class OrderController {
List<String> allLineList = liteOrderManager.findAllLines();
return allLineList;
}
private boolean isItemPos(LiteOrderItem item, Barcode barcode) {
boolean isItemPos = false;
if (ObjectUtil.isNotEmpty(item.getRi())) {
if (barcode.getBarcode().equals(item.getRi())) {
isItemPos = true;
}
} else if (ObjectUtil.isNotEmpty(item.getPn())) {
if (ObjectUtil.isNotEmpty(barcode.getPartNumber()) && barcode.getPartNumber().startsWith(item.getPn())) {
isItemPos = true;
}
} else if (ObjectUtil.isNotEmpty(item.getMpn())) {
if (ObjectUtil.isNotEmpty(barcode.getMpn()) && barcode.getMpn().equals(item.getMpn())) {
isItemPos = true;
}
}
return isItemPos;
}
}
......@@ -109,7 +109,7 @@ public class MaterialBoxController {
if(describe==null){
throw new ValidateException("smfcore.valueCanotNull","{0}不能为空",new String[]{"describe"} );
}
barcode.setDescribe(describe);
barcode.setMemo(describe);
barcodeManager.saveBarcode(barcode);
log.info("更改料盒[" + code + "]的描述信息为:" + describe);
return ResultBean.newOkResult("");
......@@ -544,7 +544,7 @@ public class MaterialBoxController {
* @param opQty 数量
* @throws ValidateException
*/
private void finishTask(Barcode pidBarcode, int opType, DataLog currentTask, Barcode subBarcode, int opQty) throws ValidateException {
private synchronized void finishTask(Barcode pidBarcode, int opType, DataLog currentTask, Barcode subBarcode, int opQty) throws ValidateException {
//更新barcode缓存
......
......@@ -198,7 +198,10 @@ public class StorageController {
List<Storage> allStorages = storageManager.findAll();
List<Storage> myStorages = new ArrayList<>();
for (Storage s : allStorages) {
if (BARCODE_SOURCE.VIRTUAL.equals(type)){
if (BARCODE_SOURCE.ALL.equals(type)){
}
else if (BARCODE_SOURCE.VIRTUAL.equals(type)){
if (!s.isVirtual()){
continue;
}
......
......@@ -15,6 +15,7 @@ import com.neotel.smfcore.core.barcode.enums.BARCODE_SOURCE;
import com.neotel.smfcore.core.barcode.rest.bean.dto.BarcodeDto;
import com.neotel.smfcore.core.barcode.rest.bean.dto.CodeDto;
import com.neotel.smfcore.core.barcode.rest.bean.mapstruct.CodeMapper;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.utils.CodeResolve;
import com.neotel.smfcore.core.device.util.DataCache;
......@@ -54,6 +55,7 @@ import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@RestController
......@@ -79,6 +81,9 @@ public class StoragePosController {
@Autowired
private CodeMapper codeMapper;
@Autowired
private IBarcodeManager barcodeManager;
@ApiOperation("查询库位")
@GetMapping
......@@ -568,8 +573,10 @@ public class StoragePosController {
String isSingleOutStr = checkOutDto.getSingleOut();
boolean isSingleOut = Boolean.valueOf(isSingleOutStr);
List<String> needOutPosIdList = new ArrayList<>();
for (String pid : checkOutDto.getPids()) {
StoragePos pos = storagePosManager.get(pid);
StoragePos pos = storagePosManager.getByBarcodeId(pid);
if (pos == null) {
//throw new ValidateException("smfcore.valueNotExist", "{0}[{1}]不存在", new String[]{"pid", pid});
// throw new ValidateException("位置[" + pid + "]不存在");
......@@ -591,7 +598,7 @@ public class StoragePosController {
//如果料仓不可用,不能出库
if (!storage.isVirtual()) {
if (!dataCache.StorageIsAvailable(storage)) {
throw new ValidateException("smfcore.storage.notAvailable", "料仓{0}离线或不可用,无法出库", new String[]{storage.getName()});
//throw new ValidateException("smfcore.storage.notAvailable", "料仓{0}离线或不可用,无法出库", new String[]{storage.getName()});
}
}
......@@ -600,11 +607,29 @@ public class StoragePosController {
// if(!result) {
// throw new ValidateException("smfcore.error.getMaterialLot.out", "条码[{0}]验证失败,无法出库", new String[]{pos.getBarcode().getBarcode()});
// }
//判断是属于料箱还是物料
List<Barcode> subCodeList = posBarcode.getSubCodeList();
if(subCodeList != null && !subCodeList.isEmpty()){
Barcode subCode = posBarcode.getSubCodeByBarcodeId(pid);
if (subCode != null){
subCode.updateAppendData("awaiting", subCode.getAmount());
barcodeManager.save(subCode);
posBarcode.UpdateSubCode(subCode);
barcodeManager.save(posBarcode);
pos.setBarcode(posBarcode);
storagePosManager.save(pos);
}
}
log.info("手动出库:出库料仓【" + storage.getName() + "_" + storage.getCid() + "】位置仓位【" + pos.getPosName() + "】");
String outResult = taskService.checkout(storage, pos, isSingleOut,SecurityUtils.getCurrentUsername());
if (!Strings.isNullOrEmpty(outResult)) {
throw new ValidateException("smfcore.error", outResult);
needOutPosIdList.add(pos.getId());
}
if (needOutPosIdList != null && !needOutPosIdList.isEmpty()){
needOutPosIdList = needOutPosIdList.stream().distinct().collect(Collectors.toList());
for (String posId : needOutPosIdList) {
StoragePos pos = storagePosManager.get(posId);
Storage storage = dataCache.getStorageById(pos.getStorageId());
taskService.checkout(storage, pos, isSingleOut,SecurityUtils.getCurrentUsername());
}
}
return ResultBean.newOkResult("");
......
......@@ -96,4 +96,8 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
StoragePos findOne(Query query);
Sort getSortByCheckOutType(CHECKOUT_TYPE checkoutType);
List<StoragePos> findPosListByPartNumber(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType,Map<String,String> appendData);
List<StoragePos> findPosListByMpn(List<String> availableStorageIds, String mpn, Collection<String> excludePosIds, CHECKOUT_TYPE checkoutType, Map<String, String> appendDate);
}
......@@ -171,6 +171,9 @@ public class DevicesStatusUtil {
// return statusBean;
// }
//缓存信息
private static Map<String, List<MsgInfo>> cacheMsgMap = Maps.newConcurrentMap();
/**
* 更新客户端发上来的消息(设备故障等消息)
*/
......@@ -195,6 +198,38 @@ public class DevicesStatusUtil {
}
}
if (newMsg) {
List<MsgInfo> cacheMsgList = cacheMsgMap.get(cid);
if (cacheMsgList == null || cacheMsgList.isEmpty()) {
cacheMsgList = new ArrayList<>();
}
List<MsgInfo> newCacheList = new ArrayList<>();
for (MsgInfo msgInfo : cacheMsgList) {
if (System.currentTimeMillis() - msgInfo.getLastReceiveTime() > 1000 * 60 * 5) {
continue;
}
String msgKey = msg.getMsgKey();
String msgStr = msg.getMsg();
if (StringUtils.isNotEmpty(msgKey)) {
if (msgKey.equals(msgInfo.getMsgKey())) {
newMsg = false;
msgInfo.setLastReceiveTime(System.currentTimeMillis());
}
}
if (StringUtils.isNotEmpty(msgStr)) {
if (msgStr.equals(msgInfo.getMsg())) {
newMsg = false;
msgInfo.setLastReceiveTime(System.currentTimeMillis());
}
}
newCacheList.add(msgInfo);
}
if (newMsg){
newCacheList.add(msg);
}
cacheMsgMap.put(cid, newCacheList);
}
if (newMsg) {
String msgType= msg.getType();
if(ObjectUtil.isEmpty(msgType)){
msgType=MessageType.ERROR.name();
......
package com.neotel.smfcore.core.virtual.util;
import java.util.concurrent.atomic.AtomicInteger;
public class ShortUniqueCodeUtil {
// 使用36进制(0-9,a-z)可以表示更多组合
private static final int RADIX = 36;
// 最后时间戳和序列号
private static volatile long lastTimestamp = 0L;
private static final AtomicInteger sequence = new AtomicInteger(0);
// 序列号最大值(保留2位36进制数)
private static final int MAX_SEQUENCE = RADIX * RADIX;
/**
* 生成6位不重复的唯一码
*
* @return 6位36进制的唯一码(包含数字和小写字母)
*/
public static synchronized String generate() {
long currentTime = System.currentTimeMillis();
// 如果同一毫秒内,增加序列号
if (currentTime == lastTimestamp) {
int seq = sequence.incrementAndGet();
if (seq >= MAX_SEQUENCE) {
// 序列号用尽,等待到下一毫秒
while (currentTime <= lastTimestamp) {
currentTime = System.currentTimeMillis();
}
sequence.set(0);
}
} else {
sequence.set(0);
}
lastTimestamp = currentTime;
// 将时间戳和序列号转换为36进制字符串
String timePart = Long.toString(currentTime, RADIX);
String seqPart = String.format("%02d", sequence.get());
// 组合并确保长度为6
String fullCode = timePart + seqPart;
if (fullCode.length() > 6) {
fullCode = fullCode.substring(fullCode.length() - 6);
} else if (fullCode.length() < 6) {
fullCode = String.format("%6s", fullCode).replace(' ', '0');
}
return fullCode;
}
}
......@@ -182,8 +182,8 @@ public class FujiApi extends BaseSmfApiListener {
*/
public String getAccessToken() {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("userName", FujiUrlConfig.userName);
paramMap.put("password", FujiUrlConfig.password);
paramMap.put("userName", getAuthUserName());
paramMap.put("password", getAuthPassword());
String paramStr = JSON.toJSONString(paramMap);
log.info("获取Fuji的token参数为:" + paramStr);
String accessToken = "";
......@@ -218,6 +218,22 @@ public class FujiApi extends BaseSmfApiListener {
return config.getAuthUrl();
}
private String getAuthUserName(){
FujiConfig config = dataCache.getCache(FujiCacheConfig.FujiConfig_Cache_Name);
if (config == null) {
config = new FujiConfig();
}
return config.getUserName();
}
private String getAuthPassword(){
FujiConfig config = dataCache.getCache(FujiCacheConfig.FujiConfig_Cache_Name);
if (config == null) {
config = new FujiConfig();
}
return config.getPassword();
}
private String getInventoryDids(){
FujiConfig config = dataCache.getCache(FujiCacheConfig.FujiConfig_Cache_Name);
if (config == null) {
......
......@@ -7,6 +7,8 @@ import java.util.Date;
@Data
public class FujiConfig {
private String authUrl = "";
private String userName = "";
private String password = "";
private String getDidInfoUrl = "";
private String registerDidInfoUrl = "";
private String result = "";
......
......@@ -7,9 +7,9 @@ public class FujiUrlConfig {
//private static final String baseUrl = "http://175.41.238.212/fujiopenwebapi/api/v1";
public static final String userName = "Neotel";
//public static final String userName = "Neotel";
public static final String password = "Neotel";
//public static final String password = "Neotel";
//private static final String authLogin = "/auth/login";
......
......@@ -62,6 +62,8 @@ public class FujiController {
config.setInputEto(newConfig.getInputEto());
config.setOutputEtn(newConfig.getOutputEtn());
config.setTime(newConfig.getTime());
config.setUserName(newConfig.getUserName());
config.setPassword(newConfig.getPassword());
dataCache.updateCache(FujiCacheConfig.FujiConfig_Cache_Name, config);
return ResultBean.newOkResult("");
}
......@@ -85,6 +87,8 @@ public class FujiController {
dto.setTime(config.getTime());
dto.setEtnUpdateDateStr(getUpdateDate(config.getOutputEtn()));
dto.setEtoUpdateDateStr(getUpdateDate(config.getInputEto()));
dto.setUserName(config.getUserName());
dto.setPassword(config.getPassword());
return ResultBean.newOkResult(dto);
}
......
......@@ -58,4 +58,9 @@ public class UserDto implements Serializable {
@ApiModelProperty("语言名称:简体中文,繁体中文 等")
private String lanName;
@ApiModelProperty("激活码")
private String checkCode;
@ApiModelProperty("是否启用")
private boolean active = false;
}
......@@ -238,6 +238,15 @@ public class UserManagerImpl implements IUserManager {
dtos.get(i).setRoleName(role.getName());
}
}
String username = dtos.get(i).getUsername();
String checkCode = dtos.get(i).getCheckCode();
if (Constants.SUPER_USERNAME.equals(username)){
dtos.get(i).setActive(true);
} else {
if (StringUtils.isNotEmpty(checkCode)){
dtos.get(i).setActive(true);
}
}
}
return dtos;
}
......
......@@ -434,3 +434,4 @@ smfcore.virtualOperations=\u865A\u62DF\u4ED3\u64CD\u4F5C
smfcore.equipment.view.ncgroup=Neo Counter
smfcore.virtual.boxInPos=[{0}]\u5DF2\u5728\u5E93\u4F4D[{1}]\u4E2D,\u8BF7\u5148\u53D6\u51FA
smfcore.virtual.quantityError=\u53D6\u51FA\u6570\u91CF\u5E94\u4E3A[{0}]
smfcode.virtual.enter=\u8BF7\u626B\u63CF\u6216\u8F93\u5165\u6761\u7801\u540E\u6309\u56DE\u8F66\u786E\u8BA4
\ No newline at end of file
......@@ -424,3 +424,4 @@ smfcore.virtualOperations=Vorg\u00E4nge im virtuellen Lager
smfcore.equipment.view.ncgroup=Neo Counter
smfcore.virtual.boxInPos=[{0}] befindet sich bereits im Lagerplatz [{1}]. Bitte entnehmen Sie es zuerst
smfcore.virtual.quantityError=Die zu entnehmende Menge sollte [{0}] betragen
smfcode.virtual.enter=Bitte scannen Sie den Barcode oder geben Sie ihn ein und best\u00E4tigen Sie mit Enter
\ No newline at end of file
......@@ -146,7 +146,7 @@ smfcore.translation=Resource Translation
smfcore.languageCanotNull=Language type cannot be empty
smfcore.noLanguageSetAccess=No permission to edit the language
smfcore.languageCanotRemoveAll=Cannot delete all languages
smfcore.solderPaste=Solder Paste
smfcore.solderPaste=Solder Paste Management
smfcore.solderPasteKanban=Equipment Overview
smfcore.solderPasteManage=Inventory
smfcore.solderPasteData=Traceability
......@@ -425,3 +425,4 @@ smfcore.virtualOperations=Virtual Storage Op
smfcore.equipment.view.ncgroup=Neo Counter
smfcore.virtual.boxInPos=[{0}] is already in location [{1}]. Please remove it first
smfcore.virtual.quantityError=The quantity to be removed should be [{0}]
smfcode.virtual.enter=Please scan or enter the barcode, then press Enter
\ No newline at end of file
......@@ -424,3 +424,4 @@ smfcore.virtualOperations=Op\u00E9rations de l'entrep\u00F4t virtuel
smfcore.equipment.view.ncgroup=Neo Counter
smfcore.virtual.boxInPos=[{0}] est d\u00E9j\u00E0 dans l'emplacement [{1}]. Veuillez d'abord le retirer
smfcore.virtual.quantityError=La quantit\u00E9 \u00E0 retirer doit \u00EAtre [{0}]
smfcode.virtual.enter=Veuillez scanner ou saisir le code-barres, puis appuyer sur Entr\u00E9e
\ No newline at end of file
......@@ -421,3 +421,4 @@ smfcore.virtualOperations=\u4EEE\u60F3\u5009\u5EAB\u64CD\u4F5C
smfcore.equipment.view.ncgroup=Neo Counter
smfcore.virtual.boxInPos=[{0}] \u306F\u65E2\u306B\u30ED\u30B1\u30FC\u30B7\u30E7\u30F3 [{1}] \u306B\u3042\u308A\u307E\u3059\u3002\u5148\u306B\u53D6\u308A\u51FA\u3057\u3066\u304F\u3060\u3055\u3044
smfcore.virtual.quantityError=\u53D6\u308A\u51FA\u3057\u6570\u91CF\u306F[{0}]\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
smfcode.virtual.enter=\u30D0\u30FC\u30B3\u30FC\u30C9\u3092\u30B9\u30AD\u30E3\u30F3\u3001\u307E\u305F\u306F\u5165\u529B\u5F8C\u3001Enter\u30AD\u30FC\u3092\u62BC\u3057\u3066\u304F\u3060\u3055\u3044
\ No newline at end of file
......@@ -421,3 +421,4 @@ smfcore.virtualOperations=\u865A\u62DF\u4ED3\u64CD\u4F5C
smfcore.equipment.view.ncgroup=Neo Counter
smfcore.virtual.boxInPos=[{0}]\u5DF2\u5728\u5E93\u4F4D[{1}]\u4E2D,\u8BF7\u5148\u53D6\u51FA
smfcore.virtual.quantityError=\u53D6\u51FA\u6570\u91CF\u5E94\u4E3A[{0}]
smfcode.virtual.enter=\u8BF7\u626B\u63CF\u6216\u8F93\u5165\u6761\u7801\u540E\u6309\u56DE\u8F66\u786E\u8BA4
\ No newline at end of file
......@@ -421,3 +421,4 @@ smfcore.virtualOperations=\u865B\u64EC\u5009\u64CD\u4F5C
smfcore.equipment.view.ncgroup=Neo Counter
smfcore.virtual.boxInPos=[{0}]\u5DF2\u5728\u5EAB\u4F4D[{1}]\u4E2D,\u8ACB\u5148\u53D6\u51FA
smfcore.virtual.quantityError=\u53D6\u51FA\u6578\u91CF\u61C9\u70BA[{0}]
smfcode.virtual.enter=\u8ACB\u6383\u63CF\u6216\u8F38\u5165\u689D\u78BC\u5F8C\u6309\u56DE\u8ECA\u78BA\u8A8D
\ No newline at end of file
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!