Files
xj-screen/src/views/sys/login.vue
T
2024-05-17 16:10:51 +08:00

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>