Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
孙克
/
smf-core
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit 1449ec19
由
张少辉
编写于
2026-03-10 13:08:54 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
1.双库位功能修改
1 个父辈
e230cfd4
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
1104 行增加
和
11 行删除
src/main/java/com/neotel/smfcore/core/device/handler/impl/BaseDeviceHandler.java
src/main/java/com/neotel/smfcore/core/device/rest/DualPosNameDeviceController.java
src/main/java/com/neotel/smfcore/core/storage/rest/MaterialBoxController.java
src/main/java/com/neotel/smfcore/core/storage/service/manager/IStoragePosManager.java
src/main/java/com/neotel/smfcore/core/storage/service/manager/impl/StoragePosManagerImpl.java
src/main/java/com/neotel/smfcore/core/system/util/TaskService.java
src/main/java/com/neotel/smfcore/custom/aiqingzhiyin1643/momo/MomoApi.java
src/main/java/com/neotel/smfcore/custom/aiqingzhiyin1643/structuralWarehouse/controller/AgvDeviceController.java
src/main/java/com/neotel/smfcore/core/device/handler/impl/BaseDeviceHandler.java
查看文件 @
1449ec1
...
...
@@ -251,7 +251,19 @@ public class BaseDeviceHandler implements IDeviceHandler {
throw
new
ValidateException
(
"smfcore.error.pos.hasReel"
,
"库位[{0}]中已有物料,无法入库"
,
new
String
[]{
posName
});
}
if
(!
storage
.
canPutInPos
(
barcodeSave
.
getPlateSize
(),
barcodeSave
.
getHeight
(),
storagePos
.
getW
(),
storagePos
.
getH
()))
{
int
w
=
barcodeSave
.
getPlateSize
();
if
(
"ATAA000508"
.
equals
(
barcodeSave
.
getPartNumber
())
||
"ATAA000892"
.
equals
(
barcodeSave
.
getPartNumber
())
||
"ATAA000507"
.
equals
(
barcodeSave
.
getPartNumber
())
||
"ATAA000502"
.
equals
(
barcodeSave
.
getPartNumber
())
||
"ATAA000893"
.
equals
(
barcodeSave
.
getPartNumber
())
)
{
w
=
15
;
}
if
(!
storage
.
canPutInPos
(
w
,
barcodeSave
.
getHeight
(),
storagePos
.
getW
(),
storagePos
.
getH
()))
{
String
reelSize
=
barcodeSave
.
getPlateSize
()
+
"x"
+
barcodeSave
.
getHeight
();
String
posSize
=
storagePos
.
getW
()
+
"x"
+
storagePos
.
getH
();
throw
new
ValidateException
(
"smfcore.error.pos.sizeNotMatch"
,
"料盘尺寸[{0}}]与库位{1}尺寸[{2}]不符,无法入库"
,
new
String
[]{
reelSize
,
posName
,
posSize
});
...
...
src/main/java/com/neotel/smfcore/core/device/rest/DualPosNameDeviceController.java
0 → 100644
查看文件 @
1449ec1
package
com
.
neotel
.
smfcore
.
core
.
device
.
rest
;
import
cn.hutool.core.util.ObjectUtil
;
import
com.google.common.base.Strings
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
com.neotel.smfcore.common.bean.ReelLockPosInfo
;
import
com.neotel.smfcore.common.bean.ResultBean
;
import
com.neotel.smfcore.common.exception.ValidateException
;
import
com.neotel.smfcore.common.utils.Constants
;
import
com.neotel.smfcore.common.utils.ReelLockPosUtil
;
import
com.neotel.smfcore.common.utils.StringUtils
;
import
com.neotel.smfcore.core.api.SmfApi
;
import
com.neotel.smfcore.core.api.bean.CodeValidateParam
;
import
com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager
;
import
com.neotel.smfcore.core.barcode.service.manager.IComponentManager
;
import
com.neotel.smfcore.core.barcode.service.po.Barcode
;
import
com.neotel.smfcore.core.barcode.service.po.Component
;
import
com.neotel.smfcore.core.barcode.utils.CodeResolve
;
import
com.neotel.smfcore.core.device.enums.OP
;
import
com.neotel.smfcore.core.device.enums.OP_STATUS
;
import
com.neotel.smfcore.core.device.util.DataCache
;
import
com.neotel.smfcore.core.inList.service.po.InList
;
import
com.neotel.smfcore.core.inList.service.po.InListItem
;
import
com.neotel.smfcore.core.inList.util.InListCache
;
import
com.neotel.smfcore.core.language.util.MessageUtils
;
import
com.neotel.smfcore.core.message.util.DeviceMessageUtil
;
import
com.neotel.smfcore.core.storage.service.manager.IStoragePosManager
;
import
com.neotel.smfcore.core.storage.service.po.Storage
;
import
com.neotel.smfcore.core.storage.service.po.StoragePos
;
import
com.neotel.smfcore.core.system.service.dao.IAlarmInfoDao
;
import
com.neotel.smfcore.core.system.service.po.AlarmInfo
;
import
com.neotel.smfcore.core.system.service.po.DataLog
;
import
com.neotel.smfcore.core.system.util.TaskService
;
import
com.neotel.smfcore.security.annotation.AnonymousAccess
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.*
;
@Slf4j
@Api
(
tags
=
"双库位设备"
)
@RequestMapping
(
"/dualPosNameDevice"
)
@RestController
public
class
DualPosNameDeviceController
{
@Autowired
private
DataCache
dataCache
;
@Autowired
private
SmfApi
smfApi
;
@Autowired
private
TaskService
taskService
;
@Autowired
private
IStoragePosManager
storagePosManager
;
@Autowired
private
CodeResolve
codeResolve
;
@Autowired
private
IAlarmInfoDao
alarmInfoDao
;
@Autowired
private
IBarcodeManager
barcodeManager
;
/**
* 流水线提示消息
*/
private
static
String
lineMsg
=
""
;
@Autowired
private
InListCache
inListCache
;
@Autowired
private
IComponentManager
componentManager
;
/**
* 流水线入库查找空的料格
*/
@ApiOperation
(
"环行线扫码获取库位号"
)
@PostMapping
(
value
=
"/emptyPosForPutin"
)
@ResponseBody
@AnonymousAccess
public
Map
<
String
,
Object
>
emptyPosForPutin
(
HttpServletRequest
request
)
{
String
code
=
request
.
getParameter
(
"code"
);
String
cids
=
request
.
getParameter
(
"cids"
);
String
rfid
=
request
.
getParameter
(
"rfid"
);
String
rfidLoc
=
request
.
getParameter
(
"rfidLoc"
);
String
lastPosId
=
request
.
getParameter
(
"lastPosId"
);
lineMsg
=
""
;
log
.
info
(
"流水线["
+
cids
+
"]获取["
+
rfid
+
"]["
+
code
+
"]的入库库位"
);
Map
<
String
,
Object
>
resultMap
=
Maps
.
newHashMap
();
Boolean
stopOut
=
dataCache
.
getCache
(
Constants
.
CACHE_StopOut
);
if
(
stopOut
)
{
lineMsg
=
MessageUtils
.
getText
(
"smfcore.linemsg.update"
,
MessageUtils
.
getDefaultLocal
(),
"系统更新中,暂停出入库"
);
DeviceMessageUtil
.
updateLineMsg
(
lineMsg
,
code
,
cids
,
""
,
"smfcore.linemsg.update"
,
null
);
resultMap
.
put
(
"result"
,
"100"
);
resultMap
.
put
(
"msg"
,
lineMsg
);
return
resultMap
;
}
String
okMsg
=
""
;
String
errorMsg
=
""
;
// List<String> needRemoveReelLockPosIdList = new ArrayList<>();
if
(
Strings
.
isNullOrEmpty
(
cids
))
{
resultMap
.
put
(
"result"
,
"101"
);
String
msg
=
MessageUtils
.
getText
(
"smfcore.storage.noCids"
,
MessageUtils
.
getDefaultLocal
(),
"未指定料仓CID"
);
resultMap
.
put
(
"msg"
,
msg
);
}
else
{
List
<
Storage
>
storageList
=
Lists
.
newArrayList
();
List
<
String
>
cidList
=
Lists
.
newArrayList
();
for
(
String
cid
:
cids
.
split
(
","
))
{
String
notIntoCids
=
dataCache
.
getSettings
().
getNotIntoCids
();
if
(
notIntoCids
!=
null
)
{
if
(
notIntoCids
.
contains
(
cid
))
{
log
.
info
(
"料仓["
+
cid
+
"]已被屏蔽入库"
);
continue
;
}
}
Storage
storage
=
dataCache
.
getStorage
(
cid
);
if
(
storage
!=
null
)
{
storageList
.
add
(
storage
);
cidList
.
add
(
cid
);
}
}
if
(
storageList
.
isEmpty
())
{
resultMap
.
put
(
"result"
,
"99"
);
errorMsg
=
MessageUtils
.
getText
(
"smfcore.storage.noCanUseStorage"
,
MessageUtils
.
getDefaultLocal
(),
"无可用的料仓"
);
resultMap
.
put
(
"msg"
,
errorMsg
);
}
else
{
try
{
CodeValidateParam
params
=
new
CodeValidateParam
(
""
,
""
,
""
,
code
,
""
);
params
.
setStorageList
(
storageList
);
Barcode
barcode
=
resolveBarcodeFromApi
(
params
);
if
(
barcode
==
null
)
{
throw
new
ValidateException
(
"smfcore.error.barcode.invalid"
,
"未找到有效的条码"
);
}
//判断是否有出入库任务
for
(
DataLog
dataLog
:
taskService
.
getAllTasks
())
{
if
(
dataLog
.
getBarcode
().
equals
(
barcode
.
getBarcode
())
&&
!
dataLog
.
isCancel
()
&&
!
dataLog
.
isFinished
())
{
if
(
dataLog
.
isPutInTask
())
{
//已有入库任务
errorMsg
=
"物料["
+
dataLog
.
getBarcode
()
+
"]已有入库任务,需继续执行入库动作"
;
resultMap
.
put
(
"pos"
,
dataLog
.
getPosName
());
resultMap
.
put
(
"barcode"
,
barcode
.
getBarcode
());
resultMap
.
put
(
"cid"
,
dataLog
.
getCid
());
return
resultMap
;
}
else
{
//已有出库任务
errorMsg
=
MessageUtils
.
getText
(
"smfcore.barcode.hasOutTask"
,
new
String
[]{
dataLog
.
getBarcode
()},
MessageUtils
.
getDefaultLocal
(),
"物料[{0}]已有出库任务,需继续执行出库动作"
);
resultMap
.
put
(
"result"
,
"98"
);
resultMap
.
put
(
"msg"
,
errorMsg
);
resultMap
.
put
(
"posId"
,
dataLog
.
getPosName
());
resultMap
.
put
(
"plateW"
,
barcode
.
getPlateSize
());
resultMap
.
put
(
"plateH"
,
barcode
.
getHeight
());
resultMap
.
put
(
"singleOut"
,
dataLog
.
isSingleOut
()
+
""
);
//紧急料
resultMap
.
put
(
"urgentReel"
,
dataLog
.
isUrgentReel
()
+
""
);
//需要分盘,进入分盘料
resultMap
.
put
(
"cutReel"
,
dataLog
.
isCutReel
()
+
""
);
resultMap
.
put
(
"rfid"
,
""
);
resultMap
.
put
(
"realRfid"
,
""
);
resultMap
.
put
(
"rfidLoc"
,
""
);
resultMap
.
put
(
"barcode"
,
dataLog
.
getBarcode
());
boolean
smallReel
=
barcode
.
isSmallReel
();
resultMap
.
put
(
"smallReel"
,
smallReel
+
""
);
return
resultMap
;
}
}
}
//判断对应的尺寸,外侧的库位,是否保留5个
List
<
String
>
findCidList
=
new
ArrayList
<>();
List
<
Storage
>
findNewStorageList
=
new
ArrayList
<>();
for
(
Storage
storage
:
storageList
)
{
int
count
=
storagePosManager
.
getRemainPosCountByStorage
(
storage
,
barcode
,
taskService
.
excludePosIds
(),
""
,
"_F"
);
if
(
count
>
5
)
{
findCidList
.
add
(
storage
.
getCid
());
findNewStorageList
.
add
(
storage
);
}
else
{
log
.
info
(
storage
.
getCid
()
+
"对应的尺寸:"
+
barcode
.
getPlateSize
()
+
"x"
+
barcode
.
getHeight
()
+
"外侧库位数量小于等于5个,忽略不入库"
);
}
}
if
(
findNewStorageList
==
null
||
findNewStorageList
.
isEmpty
())
{
throw
new
ValidateException
(
"smfcore.noValidStorage"
,
"[{0}]料仓列表中未找到可用的料仓"
,
new
String
[]{
barcode
.
getBarcode
()});
}
//判断是不是对接momo
boolean
isDocking
=
dataCache
.
isElectronicWarehouseDocking
();
if
(
isDocking
)
{
//判断是不是退库操作
if
(
StringUtils
.
isEmpty
(
barcode
.
getStockoutNo
()))
{
//判断是否有入库单
Collection
<
InList
>
aLlInList
=
inListCache
.
getALlInList
();
InListItem
item
=
null
;
for
(
InList
inList
:
aLlInList
)
{
List
<
InListItem
>
inListItems
=
inList
.
getInListItems
();
for
(
InListItem
inListItem
:
inListItems
)
{
if
(
barcode
.
getBarcode
().
equals
(
inListItem
.
getRi
()))
{
item
=
inListItem
;
break
;
}
}
if
(
item
!=
null
)
{
break
;
}
}
if
(
item
==
null
)
{
throw
new
ValidateException
(
"smfcore.noValidInList"
,
"[{0}]入库单中未找到该物料"
,
new
String
[]{
barcode
.
getBarcode
()});
}
if
(
item
.
getInNum
()
>=
item
.
getNum
())
{
throw
new
ValidateException
(
"smfcore.noValidInList"
,
"[{0}]入库单中该物料已入库完成,不能继续入库"
,
new
String
[]{
barcode
.
getBarcode
()});
}
barcode
.
setReceiptOrder
(
item
.
getName
());
barcode
.
setRowNumber
(
item
.
getRowNumber
());
}
}
//设置元器件中的其他值
Component
component
=
componentManager
.
findByPartNumberAndProvider
(
barcode
.
getPartNumber
(),
barcode
.
getProvider
());
if
(
component
!=
null
){
barcode
.
setDescription
(
component
.
getDescription
());
barcode
.
setProviderMaterialCode
(
component
.
getProviderMaterialCode
());
barcode
.
setProviderNumber
(
component
.
getProviderNumber
());
barcode
.
setContainmentAmount
(
component
.
getContainmentAmount
());
barcode
.
setPlant
(
component
.
getPlant
());
barcode
.
setOriginalFactory
(
component
.
getOriginalFactory
());
barcode
.
setMassProduction
(
component
.
getMassProduction
());
}
//先移除被锁定的库位
ReelLockPosUtil
.
removeReelLockPosInfo
(
barcode
.
getBarcode
());
log
.
info
(
barcode
.
getBarcode
()
+
"料盘重新入库,先移除被锁定的库位"
);
StoragePos
pos
=
null
;
int
loopCount
=
0
;
List
<
String
>
needRemoveLockPosId
=
new
ArrayList
<>();
String
endStr
=
"B"
;
while
(
pos
==
null
)
{
loopCount
++;
if
(
loopCount
>=
30
)
{
log
.
info
(
barcode
.
getBarcode
()
+
"已循环查找30次 直接跳出循环"
);
break
;
}
if
(
loopCount
>=
15
)
{
endStr
=
"F"
;
}
pos
=
taskService
.
dualPosNameFindEmptyPosForPutIn
(
findNewStorageList
,
barcode
,
rfid
,
lastPosId
,
barcode
.
getBarcode
(),
endStr
);
if
(
pos
==
null
)
{
if
(
"B"
.
equals
(
endStr
))
{
endStr
=
"F"
;
}
else
{
endStr
=
"B"
;
}
pos
=
taskService
.
dualPosNameFindEmptyPosForPutIn
(
findNewStorageList
,
barcode
,
rfid
,
lastPosId
,
barcode
.
getBarcode
(),
endStr
);
}
if
(
pos
==
null
)
{
break
;
}
//如果是以S结尾的,则判断不带S的有没有料
String
posName
=
pos
.
getPosName
();
if
(
posName
.
endsWith
(
"B"
)
||
posName
.
endsWith
(
"b"
))
{
log
.
info
(
posName
+
"以B结尾,需要判断外层有没有物料"
);
posName
=
posName
.
substring
(
0
,
posName
.
length
()
-
1
);
posName
=
posName
+
"F"
;
StoragePos
storagePos
=
storagePosManager
.
getByPosName
(
posName
);
if
(
storagePos
!=
null
)
{
Set
<
String
>
allLockPosIds
=
ReelLockPosUtil
.
getAllLockPosIds
();
boolean
contains
=
allLockPosIds
.
contains
(
storagePos
.
getId
());
if
(
storagePos
.
getBarcode
()
!=
null
||
contains
)
{
log
.
info
(
posName
+
"有物料信息,重新查找库位,清除条码["
+
barcode
.
getBarcode
()
+
"]锁定库位"
);
ReelLockPosUtil
.
removeReelLockPosInfo
(
barcode
.
getBarcode
());
ReelLockPosInfo
reelLocInfo
=
new
ReelLockPosInfo
();
reelLocInfo
.
setBarcode
(
pos
.
getId
());
reelLocInfo
.
setCid
(
dataCache
.
getStorageById
(
pos
.
getStorageId
()).
getCid
());
reelLocInfo
.
setLockPosName
(
pos
.
getPosName
());
reelLocInfo
.
setLockPosId
(
pos
.
getId
());
ReelLockPosUtil
.
addReelLockPosInfo
(
reelLocInfo
,
findCidList
);
needRemoveLockPosId
.
add
(
pos
.
getId
());
pos
=
null
;
}
}
}
}
//判断有没有锁定的异常库位
if
(
needRemoveLockPosId
!=
null
&&
!
needRemoveLockPosId
.
isEmpty
())
{
for
(
String
posId
:
needRemoveLockPosId
)
{
ReelLockPosUtil
.
removeReelLockPosInfo
(
posId
);
}
}
if
(
pos
!=
null
)
{
Storage
theStorage
=
dataCache
.
getStorageById
(
pos
.
getStorageId
());
resultMap
.
put
(
"result"
,
"0"
);
resultMap
.
put
(
"msg"
,
""
);
okMsg
=
"["
+
rfid
+
"]["
+
barcode
.
getBarcode
()
+
"]锁定库位["
+
pos
.
getPosName
()
+
"]优先级["
+
pos
.
getPriority
()
+
"] 上个库位号["
+
lastPosId
+
"]"
;
ReelLockPosInfo
oldLockInfo
=
ReelLockPosUtil
.
getLockPosInfoByCode
(
barcode
.
getBarcode
());
if
(
oldLockInfo
!=
null
)
{
if
(!
oldLockInfo
.
getLockPosId
().
equals
(
pos
.
getId
()))
{
String
result
=
"-1"
;
okMsg
=
MessageUtils
.
getText
(
"smfcore.barcode.clearOldLock"
,
new
String
[]{
rfid
,
rfidLoc
,
barcode
.
getBarcode
(),
pos
.
getPosName
()},
MessageUtils
.
getDefaultLocal
(),
"{0}[{1}][{2}]锁定库位[{3}],清理旧有锁定信息"
);
resultMap
.
put
(
"result"
,
result
);
resultMap
.
put
(
"msg"
,
okMsg
);
//已经锁定过库位,但不是同一个条码,需要把对应位置的锁定信息清理掉
ReelLockPosUtil
.
removeReelLockPosInfo
(
oldLockInfo
.
getBarcode
());
log
.
info
(
"清理锁定库位:库位号["
+
oldLockInfo
.
getLockPosName
()
+
"]上物料["
+
oldLockInfo
.
getBarcode
()
+
"]锁定的库位"
);
}
}
log
.
info
(
okMsg
+
oldLockInfo
);
ReelLockPosInfo
reelLocInfo
=
new
ReelLockPosInfo
();
reelLocInfo
.
setBarcode
(
barcode
.
getBarcode
());
reelLocInfo
.
setCid
(
theStorage
.
getCid
());
reelLocInfo
.
setLockPosName
(
pos
.
getPosName
());
reelLocInfo
.
setLockPosId
(
pos
.
getId
());
reelLocInfo
=
ReelLockPosUtil
.
addReelLockPosInfo
(
reelLocInfo
,
findCidList
);
if
(
reelLocInfo
==
null
)
{
errorMsg
=
MessageUtils
.
getText
(
"smfcore.linemsg.posLock"
,
new
String
[]{
barcode
.
getBarcode
(),
reelLocInfo
.
getLockPosName
()},
MessageUtils
.
getDefaultLocal
(),
"[{0}]库位[{1}]已被锁定,暂停入库"
);
lineMsg
=
errorMsg
;
DeviceMessageUtil
.
updateLineMsg
(
lineMsg
,
code
,
cids
,
reelLocInfo
.
getLockPosName
(),
"smfcore.linemsg.posLock"
,
new
String
[]{
barcode
.
getBarcode
(),
reelLocInfo
.
getLockPosName
()});
resultMap
.
put
(
"result"
,
"99"
);
resultMap
.
put
(
"msg"
,
errorMsg
);
return
resultMap
;
}
else
{
resultMap
.
put
(
"pos"
,
pos
.
getPosName
());
resultMap
.
put
(
"barcode"
,
barcode
.
getBarcode
());
resultMap
.
put
(
"cid"
,
theStorage
.
getCid
());
}
}
else
{
resultMap
.
put
(
"result"
,
"104"
);
errorMsg
=
MessageUtils
.
getText
(
"smfcore.barcode.noPutInPos"
,
new
String
[]{
barcode
.
getBarcode
(),
barcode
.
getPlateSize
()+
""
,
barcode
.
getHeight
()+
""
},
MessageUtils
.
getDefaultLocal
(),
"[{0}]未找到[{1}x{2}]仓位"
);
resultMap
.
put
(
"msg"
,
errorMsg
);
}
}
catch
(
ValidateException
ve
)
{
errorMsg
=
ve
.
getMessage
();
errorMsg
=
MessageUtils
.
getText
(
ve
.
getMsgKey
(),
ve
.
getMsgParam
(),
MessageUtils
.
getDefaultLocal
(),
ve
.
getDefaultMsg
());
log
.
info
(
"查找空库位失败:"
+
errorMsg
);
resultMap
.
put
(
"result"
,
"105"
);
resultMap
.
put
(
"msg"
,
errorMsg
);
}
catch
(
Exception
e
)
{
errorMsg
=
e
.
getMessage
();
log
.
info
(
"查找空库位失败,"
,
e
);
resultMap
.
put
(
"result"
,
"105"
);
resultMap
.
put
(
"msg"
,
errorMsg
);
}
}
}
//没入成功
if
(!
errorMsg
.
isEmpty
())
{
//有错误,记录日志
AlarmInfo
alarmInfo
=
new
AlarmInfo
();
alarmInfo
.
setBoxId
(
"0"
);
alarmInfo
.
setStorageName
(
"流水线"
);
alarmInfo
.
setInOutStatus
(
"1"
);
alarmInfo
.
setAlarmType
(
"入库"
);
Date
date
=
new
Date
();
alarmInfo
.
setStartTime
(
date
);
alarmInfo
.
setEndTime
(
date
);
String
msg
=
"["
+
code
+
"]"
+
errorMsg
;
alarmInfo
.
setAlarmMsg
(
msg
);
alarmInfoDao
.
save
(
alarmInfo
);
lineMsg
=
errorMsg
;
DeviceMessageUtil
.
updateLineMsg
(
lineMsg
,
code
,
cids
,
""
,
""
,
null
);
}
else
{
lineMsg
=
okMsg
;
DeviceMessageUtil
.
lastLineMsg
=
null
;
}
return
resultMap
;
}
@ApiOperation
(
"获取需要移动的库位是否有料"
)
@RequestMapping
(
"/needMovePosHasReel"
)
@ResponseBody
@AnonymousAccess
public
ResultBean
needMovePosHasReel
(
@RequestBody
Map
<
String
,
String
>
paramMap
)
{
String
checkOutPosName
=
paramMap
.
get
(
"checkOutPosName"
);
String
needMovePosName
=
paramMap
.
get
(
"needMovePosName"
);
log
.
info
(
"出库的库位为:"
+
checkOutPosName
+
",需要移动的库位为:"
+
needMovePosName
);
StoragePos
checkOutPos
=
storagePosManager
.
getByPosName
(
checkOutPosName
);
if
(
checkOutPos
==
null
)
{
return
ResultBean
.
newErrorResult
(-
1
,
"smfcore.valueNotExist"
,
"{0}[{1}]不存在"
,
new
String
[]{
"posName"
,
checkOutPosName
});
}
StoragePos
needMovePos
=
storagePosManager
.
getByPosName
(
needMovePosName
);
if
(
needMovePos
==
null
)
{
return
ResultBean
.
newErrorResult
(-
1
,
"smfcore.valueNotExist"
,
"{0}[{1}]不存在"
,
new
String
[]{
"posName"
,
needMovePosName
});
}
//如果barcode不为空,则提前锁定目标库位
boolean
hasReel
=
true
;
Barcode
barcode
=
needMovePos
.
getBarcode
();
String
posName
=
""
;
if
(
barcode
!=
null
)
{
log
.
info
(
"需要移动的库位"
+
needMovePosName
+
",对应的barcode为:"
+
barcode
.
getBarcode
()
+
",尺寸为:"
+
barcode
.
getPlateSize
()
+
"x"
+
barcode
.
getHeight
());
//有料,先查找锁定的lockS库位,有的话返回
ReelLockPosInfo
lockPosInfo
=
ReelLockPosUtil
.
getLockPosInfoByCode
(
getLockPosSKey
(
needMovePos
.
getStorageId
()));
if
(
lockPosInfo
!=
null
&&
ObjectUtil
.
isNotEmpty
(
lockPosInfo
.
getLockPosName
()))
{
posName
=
lockPosInfo
.
getLockPosName
();
log
.
info
(
"查找到锁定的内侧库位为目标库位:"
+
posName
+
" "
);
StoragePos
pos
=
storagePosManager
.
getByPosName
(
posName
);
if
(
pos
!=
null
)
{
if
(
pos
.
getW
()
!=
needMovePos
.
getW
()
||
pos
.
getH
()
!=
needMovePos
.
getH
())
{
log
.
info
(
posName
+
"对应的w{},h{}与移动的宽{},高{}不一致,重新找"
,
pos
.
getW
(),
pos
.
getH
(),
needMovePos
.
getW
(),
needMovePos
.
getH
());
posName
=
""
;
}
}
else
{
posName
=
""
;
}
}
if
(
StringUtils
.
isEmpty
(
posName
))
{
ReelLockPosUtil
.
removeReelLockPosInfo
(
getLockPosSKey
(
needMovePos
.
getStorageId
()));
}
if
(
StringUtils
.
isEmpty
(
posName
))
{
//查找一个库位号
StoragePos
pos
=
null
;
int
loopCount
=
0
;
List
<
Storage
>
storageList
=
new
ArrayList
<>();
Storage
storage
=
dataCache
.
getStorageById
(
needMovePos
.
getStorageId
());
storageList
.
add
(
storage
);
List
<
String
>
cidList
=
new
ArrayList
<>();
cidList
.
add
(
storage
.
getCid
());
List
<
String
>
needRemoveLockPosId
=
new
ArrayList
<>();
while
(
pos
==
null
)
{
loopCount
++;
if
(
loopCount
>=
20
)
{
log
.
info
(
barcode
.
getBarcode
()
+
"已循环查找20次 直接跳出循环"
);
break
;
}
//优先找B结束的,如果没有再找F的
String
endStr
=
"B"
;
if
(
loopCount
>=
10
)
{
endStr
=
"F"
;
}
pos
=
taskService
.
dualPosNameFindEmptyPosForMoveIn
(
storageList
,
barcode
,
""
,
""
,
needMovePosName
,
endStr
);
if
(
pos
==
null
)
{
if
(
"F"
.
equals
(
endStr
))
{
}
else
{
endStr
=
"F"
;
pos
=
taskService
.
dualPosNameFindEmptyPosForMoveIn
(
storageList
,
barcode
,
""
,
""
,
needMovePosName
,
endStr
);
}
}
if
(
pos
==
null
)
{
log
.
info
(
"需要移动的库位"
+
needMovePosName
+
"未找到对应的库位信息"
);
break
;
}
//如果是以S结尾的,则判断不带S的有没有料
posName
=
pos
.
getPosName
();
String
wPosName
=
""
;
if
(
posName
.
endsWith
(
"B"
)
||
posName
.
endsWith
(
"b"
))
{
log
.
info
(
posName
+
"以B结尾,需要判断外层有没有物料"
);
wPosName
=
posName
.
substring
(
0
,
posName
.
length
()
-
1
);
wPosName
=
wPosName
+
"F"
;
StoragePos
storagePos
=
storagePosManager
.
getByPosName
(
wPosName
);
if
(
storagePos
!=
null
)
{
if
(
storagePos
.
getBarcode
()
!=
null
)
{
log
.
info
(
"查找到目标库位:"
+
pos
.
getPosName
()
+
" 的外侧库位"
+
wPosName
+
"有物料信息,重新查找库位 "
);
ReelLockPosInfo
reelLocInfo
=
new
ReelLockPosInfo
();
reelLocInfo
.
setBarcode
(
pos
.
getId
());
reelLocInfo
.
setCid
(
dataCache
.
getStorageById
(
pos
.
getStorageId
()).
getCid
());
reelLocInfo
.
setLockPosName
(
pos
.
getPosName
());
reelLocInfo
.
setLockPosId
(
pos
.
getId
());
ReelLockPosUtil
.
addReelLockPosInfo
(
reelLocInfo
,
cidList
);
needRemoveLockPosId
.
add
(
pos
.
getId
());
pos
=
null
;
posName
=
""
;
}
else
{
log
.
info
(
"查找到目标库位:"
+
pos
.
getPosName
()
+
" 且外侧库位"
+
wPosName
+
"无料,锁定两个库位 :"
+
pos
.
getPosName
()
+
"="
+
getLockPosSKey
(
needMovePos
.
getStorageId
())
+
",wPosName="
+
getLockPosKey
(
needMovePos
.
getStorageId
()));
//是内侧库位,且外侧库位也无料,锁定两个库位
AddLock
(
pos
,
getLockPosSKey
(
needMovePos
.
getStorageId
()),
cidList
);
AddLock
(
storagePos
,
getLockPosKey
(
needMovePos
.
getStorageId
()),
cidList
);
//如果外侧有任务,则改成新库位一样的
DataLog
dataLog
=
null
;
for
(
DataLog
queueTask
:
taskService
.
getQueueTasks
())
{
if
(
barcode
.
getBarcode
().
equals
(
queueTask
))
{
dataLog
=
queueTask
;
break
;
}
}
if
(
dataLog
!=
null
)
{
log
.
info
(
"posName:[{}],barcode为[{}]有任务,需要重新设置任务库位:[{}]"
,
dataLog
.
getPosName
(),
barcode
.
getBarcode
(),
pos
.
getPosName
());
dataLog
.
setPosName
(
pos
.
getPosName
());
dataLog
.
setPosId
(
pos
.
getId
());
if
(
dataLog
.
isExecuting
()
||
dataLog
.
isWait
())
{
dataLog
.
setStatus
(
OP_STATUS
.
WAIT
.
name
());
taskService
.
updateQueueTask
(
dataLog
);
}
else
{
taskService
.
updateFinishedTask
(
dataLog
);
}
}
}
}
}
else
{
//是外侧库位,直接锁定外侧库位
log
.
info
(
"查找到外侧库位作为目标库位,锁定库位 :"
+
pos
.
getPosName
()
+
"="
+
getLockPosKey
(
needMovePos
.
getStorageId
()));
AddLock
(
pos
,
getLockPosKey
(
needMovePos
.
getStorageId
()),
cidList
);
//如果外侧有任务,则改成新库位一样的
DataLog
dataLog
=
null
;
for
(
DataLog
queueTask
:
taskService
.
getQueueTasks
())
{
if
(
barcode
.
getBarcode
().
equals
(
queueTask
))
{
dataLog
=
queueTask
;
break
;
}
}
if
(
dataLog
!=
null
)
{
log
.
info
(
"posName:[{}],barcode为[{}]有任务,需要重新设置任务库位:[{}]"
,
dataLog
.
getPosName
(),
barcode
.
getBarcode
(),
pos
.
getPosName
());
dataLog
.
setPosName
(
pos
.
getPosName
());
dataLog
.
setPosId
(
pos
.
getId
());
if
(
dataLog
.
isExecuting
()
||
dataLog
.
isWait
())
{
dataLog
.
setStatus
(
OP_STATUS
.
WAIT
.
name
());
taskService
.
updateQueueTask
(
dataLog
);
}
else
{
taskService
.
updateFinishedTask
(
dataLog
);
}
}
}
}
//判断有没有锁定的异常库位
if
(
needRemoveLockPosId
!=
null
&&
!
needRemoveLockPosId
.
isEmpty
())
{
for
(
String
posId
:
needRemoveLockPosId
)
{
ReelLockPosUtil
.
removeReelLockPosInfo
(
posId
);
}
}
}
}
else
{
hasReel
=
false
;
}
Map
<
String
,
Object
>
resultMap
=
new
HashMap
<>();
resultMap
.
put
(
"hasReel"
,
hasReel
);
if
(
hasReel
)
{
resultMap
.
put
(
"barcode"
,
barcode
.
getBarcode
());
resultMap
.
put
(
"partNumber"
,
barcode
.
getPartNumber
());
if
(
ObjectUtil
.
isEmpty
(
posName
))
{
return
ResultBean
.
newErrorResult
(-
1
,
"smfcore.shelf.msg.inError"
,
"未找到适合[{0}]的库位"
,
new
String
[]{
needMovePosName
});
}
else
{
resultMap
.
put
(
"posName"
,
posName
);
}
}
return
ResultBean
.
newOkResult
(
resultMap
);
}
@ApiOperation
(
"移动物料到另外一个库位"
)
@RequestMapping
(
"/moveToOtherPos"
)
@ResponseBody
@AnonymousAccess
public
ResultBean
moveToOtherPos
(
@RequestBody
Map
<
String
,
String
>
paramMap
)
{
String
needMovePosName
=
paramMap
.
get
(
"needMovePosName"
);
//需要移动的库位
String
targetPosName
=
paramMap
.
get
(
"targetPosName"
);
//目标库位
log
.
info
(
"需要移动的库位为:"
+
needMovePosName
+
",目标库位为:"
+
targetPosName
);
//判断目标库位是否存在
StoragePos
targetPos
=
storagePosManager
.
getByPosName
(
targetPosName
);
if
(
targetPos
==
null
)
{
return
ResultBean
.
newErrorResult
(-
1
,
"smfcore.valueNotExist"
,
"{0}[{1}]不存在"
,
new
String
[]{
"posName"
,
targetPosName
});
}
Barcode
targetBarcode
=
targetPos
.
getBarcode
();
//判断有没有物料
StoragePos
needMovePos
=
storagePosManager
.
getByPosName
(
needMovePosName
);
Barcode
barcode
=
needMovePos
.
getBarcode
();
//如果目标库位不为空,当前库位为空,直接返回ok
if
(
barcode
==
null
)
{
if
(
targetBarcode
==
null
)
{
return
ResultBean
.
newErrorResult
(-
1
,
"smfcore.valueNotExist"
,
"{0}[{1}]不存在"
,
new
String
[]{
needMovePosName
,
"barcode"
});
}
else
{
return
ResultBean
.
newOkResult
(
""
);
}
}
//把外侧相同的任务给改成内侧的
List
<
DataLog
>
allTasks
=
taskService
.
getAllTasks
();
for
(
DataLog
dataLog
:
allTasks
)
{
if
(
dataLog
.
isCheckOutTask
())
{
if
(!
dataLog
.
isFinished
()
&&
!
dataLog
.
isCancel
())
{
if
(
dataLog
.
getPosId
().
equals
(
needMovePos
.
getId
()))
{
dataLog
.
setPosId
(
targetPos
.
getId
());
dataLog
.
setPosName
(
targetPos
.
getPosName
());
taskService
.
updateQueueTask
(
dataLog
);
log
.
info
(
dataLog
.
getBarcode
()
+
":外测有任务,原始库位为:"
+
dataLog
.
getPosName
()
+
"更改后的库位为:"
+
targetPos
.
getPosName
());
break
;
}
}
}
}
//生成一条出库任务
Storage
storage
=
dataCache
.
getStorageById
(
needMovePos
.
getStorageId
());
DataLog
needMovePosTask
=
new
DataLog
(
storage
,
barcode
,
needMovePos
);
needMovePosTask
.
setOperator
(
"admin-move"
);
needMovePosTask
.
setType
(
OP
.
CHECKOUT
);
needMovePosTask
.
setStatus
(
OP_STATUS
.
FINISHED
.
name
());
taskService
.
updateFinishedTask
(
needMovePosTask
);
needMovePos
.
setBarcode
(
null
);
needMovePos
.
setUsed
(
false
);
storagePosManager
.
save
(
needMovePos
);
log
.
info
(
barcode
.
getBarcode
()
+
"转移库位,清空仓位: "
+
needMovePos
.
getId
()
+
"["
+
needMovePos
.
getPosName
()
+
"]"
);
dataCache
.
updateInventory
(
needMovePos
,
barcode
);
//重新设置barcode的库位
barcode
.
setPosName
(
targetPos
.
getPosName
());
barcodeManager
.
save
(
barcode
);
//生成一条入库任务
DataLog
targetPosTask
=
new
DataLog
(
storage
,
barcode
,
targetPos
);
targetPosTask
.
setOperator
(
"admin-move"
);
targetPosTask
.
setType
(
OP
.
PUT_IN
);
targetPosTask
.
setStatus
(
OP_STATUS
.
FINISHED
.
name
());
taskService
.
updateFinishedTask
(
targetPosTask
);
targetPos
.
setBarcode
(
barcode
);
targetPos
.
setUsed
(
true
);
targetPos
.
setCanCheckOutTime
(
System
.
currentTimeMillis
());
storagePosManager
.
save
(
targetPos
);
log
.
info
(
barcode
.
getBarcode
()
+
"转移库位,入库库位: "
+
targetPos
.
getId
()
+
"["
+
targetPos
.
getPosName
()
+
"]"
);
dataCache
.
updateInventory
(
targetPos
,
barcode
);
//解除库位绑定
ReelLockPosUtil
.
removeReelLockPosInfo
(
barcode
.
getBarcode
());
ReelLockPosInfo
lockS
=
ReelLockPosUtil
.
getLockPosInfoByCode
(
getLockPosSKey
(
needMovePos
.
getStorageId
()));
if
(
lockS
!=
null
&&
ObjectUtil
.
isNotEmpty
(
lockS
.
getLockPosName
())
&&
lockS
.
getLockPosName
().
equals
(
targetPosName
))
{
ReelLockPosUtil
.
removeReelLockPosInfo
(
getLockPosSKey
(
needMovePos
.
getStorageId
()));
}
else
{
ReelLockPosInfo
lock
=
ReelLockPosUtil
.
getLockPosInfoByCode
(
getLockPosKey
(
needMovePos
.
getStorageId
()));
if
(
lock
!=
null
&&
ObjectUtil
.
isNotEmpty
(
lock
.
getLockPosName
())
&&
lock
.
getLockPosName
().
equals
(
targetPosName
))
{
ReelLockPosUtil
.
removeReelLockPosInfo
(
getLockPosKey
(
needMovePos
.
getStorageId
()));
lock
=
null
;
}
if
(
lock
==
null
)
{
if
(
needMovePosName
.
endsWith
(
"F"
)
||
needMovePosName
.
endsWith
(
"f"
))
{
log
.
info
(
"需要移动的库位为:"
+
needMovePosName
+
"是内侧库位,不需要锁定库位"
);
}
else
{
needMovePosName
=
needMovePosName
.
substring
(
0
,
needMovePosName
.
length
()
-
1
);
String
sPosname
=
needMovePosName
+
"B"
;
StoragePos
sPos
=
storagePosManager
.
getByPosName
(
sPosname
);
if
(
sPos
!=
null
)
{
String
cid
=
dataCache
.
getStorageById
(
sPos
.
getStorageId
()).
getCid
();
List
<
String
>
cidList
=
new
ArrayList
<>();
cidList
.
add
(
cid
);
//如果两个库位锁定都为空了,将当前库位锁定为缓存库位
log
.
info
(
"重新锁定两个缓存库位 :"
+
sPos
.
getPosName
()
+
"="
+
getLockPosSKey
(
needMovePos
.
getStorageId
())
+
","
+
needMovePos
.
getPosName
()
+
"="
+
getLockPosKey
(
needMovePos
.
getStorageId
()));
//是内侧库位,且外侧库位也无料,锁定两个库位
AddLock
(
sPos
,
getLockPosSKey
(
needMovePos
.
getStorageId
()),
cidList
);
AddLock
(
needMovePos
,
getLockPosKey
(
needMovePos
.
getStorageId
()),
cidList
);
}
}
}
}
return
ResultBean
.
newOkResult
(
""
);
}
public
Barcode
resolveBarcodeFromApi
(
CodeValidateParam
params
)
{
Barcode
barcodeSave
=
smfApi
.
canPutInBeforeResolve
(
params
);
if
(
barcodeSave
==
null
)
{
barcodeSave
=
codeResolve
.
resolveOneValideBarcode
(
params
.
getCode
());
}
//从API验证
Barcode
barcodeFromApi
=
smfApi
.
canPutInAfterResolve
(
params
,
barcodeSave
);
if
(
barcodeFromApi
!=
null
)
{
barcodeSave
=
barcodeFromApi
;
}
return
barcodeSave
;
}
private
void
AddLock
(
StoragePos
pos
,
String
key
,
List
<
String
>
cidList
)
{
ReelLockPosInfo
lockS
=
new
ReelLockPosInfo
();
lockS
.
setBarcode
(
key
);
lockS
.
setCid
(
dataCache
.
getStorageById
(
pos
.
getStorageId
()).
getCid
());
lockS
.
setLockPosName
(
pos
.
getPosName
());
lockS
.
setLockPosId
(
pos
.
getId
());
ReelLockPosUtil
.
addReelLockPosInfo
(
lockS
,
cidList
);
}
private
String
getLockPosSKey
(
String
storageId
)
{
return
Constants
.
XLR_lockPosS
+
"_"
+
storageId
;
}
private
String
getLockPosKey
(
String
storageId
)
{
return
Constants
.
XLR_lockPos
+
"_"
+
storageId
;
}
}
src/main/java/com/neotel/smfcore/core/storage/rest/MaterialBoxController.java
查看文件 @
1449ec1
...
...
@@ -16,6 +16,8 @@ import com.neotel.smfcore.core.barcode.utils.CodeResolve;
import
com.neotel.smfcore.core.device.enums.OP
;
import
com.neotel.smfcore.core.device.enums.OP_STATUS
;
import
com.neotel.smfcore.core.device.util.DataCache
;
import
com.neotel.smfcore.core.inList.service.po.InList
;
import
com.neotel.smfcore.core.inList.service.po.InListItem
;
import
com.neotel.smfcore.core.storage.service.manager.IStoragePosManager
;
import
com.neotel.smfcore.core.storage.service.po.StoragePos
;
import
com.neotel.smfcore.core.system.service.manager.IDataLogManager
;
...
...
@@ -228,10 +230,15 @@ public class MaterialBoxController {
throw
new
ValidateException
(
"smfcore.materialBox.inPos"
,
"物料已在库位{0}中"
,
new
String
[]{
pos
.
getPosName
()});
}
//通知momo,退库接口
StockReturnResponse
response
=
momoApi
.
stockReturn
(
barcode
);
if
(!
response
.
getIsSuccess
()){
return
ResultBean
.
newErrorResult
(-
1
,
"smfcore.momo.stockOutError"
,
response
.
getErrorMessage
(),
new
String
[]{});
//判断是不是对接momo
boolean
isDocking
=
dataCache
.
isElectronicWarehouseDocking
();
if
(
isDocking
)
{
//通知momo,退库接口
StockReturnResponse
response
=
momoApi
.
stockReturn
(
barcode
);
if
(!
response
.
getIsSuccess
()){
return
ResultBean
.
newErrorResult
(-
1
,
"smfcore.momo.stockOutError"
,
response
.
getErrorMessage
(),
new
String
[]{});
}
}
//设置barcode的入库时间
...
...
src/main/java/com/neotel/smfcore/core/storage/service/manager/IStoragePosManager.java
查看文件 @
1449ec1
...
...
@@ -104,4 +104,6 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
StoragePos
getByPidBarcode
(
String
reelId
);
StoragePos
findFgWarehouseForPutIn
(
Storage
fgWarehouseStorage
,
Barcode
barcode
,
Collection
<
String
>
strings
,
boolean
heightLimited
);
StoragePos
dualPosNameGetEmptyPosByStorage
(
Storage
storage
,
Barcode
barcode
,
Collection
<
String
>
operatingPosIds
,
String
lastPosId
,
String
needMovePosName
,
String
endStr
,
List
<
String
>
needExcludePosName
);
}
src/main/java/com/neotel/smfcore/core/storage/service/manager/impl/StoragePosManagerImpl.java
查看文件 @
1449ec1
...
...
@@ -439,6 +439,78 @@ public class StoragePosManagerImpl implements IStoragePosManager {
return
pos
;
}
private
static
boolean
max
=
true
;
@Override
public
StoragePos
dualPosNameGetEmptyPosByStorage
(
Storage
storage
,
Barcode
barcode
,
Collection
<
String
>
excludePosIds
,
String
lastPosId
,
String
needMovePosName
,
String
endStr
,
List
<
String
>
needExcludePosNameList
)
{
Criteria
c
=
Criteria
.
where
(
"storageId"
).
is
(
storage
.
getId
());
int
w
=
barcode
.
getPlateSize
();
int
h
=
barcode
.
getHeight
();
if
(
"ATAA000508"
.
equals
(
barcode
.
getPartNumber
())
||
"ATAA000892"
.
equals
(
barcode
.
getPartNumber
())
||
"ATAA000507"
.
equals
(
barcode
.
getPartNumber
())
||
"ATAA000502"
.
equals
(
barcode
.
getPartNumber
())
||
"ATAA000893"
.
equals
(
barcode
.
getPartNumber
())
)
{
w
=
15
;
}
COMPATIBLE_TYPE
compatibleType
=
storage
.
getCompatibleType
();
if
(
compatibleType
==
COMPATIBLE_TYPE
.
EXACT_MATCH
)
{
//完全匹配
c
=
c
.
and
(
"w"
).
is
(
w
).
and
(
"h"
).
is
(
h
);
}
else
if
(
compatibleType
==
COMPATIBLE_TYPE
.
FULLY_COMPATIBLE
)
{
//同厚度兼容
c
=
c
.
and
(
"w"
).
gte
(
w
).
and
(
"h"
).
gte
(
h
);
//除7寸外,完全兼容
}
else
if
(
compatibleType
==
COMPATIBLE_TYPE
.
SIZE_COMPATIBLE
)
{
//同尺寸兼容
c
=
c
.
and
(
"w"
).
is
(
w
).
and
(
"h"
).
gte
(
h
);
//宽度等于料盘宽度,高度大于等于料盘高度
}
c
=
c
.
and
(
"enabled"
).
is
(
true
)
//可用
.
and
(
"used"
).
is
(
false
);
//未使用
//去除的仓位
if
(
excludePosIds
!=
null
&&
!
excludePosIds
.
isEmpty
())
{
c
=
c
.
and
(
"id"
).
nin
(
excludePosIds
);
}
if
(
StringUtils
.
isNotEmpty
(
needMovePosName
)
&&
StringUtils
.
isNotEmpty
(
endStr
))
{
Criteria
posNameCriteria
=
new
Criteria
();
String
regex
=
""
+
endStr
+
"$"
;
posNameCriteria
.
andOperator
(
Criteria
.
where
(
"posName"
).
ne
(
needMovePosName
),
Criteria
.
where
(
"posName"
).
regex
(
Pattern
.
compile
(
regex
)));
c
.
andOperator
(
posNameCriteria
);
}
if
(
needExcludePosNameList
!=
null
&&
!
needExcludePosNameList
.
isEmpty
()){
c
.
and
(
"posName"
).
nin
(
needExcludePosNameList
);
}
Query
query
=
new
Query
(
c
);
String
msg
=
""
;
// if (lastPosId == null || lastPosId.equals("")) {
//优先放入最合适的位置(根据尺寸),相同尺寸按优先级排序
if
(
max
){
query
.
with
(
Sort
.
by
(
Sort
.
Direction
.
ASC
,
"w"
).
and
(
Sort
.
by
(
Sort
.
Direction
.
ASC
,
"h"
)).
and
(
Sort
.
by
(
Sort
.
Direction
.
DESC
,
"priority"
)));
max
=
true
;
}
else
{
query
.
with
(
Sort
.
by
(
Sort
.
Direction
.
ASC
,
"w"
).
and
(
Sort
.
by
(
Sort
.
Direction
.
ASC
,
"h"
)).
and
(
Sort
.
by
(
Sort
.
Direction
.
ASC
,
"priority"
)));
max
=
false
;
}
StoragePos
pos
=
storagePosDao
.
findOne
(
query
);
if
((!
ObjectUtil
.
isNotEmpty
(
msg
)
)&&
(
pos
!=
null
))
{
Point
targetP
=
PointUtil
.
getPosPoint
(
lastPosId
,
false
);
log
.
debug
(
msg
+
"结果:["
+
pos
.
getPosName
()
+
"]["
+
targetP
.
getX
()
+
","
+
targetP
.
getY
()
+
"]"
);
}
return
pos
;
}
@Override
public
PageData
<
StoragePos
>
findByPage
(
Query
query
,
Pageable
pageable
)
{
int
totalCount
=
storagePosDao
.
countByQuery
(
query
);
...
...
src/main/java/com/neotel/smfcore/core/system/util/TaskService.java
查看文件 @
1449ec1
...
...
@@ -1283,4 +1283,288 @@ public class TaskService {
}
}
}
public
StoragePos
dualPosNameFindEmptyPosForPutIn
(
List
<
Storage
>
storageList
,
Barcode
barcode
,
String
inRFID
,
String
lastPosId
,
String
needMovePosName
,
String
endStr
)
throws
ValidateException
{
verifyBarcodePutIn
(
storageList
,
barcode
,
inRFID
);
List
<
String
>
storageIds
=
new
ArrayList
<>();
//查找任务数最少的料仓
final
Map
<
String
,
Integer
>
storageTaskCountMap
=
new
HashMap
<>();
for
(
Storage
storage
:
storageList
)
{
storageTaskCountMap
.
put
(
storage
.
getId
(),
0
);
storageIds
.
add
(
storage
.
getId
());
}
Set
<
String
>
hasOutTaskStorageIds
=
new
HashSet
<>();
//如果有正在执行的任务,把库位发过去
Collection
<
DataLog
>
allTasks
=
taskMap
.
values
();
for
(
DataLog
task
:
allTasks
)
{
if
(
barcode
.
getBarcode
().
equals
(
task
.
getBarcode
()))
{
String
posId
=
task
.
getPosId
();
log
.
info
(
barcode
.
getBarcode
()
+
" 已有任务,返回任务中的库位:"
+
task
.
getPosName
());
return
storagePosManager
.
get
(
posId
);
}
String
storageId
=
task
.
getStorageId
();
if
(!
Strings
.
isNullOrEmpty
(
storageId
))
{
Integer
taskCount
=
storageTaskCountMap
.
get
(
storageId
);
if
(
taskCount
!=
null
)
{
taskCount
=
taskCount
+
1
;
storageTaskCountMap
.
put
(
storageId
,
taskCount
);
}
if
(
task
.
isCheckOutTask
())
{
hasOutTaskStorageIds
.
add
(
storageId
);
}
}
}
String
lockPosId
=
ReelLockPosUtil
.
getReelLockPosId
(
barcode
.
getBarcode
());
StoragePos
pos
=
null
;
if
(!
Strings
.
isNullOrEmpty
(
lockPosId
))
{
//已有锁定库位
pos
=
storagePosManager
.
get
(
lockPosId
);
if
(
pos
!=
null
)
{
if
(!
storageIds
.
contains
(
pos
.
getStorageId
())){
log
.
info
(
"条码["
+
barcode
.
getBarcode
()
+
"]已有锁定库位["
+
pos
.
getPosName
()
+
"],料仓ID["
+
pos
.
getStorageId
()+
"]不在请求列表["
+
String
.
join
(
","
,
storageIds
)+
"]中,重新查找库位"
);
pos
=
null
;
}
else
if
(
pos
.
getW
()
!=
barcode
.
getPlateSize
()
||
pos
.
getH
()
!=
barcode
.
getHeight
())
{
log
.
info
(
"条码["
+
barcode
.
getBarcode
()
+
"]尺寸已改变,无法放入已锁定库位["
+
pos
.
getPosName
()
+
"],重新查找库位"
);
pos
=
null
;
}
else
{
Barcode
posBarcode
=
pos
.
getBarcode
();
if
(
posBarcode
==
null
)
{
log
.
info
(
"条码["
+
barcode
.
getBarcode
()
+
"]已锁定库位["
+
pos
.
getPosName
()
+
"],返回锁定中的库位"
);
}
else
{
log
.
info
(
"条码["
+
barcode
.
getBarcode
()
+
"]已锁定库位["
+
pos
.
getPosName
()
+
"]中已有物料["
+
posBarcode
.
getBarcode
()
+
"],重新查找库位"
);
pos
=
null
;
}
}
}
}
if
(
pos
!=
null
)
{
return
pos
;
}
//可用的料仓(在线,且可以放入)
List
<
Storage
>
availbleStorageList
=
new
ArrayList
<>();
for
(
Storage
storage
:
storageList
)
{
if
(
storage
.
canPutIn
(
barcode
.
getPlateSize
(),
barcode
.
getHeight
()))
{
availbleStorageList
.
add
(
storage
);
}
}
if
(
availbleStorageList
.
isEmpty
())
{
throw
new
ValidateException
(
"smfcore.noValidStorage"
,
"[{0}]料仓列表中未找到可用的料仓"
,
new
String
[]{
barcode
.
getBarcode
()});
}
/*availbleStorageList.sort(new Comparator<Storage>() {
@Override
public int compare(Storage o1, Storage o2) {
Integer taskCount1 = storageTaskCountMap.get(o1.getId());
Integer taskCount2 = storageTaskCountMap.get(o2.getId());
return taskCount1.compareTo(taskCount2);
}
});*/
return
dualPosNameFindEmptyPosInStorages
(
barcode
,
availbleStorageList
,
hasOutTaskStorageIds
,
lastPosId
,
needMovePosName
,
endStr
);
}
private
synchronized
StoragePos
dualPosNameFindEmptyPosInStorages
(
Barcode
barcode
,
List
<
Storage
>
availbleStorageList
,
final
Set
<
String
>
hasOutTaskStorageIds
,
String
lastPosId
,
String
needMovePosName
,
String
endStr
)
{
List
<
String
>
needExcludePosName
=
new
ArrayList
<>();
//新增外侧有料,里侧没料,排除里侧的库位信息
List
<
StoragePos
>
allUsePosList
=
new
ArrayList
<>();
for
(
Storage
storage
:
availbleStorageList
)
{
Map
<
String
,
StoragePos
>
usedPosList
=
dataCache
.
getUsedPosList
(
storage
.
getCid
());
for
(
StoragePos
pos
:
usedPosList
.
values
())
{
allUsePosList
.
add
(
pos
);
}
}
for
(
StoragePos
pos
:
allUsePosList
)
{
String
posName
=
pos
.
getPosName
();
if
(
posName
.
endsWith
(
"_F"
))
{
boolean
hasEndBPos
=
false
;
String
posName_B
=
posName
.
substring
(
0
,
posName
.
length
()
-
1
)
+
"B"
;
for
(
StoragePos
usePos
:
allUsePosList
)
{
if
(
posName_B
.
equals
(
usePos
.
getPosName
()))
{
hasEndBPos
=
true
;
break
;
}
}
if
(!
hasEndBPos
)
{
needExcludePosName
.
add
(
posName_B
);
}
}
}
//第一遍查找,先不查找有出库任务的料仓
for
(
Storage
storage
:
availbleStorageList
)
{
if
(!
storage
.
isSmdDuo
()){
//DUO料仓无论是否有出库任务,都可以查找空库位
if
(
hasOutTaskStorageIds
.
contains
(
storage
.
getId
())){
continue
;
}
}
try
{
Collection
<
String
>
operatingPosIds
=
excludePosIds
();
log
.
debug
(
"尝试从["
+
storage
.
getCid
()
+
"]中为["
+
barcode
.
getBarcode
()
+
"]查找空位"
);
StoragePos
pos
=
storagePosManager
.
dualPosNameGetEmptyPosByStorage
(
storage
,
barcode
,
operatingPosIds
,
lastPosId
,
needMovePosName
,
endStr
,
needExcludePosName
);
if
(
pos
!=
null
)
{
return
pos
;
}
}
catch
(
Exception
e
)
{
log
.
error
(
"尝试从["
+
storage
.
getCid
()
+
"]中为["
+
barcode
.
getBarcode
()
+
"]查找空位失败:"
+
e
.
getMessage
());
}
}
//第二遍查找,从所有料仓中查找
for
(
Storage
storage
:
availbleStorageList
)
{
try
{
Collection
<
String
>
operatingPosIds
=
excludePosIds
();
log
.
debug
(
"尝试从["
+
storage
.
getCid
()
+
"]中为["
+
barcode
.
getBarcode
()
+
"]查找空位"
);
StoragePos
pos
=
storagePosManager
.
dualPosNameGetEmptyPosByStorage
(
storage
,
barcode
,
operatingPosIds
,
lastPosId
,
needMovePosName
,
endStr
,
needExcludePosName
);
if
(
pos
!=
null
)
{
return
pos
;
}
}
catch
(
Exception
e
)
{
log
.
error
(
"尝试从["
+
storage
.
getCid
()
+
"]中为["
+
barcode
.
getBarcode
()
+
"]查找空位失败:"
+
e
.
getMessage
());
}
}
try
{
String
cids
=
""
;
for
(
Storage
storage
:
availbleStorageList
)
{
cids
=
cids
+
storage
.
getCid
()
+
","
;
}
log
.
info
(
barcode
.
getBarcode
()
+
" 未找到可用库位,可用料仓:"
+
cids
);
}
catch
(
Exception
e
)
{
log
.
error
(
"打印可用料仓出错"
,
e
);
}
return
null
;
}
/**
* 查找可以移库的目标库位
*
* @param storageList
* @param barcode
* @return
*/
public
StoragePos
dualPosNameFindEmptyPosForMoveIn
(
List
<
Storage
>
storageList
,
Barcode
barcode
,
String
inRFID
,
String
lastPosId
,
String
needMovePosName
,
String
endStr
)
throws
ValidateException
{
Collection
<
DataLog
>
queueTasks
=
getQueueTasks
();
List
<
DataLog
>
allTasksa
=
getFinishedTasks
();
if
(!
queueTasks
.
isEmpty
())
{
allTasksa
.
addAll
(
queueTasks
);
}
for
(
DataLog
task
:
allTasksa
)
{
if
(
task
.
isPutInTask
())
{
if
(
task
.
isFinished
()
||
task
.
isCancel
()){
continue
;
}
if
(
task
.
getBarcode
().
equals
(
barcode
.
getBarcode
()))
{
//同一个条码的入库任务
for
(
Storage
storage
:
storageList
)
{
if
(
task
.
getStorageId
().
equals
(
storage
.
getId
())
&&
task
.
isPutInTask
())
{
log
.
error
(
"料盘["
+
barcode
.
getBarcode
()+
"]的操作未完成,无法执行入库操作"
);
throw
new
ValidateException
(
"smfcore.error.barcode.taskNotEnd"
,
"料盘[{0}}]的操作未完成,无法执行入库操作"
,
new
String
[]{
barcode
.
getBarcode
()});
}
}
}
}
}
List
<
String
>
storageIds
=
new
ArrayList
<>();
//查找任务数最少的料仓
final
Map
<
String
,
Integer
>
storageTaskCountMap
=
new
HashMap
<>();
for
(
Storage
storage
:
storageList
)
{
storageTaskCountMap
.
put
(
storage
.
getId
(),
0
);
storageIds
.
add
(
storage
.
getId
());
}
Set
<
String
>
hasOutTaskStorageIds
=
new
HashSet
<>();
//如果有正在执行的任务,把库位发过去
Collection
<
DataLog
>
allTasks
=
taskMap
.
values
();
for
(
DataLog
task
:
allTasks
)
{
/*if (barcode.getBarcode().equals(task.getBarcode())) {
String posId = task.getPosId();
log.info(barcode.getBarcode() + " 已有任务,返回任务中的库位:" + task.getPosName());
return storagePosManager.get(posId);
}*/
String
storageId
=
task
.
getStorageId
();
if
(!
Strings
.
isNullOrEmpty
(
storageId
))
{
Integer
taskCount
=
storageTaskCountMap
.
get
(
storageId
);
if
(
taskCount
!=
null
)
{
taskCount
=
taskCount
+
1
;
storageTaskCountMap
.
put
(
storageId
,
taskCount
);
}
if
(
task
.
isCheckOutTask
())
{
hasOutTaskStorageIds
.
add
(
storageId
);
}
}
}
String
lockPosId
=
ReelLockPosUtil
.
getReelLockPosId
(
barcode
.
getBarcode
());
StoragePos
pos
=
null
;
if
(!
Strings
.
isNullOrEmpty
(
lockPosId
))
{
//已有锁定库位
pos
=
storagePosManager
.
get
(
lockPosId
);
if
(
pos
!=
null
)
{
if
(!
storageIds
.
contains
(
pos
.
getStorageId
())){
log
.
info
(
"条码["
+
barcode
.
getBarcode
()
+
"]已有锁定库位["
+
pos
.
getPosName
()
+
"],料仓ID["
+
pos
.
getStorageId
()+
"]不在请求列表["
+
String
.
join
(
","
,
storageIds
)+
"]中,重新查找库位"
);
pos
=
null
;
}
else
if
(
pos
.
getW
()
<
barcode
.
getPlateSize
()
||
pos
.
getH
()
<
barcode
.
getHeight
())
{
log
.
info
(
"条码["
+
barcode
.
getBarcode
()
+
"]尺寸已改变,无法放入已锁定库位["
+
pos
.
getPosName
()
+
"],重新查找库位"
);
pos
=
null
;
}
else
{
Barcode
posBarcode
=
pos
.
getBarcode
();
if
(
posBarcode
==
null
)
{
log
.
info
(
"条码["
+
barcode
.
getBarcode
()
+
"]已锁定库位["
+
pos
.
getPosName
()
+
"],返回锁定中的库位"
);
}
else
{
log
.
info
(
"条码["
+
barcode
.
getBarcode
()
+
"]已锁定库位["
+
pos
.
getPosName
()
+
"]中已有物料["
+
posBarcode
.
getBarcode
()
+
"],重新查找库位"
);
pos
=
null
;
}
}
}
}
if
(
pos
!=
null
)
{
return
pos
;
}
//可用的料仓(在线,且可以放入)
List
<
Storage
>
availbleStorageList
=
new
ArrayList
<>();
for
(
Storage
storage
:
storageList
)
{
if
(
storage
.
canPutIn
(
barcode
.
getPlateSize
(),
barcode
.
getHeight
()))
{
availbleStorageList
.
add
(
storage
);
}
}
if
(
availbleStorageList
.
isEmpty
())
{
throw
new
ValidateException
(
"smfcore.noValidStorage"
,
"[{0}]料仓列表中未找到可用的料仓"
,
new
String
[]{
barcode
.
getBarcode
()});
}
availbleStorageList
.
sort
(
new
Comparator
<
Storage
>()
{
@Override
public
int
compare
(
Storage
o1
,
Storage
o2
)
{
Integer
taskCount1
=
storageTaskCountMap
.
get
(
o1
.
getId
());
Integer
taskCount2
=
storageTaskCountMap
.
get
(
o2
.
getId
());
return
taskCount1
.
compareTo
(
taskCount2
);
}
});
return
dualPosNameFindEmptyPosInStorages
(
barcode
,
availbleStorageList
,
hasOutTaskStorageIds
,
lastPosId
,
needMovePosName
,
endStr
);
}
}
src/main/java/com/neotel/smfcore/custom/aiqingzhiyin1643/momo/MomoApi.java
查看文件 @
1449ec1
...
...
@@ -96,7 +96,8 @@ public class MomoApi extends BaseSmfApiListener {
Barcode
barcode
=
barcodeManager
.
findByBarcode
(
barcodeStr
);
String
stockoutNo
=
barcode
.
getStockoutNo
();
if
(
StringUtils
.
isNotEmpty
(
stockoutNo
))
{
stockOut
(
barcode
);
barcode
.
setPartNumber
(
task
.
getPartNumber
());
stockOut
(
barcode
,
barcode
.
getAmount
());
}
}
}
...
...
@@ -248,7 +249,7 @@ public class MomoApi extends BaseSmfApiListener {
* @param barcode 条码对象
* @return StockoutResponse MOM接口返回的响应结果(异常时返回null/封装错误信息)
*/
public
StockoutResponse
stockOut
(
Barcode
barcode
)
{
public
StockoutResponse
stockOut
(
Barcode
barcode
,
int
opQty
)
{
// 1. 空值校验:条码/出库单号为空时,直接返回null并记录日志
if
(
barcode
==
null
||
StringUtils
.
isEmpty
(
barcode
.
getStockoutNo
()))
{
log
.
warn
(
"接口5:MOM接收WMS的出库结果-参数无效,barcode={},stockoutNo={}"
,
...
...
@@ -264,7 +265,12 @@ public class MomoApi extends BaseSmfApiListener {
?
barcode
.
getPidBarcode
()
:
barcode
.
getBarcode
());
itemMap
.
put
(
"ProductName"
,
barcode
.
getDescription
());
itemMap
.
put
(
"ProductNo"
,
barcode
.
getPartNumber
());
itemMap
.
put
(
"QuantityOnHand"
,
barcode
.
getAmount
());
if
(
barcode
.
getAmount
()
!=
0
){
itemMap
.
put
(
"QuantityOnHand"
,
barcode
.
getAmount
());
}
else
{
itemMap
.
put
(
"QuantityOnHand"
,
opQty
);
}
itemMap
.
put
(
"StockoutNoLine"
,
barcode
.
getStockoutNoLine
());
detailItems
.
add
(
itemMap
);
paramMap
.
put
(
"DetailItems"
,
detailItems
);
...
...
src/main/java/com/neotel/smfcore/custom/aiqingzhiyin1643/structuralWarehouse/controller/AgvDeviceController.java
查看文件 @
1449ec1
...
...
@@ -391,12 +391,20 @@ public class AgvDeviceController {
if
(
StringUtils
.
isNotEmpty
(
barcode
.
getStockoutNo
()))
{
if
(
barcode
.
getAmount
()
==
0
)
{
StockoutResponse
stockoutResponse
=
momoApi
.
stockOut
(
barcode
);
StockoutResponse
stockoutResponse
=
momoApi
.
stockOut
(
barcode
,
opQty
);
if
(!
stockoutResponse
.
getIsSuccess
())
{
return
ResultBean
.
newErrorResult
(-
1
,
"smfcore.momo.stockOutError"
,
stockoutResponse
.
getErrorMessage
(),
new
String
[]{});
}
}
else
{
GetNewContainerNoResponse
newContainerNo
=
momoApi
.
getNewContainerNo
(
new
GetNewContainerNoRequest
(
barcode
.
getProvider
()));
String
provider
=
barcode
.
getProvider
();
String
pidBarcodeStr
=
barcode
.
getPidBarcode
();
if
(
StringUtils
.
isNotEmpty
(
pidBarcodeStr
)){
Barcode
pidBarcode
=
barcodeManager
.
findByBarcode
(
pidBarcodeStr
);
if
(
pidBarcode
!=
null
){
provider
=
pidBarcode
.
getProvider
();
}
}
GetNewContainerNoResponse
newContainerNo
=
momoApi
.
getNewContainerNo
(
new
GetNewContainerNoRequest
(
provider
));
if
(!
"200"
.
equals
(
newContainerNo
.
getResult
()))
{
return
ResultBean
.
newErrorResult
(-
1
,
"smfcore.momo.newBarcodeContentError"
,
"获取新的条码内容失败[{0}]"
,
new
String
[]{
newContainerNo
.
getMessage
()});
}
...
...
@@ -414,7 +422,7 @@ public class AgvDeviceController {
splitBarcode
.
setBarcode
(
newContainerNo
.
getData
());
splitBarcode
.
setAmount
(
opQty
);
splitBarcode
.
setNeedStockNum
(
0
);
StockoutResponse
stockoutResponse
=
momoApi
.
stockOut
(
splitBarcode
);
StockoutResponse
stockoutResponse
=
momoApi
.
stockOut
(
splitBarcode
,
opQty
);
if
(!
stockoutResponse
.
getIsSuccess
())
{
return
ResultBean
.
newErrorResult
(-
1
,
"smfcore.momo.stockOutError"
,
stockoutResponse
.
getErrorMessage
(),
new
String
[]{});
}
...
...
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论