|
|
@@ -2,37 +2,30 @@
|
|
|
<div class="login" ref="loginRef">
|
|
|
<a-carousel autoplay class="carousel" dotsClass="dots" lazyLoad :autoplaySpeed="60000" adaptiveHeight>
|
|
|
<div>
|
|
|
- <img :src="loginBg1" class="img" alt="">
|
|
|
+ <img :src="loginBg1" class="img" alt="" />
|
|
|
</div>
|
|
|
<div>
|
|
|
- <img :src="loginBg2" class="img" alt="">
|
|
|
+ <img :src="loginBg2" class="img" alt="" />
|
|
|
</div>
|
|
|
</a-carousel>
|
|
|
<div class="login-box">
|
|
|
<div class="login-left">
|
|
|
<div class="login-left-box">
|
|
|
- <img class="logo" :src="logo" alt="">
|
|
|
- <div class="slogan">合作共赢 · 品质第一 </div>
|
|
|
- <div class="type">
|
|
|
- 研发设计/生产制造/工程管理/投资运营
|
|
|
- </div>
|
|
|
+ <!-- <img class="logo" :src="logo" alt="" /> -->
|
|
|
+ <div class="slogan">合作共赢 · 品质第一</div>
|
|
|
+ <div class="type">研发设计/生产制造/工程管理/投资运营</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="login-right">
|
|
|
<div class="login-right-box">
|
|
|
- <div class="login-right-title">
|
|
|
- <span class="welcome">欢迎登录</span>润扬内控平台
|
|
|
- </div>
|
|
|
+ <div class="login-right-title"><span class="welcome">欢迎登录</span>无限畅联平台</div>
|
|
|
<div class="login-right-form">
|
|
|
-
|
|
|
<a-tabs v-model:activeKey="activeKey" class="tabs">
|
|
|
<a-tab-pane key="0" tab="账号登录" force-render>
|
|
|
<div class="login-form" v-if="activeKey === '0'">
|
|
|
<a-form ref="formRef" :model="loginForm" :rules="rules">
|
|
|
<a-form-item name="loginName" class="form-item">
|
|
|
- <div class="label">
|
|
|
- 账户
|
|
|
- </div>
|
|
|
+ <div class="label">账户</div>
|
|
|
<a-input class="input" v-model:value.trim="loginForm.loginName" placeholder="请输入用户名">
|
|
|
<template #prefix>
|
|
|
<UserOutlined />
|
|
|
@@ -41,28 +34,33 @@
|
|
|
</a-form-item>
|
|
|
<a-form-item name="emailCode" class="form-item" v-if="emailCodeShowFlag" label="邮箱验证码">
|
|
|
<a-input-group compact>
|
|
|
- <a-input style="width: calc(100% - 110px)" v-model:value="loginForm.emailCode" autocomplete="on"
|
|
|
- placeholder="请输入邮箱验证码" />
|
|
|
+ <a-input
|
|
|
+ style="width: calc(100% - 110px)"
|
|
|
+ v-model:value="loginForm.emailCode"
|
|
|
+ autocomplete="on"
|
|
|
+ placeholder="请输入邮箱验证码"
|
|
|
+ />
|
|
|
<a-button @click="sendSmsCode" type="primary" :disabled="emailCodeButtonDisabled">
|
|
|
{{ emailCodeTips }}
|
|
|
</a-button>
|
|
|
</a-input-group>
|
|
|
</a-form-item>
|
|
|
<a-form-item name="password" class="form-item">
|
|
|
- <div class="label">
|
|
|
- 密码
|
|
|
- </div>
|
|
|
- <a-input-password class="input" v-model:value="loginForm.password" autocomplete="on"
|
|
|
- :type="showPassword ? 'text' : 'password'" placeholder="请输入密码">
|
|
|
+ <div class="label">密码</div>
|
|
|
+ <a-input-password
|
|
|
+ class="input"
|
|
|
+ v-model:value="loginForm.password"
|
|
|
+ autocomplete="on"
|
|
|
+ :type="showPassword ? 'text' : 'password'"
|
|
|
+ placeholder="请输入密码"
|
|
|
+ >
|
|
|
<template #prefix>
|
|
|
<SafetyOutlined />
|
|
|
</template>
|
|
|
</a-input-password>
|
|
|
</a-form-item>
|
|
|
<a-form-item name="captchaCode" class="form-item">
|
|
|
- <div class="label">
|
|
|
- 验证码
|
|
|
- </div>
|
|
|
+ <div class="label">验证码</div>
|
|
|
<div class="captchaCode-img">
|
|
|
<a-input v-model:value.trim="loginForm.captchaCode" class="input" placeholder="请输入验证码">
|
|
|
<template #prefix>
|
|
|
@@ -87,7 +85,7 @@
|
|
|
</a-tab-pane>
|
|
|
<a-tab-pane key="1" tab="扫码登录" force-render>
|
|
|
<div class="qrcode-login" v-if="activeKey === '1'" :class="ratio > 0.985 ? 'margin-top' : 'flex-center'">
|
|
|
- <img class="img" :src="tip" alt="" v-if="ratio > 0.985">
|
|
|
+ <img class="img" :src="tip" alt="" v-if="ratio > 0.985" />
|
|
|
<div class="code" :class="{ 'absolute-right': ratio > 0.985 }">
|
|
|
<ddLogin />
|
|
|
<!-- <a-qrcode value="https://www.antdv.com/" :size="250" /> -->
|
|
|
@@ -95,7 +93,7 @@
|
|
|
</div>
|
|
|
</a-tab-pane>
|
|
|
</a-tabs>
|
|
|
- <div class="login-right-bottom">如有疑问请致电:营销热线0532-88988868</div>
|
|
|
+ <div class="login-right-bottom">如有疑问请致电:营销热线0532-xxxxxxxx</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -104,501 +102,497 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { message } from 'ant-design-vue';
|
|
|
-import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
|
|
-import { useRouter } from 'vue-router';
|
|
|
-import { loginApi } from '/@/api/system/login-api';
|
|
|
-import { SmartLoading } from '/@/components/framework/smart-loading';
|
|
|
-import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
|
|
|
-import { useUserStore } from '/@/store/modules/system/user';
|
|
|
-import loginBg2 from '/@/assets/images/login/login_bg2.png'
|
|
|
-import loginBg1 from '/@/assets/images/login/login_bg1.png'
|
|
|
-import tip from '/@/assets/images/login/tooltip.png'
|
|
|
-import logo from '/@/assets/images/login/logo1.png'
|
|
|
-import { buildRoutes } from '/@/router/index';
|
|
|
-import { smartSentry } from '/@/lib/smart-sentry';
|
|
|
-import { encryptData, decryptData } from '/@/lib/encrypt';
|
|
|
-import { localSave, localRemove, localRead } from '/@/utils/local-util.js';
|
|
|
-import LocalStorageKeyConst from '/@/constants/local-storage-key-const.js';
|
|
|
-import { Form } from 'ant-design-vue';
|
|
|
-import useBsDict from "/@/utils/dict.js";
|
|
|
-import ddLogin from '/@/components/support/dd-login/index.vue'
|
|
|
-
|
|
|
-const activeKey = ref('0')
|
|
|
-
|
|
|
-//--------------------- 登录表单 ---------------------------------
|
|
|
-
|
|
|
-const loginForm = reactive({
|
|
|
- loginName: 'admin',
|
|
|
- password: '',
|
|
|
- captchaCode: '',
|
|
|
- captchaUuid: '',
|
|
|
- loginDevice: LOGIN_DEVICE_ENUM.PC.value,
|
|
|
-});
|
|
|
-const rules = {
|
|
|
- loginName: [{ required: true, message: '用户名不能为空' }],
|
|
|
- password: [{ required: true, message: '密码不能为空' }],
|
|
|
- captchaCode: [{ required: true, message: '验证码不能为空' }],
|
|
|
-};
|
|
|
-
|
|
|
-const showPassword = ref(false);
|
|
|
-const router = useRouter();
|
|
|
-const formRef = ref();
|
|
|
-// const rememberPwd = ref(false);
|
|
|
-
|
|
|
-// function readLocalRememberMe() {
|
|
|
-// const rememberMe = JSON.parse(localRead('rememberMe') || null);
|
|
|
-// if (rememberMe) {
|
|
|
-// rememberMe.password = rememberMe.password ? decryptData(rememberMe.password) : '';
|
|
|
-// loginForm.loginName = rememberMe.loginName;
|
|
|
-// loginForm.password = rememberMe.password;
|
|
|
-// rememberPwd.value = true;
|
|
|
-// // console.log('readLocalRememberMe', rememberMe);
|
|
|
-// }
|
|
|
-// }
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- // readLocalRememberMe();
|
|
|
- document.onkeyup = (e) => {
|
|
|
- if (e.keyCode === 13) {
|
|
|
- onLogin();
|
|
|
- }
|
|
|
+ import { message } from 'ant-design-vue';
|
|
|
+ import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
|
|
+ import { useRouter } from 'vue-router';
|
|
|
+ import { loginApi } from '/@/api/system/login-api';
|
|
|
+ import { SmartLoading } from '/@/components/framework/smart-loading';
|
|
|
+ import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
|
|
|
+ import { useUserStore } from '/@/store/modules/system/user';
|
|
|
+ import loginBg2 from '/@/assets/images/login/login_bg2.png';
|
|
|
+ import loginBg1 from '/@/assets/images/login/login_bg1.png';
|
|
|
+ import tip from '/@/assets/images/login/tooltip.png';
|
|
|
+ // import logo from '/@/assets/images/login/logo1.png';
|
|
|
+ import { buildRoutes } from '/@/router/index';
|
|
|
+ import { smartSentry } from '/@/lib/smart-sentry';
|
|
|
+ import { encryptData, decryptData } from '/@/lib/encrypt';
|
|
|
+ import { localSave, localRemove, localRead } from '/@/utils/local-util.js';
|
|
|
+ import LocalStorageKeyConst from '/@/constants/local-storage-key-const.js';
|
|
|
+ import { Form } from 'ant-design-vue';
|
|
|
+ import useBsDict from '/@/utils/dict.js';
|
|
|
+ import ddLogin from '/@/components/support/dd-login/index.vue';
|
|
|
+
|
|
|
+ const activeKey = ref('0');
|
|
|
+
|
|
|
+ //--------------------- 登录表单 ---------------------------------
|
|
|
+
|
|
|
+ const loginForm = reactive({
|
|
|
+ loginName: 'admin',
|
|
|
+ password: '',
|
|
|
+ captchaCode: '',
|
|
|
+ captchaUuid: '',
|
|
|
+ loginDevice: LOGIN_DEVICE_ENUM.PC.value,
|
|
|
+ });
|
|
|
+ const rules = {
|
|
|
+ loginName: [{ required: true, message: '用户名不能为空' }],
|
|
|
+ password: [{ required: true, message: '密码不能为空' }],
|
|
|
+ captchaCode: [{ required: true, message: '验证码不能为空' }],
|
|
|
};
|
|
|
-});
|
|
|
-
|
|
|
-onUnmounted(() => {
|
|
|
- document.onkeyup = null;
|
|
|
-});
|
|
|
|
|
|
-//登录
|
|
|
-async function onLogin() {
|
|
|
- formRef.value.validate().then(async () => {
|
|
|
- try {
|
|
|
- SmartLoading.show();
|
|
|
- // 密码加密
|
|
|
- let encryptPasswordForm = Object.assign({}, loginForm, {
|
|
|
- password: encryptData(loginForm.password),
|
|
|
- });
|
|
|
- const res = await loginApi.login(encryptPasswordForm);
|
|
|
- stopRefreshCaptchaInterval();
|
|
|
-
|
|
|
- // if (rememberPwd.value === true) {
|
|
|
- // localSave('rememberMe', JSON.stringify({ loginName: encryptPasswordForm.loginName, password: encryptPasswordForm.password }));
|
|
|
- // } else {
|
|
|
- // localRemove('rememberMe');
|
|
|
- // }
|
|
|
-
|
|
|
- localSave(LocalStorageKeyConst.USER_TOKEN, res.data.token ? res.data.token : '');
|
|
|
- message.success('登录成功');
|
|
|
-
|
|
|
- // 刷新本地缓存
|
|
|
- await useBsDict.refresh();
|
|
|
- //更新用户信息到pinia
|
|
|
- useUserStore().setUserLoginInfo(res.data);
|
|
|
- localSave('loginFrom', '0');
|
|
|
- //构建系统的路由
|
|
|
- buildRoutes();
|
|
|
- router.push('/home');
|
|
|
- } catch (e) {
|
|
|
- if (e.data && e.data.code !== 0) {
|
|
|
- loginForm.captchaCode = '';
|
|
|
- getCaptcha();
|
|
|
+ const showPassword = ref(false);
|
|
|
+ const router = useRouter();
|
|
|
+ const formRef = ref();
|
|
|
+ // const rememberPwd = ref(false);
|
|
|
+
|
|
|
+ // function readLocalRememberMe() {
|
|
|
+ // const rememberMe = JSON.parse(localRead('rememberMe') || null);
|
|
|
+ // if (rememberMe) {
|
|
|
+ // rememberMe.password = rememberMe.password ? decryptData(rememberMe.password) : '';
|
|
|
+ // loginForm.loginName = rememberMe.loginName;
|
|
|
+ // loginForm.password = rememberMe.password;
|
|
|
+ // rememberPwd.value = true;
|
|
|
+ // // console.log('readLocalRememberMe', rememberMe);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ // readLocalRememberMe();
|
|
|
+ document.onkeyup = (e) => {
|
|
|
+ if (e.keyCode === 13) {
|
|
|
+ onLogin();
|
|
|
}
|
|
|
- smartSentry.captureError(e);
|
|
|
- } finally {
|
|
|
- SmartLoading.hide();
|
|
|
- }
|
|
|
+ };
|
|
|
});
|
|
|
-}
|
|
|
-
|
|
|
-//--------------------- 验证码 ---------------------------------
|
|
|
-
|
|
|
-const captchaBase64Image = ref('');
|
|
|
-async function getCaptcha() {
|
|
|
- try {
|
|
|
- let captchaResult = await loginApi.getCaptcha();
|
|
|
- captchaBase64Image.value = captchaResult.data.captchaBase64Image;
|
|
|
- loginForm.captchaUuid = captchaResult.data.captchaUuid;
|
|
|
- beginRefreshCaptchaInterval(captchaResult.data.expireSeconds);
|
|
|
- } catch (e) {
|
|
|
- console.log(e);
|
|
|
- }
|
|
|
-}
|
|
|
|
|
|
-let refreshCaptchaInterval = null;
|
|
|
-function beginRefreshCaptchaInterval(expireSeconds) {
|
|
|
- if (refreshCaptchaInterval === null) {
|
|
|
- refreshCaptchaInterval = setInterval(getCaptcha, (expireSeconds - 5) * 1000);
|
|
|
- }
|
|
|
-}
|
|
|
+ onUnmounted(() => {
|
|
|
+ document.onkeyup = null;
|
|
|
+ });
|
|
|
|
|
|
-function stopRefreshCaptchaInterval() {
|
|
|
- if (refreshCaptchaInterval != null) {
|
|
|
- clearInterval(refreshCaptchaInterval);
|
|
|
- refreshCaptchaInterval = null;
|
|
|
+ //登录
|
|
|
+ async function onLogin() {
|
|
|
+ formRef.value.validate().then(async () => {
|
|
|
+ try {
|
|
|
+ SmartLoading.show();
|
|
|
+ // 密码加密
|
|
|
+ let encryptPasswordForm = Object.assign({}, loginForm, {
|
|
|
+ password: encryptData(loginForm.password),
|
|
|
+ });
|
|
|
+ const res = await loginApi.login(encryptPasswordForm);
|
|
|
+ stopRefreshCaptchaInterval();
|
|
|
+
|
|
|
+ // if (rememberPwd.value === true) {
|
|
|
+ // localSave('rememberMe', JSON.stringify({ loginName: encryptPasswordForm.loginName, password: encryptPasswordForm.password }));
|
|
|
+ // } else {
|
|
|
+ // localRemove('rememberMe');
|
|
|
+ // }
|
|
|
+
|
|
|
+ localSave(LocalStorageKeyConst.USER_TOKEN, res.data.token ? res.data.token : '');
|
|
|
+ message.success('登录成功');
|
|
|
+
|
|
|
+ // 刷新本地缓存
|
|
|
+ await useBsDict.refresh();
|
|
|
+ //更新用户信息到pinia
|
|
|
+ useUserStore().setUserLoginInfo(res.data);
|
|
|
+ localSave('loginFrom', '0');
|
|
|
+ //构建系统的路由
|
|
|
+ buildRoutes();
|
|
|
+ router.push('/home');
|
|
|
+ } catch (e) {
|
|
|
+ if (e.data && e.data.code !== 0) {
|
|
|
+ loginForm.captchaCode = '';
|
|
|
+ getCaptcha();
|
|
|
+ }
|
|
|
+ smartSentry.captureError(e);
|
|
|
+ } finally {
|
|
|
+ SmartLoading.hide();
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- getCaptcha();
|
|
|
- getTwoFactorLoginFlag();
|
|
|
-});
|
|
|
-//--------------------- 邮箱验证码 ---------------------------------
|
|
|
-const emailCodeShowFlag = ref(false);
|
|
|
-let emailCodeTips = ref('获取邮箱验证码');
|
|
|
-let emailCodeButtonDisabled = ref(false);
|
|
|
-// 定时器
|
|
|
-let countDownTimer = null;
|
|
|
-// 开始倒计时
|
|
|
-function runCountDown() {
|
|
|
- emailCodeButtonDisabled.value = true;
|
|
|
- let countDown = 60;
|
|
|
- emailCodeTips.value = `${countDown}秒后重新获取`;
|
|
|
- countDownTimer = setInterval(() => {
|
|
|
- if (countDown > 1) {
|
|
|
- countDown--;
|
|
|
- emailCodeTips.value = `${countDown}秒后重新获取`;
|
|
|
- } else {
|
|
|
- clearInterval(countDownTimer);
|
|
|
- emailCodeButtonDisabled.value = false;
|
|
|
- emailCodeTips.value = '获取验证码';
|
|
|
+
|
|
|
+ //--------------------- 验证码 ---------------------------------
|
|
|
+
|
|
|
+ const captchaBase64Image = ref('');
|
|
|
+ async function getCaptcha() {
|
|
|
+ try {
|
|
|
+ let captchaResult = await loginApi.getCaptcha();
|
|
|
+ captchaBase64Image.value = captchaResult.data.captchaBase64Image;
|
|
|
+ loginForm.captchaUuid = captchaResult.data.captchaUuid;
|
|
|
+ beginRefreshCaptchaInterval(captchaResult.data.expireSeconds);
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e);
|
|
|
}
|
|
|
- }, 1000);
|
|
|
-}
|
|
|
-// 获取双因子登录标识
|
|
|
-async function getTwoFactorLoginFlag() {
|
|
|
- try {
|
|
|
- let result = await loginApi.getTwoFactorLoginFlag();
|
|
|
- emailCodeShowFlag.value = result.data;
|
|
|
- } catch (e) {
|
|
|
- smartSentry.captureError(e);
|
|
|
}
|
|
|
-}
|
|
|
-// 发送邮箱验证码
|
|
|
-async function sendSmsCode() {
|
|
|
- try {
|
|
|
- SmartLoading.show();
|
|
|
- let result = await loginApi.sendLoginEmailCode(loginForm.loginName);
|
|
|
- message.success('验证码发送成功!请登录邮箱查看验证码~');
|
|
|
- runCountDown();
|
|
|
- } catch (e) {
|
|
|
- smartSentry.captureError(e);
|
|
|
- } finally {
|
|
|
- SmartLoading.hide();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// ---------------- 适配屏幕缩放 ----------------
|
|
|
-const loginRef = ref(null);
|
|
|
-const ratio = ref(1);
|
|
|
-
|
|
|
-function reduceRatio() {
|
|
|
- handleResize();
|
|
|
- window.addEventListener('resize', handleResize);
|
|
|
-}
|
|
|
-
|
|
|
-function handleResize() {
|
|
|
- ratio.value = window.innerWidth / 1920;
|
|
|
- loginRef.value.style.setProperty('--fitWidthRatio', ratio.value);
|
|
|
-}
|
|
|
-watch(() => ratio.value, (value) => {
|
|
|
- console.log(value);
|
|
|
-
|
|
|
-})
|
|
|
-onMounted(() => {
|
|
|
- reduceRatio();
|
|
|
-});
|
|
|
-
|
|
|
-onUnmounted(() => {
|
|
|
- window.removeEventListener('resize', handleResize);
|
|
|
-});
|
|
|
-</script>
|
|
|
|
|
|
-<style lang="scss" scoped>
|
|
|
-.login {
|
|
|
- height: 100vh;
|
|
|
- width: 100vw;
|
|
|
- // background-color: #e39f77;
|
|
|
-
|
|
|
- .carousel {
|
|
|
- height: 100%;
|
|
|
- position: absolute;
|
|
|
- width: 100%;
|
|
|
- left: 0;
|
|
|
- top: 0;
|
|
|
- z-index: 0;
|
|
|
-
|
|
|
- .img {
|
|
|
- height: 100vh;
|
|
|
- width: 100vw;
|
|
|
+ let refreshCaptchaInterval = null;
|
|
|
+ function beginRefreshCaptchaInterval(expireSeconds) {
|
|
|
+ if (refreshCaptchaInterval === null) {
|
|
|
+ refreshCaptchaInterval = setInterval(getCaptcha, (expireSeconds - 5) * 1000);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- :deep(.dots) {
|
|
|
- width: 65%;
|
|
|
- align-items: center;
|
|
|
+ function stopRefreshCaptchaInterval() {
|
|
|
+ if (refreshCaptchaInterval != null) {
|
|
|
+ clearInterval(refreshCaptchaInterval);
|
|
|
+ refreshCaptchaInterval = null;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- :deep(.dots li) {
|
|
|
- height: calc(var(--fitWidthRatio) * 20px);
|
|
|
- width: calc(var(--fitWidthRatio) * 20px);
|
|
|
+ onMounted(() => {
|
|
|
+ getCaptcha();
|
|
|
+ getTwoFactorLoginFlag();
|
|
|
+ });
|
|
|
+ //--------------------- 邮箱验证码 ---------------------------------
|
|
|
+ const emailCodeShowFlag = ref(false);
|
|
|
+ let emailCodeTips = ref('获取邮箱验证码');
|
|
|
+ let emailCodeButtonDisabled = ref(false);
|
|
|
+ // 定时器
|
|
|
+ let countDownTimer = null;
|
|
|
+ // 开始倒计时
|
|
|
+ function runCountDown() {
|
|
|
+ emailCodeButtonDisabled.value = true;
|
|
|
+ let countDown = 60;
|
|
|
+ emailCodeTips.value = `${countDown}秒后重新获取`;
|
|
|
+ countDownTimer = setInterval(() => {
|
|
|
+ if (countDown > 1) {
|
|
|
+ countDown--;
|
|
|
+ emailCodeTips.value = `${countDown}秒后重新获取`;
|
|
|
+ } else {
|
|
|
+ clearInterval(countDownTimer);
|
|
|
+ emailCodeButtonDisabled.value = false;
|
|
|
+ emailCodeTips.value = '获取验证码';
|
|
|
+ }
|
|
|
+ }, 1000);
|
|
|
+ }
|
|
|
+ // 获取双因子登录标识
|
|
|
+ async function getTwoFactorLoginFlag() {
|
|
|
+ try {
|
|
|
+ let result = await loginApi.getTwoFactorLoginFlag();
|
|
|
+ emailCodeShowFlag.value = result.data;
|
|
|
+ } catch (e) {
|
|
|
+ smartSentry.captureError(e);
|
|
|
}
|
|
|
-
|
|
|
- :deep(.dots :not(.slick-active) button) {
|
|
|
- height: 100%;
|
|
|
- border-radius: calc(var(--fitWidthRatio) * 20px);
|
|
|
+ }
|
|
|
+ // 发送邮箱验证码
|
|
|
+ async function sendSmsCode() {
|
|
|
+ try {
|
|
|
+ SmartLoading.show();
|
|
|
+ let result = await loginApi.sendLoginEmailCode(loginForm.loginName);
|
|
|
+ message.success('验证码发送成功!请登录邮箱查看验证码~');
|
|
|
+ runCountDown();
|
|
|
+ } catch (e) {
|
|
|
+ smartSentry.captureError(e);
|
|
|
+ } finally {
|
|
|
+ SmartLoading.hide();
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- :deep(.dots .slick-active) {
|
|
|
- width: calc(var(--fitWidthRatio) * 52px);
|
|
|
- height: calc(var(--fitWidthRatio) * 16px);
|
|
|
- }
|
|
|
+ // ---------------- 适配屏幕缩放 ----------------
|
|
|
+ const loginRef = ref(null);
|
|
|
+ const ratio = ref(1);
|
|
|
|
|
|
- :deep(.slick-active button) {
|
|
|
- background-color: #2b69f8;
|
|
|
- border-radius: calc(var(--fitWidthRatio) * 20px);
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
+ function reduceRatio() {
|
|
|
+ handleResize();
|
|
|
+ window.addEventListener('resize', handleResize);
|
|
|
+ }
|
|
|
|
|
|
+ function handleResize() {
|
|
|
+ ratio.value = window.innerWidth / 1920;
|
|
|
+ loginRef.value.style.setProperty('--fitWidthRatio', ratio.value);
|
|
|
}
|
|
|
+ watch(
|
|
|
+ () => ratio.value,
|
|
|
+ (value) => {
|
|
|
+ console.log(value);
|
|
|
+ }
|
|
|
+ );
|
|
|
+ onMounted(() => {
|
|
|
+ reduceRatio();
|
|
|
+ });
|
|
|
+
|
|
|
+ onUnmounted(() => {
|
|
|
+ window.removeEventListener('resize', handleResize);
|
|
|
+ });
|
|
|
+</script>
|
|
|
|
|
|
- .login-box {
|
|
|
- display: flex;
|
|
|
- flex-direction: row;
|
|
|
- // align-items: center;
|
|
|
- gap: calc(var(--fitWidthRatio) * 60px);
|
|
|
- height: 100%;
|
|
|
- width: 100%;
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .login {
|
|
|
+ height: 100vh;
|
|
|
+ width: 100vw;
|
|
|
+ // background-color: #e39f77;
|
|
|
|
|
|
- .login-left {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- height: 35%;
|
|
|
- width: 55%;
|
|
|
+ .carousel {
|
|
|
+ height: 100%;
|
|
|
position: absolute;
|
|
|
+ width: 100%;
|
|
|
left: 0;
|
|
|
- top: 20%;
|
|
|
- background: linear-gradient(to right, #FFFFFF, #99999900);
|
|
|
- z-index: 1;
|
|
|
- padding: calc(var(--fitWidthRatio) * 30px);
|
|
|
+ top: 0;
|
|
|
+ z-index: 0;
|
|
|
|
|
|
- .login-left-box {
|
|
|
- // width: 46%;
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: space-evenly;
|
|
|
+ .img {
|
|
|
+ height: 100vh;
|
|
|
+ width: 100vw;
|
|
|
+ }
|
|
|
|
|
|
- .logo {
|
|
|
- height: calc(var(--fitWidthRatio) * 84px);
|
|
|
- width: calc(var(--fitWidthRatio) * 240px);
|
|
|
- }
|
|
|
+ :deep(.dots) {
|
|
|
+ width: 65%;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
|
|
|
- .slogan {
|
|
|
- font-size: calc(var(--fitWidthRatio) * 32px);
|
|
|
- font-weight: 600;
|
|
|
- font-family: 'PingFang SC';
|
|
|
- color: #1C449B;
|
|
|
- }
|
|
|
+ :deep(.dots li) {
|
|
|
+ height: calc(var(--fitWidthRatio) * 20px);
|
|
|
+ width: calc(var(--fitWidthRatio) * 20px);
|
|
|
+ }
|
|
|
|
|
|
- .type {
|
|
|
- width: 31.5%;
|
|
|
- background-color: #1c449b;
|
|
|
- padding: calc(var(--fitWidthRatio) * 8px) calc(var(--fitWidthRatio) * 16px);
|
|
|
- border-radius: calc(var(--fitWidthRatio) * 16px);
|
|
|
- color: #FFFFFF;
|
|
|
- font-size: calc(var(--fitWidthRatio) * 16px);
|
|
|
- font-weight: 600;
|
|
|
- font-family: 'PingFang SC';
|
|
|
- }
|
|
|
+ :deep(.dots :not(.slick-active) button) {
|
|
|
+ height: 100%;
|
|
|
+ border-radius: calc(var(--fitWidthRatio) * 20px);
|
|
|
}
|
|
|
|
|
|
+ :deep(.dots .slick-active) {
|
|
|
+ width: calc(var(--fitWidthRatio) * 52px);
|
|
|
+ height: calc(var(--fitWidthRatio) * 16px);
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.slick-active button) {
|
|
|
+ background-color: #2b69f8;
|
|
|
+ border-radius: calc(var(--fitWidthRatio) * 20px);
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- .login-right {
|
|
|
+ .login-box {
|
|
|
display: flex;
|
|
|
- flex-direction: column;
|
|
|
- align-items: center;
|
|
|
+ flex-direction: row;
|
|
|
+ // align-items: center;
|
|
|
+ gap: calc(var(--fitWidthRatio) * 60px);
|
|
|
height: 100%;
|
|
|
- width: 40%;
|
|
|
- position: absolute;
|
|
|
- right: 0;
|
|
|
- background-color: rgba(255, 255, 255, 0.6);
|
|
|
- border-radius: calc(var(--fitWidthRatio) * 20px) 0 0 calc(var(--fitWidthRatio) * 20px);
|
|
|
- backdrop-filter: blur(10px);
|
|
|
+ width: 100%;
|
|
|
|
|
|
- .login-right-box {
|
|
|
+ .login-left {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- gap: calc(var(--fitWidthRatio) * 20px);
|
|
|
+ height: 35%;
|
|
|
+ width: 55%;
|
|
|
position: absolute;
|
|
|
- top: 12%;
|
|
|
+ left: 0;
|
|
|
+ top: 20%;
|
|
|
+ background: linear-gradient(to right, #ffffff, #99999900);
|
|
|
+ z-index: 1;
|
|
|
+ padding: calc(var(--fitWidthRatio) * 30px);
|
|
|
+
|
|
|
+ .login-left-box {
|
|
|
+ // width: 46%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-evenly;
|
|
|
|
|
|
- .login-right-title {
|
|
|
- font-size: calc(var(--fitWidthRatio) * 24px);
|
|
|
- font-weight: 600;
|
|
|
- width: 100%;
|
|
|
- color: rgba(0, 0, 0, 1);
|
|
|
- font-family: 'PingFang SC';
|
|
|
+ .logo {
|
|
|
+ height: calc(var(--fitWidthRatio) * 84px);
|
|
|
+ width: calc(var(--fitWidthRatio) * 240px);
|
|
|
+ }
|
|
|
|
|
|
- .welcome {
|
|
|
+ .slogan {
|
|
|
font-size: calc(var(--fitWidthRatio) * 32px);
|
|
|
+ font-weight: 600;
|
|
|
+ font-family: 'PingFang SC';
|
|
|
+ color: #1c449b;
|
|
|
+ }
|
|
|
+
|
|
|
+ .type {
|
|
|
+ width: 31.5%;
|
|
|
+ background-color: #1c449b;
|
|
|
+ padding: calc(var(--fitWidthRatio) * 8px) calc(var(--fitWidthRatio) * 16px);
|
|
|
+ border-radius: calc(var(--fitWidthRatio) * 16px);
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: calc(var(--fitWidthRatio) * 16px);
|
|
|
+ font-weight: 600;
|
|
|
+ font-family: 'PingFang SC';
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ .login-right {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ height: 100%;
|
|
|
+ width: 40%;
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ background-color: rgba(255, 255, 255, 0.6);
|
|
|
+ border-radius: calc(var(--fitWidthRatio) * 20px) 0 0 calc(var(--fitWidthRatio) * 20px);
|
|
|
+ backdrop-filter: blur(10px);
|
|
|
|
|
|
- .login-right-form {
|
|
|
- width: 30vw;
|
|
|
- height: 65vh;
|
|
|
- min-height: 386px;
|
|
|
- background-color: #ffffff;
|
|
|
- box-shadow: 0px calc(var(--fitWidthRatio) * 6px) calc(var(--fitWidthRatio) * 4px) 0px rgba(149, 149, 149, 0.25);
|
|
|
- border-radius: calc(var(--fitWidthRatio) * 8px);
|
|
|
+ .login-right-box {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- align-items: center;
|
|
|
+ gap: calc(var(--fitWidthRatio) * 20px);
|
|
|
+ position: absolute;
|
|
|
+ top: 12%;
|
|
|
|
|
|
- .tabs {
|
|
|
- height: 90%;
|
|
|
+ .login-right-title {
|
|
|
+ font-size: calc(var(--fitWidthRatio) * 24px);
|
|
|
+ font-weight: 600;
|
|
|
width: 100%;
|
|
|
- padding: calc(var(--fitWidthRatio) * 32px) calc(var(--fitWidthRatio) * 32px) 0 calc(var(--fitWidthRatio) * 32px);
|
|
|
-
|
|
|
- :deep(.ant-tabs-nav) {
|
|
|
- margin: 0;
|
|
|
- padding: 0 calc(var(--fitWidthRatio) * 24px);
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.ant-tabs-tab) {
|
|
|
- padding: calc(var(--fitWidthRatio) * 4px) 0;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.ant-tabs-tab-active .ant-tabs-tab-btn) {
|
|
|
- color: #000;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.ant-tabs-nav-list :not(.ant-tabs-tab-active) .ant-tabs-tab-btn) {
|
|
|
- color: #9B9B9B;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.ant-tabs-nav::before) {
|
|
|
- border: none;
|
|
|
- }
|
|
|
+ color: rgba(0, 0, 0, 1);
|
|
|
+ font-family: 'PingFang SC';
|
|
|
|
|
|
- :deep(.ant-tabs-tab-btn) {
|
|
|
- font-size: calc(var(--fitWidthRatio) * 24px);
|
|
|
+ .welcome {
|
|
|
+ font-size: calc(var(--fitWidthRatio) * 32px);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- :deep(.ant-tabs-content) {
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
+ .login-right-form {
|
|
|
+ width: 30vw;
|
|
|
+ height: 65vh;
|
|
|
+ min-height: 386px;
|
|
|
+ background-color: #ffffff;
|
|
|
+ box-shadow: 0px calc(var(--fitWidthRatio) * 6px) calc(var(--fitWidthRatio) * 4px) 0px rgba(149, 149, 149, 0.25);
|
|
|
+ border-radius: calc(var(--fitWidthRatio) * 8px);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .tabs {
|
|
|
+ height: 90%;
|
|
|
+ width: 100%;
|
|
|
+ padding: calc(var(--fitWidthRatio) * 32px) calc(var(--fitWidthRatio) * 32px) 0 calc(var(--fitWidthRatio) * 32px);
|
|
|
|
|
|
- .margin-top {
|
|
|
- margin-top: calc(var(--fitWidthRatio) * 50px);
|
|
|
- }
|
|
|
+ :deep(.ant-tabs-nav) {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0 calc(var(--fitWidthRatio) * 24px);
|
|
|
+ }
|
|
|
|
|
|
- .flex-center {
|
|
|
- margin: 0;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- height: 100%;
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
+ :deep(.ant-tabs-tab) {
|
|
|
+ padding: calc(var(--fitWidthRatio) * 4px) 0;
|
|
|
+ }
|
|
|
|
|
|
- .qrcode-login {
|
|
|
+ :deep(.ant-tabs-tab-active .ant-tabs-tab-btn) {
|
|
|
+ color: #000;
|
|
|
+ }
|
|
|
|
|
|
- .img {
|
|
|
- width: calc(var(--fitWidthRatio) * 355px);
|
|
|
- height: calc(var(--fitWidthRatio) * 370px);
|
|
|
- position: absolute;
|
|
|
- z-index: 1;
|
|
|
- right: 0;
|
|
|
+ :deep(.ant-tabs-nav-list :not(.ant-tabs-tab-active) .ant-tabs-tab-btn) {
|
|
|
+ color: #9b9b9b;
|
|
|
}
|
|
|
|
|
|
- .code {
|
|
|
- left: 0;
|
|
|
- top: calc(var(--fitWidthRatio) * 16px);
|
|
|
+ :deep(.ant-tabs-nav::before) {
|
|
|
+ border: none;
|
|
|
}
|
|
|
|
|
|
- .absolute-right {
|
|
|
- position: absolute;
|
|
|
+ :deep(.ant-tabs-tab-btn) {
|
|
|
+ font-size: calc(var(--fitWidthRatio) * 24px);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- .login-form {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- padding: 0 calc(var(--fitWidthRatio) * 32px) 0 calc(var(--fitWidthRatio) * 16px);
|
|
|
-
|
|
|
- .label {
|
|
|
- font-size: calc(var(--fitWidthRatio) * 16px);
|
|
|
- font-family: 'PingFang SC';
|
|
|
- font-weight: 500;
|
|
|
- margin-top: calc(var(--fitWidthRatio) * 16px);
|
|
|
- margin-bottom: calc(var(--fitWidthRatio) * 8px);
|
|
|
+ :deep(.ant-tabs-content) {
|
|
|
+ height: 100%;
|
|
|
}
|
|
|
|
|
|
- .input {
|
|
|
- height: calc(var(--fitWidthRatio) * 44px);
|
|
|
- width: 100%;
|
|
|
- font-size: calc(var(--fitWidthRatio) * 16px);
|
|
|
- border: 1px solid rgba(238, 238, 238, 1);
|
|
|
- box-shadow: 0px calc(var(--fitWidthRatio) * 4px) calc(var(--fitWidthRatio) * 4px) 0px rgba(214, 214, 214, 0.25);
|
|
|
+ .margin-top {
|
|
|
+ margin-top: calc(var(--fitWidthRatio) * 50px);
|
|
|
}
|
|
|
|
|
|
- .form-item {
|
|
|
+ .flex-center {
|
|
|
margin: 0;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ height: 100%;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
|
|
|
- .form-btn {
|
|
|
- width: 100%;
|
|
|
- height: calc(var(--fitWidthRatio) * 50px);
|
|
|
- margin-top: calc(var(--fitWidthRatio) * 24px);
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- .btn {
|
|
|
- height: 100%;
|
|
|
- width:calc(var(--fitWidthRatio) * 410px) ;
|
|
|
- font-size: calc(var(--fitWidthRatio) * 16px);
|
|
|
+ .qrcode-login {
|
|
|
+ .img {
|
|
|
+ width: calc(var(--fitWidthRatio) * 355px);
|
|
|
+ height: calc(var(--fitWidthRatio) * 370px);
|
|
|
+ position: absolute;
|
|
|
+ z-index: 1;
|
|
|
+ right: 0;
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ .code {
|
|
|
+ left: 0;
|
|
|
+ top: calc(var(--fitWidthRatio) * 16px);
|
|
|
}
|
|
|
|
|
|
- .img {
|
|
|
- width: calc(var(--fitWidthRatio) * 124px);
|
|
|
- height: calc(var(--fitWidthRatio) * 34px);
|
|
|
- border-radius: calc(var(--fitWidthRatio) * 8px);
|
|
|
+ .absolute-right {
|
|
|
+ position: absolute;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- :deep(.ant-form) {
|
|
|
+ .login-form {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
display: flex;
|
|
|
- flex-direction: column;
|
|
|
justify-content: center;
|
|
|
- }
|
|
|
+ align-items: center;
|
|
|
+ padding: 0 calc(var(--fitWidthRatio) * 32px) 0 calc(var(--fitWidthRatio) * 16px);
|
|
|
+
|
|
|
+ .label {
|
|
|
+ font-size: calc(var(--fitWidthRatio) * 16px);
|
|
|
+ font-family: 'PingFang SC';
|
|
|
+ font-weight: 500;
|
|
|
+ margin-top: calc(var(--fitWidthRatio) * 16px);
|
|
|
+ margin-bottom: calc(var(--fitWidthRatio) * 8px);
|
|
|
+ }
|
|
|
+
|
|
|
+ .input {
|
|
|
+ height: calc(var(--fitWidthRatio) * 44px);
|
|
|
+ width: 100%;
|
|
|
+ font-size: calc(var(--fitWidthRatio) * 16px);
|
|
|
+ border: 1px solid rgba(238, 238, 238, 1);
|
|
|
+ box-shadow: 0px calc(var(--fitWidthRatio) * 4px) calc(var(--fitWidthRatio) * 4px) 0px rgba(214, 214, 214, 0.25);
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-item {
|
|
|
+ margin: 0;
|
|
|
+
|
|
|
+ .form-btn {
|
|
|
+ width: 100%;
|
|
|
+ height: calc(var(--fitWidthRatio) * 50px);
|
|
|
+ margin-top: calc(var(--fitWidthRatio) * 24px);
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ .btn {
|
|
|
+ height: 100%;
|
|
|
+ width: calc(var(--fitWidthRatio) * 410px);
|
|
|
+ font-size: calc(var(--fitWidthRatio) * 16px);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .img {
|
|
|
+ width: calc(var(--fitWidthRatio) * 124px);
|
|
|
+ height: calc(var(--fitWidthRatio) * 34px);
|
|
|
+ border-radius: calc(var(--fitWidthRatio) * 8px);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.ant-form) {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
|
|
|
- :deep(.ant-form-item) {
|
|
|
- margin-left: calc(var(--fitWidthRatio) * 20px);
|
|
|
+ :deep(.ant-form-item) {
|
|
|
+ margin-left: calc(var(--fitWidthRatio) * 20px);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- .login-right-bottom {
|
|
|
- width: 100%;
|
|
|
- height: 10%;
|
|
|
- text-align: center;
|
|
|
- font-size: calc(var(--fitWidthRatio) * 16px);
|
|
|
- padding: calc(var(--fitWidthRatio) * 16px);
|
|
|
- border-top: 1px dotted #DEDEDE;
|
|
|
- color: #EF2F22;
|
|
|
+ .login-right-bottom {
|
|
|
+ width: 100%;
|
|
|
+ height: 10%;
|
|
|
+ text-align: center;
|
|
|
+ font-size: calc(var(--fitWidthRatio) * 16px);
|
|
|
+ padding: calc(var(--fitWidthRatio) * 16px);
|
|
|
+ border-top: 1px dotted #dedede;
|
|
|
+ color: #ef2f22;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
</style>
|