<template>
|
<div>
|
<el-dialog v-model="dialogVisible"
|
title="物料"
|
width="1200px"
|
@close="handleCloseMaterialDialog">
|
<el-table v-loading="materialTableLoading"
|
:data="materialTableData"
|
border
|
row-key="id">
|
<el-table-column label="工序名称"
|
prop="processName"
|
min-width="140" />
|
<el-table-column label="原料名称"
|
prop="materialName"
|
min-width="140" />
|
<el-table-column label="原料型号"
|
prop="materialModel"
|
min-width="140" />
|
<el-table-column label="计量单位"
|
prop="unit"
|
min-width="100" />
|
<el-table-column label="线边仓数量"
|
prop="pickQty"
|
min-width="100" />
|
<el-table-column label="补料数量"
|
prop="supplementQty"
|
min-width="100" />
|
<el-table-column label="实际数量"
|
min-width="140">
|
<template #default="{ row }">
|
<el-input-number v-model="row.actualQty"
|
:min="0"
|
:precision="3"
|
:step="1"
|
controls-position="right"
|
style="width: 100%;" />
|
</template>
|
</el-table-column>
|
<el-table-column label="操作"
|
align="center"
|
fixed="right"
|
width="180">
|
<template #default="{ row }">
|
<el-button type="primary"
|
link
|
@click="openSupplementDialog(row)">补料</el-button>
|
<el-button type="info"
|
link
|
@click="openSupplementRecordDialog(row)">补料记录</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button type="primary"
|
:loading="pickSubmitting"
|
@click="handleSubmitPick">领用</el-button>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
<FormDialog v-model="supplementDialogVisible"
|
title="补料"
|
width="500px"
|
@confirm="handleSubmitSupplement">
|
<el-form ref="supplementFormRef"
|
:model="supplementForm"
|
:rules="supplementRules"
|
label-width="100px">
|
<el-form-item label="补料数量"
|
prop="supplementQty">
|
<el-input-number v-model="supplementForm.supplementQty"
|
:min="0.001"
|
:precision="3"
|
:step="1"
|
style="width: 100%;" />
|
</el-form-item>
|
<el-form-item label="补料原因"
|
prop="supplementReason">
|
<el-input v-model="supplementForm.supplementReason"
|
type="textarea"
|
:rows="3"
|
maxlength="200"
|
show-word-limit
|
placeholder="请输入补料原因" />
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button type="primary"
|
:loading="supplementSubmitting"
|
@click="handleSubmitSupplement">确定</el-button>
|
<el-button @click="supplementDialogVisible = false">取消</el-button>
|
</span>
|
</template>
|
</FormDialog>
|
<el-dialog v-model="supplementRecordDialogVisible"
|
title="补料记录"
|
width="900px">
|
<el-table v-loading="supplementRecordLoading"
|
:data="supplementRecordTableData"
|
border
|
row-key="id">
|
<el-table-column label="补料数量"
|
prop="supplementQty"
|
min-width="100" />
|
<el-table-column label="补料原因"
|
prop="supplementReason"
|
min-width="200" />
|
<el-table-column label="补料人"
|
prop="supplementUserName"
|
min-width="120" />
|
<el-table-column label="补料日期"
|
prop="supplementTime"
|
min-width="160" />
|
</el-table>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button @click="supplementRecordDialogVisible = false">关闭</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { computed, nextTick, reactive, ref, watch } from "vue";
|
import { ElMessage } from "element-plus";
|
import FormDialog from "@/components/Dialog/FormDialog.vue";
|
import {
|
listWorkOrderMaterialLedger,
|
addWorkOrderMaterialSupplement,
|
listWorkOrderMaterialSupplementRecord,
|
pickWorkOrderMaterial,
|
} from "@/api/productionManagement/workOrder.js";
|
|
const props = defineProps({
|
modelValue: {
|
type: Boolean,
|
default: false,
|
},
|
rowData: {
|
type: Object,
|
default: () => null,
|
},
|
});
|
|
const emit = defineEmits(["update:modelValue", "refresh"]);
|
|
const dialogVisible = computed({
|
get: () => props.modelValue,
|
set: val => emit("update:modelValue", val),
|
});
|
|
const materialTableLoading = ref(false);
|
const materialTableData = ref([]);
|
const currentMaterialRow = ref(null);
|
const currentMaterialOrderRow = ref(null);
|
const pickSubmitting = ref(false);
|
|
const supplementDialogVisible = ref(false);
|
const supplementSubmitting = ref(false);
|
const supplementFormRef = ref(null);
|
const supplementForm = reactive({
|
supplementQty: null,
|
supplementReason: "",
|
});
|
|
const supplementRecordDialogVisible = ref(false);
|
const supplementRecordLoading = ref(false);
|
const supplementRecordTableData = ref([]);
|
|
const supplementRules = {
|
supplementQty: [
|
{ required: true, message: "请输入补料数量", trigger: "blur" },
|
],
|
supplementReason: [
|
{ required: true, message: "请输入补料原因", trigger: "blur" },
|
],
|
};
|
const loadMaterialTable = async row => {
|
if (!row?.id) return;
|
currentMaterialOrderRow.value = row;
|
materialTableLoading.value = true;
|
materialTableData.value = [];
|
try {
|
const res = await listWorkOrderMaterialLedger({
|
workOrderId: row.id,
|
processId: row.processId,
|
productProcessRouteItemId: row.productProcessRouteItemId,
|
});
|
materialTableData.value = res.data || [];
|
} catch (e) {
|
console.error("获取物料台账失败", e);
|
ElMessage.error("获取物料台账失败");
|
} finally {
|
materialTableLoading.value = false;
|
}
|
};
|
|
watch(
|
() => props.modelValue,
|
visible => {
|
if (visible && props.rowData) {
|
loadMaterialTable(props.rowData);
|
}
|
}
|
);
|
|
const handleCloseMaterialDialog = () => {
|
materialTableData.value = [];
|
currentMaterialRow.value = null;
|
currentMaterialOrderRow.value = null;
|
};
|
|
const openSupplementDialog = row => {
|
currentMaterialRow.value = row;
|
supplementForm.supplementQty = null;
|
supplementForm.supplementReason = "";
|
supplementDialogVisible.value = true;
|
nextTick(() => {
|
supplementFormRef.value?.clearValidate();
|
});
|
};
|
|
const handleSubmitSupplement = () => {
|
supplementFormRef.value?.validate(async valid => {
|
if (!valid || !currentMaterialRow.value?.id) {
|
ElMessage.warning("缺少物料明细ID");
|
return;
|
}
|
supplementSubmitting.value = true;
|
try {
|
await addWorkOrderMaterialSupplement({
|
materialLedgerId: currentMaterialRow.value.id,
|
supplementQty: Number(supplementForm.supplementQty),
|
supplementReason: supplementForm.supplementReason,
|
workOrderId: currentMaterialOrderRow.value?.id,
|
});
|
supplementDialogVisible.value = false;
|
await loadMaterialTable(currentMaterialOrderRow.value);
|
ElMessage.success("补料成功");
|
emit("refresh");
|
} catch (e) {
|
console.error("补料失败", e);
|
ElMessage.error("补料失败");
|
} finally {
|
supplementSubmitting.value = false;
|
}
|
});
|
};
|
|
const openSupplementRecordDialog = async row => {
|
supplementRecordDialogVisible.value = true;
|
supplementRecordLoading.value = true;
|
supplementRecordTableData.value = [];
|
try {
|
const res = await listWorkOrderMaterialSupplementRecord({
|
materialLedgerId: row.id,
|
});
|
supplementRecordTableData.value = res.data || [];
|
} catch (e) {
|
console.error("获取补料记录失败", e);
|
ElMessage.error("获取补料记录失败");
|
} finally {
|
supplementRecordLoading.value = false;
|
}
|
};
|
|
const validatePickRows = () => {
|
if (materialTableData.value.length === 0) {
|
return { valid: false, message: "暂无可领用物料" };
|
}
|
const invalidRow = materialTableData.value.find(
|
item =>
|
item.actualQty === null ||
|
item.actualQty === undefined ||
|
item.actualQty === ""
|
);
|
if (invalidRow) {
|
return { valid: false, message: "请填写实际数量后再领用" };
|
}
|
const exceedRow = materialTableData.value.find(item => {
|
const maxQty = Number(item.pickQty || 0) + Number(item.supplementQty || 0);
|
return Number(item.actualQty || 0) > maxQty;
|
});
|
if (exceedRow) {
|
return { valid: false, message: "实际数量不能大于领用数量+补料数量" };
|
}
|
return { valid: true, message: "" };
|
};
|
|
const handleSubmitPick = async () => {
|
if (!currentMaterialOrderRow.value?.id) return;
|
const validateResult = validatePickRows();
|
if (!validateResult.valid) {
|
ElMessage.warning(validateResult.message);
|
return;
|
}
|
pickSubmitting.value = true;
|
try {
|
await pickWorkOrderMaterial({
|
workOrderId: currentMaterialOrderRow.value.id,
|
items: materialTableData.value.map(item => ({
|
materialLedgerId: item.id,
|
actualQty: Number(item.actualQty || 0),
|
})),
|
});
|
ElMessage.success("领用成功");
|
await loadMaterialTable(currentMaterialOrderRow.value);
|
emit("refresh");
|
} catch (e) {
|
console.error("领用失败", e);
|
ElMessage.error("领用失败");
|
} finally {
|
pickSubmitting.value = false;
|
}
|
};
|
</script>
|