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
98bfcd2b
Commit
98bfcd2b
authored
Dec 09, 2025
by
yubin
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
feeecb39
c30de553
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
1004 行增加
和
4 行删除
+1004
-4
ruoyi-admin-vue/src/api/inventory/inbound_items.js
+8
-0
ruoyi-admin-vue/src/views/inventory/inbound/details.vue
+719
-0
ruoyi-admin-vue/src/views/inventory/inbound/index.vue
+5
-0
ruoyi-admin-vue/src/views/inventory/inbound_items/index.vue
+7
-4
ruoyi-admin/src/main/java/com/ruoyi/web/controller/inventory/InboundOrderItemsController.java
+13
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/vo/InboundDetailsVO.java
+170
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/InboundOrderItemsMapper.java
+7
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IInboundOrderItemsService.java
+7
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/InboundOrderItemsServiceImpl.java
+6
-0
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/InboundOrdersServiceImpl.java
+1
-0
ruoyi-inventory/src/main/resources/mapper/inventory/InboundOrderItemsMapper.xml
+61
-0
没有找到文件。
ruoyi-admin-vue/src/api/inventory/inbound_items.js
View file @
98bfcd2b
...
...
@@ -49,3 +49,11 @@ export function delInbound_items(id) {
method
:
'delete'
})
}
// 统计入库单明细
export
function
inbound_details
(){
return
request
({
url
:
'/inventory/inbound_items/details'
,
method
:
'get'
})
}
ruoyi-admin-vue/src/views/inventory/inbound/details.vue
0 → 100644
View file @
98bfcd2b
<
template
>
<div
class=
"app-container"
>
<!-- 标题栏 + 操作按钮(对齐字典页面) -->
<PageTitle>
<template
#
buttons
>
<el-button
type=
"warning"
plain
icon=
"el-icon-download"
size=
"medium"
@
click=
"handleExport"
v-hasPermi=
"['inventory:inbound:export']"
>
导出
</el-button>
</
template
>
</PageTitle>
<!-- 搜索区域(对齐字典页面的page-wrapper-search组件) -->
<div
class=
"page-container"
>
<page-wrapper-search
:model=
"queryParams"
ref=
"queryForm"
size=
"small"
@
search=
"handleQuery"
@
reset=
"resetQuery"
>
<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=
"批次ID"
prop=
"batchId"
>
<el-input
v-model=
"queryParams.batchId"
placeholder=
"请输入批次ID"
clearable
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"入库类型"
prop=
"orderTypeId"
>
<el-select
v-model=
"queryParams.orderTypeId"
placeholder=
"请选择入库类型"
clearable
>
<el-option
v-for=
"item in inBoundTypeOptions"
:key=
"item.orderTypeId"
:label=
"item.orderTypeName"
:value=
"item.orderTypeId"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"入库单状态"
prop=
"orderStatus"
>
<el-select
v-model=
"queryParams.orderStatus"
placeholder=
"请选择入库单状态"
clearable
>
<el-option
v-for=
"item in inBoundStatusOptions"
:key=
"item.orderStatus"
:label=
"item.orderStatusName"
:value=
"item.orderStatus"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"订单类型"
prop=
"orderType"
>
<el-select
v-model=
"queryParams.orderType"
placeholder=
"请选择订单类型"
clearable
>
<el-option
v-for=
"item in orderTypeOptions"
:key=
"item.orderType"
:label=
"item.orderTypeName"
:value=
"item.orderType"
/>
</el-select>
</el-form-item>
</page-wrapper-search>
<!-- 表格区域(对齐字典页面的样式) -->
<div
class=
"table-container"
>
<el-table
v-loading=
"loading"
height=
"100%"
:data=
"inboundList"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
label=
"物料SAPNO"
align=
"center"
prop=
"materialId"
width=
"200"
/>
<el-table-column
label=
"物料名称"
align=
"center"
prop=
"materialName"
width=
"200"
/>
<el-table-column
label=
"关联入库单ID"
align=
"center"
prop=
"orderId"
:show-overflow-tooltip=
"true"
width=
"200"
/>
<el-table-column
label=
"批次ID"
align=
"center"
prop=
"batchId"
:show-overflow-tooltip=
"true"
width=
"200"
/>
<el-table-column
label=
"仓库ID"
align=
"center"
prop=
"warehouseId"
width=
"200"
/>
<el-table-column
label=
"库位ID"
align=
"center"
prop=
"locationId"
width=
"200"
/>
<el-table-column
label=
"入库数量"
align=
"center"
prop=
"actualQuantity"
width=
"200"
/>
<el-table-column
label=
"件数"
align=
"center"
prop=
"actualPackages"
width=
"200"
/>
<el-table-column
label=
"单价"
align=
"center"
prop=
"unitPrice"
width=
"200"
/>
<el-table-column
label=
"入库批次物料总价"
align=
"center"
prop=
"totalPrice"
width=
"200"
/>
<el-table-column
label=
"标签颜色"
align=
"center"
prop=
"labelColor"
width=
"200"
/>
<el-table-column
label=
"备注"
align=
"center"
prop=
"remark"
width=
"200"
/>
<el-table-column
label=
"入库时间"
align=
"center"
prop=
"inboundDate"
width=
"200"
>
<
template
slot-scope=
"scope"
>
<span>
{{
parseTime
(
scope
.
row
.
inboundDate
)
}}
</span>
</
template
>
</el-table-column>
<!-- <el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
fixed="right"
width="250"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-more"
@click="handleDetail(scope.row)"
v-hasPermi="['inventory:inbound:view']"
>详情</el-button>
</template>
</el-table-column> -->
</el-table>
</div>
<!-- 分页组件(位置对齐) -->
<pagination
v-show=
"total>0"
:total=
"total"
:page
.
sync=
"queryParams.pageNum"
:limit
.
sync=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</div>
<!-- 入库单详情弹窗 -->
<!-- <el-dialog
title="入库单详细信息"
:visible.sync="detailOpen"
width="1200px"
append-to-body
class="scrollable-dialog"
>
<div class="detail-container">
<el-descriptions :column="2" border class="mb20">
<el-descriptions-item label="入库单号">{{ detailForm.orderId || '-' }}</el-descriptions-item>
<el-descriptions-item label="系统编号">{{ detailForm.systemNo || '-' }}</el-descriptions-item>
<el-descriptions-item label="批次ID">{{ detailForm.batchId || '-' }}</el-descriptions-item>
<el-descriptions-item label="货主ID">{{ detailForm.ownerId || '-' }}</el-descriptions-item>
<el-descriptions-item label="入库类型">
{{ getInBoundTypeName(detailForm.orderTypeId) }}
</el-descriptions-item>
<el-descriptions-item label="订单类型">
{{ getOrderTypeName(detailForm.orderType) }}
</el-descriptions-item>
<el-descriptions-item label="入库日期">{{ detailForm.inboundDate || '-' }}</el-descriptions-item>
<el-descriptions-item label="负责人">{{ detailForm.opUserName || '-' }}</el-descriptions-item>
<el-descriptions-item label="计划量">{{ detailForm.totalPlannedQuantity || '-' }}</el-descriptions-item>
<el-descriptions-item label="实际量">{{ detailForm.totalActualQuantity || '-' }}</el-descriptions-item>
<el-descriptions-item label="总件数">{{ detailForm.totalPackages || '-' }}</el-descriptions-item>
<el-descriptions-item label="仓库ID">{{ detailForm.warehouseId || '-' }}</el-descriptions-item>
<el-descriptions-item label="备注" :span="2">
<div class="remark-text">{{ detailForm.remark || '-' }}</div>
</el-descriptions-item>
</el-descriptions>
<el-divider content-position="center">入库单明细信息</el-divider>
<InboundItems
ref="detailItemsRef"
v-model="detailForm.inboundOrderItemsList"
:embedded="true"
:inboundOrderId="detailForm.inboundOrderId"
:isEditable="isEditable"
:show-search-form="false"
:show-pagination="false"
:show-toolbar="false"
:show-action-column="false"
:show-selection="false"
:show-add-button="false"
:show-edit-button="false"
:show-delete-button="false"
/>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="detailOpen = false">关闭</el-button>
</div>
</el-dialog> -->
</div>
</template>
<
script
>
import
{
inbound_details
}
from
"@/api/inventory/inbound_items"
import
{
batchAddInventory
}
from
"@/api/inventory/inventory"
import
InboundItems
from
"@/views/inventory/inbound_items/index.vue"
import
PageTitle
from
"@/components/PageTitle"
// 引入字典页面的标题组件
import
PageWrapperSearch
from
"@/components/Search/PageWrapperSearch"
// 引入搜索包装组件
export
default
{
name
:
"Inbound"
,
components
:
{
InboundItems
,
PageTitle
,
PageWrapperSearch
},
data
()
{
return
{
inBoundTypeOptions
:
[
{
orderTypeId
:
'1'
,
orderTypeName
:
'入库类型1'
},
{
orderTypeId
:
'2'
,
orderTypeName
:
'入库类型2'
}
],
inBoundStatusOptions
:
[
{
orderStatus
:
1
,
orderStatusName
:
'草稿'
,
type
:
'info'
},
{
orderStatus
:
2
,
orderStatusName
:
'已完成'
,
type
:
'success'
},
{
orderStatus
:
3
,
orderStatusName
:
'已取消'
,
type
:
'danger'
}
],
orderTypeOptions
:
[
{
orderType
:
'1'
,
orderTypeName
:
'订单类型1'
},
{
orderType
:
'2'
,
orderTypeName
:
'订单类型2'
}
],
isEditable
:
true
,
// 物料组件显示
materialSelectOpen
:
false
,
selectedMaterialIds
:
[],
inboundItemsUpdateStatus
:
false
,
// 组件带来的选中的物料详情(code、name)
selectedMaterials
:
[],
detailOpen
:
false
,
detailForm
:
{},
// 新增详情表单数据
// 组件监听修改时的orderId变化
inboundOrderId
:
null
,
// 选中的明细项
selectedItems
:
[],
// 遮罩层
loading
:
true
,
// 选中数组
ids
:
[],
// 非单个禁用
single
:
true
,
// 非多个禁用
multiple
:
true
,
// 显示搜索条件
showSearch
:
true
,
// 总条数
total
:
0
,
// 入库表格数据
inboundList
:
[],
// 弹出层标题
title
:
""
,
// 是否显示弹出层
open
:
false
,
// 查询参数
queryParams
:
{
pageNum
:
1
,
pageSize
:
10
,
orderId
:
null
,
orderTypeId
:
null
,
systemNo
:
null
,
batchId
:
null
,
warehouseId
:
null
,
ownerId
:
null
,
orderStatus
:
null
,
orderType
:
null
},
// 表单参数
form
:
{
id
:
null
,
orderId
:
null
,
orderTypeId
:
null
,
batchId
:
null
,
warehouseId
:
null
,
ownerId
:
null
,
orderStatus
:
1
,
referenceNo
:
null
,
plannedArrivalDate
:
undefined
,
actualArrivalDate
:
undefined
,
totalPlannedQuantity
:
null
,
totalActualQuantity
:
null
,
totalPackages
:
null
,
remark
:
null
,
opUserName
:
null
,
isUsed
:
null
,
sortNo
:
null
,
createTime
:
null
,
createUserCode
:
null
,
updateTime
:
null
,
updateUserCode
:
null
,
// 明细列表
inboundOrderItemsList
:
[]
},
// 表单校验
rules
:
{
orderId
:
[
{
required
:
true
,
message
:
"入库单号不能为空"
,
trigger
:
"blur"
}
],
orderTypeId
:
[
{
required
:
true
,
message
:
"入库类型不能为空"
,
trigger
:
"blur"
}
],
systemNo
:
[
{
required
:
true
,
message
:
"系统编号不能为空"
,
trigger
:
"blur"
}
],
batchId
:
[
{
required
:
true
,
message
:
"批次ID不能为空"
,
trigger
:
"blur"
}
]
}
}
},
created
()
{
this
.
getList
()
},
methods
:
{
/** 查询入库列表 */
getList
()
{
this
.
loading
=
true
inbound_details
(
this
.
queryParams
).
then
(
response
=>
{
this
.
inboundList
=
response
.
rows
this
.
total
=
response
.
total
this
.
loading
=
false
}).
catch
(()
=>
{
this
.
loading
=
false
})
},
/** 获取状态样式类型 */
getStatusType
(
status
)
{
const
item
=
this
.
inBoundStatusOptions
.
find
(
item
=>
item
.
orderStatus
===
status
)
return
item
?
item
.
type
:
'info'
},
/** 获取状态类型名称 */
getStatusName
(
status
)
{
const
item
=
this
.
inBoundStatusOptions
.
find
(
item
=>
item
.
orderStatus
===
status
)
return
item
?
item
.
orderStatusName
:
status
},
getInBoundTypeName
(
typeId
)
{
if
(
!
typeId
)
return
'未知类型'
const
item
=
this
.
inBoundTypeOptions
.
find
(
item
=>
item
.
orderTypeId
===
typeId
)
return
item
?
item
.
orderTypeName
:
'未知类型'
},
getOrderTypeName
(
type
)
{
if
(
!
type
)
return
'未知类型'
const
item
=
this
.
orderTypeOptions
.
find
(
item
=>
item
.
orderType
===
type
)
return
item
?
item
.
orderTypeName
:
'未知类型'
},
/** 搜索按钮操作 */
handleQuery
()
{
this
.
queryParams
.
pageNum
=
1
this
.
getList
()
},
/** 重置按钮操作 */
resetQuery
()
{
this
.
dateRange
=
[]
this
.
queryParams
=
{
pageNum
:
1
,
pageSize
:
10
,
orderId
:
null
,
orderTypeId
:
null
,
systemNo
:
null
,
batchId
:
null
,
warehouseId
:
null
,
ownerId
:
null
,
orderStatus
:
null
,
orderType
:
null
}
// this.$refs.queryForm.resetFields()
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
getInbound
(
id
).
then
(
response
=>
{
this
.
form
=
response
.
data
// 加载明细数据
this
.
inboundOrderId
=
id
this
.
$nextTick
(()
=>
{
})
this
.
open
=
true
this
.
title
=
"修改入库单"
})
},
/** 查看详情 */
handleDetail
(
row
)
{
this
.
reset
()
const
id
=
row
.
id
this
.
isEditable
=
false
getInbound
(
id
).
then
(
response
=>
{
// 加载明细数据到详情
this
.
detailForm
=
response
.
data
this
.
detailForm
.
inboundOrderId
=
id
this
.
detailOpen
=
true
})
},
// 打开物料选择弹窗
showMaterials
(
status
)
{
this
.
materialSelectOpen
=
status
;
if
(
status
)
{
// 只有打开弹窗时才清空选择
this
.
selectedMaterialIds
=
[];
// 先清空父组件数据
this
.
selectedMaterials
=
[];
this
.
$nextTick
(()
=>
{
// 确保弹窗渲染完成后再调用子组件方法
this
.
$refs
.
materialSelector
?.
clearSelection
();
});
}
},
// 物料选择变化回调
handleMaterialChange
(
selectedRows
)
{
this
.
selectedMaterials
=
selectedRows
;
},
// 确认选择物料并添加到明细
confirmMaterialSelect
()
{
if
(
this
.
selectedMaterials
.
length
===
0
)
{
this
.
$message
.
warning
(
"请选择物料"
);
return
;
}
// 将选中的物料添加到入库明细
this
.
selectedMaterials
.
forEach
(
material
=>
{
// 检查是否已存在该物料,避免重复添加
const
exists
=
this
.
form
.
inboundOrderItemsList
.
some
(
item
=>
item
.
sapNo
===
material
.
sapNo
);
if
(
!
exists
)
{
this
.
form
.
inboundOrderItemsList
.
push
({
materialId
:
material
.
sapNo
,
// 存储物料编码
materialName
:
material
.
materialName
,
// 仅用于展示
// 其他需要的字段...
});
}
});
this
.
materialSelectOpen
=
false
;
this
.
$refs
.
inboundItemsRef
.
handleAddItem
(
this
.
selectedMaterials
)
this
.
$message
.
success
(
`成功添加
${
this
.
selectedMaterials
.
length
}
个物料`
);
},
/** 确认入库操作 */
async
handleConfirm
(
row
)
{
// 标记为 async 函数
try
{
// 第一步:确认弹窗
await
this
.
$confirm
(
'确认要入库吗?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
});
// 第二步:等待 listInbound_items 执行完成
const
queryForm
=
{
pageNum
:
1
,
pageSize
:
9999
,
orderId
:
row
.
orderId
};
const
response
=
await
listInbound_items
(
queryForm
);
row
.
inboundOrderItemsList
=
response
.
rows
;
// 第三步:确保数据存在后调用入库接口
if
(
!
row
.
inboundOrderItemsList
||
row
.
inboundOrderItemsList
.
length
===
0
)
{
this
.
$message
.
warning
(
'暂无入库明细数据,无法确认入库'
);
return
;
}
await
batchAddInventory
(
row
.
inboundOrderItemsList
);
// 第四步:操作成功提示
this
.
$modal
.
msgSuccess
(
"确认成功"
);
this
.
$message
.
success
(
'确认入库成功'
);
row
.
orderStatus
=
2
updateInbound
(
row
).
then
(()
=>
{
this
.
getList
();
})
}
catch
(
error
)
{
// 捕获取消确认/接口失败的异常
if
(
error
!==
'cancel'
)
{
this
.
$message
.
error
(
'确认入库失败:'
+
(
error
.
msg
||
'网络异常'
));
console
.
log
(
error
)
}
}
},
/** 删除按钮操作 */
handleDelete
(
row
)
{
const
ids
=
row
.
id
||
this
.
ids
.
length
this
.
$confirm
((
row
.
orderId
?
'是否确认删除入库单编号为"'
+
row
.
orderId
+
'"的数据项?'
:
'是否确认删除选中的'
+
ids
+
'条入库单'
),
'提示'
,
{
type
:
'warning'
}).
then
(()
=>
{
return
delInbound
(
ids
)
}).
then
(()
=>
{
this
.
getList
()
this
.
$message
.
success
(
"删除成功"
)
}).
catch
(()
=>
{})
},
/** 提交按钮 */
submitForm
()
{
this
.
$refs
[
"form"
].
validate
(
valid
=>
{
if
(
!
valid
)
return
// 验证明细表
const
errors
=
this
.
$refs
.
inboundItemsRef
?
this
.
$refs
.
inboundItemsRef
.
validate
()
:
[]
if
(
errors
.
length
>
0
)
{
this
.
$message
.
error
(
errors
.
join
(
';'
))
return
}
// 确保明细项数量大于0
if
(
!
this
.
form
.
inboundOrderItemsList
||
this
.
form
.
inboundOrderItemsList
.
length
===
0
)
{
this
.
$message
.
warning
(
'请至少添加一条入库明细'
)
return
}
// 自动计算总数
this
.
calculateTotals
()
// 提交数据
const
submitData
=
{
...
this
.
form
,
inboundOrderItemsList
:
this
.
form
.
inboundOrderItemsList
.
map
(
item
=>
({
...
item
,
orderId
:
this
.
form
.
orderId
,
// 确保明细项有主表ID
batchId
:
this
.
form
.
batchId
}))
}
if
(
this
.
form
.
id
!=
null
)
{
updateInbound
(
submitData
).
then
(
response
=>
{
this
.
$message
.
success
(
"修改成功"
)
this
.
open
=
false
this
.
getList
()
})
}
else
{
addInbound
(
submitData
).
then
(
response
=>
{
this
.
$message
.
success
(
"新增成功"
)
this
.
open
=
false
this
.
getList
()
})
}
})
},
/** 取消按钮 */
cancel
()
{
this
.
open
=
false
this
.
reset
()
},
/** 表单重置 */
reset
()
{
this
.
form
=
{
id
:
null
,
orderId
:
null
,
orderTypeId
:
null
,
batchId
:
null
,
warehouseId
:
null
,
ownerId
:
null
,
orderStatus
:
1
,
referenceNo
:
null
,
plannedArrivalDate
:
null
,
actualArrivalDate
:
null
,
totalPlannedQuantity
:
0
,
totalActualQuantity
:
0
,
totalPackages
:
0
,
remark
:
null
,
opUserName
:
null
,
isUsed
:
null
,
sortNo
:
null
,
createTime
:
null
,
createUserCode
:
null
,
updateTime
:
null
,
updateUserCode
:
null
,
inboundOrderItemsList
:
[]
}
if
(
this
.
$refs
.
inboundItemsRef
)
{
this
.
$refs
.
inboundItemsRef
.
resetEmbeddedData
()
}
if
(
this
.
$refs
.
form
)
{
this
.
$refs
.
form
.
resetFields
()
}
},
/** 导入按钮操作 */
handleImport
()
{
this
.
$refs
.
import
.
show
()
},
/** 处理明细项选择变化 */
handleItemsSelectionChange
(
selection
)
{
this
.
selectedItems
=
selection
},
/** 处理明细数据变化 */
handleItemsDataChange
(
items
)
{
this
.
form
.
inboundOrderItemsList
=
items
this
.
calculateTotals
()
},
/** 处理总数变化 */
handleTotalsChange
(
totals
)
{
this
.
form
.
totalPlannedQuantity
=
totals
.
plannedQuantity
this
.
form
.
totalActualQuantity
=
totals
.
actualQuantity
this
.
form
.
totalPackages
=
totals
.
packages
},
/** 添加明细项回调 */
handleItemAdded
(
item
)
{
// 为新项设置orderId
item
.
orderId
=
this
.
form
.
orderId
},
/** 行保存回调 */
handleRowSaved
(
row
)
{
// 可以在这里添加保存后的逻辑
},
/** 行删除回调 */
handleRowDeleted
(
row
)
{
this
.
$message
.
success
(
'删除成功'
)
},
/** 批量删除回调 */
handleBatchDelete
(
ids
)
{
this
.
$message
.
success
(
`成功删除
${
ids
.
length
}
项`
)
},
/** 单元格变化回调 */
handleCellChange
({
row
,
prop
,
value
})
{
// 可以在这里处理特定字段的变化
if
(
prop
===
'plannedQuantity'
||
prop
===
'actualQuantity'
)
{
this
.
calculateTotals
()
}
},
/** 计算总数 */
calculateTotals
()
{
if
(
!
this
.
form
.
inboundOrderItemsList
||
this
.
form
.
inboundOrderItemsList
.
length
===
0
)
{
this
.
form
.
totalPlannedQuantity
=
0
this
.
form
.
totalActualQuantity
=
0
this
.
form
.
totalPackages
=
0
return
}
const
totals
=
this
.
form
.
inboundOrderItemsList
.
reduce
(
(
acc
,
item
)
=>
{
acc
.
plannedQuantity
+=
parseFloat
(
item
.
plannedQuantity
)
||
0
acc
.
actualQuantity
+=
parseFloat
(
item
.
actualQuantity
)
||
0
acc
.
packages
+=
parseFloat
(
item
.
plannedPackages
)
||
0
return
acc
},
{
plannedQuantity
:
0
,
actualQuantity
:
0
,
packages
:
0
}
)
this
.
form
.
totalPlannedQuantity
=
totals
.
plannedQuantity
this
.
form
.
totalActualQuantity
=
totals
.
actualQuantity
this
.
form
.
totalPackages
=
totals
.
packages
},
/** 导出按钮操作 */
handleExport
()
{
this
.
download
(
'inventory/inbound/export'
,
{
...
this
.
queryParams
},
`inbound_
${
new
Date
().
getTime
()}
.xlsx`
)
}
}
}
</
script
>
<
style
scoped
>
/* 对齐字典页面的样式类名和布局 */
.page-container
{
padding
:
16px
;
background
:
#fff
;
border-radius
:
4px
;
margin-bottom
:
16px
;
}
.table-container
{
margin-top
:
16px
;
}
.scrollable-dialog
.el-dialog__body
{
max-height
:
80vh
;
/* 最大高度80%视口高度 */
overflow-y
:
auto
;
/* 超出滚动 */
padding
:
20px
;
}
.detail-container
{
padding
:
10px
;
}
.remark-text
{
line-height
:
1.5
;
min-height
:
40px
;
white-space
:
pre-wrap
;
}
.mb20
{
margin-bottom
:
20px
;
}
/* 统一对话框底部按钮样式 */
.dialog-footer
{
text-align
:
center
;
}
</
style
>
\ No newline at end of file
ruoyi-admin-vue/src/views/inventory/inbound/index.vue
View file @
98bfcd2b
...
...
@@ -615,6 +615,8 @@ export default {
})
this
.
open
=
true
this
.
title
=
"修改入库单"
}).
finally
(()
=>
{
this
.
inboundOrderId
=
null
})
},
/** 查看详情 */
...
...
@@ -627,6 +629,8 @@ export default {
this
.
detailForm
=
response
.
data
this
.
detailForm
.
inboundOrderId
=
id
this
.
detailOpen
=
true
}).
finally
(()
=>
{
this
.
detailForm
.
inboundOrderId
=
null
})
},
// 打开物料选择弹窗
...
...
@@ -767,6 +771,7 @@ export default {
})
}
else
{
addInbound
(
submitData
).
then
(
response
=>
{
console
.
log
(
submitData
)
this
.
$message
.
success
(
"新增成功"
)
this
.
open
=
false
this
.
getList
()
...
...
ruoyi-admin-vue/src/views/inventory/inbound_items/index.vue
View file @
98bfcd2b
...
...
@@ -302,7 +302,7 @@ export default {
},
{
prop
:
'plannedQuantity'
,
label
:
'计划数量'
,
width
:
'100'
,
type
:
'number'
,
editable
:
true
},
{
prop
:
'actualQuantity'
,
label
:
'实际数量'
,
width
:
'100'
,
type
:
'number'
,
editable
:
true
},
{
prop
:
'plannedPackages'
,
label
:
'计划件数'
,
width
:
'100'
,
type
:
'number'
,
editable
:
true
},
//
{ prop: 'plannedPackages', label: '计划件数', width: '100', type: 'number', editable: true },
{
prop
:
'actualPackages'
,
label
:
'实际件数'
,
width
:
'100'
,
type
:
'number'
,
editable
:
true
},
{
prop
:
'divisor'
,
label
:
'约数'
,
width
:
'100'
,
type
:
'number'
,
editable
:
true
},
{
prop
:
'labelColor'
,
label
:
'标签颜色'
,
width
:
'100'
,
type
:
'select'
,
editable
:
true
},
...
...
@@ -320,6 +320,8 @@ export default {
},
data
()
{
return
{
showSearch
:
true
,
loading
:
false
,
selectedRows
:
[],
...
...
@@ -389,7 +391,6 @@ export default {
inboundOrderId
:
{
immediate
:
true
,
handler
(
newVal
)
{
console
.
log
(
'inboundOrderId 变化:'
,
newVal
)
// 核心:过滤 null/空值,只在有效时执行逻辑
if
(
!
newVal
)
return
this
.
loadRelatedData
(
newVal
)
...
...
@@ -412,9 +413,7 @@ export default {
methods
:
{
// 根据字典类型和值,获取对应的listClass(标签样式)
getDictListClass
(
dictType
,
value
)
{
console
.
log
(
value
)
const
dictList
=
this
.
dict
.
type
[
dictType
]
||
[]
console
.
log
(
dictList
)
if
(
!
value
)
return
'info'
const
dictItem
=
dictList
.
find
(
item
=>
item
.
value
===
value
+
""
)
...
...
@@ -445,7 +444,9 @@ export default {
this
.
queryParams
.
inboundOrderId
=
inboundOrderId
listInbound_itemsAndMname
(
this
.
queryParams
).
then
(
response
=>
{
this
.
displayData
=
response
.
rows
.
map
(
item
=>
({
...
item
,
materialName
:
item
.
materialName
,
editable
:
false
,
tempId
:
item
.
id
||
Date
.
now
()
+
Math
.
random
()
}))
...
...
@@ -454,6 +455,8 @@ export default {
this
.
loading
=
false
}).
catch
(()
=>
{
this
.
loading
=
false
}).
finally
(()
=>
{
})
},
...
...
ruoyi-admin/src/main/java/com/ruoyi/web/controller/inventory/InboundOrderItemsController.java
View file @
98bfcd2b
...
...
@@ -5,6 +5,7 @@ import java.util.UUID;
import
javax.servlet.http.HttpServletResponse
;
import
com.ruoyi.inventory.domain.InboundOrderItems
;
import
com.ruoyi.inventory.domain.vo.InboundDetailsVO
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
...
...
@@ -131,4 +132,16 @@ public class InboundOrderItemsController extends BaseController
String
message
=
inboundOrderItemsService
.
importInboundOrderItems
(
inboundOrderItems
,
updateSupport
,
operName
);
return
success
(
message
);
}
/**
* 统计入库单物料明细
*/
@PreAuthorize
(
"@ss.hasPermi('inventory:inbound_items:list')"
)
@GetMapping
(
"/details"
)
public
TableDataInfo
itemDetails
(
InboundDetailsVO
inboundDetailsVO
)
throws
Exception
{
startPage
();
List
<
InboundDetailsVO
>
list
=
inboundOrderItemsService
.
selectInboundDetailsVOBySapNo
();
return
getDataTable
(
list
);
}
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/domain/vo/InboundDetailsVO.java
0 → 100644
View file @
98bfcd2b
package
com
.
ruoyi
.
inventory
.
domain
.
vo
;
import
com.ruoyi.common.annotation.Excel
;
import
java.util.Date
;
public
class
InboundDetailsVO
{
private
static
final
long
serialVersionUID
=
1L
;
@Excel
(
name
=
"物料sapNo"
)
private
String
materialId
;
@Excel
(
name
=
"物料名"
)
private
String
materialName
;
@Excel
(
name
=
"入库单号"
)
private
String
orderId
;
@Excel
(
name
=
"批次ID"
)
private
String
batchId
;
@Excel
(
name
=
"仓库ID"
)
private
String
warehouseId
;
@Excel
(
name
=
"库位ID"
)
private
String
locationId
;
@Excel
(
name
=
"入库数量"
)
private
Long
actualQuantity
;
@Excel
(
name
=
"件数"
)
private
Long
actualPackages
;
@Excel
(
name
=
"标签颜色"
)
private
String
labelColor
;
@Excel
(
name
=
"单价"
)
private
Double
unitPrice
;
@Excel
(
name
=
"入库物料总价"
)
private
Double
totalPrice
;
@Excel
(
name
=
"备注"
)
private
String
remark
;
@Excel
(
name
=
"入库时间"
)
private
Date
inboundDate
;
public
String
getMaterialId
()
{
return
materialId
;
}
public
void
setMaterialId
(
String
materialId
)
{
this
.
materialId
=
materialId
;
}
public
String
getMaterialName
()
{
return
materialName
;
}
public
void
setMaterialName
(
String
materialName
)
{
this
.
materialName
=
materialName
;
}
public
String
getOrderId
()
{
return
orderId
;
}
public
void
setOrderId
(
String
orderId
)
{
this
.
orderId
=
orderId
;
}
public
String
getBatchId
()
{
return
batchId
;
}
public
void
setBatchId
(
String
batchId
)
{
this
.
batchId
=
batchId
;
}
public
String
getWarehouseId
()
{
return
warehouseId
;
}
public
void
setWarehouseId
(
String
warehouseId
)
{
this
.
warehouseId
=
warehouseId
;
}
public
String
getLocationId
()
{
return
locationId
;
}
public
void
setLocationId
(
String
locationId
)
{
this
.
locationId
=
locationId
;
}
public
Long
getActualQuantity
()
{
return
actualQuantity
;
}
public
void
setActualQuantity
(
Long
actualQuantity
)
{
this
.
actualQuantity
=
actualQuantity
;
}
public
Long
getActualPackages
()
{
return
actualPackages
;
}
public
void
setActualPackages
(
Long
actualPackages
)
{
this
.
actualPackages
=
actualPackages
;
}
public
String
getLabelColor
()
{
return
labelColor
;
}
public
void
setLabelColor
(
String
labelColor
)
{
this
.
labelColor
=
labelColor
;
}
public
Double
getUnitPrice
()
{
return
unitPrice
;
}
public
void
setUnitPrice
(
Double
unitPrice
)
{
this
.
unitPrice
=
unitPrice
;
}
public
String
getRemark
()
{
return
remark
;
}
public
void
setRemark
(
String
remark
)
{
this
.
remark
=
remark
;
}
public
Double
getTotalPrice
()
{
return
totalPrice
;
}
public
void
setTotalPrice
(
Double
totalPrice
)
{
this
.
totalPrice
=
totalPrice
;
}
public
Date
getInboundDate
()
{
return
inboundDate
;
}
public
void
setInboundDate
(
Date
inboundDate
)
{
this
.
inboundDate
=
inboundDate
;
}
@Override
public
String
toString
()
{
return
"InboundDetailsVO{"
+
"sapNo='"
+
materialId
+
'\''
+
", materialName='"
+
materialName
+
'\''
+
", orderId='"
+
orderId
+
'\''
+
", batchId='"
+
batchId
+
'\''
+
", warehouseId='"
+
warehouseId
+
'\''
+
", locationId='"
+
locationId
+
'\''
+
", actualQuantity="
+
actualQuantity
+
", actualPackages="
+
actualPackages
+
", labelColor='"
+
labelColor
+
'\''
+
", unitPrice="
+
unitPrice
+
", totalPrice="
+
totalPrice
+
", remark='"
+
remark
+
'\''
+
", inboundDate="
+
inboundDate
+
'}'
;
}
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/mapper/InboundOrderItemsMapper.java
View file @
98bfcd2b
...
...
@@ -2,6 +2,7 @@ package com.ruoyi.inventory.mapper;
import
java.util.List
;
import
com.ruoyi.inventory.domain.InboundOrderItems
;
import
com.ruoyi.inventory.domain.vo.InboundDetailsVO
;
/**
* 入库单明细Mapper接口
...
...
@@ -66,4 +67,10 @@ public interface InboundOrderItemsMapper
* @return 结果
*/
public
int
deleteInboundOrderItemsByIds
(
String
[]
ids
);
/**
* 统计入库单明细
* @return 结果
*/
public
List
<
InboundDetailsVO
>
selectInboundDetailsVOBySapNo
();
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/IInboundOrderItemsService.java
View file @
98bfcd2b
...
...
@@ -4,6 +4,7 @@ import java.util.List;
import
com.ruoyi.common.core.domain.entity.Materials
;
import
com.ruoyi.inventory.domain.InboundOrderItems
;
import
com.ruoyi.inventory.domain.vo.InboundDetailsVO
;
/**
* 入库单明细Service接口
...
...
@@ -68,4 +69,10 @@ public interface IInboundOrderItemsService
* @return 结果
*/
public
String
importInboundOrderItems
(
List
<
InboundOrderItems
>
inboundOrderItems
,
Boolean
isUpdateSupport
,
String
operName
);
/**
* 统计入库单明细
* @return 结果
*/
public
List
<
InboundDetailsVO
>
selectInboundDetailsVOBySapNo
();
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/InboundOrderItemsServiceImpl.java
View file @
98bfcd2b
...
...
@@ -10,6 +10,7 @@ import com.ruoyi.common.exception.ServiceException;
import
com.ruoyi.common.utils.DateUtils
;
import
com.ruoyi.common.utils.SecurityUtils
;
import
com.ruoyi.common.utils.StringUtils
;
import
com.ruoyi.inventory.domain.vo.InboundDetailsVO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
com.ruoyi.inventory.mapper.InboundOrderItemsMapper
;
...
...
@@ -173,4 +174,9 @@ public class InboundOrderItemsServiceImpl implements IInboundOrderItemsService
}
return
successMsg
.
toString
();
}
@Override
public
List
<
InboundDetailsVO
>
selectInboundDetailsVOBySapNo
()
{
return
inboundOrderItemsMapper
.
selectInboundDetailsVOBySapNo
();
}
}
ruoyi-inventory/src/main/java/com/ruoyi/inventory/service/impl/InboundOrdersServiceImpl.java
View file @
98bfcd2b
...
...
@@ -240,6 +240,7 @@ public class InboundOrdersServiceImpl implements IInboundOrdersService
itemDO
.
setId
(
UUID
.
randomUUID
().
toString
());
itemDO
.
setMaterialId
(
vo
.
getSapNo
());
itemDO
.
setOrderId
(
orderId
);
// 关联入库单号
itemDO
.
setBatchId
(
mainDO
.
getBatchId
());
itemDO
.
setInboundOrderId
(
mainDO
.
getId
());
// 关联主表ID(核心!)
itemDO
.
setCreateBy
(
operId
);
itemDO
.
setCreateTime
(
now
);
...
...
ruoyi-inventory/src/main/resources/mapper/inventory/InboundOrderItemsMapper.xml
View file @
98bfcd2b
...
...
@@ -301,4 +301,64 @@
<result
property=
"inboundOrderId"
column=
"inbound_order_id"
/>
<result
property=
"materialName"
column=
"material_name"
/>
</resultMap>
<resultMap
id=
"InboundDetailsResultMap"
type=
"com.ruoyi.inventory.domain.vo.InboundDetailsVO"
>
<!-- 基础字段映射 -->
<result
column=
"material_id"
property=
"materialId"
jdbcType=
"VARCHAR"
/>
<result
column=
"material_name"
property=
"materialName"
jdbcType=
"VARCHAR"
/>
<result
column=
"order_id"
property=
"orderId"
jdbcType=
"VARCHAR"
/>
<result
column=
"batch_id"
property=
"batchId"
jdbcType=
"VARCHAR"
/>
<result
column=
"warehouse_id"
property=
"warehouseId"
jdbcType=
"VARCHAR"
/>
<result
column=
"location_id"
property=
"locationId"
jdbcType=
"VARCHAR"
/>
<!-- 数值型字段 -->
<result
column=
"actual_quantity"
property=
"actualQuantity"
jdbcType=
"BIGINT"
/>
<result
column=
"actual_packages"
property=
"actualPackages"
jdbcType=
"BIGINT"
/>
<!-- 字符串/枚举类字段 -->
<result
column=
"label_color"
property=
"labelColor"
jdbcType=
"VARCHAR"
/>
<!-- 金额字段 -->
<result
column=
"unit_price"
property=
"unitPrice"
jdbcType=
"DOUBLE"
/>
<result
column=
"total_price"
property=
"totalPrice"
jdbcType=
"DOUBLE"
/>
<!-- 备注字段 -->
<result
column=
"remark"
property=
"remark"
jdbcType=
"VARCHAR"
/>
<!-- 日期字段(指定日期格式化) -->
<result
column=
"inbound_date"
property=
"inboundDate"
/>
</resultMap>
<select
id=
"selectInboundDetailsVOBySapNo"
resultMap=
"InboundDetailsResultMap"
>
SELECT
ioi.material_id,
ms.material_name,
ioi.order_id,
ioi.batch_id,
ioi.warehouse_id,
ioi.location_id,
SUM(ioi.actual_quantity) AS actual_quantity,
SUM(ioi.actual_packages) AS actual_packages,
ioi.label_color,
ioi.unit_price,
SUM(ioi.unit_price * ioi.actual_quantity) AS total_price,
ioi.remark,
io.inbound_date
FROM inbound_orders io
INNER JOIN inbound_order_items ioi ON io.id = ioi.inbound_order_id
INNER JOIN materials ms ON ms.sap_no = ioi.material_id
WHERE io.order_status = 2
GROUP BY
ioi.material_id,
ioi.batch_id,
ioi.warehouse_id,
ioi.location_id,
ms.material_name,
ioi.order_id,
ioi.label_color,
ioi.unit_price,
ioi.remark,
io.inbound_date
order by ioi.order_id asc,ioi.material_id asc
</select>
</mapper>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论