@liujitcn/kratos-uni-app-core 0.0.81 → 0.0.83
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 -0
- package/dist/module.mjs +28 -69
- package/package.json +1 -1
- package/src/components/KratosEmpty.vue +35 -0
- package/src/components/KratosTabBar.vue +8 -17
- package/src/index.ts +2 -0
- package/src/locales/README.md +1 -1
- package/src/locales/en-US.json +7 -17
- package/src/locales/ja-JP.json +7 -17
- package/src/locales/zh-CN.json +7 -17
- package/src/locales/zh-TW.json +7 -17
- package/src/navigation.ts +42 -16
- package/src/pages.ts +0 -1
- package/src/styles/base.scss +21 -0
- package/src/styles/components.scss +122 -73
- package/src/utils/http.ts +25 -9
- package/src/utils/navigation.ts +36 -5
- package/src/views/pages/index/index.vue +35 -15
- package/src/views/pages/login/login.vue +13 -19
|
@@ -12,50 +12,16 @@
|
|
|
12
12
|
.k-glass {
|
|
13
13
|
position: relative;
|
|
14
14
|
overflow: hidden;
|
|
15
|
-
border:
|
|
15
|
+
border: 1px solid var(--kratos-color-border);
|
|
16
16
|
border-radius: 26rpx;
|
|
17
17
|
background: var(--kratos-color-surface);
|
|
18
|
-
box-shadow: inset 0
|
|
18
|
+
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
|
19
19
|
}
|
|
20
20
|
.k-glass--lit {
|
|
21
21
|
border-color: var(--kratos-color-border-accent);
|
|
22
22
|
box-shadow: var(--kratos-glow-soft);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
/* 四角 L 形角标:渲染为真实 view 节点(weapp 伪元素仅支持 view) */
|
|
26
|
-
.k-cnr {
|
|
27
|
-
position: absolute;
|
|
28
|
-
width: 24rpx;
|
|
29
|
-
height: 24rpx;
|
|
30
|
-
border: 3rpx solid var(--kratos-color-primary);
|
|
31
|
-
opacity: 0.5;
|
|
32
|
-
pointer-events: none;
|
|
33
|
-
}
|
|
34
|
-
.k-cnr--tl {
|
|
35
|
-
top: 16rpx;
|
|
36
|
-
left: 16rpx;
|
|
37
|
-
border-right: 0;
|
|
38
|
-
border-bottom: 0;
|
|
39
|
-
}
|
|
40
|
-
.k-cnr--tr {
|
|
41
|
-
top: 16rpx;
|
|
42
|
-
right: 16rpx;
|
|
43
|
-
border-left: 0;
|
|
44
|
-
border-bottom: 0;
|
|
45
|
-
}
|
|
46
|
-
.k-cnr--bl {
|
|
47
|
-
bottom: 16rpx;
|
|
48
|
-
left: 16rpx;
|
|
49
|
-
border-right: 0;
|
|
50
|
-
border-top: 0;
|
|
51
|
-
}
|
|
52
|
-
.k-cnr--br {
|
|
53
|
-
bottom: 16rpx;
|
|
54
|
-
right: 16rpx;
|
|
55
|
-
border-left: 0;
|
|
56
|
-
border-top: 0;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
25
|
/* 装饰网格背景 */
|
|
60
26
|
.k-grid-bg {
|
|
61
27
|
position: absolute;
|
|
@@ -105,7 +71,7 @@
|
|
|
105
71
|
justify-content: space-between;
|
|
106
72
|
gap: 24rpx;
|
|
107
73
|
padding: 28rpx 0;
|
|
108
|
-
border-top:
|
|
74
|
+
border-top: 1px solid var(--kratos-color-border);
|
|
109
75
|
}
|
|
110
76
|
.k-field:first-child {
|
|
111
77
|
border-top: 0;
|
|
@@ -168,15 +134,15 @@
|
|
|
168
134
|
height: 76rpx;
|
|
169
135
|
}
|
|
170
136
|
.k-page-nav__back {
|
|
171
|
-
border:
|
|
137
|
+
border: 1px solid var(--kratos-color-border);
|
|
172
138
|
border-radius: 24rpx;
|
|
173
139
|
background: var(--kratos-color-surface);
|
|
174
140
|
}
|
|
175
141
|
.k-page-nav__back::before {
|
|
176
142
|
width: 16rpx;
|
|
177
143
|
height: 16rpx;
|
|
178
|
-
border-left:
|
|
179
|
-
border-bottom:
|
|
144
|
+
border-left: 2px solid var(--kratos-color-primary);
|
|
145
|
+
border-bottom: 2px solid var(--kratos-color-primary);
|
|
180
146
|
content: '';
|
|
181
147
|
transform: rotate(45deg);
|
|
182
148
|
}
|
|
@@ -186,31 +152,44 @@
|
|
|
186
152
|
max-width: calc(100% - 190rpx);
|
|
187
153
|
overflow: hidden;
|
|
188
154
|
color: var(--kratos-color-text);
|
|
189
|
-
font-size:
|
|
190
|
-
font-weight:
|
|
155
|
+
font-size: 32rpx;
|
|
156
|
+
font-weight: 700;
|
|
191
157
|
text-overflow: ellipsis;
|
|
192
158
|
transform: translateX(-50%);
|
|
193
159
|
white-space: nowrap;
|
|
194
160
|
}
|
|
195
161
|
.k-top {
|
|
162
|
+
position: relative;
|
|
196
163
|
display: flex;
|
|
197
164
|
align-items: center;
|
|
198
|
-
|
|
165
|
+
/* 标题绝对居中后,流内子元素(右侧动作按钮)统一靠右排布 */
|
|
166
|
+
justify-content: flex-end;
|
|
199
167
|
gap: 16rpx;
|
|
200
168
|
/* MP-WEIXIN 原生胶囊避让:页面通过 getMpCapsuleRightGap() 写入该变量,
|
|
201
169
|
其余平台未设置时回退 0,不影响布局。 */
|
|
202
170
|
padding-right: var(--mp-capsule-gap, 0px);
|
|
203
171
|
}
|
|
172
|
+
/* #ifdef MP-WEIXIN */
|
|
173
|
+
/* 双写类名提高优先级:页面级 padding 简写(如 .message-header)不得压掉导航带 */
|
|
174
|
+
.k-top.k-top {
|
|
175
|
+
/* 小程序右上角是原生胶囊:操作按钮靠左,标题行与胶囊同行(同 k-page-nav 几何) */
|
|
176
|
+
justify-content: flex-start;
|
|
177
|
+
height: calc(88rpx + 44px);
|
|
178
|
+
padding-top: 44px;
|
|
179
|
+
padding-right: 0;
|
|
180
|
+
}
|
|
181
|
+
/* #endif */
|
|
204
182
|
.k-top__title {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
183
|
+
position: absolute;
|
|
184
|
+
left: 50%;
|
|
185
|
+
max-width: calc(100% - 190rpx);
|
|
186
|
+
overflow: hidden;
|
|
208
187
|
color: var(--kratos-color-text);
|
|
209
|
-
}
|
|
210
|
-
.k-top__t2 {
|
|
211
188
|
font-size: 32rpx;
|
|
212
189
|
font-weight: 700;
|
|
213
|
-
|
|
190
|
+
text-overflow: ellipsis;
|
|
191
|
+
transform: translateX(-50%);
|
|
192
|
+
white-space: nowrap;
|
|
214
193
|
}
|
|
215
194
|
|
|
216
195
|
/* 方形图标按钮 + 角标 */
|
|
@@ -223,7 +202,7 @@
|
|
|
223
202
|
height: 76rpx;
|
|
224
203
|
border-radius: 24rpx;
|
|
225
204
|
background: var(--kratos-color-surface);
|
|
226
|
-
border:
|
|
205
|
+
border: 1px solid var(--kratos-color-border);
|
|
227
206
|
color: var(--kratos-color-text);
|
|
228
207
|
}
|
|
229
208
|
.k-ic--gh {
|
|
@@ -254,7 +233,7 @@
|
|
|
254
233
|
justify-content: space-between;
|
|
255
234
|
gap: 28rpx;
|
|
256
235
|
padding: 26rpx 0;
|
|
257
|
-
border-top:
|
|
236
|
+
border-top: 1px solid var(--kratos-color-border);
|
|
258
237
|
}
|
|
259
238
|
.k-kv:first-child {
|
|
260
239
|
border-top: 0;
|
|
@@ -281,7 +260,7 @@
|
|
|
281
260
|
padding: 8rpx 20rpx;
|
|
282
261
|
border-radius: 999rpx;
|
|
283
262
|
background: var(--kratos-color-primary-soft-2);
|
|
284
|
-
border:
|
|
263
|
+
border: 1px solid var(--kratos-color-border-accent);
|
|
285
264
|
color: var(--kratos-color-primary);
|
|
286
265
|
font-size: 20rpx;
|
|
287
266
|
font-family: var(--kratos-font-mono);
|
|
@@ -294,7 +273,7 @@
|
|
|
294
273
|
padding: 6rpx;
|
|
295
274
|
border-radius: 22rpx;
|
|
296
275
|
background: var(--kratos-color-track);
|
|
297
|
-
border:
|
|
276
|
+
border: 1px solid var(--kratos-color-border);
|
|
298
277
|
}
|
|
299
278
|
.k-pills__item {
|
|
300
279
|
padding: 12rpx 24rpx;
|
|
@@ -311,12 +290,20 @@
|
|
|
311
290
|
box-shadow: var(--kratos-glow-soft);
|
|
312
291
|
}
|
|
313
292
|
|
|
314
|
-
/*
|
|
293
|
+
/* 过滤芯片:单行横向滚动,超出隐藏滚动条 */
|
|
315
294
|
.k-chips {
|
|
316
295
|
display: flex;
|
|
317
|
-
flex-wrap:
|
|
296
|
+
flex-wrap: nowrap;
|
|
318
297
|
gap: 16rpx;
|
|
319
298
|
margin-bottom: 24rpx;
|
|
299
|
+
overflow-x: auto;
|
|
300
|
+
scrollbar-width: none;
|
|
301
|
+
}
|
|
302
|
+
.k-chips::-webkit-scrollbar {
|
|
303
|
+
display: none;
|
|
304
|
+
}
|
|
305
|
+
.k-chips .k-ch {
|
|
306
|
+
flex: 0 0 auto;
|
|
320
307
|
}
|
|
321
308
|
.k-ch {
|
|
322
309
|
display: inline-flex;
|
|
@@ -325,7 +312,7 @@
|
|
|
325
312
|
padding: 14rpx 24rpx;
|
|
326
313
|
border-radius: 999rpx;
|
|
327
314
|
background: var(--kratos-color-surface);
|
|
328
|
-
border:
|
|
315
|
+
border: 1px solid var(--kratos-color-border);
|
|
329
316
|
color: var(--kratos-color-text-muted);
|
|
330
317
|
font-size: 22rpx;
|
|
331
318
|
font-family: var(--kratos-font-mono);
|
|
@@ -355,7 +342,7 @@
|
|
|
355
342
|
padding: 12rpx 24rpx;
|
|
356
343
|
border-radius: 999rpx;
|
|
357
344
|
background: var(--kratos-color-surface);
|
|
358
|
-
border:
|
|
345
|
+
border: 1px solid var(--kratos-color-border);
|
|
359
346
|
color: var(--kratos-color-text-muted);
|
|
360
347
|
font-size: 22rpx;
|
|
361
348
|
font-family: var(--kratos-font-mono);
|
|
@@ -382,7 +369,7 @@
|
|
|
382
369
|
right: -12rpx;
|
|
383
370
|
bottom: -12rpx;
|
|
384
371
|
left: -12rpx;
|
|
385
|
-
border:
|
|
372
|
+
border: 1px solid var(--kratos-color-border-accent);
|
|
386
373
|
border-radius: 38rpx;
|
|
387
374
|
opacity: 0.55;
|
|
388
375
|
}
|
|
@@ -408,7 +395,7 @@
|
|
|
408
395
|
margin-top: 24rpx;
|
|
409
396
|
border-radius: 20rpx;
|
|
410
397
|
background: var(--kratos-color-surface);
|
|
411
|
-
border:
|
|
398
|
+
border: 1px solid var(--kratos-color-border);
|
|
412
399
|
}
|
|
413
400
|
.k-lg-field__input {
|
|
414
401
|
flex: 1;
|
|
@@ -430,7 +417,7 @@
|
|
|
430
417
|
align-items: center;
|
|
431
418
|
justify-content: center;
|
|
432
419
|
background: var(--kratos-color-primary-soft-2);
|
|
433
|
-
border:
|
|
420
|
+
border: 1px solid var(--kratos-color-border);
|
|
434
421
|
color: var(--kratos-color-primary);
|
|
435
422
|
font-family: var(--kratos-font-mono);
|
|
436
423
|
font-size: 34rpx;
|
|
@@ -442,6 +429,8 @@
|
|
|
442
429
|
align-items: center;
|
|
443
430
|
justify-content: center;
|
|
444
431
|
gap: 16rpx;
|
|
432
|
+
/* 各端 H5 原生 button 默认宽度不一,显式通栏保证双端一致 */
|
|
433
|
+
width: 100%;
|
|
445
434
|
height: 100rpx;
|
|
446
435
|
margin-top: 36rpx;
|
|
447
436
|
border-radius: 20rpx;
|
|
@@ -455,7 +444,7 @@
|
|
|
455
444
|
}
|
|
456
445
|
.k-lg-btn--wx {
|
|
457
446
|
background: var(--kratos-color-surface);
|
|
458
|
-
border:
|
|
447
|
+
border: 1px solid var(--kratos-color-border);
|
|
459
448
|
color: var(--kratos-color-text);
|
|
460
449
|
font-weight: 700;
|
|
461
450
|
}
|
|
@@ -472,7 +461,7 @@
|
|
|
472
461
|
.k-lg-or::after {
|
|
473
462
|
content: '';
|
|
474
463
|
flex: 1;
|
|
475
|
-
height:
|
|
464
|
+
height: 1px;
|
|
476
465
|
background: var(--kratos-color-border);
|
|
477
466
|
}
|
|
478
467
|
.k-lg-agree {
|
|
@@ -543,7 +532,7 @@
|
|
|
543
532
|
padding: 14rpx 22rpx;
|
|
544
533
|
border-radius: 999rpx;
|
|
545
534
|
background: var(--kratos-color-primary-soft);
|
|
546
|
-
border:
|
|
535
|
+
border: 1px solid var(--kratos-color-border-accent);
|
|
547
536
|
color: var(--kratos-color-primary);
|
|
548
537
|
font-size: 22rpx;
|
|
549
538
|
font-family: var(--kratos-font-mono);
|
|
@@ -555,7 +544,7 @@
|
|
|
555
544
|
padding: 30rpx;
|
|
556
545
|
border-radius: 24rpx;
|
|
557
546
|
background: linear-gradient(135deg, var(--kratos-color-primary-soft-2), var(--kratos-color-primary-soft));
|
|
558
|
-
border:
|
|
547
|
+
border: 1px solid var(--kratos-color-border-accent);
|
|
559
548
|
}
|
|
560
549
|
.k-aix__ic {
|
|
561
550
|
flex-shrink: 0;
|
|
@@ -586,7 +575,7 @@
|
|
|
586
575
|
padding: 14rpx 24rpx;
|
|
587
576
|
border-radius: 999rpx;
|
|
588
577
|
background: var(--kratos-color-primary-soft-2);
|
|
589
|
-
border:
|
|
578
|
+
border: 1px solid var(--kratos-color-border-accent);
|
|
590
579
|
color: var(--kratos-color-primary);
|
|
591
580
|
font-size: 22rpx;
|
|
592
581
|
font-family: var(--kratos-font-mono);
|
|
@@ -610,7 +599,7 @@
|
|
|
610
599
|
width: 92rpx;
|
|
611
600
|
height: 92rpx;
|
|
612
601
|
border-radius: 20rpx;
|
|
613
|
-
border:
|
|
602
|
+
border: 1px solid var(--kratos-color-border);
|
|
614
603
|
color: var(--kratos-color-primary);
|
|
615
604
|
background: var(--kratos-color-primary-soft);
|
|
616
605
|
}
|
|
@@ -639,7 +628,7 @@
|
|
|
639
628
|
margin-bottom: 20rpx;
|
|
640
629
|
border-radius: 20rpx;
|
|
641
630
|
background: var(--kratos-color-surface);
|
|
642
|
-
border:
|
|
631
|
+
border: 1px solid var(--kratos-color-border);
|
|
643
632
|
}
|
|
644
633
|
.k-set-row--arrow::after {
|
|
645
634
|
content: '';
|
|
@@ -664,7 +653,7 @@
|
|
|
664
653
|
width: 76rpx;
|
|
665
654
|
height: 76rpx;
|
|
666
655
|
border-radius: 22rpx;
|
|
667
|
-
border:
|
|
656
|
+
border: 1px solid var(--kratos-color-border);
|
|
668
657
|
color: var(--kratos-color-primary);
|
|
669
658
|
}
|
|
670
659
|
.k-set-row__title {
|
|
@@ -690,7 +679,7 @@
|
|
|
690
679
|
border-radius: 20rpx;
|
|
691
680
|
color: var(--kratos-color-danger);
|
|
692
681
|
background: var(--kratos-color-danger-soft);
|
|
693
|
-
border:
|
|
682
|
+
border: 1px solid var(--kratos-color-danger);
|
|
694
683
|
font-size: 30rpx;
|
|
695
684
|
font-weight: 700;
|
|
696
685
|
}
|
|
@@ -709,7 +698,7 @@
|
|
|
709
698
|
padding: 26rpx 28rpx;
|
|
710
699
|
border-radius: 20rpx;
|
|
711
700
|
background: var(--kratos-color-surface);
|
|
712
|
-
border:
|
|
701
|
+
border: 1px solid var(--kratos-color-border);
|
|
713
702
|
}
|
|
714
703
|
.k-msg-item--unread::before {
|
|
715
704
|
content: '';
|
|
@@ -734,20 +723,35 @@
|
|
|
734
723
|
width: 76rpx;
|
|
735
724
|
height: 76rpx;
|
|
736
725
|
border-radius: 22rpx;
|
|
737
|
-
border:
|
|
726
|
+
border: 1px solid var(--kratos-color-border);
|
|
738
727
|
color: var(--kratos-color-primary);
|
|
739
728
|
background: var(--kratos-color-primary-soft);
|
|
740
729
|
}
|
|
741
730
|
.k-msg-item__title {
|
|
731
|
+
display: -webkit-box;
|
|
732
|
+
overflow: hidden;
|
|
742
733
|
font-size: 25rpx;
|
|
743
734
|
font-weight: 700;
|
|
744
735
|
color: var(--kratos-color-text);
|
|
736
|
+
-webkit-box-orient: vertical;
|
|
737
|
+
-webkit-line-clamp: 2;
|
|
738
|
+
word-break: break-word;
|
|
745
739
|
}
|
|
746
|
-
.k-msg-
|
|
740
|
+
.k-msg-item__foot {
|
|
741
|
+
display: flex;
|
|
742
|
+
align-items: center;
|
|
743
|
+
gap: 24rpx;
|
|
747
744
|
margin-top: 10rpx;
|
|
745
|
+
}
|
|
746
|
+
.k-msg-item__meta {
|
|
747
|
+
flex: 1;
|
|
748
|
+
min-width: 0;
|
|
749
|
+
overflow: hidden;
|
|
748
750
|
font-size: 20rpx;
|
|
749
751
|
color: var(--kratos-color-text-muted);
|
|
750
752
|
font-family: var(--kratos-font-mono);
|
|
753
|
+
text-overflow: ellipsis;
|
|
754
|
+
white-space: nowrap;
|
|
751
755
|
}
|
|
752
756
|
.k-msg-item__time {
|
|
753
757
|
flex-shrink: 0;
|
|
@@ -761,10 +765,55 @@
|
|
|
761
765
|
gap: 36rpx;
|
|
762
766
|
margin-top: 22rpx;
|
|
763
767
|
padding-top: 22rpx;
|
|
764
|
-
border-top:
|
|
768
|
+
border-top: 1px solid var(--kratos-color-border);
|
|
765
769
|
}
|
|
766
770
|
.k-msg-item__action {
|
|
767
771
|
font-size: 22rpx;
|
|
768
772
|
color: var(--kratos-color-primary);
|
|
769
773
|
font-family: var(--kratos-font-mono);
|
|
770
774
|
}
|
|
775
|
+
|
|
776
|
+
/* ============================================================
|
|
777
|
+
* 标准空态词汇(列表无数据时统一使用)
|
|
778
|
+
* ============================================================ */
|
|
779
|
+
.k-empty {
|
|
780
|
+
display: flex;
|
|
781
|
+
flex-direction: column;
|
|
782
|
+
align-items: center;
|
|
783
|
+
padding: 140rpx 32rpx;
|
|
784
|
+
}
|
|
785
|
+
.k-empty__icon {
|
|
786
|
+
display: flex;
|
|
787
|
+
align-items: center;
|
|
788
|
+
justify-content: center;
|
|
789
|
+
width: 112rpx;
|
|
790
|
+
height: 112rpx;
|
|
791
|
+
border-radius: 26rpx;
|
|
792
|
+
border: 1px solid var(--kratos-color-border-accent);
|
|
793
|
+
background: var(--kratos-color-primary-soft-2);
|
|
794
|
+
color: var(--kratos-color-primary);
|
|
795
|
+
box-shadow: var(--kratos-glow-soft);
|
|
796
|
+
}
|
|
797
|
+
.k-empty__title {
|
|
798
|
+
margin-top: 28rpx;
|
|
799
|
+
color: var(--kratos-color-text);
|
|
800
|
+
font-size: 27rpx;
|
|
801
|
+
font-weight: 700;
|
|
802
|
+
}
|
|
803
|
+
.k-empty__desc {
|
|
804
|
+
margin-top: 12rpx;
|
|
805
|
+
color: var(--kratos-color-text-muted);
|
|
806
|
+
font-size: 22rpx;
|
|
807
|
+
font-family: var(--kratos-font-mono);
|
|
808
|
+
text-align: center;
|
|
809
|
+
}
|
|
810
|
+
.k-empty__act {
|
|
811
|
+
margin-top: 32rpx;
|
|
812
|
+
padding: 16rpx 40rpx;
|
|
813
|
+
border-radius: 999rpx;
|
|
814
|
+
border: 1px solid var(--kratos-color-border-accent);
|
|
815
|
+
background: var(--kratos-color-primary-soft-2);
|
|
816
|
+
color: var(--kratos-color-primary);
|
|
817
|
+
font-size: 24rpx;
|
|
818
|
+
font-family: var(--kratos-font-mono);
|
|
819
|
+
}
|
package/src/utils/http.ts
CHANGED
|
@@ -398,8 +398,15 @@ async function refreshAccessToken() {
|
|
|
398
398
|
setTokenExpiresIn(expires_in)
|
|
399
399
|
}
|
|
400
400
|
|
|
401
|
+
/** 会话过期弹窗等待时长:H5 端路由切换会卸载弹窗且 Promise 永不结算,超时释放避免提示永久卡死。 */
|
|
402
|
+
const RELOGIN_PROMPT_TIMEOUT = 60_000
|
|
403
|
+
|
|
401
404
|
/** 业务页提示重新登录;登录页只清理残留登录态,避免后台请求触发循环弹窗。 */
|
|
402
405
|
async function promptRelogin() {
|
|
406
|
+
// 401 来自旧会话的在途请求而当前已是有效登录态时直接忽略,避免刚登录成功被弹窗打断。
|
|
407
|
+
if (hasValidToken()) {
|
|
408
|
+
return
|
|
409
|
+
}
|
|
403
410
|
const pages = getCurrentPages()
|
|
404
411
|
if (pages[pages.length - 1]?.route === 'pages/login/login') {
|
|
405
412
|
if (getToken() || getRefreshToken() || uni.getStorageSync('user')) {
|
|
@@ -412,14 +419,22 @@ async function promptRelogin() {
|
|
|
412
419
|
}
|
|
413
420
|
isPromptingRelogin = true
|
|
414
421
|
try {
|
|
415
|
-
const modalRes = await
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
422
|
+
const modalRes = await Promise.race([
|
|
423
|
+
// 按钮文案复用通用确认键:平台对 confirmText 限制 4 个汉字/8 字符,长文案会被整体拒绝。
|
|
424
|
+
uni
|
|
425
|
+
.showModal({
|
|
426
|
+
title: t('common.title.notice'),
|
|
427
|
+
content: t('core.auth.session_expired'),
|
|
428
|
+
showCancel: false,
|
|
429
|
+
confirmText: t('common.action.confirm'),
|
|
430
|
+
})
|
|
431
|
+
.catch(() => ({ confirm: false })),
|
|
432
|
+
new Promise<{ confirm: boolean }>((resolve) =>
|
|
433
|
+
setTimeout(() => resolve({ confirm: false }), RELOGIN_PROMPT_TIMEOUT),
|
|
434
|
+
),
|
|
435
|
+
])
|
|
421
436
|
|
|
422
|
-
if (!modalRes
|
|
437
|
+
if (!modalRes?.confirm) {
|
|
423
438
|
return
|
|
424
439
|
}
|
|
425
440
|
|
|
@@ -452,15 +467,16 @@ function silentClearAuthData() {
|
|
|
452
467
|
uni.$emit(AUTH_SILENT_LOGOUT_EVENT)
|
|
453
468
|
}
|
|
454
469
|
|
|
470
|
+
/** 清理失效认证并进入携带本次业务回跳标记的登录页。 */
|
|
455
471
|
async function clearUserData() {
|
|
456
472
|
clearToken()
|
|
457
473
|
uni.removeStorageSync('user')
|
|
458
474
|
saveCurrentRoute()
|
|
459
475
|
// token 失效时直接重启页面栈,避免小程序历史页残留。
|
|
460
476
|
uni.reLaunch({
|
|
461
|
-
url: '/pages/login/login',
|
|
477
|
+
url: '/pages/login/login?redirect=1',
|
|
462
478
|
fail: () => {
|
|
463
|
-
uni.redirectTo({ url: '/pages/login/login' })
|
|
479
|
+
uni.redirectTo({ url: '/pages/login/login?redirect=1' })
|
|
464
480
|
},
|
|
465
481
|
})
|
|
466
482
|
}
|
package/src/utils/navigation.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { hasValidToken } from './auth'
|
|
2
|
+
|
|
1
3
|
/** 登录前暂存的目标路由。 */
|
|
2
4
|
const LAST_ROUTE_KEY = 'lastRoute'
|
|
3
5
|
/** 登录页路径。 */
|
|
4
6
|
const LOGIN_PAGE = '/pages/login/login'
|
|
7
|
+
/** 携带本次回跳标记的登录入口。 */
|
|
8
|
+
const LOGIN_REDIRECT_PAGE = `${LOGIN_PAGE}?redirect=1`
|
|
5
9
|
/** 首页 tab 页面路径。 */
|
|
6
10
|
export const homeTabPage = '/pages/index/index'
|
|
7
11
|
|
|
@@ -47,7 +51,6 @@ const getCurrentRouteUrl = () => {
|
|
|
47
51
|
export const saveCurrentRoute = () => {
|
|
48
52
|
const currentRoute = getCurrentRouteUrl()
|
|
49
53
|
if (!currentRoute || currentRoute.startsWith(LOGIN_PAGE)) {
|
|
50
|
-
uni.removeStorageSync(LAST_ROUTE_KEY)
|
|
51
54
|
return
|
|
52
55
|
}
|
|
53
56
|
uni.setStorageSync(LAST_ROUTE_KEY, currentRoute)
|
|
@@ -61,6 +64,34 @@ export const saveLoginRedirectUrl = (url: string) => {
|
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
66
|
|
|
67
|
+
/** prepareLoginPage 清理直接访问的旧目标,已登录时替换回首页。 */
|
|
68
|
+
export const prepareLoginPage = (redirect?: string): boolean => {
|
|
69
|
+
if (redirect !== '1') uni.removeStorageSync(LAST_ROUTE_KEY)
|
|
70
|
+
if (!hasValidToken()) return true
|
|
71
|
+
void returnFromLogin()
|
|
72
|
+
return false
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** returnFromLogin 结束本次登录入口并替换到首页,避免返回受保护页面。 */
|
|
76
|
+
export const returnFromLogin = async (): Promise<void> => {
|
|
77
|
+
uni.removeStorageSync(LAST_ROUTE_KEY)
|
|
78
|
+
uni.setStorageSync('SwitchTabIndex', true)
|
|
79
|
+
await uni.reLaunch({ url: homeTabPage })
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** restoreLoginRedirect 替换到本次访问目标,跳转成功后才清理保存的地址。 */
|
|
83
|
+
export const restoreLoginRedirect = async (): Promise<void> => {
|
|
84
|
+
const savedRoute = uni.getStorageSync(LAST_ROUTE_KEY) || ''
|
|
85
|
+
const normalizedRoute = `/${savedRoute.replace(/^\/+/, '')}`
|
|
86
|
+
const targetRoute =
|
|
87
|
+
savedRoute && !normalizedRoute.startsWith(LOGIN_PAGE) ? normalizedRoute : homeTabPage
|
|
88
|
+
if (targetRoute.startsWith(homeTabPage)) uni.setStorageSync('SwitchTabIndex', true)
|
|
89
|
+
await uni.reLaunch({ url: targetRoute })
|
|
90
|
+
if (savedRoute && uni.getStorageSync(LAST_ROUTE_KEY) === savedRoute) {
|
|
91
|
+
uni.removeStorageSync(LAST_ROUTE_KEY)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
64
95
|
/** 跳转到登录页,并在跳转前记录当前页面。 */
|
|
65
96
|
export const navigateToLogin = (redirectUrl?: string) => {
|
|
66
97
|
// 模板直接绑定时会传入点击事件对象,只有字符串才是明确的回跳地址。
|
|
@@ -70,9 +101,9 @@ export const navigateToLogin = (redirectUrl?: string) => {
|
|
|
70
101
|
saveCurrentRoute()
|
|
71
102
|
}
|
|
72
103
|
uni.navigateTo({
|
|
73
|
-
url:
|
|
104
|
+
url: LOGIN_REDIRECT_PAGE,
|
|
74
105
|
fail: () => {
|
|
75
|
-
uni.reLaunch({ url:
|
|
106
|
+
uni.reLaunch({ url: LOGIN_REDIRECT_PAGE })
|
|
76
107
|
},
|
|
77
108
|
})
|
|
78
109
|
}
|
|
@@ -86,9 +117,9 @@ export const redirectToLogin = (redirectUrl?: string) => {
|
|
|
86
117
|
saveCurrentRoute()
|
|
87
118
|
}
|
|
88
119
|
uni.redirectTo({
|
|
89
|
-
url:
|
|
120
|
+
url: LOGIN_REDIRECT_PAGE,
|
|
90
121
|
fail: () => {
|
|
91
|
-
uni.reLaunch({ url:
|
|
122
|
+
uni.reLaunch({ url: LOGIN_REDIRECT_PAGE })
|
|
92
123
|
},
|
|
93
124
|
})
|
|
94
125
|
}
|
|
@@ -9,7 +9,7 @@ import { useI18n } from '../../../locales'
|
|
|
9
9
|
const settingStore = useSettingStore()
|
|
10
10
|
const themeStore = useThemeStore()
|
|
11
11
|
const { t } = useI18n()
|
|
12
|
-
const mainTitle = computed(() =>
|
|
12
|
+
const mainTitle = computed(() => t('core.navigation.home'))
|
|
13
13
|
const subTitle = computed(() => settingStore.getData('subTitle') || t('core.home.sub_title'))
|
|
14
14
|
const configuredAppLogo = computed(() => {
|
|
15
15
|
const configuredLogo = settingStore.getData('appLogo')
|
|
@@ -46,10 +46,6 @@ onLoad(() => {
|
|
|
46
46
|
</view>
|
|
47
47
|
|
|
48
48
|
<view class="k-glass k-glass--lit home-hero">
|
|
49
|
-
<view class="k-cnr k-cnr--tl" aria-hidden="true"></view>
|
|
50
|
-
<view class="k-cnr k-cnr--tr" aria-hidden="true"></view>
|
|
51
|
-
<view class="k-cnr k-cnr--bl" aria-hidden="true"></view>
|
|
52
|
-
<view class="k-cnr k-cnr--br" aria-hidden="true"></view>
|
|
53
49
|
<view class="home-hero__main">
|
|
54
50
|
<image class="home-logo" :src="appLogo" mode="aspectFit" @error="handleLogoError" />
|
|
55
51
|
<view class="home-hero__copy">
|
|
@@ -102,8 +98,15 @@ onLoad(() => {
|
|
|
102
98
|
<view class="home-demo-item">
|
|
103
99
|
<view class="home-demo-dot">3</view>
|
|
104
100
|
<view class="home-demo-copy">
|
|
105
|
-
<text class="home-demo-title">{{ t('core.home.
|
|
106
|
-
<text class="home-demo-desc">{{ t('core.home.
|
|
101
|
+
<text class="home-demo-title">{{ t('core.home.message_center') }}</text>
|
|
102
|
+
<text class="home-demo-desc">{{ t('core.home.message_center_description') }}</text>
|
|
103
|
+
</view>
|
|
104
|
+
</view>
|
|
105
|
+
<view class="home-demo-item">
|
|
106
|
+
<view class="home-demo-dot">4</view>
|
|
107
|
+
<view class="home-demo-copy">
|
|
108
|
+
<text class="home-demo-title">{{ t('core.home.dynamic_config') }}</text>
|
|
109
|
+
<text class="home-demo-desc">{{ t('core.home.dynamic_config_description') }}</text>
|
|
107
110
|
</view>
|
|
108
111
|
</view>
|
|
109
112
|
</view>
|
|
@@ -126,21 +129,38 @@ onLoad(() => {
|
|
|
126
129
|
padding: calc(env(safe-area-inset-top) + 20rpx) 32rpx 220rpx;
|
|
127
130
|
|
|
128
131
|
/* #ifdef MP-WEIXIN */
|
|
129
|
-
|
|
132
|
+
/* 首页标题在小程序端占导航带,页面不再额外让出顶部空间 */
|
|
133
|
+
padding-top: 0;
|
|
130
134
|
/* #endif */
|
|
131
135
|
}
|
|
132
136
|
|
|
137
|
+
/* 小程序端首页标题占导航带:与 k-page-nav 同几何,标题与胶囊同行 */
|
|
138
|
+
/* #ifdef MP-WEIXIN */
|
|
139
|
+
.home-top {
|
|
140
|
+
box-sizing: border-box;
|
|
141
|
+
height: calc(88rpx + 44px);
|
|
142
|
+
padding: 44px 4rpx 0;
|
|
143
|
+
display: flex;
|
|
144
|
+
align-items: center;
|
|
145
|
+
justify-content: center;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.home-top__title {
|
|
149
|
+
margin-top: 0;
|
|
150
|
+
}
|
|
151
|
+
/* #endif */
|
|
152
|
+
|
|
133
153
|
.home-top {
|
|
134
154
|
padding: 8rpx 4rpx 24rpx;
|
|
135
155
|
}
|
|
136
156
|
|
|
137
|
-
/*
|
|
157
|
+
/* 页面大标题:与其他页面导航标题同规格,向原生导航栏看齐 */
|
|
138
158
|
.home-top__title {
|
|
139
159
|
margin-top: 14rpx;
|
|
140
160
|
color: var(--kratos-color-text);
|
|
141
|
-
font-size:
|
|
142
|
-
font-weight:
|
|
143
|
-
|
|
161
|
+
font-size: 32rpx;
|
|
162
|
+
font-weight: 700;
|
|
163
|
+
text-align: center;
|
|
144
164
|
}
|
|
145
165
|
|
|
146
166
|
.home-hero {
|
|
@@ -158,7 +178,7 @@ onLoad(() => {
|
|
|
158
178
|
width: 104rpx;
|
|
159
179
|
height: 104rpx;
|
|
160
180
|
border-radius: 26rpx;
|
|
161
|
-
border:
|
|
181
|
+
border: 1px solid var(--kratos-color-border-accent);
|
|
162
182
|
background: var(--kratos-color-surface-2);
|
|
163
183
|
}
|
|
164
184
|
|
|
@@ -198,7 +218,7 @@ onLoad(() => {
|
|
|
198
218
|
display: flex;
|
|
199
219
|
align-items: flex-start;
|
|
200
220
|
padding: 28rpx 0;
|
|
201
|
-
border-top:
|
|
221
|
+
border-top: 1px solid var(--kratos-color-border);
|
|
202
222
|
|
|
203
223
|
&:first-child {
|
|
204
224
|
border-top: 0;
|
|
@@ -211,7 +231,7 @@ onLoad(() => {
|
|
|
211
231
|
height: 48rpx;
|
|
212
232
|
border-radius: 14rpx;
|
|
213
233
|
background: var(--kratos-color-primary-soft);
|
|
214
|
-
border:
|
|
234
|
+
border: 1px solid var(--kratos-color-primary-edge);
|
|
215
235
|
color: var(--kratos-color-primary);
|
|
216
236
|
font-size: 24rpx;
|
|
217
237
|
font-family: var(--kratos-font-mono);
|