feat: 连接相关提示信息国际化

- 右键连接: 成功/失败弹出 ElMessage 提示
- 测试连接: testSuccess/testFailed 替换硬编码
- 保存连接: created/updated/saveFailed 替换硬编码
- 导入/导出: exported/imported/importTitle 替换硬编码
- connection store: serverInfoUnavailable/connectFailed 国际化
- 新增 11 个 i18n key (5 语言): hostRequired, nameHostRequired,
  connectSuccess, connectFailed, created, updated, saveFailed,
  exported, importTitle, imported, serverInfoUnavailable
This commit is contained in:
2026-07-11 22:15:56 +08:00
parent 19b5a3d1d0
commit 0ffe3ae83f
8 changed files with 80 additions and 13 deletions
@@ -31,9 +31,19 @@ function closeCtxMenu() {
ctxMenu.value.visible = false ctxMenu.value.visible = false
} }
function ctxConnect() { async function ctxConnect() {
if (ctxMenu.value.conn) connStore.connect(ctxMenu.value.conn) if (!ctxMenu.value.conn) return
closeCtxMenu() closeCtxMenu()
try {
await connStore.connect(ctxMenu.value.conn)
if (connStore.error) {
ElMessage.error(connStore.error || t('connection.connectFailed'))
} else {
ElMessage.success(t('connection.connectSuccess'))
}
} catch (err: any) {
ElMessage.error(err.message || t('connection.connectFailed'))
}
} }
function ctxDisconnect() { function ctxDisconnect() {
@@ -140,7 +150,7 @@ async function handleExport() {
a.download = `jredis-connections-${new Date().toISOString().slice(0, 10)}.json` a.download = `jredis-connections-${new Date().toISOString().slice(0, 10)}.json`
a.click() a.click()
URL.revokeObjectURL(url) URL.revokeObjectURL(url)
ElMessage.success('Connections exported') ElMessage.success(t('connection.exported'))
} catch (err: any) { } catch (err: any) {
ElMessage.error(err.message) ElMessage.error(err.message)
} }
@@ -149,12 +159,12 @@ async function handleExport() {
async function handleImport() { async function handleImport() {
try { try {
const result = await window.electronAPI.dialog.openFile({ const result = await window.electronAPI.dialog.openFile({
title: 'Import Connections', title: t('connection.importTitle'),
filters: [{ name: 'JSON', extensions: ['json'] }], filters: [{ name: 'JSON', extensions: ['json'] }],
}) })
if (result) { if (result) {
const count = await connStore.importConnections(result.content) const count = await connStore.importConnections(result.content)
ElMessage.success(`Imported ${count} connection(s)`) ElMessage.success(t('connection.imported', { n: count }))
await connStore.loadConnections() await connStore.loadConnections()
} }
} catch (err: any) { } catch (err: any) {
@@ -134,7 +134,7 @@ async function selectTlsKeyFile() {
async function handleTest() { async function handleTest() {
if (!form.host.trim()) { if (!form.host.trim()) {
ElMessage.warning('Host is required') ElMessage.warning(t('connection.hostRequired'))
return return
} }
testing.value = true testing.value = true
@@ -164,9 +164,9 @@ async function handleTest() {
sshPassphrase: form.sshPassphrase, sshPassphrase: form.sshPassphrase,
} as any) } as any)
if (result.success) { if (result.success) {
ElMessage.success('Connection successful') ElMessage.success(t('connection.testSuccess'))
} else { } else {
ElMessage.error(result.error || 'Connection failed') ElMessage.error(result.error || t('connection.testFailed'))
} }
} finally { } finally {
testing.value = false testing.value = false
@@ -175,7 +175,7 @@ async function handleTest() {
async function handleSave() { async function handleSave() {
if (!form.name.trim() || !form.host.trim()) { if (!form.name.trim() || !form.host.trim()) {
ElMessage.warning('Name and host are required') ElMessage.warning(t('connection.nameHostRequired'))
return return
} }
saving.value = true saving.value = true
@@ -211,10 +211,10 @@ async function handleSave() {
createdAt: props.connection?.createdAt ?? Date.now(), createdAt: props.connection?.createdAt ?? Date.now(),
} }
await connStore.saveConnection(conn) await connStore.saveConnection(conn)
ElMessage.success(isEdit.value ? 'Connection updated' : 'Connection created') ElMessage.success(isEdit.value ? t('connection.updated') : t('connection.created'))
close() close()
} catch (err: any) { } catch (err: any) {
ElMessage.error(err.message || 'Failed to save connection') ElMessage.error(err.message || t('connection.saveFailed'))
} finally { } finally {
saving.value = false saving.value = false
} }
+11
View File
@@ -74,6 +74,17 @@ export default {
duplicate: 'Duplizieren', duplicate: 'Duplizieren',
setColor: 'Farbe festlegen', setColor: 'Farbe festlegen',
duplicated: 'Verbindung dupliziert', duplicated: 'Verbindung dupliziert',
hostRequired: 'Host ist erforderlich',
nameHostRequired: 'Name und Host sind erforderlich',
connectSuccess: 'Verbunden',
connectFailed: 'Verbindung fehlgeschlagen',
created: 'Verbindung erstellt',
updated: 'Verbindung aktualisiert',
saveFailed: 'Verbindung konnte nicht gespeichert werden',
exported: 'Verbindungen exportiert',
importTitle: 'Verbindungen importieren',
imported: '{n} Verbindung(en) importiert',
serverInfoUnavailable: 'Verbindung hergestellt, aber Serverinformationen nicht verfügbar',
}, },
key: { key: {
title: 'Schlüssel', title: 'Schlüssel',
+11
View File
@@ -74,6 +74,17 @@ export default {
duplicate: 'Duplicate', duplicate: 'Duplicate',
setColor: 'Set Color', setColor: 'Set Color',
duplicated: 'Connection duplicated', duplicated: 'Connection duplicated',
hostRequired: 'Host is required',
nameHostRequired: 'Name and host are required',
connectSuccess: 'Connected',
connectFailed: 'Connection failed',
created: 'Connection created',
updated: 'Connection updated',
saveFailed: 'Failed to save connection',
exported: 'Connections exported',
importTitle: 'Import Connections',
imported: 'Imported {n} connection(s)',
serverInfoUnavailable: 'Connection established but server info unavailable',
}, },
key: { key: {
title: 'Keys', title: 'Keys',
+11
View File
@@ -74,6 +74,17 @@ export default {
duplicate: '複製', duplicate: '複製',
setColor: '色を設定', setColor: '色を設定',
duplicated: '接続が複製されました', duplicated: '接続が複製されました',
hostRequired: 'ホストは必須です',
nameHostRequired: '名前とホストは必須です',
connectSuccess: '接続しました',
connectFailed: '接続に失敗しました',
created: '接続が作成されました',
updated: '接続が更新されました',
saveFailed: '接続の保存に失敗しました',
exported: '接続がエクスポートされました',
importTitle: '接続をインポート',
imported: '{n} 個の接続をインポートしました',
serverInfoUnavailable: '接続は確立されましたが、サーバー情報が利用できません',
}, },
key: { key: {
title: 'キー', title: 'キー',
+11
View File
@@ -74,6 +74,17 @@ export default {
duplicate: '복제', duplicate: '복제',
setColor: '색상 설정', setColor: '색상 설정',
duplicated: '연결이 복제되었습니다', duplicated: '연결이 복제되었습니다',
hostRequired: '호스트는 필수입니다',
nameHostRequired: '이름과 호스트는 필수입니다',
connectSuccess: '연결됨',
connectFailed: '연결 실패',
created: '연결이 생성되었습니다',
updated: '연결이 업데이트되었습니다',
saveFailed: '연결 저장 실패',
exported: '연결이 내보내기되었습니다',
importTitle: '연결 가져오기',
imported: '{n}개 연결을 가져왔습니다',
serverInfoUnavailable: '연결이 확립되었지만 서버 정보를 사용할 수 없습니다',
}, },
key: { key: {
title: '키', title: '키',
+11
View File
@@ -74,6 +74,17 @@ export default {
duplicate: '复制连接', duplicate: '复制连接',
setColor: '设置颜色', setColor: '设置颜色',
duplicated: '连接已复制', duplicated: '连接已复制',
hostRequired: '主机必填',
nameHostRequired: '名称和主机必填',
connectSuccess: '连接成功',
connectFailed: '连接失败',
created: '连接已创建',
updated: '连接已更新',
saveFailed: '保存连接失败',
exported: '连接已导出',
importTitle: '导入连接',
imported: '已导入 {n} 个连接',
serverInfoUnavailable: '连接已建立但服务器信息不可用',
}, },
key: { key: {
title: '键值', title: '键值',
+4 -2
View File
@@ -1,5 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import { useI18n } from '@renderer/i18n'
export interface ConnectionConfig { export interface ConnectionConfig {
id: string id: string
@@ -34,6 +35,7 @@ export interface ConnectionConfig {
} }
export const useConnectionStore = defineStore('connection', () => { export const useConnectionStore = defineStore('connection', () => {
const { t } = useI18n()
const connections = ref<ConnectionConfig[]>([]) const connections = ref<ConnectionConfig[]>([])
const activeId = ref<string | null>(null) const activeId = ref<string | null>(null)
const connectedIds = ref<string[]>([]) const connectedIds = ref<string[]>([])
@@ -138,7 +140,7 @@ export const useConnectionStore = defineStore('connection', () => {
// leaving the renderer in a state where isConnected is true but no // leaving the renderer in a state where isConnected is true but no
// actual Redis client exists in the main process. // actual Redis client exists in the main process.
await disconnectById(conn.id) await disconnectById(conn.id)
error.value = 'Connection established but server info unavailable' error.value = t('connection.serverInfoUnavailable')
return return
} }
// Restore last selected DB for this connection // Restore last selected DB for this connection
@@ -151,7 +153,7 @@ export const useConnectionStore = defineStore('connection', () => {
currentDb.value = lastDb currentDb.value = lastDb
startHealthCheck(conn.id) startHealthCheck(conn.id)
} else { } else {
error.value = result.error || 'Connection failed' error.value = result.error || t('connection.connectFailed')
} }
} catch (err: any) { } catch (err: any) {
error.value = err.message error.value = err.message