spring
14 小时以前 fa4ea8dd99638f58da60ac283186113619cc7e6e
src/views/basicData/product/ProductSelectDialog.vue
@@ -1,28 +1,12 @@
<template>
  <el-dialog
      v-model="visible"
      title="选择产品"
      width="900px"
      destroy-on-close
      :close-on-click-modal="false"
  >
  <el-dialog v-model="visible" title="选择产品" width="900px" destroy-on-close :close-on-click-modal="false">
    <el-form :inline="true" :model="query" class="mb-2">
      <el-form-item label="产品大类">
        <el-input
            v-model="query.productName"
            placeholder="输入产品大类"
            clearable
            @keyup.enter="onSearch"
        />
        <el-input v-model="query.productName" placeholder="输入产品大类" clearable @keyup.enter="onSearch" />
      </el-form-item>
      <el-form-item label="型号名称">
        <el-input
            v-model="query.model"
            placeholder="输入型号名称"
            clearable
            @keyup.enter="onSearch"
        />
        <el-input v-model="query.model" placeholder="输入型号名称" clearable @keyup.enter="onSearch" />
      </el-form-item>
      <el-form-item>
@@ -32,32 +16,19 @@
    </el-form>
    <!-- 列表 -->
    <el-table
        v-loading="loading"
        :data="tableData"
        height="420"
        highlight-current-row
        row-key="id"
        @selection-change="handleSelectionChange"
    >
    <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="index" label="#" width="60"/>
      <el-table-column prop="productName" label="产品大类" min-width="160"/>
      <el-table-column prop="model" label="型号名称" min-width="200"/>
      <el-table-column prop="unit" label="单位" min-width="160"/>
      <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" />
      <el-table-column prop="unit" label="单位" min-width="160" />
    </el-table>
    <div class="mt-3 flex justify-end">
      <el-pagination
          background
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          v-model:page-size="page.pageSize"
          v-model:current-page="page.pageNum"
          :page-sizes="[10, 20, 50, 100]"
          @size-change="onPageChange"
          @current-change="onPageChange"
      />
      <el-pagination background layout="total, sizes, prev, pager, next, jumper" :total="total"
        v-model:page-size="page.pageSize" v-model:current-page="page.pageNum" :page-sizes="[10, 20, 50, 100]"
        @size-change="onPageChange" @current-change="onPageChange" />
    </div>
    <template #footer>
@@ -70,9 +41,9 @@
</template>
<script setup lang="ts">
import {computed, onMounted, reactive, ref, watch} from "vue";
import {ElMessage} from "element-plus";
import {productModelList} from '@/api/basicData/productModel'
import { computed, onMounted, reactive, ref, watch, nextTick } from "vue";
import { ElMessage } from "element-plus";
import { productModelList } from '@/api/basicData/productModel'
export type ProductRow = {
  id: number;
@@ -83,6 +54,7 @@
const props = defineProps<{
  modelValue: boolean;
  single?: boolean; // 是否只能选择一个,默认false(可选择多个)
}>();
const emit = defineEmits(['update:modelValue', 'confirm']);
@@ -105,14 +77,48 @@
const loading = ref(false);
const tableData = ref<ProductRow[]>([]);
const total = ref(0);
const multipleSelection = ref<ProductRow[]>([])
const multipleSelection = ref<ProductRow[]>([]);
const tableRef = ref();
function close() {
  visible.value = false;
}
const handleSelectionChange = (val: ProductRow[]) => {
  multipleSelection.value = val
  if (props.single && val.length > 1) {
    // 如果限制为单个选择,只保留最后一个选中的
    const lastSelected = val[val.length - 1];
    multipleSelection.value = [lastSelected];
    // 清空表格选中状态,然后重新选中最后一个
    nextTick(() => {
      if (tableRef.value) {
        tableRef.value.clearSelection();
        tableRef.value.toggleRowSelection(lastSelected, true);
      }
    });
  } else {
    multipleSelection.value = val;
  }
}
// 处理单个选择
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);
            }
          });
        }
      });
    }
  }
}
function onSearch() {
@@ -136,7 +142,11 @@
    ElMessage.warning("请选择一条产品");
    return;
  }
  emit("confirm", multipleSelection.value);
  if (props.single && multipleSelection.value.length > 1) {
    ElMessage.warning("只能选择一个产品");
    return;
  }
  emit("confirm", props.single ? [multipleSelection.value[0]] : multipleSelection.value);
  close();
}
@@ -144,7 +154,7 @@
  loading.value = true;
  try {
    multipleSelection.value = []; // 翻页/搜索后清空选择更符合预期
    const res = await productModelList({
    const res: any = await productModelList({
      productName: query.productName.trim(),
      model: query.model.trim(),
      current: page.pageNum,
@@ -157,6 +167,13 @@
  }
}
// 监听弹窗打开,重置选择
watch(() => props.modelValue, (visible) => {
  if (visible) {
    multipleSelection.value = [];
  }
});
onMounted(() => {
  loadData()
})