Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
孙克
/
smf-core
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit 8188eac1
由
LN
编写于
2021-12-30 17:18:38 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
增阿虚拟仓和看板功能。
1 个父辈
eb6935dd
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
259 行增加
和
0 行删除
src/main/java/com/neotel/smfcore/core/device/bean/VirtualOperateBean.java
src/main/java/com/neotel/smfcore/core/device/handler/impl/VirtualBoxHandler.java
src/main/java/com/neotel/smfcore/core/device/bean/VirtualOperateBean.java
0 → 100644
查看文件 @
8188eac
package
com
.
neotel
.
smfcore
.
core
.
device
.
bean
;
import
com.neotel.smfcore.core.storage.service.po.StoragePos
;
import
lombok.Data
;
@Data
public
class
VirtualOperateBean
{
private
String
sessionId
;
private
long
updateTime
;
/**
* 当前操作库位信息
*/
private
StoragePos
opPos
;
public
StoragePos
getOpPos
()
{
return
opPos
;
}
public
void
setOpPos
(
StoragePos
opPos
)
{
updateOpTime
();
this
.
opPos
=
opPos
;
}
public
String
getSessionId
()
{
return
sessionId
;
}
public
void
setSessionId
(
String
sessionId
)
{
updateOpTime
();
this
.
sessionId
=
sessionId
;
}
public
long
getUpdateTime
()
{
return
updateTime
;
}
public
void
setUpdateTime
(
long
updateTime
)
{
this
.
updateTime
=
updateTime
;
}
private
void
updateOpTime
(){
setUpdateTime
(
System
.
currentTimeMillis
());
}
/**
* 1个小时没有任何操作,即认为超时
*/
public
boolean
timeOut
(){
if
(
updateTime
>
0
){
return
System
.
currentTimeMillis
()
-
updateTime
>
1
*
60
*
60
*
1000
;
}
return
false
;
}
}
src/main/java/com/neotel/smfcore/core/device/handler/impl/VirtualBoxHandler.java
0 → 100644
查看文件 @
8188eac
package
com
.
neotel
.
smfcore
.
core
.
device
.
handler
.
impl
;
import
cn.hutool.core.util.ObjectUtil
;
import
com.google.common.base.Strings
;
import
com.neotel.smfcore.common.bean.ResultBean
;
import
com.neotel.smfcore.common.exception.ValidateException
;
import
com.neotel.smfcore.common.utils.SecurityUtils
;
import
com.neotel.smfcore.core.barcode.service.po.Barcode
;
import
com.neotel.smfcore.core.device.api.IOpAuthApi
;
import
com.neotel.smfcore.core.device.bean.NLShelfOperateBean
;
import
com.neotel.smfcore.core.device.bean.VirtualOperateBean
;
import
com.neotel.smfcore.core.order.service.manager.ILiteOrderManager
;
import
com.neotel.smfcore.core.order.service.po.LiteOrder
;
import
com.neotel.smfcore.core.storage.enums.DeviceType
;
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.po.DataLog
;
import
com.neotel.smfcore.security.TokenProvider
;
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.security.access.prepost.PreAuthorize
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.ObjectUtils
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.Collection
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
/**
* 虚拟料仓
*/
@Api
(
tags
=
"BOX: 虚拟仓"
)
@RestController
@Slf4j
public
class
VirtualBoxHandler
extends
BaseDeviceHandler
{
//上一次入库的库位,用于扫下一条码时灭灯
private
static
Map
<
String
,
VirtualOperateBean
>
devidePutInBeanMap
=
new
ConcurrentHashMap
<>();
@Autowired
private
TokenProvider
tokenProvider
;
@Autowired
private
ILiteOrderManager
liteOrderManager
;
public
VirtualBoxHandler
(
List
<
IOpAuthApi
>
apiList
)
{
super
(
apiList
);
}
/**
* 扫码
*/
@ApiOperation
(
"扫码入库"
)
@PostMapping
(
"/api/virtual/codeIn"
)
@PreAuthorize
(
"@el.check('virtual:putIn')"
)
public
ResultBean
codeIn
(
@RequestBody
Map
<
String
,
String
>
mapValues
,
HttpServletRequest
request
)
{
String
code
=
mapValues
.
get
(
"code"
).
trim
();
String
groupId
=
mapValues
.
get
(
"group"
);
String
storageId
=
mapValues
.
get
(
"storageId"
);
String
sourceId
=
mapValues
.
get
(
"sourceId"
);
String
token
=
tokenProvider
.
getToken
(
request
);
String
ptoken
=
token
.
substring
(
token
.
length
()
-
10
);
String
loginUser
=
SecurityUtils
.
getLoginUsername
();
if
(
ObjectUtils
.
isEmpty
(
code
))
{
throw
new
ValidateException
(
"smfcore.valueCanotNull"
,
"{0}不能为空"
,
new
String
[]{
"code"
});
}
if
(
groupId
==
null
&&
storageId
==
null
)
{
throw
new
ValidateException
(
"smfcore.valueCanotNull"
,
"{0}不能为空"
,
new
String
[]{
"group"
});
}
Storage
currentStorage
=
null
;
if
(
groupId
==
null
&&
storageId
!=
null
)
{
currentStorage
=
dataCache
.
getStorageById
(
storageId
);
if
(
currentStorage
==
null
||
!
currentStorage
.
isVirtual
())
{
return
ResultBean
.
newErrorResult
(
1
,
"smfcore.virtual.notFound"
,
"未找到虚拟仓"
);
}
groupId
=
currentStorage
.
getGroupId
();
}
if
(
groupId
!=
null
&&
groupId
.
equals
(
"-1"
))
{
groupId
=
""
;
}
int
delayCloseTime
=
30000
;
StoragePos
pos
=
storagePosManager
.
getByPosName
(
code
);
if
(
pos
==
null
)
{
//库位的条码有可能是前面带了SOxxx-,所以这里去除SO-再查一遍库位,保持与之前的兼容
int
index
=
code
.
indexOf
(
"-"
);
if
(
index
>=
0
)
{
String
posNameStr
=
code
.
substring
(
index
+
1
);
pos
=
storagePosManager
.
getByPosName
(
posNameStr
);
}
}
if
(
pos
!=
null
)
{
//判断库位是否是对应设备或者租
if
(
currentStorage
!=
null
)
{
if
(!
pos
.
getStorageId
().
equals
(
storageId
))
{
return
ResultBean
.
newErrorResult
(
1
,
"smfcore.virtual.pos.notInStorage"
,
"虚拟仓[{0}]中未找到库位[{1}]"
,
new
String
[]{
currentStorage
.
getName
(),
pos
.
getPosName
()});
}
}
else
{
currentStorage
=
dataCache
.
getStorageById
(
pos
.
getStorageId
());
if
(
currentStorage
==
null
||
!
currentStorage
.
isVirtual
())
{
return
ResultBean
.
newErrorResult
(
1
,
"smfcore.virtual.notFound"
,
"未找到虚拟仓"
);
}
if
(
currentStorage
.
getGroupId
()
!=
groupId
)
{
return
ResultBean
.
newErrorResult
(
1
,
"smfcore.shelf.pos.notInGroup"
,
"组中未找到库位[{0}]"
,
new
String
[]{
pos
.
getPosName
()});
}
}
//扫描的为库位条码记录库位
if
(
pos
.
getBarcode
()
!=
null
)
{
return
ResultBean
.
newErrorResult
(
1
,
"smfcore.shelf.msg.hasReel"
,
"库位中[{0}]已有物料"
,
new
String
[]{
pos
.
getPosName
()});
}
else
{
VirtualOperateBean
operateBean
=
getOperateBean
(
token
);
operateBean
.
setOpPos
(
pos
);
devidePutInBeanMap
.
put
(
token
,
operateBean
);
log
.
info
(
ptoken
+
":库位["
+
pos
.
getPosName
()
+
"]操作成功,请扫描要放入的物料"
);
return
ResultBean
.
newOkResult
(
"smfcore.shelf.msg.tipScanReel"
,
"库位["
+
pos
.
getPosName
()
+
"]操作成功,请扫描要放入的物料"
,
new
String
[]{
pos
.
getPosName
()},
pos
.
getPosName
());
}
}
else
{
//扫的是物料条码
Barcode
barcode
=
codeResolve
.
resolveOneValideBarcode
(
"=1x1="
+
code
);
Date
expireDate
=
barcode
.
getExpireDate
();
if
(
expireDate
!=
null
)
{
if
(
System
.
currentTimeMillis
()
>
expireDate
.
getTime
())
{
throw
new
ValidateException
(
"smfcore.error.barcode.expired"
,
"物料已过期,无法入库."
);
}
}
try
{
//5秒内同一个条码忽略
Date
usedDate
=
barcode
.
getUsedDate
();
if
(
usedDate
!=
null
&&
(
System
.
currentTimeMillis
()
-
usedDate
.
getTime
())
<
5000
)
{
return
ResultBean
.
newErrorResult
(
1
,
"smfcore.shelf.msg.fastop"
,
"条码操作频繁,请稍后再试"
);
}
StoragePos
inPos
=
storagePosManager
.
getByBarcodeId
(
barcode
.
getId
());
if
(
inPos
!=
null
)
{
Collection
<
DataLog
>
allTasks
=
taskService
.
getQueueTasks
();
for
(
DataLog
task
:
allTasks
)
{
if
(
task
.
isCheckOutTask
()
&&
task
.
getBarcode
()
!=
null
&&
task
.
getBarcode
().
equals
(
barcode
.
getBarcode
()))
{
if
(
ObjectUtil
.
isNotEmpty
(
sourceId
)
&&
!
sourceId
.
equals
(
task
.
getSourceId
()))
{
LiteOrder
liteOrder
=
liteOrderManager
.
get
(
sourceId
);
if
(
liteOrder
!=
null
)
{
return
ResultBean
.
newErrorResult
(
1
,
"smfcore.shelf.error.orderError"
,
"任务与指定工单[{0}]不一致"
,
new
String
[]{
liteOrder
.
getOrderNo
()});
}
else
{
return
ResultBean
.
newErrorResult
(
1
,
"smfcore.shelf.error.orderError"
,
"任务与指定工单[{0}]不一致"
,
new
String
[]{
sourceId
});
}
}
taskService
.
addTaskToFinished
(
inPos
,
null
,
loginUser
);
log
.
info
(
barcode
.
getBarcode
()
+
" 库位["
+
inPos
.
getPosName
()
+
"]出库完成 "
);
return
ResultBean
.
newErrorResult
(
1
,
"smfcore.virtual.msg.outConfirm"
,
"[{0}]出库完成"
,
new
String
[]{
inPos
.
getPosName
()});
}
}
return
ResultBean
.
newErrorResult
(
1
,
"smfcore.shelf.msg.noTask"
,
"操作失败,已在库位[{0}]中,未找到对应的出库任务"
,
new
String
[]{
inPos
.
getPosName
()});
}
//入库
VirtualOperateBean
operateBean
=
getOperateBean
(
token
);
StoragePos
opPos
=
operateBean
.
getOpPos
();
if
(
opPos
==
null
)
{
log
.
info
(
ptoken
+
":条码["
+
code
+
"],请先扫描库位码"
);
return
ResultBean
.
newErrorResult
(
1
,
"smfcore.shelf.msg.scanPos"
,
"请先扫描库位码"
);
}
else
{
log
.
info
(
barcode
.
getPartNumber
()
+
" [ "
+
barcode
.
getBarcode
()
+
" ] "
+
"入库到:"
+
opPos
.
getPosName
());
opPos
.
setCanCheckOutTime
(
System
.
currentTimeMillis
()
+
delayCloseTime
);
taskService
.
addTaskToFinished
(
opPos
,
barcode
,
loginUser
);
//入库结束后清理信息,不自动到下一个库位
operateBean
.
setOpPos
(
null
);
devidePutInBeanMap
.
put
(
token
,
operateBean
);
log
.
info
(
ptoken
+
":条码["
+
code
+
"]入库操作成功,请放入库位 ["
+
opPos
.
getPosName
()
+
"]"
);
return
ResultBean
.
newOkResult
(
"smfcore.shelf.msg.inOk"
,
"操作成功,请放入库位["
+
opPos
.
getPosName
()
+
"]"
,
new
String
[]{
opPos
.
getPosName
()},
""
);
}
}
catch
(
ValidateException
e
)
{
log
.
error
(
"Error:"
+
e
.
getMessage
());
return
ResultBean
.
newErrorResult
(
1
,
e
.
getMessage
(),
e
.
getMessage
(),
e
.
getMsgParam
());
}
}
}
private
VirtualOperateBean
getOperateBean
(
String
sessionId
){
VirtualOperateBean
operateBean
=
devidePutInBeanMap
.
get
(
sessionId
);
if
(
operateBean
==
null
){
operateBean
=
new
VirtualOperateBean
();
operateBean
.
setSessionId
(
sessionId
);
devidePutInBeanMap
.
put
(
sessionId
,
operateBean
);
}
return
operateBean
;
}
@Override
public
DeviceType
getDeviceType
()
{
return
DeviceType
.
VIRTUAL
;
}
}
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论