fengshang_yangzhou/dev_wms_client/src/layout/stock.vue
2025-09-25 13:11:33 +08:00

597 lines
26 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-config-provider :locale="zhCn">
<el-container class="content">
<div class="work-area">
<fieldset class="search-area">
<el-form ref="stockQueryFormRef" :model="stockQuery" :label-position="labelPosition"
label-width="auto" style="max-width: 100%" status-icon>
<div style="display: flex;justify-content: space-between;">
<el-row>
<el-form-item label="箱号">
<el-input v-model="stockQuery.vehicleId" @keyup.enter="search()" clearable />
</el-form-item>
<el-form-item label="料号">
<el-input v-model="stockQuery.goodsId" @keyup.enter="search()" clearable />
<!-- <el-autocomplete v-model="stockQuery.goodsId" :fetch-suggestions="filterGoodsId"
popper-class="my-autocomplete" placeholder="料号" @select="handleSelectGoodsId"
style="width: 196px;">
<template #default="{ item }">
<div>
料号:<span class="goods_id">{{ item.goodsId }}</span>
名称:<span class="goods_name">{{ item.goodsDesc }}</span>
</div>
</template>
</el-autocomplete> -->
</el-form-item>
<el-form-item label="库位">
<el-input v-model="stockQuery.locationId" @keyup.enter="search()" clearable />
</el-form-item>
<el-form-item label="库存状态">
<el-select-v2 style="width: 196px" v-model="stockQuery.stockStatus" placeholder="库存状态"
:options="addAllOptionOfOptions(stockStatusOptions)"
@change="search()"></el-select-v2>
</el-form-item>
<el-form-item label="物料状态">
<el-select-v2 style="width: 196px" v-model="stockQuery.goodsStatus" placeholder="物料状态"
:options="addAllOptionOfOptions(goodsStatusOptions)"
@change="search()"></el-select-v2>
</el-form-item>
<el-form-item label="起始日期">
<el-date-picker v-model="stockQuery.fromDate" type="date" placeholder="起始日期"
:shortcuts="shortcuts" style="width: 196px;" clearable />
</el-form-item>
<el-form-item label="结束日期">
<el-date-picker v-model="stockQuery.toDate" type="date" placeholder="结束日期"
:shortcuts="shortcuts" style="width: 196px;" clearable />
</el-form-item>
</el-row>
<div style="align-content: center;">
<el-row>
<el-button type="primary"
style="height: 30px; width: 80px; margin: auto 5px 5px auto; color: black;"
@click="search()">查询库存</el-button>
<el-button type="warning"
style="height: 30px; width: 80px; margin: auto 5px 5px auto; color: black;"
@click="clearQuery()">清除输入</el-button>
</el-row>
<el-row>
<el-button type="success"
style="height: 30px; width: 80px; margin: auto 5px 5px auto; color: black;"
@click="exportExcel()">导出excel</el-button>
</el-row>
</div>
</div>
</el-form>
</fieldset>
<div class="table-area">
<el-table :data="displayStocks" stripe border v-loading="tableLoading" class="table-class"
:max-height="maxHeight" highlight-current-row @row-click="getCurrentRow" :row-style="rowStyle"
:header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }"
@sort-change="handleSortChange">
<el-table-column width="65px" fixed="left">
<template v-slot="scope">
<el-radio :label="scope.row.stockId" v-model="stockId">&nbsp;</el-radio>
</template>
</el-table-column>
<!-- <el-table-column prop="stockId" label="库存编号" fixed="left" min-width="120px" sortable="custom"-->
<!-- show-overflow-tooltip />-->
<el-table-column prop="vehicleId" label="箱号" fixed="left" min-width="120px" sortable="custom"
show-overflow-tooltip />
<el-table-column prop="goodsId" label="物料号" fixed="left" min-width="120px" sortable="custom"
show-overflow-tooltip />
<el-table-column prop="specialStock" label="特殊库存" min-width="120px" sortable="custom"
show-overflow-tooltip />
<el-table-column prop="specialStockNo" label="特殊库存号" min-width="120px" sortable="custom"
show-overflow-tooltip />
<el-table-column prop="specialStockItemNo" label="特殊库存item号" min-width="120px" sortable="custom"
show-overflow-tooltip />
<el-table-column prop="batchNo" label="批次号" min-width="120px" sortable="custom"
show-overflow-tooltip />
<el-table-column prop="goodsDesc" label="物料名称" min-width="120px" sortable="custom" show-overflow-tooltip />
<el-table-column prop="locationId" label="库位" :formatter="locationFormat" min-width="120px"
sortable="custom" show-overflow-tooltip />
<el-table-column prop="totalNum" label="入库数量" sortable="custom" min-width="120px" show-overflow-tooltip />
<el-table-column prop="remainNum" label="剩余可用数量" sortable="custom" min-width="120px" show-overflow-tooltip />
<el-table-column prop="realNum" label="实际剩余数量" sortable="custom" min-width="120px" show-overflow-tooltip />
<el-table-column prop="goodsStatus" label="物料状态" :formatter="goodsStatusFormat"
min-width="120px" sortable="custom" show-overflow-tooltip />
<el-table-column prop="stockStatus" label="库存状态" :formatter="stockStatusFormat" fixed="right"
min-width="120px" sortable="custom" show-overflow-tooltip />
<el-table-column prop="firstInTime" label="上架时间" sortable="custom" :formatter="timeFormat"
min-width="120px" show-overflow-tooltip />
<el-table-column prop="firstInUser" label="上架用户" min-width="120px" sortable="custom" show-overflow-tooltip />
<el-table-column prop="lastUpdateTime" label="最近更新时间" sortable="custom" :formatter="timeFormat"
min-width="140px" show-overflow-tooltip />
<el-table-column prop="lastUpdateUser" label="最近更新用户" min-width="120px" show-overflow-tooltip />
<!-- <el-table-column fixed="right" label="操作" width="120px">
<template v-slot="scope">
<el-button plain type="primary" @click="editCurrentRowStock(scope.row)">编辑</el-button>
</template>
</el-table-column> -->
</el-table>
<br />
<el-pagination v-model:current-page="baseTableQuery.currentPage"
v-model:page-size="baseTableQuery.pageSize" :page-sizes="[10, 25, 50]" :small="false"
:disabled="false" :background="false" :default-page-size="10" @size-change="search"
@current-change="search" layout="total, sizes, prev, pager, next, jumper"
:total="baseTableQuery.total" />
</div>
<!-- <el-dialog v-model="dialogVisible" title="库存信息" width="40%" draggable :show-close="false">
<el-form ref="stockFormRef" :model="stockFormEntity" :label-position="labelPosition"
label-width="100px" style="max-width: 100%" :rules="rules" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="库存编号" prop="stockId">
<el-input v-model="stockFormEntity.stockId" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="箱号" prop="vehicleId">
<el-input v-model="stockFormEntity.vehicleId" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="料号" prop="goodsId">
<el-input v-model="stockFormEntity.goodsId" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="料名" prop="goodsName">
<el-input v-model="stockFormEntity.goodsName" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="入库数量" prop="totalNum">
<el-input-number v-model.number="stockFormEntity.totalNum" controls-position="right"
:min="0" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="剩余数量为0时删除库存" prop="remainNum">
<el-input-number v-model.number="stockFormEntity.remainNum"
controls-position="right" :min="0" :max="stockFormEntity.totalNum" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="库位" prop="locationId">
<el-input v-model="stockFormEntity.locationId" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="未使用天数" prop="noUseDays">
<el-input-number v-model.number="stockFormEntity.noUseDays"
controls-position="right" :min="0" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="库存状态" prop="stockStatus">
<el-select-v2 v-model="stockFormEntity.stockStatus" placeholder="请选择库存状态"
:options="stockStatusOptions"></el-select-v2>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料状态" prop="goodsStatus">
<el-select-v2 v-model="stockFormEntity.goodsStatus" placeholder="请选择物料状态"
:options="goodsStatusOptions"></el-select-v2>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="盘点任务号" prop="inventoryTaskId">
<el-input v-model="stockFormEntity.inventoryTaskId" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否盘点" prop="isInventory">
<el-input v-model="stockFormEntity.isInventory" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="创建时间" prop="createTime">
<el-input v-model="stockFormEntity.createTime" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="最近更新时间" prop="lastUpdateTime">
<el-input v-model="stockFormEntity.lastUpdateTime" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="最近更新用户" prop="lastUpdateUser">
<el-input v-model="stockFormEntity.lastUpdateUser" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitStockInfo(stockFormEntity)">
确定
</el-button>
</span>
</template>
</el-dialog> -->
</div>
</el-container>
</el-config-provider>
</template>
<script setup>
import store from '@/store'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { queryStocksByPage } from '@/api/stock.js'
import { exportStockExcel } from '@/api/excel.js'
import { dateFormatter, locationFormatter, timeFormatter, yesOrNoFormatter } from '@/utils/formatter.js'
import { ref, reactive, onMounted, nextTick, onBeforeUnmount } from 'vue'
import { ElMessage } from 'element-plus'
import { genTableRequest, addAllOptionOfOptions } from '@/utils/generator.js'
import { labelPosition, shortcuts } from '@/constant/form'
import { stockStatusOptions, goodsStatusOptions } from '@/constant/options'
/**
* 常量定义
*/
/**
* 变量定义
*/
let maxHeight = ref(window.innerHeight * 0.55)
let tableLoading = ref(false)
let displayStocks = ref([])
let baseTableQuery = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
sortBy: new Map([['firstInTime', true]]),
standId: store.getters.getStandId,
userName: store.getters.getUserName
})
let stockQuery = reactive({
vehicleId: '',
goodsId: '',
locationId: '',
stockStatus: -99,
goodsStatus: -99,
fromDate: null,
toDate: null
})
let stockQueryFormRef = ref()
let goodsIdList = ref([])
let showStockEditFlag = ref(false)
let stockId = ''
let stockFormRef = ref()
let stockFormEntity = reactive({})
/**
* 系统方法
*/
onMounted(() => {
nextTick(() => {
window.addEventListener('resize', resizeHeight)
search()
})
})
onBeforeUnmount(() => {
nextTick(() => {
window.removeEventListener('resize', resizeHeight)
})
})
const resizeHeight = () => {
maxHeight.value = window.innerHeight * 0.55
}
/**
* 自定义方法
*/
// 查询
const search = () => {
tableLoading.value = true
let request = genTableRequest(baseTableQuery)
// 设定查询参数
request.vehicleId = stockQuery.vehicleId.trim()
request.goodsId = stockQuery.goodsId.trim()
request.locationId = stockQuery.locationId.trim()
request.stockStatus = stockQuery.stockStatus === -99 ? null : stockQuery.stockStatus
request.goodsStatus = stockQuery.goodsStatus === -99 ? null : stockQuery.goodsStatus
request.fromDate = stockQuery.fromDate == null ? null : dateFormatter(stockQuery.fromDate)
request.toDate = stockQuery.toDate == null ? null : dateFormatter(stockQuery.toDate)
queryStocksByPage(request).then((res) => {
const response = res.data
if (response.code === 0) {
const data = response.data
console.log(data)
if (data != null) {
displayStocks.value = data.lists
baseTableQuery.total = data.total
} else {
displayStocks.value = []
baseTableQuery.total = 0
}
} else {
ElMessage.error(response.message)
}
}).catch(err => {
console.log(err)
ElMessage.error('查询库存信息异常。')
}).finally(() => {
tableLoading.value = false
})
}
const clearQuery = () => {
stockQuery.vehicleId = '',
stockQuery.goodsId = '',
stockQuery.locationId = '',
stockQuery.stockStatus = -99,
stockQuery.goodsStatus = -99,
stockQuery.fromDate = null,
stockQuery.toDate = null
}
const loadAllGoodsInfo = () => {
const request = {
userName: store.getters.getUserName
}
getGoodsInfoByGoodsId(request).then(res => {
const tableResponse = res.data
if (tableResponse.code == 0) {
this.goodsList = tableResponse.returnData
} else {
ElMessage.error(tableResponse.message)
}
}).catch(err => {
console.log(err)
ElMessage.error('查询物料信息异常。')
})
}
const filterGoodsId = (queryString, cb) => {
const results = queryString
? this.goodsList.filter(this.createFilter(queryString))
: this.goodsList
// call callback function to return suggestion objects
cb(results)
}
const createFilter = (queryString) => {
return (restaurant) => {
return (
restaurant.goodsId.toLowerCase().indexOf(queryString.toLowerCase()) != -1
)
}
}
const handleSelectGoodsId = (item) => {
this.goodsIdQuery = item.goodsId
}
const locationFormat = (row, column, cellValue, index) => {
return locationFormatter(cellValue)
}
const dateFormat = (row, column, cellValue, index) => {
return dateFormatter(cellValue)
}
const timeFormat = (row, column, cellValue, index) => {
return timeFormatter(cellValue)
}
const goodsStatusFormat = (row, column, cellValue, index) => {
if (cellValue === 0) {
return '正常'
} else if (cellValue === 1) {
return '不合格'
} else if (cellValue === 2) {
return '延期'
} else if (cellValue === 3) {
return '过期'
} else if (cellValue === 5) {
return '长时间未使用'
}
}
const stockStatusFormat = (row, column, cellValue, index) => {
switch (cellValue) {
case 0:
return '在库中'
case 1:
return '出库中'
case 2:
return '已出库'
case 3:
return '回库中'
case 4:
return '盘点中'
case 9:
return '库存锁定'
default:
return '异常'
}
}
const yesOrNoFormat = (row, column, cellValue, index) => {
return yesOrNoFormatter(cellValue)
}
const rowStyle = ({ row, rowIndex }) => {
if (row.goodsStatus == 3) {
return { "color": "red" }
}
if (row.goodsStatus == 5) {
return { "color": "yellow" }
}
}
const handleSortChange = (data) => {
if (baseTableQuery.sortBy.has(data.prop)) {
baseTableQuery.sortBy.delete(data.prop)
}
baseTableQuery.sortBy.set(data.prop, data.order == 'ascending')
search()
}
const getCurrentRow = (row) => {
stockId = row.stockId
}
const exportExcel = () => {
const params = {
vehicleId: stockQuery.vehicleId,
goodsId: stockQuery.goodsId,
locationId: stockQuery.locationId,
stockStatus: stockQuery.stockStatus == -99 ? null : stockQuery.stockStatus,
goodsStatus: stockQuery.goodsStatus == -99 ? null : stockQuery.goodsStatus,
fromDate: stockQuery.fromDate,
toDate: stockQuery.toDate
}
exportStockExcel(params).then(res => {
const link = document.createElement('a');//创建a标签
try {
// let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'}); //如果后台返回的不是blob对象类型先定义成blob对象格式该type导出为xls格式
let blob = res.data //如果后台返回的直接是blob对象类型直接获取数据
// let _fileName = res.headers['content-disposition'].split(';')[1].split('=')[1]; //拆解获取文件名,如果后端有给返回文件名的话
let _fileName = "库存报表" + dateFormatter(new Date) + ".xlsx"
link.style.display = 'none'//隐藏
// 兼容不同浏览器的URL对象
const url = window.URL || window.webkitURL || window.moxURL
link.href = url.createObjectURL(blob)
link.setAttribute('download', _fileName.substring(_fileName.lastIndexOf('_') + 1))
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
url.revokeObjectURL(link.href)//移除url对象
} catch (e) {
console.log(e)
ElMessage.error('下载文件失败')
}
}).catch(err => {
console.log(err)
ElMessage.error('导出失败')
})
}
const editCurrentRowStock = (row) => {
this.stockFormEntity = {
stockId: row.stockId,
locationId: row.locationId,
vehicleId: row.vehicleId,
stockStatus: row.stockStatus,
createTime: row.createTime,
lastUpdateTime: row.lastUpdateTime,
lastUpdateUser: row.lastUpdateUser,
isInventory: row.isInventory,
inventoryTaskId: row.inventoryTaskId,
noUseDays: row.noUseDays,
goodsId: row.goodsId,
goodsName: row.goodsName,
goodsStatus: row.goodsStatus,
remainNum: row.remainNum,
totalNum: row.totalNum
}
this.dialogVisible = true
}
const submitStockInfo = () => {
const request = {
stockId: this.stockFormEntity.stockId,
locationId: this.stockFormEntity.locationId,
vehicleId: this.stockFormEntity.vehicleId,
stockStatus: this.stockFormEntity.stockStatus,
goodsId: this.stockFormEntity.goodsId,
goodsStatus: this.stockFormEntity.goodsStatus,
remainNum: this.stockFormEntity.remainNum,
userName: store.getters.getUserName
}
updateStockInfo(request).then(res => {
if (res.data.code == 0) {
this.dialogVisible = false
ElMessage.success('更新库存成功')
this.search()
} else {
errorBox(res.data.message)
}
}).catch(err => {
console.log(err)
errorBox('更新库存失败')
})
}
</script>
<style scoped>
.content {
display: flex;
width: 100%;
}
.work-area {
width: 100%;
/* padding: 5px; */
}
.search-area {
margin: auto;
min-height: fit-content;
max-height: 40%;
margin-bottom: 10px;
min-width: inherit;
border: solid 1px;
border-radius: 10px;
box-shadow: 0px 15px 10px -15px #000;
overflow: auto;
padding: 10px;
}
.table-area {
margin: auto;
min-height: fit-content;
max-height: 60%;
margin-bottom: 10px;
min-width: inherit;
border: solid 1px;
border-radius: 10px;
box-shadow: 0px 15px 10px -15px #000;
overflow: auto;
padding: 10px;
}
.el-form-item {
margin: 5px 5px 5px 5px;
}
.el-form-item .el-input {
width: 196px;
}
.table-class {
margin: 5px 5px 5px 5px;
width: inherit;
}
.el-pagination {
padding-left: 5px;
}
.my-autocomplete li {
width: 196px;
line-height: normal;
padding: 7px;
}
.my-autocomplete li .name {
text-overflow: ellipsis;
overflow: hidden;
}
.my-autocomplete li .addr {
font-size: 12px;
color: #b4b4b4;
}
.my-autocomplete li .highlighted .addr {
color: #ddd;
}
.my-autocomplete li .goods_id {
color: brown;
}
.my-autocomplete li .goods_name {
color: cornflowerblue;
}
</style>