<template>
|
<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-form-item>
|
|
<el-form-item label="型号名称">
|
<el-input
|
v-model="query.model"
|
placeholder="输入型号名称"
|
clearable
|
@keyup.enter="onSearch"
|
/>
|
</el-form-item>
|
|
<el-form-item>
|
<el-button type="primary" @click="onSearch">搜索</el-button>
|
<el-button @click="onReset">重置</el-button>
|
</el-form-item>
|
</el-form>
|
|
<!-- 列表 -->
|
<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>
|
|
<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"
|
/>
|
</div>
|
|
<template #footer>
|
<el-button @click="close()">取消</el-button>
|
<el-button type="primary" :disabled="multipleSelection.length === 0" @click="onConfirm">
|
确定
|
</el-button>
|
</template>
|
</el-dialog>
|
</template>
|
|
<script setup lang="ts">
|
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;
|
productName: string;
|
model: string;
|
unit?: string;
|
};
|
|
const props = defineProps<{
|
modelValue: boolean;
|
single?: boolean; // 是否只能选择一个,默认false(可选择多个)
|
}>();
|
|
const emit = defineEmits(['update:modelValue', 'confirm']);
|
|
const visible = computed({
|
get: () => props.modelValue,
|
set: (v) => emit("update:modelValue", v),
|
});
|
|
const query = reactive({
|
productName: "",
|
model: "",
|
});
|
|
const page = reactive({
|
pageNum: 1,
|
pageSize: 10,
|
});
|
|
const loading = ref(false);
|
const tableData = ref<ProductRow[]>([]);
|
const total = ref(0);
|
const multipleSelection = ref<ProductRow[]>([]);
|
const tableRef = ref();
|
|
function close() {
|
visible.value = false;
|
}
|
|
const handleSelectionChange = (val: ProductRow[]) => {
|
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() {
|
page.pageNum = 1;
|
loadData();
|
}
|
|
function onReset() {
|
query.productName = "";
|
query.model = "";
|
page.pageNum = 1;
|
loadData();
|
}
|
|
function onPageChange() {
|
loadData();
|
}
|
|
function onConfirm() {
|
if (multipleSelection.value.length === 0) {
|
ElMessage.warning("请选择一条产品");
|
return;
|
}
|
if (props.single && multipleSelection.value.length > 1) {
|
ElMessage.warning("只能选择一个产品");
|
return;
|
}
|
emit("confirm", props.single ? [multipleSelection.value[0]] : multipleSelection.value);
|
close();
|
}
|
|
async function loadData() {
|
loading.value = true;
|
try {
|
multipleSelection.value = []; // 翻页/搜索后清空选择更符合预期
|
const res = await productModelList({
|
productName: query.productName.trim(),
|
model: query.model.trim(),
|
current: page.pageNum,
|
size: page.pageSize,
|
});
|
tableData.value = res.records;
|
total.value = res.total;
|
} finally {
|
loading.value = false;
|
}
|
}
|
|
// 监听弹窗打开,重置选择
|
watch(() => props.modelValue, (visible) => {
|
if (visible) {
|
multipleSelection.value = [];
|
}
|
});
|
|
onMounted(() => {
|
loadData()
|
})
|
</script>
|