@liujitcn/kratos-uni-app-core 0.0.21 → 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.
@@ -5,10 +5,8 @@
5
5
  "common.action.login": "登入",
6
6
  "common.action.logout": "退出登入",
7
7
  "common.action.new": "新建",
8
- "common.action.openInNewWindow": "新視窗開啟",
9
- "common.action.retry": "重試",
8
+ "common.action.open_in_new_window": "新視窗開啟",
10
9
  "common.action.save": "儲存",
11
- "common.action.search": "搜尋",
12
10
  "common.field.language": "語言",
13
11
  "common.language.en-US": "English",
14
12
  "common.language.ja-JP": "日本語",
@@ -18,93 +16,92 @@
18
16
  "common.language.fr-FR": "法語",
19
17
  "common.language.es-ES": "西班牙語",
20
18
  "common.message.loading": "正在載入",
21
- "common.message.networkError": "網路錯誤,換個網路試試",
22
- "common.message.requestError": "請求錯誤",
19
+ "common.message.network_error": "網路錯誤,換個網路試試",
20
+ "common.message.request_error": "請求錯誤",
23
21
  "common.message.unknown": "暫時無法處理,請稍後重試",
24
22
  "common.title.notice": "提示",
25
- "core.auth.loginAgain": "重新登入",
26
- "core.auth.sessionExpired": "當前頁面已失效,請重新登入",
23
+ "core.auth.login_again": "重新登入",
24
+ "core.auth.session_expired": "當前頁面已失效,請重新登入",
27
25
  "core.config.missing": "移動端配置缺失:{names}",
28
- "core.crypto.base64DecodeUnsupported": "當前環境不支援 Base64 解碼",
29
- "core.crypto.base64EncodeUnsupported": "當前環境不支援 Base64 編碼",
30
- "core.crypto.encryptFailed": "密碼加密失敗",
31
- "core.crypto.passwordRequired": "密碼不能為空",
32
- "core.crypto.passwordTooLong": "密碼長度超出限制",
33
- "core.crypto.publicKeyInvalid": "公鑰格式無效",
34
- "core.crypto.randomFailed": "隨機數生成失敗",
26
+ "core.crypto.base64_decode_unsupported": "當前環境不支援 Base64 解碼",
27
+ "core.crypto.base64_encode_unsupported": "當前環境不支援 Base64 編碼",
28
+ "core.crypto.encrypt_failed": "密碼加密失敗",
29
+ "core.crypto.password_required": "密碼不能為空",
30
+ "core.crypto.password_too_long": "密碼長度超出限制",
31
+ "core.crypto.public_key_invalid": "公鑰格式無效",
32
+ "core.crypto.random_failed": "隨機數生成失敗",
35
33
  "core.crypto.unsupported": "當前環境不支援密碼加密",
36
- "core.file.uploadFailed": "上傳失敗",
37
- "core.home.accountCapability": "賬戶能力",
38
- "core.home.accountCapabilityDescription": "個人資料、應用設定與智慧助手入口已保留",
39
- "core.home.crossPlatform": "跨端頁面",
40
- "core.home.crossPlatformDescription": "同一套頁面程式碼適配 H5 和微信小程式",
41
- "core.home.demoScope": "演示範圍",
34
+ "core.file.upload_failed": "上傳失敗",
35
+ "core.home.account_capability": "賬戶能力",
36
+ "core.home.account_capability_description": "個人資料、應用設定與智慧助手入口已保留",
37
+ "core.home.cross_platform": "跨端頁面",
38
+ "core.home.cross_platform_description": "同一套頁面程式碼適配 H5 和微信小程式",
39
+ "core.home.demo_scope": "演示範圍",
42
40
  "core.home.framework": "應用框架",
43
41
  "core.home.language": "開發語言",
44
- "core.home.mainTitle": "應用框架示例",
45
- "core.home.stateManagement": "狀態管理",
46
- "core.home.staticHome": "靜態首頁",
47
- "core.home.staticHomeDescription": "當前首頁用於展示框架資訊,不依賴業務介面",
48
- "core.home.styleSolution": "樣式方案",
49
- "core.home.subTitle": "保留通用導航與個人中心體驗",
50
- "core.home.techStack": "當前技術棧",
51
- "core.login.agreePrefix": "我已閱讀並同意",
52
- "core.login.agreeSeparator": "和",
53
- "core.login.behaviorClick": "請按順序點選文字",
54
- "core.login.behaviorLoading": "載入中...",
55
- "core.login.behaviorPuzzle": "請拖動滑塊完成拼圖",
56
- "core.login.behaviorRotate": "拖動滑塊,將內圈圖片轉正",
57
- "core.login.bindWechat": "登入並繫結微信",
42
+ "core.home.main_title": "應用框架示例",
43
+ "core.home.state_management": "狀態管理",
44
+ "core.home.static_home": "靜態首頁",
45
+ "core.home.static_home_description": "當前首頁用於展示框架資訊,不依賴業務介面",
46
+ "core.home.style_solution": "樣式方案",
47
+ "core.home.sub_title": "保留通用導航與個人中心體驗",
48
+ "core.home.tech_stack": "當前技術棧",
49
+ "core.login.agree_prefix": "我已閱讀並同意",
50
+ "core.login.agree_separator": "和",
51
+ "core.login.behavior_click": "請按順序點選文字",
52
+ "core.login.behavior_loading": "載入中...",
53
+ "core.login.behavior_puzzle": "請拖動滑塊完成拼圖",
54
+ "core.login.behavior_rotate": "拖動滑塊,將內圈圖片轉正",
55
+ "core.login.bind_wechat": "登入並繫結微信",
58
56
  "core.login.captcha": "請輸入驗證碼",
59
- "core.login.captchaLoadFailed": "驗證碼載入失敗",
60
- "core.login.captchaTypeMissing": "登入驗證碼型別未配置",
61
- "core.login.captchaTypeName": "登入驗證碼型別",
62
- "core.login.captchaTypeResponseMissing": "驗證碼介面未返回型別",
63
- "core.login.captchaWriteFailed": "驗證碼圖片寫入失敗",
64
- "core.login.defaultSubTitle": "歡迎使用本應用",
65
- "core.login.loginFailed": "登入失敗,請重試",
66
- "core.login.loginSuccess": "登入成功",
57
+ "core.login.captcha_load_failed": "驗證碼載入失敗",
58
+ "core.login.captcha_type_missing": "登入驗證碼型別未配置",
59
+ "core.login.captcha_type_name": "登入驗證碼型別",
60
+ "core.login.captcha_type_response_missing": "驗證碼介面未返回型別",
61
+ "core.login.captcha_write_failed": "驗證碼圖片寫入失敗",
62
+ "core.login.default_sub_title": "歡迎使用本應用",
63
+ "core.login.login_success": "登入成功",
67
64
  "core.login.password": "請輸入密碼",
68
65
  "core.login.privacy": "《隱私協議》",
69
- "core.login.protocolMissing": "服務條款和隱私協議未配置",
70
- "core.login.protocolPrompt": "請先閱讀並勾選協議內容,點選確定後將自動勾選並繼續登入",
66
+ "core.login.protocol_missing": "服務條款和隱私協議未配置",
67
+ "core.login.protocol_prompt": "請先閱讀並勾選協議內容,點選確定後將自動勾選並繼續登入",
71
68
  "core.login.service": "《服務條款》",
72
69
  "core.login.tenant": "請輸入租戶編號",
73
- "core.login.userName": "請輸入使用者名稱或手機號",
74
- "core.login.userNameMobile": "請輸入使用者名稱/手機號碼",
75
- "core.login.userNamePassword": "請輸入使用者名稱和密碼",
70
+ "core.login.user_name": "請輸入使用者名稱或手機號",
71
+ "core.login.user_name_mobile": "請輸入使用者名稱/手機號碼",
72
+ "core.login.user_name_password": "請輸入使用者名稱和密碼",
76
73
  "core.login.wechat": "微信一鍵登入",
77
- "core.login.wechatBindTip": "該微信尚未繫結,請登入已有賬號完成繫結",
78
- "core.login.wechatFailed": "微信登入失敗,請稍後重試",
74
+ "core.login.wechat_bind_tip": "該微信尚未繫結,請登入已有賬號完成繫結",
75
+ "core.login.wechat_failed": "微信登入失敗,請稍後重試",
79
76
  "core.navigation.home": "首頁",
80
77
  "core.navigation.error.access": "選單訪問模式無效:{access}",
81
- "core.navigation.error.childTab": "只有移動端二級選單可以作為 tab:{name}",
78
+ "core.navigation.error.child_tab": "只有移動端二級選單可以作為 tab:{name}",
82
79
  "core.navigation.error.cycle": "移動端選單存在迴圈父級:{name}",
83
80
  "core.navigation.error.identity": "選單 id、name 或 app/ 路徑無效",
84
- "core.navigation.error.itemObject": "選單項不是物件",
85
- "core.navigation.error.listMissing": "選單響應缺少扁平列表",
86
- "core.navigation.error.namePrefix": "選單名稱必須使用 App 字首:{name}",
87
- "core.navigation.error.parentInvalid": "移動端選單父級編號無效:{name}",
88
- "core.navigation.error.parentMissing": "選單缺少父級編號:{name}",
89
- "core.navigation.error.parentNotFound": "移動端選單父級不存在:{name}",
90
- "core.navigation.error.responseObject": "選單響應不是物件",
91
- "core.navigation.error.rootTab": "移動端二級選單必須作為 tab:{name}",
92
- "core.navigation.error.tabCount": "tabBar 只能配置 0 或 2-5 項",
81
+ "core.navigation.error.item_object": "選單項不是物件",
82
+ "core.navigation.error.list_missing": "選單響應缺少扁平列表",
83
+ "core.navigation.error.name_prefix": "選單名稱必須使用 App 字首:{name}",
84
+ "core.navigation.error.parent_invalid": "移動端選單父級編號無效:{name}",
85
+ "core.navigation.error.parent_missing": "選單缺少父級編號:{name}",
86
+ "core.navigation.error.parent_not_found": "移動端選單父級不存在:{name}",
87
+ "core.navigation.error.response_object": "選單響應不是物件",
88
+ "core.navigation.error.root_tab": "移動端二級選單必須作為 tab:{name}",
89
+ "core.navigation.error.tab_count": "tabBar 只能配置 0 或 2-5 項",
93
90
  "core.navigation.error.unique": "選單 id、name、path 必須唯一",
94
- "core.navigation.error.viewKey": "未註冊 viewKey:{viewKey}",
91
+ "core.navigation.error.view_key": "未註冊 viewKey:{viewKey}",
95
92
  "core.navigation.my": "我的",
96
93
  "core.navigation.protocol": "協議詳情",
97
- "core.protocol.loadFailed": "移動端配置載入失敗",
98
- "core.protocol.notConfigured": "{title}未配置,暫時無法檢視",
94
+ "core.protocol.load_failed": "移動端配置載入失敗",
95
+ "core.protocol.not_configured": "{title}未配置,暫時無法檢視",
99
96
  "core.protocol.privacy": "隱私協議",
100
97
  "core.protocol.service": "服務條款",
101
98
  "core.status.CONFIG_ERROR": "導航配置無效",
102
- "core.status.FORBIDDEN": "暫無訪問許可權",
99
+ "core.status.forbidden": "暫無訪問許可權",
103
100
  "core.status.NOT_FOUND": "頁面不存在",
104
- "core.status.OFFLINE": "網路不可用",
105
- "core.status.PAGE_UNAVAILABLE": "頁面暫不可用",
101
+ "core.status.offline": "網路不可用",
102
+ "core.status.page_unavailable": "頁面暫不可用",
106
103
  "core.status.loading": "正在載入",
107
- "core.webview.embedBlocked": "當前 H5 頁面可能被目標站點限制嵌入",
108
- "core.webview.invalidUrl": "缺少有效連結地址",
109
- "core.webview.openFailed": "連結無法開啟"
104
+ "core.webview.embed_blocked": "當前 H5 頁面可能被目標站點限制嵌入",
105
+ "core.webview.invalid_url": "缺少有效連結地址",
106
+ "core.webview.open_failed": "連結無法開啟"
110
107
  }
package/src/module.ts CHANGED
@@ -1,14 +1,8 @@
1
1
  import { corePages } from './pages'
2
2
  import type { LocaleMessages, SupportedLocale } from './locales'
3
3
 
4
- // Core 语言包随 coreModule 注册,供 uni-app 公共页面、请求工具和基础组件使用。
5
- import coreEnUS from './locales/en-US.json'
6
- import coreJaJP from './locales/ja-JP.json'
7
- import coreZhCN from './locales/zh-CN.json'
8
- import coreZhTW from './locales/zh-TW.json'
9
- import coreKoKR from './locales/ko-KR.json'
10
- import coreFrFR from './locales/fr-FR.json'
11
- import coreEsES from './locales/es-ES.json'
4
+ // Core 语言包由同步脚本生成并注册,供 uni-app 公共页面、请求工具和基础组件使用。
5
+ import { LOCALE_MESSAGES } from './locales/generated'
12
6
 
13
7
  /** bootstrap 可见状态键。 */
14
8
  export type BootstrapViewKey =
@@ -94,13 +88,5 @@ export const coreModule = defineKratosAppModule({
94
88
  USER_DEFAULT: 'static/tabs/user_default.png',
95
89
  USER_SELECTED: 'static/tabs/user_selected.png',
96
90
  },
97
- messages: {
98
- 'zh-CN': coreZhCN,
99
- 'zh-TW': coreZhTW,
100
- 'ko-KR': coreKoKR,
101
- 'fr-FR': coreFrFR,
102
- 'es-ES': coreEsES,
103
- 'en-US': coreEnUS,
104
- 'ja-JP': coreJaJP,
105
- },
91
+ messages: LOCALE_MESSAGES,
106
92
  })
package/src/navigation.ts CHANGED
@@ -117,7 +117,7 @@ const createDefaultMenus = (): AppMenu[] => [
117
117
  name: 'AppAi',
118
118
  path: 'app/ai',
119
119
  viewKey: 'AI',
120
- title: t('system.ai.chatTitle'),
120
+ title: t('system.ai.chat_title'),
121
121
  access: 'AUTHENTICATED',
122
122
  inTabBar: false,
123
123
  },
@@ -135,6 +135,7 @@ const createDefaultMenus = (): AppMenu[] => [
135
135
 
136
136
  const menus = ref<AppMenu[]>([])
137
137
  const ready = ref(false)
138
+ let tabNavigationTarget: string | undefined
138
139
  let adapter: AppNavigationAdapter = {
139
140
  list: () => defBaseMenuService.ListBaseMenu(),
140
141
  }
@@ -208,13 +209,31 @@ export function navigateAppRoute(rawRoute: string, options: { replace?: boolean
208
209
  .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
209
210
  .join('&')
210
211
  const url = `/${resolved.physicalRoute}${query ? `?${query}` : ''}`
211
- if (options.replace || resolved.menu.inTabBar) {
212
+ if (resolved.menu.inTabBar) {
213
+ navigateTabRoute(url)
214
+ return
215
+ }
216
+ if (options.replace) {
212
217
  uni.reLaunch({ url })
213
218
  return
214
219
  }
215
220
  uni.navigateTo({ url, fail: () => uni.reLaunch({ url }) })
216
221
  }
217
222
 
223
+ /** 切换 tab 页面,避免当前页重复跳转和并发重建页面栈。 */
224
+ function navigateTabRoute(url: string): void {
225
+ const targetRoute = url.slice(1).split('?', 1)[0]
226
+ const pages = getCurrentPages()
227
+ const currentPage = pages[pages.length - 1]
228
+ if (currentPage?.route === targetRoute || tabNavigationTarget) return
229
+
230
+ tabNavigationTarget = targetRoute
231
+ const release = () => {
232
+ if (tabNavigationTarget === targetRoute) tabNavigationTarget = undefined
233
+ }
234
+ uni.reLaunch({ url, success: release, fail: release, complete: release })
235
+ }
236
+
218
237
  /** 获取导航响应式状态。 */
219
238
  export function useAppNavigation() {
220
239
  const menuTree = computed<AppMenuNode[]>(() => buildMenuTree(menus.value, APP_MENU_ROOT_ID))
@@ -255,15 +274,15 @@ function readCachedMenus(cacheKey: string): AppMenu[] | undefined {
255
274
  function normalizeMenuResponse(response: unknown): AppMenu[] {
256
275
  if (Array.isArray(response)) return response.map(normalizeMenu)
257
276
  if (!response || typeof response !== 'object')
258
- throw new Error(t('core.navigation.error.responseObject'))
277
+ throw new Error(t('core.navigation.error.response_object'))
259
278
  const record = response as Record<string, unknown>
260
279
  const list = record.items ?? record.list ?? record.data
261
- if (!Array.isArray(list)) throw new Error(t('core.navigation.error.listMissing'))
280
+ if (!Array.isArray(list)) throw new Error(t('core.navigation.error.list_missing'))
262
281
  return list.map(normalizeMenu)
263
282
  }
264
283
 
265
284
  function normalizeMenu(value: unknown): AppMenu {
266
- if (!value || typeof value !== 'object') throw new Error(t('core.navigation.error.itemObject'))
285
+ if (!value || typeof value !== 'object') throw new Error(t('core.navigation.error.item_object'))
267
286
  const item = value as Record<string, unknown>
268
287
  const meta = (item.meta ?? {}) as Record<string, unknown>
269
288
  const app = (meta.app ?? item.app ?? {}) as Record<string, unknown>
@@ -298,13 +317,13 @@ function validateMenus(nextMenus: AppMenu[]): void {
298
317
  throw new Error(t('core.navigation.error.identity'))
299
318
  }
300
319
  if (!menu.name.startsWith('App')) {
301
- throw new Error(t('core.navigation.error.namePrefix', { name: menu.name }))
320
+ throw new Error(t('core.navigation.error.name_prefix', { name: menu.name }))
302
321
  }
303
322
  if (!['PUBLIC', 'GUEST_ONLY', 'AUTHENTICATED'].includes(menu.access)) {
304
323
  throw new Error(t('core.navigation.error.access', { access: menu.access }))
305
324
  }
306
325
  if (!resolveStaticView(menu.viewKey)) {
307
- throw new Error(t('core.navigation.error.viewKey', { viewKey: menu.viewKey }))
326
+ throw new Error(t('core.navigation.error.view_key', { viewKey: menu.viewKey }))
308
327
  }
309
328
  if (ids.has(menu.id) || names.has(menu.name) || paths.has(menu.path)) {
310
329
  throw new Error(t('core.navigation.error.unique'))
@@ -316,13 +335,13 @@ function validateMenus(nextMenus: AppMenu[]): void {
316
335
  const menuMap = new Map(nextMenus.map((menu) => [menu.id, menu]))
317
336
  for (const menu of nextMenus) {
318
337
  if (menu.parentId === undefined) {
319
- throw new Error(t('core.navigation.error.parentMissing', { name: menu.name }))
338
+ throw new Error(t('core.navigation.error.parent_missing', { name: menu.name }))
320
339
  }
321
340
  if (menu.parentId === APP_MENU_ROOT_ID) {
322
- if (!menu.inTabBar) throw new Error(t('core.navigation.error.rootTab', { name: menu.name }))
341
+ if (!menu.inTabBar) throw new Error(t('core.navigation.error.root_tab', { name: menu.name }))
323
342
  continue
324
343
  }
325
- if (menu.inTabBar) throw new Error(t('core.navigation.error.childTab', { name: menu.name }))
344
+ if (menu.inTabBar) throw new Error(t('core.navigation.error.child_tab', { name: menu.name }))
326
345
  const visited = new Set<number>([menu.id])
327
346
  let parentId = menu.parentId
328
347
  while (parentId !== APP_MENU_ROOT_ID) {
@@ -330,13 +349,13 @@ function validateMenus(nextMenus: AppMenu[]): void {
330
349
  throw new Error(t('core.navigation.error.cycle', { name: menu.name }))
331
350
  visited.add(parentId)
332
351
  const parent = menuMap.get(parentId)
333
- if (!parent) throw new Error(t('core.navigation.error.parentNotFound', { name: menu.name }))
352
+ if (!parent) throw new Error(t('core.navigation.error.parent_not_found', { name: menu.name }))
334
353
  if (parent.parentId === undefined) {
335
- throw new Error(t('core.navigation.error.parentInvalid', { name: menu.name }))
354
+ throw new Error(t('core.navigation.error.parent_invalid', { name: menu.name }))
336
355
  }
337
356
  parentId = parent.parentId
338
357
  }
339
358
  }
340
359
  const tabCount = nextMenus.filter((menu) => menu.parentId === APP_MENU_ROOT_ID).length
341
- if (tabCount === 1 || tabCount > 5) throw new Error(t('core.navigation.error.tabCount'))
360
+ if (tabCount === 1 || tabCount > 5) throw new Error(t('core.navigation.error.tab_count'))
342
361
  }
@@ -5,7 +5,18 @@
5
5
  // source: base/v1/config.proto
6
6
 
7
7
  /* eslint-disable */
8
- import type { BaseConfigSite } from "./enum";
8
+
9
+ /** 系统配置位置。 */
10
+ export enum BaseConfigSite {
11
+ /** BASE_CONFIG_SITE_UNSPECIFIED - 未指定系统配置位置。 */
12
+ BASE_CONFIG_SITE_UNSPECIFIED = 0,
13
+ /** BASE_CONFIG_SITE_SYSTEM - 系统内使用。 */
14
+ BASE_CONFIG_SITE_SYSTEM = 1,
15
+ /** BASE_CONFIG_SITE_ADMIN - 管理端。 */
16
+ BASE_CONFIG_SITE_ADMIN = 2,
17
+ /** BASE_CONFIG_SITE_APP - 移动端。 */
18
+ BASE_CONFIG_SITE_APP = 3,
19
+ }
9
20
 
10
21
  /** 获取系统配置条件 */
11
22
  export interface GetConfigRequest {
@@ -6,32 +6,26 @@
6
6
 
7
7
  /* eslint-disable */
8
8
 
9
- /** 查询语言请求参数。 */
10
- export interface GetLanguageRequest {
9
+ /** 查询语言选项请求参数。 */
10
+ export interface OptionLanguageRequest {
11
11
  }
12
12
 
13
- /** 支持的语言。 */
13
+ /** 语言选择项。 */
14
14
  export interface LanguageItem {
15
15
  /** 标准语言代码 */
16
16
  language_code: string;
17
- /** 语言名称 */
18
- language_name: string;
19
17
  /** 本地语言名称 */
20
18
  native_name: string;
21
- /** 排序,值越小越靠前 */
22
- sort: number;
23
19
  }
24
20
 
25
- /** 当前支持的语言查询结果。 */
26
- export interface GetLanguageResponse {
21
+ /** 当前支持的语言选项查询结果。 */
22
+ export interface OptionLanguageResponse {
27
23
  /** 当前支持的语言列表 */
28
24
  languages: LanguageItem[];
29
- /** 主语言代码 */
30
- primary_language_code: string;
31
25
  }
32
26
 
33
27
  /** 语言公共服务。 */
34
28
  export interface LanguageService {
35
- /** 查询当前支持的语言和主语言。 */
36
- GetLanguage(request: GetLanguageRequest): Promise<GetLanguageResponse>;
29
+ /** 查询当前支持的语言选项。 */
30
+ OptionLanguage(request: OptionLanguageRequest): Promise<OptionLanguageResponse>;
37
31
  }
@@ -7,7 +7,20 @@
7
7
  /* eslint-disable */
8
8
  import type { PasswordCrypto } from "../../common/v1/types";
9
9
  import type { Empty } from "../../google/protobuf/empty";
10
- import type { PasswordCryptoScene } from "./enum";
10
+
11
+ /** 密码加密场景枚举。 */
12
+ export enum PasswordCryptoScene {
13
+ /** PASSWORD_CRYPTO_SCENE_UNSPECIFIED - 未指定密码加密场景。 */
14
+ PASSWORD_CRYPTO_SCENE_UNSPECIFIED = 0,
15
+ /** PASSWORD_CRYPTO_SCENE_LOGIN - 登录密码加密场景。 */
16
+ PASSWORD_CRYPTO_SCENE_LOGIN = 1,
17
+ /** PASSWORD_CRYPTO_SCENE_CREATE_BASE_USER - 新增后台用户密码加密场景。 */
18
+ PASSWORD_CRYPTO_SCENE_CREATE_BASE_USER = 2,
19
+ /** PASSWORD_CRYPTO_SCENE_RESET_BASE_USER_PASSWORD - 重置后台用户密码加密场景。 */
20
+ PASSWORD_CRYPTO_SCENE_RESET_BASE_USER_PASSWORD = 3,
21
+ /** PASSWORD_CRYPTO_SCENE_UPDATE_USER_PASSWORD - 个人修改密码加密场景。 */
22
+ PASSWORD_CRYPTO_SCENE_UPDATE_USER_PASSWORD = 4,
23
+ }
11
24
 
12
25
  /** 验证码获取条件 */
13
26
  export interface CaptchaRequest {
@@ -1,13 +1,13 @@
1
1
  import { defConfigService } from '../../api/base/config'
2
2
  import { defineStore } from 'pinia'
3
3
  import { ref } from 'vue'
4
- import { BaseConfigSite } from '../../rpc/base/v1/enum'
4
+ import { BaseConfigSite } from '../../rpc/base/v1/config'
5
5
  import { t } from '../../locales'
6
6
 
7
7
  const REQUIRED_APP_CONFIGS = [
8
8
  { key: 'serviceProtocol', nameKey: 'core.protocol.service' },
9
9
  { key: 'privacyProtocol', nameKey: 'core.protocol.privacy' },
10
- { key: 'captchaType', nameKey: 'core.login.captchaTypeName' },
10
+ { key: 'captchaType', nameKey: 'core.login.captcha_type_name' },
11
11
  ] as const
12
12
 
13
13
  export const useSettingStore = defineStore('setting', () => {
@@ -27,7 +27,7 @@ export const useSettingStore = defineStore('setting', () => {
27
27
 
28
28
  const request = (async () => {
29
29
  const res = await defConfigService.GetConfig({
30
- site: BaseConfigSite.APP,
30
+ site: BaseConfigSite.BASE_CONFIG_SITE_APP,
31
31
  })
32
32
  const nextData = new Map<string, string>()
33
33
  res.configs.forEach((item) => {
package/src/utils/file.ts CHANGED
@@ -22,7 +22,7 @@ export const uploadFile = async (fileType: string, filePath: string): Promise<Fi
22
22
  if (res.statusCode === 200) {
23
23
  return JSON.parse(res.data) as FileInfo
24
24
  } else {
25
- throw new Error(t('core.file.uploadFailed'))
25
+ throw new Error(t('core.file.upload_failed'))
26
26
  }
27
27
  }
28
28
 
@@ -58,7 +58,7 @@ export const multiUploadFile = async (fileType: string, files: any): Promise<Fil
58
58
  const data = JSON.parse(res.data) as MultiUploadFileResponse
59
59
  return data.files
60
60
  } else {
61
- await uni.showToast({ icon: 'error', title: t('core.file.uploadFailed') })
61
+ await uni.showToast({ icon: 'error', title: t('core.file.upload_failed') })
62
62
  return []
63
63
  }
64
64
  }
package/src/utils/http.ts CHANGED
@@ -224,7 +224,7 @@ export const http = <T>(options: HttpRequestOptions) => {
224
224
  // 其他错误 -> 根据后端错误信息轻提示
225
225
  void uni.showToast({
226
226
  icon: 'none',
227
- title: responseData.message || t('common.message.requestError'),
227
+ title: responseData.message || t('common.message.request_error'),
228
228
  })
229
229
  reject(res)
230
230
  }
@@ -233,7 +233,7 @@ export const http = <T>(options: HttpRequestOptions) => {
233
233
  fail(err) {
234
234
  void uni.showToast({
235
235
  icon: 'none',
236
- title: t('common.message.networkError'),
236
+ title: t('common.message.network_error'),
237
237
  })
238
238
  reject(err)
239
239
  },
@@ -384,9 +384,9 @@ async function promptRelogin() {
384
384
  try {
385
385
  const modalRes = await uni.showModal({
386
386
  title: t('common.title.notice'),
387
- content: t('core.auth.sessionExpired'),
387
+ content: t('core.auth.session_expired'),
388
388
  showCancel: false,
389
- confirmText: t('core.auth.loginAgain'),
389
+ confirmText: t('core.auth.login_again'),
390
390
  })
391
391
 
392
392
  if (!modalRes.confirm) {
@@ -411,7 +411,7 @@ function handleAuthExpiredByMode(authMode: AuthMode, url: string, responseData:
411
411
  if (authMode !== 'optional') {
412
412
  void uni.showToast({
413
413
  icon: 'none',
414
- title: responseData.message || t('common.message.requestError'),
414
+ title: responseData.message || t('common.message.request_error'),
415
415
  })
416
416
  }
417
417
  }
@@ -1,6 +1,6 @@
1
1
  import { defLoginService } from '../api/base/login'
2
2
  import { t } from '../locales'
3
- import { PasswordCryptoScene } from '../rpc/base/v1/enum'
3
+ import { PasswordCryptoScene } from '../rpc/base/v1/login'
4
4
  import type { PasswordCrypto } from '../rpc/common/v1/types'
5
5
 
6
6
  // #ifdef MP-WEIXIN
@@ -20,7 +20,7 @@ function pemToArrayBuffer(pem: string) {
20
20
  .replace(/\s/g, '')
21
21
  const decode = globalThis.atob
22
22
  if (!decode) {
23
- throw new Error(t('core.crypto.base64DecodeUnsupported'))
23
+ throw new Error(t('core.crypto.base64_decode_unsupported'))
24
24
  }
25
25
  const binary = decode(base64)
26
26
  const buffer = new Uint8Array(binary.length)
@@ -39,7 +39,7 @@ function arrayBufferToBase64(buffer: ArrayBuffer) {
39
39
  }
40
40
  const encode = globalThis.btoa
41
41
  if (!encode) {
42
- throw new Error(t('core.crypto.base64EncodeUnsupported'))
42
+ throw new Error(t('core.crypto.base64_encode_unsupported'))
43
43
  }
44
44
  return encode(binary)
45
45
  }
@@ -66,7 +66,7 @@ function getMiniRandomBytes(length: number) {
66
66
  resolve(randomValues)
67
67
  },
68
68
  fail: ({ errMsg }) => {
69
- reject(new Error(errMsg || t('core.crypto.randomFailed')))
69
+ reject(new Error(errMsg || t('core.crypto.random_failed')))
70
70
  },
71
71
  })
72
72
  })
@@ -81,7 +81,7 @@ type DerNode = {
81
81
  /** 读取 DER 编码节点,用于解析 RSA SubjectPublicKeyInfo。 */
82
82
  function readDerNode(data: Uint8Array, offset: number): DerNode {
83
83
  if (offset + 2 > data.length) {
84
- throw new Error(t('core.crypto.publicKeyInvalid'))
84
+ throw new Error(t('core.crypto.public_key_invalid'))
85
85
  }
86
86
  const tag = data[offset]
87
87
  const firstLengthByte = data[offset + 1]
@@ -90,7 +90,7 @@ function readDerNode(data: Uint8Array, offset: number): DerNode {
90
90
  if (firstLengthByte & 0x80) {
91
91
  const lengthByteCount = firstLengthByte & 0x7f
92
92
  if (lengthByteCount === 0 || valueOffset + lengthByteCount > data.length) {
93
- throw new Error(t('core.crypto.publicKeyInvalid'))
93
+ throw new Error(t('core.crypto.public_key_invalid'))
94
94
  }
95
95
  length = 0
96
96
  for (let index = 0; index < lengthByteCount; index += 1) {
@@ -100,7 +100,7 @@ function readDerNode(data: Uint8Array, offset: number): DerNode {
100
100
  }
101
101
  const end = valueOffset + length
102
102
  if (end > data.length) {
103
- throw new Error(t('core.crypto.publicKeyInvalid'))
103
+ throw new Error(t('core.crypto.public_key_invalid'))
104
104
  }
105
105
  return {
106
106
  tag,
@@ -129,13 +129,13 @@ function parseMiniRsaPublicKey(publicKey: string): [Uint8Array, Uint8Array] {
129
129
  const algorithm = readDerNode(subjectPublicKeyInfo.value, 0)
130
130
  const bitString = readDerNode(subjectPublicKeyInfo.value, algorithm.next)
131
131
  if (bitString.tag !== 0x03 || bitString.value[0] !== 0) {
132
- throw new Error(t('core.crypto.publicKeyInvalid'))
132
+ throw new Error(t('core.crypto.public_key_invalid'))
133
133
  }
134
134
  const rsaPublicKey = readDerNode(bitString.value, 1)
135
135
  const modulus = readDerNode(rsaPublicKey.value, 0)
136
136
  const exponent = readDerNode(rsaPublicKey.value, modulus.next)
137
137
  if (modulus.tag !== 0x02 || exponent.tag !== 0x02) {
138
- throw new Error(t('core.crypto.publicKeyInvalid'))
138
+ throw new Error(t('core.crypto.public_key_invalid'))
139
139
  }
140
140
  return [trimDerInteger(modulus.value), trimDerInteger(exponent.value)]
141
141
  }
@@ -153,7 +153,7 @@ function generateMgf1Mask(crypto: MiniCrypto, seed: Uint8Array, length: number)
153
153
  counter[3] = index
154
154
  let block = hash.reset().process(seed).process(counter).finish().result
155
155
  if (!block) {
156
- throw new Error(t('core.crypto.encryptFailed'))
156
+ throw new Error(t('core.crypto.encrypt_failed'))
157
157
  }
158
158
  const target = mask.subarray(index * hash.HASH_SIZE)
159
159
  if (block.length > target.length) {
@@ -190,14 +190,14 @@ async function encryptMiniProgramPassword(
190
190
  const dataBlockLength = keySize - hash.HASH_SIZE - 1
191
191
  const paddingLength = dataBlockLength - aesKey.length - hash.HASH_SIZE - 1
192
192
  if (paddingLength < 0) {
193
- throw new Error(t('core.crypto.passwordTooLong'))
193
+ throw new Error(t('core.crypto.password_too_long'))
194
194
  }
195
195
  const encodedMessage = new Uint8Array(keySize)
196
196
  const maskedSeed = encodedMessage.subarray(1, hash.HASH_SIZE + 1)
197
197
  const dataBlock = encodedMessage.subarray(hash.HASH_SIZE + 1)
198
198
  const labelHash = hash.reset().process(new Uint8Array()).finish().result
199
199
  if (!labelHash) {
200
- throw new Error(t('core.crypto.encryptFailed'))
200
+ throw new Error(t('core.crypto.encrypt_failed'))
201
201
  }
202
202
  dataBlock.set(labelHash, 0)
203
203
  dataBlock.set(aesKey, hash.HASH_SIZE + paddingLength + 1)
@@ -215,7 +215,7 @@ async function encryptMiniProgramPassword(
215
215
  new crypto.BigNumber(encodedMessage),
216
216
  ).result
217
217
  if (!encryptedKey) {
218
- throw new Error(t('core.crypto.encryptFailed'))
218
+ throw new Error(t('core.crypto.encrypt_failed'))
219
219
  }
220
220
  const ciphertext = crypto.AES_GCM.encrypt(plaintext, aesKey, iv)
221
221
  return {
@@ -235,7 +235,7 @@ export async function encryptPassword(
235
235
  ): Promise<PasswordCrypto> {
236
236
  const plainPassword = password.trim()
237
237
  if (!plainPassword) {
238
- throw new Error(t('core.crypto.passwordRequired'))
238
+ throw new Error(t('core.crypto.password_required'))
239
239
  }
240
240
 
241
241
  const publicKeyResponse = await defLoginService.PasswordPublicKey({ scene })