From 1f45867eb5347560a90d4b8c5fa5622a32723e65 Mon Sep 17 00:00:00 2001 From: dream10201 Date: Wed, 10 Dec 2025 19:07:18 +0800 Subject: [PATCH] feat: add support for Chinese language (zh-CN) (#365) --- frontend/config/selection.ts | 1 + frontend/messages/zh-CN.json | 408 +++++++++++++++++++++++++++++++++++ frontend/src/i18n/routing.ts | 2 +- frontend/src/middleware.ts | 2 +- frontend/types/locale.ts | 2 +- 5 files changed, 412 insertions(+), 3 deletions(-) create mode 100644 frontend/messages/zh-CN.json diff --git a/frontend/config/selection.ts b/frontend/config/selection.ts index a74fb6e..177f2ac 100644 --- a/frontend/config/selection.ts +++ b/frontend/config/selection.ts @@ -13,6 +13,7 @@ const locales: LocaleType[] = [ { code: 'en', name: 'English' }, { code: 'ja', name: '日本語' }, { code: 'pt-BR', name: 'Português' }, + { code: 'zh-CN', name: '简体中文' }, ]; // The status of each test run diff --git a/frontend/messages/zh-CN.json b/frontend/messages/zh-CN.json new file mode 100644 index 0000000..af2f603 --- /dev/null +++ b/frontend/messages/zh-CN.json @@ -0,0 +1,408 @@ +{ + "RunStatus": { + "new": "新建", + "inProgress": "进行中", + "underReview": "审核中", + "rejected": "已拒绝", + "done": "完成", + "closed": "已关闭" + }, + "RunCaseStatus": { + "untested": "未测试", + "passed": "通过", + "failed": "失败", + "retest": "重测", + "skipped": "跳过" + }, + "Priority": { + "critical": "严重", + "high": "高", + "medium": "中", + "low": "低" + }, + "Type": { + "other": "其他", + "security": "安全", + "performance": "性能", + "accessibility": "无障碍", + "functional": "功能", + "acceptance": "验收", + "usability": "易用性", + "smoke_sanity": "冒烟与健全性", + "compatibility": "兼容性", + "destructive": "破坏性", + "regression": "回归", + "automated": "自动化", + "manual": "手动" + }, + "ProjectDialog": { + "project": "项目", + "project_name": "项目名称", + "project_detail": "项目详情", + "public": "公开", + "private": "私有", + "if_you_make_public": "将项目设为公开将使其对非项目成员用户可见。", + "close": "关闭", + "create": "创建", + "update": "更新", + "please_enter": "请输入项目名称" + }, + "Index": { + "get_started": "开始使用", + "demo": "演示", + "oss_tcms": "开源测试用例管理系统", + "integrate_and_manage": "集成并管理您的所有软件测试。", + "oss_title": "开源", + "oss_detail": "UnitTCMS 是免费且开源的。应用程序支持自托管,可部署在有严格安全要求的环境中。", + "organize_title": "组织测试用例", + "organize_detail": "可以通过项目和文件夹来组织测试用例。现代化的 UI 框架使其运行迅速。", + "usability_title": "易用性", + "usability_detail": "定义好的测试用例可以在测试运行中反复使用。测试运行和项目的状态可以通过图表直观查看。", + "universal_title": "通用性", + "universal_detail": "多语言支持和深色模式让任何人都可以无障碍地使用该系统。", + "project_title": "基于项目", + "project_subtitle": "以项目为单位管理测试用例和测试运行。我们的仪表盘提供了每个项目中测试用例类型及其进度的概览。这使您能够实时监控项目状态并进行高效管理。", + "case_management_title": "测试用例管理", + "case_management_subtitle": "在项目中创建文件夹,利用我们现代化且直观的 UI 轻松定义测试用例。支持附件上传,可对测试用例进行详细说明,便于在整个团队中共享信息。", + "run_management_title": "测试运行管理", + "run_management_subtitle": "定义好的测试用例可以在测试运行中多次复用,实现高效的测试循环。此外,您还可以可视化地监控测试运行和项目的状态。", + "member_management_title": "成员管理", + "member_management_subtitle": "通过在项目中添加或移除成员来支持团队开发。您可以为每个成员分配角色并详细设置权限。我们提供三种主要角色:“管理者”管理整个项目,“开发者”设计测试,“报告者”执行测试。" + }, + "Header": { + "title": "开源测试用例管理系统", + "description": "集成并管理您的所有软件测试", + "docs": "文档", + "roadmap": "路线图", + "projects": "项目", + "admin": "管理后台", + "account": "账户", + "profile_settings": "个人设置", + "signup": "注册", + "signin": "登录", + "signout": "退出", + "links": "链接", + "languages": "语言" + }, + "Toast": { + "need_signed_in": "您需要先登录", + "session_expired": "会话已过期" + }, + "Auth": { + "account": "账户", + "signup": "注册", + "signin": "登录", + "or_signup": "没有账号?去注册", + "or_signin": "已有账号?去登录", + "signin_as_guest": "或以访客身份登录", + "email": "邮箱", + "username": "用户名", + "password": "密码", + "confirm_password": "确认密码", + "invalid_email": "无效的邮箱地址", + "invalid_password": "密码必须至少包含 8 个字符", + "username_empty": "用户名不能为空", + "password_empty": "密码不能为空", + "password_not_match": "密码不匹配", + "email_already_exist": "邮箱已被注册", + "email_not_exist": "未找到该邮箱地址", + "signup_error": "注册失败", + "signin_error": "登录失败", + "demo_page_warning": "这是一个演示环境,您输入的任何数据都将被定期重置。", + "your_projects": "您的项目", + "public": "公开", + "private": "私有", + "not_own_any_projects": "您没有任何项目。", + "find_projects": "发现项目", + "profile_settings": "个人设置", + "change_username": "修改用户名", + "new_username": "新用户名", + "update_username": "更新用户名", + "username_updated": "用户名更新成功", + "change_password": "修改密码", + "current_password": "当前密码", + "new_password": "新密码", + "confirm_new_password": "确认新密码", + "update_password": "更新密码", + "password_updated": "密码更新成功", + "change_avatar": "修改头像", + "upload_avatar": "上传头像", + "remove_avatar": "移除头像", + "avatar_updated": "头像更新成功", + "avatar_removed": "头像移除成功", + "max_file_size_5mb": "最大文件大小:5MB", + "only_images_allowed": "仅允许上传图片文件", + "current_password_incorrect": "当前密码不正确", + "update_error": "更新失败" + }, + "Health": { + "health_check": "健康检查", + "status": "状态", + "ok": "正常", + "error": "错误", + "api_server": "API 服务器", + "unittcms_version": "UnitTCMS 版本" + }, + "Admin": { + "user_management": "用户管理", + "avatar": "头像", + "id": "ID", + "email": "邮箱", + "username": "用户名", + "role": "角色", + "administrator": "管理员", + "user": "用户", + "no_users_found": "未找到用户", + "quit_admin": "放弃管理员权限", + "close": "关闭", + "quit": "放弃", + "quit_confirm": "如果您放弃管理员权限,您将无法再访问管理页面。", + "role_changed": "角色已变更", + "lost_admin_auth": "已失去管理员权限", + "at_least": "至少需要保留一名管理员", + "reset_password": "重置密码", + "reset": "重置", + "invalid_password": "密码必须至少包含 8 个字符", + "password_not_match": "密码不匹配" + }, + "Projects": { + "project_list": "项目列表", + "new_project": "新建项目", + "id": "ID", + "publicity": "公开性", + "public": "公开", + "private": "私有", + "name": "名称", + "detail": "详情", + "last_update": "最后更新", + "no_projects_found": "未找到项目" + }, + "Project": { + "project": "项目", + "toggle_sidebar": "切换侧边栏", + "home": "首页", + "test_cases": "测试用例", + "test_runs": "测试运行", + "members": "成员", + "settings": "设置" + }, + "Home": { + "home": "首页", + "Folders": "文件夹", + "test_cases": "测试用例", + "test_runs": "测试运行", + "progress": "进度", + "test_classification": "测试分类", + "by_type": "按测试类型", + "by_priority": "按测试优先级" + }, + "Folders": { + "folder": "文件夹", + "new_folder": "新建文件夹", + "edit_folder": "编辑文件夹", + "delete_folder": "删除文件夹", + "folder_name": "文件夹名称", + "folder_detail": "文件夹详情", + "close": "关闭", + "create": "创建", + "update": "更新", + "please_enter": "请输入文件夹名称", + "delete": "删除", + "are_you_sure": "您确定要删除该文件夹吗?", + "no_folders_found": "未找到文件夹" + }, + "Cases": { + "test_case_list": "测试用例列表", + "id": "ID", + "title": "标题", + "priority": "优先级", + "actions": "操作", + "delete_case": "删除测试用例", + "delete": "删除", + "close": "关闭", + "are_you_sure": "您确定要删除测试用例吗?", + "new_test_case": "新建", + "export": "导出", + "status": "状态", + "no_cases_found": "未找到测试用例", + "case_title": "测试用例标题", + "case_description": "测试用例描述", + "case_title_or_description": "测试用例标题或描述", + "create": "创建", + "please_enter": "请输入测试用例标题", + "filter": "筛选", + "clear_all": "清除所有", + "apply": "应用", + "select_priorities": "选择优先级", + "selected": "已选择", + "type": "类型", + "select_types": "选择类型", + "cases_selected": "个用例已选择", + "select_action": "选择操作", + "move": "移动", + "clone": "克隆", + "cases_moved": "测试用例已移动", + "cases_cloned": "测试用例已克隆", + "tags": "标签", + "select_tags": "选择标签", + "import": "导入", + "import_cases": "导入测试用例", + "import_available": "您可以从 Excel 文件 (xlsx, xls) 导入测试用例。导入的 Excel 文件必须遵循指定格式。", + "download_template": "下载模板", + "click_to_upload": "点击上传", + "or_drag_and_drop": " 或拖拽文件到此处", + "max_file_size": "最大文件大小", + "cases_imported": "测试用例已导入", + "create_more": "继续创建" + }, + "Case": { + "back_to_cases": "返回测试用例列表", + "updating": "更新中...", + "update": "更新", + "updated_test_case": "测试用例已更新", + "basic": "基本信息", + "title": "标题", + "please_enter_title": "请输入标题", + "description": "描述", + "test_case_description": "测试用例描述", + "priority": "优先级", + "type": "类型", + "template": "模板", + "test_detail": "测试详情", + "preconditions": "前置条件", + "expected_result": "预期结果", + "step": "步骤", + "text": "文本", + "steps": "步骤", + "new_step": "新步骤", + "details_of_the_step": "步骤详情", + "delete_this_step": "删除此步骤", + "insert_step": "插入步骤", + "attachments": "附件", + "delete": "删除", + "download": "下载", + "delete_file": "删除文件", + "click_to_upload": "点击上传", + "or_drag_and_drop": " 或拖拽文件到此处", + "max_file_size": "最大文件大小", + "are_you_sure_leave": "您确定要离开此页面吗?", + "tags": "标签", + "create_tag": "创建标签", + "max_tags_limit": "最大标签数量限制", + "tag_already_exists": "标签已存在", + "tag_created_and_added": "标签已创建并添加", + "error_creating_tag": "创建标签失败", + "error_updating_test_case": "更新测试用例失败", + "search_or_create_tag": "搜索或创建标签", + "no_tags_selected": "未选择标签" + }, + "Runs": { + "run_list": "测试运行列表", + "run": "运行", + "new_run": "新建运行", + "edit_run": "编辑运行", + "delete_run": "删除运行", + "id": "ID", + "name": "名称", + "description": "描述", + "last_update": "最后更新", + "actions": "操作", + "run_name": "运行名称", + "run_description": "运行描述", + "no_runs_found": "未找到测试运行", + "close": "关闭", + "create": "创建", + "update": "更新", + "please_enter": "请输入运行名称", + "are_you_sure": "您确定要删除该测试运行吗?", + "delete": "删除" + }, + "Run": { + "back_to_runs": "返回测试运行列表", + "updating": "更新中...", + "update": "更新", + "updated_test_run": "测试运行已更新", + "export": "导出", + "progress": "进度", + "refresh": "刷新", + "id": "ID", + "title": "标题", + "please_enter": "请输入运行名称", + "description": "描述", + "priority": "优先级", + "status": "状态", + "actions": "操作", + "select_test_case": "选择测试用例", + "test_case_selection": "测试用例选择", + "include_in_run": "包含在运行中", + "exclude_from_run": "从运行中排除", + "no_cases_found": "未找到用例", + "are_you_sure_leave": "您确定要离开此页面吗?", + "type": "类型", + "test_detail": "测试详情", + "steps": "步骤", + "preconditions": "前置条件", + "expected_result": "预期结果", + "details_of_the_step": "步骤详情", + "close": "关闭", + "filter": "筛选", + "clear_all": "清除所有", + "apply": "应用", + "select_status": "选择状态", + "please_save": "请保存更改", + "case_title_or_description": "测试用例标题或描述", + "selected": "已选择", + "tags": "标签", + "select_tags": "选择标签" + }, + "Members": { + "member_management": "成员管理", + "avatar": "头像", + "email": "邮箱", + "username": "用户名", + "role": "角色", + "manager": "管理者", + "developer": "开发者", + "reporter": "报告者", + "delete": "删除", + "deleteMember": "删除成员", + "no_members_found": "未找到成员", + "add_member": "添加成员", + "user_name_or_email": "用户名或邮箱", + "close": "关闭", + "add": "添加", + "are_you_sure": "您确定要删除该成员吗?", + "member_added": "成员已添加", + "role_changed": "成员角色已变更", + "member_deleted": "成员已删除" + }, + "Settings": { + "project_management": "项目管理", + "project_name": "项目名称", + "project_detail": "项目详情", + "project_owner": "项目所有者", + "edit_project": "编辑项目", + "publicity": "公开性", + "public": "公开", + "private": "私有", + "delete_project": "删除项目", + "delete": "删除", + "close": "关闭", + "are_you_sure": "您确定要删除该项目吗?", + "tag_management": "标签管理", + "tag_name": "标签名称", + "add_tag": "添加标签", + "no_tags_available": "暂无标签", + "delete_tag": "删除标签", + "are_you_sure_delete_tag": "您确定要删除该标签吗?", + "tag_created": "标签创建成功。", + "tag_updated": "标签更新成功。", + "tag_deleted": "标签删除成功。", + "tag_error_empty": "标签名称不能为空。", + "tag_error_min_length": "标签名称长度至少为 3 个字符。", + "tag_error_max_length": "标签名称不能超过 20 个字符。", + "tag_error_create": "标签创建失败,请重试。", + "tag_error_update": "标签更新失败,请重试。", + "tag_error_delete": "标签删除失败,请重试。" + } +} diff --git a/frontend/src/i18n/routing.ts b/frontend/src/i18n/routing.ts index e7fca45..7d53fab 100644 --- a/frontend/src/i18n/routing.ts +++ b/frontend/src/i18n/routing.ts @@ -2,7 +2,7 @@ import { createNavigation } from 'next-intl/navigation'; import { defineRouting } from 'next-intl/routing'; export const routing = defineRouting({ - locales: ['en', 'ja', 'pt-BR'], + locales: ['en', 'ja', 'pt-BR', 'zh-CN'], defaultLocale: 'en', localePrefix: { mode: 'always', diff --git a/frontend/src/middleware.ts b/frontend/src/middleware.ts index e781684..8f818c3 100644 --- a/frontend/src/middleware.ts +++ b/frontend/src/middleware.ts @@ -4,5 +4,5 @@ import { routing } from './i18n/routing'; export default createMiddleware(routing); export const config = { - matcher: ['/', '/(ja|en|pt-BR)/:path*'], + matcher: ['/', '/(ja|en|pt-BR|zh-CN)/:path*'], }; diff --git a/frontend/types/locale.ts b/frontend/types/locale.ts index 04ded07..50f8241 100644 --- a/frontend/types/locale.ts +++ b/frontend/types/locale.ts @@ -1,4 +1,4 @@ -export type LocaleCodeType = 'en' | 'ja' | 'pt-BR'; +export type LocaleCodeType = 'en' | 'ja' | 'pt-BR' | 'zh-CN'; export type LocaleType = { code: LocaleCodeType;