中兴实强
1.bom加一个引用功能,
2.工艺路线需要修改,bom不必填,选了bom就带入bom信息
已修改1个文件
274 ■■■■■ 文件已修改
src/views/productionManagement/processRoute/New.vue 274 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/processRoute/New.vue
@@ -1,53 +1,54 @@
<template>
  <div>
    <el-dialog
        v-model="isShow"
        title="新增工艺路线"
        width="400"
        @close="closeModal"
      v-model="isShow"
      title="新增工艺路线"
      width="800"
      @close="closeModal"
    >
      <el-form label-width="140px" :model="formState" label-position="top" ref="formRef">
      <el-form ref="formRef" label-width="140px" :model="formState" label-position="top">
        <el-form-item
            label="产品名称"
            prop="productModelId"
            :rules="[
                {
                required: true,
                message: '请选择产品',
                trigger: 'change',
              }
            ]"
          label="产品名称"
          prop="selectedProducts"
          :rules="[
            {
              required: true,
              message: '请选择产品',
              trigger: 'change',
            },
          ]"
        >
          <el-button type="primary" @click="showProductSelectDialog = true">
            {{ formState.productName && formState.productModelName
              ? `${formState.productName} - ${formState.productModelName}`
              : '选择产品' }}
          </el-button>
          <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"
            :rules="[
                {
                required: true,
                message: '请选择BOM',
                trigger: 'change',
              }
            ]"
        >
        <el-form-item label="BOM" prop="bomId">
          <el-select
              v-model="formState.bomId"
              placeholder="请选择BOM"
              clearable
              :disabled="!formState.productModelId || bomOptions.length === 0"
              style="width: 100%"
            v-model="formState.bomId"
            placeholder="请选择BOM"
            clearable
            :disabled="formState.selectedProducts.length !== 1 || 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"
              v-for="item in bomOptions"
              :key="item.id"
              :label="item.bomNo || `BOM-${item.id}`"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
@@ -56,12 +57,10 @@
          <el-input v-model="formState.description" type="textarea" />
        </el-form-item>
      </el-form>
      <!-- 产品选择弹窗 -->
      <ProductSelectDialog
          v-model="showProductSelectDialog"
          @confirm="handleProductSelect"
          single
        v-model="showProductSelectDialog"
        @confirm="handleProductSelect"
      />
      <template #footer>
        <div class="dialog-footer">
@@ -74,9 +73,9 @@
</template>
<script setup>
import {ref, computed, getCurrentInstance} from "vue";
import {add} from "@/api/productionManagement/processRoute.js";
import {getByModel} from "@/api/productionManagement/productBom.js";
import { computed, getCurrentInstance, ref } from "vue";
import { add } from "@/api/productionManagement/processRoute.js";
import { getByModel } from "@/api/productionManagement/productBom.js";
import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
const props = defineProps({
@@ -86,16 +85,20 @@
  },
});
const emit = defineEmits(['update:visible', 'completed']);
const emit = defineEmits(["update:visible", "completed"]);
// 响应式数据(替代选项式的 data)
const formRef = ref();
const showProductSelectDialog = ref(false);
const bomOptions = ref([]);
const formState = ref({
  productId: undefined,
  productModelId: undefined,
  productModelIds: "",
  productName: "",
  productModelName: "",
  selectedProducts: [],
  bomId: undefined,
  description: '',
  description: "",
});
const isShow = computed({
@@ -103,88 +106,117 @@
    return props.visible;
  },
  set(val) {
    emit('update:visible', val);
    emit("update:visible", val);
  },
});
const showProductSelectDialog = ref(false);
const bomOptions = ref([]);
const { proxy } = getCurrentInstance();
let { proxy } = getCurrentInstance()
const closeModal = () => {
  // 重置表单数据
const resetForm = () => {
  formState.value = {
    productId: undefined,
    productModelId: undefined,
    productModelIds: "",
    productName: "",
    productModelName: "",
    selectedProducts: [],
    bomId: undefined,
    description: '',
    description: "",
  };
  bomOptions.value = [];
};
const closeModal = () => {
  resetForm();
  isShow.value = false;
};
// 产品选择处理
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;
        formState.value.bomId = undefined; // 重置BOM选择
        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 loadBomList = async (productModelId) => {
  if (!productModelId) {
    bomOptions.value = [];
    return;
  }
  try {
    const res = await getByModel(productModelId);
    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 handleSubmit = () => {
  proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      // 验证是否选择了产品和BOM
      if (!formState.value.productModelId) {
        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("提交成功");
      })
    }
  })
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 = "";
    bomOptions.value = [];
  }
  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;
    }
    add({
      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.selectedProducts.length === 1 ? formState.value.bomId : undefined,
      description: formState.value.description,
    })
      .then(() => {
        isShow.value = false;
        emit("completed");
        proxy.$modal.msgSuccess("提交成功");
        resetForm();
      })
      .catch(() => {});
  });
};
defineExpose({
  closeModal,
@@ -192,3 +224,23 @@
  isShow,
});
</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>