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
c30de553
Commit
c30de553
authored
Dec 09, 2025
by
zhangtw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
入库物料明细统计
入库明细显示物料名bug
parent
36733eb3
显示空白字符变更
内嵌
并排
正在显示
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 @
c30de553
...
...
@@ -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 @
c30de553
<
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 @
c30de553
...
...
@@ -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 @
c30de553
...
...
@@ -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 @
c30de553
...
...
@@ -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 @
c30de553
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 @
c30de553
...
...
@@ -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 @
c30de553
...
...
@@ -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 @
c30de553
...
...
@@ -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 @
c30de553
...
...
@@ -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 @
c30de553
...
...
@@ -299,4 +299,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
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论