| | |
| | | <!-- 列表 --> |
| | | <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" /> |
| | |
| | | </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> |
| | |
| | | |
| | | const props = defineProps<{ |
| | | modelValue: boolean; |
| | | single?: boolean; // 是否只能选择一个,默认false(可选择多个) |
| | | single?: boolean; |
| | | }>(); |
| | | |
| | | const emit = defineEmits(['update:modelValue', 'confirm']); |
| | |
| | | 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); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | function onConfirm() { |
| | | if (multipleSelection.value.length === 0) { |
| | | ElMessage.warning("请选择一条产品"); |
| | | ElMessage.warning("请选择产品"); |
| | | return; |
| | | } |
| | | if (props.single && multipleSelection.value.length > 1) { |
| | |
| | | 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(); |
| | | } |
| | | }); |
| | | |