style: 数据管理数据库选择改为弹窗列表
This commit is contained in:
@@ -724,3 +724,9 @@
|
|||||||
- 后端数据库接口新增 `database_source` 参数,`main` 保持原有直连 MySQL / Metrix 仓库逻辑,`cell_data` 使用 `CellData.MySQL_DBInfo` 创建独立 MySQL 仓库。表列表、表结构、分页数据、清空、删除、删除全部、执行 SQL 和导出均按该参数选择数据库。
|
- 后端数据库接口新增 `database_source` 参数,`main` 保持原有直连 MySQL / Metrix 仓库逻辑,`cell_data` 使用 `CellData.MySQL_DBInfo` 创建独立 MySQL 仓库。表列表、表结构、分页数据、清空、删除、删除全部、执行 SQL 和导出均按该参数选择数据库。
|
||||||
- CellData 数据库当前只支持直连 MySQL 配置;Metrix 仓库模式只影响主数据库。
|
- CellData 数据库当前只支持直连 MySQL 配置;Metrix 仓库模式只影响主数据库。
|
||||||
- 验证:`python -m compileall -q app` 通过;`frontend` `npm run build` 通过(仅既有大 chunk 提示);构建产物与 Python 缓存已清理。
|
- 验证:`python -m compileall -q app` 通过;`frontend` `npm run build` 通过(仅既有大 chunk 提示);构建产物与 Python 缓存已清理。
|
||||||
|
|
||||||
|
## 2026-06-25:数据管理数据库选择改为弹窗列表
|
||||||
|
|
||||||
|
- 数据管理页不再用下拉框切换数据库,改为表标题旁的图标按钮打开「选择数据库」弹窗;弹窗内为固定高度列表,超出高度滚动。
|
||||||
|
- 选择项仍来自主数据库与 CellData 数据库配置,后续新增更多数据库时继续扩展同一列表,不占用侧栏宽度。
|
||||||
|
- 验证:`frontend` `npm run build` 通过(仅既有大 chunk 提示);构建产物已清理。
|
||||||
|
|||||||
@@ -5,13 +5,19 @@
|
|||||||
<div class="database-table-pane-header">
|
<div class="database-table-pane-header">
|
||||||
<div class="database-source-header">
|
<div class="database-source-header">
|
||||||
<h2>表</h2>
|
<h2>表</h2>
|
||||||
<n-select
|
<span class="database-source-name">{{ selectedDatabaseSourceLabel }}</span>
|
||||||
v-model:value="selectedDatabaseSource"
|
<n-button
|
||||||
|
quaternary
|
||||||
|
circle
|
||||||
size="small"
|
size="small"
|
||||||
class="database-source-select"
|
aria-label="切换数据库"
|
||||||
:options="databaseSourceOptions"
|
title="切换数据库"
|
||||||
@update:value="switchDatabaseSource"
|
@click="databaseSourceModalVisible = true"
|
||||||
/>
|
>
|
||||||
|
<template #icon>
|
||||||
|
<n-icon><ServerOutline /></n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
<n-button
|
<n-button
|
||||||
quaternary
|
quaternary
|
||||||
@@ -224,17 +230,40 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</n-modal>
|
</n-modal>
|
||||||
|
|
||||||
|
<n-modal
|
||||||
|
v-model:show="databaseSourceModalVisible"
|
||||||
|
preset="card"
|
||||||
|
class="database-source-modal"
|
||||||
|
title="选择数据库"
|
||||||
|
style="width: min(420px, calc(100vw - 32px))"
|
||||||
|
>
|
||||||
|
<n-scrollbar class="database-source-options">
|
||||||
|
<button
|
||||||
|
v-for="option in databaseSourceOptions"
|
||||||
|
:key="String(option.value)"
|
||||||
|
type="button"
|
||||||
|
class="database-source-option"
|
||||||
|
:class="{ active: selectedDatabaseSource === option.value }"
|
||||||
|
@click="switchDatabaseSource(String(option.value))"
|
||||||
|
>
|
||||||
|
<span>{{ option.label }}</span>
|
||||||
|
<span v-if="selectedDatabaseSource === option.value" class="database-source-current">当前</span>
|
||||||
|
</button>
|
||||||
|
</n-scrollbar>
|
||||||
|
</n-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onActivated, onBeforeUnmount, onMounted, ref } from 'vue';
|
import { computed, onActivated, onBeforeUnmount, onMounted, ref } from 'vue';
|
||||||
import { onBeforeRouteLeave } from 'vue-router';
|
import { onBeforeRouteLeave } from 'vue-router';
|
||||||
import { useDialog, useMessage } from 'naive-ui';
|
import { useDialog, useMessage } from 'naive-ui';
|
||||||
import type { DataTableColumns, DropdownOption, SelectOption } from 'naive-ui';
|
import type { DataTableColumns, DropdownOption } from 'naive-ui';
|
||||||
import {
|
import {
|
||||||
ChevronForwardOutline,
|
ChevronForwardOutline,
|
||||||
CloudDownloadOutline,
|
CloudDownloadOutline,
|
||||||
RefreshOutline,
|
RefreshOutline,
|
||||||
|
ServerOutline,
|
||||||
TrashOutline
|
TrashOutline
|
||||||
} from '@vicons/ionicons5';
|
} from '@vicons/ionicons5';
|
||||||
|
|
||||||
@@ -246,13 +275,18 @@ import { resetPageHeader, setPageHeader } from '../composables/pageHeader';
|
|||||||
type RowData = Record<string, unknown>;
|
type RowData = Record<string, unknown>;
|
||||||
type DownloadFormat = 'csv' | 'xlsx';
|
type DownloadFormat = 'csv' | 'xlsx';
|
||||||
type DatabaseSource = 'main' | 'cell_data';
|
type DatabaseSource = 'main' | 'cell_data';
|
||||||
|
interface DatabaseSourceOption {
|
||||||
|
label: string;
|
||||||
|
value: DatabaseSource;
|
||||||
|
}
|
||||||
|
|
||||||
const COLUMN_MIN_WIDTH = 140;
|
const COLUMN_MIN_WIDTH = 140;
|
||||||
const message = useMessage();
|
const message = useMessage();
|
||||||
const dialog = useDialog();
|
const dialog = useDialog();
|
||||||
const databaseInfo = ref<DatabaseInfo | null>(null);
|
const databaseInfo = ref<DatabaseInfo | null>(null);
|
||||||
const selectedDatabaseSource = ref<DatabaseSource>('main');
|
const selectedDatabaseSource = ref<DatabaseSource>('main');
|
||||||
const databaseSourceOptions = ref<SelectOption[]>([
|
const databaseSourceModalVisible = ref(false);
|
||||||
|
const databaseSourceOptions = ref<DatabaseSourceOption[]>([
|
||||||
{ label: '主数据库', value: 'main' },
|
{ label: '主数据库', value: 'main' },
|
||||||
{ label: 'CellData', value: 'cell_data' }
|
{ label: 'CellData', value: 'cell_data' }
|
||||||
]);
|
]);
|
||||||
@@ -275,6 +309,9 @@ const columnSchemaExpanded = ref(false);
|
|||||||
let tableLoadToken = 0;
|
let tableLoadToken = 0;
|
||||||
|
|
||||||
const totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)));
|
const totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)));
|
||||||
|
const selectedDatabaseSourceLabel = computed(() => (
|
||||||
|
databaseSourceOptions.value.find(option => option.value === selectedDatabaseSource.value)?.label || '主数据库'
|
||||||
|
));
|
||||||
const downloading = computed(() => Boolean(downloadingFormat.value));
|
const downloading = computed(() => Boolean(downloadingFormat.value));
|
||||||
const exportButtonText = computed(() => (
|
const exportButtonText = computed(() => (
|
||||||
downloadingFormat.value ? `导出 ${downloadingFormat.value.toUpperCase()}...` : '导出'
|
downloadingFormat.value ? `导出 ${downloadingFormat.value.toUpperCase()}...` : '导出'
|
||||||
@@ -417,7 +454,10 @@ async function loadTables() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function switchDatabaseSource(value: string) {
|
function switchDatabaseSource(value: string) {
|
||||||
selectedDatabaseSource.value = value === 'cell_data' ? 'cell_data' : 'main';
|
const nextSource: DatabaseSource = value === 'cell_data' ? 'cell_data' : 'main';
|
||||||
|
databaseSourceModalVisible.value = false;
|
||||||
|
if (selectedDatabaseSource.value === nextSource) return;
|
||||||
|
selectedDatabaseSource.value = nextSource;
|
||||||
resetTableState();
|
resetTableState();
|
||||||
void testConnection();
|
void testConnection();
|
||||||
void loadTables();
|
void loadTables();
|
||||||
@@ -732,8 +772,48 @@ function formatCell(value: unknown): string {
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.database-source-select {
|
.database-source-name {
|
||||||
width: 150px;
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
color: var(--td-text-color-secondary);
|
||||||
|
font-size: 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.database-source-options {
|
||||||
|
max-height: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.database-source-option {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
color: var(--td-text-color-primary);
|
||||||
|
font: inherit;
|
||||||
|
text-align: left;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid var(--td-border-color-light);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.database-source-option:hover {
|
||||||
|
background: var(--td-bg-color-container-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.database-source-option.active {
|
||||||
|
color: var(--td-brand-color);
|
||||||
|
font-weight: 600;
|
||||||
|
background: var(--td-brand-color-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.database-source-current {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.database-table-list-wrap {
|
.database-table-list-wrap {
|
||||||
|
|||||||
Reference in New Issue
Block a user