@liujitcn/kratos-taro-app-core 0.0.20 → 0.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/build.mjs +3 -3
  2. package/dist/runner.mjs +11 -1
  3. package/package.json +1 -1
  4. package/src/api/base/file.ts +9 -4
  5. package/src/api/base/language.ts +21 -0
  6. package/src/bootstrap.ts +15 -1
  7. package/src/components/BootstrapStatus.tsx +3 -1
  8. package/src/components/KratosPageFrame.tsx +3 -1
  9. package/src/index.ts +4 -0
  10. package/src/locales/README.md +15 -0
  11. package/src/locales/en-US.json +108 -0
  12. package/src/locales/es-ES.json +108 -0
  13. package/src/locales/fr-FR.json +108 -0
  14. package/src/locales/generated.ts +22 -0
  15. package/src/locales/index.ts +214 -0
  16. package/src/locales/ja-JP.json +108 -0
  17. package/src/locales/ko-KR.json +108 -0
  18. package/src/locales/zh-CN.json +108 -0
  19. package/src/locales/zh-TW.json +108 -0
  20. package/src/module.ts +5 -1
  21. package/src/navigation.ts +48 -23
  22. package/src/pages.ts +3 -3
  23. package/src/rpc/base/v1/config.ts +14 -1
  24. package/src/rpc/base/v1/language.ts +31 -0
  25. package/src/rpc/base/v1/login.ts +14 -1
  26. package/src/runner.ts +11 -1
  27. package/src/stores/setting.ts +11 -6
  28. package/src/utils/file.ts +7 -2
  29. package/src/utils/http.ts +31 -12
  30. package/src/utils/index.ts +1 -1
  31. package/src/utils/passwordCrypto.ts +14 -13
  32. package/src/views/pages/index/index.tsx +13 -11
  33. package/src/views/pages/login/login.scss +24 -3
  34. package/src/views/pages/login/login.tsx +74 -50
  35. package/src/views/pages/login/protocal.tsx +5 -3
  36. package/src/views/pages/status/index.tsx +4 -10
  37. package/src/views/pages/webview/webview.tsx +6 -4
  38. package/src/rpc/base/v1/enum.ts +0 -54
  39. package/src/rpc/system/common/v1/enum.ts +0 -80
package/dist/build.mjs CHANGED
@@ -8,11 +8,11 @@ var corePages = {
8
8
  style: {
9
9
  navigationStyle: "custom",
10
10
  navigationBarTextStyle: "white",
11
- navigationBarTitleText: "\u9996\u9875"
11
+ navigationBarTitleText: ""
12
12
  }
13
13
  },
14
- "pages/login/login": { style: { navigationBarTitleText: "\u767B\u5F55" } },
15
- "pages/login/protocal": { style: { navigationBarTitleText: "\u534F\u8BAE\u8BE6\u60C5" } },
14
+ "pages/login/login": { style: { navigationBarTitleText: "" } },
15
+ "pages/login/protocal": { style: { navigationBarTitleText: "" } },
16
16
  "pages/webview/webview": { style: { navigationBarTitleText: "" } },
17
17
  "pages/status/index": {
18
18
  style: {
package/dist/runner.mjs CHANGED
@@ -67,7 +67,17 @@ async function main() {
67
67
  process.once("SIGINT", () => handleSignal("SIGINT"));
68
68
  process.once("SIGTERM", () => handleSignal("SIGTERM"));
69
69
  try {
70
- const args = ["exec", "taro", "build", "--type", options.type, "--mode", options.mode];
70
+ const args = [
71
+ "exec",
72
+ "taro",
73
+ "build",
74
+ "--type",
75
+ options.type,
76
+ "--mode",
77
+ options.mode,
78
+ "--env-prefix",
79
+ "VITE_APP_,TARO_APP_"
80
+ ];
71
81
  if (options.watch) args.push("--watch");
72
82
  child = spawn(process.platform === "win32" ? "pnpm.cmd" : "pnpm", args, {
73
83
  cwd: hostRoot,
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "type": "git",
8
8
  "url": "git@github.com:liujitcn/kratos-admin.git"
9
9
  },
10
- "version": "0.0.20",
10
+ "version": "0.0.23",
11
11
  "type": "module",
12
12
  "files": [
13
13
  "dist",
@@ -5,6 +5,7 @@ import type {
5
5
  MultiUploadFileResponse,
6
6
  } from '../../rpc/base/v1/file'
7
7
  import { uploadFile, uploadFileList } from '../../utils/file'
8
+ import { getLocaleRequestHeaders, t } from '../../locales'
8
9
  import { getRequestAccessToken, requestBaseURL } from '../../utils/http'
9
10
 
10
11
  const FILE_URL = '/v1/base/file'
@@ -14,7 +15,7 @@ export class FileServiceImpl {
14
15
  /** 上传多个浏览器文件。 */
15
16
  async MultiUploadFile(files: File[], fileType: string): Promise<MultiUploadFileResponse> {
16
17
  if (process.env.TARO_ENV !== 'h5') {
17
- throw new Error('小程序端请使用文件临时路径上传')
18
+ throw new Error(t('core.file.temporary_path_required'))
18
19
  }
19
20
  const paths = files.map((file) => URL.createObjectURL(file))
20
21
  try {
@@ -27,7 +28,7 @@ export class FileServiceImpl {
27
28
  /** 上传单个浏览器文件。 */
28
29
  async UploadFile(file: File, fileType: string): Promise<FileInfo> {
29
30
  if (process.env.TARO_ENV !== 'h5') {
30
- throw new Error('小程序端请使用文件临时路径上传')
31
+ throw new Error(t('core.file.temporary_path_required'))
31
32
  }
32
33
  const path = URL.createObjectURL(file)
33
34
  try {
@@ -46,9 +47,13 @@ export class FileServiceImpl {
46
47
  const token = await getRequestAccessToken()
47
48
  const response = await Taro.downloadFile({
48
49
  url: `${requestBaseURL}${FILE_URL}?${query}`,
49
- header: { Authorization: token, 'source-client': 'miniapp' },
50
+ header: {
51
+ ...getLocaleRequestHeaders(),
52
+ Authorization: token,
53
+ 'source-client': 'miniapp',
54
+ },
50
55
  })
51
- if (response.statusCode !== 200) throw new Error('下载失败')
56
+ if (response.statusCode !== 200) throw new Error(t('core.file.download_failed'))
52
57
  await Taro.openDocument({ filePath: response.tempFilePath, showMenu: true })
53
58
  }
54
59
  }
@@ -0,0 +1,21 @@
1
+ import { http } from '../../utils/http'
2
+ import type { LanguageService, OptionLanguageRequest, OptionLanguageResponse } from '../../rpc/base/v1/language'
3
+
4
+ const LANGUAGE_URL = '/v1/base/language'
5
+
6
+ /** 语言公共服务。 */
7
+ export class LanguageServiceImpl implements LanguageService {
8
+ /** 查询当前支持的语言选项。 */
9
+ OptionLanguage(request: OptionLanguageRequest): Promise<OptionLanguageResponse> {
10
+ return http<OptionLanguageResponse>({
11
+ url: LANGUAGE_URL,
12
+ method: 'GET',
13
+ authMode: 'none',
14
+ data: request,
15
+ header: { Authorization: 'no-auth' },
16
+ })
17
+ }
18
+ }
19
+
20
+ /** 主语言公共服务。 */
21
+ export const defLanguageService = new LanguageServiceImpl()
package/src/bootstrap.ts CHANGED
@@ -7,7 +7,9 @@ import {
7
7
  registerUserStoreExtension,
8
8
  startUserStoreEventBridge,
9
9
  useUserStore,
10
- } from './stores'
10
+ useSettingStore } from './stores'
11
+ import { applyLanguageConfig, initializeLocale, registerLocaleChangeHandler, registerLocaleMessages } from './locales'
12
+ import { defLanguageService } from './api/base/language'
11
13
 
12
14
  /** Taro 应用启动参数。 */
13
15
  export interface KratosTaroBootstrapOptions {
@@ -20,8 +22,20 @@ let bootstrapped = false
20
22
  /** 注册模块、认证生命周期和导航运行时。 */
21
23
  export function bootstrapKratosTaroApp(options: KratosTaroBootstrapOptions): void {
22
24
  registerKratosTaroModules(options.modules)
25
+ registerLocaleMessages(options.modules)
26
+ initializeLocale()
27
+ void defLanguageService
28
+ .OptionLanguage({})
29
+ .then((response) => {
30
+ applyLanguageConfig(response)
31
+ })
32
+ .catch(() => {
33
+ // 语言公共接口失败时继续使用静态语言包和系统语言。
34
+ })
23
35
  if (bootstrapped) return
24
36
  bootstrapped = true
37
+ registerLocaleChangeHandler(initializeAppNavigation)
38
+ registerLocaleChangeHandler(() => useSettingStore.getState().loadData())
25
39
  startUserStoreEventBridge()
26
40
  registerUserStoreExtension({
27
41
  onLogin: initializeAppNavigation,
@@ -1,5 +1,6 @@
1
1
  import { Image, Text, View } from '@tarojs/components'
2
2
  import './BootstrapStatus.scss'
3
+ import { useI18n } from '../locales'
3
4
 
4
5
  /** 启动状态组件参数。 */
5
6
  export interface BootstrapStatusProps {
@@ -9,6 +10,7 @@ export interface BootstrapStatusProps {
9
10
 
10
11
  /** 全屏启动状态。 */
11
12
  export function BootstrapStatus({ title, detail }: BootstrapStatusProps) {
13
+ const { t } = useI18n()
12
14
  return (
13
15
  <View className='bootstrap-status'>
14
16
  <Image
@@ -16,7 +18,7 @@ export function BootstrapStatus({ title, detail }: BootstrapStatusProps) {
16
18
  src='/static/images/logo_icon.png'
17
19
  mode='aspectFit'
18
20
  />
19
- <Text className='bootstrap-status__title'>{title || '正在加载'}</Text>
21
+ <Text className='bootstrap-status__title'>{title || t('core.status.loading')}</Text>
20
22
  {detail ? <Text className='bootstrap-status__detail'>{detail}</Text> : null}
21
23
  </View>
22
24
  )
@@ -1,6 +1,7 @@
1
1
  import { Text, View } from '@tarojs/components'
2
2
  import Taro from '@tarojs/taro'
3
3
  import type { ReactNode } from 'react'
4
+ import { useI18n } from '../locales'
4
5
  import { homeTabPage } from '../utils/navigation'
5
6
  import './KratosPageFrame.scss'
6
7
 
@@ -21,6 +22,7 @@ export function KratosPageFrame({
21
22
  navigationBarBackgroundColor,
22
23
  navigationBarTextStyle,
23
24
  }: KratosPageFrameProps) {
25
+ const { t } = useI18n()
24
26
  if (process.env.TARO_ENV !== 'h5' || navigationStyle === 'custom') return children
25
27
 
26
28
  const color = navigationBarTextStyle === 'white' ? '#fff' : '#000'
@@ -38,7 +40,7 @@ export function KratosPageFrame({
38
40
  className='kratos-page-frame__navigation'
39
41
  style={{ backgroundColor: navigationBarBackgroundColor, color }}
40
42
  >
41
- <View className='kratos-page-frame__back' aria-label='返回' onClick={() => void goBack()}>
43
+ <View className='kratos-page-frame__back' aria-label={t('common.action.back')} onClick={() => void goBack()}>
42
44
  <View className='kratos-page-frame__back-icon' />
43
45
  </View>
44
46
  <Text className='kratos-page-frame__title'>{navigationBarTitleText}</Text>
package/src/index.ts CHANGED
@@ -1,5 +1,7 @@
1
+ // Core 语言包由同步脚本生成并在本文件的 coreModule 中注册,供 Taro 公共页面、请求工具和业务模块复用。
1
2
  import { corePages } from './pages'
2
3
  import { defineKratosTaroModule } from './module'
4
+ import { LOCALE_MESSAGES } from './locales/generated'
3
5
 
4
6
  /** core 内置模块。 */
5
7
  export const coreModule = defineKratosTaroModule({
@@ -23,11 +25,13 @@ export const coreModule = defineKratosTaroModule({
23
25
  USER_DEFAULT: 'static/tabs/user_default.png',
24
26
  USER_SELECTED: 'static/tabs/user_selected.png',
25
27
  },
28
+ messages: LOCALE_MESSAGES,
26
29
  })
27
30
 
28
31
  export * from './module'
29
32
  export * from './bootstrap'
30
33
  export * from './navigation'
34
+ export * from './locales'
31
35
  export * from './stores'
32
36
  export * from './utils/auth'
33
37
  export * from './utils/file'
@@ -0,0 +1,15 @@
1
+ # Taro Core 语言包
2
+
3
+ 本目录提供 Taro 应用底座和公共页面使用的稳定文案,包括登录、启动状态、导航、认证、文件处理和网络错误提示。语言包由 `../index.ts` 的 `coreModule` 导入并注册,应用启动时由 `bootstrapKratosTaroApp` 调用 `registerLocaleMessages` 合并;页面、hooks、请求工具通过 `useI18n()` 或 `t()` 使用。
4
+
5
+ | 文件 | 用途 | 使用位置 |
6
+ | --- | --- | --- |
7
+ | `zh-CN.json` | 简体中文固定 UI 默认语言包,也是所有语言键集合和占位符校验基准。 | Taro 固定文案默认语言及缺失翻译回退。 |
8
+ | `zh-TW.json` | 繁体中文 Core 语言包。 | Taro 切换为繁体中文时使用。 |
9
+ | `en-US.json` | 英文 Core 语言包。 | Taro 切换为英文时使用。 |
10
+ | `ja-JP.json` | 日文 Core 语言包。 | Taro 切换为日文时使用。 |
11
+ | `ko-KR.json` | 韩语 Core 语言包。 | Taro 切换为韩语时使用。 |
12
+ | `fr-FR.json` | 法语 Core 语言包。 | Taro 切换为法语时使用。 |
13
+ | `es-ES.json` | 西班牙语 Core 语言包。 | Taro 切换为西班牙语时使用。 |
14
+
15
+ 语言包是标准 JSON,不能在文件内直接写注释;公共键使用 `common.` 或 `core.` 命名空间。新增语言后执行仓库根目录的 `make i18n-sync`。语言切换选项固定显示后端 `base_language.native_name`,接口不可用时使用代码内置的原生名称;`common.language.*` 仅用于普通文案和语言迁移初始数据。新增语言的完整文件清单见[国际化语言扩展指南](../../../../../../docs/国际化语言扩展指南.md)。
@@ -0,0 +1,108 @@
1
+ {
2
+ "common.action.back": "Back",
3
+ "common.action.cancel": "Cancel",
4
+ "common.action.confirm": "Confirm",
5
+ "common.action.delete": "Delete",
6
+ "common.action.login": "Log in",
7
+ "common.action.logout": "Log out",
8
+ "common.action.new": "New",
9
+ "common.action.open_in_new_window": "Open in new window",
10
+ "common.action.save": "Save",
11
+ "common.field.language": "Language",
12
+ "common.language.en-US": "English",
13
+ "common.language.ja-JP": "日本語",
14
+ "common.language.zh-CN": "简体中文",
15
+ "common.language.zh-TW": "Traditional Chinese",
16
+ "common.language.ko-KR": "Korean",
17
+ "common.language.fr-FR": "French",
18
+ "common.language.es-ES": "Spanish",
19
+ "common.message.loading": "Loading",
20
+ "common.message.network_error": "Network error. Check your connection and try again.",
21
+ "common.message.request_error": "Request failed",
22
+ "common.message.unknown": "Unable to process this request. Try again later.",
23
+ "common.title.notice": "Notice",
24
+ "core.auth.login_again": "Log in again",
25
+ "core.auth.session_expired": "Your session has expired. Please log in again.",
26
+ "core.config.missing": "Missing app configuration: {names}",
27
+ "core.crypto.base64_decode_unsupported": "Base64 decoding is not supported in this environment",
28
+ "core.crypto.base64_encode_unsupported": "Base64 encoding is not supported in this environment",
29
+ "core.crypto.encrypt_failed": "Password encryption failed",
30
+ "core.crypto.password_required": "Password is required",
31
+ "core.crypto.password_too_long": "Password exceeds the supported length",
32
+ "core.crypto.public_key_invalid": "Invalid public key",
33
+ "core.file.download_failed": "Download failed",
34
+ "core.file.temporary_path_required": "Use a temporary file path when uploading from a Mini Program",
35
+ "core.file.upload_failed": "Upload failed",
36
+ "core.home.account_capability": "Account features",
37
+ "core.home.account_capability_description": "Profile, app settings, and AI assistant access are included",
38
+ "core.home.cross_platform": "Cross-platform pages",
39
+ "core.home.cross_platform_description": "One codebase for H5 and WeChat Mini Program",
40
+ "core.home.demo_scope": "Demo scope",
41
+ "core.home.framework": "App framework",
42
+ "core.home.language": "Language",
43
+ "core.home.main_title": "Application Framework",
44
+ "core.home.state_management": "State management",
45
+ "core.home.static_home": "Static home",
46
+ "core.home.static_home_description": "This page presents framework details without business APIs",
47
+ "core.home.style_solution": "Styling",
48
+ "core.home.sub_title": "Shared navigation and account experience",
49
+ "core.home.tech_stack": "Technology stack",
50
+ "core.login.agree_prefix": "I have read and agree to the",
51
+ "core.login.agree_separator": "and",
52
+ "core.login.behavior_click": "Click the characters in order",
53
+ "core.login.behavior_loading": "Loading...",
54
+ "core.login.behavior_puzzle": "Drag the slider to complete the puzzle",
55
+ "core.login.behavior_rotate": "Drag the slider to rotate the inner image upright",
56
+ "core.login.bind_wechat": "Log in and link WeChat",
57
+ "core.login.captcha": "Enter verification code",
58
+ "core.login.captcha_load_failed": "Failed to load verification code",
59
+ "core.login.captcha_type_missing": "Verification method is not configured",
60
+ "core.login.captcha_type_name": "Login verification method",
61
+ "core.login.captcha_type_response_missing": "Verification response did not include a type",
62
+ "core.login.captcha_write_failed": "Failed to save verification image",
63
+ "core.login.default_sub_title": "Welcome",
64
+ "core.login.login_failed": "Login failed. Try again.",
65
+ "core.login.login_success": "Logged in",
66
+ "core.login.password": "Enter password",
67
+ "core.login.privacy": "Privacy Policy",
68
+ "core.login.protocol_missing": "Terms of Service and Privacy Policy are not configured",
69
+ "core.login.protocol_prompt": "Read and accept the agreements first. Confirm to accept and continue.",
70
+ "core.login.service": "Terms of Service",
71
+ "core.login.tenant": "Enter tenant code",
72
+ "core.login.user_name": "Enter username or mobile number",
73
+ "core.login.user_name_mobile": "Enter username or mobile number",
74
+ "core.login.user_name_password": "Enter username and password",
75
+ "core.login.wechat": "Continue with WeChat",
76
+ "core.login.wechat_bind_tip": "This WeChat account is not linked. Log in to an existing account to link it.",
77
+ "core.login.wechat_failed": "WeChat login failed. Try again later.",
78
+ "core.navigation.home": "Home",
79
+ "core.navigation.error.access": "Invalid menu access mode: {access}",
80
+ "core.navigation.error.child_tab": "Only second-level app menus can be tabs: {name}",
81
+ "core.navigation.error.cycle": "Menu parent cycle detected: {name}",
82
+ "core.navigation.error.identity": "Menu id, name, or app/ path is invalid",
83
+ "core.navigation.error.item_object": "Menu item is not an object",
84
+ "core.navigation.error.list_missing": "Menu response does not contain a flat list",
85
+ "core.navigation.error.name_prefix": "Menu name must start with App: {name}",
86
+ "core.navigation.error.parent_missing": "Menu parent id is missing: {name}",
87
+ "core.navigation.error.parent_not_found": "Menu parent was not found: {name}",
88
+ "core.navigation.error.response_object": "Menu response is not an object",
89
+ "core.navigation.error.root_tab": "Second-level app menu must be a tab: {name}",
90
+ "core.navigation.error.tab_count": "tabBar must contain 0 or 2-5 items",
91
+ "core.navigation.error.unique": "Menu id, name, and path must be unique",
92
+ "core.navigation.error.view_key": "Unregistered viewKey: {viewKey}",
93
+ "core.navigation.my": "My Account",
94
+ "core.navigation.protocol": "Agreement",
95
+ "core.protocol.load_failed": "Failed to load app configuration",
96
+ "core.protocol.not_configured": "{title} is not configured and cannot be viewed",
97
+ "core.protocol.privacy": "Privacy Policy",
98
+ "core.protocol.service": "Terms of Service",
99
+ "core.status.CONFIG_ERROR": "Invalid navigation configuration",
100
+ "core.status.forbidden": "Access denied",
101
+ "core.status.NOT_FOUND": "Page not found",
102
+ "core.status.offline": "Network unavailable",
103
+ "core.status.page_unavailable": "Page temporarily unavailable",
104
+ "core.status.loading": "Loading",
105
+ "core.webview.embed_blocked": "The destination may block embedding on H5",
106
+ "core.webview.invalid_url": "No valid link was provided",
107
+ "core.webview.open_failed": "Unable to open link"
108
+ }
@@ -0,0 +1,108 @@
1
+ {
2
+ "common.action.back": "Volver",
3
+ "common.action.cancel": "Cancelar",
4
+ "common.action.confirm": "Confirmar",
5
+ "common.action.delete": "Eliminar",
6
+ "common.action.login": "Iniciar sesión",
7
+ "common.action.logout": "Cerrar sesión",
8
+ "common.action.new": "Nuevo",
9
+ "common.action.open_in_new_window": "Abrir en una ventana nueva",
10
+ "common.action.save": "Guardar",
11
+ "common.field.language": "Idioma",
12
+ "common.language.en-US": "Inglés",
13
+ "common.language.ja-JP": "Japonés",
14
+ "common.language.zh-CN": "Chino simplificado",
15
+ "common.language.zh-TW": "Chino tradicional",
16
+ "common.language.ko-KR": "Coreano",
17
+ "common.language.fr-FR": "Francés",
18
+ "common.language.es-ES": "Español",
19
+ "common.message.loading": "Cargando",
20
+ "common.message.network_error": "Error de red. Comprueba tu conexión e inténtalo de nuevo.",
21
+ "common.message.request_error": "Error de solicitud",
22
+ "common.message.unknown": "No se puede procesar esta solicitud. Inténtalo de nuevo más tarde.",
23
+ "common.title.notice": "Aviso",
24
+ "core.auth.login_again": "Vuelve a iniciar sesión",
25
+ "core.auth.session_expired": "Tu sesión ha caducado. Vuelve a iniciar sesión.",
26
+ "core.config.missing": "Falta la configuración de la aplicación: {names}",
27
+ "core.crypto.base64_decode_unsupported": "La decodificación Base64 no está disponible en este entorno",
28
+ "core.crypto.base64_encode_unsupported": "La codificación Base64 no está disponible en este entorno",
29
+ "core.crypto.encrypt_failed": "Error al cifrar la contraseña",
30
+ "core.crypto.password_required": "La contraseña es obligatoria",
31
+ "core.crypto.password_too_long": "La contraseña supera la longitud permitida",
32
+ "core.crypto.public_key_invalid": "Clave pública no válida",
33
+ "core.file.download_failed": "Error de descarga",
34
+ "core.file.temporary_path_required": "Al cargar desde un miniprograma, usa una ruta temporal del archivo",
35
+ "core.file.upload_failed": "Error de carga",
36
+ "core.home.account_capability": "Funciones de la cuenta",
37
+ "core.home.account_capability_description": "Incluye el perfil, la configuración de la aplicación y el acceso al asistente de IA",
38
+ "core.home.cross_platform": "Páginas multiplataforma",
39
+ "core.home.cross_platform_description": "Una sola base de código para H5 y el miniprograma de WeChat",
40
+ "core.home.demo_scope": "Alcance de la demostración",
41
+ "core.home.framework": "Marco de la aplicación",
42
+ "core.home.language": "idioma",
43
+ "core.home.main_title": "Ejemplo de marco de aplicación",
44
+ "core.home.state_management": "Gestión del estado",
45
+ "core.home.static_home": "Página de inicio estática",
46
+ "core.home.static_home_description": "Esta página presenta información del marco sin usar APIs de negocio",
47
+ "core.home.style_solution": "Estilos",
48
+ "core.home.sub_title": "Navegación compartida y experiencia de cuenta",
49
+ "core.home.tech_stack": "Pila tecnológica",
50
+ "core.login.agree_prefix": "He leído y acepto",
51
+ "core.login.agree_separator": "y",
52
+ "core.login.behavior_click": "Haz clic en los caracteres en orden",
53
+ "core.login.behavior_loading": "Cargando...",
54
+ "core.login.behavior_puzzle": "Arrastra el control deslizante para completar el rompecabezas",
55
+ "core.login.behavior_rotate": "Arrastra el control deslizante para orientar correctamente la imagen interior",
56
+ "core.login.bind_wechat": "Iniciar sesión y vincular WeChat",
57
+ "core.login.captcha": "Introduce el código de verificación",
58
+ "core.login.captcha_load_failed": "Error al cargar el código de verificación",
59
+ "core.login.captcha_type_missing": "El método de verificación no está configurado",
60
+ "core.login.captcha_type_name": "Método de verificación de inicio de sesión",
61
+ "core.login.captcha_type_response_missing": "La respuesta de verificación no incluye un tipo",
62
+ "core.login.captcha_write_failed": "Error al guardar la imagen de verificación",
63
+ "core.login.default_sub_title": "Bienvenido",
64
+ "core.login.login_failed": "Error de inicio de sesión. Inténtalo de nuevo.",
65
+ "core.login.login_success": "Sesión iniciada",
66
+ "core.login.password": "Introduce la contraseña",
67
+ "core.login.privacy": "Política de privacidad",
68
+ "core.login.protocol_missing": "Los términos del servicio y la política de privacidad no están configurados",
69
+ "core.login.protocol_prompt": "Lee y acepta primero los acuerdos. Confirma para aceptar y continuar.",
70
+ "core.login.service": "Términos del servicio",
71
+ "core.login.tenant": "Introduce el código del inquilino",
72
+ "core.login.user_name": "Introduce el nombre de usuario",
73
+ "core.login.user_name_mobile": "Introduce el nombre de usuario o el número de móvil",
74
+ "core.login.user_name_password": "Introduce el nombre de usuario y la contraseña",
75
+ "core.login.wechat": "Continuar con WeChat",
76
+ "core.login.wechat_bind_tip": "Esta cuenta de WeChat no está vinculada. Inicia sesión con una cuenta existente para vincularla.",
77
+ "core.login.wechat_failed": "Error de inicio de sesión de WeChat. Inténtalo de nuevo más tarde.",
78
+ "core.navigation.home": "Inicio",
79
+ "core.navigation.error.access": "Modo de acceso al menú no válido: {access}",
80
+ "core.navigation.error.child_tab": "Solo los menús de aplicación de segundo nivel pueden ser pestañas: {name}",
81
+ "core.navigation.error.cycle": "Se detectó un ciclo en los menús superiores: {name}",
82
+ "core.navigation.error.identity": "El id, nombre o ruta app/ del menú no es válido",
83
+ "core.navigation.error.item_object": "El elemento del menú no es un objeto",
84
+ "core.navigation.error.list_missing": "La respuesta del menú no contiene una lista plana",
85
+ "core.navigation.error.name_prefix": "El nombre del menú debe comenzar por App: {name}",
86
+ "core.navigation.error.parent_missing": "Falta el ID del menú superior: {name}",
87
+ "core.navigation.error.parent_not_found": "No se encontró el menú superior: {name}",
88
+ "core.navigation.error.response_object": "La respuesta del menú no es un objeto",
89
+ "core.navigation.error.root_tab": "El menú de aplicación de segundo nivel debe ser una pestaña: {name}",
90
+ "core.navigation.error.tab_count": "tabBar debe contener 0 o entre 2 y 5 elementos",
91
+ "core.navigation.error.unique": "El id, nombre y ruta del menú deben ser únicos",
92
+ "core.navigation.error.view_key": "viewKey no registrado: {viewKey}",
93
+ "core.navigation.my": "Mi cuenta",
94
+ "core.navigation.protocol": "Acuerdo",
95
+ "core.protocol.load_failed": "Error al cargar la configuración de la aplicación",
96
+ "core.protocol.not_configured": "{title} no está configurado y no se puede ver",
97
+ "core.protocol.privacy": "Política de privacidad",
98
+ "core.protocol.service": "Términos del servicio",
99
+ "core.status.CONFIG_ERROR": "Configuración de navegación no válida",
100
+ "core.status.forbidden": "Acceso denegado",
101
+ "core.status.NOT_FOUND": "Página no encontrada",
102
+ "core.status.offline": "Red no disponible",
103
+ "core.status.page_unavailable": "Página temporalmente no disponible",
104
+ "core.status.loading": "Cargando",
105
+ "core.webview.embed_blocked": "El destino puede impedir la incrustación en H5",
106
+ "core.webview.invalid_url": "No se ha proporcionado un enlace válido",
107
+ "core.webview.open_failed": "No se pudo abrir el enlace"
108
+ }
@@ -0,0 +1,108 @@
1
+ {
2
+ "common.action.back": "Retour",
3
+ "common.action.cancel": "Annuler",
4
+ "common.action.confirm": "Confirmer",
5
+ "common.action.delete": "Supprimer",
6
+ "common.action.login": "Se connecter",
7
+ "common.action.logout": "Se déconnecter",
8
+ "common.action.new": "Nouveau",
9
+ "common.action.open_in_new_window": "Ouvrir dans une nouvelle fenêtre",
10
+ "common.action.save": "Enregistrer",
11
+ "common.field.language": "Langue",
12
+ "common.language.en-US": "Anglais",
13
+ "common.language.ja-JP": "Japonais",
14
+ "common.language.zh-CN": "Chinois simplifié",
15
+ "common.language.zh-TW": "Chinois traditionnel",
16
+ "common.language.ko-KR": "Coréen",
17
+ "common.language.fr-FR": "Français",
18
+ "common.language.es-ES": "Espagnol",
19
+ "common.message.loading": "Chargement",
20
+ "common.message.network_error": "Erreur réseau. Vérifiez votre connexion et réessayez.",
21
+ "common.message.request_error": "Échec de la requête",
22
+ "common.message.unknown": "Impossible de traiter cette demande. Réessayez plus tard.",
23
+ "common.title.notice": "Avis",
24
+ "core.auth.login_again": "Se reconnecter",
25
+ "core.auth.session_expired": "Votre session a expiré. Veuillez vous reconnecter.",
26
+ "core.config.missing": "Configuration de l’application manquante : {names}",
27
+ "core.crypto.base64_decode_unsupported": "Le décodage Base64 n’est pas pris en charge dans cet environnement",
28
+ "core.crypto.base64_encode_unsupported": "L’encodage Base64 n’est pas pris en charge dans cet environnement",
29
+ "core.crypto.encrypt_failed": "Échec du chiffrement du mot de passe",
30
+ "core.crypto.password_required": "Le mot de passe est obligatoire",
31
+ "core.crypto.password_too_long": "Le mot de passe dépasse la longueur autorisée",
32
+ "core.crypto.public_key_invalid": "Clé publique non valide",
33
+ "core.file.download_failed": "Échec du téléchargement",
34
+ "core.file.temporary_path_required": "Utilisez un chemin de fichier temporaire pour téléverser depuis un mini-programme",
35
+ "core.file.upload_failed": "Échec de l’envoi",
36
+ "core.home.account_capability": "Fonctionnalités du compte",
37
+ "core.home.account_capability_description": "Le profil, les paramètres de l’application et l’accès à l’assistant IA sont inclus",
38
+ "core.home.cross_platform": "Pages multiplateformes",
39
+ "core.home.cross_platform_description": "Une seule base de code pour H5 et le mini-programme WeChat",
40
+ "core.home.demo_scope": "Périmètre de démonstration",
41
+ "core.home.framework": "Framework de l’application",
42
+ "core.home.language": "Langage",
43
+ "core.home.main_title": "Exemple de framework d’application",
44
+ "core.home.state_management": "Gestion de l’état",
45
+ "core.home.static_home": "Accueil statique",
46
+ "core.home.static_home_description": "Cette page présente le framework sans utiliser d’API métier",
47
+ "core.home.style_solution": "Styles",
48
+ "core.home.sub_title": "Navigation partagée et expérience de compte",
49
+ "core.home.tech_stack": "Stack technique",
50
+ "core.login.agree_prefix": "J’ai lu et j’accepte",
51
+ "core.login.agree_separator": "et",
52
+ "core.login.behavior_click": "Cliquez sur les caractères dans l'ordre",
53
+ "core.login.behavior_loading": "Chargement...",
54
+ "core.login.behavior_puzzle": "Faites glisser le curseur pour terminer le puzzle",
55
+ "core.login.behavior_rotate": "Faites glisser le curseur pour remettre l'image intérieure à l'endroit",
56
+ "core.login.bind_wechat": "Se connecter et lier WeChat",
57
+ "core.login.captcha": "Saisissez le code de vérification",
58
+ "core.login.captcha_load_failed": "Échec du chargement du code de vérification",
59
+ "core.login.captcha_type_missing": "La méthode de vérification n’est pas configurée",
60
+ "core.login.captcha_type_name": "Méthode de vérification de connexion",
61
+ "core.login.captcha_type_response_missing": "La réponse de vérification ne contient aucun type",
62
+ "core.login.captcha_write_failed": "Échec de l’enregistrement de l’image de vérification",
63
+ "core.login.default_sub_title": "Bienvenue",
64
+ "core.login.login_failed": "Échec de la connexion. Réessayez.",
65
+ "core.login.login_success": "Connexion réussie",
66
+ "core.login.password": "Saisissez le mot de passe",
67
+ "core.login.privacy": "Politique de confidentialité",
68
+ "core.login.protocol_missing": "Les conditions d’utilisation et la politique de confidentialité ne sont pas configurées",
69
+ "core.login.protocol_prompt": "Lisez et acceptez d’abord les accords. Confirmez pour accepter et continuer.",
70
+ "core.login.service": "Conditions d’utilisation",
71
+ "core.login.tenant": "Saisissez le code du locataire",
72
+ "core.login.user_name": "Saisissez le nom d'utilisateur",
73
+ "core.login.user_name_mobile": "Saisissez le nom d’utilisateur ou le numéro de mobile",
74
+ "core.login.user_name_password": "Saisissez le nom d’utilisateur et le mot de passe",
75
+ "core.login.wechat": "Continuer avec WeChat",
76
+ "core.login.wechat_bind_tip": "Ce compte WeChat n’est pas lié. Connectez-vous à un compte existant pour le lier.",
77
+ "core.login.wechat_failed": "Échec de la connexion WeChat. Réessayez plus tard.",
78
+ "core.navigation.home": "Accueil",
79
+ "core.navigation.error.access": "Mode d’accès au menu invalide : {access}",
80
+ "core.navigation.error.child_tab": "Seuls les menus d’application de deuxième niveau peuvent être des onglets : {name}",
81
+ "core.navigation.error.cycle": "Cycle de parenté détecté dans le menu : {name}",
82
+ "core.navigation.error.identity": "L’identifiant, le nom ou le chemin app/ du menu est invalide",
83
+ "core.navigation.error.item_object": "L’élément de menu n’est pas un objet",
84
+ "core.navigation.error.list_missing": "La réponse du menu ne contient pas de liste plate",
85
+ "core.navigation.error.name_prefix": "Le nom du menu doit commencer par App : {name}",
86
+ "core.navigation.error.parent_missing": "L’identifiant du parent du menu est manquant : {name}",
87
+ "core.navigation.error.parent_not_found": "Le parent du menu est introuvable : {name}",
88
+ "core.navigation.error.response_object": "La réponse du menu n’est pas un objet",
89
+ "core.navigation.error.root_tab": "Le menu d’application de deuxième niveau doit être un onglet : {name}",
90
+ "core.navigation.error.tab_count": "tabBar doit contenir 0 ou 2 à 5 éléments",
91
+ "core.navigation.error.unique": "L’identifiant, le nom et le chemin du menu doivent être uniques",
92
+ "core.navigation.error.view_key": "viewKey non enregistré : {viewKey}",
93
+ "core.navigation.my": "Mon compte",
94
+ "core.navigation.protocol": "Accord",
95
+ "core.protocol.load_failed": "Échec du chargement de la configuration de l’application",
96
+ "core.protocol.not_configured": "{title} n’est pas configuré et ne peut pas être consulté",
97
+ "core.protocol.privacy": "Politique de confidentialité",
98
+ "core.protocol.service": "Conditions d’utilisation",
99
+ "core.status.CONFIG_ERROR": "Configuration de navigation invalide",
100
+ "core.status.forbidden": "Accès refusé",
101
+ "core.status.NOT_FOUND": "Page introuvable",
102
+ "core.status.offline": "Réseau indisponible",
103
+ "core.status.page_unavailable": "Page temporairement indisponible",
104
+ "core.status.loading": "Chargement",
105
+ "core.webview.embed_blocked": "La destination peut bloquer l’intégration sur H5",
106
+ "core.webview.invalid_url": "Aucun lien valide n’a été fourni",
107
+ "core.webview.open_failed": "Impossible d’ouvrir le lien"
108
+ }
@@ -0,0 +1,22 @@
1
+ /* 此文件由 scripts/sync_locales.py 生成,请勿手工修改。 */
2
+ import localeZhCn from './zh-CN.json'
3
+ import localeEnUs from './en-US.json'
4
+ import localeEsEs from './es-ES.json'
5
+ import localeFrFr from './fr-FR.json'
6
+ import localeJaJp from './ja-JP.json'
7
+ import localeKoKr from './ko-KR.json'
8
+ import localeZhTw from './zh-TW.json'
9
+
10
+ export const LOCALE_MESSAGES = {
11
+ 'zh-CN': localeZhCn,
12
+ 'en-US': localeEnUs,
13
+ 'es-ES': localeEsEs,
14
+ 'fr-FR': localeFrFr,
15
+ 'ja-JP': localeJaJp,
16
+ 'ko-KR': localeKoKr,
17
+ 'zh-TW': localeZhTw,
18
+ } as const satisfies Record<string, Record<string, string>>
19
+
20
+ export type GeneratedLocale = keyof typeof LOCALE_MESSAGES
21
+ export const DEFAULT_LOCALE: GeneratedLocale = 'zh-CN'
22
+ export const SUPPORTED_LOCALES = Object.keys(LOCALE_MESSAGES) as GeneratedLocale[]