Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
孙克
/
smf-core
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit 4b69d55c
由
zshaohui
编写于
2025-11-11 10:47:10 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
1.增加双库位获取库位号,移库功能
1 个父辈
a6ad05c1
全部展开
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
260 行增加
和
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
此文件的差异被折叠,
点击展开。
src/main/java/com/neotel/smfcore/core/storage/service/manager/IStoragePosManager.java
查看文件 @
4b69d55
...
...
@@ -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
>
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 {
q
.
with
(
sort
);
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 {
}
}
}
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
请
注册
或
登录
后发表评论