<template>
|
<div>
|
<el-dialog
|
v-model="isShow"
|
title="编辑工艺路线"
|
width="800"
|
@close="closeModal"
|
>
|
<el-form ref="formRef" label-width="140px" :model="formState" label-position="top">
|
<el-form-item
|
label="产品名称"
|
prop="selectedProducts"
|
:rules="[
|
{
|
required: true,
|
message: '请选择产品',
|
trigger: 'change',
|
},
|
]"
|
>
|
<div class="product-picker">
|
<el-button type="primary" @click="showProductSelectDialog = true">
|
{{ formState.selectedProducts.length ? "重新选择产品" : "选择产品" }}
|
</el-button>
|
<div v-if="formState.selectedProducts.length" class="product-tags">
|
<el-tag
|
v-for="product in formState.selectedProducts"
|
:key="product.id"
|
type="info"
|
effect="plain"
|
class="product-tag"
|
>
|
{{ product.productName }} / {{ product.model }}
|
</el-tag>
|
</div>
|
</div>
|
</el-form-item>
|
|
<el-form-item label="BOM" prop="bomId">
|
<el-select
|
v-model="formState.bomId"
|
placeholder="请选择BOM"
|
clearable
|
:disabled="bomOptions.length === 0"
|
style="width: 100%"
|
>
|
<el-option
|
v-for="item in bomOptions"
|
:key="item.id"
|
:label="item.bomNo || `BOM-${item.id}`"
|
:value="item.id"
|
/>
|
</el-select>
|
</el-form-item>
|
|
<el-form-item label="备注" prop="description">
|
<el-input v-model="formState.description" type="textarea" />
|
</el-form-item>
|
</el-form>
|
|
<ProductSelectDialog
|
v-model="showProductSelectDialog"
|
@confirm="handleProductSelect"
|
/>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button type="primary" @click="handleSubmit">确认</el-button>
|
<el-button @click="closeModal">取消</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { computed, getCurrentInstance, nextTick, ref, watch } from "vue";
|
import { update } from "@/api/productionManagement/processRoute.js";
|
import { getByModelList } from "@/api/productionManagement/productBom.js";
|
import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
|
|
const props = defineProps({
|
visible: {
|
type: Boolean,
|
required: true,
|
},
|
record: {
|
type: Object,
|
required: true,
|
},
|
});
|
|
const emit = defineEmits(["update:visible", "completed"]);
|
|
const formRef = ref();
|
const showProductSelectDialog = ref(false);
|
const bomOptions = ref([]);
|
const formState = ref(createDefaultFormState());
|
|
const isShow = computed({
|
get() {
|
return props.visible;
|
},
|
set(val) {
|
emit("update:visible", val);
|
},
|
});
|
|
const { proxy } = getCurrentInstance();
|
|
const splitFieldValues = value =>
|
String(value || "")
|
.split(/[,\uff0c]/)
|
.map(item => item.trim())
|
.filter(Boolean);
|
|
function createDefaultFormState() {
|
return {
|
id: undefined,
|
productId: undefined,
|
productModelId: undefined,
|
productModelIds: "",
|
productName: "",
|
productModelName: "",
|
selectedProducts: [],
|
bomId: undefined,
|
description: "",
|
};
|
}
|
|
const resetForm = () => {
|
formState.value = createDefaultFormState();
|
bomOptions.value = [];
|
};
|
|
const closeModal = () => {
|
resetForm();
|
isShow.value = false;
|
};
|
|
const loadBomList = async productModelIds => {
|
if (!productModelIds?.length) {
|
bomOptions.value = [];
|
return;
|
}
|
|
try {
|
const res = await getByModelList(productModelIds);
|
if (Array.isArray(res)) {
|
bomOptions.value = res;
|
return;
|
}
|
if (res && res.data) {
|
bomOptions.value = Array.isArray(res.data) ? res.data : [res.data];
|
return;
|
}
|
bomOptions.value = res && typeof res === "object" ? [res] : [];
|
} catch (error) {
|
bomOptions.value = [];
|
}
|
};
|
|
const buildSelectedProducts = record => {
|
const ids = splitFieldValues(record.productModelIds || record.productModelId);
|
const productNames = splitFieldValues(record.productName);
|
const modelNames = splitFieldValues(record.model || record.productModelName);
|
const productIds = splitFieldValues(record.productIds || record.productId);
|
|
return ids.map((id, index) => ({
|
id,
|
productId: productIds[index] || undefined,
|
productName: productNames[index] || record.productName || "",
|
model: modelNames[index] || record.model || record.productModelName || "",
|
}));
|
};
|
|
const setFormData = async () => {
|
if (!props.record) return;
|
|
const selectedProducts = buildSelectedProducts(props.record);
|
|
const productModelIds = props.record.productModelIds
|
|| (props.record.productModelId ? String(props.record.productModelId) : "");
|
|
formState.value = {
|
id: props.record.id,
|
productId: props.record.productId,
|
productModelId: props.record.productModelId,
|
productModelIds,
|
productName: props.record.productName || "",
|
productModelName: props.record.model || props.record.productModelName || "",
|
selectedProducts,
|
bomId: props.record.bomId,
|
description: props.record.description || "",
|
};
|
|
const ids = productModelIds
|
? splitFieldValues(productModelIds)
|
: [];
|
await loadBomList(ids);
|
};
|
|
const handleProductSelect = async products => {
|
if (!products?.length) {
|
return;
|
}
|
|
formState.value.selectedProducts = products;
|
formState.value.productModelIds = products.map(product => product.id).join(",");
|
formState.value.bomId = undefined;
|
|
if (products.length === 1) {
|
const product = products[0];
|
formState.value.productId = product.productId;
|
formState.value.productModelId = product.id;
|
formState.value.productName = product.productName;
|
formState.value.productModelName = product.model;
|
await loadBomList([product.id]);
|
} else {
|
formState.value.productId = undefined;
|
formState.value.productModelId = undefined;
|
formState.value.productName = "";
|
formState.value.productModelName = "";
|
await loadBomList(products.map(product => product.id));
|
}
|
|
showProductSelectDialog.value = false;
|
formRef.value?.validateField("selectedProducts");
|
};
|
|
const handleSubmit = () => {
|
formRef.value.validate(valid => {
|
if (!valid) {
|
return;
|
}
|
if (!formState.value.selectedProducts.length) {
|
proxy.$modal.msgError("请选择产品");
|
return;
|
}
|
|
update({
|
...props.record,
|
id: formState.value.id,
|
productId: formState.value.selectedProducts.length === 1
|
? formState.value.selectedProducts[0].productId
|
: undefined,
|
productModelId: formState.value.selectedProducts.length === 1
|
? formState.value.selectedProducts[0].id
|
: undefined,
|
productModelIds: formState.value.productModelIds,
|
productName: formState.value.selectedProducts.length === 1
|
? formState.value.selectedProducts[0].productName
|
: undefined,
|
productModelName: formState.value.selectedProducts.length === 1
|
? formState.value.selectedProducts[0].model
|
: undefined,
|
bomId: formState.value.bomId,
|
description: formState.value.description,
|
}).then(() => {
|
isShow.value = false;
|
emit("completed");
|
proxy.$modal.msgSuccess("提交成功");
|
resetForm();
|
});
|
});
|
};
|
|
defineExpose({
|
closeModal,
|
handleSubmit,
|
isShow,
|
});
|
|
watch(
|
() => [props.visible, props.record?.id],
|
([visible]) => {
|
if (visible && props.record?.id) {
|
nextTick(() => {
|
setFormData();
|
});
|
}
|
},
|
{ immediate: true }
|
);
|
</script>
|
|
<style scoped>
|
.product-picker {
|
display: flex;
|
flex-direction: column;
|
gap: 10px;
|
align-items: flex-start;
|
}
|
|
.product-tags {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 8px;
|
}
|
|
.product-tag {
|
max-width: 220px;
|
}
|
</style>
|