refactor(i18n): U34 System & User 模块 i18n 清理 — ProfilePage + ResetPasswordDialog + SystemRolesTab + LdapManagementSection 4 文件 UI 硬编码中文清零
- ProfilePage.tsx: 从零接入 useTranslation,基本信息/安全设置/密码修改/用户名邮箱手机/账号来源 15 处中文→t() - ResetPasswordDialog.tsx: 从零接入 useTranslation,重置密码标题/描述/LDAP提示/新密码确认密码/确认重置 11 处中文→t() - SystemRolesTab.tsx: 权限分组标签(云资源/自动化/审批/审计)+toast 校验+confirm description+角色计数+空状态+权限列表计数+编码标签+尾部文案 12 处中文→t()/i18n.t() - LdapManagementSection.tsx: 验证按钮+根OU标签+创建按钮×2+导入按钮+编辑用户描述 8 处中文→t() - 新增 user.profile.* 14键 + user.resetPwd.* 11键 + system.* 16键 共 41 翻译键 - zh/en 7524→7565 +41 对齐 - tsc -b=0, npm build✓ (16.05s), ESLint errors=0/any=0/unused=0, go build=0 - 17/17 集成回归测试通过
This commit is contained in:
1 parent
ad9acea1e5
commit
0dbb85f5b8
7 files changed
+141
-46
No files matched your search
@@ -204,7 +204,7 @@ export function LdapManagementSection(props: LdapManagementSectionProps) {
|
||||
disabled={ldapUserTesting || !ldapTestUser}
|
||||
>
|
||||
{ldapUserTesting ? <Loader2 className="h-4 w-4 mr-1.5 animate-spin" /> : null}
|
||||
验证
|
||||
{t('system.testConnection')}
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
@@ -221,7 +221,7 @@ export function LdapManagementSection(props: LdapManagementSectionProps) {
|
||||
<SelectValue placeholder={t('system.selectOu')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="dg-input">
|
||||
<SelectItem value={ldapConfig.base_dn}>根 ({ldapConfig.base_dn})</SelectItem>
|
||||
<SelectItem value={ldapConfig.base_dn}>{t('system.rootOu', { dn: ldapConfig.base_dn })}</SelectItem>
|
||||
{ldapOUs.map((ou: JsonData) => (
|
||||
<SelectItem key={ou.dn} value={ou.dn}>
|
||||
{ou.description ? `${ou.name} (${ou.description})` : ou.name}
|
||||
@@ -258,7 +258,7 @@ export function LdapManagementSection(props: LdapManagementSectionProps) {
|
||||
</div>
|
||||
<Button className="w-full bg-blue-600 hover:bg-blue-700 text-white" onClick={handleCreateOU} disabled={!ouForm.ou_name || ldapSaving}>
|
||||
{ldapSaving ? <Loader2 className="h-4 w-4 mr-1.5 animate-spin" /> : null}
|
||||
创建
|
||||
{t('common.create')}
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
@@ -300,7 +300,7 @@ export function LdapManagementSection(props: LdapManagementSectionProps) {
|
||||
</div>
|
||||
<Button className="w-full bg-blue-600 hover:bg-blue-700 text-white" onClick={handleCreateLDAPUser} disabled={!newUser.username || !newUser.password || ldapSaving}>
|
||||
{ldapSaving ? <Loader2 className="h-4 w-4 mr-1.5 animate-spin" /> : null}
|
||||
创建
|
||||
{t('common.create')}
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
@@ -315,7 +315,7 @@ export function LdapManagementSection(props: LdapManagementSectionProps) {
|
||||
disabled={ldapUsers.length === 0 || importing}
|
||||
>
|
||||
{importing ? <Loader2 className="h-3.5 w-3.5 mr-1 animate-spin" /> : <Download className="h-3.5 w-3.5 mr-1" />}
|
||||
{selectedLDAPUsers.length > 0 ? `导入 (${selectedLDAPUsers.length})` : `导入全部 (${ldapUsers.length})`}
|
||||
{selectedLDAPUsers.length > 0 ? t('system.importSelected', { count: selectedLDAPUsers.length }) : t('system.importAll', { count: ldapUsers.length })}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -427,7 +427,7 @@ export function LdapManagementSection(props: LdapManagementSectionProps) {
|
||||
{t('system.editLdapUser')}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="dg-text-muted">
|
||||
修改 {editLdapUser?.uid} 的属性
|
||||
{t('system.editLdapUserDesc', { uid: editLdapUser?.uid })}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
{editLdapUser && (
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// 管理员重置用户密码弹窗 // Logan.Li
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
@@ -17,6 +18,7 @@ interface ResetPasswordDialogProps {
|
||||
}
|
||||
|
||||
export function ResetPasswordDialog({ user, onClose }: ResetPasswordDialogProps) {
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const [password, setPassword] = useState('');
|
||||
const [confirm, setConfirm] = useState('');
|
||||
@@ -30,12 +32,12 @@ export function ResetPasswordDialog({ user, onClose }: ResetPasswordDialogProps)
|
||||
setSaving(true);
|
||||
try {
|
||||
await userApi.resetUserPassword(user.id, password);
|
||||
toast({ title: '密码已重置', description: `用户 ${user.nickname || user.username} 的新密码已生效` });
|
||||
toast({ title: t('user.resetPwd.success'), description: t('user.resetPwd.successDesc', { name: user.nickname || user.username }) });
|
||||
setPassword('');
|
||||
setConfirm('');
|
||||
onClose();
|
||||
} catch (e: unknown) {
|
||||
toast({ title: '重置失败', description: getErrorMessage(e), variant: 'destructive' });
|
||||
toast({ title: t('user.resetPwd.failed'), description: getErrorMessage(e), variant: 'destructive' });
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
@@ -47,34 +49,34 @@ export function ResetPasswordDialog({ user, onClose }: ResetPasswordDialogProps)
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-[var(--dg-text-primary)] flex items-center gap-2">
|
||||
<Key className="h-5 w-5 text-[var(--dg-blue)]" />
|
||||
重置密码
|
||||
{t('user.resetPwd.title')}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-[var(--dg-text-muted)]">
|
||||
{user ? `为「${user.nickname || user.username}」设置新密码` : ''}
|
||||
{user ? t('user.resetPwd.desc', { name: user.nickname || user.username }) : ''}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
{isLdap ? (
|
||||
<p className="text-sm dg-text-yellow/90 py-2">LDAP 用户请在 LDAP 目录中管理密码,不支持本地重置。</p>
|
||||
<p className="text-sm dg-text-yellow/90 py-2">{t('user.resetPwd.ldapHint')}</p>
|
||||
) : (
|
||||
<div className="space-y-3 py-1">
|
||||
<div>
|
||||
<Label className="text-xs text-[var(--dg-text-muted)]">新密码</Label>
|
||||
<Label className="text-xs text-[var(--dg-text-muted)]">{t('user.resetPwd.newPwd')}</Label>
|
||||
<Input
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
placeholder="至少 6 位"
|
||||
placeholder={t('user.resetPwd.newPwdPlaceholder')}
|
||||
className="mt-1 h-9 bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)]"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-xs text-[var(--dg-text-muted)]">确认密码</Label>
|
||||
<Label className="text-xs text-[var(--dg-text-muted)]">{t('user.resetPwd.confirmPwd')}</Label>
|
||||
<Input
|
||||
type="password"
|
||||
value={confirm}
|
||||
onChange={e => setConfirm(e.target.value)}
|
||||
placeholder="再次输入新密码"
|
||||
placeholder={t('user.resetPwd.confirmPlaceholder')}
|
||||
className="mt-1 h-9 bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)]"
|
||||
/>
|
||||
</div>
|
||||
@@ -82,11 +84,11 @@ export function ResetPasswordDialog({ user, onClose }: ResetPasswordDialogProps)
|
||||
)}
|
||||
|
||||
<DialogFooter>
|
||||
<Button variant="outline" className="border-[var(--dg-border)]" onClick={onClose}>取消</Button>
|
||||
<Button variant="outline" className="border-[var(--dg-border)]" onClick={onClose}>{t('common.cancel')}</Button>
|
||||
{!isLdap && (
|
||||
<Button onClick={handleReset} disabled={!canSubmit || saving} className="bg-[var(--dg-blue)] hover:opacity-90">
|
||||
{saving ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : null}
|
||||
确认重置
|
||||
{t('user.resetPwd.confirm')}
|
||||
</Button>
|
||||
)}
|
||||
</DialogFooter>
|
||||
|
||||
@@ -35,14 +35,14 @@ const ROLE_ICONS: Record<string, string> = {
|
||||
const PERM_MODULE_GROUPS: { label: string; prefixes: string[] }[] = [
|
||||
{ label: i18n.t('menu.dashboard'), prefixes: ['dashboard:'] },
|
||||
{ label: i18n.t('menu.assets'), prefixes: ['server:'] },
|
||||
{ label: '云资源', prefixes: ['cloud:'] },
|
||||
{ label: i18n.t('system.permCloudResource'), prefixes: ['cloud:'] },
|
||||
{ label: 'K8s', prefixes: ['k8s:'] },
|
||||
{ label: i18n.t('common.publish'), prefixes: ['deploy:'] },
|
||||
{ label: i18n.t('monitor.hostDashboard.monitor'), prefixes: ['monitor:', 'agent:'] },
|
||||
{ label: '自动化', prefixes: ['auto:'] },
|
||||
{ label: i18n.t('system.permAutomation'), prefixes: ['auto:'] },
|
||||
{ label: 'AI', prefixes: ['aiops:'] },
|
||||
{ label: '审批', prefixes: ['approval:'] },
|
||||
{ label: '审计', prefixes: ['audit:'] },
|
||||
{ label: i18n.t('system.permApproval'), prefixes: ['approval:'] },
|
||||
{ label: i18n.t('system.permAudit'), prefixes: ['audit:'] },
|
||||
{ label: i18n.t('common.system3'), prefixes: ['system:'] },
|
||||
];
|
||||
|
||||
@@ -138,8 +138,8 @@ export function SystemRolesTab({ selectedRole, setSelectedRole }: SystemRolesTab
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!form.name.trim()) { toast.error('请输入角色名称'); return; }
|
||||
if (!form.code.trim()) { toast.error('请输入角色编码'); return; }
|
||||
if (!form.name.trim()) { toast.error(t('system.roleNameRequired')); return; }
|
||||
if (!form.code.trim()) { toast.error(t('system.roleCodeRequired')); return; }
|
||||
setSaving(true);
|
||||
try {
|
||||
const payload = {
|
||||
@@ -171,7 +171,7 @@ export function SystemRolesTab({ selectedRole, setSelectedRole }: SystemRolesTab
|
||||
}
|
||||
const ok = await confirm({
|
||||
title: t('system.deleteRole'),
|
||||
description: `确认删除角色「${role.name}」吗?该操作不可恢复。`,
|
||||
description: t('system.confirmDeleteRoleDesc', { name: role.name }),
|
||||
confirmText: t('common.delete'),
|
||||
variant: 'destructive',
|
||||
});
|
||||
@@ -192,12 +192,12 @@ export function SystemRolesTab({ selectedRole, setSelectedRole }: SystemRolesTab
|
||||
<ShieldCheck className="h-5 w-5 dg-text-blue shrink-0 mt-0.5" />
|
||||
<div className="text-sm text-[var(--dg-text-secondary)] space-y-1">
|
||||
<p className="font-medium text-[var(--dg-text-primary)]">{t('system.permHowEffect')}</p>
|
||||
<p>{t('system.permEffectDesc')}<strong className="text-[var(--dg-text-primary)]">{t('system.permBackendAuth')}</strong>{t('monitor.logCenterArch.connector')}<strong className="text-[var(--dg-text-primary)]">{t('system.permEffectFrontend')}</strong>,修改后用户需重新登录生效。</p>
|
||||
<p>{t('system.permEffectDesc')}<strong className="text-[var(--dg-text-primary)]">{t('system.permBackendAuth')}</strong>{t('monitor.logCenterArch.connector')}<strong className="text-[var(--dg-text-primary)]">{t('system.permEffectFrontend')}</strong>{t('system.permEffectTrailing')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<span className="text-xs text-[var(--dg-text-muted)]">{roles.length} 个角色</span>
|
||||
<span className="text-xs text-[var(--dg-text-muted)]">{t('system.roleCount', { count: roles.length })}</span>
|
||||
<Button className="bg-blue-600 hover:bg-blue-700 text-white" onClick={openCreate}>
|
||||
<Plus className="h-4 w-4 mr-2" />{t('pipeline.newRole')}
|
||||
</Button>
|
||||
@@ -210,7 +210,7 @@ export function SystemRolesTab({ selectedRole, setSelectedRole }: SystemRolesTab
|
||||
) : roles.length === 0 ? (
|
||||
<div className="flex flex-col items-center justify-center py-16 text-[var(--dg-text-muted)]">
|
||||
<Shield className="h-10 w-10 mb-3 opacity-40" />
|
||||
<p className="text-sm">暂无角色数据</p>
|
||||
<p className="text-sm">{t('system.noRoleData')}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
@@ -321,7 +321,7 @@ function RoleDetailDialog({
|
||||
</Badge>
|
||||
)}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-[var(--dg-text-muted)]">编码:{role?.code}</DialogDescription>
|
||||
<DialogDescription className="text-[var(--dg-text-muted)]">{t('system.roleCodeLabel', { code: role?.code })}</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="rounded-lg bg-[var(--dg-bg-tertiary)] p-4">
|
||||
@@ -330,7 +330,7 @@ function RoleDetailDialog({
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-sm font-medium text-[var(--dg-text-primary)] mb-2">
|
||||
权限列表 ({role?.permissions?.length || 0} 项)
|
||||
{t('system.permListCount', { count: role?.permissions?.length || 0 })}
|
||||
</h4>
|
||||
{role && (role.permissions as string[]).length > 0 ? (
|
||||
<div className="flex flex-wrap gap-2 max-h-60 overflow-y-auto">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// ProfilePage — 个人中心(基本信息 / 安全 / API 访问密钥)// Logan.Li
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
@@ -29,6 +30,7 @@ type Profile = {
|
||||
}
|
||||
|
||||
export default function ProfilePage() {
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const storeUser = useUserStore(s => s.user);
|
||||
|
||||
@@ -51,7 +53,7 @@ export default function ProfilePage() {
|
||||
|
||||
useEffect(() => { load(); }, [load]);
|
||||
|
||||
const displayName = profile?.real_name || profile?.nickname || storeUser?.nickname || storeUser?.username || '用户';
|
||||
const displayName = profile?.real_name || profile?.nickname || storeUser?.nickname || storeUser?.username || t('user.profile.defaultUser');
|
||||
const username = profile?.username || storeUser?.username || '';
|
||||
|
||||
const handleChangePassword = async () => {
|
||||
@@ -59,11 +61,11 @@ export default function ProfilePage() {
|
||||
setPwdSaving(true);
|
||||
try {
|
||||
await authApi.changePassword({ old_password: oldPwd, new_password: newPwd });
|
||||
toast({ title: '密码已修改' });
|
||||
toast({ title: t('user.profile.pwdChanged') });
|
||||
setOldPwd('');
|
||||
setNewPwd('');
|
||||
} catch (e: unknown) {
|
||||
toast({ title: '修改失败', description: getErrorMessage(e), variant: 'destructive' });
|
||||
toast({ title: t('user.profile.pwdChangeFailed'), description: getErrorMessage(e), variant: 'destructive' });
|
||||
} finally {
|
||||
setPwdSaving(false);
|
||||
}
|
||||
@@ -77,7 +79,7 @@ export default function ProfilePage() {
|
||||
subtitle={`@${username} · ${profile?.email || '—'}`}
|
||||
icon={<User className="h-5 w-5" />}
|
||||
loading={loading}
|
||||
loadingLabel="加载中..."
|
||||
loadingLabel={t('common.loading')}
|
||||
actions={(
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
{(profile?.roles || []).map((r) => (
|
||||
@@ -92,15 +94,15 @@ export default function ProfilePage() {
|
||||
<Card className="dg-card">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-base flex items-center gap-2 text-[var(--dg-text-primary)]">
|
||||
<User className="h-4 w-4 text-[var(--dg-blue)]" />基本信息
|
||||
<User className="h-4 w-4 text-[var(--dg-blue)]" />{t('user.profile.basicInfo')}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3 text-sm">
|
||||
<div className="flex justify-between"><span className="text-[var(--dg-text-muted)]">用户名</span><span className="font-mono">{username}</span></div>
|
||||
<div className="flex justify-between"><span className="text-[var(--dg-text-muted)]">邮箱</span><span>{profile?.email || '—'}</span></div>
|
||||
<div className="flex justify-between"><span className="text-[var(--dg-text-muted)]">手机</span><span>{profile?.phone || '—'}</span></div>
|
||||
<div className="flex justify-between"><span className="text-[var(--dg-text-muted)]">账号来源</span>
|
||||
<Badge variant="outline" className="text-xs">{profile?.auth_source === 'ldap' ? 'LDAP' : '本地'}</Badge>
|
||||
<div className="flex justify-between"><span className="text-[var(--dg-text-muted)]">{t('user.profile.username')}</span><span className="font-mono">{username}</span></div>
|
||||
<div className="flex justify-between"><span className="text-[var(--dg-text-muted)]">{t('user.profile.email')}</span><span>{profile?.email || '—'}</span></div>
|
||||
<div className="flex justify-between"><span className="text-[var(--dg-text-muted)]">{t('user.profile.phone')}</span><span>{profile?.phone || '—'}</span></div>
|
||||
<div className="flex justify-between"><span className="text-[var(--dg-text-muted)]">{t('user.profile.authSource')}</span>
|
||||
<Badge variant="outline" className="text-xs">{profile?.auth_source === 'ldap' ? 'LDAP' : t('user.profile.local')}</Badge>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -108,22 +110,22 @@ export default function ProfilePage() {
|
||||
<Card className="dg-card">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-base flex items-center gap-2 text-[var(--dg-text-primary)]">
|
||||
<Shield className="h-4 w-4 dg-text-green" />安全设置
|
||||
<Shield className="h-4 w-4 dg-text-green" />{t('user.profile.security')}
|
||||
</CardTitle>
|
||||
<CardDescription className="text-xs">修改登录密码</CardDescription>
|
||||
<CardDescription className="text-xs">{t('user.profile.changePwd')}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<div>
|
||||
<Label className="text-xs text-[var(--dg-text-muted)]">当前密码</Label>
|
||||
<Label className="text-xs text-[var(--dg-text-muted)]">{t('user.profile.currentPwd')}</Label>
|
||||
<Input type="password" value={oldPwd} onChange={e => setOldPwd(e.target.value)} className="mt-1 h-9 bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)]" />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-xs text-[var(--dg-text-muted)]">新密码</Label>
|
||||
<Label className="text-xs text-[var(--dg-text-muted)]">{t('user.profile.newPwd')}</Label>
|
||||
<Input type="password" value={newPwd} onChange={e => setNewPwd(e.target.value)} className="mt-1 h-9 bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)]" />
|
||||
</div>
|
||||
<Button size="sm" onClick={handleChangePassword} disabled={pwdSaving || !oldPwd || newPwd.length < 6}>
|
||||
{pwdSaving ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : null}
|
||||
保存密码
|
||||
{t('user.profile.savePwd')}
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -7455,7 +7455,23 @@
|
||||
"loadFailed": "Failed to load audit settings",
|
||||
"invalidRetentionDays": "Please select valid retention days",
|
||||
"noExpiredRecords": ", no expired records"
|
||||
}
|
||||
},
|
||||
"permCloudResource": "Cloud Resources",
|
||||
"permAutomation": "Automation",
|
||||
"permApproval": "Approval",
|
||||
"permAudit": "Audit",
|
||||
"roleCodeRequired": "Please enter role code",
|
||||
"confirmDeleteRoleDesc": "Are you sure to delete role \"{{name}}\"? This action cannot be undone.",
|
||||
"roleCount": "{{count}} roles",
|
||||
"noRoleData": "No role data",
|
||||
"permListCount": "Permissions ({{count}})",
|
||||
"roleCodeLabel": "Code: {{code}}",
|
||||
"testConnection": "Verify",
|
||||
"rootOu": "Root ({{dn}})",
|
||||
"importSelected": "Import ({{count}})",
|
||||
"importAll": "Import All ({{count}})",
|
||||
"editLdapUserDesc": "Modify attributes of {{uid}}",
|
||||
"permEffectTrailing": ", changes take effect after user re-login."
|
||||
},
|
||||
"aiops": {
|
||||
"title": "AIOps",
|
||||
@@ -8273,6 +8289,35 @@
|
||||
"credentialCopied": "Credential copied",
|
||||
"saved": "I've saved it",
|
||||
"placeholderToken": "Your access credential"
|
||||
},
|
||||
"profile": {
|
||||
"basicInfo": "Basic Info",
|
||||
"security": "Security",
|
||||
"changePwd": "Change Login Password",
|
||||
"currentPwd": "Current Password",
|
||||
"newPwd": "New Password",
|
||||
"savePwd": "Save Password",
|
||||
"username": "Username",
|
||||
"email": "Email",
|
||||
"phone": "Phone",
|
||||
"authSource": "Account Source",
|
||||
"local": "Local",
|
||||
"pwdChanged": "Password Changed",
|
||||
"pwdChangeFailed": "Change Failed",
|
||||
"defaultUser": "User"
|
||||
},
|
||||
"resetPwd": {
|
||||
"title": "Reset Password",
|
||||
"desc": "Set a new password for \"{{name}}\"",
|
||||
"ldapHint": "LDAP users must manage passwords in the LDAP directory. Local reset is not supported.",
|
||||
"newPwd": "New Password",
|
||||
"newPwdPlaceholder": "At least 6 characters",
|
||||
"confirmPwd": "Confirm Password",
|
||||
"confirmPlaceholder": "Enter the new password again",
|
||||
"confirm": "Confirm Reset",
|
||||
"success": "Password Reset",
|
||||
"successDesc": "New password for user {{name}} is now active",
|
||||
"failed": "Reset Failed"
|
||||
}
|
||||
},
|
||||
"logCenter": {
|
||||
|
||||
@@ -7455,7 +7455,23 @@
|
||||
"loadFailed": "加载审计设置失败",
|
||||
"invalidRetentionDays": "请选择有效的保留天数",
|
||||
"noExpiredRecords": ",无超期记录"
|
||||
}
|
||||
},
|
||||
"permCloudResource": "云资源",
|
||||
"permAutomation": "自动化",
|
||||
"permApproval": "审批",
|
||||
"permAudit": "审计",
|
||||
"roleCodeRequired": "请输入角色编码",
|
||||
"confirmDeleteRoleDesc": "确认删除角色「{{name}}」吗?该操作不可恢复。",
|
||||
"roleCount": "{{count}} 个角色",
|
||||
"noRoleData": "暂无角色数据",
|
||||
"permListCount": "权限列表 ({{count}} 项)",
|
||||
"roleCodeLabel": "编码:{{code}}",
|
||||
"testConnection": "验证",
|
||||
"rootOu": "根 ({{dn}})",
|
||||
"importSelected": "导入 ({{count}})",
|
||||
"importAll": "导入全部 ({{count}})",
|
||||
"editLdapUserDesc": "修改 {{uid}} 的属性",
|
||||
"permEffectTrailing": ",修改后用户需重新登录生效。"
|
||||
},
|
||||
"aiops": {
|
||||
"title": "AIOps 智能",
|
||||
@@ -8273,6 +8289,35 @@
|
||||
"credentialCopied": "凭证已复制",
|
||||
"saved": "我已保存",
|
||||
"placeholderToken": "你的访问凭证"
|
||||
},
|
||||
"profile": {
|
||||
"basicInfo": "基本信息",
|
||||
"security": "安全设置",
|
||||
"changePwd": "修改登录密码",
|
||||
"currentPwd": "当前密码",
|
||||
"newPwd": "新密码",
|
||||
"savePwd": "保存密码",
|
||||
"username": "用户名",
|
||||
"email": "邮箱",
|
||||
"phone": "手机",
|
||||
"authSource": "账号来源",
|
||||
"local": "本地",
|
||||
"pwdChanged": "密码已修改",
|
||||
"pwdChangeFailed": "修改失败",
|
||||
"defaultUser": "用户"
|
||||
},
|
||||
"resetPwd": {
|
||||
"title": "重置密码",
|
||||
"desc": "为「{{name}}」设置新密码",
|
||||
"ldapHint": "LDAP 用户请在 LDAP 目录中管理密码,不支持本地重置。",
|
||||
"newPwd": "新密码",
|
||||
"newPwdPlaceholder": "至少 6 位",
|
||||
"confirmPwd": "确认密码",
|
||||
"confirmPlaceholder": "再次输入新密码",
|
||||
"confirm": "确认重置",
|
||||
"success": "密码已重置",
|
||||
"successDesc": "用户 {{name}} 的新密码已生效",
|
||||
"failed": "重置失败"
|
||||
}
|
||||
},
|
||||
"logCenter": {
|
||||
|
||||
Reference in new issue
Block a user