@liujitcn/kratos-admin-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 (131) hide show
  1. package/README.md +2 -2
  2. package/dist/package/declarations/src/api/base/language.d.ts +8 -0
  3. package/dist/package/declarations/src/components/Dialog/ProDialog.vue.d.ts +1 -0
  4. package/dist/package/declarations/src/components/Dict/index.vue.d.ts +4 -3
  5. package/dist/package/declarations/src/components/Dict/value.d.ts +11 -0
  6. package/dist/package/declarations/src/components/LocaleSwitch/index.vue.d.ts +3 -0
  7. package/dist/package/declarations/src/index.d.ts +2 -0
  8. package/dist/package/declarations/src/locales/generated.d.ts +3382 -0
  9. package/dist/package/declarations/src/locales/index.d.ts +53 -0
  10. package/dist/package/declarations/src/modules/index.d.ts +7 -2
  11. package/dist/package/declarations/src/request.d.ts +1 -0
  12. package/dist/package/declarations/src/routers/modules/staticRouter.d.ts +1 -0
  13. package/dist/package/declarations/src/rpc/base/v1/config.d.ts +13 -1
  14. package/dist/package/declarations/src/rpc/base/v1/language.d.ts +20 -0
  15. package/dist/package/declarations/src/rpc/base/v1/login.d.ts +13 -1
  16. package/dist/package/declarations/src/rpc/system/admin/v1/auth.d.ts +1 -1
  17. package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +9 -0
  18. package/dist/package/declarations/src/rpc/system/admin/v1/base_translation.d.ts +75 -0
  19. package/dist/package/declarations/src/rpc/system/admin/v1/common.d.ts +13 -0
  20. package/dist/package/declarations/src/stores/interface/index.d.ts +2 -0
  21. package/dist/package/declarations/src/stores/modules/auth.d.ts +6 -6
  22. package/dist/package/declarations/src/stores/runtime.d.ts +1 -0
  23. package/dist/package/declarations/src/utils/dict.d.ts +2 -2
  24. package/dist/package/declarations/src/utils/index.d.ts +1 -1
  25. package/dist/package/declarations/src/utils/oauthProvider.d.ts +2 -0
  26. package/dist/package/declarations/src/utils/passwordCrypto.d.ts +1 -1
  27. package/dist/package/declarations/src/utils/passwordStrength.d.ts +0 -7
  28. package/dist/package/src/App.vue +5 -2
  29. package/dist/package/src/api/base/language.ts +20 -0
  30. package/dist/package/src/api/base/oauth.ts +0 -1
  31. package/dist/package/src/api/system/auth.ts +0 -1
  32. package/dist/package/src/bootstrap.ts +57 -2
  33. package/dist/package/src/components/CronExpression/index.vue +80 -82
  34. package/dist/package/src/components/Dialog/FormDialog.vue +10 -5
  35. package/dist/package/src/components/Dialog/ProDialog.vue +10 -4
  36. package/dist/package/src/components/Dict/index.vue +26 -9
  37. package/dist/package/src/components/Dict/value.ts +18 -0
  38. package/dist/package/src/components/ECharts/config/index.ts +6 -1
  39. package/dist/package/src/components/ErrorMessage/index.vue +3 -1
  40. package/dist/package/src/components/ImportExcel/index.vue +29 -18
  41. package/dist/package/src/components/LocaleSwitch/index.vue +28 -0
  42. package/dist/package/src/components/PasswordStrength/index.vue +8 -5
  43. package/dist/package/src/components/ProForm/components/DynamicList.vue +8 -3
  44. package/dist/package/src/components/ProForm/components/KvList.vue +14 -6
  45. package/dist/package/src/components/ProForm/index.vue +2 -2
  46. package/dist/package/src/components/ProTable/components/ColSetting.vue +7 -5
  47. package/dist/package/src/components/ProTable/components/TableColumn.vue +2 -1
  48. package/dist/package/src/components/ProTable/index.vue +36 -11
  49. package/dist/package/src/components/SearchForm/components/SearchFormItem.vue +9 -4
  50. package/dist/package/src/components/SearchForm/index.vue +6 -3
  51. package/dist/package/src/components/SelectFilter/index.vue +4 -1
  52. package/dist/package/src/components/SelectIcon/index.vue +8 -4
  53. package/dist/package/src/components/TreeFilter/index.vue +14 -6
  54. package/dist/package/src/components/Upload/File.vue +18 -13
  55. package/dist/package/src/components/Upload/Files.vue +22 -15
  56. package/dist/package/src/components/Upload/Img.vue +14 -11
  57. package/dist/package/src/components/Upload/Imgs.vue +15 -12
  58. package/dist/package/src/components/WangEditor/index.vue +12 -4
  59. package/dist/package/src/directives/modules/copy.ts +2 -1
  60. package/dist/package/src/hooks/useDownload.ts +3 -2
  61. package/dist/package/src/hooks/useHandleData.ts +5 -4
  62. package/dist/package/src/hooks/useTheme.ts +2 -1
  63. package/dist/package/src/hooks/useTime.ts +11 -2
  64. package/dist/package/src/index.ts +2 -0
  65. package/dist/package/src/layouts/components/Header/ToolBarRight.vue +2 -0
  66. package/dist/package/src/layouts/components/Header/components/AssemblySize.vue +8 -6
  67. package/dist/package/src/layouts/components/Header/components/Avatar.vue +11 -9
  68. package/dist/package/src/layouts/components/Header/components/Breadcrumb.vue +11 -3
  69. package/dist/package/src/layouts/components/Header/components/Fullscreen.vue +4 -2
  70. package/dist/package/src/layouts/components/Header/components/InfoDialog.vue +6 -3
  71. package/dist/package/src/layouts/components/Header/components/PasswordDialog.vue +6 -3
  72. package/dist/package/src/layouts/components/Header/components/SearchMenu.vue +5 -3
  73. package/dist/package/src/layouts/components/Header/components/ThemeSetting.vue +3 -1
  74. package/dist/package/src/layouts/components/Main/index.vue +1 -0
  75. package/dist/package/src/layouts/components/Tabs/components/MoreButton.vue +9 -7
  76. package/dist/package/src/layouts/components/Tabs/index.vue +15 -1
  77. package/dist/package/src/layouts/components/ThemeDrawer/index.vue +27 -24
  78. package/dist/package/src/locales/README.md +15 -0
  79. package/dist/package/src/locales/en-US.json +283 -0
  80. package/dist/package/src/locales/es-ES.json +283 -0
  81. package/dist/package/src/locales/fr-FR.json +283 -0
  82. package/dist/package/src/locales/generated.ts +57 -0
  83. package/dist/package/src/locales/index.ts +222 -0
  84. package/dist/package/src/locales/ja-JP.json +283 -0
  85. package/dist/package/src/locales/ko-KR.json +283 -0
  86. package/dist/package/src/locales/zh-CN.json +283 -0
  87. package/dist/package/src/locales/zh-TW.json +283 -0
  88. package/dist/package/src/modules/index.ts +7 -2
  89. package/dist/package/src/modules/kratosAdmin.ts +5 -1
  90. package/dist/package/src/request.ts +8 -1
  91. package/dist/package/src/routers/index.ts +4 -1
  92. package/dist/package/src/routers/modules/dynamicRouter.ts +5 -4
  93. package/dist/package/src/routers/modules/staticRouter.ts +8 -4
  94. package/dist/package/src/rpc/base/v1/config.ts +14 -1
  95. package/dist/package/src/rpc/base/v1/language.ts +31 -0
  96. package/dist/package/src/rpc/base/v1/login.ts +14 -1
  97. package/dist/package/src/rpc/system/admin/v1/auth.ts +1 -1
  98. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +9 -0
  99. package/dist/package/src/rpc/system/admin/v1/base_translation.ts +90 -0
  100. package/dist/package/src/rpc/system/admin/v1/common.ts +21 -0
  101. package/dist/package/src/stores/interface/index.ts +2 -0
  102. package/dist/package/src/stores/modules/config.ts +7 -3
  103. package/dist/package/src/stores/modules/user.ts +2 -1
  104. package/dist/package/src/stores/runtime.ts +1 -0
  105. package/dist/package/src/styles/element.scss +2 -0
  106. package/dist/package/src/utils/color.ts +5 -4
  107. package/dist/package/src/utils/dict.ts +27 -4
  108. package/dist/package/src/utils/eleValidate.ts +3 -2
  109. package/dist/package/src/utils/errorHandler.ts +9 -8
  110. package/dist/package/src/utils/index.ts +9 -8
  111. package/dist/package/src/utils/oauthProvider.ts +15 -10
  112. package/dist/package/src/utils/passwordCrypto.ts +4 -3
  113. package/dist/package/src/utils/passwordStrength.ts +1 -16
  114. package/dist/package/src/utils/request.ts +13 -8
  115. package/dist/package/src/views/error/403.vue +3 -1
  116. package/dist/package/src/views/error/404.vue +3 -1
  117. package/dist/package/src/views/error/500.vue +3 -1
  118. package/dist/package/src/views/error/pending.vue +5 -2
  119. package/dist/package/src/views/login/components/LoginForm.vue +58 -29
  120. package/dist/package/src/views/login/index.scss +6 -0
  121. package/dist/package/src/views/login/index.vue +2 -0
  122. package/dist/package/types/generated/auto-imports.d.ts +129 -111
  123. package/dist/package/types/generated/components.d.ts +67 -67
  124. package/package.json +4 -2
  125. package/types/generated/auto-imports.d.ts +129 -111
  126. package/types/generated/components.d.ts +67 -67
  127. package/vite.config.ts +12 -0
  128. package/dist/package/declarations/src/rpc/base/v1/enum.d.ts +0 -43
  129. package/dist/package/declarations/src/rpc/system/common/v1/enum.d.ts +0 -67
  130. package/dist/package/src/rpc/base/v1/enum.ts +0 -54
  131. package/dist/package/src/rpc/system/common/v1/enum.ts +0 -80
@@ -0,0 +1,283 @@
1
+ {
2
+ "common.action.back": "Retour",
3
+ "common.action.cancel": "Annuler",
4
+ "common.action.close": "Fermer",
5
+ "common.action.confirm": "Confirmer",
6
+ "common.action.create": "Créer",
7
+ "common.action.delete": "Supprimer",
8
+ "common.action.download": "Télécharger",
9
+ "common.action.edit": "Modifier",
10
+ "common.action.expand": "Développer",
11
+ "common.action.collapse": "Réduire",
12
+ "common.action.login": "Se connecter",
13
+ "common.action.logout": "Se déconnecter",
14
+ "common.action.reset": "Réinitialiser",
15
+ "common.action.save": "Enregistrer",
16
+ "common.action.search": "Rechercher",
17
+ "common.action.view": "Afficher",
18
+ "common.field.end_time": "Heure de fin",
19
+ "common.field.language": "Langue",
20
+ "common.field.operation": "Actions",
21
+ "common.field.parameter_name": "Nom du paramètre",
22
+ "common.field.parameter_value": "Valeur du paramètre",
23
+ "common.field.phone": "Numéro de téléphone",
24
+ "common.field.start_time": "Heure de début",
25
+ "common.language.en-US": "Anglais",
26
+ "common.language.ja-JP": "Japonais",
27
+ "common.language.zh-CN": "Chinois simplifié",
28
+ "common.language.zh-TW": "Chinois traditionnel",
29
+ "common.language.ko-KR": "Coréen",
30
+ "common.language.fr-FR": "Français",
31
+ "common.language.es-ES": "Espagnol",
32
+ "common.message.no_data": "Aucune donnée",
33
+ "common.message.operation_success": "Opération terminée",
34
+ "common.message.system_error": "Erreur système",
35
+ "common.validation.phone_invalid": "Saisissez un numéro de téléphone valide",
36
+ "common.validation.phone_required": "Saisissez un numéro de téléphone",
37
+ "common.title.notice": "Avis",
38
+ "common.title.warning": "Confirmation",
39
+ "common.placeholder.input": "Saisissez une valeur",
40
+ "common.placeholder.input_content": "Saisissez le contenu",
41
+ "common.placeholder.select": "Sélectionnez une valeur",
42
+ "common.status.disabled": "Désactivé",
43
+ "common.status.enabled": "Activé",
44
+ "common.value.female": "Femme",
45
+ "common.value.male": "Homme",
46
+ "common.value.all": "Tous",
47
+ "core.auth.login_again": "Se reconnecter",
48
+ "core.auth.refresh_token_missing": "Le jeton d’actualisation est manquant",
49
+ "core.auth.session_expired": "Votre session a expiré. Veuillez vous reconnecter.",
50
+ "core.auth.no_menu_permission": "Ce compte n’a aucun droit de menu. Contactez un administrateur.",
51
+ "core.auth.no_permission": "Accès refusé",
52
+ "core.clipboard.success": "Copié",
53
+ "core.cron.cycle_unit.day": "jours",
54
+ "core.cron.cycle_unit.hour": "heures",
55
+ "core.cron.cycle_unit.minute": "minutes",
56
+ "core.cron.cycle_unit.month": "mois",
57
+ "core.cron.cycle_unit.second": "secondes",
58
+ "core.cron.cycle_unit.year": "ans",
59
+ "core.cron.description.every": "Chaque {unit}",
60
+ "core.cron.description.range": "{segment} de {start} à {end}",
61
+ "core.cron.description.specific": "{segment} : {values}",
62
+ "core.cron.description.step": "À partir de {start} {unit}, exécuter toutes les {step} {cycleUnit}",
63
+ "core.cron.description.unspecified": "{segment} non défini",
64
+ "core.cron.description.weekday": "Jour ouvré le plus proche du {day} de ce mois",
65
+ "core.cron.description_separator": "; ",
66
+ "core.cron.edit": "Modifier l'expression",
67
+ "core.cron.every_unit": "Chaque {unit}",
68
+ "core.cron.expression": "Expression Cron",
69
+ "core.cron.from": "à partir de",
70
+ "core.cron.last_day": "Dernier jour de ce mois",
71
+ "core.cron.nearest_workday": "jour ouvré le plus proche",
72
+ "core.cron.not_configured": "Aucune planification configurée",
73
+ "core.cron.placeholder": "Saisissez une expression Cron",
74
+ "core.cron.preset.daily_eight": "Tous les jours à 8 h",
75
+ "core.cron.preset.daily_midnight": "Tous les jours à minuit",
76
+ "core.cron.preset.every_five_minutes": "Toutes les 5 minutes",
77
+ "core.cron.preset.every_hour": "Toutes les heures",
78
+ "core.cron.preset.every_minute": "Toutes les minutes",
79
+ "core.cron.preset.monthly_first": "Le 1er de chaque mois à minuit",
80
+ "core.cron.preset.next_year_daily": "Tous les jours de l'année prochaine à minuit",
81
+ "core.cron.presets": "Expressions courantes",
82
+ "core.cron.range": "Plage",
83
+ "core.cron.repeat": "Répéter",
84
+ "core.cron.run_once": "Exécuter une fois par {unit}",
85
+ "core.cron.segment.day": "Jour",
86
+ "core.cron.segment.hour": "Heure",
87
+ "core.cron.segment.minute": "Minute",
88
+ "core.cron.segment.month": "Mois",
89
+ "core.cron.segment.second": "Seconde",
90
+ "core.cron.segment.year": "Année",
91
+ "core.cron.specific": "Spécifique",
92
+ "core.cron.start_every": "{unit}, toutes les",
93
+ "core.cron.this_month": "Jour de ce mois",
94
+ "core.cron.title": "Modifier l'expression de planification",
95
+ "core.cron.to": "à",
96
+ "core.cron.unit.day": "jour",
97
+ "core.cron.unit.hour": "heure",
98
+ "core.cron.unit.minute": "minute",
99
+ "core.cron.unit.month": "mois",
100
+ "core.cron.unit.second": "seconde",
101
+ "core.cron.unit.year": "an",
102
+ "core.cron.unspecified": "Non défini",
103
+ "core.cron.value_separator": ", ",
104
+ "core.cron.value_with_unit": "{value} {unit}",
105
+ "core.cron.workday": "Jour ouvré",
106
+ "core.data.confirm_action": "Voulez-vous vraiment {action} ?",
107
+ "core.data.operation_success": "{action} terminé",
108
+ "core.download.large_file_notice": "Le téléchargement de gros volumes de données peut prendre plus de temps. Veuillez patienter.",
109
+ "core.error.403.detail": "Vous n’avez pas l’autorisation d’accéder à cette page.",
110
+ "core.error.404.detail": "La page demandée n’existe pas.",
111
+ "core.error.500.detail": "Le serveur a rencontré une erreur.",
112
+ "core.error.pending.detail": "Cette fonctionnalité est en cours de développement.",
113
+ "core.error.javascript.eval": "Utilisation invalide de Eval",
114
+ "core.error.javascript.internal": "Erreur interne du moteur JavaScript",
115
+ "core.error.javascript.range": "Le paramètre est hors limites",
116
+ "core.error.javascript.reference": "Objet introuvable",
117
+ "core.error.javascript.syntax": "Erreur de syntaxe",
118
+ "core.error.javascript.type": "Type ou objet invalide",
119
+ "core.error.javascript.unknown": "Erreur inconnue",
120
+ "core.error.javascript.uri": "Erreur d’URI",
121
+ "core.header.fullscreen": "Plein écran",
122
+ "core.header.fullscreen_exit": "Quitter le plein écran",
123
+ "core.header.fullscreen_unsupported": "Le plein écran n’est pas pris en charge par ce navigateur",
124
+ "core.header.language": "Changer de langue",
125
+ "core.header.menu_search": "Rechercher dans les menus",
126
+ "core.header.menu_search_empty": "Aucun menu trouvé",
127
+ "core.header.menu_search_placeholder": "Rechercher par nom ou chemin du menu",
128
+ "core.header.size.default": "Par défaut",
129
+ "core.header.size.large": "Grand",
130
+ "core.header.size.small": "Petit",
131
+ "core.header.size_select": "Taille du composant",
132
+ "core.header.theme": "Paramètres du thème",
133
+ "core.icon.empty": "Aucune icône correspondante",
134
+ "core.icon.placeholder": "Sélectionnez une icône",
135
+ "core.icon.search": "Rechercher des icônes",
136
+ "core.layout.department_unassigned": "Aucun département attribué",
137
+ "core.layout.home": "Accueil",
138
+ "core.layout.info": "Informations personnelles",
139
+ "core.layout.password_change": "Modifier le mot de passe",
140
+ "core.layout.unnamed_menu": "Menu sans nom",
141
+ "core.layout.logout_confirm": "Voulez-vous vraiment vous déconnecter ?",
142
+ "core.layout.logout_success": "Déconnecté",
143
+ "core.layout.not_set": "Non défini",
144
+ "core.layout.role_unassigned": "Aucun rôle attribué",
145
+ "core.login.behavior_click": "Cliquez sur les caractères dans l'ordre",
146
+ "core.login.behavior_confirm": "Confirmer",
147
+ "core.login.behavior_puzzle": "Faites glisser le curseur pour terminer le puzzle",
148
+ "core.login.behavior_rotate": "Faites glisser le curseur pour remettre l'image intérieure à l'endroit",
149
+ "core.login.captcha": "Saisissez le code de vérification",
150
+ "core.login.captcha_alt": "Code de vérification",
151
+ "core.login.greeting.afternoon": "Bon après-midi",
152
+ "core.login.greeting.evening": "Bonsoir",
153
+ "core.login.greeting.morning": "Bonjour",
154
+ "core.login.greeting.night": "Bonjour",
155
+ "core.login.greeting.noon": "Bon après-midi",
156
+ "core.login.other_methods": "Autres méthodes de connexion",
157
+ "core.login.password": "Saisissez le mot de passe",
158
+ "core.login.tenant_code": "Saisissez le code du locataire",
159
+ "core.login.user_name": "Saisissez le nom d'utilisateur",
160
+ "core.login.welcome": "Bienvenue dans la console d'administration",
161
+ "core.oauth.dingtalk": "DingTalk",
162
+ "core.oauth.feishu": "Feishu",
163
+ "core.oauth.wechat": "WeChat",
164
+ "core.oauth.wechatmp": "Compte officiel WeChat",
165
+ "core.oauth.wechatwork": "WeCom",
166
+ "core.oauth.unknown": "Fournisseur inconnu",
167
+ "core.password.error": "Le mot de passe doit contenir des majuscules, des minuscules, un chiffre et un caractère spécial, et comporter au moins 8 caractères.",
168
+ "core.password.crypto_unsupported": "Le chiffrement des mots de passe n’est pas pris en charge dans cet environnement",
169
+ "core.password.required": "Le mot de passe est obligatoire",
170
+ "core.password.strength": "Force du mot de passe",
171
+ "core.password.strength.empty": "Non saisie",
172
+ "core.password.strength.high": "Élevée",
173
+ "core.password.strength.low": "Faible",
174
+ "core.password.strength.medium": "Moyenne",
175
+ "core.password.tip": "Utilisez au moins 8 caractères avec des majuscules, des minuscules, un chiffre et un caractère spécial. Le mot de passe doit atteindre une force élevée avant l’envoi.",
176
+ "core.theme.accordion": "Menu accordéon",
177
+ "core.theme.aside_inverted": "Barre latérale sombre",
178
+ "core.theme.aside_inverted_tip": "Utiliser des couleurs sombres pour la barre latérale",
179
+ "core.theme.breadcrumb": "Fil d’Ariane",
180
+ "core.theme.breadcrumb_icon": "Icônes du fil d’Ariane",
181
+ "core.theme.color": "Couleur du thème",
182
+ "core.theme.dark": "Mode sombre",
183
+ "core.theme.footer": "Pied de page",
184
+ "core.theme.global": "Thème global",
185
+ "core.theme.grey": "Mode niveaux de gris",
186
+ "core.theme.header_inverted": "En-tête sombre",
187
+ "core.theme.header_inverted_tip": "Utiliser des couleurs sombres pour l’en-tête",
188
+ "core.theme.interface": "Paramètres de l’interface",
189
+ "core.theme.layout": "Mise en page",
190
+ "core.theme.layout.classic": "Classique",
191
+ "core.theme.layout.columns": "Colonnes",
192
+ "core.theme.layout.transverse": "Transversal",
193
+ "core.theme.layout.vertical": "Vertical",
194
+ "core.theme.menu_collapse": "Réduire le menu",
195
+ "core.theme.primary_reset": "Couleur du thème réinitialisée à {color}",
196
+ "core.theme.settings": "Paramètres de mise en page",
197
+ "core.theme.tabs": "Onglets",
198
+ "core.theme.tabs_icon": "Icônes des onglets",
199
+ "core.theme.watermark": "Filigrane",
200
+ "core.theme.weak": "Mode daltonisme",
201
+ "core.theme.color_hex_invalid": "Saisissez une couleur hexadécimale valide",
202
+ "core.theme.color_rgb_invalid": "Saisissez une couleur RGB valide",
203
+ "core.route.forbidden": "Page 403",
204
+ "core.route.login": "Se connecter",
205
+ "core.route.not_found": "Page 404",
206
+ "core.route.server_error": "Page 500",
207
+ "core.tabs.close_all": "Tout fermer",
208
+ "core.tabs.close_current": "Fermer l’onglet actuel",
209
+ "core.tabs.close_left": "Fermer les onglets à gauche",
210
+ "core.tabs.close_other": "Fermer les autres onglets",
211
+ "core.tabs.close_right": "Fermer les onglets à droite",
212
+ "core.tabs.maximize": "Maximiser",
213
+ "core.tabs.refresh": "Actualiser",
214
+ "core.table.collapse_all": "Tout réduire",
215
+ "core.table.column_name": "Colonne",
216
+ "core.table.column_setting": "Paramètres des colonnes",
217
+ "core.table.expand_all": "Tout développer",
218
+ "core.table.hide_search": "Masquer la recherche",
219
+ "core.table.no_configurable_columns": "Aucune colonne configurable",
220
+ "core.table.refresh": "Actualiser les données",
221
+ "core.table.show": "Visible",
222
+ "core.table.show_search": "Afficher la recherche",
223
+ "core.table.sort": "Triable",
224
+ "core.tree.filter_placeholder": "Saisissez des mots-clés à filtrer",
225
+ "core.tree.reset_selection": "Réinitialiser la sélection",
226
+ "core.upload.action": "Téléverser un fichier",
227
+ "core.upload.batch_add": "Ajouter {resource} par lot",
228
+ "core.upload.batch_failed": "Échec de l’ajout groupé de {resource}. Téléversez à nouveau le fichier.",
229
+ "core.upload.batch_success": "{resource} ajouté avec succès",
230
+ "core.upload.click": "cliquez pour téléverser",
231
+ "core.upload.data_cover": "Écraser les données",
232
+ "core.upload.drag_or_click": "Déposez un fichier ici ou ",
233
+ "core.upload.excel_format": "Téléversez un fichier .xls ou .xlsx standard de {size} Mo maximum",
234
+ "core.upload.file": "Téléversement de fichier",
235
+ "core.upload.file_failed": "Échec du téléversement. Réessayez.",
236
+ "core.upload.file_format_invalid": "Le format du fichier n’est pas pris en charge",
237
+ "core.upload.file_size_exceeded": "Le fichier ne doit pas dépasser {size} Mo",
238
+ "core.upload.file_success": "Fichier téléversé",
239
+ "core.upload.image_failed": "Échec du téléversement de l’image. Réessayez.",
240
+ "core.upload.image_format_invalid": "Le format de l’image n’est pas pris en charge",
241
+ "core.upload.image_limit_exceeded": "Vous pouvez téléverser jusqu’à {limit} images. Supprimez-en une avant d’en téléverser une autre.",
242
+ "core.upload.image_size_exceeded": "L’image ne doit pas dépasser {size} Mo",
243
+ "core.upload.image_success": "Image téléversée",
244
+ "core.upload.limit_exceeded": "Vous pouvez téléverser jusqu’à {limit} fichiers. Supprimez-en un avant d’en téléverser un autre.",
245
+ "core.upload.single_file_only": "Un seul fichier peut être téléversé",
246
+ "core.upload.template": "Modèle de {resource}",
247
+ "core.upload.template_download": "Télécharger le modèle",
248
+ "core.upload.unnamed_file": "Fichier sans nom",
249
+ "common.action.create_resource": "Créer {resource}",
250
+ "common.action.edit_resource": "Modifier {resource}",
251
+ "common.action.refresh_cache": "Actualiser le cache",
252
+ "common.dialog.cancel_delete": "Suppression de {resource} annulée",
253
+ "common.dialog.delete_batch": "Supprimer les {count} {resource} {unit} sélectionnés ?",
254
+ "common.dialog.delete_selected": "Supprimer le {resource} sélectionné ?",
255
+ "common.dialog.delete_single": "Supprimer ce {resource} ?",
256
+ "common.dialog.resource_field": "{field} : {value}",
257
+ "common.dialog.status_change": "{action} ce {resource} ?\n{field} : {value}",
258
+ "common.field.created_at": "Créé le",
259
+ "common.field.remark": "Remarques",
260
+ "common.field.sort": "Ordre",
261
+ "common.field.status": "Statut",
262
+ "common.field.tenant": "Locataire",
263
+ "common.field.updated_at": "Mis à jour le",
264
+ "common.message.create_success": "{resource} créé",
265
+ "common.message.delete_success": "{resource} supprimé",
266
+ "common.message.load_children_failed": "Échec du chargement des {resource} enfants",
267
+ "common.message.refresh_success": "Actualisé",
268
+ "common.message.select_delete_item": "Sélectionnez les éléments à supprimer",
269
+ "common.message.status_success": "{action} terminé",
270
+ "common.message.update_success": "{resource} mis à jour",
271
+ "common.placeholder.remark": "Saisissez des remarques",
272
+ "common.validation.max_length": "{field} ne doit pas dépasser {max} caractères",
273
+ "common.validation.required_input": "Saisissez {field}",
274
+ "common.validation.required_select": "Sélectionnez {field}",
275
+ "common.validation.sort_positive": "L’ordre doit être supérieur à 0",
276
+ "common.field.action": "Actions",
277
+ "common.placeholder.start_date": "Date de début",
278
+ "common.placeholder.end_date": "Date de fin",
279
+ "common.value.yes": "Oui",
280
+ "common.value.no": "Non",
281
+ "common.value.unknown": "Inconnu",
282
+ "common.value.none": "Aucun"
283
+ }
@@ -0,0 +1,57 @@
1
+ /* 此文件由 scripts/sync_locales.py 生成,请勿手工修改。 */
2
+ import "dayjs/locale/zh-cn";
3
+ import "dayjs/locale/en";
4
+ import "dayjs/locale/es";
5
+ import "dayjs/locale/fr";
6
+ import "dayjs/locale/ja";
7
+ import "dayjs/locale/ko";
8
+ import "dayjs/locale/zh-tw";
9
+ import elementLocaleZhCn from "element-plus/es/locale/lang/zh-cn";
10
+ import elementLocaleEnUs from "element-plus/es/locale/lang/en";
11
+ import elementLocaleEsEs from "element-plus/es/locale/lang/es";
12
+ import elementLocaleFrFr from "element-plus/es/locale/lang/fr";
13
+ import elementLocaleJaJp from "element-plus/es/locale/lang/ja";
14
+ import elementLocaleKoKr from "element-plus/es/locale/lang/ko";
15
+ import elementLocaleZhTw from "element-plus/es/locale/lang/zh-tw";
16
+
17
+ import localeZhCn from "./zh-CN.json";
18
+ import localeEnUs from "./en-US.json";
19
+ import localeEsEs from "./es-ES.json";
20
+ import localeFrFr from "./fr-FR.json";
21
+ import localeJaJp from "./ja-JP.json";
22
+ import localeKoKr from "./ko-KR.json";
23
+ import localeZhTw from "./zh-TW.json";
24
+
25
+ export const LOCALE_MESSAGES = {
26
+ "zh-CN": localeZhCn,
27
+ "en-US": localeEnUs,
28
+ "es-ES": localeEsEs,
29
+ "fr-FR": localeFrFr,
30
+ "ja-JP": localeJaJp,
31
+ "ko-KR": localeKoKr,
32
+ "zh-TW": localeZhTw,
33
+ } as const satisfies Record<string, Record<string, string>>;
34
+
35
+ export type GeneratedLocale = keyof typeof LOCALE_MESSAGES;
36
+ export const DEFAULT_LOCALE: GeneratedLocale = "zh-CN";
37
+ export const SUPPORTED_LOCALES = Object.keys(LOCALE_MESSAGES) as GeneratedLocale[];
38
+
39
+ export const DAYJS_LOCALE_MAP: Record<string, string> = {
40
+ "zh-CN": "zh-cn",
41
+ "en-US": "en",
42
+ "es-ES": "es",
43
+ "fr-FR": "fr",
44
+ "ja-JP": "ja",
45
+ "ko-KR": "ko",
46
+ "zh-TW": "zh-tw",
47
+ };
48
+
49
+ export const ELEMENT_LOCALES = {
50
+ "zh-CN": elementLocaleZhCn,
51
+ "en-US": elementLocaleEnUs,
52
+ "es-ES": elementLocaleEsEs,
53
+ "fr-FR": elementLocaleFrFr,
54
+ "ja-JP": elementLocaleJaJp,
55
+ "ko-KR": elementLocaleKoKr,
56
+ "zh-TW": elementLocaleZhTw,
57
+ } as const;
@@ -0,0 +1,222 @@
1
+ /**
2
+ * 管理端国际化运行时:合并 core 和业务模块语言包,并为 Vue I18n、组件和请求层提供统一入口。
3
+ * 各语言 JSON 由对应模块定义文件导入,不能在 JSON 文件内添加注释。
4
+ */
5
+ import dayjs from "dayjs";
6
+ import { computed, readonly, ref } from "vue";
7
+ import { createI18n } from "vue-i18n";
8
+ import type { AdminModule } from "../modules";
9
+ import type { OptionLanguageResponse } from "../rpc/base/v1/language";
10
+ import {
11
+ DAYJS_LOCALE_MAP,
12
+ DEFAULT_LOCALE as GENERATED_DEFAULT_LOCALE,
13
+ SUPPORTED_LOCALES as GENERATED_SUPPORTED_LOCALES,
14
+ type GeneratedLocale,
15
+ } from "./generated";
16
+
17
+ /** 管理端已打包的语言区域;运行时可切换列表由 base_language 接口决定。 */
18
+ export const SUPPORTED_LOCALES = GENERATED_SUPPORTED_LOCALES;
19
+ /** 管理端支持的语言区域类型。 */
20
+ export type SupportedLocale = GeneratedLocale;
21
+ /** 单个模块的扁平语言包。 */
22
+ export type LocaleMessages = Record<string, string>;
23
+ /** 翻译插值参数。 */
24
+ export type LocaleParams = Record<string, string | number>;
25
+
26
+ /** 运行时语言选项。 */
27
+ export interface LocaleOption {
28
+ /** 标准语言代码。 */
29
+ language_code: SupportedLocale;
30
+ /** 本地语言名称。 */
31
+ native_name: string;
32
+ }
33
+
34
+ export const DEFAULT_LOCALE: SupportedLocale = GENERATED_DEFAULT_LOCALE;
35
+ export const LOCALE_STORAGE_KEY = "kratos-admin:locale";
36
+
37
+ const mutableLocale = ref<SupportedLocale>(DEFAULT_LOCALE);
38
+ const mutableLanguageOptions = ref<LocaleOption[]>([]);
39
+ const localeChangeHandlers = new Set<() => void | Promise<void>>();
40
+
41
+ /** 管理端 Vue I18n 实例。 */
42
+ export const adminI18n = createI18n({
43
+ legacy: false,
44
+ locale: DEFAULT_LOCALE,
45
+ fallbackLocale: DEFAULT_LOCALE,
46
+ messages: {},
47
+ missingWarn: false,
48
+ fallbackWarn: false
49
+ });
50
+
51
+ /** 规范化任意语言输入到管理端白名单。 */
52
+ export function normalizeLocale(value?: string): SupportedLocale {
53
+ return parseSupportedLocale(value) ?? DEFAULT_LOCALE;
54
+ }
55
+
56
+ /** 将接口或系统语言代码解析为已打包的语言区域。 */
57
+ function parseSupportedLocale(value?: string): SupportedLocale | undefined {
58
+ const normalized = String(value ?? "").replace("_", "-").toLowerCase();
59
+ if (!normalized) return undefined;
60
+ const alias = normalized.startsWith("zh-hk") || normalized.startsWith("zh-mo") ? "zh-tw" : normalized;
61
+ const exact = SUPPORTED_LOCALES.find(locale => locale.toLowerCase() === alias);
62
+ if (exact) return exact;
63
+ const language = alias.split("-", 1)[0];
64
+ return SUPPORTED_LOCALES.find(locale => locale.toLowerCase().split("-", 1)[0] === language);
65
+ }
66
+
67
+ /** 注册模块语言包并校验语言键、占位符和命名空间。 */
68
+ export function registerLocaleMessages(modules: AdminModule[]): void {
69
+ const merged = new Map<SupportedLocale, LocaleMessages>(SUPPORTED_LOCALES.map(locale => [locale, {}]));
70
+
71
+ modules.forEach(module => {
72
+ if (!module.messages) return;
73
+ const expectedKeys = requiredLocaleKeys(module.messages[DEFAULT_LOCALE] ?? {});
74
+ SUPPORTED_LOCALES.forEach(locale => {
75
+ const messages = module.messages?.[locale];
76
+ if (!messages) throw new Error(`${module.name} 缺少 ${locale} 语言包`);
77
+ const keys = requiredLocaleKeys(messages);
78
+ if (keys.join("\u0000") !== expectedKeys.join("\u0000")) {
79
+ throw new Error(`${module.name} 的 ${locale} 语言包键集合不一致`);
80
+ }
81
+
82
+ const target = merged.get(locale) as LocaleMessages;
83
+ Object.keys(messages).forEach(key => {
84
+ assertLocaleKeyNamespace(module.name, key);
85
+ if (Object.prototype.hasOwnProperty.call(target, key)) {
86
+ throw new Error(`${locale} 语言键重复: ${key}`);
87
+ }
88
+ assertLocalePlaceholders(module.name, key, messages[key], module.messages?.[DEFAULT_LOCALE]?.[key] ?? "");
89
+ target[key] = messages[key];
90
+ });
91
+ });
92
+ });
93
+
94
+ SUPPORTED_LOCALES.forEach(locale => adminI18n.global.setLocaleMessage(locale, merged.get(locale) ?? {}));
95
+ }
96
+
97
+ /** 初始化持久化语言偏好并同步日期库。 */
98
+ export function initializeLocale(): SupportedLocale {
99
+ const stored = window.localStorage.getItem(LOCALE_STORAGE_KEY) ?? "";
100
+ const preferred = stored || window.navigator.languages?.[0] || window.navigator.language;
101
+ applyLocale(normalizeLocale(preferred));
102
+ return mutableLocale.value;
103
+ }
104
+
105
+ /** 应用后端语言配置,并在当前语言不可用时回退到接口第一项。 */
106
+ export function applyLanguageConfig(response: OptionLanguageResponse): void {
107
+ const options = response.languages.reduce<LocaleOption[]>((items, item) => {
108
+ const languageCode = parseSupportedLocale(item.language_code);
109
+ if (!languageCode || items.some((option) => option.language_code === languageCode)) return items;
110
+ items.push({
111
+ language_code: languageCode,
112
+ native_name: item.native_name || languageCode,
113
+ });
114
+ return items;
115
+ }, []);
116
+ mutableLanguageOptions.value = options.length ? options : getFallbackLanguageOptions();
117
+ const availableLocales = getSupportedLocales();
118
+ if (!availableLocales.includes(mutableLocale.value)) {
119
+ applyLocale(availableLocales[0] ?? DEFAULT_LOCALE);
120
+ }
121
+ }
122
+
123
+ /** 获取当前接口配置的语言选项。 */
124
+ export function getLanguageOptions(): LocaleOption[] {
125
+ return mutableLanguageOptions.value.length ? mutableLanguageOptions.value : getFallbackLanguageOptions();
126
+ }
127
+
128
+ /** 获取当前可切换的语言区域。 */
129
+ export function getSupportedLocales(): SupportedLocale[] {
130
+ return getLanguageOptions().map((item) => item.language_code);
131
+ }
132
+
133
+ /** 获取当前规范语言区域。 */
134
+ export function getCurrentLocale(): SupportedLocale {
135
+ return mutableLocale.value;
136
+ }
137
+
138
+ /** 获取非 Axios 请求统一使用的语言头。 */
139
+ export function getLocaleRequestHeaders(): Record<"Accept-Language", SupportedLocale> {
140
+ return { "Accept-Language": getCurrentLocale() };
141
+ }
142
+
143
+ /** 切换语言并刷新动态本地化数据。 */
144
+ export async function setCurrentLocale(value: SupportedLocale): Promise<void> {
145
+ const locale = normalizeLocale(value);
146
+ if (!getSupportedLocales().includes(locale)) return;
147
+ if (locale === mutableLocale.value) return;
148
+ applyLocale(locale);
149
+ window.localStorage.setItem(LOCALE_STORAGE_KEY, locale);
150
+ for (const handler of localeChangeHandlers) await handler();
151
+ }
152
+
153
+ /** 注册语言切换后的动态数据刷新处理器。 */
154
+ export function registerLocaleChangeHandler(handler: () => void | Promise<void>): () => void {
155
+ localeChangeHandlers.add(handler);
156
+ return () => localeChangeHandlers.delete(handler);
157
+ }
158
+
159
+ /** 在非组件代码中翻译稳定语言键。 */
160
+ export function t(key: string, params: LocaleParams = {}): string {
161
+ return String(adminI18n.global.t(key, params));
162
+ }
163
+
164
+ /** 管理端响应式语言状态。 */
165
+ export function useLocaleStore() {
166
+ return {
167
+ locale: readonly(mutableLocale),
168
+ localeIndex: computed(() => Math.max(0, getSupportedLocales().indexOf(mutableLocale.value))),
169
+ languageOptions: computed(() => getLanguageOptions()),
170
+ supportedLocales: computed(() => getSupportedLocales()),
171
+ setLocale: setCurrentLocale,
172
+ t
173
+ };
174
+ }
175
+
176
+ function getFallbackLanguageOptions(): LocaleOption[] {
177
+ return SUPPORTED_LOCALES.map(languageCode => {
178
+ return {
179
+ language_code: languageCode,
180
+ native_name: fallbackNativeLanguageName(languageCode),
181
+ };
182
+ });
183
+ }
184
+
185
+ function fallbackNativeLanguageName(languageCode: SupportedLocale): string {
186
+ return {
187
+ "zh-CN": "简体中文",
188
+ "zh-TW": "繁體中文",
189
+ "en-US": "English",
190
+ "ja-JP": "日本語",
191
+ "ko-KR": "한국어",
192
+ "fr-FR": "Français",
193
+ "es-ES": "Español",
194
+ }[languageCode];
195
+ }
196
+
197
+ function applyLocale(locale: SupportedLocale): void {
198
+ mutableLocale.value = locale;
199
+ adminI18n.global.locale.value = locale;
200
+ const dayjsLocale = DAYJS_LOCALE_MAP[locale];
201
+ if (dayjsLocale) dayjs.locale(dayjsLocale);
202
+ document.documentElement.lang = locale;
203
+ }
204
+
205
+ function assertLocaleKeyNamespace(moduleName: string, key: string): void {
206
+ const valid =
207
+ moduleName === "kratos-admin" ? key.startsWith("common.") || key.startsWith("core.") : key.startsWith(`${moduleName}.`);
208
+ if (!valid) throw new Error(`${moduleName} 的语言键命名空间无效: ${key}`);
209
+ }
210
+
211
+ function requiredLocaleKeys(messages: LocaleMessages): string[] {
212
+ return Object.keys(messages)
213
+ .filter(key => !key.startsWith("common.language."))
214
+ .sort();
215
+ }
216
+
217
+ function assertLocalePlaceholders(moduleName: string, key: string, message: string, sourceMessage: string): void {
218
+ const placeholders = (value: string) => [...value.matchAll(/\{([A-Za-z0-9_]+)\}/g)].map(match => match[1]).sort();
219
+ if (placeholders(message).join("\u0000") !== placeholders(sourceMessage).join("\u0000")) {
220
+ throw new Error(`${moduleName} 的 ${key} 占位符集合不一致`);
221
+ }
222
+ }