Commit 1f9d9564 by yubin

组件双击 去选框 弹窗修改高度 物料根据库存排序反显 列表id修改

parent b0192161
......@@ -8,7 +8,13 @@ export function listItems(query) {
params: query
})
}
export function listLog(query) {
return request({
url: '/inventory/items/listLog',
method: 'get',
params: query
})
}
export function getStatistics(query) {
return request({
url: '/inventory/items/getStatistics',
......
......@@ -49,3 +49,10 @@ export function getMaterialsdicts() {
method: 'get'
})
}
export function ListMaterialsInventory(query){
return request({
url: '/inventory/materials/ListMaterialsInventory',
method: 'post',
params: query
})
}
<template>
<div class="material-selector-container" style="overflow: hidden;">
<div class="material-selector-container">
<splitpanes class="default-theme">
<!-- 左侧分类树 -->
<pane size="16" style="overflow: auto;">
<pane size="16" class="tree-pane">
<TreeComponent
ref="treeComponent"
:tree-data="categoryTreeData"
......@@ -22,9 +22,8 @@
</pane>
<!-- 右侧物料列表 -->
<pane size="84" style="overflow: auto;">
<div style="padding: 10px; display: flex; flex-direction: column;">
<!-- 查询表单(恢复所有查询项,保留ID核心逻辑) -->
<pane size="84" class="table-pane">
<div class="table-header">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="88px">
<el-form-item label="SAP物料号" prop="sapNo">
<el-input
......@@ -55,9 +54,10 @@
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<div class="table-container" style="flex: 1; min-height: 400px; max-height: 600px; overflow: auto; margin: 10px 0;">
<!-- 物料表格(恢复所有字段显示) -->
</div>
<!-- 表格容器:唯一滚动区域 -->
<div class="table-container">
<el-table
ref="materialTable"
v-loading="loading"
......@@ -95,10 +95,20 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="原始库存" align="center" prop="originalStock" />
<el-table-column label="新增数量" align="center" prop="addedQuantity" />
<el-table-column label="可用库存" align="center" prop="availableStock">
<template slot-scope="scope">
<span :style="{color: scope.row.availableStock <= 0 ? 'red' : 'inherit'}">
{{ scope.row.availableStock }}
</span>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
</div>
<!-- 分页:固定在底部 -->
<div class="pagination-container">
<pagination
v-show="total>0"
:total="total"
......@@ -113,8 +123,9 @@
</template>
<script>
import { listMaterials } from "@/api/inventory/materials"
import { ListMaterialsInventory } from "@/api/inventory/materials"
import { listMaterials_category } from "@/api/inventory/materials_category"
import { listLog } from "@/api/inventory/items"
import TreeComponent from '@/views/inventory/materials_category/treeComponent.vue'
import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
......@@ -135,9 +146,17 @@ export default {
type: Array,
default: () => []
},
selectedMaterialIds: { // 核心:基于ID的选中项
selectedMaterialIds: {
type: Array,
default: () => []
},
detailList: {
type: Array,
default: () => []
},
ordersId: {
type: [String, Number],
default: ''
}
},
data() {
......@@ -146,11 +165,11 @@ export default {
treeProps: { children: 'children', label: 'label', value: 'sid' },
nodeKey: 'sid',
loadingTree: false,
categoryMap: {}, // 恢复分类名称映射(显示用)
categoryNameToCodeMap: {}, // 恢复分类名称转编码(查询用)
categoryCodeToSidMap: {}, // 恢复分类编码转SID(树选择用)
categoryMap: {},
categoryNameToCodeMap: {},
categoryCodeToSidMap: {},
currentNodeId: null,
queryParams: { // 恢复所有查询参数(显示+查询用)
queryParams: {
pageNum: 1,
pageSize: 10,
sapNo: null,
......@@ -166,7 +185,10 @@ export default {
selectedRows: [],
singleSelectedId: null,
isSelecting: false,
isRetrySync: false
isRetrySync: false,
inventoryCache: {},
// 新增:存储listLog返回的订单明细数据
orderLogData: []
}
},
watch: {
......@@ -218,29 +240,93 @@ export default {
})
}
}
},
detailList: {
immediate: true,
deep: true,
handler() {
if (this.materialsList.length > 0) {
this.calculateMaterialStock()
}
}
},
// 监听订单ID变化,重新获取日志数据并计算库存
ordersId: {
immediate: true,
handler(val) {
console.log('MaterialSelector 接收的 ordersId 更新:', val);
if (val) {
this.getOrderLogData(val)
}
}
}
},
async created() {
// 恢复分类列表和树数据加载(显示分类名称用)
await Promise.all([this.getCategoryList(), this.getCategoryTreeData()])
// 如果有订单ID,先获取日志数据
if (this.ordersId) {
await this.getOrderLogData(this.ordersId)
}
this.getList()
console.log('父组件接收的 ordersId:', this.ordersId);
},
methods: {
// 新增:双击行事件处理
// 新增:获取订单日志数据(listLog接口)
async getOrderLogData(orderId) {
try {
const res = await listLog({ orderId })
if (res.code === 200 && res.rows) {
this.orderLogData = res.rows
console.log('获取订单日志数据成功:', this.orderLogData)
// 获取数据后重新计算库存
if (this.materialsList.length > 0) {
this.calculateMaterialStock()
}
}
} catch (error) {
console.error('获取订单日志数据失败:', error)
}
},
// 重写:库存计算逻辑(可用库存 = 原始库存 + actualQuantity)
calculateMaterialStock() {
console.log("开始计算库存 - 订单日志数据:", this.orderLogData)
if (!this.orderLogData.length) return
// 按materialId汇总actualQuantity
const materialQtyMap = {}
this.orderLogData.forEach(item => {
const materialId = item.materialId
const actualQty = Number(item.actualQuantity) || 0
if (!materialQtyMap[materialId]) {
materialQtyMap[materialId] = 0
}
materialQtyMap[materialId] += actualQty
})
// 更新物料列表的库存数据
this.materialsList.forEach(material => {
const addedQty = materialQtyMap[material.id] || 0
// 新增数量
this.$set(material, 'addedQuantity', addedQty)
// 可用库存 = 原始库存 + 新增数量
this.$set(material, 'availableStock', (material.originalStock || 0) + addedQty)
})
},
// 双击行事件处理
handleRowDblClick(row) {
if (this.isSelecting || !this.$refs.materialTable) return
this.isSelecting = true
try {
// 单选模式下双击直接选择并关闭组件
if (!this.multiple) {
// 选中当前行
this.$refs.materialTable.clearSelection()
this.$refs.materialTable.toggleRowSelection(row, true)
this.singleSelectedId = row.id
this.selectedRows = [row]
// 构造返回数据
const selectedData = {
id: row.id,
sapNo: row.sapNo,
......@@ -250,10 +336,12 @@ export default {
categoryName: this.categoryMap[row.categoryCode] || row.categoryCode,
specification: row.specification,
materialUnit: row.materialUnit,
isBatchManaged: row.isBatchManaged
isBatchManaged: row.isBatchManaged,
originalStock: row.originalStock,
addedQuantity: row.addedQuantity,
availableStock: row.availableStock
}
// 触发事件
this.$emit('input', row.id)
this.$emit('change', selectedData)
this.$emit('selection-change', {
......@@ -263,11 +351,9 @@ export default {
categoryIds: [row.categoryCode || '']
})
// 触发关闭事件(需要父组件监听此事件并关闭弹窗)
this.$emit('confirm', selectedData)
this.$emit('close')
} else {
// 多选模式下双击仅切换选择状态
this.$refs.materialTable.toggleRowSelection(row)
}
} finally {
......@@ -275,7 +361,7 @@ export default {
}
},
// 恢复分类列表加载(分类名称映射)
// 获取分类列表
async getCategoryList() {
try {
const response = await listMaterials_category({ pageNum: 1, pageSize: 1000 })
......@@ -402,15 +488,29 @@ export default {
this.getList()
},
// 改造:获取物料列表并初始化库存字段
getList() {
this.loading = true
listMaterials(this.queryParams).then(response => {
// 恢复所有字段映射(显示用)
this.materialsList = (response.rows || []).filter(item => item.isUsed !== 0 && item.isUsed !== '0').map(item => ({
ListMaterialsInventory(this.queryParams).then(response => {
const materialRows = (response.rows || []).filter(item => item.isUsed !== 0 && item.isUsed !== '0').map(item => ({
...item,
displayCategory: this.categoryMap[item.categoryCode] || '未匹配分类'
displayCategory: this.categoryMap[item.categoryCode] || '未匹配分类',
originalStock: item.stock || 0, // 原始库存
addedQuantity: 0, // 初始化新增数量(actualQuantity)
availableStock: item.stock || 0 // 初始化可用库存
}))
this.materialsList = materialRows
this.total = response.total || 0
// 缓存库存数据
materialRows.forEach(item => {
this.inventoryCache[item.id] = item.stock || 0
})
// 计算库存(可用库存 = 原始库存 + actualQuantity)
this.calculateMaterialStock()
this.$nextTick(() => {
setTimeout(() => this.handleValueSync(), 400)
})
......@@ -424,7 +524,6 @@ export default {
},
handleQuery() {
// 恢复分类名称查询逻辑
const inputName = this.queryParams.categoryNameInput
if (inputName) {
const matchedCode = this.categoryNameToCodeMap[inputName]
......@@ -444,7 +543,6 @@ export default {
},
resetQuery() {
// 恢复所有查询参数重置
this.queryParams = {
pageNum: 1,
pageSize: 10,
......@@ -463,7 +561,7 @@ export default {
this.getList()
},
// 核心:基于 ID 的选择事件(保留所有字段返回)
// 改造:选择事件返回新增的库存数据
handleSelectionChange(selection) {
if (this.isSelecting || !this.$refs.materialTable) return
......@@ -474,8 +572,8 @@ export default {
const lastRow = selection.pop()
this.$refs.materialTable.clearSelection()
this.$refs.materialTable.toggleRowSelection(lastRow, true)
this.selectedRows = [lastRow]
this.singleSelectedId = lastRow.id
this.selectedRows = [lastRow]
} else {
this.selectedRows = selection
this.singleSelectedId = selection.length > 0 ? selection[0].id : null
......@@ -484,7 +582,6 @@ export default {
this.selectedRows = selection
}
// 返回数据保留所有字段,但核心标识为id
const selectedIds = this.selectedRows.map(row => row.id)
const selectedData = this.selectedRows.map(item => ({
id: item.id,
......@@ -495,18 +592,21 @@ export default {
categoryName: this.categoryMap[item.categoryCode] || item.categoryCode,
specification: item.specification,
materialUnit: item.materialUnit,
isBatchManaged: item.isBatchManaged
isBatchManaged: item.isBatchManaged,
originalStock: item.originalStock,
addedQuantity: item.addedQuantity,
availableStock: item.availableStock
}))
this.$emit('selection-change', {
materialIds: selectedIds, // 核心:返回ID数组
materials: selectedData, // 保留所有字段数据
materialIds: selectedIds,
materials: selectedData,
names: selectedData.map(item => item.materialName),
categoryIds: selectedData.map(item => item.categoryCode)
})
if (this.multiple) {
this.$emit('input', selectedIds) // v-model绑定ID
this.$emit('input', selectedIds)
this.$emit('change', selectedData)
} else {
const singleId = selectedIds.length > 0 ? selectedIds[0] : ''
......@@ -519,7 +619,6 @@ export default {
}
},
// 单选模式下的选择事件(纯 ID 逻辑,保留字段返回)
handleTableSelect(selection, row) {
if (this.isSelecting || this.multiple) return
......@@ -531,7 +630,6 @@ export default {
this.$refs.materialTable.toggleRowSelection(row, true)
this.singleSelectedId = row.id
this.selectedRows = [row]
// 返回完整字段数据
const selectedData = {
id: row.id,
sapNo: row.sapNo,
......@@ -541,7 +639,10 @@ export default {
categoryName: this.categoryMap[row.categoryCode] || row.categoryCode,
specification: row.specification,
materialUnit: row.materialUnit,
isBatchManaged: row.isBatchManaged
isBatchManaged: row.isBatchManaged,
originalStock: row.originalStock,
addedQuantity: row.addedQuantity,
availableStock: row.availableStock
}
this.$emit('input', row.id)
this.$emit('change', selectedData)
......@@ -568,7 +669,6 @@ export default {
}
},
// 行点击事件(纯 ID 逻辑,保留字段返回)
handleRowClick(row) {
if (this.isSelecting || !this.$refs.materialTable) return
......@@ -582,7 +682,6 @@ export default {
this.$refs.materialTable.toggleRowSelection(row, true)
this.singleSelectedId = row.id
this.selectedRows = [row]
// 返回完整字段数据
const selectedData = {
id: row.id,
sapNo: row.sapNo,
......@@ -592,7 +691,10 @@ export default {
categoryName: this.categoryMap[row.categoryCode] || row.categoryCode,
specification: row.specification,
materialUnit: row.materialUnit,
isBatchManaged: row.isBatchManaged
isBatchManaged: row.isBatchManaged,
originalStock: row.originalStock,
addedQuantity: row.addedQuantity,
availableStock: row.availableStock
}
this.$emit('input', row.id)
this.$emit('change', selectedData)
......@@ -622,7 +724,6 @@ export default {
}
},
// 清空选择(纯 ID 逻辑)
clearSelection() {
if (this.isSelecting || !this.$refs.materialTable) return
......@@ -644,13 +745,11 @@ export default {
}
},
// 核心:基于 ID 的反显逻辑(保留所有字段显示)
handleValueSync(isRetry = false) {
if (this.loading || this.isSelecting || !this.$refs.materialTable) return
if (isRetry) this.isRetrySync = true
// 优先使用 selectedMaterialIds,其次是 value
const val = this.selectedMaterialIds.length ? this.selectedMaterialIds : this.value
if (!val || (Array.isArray(val) && !val.length)) {
this.clearSelection()
......@@ -658,7 +757,6 @@ export default {
return
}
// 统一处理 ID 格式(兼容字符串/数字)
const targetIds = this.multiple
? Array.isArray(val) ? val.map(id => String(id)) : [String(val)]
: [String(Array.isArray(val) ? val[0] : val)]
......@@ -675,7 +773,6 @@ export default {
this.$refs.materialTable.clearSelection()
let matchedCount = 0
// 基于 ID 精准匹配反显(保留所有字段)
this.materialsList.forEach(row => {
const rowId = String(row.id)
if (validTargetIds.includes(rowId)) {
......@@ -684,13 +781,11 @@ export default {
}
})
// 更新选中行
this.selectedRows = this.materialsList.filter(row =>
validTargetIds.includes(String(row.id))
)
this.singleSelectedId = this.multiple ? null : (this.selectedRows[0]?.id || null)
// 未匹配到的处理
if (matchedCount === 0 && !isRetry) {
this.$emit('selection-change', {
materialIds: [],
......@@ -715,7 +810,6 @@ export default {
}
},
// 外部设置选中 ID 的方法
setSelectedIds(ids) {
if (this.isSelecting) return
......@@ -735,7 +829,6 @@ export default {
}
},
// 获取选中物料(返回完整字段,核心为ID)
getSelectedMaterials() {
if (this.multiple) {
return this.selectedRows.map(row => ({
......@@ -747,7 +840,10 @@ export default {
categoryName: this.categoryMap[row.categoryCode] || row.categoryCode,
specification: row.specification,
materialUnit: row.materialUnit,
isBatchManaged: row.isBatchManaged
isBatchManaged: row.isBatchManaged,
originalStock: row.originalStock,
addedQuantity: row.addedQuantity,
availableStock: row.availableStock
}))
} else {
return this.selectedRows[0] ? {
......@@ -759,12 +855,14 @@ export default {
categoryName: this.categoryMap[this.selectedRows[0].categoryCode] || this.selectedRows[0].categoryCode,
specification: this.selectedRows[0].specification,
materialUnit: this.selectedRows[0].materialUnit,
isBatchManaged: this.selectedRows[0].isBatchManaged
isBatchManaged: this.selectedRows[0].isBatchManaged,
originalStock: this.selectedRows[0].originalStock,
addedQuantity: this.selectedRows[0].addedQuantity,
availableStock: this.selectedRows[0].availableStock
} : null
}
},
// 单选模式下设置选中 ID
setSingleSelection(id) {
if (this.isSelecting || this.multiple) return
......@@ -777,7 +875,6 @@ export default {
if (targetRow) {
this.$refs.materialTable.toggleRowSelection(targetRow, true)
this.selectedRows = [targetRow]
// 返回完整字段数据
const selectedData = {
id: targetRow.id,
sapNo: targetRow.sapNo,
......@@ -787,7 +884,10 @@ export default {
categoryName: this.categoryMap[targetRow.categoryCode] || targetRow.categoryCode,
specification: targetRow.specification,
materialUnit: targetRow.materialUnit,
isBatchManaged: targetRow.isBatchManaged
isBatchManaged: targetRow.isBatchManaged,
originalStock: targetRow.originalStock,
addedQuantity: targetRow.addedQuantity,
availableStock: targetRow.availableStock
}
this.$emit('input', id)
this.$emit('change', selectedData)
......@@ -820,22 +920,64 @@ export default {
.material-selector-container {
height: 100%;
min-height: 500px;
overflow: hidden !important;
}
.custom-tree-node {
font-size: 14px;
}
.tree-pane {
overflow: hidden !important;
max-height: 100%;
scrollbar-width: none;
-ms-overflow-style: none;
}
.tree-pane::-webkit-scrollbar {
display: none;
}
.table-pane {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden !important;
}
.table-header {
flex-shrink: 0;
padding: 10px;
}
.table-container {
flex: 1;
padding: 0 10px;
overflow: auto !important;
scrollbar-width: thin;
scrollbar-color: #ccc #f5f5f5;
}
.table-container::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.table-container::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 3px;
}
.table-container::-webkit-scrollbar-track {
background-color: #f5f5f5;
}
.pagination-container {
flex-shrink: 0;
padding: 10px;
text-align: right;
}
/deep/ .el-table .el-table__header .cell {
text-align: center;
}
/deep/ .el-table--enable-row-hover .el-table__body tr:hover>td {
background-color: #f5f7fa;
cursor: pointer; /* 新增:鼠标悬停显示指针 */
background-color: #f5f5f5;
cursor: pointer;
}
/deep/ .el-table__fixed-right,
/deep/ .el-table__fixed-left {
pointer-events: auto !important;
}
/* 单选模式下表格行样式优化 */
/deep/ .el-table__body tr.el-table__row--striped td {
background-color: #fafafa;
}
......
......@@ -71,6 +71,7 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- 注释掉仓库查询相关 -->
<!-- <el-form-item label="仓库" prop="warehouseId">
<el-input
v-model="queryWarehouseName"
......@@ -221,15 +222,17 @@
</el-col>
</el-row>
<el-row :gutter="20" style="margin: 10px 0;">
<el-col :span="24">
<!-- 注释掉物料分类相关 -->
<!-- <el-col :span="24">
<div><strong>允许存放物料名称:</strong>{{ scope.row.allowedCategoryNames || '-' }}</div>
</el-col>
</el-col> -->
</el-row>
</template>
</el-table-column>
<el-table-column type="selection" width="55" align="center" fixed />
<el-table-column label="库位编码" align="center" prop="locationCode" width="120" fixed />
<el-table-column label="库位名称" align="center" prop="locationName" width="150" />
<!-- 注释掉仓库列 -->
<!-- <el-table-column label="仓库" align="center" prop="warehousesName" width="180">
<template slot-scope="scope">
{{ scope.row.warehousesName }}
......@@ -263,7 +266,8 @@
<el-table-column label="库位容量(千克)" align="center" prop="capacity" width="120" />
<el-table-column label="体积容量(立方米)" align="center" prop="volumeCapacity" width="120" />
<el-table-column label="允许存放的危险等级" align="center" prop="allowedHazardLevels" width="140" />
<el-table-column label="允许存放的物料名称" align="center" prop="allowedCategoryNames" width="200">
<!-- 注释掉物料分类列 -->
<!-- <el-table-column label="允许存放的物料名称" align="center" prop="allowedCategoryNames" width="200">
<template slot-scope="scope">
<el-tooltip
:content="scope.row.allowedCategoryNames"
......@@ -293,7 +297,7 @@
</div>
</el-tooltip>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column label="温区" align="center" prop="temperatureZone" width="100" />
<el-table-column label="应用状态" align="center" prop="isEnabled" width="100">
<template slot-scope="scope">
......@@ -357,6 +361,7 @@
</el-form-item>
</el-col>
</el-row>
<!-- 注释掉仓库选择 -->
<!-- <el-form-item label="仓库" prop="warehouseId">
<el-input
v-model="form.warehouseName"
......@@ -510,7 +515,8 @@
<el-input v-model="form.allowedHazardLevels" placeholder="请输入允许存放的危险等级" />
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 注释掉物料分类选择 -->
<!-- <el-col :span="12">
<el-form-item label="允许存放物料" prop="allowedCategoryIds">
<div style="display: flex; align-items: center; flex-direction: column; gap: 8px;">
<el-input
......@@ -522,7 +528,7 @@
/>
</div>
</el-form-item>
</el-col>
</el-col> -->
</el-row>
<el-row :gutter="20">
<el-col :span="12">
......@@ -549,8 +555,8 @@
</div>
</el-dialog>
<!-- 选择允许存放的物料对话框 -->
<el-dialog
<!-- 注释掉物料选择对话框 -->
<!-- <el-dialog
title="选择允许存放的物料"
:visible.sync="showMaterialSelect"
width="1000px"
......@@ -570,7 +576,7 @@
<el-button @click="handleMaterialSelectionCancel">取消</el-button>
<el-button type="primary" @click="confirmMaterialSelection">确认选择</el-button>
</div>
</el-dialog>
</el-dialog> -->
<!-- 导入组件 -->
<import-excel
......@@ -582,7 +588,7 @@
@success="getList"
/>
<!-- 仓库选择器组件 -->
<!-- 注释掉仓库选择器组件 -->
<!-- <WarehouseSelector
v-model="warehouseSelectorVisible"
@selected="handleWarehouseSelected"
......@@ -592,15 +598,24 @@
<script>
import { listLocations, getLocations, delLocations, addLocations, updateLocations } from "@/api/inventory/locations"
import { listWarehouses } from "@/api/inventory/warehouses"
import materialsSeletor from "../../../components/materialsSeletor.vue"
// 注释掉仓库相关api
// import { listWarehouses } from "@/api/inventory/warehouses"
// 注释掉物料选择器组件
// import materialsSeletor from "../../../components/materialsSeletor.vue"
// 注释掉仓库选择器组件
// import WarehouseSelector from "@/views/compononents/WarehouseSelector.vue"
import ImportExcel from "@/components/ImportExcel/index"
import { listMaterials } from "@/api/inventory/materials"
// 注释掉物料相关api
// import { listMaterials } from "@/api/inventory/materials"
export default {
name: "Locations",
components: { materialsSeletor, WarehouseSelector, ImportExcel },
components: {
// 注释掉物料选择器和仓库选择器组件
// materialsSeletor,
// WarehouseSelector,
ImportExcel
},
dicts: ['sys_normal_disable', 'location_type', 'location_usage', 'yorn','is_enabled'],
data() {
return {
......@@ -620,7 +635,8 @@ export default {
pageSize: 10,
locationCode: null,
locationName: null,
warehouseId: null,
// 注释掉仓库查询参数
// warehouseId: null,
locationType: null,
layerCode: null,
locationUsage: null,
......@@ -634,8 +650,9 @@ export default {
id: null,
locationCode: null,
locationName: null,
warehouseId: null,
warehouseName: null,
// 注释掉仓库相关字段
// warehouseId: null,
// warehouseName: null,
locationType: null,
zoneCode: null,
rowCode: null,
......@@ -644,8 +661,9 @@ export default {
capacity: null,
volumeCapacity: null,
allowedHazardLevels: null,
allowedCategoryIds: null, // 原materialCodes
allowedCategoryNames: null, // 原materialNames
// 注释掉物料分类相关字段
// allowedCategoryIds: null, // 原materialCodes
// allowedCategoryNames: null, // 原materialNames
temperatureZone: null,
isEnabled: 1,
isUsed: 1,
......@@ -670,6 +688,7 @@ export default {
{ required: true, message: '库位名称不能为空', trigger: 'blur' },
{ min: 1, max: 100, message: '库位名称长度不能超过100个字符', trigger: 'blur' }
],
// 注释掉仓库验证规则
// warehouseId: [
// { required: true, message: '仓库不能为空', trigger: 'change' }
// ],
......@@ -688,172 +707,173 @@ export default {
isEnabled: [
{ required: true, message: '应用状态不能为空', trigger: 'change' }
]
// 注释掉物料分类验证规则
// allowedCategoryIds: [
// { required: true, message: '允许存放物料不能为空', trigger: 'change' }
// ]
},
// 仓库相关
warehouseList: [],
loadingWarehouse: false,
queryWarehouseName: '',
// 注释掉仓库相关数据
// warehouseList: [],
// loadingWarehouse: false,
// queryWarehouseName: '',
// 物料选择相关
showMaterialSelect: false,
tempSelectedMaterials: {
materialCodes: [],
names: [],
categoryIds: []
},
materialCodeToNameMap: {},
materialMapLoaded: false,
// 注释掉物料选择相关数据
// showMaterialSelect: false,
// tempSelectedMaterials: {
// materialCodes: [],
// names: [],
// categoryIds: []
// },
// materialCodeToNameMap: {},
// materialMapLoaded: false,
// 仓库选择器相关
warehouseSelectorVisible: false,
warehouseSelectTarget: '',
currentDetailItem: null
// 注释掉仓库选择器相关数据
// warehouseSelectorVisible: false,
// warehouseSelectTarget: '',
// currentDetailItem: null
}
},
created() {
console.log('【Locations组件】开始初始化')
this.getList()
this.getWarehouseList()
this.initMaterialCodeToNameMap()
// 注释掉仓库列表和物料映射表初始化
// this.getWarehouseList()
// this.initMaterialCodeToNameMap()
},
methods: {
// ========== 新增:初始化物料选择器(核心修复数据残留) ==========
initMaterialSelector() {
console.log('【初始化物料选择器】清空残留数据')
// 1. 清空临时选择数据(区分新增/修改)
this.tempSelectedMaterials = {
materialCodes: this.form.id ? (this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(u => u.trim()) : []) : [],
names: this.form.id ? (this.form.allowedCategoryNames ? this.form.allowedCategoryNames.split(',').filter(n => n.trim()) : []) : [],
categoryIds: this.form.id ? (this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(c => c.trim()) : []) : []
}
// 2. 延迟打开弹窗,确保数据先清空
this.$nextTick(() => {
this.showMaterialSelect = true
// 3. 兼容子组件清空选中状态(如果有该方法)
if (this.$refs.materialsSeletor && this.$refs.materialsSeletor.clearSelection) {
this.$refs.materialsSeletor.clearSelection()
// 修改模式下重新设置选中值
if (this.form.id) {
this.$refs.materialsSeletor.setSelection(this.tempSelectedMaterials.materialCodes)
}
}
})
},
// 注释掉物料选择器初始化方法
// initMaterialSelector() {
// console.log('【初始化物料选择器】清空残留数据')
// this.tempSelectedMaterials = {
// materialCodes: this.form.id ? (this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(u => u.trim()) : []) : [],
// names: this.form.id ? (this.form.allowedCategoryNames ? this.form.allowedCategoryNames.split(',').filter(n => n.trim()) : []) : [],
// categoryIds: this.form.id ? (this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(c => c.trim()) : []) : []
// }
// this.$nextTick(() => {
// this.showMaterialSelect = true
// if (this.$refs.materialsSeletor && this.$refs.materialsSeletor.clearSelection) {
// this.$refs.materialsSeletor.clearSelection()
// if (this.form.id) {
// this.$refs.materialsSeletor.setSelection(this.tempSelectedMaterials.materialCodes)
// }
// }
// })
// },
// 清空查询仓库
clearQueryWarehouse() {
console.log('【清空查询仓库】执行清空操作')
this.queryWarehouseName = ''
this.queryParams.warehouseId = null
this.handleQuery()
},
// 注释掉清空查询仓库方法
// clearQueryWarehouse() {
// console.log('【清空查询仓库】执行清空操作')
// this.queryWarehouseName = ''
// this.queryParams.warehouseId = null
// this.handleQuery()
// },
// 清空表单仓库
clearFormWarehouse() {
console.log('【清空表单仓库】执行清空操作')
this.form.warehouseName = ''
this.form.warehouseId = null
},
// 注释掉清空表单仓库方法
// clearFormWarehouse() {
// console.log('【清空表单仓库】执行清空操作')
// this.form.warehouseName = ''
// this.form.warehouseId = null
// },
// 仓库选择回调
handleWarehouseSelected(warehouse) {
console.log('【仓库选择回调】选中的仓库数据:', warehouse)
if (!warehouse) return
const warehouseId = warehouse.warehousesId || warehouse.warehouseId || warehouse.id
const warehouseName = warehouse.warehousesName || warehouse.name || warehouse.warehouseName
// 注释掉仓库选择回调方法
// handleWarehouseSelected(warehouse) {
// console.log('【仓库选择回调】选中的仓库数据:', warehouse)
// if (!warehouse) return
// const warehouseId = warehouse.warehousesId || warehouse.warehouseId || warehouse.id
// const warehouseName = warehouse.warehousesName || warehouse.name || warehouse.warehouseName
if (this.warehouseSelectTarget === 'query') {
this.queryParams.warehouseId = warehouseId
this.queryWarehouseName = warehouseName
this.handleQuery()
} else {
this.form.warehouseId = warehouseId
this.form.warehouseName = warehouseName
// if (this.warehouseSelectTarget === 'query') {
// this.queryParams.warehouseId = warehouseId
// this.queryWarehouseName = warehouseName
// this.handleQuery()
// } else {
// this.form.warehouseId = warehouseId
// this.form.warehouseName = warehouseName
if (this.currentDetailItem) {
this.currentDetailItem.warehouseId = warehouseId
this.currentDetailItem.warehouseName = warehouseName
}
}
this.warehouseSelectorVisible = false
},
// if (this.currentDetailItem) {
// this.currentDetailItem.warehouseId = warehouseId
// this.currentDetailItem.warehouseName = warehouseName
// }
// }
// this.warehouseSelectorVisible = false
// },
// 打开仓库选择器
openWarehouseSelector(target = 'form') {
console.log('【打开仓库选择器】目标:', target)
this.warehouseSelectTarget = target
this.warehouseSelectorVisible = true
},
// 注释掉打开仓库选择器方法
// openWarehouseSelector(target = 'form') {
// console.log('【打开仓库选择器】目标:', target)
// this.warehouseSelectTarget = target
// this.warehouseSelectorVisible = true
// },
// 获取仓库列表
getWarehouseList() {
console.log('【获取仓库列表】开始请求仓库数据')
this.loadingWarehouse = true
listWarehouses({ pageNum: 1, pageSize: 1000, isUsed: 1 }).then(response => {
console.log('【获取仓库列表】请求成功,返回数据:', response)
this.warehouseList = response.rows || []
this.loadingWarehouse = false
}).catch(error => {
console.error('【获取仓库列表】请求失败:', error)
this.warehouseList = []
this.loadingWarehouse = false
})
},
// 注释掉获取仓库列表方法
// getWarehouseList() {
// console.log('【获取仓库列表】开始请求仓库数据')
// this.loadingWarehouse = true
// listWarehouses({ pageNum: 1, pageSize: 1000, isUsed: 1 }).then(response => {
// console.log('【获取仓库列表】请求成功,返回数据:', response)
// this.warehouseList = response.rows || []
// this.loadingWarehouse = false
// }).catch(error => {
// console.error('【获取仓库列表】请求失败:', error)
// this.warehouseList = []
// this.loadingWarehouse = false
// })
// },
// 根据仓库ID获取仓库名称
getWarehouseNameById(warehouseId) {
console.log('【根据仓库ID获取名称】仓库ID:', warehouseId)
if (!warehouseId) return '-'
const warehouse = this.warehouseList.find(item =>
item.warehousesId === warehouseId || item.warehouseId === warehouseId || item.id === warehouseId
)
const warehouseName = warehouse ? (warehouse.warehousesName || warehouse.name || warehouse.warehouseName || '-') : '-'
console.log('【根据仓库ID获取名称】匹配到的仓库名称:', warehouseName)
return warehouseName
},
// 注释掉根据仓库ID获取名称方法
// getWarehouseNameById(warehouseId) {
// console.log('【根据仓库ID获取名称】仓库ID:', warehouseId)
// if (!warehouseId) return '-'
// const warehouse = this.warehouseList.find(item =>
// item.warehousesId === warehouseId || item.warehouseId === warehouseId || item.id === warehouseId
// )
// const warehouseName = warehouse ? (warehouse.warehousesName || warehouse.name || warehouse.warehouseName || '-') : '-'
// console.log('【根据仓库ID获取名称】匹配到的仓库名称:', warehouseName)
// return warehouseName
// },
// 初始化物料编码-名称映射表
async initMaterialCodeToNameMap() {
console.log('【初始化物料映射表】开始加载物料数据')
try {
this.materialMapLoaded = true
let pageNum = 1
const pageSize = 1000
let hasMore = true
this.materialCodeToNameMap = {}
// 注释掉初始化物料编码-名称映射表方法
// async initMaterialCodeToNameMap() {
// console.log('【初始化物料映射表】开始加载物料数据')
// try {
// this.materialMapLoaded = true
// let pageNum = 1
// const pageSize = 1000
// let hasMore = true
// this.materialCodeToNameMap = {}
while (hasMore) {
console.log(`【初始化物料映射表】请求第${pageNum}页物料数据,每页${pageSize}条`)
const response = await listMaterials({
pageNum,
pageSize,
isUsed: 1,
materialCode: null,
materialName: null
})
// while (hasMore) {
// console.log(`【初始化物料映射表】请求第${pageNum}页物料数据,每页${pageSize}条`)
// const response = await listMaterials({
// pageNum,
// pageSize,
// isUsed: 1,
// materialCode: null,
// materialName: null
// })
if (response.rows && response.rows.length) {
console.log(`【初始化物料映射表】第${pageNum}页返回${response.rows.length}条物料数据`)
response.rows.forEach(item => {
if (item.materialCode && item.materialName) {
const code = item.materialCode.trim().toUpperCase()
this.materialCodeToNameMap[code] = item.materialName
}
})
hasMore = pageNum * pageSize < response.total
pageNum++
} else {
hasMore = false
}
}
console.log('【初始化物料映射表】完成,映射表长度:', Object.keys(this.materialCodeToNameMap).length)
} catch (error) {
console.error('【初始化物料映射表】失败:', error)
this.materialMapLoaded = false
this.$modal.msgError('物料数据加载失败,请刷新页面重试!')
}
},
// if (response.rows && response.rows.length) {
// console.log(`【初始化物料映射表】第${pageNum}页返回${response.rows.length}条物料数据`)
// response.rows.forEach(item => {
// if (item.materialCode && item.materialName) {
// const code = item.materialCode.trim().toUpperCase()
// this.materialCodeToNameMap[code] = item.materialName
// }
// })
// hasMore = pageNum * pageSize < response.total
// pageNum++
// } else {
// hasMore = false
// }
// }
// console.log('【初始化物料映射表】完成,映射表长度:', Object.keys(this.materialCodeToNameMap).length)
// } catch (error) {
// console.error('【初始化物料映射表】失败:', error)
// this.materialMapLoaded = false
// this.$modal.msgError('物料数据加载失败,请刷新页面重试!')
// }
// },
// 行点击事件
handleRowClick(row, event, column) {
......@@ -870,8 +890,9 @@ export default {
const params = {
...this.queryParams,
isUsed: 1,
warehousesId: this.queryParams.warehouseId,
warehouseId: undefined
// 注释掉仓库ID参数
// warehousesId: this.queryParams.warehouseId,
// warehouseId: undefined
}
console.log('【获取库位列表】最终请求参数:', params)
listLocations(params).then(response => {
......@@ -902,7 +923,8 @@ export default {
pageSize: 10,
locationCode: null,
locationName: null,
warehouseId: null,
// 注释掉仓库查询参数
// warehouseId: null,
locationType: null,
layerCode: null,
locationUsage: null,
......@@ -910,7 +932,8 @@ export default {
zoneCode: null,
pickingArea: null
}
this.queryWarehouseName = ''
// 注释掉查询仓库名称重置
// this.queryWarehouseName = ''
this.getList()
},
......@@ -950,73 +973,68 @@ export default {
// 映射后端字段到前端
const formData = {
...rowData,
warehouseId: rowData.warehousesId || rowData.warehouseId || rowData.id,
warehousesId: undefined
// 注释掉仓库相关字段映射
// warehouseId: rowData.warehousesId || rowData.warehouseId || rowData.id,
// warehousesId: undefined
}
this.form = JSON.parse(JSON.stringify(formData))
// 设置仓库名称
if (this.form.warehouseId) {
this.form.warehouseName = this.getWarehouseNameById(this.form.warehouseId)
}
// 注释掉仓库名称设置
// if (this.form.warehouseId) {
// this.form.warehouseName = this.getWarehouseNameById(this.form.warehouseId)
// }
await this.initMaterialCodeToNameMap()
// 注释掉物料映射表初始化
// await this.initMaterialCodeToNameMap()
// 处理物料编码和名称(支持数组或字符串格式)
let materialCodes = []
let materialNames = []
// 注释掉物料编码和名称处理
// let materialCodes = []
// let materialNames = []
// 优先从allowedCategoryIds数组读取(原materialIds)
if (Array.isArray(rowData.allowedCategoryIds) && rowData.allowedCategoryIds.length) {
materialCodes = rowData.allowedCategoryIds
.filter(code => code && code.trim())
.map(code => code.trim().toUpperCase())
.filter((code, index, self) => self.indexOf(code) === index)
}
// 兼容字符串格式
else if (rowData.allowedCategoryIds) {
materialCodes = rowData.allowedCategoryIds.split(',')
.filter(code => code && code.trim())
.map(code => code.trim().toUpperCase())
.filter((code, index, self) => self.indexOf(code) === index)
}
// if (Array.isArray(rowData.allowedCategoryIds) && rowData.allowedCategoryIds.length) {
// materialCodes = rowData.allowedCategoryIds
// .filter(code => code && code.trim())
// .map(code => code.trim().toUpperCase())
// .filter((code, index, self) => self.indexOf(code) === index)
// }
// else if (rowData.allowedCategoryIds) {
// materialCodes = rowData.allowedCategoryIds.split(',')
// .filter(code => code && code.trim())
// .map(code => code.trim().toUpperCase())
// .filter((code, index, self) => self.indexOf(code) === index)
// }
// 处理物料名称
if (Array.isArray(rowData.allowedCategoryNames) && rowData.allowedCategoryNames.length) {
materialNames = rowData.allowedCategoryNames
.filter(name => name && name.trim())
.filter((name, index, self) => self.indexOf(name) === index)
}
else if (rowData.allowedCategoryNames) {
materialNames = rowData.allowedCategoryNames.split(',')
.filter(name => name && name.trim())
.filter((name, index, self) => self.indexOf(name) === index)
}
// 兜底:通过物料编码映射名称
else if (materialCodes.length) {
materialNames = materialCodes.map(code => {
return this.materialCodeToNameMap[code] || `【未匹配】${code}`
})
}
// if (Array.isArray(rowData.allowedCategoryNames) && rowData.allowedCategoryNames.length) {
// materialNames = rowData.allowedCategoryNames
// .filter(name => name && name.trim())
// .filter((name, index, self) => self.indexOf(name) === index)
// }
// else if (rowData.allowedCategoryNames) {
// materialNames = rowData.allowedCategoryNames.split(',')
// .filter(name => name && name.trim())
// .filter((name, index, self) => self.indexOf(name) === index)
// }
// else if (materialCodes.length) {
// materialNames = materialCodes.map(code => {
// return this.materialCodeToNameMap[code] || `【未匹配】${code}`
// })
// }
// 处理分类ID(现在存储的是物料编码)
let categoryIds = materialCodes
// let categoryIds = materialCodes
// 更新表单数据
this.form.allowedCategoryIds = materialCodes.join(',')
this.form.allowedCategoryNames = materialNames.join(',')
// this.form.allowedCategoryIds = materialCodes.join(',')
// this.form.allowedCategoryNames = materialNames.join(',')
// 更新临时选择数据
this.tempSelectedMaterials = {
materialCodes: materialCodes,
names: materialNames,
categoryIds: categoryIds
}
// this.tempSelectedMaterials = {
// materialCodes: materialCodes,
// names: materialNames,
// categoryIds: categoryIds
// }
console.log('【修改库位】处理后的物料数据:', {
allowedCategoryIds: this.form.allowedCategoryIds,
allowedCategoryNames: this.form.allowedCategoryNames
})
// console.log('【修改库位】处理后的物料数据:', {
// allowedCategoryIds: this.form.allowedCategoryIds,
// allowedCategoryNames: this.form.allowedCategoryNames
// })
this.open = true
this.title = "修改库位"
......@@ -1032,26 +1050,27 @@ export default {
this.$refs["form"].validate(valid => {
if (valid) {
console.log('【提交表单】表单验证通过,开始格式化数据')
// 格式化物料相关字段(去重、过滤空值)
const formatField = (value) => {
if (!value) return ''
const result = value.split(',')
.filter(item => item && item.trim())
.filter((item, index, self) => self.indexOf(item) === index)
.join(',')
console.log(`【提交表单】格式化字段值 "${value}" 结果: "${result}"`)
return result
}
// 注释掉物料字段格式化
// const formatField = (value) => {
// if (!value) return ''
// const result = value.split(',')
// .filter(item => item && item.trim())
// .filter((item, index, self) => self.indexOf(item) === index)
// .join(',')
// console.log(`【提交表单】格式化字段值 "${value}" 结果: "${result}"`)
// return result
// }
this.form.allowedCategoryIds = formatField(this.form.allowedCategoryIds)
this.form.allowedCategoryNames = formatField(this.form.allowedCategoryNames)
// this.form.allowedCategoryIds = formatField(this.form.allowedCategoryIds)
// this.form.allowedCategoryNames = formatField(this.form.allowedCategoryNames)
// 转换表单数据
const submitData = {
...this.form,
warehousesId: this.form.warehouseId,
warehouseId: undefined,
warehouseName: undefined
// 注释掉仓库相关字段转换
// warehousesId: this.form.warehouseId,
// warehouseId: undefined,
// warehouseName: undefined
}
console.log('【提交表单】最终提交数据:', submitData)
......@@ -1100,76 +1119,71 @@ export default {
console.log('【导出库位】执行导出操作,查询参数:', this.queryParams)
const exportParams = {
...this.queryParams,
warehousesId: this.queryParams.warehouseId,
warehouseId: undefined
// 注释掉仓库导出参数
// warehousesId: this.queryParams.warehouseId,
// warehouseId: undefined
}
console.log('【导出库位】最终导出参数:', exportParams)
this.download('inventory/locations/export', exportParams, `locations_${new Date().getTime()}.xlsx`)
},
// 物料选择变化
handleMaterialSelectionChange(selectedData) {
console.log('【物料选择变化】接收到的选择数据:', selectedData)
// 注释掉物料选择变化方法
// handleMaterialSelectionChange(selectedData) {
// console.log('【物料选择变化】接收到的选择数据:', selectedData)
// 修复:从selectedData中取materialIds(而非materialCodes)
const materialCodes = (selectedData.materialIds || [])
.filter(code => code && code.trim())
.map(code => code.trim().toUpperCase())
.filter((code, index, self) => self.indexOf(code) === index)
// const materialCodes = (selectedData.materialIds || [])
// .filter(code => code && code.trim())
// .map(code => code.trim().toUpperCase())
// .filter((code, index, self) => self.indexOf(code) === index)
// 物料名称取selectedData.names
const names = (selectedData.names || [])
.filter(name => name && name.trim())
.filter((name, index, self) => self.indexOf(name) === index)
// const names = (selectedData.names || [])
// .filter(name => name && name.trim())
// .filter((name, index, self) => self.indexOf(name) === index)
// 分类ID取selectedData.categoryIds(现在存储的是物料编码)
const categoryIds = materialCodes
// const categoryIds = materialCodes
this.tempSelectedMaterials = {
materialCodes,
names,
categoryIds
}
// this.tempSelectedMaterials = {
// materialCodes,
// names,
// categoryIds
// }
console.log('【物料选择变化】处理后的临时选择数据:', this.tempSelectedMaterials)
},
// console.log('【物料选择变化】处理后的临时选择数据:', this.tempSelectedMaterials)
// },
// 取消物料选择
handleMaterialSelectionCancel() {
console.log('【取消物料选择】执行取消操作,恢复原有选择状态')
this.showMaterialSelect = false
// 恢复原有选择状态
this.tempSelectedMaterials = {
materialCodes: this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(u => u.trim()) : [],
names: this.form.allowedCategoryNames ? this.form.allowedCategoryNames.split(',').filter(n => n.trim()) : [],
categoryIds: this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(c => c.trim()) : []
}
console.log('【取消物料选择】恢复后的临时选择数据:', this.tempSelectedMaterials)
},
// 注释掉取消物料选择方法
// handleMaterialSelectionCancel() {
// console.log('【取消物料选择】执行取消操作,恢复原有选择状态')
// this.showMaterialSelect = false
// this.tempSelectedMaterials = {
// materialCodes: this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(u => u.trim()) : [],
// names: this.form.allowedCategoryNames ? this.form.allowedCategoryNames.split(',').filter(n => n.trim()) : [],
// categoryIds: this.form.allowedCategoryIds ? this.form.allowedCategoryIds.split(',').filter(c => c.trim()) : []
// }
// console.log('【取消物料选择】恢复后的临时选择数据:', this.tempSelectedMaterials)
// },
// 确认物料选择
confirmMaterialSelection() {
console.log('【确认物料选择】当前临时选择数据:', this.tempSelectedMaterials)
// 注释掉确认物料选择方法
// confirmMaterialSelection() {
// console.log('【确认物料选择】当前临时选择数据:', this.tempSelectedMaterials)
// 修复:判断tempSelectedMaterials.materialCodes是否有值
if (!this.tempSelectedMaterials.materialCodes.length) {
console.warn('【确认物料选择】未选择任何物料,提示用户')
this.$modal.msgWarning('请至少选择一个物料!')
return
}
// if (!this.tempSelectedMaterials.materialCodes.length) {
// console.warn('【确认物料选择】未选择任何物料,提示用户')
// this.$modal.msgWarning('请至少选择一个物料!')
// return
// }
// 更新表单数据(确保去重和过滤)
this.form.allowedCategoryIds = this.tempSelectedMaterials.materialCodes.join(',')
this.form.allowedCategoryNames = this.tempSelectedMaterials.names.join(',')
// this.form.allowedCategoryIds = this.tempSelectedMaterials.materialCodes.join(',')
// this.form.allowedCategoryNames = this.tempSelectedMaterials.names.join(',')
console.log('【确认物料选择】更新后的表单物料数据:', {
allowedCategoryIds: this.form.allowedCategoryIds,
allowedCategoryNames: this.form.allowedCategoryNames
})
// console.log('【确认物料选择】更新后的表单物料数据:', {
// allowedCategoryIds: this.form.allowedCategoryIds,
// allowedCategoryNames: this.form.allowedCategoryNames
// })
this.showMaterialSelect = false
this.$modal.msgSuccess(`成功选择 ${this.tempSelectedMaterials.names.length} 个物料`)
},
// this.showMaterialSelect = false
// this.$modal.msgSuccess(`成功选择 ${this.tempSelectedMaterials.names.length} 个物料`)
// },
// 导入库位
handleImport() {
......@@ -1184,8 +1198,9 @@ export default {
id: null,
locationCode: null,
locationName: null,
warehouseId: null,
warehouseName: null,
// 注释掉仓库相关字段重置
// warehouseId: null,
// warehouseName: null,
locationType: null,
zoneCode: null,
rowCode: null,
......@@ -1194,8 +1209,9 @@ export default {
capacity: null,
volumeCapacity: null,
allowedHazardLevels: null,
allowedCategoryIds: null, // 原materialCodes
allowedCategoryNames: null, // 原materialNames
// 注释掉物料分类相关字段重置
// allowedCategoryIds: null,
// allowedCategoryNames: null,
temperatureZone: null,
isEnabled: 1,
isUsed: 1,
......@@ -1209,15 +1225,16 @@ export default {
allowMixedProducts: null,
allowMixedBatches: null
}
this.tempSelectedMaterials = {
materialCodes: [],
names: [],
categoryIds: []
}
// 修复:清空物料选择器残留
if (this.$refs.materialsSeletor && this.$refs.materialsSeletor.clearSelection) {
this.$refs.materialsSeletor.clearSelection()
}
// 注释掉物料选择临时数据重置
// this.tempSelectedMaterials = {
// materialCodes: [],
// names: [],
// categoryIds: []
// }
// 注释掉物料选择器清空
// if (this.$refs.materialsSeletor && this.$refs.materialsSeletor.clearSelection) {
// this.$refs.materialsSeletor.clearSelection()
// }
if (this.$refs.form) {
this.$refs.form.resetFields()
}
......
......@@ -49,12 +49,13 @@
<div style="height: 70vh; overflow: auto; padding: 0 10px;">
<MaterialSelector
ref="materialsSeletor"
@selection-change="confirmMaterialSelect"
:selected-material-codes="form.materialUuids ? [form.materialUuids] : []"
@selection-change="handleMaterialSelectionChange"
:selected-material-ids="form.materialId ? [form.materialId] : []"
:orders-id="ordersId || outboundOrderId"
:multiple="false"
:detail-list="details"
/>
</div>
</el-dialog>
<!-- 库存信息列表 -->
......@@ -76,7 +77,7 @@
:row-key="item => item.inventoryId"
>
<el-table-column prop="materialName" label="物料名称" width="180" />
<el-table-column prop="batchId" label="批次ID" width="150" />
<el-table-column prop="batchId" label="批次" width="150" />
<el-table-column prop="warehousesName" label="仓库名称" width="120" />
<el-table-column prop="locationName" label="库位名称" width="120" />
<el-table-column
......@@ -141,7 +142,7 @@
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-col :span="8">
<el-form-item label="凭证号" prop="voucherNumber">
<el-input
v-model="currentSelectedRow.voucherNumber"
......@@ -152,7 +153,7 @@
</el-col>
</el-row>
<el-row :gutter="20" style="margin-top: 10px;">
<el-col :span="8">
<el-col :span="8">
<el-form-item label="约数" prop="divisor">
<el-input
v-model.number="currentSelectedRow.divisor"
......@@ -189,7 +190,7 @@
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" style="margin-top: 10px;">
<el-col :span="16">
<el-form-item label="备注" prop="remark">
......@@ -224,9 +225,8 @@
<el-table-column prop="batchId" label="批次ID" width="150" />
<el-table-column prop="warehousesName" label="仓库名称" width="120" />
<el-table-column prop="locationName" label="库位名称" width="120" />
<el-table-column prop="plannedQuantity" label="计划数量" width="100" />
<el-table-column prop="actualQuantity" label="实际数量" width="100" fixed="right"/>
<el-table-column prop="actualQuantity" label="实际数量" width="100" fixed="right"/>
<el-table-column prop="unitPrice" label="单价" width="100" />
<el-table-column prop="divisor" label="约数" width="80" />
<el-table-column prop="labelColor" label="标签颜色" width="100">
......@@ -311,6 +311,7 @@ export default {
},
data() {
return {
orderId: this.ordersId || this.outboundOrderId || '',
form: {
materialUuids: '',
materialId: '',
......@@ -333,7 +334,7 @@ export default {
selectedMaterialInfo: null,
currentSelectedRowId: null,
isInitEcho: false,
openMaterialSelector: false, // 确保初始为关闭状态
isUserInitiatedSelect: false
};
},
computed: {
......@@ -344,6 +345,10 @@ export default {
return this.initDetails.length > 0 || !!this.initForm.materialId;
}
},
created() {
console.log('子组件接收的 ordersId:', this.ordersId);
console.log('子组件接收的 initDetails:', this.initDetails);
},
watch: {
open: {
handler(newVal) {
......@@ -358,7 +363,10 @@ export default {
this.selectedMaterialId = this.form.materialId || '';
this.selectedMaterialInfo = null;
this.currentSelectedRowId = null;
this.details = this.initDetails.length > 0 ? JSON.parse(JSON.stringify(this.initDetails)) : [];
// 初始化 details:使用传入的 initDetails
this.details = this.initDetails.length > 0
? JSON.parse(JSON.stringify(this.initDetails))
: [];
this.$nextTick(async () => {
if (this.form.materialId && this.form.materialId.trim()) {
await this.handleMaterialIdChange();
......@@ -513,6 +521,8 @@ export default {
} finally {
this.$nextTick(() => {
this.closeLoading();
// 主动触发明细同步,确保 details 有初始值
this.syncDetails(false);
});
}
},
......@@ -603,142 +613,148 @@ export default {
this.$set(row, 'plannedQuantity', 1);
}
},
// 改造后的 syncDetails:仅校验有实际数量的行,且有值才校验
syncDetails(strict = true) {
this.details = [];
const errorMessages = []; // 收集有值但不合规的字段提示
let validRows = [];
// 第一步:先过滤出「实际数量有值」的行(核心:无实际数量的行直接排除)
const rowsWithActualQty = this.inventoryList.filter(row => {
return row.actualQuantity !== null && row.actualQuantity !== undefined;
});
if (strict && rowsWithActualQty.length > 0) {
// 严格模式:仅校验有实际数量的行,且「有值才校验」
validRows = rowsWithActualQty.filter((row, index) => {
const rowErrors = [];
const rowName = `第${index + 1}行【${row.materialName || '未知物料'}】`;
const availableQty = (row.quantity || 0) - (row.lockedQuantity || 0);
syncDetails(strict = true) {
this.details = [];
const errorMessages = [];
let validRows = [];
if (!strict) {
validRows = this.inventoryList.filter(row => {
return row.actualQuantity !== null ||
row.plannedQuantity !== null ||
row.unitPrice !== null ||
row.labelColor !== '' ||
row.voucherNumber !== '' ||
row.shippedBy !== '';
});
// 1. 实际数量(必校验,因为能走到这步说明有值)
if (row.actualQuantity < 1) {
rowErrors.push('实际数量不能小于1');
}
if (row.actualQuantity > availableQty) {
rowErrors.push(`实际数量不能超过可用库存(${availableQty})`);
validRows.forEach((row, index) => {
const availableQty = (row.quantity || 0) - (row.lockedQuantity || 0);
if (row.actualQuantity !== null && row.actualQuantity < 1) {
this.$set(row, 'actualQuantity', 1);
}
if (row.actualQuantity !== null && row.actualQuantity > availableQty) {
this.$set(row, 'actualQuantity', availableQty);
}
if (row.plannedQuantity !== null && row.plannedQuantity < 1) {
this.$set(row, 'plannedQuantity', 1);
}
if (row.plannedQuantity !== null && row.plannedQuantity > availableQty) {
this.$set(row, 'plannedQuantity', availableQty);
}
});
} else {
const rowsWithActualQty = this.inventoryList.filter(row => {
return row.actualQuantity !== null && row.actualQuantity !== undefined;
});
validRows = rowsWithActualQty.filter((row, index) => {
const rowErrors = [];
const rowName = `第${index + 1}行【${row.materialName || '未知物料'}】`;
const availableQty = (row.quantity || 0) - (row.lockedQuantity || 0);
if (row.actualQuantity < 1) {
rowErrors.push('实际数量不能小于1');
}
if (row.actualQuantity > availableQty) {
rowErrors.push(`实际数量不能超过可用库存(${availableQty})`);
}
if (row.plannedQuantity !== null && row.plannedQuantity !== undefined) {
if (row.plannedQuantity < 1) {
rowErrors.push('计划数量不能小于1');
}
if (row.plannedQuantity > availableQty) {
rowErrors.push(`计划数量不能超过可用库存(${availableQty})`);
}
} else {
rowErrors.push(`请填写计划数量`);
}
if (row.unitPrice === null || row.unitPrice === undefined || row.unitPrice <= 0) {
rowErrors.push('请填写有效的单价(大于0)');
}
if (rowErrors.length > 0) {
errorMessages.push(`${rowName}${rowErrors.join('、')}`);
return false;
}
return true;
});
}
// 2. 计划数量(有值才校验)
if (row.plannedQuantity !== null && row.plannedQuantity !== undefined) {
if (row.plannedQuantity < 1) {
rowErrors.push('计划数量不能小于1');
}
if (row.plannedQuantity > availableQty) {
rowErrors.push(`计划数量不能超过可用库存(${availableQty})`);
}
}else{
rowErrors.push(`请填写计划数量`);
validRows.forEach(row => {
const newDetail = {
inventoryId: row.inventoryId,
materialId: row.materialId || this.form.materialId,
materialName: row.materialName || this.form.materialName || '',
batchId: row.batchId || row.batchCode || '',
warehouseId: row.warehouseId,
warehousesId: row.warehousesId || '',
warehousesName: row.warehousesName || '',
locationId: row.locationId || '',
locationName: row.locationName || '',
outboundOrderId: this.form.outboundOrderId || '',
plannedQuantity: row.plannedQuantity,
actualQuantity: row.actualQuantity,
divisor: row.divisor,
labelColor: row.labelColor,
unitPrice: row.unitPrice,
shippedBy: row.shippedBy,
voucherNumber: row.voucherNumber,
remark: row.remark
};
this.details.push(newDetail);
});
console.log('syncDetails 执行结果:', this.details);
return errorMessages;
},
handleSubmit() {
if (!this.form.materialId?.trim()) {
this.$message.error('请先选择物料ID');
return;
}
// 3. 除数(有值才校验,无值不提示)
if (row.unitPrice !== null && row.unitPrice !== undefined) {
// 若有值但为0/负数,可补充校验(按需)
if (row.unitPrice <= 0) {
rowErrors.push('请填写单价');
this.$refs.detailForm.validate(async (valid) => {
if (!valid) {
this.$message.error('表单校验失败,请检查必填项');
return;
}
}
// 收集当前行的错误(仅有值但不合规的字段)
if (rowErrors.length > 0) {
errorMessages.push(`${rowName}${rowErrors.join('、')}`);
return false;
}
return true;
});
}
// 格式化通过校验的行并同步到details
validRows.forEach(row => {
const newDetail = {
inventoryId: row.inventoryId,
materialId: row.materialId || this.form.materialId,
materialName: row.materialName || this.form.materialName || '',
batchId: row.batchId || row.batchCode || '',
warehouseId: row.warehouseId,
warehousesId: row.warehousesId || '',
warehousesName: row.warehousesName || '',
locationId: row.locationId || '',
locationName: row.locationName || '',
outboundOrderId: this.form.outboundOrderId || '',
plannedQuantity: row.plannedQuantity,
actualQuantity: row.actualQuantity,
divisor: row.divisor,
labelColor: row.labelColor,
unitPrice: row.unitPrice,
shippedBy: row.shippedBy,
voucherNumber: row.voucherNumber,
remark: row.remark
};
this.details.push(newDetail);
});
// 返回错误信息,供提交方法使用
return errorMessages;
},
// 提交方法:集成精准提示
handleSubmit() {
// 1. 校验物料ID
if (!this.form.materialId?.trim()) {
this.$message.error('请先选择物料ID');
return;
}
console.log("syncDetails前", this.details);
const detailErrors = this.syncDetails(true);
console.log("syncDetails后", this.details);
if (detailErrors.length > 0) {
this.$message.error({
title: '明细数据校验失败',
message: detailErrors.join('<br/>'),
dangerouslyUseHTMLString: true,
duration: 15000,
showClose: true
});
return;
}
// 2. 校验表单基础项
this.$refs.detailForm.validate(async (valid) => {
if (!valid) {
this.$message.error('表单校验失败,请检查必填项');
return;
}
if (this.details.length === 0) {
this.$message.error('无有效明细数据,请检查实际数量及相关字段');
return;
}
console.log("syncDetails前", this.details);
// 执行明细校验,接收错误信息
const detailErrors = this.syncDetails(true);
console.log("syncDetails后", this.details);
// 3. 提示有值但不合规的字段
if (detailErrors.length > 0) {
this.$message.error({
title: '明细数据校验失败',
message: detailErrors.join('<br/>'),
dangerouslyUseHTMLString: true,
duration: 15000,
showClose: true
const submitDetails = this.details.map(detail => ({
...detail,
materialName: this.form.materialName || detail.materialName,
outboundOrderId: this.form.outboundOrderId || detail.outboundOrderId,
materialId: this.form.materialId || detail.materialId
}));
console.log('提交的明细数据:', submitDetails);
this.$emit('submit', submitDetails);
this.$emit('update:open', false);
});
return;
}
// 4. 兜底:有实际数量的行都校验通过,但无有效行(比如实际数量都<1
if (this.details.length === 0) {
this.$message.error('无有效明细数据,请检查实际数量及相关字段');
return;
}
// 5. 组装提交数据
const submitDetails = this.details.map(detail => ({
...detail,
materialName: this.form.materialName || detail.materialName,
outboundOrderId: this.form.outboundOrderId || detail.outboundOrderId,
materialId: this.form.materialId || detail.materialId
}));
console.log('提交的明细数据:', submitDetails);
this.$emit('submit', submitDetails);
this.$emit('update:open', false);
});
},
},
removeDetail(row) {
this.details = this.details.filter(d => d.inventoryId !== row.inventoryId);
const inventoryRow = this.inventoryList.find(item => item.inventoryId === row.inventoryId);
......@@ -757,7 +773,6 @@ handleSubmit() {
}
this.syncDetails(this.initDetails.length === 0);
},
handleClose() {
this.closeLoading();
this.$nextTick(() => {
......@@ -775,71 +790,43 @@ handleSubmit() {
});
this.$emit('update:open', false);
},
// 修复:接收selection-change事件参数,兼容多种字段名
handleMaterialSelectionChange(selectedData) {
console.log("【物料选择事件触发】选中数据:", selectedData);
// 兼容数组格式(multiple=false时可能返回对象,需转为数组)
const selectList = Array.isArray(selectedData) ? selectedData : selectedData ? [selectedData] : [];
handleMaterialSelectionChange(selectionData) {
console.log('传给子组件的detailList:', this.details);
if (selectList.length > 0) {
this.selectedMaterialInfo = selectList[0];
// 关键:兼容常见的物料ID字段名(id/materialId/uuid)
this.selectedMaterialId = this.selectedMaterialInfo.id || this.selectedMaterialInfo.materialId || this.selectedMaterialInfo.uuid || '';
// 兼容常见的物料名称字段名(materialName/name)
this.$set(this.form, 'materialName', this.selectedMaterialInfo.materialName || this.selectedMaterialInfo.name || '');
console.log("【物料选择成功】ID:", this.selectedMaterialId, "名称:", this.form.materialName);
} else {
this.selectedMaterialInfo = null;
this.selectedMaterialId = '';
this.$set(this.form, 'materialName', '');
console.log("【物料选择清空】");
}
},
// 修复:增强校验逻辑,增加组件存在性检查和异步同步
confirmMaterialSelect() {
// 标记为“用户主动操作”
this.isUserInitiatedSelect = true;
// 1. 检查选择器组件是否存在
if (!this.$refs.materialsSeletor) {
this.$message.error('物料选择器组件加载失败,请重试');
return;
}
this.selectedMaterialInfo = null;
this.selectedMaterialId = '';
this.$set(this.form, 'materialName', '');
// 2. 异步等待组件数据同步(避免取值过早)
this.$nextTick(() => {
// 3. 强制触发选中数据同步
const selector = this.$refs.materialsSeletor;
let selectedData = [];
// 兼容组件的多种取值方式
if (selector.getSelectedMaterials) {
selectedData = selector.getSelectedMaterials();
} else if (selector.selectedList) {
selectedData = selector.selectedList;
} else if (selector.value) {
selectedData = selector.value;
}
// 触发数据同步(覆盖事件未触发的场景)
this.handleMaterialSelectionChange(selectedData);
if (!selectionData || !selectionData.materials) {
console.log("【物料选择清空】无有效选中数据");
return;
}
const materials = Array.isArray(selectionData.materials) ? selectionData.materials : [];
if (materials.length === 0) {
console.log("【物料选择清空】选中列表为空");
return;
}
// 5. 容错处理:确保物料ID有效
const materialId = this.selectedMaterialInfo.id || this.selectedMaterialInfo.materialId || this.selectedMaterialInfo.uuid || '';
const firstItem = materials[0];
if (!firstItem) {
console.log("【物料选择清空】第一个选中项为空");
return;
}
// 6. 赋值并关闭弹窗
this.$set(this.form, 'materialId', materialId);
this.$set(this.form, 'materialUuids', materialId);
this.openMaterialSelector = false;
this.selectedMaterialInfo = firstItem;
this.selectedMaterialId = firstItem.id || firstItem.materialId || firstItem.uuid || '';
this.$set(this.form, 'materialName', firstItem.materialName || firstItem.name || '');
this.$set(this.form, 'materialId', this.selectedMaterialId);
this.$set(this.form, 'materialUuids', this.selectedMaterialId);
this.openMaterialSelector = false;
// 7. 查询库存并校验字段
this.handleMaterialIdChange();
this.$nextTick(() => {
this.$refs.detailForm?.validateField('materialId');
});
console.log("【物料选择成功】ID:", this.selectedMaterialId, "名称:", this.form.materialName);
// 重置标记
this.isUserInitiatedSelect = false;
});
this.$nextTick(async () => {
await this.handleMaterialIdChange();
this.$refs.detailForm?.validateField('materialId');
});
}
},
beforeDestroy() {
......
......@@ -3,14 +3,16 @@
<!-- 页面标题和操作按钮 -->
<PageTitle>
<template #buttons>
<el-button
<el-button
type="primary"
plain
icon="el-icon-plus"
size="medium"
@click="handleAdd"
v-hasPermi="['inventory:orders:add']"
v-hasPermi="['inventory:inbound:add']"
>新增</el-button>
<el-button
type="success"
plain
......@@ -18,16 +20,9 @@
size="medium"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['inventory:orders:edit']"
v-hasPermi="['inventory:inbound:edit']"
>修改</el-button>
<el-button
type="success"
plain
icon="el-icon-edit"
size="medium"
@click="handleImport"
v-hasPermi="['inventory:orders:add']"
>导入</el-button>
<el-button
type="danger"
plain
......@@ -35,15 +30,25 @@
size="medium"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['inventory:orders:remove']"
v-hasPermi="['inventory:inbound:remove']"
>删除</el-button>
<el-button
type="warning"
plain
icon="el-icon-upload"
size="medium"
@click="handleImport"
v-hasPermi="['inventory:inbound:import']"
>导入</el-button>
<el-button
type="warning"
plain
icon="el-icon-download"
size="medium"
@click="handleExport"
v-hasPermi="['inventory:orders:export']"
v-hasPermi="['inventory:inbound:export']"
>导出</el-button>
</template>
</PageTitle>
......@@ -98,10 +103,10 @@
/>
</el-select>
</el-form-item>
<el-form-item label="批次ID" prop="batchCode">
<el-form-item label="批次" prop="batchCode">
<el-input
v-model="queryParams.batchCode"
placeholder="请输入批次ID"
placeholder="请输入批次"
clearable
@keyup.enter.native="handleQuery"
/>
......@@ -205,7 +210,7 @@
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="批次ID" align="center" prop="batchCode" width="120" />
<el-table-column label="批次" align="center" prop="batchCode" width="120" />
<el-table-column label="仓库" align="center" prop="warehouseName" width="120">
<template slot-scope="scope">
{{ scope.row.warehouseName || '-' }}
......@@ -336,8 +341,8 @@
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="批次ID" prop="batchCode">
<el-input v-model="form.batchCode" placeholder="请输入批次ID" :disabled="isViewDetail || formDisabled.batchCode" />
<el-form-item label="批次" prop="batchCode">
<el-input v-model="form.batchCode" placeholder="请输入批次" :disabled="isViewDetail || formDisabled.batchCode" />
</el-form-item>
</el-col>
<el-col :span="12">
......@@ -420,13 +425,10 @@
</el-col>
</el-row>
<!-- 【修改1】新增materialName展示 -->
<div v-for="(group, materialId) in outboundOrderItemsGroup" :key="materialId" class="material-group mb10">
<div class="group-header" style="background: #f5f7fa; padding: 8px 12px; border-radius: 4px; margin-bottom: 8px;">
<!-- 【修改2】展示物料名称(优先取分组的materialName,无则用getMaterialName方法) -->
<span style="font-weight: 600; margin-right: 16px;">物料:{{ group.materialName }}</span>
<span style="color: #666;">明细数量:{{ group.items.length }} </span>
<!-- 仅编辑模式显示分组操作按钮 -->
<el-button
type="text"
size="mini"
......
......@@ -7,6 +7,8 @@ import java.util.UUID;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.common.core.domain.entity.Materials;
import com.ruoyi.inventory.domain.Inventory;
import com.ruoyi.inventory.domain.OutboundOrderItems;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
......@@ -45,6 +47,19 @@ public class MaterialsController extends BaseController
}
/**
* 查询库存列表
*/
@PreAuthorize("@ss.hasPermi('inventory:inventory:list')")
@PostMapping("/ListMaterialsInventory")
public TableDataInfo ListMaterialsInventory(Materials materials)
{
startPage();
List<Materials> list = materialsService.ListMaterialsInventory(materials);
return getDataTable(list);
}
/**
* 导出物料列表
*/
@PreAuthorize("@ss.hasPermi('inventory:materials:export')")
......
......@@ -2,16 +2,13 @@ package com.ruoyi.common.core.domain.entity;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 物料对象 materials
*
*
* @author ruoyi
* @date 2025-11-28
*/
public class Materials extends BaseEntity
{
private static final long serialVersionUID = 1L;
......@@ -38,7 +35,6 @@ public class Materials extends BaseEntity
@Excel(name = "中文描述")
private String materialName;
/** 物料名称 检索条件 */
@Excel(name = "英文描述")
private String materialEname;
......@@ -136,6 +132,12 @@ public class Materials extends BaseEntity
/** 排序号 */
private String updateUserCode;
// ======================== 仅新增这一个库存字段 ========================
/** 库存数量(关联inventory表) */
@Excel(name = "库存数量")
private Long stock;
// ======================== 原有所有getter/setter(完整保留) ========================
public String getId() {
return id;
}
......@@ -386,6 +388,15 @@ public class Materials extends BaseEntity
this.updateUserCode = updateUserCode;
}
// ======================== 仅新增库存字段的getter/setter ========================
public Long getStock() {
return stock;
}
public void setStock(Long stock) {
this.stock = stock;
}
@Override
public String toString() {
return "Materials{" +
......@@ -420,6 +431,7 @@ public class Materials extends BaseEntity
", sortNo=" + sortNo +
", createUserCode='" + createUserCode + '\'' +
", updateUserCode='" + updateUserCode + '\'' +
", stock=" + stock + // 仅追加这一行
'}';
}
}
}
\ No newline at end of file
......@@ -99,6 +99,9 @@ public class InventoryController extends BaseController
List<Inventory> list = inventoryService.listByMatreialId(inventory);
return getDataTable(list);
}
/**
* 导出库存列表
*/
......
......@@ -3,9 +3,11 @@ package com.ruoyi.inventory.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.inventory.domain.OutboundOrderLog;
import com.ruoyi.inventory.domain.vo.inboundVO.InboundTemplateVO;
import com.ruoyi.inventory.domain.vo.OutboundOrdersSummaryVO;
import com.ruoyi.inventory.domain.vo.OutboundTemplateVO;
import com.ruoyi.inventory.service.IOutboundOrderLogService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -39,6 +41,9 @@ public class OutboundOrderItemsController extends BaseController
{
@Autowired
private IOutboundOrderItemsService outboundOrderItemsService;
@Autowired
private IOutboundOrderLogService outboundOrderLogService;
/**
* 查询出库单明细列表
......@@ -55,6 +60,19 @@ public class OutboundOrderItemsController extends BaseController
* 查询出库单明细列表
*/
@PreAuthorize("@ss.hasPermi('inventory:items:list')")
@GetMapping("/listLog")
public TableDataInfo listLog(OutboundOrderItems outboundOrderItems)
{
startPage();
OutboundOrderLog outboundOrderLog = new OutboundOrderLog();
outboundOrderLog.setOrderId(outboundOrderItems.getOrderId());
List<OutboundOrderLog> list = outboundOrderLogService.selectOutboundOrderLogList(outboundOrderLog);
return getDataTable(list);
}
/**
* 查询出库单明细列表
*/
@PreAuthorize("@ss.hasPermi('inventory:items:list')")
@GetMapping("/getStatistics")
public TableDataInfo getStatistics(OutboundOrdersSummaryVO outboundOrderItems)
{
......@@ -146,4 +164,5 @@ public class OutboundOrderItemsController extends BaseController
return toAjax(outboundOrderItemsService.deleteOutboundOrderItemsByIds(ids));
}
}
......@@ -4,6 +4,7 @@ import java.util.List;
import java.util.Map;
import com.ruoyi.common.core.domain.entity.Materials;
import com.ruoyi.inventory.domain.OutboundOrderItems;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Mapper;
......@@ -41,6 +42,14 @@ public interface MaterialsMapper
public List<Materials> selectMaterialsList(Materials materials);
/**
* 查询物料列表
*
* @param materials 物料
* @return 物料集合
*/
public List<Materials> selectMaterialsInventoryList(Materials materials);
/**
* 新增物料
*
* @param materials 物料
......@@ -104,4 +113,6 @@ public interface MaterialsMapper
*/
@MapKey("sap_no")
public Map<String,Map<String,String>> selectMaterialIdAndSapMap();
}
package com.ruoyi.inventory.service;
import com.ruoyi.common.core.domain.entity.Materials;
import com.ruoyi.inventory.domain.OutboundOrderItems;
import java.util.List;
import java.util.Map;
......@@ -30,6 +31,13 @@ public interface IMaterialsService
public List<Materials> selectMaterialsList(Materials materials);
/**
* 查询物料列表
*
* @param materials 物料
* @return 物料集合
*/
public List<Materials> ListMaterialsInventory(Materials materials);
/**
* 新增物料
*
* @param materials 物料
......
......@@ -55,6 +55,7 @@ public class InventoryServiceImpl implements IInventoryService
return inventoryMapper.selectInventoryById(id);
}
/**
* 查询库存列表
*
......
......@@ -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.OutboundOrderItems;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.inventory.mapper.MaterialsMapper;
......@@ -51,6 +52,11 @@ public class MaterialsServiceImpl implements IMaterialsService
return materialsMapper.selectMaterialsList(materials);
}
@Override
public List<Materials> ListMaterialsInventory(Materials materials) {
return materialsMapper.selectMaterialsInventoryList(materials);
}
/**
* 新增物料
*
......
......@@ -34,6 +34,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="createUserCode" column="create_user_code" />
<result property="updateTime" column="update_time" />
<result property="updateUserCode" column="update_user_code" />
<result property="stock" column="stock" />
</resultMap>
<sql id="selectMaterialsVo">
......@@ -73,6 +74,73 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by sort_no asc
</select>
<select id="selectMaterialsInventoryList" parameterType="Materials" resultMap="MaterialsResult">
select
m.id,
m.material_code,
m.material_name,
m.material_ename,
m.sap_no,
m.ts_code,
m.category_code,
m.hazard_id,
m.specification,
m.material_unit,
m.unit_weight,
m.package_weight,
m.total_weight,
m.volume,
m.shelf_life_days,
m.storage_temperature,
m.special_requirements,
m.is_batch_managed,
m.is_serial_managed,
m.min_stock_level,
m.max_stock_level,
IFNULL(i.quantity-locked_quantity, 0) as stock, -- 无库存时默认显示0
m.is_used,
m.is_active,
m.risk_level,
m.sort_no,
m.create_time,
m.create_user_code,
m.update_time,
m.update_user_code
from materials m
left join inventory i on m.id = i.material_id
<where>
m.is_used = 1
<if test="materialCode != null and materialCode != ''"> and m.material_code like concat('%', #{materialCode}, '%')</if>
<if test="materialName != null and materialName != ''"> and m.material_name like concat('%', #{materialName}, '%')</if>
<if test="sapNo != null and sapNo != ''"> and m.sap_no like concat('%', #{sapNo}, '%')</if>
<if test="tsCode != null and tsCode != ''"> and m.ts_code like concat('%', #{tsCode}, '%')</if>
<if test="categoryCode != null and categoryCode != ''"> and m.category_code = #{categoryCode}</if>
<if test="hazardId != null and hazardId != ''"> and m.hazard_id like concat('%', #{hazardId}, '%')</if>
<if test="specification != null and specification != ''"> and m.specification like concat('%', #{specification}, '%')</if>
<if test="materialUnit != null and materialUnit != ''"> and m.material_unit like concat('%', #{materialUnit}, '%')</if>
<if test="unitWeight != null "> and m.unit_weight = #{unitWeight}</if>
<if test="packageWeight != null "> and m.package_weight = #{packageWeight}</if>
<if test="totalWeight != null "> and m.total_weight = #{totalWeight}</if>
<if test="volume != null "> and m.volume = #{volume}</if>
<if test="shelfLifeDays != null "> and m.shelf_life_days = #{shelfLifeDays}</if>
<if test="storageTemperature != null and storageTemperature != ''"> and m.storage_temperature like concat('%', #{storageTemperature}, '%')</if>
<if test="specialRequirements != null and specialRequirements != ''"> and m.special_requirements like concat('%', #{specialRequirements}, '%')</if>
<if test="isBatchManaged != null "> and m.is_batch_managed = #{isBatchManaged}</if>
<if test="isSerialManaged != null "> and m.is_serial_managed = #{isSerialManaged}</if>
<if test="minStockLevel != null "> and m.min_stock_level = #{minStockLevel}</if>
<if test="maxStockLevel != null "> and m.max_stock_level = #{maxStockLevel}</if>
<if test="isUsed != null "> and m.is_used = #{isUsed}</if>
<if test="isActive != null "> and m.is_active = #{isActive}</if>
<if test="riskLevel != null and riskLevel != ''"> and m.risk_level like concat('%', #{riskLevel}, '%')</if>
<if test="sortNo != null "> and m.sort_no = #{sortNo}</if>
<if test="createTime != null "> and m.create_time like concat('%', #{createTime}, '%')</if>
<if test="updateTime != null "> and m.update_time like concat('%', #{updateTime}, '%')</if>
-- 可选:添加库存数量的查询条件(如果需要)
<if test="stock != null "> and i.stock = #{stock}</if>
</where>
order by stock desc
</select>
<select id="selectMaterialsById" parameterType="String" resultMap="MaterialsResult">
<include refid="selectMaterialsVo"/>
where id = #{id}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论