@liujitcn/kratos-uni-app-core 0.0.78 → 0.0.80
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/dist/module.mjs +36 -6
- package/package.json +1 -1
- package/src/components/BootstrapStatus.vue +6 -4
- package/src/components/KratosSettingsPage.vue +161 -109
- package/src/components/KratosTabBar.vue +67 -16
- package/src/components/MfaManageDialog.vue +14 -13
- package/src/components/MfaRecoveryCodesDialog.vue +13 -12
- package/src/components/MfaSetupPanel.vue +8 -8
- package/src/components/PasswordVerifyDialog.vue +15 -14
- package/src/locales/en-US.json +8 -1
- package/src/locales/ja-JP.json +8 -1
- package/src/locales/zh-CN.json +8 -1
- package/src/locales/zh-TW.json +8 -1
- package/src/navigation.ts +10 -3
- package/src/pages.ts +4 -2
- package/src/stores/index.ts +1 -0
- package/src/stores/modules/theme.ts +111 -0
- package/src/styles/base.scss +57 -0
- package/src/styles/components.scss +770 -0
- package/src/styles/theme.scss +66 -0
- package/src/utils/index.ts +21 -0
- package/src/utils/navigation.ts +16 -0
- package/src/views/pages/index/index.vue +137 -141
- package/src/views/pages/login/login.vue +266 -274
- package/src/views/pages/login/protocal.vue +30 -20
- package/src/views/pages/webview/webview.vue +12 -6
|
@@ -363,7 +363,7 @@ watch(
|
|
|
363
363
|
.mfa-bind-dialog__panel {
|
|
364
364
|
width: min(100%, 680rpx);
|
|
365
365
|
overflow: hidden;
|
|
366
|
-
background-color:
|
|
366
|
+
background-color: var(--kratos-color-surface-solid);
|
|
367
367
|
border-radius: 16rpx;
|
|
368
368
|
box-shadow: 0 20rpx 64rpx rgb(0 0 0 / 20%);
|
|
369
369
|
}
|
|
@@ -373,17 +373,17 @@ watch(
|
|
|
373
373
|
align-items: center;
|
|
374
374
|
justify-content: space-between;
|
|
375
375
|
padding: 28rpx 32rpx;
|
|
376
|
-
border-bottom: 1rpx solid
|
|
376
|
+
border-bottom: 1rpx solid var(--kratos-color-border);
|
|
377
377
|
}
|
|
378
378
|
|
|
379
379
|
.mfa-bind-dialog__title {
|
|
380
|
-
color:
|
|
380
|
+
color: var(--kratos-color-text);
|
|
381
381
|
font-size: 34rpx;
|
|
382
382
|
font-weight: 600;
|
|
383
383
|
}
|
|
384
384
|
|
|
385
385
|
.mfa-bind-dialog__close {
|
|
386
|
-
color:
|
|
386
|
+
color: var(--kratos-color-text-muted);
|
|
387
387
|
font-size: 42rpx;
|
|
388
388
|
line-height: 1;
|
|
389
389
|
}
|
|
@@ -395,7 +395,7 @@ watch(
|
|
|
395
395
|
.mfa-bind-dialog__label {
|
|
396
396
|
display: block;
|
|
397
397
|
margin-bottom: 12rpx;
|
|
398
|
-
color:
|
|
398
|
+
color: var(--kratos-color-text);
|
|
399
399
|
font-size: 28rpx;
|
|
400
400
|
}
|
|
401
401
|
|
|
@@ -403,9 +403,10 @@ watch(
|
|
|
403
403
|
box-sizing: border-box;
|
|
404
404
|
width: 100%;
|
|
405
405
|
padding: 20rpx 24rpx;
|
|
406
|
-
color:
|
|
406
|
+
color: var(--kratos-color-text);
|
|
407
407
|
font-size: 30rpx;
|
|
408
|
-
border: 1rpx solid
|
|
408
|
+
border: 1rpx solid var(--kratos-color-border);
|
|
409
|
+
background-color: var(--kratos-color-surface-2);
|
|
409
410
|
border-radius: 8rpx;
|
|
410
411
|
}
|
|
411
412
|
|
|
@@ -422,7 +423,7 @@ watch(
|
|
|
422
423
|
}
|
|
423
424
|
|
|
424
425
|
.mfa-bind-dialog__error {
|
|
425
|
-
color:
|
|
426
|
+
color: var(--kratos-color-danger);
|
|
426
427
|
}
|
|
427
428
|
|
|
428
429
|
.mfa-bind-dialog__footer {
|
|
@@ -448,16 +449,16 @@ watch(
|
|
|
448
449
|
}
|
|
449
450
|
|
|
450
451
|
.mfa-bind-dialog__button--cancel {
|
|
451
|
-
color:
|
|
452
|
-
background-color:
|
|
452
|
+
color: var(--kratos-color-text-muted);
|
|
453
|
+
background-color: var(--kratos-color-track);
|
|
453
454
|
}
|
|
454
455
|
|
|
455
456
|
.mfa-bind-dialog__button--confirm {
|
|
456
|
-
color:
|
|
457
|
-
background-color:
|
|
457
|
+
color: var(--kratos-color-on-primary);
|
|
458
|
+
background-color: var(--kratos-color-primary);
|
|
458
459
|
}
|
|
459
460
|
|
|
460
461
|
.mfa-bind-dialog__button--danger {
|
|
461
|
-
background-color:
|
|
462
|
+
background-color: var(--kratos-color-danger);
|
|
462
463
|
}
|
|
463
464
|
</style>
|
|
@@ -115,18 +115,18 @@ onBeforeUnmount(() => {
|
|
|
115
115
|
.mfa-recovery-dialog__panel {
|
|
116
116
|
width: min(100%, 640rpx);
|
|
117
117
|
overflow: hidden;
|
|
118
|
-
background-color:
|
|
118
|
+
background-color: var(--kratos-color-surface-solid);
|
|
119
119
|
border-radius: 16rpx;
|
|
120
120
|
box-shadow: 0 20rpx 64rpx rgb(0 0 0 / 20%);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
.mfa-recovery-dialog__header {
|
|
124
124
|
padding: 28rpx 32rpx;
|
|
125
|
-
border-bottom: 1rpx solid
|
|
125
|
+
border-bottom: 1rpx solid var(--kratos-color-border);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
.mfa-recovery-dialog__title {
|
|
129
|
-
color:
|
|
129
|
+
color: var(--kratos-color-text);
|
|
130
130
|
font-size: 34rpx;
|
|
131
131
|
font-weight: 600;
|
|
132
132
|
}
|
|
@@ -141,10 +141,11 @@ onBeforeUnmount(() => {
|
|
|
141
141
|
min-height: 220rpx;
|
|
142
142
|
margin-bottom: 16rpx;
|
|
143
143
|
padding: 20rpx 24rpx;
|
|
144
|
-
color:
|
|
144
|
+
color: var(--kratos-color-text);
|
|
145
145
|
font-size: 30rpx;
|
|
146
146
|
line-height: 1.6;
|
|
147
|
-
border: 1rpx solid
|
|
147
|
+
border: 1rpx solid var(--kratos-color-border);
|
|
148
|
+
background-color: var(--kratos-color-surface-2);
|
|
148
149
|
border-radius: 8rpx;
|
|
149
150
|
overflow-wrap: anywhere;
|
|
150
151
|
white-space: pre-wrap;
|
|
@@ -156,10 +157,10 @@ onBeforeUnmount(() => {
|
|
|
156
157
|
height: 58rpx;
|
|
157
158
|
margin: 0;
|
|
158
159
|
padding: 0 18rpx;
|
|
159
|
-
color:
|
|
160
|
+
color: var(--kratos-color-primary);
|
|
160
161
|
font-size: 24rpx;
|
|
161
162
|
line-height: 58rpx;
|
|
162
|
-
background-color:
|
|
163
|
+
background-color: var(--kratos-color-primary-soft);
|
|
163
164
|
border: 0;
|
|
164
165
|
border-radius: 8rpx;
|
|
165
166
|
}
|
|
@@ -170,14 +171,14 @@ onBeforeUnmount(() => {
|
|
|
170
171
|
}
|
|
171
172
|
|
|
172
173
|
.mfa-recovery-dialog__copy.is-failed {
|
|
173
|
-
color:
|
|
174
|
-
background-color:
|
|
174
|
+
color: var(--kratos-color-danger);
|
|
175
|
+
background-color: var(--kratos-color-danger-soft);
|
|
175
176
|
}
|
|
176
177
|
|
|
177
178
|
.mfa-recovery-dialog__warning {
|
|
178
179
|
display: block;
|
|
179
180
|
margin-top: 12rpx;
|
|
180
|
-
color:
|
|
181
|
+
color: var(--kratos-color-warning);
|
|
181
182
|
font-size: 24rpx;
|
|
182
183
|
line-height: 1.5;
|
|
183
184
|
}
|
|
@@ -193,10 +194,10 @@ onBeforeUnmount(() => {
|
|
|
193
194
|
height: 72rpx;
|
|
194
195
|
margin: 0;
|
|
195
196
|
padding: 0 24rpx;
|
|
196
|
-
color:
|
|
197
|
+
color: var(--kratos-color-on-primary);
|
|
197
198
|
font-size: 28rpx;
|
|
198
199
|
line-height: 72rpx;
|
|
199
|
-
background-color:
|
|
200
|
+
background-color: var(--kratos-color-primary);
|
|
200
201
|
border: 0;
|
|
201
202
|
border-radius: 8rpx;
|
|
202
203
|
}
|
|
@@ -88,7 +88,7 @@ onBeforeUnmount(() => {
|
|
|
88
88
|
.mfa-setup-panel__uri-text {
|
|
89
89
|
flex: 1;
|
|
90
90
|
min-width: 0;
|
|
91
|
-
color:
|
|
91
|
+
color: var(--kratos-color-text-muted);
|
|
92
92
|
font-size: 24rpx;
|
|
93
93
|
line-height: 1.5;
|
|
94
94
|
overflow-wrap: anywhere;
|
|
@@ -103,8 +103,8 @@ onBeforeUnmount(() => {
|
|
|
103
103
|
height: 58rpx;
|
|
104
104
|
margin: 0;
|
|
105
105
|
padding: 0;
|
|
106
|
-
color:
|
|
107
|
-
background:
|
|
106
|
+
color: var(--kratos-color-primary);
|
|
107
|
+
background: var(--kratos-color-primary-soft);
|
|
108
108
|
border: 0;
|
|
109
109
|
border-radius: 8rpx;
|
|
110
110
|
}
|
|
@@ -114,13 +114,13 @@ onBeforeUnmount(() => {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
.mfa-setup-panel__copy.is-copied {
|
|
117
|
-
color:
|
|
118
|
-
background:
|
|
117
|
+
color: var(--kratos-color-on-primary);
|
|
118
|
+
background: var(--kratos-color-primary);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
.mfa-setup-panel__copy.is-failed {
|
|
122
|
-
color:
|
|
123
|
-
background:
|
|
122
|
+
color: var(--kratos-color-danger);
|
|
123
|
+
background: var(--kratos-color-danger-soft);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
.mfa-setup-panel__status {
|
|
@@ -155,6 +155,6 @@ onBeforeUnmount(() => {
|
|
|
155
155
|
.mfa-setup-panel__copy-front {
|
|
156
156
|
right: 0;
|
|
157
157
|
bottom: 0;
|
|
158
|
-
background-color:
|
|
158
|
+
background-color: var(--kratos-color-primary-soft);
|
|
159
159
|
}
|
|
160
160
|
</style>
|
|
@@ -169,7 +169,7 @@ watch(
|
|
|
169
169
|
.password-verify-dialog__panel {
|
|
170
170
|
width: min(100%, 640rpx);
|
|
171
171
|
overflow: hidden;
|
|
172
|
-
background-color:
|
|
172
|
+
background-color: var(--kratos-color-surface-solid);
|
|
173
173
|
border-radius: 16rpx;
|
|
174
174
|
box-shadow: 0 20rpx 64rpx rgb(0 0 0 / 20%);
|
|
175
175
|
}
|
|
@@ -179,18 +179,18 @@ watch(
|
|
|
179
179
|
align-items: center;
|
|
180
180
|
justify-content: space-between;
|
|
181
181
|
padding: 28rpx 32rpx;
|
|
182
|
-
border-bottom: 1rpx solid
|
|
182
|
+
border-bottom: 1rpx solid var(--kratos-color-border);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
.password-verify-dialog__title {
|
|
186
|
-
color:
|
|
186
|
+
color: var(--kratos-color-text);
|
|
187
187
|
font-size: 34rpx;
|
|
188
188
|
font-weight: 600;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
.password-verify-dialog__close {
|
|
192
192
|
padding: 0 8rpx;
|
|
193
|
-
color:
|
|
193
|
+
color: var(--kratos-color-text-muted);
|
|
194
194
|
font-size: 42rpx;
|
|
195
195
|
line-height: 1;
|
|
196
196
|
}
|
|
@@ -202,7 +202,7 @@ watch(
|
|
|
202
202
|
.password-verify-dialog__description {
|
|
203
203
|
display: block;
|
|
204
204
|
margin-bottom: 24rpx;
|
|
205
|
-
color:
|
|
205
|
+
color: var(--kratos-color-text-muted);
|
|
206
206
|
font-size: 26rpx;
|
|
207
207
|
line-height: 1.6;
|
|
208
208
|
}
|
|
@@ -210,7 +210,7 @@ watch(
|
|
|
210
210
|
.password-verify-dialog__label {
|
|
211
211
|
display: block;
|
|
212
212
|
margin-bottom: 12rpx;
|
|
213
|
-
color:
|
|
213
|
+
color: var(--kratos-color-text);
|
|
214
214
|
font-size: 28rpx;
|
|
215
215
|
}
|
|
216
216
|
|
|
@@ -219,20 +219,21 @@ watch(
|
|
|
219
219
|
width: 100%;
|
|
220
220
|
height: 84rpx;
|
|
221
221
|
padding: 0 24rpx;
|
|
222
|
-
color:
|
|
222
|
+
color: var(--kratos-color-text);
|
|
223
223
|
font-size: 30rpx;
|
|
224
|
-
border: 1rpx solid
|
|
224
|
+
border: 1rpx solid var(--kratos-color-border);
|
|
225
|
+
background-color: var(--kratos-color-surface-2);
|
|
225
226
|
border-radius: 8rpx;
|
|
226
227
|
}
|
|
227
228
|
|
|
228
229
|
.password-verify-dialog__input:focus {
|
|
229
|
-
border-color:
|
|
230
|
+
border-color: var(--kratos-color-primary);
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
.password-verify-dialog__error {
|
|
233
234
|
display: block;
|
|
234
235
|
margin-top: 10rpx;
|
|
235
|
-
color:
|
|
236
|
+
color: var(--kratos-color-danger);
|
|
236
237
|
font-size: 24rpx;
|
|
237
238
|
}
|
|
238
239
|
|
|
@@ -259,13 +260,13 @@ watch(
|
|
|
259
260
|
}
|
|
260
261
|
|
|
261
262
|
.password-verify-dialog__button--cancel {
|
|
262
|
-
color:
|
|
263
|
-
background-color:
|
|
263
|
+
color: var(--kratos-color-text-muted);
|
|
264
|
+
background-color: var(--kratos-color-track);
|
|
264
265
|
}
|
|
265
266
|
|
|
266
267
|
.password-verify-dialog__button--confirm {
|
|
267
|
-
color:
|
|
268
|
-
background-color:
|
|
268
|
+
color: var(--kratos-color-on-primary);
|
|
269
|
+
background-color: var(--kratos-color-primary);
|
|
269
270
|
}
|
|
270
271
|
|
|
271
272
|
.password-verify-dialog__button[disabled] {
|
package/src/locales/en-US.json
CHANGED
|
@@ -115,6 +115,9 @@
|
|
|
115
115
|
"core.settings.authorization": "Authorization settings",
|
|
116
116
|
"core.settings.contact": "Contact us",
|
|
117
117
|
"core.settings.feedback": "Feedback",
|
|
118
|
+
"core.settings.section_appearance": "Appearance",
|
|
119
|
+
"core.settings.section_security": "Account security",
|
|
120
|
+
"core.settings.section_more": "More · Mini Program",
|
|
118
121
|
"core.settings.logout_confirm": "Log out now?",
|
|
119
122
|
"core.settings.logout_failed": "Logout failed",
|
|
120
123
|
"core.settings.mfa_bind_success": "Multi-factor authentication enabled",
|
|
@@ -144,5 +147,9 @@
|
|
|
144
147
|
"common.action.load_more": "Load more",
|
|
145
148
|
"common.status.loading": "Loading…",
|
|
146
149
|
"core.navigation.analytics": "Analytics",
|
|
147
|
-
"core.navigation.report": "Reports"
|
|
150
|
+
"core.navigation.report": "Reports",
|
|
151
|
+
"core.settings.theme": "Theme Appearance",
|
|
152
|
+
"core.theme.auto": "Follow System",
|
|
153
|
+
"core.theme.dark": "Dark",
|
|
154
|
+
"core.theme.light": "Light"
|
|
148
155
|
}
|
package/src/locales/ja-JP.json
CHANGED
|
@@ -115,6 +115,9 @@
|
|
|
115
115
|
"core.settings.authorization": "認可管理",
|
|
116
116
|
"core.settings.contact": "お問い合わせ",
|
|
117
117
|
"core.settings.feedback": "問題のフィードバック",
|
|
118
|
+
"core.settings.section_appearance": "外観",
|
|
119
|
+
"core.settings.section_security": "アカウントセキュリティ",
|
|
120
|
+
"core.settings.section_more": "その他・ミニプログラム",
|
|
118
121
|
"core.settings.logout_confirm": "ログアウトしますか?",
|
|
119
122
|
"core.settings.logout_failed": "ログアウトに失敗しました",
|
|
120
123
|
"core.settings.mfa_bind_success": "多要素認証を有効にしました",
|
|
@@ -144,5 +147,9 @@
|
|
|
144
147
|
"common.action.load_more": "さらに読み込む",
|
|
145
148
|
"common.status.loading": "読み込み中…",
|
|
146
149
|
"core.navigation.analytics": "分析",
|
|
147
|
-
"core.navigation.report": "レポート"
|
|
150
|
+
"core.navigation.report": "レポート",
|
|
151
|
+
"core.settings.theme": "テーマ外観",
|
|
152
|
+
"core.theme.auto": "システムに従う",
|
|
153
|
+
"core.theme.dark": "ダーク",
|
|
154
|
+
"core.theme.light": "ライト"
|
|
148
155
|
}
|
package/src/locales/zh-CN.json
CHANGED
|
@@ -115,6 +115,9 @@
|
|
|
115
115
|
"core.settings.authorization": "授权管理",
|
|
116
116
|
"core.settings.contact": "联系我们",
|
|
117
117
|
"core.settings.feedback": "问题反馈",
|
|
118
|
+
"core.settings.section_appearance": "外观",
|
|
119
|
+
"core.settings.section_security": "账户安全",
|
|
120
|
+
"core.settings.section_more": "更多 · 小程序端",
|
|
118
121
|
"core.settings.logout_confirm": "是否退出登录?",
|
|
119
122
|
"core.settings.logout_failed": "退出登录失败",
|
|
120
123
|
"core.settings.mfa_bind_success": "多因素认证绑定成功",
|
|
@@ -144,5 +147,9 @@
|
|
|
144
147
|
"common.action.load_more": "加载更多",
|
|
145
148
|
"common.status.loading": "加载中…",
|
|
146
149
|
"core.navigation.analytics": "分析",
|
|
147
|
-
"core.navigation.report": "报表"
|
|
150
|
+
"core.navigation.report": "报表",
|
|
151
|
+
"core.settings.theme": "主题外观",
|
|
152
|
+
"core.theme.auto": "跟随系统",
|
|
153
|
+
"core.theme.dark": "暗黑",
|
|
154
|
+
"core.theme.light": "明亮"
|
|
148
155
|
}
|
package/src/locales/zh-TW.json
CHANGED
|
@@ -115,6 +115,9 @@
|
|
|
115
115
|
"core.settings.authorization": "授權管理",
|
|
116
116
|
"core.settings.contact": "聯絡我們",
|
|
117
117
|
"core.settings.feedback": "問題反饋",
|
|
118
|
+
"core.settings.section_appearance": "外觀",
|
|
119
|
+
"core.settings.section_security": "帳戶安全",
|
|
120
|
+
"core.settings.section_more": "更多・小程式端",
|
|
118
121
|
"core.settings.logout_confirm": "是否退出登入?",
|
|
119
122
|
"core.settings.logout_failed": "退出登入失敗",
|
|
120
123
|
"core.settings.mfa_bind_success": "多因素認證綁定成功",
|
|
@@ -144,5 +147,9 @@
|
|
|
144
147
|
"common.action.load_more": "載入更多",
|
|
145
148
|
"common.status.loading": "載入中…",
|
|
146
149
|
"core.navigation.analytics": "分析",
|
|
147
|
-
"core.navigation.report": "報表"
|
|
150
|
+
"core.navigation.report": "報表",
|
|
151
|
+
"core.settings.theme": "主題外觀",
|
|
152
|
+
"core.theme.auto": "跟隨系統",
|
|
153
|
+
"core.theme.dark": "暗黑",
|
|
154
|
+
"core.theme.light": "明亮"
|
|
148
155
|
}
|
package/src/navigation.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { computed, readonly, ref } from 'vue'
|
|
|
2
2
|
import { defBaseMenuService } from './api/system/app/v1/base_menu'
|
|
3
3
|
import type { BaseMenu, ListBaseMenuResponse } from './rpc/system/app/v1/base_menu'
|
|
4
4
|
import { hasValidToken } from './utils/auth'
|
|
5
|
-
import {
|
|
5
|
+
import { redirectToLogin } from './utils/navigation'
|
|
6
6
|
import { resolveStaticView } from './module'
|
|
7
7
|
import { matchLogicalPath, parseLogicalQuery } from './navigation-pattern.mjs'
|
|
8
8
|
import { buildMenuTree } from './navigation-tree.mjs'
|
|
@@ -233,8 +233,9 @@ export function navigateAppRoute(rawRoute: string, options: { replace?: boolean
|
|
|
233
233
|
launchAppStatus('NOT_FOUND')
|
|
234
234
|
return
|
|
235
235
|
}
|
|
236
|
+
// 守卫拦截用替换式跳转:登录页顶掉当前页,返回时不再弹回被拦截的页面形成循环。
|
|
236
237
|
if (resolved.menu.access === 'AUTHENTICATED' && !hasValidToken()) {
|
|
237
|
-
|
|
238
|
+
redirectToLogin(`/pages/bootstrap/index?route=${encodeURIComponent(rawRoute)}`)
|
|
238
239
|
return
|
|
239
240
|
}
|
|
240
241
|
if (resolved.menu.access === 'GUEST_ONLY' && hasValidToken()) {
|
|
@@ -270,7 +271,13 @@ function navigateTabRoute(url: string): void {
|
|
|
270
271
|
if (tabNavigationTarget === targetRoute) tabNavigationTarget = undefined
|
|
271
272
|
}
|
|
272
273
|
if (isH5Runtime) {
|
|
273
|
-
uni.
|
|
274
|
+
uni.redirectTo({
|
|
275
|
+
url,
|
|
276
|
+
success: release,
|
|
277
|
+
fail: () => {
|
|
278
|
+
uni.reLaunch({ url, success: release, fail: release, complete: release })
|
|
279
|
+
},
|
|
280
|
+
})
|
|
274
281
|
return
|
|
275
282
|
}
|
|
276
283
|
if (nativeTabViewKeys.some((viewKey) => resolveStaticView(viewKey) === targetRoute)) {
|
package/src/pages.ts
CHANGED
|
@@ -9,8 +9,10 @@ export const corePages: Record<string, KratosAppPageConfig> = {
|
|
|
9
9
|
navigationBarTitleText: '',
|
|
10
10
|
},
|
|
11
11
|
},
|
|
12
|
-
'pages/login/login': {
|
|
13
|
-
|
|
12
|
+
'pages/login/login': {
|
|
13
|
+
style: { navigationStyle: 'custom', navigationBarTitleText: '' },
|
|
14
|
+
},
|
|
15
|
+
'pages/login/protocal': { style: { navigationStyle: 'custom', navigationBarTitleText: '' } },
|
|
14
16
|
'pages/webview/webview': {
|
|
15
17
|
style: {
|
|
16
18
|
navigationBarTitleText: '',
|
package/src/stores/index.ts
CHANGED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { defineStore } from 'pinia'
|
|
2
|
+
import { computed, ref, watch } from 'vue'
|
|
3
|
+
|
|
4
|
+
/** 主题模式:暗黑、明亮、跟随系统。 */
|
|
5
|
+
export type ThemeMode = 'dark' | 'light' | 'auto'
|
|
6
|
+
/** 实际生效的主题。 */
|
|
7
|
+
export type ResolvedTheme = 'dark' | 'light'
|
|
8
|
+
|
|
9
|
+
const THEME_MODE_STORAGE_KEY = 'kratos_theme_mode'
|
|
10
|
+
const DEFAULT_THEME_MODE: ThemeMode = 'light'
|
|
11
|
+
|
|
12
|
+
/** 判断当前运行环境是否为 H5。 */
|
|
13
|
+
const isH5 = () => {
|
|
14
|
+
// #ifdef H5
|
|
15
|
+
return true
|
|
16
|
+
// #endif
|
|
17
|
+
// #ifndef H5
|
|
18
|
+
return false
|
|
19
|
+
// #endif
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** 读取系统主题;系统未上报时回退明亮。 */
|
|
23
|
+
const readSystemTheme = (): ResolvedTheme => {
|
|
24
|
+
if (isH5() && typeof window.matchMedia === 'function') {
|
|
25
|
+
return window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
return uni.getSystemInfoSync().theme === 'dark' ? 'dark' : 'light'
|
|
29
|
+
} catch {
|
|
30
|
+
return 'light'
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** 读取本地持久化的主题模式。 */
|
|
35
|
+
const readStoredMode = (): ThemeMode => {
|
|
36
|
+
try {
|
|
37
|
+
const stored = uni.getStorageSync(THEME_MODE_STORAGE_KEY)
|
|
38
|
+
if (stored === 'dark' || stored === 'light' || stored === 'auto') return stored
|
|
39
|
+
} catch {
|
|
40
|
+
// 存储读取失败时使用默认主题。
|
|
41
|
+
}
|
|
42
|
+
return DEFAULT_THEME_MODE
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** 主题实际生效时给导航栏与页面底色染色,覆盖 pages.json 的静态浅色配置。 */
|
|
46
|
+
const applyChrome = (theme: ResolvedTheme) => {
|
|
47
|
+
try {
|
|
48
|
+
const navigationBarColor = theme === 'light' ? '#f4f9fd' : '#060a12'
|
|
49
|
+
uni.setNavigationBarColor({
|
|
50
|
+
frontColor: theme === 'light' ? '#000000' : '#ffffff',
|
|
51
|
+
backgroundColor: navigationBarColor,
|
|
52
|
+
fail: () => undefined,
|
|
53
|
+
})
|
|
54
|
+
uni.setBackgroundColor({ backgroundColor: navigationBarColor, fail: () => undefined })
|
|
55
|
+
} catch {
|
|
56
|
+
// 部分平台/版本未暴露导航栏染色 API,跳过不影响主题类。
|
|
57
|
+
}
|
|
58
|
+
// H5 弹层(showModal/showToast)挂在 body 下,取不到页面根类,把主题类镜像到 html 上。
|
|
59
|
+
if (isH5() && typeof document !== 'undefined') {
|
|
60
|
+
document.documentElement.classList.toggle('theme-dark', theme === 'dark')
|
|
61
|
+
document.documentElement.classList.toggle('theme-light', theme === 'light')
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** 全局主题状态:模式持久化存储,auto 跟随系统深浅色。 */
|
|
66
|
+
export const useThemeStore = defineStore('theme', () => {
|
|
67
|
+
const mode = ref<ThemeMode>(readStoredMode())
|
|
68
|
+
const systemTheme = ref<ResolvedTheme>(readSystemTheme())
|
|
69
|
+
|
|
70
|
+
const theme = computed<ResolvedTheme>(() =>
|
|
71
|
+
mode.value === 'auto' ? systemTheme.value : mode.value,
|
|
72
|
+
)
|
|
73
|
+
const themeClass = computed(() => `theme-${theme.value}`)
|
|
74
|
+
|
|
75
|
+
/** 切换主题模式并持久化。 */
|
|
76
|
+
const setMode = (nextMode: ThemeMode) => {
|
|
77
|
+
mode.value = nextMode
|
|
78
|
+
try {
|
|
79
|
+
uni.setStorageSync(THEME_MODE_STORAGE_KEY, nextMode)
|
|
80
|
+
} catch {
|
|
81
|
+
// 存储写入失败不影响当前会话主题。
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 跟随系统:H5 监听 matchMedia,小程序监听 onThemeChange。
|
|
86
|
+
if (isH5()) {
|
|
87
|
+
if (typeof window.matchMedia === 'function') {
|
|
88
|
+
const media = window.matchMedia('(prefers-color-scheme: light)')
|
|
89
|
+
const listener = (event: MediaQueryListEvent) => {
|
|
90
|
+
systemTheme.value = event.matches ? 'light' : 'dark'
|
|
91
|
+
}
|
|
92
|
+
if (typeof media.addEventListener === 'function') {
|
|
93
|
+
media.addEventListener('change', listener)
|
|
94
|
+
} else if (typeof media.addListener === 'function') {
|
|
95
|
+
media.addListener(listener)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
try {
|
|
100
|
+
uni.onThemeChange?.((result: { theme?: string }) => {
|
|
101
|
+
systemTheme.value = result.theme === 'light' ? 'light' : 'dark'
|
|
102
|
+
})
|
|
103
|
+
} catch {
|
|
104
|
+
// 平台不支持系统主题回调时保持启动时读取的值。
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
watch(theme, (value) => applyChrome(value), { immediate: true })
|
|
109
|
+
|
|
110
|
+
return { mode, theme, themeClass, setMode }
|
|
111
|
+
})
|
package/src/styles/base.scss
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
@use './theme.scss';
|
|
2
|
+
@use './components.scss';
|
|
3
|
+
|
|
1
4
|
view,
|
|
2
5
|
navigator,
|
|
3
6
|
input,
|
|
@@ -40,3 +43,57 @@ image {
|
|
|
40
43
|
color: #dd524d;
|
|
41
44
|
margin-right: 8rpx;
|
|
42
45
|
}
|
|
46
|
+
|
|
47
|
+
/* ============================================================
|
|
48
|
+
* H5 系统弹层随主题:uni.showModal/showToast 渲染在 body 下,
|
|
49
|
+
* 取不到页面根类,用 theme store 镜像到 html 上的主题类着色。
|
|
50
|
+
* ============================================================ */
|
|
51
|
+
/* #ifdef H5 */
|
|
52
|
+
html.theme-light page {
|
|
53
|
+
background-color: #eef3f8;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
html.theme-dark page {
|
|
57
|
+
background-color: #060a12;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
html.theme-dark .uni-modal {
|
|
61
|
+
background-color: #070d18;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
html.theme-dark .uni-modal__title {
|
|
65
|
+
color: #e9f4f6;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
html.theme-dark .uni-modal__bd {
|
|
69
|
+
color: #8aa0b4;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
html.theme-dark .uni-modal__btn_default {
|
|
73
|
+
color: #8aa0b4;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
html.theme-dark .uni-modal__btn_primary {
|
|
77
|
+
color: #28f0d4;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
html.theme-dark .uni-toast,
|
|
81
|
+
html.theme-dark .uni-sample-toast {
|
|
82
|
+
background: rgba(10, 18, 30, 0.9);
|
|
83
|
+
border: 1px solid rgba(120, 230, 215, 0.16);
|
|
84
|
+
color: #e9f4f6;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* Chrome 密码自动填充默认涂浅蓝底,用不透明内阴影盖回主题色 */
|
|
88
|
+
html.theme-dark .uni-input-input:-webkit-autofill {
|
|
89
|
+
-webkit-box-shadow: 0 0 0 1000px #121b2a inset;
|
|
90
|
+
-webkit-text-fill-color: #e9f4f6;
|
|
91
|
+
caret-color: #e9f4f6;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
html.theme-light .uni-input-input:-webkit-autofill {
|
|
95
|
+
-webkit-box-shadow: 0 0 0 1000px #eef4fa inset;
|
|
96
|
+
-webkit-text-fill-color: #102232;
|
|
97
|
+
caret-color: #102232;
|
|
98
|
+
}
|
|
99
|
+
/* #endif */
|