| | |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="产品名称" prop="productModelId"> |
| | | <el-form-item label="产品名称" prop="selectedProducts"> |
| | | <el-button type="primary" @click="showProductSelectDialog = true"> |
| | | {{ form.productName && form.model |
| | | ? `${form.productName} - ${form.model}` |
| | | : '选择产品' }} |
| | | {{ form.selectedProducts.length ? '重新选择产品' : '选择产品' }} |
| | | </el-button> |
| | | <div v-if="form.selectedProducts.length" class="selected-product-tags"> |
| | | <el-tag |
| | | v-for="product in form.selectedProducts" |
| | | :key="product.id" |
| | | class="selected-product-tag" |
| | | type="info" |
| | | effect="plain" |
| | | > |
| | | {{ product.productName }} - {{ product.model }} |
| | | </el-tag> |
| | | </div> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="单位" prop="unit"> |
| | | <el-input |
| | | v-model="form.unit" |
| | | :placeholder="form.productModelId ? '根据选择的产品自动带出' : '请先选择产品'" |
| | | :placeholder="form.selectedProducts.length === 1 ? '根据选择的产品自动带出' : '多个产品时不展示单个单位'" |
| | | clearable |
| | | :disabled="true" |
| | | /> |
| | |
| | | <ProductSelectDialog |
| | | v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single |
| | | /> |
| | | </div> |
| | | </template> |
| | |
| | | routeId: routeId.value, |
| | | processId: undefined, |
| | | productModelId: undefined, |
| | | productModelIds: "", |
| | | selectedProducts: [], |
| | | productName: "", |
| | | model: "", |
| | | unit: "", |
| | |
| | | |
| | | const rules = { |
| | | processId: [{ required: true, message: '请选择工序', trigger: 'change' }], |
| | | productModelId: [{ required: true, message: '请选择产品', trigger: 'change' }], |
| | | selectedProducts: [{ |
| | | required: true, |
| | | validator: (_, value, callback) => { |
| | | if (Array.isArray(value) && value.length > 0) { |
| | | callback(); |
| | | return; |
| | | } |
| | | callback(new Error('请选择产品')); |
| | | }, |
| | | trigger: 'change', |
| | | }], |
| | | }; |
| | | |
| | | // 根据工序ID获取工序名称 |
| | | const getProcessName = (processId) => { |
| | | if (!processId) return ''; |
| | | const process = processOptions.value.find(p => p.id === processId); |
| | | const process = processOptions.value.find((p) => p.id === processId); |
| | | return process ? process.name : ''; |
| | | }; |
| | | |
| | | // 获取列表 |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const listPromise = |
| | | pageType.value === "order" |
| | | pageType.value === 'order' |
| | | ? findProductProcessRouteItemList({ orderId: orderId.value }) |
| | | : findProcessRouteItemList({ routeId: routeId.value }); |
| | | |
| | | listPromise |
| | | .then(res => { |
| | | .then((res) => { |
| | | tableData.value = res.data || []; |
| | | tableLoading.value = false; |
| | | // 列表加载完成后初始化拖拽排序 |
| | | nextTick(() => { |
| | | initSortable(); |
| | | }); |
| | | }) |
| | | .catch(err => { |
| | | .catch((err) => { |
| | | tableLoading.value = false; |
| | | console.error("获取列表失败:", err); |
| | | proxy?.$modal?.msgError("获取列表失败"); |
| | | console.error('获取列表失败:', err); |
| | | proxy?.$modal?.msgError('获取列表失败'); |
| | | }); |
| | | }; |
| | | |
| | | // 获取工序列表 |
| | | const getProcessList = () => { |
| | | processList({}) |
| | | .then(res => { |
| | | .then((res) => { |
| | | processOptions.value = res.data || []; |
| | | }) |
| | | .catch(err => { |
| | | console.error("获取工序失败:", err); |
| | | .catch((err) => { |
| | | console.error('获取工序失败:', err); |
| | | }); |
| | | }; |
| | | |
| | | // 获取工艺路线详情(从路由参数获取) |
| | | const getRouteInfo = () => { |
| | | routeInfo.value = { |
| | | processRouteCode: route.query.processRouteCode || '', |
| | | productName: route.query.productName || '', |
| | | model: route.query.model || '', |
| | | bomNo: route.query.bomNo || '', |
| | | description: route.query.description || '' |
| | | description: route.query.description || '', |
| | | }; |
| | | }; |
| | | |
| | | // 新增 |
| | | const getEditSelectedProducts = (row) => { |
| | | const idList = String(row.productModelIds || row.productModelId || '') |
| | | .split(',') |
| | | .map((item) => item.trim()) |
| | | .filter(Boolean); |
| | | const nameList = String(row.productName || '') |
| | | .split(',') |
| | | .map((item) => item.trim()); |
| | | const modelList = String(row.model || '') |
| | | .split(',') |
| | | .map((item) => item.trim()); |
| | | |
| | | return idList.map((id, index) => ({ |
| | | id: Number(id) || id, |
| | | productName: nameList[index] || row.productName || '', |
| | | model: modelList[index] || row.model || '', |
| | | unit: row.unit || '', |
| | | })); |
| | | }; |
| | | |
| | | const handleAdd = () => { |
| | | operationType.value = 'add'; |
| | | resetForm(); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // 编辑 |
| | | const handleEdit = (row) => { |
| | | operationType.value = 'edit'; |
| | | const selectedProducts = getEditSelectedProducts(row); |
| | | form.value = { |
| | | id: row.id, |
| | | routeId: routeId.value, |
| | | processId: row.processId, |
| | | productModelId: row.productModelId, |
| | | productName: row.productName || "", |
| | | model: row.model || "", |
| | | unit: row.unit || "", |
| | | productModelIds: row.productModelIds || (row.productModelId ? String(row.productModelId) : ''), |
| | | selectedProducts, |
| | | productName: row.productName || '', |
| | | model: row.model || '', |
| | | unit: row.unit || '', |
| | | isQuality: row.isQuality, |
| | | }; |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // 删除 |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm('确认删除该工艺路线项目?', '提示', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | // 生产订单下使用 productProcessRoute 的删除接口(路由后拼接 id),其它情况使用工艺路线项目批量删除接口 |
| | | const deletePromise = |
| | | pageType.value === 'order' |
| | | ? deleteRouteItem(row.id) |
| | |
| | | .catch(() => {}); |
| | | }; |
| | | |
| | | // 产品选择 |
| | | const handleProductSelect = (products) => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | form.value.productModelId = product.id; |
| | | form.value.productName = product.productName; |
| | | form.value.model = product.model; |
| | | form.value.unit = product.unit || ""; |
| | | const firstProduct = products[0]; |
| | | form.value.selectedProducts = products; |
| | | form.value.productModelIds = products.map((item) => item.id).join(','); |
| | | form.value.productModelId = products.length === 1 ? firstProduct.id : undefined; |
| | | form.value.productName = products.length === 1 ? firstProduct.productName : ''; |
| | | form.value.model = products.length === 1 ? firstProduct.model : ''; |
| | | form.value.unit = products.length === 1 ? (firstProduct.unit || '') : ''; |
| | | showProductSelectDialog.value = false; |
| | | // 触发表单验证 |
| | | formRef.value?.validateField('productModelId'); |
| | | formRef.value?.validateField('selectedProducts'); |
| | | } |
| | | }; |
| | | |
| | | // 提交 |
| | | const handleSubmit = () => { |
| | | formRef.value.validate((valid) => { |
| | | if (valid) { |
| | | if (!valid) { |
| | | return; |
| | | } |
| | | |
| | | submitLoading.value = true; |
| | | |
| | | if (operationType.value === 'add') { |
| | | // 新增:传单个对象,包含dragSort字段 |
| | | // dragSort = 当前列表长度 + 1,表示新增记录排在最后 |
| | | const dragSort = tableData.value.length + 1; |
| | | const isOrderPage = pageType.value === 'order'; |
| | | |
| | |
| | | productRouteId: routeId.value, |
| | | processId: form.value.processId, |
| | | productModelId: form.value.productModelId, |
| | | productModelIds: form.value.productModelIds, |
| | | isQuality: form.value.isQuality, |
| | | dragSort, |
| | | }) |
| | |
| | | routeId: routeId.value, |
| | | processId: form.value.processId, |
| | | productModelId: form.value.productModelId, |
| | | productModelIds: form.value.productModelIds, |
| | | isQuality: form.value.isQuality, |
| | | dragSort, |
| | | }); |
| | |
| | | .finally(() => { |
| | | submitLoading.value = false; |
| | | }); |
| | | } else { |
| | | // 编辑:生产订单下使用 productProcessRoute/updateRouteItem,其它情况使用工艺路线项目更新接口 |
| | | const isOrderPage = pageType.value === 'order'; |
| | | return; |
| | | } |
| | | |
| | | const isOrderPage = pageType.value === 'order'; |
| | | const updatePromise = isOrderPage |
| | | ? addOrUpdateProductProcessRouteItem({ |
| | | id: form.value.id, |
| | | processId: form.value.processId, |
| | | productModelId: form.value.productModelId, |
| | | productModelIds: form.value.productModelIds, |
| | | isQuality: form.value.isQuality, |
| | | }) |
| | | : addOrUpdateProcessRouteItem({ |
| | | routeId: routeId.value, |
| | | processId: form.value.processId, |
| | | productModelId: form.value.productModelId, |
| | | productModelIds: form.value.productModelIds, |
| | | id: form.value.id, |
| | | isQuality: form.value.isQuality, |
| | | }); |
| | |
| | | .finally(() => { |
| | | submitLoading.value = false; |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 重置表单 |
| | | const resetForm = () => { |
| | | form.value = { |
| | | id: undefined, |
| | | routeId: routeId.value, |
| | | processId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | model: "", |
| | | unit: "", |
| | | productModelIds: '', |
| | | selectedProducts: [], |
| | | productName: '', |
| | | model: '', |
| | | unit: '', |
| | | isQuality: false, |
| | | }; |
| | | formRef.value?.resetFields(); |
| | | }; |
| | | |
| | | // 关闭弹窗 |
| | | const closeDialog = () => { |
| | | dialogVisible.value = false; |
| | | resetForm(); |
| | |
| | | margin: 10px 0; |
| | | } |
| | | |
| | | .selected-product-tags { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 8px; |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .selected-product-tag { |
| | | max-width: 100%; |
| | | } |
| | | |
| | | |
| | | .card-footer { |
| | | display: flex; |
| | | justify-content: space-around; |