Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
孙克
/
smf-core
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit d89f1ab3
由
sunke
编写于
2022-06-27 18:23:54 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
哈曼料架功能
1 个父辈
17974676
隐藏空白字符变更
内嵌
并排
正在显示
21 个修改的文件
包含
1037 行增加
和
275 行删除
src/main/java/com/neotel/smfcore/common/base/AbstractBaseDao.java
src/main/java/com/neotel/smfcore/common/base/IBaseDao.java
src/main/java/com/neotel/smfcore/common/csv/CsvReader.java
src/main/java/com/neotel/smfcore/core/haman/enums/BIN_STATUS.java
src/main/java/com/neotel/smfcore/core/haman/listener/HamanOrderFileListener.java
src/main/java/com/neotel/smfcore/core/haman/rest/HamanController.java
src/main/java/com/neotel/smfcore/core/haman/rest/PosOutputController.java
src/main/java/com/neotel/smfcore/core/haman/rest/dto/BINPosDto.java
src/main/java/com/neotel/smfcore/core/haman/rest/mapstruct/BINPosMapper.java
src/main/java/com/neotel/smfcore/core/haman/rest/query/HamanBinQueryCondition.java
src/main/java/com/neotel/smfcore/core/haman/services/dao/IHamanBinPosDao.java
src/main/java/com/neotel/smfcore/core/haman/services/dao/impl/HamanBinPosDaoImpl.java
src/main/java/com/neotel/smfcore/core/haman/services/po/HamanBinPos.java
src/main/java/com/neotel/smfcore/core/order/enums/ORDER_COLOR.java
src/main/java/com/neotel/smfcore/core/order/listener/DefaultOrderFileListener.java
src/main/java/com/neotel/smfcore/core/order/listener/IOrderFileListener.java
src/main/java/com/neotel/smfcore/core/order/rest/OrderController.java
src/main/java/com/neotel/smfcore/core/order/util/OrderFileWatch.java
src/main/java/com/neotel/smfcore/core/storage/service/manager/impl/StoragePosManagerImpl.java
src/main/java/com/neotel/smfcore/security/config/SpringSecurityConfig.java
src/main/java/com/neotel/smfcore/security/config/SwaggerConfig.java
src/main/java/com/neotel/smfcore/common/base/AbstractBaseDao.java
查看文件 @
d89f1ab
...
...
@@ -3,8 +3,6 @@ package com.neotel.smfcore.common.base;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.PageRequest
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.mongodb.core.FindAndModifyOptions
;
import
org.springframework.data.mongodb.core.MongoTemplate
;
...
...
@@ -169,11 +167,10 @@ public abstract class AbstractBaseDao implements IBaseDao {
}
// @Override
// public List<String> distinct(String key, DBObject query){
// String collectionName = getMongoTemplate().getCollectionName(getEntityClass());
// return getMongoTemplate().getCollection(collectionName).distinct(key, query);
// }
@Override
public
List
<
String
>
distinct
(
String
field
,
Query
query
){
return
getMongoTemplate
().
findDistinct
(
query
,
field
,
getEntityClass
(),
String
.
class
);
}
public
<
T
extends
BasePo
>
void
removeByQuery
(
Query
query
)
{
List
<
T
>
list
=
getMongoTemplate
().
find
(
query
,
getEntityClass
());
...
...
src/main/java/com/neotel/smfcore/common/base/IBaseDao.java
查看文件 @
d89f1ab
...
...
@@ -47,6 +47,8 @@ public interface IBaseDao {
// List<String> distinct(String key, DBObject query);
List
<
String
>
distinct
(
String
field
,
Query
query
);
public
<
T
extends
BasePo
>
void
removeByQuery
(
Query
query
);
public
long
count
();
...
...
src/main/java/com/neotel/smfcore/common/csv/CsvReader.java
查看文件 @
d89f1ab
...
...
@@ -45,6 +45,7 @@ public class CsvReader {
//未找到列,重新读取
if
(
index
==
-
1
)
{
log
.
info
(
"文件未包含列["
+
titleName
+
"]["
+
titleNameEn
+
"],改为"
+
reloadEncodeing
+
"重新读取"
);
csvRead
.
close
();
csvRead
=
new
CsvReader
(
fileURL
,
CsvReader
.
Letters
.
COMMA
,
Charset
.
forName
(
reloadEncodeing
));
csvRead
.
setSkipEmptyRecords
(
true
);
csvRead
.
setTrimWhitespace
(
true
);
...
...
src/main/java/com/neotel/smfcore/core/haman/enums/BIN_STATUS.java
0 → 100644
查看文件 @
d89f1ab
package
com
.
neotel
.
smfcore
.
core
.
haman
.
enums
;
public
class
BIN_STATUS
{
/**
* 0无操作
*/
public
final
static
int
NEW
=
0
;
/**
* 1正在执行
*/
public
final
static
int
EXCUTING
=
1
;
/**
* 2 已完成
*/
public
final
static
int
FINISHED
=
2
;
}
src/main/java/com/neotel/smfcore/core/haman/listener/HamanOrderFileListener.java
0 → 100644
查看文件 @
d89f1ab
package
com
.
neotel
.
smfcore
.
core
.
haman
.
listener
;
import
cn.hutool.core.util.ObjectUtil
;
import
com.google.common.collect.Lists
;
import
com.neotel.smfcore.common.csv.CsvReader
;
import
com.neotel.smfcore.core.device.enums.OP
;
import
com.neotel.smfcore.core.device.util.DataCache
;
import
com.neotel.smfcore.core.haman.services.dao.IHamanBinPosDao
;
import
com.neotel.smfcore.core.haman.services.po.HamanBinPos
;
import
com.neotel.smfcore.core.order.LiteOrderCache
;
import
com.neotel.smfcore.core.order.listener.DefaultOrderFileListener
;
import
com.neotel.smfcore.core.order.listener.IOrderFileListener
;
import
com.neotel.smfcore.core.order.service.manager.ILiteOrderManager
;
import
com.neotel.smfcore.core.order.service.po.LiteOrder
;
import
com.neotel.smfcore.core.order.service.po.LiteOrderItem
;
import
com.neotel.smfcore.core.system.bean.OrderSetting
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.logging.log4j.util.Strings
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.io.File
;
import
java.text.SimpleDateFormat
;
import
java.util.*
;
/**
* Created by sunke on 2021/7/12.
*/
@Service
@Slf4j
public
class
HamanOrderFileListener
extends
DefaultOrderFileListener
{
@Autowired
protected
IHamanBinPosDao
hamanBinPosDao
;
@Override
public
boolean
handleOrderFile
(
File
orderFile
)
{
String
fileName
=
orderFile
.
getName
();
if
(
isFileType
(
fileName
,
"csv"
)){
return
processHamanCsvFile
(
orderFile
);
}
return
false
;
}
public
boolean
processHamanCsvFile
(
File
file
)
{
CsvReader
csvRead
=
null
;
try
{
csvRead
=
new
CsvReader
(
file
.
getAbsolutePath
());
csvRead
.
setSkipEmptyRecords
(
true
);
//忽略空行
csvRead
.
setTrimWhitespace
(
true
);
//去除空格
csvRead
.
readHeaders
();
int
toNumberIndex
=
csvRead
.
getIndex
(
"Transfer Order Number"
);
if
(
toNumberIndex
!=
-
1
){
int
row
=
1
;
List
<
HamanBinPos
>
hamanBinPosList
=
Lists
.
newArrayList
();
while
(
csvRead
.
readRecord
())
{
row
++;
HamanBinPos
hamanBinPos
=
new
HamanBinPos
();
String
toNumber
=
csvRead
.
get
(
toNumberIndex
);
hamanBinPos
.
setToNumber
(
toNumber
);
String
material
=
csvRead
.
get
(
"Material"
);
hamanBinPos
.
setMaterial
(
material
);
String
batch
=
csvRead
.
get
(
"Batch"
);
hamanBinPos
.
setBatch
(
batch
);
//Source storage type = S02,则表示下架,对应的BIN位信息读取Source storage BIN
String
sourceType
=
csvRead
.
get
(
"Source Storage Type"
);
String
destType
=
csvRead
.
get
(
"Dest. Storage Type"
);
if
(
sourceType
.
toUpperCase
().
equals
(
"S02"
)){
hamanBinPos
.
setType
(
OP
.
CHECKOUT
);
String
sourceBin
=
csvRead
.
get
(
"Source Storage Bin"
);
hamanBinPos
.
setBinPos
(
sourceBin
);
}
else
if
(
destType
.
toUpperCase
().
equals
(
"S02"
)){
//Dest. Storage Type = S02,则表示上架,对应的BIN位信息读取Dest.Storage BIN
hamanBinPos
.
setType
(
OP
.
PUT_IN
);
String
destBin
=
csvRead
.
get
(
"Dest.Storage Bin"
);
hamanBinPos
.
setBinPos
(
destBin
);
}
else
{
log
.
info
(
"第 "
+
row
+
" 行destType="
+
sourceType
+
"destType="
+
destType
+
",都不是S02忽略"
);
continue
;
}
hamanBinPosList
.
add
(
hamanBinPos
);
}
if
(
hamanBinPosList
.
size
()
>
0
){
log
.
info
(
"共解析到"
+
hamanBinPosList
.
size
()+
"条有效数据"
);
hamanBinPosDao
.
insertAll
(
hamanBinPosList
);
return
true
;
}
}
}
catch
(
Exception
ex
)
{
log
.
error
(
"解析出错:"
+
ex
.
toString
());
}
finally
{
if
(
csvRead
!=
null
){
csvRead
.
close
();
}
}
return
false
;
}
}
src/main/java/com/neotel/smfcore/core/haman/rest/HamanController.java
0 → 100644
查看文件 @
d89f1ab
package
com
.
neotel
.
smfcore
.
core
.
haman
.
rest
;
import
cn.hutool.core.util.ObjectUtil
;
import
com.google.common.collect.Lists
;
import
com.neotel.smfcore.common.bean.PageData
;
import
com.neotel.smfcore.common.bean.ResultBean
;
import
com.neotel.smfcore.common.csv.CsvReader
;
import
com.neotel.smfcore.common.exception.ValidateException
;
import
com.neotel.smfcore.common.utils.FileUtil
;
import
com.neotel.smfcore.common.utils.QueryHelp
;
import
com.neotel.smfcore.common.utils.SecurityUtils
;
import
com.neotel.smfcore.core.device.util.DataCache
;
import
com.neotel.smfcore.core.haman.bean.BINPosInfo
;
import
com.neotel.smfcore.core.haman.enums.BIN_STATUS
;
import
com.neotel.smfcore.core.haman.rest.dto.BINPosDto
;
import
com.neotel.smfcore.core.haman.rest.mapstruct.BINPosMapper
;
import
com.neotel.smfcore.core.haman.rest.query.HamanBinQueryCondition
;
import
com.neotel.smfcore.core.haman.services.dao.IHamanBinPosDao
;
import
com.neotel.smfcore.core.haman.services.po.HamanBinPos
;
import
com.neotel.smfcore.core.inList.rest.bean.dto.InListDto
;
import
com.neotel.smfcore.core.inList.rest.bean.query.InListQueryCondition
;
import
com.neotel.smfcore.core.inList.service.po.InList
;
import
com.neotel.smfcore.core.order.enums.LITEORDER_STATUS
;
import
com.neotel.smfcore.core.order.enums.ORDER_COLOR
;
import
com.neotel.smfcore.core.order.rest.bean.dto.OrderDto
;
import
com.neotel.smfcore.core.order.rest.bean.query.OrderQueryCondition
;
import
com.neotel.smfcore.core.order.service.po.LiteOrder
;
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.util.DevicesStatusUtil
;
import
com.neotel.smfcore.security.TokenProvider
;
import
com.neotel.smfcore.security.annotation.AnonymousAccess
;
import
com.neotel.smfcore.security.bean.FileProperties
;
import
com.neotel.smfcore.security.service.po.Group
;
import
com.neotel.smfcore.security.service.po.User
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.logging.log4j.util.Strings
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.mongodb.core.query.Criteria
;
import
org.springframework.data.mongodb.core.query.Query
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.File
;
import
java.text.DecimalFormat
;
import
java.util.*
;
@Slf4j
@RestController
@RequiredArgsConstructor
@Api
(
tags
=
"哈曼接口"
)
@RequestMapping
(
"api/haman"
)
public
class
HamanController
{
@Autowired
private
IHamanBinPosDao
hamanBinPosDao
;
@Autowired
private
IStoragePosManager
storagePosManager
;
@Autowired
private
DataCache
dataCache
;
@Autowired
private
BINPosMapper
binPosMapper
;
@ApiOperation
(
"查询"
)
@GetMapping
(
"/search"
)
public
PageData
<
BINPosDto
>
query
(
HamanBinQueryCondition
criteria
,
Pageable
pageable
)
{
Query
query
=
QueryHelp
.
getQuery
(
criteria
);
PageData
<
HamanBinPos
>
list
=
hamanBinPosDao
.
findByPage
(
query
,
pageable
);
PageData
<
BINPosDto
>
resultList
=
binPosMapper
.
toDto
(
list
);
return
resultList
;
}
@ApiOperation
(
"上架扫描条码"
)
@PostMapping
(
value
=
"/loadMaterial"
)
@AnonymousAccess
public
ResultBean
loadMaterial
(
@RequestBody
Map
<
String
,
String
>
bodyParamMap
)
{
//解析二维码X@UID011490051762@CPN3831051@1T2112290001@Q2500@EXP20221201
//料盘二维码
String
code
=
bodyParamMap
.
get
(
"code"
);
log
.
info
(
"入库扫描条码:"
+
code
);
String
[]
codeItemArr
=
code
.
split
(
"@"
);
if
(
codeItemArr
.
length
==
6
){
String
material
=
codeItemArr
[
2
].
replace
(
"CPN"
,
""
);
String
batch
=
codeItemArr
[
3
].
replace
(
"1T"
,
""
);
HamanBinPos
putInBin
=
hamanBinPosDao
.
getPutInBin
(
material
,
batch
);
if
(
putInBin
!=
null
){
String
posName
=
convertToPos
(
putInBin
.
getBinPos
());
StoragePos
pos
=
storagePosManager
.
getByPosName
(
posName
);
if
(
pos
!=
null
){
String
storageId
=
pos
.
getStorageId
();
String
cid
=
dataCache
.
getStorageById
(
storageId
).
getCid
();
String
lightOnStr
=
pos
.
getPosName
()
+
"="
+
"green"
;
DevicesStatusUtil
.
appendOp
(
cid
,
"open"
,
lightOnStr
);
log
.
info
(
"操作成功,架位"
+
pos
.
getPosName
()
+
"亮绿灯,准备放入物料"
+
material
+
"["
+
batch
+
"]"
);
putInBin
.
setShelfCid
(
cid
);
putInBin
.
setShelfPos
(
pos
.
getPosName
());
putInBin
.
setStatus
(
BIN_STATUS
.
EXCUTING
);
hamanBinPosDao
.
save
(
putInBin
);
return
ResultBean
.
newOkResult
(
"smfcore.haman.loadOk"
,
"操作成功, 请将物料放入亮灯架位"
,
""
);
}
else
{
//未找到Bin位对应的料架位
String
msg
=
"未找到BIN位["
+
putInBin
.
getBinPos
()+
"]对应料料架位["
+
posName
+
"]"
;
log
.
error
(
msg
);
return
ResultBean
.
newErrorResult
(
1001
,
"smfcore.haman.binNotFound"
,
msg
);
}
}
else
{
//无效的条码
String
msg
=
"未找到条码["
+
code
+
"]对应的上架BIN位"
;
log
.
error
(
msg
);
return
ResultBean
.
newErrorResult
(
1002
,
"smfcore.haman.barcodeInvalid"
,
msg
);
}
}
else
{
//库位二维码查找正在执行的bin位
HamanBinPos
putInBin
=
hamanBinPosDao
.
getExecutingBin
(
code
);
if
(
putInBin
!=
null
){
//库位灭灯
String
cid
=
putInBin
.
getShelfCid
();
DevicesStatusUtil
.
appendOp
(
cid
,
"close"
,
putInBin
.
getShelfPos
()
+
"="
);
String
msg
=
"上架成功,物料"
+
putInBin
.
getMaterial
()
+
"所在架位灭灯"
;
log
.
info
(
msg
);
putInBin
.
setStatus
(
BIN_STATUS
.
FINISHED
);
hamanBinPosDao
.
save
(
putInBin
);
return
ResultBean
.
newOkResult
(
"smfcore.haman.load.finished"
,
msg
,
""
);
}
else
{
StoragePos
pos
=
storagePosManager
.
getByPosName
(
code
);
if
(
pos
!=
null
){
//是库位码,但无任务
String
msg
=
"未找到库位["
+
code
+
"]对应的上架任务"
;
log
.
info
(
msg
);
ResultBean
.
newErrorResult
(
1004
,
"smfcore.haman.noLoadTask"
,
msg
);
}
else
{
//不是库位码
String
msg
=
"扫描的条码无效["
+
code
+
"]"
;
log
.
error
(
msg
);
return
ResultBean
.
newErrorResult
(
1005
,
"smfcore.haman.barcodeInvalid"
,
msg
);
}
}
}
String
msg
=
"无效条码["
+
code
+
"]"
;
log
.
error
(
msg
);
return
ResultBean
.
newErrorResult
(
1006
,
"smfcore.haman.barcodeInvalid"
,
msg
);
}
@ApiOperation
(
"下架扫描条码"
)
@PostMapping
(
value
=
"/unloadMaterial"
)
@AnonymousAccess
public
ResultBean
unloadMaterial
(
@RequestBody
Map
<
String
,
String
>
bodyParamMap
)
{
String
code
=
bodyParamMap
.
get
(
"code"
);
log
.
info
(
"下架扫描条码:"
+
code
);
//库位二维码查找正在执行的bin位
HamanBinPos
bin
=
hamanBinPosDao
.
getExecutingBin
(
code
);
if
(
bin
!=
null
){
//库位灭灯
String
cid
=
bin
.
getShelfCid
();
DevicesStatusUtil
.
appendOp
(
cid
,
"close"
,
bin
.
getShelfPos
()
+
"="
);
String
msg
=
"下架操作成功,物料"
+
bin
.
getMaterial
()
+
"所在架位灭灯"
;
log
.
info
(
msg
);
bin
.
setStatus
(
BIN_STATUS
.
FINISHED
);
hamanBinPosDao
.
save
(
bin
);
return
ResultBean
.
newOkResult
(
"smfcore.haman.unload.finished"
,
msg
,
""
);
}
else
{
StoragePos
pos
=
storagePosManager
.
getByPosName
(
code
);
if
(
pos
!=
null
){
//是库位码,但无任务
String
msg
=
"未找到库位["
+
code
+
"]对应的下架任务"
;
log
.
info
(
msg
);
ResultBean
.
newErrorResult
(
2001
,
"smfcore.haman.noUnloadTask"
,
msg
);
}
}
//不是库位码
String
msg
=
"扫描的条码无效["
+
code
+
"]"
;
log
.
error
(
msg
);
return
ResultBean
.
newErrorResult
(
2002
,
"smfcore.haman.barcodeInvalid"
,
msg
);
}
@ApiOperation
(
value
=
"执行下架"
,
notes
=
"输入toNumber后执行下架动作"
)
@PostMapping
(
value
=
"/outToNumber"
)
@AnonymousAccess
public
ResultBean
outToNumber
(
@RequestBody
Map
<
String
,
String
>
bodyParamMap
)
{
String
toNumber
=
bodyParamMap
.
get
(
"toNumber"
);
log
.
info
(
"执行"
+
toNumber
+
"的下架任务"
);
List
<
HamanBinPos
>
taskList
=
hamanBinPosDao
.
listByToNumber
(
toNumber
);
if
(
taskList
.
isEmpty
()){
String
msg
=
"未找到"
+
toNumber
+
"未完成的下架任务"
;
log
.
info
(
msg
);
return
ResultBean
.
newErrorResult
(
3001
,
"smfcore.haman.outToNumber.invalid"
,
msg
);
}
String
color
=
taskList
.
get
(
0
).
getLightColor
();
if
(
Strings
.
isBlank
(
color
)){
//未设置过颜色
Collection
<
String
>
excludeColors
=
hamanBinPosDao
.
distinctColor
();
ORDER_COLOR
nextColor
=
ORDER_COLOR
.
nextColor
(
excludeColors
);
if
(
nextColor
==
null
){
return
ResultBean
.
newErrorResult
(
3002
,
"smfcore.haman.outToNumber.toMany"
,
"执行中的TO数量已达最大数量,请先完成正在执行的TO"
);
}
color
=
nextColor
.
name
();
}
for
(
HamanBinPos
hamanBinPos
:
taskList
)
{
if
(
hamanBinPos
.
getStatus
()
!=
BIN_STATUS
.
FINISHED
){
String
posName
=
convertToPos
(
hamanBinPos
.
getBinPos
());
StoragePos
pos
=
storagePosManager
.
getByPosName
(
posName
);
if
(
pos
!=
null
){
String
storageId
=
pos
.
getStorageId
();
String
cid
=
dataCache
.
getStorageById
(
storageId
).
getCid
();
String
lightOnStr
=
pos
.
getPosName
()
+
"="
+
color
;
DevicesStatusUtil
.
appendOp
(
cid
,
"open"
,
lightOnStr
);
log
.
info
(
"架位"
+
pos
.
getPosName
()
+
"亮灯("
+
color
+
"),物料"
+
hamanBinPos
.
getMaterial
()+
"["
+
hamanBinPos
.
getBinPos
()+
"]"
);
hamanBinPos
.
setShelfCid
(
cid
);
hamanBinPos
.
setShelfPos
(
pos
.
getPosName
());
hamanBinPos
.
setStatus
(
BIN_STATUS
.
EXCUTING
);
hamanBinPosDao
.
save
(
hamanBinPos
);
}
else
{
//未找到Bin位对应的料架位
String
msg
=
"未找到BIN位["
+
hamanBinPos
.
getBinPos
()+
"]对应料料架位["
+
posName
+
"],忽略"
;
log
.
error
(
msg
);
}
}
}
return
ResultBean
.
newOkResult
(
"smfcore.haman.outToNumber.ok"
,
"操作成功"
,
""
);
}
@ApiOperation
(
value
=
"获取下架列表"
,
notes
=
"下架页面定时获取下架的执行列表"
)
@GetMapping
(
value
=
"/unloadTasks"
)
@AnonymousAccess
public
List
<
BINPosDto
>
unloadTasks
()
{
List
<
HamanBinPos
>
executingList
=
hamanBinPosDao
.
listUnLoadExecutingTasks
();
List
<
BINPosDto
>
results
=
binPosMapper
.
toDto
(
executingList
);
return
results
;
}
@ApiOperation
(
value
=
"一键灭灯"
,
notes
=
"不扫库位码直接完成所有正在执行的出库任务"
)
@PostMapping
(
value
=
"/finishedAllTasks"
)
@AnonymousAccess
public
ResultBean
closeAllLed
(
@RequestBody
Map
<
String
,
String
>
bodyParamMap
)
{
String
toNumber
=
bodyParamMap
.
get
(
"toNumber"
);
log
.
info
(
"执行一键灭灯指令:"
+
toNumber
);
List
<
HamanBinPos
>
executingList
=
hamanBinPosDao
.
listByToNumber
(
toNumber
);
boolean
hasTask
=
false
;
for
(
HamanBinPos
outBinPos
:
executingList
)
{
if
(
outBinPos
.
getStatus
()
!=
BIN_STATUS
.
EXCUTING
){
String
cid
=
outBinPos
.
getShelfCid
();
DevicesStatusUtil
.
appendOp
(
cid
,
"close"
,
outBinPos
.
getShelfPos
()
+
"="
);
String
msg
=
"物料"
+
outBinPos
.
getMaterial
()
+
"所在架位["
+
outBinPos
.
getShelfPos
()+
"]灭灯"
;
log
.
info
(
msg
);
outBinPos
.
setStatus
(
BIN_STATUS
.
FINISHED
);
hamanBinPosDao
.
save
(
outBinPos
);
hasTask
=
true
;
}
}
if
(
hasTask
){
return
ResultBean
.
newOkResult
(
"操作成功"
);
}
else
{
return
ResultBean
.
newErrorResult
(
3001
,
"smfcore.oneKeyOff.noTask"
,
"未到到该TO号的正在执行的任务"
);
}
}
private
String
convertToPos
(
String
binStr
)
{
// 002-01-002
// S1-01-01
if
(
binStr
.
startsWith
(
"S"
))
{
String
[]
array
=
binStr
.
substring
(
1
,
binStr
.
length
()).
split
(
"-"
);
if
(
array
.
length
==
3
)
{
try
{
DecimalFormat
format3
=
new
DecimalFormat
(
"000"
);
DecimalFormat
format2
=
new
DecimalFormat
(
"00"
);
String
shelf
=
format3
.
format
(
Integer
.
parseInt
(
array
[
0
]));
String
hang
=
format2
.
format
(
Integer
.
parseInt
(
array
[
1
]));
String
num
=
format3
.
format
(
Integer
.
parseInt
(
array
[
2
]));
String
pos
=
shelf
+
"-"
+
hang
+
"-"
+
num
;
return
pos
;
}
catch
(
Exception
exception
)
{
log
.
info
(
"convertToPos["
+
binStr
+
"] error:"
+
exception
.
toString
());
}
}
}
return
binStr
;
}
}
src/main/java/com/neotel/smfcore/core/haman/rest/PosOutputController.java
查看文件 @
d89f1ab
...
...
@@ -54,70 +54,70 @@ public class PosOutputController {
private
List
<
BINPosInfo
>
posInfoList
=
new
ArrayList
<>();
@ApiOperation
(
"上传库位"
)
@PostMapping
(
value
=
"/upload"
)
@AnonymousAccess
public
List
<
BINPosDto
>
upload
(
@RequestParam
MultipartFile
orderFile
,
HttpServletRequest
request
)
{
String
image
=
"csv"
;
String
fileType
=
FileUtil
.
getExtensionName
(
orderFile
.
getOriginalFilename
());
String
fileName
=
FileUtil
.
getFileNameNoEx
(
orderFile
.
getOriginalFilename
());
if
(
fileType
!=
null
&&
!
image
.
contains
(
fileType
))
{
throw
new
ValidateException
(
"smfcore.feleFormatError"
,
"文件格式错误!, 仅支持{0}格式"
,
new
String
[]{
image
});
}
File
folder
=
new
File
(
properties
.
getPath
(),
"pos"
);
File
localFile
=
FileUtil
.
upload
(
orderFile
,
folder
.
getAbsolutePath
());
List
<
String
>
itemList
=
readFile
(
fileName
,
localFile
.
getAbsolutePath
());
String
posStr
=
""
;
if
(
itemList
==
null
||
itemList
.
size
()
<=
0
)
{
throw
new
ValidateException
(
"smfcore.fileError"
,
"文件解析失败"
);
}
else
{
//先把之前的灯关闭
for
(
BINPosInfo
pos
:
posInfoList
)
{
Storage
storage
=
dataCache
.
getStorageById
(
pos
.
getStorageId
());
DevicesStatusUtil
.
appendOp
(
storage
.
getCid
(),
"close"
,
pos
.
getPosName
()
+
"="
);
posStr
+=
"["
+
pos
.
getPosName
()+
"]"
;
}
posInfoList
=
new
ArrayList
<>();
}
if
(
ObjectUtil
.
isNotEmpty
(
posStr
)){
log
.
info
(
"上传文件时关闭上次的灯,关灯:"
+
posStr
);
}
String
token
=
tokenProvider
.
getToken
(
request
);
String
ptoken
=
token
.
substring
(
token
.
length
()
-
10
);
String
lightOnString
=
""
;
String
color
=
"green"
;
for
(
String
bin
:
itemList
)
{
String
posName
=
bin
;
StoragePos
pos
=
storagePosManager
.
getByPosName
(
posName
);
if
(
pos
==
null
)
{
//转换为Pos
posName
=
convertToPos
(
bin
);
pos
=
storagePosManager
.
getByPosName
(
posName
);
if
(
pos
==
null
)
{
continue
;
}
}
Storage
storage
=
dataCache
.
getStorageById
(
pos
.
getStorageId
());
if
(
storage
==
null
)
{
log
.
info
(
"上传库位出库文件时,库位["
+
pos
.
getId
()
+
"]["
+
pos
.
getPosName
()
+
"],storageId=["
+
pos
.
getStorageId
()
+
"]未找到料仓"
);
continue
;
}
BINPosInfo
posInfo
=
new
BINPosInfo
(
bin
,
pos
.
getId
(),
pos
.
getPosName
(),
pos
.
getStorageId
(),
storage
.
getName
());
posInfoList
.
add
(
posInfo
);
String
lightOnStr
=
pos
.
getPosName
()
+
"="
+
color
;
DevicesStatusUtil
.
appendOp
(
storage
.
getCid
(),
"open"
,
lightOnStr
);
lightOnString
+=
"["
+
lightOnStr
+
"]"
;
}
log
.
info
(
"["
+
ptoken
+
"]上传["
+
posInfoList
.
size
()
+
"]条出库库位信息,点亮库位:"
+
lightOnString
);
List
<
BINPosDto
>
results
=
binPosMapper
.
toDto
(
posInfoList
);
return
results
;
}
//
@ApiOperation("上传库位")
//
@PostMapping(value = "/upload")
//
@AnonymousAccess
//
public List<BINPosDto> upload(@RequestParam MultipartFile orderFile, HttpServletRequest request) {
//
//
String image = "csv";
//
String fileType = FileUtil.getExtensionName(orderFile.getOriginalFilename());
//
String fileName = FileUtil.getFileNameNoEx(orderFile.getOriginalFilename());
//
if (fileType != null && !image.contains(fileType)) {
//
throw new ValidateException("smfcore.feleFormatError", "文件格式错误!, 仅支持{0}格式", new String[]{image});
//
}
//
File folder = new File(properties.getPath(), "pos");
//
File localFile = FileUtil.upload(orderFile, folder.getAbsolutePath());
//
List<String> itemList = readFile(fileName, localFile.getAbsolutePath());
//
//
String posStr="";
//
if (itemList == null || itemList.size() <= 0) {
//
throw new ValidateException("smfcore.fileError", "文件解析失败");
//
} else {
//
//先把之前的灯关闭
//
for (BINPosInfo pos :
//
posInfoList) {
//
Storage storage = dataCache.getStorageById(pos.getStorageId());
//
DevicesStatusUtil.appendOp(storage.getCid(), "close", pos.getPosName() + "=");
//
posStr+="["+pos.getPosName()+"]";
//
}
//
posInfoList = new ArrayList<>();
//
}
//
if(ObjectUtil.isNotEmpty(posStr)){
//
log.info("上传文件时关闭上次的灯,关灯:" + posStr);
//
}
//
String token = tokenProvider.getToken(request);
//
String ptoken = token.substring(token.length() - 10);
//
//
String lightOnString="";
//
String color = "green";
//
for (String bin : itemList
//
) {
//
String posName = bin;
//
StoragePos pos = storagePosManager.getByPosName(posName);
//
if (pos == null) {
//
//转换为Pos
//
posName = convertToPos(bin);
//
pos = storagePosManager.getByPosName(posName);
//
if (pos == null) {
//
continue;
//
}
//
}
//
Storage storage = dataCache.getStorageById(pos.getStorageId());
//
if (storage == null) {
//
log.info("上传库位出库文件时,库位[" + pos.getId() + "][" + pos.getPosName() + "],storageId=[" + pos.getStorageId() + "]未找到料仓");
//
continue;
//
}
//
BINPosInfo posInfo = new BINPosInfo(bin, pos.getId(), pos.getPosName(), pos.getStorageId(), storage.getName());
//
posInfoList.add(posInfo);
//
//
String lightOnStr = pos.getPosName() + "=" + color;
//
DevicesStatusUtil.appendOp(storage.getCid(), "open", lightOnStr);
//
lightOnString+="["+lightOnStr+"]";
//
}
//
log.info("[" + ptoken + "]上传[" + posInfoList.size() + "]条出库库位信息,点亮库位:" + lightOnString);
//
List<BINPosDto> results = binPosMapper.toDto(posInfoList);
//
return results;
//
}
@ApiOperation
(
"全部灭灯"
)
@PostMapping
(
value
=
"/closeAllLed"
)
...
...
src/main/java/com/neotel/smfcore/core/haman/rest/dto/BINPosDto.java
查看文件 @
d89f1ab
package
com
.
neotel
.
smfcore
.
core
.
haman
.
rest
.
dto
;
import
com.neotel.smfcore.core.device.enums.OP
;
import
com.neotel.smfcore.core.haman.enums.BIN_STATUS
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
...
...
@@ -7,12 +9,52 @@ import java.io.Serializable;
@Data
public
class
BINPosDto
implements
Serializable
{
@ApiModelProperty
(
value
=
"BIN名称"
)
private
String
bIN
;
@ApiModelProperty
(
value
=
"TO号"
)
/**
* Transfer Order Number
*/
private
String
toNumber
;
@ApiModelProperty
(
value
=
"料架名称"
)
private
String
storageName
;
/**
* Materia
*/
@ApiModelProperty
(
value
=
"物料号"
)
private
String
material
;
@ApiModelProperty
(
value
=
"库位号"
)
private
String
posName
;
//Batch
@ApiModelProperty
(
value
=
"批次"
)
private
String
batch
;
/**
* 类型: 上架或下架
*/
@ApiModelProperty
(
value
=
"类型:1=上架,2=下架"
)
private
int
type
=
OP
.
PUT_IN
;
//库位信息
@ApiModelProperty
(
value
=
"BIN"
)
private
String
binPos
;
/**
* 料架架位信息
*/
@ApiModelProperty
(
value
=
"架位"
)
private
String
shelfPos
;
/**
* 料架编号信息
*/
@ApiModelProperty
(
value
=
"料架编号"
)
private
String
shelfCid
;
/**
* 状态:0=未完成, 1=正在执行, 2=已完成
*/
@ApiModelProperty
(
value
=
"状态:0=未完成, 1=正在执行, 2=已完成"
)
private
int
status
=
BIN_STATUS
.
NEW
;
/**
* 亮灯料架颜色
*/
@ApiModelProperty
(
value
=
"灯颜色"
)
private
String
lightColor
=
""
;
}
src/main/java/com/neotel/smfcore/core/haman/rest/mapstruct/BINPosMapper.java
查看文件 @
d89f1ab
...
...
@@ -3,9 +3,10 @@ package com.neotel.smfcore.core.haman.rest.mapstruct;
import
com.neotel.smfcore.common.base.BaseMapper
;
import
com.neotel.smfcore.core.haman.bean.BINPosInfo
;
import
com.neotel.smfcore.core.haman.rest.dto.BINPosDto
;
import
com.neotel.smfcore.core.haman.services.po.HamanBinPos
;
import
org.mapstruct.Mapper
;
import
org.mapstruct.ReportingPolicy
;
@Mapper
(
componentModel
=
"spring"
,
unmappedTargetPolicy
=
ReportingPolicy
.
IGNORE
)
public
interface
BINPosMapper
extends
BaseMapper
<
BINPosDto
,
BINPosInfo
>
{
public
interface
BINPosMapper
extends
BaseMapper
<
BINPosDto
,
HamanBinPos
>
{
}
src/main/java/com/neotel/smfcore/core/haman/rest/query/HamanBinQueryCondition.java
0 → 100644
查看文件 @
d89f1ab
package
com
.
neotel
.
smfcore
.
core
.
haman
.
rest
.
query
;
import
com.neotel.smfcore.common.annotation.QueryCondition
;
import
com.neotel.smfcore.common.bean.BetweenData
;
import
com.neotel.smfcore.core.device.enums.OP
;
import
lombok.Data
;
import
java.util.Date
;
@Data
public
class
HamanBinQueryCondition
{
@QueryCondition
private
String
toNumber
;
@QueryCondition
private
String
material
;
@QueryCondition
private
String
batch
;
@QueryCondition
private
String
binPos
;
//类型:1=上架,2=下架
@QueryCondition
private
Integer
type
;
//状态:0=未完成, 1=正在执行, 2=已完成
@QueryCondition
private
Integer
status
;
}
src/main/java/com/neotel/smfcore/core/haman/services/dao/IHamanBinPosDao.java
0 → 100644
查看文件 @
d89f1ab
package
com
.
neotel
.
smfcore
.
core
.
haman
.
services
.
dao
;
import
com.neotel.smfcore.common.base.IBaseDao
;
import
com.neotel.smfcore.common.bean.PageData
;
import
com.neotel.smfcore.core.haman.services.po.HamanBinPos
;
import
com.neotel.smfcore.core.inList.service.po.InList
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.mongodb.core.query.Query
;
import
java.util.List
;
public
interface
IHamanBinPosDao
extends
IBaseDao
{
HamanBinPos
getPutInBin
(
String
material
,
String
batch
);
HamanBinPos
getExecutingBin
(
String
shelfPos
);
List
<
HamanBinPos
>
listUnLoadExecutingTasks
();
List
<
HamanBinPos
>
listByToNumber
(
String
toNumber
);
List
<
String
>
distinctColor
();
PageData
<
HamanBinPos
>
findByPage
(
Query
query
,
Pageable
pageable
);
}
src/main/java/com/neotel/smfcore/core/haman/services/dao/impl/HamanBinPosDaoImpl.java
0 → 100644
查看文件 @
d89f1ab
package
com
.
neotel
.
smfcore
.
core
.
haman
.
services
.
dao
.
impl
;
import
com.neotel.smfcore.common.base.AbstractBaseDao
;
import
com.neotel.smfcore.common.bean.PageData
;
import
com.neotel.smfcore.core.device.enums.OP
;
import
com.neotel.smfcore.core.haman.enums.BIN_STATUS
;
import
com.neotel.smfcore.core.haman.services.dao.IHamanBinPosDao
;
import
com.neotel.smfcore.core.haman.services.po.HamanBinPos
;
import
com.neotel.smfcore.core.inList.service.po.InList
;
import
com.neotel.smfcore.core.order.service.po.LiteOrder
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.mongodb.core.query.Criteria
;
import
org.springframework.data.mongodb.core.query.Query
;
import
org.springframework.stereotype.Service
;
import
java.util.List
;
@Service
public
class
HamanBinPosDaoImpl
extends
AbstractBaseDao
implements
IHamanBinPosDao
{
@Override
public
Class
getEntityClass
()
{
return
HamanBinPos
.
class
;
}
@Override
public
HamanBinPos
getPutInBin
(
String
material
,
String
batch
)
{
Criteria
c
=
Criteria
.
where
(
"material"
).
is
(
material
)
.
and
(
"batch"
).
is
(
batch
)
.
and
(
"type"
).
is
(
OP
.
PUT_IN
)
.
and
(
"status"
).
is
(
BIN_STATUS
.
NEW
);
return
findOne
(
new
Query
(
c
));
}
@Override
public
HamanBinPos
getExecutingBin
(
String
shelfPos
)
{
Criteria
c
=
Criteria
.
where
(
"shelfPos"
).
is
(
shelfPos
)
.
and
(
"status"
).
is
(
BIN_STATUS
.
EXCUTING
);
HamanBinPos
binPos
=
findOne
(
new
Query
(
c
));
if
(
binPos
==
null
){
//库位的条码有可能是前面带了SOxxx-,所以这里去除SO-再查一遍库位,保持与之前的兼容
int
index
=
shelfPos
.
indexOf
(
"-"
);
if
(
index
>=
0
){
String
posNameStr
=
shelfPos
.
substring
(
index
+
1
);
c
=
Criteria
.
where
(
"shelfPos"
).
is
(
posNameStr
)
.
and
(
"status"
).
is
(
BIN_STATUS
.
EXCUTING
);
binPos
=
findOne
(
new
Query
(
c
));
}
}
return
binPos
;
}
@Override
public
List
<
HamanBinPos
>
listUnLoadExecutingTasks
(){
Criteria
c
=
Criteria
.
where
(
"status"
).
is
(
BIN_STATUS
.
EXCUTING
)
.
and
(
"type"
).
is
(
OP
.
CHECKOUT
);;
List
<
HamanBinPos
>
list
=
findByQuery
(
new
Query
(
c
));
return
list
;
}
@Override
public
List
<
HamanBinPos
>
listByToNumber
(
String
toNumber
){
Criteria
c
=
Criteria
.
where
(
"toNumber"
).
is
(
toNumber
);
List
<
HamanBinPos
>
list
=
findByQuery
(
new
Query
(
c
));
return
list
;
}
@Override
public
PageData
<
HamanBinPos
>
findByPage
(
Query
query
,
Pageable
pageable
){
int
totalCount
=
countByQuery
(
query
);
List
<
HamanBinPos
>
list
=
findByQuery
(
query
,
pageable
);
return
new
PageData
<
HamanBinPos
>(
list
,
totalCount
);
}
@Override
public
List
<
String
>
distinctColor
(){
Criteria
c
=
Criteria
.
where
(
"status"
).
is
(
BIN_STATUS
.
EXCUTING
)
.
and
(
"type"
).
is
(
OP
.
CHECKOUT
);
return
distinct
(
"lightColor"
,
new
Query
(
c
));
}
}
src/main/java/com/neotel/smfcore/core/haman/services/po/HamanBinPos.java
0 → 100644
查看文件 @
d89f1ab
package
com
.
neotel
.
smfcore
.
core
.
haman
.
services
.
po
;
import
com.google.common.collect.Lists
;
import
com.neotel.smfcore.common.base.BasePo
;
import
com.neotel.smfcore.common.utils.DateUtil
;
import
com.neotel.smfcore.core.barcode.enums.BARCODE_STATUS
;
import
com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE
;
import
com.neotel.smfcore.core.barcode.enums.SOLDER_STATUS
;
import
com.neotel.smfcore.core.device.enums.OP
;
import
com.neotel.smfcore.core.haman.enums.BIN_STATUS
;
import
lombok.Data
;
import
org.springframework.data.annotation.Transient
;
import
org.springframework.data.mongodb.core.mapping.Document
;
import
java.io.Serializable
;
import
java.util.Date
;
import
java.util.List
;
@Data
@Document
public
class
HamanBinPos
extends
BasePo
implements
Serializable
{
/**
* Transfer Order Number
*/
private
String
toNumber
;
/**
* Materia
*/
private
String
material
;
//Batch
private
String
batch
;
/**
* 类型: 上架或下架
*/
private
int
type
=
OP
.
PUT_IN
;
//库位信息
private
String
binPos
;
/**
* 料架架位信息
*/
private
String
shelfPos
;
/**
* 料架编号信息
*/
private
String
shelfCid
;
/**
* 状态:0=未完成, 1=正在执行, 2=已完成
*/
private
int
status
=
BIN_STATUS
.
NEW
;
/**
* 亮灯料架颜色
*/
private
String
lightColor
=
""
;
}
src/main/java/com/neotel/smfcore/core/order/enums/ORDER_COLOR.java
查看文件 @
d89f1ab
...
...
@@ -78,7 +78,7 @@ public enum ORDER_COLOR {
int
nextColorIndex
=
(
currentColorIndex
+
1
)
%
allColors
.
length
;
for
(
ORDER_COLOR
color
:
allColors
)
{
if
(!
excludeColors
.
contains
(
color
.
getRgb
())
&&
color
.
ordinal
()
>=
nextColorIndex
){
if
(!
excludeColors
.
contains
(
color
.
getRgb
())
&&
!
excludeColors
.
contains
(
color
.
name
())
&&
color
.
ordinal
()
>=
nextColorIndex
){
currentColorIndex
=
color
.
ordinal
();
return
color
;
}
...
...
src/main/java/com/neotel/smfcore/core/order/listener/DefaultOrderFileListener.java
0 → 100644
查看文件 @
d89f1ab
package
com
.
neotel
.
smfcore
.
core
.
order
.
listener
;
import
cn.hutool.core.util.ObjectUtil
;
import
com.google.common.collect.Lists
;
import
com.neotel.smfcore.common.csv.CsvReader
;
import
com.neotel.smfcore.core.device.util.DataCache
;
import
com.neotel.smfcore.core.order.LiteOrderCache
;
import
com.neotel.smfcore.core.order.service.manager.ILiteOrderManager
;
import
com.neotel.smfcore.core.order.service.po.LiteOrder
;
import
com.neotel.smfcore.core.order.service.po.LiteOrderItem
;
import
com.neotel.smfcore.core.system.bean.OrderSetting
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.logging.log4j.util.Strings
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.io.File
;
import
java.text.SimpleDateFormat
;
import
java.util.*
;
/**
* Created by sunke on 2021/7/12.
*/
@Service
@Slf4j
public
class
DefaultOrderFileListener
implements
IOrderFileListener
{
@Autowired
protected
DataCache
dataCache
;
@Autowired
protected
ILiteOrderManager
liteOrderManager
;
@Autowired
protected
LiteOrderCache
liteOrderCache
;
@Override
public
boolean
handleOrderFile
(
File
orderFile
)
{
String
fileName
=
orderFile
.
getName
();
//String backupFileName = fileName +"_" + System.currentTimeMillis();
//看数据库是否已有此工单
// if(!fileName.endsWith(".process") && fileName.endsWith("_result.txt")){
//
// }
if
(
isFileType
(
fileName
,
"csv"
)){
LiteOrder
fileNameOrder
=
liteOrderManager
.
findBySource
(
fileName
);
if
(
fileNameOrder
==
null
){
try
{
Map
<
String
,
List
<
LiteOrderItem
>>
itemMap
=
readCsvFile
(
fileName
,
orderFile
.
getAbsolutePath
());
if
(
itemMap
!=
null
&&
itemMap
.
size
()
>
0
)
{
for
(
String
so:
itemMap
.
keySet
())
{
List
<
LiteOrderItem
>
liteOrderItems
=
itemMap
.
get
(
so
);
if
(
liteOrderItems
.
size
()
<=
0
)
{
continue
;
}
LiteOrder
liteOrder
=
new
LiteOrder
(
so
,
liteOrderItems
);
liteOrder
.
setSource
(
fileName
);
LiteOrder
dbOrder
=
liteOrderManager
.
findByOrderNo
(
liteOrder
.
getOrderNo
());
if
(
dbOrder
!=
null
)
{
SimpleDateFormat
format
=
new
SimpleDateFormat
(
"yyyyMMddHHmmss"
);
//把名字改为带时间的
String
newOrderNo
=
liteOrder
.
getOrderNo
()
+
"-"
+
format
.
format
(
new
Date
());
dbOrder
=
liteOrderManager
.
findByOrderNo
(
newOrderNo
);
if
(
dbOrder
==
null
)
{
liteOrder
.
setOrderNo
(
newOrderNo
);
}
else
{
log
.
info
(
"watchOrderDir:数据库中已存在工单号为["
+
liteOrder
.
getOrderNo
()
+
"],忽略文件:"
+
orderFile
.
getAbsolutePath
());
//resultFile = new File(localDir+File.separator + "error",backupFileName);
return
false
;
}
}
log
.
info
(
"watchOrderDir:新增加订单:"
+
liteOrder
.
getOrderNo
()
+
",共"
+
liteOrderItems
.
size
()
+
"条工单详情"
);
liteOrder
=
liteOrderManager
.
createWithItems
(
liteOrder
);
liteOrderCache
.
addOrderToMap
(
liteOrder
);
//resultFile = new File(localDir+File.separator + "sucess",backupFileName);
return
true
;
}
}
}
catch
(
Exception
e
){
log
.
error
(
"read order from file ["
+
orderFile
.
getAbsolutePath
()+
"] :"
,
e
);
//resultFile = new File(localDir+File.separator + "error",backupFileName);
}
}
//resultFile = new File(localDir+File.separator + "sucess",backupFileName);
}
return
false
;
}
public
Map
<
String
,
List
<
LiteOrderItem
>>
readCsvFile
(
String
fileName
,
String
fileURL
)
{
CsvReader
csvRead
=
null
;
try
{
fileName
=
fileName
.
replace
(
".csv"
,
""
);
Map
<
String
,
List
<
LiteOrderItem
>>
itemMap
=
new
HashMap
<>();
List
<
LiteOrderItem
>
items
=
Lists
.
newArrayList
();
OrderSetting
orderSetting
=
dataCache
.
getOrderSetting
();
csvRead
=
CsvReader
.
newReader
(
fileURL
,
"PN"
,
orderSetting
.
getPn
());
int
partNumberIndex
=
csvRead
.
getIndex
(
"PN"
,
orderSetting
.
getPn
());
int
qtyIndex
=
csvRead
.
getIndex
(
"QTY"
,
orderSetting
.
getQty
());
int
feederIndex
=
csvRead
.
getIndex
(
"FEEDER"
,
orderSetting
.
getFeeder
());
int
riIndex
=
csvRead
.
getIndex
(
"RI"
,
orderSetting
.
getRi
());
int
soIndex
=
csvRead
.
getIndex
(
"SO"
,
orderSetting
.
getSo
());
int
row
=
1
;
int
newRowCount
=
0
;
int
updateRowCount
=
0
;
while
(
csvRead
.
readRecord
())
{
row
++;
String
[]
lineValues
=
csvRead
.
getValues
();
String
partNumber
=
lineValues
[
partNumberIndex
];
String
ri
=
""
;
if
(
riIndex
!=-
1
){
ri
=
lineValues
[
riIndex
];
}
if
(
partNumber
.
isEmpty
()&&
ri
.
isEmpty
())
{
log
.
warn
(
"行[partNumber="
+
partNumber
+
"]中PN和RI都 为空,此行忽略"
);
}
else
{
int
num
=
1
;
if
(
qtyIndex
!=
-
1
)
{
String
numStr
=
lineValues
[
qtyIndex
];
if
(
Strings
.
isNotBlank
(
numStr
))
{
try
{
num
=
Integer
.
valueOf
(
numStr
);
}
catch
(
Exception
e
)
{
log
.
error
(
partNumber
+
"的数量:"
+
numStr
+
" 不是数字,使用1"
);
}
}
}
String
feeder
=
""
;
if
(
feederIndex
!=
-
1
)
{
feeder
=
lineValues
[
feederIndex
];
}
String
so
=
fileName
;
if
(
soIndex
!=-
1
){
so
=
lineValues
[
soIndex
];
}
if
(!
ObjectUtil
.
isNotEmpty
(
so
)){
so
=
fileName
;
}
LiteOrderItem
item
=
new
LiteOrderItem
();
item
.
setPn
(
partNumber
);
if
(
partNumber
.
isEmpty
()){
item
.
setNeedReelCount
(
1
);
}
item
.
setNeedNum
(
num
);
item
.
setFeederInfo
(
feeder
);
item
.
setRi
(
ri
);
if
(!
itemMap
.
containsKey
(
so
)){
itemMap
.
put
(
so
,
new
ArrayList
<
LiteOrderItem
>());
}
itemMap
.
get
(
so
).
add
(
item
);
items
.
add
(
item
);
}
}
return
itemMap
;
}
catch
(
Exception
ex
)
{
log
.
error
(
"解析上传的工单出错:"
+
ex
.
toString
());
}
finally
{
if
(
csvRead
!=
null
){
csvRead
.
close
();
}
}
return
null
;
}
protected
boolean
isFileType
(
String
smbFile
,
String
type
){
//判断是否是有效的工单文件
if
(
smbFile
.
toLowerCase
().
endsWith
(
type
)){
return
true
;
}
return
false
;
}
}
src/main/java/com/neotel/smfcore/core/order/listener/IOrderFileListener.java
0 → 100644
查看文件 @
d89f1ab
package
com
.
neotel
.
smfcore
.
core
.
order
.
listener
;
import
java.io.File
;
/**
* Created by sunke on 2021/7/12.
*/
public
interface
IOrderFileListener
{
boolean
handleOrderFile
(
File
orderFile
);
}
src/main/java/com/neotel/smfcore/core/order/rest/OrderController.java
查看文件 @
d89f1ab
...
...
@@ -121,39 +121,40 @@ public class OrderController {
}
File
folder
=
new
File
(
properties
.
getPath
(),
"pos"
);
File
localFile
=
FileUtil
.
upload
(
orderFile
,
folder
.
getAbsolutePath
());
Map
<
String
,
List
<
LiteOrderItem
>>
itemMap
=
orderFileWatch
.
readCsvFile
(
fileName
,
localFile
.
getAbsolutePath
());
if
(
itemMap
==
null
||
itemMap
.
size
()
<=
0
)
{
throw
new
ValidateException
(
"smfcore.fileError"
,
"文件解析失败"
);
}
for
(
String
so
:
itemMap
.
keySet
()
)
{
List
<
LiteOrderItem
>
liteOrderItems
=
itemMap
.
get
(
so
);
if
(
liteOrderItems
.
size
()
<=
0
)
{
continue
;
}
LiteOrder
liteOrder
=
new
LiteOrder
(
so
,
liteOrderItems
);
liteOrder
.
setSource
(
localFile
.
getName
());
LiteOrder
dbOrder
=
liteOrderManager
.
findByOrderNo
(
liteOrder
.
getOrderNo
());
if
(
dbOrder
!=
null
)
{
SimpleDateFormat
format
=
new
SimpleDateFormat
(
"yyyyMMddHHmmss"
);
//把名字改为带时间的
String
newOrderNo
=
liteOrder
.
getOrderNo
()
+
"-"
+
format
.
format
(
new
Date
());
dbOrder
=
liteOrderManager
.
findByOrderNo
(
newOrderNo
);
if
(
dbOrder
==
null
)
{
liteOrder
.
setOrderNo
(
newOrderNo
);
}
else
{
log
.
info
(
"数据库中已存在工单号为["
+
liteOrder
.
getOrderNo
()
+
"],忽略文件:"
+
localFile
.
getAbsolutePath
());
return
ResultBean
.
newErrorResult
(-
1
,
"smfcore.order.ameExists"
,
"工单名称[{0}]已存在"
,
new
String
[]{
liteOrder
.
getOrderNo
()});
}
}
log
.
info
(
"新增加订单:"
+
liteOrder
.
getOrderNo
()
+
",共"
+
liteOrderItems
.
size
()
+
"条工单详情"
);
liteOrder
=
liteOrderManager
.
createWithItems
(
liteOrder
);
liteOrderCache
.
addOrderToMap
(
liteOrder
);
}
orderFileWatch
.
handleOrderFile
(
localFile
);
// Map<String, List<LiteOrderItem>> itemMap = orderFileWatch.readCsvFile(fileName, localFile.getAbsolutePath());
//
// if (itemMap == null || itemMap.size() <= 0) {
// throw new ValidateException("smfcore.fileError", "文件解析失败");
// }
//
// for (String so : itemMap.keySet()
// ) {
//
// List<LiteOrderItem> liteOrderItems = itemMap.get(so);
// if (liteOrderItems.size() <= 0) {
// continue;
// }
// LiteOrder liteOrder = new LiteOrder(so, liteOrderItems);
// liteOrder.setSource(localFile.getName());
// LiteOrder dbOrder = liteOrderManager.findByOrderNo(liteOrder.getOrderNo());
// if (dbOrder != null) {
//
// SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
// //把名字改为带时间的
// String newOrderNo = liteOrder.getOrderNo() + "-" + format.format(new Date());
// dbOrder = liteOrderManager.findByOrderNo(newOrderNo);
// if (dbOrder == null) {
// liteOrder.setOrderNo(newOrderNo);
// } else {
// log.info("数据库中已存在工单号为[" + liteOrder.getOrderNo() + "],忽略文件:" + localFile.getAbsolutePath());
// return ResultBean.newErrorResult(-1, "smfcore.order.ameExists", "工单名称[{0}]已存在", new String[]{liteOrder.getOrderNo()});
// }
// }
// log.info("新增加订单:" + liteOrder.getOrderNo() + ",共" + liteOrderItems.size() + "条工单详情");
// liteOrder = liteOrderManager.createWithItems(liteOrder);
// liteOrderCache.addOrderToMap(liteOrder);
// }
return
ResultBean
.
newOkResult
(
"smfcore.order.uploadOK"
,
"工单上传成功"
,
""
);
}
...
...
src/main/java/com/neotel/smfcore/core/order/util/OrderFileWatch.java
查看文件 @
d89f1ab
...
...
@@ -6,16 +6,21 @@ import com.neotel.smfcore.common.csv.CsvReader;
import
com.neotel.smfcore.common.utils.SmbUtil
;
import
com.neotel.smfcore.core.device.util.DataCache
;
import
com.neotel.smfcore.core.order.LiteOrderCache
;
import
com.neotel.smfcore.core.order.listener.IOrderFileListener
;
import
com.neotel.smfcore.core.order.service.manager.ILiteOrderManager
;
import
com.neotel.smfcore.core.order.service.po.LiteOrder
;
import
com.neotel.smfcore.core.order.service.po.LiteOrderItem
;
import
com.neotel.smfcore.core.system.bean.OrderSetting
;
import
com.neotel.smfcore.core.system.listener.ITaskListener
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.logging.log4j.util.Strings
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
javax.activation.MimeType
;
import
java.io.File
;
import
java.io.FileFilter
;
import
java.nio.file.Files
;
import
java.text.SimpleDateFormat
;
import
java.util.*
;
import
java.util.concurrent.Executors
;
...
...
@@ -33,10 +38,7 @@ public class OrderFileWatch {
private
DataCache
dataCache
;
@Autowired
private
ILiteOrderManager
liteOrderManager
;
@Autowired
private
LiteOrderCache
liteOrderCache
;
private
List
<
IOrderFileListener
>
orderFileListenerList
=
new
ArrayList
<>();
ScheduledExecutorService
scheduledThreadPool
=
Executors
.
newScheduledThreadPool
(
1
);
...
...
@@ -59,7 +61,8 @@ public class OrderFileWatch {
private
synchronized
void
watchOrderDir
(){
try
{
String
dir
=
dataCache
.
getOrderSetting
().
getOrderDir
()
;
String
dir
=
dataCache
.
getOrderSetting
().
getOrderDir
();
//dir = "/Volumes/HDD/orderTest";
if
(
Strings
.
isNotBlank
(
dir
)){
dir
=
dir
.
replaceAll
(
"\\\\"
,
"/"
);
}
else
{
...
...
@@ -71,74 +74,33 @@ public class OrderFileWatch {
if
(
Strings
.
isNotBlank
(
localDir
)){
File
orderFolder
=
new
File
(
localDir
);
if
(
orderFolder
.
exists
()
&&
orderFolder
.
isDirectory
()){
for
(
File
file
:
orderFolder
.
listFiles
())
{
if
(
file
.
isDirectory
()){
continue
;
}
File
resultFile
=
null
;
String
fileName
=
file
.
getName
();
String
backupFileName
=
fileName
+
"_"
+
System
.
currentTimeMillis
();
//看数据库是否已有此工单
if
(
fileName
.
endsWith
(
".process"
)
||
fileName
.
endsWith
(
"_result.txt"
)){
continue
;
}
if
(
isOrderFileType
(
fileName
)){
LiteOrder
fileNameOrder
=
liteOrderManager
.
findBySource
(
fileName
);
if
(
fileNameOrder
==
null
){
log
.
info
(
"watchOrderDir:监控到新的Order文件,准备处理:"
+
file
.
getAbsolutePath
());
try
{
Map
<
String
,
List
<
LiteOrderItem
>>
itemMap
=
readCsvFile
(
fileName
,
file
.
getAbsolutePath
());
if
(
itemMap
==
null
||
itemMap
.
size
()
<=
0
)
{
log
.
error
(
"watchOrderDir: 文件["
+
fileName
+
"]解析失败"
);
continue
;
}
for
(
String
so:
itemMap
.
keySet
()
)
{
List
<
LiteOrderItem
>
liteOrderItems
=
itemMap
.
get
(
so
);
if
(
liteOrderItems
.
size
()
<=
0
)
{
continue
;
}
LiteOrder
liteOrder
=
new
LiteOrder
(
so
,
liteOrderItems
);
liteOrder
.
setSource
(
fileName
);
LiteOrder
dbOrder
=
liteOrderManager
.
findByOrderNo
(
liteOrder
.
getOrderNo
());
if
(
dbOrder
!=
null
)
{
SimpleDateFormat
format
=
new
SimpleDateFormat
(
"yyyyMMddHHmmss"
);
//把名字改为带时间的
String
newOrderNo
=
liteOrder
.
getOrderNo
()
+
"-"
+
format
.
format
(
new
Date
());
dbOrder
=
liteOrderManager
.
findByOrderNo
(
newOrderNo
);
if
(
dbOrder
==
null
)
{
liteOrder
.
setOrderNo
(
newOrderNo
);
}
else
{
log
.
info
(
"watchOrderDir:数据库中已存在工单号为["
+
liteOrder
.
getOrderNo
()
+
"],忽略文件:"
+
file
.
getAbsolutePath
());
resultFile
=
new
File
(
localDir
+
File
.
separator
+
"error"
,
backupFileName
);
continue
;
}
}
log
.
info
(
"watchOrderDir:新增加订单:"
+
liteOrder
.
getOrderNo
()
+
",共"
+
liteOrderItems
.
size
()
+
"条工单详情"
);
liteOrder
=
liteOrderManager
.
createWithItems
(
liteOrder
);
liteOrderCache
.
addOrderToMap
(
liteOrder
);
resultFile
=
new
File
(
localDir
+
File
.
separator
+
"sucess"
,
backupFileName
);
}
}
catch
(
Exception
e
){
log
.
error
(
"read order from file ["
+
file
.
getAbsolutePath
()+
"] :"
,
e
);
resultFile
=
new
File
(
localDir
+
File
.
separator
+
"error"
,
backupFileName
);
}
FileFilter
fileFilter
=
new
FileFilter
()
{
@Override
public
boolean
accept
(
File
pathname
)
{
if
(
pathname
.
isDirectory
()){
return
false
;
}
resultFile
=
new
File
(
localDir
+
File
.
separator
+
"sucess"
,
backupFileName
);
String
fileNameStr
=
pathname
.
getName
().
toLowerCase
();
//只处理csv,xml和txt文件
if
(
fileNameStr
.
endsWith
(
"csv"
)
||
fileNameStr
.
endsWith
(
"xml"
)
||
fileNameStr
.
endsWith
(
"txt"
)){
return
true
;
}
return
false
;
}
};
for
(
File
file
:
orderFolder
.
listFiles
(
fileFilter
))
{
boolean
handled
=
handleOrderFile
(
file
);
if
(
resultFile
!=
null
){
resultFile
.
getParentFile
().
mkdirs
();
file
.
renameTo
(
resultFile
);
String
backupFileName
=
file
.
getName
()
+
"_"
+
System
.
currentTimeMillis
();
File
resultFile
=
null
;
if
(
handled
){
resultFile
=
new
File
(
localDir
+
File
.
separator
+
"sucess"
,
backupFileName
);
}
else
{
resultFile
=
new
File
(
localDir
+
File
.
separator
+
"error"
,
backupFileName
);
}
log
.
info
(
"处理完成,移动文件到:"
+
resultFile
.
getAbsolutePath
());
resultFile
.
getParentFile
().
mkdirs
();
file
.
renameTo
(
resultFile
);
}
}
...
...
@@ -148,17 +110,27 @@ public class OrderFileWatch {
}
}
private
boolean
isOrderFileType
(
String
smbFile
){
//判断是否是有效的工单文件
if
(
smbFile
.
toLowerCase
().
endsWith
(
"csv"
)){
return
true
;
/**
* 解析工单文件
* @param orderFile
* @return
*/
public
boolean
handleOrderFile
(
File
orderFile
){
log
.
info
(
"开始处理Order文件:"
+
orderFile
.
getAbsolutePath
());
for
(
IOrderFileListener
orderFileListener
:
orderFileListenerList
)
{
boolean
result
=
orderFileListener
.
handleOrderFile
(
orderFile
);
if
(
result
){
return
true
;
}
}
return
false
;
}
private
String
getLocalDir
(
String
orderDir
){
String
[]
fileTypes
=
new
String
[]{
"csv"
,
"xml
"
};
//String[] fileTypes=new String[]{"csv","xml","txt
"};
String
localDir
=
orderDir
;
if
(
Strings
.
isNotBlank
(
orderDir
))
{
orderDir
=
orderDir
.
replaceAll
(
"\\\\"
,
"/"
);
...
...
@@ -173,18 +145,18 @@ public class OrderFileWatch {
if
(
smbFiles
!=
null
){
for
(
String
smbFile
:
smbFiles
)
{
if
(
isOrderFileType
(
smbFile
)){
//
if(isOrderFileType(smbFile)){
File
localFile
=
new
File
(
localDirFile
,
smbFile
);
if
(!
localFile
.
exists
()){
SmbUtil
.
smbGet
(
orderDir
+
smbFile
,
localDir
);
}
}
//
}
}
//再删除远程不存在的
String
[]
localFiles
=
localDirFile
.
list
();
if
(
localFiles
!=
null
){
for
(
String
fileName
:
localFiles
){
if
(
isOrderFileType
(
fileName
)){
//
if(isOrderFileType(fileName)){
if
(!
smbFiles
.
contains
(
fileName
)){
//同时删除本地的result 文件
log
.
info
(
"远程文件["
+
fileName
+
"]已经清除,删除本地文件和result 文件"
);
...
...
@@ -198,7 +170,7 @@ public class OrderFileWatch {
File
file
=
new
File
(
localDir
,
fileName
);
file
.
delete
();
}
}
//
}
}
}
...
...
@@ -206,88 +178,5 @@ public class OrderFileWatch {
}
}
return
localDir
;
}
public
Map
<
String
,
List
<
LiteOrderItem
>>
readCsvFile
(
String
fileName
,
String
fileURL
)
{
try
{
fileName
=
fileName
.
replace
(
".csv"
,
""
);
log
.
info
(
"开始更解析上传的工单"
);
Map
<
String
,
List
<
LiteOrderItem
>>
itemMap
=
new
HashMap
<>();
List
<
LiteOrderItem
>
items
=
Lists
.
newArrayList
();
OrderSetting
orderSetting
=
dataCache
.
getOrderSetting
();
CsvReader
csvRead
=
CsvReader
.
newReader
(
fileURL
,
"PN"
,
orderSetting
.
getPn
());
int
partNumberIndex
=
csvRead
.
getIndex
(
"PN"
,
orderSetting
.
getPn
());
int
qtyIndex
=
csvRead
.
getIndex
(
"QTY"
,
orderSetting
.
getQty
());
int
feederIndex
=
csvRead
.
getIndex
(
"FEEDER"
,
orderSetting
.
getFeeder
());
int
riIndex
=
csvRead
.
getIndex
(
"RI"
,
orderSetting
.
getRi
());
int
soIndex
=
csvRead
.
getIndex
(
"SO"
,
orderSetting
.
getSo
());
int
row
=
1
;
int
newRowCount
=
0
;
int
updateRowCount
=
0
;
while
(
csvRead
.
readRecord
())
{
row
++;
String
[]
lineValues
=
csvRead
.
getValues
();
String
partNumber
=
lineValues
[
partNumberIndex
];
String
ri
=
""
;
if
(
riIndex
!=-
1
){
ri
=
lineValues
[
riIndex
];
}
if
(
partNumber
.
isEmpty
()&&
ri
.
isEmpty
())
{
log
.
warn
(
"行[partNumber="
+
partNumber
+
"]中PN和RI都 为空,此行忽略"
);
}
else
{
int
num
=
1
;
if
(
qtyIndex
!=
-
1
)
{
String
numStr
=
lineValues
[
qtyIndex
];
if
(
Strings
.
isNotBlank
(
numStr
))
{
try
{
num
=
Integer
.
valueOf
(
numStr
);
}
catch
(
Exception
e
)
{
log
.
error
(
partNumber
+
"的数量:"
+
numStr
+
" 不是数字,使用1"
);
}
}
}
String
feeder
=
""
;
if
(
feederIndex
!=
-
1
)
{
feeder
=
lineValues
[
feederIndex
];
}
String
so
=
fileName
;
if
(
soIndex
!=-
1
){
so
=
lineValues
[
soIndex
];
}
if
(!
ObjectUtil
.
isNotEmpty
(
so
)){
so
=
fileName
;
}
LiteOrderItem
item
=
new
LiteOrderItem
();
item
.
setPn
(
partNumber
);
if
(
partNumber
.
isEmpty
()){
item
.
setNeedReelCount
(
1
);
}
item
.
setNeedNum
(
num
);
item
.
setFeederInfo
(
feeder
);
item
.
setRi
(
ri
);
if
(!
itemMap
.
containsKey
(
so
)){
itemMap
.
put
(
so
,
new
ArrayList
<
LiteOrderItem
>());
}
itemMap
.
get
(
so
).
add
(
item
);
items
.
add
(
item
);
}
}
return
itemMap
;
}
catch
(
Exception
ex
)
{
log
.
error
(
"解析上传的工单出错:"
+
ex
.
toString
());
}
return
null
;
}
}
src/main/java/com/neotel/smfcore/core/storage/service/manager/impl/StoragePosManagerImpl.java
查看文件 @
d89f1ab
...
...
@@ -172,7 +172,16 @@ public class StoragePosManagerImpl implements IStoragePosManager {
@Override
public
StoragePos
getByPosName
(
String
posName
)
{
return
storagePosDao
.
findOneByCondition
(
new
String
[]{
"posName"
},
new
String
[]{
posName
});
StoragePos
pos
=
storagePosDao
.
findOneByCondition
(
new
String
[]{
"posName"
},
new
String
[]{
posName
});
if
(
pos
==
null
){
//库位的条码有可能是前面带了SOxxx-,所以这里去除SO-再查一遍库位,保持与之前的兼容
int
index
=
posName
.
indexOf
(
"-"
);
if
(
index
>=
0
){
String
posNameStr
=
posName
.
substring
(
index
+
1
);
pos
=
storagePosDao
.
findOneByCondition
(
new
String
[]{
"posName"
},
new
String
[]{
posNameStr
});
}
}
return
pos
;
}
@Override
...
...
src/main/java/com/neotel/smfcore/security/config/SpringSecurityConfig.java
查看文件 @
d89f1ab
...
...
@@ -119,6 +119,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
.
antMatchers
(
"/file/**"
).
permitAll
()
// 阿里巴巴 druid
.
antMatchers
(
"/druid/**"
).
permitAll
()
.
antMatchers
(
"/api/**"
).
permitAll
()
// 放行OPTIONS请求
.
antMatchers
(
HttpMethod
.
OPTIONS
,
"/**"
).
permitAll
()
// .antMatchers("api/menus/build").permitAll()
...
...
src/main/java/com/neotel/smfcore/security/config/SwaggerConfig.java
查看文件 @
d89f1ab
...
...
@@ -70,7 +70,8 @@ public class SwaggerConfig {
.
build
()
//添加登陆认证
.
securitySchemes
(
securitySchemes
())
.
securityContexts
(
securityContexts
());
.
securityContexts
(
securityContexts
())
;
}
private
ApiInfo
apiInfo
()
{
...
...
@@ -92,6 +93,17 @@ public class SwaggerConfig {
.
groupName
(
"设备通信"
)
.
pathMapping
(
"/"
);
}
@Bean
public
Docket
haman
()
{
return
new
Docket
(
DocumentationType
.
SWAGGER_2
)
.
apiInfo
(
apiInfo
())
.
select
()
.
apis
(
RequestHandlerSelectors
.
any
())
.
paths
(
PathSelectors
.
ant
(
"/api/haman/**"
))
.
build
()
.
groupName
(
"哈曼接口"
)
.
pathMapping
(
"/"
);
}
private
List
<
SecurityScheme
>
securitySchemes
()
{
//设置请求头信息
...
...
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论