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
203b5590
Commit
203b5590
authored
Dec 03, 2025
by
yubin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
inventory
parent
0c8bf004
隐藏空白字符变更
内嵌
并排
正在显示
13 个修改的文件
包含
1966 行增加
和
0 行删除
+1966
-0
package-lock.json
+3
-0
ruoyi-admin-vue/src/api/inventory/orders.js
+53
-0
ruoyi-admin-vue/src/views/inventory/locations/MaterialSelectComponent.vue
+293
-0
ruoyi-admin-vue/src/views/inventory/locations/treeComponent.vue
+377
-0
ruoyi-admin-vue/src/views/inventory/orders/index.vue
+656
-0
ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
+39
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/OutboundOrderItemsInventory.java
+50
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/OutboundOrderLog.java
+145
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/OutboundOrderLogMapper.java
+71
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IOutboundOrderLogService.java
+61
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/OutboundOrderLogServiceImpl.java
+93
-0
ruoyi-inventory/src/main/resources/mapper/inventory/OutboundOrderLogMapper.xml
+104
-0
ruoyi-inventory/src/main/resources/mybatis/mybatis-config.xml
+21
-0
没有找到文件。
package-lock.json
0 → 100644
View file @
203b5590
{
"lockfileVersion"
:
1
}
ruoyi-admin-vue/src/api/inventory/orders.js
0 → 100644
View file @
203b5590
import
request
from
'@/utils/request'
// 查询出库单主列表
export
function
listOrders
(
query
)
{
return
request
({
url
:
'/inventory/orders/list'
,
method
:
'get'
,
params
:
query
})
}
// 查询出库单主详细
export
function
getOrders
(
id
)
{
return
request
({
url
:
'/inventory/orders/'
+
id
,
method
:
'get'
})
}
// 新增出库单主
export
function
addOrders
(
data
)
{
return
request
({
url
:
'/inventory/orders'
,
method
:
'post'
,
data
:
data
})
}
// 修改出库单主
export
function
updateOrders
(
data
)
{
return
request
({
url
:
'/inventory/orders'
,
method
:
'put'
,
data
:
data
})
}
// 删除出库单主
export
function
delOrders
(
id
)
{
return
request
({
url
:
'/inventory/orders/'
+
id
,
method
:
'delete'
})
}
// 查询仓库库存列表
export
function
listWarehouseInventory
(
warehouseId
)
{
return
request
({
url
:
'/inventory/items/list'
,
method
:
'get'
,
params
:
{
warehouseId
:
warehouseId
}
})
}
ruoyi-admin-vue/src/views/inventory/locations/MaterialSelectComponent.vue
0 → 100644
View file @
203b5590
<
template
>
<div
class=
"material-select-component"
>
<el-dialog
:title=
"title"
:visible
.
sync=
"visible"
width=
"900px"
append-to-body
>
<!-- 左右分栏布局 -->
<div
class=
"split-layout"
>
<!-- 左侧分类树 -->
<div
class=
"left-panel"
>
<TreeComponent
ref=
"treeComponent"
:tree-data=
"categoryTreeData"
:tree-props=
"treeProps"
:node-key=
"nodeKey"
:show-search=
"true"
search-placeholder=
"请输入分类名称"
:default-expand-all=
"true"
:highlight-current=
"true"
:loading=
"loadingTree"
@
node-click=
"handleCategoryChange"
>
<!-- 自定义节点内容插槽 -->
<template
#
node-content=
"
{ node, data }">
<span
class=
"custom-tree-node"
>
<span>
{{
node
.
label
}}
</span>
</span>
</
template
>
</TreeComponent>
</div>
<!-- 右侧物料列表 -->
<div
class=
"right-panel"
>
<!-- 物料列表 -->
<el-table
v-loading=
"loading"
:data=
"materialsList"
@
selection-change=
"handleSelectionChange"
:scroll-x=
"true"
>
<el-table-column
type=
"selection"
width=
"55"
align=
"center"
/>
<el-table-column
type=
"index"
label=
"序号"
align=
"center"
/>
<el-table-column
label=
"物料编码"
align=
"center"
prop=
"materialCode"
/>
<el-table-column
label=
"物料名称"
align=
"center"
prop=
"materialName"
/>
<el-table-column
label=
"SAP物料号"
align=
"center"
prop=
"sapNo"
/>
<el-table-column
label=
"规格型号"
align=
"center"
prop=
"specification"
/>
<el-table-column
label=
"计量单位"
align=
"center"
prop=
"materialUnit"
/>
</el-table>
<!-- 分页 -->
<pagination
v-show=
"total>0"
:total=
"total"
:page
.
sync=
"queryParams.pageNum"
:limit
.
sync=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</div>
</div>
<!-- 底部按钮 -->
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"cancel"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"confirmSelection"
>
确 定
</el-button>
</div>
</el-dialog>
</div>
</template>
<
script
>
import
{
listMaterials
}
from
"@/api/inventory/materials"
import
{
listMaterials_category
}
from
"@/api/inventory/materials_category"
import
Pagination
from
"@/components/Pagination"
import
TreeComponent
from
'./treeComponent.vue'
export
default
{
name
:
"MaterialSelectComponent"
,
components
:
{
Pagination
,
TreeComponent
},
props
:
{
// 对话框标题
title
:
{
type
:
String
,
default
:
"选择物料"
},
// 是否显示对话框
visible
:
{
type
:
Boolean
,
default
:
false
}
},
data
()
{
return
{
// 树相关数据
categoryTreeData
:
[],
treeProps
:
{
children
:
'children'
,
label
:
'label'
,
value
:
'sid'
},
nodeKey
:
'sid'
,
loadingTree
:
false
,
// 分类映射
categoryMap
:
{},
// 选中的分类
selectedCategory
:
null
,
// 加载状态
loading
:
false
,
// 总条数
total
:
0
,
// 物料列表
materialsList
:
[],
// 选中的物料
selectedMaterials
:
[],
// 查询参数
queryParams
:
{
pageNum
:
1
,
pageSize
:
10
,
categoryCode
:
null
}
}
},
watch
:
{
// 监听对话框显示状态,当显示时加载物料列表和分类树
visible
(
newVal
)
{
if
(
newVal
)
{
this
.
getCategoryTreeData
()
this
.
getList
()
}
}
},
methods
:
{
/** 获取分类树数据 */
async
getCategoryTreeData
()
{
this
.
loadingTree
=
true
try
{
// 调用物料分类列表API获取所有分类
const
response
=
await
listMaterials_category
({
pageNum
:
1
,
pageSize
:
1000
// 获取足够多的数据
})
if
(
response
.
rows
&&
response
.
rows
.
length
>
0
)
{
// 过滤掉已禁用的分类
const
activeCategories
=
response
.
rows
.
filter
(
item
=>
item
.
isUsed
!==
0
&&
item
.
isUsed
!==
'0'
)
// 构建树形结构
this
.
categoryTreeData
=
this
.
buildTreeData
(
activeCategories
)
// 构建分类映射
this
.
buildCategoryMap
(
activeCategories
)
}
}
catch
(
error
)
{
console
.
error
(
'获取分类树数据失败:'
,
error
)
}
finally
{
this
.
loadingTree
=
false
}
},
/** 构建树形结构 */
buildTreeData
(
list
,
parentId
=
null
)
{
const
result
=
list
.
filter
(
item
=>
{
if
(
parentId
===
null
)
{
// 根节点:parentId为null、0或空
return
!
item
.
parentId
||
item
.
parentId
===
0
||
item
.
parentId
===
'0'
}
else
{
// 子节点:parentId匹配
return
item
.
parentId
==
parentId
}
})
.
map
(
item
=>
{
const
children
=
this
.
buildTreeData
(
list
,
item
.
id
)
return
{
...
item
,
sid
:
String
(
item
.
id
),
label
:
item
.
categoryName
,
children
:
children
.
length
>
0
?
children
:
undefined
}
})
return
result
},
/** 构建分类映射 */
buildCategoryMap
(
categories
)
{
this
.
categoryMap
=
{}
categories
.
forEach
(
item
=>
{
this
.
categoryMap
[
item
.
id
]
=
item
.
categoryName
})
},
/** 处理分类选择变化 */
handleCategoryChange
(
data
)
{
this
.
selectedCategory
=
data
// 更新查询参数,按选中的分类筛选物料
this
.
queryParams
.
categoryCode
=
data
?
data
.
categoryCode
:
null
this
.
queryParams
.
pageNum
=
1
this
.
getList
()
},
/** 获取物料列表 */
async
getList
()
{
this
.
loading
=
true
try
{
const
response
=
await
listMaterials
(
this
.
queryParams
)
this
.
materialsList
=
response
.
rows
this
.
total
=
response
.
total
}
catch
(
error
)
{
console
.
error
(
'获取物料列表失败:'
,
error
)
}
finally
{
this
.
loading
=
false
}
},
/** 处理选择变化 */
handleSelectionChange
(
selection
)
{
this
.
selectedMaterials
=
selection
},
/** 确认选择 */
confirmSelection
()
{
// 提取选中物料的uuid和名称,用逗号隔开
const
uuids
=
this
.
selectedMaterials
.
map
(
item
=>
item
.
uuid
||
item
.
id
)
// 兼容uuid和id字段
.
join
(
','
)
const
names
=
this
.
selectedMaterials
.
map
(
item
=>
item
.
materialName
)
// 提取物料名称
.
join
(
','
)
// 触发选择确认事件,将选中的uuid和名称传递给父组件
this
.
$emit
(
'selection-confirm'
,
uuids
,
names
)
// 关闭对话框
this
.
$emit
(
'update:visible'
,
false
)
},
/** 取消选择 */
cancel
()
{
// 清空选择
this
.
selectedMaterials
=
[]
this
.
selectedCategory
=
null
this
.
queryParams
.
categoryCode
=
null
// 触发取消事件
this
.
$emit
(
'selection-cancel'
)
// 关闭对话框
this
.
$emit
(
'update:visible'
,
false
)
}
}
}
</
script
>
<
style
scoped
>
.material-select-component
{
.dialog-footer
{
text-align
:
right
;
}
.split-layout
{
display
:
flex
;
height
:
500px
;
gap
:
10px
;
.left-panel
{
width
:
250px
;
border
:
1px
solid
#e4e7ed
;
border-radius
:
4px
;
overflow
:
hidden
;
.tree-container
{
height
:
100%
;
}
}
.right-panel
{
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
.el-table
{
flex
:
1
;
overflow
:
auto
;
}
.pagination
{
margin-top
:
10px
;
}
}
}
}
</
style
>
\ No newline at end of file
ruoyi-admin-vue/src/views/inventory/locations/treeComponent.vue
0 → 100644
View file @
203b5590
<
template
>
<div
class=
"tree-container"
:style=
"containerStyle"
>
<!-- 搜索框 -->
<div
class=
"tree-header"
v-if=
"showSearch"
>
<el-input
v-model=
"searchText"
:placeholder=
"searchPlaceholder"
clearable
size=
"small"
prefix-icon=
"el-icon-search"
@
input=
"handleSearch"
style=
"width: 100%; margin-bottom: 10px;"
/>
</div>
<!-- 树组件 -->
<div
class=
"tree-body"
:style=
"treeBodyStyle"
>
<el-tree
v-if=
"treeData && treeData.length > 0"
ref=
"treeRef"
:data=
"filteredTreeData"
:props=
"treeProps"
:node-key=
"nodeKey"
:default-expand-all=
"defaultExpandAll"
:expand-on-click-node=
"expandOnClickNode"
:highlight-current=
"highlightCurrent"
:filter-node-method=
"filterNodeMethod"
:empty-text=
"emptyText"
:style=
"treeStyle"
@
node-click=
"handleNodeClick"
@
node-expand=
"handleNodeExpand"
@
node-collapse=
"handleNodeCollapse"
@
current-change=
"handleCurrentChange"
>
<!-- 自定义节点内容插槽 -->
<template
#
default=
"
{ node, data }">
<slot
name=
"node-content"
:node=
"node"
:data=
"data"
>
<span
class=
"custom-tree-node"
>
<span>
{{
node
.
label
}}
</span>
</span>
</slot>
</
template
>
</el-tree>
<!-- 空状态 -->
<div
v-else
class=
"tree-empty"
>
<slot
name=
"empty"
>
<div
style=
"padding: 20px; text-align: center; color: #999;"
>
{{ loading ? '加载中...' : '暂无数据' }}
</div>
</slot>
</div>
</div>
</div>
</template>
<
script
>
export
default
{
name
:
'TreeComponent'
,
props
:
{
// 树数据
treeData
:
{
type
:
Array
,
default
:
()
=>
[]
},
// 树配置
treeProps
:
{
type
:
Object
,
default
:
()
=>
({
children
:
'children'
,
label
:
'label'
,
value
:
'sid'
})
},
// 节点key
nodeKey
:
{
type
:
String
,
default
:
'sid'
},
// 是否显示搜索框
showSearch
:
{
type
:
Boolean
,
default
:
true
},
// 搜索框占位符
searchPlaceholder
:
{
type
:
String
,
default
:
'请输入搜索内容'
},
// 是否默认展开所有节点
defaultExpandAll
:
{
type
:
Boolean
,
default
:
true
},
// 是否点击节点时展开
expandOnClickNode
:
{
type
:
Boolean
,
default
:
false
},
// 是否高亮当前选中节点
highlightCurrent
:
{
type
:
Boolean
,
default
:
true
},
// 容器样式
containerStyle
:
{
type
:
Object
,
default
:
()
=>
({
height
:
'100%'
,
padding
:
'10px'
})
},
// 树容器样式
treeBodyStyle
:
{
type
:
Object
,
default
:
()
=>
({
height
:
'calc(100% - 50px)'
,
overflow
:
'auto'
})
},
// 树样式
treeStyle
:
{
type
:
Object
,
default
:
()
=>
({})
},
// 空状态文本
emptyText
:
{
type
:
String
,
default
:
'暂无数据'
},
// 加载状态
loading
:
{
type
:
Boolean
,
default
:
false
},
// 初始选中的节点key
defaultSelectedKey
:
{
type
:
[
String
,
Number
],
default
:
null
}
},
data
()
{
return
{
searchText
:
''
,
filteredTreeData
:
[],
selectedNode
:
null
}
},
watch
:
{
treeData
:
{
immediate
:
true
,
handler
(
newData
)
{
this
.
filteredTreeData
=
newData
this
.
$nextTick
(()
=>
{
if
(
this
.
defaultSelectedKey
&&
this
.
$refs
.
treeRef
)
{
this
.
$refs
.
treeRef
.
setCurrentKey
(
this
.
defaultSelectedKey
)
}
})
}
},
defaultSelectedKey
:
{
immediate
:
true
,
handler
(
newKey
)
{
if
(
newKey
&&
this
.
$refs
.
treeRef
)
{
this
.
$refs
.
treeRef
.
setCurrentKey
(
newKey
)
}
}
}
},
methods
:
{
/**
* 过滤节点方法
*/
filterNodeMethod
(
value
,
data
,
node
)
{
if
(
!
value
)
return
true
const
label
=
data
[
this
.
treeProps
.
label
]
||
''
return
label
.
toLowerCase
().
includes
(
value
.
toLowerCase
())
},
/**
* 处理搜索
*/
handleSearch
(
value
)
{
this
.
$refs
.
treeRef
.
filter
(
value
)
},
/**
* 节点点击事件
*/
handleNodeClick
(
data
,
node
,
component
)
{
this
.
selectedNode
=
{
data
,
node
,
component
}
this
.
$emit
(
'node-click'
,
data
,
node
,
component
)
},
/**
* 节点展开事件
*/
handleNodeExpand
(
data
,
node
,
component
)
{
this
.
$emit
(
'node-expand'
,
data
,
node
,
component
)
},
/**
* 节点折叠事件
*/
handleNodeCollapse
(
data
,
node
,
component
)
{
this
.
$emit
(
'node-collapse'
,
data
,
node
,
component
)
},
/**
* 当前节点变化事件
*/
handleCurrentChange
(
data
,
node
)
{
this
.
$emit
(
'current-change'
,
data
,
node
)
},
/**
* 重置树结构
*/
resetTree
()
{
// 修复:使用正确的 ref 名称 treeRef
if
(
this
.
$refs
.
treeRef
)
{
this
.
$refs
.
treeRef
.
setCurrentKey
(
null
);
this
.
searchText
=
''
;
this
.
$refs
.
treeRef
.
filter
(
''
);
// 清空搜索
}
},
/**
* 设置当前选中的节点
*/
setCurrentNode
(
node
)
{
this
.
$refs
.
treeRef
.
setCurrentNode
(
node
)
},
/**
* 设置当前选中的节点key
*/
setCurrentKey
(
key
)
{
this
.
$refs
.
treeRef
.
setCurrentKey
(
key
)
},
/**
* 获取当前选中的节点
*/
getCurrentNode
()
{
return
this
.
$refs
.
treeRef
.
getCurrentNode
()
},
/**
* 获取当前选中的节点key
*/
getCurrentKey
()
{
return
this
.
$refs
.
treeRef
.
getCurrentKey
()
},
/**
* 展开指定节点
*/
expandNode
(
node
)
{
this
.
$refs
.
treeRef
.
expandNode
(
node
)
},
/**
* 折叠指定节点
*/
collapseNode
(
node
)
{
this
.
$refs
.
treeRef
.
collapseNode
(
node
)
},
/**
* 展开所有节点
*/
expandAll
()
{
this
.
$refs
.
treeRef
.
expandAll
()
},
/**
* 折叠所有节点
*/
collapseAll
()
{
this
.
$refs
.
treeRef
.
collapseAll
()
},
/**
* 更新节点数据
*/
updateKeyChildren
(
key
,
data
)
{
this
.
$refs
.
treeRef
.
updateKeyChildren
(
key
,
data
)
},
/**
* 获取节点信息
*/
getNode
(
key
)
{
return
this
.
$refs
.
treeRef
.
getNode
(
key
)
},
/**
* 移除节点
*/
remove
(
key
)
{
this
.
$refs
.
treeRef
.
remove
(
key
)
},
/**
* 追加节点数据
*/
append
(
data
,
parentNode
)
{
this
.
$refs
.
treeRef
.
append
(
data
,
parentNode
)
},
/**
* 插入节点数据
*/
insertBefore
(
data
,
refNode
)
{
this
.
$refs
.
treeRef
.
insertBefore
(
data
,
refNode
)
},
/**
* 插入节点数据后
*/
insertAfter
(
data
,
refNode
)
{
this
.
$refs
.
treeRef
.
insertAfter
(
data
,
refNode
)
}
}
}
</
script
>
<
style
scoped
>
.tree-container
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
}
.tree-header
{
flex-shrink
:
0
;
}
.tree-body
{
flex
:
1
;
overflow
:
auto
;
}
.custom-tree-node
{
flex
:
1
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
font-size
:
14px
;
padding-right
:
8px
;
}
.tree-empty
{
height
:
100%
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
color
:
#999
;
}
</
style
>
\ No newline at end of file
ruoyi-admin-vue/src/views/inventory/orders/index.vue
0 → 100644
View file @
203b5590
<
template
>
<div
class=
"app-container"
>
<el-form
:model=
"queryParams"
ref=
"queryForm"
size=
"small"
:inline=
"true"
v-show=
"showSearch"
label-width=
"68px"
>
<el-form-item
label=
"出库单号"
prop=
"orderId"
>
<el-input
v-model=
"queryParams.orderId"
placeholder=
"请输入出库单号"
clearable
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"系统编号"
prop=
"systemNo"
>
<el-input
v-model=
"queryParams.systemNo"
placeholder=
"请输入系统编号"
clearable
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"入库类型"
prop=
"orderTypeId"
>
<el-input
v-model=
"queryParams.orderTypeId"
placeholder=
"请输入入库类型"
clearable
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"批次ID"
prop=
"batchCode"
>
<el-input
v-model=
"queryParams.batchCode"
placeholder=
"请输入批次ID"
clearable
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"订单状态"
prop=
"orderStatus"
>
<el-select
v-model=
"queryParams.orderStatus"
placeholder=
"请选择订单状态"
clearable
>
<el-option
v-for=
"dict in dict.type.inbound_order_status"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
icon=
"el-icon-search"
size=
"mini"
@
click=
"handleQuery"
>
搜索
</el-button>
<el-button
icon=
"el-icon-refresh"
size=
"mini"
@
click=
"resetQuery"
>
重置
</el-button>
</el-form-item>
</el-form>
<el-row
:gutter=
"10"
class=
"mb8"
>
<el-col
:span=
"1.5"
>
<el-button
type=
"primary"
plain
icon=
"el-icon-plus"
size=
"mini"
@
click=
"handleAdd"
v-hasPermi=
"['inventory:orders:add']"
>
新增
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"success"
plain
icon=
"el-icon-edit"
size=
"mini"
:disabled=
"single"
@
click=
"handleUpdate"
v-hasPermi=
"['inventory:orders:edit']"
>
修改
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"danger"
plain
icon=
"el-icon-delete"
size=
"mini"
:disabled=
"multiple"
@
click=
"handleDelete"
v-hasPermi=
"['inventory:orders:remove']"
>
删除
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"warning"
plain
icon=
"el-icon-download"
size=
"mini"
@
click=
"handleExport"
v-hasPermi=
"['inventory:orders:export']"
>
导出
</el-button>
</el-col>
<right-toolbar
:showSearch
.
sync=
"showSearch"
@
queryTable=
"getList"
></right-toolbar>
</el-row>
<el-table
v-loading=
"loading"
:data=
"ordersList"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
align=
"center"
/>
<el-table-column
label=
"编号"
align=
"center"
prop=
"id"
width=
"80"
/>
<el-table-column
label=
"出库单号"
align=
"center"
prop=
"orderId"
width=
"150"
/>
<el-table-column
label=
"系统编号"
align=
"center"
prop=
"systemNo"
width=
"150"
/>
<el-table-column
label=
"入库类型"
align=
"center"
prop=
"orderTypeId"
width=
"120"
>
<template
slot-scope=
"scope"
>
<dict-tag
:options=
"dict.type.inbound_order_type"
:value=
"scope.row.orderTypeId"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"批次ID"
align=
"center"
prop=
"batchCode"
width=
"120"
/>
<el-table-column
label=
"仓库ID"
align=
"center"
prop=
"warehouseId"
width=
"100"
/>
<el-table-column
label=
"货主ID"
align=
"center"
prop=
"ownerId"
width=
"100"
/>
<el-table-column
label=
"订单状态"
align=
"center"
prop=
"orderStatus"
width=
"150"
>
<
template
slot-scope=
"scope"
>
<dict-tag
:options=
"dict.type.inbound_order_status"
:value=
"scope.row.orderStatus"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"出库日期"
align=
"center"
prop=
"inboundDate"
width=
"150"
>
<
template
slot-scope=
"scope"
>
<span>
{{
parseTime
(
scope
.
row
.
inboundDate
,
'{y
}
-{m
}
-{d
}
'
)
}}
<
/span
>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"目的地"
align
=
"center"
prop
=
"destination"
width
=
"150"
/>
<
el
-
table
-
column
label
=
"计划量"
align
=
"center"
prop
=
"totalPlannedQuantity"
width
=
"100"
/>
<
el
-
table
-
column
label
=
"实际量"
align
=
"center"
prop
=
"totalActualQuantity"
width
=
"100"
/>
<
el
-
table
-
column
label
=
"总件数"
align
=
"center"
prop
=
"totalPackages"
width
=
"100"
/>
<
el
-
table
-
column
label
=
"备注"
align
=
"center"
prop
=
"remark"
width
=
"150"
/>
<
el
-
table
-
column
label
=
"是否使用"
align
=
"center"
prop
=
"isUsed"
width
=
"120"
/>
<
el
-
table
-
column
label
=
"排序"
align
=
"center"
prop
=
"sortNo"
width
=
"80"
/>
<
el
-
table
-
column
label
=
"创建人"
align
=
"center"
prop
=
"createUserCode"
width
=
"150"
/>
<
el
-
table
-
column
label
=
"更新人"
align
=
"center"
prop
=
"updateUserCode"
width
=
"150"
/>
<
el
-
table
-
column
label
=
"操作"
align
=
"center"
class
-
name
=
"small-padding fixed-width"
width
=
"120"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
button
size
=
"mini"
type
=
"text"
icon
=
"el-icon-edit"
@
click
=
"handleUpdate(scope.row)"
v
-
hasPermi
=
"['inventory:orders:edit']"
>
修改
<
/el-button
>
<
el
-
button
size
=
"mini"
type
=
"text"
icon
=
"el-icon-delete"
@
click
=
"handleDelete(scope.row)"
v
-
hasPermi
=
"['inventory:orders:remove']"
>
删除
<
/el-button
>
<
/template
>
<
/el-table-column
>
<
/el-table
>
<
pagination
v
-
show
=
"total>0"
:
total
=
"total"
:
page
.
sync
=
"queryParams.pageNum"
:
limit
.
sync
=
"queryParams.pageSize"
@
pagination
=
"getList"
/>
<!--
添加或修改出库单主对话框
-->
<
el
-
dialog
:
title
=
"title"
:
visible
.
sync
=
"open"
width
=
"900px"
append
-
to
-
body
>
<
el
-
form
ref
=
"form"
:
model
=
"form"
:
rules
=
"rules"
label
-
width
=
"120px"
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"出库单号"
prop
=
"orderId"
>
<
el
-
input
v
-
model
=
"form.orderId"
placeholder
=
"请输入出库单号"
/>
<
/el-form-item
>
<
/el-col
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"系统编号"
prop
=
"systemNo"
>
<
el
-
input
v
-
model
=
"form.systemNo"
placeholder
=
"请输入系统编号"
/>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"入库类型"
prop
=
"orderTypeId"
>
<
el
-
input
v
-
model
=
"form.orderTypeId"
placeholder
=
"请输入入库类型"
/>
<
/el-form-item
>
<
/el-col
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"批次ID"
prop
=
"batchCode"
>
<
el
-
input
v
-
model
=
"form.batchCode"
placeholder
=
"请输入批次ID"
/>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"仓库ID"
prop
=
"warehouseId"
>
<
el
-
input
v
-
model
=
"form.warehouseId"
placeholder
=
"请输入仓库ID"
/>
<
/el-form-item
>
<
/el-col
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"货主ID"
prop
=
"ownerId"
>
<
el
-
input
v
-
model
=
"form.ownerId"
placeholder
=
"请输入货主ID"
/>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"订单状态"
prop
=
"orderStatus"
>
<
el
-
radio
-
group
v
-
model
=
"form.orderStatus"
>
<
el
-
radio
v
-
for
=
"dict in dict.type.inbound_order_status"
:
key
=
"dict.value"
:
label
=
"parseInt(dict.value)"
>
{{
dict
.
label
}}
<
/el-radio
>
<
/el-radio-group
>
<
/el-form-item
>
<
/el-col
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"出库日期"
prop
=
"inboundDate"
>
<
el
-
date
-
picker
clearable
v
-
model
=
"form.inboundDate"
type
=
"date"
value
-
format
=
"yyyy-MM-dd"
placeholder
=
"请选择出库日期"
>
<
/el-date-picker
>
<
/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
=
"请输入目的地"
/>
<
/el-form-item
>
<
/el-col
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"计划量"
prop
=
"totalPlannedQuantity"
>
<
el
-
input
v
-
model
=
"form.totalPlannedQuantity"
placeholder
=
"请输入计划量"
/>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"实际量"
prop
=
"totalActualQuantity"
>
<
el
-
input
v
-
model
=
"form.totalActualQuantity"
placeholder
=
"请输入实际量"
/>
<
/el-form-item
>
<
/el-col
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"总件数"
prop
=
"totalPackages"
>
<
el
-
input
v
-
model
=
"form.totalPackages"
placeholder
=
"请输入总件数"
/>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"24"
>
<
el
-
form
-
item
label
=
"备注"
prop
=
"remark"
>
<
el
-
input
v
-
model
=
"form.remark"
type
=
"textarea"
placeholder
=
"请输入内容"
/>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"是否使用"
prop
=
"isUsed"
>
<
el
-
input
v
-
model
=
"form.isUsed"
placeholder
=
"请输入是否使用"
/>
<
/el-form-item
>
<
/el-col
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"排序"
prop
=
"sortNo"
>
<
el
-
input
v
-
model
=
"form.sortNo"
placeholder
=
"请输入排序"
/>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
row
:
gutter
=
"20"
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"创建人"
prop
=
"createUserCode"
>
<
el
-
input
v
-
model
=
"form.createUserCode"
placeholder
=
"请输入创建人"
/>
<
/el-form-item
>
<
/el-col
>
<
el
-
col
:
span
=
"12"
>
<
el
-
form
-
item
label
=
"更新人"
prop
=
"updateUserCode"
>
<
el
-
input
v
-
model
=
"form.updateUserCode"
placeholder
=
"请输入更新人"
/>
<
/el-form-item
>
<
/el-col
>
<
/el-row
>
<
el
-
divider
content
-
position
=
"center"
>
库存信息
<
/el-divider
>
<
el
-
row
:
gutter
=
"10"
class
=
"mb8"
>
<
el
-
col
:
span
=
"1.5"
>
<
el
-
button
type
=
"primary"
icon
=
"el-icon-plus"
size
=
"mini"
@
click
=
"handleAddInventoryItem"
>
添加
<
/el-button
>
<
/el-col
>
<
el
-
col
:
span
=
"1.5"
>
<
el
-
button
type
=
"danger"
icon
=
"el-icon-delete"
size
=
"mini"
@
click
=
"handleDeleteInventoryItem"
>
删除
<
/el-button
>
<
/el-col
>
<
/el-row
>
<
el
-
table
:
data
=
"inventoryList"
:
row
-
class
-
name
=
"rowInventoryIndex"
@
selection
-
change
=
"handleInventorySelectionChange"
ref
=
"inventory"
>
<
el
-
table
-
column
type
=
"selection"
width
=
"50"
align
=
"center"
/>
<
el
-
table
-
column
label
=
"序号"
align
=
"center"
prop
=
"index"
width
=
"50"
/>
<
el
-
table
-
column
label
=
"货物ID"
prop
=
"materialId"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
input
v
-
model
=
"scope.row.materialId"
placeholder
=
"请输入货物ID"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"批次ID"
prop
=
"batchId"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
input
v
-
model
=
"scope.row.batchId"
placeholder
=
"请输入批次ID"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"仓库ID"
prop
=
"warehouseId"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
input
v
-
model
=
"scope.row.warehouseId"
placeholder
=
"请输入仓库ID"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"库位ID"
prop
=
"locationId"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
input
v
-
model
=
"scope.row.locationId"
placeholder
=
"请输入库位ID"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"货主ID"
prop
=
"ownerId"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
input
v
-
model
=
"scope.row.ownerId"
placeholder
=
"请输入货主ID"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"库存数量"
prop
=
"quantity"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
input
v
-
model
=
"scope.row.quantity"
placeholder
=
"请输入库存数量"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"锁定数量"
prop
=
"lockedQuantity"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
input
v
-
model
=
"scope.row.lockedQuantity"
placeholder
=
"请输入锁定数量"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"可用库存"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
{{
(
Number
(
scope
.
row
.
quantity
)
||
0
)
-
(
Number
(
scope
.
row
.
lockedQuantity
)
||
0
)
}}
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"选择数量"
prop
=
"selectQty"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
input
v
-
model
.
number
=
"scope.row.selectQty"
placeholder
=
"请输入选择数量"
@
blur
=
"validateSelectQty(scope.row)"
@
input
=
"validateSelectQty(scope.row)"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"库存状态"
prop
=
"inventoryStatus"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
dict
-
tag
:
options
=
"dict.type.inventory_status"
:
value
=
"scope.row.inventoryStatus"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"库存类别"
prop
=
"inventoryType"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
dict
-
tag
:
options
=
"dict.type.inventory_type"
:
value
=
"scope.row.inventoryType"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"单位重量"
prop
=
"unitWeight"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
input
v
-
model
=
"scope.row.unitWeight"
placeholder
=
"请输入单位重量"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"最后入库时间"
prop
=
"lastInboundTime"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
date
-
picker
v
-
model
=
"scope.row.lastInboundTime"
type
=
"datetime"
placeholder
=
"选择最后入库时间"
value
-
format
=
"yyyy-MM-dd HH:mm:ss"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"最后出库时间"
prop
=
"lastOutboundTime"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
date
-
picker
v
-
model
=
"scope.row.lastOutboundTime"
type
=
"datetime"
placeholder
=
"选择最后出库时间"
value
-
format
=
"yyyy-MM-dd HH:mm:ss"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"是否使用"
prop
=
"isUsed"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
input
v
-
model
=
"scope.row.isUsed"
placeholder
=
"请输入是否使用"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"排序"
prop
=
"sortNo"
width
=
"150"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
input
v
-
model
=
"scope.row.sortNo"
placeholder
=
"请输入排序"
/>
<
/template
>
<
/el-table-column
>
<
/el-table
>
<
/el-form
>
<
div
slot
=
"footer"
class
=
"dialog-footer"
>
<
el
-
button
type
=
"primary"
@
click
=
"submitForm"
>
确
定
<
/el-button
>
<
el
-
button
@
click
=
"cancel"
>
取
消
<
/el-button
>
<
/div
>
<
/el-dialog
>
<
/div
>
<
/template
>
<
script
>
import
{
listOrders
,
getOrders
,
delOrders
,
addOrders
,
updateOrders
,
listWarehouseInventory
}
from
"@/api/inventory/orders"
export
default
{
name
:
"Orders"
,
dicts
:
[
'inbound_order_status'
,
'outbound_item_status'
,
'label_color'
,
'inventory_status'
,
'inventory_type'
],
data
()
{
return
{
// 遮罩层
loading
:
true
,
// 选中数组
ids
:
[],
// 子表选中数据
checkedInventory
:
[],
// 非单个禁用
single
:
true
,
// 非多个禁用
multiple
:
true
,
// 显示搜索条件
showSearch
:
true
,
// 总条数
total
:
0
,
// 出库单主表格数据
ordersList
:
[],
// 库存表格数据
inventoryList
:
[],
// 弹出层标题
title
:
""
,
// 是否显示弹出层
open
:
false
,
// 查询参数
queryParams
:
{
pageNum
:
1
,
pageSize
:
10
,
orderId
:
null
,
systemNo
:
null
,
orderTypeId
:
null
,
batchCode
:
null
,
warehouseId
:
null
,
ownerId
:
null
,
orderStatus
:
null
,
inboundDate
:
null
,
destination
:
null
,
totalPlannedQuantity
:
null
,
totalActualQuantity
:
null
,
totalPackages
:
null
,
isUsed
:
null
,
sortNo
:
null
,
createUserCode
:
null
,
updateUserCode
:
null
}
,
// 表单参数
form
:
{
}
,
// 表单校验
rules
:
{
}
}
}
,
// 监听仓库ID变化
watch
:
{
'form.warehouseId'
(
newVal
)
{
if
(
newVal
)
{
this
.
queryWarehouseInventory
(
newVal
)
}
else
{
this
.
inventoryList
=
[]
}
}
}
,
created
()
{
this
.
getList
()
}
,
methods
:
{
/** 查询出库单主列表 */
getList
()
{
this
.
loading
=
true
listOrders
(
this
.
queryParams
).
then
(
response
=>
{
this
.
ordersList
=
response
.
rows
this
.
total
=
response
.
total
this
.
loading
=
false
}
)
}
,
// 取消按钮
cancel
()
{
this
.
open
=
false
this
.
reset
()
}
,
// 表单重置
reset
()
{
this
.
form
=
{
id
:
null
,
orderId
:
null
,
systemNo
:
null
,
orderTypeId
:
null
,
batchCode
:
null
,
warehouseId
:
null
,
ownerId
:
null
,
orderStatus
:
null
,
inboundDate
:
null
,
destination
:
null
,
totalPlannedQuantity
:
null
,
totalActualQuantity
:
null
,
totalPackages
:
null
,
remark
:
null
,
isUsed
:
null
,
sortNo
:
null
,
createTime
:
null
,
createUserCode
:
null
,
updateTime
:
null
,
updateUserCode
:
null
}
this
.
inventoryList
=
[]
this
.
resetForm
(
"form"
)
}
,
// 查询仓库库存
queryWarehouseInventory
(
warehouseId
)
{
this
.
loading
=
true
listWarehouseInventory
(
warehouseId
).
then
(
response
=>
{
this
.
inventoryList
=
response
.
rows
||
response
.
data
||
response
// 按货物ID分类
this
.
groupInventoryByMaterialId
()
this
.
loading
=
false
}
).
catch
(
error
=>
{
this
.
loading
=
false
console
.
error
(
'查询库存失败:'
,
error
)
}
)
}
,
// 按货物ID分类库存数据
groupInventoryByMaterialId
()
{
// 这里可以根据需要实现按货物ID分类的逻辑
// 例如:将同一货物ID的库存数据合并或排序
this
.
inventoryList
.
sort
((
a
,
b
)
=>
{
if
(
a
.
materialId
<
b
.
materialId
)
return
-
1
if
(
a
.
materialId
>
b
.
materialId
)
return
1
return
0
}
)
}
,
/** 搜索按钮操作 */
handleQuery
()
{
this
.
queryParams
.
pageNum
=
1
this
.
getList
()
}
,
/** 重置按钮操作 */
resetQuery
()
{
this
.
resetForm
(
"queryForm"
)
this
.
handleQuery
()
}
,
// 多选框选中数据
handleSelectionChange
(
selection
)
{
this
.
ids
=
selection
.
map
(
item
=>
item
.
id
)
this
.
single
=
selection
.
length
!==
1
this
.
multiple
=
!
selection
.
length
}
,
/** 新增按钮操作 */
handleAdd
()
{
this
.
reset
()
this
.
open
=
true
this
.
title
=
"添加出库单主"
}
,
/** 修改按钮操作 */
handleUpdate
(
row
)
{
this
.
reset
()
const
id
=
row
.
id
||
this
.
ids
getOrders
(
id
).
then
(
response
=>
{
this
.
form
=
response
.
data
// 如果有inventoryList直接使用,否则根据仓库ID查询
if
(
response
.
data
.
inventoryList
&&
response
.
data
.
inventoryList
.
length
>
0
)
{
this
.
inventoryList
=
response
.
data
.
inventoryList
// 按货物ID分类
this
.
groupInventoryByMaterialId
()
}
else
if
(
response
.
data
.
warehouseId
)
{
this
.
queryWarehouseInventory
(
response
.
data
.
warehouseId
)
}
this
.
open
=
true
this
.
title
=
"修改出库单主"
}
)
}
,
/** 提交按钮 */
submitForm
()
{
this
.
$refs
[
"form"
].
validate
(
valid
=>
{
if
(
valid
)
{
this
.
form
.
inventoryList
=
this
.
inventoryList
if
(
this
.
form
.
id
!=
null
)
{
updateOrders
(
this
.
form
).
then
(
response
=>
{
this
.
$modal
.
msgSuccess
(
"修改成功"
)
this
.
open
=
false
this
.
getList
()
}
)
}
else
{
addOrders
(
this
.
form
).
then
(
response
=>
{
this
.
$modal
.
msgSuccess
(
"新增成功"
)
this
.
open
=
false
this
.
getList
()
}
)
}
}
}
)
}
,
/** 删除按钮操作 */
handleDelete
(
row
)
{
const
ids
=
row
.
id
||
this
.
ids
this
.
$modal
.
confirm
(
'是否确认删除出库单主编号为"'
+
ids
+
'"的数据项?'
).
then
(
function
()
{
return
delOrders
(
ids
)
}
).
then
(()
=>
{
this
.
getList
()
this
.
$modal
.
msgSuccess
(
"删除成功"
)
}
).
catch
(()
=>
{
}
)
}
,
/** 库存序号 */
rowInventoryIndex
({
row
,
rowIndex
}
)
{
row
.
index
=
rowIndex
+
1
}
,
/** 库存添加按钮操作 */
handleAddInventoryItem
()
{
let
obj
=
{
}
obj
.
materialId
=
""
obj
.
batchId
=
""
obj
.
warehouseId
=
""
obj
.
locationId
=
""
obj
.
ownerId
=
""
obj
.
quantity
=
""
obj
.
lockedQuantity
=
""
obj
.
selectQty
=
""
obj
.
inventoryStatus
=
""
obj
.
inventoryType
=
""
obj
.
unitWeight
=
""
obj
.
lastInboundTime
=
null
obj
.
lastOutboundTime
=
null
obj
.
isUsed
=
""
obj
.
sortNo
=
""
this
.
inventoryList
.
push
(
obj
)
}
,
/** 验证选择数量 */
validateSelectQty
(
row
)
{
const
selectQty
=
Number
(
row
.
selectQty
)
||
0
const
availableQty
=
(
Number
(
row
.
quantity
)
||
0
)
-
(
Number
(
row
.
lockedQuantity
)
||
0
)
if
(
selectQty
<
0
)
{
this
.
$message
.
error
(
'选择数量不能为负数'
)
row
.
selectQty
=
''
return
false
}
if
(
selectQty
>
availableQty
)
{
this
.
$message
.
error
(
'选择数量不能超过可用库存'
)
row
.
selectQty
=
''
return
false
}
return
true
}
,
/** 库存删除按钮操作 */
handleDeleteInventoryItem
()
{
if
(
this
.
checkedInventory
.
length
==
0
)
{
this
.
$modal
.
msgError
(
"请先选择要删除的库存数据"
)
}
else
{
const
inventoryList
=
this
.
inventoryList
const
checkedInventory
=
this
.
checkedInventory
this
.
inventoryList
=
inventoryList
.
filter
(
function
(
item
)
{
return
checkedInventory
.
indexOf
(
item
.
index
)
==
-
1
}
)
}
}
,
/** 复选框选中数据 */
handleInventorySelectionChange
(
selection
)
{
this
.
checkedInventory
=
selection
.
map
(
item
=>
item
.
index
)
}
,
/** 导出按钮操作 */
handleExport
()
{
this
.
download
(
'inventory/orders/export'
,
{
...
this
.
queryParams
}
,
`orders_${new Date().getTime()
}
.xlsx`
)
}
}
}
<
/script
>
ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
0 → 100644
View file @
203b5590
#错误消息
not.null
=
* 必须填写
user.jcaptcha.error
=
验证码错误
user.jcaptcha.expire
=
验证码已失效
user.not.exists
=
用户不存在/密码错误
user.password.not.match
=
用户不存在/密码错误
user.password.retry.limit.count
=
密码输入错误{0}次
user.password.retry.limit.exceed
=
密码输入错误{0}次,帐户锁定{1}分钟
user.password.delete
=
对不起,您的账号已被删除
user.blocked
=
用户已封禁,请联系管理员
role.blocked
=
角色已封禁,请联系管理员
login.blocked
=
很遗憾,访问IP已被列入系统黑名单
user.logout.success
=
退出成功
length.not.valid
=
长度必须在{min}到{max}个字符之间
user.username.not.valid
=
* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
user.password.not.valid
=
* 5-50个字符
user.email.not.valid
=
邮箱格式错误
user.mobile.phone.number.not.valid
=
手机号格式错误
user.login.success
=
登录成功
user.register.success
=
注册成功
user.notfound
=
请重新登录
user.forcelogout
=
管理员强制退出,请重新登录
user.unknown.error
=
未知错误,请重新登录
##文件上传消息
upload.exceed.maxSize
=
上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
upload.filename.exceed.length
=
上传的文件名最长{0}个字符
##权限
no.permission
=
您没有数据的权限,请联系管理员添加权限 [{0}]
no.create.permission
=
您没有创建数据的权限,请联系管理员添加权限 [{0}]
no.update.permission
=
您没有修改数据的权限,请联系管理员添加权限 [{0}]
no.delete.permission
=
您没有删除数据的权限,请联系管理员添加权限 [{0}]
no.export.permission
=
您没有导出数据的权限,请联系管理员添加权限 [{0}]
no.view.permission
=
您没有查看数据的权限,请联系管理员添加权限 [{0}]
\ No newline at end of file
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/OutboundOrderItemsInventory.java
0 → 100644
View file @
203b5590
package
com
.
ruoyi
.
inventory
.
domain
;
import
org.apache.commons.lang3.builder.ToStringBuilder
;
import
org.apache.commons.lang3.builder.ToStringStyle
;
/**
* 出库单明细库存DTO对象 outbound_order_items_inventory
*
* @author ruoyi
* @date 2025-12-03
*/
public
class
OutboundOrderItemsInventory
{
private
static
final
long
serialVersionUID
=
1L
;
/** 出库单明细 */
private
OutboundOrderItems
outboundOrderItems
;
/** 库存信息 */
private
Inventory
inventory
;
public
OutboundOrderItems
getOutboundOrderItems
()
{
return
outboundOrderItems
;
}
public
void
setOutboundOrderItems
(
OutboundOrderItems
outboundOrderItems
)
{
this
.
outboundOrderItems
=
outboundOrderItems
;
}
public
Inventory
getInventory
()
{
return
inventory
;
}
public
void
setInventory
(
Inventory
inventory
)
{
this
.
inventory
=
inventory
;
}
@Override
public
String
toString
()
{
return
new
ToStringBuilder
(
this
,
ToStringStyle
.
MULTI_LINE_STYLE
)
.
append
(
"outboundOrderItems"
,
getOutboundOrderItems
())
.
append
(
"inventory"
,
getInventory
())
.
toString
();
}
}
\ No newline at end of file
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/OutboundOrderLog.java
0 → 100644
View file @
203b5590
package
com
.
ruoyi
.
inventory
.
domain
;
import
org.apache.commons.lang3.builder.ToStringBuilder
;
import
org.apache.commons.lang3.builder.ToStringStyle
;
import
com.ruoyi.common.annotation.Excel
;
import
com.ruoyi.common.core.domain.BaseEntity
;
/**
* 出库明细子(仅用于锁定数量统计)对象 outbound_order_log
*
* @author ruoyi
* @date 2025-12-03
*/
public
class
OutboundOrderLog
extends
BaseEntity
{
private
static
final
long
serialVersionUID
=
1L
;
/** 明细ID(主键) */
private
String
id
;
/** 货物ID */
@Excel
(
name
=
"货物ID"
)
private
String
orderId
;
/** 货物ID */
@Excel
(
name
=
"货物ID"
)
private
String
materialId
;
/** 仓库ID */
@Excel
(
name
=
"仓库ID"
)
private
String
warehouseId
;
/** 批次ID */
@Excel
(
name
=
"批次ID"
)
private
String
batchCode
;
/** 实际入库数量 */
@Excel
(
name
=
"实际入库数量"
)
private
Long
actualQuantity
;
/** 明细状态:1-待入库/2-部分入库/3-已完成 */
@Excel
(
name
=
"明细状态:1-待入库/2-部分入库/3-已完成"
)
private
Long
itemStatus
;
/** 数据状态:1-有效/0-删除 */
@Excel
(
name
=
"数据状态:1-有效/0-删除"
)
private
Long
isUsed
;
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
setMaterialId
(
String
materialId
)
{
this
.
materialId
=
materialId
;
}
public
String
getMaterialId
()
{
return
materialId
;
}
public
void
setWarehouseId
(
String
warehouseId
)
{
this
.
warehouseId
=
warehouseId
;
}
public
String
getWarehouseId
()
{
return
warehouseId
;
}
public
void
setBatchCode
(
String
batchCode
)
{
this
.
batchCode
=
batchCode
;
}
public
String
getBatchCode
()
{
return
batchCode
;
}
public
void
setActualQuantity
(
Long
actualQuantity
)
{
this
.
actualQuantity
=
actualQuantity
;
}
public
Long
getActualQuantity
()
{
return
actualQuantity
;
}
public
void
setItemStatus
(
Long
itemStatus
)
{
this
.
itemStatus
=
itemStatus
;
}
public
Long
getItemStatus
()
{
return
itemStatus
;
}
public
void
setIsUsed
(
Long
isUsed
)
{
this
.
isUsed
=
isUsed
;
}
public
Long
getIsUsed
()
{
return
isUsed
;
}
@Override
public
String
toString
()
{
return
new
ToStringBuilder
(
this
,
ToStringStyle
.
MULTI_LINE_STYLE
)
.
append
(
"id"
,
getId
())
.
append
(
"orderId"
,
getOrderId
())
.
append
(
"materialId"
,
getMaterialId
())
.
append
(
"warehouseId"
,
getWarehouseId
())
.
append
(
"batchCode"
,
getBatchCode
())
.
append
(
"actualQuantity"
,
getActualQuantity
())
.
append
(
"itemStatus"
,
getItemStatus
())
.
append
(
"isUsed"
,
getIsUsed
())
.
toString
();
}
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/OutboundOrderLogMapper.java
0 → 100644
View file @
203b5590
package
com
.
ruoyi
.
inventory
.
mapper
;
import
java.util.List
;
import
com.ruoyi.inventory.domain.OutboundOrderLog
;
/**
* 出库明细子(仅用于锁定数量统计)Mapper接口
*
* @author ruoyi
* @date 2025-12-03
*/
public
interface
OutboundOrderLogMapper
{
/**
* 查询出库明细子(仅用于锁定数量统计)
*
* @param id 出库明细子(仅用于锁定数量统计)主键
* @return 出库明细子(仅用于锁定数量统计)
*/
public
OutboundOrderLog
selectOutboundOrderLogById
(
String
id
);
/**
* 查询出库明细子(仅用于锁定数量统计)列表
*
* @param outboundOrderLog 出库明细子(仅用于锁定数量统计)
* @return 出库明细子(仅用于锁定数量统计)集合
*/
public
List
<
OutboundOrderLog
>
selectOutboundOrderLogList
(
OutboundOrderLog
outboundOrderLog
);
/**
* 查询出库明细子(仅用于锁定数量统计)列表
*
* @param outboundOrderLog 出库明细子(仅用于锁定数量统计)
* @return 出库明细子(仅用于锁定数量统计)集合
*/
public
Long
selectLockedQuantity
(
OutboundOrderLog
outboundOrderLog
);
/**
* 新增出库明细子(仅用于锁定数量统计)
*
* @param outboundOrderLog 出库明细子(仅用于锁定数量统计)
* @return 结果
*/
public
int
insertOutboundOrderLog
(
OutboundOrderLog
outboundOrderLog
);
/**
* 修改出库明细子(仅用于锁定数量统计)
*
* @param outboundOrderLog 出库明细子(仅用于锁定数量统计)
* @return 结果
*/
public
int
updateOutboundOrderLog
(
OutboundOrderLog
outboundOrderLog
);
/**
* 删除出库明细子(仅用于锁定数量统计)
*
* @param id 出库明细子(仅用于锁定数量统计)主键
* @return 结果
*/
public
int
deleteOutboundOrderLogById
(
String
id
);
/**
* 批量删除出库明细子(仅用于锁定数量统计)
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public
int
deleteOutboundOrderLogByIds
(
String
[]
ids
);
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IOutboundOrderLogService.java
0 → 100644
View file @
203b5590
package
com
.
ruoyi
.
inventory
.
service
;
import
java.util.List
;
import
com.ruoyi.inventory.domain.OutboundOrderLog
;
/**
* 出库明细子(仅用于锁定数量统计)Service接口
*
* @author ruoyi
* @date 2025-12-03
*/
public
interface
IOutboundOrderLogService
{
/**
* 查询出库明细子(仅用于锁定数量统计)
*
* @param id 出库明细子(仅用于锁定数量统计)主键
* @return 出库明细子(仅用于锁定数量统计)
*/
public
OutboundOrderLog
selectOutboundOrderLogById
(
String
id
);
/**
* 查询出库明细子(仅用于锁定数量统计)列表
*
* @param outboundOrderLog 出库明细子(仅用于锁定数量统计)
* @return 出库明细子(仅用于锁定数量统计)集合
*/
public
List
<
OutboundOrderLog
>
selectOutboundOrderLogList
(
OutboundOrderLog
outboundOrderLog
);
/**
* 新增出库明细子(仅用于锁定数量统计)
*
* @param outboundOrderLog 出库明细子(仅用于锁定数量统计)
* @return 结果
*/
public
int
insertOutboundOrderLog
(
OutboundOrderLog
outboundOrderLog
);
/**
* 修改出库明细子(仅用于锁定数量统计)
*
* @param outboundOrderLog 出库明细子(仅用于锁定数量统计)
* @return 结果
*/
public
int
updateOutboundOrderLog
(
OutboundOrderLog
outboundOrderLog
);
/**
* 批量删除出库明细子(仅用于锁定数量统计)
*
* @param ids 需要删除的出库明细子(仅用于锁定数量统计)主键集合
* @return 结果
*/
public
int
deleteOutboundOrderLogByIds
(
String
[]
ids
);
/**
* 删除出库明细子(仅用于锁定数量统计)信息
*
* @param id 出库明细子(仅用于锁定数量统计)主键
* @return 结果
*/
public
int
deleteOutboundOrderLogById
(
String
id
);
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/OutboundOrderLogServiceImpl.java
0 → 100644
View file @
203b5590
package
com
.
ruoyi
.
inventory
.
service
.
impl
;
import
java.util.List
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
com.ruoyi.inventory.mapper.OutboundOrderLogMapper
;
import
com.ruoyi.inventory.domain.OutboundOrderLog
;
import
com.ruoyi.inventory.service.IOutboundOrderLogService
;
/**
* 出库明细子(仅用于锁定数量统计)Service业务层处理
*
* @author ruoyi
* @date 2025-12-03
*/
@Service
public
class
OutboundOrderLogServiceImpl
implements
IOutboundOrderLogService
{
@Autowired
private
OutboundOrderLogMapper
outboundOrderLogMapper
;
/**
* 查询出库明细子(仅用于锁定数量统计)
*
* @param id 出库明细子(仅用于锁定数量统计)主键
* @return 出库明细子(仅用于锁定数量统计)
*/
@Override
public
OutboundOrderLog
selectOutboundOrderLogById
(
String
id
)
{
return
outboundOrderLogMapper
.
selectOutboundOrderLogById
(
id
);
}
/**
* 查询出库明细子(仅用于锁定数量统计)列表
*
* @param outboundOrderLog 出库明细子(仅用于锁定数量统计)
* @return 出库明细子(仅用于锁定数量统计)
*/
@Override
public
List
<
OutboundOrderLog
>
selectOutboundOrderLogList
(
OutboundOrderLog
outboundOrderLog
)
{
return
outboundOrderLogMapper
.
selectOutboundOrderLogList
(
outboundOrderLog
);
}
/**
* 新增出库明细子(仅用于锁定数量统计)
*
* @param outboundOrderLog 出库明细子(仅用于锁定数量统计)
* @return 结果
*/
@Override
public
int
insertOutboundOrderLog
(
OutboundOrderLog
outboundOrderLog
)
{
return
outboundOrderLogMapper
.
insertOutboundOrderLog
(
outboundOrderLog
);
}
/**
* 修改出库明细子(仅用于锁定数量统计)
*
* @param outboundOrderLog 出库明细子(仅用于锁定数量统计)
* @return 结果
*/
@Override
public
int
updateOutboundOrderLog
(
OutboundOrderLog
outboundOrderLog
)
{
return
outboundOrderLogMapper
.
updateOutboundOrderLog
(
outboundOrderLog
);
}
/**
* 批量删除出库明细子(仅用于锁定数量统计)
*
* @param ids 需要删除的出库明细子(仅用于锁定数量统计)主键
* @return 结果
*/
@Override
public
int
deleteOutboundOrderLogByIds
(
String
[]
ids
)
{
return
outboundOrderLogMapper
.
deleteOutboundOrderLogByIds
(
ids
);
}
/**
* 删除出库明细子(仅用于锁定数量统计)信息
*
* @param id 出库明细子(仅用于锁定数量统计)主键
* @return 结果
*/
@Override
public
int
deleteOutboundOrderLogById
(
String
id
)
{
return
outboundOrderLogMapper
.
deleteOutboundOrderLogById
(
id
);
}
}
ruoyi-inventory/src/main/resources/mapper/inventory/OutboundOrderLogMapper.xml
0 → 100644
View file @
203b5590
<?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">
<mapper
namespace=
"com.ruoyi.inventory.mapper.OutboundOrderLogMapper"
>
<resultMap
type=
"OutboundOrderLog"
id=
"OutboundOrderLogResult"
>
<result
property=
"id"
column=
"id"
/>
<result
property=
"orderId"
column=
"order_id"
/>
<result
property=
"materialId"
column=
"material_id"
/>
<result
property=
"warehouseId"
column=
"warehouse_id"
/>
<result
property=
"batchCode"
column=
"batch_code"
/>
<result
property=
"actualQuantity"
column=
"actual_quantity"
/>
<result
property=
"itemStatus"
column=
"item_status"
/>
<result
property=
"isUsed"
column=
"is_used"
/>
</resultMap>
<sql
id=
"selectOutboundOrderLogVo"
>
select id, order_id, material_id, warehouse_id, batch_code, actual_quantity, item_status, is_used
from outbound_order_log
</sql>
<select
id=
"selectOutboundOrderLogList"
parameterType=
"OutboundOrderLog"
resultMap=
"OutboundOrderLogResult"
>
<include
refid=
"selectOutboundOrderLogVo"
/>
<where>
<if
test=
"orderId != null and orderId != ''"
>
and order_id = #{orderId}
</if>
<if
test=
"materialId != null and materialId != ''"
>
and material_id = #{materialId}
</if>
<if
test=
"warehouseId != null and warehouseId != ''"
>
and warehouse_id = #{warehouseId}
</if>
<if
test=
"batchCode != null and batchCode != ''"
>
and batch_code = #{batchCode}
</if>
<if
test=
"actualQuantity != null "
>
and actual_quantity = #{actualQuantity}
</if>
<if
test=
"itemStatus != null "
>
and item_status = #{itemStatus}
</if>
<if
test=
"isUsed != null "
>
and is_used = #{isUsed}
</if>
</where>
</select>
<select
id=
"selectLockedQuantity"
parameterType=
"OutboundOrderLog"
resultType=
"java.lang.Long"
>
select ifnull(sum(actual_quantity), 0)
from outbound_order_log
<where>
<if
test=
"orderId != null and orderId != ''"
>
and order_id = #{orderId}
</if>
<if
test=
"materialId != null and materialId != ''"
>
and material_id = #{materialId}
</if>
<if
test=
"warehouseId != null and warehouseId != ''"
>
and warehouse_id = #{warehouseId}
</if>
<if
test=
"batchCode != null and batchCode != ''"
>
and batch_code = #{batchCode}
</if>
<if
test=
"actualQuantity != null "
>
and actual_quantity = #{actualQuantity}
</if>
<if
test=
"itemStatus != null "
>
and item_status = #{itemStatus}
</if>
<if
test=
"isUsed != null "
>
and is_used = #{isUsed}
</if>
</where>
</select>
<select
id=
"selectOutboundOrderLogById"
parameterType=
"String"
resultMap=
"OutboundOrderLogResult"
>
<include
refid=
"selectOutboundOrderLogVo"
/>
where id = #{id}
</select>
<insert
id=
"insertOutboundOrderLog"
parameterType=
"OutboundOrderLog"
>
insert into outbound_order_log
<trim
prefix=
"("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"id != null"
>
id,
</if>
<if
test=
"orderId != null"
>
order_id,
</if>
<if
test=
"materialId != null"
>
material_id,
</if>
<if
test=
"warehouseId != null"
>
warehouse_id,
</if>
<if
test=
"batchCode != null"
>
batch_code,
</if>
<if
test=
"actualQuantity != null"
>
actual_quantity,
</if>
<if
test=
"itemStatus != null"
>
item_status,
</if>
<if
test=
"isUsed != null"
>
is_used,
</if>
</trim>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"id != null"
>
#{id},
</if>
<if
test=
"orderId != null"
>
#{orderId},
</if>
<if
test=
"materialId != null"
>
#{materialId},
</if>
<if
test=
"warehouseId != null"
>
#{warehouseId},
</if>
<if
test=
"batchCode != null"
>
#{batchCode},
</if>
<if
test=
"actualQuantity != null"
>
#{actualQuantity},
</if>
<if
test=
"itemStatus != null"
>
#{itemStatus},
</if>
<if
test=
"isUsed != null"
>
#{isUsed},
</if>
</trim>
</insert>
<update
id=
"updateOutboundOrderLog"
parameterType=
"OutboundOrderLog"
>
update outbound_order_log
<trim
prefix=
"SET"
suffixOverrides=
","
>
<if
test=
"orderId != null"
>
order_id = #{orderId},
</if>
<if
test=
"materialId != null"
>
material_id = #{materialId},
</if>
<if
test=
"warehouseId != null"
>
warehouse_id = #{warehouseId},
</if>
<if
test=
"batchCode != null"
>
batch_code = #{batchCode},
</if>
<if
test=
"actualQuantity != null"
>
actual_quantity = #{actualQuantity},
</if>
<if
test=
"itemStatus != null"
>
item_status = #{itemStatus},
</if>
<if
test=
"isUsed != null"
>
is_used = #{isUsed},
</if>
</trim>
where id = #{id}
</update>
<delete
id=
"deleteOutboundOrderLogById"
parameterType=
"String"
>
delete from outbound_order_log where id = #{id}
</delete>
<delete
id=
"deleteOutboundOrderLogByIds"
parameterType=
"String"
>
delete from outbound_order_log where id in
<foreach
item=
"id"
collection=
"array"
open=
"("
separator=
","
close=
")"
>
#{id}
</foreach>
</delete>
</mapper>
\ No newline at end of file
ruoyi-inventory/src/main/resources/mybatis/mybatis-config.xml
0 → 100644
View file @
203b5590
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局参数 -->
<settings>
<!-- 使全局的映射器启用或禁用缓存 -->
<setting
name=
"cacheEnabled"
value=
"true"
/>
<!-- 允许JDBC 支持自动生成主键 -->
<setting
name=
"useGeneratedKeys"
value=
"true"
/>
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
<setting
name=
"defaultExecutorType"
value=
"SIMPLE"
/>
<!-- 指定 MyBatis 所用日志的具体实现 -->
<setting
name=
"logImpl"
value=
"SLF4J"
/>
<!-- 使用驼峰命名法转换字段 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
</settings>
</configuration>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论