@liujitcn/kratos-uni-app-core 0.0.81 → 0.0.82
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 +24 -17
- 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/en-US.json +6 -4
- package/src/locales/ja-JP.json +6 -4
- package/src/locales/zh-CN.json +6 -4
- package/src/locales/zh-TW.json +6 -4
- 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 +22 -7
- package/src/views/pages/index/index.vue +35 -15
- package/src/views/pages/login/login.vue +0 -4
package/dist/module.mjs
CHANGED
|
@@ -3,7 +3,6 @@ var corePages = {
|
|
|
3
3
|
"pages/index/index": {
|
|
4
4
|
style: {
|
|
5
5
|
navigationStyle: "custom",
|
|
6
|
-
navigationBarTextStyle: "white",
|
|
7
6
|
navigationBarTitleText: ""
|
|
8
7
|
}
|
|
9
8
|
},
|
|
@@ -61,18 +60,20 @@ var zh_CN_default = {
|
|
|
61
60
|
"core.password.verify_label": "\u5F53\u524D\u5BC6\u7801",
|
|
62
61
|
"core.file.upload_failed": "\u4E0A\u4F20\u5931\u8D25",
|
|
63
62
|
"core.home.account_capability": "\u8D26\u6237\u80FD\u529B",
|
|
64
|
-
"core.home.account_capability_description": "\u4E2A\u4EBA\u8D44\u6599\u3001\
|
|
63
|
+
"core.home.account_capability_description": "\u767B\u5F55\u3001\u4E2A\u4EBA\u8D44\u6599\u3001\u591A\u56E0\u7D20\u8BA4\u8BC1\u4E0E\u5E94\u7528\u8BBE\u7F6E\u5F00\u7BB1\u5373\u7528",
|
|
65
64
|
"core.home.cross_platform": "\u8DE8\u7AEF\u9875\u9762",
|
|
66
65
|
"core.home.cross_platform_description": "\u540C\u4E00\u5957\u9875\u9762\u4EE3\u7801\u9002\u914D H5 \u548C\u5FAE\u4FE1\u5C0F\u7A0B\u5E8F",
|
|
67
66
|
"core.home.demo_scope": "\u529F\u80FD\u6982\u89C8",
|
|
67
|
+
"core.home.dynamic_config": "\u52A8\u6001\u914D\u7F6E",
|
|
68
|
+
"core.home.dynamic_config_description": "\u9996\u9875 Logo \u4E0E\u6807\u8BED\u652F\u6301\u540E\u53F0\u8FDC\u7A0B\u914D\u7F6E",
|
|
68
69
|
"core.home.framework": "\u5E94\u7528\u6846\u67B6",
|
|
69
70
|
"core.home.language": "\u5F00\u53D1\u8BED\u8A00",
|
|
70
71
|
"core.home.main_title": "\u5E94\u7528\u9996\u9875",
|
|
72
|
+
"core.home.message_center": "\u6D88\u606F\u4E2D\u5FC3",
|
|
73
|
+
"core.home.message_center_description": "\u672A\u8BFB\u6D88\u606F\u7EDF\u4E00\u6536\u7EB3\uFF0C\u7EA2\u70B9\u63D0\u9192\u4E0D\u9519\u8FC7",
|
|
71
74
|
"core.home.state_management": "\u72B6\u6001\u7BA1\u7406",
|
|
72
|
-
"core.home.static_home": "\u9759\u6001\u9996\u9875",
|
|
73
|
-
"core.home.static_home_description": "\u5F53\u524D\u9996\u9875\u7528\u4E8E\u5C55\u793A\u6846\u67B6\u4FE1\u606F\uFF0C\u4E0D\u4F9D\u8D56\u4E1A\u52A1\u63A5\u53E3",
|
|
74
75
|
"core.home.style_solution": "\u6837\u5F0F\u65B9\u6848",
|
|
75
|
-
"core.home.sub_title": "\
|
|
76
|
+
"core.home.sub_title": "\u8D26\u53F7\u3001\u6D88\u606F\u4E0E\u667A\u80FD\u52A9\u624B\uFF0C\u4E00\u7AD9\u89E6\u8FBE",
|
|
76
77
|
"core.home.tech_stack": "\u5F53\u524D\u6280\u672F\u6808",
|
|
77
78
|
"core.login.agree_prefix": "\u6211\u5DF2\u9605\u8BFB\u5E76\u540C\u610F",
|
|
78
79
|
"core.login.agree_separator": "\u548C",
|
|
@@ -218,18 +219,20 @@ var en_US_default = {
|
|
|
218
219
|
"core.password.verify_label": "Current password",
|
|
219
220
|
"core.file.upload_failed": "Upload failed",
|
|
220
221
|
"core.home.account_capability": "Account features",
|
|
221
|
-
"core.home.account_capability_description": "
|
|
222
|
+
"core.home.account_capability_description": "Sign-in, profile, multi-factor authentication, and app settings out of the box",
|
|
222
223
|
"core.home.cross_platform": "Cross-platform pages",
|
|
223
224
|
"core.home.cross_platform_description": "One codebase for H5 and WeChat Mini Program",
|
|
224
225
|
"core.home.demo_scope": "Overview",
|
|
226
|
+
"core.home.dynamic_config": "Dynamic config",
|
|
227
|
+
"core.home.dynamic_config_description": "Home logo and tagline configurable from the admin console",
|
|
225
228
|
"core.home.framework": "App framework",
|
|
226
229
|
"core.home.language": "Language",
|
|
227
230
|
"core.home.main_title": "Application Home",
|
|
231
|
+
"core.home.message_center": "Message center",
|
|
232
|
+
"core.home.message_center_description": "Unread messages in one inbox with badge reminders",
|
|
228
233
|
"core.home.state_management": "State management",
|
|
229
|
-
"core.home.static_home": "Static home",
|
|
230
|
-
"core.home.static_home_description": "This page presents framework details without business APIs",
|
|
231
234
|
"core.home.style_solution": "Styling",
|
|
232
|
-
"core.home.sub_title": "
|
|
235
|
+
"core.home.sub_title": "Accounts, messages, and AI assistant in one place",
|
|
233
236
|
"core.home.tech_stack": "Technology stack",
|
|
234
237
|
"core.login.agree_prefix": "I have read and agree to the",
|
|
235
238
|
"core.login.agree_separator": "and",
|
|
@@ -375,18 +378,20 @@ var ja_JP_default = {
|
|
|
375
378
|
"core.password.verify_label": "\u73FE\u5728\u306E\u30D1\u30B9\u30EF\u30FC\u30C9",
|
|
376
379
|
"core.file.upload_failed": "\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
|
|
377
380
|
"core.home.account_capability": "\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u6A5F\u80FD",
|
|
378
|
-
"core.home.account_capability_description": "\
|
|
381
|
+
"core.home.account_capability_description": "\u30ED\u30B0\u30A4\u30F3\u3001\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB\u3001\u591A\u8981\u7D20\u8A8D\u8A3C\u3001\u30A2\u30D7\u30EA\u8A2D\u5B9A\u3092\u540C\u68B1",
|
|
379
382
|
"core.home.cross_platform": "\u30AF\u30ED\u30B9\u30A8\u30F3\u30C9 \u30DA\u30FC\u30B8",
|
|
380
383
|
"core.home.cross_platform_description": "\u540C\u3058\u30DA\u30FC\u30B8 \u30B3\u30FC\u30C9 \u30BB\u30C3\u30C8\u304C H5 \u304A\u3088\u3073 WeChat \u30DF\u30CB \u30D7\u30ED\u30B0\u30E9\u30E0\u306B\u9069\u5FDC\u3057\u307E\u3059",
|
|
381
384
|
"core.home.demo_scope": "\u6A5F\u80FD\u6982\u8981",
|
|
385
|
+
"core.home.dynamic_config": "\u52D5\u7684\u8A2D\u5B9A",
|
|
386
|
+
"core.home.dynamic_config_description": "\u30DB\u30FC\u30E0\u306E\u30ED\u30B4\u3068\u30AD\u30E3\u30C3\u30C1\u30B3\u30D4\u30FC\u306F\u7BA1\u7406\u753B\u9762\u304B\u3089\u5909\u66F4\u53EF\u80FD",
|
|
382
387
|
"core.home.framework": "\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3 \u30D5\u30EC\u30FC\u30E0\u30EF\u30FC\u30AF",
|
|
383
388
|
"core.home.language": "\u958B\u767A\u8A00\u8A9E",
|
|
384
389
|
"core.home.main_title": "\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30DB\u30FC\u30E0",
|
|
390
|
+
"core.home.message_center": "\u30E1\u30C3\u30BB\u30FC\u30B8\u30BB\u30F3\u30BF\u30FC",
|
|
391
|
+
"core.home.message_center_description": "\u672A\u8AAD\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u4E00\u62EC\u7BA1\u7406\u3057\u3001\u30D0\u30C3\u30B8\u3067\u304A\u77E5\u3089\u305B",
|
|
385
392
|
"core.home.state_management": "\u30B9\u30C6\u30FC\u30BF\u30B9\u7BA1\u7406",
|
|
386
|
-
"core.home.static_home": "\u9759\u7684\u30DB\u30FC\u30E0\u30DA\u30FC\u30B8",
|
|
387
|
-
"core.home.static_home_description": "\u73FE\u5728\u306E\u30DB\u30FC\u30E0\u30DA\u30FC\u30B8\u306F\u30D5\u30EC\u30FC\u30E0\u60C5\u5831\u3092\u8868\u793A\u3059\u308B\u305F\u3081\u306B\u4F7F\u7528\u3055\u308C\u3066\u304A\u308A\u3001\u30D3\u30B8\u30CD\u30B9 \u30A4\u30F3\u30BF\u30FC\u30D5\u30A7\u30A4\u30B9\u306B\u306F\u4F9D\u5B58\u3057\u3066\u3044\u307E\u305B\u3093",
|
|
388
393
|
"core.home.style_solution": "\u30B9\u30BF\u30A4\u30EB \u30B9\u30AD\u30FC\u30E0",
|
|
389
|
-
"core.home.sub_title": "\
|
|
394
|
+
"core.home.sub_title": "\u30A2\u30AB\u30A6\u30F3\u30C8\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u30FB\u30B9\u30DE\u30FC\u30C8\u30A2\u30B7\u30B9\u30BF\u30F3\u30C8\u3092\u3072\u3068\u3064\u306B",
|
|
390
395
|
"core.home.tech_stack": "\u73FE\u5728\u306E\u30C6\u30AF\u30CE\u30ED\u30B8\u30FC\u30B9\u30BF\u30C3\u30AF",
|
|
391
396
|
"core.login.agree_prefix": "\u8AAD\u3093\u3067\u540C\u610F\u3057\u307E\u3059",
|
|
392
397
|
"core.login.agree_separator": "\u304A\u3088\u3073",
|
|
@@ -532,18 +537,20 @@ var zh_TW_default = {
|
|
|
532
537
|
"core.password.verify_label": "\u7576\u524D\u5BC6\u78BC",
|
|
533
538
|
"core.file.upload_failed": "\u4E0A\u50B3\u5931\u6557",
|
|
534
539
|
"core.home.account_capability": "\u8CEC\u6236\u80FD\u529B",
|
|
535
|
-
"core.home.account_capability_description": "\u500B\u4EBA\u8CC7\u6599\u3001\
|
|
540
|
+
"core.home.account_capability_description": "\u767B\u5165\u3001\u500B\u4EBA\u8CC7\u6599\u3001\u591A\u56E0\u7D20\u8A8D\u8B49\u8207\u61C9\u7528\u8A2D\u5B9A\u958B\u7BB1\u5373\u7528",
|
|
536
541
|
"core.home.cross_platform": "\u8DE8\u7AEF\u9801\u9762",
|
|
537
542
|
"core.home.cross_platform_description": "\u540C\u4E00\u5957\u9801\u9762\u7A0B\u5F0F\u78BC\u9069\u914D H5 \u548C\u5FAE\u4FE1\u5C0F\u7A0B\u5F0F",
|
|
538
543
|
"core.home.demo_scope": "\u529F\u80FD\u6982\u89BD",
|
|
544
|
+
"core.home.dynamic_config": "\u52D5\u614B\u8A2D\u5B9A",
|
|
545
|
+
"core.home.dynamic_config_description": "\u9996\u9801 Logo \u8207\u6A19\u8A9E\u652F\u63F4\u5F8C\u53F0\u9060\u7AEF\u8A2D\u5B9A",
|
|
539
546
|
"core.home.framework": "\u61C9\u7528\u6846\u67B6",
|
|
540
547
|
"core.home.language": "\u958B\u767C\u8A9E\u8A00",
|
|
541
548
|
"core.home.main_title": "\u61C9\u7528\u9996\u9801",
|
|
549
|
+
"core.home.message_center": "\u8A0A\u606F\u4E2D\u5FC3",
|
|
550
|
+
"core.home.message_center_description": "\u672A\u8B80\u8A0A\u606F\u7D71\u4E00\u67E5\u770B\uFF0C\u7D05\u9EDE\u63D0\u9192\u4E0D\u932F\u904E",
|
|
542
551
|
"core.home.state_management": "\u72C0\u614B\u7BA1\u7406",
|
|
543
|
-
"core.home.static_home": "\u975C\u614B\u9996\u9801",
|
|
544
|
-
"core.home.static_home_description": "\u7576\u524D\u9996\u9801\u7528\u65BC\u5C55\u793A\u6846\u67B6\u8CC7\u8A0A\uFF0C\u4E0D\u4F9D\u8CF4\u696D\u52D9\u4ECB\u9762",
|
|
545
552
|
"core.home.style_solution": "\u6A23\u5F0F\u65B9\u6848",
|
|
546
|
-
"core.home.sub_title": "\
|
|
553
|
+
"core.home.sub_title": "\u5E33\u865F\u3001\u8A0A\u606F\u8207\u667A\u6167\u52A9\u624B\uFF0C\u4E00\u7AD9\u89F8\u9054",
|
|
547
554
|
"core.home.tech_stack": "\u7576\u524D\u6280\u8853\u68E7",
|
|
548
555
|
"core.login.agree_prefix": "\u6211\u5DF2\u95B1\u8B80\u4E26\u540C\u610F",
|
|
549
556
|
"core.login.agree_separator": "\u548C",
|
package/package.json
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
defineOptions({ name: 'KratosEmpty' })
|
|
3
|
+
|
|
4
|
+
withDefaults(
|
|
5
|
+
defineProps<{
|
|
6
|
+
/** 图标名称(uni-icons),不传则不渲染图标位。 */
|
|
7
|
+
icon?: string
|
|
8
|
+
/** 主文案。 */
|
|
9
|
+
title?: string
|
|
10
|
+
/** 次级提示文案。 */
|
|
11
|
+
description?: string
|
|
12
|
+
}>(),
|
|
13
|
+
{
|
|
14
|
+
icon: '',
|
|
15
|
+
title: '',
|
|
16
|
+
description: '',
|
|
17
|
+
},
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
defineSlots<{
|
|
21
|
+
/** 操作区插槽:渲染引导按钮等自定义内容。 */
|
|
22
|
+
default?: () => unknown
|
|
23
|
+
}>()
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template>
|
|
27
|
+
<view class="k-empty">
|
|
28
|
+
<view v-if="icon" class="k-empty__icon">
|
|
29
|
+
<uni-icons :type="icon" size="26" color="var(--kratos-color-primary)" aria-hidden="true" />
|
|
30
|
+
</view>
|
|
31
|
+
<text v-if="title" class="k-empty__title">{{ title }}</text>
|
|
32
|
+
<text v-if="description" class="k-empty__desc">{{ description }}</text>
|
|
33
|
+
<slot />
|
|
34
|
+
</view>
|
|
35
|
+
</template>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, onMounted } from 'vue'
|
|
2
|
+
import { computed, onBeforeMount, onMounted } from 'vue'
|
|
3
3
|
import { resolveModuleIcon, resolveStaticView } from '../module'
|
|
4
4
|
import { APP_MENU_ROOT_ID, useAppMenuBadge, useAppNavigation } from '../navigation'
|
|
5
5
|
import { useThemeStore } from '../stores'
|
|
@@ -43,9 +43,12 @@ const visible = computed(() => Boolean(activeMenu.value && tabBar.value.length))
|
|
|
43
43
|
const messageBadge = useAppMenuBadge('MESSAGE_INBOX')
|
|
44
44
|
// #ifdef H5
|
|
45
45
|
// H5 端 tabBar.custom 不隐藏内置 tabbar,需手动隐藏,否则其边线从自定义栏上方露出形成双线。
|
|
46
|
-
|
|
46
|
+
const hideNativeTabBar = () => {
|
|
47
47
|
uni.hideTabBar({ fail: () => {} })
|
|
48
|
-
}
|
|
48
|
+
}
|
|
49
|
+
onBeforeMount(hideNativeTabBar)
|
|
50
|
+
// H5 runtime 可能在页面挂载时重新同步内置 tabbar 状态,挂载后幂等重试避免首次切换露出一帧。
|
|
51
|
+
onMounted(hideNativeTabBar)
|
|
49
52
|
// #endif
|
|
50
53
|
</script>
|
|
51
54
|
|
|
@@ -105,7 +108,7 @@ onMounted(() => {
|
|
|
105
108
|
display: flex;
|
|
106
109
|
height: 104rpx;
|
|
107
110
|
padding: 0 8rpx;
|
|
108
|
-
border:
|
|
111
|
+
border: 1px solid var(--kratos-color-border-accent, rgba(120, 230, 215, 0.16));
|
|
109
112
|
border-radius: 30rpx;
|
|
110
113
|
background: var(--kratos-dock-bg, rgba(10, 18, 30, 0.72));
|
|
111
114
|
box-shadow: 0 24rpx 64rpx rgba(0, 0, 0, 0.45);
|
|
@@ -123,20 +126,8 @@ onMounted(() => {
|
|
|
123
126
|
line-height: 12px;
|
|
124
127
|
}
|
|
125
128
|
|
|
126
|
-
/* 设计稿:激活项顶部霓虹发光条 */
|
|
127
|
-
.kratos-tab-bar__item--active::before {
|
|
128
|
-
position: absolute;
|
|
129
|
-
top: 0;
|
|
130
|
-
left: 50%;
|
|
131
|
-
width: 26px;
|
|
132
|
-
height: 3px;
|
|
133
|
-
border-radius: 3px;
|
|
134
|
-
background: var(--kratos-tab-bar-active-color);
|
|
135
|
-
box-shadow: 0 0 12px var(--kratos-tab-bar-active-color);
|
|
136
|
-
content: '';
|
|
137
|
-
transform: translateX(-50%);
|
|
138
|
-
}
|
|
139
129
|
.kratos-tab-bar__icon {
|
|
130
|
+
flex-shrink: 0;
|
|
140
131
|
width: 28px;
|
|
141
132
|
height: 28px;
|
|
142
133
|
margin-bottom: 4px;
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,8 @@ export * from './navigation'
|
|
|
5
5
|
/** KratosSettingsPage 可通过顶部插槽扩展业务内容的公共设置页。 */
|
|
6
6
|
export { default as KratosSettingsPage } from './components/KratosSettingsPage.vue'
|
|
7
7
|
export { default as KratosTabBar } from './components/KratosTabBar.vue'
|
|
8
|
+
/** KratosEmpty 标准空态组件,支持自定义图标、主文案与提示文案。 */
|
|
9
|
+
export { default as KratosEmpty } from './components/KratosEmpty.vue'
|
|
8
10
|
export { default as pinia } from './stores'
|
|
9
11
|
export * from './stores'
|
|
10
12
|
export * from './utils/secretCrypto'
|
package/src/locales/en-US.json
CHANGED
|
@@ -33,18 +33,20 @@
|
|
|
33
33
|
"core.password.verify_label": "Current password",
|
|
34
34
|
"core.file.upload_failed": "Upload failed",
|
|
35
35
|
"core.home.account_capability": "Account features",
|
|
36
|
-
"core.home.account_capability_description": "
|
|
36
|
+
"core.home.account_capability_description": "Sign-in, profile, multi-factor authentication, and app settings out of the box",
|
|
37
37
|
"core.home.cross_platform": "Cross-platform pages",
|
|
38
38
|
"core.home.cross_platform_description": "One codebase for H5 and WeChat Mini Program",
|
|
39
39
|
"core.home.demo_scope": "Overview",
|
|
40
|
+
"core.home.dynamic_config": "Dynamic config",
|
|
41
|
+
"core.home.dynamic_config_description": "Home logo and tagline configurable from the admin console",
|
|
40
42
|
"core.home.framework": "App framework",
|
|
41
43
|
"core.home.language": "Language",
|
|
42
44
|
"core.home.main_title": "Application Home",
|
|
45
|
+
"core.home.message_center": "Message center",
|
|
46
|
+
"core.home.message_center_description": "Unread messages in one inbox with badge reminders",
|
|
43
47
|
"core.home.state_management": "State management",
|
|
44
|
-
"core.home.static_home": "Static home",
|
|
45
|
-
"core.home.static_home_description": "This page presents framework details without business APIs",
|
|
46
48
|
"core.home.style_solution": "Styling",
|
|
47
|
-
"core.home.sub_title": "
|
|
49
|
+
"core.home.sub_title": "Accounts, messages, and AI assistant in one place",
|
|
48
50
|
"core.home.tech_stack": "Technology stack",
|
|
49
51
|
"core.login.agree_prefix": "I have read and agree to the",
|
|
50
52
|
"core.login.agree_separator": "and",
|
package/src/locales/ja-JP.json
CHANGED
|
@@ -33,18 +33,20 @@
|
|
|
33
33
|
"core.password.verify_label": "現在のパスワード",
|
|
34
34
|
"core.file.upload_failed": "アップロードに失敗しました",
|
|
35
35
|
"core.home.account_capability": "アカウントの機能",
|
|
36
|
-
"core.home.account_capability_description": "
|
|
36
|
+
"core.home.account_capability_description": "ログイン、プロフィール、多要素認証、アプリ設定を同梱",
|
|
37
37
|
"core.home.cross_platform": "クロスエンド ページ",
|
|
38
38
|
"core.home.cross_platform_description": "同じページ コード セットが H5 および WeChat ミニ プログラムに適応します",
|
|
39
39
|
"core.home.demo_scope": "機能概要",
|
|
40
|
+
"core.home.dynamic_config": "動的設定",
|
|
41
|
+
"core.home.dynamic_config_description": "ホームのロゴとキャッチコピーは管理画面から変更可能",
|
|
40
42
|
"core.home.framework": "アプリケーション フレームワーク",
|
|
41
43
|
"core.home.language": "開発言語",
|
|
42
44
|
"core.home.main_title": "アプリケーションホーム",
|
|
45
|
+
"core.home.message_center": "メッセージセンター",
|
|
46
|
+
"core.home.message_center_description": "未読メッセージを一括管理し、バッジでお知らせ",
|
|
43
47
|
"core.home.state_management": "ステータス管理",
|
|
44
|
-
"core.home.static_home": "静的ホームページ",
|
|
45
|
-
"core.home.static_home_description": "現在のホームページはフレーム情報を表示するために使用されており、ビジネス インターフェイスには依存していません",
|
|
46
48
|
"core.home.style_solution": "スタイル スキーム",
|
|
47
|
-
"core.home.sub_title": "
|
|
49
|
+
"core.home.sub_title": "アカウント・メッセージ・スマートアシスタントをひとつに",
|
|
48
50
|
"core.home.tech_stack": "現在のテクノロジースタック",
|
|
49
51
|
"core.login.agree_prefix": "読んで同意します",
|
|
50
52
|
"core.login.agree_separator": "および",
|
package/src/locales/zh-CN.json
CHANGED
|
@@ -33,18 +33,20 @@
|
|
|
33
33
|
"core.password.verify_label": "当前密码",
|
|
34
34
|
"core.file.upload_failed": "上传失败",
|
|
35
35
|
"core.home.account_capability": "账户能力",
|
|
36
|
-
"core.home.account_capability_description": "
|
|
36
|
+
"core.home.account_capability_description": "登录、个人资料、多因素认证与应用设置开箱即用",
|
|
37
37
|
"core.home.cross_platform": "跨端页面",
|
|
38
38
|
"core.home.cross_platform_description": "同一套页面代码适配 H5 和微信小程序",
|
|
39
39
|
"core.home.demo_scope": "功能概览",
|
|
40
|
+
"core.home.dynamic_config": "动态配置",
|
|
41
|
+
"core.home.dynamic_config_description": "首页 Logo 与标语支持后台远程配置",
|
|
40
42
|
"core.home.framework": "应用框架",
|
|
41
43
|
"core.home.language": "开发语言",
|
|
42
44
|
"core.home.main_title": "应用首页",
|
|
45
|
+
"core.home.message_center": "消息中心",
|
|
46
|
+
"core.home.message_center_description": "未读消息统一收纳,红点提醒不错过",
|
|
43
47
|
"core.home.state_management": "状态管理",
|
|
44
|
-
"core.home.static_home": "静态首页",
|
|
45
|
-
"core.home.static_home_description": "当前首页用于展示框架信息,不依赖业务接口",
|
|
46
48
|
"core.home.style_solution": "样式方案",
|
|
47
|
-
"core.home.sub_title": "
|
|
49
|
+
"core.home.sub_title": "账号、消息与智能助手,一站触达",
|
|
48
50
|
"core.home.tech_stack": "当前技术栈",
|
|
49
51
|
"core.login.agree_prefix": "我已阅读并同意",
|
|
50
52
|
"core.login.agree_separator": "和",
|
package/src/locales/zh-TW.json
CHANGED
|
@@ -33,18 +33,20 @@
|
|
|
33
33
|
"core.password.verify_label": "當前密碼",
|
|
34
34
|
"core.file.upload_failed": "上傳失敗",
|
|
35
35
|
"core.home.account_capability": "賬戶能力",
|
|
36
|
-
"core.home.account_capability_description": "
|
|
36
|
+
"core.home.account_capability_description": "登入、個人資料、多因素認證與應用設定開箱即用",
|
|
37
37
|
"core.home.cross_platform": "跨端頁面",
|
|
38
38
|
"core.home.cross_platform_description": "同一套頁面程式碼適配 H5 和微信小程式",
|
|
39
39
|
"core.home.demo_scope": "功能概覽",
|
|
40
|
+
"core.home.dynamic_config": "動態設定",
|
|
41
|
+
"core.home.dynamic_config_description": "首頁 Logo 與標語支援後台遠端設定",
|
|
40
42
|
"core.home.framework": "應用框架",
|
|
41
43
|
"core.home.language": "開發語言",
|
|
42
44
|
"core.home.main_title": "應用首頁",
|
|
45
|
+
"core.home.message_center": "訊息中心",
|
|
46
|
+
"core.home.message_center_description": "未讀訊息統一查看,紅點提醒不錯過",
|
|
43
47
|
"core.home.state_management": "狀態管理",
|
|
44
|
-
"core.home.static_home": "靜態首頁",
|
|
45
|
-
"core.home.static_home_description": "當前首頁用於展示框架資訊,不依賴業務介面",
|
|
46
48
|
"core.home.style_solution": "樣式方案",
|
|
47
|
-
"core.home.sub_title": "
|
|
49
|
+
"core.home.sub_title": "帳號、訊息與智慧助手,一站觸達",
|
|
48
50
|
"core.home.tech_stack": "當前技術棧",
|
|
49
51
|
"core.login.agree_prefix": "我已閱讀並同意",
|
|
50
52
|
"core.login.agree_separator": "和",
|
package/src/navigation.ts
CHANGED
|
@@ -73,6 +73,16 @@ const createDefaultMenus = (): AppMenu[] => [
|
|
|
73
73
|
icon: 'MESSAGE_DEFAULT',
|
|
74
74
|
selectedIcon: 'MESSAGE_SELECTED',
|
|
75
75
|
},
|
|
76
|
+
{
|
|
77
|
+
id: 99050100,
|
|
78
|
+
parentId: 99040000,
|
|
79
|
+
name: 'AppMessageDetail',
|
|
80
|
+
path: 'app/message/detail',
|
|
81
|
+
viewKey: 'MESSAGE_DETAIL',
|
|
82
|
+
title: '',
|
|
83
|
+
access: 'AUTHENTICATED',
|
|
84
|
+
inTabBar: false,
|
|
85
|
+
},
|
|
76
86
|
{
|
|
77
87
|
id: 99090000,
|
|
78
88
|
parentId: APP_MENU_ROOT_ID,
|
|
@@ -181,8 +191,9 @@ export async function initializeAppNavigation(): Promise<void> {
|
|
|
181
191
|
const cached = readCachedMenus(cacheKey)
|
|
182
192
|
menus.value = filterUnavailableMenus(cached ?? createDefaultMenus())
|
|
183
193
|
try {
|
|
184
|
-
const nextMenus =
|
|
185
|
-
|
|
194
|
+
const nextMenus = validateMenus(
|
|
195
|
+
filterUnavailableMenus(normalizeMenuResponse(await adapter.list())),
|
|
196
|
+
)
|
|
186
197
|
uni.setStorageSync(cacheKey, nextMenus)
|
|
187
198
|
menus.value = nextMenus
|
|
188
199
|
} catch (error) {
|
|
@@ -202,8 +213,7 @@ function filterUnavailableMenus(nextMenus: AppMenu[]): AppMenu[] {
|
|
|
202
213
|
|
|
203
214
|
/** 使用已经校验的整份配置进行原子切换。 */
|
|
204
215
|
export function installAppNavigation(nextMenus: AppMenu[]): void {
|
|
205
|
-
validateMenus(nextMenus)
|
|
206
|
-
const snapshot = nextMenus.map((menu) => ({ ...menu }))
|
|
216
|
+
const snapshot = validateMenus(nextMenus).map((menu) => ({ ...menu }))
|
|
207
217
|
uni.setStorageSync(resolveCacheKey(), snapshot)
|
|
208
218
|
menus.value = snapshot
|
|
209
219
|
ready.value = true
|
|
@@ -394,9 +404,16 @@ function readCachedMenus(cacheKey: string): AppMenu[] | undefined {
|
|
|
394
404
|
const cached = uni.getStorageSync(cacheKey) as unknown
|
|
395
405
|
if (!Array.isArray(cached)) return
|
|
396
406
|
try {
|
|
397
|
-
const cachedMenus = cached as AppMenu[]
|
|
398
|
-
|
|
399
|
-
|
|
407
|
+
const cachedMenus = (cached as AppMenu[]).map((menu) => ({
|
|
408
|
+
...menu,
|
|
409
|
+
title:
|
|
410
|
+
menu.viewKey === 'HOME'
|
|
411
|
+
? t('core.navigation.home')
|
|
412
|
+
: menu.viewKey === 'MESSAGE_INBOX'
|
|
413
|
+
? t('core.navigation.message')
|
|
414
|
+
: menu.title,
|
|
415
|
+
}))
|
|
416
|
+
return validateMenus(cachedMenus)
|
|
400
417
|
} catch {
|
|
401
418
|
uni.removeStorageSync(cacheKey)
|
|
402
419
|
}
|
|
@@ -415,7 +432,12 @@ function normalizeMenu(item: BaseMenu): AppMenu {
|
|
|
415
432
|
name: item.name,
|
|
416
433
|
path: item.path,
|
|
417
434
|
viewKey: app?.view_key ?? '',
|
|
418
|
-
title:
|
|
435
|
+
title:
|
|
436
|
+
app?.view_key === 'HOME'
|
|
437
|
+
? t('core.navigation.home')
|
|
438
|
+
: app?.view_key === 'MESSAGE_INBOX'
|
|
439
|
+
? t('core.navigation.message')
|
|
440
|
+
: (meta?.title ?? ''),
|
|
419
441
|
access: (app?.access ?? 'AUTHENTICATED') as AppMenuAccess,
|
|
420
442
|
inTabBar: app?.in_tab_bar ?? false,
|
|
421
443
|
icon: meta?.icon,
|
|
@@ -423,11 +445,17 @@ function normalizeMenu(item: BaseMenu): AppMenu {
|
|
|
423
445
|
}
|
|
424
446
|
}
|
|
425
447
|
|
|
426
|
-
function validateMenus(nextMenus: AppMenu[]):
|
|
448
|
+
function validateMenus(nextMenus: AppMenu[]): AppMenu[] {
|
|
449
|
+
// 多端共用后端时菜单可能携带本应用未注册的视图键,过滤跳过而不是让整份菜单失效。
|
|
450
|
+
const knownMenus = nextMenus.filter((menu) => {
|
|
451
|
+
if (resolveStaticView(menu.viewKey)) return true
|
|
452
|
+
console.warn(t('core.navigation.error.view_key', { viewKey: menu.viewKey }))
|
|
453
|
+
return false
|
|
454
|
+
})
|
|
427
455
|
const ids = new Set<number>()
|
|
428
456
|
const names = new Set<string>()
|
|
429
457
|
const paths = new Set<string>()
|
|
430
|
-
for (const menu of
|
|
458
|
+
for (const menu of knownMenus) {
|
|
431
459
|
if (!Number.isSafeInteger(menu.id) || !menu.name || !menu.path.startsWith('app/')) {
|
|
432
460
|
throw new Error(t('core.navigation.error.identity'))
|
|
433
461
|
}
|
|
@@ -437,9 +465,6 @@ function validateMenus(nextMenus: AppMenu[]): void {
|
|
|
437
465
|
if (!['PUBLIC', 'GUEST_ONLY', 'AUTHENTICATED'].includes(menu.access)) {
|
|
438
466
|
throw new Error(t('core.navigation.error.access', { access: menu.access }))
|
|
439
467
|
}
|
|
440
|
-
if (!resolveStaticView(menu.viewKey)) {
|
|
441
|
-
throw new Error(t('core.navigation.error.view_key', { viewKey: menu.viewKey }))
|
|
442
|
-
}
|
|
443
468
|
if (ids.has(menu.id) || names.has(menu.name) || paths.has(menu.path)) {
|
|
444
469
|
throw new Error(t('core.navigation.error.unique'))
|
|
445
470
|
}
|
|
@@ -447,8 +472,8 @@ function validateMenus(nextMenus: AppMenu[]): void {
|
|
|
447
472
|
names.add(menu.name)
|
|
448
473
|
paths.add(menu.path)
|
|
449
474
|
}
|
|
450
|
-
const menuMap = new Map(
|
|
451
|
-
for (const menu of
|
|
475
|
+
const menuMap = new Map(knownMenus.map((menu) => [menu.id, menu]))
|
|
476
|
+
for (const menu of knownMenus) {
|
|
452
477
|
if (menu.parentId === undefined) {
|
|
453
478
|
throw new Error(t('core.navigation.error.parent_missing', { name: menu.name }))
|
|
454
479
|
}
|
|
@@ -471,6 +496,7 @@ function validateMenus(nextMenus: AppMenu[]): void {
|
|
|
471
496
|
parentId = parent.parentId
|
|
472
497
|
}
|
|
473
498
|
}
|
|
474
|
-
const tabCount =
|
|
499
|
+
const tabCount = knownMenus.filter((menu) => menu.parentId === APP_MENU_ROOT_ID).length
|
|
475
500
|
if (tabCount === 1 || tabCount > 5) throw new Error(t('core.navigation.error.tab_count'))
|
|
501
|
+
return knownMenus
|
|
476
502
|
}
|
package/src/pages.ts
CHANGED
package/src/styles/base.scss
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
@use './theme.scss';
|
|
2
2
|
@use './components.scss';
|
|
3
3
|
|
|
4
|
+
page,
|
|
5
|
+
body,
|
|
6
|
+
uni-page-body {
|
|
7
|
+
font-family:
|
|
8
|
+
-apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB',
|
|
9
|
+
'Microsoft YaHei', sans-serif;
|
|
10
|
+
}
|
|
11
|
+
|
|
4
12
|
view,
|
|
5
13
|
navigator,
|
|
6
14
|
input,
|
|
@@ -97,3 +105,16 @@ html.theme-light .uni-input-input:-webkit-autofill {
|
|
|
97
105
|
caret-color: #102232;
|
|
98
106
|
}
|
|
99
107
|
/* #endif */
|
|
108
|
+
|
|
109
|
+
/* H5 隐藏滚动条但保留滚动能力,视觉对齐小程序;小程序端滚动条本就不存在,无副作用。 */
|
|
110
|
+
/* #ifdef H5 */
|
|
111
|
+
::-webkit-scrollbar {
|
|
112
|
+
width: 0;
|
|
113
|
+
height: 0;
|
|
114
|
+
display: none;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
* {
|
|
118
|
+
scrollbar-width: none;
|
|
119
|
+
}
|
|
120
|
+
/* #endif */
|
|
@@ -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
|
|
|
@@ -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);
|
|
@@ -918,10 +918,6 @@ onUnload(() => {
|
|
|
918
918
|
</view>
|
|
919
919
|
</view>
|
|
920
920
|
<view class="k-glass k-glass--lit login-panel">
|
|
921
|
-
<view class="k-cnr k-cnr--tl" aria-hidden="true"></view>
|
|
922
|
-
<view class="k-cnr k-cnr--tr" aria-hidden="true"></view>
|
|
923
|
-
<view class="k-cnr k-cnr--bl" aria-hidden="true"></view>
|
|
924
|
-
<view class="k-cnr k-cnr--br" aria-hidden="true"></view>
|
|
925
921
|
<view class="login-form">
|
|
926
922
|
<!-- 网页端表单登录 -->
|
|
927
923
|
<!-- #ifdef H5 -->
|