<template>
|
<vol-box v-model="show" title="物料库存查询" :width="800" :height="600">
|
<template #content>
|
<el-form ref="form" :model="form" :rules="rules" label-width="90px">
|
<!-- 仓库号输入框 -->
|
<el-form-item label="仓库号:" prop="warehouseCode">
|
<el-input
|
v-model="form.warehouseCode"
|
placeholder="请输入仓库号(如:5053)"
|
clearable
|
@input="handleWarehouseInput"
|
@keyup.enter="focusMaterielInput"
|
ref="warehouseCodeInput"
|
:disabled="loading"
|
/>
|
</el-form-item>
|
|
<!-- 物料条码输入框 -->
|
<el-form-item label="物料条码:" prop="materielBarcode">
|
<el-input
|
v-model="form.materielBarcode"
|
placeholder="请扫描/输入物料条码(如:100401-01211)"
|
@keyup.enter="getStockTotal"
|
clearable
|
@paste="handlePaste"
|
@input="handleInput"
|
ref="materielCodeInput"
|
:disabled="loading"
|
/>
|
<!-- 库存查询加载状态 -->
|
<el-icon class="ml-2" v-if="loading"><loading /></el-icon>
|
</el-form-item>
|
|
<!-- 库存总和显示区域 -->
|
<el-form-item label="库存总和:" prop="totalStockQuantity">
|
<el-input
|
v-model="form.totalStockQuantity"
|
placeholder="请输入仓库号和物料条码查询"
|
disabled
|
prefix-icon="el-icon-s-data"
|
/>
|
<!-- 无数据提示 -->
|
<span v-if="form.totalStockQuantity === 0 && !loading && form.materielBarcode && form.warehouseCode" class="text-gray-500 ml-2">
|
该物料在当前仓库暂无库存
|
</span>
|
</el-form-item>
|
</el-form>
|
</template>
|
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button @click="resetForm">重置</el-button>
|
<el-button @click="show = false">关闭</el-button>
|
</div>
|
</template>
|
</vol-box>
|
</template>
|
|
<script>
|
import VolBox from '@/components/basic/VolBox.vue'
|
import { Loading } from '@element-plus/icons-vue'
|
|
export default {
|
components: { VolBox, Loading },
|
props: {
|
value: { type: Boolean, default: false }
|
},
|
data() {
|
// 仓库号验证规则
|
const validateWarehouseCode = (rule, value, callback) => {
|
if (!value) {
|
return callback(new Error('请输入仓库号'));
|
}
|
callback();
|
};
|
|
// 物料条码验证规则
|
const validateMaterielBarcode = (rule, value, callback) => {
|
if (!value) {
|
return callback(new Error('请输入物料条码'));
|
}
|
callback();
|
};
|
|
return {
|
show: false,
|
loading: false, // 库存查询加载状态
|
form: {
|
warehouseCode: '', // 仓库号
|
materielBarcode: '', // 物料条码
|
totalStockQuantity: 0 // 库存总和
|
},
|
// 表单验证规则
|
rules: {
|
warehouseCode: [
|
{ validator: validateWarehouseCode, trigger: ['blur', 'change'] }
|
],
|
materielBarcode: [
|
{ validator: validateMaterielBarcode, trigger: ['blur', 'change'] }
|
]
|
}
|
}
|
},
|
methods: {
|
// 打开弹窗初始化
|
open() {
|
this.show = true
|
this.$nextTick(() => {
|
this.focusWarehouseInput()
|
})
|
},
|
async getStockTotal() {
|
// 表单验证
|
try {
|
await this.$refs.form.validate();
|
} catch (error) {
|
if (!this.form.warehouseCode) {
|
this.focusWarehouseInput();
|
} else {
|
this.focusAndSelectInput();
|
}
|
return;
|
}
|
|
this.loading = true;
|
try {
|
const res = await this.http.post('/api/StockDetailByMateriel/CalculateStock?warehouseCode=' + this.form.warehouseCode.trim() + '&materielCode=' + this.form.materielBarcode.trim());
|
if (res.status && res.code === 0) {
|
this.form.totalStockQuantity = Number(res.data) || 0;
|
this.$message.success('库存查询成功');
|
} else {
|
this.form.totalStockQuantity = 0;
|
this.$message.error(res.message || '库存查询失败:接口返回异常');
|
}
|
} catch (error) {
|
this.form.totalStockQuantity = 0;
|
const errorMsg = error.response
|
? `接口错误:${error.response.status} - ${error.response.data?.message || '未知错误'}`
|
: `网络异常:${error.message}`;
|
this.$message.error(`库存查询失败:${errorMsg}`);
|
} finally {
|
this.loading = false;
|
}
|
},
|
|
// 仓库号输入过滤
|
handleWarehouseInput(value) {
|
this.form.warehouseCode = value.replace(/[^a-zA-Z0-9]/g, '').toUpperCase();
|
this.$nextTick(() => {
|
this.$refs.form.validateField('warehouseCode');
|
});
|
},
|
|
// 物料条码输入过滤
|
handleInput(value) {
|
this.form.materielBarcode = value.replace(/[^-a-zA-Z0-9]/g, '');
|
this.$nextTick(() => {
|
this.$refs.form.validateField('materielBarcode');
|
});
|
},
|
|
// 粘贴物料条码自动查询
|
handlePaste(e) {
|
const clipboardData = e.clipboardData || window.clipboardData;
|
const pastedText = clipboardData.getData('text');
|
const cleanedText = pastedText.replace(/[^-a-zA-Z0-9]/g, '');
|
if (cleanedText) {
|
this.form.materielBarcode = cleanedText;
|
setTimeout(() => {
|
this.getStockTotal();
|
}, 50);
|
}
|
e.preventDefault();
|
},
|
|
// 仓库号回车聚焦物料条码
|
focusMaterielInput() {
|
this.$nextTick(() => {
|
const inputRef = this.$refs.materielCodeInput;
|
if (inputRef) {
|
const inputEl = inputRef.$el ? inputRef.$el.querySelector('input') : inputRef;
|
inputEl?.focus();
|
}
|
});
|
},
|
|
// 聚焦仓库号输入框
|
focusWarehouseInput() {
|
this.$nextTick(() => {
|
const inputRef = this.$refs.warehouseCodeInput;
|
if (inputRef) {
|
const inputEl = inputRef.$el ? inputRef.$el.querySelector('input') : inputRef;
|
inputEl?.focus();
|
}
|
});
|
},
|
|
// 聚焦并选中物料条码输入框
|
focusAndSelectInput() {
|
this.$nextTick(() => {
|
setTimeout(() => {
|
const inputRef = this.$refs.materielCodeInput;
|
if (inputRef) {
|
const inputEl = inputRef.$el ? inputRef.$el.querySelector('input') : inputRef;
|
if (inputEl) {
|
inputEl.focus();
|
inputEl.select();
|
}
|
}
|
}, 100);
|
});
|
},
|
|
// 重置表单
|
resetForm() {
|
this.form = {
|
warehouseCode: '',
|
materielBarcode: '',
|
totalStockQuantity: 0
|
};
|
this.$refs.form.clearValidate();
|
this.focusWarehouseInput();
|
}
|
},
|
watch: {
|
show(val) {
|
if (val) {
|
this.$nextTick(() => {
|
this.focusWarehouseInput()
|
})
|
} else {
|
this.resetForm();
|
}
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.dialog-footer {
|
text-align: right;
|
}
|
.text-gray-500 {
|
color: #909399;
|
font-size: 12px;
|
}
|
.ml-2 {
|
margin-left: 8px;
|
}
|
</style>
|