Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
M
mini-wms
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Members
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
周海峰
mini-wms
Commits
19bd4ddb
Commit
19bd4ddb
authored
Dec 12, 2025
by
yubin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
导入
parent
bdfed8f5
隐藏空白字符变更
内嵌
并排
正在显示
35 个修改的文件
包含
2001 行增加
和
1052 行删除
+2001
-1052
ruoyi-admin-vue/src/components/materialsSeletor.vue
+161
-84
ruoyi-admin-vue/src/views/inventory/locations/index.vue
+216
-8
ruoyi-admin-vue/src/views/inventory/orders/OutboundOrderFormWithItems.vue
+194
-143
ruoyi-admin-vue/src/views/inventory/orders/index.vue
+126
-51
ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java
+1
-0
ruoyi-inventory/pom.xml
+1
-1
ruoyi-inventory/src/main/java/com/ruoyi/inventory/controller/OutboundOrderItemsController.java
+0
-25
ruoyi-inventory/src/main/java/com/ruoyi/inventory/controller/OutboundOrdersController.java
+28
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/controller/OwnersController.java
+4
-3
ruoyi-inventory/src/main/java/com/ruoyi/inventory/controller/StorageLocationsController.java
+24
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/Inventory.java
+89
-34
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/OutboundOrders.java
+6
-227
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/Owners.java
+14
-2
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/StorageLocations.java
+39
-1
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/vo/OutboundTemplateVO.java
+228
-209
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/vo/OwnerTemplateVO.java
+64
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/vo/StorageLocationsLocationTemplateVO.java
+52
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/OutboundOrderItemsMapper.java
+1
-1
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/OutboundOrderLogMapper.java
+2
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/OwnersMapper.java
+1
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/StorageLocationsMapper.java
+3
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IOutboundOrderItemsService.java
+0
-2
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IOutboundOrdersService.java
+5
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IOwnersService.java
+3
-1
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IStorageLocationsService.java
+6
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/InventoryServiceImpl.java
+21
-15
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/OutboundOrderItemsServiceImpl.java
+0
-149
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/OutboundOrdersServiceImpl.java
+322
-8
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/OwnersServiceImpl.java
+69
-45
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/StorageLocationsServiceImpl.java
+94
-0
ruoyi-inventory/src/main/resources/mapper/inventory/InventoryMapper.xml
+46
-10
ruoyi-inventory/src/main/resources/mapper/inventory/OutboundOrderItemsMapper.xml
+1
-1
ruoyi-inventory/src/main/resources/mapper/inventory/OutboundOrdersMapper.xml
+11
-4
ruoyi-inventory/src/main/resources/mapper/inventory/OwnersMapper.xml
+51
-23
ruoyi-inventory/src/main/resources/mapper/inventory/StorageLocationsMapper.xml
+118
-5
没有找到文件。
ruoyi-admin-vue/src/components/materialsSeletor.vue
View file @
19bd4ddb
...
...
@@ -24,7 +24,7 @@
<!-- 右侧物料列表 -->
<pane
size=
"84"
style=
"overflow: auto;"
>
<div
style=
"padding: 10px; display: flex; flex-direction: column;"
>
<!-- 查询表单 -->
<!-- 查询表单
(恢复所有查询项,保留ID核心逻辑)
-->
<el-form
:model=
"queryParams"
ref=
"queryForm"
size=
"small"
:inline=
"true"
label-width=
"88px"
>
<el-form-item
label=
"SAP物料号"
prop=
"sapNo"
>
<el-input
...
...
@@ -56,7 +56,7 @@
</el-form-item>
</el-form>
<!-- 物料表格 -->
<!-- 物料表格
(恢复所有字段显示)
-->
<el-table
ref=
"materialTable"
v-loading=
"loading"
...
...
@@ -74,6 +74,7 @@
align=
"center"
/>
<el-table-column
type=
"index"
label=
"序号"
align=
"center"
/>
<el-table-column
label=
"物料ID"
align=
"center"
prop=
"id"
/>
<el-table-column
label=
"SAP物料号"
align=
"center"
prop=
"sapNo"
/>
<el-table-column
label=
"物料名称"
align=
"center"
prop=
"materialName"
width=
"150"
/>
<el-table-column
label=
"TS Code"
align=
"center"
prop=
"tsCode"
/>
...
...
@@ -119,7 +120,7 @@ export default {
components
:
{
TreeComponent
,
Splitpanes
,
Pane
},
props
:
{
value
:
{
type
:
[
Array
,
String
],
type
:
[
Array
,
String
,
Number
],
default
:
()
=>
[]
},
multiple
:
{
...
...
@@ -130,7 +131,7 @@ export default {
type
:
Array
,
default
:
()
=>
[]
},
selectedMaterial
Codes
:
{
selectedMaterial
Ids
:
{
// 核心:基于ID的选中项
type
:
Array
,
default
:
()
=>
[]
}
...
...
@@ -141,11 +142,11 @@ export default {
treeProps
:
{
children
:
'children'
,
label
:
'label'
,
value
:
'sid'
},
nodeKey
:
'sid'
,
loadingTree
:
false
,
categoryMap
:
{},
categoryNameToCodeMap
:
{},
categoryCodeToSidMap
:
{},
categoryMap
:
{},
// 恢复分类名称映射(显示用)
categoryNameToCodeMap
:
{},
// 恢复分类名称转编码(查询用)
categoryCodeToSidMap
:
{},
// 恢复分类编码转SID(树选择用)
currentNodeId
:
null
,
queryParams
:
{
queryParams
:
{
// 恢复所有查询参数(显示+查询用)
pageNum
:
1
,
pageSize
:
10
,
sapNo
:
null
,
...
...
@@ -169,12 +170,12 @@ export default {
immediate
:
true
,
deep
:
true
,
handler
(
val
)
{
if
(
this
.
selectedMaterial
Code
s
.
length
===
0
)
{
if
(
this
.
selectedMaterial
Id
s
.
length
===
0
)
{
this
.
handleValueChange
(
val
)
}
}
},
selectedMaterial
Code
s
:
{
selectedMaterial
Id
s
:
{
immediate
:
true
,
deep
:
true
,
handler
(
val
)
{
...
...
@@ -216,14 +217,35 @@ export default {
}
},
async
created
()
{
// 恢复分类列表和树数据加载(显示分类名称用)
await
Promise
.
all
([
this
.
getCategoryList
(),
this
.
getCategoryTreeData
()])
this
.
getList
()
},
methods
:
{
// 新增:清洗名称方法(不改动原有逻辑,仅新增)
cleanMaterialName
(
name
)
{
if
(
!
name
)
return
''
return
name
.
trim
().
toLowerCase
().
replace
(
/
[^\u
4e00-
\u
9fa5a-zA-Z0-9
]
/g
,
''
)
// 恢复分类列表加载(分类名称映射)
async
getCategoryList
()
{
try
{
const
response
=
await
listMaterials_category
({
pageNum
:
1
,
pageSize
:
1000
})
if
(
response
.
rows
&&
response
.
rows
.
length
>
0
)
{
this
.
categoryMap
=
{}
this
.
categoryNameToCodeMap
=
{}
response
.
rows
.
forEach
(
item
=>
{
if
(
item
.
isUsed
!==
0
&&
item
.
isUsed
!==
'0'
)
{
const
code
=
item
.
categoryCode
this
.
categoryMap
[
code
]
=
item
.
categoryName
if
(
!
this
.
categoryNameToCodeMap
[
item
.
categoryName
])
{
this
.
categoryNameToCodeMap
[
item
.
categoryName
]
=
code
}
else
if
(
!
Array
.
isArray
(
this
.
categoryNameToCodeMap
[
item
.
categoryName
]))
{
this
.
categoryNameToCodeMap
[
item
.
categoryName
]
=
[
this
.
categoryNameToCodeMap
[
item
.
categoryName
],
code
]
}
else
{
this
.
categoryNameToCodeMap
[
item
.
categoryName
].
push
(
code
)
}
}
})
}
}
catch
(
error
)
{
console
.
error
(
'获取分类列表失败:'
,
error
)
}
},
handleValueChange
(
val
)
{
if
(
this
.
isSelecting
)
return
...
...
@@ -255,30 +277,6 @@ export default {
this
.
handleValueSync
()
}
},
async
getCategoryList
()
{
try
{
const
response
=
await
listMaterials_category
({
pageNum
:
1
,
pageSize
:
1000
})
if
(
response
.
rows
&&
response
.
rows
.
length
>
0
)
{
this
.
categoryMap
=
{}
this
.
categoryNameToCodeMap
=
{}
response
.
rows
.
forEach
(
item
=>
{
if
(
item
.
isUsed
!==
0
&&
item
.
isUsed
!==
'0'
)
{
const
code
=
item
.
categoryCode
this
.
categoryMap
[
code
]
=
item
.
categoryName
if
(
!
this
.
categoryNameToCodeMap
[
item
.
categoryName
])
{
this
.
categoryNameToCodeMap
[
item
.
categoryName
]
=
code
}
else
if
(
!
Array
.
isArray
(
this
.
categoryNameToCodeMap
[
item
.
categoryName
]))
{
this
.
categoryNameToCodeMap
[
item
.
categoryName
]
=
[
this
.
categoryNameToCodeMap
[
item
.
categoryName
],
code
]
}
else
{
this
.
categoryNameToCodeMap
[
item
.
categoryName
].
push
(
code
)
}
}
})
}
}
catch
(
error
)
{
console
.
error
(
'获取分类列表失败:'
,
error
)
}
},
async
getCategoryTreeData
()
{
this
.
loadingTree
=
true
try
{
...
...
@@ -347,10 +345,10 @@ export default {
getList
()
{
this
.
loading
=
true
listMaterials
(
this
.
queryParams
).
then
(
response
=>
{
// 恢复所有字段映射(显示用)
this
.
materialsList
=
(
response
.
rows
||
[]).
filter
(
item
=>
item
.
isUsed
!==
0
&&
item
.
isUsed
!==
'0'
).
map
(
item
=>
({
...
item
,
displayCategory
:
this
.
categoryMap
[
item
.
categoryCode
]
||
`
${
item
.
categoryCode
}
(未匹配分类)`
,
cleanName
:
this
.
cleanMaterialName
(
item
.
materialName
)
// 新增:预处理清洗名称
displayCategory
:
this
.
categoryMap
[
item
.
categoryCode
]
||
`
${
item
.
categoryCode
}
(未匹配分类)`
}))
this
.
total
=
response
.
total
||
0
this
.
$nextTick
(()
=>
{
...
...
@@ -365,6 +363,7 @@ export default {
})
},
handleQuery
()
{
// 恢复分类名称查询逻辑
const
inputName
=
this
.
queryParams
.
categoryNameInput
if
(
inputName
)
{
const
matchedCode
=
this
.
categoryNameToCodeMap
[
inputName
]
...
...
@@ -383,6 +382,7 @@ export default {
this
.
getList
()
},
resetQuery
()
{
// 恢复所有查询参数重置
this
.
queryParams
=
{
pageNum
:
1
,
pageSize
:
10
,
...
...
@@ -400,6 +400,7 @@ export default {
this
.
clearSelection
()
this
.
getList
()
},
// 核心:基于 ID 的选择事件(保留所有字段返回)
handleSelectionChange
(
selection
)
{
if
(
this
.
isSelecting
||
!
this
.
$refs
.
materialTable
)
return
...
...
@@ -420,22 +421,29 @@ export default {
this
.
selectedRows
=
selection
}
// 返回数据保留所有字段,但核心标识为id
const
selectedIds
=
this
.
selectedRows
.
map
(
row
=>
row
.
id
)
const
selectedData
=
this
.
selectedRows
.
map
(
item
=>
({
id
:
item
.
id
,
sapNo
:
item
.
sapNo
,
materialName
:
item
.
materialName
,
categoryId
:
item
.
categoryCode
||
''
tsCode
:
item
.
tsCode
,
categoryCode
:
item
.
categoryCode
,
categoryName
:
this
.
categoryMap
[
item
.
categoryCode
]
||
item
.
categoryCode
,
specification
:
item
.
specification
,
materialUnit
:
item
.
materialUnit
,
isBatchManaged
:
item
.
isBatchManaged
}))
this
.
$emit
(
'selection-change'
,
{
materialCodes
:
selectedIds
,
materialIds
:
selectedIds
,
// 核心:返回ID数组
materials
:
selectedData
,
// 保留所有字段数据
names
:
selectedData
.
map
(
item
=>
item
.
materialName
),
categoryIds
:
selectedData
.
map
(
item
=>
item
.
category
Id
)
categoryIds
:
selectedData
.
map
(
item
=>
item
.
category
Code
)
})
if
(
this
.
multiple
)
{
this
.
$emit
(
'input'
,
selectedIds
)
this
.
$emit
(
'input'
,
selectedIds
)
// v-model绑定ID
this
.
$emit
(
'change'
,
selectedData
)
}
else
{
const
singleId
=
selectedIds
.
length
>
0
?
selectedIds
[
0
]
:
''
...
...
@@ -447,6 +455,7 @@ export default {
this
.
isSelecting
=
false
}
},
// 单选模式下的选择事件(纯 ID 逻辑,保留字段返回)
handleTableSelect
(
selection
,
row
)
{
if
(
this
.
isSelecting
||
this
.
multiple
)
return
...
...
@@ -458,10 +467,23 @@ export default {
this
.
$refs
.
materialTable
.
toggleRowSelection
(
row
,
true
)
this
.
singleSelectedId
=
row
.
id
this
.
selectedRows
=
[
row
]
// 返回完整字段数据
const
selectedData
=
{
id
:
row
.
id
,
sapNo
:
row
.
sapNo
,
materialName
:
row
.
materialName
,
tsCode
:
row
.
tsCode
,
categoryCode
:
row
.
categoryCode
,
categoryName
:
this
.
categoryMap
[
row
.
categoryCode
]
||
row
.
categoryCode
,
specification
:
row
.
specification
,
materialUnit
:
row
.
materialUnit
,
isBatchManaged
:
row
.
isBatchManaged
}
this
.
$emit
(
'input'
,
row
.
id
)
this
.
$emit
(
'change'
,
{
id
:
row
.
id
,
sapNo
:
row
.
sapNo
,
materialName
:
row
.
materialName
}
)
this
.
$emit
(
'change'
,
selectedData
)
this
.
$emit
(
'selection-change'
,
{
materialCodes
:
[
row
.
id
],
materialIds
:
[
row
.
id
],
materials
:
[
selectedData
],
names
:
[
row
.
materialName
],
categoryIds
:
[
row
.
categoryCode
||
''
]
})
...
...
@@ -471,7 +493,8 @@ export default {
this
.
$emit
(
'input'
,
''
)
this
.
$emit
(
'change'
,
null
)
this
.
$emit
(
'selection-change'
,
{
materialCodes
:
[],
materialIds
:
[],
materials
:
[],
names
:
[],
categoryIds
:
[]
})
...
...
@@ -480,6 +503,7 @@ export default {
this
.
isSelecting
=
false
}
},
// 行点击事件(纯 ID 逻辑,保留字段返回)
handleRowClick
(
row
)
{
if
(
this
.
isSelecting
||
!
this
.
$refs
.
materialTable
)
return
...
...
@@ -493,10 +517,23 @@ export default {
this
.
$refs
.
materialTable
.
toggleRowSelection
(
row
,
true
)
this
.
singleSelectedId
=
row
.
id
this
.
selectedRows
=
[
row
]
// 返回完整字段数据
const
selectedData
=
{
id
:
row
.
id
,
sapNo
:
row
.
sapNo
,
materialName
:
row
.
materialName
,
tsCode
:
row
.
tsCode
,
categoryCode
:
row
.
categoryCode
,
categoryName
:
this
.
categoryMap
[
row
.
categoryCode
]
||
row
.
categoryCode
,
specification
:
row
.
specification
,
materialUnit
:
row
.
materialUnit
,
isBatchManaged
:
row
.
isBatchManaged
}
this
.
$emit
(
'input'
,
row
.
id
)
this
.
$emit
(
'change'
,
{
id
:
row
.
id
,
sapNo
:
row
.
sapNo
,
materialName
:
row
.
materialName
}
)
this
.
$emit
(
'change'
,
selectedData
)
this
.
$emit
(
'selection-change'
,
{
materialCodes
:
[
row
.
id
],
materialIds
:
[
row
.
id
],
materials
:
[
selectedData
],
names
:
[
row
.
materialName
],
categoryIds
:
[
row
.
categoryCode
||
''
]
})
...
...
@@ -506,7 +543,8 @@ export default {
this
.
$emit
(
'input'
,
''
)
this
.
$emit
(
'change'
,
null
)
this
.
$emit
(
'selection-change'
,
{
materialCodes
:
[],
materialIds
:
[],
materials
:
[],
names
:
[],
categoryIds
:
[]
})
...
...
@@ -518,6 +556,7 @@ export default {
this
.
isSelecting
=
false
}
},
// 清空选择(纯 ID 逻辑)
clearSelection
()
{
if
(
this
.
isSelecting
||
!
this
.
$refs
.
materialTable
)
return
...
...
@@ -529,7 +568,8 @@ export default {
this
.
$emit
(
'input'
,
this
.
multiple
?
[]
:
''
)
this
.
$emit
(
'change'
,
this
.
multiple
?
[]
:
null
)
this
.
$emit
(
'selection-change'
,
{
materialCodes
:
[],
materialIds
:
[],
materials
:
[],
names
:
[],
categoryIds
:
[]
})
...
...
@@ -537,27 +577,27 @@ export default {
this
.
isSelecting
=
false
}
},
// 核心
修改:反显逻辑改为匹配物料名称
// 核心
:基于 ID 的反显逻辑(保留所有字段显示)
handleValueSync
(
isRetry
=
false
)
{
if
(
this
.
loading
||
this
.
isSelecting
||
!
this
.
$refs
.
materialTable
)
return
if
(
isRetry
)
this
.
isRetrySync
=
true
const
val
=
this
.
selectedMaterialCodes
.
length
?
this
.
selectedMaterialCodes
:
this
.
value
// 优先使用 selectedMaterialIds,其次是 value
const
val
=
this
.
selectedMaterialIds
.
length
?
this
.
selectedMaterialIds
:
this
.
value
if
(
!
val
||
(
Array
.
isArray
(
val
)
&&
!
val
.
length
))
{
this
.
clearSelection
()
this
.
isRetrySync
=
false
return
}
// 处理名称格式:转数组+清洗
const
targetNames
=
this
.
multiple
?
Array
.
isArray
(
val
)
?
val
:
[
val
]
:
[
Array
.
isArray
(
val
)
?
val
[
0
]
:
val
]
const
targetCleanNames
=
targetNames
.
map
(
name
=>
this
.
cleanMaterialName
(
name
)).
filter
(
Boolean
)
const
targetRawNames
=
targetNames
.
filter
(
Boolean
)
// 统一处理 ID 格式(兼容字符串/数字)
const
targetIds
=
this
.
multiple
?
Array
.
isArray
(
val
)
?
val
.
map
(
id
=>
String
(
id
))
:
[
String
(
val
)]
:
[
String
(
Array
.
isArray
(
val
)
?
val
[
0
]
:
val
)]
const
validTargetIds
=
targetIds
.
filter
(
id
=>
id
&&
id
!==
'undefined'
&&
id
!==
'null'
)
if
(
!
targetCleanNames
.
length
&&
!
targetRawName
s
.
length
)
{
if
(
!
validTargetId
s
.
length
)
{
this
.
clearSelection
()
this
.
isRetrySync
=
false
return
...
...
@@ -568,36 +608,36 @@ export default {
this
.
$refs
.
materialTable
.
clearSelection
()
let
matchedCount
=
0
//
匹配物料名称(精准/清洗后
)
//
基于 ID 精准匹配反显(保留所有字段
)
this
.
materialsList
.
forEach
(
row
=>
{
const
rowRawName
=
row
.
materialName
const
rowCleanName
=
row
.
cleanName
||
this
.
cleanMaterialName
(
rowRawName
)
const
isMatched
=
targetRawNames
.
includes
(
rowRawName
)
||
targetCleanNames
.
includes
(
rowCleanName
)
if
(
isMatched
)
{
const
rowId
=
String
(
row
.
id
)
if
(
validTargetIds
.
includes
(
rowId
))
{
this
.
$refs
.
materialTable
.
toggleRowSelection
(
row
,
true
)
matchedCount
++
}
})
// 刷新选中行
this
.
selectedRows
=
this
.
materialsList
.
filter
(
row
=>
{
const
rowRawName
=
row
.
materialName
const
rowCleanName
=
row
.
cleanName
||
this
.
cleanMaterialName
(
rowRawName
)
return
targetRawNames
.
includes
(
rowRawName
)
||
targetCleanNames
.
includes
(
rowCleanName
)
})
// 更新选中行
this
.
selectedRows
=
this
.
materialsList
.
filter
(
row
=>
validTargetIds
.
includes
(
String
(
row
.
id
))
)
this
.
singleSelectedId
=
this
.
multiple
?
null
:
(
this
.
selectedRows
[
0
]?.
id
||
null
)
// 未匹配到的处理
if
(
matchedCount
===
0
&&
!
isRetry
)
{
this
.
$emit
(
'selection-change'
,
{
materialCodes
:
[],
names
:
[],
categoryIds
:
[]
})
this
.
$emit
(
'selection-change'
,
{
materialIds
:
[],
materials
:
[],
names
:
[],
categoryIds
:
[]
})
this
.
$emit
(
'input'
,
this
.
multiple
?
[]
:
''
)
}
if
(
matchedCount
===
0
&&
isRetry
)
{
console
.
warn
(
'反显重试仍未匹配到数据'
,
{
targetNames
:
targetRawNames
,
targetCleanNames
:
targetCleanNames
,
listNames
:
this
.
materialsList
.
map
(
r
=>
r
.
materialName
)
console
.
warn
(
'反显重试仍未匹配到ID'
,
{
targetIds
:
validTargetIds
,
listIds
:
this
.
materialsList
.
map
(
r
=>
String
(
r
.
id
))
})
}
}
catch
(
e
)
{
...
...
@@ -607,7 +647,8 @@ export default {
this
.
isRetrySync
=
false
}
},
setSelectedCodes
(
codes
)
{
// 外部设置选中 ID 的方法
setSelectedIds
(
ids
)
{
if
(
this
.
isSelecting
)
return
this
.
isSelecting
=
true
...
...
@@ -617,7 +658,7 @@ export default {
this
.
getList
().
then
(()
=>
{
this
.
$nextTick
(()
=>
{
this
.
$props
.
selectedMaterial
Codes
=
code
s
this
.
$props
.
selectedMaterial
Ids
=
id
s
this
.
handleValueSync
(
true
)
})
})
...
...
@@ -625,13 +666,35 @@ export default {
this
.
isSelecting
=
false
}
},
// 获取选中物料(返回完整字段,核心为ID)
getSelectedMaterials
()
{
if
(
this
.
multiple
)
{
return
this
.
selectedRows
.
map
(
row
=>
({
id
:
row
.
id
,
sapNo
:
row
.
sapNo
,
materialName
:
row
.
materialName
}))
return
this
.
selectedRows
.
map
(
row
=>
({
id
:
row
.
id
,
sapNo
:
row
.
sapNo
,
materialName
:
row
.
materialName
,
tsCode
:
row
.
tsCode
,
categoryCode
:
row
.
categoryCode
,
categoryName
:
this
.
categoryMap
[
row
.
categoryCode
]
||
row
.
categoryCode
,
specification
:
row
.
specification
,
materialUnit
:
row
.
materialUnit
,
isBatchManaged
:
row
.
isBatchManaged
}))
}
else
{
return
this
.
selectedRows
[
0
]
?
{
id
:
this
.
selectedRows
[
0
].
id
,
sapNo
:
this
.
selectedRows
[
0
].
sapNo
,
materialName
:
this
.
selectedRows
[
0
].
materialName
}
:
null
return
this
.
selectedRows
[
0
]
?
{
id
:
this
.
selectedRows
[
0
].
id
,
sapNo
:
this
.
selectedRows
[
0
].
sapNo
,
materialName
:
this
.
selectedRows
[
0
].
materialName
,
tsCode
:
this
.
selectedRows
[
0
].
tsCode
,
categoryCode
:
this
.
selectedRows
[
0
].
categoryCode
,
categoryName
:
this
.
categoryMap
[
this
.
selectedRows
[
0
].
categoryCode
]
||
this
.
selectedRows
[
0
].
categoryCode
,
specification
:
this
.
selectedRows
[
0
].
specification
,
materialUnit
:
this
.
selectedRows
[
0
].
materialUnit
,
isBatchManaged
:
this
.
selectedRows
[
0
].
isBatchManaged
}
:
null
}
},
// 单选模式下设置选中 ID
setSingleSelection
(
id
)
{
if
(
this
.
isSelecting
||
this
.
multiple
)
return
...
...
@@ -644,10 +707,23 @@ export default {
if
(
targetRow
)
{
this
.
$refs
.
materialTable
.
toggleRowSelection
(
targetRow
,
true
)
this
.
selectedRows
=
[
targetRow
]
// 返回完整字段数据
const
selectedData
=
{
id
:
targetRow
.
id
,
sapNo
:
targetRow
.
sapNo
,
materialName
:
targetRow
.
materialName
,
tsCode
:
targetRow
.
tsCode
,
categoryCode
:
targetRow
.
categoryCode
,
categoryName
:
this
.
categoryMap
[
targetRow
.
categoryCode
]
||
targetRow
.
categoryCode
,
specification
:
targetRow
.
specification
,
materialUnit
:
targetRow
.
materialUnit
,
isBatchManaged
:
targetRow
.
isBatchManaged
}
this
.
$emit
(
'input'
,
id
)
this
.
$emit
(
'change'
,
{
id
:
targetRow
.
id
,
sapNo
:
targetRow
.
sapNo
,
materialName
:
targetRow
.
materialName
}
)
this
.
$emit
(
'change'
,
selectedData
)
this
.
$emit
(
'selection-change'
,
{
materialCodes
:
[
id
],
materialIds
:
[
id
],
materials
:
[
selectedData
],
names
:
[
targetRow
.
materialName
],
categoryIds
:
[
targetRow
.
categoryCode
||
''
]
})
...
...
@@ -655,7 +731,8 @@ export default {
this
.
$emit
(
'input'
,
''
)
this
.
$emit
(
'change'
,
null
)
this
.
$emit
(
'selection-change'
,
{
materialCodes
:
[],
materialIds
:
[],
materials
:
[],
names
:
[],
categoryIds
:
[]
})
...
...
ruoyi-admin-vue/src/views/inventory/locations/index.vue
View file @
19bd4ddb
...
...
@@ -113,6 +113,53 @@
/>
</el-select>
</el-form-item>
<!-- 新增查询字段 -->
<el-form-item
label=
"库位使用"
prop=
"locationUsage"
>
<el-select
v-model=
"queryParams.locationUsage"
placeholder=
"请选择库位使用"
clearable
style=
"width: 100%;"
>
<el-option
v-for=
"item in dict.type.location_usage"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"允许混放产品"
prop=
"allowMixedProducts"
>
<el-select
v-model=
"queryParams.allowMixedProducts"
placeholder=
"请选择是否允许混放产品"
clearable
style=
"width: 100%;"
>
<el-option
v-for=
"item in dict.type.yorn"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"上架区"
prop=
"zoneCode"
>
<el-input
v-model=
"queryParams.zoneCode"
placeholder=
"请输入上架区"
clearable
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"拣货区"
prop=
"pickingArea"
>
<el-input
v-model=
"queryParams.pickingArea"
placeholder=
"请输入拣货区"
clearable
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
</page-wrapper-search>
<div
class=
"table-container"
>
...
...
@@ -141,6 +188,39 @@
<div><strong>
层:
</strong>
{{
scope
.
row
.
layerCode
||
'-'
}}
</div>
</el-col>
</el-row>
<!-- 新增展开字段 -->
<el-row
:gutter=
"20"
style=
"margin: 10px 0;"
>
<el-col
:span=
"6"
>
<div><strong>
上架顺序:
</strong>
{{
scope
.
row
.
putawayOrder
||
'-'
}}
</div>
</el-col>
<el-col
:span=
"6"
>
<div><strong>
拣货顺序:
</strong>
{{
scope
.
row
.
pickingOrder
||
'-'
}}
</div>
</el-col>
<el-col
:span=
"6"
>
<div><strong>
库位处理:
</strong>
{{
scope
.
row
.
locationHandling
||
'-'
}}
</div>
</el-col>
<el-col
:span=
"6"
>
<div><strong>
周转需求:
</strong>
{{
scope
.
row
.
turnoverDemand
||
'-'
}}
</div>
</el-col>
</el-row>
<el-row
:gutter=
"20"
style=
"margin: 10px 0;"
>
<el-col
:span=
"6"
>
<div><strong>
库位使用:
</strong>
<dict-tag
:options=
"dict.type.location_usage"
:value=
"scope.row.locationUsage"
/>
</div>
</el-col>
<el-col
:span=
"6"
>
<div><strong>
允许混放产品:
</strong>
<dict-tag
:options=
"dict.type.yorn"
:value=
"scope.row.allowMixedProducts"
/>
</div>
</el-col>
<el-col
:span=
"6"
>
<div><strong>
允许混放批次:
</strong>
{{
scope
.
row
.
allowMixedBatches
||
'-'
}}
</div>
</el-col>
<el-col
:span=
"6"
>
<div><strong>
拣货区:
</strong>
{{
scope
.
row
.
pickingArea
||
'-'
}}
</div>
</el-col>
</el-row>
<el-row
:gutter=
"20"
style=
"margin: 10px 0;"
>
<el-col
:span=
"24"
>
<div><strong>
允许存放物料名称:
</strong>
{{
scope
.
row
.
materialNames
||
'-'
}}
</div>
...
...
@@ -161,6 +241,23 @@
<dict-tag
:options=
"dict.type.location_type"
:value=
"scope.row.locationType"
/>
</
template
>
</el-table-column>
<!-- 新增表格列 -->
<el-table-column
label=
"库位使用"
align=
"center"
prop=
"locationUsage"
width=
"100"
>
<
template
slot-scope=
"scope"
>
<dict-tag
:options=
"dict.type.location_usage"
:value=
"scope.row.locationUsage"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"上架区"
align=
"center"
prop=
"zoneCode"
width=
"100"
/>
<el-table-column
label=
"拣货区"
align=
"center"
prop=
"pickingArea"
width=
"100"
/>
<el-table-column
label=
"允许混放产品"
align=
"center"
prop=
"allowMixedProducts"
width=
"120"
>
<
template
slot-scope=
"scope"
>
<dict-tag
:options=
"dict.type.yorn"
:value=
"scope.row.allowMixedProducts"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"允许混放批次"
align=
"center"
prop=
"allowMixedBatches"
width=
"120"
/>
<el-table-column
label=
"上架顺序"
align=
"center"
prop=
"putawayOrder"
width=
"100"
/>
<el-table-column
label=
"拣货顺序"
align=
"center"
prop=
"pickingOrder"
width=
"100"
/>
<el-table-column
label=
"库位容量(千克)"
align=
"center"
prop=
"capacity"
width=
"120"
/>
<el-table-column
label=
"体积容量(立方米)"
align=
"center"
prop=
"volumeCapacity"
width=
"120"
/>
<el-table-column
label=
"允许存放的危险等级"
align=
"center"
prop=
"allowedHazardLevels"
width=
"140"
/>
...
...
@@ -243,7 +340,7 @@
</div>
<!-- 添加或修改库位对话框 -->
<el-dialog
:title=
"title"
:visible
.
sync=
"open"
width=
"
9
00px"
append-to-body
>
<el-dialog
:title=
"title"
:visible
.
sync=
"open"
width=
"
10
00px"
append-to-body
>
<el-form
ref=
"form"
:model=
"form"
:rules=
"rules"
label-width=
"120px"
>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
...
...
@@ -299,6 +396,73 @@
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"库位使用"
prop=
"locationUsage"
>
<el-select
v-model=
"form.locationUsage"
placeholder=
"请选择库位使用"
style=
"width: 100%;"
>
<el-option
v-for=
"item in dict.type.location_usage"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"上架区"
prop=
"zoneCode"
>
<el-input
v-model=
"form.zoneCode"
placeholder=
"请输入上架区"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"拣货区"
prop=
"pickingArea"
>
<el-input
v-model=
"form.pickingArea"
placeholder=
"请输入拣货区"
/>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"上架顺序"
prop=
"putawayOrder"
>
<el-input
v-model=
"form.putawayOrder"
placeholder=
"请输入上架顺序"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"拣货顺序"
prop=
"pickingOrder"
>
<el-input
v-model=
"form.pickingOrder"
placeholder=
"请输入拣货顺序"
/>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"允许混放产品"
prop=
"allowMixedProducts"
>
<el-select
v-model=
"form.allowMixedProducts"
placeholder=
"请选择是否允许混放产品"
style=
"width: 100%;"
>
<el-option
v-for=
"item in dict.type.yorn"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"允许混放批次"
prop=
"allowMixedBatches"
>
<el-input
v-model=
"form.allowMixedBatches"
placeholder=
"请输入允许混放批次"
/>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"库位处理"
prop=
"locationHandling"
>
<el-input
v-model=
"form.locationHandling"
placeholder=
"请输入库位处理"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"周转需求"
prop=
"turnoverDemand"
>
<el-input
v-model=
"form.turnoverDemand"
placeholder=
"请输入周转需求"
/>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
...
...
@@ -431,7 +595,7 @@
</div>
</el-dialog>
<!-- 导入组件 -->
<!-- 导入组件 -
集成货主页面的导入功能 -
->
<import-excel
ref=
"import"
title=
"库位导入"
...
...
@@ -440,6 +604,8 @@
template-name=
"locations_importTemplate"
@
success=
"getList"
/>
<!-- 仓库选择器组件 -->
<WarehouseSelector
v-model=
"warehouseSelectorVisible"
@
selected=
"handleWarehouseSelected"
...
...
@@ -458,7 +624,8 @@ import { listMaterials } from "@/api/inventory/materials"
export
default
{
name
:
"Locations"
,
components
:
{
materialsSeletor
,
WarehouseSelector
,
ImportExcel
},
dicts
:
[
'sys_normal_disable'
,
'location_type'
],
// 新增字典类型
dicts
:
[
'sys_normal_disable'
,
'location_type'
,
'location_usage'
,
'yorn'
],
data
()
{
return
{
loading
:
true
,
...
...
@@ -482,6 +649,12 @@ export default {
sys_normal_disable
:
[
{
label
:
"启用"
,
value
:
"1"
},
{
label
:
"禁用"
,
value
:
"0"
}
],
// 新增字典默认值(实际会从后端加载)
location_usage
:
[],
yorn
:
[
{
label
:
"是"
,
value
:
"Y"
},
{
label
:
"否"
,
value
:
"N"
}
]
}
},
...
...
@@ -493,7 +666,12 @@ export default {
locationName
:
null
,
warehouseId
:
null
,
// 前端保持warehouseId,内部映射后端的warehousesId
locationType
:
null
,
layerCode
:
null
layerCode
:
null
,
// 新增查询参数
locationUsage
:
null
,
allowMixedProducts
:
null
,
zoneCode
:
null
,
pickingArea
:
null
},
form
:
{
...
...
@@ -517,7 +695,16 @@ export default {
temperatureZone
:
null
,
isEnabled
:
1
,
isUsed
:
1
,
sortNo
:
0
sortNo
:
0
,
// 新增表单字段
putawayOrder
:
null
,
pickingOrder
:
null
,
locationUsage
:
null
,
locationHandling
:
null
,
turnoverDemand
:
null
,
pickingArea
:
null
,
allowMixedProducts
:
null
,
allowMixedBatches
:
null
},
rules
:
{
...
...
@@ -535,6 +722,13 @@ export default {
locationType
:
[
{
required
:
true
,
message
:
'库位类型不能为空'
,
trigger
:
'change'
}
],
// 新增表单验证规则
locationUsage
:
[
{
required
:
true
,
message
:
'库位使用不能为空'
,
trigger
:
'change'
}
],
allowMixedProducts
:
[
{
required
:
true
,
message
:
'允许混放产品不能为空'
,
trigger
:
'change'
}
],
isEnabled
:
[
{
required
:
true
,
message
:
'应用状态不能为空'
,
trigger
:
'change'
}
]
...
...
@@ -712,7 +906,12 @@ export default {
locationName
:
null
,
warehouseId
:
null
,
locationType
:
null
,
layerCode
:
null
layerCode
:
null
,
// 重置新增的查询参数
locationUsage
:
null
,
allowMixedProducts
:
null
,
zoneCode
:
null
,
pickingArea
:
null
}
this
.
queryWarehouseName
=
''
this
.
getList
()
...
...
@@ -901,7 +1100,7 @@ export default {
this
.
$modal
.
msgSuccess
(
`成功选择
${
this
.
tempSelectedMaterials
.
names
.
length
}
个物料`
)
},
// 导入库位
// 导入库位
- 集成货主页面的导入逻辑
handleImport
()
{
this
.
$refs
.
import
.
show
()
},
...
...
@@ -929,7 +1128,16 @@ export default {
temperatureZone
:
null
,
isEnabled
:
1
,
isUsed
:
1
,
sortNo
:
0
sortNo
:
0
,
// 重置新增的表单字段
putawayOrder
:
null
,
pickingOrder
:
null
,
locationUsage
:
null
,
locationHandling
:
null
,
turnoverDemand
:
null
,
pickingArea
:
null
,
allowMixedProducts
:
null
,
allowMixedBatches
:
null
}
this
.
tempSelectedMaterials
=
{
materialCodes
:
[],
...
...
ruoyi-admin-vue/src/views/inventory/orders/OutboundOrderFormWithItems.vue
View file @
19bd4ddb
...
...
@@ -13,8 +13,8 @@
<el-col
:span=
"12"
>
<el-form-item
label=
"货物ID"
prop=
"materialId"
>
<el-input
v-model=
"form.material
Id
"
placeholder=
"请选择
或输入货物ID
"
v-model=
"form.material
Name
"
placeholder=
"请选择
物料
"
readonly
@
click
.
native=
"!isMaterialLocked && (openMaterialSelector = true)"
style=
"cursor: pointer"
...
...
@@ -29,34 +29,38 @@
></el-button>
</
template
>
</el-input>
<el-dialog
v-if=
"!isMaterialLocked"
title=
"选择物料"
:visible
.
sync=
"openMaterialSelector"
width=
"90%"
append-to-body
:close-on-click-modal=
"false"
:close-on-press-escape=
"false"
:modal=
"true"
:modal-append-to-body=
"true"
>
<div
style=
"height: 70vh; overflow: auto; padding: 0 10px;"
>
<MaterialSelector
ref=
"materialsSeletor"
@
selection-change=
"handleMaterialSelectionChange"
:selected-material-codes=
"form.materialUuids ? [form.materialUuids] : []"
:multiple=
"false"
/>
</div>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click
.
native=
"openMaterialSelector = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click
.
native=
"confirmMaterialSelect"
>
确认选择
</el-button>
</div>
</el-dialog>
<el-input
v-model=
"form.materialId"
type=
"hidden"
/>
</el-form-item>
</el-col>
</el-row>
<!-- 选择物料的弹窗 -->
<el-dialog
v-if=
"!isMaterialLocked"
title=
"选择物料"
:visible
.
sync=
"openMaterialSelector"
width=
"90%"
append-to-body
:close-on-click-modal=
"false"
:close-on-press-escape=
"false"
:modal=
"true"
:modal-append-to-body=
"true"
>
<div
style=
"height: 70vh; overflow: auto; padding: 0 10px;"
>
<MaterialSelector
ref=
"materialsSeletor"
@
selection-change=
"handleMaterialSelectionChange"
:selected-material-codes=
"form.materialUuids ? [form.materialUuids] : []"
:multiple=
"false"
/>
</div>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click
.
native=
"openMaterialSelector = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click
.
native=
"confirmMaterialSelect"
>
确认选择
</el-button>
</div>
</el-dialog>
<!-- 库存信息列表 -->
<el-row
v-if=
"form.materialId && form.materialId.trim()"
style=
"margin: 10px 0;"
>
<el-col
:span=
"24"
>
<div
style=
"margin-bottom: 8px; font-weight: 600; color: #1989fa;"
>
...
...
@@ -74,10 +78,11 @@
@
row-click=
"handleRowClick"
:row-key=
"item => item.inventoryId"
>
<el-table-column
prop=
"material
Id"
label=
"货物ID"
width=
"15
0"
/>
<el-table-column
prop=
"material
Name"
label=
"物料名称"
width=
"18
0"
/>
<el-table-column
prop=
"batchId"
label=
"批次ID"
width=
"150"
/>
<el-table-column
prop=
"outboundOrderId"
label=
"出库单号"
width=
"150"
/>
<!-- <el-table-column prop="warehouseId" label="仓库ID" width="120" /> -->
<el-table-column
prop=
"warehousesName"
label=
"仓库名称"
width=
"120"
/>
<el-table-column
prop=
"locationName"
label=
"库位名称"
width=
"120"
/>
<el-table-column
prop=
"locationId"
label=
"库位ID"
width=
"140"
/>
<el-table-column
prop=
"inventoryType"
...
...
@@ -110,6 +115,7 @@
</el-table-column>
</el-table>
<!-- 库存明细信息 -->
<div
v-if=
"currentSelectedRow"
style=
"margin-top: 10px; padding: 10px; border: 1px solid #e6e6e6; border-radius: 4px;"
...
...
@@ -131,15 +137,15 @@
</el-col>
<el-col
:span=
"8"
>
<el-form-item
label=
"标签颜色"
prop=
"labelColor"
>
<el-select
v-model=
"currentSelectedRow.labelColor"
<el-select
v-model=
"currentSelectedRow.labelColor"
placeholder=
"请选择标签颜色"
style=
"width: 100%;"
>
<el-option
v-for=
"color in dict.type.label_color"
:key=
"color.value"
:label=
"color.label"
<el-option
v-for=
"color in dict.type.label_color"
:key=
"color.value"
:label=
"color.label"
:value=
"color.value"
/>
</el-select>
...
...
@@ -191,17 +197,6 @@
</el-col>
</el-row>
<el-row
:gutter=
"20"
style=
"margin-top: 10px;"
>
<!-- <el-col :span="8">
<el-form-item label="发货时间" prop="shippedAt">
<el-date-picker
v-model="currentSelectedRow.shippedAt"
type="date"
placeholder="选择发货时间"
style="width: 100%;"
@input="syncDetails(false)"
/>
</el-form-item>
</el-col> -->
<el-col
:span=
"16"
>
<el-form-item
label=
"备注"
prop=
"remark"
>
<el-input
...
...
@@ -218,6 +213,7 @@
</el-col>
</el-row>
<!-- 已生成明细项 -->
<el-row
v-if=
"details.length > 0"
style=
"margin: 10px 0;"
>
<el-col
:span=
"24"
>
<div
style=
"margin-bottom: 8px; font-weight: 600; color: #1989fa;"
>
...
...
@@ -230,23 +226,23 @@
max-height=
"200"
:row-key=
"item => item.inventoryId"
>
<!-- <el-table-column prop="inventoryId" label="库存ID" width="100" /> -->
<el-table-column
prop=
"batchId"
label=
"批次ID"
/>
<!-- <el-table-column prop="warehouseId" label="仓库ID" /> -->
<el-table-column
prop=
"locationId"
label=
"库位ID"
/>
<el-table-column
prop=
"plannedQuantity"
label=
"计划数量"
/>
<el-table-column
prop=
"actualQuantity"
label=
"实际数量"
/>
<el-table-column
prop=
"unitPrice"
label=
"单价"
/>
<el-table-column
prop=
"divisor"
label=
"约数"
/>
<el-table-column
prop=
"labelColor"
label=
"标签颜色"
>
<el-table-column
prop=
"materialName"
label=
"物料名称"
width=
"180"
/>
<el-table-column
prop=
"batchId"
label=
"批次ID"
width=
"150"
/>
<el-table-column
prop=
"warehousesName"
label=
"仓库名称"
width=
"120"
/>
<el-table-column
prop=
"locationName"
label=
"库位名称"
width=
"120"
/>
<el-table-column
prop=
"locationId"
label=
"库位ID"
width=
"140"
/>
<el-table-column
prop=
"plannedQuantity"
label=
"计划数量"
width=
"100"
/>
<el-table-column
prop=
"actualQuantity"
label=
"实际数量"
width=
"100"
/>
<el-table-column
prop=
"unitPrice"
label=
"单价"
width=
"100"
/>
<el-table-column
prop=
"divisor"
label=
"约数"
width=
"80"
/>
<el-table-column
prop=
"labelColor"
label=
"标签颜色"
width=
"100"
>
<
template
slot-scope=
"scope"
>
<dict-tag
v-if=
"dict.type.label_color"
:options=
"dict.type.label_color"
:value=
"scope.row.labelColor"
/>
</
template
>
</el-table-column>
<el-table-column
prop=
"voucherNumber"
label=
"凭证号"
/>
<el-table-column
prop=
"shippedBy"
label=
"发货方"
/>
<!-- <el-table-column prop="shippedAt" label="发货时间" /> -->
<el-table-column
prop=
"remark"
label=
"备注"
/>
<el-table-column
prop=
"voucherNumber"
label=
"凭证号"
width=
"120"
/>
<el-table-column
prop=
"shippedBy"
label=
"发货方"
width=
"120"
/>
<el-table-column
prop=
"remark"
label=
"备注"
width=
"150"
/>
<el-table-column
label=
"操作"
width=
"80"
>
<
template
slot-scope=
"scope"
>
<el-button
...
...
@@ -260,6 +256,8 @@
</el-col>
</el-row>
</el-form>
<!-- 弹窗底部按钮 -->
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click
.
native=
"handleClose"
>
取消
</el-button>
<el-button
type=
"primary"
@
click
.
native=
"handleSubmit"
>
生成明细
</el-button>
...
...
@@ -314,7 +312,7 @@ export default {
},
ordersId
:
{
type
:
String
,
default
:
""
default
:
""
}
},
data
()
{
...
...
@@ -322,6 +320,7 @@ export default {
form
:
{
materialUuids
:
''
,
materialId
:
''
,
materialName
:
''
,
itemStatus
:
1
,
outboundOrderId
:
''
},
...
...
@@ -358,17 +357,16 @@ export default {
this
.
form
=
{
...
this
.
$options
.
data
().
form
,
...
this
.
initForm
,
materialName
:
this
.
initForm
.
materialName
||
''
,
outboundOrderId
:
this
.
outboundOrderId
||
this
.
initForm
.
outboundOrderId
||
''
};
this
.
selectedMaterialId
=
this
.
form
.
materialId
||
''
;
this
.
selectedMaterialInfo
=
null
;
this
.
currentSelectedRowId
=
null
;
this
.
details
=
this
.
initDetails
.
length
>
0
?
JSON
.
parse
(
JSON
.
stringify
(
this
.
initDetails
))
:
[];
// 强制等待DOM更新后再查库存,避免数据未初始化
this
.
$nextTick
(
async
()
=>
{
if
(
this
.
form
.
materialId
&&
this
.
form
.
materialId
.
trim
())
{
await
this
.
handleMaterialIdChange
();
// 二次确认:库存加载完成后手动触发回显
if
(
this
.
inventoryList
.
length
>
0
&&
!
this
.
isInitEcho
)
{
this
.
initEchoDetails
();
this
.
isInitEcho
=
true
;
...
...
@@ -393,12 +391,12 @@ export default {
this
.
form
=
{
...
this
.
$options
.
data
().
form
,
...
val
,
materialName
:
val
.
materialName
||
''
,
outboundOrderId
:
this
.
outboundOrderId
||
val
.
outboundOrderId
||
''
};
const
oldMaterialId
=
this
.
selectedMaterialId
;
this
.
selectedMaterialId
=
this
.
form
.
materialId
||
''
;
this
.
currentSelectedRowId
=
null
;
// 强制等待DOM更新后再查库存
this
.
$nextTick
(
async
()
=>
{
if
(
this
.
form
.
materialId
&&
this
.
form
.
materialId
.
trim
()
&&
this
.
form
.
materialId
!==
oldMaterialId
)
{
await
this
.
handleMaterialIdChange
();
...
...
@@ -460,7 +458,7 @@ export default {
lock
:
true
,
background
:
'rgba(0, 0, 0, 0.7)'
});
console
.
log
(
"this.form"
,
this
.
form
)
console
.
log
(
"this.form"
,
this
.
form
);
const
params
=
{
materialId
:
materialId
,
outboundOrderId
:
this
.
ordersId
...
...
@@ -468,20 +466,23 @@ export default {
console
.
log
(
'【查询库存参数】'
,
params
);
const
res
=
await
listInventoryByMaterialId
(
params
);
console
.
log
(
'【库存接口返回】'
,
res
);
console
.
log
(
'【库存接口原始行数据】'
,
res
.
rows
);
// 打印原始行数据
console
.
log
(
'【库存接口原始行数据】'
,
res
.
rows
);
if
(
res
.
code
===
200
)
{
this
.
inventoryList
=
[];
(
res
.
rows
||
[]).
forEach
(
item
=>
{
console
.
log
(
'【单条库存数据】'
,
item
);
// 打印单条库存数据
console
.
log
(
'【单条库存数据】'
,
item
);
const
newRow
=
{
// 核心修复:优先取item.inventoryId(匹配回显字段),兼容item.id
inventoryId
:
item
.
inventoryId
||
item
.
id
,
id
:
item
.
id
,
// 保留原id字段
inventoryId
:
item
.
id
,
id
:
item
.
id
,
materialId
:
item
.
materialId
||
materialId
,
materialName
:
item
.
materialName
||
''
,
batchId
:
item
.
batchId
||
''
,
outboundOrderId
:
item
.
outboundOrderId
||
this
.
form
.
outboundOrderId
,
warehouseId
:
item
.
warehouseId
||
''
,
outboundOrderId
:
item
.
orderId
||
this
.
form
.
outboundOrderId
,
warehouseId
:
item
.
warehousesId
||
''
,
warehousesId
:
item
.
warehousesId
||
''
,
warehousesName
:
item
.
warehousesName
||
''
,
locationId
:
item
.
locationId
||
''
,
locationName
:
item
.
locationName
||
''
,
inventoryType
:
item
.
inventoryType
||
1
,
quantity
:
item
.
quantity
||
0
,
lockedQuantity
:
item
.
lockedQuantity
||
0
,
...
...
@@ -498,6 +499,9 @@ export default {
};
this
.
inventoryList
.
push
(
newRow
);
});
if
(
this
.
inventoryList
.
length
>
0
&&
!
this
.
form
.
materialName
)
{
this
.
$set
(
this
.
form
,
'materialName'
,
this
.
inventoryList
[
0
].
materialName
||
''
);
}
console
.
log
(
'【组装后的库存列表】'
,
this
.
inventoryList
);
console
.
log
(
'【待回显的initDetails】'
,
this
.
initDetails
);
...
...
@@ -517,64 +521,67 @@ export default {
});
}
},
initEchoDetails
()
{
console
.
log
(
'【开始回显】inventoryList='
,
this
.
inventoryList
,
'initDetails='
,
this
.
initDetails
);
if
(
this
.
initDetails
.
length
===
0
||
this
.
inventoryList
.
length
===
0
)
return
;
// 1. 先清空所有库存行的临时数据(避免残留)
this
.
inventoryList
.
forEach
(
row
=>
{
this
.
$set
(
row
,
'actualQuantity'
,
null
);
this
.
$set
(
row
,
'plannedQuantity'
,
null
);
this
.
$set
(
row
,
'divisor'
,
null
);
this
.
$set
(
row
,
'labelColor'
,
''
);
this
.
$set
(
row
,
'unitPrice'
,
null
);
this
.
$set
(
row
,
'shippedBy'
,
''
);
this
.
$set
(
row
,
'voucherNumber'
,
''
);
this
.
$set
(
row
,
'remark'
,
''
);
});
// 2. 遍历所有initDetails明细项,逐个匹配库存行并回显
this
.
initDetails
.
forEach
(
detail
=>
{
let
targetRow
=
null
;
// 方案1:优先用inventoryId精确匹配(最可靠)
targetRow
=
this
.
inventoryList
.
find
(
row
=>
row
.
inventoryId
===
detail
.
inventoryId
);
// 方案2:兜底用batchId+warehouseId+locationId组合匹配
if
(
!
targetRow
)
{
targetRow
=
this
.
inventoryList
.
find
(
row
=>
row
.
batchId
===
detail
.
batchId
&&
row
.
warehouseId
===
detail
.
warehouseId
&&
row
.
locationId
===
detail
.
locationId
);
}
initEchoDetails
()
{
console
.
log
(
'【开始回显】inventoryList='
,
this
.
inventoryList
,
'initDetails='
,
this
.
initDetails
);
if
(
this
.
initDetails
.
length
===
0
||
this
.
inventoryList
.
length
===
0
)
return
;
// 方案3:终极兜底(如果允许“无匹配则不回显”,可去掉这一步)
if
(
!
targetRow
)
{
console
.
warn
(
'【匹配失败】明细无对应库存行,detail.inventoryId='
,
detail
.
inventoryId
);
return
;
// 跳过当前明细的回显
}
this
.
inventoryList
.
forEach
(
row
=>
{
this
.
$set
(
row
,
'actualQuantity'
,
null
);
this
.
$set
(
row
,
'plannedQuantity'
,
null
);
this
.
$set
(
row
,
'divisor'
,
null
);
this
.
$set
(
row
,
'labelColor'
,
''
);
this
.
$set
(
row
,
'unitPrice'
,
null
);
this
.
$set
(
row
,
'shippedBy'
,
''
);
this
.
$set
(
row
,
'voucherNumber'
,
''
);
this
.
$set
(
row
,
'remark'
,
''
);
});
this
.
initDetails
.
forEach
(
detail
=>
{
let
targetRow
=
null
;
targetRow
=
this
.
inventoryList
.
find
(
row
=>
row
.
inventoryId
===
detail
.
inventoryId
);
if
(
!
targetRow
)
{
targetRow
=
this
.
inventoryList
.
find
(
row
=>
row
.
batchId
===
detail
.
batchId
&&
row
.
warehousesId
===
detail
.
warehousesId
&&
row
.
locationId
===
detail
.
locationId
);
}
if
(
!
targetRow
)
{
targetRow
=
this
.
inventoryList
.
find
(
row
=>
row
.
batchId
===
detail
.
batchId
&&
row
.
materialId
===
detail
.
materialId
);
}
if
(
!
targetRow
)
{
console
.
warn
(
'【匹配失败】明细无对应库存行,detail.inventoryId='
,
detail
.
inventoryId
);
return
;
}
this
.
$set
(
targetRow
,
'actualQuantity'
,
detail
.
actualQuantity
??
null
);
this
.
$set
(
targetRow
,
'plannedQuantity'
,
detail
.
plannedQuantity
??
null
);
this
.
$set
(
targetRow
,
'divisor'
,
detail
.
divisor
??
null
);
this
.
$set
(
targetRow
,
'labelColor'
,
detail
.
labelColor
??
''
);
this
.
$set
(
targetRow
,
'unitPrice'
,
detail
.
unitPrice
??
null
);
this
.
$set
(
targetRow
,
'shippedBy'
,
detail
.
shippedBy
??
''
);
this
.
$set
(
targetRow
,
'voucherNumber'
,
detail
.
voucherNumber
??
''
);
this
.
$set
(
targetRow
,
'remark'
,
detail
.
remark
??
''
);
if
(
detail
.
warehousesName
)
this
.
$set
(
targetRow
,
'warehousesName'
,
detail
.
warehousesName
);
if
(
detail
.
locationName
)
this
.
$set
(
targetRow
,
'locationName'
,
detail
.
locationName
);
if
(
detail
.
materialName
)
this
.
$set
(
targetRow
,
'materialName'
,
detail
.
materialName
);
});
// 3. 给匹配到的库存行赋值回显数据
this
.
$set
(
targetRow
,
'actualQuantity'
,
detail
.
actualQuantity
??
null
);
this
.
$set
(
targetRow
,
'plannedQuantity'
,
detail
.
plannedQuantity
??
null
);
this
.
$set
(
targetRow
,
'divisor'
,
detail
.
divisor
??
null
);
this
.
$set
(
targetRow
,
'labelColor'
,
detail
.
labelColor
??
''
);
this
.
$set
(
targetRow
,
'unitPrice'
,
detail
.
unitPrice
??
null
);
this
.
$set
(
targetRow
,
'shippedBy'
,
detail
.
shippedBy
??
''
);
this
.
$set
(
targetRow
,
'voucherNumber'
,
detail
.
voucherNumber
??
''
);
this
.
$set
(
targetRow
,
'remark'
,
detail
.
remark
??
''
);
});
// 4. 同步明细数据(保持页面显示一致)
this
.
syncDetails
(
false
);
console
.
log
(
'【回显完成】inventoryList='
,
this
.
inventoryList
);
},
this
.
syncDetails
(
false
);
console
.
log
(
'【回显完成】inventoryList='
,
this
.
inventoryList
);
},
handleRowClick
(
row
)
{
if
(
!
row
)
return
;
this
.
currentSelectedRowId
=
row
.
inventoryId
;
},
handleRowActualQtyInput
(
row
)
{
if
(
isNaN
(
row
.
actualQuantity
)
||
row
.
actualQuantity
===
''
)
{
if
(
isNaN
(
row
.
actualQuantity
)
||
row
.
actualQuantity
===
''
||
row
.
actualQuantity
===
null
)
{
this
.
$set
(
row
,
'actualQuantity'
,
null
);
return
;
}
...
...
@@ -588,7 +595,7 @@ export default {
}
},
handleRowPlannedQtyInput
(
row
)
{
if
(
isNaN
(
row
.
plannedQuantity
)
||
row
.
plannedQuantity
===
''
)
{
if
(
isNaN
(
row
.
plannedQuantity
)
||
row
.
plannedQuantity
===
''
||
row
.
plannedQuantity
===
null
)
{
this
.
$set
(
row
,
'plannedQuantity'
,
null
);
return
;
}
...
...
@@ -613,6 +620,9 @@ export default {
row
.
actualQuantity
>=
1
&&
row
.
actualQuantity
<=
availableQty
&&
row
.
plannedQuantity
!==
null
&&
row
.
plannedQuantity
!==
undefined
&&
row
.
plannedQuantity
>=
1
&&
row
.
plannedQuantity
<=
availableQty
&&
row
.
divisor
!==
null
&&
row
.
labelColor
!==
''
&&
row
.
voucherNumber
!==
''
&&
...
...
@@ -626,7 +636,6 @@ export default {
row
.
labelColor
!==
''
||
row
.
unitPrice
!==
null
||
row
.
shippedBy
!==
''
||
// row.shippedAt !== '' ||
row
.
voucherNumber
!==
''
||
row
.
remark
!==
''
;
});
...
...
@@ -636,9 +645,13 @@ export default {
const
newDetail
=
{
inventoryId
:
row
.
inventoryId
,
materialId
:
row
.
materialId
||
this
.
form
.
materialId
,
materialName
:
row
.
materialName
||
this
.
form
.
materialName
||
''
,
batchId
:
row
.
batchId
||
row
.
batchCode
||
''
,
warehouseId
:
row
.
warehouseId
||
''
,
warehouseId
:
row
.
warehouseId
,
warehousesId
:
row
.
warehousesId
||
''
,
warehousesName
:
row
.
warehousesName
||
''
,
locationId
:
row
.
locationId
||
''
,
locationName
:
row
.
locationName
||
''
,
outboundOrderId
:
this
.
form
.
outboundOrderId
||
''
,
plannedQuantity
:
row
.
plannedQuantity
,
actualQuantity
:
row
.
actualQuantity
,
...
...
@@ -646,7 +659,6 @@ export default {
labelColor
:
row
.
labelColor
,
unitPrice
:
row
.
unitPrice
,
shippedBy
:
row
.
shippedBy
,
// shippedAt: row.shippedAt,
voucherNumber
:
row
.
voucherNumber
,
remark
:
row
.
remark
};
...
...
@@ -663,7 +675,6 @@ export default {
this
.
$set
(
inventoryRow
,
'labelColor'
,
''
);
this
.
$set
(
inventoryRow
,
'unitPrice'
,
null
);
this
.
$set
(
inventoryRow
,
'shippedBy'
,
''
);
// this.$set(inventoryRow, 'shippedAt', '');
this
.
$set
(
inventoryRow
,
'voucherNumber'
,
''
);
this
.
$set
(
inventoryRow
,
'remark'
,
''
);
if
(
this
.
currentSelectedRowId
===
row
.
inventoryId
)
{
...
...
@@ -693,6 +704,7 @@ export default {
const
submitDetails
=
this
.
details
.
map
(
detail
=>
({
...
detail
,
materialName
:
this
.
form
.
materialName
||
detail
.
materialName
,
outboundOrderId
:
this
.
form
.
outboundOrderId
||
detail
.
outboundOrderId
,
materialId
:
this
.
form
.
materialId
||
detail
.
materialId
}));
...
...
@@ -720,34 +732,73 @@ export default {
});
this
.
$emit
(
'update:open'
,
false
);
},
handleMaterialSelectionChange
()
{
const
selectedData
=
this
.
$refs
.
materialsSeletor
?.
getSelectedMaterials
?.()
||
this
.
$refs
.
materialsSeletor
?.
selectedList
||
[];
if
(
selectedData
)
{
this
.
selectedMaterialInfo
=
selectedData
;
this
.
selectedMaterialId
=
this
.
selectedMaterialInfo
.
sapNo
||
this
.
selectedMaterialInfo
.
materialId
||
''
;
console
.
log
(
"选中的SAP物料号:"
,
this
.
selectedMaterialId
);
// 修复:接收selection-change事件参数,兼容多种字段名
handleMaterialSelectionChange
(
selectedData
)
{
console
.
log
(
"【物料选择事件触发】选中数据:"
,
selectedData
);
// 兼容数组格式(multiple=false时可能返回对象,需转为数组)
const
selectList
=
Array
.
isArray
(
selectedData
)
?
selectedData
:
selectedData
?
[
selectedData
]
:
[];
if
(
selectList
.
length
>
0
)
{
this
.
selectedMaterialInfo
=
selectList
[
0
];
// 关键:兼容常见的物料ID字段名(id/materialId/uuid)
this
.
selectedMaterialId
=
this
.
selectedMaterialInfo
.
id
||
this
.
selectedMaterialInfo
.
materialId
||
this
.
selectedMaterialInfo
.
uuid
||
''
;
// 兼容常见的物料名称字段名(materialName/name)
this
.
$set
(
this
.
form
,
'materialName'
,
this
.
selectedMaterialInfo
.
materialName
||
this
.
selectedMaterialInfo
.
name
||
''
);
console
.
log
(
"【物料选择成功】ID:"
,
this
.
selectedMaterialId
,
"名称:"
,
this
.
form
.
materialName
);
}
else
{
this
.
selectedMaterialInfo
=
null
;
this
.
selectedMaterialId
=
''
;
this
.
$set
(
this
.
form
,
'materialName'
,
''
);
console
.
log
(
"【物料选择清空】"
);
}
},
// 修复:增强校验逻辑,增加组件存在性检查和异步同步
confirmMaterialSelect
()
{
this
.
handleMaterialSelectionChange
();
if
(
!
this
.
selectedMaterialId
)
{
this
.
$message
.
warning
(
'请选择物料后再确认
'
);
// 1. 检查选择器组件是否存在
if
(
!
this
.
$refs
.
materialsSeletor
)
{
this
.
$message
.
error
(
'物料选择器组件加载失败,请重试
'
);
return
;
}
this
.
$set
(
this
.
form
,
'materialId'
,
this
.
selectedMaterialInfo
.
sapNo
||
this
.
selectedMaterialId
);
this
.
$set
(
this
.
form
,
'materialUuids'
,
this
.
selectedMaterialInfo
.
sapNo
||
this
.
selectedMaterialId
);
this
.
openMaterialSelector
=
false
;
this
.
handleMaterialIdChange
();
// 2. 异步等待组件数据同步(避免取值过早)
this
.
$nextTick
(()
=>
{
if
(
this
.
$refs
.
detailForm
)
{
this
.
$refs
.
detailForm
.
validateField
(
'materialId'
);
// 3. 强制触发选中数据同步
const
selector
=
this
.
$refs
.
materialsSeletor
;
let
selectedData
=
[];
// 兼容组件的多种取值方式
if
(
selector
.
getSelectedMaterials
)
{
selectedData
=
selector
.
getSelectedMaterials
();
}
else
if
(
selector
.
selectedList
)
{
selectedData
=
selector
.
selectedList
;
}
else
if
(
selector
.
value
)
{
selectedData
=
selector
.
value
;
}
// 触发数据同步(覆盖事件未触发的场景)
this
.
handleMaterialSelectionChange
(
selectedData
);
// 4. 增强空值校验
if
(
!
this
.
selectedMaterialInfo
||
!
this
.
selectedMaterialId
)
{
this
.
$message
.
warning
(
'请选择物料后再确认'
);
return
;
}
// 5. 容错处理:确保物料ID有效
const
materialId
=
this
.
selectedMaterialInfo
.
id
||
this
.
selectedMaterialInfo
.
materialId
||
this
.
selectedMaterialInfo
.
uuid
||
''
;
if
(
!
materialId
)
{
this
.
$message
.
error
(
'选中的物料缺少有效ID,请重新选择'
);
return
;
}
// 6. 赋值并关闭弹窗
this
.
$set
(
this
.
form
,
'materialId'
,
materialId
);
this
.
$set
(
this
.
form
,
'materialUuids'
,
materialId
);
this
.
openMaterialSelector
=
false
;
// 7. 查询库存并校验字段
this
.
handleMaterialIdChange
();
this
.
$nextTick
(()
=>
{
this
.
$refs
.
detailForm
?.
validateField
(
'materialId'
);
});
});
}
},
...
...
ruoyi-admin-vue/src/views/inventory/orders/index.vue
View file @
19bd4ddb
...
...
@@ -20,6 +20,14 @@
@
click=
"handleUpdate"
v-hasPermi=
"['inventory:orders:edit']"
>
修改
</el-button>
<el-button
type=
"success"
plain
icon=
"el-icon-edit"
size=
"medium"
@
click=
"handleImport"
v-hasPermi=
"['inventory:orders:add']"
>
导入
</el-button>
<el-button
type=
"danger"
plain
...
...
@@ -74,6 +82,22 @@
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<!-- 新增:订单类型查询项 -->
<el-form-item
label=
"订单类型"
prop=
"orderType"
>
<el-select
v-model=
"queryParams.orderType"
placeholder=
"请选择订单类型"
clearable
style=
"width: 100%"
>
<el-option
v-for=
"dict in dict.type.outbound_order_type"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"批次ID"
prop=
"batchCode"
>
<el-input
v-model=
"queryParams.batchCode"
...
...
@@ -174,6 +198,13 @@
<span
v-else
>
-
</span>
</
template
>
</el-table-column>
<!-- 新增:订单类型列 -->
<el-table-column
label=
"订单类型"
align=
"center"
prop=
"orderType"
width=
"120"
>
<
template
slot-scope=
"scope"
>
<dict-tag
v-if=
"dict.type.outbound_order_type"
:options=
"dict.type.outbound_order_type"
:value=
"scope.row.orderType"
/>
<span
v-else
>
-
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"批次ID"
align=
"center"
prop=
"batchCode"
width=
"120"
/>
<el-table-column
label=
"仓库"
align=
"center"
prop=
"warehouseName"
width=
"120"
>
<
template
slot-scope=
"scope"
>
...
...
@@ -278,14 +309,29 @@
<
/el-select
>
<
/el-form-item
>
<
/el-col
>
<!--
新增:订单类型表单项
-->
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"批次ID"
prop
=
"batchCode"
>
<
el
-
input
v
-
model
=
"form.batchCode"
placeholder
=
"请输入批次ID"
:
disabled
=
"isViewDetail || formDisabled.batchCode"
/>
<
el
-
form
-
item
label
=
"订单类型"
prop
=
"orderType"
>
<
el
-
select
v
-
model
=
"form.orderType"
placeholder
=
"请选择订单类型"
:
disabled
=
"isViewDetail || formDisabled.orderType"
style
=
"width: 100%"
>
<
el
-
option
v
-
for
=
"item in dict.type.outbound_order_type"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
>
<
span
style
=
"margin-left: 8px;"
>
{{
item
.
label
}}
<
/span
>
<
/el-option
>
<
/el-select
>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"批次ID"
prop
=
"batchCode"
>
<
el
-
input
v
-
model
=
"form.batchCode"
placeholder
=
"请输入批次ID"
:
disabled
=
"isViewDetail || formDisabled.batchCode"
/>
<
/el-form-item
>
<
/el-col
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"仓库"
prop
=
"warehouseId"
>
<
el
-
input
v
-
model
=
"form.warehouseName"
...
...
@@ -307,6 +353,8 @@
<
/el-input
>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"货主"
prop
=
"ownerId"
>
<
el
-
input
...
...
@@ -329,8 +377,6 @@
<
/el-input
>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"出库日期"
prop
=
"inboundDate"
>
<
el
-
date
-
picker
...
...
@@ -344,14 +390,14 @@
/>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"目的地"
prop
=
"destination"
>
<
el
-
input
v
-
model
=
"form.destination"
placeholder
=
"请输入目的地"
:
disabled
=
"isViewDetail"
/>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"24"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"备注"
prop
=
"remark"
>
<
el
-
input
v
-
model
=
"form.remark"
type
=
"textarea"
placeholder
=
"请输入内容"
:
disabled
=
"isViewDetail"
/>
<
/el-form-item
>
...
...
@@ -371,9 +417,11 @@
<
/el-col
>
<
/el-row
>
<!--
【修改
1
】新增
materialName
展示
-->
<
div
v
-
for
=
"(group, materialId) in outboundOrderItemsGroup"
:
key
=
"materialId"
class
=
"material-group mb10"
>
<
div
class
=
"group-header"
style
=
"background: #f5f7fa; padding: 8px 12px; border-radius: 4px; margin-bottom: 8px;"
>
<
span
style
=
"font-weight: 600; margin-right: 16px;"
>
物料:
{{
materialId
+
" "
+
getMaterialName
(
materialId
)
}}
<
/span
>
<!--
【修改
2
】展示物料名称(优先取分组的
materialName
,无则用
getMaterialName
方法)
-->
<
span
style
=
"font-weight: 600; margin-right: 16px;"
>
物料:
{{
group
.
materialName
}}
<
/span
>
<
span
style
=
"color: #666;"
>
明细数量:
{{
group
.
items
.
length
}}
条
<
/span
>
<!--
仅编辑模式显示分组操作按钮
-->
<
el
-
button
...
...
@@ -398,9 +446,13 @@
<!--
仅编辑模式显示选择列
-->
<
el
-
table
-
column
type
=
"selection"
width
=
"50"
align
=
"center"
v
-
if
=
"!isViewDetail"
/>
<
el
-
table
-
column
label
=
"序号"
align
=
"center"
prop
=
"index"
width
=
"50"
/>
<
el
-
table
-
column
label
=
"物料编号"
prop
=
"materialId"
width
=
"180"
/>
<
el
-
table
-
column
label
=
"物料名称"
prop
=
"materialName"
width
=
"180"
>
<
template
slot
-
scope
=
"scope"
>
{{
scope
.
row
.
materialName
||
'-'
}}
<
/template
>
<
/el-table-column
>
<!--
<
el
-
table
-
column
label
=
"仓库编号"
prop
=
"warehouseId"
width
=
"150"
/>
-->
<
el
-
table
-
column
label
=
"库位编号"
prop
=
"location
Id
"
width
=
"150"
/>
<
el
-
table
-
column
label
=
"库位编号"
prop
=
"location
Name
"
width
=
"150"
/>
<
el
-
table
-
column
label
=
"批次编号"
prop
=
"batchCode"
width
=
"150"
/>
<
el
-
table
-
column
label
=
"计划数量"
prop
=
"plannedQuantity"
width
=
"150"
><
/el-table-column
>
...
...
@@ -462,6 +514,14 @@
@
selected
=
"handleLocationSelected"
/>
<
import
-
excel
ref
=
"import"
title
=
"导入"
import
-
url
=
"/inventory/orders/import"
template
-
url
=
"inventory/orders/importTemplate"
template
-
name
=
"owners_importTemplate"
@
success
=
"getList"
/>
<
/div
>
<
/template
>
...
...
@@ -474,7 +534,7 @@ import WarehouseSelector from "@/views/compononents/WarehouseSelector.vue"
import
LocationSelector
from
"@/views/compononents/LocationSelector.vue"
import
OwnerSelector
from
"@/views/compononents/OwnerSelector.vue"
import
PageTitle
from
"@/components/PageTitle"
import
ImportExcel
from
"@/components/ImportExcel/index"
export
default
{
name
:
"Orders"
,
dicts
:
[
'outbound_order_type'
,
'inbound_order_type'
,
'inbound_order_status'
,
'label_color'
],
...
...
@@ -483,7 +543,8 @@ export default {
WarehouseSelector
,
LocationSelector
,
OwnerSelector
,
PageTitle
PageTitle
,
ImportExcel
}
,
data
()
{
return
{
...
...
@@ -510,7 +571,7 @@ export default {
open
:
false
,
// 是否为详细查看模式
isViewDetail
:
false
,
// 明细列表(按物料ID分组)
{
materialId
:
{
items
:
[]
}
}
// 明细列表(按物料ID分组)
{
materialId
:
{
items
:
[]
,
materialName
:
''
}
}
outboundOrderItemsGroup
:
{
}
,
// 选中的明细行
selectedInboundOrderItems
:
[],
...
...
@@ -521,6 +582,7 @@ export default {
inventoryId
:
''
,
materialUuids
:
''
,
materialId
:
''
,
materialName
:
''
,
// 【修改4】新增materialName字段
batchCode
:
''
,
warehouseId
:
''
,
warehouseName
:
''
,
...
...
@@ -550,6 +612,7 @@ export default {
orderId
:
false
,
systemNo
:
false
,
orderTypeId
:
false
,
orderType
:
false
,
// 新增:订单类型禁用控制
batchCode
:
false
,
warehouseId
:
false
,
ownerId
:
false
,
...
...
@@ -562,6 +625,7 @@ export default {
orderId
:
null
,
systemNo
:
null
,
orderTypeId
:
null
,
orderType
:
null
,
// 新增:订单类型查询参数
batchCode
:
null
,
warehouseId
:
null
,
ownerId
:
null
,
...
...
@@ -580,14 +644,18 @@ export default {
form
:
{
totalAmount
:
0.00
,
warehouseName
:
''
,
ownerName
:
''
ownerName
:
''
,
ownerId
:
''
,
// 【新增】补充货主ID字段
warehouseId
:
''
,
// 【新增】补充仓库ID字段
orderType
:
null
,
// 新增:订单类型表单字段
}
,
// 表单校验规则
rules
:
{
orderId
:
[{
required
:
true
,
message
:
'请输入出库单号'
,
trigger
:
'blur'
}
],
warehouseId
:
[{
required
:
true
,
message
:
'请选择仓库'
,
trigger
:
'blur'
}
],
ownerId
:
[{
required
:
true
,
message
:
'请选择货主'
,
trigger
:
'blur'
}
],
inboundDate
:
[{
required
:
true
,
message
:
'请选择出库日期'
,
trigger
:
'change'
}
]
inboundDate
:
[{
required
:
true
,
message
:
'请选择出库日期'
,
trigger
:
'change'
}
],
orderType
:
[{
required
:
true
,
message
:
'请选择订单类型'
,
trigger
:
'change'
}
],
// 新增:订单类型校验
}
,
// 货主/仓库选择相关
ownerSelectorVisible
:
false
,
...
...
@@ -604,33 +672,14 @@ export default {
created
()
{
// 延迟加载避免初始化渲染问题
this
.
$nextTick
(()
=>
{
this
.
getdicts
(),
this
.
getList
()
}
)
}
,
methods
:
{
getMaterialName
(
materialId
)
{
if
(
!
materialId
||
!
this
.
materialdicts
.
length
)
return
'未知物料'
;
// 精准匹配(如果需要模糊匹配,把 === 改成 includes 即可)
const
matchItem
=
this
.
materialdicts
.
find
(
item
=>
String
(
item
.
value
)
===
String
(
materialId
)
);
return
matchItem
?
matchItem
.
label
:
'未知物料'
;
}
,
getdicts
(){
return
getMaterialsdicts
()
.
then
(
response
=>
{
this
.
materialdicts
=
(
response
.
data
||
response
).
map
(
item
=>
({
value
:
item
.
sap_no
,
label
:
item
.
material_name
,
}
));
console
.
log
(
"物料字典数据加载成功:"
,
this
.
materialdicts
);
}
)
.
catch
(
error
=>
{
console
.
error
(
"加载物料字典失败:"
,
error
);
this
.
$message
.
error
(
"物料字典加载失败,请刷新重试"
);
}
);
/** 打开导入弹窗 */
handleImport
()
{
this
.
$refs
.
import
.
show
()
}
,
// 仓库选择回调
handleWarehouseSelected
(
warehouse
)
{
...
...
@@ -784,6 +833,7 @@ handleOwnerSelected(owner) {
this
.
currentDetailItem
=
this
.
currentGroupData
.
items
.
length
>
0
?
{
...
this
.
currentGroupData
.
items
[
0
],
materialName
:
this
.
currentGroupData
.
items
[
0
].
materialName
||
''
,
// 【修改5】传递物料名称
plannedQuantity
:
Number
(
this
.
currentGroupData
.
items
[
0
].
plannedQuantity
)
||
0
,
actualQuantity
:
Number
(
this
.
currentGroupData
.
items
[
0
].
actualQuantity
)
||
0
,
divisor
:
Number
(
this
.
currentGroupData
.
items
[
0
].
divisor
)
||
1
,
...
...
@@ -798,6 +848,7 @@ handleOwnerSelected(owner) {
inventoryId
:
''
,
materialUuids
:
''
,
materialId
:
materialId
,
materialName
:
this
.
outboundOrderItemsGroup
[
materialId
]?.
materialName
||
''
,
// 【修改6】默认填充分组的物料名称
batchCode
:
''
,
warehouseId
:
this
.
form
.
warehouseId
||
''
,
warehouseName
:
this
.
form
.
warehouseName
||
''
,
...
...
@@ -832,6 +883,7 @@ handleOwnerSelected(owner) {
inventoryId
:
''
,
materialUuids
:
''
,
materialId
:
materialId
||
''
,
materialName
:
''
,
// 【修改7】初始化物料名称
batchCode
:
''
,
warehouseId
:
this
.
form
.
warehouseId
||
''
,
warehouseName
:
this
.
form
.
warehouseName
||
''
,
...
...
@@ -866,6 +918,7 @@ handleOwnerSelected(owner) {
...
row
,
inventoryId
:
row
.
inventoryId
||
''
,
materialUuids
:
row
.
materialId
||
''
,
materialName
:
row
.
materialName
||
''
,
// 【修改8】赋值物料名称
divisor
:
Number
(
row
.
divisor
)
||
1
,
itemStatus
:
Number
(
row
.
itemStatus
)
||
1
,
labelColor
:
Number
(
row
.
labelColor
)
||
0
,
...
...
@@ -900,6 +953,7 @@ handleOwnerSelected(owner) {
if
(
!
this
.
outboundOrderItemsGroup
[
materialId
])
{
this
.
outboundOrderItemsGroup
[
materialId
]
=
{
materialId
:
materialId
,
materialName
:
detailList
[
0
]?.
materialName
||
''
,
// 【修改9】初始化分组的物料名称
items
:
[]
}
;
}
...
...
@@ -915,6 +969,7 @@ handleOwnerSelected(owner) {
orderId
:
null
,
// 明细的orderId设为空
outboundOrderId
:
this
.
form
.
id
,
// 使用主表ID作为outboundOrderId
materialId
:
materialId
,
materialName
:
item
.
materialName
||
group
.
materialName
||
''
,
// 【修改10】保留物料名称
inventoryId
:
item
.
inventoryId
||
''
,
itemStatus
:
Number
(
item
.
itemStatus
)
||
1
,
labelColor
:
Number
(
item
.
labelColor
)
||
0
,
...
...
@@ -934,6 +989,8 @@ handleOwnerSelected(owner) {
// 全量替换分组数据
group
.
items
=
newDetails
;
// 更新分组的物料名称(取第一条的物料名称)
group
.
materialName
=
newDetails
[
0
]?.
materialName
||
group
.
materialName
;
this
.
$message
.
success
(
`成功编辑${materialId
}
物料组,共${newDetails.length
}
条明细`
);
}
else
{
// 新增模式:按库存ID去重后追加
...
...
@@ -949,6 +1006,7 @@ handleOwnerSelected(owner) {
orderId
:
null
,
// 明细的orderId设为空
outboundOrderId
:
this
.
form
.
id
||
null
,
// 使用主表ID作为outboundOrderId
materialId
:
materialId
,
materialName
:
item
.
materialName
||
''
,
// 【修改11】保留物料名称
inventoryId
:
item
.
inventoryId
||
''
,
itemStatus
:
Number
(
item
.
itemStatus
)
||
1
,
labelColor
:
Number
(
item
.
labelColor
)
||
0
,
...
...
@@ -972,6 +1030,10 @@ handleOwnerSelected(owner) {
}
group
.
items
=
[...
group
.
items
,
...
newDetails
];
// 更新分组的物料名称(如果为空,取第一条的物料名称)
if
(
!
group
.
materialName
)
{
group
.
materialName
=
newDetails
[
0
]?.
materialName
||
''
;
}
this
.
$message
.
success
(
`成功新增${newDetails.length
}
条明细`
);
}
...
...
@@ -1087,6 +1149,7 @@ handleOwnerSelected(owner) {
outboundOrderId
:
null
,
// 主表ID,由后端生成
systemNo
:
null
,
orderTypeId
:
null
,
orderType
:
null
,
// 新增:订单类型重置
batchCode
:
null
,
warehouseId
:
null
,
warehouseName
:
''
,
...
...
@@ -1112,6 +1175,7 @@ handleOwnerSelected(owner) {
orderId
:
false
,
systemNo
:
false
,
orderTypeId
:
false
,
orderType
:
false
,
// 新增:订单类型禁用重置
batchCode
:
false
,
warehouseId
:
false
,
ownerId
:
false
,
...
...
@@ -1141,12 +1205,13 @@ handleOwnerSelected(owner) {
resetQuery
()
{
// 检查ref存在性
if
(
this
.
$refs
.
queryForm
)
{
queryParams
=
{
this
.
queryParams
=
{
pageNum
:
1
,
pageSize
:
10
,
orderId
:
null
,
systemNo
:
null
,
orderTypeId
:
null
,
orderType
:
null
,
// 新增:订单类型重置
batchCode
:
null
,
warehouseId
:
null
,
ownerId
:
null
,
...
...
@@ -1181,6 +1246,7 @@ handleOwnerSelected(owner) {
orderId
:
false
,
systemNo
:
false
,
orderTypeId
:
false
,
orderType
:
false
,
// 新增:订单类型启用
batchCode
:
false
,
warehouseId
:
false
,
ownerId
:
false
,
...
...
@@ -1200,10 +1266,13 @@ handleOwnerSelected(owner) {
this
.
form
=
{
...
response
.
data
,
// outboundOrderId是后端的主键ID,orderId是用户填写的出货单号
orderId
:
response
.
data
.
outboundOrderId
||
response
.
data
.
orderId
,
// 显示用户填写的出货单号
orderId
:
response
.
data
.
outboundOrderId
||
response
.
data
.
orderId
,
warehouseName
:
response
.
data
.
warehouseName
||
response
.
data
.
warehouseId
,
ownerName
:
response
.
data
.
ownerName
||
response
.
data
.
ownerId
,
totalAmount
:
0.00
totalAmount
:
0.00
,
ownerId
:
response
.
data
.
ownerId
||
''
,
// 【新增】赋值货主ID
warehouseId
:
response
.
data
.
warehouseId
||
''
,
// 【新增】赋值仓库ID
orderType
:
response
.
data
.
orderType
||
null
,
// 新增:订单类型回显
}
if
(
response
.
data
&&
response
.
data
.
outboundOrderItemsList
&&
Array
.
isArray
(
response
.
data
.
outboundOrderItemsList
))
{
// 按物料ID分组 + 库存ID去重
...
...
@@ -1214,6 +1283,7 @@ handleOwnerSelected(owner) {
if
(
!
groupMap
[
materialId
])
{
groupMap
[
materialId
]
=
{
materialId
:
materialId
,
materialName
:
item
.
materialName
||
''
,
// 【修改12】存储分组的物料名称
items
:
[]
}
}
...
...
@@ -1226,6 +1296,7 @@ handleOwnerSelected(owner) {
...
item
,
index
:
groupMap
[
materialId
].
items
.
length
+
1
,
inventoryId
:
item
.
inventoryId
||
''
,
materialName
:
item
.
materialName
||
''
,
// 【修改13】赋值物料名称
divisor
:
item
.
divisor
!==
null
?
Number
(
item
.
divisor
)
:
1
,
itemStatus
:
item
.
itemStatus
!==
null
?
Number
(
item
.
itemStatus
)
:
1
,
labelColor
:
item
.
labelColor
!==
null
?
Number
(
item
.
labelColor
)
:
0
,
...
...
@@ -1265,6 +1336,7 @@ handleOwnerSelected(owner) {
orderId
:
true
,
// 编辑时禁用出货单号修改
systemNo
:
true
,
orderTypeId
:
true
,
orderType
:
true
,
// 新增:订单类型禁用
batchCode
:
true
,
warehouseId
:
true
,
ownerId
:
true
,
...
...
@@ -1278,7 +1350,10 @@ handleOwnerSelected(owner) {
orderId
:
response
.
data
.
outboundOrderId
||
response
.
data
.
orderId
,
// 显示用户填写的出货单号
warehouseName
:
response
.
data
.
warehouseName
||
response
.
data
.
warehouseId
,
ownerName
:
response
.
data
.
ownerName
||
response
.
data
.
ownerId
,
totalAmount
:
0.00
totalAmount
:
0.00
,
ownerId
:
response
.
data
.
ownerId
||
''
,
// 【新增】赋值货主ID
warehouseId
:
response
.
data
.
warehouseId
||
''
,
// 【新增】赋值仓库ID
orderType
:
response
.
data
.
orderType
||
null
,
// 新增:订单类型回显
}
console
.
log
(
"this.form"
,
this
.
form
)
if
(
response
.
data
&&
response
.
data
.
outboundOrderItemsList
&&
Array
.
isArray
(
response
.
data
.
outboundOrderItemsList
))
{
...
...
@@ -1290,6 +1365,7 @@ handleOwnerSelected(owner) {
if
(
!
groupMap
[
materialId
])
{
groupMap
[
materialId
]
=
{
materialId
:
materialId
,
materialName
:
item
.
materialName
||
''
,
// 【修改14】存储分组的物料名称
items
:
[]
}
}
...
...
@@ -1302,6 +1378,7 @@ handleOwnerSelected(owner) {
...
item
,
index
:
groupMap
[
materialId
].
items
.
length
+
1
,
inventoryId
:
item
.
inventoryId
||
''
,
materialName
:
item
.
materialName
||
''
,
// 【修改15】赋值物料名称
divisor
:
item
.
divisor
!==
null
?
Number
(
item
.
divisor
)
:
1
,
itemStatus
:
item
.
itemStatus
!==
null
?
Number
(
item
.
itemStatus
)
:
1
,
labelColor
:
item
.
labelColor
!==
null
?
Number
(
item
.
labelColor
)
:
0
,
...
...
@@ -1376,19 +1453,16 @@ handleOwnerSelected(owner) {
// 修改点7:构造提交数据,适配新的字段映射规则
const
submitData
=
{
...
this
.
form
,
// 关键修改:主表的orderId作为用户填写的出货单号
// 主表的id作为outboundOrderId(新增时为空,由后端生成)
outboundOrderId
:
this
.
form
.
id
,
// 主表ID作为outboundOrderId
orderId
:
this
.
form
.
orderId
,
// 用户填写的出货单号
outboundOrderId
:
this
.
form
.
id
,
orderId
:
this
.
form
.
orderId
,
orderType
:
this
.
form
.
orderType
,
// 新增:提交订单类型
outboundOrderItemsList
:
uniqueDetails
.
map
(
item
=>
{
const
{
index
,
materialUuids
,
warehouseName
,
locationName
,
...
rest
}
=
item
return
{
...
rest
,
// 修改点8:明细的orderId设为空,使用主表的id作为outboundOrderId
orderId
:
null
,
// 明细的orderId设为空
outboundOrderId
:
this
.
form
.
id
||
null
,
// 使用主表ID作为outboundOrderId
orderId
:
null
,
outboundOrderId
:
this
.
form
.
id
||
null
,
materialName
:
item
.
materialName
||
''
,
// 【修改16】提交物料名称
inventoryId
:
rest
.
inventoryId
||
''
,
materialId
:
rest
.
materialId
||
''
,
batchCode
:
rest
.
batchCode
||
''
,
...
...
@@ -1448,7 +1522,8 @@ handleOwnerSelected(owner) {
// 适配导出参数,将orderId映射到outboundOrderId
const
exportParams
=
{
...
this
.
queryParams
,
outboundOrderId
:
this
.
queryParams
.
orderId
// 映射导出参数
outboundOrderId
:
this
.
queryParams
.
orderId
,
// 映射导出参数
orderType
:
this
.
queryParams
.
orderType
,
// 新增:导出订单类型参数
}
this
.
download
(
'inventory/orders/export'
,
exportParams
,
`orders_${new Date().getTime()
}
.xlsx`
)
}
...
...
ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java
View file @
19bd4ddb
...
...
@@ -236,4 +236,5 @@ public class DictUtils
{
return
CacheConstants
.
SYS_DICT_KEY
+
configKey
;
}
}
ruoyi-inventory/pom.xml
View file @
19bd4ddb
...
...
@@ -7,7 +7,7 @@
<groupId>
com.ruoyi
</groupId>
<version>
3.9.0
</version>
<relativePath>
../pom.xml
</relativePath>
</parent>
</parent>
<build><plugins><plugin><groupId>
org.apache.maven.plugins
</groupId><artifactId>
maven-compiler-plugin
</artifactId><configuration><source>
8
</source><target>
8
</target></configuration></plugin></plugins></build>
<modelVersion>
4.0.0
</modelVersion>
<artifactId>
ruoyi-inventory
</artifactId>
...
...
ruoyi-inventory/src/main/java/com/ruoyi/inventory/controller/OutboundOrderItemsController.java
View file @
19bd4ddb
...
...
@@ -137,30 +137,5 @@ public class OutboundOrderItemsController extends BaseController
{
return
toAjax
(
outboundOrderItemsService
.
deleteOutboundOrderItemsByIds
(
ids
));
}
/**
* 下载入库单导入模板
*/
@PreAuthorize
(
"@ss.hasPermi('inventory:inbound:importTemplate')"
)
@Log
(
title
=
"入库导入模板"
,
businessType
=
BusinessType
.
IMPORT
)
@PostMapping
(
"/importTemplate"
)
public
void
importTemplate
(
HttpServletResponse
response
)
{
ExcelUtil
<
InboundTemplateVO
>
util
=
new
ExcelUtil
<
InboundTemplateVO
>(
InboundTemplateVO
.
class
);
util
.
importTemplateExcel
(
response
,
"入库单及入库物料明细信息"
);
}
/**
* 导入入库单物料明细
*/
@PreAuthorize
(
"@ss.hasPermi('inventory:inbound:import')"
)
@Log
(
title
=
"入库信息导入"
,
businessType
=
BusinessType
.
IMPORT
)
@PostMapping
(
"/import"
)
public
AjaxResult
importTemplate
(
MultipartFile
file
,
boolean
updateSupport
)
throws
Exception
{
ExcelUtil
<
OutboundTemplateVO
>
util
=
new
ExcelUtil
<
OutboundTemplateVO
>(
OutboundTemplateVO
.
class
);
List
<
OutboundTemplateVO
>
inboundOrders
=
util
.
importExcel
(
file
.
getInputStream
());
String
operName
=
getUsername
();
String
message
=
outboundOrderItemsService
.
importOutoundOrders
(
inboundOrders
,
updateSupport
,
operName
);
return
success
(
message
);
}
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/controller/OutboundOrdersController.java
View file @
19bd4ddb
...
...
@@ -5,6 +5,8 @@ import java.util.Map;
import
javax.servlet.http.HttpServletResponse
;
import
com.ruoyi.inventory.domain.Inventory
;
import
com.ruoyi.inventory.domain.vo.InboundTemplateVO
;
import
com.ruoyi.inventory.domain.vo.OutboundTemplateVO
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
...
...
@@ -23,6 +25,7 @@ import com.ruoyi.inventory.domain.OutboundOrders;
import
com.ruoyi.inventory.service.IOutboundOrdersService
;
import
com.ruoyi.common.utils.poi.ExcelUtil
;
import
com.ruoyi.common.core.page.TableDataInfo
;
import
org.springframework.web.multipart.MultipartFile
;
/**
* 出库单主Controller
...
...
@@ -136,5 +139,30 @@ public class OutboundOrdersController extends BaseController
String
resultMap
=
outboundOrdersService
.
outboundOrdersCount
();
return
AjaxResult
.
success
(
resultMap
);
}
/**
* 下载入库单导入模板
*/
@PreAuthorize
(
"@ss.hasPermi('inventory:inbound:importTemplate')"
)
@Log
(
title
=
"入库导入模板"
,
businessType
=
BusinessType
.
IMPORT
)
@PostMapping
(
"/importTemplate"
)
public
void
importTemplate
(
HttpServletResponse
response
)
{
ExcelUtil
<
InboundTemplateVO
>
util
=
new
ExcelUtil
<
InboundTemplateVO
>(
InboundTemplateVO
.
class
);
util
.
importTemplateExcel
(
response
,
"入库单及入库物料明细信息"
);
}
/**
* 导入入库单物料明细
*/
@PreAuthorize
(
"@ss.hasPermi('inventory:inbound:import')"
)
@Log
(
title
=
"入库信息导入"
,
businessType
=
BusinessType
.
IMPORT
)
@PostMapping
(
"/import"
)
public
AjaxResult
importTemplate
(
MultipartFile
file
,
boolean
updateSupport
)
throws
Exception
{
ExcelUtil
<
OutboundTemplateVO
>
util
=
new
ExcelUtil
<
OutboundTemplateVO
>(
OutboundTemplateVO
.
class
);
List
<
OutboundTemplateVO
>
inboundOrders
=
util
.
importExcel
(
file
.
getInputStream
());
String
operName
=
getUsername
();
String
message
=
outboundOrdersService
.
importOutboundOrders
(
inboundOrders
,
updateSupport
,
operName
);
return
success
(
message
);
}
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/controller/OwnersController.java
View file @
19bd4ddb
...
...
@@ -4,6 +4,7 @@ import java.util.List;
import
javax.servlet.http.HttpServletResponse
;
import
com.ruoyi.common.core.domain.entity.SysUser
;
import
com.ruoyi.inventory.domain.vo.OwnerTemplateVO
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
...
...
@@ -67,8 +68,8 @@ public class OwnersController extends BaseController
@PostMapping
(
"/import"
)
public
AjaxResult
importTemplate
(
MultipartFile
file
,
boolean
updateSupport
)
throws
Exception
{
ExcelUtil
<
Owner
s
>
util
=
new
ExcelUtil
<
Owners
>(
Owners
.
class
);
List
<
Owner
s
>
ownersList
=
util
.
importExcel
(
file
.
getInputStream
());
ExcelUtil
<
Owner
TemplateVO
>
util
=
new
ExcelUtil
<
OwnerTemplateVO
>(
OwnerTemplateVO
.
class
);
List
<
Owner
TemplateVO
>
ownersList
=
util
.
importExcel
(
file
.
getInputStream
());
String
operName
=
getUsername
();
String
message
=
ownersService
.
importOwners
(
ownersList
,
updateSupport
,
operName
);
return
success
(
message
);
...
...
@@ -77,7 +78,7 @@ public class OwnersController extends BaseController
@PostMapping
(
"/importTemplate"
)
public
void
importTemplate
(
HttpServletResponse
response
)
{
ExcelUtil
<
Owner
s
>
util
=
new
ExcelUtil
<
Owners
>(
Owners
.
class
);
ExcelUtil
<
Owner
TemplateVO
>
util
=
new
ExcelUtil
<
OwnerTemplateVO
>(
OwnerTemplateVO
.
class
);
util
.
importTemplateExcel
(
response
,
"货主数据"
);
}
...
...
ruoyi-inventory/src/main/java/com/ruoyi/inventory/controller/StorageLocationsController.java
View file @
19bd4ddb
...
...
@@ -4,6 +4,10 @@ import java.util.Collections;
import
java.util.List
;
import
java.util.Map
;
import
javax.servlet.http.HttpServletResponse
;
import
com.ruoyi.inventory.domain.Owners
;
import
com.ruoyi.inventory.domain.vo.OwnerTemplateVO
;
import
com.ruoyi.inventory.domain.vo.StorageLocationsLocationTemplateVO
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
...
...
@@ -15,6 +19,7 @@ import com.ruoyi.inventory.domain.StorageLocations;
import
com.ruoyi.inventory.service.IStorageLocationsService
;
import
com.ruoyi.common.utils.poi.ExcelUtil
;
import
com.ruoyi.common.core.page.TableDataInfo
;
import
org.springframework.web.multipart.MultipartFile
;
/**
* 库位Controller
...
...
@@ -124,4 +129,23 @@ public class StorageLocationsController extends BaseController
List
<
StorageLocations
>
list
=
storageLocationsService
.
getStorageLocationsList
(
storageLocations
);
return
getDataTable
(
list
);
}
@PreAuthorize
(
"@ss.hasPermi('inventory:owners:add')"
)
@Log
(
title
=
"货主信息"
,
businessType
=
BusinessType
.
IMPORT
)
@PostMapping
(
"/import"
)
public
AjaxResult
importTemplate
(
MultipartFile
file
,
boolean
updateSupport
)
throws
Exception
{
ExcelUtil
<
StorageLocationsLocationTemplateVO
>
util
=
new
ExcelUtil
<
StorageLocationsLocationTemplateVO
>(
StorageLocationsLocationTemplateVO
.
class
);
List
<
StorageLocationsLocationTemplateVO
>
storageLocationsLocationTemplateVOS
=
util
.
importExcel
(
file
.
getInputStream
());
String
operName
=
getUsername
();
String
message
=
storageLocationsService
.
importStorageLocationsLocation
(
storageLocationsLocationTemplateVOS
,
updateSupport
,
operName
);
return
success
(
message
);
}
@PostMapping
(
"/importTemplate"
)
public
void
importTemplate
(
HttpServletResponse
response
)
{
ExcelUtil
<
StorageLocationsLocationTemplateVO
>
util
=
new
ExcelUtil
<
StorageLocationsLocationTemplateVO
>(
StorageLocationsLocationTemplateVO
.
class
);
util
.
importTemplateExcel
(
response
,
"货主数据"
);
}
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/Inventory.java
View file @
19bd4ddb
...
...
@@ -28,9 +28,13 @@ public class Inventory extends BaseEntity
@Excel
(
name
=
"入库单号"
)
private
String
orderId
;
/** 货物名称 */
private
String
orderName
;
/** 物料ID 检索条件 */
@Excel
(
name
=
"物料ID 检索条件"
)
private
String
materialId
;
/** 货物名称 */
private
String
materialName
;
/** 批次ID 检索条件 */
@Excel
(
name
=
"批次ID 检索条件"
)
...
...
@@ -40,15 +44,20 @@ public class Inventory extends BaseEntity
private
String
warehousesId
;
/** 仓库编码 检索条件 */
private
String
warehousesCode
;
/** 仓库编码 检索条件 */
private
String
warehousesName
;
/** 库位ID 检索条件 */
@Excel
(
name
=
"库位ID 检索条件"
)
private
String
locationId
;
/** 库位名称 */
private
String
locationName
;
/** 货主ID 检索条件 */
@Excel
(
name
=
"货主ID 检索条件"
)
private
String
ownerId
;
private
String
ownerName
;
/** 库存数量 */
@Excel
(
name
=
"库存数量"
)
private
Long
quantity
;
...
...
@@ -112,6 +121,54 @@ public class Inventory extends BaseEntity
/** 预警类型 */
private
String
alertType
;
public
String
getOrderName
()
{
return
orderName
;
}
public
void
setOrderName
(
String
orderName
)
{
this
.
orderName
=
orderName
;
}
public
String
getMaterialName
()
{
return
materialName
;
}
public
void
setMaterialName
(
String
materialName
)
{
this
.
materialName
=
materialName
;
}
public
String
getWarehousesName
()
{
return
warehousesName
;
}
public
void
setWarehousesName
(
String
warehousesName
)
{
this
.
warehousesName
=
warehousesName
;
}
public
String
getLocationName
()
{
return
locationName
;
}
public
void
setLocationName
(
String
locationName
)
{
this
.
locationName
=
locationName
;
}
public
String
getWarehousesCode
()
{
return
warehousesCode
;
}
public
void
setWarehousesCode
(
String
warehousesCode
)
{
this
.
warehousesCode
=
warehousesCode
;
}
public
String
getOwnerName
()
{
return
ownerName
;
}
public
void
setOwnerName
(
String
ownerName
)
{
this
.
ownerName
=
ownerName
;
}
public
String
getWarehousesId
()
{
return
warehousesId
;
}
...
...
@@ -330,16 +387,6 @@ public class Inventory extends BaseEntity
return
updateUserCode
;
}
public
void
setWarehousesCode
(
String
warehousesCode
)
{
this
.
warehousesCode
=
warehousesCode
;
}
public
String
getWarehousesCode
()
{
return
warehousesCode
;
}
public
void
setAlertType
(
String
alertType
)
{
this
.
alertType
=
alertType
;
...
...
@@ -353,29 +400,37 @@ public class Inventory extends BaseEntity
@Override
public
String
toString
()
{
return
new
ToStringBuilder
(
this
,
ToStringStyle
.
MULTI_LINE_STYLE
)
.
append
(
"id"
,
getId
())
.
append
(
"inventoryType"
,
getInventoryType
())
.
append
(
"orderId"
,
getOrderId
())
.
append
(
"materialId"
,
getMaterialId
())
.
append
(
"batchId"
,
getBatchId
())
.
append
(
"locationId"
,
getLocationId
())
.
append
(
"ownerId"
,
getOwnerId
())
.
append
(
"quantity"
,
getQuantity
())
.
append
(
"lockedQuantity"
,
getLockedQuantity
())
.
append
(
"unitWeight"
,
getUnitWeight
())
.
append
(
"totalWeight"
,
getTotalWeight
())
.
append
(
"totalVolume"
,
getTotalVolume
())
.
append
(
"productionDate"
,
getProductionDate
())
.
append
(
"expirationDate"
,
getExpirationDate
())
.
append
(
"inventoryStatus"
,
getInventoryStatus
())
.
append
(
"lastInboundTime"
,
getLastInboundTime
())
.
append
(
"lastOutboundTime"
,
getLastOutboundTime
())
.
append
(
"isUsed"
,
getIsUsed
())
.
append
(
"sortNo"
,
getSortNo
())
.
append
(
"createTime"
,
getCreateTime
())
.
append
(
"createUserCode"
,
getCreateUserCode
())
.
append
(
"updateTime"
,
getUpdateTime
())
.
append
(
"updateUserCode"
,
getUpdateUserCode
())
.
toString
();
.
append
(
"id"
,
getId
())
.
append
(
"inventoryType"
,
getInventoryType
())
.
append
(
"orderId"
,
getOrderId
())
.
append
(
"orderName"
,
getOrderName
())
.
append
(
"materialId"
,
getMaterialId
())
.
append
(
"materialName"
,
getMaterialName
())
.
append
(
"batchId"
,
getBatchId
())
.
append
(
"warehousesId"
,
getWarehousesId
())
.
append
(
"warehousesName"
,
getWarehousesName
())
.
append
(
"warehousesCode"
,
getWarehousesCode
())
.
append
(
"locationId"
,
getLocationId
())
.
append
(
"locationName"
,
getLocationName
())
.
append
(
"ownerId"
,
getOwnerId
())
.
append
(
"ownerName"
,
getOwnerName
())
.
append
(
"quantity"
,
getQuantity
())
.
append
(
"lockedQuantity"
,
getLockedQuantity
())
.
append
(
"unitWeight"
,
getUnitWeight
())
.
append
(
"totalWeight"
,
getTotalWeight
())
.
append
(
"totalVolume"
,
getTotalVolume
())
.
append
(
"productionDate"
,
getProductionDate
())
.
append
(
"expirationDate"
,
getExpirationDate
())
.
append
(
"inventoryStatus"
,
getInventoryStatus
())
.
append
(
"lastInboundTime"
,
getLastInboundTime
())
.
append
(
"lastOutboundTime"
,
getLastOutboundTime
())
.
append
(
"isUsed"
,
getIsUsed
())
.
append
(
"sortNo"
,
getSortNo
())
.
append
(
"createTime"
,
getCreateTime
())
.
append
(
"createUserCode"
,
getCreateUserCode
())
.
append
(
"updateTime"
,
getUpdateTime
())
.
append
(
"updateUserCode"
,
getUpdateUserCode
())
.
append
(
"alertType"
,
getAlertType
())
.
toString
();
}
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/OutboundOrders.java
View file @
19bd4ddb
...
...
@@ -3,6 +3,7 @@ package com.ruoyi.inventory.domain;
import
java.util.List
;
import
java.util.Date
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
lombok.Data
;
import
org.apache.commons.lang3.builder.ToStringBuilder
;
import
org.apache.commons.lang3.builder.ToStringStyle
;
import
com.ruoyi.common.annotation.Excel
;
...
...
@@ -14,6 +15,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
* @author ruoyi
* @date 2025-12-03
*/
@Data
public
class
OutboundOrders
extends
BaseEntity
{
private
static
final
long
serialVersionUID
=
1L
;
...
...
@@ -57,6 +59,8 @@ public class OutboundOrders extends BaseEntity
@Excel
(
name
=
"出库单状态1-草稿 2-已完成 3-已取消 字典,检索条件"
)
private
Long
orderStatus
;
/** 出库日期 日期无时间 */
@JsonFormat
(
pattern
=
"yyyy-MM-dd"
)
@Excel
(
name
=
"出库日期 日期无时间"
,
width
=
30
,
dateFormat
=
"yyyy-MM-dd"
)
...
...
@@ -86,6 +90,8 @@ public class OutboundOrders extends BaseEntity
@Excel
(
name
=
"排序"
)
private
Long
sortNo
;
private
Long
orderType
;
/** 创建日期 */
@Excel
(
name
=
"创建日期"
)
private
String
createUserCode
;
...
...
@@ -97,230 +103,4 @@ public class OutboundOrders extends BaseEntity
/** 出库单明细信息 */
private
List
<
OutboundOrderItems
>
outboundOrderItemsList
;
public
void
setId
(
String
id
)
{
this
.
id
=
id
;
}
public
String
getId
()
{
return
id
;
}
public
void
setOrderId
(
String
orderId
)
{
this
.
orderId
=
orderId
;
}
public
String
getOrderId
()
{
return
orderId
;
}
public
void
setSystemNo
(
String
systemNo
)
{
this
.
systemNo
=
systemNo
;
}
public
String
getSystemNo
()
{
return
systemNo
;
}
public
void
setOrderTypeId
(
String
orderTypeId
)
{
this
.
orderTypeId
=
orderTypeId
;
}
public
String
getOrderTypeId
()
{
return
orderTypeId
;
}
public
void
setBatchCode
(
String
batchCode
)
{
this
.
batchCode
=
batchCode
;
}
public
String
getBatchCode
()
{
return
batchCode
;
}
public
void
setWarehouseId
(
String
warehouseId
)
{
this
.
warehouseId
=
warehouseId
;
}
public
String
getWarehouseId
()
{
return
warehouseId
;
}
public
void
setOwnerId
(
String
ownerId
)
{
this
.
ownerId
=
ownerId
;
}
public
String
getOwnerId
()
{
return
ownerId
;
}
public
void
setOrderStatus
(
Long
orderStatus
)
{
this
.
orderStatus
=
orderStatus
;
}
public
Long
getOrderStatus
()
{
return
orderStatus
;
}
public
void
setInboundDate
(
Date
inboundDate
)
{
this
.
inboundDate
=
inboundDate
;
}
public
Date
getInboundDate
()
{
return
inboundDate
;
}
public
void
setDestination
(
String
destination
)
{
this
.
destination
=
destination
;
}
public
String
getDestination
()
{
return
destination
;
}
public
void
setTotalPlannedQuantity
(
Long
totalPlannedQuantity
)
{
this
.
totalPlannedQuantity
=
totalPlannedQuantity
;
}
public
Long
getTotalPlannedQuantity
()
{
return
totalPlannedQuantity
;
}
public
void
setTotalActualQuantity
(
Long
totalActualQuantity
)
{
this
.
totalActualQuantity
=
totalActualQuantity
;
}
public
Long
getTotalActualQuantity
()
{
return
totalActualQuantity
;
}
public
void
setTotalPackages
(
Long
totalPackages
)
{
this
.
totalPackages
=
totalPackages
;
}
public
Long
getTotalPackages
()
{
return
totalPackages
;
}
public
void
setIsUsed
(
Long
isUsed
)
{
this
.
isUsed
=
isUsed
;
}
public
Long
getIsUsed
()
{
return
isUsed
;
}
public
void
setSortNo
(
Long
sortNo
)
{
this
.
sortNo
=
sortNo
;
}
public
Long
getSortNo
()
{
return
sortNo
;
}
public
void
setCreateUserCode
(
String
createUserCode
)
{
this
.
createUserCode
=
createUserCode
;
}
public
String
getCreateUserCode
()
{
return
createUserCode
;
}
public
void
setUpdateUserCode
(
String
updateUserCode
)
{
this
.
updateUserCode
=
updateUserCode
;
}
public
String
getUpdateUserCode
()
{
return
updateUserCode
;
}
public
List
<
OutboundOrderItems
>
getOutboundOrderItemsList
()
{
return
outboundOrderItemsList
;
}
public
void
setOutboundOrderItemsList
(
List
<
OutboundOrderItems
>
outboundOrderItemsList
)
{
this
.
outboundOrderItemsList
=
outboundOrderItemsList
;
}
// 补充 warehouseName 的 getter/setter 方法
public
String
getWarehouseName
()
{
return
warehouseName
;
}
public
void
setWarehouseName
(
String
warehouseName
)
{
this
.
warehouseName
=
warehouseName
;
}
// 补充 ownerName 的 getter/setter 方法
public
String
getOwnerName
()
{
return
ownerName
;
}
public
void
setOwnerName
(
String
ownerName
)
{
this
.
ownerName
=
ownerName
;
}
@Override
public
String
toString
()
{
return
new
ToStringBuilder
(
this
,
ToStringStyle
.
MULTI_LINE_STYLE
)
.
append
(
"id"
,
getId
())
.
append
(
"orderId"
,
getOrderId
())
.
append
(
"systemNo"
,
getSystemNo
())
.
append
(
"orderTypeId"
,
getOrderTypeId
())
.
append
(
"batchCode"
,
getBatchCode
())
.
append
(
"warehouseId"
,
getWarehouseId
())
.
append
(
"warehouseName"
,
getWarehouseName
())
// 新增
.
append
(
"ownerId"
,
getOwnerId
())
.
append
(
"ownerName"
,
getOwnerName
())
// 新增
.
append
(
"orderStatus"
,
getOrderStatus
())
.
append
(
"inboundDate"
,
getInboundDate
())
.
append
(
"destination"
,
getDestination
())
.
append
(
"totalPlannedQuantity"
,
getTotalPlannedQuantity
())
.
append
(
"totalActualQuantity"
,
getTotalActualQuantity
())
.
append
(
"totalPackages"
,
getTotalPackages
())
.
append
(
"remark"
,
getRemark
())
.
append
(
"isUsed"
,
getIsUsed
())
.
append
(
"sortNo"
,
getSortNo
())
.
append
(
"createTime"
,
getCreateTime
())
.
append
(
"createUserCode"
,
getCreateUserCode
())
.
append
(
"updateTime"
,
getUpdateTime
())
.
append
(
"updateUserCode"
,
getUpdateUserCode
())
.
append
(
"outboundOrderItemsList"
,
getOutboundOrderItemsList
())
.
toString
();
}
}
\ No newline at end of file
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/Owners.java
View file @
19bd4ddb
...
...
@@ -28,8 +28,11 @@ public class Owners extends BaseEntity
@Excel
(
name
=
"货主名称"
)
private
String
ownerName
;
@Excel
(
name
=
"货主名称"
)
private
String
englishName
;
/** 货主类型 1-供应商 2-客户 3-内部 检索条件 */
@Excel
(
name
=
"货主类型"
,
dictType
=
"owner_type"
)
@Excel
(
name
=
"货主类型"
)
private
Long
ownerType
;
/** 联系人 */
...
...
@@ -123,7 +126,15 @@ public class Owners extends BaseEntity
return
contactPerson
;
}
public
void
setContactPhone
(
String
contactPhone
)
public
String
getEnglishName
()
{
return
englishName
;
}
public
void
setEnglishName
(
String
englishName
)
{
this
.
englishName
=
englishName
;
}
public
void
setContactPhone
(
String
contactPhone
)
{
this
.
contactPhone
=
contactPhone
;
}
...
...
@@ -237,6 +248,7 @@ public class Owners extends BaseEntity
.
append
(
"taxNumber"
,
getTaxNumber
())
.
append
(
"bankAccount"
,
getBankAccount
())
.
append
(
"isActive"
,
getIsActive
())
.
append
(
"english_name"
,
getEnglishName
())
.
append
(
"sortNo"
,
getSortNo
())
.
append
(
"createTime"
,
getCreateTime
())
.
append
(
"createUserCode"
,
getCreateUserCode
())
...
...
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/StorageLocations.java
View file @
19bd4ddb
...
...
@@ -26,6 +26,44 @@ public class StorageLocations extends BaseEntity
@Excel
(
name
=
"库位编码 检索条件"
)
private
String
locationCode
;
/**
* 上架顺序(数字越小优先级越高)
*/
private
String
putawayOrder
;
/**
* 拣货顺序(数字越小优先级越高)
*/
private
String
pickingOrder
;
/**
* 库位使用(
*/
private
Integer
LocationUsage
;
/**
* 库位处理状态(如:正常/冻结/锁定/禁用)
*/
private
String
locationHandling
;
/**
* 周转需求(如:高周转/中周转/低周转)
*/
private
String
turnoverDemand
;
/**
* 所属拣货区域(编码/名称)
*/
private
String
pickingArea
;
/**
* 是否允许混放产品(true=允许,false=不允许)
*/
private
String
allowMixedProducts
;
/**
* 是否允许混放批次(true=允许,false=不允许)
*/
private
String
allowMixedBatches
;
/** 库位名称 检索条件 */
@Excel
(
name
=
"库位名称 检索条件"
)
private
String
locationName
;
...
...
@@ -77,7 +115,7 @@ public class StorageLocations extends BaseEntity
@Excel
(
name
=
"温区"
)
private
String
temperatureZone
;
/**
应用状态1使用0未使用
*/
/**
库位属性
*/
@Excel
(
name
=
"应用状态1使用0未使用"
)
private
Long
isEnabled
;
...
...
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/vo/OutboundTemplateVO.java
View file @
19bd4ddb
...
...
@@ -10,120 +10,122 @@ import java.util.Date;
/**
* 出库单明细对象 outbound_order_items
*
*
* @author ruoyi
* @date 2025-12-03
*/
public
class
OutboundTemplateVO
extends
BaseEntity
{
public
class
OutboundTemplateVO
extends
BaseEntity
{
private
static
final
long
serialVersionUID
=
1L
;
/** 编号 */
private
String
id
;
/** 入库单号 检索条件 */
@Excel
(
name
=
"入库单号"
)
private
String
orderId
;
/** 系统编号 检索条件 */
@Excel
(
name
=
"系统编号"
)
private
String
systemNo
;
/** 入库类型 字典,检索条件 */
@Excel
(
name
=
"入库类型"
)
private
String
orderTypeId
;
/** 批次ID 检索条件 */
@Excel
(
name
=
"批次ID"
)
private
String
batchId
;
/** 入库日期 日期无时间 */
/** 日期(入库日期) */
@JsonFormat
(
pattern
=
"yyyy-MM-dd"
)
@Excel
(
name
=
"
入库
日期"
,
width
=
30
,
dateFormat
=
"yyyy-MM-dd"
)
@Excel
(
name
=
"日期"
,
width
=
30
,
dateFormat
=
"yyyy-MM-dd"
)
private
Date
inboundDate
;
/** 订单类型 字典,检索条件 */
@Excel
(
name
=
"订单类型"
)
private
String
orderType
;
/** 备注 */
@Excel
(
name
=
"备注"
)
private
String
remark
;
/** 货主ID */
@Excel
(
name
=
"货主ID"
)
private
String
ownerId
;
/** 仓库ID 暂无用 */
@Excel
(
name
=
"仓库ID"
)
private
String
warehouseId
;
/** 库位ID 检索条件 */
@Excel
(
name
=
"库位ID"
)
private
String
locationId
;
/** 货物ID 字典,检索条件 */
@Excel
(
name
=
"SAP号"
)
/** SAP号 */
@Excel
(
name
=
"SAP No"
)
private
String
sapNo
;
/** 货物ID 字典,检索条件 */
@Excel
(
name
=
"货物名称"
)
/** 物料ID */
private
String
materialId
;
/** 货物名称 */
@Excel
(
name
=
"物料名称"
)
private
String
materialName
;
/** 负责人 暂无用 */
// @Excel(name = "负责人 暂无用")
private
String
opUserName
;
/** TS Code */
@Excel
(
name
=
"TS Code"
)
private
String
tsCode
;
/** 批号 */
@Excel
(
name
=
" 批号"
)
private
String
batchCode
;
/** 计划数量 */
@Excel
(
name
=
"计划数量"
)
private
Long
plannedQuantity
;
/** 实际数量 */
@Excel
(
name
=
"实际数量"
)
/** 件重 */
@Excel
(
name
=
"件重"
)
private
Long
pieceWeight
;
/** 件数(实际件数) */
@Excel
(
name
=
"件数"
)
private
Long
actualPackages
;
/** 实发数量(实际数量) */
@Excel
(
name
=
"实发数量"
)
private
Long
actualQuantity
;
/**
计划件数 暂无用
*/
// @Excel(name = "计划件数
")
private
Long
plannedPackages
;
/**
库位名称
*/
@Excel
(
name
=
"库位
"
)
private
String
locationName
;
/** 实际件数 */
@Excel
(
name
=
"实际件数"
)
private
Long
actualPackages
;
/** 库位ID */
private
String
locationId
;
/** 约数 */
@Excel
(
name
=
"约数"
)
private
Long
divisor
;
/** 仓库ID */
private
String
warehouseId
;
/** 仓库名称 */
@Excel
(
name
=
"仓库"
)
private
String
warehouseName
;
/** 标签颜色 字典,检索条件 */
@Excel
(
name
=
"标签颜色"
)
/** 备注 */
@Excel
(
name
=
"备注"
)
private
String
remark
;
/** 标签颜色 */
@Excel
(
name
=
"标签颜色"
,
dictType
=
"label_color"
)
private
Long
labelColor
;
/** 凭证号
检索条件
*/
/** 凭证号 */
@Excel
(
name
=
"凭证号"
)
private
String
voucherNumber
;
/** 单价 */
@Excel
(
name
=
"单价"
)
private
Long
unitPrice
;
/** 保温状态/类型 */
@Excel
(
name
=
"保温"
)
private
String
insulation
;
/** 危检类别(危险类别) */
@Excel
(
name
=
"危险类别"
)
private
String
dangerCheckType
;
/** 单号 */
@Excel
(
name
=
"单号"
)
private
String
orderId
;
/** 系统编号(系统单号) */
@Excel
(
name
=
"系统单号"
)
private
String
systemNo
;
/**
收货人
*/
@Excel
(
name
=
"
收货人
"
)
private
String
receivedBy
;
/**
订单类型
*/
@Excel
(
name
=
"
订单类型
"
)
private
String
orderType
;
/** 物料备注 */
@Excel
(
name
=
"物料备注"
)
private
String
remark2
;
/** 货主ID */
private
String
ownerId
;
/** 排序号 */
private
Long
sortNo
;
/** 货主名称 */
@Excel
(
name
=
"货主"
)
private
String
ownerName
;
/** 创建日期 */
private
String
createUserCode
;
/** 目的地 */
@Excel
(
name
=
"目的地"
)
private
String
destination
;
/** 预留 */
@Excel
(
name
=
"预留"
)
private
String
reservation
;
private
String
updateUserCode
;
/** 单个件重值(单件重量) */
@Excel
(
name
=
"单件重量"
)
private
Long
singlePieceWeight
;
// ===================== Getter & Setter 完整实现 =====================
public
String
getId
()
{
return
id
;
}
...
...
@@ -132,241 +134,257 @@ public class OutboundTemplateVO extends BaseEntity
this
.
id
=
id
;
}
public
String
getOrderId
()
{
return
orderId
;
public
Date
getInboundDate
()
{
return
inboundDate
;
}
public
void
set
OrderId
(
String
orderId
)
{
this
.
orderId
=
orderId
;
public
void
set
InboundDate
(
Date
inboundDate
)
{
this
.
inboundDate
=
inboundDate
;
}
public
String
getS
ystem
No
()
{
return
s
ystem
No
;
public
String
getS
ap
No
()
{
return
s
ap
No
;
}
public
void
setS
ystemNo
(
String
system
No
)
{
this
.
s
ystemNo
=
system
No
;
public
void
setS
apNo
(
String
sap
No
)
{
this
.
s
apNo
=
sap
No
;
}
public
String
getOrderTypeId
(
)
{
return
orderTypeId
;
public
void
setTsCode
(
String
tsCode
)
{
this
.
tsCode
=
tsCode
;
}
public
void
setOrderTypeId
(
String
orderTypeId
)
{
this
.
orderTypeId
=
orderTypeId
;
public
String
getBatchCode
(
)
{
return
batchCode
;
}
public
String
getBatchId
(
)
{
return
batchId
;
public
void
setBatchCode
(
String
batchCode
)
{
this
.
batchCode
=
batchCode
;
}
public
void
setBatchId
(
String
batchId
)
{
this
.
batchId
=
batch
Id
;
public
String
getMaterialId
(
)
{
return
material
Id
;
}
public
Date
getInboundDate
(
)
{
return
inboundDate
;
public
void
setMaterialId
(
String
materialId
)
{
this
.
materialId
=
materialId
;
}
public
void
setInboundDate
(
Date
inboundDate
)
{
this
.
inboundDate
=
inboundDat
e
;
public
String
getMaterialName
(
)
{
return
materialNam
e
;
}
public
String
getOrderType
(
)
{
return
orderTyp
e
;
public
void
setMaterialName
(
String
materialName
)
{
this
.
materialName
=
materialNam
e
;
}
public
void
setOrderType
(
String
orderType
)
{
this
.
orderType
=
orderTyp
e
;
public
String
getTsCode
(
)
{
return
tsCod
e
;
}
public
String
getRemark
(
)
{
return
remark
;
public
void
setTsCo
(
String
tsCode
)
{
this
.
tsCode
=
tsCode
;
}
public
void
setRemark
(
String
remark
)
{
this
.
remark
=
remark
;
public
Long
getPlannedQuantity
()
{
return
plannedQuantity
;
}
public
String
getOwnerId
(
)
{
return
ownerId
;
public
void
setPlannedQuantity
(
Long
plannedQuantity
)
{
this
.
plannedQuantity
=
plannedQuantity
;
}
public
void
setOwnerId
(
String
ownerId
)
{
this
.
ownerId
=
ownerId
;
public
Long
getPieceWeight
(
)
{
return
pieceWeight
;
}
public
String
getWarehouseId
(
)
{
return
warehouseId
;
public
void
setPieceWeight
(
Long
pieceWeight
)
{
this
.
pieceWeight
=
pieceWeight
;
}
public
void
setWarehouseId
(
String
warehouseId
)
{
this
.
warehouseId
=
warehouseId
;
public
Long
getActualPackages
(
)
{
return
actualPackages
;
}
public
String
getLocationId
(
)
{
return
locationId
;
public
void
setActualPackages
(
Long
actualPackages
)
{
this
.
actualPackages
=
actualPackages
;
}
public
void
setLocationId
(
String
locationId
)
{
this
.
locationId
=
locationId
;
public
Long
getActualQuantity
(
)
{
return
actualQuantity
;
}
public
String
getRemark2
(
)
{
return
remark2
;
public
void
setActualQuantity
(
Long
actualQuantity
)
{
this
.
actualQuantity
=
actualQuantity
;
}
public
void
setRemark2
(
String
remark2
)
{
this
.
remark2
=
remark2
;
public
String
getLocationName
(
)
{
return
locationName
;
}
public
String
getSapNo
(
)
{
return
sapNo
;
public
void
setLocationName
(
String
locationName
)
{
this
.
locationName
=
locationName
;
}
public
void
setSapNo
(
String
sapNo
)
{
this
.
sapNo
=
sapNo
;
public
String
getLocationId
(
)
{
return
locationId
;
}
public
String
getMaterialName
(
)
{
return
materialName
;
public
void
setLocationId
(
String
locationId
)
{
this
.
locationId
=
locationId
;
}
public
void
setMaterialName
(
String
materialName
)
{
this
.
materialName
=
materialName
;
public
String
getWarehouseId
(
)
{
return
warehouseId
;
}
public
String
getOpUserName
(
)
{
return
opUserName
;
public
void
setWarehouseId
(
String
warehouseId
)
{
this
.
warehouseId
=
warehouseId
;
}
public
void
setOpUserName
(
String
opUserName
)
{
this
.
opUserName
=
opUser
Name
;
public
String
getWarehouseName
(
)
{
return
warehouse
Name
;
}
public
Long
getPlannedQuantity
(
)
{
return
plannedQuantity
;
public
void
setWarehouseName
(
String
warehouseName
)
{
this
.
warehouseName
=
warehouseName
;
}
public
void
setPlannedQuantity
(
Long
plannedQuantity
)
{
this
.
plannedQuantity
=
plannedQuantity
;
public
String
getRemark
(
)
{
return
remark
;
}
public
Long
getActualQuantity
(
)
{
return
actualQuantity
;
public
void
setRemark
(
String
remark
)
{
this
.
remark
=
remark
;
}
public
void
setActualQuantity
(
Long
actualQuantity
)
{
this
.
actualQuantity
=
actualQuantity
;
public
Long
getLabelColor
(
)
{
return
labelColor
;
}
public
Long
getPlannedPackages
(
)
{
return
plannedPackages
;
public
void
setLabelColor
(
Long
labelColor
)
{
this
.
labelColor
=
labelColor
;
}
public
void
setPlannedPackages
(
Long
plannedPackages
)
{
this
.
plannedPackages
=
plannedPackages
;
public
String
getVoucherNumber
(
)
{
return
voucherNumber
;
}
public
Long
getActualPackages
(
)
{
return
actualPackages
;
public
void
setVoucherNumber
(
String
voucherNumber
)
{
this
.
voucherNumber
=
voucherNumber
;
}
public
void
setActualPackages
(
Long
actualPackages
)
{
this
.
actualPackages
=
actualPackages
;
public
String
getInsulation
(
)
{
return
insulation
;
}
public
Long
getDivisor
(
)
{
return
divisor
;
public
void
setInsulation
(
String
insulation
)
{
this
.
insulation
=
insulation
;
}
public
void
setDivisor
(
Long
divisor
)
{
this
.
divisor
=
divisor
;
public
String
getDangerCheckType
(
)
{
return
dangerCheckType
;
}
public
Long
getLabelColor
(
)
{
return
labelColor
;
public
void
setDangerCheckType
(
String
dangerCheckType
)
{
this
.
dangerCheckType
=
dangerCheckType
;
}
public
void
setLabelColor
(
Long
labelColor
)
{
this
.
labelColor
=
labelColor
;
public
String
getOrderId
(
)
{
return
orderId
;
}
public
String
getVoucherNumber
(
)
{
return
voucherNumber
;
public
void
setOrderId
(
String
orderId
)
{
this
.
orderId
=
orderId
;
}
public
void
setVoucherNumber
(
String
voucherNumber
)
{
this
.
voucherNumber
=
voucherNumber
;
public
String
getSystemNo
(
)
{
return
systemNo
;
}
public
Long
getUnitPrice
()
{
return
unitPrice
;
public
void
setSystemNo
(
String
systemNo
)
{
this
.
systemNo
=
systemNo
;
}
public
String
getOrderType
()
{
return
orderType
;
}
public
void
setUnitPrice
(
Long
unitPrice
)
{
this
.
unitPrice
=
unitPrice
;
public
void
setOrderType
(
String
orderType
)
{
this
.
orderType
=
orderType
;
}
public
String
getOwnerId
()
{
return
ownerId
;
}
public
void
setOwnerId
(
String
ownerId
)
{
this
.
ownerId
=
ownerId
;
}
public
String
get
ReceivedBy
()
{
return
receivedBy
;
public
String
get
OwnerName
()
{
return
ownerName
;
}
public
void
set
ReceivedBy
(
String
receivedBy
)
{
this
.
receivedBy
=
receivedBy
;
public
void
set
OwnerName
(
String
ownerName
)
{
this
.
ownerName
=
ownerName
;
}
public
String
get
CreateUserCode
()
{
return
createUserCode
;
public
String
get
Destination
()
{
return
destination
;
}
public
void
set
CreateUserCode
(
String
createUserCode
)
{
this
.
createUserCode
=
createUserCode
;
public
void
set
Destination
(
String
destination
)
{
this
.
destination
=
destination
;
}
public
String
get
UpdateUserCode
()
{
return
updateUserCode
;
public
String
get
Reservation
()
{
return
reservation
;
}
public
void
set
UpdateUserCode
(
String
updateUserCode
)
{
this
.
updateUserCode
=
updateUserCode
;
public
void
set
Reservation
(
String
reservation
)
{
this
.
reservation
=
reservation
;
}
public
Long
getS
ortNo
()
{
return
s
ortNo
;
public
Long
getS
inglePieceWeight
()
{
return
s
inglePieceWeight
;
}
public
void
setS
ortNo
(
Long
sortNo
)
{
this
.
s
ortNo
=
sortNo
;
public
void
setS
inglePieceWeight
(
Long
singlePieceWeight
)
{
this
.
s
inglePieceWeight
=
singlePieceWeight
;
}
@Override
public
String
toString
()
{
return
"InboundTemplateVO{"
+
"id='"
+
id
+
'\''
+
", orderId='"
+
orderId
+
'\''
+
", systemNo='"
+
systemNo
+
'\''
+
", orderTypeId='"
+
orderTypeId
+
'\''
+
", batchId='"
+
batchId
+
'\''
+
", inboundDate="
+
inboundDate
+
", orderType='"
+
orderType
+
'\''
+
", remark1='"
+
remark
+
'\''
+
", ownerId='"
+
ownerId
+
'\''
+
", warehouseId='"
+
warehouseId
+
'\''
+
", locationId='"
+
locationId
+
'\''
+
", sapNo='"
+
sapNo
+
'\''
+
", materialName='"
+
materialName
+
'\''
+
", opUserName='"
+
opUserName
+
'\''
+
", plannedQuantity="
+
plannedQuantity
+
", actualQuantity="
+
actualQuantity
+
", plannedPackages="
+
plannedPackages
+
", actualPackages="
+
actualPackages
+
", divisor="
+
divisor
+
", labelColor="
+
labelColor
+
", voucherNumber='"
+
voucherNumber
+
'\''
+
", unitPrice="
+
unitPrice
+
", receivedBy='"
+
receivedBy
+
'\''
+
", remark2='"
+
remark2
+
'\''
+
'}'
;
}
}
return
new
ToStringBuilder
(
this
,
ToStringStyle
.
MULTI_LINE_STYLE
)
.
append
(
"id"
,
id
)
.
append
(
"inboundDate"
,
inboundDate
)
.
append
(
"sapNo"
,
sapNo
)
.
append
(
"materialId"
,
materialId
)
.
append
(
"materialName"
,
materialName
)
.
append
(
"tsCode"
,
tsCode
)
.
append
(
"plannedQuantity"
,
plannedQuantity
)
.
append
(
"pieceWeight"
,
pieceWeight
)
.
append
(
"actualPackages"
,
actualPackages
)
.
append
(
"actualQuantity"
,
actualQuantity
)
.
append
(
"locationName"
,
locationName
)
.
append
(
"locationId"
,
locationId
)
.
append
(
"warehouseId"
,
warehouseId
)
.
append
(
"warehouseName"
,
warehouseName
)
.
append
(
"remark"
,
remark
)
.
append
(
"labelColor"
,
labelColor
)
.
append
(
"voucherNumber"
,
voucherNumber
)
.
append
(
"insulation"
,
insulation
)
.
append
(
"dangerCheckType"
,
dangerCheckType
)
.
append
(
"orderId"
,
orderId
)
.
append
(
"systemNo"
,
systemNo
)
.
append
(
"orderType"
,
orderType
)
.
append
(
"ownerId"
,
ownerId
)
.
append
(
"ownerName"
,
ownerName
)
.
append
(
"destination"
,
destination
)
.
append
(
"reservation"
,
reservation
)
.
append
(
"singlePieceWeight"
,
singlePieceWeight
)
.
toString
();
}
}
\ No newline at end of file
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/vo/OwnerTemplateVO.java
0 → 100644
View file @
19bd4ddb
package
com
.
ruoyi
.
inventory
.
domain
.
vo
;
import
com.ruoyi.common.annotation.Excel
;
import
lombok.Data
;
/**
* 客户信息实体类
*
* @author 豆包编程助手
* @date 2025-12-11
*/
@Data
public
class
OwnerTemplateVO
{
/**
* 客户编码/客户名称(根据业务场景调整,若为编码建议命名为 customerCode)
*/
@Excel
(
name
=
"客户"
)
private
String
ownerCode
;
/**
* 激活状态(如:是/否、已激活/未激活,建议用布尔值或枚举)
*/
@Excel
(
name
=
"激活"
,
dictType
=
"yorn"
)
private
String
isActive
;
/**
* 客户类型(如:个人/企业、经销商/终端客户等)
*/
@Excel
(
name
=
"类型"
,
dictType
=
"owner_type"
)
private
String
ownerType
;
/**
* 客户中文名称
*/
@Excel
(
name
=
"中文名称"
)
private
String
ownerName
;
/**
* 客户英文名称
*/
@Excel
(
name
=
"英文名称"
)
private
String
englishName
;
/**
* 地址1(主地址)
*/
@Excel
(
name
=
"地址1"
)
private
String
address
;
/**
* 联系人1(主要联系人)
*/
@Excel
(
name
=
"电话1"
)
private
String
contactPerson
;
/**
* 电话1(主要联系电话)
*/
@Excel
(
name
=
"联系人1"
)
private
String
contactPhone
;
}
\ No newline at end of file
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/vo/StorageLocationsLocationTemplateVO.java
0 → 100644
View file @
19bd4ddb
package
com
.
ruoyi
.
inventory
.
domain
.
vo
;
import
com.ruoyi.common.annotation.Excel
;
import
com.ruoyi.common.annotation.Log
;
import
lombok.Data
;
/**
* 库位信息实体类
*
* @author 豆包编程助手
* @date 2025-12-11
*/
@Data
public
class
StorageLocationsLocationTemplateVO
{
@Excel
(
name
=
"库位编码"
)
private
String
locationCode
;
@Excel
(
name
=
"上架顺序"
)
private
String
putawayOrder
;
@Excel
(
name
=
"拣货顺序"
)
private
String
pickingOrder
;
@Excel
(
name
=
"库位使用"
,
dictType
=
"location_usage"
)
private
String
LocationUsage
;
@Excel
(
name
=
"库位类型"
,
dictType
=
"location_type"
)
private
String
locationType
;
@Excel
(
name
=
"库位属性"
,
dictType
=
"is_enabled"
)
private
String
isEnabled
;
@Excel
(
name
=
"库位处理"
)
private
String
locationHandling
;
@Excel
(
name
=
"周转需求"
)
private
String
turnoverDemand
;
@Excel
(
name
=
"上架区"
)
private
String
zoneCode
;
@Excel
(
name
=
"拣货区"
)
private
String
pickingArea
;
@Excel
(
name
=
"允许混放产品"
,
dictType
=
"yorn"
)
private
String
allowMixedProducts
;
@Excel
(
name
=
"允许混放批次"
)
private
String
allowMixedBatches
;
}
\ No newline at end of file
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/OutboundOrderItemsMapper.java
View file @
19bd4ddb
...
...
@@ -70,7 +70,7 @@ public interface OutboundOrderItemsMapper
public
int
deleteOutboundOrderItemsById
(
String
[]
ids
);
public
int
batchInsertOutboundOrderItems
(
List
<
In
boundOrderItems
>
inboundOrderItems
);
public
int
batchInsertOutboundOrderItems
(
List
<
Out
boundOrderItems
>
inboundOrderItems
);
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/OutboundOrderLogMapper.java
View file @
19bd4ddb
...
...
@@ -2,6 +2,7 @@ package com.ruoyi.inventory.mapper;
import
java.util.List
;
import
com.ruoyi.common.annotation.SerialExecution
;
import
com.ruoyi.inventory.domain.OutboundOrderItems
;
import
com.ruoyi.inventory.domain.OutboundOrderLog
;
...
...
@@ -96,6 +97,7 @@ public interface OutboundOrderLogMapper
* @param outboundOrderItemsList 出库单明细列表
* @return 结果
*/
public
int
batchOutboundOrderLog
(
List
<
OutboundOrderLog
>
outboundOrderLogs
);
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/OwnersMapper.java
View file @
19bd4ddb
...
...
@@ -61,5 +61,6 @@ public interface OwnersMapper
*/
public
int
deleteOwnersByIds
(
String
[]
ids
);
public
int
batchInsertOwners
(
List
<
Owners
>
list
);
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/StorageLocationsMapper.java
View file @
19bd4ddb
...
...
@@ -97,4 +97,7 @@ public interface StorageLocationsMapper
* @return 库位集合
*/
List
<
StorageLocations
>
getStorageLocationsList
(
StorageLocations
storageLocations
);
int
batchInsertStorageLocations
(
List
<
StorageLocations
>
storageLocations
);
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IOutboundOrderItemsService.java
View file @
19bd4ddb
...
...
@@ -70,6 +70,4 @@ public interface IOutboundOrderItemsService
public
int
deleteOutboundOrderItemsById
(
String
id
);
@Transactional
(
rollbackFor
=
Exception
.
class
)
String
importOutoundOrders
(
List
<
OutboundTemplateVO
>
inboundOrdersList
,
Boolean
isUpdateSupport
,
String
operName
);
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IOutboundOrdersService.java
View file @
19bd4ddb
...
...
@@ -4,6 +4,8 @@ import java.util.List;
import
java.util.Map
;
import
com.ruoyi.inventory.domain.OutboundOrders
;
import
com.ruoyi.inventory.domain.vo.OutboundTemplateVO
;
import
org.springframework.transaction.annotation.Transactional
;
/**
* 出库单主Service接口
...
...
@@ -74,4 +76,7 @@ public interface IOutboundOrdersService
public
List
<
Map
<
String
,
String
>>
outboundOrdersTopTenByAmount
();
public
String
outboundOrdersCount
();
@Transactional
(
rollbackFor
=
Exception
.
class
)
String
importOutboundOrders
(
List
<
OutboundTemplateVO
>
inboundOrdersList
,
Boolean
isUpdateSupport
,
String
operName
);
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IOwnersService.java
View file @
19bd4ddb
...
...
@@ -2,6 +2,7 @@ package com.ruoyi.inventory.service;
import
java.util.List
;
import
com.ruoyi.inventory.domain.Owners
;
import
com.ruoyi.inventory.domain.vo.OwnerTemplateVO
;
/**
* 货主信息Service接口
...
...
@@ -42,7 +43,7 @@ public interface IOwnersService
* @param ownersList 货主信息
* @return 结果
*/
public
String
importOwners
(
List
<
Owner
s
>
ownersList
,
Boolean
isUpdateSupport
,
String
operName
);
public
String
importOwners
(
List
<
Owner
TemplateVO
>
ownersList
,
Boolean
isUpdateSupport
,
String
operName
);
/**
* 修改货主信息
...
...
@@ -67,4 +68,5 @@ public interface IOwnersService
* @return 结果
*/
public
int
deleteOwnersById
(
String
id
);
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IStorageLocationsService.java
View file @
19bd4ddb
...
...
@@ -5,6 +5,9 @@ import java.util.List;
import
java.util.Map
;
import
com.ruoyi.inventory.domain.StorageLocations
;
import
com.ruoyi.inventory.domain.vo.OutboundTemplateVO
;
import
com.ruoyi.inventory.domain.vo.OwnerTemplateVO
;
import
com.ruoyi.inventory.domain.vo.StorageLocationsLocationTemplateVO
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.ResponseBody
;
...
...
@@ -97,4 +100,7 @@ public interface IStorageLocationsService
* @return 库位集合
*/
public
List
<
StorageLocations
>
getStorageLocationsList
(
StorageLocations
storageLocations
);
public
String
importStorageLocationsLocation
(
List
<
StorageLocationsLocationTemplateVO
>
ownersList
,
Boolean
isUpdateSupport
,
String
operName
);
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/InventoryServiceImpl.java
View file @
19bd4ddb
...
...
@@ -4,6 +4,7 @@ import java.util.*;
import
java.util.stream.Collectors
;
import
com.ruoyi.common.annotation.SerialExecution
;
import
com.ruoyi.common.exception.ServiceException
;
import
com.ruoyi.common.utils.DateUtils
;
import
com.ruoyi.inventory.domain.InboundOrderItems
;
import
com.ruoyi.inventory.domain.OutboundOrderItems
;
...
...
@@ -134,21 +135,26 @@ public class InventoryServiceImpl implements IInventoryService
@Override
public
int
ship
(
List
<
OutboundOrderItems
>
outboundOrderItems
)
{
if
(!
outboundOrderItems
.
isEmpty
())
{
List
<
String
>
inventoryIds
=
outboundOrderItems
.
stream
().
map
(
OutboundOrderItems:
:
getInventoryId
).
collect
(
Collectors
.
toList
());
for
(
OutboundOrderItems
outboundOrderItem
:
outboundOrderItems
)
{
OutboundOrderLog
outboundOrderLog
=
outboundOrderLogMapper
.
selectOutboundOrderLogById
(
outboundOrderItem
.
getId
());
Inventory
inventory
=
inventoryMapper
.
selectInventoryById
(
outboundOrderLog
.
getInventoryId
());
inventory
.
setQuantity
(
inventory
.
getQuantity
()-
outboundOrderItem
.
getActualQuantity
());
if
(
inventory
.
getQuantity
()==
0
){
inventory
.
setInventoryStatus
(
0
l
);
}
updateInventory
(
inventory
);
}
RefreshInventory
(
inventoryIds
);
}
return
1
;
if
(!
outboundOrderItems
.
isEmpty
())
{
List
<
String
>
inventoryIds
=
outboundOrderItems
.
stream
().
map
(
OutboundOrderItems:
:
getInventoryId
).
collect
(
Collectors
.
toList
());
for
(
OutboundOrderItems
outboundOrderItem
:
outboundOrderItems
)
{
OutboundOrderLog
outboundOrderLog
=
outboundOrderLogMapper
.
selectOutboundOrderLogById
(
outboundOrderItem
.
getId
());
// ========== 新增空值校验(兜底) ==========
if
(
outboundOrderLog
==
null
)
{
throw
new
ServiceException
(
"明细ID【"
+
outboundOrderItem
.
getId
()
+
"】对应的出库日志不存在"
);
}
// ==========================================
Inventory
inventory
=
inventoryMapper
.
selectInventoryById
(
outboundOrderLog
.
getInventoryId
());
inventory
.
setQuantity
(
inventory
.
getQuantity
()-
outboundOrderItem
.
getActualQuantity
());
if
(
inventory
.
getQuantity
()==
0
){
inventory
.
setInventoryStatus
(
0
l
);
}
updateInventory
(
inventory
);
}
RefreshInventory
(
inventoryIds
);
}
return
1
;
}
@SerialExecution
(
group
=
"inventoryRefresh"
,
fair
=
true
)
...
...
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/OutboundOrderItemsServiceImpl.java
View file @
19bd4ddb
...
...
@@ -109,154 +109,5 @@ public class OutboundOrderItemsServiceImpl implements IOutboundOrderItemsService
return
outboundOrderItemsMapper
.
deleteOutboundOrderItemsById
(
id
);
}
/**
* 导入入库单明细信息
*
* @param inboundOrdersList,isUpdateSupport,operName 入库单数据信息
* @return 结果
*/
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
public
String
importOutoundOrders
(
List
<
OutboundTemplateVO
>
inboundOrdersList
,
Boolean
isUpdateSupport
,
String
operName
)
{
if
(
StringUtils
.
isNull
(
inboundOrdersList
)
||
inboundOrdersList
.
size
()
==
0
)
{
throw
new
ServiceException
(
"导入数据不能为空!"
);
}
// 2. 初始化统计变量
int
totalMainSuccess
=
0
;
// 成功的主表数量
int
totalMainFailure
=
0
;
// 失败的主表数量
int
totalItemSuccess
=
0
;
// 成功的明细数量
int
totalItemFailure
=
0
;
// 失败的明细数量
StringBuilder
successMsg
=
new
StringBuilder
();
StringBuilder
failureMsg
=
new
StringBuilder
();
Date
now
=
DateUtils
.
getNowDate
();
Long
userId
=
SecurityUtils
.
getUserId
();
String
operId
=
userId
.
toString
();
// 3. 按入库单号分组(核心:同一入库单的多条明细归为一组)
Map
<
String
,
List
<
OutboundTemplateVO
>>
orderGroupMap
=
inboundOrdersList
.
stream
()
.
filter
(
vo
->
StringUtils
.
isNotBlank
(
vo
.
getOrderId
()))
// 过滤无入库单号的无效行
.
collect
(
Collectors
.
groupingBy
(
OutboundTemplateVO:
:
getOrderId
));
// 4. 遍历每个入库单分组处理
for
(
Map
.
Entry
<
String
,
List
<
OutboundTemplateVO
>>
entry
:
orderGroupMap
.
entrySet
())
{
String
orderId
=
entry
.
getKey
();
List
<
OutboundTemplateVO
>
voList
=
entry
.
getValue
();
OutboundOrderItems
mainDO
=
null
;
List
<
InboundOrderItems
>
itemDOList
=
new
ArrayList
<>();
try
{
// 4.1 处理主表(每个入库单号只处理一次主表)
OutboundTemplateVO
firstVO
=
voList
.
get
(
0
);
// 取第一条VO的主表信息
// 检查入库单是否已存在
OutboundOrderItems
existMain
=
outboundOrderItemsMapper
.
selectOutboundOrderItemsById
(
orderId
);
if
(
existMain
!=
null
)
{
if
(!
isUpdateSupport
)
{
// 不支持更新,跳过该入库单
totalMainFailure
++;
failureMsg
.
append
(
String
.
format
(
"入库单号【%s】已存在,且不支持更新,跳过导入;\n"
,
orderId
));
totalItemFailure
+=
voList
.
size
();
// 该单的明细全部失败
continue
;
}
// 支持更新,复用已有主表ID
mainDO
=
existMain
;
// 复制VO中的主表字段到已有主表(只更新可修改的字段)
BeanUtils
.
copyProperties
(
firstVO
,
mainDO
,
"id"
,
"createBy"
,
"createTime"
);
// 排除不可更新字段
mainDO
.
setUpdateBy
(
operId
);
mainDO
.
setUpdateTime
(
now
);
mainDO
.
setUpdateUserCode
(
operId
);
// 更新主表
outboundOrderItemsMapper
.
updateOutboundOrderItems
(
mainDO
);
totalMainSuccess
++;
successMsg
.
append
(
String
.
format
(
"入库单号【%s】已更新;\n"
,
orderId
));
}
else
{
// 新增主表
mainDO
=
new
OutboundOrderItems
();
// 复制主表字段(只复制主表相关字段,避免物料字段污染)
BeanUtils
.
copyProperties
(
firstVO
,
mainDO
,
"sapNo"
,
"materialName"
,
"plannedQuantity"
,
"actualQuantity"
,
"plannedPackages"
,
"materialUnit"
,
"materialRemark"
);
// 排除子表字段
// 填充主表必填字段
mainDO
.
setId
(
UUID
.
randomUUID
().
toString
());
mainDO
.
setOrderId
(
orderId
);
mainDO
.
setCreateBy
(
operId
);
mainDO
.
setCreateTime
(
now
);
mainDO
.
setCreateUserCode
(
operId
);
mainDO
.
setUpdateBy
(
operId
);
mainDO
.
setUpdateTime
(
now
);
mainDO
.
setUpdateUserCode
(
operId
);
// 设置默认值
if
(
mainDO
.
getSortNo
()
==
null
)
{
mainDO
.
setSortNo
(
0L
);
}
if
(
mainDO
.
getItemStatus
()
==
null
)
{
mainDO
.
setItemStatus
(
1L
);
// 默认草稿状态
}
// 插入主表
outboundOrderItemsMapper
.
insertOutboundOrderItems
(
mainDO
);
totalMainSuccess
++;
successMsg
.
append
(
String
.
format
(
"入库单号【%s】已新增;\n"
,
orderId
));
}
// 4.2 处理子表明细(每条VO对应一条明细)
for
(
OutboundTemplateVO
vo
:
voList
)
{
InboundOrderItems
itemDO
=
new
InboundOrderItems
();
// 复制子表字段(物料相关)
BeanUtils
.
copyProperties
(
vo
,
itemDO
,
"orderId"
,
"systemNo"
,
"orderTypeId"
,
"batchId"
);
// 排除主表字段
// 填充明细必填字段
itemDO
.
setId
(
UUID
.
randomUUID
().
toString
());
Materials
materials
=
new
Materials
();
materials
.
setSapNo
(
vo
.
getSapNo
());
itemDO
.
setMaterialId
(
vo
.
getSapNo
());
itemDO
.
setOrderId
(
orderId
);
// 关联入库单号
itemDO
.
setBatchId
(
mainDO
.
getBatchCode
());
itemDO
.
setInboundOrderId
(
mainDO
.
getId
());
// 关联主表ID(核心!)
itemDO
.
setCreateBy
(
operId
);
itemDO
.
setCreateTime
(
now
);
itemDO
.
setCreateUserCode
(
operId
);
itemDO
.
setSortNo
(
0L
);
// 校验物料字段(示例:必填sapNo)
if
(
StringUtils
.
isBlank
(
vo
.
getSapNo
()))
{
throw
new
ServiceException
(
String
.
format
(
"入库单号【%s】的物料SAP号为空,明细导入失败"
,
orderId
));
}
System
.
out
.
println
(
itemDO
);
itemDOList
.
add
(
itemDO
);
}
// 4.3 批量插入明细
if
(!
CollectionUtils
.
isEmpty
(
itemDOList
))
{
int
itemSuccess
=
outboundOrderItemsMapper
.
batchInsertOutboundOrderItems
(
itemDOList
);
totalItemSuccess
+=
itemSuccess
;
totalItemFailure
+=
(
itemDOList
.
size
()
-
itemSuccess
);
successMsg
.
append
(
String
.
format
(
"入库单号【%s】成功导入%d条物料明细;\n"
,
orderId
,
itemSuccess
));
if
(
itemDOList
.
size
()
-
itemSuccess
>
0
)
{
failureMsg
.
append
(
String
.
format
(
"入库单号【%s】有%d条物料明细导入失败;\n"
,
orderId
,
itemDOList
.
size
()
-
itemSuccess
));
}
}
}
catch
(
Exception
e
)
{
// 单个入库单处理失败,统计错误
totalMainFailure
++;
totalItemFailure
+=
voList
.
size
();
failureMsg
.
append
(
String
.
format
(
"入库单号【%s】处理失败:%s;\n"
,
orderId
,
e
.
getMessage
()));
}
}
// 5. 结果汇总
if
(
totalMainFailure
>
0
||
totalItemFailure
>
0
)
{
// 有失败数据,抛出异常提示
String
finalFailureMsg
=
String
.
format
(
"导入结果:成功新增/更新%d个入库单,失败%d个;成功导入%d条明细,失败%d条。失败详情:%s"
,
totalMainSuccess
,
totalMainFailure
,
totalItemSuccess
,
totalItemFailure
,
failureMsg
.
toString
()
);
throw
new
ServiceException
(
finalFailureMsg
);
}
else
{
// 全部成功
String
finalSuccessMsg
=
String
.
format
(
"恭喜您,数据已全部导入成功!共处理%d个入库单,成功导入%d条物料明细。详情:%s"
,
totalMainSuccess
,
totalItemSuccess
,
successMsg
.
toString
()
);
return
finalSuccessMsg
;
}
}
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/OutboundOrdersServiceImpl.java
View file @
19bd4ddb
package
com
.
ruoyi
.
inventory
.
service
.
impl
;
import
java.util.List
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
com.ruoyi.common.annotation.SerialExecution
;
import
com.ruoyi.common.core.domain.entity.Materials
;
import
com.ruoyi.common.exception.ServiceException
;
import
com.ruoyi.common.utils.DateUtils
;
import
com.ruoyi.inventory.domain.Inventory
;
import
com.ruoyi.inventory.domain.OutboundOrderLog
;
import
com.ruoyi.common.utils.SecurityUtils
;
import
com.ruoyi.inventory.domain.*
;
import
com.ruoyi.inventory.domain.vo.OutboundTemplateVO
;
import
com.ruoyi.inventory.mapper.InventoryMapper
;
import
com.ruoyi.inventory.mapper.OutboundOrderItemsMapper
;
import
com.ruoyi.inventory.mapper.OutboundOrderLogMapper
;
...
...
@@ -13,16 +17,14 @@ import org.apache.commons.lang3.SystemUtils;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.ArrayList
;
import
java.util.Map
;
import
java.util.UUID
;
import
com.ruoyi.common.utils.StringUtils
;
import
org.springframework.transaction.annotation.Transactional
;
import
com.ruoyi.inventory.domain.OutboundOrderItems
;
import
com.ruoyi.inventory.mapper.OutboundOrdersMapper
;
import
com.ruoyi.inventory.domain.OutboundOrders
;
import
com.ruoyi.inventory.service.IOutboundOrdersService
;
import
org.springframework.transaction.support.TransactionSynchronization
;
import
org.springframework.transaction.support.TransactionSynchronizationManager
;
import
org.springframework.util.CollectionUtils
;
/**
* 出库单主Service业务层处理
...
...
@@ -48,6 +50,10 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
private
WarehousesServiceImpl
warehousesService
;
@Autowired
private
InventoryServiceImpl
inventoryService
;
@Autowired
private
MaterialsServiceImpl
materialsService
;
@Autowired
private
StorageLocationsServiceImpl
storageLocationsService
;
/**
* 查询出库单主
*
...
...
@@ -244,4 +250,312 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
}
}
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
public
String
importOutboundOrders
(
List
<
OutboundTemplateVO
>
inboundOrdersList
,
Boolean
isUpdateSupport
,
String
operName
)
{
// 1. 基础空值校验(完全保留你的代码)
if
(
CollectionUtils
.
isEmpty
(
inboundOrdersList
))
{
throw
new
ServiceException
(
"导入数据不能为空!"
);
}
// 2. 初始化变量(完全保留你的代码)
int
totalMainSuccess
=
0
;
int
totalMainFailure
=
0
;
int
totalItemSuccess
=
0
;
int
totalItemFailure
=
0
;
StringBuilder
successMsg
=
new
StringBuilder
();
StringBuilder
failureMsg
=
new
StringBuilder
();
Date
now
=
DateUtils
.
getNowDate
();
Long
userId
=
SecurityUtils
.
getUserId
();
String
operId
=
userId
!=
null
?
userId
.
toString
()
:
"system"
;
Map
<
String
,
OutboundOrders
>
validMainMap
=
new
HashMap
<>();
Map
<
String
,
List
<
OutboundOrderItems
>>
validItemMap
=
new
HashMap
<>();
boolean
hasValidateError
=
false
;
// 3. 按入库单号分组(完全保留你的代码)
Map
<
String
,
List
<
OutboundTemplateVO
>>
orderGroupMap
=
inboundOrdersList
.
stream
()
.
filter
(
vo
->
StringUtils
.
isNotBlank
(
vo
.
getOrderId
()))
.
collect
(
Collectors
.
groupingBy
(
OutboundTemplateVO:
:
getOrderId
));
// 4. 第一步:仅验证所有数据(完全保留你的代码)
for
(
Map
.
Entry
<
String
,
List
<
OutboundTemplateVO
>>
entry
:
orderGroupMap
.
entrySet
())
{
String
orderId
=
entry
.
getKey
();
List
<
OutboundTemplateVO
>
voList
=
entry
.
getValue
();
OutboundOrders
mainDO
=
null
;
List
<
OutboundOrderItems
>
itemDOList
=
new
ArrayList
<>();
try
{
OutboundTemplateVO
firstVO
=
voList
.
get
(
0
);
OutboundOrders
outboundOrdersQuery
=
new
OutboundOrders
();
outboundOrdersQuery
.
setOrderId
(
orderId
);
List
<
OutboundOrders
>
existMains
=
outboundOrdersMapper
.
selectOutboundOrdersList
(
outboundOrdersQuery
);
if
(
CollectionUtils
.
isEmpty
(
existMains
)
&&
existMains
.
size
()
>
1
)
{
throw
new
ServiceException
(
String
.
format
(
"入库单号【%s】存在多条重复主表数据"
,
orderId
));
}
OutboundOrders
existMain
=
CollectionUtils
.
isEmpty
(
existMains
)
?
null
:
existMains
.
get
(
0
);
if
(
existMain
!=
null
)
{
if
(!
Boolean
.
TRUE
.
equals
(
isUpdateSupport
))
{
throw
new
ServiceException
(
String
.
format
(
"入库单号【%s】已存在,且不支持更新"
,
orderId
));
}
mainDO
=
existMain
;
BeanUtils
.
copyProperties
(
firstVO
,
mainDO
,
"id"
,
"createBy"
,
"createTime"
);
mainDO
.
setUpdateBy
(
operId
);
mainDO
.
setUpdateTime
(
now
);
mainDO
.
setUpdateUserCode
(
operId
);
}
else
{
mainDO
=
new
OutboundOrders
();
com
.
ruoyi
.
common
.
utils
.
bean
.
BeanUtils
.
copyProperties
(
firstVO
,
mainDO
,
"sapNo"
,
"materialName"
,
"plannedQuantity"
,
"actualQuantity"
,
"plannedPackages"
,
"materialUnit"
,
"materialRemark"
);
if
(
StringUtils
.
isNotBlank
(
firstVO
.
getOwnerName
()))
{
Owners
ownerQuery
=
new
Owners
();
ownerQuery
.
setOwnerName
(
firstVO
.
getOwnerName
());
List
<
Owners
>
owners
=
ownersService
.
selectOwnersList
(
ownerQuery
);
if
(
CollectionUtils
.
isEmpty
(
owners
))
{
throw
new
ServiceException
(
String
.
format
(
"业主【%s】不存在,无法新增入库单【%s】"
,
firstVO
.
getOwnerName
(),
orderId
));
}
if
(
firstVO
.
getOwnerId
()
!=
null
)
{
boolean
isMatch
=
owners
.
stream
().
anyMatch
(
o
->
firstVO
.
getOwnerId
().
equals
(
o
.
getId
()));
if
(!
isMatch
)
{
throw
new
ServiceException
(
String
.
format
(
"入库单号【%s】的业主ID【%s】与业主名称【%s】不匹配"
,
orderId
,
firstVO
.
getOwnerId
(),
firstVO
.
getOwnerName
()));
}
mainDO
.
setOwnerId
(
firstVO
.
getOwnerId
());
}
else
{
mainDO
.
setOwnerId
(
owners
.
get
(
0
).
getId
());
}
}
else
if
(
firstVO
.
getOwnerId
()
!=
null
)
{
Owners
ownerById
=
ownersService
.
selectOwnersById
(
firstVO
.
getOwnerId
());
if
(
ownerById
==
null
)
{
throw
new
ServiceException
(
String
.
format
(
"入库单号【%s】的业主ID【%s】不存在"
,
orderId
,
firstVO
.
getOwnerId
()));
}
mainDO
.
setOwnerId
(
firstVO
.
getOwnerId
());
}
else
{
throw
new
ServiceException
(
String
.
format
(
"入库单号【%s】的业主名称/ID不能为空"
,
orderId
));
}
mainDO
.
setId
(
UUID
.
randomUUID
().
toString
());
mainDO
.
setOrderId
(
orderId
);
mainDO
.
setOrderStatus
(
3L
);
mainDO
.
setCreateBy
(
operId
);
mainDO
.
setCreateTime
(
now
);
mainDO
.
setCreateUserCode
(
operId
);
mainDO
.
setUpdateBy
(
operId
);
mainDO
.
setUpdateTime
(
now
);
mainDO
.
setUpdateUserCode
(
operId
);
mainDO
.
setSortNo
(
Optional
.
ofNullable
(
mainDO
.
getSortNo
()).
orElse
(
0L
));
}
for
(
int
i
=
0
;
i
<
voList
.
size
();
i
++)
{
OutboundTemplateVO
vo
=
voList
.
get
(
i
);
int
lineNo
=
i
+
1
;
OutboundOrderItems
itemDO
=
new
OutboundOrderItems
();
com
.
ruoyi
.
common
.
utils
.
bean
.
BeanUtils
.
copyProperties
(
vo
,
itemDO
,
"orderId"
,
"systemNo"
,
"orderTypeId"
,
"batchId"
);
itemDO
.
setId
(
UUID
.
randomUUID
().
toString
());
itemDO
.
setOrderId
(
orderId
);
itemDO
.
setBatchCode
(
Optional
.
ofNullable
(
mainDO
.
getBatchCode
()).
orElse
(
""
));
itemDO
.
setInboundOrderId
(
mainDO
.
getId
());
itemDO
.
setCreateBy
(
operId
);
itemDO
.
setCreateTime
(
now
);
itemDO
.
setCreateUserCode
(
operId
);
itemDO
.
setSortNo
(
0L
);
if
(
StringUtils
.
isBlank
(
vo
.
getSapNo
()))
{
throw
new
ServiceException
(
String
.
format
(
"入库单号【%s】第%d条明细的物料SAP号不能为空"
,
orderId
,
lineNo
));
}
Materials
materialsQuery
=
new
Materials
();
materialsQuery
.
setSapNo
(
vo
.
getSapNo
());
List
<
Materials
>
materialsList
=
materialsService
.
selectMaterialsList
(
materialsQuery
);
if
(
CollectionUtils
.
isEmpty
(
materialsList
))
{
throw
new
ServiceException
(
String
.
format
(
"入库单号【%s】第%d条明细的SAP号【%s】对应的物料不存在"
,
orderId
,
lineNo
,
vo
.
getSapNo
()));
}
itemDO
.
setMaterialId
(
materialsList
.
get
(
0
).
getId
());
if
(
StringUtils
.
isBlank
(
vo
.
getLocationName
()))
{
throw
new
ServiceException
(
String
.
format
(
"入库单号【%s】第%d条明细的库位名称不能为空"
,
orderId
,
lineNo
));
}
StorageLocations
storageQuery
=
new
StorageLocations
();
storageQuery
.
setLocationCode
(
vo
.
getLocationName
());
List
<
StorageLocations
>
storageList
=
storageLocationsService
.
selectStorageLocationsList
(
storageQuery
);
if
(
CollectionUtils
.
isEmpty
(
storageList
))
{
throw
new
ServiceException
(
String
.
format
(
"入库单号【%s】第%d条明细的库位【%s】不存在"
,
orderId
,
lineNo
,
vo
.
getLocationName
()));
}
itemDO
.
setLocationId
(
storageList
.
get
(
0
).
getId
());
List
<
Warehouses
>
warehousesList
=
warehousesService
.
selectWarehousesList
(
new
Warehouses
());
if
(
CollectionUtils
.
isEmpty
(
warehousesList
))
{
throw
new
ServiceException
(
String
.
format
(
"系统未配置仓库,无法导入入库单号【%s】的第%d条明细"
,
orderId
,
lineNo
));
}
itemDO
.
setWarehouseId
(
warehousesList
.
get
(
0
).
getId
());
Inventory
itemsList
=
new
Inventory
();
itemsList
.
setWarehousesId
(
itemDO
.
getWarehouseId
());
itemsList
.
setMaterialId
(
itemDO
.
getMaterialId
());
itemsList
.
setLocationId
(
itemDO
.
getLocationId
());
List
<
Inventory
>
inventory
=
inventoryService
.
selectInventoryList
(
itemsList
);
if
(
CollectionUtils
.
isEmpty
(
inventory
))
{
throw
new
ServiceException
(
String
.
format
(
"入库单号【%s】第%d条明细:仓库【%s】+物料【%s】+库位【%s】组合的库存记录不存在"
,
orderId
,
lineNo
,
itemDO
.
getWarehouseName
(),
firstVO
.
getMaterialName
(),
firstVO
.
getLocationName
()));
}
itemDO
.
setInventoryId
(
inventory
.
get
(
0
).
getId
());
itemDO
.
setItemStatus
(
3
l
);
itemDOList
.
add
(
itemDO
);
}
validMainMap
.
put
(
orderId
,
mainDO
);
validItemMap
.
put
(
orderId
,
itemDOList
);
}
catch
(
Exception
e
)
{
hasValidateError
=
true
;
totalMainFailure
++;
totalItemFailure
+=
voList
.
size
();
failureMsg
.
append
(
String
.
format
(
"入库单号【%s】验证失败:%s;\n"
,
orderId
,
e
.
getMessage
()));
}
}
// 5. 有验证失败直接抛异常(完全保留你的代码)
if
(
hasValidateError
)
{
throw
new
ServiceException
(
String
.
format
(
"验证失败,导入终止!失败详情:%s"
,
failureMsg
.
toString
()));
}
// 6. 验证全通过:统一执行入库/更新操作(完全保留你的代码)
for
(
Map
.
Entry
<
String
,
OutboundOrders
>
entry
:
validMainMap
.
entrySet
())
{
String
orderId
=
entry
.
getKey
();
OutboundOrders
mainDO
=
entry
.
getValue
();
List
<
OutboundOrderItems
>
itemDOList
=
validItemMap
.
get
(
orderId
);
if
(
mainDO
!=
null
)
{
outboundOrdersMapper
.
insertOutboundOrders
(
mainDO
);
totalMainSuccess
++;
successMsg
.
append
(
String
.
format
(
"入库单号【%s】已新增;\n"
,
orderId
));
}
else
{
outboundOrdersMapper
.
updateOutboundOrders
(
mainDO
);
totalMainSuccess
++;
successMsg
.
append
(
String
.
format
(
"入库单号【%s】已更新;\n"
,
orderId
));
}
if
(!
CollectionUtils
.
isEmpty
(
itemDOList
))
{
int
itemSuccess
=
outboundOrderItemsMapper
.
batchInsertOutboundOrderItems
(
itemDOList
);
totalItemSuccess
+=
itemSuccess
;
int
itemFail
=
itemDOList
.
size
()
-
itemSuccess
;
totalItemFailure
+=
itemFail
;
successMsg
.
append
(
String
.
format
(
"入库单号【%s】成功导入%d条物料明细;\n"
,
orderId
,
itemSuccess
));
if
(
itemFail
>
0
)
{
failureMsg
.
append
(
String
.
format
(
"入库单号【%s】有%d条物料明细导入失败;\n"
,
orderId
,
itemFail
));
}
}
}
// ========== 仅新增这一段代码(核心:事务提交后执行自定义逻辑) ==========
if
(
TransactionSynchronizationManager
.
isSynchronizationActive
())
{
// 保存当前需要的变量,用于事务提交后执行
Map
<
String
,
OutboundOrders
>
finalValidMainMap
=
new
HashMap
<>(
validMainMap
);
Map
<
String
,
List
<
OutboundOrderItems
>>
finalValidItemMap
=
new
HashMap
<>(
validItemMap
);
String
finalOperId
=
operId
;
Date
finalNow
=
now
;
TransactionSynchronizationManager
.
registerSynchronization
(
new
TransactionSynchronization
()
{
@Override
public
void
afterCommit
()
{
// 事务提交后,调用你原来的executeCustomLogic方法
executeCustomLogic
(
finalValidMainMap
,
finalValidItemMap
,
finalOperId
,
finalNow
);
}
});
}
else
{
// 无事务时,直接执行(和你原有逻辑一致)
executeCustomLogic
(
validMainMap
,
validItemMap
,
operId
,
now
);
}
// ========== 新增代码结束 ==========
// 8. 结果汇总(完全保留你的代码)
if
(
totalMainFailure
>
0
||
totalItemFailure
>
0
)
{
String
finalFailureMsg
=
String
.
format
(
"导入结果:成功新增/更新%d个入库单,失败%d个;成功导入%d条明细,失败%d条。失败详情:%s"
,
totalMainSuccess
,
totalMainFailure
,
totalItemSuccess
,
totalItemFailure
,
failureMsg
.
toString
()
);
throw
new
ServiceException
(
finalFailureMsg
);
}
else
{
String
finalSuccessMsg
=
String
.
format
(
"恭喜您,数据已全部导入成功!共处理%d个入库单,成功导入%d条物料明细。详情:%s"
,
totalMainSuccess
,
totalItemSuccess
,
successMsg
.
toString
()
);
return
finalSuccessMsg
;
}
}
// 仅修改这个方法中【设置日志ID】的一行代码,其余完全保留
private
void
executeCustomLogic
(
Map
<
String
,
OutboundOrders
>
validMainMap
,
Map
<
String
,
List
<
OutboundOrderItems
>>
validItemMap
,
String
operId
,
Date
now
)
{
for
(
String
orderId
:
validMainMap
.
keySet
())
{
OutboundOrders
mainDO
=
validMainMap
.
get
(
orderId
);
List
<
OutboundOrderItems
>
itemList
=
validItemMap
.
get
(
orderId
);
System
.
out
.
println
(
String
.
format
(
"订单【%s】导入成功,主表ID:%s,明细数:%d"
,
orderId
,
mainDO
.
getId
(),
itemList
.
size
()));
List
<
OutboundOrderLog
>
outboundOrderLogs
=
new
ArrayList
<>();
for
(
OutboundOrderItems
item
:
itemList
)
{
OutboundOrderLog
outboundOrderLog
=
new
OutboundOrderLog
();
// ========== 唯一改动:设置日志ID = 明细ID ==========
outboundOrderLog
.
setId
(
item
.
getId
());
outboundOrderLog
.
setOrderId
(
item
.
getOutboundOrderId
());
BeanUtils
.
copyProperties
(
item
,
outboundOrderLog
);
outboundOrderLogs
.
add
(
outboundOrderLog
);
}
outboundOrderLogMapper
.
batchOutboundOrderLog
(
outboundOrderLogs
);
ship
(
itemList
);
}
}
public
int
ship
(
List
<
OutboundOrderItems
>
outboundOrderItems
)
{
if
(!
outboundOrderItems
.
isEmpty
())
{
List
<
String
>
inventoryIds
=
new
ArrayList
<>();
// 手动收集inventoryId
for
(
OutboundOrderItems
outboundOrderItem
:
outboundOrderItems
)
{
// 直接用明细的inventoryId,不查日志!
String
inventoryId
=
outboundOrderItem
.
getInventoryId
();
if
(
StringUtils
.
isBlank
(
inventoryId
))
{
throw
new
ServiceException
(
"明细ID【"
+
outboundOrderItem
.
getId
()
+
"】的库存ID为空,无法扣减"
);
}
Inventory
inventory
=
inventoryService
.
selectInventoryById
(
inventoryId
);
if
(
inventory
==
null
)
{
throw
new
ServiceException
(
"库存ID【"
+
inventoryId
+
"】不存在,无法扣减"
);
}
// 扣减库存
inventory
.
setQuantity
(
inventory
.
getQuantity
()
-
outboundOrderItem
.
getActualQuantity
());
if
(
inventory
.
getQuantity
()
==
0
)
{
inventory
.
setInventoryStatus
(
0L
);
}
inventoryService
.
updateInventory
(
inventory
);
inventoryIds
.
add
(
inventoryId
);
// 收集库存ID用于刷新
}
inventoryService
.
RefreshInventory
(
inventoryIds
);
}
return
1
;
}
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/OwnersServiceImpl.java
View file @
19bd4ddb
package
com
.
ruoyi
.
inventory
.
service
.
impl
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.UUID
;
import
com.ruoyi.common.exception.ServiceException
;
import
com.ruoyi.common.utils.DateUtils
;
import
com.ruoyi.common.utils.DictUtils
;
import
com.ruoyi.common.utils.SecurityUtils
;
import
com.ruoyi.common.utils.StringUtils
;
import
com.ruoyi.inventory.domain.vo.OwnerTemplateVO
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
com.ruoyi.inventory.mapper.OwnersMapper
;
...
...
@@ -21,76 +26,69 @@ import com.ruoyi.inventory.service.IOwnersService;
* @date 2025-11-28
*/
@Service
public
class
OwnersServiceImpl
implements
IOwnersService
{
public
class
OwnersServiceImpl
implements
IOwnersService
{
@Autowired
private
OwnersMapper
ownersMapper
;
/**
* 查询货主信息
*
*
* @param id 货主信息主键
* @return 货主信息
*/
@Override
public
Owners
selectOwnersById
(
String
id
)
{
public
Owners
selectOwnersById
(
String
id
)
{
return
ownersMapper
.
selectOwnersById
(
id
);
}
/**
* 查询货主信息列表
*
*
* @param owners 货主信息
* @return 货主信息
*/
@Override
public
List
<
Owners
>
selectOwnersList
(
Owners
owners
)
{
public
List
<
Owners
>
selectOwnersList
(
Owners
owners
)
{
return
ownersMapper
.
selectOwnersList
(
owners
);
}
/**
* 新增货主信息
*
*
* @param owners 货主信息
* @return 结果
*/
@Override
public
int
insertOwners
(
Owners
owners
)
{
public
int
insertOwners
(
Owners
owners
)
{
Long
userId
=
SecurityUtils
.
getUserId
();
String
operId
=
userId
.
toString
();
Date
now
=
DateUtils
.
getNowDate
();
// 填充创建人、创建时间、修改人、修改时间
owners
.
setId
(
UUID
.
randomUUID
().
toString
());
owners
.
setCreateBy
(
operId
);
owners
.
setCreateTime
(
now
);
// 填充创建用户编码和更新用户编码
owners
.
setCreateUserCode
(
operId
);
// 设置默认值
if
(
owners
.
getIsActive
()
==
null
)
{
if
(
owners
.
getIsActive
()
==
null
)
{
owners
.
setIsActive
(
1L
);
// 默认激活
}
if
(
owners
.
getIsUsed
()
==
null
)
{
owners
.
setIsUsed
(
0L
);
// 默认未删除
if
(
owners
.
getIsUsed
()
==
null
)
{
owners
.
setIsUsed
(
1L
);
// 默认未删除
}
if
(
owners
.
getSortNo
()
==
null
)
{
if
(
owners
.
getSortNo
()
==
null
)
{
owners
.
setSortNo
(
0L
);
// 默认排序号
}
return
ownersMapper
.
insertOwners
(
owners
);
}
@Override
public
String
importOwners
(
List
<
Owners
>
ownersList
,
Boolean
isUpdateSupport
,
String
operName
)
{
if
(
StringUtils
.
isNull
(
ownersList
)
||
ownersList
.
size
()
==
0
)
{
public
String
importOwners
(
List
<
OwnerTemplateVO
>
ownersList
,
Boolean
isUpdateSupport
,
String
operName
)
{
if
(
CollectionUtils
.
isEmpty
(
ownersList
))
{
throw
new
ServiceException
(
"导入用户数据不能为空!"
);
}
int
successNum
=
0
;
int
failureNum
=
0
;
StringBuilder
successMsg
=
new
StringBuilder
();
...
...
@@ -99,48 +97,73 @@ public class OwnersServiceImpl implements IOwnersService
// 获取当前登录用户ID
Long
userId
=
SecurityUtils
.
getUserId
();
String
operId
=
userId
.
toString
();
for
(
Owners
owners
:
ownersList
)
{
try
{
// 批量插入的有效数据集合
List
<
Owners
>
batchInsertList
=
new
ArrayList
<>();
for
(
OwnerTemplateVO
ownerTemp
:
ownersList
)
{
try
{
Owners
owners
=
new
Owners
();
// 处理激活状态转换
BeanUtils
.
copyProperties
(
ownerTemp
,
owners
);
if
(
ownerTemp
.
getIsActive
()!=
null
)
{
owners
.
setIsActive
(
Long
.
valueOf
(
ownerTemp
.
getIsActive
()));
}
// 类型转换
if
(
ownerTemp
.
getOwnerType
()!=
null
)
{
owners
.
setOwnerType
(
Long
.
valueOf
(
ownerTemp
.
getOwnerType
()));
}
// 生成UUID主键
owners
.
setId
(
UUID
.
randomUUID
().
toString
());
// 填充创建人、创建时间、修改人、修改时间
// 填充公共字段
owners
.
setCreateBy
(
operId
);
owners
.
setCreateTime
(
now
);
// 填充创建用户编码和更新用户编码
owners
.
setCreateUserCode
(
operId
);
// 设置默认值
if
(
owners
.
getIsActive
()
==
null
)
{
if
(
owners
.
getIsActive
()
==
null
)
{
owners
.
setIsActive
(
1L
);
// 默认激活
}
if
(
owners
.
getIsUsed
()
==
null
)
{
owners
.
setIsUsed
(
0L
);
// 默认未删除
if
(
owners
.
getIsUsed
()
==
null
)
{
owners
.
setIsUsed
(
1L
);
// 默认未删除
}
if
(
owners
.
getSortNo
()
==
null
)
{
if
(
owners
.
getSortNo
()
==
null
)
{
owners
.
setSortNo
(
0L
);
// 默认排序号
}
ownersMapper
.
insertOwners
(
owners
);
// 加入批量集合
batchInsertList
.
add
(
owners
);
successNum
++;
successMsg
.
append
(
"<br/>"
+
successNum
+
"、用户 "
+
owners
.
getOwnerName
()
+
" 导入成功"
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
failureNum
++;
String
msg
=
"<br/>"
+
failureNum
+
"、账号 "
+
owners
.
getOwnerName
()
+
" 导入失败:"
;
String
ownerName
=
ownerTemp
.
getOwnerCode
()
!=
null
?
ownerTemp
.
getOwnerCode
()
:
"未知名称"
;
String
msg
=
"<br/>"
+
failureNum
+
"、账号 "
+
ownerName
+
" 导入失败:"
;
failureMsg
.
append
(
msg
+
e
.
getMessage
());
// 异常数据不加入批量集合,继续处理下一条
continue
;
}
}
// 批量插入有效数据(如果有)
if
(!
CollectionUtils
.
isEmpty
(
batchInsertList
))
{
try
{
ownersMapper
.
batchInsertOwners
(
batchInsertList
);
}
catch
(
Exception
e
)
{
// 批量插入失败时,统计失败数量并抛出异常
failureNum
+=
batchInsertList
.
size
();
successNum
-=
batchInsertList
.
size
();
failureMsg
.
insert
(
0
,
String
.
format
(
"<br/>批量插入失败:%s,已失败数据条数追加 %d 条"
,
e
.
getMessage
(),
batchInsertList
.
size
()));
}
}
if
(
failureNum
>
0
)
{
// 处理结果反馈
if
(
failureNum
>
0
)
{
failureMsg
.
insert
(
0
,
"很抱歉,导入失败!共 "
+
failureNum
+
" 条数据格式不正确"
);
throw
new
ServiceException
(
failureMsg
.
toString
());
}
else
{
}
else
{
successMsg
.
insert
(
0
,
"恭喜您,数据已全部导入成功!共 "
+
successNum
+
" 条,数据如下:"
);
}
return
successMsg
.
toString
();
...
...
@@ -188,4 +211,5 @@ public class OwnersServiceImpl implements IOwnersService
{
return
ownersMapper
.
deleteOwnersById
(
id
);
}
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/StorageLocationsServiceImpl.java
View file @
19bd4ddb
package
com
.
ruoyi
.
inventory
.
service
.
impl
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
import
com.ruoyi.common.core.domain.entity.Materials
;
import
com.ruoyi.common.exception.ServiceException
;
import
com.ruoyi.common.utils.DateUtils
;
import
com.ruoyi.common.utils.SecurityUtils
;
import
com.ruoyi.common.utils.StringUtils
;
import
com.ruoyi.common.utils.bean.BeanUtils
;
import
com.ruoyi.common.utils.uuid.UUID
;
import
com.ruoyi.inventory.domain.Owners
;
import
com.ruoyi.inventory.domain.StorageLocationsCategory
;
import
com.ruoyi.inventory.domain.vo.StorageLocationsLocationTemplateVO
;
import
com.ruoyi.inventory.mapper.MaterialsMapper
;
import
com.ruoyi.inventory.mapper.StorageLocationsCategoryMapper
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
com.ruoyi.inventory.mapper.StorageLocationsMapper
;
...
...
@@ -222,4 +229,91 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
List
<
StorageLocations
>
storageLocations1
=
storageLocationsMapper
.
getStorageLocationsList
(
storageLocations
);
return
storageLocations1
;
}
@Override
public
String
importStorageLocationsLocation
(
List
<
StorageLocationsLocationTemplateVO
>
storageLocationsLocationTemplateVOS
,
Boolean
isUpdateSupport
,
String
operName
)
{
// 空数据校验
if
(
CollectionUtils
.
isEmpty
(
storageLocationsLocationTemplateVOS
))
{
throw
new
ServiceException
(
"导入库位数据不能为空!"
);
}
int
successNum
=
0
;
int
failureNum
=
0
;
StringBuilder
successMsg
=
new
StringBuilder
();
StringBuilder
failureMsg
=
new
StringBuilder
();
Date
now
=
DateUtils
.
getNowDate
();
// 获取当前登录用户ID
Long
userId
=
SecurityUtils
.
getUserId
();
String
operId
=
userId
.
toString
();
// 批量插入数据集合
List
<
StorageLocations
>
batchInsertList
=
new
ArrayList
<>();
for
(
StorageLocationsLocationTemplateVO
templateVO
:
storageLocationsLocationTemplateVOS
)
{
try
{
StorageLocations
storageLocations
=
new
StorageLocations
();
// 拷贝基础属性
BeanUtils
.
copyProperties
(
templateVO
,
storageLocations
);
// 字段类型转换与赋值
storageLocations
.
setId
(
UUID
.
randomUUID
().
toString
());
if
(
StringUtils
.
isNotBlank
(
templateVO
.
getLocationUsage
()))
{
storageLocations
.
setLocationUsage
(
Integer
.
valueOf
(
templateVO
.
getLocationUsage
()));
}
if
(
StringUtils
.
isNotBlank
(
templateVO
.
getIsEnabled
()))
{
storageLocations
.
setIsEnabled
(
Long
.
valueOf
(
templateVO
.
getIsEnabled
()));
}
// 填充公共字段
storageLocations
.
setCreateBy
(
operId
);
storageLocations
.
setCreateTime
(
now
);
storageLocations
.
setCreateUserCode
(
operId
);
// 设置默认值
if
(
storageLocations
.
getIsUsed
()
==
null
)
{
storageLocations
.
setIsUsed
(
1L
);
// 默认未删除
}
if
(
storageLocations
.
getSortNo
()
==
null
)
{
storageLocations
.
setSortNo
(
0L
);
// 默认排序号
}
// 加入批量集合
batchInsertList
.
add
(
storageLocations
);
successNum
++;
String
locationName
=
storageLocations
.
getLocationName
()
!=
null
?
storageLocations
.
getLocationName
()
:
"未知名称"
;
successMsg
.
append
(
"<br/>"
+
successNum
+
"、库位 "
+
locationName
+
" 导入成功"
);
}
catch
(
Exception
e
)
{
failureNum
++;
String
locationName
=
templateVO
.
getLocationCode
()
!=
null
?
templateVO
.
getLocationCode
()
:
"未知名称"
;
String
msg
=
"<br/>"
+
failureNum
+
"、库位 "
+
locationName
+
" 导入失败:"
;
failureMsg
.
append
(
msg
+
e
.
getMessage
());
// 异常数据跳过,继续处理下一条
continue
;
}
}
// 执行批量插入(有有效数据时)
if
(!
CollectionUtils
.
isEmpty
(
batchInsertList
))
{
try
{
storageLocationsMapper
.
batchInsertStorageLocations
(
batchInsertList
);
}
catch
(
Exception
e
)
{
// 批量插入失败,更新失败统计
failureNum
+=
batchInsertList
.
size
();
successNum
-=
batchInsertList
.
size
();
failureMsg
.
insert
(
0
,
String
.
format
(
"<br/>批量插入失败:%s,失败条数追加 %d 条"
,
e
.
getMessage
(),
batchInsertList
.
size
()));
}
}
// 结果反馈处理
if
(
failureNum
>
0
)
{
failureMsg
.
insert
(
0
,
"很抱歉,导入失败!共 "
+
failureNum
+
" 条数据格式不正确"
);
throw
new
ServiceException
(
failureMsg
.
toString
());
}
else
{
successMsg
.
insert
(
0
,
"恭喜您,数据已全部导入成功!共 "
+
successNum
+
" 条,数据如下:"
);
}
return
successMsg
.
toString
();
}
}
ruoyi-inventory/src/main/resources/mapper/inventory/InventoryMapper.xml
View file @
19bd4ddb
...
...
@@ -9,9 +9,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result
property=
"inventoryType"
column=
"inventory_type"
/>
<result
property=
"orderId"
column=
"order_id"
/>
<result
property=
"materialId"
column=
"material_id"
/>
<result
property=
"materialName"
column=
"material_name"
/>
<result
property=
"batchId"
column=
"batch_id"
/>
<result
property=
"warehousesCode"
column=
"warehouses_code"
/>
<result
property=
"warehousesCode"
column=
"warehouses_code"
/>
<result
property=
"warehousesName"
column=
"warehouses_name"
/>
<result
property=
"locationId"
column=
"location_id"
/>
<result
property=
"locationName"
column=
"location_name"
/>
<result
property=
"ownerId"
column=
"owner_id"
/>
<result
property=
"quantity"
column=
"quantity"
/>
<result
property=
"lockedQuantity"
column=
"locked_quantity"
/>
...
...
@@ -30,6 +33,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result
property=
"updateTime"
column=
"update_time"
/>
<result
property=
"updateUserCode"
column=
"update_user_code"
/>
<result
property=
"warehousesId"
column=
"warehouses_id"
/>
<result
property=
"oderCode"
column=
"order_code"
/>
</resultMap>
<resultMap
type=
"com.ruoyi.inventory.domain.TO.StocktakeItemsTo"
id=
"StocktakeItemsResult"
>
...
...
@@ -212,14 +216,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where id = #{id}
</select>
<select
id=
"listByMaterialId"
parameterType=
"String"
resultMap=
"InventoryResult"
>
<include
refid=
"selectInventoryVo"
/>
where 1=1
SELECT
i.id,
i.inventory_type,
i.warehouses_id,
w.warehouses_name,
i.order_id,
i.material_id,
m.material_name,
i.batch_id,
i.location_id,
sl.location_name,
i.owner_id,
i.quantity,
i.locked_quantity,
i.unit_weight,
i.total_weight,
i.total_volume,
i.production_date,
i.expiration_date,
i.inventory_status,
i.last_inbound_time,
i.last_outbound_time,
i.is_used,
i.sort_no,
i.create_time,
i.create_user_code,
i.update_time,
i.update_user_code
FROM inventory i
LEFT JOIN materials m ON i.material_id = m.id AND m.is_used = 1
LEFT JOIN warehouses w ON i.warehouses_id = w.id AND w.is_enabled = 1 AND w.is_used = 1
LEFT JOIN storage_locations sl ON i.location_id = sl.id AND sl.is_enabled = 1 AND sl.is_used = 1
WHERE 1=1
<if
test=
"materialId != null and materialId.trim() != ''"
>
and
material_id = #{materialId}
AND i.
material_id = #{materialId}
</if>
<![CDATA[
and inventory_status = '1'
]]>
AND i.inventory_status = '1'
]]>
ORDER BY i.expiration_date ASC
</select>
<insert
id=
"insertInventory"
parameterType=
"Inventory"
>
insert into inventory
...
...
@@ -345,8 +381,8 @@ and inventory_status = '1'
sum(i.quantity) as value
from inventory i
left join materials m on i.material_id = m.id
where i.is_used = 1 and i.
production_dat
e
>
= DATE_FORMAT(CURDATE(), '%Y-%m-01')
and i.
production_dat
e
<
DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')
where i.is_used = 1 and i.
last_inbound_tim
e
>
= DATE_FORMAT(CURDATE(), '%Y-%m-01')
and i.
last_inbound_tim
e
<
DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')
group by m.material_name
order by sum(i.quantity) desc
</select>
...
...
@@ -357,8 +393,8 @@ and inventory_status = '1'
sum(i.quantity)*i.unit_price as value
from inventory i
left join materials m on i.material_id = m.id
where i.is_used = 1 and i.
production_dat
e
>
= DATE_FORMAT(CURDATE(), '%Y-%m-01')
and i.
production_dat
e
<
DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')
where i.is_used = 1 and i.
last_inbound_tim
e
>
= DATE_FORMAT(CURDATE(), '%Y-%m-01')
and i.
last_inbound_tim
e
<
DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')
group by m.material_name
order by sum(i.quantity)*i.unit_price desc
</select>
...
...
ruoyi-inventory/src/main/resources/mapper/inventory/OutboundOrderItemsMapper.xml
View file @
19bd4ddb
...
...
@@ -257,7 +257,7 @@
o.order_id as main_order_id
from outbound_order_items oi
left join outbound_orders o on oi.outbound_order_id = o.id
left join materials m on oi.material_id = m.
sap_no
left join materials m on oi.material_id = m.
id
left join warehouses w on oi.warehouse_id = w.id
left join storage_locations sl on oi.location_id = sl.id
<where>
...
...
ruoyi-inventory/src/main/resources/mapper/inventory/OutboundOrdersMapper.xml
View file @
19bd4ddb
...
...
@@ -9,6 +9,7 @@
<result
property=
"orderId"
column=
"order_id"
/>
<result
property=
"systemNo"
column=
"system_no"
/>
<result
property=
"orderTypeId"
column=
"order_type_id"
/>
<result
property=
"orderType"
column=
"order_type"
/>
<!-- 新增order_type字段映射 -->
<result
property=
"batchCode"
column=
"batch_code"
/>
<result
property=
"warehouseId"
column=
"warehouse_id"
/>
<result
property=
"warehouseName"
column=
"warehouse_name"
/>
...
...
@@ -74,6 +75,7 @@
oo.order_id,
oo.system_no,
oo.order_type_id,
oo.order_type, -- 新增order_type字段查询
oo.batch_code,
oo.warehouse_id,
w.warehouses_name as warehouse_name,
...
...
@@ -103,6 +105,7 @@
<if
test=
"orderId != null and orderId != ''"
>
and oo.order_id = #{orderId}
</if>
<if
test=
"systemNo != null and systemNo != ''"
>
and oo.system_no = #{systemNo}
</if>
<if
test=
"orderTypeId != null and orderTypeId != ''"
>
and oo.order_type_id = #{orderTypeId}
</if>
<if
test=
"orderType != null and orderType != ''"
>
and oo.order_type = #{orderType}
</if>
<!-- 新增order_type查询条件 -->
<if
test=
"batchCode != null and batchCode != ''"
>
and oo.batch_code = #{batchCode}
</if>
<if
test=
"warehouseId != null and warehouseId != ''"
>
and oo.warehouse_id = #{warehouseId}
</if>
<if
test=
"ownerId != null and ownerId != ''"
>
and oo.owner_id = #{ownerId}
</if>
...
...
@@ -123,9 +126,9 @@
oo.order_id,
oo.system_no,
oo.order_type_id,
oo.order_type, -- 新增order_type字段查询
oo.batch_code,
oo.warehouse_id,
w.warehouses_name as warehouse_name,
oo.owner_id,
o.owner_name,
oo.order_status,
...
...
@@ -190,6 +193,7 @@
<if
test=
"orderId != null"
>
order_id,
</if>
<if
test=
"systemNo != null"
>
system_no,
</if>
<if
test=
"orderTypeId != null"
>
order_type_id,
</if>
<if
test=
"orderType != null"
>
order_type,
</if>
<!-- 新增order_type字段插入 -->
<if
test=
"batchCode != null"
>
batch_code,
</if>
<if
test=
"warehouseId != null"
>
warehouse_id,
</if>
<if
test=
"ownerId != null"
>
owner_id,
</if>
...
...
@@ -212,6 +216,7 @@
<if
test=
"orderId != null"
>
#{orderId},
</if>
<if
test=
"systemNo != null"
>
#{systemNo},
</if>
<if
test=
"orderTypeId != null"
>
#{orderTypeId},
</if>
<if
test=
"orderType != null"
>
#{orderType},
</if>
<!-- 新增order_type值插入 -->
<if
test=
"batchCode != null"
>
#{batchCode},
</if>
<if
test=
"warehouseId != null"
>
#{warehouseId},
</if>
<if
test=
"ownerId != null"
>
#{ownerId},
</if>
...
...
@@ -237,6 +242,7 @@
<if
test=
"orderId != null"
>
order_id = #{orderId},
</if>
<if
test=
"systemNo != null"
>
system_no = #{systemNo},
</if>
<if
test=
"orderTypeId != null"
>
order_type_id = #{orderTypeId},
</if>
<if
test=
"orderType != null"
>
order_type = #{orderType},
</if>
<!-- 新增order_type字段更新 -->
<if
test=
"batchCode != null"
>
batch_code = #{batchCode},
</if>
<if
test=
"warehouseId != null"
>
warehouse_id = #{warehouseId},
</if>
<if
test=
"ownerId != null"
>
owner_id = #{ownerId},
</if>
...
...
@@ -303,7 +309,7 @@
m.material_name as name,
sum(ooi.actual_quantity) as value
from outbound_order_items ooi
left join materials m on ooi.material_id = m.sap_no
left join materials m on ooi.material_id = m.id
where ooi.is_used = 1 and ooi.shipped_at
>
= DATE_FORMAT(CURDATE(), '%Y-%m-01')
and ooi.shipped_at
<
DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')
group by m.material_name
...
...
@@ -316,7 +322,7 @@
m.material_name as name,
sum(ooi.actual_quantity)*ooi.unit_price as value
from outbound_order_items ooi
left join materials m on ooi.material_id = m.sap_no
left join materials m on ooi.material_id = m.id
where ooi.is_used = 1 and ooi.shipped_at
>
= DATE_FORMAT(CURDATE(), '%Y-%m-01')
and ooi.shipped_at
<
DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')
group by m.material_name
...
...
@@ -326,6 +332,6 @@
<select
id=
"outboundOrdersCount"
resultType=
"String"
>
select count(*) from outbound_order_items where is_used = 1 and shipped_at
>
= DATE_FORMAT(CURDATE(), '%Y-%m-01')
and shipped_at
<
DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')
and shipped_at
<
DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')
</select>
</mapper>
\ No newline at end of file
ruoyi-inventory/src/main/resources/mapper/inventory/OwnersMapper.xml
View file @
19bd4ddb
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.ruoyi.inventory.mapper.OwnersMapper"
>
<resultMap
type=
"Owners"
id=
"OwnersResult"
>
<result
property=
"id"
column=
"id"
/>
<result
property=
"ownerCode"
column=
"owner_code"
/>
...
...
@@ -19,34 +19,38 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result
property=
"sortNo"
column=
"sort_no"
/>
<result
property=
"createTime"
column=
"create_time"
/>
<result
property=
"createUserCode"
column=
"create_user_code"
/>
<result
property=
"englishName"
column=
"english_name"
/>
<result
property=
"updateTime"
column=
"update_time"
/>
<result
property=
"updateUserCode"
column=
"update_user_code"
/>
<result
property=
"isUsed"
column=
"is_used"
/>
</resultMap>
<sql
id=
"selectOwnersVo"
>
select id, owner_code, owner_name, owner_type, contact_person, contact_phone, email, address, tax_number, bank_account, is_active, sort_no, create_time, create_user_code, update_time, update_user_code, is_used from owners
select id, owner_code, owner_name, owner_type,
english_name ,
contact_person, contact_phone, email, address, tax_number, bank_account, is_active, sort_no, create_time, create_user_code, update_time, update_user_code, is_used from owners
</sql>
<select
id=
"selectOwnersList"
parameterType=
"Owners"
resultMap=
"OwnersResult"
>
<include
refid=
"selectOwnersVo"
/>
where is_used = 0
<if
test=
"ownerCode != null and ownerCode != ''"
>
and owner_code = #{ownerCode}
</if>
<if
test=
"ownerName != null and ownerName != ''"
>
and owner_name like concat('%', #{ownerName}, '%')
</if>
<if
test=
"ownerType != null "
>
and owner_type = #{ownerType}
</if>
<if
test=
"contactPerson != null and contactPerson != ''"
>
and contact_person = #{contactPerson}
</if>
<if
test=
"contactPhone != null and contactPhone != ''"
>
and contact_phone = #{contactPhone}
</if>
<if
test=
"email != null and email != ''"
>
and email = #{email}
</if>
<if
test=
"address != null and address != ''"
>
and address = #{address}
</if>
<if
test=
"taxNumber != null and taxNumber != ''"
>
and tax_number = #{taxNumber}
</if>
<if
test=
"bankAccount != null and bankAccount != ''"
>
and bank_account = #{bankAccount}
</if>
<if
test=
"isActive != null "
>
and is_active = #{isActive}
</if>
<if
test=
"sortNo != null "
>
and sort_no = #{sortNo}
</if>
<if
test=
"createUserCode != null and createUserCode != ''"
>
and create_user_code = #{createUserCode}
</if>
<if
test=
"updateUserCode != null and updateUserCode != ''"
>
and update_user_code = #{updateUserCode}
</if>
order by sort_no asc
where is_used = 1
<if
test=
"ownerCode != null and ownerCode != ''"
>
and owner_code = #{ownerCode}
</if>
<if
test=
"ownerName != null and ownerName != ''"
>
and owner_name like concat('%', #{ownerName}, '%')
</if>
<!-- 新增englishName查询条件 -->
<if
test=
"englishName != null and englishName != ''"
>
and english_name like concat('%', #{englishName}, '%')
</if>
<if
test=
"ownerType != null "
>
and owner_type = #{ownerType}
</if>
<if
test=
"contactPerson != null and contactPerson != ''"
>
and contact_person = #{contactPerson}
</if>
<if
test=
"contactPhone != null and contactPhone != ''"
>
and contact_phone = #{contactPhone}
</if>
<if
test=
"email != null and email != ''"
>
and email = #{email}
</if>
<if
test=
"address != null and address != ''"
>
and address = #{address}
</if>
<if
test=
"taxNumber != null and taxNumber != ''"
>
and tax_number = #{taxNumber}
</if>
<if
test=
"bankAccount != null and bankAccount != ''"
>
and bank_account = #{bankAccount}
</if>
<if
test=
"isActive != null "
>
and is_active = #{isActive}
</if>
<if
test=
"sortNo != null "
>
and sort_no = #{sortNo}
</if>
<if
test=
"createUserCode != null and createUserCode != ''"
>
and create_user_code = #{createUserCode}
</if>
<if
test=
"updateUserCode != null and updateUserCode != ''"
>
and update_user_code = #{updateUserCode}
</if>
order by sort_no asc
</select>
<select
id=
"selectOwnersById"
parameterType=
"String"
resultMap=
"OwnersResult"
>
<include
refid=
"selectOwnersVo"
/>
where id = #{id}
...
...
@@ -59,6 +63,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"ownerCode != null"
>
owner_code,
</if>
<if
test=
"ownerName != null"
>
owner_name,
</if>
<if
test=
"ownerType != null"
>
owner_type,
</if>
<!-- 新增english_name插入字段 -->
<if
test=
"englishName != null"
>
english_name,
</if>
<if
test=
"contactPerson != null"
>
contact_person,
</if>
<if
test=
"contactPhone != null"
>
contact_phone,
</if>
<if
test=
"email != null"
>
email,
</if>
...
...
@@ -71,12 +77,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"createUserCode != null"
>
create_user_code,
</if>
<if
test=
"updateTime != null"
>
update_time,
</if>
<if
test=
"updateUserCode != null"
>
update_user_code,
</if>
</trim>
</trim>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"id != null"
>
#{id},
</if>
<if
test=
"ownerCode != null"
>
#{ownerCode},
</if>
<if
test=
"ownerName != null"
>
#{ownerName},
</if>
<if
test=
"ownerType != null"
>
#{ownerType},
</if>
<!-- 新增englishName插入值 -->
<if
test=
"englishName != null"
>
#{englishName},
</if>
<if
test=
"contactPerson != null"
>
#{contactPerson},
</if>
<if
test=
"contactPhone != null"
>
#{contactPhone},
</if>
<if
test=
"email != null"
>
#{email},
</if>
...
...
@@ -89,7 +97,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"createUserCode != null"
>
#{createUserCode},
</if>
<if
test=
"updateTime != null"
>
#{updateTime},
</if>
<if
test=
"updateUserCode != null"
>
#{updateUserCode},
</if>
</trim>
</trim>
</insert>
<!-- 新增批量插入方法 -->
<insert
id=
"batchInsertOwners"
parameterType=
"java.util.List"
>
insert into owners (
id, owner_code, owner_name, owner_type, english_name,
contact_person, contact_phone, email, address, tax_number,
bank_account, is_active, sort_no, create_time, create_user_code,
update_time, update_user_code, is_used
) VALUES
<foreach
collection=
"list"
item=
"item"
separator=
","
>
(
#{item.id}, #{item.ownerCode}, #{item.ownerName}, #{item.ownerType}, #{item.englishName},
#{item.contactPerson}, #{item.contactPhone}, #{item.email}, #{item.address}, #{item.taxNumber},
#{item.bankAccount}, #{item.isActive}, #{item.sortNo}, #{item.createTime}, #{item.createUserCode},
#{item.updateTime}, #{item.updateUserCode}, #{item.isUsed}
)
</foreach>
</insert>
<update
id=
"updateOwners"
parameterType=
"Owners"
>
...
...
@@ -98,6 +124,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"ownerCode != null"
>
owner_code = #{ownerCode},
</if>
<if
test=
"ownerName != null"
>
owner_name = #{ownerName},
</if>
<if
test=
"ownerType != null"
>
owner_type = #{ownerType},
</if>
<!-- 新增english_name更新字段 -->
<if
test=
"englishName != null"
>
english_name = #{englishName},
</if>
<if
test=
"contactPerson != null"
>
contact_person = #{contactPerson},
</if>
<if
test=
"contactPhone != null"
>
contact_phone = #{contactPhone},
</if>
<if
test=
"email != null"
>
email = #{email},
</if>
...
...
@@ -120,7 +148,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</update>
<update
id=
"deleteOwnersByIds"
parameterType=
"String"
>
update owners set is_used = 1 where id in
update owners set is_used = 1 where id in
<foreach
item=
"id"
collection=
"array"
open=
"("
separator=
","
close=
")"
>
#{id}
</foreach>
...
...
ruoyi-inventory/src/main/resources/mapper/inventory/StorageLocationsMapper.xml
View file @
19bd4ddb
...
...
@@ -4,7 +4,7 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.ruoyi.inventory.mapper.StorageLocationsMapper"
>
<!-- 原有基础ResultMap -->
<!-- 原有基础ResultMap -
仅添加新字段映射 -
->
<resultMap
type=
"StorageLocations"
id=
"StorageLocationsResult"
>
<result
property=
"id"
column=
"id"
/>
<result
property=
"locationCode"
column=
"location_code"
/>
...
...
@@ -28,9 +28,18 @@
<result
property=
"updateTime"
column=
"update_time"
/>
<result
property=
"updateUserCode"
column=
"update_user_code"
/>
<result
property=
"warehousesId"
column=
"warehouses_id"
/>
<!-- 新增字段映射 -->
<result
property=
"putawayOrder"
column=
"putaway_order"
/>
<result
property=
"pickingOrder"
column=
"picking_order"
/>
<result
property=
"LocationUsage"
column=
"location_usage"
/>
<result
property=
"locationHandling"
column=
"location_handling"
/>
<result
property=
"turnoverDemand"
column=
"turnover_demand"
/>
<result
property=
"pickingArea"
column=
"picking_area"
/>
<result
property=
"allowMixedProducts"
column=
"allow_mixed_products"
/>
<result
property=
"allowMixedBatches"
column=
"allow_mixed_batches"
/>
</resultMap>
<!-- 关联仓库表的ResultMap -->
<!-- 关联仓库表的ResultMap -
继承基础ResultMap(自动包含新字段) -
->
<resultMap
type=
"StorageLocations"
id=
"StorageLocationsWithWarehousesResult"
extends=
"StorageLocationsResult"
>
<result
property=
"warehousesName"
column=
"warehouses_name"
/>
<result
property=
"warehousesAddress"
column=
"warehouses_address"
/>
...
...
@@ -44,7 +53,11 @@
sl.zone_code, sl.row_code, sl.column_code, sl.layer_code, sl.capacity,
sl.volume_capacity, sl.allowed_hazard_levels, sl.allowed_category_ids,
sl.temperature_zone, sl.is_enabled, sl.is_used, sl.sort_no,
sl.create_time, sl.create_user_code, sl.update_time, sl.update_user_code, sl.warehouses_id
sl.create_time, sl.create_user_code, sl.update_time, sl.update_user_code, sl.warehouses_id,
-- 新增字段查询
sl.putaway_order, sl.picking_order, sl.location_usage,
sl.location_handling, sl.turnover_demand, sl.picking_area,
sl.allow_mixed_products, sl.allow_mixed_batches
from storage_locations sl
where sl.is_used = 1
</sql>
...
...
@@ -56,6 +69,10 @@
sl.volume_capacity, sl.allowed_hazard_levels, sl.allowed_category_ids,
sl.temperature_zone, sl.is_enabled, sl.is_used, sl.sort_no,
sl.create_time, sl.create_user_code, sl.update_time, sl.update_user_code, sl.warehouses_id,
-- 新增字段查询
sl.putaway_order, sl.picking_order, sl.location_usage,
sl.location_handling, sl.turnover_demand, sl.picking_area,
sl.allow_mixed_products, sl.allow_mixed_batches,
w.warehouses_name
from storage_locations sl
left join warehouses w on sl.warehouses_id = w.id
...
...
@@ -82,6 +99,15 @@
<if
test=
"sortNo != null "
>
and sl.sort_no = #{sortNo}
</if>
<if
test=
"createUserCode != null and createUserCode != ''"
>
and sl.create_user_code = #{createUserCode}
</if>
<if
test=
"updateUserCode != null and updateUserCode != ''"
>
and sl.update_user_code = #{updateUserCode}
</if>
<!-- 新增字段查询条件 -->
<if
test=
"putawayOrder != null "
>
and sl.putaway_order = #{putawayOrder}
</if>
<if
test=
"pickingOrder != null "
>
and sl.picking_order = #{pickingOrder}
</if>
<if
test=
"LocationUsage != null and LocationUsage != ''"
>
and sl.location_usage = #{LocationUsage}
</if>
<if
test=
"locationHandling != null and locationHandling != ''"
>
and sl.location_handling = #{locationHandling}
</if>
<if
test=
"turnoverDemand != null and turnoverDemand != ''"
>
and sl.turnover_demand = #{turnoverDemand}
</if>
<if
test=
"pickingArea != null and pickingArea != ''"
>
and sl.picking_area = #{pickingArea}
</if>
<if
test=
"allowMixedProducts != null "
>
and sl.allow_mixed_products = #{allowMixedProducts}
</if>
<if
test=
"allowMixedBatches != null "
>
and sl.allow_mixed_batches = #{allowMixedBatches}
</if>
</select>
<!-- 关联仓库表的列表查询(简化) -->
...
...
@@ -94,6 +120,15 @@
<if
test=
"zoneCode != null and zoneCode != ''"
>
and sl.zone_code = #{zoneCode}
</if>
<if
test=
"warehousesName != null and warehousesName != ''"
>
and w.warehouses_name like concat('%', #{warehousesName}, '%')
</if>
<if
test=
"warehousesManager != null and warehousesManager != ''"
>
and w.warehouses_manager = #{warehousesManager}
</if>
<!-- 新增字段查询条件 -->
<if
test=
"putawayOrder != null "
>
and sl.putaway_order = #{putawayOrder}
</if>
<if
test=
"pickingOrder != null "
>
and sl.picking_order = #{pickingOrder}
</if>
<if
test=
"LocationUsage != null and LocationUsage != ''"
>
and sl.location_usage = #{LocationUsage}
</if>
<if
test=
"locationHandling != null and locationHandling != ''"
>
and sl.location_handling = #{locationHandling}
</if>
<if
test=
"turnoverDemand != null and turnoverDemand != ''"
>
and sl.turnover_demand = #{turnoverDemand}
</if>
<if
test=
"pickingArea != null and pickingArea != ''"
>
and sl.picking_area = #{pickingArea}
</if>
<if
test=
"allowMixedProducts != null "
>
and sl.allow_mixed_products = #{allowMixedProducts}
</if>
<if
test=
"allowMixedBatches != null "
>
and sl.allow_mixed_batches = #{allowMixedBatches}
</if>
</select>
<!-- 根据ID查询(调整:保留where,单独条件) -->
...
...
@@ -102,7 +137,11 @@
sl.zone_code, sl.row_code, sl.column_code, sl.layer_code, sl.capacity,
sl.volume_capacity, sl.allowed_hazard_levels, sl.allowed_category_ids,
sl.temperature_zone, sl.is_enabled, sl.is_used, sl.sort_no,
sl.create_time, sl.create_user_code, sl.update_time, sl.update_user_code, sl.warehouses_id
sl.create_time, sl.create_user_code, sl.update_time, sl.update_user_code, sl.warehouses_id,
-- 新增字段查询
sl.putaway_order, sl.picking_order, sl.location_usage,
sl.location_handling, sl.turnover_demand, sl.picking_area,
sl.allow_mixed_products, sl.allow_mixed_batches
from storage_locations sl
where sl.id = #{id}
</select>
...
...
@@ -114,6 +153,10 @@
sl.volume_capacity, sl.allowed_hazard_levels, sl.allowed_category_ids,
sl.temperature_zone, sl.is_enabled, sl.is_used, sl.sort_no,
sl.create_time, sl.create_user_code, sl.update_time, sl.update_user_code, sl.warehouses_id,
-- 新增字段查询
sl.putaway_order, sl.picking_order, sl.location_usage,
sl.location_handling, sl.turnover_demand, sl.picking_area,
sl.allow_mixed_products, sl.allow_mixed_batches,
w.warehouses_name, w.warehouses_address, w.warehouses_manager, w.warehouses_phone
from storage_locations sl
left join warehouses w on sl.warehouses_code = w.warehouses_code
...
...
@@ -165,7 +208,7 @@
<if
test=
"warehousesCode != null and warehousesCode != ''"
>
and sl.warehouses_code = #{warehousesCode}
</if>
</select>
<!-- 原有新增/更新/删除方法(
无修改
) -->
<!-- 原有新增/更新/删除方法(
仅添加新字段
) -->
<insert
id=
"insertStorageLocations"
parameterType=
"StorageLocations"
>
insert into storage_locations
<trim
prefix=
"("
suffix=
")"
suffixOverrides=
","
>
...
...
@@ -191,6 +234,15 @@
<if
test=
"updateTime != null"
>
update_time,
</if>
<if
test=
"updateUserCode != null"
>
update_user_code,
</if>
<if
test=
"warehousesId != null"
>
warehouses_id,
</if>
<!-- 新增字段插入 -->
<if
test=
"putawayOrder != null"
>
putaway_order,
</if>
<if
test=
"pickingOrder != null"
>
picking_order,
</if>
<if
test=
"LocationUsage != null"
>
location_usage,
</if>
<if
test=
"locationHandling != null"
>
location_handling,
</if>
<if
test=
"turnoverDemand != null"
>
turnover_demand,
</if>
<if
test=
"pickingArea != null"
>
picking_area,
</if>
<if
test=
"allowMixedProducts != null"
>
allow_mixed_products,
</if>
<if
test=
"allowMixedBatches != null"
>
allow_mixed_batches,
</if>
</trim>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"id != null"
>
#{id},
</if>
...
...
@@ -215,9 +267,42 @@
<if
test=
"updateTime != null"
>
#{updateTime},
</if>
<if
test=
"updateUserCode != null"
>
#{updateUserCode},
</if>
<if
test=
"warehousesId != null"
>
#{warehousesId},
</if>
<!-- 新增字段值 -->
<if
test=
"putawayOrder != null"
>
#{putawayOrder},
</if>
<if
test=
"pickingOrder != null"
>
#{pickingOrder},
</if>
<if
test=
"LocationUsage != null"
>
#{LocationUsage},
</if>
<if
test=
"locationHandling != null"
>
#{locationHandling},
</if>
<if
test=
"turnoverDemand != null"
>
#{turnoverDemand},
</if>
<if
test=
"pickingArea != null"
>
#{pickingArea},
</if>
<if
test=
"allowMixedProducts != null"
>
#{allowMixedProducts},
</if>
<if
test=
"allowMixedBatches != null"
>
#{allowMixedBatches},
</if>
</trim>
</insert>
<!-- 新增批量插入库位信息方法 -->
<insert
id=
"batchInsertStorageLocations"
parameterType=
"java.util.List"
>
insert into storage_locations (
id, location_code, location_name, warehouses_code, location_type,
zone_code, row_code, column_code, layer_code, capacity,
volume_capacity, allowed_hazard_levels, allowed_category_ids, temperature_zone,
is_enabled, is_used, sort_no, create_time, create_user_code,
update_time, update_user_code, warehouses_id, putaway_order, picking_order,
location_usage, location_handling, turnover_demand, picking_area,
allow_mixed_products, allow_mixed_batches
) VALUES
<foreach
collection=
"list"
item=
"item"
separator=
","
>
(
#{item.id}, #{item.locationCode}, #{item.locationName}, #{item.warehousesCode}, #{item.locationType},
#{item.zoneCode}, #{item.rowCode}, #{item.columnCode}, #{item.layerCode}, #{item.capacity},
#{item.volumeCapacity}, #{item.allowedHazardLevels}, #{item.allowedCategoryIds}, #{item.temperatureZone},
#{item.isEnabled}, #{item.isUsed}, #{item.sortNo}, #{item.createTime}, #{item.createUserCode},
#{item.updateTime}, #{item.updateUserCode}, #{item.warehousesId}, #{item.putawayOrder}, #{item.pickingOrder},
#{item.LocationUsage}, #{item.locationHandling}, #{item.turnoverDemand}, #{item.pickingArea},
#{item.allowMixedProducts}, #{item.allowMixedBatches}
)
</foreach>
</insert>
<update
id=
"updateStorageLocations"
parameterType=
"StorageLocations"
>
update storage_locations
<trim
prefix=
"SET"
suffixOverrides=
","
>
...
...
@@ -241,6 +326,15 @@
<if
test=
"createUserCode != null"
>
create_user_code = #{createUserCode},
</if>
<if
test=
"updateTime != null"
>
update_time = #{updateTime},
</if>
<if
test=
"updateUserCode != null"
>
update_user_code = #{updateUserCode},
</if>
<!-- 新增字段更新 -->
<if
test=
"putawayOrder != null"
>
putaway_order = #{putawayOrder},
</if>
<if
test=
"pickingOrder != null"
>
picking_order = #{pickingOrder},
</if>
<if
test=
"LocationUsage != null"
>
location_usage = #{LocationUsage},
</if>
<if
test=
"locationHandling != null"
>
location_handling = #{locationHandling},
</if>
<if
test=
"turnoverDemand != null"
>
turnover_demand = #{turnoverDemand},
</if>
<if
test=
"pickingArea != null"
>
picking_area = #{pickingArea},
</if>
<if
test=
"allowMixedProducts != null"
>
allow_mixed_products = #{allowMixedProducts},
</if>
<if
test=
"allowMixedBatches != null"
>
allow_mixed_batches = #{allowMixedBatches},
</if>
</trim>
where id = #{id}
</update>
...
...
@@ -277,6 +371,15 @@
<if
test=
"sortNo != null "
>
and sl.sort_no = #{sortNo}
</if>
<if
test=
"createUserCode != null and createUserCode != ''"
>
and sl.create_user_code = #{createUserCode}
</if>
<if
test=
"updateUserCode != null and updateUserCode != ''"
>
and sl.update_user_code = #{updateUserCode}
</if>
<!-- 新增字段查询条件 -->
<if
test=
"putawayOrder != null "
>
and sl.putaway_order = #{putawayOrder}
</if>
<if
test=
"pickingOrder != null "
>
and sl.picking_order = #{pickingOrder}
</if>
<if
test=
"LocationUsage != null and LocationUsage != ''"
>
and sl.location_usage = #{LocationUsage}
</if>
<if
test=
"locationHandling != null and locationHandling != ''"
>
and sl.location_handling = #{locationHandling}
</if>
<if
test=
"turnoverDemand != null and turnoverDemand != ''"
>
and sl.turnover_demand = #{turnoverDemand}
</if>
<if
test=
"pickingArea != null and pickingArea != ''"
>
and sl.picking_area = #{pickingArea}
</if>
<if
test=
"allowMixedProducts != null "
>
and sl.allow_mixed_products = #{allowMixedProducts}
</if>
<if
test=
"allowMixedBatches != null "
>
and sl.allow_mixed_batches = #{allowMixedBatches}
</if>
</select>
<!-- 关联仓库的getStorageLocationsList -->
...
...
@@ -289,6 +392,15 @@
<if
test=
"locationType != null "
>
and sl.location_type = #{locationType}
</if>
<if
test=
"zoneCode != null and zoneCode != ''"
>
and sl.zone_code = #{zoneCode}
</if>
<if
test=
"warehousesName != null and warehousesName != ''"
>
and w.warehouses_name like concat('%', #{warehousesName}, '%')
</if>
<!-- 新增字段查询条件 -->
<if
test=
"putawayOrder != null "
>
and sl.putaway_order = #{putawayOrder}
</if>
<if
test=
"pickingOrder != null "
>
and sl.picking_order = #{pickingOrder}
</if>
<if
test=
"LocationUsage != null and LocationUsage != ''"
>
and sl.location_usage = #{LocationUsage}
</if>
<if
test=
"locationHandling != null and locationHandling != ''"
>
and sl.location_handling = #{locationHandling}
</if>
<if
test=
"turnoverDemand != null and turnoverDemand != ''"
>
and sl.turnover_demand = #{turnoverDemand}
</if>
<if
test=
"pickingArea != null and pickingArea != ''"
>
and sl.picking_area = #{pickingArea}
</if>
<if
test=
"allowMixedProducts != null "
>
and sl.allow_mixed_products = #{allowMixedProducts}
</if>
<if
test=
"allowMixedBatches != null "
>
and sl.allow_mixed_batches = #{allowMixedBatches}
</if>
</select>
</mapper>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论