<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.name" 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>
|
|
<!-- 列表 -->
|
<PIMTable
|
rowKey="id"
|
:column="tableColumn"
|
:tableData="tableData"
|
:page="page"
|
:isSelection="true"
|
:tableLoading="loading"
|
:total="total"
|
@selection-change="handleSelectionChange"
|
@pagination="pagination"
|
@select="handleSelect"
|
/>
|
|
<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 { qualityInspectItemListPage } from "@/api/qualityManagement/inspectItem.js";
|
|
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({
|
name: "",
|
});
|
|
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();
|
|
const tableColumn = ref([
|
{ label: "检测项目", prop: "name" },
|
{ label: "单位", prop: "unit", width: 120 },
|
{ label: "标准值", prop: "standardValue", width: 160 },
|
{ label: "内控值", prop: "internalControl", width: 160 },
|
{ label: "化验值", prop: "testValue", width: 160 },
|
]);
|
|
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.name = "";
|
page.pageNum = 1;
|
loadData();
|
}
|
|
function onPageChange() {
|
loadData();
|
}
|
|
const pagination = (obj) => {
|
page.pageNum = obj.page;
|
page.pageSize = obj.limit;
|
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: any = await qualityInspectItemListPage({
|
name: query.name.trim(),
|
current: page.pageNum,
|
size: page.pageSize,
|
});
|
tableData.value = res.data.records;
|
total.value = res.data.total;
|
} finally {
|
loading.value = false;
|
}
|
}
|
|
// 监听弹窗打开,重置选择
|
watch(() => props.modelValue, (visible) => {
|
if (visible) {
|
multipleSelection.value = [];
|
}
|
});
|
|
onMounted(() => {
|
loadData()
|
})
|
</script>
|