Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
孙克
/
smf-core
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit 4b69d55c
由
zshaohui
编写于
2025-11-11 10:47:10 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
1.增加双库位获取库位号,移库功能
1 个父辈
a6ad05c1
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
907 行增加
和
0 行删除
src/main/java/com/neotel/smfcore/core/device/rest/DualPosNameDeviceController.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/core/device/rest/DualPosNameDeviceController.java
0 → 100644
查看文件 @
4b69d55
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.po.Barcode
;
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.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
=
""
;
/**
* 流水线入库查找空的料格
*/
@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
();
if
(
dataCache
.
getCache
(
Constants
.
CACHE_StopOut
))
{
lineMsg
=
"系统更新中,暂停出入库"
;
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"
);
resultMap
.
put
(
"msg"
,
"未指定料仓 cids "
);
}
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
=
"无可用的料仓"
;
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
=
"物料["
+
dataLog
.
getBarcode
()
+
"]已有出库任务,需继续执行出库动作"
;
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
()});
}
//先移除被锁定的库位
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
=
rfid
+
"["
+
rfidLoc
+
"]["
+
barcode
.
getBarcode
()
+
"]锁定库位["
+
pos
.
getPosName
()
+
"],清理旧有锁定信息"
;
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
=
"["
+
barcode
.
getBarcode
()
+
"]库位["
+
reelLocInfo
.
getLockPosName
()
+
"]已被锁定,暂停入库"
;
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
=
"["
+
barcode
.
getBarcode
()
+
"]未找到可用的["
+
barcode
.
getPlateSize
()
+
"x"
+
barcode
.
getHeight
()
+
"]仓位"
;
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
.
dualPosNameFindEmptyPosForPutIn
(
storageList
,
barcode
,
""
,
""
,
needMovePosName
,
endStr
);
if
(
pos
==
null
)
{
if
(
"F"
.
equals
(
endStr
))
{
}
else
{
endStr
=
"F"
;
pos
=
taskService
.
dualPosNameFindEmptyPosForPutIn
(
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/service/manager/IStoragePosManager.java
查看文件 @
4b69d55
...
@@ -100,4 +100,8 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
...
@@ -100,4 +100,8 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
List
<
StoragePos
>
findPosListByPartNumber
(
List
<
String
>
storageIdList
,
String
pn
,
Collection
<
String
>
excludePosIds
,
CHECKOUT_TYPE
checkOutType
,
Map
<
String
,
String
>
appendData
);
List
<
StoragePos
>
findPosListByPartNumber
(
List
<
String
>
storageIdList
,
String
pn
,
Collection
<
String
>
excludePosIds
,
CHECKOUT_TYPE
checkOutType
,
Map
<
String
,
String
>
appendData
);
List
<
StoragePos
>
findPosListByMpn
(
List
<
String
>
availableStorageIds
,
String
mpn
,
Collection
<
String
>
excludePosIds
,
CHECKOUT_TYPE
checkoutType
,
Map
<
String
,
String
>
appendDate
);
List
<
StoragePos
>
findPosListByMpn
(
List
<
String
>
availableStorageIds
,
String
mpn
,
Collection
<
String
>
excludePosIds
,
CHECKOUT_TYPE
checkoutType
,
Map
<
String
,
String
>
appendDate
);
int
getRemainPosCountByStorage
(
Storage
storage
,
Barcode
barcode
,
Collection
<
String
>
excludePosIds
,
String
lastPosId
,
String
endStr
)
throws
ValidateException
;
StoragePos
dualPosNameGetEmptyPosByStorage
(
Storage
storage
,
Barcode
barcode
,
Collection
<
String
>
excludePosIds
,
String
lastPosId
,
String
needMovePosName
,
String
endStr
,
List
<
String
>
needExcludePosNameList
)
throws
ValidateException
;
}
}
src/main/java/com/neotel/smfcore/core/storage/service/manager/impl/StoragePosManagerImpl.java
查看文件 @
4b69d55
...
@@ -1033,4 +1033,95 @@ public class StoragePosManagerImpl implements IStoragePosManager {
...
@@ -1033,4 +1033,95 @@ public class StoragePosManagerImpl implements IStoragePosManager {
q
.
with
(
sort
);
q
.
with
(
sort
);
return
storagePosDao
.
findByQuery
(
q
);
return
storagePosDao
.
findByQuery
(
q
);
}
}
@Override
public
int
getRemainPosCountByStorage
(
Storage
storage
,
Barcode
barcode
,
Collection
<
String
>
excludePosIds
,
String
lastPosId
,
String
endStr
)
throws
ValidateException
{
Criteria
c
=
Criteria
.
where
(
"storageId"
).
is
(
storage
.
getId
());
COMPATIBLE_TYPE
compatibleType
=
storage
.
getCompatibleType
();
if
(
compatibleType
==
COMPATIBLE_TYPE
.
EXACT_MATCH
)
{
//完全匹配
c
=
c
.
and
(
"w"
).
is
(
barcode
.
getPlateSize
()).
and
(
"h"
).
is
(
barcode
.
getHeight
());
}
else
if
(
compatibleType
==
COMPATIBLE_TYPE
.
FULLY_COMPATIBLE
)
{
//同厚度兼容
c
=
c
.
and
(
"w"
).
gte
(
barcode
.
getPlateSize
()).
and
(
"h"
).
gte
(
barcode
.
getHeight
());
//除7寸外,完全兼容
}
else
if
(
compatibleType
==
COMPATIBLE_TYPE
.
SIZE_COMPATIBLE
)
{
//同尺寸兼容
c
=
c
.
and
(
"w"
).
is
(
barcode
.
getPlateSize
()).
and
(
"h"
).
gte
(
barcode
.
getHeight
());
//宽度等于料盘宽度,高度大于等于料盘高度
}
c
=
c
.
and
(
"enabled"
).
is
(
true
)
//可用
.
and
(
"used"
).
is
(
false
);
//未使用
//去除的仓位
if
(
excludePosIds
!=
null
&&
!
excludePosIds
.
isEmpty
())
{
c
=
c
.
and
(
"id"
).
nin
(
excludePosIds
);
}
if
(
StringUtils
.
isNotEmpty
(
endStr
))
{
String
regex
=
""
+
endStr
+
"$"
;
c
.
and
(
"posName"
).
regex
(
Pattern
.
compile
(
regex
));
}
Query
query
=
new
Query
(
c
);
query
.
with
(
Sort
.
by
(
Sort
.
Direction
.
ASC
,
"w"
).
and
(
Sort
.
by
(
Sort
.
Direction
.
ASC
,
"h"
)).
and
(
Sort
.
by
(
Sort
.
Direction
.
DESC
,
"priority"
)));
return
storagePosDao
.
countByQuery
(
query
);
}
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
)
throws
ValidateException
{
Criteria
c
=
Criteria
.
where
(
"storageId"
).
is
(
storage
.
getId
());
COMPATIBLE_TYPE
compatibleType
=
storage
.
getCompatibleType
();
if
(
compatibleType
==
COMPATIBLE_TYPE
.
EXACT_MATCH
)
{
//完全匹配
c
=
c
.
and
(
"w"
).
is
(
barcode
.
getPlateSize
()).
and
(
"h"
).
is
(
barcode
.
getHeight
());
}
else
if
(
compatibleType
==
COMPATIBLE_TYPE
.
FULLY_COMPATIBLE
)
{
//同厚度兼容
c
=
c
.
and
(
"w"
).
gte
(
barcode
.
getPlateSize
()).
and
(
"h"
).
gte
(
barcode
.
getHeight
());
//除7寸外,完全兼容
}
else
if
(
compatibleType
==
COMPATIBLE_TYPE
.
SIZE_COMPATIBLE
)
{
//同尺寸兼容
c
=
c
.
and
(
"w"
).
is
(
barcode
.
getPlateSize
()).
and
(
"h"
).
gte
(
barcode
.
getHeight
());
//宽度等于料盘宽度,高度大于等于料盘高度
}
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
;
}
}
}
src/main/java/com/neotel/smfcore/core/system/util/TaskService.java
查看文件 @
4b69d55
...
@@ -1448,4 +1448,169 @@ public class TaskService {
...
@@ -1448,4 +1448,169 @@ 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
;
}
}
}
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论