From 01967bc52b87713e705efd80e0c4e9e24b55d698 Mon Sep 17 00:00:00 2001 From: attacker Date: Tue, 30 Jun 2026 22:10:26 +0800 Subject: [PATCH] =?UTF-8?q?feat(i18n):=20deploy=20=E6=A8=A1=E5=9D=97(Pipel?= =?UTF-8?q?ine/Credential)=E5=9B=BD=E9=99=85=E5=8C=96=E5=A2=9E=E9=87=8F?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=20=E2=80=94=20=E7=BF=BB=E8=AF=91=E9=94=AE=20?= =?UTF-8?q?deploy=20=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4(455=E9=94=AE)=20+?= =?UTF-8?q?=20CredentialManager=20=E8=A1=A5=E5=85=A8=203=20=E5=A4=84=20UI?= =?UTF-8?q?=20=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PipelineManager.tsx: 流水线全量翻译(标题/搜索/CRUD/阶段/任务/运行/横幅) - CredentialManager.tsx: 操作按钮 title 属性补全(编辑/禁用启用/删除) - zh-CN.json + en-US.json: deploy 命名空间 455 键完全对齐 - 总翻译键: 1019(zh) = 1019(en) - tsc -b 零错误, npm build 成功(17.42s) --- .../components/deploy/CredentialManager.tsx | 68 +-- .../src/components/deploy/PipelineManager.tsx | 70 +-- frontend/src/locales/en-US.json | 491 ++++++++++++++++++ frontend/src/locales/zh-CN.json | 491 ++++++++++++++++++ 4 files changed, 1053 insertions(+), 67 deletions(-) diff --git a/frontend/src/components/deploy/CredentialManager.tsx b/frontend/src/components/deploy/CredentialManager.tsx index 36957b0..4fa2373 100644 --- a/frontend/src/components/deploy/CredentialManager.tsx +++ b/frontend/src/components/deploy/CredentialManager.tsx @@ -1,4 +1,5 @@ import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { Plus, Pencil, Trash2, RefreshCw, Key, Shield, Search, Clock, CheckCircle2, XCircle, Zap, @@ -17,6 +18,7 @@ import { CredFormDialog } from './credential-manager/CredFormDialog'; // 凭据管理页编排器 // Logan.Li export default function CredentialManager() { + const { t } = useTranslation(); const confirm = useConfirm(); const [dialogOpen, setDialogOpen] = useState(false); const [editing, setEditing] = useState(null); @@ -38,28 +40,28 @@ export default function CredentialManager() { const handleDelete = async (cred: Credential) => { const ok = await confirm({ - title: '删除凭据', - description: `确定删除凭据「${cred.name}」?此操作不可撤销。`, - confirmText: '删除', + title: t('deploy.cred.deleteCred'), + description: t('deploy.pipeline.deleteConfirm', { name: cred.name }), + confirmText: t('common.delete'), variant: 'destructive', }); if (!ok) return; try { await deleteMutation.mutateAsync(cred.id); - toast.success('已删除'); - } catch { toast.error('删除失败'); } + toast.success(t('deploy.toast.deleted')); + } catch { toast.error(t('deploy.toast.deleteFailed')); } }; const handleToggleActive = async (cred: Credential) => { try { await toggleActiveMutation.mutateAsync({ id: cred.id, isActive: !cred.is_active }); - toast.success(cred.is_active ? '已禁用' : '已启用'); - } catch { toast.error('操作失败'); } + toast.success(cred.is_active ? t('deploy.toast.disabled') : t('deploy.toast.enabled')); + } catch { toast.error(t('deploy.toast.operationFailed')); } }; const handleCopyPrefix = (prefix: string) => { navigator.clipboard.writeText(prefix); - toast.success('引用 ID 已复制'); + toast.success(t('deploy.cred.refIdCopied')); }; const typeOptions = Object.entries(TYPE_CONFIG) as [SecretType, typeof TYPE_CONFIG[SecretType]][]; @@ -68,17 +70,17 @@ export default function CredentialManager() {
-

凭据管理

+

{t('deploy.cred.title')}

- 统一管理 SSH 密钥、Docker 密码、AKSK、数据库等敏感凭据(AES 加密存储) + {t('deploy.cred.subtitle')}

@@ -87,10 +89,10 @@ export default function CredentialManager() {
setFilterSearch(e.target.value)} - placeholder="搜索名称、描述..." + placeholder={t('deploy.label.searchPlaceholder')} className="pl-8 bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)] h-9 text-sm" />
- {credentials.length} 个凭据 + {t('deploy.cred.credCount', { count: credentials.length })}
{loading ? (
- 加载中... + {t('deploy.label.loading')}
) : credentials.length === 0 ? (
-

暂无凭据

-

创建 SSH、Docker、AKSK 等类型的凭据,供流水线和服务器使用

+

{t('deploy.cred.noCredentials')}

+

{t('deploy.cred.subtitle')}

) : ( @@ -125,13 +127,13 @@ export default function CredentialManager() { - - - - - - - + + + + + + + @@ -181,28 +183,28 @@ export default function CredentialManager() {
名称类型摘要标签引用ID状态操作{t('deploy.table.name')}{t('deploy.table.type')}{t('deploy.table.repoUrl')}{t('deploy.table.tagLabel')}{t('deploy.cred.refId')}{t('deploy.table.status')}{t('deploy.table.actions')}
{cred.is_active ? ( - 启用 + {t('common.enable')} ) : ( - 禁用 + {t('common.disable')} )} {isExpired && ( - 过期 + {t('deploy.status.expired')} )}
e.stopPropagation()}>
diff --git a/frontend/src/components/deploy/PipelineManager.tsx b/frontend/src/components/deploy/PipelineManager.tsx index 0b81855..e8e9836 100644 --- a/frontend/src/components/deploy/PipelineManager.tsx +++ b/frontend/src/components/deploy/PipelineManager.tsx @@ -1,4 +1,5 @@ import { useState, useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { @@ -28,6 +29,7 @@ import { PipelineCreateDialog } from './pipeline-manager/PipelineCreateDialog'; // 流水线列表页编排器 // Logan.Li export function PipelineManager() { + const { t } = useTranslation(); const [searchQuery, setSearchQuery] = useState(''); const { data: pipelines = [], isLoading: loading, refetch: refetchPipelines } = usePipelines(); const { triggerMutation, deleteMutation, stopRunMutation } = usePipelineMutations(); @@ -41,11 +43,11 @@ export function PipelineManager() { const confirm = useConfirm(); const ENV_TYPES = [ - { key: 'all', label: '全部', icon: Layers, color: '#6B7280' }, - { key: 'production', label: '生产', icon: ShieldCheck, color: '#EF4444' }, - { key: 'testing', label: '测试', icon: CheckCircle, color: '#F59E0B' }, - { key: 'staging', label: '预发布', icon: Globe, color: '#8B5CF6' }, - { key: 'development', label: '开发', icon: Code, color: '#3B82F6' }, + { key: 'all', label: t('deploy.env.all'), icon: Layers, color: '#6B7280' }, + { key: 'production', label: t('deploy.env.production'), icon: ShieldCheck, color: '#EF4444' }, + { key: 'testing', label: t('deploy.env.testing'), icon: CheckCircle, color: '#F59E0B' }, + { key: 'staging', label: t('deploy.env.staging'), icon: Globe, color: '#8B5CF6' }, + { key: 'development', label: t('deploy.env.development'), icon: Code, color: '#3B82F6' }, ]; // 同步运行中的任务 ID // Logan.Li @@ -86,20 +88,20 @@ export function PipelineManager() { const handleTrigger = async (pipelineId: number, code: string) => { try { await triggerMutation.mutateAsync(code); - toast.success('已触发'); + toast.success(t('deploy.toast.triggered')); loadRuns(pipelineId, code); refetchPipelines(); } catch { - toast.error('触发失败'); + toast.error(t('deploy.toast.triggerFailed')); } }; const handleStop = async (pipelineId: number, code: string, runId: number | string) => { - const ok = await confirm({ title: '停止运行', description: '确定要停止此运行吗?', variant: 'destructive' }); + const ok = await confirm({ title: t('deploy.run.stopRun'), description: t('deploy.run.stopConfirm'), variant: 'destructive' }); if (!ok) return; try { await stopRunMutation.mutateAsync({ code, runId }); - toast.success('已停止'); + toast.success(t('deploy.toast.stopped')); loadRuns(pipelineId, code); setRunningRunMap((prev) => { const n = { ...prev }; @@ -107,7 +109,7 @@ export function PipelineManager() { return n; }); } catch { - toast.error('停止失败'); + toast.error(t('deploy.toast.stopFailed')); } }; @@ -120,9 +122,9 @@ export function PipelineManager() { (r) => r.status === 'running' || r.status === 'pending', ); if (running) await handleStop(pipelineId, code, running.id as number | string); - else toast.error('未找到运行中的任务'); + else toast.error(t('deploy.pipeline.noRunningTask')); } catch { - toast.error('停止失败'); + toast.error(t('deploy.toast.stopFailed')); } return; } @@ -131,17 +133,17 @@ export function PipelineManager() { const handleDelete = async (pipeline: Record) => { const ok = await confirm({ - title: '删除流水线', - description: `确定删除「${pipeline.name}」?`, + title: t('deploy.pipeline.deletePipeline'), + description: t('deploy.pipeline.deleteConfirm', { name: pipeline.name }), variant: 'destructive', }); if (!ok) return; try { await deleteMutation.mutateAsync(pipeline.id as number | string); - toast.success('已删除'); + toast.success(t('deploy.toast.deleted')); refetchPipelines(); } catch { - toast.error('删除失败'); + toast.error(t('deploy.toast.deleteFailed')); } }; @@ -157,14 +159,14 @@ export function PipelineManager() {
-

流水线

-

CI/CD 构建 · 部署 · 发布一体化

+

{t('deploy.pipeline.title')}

+

{t('deploy.pipeline.subtitle')}

- +
@@ -173,45 +175,45 @@ export function PipelineManager() {
- 构建 + {t('deploy.banner.build')} - 部署 + {t('deploy.banner.deploy')}
- SSH 主机 + {t('deploy.banner.sshHost')}
-

传统主机 SCP 部署 · 无需镜像仓库

+

{t('deploy.banner.sshDesc')}

- 构建 + {t('deploy.banner.build')} - 镜像仓库 + {t('deploy.banner.imageRegistry')} - 部署 + {t('deploy.banner.deploy')}
- Kubernetes + {t('deploy.banner.kubernetes')}
-

容器化部署 · 需镜像仓库推送

+

{t('deploy.banner.k8sDesc')}

- 全流程可视化 + {t('deploy.banner.fullFlow')}
setSearchQuery(e.target.value)} className="pl-10 bg-[var(--dg-bg-secondary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" @@ -244,9 +246,9 @@ export function PipelineManager() { ) : filtered.length === 0 ? (
-

暂无流水线

+

{t('deploy.pipeline.noData')}

) : ( @@ -275,4 +277,4 @@ export function PipelineManager() {
); -} \ No newline at end of file +} diff --git a/frontend/src/locales/en-US.json b/frontend/src/locales/en-US.json index 7afeec6..b185b16 100644 --- a/frontend/src/locales/en-US.json +++ b/frontend/src/locales/en-US.json @@ -654,5 +654,496 @@ "closed": "Closed" } } + }, + "deploy": { + "pipeline": { + "title": "Pipelines", + "subtitle": "CI/CD Build · Deploy · Release All-in-One", + "newPipeline": "New Pipeline", + "createFirst": "Create your first pipeline", + "searchPlaceholder": "Search pipelines...", + "noData": "No pipelines", + "triggered": "Triggered", + "triggerFailed": "Trigger failed", + "stopRun": "Stop Run", + "stopConfirm": "Are you sure you want to stop this run?", + "stopped": "Stopped", + "stopFailed": "Stop failed", + "noRunningTask": "No running task found", + "deletePipeline": "Delete Pipeline", + "deleteConfirm": "Delete \"{{name}}\"?", + "deleted": "Deleted", + "deleteFailed": "Delete failed", + "detail": "Pipeline Detail", + "notExist": "Pipeline does not exist", + "config": "Pipeline Config", + "name": "Pipeline Name", + "namePlaceholder": "Enter pipeline name", + "type": "Pipeline Type", + "stages": "Pipeline Stages ({{count}})", + "allStages": "All Stages", + "noStages": "No stage configuration", + "clickToAddStage": "Click \"Add Stage\" to start", + "addStage": "Add Stage", + "newStage": "New Stage", + "addTask": "Add Task", + "newTask": "New Task", + "taskEdit": "Task Editor", + "selectTaskHint": "Select a task to start editing", + "matchPreview": "Pipeline Match Preview", + "created": "Pipeline created", + "createFailed": "Create failed", + "saving": "Saving...", + "save": "Save", + "editPipeline": "Edit Pipeline", + "modifyConfig": "Modify Pipeline Config", + "configureNew": "Configure new CI/CD pipeline", + "editMode": "Save Changes", + "createMode": "Create Pipeline", + "desc": "No description", + "buildNumber": "Build", + "runs": "Run Count", + "neverRun": "Never run", + "runNow": "Run Now", + "executing": "Executing...", + "logOutput": "No log output", + "noLogStage": "No log output for this stage", + "realtimeOutput": "Pipeline running, real-time output...", + "buildDir": "Pipeline Build Directory Terminal", + "fileBrowser": "File Browser #{{buildNumber}}", + "buildDirFiles": "Pipeline Build Directory File Browser", + "workspaceTerminal": "Workspace Terminal #{{buildNumber}}", + "execLog": "Execution Log #{{number}}", + "release": "Release #{{number}}", + "all": "All ({{count}})" + }, + "stage": { + "checkout": "Checkout", + "build": "Build", + "image": "Image Build", + "deploy": "Deploy", + "test": "Test", + "custom": "Custom", + "tasks": "{{count}} tasks", + "selectOrder": "Select stages in order", + "checkoutDesc": "Pull code", + "buildDesc": "Build & package", + "imageDesc": "Push image", + "deployDesc": "Deploy to Kubernetes", + "testDesc": "Code inspection", + "checkoutNeedGit": "Checkout stage requires Git URL", + "imageNeedDocker": "Image build stage requires Docker credential", + "suggestDocker": "Recommended credential", + "needDocker": "Docker credential required" + }, + "env": { + "all": "All", + "production": "Production", + "testing": "Testing", + "staging": "Staging", + "development": "Development", + "prodEnv": "Production", + "testEnv": "Testing", + "stagingEnv": "Staging", + "devEnv": "Development", + "selectEnv": "Select Environment", + "envType": "Environment Type", + "envGroup": "Environment Group", + "envLabel": "Environment ID", + "selectEnvHint": "Pipeline runs will be linked to the selected environment", + "addEnv": "Add Environment", + "editEnv": "Edit Environment", + "envManage": "Environments ({{count}})", + "noEnvConfig": "No environment config, click \"Add Environment\" to create" + }, + "trigger": { + "manual": "Manual", + "manualTrigger": "Manual Trigger", + "manualExec": "Manual Execution", + "gitPush": "Git Push Trigger", + "gitPushAuto": "Git Push Auto Trigger", + "cron": "Cron Schedule", + "webhook": "Webhook Trigger", + "externalWebhook": "External Webhook Call", + "method": "Trigger Method", + "triggerBuild": "Trigger Build", + "settings": "Trigger Settings", + "listenBranch": "Listen Branch", + "excludeBranch": "Exclude Branch", + "cronExpr": "Cron Expression", + "every5min": "Every 5 minutes", + "everyHour": "Every hour", + "everyDay2": "Daily at 2:00", + "everySunday": "Every Sunday", + "tagRelease": "Tag Release", + "branchTag": "Branch / Tag", + "noTriggerMode": "Manual" + }, + "run": { + "status": "Status", + "triggeredBy": "Triggered By", + "triggerMode": "Trigger Method", + "duration": "Duration", + "startTime": "Start Time", + "branch": "Branch", + "commit": "Code", + "noRecords": "No execution records", + "noRecordsHint": "No execution records, click \"Run Now\" to trigger a build", + "stopRun": "Stop Run", + "stopConfirm": "Are you sure you want to stop this run?", + "buildStatus": "Build Status", + "buildLog": "Build Log", + "execStage": "Execution Stage", + "fullFlowVisual": "Full-flow Visualization" + }, + "status": { + "pending": "Pending", + "running": "Running", + "success": "Success", + "failed": "Failed", + "stopped": "Stopped", + "building": "Building", + "deploying": "Deploying", + "succeeded": "Succeeded", + "failed_deploy": "Deploy Failed", + "rolledBack": "Rolled Back", + "pendingRelease": "Pending Release", + "pendingApproval": "Pending Approval", + "approved": "Approved", + "rejected": "Rejected", + "cancelled": "Cancelled", + "expired": "Expired", + "created": "Created", + "updated": "Updated", + "deleted": "Deleted", + "enabled": "Enabled", + "disabled": "Disabled", + "installed": "Installed", + "notInstalled": "Not Installed", + "installing": "Installing" + }, + "cred": { + "title": "Credentials", + "subtitle": "Manage SSH keys, Docker passwords, AKSK, database and other sensitive credentials (AES encrypted)", + "addCredential": "Add Credential", + "createFirst": "Create your first credential", + "searchPlaceholder": "Search credentials...", + "credName": "Credential Name", + "nameRequired": "Please enter credential name", + "credType": "Type", + "authMethod": "Auth Method", + "noCredentials": "No credentials", + "credCount": "{{count}} credentials", + "editCred": "Edit Credential", + "newCred": "New Credential", + "deleteCred": "Delete Credential", + "credData": "Secret Data", + "noCredData": "Credential data not found", + "refId": "Reference ID", + "refIdCopied": "Reference ID copied", + "refHint": "Reference this credential in pipelines/scripts:", + "credDetail": "Credential Detail", + "refIdLabel": "Reference ID:", + "descDefault": "Manage sensitive credentials", + "suggestLink": "Recommended credential", + "notLinked": "Not linked", + "notLinkedCred": "No credential", + "selectDocker": "Select Docker credential", + "selectDockerPwd": "Select Docker password credential", + "selectApiCred": "Select credential (API/password etc.)", + "selectCred": "Select credential", + "linkedCred": "Linked Credential" + }, + "release": { + "title": "Application Release", + "subtitle": "Manage application version releases and approval workflows", + "newRelease": "New Release", + "searchApp": "Search app name or version...", + "noRecords": "No release records", + "appName": "App Name", + "version": "Version", + "versionNo": "Version Number", + "releaseDesc": "Release Notes", + "releaseProgress": "Release Progress", + "releaseDetail": "Release Detail", + "approve": "Approve Release", + "approveFail": "Approval failed", + "approveHint": "After approval, it will enter the ready-to-deploy state", + "reject": "Reject", + "rejectFail": "Reject failed", + "deploy": "Deploy", + "deployStarted": "Deployment started", + "deployFail": "Deploy failed", + "confirmDeploy": "Confirm Deploy", + "rollback": "Rollback", + "rollbackSuccess": "Rollback succeeded", + "rollbackFail": "Rollback failed", + "confirmRollback": "Confirm Rollback", + "redeploy": "Redeploy", + "redeployFail": "Redeploy failed", + "redeployed": "Redeployment triggered", + "submitApp": "Submit Request", + "submitFail": "Release request submitted", + "createNew": "Create new application version release request", + "appPlaceholder": "e.g., demo-jar backend deployment", + "nameVerRequired": "Please enter app name and version", + "getReleaseFail": "Failed to get release list", + "deployEnv": "Deploy Environment:", + "targetEnv": "Target Environment", + "releaseConfig": "Release Config Management", + "releaseRecords": "Release Records ({{count}})", + "releaseFlow": "Release Flow", + "releasePerson": "Released By", + "releaseManage": "Release Management" + }, + "tool": { + "title": "Tool Config", + "subtitle": "Manage DevOps tool installation strategy: pre-installed, lazy-load on first use, or disabled", + "installMethod": "Install Method", + "preinstall": "Pre-install", + "lazyLoad": "Lazy Load", + "selectVersion": "Select Version", + "versionPrompt": "{{name}} — Please select a version to install", + "noConfig": "No tool config, please check backend seed data", + "getToolFail": "Failed to get tool config", + "installed": "Installed", + "notInstalled": "Not installed", + "installing": "Installing", + "test": "Test", + "install": "Install" + }, + "rbac": { + "title": "Deploy Permissions", + "subtitle": "Jenkins-style Role Strategy — Assign roles by pipeline code regex matching", + "newRole": "New Item Role", + "newGroup": "New User Group", + "assignToUser": "Assign roles to users", + "userGroupManage": "User Group Management", + "groupDesc": "Create user groups, authorize groups to pipelines, group members automatically inherit permissions", + "noRoles": "No Item Roles", + "noGroups": "No user groups, click \"New User Group\" to create", + "noDirectUsers": "No direct users", + "noGroupAuth": "No group authorization — Create a group in \"", + "noGroupAuthSuffix": "\" page, then authorize here", + "directUsers": "👤 Direct User Authorization ({{count}})", + "groupAssignments": "👥 Group Authorization ({{count}})", + "rolePattern": "Regex Match Pattern", + "regexEmpty": "Regex cannot be empty", + "noMatch": "No match — please adjust the regex", + "regexError": "❌ Invalid regex syntax", + "matchCount": "{{count}} matches", + "matchPreview": "Pipeline Match Preview", + "roleHint": "— Select a role to see which pipelines match", + "owner": "Owner", + "editor": "Editor", + "viewer": "Viewer", + "ownerRole": "Owner", + "editorRole": "Editor", + "viewerRole": "Viewer", + "assigned": "Assigned", + "assignedRoles": "Assigned roles:", + "addUser": "Add User", + "selectUser": "Select User", + "selectUserPlaceholder": "Select user...", + "selectRole": "Select Role", + "assign": "Assign", + "assignFail": "Assign failed", + "memberManage": "Members ({{count}})", + "addMember": "Add User", + "removeMember": "Remove Member", + "removeConfirm": "Are you sure you want to remove this member?", + "removeFail": "Remove failed", + "noMembers": "No members", + "addedMember": "Member added", + "removed": "Removed", + "groupNewTitle": "New User Group", + "groupEditTitle": "Edit User Group", + "groupName": "Group Name", + "groupPlaceholder": "Enter group name", + "createGroup": "Create", + "creating": "Creating...", + "deleteGroup": "Delete User Group", + "deleteRole": "Delete Role", + "userCol": "User", + "noUserRole": "This user has not been assigned any Item Role" + }, + "banner": { + "build": "Build", + "deploy": "Deploy", + "sshHost": "SSH Host", + "kubernetes": "Kubernetes", + "imageRegistry": "Image Registry", + "sshDesc": "Traditional host SCP deployment · No registry needed", + "k8sDesc": "Containerized deployment · Requires registry push", + "fullFlow": "Full-flow Visualization" + }, + "template": { + "go": "Go Project", + "goDesc": "For Go backend projects", + "java": "Java Project", + "javaDesc": "For Java Spring Boot projects", + "nodejs": "Node.js Project", + "nodejsDesc": "For Node.js frontend projects", + "python": "Python Project", + "pythonDesc": "For Python projects", + "selectTemplate": "Select Template", + "mavenBuild": "Maven Build", + "dependencyInstall": "Dependency Install", + "unitTest": "Unit Test", + "healthCheck": "Health Check", + "package": "Package", + "verify": "Verify", + "detect": "Detect" + }, + "var": { + "title": "Variables", + "addVar": "Add Variable", + "varName": "Variable Name", + "varValue": "Variable Value", + "varAlias": "Variable Alias", + "noVars": "No variables, click \"Add Variable\" to create", + "envVar": "Environment Variables", + "envVarOptional": "Environment Variables (optional)" + }, + "table": { + "name": "Name", + "code": "Code", + "codeCol": "Repository", + "type": "Type", + "status": "Status", + "env": "Environment", + "duration": "Duration", + "trigger": "Trigger", + "triggerBy": "Triggered By", + "startTime": "Start Time", + "actions": "Actions", + "sortOrder": "Sort", + "modifyTime": "Modified", + "size": "Size", + "color": "Color", + "icon": "Icon", + "displayName": "Display Name", + "envId": "Env ID", + "successRate": "Success Rate", + "todayRelease": "Today's Releases", + "defaultBranch": "Default Branch", + "repoUrl": "Repository URL", + "tagLabel": "Tag", + "version": "Version", + "user": "User", + "category": "Category" + }, + "form": { + "name": "Name", + "nameStar": "Name *", + "nameRequired": "Please enter a name", + "code": "Code (unique identifier)", + "desc": "Description", + "descOptional": "Description (optional)", + "repoUrlStar": "Repository URL *", + "registryUrlStar": "Registry URL *", + "nameAddrRequired": "Please enter name and address", + "concurrent": "Concurrent Executors", + "concurrentHint": "Set to 1 for sequential execution, default 2 allows parallel builds", + "serial": "1 — Sequential", + "gitCred": "Git Credential", + "jobName": "Job Name", + "envVars": "Environment Variables", + "deployMode": "Deploy Mode", + "deployTarget": "Deploy Target", + "commitId": "Commit ID (optional)", + "dockerfilePath": "Dockerfile Path", + "buildCache": "Build Cache", + "cachePaths": "Separate multiple paths with commas, same Key will hit existing cache", + "registryAddr": "Registry Address", + "imageName": "Image Name:", + "varRef": "(${'{VAR_NAME}'} reference)", + "scriptType": "Script Type", + "scriptContent": "Script Content", + "buildQueue": "Build Queue", + "defaultNamespace": "Default Namespace", + "defaultEnabled": "Enabled by default", + "notSpecified": "Not specified", + "save": "Save", + "cancel": "Cancel", + "create": "Create", + "update": "Update" + }, + "toast": { + "saved": "Saved", + "updated": "Updated", + "deleted": "Deleted", + "created": "Created", + "enabled": "Enabled", + "disabled": "Disabled", + "installed": "Installed", + "triggered": "Triggered", + "stopped": "Stopped", + "added": "Added", + "removed": "Removed", + "revoked": "Revoked", + "approved": "Approved", + "rejected": "Rejected", + "cancelled": "Cancelled", + "expired": "Expired", + "rolledBack": "Rolled back", + "redeployed": "Redeployment triggered", + "assigned": "Assigned", + "createdPipeline": "Pipeline created", + "releaseSubmitted": "Release request submitted", + "deployStarted": "Deployment started", + "saveFailed": "Save failed", + "updateFailed": "Update failed", + "deleteFailed": "Delete failed", + "createFailed": "Create failed", + "triggerFailed": "Trigger failed", + "stopFailed": "Stop failed", + "addFailed": "Add failed", + "removeFailed": "Remove failed", + "revokeFailed": "Revoke failed", + "approveFailed": "Approve failed", + "rejectFailed": "Reject failed", + "deployFailed": "Deploy failed", + "rollbackFailed": "Rollback failed", + "redeployFailed": "Redeploy failed", + "assignFailed": "Assign failed", + "batchDeleteFailed": "Batch delete failed", + "cancelFailed": "Cancel failed", + "operationFailed": "Operation failed", + "getDataFailed": "Failed to get data", + "loadFailed": "Load failed", + "saveSuccess": "Saved successfully" + }, + "label": { + "basicInfo": "Basic Info", + "flowConfig": "Flow Config", + "triggerSettings": "Trigger Settings", + "variables": "Variables", + "credentials": "Credentials", + "environments": "Environments", + "toolConfig": "Tool Config", + "releaseConfig": "Release Config", + "releaseRecords": "Release Records", + "permission": "Permissions", + "userGroups": "User Groups", + "roles": "Roles", + "gitRepo": "Git Repos ({{count}})", + "registry": "Registries ({{count}})", + "envManage": "Environments ({{count}})", + "advanced": "Advanced", + "loading": "Loading...", + "emptyDir": "Directory is empty", + "browse": "Browse", + "record": "Record", + "log": "Log", + "run": "Run", + "execute": "Execute", + "download": "Download", + "searchPlaceholder": "Search name, description...", + "allStatus": "All Status", + "allEnv": "All Environments", + "allType": "All Types", + "pagination": "{{n}}/page" + } } } diff --git a/frontend/src/locales/zh-CN.json b/frontend/src/locales/zh-CN.json index 8341b09..a43e259 100644 --- a/frontend/src/locales/zh-CN.json +++ b/frontend/src/locales/zh-CN.json @@ -654,5 +654,496 @@ "closed": "已关闭" } } + }, + "deploy": { + "pipeline": { + "title": "流水线", + "subtitle": "CI/CD 构建 · 部署 · 发布一体化", + "newPipeline": "新建流水线", + "createFirst": "创建第一个流水线", + "searchPlaceholder": "搜索流水线...", + "noData": "暂无流水线", + "triggered": "已触发", + "triggerFailed": "触发失败", + "stopRun": "停止运行", + "stopConfirm": "确定要停止此运行吗?", + "stopped": "已停止", + "stopFailed": "停止失败", + "noRunningTask": "未找到运行中的任务", + "deletePipeline": "删除流水线", + "deleteConfirm": "确定删除「{{name}}」?", + "deleted": "已删除", + "deleteFailed": "删除失败", + "detail": "流水线详情", + "notExist": "流水线不存在", + "config": "流水线配置", + "name": "流水线名称", + "namePlaceholder": "请输入流水线名称", + "type": "流水线类型", + "stages": "流水线阶段 ({{count}})", + "allStages": "全阶段", + "noStages": "暂无阶段配置", + "clickToAddStage": "点击「添加阶段」开始", + "addStage": "添加阶段", + "newStage": "新阶段", + "addTask": "添加任务", + "newTask": "新任务", + "taskEdit": "任务编辑", + "selectTaskHint": "选择一个任务开始编辑", + "matchPreview": "流水线命中预览", + "created": "流水线已创建", + "createFailed": "创建失败", + "saving": "保存中...", + "save": "保存", + "editPipeline": "编辑流水线", + "modifyConfig": "修改流水线配置", + "configureNew": "配置新的 CI/CD 流水线", + "editMode": "保存修改", + "createMode": "创建流水线", + "desc": "暂无描述", + "buildNumber": "构建", + "runs": "运行次数", + "neverRun": "从未运行", + "runNow": "立即执行", + "executing": "执行中...", + "logOutput": "暂无日志输出", + "noLogStage": "该阶段暂无日志输出", + "realtimeOutput": "流水线执行中,实时输出...", + "buildDir": "流水线构建目录终端", + "fileBrowser": "文件浏览器 #{{buildNumber}}", + "buildDirFiles": "流水线构建目录文件浏览", + "workspaceTerminal": "Workspace 终端 #{{buildNumber}}", + "execLog": "执行日志 #{{number}}", + "release": "发布 #{{number}}", + "all": "全部 ({{count}})" + }, + "stage": { + "checkout": "代码检出", + "build": "构建", + "image": "镜像打包", + "deploy": "部署", + "test": "测试", + "custom": "自定义", + "tasks": "{{count}} 任务", + "selectOrder": "按顺序选择阶段", + "checkoutDesc": "拉取代码", + "buildDesc": "构建打包", + "imageDesc": "推送镜像", + "deployDesc": "部署到Kubernetes", + "testDesc": "代码检查", + "checkoutNeedGit": "代码检出阶段需要填写 Git URL", + "imageNeedDocker": "镜像打包阶段需要关联 Docker 凭证", + "suggestDocker": "建议关联凭证", + "needDocker": "需要关联 Docker 凭证" + }, + "env": { + "all": "全部", + "production": "生产", + "testing": "测试", + "staging": "预发布", + "development": "开发", + "prodEnv": "生产环境", + "testEnv": "测试环境", + "stagingEnv": "预发环境", + "devEnv": "开发环境", + "selectEnv": "选择环境", + "envType": "环境类型", + "envGroup": "环境分组", + "envLabel": "环境标识", + "selectEnvHint": "选择后流水线执行记录会关联到对应环境", + "addEnv": "新增环境", + "editEnv": "编辑环境", + "envManage": "环境管理 ({{count}})", + "noEnvConfig": "暂无环境配置,点击\"新增环境\"创建" + }, + "trigger": { + "manual": "手动", + "manualTrigger": "手动触发", + "manualExec": "手动触发执行", + "gitPush": "Git Push 触发", + "gitPushAuto": "Git Push 自动触发", + "cron": "Cron 定时执行", + "webhook": "Webhook 触发", + "externalWebhook": "外部 Webhook 调用", + "method": "触发方式", + "triggerBuild": "触发构建", + "settings": "触发设置", + "listenBranch": "监听分支", + "excludeBranch": "排除分支", + "cronExpr": "Cron 表达式", + "every5min": "每5分钟", + "everyHour": "每小时", + "everyDay2": "每天2点", + "everySunday": "每周日", + "tagRelease": "Tag 发版", + "branchTag": "分支 / Tag", + "noTriggerMode": "手动" + }, + "run": { + "status": "状态", + "triggeredBy": "触发人", + "triggerMode": "触发方式", + "duration": "耗时", + "startTime": "开始时间", + "branch": "分支", + "commit": "代码", + "noRecords": "暂无执行记录", + "noRecordsHint": "暂无执行记录,点击\"立即执行\"触发构建", + "stopRun": "停止运行", + "stopConfirm": "确定要停止此运行吗?", + "buildStatus": "构建执行状态", + "buildLog": "构建日志", + "execStage": "执行阶段", + "fullFlowVisual": "全流程可视化" + }, + "status": { + "pending": "待执行", + "running": "运行中", + "success": "成功", + "failed": "失败", + "stopped": "已停止", + "building": "构建中", + "deploying": "发布中", + "succeeded": "发布成功", + "failed_deploy": "发布失败", + "rolledBack": "已回滚", + "pendingRelease": "待发布", + "pendingApproval": "待审批", + "approved": "已审批", + "rejected": "已驳回", + "cancelled": "已取消", + "expired": "已过期", + "created": "已创建", + "updated": "已更新", + "deleted": "已删除", + "enabled": "已启用", + "disabled": "已禁用", + "installed": "已安装", + "notInstalled": "未安装", + "installing": "安装中" + }, + "cred": { + "title": "凭据管理", + "subtitle": "统一管理 SSH 密钥、Docker 密码、AKSK、数据库等敏感凭据(AES 加密存储)", + "addCredential": "新增凭据", + "createFirst": "创建第一个凭据", + "searchPlaceholder": "搜索凭据...", + "credName": "凭据名称", + "nameRequired": "请填写凭据名称", + "credType": "类型", + "authMethod": "认证方式", + "noCredentials": "暂无凭据", + "credCount": "{{count}} 个凭据", + "editCred": "编辑凭据", + "newCred": "新增凭据", + "deleteCred": "删除凭据", + "credData": "密钥数据", + "noCredData": "未找到凭据数据", + "refId": "引用ID", + "refIdCopied": "引用 ID 已复制", + "refHint": "在流水线/脚本中引用此凭据:", + "credDetail": "凭据详情", + "refIdLabel": "引用ID:", + "descDefault": "管理敏感凭据信息", + "suggestLink": "建议关联凭证", + "notLinked": "不关联", + "notLinkedCred": "不关联凭证", + "selectDocker": "选择 Docker 凭证", + "selectDockerPwd": "选择 Docker 密码凭据", + "selectApiCred": "选择凭据(API/密码等)", + "selectCred": "选择凭证", + "linkedCred": "关联凭证" + }, + "release": { + "title": "应用发布", + "subtitle": "管理应用版本发布与审批流程", + "newRelease": "新建发布", + "searchApp": "搜索应用名称或版本...", + "noRecords": "暂无发布记录", + "appName": "应用名称", + "version": "版本", + "versionNo": "版本号", + "releaseDesc": "发布说明", + "releaseProgress": "发布进度", + "releaseDetail": "发布详情", + "approve": "审批发布", + "approveFail": "审批失败", + "approveHint": "确认审批后将进入部署就绪状态", + "reject": "驳回", + "rejectFail": "驳回失败", + "deploy": "部署", + "deployStarted": "部署已启动", + "deployFail": "部署失败", + "confirmDeploy": "确认部署", + "rollback": "回滚", + "rollbackSuccess": "回滚成功", + "rollbackFail": "回滚失败", + "confirmRollback": "确认回滚", + "redeploy": "重新部署", + "redeployFail": "重新部署失败", + "redeployed": "已重新触发部署", + "submitApp": "提交申请", + "submitFail": "发布申请已提交", + "createNew": "创建新的应用版本发布申请", + "appPlaceholder": "例如: demo-jar 后端部署", + "nameVerRequired": "请填写应用名称和版本号", + "getReleaseFail": "获取发布列表失败", + "deployEnv": "部署环境:", + "targetEnv": "目标环境", + "releaseConfig": "发布配置管理", + "releaseRecords": "发布记录 ({{count}})", + "releaseFlow": "发布流程", + "releasePerson": "发布人", + "releaseManage": "发布管理" + }, + "tool": { + "title": "工具配置", + "subtitle": "管理 DevOps 工具的安装策略:预装在镜像中、首次使用自动下载(懒加载)、或禁用不安装", + "installMethod": "安装方式", + "preinstall": "预装", + "lazyLoad": "懒加载", + "selectVersion": "选择安装版本", + "versionPrompt": "{{name}} — 请选择要安装的版本", + "noConfig": "暂无工具配置,请检查后端种子数据", + "getToolFail": "获取工具配置失败", + "installed": "已安装", + "notInstalled": "未安装", + "installing": "安装中", + "test": "测试", + "install": "安装" + }, + "rbac": { + "title": "发布权限", + "subtitle": "Jenkins-style Role Strategy — 按流水线 code 正则匹配分配角色", + "newRole": "新建 Item Role", + "newGroup": "新建用户组", + "assignToUser": "分配角色给用户", + "userGroupManage": "用户组管理", + "groupDesc": "创建用户组,将组授权给流水线,组内成员自动获得流水线权限", + "noRoles": "暂无 Item Role", + "noGroups": "暂无用户组,点击「新建用户组」创建", + "noDirectUsers": "暂无直接用户", + "noGroupAuth": "暂无组授权 — 在「", + "noGroupAuthSuffix": "」页面创建组后,可在此授权", + "directUsers": "👤 直接用户授权 ({{count}})", + "groupAssignments": "👥 用户组授权 ({{count}})", + "rolePattern": "正则匹配 Pattern", + "regexEmpty": "正则不能为空", + "noMatch": "无匹配 — 请调整正则表达式", + "regexError": "❌ 正则语法错误", + "matchCount": "{{count}} 条", + "matchPreview": "流水线命中预览", + "roleHint": "— 选择一个角色查看哪些流水线会被匹配", + "owner": "拥有者", + "editor": "编辑者", + "viewer": "查看者", + "ownerRole": "拥有者 (owner)", + "editorRole": "编辑者 (editor)", + "viewerRole": "查看者 (viewer)", + "assigned": "已分配", + "assignedRoles": "已分配角色:", + "addUser": "添加用户", + "selectUser": "选择用户", + "selectUserPlaceholder": "选择用户...", + "selectRole": "选择角色", + "assign": "分配", + "assignFail": "分配失败", + "memberManage": "成员管理 ({{count}})", + "addMember": "添加用户", + "removeMember": "移除成员", + "removeConfirm": "确定要移除此成员吗?", + "removeFail": "移除失败", + "noMembers": "暂无成员", + "addedMember": "已添加成员", + "removed": "已移除", + "groupNewTitle": "新建用户组", + "groupEditTitle": "编辑用户组", + "groupName": "组名", + "groupPlaceholder": "请输入组名", + "createGroup": "创建", + "creating": "创建中...", + "deleteGroup": "删除用户组", + "deleteRole": "删除角色", + "userCol": "用户", + "noUserRole": "该用户尚未分配任何 Item Role" + }, + "banner": { + "build": "构建", + "deploy": "部署", + "sshHost": "SSH 主机", + "kubernetes": "Kubernetes", + "imageRegistry": "镜像仓库", + "sshDesc": "传统主机 SCP 部署 · 无需镜像仓库", + "k8sDesc": "容器化部署 · 需镜像仓库推送", + "fullFlow": "全流程可视化" + }, + "template": { + "go": "Go 项目", + "goDesc": "适用于 Go 后端项目", + "java": "Java 项目", + "javaDesc": "适用于 Java Spring Boot 项目", + "nodejs": "Node.js 项目", + "nodejsDesc": "适用于 Node.js 前端项目", + "python": "Python 项目", + "pythonDesc": "适用于 Python 项目", + "selectTemplate": "选择模板", + "mavenBuild": "Maven构建", + "dependencyInstall": "依赖安装", + "unitTest": "单元测试", + "healthCheck": "健康检查", + "package": "打包", + "verify": "验证", + "detect": "检测" + }, + "var": { + "title": "变量", + "addVar": "添加变量", + "varName": "变量名", + "varValue": "变量值", + "varAlias": "变量别名", + "noVars": "暂无变量,点击\"添加变量\"新增", + "envVar": "环境变量", + "envVarOptional": "环境变量 (可选)" + }, + "table": { + "name": "名称", + "code": "代码", + "codeCol": "代码仓库", + "type": "类型", + "status": "状态", + "env": "环境", + "duration": "耗时", + "trigger": "触发方式", + "triggerBy": "触发人", + "startTime": "开始时间", + "actions": "操作", + "sortOrder": "排序", + "modifyTime": "修改时间", + "size": "大小", + "color": "颜色", + "icon": "图标", + "displayName": "显示名称", + "envId": "环境标识", + "successRate": "成功率", + "todayRelease": "今日发布", + "defaultBranch": "默认分支", + "repoUrl": "仓库 URL", + "tagLabel": "标签", + "version": "版本", + "user": "用户", + "category": "分类" + }, + "form": { + "name": "名称", + "nameStar": "名称 *", + "nameRequired": "请填写名称", + "code": "代码 (唯一标识)", + "desc": "描述", + "descOptional": "描述 (可选)", + "repoUrlStar": "仓库 URL *", + "registryUrlStar": "Registry URL *", + "nameAddrRequired": "请填写名称和地址", + "concurrent": "并发执行数", + "concurrentHint": "设为 1 则按顺序串行执行,默认 2 可并发构建", + "serial": "1 — 串行", + "gitCred": "Git 凭证", + "jobName": "Job 名称", + "envVars": "环境变量", + "deployMode": "部署模式", + "deployTarget": "部署目标", + "commitId": "Commit ID (可选)", + "dockerfilePath": "Dockerfile 路径", + "buildCache": "构建缓存", + "cachePaths": "多个路径用逗号分隔,相同的 Key 会命中已有缓存", + "registryAddr": "Registry 地址", + "imageName": "镜像命名:", + "varRef": "(${'{VAR_NAME}'} 引用)", + "scriptType": "脚本类型", + "scriptContent": "脚本内容", + "buildQueue": "构建队列", + "defaultNamespace": "默认命名空间", + "defaultEnabled": "默认启用", + "notSpecified": "不指定", + "save": "保存", + "cancel": "取消", + "create": "创建", + "update": "更新" + }, + "toast": { + "saved": "已保存", + "updated": "已更新", + "deleted": "已删除", + "created": "已创建", + "enabled": "已启用", + "disabled": "已禁用", + "installed": "已安装", + "triggered": "已触发", + "stopped": "已停止", + "added": "已添加", + "removed": "已移除", + "revoked": "已撤销", + "approved": "已审批", + "rejected": "已驳回", + "cancelled": "已取消", + "expired": "已过期", + "rolledBack": "已回滚", + "redeployed": "已重新触发部署", + "assigned": "已分配", + "createdPipeline": "流水线已创建", + "releaseSubmitted": "发布申请已提交", + "deployStarted": "部署已启动", + "saveFailed": "保存失败", + "updateFailed": "更新失败", + "deleteFailed": "删除失败", + "createFailed": "创建失败", + "triggerFailed": "触发失败", + "stopFailed": "停止失败", + "addFailed": "添加失败", + "removeFailed": "移除失败", + "revokeFailed": "撤销失败", + "approveFailed": "审批失败", + "rejectFailed": "驳回失败", + "deployFailed": "部署失败", + "rollbackFailed": "回滚失败", + "redeployFailed": "重新部署失败", + "assignFailed": "分配失败", + "batchDeleteFailed": "批量删除失败", + "cancelFailed": "取消失败", + "operationFailed": "操作失败", + "getDataFailed": "获取数据失败", + "loadFailed": "加载失败", + "saveSuccess": "保存成功" + }, + "label": { + "basicInfo": "基本信息", + "flowConfig": "流程配置", + "triggerSettings": "触发设置", + "variables": "变量", + "credentials": "凭据", + "environments": "环境", + "toolConfig": "工具配置", + "releaseConfig": "发布配置", + "releaseRecords": "发布记录", + "permission": "发布权限", + "userGroups": "用户组", + "roles": "角色", + "gitRepo": "Git 仓库 ({{count}})", + "registry": "镜像仓库 ({{count}})", + "envManage": "环境管理 ({{count}})", + "advanced": "高级", + "loading": "加载中...", + "emptyDir": "目录为空", + "browse": "浏览", + "record": "记录", + "log": "日志", + "run": "运行", + "execute": "执行", + "download": "下载", + "searchPlaceholder": "搜索名称、描述...", + "allStatus": "全部状态", + "allEnv": "全部环境", + "allType": "全部类型", + "pagination": "{{n}}条/页" + } } }