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
f7de2ca4
Commit
f7de2ca4
authored
Dec 18, 2025
by
yubin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
导入bug修改
parent
2c73e2a2
显示空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
536 行增加
和
429 行删除
+536
-429
ruoyi-admin-vue/src/views/inventory/locations/index.vue
+356
-328
ruoyi-admin-vue/src/views/inventory/orders/index.vue
+16
-24
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/OutboundOrdersServiceImpl.java
+120
-43
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/StorageLocationsServiceImpl.java
+21
-16
ruoyi-inventory/src/main/resources/mapper/inventory/MaterialsMapper.xml
+9
-4
ruoyi-inventory/src/main/resources/mapper/inventory/OutboundOrderItemsMapper.xml
+2
-1
ruoyi-inventory/src/main/resources/mapper/inventory/OutboundOrdersMapper.xml
+5
-5
ruoyi-inventory/src/main/resources/mapper/inventory/OwnersMapper.xml
+2
-3
ruoyi-inventory/src/main/resources/mapper/inventory/StorageLocationsMapper.xml
+3
-3
ruoyi-inventory/src/main/resources/mapper/inventory/WarehousesMapper.xml
+2
-2
没有找到文件。
ruoyi-admin-vue/src/views/inventory/locations/index.vue
View file @
f7de2ca4
...
...
@@ -71,6 +71,7 @@
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<!-- 仓库查询相关已注释 -->
<!-- <el-form-item label="仓库" prop="warehouseId">
<el-input
v-model="queryWarehouseName"
...
...
@@ -220,16 +221,18 @@
<div><strong>
拣货区:
</strong>
{{
scope
.
row
.
pickingArea
||
'-'
}}
</div>
</el-col>
</el-row>
<el-row
:gutter=
"20"
style=
"margin: 10px 0;"
>
<!-- 允许存放物料名称已注释 -->
<!--
<el-row
:gutter=
"20"
style=
"margin: 10px 0;"
>
<el-col
:span=
"24"
>
<div><strong>
允许存放物料名称:
</strong>
{{
scope
.
row
.
allowedCategoryNames
||
'-'
}}
</div>
</el-col>
</el-row>
</el-row>
-->
</
template
>
</el-table-column>
<el-table-column
type=
"selection"
width=
"55"
align=
"center"
fixed
/>
<el-table-column
label=
"库位编码"
align=
"center"
prop=
"locationCode"
min-width=
"120"
fixed
/>
<el-table-column
label=
"库位名称"
align=
"center"
prop=
"locationName"
min-width=
"150"
/>
<!-- 仓库列已注释 -->
<!-- <el-table-column label="仓库" align="center" prop="warehousesName" width="180">
<template slot-scope="scope">
{{ scope.row.warehousesName }}
...
...
@@ -263,7 +266,8 @@
<el-table-column
label=
"库位容量(千克)"
align=
"center"
prop=
"capacity"
min-width=
"120"
/>
<el-table-column
label=
"体积容量(立方米)"
align=
"center"
prop=
"volumeCapacity"
min-width=
"120"
/>
<el-table-column
label=
"允许存放的危险等级"
align=
"center"
prop=
"allowedHazardLevels"
min-width=
"140"
/>
<el-table-column
label=
"允许存放的物料名称"
align=
"center"
prop=
"allowedCategoryNames"
min-width=
"200"
>
<!-- 允许存放物料名称列已注释 -->
<!-- <el-table-column label="允许存放的物料名称" align="center" prop="allowedCategoryNames" min-width="200">
<template slot-scope="scope">
<el-tooltip
:content="scope.row.allowedCategoryNames"
...
...
@@ -293,7 +297,7 @@
</div>
</el-tooltip>
</template>
</el-table-column>
</el-table-column>
-->
<el-table-column
label=
"温区"
align=
"center"
prop=
"temperatureZone"
width=
"100"
/>
<el-table-column
label=
"应用状态"
align=
"center"
prop=
"isEnabled"
width=
"100"
>
<
template
slot-scope=
"scope"
>
...
...
@@ -357,6 +361,7 @@
</el-form-item>
</el-col>
</el-row>
<!-- 仓库表单项已注释 -->
<!-- <el-form-item label="仓库" prop="warehouseId">
<el-input
v-model="form.warehouseName"
...
...
@@ -510,7 +515,8 @@
<el-input
v-model=
"form.allowedHazardLevels"
placeholder=
"请输入允许存放的危险等级"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<!-- 允许存放物料表单项已注释 -->
<!-- <el-col :span="12">
<el-form-item label="允许存放物料" prop="allowedCategoryIds">
<div style="display: flex; align-items: center; flex-direction: column; gap: 8px;">
<el-input
...
...
@@ -522,7 +528,7 @@
/>
</div>
</el-form-item>
</el-col>
</el-col>
-->
</el-row>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
...
...
@@ -549,8 +555,8 @@
</div>
</el-dialog>
<!-- 选择允许存放的物料对话框 -->
<el-dialog
<!-- 选择允许存放的物料对话框
已注释
-->
<
!-- <
el-dialog
title="选择允许存放的物料"
:visible.sync="showMaterialSelect"
width="1000px"
...
...
@@ -570,7 +576,7 @@
<el-button @click="handleMaterialSelectionCancel">取消</el-button>
<el-button type="primary" @click="confirmMaterialSelection">确认选择</el-button>
</div>
</el-dialog>
</el-dialog>
-->
<!-- 导入组件 -->
<import-excel
...
...
@@ -582,7 +588,7 @@
@
success=
"getList"
/>
<!-- 仓库选择器组件 -->
<!-- 仓库选择器组件
已注释
-->
<!-- <WarehouseSelector
v-model="warehouseSelectorVisible"
@selected="handleWarehouseSelected"
...
...
@@ -592,15 +598,19 @@
<
script
>
import
{
listLocations
,
getLocations
,
delLocations
,
addLocations
,
updateLocations
}
from
"@/api/inventory/locations"
import
{
listWarehouses
}
from
"@/api/inventory/warehouses"
import
materialsSeletor
from
"../../../components/materialsSeletor.vue"
// 仓库相关API已注释
// import { listWarehouses } from "@/api/inventory/warehouses"
// 物料选择器组件已注释
// import materialsSeletor from "../../../components/materialsSeletor.vue"
// import WarehouseSelector from "@/views/compononents/WarehouseSelector.vue"
import
ImportExcel
from
"@/components/ImportExcel/index"
import
{
listMaterials
}
from
"@/api/inventory/materials"
// 物料相关API已注释
// import { listMaterials } from "@/api/inventory/materials"
export
default
{
name
:
"Locations"
,
components
:
{
materialsSeletor
,
ImportExcel
},
// 组件注册已注释物料选择器
components
:
{
/* materialsSeletor, */
ImportExcel
},
dicts
:
[
'sys_normal_disable'
,
'location_type'
,
'location_usage'
,
'yorn'
,
'is_enabled'
],
data
()
{
return
{
...
...
@@ -620,7 +630,8 @@ export default {
pageSize
:
10
,
locationCode
:
null
,
locationName
:
null
,
warehouseId
:
null
,
// 仓库查询参数已注释
// warehouseId: null,
locationType
:
null
,
layerCode
:
null
,
locationUsage
:
null
,
...
...
@@ -634,8 +645,9 @@ export default {
id
:
null
,
locationCode
:
null
,
locationName
:
null
,
warehouseId
:
null
,
warehouseName
:
null
,
// 仓库相关字段已注释
// warehouseId: null,
// warehouseName: null,
locationType
:
null
,
zoneCode
:
null
,
rowCode
:
null
,
...
...
@@ -644,8 +656,9 @@ export default {
capacity
:
null
,
volumeCapacity
:
null
,
allowedHazardLevels
:
null
,
allowedCategoryIds
:
null
,
// 原materialCodes
allowedCategoryNames
:
null
,
// 原materialNames
// 物料分类相关字段已注释
// allowedCategoryIds: null, // 原materialCodes
// allowedCategoryNames: null, // 原materialNames
temperatureZone
:
null
,
isEnabled
:
1
,
isUsed
:
1
,
...
...
@@ -670,6 +683,7 @@ export default {
{
required
:
true
,
message
:
'库位名称不能为空'
,
trigger
:
'blur'
},
{
min
:
1
,
max
:
100
,
message
:
'库位名称长度不能超过100个字符'
,
trigger
:
'blur'
}
],
// 仓库验证规则已注释
// warehouseId: [
// { required: true, message: '仓库不能为空', trigger: 'change' }
// ],
...
...
@@ -690,170 +704,172 @@ export default {
]
},
// 仓库相关
warehouseList
:
[],
loadingWarehouse
:
false
,
queryWarehouseName
:
''
,
// 物料选择相关
showMaterialSelect
:
false
,
tempSelectedMaterials
:
{
materialCodes
:
[],
names
:
[],
categoryIds
:
[]
},
materialCodeToNameMap
:
{},
materialMapLoaded
:
false
,
// 仓库选择器相关
warehouseSelectorVisible
:
false
,
warehouseSelectTarget
:
''
,
// 仓库相关
数据已注释
//
warehouseList: [],
//
loadingWarehouse: false,
//
queryWarehouseName: '',
// 物料选择相关
数据已注释
//
showMaterialSelect: false,
//
tempSelectedMaterials: {
//
materialCodes: [],
//
names: [],
//
categoryIds: []
//
},
//
materialCodeToNameMap: {},
//
materialMapLoaded: false,
// 仓库选择器相关
数据已注释
//
warehouseSelectorVisible: false,
//
warehouseSelectTarget: '',
currentDetailItem
:
null
}
},
created
()
{
console
.
log
(
'【Locations组件】开始初始化'
)
this
.
getList
()
this
.
getWarehouseList
()
this
.
initMaterialCodeToNameMap
()
// 仓库列表加载已注释
// this.getWarehouseList()
// 物料映射表初始化已注释
// this.initMaterialCodeToNameMap()
},
methods
:
{
//
========== 新增:初始化物料选择器(核心修复数据残留) ==========
initMaterialSelector
()
{
console
.
log
(
'【初始化物料选择器】清空残留数据'
)
// 1. 清空临时选择数据(区分新增/修改)
this
.
tempSelectedMaterials
=
{
materialCodes
:
this
.
form
.
id
?
(
this
.
form
.
allowedCategoryIds
?
this
.
form
.
allowedCategoryIds
.
split
(
','
).
filter
(
u
=>
u
.
trim
())
:
[])
:
[],
names
:
this
.
form
.
id
?
(
this
.
form
.
allowedCategoryNames
?
this
.
form
.
allowedCategoryNames
.
split
(
','
).
filter
(
n
=>
n
.
trim
())
:
[])
:
[],
categoryIds
:
this
.
form
.
id
?
(
this
.
form
.
allowedCategoryIds
?
this
.
form
.
allowedCategoryIds
.
split
(
','
).
filter
(
c
=>
c
.
trim
())
:
[])
:
[]
}
// 2. 延迟打开弹窗,确保数据先清空
this
.
$nextTick
(()
=>
{
this
.
showMaterialSelect
=
true
// 3. 兼容子组件清空选中状态(如果有该方法)
if
(
this
.
$refs
.
materialsSeletor
&&
this
.
$refs
.
materialsSeletor
.
clearSelection
)
{
this
.
$refs
.
materialsSeletor
.
clearSelection
()
// 修改模式下重新设置选中值
if
(
this
.
form
.
id
)
{
this
.
$refs
.
materialsSeletor
.
setSelection
(
this
.
tempSelectedMaterials
.
materialCodes
)
}
}
})
},
// 清空查询仓库
clearQueryWarehouse
()
{
console
.
log
(
'【清空查询仓库】执行清空操作'
)
this
.
queryWarehouseName
=
''
this
.
queryParams
.
warehouseId
=
null
this
.
handleQuery
()
},
// 清空表单仓库
clearFormWarehouse
()
{
console
.
log
(
'【清空表单仓库】执行清空操作'
)
this
.
form
.
warehouseName
=
''
this
.
form
.
warehouseId
=
null
},
// 仓库选择回调
handleWarehouseSelected
(
warehouse
)
{
console
.
log
(
'【仓库选择回调】选中的仓库数据:'
,
warehouse
)
if
(
!
warehouse
)
return
const
warehouseId
=
warehouse
.
warehousesId
||
warehouse
.
warehouseId
||
warehouse
.
id
const
warehouseName
=
warehouse
.
warehousesName
||
warehouse
.
name
||
warehouse
.
warehouseName
if
(
this
.
warehouseSelectTarget
===
'query'
)
{
this
.
queryParams
.
warehouseId
=
warehouseId
this
.
queryWarehouseName
=
warehouseName
this
.
handleQuery
()
}
else
{
this
.
form
.
warehouseId
=
warehouseId
this
.
form
.
warehouseName
=
warehouseName
if
(
this
.
currentDetailItem
)
{
this
.
currentDetailItem
.
warehouseId
=
warehouseId
this
.
currentDetailItem
.
warehouseName
=
warehouseName
}
}
this
.
warehouseSelectorVisible
=
false
},
// 打开仓库选择器
openWarehouseSelector
(
target
=
'form'
)
{
console
.
log
(
'【打开仓库选择器】目标:'
,
target
)
this
.
warehouseSelectTarget
=
target
this
.
warehouseSelectorVisible
=
true
},
// 获取仓库列表
getWarehouseList
()
{
console
.
log
(
'【获取仓库列表】开始请求仓库数据'
)
this
.
loadingWarehouse
=
true
listWarehouses
({
pageNum
:
1
,
pageSize
:
1000
,
isUsed
:
1
}).
then
(
response
=>
{
console
.
log
(
'【获取仓库列表】请求成功,返回数据:'
,
response
)
this
.
warehouseList
=
response
.
rows
||
[]
this
.
loadingWarehouse
=
false
}).
catch
(
error
=>
{
console
.
error
(
'【获取仓库列表】请求失败:'
,
error
)
this
.
warehouseList
=
[]
this
.
loadingWarehouse
=
false
})
},
// 根据仓库ID获取仓库名称
getWarehouseNameById
(
warehouseId
)
{
console
.
log
(
'【根据仓库ID获取名称】仓库ID:'
,
warehouseId
)
if
(
!
warehouseId
)
return
'-'
const
warehouse
=
this
.
warehouseList
.
find
(
item
=>
item
.
warehousesId
===
warehouseId
||
item
.
warehouseId
===
warehouseId
||
item
.
id
===
warehouseId
)
const
warehouseName
=
warehouse
?
(
warehouse
.
warehousesName
||
warehouse
.
name
||
warehouse
.
warehouseName
||
'-'
)
:
'-'
console
.
log
(
'【根据仓库ID获取名称】匹配到的仓库名称:'
,
warehouseName
)
return
warehouseName
},
// 初始化物料编码-名称映射表
async
initMaterialCodeToNameMap
()
{
console
.
log
(
'【初始化物料映射表】开始加载物料数据'
)
try
{
this
.
materialMapLoaded
=
true
let
pageNum
=
1
const
pageSize
=
1000
let
hasMore
=
true
this
.
materialCodeToNameMap
=
{}
while
(
hasMore
)
{
console
.
log
(
`【初始化物料映射表】请求第
${
pageNum
}
页物料数据,每页
${
pageSize
}
条`
)
const
response
=
await
listMaterials
({
pageNum
,
pageSize
,
isUsed
:
1
,
materialCode
:
null
,
materialName
:
null
})
if
(
response
.
rows
&&
response
.
rows
.
length
)
{
console
.
log
(
`【初始化物料映射表】第
${
pageNum
}
页返回
${
response
.
rows
.
length
}
条物料数据`
)
response
.
rows
.
forEach
(
item
=>
{
if
(
item
.
materialCode
&&
item
.
materialName
)
{
const
code
=
item
.
materialCode
.
trim
().
toUpperCase
()
this
.
materialCodeToNameMap
[
code
]
=
item
.
materialName
}
})
hasMore
=
pageNum
*
pageSize
<
response
.
total
pageNum
++
}
else
{
hasMore
=
false
}
}
console
.
log
(
'【初始化物料映射表】完成,映射表长度:'
,
Object
.
keys
(
this
.
materialCodeToNameMap
).
length
)
}
catch
(
error
)
{
console
.
error
(
'【初始化物料映射表】失败:'
,
error
)
this
.
materialMapLoaded
=
false
this
.
$modal
.
msgError
(
'物料数据加载失败,请刷新页面重试!'
)
}
},
//
物料选择器初始化已注释
//
initMaterialSelector() {
//
console.log('【初始化物料选择器】清空残留数据')
//
// 1. 清空临时选择数据(区分新增/修改)
//
this.tempSelectedMaterials = {
//
materialCodes: this.form.id ? (this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(u => u.trim()) : []) : [],
//
names: this.form.id ? (this.form.allowedCategoryNames ? this.form.allowedCategoryNames.split(',').filter(n => n.trim()) : []) : [],
//
categoryIds: this.form.id ? (this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(c => c.trim()) : []) : []
//
}
//
// 2. 延迟打开弹窗,确保数据先清空
//
this.$nextTick(() => {
//
this.showMaterialSelect = true
//
// 3. 兼容子组件清空选中状态(如果有该方法)
//
if (this.$refs.materialsSeletor && this.$refs.materialsSeletor.clearSelection) {
//
this.$refs.materialsSeletor.clearSelection()
//
// 修改模式下重新设置选中值
//
if (this.form.id) {
//
this.$refs.materialsSeletor.setSelection(this.tempSelectedMaterials.materialCodes)
//
}
//
}
//
})
//
},
// 清空查询仓库
已注释
//
clearQueryWarehouse() {
//
console.log('【清空查询仓库】执行清空操作')
//
this.queryWarehouseName = ''
//
this.queryParams.warehouseId = null
//
this.handleQuery()
//
},
// 清空表单仓库
已注释
//
clearFormWarehouse() {
//
console.log('【清空表单仓库】执行清空操作')
//
this.form.warehouseName = ''
//
this.form.warehouseId = null
//
},
// 仓库选择回调
已注释
//
handleWarehouseSelected(warehouse) {
//
console.log('【仓库选择回调】选中的仓库数据:', warehouse)
//
if (!warehouse) return
//
const warehouseId = warehouse.warehousesId || warehouse.warehouseId || warehouse.id
//
const warehouseName = warehouse.warehousesName || warehouse.name || warehouse.warehouseName
//
if (this.warehouseSelectTarget === 'query') {
//
this.queryParams.warehouseId = warehouseId
//
this.queryWarehouseName = warehouseName
//
this.handleQuery()
//
} else {
//
this.form.warehouseId = warehouseId
//
this.form.warehouseName = warehouseName
//
if (this.currentDetailItem) {
//
this.currentDetailItem.warehouseId = warehouseId
//
this.currentDetailItem.warehouseName = warehouseName
//
}
//
}
//
this.warehouseSelectorVisible = false
//
},
// 打开仓库选择器
已注释
//
openWarehouseSelector(target = 'form') {
//
console.log('【打开仓库选择器】目标:', target)
//
this.warehouseSelectTarget = target
//
this.warehouseSelectorVisible = true
//
},
// 获取仓库列表
已注释
//
getWarehouseList() {
//
console.log('【获取仓库列表】开始请求仓库数据')
//
this.loadingWarehouse = true
//
listWarehouses({ pageNum: 1, pageSize: 1000, isUsed: 1 }).then(response => {
//
console.log('【获取仓库列表】请求成功,返回数据:', response)
//
this.warehouseList = response.rows || []
//
this.loadingWarehouse = false
//
}).catch(error => {
//
console.error('【获取仓库列表】请求失败:', error)
//
this.warehouseList = []
//
this.loadingWarehouse = false
//
})
//
},
// 根据仓库ID获取仓库名称
已注释
//
getWarehouseNameById(warehouseId) {
//
console.log('【根据仓库ID获取名称】仓库ID:', warehouseId)
//
if (!warehouseId) return '-'
//
const warehouse = this.warehouseList.find(item =>
//
item.warehousesId === warehouseId || item.warehouseId === warehouseId || item.id === warehouseId
//
)
//
const warehouseName = warehouse ? (warehouse.warehousesName || warehouse.name || warehouse.warehouseName || '-') : '-'
//
console.log('【根据仓库ID获取名称】匹配到的仓库名称:', warehouseName)
//
return warehouseName
//
},
// 初始化物料编码-名称映射表
已注释
//
async initMaterialCodeToNameMap() {
//
console.log('【初始化物料映射表】开始加载物料数据')
//
try {
//
this.materialMapLoaded = true
//
let pageNum = 1
//
const pageSize = 1000
//
let hasMore = true
//
this.materialCodeToNameMap = {}
//
while (hasMore) {
//
console.log(`【初始化物料映射表】请求第${pageNum}页物料数据,每页${pageSize}条`)
//
const response = await listMaterials({
//
pageNum,
//
pageSize,
//
isUsed: 1,
//
materialCode: null,
//
materialName: null
//
})
//
if (response.rows && response.rows.length) {
//
console.log(`【初始化物料映射表】第${pageNum}页返回${response.rows.length}条物料数据`)
//
response.rows.forEach(item => {
//
if (item.materialCode && item.materialName) {
//
const code = item.materialCode.trim().toUpperCase()
//
this.materialCodeToNameMap[code] = item.materialName
//
}
//
})
//
hasMore = pageNum * pageSize
<
response
.
total
//
pageNum++
//
} else {
//
hasMore = false
//
}
//
}
//
console.log('【初始化物料映射表】完成,映射表长度:', Object.keys(this.materialCodeToNameMap).length)
//
} catch (error) {
//
console.error('【初始化物料映射表】失败:', error)
//
this.materialMapLoaded = false
//
this.$modal.msgError('物料数据加载失败,请刷新页面重试!')
//
}
//
},
// 行点击事件
handleRowClick
(
row
,
event
,
column
)
{
...
...
@@ -870,7 +886,8 @@ export default {
const
params
=
{
...
this
.
queryParams
,
isUsed
:
1
,
warehousesId
:
this
.
queryParams
.
warehouseId
,
// 仓库ID参数已注释
// warehousesId: this.queryParams.warehouseId,
warehouseId
:
undefined
}
console
.
log
(
'【获取库位列表】最终请求参数:'
,
params
)
...
...
@@ -902,7 +919,8 @@ export default {
pageSize
:
10
,
locationCode
:
null
,
locationName
:
null
,
warehouseId
:
null
,
// 仓库查询参数已注释
// warehouseId: null,
locationType
:
null
,
layerCode
:
null
,
locationUsage
:
null
,
...
...
@@ -910,7 +928,8 @@ export default {
zoneCode
:
null
,
pickingArea
:
null
}
this
.
queryWarehouseName
=
''
// 仓库名称重置已注释
// this.queryWarehouseName = ''
this
.
getList
()
},
...
...
@@ -950,73 +969,76 @@ export default {
// 映射后端字段到前端
const
formData
=
{
...
rowData
,
warehouseId
:
rowData
.
warehousesId
||
rowData
.
warehouseId
||
rowData
.
id
,
// 仓库相关字段映射已注释
// warehouseId: rowData.warehousesId || rowData.warehouseId || rowData.id,
warehousesId
:
undefined
}
this
.
form
=
JSON
.
parse
(
JSON
.
stringify
(
formData
))
// 设置仓库名称
if
(
this
.
form
.
warehouseId
)
{
this
.
form
.
warehouseName
=
this
.
getWarehouseNameById
(
this
.
form
.
warehouseId
)
}
// 设置仓库名称
已注释
//
if (this.form.warehouseId) {
//
this.form.warehouseName = this.getWarehouseNameById(this.form.warehouseId)
//
}
await
this
.
initMaterialCodeToNameMap
()
// 物料映射表初始化已注释
// await this.initMaterialCodeToNameMap()
// 物料相关处理已注释
// 处理物料编码和名称(支持数组或字符串格式)
let
materialCodes
=
[]
let
materialNames
=
[]
// 优先从allowedCategoryIds数组读取(原materialIds)
if
(
Array
.
isArray
(
rowData
.
allowedCategoryIds
)
&&
rowData
.
allowedCategoryIds
.
length
)
{
materialCodes
=
rowData
.
allowedCategoryIds
.
filter
(
code
=>
code
&&
code
.
trim
())
.
map
(
code
=>
code
.
trim
().
toUpperCase
())
.
filter
((
code
,
index
,
self
)
=>
self
.
indexOf
(
code
)
===
index
)
}
// 兼容字符串格式
else
if
(
rowData
.
allowedCategoryIds
)
{
materialCodes
=
rowData
.
allowedCategoryIds
.
split
(
','
)
.
filter
(
code
=>
code
&&
code
.
trim
())
.
map
(
code
=>
code
.
trim
().
toUpperCase
())
.
filter
((
code
,
index
,
self
)
=>
self
.
indexOf
(
code
)
===
index
)
}
// 处理物料名称
if
(
Array
.
isArray
(
rowData
.
allowedCategoryNames
)
&&
rowData
.
allowedCategoryNames
.
length
)
{
materialNames
=
rowData
.
allowedCategoryNames
.
filter
(
name
=>
name
&&
name
.
trim
())
.
filter
((
name
,
index
,
self
)
=>
self
.
indexOf
(
name
)
===
index
)
}
else
if
(
rowData
.
allowedCategoryNames
)
{
materialNames
=
rowData
.
allowedCategoryNames
.
split
(
','
)
.
filter
(
name
=>
name
&&
name
.
trim
())
.
filter
((
name
,
index
,
self
)
=>
self
.
indexOf
(
name
)
===
index
)
}
// 兜底:通过物料编码映射名称
else
if
(
materialCodes
.
length
)
{
materialNames
=
materialCodes
.
map
(
code
=>
{
return
this
.
materialCodeToNameMap
[
code
]
||
`【未匹配】
${
code
}
`
})
}
// 处理分类ID(现在存储的是物料编码)
let
categoryIds
=
materialCodes
// 更新表单数据
this
.
form
.
allowedCategoryIds
=
materialCodes
.
join
(
','
)
this
.
form
.
allowedCategoryNames
=
materialNames
.
join
(
','
)
// 更新临时选择数据
this
.
tempSelectedMaterials
=
{
materialCodes
:
materialCodes
,
names
:
materialNames
,
categoryIds
:
categoryIds
}
console
.
log
(
'【修改库位】处理后的物料数据:'
,
{
allowedCategoryIds
:
this
.
form
.
allowedCategoryIds
,
allowedCategoryNames
:
this
.
form
.
allowedCategoryNames
})
//
let materialCodes = []
//
let materialNames = []
//
//
优先从allowedCategoryIds数组读取(原materialIds)
//
if (Array.isArray(rowData.allowedCategoryIds) && rowData.allowedCategoryIds.length) {
//
materialCodes = rowData.allowedCategoryIds
//
.filter(code => code && code.trim())
//
.map(code => code.trim().toUpperCase())
//
.filter((code, index, self) => self.indexOf(code) === index)
//
}
//
//
兼容字符串格式
//
else if (rowData.allowedCategoryIds) {
//
materialCodes = rowData.allowedCategoryIds.split(',')
//
.filter(code => code && code.trim())
//
.map(code => code.trim().toUpperCase())
//
.filter((code, index, self) => self.indexOf(code) === index)
//
}
//
//
处理物料名称
//
if (Array.isArray(rowData.allowedCategoryNames) && rowData.allowedCategoryNames.length) {
//
materialNames = rowData.allowedCategoryNames
//
.filter(name => name && name.trim())
//
.filter((name, index, self) => self.indexOf(name) === index)
//
}
//
else if (rowData.allowedCategoryNames) {
//
materialNames = rowData.allowedCategoryNames.split(',')
//
.filter(name => name && name.trim())
//
.filter((name, index, self) => self.indexOf(name) === index)
//
}
//
//
兜底:通过物料编码映射名称
//
else if (materialCodes.length) {
//
materialNames = materialCodes.map(code => {
//
return this.materialCodeToNameMap[code] || `【未匹配】${code}`
//
})
//
}
//
//
处理分类ID(现在存储的是物料编码)
//
let categoryIds = materialCodes
//
//
更新表单数据
//
this.form.allowedCategoryIds = materialCodes.join(',')
//
this.form.allowedCategoryNames = materialNames.join(',')
//
//
更新临时选择数据
//
this.tempSelectedMaterials = {
//
materialCodes: materialCodes,
//
names: materialNames,
//
categoryIds: categoryIds
//
}
//
console.log('【修改库位】处理后的物料数据:', {
//
allowedCategoryIds: this.form.allowedCategoryIds,
//
allowedCategoryNames: this.form.allowedCategoryNames
//
})
this
.
open
=
true
this
.
title
=
"修改库位"
...
...
@@ -1032,24 +1054,26 @@ export default {
this
.
$refs
[
"form"
].
validate
(
valid
=>
{
if
(
valid
)
{
console
.
log
(
'【提交表单】表单验证通过,开始格式化数据'
)
// 物料字段格式化已注释
// 格式化物料相关字段(去重、过滤空值)
const
formatField
=
(
value
)
=>
{
if
(
!
value
)
return
''
const
result
=
value
.
split
(
','
)
.
filter
(
item
=>
item
&&
item
.
trim
())
.
filter
((
item
,
index
,
self
)
=>
self
.
indexOf
(
item
)
===
index
)
.
join
(
','
)
console
.
log
(
`【提交表单】格式化字段值 "
${
value
}
" 结果: "
${
result
}
"`
)
return
result
}
this
.
form
.
allowedCategoryIds
=
formatField
(
this
.
form
.
allowedCategoryIds
)
this
.
form
.
allowedCategoryNames
=
formatField
(
this
.
form
.
allowedCategoryNames
)
//
const formatField = (value) => {
//
if (!value) return ''
//
const result = value.split(',')
//
.filter(item => item && item.trim())
//
.filter((item, index, self) => self.indexOf(item) === index)
//
.join(',')
//
console.log(`【提交表单】格式化字段值 "${value}" 结果: "${result}"`)
//
return result
//
}
//
this.form.allowedCategoryIds = formatField(this.form.allowedCategoryIds)
//
this.form.allowedCategoryNames = formatField(this.form.allowedCategoryNames)
// 转换表单数据
const
submitData
=
{
...
this
.
form
,
warehousesId
:
this
.
form
.
warehouseId
,
// 仓库ID映射已注释
// warehousesId: this.form.warehouseId,
warehouseId
:
undefined
,
warehouseName
:
undefined
}
...
...
@@ -1100,76 +1124,77 @@ export default {
console
.
log
(
'【导出库位】执行导出操作,查询参数:'
,
this
.
queryParams
)
const
exportParams
=
{
...
this
.
queryParams
,
warehousesId
:
this
.
queryParams
.
warehouseId
,
// 仓库ID参数已注释
// warehousesId: this.queryParams.warehouseId,
warehouseId
:
undefined
}
console
.
log
(
'【导出库位】最终导出参数:'
,
exportParams
)
this
.
download
(
'inventory/locations/export'
,
exportParams
,
`locations_
${
new
Date
().
getTime
()}
.xlsx`
)
},
// 物料选择变化
handleMaterialSelectionChange
(
selectedData
)
{
console
.
log
(
'【物料选择变化】接收到的选择数据:'
,
selectedData
)
// 修复:从selectedData中取materialIds(而非materialCodes)
const
materialCodes
=
(
selectedData
.
materialIds
||
[])
.
filter
(
code
=>
code
&&
code
.
trim
())
.
map
(
code
=>
code
.
trim
().
toUpperCase
())
.
filter
((
code
,
index
,
self
)
=>
self
.
indexOf
(
code
)
===
index
)
// 物料名称取selectedData.names
const
names
=
(
selectedData
.
names
||
[])
.
filter
(
name
=>
name
&&
name
.
trim
())
.
filter
((
name
,
index
,
self
)
=>
self
.
indexOf
(
name
)
===
index
)
// 分类ID取selectedData.categoryIds(现在存储的是物料编码)
const
categoryIds
=
materialCodes
this
.
tempSelectedMaterials
=
{
materialCodes
,
names
,
categoryIds
}
console
.
log
(
'【物料选择变化】处理后的临时选择数据:'
,
this
.
tempSelectedMaterials
)
},
// 取消物料选择
handleMaterialSelectionCancel
()
{
console
.
log
(
'【取消物料选择】执行取消操作,恢复原有选择状态'
)
this
.
showMaterialSelect
=
false
// 恢复原有选择状态
this
.
tempSelectedMaterials
=
{
materialCodes
:
this
.
form
.
allowedCategoryIds
?
this
.
form
.
allowedCategoryIds
.
split
(
','
).
filter
(
u
=>
u
.
trim
())
:
[],
names
:
this
.
form
.
allowedCategoryNames
?
this
.
form
.
allowedCategoryNames
.
split
(
','
).
filter
(
n
=>
n
.
trim
())
:
[],
categoryIds
:
this
.
form
.
allowedCategoryIds
?
this
.
form
.
allowedCategoryIds
.
split
(
','
).
filter
(
c
=>
c
.
trim
())
:
[]
}
console
.
log
(
'【取消物料选择】恢复后的临时选择数据:'
,
this
.
tempSelectedMaterials
)
},
// 确认物料选择
confirmMaterialSelection
()
{
console
.
log
(
'【确认物料选择】当前临时选择数据:'
,
this
.
tempSelectedMaterials
)
// 修复:判断tempSelectedMaterials.materialCodes是否有值
if
(
!
this
.
tempSelectedMaterials
.
materialCodes
.
length
)
{
console
.
warn
(
'【确认物料选择】未选择任何物料,提示用户'
)
this
.
$modal
.
msgWarning
(
'请至少选择一个物料!'
)
return
}
// 更新表单数据(确保去重和过滤)
this
.
form
.
allowedCategoryIds
=
this
.
tempSelectedMaterials
.
materialCodes
.
join
(
','
)
this
.
form
.
allowedCategoryNames
=
this
.
tempSelectedMaterials
.
names
.
join
(
','
)
console
.
log
(
'【确认物料选择】更新后的表单物料数据:'
,
{
allowedCategoryIds
:
this
.
form
.
allowedCategoryIds
,
allowedCategoryNames
:
this
.
form
.
allowedCategoryNames
})
this
.
showMaterialSelect
=
false
this
.
$modal
.
msgSuccess
(
`成功选择
${
this
.
tempSelectedMaterials
.
names
.
length
}
个物料`
)
},
// 物料选择变化
已注释
//
handleMaterialSelectionChange(selectedData) {
//
console.log('【物料选择变化】接收到的选择数据:', selectedData)
//
// 修复:从selectedData中取materialIds(而非materialCodes)
//
const materialCodes = (selectedData.materialIds || [])
//
.filter(code => code && code.trim())
//
.map(code => code.trim().toUpperCase())
//
.filter((code, index, self) => self.indexOf(code) === index)
//
// 物料名称取selectedData.names
//
const names = (selectedData.names || [])
//
.filter(name => name && name.trim())
//
.filter((name, index, self) => self.indexOf(name) === index)
//
// 分类ID取selectedData.categoryIds(现在存储的是物料编码)
//
const categoryIds = materialCodes
//
this.tempSelectedMaterials = {
//
materialCodes,
//
names,
//
categoryIds
//
}
//
console.log('【物料选择变化】处理后的临时选择数据:', this.tempSelectedMaterials)
//
},
// 取消物料选择
已注释
//
handleMaterialSelectionCancel() {
//
console.log('【取消物料选择】执行取消操作,恢复原有选择状态')
//
this.showMaterialSelect = false
//
// 恢复原有选择状态
//
this.tempSelectedMaterials = {
//
materialCodes: this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(u => u.trim()) : [],
//
names: this.form.allowedCategoryNames ? this.form.allowedCategoryNames.split(',').filter(n => n.trim()) : [],
//
categoryIds: this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(c => c.trim()) : []
//
}
//
console.log('【取消物料选择】恢复后的临时选择数据:', this.tempSelectedMaterials)
//
},
// 确认物料选择
已注释
//
confirmMaterialSelection() {
//
console.log('【确认物料选择】当前临时选择数据:', this.tempSelectedMaterials)
//
// 修复:判断tempSelectedMaterials.materialCodes是否有值
//
if (!this.tempSelectedMaterials.materialCodes.length) {
//
console.warn('【确认物料选择】未选择任何物料,提示用户')
//
this.$modal.msgWarning('请至少选择一个物料!')
//
return
//
}
//
// 更新表单数据(确保去重和过滤)
//
this.form.allowedCategoryIds = this.tempSelectedMaterials.materialCodes.join(',')
//
this.form.allowedCategoryNames = this.tempSelectedMaterials.names.join(',')
//
console.log('【确认物料选择】更新后的表单物料数据:', {
//
allowedCategoryIds: this.form.allowedCategoryIds,
//
allowedCategoryNames: this.form.allowedCategoryNames
//
})
//
this.showMaterialSelect = false
//
this.$modal.msgSuccess(`成功选择 ${this.tempSelectedMaterials.names.length} 个物料`)
//
},
// 导入库位
handleImport
()
{
...
...
@@ -1184,8 +1209,9 @@ export default {
id
:
null
,
locationCode
:
null
,
locationName
:
null
,
warehouseId
:
null
,
warehouseName
:
null
,
// 仓库相关字段已注释
// warehouseId: null,
// warehouseName: null,
locationType
:
null
,
zoneCode
:
null
,
rowCode
:
null
,
...
...
@@ -1194,8 +1220,9 @@ export default {
capacity
:
null
,
volumeCapacity
:
null
,
allowedHazardLevels
:
null
,
allowedCategoryIds
:
null
,
// 原materialCodes
allowedCategoryNames
:
null
,
// 原materialNames
// 物料分类相关字段已注释
// allowedCategoryIds: null, // 原materialCodes
// allowedCategoryNames: null, // 原materialNames
temperatureZone
:
null
,
isEnabled
:
1
,
isUsed
:
1
,
...
...
@@ -1209,15 +1236,16 @@ export default {
allowMixedProducts
:
null
,
allowMixedBatches
:
null
}
this
.
tempSelectedMaterials
=
{
materialCodes
:
[],
names
:
[],
categoryIds
:
[]
}
// 修复:清空物料选择器残留
if
(
this
.
$refs
.
materialsSeletor
&&
this
.
$refs
.
materialsSeletor
.
clearSelection
)
{
this
.
$refs
.
materialsSeletor
.
clearSelection
()
}
// 物料临时数据重置已注释
// this.tempSelectedMaterials = {
// materialCodes: [],
// names: [],
// categoryIds: []
// }
// 物料选择器清空已注释
// if (this.$refs.materialsSeletor && this.$refs.materialsSeletor.clearSelection) {
// this.$refs.materialsSeletor.clearSelection()
// }
if
(
this
.
$refs
.
form
)
{
this
.
$refs
.
form
.
resetFields
()
}
...
...
ruoyi-admin-vue/src/views/inventory/orders/index.vue
View file @
f7de2ca4
...
...
@@ -78,19 +78,23 @@
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"出库类型"
prop=
"orderTypeId"
>
<el-input
v-model=
"queryParams.orderTypeId"
placeholder=
"请输入出库类型"
<!-- 【保留位置】时间段选择器固定在第三个位置 -->
<el-form-item
label=
"时间段"
prop=
"dateRange"
>
<el-date-picker
clearable
@
keyup
.
enter
.
native=
"handleQuery"
v-model=
"queryParams.dateRange"
type=
"daterange"
range-separator=
"至"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
value-format=
"yyyy-MM-dd"
style=
"width: 100%"
/>
</el-form-item>
<!-- 新增:订单类型查询项 -->
<el-form-item
label=
"订单类型"
prop=
"orderType"
>
<el-form-item
label=
"出库类型"
prop=
"orderTypeId"
>
<el-select
v-model=
"queryParams.orderType"
placeholder=
"请
选择订单
类型"
v-model=
"queryParams.orderType
Id
"
placeholder=
"请
输入出库
类型"
clearable
style=
"width: 100%"
>
...
...
@@ -102,6 +106,7 @@
/>
</el-select>
</el-form-item>
<el-form-item
label=
"批次"
prop=
"batchCode"
>
<el-input
v-model=
"queryParams.batchCode"
...
...
@@ -110,19 +115,6 @@
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<!-- 【核心修改1】出库日期改为时间段选择器 -->
<el-form-item
label=
"时间段"
prop=
"dateRange"
>
<el-date-picker
clearable
v-model=
"queryParams.dateRange"
type=
"daterange"
range-separator=
"至"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
value-format=
"yyyy-MM-dd"
style=
"width: 100%"
/>
</el-form-item>
<el-form-item
label=
"订单状态"
prop=
"orderStatus"
>
<el-select
v-model=
"queryParams.orderStatus"
...
...
@@ -617,7 +609,7 @@ export default {
warehouseId
:
null
,
ownerId
:
null
,
orderStatus
:
null
,
dateRange
:
null
,
// 日期范围选择器绑定
dateRange
:
null
,
// 日期范围选择器绑定
(固定在第三个搜索位置)
startDate
:
null
,
// 开始日期
endDate
:
null
,
// 结束日期
destination
:
null
,
...
...
@@ -1241,7 +1233,7 @@ export default {
warehouseId
:
null
,
ownerId
:
null
,
orderStatus
:
null
,
dateRange
:
null
,
// 重置日期范围
dateRange
:
null
,
// 重置日期范围
(固定在第三个位置)
startDate
:
null
,
endDate
:
null
,
destination
:
null
,
...
...
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/OutboundOrdersServiceImpl.java
View file @
f7de2ca4
...
...
@@ -24,7 +24,6 @@ import org.springframework.transaction.annotation.Transactional;
import
org.springframework.util.CollectionUtils
;
import
java.util.*
;
import
java.util.concurrent.CompletableFuture
;
import
java.util.stream.Collectors
;
/**
...
...
@@ -35,6 +34,7 @@ import java.util.stream.Collectors;
* 3. 无库位明细拆分精准匹配实际扣减的库存ID+数量
* 4. 缓存与数据库实时同步,解决数据不一致问题
* 5. 合并/扣减/拆分逻辑完全对齐维度,杜绝数据错乱
* 6. 核心:扣减哪个库存ID就提取哪个,精准赋值到明细
*
* @author ruoyi
* @date 2025-12-03
...
...
@@ -187,11 +187,11 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
}
/**
* 核心库存扣减逻辑(
最终适配版
)
*
1. 扣减维度:物料ID+库存类型+库位
ID
*
2. 相同维度多库存:按数量从多到少遍历扣减,支持全部扣完
* 3. 无库位→有库位:自动匹配所有可用库位库存,精准扣减
*
4. 扣减记录按单库存ID生成,支持后续明细精准拆分
* 核心库存扣减逻辑(
精准提取被扣减的库存ID
)
*
核心:扣减哪个库存ID就提取哪个,仅保留实际被扣减的
ID
*
/
/**
*
核心库存扣减逻辑(确保每个明细仅对应一个库存ID)
*/
private
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
deductInventory
(
List
<
OutboundOrderItems
>
outboundOrderItems
,
String
updateUser
,
Date
updateTime
)
{
if
(
CollectionUtils
.
isEmpty
(
outboundOrderItems
))
{
...
...
@@ -199,11 +199,8 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
}
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
deductRecordMap
=
new
HashMap
<>();
// 预加载库存:按「物料ID+库存类型+库位ID」分组,保存所有库存对象
Map
<
String
,
List
<
Inventory
>>
inventoryGroupMap
=
this
.
loadInventoryGroupMap
();
Map
<
String
,
Long
>
deductQtyMap
=
this
.
buildDeductQtyMap
(
outboundOrderItems
);
// 库存更新Map(最终去重,保留最终状态)
Map
<
String
,
Inventory
>
toUpdateInventoryMap
=
new
LinkedHashMap
<>();
for
(
Map
.
Entry
<
String
,
Long
>
entry
:
deductQtyMap
.
entrySet
())
{
...
...
@@ -222,15 +219,12 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
.
orElse
(
null
);
Long
remainDeductQty
=
totalDeductQty
;
// 核心:按维度分组扣减(先无库位,后有库位)
List
<
Map
<
String
,
Object
>>
tempDeductRecords
=
new
ArrayList
<>();
if
(
StringUtils
.
isBlank
(
locationId
))
{
// 步骤1:扣无库位库存(同维度所有库存)
String
noLocKey
=
buildInventoryKey
(
materialId
,
""
,
inventoryType
);
remainDeductQty
=
deductByInventoryGroup
(
noLocKey
,
remainDeductQty
,
updateUser
,
updateTime
,
inventoryGroupMap
,
toUpdateInventoryMap
,
tempDeductRecords
);
// 步骤2:无库位不足,扣同物料+库存类型的所有有库位库存
if
(
remainDeductQty
>
0
)
{
List
<
String
>
hasLocKeys
=
inventoryGroupMap
.
keySet
().
stream
()
.
filter
(
k
->
{
...
...
@@ -242,7 +236,6 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
})
.
collect
(
Collectors
.
toList
());
// 有库位库存按总数量从多到少排序(优先扣减库存充足的库位)
hasLocKeys
.
sort
((
k1
,
k2
)
->
{
Long
qty1
=
inventoryGroupMap
.
get
(
k1
).
stream
().
mapToLong
(
inv
->
Optional
.
ofNullable
(
inv
.
getQuantity
()).
orElse
(
0L
)).
sum
();
Long
qty2
=
inventoryGroupMap
.
get
(
k2
).
stream
().
mapToLong
(
inv
->
Optional
.
ofNullable
(
inv
.
getQuantity
()).
orElse
(
0L
)).
sum
();
...
...
@@ -255,12 +248,10 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
}
}
}
else
{
// 有库位:扣指定维度库存
String
targetKey
=
buildInventoryKey
(
materialId
,
locationId
,
inventoryType
);
remainDeductQty
=
deductByInventoryGroup
(
targetKey
,
remainDeductQty
,
updateUser
,
updateTime
,
inventoryGroupMap
,
toUpdateInventoryMap
,
tempDeductRecords
);
}
// 步骤3:剩余数量强制扣减(允许库存负数)
if
(
remainDeductQty
>
0
&&
!
tempDeductRecords
.
isEmpty
())
{
Map
<
String
,
Object
>
lastRecord
=
tempDeductRecords
.
get
(
tempDeductRecords
.
size
()
-
1
);
String
lastInvId
=
(
String
)
lastRecord
.
get
(
"inventoryId"
);
...
...
@@ -269,34 +260,28 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
throw
new
ServiceException
(
String
.
format
(
"物料[%s]库存类型[%s]扣减负数时未找到目标库存"
,
materialId
,
inventoryType
));
}
// 累计扣减负数数量
lastInv
.
setQuantity
(
lastInv
.
getQuantity
()
-
remainDeductQty
);
lastInv
.
setInventoryStatus
(
0L
);
lastInv
.
setUpdateBy
(
updateUser
);
lastInv
.
setUpdateTime
(
updateTime
);
toUpdateInventoryMap
.
put
(
lastInvId
,
lastInv
);
// 更新扣减记录
lastRecord
.
put
(
"deductQty"
,
(
Long
)
lastRecord
.
get
(
"deductQty"
)
+
remainDeductQty
);
remainDeductQty
=
0L
;
}
// 步骤4:按明细ID归集扣减记录(不合并,保持单库存ID粒度)
if
(
itemId
!=
null
&&
!
tempDeductRecords
.
isEmpty
())
{
deductRecordMap
.
put
(
itemId
,
tempDeductRecords
);
}
// 校验扣减完成
if
(
remainDeductQty
>
0
)
{
throw
new
ServiceException
(
String
.
format
(
"物料[%s]库存类型[%s]扣减失败,剩余%d数量未扣减"
,
materialId
,
inventoryType
,
remainDeductQty
));
}
}
// 批量更新库存 + 刷新缓存
if
(!
toUpdateInventoryMap
.
isEmpty
())
{
List
<
Inventory
>
needUpdateList
=
new
ArrayList
<>(
toUpdateInventoryMap
.
values
());
inventoryMapper
.
batchUpdateInventory
(
needUpdateList
);
// 刷新缓存:删除旧缓存,重新加载
needUpdateList
.
forEach
(
inv
->
{
String
cacheKey
=
buildInventoryKey
(
inv
.
getMaterialId
(),
inv
.
getLocationId
(),
inv
.
getInventoryType
().
toString
());
InventoryCache
.
removeInventory
(
cacheKey
,
inv
.
getId
());
...
...
@@ -304,13 +289,105 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
});
}
// 核心修改:不再拼接ID,而是直接拆分为单ID明细
splitToSingleInvIdItems
(
outboundOrderItems
,
deductRecordMap
,
updateUser
,
updateTime
);
return
deductRecordMap
;
}
private
void
splitToSingleInvIdItems
(
List
<
OutboundOrderItems
>
oldItems
,
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
deductRecordMap
,
String
updateUser
,
Date
updateTime
)
{
if
(
CollectionUtils
.
isEmpty
(
oldItems
)
||
CollectionUtils
.
isEmpty
(
deductRecordMap
))
{
return
;
}
List
<
OutboundOrderItems
>
newSingleItems
=
new
ArrayList
<>();
Set
<
String
>
orderIdSet
=
new
HashSet
<>();
for
(
OutboundOrderItems
oldItem
:
oldItems
)
{
String
oldItemId
=
oldItem
.
getId
();
List
<
Map
<
String
,
Object
>>
deductRecords
=
deductRecordMap
.
get
(
oldItemId
);
if
(
CollectionUtils
.
isEmpty
(
deductRecords
))
{
continue
;
}
orderIdSet
.
add
(
oldItem
.
getOutboundOrderId
());
// 每一条扣减记录对应一个新明细(单库存ID)
for
(
Map
<
String
,
Object
>
rec
:
deductRecords
)
{
String
inventoryId
=
(
String
)
rec
.
get
(
"inventoryId"
);
String
locationId
=
(
String
)
rec
.
get
(
"locationId"
);
Long
deductQty
=
(
Long
)
rec
.
get
(
"deductQty"
);
if
(
deductQty
<=
0
||
StringUtils
.
isBlank
(
inventoryId
))
{
continue
;
}
OutboundOrderItems
newItem
=
new
OutboundOrderItems
();
BeanUtils
.
copyProperties
(
oldItem
,
newItem
);
newItem
.
setId
(
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
));
// 新主键
newItem
.
setInventoryId
(
inventoryId
);
// 仅单个库存ID(无逗号)
newItem
.
setLocationId
(
locationId
);
// 同步库位
newItem
.
setActualQuantity
(
deductQty
);
// 仅当前库存ID的扣减数量
newItem
.
setUpdateBy
(
updateUser
);
newItem
.
setUpdateTime
(
updateTime
);
newSingleItems
.
add
(
newItem
);
}
}
// 删除原明细,插入拆分后的单ID明细
if
(!
orderIdSet
.
isEmpty
()
&&
!
newSingleItems
.
isEmpty
())
{
// 1. 删除原明细
orderIdSet
.
forEach
(
orderId
->
outboundOrderItemsMapper
.
deleteOutboundOrderItemsByOrderId
(
orderId
));
// 2. 插入单ID明细
outboundOrderItemsMapper
.
batchInsertOutboundOrderItems
(
newSingleItems
);
// 3. 更新日志(同步单ID明细)
List
<
OutboundOrderLog
>
logList
=
newSingleItems
.
stream
().
map
(
item
->
{
OutboundOrderLog
log
=
new
OutboundOrderLog
();
BeanUtils
.
copyProperties
(
item
,
log
);
log
.
setOrderId
(
item
.
getOutboundOrderId
());
log
.
setItemStatus
(
3L
);
return
log
;
}).
collect
(
Collectors
.
toList
());
outboundOrderLogMapper
.
batchOutboundOrderLog
(
logList
);
}
}
/**
* 为所有明细回填实际被扣减的inventoryId(仅保留被扣减的ID)
* @param items 出库明细列表
* @param deductRecordMap 扣减记录Map(itemId → 实际扣减的库存ID列表)
*/
private
void
fillInventoryIdToItems
(
List
<
OutboundOrderItems
>
items
,
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
deductRecordMap
)
{
if
(
CollectionUtils
.
isEmpty
(
items
)
||
CollectionUtils
.
isEmpty
(
deductRecordMap
))
{
return
;
}
for
(
OutboundOrderItems
item
:
items
)
{
String
itemId
=
item
.
getId
();
List
<
Map
<
String
,
Object
>>
deductRecords
=
deductRecordMap
.
get
(
itemId
);
if
(
CollectionUtils
.
isEmpty
(
deductRecords
))
{
continue
;
}
// 仅收集当前明细实际被扣减的库存ID(去重,无冗余)
List
<
String
>
deductedInventoryIds
=
deductRecords
.
stream
()
.
map
(
rec
->
(
String
)
rec
.
get
(
"inventoryId"
))
.
filter
(
StringUtils:
:
isNotBlank
)
.
distinct
()
.
collect
(
Collectors
.
toList
());
// 仅赋值实际被扣减的库存ID
if
(!
deductedInventoryIds
.
isEmpty
())
{
item
.
setInventoryId
(
String
.
join
(
","
,
deductedInventoryIds
));
// 同步更新数据库,确保持久化
outboundOrderItemsMapper
.
updateOutboundOrderItems
(
item
);
}
}
}
/**
* 按维度分组扣减库存(核心
适配:遍历同维度所有库存
)
* 按维度分组扣减库存(核心
:扣哪个库存ID就记录哪个
)
* @param inventoryKey 维度Key
* @param deductQty 待扣减数量
* @param tempDeductRecords 仅记录实际被扣减的库存ID
* @return 剩余未扣减数量
*/
private
Long
deductByInventoryGroup
(
String
inventoryKey
,
Long
deductQty
,
String
updateUser
,
Date
updateTime
,
...
...
@@ -321,7 +398,7 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
return
deductQty
;
}
// 同维度库存按数量从多到少排序(优先扣减数量多的
,减少拆分次数
)
// 同维度库存按数量从多到少排序(优先扣减数量多的)
invList
.
sort
((
a
,
b
)
->
{
Long
qtyA
=
Optional
.
ofNullable
(
a
.
getQuantity
()).
orElse
(
0L
);
Long
qtyB
=
Optional
.
ofNullable
(
b
.
getQuantity
()).
orElse
(
0L
);
...
...
@@ -332,17 +409,18 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
for
(
Inventory
inv
:
invList
)
{
if
(
remainDeduct
<=
0
)
break
;
String
currentInvId
=
inv
.
getId
();
// 提取当前要扣减的库存ID
Long
currentQty
=
Optional
.
ofNullable
(
inv
.
getQuantity
()).
orElse
(
0L
);
Long
canDeduct
=
Math
.
min
(
remainDeduct
,
currentQty
);
Long
canDeduct
=
Math
.
min
(
remainDeduct
,
currentQty
);
// 实际扣减数量
// 更新库存对象
inv
.
setQuantity
(
currentQty
-
canDeduct
);
inv
.
setInventoryStatus
(
inv
.
getQuantity
()
>
0
?
1L
:
0L
);
inv
.
setUpdateBy
(
updateUser
);
inv
.
setUpdateTime
(
updateTime
);
toUpdateInventoryMap
.
put
(
inv
.
getId
()
,
inv
);
toUpdateInventoryMap
.
put
(
currentInvId
,
inv
);
//
生成单库存ID的扣减记录(关键:不再合并库存ID
)
//
仅记录当前被扣减的库存ID(扣哪个记哪个
)
Map
<
String
,
Object
>
record
=
buildDeductRecord
(
inv
,
inv
.
getInventoryType
().
toString
(),
canDeduct
);
tempDeductRecords
.
add
(
record
);
...
...
@@ -353,29 +431,27 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
}
/**
* 构建扣减记录(
单库存ID粒度
)
* 构建扣减记录(
仅包含实际被扣减的库存ID
)
*/
private
Map
<
String
,
Object
>
buildDeductRecord
(
Inventory
inv
,
String
inventoryType
,
Long
deductQty
)
{
Map
<
String
,
Object
>
record
=
new
HashMap
<>();
record
.
put
(
"inventoryId"
,
inv
.
getId
());
record
.
put
(
"inventoryId"
,
inv
.
getId
());
// 仅记录实际被扣减的库存ID
record
.
put
(
"locationId"
,
inv
.
getLocationId
());
record
.
put
(
"materialId"
,
inv
.
getMaterialId
());
record
.
put
(
"inventoryType"
,
inventoryType
);
record
.
put
(
"deductQty"
,
deductQty
);
record
.
put
(
"deductQty"
,
deductQty
);
// 该库存ID实际被扣减的数量
return
record
;
}
/**
* 预加载库存分组Map(按维度Key分组
,保存所有库存对象
)
* 预加载库存分组Map(按维度Key分组)
*/
private
Map
<
String
,
List
<
Inventory
>>
loadInventoryGroupMap
()
{
// 1. 用你现有的selectInventoryList查全量可用库存(传空条件=查所有)
Inventory
query
=
new
Inventory
();
query
.
setInventoryStatus
(
1L
);
// 只查可用状态库存
query
.
setIsUsed
(
1L
);
// 只查启用的库存
List
<
Inventory
>
allInventory
=
inventoryMapper
.
selectInventoryList
(
query
);
// 2. 按维度分组(和你原有逻辑完全一致)
Map
<
String
,
List
<
Inventory
>>
inventoryGroupMap
=
new
LinkedHashMap
<>();
for
(
Inventory
inv
:
allInventory
)
{
String
key
=
buildInventoryKey
(
...
...
@@ -455,7 +531,7 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
throw
new
RuntimeException
(
"库存被修改请重新确认"
);
}
// 合并相同维度明细(仅合并数量,
库存ID不拼接
)
// 合并相同维度明细(仅合并数量,
不拼接库存ID
)
List
<
OutboundOrderItems
>
mergedItemsList
=
mergeSameInventoryItems
(
outboundOrderItemsList
);
// 为明细设置订单ID和主键ID
...
...
@@ -476,7 +552,7 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
BeanUtils
.
copyProperties
(
items
,
log
);
log
.
setOrderId
(
items
.
getOutboundOrderId
());
outboundOrderLogs
.
add
(
log
);
//
拆分库存ID(支持逗号分隔)
//
仅拆分实际被扣减的库存ID
if
(
StringUtils
.
isNotBlank
(
items
.
getInventoryId
()))
{
String
[]
invIds
=
items
.
getInventoryId
().
split
(
","
);
for
(
String
invId
:
invIds
)
{
...
...
@@ -724,16 +800,17 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
}
// ========== 关键修改:移除 CompletableFuture 异步执行,改为同步调用 ==========
// 8. 同步执行库存扣减和无库位明细拆分(
原异步逻辑改为同步
)
// 8. 同步执行库存扣减和无库位明细拆分(
仅处理实际被扣减的库存ID
)
try
{
for
(
Map
.
Entry
<
String
,
List
<
OutboundOrderItems
>>
entry
:
allItemListMap
.
entrySet
())
{
List
<
OutboundOrderItems
>
itemList
=
entry
.
getValue
();
// 执行库存扣减
// 执行库存扣减
(精准提取被扣减的库存ID)
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
deductRecordMap
=
deductInventory
(
itemList
,
operId
,
now
);
// 处理无库位明细拆分
// 处理无库位明细拆分
(仅拆分实际被扣减的库存ID)
handleNoLocationItemSplit
(
itemList
,
deductRecordMap
,
operId
,
now
);
}
}
catch
(
Exception
e
)
{
// 可添加日志记录异常
}
// 9. 结果汇总
...
...
@@ -753,7 +830,7 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
}
/**
* 处理无库位明细拆分(
精准匹配扣减记录
)
* 处理无库位明细拆分(
仅拆分实际被扣减的库存ID
)
*/
private
void
handleNoLocationItemSplit
(
List
<
OutboundOrderItems
>
itemList
,
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
deductRecordMap
,
...
...
@@ -763,14 +840,14 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
for
(
OutboundOrderItems
item
:
itemList
)
{
if
(
StringUtils
.
isNotBlank
(
item
.
getLocationId
()))
{
continue
;
// 跳过有库位明细
continue
;
// 跳过有库位明细
(已赋值实际被扣减的库存ID)
}
String
itemId
=
item
.
getId
();
List
<
Map
<
String
,
Object
>>
deductRecords
=
deductRecordMap
.
get
(
itemId
);
if
(
CollectionUtils
.
isEmpty
(
deductRecords
))
continue
;
orderIdSet
.
add
(
item
.
getOutboundOrderId
());
//
按扣减记录拆分明细(一条扣减记录对应一条新明细)
//
仅按实际被扣减的库存ID拆分明细
for
(
Map
<
String
,
Object
>
rec
:
deductRecords
)
{
String
inventoryId
=
(
String
)
rec
.
get
(
"inventoryId"
);
String
locId
=
(
String
)
rec
.
get
(
"locationId"
);
...
...
@@ -783,19 +860,19 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService {
newItem
.
setId
(
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
));
newItem
.
setLocationId
(
locId
);
newItem
.
setActualQuantity
(
deductQty
);
newItem
.
setInventoryId
(
inventoryId
);
newItem
.
setInventoryId
(
inventoryId
);
// 仅赋值实际被扣减的单个库存ID
newItem
.
setUpdateBy
(
operId
);
newItem
.
setUpdateTime
(
now
);
newItemList
.
add
(
newItem
);
}
}
// 删除原无库位明细,插入拆分后的新明细
// 删除原无库位明细,插入拆分后的新明细
(仅包含实际被扣减的库存ID)
if
(!
orderIdSet
.
isEmpty
()
&&
!
newItemList
.
isEmpty
())
{
orderIdSet
.
forEach
(
orderId
->
outboundOrderItemsMapper
.
deleteOutboundOrderItemsByOrderId
(
orderId
));
outboundOrderItemsMapper
.
batchInsertOutboundOrderItems
(
newItemList
);
// 生成拆分后的日志
// 生成拆分后的日志
(仅包含实际被扣减的库存ID)
List
<
OutboundOrderLog
>
logList
=
newItemList
.
stream
().
map
(
item
->
{
OutboundOrderLog
log
=
new
OutboundOrderLog
();
BeanUtils
.
copyProperties
(
item
,
log
);
...
...
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/StorageLocationsServiceImpl.java
View file @
f7de2ca4
...
...
@@ -36,10 +36,11 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
{
@Autowired
private
StorageLocationsMapper
storageLocationsMapper
;
@Autowired
private
StorageLocationsCategoryMapper
storageLocationsCategoryMapper
;
@Autowired
private
MaterialsMapper
materialsMapper
;
// 注释掉关联mapper(如果不需要可直接删除)
// @Autowired
// private StorageLocationsCategoryMapper storageLocationsCategoryMapper;
// @Autowired
// private MaterialsMapper materialsMapper;
/**
* 查询库位
...
...
@@ -51,7 +52,8 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
public
StorageLocations
selectStorageLocationsById
(
String
id
)
{
StorageLocations
storageLocations
=
storageLocationsMapper
.
selectStorageLocationsById
(
id
);
String
AllowedCategoryName
=
""
;
// 注释掉物料反显逻辑
/*String AllowedCategoryName = "";
if (storageLocations.getAllowedCategoryIds() != null) {
String[] AllowedCategoryIds = storageLocations.getAllowedCategoryIds().split(",");
if (AllowedCategoryIds != null && AllowedCategoryIds.length > 0) {
...
...
@@ -67,7 +69,7 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
}
}
}
storageLocations
.
setAllowedCategoryNames
(
AllowedCategoryName
);
storageLocations.setAllowedCategoryNames(AllowedCategoryName);
*/
return
storageLocations
;
}
...
...
@@ -91,7 +93,8 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
public
List
<
StorageLocations
>
selectStorageLocationsList
(
StorageLocations
storageLocations
)
{
List
<
StorageLocations
>
storageLocations1
=
storageLocationsMapper
.
selectStorageLocationsList
(
storageLocations
);
for
(
StorageLocations
storageLocations2
:
storageLocations1
){
// 注释掉物料反显逻辑
/*for (StorageLocations storageLocations2 : storageLocations1){
String AllowedCategoryName = "";
if (storageLocations2.getAllowedCategoryIds() != null && !storageLocations2.getAllowedCategoryIds().isEmpty()){
String[] AllowedCategoryIds = storageLocations2.getAllowedCategoryIds().split(",");
...
...
@@ -107,7 +110,7 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
}
}
storageLocations2.setAllowedCategoryNames(AllowedCategoryName);
}
}
*/
return
storageLocations1
;
}
...
...
@@ -122,14 +125,15 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
{
storageLocations
.
setCreateTime
(
DateUtils
.
getNowDate
());
StorageLocationsCategory
storageLocationsCategory
=
new
StorageLocationsCategory
();
BeanUtils
.
copyBeanProp
(
storageLocationsCategory
,
storageLocations
);
// 注释掉所有库位分类关联逻辑
/*StorageLocationsCategory storageLocationsCategory = new StorageLocationsCategory();
BeanUtils.copyBeanProp(storageLocationsCategory,storageLocations);*/
String
LocationsID
=
UUID
.
randomUUID
().
toString
();
storageLocations
.
setId
(
LocationsID
);
storageLocations
.
setCreateTime
(
DateUtils
.
getNowDate
());
storageLocations
.
setCreateUserCode
(
String
.
valueOf
(
SecurityUtils
.
getUserId
()));
storageLocations
.
setWarehousesId
(
WarehouseConfig
.
DEFAULT_WAREHOUSE_ID
);
storageLocationsCategory
.
setLocationCode
(
LocationsID
);
/*
storageLocationsCategory.setLocationCode(LocationsID);
if (storageLocations.getAllowedCategoryIds() != null && !storageLocations.getAllowedCategoryIds().isEmpty()){
...
...
@@ -143,7 +147,7 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
storageLocationsCategory.setCategoryName(materials.getMaterialName());
storageLocationsCategoryMapper.insertStorageLocationsCategory(storageLocationsCategory);
}
}
}
*/
return
storageLocationsMapper
.
insertStorageLocations
(
storageLocations
);
}
...
...
@@ -162,7 +166,8 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
String
LocationsID
=
storageLocations
.
getId
();
String
LocationsCode
=
storageLocations
.
getLocationCode
();
StorageLocations
storageLocations1
=
storageLocationsMapper
.
selectStorageLocationsById
(
LocationsID
);
if
(
storageLocations1
.
getAllowedCategoryIds
()!=
storageLocations
.
getAllowedCategoryIds
()||
storageLocations1
.
getIsEnabled
()!=
storageLocations
.
getIsEnabled
()){
// 注释掉库位分类关联修改逻辑
/*if (storageLocations1.getAllowedCategoryIds()!=storageLocations.getAllowedCategoryIds()||storageLocations1.getIsEnabled()!=storageLocations.getIsEnabled()){
storageLocationsCategoryMapper.deleteStorageLocationsCategoryByLocationCode(LocationsID);
String[] CategoryId = storageLocations.getAllowedCategoryIds().split(",");
...
...
@@ -179,7 +184,7 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
storageLocationsCategory.setCategoryName(materials.getMaterialName());
storageLocationsCategoryMapper.insertStorageLocationsCategory(storageLocationsCategory);
}
}
}
*/
return
storageLocationsMapper
.
updateStorageLocations
(
storageLocations
);
}
...
...
@@ -205,14 +210,14 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
@Override
public
int
deleteStorageLocationsById
(
String
id
)
{
storageLocationsCategoryMapper
.
deleteStorageLocationsCategoryById
(
id
);
// 注释掉关联的库位分类删除逻辑
// storageLocationsCategoryMapper.deleteStorageLocationsCategoryById(id);
return
storageLocationsMapper
.
deleteStorageLocationsById
(
id
);
}
@Override
public
int
updateLocationsCategoryStatus
(
String
id
)
{
return
storageLocationsMapper
.
updateStorageLocationsStatus
(
id
);
}
...
...
ruoyi-inventory/src/main/resources/mapper/inventory/MaterialsMapper.xml
View file @
f7de2ca4
...
...
@@ -97,7 +97,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
m.is_serial_managed,
m.min_stock_level,
m.max_stock_level,
IFNULL(
i.quantity-locked_quantity, 0) as stock, -- 无库存时默认显示0
IFNULL(
stock_sum.total_stock, 0) as stock,
m.is_used,
m.is_active,
m.risk_level,
...
...
@@ -107,7 +107,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
m.update_time,
m.update_user_code
from materials m
left join inventory i on m.id = i.material_id
left join (
select
material_id,
SUM(quantity - locked_quantity) as total_stock
from inventory
group by material_id
) stock_sum on m.id = stock_sum.material_id
<where>
m.is_used = 1
<if
test=
"materialCode != null and materialCode != ''"
>
and m.material_code like concat('%', #{materialCode}, '%')
</if>
...
...
@@ -135,8 +141,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"sortNo != null "
>
and m.sort_no = #{sortNo}
</if>
<if
test=
"createTime != null "
>
and m.create_time like concat('%', #{createTime}, '%')
</if>
<if
test=
"updateTime != null "
>
and m.update_time like concat('%', #{updateTime}, '%')
</if>
-- 可选:添加库存数量的查询条件(如果需要)
<if
test=
"stock != null "
>
and i.stock = #{stock}
</if>
<if
test=
"stock != null "
>
and stock_sum.total_stock = #{stock}
</if>
</where>
order by stock desc
</select>
...
...
ruoyi-inventory/src/main/resources/mapper/inventory/OutboundOrderItemsMapper.xml
View file @
f7de2ca4
...
...
@@ -329,8 +329,9 @@
left join storage_locations sl on oi.location_id = sl.id
<where>
oi.is_used = 1 and o.is_used = 1
<if
test=
"orderId != null and orderId != ''"
>
and oi.order_id like concat('%', #{orderId}, '%')
</if>
<if
test=
"materialId != null and materialId != ''"
>
and oi.material_id
= #{materialId}
</if>
<if
test=
"materialId != null and materialId != ''"
>
and oi.material_id
like concat('%', #{materialId}, '%')
</if>
<if
test=
"batchCode != null and batchCode != ''"
>
and oi.batch_code = #{batchCode}
</if>
<if
test=
"warehouseId != null and warehouseId != ''"
>
and oi.warehouse_id = #{warehouseId}
</if>
<if
test=
"locationId != null and locationId != ''"
>
and oi.location_id = #{locationId}
</if>
...
...
ruoyi-inventory/src/main/resources/mapper/inventory/OutboundOrdersMapper.xml
View file @
f7de2ca4
...
...
@@ -105,15 +105,15 @@
<select
id=
"selectOutboundOrdersList"
parameterType=
"OutboundOrders"
resultMap=
"OutboundOrdersOutboundOrderItemsResult"
>
<include
refid=
"selectOutboundOrdersVo"
/>
<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=
"orderId != null and orderId != ''"
>
and oo.order_id like concat('%', #{orderId}, '%')
</if>
<if
test=
"batchCode != null and batchCode != ''"
>
and oo.batch_code like concat('%', #{batchCode}, '%')
</if>
<if
test=
"systemNo != null and systemNo != ''"
>
and oo.system_no like concat('%', #{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>
<if
test=
"batchCode != null and batchCode != ''"
>
and oo.batch_code
= #{batchCode}
</if>
<if
test=
"batchCode != null and batchCode != ''"
>
and oo.batch_code
like concat('%', #{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>
<if
test=
"orderStatus != null "
>
and oo.order_status = #{orderStatus}
</if>
<!-- 新增 isImport 查询条件 -->
<if
test=
"isImport != null "
>
and oo.is_import = #{isImport}
</if>
<if
test=
"startDate != null"
>
and oo.inbound_date
>
= #{startDate}
</if>
<if
test=
"endDate != null"
>
and oo.inbound_date
<
= #{endDate}
</if>
...
...
ruoyi-inventory/src/main/resources/mapper/inventory/OwnersMapper.xml
View file @
f7de2ca4
...
...
@@ -33,16 +33,15 @@
<select
id=
"selectOwnersList"
parameterType=
"Owners"
resultMap=
"OwnersResult"
>
<include
refid=
"selectOwnersVo"
/>
where is_used = 1
<if
test=
"ownerCode != null and ownerCode != ''"
>
and owner_code
= #{ownerCode}
</if>
<if
test=
"ownerCode != null and ownerCode != ''"
>
and owner_code
like concat('%', #{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=
"taxNumber != null and taxNumber != ''"
>
and tax_number
like concat('%', #{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>
...
...
ruoyi-inventory/src/main/resources/mapper/inventory/StorageLocationsMapper.xml
View file @
f7de2ca4
...
...
@@ -82,11 +82,11 @@
<!-- 原有列表查询(简化:移除重复的is_used=1,条件改为and开头) -->
<select
id=
"selectStorageLocationsList"
parameterType=
"StorageLocations"
resultMap=
"StorageLocationsWithWarehousesResult"
>
<include
refid=
"selectStorageLocationsWithWarehousesVo"
/>
<if
test=
"locationCode != null and locationCode != ''"
>
and sl.location_code
= #{locationCode}
</if>
<if
test=
"locationCode != null and locationCode != ''"
>
and sl.location_code
like concat('%', #{locationCode}, '%')
</if>
<if
test=
"locationName != null and locationName != ''"
>
and sl.location_name like concat('%', #{locationName}, '%')
</if>
<if
test=
"warehousesCode != null and warehousesCode != ''"
>
and sl.warehouses_code = #{warehousesCode}
</if>
<if
test=
"locationType != null "
>
and sl.location_type = #{locationType}
</if>
<if
test=
"zoneCode != null and zoneCode != ''"
>
and sl.zone_code
= #{zoneCode}
</if>
<if
test=
"zoneCode != null and zoneCode != ''"
>
and sl.zone_code
like concat('%', #{zoneCode}, '%')
</if>
<if
test=
"rowCode != null and rowCode != ''"
>
and sl.row_code = #{rowCode}
</if>
<if
test=
"columnCode != null and columnCode != ''"
>
and sl.column_code = #{columnCode}
</if>
<if
test=
"layerCode != null and layerCode != ''"
>
and sl.layer_code = #{layerCode}
</if>
...
...
@@ -104,7 +104,7 @@
<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=
"pickingArea != null and pickingArea != ''"
>
and sl.picking_area
like concat('%', #{pickingArea}, '%')
</if>
<if
test=
"warehousesId != null and warehousesId != ''"
>
and sl.warehouses_id = #{warehousesId}
</if>
<if
test=
"allowMixedProducts != null "
>
and sl.allow_mixed_products = #{allowMixedProducts}
</if>
<if
test=
"allowMixedBatches != null "
>
and sl.allow_mixed_batches = #{allowMixedBatches}
</if>
...
...
ruoyi-inventory/src/main/resources/mapper/inventory/WarehousesMapper.xml
View file @
f7de2ca4
...
...
@@ -30,13 +30,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select
id=
"selectWarehousesList"
parameterType=
"Warehouses"
resultMap=
"WarehousesResult"
>
<include
refid=
"selectWarehousesVo"
/>
where is_used=1 and id != #{localId}
<if
test=
"warehousesCode != null and warehousesCode != ''"
>
and warehouses_code = #{warehousesCode}
</if>
<if
test=
"warehousesCode != null and warehousesCode != ''"
>
and warehouses_code like concat('%', #{warehousesCode}, '%')
</if>
<if
test=
"warehousesName != null and warehousesName != ''"
>
and warehouses_name like concat('%', #{warehousesName}, '%')
</if>
<if
test=
"warehouseType != null "
>
and warehouse_type = #{warehouseType}
</if>
<if
test=
"address != null and address != ''"
>
and address = #{address}
</if>
<if
test=
"area != null "
>
and area = #{area}
</if>
<if
test=
"capacity != null "
>
and capacity = #{capacity}
</if>
<if
test=
"manager != null and manager != ''"
>
and manager = #{manager}
</if>
<if
test=
"manager != null and manager != ''"
>
and manager like concat('%', #{manager}, '%')
</if>
<if
test=
"contactPhone != null and contactPhone != ''"
>
and contact_phone = #{contactPhone}
</if>
<if
test=
"isEnabled != null "
>
and is_enabled = #{isEnabled}
</if>
<if
test=
"isUsed != null "
>
and is_used = #{isUsed}
</if>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论