Files
JY1.0/src/views/WarehouseManagement/InventoryQuery/index.vue

730 lines
29 KiB
Vue

<template>
<div class="app-container">
<el-card style="height: 850px;padding: 0 0 0 10px">
<div style="margin-top: 7px; margin-bottom: 7px">
<el-input
v-model="materialCodeValue"
style="width:200px"
placeholder="物料编码"
size="small"
clearable
@keyup.enter.native="pageCurrent=1;searchTable()"/>
<el-input
v-model="materialNameTypeValue"
style="width:200px"
placeholder="物料名称"
size="small"
clearable
@keyup.enter.native="pageCurrent=1;searchTable()"/>
<el-input
v-model="materialTypeValue"
style="width:200px"
placeholder="图号型号"
size="small"
clearable
@keyup.enter.native="pageCurrent=1;searchTable()"/>
<el-select
v-model="materialType"
style="width:200px;"
placeholder="类型"
size="small"
filterable
clearable
@change="searchTable()">
<el-option
v-for="item in typeArray"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
<el-input
v-model="locationWarehouseValue"
style="width:200px"
placeholder="库位"
size="small"
clearable
@keyup.enter.native="pageCurrent=1;searchTable()"/>
<el-button
type="primary"
plain
icon="el-icon-search"
size="small"
style="margin-left: 15px"
@click="pageCurrent=1;searchTable()">查询
</el-button>
<el-button type="success" plain icon="el-icon-search" size="small" style="margin-left: 15px" @click="upDate()">
更新
</el-button>
<el-button
v-show="Number(token)===7 || Number(token)===8 || Number(token)===2 || Number(token)===21"
type="success"
plain
icon="el-icon-download"
size="small"
@click="exportExcel()">导出
</el-button>
</div>
<div style="margin-top: 10px">
<el-table
v-loading="loading"
ref="table1"
:data="tableData1"
:reserve-selection="true"
:row-key="row => row.物料流水号"
highlight-current-row
show-summary
border
size="small"
style="width:1622px"
height="740px"
@cell-click="handleEdit"
@sort-change="sortChange"
@selection-change="handleSelectionChange">
<el-table-column :reserve-selection="true" type="selection" width="40" />
<el-table-column type="expand" width="1">
<template slot-scope="scope">
<el-table
v-loading="loading"
ref="table"
:data="tableData9"
highlight-current-row
border
stripe
style="width:962px"
height="258px"
size="small">
<el-table-column label="物料编码" align="center" prop="物料码"><!-- 备注:修改人:Ld 修改时间:2026-07-15 17:14:07; 展开行恢复原出入库记录数据。 -->
<template slot-scope="scope">
{{ scope.row.物料编码 }}
</template>
</el-table-column>
<el-table-column width="170px" label="物料名称" align="center" prop="物料名称" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.物料名称 }}
</template>
</el-table-column>
<el-table-column width="150px" label="图号/型号" align="center" prop="图号" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.图号或型号 }}
</template>
</el-table-column>
<el-table-column width="100px" label="类型" align="center">
<template slot-scope="scope">
{{ scope.row.类型 }}
</template>
</el-table-column>
<el-table-column width="100px" label="/入库数" align="center" prop="数量">
<template slot-scope="scope">
{{ scope.row.数量 }}
</template>
</el-table-column>
<el-table-column width="150px" label="/入库日期" align="center">
<template slot-scope="scope">
{{ scope.row.日期 }}
</template>
</el-table-column>
<el-table-column width="150px" label="批次编码" align="center">
<template slot-scope="scope">
{{ scope.row.批次编号 || scope.row.批次编码 }}
</template>
</el-table-column>
</el-table>
<div class="block" style="margin-top: 10px;">
<el-pagination
:current-page="pageCurrent1"
:page-sizes="[5, 10, 20, 30, 40, 100]"
:page-size="pageSize1"
:total="total1"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChanges1"
@current-change="handleCurrentChanges1"/>
</div>
</template>
</el-table-column>
<el-table-column
width="140px"
label="物料编码"
align="center"
show-overflow-tooltip
sortable="物料编码"
prop="物料编码">
<template slot-scope="scope">
{{ scope.row.物料编码 }}
</template>
</el-table-column>
<el-table-column
width="170px"
label="物料名称"
align="center"
show-overflow-tooltip
sortable="物料名称"
prop="物料名称">
<template slot-scope="scope">
{{ scope.row.物料名称 }}
</template>
</el-table-column>
<el-table-column width="150px" label="图号型号" align="center">
<template slot-scope="scope">
{{ scope.row.图号或型号 }}
</template>
</el-table-column>
<el-table-column :width="setColumnWidth('数量')" label="库存" sortable="库存" prop="库存" align="center">
<template slot-scope="scope">
<el-popover
placement="bottom"
width="300"
trigger="click"
@show="getStockLocationDetail(scope.row)">
<el-table v-loading="stockLocationLoading" :data="stockLocationData" border stripe size="mini" max-height="300">
<el-table-column prop="货位名称" label="库位" align="center" show-overflow-tooltip/>
<el-table-column prop="货位存量" label="数量" align="center">
<template slot-scope="stockScope">
{{ stockScope.row.货位存量 || stockScope.row.库存 || 0 }}
</template>
</el-table-column>
</el-table>
<span slot="reference" style="cursor: pointer; color: #409EFF; text-decoration: underline;">{{ scope.row.库存 }}</span><!-- 备注:修改人:Ld 修改时间:2026-07-15 17:14:07; 库存库位明细改为参考需求数的小窗显示。 -->
</el-popover>
</template>
</el-table-column>
<el-table-column :width="setColumnWidth('数量')" label="需求数" align="center">
<template slot-scope="scope">
<el-popover
placement="bottom"
width="400"
trigger="click"
@show="getDemandDetail(scope.row)">
<el-table v-loading="demandDetailLoading" :data="demandDetailData" border stripe size="mini" max-height="300">
<el-table-column prop="订单编号" label="订单号" align="center" show-overflow-tooltip/>
<el-table-column prop="最终需求量" label="需求量" align="center"/>
<el-table-column prop="简称" label="客户" align="center"/>
</el-table>
<span slot="reference" style="cursor: pointer; color: #409EFF; text-decoration: underline;">{{ scope.row.需求量 }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column :width="setColumnWidth('数量')" label="可用库存" align="center">
<template slot-scope="scope">
{{ scope.row.库存 - scope.row.需求量 }}
</template>
</el-table-column>
<el-table-column :width="setColumnWidth('数量')" label="加工中" align="center">
<template slot-scope="scope">
<!--{{ scope.row.加工中 }}-->
<span v-text="scope.row.加工中 < 0 ? 0 : scope.row.加工中"/>
</template>
</el-table-column>
<el-table-column :width="setColumnWidth('数量')" label="采购中" align="center">
<template slot-scope="scope">
{{ scope.row.采购中 }}
</template>
</el-table-column>
<el-table-column :width="setColumnWidth('数量')" label="毛坯数" align="center">
<template slot-scope="scope">
{{ scope.row.毛坯库存 }}
</template>
</el-table-column>
<el-table-column v-if="Number(token) === 2" :width="setColumnWidth('数量')" label="毛坯补货" align="center">
<template slot-scope="scope">
{{ scope.row.补货毛坯 }}
</template>
</el-table-column>
<el-table-column v-if="Number(token) === 2" :width="setColumnWidth('数量')" label="补货中" align="center">
<template slot-scope="scope">
{{ scope.row.补货中 }}
</template>
</el-table-column>
<el-table-column :width="setColumnWidth('单位')" label="单位" align="center">
<template slot-scope="scope">
{{ scope.row.单位 }}
</template>
</el-table-column>
<el-table-column :width="setColumnWidth('单位')" label="类型" align="center">
<template slot-scope="scope">
{{ scope.row.类型 }}
</template>
</el-table-column>
<el-table-column :width="setColumnWidth('数量')" label="库存批次" align="center">
<template slot-scope="scope">
{{ scope.row.批次 }}
</template>
</el-table-column>
<el-table-column :width="setColumnWidth('数量')" label="待入库" prop="预库存" align="center">
<template slot-scope="scope">
{{ scope.row.预库存 }}
</template>
</el-table-column>
<el-table-column
v-if="Number(token)===7 || Number(token)===8 || Number(token)===2"
width="120px"
label="最低库存"
align="center"
sortable="最低库存"
prop="最低库存">
<template slot-scope="scope">
{{ scope.row.最低库存 }}
</template>
</el-table-column>
<el-table-column
v-if="Number(token)===7 || Number(token)===8 || Number(token)===2"
width="120px"
label="安全库存"
align="center"
sortable="安全库存"
prop="安全库存">
<template slot-scope="scope">
{{ scope.row.安全库存 }}
</template>
</el-table-column>
<el-table-column
v-if="Number(token)===7 || Number(token)===8 || Number(token)===2"
width="120px"
label="最高库存"
align="center"
sortable="最高库存"
prop="最高库存">
<template slot-scope="scope">
{{ scope.row.最高库存 }}
</template>
</el-table-column>
<el-table-column
v-if="Number(token)===7 || Number(token)===8 || Number(token)===2"
width="180px"
label="操作"
align="center"
fixed="right">
<template slot-scope="scope">
<!-- <el-button
type="text"
icon="el-icon-edit"
size="mini"
style="margin-right: 10px"
@click="openStock(scope.row)">最低库存
</el-button> -->
<el-popover placement="right" width="500" trigger="click">
<el-table
:data="gridData"
:header-cell-style="{background: '#19466E',color: 'white'}"
border
highlight-current-row
size="mini"
show-summary>
<el-table-column width="50" align="center" type="index" label="批次"/>
<el-table-column min-width="100" align="center" label="批次编号">
<template slot-scope="scope">
{{ scope.row.批次编号 }}
</template>
</el-table-column>
<el-table-column min-width="100" align="center" label="批次库存" prop="货位存量">
<template slot-scope="scope">
{{ scope.row.货位存量 }}
</template>
</el-table-column>
<el-table-column width="120px" label="供应商" align="center">
<template slot-scope="scope">
{{ scope.row.供应商 }}
</template>
</el-table-column>
</el-table>
<el-button
slot="reference"
type="text"
icon="el-icon-search"
size="mini"
@click="showDelivery(scope.row)">批次
</el-button>
</el-popover>
</template>
</el-table-column>
</el-table>
<div class="block" style="margin-top: 10px;">
<el-pagination
:current-page="pageCurrent"
:page-sizes="[10, 20, 30, 40, 100]"
:page-size="pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChanges"
@current-change="handleCurrentChanges"/>
</div>
</div>
</el-card>
<el-dialog v-el-drag-dialog :visible.sync="dialogFormVisible" title="最低库存" center width="300px">
<el-form ref="form" :model="form">
<el-form-item prop="最低库存">
<el-input-number
v-model="form.最低库存"
:min="0"
:step="1"
size="small"
clearable
style="width:200px;margin-left: 25px"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="callOff()">取 消</el-button>
<el-button type="primary" @click="submitStock()">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import XLSX from 'xlsx'
import FileSaver from 'file-saver'
export default {
data() {
return {
materialSerialNumber: '',
locationWarehouseValue: '', // 库位
gridData: [],
materialCodeValue: '',
materialNameTypeValue: '',
materialTypeValue: '',
materialType: '',
typeValue: '', // 类型
typeNameValue: '',
typeArray: [{
value: '采购件',
label: '采购件'
}, {
value: '自制件',
label: '自制件'
}],
stockValue: '', // 累计库存流水号
minimumStock: '', // 最低库存
loading: false, // 数据加载
loading1: false, // 数据加载
dialogFormVisible: false,
form: {
最低库存: ''
},
total: 0, // 分页总数
total1: 0, // 分页总数
tableData1: [], // 合同信息表
tableData9: [],
pageCurrent: 1, // 分页当前页
pageSize: 30, // 分页每页显示条数
pageCurrent1: 1, // 分页当前页
pageSize1: 30, // 分页每页显示条数
orderName: '', // 排序列名
order: '', // 排序方式
multipleSelection: [], // 选中的行
demandDetailData: [],
demandDetailLoading: false,
stockLocationData: [],
stockLocationLoading: false
}
},
computed: {
...mapGetters([
'id',
'token'
])
},
watch: {
'$route': {
handler(route) {
this.typeNameValue = this.$route.query.类型
console.log(this.typeNameValue, this.$route.query.类型)
this.searchTable()
},
immediate: true
}
},
updated() {
this.$nextTick(() => {
this.$refs['table1'].doLayout()
})
},
created() {
this.searchTable()
},
methods: {
upDate() {
var param = []
var Data = this.CreateData('12', '物料管理_补货中更新', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('更新成功')
} else {
this.$message.error('更新失败')
}
})
},
getDemandDetail(row) {
this.demandDetailLoading = true
this.demandDetailData = []
var param = []
param[0] = ['物料流水号', row.物料流水号]
var Data = this.CreateData('11', '仓储管理_报缺补货_需求量明细_查询', param)
this.ExecDatabase(Data).then(response => {
this.demandDetailData = response.data.filter(item => item.最终需求量 !== 0)
this.demandDetailLoading = false
}).catch(() => {
this.demandDetailLoading = false
})
},
handleSizeChanges1(val) {
this.pageCurrent1 = 1
this.pageSize1 = val
this.searchTable2()
},
handleCurrentChanges1(val) {
this.pageCurrent1 = val
this.searchTable2()
},
getInventoryLocationRows(row) {
var param = []
var materialCode_check = row.物料编码 ? 1 : 0
param[0] = ['物料名称_check', 0]
param[1] = ['物料名称', '']
param[2] = ['图号或型号_check', 0]
param[3] = ['图号或型号', '']
param[4] = ['库位_check', 0]
param[5] = ['库位', '']
param[6] = ['排序名称', '']
param[7] = ['排序方式', '']
param[8] = ['物料编码_check', materialCode_check]
param[9] = ['物料编码', row.物料编码 || '']
var Data = this.CreateData('11', '仓储管理_库存盘点_查询', param)
return this.ExecDatabase(Data).then(response => {
var rows = response.data.rows || response.data || []
var locationMap = {}
// 备注:修改人:Ld 修改时间:2026-07-17 17:23:23; 库存小窗按物料编码精确过滤并按库位汇总,避免同名称或相似图号物料混入。
rows.filter(function(item) {
return (!row.物料编码 || item.物料编码 === row.物料编码) && Number(item.货位存量 || item.库存 || 0) > 0
}).forEach(function(item) {
var locationName = item.货位名称 || ''
if (!locationMap[locationName]) {
locationMap[locationName] = {
货位名称: locationName,
货位存量: 0
}
}
locationMap[locationName].货位存量 = Number(locationMap[locationName].货位存量) + Number(item.货位存量 || item.库存 || 0)
})
return Object.keys(locationMap).map(function(key) {
return locationMap[key]
})
})
},
getStockLocationDetail(row) {
this.stockLocationLoading = true
this.stockLocationData = []
this.getInventoryLocationRows(row).then(rows => {
this.stockLocationData = rows
this.stockLocationLoading = false
}).catch(() => {
this.stockLocationLoading = false
})
},
searchTable2() {
var param = []
param[0] = ['物料流水号', this.materialSerialNumber]
var Data = this.CreateData('11', '库存查询_物料出入库记录_查询', param, this.pageSize1, this.pageCurrent1)
this.ExecDatabase(Data).then(response => {
this.tableData9 = response.data.rows
this.total1 = response.data.total
})
},
handleEdit(row, column) {
if (column.label === '物料编码') { // 备注:修改人:Ld 修改时间:2026-07-15 17:14:07; 展开行继续使用原物料出入库记录。
this.materialSerialNumber = row.物料流水号
this.tableData9 = []
this.searchTable2()
const $table = this.$refs.table1
this.tableData1.map(item => {
if (row.物料流水号 !== item.物料流水号) {
$table.toggleRowExpansion(item, false)
}
})
$table.toggleRowExpansion(row)
}
},
searchTable() {
let materialCodeValue_check, materialNameTypeValue_check, locationWarehouseValue_check, materialTypeValue_check, materialType_check
this.materialCodeValue ? materialCodeValue_check = 1 : materialCodeValue_check = 0
this.materialNameTypeValue ? materialNameTypeValue_check = 1 : materialNameTypeValue_check = 0
this.materialTypeValue ? materialTypeValue_check = 1 : materialTypeValue_check = 0
this.materialType ? materialType_check = 1 : materialType_check = 0
this.locationWarehouseValue ? locationWarehouseValue_check = 1 : locationWarehouseValue_check = 0
var param = []
param[0] = ['物料名称_check', materialNameTypeValue_check]
param[1] = ['物料名称', this.materialNameTypeValue]
param[2] = ['图号_check', materialTypeValue_check]
param[3] = ['图号', this.materialTypeValue]
param[4] = ['库位_check', locationWarehouseValue_check]
param[5] = ['库位', this.locationWarehouseValue]
param[6] = ['排序名称', this.orderName]
param[7] = ['排序方式', this.order]
param[8] = ['类型_check', materialType_check]
param[9] = ['类型', this.materialType]
param[10] = ['物料编码_check', materialCodeValue_check]
param[11] = ['物料编码', this.materialCodeValue]
var Data = this.CreateData('11', '仓储管理_库存查询_查询', param, this.pageSize, this.pageCurrent)
this.ExecDatabase(Data).then(response => {
this.tableData1 = response.data.rows
this.total = response.data.total
})
},
handleSelectionChange(val) {
this.multipleSelection = val
},
exportExcel() {
if (this.tableData1.length === 0) {
this.$message.warning('暂无数据')
return
}
if (this.multipleSelection.length > 0) {
this.exportSelected()
} else {
this.exportAll()
}
},
exportAll() {
let materialCodeValue_check, materialNameTypeValue_check, locationWarehouseValue_check
this.materialCodeValue ? materialCodeValue_check = 1 : materialCodeValue_check = 0
this.materialNameTypeValue ? materialNameTypeValue_check = 1 : materialNameTypeValue_check = 0
this.locationWarehouseValue ? locationWarehouseValue_check = 1 : locationWarehouseValue_check = 0
var param = []
param[0] = ['物料名称_check', materialNameTypeValue_check]
param[1] = ['物料名称', this.materialNameTypeValue]
param[2] = ['库位_check', locationWarehouseValue_check]
param[3] = ['库位', this.locationWarehouseValue]
param[4] = ['排序名称', this.orderName]
param[5] = ['排序方式', this.order]
param[6] = ['物料编码_check', materialCodeValue_check]
param[7] = ['物料编码', this.materialCodeValue]
var Data = this.CreateData('2001', '报表_仓储管理_通用库存_查询', param)
this.exportExcel_NPOI(Data)
},
exportSelected() {
var loadingInstance = this.$loading({ text: '正在导出,请稍候...' })
var promises = this.multipleSelection.map(function(row) {
var param = []
param[0] = ['物料流水号', row.物料流水号]
var Data = this.CreateData('11', '库存查询_物料出入库记录_查询', param, 10000, 1)
return this.ExecDatabase(Data).then(function(response) {
return { row: row, expandData: response.data.rows || [] }
})
}.bind(this))
Promise.all(promises).then(function(results) {
var data = []
// 表头
data.push(['物料编码', '物料名称', '图号型号', '库存', '需求数', '可用库存', '加工中', '采购中', '毛坯数', '单位', '类型', '库存批次', '待入库', '最低库存', '安全库存', '最高库存', '', '物料编码', '物料名称', '图号/型号', '类型', '出/入库数', '出/入库日期', '批次编码']) // 备注:修改人:Ld 修改时间:2026-07-15 17:14:07; 选中导出恢复原展开出入库记录明细。
results.forEach(function(item) {
var row = item.row
var mainRow = [
row.物料编码, row.物料名称, row.图号或型号, row.库存,
row.需求量, row.库存 - row.需求量, row.加工中 < 0 ? 0 : row.加工中,
row.采购中, row.毛坯库存, row.单位, row.类型, row.批次, row.预库存,
row.最低库存, row.安全库存, row.最高库存, ''
]
if (item.expandData.length > 0) {
item.expandData.forEach(function(expand, idx) {
if (idx === 0) {
data.push(mainRow.concat([expand.物料编码, expand.物料名称, expand.图号或型号, expand.类型, expand.数量, expand.日期, expand.批次编号 || expand.批次编码]))
} else {
data.push(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', expand.物料编码, expand.物料名称, expand.图号或型号, expand.类型, expand.数量, expand.日期, expand.批次编号 || expand.批次编码])
}
})
} else {
data.push(mainRow)
}
})
var ws = XLSX.utils.aoa_to_sheet(data)
ws['!cols'] = [
{ wch: 15 }, { wch: 20 }, { wch: 15 }, { wch: 8 }, { wch: 8 },
{ wch: 10 }, { wch: 8 }, { wch: 8 }, { wch: 8 }, { wch: 6 },
{ wch: 8 }, { wch: 12 }, { wch: 8 }, { wch: 10 }, { wch: 10 },
{ wch: 10 }, { wch: 2 }, { wch: 15 }, { wch: 20 }, { wch: 15 },
{ wch: 8 }, { wch: 10 }, { wch: 15 }, { wch: 15 }
]
var wb = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(wb, ws, '库存查询')
var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'array' })
FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), '库存查询.xlsx')
loadingInstance.close()
this.$message.success('导出成功')
}.bind(this)).catch(function() {
loadingInstance.close()
this.$message.error('导出失败')
}.bind(this))
},
sortChange(column) {
if (column.prop === '物料编码') {
this.orderName = 1
} else if (column.prop === '物料名称') {
this.orderName = 2
} else if (column.prop === '库存') {
this.orderName = 4
} else if (column.prop === '最低库存') {
this.orderName = 5
}
if (column.order === 'ascending') {
this.order = 1
} else if (column.order === 'descending') {
this.order = 2
} else {
this.order = ''
}
this.searchTable()
},
openStock(row) {
this.typeValue = row.类型流水号
this.stockValue = row.累计库存流水号
this.form.最低库存 = Number(row.最低库存)
this.dialogFormVisible = true
},
callOff() {
this.dialogFormVisible = false
},
showDelivery(row) {
var param = []
param[0] = ['物料流水号', row.物料流水号]
var Data = this.CreateData('11', '装配管理_领料单明细_批次查询', param)
this.ExecDatabase(Data).then(response => {
this.gridData = response.data
})
},
submitStock() {
if (this.form.最低库存 !== '' && this.form.最低库存 !== undefined) {
var param = []
param[0] = ['累计库存流水号', this.stockValue]
param[1] = ['类型流水号', this.typeValue]
param[2] = ['最低库存', this.form.最低库存]
var Data = this.CreateData('12', '最低库存_编辑数据', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.searchTable()
this.dialogFormVisible = false
this.$message.success('编辑成功')
} else {
this.$message.error('编辑失败')
}
})
} else {
this.$message.warning('不能为空')
}
},
handleSizeChanges(val) {
this.pageCurrent = 1
this.pageSize = val
this.searchTable()
},
handleCurrentChanges(val) {
this.pageCurrent = val
this.searchTable()
}
}
}
</script>
<style scoped lang="scss">
/deep/ .el-card__body {
padding: 0px !important;
}
</style>