mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 09:13:49 +08:00
feat: 前端支持翻译
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
module.exports = {
|
||||
output: {
|
||||
path: './src/locales',
|
||||
potPath: './frontend.pot',
|
||||
locales: ['en', 'zh_CN', 'zh_TW']
|
||||
}
|
||||
}
|
||||
62
web/gettext.config.mjs
Normal file
62
web/gettext.config.mjs
Normal file
@@ -0,0 +1,62 @@
|
||||
export default {
|
||||
input: {
|
||||
include: ['**/*.js', '**/*.ts', '**/*.vue'],
|
||||
exclude: ['utils/gettext/**'],
|
||||
jsExtractorOpts: [
|
||||
{
|
||||
keyword: '__', // $gettext
|
||||
options: {
|
||||
content: {
|
||||
replaceNewLines: '\n'
|
||||
},
|
||||
arguments: {
|
||||
text: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
keyword: '_n', // $ngettext
|
||||
options: {
|
||||
content: {
|
||||
replaceNewLines: '\n'
|
||||
},
|
||||
arguments: {
|
||||
text: 0,
|
||||
textPlural: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
keyword: '_x', // $pgettext
|
||||
options: {
|
||||
content: {
|
||||
replaceNewLines: '\n'
|
||||
},
|
||||
arguments: {
|
||||
context: 0,
|
||||
text: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
keyword: '_nx', // $npgettext
|
||||
options: {
|
||||
content: {
|
||||
replaceNewLines: '\n'
|
||||
},
|
||||
arguments: {
|
||||
context: 0,
|
||||
text: 1,
|
||||
textPlural: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
output: {
|
||||
path: './src/locales',
|
||||
potPath: './frontend.pot',
|
||||
locales: ['en', 'zh_CN', 'zh_TW'],
|
||||
linguas: false
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { App } from 'vue'
|
||||
import type { Composer } from 'vue-i18n'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
|
||||
import { useThemeStore } from '@/store'
|
||||
@@ -24,7 +23,3 @@ export function setupI18n(app: App) {
|
||||
})
|
||||
app.use(i18n)
|
||||
}
|
||||
|
||||
export const trans = (key: string, attributes = {}) => {
|
||||
return (i18n.global.t as Composer['t'])(key, attributes)
|
||||
}
|
||||
|
||||
30
web/src/locales/en.po
Normal file
30
web/src/locales/en.po
Normal file
@@ -0,0 +1,30 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: en\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:25
|
||||
msgid "Saved successfully"
|
||||
msgstr "Saved successfully"
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:34
|
||||
msgid "Panel HTTPS"
|
||||
msgstr "Panel HTTPS"
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:37
|
||||
msgid "Certificate"
|
||||
msgstr "Certificate"
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:44
|
||||
msgid "Private Key"
|
||||
msgstr "Private Key"
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:54
|
||||
msgid "Save"
|
||||
msgstr "Save"
|
||||
23
web/src/locales/frontend.pot
Normal file
23
web/src/locales/frontend.pot
Normal file
@@ -0,0 +1,23 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:25
|
||||
msgid "Saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:34
|
||||
msgid "Panel HTTPS"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:37
|
||||
msgid "Certificate"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:44
|
||||
msgid "Private Key"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:54
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
29
web/src/locales/zh_CN.po
Normal file
29
web/src/locales/zh_CN.po
Normal file
@@ -0,0 +1,29 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: zh_CN\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:25
|
||||
msgid "Saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:34
|
||||
msgid "Panel HTTPS"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:37
|
||||
msgid "Certificate"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:44
|
||||
msgid "Private Key"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:54
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
29
web/src/locales/zh_TW.po
Normal file
29
web/src/locales/zh_TW.po
Normal file
@@ -0,0 +1,29 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: zh_TW\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:25
|
||||
msgid "Saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:34
|
||||
msgid "Panel HTTPS"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:37
|
||||
msgid "Certificate"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:44
|
||||
msgid "Private Key"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/setting/SettingHttps.vue:54
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
@@ -9,7 +9,7 @@ import App from './App.vue'
|
||||
import { setupI18n } from '@/i18n/i18n'
|
||||
import { setupRouter } from '@/router'
|
||||
import { setupStore, useThemeStore } from '@/store'
|
||||
import { setupGettext, setupNaiveDiscreteApi } from '@/utils'
|
||||
import { createGettext, setupNaiveDiscreteApi } from '@/utils'
|
||||
|
||||
import { install as VueMonacoEditorPlugin } from '@guolao/vue-monaco-editor'
|
||||
|
||||
@@ -30,7 +30,7 @@ async function setupApp() {
|
||||
await setupStore(app)
|
||||
await setupNaiveDiscreteApi()
|
||||
await setupPanel().then(() => {
|
||||
setupGettext(app)
|
||||
app.use(createGettext)
|
||||
setupI18n(app)
|
||||
})
|
||||
await setupRouter(app)
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import type { Router } from 'vue-router'
|
||||
|
||||
import { trans } from '@/i18n/i18n'
|
||||
import { useThemeStore } from '@/store'
|
||||
|
||||
export function createPageTitleGuard(router: Router) {
|
||||
const themeStore = useThemeStore()
|
||||
router.afterEach((to) => {
|
||||
const pageTitle = String(to.meta.title)
|
||||
if (pageTitle) document.title = `${trans(pageTitle)} | ${themeStore.name}`
|
||||
if (pageTitle) document.title = `${pageTitle} | ${themeStore.name}`
|
||||
else document.title = themeStore.name
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,10 +1,41 @@
|
||||
import type { App } from 'vue'
|
||||
import { createGettext } from 'vue3-gettext'
|
||||
import { createGettext as vue3Gettext } from 'vue3-gettext'
|
||||
|
||||
let gettext: ReturnType<typeof createGettext>
|
||||
export let gettext: ReturnType<typeof vue3Gettext>
|
||||
|
||||
export function $gettext(msgid: string, params?: Record<string, string | number>) {
|
||||
return gettext.$gettext(msgid, params)
|
||||
}
|
||||
|
||||
export function $ngettext(
|
||||
msgid: string,
|
||||
plural: string,
|
||||
n: number,
|
||||
params?: Record<string, string | number>
|
||||
) {
|
||||
return gettext.$ngettext(msgid, plural, n, params)
|
||||
}
|
||||
|
||||
export function setupGettext(app: App) {
|
||||
gettext = createGettext({
|
||||
gettext = vue3Gettext({
|
||||
availableLanguages: {
|
||||
en: 'English',
|
||||
zh_CN: '简体中文',
|
||||
zh_TW: '繁體中文'
|
||||
},
|
||||
defaultLanguage: 'zh_CN',
|
||||
globalProperties: {
|
||||
gettext: ['$gettext', '__'], // 这样支持同时使用 $gettext, __ 两种方式
|
||||
ngettext: ['$ngettext', '_n'],
|
||||
pgettext: ['$pgettext', '_x'],
|
||||
npgettext: ['$npgettext', '_nx']
|
||||
}
|
||||
})
|
||||
app.use(gettext)
|
||||
}
|
||||
|
||||
export function createGettext(): any {
|
||||
gettext = vue3Gettext({
|
||||
availableLanguages: {
|
||||
en: 'English',
|
||||
zh_CN: '简体中文',
|
||||
@@ -12,5 +43,6 @@ export function setupGettext(app: App) {
|
||||
},
|
||||
defaultLanguage: 'zh_CN'
|
||||
})
|
||||
app.use(gettext)
|
||||
|
||||
return gettext
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import setting from '@/api/panel/setting'
|
||||
|
||||
const { t } = useI18n()
|
||||
import { $gettext } from '@/utils/gettext'
|
||||
|
||||
const { data: model } = useRequest(setting.list, {
|
||||
initialData: {
|
||||
@@ -25,7 +22,7 @@ const { data: model } = useRequest(setting.list, {
|
||||
|
||||
const handleSave = () => {
|
||||
useRequest(setting.update(model.value)).onSuccess(() => {
|
||||
window.$message.success(t('settingIndex.edit.toasts.success'))
|
||||
window.$message.success($gettext('Saved successfully'))
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -34,17 +31,17 @@ const handleSave = () => {
|
||||
<n-space vertical>
|
||||
<n-alert type="warning"> 错误的证书可能导致面板无法访问,请谨慎操作!</n-alert>
|
||||
<n-form>
|
||||
<n-form-item :label="$t('settingIndex.edit.fields.https.label')">
|
||||
<n-form-item :label="$gettext('Panel HTTPS')">
|
||||
<n-switch v-model:value="model.https" />
|
||||
</n-form-item>
|
||||
<n-form-item v-if="model.https" :label="$t('settingIndex.edit.fields.cert.label')">
|
||||
<n-form-item v-if="model.https" :label="$gettext('Certificate')">
|
||||
<n-input
|
||||
v-model:value="model.cert"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 10, maxRows: 15 }"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item v-if="model.https" :label="$t('settingIndex.edit.fields.key.label')">
|
||||
<n-form-item v-if="model.https" :label="$gettext('Private Key')">
|
||||
<n-input
|
||||
v-model:value="model.key"
|
||||
type="textarea"
|
||||
@@ -54,7 +51,7 @@ const handleSave = () => {
|
||||
</n-form>
|
||||
</n-space>
|
||||
<n-button type="primary" @click="handleSave">
|
||||
{{ $t('settingIndex.edit.actions.submit') }}
|
||||
{{ $gettext('Save') }}
|
||||
</n-button>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user