<template>
|
<el-dialog v-model="visible"
|
title="BOM齐套分析"
|
width="900px"
|
@close="handleClose">
|
<div class="bom-info">
|
<span>BOM编号:{{ bom.bomNo || '-' }}</span>
|
<span>产品名称:{{ bom.productName || '-' }}</span>
|
<span>规格型号:{{ bom.productModelName || '-' }}</span>
|
</div>
|
|
<el-form :inline="true"
|
@submit.prevent>
|
<el-form-item label="需求数量">
|
<el-input-number v-model="demandQty"
|
:min="0"
|
:precision="4"
|
:step="1"
|
:controls="false"
|
placeholder="请输入需求数量"
|
style="width: 180px" />
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary"
|
:loading="loading"
|
@click="handleAnalyze">开始分析</el-button>
|
<el-button :disabled="!resultList.length"
|
:loading="exportLoading"
|
@click="handleExport">导出</el-button>
|
<el-button type="success"
|
:disabled="!resultList.length"
|
:loading="genLoading"
|
@click="handleGenerate">生成采购需求</el-button>
|
</el-form-item>
|
</el-form>
|
|
<el-table v-loading="loading"
|
:data="resultList"
|
border
|
size="small"
|
max-height="420"
|
style="width: 100%">
|
<el-table-column type="index"
|
label="序号"
|
width="60"
|
align="center" />
|
<el-table-column label="物料名称"
|
prop="productName"
|
min-width="140" />
|
<el-table-column label="规格型号"
|
prop="model"
|
min-width="140" />
|
<el-table-column label="单位"
|
prop="unit"
|
width="80"
|
align="center" />
|
<el-table-column label="需求数量"
|
prop="requiredQty"
|
width="110"
|
align="right" />
|
<el-table-column label="可用库存"
|
prop="availableQty"
|
width="110"
|
align="right" />
|
<el-table-column label="缺口数量"
|
prop="shortageQty"
|
width="110"
|
align="right">
|
<template #default="{ row }">
|
<span :class="{ shortage: Number(row.shortageQty) > 0 }">{{ row.shortageQty }}</span>
|
</template>
|
</el-table-column>
|
</el-table>
|
</el-dialog>
|
</template>
|
|
<script setup>
|
import { ref, computed, getCurrentInstance } from "vue";
|
import { saveAs } from "file-saver";
|
import { blobValidate } from "@/utils/ruoyi";
|
import {
|
kitCheck,
|
kitCheckExport,
|
generateDemand,
|
} from "@/api/productionManagement/productBom.js";
|
|
const props = defineProps({
|
showModel: {
|
type: Boolean,
|
default: false,
|
},
|
bom: {
|
type: Object,
|
default: () => ({}),
|
},
|
});
|
|
const emits = defineEmits(["update:showModel"]);
|
const { proxy } = getCurrentInstance();
|
|
const visible = computed({
|
get() {
|
return props.showModel;
|
},
|
set(val) {
|
emits("update:showModel", val);
|
},
|
});
|
|
const demandQty = ref(undefined);
|
const resultList = ref([]);
|
const loading = ref(false);
|
const exportLoading = ref(false);
|
const genLoading = ref(false);
|
|
// 校验并组装请求参数
|
const buildParams = () => {
|
if (!props.bom?.id) {
|
proxy.$modal.msgWarning("未获取到BOM信息,请重试");
|
return null;
|
}
|
const qty = Number(demandQty.value);
|
if (!qty || qty <= 0) {
|
proxy.$modal.msgWarning("请输入大于0的需求数量");
|
return null;
|
}
|
return { bomId: props.bom.id, demandQty: qty };
|
};
|
|
// 开始分析
|
const handleAnalyze = () => {
|
const params = buildParams();
|
if (!params) return;
|
loading.value = true;
|
kitCheck(params)
|
.then(res => {
|
resultList.value = res?.data || [];
|
if (!resultList.value.length) {
|
proxy.$modal.msgWarning("该BOM下无物料节点");
|
}
|
})
|
.catch(() => {})
|
.finally(() => {
|
loading.value = false;
|
});
|
};
|
|
// 导出
|
const handleExport = async () => {
|
const params = buildParams();
|
if (!params) return;
|
exportLoading.value = true;
|
try {
|
const blobData = await kitCheckExport(params);
|
if (blobValidate(blobData)) {
|
if (blobData.size === 0) {
|
proxy.$modal.msgWarning("暂无数据可导出");
|
return;
|
}
|
const blob = new Blob([blobData], {
|
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
});
|
saveAs(blob, `BOM齐套分析_${props.bom.bomNo || props.bom.id}.xlsx`);
|
proxy.$modal.msgSuccess("导出成功");
|
} else {
|
const resText = await blobData.text();
|
let rspObj = {};
|
try {
|
rspObj = JSON.parse(resText);
|
} catch (error) {
|
rspObj = {};
|
}
|
proxy.$modal.msgError(rspObj.msg || "导出失败");
|
}
|
} catch (error) {
|
proxy.$modal.msgError("导出失败,请稍后重试");
|
} finally {
|
exportLoading.value = false;
|
}
|
};
|
|
// 缺口生成采购需求
|
const handleGenerate = () => {
|
const params = buildParams();
|
if (!params) return;
|
genLoading.value = true;
|
generateDemand(params)
|
.then(res => {
|
proxy.$modal.msgSuccess(res?.data || "生成完成");
|
})
|
.catch(() => {})
|
.finally(() => {
|
genLoading.value = false;
|
});
|
};
|
|
const handleClose = () => {
|
demandQty.value = undefined;
|
resultList.value = [];
|
};
|
</script>
|
|
<style scoped lang="scss">
|
.bom-info {
|
display: flex;
|
gap: 24px;
|
margin-bottom: 16px;
|
font-size: 13px;
|
color: #606266;
|
}
|
|
.shortage {
|
color: #d93025;
|
font-weight: 600;
|
}
|
</style>
|