| | |
| | | :model="formState" |
| | | label-position="top" |
| | | ref="formRef"> |
| | | <el-form-item label="产品名称" |
| | | prop="productModelId" |
| | | <el-form-item label="产品类型" |
| | | prop="dictCode" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请选择产品', |
| | | message: '请选择产品类型', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-button type="primary" |
| | | @click="showProductSelectDialog = true"> |
| | | {{ formState.productName && formState.productModelName |
| | | ? `${formState.productName} - ${formState.productModelName}` |
| | | : '选择产品' }} |
| | | </el-button> |
| | | <el-select v-model="formState.dictCode" |
| | | placeholder="请选择产品类型" |
| | | clearable |
| | | style="width: 100%" |
| | | @change="handleProductTypeChange"> |
| | | <el-option v-for="item in productTypeOptions" |
| | | :key="item.dictCode" |
| | | :label="item.dictLabel" |
| | | :value="item.dictCode" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="BOM" |
| | | prop="bomId" |
| | |
| | | <el-select v-model="formState.bomId" |
| | | placeholder="请选择BOM" |
| | | clearable |
| | | :disabled="!formState.productModelId || bomOptions.length === 0" |
| | | :disabled="!formState.dictCode || bomOptions.length === 0" |
| | | style="width: 100%"> |
| | | <el-option v-for="item in bomOptions" |
| | | :key="item.id" |
| | |
| | | type="textarea" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- 产品选择弹窗 --> |
| | | <ProductSelectDialog v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single /> |
| | | |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" |
| | |
| | | watch, |
| | | } from "vue"; |
| | | import { update } from "@/api/productionManagement/processRoute.js"; |
| | | import { getByModel } from "@/api/productionManagement/productBom.js"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import { listPage } from "@/api/productionManagement/productBom.js"; |
| | | import { getDicts } from "@/api/system/dict/data.js"; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | |
| | | |
| | | // 响应式数据(替代选项式的 data) |
| | | const formState = ref({ |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | dictCode: undefined, |
| | | dictLabel: "", |
| | | bomId: undefined, |
| | | description: "", |
| | | }); |
| | |
| | | }, |
| | | }); |
| | | |
| | | const showProductSelectDialog = ref(false); |
| | | const productTypeOptions = ref([]); |
| | | const bomOptions = ref([]); |
| | | |
| | | let { proxy } = getCurrentInstance(); |
| | | |
| | | // 获取产品类型字典 |
| | | const getProductTypeOptions = () => { |
| | | getDicts("product_type") |
| | | .then(res => { |
| | | if (res.code === 200) { |
| | | productTypeOptions.value = res.data; |
| | | } |
| | | }) |
| | | .catch(err => { |
| | | console.error("获取产品类型字典失败:", err); |
| | | }); |
| | | }; |
| | | |
| | | // 根据产品类型获取BOM列表 |
| | | const getBomListByProductType = async dictCode => { |
| | | if (!dictCode) { |
| | | bomOptions.value = []; |
| | | return; |
| | | } |
| | | try { |
| | | // 使用listPage接口,根据dictCode查询BOM |
| | | const res = await listPage({ dictCode }); |
| | | // 处理返回的BOM数据 |
| | | let bomList = []; |
| | | if (res.data && res.data.records) { |
| | | bomList = res.data.records; |
| | | } |
| | | bomOptions.value = bomList; |
| | | if (bomList.length === 0) { |
| | | proxy.$modal.msgError("该产品类型没有BOM,请先创建BOM"); |
| | | } |
| | | } catch (error) { |
| | | // 如果接口返回404或其他错误,说明没有BOM |
| | | proxy.$modal.msgError("该产品类型没有BOM,请先创建BOM"); |
| | | bomOptions.value = []; |
| | | } |
| | | }; |
| | | |
| | | const closeModal = () => { |
| | | isShow.value = false; |
| | |
| | | if (props.record) { |
| | | formState.value = { |
| | | ...props.record, |
| | | productId: props.record.productId, |
| | | productModelId: props.record.productModelId, |
| | | productName: props.record.productName || "", |
| | | // 注意:record中的字段是model,需要映射到productModelName |
| | | productModelName: |
| | | props.record.model || props.record.productModelName || "", |
| | | dictCode: props.record.dictCode, |
| | | dictLabel: props.record.dictLabel || "", |
| | | bomId: props.record.bomId, |
| | | description: props.record.description || "", |
| | | }; |
| | | // 如果有产品型号ID,加载BOM列表 |
| | | if (props.record.productModelId) { |
| | | loadBomList(props.record.productModelId); |
| | | // 如果有产品类型,加载BOM列表 |
| | | if (props.record.dictCode) { |
| | | getBomListByProductType(props.record.dictCode); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 加载BOM列表 |
| | | const loadBomList = async productModelId => { |
| | | if (!productModelId) { |
| | | bomOptions.value = []; |
| | | return; |
| | | } |
| | | try { |
| | | const res = await getByModel(productModelId); |
| | | // 处理返回的BOM数据:可能是数组、对象或包含data字段 |
| | | let bomList = []; |
| | | if (Array.isArray(res)) { |
| | | bomList = res; |
| | | } else if (res && res.data) { |
| | | bomList = Array.isArray(res.data) ? res.data : [res.data]; |
| | | } else if (res && typeof res === "object") { |
| | | bomList = [res]; |
| | | // 产品类型选择处理 |
| | | const handleProductTypeChange = async dictCode => { |
| | | if (dictCode) { |
| | | const selectedType = productTypeOptions.value.find(item => item.dictCode === dictCode); |
| | | if (selectedType) { |
| | | formState.value.dictLabel = selectedType.dictLabel; |
| | | } |
| | | bomOptions.value = bomList; |
| | | } catch (error) { |
| | | console.error("加载BOM列表失败:", error); |
| | | // 如果当前选择的BOM不在新列表中,则重置BOM选择 |
| | | formState.value.bomId = undefined; |
| | | await getBomListByProductType(dictCode); |
| | | // 触发表单验证更新 |
| | | proxy.$refs["formRef"]?.validateField("dictCode"); |
| | | } else { |
| | | formState.value.dictLabel = ""; |
| | | bomOptions.value = []; |
| | | } |
| | | }; |
| | | |
| | | // 产品选择处理 |
| | | const handleProductSelect = async products => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | // 先查询BOM列表(必选) |
| | | try { |
| | | const res = await getByModel(product.id); |
| | | // 处理返回的BOM数据:可能是数组、对象或包含data字段 |
| | | let bomList = []; |
| | | if (Array.isArray(res)) { |
| | | bomList = res; |
| | | } else if (res && res.data) { |
| | | bomList = Array.isArray(res.data) ? res.data : [res.data]; |
| | | } else if (res && typeof res === "object") { |
| | | bomList = [res]; |
| | | } |
| | | |
| | | if (bomList.length > 0) { |
| | | formState.value.productModelId = product.id; |
| | | formState.value.productName = product.productName; |
| | | formState.value.productModelName = product.model; |
| | | // 如果当前选择的BOM不在新列表中,则重置BOM选择 |
| | | const currentBomExists = bomList.some( |
| | | bom => bom.id === formState.value.bomId |
| | | ); |
| | | if (!currentBomExists) { |
| | | formState.value.bomId = undefined; |
| | | } |
| | | bomOptions.value = bomList; |
| | | showProductSelectDialog.value = false; |
| | | // 触发表单验证更新 |
| | | proxy.$refs["formRef"]?.validateField("productModelId"); |
| | | } else { |
| | | proxy.$modal.msgError("该产品没有BOM,请先创建BOM"); |
| | | } |
| | | } catch (error) { |
| | | // 如果接口返回404或其他错误,说明没有BOM |
| | | proxy.$modal.msgError("该产品没有BOM,请先创建BOM"); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // 验证是否选择了产品和BOM |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择产品"); |
| | | // 验证是否选择了产品类型和BOM |
| | | if (!formState.value.dictCode) { |
| | | proxy.$modal.msgError("请选择产品类型"); |
| | | return; |
| | | } |
| | | if (!formState.value.bomId) { |
| | |
| | | ); |
| | | |
| | | onMounted(() => { |
| | | getProductTypeOptions(); |
| | | if (props.visible && props.record) { |
| | | setFormData(); |
| | | } |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog |
| | | v-model="isShow" |
| | | title="新增工艺路线" |
| | | width="400" |
| | | @close="closeModal" |
| | | > |
| | | <el-form label-width="140px" :model="formState" label-position="top" ref="formRef"> |
| | | <el-form-item |
| | | label="产品名称" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | <el-dialog v-model="isShow" |
| | | title="新增工艺路线" |
| | | width="400" |
| | | @close="closeModal"> |
| | | <el-form label-width="140px" |
| | | :model="formState" |
| | | label-position="top" |
| | | ref="formRef"> |
| | | <el-form-item label="产品类型" |
| | | prop="dictCode" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请选择产品', |
| | | message: '请选择产品类型', |
| | | trigger: 'change', |
| | | } |
| | | ]" |
| | | > |
| | | <el-button type="primary" @click="showProductSelectDialog = true"> |
| | | {{ formState.productName && formState.productModelName |
| | | ? `${formState.productName} - ${formState.productModelName}` |
| | | : '选择产品' }} |
| | | </el-button> |
| | | ]"> |
| | | <el-select v-model="formState.dictCode" |
| | | placeholder="请选择产品类型" |
| | | clearable |
| | | style="width: 100%" |
| | | @change="handleProductTypeChange"> |
| | | <el-option v-for="item in productTypeOptions" |
| | | :key="item.dictCode" |
| | | :label="item.dictLabel" |
| | | :value="item.dictCode" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="BOM" |
| | | prop="bomId" |
| | | :rules="[ |
| | | <el-form-item label="BOM" |
| | | prop="bomId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请选择BOM', |
| | | trigger: 'change', |
| | | } |
| | | ]" |
| | | > |
| | | <el-select |
| | | v-model="formState.bomId" |
| | | placeholder="请选择BOM" |
| | | clearable |
| | | :disabled="!formState.productModelId || 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 v-model="formState.bomId" |
| | | placeholder="请选择BOM" |
| | | clearable |
| | | :disabled="!formState.dictCode || 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 label="备注" |
| | | prop="description"> |
| | | <el-input v-model="formState.description" |
| | | type="textarea" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <!-- 产品选择弹窗 --> |
| | | <ProductSelectDialog |
| | | v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single |
| | | /> |
| | | <ProductSelectDialog v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSubmit">确认</el-button> |
| | | <el-button type="primary" |
| | | @click="handleSubmit">确认</el-button> |
| | | <el-button @click="closeModal">取消</el-button> |
| | | </div> |
| | | </template> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, computed, getCurrentInstance} from "vue"; |
| | | import {add} from "@/api/productionManagement/processRoute.js"; |
| | | import {getByModel} from "@/api/productionManagement/productBom.js"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import { ref, computed, getCurrentInstance, onMounted } from "vue"; |
| | | import { add } from "@/api/productionManagement/processRoute.js"; |
| | | import { listPage } from "@/api/productionManagement/productBom.js"; |
| | | import { getDicts } from "@/api/system/dict/data.js"; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | }, |
| | | }); |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | }, |
| | | }); |
| | | |
| | | const emit = defineEmits(['update:visible', 'completed']); |
| | | const emit = defineEmits(["update:visible", "completed"]); |
| | | |
| | | // 响应式数据(替代选项式的 data) |
| | | const formState = ref({ |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | bomId: undefined, |
| | | description: '', |
| | | }); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit('update:visible', val); |
| | | }, |
| | | }); |
| | | |
| | | const showProductSelectDialog = ref(false); |
| | | const bomOptions = ref([]); |
| | | |
| | | let { proxy } = getCurrentInstance() |
| | | |
| | | const closeModal = () => { |
| | | // 重置表单数据 |
| | | formState.value = { |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | // 响应式数据(替代选项式的 data) |
| | | const formState = ref({ |
| | | dictCode: undefined, |
| | | dictLabel: "", |
| | | bomId: undefined, |
| | | description: '', |
| | | }; |
| | | bomOptions.value = []; |
| | | isShow.value = false; |
| | | }; |
| | | description: "", |
| | | }); |
| | | |
| | | // 产品选择处理 |
| | | const handleProductSelect = async (products) => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | // 先查询BOM列表(必选) |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit("update:visible", val); |
| | | }, |
| | | }); |
| | | |
| | | const productTypeOptions = ref([]); |
| | | const bomOptions = ref([]); |
| | | |
| | | let { proxy } = getCurrentInstance(); |
| | | |
| | | // 获取产品类型字典 |
| | | const getProductTypeOptions = () => { |
| | | getDicts("product_type") |
| | | .then(res => { |
| | | if (res.code === 200) { |
| | | productTypeOptions.value = res.data; |
| | | } |
| | | }) |
| | | .catch(err => { |
| | | console.error("获取产品类型字典失败:", err); |
| | | }); |
| | | }; |
| | | |
| | | // 根据产品类型获取BOM列表 |
| | | const getBomListByProductType = async dictCode => { |
| | | if (!dictCode) { |
| | | bomOptions.value = []; |
| | | return; |
| | | } |
| | | try { |
| | | const res = await getByModel(product.id); |
| | | // 处理返回的BOM数据:可能是数组、对象或包含data字段 |
| | | // 使用listPage接口,根据dictCode查询BOM |
| | | const res = await listPage({ dictCode }); |
| | | // 处理返回的BOM数据 |
| | | let bomList = []; |
| | | if (Array.isArray(res)) { |
| | | bomList = res; |
| | | } else if (res && res.data) { |
| | | bomList = Array.isArray(res.data) ? res.data : [res.data]; |
| | | } else if (res && typeof res === 'object') { |
| | | bomList = [res]; |
| | | if (res.data && res.data.records) { |
| | | bomList = res.data.records; |
| | | } |
| | | |
| | | if (bomList.length > 0) { |
| | | formState.value.productModelId = product.id; |
| | | formState.value.productName = product.productName; |
| | | formState.value.productModelName = product.model; |
| | | formState.value.bomId = undefined; // 重置BOM选择 |
| | | bomOptions.value = bomList; |
| | | showProductSelectDialog.value = false; |
| | | // 触发表单验证更新 |
| | | proxy.$refs["formRef"]?.validateField('productModelId'); |
| | | } else { |
| | | proxy.$modal.msgError("该产品没有BOM,请先创建BOM"); |
| | | bomOptions.value = bomList; |
| | | if (bomList.length === 0) { |
| | | proxy.$modal.msgError("该产品类型没有BOM,请先创建BOM"); |
| | | } |
| | | } catch (error) { |
| | | // 如果接口返回404或其他错误,说明没有BOM |
| | | proxy.$modal.msgError("该产品没有BOM,请先创建BOM"); |
| | | proxy.$modal.msgError("该产品类型没有BOM,请先创建BOM"); |
| | | bomOptions.value = []; |
| | | } |
| | | } |
| | | }; |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // 验证是否选择了产品和BOM |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择产品"); |
| | | return; |
| | | const closeModal = () => { |
| | | // 重置表单数据 |
| | | formState.value = { |
| | | dictCode: undefined, |
| | | dictLabel: "", |
| | | bomId: undefined, |
| | | description: "", |
| | | }; |
| | | bomOptions.value = []; |
| | | isShow.value = false; |
| | | }; |
| | | |
| | | // 产品类型选择处理 |
| | | const handleProductTypeChange = async dictCode => { |
| | | if (dictCode) { |
| | | const selectedType = productTypeOptions.value.find( |
| | | item => item.dictCode === dictCode |
| | | ); |
| | | if (selectedType) { |
| | | formState.value.dictLabel = selectedType.dictLabel; |
| | | } |
| | | if (!formState.value.bomId) { |
| | | proxy.$modal.msgError("请选择BOM"); |
| | | return; |
| | | } |
| | | add(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }) |
| | | formState.value.bomId = undefined; // 重置BOM选择 |
| | | await getBomListByProductType(dictCode); |
| | | // 触发表单验证更新 |
| | | proxy.$refs["formRef"]?.validateField("dictCode"); |
| | | } else { |
| | | formState.value.dictLabel = ""; |
| | | bomOptions.value = []; |
| | | } |
| | | }) |
| | | }; |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // 验证是否选择了产品类型和BOM |
| | | if (!formState.value.dictCode) { |
| | | proxy.$modal.msgError("请选择产品类型"); |
| | | return; |
| | | } |
| | | if (!formState.value.bomId) { |
| | | proxy.$modal.msgError("请选择BOM"); |
| | | return; |
| | | } |
| | | add(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit("completed"); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | | isShow, |
| | | }); |
| | | // 组件挂载时获取产品类型字典 |
| | | onMounted(() => { |
| | | getProductTypeOptions(); |
| | | }); |
| | | |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | | isShow, |
| | | }); |
| | | </script> |
| | |
| | | prop: "processRouteCode", |
| | | }, |
| | | { |
| | | label: "产品名称", |
| | | prop: "productName", |
| | | }, |
| | | { |
| | | label: "规格名称", |
| | | prop: "model", |
| | | label: "产品类型", |
| | | prop: "dictLabel", |
| | | }, |
| | | { |
| | | label: "BOM编号", |
| | |
| | | productName: row.productName || "", |
| | | model: row.model || "", |
| | | bomNo: row.bomNo || "", |
| | | dictLabel: row.dictLabel || "", |
| | | bomId: row.bomId || null, |
| | | description: row.description || "", |
| | | type: "route", |
| | |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-label-wrapper"> |
| | | <span class="info-label">产品名称</span> |
| | | <span class="info-label">产品类型</span> |
| | | </div> |
| | | <div class="info-value-wrapper"> |
| | | <span class="info-value">{{ routeInfo.productName || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-label-wrapper"> |
| | | <span class="info-label">规格名称</span> |
| | | </div> |
| | | <div class="info-value-wrapper"> |
| | | <span class="info-value">{{ routeInfo.model || '-' }}</span> |
| | | <span class="info-value">{{ routeInfo.dictLabel || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="info-item"> |
| | |
| | | :data="tableData" |
| | | :header-cell-style="{ background: '#F0F1F5', color: '#333333' }" |
| | | row-key="id" |
| | | height="350" |
| | | tooltip-effect="dark" |
| | | style="margin-bottom: 20px;" |
| | | class="lims-table"> |
| | | <el-table-column align="center" |
| | | label="序号" |
| | |
| | | {{ getProcessName(scope.row.processId) || '-' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="产品名称" |
| | | prop="productName" |
| | | min-width="160" /> |
| | | <el-table-column label="规格名称" |
| | | prop="model" |
| | | min-width="140" /> |
| | | <el-table-column label="参数列表" |
| | | min-width="160"> |
| | | <template #default="scope"> |
| | |
| | | @click="handleViewParams(scope.row)">参数列表</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="单位" |
| | | prop="unit" |
| | | width="100" /> |
| | | <el-table-column label="是否质检" |
| | | prop="isQuality" |
| | | width="100"> |
| | | prop="isQuality"> |
| | | <template #default="scope"> |
| | | {{scope.row.isQuality ? "是" : "否"}} |
| | | <el-tag :type="scope.row.isQuality ? 'success' : 'danger'"> |
| | | {{scope.row.isQuality ? '是' : '否' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" |
| | |
| | | size="small" |
| | | @click="handleEdit(scope.row)" |
| | | :disabled="scope.row.isComplete">编辑</el-button> |
| | | <!-- <el-button type="info" |
| | | link |
| | | size="small" |
| | | @click="handleViewParams(scope.row)">参数列表</el-button> --> |
| | | <el-button type="danger" |
| | | link |
| | | size="small" |
| | |
| | | </div> |
| | | <!-- 产品信息 --> |
| | | <div class="card-content"> |
| | | <div v-if="item.productName" |
| | | class="product-info"> |
| | | <div class="product-name">{{ item.productName }}</div> |
| | | <div v-if="item.model" |
| | | class="product-model"> |
| | | {{ item.model }} |
| | | <!-- <span v-if="item.unit" class="product-unit">{{ item.unit }}</span> --> |
| | | </div> |
| | | <el-tag type="primary" |
| | | class="product-tag" |
| | | v-if="item.isQuality">质检</el-tag> |
| | | </div> |
| | | <div v-else |
| | | class="product-info empty">暂无产品信息</div> |
| | | </div> |
| | | <!-- 操作按钮 --> |
| | | <div class="card-footer"> |
| | |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <div class="section-BOM"> |
| | | <div class="section-header"> |
| | | <div class="section-title">BOM</div> |
| | | </div> |
| | | <div> |
| | | <!-- BOM表格 --> |
| | | <el-table :data="bomTableData" |
| | | border |
| | | :preserve-expanded-content="false" |
| | | :default-expand-all="true" |
| | | style="width: 100%"> |
| | | <el-table-column type="expand"> |
| | | <template #default="props"> |
| | | <el-table :data="props.row.bomList" |
| | | row-key="id" |
| | | default-expand-all |
| | | :tree-props="{children: 'children', hasChildren: 'hasChildren'}" |
| | | style="width: 100%"> |
| | | <el-table-column prop="productName" |
| | | label="产品" /> |
| | | <el-table-column prop="model" |
| | | label="规格" /> |
| | | <el-table-column prop="processName" |
| | | label="消耗工序" /> |
| | | <el-table-column prop="unitQuantity" |
| | | label="单位产出所需数量" /> |
| | | <el-table-column prop="unit" |
| | | label="单位" /> |
| | | </el-table> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="BOM编号" |
| | | prop="bomNo" /> |
| | | <el-table-column label="产品类型" |
| | | prop="dictLabel" /> |
| | | <!-- <el-table-column label="产品编码" |
| | | prop="productCode" /> |
| | | <el-table-column label="产品名称" |
| | | prop="productName" /> |
| | | <el-table-column label="规格型号" |
| | | prop="model" /> --> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | <!-- 新增/编辑弹窗 --> |
| | | <el-dialog v-model="dialogVisible" |
| | | :title="operationType === 'add' ? '新增工艺路线项目' : '编辑工艺路线项目'" |
| | |
| | | :label="process.name" |
| | | :value="process.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="产品名称" |
| | | prop="productModelId"> |
| | | <el-button type="primary" |
| | | @click="showProductSelectDialog = true"> |
| | | {{ form.productName && form.model |
| | | ? `${form.productName} - ${form.model}` |
| | | : '选择产品' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | <el-form-item label="单位" |
| | | prop="unit"> |
| | | <el-input v-model="form.unit" |
| | | :placeholder="form.productModelId ? '根据选择的产品自动带出' : '请先选择产品'" |
| | | clearable |
| | | :disabled="true" /> |
| | | </el-form-item> |
| | | <el-form-item label="是否质检" |
| | | prop="isQuality"> |
| | |
| | | sortRouteItem, |
| | | } from "@/api/productionManagement/productProcessRoute.js"; |
| | | import { processList } from "@/api/productionManagement/productionProcess.js"; |
| | | import { queryList } from "@/api/productionManagement/productStructure.js"; |
| | | import { useRoute } from "vue-router"; |
| | | import { ElMessageBox, ElMessage } from "element-plus"; |
| | | import Sortable from "sortablejs"; |
| | |
| | | productName: "", |
| | | model: "", |
| | | bomNo: "", |
| | | dictLabel: "", |
| | | bomId: null, |
| | | description: "", |
| | | }); |
| | |
| | | const showParamListDialog = ref(false); |
| | | const currentProcess = ref(null); |
| | | const paramList = ref([]); |
| | | const bomTableData = ref([]); |
| | | let tableSortable = null; |
| | | let cardSortable = null; |
| | | |
| | |
| | | |
| | | const rules = { |
| | | processId: [{ required: true, message: "请选择工序", trigger: "change" }], |
| | | productModelId: [ |
| | | { required: true, message: "请选择产品", trigger: "change" }, |
| | | ], |
| | | }; |
| | | |
| | | // 根据工序ID获取工序名称 |
| | |
| | | productName: route.query.productName || "", |
| | | model: route.query.model || "", |
| | | bomNo: route.query.bomNo || "", |
| | | dictLabel: route.query.dictLabel || "", |
| | | bomId: route.query.bomId || null, |
| | | description: route.query.description || "", |
| | | }; |
| | | |
| | | // 如果有bomId,获取BOM数据 |
| | | if (routeInfo.value.bomId) { |
| | | queryList(routeInfo.value.bomId) |
| | | .then(res => { |
| | | if (res.data) { |
| | | bomTableData.value = [ |
| | | { |
| | | bomNo: routeInfo.value.bomNo, |
| | | dictLabel: routeInfo.value.dictLabel, |
| | | productCode: "", |
| | | productName: routeInfo.value.productName, |
| | | model: routeInfo.value.model, |
| | | bomList: res.data, |
| | | }, |
| | | ]; |
| | | } |
| | | }) |
| | | .catch(err => { |
| | | console.error("获取BOM数据失败:", err); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // 新增 |
| | |
| | | <style scoped> |
| | | .card-container { |
| | | padding: 20px 0; |
| | | /* height: 350px; */ |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .cards-wrapper { |
| | |
| | | opacity: 0.8; |
| | | } |
| | | |
| | | /* 表格视图样式 */ |
| | | :deep(.el-table__row) { |
| | | /* 表格视图样式 - 仅应用于项目列表 */ |
| | | :deep(.lims-table .el-table__row) { |
| | | transition: background-color 0.2s; |
| | | cursor: move; |
| | | } |
| | | |
| | | :deep(.el-table__row:hover) { |
| | | :deep(.lims-table .el-table__row:hover) { |
| | | background-color: #f9fafc !important; |
| | | } |
| | | |
| | |
| | | |
| | | .route-info { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); |
| | | grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); |
| | | gap: 16px; |
| | | padding: 4px; |
| | | } |
| | |
| | | </el-table-column> |
| | | <el-table-column label="BOM编号" |
| | | prop="bomNo" /> |
| | | <el-table-column label="产品编码" |
| | | prop="productCode" /> |
| | | <el-table-column label="产品名称" |
| | | prop="productName" /> |
| | | <el-table-column label="规格型号" |
| | | prop="model" /> |
| | | <el-table-column label="产品类型" |
| | | prop="dictLabel" /> |
| | | </el-table> |
| | | <div v-if="dataValue.isEdit && dataValue.dataList.length == 0" |
| | | style="text-align: center;border: 1px solid #e4e7ed;padding: 10px;transition: all 0.3s ease;cursor: pointer;" |
| | |
| | | |
| | | // 从路由参数获取产品信息 |
| | | const routeBomNo = computed(() => route.query.bomNo || ""); |
| | | const routeProductCode = computed(() => route.query.productCode || ""); |
| | | const routeProductName = computed(() => route.query.productName || ""); |
| | | const routeProductModelName = computed( |
| | | () => route.query.productModelName || "" |
| | | ); |
| | | const routeDictLabel = computed(() => route.query.dictLabel || ""); |
| | | |
| | | const routeOrderId = computed(() => route.query.orderId); |
| | | const pageType = computed(() => route.query.type); |
| | | const isOrderPage = computed( |
| | |
| | | |
| | | const tableData = reactive([ |
| | | { |
| | | productName: "", |
| | | model: "", |
| | | bomNo: "", |
| | | dictLabel: "", |
| | | }, |
| | | ]); |
| | | |
| | |
| | | |
| | | onMounted(async () => { |
| | | // 从路由参数回显数据 |
| | | tableData[0].productName = routeProductName.value as string; |
| | | tableData[0].model = routeProductModelName.value as string; |
| | | tableData[0].bomNo = routeBomNo.value as string; |
| | | tableData[0].dictLabel = routeDictLabel.value as string; |
| | | |
| | | // 订单情况下禁用编辑 |
| | | if (isOrderPage.value) { |
| | |
| | | query: { |
| | | id: row.id, |
| | | bomNo: row.bomNo || "", |
| | | productName: row.productName || "", |
| | | productModelName: row.productModelName || "", |
| | | dictLabel: row.dictLabel || "", |
| | | }, |
| | | }); |
| | | }; |