dev #3
@ -19,7 +19,7 @@
|
||||
variant="outline"
|
||||
@click="copyTextContentToClipboard"
|
||||
>
|
||||
{{ copied ? '已复制' : '复制' }}
|
||||
{{ copied ? $t('Copied') : $t('Copy') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
@ -51,7 +51,7 @@ export default {
|
||||
setTimeout(() => {
|
||||
this.copied = false;
|
||||
}, 4000);
|
||||
toast.success('已复制到剪贴板!');
|
||||
toast.success(this.$t('Copied to clipboard!'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,21 +11,21 @@
|
||||
class="space-y-4"
|
||||
>
|
||||
<AlertBanner
|
||||
title="如果禁用双重认证,您的账户将变得不安全"
|
||||
:title="$t('If you disable two-factor authentication, your account will become insecure')"
|
||||
type="error"
|
||||
/>
|
||||
|
||||
<!-- 用户需要遵循的步骤 -->
|
||||
<div class="rounded border border-gray-200 bg-gray-50 p-4">
|
||||
<h3 class="text-lg font-semibold">禁用双重认证的步骤</h3>
|
||||
<h3 class="text-lg font-semibold">{{ $t('Steps to Disable Two-Factor Authentication') }}</h3>
|
||||
<ol class="mt-2 list-disc pl-2 text-sm">
|
||||
<li>打开认证器应用</li>
|
||||
<li>在下方输入应用中的代码</li>
|
||||
<li>{{ $t('Open the authenticator app') }}</li>
|
||||
<li>{{ $t('Enter the code from the app below') }}</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<FormControl
|
||||
label="验证应用中的代码以禁用双重认证"
|
||||
:label="$t('Verify the code in the app to disable two-factor authentication')"
|
||||
v-model="totpCode"
|
||||
/>
|
||||
</div>
|
||||
@ -43,14 +43,14 @@
|
||||
|
||||
<!-- 用户需要遵循的步骤 -->
|
||||
<div class="rounded border border-gray-200 bg-gray-50 p-4">
|
||||
<h3 class="text-lg font-semibold">启用双重认证的步骤</h3>
|
||||
<h3 class="text-lg font-semibold">{{ $t('Steps to Enable Two-Factor Authentication') }}</h3>
|
||||
<ol class="ml-1 mt-2 list-disc pl-2 text-sm text-gray-700">
|
||||
<li>在手机上下载认证器应用,例如阿里云APP等。</li>
|
||||
<li>扫描二维码</li>
|
||||
<li>在下方输入认证器应用中的代码</li>
|
||||
<li>{{ $t('Download an authenticator app on your phone, such as Alibaba Cloud APP, etc.') }}</li>
|
||||
<li>{{ $t('Scan the QR code') }}</li>
|
||||
<li>{{ $t('Enter the code from the authenticator app below') }}</li>
|
||||
</ol>
|
||||
<p class="mt-4 text-sm text-gray-700">
|
||||
<strong>注意:</strong> 如果您无法访问认证器应用,您的账户将被锁定。请确保备份您的保险库/密钥。
|
||||
<strong>{{ $t('Note') }}:</strong> {{ $t('If you cannot access the authenticator app, your account will be locked. Please ensure you back up your vault/key.') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -58,14 +58,14 @@
|
||||
v-if="showSetupKey"
|
||||
class="rounded border border-gray-200 bg-gray-50 p-4"
|
||||
>
|
||||
<h3 class="text-lg font-semibold">设置密钥</h3>
|
||||
<h3 class="text-lg font-semibold">{{ $t('Setup Key') }}</h3>
|
||||
<p class="mt-2 text-sm">
|
||||
{{ setupKey }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<FormControl
|
||||
label="验证应用中的代码以启用双重认证"
|
||||
:label="$t('Verify the code in the app to enable two-factor authentication')"
|
||||
v-model="totpCode"
|
||||
/>
|
||||
</div>
|
||||
@ -75,7 +75,7 @@
|
||||
v-if="!is2FAEnabled"
|
||||
class="w-full"
|
||||
variant="solid"
|
||||
label="启用双重认证"
|
||||
:label="$t('Enable Two-Factor Authentication')"
|
||||
:disabled="!totpCode"
|
||||
:loading="$resources.enable2FA.loading"
|
||||
@click="enable2FA"
|
||||
@ -84,7 +84,7 @@
|
||||
v-else
|
||||
class="w-full"
|
||||
variant="solid"
|
||||
label="禁用双重认证"
|
||||
:label="$t('Disable Two-Factor Authentication')"
|
||||
:disabled="!totpCode"
|
||||
:loading="$resources.disable2FA.loading"
|
||||
@click="disable2FA"
|
||||
@ -118,7 +118,7 @@ qrUrl: '', // not storing as computed property to avoid re-fetching on dialog cl
|
||||
totp_code: this.totpCode
|
||||
}),
|
||||
{
|
||||
loading: '正在启用双因素认证...',
|
||||
loading: this.$t('Enabling two-factor authentication...'),
|
||||
success: () => {
|
||||
this.totpCode = '';
|
||||
|
||||
@ -128,17 +128,17 @@ qrUrl: '', // not storing as computed property to avoid re-fetching on dialog cl
|
||||
}, 500);
|
||||
this.$emit('enabled');
|
||||
|
||||
return '双因素认证已成功启用';
|
||||
return this.$t('Two-factor authentication enabled successfully');
|
||||
},
|
||||
error(err) {
|
||||
if (err.messages) {
|
||||
if (err.messages.includes('Invalid TOTP code')) {
|
||||
return '无效的TOTP验证码,请重试';
|
||||
return this.$t('Invalid TOTP code, please try again');
|
||||
} else {
|
||||
return err.messages.join('.');
|
||||
}
|
||||
} else {
|
||||
return '启用双因素认证失败';
|
||||
return this.$t('Failed to enable two-factor authentication');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,7 +150,7 @@ qrUrl: '', // not storing as computed property to avoid re-fetching on dialog cl
|
||||
totp_code: this.totpCode
|
||||
}),
|
||||
{
|
||||
loading: '正在禁用双因素认证...',
|
||||
loading: this.$t('Disabling two-factor authentication...'),
|
||||
success: () => {
|
||||
this.totpCode = '';
|
||||
|
||||
@ -161,17 +161,17 @@ qrUrl: '', // not storing as computed property to avoid re-fetching on dialog cl
|
||||
|
||||
this.$emit('disabled');
|
||||
|
||||
return '双因素认证已成功禁用';
|
||||
return this.$t('Two-factor authentication disabled successfully');
|
||||
},
|
||||
error(err) {
|
||||
if (err.messages) {
|
||||
if (err.messages.includes('Invalid TOTP code')) {
|
||||
return '无效的TOTP验证码,请重试';
|
||||
return this.$t('Invalid TOTP code, please try again');
|
||||
} else {
|
||||
return err.messages.join('.');
|
||||
}
|
||||
} else {
|
||||
return '禁用双因素认证失败';
|
||||
return this.$t('Failed to disable two-factor authentication');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<Dialog
|
||||
:options="{
|
||||
title: '添加新Webhook',
|
||||
title: $t('Add New Webhook'),
|
||||
actions: [
|
||||
{
|
||||
label: '添加Webhook',
|
||||
label: $t('Add Webhook'),
|
||||
variant: 'solid',
|
||||
onClick: addWebhook,
|
||||
loading: $resources?.addWebhook?.loading
|
||||
@ -14,9 +14,9 @@
|
||||
>
|
||||
<template #body-content>
|
||||
<div class="space-y-4">
|
||||
<FormControl label="端点" v-model="endpoint" />
|
||||
<FormControl :label="$t('Endpoint')" v-model="endpoint" />
|
||||
<div>
|
||||
<FormControl label="密钥" v-model="secret">
|
||||
<FormControl :label="$t('Secret Key')" v-model="secret">
|
||||
<template #suffix>
|
||||
<FeatherIcon
|
||||
class="w-4 cursor-pointer"
|
||||
@ -26,21 +26,21 @@
|
||||
</template>
|
||||
</FormControl>
|
||||
<p class="mt-2 text-sm text-gray-700">
|
||||
<strong>注意:</strong> 密钥是可选的。查看
|
||||
<strong>{{ $t('Note') }}:</strong> {{ $t('The secret key is optional. View') }}
|
||||
<a href="https://jingrow.com/docs/webhook-introduction" class="underline" target="_blank"
|
||||
>文档</a
|
||||
>{{ $t('documentation') }}</a
|
||||
>
|
||||
了解更多
|
||||
{{ $t('to learn more') }}
|
||||
</p>
|
||||
</div>
|
||||
<p class="text-base font-medium text-gray-900">
|
||||
选择Webhook事件
|
||||
{{ $t('Select Webhook Events') }}
|
||||
</p>
|
||||
<div
|
||||
class="text-center text-sm leading-10 text-gray-500"
|
||||
v-if="$resources.events.loading"
|
||||
>
|
||||
加载中...
|
||||
{{ $t('Loading...') }}
|
||||
</div>
|
||||
<div class="mt-6 flex flex-col gap-4" v-else>
|
||||
<Switch
|
||||
@ -94,7 +94,7 @@ export default {
|
||||
events: this.selectedEvents
|
||||
},
|
||||
onSuccess() {
|
||||
toast.success('Webhook添加成功');
|
||||
toast.success(this.$t('Webhook added successfully'));
|
||||
this.$emit('success');
|
||||
}
|
||||
};
|
||||
@ -105,25 +105,27 @@ export default {
|
||||
if (!this.$resources.events.data) return [];
|
||||
|
||||
return this.$resources.events.data.map(event => {
|
||||
// 如果后端已返回title和description字段,则直接使用
|
||||
// 否则根据事件名称进行本地化翻译
|
||||
if (!event.title) {
|
||||
if (event.name === 'Site Status Update') {
|
||||
event.title = '站点状态更新';
|
||||
} else if (event.name === 'Site Plan Change') {
|
||||
event.title = '站点套餐变更';
|
||||
// 创建新对象,避免直接修改原始数据
|
||||
const localizedEvent = { ...event };
|
||||
|
||||
// 根据事件名称进行本地化翻译
|
||||
if (localizedEvent.name === 'Site Status Update') {
|
||||
localizedEvent.title = this.$t('Site Status Update');
|
||||
localizedEvent.description = this.$t('Pending, Installing, Updating, Active, Inactive, Abnormal, Archived, Paused');
|
||||
} else if (localizedEvent.name === 'Site Plan Change') {
|
||||
localizedEvent.title = this.$t('Site Plan Change');
|
||||
localizedEvent.description = this.$t('Get notifications for site subscription plan changes');
|
||||
} else {
|
||||
// 对于其他事件,如果没有title则使用name,如果没有description则使用空字符串
|
||||
if (!localizedEvent.title) {
|
||||
localizedEvent.title = localizedEvent.name;
|
||||
}
|
||||
if (!localizedEvent.description) {
|
||||
localizedEvent.description = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!event.description || event.description.includes('Pending') || event.description.includes('Get notified')) {
|
||||
if (event.name === 'Site Status Update') {
|
||||
event.description = '等待中、安装中、更新中、活跃、不活跃、异常、已归档、已暂停';
|
||||
} else if (event.name === 'Site Plan Change') {
|
||||
event.description = '获取站点套餐变更的通知';
|
||||
}
|
||||
}
|
||||
|
||||
return event;
|
||||
return localizedEvent;
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -151,11 +153,11 @@ export default {
|
||||
},
|
||||
addWebhook() {
|
||||
if (!this.endpoint) {
|
||||
this.errorMessage = '请提供有效的Webhook端点';
|
||||
this.errorMessage = this.$t('Please provide a valid webhook endpoint');
|
||||
return;
|
||||
}
|
||||
if (!this.selectedEvents.length) {
|
||||
this.errorMessage = '请启用至少一个事件';
|
||||
this.errorMessage = this.$t('Please enable at least one event');
|
||||
return;
|
||||
}
|
||||
this.errorMessage = '';
|
||||
|
||||
@ -118,6 +118,10 @@ const listOptions = ref({
|
||||
autocomplete: 'off',
|
||||
},
|
||||
],
|
||||
primaryAction: {
|
||||
label: $t('Confirm'),
|
||||
variant: 'solid'
|
||||
},
|
||||
onSuccess({ hide, values }) {
|
||||
if (values.title) {
|
||||
return groups.insert.submit(
|
||||
|
||||
@ -411,6 +411,10 @@ url: 'jcloud.api.billing.get_unpaid_invoices',
|
||||
confirmDialog({
|
||||
title: this.$t('Become a Marketplace Developer?'),
|
||||
message: this.$t('After confirmation, you will be able to publish apps to our marketplace.'),
|
||||
primaryAction: {
|
||||
label: this.$t('Confirm'),
|
||||
variant: 'solid'
|
||||
},
|
||||
onSuccess: ({ hide }) => {
|
||||
toast.promise(
|
||||
this.$team.setValue.submit(
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Dialog v-model="showDialog" :options="{ title: '重置密码' }">
|
||||
<Dialog v-model="showDialog" :options="{ title: $t('Reset Password') }">
|
||||
<template #body-content>
|
||||
<div class="space-y-4">
|
||||
<div v-if="!isResetMode" class="space-y-4">
|
||||
@ -7,10 +7,10 @@
|
||||
v-model="oldPassword"
|
||||
type="password"
|
||||
:fieldtype="'Password'"
|
||||
:label="'当前密码'"
|
||||
:label="$t('Current Password')"
|
||||
:fieldname="'old_password'"
|
||||
:reqd="1"
|
||||
:placeholder="'请输入当前密码'"
|
||||
:placeholder="$t('Please enter current password')"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
@ -18,10 +18,10 @@
|
||||
v-model="newPassword"
|
||||
type="password"
|
||||
:fieldtype="'Password'"
|
||||
:label="'新密码'"
|
||||
:label="$t('New Password')"
|
||||
:fieldname="'new_password'"
|
||||
:reqd="1"
|
||||
:placeholder="'请输入新密码'"
|
||||
:placeholder="$t('Please enter new password')"
|
||||
/>
|
||||
<div v-if="passwordStrengthMessage" class="text-sm" :class="passwordStrengthClass">
|
||||
{{ passwordStrengthMessage }}
|
||||
@ -30,10 +30,10 @@
|
||||
v-model="confirmPassword"
|
||||
type="password"
|
||||
:fieldtype="'Password'"
|
||||
:label="'确认密码'"
|
||||
:label="$t('Confirm Password')"
|
||||
:fieldname="'confirm_password'"
|
||||
:reqd="1"
|
||||
:placeholder="'请再次输入新密码'"
|
||||
:placeholder="$t('Please re-enter new password')"
|
||||
/>
|
||||
<div v-if="passwordMismatchMessage" class="text-sm text-red-600">
|
||||
{{ passwordMismatchMessage }}
|
||||
@ -49,7 +49,7 @@
|
||||
class="flex-1"
|
||||
@click="hide"
|
||||
>
|
||||
取消
|
||||
{{ $t('Cancel') }}
|
||||
</Button>
|
||||
<Button
|
||||
variant="solid"
|
||||
@ -58,7 +58,7 @@
|
||||
:disabled="!isFormValid"
|
||||
@click="onConfirm"
|
||||
>
|
||||
确认
|
||||
{{ $t('Confirm') }}
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
@ -152,10 +152,10 @@ export default {
|
||||
|
||||
checkPasswordMismatch() {
|
||||
if (this.oldPassword && this.newPassword && this.oldPassword === this.newPassword) {
|
||||
this.passwordMismatchMessage = '新密码不能与当前密码相同';
|
||||
this.passwordMismatchMessage = this.$t('New password cannot be the same as current password');
|
||||
this.passwordStrengthMessage = '';
|
||||
} else if (this.confirmPassword && this.newPassword !== this.confirmPassword) {
|
||||
this.passwordMismatchMessage = '两次输入的密码不一致';
|
||||
this.passwordMismatchMessage = this.$t('Passwords do not match');
|
||||
this.passwordStrengthMessage = '';
|
||||
} else {
|
||||
this.passwordMismatchMessage = '';
|
||||
@ -178,7 +178,7 @@ export default {
|
||||
logout_all_sessions: 1
|
||||
});
|
||||
} catch (error) {
|
||||
this.error = error.message || '密码更新失败';
|
||||
this.error = error.message || this.$t('Failed to update password');
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
@ -186,22 +186,22 @@ export default {
|
||||
|
||||
validateForm() {
|
||||
if (!this.isResetMode && !this.oldPassword) {
|
||||
this.error = '请输入当前密码';
|
||||
this.error = this.$t('Please enter current password');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.newPassword) {
|
||||
this.error = '请输入新密码';
|
||||
this.error = this.$t('Please enter new password');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.newPassword !== this.confirmPassword) {
|
||||
this.error = '两次输入的密码不一致';
|
||||
this.error = this.$t('Passwords do not match');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.isResetMode && this.oldPassword === this.newPassword) {
|
||||
this.error = '新密码不能与当前密码相同';
|
||||
this.error = this.$t('New password cannot be the same as current password');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -247,7 +247,7 @@ export default {
|
||||
const feedback = data.message.feedback;
|
||||
|
||||
if (feedback.password_policy_validation_passed) {
|
||||
this.passwordStrengthMessage = '密码强度良好 👍';
|
||||
this.passwordStrengthMessage = this.$t('Password strength is good 👍');
|
||||
this.passwordStrengthClass = 'text-green-600';
|
||||
} else {
|
||||
let message = [];
|
||||
@ -256,7 +256,7 @@ export default {
|
||||
} else if (feedback.warning) {
|
||||
message.push(feedback.warning);
|
||||
}
|
||||
message.push('提示:密码应包含符号、数字和大写字母');
|
||||
message.push(this.$t('Tip: Password should contain symbols, numbers and uppercase letters'));
|
||||
this.passwordStrengthMessage = message.join(' ');
|
||||
this.passwordStrengthClass = 'text-red-600';
|
||||
}
|
||||
@ -273,9 +273,9 @@ export default {
|
||||
url: 'jingrow.core.pagetype.user.user.update_password',
|
||||
onSuccess(data) {
|
||||
// 显示成功提示,5秒后自动消失
|
||||
toast.success('密码更新成功', {
|
||||
toast.success(this.$t('Password updated successfully'), {
|
||||
duration: 3000,
|
||||
description: '您的密码已更新'
|
||||
description: this.$t('Your password has been updated')
|
||||
});
|
||||
|
||||
// 立即关闭对话框
|
||||
@ -290,9 +290,9 @@ export default {
|
||||
},
|
||||
onError(error) {
|
||||
if (error.status === 401) {
|
||||
this.error = '当前密码不正确';
|
||||
this.error = this.$t('Current password is incorrect');
|
||||
} else {
|
||||
this.error = error.message || '密码更新失败';
|
||||
this.error = error.message || this.$t('Failed to update password');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
v-model="show"
|
||||
:options="{
|
||||
title: is2FAEnabled
|
||||
? '禁用双因素认证'
|
||||
: '启用双因素认证'
|
||||
? $t('Disable Two-Factor Authentication')
|
||||
: $t('Enable Two-Factor Authentication')
|
||||
}"
|
||||
>
|
||||
<template #body-content>
|
||||
|
||||
@ -81,7 +81,7 @@ export default {
|
||||
computed: {
|
||||
primaryActionProps() {
|
||||
return {
|
||||
label: '确认',
|
||||
label: this.$t('Confirm'),
|
||||
variant: 'solid',
|
||||
...this.primaryAction,
|
||||
loading: this.isLoading,
|
||||
|
||||
@ -978,3 +978,55 @@ Default,默认,
|
||||
Release Group,发布组,
|
||||
Note,注意,
|
||||
Submit,提交,
|
||||
Copy,复制,
|
||||
Copied,已复制,
|
||||
Copied to clipboard!,已复制到剪贴板!,
|
||||
Confirm,确认,
|
||||
Current Password,当前密码,
|
||||
Please enter current password,请输入当前密码,
|
||||
New Password,新密码,
|
||||
Please enter new password,请输入新密码,
|
||||
Confirm Password,确认密码,
|
||||
Please re-enter new password,请再次输入新密码,
|
||||
New password cannot be the same as current password,新密码不能与当前密码相同,
|
||||
Passwords do not match,两次输入的密码不一致,
|
||||
Failed to update password,密码更新失败,
|
||||
Password strength is good 👍,密码强度良好 👍,
|
||||
Tip: Password should contain symbols, numbers and uppercase letters,提示:密码应包含符号、数字和大写字母,
|
||||
Password updated successfully,密码更新成功,
|
||||
Your password has been updated,您的密码已更新,
|
||||
Current password is incorrect,当前密码不正确,
|
||||
Cancel,取消,
|
||||
Add New Webhook,添加新Webhook,
|
||||
Secret Key,密钥,
|
||||
The secret key is optional. View,密钥是可选的。查看,
|
||||
documentation,文档,
|
||||
to learn more,了解更多,
|
||||
Select Webhook Events,选择Webhook事件,
|
||||
Loading...,加载中...,
|
||||
Webhook added successfully,Webhook添加成功,
|
||||
Site Status Update,站点状态更新,
|
||||
Site Plan Change,站点套餐变更,
|
||||
Pending, Installing, Updating, Active, Inactive, Abnormal, Archived, Paused,等待中、安装中、更新中、活跃、不活跃、异常、已归档、已暂停,
|
||||
Get notifications for site subscription plan changes,获取站点套餐变更的通知,
|
||||
Please provide a valid webhook endpoint,请提供有效的Webhook端点,
|
||||
Please enable at least one event,请启用至少一个事件,
|
||||
If you disable two-factor authentication, your account will become insecure,如果禁用双重认证,您的账户将变得不安全,
|
||||
Steps to Disable Two-Factor Authentication,禁用双重认证的步骤,
|
||||
Open the authenticator app,打开认证器应用,
|
||||
Enter the code from the app below,在下方输入应用中的代码,
|
||||
Verify the code in the app to disable two-factor authentication,验证应用中的代码以禁用双重认证,
|
||||
Steps to Enable Two-Factor Authentication,启用双重认证的步骤,
|
||||
Download an authenticator app on your phone, such as Alibaba Cloud APP, etc.,在手机上下载认证器应用,例如阿里云APP等。,
|
||||
Scan the QR code,扫描二维码,
|
||||
Enter the code from the authenticator app below,在下方输入认证器应用中的代码,
|
||||
If you cannot access the authenticator app, your account will be locked. Please ensure you back up your vault/key.,如果您无法访问认证器应用,您的账户将被锁定。请确保备份您的保险库/密钥。,
|
||||
Setup Key,设置密钥,
|
||||
Verify the code in the app to enable two-factor authentication,验证应用中的代码以启用双重认证,
|
||||
Enabling two-factor authentication...,正在启用双因素认证...,
|
||||
Two-factor authentication enabled successfully,双因素认证已成功启用,
|
||||
Invalid TOTP code, please try again,无效的TOTP验证码,请重试,
|
||||
Failed to enable two-factor authentication,启用双因素认证失败,
|
||||
Disabling two-factor authentication...,正在禁用双因素认证...,
|
||||
Two-factor authentication disabled successfully,双因素认证已成功禁用,
|
||||
Failed to disable two-factor authentication,禁用双因素认证失败,
|
||||
|
||||
|
Can't render this file because it has a wrong number of fields in line 390.
|
Loading…
x
Reference in New Issue
Block a user