mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-15 19:24:23 +08:00
- 在表概览及新旧侧栏右键菜单接入复制整表入口与确认、进度和刷新反馈 - 按 source_copyN 原子创建目标表并复制列、索引、默认值及全部数据 - 处理 PostgreSQL 生成列、identity/serial 序列校准与失败清理 - 限定安全数据源与连接保护策略,阻止分区表、RLS 及引用型存储引擎 - 加固 MySQL/PostgreSQL 元数据标识符处理并补齐六语种文案 - 增加后端、能力矩阵、菜单接线和国际化回归测试
93 lines
2.5 KiB
TypeScript
93 lines
2.5 KiB
TypeScript
import { message } from 'antd';
|
|
|
|
import { t } from '../i18n';
|
|
import Modal from './common/ResizableDraggableModal';
|
|
|
|
type CopyTableResult = {
|
|
success?: boolean;
|
|
data?: unknown;
|
|
message?: string;
|
|
};
|
|
|
|
type CopyTableBackend = (
|
|
config: unknown,
|
|
dbName: string,
|
|
sourceSchemaName: string,
|
|
sourceTableName: string,
|
|
) => Promise<CopyTableResult>;
|
|
|
|
type ConfirmCopyTableOptions = {
|
|
config: unknown;
|
|
dbName: string;
|
|
sourceSchemaName?: string;
|
|
sourceTableName: string;
|
|
onSuccess?: (targetTableName: string) => void | Promise<void>;
|
|
};
|
|
|
|
const resolveCopyTableBackend = (): CopyTableBackend | null => {
|
|
const runtime = globalThis as typeof globalThis & {
|
|
go?: { app?: { App?: { CopyTable?: CopyTableBackend } } };
|
|
};
|
|
return typeof runtime.go?.app?.App?.CopyTable === 'function'
|
|
? runtime.go.app.App.CopyTable
|
|
: null;
|
|
};
|
|
|
|
export const confirmCopyTable = ({
|
|
config,
|
|
dbName,
|
|
sourceSchemaName = '',
|
|
sourceTableName,
|
|
onSuccess,
|
|
}: ConfirmCopyTableOptions): void => {
|
|
const source = String(sourceTableName || '').trim();
|
|
if (!source) return;
|
|
|
|
Modal.confirm({
|
|
title: t('table_copy.modal.title'),
|
|
content: t('table_copy.modal.content', { source, target: `${source}_copy1` }),
|
|
okText: t('common.confirm'),
|
|
cancelText: t('common.cancel'),
|
|
onOk: async () => {
|
|
const copyTable = resolveCopyTableBackend();
|
|
if (!copyTable) {
|
|
const error = t('table_copy.message.backend_unavailable');
|
|
message.error(error);
|
|
return Promise.reject(new Error(error));
|
|
}
|
|
|
|
const hide = message.loading(t('table_copy.message.loading', { source }), 0);
|
|
try {
|
|
const result = await copyTable(config, dbName, sourceSchemaName, source);
|
|
if (!result?.success) {
|
|
throw new Error(result?.message || t('common.unknown'));
|
|
}
|
|
|
|
const target = String(result.data || '').trim();
|
|
if (!target) {
|
|
throw new Error(t('table_copy.message.target_missing'));
|
|
}
|
|
|
|
message.success(t('table_copy.message.success', { target }));
|
|
if (onSuccess) {
|
|
try {
|
|
await onSuccess(target);
|
|
} catch (error: any) {
|
|
message.warning(t('table_copy.message.refresh_failed', {
|
|
target,
|
|
error: error?.message || String(error),
|
|
}));
|
|
}
|
|
}
|
|
} catch (error: any) {
|
|
message.error(t('table_copy.message.failed', {
|
|
error: error?.message || String(error),
|
|
}));
|
|
return Promise.reject(error);
|
|
} finally {
|
|
hide();
|
|
}
|
|
},
|
|
});
|
|
};
|