mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-19 21:14:21 +08:00
新增连接后上传本地数据到远程的手动入口
This commit is contained in:
@@ -79,6 +79,7 @@ export const Settings: React.FC<{ permission: permissionLevel }> = ({ permission
|
|||||||
}>({ connected: true, type: "sqlite" })
|
}>({ connected: true, type: "sqlite" })
|
||||||
const [pgTestLoading, setPgTestLoading] = useState(false)
|
const [pgTestLoading, setPgTestLoading] = useState(false)
|
||||||
const [pgSwitchLoading, setPgSwitchLoading] = useState(false)
|
const [pgSwitchLoading, setPgSwitchLoading] = useState(false)
|
||||||
|
const [pgUploadLoading, setPgUploadLoading] = useState(false)
|
||||||
|
|
||||||
const permissionTag = useMemo(() => {
|
const permissionTag = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
@@ -360,6 +361,61 @@ export const Settings: React.FC<{ permission: permissionLevel }> = ({ permission
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uploadLocalToRemote = async () => {
|
||||||
|
if (!(window as any).api) return
|
||||||
|
try {
|
||||||
|
const statusRes = await (window as any).api.dbGetStatus()
|
||||||
|
if (!statusRes.success || !statusRes.data?.connected || statusRes.data?.type !== "postgresql") {
|
||||||
|
messageApi.warning(t("settings.database.uploadNeedRemote"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const previewRes = await (window as any).api.dbSyncPreview()
|
||||||
|
if (!previewRes.success || !previewRes.data?.can_sync) {
|
||||||
|
messageApi.error(previewRes.message || previewRes.data?.message || t("settings.database.uploadFailed"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!previewRes.data.need_sync) {
|
||||||
|
messageApi.info(t("settings.database.noNeedUpload"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Modal.confirm({
|
||||||
|
title: t("settings.database.uploadConfirmTitle"),
|
||||||
|
content: t("settings.database.uploadConfirmContent", {
|
||||||
|
localOnly: previewRes.data.local_only || 0,
|
||||||
|
remoteOnly: previewRes.data.remote_only || 0,
|
||||||
|
conflicts: previewRes.data.conflicts?.length || 0,
|
||||||
|
}),
|
||||||
|
okText: t("settings.database.uploadButton"),
|
||||||
|
cancelText: t("common.cancel"),
|
||||||
|
onOk: async () => {
|
||||||
|
setPgUploadLoading(true)
|
||||||
|
try {
|
||||||
|
const applyRes = await (window as any).api.dbSyncApply("keep_local")
|
||||||
|
if (applyRes.success && applyRes.data?.success) {
|
||||||
|
messageApi.success(
|
||||||
|
applyRes.data?.message || t("settings.database.uploadSuccess")
|
||||||
|
)
|
||||||
|
emitDataUpdated("all")
|
||||||
|
await loadAll()
|
||||||
|
} else {
|
||||||
|
messageApi.error(
|
||||||
|
applyRes.data?.message || applyRes.message || t("settings.database.uploadFailed")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
messageApi.error(e?.message || t("settings.database.uploadFailed"))
|
||||||
|
} finally {
|
||||||
|
setPgUploadLoading(false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} catch (e: any) {
|
||||||
|
messageApi.error(e?.message || t("settings.database.uploadFailed"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const currentYear = new Date().getFullYear()
|
const currentYear = new Date().getFullYear()
|
||||||
|
|
||||||
const tabItems = [
|
const tabItems = [
|
||||||
@@ -678,7 +734,17 @@ export const Settings: React.FC<{ permission: permissionLevel }> = ({ permission
|
|||||||
>
|
>
|
||||||
{t("settings.database.switchToSQLite")}
|
{t("settings.database.switchToSQLite")}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={uploadLocalToRemote}
|
||||||
|
loading={pgUploadLoading}
|
||||||
|
disabled={!canAdmin || pgConnectionStatus.type !== "postgresql"}
|
||||||
|
>
|
||||||
|
{t("settings.database.uploadButton")}
|
||||||
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
|
<div style={{ marginTop: "8px", fontSize: "12px", color: "var(--ss-text-secondary)" }}>
|
||||||
|
{t("settings.database.uploadHint")}
|
||||||
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card style={{ backgroundColor: "var(--ss-card-bg)", color: "var(--ss-text-main)" }}>
|
<Card style={{ backgroundColor: "var(--ss-card-bg)", color: "var(--ss-text-main)" }}>
|
||||||
|
|||||||
@@ -205,7 +205,15 @@
|
|||||||
"syncPoint3": "Application restart required after switching database.",
|
"syncPoint3": "Application restart required after switching database.",
|
||||||
"syncPoint4": "Recommended cloud database services: Neon, Supabase, AWS RDS, etc.",
|
"syncPoint4": "Recommended cloud database services: Neon, Supabase, AWS RDS, etc.",
|
||||||
"enterConnectionString": "Please enter PostgreSQL connection string",
|
"enterConnectionString": "Please enter PostgreSQL connection string",
|
||||||
"connectionExample": "Example: postgresql://xxxxxx_xxxxx:xxxxxxxx@xx-xxx.xxx.neon.xxxx/xxxxdxx?sslmode=require"
|
"connectionExample": "Example: postgresql://xxxxxx_xxxxx:xxxxxxxx@xx-xxx.xxx.neon.xxxx/xxxxdxx?sslmode=require",
|
||||||
|
"uploadButton": "Upload Local Data to Remote",
|
||||||
|
"uploadHint": "After connecting remote database, upload and merge local SQLite history into remote.",
|
||||||
|
"uploadNeedRemote": "Please connect to PostgreSQL remote database first",
|
||||||
|
"noNeedUpload": "Local and remote data are already consistent",
|
||||||
|
"uploadConfirmTitle": "Upload local data to remote?",
|
||||||
|
"uploadConfirmContent": "Sync will prefer local data. Detected local-only {{localOnly}}, remote-only {{remoteOnly}}, conflicts {{conflicts}}.",
|
||||||
|
"uploadSuccess": "Local data uploaded to remote",
|
||||||
|
"uploadFailed": "Upload failed"
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"title": "Data Management",
|
"title": "Data Management",
|
||||||
|
|||||||
@@ -205,7 +205,15 @@
|
|||||||
"syncPoint3": "切换数据库后需要重启应用以生效。",
|
"syncPoint3": "切换数据库后需要重启应用以生效。",
|
||||||
"syncPoint4": "建议使用云数据库服务(如 Neon、Supabase、AWS RDS 等)。",
|
"syncPoint4": "建议使用云数据库服务(如 Neon、Supabase、AWS RDS 等)。",
|
||||||
"enterConnectionString": "请输入 PostgreSQL 连接字符串",
|
"enterConnectionString": "请输入 PostgreSQL 连接字符串",
|
||||||
"connectionExample": "示例:postgresql://xxxxxx_xxxxx:xxxxxxxx@xx-xxx.xxx.neon.xxxx/xxxxdxx?sslmode=require"
|
"connectionExample": "示例:postgresql://xxxxxx_xxxxx:xxxxxxxx@xx-xxx.xxx.neon.xxxx/xxxxdxx?sslmode=require",
|
||||||
|
"uploadButton": "上传本地数据到远程",
|
||||||
|
"uploadHint": "连接远程数据库后,可将本地 SQLite 历史数据上传并合并到远程。",
|
||||||
|
"uploadNeedRemote": "请先切换并连接到 PostgreSQL 远程数据库",
|
||||||
|
"noNeedUpload": "本地与远程数据已一致,无需上传",
|
||||||
|
"uploadConfirmTitle": "确认上传本地数据到远程?",
|
||||||
|
"uploadConfirmContent": "将以本地数据为优先进行同步。检测到本地新增 {{localOnly}} 条、远程新增 {{remoteOnly}} 条、冲突 {{conflicts}} 条。",
|
||||||
|
"uploadSuccess": "本地数据已上传到远程",
|
||||||
|
"uploadFailed": "上传失败"
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"title": "数据管理",
|
"title": "数据管理",
|
||||||
|
|||||||
Reference in New Issue
Block a user