Commit 98bfcd2b by yubin

Merge remote-tracking branch 'origin/master'

parents feeecb39 c30de553
...@@ -49,3 +49,11 @@ export function delInbound_items(id) { ...@@ -49,3 +49,11 @@ export function delInbound_items(id) {
method: 'delete' method: 'delete'
}) })
} }
// 统计入库单明细
export function inbound_details(){
return request({
url: '/inventory/inbound_items/details',
method: 'get'
})
}
<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
...@@ -615,6 +615,8 @@ export default { ...@@ -615,6 +615,8 @@ export default {
}) })
this.open = true this.open = true
this.title = "修改入库单" this.title = "修改入库单"
}).finally(() => {
this.inboundOrderId = null
}) })
}, },
/** 查看详情 */ /** 查看详情 */
...@@ -627,6 +629,8 @@ export default { ...@@ -627,6 +629,8 @@ export default {
this.detailForm = response.data this.detailForm = response.data
this.detailForm.inboundOrderId = id this.detailForm.inboundOrderId = id
this.detailOpen = true this.detailOpen = true
}).finally(() => {
this.detailForm.inboundOrderId = null
}) })
}, },
// 打开物料选择弹窗 // 打开物料选择弹窗
...@@ -767,6 +771,7 @@ export default { ...@@ -767,6 +771,7 @@ export default {
}) })
} else { } else {
addInbound(submitData).then(response => { addInbound(submitData).then(response => {
console.log(submitData)
this.$message.success("新增成功") this.$message.success("新增成功")
this.open = false this.open = false
this.getList() this.getList()
......
...@@ -302,7 +302,7 @@ export default { ...@@ -302,7 +302,7 @@ export default {
}, },
{ prop: 'plannedQuantity', label: '计划数量', width: '100', type: 'number', editable: true }, { prop: 'plannedQuantity', label: '计划数量', width: '100', type: 'number', editable: true },
{ prop: 'actualQuantity', 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: 'actualPackages', label: '实际件数', width: '100', type: 'number', editable: true },
{ prop: 'divisor', 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 }, { prop: 'labelColor', label: '标签颜色', width: '100', type: 'select', editable: true },
...@@ -320,6 +320,8 @@ export default { ...@@ -320,6 +320,8 @@ export default {
}, },
data() { data() {
return { return {
showSearch: true, showSearch: true,
loading: false, loading: false,
selectedRows: [], selectedRows: [],
...@@ -389,7 +391,6 @@ export default { ...@@ -389,7 +391,6 @@ export default {
inboundOrderId: { inboundOrderId: {
immediate: true, immediate: true,
handler(newVal) { handler(newVal) {
console.log('inboundOrderId 变化:', newVal)
// 核心:过滤 null/空值,只在有效时执行逻辑 // 核心:过滤 null/空值,只在有效时执行逻辑
if (!newVal) return if (!newVal) return
this.loadRelatedData(newVal) this.loadRelatedData(newVal)
...@@ -412,9 +413,7 @@ export default { ...@@ -412,9 +413,7 @@ export default {
methods: { methods: {
// 根据字典类型和值,获取对应的listClass(标签样式) // 根据字典类型和值,获取对应的listClass(标签样式)
getDictListClass(dictType, value) { getDictListClass(dictType, value) {
console.log(value)
const dictList = this.dict.type[dictType] || [] const dictList = this.dict.type[dictType] || []
console.log(dictList)
if (!value) return 'info' if (!value) return 'info'
const dictItem = dictList.find(item => item.value === value+"") const dictItem = dictList.find(item => item.value === value+"")
...@@ -445,7 +444,9 @@ export default { ...@@ -445,7 +444,9 @@ export default {
this.queryParams.inboundOrderId = inboundOrderId this.queryParams.inboundOrderId = inboundOrderId
listInbound_itemsAndMname(this.queryParams).then(response => { listInbound_itemsAndMname(this.queryParams).then(response => {
this.displayData = response.rows.map(item => ({ this.displayData = response.rows.map(item => ({
...item, ...item,
materialName: item.materialName,
editable: false, editable: false,
tempId: item.id || Date.now() + Math.random() tempId: item.id || Date.now() + Math.random()
})) }))
...@@ -454,6 +455,8 @@ export default { ...@@ -454,6 +455,8 @@ export default {
this.loading = false this.loading = false
}).catch(() => { }).catch(() => {
this.loading = false this.loading = false
}).finally(() => {
}) })
}, },
......
...@@ -5,6 +5,7 @@ import java.util.UUID; ...@@ -5,6 +5,7 @@ import java.util.UUID;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.ruoyi.inventory.domain.InboundOrderItems; import com.ruoyi.inventory.domain.InboundOrderItems;
import com.ruoyi.inventory.domain.vo.InboundDetailsVO;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
...@@ -131,4 +132,16 @@ public class InboundOrderItemsController extends BaseController ...@@ -131,4 +132,16 @@ public class InboundOrderItemsController extends BaseController
String message = inboundOrderItemsService.importInboundOrderItems(inboundOrderItems, updateSupport, operName); String message = inboundOrderItemsService.importInboundOrderItems(inboundOrderItems, updateSupport, operName);
return success(message); 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);
}
} }
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 +
'}';
}
}
...@@ -2,6 +2,7 @@ package com.ruoyi.inventory.mapper; ...@@ -2,6 +2,7 @@ package com.ruoyi.inventory.mapper;
import java.util.List; import java.util.List;
import com.ruoyi.inventory.domain.InboundOrderItems; import com.ruoyi.inventory.domain.InboundOrderItems;
import com.ruoyi.inventory.domain.vo.InboundDetailsVO;
/** /**
* 入库单明细Mapper接口 * 入库单明细Mapper接口
...@@ -66,4 +67,10 @@ public interface InboundOrderItemsMapper ...@@ -66,4 +67,10 @@ public interface InboundOrderItemsMapper
* @return 结果 * @return 结果
*/ */
public int deleteInboundOrderItemsByIds(String[] ids); public int deleteInboundOrderItemsByIds(String[] ids);
/**
* 统计入库单明细
* @return 结果
*/
public List<InboundDetailsVO> selectInboundDetailsVOBySapNo();
} }
...@@ -4,6 +4,7 @@ import java.util.List; ...@@ -4,6 +4,7 @@ import java.util.List;
import com.ruoyi.common.core.domain.entity.Materials; import com.ruoyi.common.core.domain.entity.Materials;
import com.ruoyi.inventory.domain.InboundOrderItems; import com.ruoyi.inventory.domain.InboundOrderItems;
import com.ruoyi.inventory.domain.vo.InboundDetailsVO;
/** /**
* 入库单明细Service接口 * 入库单明细Service接口
...@@ -68,4 +69,10 @@ public interface IInboundOrderItemsService ...@@ -68,4 +69,10 @@ public interface IInboundOrderItemsService
* @return 结果 * @return 结果
*/ */
public String importInboundOrderItems(List<InboundOrderItems> inboundOrderItems, Boolean isUpdateSupport, String operName); public String importInboundOrderItems(List<InboundOrderItems> inboundOrderItems, Boolean isUpdateSupport, String operName);
/**
* 统计入库单明细
* @return 结果
*/
public List<InboundDetailsVO> selectInboundDetailsVOBySapNo();
} }
...@@ -10,6 +10,7 @@ import com.ruoyi.common.exception.ServiceException; ...@@ -10,6 +10,7 @@ import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.inventory.domain.vo.InboundDetailsVO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.inventory.mapper.InboundOrderItemsMapper; import com.ruoyi.inventory.mapper.InboundOrderItemsMapper;
...@@ -173,4 +174,9 @@ public class InboundOrderItemsServiceImpl implements IInboundOrderItemsService ...@@ -173,4 +174,9 @@ public class InboundOrderItemsServiceImpl implements IInboundOrderItemsService
} }
return successMsg.toString(); return successMsg.toString();
} }
@Override
public List<InboundDetailsVO> selectInboundDetailsVOBySapNo() {
return inboundOrderItemsMapper.selectInboundDetailsVOBySapNo();
}
} }
...@@ -240,6 +240,7 @@ public class InboundOrdersServiceImpl implements IInboundOrdersService ...@@ -240,6 +240,7 @@ public class InboundOrdersServiceImpl implements IInboundOrdersService
itemDO.setId(UUID.randomUUID().toString()); itemDO.setId(UUID.randomUUID().toString());
itemDO.setMaterialId(vo.getSapNo()); itemDO.setMaterialId(vo.getSapNo());
itemDO.setOrderId(orderId); // 关联入库单号 itemDO.setOrderId(orderId); // 关联入库单号
itemDO.setBatchId(mainDO.getBatchId());
itemDO.setInboundOrderId(mainDO.getId()); // 关联主表ID(核心!) itemDO.setInboundOrderId(mainDO.getId()); // 关联主表ID(核心!)
itemDO.setCreateBy(operId); itemDO.setCreateBy(operId);
itemDO.setCreateTime(now); itemDO.setCreateTime(now);
......
...@@ -301,4 +301,64 @@ ...@@ -301,4 +301,64 @@
<result property="inboundOrderId" column="inbound_order_id" /> <result property="inboundOrderId" column="inbound_order_id" />
<result property="materialName" column="material_name" /> <result property="materialName" column="material_name" />
</resultMap> </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> </mapper>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论