@liujitcn/kratos-taro-app-system 0.0.31 → 0.0.32
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.
- package/README.md +2 -2
- package/dist/build.mjs +6 -1
- package/dist/module.mjs +62 -1
- package/package.json +3 -3
- package/src/api/base/{ai_message.ts → v1/ai_message.ts} +2 -2
- package/src/api/base/{ai_session.ts → v1/ai_session.ts} +1 -1
- package/src/api/base/{ai_tool.ts → v1/ai_tool.ts} +1 -1
- package/src/api/base/{notification.ts → v1/notification.ts} +44 -4
- package/src/locales/en-US.json +14 -0
- package/src/locales/ja-JP.json +14 -0
- package/src/locales/zh-CN.json +14 -0
- package/src/locales/zh-TW.json +14 -0
- package/src/notification.ts +4 -1
- package/src/pages.ts +6 -1
- package/src/rpc/base/v1/notification.ts +28 -0
- package/src/views/pagesMember/ai/index.tsx +3 -3
- package/src/views/pagesMember/message/detail.tsx +30 -8
- package/src/views/pagesMember/message/icons.ts +26 -0
- package/src/views/pagesMember/message/index.tsx +89 -41
- package/src/views/pagesMember/message/message.scss +144 -46
- package/src/views/pagesMember/profile/profile.tsx +52 -5
- package/src/views/pagesMember/settings/components/PasswordVerifyDialog.tsx +1 -1
- package/src/views/pagesMember/settings/settings.tsx +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
| 页面 | 视图键 | 用途 |
|
|
8
8
|
| --- | --- | --- |
|
|
9
9
|
| `pages/my/my` | `PROFILE_HOME` | 我的 tab 与登录概览。 |
|
|
10
|
-
| `pagesMember/profile/profile` | `PROFILE` |
|
|
10
|
+
| `pagesMember/profile/profile` | `PROFILE` | 头像、昵称、性别、邮箱和证件资料。 |
|
|
11
11
|
| `pagesMember/settings/settings` | `SETTINGS` | MFA 状态、设置与退出登录。 |
|
|
12
12
|
| `pagesMember/ai/index` | `AI` | AI 会话、流式消息、附件和快捷入口。 |
|
|
13
13
|
|
|
@@ -21,7 +21,7 @@ AI 页面支持会话创建与切换、历史会话搜索、消息加载、附
|
|
|
21
21
|
|
|
22
22
|
## MFA
|
|
23
23
|
|
|
24
|
-
设置页通过 `@liujitcn/kratos-taro-app-core/api/base/mfa` 查询状态并发起绑定或禁用;页面私有的 `components/PasswordVerifyDialog.tsx` 提供 `setup`、`disable` 两种模式。未启用 MFA 时组件只显示密码输入,已启用 MFA 时在同一组件内同时完成密码和 MFA 校验,绑定成功展示一次性恢复码,禁用成功后清理会话并重新登录。
|
|
24
|
+
设置页通过 `@liujitcn/kratos-taro-app-core/api/base/v1/mfa` 查询状态并发起绑定或禁用;页面私有的 `components/PasswordVerifyDialog.tsx` 提供 `setup`、`disable` 两种模式。未启用 MFA 时组件只显示密码输入,已启用 MFA 时在同一组件内同时完成密码和 MFA 校验,绑定成功展示一次性恢复码,禁用成功后清理会话并重新登录。
|
|
25
25
|
|
|
26
26
|
## 验证
|
|
27
27
|
|
package/dist/build.mjs
CHANGED
|
@@ -26,7 +26,12 @@ var systemPages = {
|
|
|
26
26
|
navigationBarTitleText: ""
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
|
-
"pagesMember/message/index": {
|
|
29
|
+
"pagesMember/message/index": {
|
|
30
|
+
style: {
|
|
31
|
+
navigationStyle: "custom",
|
|
32
|
+
navigationBarTitleText: ""
|
|
33
|
+
}
|
|
34
|
+
},
|
|
30
35
|
"pagesMember/message/detail": { style: { navigationBarTitleText: "" } }
|
|
31
36
|
};
|
|
32
37
|
|
package/dist/module.mjs
CHANGED
|
@@ -24,7 +24,12 @@ var systemPages = {
|
|
|
24
24
|
navigationBarTitleText: ""
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
|
-
"pagesMember/message/index": {
|
|
27
|
+
"pagesMember/message/index": {
|
|
28
|
+
style: {
|
|
29
|
+
navigationStyle: "custom",
|
|
30
|
+
navigationBarTitleText: ""
|
|
31
|
+
}
|
|
32
|
+
},
|
|
28
33
|
"pagesMember/message/detail": { style: { navigationBarTitleText: "" } }
|
|
29
34
|
};
|
|
30
35
|
|
|
@@ -99,6 +104,20 @@ var zh_CN_default = {
|
|
|
99
104
|
"system.profile.avatar_upload_failed": "\u4E0A\u4F20\u5934\u50CF\u5931\u8D25",
|
|
100
105
|
"system.profile.avatar_update": "\u66F4\u65B0\u5934\u50CF\u6635\u79F0",
|
|
101
106
|
"system.profile.gender": "\u6027\u522B",
|
|
107
|
+
"system.profile.email": "\u90AE\u7BB1",
|
|
108
|
+
"system.profile.email_placeholder": "\u8BF7\u8F93\u5165\u90AE\u7BB1",
|
|
109
|
+
"system.profile.email_invalid": "\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u90AE\u7BB1",
|
|
110
|
+
"system.profile.id_type": "\u8BC1\u4EF6\u7C7B\u578B",
|
|
111
|
+
"system.profile.id_code": "\u8BC1\u4EF6\u53F7",
|
|
112
|
+
"system.profile.id_code_placeholder": "\u8BF7\u8F93\u5165\u8BC1\u4EF6\u53F7",
|
|
113
|
+
"system.profile.id_code_invalid": "\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u8BC1\u4EF6\u53F7",
|
|
114
|
+
"system.profile.id_type.unspecified": "\u672A\u6307\u5B9A",
|
|
115
|
+
"system.profile.id_type.id_card": "\u5C45\u6C11\u8EAB\u4EFD\u8BC1",
|
|
116
|
+
"system.profile.id_type.passport": "\u62A4\u7167",
|
|
117
|
+
"system.profile.id_type.hk_macao_permit": "\u6E2F\u6FB3\u5C45\u6C11\u6765\u5F80\u5185\u5730\u901A\u884C\u8BC1",
|
|
118
|
+
"system.profile.id_type.taiwan_permit": "\u53F0\u6E7E\u5C45\u6C11\u6765\u5F80\u5927\u9646\u901A\u884C\u8BC1",
|
|
119
|
+
"system.profile.id_type.foreign_permanent_residence": "\u5916\u56FD\u4EBA\u6C38\u4E45\u5C45\u7559\u8EAB\u4EFD\u8BC1",
|
|
120
|
+
"system.profile.id_type.other": "\u5176\u4ED6\u8BC1\u4EF6",
|
|
102
121
|
"system.profile.login_prompt": "\u70B9\u51FB\u767B\u5F55\u8D26\u53F7",
|
|
103
122
|
"system.profile.mobile": "\u624B\u673A\u53F7",
|
|
104
123
|
"system.profile.nick_name": "\u6635\u79F0",
|
|
@@ -216,6 +235,20 @@ var en_US_default = {
|
|
|
216
235
|
"system.profile.avatar_upload_failed": "Avatar upload failed",
|
|
217
236
|
"system.profile.avatar_update": "Update avatar and name",
|
|
218
237
|
"system.profile.gender": "Gender",
|
|
238
|
+
"system.profile.email": "Email",
|
|
239
|
+
"system.profile.email_placeholder": "Enter email",
|
|
240
|
+
"system.profile.email_invalid": "Enter a valid email",
|
|
241
|
+
"system.profile.id_type": "ID type",
|
|
242
|
+
"system.profile.id_code": "ID number",
|
|
243
|
+
"system.profile.id_code_placeholder": "Enter ID number",
|
|
244
|
+
"system.profile.id_code_invalid": "Enter a valid ID number",
|
|
245
|
+
"system.profile.id_type.unspecified": "Unspecified",
|
|
246
|
+
"system.profile.id_type.id_card": "Resident ID card",
|
|
247
|
+
"system.profile.id_type.passport": "Passport",
|
|
248
|
+
"system.profile.id_type.hk_macao_permit": "Mainland travel permit for Hong Kong/Macao residents",
|
|
249
|
+
"system.profile.id_type.taiwan_permit": "Mainland travel permit for Taiwan residents",
|
|
250
|
+
"system.profile.id_type.foreign_permanent_residence": "Foreign permanent residence ID",
|
|
251
|
+
"system.profile.id_type.other": "Other ID",
|
|
219
252
|
"system.profile.login_prompt": "Tap to log in",
|
|
220
253
|
"system.profile.mobile": "Mobile",
|
|
221
254
|
"system.profile.nick_name": "Nickname",
|
|
@@ -333,6 +366,20 @@ var ja_JP_default = {
|
|
|
333
366
|
"system.profile.avatar_upload_failed": "\u30A2\u30D0\u30BF\u30FC\u306E\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
|
|
334
367
|
"system.profile.avatar_update": "\u30A2\u30D0\u30BF\u30FC\u306E\u30CB\u30C3\u30AF\u30CD\u30FC\u30E0\u3092\u66F4\u65B0",
|
|
335
368
|
"system.profile.gender": "\u6027\u5225",
|
|
369
|
+
"system.profile.email": "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9",
|
|
370
|
+
"system.profile.email_placeholder": "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
371
|
+
"system.profile.email_invalid": "\u6B63\u3057\u3044\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
372
|
+
"system.profile.id_type": "\u8EAB\u5206\u8A3C\u660E\u66F8\u306E\u7A2E\u985E",
|
|
373
|
+
"system.profile.id_code": "\u8EAB\u5206\u8A3C\u660E\u66F8\u756A\u53F7",
|
|
374
|
+
"system.profile.id_code_placeholder": "\u8EAB\u5206\u8A3C\u660E\u66F8\u756A\u53F7\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
375
|
+
"system.profile.id_code_invalid": "\u6B63\u3057\u3044\u8EAB\u5206\u8A3C\u660E\u66F8\u756A\u53F7\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
376
|
+
"system.profile.id_type.unspecified": "\u672A\u6307\u5B9A",
|
|
377
|
+
"system.profile.id_type.id_card": "\u8EAB\u5206\u8A3C\u660E\u66F8",
|
|
378
|
+
"system.profile.id_type.passport": "\u30D1\u30B9\u30DD\u30FC\u30C8",
|
|
379
|
+
"system.profile.id_type.hk_macao_permit": "\u9999\u6E2F\u30FB\u30DE\u30AB\u30AA\u4F4F\u6C11\u5185\u5730\u901A\u884C\u8A3C",
|
|
380
|
+
"system.profile.id_type.taiwan_permit": "\u53F0\u6E7E\u4F4F\u6C11\u5927\u9678\u901A\u884C\u8A3C",
|
|
381
|
+
"system.profile.id_type.foreign_permanent_residence": "\u5916\u56FD\u4EBA\u6C38\u4E45\u5C45\u7559\u8EAB\u5206\u8A3C\u660E\u66F8",
|
|
382
|
+
"system.profile.id_type.other": "\u305D\u306E\u4ED6",
|
|
336
383
|
"system.profile.login_prompt": "\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u30A2\u30AB\u30A6\u30F3\u30C8\u306B\u30ED\u30B0\u30A4\u30F3\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
337
384
|
"system.profile.mobile": "\u643A\u5E2F\u96FB\u8A71\u756A\u53F7",
|
|
338
385
|
"system.profile.nick_name": "\u30CB\u30C3\u30AF\u30CD\u30FC\u30E0",
|
|
@@ -450,6 +497,20 @@ var zh_TW_default = {
|
|
|
450
497
|
"system.profile.avatar_upload_failed": "\u4E0A\u50B3\u982D\u50CF\u5931\u6557",
|
|
451
498
|
"system.profile.avatar_update": "\u66F4\u65B0\u982D\u50CF\u66B1\u7A31",
|
|
452
499
|
"system.profile.gender": "\u6027\u5225",
|
|
500
|
+
"system.profile.email": "\u96FB\u5B50\u90F5\u4EF6",
|
|
501
|
+
"system.profile.email_placeholder": "\u8ACB\u8F38\u5165\u96FB\u5B50\u90F5\u4EF6",
|
|
502
|
+
"system.profile.email_invalid": "\u8ACB\u8F38\u5165\u6B63\u78BA\u7684\u96FB\u5B50\u90F5\u4EF6",
|
|
503
|
+
"system.profile.id_type": "\u8B49\u4EF6\u985E\u578B",
|
|
504
|
+
"system.profile.id_code": "\u8B49\u4EF6\u865F",
|
|
505
|
+
"system.profile.id_code_placeholder": "\u8ACB\u8F38\u5165\u8B49\u4EF6\u865F",
|
|
506
|
+
"system.profile.id_code_invalid": "\u8ACB\u8F38\u5165\u6B63\u78BA\u7684\u8B49\u4EF6\u865F",
|
|
507
|
+
"system.profile.id_type.unspecified": "\u672A\u6307\u5B9A",
|
|
508
|
+
"system.profile.id_type.id_card": "\u5C45\u6C11\u8EAB\u5206\u8B49",
|
|
509
|
+
"system.profile.id_type.passport": "\u8B77\u7167",
|
|
510
|
+
"system.profile.id_type.hk_macao_permit": "\u6E2F\u6FB3\u5C45\u6C11\u4F86\u5F80\u5167\u5730\u901A\u884C\u8B49",
|
|
511
|
+
"system.profile.id_type.taiwan_permit": "\u81FA\u7063\u5C45\u6C11\u4F86\u5F80\u5927\u9678\u901A\u884C\u8B49",
|
|
512
|
+
"system.profile.id_type.foreign_permanent_residence": "\u5916\u570B\u4EBA\u6C38\u4E45\u5C45\u7559\u8EAB\u5206\u8B49",
|
|
513
|
+
"system.profile.id_type.other": "\u5176\u4ED6\u8B49\u4EF6",
|
|
453
514
|
"system.profile.login_prompt": "\u9EDE\u9078\u767B\u5165\u8CEC\u865F",
|
|
454
515
|
"system.profile.mobile": "\u624B\u6A5F\u865F",
|
|
455
516
|
"system.profile.nick_name": "\u66B1\u7A31",
|
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.
|
|
10
|
+
"version": "0.0.32",
|
|
11
11
|
"type": "module",
|
|
12
12
|
"files": [
|
|
13
13
|
"dist",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"@tarojs/components": "4.2.1",
|
|
39
39
|
"@tarojs/taro": "4.2.1",
|
|
40
40
|
"react": "18.3.1",
|
|
41
|
-
"@liujitcn/kratos-taro-app-core": "^0.0.
|
|
42
|
-
"@liujitcn/kratos-taro-app-ui": "^0.0.
|
|
41
|
+
"@liujitcn/kratos-taro-app-core": "^0.0.32",
|
|
42
|
+
"@liujitcn/kratos-taro-app-ui": "^0.0.32"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "pnpm run build:entries && pnpm pack --pack-destination ../../../dist/npm",
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from '@liujitcn/kratos-taro-app-core/utils/http'
|
|
7
7
|
import { getLocaleRequestHeaders, t } from '@liujitcn/kratos-taro-app-core'
|
|
8
8
|
import Taro from '@tarojs/taro'
|
|
9
|
-
import type { ListAiMessageRequest, ListAiMessageResponse } from '
|
|
9
|
+
import type { ListAiMessageRequest, ListAiMessageResponse } from '../../../rpc/base/v1/ai_session'
|
|
10
10
|
import type {
|
|
11
11
|
AiMessageService,
|
|
12
12
|
DeleteAiMessageRequest,
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
SendAiMessageRequest,
|
|
17
17
|
SendAiMessageResponse,
|
|
18
18
|
UpdateAiMessageRequest,
|
|
19
|
-
} from '
|
|
19
|
+
} from '../../../rpc/base/v1/ai_message'
|
|
20
20
|
|
|
21
21
|
const AI_SESSION_URL = '/v1/base/ai/session'
|
|
22
22
|
|
|
@@ -4,6 +4,8 @@ import type {
|
|
|
4
4
|
DeleteNotificationRequest,
|
|
5
5
|
GetNotificationRequest,
|
|
6
6
|
GetNotificationSummaryRequest,
|
|
7
|
+
ListNotificationCategoriesRequest,
|
|
8
|
+
ListNotificationCategoriesResponse,
|
|
7
9
|
MarkAllNotificationReadRequest,
|
|
8
10
|
MarkNotificationReadRequest,
|
|
9
11
|
MarkNotificationUnreadRequest,
|
|
@@ -13,8 +15,8 @@ import type {
|
|
|
13
15
|
PageNotificationRequest,
|
|
14
16
|
PageNotificationResponse,
|
|
15
17
|
RestoreNotificationRequest,
|
|
16
|
-
} from '
|
|
17
|
-
import type { Empty } from '
|
|
18
|
+
} from '../../../rpc/base/v1/notification'
|
|
19
|
+
import type { Empty } from '../../../rpc/google/protobuf/empty'
|
|
18
20
|
|
|
19
21
|
const NOTIFICATION_URL = '/v1/base/notification'
|
|
20
22
|
|
|
@@ -22,7 +24,35 @@ const NOTIFICATION_URL = '/v1/base/notification'
|
|
|
22
24
|
export class NotificationServiceImpl implements NotificationService {
|
|
23
25
|
/** 分页查询收件箱。 */
|
|
24
26
|
PageNotification(request: PageNotificationRequest): Promise<PageNotificationResponse> {
|
|
25
|
-
|
|
27
|
+
const data = Object.fromEntries(
|
|
28
|
+
Object.entries(request).filter(([, value]) => value !== undefined),
|
|
29
|
+
)
|
|
30
|
+
return http<Partial<PageNotificationResponse>>({
|
|
31
|
+
url: NOTIFICATION_URL,
|
|
32
|
+
method: 'GET',
|
|
33
|
+
authMode: 'required',
|
|
34
|
+
data,
|
|
35
|
+
}).then((response) => ({
|
|
36
|
+
...response,
|
|
37
|
+
notifications: Array.isArray(response.notifications) ? response.notifications : [],
|
|
38
|
+
total: response.total ?? 0,
|
|
39
|
+
next_cursor_id: response.next_cursor_id ?? 0,
|
|
40
|
+
has_more: response.has_more ?? false,
|
|
41
|
+
}))
|
|
42
|
+
}
|
|
43
|
+
/** 查询当前可用的消息分类。 */
|
|
44
|
+
ListNotificationCategories(
|
|
45
|
+
request: ListNotificationCategoriesRequest,
|
|
46
|
+
): Promise<ListNotificationCategoriesResponse> {
|
|
47
|
+
return http<Partial<ListNotificationCategoriesResponse>>({
|
|
48
|
+
url: `${NOTIFICATION_URL}/categories`,
|
|
49
|
+
method: 'GET',
|
|
50
|
+
authMode: 'required',
|
|
51
|
+
data: request,
|
|
52
|
+
}).then((response) => ({
|
|
53
|
+
...response,
|
|
54
|
+
categories: Array.isArray(response.categories) ? response.categories : [],
|
|
55
|
+
}))
|
|
26
56
|
}
|
|
27
57
|
/** 查询消息详情。 */
|
|
28
58
|
GetNotification(request: GetNotificationRequest): Promise<Notification> {
|
|
@@ -30,7 +60,17 @@ export class NotificationServiceImpl implements NotificationService {
|
|
|
30
60
|
}
|
|
31
61
|
/** 查询未读汇总。 */
|
|
32
62
|
GetNotificationSummary(request: GetNotificationSummaryRequest): Promise<NotificationSummary> {
|
|
33
|
-
return http({
|
|
63
|
+
return http<Partial<NotificationSummary>>({
|
|
64
|
+
url: `${NOTIFICATION_URL}/summary`,
|
|
65
|
+
method: 'GET',
|
|
66
|
+
authMode: 'required',
|
|
67
|
+
data: request,
|
|
68
|
+
}).then((response) => ({
|
|
69
|
+
...response,
|
|
70
|
+
unread_total: response.unread_total ?? 0,
|
|
71
|
+
latest_delivery_id: response.latest_delivery_id ?? 0,
|
|
72
|
+
category_unread: Array.isArray(response.category_unread) ? response.category_unread : [],
|
|
73
|
+
}))
|
|
34
74
|
}
|
|
35
75
|
/** 标记消息已读。 */
|
|
36
76
|
MarkNotificationRead(request: MarkNotificationReadRequest): Promise<Empty> {
|
package/src/locales/en-US.json
CHANGED
|
@@ -68,6 +68,20 @@
|
|
|
68
68
|
"system.profile.avatar_upload_failed": "Avatar upload failed",
|
|
69
69
|
"system.profile.avatar_update": "Update avatar and name",
|
|
70
70
|
"system.profile.gender": "Gender",
|
|
71
|
+
"system.profile.email": "Email",
|
|
72
|
+
"system.profile.email_placeholder": "Enter email",
|
|
73
|
+
"system.profile.email_invalid": "Enter a valid email",
|
|
74
|
+
"system.profile.id_type": "ID type",
|
|
75
|
+
"system.profile.id_code": "ID number",
|
|
76
|
+
"system.profile.id_code_placeholder": "Enter ID number",
|
|
77
|
+
"system.profile.id_code_invalid": "Enter a valid ID number",
|
|
78
|
+
"system.profile.id_type.unspecified": "Unspecified",
|
|
79
|
+
"system.profile.id_type.id_card": "Resident ID card",
|
|
80
|
+
"system.profile.id_type.passport": "Passport",
|
|
81
|
+
"system.profile.id_type.hk_macao_permit": "Mainland travel permit for Hong Kong/Macao residents",
|
|
82
|
+
"system.profile.id_type.taiwan_permit": "Mainland travel permit for Taiwan residents",
|
|
83
|
+
"system.profile.id_type.foreign_permanent_residence": "Foreign permanent residence ID",
|
|
84
|
+
"system.profile.id_type.other": "Other ID",
|
|
71
85
|
"system.profile.login_prompt": "Tap to log in",
|
|
72
86
|
"system.profile.mobile": "Mobile",
|
|
73
87
|
"system.profile.nick_name": "Nickname",
|
package/src/locales/ja-JP.json
CHANGED
|
@@ -68,6 +68,20 @@
|
|
|
68
68
|
"system.profile.avatar_upload_failed": "アバターのアップロードに失敗しました",
|
|
69
69
|
"system.profile.avatar_update": "アバターのニックネームを更新",
|
|
70
70
|
"system.profile.gender": "性別",
|
|
71
|
+
"system.profile.email": "メールアドレス",
|
|
72
|
+
"system.profile.email_placeholder": "メールアドレスを入力してください",
|
|
73
|
+
"system.profile.email_invalid": "正しいメールアドレスを入力してください",
|
|
74
|
+
"system.profile.id_type": "身分証明書の種類",
|
|
75
|
+
"system.profile.id_code": "身分証明書番号",
|
|
76
|
+
"system.profile.id_code_placeholder": "身分証明書番号を入力してください",
|
|
77
|
+
"system.profile.id_code_invalid": "正しい身分証明書番号を入力してください",
|
|
78
|
+
"system.profile.id_type.unspecified": "未指定",
|
|
79
|
+
"system.profile.id_type.id_card": "身分証明書",
|
|
80
|
+
"system.profile.id_type.passport": "パスポート",
|
|
81
|
+
"system.profile.id_type.hk_macao_permit": "香港・マカオ住民内地通行証",
|
|
82
|
+
"system.profile.id_type.taiwan_permit": "台湾住民大陸通行証",
|
|
83
|
+
"system.profile.id_type.foreign_permanent_residence": "外国人永久居留身分証明書",
|
|
84
|
+
"system.profile.id_type.other": "その他",
|
|
71
85
|
"system.profile.login_prompt": "クリックしてアカウントにログインしてください",
|
|
72
86
|
"system.profile.mobile": "携帯電話番号",
|
|
73
87
|
"system.profile.nick_name": "ニックネーム",
|
package/src/locales/zh-CN.json
CHANGED
|
@@ -68,6 +68,20 @@
|
|
|
68
68
|
"system.profile.avatar_upload_failed": "上传头像失败",
|
|
69
69
|
"system.profile.avatar_update": "更新头像昵称",
|
|
70
70
|
"system.profile.gender": "性别",
|
|
71
|
+
"system.profile.email": "邮箱",
|
|
72
|
+
"system.profile.email_placeholder": "请输入邮箱",
|
|
73
|
+
"system.profile.email_invalid": "请输入正确的邮箱",
|
|
74
|
+
"system.profile.id_type": "证件类型",
|
|
75
|
+
"system.profile.id_code": "证件号",
|
|
76
|
+
"system.profile.id_code_placeholder": "请输入证件号",
|
|
77
|
+
"system.profile.id_code_invalid": "请输入正确的证件号",
|
|
78
|
+
"system.profile.id_type.unspecified": "未指定",
|
|
79
|
+
"system.profile.id_type.id_card": "居民身份证",
|
|
80
|
+
"system.profile.id_type.passport": "护照",
|
|
81
|
+
"system.profile.id_type.hk_macao_permit": "港澳居民来往内地通行证",
|
|
82
|
+
"system.profile.id_type.taiwan_permit": "台湾居民来往大陆通行证",
|
|
83
|
+
"system.profile.id_type.foreign_permanent_residence": "外国人永久居留身份证",
|
|
84
|
+
"system.profile.id_type.other": "其他证件",
|
|
71
85
|
"system.profile.login_prompt": "点击登录账号",
|
|
72
86
|
"system.profile.mobile": "手机号",
|
|
73
87
|
"system.profile.nick_name": "昵称",
|
package/src/locales/zh-TW.json
CHANGED
|
@@ -68,6 +68,20 @@
|
|
|
68
68
|
"system.profile.avatar_upload_failed": "上傳頭像失敗",
|
|
69
69
|
"system.profile.avatar_update": "更新頭像暱稱",
|
|
70
70
|
"system.profile.gender": "性別",
|
|
71
|
+
"system.profile.email": "電子郵件",
|
|
72
|
+
"system.profile.email_placeholder": "請輸入電子郵件",
|
|
73
|
+
"system.profile.email_invalid": "請輸入正確的電子郵件",
|
|
74
|
+
"system.profile.id_type": "證件類型",
|
|
75
|
+
"system.profile.id_code": "證件號",
|
|
76
|
+
"system.profile.id_code_placeholder": "請輸入證件號",
|
|
77
|
+
"system.profile.id_code_invalid": "請輸入正確的證件號",
|
|
78
|
+
"system.profile.id_type.unspecified": "未指定",
|
|
79
|
+
"system.profile.id_type.id_card": "居民身分證",
|
|
80
|
+
"system.profile.id_type.passport": "護照",
|
|
81
|
+
"system.profile.id_type.hk_macao_permit": "港澳居民來往內地通行證",
|
|
82
|
+
"system.profile.id_type.taiwan_permit": "臺灣居民來往大陸通行證",
|
|
83
|
+
"system.profile.id_type.foreign_permanent_residence": "外國人永久居留身分證",
|
|
84
|
+
"system.profile.id_type.other": "其他證件",
|
|
71
85
|
"system.profile.login_prompt": "點選登入賬號",
|
|
72
86
|
"system.profile.mobile": "手機號",
|
|
73
87
|
"system.profile.nick_name": "暱稱",
|
package/src/notification.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { setAppMenuBadge } from '@liujitcn/kratos-taro-app-core/navigation'
|
|
2
|
+
import { getToken } from '@liujitcn/kratos-taro-app-core/utils/auth'
|
|
2
3
|
import { getRequestAccessToken } from '@liujitcn/kratos-taro-app-core/utils/http'
|
|
3
|
-
import { defNotificationService } from './api/base/notification'
|
|
4
|
+
import { defNotificationService } from './api/base/v1/notification'
|
|
4
5
|
|
|
5
6
|
/** System 模块共享的站内信未读数。 */
|
|
6
7
|
let unreadTotal = 0
|
|
@@ -10,6 +11,7 @@ let notificationPaused = false
|
|
|
10
11
|
|
|
11
12
|
/** 从服务端刷新未读汇总并同步消息入口 badge。 */
|
|
12
13
|
export async function refreshNotificationSummary(): Promise<number> {
|
|
14
|
+
if (!getToken()) return unreadTotal
|
|
13
15
|
try {
|
|
14
16
|
const summary = await defNotificationService.GetNotificationSummary({})
|
|
15
17
|
unreadTotal = summary.unread_total
|
|
@@ -23,6 +25,7 @@ export async function refreshNotificationSummary(): Promise<number> {
|
|
|
23
25
|
/** 启动应用端站内信定时回源。 */
|
|
24
26
|
export function startNotificationPolling(): void {
|
|
25
27
|
stopNotificationPolling()
|
|
28
|
+
if (!getToken()) return
|
|
26
29
|
notificationPaused = false
|
|
27
30
|
void refreshNotificationSummary()
|
|
28
31
|
notificationTimer = setInterval(() => void refreshNotificationSummary(), 30_000)
|
package/src/pages.ts
CHANGED
|
@@ -23,6 +23,11 @@ export const systemPages: Record<string, KratosTaroPageConfig> = {
|
|
|
23
23
|
navigationBarTitleText: '',
|
|
24
24
|
},
|
|
25
25
|
},
|
|
26
|
-
'pagesMember/message/index': {
|
|
26
|
+
'pagesMember/message/index': {
|
|
27
|
+
style: {
|
|
28
|
+
navigationStyle: 'custom',
|
|
29
|
+
navigationBarTitleText: '',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
27
32
|
'pagesMember/message/detail': { style: { navigationBarTitleText: '' } },
|
|
28
33
|
}
|
|
@@ -184,6 +184,32 @@ export interface PageNotificationResponse {
|
|
|
184
184
|
has_more: boolean;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
/** 消息分类列表查询条件。 */
|
|
188
|
+
export interface ListNotificationCategoriesRequest {
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** 消息分类列表响应。 */
|
|
192
|
+
export interface ListNotificationCategoriesResponse {
|
|
193
|
+
/** 消息分类列表 */
|
|
194
|
+
categories: NotificationCategory[];
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** 当前可用的消息分类。 */
|
|
198
|
+
export interface NotificationCategory {
|
|
199
|
+
/** 消息分类ID */
|
|
200
|
+
id: number;
|
|
201
|
+
/** 分类编码 */
|
|
202
|
+
code: string;
|
|
203
|
+
/** 分类名称 */
|
|
204
|
+
name: string;
|
|
205
|
+
/** 分类图标 */
|
|
206
|
+
icon: string;
|
|
207
|
+
/** 分类颜色 */
|
|
208
|
+
color: string;
|
|
209
|
+
/** 排序 */
|
|
210
|
+
sort: number;
|
|
211
|
+
}
|
|
212
|
+
|
|
187
213
|
/** 消息详情查询条件。 */
|
|
188
214
|
export interface GetNotificationRequest {
|
|
189
215
|
/** 投递ID */
|
|
@@ -296,6 +322,8 @@ export interface Notification {
|
|
|
296
322
|
export interface NotificationService {
|
|
297
323
|
/** 分页查询当前用户收件箱。 */
|
|
298
324
|
PageNotification(request: PageNotificationRequest): Promise<PageNotificationResponse>;
|
|
325
|
+
/** 查询消息分类列表。 */
|
|
326
|
+
ListNotificationCategories(request: ListNotificationCategoriesRequest): Promise<ListNotificationCategoriesResponse>;
|
|
299
327
|
/** 查询当前用户未读汇总。 */
|
|
300
328
|
GetNotificationSummary(request: GetNotificationSummaryRequest): Promise<NotificationSummary>;
|
|
301
329
|
/** 查询当前用户消息详情。 */
|
|
@@ -10,9 +10,9 @@ import {
|
|
|
10
10
|
useI18n,
|
|
11
11
|
} from '@liujitcn/kratos-taro-app-core'
|
|
12
12
|
import { UniIcon } from '@liujitcn/kratos-taro-app-ui'
|
|
13
|
-
import { defAiMessageService, StreamAiMessageByChunkedRequest } from '../../../api/base/ai_message'
|
|
14
|
-
import { defAiSessionService } from '../../../api/base/ai_session'
|
|
15
|
-
import { defAiToolService } from '../../../api/base/ai_tool'
|
|
13
|
+
import { defAiMessageService, StreamAiMessageByChunkedRequest } from '../../../api/base/v1/ai_message'
|
|
14
|
+
import { defAiSessionService } from '../../../api/base/v1/ai_session'
|
|
15
|
+
import { defAiToolService } from '../../../api/base/v1/ai_tool'
|
|
16
16
|
import type { AiAttachment, AiMessage, AiSession } from '../../../rpc/base/v1/ai_session'
|
|
17
17
|
import type { AiShortcut, AiToolCall } from '../../../rpc/base/v1/ai_tool'
|
|
18
18
|
import { AiMessageStatus } from '../../../rpc/base/v1/ai_session'
|
|
@@ -2,9 +2,11 @@ import { useLoad } from '@tarojs/taro'
|
|
|
2
2
|
import { Button, RichText, Text, View } from '@tarojs/components'
|
|
3
3
|
import { useState } from 'react'
|
|
4
4
|
import { navigateAppView, t } from '@liujitcn/kratos-taro-app-core'
|
|
5
|
-
import {
|
|
5
|
+
import { UniIcon } from '@liujitcn/kratos-taro-app-ui'
|
|
6
|
+
import { defNotificationService } from '../../../api/base/v1/notification'
|
|
6
7
|
import type { Notification } from '../../../rpc/base/v1/notification'
|
|
7
8
|
import { MessageActionType, MessageContentFormat } from '../../../rpc/base/v1/notification'
|
|
9
|
+
import { resolveMessageCategoryIcon } from './icons'
|
|
8
10
|
import './message.scss'
|
|
9
11
|
|
|
10
12
|
/** Taro 站内信详情页面。 */
|
|
@@ -13,7 +15,7 @@ export default function MessageDetailPage() {
|
|
|
13
15
|
|
|
14
16
|
useLoad((options) => {
|
|
15
17
|
const id = Number(options?.id)
|
|
16
|
-
if (id > 0) void loadDetail(id)
|
|
18
|
+
if (id > 0) void loadDetail(id).catch(() => undefined)
|
|
17
19
|
})
|
|
18
20
|
|
|
19
21
|
/** 加载站内信详情。 */
|
|
@@ -31,7 +33,11 @@ export default function MessageDetailPage() {
|
|
|
31
33
|
try {
|
|
32
34
|
const value = JSON.parse(detail.action_params) as Record<string, unknown>
|
|
33
35
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
34
|
-
params = Object.fromEntries(
|
|
36
|
+
params = Object.fromEntries(
|
|
37
|
+
Object.entries(value)
|
|
38
|
+
.filter(([, item]) => typeof item === 'string' || typeof item === 'number')
|
|
39
|
+
.map(([key, item]) => [key, String(item)]),
|
|
40
|
+
)
|
|
35
41
|
}
|
|
36
42
|
} catch {
|
|
37
43
|
params = {}
|
|
@@ -45,12 +51,28 @@ export default function MessageDetailPage() {
|
|
|
45
51
|
<View className='detail-page'>
|
|
46
52
|
<Text className='detail-title'>{detail.title}</Text>
|
|
47
53
|
<View className='detail-meta'>
|
|
48
|
-
<
|
|
54
|
+
<View className='detail-category' style={{ color: detail.category_color || undefined }}>
|
|
55
|
+
<UniIcon
|
|
56
|
+
className='detail-category__icon'
|
|
57
|
+
type={resolveMessageCategoryIcon(detail.category_icon)}
|
|
58
|
+
size={18}
|
|
59
|
+
color={detail.category_color || '#64748b'}
|
|
60
|
+
/>
|
|
61
|
+
<Text>{detail.category_name}</Text>
|
|
62
|
+
</View>
|
|
63
|
+
<Text>{detail.sender_name}</Text>
|
|
64
|
+
<Text>{detail.received_at}</Text>
|
|
49
65
|
</View>
|
|
50
|
-
{detail.content_format === MessageContentFormat.MESSAGE_CONTENT_FORMAT_RICH_TEXT
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
66
|
+
{detail.content_format === MessageContentFormat.MESSAGE_CONTENT_FORMAT_RICH_TEXT ? (
|
|
67
|
+
<RichText className='detail-content-rich' nodes={detail.content} />
|
|
68
|
+
) : (
|
|
69
|
+
<Text className='detail-content'>{detail.content}</Text>
|
|
70
|
+
)}
|
|
71
|
+
{detail.action_type === MessageActionType.MESSAGE_ACTION_TYPE_VIEW_KEY && (
|
|
72
|
+
<Button className='detail-action' onClick={openAction}>
|
|
73
|
+
{t('common.action.view')}
|
|
74
|
+
</Button>
|
|
75
|
+
)}
|
|
54
76
|
</View>
|
|
55
77
|
)
|
|
56
78
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { UniIconName } from '@liujitcn/kratos-taro-app-ui'
|
|
2
|
+
|
|
3
|
+
/** 消息分类在 Taro 中可渲染的图标名称。 */
|
|
4
|
+
export type MessageCategoryIcon = UniIconName
|
|
5
|
+
|
|
6
|
+
const categoryIconMap: Record<string, MessageCategoryIcon> = {
|
|
7
|
+
Bell: 'notification-filled',
|
|
8
|
+
Lock: 'locked-filled',
|
|
9
|
+
List: 'list',
|
|
10
|
+
Message: 'chatboxes-filled',
|
|
11
|
+
InfoFilled: 'info-filled',
|
|
12
|
+
WarningFilled: 'flag-filled',
|
|
13
|
+
CircleCheckFilled: 'checkbox-filled',
|
|
14
|
+
Promotion: 'paperplane-filled',
|
|
15
|
+
Setting: 'settings-filled',
|
|
16
|
+
User: 'person-filled',
|
|
17
|
+
Calendar: 'calendar-filled',
|
|
18
|
+
ChatDotRound: 'chatbubble-filled',
|
|
19
|
+
DataAnalysis: 'bars',
|
|
20
|
+
CollectionTag: 'list',
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** 将管理端维护的 Element Plus 图标名转换为 Taro 图标名。 */
|
|
24
|
+
export function resolveMessageCategoryIcon(icon?: string): MessageCategoryIcon {
|
|
25
|
+
return categoryIconMap[icon ?? ''] ?? 'notification'
|
|
26
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { useDidShow } from '@tarojs/taro'
|
|
2
|
-
import { Button,
|
|
2
|
+
import { Button, ScrollView, Text, View } from '@tarojs/components'
|
|
3
3
|
import { useState } from 'react'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
4
|
+
import { navigateAppView, t } from '@liujitcn/kratos-taro-app-core'
|
|
5
|
+
import { UniIcon } from '@liujitcn/kratos-taro-app-ui'
|
|
6
|
+
import { defNotificationService } from '../../../api/base/v1/notification'
|
|
7
|
+
import type { Notification, NotificationCategory } from '../../../rpc/base/v1/notification'
|
|
7
8
|
import { NotificationView } from '../../../rpc/base/v1/notification'
|
|
8
9
|
import { refreshNotificationSummary } from '../../../notification'
|
|
10
|
+
import { resolveMessageCategoryIcon } from './icons'
|
|
9
11
|
import './message.scss'
|
|
10
12
|
|
|
11
13
|
/** Taro 站内信收件箱页面。 */
|
|
@@ -16,8 +18,10 @@ export default function MessageInboxPage() {
|
|
|
16
18
|
const [finished, setFinished] = useState(false)
|
|
17
19
|
const [unreadTotal, setUnreadTotal] = useState(0)
|
|
18
20
|
const [selectedView, setSelectedView] = useState(NotificationView.NOTIFICATION_VIEW_INBOX)
|
|
19
|
-
const [categoryInput, setCategoryInput] = useState('')
|
|
20
21
|
const [categoryId, setCategoryId] = useState<number>()
|
|
22
|
+
const [categoryOptions, setCategoryOptions] = useState<
|
|
23
|
+
NotificationCategory[]
|
|
24
|
+
>([])
|
|
21
25
|
const viewOptions = [
|
|
22
26
|
{ value: NotificationView.NOTIFICATION_VIEW_INBOX, key: 'system.notification.view.inbox' },
|
|
23
27
|
{ value: NotificationView.NOTIFICATION_VIEW_UNREAD, key: 'system.notification.view.unread' },
|
|
@@ -28,12 +32,24 @@ export default function MessageInboxPage() {
|
|
|
28
32
|
]
|
|
29
33
|
|
|
30
34
|
useDidShow(() => {
|
|
31
|
-
void
|
|
32
|
-
void
|
|
35
|
+
void loadCategories().catch(() => undefined)
|
|
36
|
+
void refresh().catch(() => undefined)
|
|
37
|
+
void refreshNotificationSummary()
|
|
38
|
+
.then(setUnreadTotal)
|
|
39
|
+
.catch(() => undefined)
|
|
33
40
|
})
|
|
34
41
|
|
|
42
|
+
/** 加载管理端维护的消息分类。 */
|
|
43
|
+
async function loadCategories() {
|
|
44
|
+
const result = await defNotificationService.ListNotificationCategories({})
|
|
45
|
+
setCategoryOptions(result.categories ?? [])
|
|
46
|
+
}
|
|
47
|
+
|
|
35
48
|
/** 刷新站内信列表。 */
|
|
36
49
|
async function refresh(view = selectedView, category = categoryId) {
|
|
50
|
+
setItems([])
|
|
51
|
+
setCursorId(0)
|
|
52
|
+
setFinished(false)
|
|
37
53
|
setLoading(true)
|
|
38
54
|
try {
|
|
39
55
|
const result = await defNotificationService.PageNotification({
|
|
@@ -77,15 +93,13 @@ export default function MessageInboxPage() {
|
|
|
77
93
|
/** 切换收件箱视图。 */
|
|
78
94
|
function changeView(view: NotificationView) {
|
|
79
95
|
setSelectedView(view)
|
|
80
|
-
void refresh(view, categoryId)
|
|
96
|
+
void refresh(view, categoryId).catch(() => undefined)
|
|
81
97
|
}
|
|
82
98
|
|
|
83
|
-
/**
|
|
84
|
-
function
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
setCategoryId(next)
|
|
88
|
-
void refresh(selectedView, next)
|
|
99
|
+
/** 切换消息分类。 */
|
|
100
|
+
function changeCategory(id?: number) {
|
|
101
|
+
setCategoryId(id)
|
|
102
|
+
void refresh(selectedView, id).catch(() => undefined)
|
|
89
103
|
}
|
|
90
104
|
|
|
91
105
|
/** 标记当前水位线之前的消息为已读。 */
|
|
@@ -116,18 +130,53 @@ export default function MessageInboxPage() {
|
|
|
116
130
|
/** 打开站内信详情。 */
|
|
117
131
|
async function openDetail(item: Notification) {
|
|
118
132
|
if (!item.read_at) await defNotificationService.MarkNotificationRead({ ids: [item.id] })
|
|
119
|
-
|
|
133
|
+
navigateAppView('MESSAGE_DETAIL', { id: String(item.id) })
|
|
120
134
|
}
|
|
121
135
|
|
|
122
136
|
return (
|
|
123
137
|
<View className='message-page'>
|
|
124
138
|
<View className='message-header'>
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
<
|
|
139
|
+
<View className='message-header__title'>
|
|
140
|
+
<Text className='message-title'>{t('system.notification.title')}</Text>
|
|
141
|
+
{unreadTotal > 0 && <View className='message-unread-dot' aria-hidden='true' />}
|
|
142
|
+
</View>
|
|
143
|
+
{selectedView !== NotificationView.NOTIFICATION_VIEW_ARCHIVED && unreadTotal > 0 && (
|
|
144
|
+
<Button
|
|
145
|
+
className='message-action message-action--read message-header__action'
|
|
146
|
+
onClick={() => void markAllRead().catch(() => undefined)}
|
|
147
|
+
>
|
|
148
|
+
{t('system.notification.mark_all_read')}
|
|
149
|
+
</Button>
|
|
128
150
|
)}
|
|
129
151
|
</View>
|
|
130
152
|
<View className='message-controls'>
|
|
153
|
+
<ScrollView className='message-category-scroll' scrollX showScrollbar={false}>
|
|
154
|
+
<View className='message-category-list'>
|
|
155
|
+
<Button
|
|
156
|
+
className={categoryId === undefined ? 'message-category active' : 'message-category'}
|
|
157
|
+
onClick={() => changeCategory()}
|
|
158
|
+
>
|
|
159
|
+
{t('system.notification.view.inbox')}
|
|
160
|
+
</Button>
|
|
161
|
+
{categoryOptions.map((category) => (
|
|
162
|
+
<Button
|
|
163
|
+
key={category.id}
|
|
164
|
+
className={
|
|
165
|
+
categoryId === category.id ? 'message-category active' : 'message-category'
|
|
166
|
+
}
|
|
167
|
+
onClick={() => changeCategory(category.id)}
|
|
168
|
+
>
|
|
169
|
+
<UniIcon
|
|
170
|
+
className='message-category__icon'
|
|
171
|
+
type={resolveMessageCategoryIcon(category.icon)}
|
|
172
|
+
size={16}
|
|
173
|
+
color={categoryId === category.id ? '#fff' : category.color || '#64748b'}
|
|
174
|
+
/>
|
|
175
|
+
{category.name}
|
|
176
|
+
</Button>
|
|
177
|
+
))}
|
|
178
|
+
</View>
|
|
179
|
+
</ScrollView>
|
|
131
180
|
<View className='message-tabs'>
|
|
132
181
|
{viewOptions.map((option) => (
|
|
133
182
|
<Button
|
|
@@ -139,40 +188,35 @@ export default function MessageInboxPage() {
|
|
|
139
188
|
</Button>
|
|
140
189
|
))}
|
|
141
190
|
</View>
|
|
142
|
-
<View className='message-filter'>
|
|
143
|
-
<Input
|
|
144
|
-
type='number'
|
|
145
|
-
value={categoryInput}
|
|
146
|
-
placeholder={t('system.notification.category_filter')}
|
|
147
|
-
onInput={(event) => setCategoryInput(event.detail.value)}
|
|
148
|
-
onConfirm={applyCategoryFilter}
|
|
149
|
-
/>
|
|
150
|
-
<Button size='mini' onClick={applyCategoryFilter}>
|
|
151
|
-
{t('common.action.confirm')}
|
|
152
|
-
</Button>
|
|
153
|
-
{selectedView !== NotificationView.NOTIFICATION_VIEW_ARCHIVED && unreadTotal > 0 && (
|
|
154
|
-
<Button size='mini' onClick={() => void markAllRead()}>
|
|
155
|
-
{t('system.notification.mark_all_read')}
|
|
156
|
-
</Button>
|
|
157
|
-
)}
|
|
158
|
-
</View>
|
|
159
191
|
</View>
|
|
160
192
|
{items.map((item) => (
|
|
161
|
-
<View
|
|
193
|
+
<View
|
|
194
|
+
className='message-item'
|
|
195
|
+
key={item.id}
|
|
196
|
+
onClick={() => void openDetail(item).catch(() => undefined)}
|
|
197
|
+
>
|
|
162
198
|
<View className='message-item__main'>
|
|
163
199
|
<Text className={`message-item__title ${item.read_at ? '' : 'unread'}`}>
|
|
164
200
|
{item.title}
|
|
165
201
|
</Text>
|
|
166
202
|
<Text className='message-item__time'>{item.received_at}</Text>
|
|
167
203
|
</View>
|
|
168
|
-
<
|
|
204
|
+
<View className='message-item__category'>
|
|
205
|
+
<UniIcon
|
|
206
|
+
className='message-item__category-icon'
|
|
207
|
+
type={resolveMessageCategoryIcon(item.category_icon)}
|
|
208
|
+
size={16}
|
|
209
|
+
color={item.category_color || '#64748b'}
|
|
210
|
+
/>
|
|
211
|
+
<Text>{item.category_name}</Text>
|
|
212
|
+
</View>
|
|
169
213
|
<View className='message-item__actions'>
|
|
170
214
|
{selectedView !== NotificationView.NOTIFICATION_VIEW_ARCHIVED && item.allow_archive && (
|
|
171
215
|
<Button
|
|
172
216
|
size='mini'
|
|
173
217
|
onClick={(event) => {
|
|
174
218
|
event.stopPropagation()
|
|
175
|
-
void toggleArchive(item)
|
|
219
|
+
void toggleArchive(item).catch(() => undefined)
|
|
176
220
|
}}
|
|
177
221
|
>
|
|
178
222
|
{t('system.notification.action.archive')}
|
|
@@ -183,7 +227,7 @@ export default function MessageInboxPage() {
|
|
|
183
227
|
size='mini'
|
|
184
228
|
onClick={(event) => {
|
|
185
229
|
event.stopPropagation()
|
|
186
|
-
void toggleArchive(item)
|
|
230
|
+
void toggleArchive(item).catch(() => undefined)
|
|
187
231
|
}}
|
|
188
232
|
>
|
|
189
233
|
{t('system.notification.action.restore')}
|
|
@@ -194,7 +238,7 @@ export default function MessageInboxPage() {
|
|
|
194
238
|
size='mini'
|
|
195
239
|
onClick={(event) => {
|
|
196
240
|
event.stopPropagation()
|
|
197
|
-
void deleteItem(item)
|
|
241
|
+
void deleteItem(item).catch(() => undefined)
|
|
198
242
|
}}
|
|
199
243
|
>
|
|
200
244
|
{t('system.notification.action.delete')}
|
|
@@ -204,7 +248,11 @@ export default function MessageInboxPage() {
|
|
|
204
248
|
</View>
|
|
205
249
|
))}
|
|
206
250
|
{!finished && (
|
|
207
|
-
<Button
|
|
251
|
+
<Button
|
|
252
|
+
className='load-more'
|
|
253
|
+
loading={loading}
|
|
254
|
+
onClick={() => void loadMore().catch(() => undefined)}
|
|
255
|
+
>
|
|
208
256
|
{t('common.action.load_more')}
|
|
209
257
|
</Button>
|
|
210
258
|
)}
|
|
@@ -1,79 +1,155 @@
|
|
|
1
1
|
.message-page {
|
|
2
|
+
box-sizing: border-box;
|
|
2
3
|
min-height: 100vh;
|
|
3
|
-
padding: 24px;
|
|
4
|
-
background: var(--kratos-color-background);
|
|
4
|
+
padding: 16px 24px calc(120px + env(safe-area-inset-bottom));
|
|
5
|
+
background: var(--kratos-color-background, #f7f8fa);
|
|
6
|
+
color: var(--kratos-color-text, #1f2937);
|
|
5
7
|
}
|
|
6
8
|
|
|
7
|
-
.message-header {
|
|
8
|
-
padding: 20px 4px 28px;
|
|
9
|
-
}
|
|
10
9
|
.message-header {
|
|
11
10
|
display: flex;
|
|
12
11
|
align-items: center;
|
|
13
12
|
justify-content: space-between;
|
|
13
|
+
gap: 20px;
|
|
14
|
+
padding: 20px 4px 24px;
|
|
15
|
+
}
|
|
16
|
+
.message-header__title {
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
min-width: 0;
|
|
14
20
|
}
|
|
15
21
|
.message-title {
|
|
16
|
-
|
|
22
|
+
display: block;
|
|
23
|
+
color: var(--kratos-color-text, #1f2937);
|
|
17
24
|
font-size: 40px;
|
|
18
25
|
font-weight: 700;
|
|
26
|
+
line-height: 1.35;
|
|
19
27
|
}
|
|
20
|
-
.message-unread {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
.message-unread-dot {
|
|
29
|
+
width: 12px;
|
|
30
|
+
height: 12px;
|
|
31
|
+
margin-left: 8px;
|
|
32
|
+
border-radius: 50%;
|
|
24
33
|
background: #e5484d;
|
|
25
|
-
color: #fff;
|
|
26
|
-
font-size: 22px;
|
|
27
|
-
line-height: 28px;
|
|
28
|
-
text-align: center;
|
|
29
34
|
}
|
|
30
35
|
.message-controls {
|
|
31
|
-
margin-bottom:
|
|
36
|
+
margin-bottom: 24px;
|
|
37
|
+
}
|
|
38
|
+
.message-category-scroll {
|
|
39
|
+
width: 100%;
|
|
40
|
+
white-space: nowrap;
|
|
41
|
+
}
|
|
42
|
+
.message-category-list {
|
|
43
|
+
display: flex;
|
|
44
|
+
gap: 12px;
|
|
45
|
+
width: max-content;
|
|
46
|
+
padding-bottom: 4px;
|
|
32
47
|
}
|
|
48
|
+
.message-category,
|
|
33
49
|
.message-tabs,
|
|
34
|
-
.message-filter,
|
|
35
50
|
.message-item__actions {
|
|
36
51
|
display: flex;
|
|
37
52
|
align-items: center;
|
|
53
|
+
}
|
|
54
|
+
.message-category {
|
|
55
|
+
flex-shrink: 0;
|
|
56
|
+
width: auto;
|
|
57
|
+
height: 64px;
|
|
58
|
+
margin: 0;
|
|
59
|
+
padding: 0 22px;
|
|
60
|
+
border: 1px solid var(--kratos-color-border, #e2e8f0);
|
|
61
|
+
border-radius: 32px;
|
|
62
|
+
background: #fff;
|
|
63
|
+
color: var(--kratos-color-text-muted, #6b7280);
|
|
64
|
+
font-size: 24px;
|
|
65
|
+
line-height: 64px;
|
|
66
|
+
white-space: nowrap;
|
|
67
|
+
}
|
|
68
|
+
.message-category__icon,
|
|
69
|
+
.message-item__category-icon {
|
|
70
|
+
flex: 0 0 auto;
|
|
71
|
+
margin-right: 8px;
|
|
72
|
+
}
|
|
73
|
+
.message-category.active {
|
|
74
|
+
border-color: var(--kratos-color-primary, #27ba9b);
|
|
75
|
+
background: var(--kratos-color-primary, #27ba9b);
|
|
76
|
+
color: #fff;
|
|
77
|
+
}
|
|
78
|
+
.message-tabs {
|
|
79
|
+
gap: 12px;
|
|
80
|
+
margin-top: 18px;
|
|
81
|
+
padding: 6px;
|
|
82
|
+
border-radius: 12px;
|
|
83
|
+
background: #eef1f3;
|
|
84
|
+
}
|
|
85
|
+
.message-tab::after,
|
|
86
|
+
.message-category::after,
|
|
87
|
+
.message-action::after,
|
|
88
|
+
.message-item__actions button::after,
|
|
89
|
+
.load-more::after {
|
|
90
|
+
border: 0;
|
|
91
|
+
}
|
|
92
|
+
.message-item__actions {
|
|
93
|
+
flex-wrap: wrap;
|
|
94
|
+
justify-content: flex-end;
|
|
38
95
|
gap: 12px;
|
|
39
96
|
}
|
|
40
97
|
.message-tab {
|
|
98
|
+
box-sizing: border-box;
|
|
41
99
|
flex: 1;
|
|
100
|
+
min-width: 0;
|
|
101
|
+
height: 68px;
|
|
42
102
|
margin: 0;
|
|
43
|
-
padding:
|
|
103
|
+
padding: 0 12px;
|
|
104
|
+
border: 0;
|
|
105
|
+
border-radius: 8px;
|
|
44
106
|
background: transparent;
|
|
45
|
-
color: var(--kratos-color-text-muted);
|
|
107
|
+
color: var(--kratos-color-text-muted, #6b7280);
|
|
46
108
|
font-size: 26px;
|
|
109
|
+
line-height: 68px;
|
|
110
|
+
white-space: nowrap;
|
|
47
111
|
}
|
|
48
112
|
.message-tab.active {
|
|
49
|
-
background: var(--kratos-color-primary);
|
|
113
|
+
background: var(--kratos-color-primary, #27ba9b);
|
|
50
114
|
color: #fff;
|
|
51
115
|
}
|
|
52
|
-
.message-
|
|
53
|
-
margin-top: 14px;
|
|
54
|
-
}
|
|
55
|
-
.message-filter input {
|
|
56
|
-
min-width: 0;
|
|
57
|
-
flex: 1;
|
|
58
|
-
padding: 12px 16px;
|
|
59
|
-
border: 1px solid var(--kratos-color-border);
|
|
60
|
-
border-radius: 8px;
|
|
61
|
-
}
|
|
62
|
-
.message-filter button,
|
|
116
|
+
.message-action,
|
|
63
117
|
.message-item__actions button {
|
|
118
|
+
box-sizing: border-box;
|
|
119
|
+
flex-shrink: 0;
|
|
120
|
+
width: auto;
|
|
121
|
+
height: 68px;
|
|
64
122
|
margin: 0;
|
|
65
|
-
padding: 0
|
|
123
|
+
padding: 0 20px;
|
|
124
|
+
border: 0;
|
|
125
|
+
border-radius: 8px;
|
|
126
|
+
background: #eef1f3;
|
|
127
|
+
color: var(--kratos-color-text, #1f2937);
|
|
66
128
|
font-size: 24px;
|
|
129
|
+
line-height: 68px;
|
|
130
|
+
white-space: nowrap;
|
|
67
131
|
}
|
|
68
|
-
.message-
|
|
69
|
-
|
|
70
|
-
|
|
132
|
+
.message-action--read {
|
|
133
|
+
background: #e8f8f4;
|
|
134
|
+
color: var(--kratos-color-primary, #16806d);
|
|
135
|
+
}
|
|
136
|
+
.message-header__action {
|
|
137
|
+
height: 56px;
|
|
138
|
+
padding: 0 18px;
|
|
139
|
+
line-height: 56px;
|
|
140
|
+
}
|
|
141
|
+
.message-item__actions button {
|
|
142
|
+
height: 56px;
|
|
143
|
+
padding: 0 16px;
|
|
144
|
+
font-size: 22px;
|
|
145
|
+
line-height: 56px;
|
|
71
146
|
}
|
|
72
147
|
.message-item {
|
|
73
148
|
margin-bottom: 16px;
|
|
74
149
|
padding: 28px;
|
|
75
150
|
border-radius: 12px;
|
|
76
151
|
background: #fff;
|
|
152
|
+
box-shadow: 0 4px 16px rgba(31, 41, 55, 0.05);
|
|
77
153
|
}
|
|
78
154
|
.message-item__main {
|
|
79
155
|
display: flex;
|
|
@@ -82,43 +158,58 @@
|
|
|
82
158
|
gap: 20px;
|
|
83
159
|
}
|
|
84
160
|
.message-item__title {
|
|
161
|
+
display: block;
|
|
85
162
|
min-width: 0;
|
|
86
163
|
flex: 1;
|
|
87
164
|
overflow: hidden;
|
|
88
|
-
color: var(--kratos-color-text);
|
|
165
|
+
color: var(--kratos-color-text, #1f2937);
|
|
89
166
|
text-overflow: ellipsis;
|
|
90
167
|
white-space: nowrap;
|
|
91
168
|
}
|
|
92
169
|
.message-item__title.unread {
|
|
93
|
-
color: var(--kratos-color-text);
|
|
170
|
+
color: var(--kratos-color-text, #1f2937);
|
|
94
171
|
font-weight: 700;
|
|
95
172
|
}
|
|
96
173
|
.message-item__time,
|
|
97
174
|
.message-item__category {
|
|
98
|
-
color: var(--kratos-color-text-muted);
|
|
175
|
+
color: var(--kratos-color-text-muted, #6b7280);
|
|
99
176
|
font-size: 24px;
|
|
100
177
|
}
|
|
178
|
+
.message-item__time {
|
|
179
|
+
flex-shrink: 0;
|
|
180
|
+
}
|
|
101
181
|
.message-item__category {
|
|
102
|
-
display:
|
|
182
|
+
display: flex;
|
|
183
|
+
align-items: center;
|
|
103
184
|
margin-top: 14px;
|
|
104
185
|
}
|
|
105
186
|
.load-more {
|
|
187
|
+
box-sizing: border-box;
|
|
188
|
+
width: 100%;
|
|
189
|
+
height: 72px;
|
|
106
190
|
margin-top: 24px;
|
|
191
|
+
padding: 0 24px;
|
|
192
|
+
border: 0;
|
|
193
|
+
border-radius: 8px;
|
|
194
|
+
background: #eef1f3;
|
|
195
|
+
color: var(--kratos-color-text, #1f2937);
|
|
107
196
|
font-size: 28px;
|
|
197
|
+
line-height: 72px;
|
|
108
198
|
}
|
|
109
199
|
.empty {
|
|
110
|
-
padding
|
|
111
|
-
color: var(--kratos-color-text-muted);
|
|
200
|
+
padding: 120px 0;
|
|
201
|
+
color: var(--kratos-color-text-muted, #6b7280);
|
|
112
202
|
text-align: center;
|
|
113
203
|
}
|
|
114
204
|
.detail-page {
|
|
205
|
+
box-sizing: border-box;
|
|
115
206
|
min-height: 100vh;
|
|
116
|
-
padding:
|
|
117
|
-
background: var(--kratos-color-background);
|
|
207
|
+
padding: 24px 30px calc(96px + env(safe-area-inset-bottom));
|
|
208
|
+
background: var(--kratos-color-background, #f7f8fa);
|
|
118
209
|
}
|
|
119
210
|
.detail-title {
|
|
120
211
|
display: block;
|
|
121
|
-
color: var(--kratos-color-text);
|
|
212
|
+
color: var(--kratos-color-text, #1f2937);
|
|
122
213
|
font-size: 42px;
|
|
123
214
|
font-weight: 700;
|
|
124
215
|
line-height: 1.35;
|
|
@@ -128,11 +219,18 @@
|
|
|
128
219
|
flex-wrap: wrap;
|
|
129
220
|
gap: 18px;
|
|
130
221
|
margin: 24px 0 36px;
|
|
131
|
-
color: var(--kratos-color-text-muted);
|
|
222
|
+
color: var(--kratos-color-text-muted, #6b7280);
|
|
132
223
|
font-size: 24px;
|
|
133
224
|
}
|
|
225
|
+
.detail-category {
|
|
226
|
+
display: inline-flex;
|
|
227
|
+
align-items: center;
|
|
228
|
+
}
|
|
229
|
+
.detail-category__icon {
|
|
230
|
+
margin-right: 8px;
|
|
231
|
+
}
|
|
134
232
|
.detail-content {
|
|
135
|
-
color: var(--kratos-color-text);
|
|
233
|
+
color: var(--kratos-color-text, #1f2937);
|
|
136
234
|
font-size: 30px;
|
|
137
235
|
line-height: 1.8;
|
|
138
236
|
white-space: pre-wrap;
|
|
@@ -140,7 +238,7 @@
|
|
|
140
238
|
}
|
|
141
239
|
.detail-content-rich {
|
|
142
240
|
display: block;
|
|
143
|
-
color: var(--kratos-color-text);
|
|
241
|
+
color: var(--kratos-color-text, #1f2937);
|
|
144
242
|
font-size: 30px;
|
|
145
243
|
line-height: 1.8;
|
|
146
244
|
overflow-wrap: anywhere;
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
Image,
|
|
4
4
|
Input,
|
|
5
5
|
Label,
|
|
6
|
+
Picker,
|
|
6
7
|
Radio,
|
|
7
8
|
RadioGroup,
|
|
8
9
|
Text,
|
|
@@ -12,10 +13,11 @@ import Taro, { useLoad } from '@tarojs/taro'
|
|
|
12
13
|
import { useEffect, useState } from 'react'
|
|
13
14
|
import defaultAvatar from '@liujitcn/kratos-taro-app-core/static/images/avatar.png'
|
|
14
15
|
import navigatorBackground from '@liujitcn/kratos-taro-app-core/static/images/navigator_bg.png'
|
|
15
|
-
import { defAuthService } from '@liujitcn/kratos-taro-app-core/api/system/auth'
|
|
16
|
-
import { defBaseDictService } from '@liujitcn/kratos-taro-app-core/api/system/base_dict'
|
|
16
|
+
import { defAuthService } from '@liujitcn/kratos-taro-app-core/api/system/app/v1/auth'
|
|
17
|
+
import { defBaseDictService } from '@liujitcn/kratos-taro-app-core/api/system/app/v1/base_dict'
|
|
17
18
|
import type { BaseDictForm_DictItem } from '@liujitcn/kratos-taro-app-core/rpc/system/app/v1/base_dict'
|
|
18
19
|
import type { UserProfileForm } from '@liujitcn/kratos-taro-app-core/rpc/system/app/v1/auth'
|
|
20
|
+
import { BaseUserIDType } from '@liujitcn/kratos-taro-app-core/rpc/system/common/v1/common'
|
|
19
21
|
import {
|
|
20
22
|
formatSrc,
|
|
21
23
|
navigateToLogin,
|
|
@@ -26,6 +28,8 @@ import {
|
|
|
26
28
|
import './profile.scss'
|
|
27
29
|
|
|
28
30
|
const IMG_MAX_SIZE = 1024 * 1024
|
|
31
|
+
const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
|
32
|
+
const ID_CODE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9-]{0,63}$/
|
|
29
33
|
|
|
30
34
|
/** 用户个人资料编辑页。 */
|
|
31
35
|
export default function ProfilePage() {
|
|
@@ -35,11 +39,27 @@ export default function ProfilePage() {
|
|
|
35
39
|
nick_name: '',
|
|
36
40
|
gender: 0,
|
|
37
41
|
phone: '',
|
|
42
|
+
email: '',
|
|
43
|
+
id_type: BaseUserIDType.BASE_USER_ID_TYPE_UNSPECIFIED,
|
|
44
|
+
id_code: '',
|
|
38
45
|
avatar: '',
|
|
39
46
|
})
|
|
40
47
|
const [genderList, setGenderList] = useState<BaseDictForm_DictItem[]>([])
|
|
41
48
|
const ensureAuthenticated = useUserStore((state) => state.ensureAuthenticated)
|
|
42
49
|
const safeTop = Taro.getWindowInfo().safeArea?.top || 0
|
|
50
|
+
const idTypeOptions = [
|
|
51
|
+
{ label: t('system.profile.id_type.unspecified'), value: BaseUserIDType.BASE_USER_ID_TYPE_UNSPECIFIED },
|
|
52
|
+
{ label: t('system.profile.id_type.id_card'), value: BaseUserIDType.BASE_USER_ID_TYPE_ID_CARD },
|
|
53
|
+
{ label: t('system.profile.id_type.passport'), value: BaseUserIDType.BASE_USER_ID_TYPE_PASSPORT },
|
|
54
|
+
{ label: t('system.profile.id_type.hk_macao_permit'), value: BaseUserIDType.BASE_USER_ID_TYPE_HK_MACAO_PERMIT },
|
|
55
|
+
{ label: t('system.profile.id_type.taiwan_permit'), value: BaseUserIDType.BASE_USER_ID_TYPE_TAIWAN_PERMIT },
|
|
56
|
+
{
|
|
57
|
+
label: t('system.profile.id_type.foreign_permanent_residence'),
|
|
58
|
+
value: BaseUserIDType.BASE_USER_ID_TYPE_FOREIGN_PERMANENT_RESIDENCE,
|
|
59
|
+
},
|
|
60
|
+
{ label: t('system.profile.id_type.other'), value: BaseUserIDType.BASE_USER_ID_TYPE_OTHER },
|
|
61
|
+
]
|
|
62
|
+
const idTypeIndex = Math.max(0, idTypeOptions.findIndex((item) => item.value === userInfo.id_type))
|
|
43
63
|
|
|
44
64
|
useEffect(() => {
|
|
45
65
|
void Taro.setNavigationBarTitle({ title: t('system.profile.title') })
|
|
@@ -54,7 +74,7 @@ export default function ProfilePage() {
|
|
|
54
74
|
const loadData = async () => {
|
|
55
75
|
const [profile, gender] = await Promise.all([
|
|
56
76
|
useUserStore.getState().getUserProfile(),
|
|
57
|
-
defBaseDictService.GetBaseDict({
|
|
77
|
+
defBaseDictService.GetBaseDict({ code: 'base_user_gender' }),
|
|
58
78
|
])
|
|
59
79
|
setUserInfo(profile)
|
|
60
80
|
setGenderList(gender.items || [])
|
|
@@ -69,7 +89,7 @@ export default function ProfilePage() {
|
|
|
69
89
|
try {
|
|
70
90
|
const fileInfo = await uploadFile('avatar', filePath)
|
|
71
91
|
const nextProfile = { ...userInfo, avatar: fileInfo.url }
|
|
72
|
-
await defAuthService.UpdateUserProfile(nextProfile)
|
|
92
|
+
await defAuthService.UpdateUserProfile({ user_profile: nextProfile })
|
|
73
93
|
setUserInfo(nextProfile)
|
|
74
94
|
await useUserStore.getState().getUserProfile()
|
|
75
95
|
await Taro.showToast({ icon: 'success', title: t('system.profile.update_success') })
|
|
@@ -103,7 +123,15 @@ export default function ProfilePage() {
|
|
|
103
123
|
|
|
104
124
|
const onSubmit = async () => {
|
|
105
125
|
if (!requireAuth()) return
|
|
106
|
-
|
|
126
|
+
if (userInfo.email && !EMAIL_PATTERN.test(userInfo.email)) {
|
|
127
|
+
await Taro.showToast({ icon: 'none', title: t('system.profile.email_invalid') })
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
if (userInfo.id_code && !ID_CODE_PATTERN.test(userInfo.id_code)) {
|
|
131
|
+
await Taro.showToast({ icon: 'none', title: t('system.profile.id_code_invalid') })
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
await defAuthService.UpdateUserProfile({ user_profile: userInfo })
|
|
107
135
|
await useUserStore.getState().getUserProfile()
|
|
108
136
|
await Taro.showToast({ icon: 'success', title: t('system.profile.save_success') })
|
|
109
137
|
setTimeout(() => void Taro.navigateBack(), 400)
|
|
@@ -145,6 +173,25 @@ export default function ProfilePage() {
|
|
|
145
173
|
<Text className='profile-label'>{t('system.profile.nick_name')}</Text>
|
|
146
174
|
<Input className='profile-input' placeholder={t('system.profile.nick_name_placeholder')} value={userInfo.nick_name} onInput={(event) => setUserInfo((current) => ({ ...current, nick_name: event.detail.value }))} />
|
|
147
175
|
</View>
|
|
176
|
+
<View className='profile-form__item'>
|
|
177
|
+
<Text className='profile-label'>{t('system.profile.email')}</Text>
|
|
178
|
+
<Input className='profile-input' type='text' placeholder={t('system.profile.email_placeholder')} value={userInfo.email} onInput={(event) => setUserInfo((current) => ({ ...current, email: event.detail.value }))} />
|
|
179
|
+
</View>
|
|
180
|
+
<Picker
|
|
181
|
+
mode='selector'
|
|
182
|
+
range={idTypeOptions.map((item) => item.label)}
|
|
183
|
+
value={idTypeIndex}
|
|
184
|
+
onChange={(event) => setUserInfo((current) => ({ ...current, id_type: idTypeOptions[Number(event.detail.value)]?.value ?? BaseUserIDType.BASE_USER_ID_TYPE_UNSPECIFIED }))}
|
|
185
|
+
>
|
|
186
|
+
<View className='profile-form__item'>
|
|
187
|
+
<Text className='profile-label'>{t('system.profile.id_type')}</Text>
|
|
188
|
+
<Text className='profile-input profile-account'>{idTypeOptions[idTypeIndex]?.label}</Text>
|
|
189
|
+
</View>
|
|
190
|
+
</Picker>
|
|
191
|
+
<View className='profile-form__item'>
|
|
192
|
+
<Text className='profile-label'>{t('system.profile.id_code')}</Text>
|
|
193
|
+
<Input className='profile-input' type='text' placeholder={t('system.profile.id_code_placeholder')} value={userInfo.id_code} onInput={(event) => setUserInfo((current) => ({ ...current, id_code: event.detail.value }))} />
|
|
194
|
+
</View>
|
|
148
195
|
<View className='profile-form__item'>
|
|
149
196
|
<Text className='profile-label'>{t('system.profile.gender')}</Text>
|
|
150
197
|
<RadioGroup onChange={(event) => setUserInfo((current) => ({ ...current, gender: Number(event.detail.value) }))}>
|
|
@@ -3,7 +3,7 @@ import { useEffect, useState } from 'react'
|
|
|
3
3
|
import { useI18n } from '@liujitcn/kratos-taro-app-core'
|
|
4
4
|
import MfaRecoveryCodesDialog from '@liujitcn/kratos-taro-app-core/components/MfaRecoveryCodesDialog'
|
|
5
5
|
import MfaSetupPanel from '@liujitcn/kratos-taro-app-core/components/MfaSetupPanel'
|
|
6
|
-
import { defMfaService } from '@liujitcn/kratos-taro-app-core/api/base/mfa'
|
|
6
|
+
import { defMfaService } from '@liujitcn/kratos-taro-app-core/api/base/v1/mfa'
|
|
7
7
|
import {
|
|
8
8
|
createWebAuthnCredential,
|
|
9
9
|
getWebAuthnAssertion,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
useI18n,
|
|
9
9
|
useUserStore,
|
|
10
10
|
} from '@liujitcn/kratos-taro-app-core'
|
|
11
|
-
import { defMfaService } from '@liujitcn/kratos-taro-app-core/api/base/mfa'
|
|
11
|
+
import { defMfaService } from '@liujitcn/kratos-taro-app-core/api/base/v1/mfa'
|
|
12
12
|
import PasswordVerifyDialog from './components/PasswordVerifyDialog'
|
|
13
13
|
import './settings.scss'
|
|
14
14
|
|