Commit 078c99f3 孙克

Merge remote-tracking branch 'origin/master'

2 个父辈 a07ba255 5cbae4a0
正在显示 55 个修改的文件 包含 1280 行增加64 行删除
...@@ -19,6 +19,10 @@ import java.util.Locale; ...@@ -19,6 +19,10 @@ import java.util.Locale;
@Data @Data
public class ResultBean<T> { public class ResultBean<T> {
public static ResultBean newErrorResult(int code, String msg) {
return newErrorResult(code, "", msg);
}
public static ResultBean newErrorResult(int code, String msgKey, String msg ) { public static ResultBean newErrorResult(int code, String msgKey, String msg ) {
return newErrorResult(code, msgKey, msg, new String[]{},true); return newErrorResult(code, msgKey, msg, new String[]{},true);
} }
......
...@@ -235,6 +235,7 @@ public class MenuInit { ...@@ -235,6 +235,7 @@ public class MenuInit {
Menu poutSet = Menu.CreatePMenu("设置", 13, "system","system",null); Menu poutSet = Menu.CreatePMenu("设置", 13, "system","system",null);
addDefaultFunctionMenu(101, poutSet, "设备管理", "bunker", "storage/storage/index", "database",DEFAULT_SHOW_MENU); addDefaultFunctionMenu(101, poutSet, "设备管理", "bunker", "storage/storage/index", "database",DEFAULT_SHOW_MENU);
addDefaultFunctionMenu(102,poutSet, "库位管理", "storagePos", "storagePos/storagePos/index", "tree-table",DEFAULT_SHOW_MENU); addDefaultFunctionMenu(102,poutSet, "库位管理", "storagePos", "storagePos/storagePos/index", "tree-table",DEFAULT_SHOW_MENU);
addDefaultFunctionMenu(103,poutSet, "合并库位", "selectDevice", "neolight/selectDevice/index", "selectDevice");
addDefaultFunctionMenu(103, poutSet, "菜单管理", "menu", "system/menu/index", "menu"); addDefaultFunctionMenu(103, poutSet, "菜单管理", "menu", "system/menu/index", "menu");
// Menu sysSetting = new Menu(, "barcode", "条码设置", "barcodeSetting", "system/barcodeSetting/index", "database"); // Menu sysSetting = new Menu(, "barcode", "条码设置", "barcodeSetting", "system/barcodeSetting/index", "database");
// Menu outSet = new Menu(, "outSetting", "出库策略", "outSetting", "system/outSetting/index", "outSet"); // Menu outSet = new Menu(, "outSetting", "出库策略", "outSetting", "system/outSetting/index", "outSet");
......
...@@ -666,7 +666,7 @@ public class HttpHelper { ...@@ -666,7 +666,7 @@ public class HttpHelper {
List<NameValuePair> params = toNameValuePair(paramMap); List<NameValuePair> params = toNameValuePair(paramMap);
URI uri = new URIBuilder(url).setParameters(params).build(); URI uri = new URIBuilder(url).setParameters(params).build();
log.info("getParam请求,地址为:"+uri); //log.info("getParam请求,地址为:"+uri);
HttpGet httpGet = new HttpGet(uri); HttpGet httpGet = new HttpGet(uri);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECTION_TIMEOUT).build(); RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECTION_TIMEOUT).build();
httpGet.setConfig(requestConfig); httpGet.setConfig(requestConfig);
......
...@@ -9,6 +9,7 @@ import com.neotel.smfcore.core.api.bean.CodeValidateParam; ...@@ -9,6 +9,7 @@ import com.neotel.smfcore.core.api.bean.CodeValidateParam;
import com.neotel.smfcore.core.device.util.DataCache; import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.inList.service.po.InList; import com.neotel.smfcore.core.inList.service.po.InList;
import com.neotel.smfcore.core.order.service.po.LiteOrder; import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.po.DataLog; import com.neotel.smfcore.core.system.service.po.DataLog;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings; import org.apache.logging.log4j.util.Strings;
...@@ -85,6 +86,12 @@ public class SmfApi { ...@@ -85,6 +86,12 @@ public class SmfApi {
@Value("${api.deviceStatusUrl:}") @Value("${api.deviceStatusUrl:}")
protected String deviceStatusUrl = ""; protected String deviceStatusUrl = "";
@Value("${api.mergePosUrl:}")
protected String mergePosUrl = "";
@Value("${api.splitPosUrl:}")
protected String splitPosUrl = "";
@PostConstruct @PostConstruct
public void init(){ public void init(){
apiName = dataCache.getConfigCache("api.name",apiName); apiName = dataCache.getConfigCache("api.name",apiName);
...@@ -100,6 +107,8 @@ public class SmfApi { ...@@ -100,6 +107,8 @@ public class SmfApi {
fetchOrderUrl = dataCache.getConfigCache("api.fetchOrderUrl",fetchOrderUrl); fetchOrderUrl = dataCache.getConfigCache("api.fetchOrderUrl",fetchOrderUrl);
loginCheckUrl=dataCache.getConfigCache("api.loginCheckUrl",loginCheckUrl); loginCheckUrl=dataCache.getConfigCache("api.loginCheckUrl",loginCheckUrl);
deviceStatusUrl=dataCache.getConfigCache("api.deviceStatusUrl",deviceStatusUrl); deviceStatusUrl=dataCache.getConfigCache("api.deviceStatusUrl",deviceStatusUrl);
mergePosUrl = dataCache.getConfigCache("api.mergePosUrl",mergePosUrl);
splitPosUrl = dataCache.getConfigCache("api.splitPosUrl",splitPosUrl);
} }
/** /**
...@@ -294,6 +303,37 @@ public class SmfApi { ...@@ -294,6 +303,37 @@ public class SmfApi {
} }
return true; return true;
} }
public void splitPos(String splitPosName) {
if(isUrlExist(splitPosUrl)){
threadPool.execute(new Runnable() {
@Override
public void run() {
for (ISmfApiListener apiListener : apiListenerList) {
if(apiListener.isForThisApi(apiName)){
apiListener.splitPos(splitPosUrl,splitPosName);
}
}
}
});
}
}
public void mergePos(StoragePos storagePos) {
if(isUrlExist(mergePosUrl)){
threadPool.execute(new Runnable() {
@Override
public void run() {
for (ISmfApiListener apiListener : apiListenerList) {
if(apiListener.isForThisApi(apiName)){
apiListener.mergePos(mergePosUrl,storagePos);
}
}
}
});
}
}
public String getApiName(){ public String getApiName(){
return apiName; return apiName;
} }
......
...@@ -20,6 +20,7 @@ import com.neotel.smfcore.core.inList.util.InListCache; ...@@ -20,6 +20,7 @@ import com.neotel.smfcore.core.inList.util.InListCache;
import com.neotel.smfcore.core.order.LiteOrderCache; import com.neotel.smfcore.core.order.LiteOrderCache;
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.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.po.DataLog; import com.neotel.smfcore.core.system.service.po.DataLog;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings; import org.apache.logging.log4j.util.Strings;
...@@ -152,4 +153,14 @@ public abstract class BaseSmfApiListener implements ISmfApiListener { ...@@ -152,4 +153,14 @@ public abstract class BaseSmfApiListener implements ISmfApiListener {
public boolean deviceStatusChanges(String deviceStatusUrl, String[] cids,Integer[] status) { public boolean deviceStatusChanges(String deviceStatusUrl, String[] cids,Integer[] status) {
return true; return true;
} }
@Override
public void splitPos(String splitPosUrl, String splitPosName) {
}
@Override
public void mergePos(String mergePosUrl, StoragePos storagePos) {
}
} }
...@@ -6,6 +6,7 @@ import com.neotel.smfcore.core.barcode.service.po.Barcode; ...@@ -6,6 +6,7 @@ import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.api.bean.CodeValidateParam; import com.neotel.smfcore.core.api.bean.CodeValidateParam;
import com.neotel.smfcore.core.inList.service.po.InList; import com.neotel.smfcore.core.inList.service.po.InList;
import com.neotel.smfcore.core.order.service.po.LiteOrder; import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.po.DataLog; import com.neotel.smfcore.core.system.service.po.DataLog;
public interface ISmfApiListener { public interface ISmfApiListener {
...@@ -80,4 +81,9 @@ public interface ISmfApiListener { ...@@ -80,4 +81,9 @@ public interface ISmfApiListener {
* @return * @return
*/ */
boolean deviceStatusChanges(String deviceStatusUrl, String[] cids,Integer[] status ); boolean deviceStatusChanges(String deviceStatusUrl, String[] cids,Integer[] status );
void splitPos(String splitPosUrl, String splitPosName);
void mergePos(String mergePosUrl, StoragePos storagePos);
} }
...@@ -17,4 +17,6 @@ public interface IBarcodeManager extends IBaseManager<Barcode> { ...@@ -17,4 +17,6 @@ public interface IBarcodeManager extends IBaseManager<Barcode> {
void download(List<Barcode> list, HttpServletResponse response) throws IOException; void download(List<Barcode> list, HttpServletResponse response) throws IOException;
void deleteBarcodes(Set<String> ids); void deleteBarcodes(Set<String> ids);
Barcode findOneByLockName(String lockName);
} }
...@@ -96,6 +96,11 @@ public class BarcodeManagerImpl implements IBarcodeManager { ...@@ -96,6 +96,11 @@ public class BarcodeManagerImpl implements IBarcodeManager {
} }
@Override @Override
public Barcode findOneByLockName(String lockName) {
return barcodeDao.findOne(new Query(Criteria.where("lockName").is(lockName)));
}
@Override
public Barcode saveBarcode(Barcode resources) { public Barcode saveBarcode(Barcode resources) {
validateSave(resources); validateSave(resources);
......
...@@ -18,6 +18,7 @@ import com.neotel.smfcore.core.dashboard.bean.dto.first.InOutDataDto; ...@@ -18,6 +18,7 @@ import com.neotel.smfcore.core.dashboard.bean.dto.first.InOutDataDto;
import com.neotel.smfcore.core.inout.service.manager.IInOutDataManager; import com.neotel.smfcore.core.inout.service.manager.IInOutDataManager;
import com.neotel.smfcore.core.inout.service.po.InOutData; import com.neotel.smfcore.core.inout.service.po.InOutData;
import com.neotel.smfcore.core.kanban.rest.bean.dto.BoxStatusDto; import com.neotel.smfcore.core.kanban.rest.bean.dto.BoxStatusDto;
import com.neotel.smfcore.core.kanban.rest.utils.NaturalOrderComparator;
import com.neotel.smfcore.core.language.util.MessageUtils; import com.neotel.smfcore.core.language.util.MessageUtils;
import com.neotel.smfcore.core.message.rest.bean.dto.MessageDto; import com.neotel.smfcore.core.message.rest.bean.dto.MessageDto;
import com.neotel.smfcore.core.message.rest.bean.mapstruct.MessageMapper; import com.neotel.smfcore.core.message.rest.bean.mapstruct.MessageMapper;
...@@ -105,7 +106,18 @@ public class SmdBoxMimoController { ...@@ -105,7 +106,18 @@ public class SmdBoxMimoController {
posCount += item.getTotalCount(); posCount += item.getTotalCount();
usePosCount += item.getUsedCount(); usePosCount += item.getUsedCount();
} }
InventoryBoxDto boxDto = new InventoryBoxDto(storage.getId(), storage.getName(), storage.getCid(), storage.getType(), storage.getUsageMap(), posCount, usePosCount);
Map<String, UsageItem> sortUsageMap = new LinkedHashMap<>();
Map<String, UsageItem> usageMap = storage.getUsageMap();
if (usageMap != null && !usageMap.isEmpty()) {
List<UsageItem> usageList = new ArrayList<>(usageMap.values());
usageList = usageList.stream().sorted(Comparator.comparing(UsageItem :: getW).thenComparing(UsageItem :: getH)).collect(Collectors.toList());
for (UsageItem usageItem : usageList) {
sortUsageMap.put(usageItem.getSizeStr(),usageItem);
}
}
InventoryBoxDto boxDto = new InventoryBoxDto(storage.getId(), storage.getName(), storage.getCid(), storage.getType(), sortUsageMap, posCount, usePosCount);
boxDtos.add(boxDto); boxDtos.add(boxDto);
} }
if (boxDtos.size() > 0) { if (boxDtos.size() > 0) {
......
...@@ -823,6 +823,7 @@ public class BaseDeviceHandler implements IDeviceHandler { ...@@ -823,6 +823,7 @@ public class BaseDeviceHandler implements IDeviceHandler {
//仓位状态 //仓位状态
barcodeDB.setCheckOutDate(new Date(), task.getOperator()); barcodeDB.setCheckOutDate(new Date(), task.getOperator());
barcodeDB.setPosName(""); barcodeDB.setPosName("");
barcodeDB.setOnlySingleOut(false);
barcodeManager.save(barcodeDB); barcodeManager.save(barcodeDB);
task.setBatchInfo(barcodeDB.getBatch()); task.setBatchInfo(barcodeDB.getBatch());
......
package com.neotel.smfcore.core.device.handler.impl;
import com.neotel.smfcore.core.storage.enums.DeviceType;
import org.springframework.stereotype.Service;
@Service
public class MimoG4BoxHandler extends MimoG3BoxHandler{
@Override
public DeviceType getDeviceType() {
return DeviceType.SMD_MIMO_G4;
}
}
...@@ -242,32 +242,32 @@ public class NLPShelfHandler extends BaseDeviceHandler { ...@@ -242,32 +242,32 @@ public class NLPShelfHandler extends BaseDeviceHandler {
//亮灯 //亮灯
Collection<DataLog> queueTasks = taskService.getQueueTasks(statusBean.getCid()); Collection<DataLog> queueTasks = taskService.getQueueTasks(statusBean.getCid());
for (DataLog queueTask : queueTasks) { for (DataLog queueTask : queueTasks) {
if (queueTask.isWait() && queueTask.isCheckOutTask()) { if (!openZhiYin || StringUtils.isBlank(queueTask.getSourceId())) {
queueTask.setStatus(OP_STATUS.EXECUTING.name()); if (queueTask.isWait()) {
taskService.updateQueueTask(queueTask);
String rgb = queueTask.getLightColor(); String rgb = queueTask.getLightColor();
ORDER_COLOR color = ORDER_COLOR.fromRgb(rgb); ORDER_COLOR color = ORDER_COLOR.fromRgb(rgb);
if (color == null) { if (color == null) {
if (openZhiYin && ObjectUtil.isNotEmpty(queueTask.getSourceId())) { if (queueTask.isPutInTask()) {
color = ORDER_COLOR.FORESTGREEN;
} else {
color = ORDER_COLOR.BLUE;
}
}
queueTask.setStatus(OP_STATUS.EXECUTING.name());
taskService.updateQueueTask(queueTask);
statusBean.addData("open", queueTask.getPosName() + "=" + color.name());
log.info("库位[" + queueTask.getPosName() + "][" + queueTask.getType() + "]+亮灯:" + color.name());
}
} else {
if (queueTask.isWait() || queueTask.isExecuting()) {
List<DataLog> dataLogList = outMap.get(queueTask.getSourceId()); List<DataLog> dataLogList = outMap.get(queueTask.getSourceId());
if (dataLogList == null) { if (dataLogList == null) {
dataLogList = new ArrayList<>(); dataLogList = new ArrayList<>();
} }
dataLogList.add(queueTask); dataLogList.add(queueTask);
outMap.put(queueTask.getSourceId(), dataLogList); outMap.put(queueTask.getSourceId(), dataLogList);
} else {
if (StringUtils.isNotBlank(rgb)){
log.info(queueTask.getPosName() + "库位亮灯:" + "#" + rgb);
statusBean.addData("open", queueTask.getPosName() + "=#" + rgb);
} else {
color = ORDER_COLOR.BLUE;
}
}
}
if (color != null){
statusBean.addData("open", queueTask.getPosName() + "=" + color.name());
log.info("库位[" + queueTask.getPosName() + "]+亮灯:" + color.name());
} }
} }
} }
......
...@@ -820,7 +820,7 @@ public class DataCache { ...@@ -820,7 +820,7 @@ public class DataCache {
public List<String> getAvailableStorageIds() { public List<String> getAvailableStorageIds() {
List<String> availableStorageIds = new ArrayList<>(); List<String> availableStorageIds = new ArrayList<>();
for (Storage storage : getAllStorage().values()) { for (Storage storage : getAllStorage().values()) {
if (!storage.isVirtual()) { if (!storage.isVirtual() && !storage.isNLPHBShelf()) {
StatusBean bean = DevicesStatusUtil.getStatusBean(storage.getCid()); StatusBean bean = DevicesStatusUtil.getStatusBean(storage.getCid());
if (bean == null || bean.timeOut() || !bean.isAvailable()) { if (bean == null || bean.timeOut() || !bean.isAvailable()) {
continue; continue;
...@@ -832,6 +832,7 @@ public class DataCache { ...@@ -832,6 +832,7 @@ public class DataCache {
} }
return availableStorageIds; return availableStorageIds;
} }
public List<String> getAvailableStorageIds(List<String> cidList) { public List<String> getAvailableStorageIds(List<String> cidList) {
if (cidList == null || cidList.size() <= 0) { if (cidList == null || cidList.size() <= 0) {
return getAvailableStorageIds(); return getAvailableStorageIds();
...@@ -841,7 +842,7 @@ public class DataCache { ...@@ -841,7 +842,7 @@ public class DataCache {
if (!cidList.contains(storage.getCid())) { if (!cidList.contains(storage.getCid())) {
continue; continue;
} }
if (!storage.isVirtual()) { if (!storage.isVirtual() && !storage.isNLPHBShelf()) {
StatusBean bean = DevicesStatusUtil.getStatusBean(storage.getCid()); StatusBean bean = DevicesStatusUtil.getStatusBean(storage.getCid());
if (bean == null || bean.timeOut() || !bean.isAvailable()) { if (bean == null || bean.timeOut() || !bean.isAvailable()) {
continue; continue;
...@@ -853,6 +854,7 @@ public class DataCache { ...@@ -853,6 +854,7 @@ public class DataCache {
} }
return availableStorageIds; return availableStorageIds;
} }
public List<String> getAvailableStorageIds(DeviceType deviceType) { public List<String> getAvailableStorageIds(DeviceType deviceType) {
List<String> availableStorageIds = new ArrayList<>(); List<String> availableStorageIds = new ArrayList<>();
for (Storage storage : getAllStorage().values()) { for (Storage storage : getAllStorage().values()) {
......
...@@ -5,10 +5,7 @@ import com.google.common.base.Strings; ...@@ -5,10 +5,7 @@ import com.google.common.base.Strings;
import com.neotel.smfcore.common.bean.PageData; import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.bean.ResultBean; 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.common.utils.Constants; import com.neotel.smfcore.common.utils.*;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.service.po.Barcode; import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.bean.BoxStatusBean; import com.neotel.smfcore.core.device.bean.BoxStatusBean;
import com.neotel.smfcore.core.device.bean.StatusBean; import com.neotel.smfcore.core.device.bean.StatusBean;
...@@ -374,6 +371,31 @@ public class BoxKanbanController { ...@@ -374,6 +371,31 @@ public class BoxKanbanController {
throw new ValidateException("smfcore.posNotExist", "仓位不存在"); throw new ValidateException("smfcore.posNotExist", "仓位不存在");
} }
//{opValue: "doit", cid: "SMD_DUO", opKey: "openNgLock"}
@ApiOperation("打开或者关闭ng门")
@RequestMapping("api/boxkanban/boxNgDoorOp")
@AnonymousAccess
public ResultBean boxNgDoorOp(@RequestBody Map<String, Object> paramList) {
log.info("{}收到数据为:{}", "boxNgDoorOp", JsonUtil.toJsonStr(paramList));
String cid = paramList.get("cid").toString();
String opValue = paramList.get("opValue").toString();
String opKey = paramList.get("opKey").toString();
StatusBean statusBean = DevicesStatusUtil.getStatusBean(cid);
if (statusBean == null || statusBean.timeOut()) {
//return ResultBean.newErrorResult(1, "smfcore.duo.offline", "设备{0}离线", new String[]{cid});
}
if (ObjectUtil.isNotEmpty(opKey)) {
String openLock = statusBean.getData().getOrDefault(opKey, "");
if (openLock.equals("enable")) {
log.info("boxDoorOp:cid=" + cid + "," + opKey + "=" + opValue);
DevicesStatusUtil.addOp(cid, opKey, opValue);
return ResultBean.newOkResult("smfcore.msg.ok", "操作成功");
}
}
return ResultBean.newErrorResult(2, "smfcore.msg.op.fail", "操作失败");
}
private BoxKanbanDto getKanBan(List<DataLog> allTasks,Locale local) { private BoxKanbanDto getKanBan(List<DataLog> allTasks,Locale local) {
int allCount = allTasks.size(); int allCount = allTasks.size();
...@@ -433,7 +455,7 @@ public class BoxKanbanController { ...@@ -433,7 +455,7 @@ public class BoxKanbanController {
boxDto.setOnLine(false); boxDto.setOnLine(false);
//如果是虚拟仓,默认在线 //如果是虚拟仓,默认在线
if (storage.isVirtual()) { if (storage.isVirtual() || storage.isNLPHBShelf()) {
boxDto.setOnLine(true); boxDto.setOnLine(true);
boxDto.setStatus(1); boxDto.setStatus(1);
} }
......
...@@ -33,16 +33,16 @@ public enum ORDER_COLOR { ...@@ -33,16 +33,16 @@ public enum ORDER_COLOR {
//MAGENTA("FF00FF"), //MAGENTA("FF00FF"),
CYAN("00FFFF"), CYAN("00FFFF"),
FIREBRICK("B22222"), FIREBRICK("B22222"),
PURPLE("A020F0"), //PURPLE("A020F0"),
//SKYBLUE("6CA6CD"), //SKYBLUE("6CA6CD"),
//PINK("FF1493"), //PINK("FF1493"),
FORESTGREEN("228B22"), FORESTGREEN("228B22"),
//LIGHTBLUE("8470FF"), //LIGHTBLUE("8470FF"),
//INDIANRED("8B3A3A"), //INDIANRED("8B3A3A"),
DARKGREEN("556B2F"), //DARKGREEN("556B2F"),
RED("FF0000"), //RED("FF0000"),
YELLOW("FFFF00"), YELLOW("FFFF00"),
ORANGE("FFA500"), //ORANGE("FFA500"),
WHITE("FFFFFF") WHITE("FFFFFF")
; ;
......
...@@ -376,7 +376,7 @@ public class SelfAuditController { ...@@ -376,7 +376,7 @@ public class SelfAuditController {
} }
log.info("处理盘点批次【" + batchNo + "】,料仓【" + storage.getName() + "_" + storage.getCid() + "】位置仓位【" + pos.getPosName() + "】 自动生成出库任务"); log.info("处理盘点批次【" + batchNo + "】,料仓【" + storage.getName() + "_" + storage.getCid() + "】位置仓位【" + pos.getPosName() + "】 自动生成出库任务");
String outResult = taskService.checkoutTest(storage, pos, true, "selfAudit-clear"); String outResult = taskService.checkoutTest(storage, pos, true, "selfAudit-clear",false);
if (!Strings.isNullOrEmpty(outResult)) { if (!Strings.isNullOrEmpty(outResult)) {
throw new ValidateException("smfcore.error", outResult); throw new ValidateException("smfcore.error", outResult);
} }
......
...@@ -102,6 +102,7 @@ public class SpBoxHandler extends BaseDeviceHandler { ...@@ -102,6 +102,7 @@ public class SpBoxHandler extends BaseDeviceHandler {
@Override @Override
public StatusBean handleClientRequest(StatusBean statusBean, HttpServletRequest request) { public StatusBean handleClientRequest(StatusBean statusBean, HttpServletRequest request) {
String cid = statusBean.getCid(); String cid = statusBean.getCid();
int isDuoSidePos=statusBean.getDuoSidePos();
Storage storage = dataCache.getStorage(cid); Storage storage = dataCache.getStorage(cid);
if (storage != null) { if (storage != null) {
statusBean.setClientIp(request.getRemoteHost()); statusBean.setClientIp(request.getRemoteHost());
...@@ -343,19 +344,19 @@ public class SpBoxHandler extends BaseDeviceHandler { ...@@ -343,19 +344,19 @@ public class SpBoxHandler extends BaseDeviceHandler {
if (!hasOutTask) { if (!hasOutTask) {
if (isDuoSidePos == 1) { if (isDuoSidePos == 1) {
//先查找B结尾的,再查找F结尾的 //先查找B结尾的,再查找F结尾的
log.info("从" + storage.getName() + "中为" + barcode.getBarcode() + "寻找空的仓位,先查找B结尾的库位"); log.info(isDuoSidePos+"从" + storage.getName() + "中为" + barcode.getBarcode() + "寻找空的仓位,先查找B结尾的库位");
storagePos = storagePosManager.getSpEmptyPosByStorage(storage, barcode, operatingPosIds, "B"); storagePos = storagePosManager.getSpEmptyPosByStorage(storage, barcode, operatingPosIds, "B");
if (storagePos == null) { if (storagePos == null) {
log.info("从" + storage.getName() + "中为" + barcode.getBarcode() + "寻找空的仓位,未找到B结尾的库位,查找F结尾库位"); log.info(isDuoSidePos+"从" + storage.getName() + "中为" + barcode.getBarcode() + "寻找空的仓位,未找到B结尾的库位,查找F结尾库位");
storagePos = storagePosManager.getSpEmptyPosByStorage(storage, barcode, operatingPosIds, "F"); storagePos = storagePosManager.getSpEmptyPosByStorage(storage, barcode, operatingPosIds, "F");
} }
if(storagePos==null){ if(storagePos==null){
log.info("从" + storage.getName() + "中为" + barcode.getBarcode() + "寻找空的仓位,查找所有库位"); log.info(isDuoSidePos+"从" + storage.getName() + "中为" + barcode.getBarcode() + "寻找空的仓位,查找所有库位");
storagePos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds); storagePos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds);
} }
} else { } else {
log.info("从" + storage.getName() + "中为" + barcode.getBarcode() + "寻找空的仓位"); log.info(isDuoSidePos+"从" + storage.getName() + "中为" + barcode.getBarcode() + "寻找空的仓位");
storagePos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds); storagePos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds);
} }
...@@ -368,7 +369,7 @@ public class SpBoxHandler extends BaseDeviceHandler { ...@@ -368,7 +369,7 @@ public class SpBoxHandler extends BaseDeviceHandler {
if (storagePos == null) { if (storagePos == null) {
throw new ValidateException("smfcore.error.storage.noPos", "{0}的料格[{1}]已满,无法继续放入", new String[]{storage.getName(), barcode.getPlateSize() + "x" + barcode.getHeight()}); throw new ValidateException("smfcore.error.storage.noPos", "{0}的料格[{1}]已满,无法继续放入", new String[]{storage.getName(), barcode.getPlateSize() + "x" + barcode.getHeight()});
} }
log.info("[" + barcode.getBarcode() + "]寻找到" + storage.getName() + "的空仓位[" + storagePos.getPosName() + "]"); log.info(isDuoSidePos+"[" + barcode.getBarcode() + "]寻找到" + storage.getName() + "的空仓位[" + storagePos.getPosName() + "]");
return storagePos; return storagePos;
} }
...@@ -430,6 +431,7 @@ public class SpBoxHandler extends BaseDeviceHandler { ...@@ -430,6 +431,7 @@ public class SpBoxHandler extends BaseDeviceHandler {
return null; return null;
} }
//锡膏料仓空闲 //锡膏料仓空闲
queueTasks = taskService.getQueueTasks(); queueTasks = taskService.getQueueTasks();
for (DataLog task : queueTasks) { for (DataLog task : queueTasks) {
...@@ -692,6 +694,7 @@ public class SpBoxHandler extends BaseDeviceHandler { ...@@ -692,6 +694,7 @@ public class SpBoxHandler extends BaseDeviceHandler {
// theFinishedTaskMap.put(task.getId(), task); // theFinishedTaskMap.put(task.getId(), task);
} }
private void changeSolderStatus(String posName, SOLDER_STATUS solderStatus) throws ValidateException { private void changeSolderStatus(String posName, SOLDER_STATUS solderStatus) throws ValidateException {
try {
StoragePos storagePos = storagePosManager.getByPosName(posName); StoragePos storagePos = storagePosManager.getByPosName(posName);
if (storagePos == null) { if (storagePos == null) {
log.error("更改状态为[" + solderStatus + "]时,未找到库位[" + posName + "]"); log.error("更改状态为[" + solderStatus + "]时,未找到库位[" + posName + "]");
...@@ -699,28 +702,32 @@ public class SpBoxHandler extends BaseDeviceHandler { ...@@ -699,28 +702,32 @@ public class SpBoxHandler extends BaseDeviceHandler {
} }
Barcode barcode = storagePos.getBarcode(); Barcode barcode = storagePos.getBarcode();
if (barcode != null) { if (barcode != null) {
if(!solderStatus.name().equals(barcode.getSolderStatus())){ if (!solderStatus.name().equals(barcode.getSolderStatus())) {
log.error(barcode.getBarcode()+"的状态状态从[" + barcode.getSolderStatus() + "]更改为[" + solderStatus + "]"); log.error(barcode.getBarcode() + "的状态状态从[" + barcode.getSolderStatus() + "]更改为[" + solderStatus + "]");
barcode.setSolderStatus(solderStatus.toString()); barcode.setSolderStatus(solderStatus.toString());
barcode = barcodeManager.save(barcode); barcode = barcodeManager.save(barcode);
storagePos.setBarcode(barcode); storagePos.setBarcode(barcode);
storagePosManager.save(storagePos); storagePosManager.save(storagePos);
}else{ } else {
log.error(barcode.getBarcode()+"的状态状态["+barcode.getSolderStatus()+"]与原来一致,无需更改"); log.error(barcode.getBarcode() + "的状态状态[" + barcode.getSolderStatus() + "]与原来一致,无需更改");
} }
} }
} catch (Exception ex) {
log.error("changeSolderStatus posName=" + posName + ",solderStatus=" + solderStatus + " error :" + ex.toString());
}
} }
private void mixEnd(DataLog mixTask) throws ValidateException { private void mixEnd(DataLog mixTask) throws ValidateException {
if (mixTask != null) { if (mixTask != null) {
log.info(mixTask.getBarcode() + "搅拌完成,送回原库位["+mixTask.getPosName()+"],更改状态为待出库"); log.info(mixTask.getBarcode() + "搅拌完成,送回原库位["+mixTask.getPosName()+"],更改状态为待出库");
changeSolderStatus(mixTask.getPosName(), SOLDER_STATUS.TO_BE_OUT);
//先更改状态再结束任务
taskService.removeQueueTask(mixTask); taskService.removeQueueTask(mixTask);
mixTask.setStatus(OP_STATUS.FINISHED.name()); mixTask.setStatus(OP_STATUS.FINISHED.name());
taskService.updateFinishedTask(mixTask); taskService.updateFinishedTask(mixTask);
changeSolderStatus(mixTask.getPosName(), SOLDER_STATUS.TO_BE_OUT);
} else { } else {
log.error("搅拌完成时,未找到任务"); log.error("搅拌完成时,未找到任务");
} }
......
...@@ -7,6 +7,7 @@ import com.neotel.smfcore.common.bean.ResultBean; ...@@ -7,6 +7,7 @@ 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.common.utils.DateUtil; import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.common.utils.QueryHelp; import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.api.SmfApi; import com.neotel.smfcore.core.api.SmfApi;
import com.neotel.smfcore.core.api.bean.CodeValidateParam; import com.neotel.smfcore.core.api.bean.CodeValidateParam;
import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE; import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE;
...@@ -48,6 +49,7 @@ import org.springframework.web.bind.annotation.*; ...@@ -48,6 +49,7 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.*; import java.util.*;
import java.util.regex.Pattern;
@Slf4j @Slf4j
@RestController @RestController
...@@ -157,7 +159,21 @@ public class SpBoxController { ...@@ -157,7 +159,21 @@ public class SpBoxController {
if (outDate == null) { if (outDate == null) {
outDate = new Date(); outDate = new Date();
} }
List<StoragePos> solderPosList = findSolder(storageId, pn, num); //先查找外侧库位
List<StoragePos> solderPosList = findSolder(storageId, pn, num, "F");
int fNum = solderPosList.size();
int bNum = 0;
int oNum = num - fNum;
if (oNum > 0) {
List<StoragePos> oPos = findSolder(storageId, pn, oNum, "");
if (oPos.size() > 0) {
bNum = oPos.size();
solderPosList.addAll(oPos);
}
}
log.info("outSolder 锡膏定时出库,storageId=" + storageId + ",pn="+pn+",共需要出" + num + ",查找到F库位=" + fNum + ",B库位=" + bNum);
setOutDate(solderPosList, outDate); setOutDate(solderPosList, outDate);
} }
return ResultBean.newOkResult(""); return ResultBean.newOkResult("");
...@@ -246,7 +262,7 @@ public class SpBoxController { ...@@ -246,7 +262,7 @@ public class SpBoxController {
return query; return query;
} }
private List<StoragePos> findSolder(String storageId, String pn, int num) { private List<StoragePos> findSolder(String storageId, String pn, int num,String endStr) {
Criteria c = Criteria.where("enabled").is(true).and("barcode").exists(true) Criteria c = Criteria.where("enabled").is(true).and("barcode").exists(true)
.and("barcode.solderStatus").in(SOLDER_STATUS.RETREAT_STORAGE, SOLDER_STATUS.UNDER_REFRIGERATION); .and("barcode.solderStatus").in(SOLDER_STATUS.RETREAT_STORAGE, SOLDER_STATUS.UNDER_REFRIGERATION);
if (!Strings.isNullOrEmpty(storageId)) { if (!Strings.isNullOrEmpty(storageId)) {
...@@ -261,6 +277,11 @@ public class SpBoxController { ...@@ -261,6 +277,11 @@ public class SpBoxController {
Sort sort =storagePosManager.getSortByCheckOutType(checkoutType); Sort sort =storagePosManager.getSortByCheckOutType(checkoutType);
//优先使用二次入库的 //优先使用二次入库的
q.with(Sort.by(Sort.Direction.ASC, "barcode.solderStatus").and(sort)); q.with(Sort.by(Sort.Direction.ASC, "barcode.solderStatus").and(sort));
if (StringUtils.isNotEmpty(endStr)) {
String regex = "" + endStr + "$";
c.and("posName").regex(Pattern.compile(regex));
}
return storagePosManager.findByQuery(q); return storagePosManager.findByQuery(q);
} }
......
...@@ -203,11 +203,10 @@ public class SolderBoxCache { ...@@ -203,11 +203,10 @@ public class SolderBoxCache {
} }
} }
/** private boolean CanCreateTask(StoragePos storagePos) {
* 创建出库任务
* @param storagePos try {
*/
private boolean createOutTask(StoragePos storagePos) throws ValidateException {
Barcode barcode = storagePos.getBarcode(); Barcode barcode = storagePos.getBarcode();
Collection<DataLog> queueTasks = taskService.getQueueTasks(); Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) { for (DataLog queueTask : queueTasks) {
...@@ -225,6 +224,39 @@ public class SolderBoxCache { ...@@ -225,6 +224,39 @@ public class SolderBoxCache {
return false; return false;
} }
} }
} catch (Exception exception) {
log.error("CanCreateTask 出错:" + exception.toString());
}
return true;
}
/**
* 创建出库任务
* @param storagePos
*/
private boolean createOutTask(StoragePos storagePos) throws ValidateException {
try {
if (!CanCreateTask(storagePos)) {
return false;
}
//等待1000后再次判断,防止正在处理出库任务过程中
Thread.sleep(500);
if (!CanCreateTask(storagePos)) {
log.error("createOutTask 库位号"+storagePos.getPosName()+" 再次验证时发现已有任务,暂不创建出库任务");
return false;
}
//重新查找库位
storagePos=storagePosManager.getByPosName(storagePos.getPosName());
if(storagePos.getBarcode()==null){
log.error("createOutTask 库位号"+storagePos.getPosName()+" 再次验证时发现库位已空,暂不创建出库任务");
return false;
}
Barcode barcode = storagePos.getBarcode();
// TimeUnit.SECONDS.sleep(1);
log.info(barcode.getBarcode() + "创建出库任务"); log.info(barcode.getBarcode() + "创建出库任务");
Storage storage = dataCache.getStorageById(storagePos.getStorageId()); Storage storage = dataCache.getStorageById(storagePos.getStorageId());
DataLog outTask = new DataLog(storage, barcode, storagePos); DataLog outTask = new DataLog(storage, barcode, storagePos);
...@@ -246,6 +278,13 @@ public class SolderBoxCache { ...@@ -246,6 +278,13 @@ public class SolderBoxCache {
// //
// log.info(barcode.getBarcode() + "创建出库任务完成,更改状态="+barcode.getSolderStatus()); // log.info(barcode.getBarcode() + "创建出库任务完成,更改状态="+barcode.getSolderStatus());
saveSolderLog(storagePos); saveSolderLog(storagePos);
} catch (ValidateException ex) {
log.error("createOutTask error " + ex.toString());
throw ex;
} catch (Exception ex1) {
log.error("createOutTask error " + ex1.toString());
}
return true; return true;
} }
......
...@@ -161,9 +161,21 @@ public enum DeviceType { ...@@ -161,9 +161,21 @@ public enum DeviceType {
SMD_ONE("storage.type.smdOne"), SMD_ONE("storage.type.smdOne"),
/** /**
* 尾料柜 * 27 尾料柜
*/ */
TAILING_MATERIAL("storage.type.tailingMaterial"), TAILING_MATERIAL("storage.type.tailingMaterial"),
/**
* 28 SMD_MIMO_G4
*/
SMD_MIMO_G4("storage.type.smdMimoG4"),
/**
* 29 感应料架NLP(浩博)
*/
NLP_HB("storage.type.nlpHb"),
; ;
private String key; private String key;
...@@ -185,6 +197,6 @@ public enum DeviceType { ...@@ -185,6 +197,6 @@ public enum DeviceType {
} }
public static List<DeviceType> availableTypeList(){ public static List<DeviceType> availableTypeList(){
return Lists.newArrayList(AUTO,LINE,BATCH,SOLDERPASTE,VERTICALBOX,SMD_XL,SMD_DUO,SMD_XLC,SMD_XLR,SMD_ONE,VIRTUAL,NL,NLP,NLM,NLL,NLS,NLSM,SMDBOX_THIRD,SMD_MIMO_G2,SMD_MIMO_G3,TAILING_MATERIAL); return Lists.newArrayList(AUTO,LINE,BATCH,SOLDERPASTE,VERTICALBOX,SMD_XL,SMD_DUO,SMD_XLC,SMD_XLR,SMD_ONE,VIRTUAL,NL,NLP,NLP_HB,NLM,NLL,NLS,NLSM,SMDBOX_THIRD,SMD_MIMO_G2,SMD_MIMO_G3,SMD_MIMO_G4,TAILING_MATERIAL);
} }
} }
...@@ -512,6 +512,7 @@ public class StoragePosController { ...@@ -512,6 +512,7 @@ public class StoragePosController {
header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.proDate",locale,"生产日期"))); header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.proDate",locale,"生产日期")));
header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.expireDate",locale,"过期时间"))); header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.expireDate",locale,"过期时间")));
header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.batch",locale,"物料批次"))); header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.batch",locale,"物料批次")));
header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.provider",locale,"供应商")));
header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.posName",locale,"库位号"))); header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.posName",locale,"库位号")));
header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.lockName",locale,"工单号"))); header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.lockName",locale,"工单号")));
header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.amount",locale,"数量"))); header.add(Lists.newArrayList(MessageUtils.getText("smfcore.storagePos.amount",locale,"数量")));
...@@ -547,6 +548,7 @@ public class StoragePosController { ...@@ -547,6 +548,7 @@ public class StoragePosController {
data.add(proDate); data.add(proDate);
data.add(expireDate); data.add(expireDate);
data.add(barcode.getBatch()); data.add(barcode.getBatch());
data.add(barcode.getProvider());
data.add(pos.getPosName()); data.add(pos.getPosName());
data.add(barcode.getLockName()); data.add(barcode.getLockName());
data.add(barcode.getAmount()); data.add(barcode.getAmount());
...@@ -576,6 +578,7 @@ public class StoragePosController { ...@@ -576,6 +578,7 @@ public class StoragePosController {
subData.add(subCodeProDate); subData.add(subCodeProDate);
subData.add(subCodeExpireDate); subData.add(subCodeExpireDate);
subData.add(subCode.getBatch()); subData.add(subCode.getBatch());
subData.add(subCode.getProvider());
subData.add(pos.getPosName()+"("+barcode.getBarcode()+")"); subData.add(pos.getPosName()+"("+barcode.getBarcode()+")");
subData.add(subCode.getLockName()); subData.add(subCode.getLockName());
subData.add(subCode.getAmount()); subData.add(subCode.getAmount());
...@@ -701,8 +704,8 @@ public class StoragePosController { ...@@ -701,8 +704,8 @@ public class StoragePosController {
// throw new ValidateException("smfcore.error.getMaterialLot.out", "条码[{0}]验证失败,无法出库", new String[]{pos.getBarcode().getBarcode()}); // throw new ValidateException("smfcore.error.getMaterialLot.out", "条码[{0}]验证失败,无法出库", new String[]{pos.getBarcode().getBarcode()});
// } // }
log.info("库位管理手动出库:出库料仓【" + storage.getName() + "_" + storage.getCid() + "】位置仓位【" + pos.getPosName() + "】"); log.info("库位管理手动出库:出库料仓【" + storage.getName() + "_" + storage.getCid() + "】位置仓位【" + pos.getPosName() + "】,posCheckout=true");
String outResult = taskService.checkoutTest(storage, pos, isSingleOut,SecurityUtils.getCurrentUsername()); String outResult = taskService.checkoutTest(storage, pos, isSingleOut,SecurityUtils.getCurrentUsername(),true);
if (!Strings.isNullOrEmpty(outResult)) { if (!Strings.isNullOrEmpty(outResult)) {
throw new ValidateException("smfcore.error", outResult); throw new ValidateException("smfcore.error", outResult);
} }
......
...@@ -107,4 +107,5 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> { ...@@ -107,4 +107,5 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
StoragePos getSpEmptyPosByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds,String endStr) throws ValidateException; StoragePos getSpEmptyPosByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds,String endStr) throws ValidateException;
void saveMergePos(StoragePos storagePos);
} }
...@@ -1176,4 +1176,9 @@ public class StoragePosManagerImpl implements IStoragePosManager { ...@@ -1176,4 +1176,9 @@ public class StoragePosManagerImpl implements IStoragePosManager {
StoragePos pos = storagePosDao.findOne(query); StoragePos pos = storagePosDao.findOne(query);
return pos; return pos;
} }
@Override
public void saveMergePos(StoragePos storagePos) {
storagePosDao.save(storagePos);
}
} }
...@@ -207,6 +207,10 @@ public class Storage extends BasePo implements Serializable { ...@@ -207,6 +207,10 @@ public class Storage extends BasePo implements Serializable {
return DeviceType.SMD_XLC.name().equals(type); return DeviceType.SMD_XLC.name().equals(type);
} }
public boolean isNLPHBShelf() {
return DeviceType.NLP_HB.name().equals(type);
}
public boolean isType(DeviceType[] types){ public boolean isType(DeviceType[] types){
for (DeviceType str : for (DeviceType str :
types) { types) {
......
...@@ -157,7 +157,7 @@ public class SettingsController { ...@@ -157,7 +157,7 @@ public class SettingsController {
List<Storage> storages = new ArrayList<>(dataCache.getAllStorage().values()); List<Storage> storages = new ArrayList<>(dataCache.getAllStorage().values());
for (Storage storage : storages for (Storage storage : storages
) { ) {
if (storage.isType(new DeviceType[]{DeviceType.NLP,DeviceType.NL,DeviceType.NLS})) { if (storage.isType(new DeviceType[]{DeviceType.NLP,DeviceType.NL,DeviceType.NLS,DeviceType.NLP_HB})) {
orderSetting.setShowLightType(true); orderSetting.setShowLightType(true);
break; break;
} }
...@@ -222,6 +222,10 @@ public class SettingsController { ...@@ -222,6 +222,10 @@ public class SettingsController {
orderSetting.setAppendData(appendData); orderSetting.setAppendData(appendData);
} }
OrderSetting cacheOrderSetting = dataCache.getOrderSetting();
orderSetting.setShelfLightType(cacheOrderSetting.getShelfLightType());
orderSetting.setShelfConfigPutIn(cacheOrderSetting.isShelfConfigPutIn());
dataCache.updateCache(Constants.CACHE_OrderSetting, orderSetting); dataCache.updateCache(Constants.CACHE_OrderSetting, orderSetting);
dataCache.updateCache(Constants.CACHE_closeWorkOrder,orderSetting.isCloseWorkOrder()); dataCache.updateCache(Constants.CACHE_closeWorkOrder,orderSetting.isCloseWorkOrder());
log.info("更改工单设置:"+Constants.CACHE_OrderSetting+"=" + orderSetting.toString()); log.info("更改工单设置:"+Constants.CACHE_OrderSetting+"=" + orderSetting.toString());
...@@ -352,4 +356,15 @@ public class SettingsController { ...@@ -352,4 +356,15 @@ public class SettingsController {
} }
return ResultBean.newOkResult(QRCodeLogin); return ResultBean.newOkResult(QRCodeLogin);
} }
@ApiOperation("修改料架设置")
@PutMapping("/shelf")
public ResultBean updateShelfSetting(@RequestBody OrderSetting orderSetting) {
OrderSetting cacheOrderSetting = dataCache.getOrderSetting();
cacheOrderSetting.setShelfConfigPutIn(orderSetting.isShelfConfigPutIn());
cacheOrderSetting.setShelfLightType(orderSetting.getShelfLightType());
dataCache.updateCache(Constants.CACHE_OrderSetting, cacheOrderSetting);
return ResultBean.newOkResult("保存成功");
}
} }
...@@ -17,4 +17,6 @@ public interface IDataLogManager extends IBaseManager<DataLog> { ...@@ -17,4 +17,6 @@ public interface IDataLogManager extends IBaseManager<DataLog> {
List<SpDailyLog> getSpDailyLogs(Date start, Date end, String inoutType); List<SpDailyLog> getSpDailyLogs(Date start, Date end, String inoutType);
List<SpDailyLog> getSpPnSummaryLists(String inoutType); List<SpDailyLog> getSpPnSummaryLists(String inoutType);
DataLog findOne(Query query);
} }
...@@ -83,4 +83,9 @@ public class DataLogManagerImpl implements IDataLogManager { ...@@ -83,4 +83,9 @@ public class DataLogManagerImpl implements IDataLogManager {
return dataLogDao.getSpPnSummaryLists( inoutType ); return dataLogDao.getSpPnSummaryLists( inoutType );
} }
@Override
public DataLog findOne(Query query) {
return dataLogDao.findOne(query);
}
} }
...@@ -502,10 +502,12 @@ public class DataLog extends BasePo implements Serializable ,Comparable<DataLog> ...@@ -502,10 +502,12 @@ public class DataLog extends BasePo implements Serializable ,Comparable<DataLog>
* @param <T> * @param <T>
* @return * @return
*/ */
public <T> T getAppendData(String appendKey){ public <T> T getAppendData(String appendKey) {
if (appendData != null) {
Object value = appendData.get(appendKey); Object value = appendData.get(appendKey);
if(value != null){ if (value != null) {
return (T)value; return (T) value;
}
} }
return null; return null;
} }
......
...@@ -143,7 +143,7 @@ public class TaskService { ...@@ -143,7 +143,7 @@ public class TaskService {
/** /**
* 库位出库 测试,空库位也可以出库 * 库位出库 测试,空库位也可以出库
*/ */
public synchronized String checkoutTest(Storage storage, StoragePos pos, boolean isSingleOut, String opUserName) throws ValidateException { public synchronized String checkoutTest(Storage storage, StoragePos pos, boolean isSingleOut, String opUserName,boolean posCheckout) throws ValidateException {
DataLog task = new DataLog(storage, pos.getBarcode(), pos); DataLog task = new DataLog(storage, pos.getBarcode(), pos);
...@@ -156,6 +156,9 @@ public class TaskService { ...@@ -156,6 +156,9 @@ public class TaskService {
task.setStatus(OP_STATUS.WAIT.name()); task.setStatus(OP_STATUS.WAIT.name());
task.setSingleOut(isSingleOut); task.setSingleOut(isSingleOut);
task.setOperator(opUserName); task.setOperator(opUserName);
if(posCheckout){
task.updateAppendData("posCheckout",true);
}
addTaskToExecute(task); addTaskToExecute(task);
return ""; return "";
} }
......
...@@ -67,7 +67,10 @@ public class HaierIndiaSpApi extends BaseSmfApiListener { ...@@ -67,7 +67,10 @@ public class HaierIndiaSpApi extends BaseSmfApiListener {
// OP_TIME STRING 操作时间,必填,格式:yyyy-MM-dd HH:mm:ss // OP_TIME STRING 操作时间,必填,格式:yyyy-MM-dd HH:mm:ss
Barcode barcode = barcodeManager.get(task.getBarcode()); Barcode barcode = barcodeManager.findByBarcode(task.getBarcode());
if(barcode==null){
log.error("TaskStatusChange 未找到barcode:"+task.getBarcode()+", taskPosName="+task.getPosName());
}
int opType = -1; int opType = -1;
if (task.isCheckOutTask()) { if (task.isCheckOutTask()) {
//4领用 //4领用
...@@ -75,7 +78,10 @@ public class HaierIndiaSpApi extends BaseSmfApiListener { ...@@ -75,7 +78,10 @@ public class HaierIndiaSpApi extends BaseSmfApiListener {
} else if (task.isPutInTask()) { } else if (task.isPutInTask()) {
StoragePos pos = storagePosManager.getByPosName(task.getPosName()); StoragePos pos = storagePosManager.getByPosName(task.getPosName());
if (!pos.isWarmPos()) { if(pos==null){
log.error("TaskStatusChange 未找到PosName:"+task.getPosName());
}
else if (!pos.isWarmPos()) {
//入库到冷藏区, 1入冰箱 //入库到冷藏区, 1入冰箱
opType = 1; opType = 1;
} }
...@@ -99,19 +105,20 @@ public class HaierIndiaSpApi extends BaseSmfApiListener { ...@@ -99,19 +105,20 @@ public class HaierIndiaSpApi extends BaseSmfApiListener {
Map<String, Object> param = new HashMap<>(); Map<String, Object> param = new HashMap<>();
Map<String, String> dataMap = new HashMap<>(); Map<String, String> dataMap = new HashMap<>();
dataMap.put("STATUS", opType + ""); dataMap.put("STATUS", opType + "");
dataMap.put("ITEM_SN", barcode.getBarcode()); dataMap.put("ITEM_SN", barcode.getFullCode());
String time = DateUtil.toDateString(task.getUpdateDate(), DateUtil.DATE_PATTERN); String time = DateUtil.toDateString(task.getUpdateDate(), DateUtil.DATE_PATTERN);
dataMap.put("OP_TIME", time); dataMap.put("OP_TIME", time);
param.put("date", dataMap); dataMap.put("EMP","192024694");
param.put("data", dataMap);
log.info("TaskStatusChange,url=" + url + ",发送数据=" + JsonUtil.toJsonStr(param) ); log.info("TaskStatusChange,url=" + url + ",发送数据=" + JsonUtil.toJsonStr(param) );
String result = HttpHelper.postJson(url, param); String result = HttpHelper.postJson(url, param);
log.info("TaskStatusChange,url=" + url + ",收到数据=" + result); log.info("TaskStatusChange,url=" + url + ",收到数据=" + result);
return true; return true;
} catch (ApiException apiException) { } catch (ApiException apiException) {
log.info("TaskStatusChange,url=" + url + " apiException " + apiException.toString()); log.info("TaskStatusChange,url=" + url + " apiException " + apiException.getMessage());
} catch (Exception exception) { } catch (Exception exception) {
log.info("TaskStatusChange,url=" + url + " apiException " + exception.toString()); log.info("TaskStatusChange,url=" + url + " apiException " + exception.getMessage());
} }
return false; return false;
} }
......
package com.neotel.smfcore.custom.haobo;
import com.neotel.smfcore.core.api.SmfApi;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.DevicesStatusUtil;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.haobo.bean.PosDiff;
import com.neotel.smfcore.custom.haobo.bean.PosTotalDiffResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class HaoBoNlpPosHandler {
@Autowired
private SmfApi smfApi;
@Autowired
private HaoboApi haoboApi;
@Autowired
private DataCache dataCache;
@Autowired
private TaskService taskService;
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
@PostConstruct
private void init() {
scheduledThreadPool.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
String apiName = smfApi.getApiName();
if (haoboApi.isForThisApi(apiName)) {
handlePos();
}
}
}, 30, 5, TimeUnit.SECONDS);
}
private void handlePos() {
for (Storage storage : dataCache.getAllStorage().values()) {
String cid = storage.getCid(); // 提取CID,便于日志定位
if (storage.isNLPHBShelf()) {
// ========== 1. 获取旧数据(空值兜底,避免索引越界) ==========
List<List<String>> oldDeviceData = DevicesStatusUtil.getDeviceData(cid);
// ========== 2. 计算新的差异数据 ==========
List<String> inventoryPosName = haoboApi.getInventoryPosName(cid);
List<String> usedPosNameList = dataCache.getUsedPosNameList(cid);
PosDiff posDiff = calculatePosDiff(inventoryPosName, usedPosNameList);
List<String> newInventoryOnly = posDiff.getInventoryOnly() == null ? new ArrayList<>() : posDiff.getInventoryOnly();
List<String> newUsedOnly = posDiff.getUsedOnly() == null ? new ArrayList<>() : posDiff.getUsedOnly();
List<List<String>> newData = new ArrayList<>();
newData.add(newInventoryOnly);
newData.add(newUsedOnly);
//3.开始新增差异信息,亮灯或者灭灯
PosTotalDiffResult posTotalDiffResult = calculateAndPrintPosDiff(oldDeviceData, newData);
List<String> totalAddList = posTotalDiffResult.getTotalAddList();
List<String> totalReduceList = posTotalDiffResult.getTotalReduceList();
haoboApi.lightUpSomeLampBeads(totalAddList, totalReduceList);
DevicesStatusUtil.updateDeviceData(cid, newData);
}
}
}
/**
* 计算并打印新旧货位数据的差异,同时返回合并后的总新增/总减少列表
*
* @param oldDeviceData 旧设备数据(二维列表:[库存独有列表, 已用独有列表])
* @param newData 新计算的差异数据(二维列表:[库存独有列表, 已用独有列表])
* @return PosTotalDiffResult 合并后的总新增、总减少货位列表
*/
private PosTotalDiffResult calculateAndPrintPosDiff(List<List<String>> oldDeviceData, List<List<String>> newData) {
// ========== 1. 解析旧数据(空值兜底) ==========
List<String> oldInventoryOnly = new ArrayList<>();
List<String> oldUsedOnly = new ArrayList<>();
if (oldDeviceData != null && !oldDeviceData.isEmpty()) {
oldInventoryOnly = oldDeviceData.size() >= 1 ? oldDeviceData.get(0) : new ArrayList<>();
oldUsedOnly = oldDeviceData.size() >= 2 ? oldDeviceData.get(1) : new ArrayList<>();
}
oldInventoryOnly = oldInventoryOnly == null ? new ArrayList<>() : oldInventoryOnly;
oldUsedOnly = oldUsedOnly == null ? new ArrayList<>() : oldUsedOnly;
// ========== 2. 解析新数据(空值兜底) ==========
List<String> newInventoryOnly = new ArrayList<>();
List<String> newUsedOnly = new ArrayList<>();
if (newData != null && !newData.isEmpty()) {
newInventoryOnly = newData.size() >= 1 ? newData.get(0) : new ArrayList<>();
newUsedOnly = newData.size() >= 2 ? newData.get(1) : new ArrayList<>();
}
newInventoryOnly = newInventoryOnly == null ? new ArrayList<>() : newInventoryOnly;
newUsedOnly = newUsedOnly == null ? new ArrayList<>() : newUsedOnly;
// ========== 3. 计算细分维度差异 ==========
Set<String> oldInventorySet = new HashSet<>(oldInventoryOnly);
Set<String> newInventorySet = new HashSet<>(newInventoryOnly);
Set<String> inventoryAdd = new HashSet<>(newInventorySet);
inventoryAdd.removeAll(oldInventorySet);
Set<String> inventoryReduce = new HashSet<>(oldInventorySet);
inventoryReduce.removeAll(newInventorySet);
Set<String> oldUsedSet = new HashSet<>(oldUsedOnly);
Set<String> newUsedSet = new HashSet<>(newUsedOnly);
Set<String> usedAdd = new HashSet<>(newUsedSet);
usedAdd.removeAll(oldUsedSet);
Set<String> usedReduce = new HashSet<>(oldUsedSet);
usedReduce.removeAll(newUsedSet);
// ========== 4. 合并总差异(去重)并转List ==========
Set<String> totalAddSet = new HashSet<>();
totalAddSet.addAll(inventoryAdd);
totalAddSet.addAll(usedAdd);
List<String> totalAddList = new ArrayList<>(totalAddSet); // 转List更易用
Set<String> totalReduceSet = new HashSet<>();
totalReduceSet.addAll(inventoryReduce);
totalReduceSet.addAll(usedReduce);
List<String> totalReduceList = new ArrayList<>(totalReduceSet); // 转List更易用
// ========== 6. 返回合并后的差异结果 ==========
return new PosTotalDiffResult(totalAddList, totalReduceList);
}
/**
* 计算两个货位名称列表的双向差集(纯String类型,无DataItem依赖)
*
* @param inventoryPosNameList 库存货位名称列表
* @param usedPosNameList 已用货位名称列表
* @return PosDiff inventoryOnly=库存有但已用无的名称列表 | usedOnly=已用有但库存无的名称列表
*/
private PosDiff calculatePosDiff(List<String> inventoryPosNameList, List<String> usedPosNameList) {
// 1. 空值兜底:避免NPE
List<String> safeInventoryNames = inventoryPosNameList == null ? new ArrayList<>() : inventoryPosNameList;
List<String> safeUsedNames = usedPosNameList == null ? new ArrayList<>() : usedPosNameList;
// 2. 转Set去重+提高差集计算效率(纯String操作)
Set<String> inventoryPosSet = new HashSet<>(safeInventoryNames);
Set<String> usedPosSet = new HashSet<>(safeUsedNames);
// 3. 计算:库存有但已用无的货位名称列表
Set<String> inventoryOnlySet = new HashSet<>(inventoryPosSet);
inventoryOnlySet.removeAll(usedPosSet);
List<String> inventoryOnly = new ArrayList<>(inventoryOnlySet);
// 4. 计算:已用有但库存无的货位名称列表
Set<String> usedOnlySet = new HashSet<>(usedPosSet);
usedOnlySet.removeAll(inventoryPosSet);
List<String> usedOnly = new ArrayList<>(usedOnlySet);
// 5. 返回纯String类型的差集结果
return new PosDiff(inventoryOnly, usedOnly);
}
}
package com.neotel.smfcore.custom.haobo;
import com.alibaba.fastjson.JSON;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.enums.SOLDER_STATUS;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
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_STATUS;
import com.neotel.smfcore.core.device.handler.impl.BaseDeviceHandler;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.enums.ORDER_COLOR;
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.bean.OrderSetting;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.haobo.bean.request.InStockCallbackRequest;
import com.neotel.smfcore.custom.haobo.bean.request.OutStockCallbackRequest;
import com.neotel.smfcore.custom.haobo.bean.response.HaoBoApiResponse;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
@RestController
@RequestMapping("/hbNlp")
public class HaoboNlpController {
@Autowired
private TaskService taskService;
@Autowired
private DataCache dataCache;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private IBarcodeManager barcodeManager;
@ApiOperation("入库完成回调")
@RequestMapping("/inStockCallback")
@AnonymousAccess
public HaoBoApiResponse inStockCallback(@RequestBody InStockCallbackRequest request) {
log.info("收到入库完成回调信息:" + JSON.toJSONString(request));
DataLog dataLog = null;
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (queueTask.getBarcode().equals(request.getLabelId())) {
if (queueTask.isPutInTask() && queueTask.isWait()) {
dataLog = queueTask;
break;
}
}
}
if (dataLog == null) {
return new HaoBoApiResponse(false, "未找到对应的入库任务");
}
StoragePos pos = storagePosManager.getByPosName(request.getLocation());
if (pos == null) {
return new HaoBoApiResponse(false, "未找到对应的库位");
}
if (pos.getBarcode() != null) {
return new HaoBoApiResponse(false, "库位已被占用");
}
Storage storage = dataCache.getStorageById(pos.getStorageId());
dataLog.setCid(storage.getCid());
dataLog.setPosId(pos.getId());
dataLog.setPosName(pos.getPosName());
dataLog.setStorageId(storage.getId());
dataLog.setStorageName(storage.getName());
updatePutInData(dataLog);
return new HaoBoApiResponse(true, "入库完成");
}
@ApiOperation("出库完成回调")
@RequestMapping("/outStockCallback")
@AnonymousAccess
public HaoBoApiResponse outStockCallback(@RequestBody OutStockCallbackRequest request) {
log.info("收到出库完成回调信息:" + JSON.toJSONString(request));
DataLog dataLog = null;
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (queueTask.getBarcode().equals(request.getLabelId())) {
if (queueTask.isCheckOutTask() && (queueTask.isWait() || queueTask.isExecuting())) {
dataLog = queueTask;
break;
}
}
}
if (dataLog != null) {
updateCheckoutData(dataLog, OP_STATUS.FINISHED);
return new HaoBoApiResponse(true, "出库完成");
} else {
//判断在不在库位中,如果不在库位中,则忽略
StoragePos pos = storagePosManager.getByBarcode(request.getLabelId());
if (pos == null) {
if (StringUtils.isNotEmpty(request.getLocation())) {
pos = storagePosManager.getByPosName(request.getLocation());
}
}
if (pos == null || pos.getBarcode() == null) {
log.info("根据库位名称和条码都未找到对应的库存信息,库位名称为:{},唯一码为:{}", request.getLocation(), request.getLabelId());
return new HaoBoApiResponse(true, "根据唯一码或者库位号都未找到对应的库存信息,默认已出库");
}
Storage storage = dataCache.getStorageById(pos.getStorageId());
DataLog createDataLog = new DataLog(storage, pos.getBarcode(), pos);
createDataLog.setType(OP.CHECKOUT);
createDataLog.setOperator("system");
createDataLog = taskService.updateQueueTask(createDataLog);
updateCheckoutData(createDataLog, OP_STATUS.FINISHED);
return new HaoBoApiResponse(true, "出库完成");
}
}
/**
* 入仓位完成
*/
protected void updatePutInData(DataLog task) throws ValidateException {
//从队列里面移除操作
taskService.removeQueueTask(task);
StoragePos storagePos = storagePosManager.get(task.getPosId());
//二维码状态
Barcode barcode = barcodeManager.findByBarcode(task.getBarcode());
if (barcode != null) {
barcode.setUsedCount(barcode.getUsedCount() + 1);
barcode.setPutInTime(System.currentTimeMillis());
barcode.updateSluggishTime(dataCache.getPNsluggishDay(barcode.getPartNumber()));
barcode.setInOpor(task.getOperator());
barcode.setCheckOutDate(null, "");
barcode.setPosName(task.getPosName());
if (barcode.isSolder()) {
if (storagePos.isWarmPos()) {
//回温仓位
barcode.setSolderStatus(SOLDER_STATUS.RETREAT_STORAGE.name());
} else {
barcode.setSolderStatus(SOLDER_STATUS.UNDER_REFRIGERATION.name());
}
barcode.setNeedOutDate(null);
}
barcodeManager.save(barcode);
}
storagePos.setBarcode(barcode);
storagePos.setUsed(true);
storagePos.setCanCheckOutTime(System.currentTimeMillis());
storagePosManager.saveMergePos(storagePos);
if (barcode != null) {
dataCache.updateInventory(storagePos, barcode);
//记录日志,完成 task
task.setBatchInfo(barcode.getBatch());
task.setNum(barcode.getAmount());
task.setProviderNumber(barcode.getProviderNumber());
}
//更新缓存中的库存信息
task.setStatus(OP_STATUS.FINISHED.name());
taskService.updateFinishedTask(task);
}
/**
* 出仓位完成
*/
private void updateCheckoutData(DataLog task, OP_STATUS outBoxStatus) throws ValidateException {
//从队列里面移除操作
taskService.removeQueueTask(task);
StoragePos storagePos = storagePosManager.get(task.getPosId());
Barcode barcode = storagePos.getBarcode();
if (barcode == null) {
log.warn("任务:" + task.getId() + " 仓位:" + task.getPosId() + " 的 Barcode 为null, 之前可能处理过,结束任务后直接返回");
//记录日志
task.setStatus(outBoxStatus.name());
taskService.updateFinishedTask(task);
return;
}
Barcode barcodeDB = barcodeManager.get(barcode.getId());
if (barcodeDB != null) {
//二维码状态
barcodeDB.setUsed(true);
barcodeDB.setUsedDate(new Date());
//仓位状态
barcodeDB.setCheckOutDate(new Date(), task.getOperator());
barcodeDB.setPosName("");
barcodeManager.save(barcodeDB);
task.setBatchInfo(barcodeDB.getBatch());
//记录在库时长
task.setInStoreTime(barcodeDB.getInStoreMiniute());
}
storagePos.setBarcode(null);
storagePos.setUsed(false);
storagePosManager.saveMergePos(storagePos);
log.info("出库完成,清空仓位: " + storagePos.getId() + "[" + storagePos.getPosName() + "]");
//更新缓存中的库存信息
dataCache.updateInventory(storagePos, barcode);
// 调用西门子接口
// SiemensApi.lotInOut(barcode.getBarcode(),2);
//记录日志
task.setStatus(outBoxStatus.name());
taskService.updateFinishedTask(task);
}
}
package com.neotel.smfcore.custom.haobo.bean;
import lombok.Data;
import java.util.List;
@Data
public class PosDiff {
List<String> inventoryOnly;
List<String> usedOnly;
public PosDiff(List<String> inventoryOnly, List<String> usedOnly) {
this.inventoryOnly = inventoryOnly;
this.usedOnly = usedOnly;
}
}
package com.neotel.smfcore.custom.haobo.bean;
import java.util.List;
public class PosTotalDiffResult {
// 所有新增(多的)货位列表
private List<String> totalAddList;
// 所有减少(少的)货位列表
private List<String> totalReduceList;
public PosTotalDiffResult(List<String> totalAddList, List<String> totalReduceList) {
this.totalAddList = totalAddList;
this.totalReduceList = totalReduceList;
}
// Getter方法(用于外部获取返回值)
public List<String> getTotalAddList() {
return totalAddList;
}
public List<String> getTotalReduceList() {
return totalReduceList;
}
}
package com.neotel.smfcore.custom.haobo.bean.request;
import lombok.Data;
@Data
public class InStockCallbackRequest {
private String labelId;
private String location;
private String detailsJson;
}
package com.neotel.smfcore.custom.haobo.bean.request;
import lombok.Data;
@Data
public class OutStockCallbackRequest {
private String labelId;
private String location;
private String detailsJson;
}
package com.neotel.smfcore.custom.haobo.bean.response;
import lombok.Data;
import java.util.List;
@Data
public class GetInventoryResponse {
private Result result;
private String targetUrl;
private boolean success;
private Object error;
private boolean unAuthorizedRequest;
@Data
public static class Result {
private boolean success;
private String message;
private List<DataItem> data;
}
@Data
public static class DataItem {
private String location;
private String labelId;
private String shelfCode;
private String operationTime;
private int status;
private String externalLocation;
private String presentInductionLocation;
private String transferShelfCode;
private String inStockDetailsJson;
private String outStockDetailsJson;
private boolean inStockCallbackSuccess;
private int inStockCallbackNum;
private boolean outStockCallbackSuccess;
private int outStockCallbackNum;
private String updateTime;
private long hardwareTime;
private String materialCode;
private String materialName;
private String materialSpec;
private Integer materialQuantity;
private String productionDate;
private String timeout;
private int id;
}
}
\ No newline at end of file \ No newline at end of file
package com.neotel.smfcore.custom.haobo.bean.response;
import lombok.Data;
@Data
public class HaoBoApiResponse {
private boolean success;
private String message;
private Object data;
public HaoBoApiResponse(boolean success,String message) {
this.message = message;
this.success = success;
this.data = null;
}
}
package com.neotel.smfcore.custom.jiahe1671;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.utils.CodeResolve;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@Api(tags = "客户端对接")
@Slf4j
@RestController
@RequestMapping("/1671device")
public class JiaHe1671DeviceController {
@Autowired
private CodeResolve codeResolve;
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@ApiOperation("根据barcode获取最后一条出库任务对应的站位信息")
@RequestMapping("/getLastestOrderTask")
@ResponseBody
@AnonymousAccess
public ResultBean getLastestOrderTask(@RequestBody Map<String, String> paramMap) {
String code = paramMap.get("code");
log.info("收到获取站位信息:" + code);
Barcode barcode = null;
try {
barcode = codeResolve.resolveOneValideBarcode(code);
} catch (ValidateException e) {
return ResultBean.newErrorResult(-1, e.getMsgKey(), e.getMessage(), e.getMsgParam());
}
//开始寻找最后一条任务
Criteria c = Criteria.where("barcode").is(barcode.getBarcode());
Query query = new Query(c);
query.with(Sort.by(Sort.Direction.DESC,"createDate"));
DataLog dataLog = dataLogManager.findOne(query);
if (dataLog != null && dataLog.isCheckOutTask()){
String subSourceId = dataLog.getSubSourceId();
if (StringUtils.isNotBlank(subSourceId)){
LiteOrderItem item = liteOrderItemManager.get(subSourceId);
if (item != null){
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("slotNum",item.getSlotNum());
resultMap.put("feederInfo",item.getFeederInfo());
resultMap.put("barcode",barcode.getBarcode());
resultMap.put("partNumber",barcode.getPartNumber());
resultMap.put("w",dataLog.getW());
resultMap.put("h",dataLog.getH());
return ResultBean.newOkResult(resultMap);
}
}
}
return ResultBean.newErrorResult(-1,"smfcore.barcode.notFindFeerder","未找到[{0}]站位信息",new String[]{barcode.getBarcode()});
}
}
package com.neotel.smfcore.custom.jiahe1671;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.neotel.NeotelApi;
import org.springframework.stereotype.Service;
@Service
public class JiaHeApi extends NeotelApi {
@Override
public boolean isForThisApi(String apiName) {
return apiName != null && apiName.equalsIgnoreCase("JiaHe");
}
@Override
public void outTaskStatusChange(String outNotifyUrl, DataLog task) {
String operator = task.getOperator();
if (StringUtils.isNotEmpty(operator)) {
if (operator.contains("move")) {
return;
}
}
super.outTaskStatusChange(outNotifyUrl, task);
}
@Override
public void inTaskStatusChange(String inNotifyUrl, DataLog task) {
String operator = task.getOperator();
if (StringUtils.isNotEmpty(operator)) {
if (operator.contains("move")) {
return;
}
}
super.inTaskStatusChange(inNotifyUrl, task);
}
}
package com.neotel.smfcore.custom.neotel; package com.neotel.smfcore.custom.neotel;
import com.alibaba.fastjson.JSON;
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.bean.ResultBean; import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.JsonUtil; import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.StorageConstants; import com.neotel.smfcore.common.utils.StorageConstants;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
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.device.bean.BoxStatusBean; import com.neotel.smfcore.core.device.bean.BoxStatusBean;
import com.neotel.smfcore.core.device.bean.StatusBean; import com.neotel.smfcore.core.device.bean.StatusBean;
import com.neotel.smfcore.core.device.util.DataCache; import com.neotel.smfcore.core.device.util.DataCache;
...@@ -18,6 +22,7 @@ import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager; ...@@ -18,6 +22,7 @@ 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.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos; import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.util.DevicesStatusUtil; import com.neotel.smfcore.core.system.util.DevicesStatusUtil;
import com.neotel.smfcore.custom.neotel.bean.XrayUploadResult;
import com.neotel.smfcore.security.annotation.AnonymousAccess; import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.neotel.smfcore.security.annotation.AnonymousPostMapping; import com.neotel.smfcore.security.annotation.AnonymousPostMapping;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
...@@ -47,6 +52,11 @@ public class NeotelController { ...@@ -47,6 +52,11 @@ public class NeotelController {
@Autowired @Autowired
private IStoragePosManager storagePosManager; private IStoragePosManager storagePosManager;
@Autowired
private CodeResolve codeResolve;
@Autowired
private IBarcodeManager barcodeManager;
@ApiOperation("6.1创建需求单") @ApiOperation("6.1创建需求单")
@RequestMapping("/outInfo") @RequestMapping("/outInfo")
...@@ -258,4 +268,30 @@ public class NeotelController { ...@@ -258,4 +268,30 @@ public class NeotelController {
return ResultBean.newOkResult(results); return ResultBean.newOkResult(results);
} }
@ApiOperation("6.5 点料结果上传")
@RequestMapping("/xrayUploadResult")
@AnonymousAccess
public ResultBean xrayUploadResult(@RequestBody XrayUploadResult xrayUploadResult) {
log.info("收到点料信息上传:" + JSON.toJSONString(xrayUploadResult));
String reelId = xrayUploadResult.getReelId();
int qty = xrayUploadResult.getQty();
//解析条码是否存在
Barcode barcode = codeResolve.resolveOneValideBarcode(reelId);
if (barcode == null) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.invalid", "{0}不是有效的条码", new String[]{reelId});
}
//判断数量是否为0
if (qty <= 0) {
throw new ValidateException("smfcore.error.barcode.wrongQty", "条码[{0}]对应的数量<=0为: {1}", new String[]{reelId, qty + ""});
}
//判断是否在库存中
StoragePos pos = storagePosManager.getByBarcode(reelId);
if (pos != null) {
//smfcore.materialBox.inPos=物料已在库位{0}中
return ResultBean.newErrorResult(-1, "smfcore.materialBox.inPos", "物料已在库位{0}中", new String[]{pos.getPosName()});
}
barcode.setAmount(qty);
barcodeManager.save(barcode);
return ResultBean.newOkResult("");
}
} }
package com.neotel.smfcore.custom.neotel.bean;
import lombok.Data;
@Data
public class XrayUploadResult {
private String reelId;
private int qty;
}
package com.neotel.smfcore.custom.so1374.bean;
import lombok.Data;
/**
* 入库/退货请求实体类 (PokaNon INBOUND/RETURN Request)
* 对应I/F 定義表的字段规范
*/
@Data // Lombok注解,自动生成getter/setter/toString/equals/hashCode
public class PokaNonInboundReturnRequest {
/**
* PokaNon交易ID(幂等键)
* 类型:string | 必填:Y
* 示例:POKANON-INB-20260124-000123
*/
private String clientTxnId;
/**
* 客户编码(Panasonic可能固定)
* 类型:string | 必填:Y
* 示例:PANASONIC
*/
private String customerCode;
/**
* 操作类型:INBOUND(新品入库) / RETURN(退货重新入库)
* 类型:string | 必填:Y
* 示例:INBOUND
*/
private String operation;
/**
* 操作人员信息
* 类型:object | 必填:Y(子字段operatorId必填)
*/
private Operator operator;
/**
* 物料信息
* 类型:object | 必填:Y(核心子字段必填)
*/
private Material material;
/**
* 库位信息
* 类型:object | 必填:Y(子字段locationId必填)
*/
private Location location;
/**
* 标签信息
* 类型:object | 必填:N
*/
private Label label;
/**
* 客户端时间戳(审计用)
* 类型:string | 必填:N
* 格式:YYYY-MM-DD HH:mm:ss
* 示例:2026-01-24 10:12:30
*/
private String timestamp;
/**
* 操作人员子实体
*/
@Data
public static class Operator {
/**
* 操作人员ID
* 类型:string | 必填:Y
* 示例:U001
*/
private String operatorId;
}
/**
* 物料子实体
*/
@Data
public static class Material {
/**
* PokaNon序列号(标签序列号)
* 类型:string | 必填:Y
* 示例:ID-2026012400001-001
*/
private String serial;
/**
* 主物料编号(建议必填)
* 类型:string | 必填:Y*
* 示例:GLOBAL-PN-001
*/
private String partNo;
/**
* 制造商物料编号
* 类型:string | 必填:N
* 示例:ABC-123
*/
private String makerPartNo;
/**
* 内部批次号(如有)
* 类型:string | 必填:N
* 示例:LOT202601
*/
private String lotNo;
/**
* 制造商批次号
* 类型:string | 必填:N
* 示例:MLOT-5566
*/
private String makerLot;
/**
* 实际入库数量(已确认)
* 类型:number | 必填:Y
* 示例:500
*/
private Integer qty;
/**
* 计量单位
* 类型:string | 必填:N
* 示例:PCS
*/
private String uom;
/**
* 接收日期
* 类型:date | 必填:N
* 格式:YYYY-MM-DD
* 示例:2026-01-24
*/
private String receiveDate; // 用String避免日期序列化问题,也可改用LocalDate
/**
* 有效期
* 类型:date | 必填:N
* 格式:YYYY-MM-DD
* 示例:2027-01-31
*/
private String expireDate; // 同上
}
/**
* 库位子实体
*/
@Data
public static class Location {
/**
* SMF库位地址(扫描的QR文本)
* 类型:string | 必填:Y
* 示例:R01-S03
*/
private String locationId;
/**
* 库位类型(固定字面量,避免混淆)
* 类型:string | 必填:N
* 示例:SMF_ADDRESS
*/
private String locationType;
}
/**
* 标签子实体
*/
@Data
public static class Label {
/**
* 原始标签QR文本(可选存储/校验)
* 类型:string | 必填:N
* 示例:(raw QR text)
*/
private String fullCode;
/**
* QR标签上打印的数量(参考用)
* 类型:number | 必填:N
* 示例:500
*/
private Integer qrQty;
}
}
\ No newline at end of file \ No newline at end of file
...@@ -18,6 +18,7 @@ import com.neotel.smfcore.core.barcode.service.po.Component; ...@@ -18,6 +18,7 @@ import com.neotel.smfcore.core.barcode.service.po.Component;
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 com.neotel.smfcore.core.system.service.po.DataLog; import com.neotel.smfcore.core.system.service.po.DataLog;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings; import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -29,6 +30,12 @@ import java.util.*; ...@@ -29,6 +30,12 @@ import java.util.*;
@Service @Service
@Slf4j @Slf4j
public class SpApi extends BaseSmfApiListener { public class SpApi extends BaseSmfApiListener {
//api:
// name: sp
// codeResolveUrl: http://172.30.11.214:8036/SmartRefrigerator/warehousing
// inNotifyUrl: http://172.30.11.214:8036/SmartRefrigerator/warehousingStatus
// outNotifyUrl: http://172.30.11.214:8036/SmartRefrigerator/exitWarehouseStatus
// taskNotifyUrl: http://172.30.11.214:8036/SmartRefrigerator/exitWarehouseStatus
@Autowired @Autowired
IBarcodeManager barcodeManager; IBarcodeManager barcodeManager;
...@@ -109,9 +116,25 @@ public class SpApi extends BaseSmfApiListener { ...@@ -109,9 +116,25 @@ public class SpApi extends BaseSmfApiListener {
} }
String produceDateStr = getData(dataMap, "produceDate"); String produceDateStr = getData(dataMap, "produceDate");
if (Strings.isNotBlank(produceDateStr)) { if (Strings.isNotBlank(produceDateStr)) {
Date produceDate = DateUtil.toDate(produceDateStr, "yyyy-MM-dd HH:mm:ss"); Date produceDate = null;
try {
produceDate = DateUtil.toDate(produceDateStr, "yyyy-MM-dd HH:mm:ss");
} catch (Exception ex) {
log.error("生成日期["+produceDateStr+"]转换出错:"+ex.toString());
}
if (produceDate == null) {
try {
produceDate = DateUtil.toDate(produceDateStr, "yyyyMMdd");
} catch (Exception ex) {
log.error("生成日期["+produceDateStr+"]转换出错:"+ex.toString());
}
}
if (produceDate != null) {
log.info("保存生成日期:["+produceDate.toString()+"]");
barcode.setProduceDate(produceDate); barcode.setProduceDate(produceDate);
} }
}
String expireDateStr = getData(dataMap, "expireDate"); String expireDateStr = getData(dataMap, "expireDate");
if (Strings.isNotBlank(expireDateStr)) { if (Strings.isNotBlank(expireDateStr)) {
...@@ -182,6 +205,12 @@ public class SpApi extends BaseSmfApiListener { ...@@ -182,6 +205,12 @@ public class SpApi extends BaseSmfApiListener {
paramMap.put("mixRSpeed", mrSpeed + ""); paramMap.put("mixRSpeed", mrSpeed + "");
} }
paramMap.put("currTime", DateUtil.toDateString(new Date(), "yyyy-MM-dd HH:mm:ss")); paramMap.put("currTime", DateUtil.toDateString(new Date(), "yyyy-MM-dd HH:mm:ss"));
Boolean posCheckout=task.getAppendData("posCheckout");
if(posCheckout==null){
posCheckout=false;
}
paramMap.put("posCheckout",posCheckout);
try { try {
log.info(task.getBarcode() + "出库通知,参数" + JsonUtil.toJsonStr(paramMap)); log.info(task.getBarcode() + "出库通知,参数" + JsonUtil.toJsonStr(paramMap));
String result = HttpHelper.postJson(outNotifyUrl, paramMap); String result = HttpHelper.postJson(outNotifyUrl, paramMap);
......
...@@ -188,6 +188,7 @@ smfcore.storagePos.lockName=\u5DE5\u5355\u53F7 ...@@ -188,6 +188,7 @@ smfcore.storagePos.lockName=\u5DE5\u5355\u53F7
smfcore.storagePos.amount=\u6570\u91CF smfcore.storagePos.amount=\u6570\u91CF
smfcore.storagePos.putInTime=\u9996\u6B21\u5165\u5E93\u65F6\u95F4 smfcore.storagePos.putInTime=\u9996\u6B21\u5165\u5E93\u65F6\u95F4
smfcore.storagePos.putInDate=\u5165\u5E93\u65F6\u95F4 smfcore.storagePos.putInDate=\u5165\u5E93\u65F6\u95F4
smfcore.storagePos.provider=\u4F9B\u5E94\u5546
smfcore.inventory.partNumber=\u7269\u6599\u7F16\u53F7 smfcore.inventory.partNumber=\u7269\u6599\u7F16\u53F7
smfcore.inventory.count=\u6570\u91CF smfcore.inventory.count=\u6570\u91CF
smfcore.inventory.lockReel=\u9501\u5B9A smfcore.inventory.lockReel=\u9501\u5B9A
...@@ -461,4 +462,13 @@ smfcore.reelPosMove.paramerror=\u53C2\u6570\u4E0D\u5B8C\u6574 ...@@ -461,4 +462,13 @@ smfcore.reelPosMove.paramerror=\u53C2\u6570\u4E0D\u5B8C\u6574
smfcore.reelPosMove.posIsNull=\u5E93\u4F4D[{1}]\u4E3A\u7A7A smfcore.reelPosMove.posIsNull=\u5E93\u4F4D[{1}]\u4E3A\u7A7A
smfcore.liteOrder.exist=\u9700\u6C42\u5355{0}\u5DF2\u5B58\u5728 smfcore.liteOrder.exist=\u9700\u6C42\u5355{0}\u5DF2\u5B58\u5728
smfcore.reelPosMove.barcodeError=\u5E93\u4F4D{0}\u6761\u7801\u4E3A{1}\uFF0C\u4E0E\u79FB\u5E93\u6761\u7801{1}\u4E0D\u4E00\u81F4 smfcore.reelPosMove.barcodeError=\u5E93\u4F4D{0}\u6761\u7801\u4E3A{1}\uFF0C\u4E0E\u79FB\u5E93\u6761\u7801{1}\u4E0D\u4E00\u81F4
smfcore.barcode.notFindFeerder=\u672A\u627E\u5230[{0}]\u7AD9\u4F4D\u4FE1\u606F
smfcore.pos.merge.notNull=\u5E93\u4F4D\u4E0D\u80FD\u4E3A\u7A7A
smfcore.pos.merge.numError=\u8BF7\u9009\u62E9[{0}]\u4E2A\u8981\u5408\u5E76\u7684\u5E93\u4F4D
smfcore.pos.merge.hasMaterial=\u5E93\u4F4D[{0}]\u6709\u7269\u6599,\u4E0D\u80FD\u5408\u5E76
smfcore.pos.merge.hasMergePos=\u5E93\u4F4D[{0}]\u5DF2\u5408\u5E76,\u4E0D\u80FD\u7EE7\u7EED\u5408\u5E76
smfcore.pos.merge.notAdjacent=\u8BF7\u9009\u62E9\u76F8\u90BB\u7684\u5E93\u4F4D\u5408\u5E76
smfcore.pos.split.notNull=\u5E93\u4F4D\u4E0D\u80FD\u4E3A\u7A7A
smfcore.pos.split.notMergePos=\u5E93\u4F4D[{0}]\u672A\u5408\u5E76,\u4E0D\u80FD\u62C6\u5206
smfcore.pos.split.hasMaterial=\u5E93\u4F4D[{0}]\u6709\u7269\u6599,\u4E0D\u80FD\u62C6\u5206
smfcore.selectDevice=\u5408\u5E76\u5E93\u4F4D
...@@ -451,3 +451,14 @@ smfcore.reelPosMove.paramerror=Incomplete Parameter ...@@ -451,3 +451,14 @@ smfcore.reelPosMove.paramerror=Incomplete Parameter
smfcore.reelPosMove.posIsNull=Lagerort [{1}] ist leer smfcore.reelPosMove.posIsNull=Lagerort [{1}] ist leer
smfcore.liteOrder.exist=Bedarfsauftrag {0} existiert bereits smfcore.liteOrder.exist=Bedarfsauftrag {0} existiert bereits
smfcore.reelPosMove.barcodeError=Der Barcode des Lagerorts {0} ist {1}, nicht identisch mit dem Umzugscode {1} smfcore.reelPosMove.barcodeError=Der Barcode des Lagerorts {0} ist {1}, nicht identisch mit dem Umzugscode {1}
smfcore.barcode.notFindFeerder=Stationsinformation [{0}] nicht gefunden
smfcore.storagePos.provider=Lieferant
smfcore.pos.merge.notNull=Lagerposition darf nicht leer sein
smfcore.pos.merge.numError=W\u00E4hlen Sie [{0}] Lagerpositionen zum Zusammenf\u00FChren aus
smfcore.pos.merge.hasMaterial=Lagerposition [{0}] enth\u00E4lt Materialien und kann nicht zusammengef\u00FChrt werden
smfcore.pos.merge.hasMergePos=Lagerposition [{0}] wurde bereits zusammengef\u00FChrt und kann nicht weiter zusammengef\u00FChrt werden
smfcore.pos.merge.notAdjacent=W\u00E4hlen Sie benachbarte Lagerpositionen zum Zusammenf\u00FChren aus
smfcore.pos.split.notNull=Lagerposition darf nicht leer sein
smfcore.pos.split.notMergePos=Lagerposition [{0}] wurde nicht zusammengef\u00FChrt und kann nicht aufgeteilt werden
smfcore.pos.split.hasMaterial=Lagerposition [{0}] enth\u00E4lt Materialien und kann nicht aufgeteilt werden
smfcore.selectDevice=Speicherplatz zusammenf\u00FChren
...@@ -452,3 +452,14 @@ smfcore.reelPosMove.paramerror=Incomplete parameters ...@@ -452,3 +452,14 @@ smfcore.reelPosMove.paramerror=Incomplete parameters
smfcore.reelPosMove.posIsNull=Location [{1}] is empty smfcore.reelPosMove.posIsNull=Location [{1}] is empty
smfcore.liteOrder.exist=Requirement order {0} already exists smfcore.liteOrder.exist=Requirement order {0} already exists
smfcore.reelPosMove.barcodeError=Location {0} barcode is {1}, inconsistent with the transfer barcode {1} smfcore.reelPosMove.barcodeError=Location {0} barcode is {1}, inconsistent with the transfer barcode {1}
smfcore.barcode.notFindFeerder=Station information [{0}] not found
smfcore.storagePos.provider=Provider
smfcore.pos.merge.notNull=Storage position cannot be empty
smfcore.pos.merge.numError=Please select [{0}] storage positions to merge
smfcore.pos.merge.hasMaterial=Storage position [{0}] contains materials and cannot be merged
smfcore.pos.merge.hasMergePos=Storage position [{0}] has been merged and cannot be merged further
smfcore.pos.merge.notAdjacent=Please select adjacent storage positions to merge
smfcore.pos.split.notNull=Storage position cannot be empty
smfcore.pos.split.notMergePos=Storage position [{0}] has not been merged and cannot be split
smfcore.pos.split.hasMaterial=Storage position [{0}] contains materials and cannot be split
smfcore.selectDevice=Merge Storage Location
...@@ -451,3 +451,14 @@ smfcore.reelPosMove.paramerror=Param\u00E8tres incomplets ...@@ -451,3 +451,14 @@ smfcore.reelPosMove.paramerror=Param\u00E8tres incomplets
smfcore.reelPosMove.posIsNull=L'emplacement [{1}] est vide smfcore.reelPosMove.posIsNull=L'emplacement [{1}] est vide
smfcore.liteOrder.exist=Le bon de commande {0} existe d\u00E9j\u00E0 smfcore.liteOrder.exist=Le bon de commande {0} existe d\u00E9j\u00E0
smfcore.reelPosMove.barcodeError=Le code-barres de l'emplacement {0} est {1}, incompatible avec le code-barres de transfert {1} smfcore.reelPosMove.barcodeError=Le code-barres de l'emplacement {0} est {1}, incompatible avec le code-barres de transfert {1}
smfcore.barcode.notFindFeerder=Informations de station [{0}] non trouv\u00E9es
smfcore.storagePos.provider=Fournisseur
smfcore.pos.merge.notNull=L'emplacement de stockage ne peut pas \u00EAtre vide
smfcore.pos.merge.numError=Veuillez s\u00E9lectionner [{0}] emplacements de stockage \u00E0 fusionner
smfcore.pos.merge.hasMaterial=L'emplacement de stockage [{0}] contient des mati\u00E8res et ne peut pas \u00EAtre fusionn\u00E9
smfcore.pos.merge.hasMergePos=L'emplacement de stockage [{0}] a d\u00E9j\u00E0 \u00E9t\u00E9 fusionn\u00E9 et ne peut pas \u00EAtre fusionn\u00E9 davantage
smfcore.pos.merge.notAdjacent=Veuillez s\u00E9lectionner des emplacements de stockage adjacents \u00E0 fusionner
smfcore.pos.split.notNull=L'emplacement de stockage ne peut pas \u00EAtre vide
smfcore.pos.split.notMergePos=L'emplacement de stockage [{0}] n'a pas \u00E9t\u00E9 fusionn\u00E9 et ne peut pas \u00EAtre divis\u00E9
smfcore.pos.split.hasMaterial=L'emplacement de stockage [{0}] contient des mati\u00E8res et ne peut pas \u00EAtre divis\u00E9
smfcore.selectDevice=Fusionner l'emplacement de stockage
...@@ -448,3 +448,14 @@ smfcore.reelPosMove.paramerror=\u30D1\u30E9\u30E1\u30FC\u30BF\u304C\u4E0D\u5B8C\ ...@@ -448,3 +448,14 @@ smfcore.reelPosMove.paramerror=\u30D1\u30E9\u30E1\u30FC\u30BF\u304C\u4E0D\u5B8C\
smfcore.reelPosMove.posIsNull=\u5EAB\u4F4D [{1}] \u304C\u7A7A\u3067\u3059 smfcore.reelPosMove.posIsNull=\u5EAB\u4F4D [{1}] \u304C\u7A7A\u3067\u3059
smfcore.liteOrder.exist=\u8981\u6C42\u5358 {0} \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059 smfcore.liteOrder.exist=\u8981\u6C42\u5358 {0} \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059
smfcore.reelPosMove.barcodeError=\u5EAB\u4F4D {0} \u306E\u30D0\u30FC\u30B3\u30FC\u30C9\u306F {1} \u3067\u3001\u79FB\u5EAB\u30D0\u30FC\u30B3\u30FC\u30C9 {1} \u3068\u4E0D\u4E00\u81F4\u3067\u3059 smfcore.reelPosMove.barcodeError=\u5EAB\u4F4D {0} \u306E\u30D0\u30FC\u30B3\u30FC\u30C9\u306F {1} \u3067\u3001\u79FB\u5EAB\u30D0\u30FC\u30B3\u30FC\u30C9 {1} \u3068\u4E0D\u4E00\u81F4\u3067\u3059
smfcore.barcode.notFindFeerder=[{0}]\u30B9\u30C6\u30FC\u30B7\u30E7\u30F3\u60C5\u5831\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
smfcore.storagePos.provider=\u4F9B\u7D66\u8005
smfcore.pos.merge.notNull=\u68DA\u4F4D\u7F6E\u3092\u7A7A\u306B\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093
smfcore.pos.merge.numError=\u7D71\u5408\u3059\u308B\u68DA\u4F4D\u7F6E\u3092[{0}]\u3064\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044
smfcore.pos.merge.hasMaterial=\u68DA\u4F4D\u7F6E[{0}]\u306B\u8CC7\u6750\u304C\u3042\u308B\u305F\u3081\u3001\u7D71\u5408\u3067\u304D\u307E\u305B\u3093
smfcore.pos.merge.hasMergePos=\u68DA\u4F4D\u7F6E[{0}]\u306F\u65E2\u306B\u7D71\u5408\u3055\u308C\u3066\u3044\u308B\u305F\u3081\u3001\u3055\u3089\u306B\u7D71\u5408\u3067\u304D\u307E\u305B\u3093
smfcore.pos.merge.notAdjacent=\u96A3\u63A5\u3059\u308B\u68DA\u4F4D\u7F6E\u3092\u9078\u629E\u3057\u3066\u7D71\u5408\u3057\u3066\u304F\u3060\u3055\u3044
smfcore.pos.split.notNull=\u68DA\u4F4D\u7F6E\u3092\u7A7A\u306B\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093
smfcore.pos.split.notMergePos=\u68DA\u4F4D\u7F6E[{0}]\u306F\u7D71\u5408\u3055\u308C\u3066\u3044\u306A\u3044\u305F\u3081\u3001\u5206\u5272\u3067\u304D\u307E\u305B\u3093
smfcore.pos.split.hasMaterial=\u68DA\u4F4D\u7F6E[{0}]\u306B\u8CC7\u6750\u304C\u3042\u308B\u305F\u3081\u3001\u5206\u5272\u3067\u304D\u307E\u305B\u3093
smfcore.selectDevice=\u4FDD\u7BA1\u5834\u6240\u3092\u7D71\u5408
...@@ -448,3 +448,14 @@ smfcore.reelPosMove.paramerror=\u53C2\u6570\u4E0D\u5B8C\u6574 ...@@ -448,3 +448,14 @@ smfcore.reelPosMove.paramerror=\u53C2\u6570\u4E0D\u5B8C\u6574
smfcore.reelPosMove.posIsNull=\u5E93\u4F4D[{1}]\u4E3A\u7A7A smfcore.reelPosMove.posIsNull=\u5E93\u4F4D[{1}]\u4E3A\u7A7A
smfcore.liteOrder.exist=\u9700\u6C42\u5355{0}\u5DF2\u5B58\u5728 smfcore.liteOrder.exist=\u9700\u6C42\u5355{0}\u5DF2\u5B58\u5728
smfcore.reelPosMove.barcodeError=\u5E93\u4F4D{0}\u6761\u7801\u4E3A{1}\uFF0C\u4E0E\u79FB\u5E93\u6761\u7801{1}\u4E0D\u4E00\u81F4 smfcore.reelPosMove.barcodeError=\u5E93\u4F4D{0}\u6761\u7801\u4E3A{1}\uFF0C\u4E0E\u79FB\u5E93\u6761\u7801{1}\u4E0D\u4E00\u81F4
smfcore.barcode.notFindFeerder=\u672A\u627E\u5230[{0}]\u7AD9\u4F4D\u4FE1\u606F
smfcore.storagePos.provider=\u4F9B\u5E94\u5546
smfcore.pos.merge.notNull=\u5E93\u4F4D\u4E0D\u80FD\u4E3A\u7A7A
smfcore.pos.merge.numError=\u8BF7\u9009\u62E9[{0}]\u4E2A\u8981\u5408\u5E76\u7684\u5E93\u4F4D
smfcore.pos.merge.hasMaterial=\u5E93\u4F4D[{0}]\u6709\u7269\u6599,\u4E0D\u80FD\u5408\u5E76
smfcore.pos.merge.hasMergePos=\u5E93\u4F4D[{0}]\u5DF2\u5408\u5E76,\u4E0D\u80FD\u7EE7\u7EED\u5408\u5E76
smfcore.pos.merge.notAdjacent=\u8BF7\u9009\u62E9\u76F8\u90BB\u7684\u5E93\u4F4D\u5408\u5E76
smfcore.pos.split.notNull=\u5E93\u4F4D\u4E0D\u80FD\u4E3A\u7A7A
smfcore.pos.split.notMergePos=\u5E93\u4F4D[{0}]\u672A\u5408\u5E76,\u4E0D\u80FD\u62C6\u5206
smfcore.pos.split.hasMaterial=\u5E93\u4F4D[{0}]\u6709\u7269\u6599,\u4E0D\u80FD\u62C6\u5206
smfcore.selectDevice=\u5408\u5E76\u5E93\u4F4D
...@@ -448,3 +448,14 @@ smfcore.reelPosMove.paramerror=\u53C3\u6578\u4E0D\u5B8C\u6574 ...@@ -448,3 +448,14 @@ smfcore.reelPosMove.paramerror=\u53C3\u6578\u4E0D\u5B8C\u6574
smfcore.reelPosMove.posIsNull=\u5EAB\u4F4D [{1}] \u70BA\u7A7A smfcore.reelPosMove.posIsNull=\u5EAB\u4F4D [{1}] \u70BA\u7A7A
smfcore.liteOrder.exist=\u9700\u6C42\u55AE {0} \u5DF2\u5B58\u5728 smfcore.liteOrder.exist=\u9700\u6C42\u55AE {0} \u5DF2\u5B58\u5728
smfcore.reelPosMove.barcodeError=\u5EAB\u4F4D {0} \u689D\u78BC\u70BA {1}\uFF0C\u8207\u79FB\u5EAB\u689D\u78BC {1} \u4E0D\u4E00\u81F4 smfcore.reelPosMove.barcodeError=\u5EAB\u4F4D {0} \u689D\u78BC\u70BA {1}\uFF0C\u8207\u79FB\u5EAB\u689D\u78BC {1} \u4E0D\u4E00\u81F4
smfcore.barcode.notFindFeerder=\u672A\u627E\u5230[{0}]\u7AD9\u4F4D\u8CC7\u8A0A
smfcore.storagePos.provider=\u4F9B\u7D66\u8005
smfcore.pos.merge.notNull=\u5EAB\u4F4D\u4E0D\u80FD\u70BA\u7A7A
smfcore.pos.merge.numError=\u8ACB\u9078\u64C7[{0}]\u500B\u8981\u5408\u4F75\u7684\u5EAB\u4F4D
smfcore.pos.merge.hasMaterial=\u5EAB\u4F4D[{0}]\u6709\u7269\u6599,\u4E0D\u80FD\u5408\u4F75
smfcore.pos.merge.hasMergePos=\u5EAB\u4F4D[{0}]\u5DF2\u5408\u4F75,\u4E0D\u80FD\u7E7C\u7E8C\u5408\u4F75
smfcore.pos.merge.notAdjacent=\u8ACB\u9078\u64C7\u76F8\u9130\u7684\u5EAB\u4F4D\u5408\u4F75
smfcore.pos.split.notNull=\u5EAB\u4F4D\u4E0D\u80FD\u70BA\u7A7A
smfcore.pos.split.notMergePos=\u5EAB\u4F4D[{0}]\u672A\u5408\u4F75,\u4E0D\u80FD\u62C6\u5206
smfcore.pos.split.hasMaterial=\u5EAB\u4F4D[{0}]\u6709\u7269\u6599,\u4E0D\u80FD\u62C6\u5206
smfcore.selectDevice=\u5408\u4F75\u5EAB\u4F4D
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!