From 5f7ed2ffe98d9b982e31ea82db62b58d30a575a1 Mon Sep 17 00:00:00 2001 From: wizardchen Date: Mon, 22 Jun 2026 15:19:47 +0800 Subject: [PATCH] feat(i18n): add key descriptions for various settings in multiple languages - Introduce detailed descriptions for authentication, SSRF protection, tenant management, and async task worker settings in English, Korean, Russian, and Chinese localization files. - Enhance user understanding of configuration options by providing context-sensitive help directly within the settings interface. - Update the Settings and SystemSettings components to utilize these new descriptions for improved user experience. --- frontend/src/i18n/locales/en-US.ts | 23 ++++++++++++++++ frontend/src/i18n/locales/ko-KR.ts | 22 +++++++++++++++ frontend/src/i18n/locales/ru-RU.ts | 22 +++++++++++++++ frontend/src/i18n/locales/zh-CN.ts | 29 ++++++++++++++++++++ frontend/src/views/settings/Settings.vue | 2 +- frontend/src/views/system/SystemSettings.vue | 10 ++++++- 6 files changed, 106 insertions(+), 2 deletions(-) diff --git a/frontend/src/i18n/locales/en-US.ts b/frontend/src/i18n/locales/en-US.ts index 79e084ec..f9f0541f 100755 --- a/frontend/src/i18n/locales/en-US.ts +++ b/frontend/src/i18n/locales/en-US.ts @@ -1220,6 +1220,7 @@ export default { addModelsSuccess: 'Successfully added {count} model(s)', addModelsPartial: 'Added {success}, {failed} failed', addModelsFailed: 'Failed to add models', + addModelsAllExist: 'All four model types already exist', addModelsEmbeddingFailed: 'Embedding connection test failed; could not detect vector dimension', addModelsDisplayName: { chat: 'WeKnoraCloud Chat', @@ -3385,6 +3386,26 @@ export default { concurrency: 'Async task worker concurrency', }, }, + keyDescriptions: { + auth: { + registration_mode: + 'Self-service registration mode. self_serve = anyone can register an account; invite_only = public registration is disabled and only Owners/Admins can invite. Takes effect immediately after saving, but use self_serve with care (the public internet will send spam sign-ups).', + }, + ssrf: { + whitelist: + 'SSRF protection allowlist. Accepts entries such as example.com / *.foo.com / 10.0.0.0/8 / 2001:db8::1. Takes effect immediately after saving. The SSRF_WHITELIST_EXTRA environment variable is still maintained by the deployer and is not overridden here.', + }, + tenant: { + max_owned_per_user: + 'Maximum number of tenants a non-superuser may own via self-service creation. Read on every tenant creation and takes effect immediately after saving. 0 uses the built-in default of 10; a negative value disables the cap entirely (not recommended on public deployments).', + default_storage_quota_gb: + 'Default storage quota (GB) assigned when a new tenant is created, covering vectors, originals, text, indexes, and related data. Read only at creation time — changes apply to newly created tenants only and do not retroactively update existing tenants. 0 or a negative value uses the built-in default of 10 GB.', + }, + asynq: { + concurrency: + 'Async task worker concurrency (asynq thread-pool size). Document parsing, embedding, and similar tasks are mostly I/O-bound, so raising this value can shorten queue time for bulk uploads. Requires a service process restart to take effect.', + }, + }, enumLabels: { auth: { registration_mode: { @@ -4830,6 +4851,8 @@ export default { fileTypeWord: 'Word Documents', fileTypePpt: 'Presentations', fileTypeExcel: 'Excel Spreadsheets', + fileTypeEbook: 'E-books', + fileTypeWebArchive: 'Web Archives', fileTypeCsv: 'CSV Files', fileTypeText: 'Plain Text', fileTypeJson: 'JSON Files', diff --git a/frontend/src/i18n/locales/ko-KR.ts b/frontend/src/i18n/locales/ko-KR.ts index afc562a2..444e60f2 100755 --- a/frontend/src/i18n/locales/ko-KR.ts +++ b/frontend/src/i18n/locales/ko-KR.ts @@ -2407,6 +2407,26 @@ export default { concurrency: "비동기 작업 워커 동시 처리 수", }, }, + keyDescriptions: { + auth: { + registration_mode: + "셀프 가입 모드입니다. self_serve = 누구나 계정을 만들 수 있음; invite_only = 공개 가입을 끄고 Owner/Admin만 초대 가능. 저장 즉시 적용되며, self_serve는 스팸 가입이 들어올 수 있으니 신중히 사용하세요.", + }, + ssrf: { + whitelist: + "SSRF 보호 허용 목록입니다. example.com / *.foo.com / 10.0.0.0/8 / 2001:db8::1 형식을 입력할 수 있습니다. 저장 즉시 적용됩니다. SSRF_WHITELIST_EXTRA 환경 변수는 배포자가 관리하며 여기서 덮어쓰지 않습니다.", + }, + tenant: { + max_owned_per_user: + "슈퍼유저가 아닌 사용자가 셀프 서비스로 소유할 수 있는 최대 테넌트 수입니다. 테넌트 생성 시마다 읽으며 저장 즉시 적용됩니다. 0은 내장 기본값 10을 사용하고, 음수는 제한을 완전히 해제합니다(공개 배포에는 권장하지 않음).", + default_storage_quota_gb: + "신규 테넌트 생성 시 기본으로 할당되는 저장 용량(GB)으로, 벡터·원본·텍스트·인덱스 등을 포함합니다. 생성 시에만 읽으며, 변경은 이후 생성되는 테넌트에만 적용되고 기존 테넌트에는 소급되지 않습니다. 0 또는 음수는 내장 기본값 10GB를 사용합니다.", + }, + asynq: { + concurrency: + "비동기 작업 worker 동시 처리 수(asynq 스레드 풀 크기)입니다. 문서 파싱·임베딩 등은 대부분 I/O 대기이므로 값을 올리면 대량 업로드 대기 시간을 줄일 수 있습니다. 적용하려면 서비스 프로세스를 재시작해야 합니다.", + }, + }, enumLabels: { auth: { registration_mode: { @@ -4848,6 +4868,8 @@ export default { fileTypeWord: 'Word 문서', fileTypePpt: '프레젠테이션', fileTypeExcel: 'Excel 스프레드시트', + fileTypeEbook: '전자책', + fileTypeWebArchive: '웹 아카이브', fileTypeCsv: 'CSV 파일', fileTypeText: '일반 텍스트', fileTypeJson: 'JSON 파일', diff --git a/frontend/src/i18n/locales/ru-RU.ts b/frontend/src/i18n/locales/ru-RU.ts index 299be0a6..cab8402f 100755 --- a/frontend/src/i18n/locales/ru-RU.ts +++ b/frontend/src/i18n/locales/ru-RU.ts @@ -2123,6 +2123,26 @@ export default { concurrency: 'Параллелизм воркеров асинхронных задач', }, }, + keyDescriptions: { + auth: { + registration_mode: + 'Режим самостоятельной регистрации. self_serve = любой может создать аккаунт; invite_only = открытая регистрация отключена, приглашать могут только Owner/Admin. Вступает в силу сразу после сохранения; используйте self_serve осторожно (в публичном интернете появятся спам-регистрации).', + }, + ssrf: { + whitelist: + 'Белый список SSRF-защиты. Можно указать example.com / *.foo.com / 10.0.0.0/8 / 2001:db8::1. Вступает в силу сразу после сохранения. Переменная окружения SSRF_WHITELIST_EXTRA по-прежнему задаётся при развёртывании и здесь не переопределяется.', + }, + tenant: { + max_owned_per_user: + 'Максимальное число тенантов, которыми может владеть обычный (не супер) пользователь через самостоятельное создание. Читается при каждом создании тенанта и вступает в силу сразу после сохранения. 0 — встроенное значение по умолчанию 10; отрицательное значение полностью снимает ограничение (не рекомендуется для публичных развёртываний).', + default_storage_quota_gb: + 'Квота хранилища по умолчанию (ГБ) для нового тенанта: векторы, оригиналы, текст, индексы и т.д. Читается только при создании — изменения применяются только к новым тенантам и не перезаписывают существующие. 0 или отрицательное значение — встроенное значение по умолчанию 10 ГБ.', + }, + asynq: { + concurrency: + 'Параллелизм воркеров асинхронных задач (размер пула потоков asynq). Парсинг документов, эмбеддинги и подобные задачи в основном ждут I/O, поэтому увеличение значения сокращает очередь при массовой загрузке. Для применения требуется перезапуск процесса сервиса.', + }, + }, enumLabels: { auth: { registration_mode: { @@ -4348,6 +4368,8 @@ export default { fileTypeWord: 'Документы Word', fileTypePpt: 'Презентации', fileTypeExcel: 'Таблицы Excel', + fileTypeEbook: 'Электронные книги', + fileTypeWebArchive: 'Веб-архивы', fileTypeCsv: 'Файлы CSV', fileTypeText: 'Текстовые файлы', fileTypeJson: 'Файлы JSON', diff --git a/frontend/src/i18n/locales/zh-CN.ts b/frontend/src/i18n/locales/zh-CN.ts index 92015c6e..67ddd2d1 100755 --- a/frontend/src/i18n/locales/zh-CN.ts +++ b/frontend/src/i18n/locales/zh-CN.ts @@ -2410,6 +2410,33 @@ export default { concurrency: "异步任务并发数", }, }, + keyDescriptions: { + auth: { + registration_mode: + "自助注册模式。self_serve = 任何人可注册账号;invite_only = 关闭公网注册," + + "仅 Owner/Admin 可邀请。修改后立即生效,但谨慎对待 self_serve(公网会接受 spam)。", + }, + ssrf: { + whitelist: + "SSRF 防护白名单。可填入 example.com / *.foo.com / 10.0.0.0/8 / 2001:db8::1。" + + "修改后立即生效。SSRF_WHITELIST_EXTRA 环境变量仍由部署方维护,不在此处覆盖。", + }, + tenant: { + max_owned_per_user: + "每个非超管用户通过自助创建可拥有的最大租户数。每次创建租户时实时读取," + + "修改后立即生效。0 表示使用内置默认值 10;负数表示完全关闭限制(不建议在公开部署使用)。", + default_storage_quota_gb: + "新建租户时默认分配的存储配额(GB),包含向量、原文、文本、索引等。" + + "仅在创建时读取,修改后只对之后新建的租户生效,不会回写已存在的租户。" + + "0 或负数表示使用内置默认值 10GB。", + }, + asynq: { + concurrency: + "异步任务 worker 并发数(asynq 线程池大小)。" + + "文档解析、嵌入等任务多为 I/O 等待,适当提高可缩短批量上传排队时间。" + + "修改后需重启服务进程方可生效。", + }, + }, enumLabels: { auth: { registration_mode: { @@ -4824,6 +4851,8 @@ export default { fileTypeWord: "Word 文档", fileTypePpt: "演示文稿", fileTypeExcel: "Excel 表格", + fileTypeEbook: "电子书", + fileTypeWebArchive: "网页归档", fileTypeCsv: "CSV 文件", fileTypeText: "纯文本", fileTypeJson: "JSON 文件", diff --git a/frontend/src/views/settings/Settings.vue b/frontend/src/views/settings/Settings.vue index bb9162dd..54d32b42 100644 --- a/frontend/src/views/settings/Settings.vue +++ b/frontend/src/views/settings/Settings.vue @@ -282,7 +282,7 @@ const navItems = computed(() => { { key: 'storage', icon: 'cloud', label: t('settings.storageEngine') }, { key: 'mcp', icon: 'tools', label: t('settings.mcpService') }, { key: 'system', icon: 'info-circle', label: t('settings.versionInfo') }, - { key: 'system-global', icon: 'server', label: '系统设置' }, + { key: 'system-global', icon: 'server', label: t('settings.system') }, { key: 'userprofile', icon: 'user', label: t('userProfile.title') }, { key: 'tenant', icon: 'user-circle', label: t('settings.tenantInfo') }, { key: 'members', icon: 'usergroup', label: t('tenantMember.title') }, diff --git a/frontend/src/views/system/SystemSettings.vue b/frontend/src/views/system/SystemSettings.vue index a669f706..1e08c470 100644 --- a/frontend/src/views/system/SystemSettings.vue +++ b/frontend/src/views/system/SystemSettings.vue @@ -173,7 +173,7 @@ :title="t('system.globalSettings.badgeOverrideTooltip')" >{{ t('system.globalSettings.badgeOverride') }} -

{{ item.description }}

+

{{ settingDescription(item) }}

{{ t('system.globalSettings.modifiedAt', { value: modifiedMeta(item) }) }}
@@ -528,6 +528,14 @@ function keyLabel(k: string): string { return te(path) ? (t(path) as string) : k } +// Descriptions are registered in Chinese on the backend for operator docs; +// user-facing copy lives in i18n (system.globalSettings.keyDescriptions.*). +function settingDescription(item: { key: string; description?: string }): string { + const path = `system.globalSettings.keyDescriptions.${item.key}` + if (te(path)) return t(path) as string + return item.description ?? '' +} + // Enum keys whose change triggers a whole-value inline popconfirm before // PUT. ssrf.whitelist is not here — it uses per-tag confirm instead. const HIGH_RISK_KEYS = new Set([