13 changed files with 770 additions and 16 deletions
@ -0,0 +1,48 @@ |
|||||||
|
<template> |
||||||
|
<transition> |
||||||
|
<div :class="prefixCls"> |
||||||
|
<MiniLogin sessionTimeout/> |
||||||
|
</div> |
||||||
|
</transition> |
||||||
|
</template> |
||||||
|
<script lang="ts" setup> |
||||||
|
import { onBeforeUnmount, onMounted, ref } from 'vue'; |
||||||
|
import MiniLogin from './MiniLogin.vue'; |
||||||
|
import { useDesign } from '/@/hooks/web/useDesign'; |
||||||
|
import { useUserStore } from '/@/store/modules/user'; |
||||||
|
import { usePermissionStore } from '/@/store/modules/permission'; |
||||||
|
import { useAppStore } from '/@/store/modules/app'; |
||||||
|
|
||||||
|
const { prefixCls } = useDesign('st-login'); |
||||||
|
const userStore = useUserStore(); |
||||||
|
const permissionStore = usePermissionStore(); |
||||||
|
const appStore = useAppStore(); |
||||||
|
const userId = ref<Nullable<number | string>>(0); |
||||||
|
|
||||||
|
onMounted(() => { |
||||||
|
// 记录当前的UserId |
||||||
|
userId.value = userStore.getUserInfo?.id; |
||||||
|
console.log('Mounted', userStore.getUserInfo); |
||||||
|
}); |
||||||
|
|
||||||
|
onBeforeUnmount(() => { |
||||||
|
if (userId.value && userId.value !== userStore.getUserInfo.id) { |
||||||
|
// 登录的不是同一个用户,刷新整个页面以便丢弃之前用户的页面状态 |
||||||
|
document.location.reload(); |
||||||
|
} else if (permissionStore.getLastBuildMenuTime === 0) { |
||||||
|
// 没有成功加载过菜单,就重新加载整个页面。这通常发生在会话过期后按F5刷新整个页面后载入了本模块这种场景 |
||||||
|
document.location.reload(); |
||||||
|
} |
||||||
|
}); |
||||||
|
</script> |
||||||
|
<style lang="less" scoped> |
||||||
|
@prefix-cls: ~'@{namespace}-st-login'; |
||||||
|
|
||||||
|
.@{prefix-cls} { |
||||||
|
position: fixed; |
||||||
|
z-index: 9999999; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
background: @component-background; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,56 @@ |
|||||||
|
<template> |
||||||
|
<PageWrapper |
||||||
|
title="登录过期示例" |
||||||
|
content="用户登录过期示例,不再跳转登录页,直接生成页面覆盖当前页面,方便保持过期前的用户状态!" |
||||||
|
> |
||||||
|
<a-card title="请点击下面的按钮访问测试接口" extra="所访问的接口会返回Token过期响应"> |
||||||
|
<a-card-grid style="width: 50%; text-align: center"> |
||||||
|
<a-button type="primary" @click="test1">HttpStatus == 401</a-button> |
||||||
|
</a-card-grid> |
||||||
|
<a-card-grid style="width: 50%; text-align: center"> |
||||||
|
<span/> |
||||||
|
<a-button class="ml-4" type="primary" @click="test2">Response.code == 401</a-button> |
||||||
|
</a-card-grid> |
||||||
|
</a-card> |
||||||
|
</PageWrapper> |
||||||
|
</template> |
||||||
|
<script lang="ts"> |
||||||
|
import { defineComponent } from 'vue'; |
||||||
|
import { PageWrapper } from '/@/components/Page'; |
||||||
|
import { useUserStore } from '/@/store/modules/user'; |
||||||
|
|
||||||
|
//import { sessionTimeoutApi, tokenExpiredApi } from '/@/api/demo/account'; |
||||||
|
import { Card } from 'ant-design-vue'; |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'TestSessionTimeout', |
||||||
|
components: { ACardGrid: Card.Grid, ACard: Card, PageWrapper }, |
||||||
|
setup() { |
||||||
|
const userStore = useUserStore(); |
||||||
|
async function test1() { |
||||||
|
userStore.setAccessToken(''); |
||||||
|
userStore.setSessionTimeout(true); |
||||||
|
// 示例网站生产环境用的是mock数据,不能返回Http状态码, |
||||||
|
// 所以在生产环境直接改变状态来达到测试效果 |
||||||
|
// if (import.meta.env.PROD) { |
||||||
|
// userStore.setToken(undefined); |
||||||
|
// userStore.setSessionTimeout(true); |
||||||
|
// } else { |
||||||
|
// // 这个api会返回状态码为401的响应 |
||||||
|
// await sessionTimeoutApi(); |
||||||
|
// } |
||||||
|
} |
||||||
|
|
||||||
|
async function test2() { |
||||||
|
// 这个api会返回code为401的json数据,Http状态码为200 |
||||||
|
try { |
||||||
|
//await tokenExpiredApi(); |
||||||
|
} catch (err) { |
||||||
|
console.log('接口访问错误:', (err as Error).message || '错误'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return { test1, test2 }; |
||||||
|
}, |
||||||
|
}); |
||||||
|
</script> |
@ -0,0 +1,559 @@ |
|||||||
|
<template> |
||||||
|
<div :class="prefixCls" class="login-background-img"> |
||||||
|
<AppLocalePicker v-if="showLocale" class="absolute top-4 right-4 enter-x xl:text-gray-600" :showText="false"/> |
||||||
|
<AppDarkModeToggle class="absolute top-3 right-10 enter-x"/> |
||||||
|
<div v-if="!getIsMobile" class="aui-logo"> |
||||||
|
<div> |
||||||
|
<h3> |
||||||
|
<img :src="logoImg"> |
||||||
|
</h3> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div v-else class="aui-phone-logo"> |
||||||
|
<img :src="logoPhoneImg"> |
||||||
|
</div> |
||||||
|
<div v-show="type === 'login'"> |
||||||
|
<div class="aui-content"> |
||||||
|
<div class="aui-container"> |
||||||
|
<div class="aui-form"> |
||||||
|
<div class="aui-image"> |
||||||
|
<div class="aui-image-text"/> |
||||||
|
</div> |
||||||
|
<div class="aui-formBox"> |
||||||
|
<div class="aui-formWell"> |
||||||
|
<div class="aui-flex aui-form-nav"> |
||||||
|
<div |
||||||
|
class="aui-flex-box" |
||||||
|
:class="activeIndex === 'accountLogin' ? 'activeNav on' : ''" |
||||||
|
@click="loginClick('accountLogin')" |
||||||
|
>{{ t('sys.login.signInFormTitle') }}</div> |
||||||
|
<div |
||||||
|
class="aui-flex-box" |
||||||
|
:class="activeIndex === 'phoneLogin' ? 'activeNav on' : ''" |
||||||
|
@click="loginClick('phoneLogin')" |
||||||
|
>{{ t('sys.login.mobileSignInFormTitle') }}</div> |
||||||
|
</div> |
||||||
|
<div class="aui-form-box" style="height: 180px"> |
||||||
|
<a-form |
||||||
|
v-if="activeIndex === 'accountLogin'" |
||||||
|
ref="loginRef" |
||||||
|
:model="formData" |
||||||
|
@keypress.enter="loginHandleClick" |
||||||
|
> |
||||||
|
<div class="aui-account"> |
||||||
|
<div class="aui-inputClear"> |
||||||
|
<i class="icon icon-code"/> |
||||||
|
<a-form-item> |
||||||
|
<a-input v-model:value="formData.username" class="fix-auto-fill" :placeholder="t('sys.login.userName')"/> |
||||||
|
</a-form-item> |
||||||
|
</div> |
||||||
|
<div class="aui-inputClear"> |
||||||
|
<i class="icon icon-password"/> |
||||||
|
<a-form-item> |
||||||
|
<a-input |
||||||
|
v-model:value="formData.password" |
||||||
|
class="fix-auto-fill" |
||||||
|
type="password" |
||||||
|
:placeholder="t('sys.login.password')" |
||||||
|
/> |
||||||
|
</a-form-item> |
||||||
|
</div> |
||||||
|
<div class="aui-inputClear"> |
||||||
|
<i class="icon icon-code"/> |
||||||
|
<a-form-item> |
||||||
|
<a-input |
||||||
|
v-model:value="formData.inputCode" |
||||||
|
class="fix-auto-fill" |
||||||
|
type="text" |
||||||
|
:placeholder="t('sys.login.captcha')" |
||||||
|
/> |
||||||
|
</a-form-item> |
||||||
|
<div class="aui-code"> |
||||||
|
<img v-if="randCodeData.requestCodeSuccess" :src="randCodeData.randCodeImage" @click="handleChangeCheckCode"> |
||||||
|
<img |
||||||
|
v-else |
||||||
|
style="margin-top: 2px; max-width: initial" |
||||||
|
:src="defaultCaptchaImg" |
||||||
|
@click="handleChangeCheckCode" |
||||||
|
> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="aui-flex"> |
||||||
|
<div class="aui-flex-box"> |
||||||
|
<div class="aui-choice"> |
||||||
|
<a-input v-model:value="rememberMe" class="fix-auto-fill" type="checkbox"/> |
||||||
|
<span style="margin-left: 5px">{{ t('sys.login.rememberMe') }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="aui-forget"> |
||||||
|
<a @click="forgetHandelClick"> {{ t('sys.login.forgetPassword') }}</a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</a-form> |
||||||
|
<a-form |
||||||
|
v-else |
||||||
|
ref="phoneFormRef" |
||||||
|
:model="phoneFormData" |
||||||
|
@keypress.enter="loginHandleClick" |
||||||
|
> |
||||||
|
<div class="aui-account phone"> |
||||||
|
<div class="aui-inputClear phoneClear"> |
||||||
|
<a-input v-model:value="phoneFormData.mobile" class="fix-auto-fill" :placeholder="t('sys.login.mobile')"/> |
||||||
|
</div> |
||||||
|
<div class="aui-inputClear"> |
||||||
|
<a-input |
||||||
|
v-model:value="phoneFormData.smscode" |
||||||
|
class="fix-auto-fill" |
||||||
|
:maxlength="6" |
||||||
|
:placeholder="t('sys.login.smsCode')" |
||||||
|
/> |
||||||
|
<div v-if="showInterval" class="aui-code" @click="getLoginCode"> |
||||||
|
<a>{{ t('component.countdown.normalText') }}</a> |
||||||
|
</div> |
||||||
|
<div v-else class="aui-code"> |
||||||
|
<span class="aui-get-code code-shape">{{ t('component.countdown.sendText', [unref(timeRuning)]) }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</a-form> |
||||||
|
</div> |
||||||
|
<div class="aui-formButton"> |
||||||
|
<div class="aui-flex"> |
||||||
|
<a-button |
||||||
|
:loading="loginLoading" |
||||||
|
class="aui-link-login aui-flex-box" |
||||||
|
type="primary" |
||||||
|
@click="loginHandleClick" |
||||||
|
>{{ t('sys.login.loginButton') }}</a-button> |
||||||
|
</div> |
||||||
|
<div class="aui-flex"> |
||||||
|
<a class="aui-linek-code aui-flex-box" @click="codeHandleClick">{{ t('sys.login.qrSignInFormTitle') }}</a> |
||||||
|
</div> |
||||||
|
<!--<div class="aui-flex"> |
||||||
|
<a class="aui-linek-code aui-flex-box" @click="registerHandleClick">{{ t('sys.login.registerButton') }}</a> |
||||||
|
</div>--> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<a-form> |
||||||
|
<div class="aui-flex aui-third-text"> |
||||||
|
<div class="aui-flex-box aui-third-border"> |
||||||
|
<span>{{ t('sys.login.otherSignIn') }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="aui-flex" :class="`${prefixCls}-sign-in-way`"> |
||||||
|
<div class="aui-flex-box"> |
||||||
|
<div class="aui-third-login"> |
||||||
|
<a title="github" @click="onThirdLogin('github')"><GithubFilled/></a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="aui-flex-box"> |
||||||
|
<div class="aui-third-login"> |
||||||
|
<a title="支付宝" @click="onThirdLogin('alipay')"><AlipayCircleFilled/></a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="aui-flex-box"> |
||||||
|
<div class="aui-third-login"> |
||||||
|
<a title="钉钉" @click="onThirdLogin('dingtalk')"><DingtalkCircleFilled/></a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="aui-flex-box"> |
||||||
|
<div class="aui-third-login"> |
||||||
|
<a title="微信" @click="onThirdLogin('wechat_open')"><WechatFilled/></a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</a-form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div v-show="type === 'forgot'" :class="`${prefixCls}-form`"> |
||||||
|
<MiniForgotpad ref="forgotRef" @go-back="goBack" @success="handleSuccess"/> |
||||||
|
</div> |
||||||
|
<div v-show="type === 'register'" :class="`${prefixCls}-form`"> |
||||||
|
<MiniRegister ref="registerRef" @go-back="goBack" @success="handleSuccess"/> |
||||||
|
</div> |
||||||
|
<div v-show="type === 'codeLogin'" :class="`${prefixCls}-form`"> |
||||||
|
<MiniCodelogin ref="codeRef" @go-back="goBack" @success="handleSuccess"/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script lang="ts" setup> |
||||||
|
import { getCaptcha } from '/@/api/platform/core/controller/user'; |
||||||
|
import { onMounted, reactive, ref, toRaw, unref } from 'vue'; |
||||||
|
import defaultCaptchaImg from '/@/assets/images/captcha.jpg'; |
||||||
|
import { useUserStore } from '/@/store/modules/user'; |
||||||
|
import { useMessage } from '/@/hooks/web/useMessage'; |
||||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||||
|
import MiniForgotpad from './MiniForgotpad.vue'; |
||||||
|
import MiniRegister from './MiniRegister.vue'; |
||||||
|
import MiniCodelogin from './MiniCodelogin.vue'; |
||||||
|
import logoImg from '/@/assets/images/logo-tag.png'; |
||||||
|
import logoPhoneImg from '/@/assets/images/logo.png'; |
||||||
|
import { AppLocalePicker, AppDarkModeToggle } from '/@/components/Application'; |
||||||
|
import { useLocaleStore } from '/@/store/modules/locale'; |
||||||
|
import { useDesign } from '/@/hooks/web/useDesign'; |
||||||
|
import { useAppInject } from '/@/hooks/web/useAppInject'; |
||||||
|
import { GithubFilled, WechatFilled, AlipayCircleFilled, DingtalkCircleFilled } from '@ant-design/icons-vue'; |
||||||
|
|
||||||
|
const { prefixCls } = useDesign('mini-login'); |
||||||
|
const { notification, createMessage } = useMessage(); |
||||||
|
const userStore = useUserStore(); |
||||||
|
const { t } = useI18n(); |
||||||
|
const localeStore = useLocaleStore(); |
||||||
|
const showLocale = localeStore.getShowPicker; |
||||||
|
const randCodeData = reactive<any>({ |
||||||
|
randCodeImage: '', |
||||||
|
requestCodeSuccess: false, |
||||||
|
}); |
||||||
|
const rememberMe = ref<string>('0'); |
||||||
|
// 手机号登录还是账号登录 |
||||||
|
const activeIndex = ref<string>('accountLogin'); |
||||||
|
const type = ref<string>('login'); |
||||||
|
// 账号登录表单字段 |
||||||
|
const formData = reactive<any>({ |
||||||
|
realKey: '', |
||||||
|
inputCode: '', |
||||||
|
username: '', |
||||||
|
password: '', |
||||||
|
}); |
||||||
|
// 手机登录表单字段 |
||||||
|
const phoneFormData = reactive<any>({ |
||||||
|
mobile: '', |
||||||
|
smscode: '', |
||||||
|
}); |
||||||
|
const loginRef = ref(); |
||||||
|
// 扫码登录 |
||||||
|
const codeRef = ref(); |
||||||
|
// 是否显示获取验证码 |
||||||
|
const showInterval = ref<boolean>(true); |
||||||
|
// 60s |
||||||
|
const timeRuning = ref<number>(60); |
||||||
|
// 定时器 |
||||||
|
const timer = ref<any>(null); |
||||||
|
// 忘记密码 |
||||||
|
const forgotRef = ref(); |
||||||
|
// 注册 |
||||||
|
const registerRef = ref(); |
||||||
|
const loginLoading = ref<boolean>(false); |
||||||
|
const { getIsMobile } = useAppInject(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取验证码 |
||||||
|
*/ |
||||||
|
async function handleChangeCheckCode() { |
||||||
|
formData.inputCode = ''; |
||||||
|
try { |
||||||
|
const codeModel = await getCaptcha(); |
||||||
|
randCodeData.randCodeImage = codeModel.img; |
||||||
|
randCodeData.requestCodeSuccess = true; |
||||||
|
formData.realKey = codeModel.realKey; |
||||||
|
} catch(error) { |
||||||
|
randCodeData.requestCodeSuccess = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 切换登录方式 |
||||||
|
*/ |
||||||
|
function loginClick(type) { |
||||||
|
activeIndex.value = type; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 账号或者手机登录 |
||||||
|
*/ |
||||||
|
async function loginHandleClick() { |
||||||
|
if (unref(activeIndex) === 'accountLogin') { |
||||||
|
await accountLogin(); |
||||||
|
} else { |
||||||
|
await phoneLogin(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
async function accountLogin() { |
||||||
|
if (!formData.username) { |
||||||
|
createMessage.warn(t('sys.login.accountPlaceholder')); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (!formData.password) { |
||||||
|
createMessage.warn(t('sys.login.passwordPlaceholder')); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (!formData.inputCode) { |
||||||
|
createMessage.warn(t('sys.login.smsPlaceholder')); |
||||||
|
return; |
||||||
|
} |
||||||
|
try { |
||||||
|
loginLoading.value = true; |
||||||
|
const userInfo = await userStore.login(toRaw({ |
||||||
|
password: formData.password, |
||||||
|
username: formData.username, |
||||||
|
realKey: formData.realKey, |
||||||
|
code: formData.inputCode, |
||||||
|
})); |
||||||
|
if (userInfo) { |
||||||
|
notification.success({ |
||||||
|
message: t('sys.login.loginSuccessTitle'), |
||||||
|
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.nickName}`, |
||||||
|
duration: 3, |
||||||
|
}); |
||||||
|
} |
||||||
|
} catch (error){ |
||||||
|
formData.code=''; |
||||||
|
formData.realKey=''; |
||||||
|
await handleChangeCheckCode(); |
||||||
|
} finally { |
||||||
|
loginLoading.value = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 手机号登录 |
||||||
|
*/ |
||||||
|
async function phoneLogin() { |
||||||
|
notification.success({ |
||||||
|
message: '功能待开发中.', |
||||||
|
duration: 3, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取手机验证码 |
||||||
|
*/ |
||||||
|
async function getLoginCode() { |
||||||
|
/*if (!phoneFormData.mobile) { |
||||||
|
createMessage.warn(t('sys.login.mobilePlaceholder')); |
||||||
|
return; |
||||||
|
}*/ |
||||||
|
const TIME_COUNT = 60; |
||||||
|
if (!unref(timer)) { |
||||||
|
timeRuning.value = TIME_COUNT; |
||||||
|
showInterval.value = false; |
||||||
|
timer.value = setInterval(() => { |
||||||
|
if (unref(timeRuning) > 0 && unref(timeRuning) <= TIME_COUNT) { |
||||||
|
timeRuning.value = timeRuning.value - 1; |
||||||
|
} else { |
||||||
|
showInterval.value = true; |
||||||
|
clearInterval(unref(timer)); |
||||||
|
timer.value = null; |
||||||
|
} |
||||||
|
}, 1000); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 第三方登录 |
||||||
|
* @param type |
||||||
|
*/ |
||||||
|
function onThirdLogin(type) { |
||||||
|
notification.success({ |
||||||
|
message: '功能待开发中.', |
||||||
|
duration: 3, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 忘记密码 |
||||||
|
*/ |
||||||
|
function forgetHandelClick() { |
||||||
|
type.value = 'forgot'; |
||||||
|
setTimeout(() => { |
||||||
|
forgotRef.value.initForm(); |
||||||
|
}, 300); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回登录页面 |
||||||
|
*/ |
||||||
|
function goBack() { |
||||||
|
activeIndex.value = 'accountLogin'; |
||||||
|
type.value = 'login'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 忘记密码/注册账号回调事件 |
||||||
|
* @param value |
||||||
|
*/ |
||||||
|
function handleSuccess(value) { |
||||||
|
Object.assign(formData, value); |
||||||
|
Object.assign(phoneFormData, { mobile: '', smscode: '' }); |
||||||
|
type.value = 'login'; |
||||||
|
activeIndex.value = 'accountLogin'; |
||||||
|
handleChangeCheckCode(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 注册 |
||||||
|
*/ |
||||||
|
function registerHandleClick() { |
||||||
|
type.value = 'register'; |
||||||
|
setTimeout(() => { |
||||||
|
registerRef.value.initForm(); |
||||||
|
}, 300); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 二维码登录 |
||||||
|
*/ |
||||||
|
function codeHandleClick() { |
||||||
|
type.value = 'codeLogin'; |
||||||
|
setTimeout(() => { |
||||||
|
codeRef.value.initFrom(); |
||||||
|
}, 300); |
||||||
|
} |
||||||
|
|
||||||
|
onMounted(() => { |
||||||
|
//加载验证码 |
||||||
|
handleChangeCheckCode(); |
||||||
|
}); |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="less" scoped> |
||||||
|
|
||||||
|
.login-background-img { |
||||||
|
background-image: url(../icon/login-bg.png); |
||||||
|
background-size: cover; |
||||||
|
background-position: top center; |
||||||
|
background-repeat: no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
.aui-logo { |
||||||
|
width: 180px; |
||||||
|
height: 80px; |
||||||
|
position: absolute; |
||||||
|
top: 2%; |
||||||
|
left: 8%; |
||||||
|
z-index: 4; |
||||||
|
} |
||||||
|
|
||||||
|
:deep(.ant-input:focus) { |
||||||
|
box-shadow: none; |
||||||
|
} |
||||||
|
.aui-get-code { |
||||||
|
float: right; |
||||||
|
position: relative; |
||||||
|
z-index: 3; |
||||||
|
background: #ffffff; |
||||||
|
color: #1573e9; |
||||||
|
border-radius: 100px; |
||||||
|
padding: 5px 16px; |
||||||
|
margin: 7px; |
||||||
|
border: 1px solid #1573e9; |
||||||
|
top: 12px; |
||||||
|
} |
||||||
|
|
||||||
|
.aui-get-code:hover { |
||||||
|
color: #1573e9; |
||||||
|
} |
||||||
|
|
||||||
|
.code-shape { |
||||||
|
border-color: #dadada !important; |
||||||
|
color: #aaa !important; |
||||||
|
} |
||||||
|
|
||||||
|
.aui-link-login{ |
||||||
|
height: 42px; |
||||||
|
padding: 10px 15px; |
||||||
|
font-size: 14px; |
||||||
|
border-radius: 8px; |
||||||
|
margin-top: 15px; |
||||||
|
margin-bottom: 8px; |
||||||
|
} |
||||||
|
.aui-phone-logo{ |
||||||
|
position: absolute; |
||||||
|
margin-left: 10px; |
||||||
|
width: 60px; |
||||||
|
top:2px; |
||||||
|
z-index: 4; |
||||||
|
} |
||||||
|
.top-3{ |
||||||
|
top: 0.45rem; |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
||||||
|
<style lang="less"> |
||||||
|
@prefix-cls: ~'@{namespace}-mini-login'; |
||||||
|
@dark-bg: #293146; |
||||||
|
|
||||||
|
html[data-theme='dark'] { |
||||||
|
.@{prefix-cls} { |
||||||
|
background-color: @dark-bg !important; |
||||||
|
background-image: none; |
||||||
|
|
||||||
|
&::before { |
||||||
|
background-image: url(/@/assets/images/login-bg-dark.svg); |
||||||
|
} |
||||||
|
.aui-inputClear{ |
||||||
|
background-color: #232a3b !important; |
||||||
|
} |
||||||
|
.ant-input, |
||||||
|
.ant-input-password { |
||||||
|
background-color: #232a3b !important; |
||||||
|
} |
||||||
|
|
||||||
|
.ant-btn:not(.ant-btn-link):not(.ant-btn-primary) { |
||||||
|
border: 1px solid #4a5569 !important; |
||||||
|
} |
||||||
|
|
||||||
|
&-form { |
||||||
|
background: @dark-bg !important; |
||||||
|
} |
||||||
|
|
||||||
|
.app-iconify { |
||||||
|
color: #fff !important; |
||||||
|
} |
||||||
|
.aui-inputClear input,.aui-input-line input,.aui-choice{ |
||||||
|
color: #c9d1d9 !important; |
||||||
|
} |
||||||
|
|
||||||
|
.aui-formBox{ |
||||||
|
background-color: @dark-bg !important; |
||||||
|
} |
||||||
|
.aui-third-text span{ |
||||||
|
background-color: @dark-bg !important; |
||||||
|
} |
||||||
|
.aui-form-nav .aui-flex-box{ |
||||||
|
color: #c9d1d9 !important; |
||||||
|
} |
||||||
|
|
||||||
|
.aui-formButton .aui-linek-code{ |
||||||
|
background: @dark-bg !important; |
||||||
|
color: white !important; |
||||||
|
} |
||||||
|
.aui-code-line{ |
||||||
|
border-left: none !important; |
||||||
|
} |
||||||
|
.ant-checkbox-inner,.aui-success h3{ |
||||||
|
border-color: #c9d1d9; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
input.fix-auto-fill, |
||||||
|
.fix-auto-fill input { |
||||||
|
-webkit-text-fill-color: #c9d1d9 !important; |
||||||
|
box-shadow: inherit !important; |
||||||
|
} |
||||||
|
|
||||||
|
&-sign-in-way { |
||||||
|
.anticon { |
||||||
|
font-size: 22px !important; |
||||||
|
color: #888 !important; |
||||||
|
cursor: pointer !important; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
color: @primary-color !important; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.ant-divider-inner-text { |
||||||
|
font-size: 12px !important; |
||||||
|
color: @text-color-secondary !important; |
||||||
|
} |
||||||
|
.aui-third-login a{ |
||||||
|
background: transparent; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
Loading…
Reference in new issue