gaoluyang
18 小时以前 cca940a6460bc4ec4266df4e413b05921d1f2e1d
src/views/basicData/product/ProductSelectDialog.vue
@@ -18,7 +18,7 @@
    <!-- 列表 -->
    <el-table ref="tableRef" v-loading="loading" :data="tableData" height="420" highlight-current-row row-key="id"
      @selection-change="handleSelectionChange" @select="handleSelect">
      <el-table-column type="selection" width="55" />
      <el-table-column type="selection" width="55" :reserve-selection="true" />
      <el-table-column type="index" label="序号" width="60" />
      <el-table-column prop="productName" label="产品大类" min-width="160" />
      <el-table-column prop="model" label="型号名称" min-width="200" />
@@ -32,10 +32,10 @@
    </div>
    <template #footer>
      <el-button @click="close()">取消</el-button>
      <el-button type="primary" :disabled="multipleSelection.length === 0" @click="onConfirm">
        确定
      </el-button>
         <el-button @click="close()">取消</el-button>
    </template>
  </el-dialog>
</template>
@@ -54,7 +54,7 @@
const props = defineProps<{
  modelValue: boolean;
  single?: boolean; // 是否只能选择一个,默认false(可选择多个)
  single?: boolean;
}>();
const emit = defineEmits(['update:modelValue', 'confirm']);
@@ -78,46 +78,68 @@
const tableData = ref<ProductRow[]>([]);
const total = ref(0);
const multipleSelection = ref<ProductRow[]>([]);
const selectedMap = ref<Map<number, ProductRow>>(new Map());
const tableRef = ref();
function close() {
  visible.value = false;
}
function syncCurrentPageSelection() {
  nextTick(() => {
    if (!tableRef.value) {
      return;
    }
    tableData.value.forEach((item) => {
      tableRef.value.toggleRowSelection(item, selectedMap.value.has(item.id));
    });
  });
}
const handleSelectionChange = (val: ProductRow[]) => {
  if (props.single && val.length > 1) {
    // 如果限制为单个选择,只保留最后一个选中的
    const lastSelected = val[val.length - 1];
    multipleSelection.value = [lastSelected];
    // 清空表格选中状态,然后重新选中最后一个
    selectedMap.value = new Map(lastSelected ? [[lastSelected.id, lastSelected]] : []);
    nextTick(() => {
      if (tableRef.value) {
        tableRef.value.clearSelection();
        tableRef.value.toggleRowSelection(lastSelected, true);
        if (lastSelected) {
          tableRef.value.toggleRowSelection(lastSelected, true);
        }
      }
    });
  } else {
    multipleSelection.value = val;
    return;
  }
  const currentPageIds = new Set(tableData.value.map((item) => item.id));
  currentPageIds.forEach((id) => {
    selectedMap.value.delete(id);
  });
  val.forEach((item) => {
    selectedMap.value.set(item.id, item);
  });
  multipleSelection.value = Array.from(selectedMap.value.values());
}
// 处理单个选择
const handleSelect = (selection: ProductRow[], row: ProductRow) => {
  if (props.single) {
    // 如果限制为单个,清空其他选择,只保留当前行
    if (selection.includes(row)) {
      // 选中当前行时,清空其他选中
      multipleSelection.value = [row];
      nextTick(() => {
        if (tableRef.value) {
          tableData.value.forEach((item) => {
            if (item.id !== row.id) {
              tableRef.value.toggleRowSelection(item, false);
            }
          });
        }
      });
    }
  if (!props.single) {
    return;
  }
  if (selection.includes(row)) {
    multipleSelection.value = [row];
    selectedMap.value = new Map([[row.id, row]]);
    nextTick(() => {
      if (tableRef.value) {
        tableData.value.forEach((item) => {
          if (item.id !== row.id) {
            tableRef.value.toggleRowSelection(item, false);
          }
        });
      }
    });
  }
}
@@ -139,7 +161,7 @@
function onConfirm() {
  if (multipleSelection.value.length === 0) {
    ElMessage.warning("请选择一条产品");
    ElMessage.warning("请选择产品");
    return;
  }
  if (props.single && multipleSelection.value.length > 1) {
@@ -153,24 +175,26 @@
async function loadData() {
  loading.value = true;
  try {
    multipleSelection.value = []; // 翻页/搜索后清空选择更符合预期
    const res: any = await productModelList({
      productName: query.productName.trim(),
      model: query.model.trim(),
      current: page.pageNum,
      size: page.pageSize,
    });
    tableData.value = res.records;
    total.value = res.total;
    tableData.value = res.records || [];
    total.value = res.total || 0;
    syncCurrentPageSelection();
  } finally {
    loading.value = false;
  }
}
// 监听弹窗打开,重置选择
watch(() => props.modelValue, (visible) => {
  if (visible) {
    multipleSelection.value = [];
    selectedMap.value = new Map();
    page.pageNum = 1;
    loadData();
  }
});