mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 15:36:33 +00:00
ba7d55f999
BODY_CONTRACT_ALLOW_LIST is empty. The last seventeen handlers type their
body with a createZodDto class, so the fail-closed boot gate has nothing left
to forgive; it still refuses a boot for a new handler that reads @Body()
without one.
Several of those contracts describe rather than constrain, and that is the
whole care in this change. The pipe runs before the handler, so a schema
stricter than the handler moves a user-visible answer:
- TagsController.create answers { error: 'Tag name is required' }, pinned
byte-for-byte in two tests, and the pipe formats as `field: message`. The
DTO leaves name optional and the handler keeps the check that owns the
message. Same shape for the booking-import confirm body, which additionally
gains per-item validation the handler never did.
- PluginsController.activate and install answer 503 when plugins are disabled,
and check that BEFORE looking at the body. A schema that rejected first
would turn that into a 400 for an operator whose server has plugins off.
- setEgressHosts reads a non-array `hosts` as "clear the list", which is the
documented reset. Typing it as string[] would have removed a working admin
action rather than tightened anything.
- PluginRoutesController.route answers { route: null } at 200 for everything
it dislikes, so the client falls back to straight lines. A 400 there would
turn a graceful degradation into a visible error.
files.bridge is gone. The multer options are built by
MulterModule.registerAsync from an AllowedFileTypesService leaf, so the
fileFilter reads the operator's extension list from the container instead of
from a second FilesService built outside it. Nest injects
MULTER_MODULE_OPTIONS with @Optional(), so a token that fails to resolve is
not a boot error: it silently falls back to defaults, with no filter and no
size cap. FILE-020 already proved that for trip files by uploading an .svg
over HTTP and expecting 400; journey uploads had no such case, and now do.
VIDEO_UPLOAD is untouched, including the filename callback that forces .jpg
regardless of what the client sends, which guards the public share proxy.
PluginFrame gets an onError. A frame whose document fails to load left a
blank element at full height, which reads as a hung app rather than as a
plugin that is gone.
typecheck:tests runs in CI now, with the test tree at zero errors. tz-lookup
is left as it is: the build puts it in a lazy helpers chunk, not the entry
chunk, and the remaining split would trade a synchronous render for an async
one to move 172 kB that is already off the critical path.
632 lines
42 KiB
TypeScript
632 lines
42 KiB
TypeScript
import type { TranslationStrings } from '../types';
|
||
|
||
const admin: TranslationStrings = {
|
||
'admin.notifications.title': '通知',
|
||
'admin.notifications.hint': '选择一个通知渠道。一次只能激活一个。',
|
||
'admin.notifications.none': '已禁用',
|
||
'admin.notifications.email': '电子邮件 (SMTP)',
|
||
'admin.notifications.webhook': 'Webhook',
|
||
'admin.notifications.save': '保存通知设置',
|
||
'admin.notifications.saved': '通知设置已保存',
|
||
'admin.notifications.testWebhook': '发送测试 Webhook',
|
||
'admin.notifications.testWebhookSuccess': '测试 Webhook 发送成功',
|
||
'admin.notifications.testWebhookFailed': '测试 Webhook 发送失败',
|
||
'admin.smtp.title': '邮件与通知',
|
||
'admin.smtp.hint': '用于发送电子邮件通知的 SMTP 配置。',
|
||
'admin.smtp.testButton': '发送测试邮件',
|
||
'admin.webhook.hint': '向外部 Webhook 发送通知(Discord、Slack 等)。',
|
||
'admin.smtp.testSuccess': '测试邮件发送成功',
|
||
'admin.smtp.testFailed': '测试邮件发送失败',
|
||
'admin.title': '管理后台',
|
||
'admin.subtitle': '用户管理和系统设置',
|
||
'admin.tabs.users': '用户',
|
||
'admin.tabs.categories': '分类',
|
||
'admin.tabs.backup': '备份',
|
||
'admin.tabs.audit': '审计',
|
||
'admin.stats.users': '用户',
|
||
'admin.stats.trips': '旅行',
|
||
'admin.stats.places': '地点',
|
||
'admin.stats.photos': '照片',
|
||
'admin.stats.files': '文件',
|
||
'admin.table.user': '用户',
|
||
'admin.table.email': '邮箱',
|
||
'admin.table.role': '角色',
|
||
'admin.table.created': '创建时间',
|
||
'admin.table.lastLogin': '最后登录',
|
||
'admin.table.actions': '操作',
|
||
'admin.you': '(你)',
|
||
'admin.editUser': '编辑用户',
|
||
'admin.newPassword': '新密码',
|
||
'admin.newPasswordHint': '留空则保持当前密码',
|
||
'admin.deleteUser': '删除用户「{name}」?所有旅行将被永久删除。',
|
||
'admin.deleteUserTitle': '删除用户',
|
||
'admin.newPasswordPlaceholder': '输入新密码…',
|
||
'admin.toast.loadError': '加载管理数据失败',
|
||
'admin.toast.userUpdated': '用户已更新',
|
||
'admin.toast.updateError': '更新失败',
|
||
'admin.toast.userDeleted': '用户已删除',
|
||
'admin.toast.deleteError': '删除失败',
|
||
'admin.toast.cannotDeleteSelf': '不能删除自己的账户',
|
||
'admin.toast.userCreated': '用户已创建',
|
||
'admin.toast.createError': '创建用户失败',
|
||
'admin.toast.fieldsRequired': '用户名、邮箱和密码为必填项',
|
||
'admin.createUser': '创建用户',
|
||
'admin.invite.title': '邀请链接',
|
||
'admin.invite.subtitle': '创建一次性注册链接',
|
||
'admin.invite.create': '创建链接',
|
||
'admin.invite.createAndCopy': '创建并复制',
|
||
'admin.invite.empty': '尚未创建邀请链接',
|
||
'admin.invite.maxUses': '最大使用次数',
|
||
'admin.invite.expiry': '有效期',
|
||
'admin.invite.uses': '已使用',
|
||
'admin.invite.expiresAt': '过期时间',
|
||
'admin.invite.createdBy': '由',
|
||
'admin.invite.active': '有效',
|
||
'admin.invite.expired': '已过期',
|
||
'admin.invite.usedUp': '已用完',
|
||
'admin.invite.copied': '邀请链接已复制',
|
||
'admin.invite.copyLink': '复制链接',
|
||
'admin.invite.deleted': '邀请链接已删除',
|
||
'admin.invite.createError': '创建链接失败',
|
||
'admin.invite.deleteError': '删除链接失败',
|
||
'admin.tabs.settings': '设置',
|
||
'admin.allowRegistration': '允许注册',
|
||
'admin.allowRegistrationHint': '新用户可以自行注册',
|
||
'admin.authMethods': '登录方式',
|
||
'admin.passwordLogin': '密码登录',
|
||
'admin.passwordLoginHint': '允许用户使用邮箱和密码登录',
|
||
'admin.passwordRegistration': '密码注册',
|
||
'admin.passwordRegistrationHint': '允许新用户使用邮箱和密码注册',
|
||
'admin.oidcLogin': 'SSO 登录',
|
||
'admin.oidcLoginHint': '允许用户通过 SSO 登录',
|
||
'admin.oidcRegistration': 'SSO 自动创建账户',
|
||
'admin.oidcRegistrationHint': '为首次通过 SSO 登录的用户自动创建账户',
|
||
'admin.envOverrideHint': '密码登录设置由 OIDC_ONLY 环境变量控制,无法在此处修改。',
|
||
'admin.lockoutWarning': '至少需要保留一种登录方式',
|
||
'admin.requireMfa': '要求双因素身份验证(2FA)',
|
||
'admin.requireMfaHint': '未启用 2FA 的用户必须先完成设置中的配置才能使用应用。',
|
||
'admin.apiKeys': 'API 密钥',
|
||
'admin.apiKeysHint': '可选。启用地点的扩展数据,如照片和天气。',
|
||
'admin.mapsKey': 'Google Maps API 密钥',
|
||
'admin.mapsKeyHint': '用于地点搜索。在 console.cloud.google.com 获取',
|
||
'admin.mapsKeyHintLong':
|
||
'没有 API 密钥时,使用 OpenStreetMap 搜索地点。有了 Google API 密钥,还可以加载照片、评分和营业时间。在 console.cloud.google.com 获取。',
|
||
'admin.recommended': '推荐',
|
||
'admin.weatherKey': 'OpenWeatherMap API 密钥',
|
||
'admin.weatherKeyHint': '用于天气数据。在 openweathermap.org 免费获取',
|
||
'admin.unsplashKey': 'Unsplash API 密钥',
|
||
'admin.unsplashKeyHint': '用于图片搜索。在 unsplash.com/developers 免费获取',
|
||
'admin.validateKey': '测试',
|
||
'admin.keyValid': '已连接',
|
||
'admin.keyInvalid': '无效',
|
||
'admin.keySaved': 'API 密钥已保存',
|
||
'admin.oidcTitle': '单点登录 (OIDC)',
|
||
'admin.oidcSubtitle': '允许通过 Google、Apple、Authentik 或 Keycloak 等外部提供商登录。',
|
||
'admin.oidcDisplayName': '显示名称',
|
||
'admin.oidcIssuer': '颁发者 URL',
|
||
'admin.oidcIssuerHint': '提供商的 OpenID Connect 颁发者 URL。如 https://accounts.google.com',
|
||
'admin.oidcSaved': 'OIDC 配置已保存',
|
||
'admin.oidcOnlyMode': '禁用密码登录',
|
||
'admin.oidcOnlyModeHint': '启用后,仅允许 SSO 登录。密码登录和注册将被禁用。',
|
||
'admin.fileTypes': '允许的文件类型',
|
||
'admin.fileTypesHint': '配置用户可以上传的文件类型。',
|
||
'admin.fileTypesFormat': '以逗号分隔的扩展名(如 jpg,png,pdf,doc)。使用 * 允许所有类型。',
|
||
'admin.fileTypesSaved': '文件类型设置已保存',
|
||
'admin.placesPhotos.title': '地点照片',
|
||
'admin.placesPhotos.subtitle': '从 Google Places API 获取照片。禁用可节省 API 配额。Wikimedia 照片不受影响。',
|
||
'admin.placesAutocomplete.title': '地点自动补全',
|
||
'admin.placesAutocomplete.subtitle': '使用 Google Places API 提供搜索建议。禁用可节省 API 配额。',
|
||
'admin.placesDetails.title': '地点详情',
|
||
'admin.placesDetails.subtitle':
|
||
'从 Google Places API 获取地点详细信息(营业时间、评分、网站)。禁用可节省 API 配额。',
|
||
'admin.placesEnrich.title': '地点信息补充',
|
||
'admin.placesEnrich.subtitle':
|
||
'添加地点时显示图片和描述。始终使用维基百科和 OpenStreetMap;开启「地点照片」或「地点详情」时会额外使用 Google。',
|
||
'admin.bagTracking.title': '行李追踪',
|
||
'admin.bagTracking.subtitle': '为打包物品启用重量和行李分配',
|
||
'admin.collab.chat.title': '聊天',
|
||
'admin.collab.chat.subtitle': '实时消息协作',
|
||
'admin.collab.notes.title': '笔记',
|
||
'admin.collab.notes.subtitle': '共享笔记和文档',
|
||
'admin.collab.polls.title': '投票',
|
||
'admin.collab.polls.subtitle': '群组投票和表决',
|
||
'admin.collab.whatsnext.title': '下一步',
|
||
'admin.collab.whatsnext.subtitle': '活动建议和后续步骤',
|
||
'admin.tabs.config': '个性化',
|
||
'admin.tabs.defaults': '用户默认设置',
|
||
'admin.defaultSettings.title': '用户默认设置',
|
||
'admin.defaultSettings.description': '设置实例范围的默认值。未更改设置的用户将看到这些值。用户自己的更改始终优先。',
|
||
'admin.defaultSettings.saved': '默认值已保存',
|
||
'admin.defaultSettings.reset': '重置为内置默认值',
|
||
'admin.defaultSettings.resetToBuiltIn': '重置',
|
||
'admin.tabs.templates': '打包模板',
|
||
'admin.packingTemplates.title': '打包模板',
|
||
'admin.packingTemplates.subtitle': '创建可复用的旅行打包清单',
|
||
'admin.packingTemplates.create': '新建模板',
|
||
'admin.packingTemplates.namePlaceholder': '模板名称(如:海滩度假)',
|
||
'admin.packingTemplates.empty': '尚未创建模板',
|
||
'admin.packingTemplates.items': '物品',
|
||
'admin.packingTemplates.categories': '分类',
|
||
'admin.packingTemplates.itemName': '物品名称',
|
||
'admin.packingTemplates.itemCategory': '分类',
|
||
'admin.packingTemplates.categoryName': '分类名称(如:衣物)',
|
||
'admin.packingTemplates.addCategory': '添加分类',
|
||
'admin.packingTemplates.created': '模板已创建',
|
||
'admin.packingTemplates.deleted': '模板已删除',
|
||
'admin.packingTemplates.loadError': '加载模板失败',
|
||
'admin.packingTemplates.createError': '创建模板失败',
|
||
'admin.packingTemplates.deleteError': '删除模板失败',
|
||
'admin.packingTemplates.deleteCategoryError': '删除分类失败',
|
||
'admin.packingTemplates.deleteItemError': '删除项目失败',
|
||
'admin.packingTemplates.saveError': '保存失败',
|
||
'admin.tabs.addons': '扩展',
|
||
'admin.tabs.plugins': '插件',
|
||
'admin.plugins.rescan': '重新扫描',
|
||
'admin.plugins.rescanned': '已重新扫描插件文件夹',
|
||
'admin.plugins.upload': '上传插件',
|
||
'admin.plugins.dropToUpload': '拖入插件 .zip 以安装',
|
||
'admin.plugins.uploaded': '插件“{name}”已上传 — 激活后即可运行',
|
||
'admin.plugins.sideloaded': '手动加载',
|
||
'admin.plugins.devLinkBadge': 'Dev-Link',
|
||
'admin.plugins.devLinkHint': '从本地构建目录加载并针对真实数据热重载 — 仅供开发',
|
||
'admin.plugins.devLinkTitle': '链接本地插件',
|
||
'admin.plugins.devLinkPathPlaceholder': '/absolute/path/to/your/plugin',
|
||
'admin.plugins.devLinkButton': '链接',
|
||
'admin.plugins.devLinkLinked': '已链接 {id} — 激活后运行',
|
||
'admin.plugins.sideloadedHint': '手动上传 — 非来自插件库,未签名且未审核',
|
||
'admin.plugins.browse': '浏览插件',
|
||
'admin.plugins.installed': '已安装',
|
||
'admin.plugins.install': '安装',
|
||
'admin.plugins.registryEmpty': '插件库中暂无可用插件。',
|
||
'admin.plugins.actionError': '操作失败',
|
||
'admin.plugins.activate': '激活',
|
||
'admin.plugins.activated': '插件已激活',
|
||
'admin.plugins.deactivate': '停用',
|
||
'admin.plugins.deactivated': '插件已停用',
|
||
'admin.plugins.viewErrors': '查看错误日志',
|
||
'admin.plugins.errorLog': '错误日志',
|
||
'admin.plugins.allowedHosts': '允许的主机',
|
||
'admin.plugins.allowedHosts.hint':
|
||
'此插件会连接一个只有你才知道地址的服务(自托管服务器)。请添加它可以访问的主机 —— 其他主机一概无法访问。',
|
||
'admin.plugins.allowedHosts.none': '尚未添加主机。',
|
||
'admin.plugins.allowedHosts.unsupported': '此插件不使用运营者提供的主机。其允许的主机已在清单中固定。',
|
||
'admin.plugins.allowedHosts.restartNote': '保存会重启插件,以便应用新的列表。',
|
||
'admin.plugins.allowedHosts.add': '添加允许的主机',
|
||
'admin.plugins.allowedHosts.count': '{n} 个允许的主机',
|
||
'admin.plugins.operatorEgressPill': '+ 你添加的主机',
|
||
'admin.plugins.operatorEgressHint':
|
||
'此插件会连接一个只有你才知道地址的服务(自托管服务器)。安装后请在 ⋯ → 允许的主机 中添加。其他主机一概无法访问。',
|
||
'admin.plugins.noErrors': '暂无错误记录。',
|
||
'admin.plugins.uninstalled': '插件已卸载',
|
||
'admin.plugins.uninstallTitle': '卸载插件?',
|
||
'admin.plugins.uninstallBody': '这将停止该插件、移除其代码并删除其全部数据。此操作无法撤销。',
|
||
'admin.plugins.status.starting': '启动中…',
|
||
'admin.plugins.type.widget': '小组件',
|
||
'admin.plugins.type.page': '页面',
|
||
'admin.plugins.type.integration': '集成',
|
||
'admin.plugins.type.trip-page': '行程页面',
|
||
'admin.plugins.reviewed': '已审核',
|
||
'admin.plugins.unreviewed': '未审核',
|
||
'admin.plugins.updated': '插件已更新',
|
||
'admin.plugins.updateTo': '更新 → v{version}',
|
||
'admin.plugins.enabledToggle': '启用插件',
|
||
'plugins.notFound': '未找到插件',
|
||
'plugins.frameLoadFailed': 'This plugin could not be loaded.',
|
||
'admin.plugins.title': '插件',
|
||
'admin.plugins.subtitle': '在你的实例上安装和管理第三方插件。',
|
||
'admin.plugins.disabledTitle': '插件功能已禁用',
|
||
'admin.plugins.disabledBody':
|
||
'插件运行时已关闭(TREK_PLUGINS_ENABLED)。在管理员于服务器配置中启用之前,任何插件都无法运行。',
|
||
'admin.plugins.empty': '尚未安装任何插件。',
|
||
'admin.plugins.loadError': '无法加载插件。',
|
||
'admin.plugins.scaffoldNote': '插件的安装与激活功能将在后续更新中推出。此面板目前仅列出已安装的插件。',
|
||
'admin.plugins.status.active': '已激活',
|
||
'admin.plugins.status.inactive': '未激活',
|
||
'admin.plugins.status.disabled': '已禁用',
|
||
'admin.plugins.status.error': '错误',
|
||
'admin.plugins.status.incompatible': '不兼容',
|
||
'admin.plugins.details': '详情',
|
||
'admin.plugins.detailError': '无法加载插件详情。',
|
||
'admin.plugins.permissionsTitle': '权限',
|
||
'admin.plugins.noPermissions': '此插件不请求任何特殊权限。',
|
||
'admin.plugins.egressNote': '可能连接到:{hosts}',
|
||
'admin.plugins.setupTitle': '设置',
|
||
'admin.plugins.noSetup': '开箱即用——无需任何配置。',
|
||
'admin.plugins.scope.instance': '全实例',
|
||
'admin.plugins.scope.user': '按用户',
|
||
'admin.plugins.fieldRequired': '必填',
|
||
'admin.plugins.sourceRepo': '源代码仓库',
|
||
'admin.plugins.reportIssue': '报告问题',
|
||
'admin.plugins.homepage': '主页',
|
||
'admin.plugins.requiresTrek': '需要 TREK {version}+',
|
||
'admin.plugins.reviewedOn': '审核于 {date}',
|
||
'admin.plugins.perm.db:own': '在隔离的数据库中存储自己的数据',
|
||
'admin.plugins.perm.db:read:trips': '读取当前用户可访问的旅行',
|
||
'admin.plugins.perm.db:read:users': '读取基本个人资料(姓名、头像——绝不包括凭据)',
|
||
'admin.plugins.perm.db:read:costs': '读取当前用户可访问的支出(预算项)',
|
||
'admin.plugins.perm.db:read:packing': '读取当前用户可访问的旅行的行李清单',
|
||
'admin.plugins.perm.db:write:packing': '在当前用户可编辑的旅行中创建、编辑和删除打包清单项',
|
||
'admin.plugins.perm.weather:read': '读取主机缓存的天气预报(按坐标)',
|
||
'admin.plugins.perm.db:read:categories': '读取全局地点类别列表',
|
||
'admin.plugins.perm.db:read:tags': '读取当前用户的标签',
|
||
'admin.plugins.perm.db:write:tags': '创建、编辑和删除当前用户的标签',
|
||
'admin.plugins.perm.db:read:todos': '读取当前用户可访问的旅行的待办事项',
|
||
'admin.plugins.perm.db:write:todos': '在当前用户可编辑的旅行中创建、编辑和删除待办事项',
|
||
'admin.plugins.perm.db:write:atlas': '标记当前用户已访问的国家和地区并管理愿望清单(需要 Atlas 插件)',
|
||
'admin.plugins.perm.db:write:vacay': '在当前用户的活动计划中切换休假日和公司假期(需要 Vacay 插件)',
|
||
'admin.plugins.perm.db:write:journal': '在当前用户可编辑的日记中创建、编辑和删除条目(需要 Journey 插件)',
|
||
'admin.plugins.perm.db:write:collections':
|
||
'创建和编辑收藏并向其中保存地点,使用当前用户的收藏角色(需要 Collections 插件)',
|
||
'admin.plugins.perm.db:write:files':
|
||
'向当前用户可编辑的旅行附加文件(10MB 上限,被阻止的扩展名将被拒绝)并管理其链接',
|
||
'admin.plugins.perm.db:write:collab': '在当前用户可编辑的旅行中发布笔记、投票和聊天消息(需要 Collab 插件)',
|
||
'admin.plugins.perm.db:write:members': '向旅行添加用户 — 授予旅行访问权限;受当前用户的成员管理权限保护',
|
||
'admin.plugins.perm.notify:send': '向当前用户或其所属的旅行发送通知(铃铛收件箱 + 邮件/ntfy)— 绝不发送给任意接收者',
|
||
'admin.plugins.perm.ai:invoke': '代表当前用户运行管理员配置的 AI 提供商(文本补全 + 文档提取)— 插件绝不持有密钥',
|
||
'admin.plugins.perm.oauth:client': '通过主机代理的 OAuth 代表你连接第三方服务(令牌由主机保管,插件永远看不到)',
|
||
'admin.plugins.perm.db:read:files': '读取当前用户可访问的旅行的文件',
|
||
'admin.plugins.perm.db:write:reservations': '在当前用户可编辑的旅行中创建、编辑和删除预订',
|
||
'admin.plugins.perm.db:write:accommodations': '在当前用户可编辑的旅行中创建、编辑和删除住宿',
|
||
'admin.plugins.perm.db:read:journal': '读取当前用户的旅行日记(需要 Journey 插件)',
|
||
'admin.plugins.perm.db:read:atlas': '读取当前用户已访问的国家和地区(需要 Atlas 插件)',
|
||
'admin.plugins.perm.db:read:vacay': '读取当前用户的假期计划(需要 Vacay 插件)',
|
||
'admin.plugins.perm.db:read:daynotes': '读取当前用户可访问的旅行的每日备注',
|
||
'admin.plugins.perm.db:read:collections': '读取当前用户已保存地点的收藏(需要 Collections 插件)',
|
||
'admin.plugins.perm.db:write:daynotes': '在当前用户可编辑的旅行中创建、编辑和删除每日备注',
|
||
'admin.plugins.perm.jobs:run': '按计划运行其声明的后台任务(无用户上下文 — 无法读取用户数据)',
|
||
'admin.plugins.perm.db:write:costs': '在当前用户可编辑的旅行中创建支出(预算项)',
|
||
'admin.plugins.perm.db:write:places': '在当前用户可编辑的旅行中添加、编辑和删除地点',
|
||
'admin.plugins.perm.db:write:days': '在当前用户可编辑的旅行中添加、编辑和删除行程日',
|
||
'admin.plugins.perm.db:write:itinerary': '在当前用户可编辑的旅行中,为各行程日分配和移除地点',
|
||
'admin.plugins.perm.db:write:trips': '在当前用户可编辑的旅行中编辑行程详情(标题、日期、货币…)',
|
||
'admin.plugins.perm.db:meta': '将其自有的私有数据附加到操作用户可访问的旅行、地点和行程日上',
|
||
'admin.plugins.perm.ws:broadcast:trip': '向旅行成员发送实时更新',
|
||
'admin.plugins.perm.ws:broadcast:user': '向单个用户发送实时更新',
|
||
'admin.plugins.perm.hook:photo-provider': '为回忆提供照片',
|
||
'admin.plugins.perm.hook:calendar-source': '为日历提供事件',
|
||
'admin.plugins.perm.hook:place-detail-provider': '为地点补充额外信息(评论、评分、链接)',
|
||
'admin.plugins.perm.hook:trip-warning-provider': '对行程发出校验警告(显示在规划器中)',
|
||
'admin.plugins.perm.hook:table-contributor': '向行程视图(预订、地点、日期)添加列和操作',
|
||
'admin.plugins.perm.hook:map-marker-provider': '向旅行地图添加标记(例如显示预订或兴趣点)',
|
||
'admin.plugins.perm.hook:map-layer-provider': '在旅行地图上绘制路线、走廊和区域',
|
||
'admin.plugins.perm.hook:route-provider': '提供路线规划方案,供规划器计算每日路线(例如带充电停靠点的电动车路线)',
|
||
'admin.plugins.perm.hook:day-schedule-provider': '向当日计划添加时间条目(充电停靠点、安全缓冲时间)',
|
||
'admin.plugins.perm.hook:day-tint-provider': '为当日计划中的日期标注颜色(例如某天属于行程的哪一段)',
|
||
'admin.plugins.perm.geolocation:read': '在其某个视图打开时请求你的实时位置(你的浏览器仍会先询问)',
|
||
'admin.plugins.perm.hook:pdf-section-provider': '向行程 PDF 导出追加文本段落',
|
||
'admin.plugins.perm.hook:atlas-layer-provider': '在 Atlas 世界地图上高亮国家(例如愿望清单或旅行提醒)',
|
||
'admin.plugins.perm.hook:journal-entry-provider': '向日志条目添加额外行(链接、统计)',
|
||
'admin.plugins.perm.hook:user-data': '删除或导出其存储的某用户数据(GDPR:账户删除与数据请求)',
|
||
'admin.plugins.perm.hook:trip-card-provider': '在仪表盘的行程卡片上添加小徽章(状态、计数)',
|
||
'admin.plugins.perm.hook:notification-channel': '通过额外的渠道发送你的通知',
|
||
'admin.plugins.perm.events:subscribe': '响应核心活动事件(仅事件名称和行程,绝不包含内容)',
|
||
'admin.plugins.perm.http:outbound': '向其声明的主机发出出站请求',
|
||
'admin.plugins.perm.db:read:collab': '读取当前用户可访问的旅行的笔记、投票和聊天消息(需要 Collab 插件)',
|
||
'admin.plugins.perm.db:read:files:content': '读取当前用户可访问的旅行的文件内容(字节)',
|
||
'admin.plugins.perm.db:create:trips': '创建归当前用户所有的新旅行',
|
||
'admin.plugins.perm.rates:read': '读取主机缓存的货币汇率',
|
||
'admin.plugins.updateConsentTitle': '此次更新需要新的权限',
|
||
'admin.plugins.updateConsentBody':
|
||
'{name} v{version} 请求了你尚未授予的权限。新版本已安装,但在你批准之前将保持关闭。',
|
||
'admin.plugins.updateNewPermissions': '新请求的权限',
|
||
'admin.plugins.updateNewEgress': '新的出站连接',
|
||
'admin.plugins.updateApprove': '批准并启用',
|
||
'admin.plugins.updateLater': '暂时保持关闭',
|
||
'admin.plugins.updateKeptOff': '更新已安装 —— 在你批准新权限之前保持关闭',
|
||
'admin.plugins.reviewedMeaning':
|
||
'“已审核”表示 TREK 维护者已针对该插件的每个版本进行了恶意软件扫描 —— 而非检查其质量或是否可用。这并不保证插件无害。',
|
||
'admin.plugins.security.title': '插件如何被隔离 —— 以及其局限',
|
||
'admin.plugins.security.isolationTitle': '每个插件都在隔离环境中运行',
|
||
'admin.plugins.security.isolationBody':
|
||
'插件作为其独立的受限进程运行,只能读取自己的文件。它无法读取你的数据库、登录密钥或加密密钥,无法启动其他程序,也无法在任何位置写入文件。它的界面运行在一个封闭的浏览器框架中,既读不到你的会话 Cookie,也无法触及周围的 TREK 页面。',
|
||
'admin.plugins.security.permsTitle': '权限的含义',
|
||
'admin.plugins.security.permsBody':
|
||
'安装前显示的权限是 TREK 在插件运行期间强制执行的硬性上限 —— 凡是不在清单上的事,插件根本无法做到。但它们只告诉你插件能做什么,而非它实际做了什么。一个获准读取你的行程并连接某服务器的插件,就能把你的行程发送到该服务器,因此请仔细阅读权限和出站主机,而不只是看描述。',
|
||
'admin.plugins.security.limitsTitle': '我们无法承诺的事',
|
||
'admin.plugins.security.limitsBody':
|
||
'这种隔离是强有力的软件边界,但并非绝对。插件所拥有的权限完全就是你批准的那些,因此在这些权限范围内,它的行为可能与其描述不符,也可能把它合法持有的数据发送到它所声明的主机。TREK 不会读取或评判插件代码实际做了什么。',
|
||
'admin.plugins.security.worstTitle': '最坏的情况',
|
||
'admin.plugins.security.worstBody':
|
||
'你启用的恶意插件可能滥用你授予它的数据和连接 —— 例如,泄露它有权读取的行程。但它无法窃取密码、伪造管理员登录、在你的服务器上执行命令,也无法触及你未授权的数据。损害始终限于你批准的范围,而停用该插件即可将其制止。',
|
||
'admin.plugins.security.reviewedTitle': '“已审核”的含义',
|
||
'admin.plugins.security.reviewedBody':
|
||
'已审核的插件,其每个版本都经过 TREK 维护者的人工恶意软件扫描 —— 检查的是有无恶意代码,而非它是否运行良好。这并不保证插件无害。',
|
||
'admin.plugins.security.signedTitle': '“已签名”的含义',
|
||
'admin.plugins.security.signedBody':
|
||
'TREK 在每次安装时校验的校验和,证明这些文件正是插件库所担保的那些文件。签名证明的则是另一回事:它们出自作者本人,并以只有作者持有的密钥签署。已签名的插件两者兼备。未签名并不意味着不安全 —— 它只是少了一重保证,而目前插件库中的大多数插件都未签名。',
|
||
'admin.plugins.signed': '已签名',
|
||
'admin.plugins.signedHint': '安装时已用作者的签名密钥验证过',
|
||
'admin.plugins.unsigned': '未签名',
|
||
'admin.plugins.unsignedHint':
|
||
'文件与插件库所担保的内容一致,但没有任何东西能把它们与作者关联起来。少了一重保证 —— 但并非不安全。',
|
||
'admin.plugins.updateBlocked': '更新已阻止 —— {reason}',
|
||
'admin.plugins.reviewBlock': '查看',
|
||
'admin.plugins.retrusted': '已信任新的签名密钥 —— 插件已更新',
|
||
'admin.plugins.sig.title': '无法验证“{name}”的签名',
|
||
'admin.plugins.sig.keyChangedBody':
|
||
'作者的签名密钥不是安装此插件时所用的那把。作者确实会轮换密钥 —— 但接管了该插件的攻击者,看上去也会与此一模一样。',
|
||
'admin.plugins.sig.invalidBody':
|
||
'这些文件与作者的签名不符。它们不是作者签署的内容 —— 要么已损坏,要么被篡改。此项无法忽略。',
|
||
'admin.plugins.sig.missingBody':
|
||
'你安装此插件时它是有签名的,但新版本未附带任何签名。TREK 不会悄然接受这种降级。此项无法忽略。',
|
||
'admin.plugins.sig.incompleteBody':
|
||
'插件库中的条目只签了一半:它声明了作者密钥,但该版本没有签名(或反之)。这是插件一方的疏漏。此项无法忽略。',
|
||
'admin.plugins.sig.pinnedKey': '安装时使用的密钥',
|
||
'admin.plugins.sig.newKey': '它现在提供的密钥',
|
||
'admin.plugins.sig.confirmOutOfBand':
|
||
'TREK 无法区分正当的密钥轮换与一次接管 —— 从这里看,两者别无二致。在接受之前,请通过你原本就信任的渠道向作者核实这把新密钥。核实并接受后,插件将被更新,新密钥也会被记住。',
|
||
'admin.plugins.sig.retrustConfirm': '信任新密钥并更新',
|
||
'admin.plugins.sig.cancel': '不信任',
|
||
'admin.plugins.sig.consentUnsigned':
|
||
'没有任何东西能把这个版本与它的作者关联起来 —— 文件与插件库一致,但不带作者签名。',
|
||
'admin.plugins.security.trustTitle': '归根结底',
|
||
'admin.plugins.security.trustBody':
|
||
'安装插件就如同安装任何第三方应用:只添加来自你信任的作者的代码,如有疑虑,请先自行检查。TREK 对第三方插件不承担任何责任。',
|
||
'admin.plugins.runtimeOn': '运行时已开启',
|
||
'admin.plugins.tabDiscover': '发现',
|
||
'admin.plugins.searchPlaceholder': '搜索插件…',
|
||
'admin.plugins.filterType': '类型',
|
||
'admin.plugins.filterStatus': '状态',
|
||
'admin.plugins.sortBy': '排序',
|
||
'admin.plugins.allTypes': '全部类型',
|
||
'admin.plugins.allStatuses': '全部',
|
||
'admin.plugins.stateOff': '已关闭',
|
||
'admin.plugins.filterUpdate': '有可用更新',
|
||
'admin.plugins.sortName': '名称',
|
||
'admin.plugins.sortRecent': '最近更新',
|
||
'admin.plugins.sortUpdates': '优先显示有更新的',
|
||
'admin.plugins.sortDownloads': '下载最多',
|
||
'admin.plugins.updatesAvailable': '你的插件有 {count} 个可用更新。',
|
||
'admin.plugins.updateAll': '全部更新',
|
||
'admin.plugins.noMatchInstalled': '没有已安装的插件与你的搜索匹配。',
|
||
'admin.plugins.noMatchRegistry': '插件库中没有与你的搜索匹配的插件。',
|
||
'admin.plugins.restart': '重启',
|
||
'admin.plugins.restarted': '插件已重启',
|
||
'admin.plugins.cap.readsTrips': '读取你的旅行',
|
||
'admin.plugins.cap.readsUsers': '读取基本个人资料',
|
||
'admin.plugins.cap.readsCosts': '读取你的支出',
|
||
'admin.plugins.cap.readsPacking': '读取行李清单',
|
||
'admin.plugins.cap.readsFiles': '读取旅行文件',
|
||
'admin.plugins.cap.writesCosts': '添加支出',
|
||
'admin.plugins.cap.writesPlaces': '编辑地点',
|
||
'admin.plugins.cap.writesDays': '编辑行程日',
|
||
'admin.plugins.cap.writesItinerary': '编辑行程',
|
||
'admin.plugins.cap.writesTrips': '编辑旅行',
|
||
'admin.plugins.cap.metadata': '添加元数据',
|
||
'admin.plugins.cap.widget': '仪表盘小组件',
|
||
'admin.plugins.cap.heroWidget': '登机牌小组件',
|
||
'admin.plugins.cap.placeSlot': '地点详情',
|
||
'admin.plugins.cap.daySlot': '日程详情',
|
||
'admin.plugins.cap.reservationSlot': '预订详情',
|
||
'admin.plugins.cap.replacesTabs': '替换行程规划标签页',
|
||
'admin.plugins.cap.realtime': '实时更新',
|
||
'admin.plugins.cap.notificationChannel': '通知渠道',
|
||
'admin.plugins.cap.photos': '提供照片',
|
||
'admin.plugins.cap.calendar': '提供日历事件',
|
||
'admin.plugins.cap.placeDetails': '丰富地点信息',
|
||
'admin.plugins.cap.warnings': '标记问题',
|
||
'admin.plugins.cap.mapLayers': '在地图上绘制',
|
||
'admin.plugins.cap.routing': '提供路线规划',
|
||
'admin.plugins.cap.daySchedule': '补充计划时间',
|
||
'admin.plugins.cap.dayTint': '为日期着色',
|
||
'admin.plugins.cap.geolocation': '读取你的位置',
|
||
'admin.plugins.cap.events': '响应活动',
|
||
'admin.plugins.cap.requiresAddon': '需要 {addon}',
|
||
'admin.plugins.cap.dependsOn': '需要 {id} {version}',
|
||
'admin.plugins.dep.addonDisabledToast': '请先启用所需的插件模块:{addons}',
|
||
'admin.plugins.dep.autoEnabled': '已先启用所需的插件:{plugins}',
|
||
'admin.plugins.dep.downloaded': '已下载 {id}',
|
||
'admin.plugins.dep.resolveTitle': '缺少依赖项',
|
||
'admin.plugins.dep.resolveBody': '“{name}” 需要先安装这些插件才能启用。',
|
||
'admin.plugins.dep.requires': '需要 {version}',
|
||
'admin.plugins.dep.mismatch': '需要 {wanted} — 已安装 {installed}',
|
||
'admin.plugins.dep.download': '下载',
|
||
'admin.plugins.dep.update': '更新',
|
||
'admin.plugins.dep.resolveHint': '下载最新的兼容版本,包括其自身的依赖项。',
|
||
'admin.plugins.dep.trekIncompatible': '需要 TREK {range}——此服务器运行的是 {host}',
|
||
'admin.plugins.dep.trekUnknown': '未声明支持的 TREK 版本',
|
||
'admin.plugins.installCompatible': '安装 {version}',
|
||
'admin.plugins.incompatible': '不兼容',
|
||
'admin.plugins.accessTitle': '可访问的内容',
|
||
'admin.plugins.connectsTitle': '连接到',
|
||
'admin.plugins.detailsTitle': '详情',
|
||
'admin.plugins.noAccess': '无需任何特殊访问权限。',
|
||
'admin.plugins.metaVersion': '版本',
|
||
'admin.plugins.metaSize': '大小',
|
||
'admin.plugins.metaRequires': '需要',
|
||
'admin.plugins.metaReviewed': '审核于',
|
||
'admin.plugins.downloads': '下载次数',
|
||
'admin.addons.title': '扩展',
|
||
'admin.addons.subtitle': '启用或禁用功能以自定义你的 TREK 体验。',
|
||
'admin.addons.catalog.memories.name': '照片 (Immich)',
|
||
'admin.addons.catalog.memories.description': '通过 Immich 实例分享旅行照片',
|
||
'admin.addons.catalog.mcp.name': 'MCP',
|
||
'admin.addons.catalog.mcp.description': '用于 AI 助手集成的模型上下文协议',
|
||
'admin.addons.catalog.packing.name': '列表',
|
||
'admin.addons.catalog.packing.description': '行程打包清单与待办任务',
|
||
'admin.addons.catalog.budget.name': '费用',
|
||
'admin.addons.catalog.budget.description': '跟踪支出并规划旅行预算',
|
||
'admin.addons.catalog.documents.name': '文档',
|
||
'admin.addons.catalog.documents.description': '存储和管理旅行文档',
|
||
'admin.addons.catalog.vacay.name': '假期',
|
||
'admin.addons.catalog.vacay.description': '带日历视图的个人假期规划器',
|
||
'admin.addons.catalog.atlas.name': '足迹',
|
||
'admin.addons.catalog.atlas.description': '标记已访问国家和旅行统计的世界地图',
|
||
'admin.addons.catalog.collab.name': '协作',
|
||
'admin.addons.catalog.collab.description': '旅行规划的实时笔记、投票和聊天',
|
||
'admin.addons.subtitleBefore': '启用或禁用功能以自定义你的 ',
|
||
'admin.addons.subtitleAfter': ' 体验。',
|
||
'admin.addons.enabled': '已启用',
|
||
'admin.addons.disabled': '已禁用',
|
||
'admin.addons.type.trip': '旅行',
|
||
'admin.addons.type.global': '全局',
|
||
'admin.addons.type.integration': '集成',
|
||
'admin.addons.tripHint': '在每次旅行中作为标签页显示',
|
||
'admin.addons.globalHint': '在主导航中作为独立板块显示',
|
||
'admin.addons.integrationHint': '后端服务和 API 集成,无专属页面',
|
||
'admin.addons.toast.updated': '扩展已更新',
|
||
'admin.addons.toast.error': '更新扩展失败',
|
||
'admin.addons.noAddons': '暂无可用扩展',
|
||
'admin.weather.title': '天气数据',
|
||
'admin.weather.badge': '自 2026 年 3 月 24 日起',
|
||
'admin.weather.description': 'TREK 使用 Open-Meteo 作为天气数据源。Open-Meteo 是免费的开源天气服务——无需 API 密钥。',
|
||
'admin.weather.forecast': '16 天天气预报',
|
||
'admin.weather.forecastDesc': '之前为 5 天 (OpenWeatherMap)',
|
||
'admin.weather.climate': '历史气候数据',
|
||
'admin.weather.climateDesc': '16 天预报之外的日期使用过去 85 年的平均值',
|
||
'admin.weather.requests': '每天 10,000 次请求',
|
||
'admin.weather.requestsDesc': '免费,无需 API 密钥',
|
||
'admin.weather.locationHint':
|
||
'天气基于每天中第一个有坐标的地点。如果当天没有分配地点,则使用地点列表中的任意地点作为参考。',
|
||
'admin.tabs.mcpTokens': 'MCP 访问',
|
||
'admin.mcpTokens.title': 'MCP 访问',
|
||
'admin.mcpTokens.subtitle': '管理所有用户的 OAuth 会话和 API 令牌',
|
||
'admin.mcpTokens.sectionTitle': 'API 令牌',
|
||
'admin.mcpTokens.owner': '所有者',
|
||
'admin.mcpTokens.tokenName': '令牌名称',
|
||
'admin.mcpTokens.created': '创建时间',
|
||
'admin.mcpTokens.lastUsed': '最后使用',
|
||
'admin.mcpTokens.never': '从未',
|
||
'admin.mcpTokens.empty': '尚未创建任何 MCP 令牌',
|
||
'admin.mcpTokens.deleteTitle': '删除令牌',
|
||
'admin.mcpTokens.deleteMessage': '此令牌将立即被撤销。用户将失去通过此令牌的 MCP 访问权限。',
|
||
'admin.mcpTokens.deleteSuccess': '令牌已删除',
|
||
'admin.mcpTokens.deleteError': '删除令牌失败',
|
||
'admin.mcpTokens.loadError': '加载令牌失败',
|
||
'admin.oauthSessions.sectionTitle': 'OAuth 会话',
|
||
'admin.oauthSessions.clientName': '客户端',
|
||
'admin.oauthSessions.owner': '所有者',
|
||
'admin.oauthSessions.scopes': '权限范围',
|
||
'admin.oauthSessions.created': '创建时间',
|
||
'admin.oauthSessions.empty': '暂无活跃的 OAuth 会话',
|
||
'admin.oauthSessions.revokeTitle': '撤销会话',
|
||
'admin.oauthSessions.revokeMessage': '此 OAuth 会话将立即被撤销。客户端将失去 MCP 访问权限。',
|
||
'admin.oauthSessions.revokeSuccess': '会话已撤销',
|
||
'admin.oauthSessions.revokeError': '撤销会话失败',
|
||
'admin.oauthSessions.loadError': '加载 OAuth 会话失败',
|
||
'admin.tabs.github': 'GitHub',
|
||
'admin.audit.subtitle': '安全与管理员操作记录(备份、用户、MFA、设置)。',
|
||
'admin.audit.empty': '暂无审计记录。',
|
||
'admin.audit.refresh': '刷新',
|
||
'admin.audit.loadMore': '加载更多',
|
||
'admin.audit.showing': '已加载 {count} 条 · 共 {total} 条',
|
||
'admin.audit.col.time': '时间',
|
||
'admin.audit.col.user': '用户',
|
||
'admin.audit.col.action': '操作',
|
||
'admin.audit.col.resource': '资源',
|
||
'admin.audit.col.ip': 'IP',
|
||
'admin.audit.col.details': '详情',
|
||
'admin.github.title': '版本历史',
|
||
'admin.github.subtitle': '{repo} 的最新更新',
|
||
'admin.github.latest': '最新',
|
||
'admin.github.prerelease': '预发布',
|
||
'admin.github.showDetails': '显示详情',
|
||
'admin.github.hideDetails': '隐藏详情',
|
||
'admin.github.loadMore': '加载更多',
|
||
'admin.github.loading': '加载中...',
|
||
'admin.github.support': '帮助我继续开发 TREK',
|
||
'admin.github.error': '加载版本失败',
|
||
'admin.github.by': '作者',
|
||
'admin.update.available': '有可用更新',
|
||
'admin.update.text': 'TREK {version} 已发布。你当前使用的是 {current}。',
|
||
'admin.update.button': '在 GitHub 查看',
|
||
'admin.update.install': '安装更新',
|
||
'admin.update.confirmTitle': '确定安装更新?',
|
||
'admin.update.confirmText': 'TREK 将从 {current} 更新到 {version}。服务器将自动重启。',
|
||
'admin.update.dataInfo': '你的所有数据(旅行、用户、API 密钥、上传文件、假期、足迹、预算)将被保留。',
|
||
'admin.update.warning': '重启期间应用将短暂不可用。',
|
||
'admin.update.confirm': '立即更新',
|
||
'admin.update.installing': '更新中…',
|
||
'admin.update.success': '更新已安装!服务器正在重启…',
|
||
'admin.update.failed': '更新失败',
|
||
'admin.update.backupHint': '建议在更新前创建备份。',
|
||
'admin.update.backupLink': '前往备份',
|
||
'admin.update.howTo': '如何更新',
|
||
'admin.update.dockerText': '你的 TREK 实例运行在 Docker 中。要更新到 {version},请在服务器上执行以下命令:',
|
||
'admin.update.nonDockerText':
|
||
'此 TREK 实例未运行在 Docker 中。要更新到 {version},请重新执行你当初使用的安装或更新方式——例如,在 Proxmox Community Scripts 上,从 LXC 控制台运行更新:',
|
||
'admin.update.wikiLink': '打开更新指南',
|
||
'admin.update.reloadHint': '请在几秒后刷新页面。',
|
||
'admin.tabs.permissions': '权限',
|
||
'admin.notifications.emailPanel.title': '电子邮件(SMTP)',
|
||
'admin.notifications.webhookPanel.title': 'Webhook',
|
||
'admin.notifications.inappPanel.title': '应用内通知',
|
||
'admin.notifications.inappPanel.hint': '应用内通知始终处于活跃状态,无法全局禁用。',
|
||
'admin.notifications.adminWebhookPanel.title': '管理员 Webhook',
|
||
'admin.notifications.adminWebhookPanel.hint':
|
||
'此 Webhook 专用于管理员通知(如版本更新提醒)。它与用户 Webhook 相互独立,配置 URL 后自动触发。',
|
||
'admin.notifications.adminWebhookPanel.saved': '管理员 Webhook URL 已保存',
|
||
'admin.notifications.adminWebhookPanel.testSuccess': '测试 Webhook 发送成功',
|
||
'admin.notifications.adminWebhookPanel.testFailed': '测试 Webhook 失败',
|
||
'admin.notifications.adminWebhookPanel.alwaysOnHint': '配置 URL 后管理员 Webhook 自动触发',
|
||
'admin.notifications.ntfy': 'Ntfy',
|
||
'admin.ntfy.hint': '允许用户配置自己的 ntfy 主题以接收推送通知。在下方设置默认服务器以预填充用户设置。',
|
||
'admin.notifications.testNtfy': '发送测试 Ntfy',
|
||
'admin.notifications.testNtfySuccess': '测试 Ntfy 发送成功',
|
||
'admin.notifications.testNtfyFailed': '测试 Ntfy 失败',
|
||
'admin.notifications.adminNtfyPanel.title': '管理员 Ntfy',
|
||
'admin.notifications.adminNtfyPanel.hint':
|
||
'此 Ntfy 主题专用于管理员通知(如版本更新提醒)。它与每用户主题相互独立,配置后始终触发。',
|
||
'admin.notifications.adminNtfyPanel.serverLabel': 'Ntfy 服务器 URL',
|
||
'admin.notifications.adminNtfyPanel.serverHint':
|
||
'同时用作用户 ntfy 通知的默认服务器。留空则默认使用 ntfy.sh。用户可在其自己的设置中覆盖此项。',
|
||
'admin.notifications.adminNtfyPanel.serverPlaceholder': 'https://ntfy.sh',
|
||
'admin.notifications.adminNtfyPanel.topicLabel': '管理员主题',
|
||
'admin.notifications.adminNtfyPanel.topicPlaceholder': 'trek-admin-alerts',
|
||
'admin.notifications.adminNtfyPanel.tokenLabel': '访问令牌(可选)',
|
||
'admin.notifications.adminNtfyPanel.tokenCleared': '管理员访问令牌已清除',
|
||
'admin.notifications.adminNtfyPanel.saved': '管理员 Ntfy 设置已保存',
|
||
'admin.notifications.adminNtfyPanel.test': '发送测试 Ntfy',
|
||
'admin.notifications.adminNtfyPanel.testSuccess': '测试 Ntfy 发送成功',
|
||
'admin.notifications.adminNtfyPanel.testFailed': '测试 Ntfy 失败',
|
||
'admin.notifications.adminNtfyPanel.alwaysOnHint': '配置主题后管理员 Ntfy 始终触发',
|
||
'admin.notifications.adminNotificationsHint':
|
||
'配置哪些渠道发送管理员通知(如版本更新提醒)。设置管理员 Webhook URL 后,Webhook 将自动触发。',
|
||
'admin.notifications.tripReminders.title': '行程提醒',
|
||
'admin.notifications.tripReminders.hint': '在行程开始前发送提醒通知(需要在行程中设置提醒天数)。',
|
||
'admin.notifications.tripReminders.enabled': '行程提醒已启用',
|
||
'admin.notifications.tripReminders.disabled': '行程提醒已禁用',
|
||
'admin.tabs.notifications': '通知',
|
||
'admin.addons.catalog.journey.name': '旅程',
|
||
'admin.addons.catalog.journey.description': '旅行追踪与旅行日志,包含签到、照片和每日故事',
|
||
'admin.addons.catalog.collections.name': '收藏',
|
||
'admin.addons.catalog.collections.description':
|
||
'个人地点库 — 将各行程的地点保存到命名列表中,复制到任意行程,并与他人共享',
|
||
'admin.passkey.title': '通行密钥登录',
|
||
'admin.passkey.cardHint': '允许用户使用通行密钥(WebAuthn)登录。默认关闭。',
|
||
'admin.passkey.login': '启用通行密钥登录',
|
||
'admin.passkey.loginHint': '显示"使用通行密钥登录"选项,并允许用户在其设置中注册通行密钥。',
|
||
'admin.passkey.notConfigured':
|
||
'此部署尚未解析出有效的 WebAuthn 域名。请设置 APP_URL 或下方的 Relying Party ID——在此之前通行密钥将保持隐藏。',
|
||
'admin.passkey.rpId': 'Relying Party ID(域名)',
|
||
'admin.passkey.rpIdHint':
|
||
'通行密钥所绑定的纯域名,如 trek.example.org。留空则从 APP_URL 推导。之后更改将使现有通行密钥失效。',
|
||
'admin.passkey.origins': '允许的来源',
|
||
'admin.passkey.originsHint': '以逗号分隔的完整来源,如 https://trek.example.org。留空则使用 APP_URL。',
|
||
'admin.passkey.reset': '重置通行密钥',
|
||
'admin.passkey.resetHint': '移除该用户的所有通行密钥(如设备丢失时)。他们仍可使用密码登录。',
|
||
'admin.passkey.resetConfirm': '移除 {name} 的所有通行密钥?',
|
||
'admin.passkey.resetDone': '已移除 {count} 个通行密钥',
|
||
'admin.defaultSettings.mapProvider': '地图引擎',
|
||
'admin.defaultSettings.mapProviderHint': '本实例中所有用户的默认地图。每位用户仍可在自己的设置中更改此项。',
|
||
'admin.defaultSettings.providerLeaflet': '标准(免费)',
|
||
'admin.defaultSettings.providerMapbox': 'Mapbox(3D)',
|
||
'admin.defaultSettings.providerMapLibre': 'MapLibre (OpenFreeMap)',
|
||
'admin.defaultSettings.mapboxToken': '共享 Mapbox 令牌',
|
||
'admin.defaultSettings.mapboxTokenHint':
|
||
'用于所有未输入自己令牌的用户 — 这样无需逐个分享密钥,整个实例即可使用 Mapbox。以加密方式存储。',
|
||
'admin.defaultSettings.mapboxStyle': '地图样式',
|
||
'admin.defaultSettings.mapboxStylePlaceholder': '选择一种样式…',
|
||
'admin.defaultSettings.mapbox3d': '3D 建筑与地形',
|
||
'admin.defaultSettings.mapboxQuality': '高质量模式',
|
||
'admin.group.users': '用户',
|
||
'admin.group.config': '配置',
|
||
'admin.group.integration': '集成',
|
||
'admin.group.maintenance': '维护',
|
||
'admin.invite.tripLabel': '添加到行程(可选)',
|
||
'admin.invite.tripNone': '不选择行程',
|
||
'admin.invite.tripHint': '新用户通过链接注册时会自动加入此行程。',
|
||
'admin.invite.boundTo': '加入 {trip}',
|
||
};
|
||
export default admin;
|