321 lines
12 KiB
Vue
321 lines
12 KiB
Vue
<template>
|
|
<div class="mini-login login-background-img">
|
|
<div v-show="type === 'login'">
|
|
<div class="aui-content">
|
|
<div class="aui-top">
|
|
<div class="aui-title">{{ t('login.loginTitle') }}</div>
|
|
<div class="aui-title-image"></div>
|
|
</div>
|
|
<div class="aui-container">
|
|
<div class="aui-form">
|
|
<div class="aui-formBox">
|
|
<div class="aui-formWell">
|
|
<div class="form-title">{{ t('login.formTitle') }}</div>
|
|
<div class="aui-form-box" style="height: 180px">
|
|
<a-form ref="loginRef" :model="formData" @keyup.enter.native="loginHandleClick">
|
|
<div class="aui-account">
|
|
<div class="aui-inputClear">
|
|
<i class="icon icon-code"></i>
|
|
<a-form-item>
|
|
<a-input
|
|
v-model:value="formData.username"
|
|
:placeholder="t('login.userName')"
|
|
class="fix-auto-fill"
|
|
/>
|
|
</a-form-item>
|
|
</div>
|
|
<div class="aui-inputClear">
|
|
<i class="icon icon-password"></i>
|
|
<a-form-item>
|
|
<a-input
|
|
v-model:value="formData.password"
|
|
:placeholder="t('login.password')"
|
|
class="fix-auto-fill"
|
|
type="password"
|
|
/>
|
|
</a-form-item>
|
|
</div>
|
|
<div class="aui-inputClear">
|
|
<i class="icon icon-code"></i>
|
|
<a-form-item>
|
|
<a-input
|
|
v-model:value="formData.inputCode"
|
|
:placeholder="t('login.inputCode')"
|
|
class="fix-auto-fill"
|
|
type="text"
|
|
/>
|
|
</a-form-item>
|
|
<div class="aui-code">
|
|
<img
|
|
v-if="randCodeData.requestCodeSuccess"
|
|
:src="randCodeData.randCodeImage"
|
|
@click="handleChangeCheckCode"
|
|
/>
|
|
<img
|
|
v-else
|
|
:src="codeImg"
|
|
style="margin-top: 2px; max-width: initial"
|
|
@click="handleChangeCheckCode"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="aui-flex remember">
|
|
<div class="aui-flex-box">
|
|
<div class="aui-choice">
|
|
<a-input v-model:value="rememberMe" class="fix-auto-fill" type="checkbox" />
|
|
<span class="aui-check">{{ t('login.rememberMe') }}</span>
|
|
</div>
|
|
</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('login.loginButton') }}
|
|
</a-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script lang="ts" name="login-mini" setup>
|
|
import { getCodeInfo } from '/@/api/user';
|
|
import { onMounted, reactive, ref, toRaw, watch } from 'vue';
|
|
import codeImg from '/@/assets/images/checkcode.png';
|
|
import { useUserStore } from '/@/store/modules/user';
|
|
import { useMessage } from '/@/hooks/web/useMessage';
|
|
import { t } from '/@/hooks/locales/useLocales.ts';
|
|
import { encipher } from '/@/utils/jsencrypt';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
import { getAuthCache } from '/@/utils/auth.ts';
|
|
import { TOKEN_KEY } from '/@/enum/cacheEnum.ts';
|
|
import { PageEnum, setBaseLogin } from '/@/enum/pageEnum.ts';
|
|
|
|
const router = useRouter();
|
|
const route = useRoute();
|
|
console.log('route', route);
|
|
const prefixCls = 'mini-login';
|
|
const { notification, createMessage } = useMessage();
|
|
const userStore = useUserStore();
|
|
const randCodeData = reactive<any>({
|
|
randCodeImage: '',
|
|
requestCodeSuccess: false,
|
|
checkKey: null,
|
|
});
|
|
const rememberMe = ref<string>('0');
|
|
const type = ref<string>('login');
|
|
//账号登录表单字段
|
|
const formData = reactive<any>({
|
|
inputCode: '',
|
|
username: '',
|
|
password: '',
|
|
});
|
|
const loginRef = ref();
|
|
const loginLoading = ref<boolean>(false);
|
|
defineProps({
|
|
sessionTimeout: {
|
|
type: Boolean,
|
|
},
|
|
});
|
|
|
|
/**
|
|
* 获取验证码
|
|
*/
|
|
function handleChangeCheckCode() {
|
|
formData.inputCode = '';
|
|
randCodeData.checkKey = 1629428467008;
|
|
getCodeInfo(randCodeData.checkKey)
|
|
.then((res) => {
|
|
randCodeData.randCodeImage = res.result;
|
|
randCodeData.requestCodeSuccess = true;
|
|
})
|
|
.catch((e) => {});
|
|
}
|
|
|
|
/**
|
|
* 账号或者手机登录
|
|
*/
|
|
async function loginHandleClick() {
|
|
accountLogin();
|
|
}
|
|
|
|
watch(
|
|
() => formData.password,
|
|
() => {
|
|
formData.password = formData.password.replace(/[\u4e00-\u9fa5]/g, '');
|
|
}
|
|
);
|
|
|
|
async function accountLogin() {
|
|
if (!formData.username) {
|
|
createMessage.warn(t('login.accountPlaceholder'));
|
|
return;
|
|
}
|
|
if (!formData.password) {
|
|
createMessage.warn(t('login.passwordPlaceholder'));
|
|
return;
|
|
}
|
|
if (!formData.inputCode) {
|
|
createMessage.warn(t('login.inputCodePlaceholder'));
|
|
return;
|
|
}
|
|
try {
|
|
loginLoading.value = true;
|
|
const { userInfo } = await userStore.login(
|
|
toRaw({
|
|
password: encipher(formData.password) as string,
|
|
// password: formData.password,
|
|
username: formData.username,
|
|
captcha: formData.inputCode,
|
|
checkKey: randCodeData.checkKey,
|
|
mode: 'none', //不要默认的错误提示
|
|
})
|
|
);
|
|
|
|
if (userInfo) {
|
|
notification.success({
|
|
message: t('login.loginSuccessTitle'),
|
|
description: `${t('login.loginSuccessDesc')}: ${userInfo.realname}`,
|
|
duration: 3,
|
|
});
|
|
|
|
let path = route.path == PageEnum.BASE_LOGIN_YINCHUAN ? PageEnum.YINCHUAN_HOME : PageEnum.BASE_HOME;
|
|
setBaseLogin(route.path);
|
|
router.replace({ path: path });
|
|
}
|
|
} catch (error) {
|
|
notification.error({
|
|
message: t('api.errorTip'),
|
|
description: error.message || t('login.networkExceptionMsg'),
|
|
duration: 3,
|
|
});
|
|
handleChangeCheckCode();
|
|
} finally {
|
|
loginLoading.value = false;
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
//加载验证码
|
|
handleChangeCheckCode();
|
|
});
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
@import '/@/assets/loginmini/style/home.less';
|
|
@import '/@/assets/loginmini/style/base.less';
|
|
</style>
|
|
|
|
<style lang="less">
|
|
@prefix-cls: ~'mini-login';
|
|
@dark-bg: #293146;
|
|
@primary-color: #1890ff;
|
|
@text-color-secondary: fade(#000, 45%);
|
|
html[data-theme='dark'] {
|
|
.@{prefix-cls} {
|
|
background-color: @dark-bg !important;
|
|
background-image: none;
|
|
|
|
&::before {
|
|
background-image: url(/@/assets/svg/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;
|
|
}
|
|
}
|
|
|
|
.ant-btn-primary:not(.ant-btn-background-ghost):not([disabled]) {
|
|
color: #fff;
|
|
}
|
|
</style>
|