@liujitcn/kratos-uni-app-core 0.0.79 → 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.
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { useSettingStore, useUserStore } from '../../../stores'
2
+ import { useSettingStore, useThemeStore, useUserStore } from '../../../stores'
3
3
  import type { LoginRequest } from '../../../rpc/base/v1/login'
4
4
  import { LoginStatus, type LoginResponse } from '../../../rpc/base/v1/login'
5
5
  import { onLoad, onUnload } from '@dcloudio/uni-app'
@@ -23,6 +23,7 @@ const GoCaptchaUni = defineAsyncComponent(() => import('go-captcha-uni'))
23
23
 
24
24
  const userStore = useUserStore()
25
25
  const settingStore = useSettingStore()
26
+ const themeStore = useThemeStore()
26
27
  const { locale, setLocale, t } = useI18n()
27
28
  const localeOptions = computed(() => getLanguageOptions())
28
29
  const localeLabels = computed(() => localeOptions.value.map((item) => item.native_name))
@@ -33,6 +34,12 @@ const localeIndex = computed(() =>
33
34
  ),
34
35
  )
35
36
  const wechatMiniProvider = 'wechatmini'
37
+
38
+ /** 参考管理端 View、Hide 图标视觉的本端 SVG 路径。 */
39
+ const passwordIconPaths = {
40
+ view: 'M512 160c320 0 512 352 512 352S832 864 512 864 0 512 0 512s192-352 512-352m0 64c-225.28 0-384.128 208.064-436.8 288 52.608 79.872 211.456 288 436.8 288 225.28 0 384.128-208.064 436.8-288-52.608-79.872-211.456-288-436.8-288m0 64a224 224 0 1 1 0 448 224 224 0 0 1 0-448m0 64a160.19 160.19 0 0 0-160 160c0 88.192 71.744 160 160 160s160-71.808 160-160-71.744-160-160-160',
41
+ hide: 'M876.8 156.8c0-9.6-3.2-16-9.6-22.4s-12.8-9.6-22.4-9.6-16 3.2-22.4 9.6L736 220.8c-64-32-137.6-51.2-224-60.8-160 16-288 73.6-377.6 176S0 496 0 512s48 73.6 134.4 176c22.4 25.6 44.8 48 73.6 67.2l-86.4 89.6c-6.4 6.4-9.6 12.8-9.6 22.4s3.2 16 9.6 22.4 12.8 9.6 22.4 9.6 16-3.2 22.4-9.6l704-710.4c3.2-6.4 6.4-12.8 6.4-22.4m-646.4 528Q115.2 579.2 76.8 512q43.2-72 153.6-172.8C304 272 400 230.4 512 224c64 3.2 124.8 19.2 176 44.8l-54.4 54.4C598.4 300.8 560 288 512 288c-64 0-115.2 22.4-160 64s-64 96-64 160c0 48 12.8 89.6 35.2 124.8L256 707.2c-9.6-6.4-19.2-16-25.6-22.4m140.8-96Q352 555.2 352 512c0-44.8 16-83.2 48-112s67.2-48 112-48c28.8 0 54.4 6.4 73.6 19.2zM889.599 336c-12.8-16-28.8-28.8-41.6-41.6l-48 48c73.6 67.2 124.8 124.8 150.4 169.6q-43.2 72-153.6 172.8c-73.6 67.2-172.8 108.8-284.8 115.2-51.2-3.2-99.2-12.8-140.8-28.8l-48 48c57.6 22.4 118.4 38.4 188.8 44.8 160-16 288-73.6 377.6-176S1024 528 1024 512s-48.001-73.6-134.401-176M511.998 672c-12.8 0-25.6-3.2-38.4-6.4l-51.2 51.2c28.8 12.8 57.6 19.2 89.6 19.2 64 0 115.2-22.4 160-64 41.6-41.6 64-96 64-160 0-32-6.4-64-19.2-89.6l-51.2 51.2c3.2 12.8 6.4 25.6 6.4 38.4 0 44.8-16 83.2-48 112s-67.2 48-112 48',
42
+ } as const
36
43
  const loginSettingsReady = ref(false)
37
44
  let loginSettingsPromise: Promise<boolean> | undefined
38
45
 
@@ -48,6 +55,13 @@ const configuredAppLogo = computed(() => {
48
55
  })
49
56
  const appLogo = ref(defaultLogo)
50
57
  const showTenantCode = computed(() => settingStore.getData('showTenantCode') !== 'false')
58
+ /** 按管理端 View、Hide 视觉生成本端密码可见性图标。 */
59
+ const passwordIconSrc = (visible: boolean) => {
60
+ const color = themeStore.theme === 'light' ? '#5a7083' : '#8aa0b4'
61
+ const path = visible ? passwordIconPaths.hide : passwordIconPaths.view
62
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" fill="${color}"><path d="${path}"/></svg>`
63
+ return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`
64
+ }
51
65
 
52
66
  watch(
53
67
  configuredAppLogo,
@@ -86,10 +100,6 @@ const mfaSetupWebAuthnOptionsJson = ref('')
86
100
  const mfaRecoveryCodesVisible = ref(false)
87
101
  const mfaRecoveryCodes = ref<string[]>([])
88
102
 
89
- watch(locale, () => void uni.setNavigationBarTitle({ title: t('common.action.login') }), {
90
- immediate: true,
91
- })
92
-
93
103
  /** 切换登录页语言。 */
94
104
  const onLocaleChange = (event: { detail: { value: string | number } }) => {
95
105
  const nextLocale = localeOptions.value[Number(event.detail.value)]?.language_code as
@@ -151,6 +161,7 @@ const miniForm = reactive({
151
161
  captcha_id: '',
152
162
  })
153
163
  const miniPasswordValue = ref('')
164
+ const miniPasswordVisible = ref(false)
154
165
 
155
166
  type MiniFileSystemManager = {
156
167
  writeFile(options: {
@@ -589,6 +600,13 @@ const refreshCaptcha = async () => {
589
600
  }
590
601
  }
591
602
 
603
+ /** 返回上一页;登录页可能是冷启动首页,无上级页面时回主页。 */
604
+ const goBack = () => {
605
+ uni.navigateBack({
606
+ fail: () => uni.reLaunch({ url: homeTabPage }),
607
+ })
608
+ }
609
+
592
610
  // 页面加载或普通表单刷新验证码,行为验证码延迟到登录弹窗打开时再请求。
593
611
  const loadPageCaptcha = async () => {
594
612
  if (isBehaviorCaptcha.value) {
@@ -636,6 +654,7 @@ const form = ref<LoginRequest>({
636
654
  captcha_code: '',
637
655
  })
638
656
  const passwordValue = ref('')
657
+ const passwordVisible = ref(false)
639
658
  // 校验账号密码与协议勾选状态。
640
659
  const validateLoginForm = async () => {
641
660
  if (!(await ensureLoginSettings())) {
@@ -807,6 +826,8 @@ const checkedAgreePrivacy = async () => {
807
826
  content: t('core.login.protocol_prompt'),
808
827
  confirmText: t('common.action.confirm'),
809
828
  cancelText: t('common.action.cancel'),
829
+ confirmColor: themeStore.theme === 'light' ? '#039e8c' : '#28f0d4',
830
+ cancelColor: themeStore.theme === 'light' ? '#5a7083' : '#8aa0b4',
810
831
  success: ({ confirm }) => {
811
832
  if (confirm) {
812
833
  isAgreePrivacy.value = true
@@ -875,64 +896,91 @@ onUnload(() => {
875
896
  </script>
876
897
 
877
898
  <template>
878
- <view class="login-page">
879
- <picker
880
- class="login-locale"
881
- :range="localeLabels"
882
- :value="localeIndex"
883
- @change="onLocaleChange"
884
- >
885
- <view class="login-locale__value">{{ localeLabels[localeIndex] }}</view>
886
- </picker>
899
+ <view class="login-page" :class="themeStore.themeClass">
900
+ <view class="login-header">
901
+ <view class="k-ic login-back" aria-hidden="true" @tap="goBack">‹</view>
902
+ <picker
903
+ class="login-locale"
904
+ :range="localeLabels"
905
+ :value="localeIndex"
906
+ @change="onLocaleChange"
907
+ >
908
+ <view class="k-lg-lang login-locale__value">{{ localeLabels[localeIndex] }}</view>
909
+ </picker>
910
+ </view>
887
911
  <view class="login-hero">
888
- <view class="login-logo-shell">
889
- <image :src="appLogo" @error="handleLogoError" />
912
+ <view class="k-lg-logo login-logo-shell">
913
+ <image class="login-logo" :src="appLogo" @error="handleLogoError" />
890
914
  </view>
891
915
  <view class="login-hero-copy">
892
- <text class="login-title">{{ configuredMainTitle }}</text>
893
- <text class="login-subtitle">{{ configuredSubTitle }}</text>
916
+ <text class="k-lg-title login-title">{{ configuredMainTitle }}</text>
917
+ <text class="k-lg-sub login-subtitle">{{ configuredSubTitle }}</text>
894
918
  </view>
895
919
  </view>
896
- <view class="login-panel">
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>
897
925
  <view class="login-form">
898
926
  <!-- 网页端表单登录 -->
899
927
  <!-- #ifdef H5 -->
900
- <input
901
- v-if="showTenantCode"
902
- v-model="form.tenant_code"
903
- class="login-input"
904
- type="text"
905
- confirm-type="next"
906
- :placeholder="t('core.login.tenant')"
907
- />
908
- <input
909
- v-model="form.user_name"
910
- class="login-input"
911
- type="text"
912
- confirm-type="next"
913
- :placeholder="t('core.login.user_name_mobile')"
914
- @confirm="onSubmit"
915
- />
916
- <input
917
- v-model="passwordValue"
918
- class="login-input"
919
- type="text"
920
- password
921
- confirm-type="done"
922
- :placeholder="t('core.login.password')"
923
- @confirm="onSubmit"
924
- />
925
- <view v-if="!isBehaviorCaptcha" class="captcha-row">
928
+ <view v-if="showTenantCode" class="k-lg-field">
929
+ <input
930
+ v-model="form.tenant_code"
931
+ class="k-lg-field__input"
932
+ type="text"
933
+ confirm-type="next"
934
+ :placeholder="t('core.login.tenant')"
935
+ />
936
+ </view>
937
+ <view class="k-lg-field">
938
+ <input
939
+ v-model="form.user_name"
940
+ class="k-lg-field__input"
941
+ type="text"
942
+ confirm-type="next"
943
+ :placeholder="t('core.login.user_name_mobile')"
944
+ @confirm="onSubmit"
945
+ />
946
+ </view>
947
+ <view class="k-lg-field">
948
+ <input
949
+ v-model="passwordValue"
950
+ class="k-lg-field__input"
951
+ type="text"
952
+ :password="!passwordVisible"
953
+ confirm-type="done"
954
+ :placeholder="t('core.login.password')"
955
+ @confirm="onSubmit"
956
+ />
957
+ <view
958
+ class="password-toggle"
959
+ :aria-label="passwordVisible ? '隐藏密码' : '显示密码'"
960
+ @tap="passwordVisible = !passwordVisible"
961
+ >
962
+ <image
963
+ class="password-toggle-icon"
964
+ :src="passwordIconSrc(passwordVisible)"
965
+ mode="aspectFit"
966
+ ></image>
967
+ </view>
968
+ </view>
969
+ <view v-if="!isBehaviorCaptcha" class="k-lg-field">
926
970
  <input
927
971
  v-model="form.captcha_code"
928
- class="login-input captcha-input"
972
+ class="k-lg-field__input"
929
973
  type="text"
930
974
  confirm-type="done"
931
975
  :placeholder="t('core.login.captcha')"
932
976
  @confirm="onSubmit"
933
977
  />
934
978
  <view class="captcha-divider"></view>
935
- <view class="captcha-trigger" :style="{ width: captchaImageWidth }" @tap="getCaptcha">
979
+ <view
980
+ class="k-lg-cap captcha-trigger"
981
+ :style="{ width: captchaImageWidth }"
982
+ @tap="getCaptcha"
983
+ >
936
984
  <image
937
985
  class="captcha-image"
938
986
  :style="{ width: captchaImageWidth }"
@@ -942,7 +990,7 @@ onUnload(() => {
942
990
  />
943
991
  </view>
944
992
  </view>
945
- <button @tap="onSubmit" class="login-button login-button-primary">
993
+ <button @tap="onSubmit" class="k-lg-btn k-lg-btn--pri">
946
994
  {{ t('common.action.login') }}
947
995
  </button>
948
996
  <view v-if="behaviorDialogVisible" class="login-behavior-mask">
@@ -965,68 +1013,75 @@ onUnload(() => {
965
1013
 
966
1014
  <!-- 小程序端授权登录 -->
967
1015
  <!-- #ifdef MP-WEIXIN -->
968
- <button
969
- v-if="!miniBinding"
970
- class="login-button login-button-primary"
971
- :loading="loading"
972
- @tap="wxLogin"
973
- >
1016
+ <button v-if="!miniBinding" class="k-lg-btn k-lg-btn--wx" :loading="loading" @tap="wxLogin">
974
1017
  <text class="icon icon-phone"></text>
975
1018
  {{ t('core.login.wechat') }}
976
1019
  </button>
977
1020
  <view v-else class="login-form">
978
1021
  <view class="login-bind-tip">{{ t('core.login.wechat_bind_tip') }}</view>
979
- <input
980
- v-if="showTenantCode"
981
- v-model="miniForm.tenant_code"
982
- class="login-input"
983
- type="text"
984
- :placeholder="t('core.login.tenant')"
985
- />
986
- <input
987
- v-model="miniForm.user_name"
988
- class="login-input"
989
- type="text"
990
- :placeholder="t('core.login.user_name_mobile')"
991
- />
992
- <input
993
- v-model="miniPasswordValue"
994
- class="login-input"
995
- type="text"
996
- password
997
- :placeholder="t('core.login.password')"
998
- />
999
- <view class="captcha-row">
1022
+ <view v-if="showTenantCode" class="k-lg-field">
1023
+ <input
1024
+ v-model="miniForm.tenant_code"
1025
+ class="k-lg-field__input"
1026
+ type="text"
1027
+ :placeholder="t('core.login.tenant')"
1028
+ />
1029
+ </view>
1030
+ <view class="k-lg-field">
1031
+ <input
1032
+ v-model="miniForm.user_name"
1033
+ class="k-lg-field__input"
1034
+ type="text"
1035
+ :placeholder="t('core.login.user_name_mobile')"
1036
+ />
1037
+ </view>
1038
+ <view class="k-lg-field">
1039
+ <input
1040
+ v-model="miniPasswordValue"
1041
+ class="k-lg-field__input"
1042
+ type="text"
1043
+ :password="!miniPasswordVisible"
1044
+ :placeholder="t('core.login.password')"
1045
+ />
1046
+ <view
1047
+ class="password-toggle"
1048
+ :aria-label="miniPasswordVisible ? '隐藏密码' : '显示密码'"
1049
+ @tap="miniPasswordVisible = !miniPasswordVisible"
1050
+ >
1051
+ <image
1052
+ class="password-toggle-icon"
1053
+ :src="passwordIconSrc(miniPasswordVisible)"
1054
+ mode="aspectFit"
1055
+ ></image>
1056
+ </view>
1057
+ </view>
1058
+ <view class="k-lg-field">
1000
1059
  <input
1001
1060
  v-model="miniForm.captcha_code"
1002
- class="login-input captcha-input"
1061
+ class="k-lg-field__input"
1003
1062
  type="text"
1004
1063
  :placeholder="t('core.login.captcha')"
1005
1064
  />
1006
1065
  <view class="captcha-divider"></view>
1007
- <view class="captcha-trigger" @tap="refreshMiniCaptcha">
1066
+ <view class="k-lg-cap captcha-trigger" @tap="refreshMiniCaptcha">
1008
1067
  <image class="captcha-image" :src="miniCaptchaImage" mode="aspectFit" />
1009
1068
  </view>
1010
1069
  </view>
1011
- <button
1012
- class="login-button login-button-primary"
1013
- :loading="loading"
1014
- @tap="bindMiniAccount"
1015
- >
1070
+ <button class="k-lg-btn k-lg-btn--pri" :loading="loading" @tap="bindMiniAccount">
1016
1071
  {{ t('core.login.bind_wechat') }}
1017
1072
  </button>
1018
1073
  </view>
1019
1074
  <!-- #endif -->
1020
1075
  </view>
1021
1076
  <view class="login-tips" :class="{ animate__shakeY: isAgreePrivacyShakeY }">
1022
- <view class="login-agreement" @tap="toggleAgreePrivacy">
1023
- <view class="login-agree-icon" :class="{ checked: isAgreePrivacy }"></view>
1077
+ <view class="k-lg-agree login-agreement" @tap="toggleAgreePrivacy">
1078
+ <view class="k-lg-chk" :class="{ 'k-lg-chk--off': !isAgreePrivacy }">✓</view>
1024
1079
  <text class="login-agree-desc">{{ t('core.login.agree_prefix') }}</text>
1025
- <text class="login-agree-link" @tap.stop="onOpenServiceProtocol">{{
1080
+ <text class="k-lg-link login-agree-link" @tap.stop="onOpenServiceProtocol">{{
1026
1081
  t('core.login.service')
1027
1082
  }}</text>
1028
1083
  <text class="login-agree-separator">{{ t('core.login.agree_separator') }}</text>
1029
- <text class="login-agree-link" @tap.stop="onOpenPrivacyContract">{{
1084
+ <text class="k-lg-link login-agree-link" @tap.stop="onOpenPrivacyContract">{{
1030
1085
  t('core.login.privacy')
1031
1086
  }}</text>
1032
1087
  </view>
@@ -1052,7 +1107,11 @@ onUnload(() => {
1052
1107
  @change="rememberMfaDevice = $event.detail.value.includes('remember')"
1053
1108
  >
1054
1109
  <label class="mfa-remember-device">
1055
- <checkbox value="remember" :checked="rememberMfaDevice" />
1110
+ <checkbox
1111
+ class="mfa-remember-device__checkbox"
1112
+ value="remember"
1113
+ :checked="rememberMfaDevice"
1114
+ />
1056
1115
  <text>{{ t('core.login.mfa_remember_device', { days: mfaRememberDays }) }}</text>
1057
1116
  </label>
1058
1117
  </checkbox-group>
@@ -1110,73 +1169,70 @@ onUnload(() => {
1110
1169
  flex-direction: column;
1111
1170
  justify-content: center;
1112
1171
  min-height: 100vh;
1113
- padding: 48rpx 40rpx 56rpx;
1114
- background: linear-gradient(180deg, #f4fbf8 0%, #ffffff 45%, #ffffff 100%);
1172
+ padding: 48rpx 40rpx calc(56rpx + env(safe-area-inset-bottom));
1173
+ background: var(--kratos-bg-gradient);
1115
1174
  box-sizing: border-box;
1116
1175
  }
1117
1176
 
1177
+ /* 自绘头部:左返回(复用 k-ic)、右上角语言(复用 k-lg-lang),替代原生导航栏 */
1178
+ .login-header {
1179
+ position: fixed;
1180
+ top: 0;
1181
+ right: 0;
1182
+ left: 0;
1183
+ z-index: 3;
1184
+ display: flex;
1185
+ align-items: center;
1186
+ justify-content: space-between;
1187
+ height: 44px;
1188
+ padding: env(safe-area-inset-top) 28rpx 0;
1189
+ box-sizing: content-box;
1190
+ }
1191
+
1192
+ /* #ifdef MP-WEIXIN */
1193
+ .login-header {
1194
+ /* 右上角避让小程序胶囊 */
1195
+ padding-right: 220rpx;
1196
+ }
1197
+ /* #endif */
1198
+
1199
+ /* k-ic 已提供方形图标按钮视觉,这里只补字号以容纳返回符号 */
1200
+ .login-back {
1201
+ font-size: 36rpx;
1202
+ line-height: 1;
1203
+ }
1204
+
1118
1205
  .login-locale {
1119
- position: absolute;
1120
- top: calc(24rpx + env(safe-area-inset-top));
1121
- right: 28rpx;
1122
- z-index: 2;
1123
- max-width: calc(100% - 56rpx);
1206
+ max-width: calc(100% - 120rpx);
1124
1207
  }
1125
1208
 
1209
+ /* k-lg-lang 已提供视觉样式,这里只补多语言文案的截断处理 */
1126
1210
  .login-locale__value {
1127
1211
  max-width: 240rpx;
1128
1212
  overflow: hidden;
1129
- padding: 12rpx 16rpx;
1130
- color: #16806d;
1131
- font-size: 24rpx;
1132
1213
  text-overflow: ellipsis;
1133
1214
  white-space: nowrap;
1134
1215
  }
1135
1216
 
1136
1217
  .login-hero {
1137
- margin-bottom: 40rpx;
1218
+ margin-bottom: 44rpx;
1138
1219
  text-align: center;
1139
1220
 
1140
- .login-logo-shell {
1141
- display: inline-flex;
1142
- align-items: center;
1143
- justify-content: center;
1144
- width: 180rpx;
1145
- height: 180rpx;
1146
- margin-bottom: 24rpx;
1147
- border-radius: 44rpx;
1148
- background: rgba(255, 255, 255, 0.92);
1149
- box-shadow: 0 18rpx 44rpx rgba(40, 187, 156, 0.12);
1150
- }
1151
-
1152
- image {
1153
- width: 120rpx;
1154
- height: 120rpx;
1221
+ /* k-lg-logo 已提供渐变底板,这里只约束内部实际 Logo 图片尺寸 */
1222
+ .login-logo {
1223
+ width: 100rpx;
1224
+ height: 100rpx;
1155
1225
  }
1156
1226
 
1157
1227
  .login-hero-copy {
1158
1228
  display: flex;
1159
1229
  flex-direction: column;
1160
1230
  }
1161
-
1162
- .login-title {
1163
- font-size: 44rpx;
1164
- font-weight: 600;
1165
- color: #1f2937;
1166
- }
1167
-
1168
- .login-subtitle {
1169
- margin-top: 12rpx;
1170
- color: #6b7280;
1171
- font-size: 26rpx;
1172
- }
1173
1231
  }
1174
1232
 
1233
+ /* k-glass/k-glass--lit 已提供卡片底色与描边,这里只补内部留白 */
1175
1234
  .login-panel {
1176
- padding: 36rpx 28rpx 30rpx;
1177
- border-radius: 24rpx;
1178
- background: rgba(255, 255, 255, 0.96);
1179
- box-shadow: 0 24rpx 60rpx rgba(15, 23, 42, 0.08);
1235
+ padding: 36rpx 30rpx 30rpx;
1180
1236
  }
1181
1237
 
1182
1238
  .login-form {
@@ -1185,100 +1241,53 @@ onUnload(() => {
1185
1241
 
1186
1242
  .login-bind-tip {
1187
1243
  margin-bottom: 20rpx;
1188
- color: #6b7280;
1244
+ color: var(--kratos-color-text-muted);
1189
1245
  font-size: 24rpx;
1190
1246
  line-height: 1.5;
1191
1247
  text-align: center;
1192
1248
  }
1193
1249
 
1194
- .login-input {
1195
- width: 100%;
1196
- height: 88rpx;
1197
- font-size: 28rpx;
1198
- color: #1f2937;
1199
- border-radius: 24rpx;
1200
- border: 1px solid #e5e7eb;
1201
- background: #f9fbfa;
1202
- padding: 0 30rpx;
1203
- margin-bottom: 20rpx;
1204
- box-sizing: border-box;
1205
- }
1206
-
1207
- .login-button {
1250
+ /* 密码/验证码行内尾随的小按钮: k-lg-field 没有对应词汇,保留页面局部样式 */
1251
+ .password-toggle {
1208
1252
  display: flex;
1253
+ flex: 0 0 52rpx;
1209
1254
  align-items: center;
1210
1255
  justify-content: center;
1211
- width: 100%;
1212
- height: 88rpx;
1213
- margin-top: 12rpx;
1214
- font-size: 30rpx;
1215
- font-weight: 500;
1216
- border-radius: 24rpx;
1217
- color: #fff;
1218
- box-shadow: 0 18rpx 36rpx rgba(40, 187, 156, 0.24);
1219
-
1220
- &::after {
1221
- border: 0;
1222
- }
1223
-
1224
- .icon {
1225
- font-size: 40rpx;
1226
- margin-right: 10rpx;
1227
- }
1256
+ width: 52rpx;
1257
+ height: 52rpx;
1258
+ margin-left: 12rpx;
1259
+ }
1228
1260
 
1229
- .icon-phone::before {
1230
- content: '☎';
1231
- }
1261
+ .password-toggle-icon {
1262
+ width: 24rpx;
1263
+ height: 24rpx;
1232
1264
  }
1233
1265
 
1234
- .login-button-primary {
1235
- background: linear-gradient(135deg, #34c8aa 0%, #28bb9c 100%);
1266
+ .icon {
1267
+ margin-right: 10rpx;
1268
+ font-size: 32rpx;
1236
1269
  }
1237
1270
 
1238
- .captcha-row {
1239
- display: flex;
1240
- align-items: center;
1241
- width: 100%;
1242
- height: 88rpx;
1243
- margin-bottom: 20rpx;
1244
- padding: 0 12rpx 0 30rpx;
1245
- border: 1px solid #e5e7eb;
1246
- border-radius: 24rpx;
1247
- background: #f9fbfa;
1248
- box-sizing: border-box;
1249
-
1250
- .captcha-input {
1251
- flex: 1;
1252
- height: 100%;
1253
- margin-bottom: 0;
1254
- padding: 0;
1255
- border: 0;
1256
- background: transparent;
1257
- }
1271
+ .icon-phone::before {
1272
+ content: '☎';
1273
+ }
1258
1274
 
1259
- .captcha-divider {
1260
- width: 1rpx;
1261
- height: 44rpx;
1262
- background: #e7ebf0;
1263
- }
1275
+ .captcha-divider {
1276
+ flex-shrink: 0;
1277
+ width: 1rpx;
1278
+ height: 44rpx;
1279
+ background: var(--kratos-color-border);
1280
+ }
1264
1281
 
1265
- .captcha-trigger {
1266
- display: flex;
1267
- align-items: center;
1268
- justify-content: center;
1269
- flex: 0 0 auto;
1270
- height: 72rpx;
1271
- margin-left: 14rpx;
1272
- border-radius: 18rpx;
1273
- background: #fff;
1274
- box-sizing: border-box;
1275
- }
1282
+ /* k-lg-cap 已提供验证码色块视觉,这里只补行内间距 */
1283
+ .captcha-trigger {
1284
+ margin-left: 14rpx;
1285
+ }
1276
1286
 
1277
- .captcha-image {
1278
- width: 170rpx;
1279
- flex-shrink: 0;
1280
- height: 60rpx;
1281
- }
1287
+ .captcha-image {
1288
+ width: 170rpx;
1289
+ flex-shrink: 0;
1290
+ height: 60rpx;
1282
1291
  }
1283
1292
  }
1284
1293
  .mfa-mask {
@@ -1289,7 +1298,7 @@ onUnload(() => {
1289
1298
  align-items: center;
1290
1299
  justify-content: center;
1291
1300
  padding: 40rpx;
1292
- background: rgba(15, 23, 42, 0.46);
1301
+ background: var(--kratos-color-mask);
1293
1302
  }
1294
1303
  .mfa-panel {
1295
1304
  display: flex;
@@ -1297,7 +1306,8 @@ onUnload(() => {
1297
1306
  width: 100%;
1298
1307
  max-width: 620rpx;
1299
1308
  padding: 36rpx;
1300
- background: #fff;
1309
+ background: var(--kratos-color-surface-solid);
1310
+ border: 1rpx solid var(--kratos-color-border-accent);
1301
1311
  border-radius: 24rpx;
1302
1312
  box-sizing: border-box;
1303
1313
  }
@@ -1305,7 +1315,7 @@ onUnload(() => {
1305
1315
  margin-bottom: 22rpx;
1306
1316
  font-size: 34rpx;
1307
1317
  font-weight: 700;
1308
- color: #172a35;
1318
+ color: var(--kratos-color-text);
1309
1319
  }
1310
1320
 
1311
1321
  .mfa-remember-device {
@@ -1314,24 +1324,24 @@ onUnload(() => {
1314
1324
  margin-bottom: 20rpx;
1315
1325
  font-size: 26rpx;
1316
1326
  line-height: 1.5;
1317
- color: #172a35;
1327
+ color: var(--kratos-color-text);
1318
1328
  }
1319
1329
 
1320
- .mfa-remember-device checkbox {
1330
+ .mfa-remember-device__checkbox {
1321
1331
  flex-shrink: 0;
1322
1332
  margin-right: 12rpx;
1323
1333
  }
1324
1334
 
1325
1335
  .mfa-panel .login-input {
1326
1336
  width: 100%;
1327
- height: 88rpx;
1337
+ height: 96rpx;
1328
1338
  margin-bottom: 20rpx;
1329
1339
  padding: 0 30rpx;
1330
- color: #1f2937;
1340
+ color: var(--kratos-color-text);
1331
1341
  font-size: 28rpx;
1332
- background: #f9fbfa;
1333
- border: 1px solid #e5e7eb;
1334
- border-radius: 24rpx;
1342
+ background: var(--kratos-color-surface-2);
1343
+ border: 1rpx solid var(--kratos-color-border);
1344
+ border-radius: 20rpx;
1335
1345
  box-sizing: border-box;
1336
1346
  }
1337
1347
 
@@ -1340,16 +1350,16 @@ onUnload(() => {
1340
1350
  align-items: center;
1341
1351
  justify-content: center;
1342
1352
  width: 100%;
1343
- height: 88rpx;
1353
+ height: 96rpx;
1344
1354
  margin-top: 12rpx;
1345
1355
  padding: 0;
1346
- color: #fff;
1356
+ color: var(--kratos-color-on-primary);
1347
1357
  font-size: 30rpx;
1348
- font-weight: 500;
1358
+ font-weight: 800;
1349
1359
  background: transparent;
1350
1360
  border: 0;
1351
- border-radius: 24rpx;
1352
- box-shadow: 0 18rpx 36rpx rgba(40, 187, 156, 0.24);
1361
+ border-radius: 20rpx;
1362
+ box-shadow: 0 0 40rpx rgba(40, 240, 212, 0.35);
1353
1363
  }
1354
1364
 
1355
1365
  .mfa-panel .login-button::after {
@@ -1357,7 +1367,11 @@ onUnload(() => {
1357
1367
  }
1358
1368
 
1359
1369
  .mfa-panel .login-button-primary {
1360
- background: linear-gradient(135deg, #34c8aa 0%, #28bb9c 100%);
1370
+ background: linear-gradient(
1371
+ 135deg,
1372
+ var(--kratos-color-primary-deep) 0%,
1373
+ var(--kratos-color-primary) 100%
1374
+ );
1361
1375
  }
1362
1376
 
1363
1377
  .login-behavior-mask {
@@ -1371,7 +1385,7 @@ onUnload(() => {
1371
1385
  align-items: center;
1372
1386
  justify-content: center;
1373
1387
  padding: 24rpx;
1374
- background: rgba(15, 23, 42, 0.38);
1388
+ background: var(--kratos-color-mask);
1375
1389
  box-sizing: border-box;
1376
1390
  }
1377
1391
 
@@ -1437,11 +1451,15 @@ onUnload(() => {
1437
1451
  width: 92rpx;
1438
1452
  height: 56rpx;
1439
1453
  margin-top: -28rpx;
1440
- background: linear-gradient(135deg, #36d6b4 0%, #20aa8f 100%);
1454
+ background: linear-gradient(
1455
+ 135deg,
1456
+ var(--kratos-color-primary-deep) 0%,
1457
+ var(--kratos-color-primary) 100%
1458
+ );
1441
1459
  border-radius: 999rpx;
1442
- box-shadow: 0 14rpx 28rpx rgba(40, 187, 156, 0.28);
1443
- color: #fff;
1444
- fill: #fff;
1460
+ box-shadow: 0 14rpx 28rpx rgba(40, 240, 212, 0.28);
1461
+ color: var(--kratos-color-on-primary);
1462
+ fill: var(--kratos-color-on-primary);
1445
1463
  }
1446
1464
 
1447
1465
  .login-behavior-panel .go-captcha .gc-drag-block.disabled {
@@ -1450,7 +1468,7 @@ onUnload(() => {
1450
1468
  }
1451
1469
 
1452
1470
  .login-behavior-panel .go-captcha .gc-drag-block .gc-icon {
1453
- color: #fff;
1471
+ color: var(--kratos-color-on-primary);
1454
1472
  font-size: 42rpx;
1455
1473
  }
1456
1474
 
@@ -1481,54 +1499,28 @@ onUnload(() => {
1481
1499
 
1482
1500
  .login-tips {
1483
1501
  margin-top: 26rpx;
1484
- font-size: 22rpx;
1485
- color: #999;
1486
- line-height: 1.6;
1487
-
1488
- .login-agreement {
1489
- display: flex;
1490
- align-items: center;
1491
- flex-wrap: wrap;
1492
- justify-content: center;
1493
- width: 100%;
1494
- max-width: 100%;
1495
- min-width: 0;
1496
- gap: 6rpx;
1497
- box-sizing: border-box;
1498
- }
1499
-
1500
- .login-agree-separator {
1501
- min-width: 0;
1502
- overflow-wrap: anywhere;
1503
- }
1502
+ }
1504
1503
 
1505
- .login-agree-icon {
1506
- flex: 0 0 auto;
1507
- width: 26rpx;
1508
- height: 26rpx;
1509
- margin-right: 2rpx;
1510
- border: 2rpx solid #d1d5db;
1511
- border-radius: 50%;
1512
- background-color: #fff;
1513
- box-sizing: border-box;
1514
- }
1504
+ /* k-lg-agree 已提供排版与字色,这里只补宽度约束,保证长文案正常换行 */
1505
+ .login-agreement {
1506
+ box-sizing: border-box;
1507
+ width: 100%;
1508
+ max-width: 100%;
1509
+ min-width: 0;
1510
+ }
1515
1511
 
1516
- .login-agree-icon.checked {
1517
- border-color: #28bb9c;
1518
- background-color: #28bb9c;
1519
- box-shadow: inset 0 0 0 6rpx #fff;
1520
- }
1512
+ .login-agree-separator {
1513
+ min-width: 0;
1514
+ overflow-wrap: anywhere;
1515
+ }
1521
1516
 
1522
- .login-agree-link {
1523
- min-width: 0;
1524
- overflow-wrap: anywhere;
1525
- color: #28bb9c;
1526
- }
1517
+ .login-agree-link {
1518
+ min-width: 0;
1519
+ overflow-wrap: anywhere;
1520
+ }
1527
1521
 
1528
- .login-agree-desc {
1529
- min-width: 0;
1530
- overflow-wrap: anywhere;
1531
- color: #9ca3af;
1532
- }
1522
+ .login-agree-desc {
1523
+ min-width: 0;
1524
+ overflow-wrap: anywhere;
1533
1525
  }
1534
1526
  </style>