zhangwencui
10 小时以前 de4e098a962e8403d9b32590f0acba025b8072f6
一些修改
已修改12个文件
1207 ■■■■ 文件已修改
src/views/basicData/product/ProductSelectDialog.vue 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/product/index.vue 76 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/New.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Subtract.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/processRoute/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/Detail/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/StructureEdit.vue 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/New.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionPlan/productionPlan/index.vue 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionPlan/summaryByProduct/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/metricBinding/index.vue 968 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/product/ProductSelectDialog.vue
@@ -8,14 +8,14 @@
             :model="query"
             class="mb-2 search-form">
      <el-form-item label="产品名称">
        <el-input v-model="query.materialName"
        <el-input v-model="query.productName"
                  size="small"
                  placeholder="输入产品名称"
                  clearable
                  @keyup.enter="onSearch" />
      </el-form-item>
      <el-form-item label="规格">
        <el-input v-model="query.specification"
        <el-input v-model="query.model"
                  size="small"
                  placeholder="输入规格"
                  clearable
@@ -42,7 +42,7 @@
              :data="tableData"
              height="420"
              highlight-current-row
              row-key="skuId"
              row-key="id"
              @selection-change="handleSelectionChange"
              @select="handleSelect">
      <el-table-column type="selection"
@@ -50,16 +50,16 @@
      <el-table-column type="index"
                       label="序号"
                       width="60" />
      <el-table-column prop="materialName"
      <el-table-column prop="productName"
                       label="产品名称"
                       min-width="160" />
      <el-table-column prop="materialCode"
                       label="物料编码"
                       min-width="200" />
      <el-table-column prop="specification"
      <el-table-column prop="model"
                       label="规格"
                       min-width="200" />
      <el-table-column prop="baseUnit"
      <el-table-column prop="unit"
                       label="单位"
                       min-width="160" />
    </el-table>
@@ -90,11 +90,11 @@
  import { modelListPage } from "@/api/basicData/newProduct";
  export type ProductRow = {
    skuId: number;
    specification: string;
    id: number;
    model: string;
    materialCode: string;
    baseUnit?: string;
    materialName?: string;
    unit?: string;
    productName?: string;
  };
  const props = defineProps<{
@@ -110,9 +110,9 @@
  });
  const query = reactive({
    specification: "",
    model: "",
    materialCode: "",
    materialName: "",
    productName: "",
  });
  const page = reactive({
@@ -157,7 +157,7 @@
        nextTick(() => {
          if (tableRef.value) {
            tableData.value.forEach(item => {
              if (item.skuId !== row.skuId) {
              if (item.id !== row.id) {
                tableRef.value.toggleRowSelection(item, false);
              }
            });
@@ -173,9 +173,9 @@
  }
  function onReset() {
    query.specification = "";
    query.model = "";
    query.materialCode = "";
    query.materialName = "";
    query.productName = "";
    page.pageNum = 1;
    loadData();
  }
@@ -205,9 +205,9 @@
    try {
      multipleSelection.value = []; // 翻页/搜索后清空选择更符合预期
      const res: any = await modelListPage({
        specification: query.specification.trim(),
        model: query.model.trim(),
        materialCode: query.materialCode.trim(),
        materialName: query.materialName.trim(),
        productName: query.productName.trim(),
        type: 1,
        current: page.pageNum,
        size: page.pageSize,
src/views/basicData/product/index.vue
@@ -84,7 +84,7 @@
        </el-button>
        <ImportExcel :product-id="currentId"
                     @uploadSuccess="getModelList" />
        <el-input v-model="specification"
        <el-input v-model="model"
                  placeholder="规格型号"
                  style="width: 150px"
                  clearable
@@ -121,8 +121,8 @@
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="产品名称:"
                          prop="materialName">
              <el-input v-model="form.materialName"
                          prop="productName">
              <el-input v-model="form.productName"
                        placeholder="请输入产品名称"
                        maxlength="20"
                        show-word-limit
@@ -168,8 +168,8 @@
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="基本单位:"
                          prop="baseUnit">
              <el-input v-model="form.baseUnit"
                          prop="unit">
              <el-input v-model="form.unit"
                        placeholder="请输入基本单位"
                        clearable
                        @keydown.enter.prevent />
@@ -210,8 +210,8 @@
        <el-row>
          <el-col :span="24">
            <el-form-item label="规格型号:"
                          prop="specification">
              <el-input v-model="modelForm.specification"
                          prop="model">
              <el-input v-model="modelForm.model"
                        placeholder="请输入规格型号"
                        clearable
                        @keydown.enter.prevent />
@@ -327,7 +327,7 @@
  const expandedKeys = ref([]);
  const inventoryCategoryList = ref([]);
  const materialTypeList = ref([]);
  const specification = ref("");
  const model = ref("");
  const materialCode = ref("");
  const getloadData = () => {
@@ -374,11 +374,11 @@
  const tableColumn = ref([
    {
      label: "规格型号",
      prop: "materialName",
      prop: "productName",
    },
    {
      label: "规格",
      prop: "specification",
      prop: "model",
    },
    {
      label: "物料编码",
@@ -386,7 +386,7 @@
    },
    {
      label: "单位",
      prop: "baseUnit",
      prop: "unit",
    },
    {
      dataType: "action",
@@ -417,28 +417,28 @@
    form: {
      materialTypeId: null,
      inventoryCategoryId: null,
      materialName: "",
      baseUnit: "",
      productName: "",
      unit: "",
      remark: "",
    },
    rules: {
      materialName: [
      productName: [
        { required: true, message: "请输入", trigger: "blur" },
        { max: 20, message: "产品名称不能超过20个字符", trigger: "blur" },
      ],
      inventoryCategoryId: [
        { required: true, message: "请选择", trigger: "change" },
      ],
      baseUnit: [{ required: true, message: "请输入", trigger: "blur" }],
      unit: [{ required: true, message: "请输入", trigger: "blur" }],
    },
    modelForm: {
      specification: "",
      model: "",
      supplyType: "",
      materialCode: "",
      id: null,
    },
    modelRules: {
      specification: [{ required: true, message: "请输入", trigger: "blur" }],
      model: [{ required: true, message: "请输入", trigger: "blur" }],
      supplyType: [{ required: true, message: "请选择", trigger: "change" }],
      materialCode: [{ required: true, message: "请输入", trigger: "blur" }],
    },
@@ -494,7 +494,7 @@
    treeLoad.value = true;
    // 调用 productTreeListQuery 接口进行搜索
    productTreeListQuery({ materialName: search.value })
    productTreeListQuery({ productName: search.value })
      .then(res => {
        // 处理返回的数据
        const newList = [];
@@ -505,11 +505,11 @@
                item.children = (category.materialList || []).map(item => ({
                  id: item.id,
                  isLeaf: true,
                  label: item.materialName,
                  label: item.productName,
                  inventoryCategoryId: item.inventoryCategoryId,
                  materialTypeId: item.materialTypeId,
                  remark: item.remark,
                  baseUnit: item.baseUnit,
                  unit: item.unit,
                }));
                break;
              }
@@ -522,11 +522,11 @@
            //   children: (category.materialList || []).map(item => ({
            //     id: item.id,
            //     isLeaf: true,
            //     label: item.materialName,
            //     label: item.productName,
            //     inventoryCategoryId: item.inventoryCategoryId,
            //     materialTypeId: item.materialTypeId,
            //     remark: item.remark,
            //     baseUnit: item.baseUnit,
            //     unit: item.unit,
            //   })),
            // };
            // newList.push(categoryNode);
@@ -546,18 +546,18 @@
    productDia.value = true;
    // 重置表单
    form.value = {
      materialName: "",
      productName: "",
      inventoryCategoryId: null,
      baseUnit: "",
      unit: "",
      remark: "",
      materialTypeId: null,
    };
    console.log(data);
    if (type === "edit" && data) {
      // 编辑模式,回填数据
      form.value.materialName = data.label || "";
      form.value.productName = data.label || "";
      form.value.inventoryCategoryId = data.inventoryCategoryId || null;
      form.value.baseUnit = data.baseUnit || "";
      form.value.unit = data.unit || "";
      form.value.remark = data.remark || "";
      form.value.materialTypeId = data.materialTypeId || null;
      form.value.id = data.id || null;
@@ -586,16 +586,16 @@
    modelOperationType.value = type;
    modelDia.value = true;
    // 重置所有字段
    modelForm.value.specification = "";
    modelForm.value.model = "";
    modelForm.value.supplyType = "";
    modelForm.value.id = null;
    modelForm.value.materialCode = null;
    if (type === "edit" && data) {
      // 编辑模式,回填数据
      modelForm.value.specification = data.specification || "";
      modelForm.value.model = data.model || "";
      modelForm.value.supplyType = data.supplyType || "";
      modelForm.value.id = data.skuId || null;
      modelForm.value.id = data.id || null;
      modelForm.value.materialCode = data.materialCode || null;
    }
  };
@@ -607,8 +607,8 @@
        // const params = {
        //   materialTypeId: null,
        //   inventoryCategoryId: form.value.inventoryCategoryId,
        //   materialName: form.value.materialName,
        //   baseUnit: form.value.baseUnit,
        //   productName: form.value.productName,
        //   unit: form.value.unit,
        //   remark: form.value.remark,
        // };
@@ -743,11 +743,11 @@
            const children = materialList.map(item => ({
              id: item.id,
              isLeaf: true,
              label: item.materialName,
              label: item.productName,
              inventoryCategoryId: item.inventoryCategoryId,
              materialTypeId: item.materialTypeId,
              remark: item.remark,
              baseUnit: item.baseUnit,
              unit: item.unit,
            }));
            // 更新节点的子节点
            val.children = children;
@@ -775,8 +775,8 @@
      if (valid) {
        // 构建提交参数
        const params = {
          materialId: currentId.value,
          specification: modelForm.value.specification,
          productId: currentId.value,
          model: modelForm.value.model,
          materialCode: modelForm.value.materialCode,
          supplyType: modelForm.value.supplyType,
        };
@@ -821,10 +821,10 @@
    }
    tableLoading.value = true;
    modelListPage({
      materialId: currentId.value,
      productId: currentId.value,
      current: page.current,
      size: page.size,
      specification: specification.value,
      model: model.value,
      materialCode: materialCode.value,
    }).then(res => {
      console.log("res", res);
@@ -837,7 +837,7 @@
  const handleDelete = () => {
    let ids = [];
    if (selectedRows.value.length > 0) {
      ids = selectedRows.value.map(item => item.skuId);
      ids = selectedRows.value.map(item => item.id);
    } else {
      proxy.$modal.msgWarning("请选择数据");
      return;
src/views/inventoryManagement/stockManagement/New.vue
@@ -131,12 +131,12 @@
  const handleProductSelect = async products => {
    if (products && products.length > 0) {
      const product = products[0];
      formState.value.productId = product.skuId;
      formState.value.productName = product.materialName;
      formState.value.productModelName = product.specification;
      formState.value.productId = product.id;
      formState.value.productName = product.productName;
      formState.value.productModelName = product.model;
      formState.value.productModelId = product.skuId;
      formState.value.unit = product.baseUnit;
      formState.value.productModelId = product.id;
      formState.value.unit = product.unit;
      showProductSelectDialog.value = false;
      // 触发表单验证更新
      proxy.$refs["formRef"]?.validateField("productModelId");
src/views/inventoryManagement/stockManagement/Subtract.vue
@@ -143,11 +143,11 @@
    if (products && products.length > 0) {
      const product = products[0];
      console.log(product);
      formState.value.productId = product.skuId;
      formState.value.productName = product.materialName;
      formState.value.productModelName = product.specification;
      formState.value.productModelId = product.skuId;
      formState.value.unit = product.baseUnit;
      formState.value.productId = product.id;
      formState.value.productName = product.productName;
      formState.value.productModelName = product.model;
      formState.value.productModelId = product.id;
      formState.value.unit = product.unit;
      showProductSelectDialog.value = false;
      // 触发表单验证更新
      proxy.$refs["formRef"]?.validateField("productModelId");
src/views/productionManagement/processRoute/index.vue
@@ -783,7 +783,7 @@
      const product = products[0];
      // 先查询BOM列表(必选)
      try {
        const res = await getByModel(product.skuId);
        const res = await getByModel(product.id);
        // 处理返回的BOM数据:可能是数组、对象或包含data字段
        let bomList = [];
        if (Array.isArray(res)) {
@@ -795,9 +795,9 @@
        }
        if (bomList.length > 0) {
          routeForm.productModelId = product.skuId;
          routeForm.productName = product.materialName;
          routeForm.productModelName = product.specification;
          routeForm.productModelId = product.id;
          routeForm.productName = product.productName;
          routeForm.productModelName = product.model;
          routeForm.bomId = undefined; // 重置BOM选择
          bomOptions.value = bomList;
          showProductSelectDialog.value = false;
src/views/productionManagement/productStructure/Detail/index.vue
@@ -148,6 +148,7 @@
    </el-table>
    <product-select-dialog v-if="dataValue.showProductDialog"
                           v-model:model-value="dataValue.showProductDialog"
                           single
                           @confirm="handleProduct" />
  </div>
</template>
@@ -326,6 +327,7 @@
    // 校验函数
    const validateItem = (item: any, isTopLevel = false) => {
      console.log(item, "item");
      // 校验当前项的必填字段
      if (!item.model) {
        ElMessage.error("请选择规格");
src/views/productionManagement/productStructure/StructureEdit.vue
@@ -19,13 +19,10 @@
               @click="cancelEdit"
               style="margin-bottom: 10px">取消
    </el-button>
    <el-table
        :data="tableData"
        border
        :preserve-expanded-content="false"
        style="width: 100%"
    >
    <el-table :data="tableData"
              border
              :preserve-expanded-content="false"
              style="width: 100%">
      <el-table-column type="expand">
        <template #default="props">
          <el-form ref="form"
@@ -154,14 +151,18 @@
          </el-form>
        </template>
      </el-table-column>
      <el-table-column label="产品编码" prop="productCode" />
      <el-table-column label="产品名称" prop="productName" />
      <el-table-column label="规格型号" prop="model" />
      <el-table-column label="单位" prop="unit" />
      <el-table-column label="产品编码"
                       prop="productCode" />
      <el-table-column label="产品名称"
                       prop="productName" />
      <el-table-column label="规格型号"
                       prop="model" />
      <el-table-column label="单位"
                       prop="unit" />
    </el-table>
    <product-select-dialog v-if="dataValue.showProductDialog"
                           v-model:model-value="dataValue.showProductDialog"
                           single
                           @confirm="handleProduct" />
    <template #footer>
      <div class="dialog-footer">
@@ -236,8 +237,8 @@
      model: props.record.model,
      unit: props.record.unit,
      productCode: props.record.productCode,
    }
  ]
    },
  ];
  const openDialog = index => {
    dataValue.currentRowIndex = index;
src/views/productionManagement/productStructure/index.vue
@@ -336,9 +336,9 @@
  const handleProductSelect = products => {
    if (products && products.length > 0) {
      const product = products[0];
      form.value.productModelId = product.skuId;
      form.value.productName = product.materialName;
      form.value.productModelName = product.specification;
      form.value.productModelId = product.id;
      form.value.productName = product.productName;
      form.value.productModelName = product.model;
    }
    showProductSelectDialog.value = false;
  };
src/views/productionManagement/productionOrder/New.vue
@@ -130,13 +130,13 @@
  const handleProductSelect = async products => {
    if (products && products.length > 0) {
      const product = products[0];
      formState.value.productId = product.skuId;
      formState.value.productName = product.materialName;
      formState.value.productModelName = product.specification;
      formState.value.productModelId = product.skuId;
      formState.value.unit = product.baseUnit;
      formState.value.productId = product.id;
      formState.value.productName = product.productName;
      formState.value.productModelName = product.model;
      formState.value.productModelId = product.id;
      formState.value.unit = product.unit;
      showProductSelectDialog.value = false;
      fetchRouteOptions(product.skuId);
      fetchRouteOptions(product.id);
      // 触发表单验证更新
      proxy.$refs["formRef"]?.validateField("productModelId");
    }
src/views/productionPlan/productionPlan/index.vue
@@ -18,7 +18,7 @@
                    @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item label="产品规格:">
          <el-input v-model="searchForm.specification"
          <el-input v-model="searchForm.model"
                    placeholder="请输入"
                    clearable
                    style="width: 160px;"
@@ -102,7 +102,7 @@
        <el-row :gutter="20">
          <el-col :span="10">
            <el-form-item label="产品规格">
              <div class="info-display">{{ mergeForm.specification || '-' }}</div>
              <div class="info-display">{{ mergeForm.model || '-' }}</div>
            </el-form-item>
          </el-col>
          <el-col :span="10">
@@ -251,9 +251,9 @@
                     filterable
                     placeholder="请选择">
            <el-option v-for="item in specificationOptions"
                       :key="item.skuId"
                       :label="item.specification"
                       :value="item.skuId" />
                       :key="item.id"
                       :label="item.model"
                       :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="块数"
@@ -398,7 +398,7 @@
    },
    {
      label: "产品规格",
      prop: "specification",
      prop: "model",
      width: "150px",
      className: "spec-cell",
    },
@@ -549,7 +549,7 @@
            mergeForm.ids = [row.id];
            mergeForm.materialCode = row.materialCode;
            mergeForm.productName = row.productName || "";
            mergeForm.specification = row.specification || "";
            mergeForm.model = row.model || "";
            mergeForm.length = row.length || 0;
            mergeForm.width = row.width || 0;
            mergeForm.height = row.height || 0;
@@ -591,7 +591,7 @@
  const mergeForm = reactive({
    materialCode: "",
    productName: "",
    specification: "",
    model: "",
    length: 0,
    width: 0,
    height: 0,
@@ -632,7 +632,7 @@
    productMaterialId: undefined,
    productMaterialSkuId: undefined,
    productName: "",
    specification: "",
    model: "",
    materialCode: "",
    quantity: 0,
    volume: 0,
@@ -699,7 +699,7 @@
      if (item.materialList && item.materialList.length > 0) {
        newItem.children = item.materialList.map(material => ({
          value: material.id, // 使用material的id作为value
          label: material.materialName, // 使用materialName作为label
          label: material.productName, // 使用materialName作为label
        }));
      }
@@ -712,28 +712,26 @@
    fetchSpecificationOptions(value);
  };
  const fetchSpecificationOptions = materialId => {
  const fetchSpecificationOptions = productId => {
    specificationOptions.value = [];
    if (materialId) {
      modelListPage({ materialId: materialId, size: -1, current: -1 }).then(
        res => {
          specificationOptions.value = res.data.records;
        }
      );
    if (productId) {
      modelListPage({ productId: productId, size: -1, current: -1 }).then(res => {
        specificationOptions.value = res.data.records;
      });
    }
  };
  const handleChangeSpecification = value => {
    form.materialCode = undefined;
    const selectedModel = specificationOptions.value.find(
      item => item.skuId === value
      item => item.id === value
    );
    if (selectedModel) {
      form.materialCode = selectedModel.materialCode;
      // 解析规格字符串获取长宽高
      const specification = selectedModel.specification;
      if (specification) {
        const dimensions = specification.match(/^(\d+)\*(\d+)\*(\d+)$/);
      const model = selectedModel.model;
      if (model) {
        const dimensions = model.match(/^(\d+)\*(\d+)\*(\d+)$/);
        if (dimensions && dimensions.length === 4) {
          form.length = parseInt(dimensions[1]);
          form.width = parseInt(dimensions[2]);
@@ -818,7 +816,7 @@
    searchForm: {
      customerName: "",
      productName: "",
      specification: "",
      model: "",
      materialCode: "",
      applyNo: "",
      dateRange: [],
@@ -838,7 +836,7 @@
    Object.assign(searchForm.value, {
      customerName: "",
      productName: "",
      specification: "",
      model: "",
      materialCode: "",
      applyNo: "",
      dateRange: [],
@@ -955,7 +953,7 @@
    const firstRow = selectedRows.value[0];
    mergeForm.materialCode = selectedserialNo.value;
    mergeForm.productName = firstRow.productName || "";
    mergeForm.specification = firstRow.specification || "";
    mergeForm.model = firstRow.model || "";
    mergeForm.length = firstRow.length || 0;
    mergeForm.width = firstRow.width || 0;
    mergeForm.height = firstRow.height || 0;
@@ -1091,7 +1089,7 @@
      productName: "",
      productMaterialId: undefined,
      productMaterialSkuId: undefined,
      specification: "",
      model: "",
      materialCode: "",
      quantity: 0,
      volume: 0,
@@ -1118,7 +1116,7 @@
      productName: row.productName || "",
      productMaterialId: row.productMaterialId || undefined,
      productMaterialSkuId: row.productMaterialSkuId || undefined,
      specification: row.specification || "",
      model: row.model || "",
      materialCode: row.materialCode || "",
      quantity: row.quantity || 0,
      volume: row.volume || 0,
src/views/productionPlan/summaryByProduct/index.vue
@@ -54,7 +54,7 @@
    },
    {
      label: "产品规格",
      prop: "specification",
      prop: "model",
      className: "spec-cell",
    },
    {
src/views/qualityManagement/metricBinding/index.vue
@@ -1,540 +1,578 @@
<template>
  <div class="app-container metric-binding">
    <el-row :gutter="16" class="metric-binding-row">
    <el-row :gutter="16"
            class="metric-binding-row">
      <!-- 左侧:检测标准列表 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="14" :xl="14" class="left-col">
      <el-col :xs="24"
              :sm="24"
              :md="12"
              :lg="14"
              :xl="14"
              class="left-col">
        <div class="panel left-panel">
      <PIMTable
        rowKey="id"
        :column="standardColumns"
        :tableData="standardTableData"
        :page="page"
        :isSelection="false"
        :rowClassName="rowClassNameCenter"
        :tableLoading="tableLoading"
        :rowClick="handleTableRowClick"
        @pagination="handlePagination"
        :total="page.total"
      >
        <template #standardNoCell="{ row }">
          <span class="clickable-link" @click="handleStandardRowClick(row)">
            {{ row.standardNo }}
          </span>
        </template>
        <!-- 表头搜索 -->
        <template #standardNoHeader>
          <el-input
            v-model="searchForm.standardNo"
            placeholder="标准编号"
            clearable
            size="small"
            @change="handleQuery"
            @clear="handleQuery"
          />
        </template>
        <template #standardNameHeader>
          <el-input
            v-model="searchForm.standardName"
            placeholder="标准名称"
            clearable
            size="small"
            @change="handleQuery"
            @clear="handleQuery"
          />
        </template>
        <template #inspectTypeHeader>
          <el-select
            v-model="searchForm.inspectType"
            placeholder="类别"
            clearable
            size="small"
            style="width: 120px"
            @change="handleQuery"
            @clear="handleQuery"
          >
            <el-option label="原材料检验" value="0" />
            <el-option label="过程检验" value="1" />
            <el-option label="出厂检验" value="2" />
          </el-select>
        </template>
        <template #stateHeader>
          <el-select
            v-model="searchForm.state"
            placeholder="状态"
            clearable
            size="small"
            style="width: 110px"
            @change="handleQuery"
            @clear="handleQuery"
          >
            <el-option label="草稿" value="0" />
            <el-option label="通过" value="1" />
            <el-option label="撤销" value="2" />
          </el-select>
        </template>
      </PIMTable>
          <PIMTable rowKey="id"
                    :column="standardColumns"
                    :tableData="standardTableData"
                    :page="page"
                    :isSelection="false"
                    :rowClassName="rowClassNameCenter"
                    :tableLoading="tableLoading"
                    :rowClick="handleTableRowClick"
                    @pagination="handlePagination"
                    :total="page.total">
            <template #standardNoCell="{ row }">
              <span class="clickable-link"
                    @click="handleStandardRowClick(row)">
                {{ row.standardNo }}
              </span>
            </template>
            <!-- 表头搜索 -->
            <template #standardNoHeader>
              <el-input v-model="searchForm.standardNo"
                        placeholder="标准编号"
                        clearable
                        size="small"
                        @change="handleQuery"
                        @clear="handleQuery" />
            </template>
            <template #standardNameHeader>
              <el-input v-model="searchForm.standardName"
                        placeholder="标准名称"
                        clearable
                        size="small"
                        @change="handleQuery"
                        @clear="handleQuery" />
            </template>
            <template #inspectTypeHeader>
              <el-select v-model="searchForm.inspectType"
                         placeholder="类别"
                         clearable
                         size="small"
                         style="width: 120px"
                         @change="handleQuery"
                         @clear="handleQuery">
                <el-option label="原材料检验"
                           value="0" />
                <el-option label="过程检验"
                           value="1" />
                <el-option label="出厂检验"
                           value="2" />
              </el-select>
            </template>
            <template #stateHeader>
              <el-select v-model="searchForm.state"
                         placeholder="状态"
                         clearable
                         size="small"
                         style="width: 110px"
                         @change="handleQuery"
                         @clear="handleQuery">
                <el-option label="草稿"
                           value="0" />
                <el-option label="通过"
                           value="1" />
                <el-option label="撤销"
                           value="2" />
              </el-select>
            </template>
          </PIMTable>
        </div>
      </el-col>
      <!-- 右侧:绑定列表 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="10" :xl="10" class="right-col">
      <el-col :xs="24"
              :sm="24"
              :md="12"
              :lg="10"
              :xl="10"
              class="right-col">
        <div class="panel right-panel">
      <div class="right-header">
        <div class="title">绑定关系</div>
        <div class="desc" v-if="currentStandard">
          当前检测标准编号:<span class="link-text">{{ currentStandard.standardNo }}</span>
        </div>
        <div class="desc" v-else>请选择左侧检测标准</div>
      </div>
      <div class="right-toolbar">
        <el-button type="primary" :disabled="!currentStandard" @click="openBindingDialog">添加绑定</el-button>
        <el-button type="danger" plain :disabled="!currentStandard" @click="handleBatchUnbind">删除</el-button>
      </div>
      <el-table
        v-loading="bindingLoading"
        :data="bindingTableData"
        border
        :row-class-name="() => 'row-center'"
        class="center-table"
        style="width: 100%"
        height="calc(100vh - 220px)"
        @selection-change="handleBindingSelectionChange"
      >
        <el-table-column type="selection" width="48" align="center" />
        <el-table-column type="index" label="序号" width="60" align="center" />
        <el-table-column prop="productName" label="产品名称" min-width="140" />
        <el-table-column label="操作" width="120" fixed="right" align="center">
          <template #default="{ row }">
            <el-button link type="danger" size="small" @click="handleUnbind(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
          <div class="right-header">
            <div class="title">绑定关系</div>
            <div class="desc"
                 v-if="currentStandard">
              当前检测标准编号:<span class="link-text">{{ currentStandard.standardNo }}</span>
            </div>
            <div class="desc"
                 v-else>请选择左侧检测标准</div>
          </div>
          <div class="right-toolbar">
            <el-button type="primary"
                       :disabled="!currentStandard"
                       @click="openBindingDialog">添加绑定</el-button>
            <el-button type="danger"
                       plain
                       :disabled="!currentStandard"
                       @click="handleBatchUnbind">删除</el-button>
          </div>
          <el-table v-loading="bindingLoading"
                    :data="bindingTableData"
                    border
                    :row-class-name="() => 'row-center'"
                    class="center-table"
                    style="width: 100%"
                    height="calc(100vh - 220px)"
                    @selection-change="handleBindingSelectionChange">
            <el-table-column type="selection"
                             width="48"
                             align="center" />
            <el-table-column type="index"
                             label="序号"
                             width="60"
                             align="center" />
            <el-table-column prop="productName"
                             label="产品名称"
                             min-width="140" />
            <el-table-column label="操作"
                             width="120"
                             fixed="right"
                             align="center">
              <template #default="{ row }">
                <el-button link
                           type="danger"
                           size="small"
                           @click="handleUnbind(row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-col>
    </el-row>
    <!-- 添加绑定弹框 -->
    <el-dialog
      v-model="bindingDialogVisible"
      title="添加绑定"
      width="520px"
      @close="closeBindingDialog"
    >
    <el-dialog v-model="bindingDialogVisible"
               title="添加绑定"
               width="520px"
               @close="closeBindingDialog">
      <el-form label-width="100px">
        <el-form-item label="产品">
          <el-tree-select
            v-model="selectedProductIds"
            multiple
            collapse-tags
            collapse-tags-tooltip
            placeholder="请选择产品(可多选)"
            clearable
            check-strictly
            :data="productOptions"
            :render-after-expand="false"
            style="width: 100%"
          />
          <el-button type="primary"
                     @click="openProductSelectDialog">选择产品</el-button>
          <div class="selected-products mt-2"
               v-if="selectedProducts.length > 0">
            <el-tag v-for="product in selectedProducts"
                    :key="product.id"
                    closable
                    @close="removeSelectedProduct(product.id)"
                    class="mr-2 mb-2">
              {{ product.productName }} - {{ product.model }}
            </el-tag>
          </div>
          <div v-else
               class="text-gray-400"></div>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="closeBindingDialog">取消</el-button>
          <el-button type="primary" @click="submitBinding">确定</el-button>
          <el-button type="primary"
                     :disabled="selectedProducts.length === 0"
                     @click="submitBinding">确定</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 产品选择对话框 -->
    <ProductSelectDialog v-model="productSelectDialogVisible"
                         :single="false"
                         @confirm="handleProductSelect" />
  </div>
</template>
<script setup>
import { Search } from '@element-plus/icons-vue'
import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
import { ElMessageBox } from 'element-plus'
import PIMTable from '@/components/PIMTable/PIMTable.vue'
import { productTreeList } from '@/api/basicData/product.js'
import {
  qualityTestStandardListPage
} from '@/api/qualityManagement/metricMaintenance.js'
import { productProcessListPage } from '@/api/basicData/productProcess.js'
import {
  qualityTestStandardBindingList,
  qualityTestStandardBindingAdd,
  qualityTestStandardBindingDel
} from '@/api/qualityManagement/qualityTestStandardBinding.js'
  import { Search } from "@element-plus/icons-vue";
  import { ref, reactive, toRefs, onMounted, getCurrentInstance } from "vue";
  import { ElMessageBox, ElMessage } from "element-plus";
  import PIMTable from "@/components/PIMTable/PIMTable.vue";
  import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
  import { qualityTestStandardListPage } from "@/api/qualityManagement/metricMaintenance.js";
  import { productProcessListPage } from "@/api/basicData/productProcess.js";
  import {
    qualityTestStandardBindingList,
    qualityTestStandardBindingAdd,
    qualityTestStandardBindingDel,
  } from "@/api/qualityManagement/qualityTestStandardBinding.js";
const { proxy } = getCurrentInstance()
  const { proxy } = getCurrentInstance();
// 左侧标准列表:整行内容居中(配合样式)
const rowClassNameCenter = () => 'row-center'
  // 左侧标准列表:整行内容居中(配合样式)
  const rowClassNameCenter = () => "row-center";
const data = reactive({
  searchForm: {
    standardNo: '',
    standardName: '',
    state: '',
    inspectType: ''
  }
})
const { searchForm } = toRefs(data)
  const data = reactive({
    searchForm: {
      standardNo: "",
      standardName: "",
      state: "",
      inspectType: "",
    },
  });
  const { searchForm } = toRefs(data);
// 左侧
const standardTableData = ref([])
const tableLoading = ref(false)
const page = reactive({ current: 1, size: 10, total: 0 })
  // 左侧
  const standardTableData = ref([]);
  const tableLoading = ref(false);
  const page = reactive({ current: 1, size: 10, total: 0 });
// 工序下拉(用于列表回显)
const processOptions = ref([])
  // 工序下拉(用于列表回显)
  const processOptions = ref([]);
const getProcessList = async () => {
  try {
    const res = await productProcessListPage({ current: 1, size: 1000 })
    if (res?.code === 200) {
      const records = res?.data?.records || []
      processOptions.value = records.map((item) => ({
        label: item.processName || item.name || item.label,
        value: item.id || item.processId || item.value
      }))
  const getProcessList = async () => {
    try {
      const res = await productProcessListPage({ current: 1, size: 1000 });
      if (res?.code === 200) {
        const records = res?.data?.records || [];
        processOptions.value = records.map(item => ({
          label: item.processName || item.name || item.label,
          value: item.id || item.processId || item.value,
        }));
      }
    } catch (error) {
      console.error("获取工序列表失败:", error);
    }
  } catch (error) {
    console.error('获取工序列表失败:', error)
  }
}
  };
const standardColumns = ref([
  { label: '标准编号', prop: 'standardNo', dataType: 'slot', slot: 'standardNoCell', minWidth: 160, align: 'center', headerSlot: 'standardNoHeader' },
  { label: '标准名称', prop: 'standardName', minWidth: 180, align: 'center', headerSlot: 'standardNameHeader' },
  {
    label: '类别',
    prop: 'inspectType',
    headerSlot: 'inspectTypeHeader',
    align: 'center',
    dataType: 'tag',
    formatData: (val) => {
      const map = { 0: '原材料检验', 1: '过程检验', 2: '出厂检验' }
      return map[val] || val
    }
  },
  {
    label: '工序',
    prop: 'processId',
    align: 'center',
    dataType: 'tag',
    formatData: (val) => {
      const target = processOptions.value.find(
        (item) => String(item.value) === String(val)
      )
      return target?.label || val
    }
  },
  {
    label: '备注',
    prop: 'remark',
    minWidth: 160,
    align: 'center'
  }
  // {
  //   label: '状态',
  //   prop: 'state',
  //   headerSlot: 'stateHeader',
  //   dataType: 'tag',
  //   formatData: (val) => {
  //     const map = { 0: '草稿', 1: '通过', 2: '撤销' }
  //     return map[val] || val
  //   },
  //   formatType: (val) => {
  //     if (val == 1) return 'success'
  //     if (val == 2) return 'warning'
  //     return 'info'
  //   }
  // }
])
  const standardColumns = ref([
    {
      label: "标准编号",
      prop: "standardNo",
      dataType: "slot",
      slot: "standardNoCell",
      minWidth: 160,
      align: "center",
      headerSlot: "standardNoHeader",
    },
    {
      label: "标准名称",
      prop: "standardName",
      minWidth: 180,
      align: "center",
      headerSlot: "standardNameHeader",
    },
    {
      label: "类别",
      prop: "inspectType",
      headerSlot: "inspectTypeHeader",
      align: "center",
      dataType: "tag",
      formatData: val => {
        const map = { 0: "原材料检验", 1: "过程检验", 2: "出厂检验" };
        return map[val] || val;
      },
    },
    {
      label: "工序",
      prop: "processId",
      align: "center",
      dataType: "tag",
      formatData: val => {
        const target = processOptions.value.find(
          item => String(item.value) === String(val)
        );
        return target?.label || val;
      },
    },
    {
      label: "备注",
      prop: "remark",
      minWidth: 160,
      align: "center",
    },
    // {
    //   label: '状态',
    //   prop: 'state',
    //   headerSlot: 'stateHeader',
    //   dataType: 'tag',
    //   formatData: (val) => {
    //     const map = { 0: '草稿', 1: '通过', 2: '撤销' }
    //     return map[val] || val
    //   },
    //   formatType: (val) => {
    //     if (val == 1) return 'success'
    //     if (val == 2) return 'warning'
    //     return 'info'
    //   }
    // }
  ]);
const currentStandard = ref(null)
  const currentStandard = ref(null);
// 右侧绑定
const bindingTableData = ref([])
const bindingLoading = ref(false)
const bindingSelectedRows = ref([])
const bindingDialogVisible = ref(false)
  // 右侧绑定
  const bindingTableData = ref([]);
  const bindingLoading = ref(false);
  const bindingSelectedRows = ref([]);
  const bindingDialogVisible = ref(false);
// 产品树(用于绑定选择)
const productOptions = ref([])
const selectedProductIds = ref([])
  // 产品选择
  const productSelectDialogVisible = ref(false);
  const selectedProducts = ref([]);
const getProductOptions = async () => {
  // 避免重复请求
  if (productOptions.value?.length) return
  const res = await productTreeList()
  productOptions.value = convertIdToValue(Array.isArray(res) ? res : [])
}
  const openProductSelectDialog = () => {
    productSelectDialogVisible.value = true;
  };
function convertIdToValue(data) {
  return (data || []).map((item) => {
    const { id, children, ...rest } = item
    const newItem = {
      ...rest,
      value: id
    }
    if (children && children.length > 0) {
      newItem.children = convertIdToValue(children)
    }
    return newItem
  })
}
  const handleProductSelect = products => {
    // 合并已选择的产品,避免重复
    const existingIds = new Set(selectedProducts.value.map(p => p.id));
    const newProducts = products.filter(p => !existingIds.has(p.id));
    selectedProducts.value = [...selectedProducts.value, ...newProducts];
  };
const handleQuery = () => {
  page.current = 1
  getStandardList()
}
  const removeSelectedProduct = id => {
    selectedProducts.value = selectedProducts.value.filter(p => p.id !== id);
  };
const handlePagination = (obj) => {
  page.current = obj.page
  page.size = obj.limit
  getStandardList()
}
  const handleQuery = () => {
    page.current = 1;
    getStandardList();
  };
const getStandardList = () => {
  tableLoading.value = true
  qualityTestStandardListPage({
    ...searchForm.value,
    current: page.current,
    size: page.size,
    state: 1
  })
    .then((res) => {
      const records = res?.data?.records || []
      standardTableData.value = records
      page.total = res?.data?.total || records.length
  const handlePagination = obj => {
    page.current = obj.page;
    page.size = obj.limit;
    getStandardList();
  };
  const getStandardList = () => {
    tableLoading.value = true;
    qualityTestStandardListPage({
      ...searchForm.value,
      current: page.current,
      size: page.size,
      state: 1,
    })
    .finally(() => {
      tableLoading.value = false
    })
}
      .then(res => {
        const records = res?.data?.records || [];
        standardTableData.value = records;
        page.total = res?.data?.total || records.length;
      })
      .finally(() => {
        tableLoading.value = false;
      });
  };
// 表格行点击,加载右侧绑定列表
const handleTableRowClick = (row) => {
  currentStandard.value = row
  loadBindingList()
}
  // 表格行点击,加载右侧绑定列表
  const handleTableRowClick = row => {
    currentStandard.value = row;
    loadBindingList();
  };
// 左侧行点击,加载右侧绑定列表(保留用于标准编号列的点击)
const handleStandardRowClick = (row) => {
  currentStandard.value = row
  loadBindingList()
}
  // 左侧行点击,加载右侧绑定列表(保留用于标准编号列的点击)
  const handleStandardRowClick = row => {
    currentStandard.value = row;
    loadBindingList();
  };
const loadBindingList = () => {
  if (!currentStandard.value?.id) {
    bindingTableData.value = []
    return
  }
  bindingLoading.value = true
  qualityTestStandardBindingList({ testStandardId: currentStandard.value.id })
    .then((res) => {
      const base = res?.data || []
      // 将当前标准的工序和备注带到绑定列表中展示
      bindingTableData.value = base.map((item) => ({
        ...item,
        processId: currentStandard.value?.processId,
        remark: currentStandard.value?.remark
      }))
    })
    .finally(() => {
      bindingLoading.value = false
    })
}
  const loadBindingList = () => {
    if (!currentStandard.value?.id) {
      bindingTableData.value = [];
      return;
    }
    bindingLoading.value = true;
    qualityTestStandardBindingList({ testStandardId: currentStandard.value.id })
      .then(res => {
        const base = res?.data || [];
        // 将当前标准的工序和备注带到绑定列表中展示
        bindingTableData.value = base.map(item => ({
          ...item,
          processId: currentStandard.value?.processId,
          remark: currentStandard.value?.remark,
        }));
      })
      .finally(() => {
        bindingLoading.value = false;
      });
  };
const handleBindingSelectionChange = (selection) => {
  bindingSelectedRows.value = selection
}
  const handleBindingSelectionChange = selection => {
    bindingSelectedRows.value = selection;
  };
const openBindingDialog = () => {
  if (!currentStandard.value?.id) return
  selectedProductIds.value = []
  getProductOptions()
  bindingDialogVisible.value = true
}
  const openBindingDialog = () => {
    if (!currentStandard.value?.id) return;
    selectedProducts.value = [];
    bindingDialogVisible.value = true;
  };
const closeBindingDialog = () => {
  bindingDialogVisible.value = false
}
  const closeBindingDialog = () => {
    bindingDialogVisible.value = false;
    selectedProducts.value = [];
  };
const submitBinding = async () => {
  const testStandardId = currentStandard.value?.id
  if (!testStandardId) return
  const ids = (selectedProductIds.value || []).filter(Boolean)
  if (!ids.length) {
    proxy.$message.warning('请选择产品')
    return
  }
  const payload = ids.map((pid) => ({
    productId: pid,
    testStandardId
  }))
  await qualityTestStandardBindingAdd(payload)
  proxy.$message.success('添加成功')
  bindingDialogVisible.value = false
  loadBindingList()
}
  const submitBinding = async () => {
    const testStandardId = currentStandard.value?.id;
    if (!testStandardId) return;
    const ids = (selectedProducts.value || []).map(p => p.id).filter(Boolean);
    if (!ids.length) {
      ElMessage.warning("请选择产品");
      return;
    }
    const payload = ids.map(pid => ({
      productId: pid,
      testStandardId,
    }));
    await qualityTestStandardBindingAdd(payload);
    ElMessage.success("添加成功");
    bindingDialogVisible.value = false;
    selectedProducts.value = [];
    loadBindingList();
  };
const handleUnbind = async (row) => {
  const id = row?.id ?? row?.qualityTestStandardBindingId
  if (id == null || id === '') return
  try {
    await ElMessageBox.confirm('确认删除该绑定?', '提示', { type: 'warning' })
  } catch {
    return
  }
  try {
    await qualityTestStandardBindingDel([id])
    proxy.$message.success('删除成功')
    loadBindingList()
  } catch (err) {
    console.error('删除绑定失败:', err)
    proxy.$message?.error(err?.message || '删除失败')
  }
}
  const handleUnbind = async row => {
    const id = row?.id ?? row?.qualityTestStandardBindingId;
    if (id == null || id === "") return;
    try {
      await ElMessageBox.confirm("确认删除该绑定?", "提示", { type: "warning" });
    } catch {
      return;
    }
    try {
      await qualityTestStandardBindingDel([id]);
      proxy.$message.success("删除成功");
      loadBindingList();
    } catch (err) {
      console.error("删除绑定失败:", err);
      proxy.$message?.error(err?.message || "删除失败");
    }
  };
const handleBatchUnbind = async () => {
  if (!bindingSelectedRows.value.length) {
    proxy.$message.warning('请选择数据')
    return
  }
  const ids = bindingSelectedRows.value
    .map((i) => i?.id ?? i?.qualityTestStandardBindingId)
    .filter((id) => id != null && id !== '')
  if (!ids.length) {
    proxy.$message.warning('选中数据缺少有效 id')
    return
  }
  try {
    await ElMessageBox.confirm('选中的内容将被删除,是否确认删除?', '删除提示', { type: 'warning' })
  } catch {
    return
  }
  try {
    await qualityTestStandardBindingDel(ids)
    proxy.$message.success('删除成功')
    loadBindingList()
  } catch (err) {
    console.error('批量删除绑定失败:', err)
    proxy.$message?.error(err?.message || '删除失败')
  }
}
  const handleBatchUnbind = async () => {
    if (!bindingSelectedRows.value.length) {
      proxy.$message.warning("请选择数据");
      return;
    }
    const ids = bindingSelectedRows.value
      .map(i => i?.id ?? i?.qualityTestStandardBindingId)
      .filter(id => id != null && id !== "");
    if (!ids.length) {
      proxy.$message.warning("选中数据缺少有效 id");
      return;
    }
    try {
      await ElMessageBox.confirm(
        "选中的内容将被删除,是否确认删除?",
        "删除提示",
        { type: "warning" }
      );
    } catch {
      return;
    }
    try {
      await qualityTestStandardBindingDel(ids);
      proxy.$message.success("删除成功");
      loadBindingList();
    } catch (err) {
      console.error("批量删除绑定失败:", err);
      proxy.$message?.error(err?.message || "删除失败");
    }
  };
onMounted(() => {
  getStandardList()
  getProcessList()
})
  onMounted(() => {
    getStandardList();
    getProcessList();
  });
</script>
<style scoped>
.metric-binding {
  padding: 0;
}
  .metric-binding {
    padding: 0;
  }
.metric-binding-row {
  width: 100%;
}
  .metric-binding-row {
    width: 100%;
  }
.metric-binding-row .left-col,
.metric-binding-row .right-col {
  margin-bottom: 16px;
}
  .metric-binding-row .left-col,
  .metric-binding-row .right-col {
    margin-bottom: 16px;
  }
.metric-binding-row .panel {
  background: #ffffff;
  padding: 16px;
  box-sizing: border-box;
  height: 100%;
  min-height: 400px;
}
  .metric-binding-row .panel {
    background: #ffffff;
    padding: 16px;
    box-sizing: border-box;
    height: 100%;
    min-height: 400px;
  }
.left-panel,
.right-panel {
  height: 100%;
}
  .left-panel,
  .right-panel {
    height: 100%;
  }
.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}
  .toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
  }
.toolbar-right {
  flex-shrink: 0;
}
  .toolbar-right {
    flex-shrink: 0;
  }
.right-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 10px;
}
  .right-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 10px;
  }
.right-header .title {
  font-size: 16px;
  font-weight: 600;
}
  .right-header .title {
    font-size: 16px;
    font-weight: 600;
  }
.right-header .desc {
  font-size: 13px;
  color: #666;
}
  .right-header .desc {
    font-size: 13px;
    color: #666;
  }
.right-toolbar {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-bottom: 10px;
}
  .right-toolbar {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-bottom: 10px;
  }
.link-text {
  color: #409eff;
  cursor: default;
}
  .link-text {
    color: #409eff;
    cursor: default;
  }
.clickable-link {
  color: #409eff;
  cursor: pointer;
}
  .clickable-link {
    color: #409eff;
    cursor: pointer;
  }
.clickable-link:hover {
  text-decoration: underline;
}
  .clickable-link:hover {
    text-decoration: underline;
  }
:deep(.row-center td) {
  text-align: center !important;
}
  :deep(.row-center td) {
    text-align: center !important;
  }
/* el-table 表头/内容统一居中(row-class-name 不作用于表头) */
:deep(.center-table .el-table__header-wrapper th .cell) {
  text-align: center !important;
}
:deep(.center-table .el-table__body-wrapper td .cell) {
  text-align: center !important;
}
  /* el-table 表头/内容统一居中(row-class-name 不作用于表头) */
  :deep(.center-table .el-table__header-wrapper th .cell) {
    text-align: center !important;
  }
  :deep(.center-table .el-table__body-wrapper td .cell) {
    text-align: center !important;
  }
/* PIMTable 表头居中 */
:deep(.lims-table .pim-table-header-cell) {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
  /* PIMTable 表头居中 */
  :deep(.lims-table .pim-table-header-cell) {
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }
:deep(.lims-table .pim-table-header-title) {
  text-align: center;
  width: 100%;
}
  :deep(.lims-table .pim-table-header-title) {
    text-align: center;
    width: 100%;
  }
:deep(.lims-table .pim-table-header-extra) {
  width: 100%;
  margin-top: 4px;
}
  :deep(.lims-table .pim-table-header-extra) {
    width: 100%;
    margin-top: 4px;
  }
</style>