WholeProcessPlatform/frontend/src/views/system/ConfigManagement/StationSelectModal.vue
2026-07-15 18:24:05 +08:00

219 lines
4.9 KiB
Vue

<template>
<a-modal
:open="visible"
title="选择测站"
width="1536px"
:footer="null"
:body-style="{ height: '700px', padding: '16px' }"
:destroy-on-close="true"
@cancel="handleClose"
>
<!-- 搜索表单 -->
<a-form layout="inline" class="search-form">
<a-form-item label="名称">
<a-input
v-model:value="searchName"
placeholder="请输入测站名称"
style="width: 180px"
allow-clear
@press-enter="handleSearch"
/>
</a-form-item>
<a-form-item>
<a-button type="primary" @click="handleSearch">查询</a-button>
</a-form-item>
</a-form>
<!-- 表格 -->
<div class="table-wrapper">
<BasicTable
ref="tableRef"
:columns="columns"
:scrollY="460"
:list-url="noAuthGetKendoPage"
:search-params="searchParams"
:transform-data="transformData"
:enable-row-selection="true"
row-key="stcd"
@selection-change="onSelectionChange"
/>
</div>
<!-- 底部按钮 -->
<div class="footer-actions">
<a-button type="primary" :disabled="!selectedRow" @click="handleConfirm">
确认选择
</a-button>
</div>
</a-modal>
<!-- 出库/入库选择弹窗 -->
<a-modal
:open="typeModalVisible"
title="选择类型"
width="400px"
:z-index="2000"
ok-text="确认"
:ok-button-props="{ disabled: selectedType === null }"
@ok="handleTypeConfirm"
@cancel="handleTypeCancel"
>
<a-radio-group v-model:value="selectedType">
<a-radio :value="1">出库</a-radio>
<a-radio :value="2">入库</a-radio>
</a-radio-group>
</a-modal>
</template>
<script lang="ts" setup>
import { ref, computed, watch } from 'vue';
import { noAuthGetKendoPage } from '@/api/select';
import BasicTable from '@/components/BasicTable/index.vue';
interface Props {
visible: boolean;
baseId: string;
}
const props = withDefaults(defineProps<Props>(), {
visible: false,
baseId: ''
});
const emit = defineEmits<{
(e: 'update:visible', value: boolean): void;
(e: 'confirm', data: { record: any; type: number }): void;
}>();
// 搜索
const searchName = ref('');
// 表格
const tableRef = ref();
const selectedRow = ref<any>(null);
// 类型选择
const typeModalVisible = ref(false);
const selectedType = ref<number | null>(null);
const columns = [
{ title: '测站名称', key: 'stnm', dataIndex: 'stnm', width: 200 },
{ title: '测站类型', key: 'sttpName', dataIndex: 'sttpName', width: 200 },
{ title: '水电基地', key: 'baseName', dataIndex: 'baseName', width: 200 },
{ title: '电站名称', key: 'ennm', dataIndex: 'ennm', width: 200 }
];
const searchParams = computed(() => ({
sort: [
{
field: 'ORDER_INDEX',
dir: 'asc'
}
]
}));
const transformData = (res: any) => {
return {
records: res?.data?.data || res?.data || [],
total: res?.data?.total || res?.data?.length || 0
};
};
// 表格选择变更:限制最多只能选一个
const onSelectionChange = (keys: string[], rows: any[]) => {
if (keys.length > 1) {
// 只保留最后选中的那个
const lastKey = keys[keys.length - 1];
const lastRow = rows[rows.length - 1];
tableRef.value.setSelectedRowKeys([lastKey]);
selectedRow.value = lastRow;
} else {
selectedRow.value = rows.length > 0 ? rows[0] : null;
}
};
// 搜索
const handleSearch = () => {
const filters: any[] = [
props.baseId != 'all'
? {
field: 'BASE_ID',
operator: 'eq',
dataType: 'string',
value: props.baseId
}
: null
].filter(Boolean);
if (searchName.value) {
filters.push({
field: 'STNM',
operator: 'contains',
value: searchName.value
});
}
const filter = {
logic: 'and',
filters
};
tableRef.value?.getList(filter);
};
// 弹窗打开时自动请求带参数据
watch(
() => props.visible,
visible => {
if (visible) {
searchName.value = '';
// 等 DOM 更新后自动请求
setTimeout(() => handleSearch(), 0);
}
}
);
// 确认选择 → 弹出类型选择
const handleConfirm = () => {
if (!selectedRow.value) return;
selectedType.value = null;
typeModalVisible.value = true;
};
// 类型确认
const handleTypeConfirm = () => {
if (selectedType.value === null) return;
emit('confirm', {
record: selectedRow.value,
type: selectedType.value
});
typeModalVisible.value = false;
handleClose();
};
// 类型取消
const handleTypeCancel = () => {
typeModalVisible.value = false;
};
// 关闭
const handleClose = () => {
emit('update:visible', false);
};
</script>
<style scoped lang="scss">
.search-form {
margin-bottom: 16px;
padding-bottom: 16px;
border-bottom: 1px solid #f0f0f0;
}
.table-wrapper {
flex: 1;
overflow: hidden;
}
.footer-actions {
margin-top: 16px;
text-align: right;
}
</style>