From db0679cd92d932deede213eccd043e5a97451d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Sun, 13 Apr 2025 00:34:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8F=90=E4=BA=A4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crowdin.yml | 4 +- web/src/views/app/route.ts | 3 +- web/src/views/cert/AccountView.vue | 45 +++++++------ web/src/views/cert/CertView.vue | 104 +++++++++++++++-------------- web/src/views/cert/DnsView.vue | 81 +++++++++++----------- 5 files changed, 124 insertions(+), 113 deletions(-) diff --git a/crowdin.yml b/crowdin.yml index 282e7f5c..049cf104 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -2,4 +2,6 @@ commit_message: 'Update translations (%language%) %original_file_name%' pull_request_title: 'l10n: update translations' files: - source: /pkg/embed/locales/*.pot - translation: /pkg/embed/locales/%locale_with_underscore%/%file_name%.mo + translation: /pkg/embed/locales/%locale_with_underscore%/%file_name%.po + - source: /web/src/locales/*.pot + translation: /web/src/locales/%locale_with_underscore%.po diff --git a/web/src/views/app/route.ts b/web/src/views/app/route.ts index 19aae324..74f8c74b 100644 --- a/web/src/views/app/route.ts +++ b/web/src/views/app/route.ts @@ -1,3 +1,4 @@ +import { $gettext } from '@/utils/gettext' import type { RouteType } from '~/types/router' const Layout = () => import('@/layout/IndexView.vue') @@ -15,7 +16,7 @@ export default { path: '', component: () => import('./IndexView.vue'), meta: { - title: '应用中心', + title: $gettext('Apps'), icon: 'mdi:apps', role: ['admin'], requireAuth: true diff --git a/web/src/views/cert/AccountView.vue b/web/src/views/cert/AccountView.vue index 3ec31344..6d01aa15 100644 --- a/web/src/views/cert/AccountView.vue +++ b/web/src/views/cert/AccountView.vue @@ -8,9 +8,12 @@ import { NSpace, NTag } from 'naive-ui' +import { useGettext } from 'vue3-gettext' import cert from '@/api/panel/cert' +const { $gettext } = useGettext() + const props = defineProps({ caProviders: { type: Array, @@ -38,7 +41,7 @@ const updateAccount = ref() const columns: any = [ { - title: '邮箱', + title: $gettext('Email'), key: 'email', minWidth: 200, resizable: true, @@ -66,14 +69,14 @@ const columns: any = [ } }, { - title: '密钥类型', + title: $gettext('Key Type'), key: 'key_type', width: 150, resizable: true, ellipsis: { tooltip: true } }, { - title: '操作', + title: $gettext('Actions'), key: 'actions', width: 200, align: 'center', @@ -96,7 +99,7 @@ const columns: any = [ } }, { - default: () => '修改' + default: () => $gettext('Modify') } ), h( @@ -104,14 +107,14 @@ const columns: any = [ { onPositiveClick: () => { useRequest(cert.accountDelete(row.id)).onSuccess(() => { - window.$message.success('删除成功') + window.$message.success($gettext('Deletion successful')) refresh() }) } }, { default: () => { - return '确定删除账号吗?' + return $gettext('Are you sure you want to delete the account?') }, trigger: () => { return h( @@ -122,7 +125,7 @@ const columns: any = [ style: 'margin-left: 15px;' }, { - default: () => '删除' + default: () => $gettext('Delete') } ) } @@ -144,7 +147,7 @@ const { loading, data, page, total, pageSize, pageCount, refresh } = usePaginati ) const handleUpdateAccount = () => { - messageReactive = window.$message.loading('正在向 CA 注册账号,请耐心等待', { + messageReactive = window.$message.loading($gettext('Registering account with CA, please wait patiently'), { duration: 0 }) useRequest(cert.accountUpdate(updateAccount.value, updateAccountModel.value)) @@ -154,7 +157,7 @@ const handleUpdateAccount = () => { updateAccountModel.value.email = '' updateAccountModel.value.hmac_encoded = '' updateAccountModel.value.kid = '' - window.$message.success('更新成功') + window.$message.success($gettext('Update successful')) }) .onComplete(() => { messageReactive?.destroy() @@ -199,40 +202,40 @@ onUnmounted(() => { - Google 和 SSL.com 需要先去官网获得 KID 和 HMAC 并填入 + {{ $gettext('Google and SSL.com require obtaining KID and HMAC from their official websites first') }} - 境内无法使用 Google,其他 CA 视网络情况而定,建议使用 GoogleCN 或 Let's Encrypt + {{ $gettext('Google is not accessible in mainland China, other CAs depend on network conditions, recommend using GoogleCN or Let\'s Encrypt') }} - + - + - + @@ -240,7 +243,7 @@ onUnmounted(() => { v-model:value="updateAccountModel.kid" type="text" @keydown.enter.prevent - placeholder="输入 KID" + :placeholder="$gettext('Enter KID')" /> @@ -248,11 +251,11 @@ onUnmounted(() => { v-model:value="updateAccountModel.hmac_encoded" type="text" @keydown.enter.prevent - placeholder="输入 HMAC" + :placeholder="$gettext('Enter HMAC')" /> - 提交 + {{ $gettext('Submit') }} diff --git a/web/src/views/cert/CertView.vue b/web/src/views/cert/CertView.vue index aeca82bb..a6e88353 100644 --- a/web/src/views/cert/CertView.vue +++ b/web/src/views/cert/CertView.vue @@ -2,11 +2,14 @@ import Editor from '@guolao/vue-monaco-editor' import type { MessageReactive } from 'naive-ui' import { NButton, NDataTable, NFlex, NPopconfirm, NSpace, NSwitch, NTag } from 'naive-ui' +import { useGettext } from 'vue3-gettext' import cert from '@/api/panel/cert' import { formatDateTime } from '@/utils' import ObtainModal from '@/views/cert/ObtainModal.vue' +const { $gettext } = useGettext() + const props = defineProps({ algorithms: { type: Array, @@ -58,13 +61,13 @@ const obtainCert = ref(0) const columns: any = [ { - title: '域名', + title: $gettext('Domain'), key: 'domains', minWidth: 200, resizable: true, render(row: any) { if (row.domains == null || row.domains.length == 0) { - return h(NTag, null, { default: () => '无' }) + return h(NTag, null, { default: () => $gettext('None') }) } return h(NFlex, null, { default: () => @@ -81,7 +84,7 @@ const columns: any = [ } }, { - title: '类型', + title: $gettext('Type'), key: 'type', width: 100, render(row: any) { @@ -103,7 +106,7 @@ const columns: any = [ case '4096': return 'RSA 4096' default: - return '上传' + return $gettext('Upload') } } } @@ -111,29 +114,29 @@ const columns: any = [ } }, { - title: '关联账号', + title: $gettext('Associated Account'), key: 'account_id', minWidth: 200, resizable: true, ellipsis: { tooltip: true }, render(row: any) { if (row.account_id == 0) { - return '无' + return $gettext('None') } return accounts.value?.find((item: any) => item.value === row.account_id)?.label } }, { - title: '颁发者', + title: $gettext('Issuer'), key: 'issuer', width: 150, ellipsis: { tooltip: true }, render(row: any) { - return row.issuer == '' ? '无' : row.issuer + return row.issuer == '' ? $gettext('None') : row.issuer } }, { - title: '过期时间', + title: $gettext('Expiration Time'), key: 'not_after', width: 200, ellipsis: { tooltip: true }, @@ -148,7 +151,7 @@ const columns: any = [ resizable: true, render(row: any) { if (row.ocsp_server == null || row.ocsp_server.length == 0) { - return h(NTag, null, { default: () => '无' }) + return h(NTag, null, { default: () => $gettext('None') }) } return h(NFlex, null, { default: () => @@ -161,7 +164,7 @@ const columns: any = [ } }, { - title: '自动续签', + title: $gettext('Auto Renew'), key: 'auto_renew', width: 100, align: 'center', @@ -176,7 +179,7 @@ const columns: any = [ } }, { - title: '操作', + title: $gettext('Actions'), key: 'actions', width: 350, align: 'center', @@ -196,7 +199,7 @@ const columns: any = [ } }, { - default: () => '签发' + default: () => $gettext('Issue') } ) : null, @@ -215,7 +218,7 @@ const columns: any = [ } }, { - default: () => '部署' + default: () => $gettext('Deploy') } ) : null, @@ -227,13 +230,13 @@ const columns: any = [ type: 'success', style: 'margin-left: 15px;', onClick: async () => { - messageReactive = window.$message.loading('请稍后...', { + messageReactive = window.$message.loading($gettext('Please wait...'), { duration: 0 }) useRequest(cert.renew(row.id)) .onSuccess(() => { refresh() - window.$message.success('续签成功') + window.$message.success($gettext('Renewal successful')) }) .onComplete(() => { messageReactive?.destroy() @@ -241,7 +244,7 @@ const columns: any = [ } }, { - default: () => '续签' + default: () => $gettext('Renew') } ) : null, @@ -259,7 +262,7 @@ const columns: any = [ } }, { - default: () => '查看' + default: () => $gettext('View') } ) : null, @@ -284,7 +287,7 @@ const columns: any = [ } }, { - default: () => '修改' + default: () => $gettext('Modify') } ), h( @@ -293,13 +296,13 @@ const columns: any = [ onPositiveClick: async () => { useRequest(cert.certDelete(row.id)).onSuccess(() => { refresh() - window.$message.success('删除成功') + window.$message.success($gettext('Deletion successful')) }) } }, { default: () => { - return '确定删除证书吗?' + return $gettext('Are you sure you want to delete the certificate?') }, trigger: () => { return h( @@ -310,7 +313,7 @@ const columns: any = [ style: 'margin-left: 15px;' }, { - default: () => '删除' + default: () => $gettext('Delete') } ) } @@ -344,7 +347,7 @@ const handleUpdateCert = () => { updateModel.value.cert = '' updateModel.value.key = '' updateModel.value.script = '' - window.$message.success('更新成功') + window.$message.success($gettext('Update successful')) }) } @@ -361,7 +364,7 @@ const handleAutoRenewUpdate = (row: any) => { useRequest(cert.certUpdate(row.id, updateModel.value)) .onSuccess(() => { refresh() - window.$message.success('更新成功') + window.$message.success($gettext('Update successful')) }) .onComplete(() => { updateModel.value.domains = [] @@ -385,7 +388,7 @@ const handleDeployCert = async () => { deployModal.value = false deployModel.value.id = null deployModel.value.websites = [] - window.$message.success('部署成功') + window.$message.success($gettext('Deployment successful')) } const handleShowModalClose = () => { @@ -431,7 +434,7 @@ onUnmounted(() => { { > - 可以通过选择网站 / DNS 中的任意一项来自动签发和部署证书,也可以手动输入域名并设置 DNS - 解析来签发证书,还可以填写部署脚本来自动部署证书。 + {{ $gettext('You can automatically issue and deploy certificates by selecting any website/DNS, or manually enter domain names and set DNS resolution to issue certificates, or fill in deployment scripts to automatically deploy certificates.') }} - + { show-sort-button /> - + - + - + - + - + - + - + - 提交 + {{ $gettext('Submit') }} { > - + - 提交 + {{ $gettext('Submit') }} { @close="handleShowModalClose" > - + { }" /> - + import { NButton, NDataTable, NInput, NPopconfirm, NSpace, NTag } from 'naive-ui' +import { useGettext } from 'vue3-gettext' import cert from '@/api/panel/cert' +const { $gettext } = useGettext() + const props = defineProps({ dnsProviders: { type: Array, @@ -25,14 +28,14 @@ const updateDNS = ref() const columns: any = [ { - title: '备注名称', + title: $gettext('Note Name'), key: 'name', minWidth: 200, resizable: true, ellipsis: { tooltip: true } }, { - title: '类型', + title: $gettext('Type'), key: 'type', width: 150, resizable: true, @@ -50,7 +53,7 @@ const columns: any = [ if (provider) { return provider.label } else { - return '未知' + return $gettext('Unknown') } } } @@ -58,7 +61,7 @@ const columns: any = [ } }, { - title: '操作', + title: $gettext('Actions'), key: 'actions', width: 200, align: 'center', @@ -80,7 +83,7 @@ const columns: any = [ } }, { - default: () => '修改' + default: () => $gettext('Modify') } ), h( @@ -89,13 +92,13 @@ const columns: any = [ onPositiveClick: async () => { useRequest(cert.dnsDelete(row.id)).onSuccess(() => { refresh() - window.$message.success('删除成功') + window.$message.success($gettext('Deletion successful')) }) } }, { default: () => { - return '确定删除 DNS 吗?' + return $gettext('Are you sure you want to delete the DNS?') }, trigger: () => { return h( @@ -106,7 +109,7 @@ const columns: any = [ style: 'margin-left: 15px;' }, { - default: () => '删除' + default: () => $gettext('Delete') } ) } @@ -134,7 +137,7 @@ const handleUpdateDNS = () => { updateDNSModel.value.data.ak = '' updateDNSModel.value.data.sk = '' updateDNSModel.value.name = '' - window.$message.success('更新成功') + window.$message.success($gettext('Update successful')) }) } @@ -176,7 +179,7 @@ onUnmounted(() => { { > - - + + - + @@ -199,172 +202,172 @@ onUnmounted(() => { - 提交 + {{ $gettext('Submit') }}