From 570586c4506d09e8fb6c08f8b8bcd6d1dc673294 Mon Sep 17 00:00:00 2001 From: jingrow Date: Mon, 29 Dec 2025 18:54:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E5=8F=8A=E9=A1=B5=E9=9D=A2=E5=AE=9E=E7=8E=B0=E5=A4=9A=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/JsiteServerOverview.vue | 236 +++++++++--------- dashboard/src/objects/jsite_server.js | 206 +++++++-------- dashboard/src/pages/NewJsiteServer.vue | 146 +++++------ 3 files changed, 295 insertions(+), 293 deletions(-) diff --git a/dashboard/src/components/JsiteServerOverview.vue b/dashboard/src/components/JsiteServerOverview.vue index 039a1a5..61f30bf 100644 --- a/dashboard/src/components/JsiteServerOverview.vue +++ b/dashboard/src/components/JsiteServerOverview.vue @@ -8,7 +8,7 @@
-

当前套餐

+

{{ $t('Current Plan') }}

@@ -19,7 +19,7 @@
- 到期时间:{{ $format.date($jsiteServer.pg.end_date) }} + {{ $t('Expiry Date') }}: {{ $format.date($jsiteServer.pg.end_date) }}
@@ -28,14 +28,14 @@ :loading="$jsiteServer.renew?.loading" class="px-5 !bg-[#1fc76f] !hover:bg-[#1bb85f] !text-white" > - 续费 + {{ $t('Renew') }}
@@ -45,25 +45,25 @@
-

服务器配置

+

{{ $t('Server Configuration') }}

- CPU: - {{ $jsiteServer.pg.cpu || '未知' }}核 + {{ $t('CPU') }}: + {{ $jsiteServer.pg.cpu || $t('Unknown') }} {{ $t('cores') }}
- 内存: - {{ $jsiteServer.pg.memory || '未知' }}GB + {{ $t('Memory') }}: + {{ $jsiteServer.pg.memory || $t('Unknown') }}GB
- 系统盘: - {{ $jsiteServer.pg.disk_size || '未知' }}GB + {{ $t('System Disk') }}: + {{ $jsiteServer.pg.disk_size || $t('Unknown') }}GB
- 带宽: - {{ $jsiteServer.pg.bandwidth || '未知' }}Mbps + {{ $t('Bandwidth') }}: + {{ $jsiteServer.pg.bandwidth || $t('Unknown') }}Mbps
@@ -72,7 +72,7 @@
-

服务器信息

+

{{ $t('Server Information') }}

-
+
{{ info.value }} @@ -113,13 +113,13 @@ class="flex-1 px-2 py-1 text-sm border border-blue-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent shadow-sm" :disabled="saveServerNameLoading" maxlength="100" - placeholder="请输入服务器名称" + :placeholder="$t('Please enter server name')" />
-

操作

+

{{ $t('Actions') }}

@@ -169,7 +169,7 @@ variant="outline" class="bg-gray-100 text-gray-700 hover:bg-gray-200" > - 重启 + {{ $t('Restart') }}
@@ -218,29 +218,29 @@
-

SSH连接

+

{{ $t('SSH Connection') }}

- SSH端口: + {{ $t('SSH Port') }}: {{ $jsiteServer.pg.ssh_port || '22' }}
- SSH用户: + {{ $t('SSH User') }}: {{ $jsiteServer.pg.ssh_user || 'root' }}
- 服务器密码: + {{ $t('Server Password') }}:
- {{ showPassword ? decryptedPassword : ($jsiteServer.pg.password || '未设置') }} + {{ showPassword ? decryptedPassword : ($jsiteServer.pg.password || $t('Not Set')) }}
- 密钥对名称: - {{ $jsiteServer.pg.key_pair_name || '未设置' }} + {{ $t('Key Pair Name') }}: + {{ $jsiteServer.pg.key_pair_name || $t('Not Set') }}
- 私钥: + {{ $t('Private Key') }}:
{{ $jsiteServer.pg.private_key }}
- 未设置 + {{ $t('Not Set') }}
@@ -316,14 +316,14 @@ export default { methods: { getStatusText(status) { const statusMap = { - 'Pending': '准备中', - 'Starting': '启动中', - 'Running': '运行中', - 'Stopping': '停止中', - 'Stopped': '已停止', - 'Resetting': '重置中', - 'Upgrading': '升级中', - 'Disabled': '已禁用' + 'Pending': this.$t('Pending'), + 'Starting': this.$t('Starting'), + 'Running': this.$t('Running'), + 'Stopping': this.$t('Stopping'), + 'Stopped': this.$t('Stopped'), + 'Resetting': this.$t('Resetting'), + 'Upgrading': this.$t('Upgrading'), + 'Disabled': this.$t('Disabled') }; return statusMap[status] || status; }, @@ -342,32 +342,32 @@ export default { }, getRegionText(region) { const regionMap = { - 'cn-qingdao': '华北1(青岛)', - 'cn-beijing': '华北2(北京)', - 'cn-zhangjiakou': '华北3(张家口)', - 'cn-huhehaote': '华北5(呼和浩特)', - 'cn-hangzhou': '华东1(杭州)', - 'cn-shanghai': '华东2(上海)', - 'cn-shenzhen': '华南1(深圳)', - 'cn-heyuan': '华南2(河源)', - 'cn-chengdu': '西南1(成都)', - 'cn-guangzhou': '华南3(广州)', - 'cn-wulanchabu': '华北6(乌兰察布)', - 'cn-nanjing': '华东5(南京)', - 'cn-fuzhou': '华东6(福州)', - 'cn-wuhan-lr': '华中1(武汉)', - 'cn-hongkong': '中国香港', - 'ap-southeast-1': '新加坡', - 'ap-southeast-3': '马来西亚(吉隆坡)', - 'ap-southeast-5': '印度尼西亚(雅加达)', - 'ap-northeast-1': '日本(东京)', - 'us-west-1': '美国(硅谷)', - 'us-east-1': '美国(弗吉尼亚)', - 'eu-central-1': '德国(法兰克福)', - 'eu-west-1': '英国(伦敦)', - 'ap-southeast-6': '菲律宾(马尼拉)', - 'ap-southeast-7': '泰国(曼谷)', - 'ap-northeast-2': '韩国(首尔)' + 'cn-qingdao': this.$t('North China 1 (Qingdao)'), + 'cn-beijing': this.$t('North China 2 (Beijing)'), + 'cn-zhangjiakou': this.$t('North China 3 (Zhangjiakou)'), + 'cn-huhehaote': this.$t('North China 5 (Hohhot)'), + 'cn-hangzhou': this.$t('East China 1 (Hangzhou)'), + 'cn-shanghai': this.$t('East China 2 (Shanghai)'), + 'cn-shenzhen': this.$t('South China 1 (Shenzhen)'), + 'cn-heyuan': this.$t('South China 2 (Heyuan)'), + 'cn-chengdu': this.$t('Southwest China 1 (Chengdu)'), + 'cn-guangzhou': this.$t('South China 3 (Guangzhou)'), + 'cn-wulanchabu': this.$t('North China 6 (Ulanqab)'), + 'cn-nanjing': this.$t('East China 5 (Nanjing)'), + 'cn-fuzhou': this.$t('East China 6 (Fuzhou)'), + 'cn-wuhan-lr': this.$t('Central China 1 (Wuhan)'), + 'cn-hongkong': this.$t('Hong Kong'), + 'ap-southeast-1': this.$t('Singapore'), + 'ap-southeast-3': this.$t('Malaysia (Kuala Lumpur)'), + 'ap-southeast-5': this.$t('Indonesia (Jakarta)'), + 'ap-northeast-1': this.$t('Japan (Tokyo)'), + 'us-west-1': this.$t('US (Silicon Valley)'), + 'us-east-1': this.$t('US (Virginia)'), + 'eu-central-1': this.$t('Germany (Frankfurt)'), + 'eu-west-1': this.$t('UK (London)'), + 'ap-southeast-6': this.$t('Philippines (Manila)'), + 'ap-southeast-7': this.$t('Thailand (Bangkok)'), + 'ap-northeast-2': this.$t('South Korea (Seoul)') }; return regionMap[region] || region; }, @@ -391,18 +391,18 @@ export default { }, async restartServer() { if (!this.$jsiteServer.pg.instance_id) { - toast.error('服务器实例ID不存在'); + toast.error(this.$t('Server instance ID does not exist')); return; } confirmDialog({ - title: '重启', - message: '确定要重启服务器吗?重启过程中服务器将暂时不可用。', + title: this.$t('Restart'), + message: this.$t('Are you sure you want to restart the server? The server will be temporarily unavailable during the restart process.'), primaryAction: { - label: '确定', + label: this.$t('Confirm'), onClick: ({ hide }) => { // 立即显示成功提示并关闭弹窗 - toast.success('重启请求已提交'); + toast.success(this.$t('Restart request submitted')); hide(); // 异步提交请求 @@ -428,17 +428,17 @@ export default { }, async forceRestartServer() { if (!this.$jsiteServer.pg.instance_id) { - toast.error('服务器实例ID不存在'); + toast.error(this.$t('Server instance ID does not exist')); return; } confirmDialog({ - title: '强制重启', - message: '确定要强制重启服务器吗?该操作可能会导致未保存的数据丢失。', + title: this.$t('Force Restart'), + message: this.$t('Are you sure you want to force restart the server? This operation may cause unsaved data loss.'), primaryAction: { - label: '确定', + label: this.$t('Confirm'), onClick: ({ hide }) => { - toast.success('强制重启请求已提交'); + toast.success(this.$t('Force restart request submitted')); hide(); this.forceRestartLoading = true; const req = createResource({ @@ -462,7 +462,7 @@ export default { }, async resetPassword() { if (!this.$jsiteServer.pg.instance_id) { - toast.error('服务器实例ID不存在'); + toast.error(this.$t('Server instance ID does not exist')); return; } @@ -470,11 +470,11 @@ export default { const PasswordDialog = defineAsyncComponent(() => import('../dialogs/PasswordDialog.vue')); renderDialog(h(PasswordDialog, { - title: '重置服务器密码', - description: '长度为 8 至 30 个字符,必须同时包含大小写英文字母、数字和特殊符号。', + title: this.$t('Reset Server Password'), + description: this.$t('Length must be between 8 and 30 characters, and must include uppercase and lowercase letters, numbers, and special characters.'), onConfirm: (password) => { // 立即显示成功提示 - toast.success('密码重置请求已提交'); + toast.success(this.$t('Password reset request submitted')); // 异步提交请求 this.resetPasswordLoading = true; @@ -499,18 +499,18 @@ export default { }, async resetKeyPair() { if (!this.$jsiteServer.pg.instance_id) { - toast.error('服务器实例ID不存在'); + toast.error(this.$t('Server instance ID does not exist')); return; } confirmDialog({ - title: '重置密钥对', - message: '确定要重置密钥对吗?这将删除旧的密钥对并创建新的密钥对。重置后需要使用新的私钥才能连接服务器。', + title: this.$t('Reset Key Pair'), + message: this.$t('Are you sure you want to reset the key pair? This will delete the old key pair and create a new one. After resetting, you will need to use the new private key to connect to the server.'), primaryAction: { - label: '确定', + label: this.$t('Confirm'), onClick: ({ hide }) => { // 立即显示成功提示并关闭弹窗 - toast.success('密钥对重置请求已提交'); + toast.success(this.$t('Key pair reset request submitted')); hide(); // 异步提交请求 @@ -535,18 +535,18 @@ export default { }, async deleteKeyPair() { if (!this.$jsiteServer.pg.instance_id) { - toast.error('服务器实例ID不存在'); + toast.error(this.$t('Server instance ID does not exist')); return; } confirmDialog({ - title: '删除密钥对', - message: '确定要删除密钥对吗?删除后将无法使用私钥连接服务器,建议先设置服务器密码。', + title: this.$t('Delete Key Pair'), + message: this.$t('Are you sure you want to delete the key pair? After deletion, you will not be able to connect to the server using the private key. It is recommended to set a server password first.'), primaryAction: { - label: '确定', + label: this.$t('Confirm'), onClick: ({ hide }) => { // 立即显示成功提示并关闭弹窗 - toast.success('密钥对删除请求已提交'); + toast.success(this.$t('Key pair deletion request submitted')); hide(); // 异步提交请求 @@ -573,18 +573,18 @@ export default { }, async resetSystem() { if (!this.$jsiteServer.pg.instance_id) { - toast.error('服务器实例ID不存在'); + toast.error(this.$t('Server instance ID does not exist')); return; } confirmDialog({ - title: '重置系统', - message: '确定要重置系统吗?这将清除所有数据并重新安装系统,操作不可逆!', + title: this.$t('Reset System'), + message: this.$t('Are you sure you want to reset the system? This will clear all data and reinstall the system. This operation is irreversible!'), primaryAction: { - label: '确定', + label: this.$t('Confirm'), onClick: ({ hide }) => { // 立即显示成功提示并关闭弹窗 - toast.success('系统重置请求已提交'); + toast.success(this.$t('System reset request submitted')); hide(); // 异步提交请求 @@ -625,11 +625,11 @@ export default { this.decryptedPassword = response; this.showPassword = true; } else { - toast.warning('当前没有保存的密码'); + toast.warning(this.$t('No password is currently saved')); } }, onError: (error) => { - toast.error('获取密码失败'); + toast.error(this.$t('Failed to get password')); } }); getPasswordRequest.submit(); @@ -639,22 +639,22 @@ export default { if (this.$jsiteServer.pg.private_key) { navigator.clipboard.writeText(this.$jsiteServer.pg.private_key).then(() => { this.copySuccess = true; - toast.success('私钥已复制到剪贴板'); + toast.success(this.$t('Private key copied to clipboard')); setTimeout(() => { this.copySuccess = false; }, 2000); }).catch(() => { - toast.error('复制失败,请手动复制'); + toast.error(this.$t('Copy failed, please copy manually')); }); } }, onRenewalSuccess(data) { - toast.success('服务器续费成功!'); + toast.success(this.$t('Server renewal successful!')); // 刷新服务器数据 this.$jsiteServer.reload(); }, onUpgradeSuccess(data) { - toast.success('服务器升级成功!'); + toast.success(this.$t('Server upgrade successful!')); // 刷新服务器数据 this.$jsiteServer.reload(); }, @@ -688,17 +688,17 @@ export default { const newName = this.editServerNameValue.trim(); if (!newName) { - toast.error('服务器名称不能为空'); + toast.error(this.$t('Server name cannot be empty')); return; } if (newName.length < 2) { - toast.error('服务器名称至少需要2个字符'); + toast.error(this.$t('Server name must be at least 2 characters')); return; } if (newName.length > 100) { - toast.error('服务器名称不能超过100个字符'); + toast.error(this.$t('Server name cannot exceed 100 characters')); return; } @@ -714,7 +714,7 @@ export default { { title: newName }, { onSuccess: () => { - toast.success('服务器名称已更新'); + toast.success(this.$t('Server name updated')); this.editingServerName = false; this.editServerNameValue = ''; this.saveServerNameLoading = false; @@ -726,7 +726,7 @@ export default { } ); } catch (error) { - toast.error('更新失败,请重试'); + toast.error(this.$t('Update failed, please try again')); this.saveServerNameLoading = false; } }, @@ -735,31 +735,31 @@ export default { serverInformation() { return [ { - label: '状态', + label: this.$t('Status'), value: this.getStatusText(this.$jsiteServer.pg?.status), }, { - label: '服务器名称', + label: this.$t('Server Name'), value: this.$jsiteServer.pg?.title || this.$jsiteServer.pg?.name, }, { - label: '实例ID', + label: this.$t('Instance ID'), value: this.$jsiteServer.pg?.instance_id || '', }, { - label: '公网IP', + label: this.$t('Public IP'), value: this.$jsiteServer.pg?.public_ip || '', }, { - label: '内网IP', + label: this.$t('Private IP'), value: this.$jsiteServer.pg?.private_ip || '', }, { - label: '区域', + label: this.$t('Region'), value: this.getRegionText(this.$jsiteServer.pg?.region), }, { - label: '系统', + label: this.$t('System'), value: this.$jsiteServer.pg?.system || '', }, ]; diff --git a/dashboard/src/objects/jsite_server.js b/dashboard/src/objects/jsite_server.js index 395e411..1a00091 100644 --- a/dashboard/src/objects/jsite_server.js +++ b/dashboard/src/objects/jsite_server.js @@ -7,6 +7,7 @@ import { duration, planTitle, userCurrency } from '../utils/format'; import { trialDays } from '../utils/site'; import { getJobsTab } from './common/jobs'; import { tagTab } from './common/tags'; +import { t } from '../utils/i18n'; export default { pagetype: 'Jsite Server', @@ -19,7 +20,7 @@ export default { }, list: { route: '/jsite-servers', - title: '服务器', + title: t('Servers'), fields: [ 'name', 'title', @@ -43,52 +44,52 @@ export default { return [ { type: 'select', - label: '状态', + label: t('Status'), fieldname: 'status', options: [ { label: '', value: '' }, - { label: '准备中', value: 'Pending' }, - { label: '启动中', value: 'Starting' }, - { label: '运行中', value: 'Running' }, - { label: '停止中', value: 'Stopping' }, - { label: '已停止', value: 'Stopped' }, - { label: '重置中', value: 'Resetting' }, - { label: '升级中', value: 'Upgrading' }, - { label: '已禁用', value: 'Disabled' } + { label: t('Pending'), value: 'Pending' }, + { label: t('Starting'), value: 'Starting' }, + { label: t('Running'), value: 'Running' }, + { label: t('Stopping'), value: 'Stopping' }, + { label: t('Stopped'), value: 'Stopped' }, + { label: t('Resetting'), value: 'Resetting' }, + { label: t('Upgrading'), value: 'Upgrading' }, + { label: t('Disabled'), value: 'Disabled' } ] }, { type: 'select', - label: '区域', + label: t('Region'), fieldname: 'region', options: [ { label: '', value: '' }, - { label: '华北1(青岛)', value: 'cn-qingdao' }, - { label: '华北2(北京)', value: 'cn-beijing' }, - { label: '华北3(张家口)', value: 'cn-zhangjiakou' }, - { label: '华北5(呼和浩特)', value: 'cn-huhehaote' }, - { label: '华东1(杭州)', value: 'cn-hangzhou' }, - { label: '华东2(上海)', value: 'cn-shanghai' }, - { label: '华南1(深圳)', value: 'cn-shenzhen' }, - { label: '华南2(河源)', value: 'cn-heyuan' }, - { label: '西南1(成都)', value: 'cn-chengdu' }, - { label: '华南3(广州)', value: 'cn-guangzhou' }, - { label: '华北6(乌兰察布)', value: 'cn-wulanchabu' }, - { label: '华东5(南京)', value: 'cn-nanjing' }, - { label: '华东6(福州)', value: 'cn-fuzhou' }, - { label: '华中1(武汉)', value: 'cn-wuhan-lr' }, - { label: '中国香港', value: 'cn-hongkong' }, - { label: '新加坡', value: 'ap-southeast-1' }, - { label: '马来西亚(吉隆坡)', value: 'ap-southeast-3' }, - { label: '印度尼西亚(雅加达)', value: 'ap-southeast-5' }, - { label: '日本(东京)', value: 'ap-northeast-1' }, - { label: '美国(硅谷)', value: 'us-west-1' }, - { label: '美国(弗吉尼亚)', value: 'us-east-1' }, - { label: '德国(法兰克福)', value: 'eu-central-1' }, - { label: '英国(伦敦)', value: 'eu-west-1' }, - { label: '菲律宾(马尼拉)', value: 'ap-southeast-6' }, - { label: '泰国(曼谷)', value: 'ap-southeast-7' }, - { label: '韩国(首尔)', value: 'ap-northeast-2' } + { label: t('North China 1 (Qingdao)'), value: 'cn-qingdao' }, + { label: t('North China 2 (Beijing)'), value: 'cn-beijing' }, + { label: t('North China 3 (Zhangjiakou)'), value: 'cn-zhangjiakou' }, + { label: t('North China 5 (Hohhot)'), value: 'cn-huhehaote' }, + { label: t('East China 1 (Hangzhou)'), value: 'cn-hangzhou' }, + { label: t('East China 2 (Shanghai)'), value: 'cn-shanghai' }, + { label: t('South China 1 (Shenzhen)'), value: 'cn-shenzhen' }, + { label: t('South China 2 (Heyuan)'), value: 'cn-heyuan' }, + { label: t('Southwest China 1 (Chengdu)'), value: 'cn-chengdu' }, + { label: t('South China 3 (Guangzhou)'), value: 'cn-guangzhou' }, + { label: t('North China 6 (Ulanqab)'), value: 'cn-wulanchabu' }, + { label: t('East China 5 (Nanjing)'), value: 'cn-nanjing' }, + { label: t('East China 6 (Fuzhou)'), value: 'cn-fuzhou' }, + { label: t('Central China 1 (Wuhan)'), value: 'cn-wuhan-lr' }, + { label: t('Hong Kong'), value: 'cn-hongkong' }, + { label: t('Singapore'), value: 'ap-southeast-1' }, + { label: t('Malaysia (Kuala Lumpur)'), value: 'ap-southeast-3' }, + { label: t('Indonesia (Jakarta)'), value: 'ap-southeast-5' }, + { label: t('Japan (Tokyo)'), value: 'ap-northeast-1' }, + { label: t('US (Silicon Valley)'), value: 'us-west-1' }, + { label: t('US (Virginia)'), value: 'us-east-1' }, + { label: t('Germany (Frankfurt)'), value: 'eu-central-1' }, + { label: t('UK (London)'), value: 'eu-west-1' }, + { label: t('Philippines (Manila)'), value: 'ap-southeast-6' }, + { label: t('Thailand (Bangkok)'), value: 'ap-southeast-7' }, + { label: t('South Korea (Seoul)'), value: 'ap-northeast-2' } ] } ]; @@ -97,7 +98,7 @@ export default { searchField: 'title', columns: [ { - label: '服务器', + label: t('Server'), fieldname: 'name', width: 1.5, class: 'font-medium', @@ -106,83 +107,82 @@ export default { } }, { - label: '状态', + label: t('Status'), fieldname: 'status', type: 'Badge', width: 0.8, format(value) { const statusMap = { - 'Pending': '准备中', - 'Starting': '启动中', - 'Running': '运行中', - 'Stopping': '停止中', - 'Stopped': '已停止', - 'Resetting': '重置中', - 'Upgrading': '升级中', - 'Disabled': '已禁用' + 'Pending': t('Pending'), + 'Starting': t('Starting'), + 'Running': t('Running'), + 'Stopping': t('Stopping'), + 'Stopped': t('Stopped'), + 'Resetting': t('Resetting'), + 'Upgrading': t('Upgrading'), + 'Disabled': t('Disabled') }; return statusMap[value] || value; } }, { - label: '配置', + label: t('Configuration'), fieldname: 'cpu', format(value, row) { - const cpu = row.cpu || '未知'; - const memory = row.memory || '未知'; - const disk = row.disk_size || '未知'; - return `${cpu}核/${memory}GB/${disk}GB`; + const cpu = row.cpu || t('Unknown'); + const memory = row.memory || t('Unknown'); + const disk = row.disk_size || t('Unknown'); + return `${cpu}${t('cores')}/${memory}GB/${disk}GB`; } }, { - label: '公网IP', + label: t('Public IP'), fieldname: 'public_ip', format(value) { return value || '-'; } }, { - label: '区域', + label: t('Region'), fieldname: 'region', format(value) { if (!value) return '-'; - // 区域ID到中文名称的映射表 + // Region ID to name mapping const regionMap = { - 'cn-qingdao': '华北1(青岛)', - 'cn-beijing': '华北2(北京)', - 'cn-zhangjiakou': '华北3(张家口)', - 'cn-huhehaote': '华北5(呼和浩特)', - 'cn-hangzhou': '华东1(杭州)', - 'cn-shanghai': '华东2(上海)', - 'cn-shenzhen': '华南1(深圳)', - 'cn-heyuan': '华南2(河源)', - 'cn-chengdu': '西南1(成都)', - 'cn-guangzhou': '华南3(广州)', - 'cn-wulanchabu': '华北6(乌兰察布)', - 'cn-nanjing': '华东5(南京)', - 'cn-fuzhou': '华东6(福州)', - 'cn-wuhan-lr': '华中1(武汉)', - 'cn-hongkong': '中国香港', - 'ap-southeast-1': '新加坡', - 'ap-southeast-3': '马来西亚(吉隆坡)', - 'ap-southeast-5': '印度尼西亚(雅加达)', - 'ap-northeast-1': '日本(东京)', - 'us-west-1': '美国(硅谷)', - 'us-east-1': '美国(弗吉尼亚)', - 'eu-central-1': '德国(法兰克福)', - 'eu-west-1': '英国(伦敦)', - 'ap-southeast-6': '菲律宾(马尼拉)', - 'ap-southeast-7': '泰国(曼谷)', - 'ap-northeast-2': '韩国(首尔)' + 'cn-qingdao': t('North China 1 (Qingdao)'), + 'cn-beijing': t('North China 2 (Beijing)'), + 'cn-zhangjiakou': t('North China 3 (Zhangjiakou)'), + 'cn-huhehaote': t('North China 5 (Hohhot)'), + 'cn-hangzhou': t('East China 1 (Hangzhou)'), + 'cn-shanghai': t('East China 2 (Shanghai)'), + 'cn-shenzhen': t('South China 1 (Shenzhen)'), + 'cn-heyuan': t('South China 2 (Heyuan)'), + 'cn-chengdu': t('Southwest China 1 (Chengdu)'), + 'cn-guangzhou': t('South China 3 (Guangzhou)'), + 'cn-wulanchabu': t('North China 6 (Ulanqab)'), + 'cn-nanjing': t('East China 5 (Nanjing)'), + 'cn-fuzhou': t('East China 6 (Fuzhou)'), + 'cn-wuhan-lr': t('Central China 1 (Wuhan)'), + 'cn-hongkong': t('Hong Kong'), + 'ap-southeast-1': t('Singapore'), + 'ap-southeast-3': t('Malaysia (Kuala Lumpur)'), + 'ap-southeast-5': t('Indonesia (Jakarta)'), + 'ap-northeast-1': t('Japan (Tokyo)'), + 'us-west-1': t('US (Silicon Valley)'), + 'us-east-1': t('US (Virginia)'), + 'eu-central-1': t('Germany (Frankfurt)'), + 'eu-west-1': t('UK (London)'), + 'ap-southeast-6': t('Philippines (Manila)'), + 'ap-southeast-7': t('Thailand (Bangkok)'), + 'ap-northeast-2': t('South Korea (Seoul)') }; - // 如果是RegionId,返回对应的中文名称;如果已经是中文名称,直接返回 return regionMap[value] || value; } }, { - label: '到期时间', + label: t('Expiry Date'), fieldname: 'end_date', format(value) { if (!value) return '-'; @@ -192,7 +192,7 @@ export default { ], primaryAction({ listResource: jsiteServers }) { return { - label: '新建服务器', + label: t('New Server'), variant: 'solid', slots: { prefix: icon('plus') @@ -205,14 +205,14 @@ export default { statusBadge({ documentResource: jsiteServer }) { const status = jsiteServer.pg?.status; const statusMap = { - 'Pending': '准备中', - 'Starting': '启动中', - 'Running': '运行中', - 'Stopping': '停止中', - 'Stopped': '已停止', - 'Resetting': '重置中', - 'Upgrading': '升级中', - 'Disabled': '已禁用' + 'Pending': t('Pending'), + 'Starting': t('Starting'), + 'Running': t('Running'), + 'Stopping': t('Stopping'), + 'Stopped': t('Stopped'), + 'Resetting': t('Resetting'), + 'Upgrading': t('Upgrading'), + 'Disabled': t('Disabled') }; return { label: statusMap[status] || status @@ -221,7 +221,7 @@ export default { breadcrumbs({ documentResource: jsiteServer }) { return [ { - label: '服务器', + label: t('Servers'), route: '/jsite-servers' }, { @@ -235,7 +235,7 @@ export default { const actions = [ { - label: '重启', + label: t('Restart'), icon: 'refresh-cw', onClick() { jsiteServer.reboot.submit(); @@ -243,14 +243,14 @@ export default { condition: () => jsiteServer.pg?.status === 'Running' }, { - label: '重命名', + label: t('Rename'), icon: 'edit-3', onClick() { jsiteServer.rename.submit(); } }, { - label: '删除', + label: t('Delete'), icon: 'trash-2', onClick() { jsiteServer.dropServer.submit(); @@ -263,10 +263,10 @@ export default { }, detail: { route: '/jsite-servers/:name', - title: '服务器详细信息', + title: t('Server Details'), tabs: [ { - label: '概览', + label: t('Overview'), route: '', type: 'Component', component: defineAsyncComponent(() => import('../components/JsiteServerOverview.vue')), @@ -275,7 +275,7 @@ export default { } }, { - label: '防火墙', + label: t('Firewall'), route: 'firewall', type: 'Component', component: defineAsyncComponent(() => import('../components/JsiteServerFirewallRules.vue')), @@ -286,7 +286,7 @@ export default { ], fields: [ { - label: '基本信息', + label: t('Basic Information'), fields: [ 'title', 'status', @@ -296,7 +296,7 @@ export default { ] }, { - label: '服务器配置', + label: t('Server Configuration'), fields: [ 'cpu', 'memory', @@ -309,7 +309,7 @@ export default { ] }, { - label: 'SSH连接', + label: t('SSH Connection'), fields: [ 'ssh_user', 'ssh_port', @@ -319,7 +319,7 @@ export default { ] }, { - label: '其他信息', + label: t('Other Information'), fields: [ 'end_date', 'period' diff --git a/dashboard/src/pages/NewJsiteServer.vue b/dashboard/src/pages/NewJsiteServer.vue index 8f7ff43..1459b21 100644 --- a/dashboard/src/pages/NewJsiteServer.vue +++ b/dashboard/src/pages/NewJsiteServer.vue @@ -5,8 +5,8 @@
@@ -17,17 +17,17 @@
-

新建服务器

+

{{ $t('New Server') }}

- 请选择服务器配置和支付方式,点击"创建"后将自动为您开通。 + {{ $t('Please select server configuration and payment method. Click "Create" to automatically provision the server.') }}

- + - + @@ -45,9 +45,9 @@
- + @@ -64,18 +64,18 @@
-
月度费用
+
{{ $t('Monthly Fee') }}
¥ {{ getSelectedPlanPrice() }} - (月付) + ({{ $t('Monthly') }})
-
购买时长
-
{{ period }} 个月
+
{{ $t('Purchase Duration') }}
+
{{ period }} {{ $t('months') }}
-
总计
+
{{ $t('Total') }}
¥ {{ getTotalAmount() }}
@@ -83,7 +83,7 @@
@@ -145,7 +145,7 @@
-

正在处理支付,请稍候...

+

{{ $t('Processing payment, please wait...') }}

@@ -157,12 +157,12 @@
-

支付成功!

+

{{ $t('Payment Successful!') }}

- 您的订单已支付成功,服务器记录已创建。服务器正在后台创建中,创建并启动需要 3-5 分钟,请耐心等待。 + {{ $t('Your order has been paid successfully and the server record has been created. The server is being created in the background. Creation and startup will take 3-5 minutes, please be patient.') }}

- 您可以在服务器列表中查看服务器状态,创建完成后状态将更新为"运行中"。 + {{ $t('You can check the server status in the server list. After creation is complete, the status will be updated to "Running".') }}

@@ -184,8 +184,8 @@
-
扫一扫付款(元)
-
{{ order?.total_amount }} 元
+
{{ $t('Scan to Pay (CNY)') }}
+
{{ order?.total_amount }} {{ $t('CNY') }}
@@ -200,9 +200,9 @@

- 请使用微信扫描二维码完成支付 + {{ $t('Please scan the QR code with WeChat to complete payment') }}

-

二维码有效期 15 分钟

+

{{ $t('QR code valid for 15 minutes') }}

@@ -212,19 +212,19 @@
-

请在新页面完成支付宝支付

+

{{ $t('Please complete Alipay payment in the new page') }}

- 如果没有自动跳转,请点击下方按钮打开支付页面 + {{ $t('If it does not automatically redirect, please click the button below to open the payment page') }}

- 支付完成后,请稍等片刻,系统会自动刷新页面 + {{ $t('After payment is completed, please wait a moment, the system will automatically refresh the page') }}

@@ -260,14 +260,7 @@ export default { regions: [], plans: [], images: [], - periods: [ - { value: 1, label: '1个月' }, - { value: 3, label: '3个月' }, - { value: 6, label: '6个月' }, - { value: 12, label: '1年' }, - { value: 24, label: '2年' }, - { value: 36, label: '3年' } - ], + periods: [], isLoading: false, error: null, success: false, @@ -314,11 +307,11 @@ export default { if (Array.isArray(regionsData) && regionsData.length > 0) { this.regions = regionsData; } else { - this.error = '区域数据格式不正确或为空'; + this.error = this.$t('Region data format is incorrect or empty'); } }, onError(error) { - this.error = error.message || '获取区域失败'; + this.error = error.message || this.$t('Failed to get regions'); } }; }, @@ -330,7 +323,7 @@ export default { this.plans = data.plans || []; }, onError(error) { - this.error = error.message || '获取套餐失败'; + this.error = error.message || this.$t('Failed to get plans'); } }; }, @@ -363,11 +356,11 @@ export default { if (Array.isArray(imagesData) && imagesData.length > 0) { this.images = imagesData; } else { - this.error = '镜像数据格式不正确或为空'; + this.error = this.$t('Image data format is incorrect or empty'); } }, onError(error) { - this.error = error.message || '获取镜像失败'; + this.error = error.message || this.$t('Failed to get images'); } }; }, @@ -377,15 +370,15 @@ export default { url: 'jcloud.api.aliyun_server_light.create_server_order', validate() { if (!this.selectedRegionId || !this.selectedPlanId || !this.selectedImageId) { - throw new DashboardError('请选择完整配置'); + throw new DashboardError(this.$t('Please select complete configuration')); } if (!this.selectedPaymentMethod) { - throw new DashboardError('请选择支付方式'); + throw new DashboardError(this.$t('Please select payment method')); } }, onSuccess(data) { if (!data.success) { - this.error = data.message || '创建服务器订单失败'; + this.error = data.message || this.$t('Failed to create server order'); return; } @@ -398,7 +391,7 @@ export default { this.processPayment(); }, onError(error) { - this.error = error.message || '创建服务器订单失败'; + this.error = error.message || this.$t('Failed to create server order'); } }; }, @@ -408,13 +401,13 @@ export default { url: 'jcloud.api.billing.process_balance_payment_for_server_order', validate() { if (!this.order || !this.order.order_id) { - throw new DashboardError('缺少订单信息'); + throw new DashboardError(this.$t('Missing order information')); } }, onSuccess(response) { if (response.status === "Error" || response.success === false) { - toast.error(response.message || '支付失败,请确保余额充足'); - this.error = response.message || '余额不足'; + toast.error(response.message || this.$t('Payment failed, please ensure sufficient balance')); + this.error = response.message || this.$t('Insufficient balance'); this.isProcessingPayment = false; return; } @@ -439,7 +432,7 @@ export default { }, 30000); }, onError(error) { - this.error = error.message || '余额支付处理失败'; + this.error = error.message || this.$t('Balance payment processing failed'); this.isProcessingPayment = false; } }; @@ -450,20 +443,20 @@ export default { url: 'jcloud.api.billing.process_alipay_order', validate() { if (!this.order || !this.order.order_id) { - throw new DashboardError('缺少订单信息'); + throw new DashboardError(this.$t('Missing order information')); } }, onSuccess(response) { this.paymentUrl = response.payment_url; window.open(response.payment_url, '_blank'); - toast.success('支付页面已在新窗口打开'); + toast.success(this.$t('Payment page opened in new window')); // 开始轮询支付状态 this.startPaymentCheck(); }, onError(error) { - this.error = error.message || '支付宝支付处理失败'; + this.error = error.message || this.$t('Alipay payment processing failed'); this.isProcessingPayment = false; } }; @@ -474,7 +467,7 @@ export default { url: 'jcloud.api.billing.process_wechatpay_order', validate() { if (!this.order || !this.order.order_id) { - throw new DashboardError('缺少订单信息'); + throw new DashboardError(this.$t('Missing order information')); } }, onSuccess(response) { @@ -485,7 +478,7 @@ export default { this.startPaymentCheck(); }, onError(error) { - this.error = error.message || '微信支付处理失败'; + this.error = error.message || this.$t('WeChat Pay payment processing failed'); this.isProcessingPayment = false; } }; @@ -499,7 +492,7 @@ export default { }, validate() { if (!this.order || !this.order.order_id) { - throw new DashboardError('缺少订单信息'); + throw new DashboardError(this.$t('Missing order information')); } }, onSuccess(data) { @@ -565,6 +558,15 @@ export default { }, mounted() { this.$resources.aliyunRegions.submit(); + // Initialize periods with translations + this.periods = [ + { value: 1, label: this.$t('1 month') }, + { value: 3, label: this.$t('3 months') }, + { value: 6, label: this.$t('6 months') }, + { value: 12, label: this.$t('1 year') }, + { value: 24, label: this.$t('2 years') }, + { value: 36, label: this.$t('3 years') } + ]; }, methods: { async onRegionChange() { @@ -592,11 +594,11 @@ export default { }, async createInstance() { if (!this.selectedRegionId || !this.selectedPlanId || !this.selectedImageId) { - this.error = '请选择完整配置'; + this.error = this.$t('Please select complete configuration'); return; } if (!this.selectedPaymentMethod) { - this.error = '请选择支付方式'; + this.error = this.$t('Please select payment method'); return; } @@ -637,7 +639,7 @@ export default { this.error = null; if (!this.order || !this.order.order_id) { - this.error = '订单信息不完整,请重试'; + this.error = this.$t('Order information is incomplete, please try again'); this.isProcessingPayment = false; return; } @@ -694,22 +696,22 @@ export default { let typePrefix = ''; switch (planType) { case 'NORMAL': - typePrefix = '通用型 - '; + typePrefix = this.$t('General Type - '); break; case 'MULTI_IP': - typePrefix = '多公网IP型 - '; + typePrefix = this.$t('Multi Public IP Type - '); break; case 'INTERNATIONAL': - typePrefix = '国际型 - '; + typePrefix = this.$t('International Type - '); break; case 'CAPACITY': - typePrefix = '容量型 - '; + typePrefix = this.$t('Capacity Type - '); break; default: typePrefix = ''; } - return `${typePrefix}${cpu}核/${memoryDisplay}/${disk}GB/${bandwidthDisplay}/${publicIpNum}个公网IP - ¥${price}/月`; + return `${typePrefix}${cpu}${this.$t('cores')}/${memoryDisplay}/${disk}GB/${bandwidthDisplay}/${publicIpNum}${this.$t('public IPs')} - ¥${price}/${this.$t('month')}`; }, getSelectedPlanPrice() { const selectedPlan = this.filteredPlans.find(plan => plan.plan_id === this.selectedPlanId); @@ -728,7 +730,7 @@ export default { }, getImageDisplayName(image) { // 根据阿里云API返回的数据结构显示镜像信息 - const name = image.image_name || image.name || image.ImageName || image.Name || '未知镜像'; + const name = image.image_name || image.name || image.ImageName || image.Name || this.$t('Unknown image'); const platform = image.platform || ''; const description = image.description || ''; @@ -740,11 +742,11 @@ export default { }, getPaymentMethodName(method) { const methodNames = { - 'balance': '余额支付', - 'alipay': '支付宝', - 'wechatpay': '微信支付' + 'balance': this.$t('Balance Payment'), + 'alipay': this.$t('Alipay'), + 'wechatpay': this.$t('WeChat Pay') }; - return methodNames[method] || '未知方式'; + return methodNames[method] || this.$t('Unknown method'); } },