Files
xj-screen/src/views/sys/login.vue
T
2024-09-23 16:43:57 +08:00

405 lines
16 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 { getAuth, getCodeInfo, getEmergencyCenterApi, getUserInfo } 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 { getCurrentPath, PageEnum, setBaseLogin, toHomeByLogoutPath } from '/@/enum/pageEnum.ts';
import { message } from 'ant-design-vue';
const router = useRouter();
const route = useRoute();
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, '');
}
);
function toHomeByNowPath() {
return route.path == PageEnum.BASE_LOGIN_YINCHUAN ? PageEnum.YINCHUAN_HOME : PageEnum.BASE_HOME;
}
function checkFormField(formData, fieldName, placeholderTranslationKey) {
if (!formData[fieldName]) {
createMessage.warn(t(placeholderTranslationKey));
return false;
}
return true;
}
async function accountLogin() {
if (!checkFormField(formData, 'username', 'login.accountPlaceholder')) return;
if (!checkFormField(formData, 'password', 'login.passwordPlaceholder')) return;
if (!checkFormField(formData, 'inputCode', 'login.inputCodePlaceholder')) return;
try {
loginLoading.value = true;
const { userInfo } = await userStore.login(
toRaw({
password: encipher(formData.password) as string,
username: formData.username,
captcha: formData.inputCode,
checkKey: randCodeData.checkKey,
mode: 'none', //不要默认的错误提示
})
);
if (userInfo) {
try {
let { code, result, message: msg } = await getAuth();
let centerInfo = {};
try {
let { result } = await getEmergencyCenterApi();
centerInfo = result;
userStore.setCenterInfo(centerInfo);
} catch (e) {}
// console.log('centerInfo', centerInfo);
let goPath = PageEnum.BASE_HOME;
if (code == 200) {
let flag1 = result?.codeList?.find((item) => ['emergency:screen:show:yinchuan'].includes(item));
let flag2 = result?.codeList?.find((item) => ['emergency:screen:show:xian'].includes(item));
let flag3 = result?.codeList?.find((item) => ['emergency:screen:show:centralScreen'].includes(item));
// console.log('flag3', flag3);
userStore.setFlag1(flag1 || '');
userStore.setFlag2(flag2 || '');
// debugger;
if (!flag1 && !flag2 && !flag3) {
userStore.setToken('');
userStore.setUserInfo({});
userStore.setCenterInfo({});
return message.warn('您没有权限访问大屏,请联系管理员!');
}
//1如果有权限
//1.2若果是有两种权限
// debugger;
if (flag1 && flag2) {
// 1.2.1 如果是登录地址是西安
// 1.2.2 如果是登录地址是银川
if (route.path == PageEnum.BASE_LOGIN_YINCHUAN) {
goPath = PageEnum.YINCHUAN_HOME;
} else if (route.path == PageEnum.BASE_LOGIN) {
goPath = PageEnum.BASE_HOME;
} else if (route.path == PageEnum.CENTRAL_SCREEN_LOGIN) {
goPath = PageEnum.CENTRAL_SCREEN;
}
} else {
if (flag1) {
goPath = PageEnum.YINCHUAN_HOME;
} else if (flag2) {
goPath = PageEnum.BASE_HOME;
} else if (flag3) {
goPath = PageEnum.CENTRAL_SCREEN;
} else {
userStore.setToken('');
userStore.setUserInfo({});
userStore.setCenterInfo({});
return message.warn('没有权限请联系管理员!');
}
}
} else {
return message.warn(msg);
}
notification.success({
message: t('login.loginSuccessTitle'),
description: `${t('login.loginSuccessDesc')}: ${userInfo.realname}`,
duration: 3,
});
setBaseLogin(route.path);
router.replace(goPath);
} catch (e) {
handleChangeCheckCode();
return message.warn(e);
}
} else {
handleChangeCheckCode();
}
} catch (error) {
notification.error({
message: t('api.errorTip'),
description: error['message'] || t('login.networkExceptionMsg'),
duration: 3,
});
handleChangeCheckCode();
} finally {
loginLoading.value = false;
}
}
onMounted(() => {
checkToken();
//加载验证码
handleChangeCheckCode();
});
//校验缓存token是否有效
function checkToken() {
const token = getAuthCache(TOKEN_KEY);
if (!token) {
return;
}
const logoutPath = getCurrentPath(); //退出时路径
let path = toHomeByNowPath();
getUserInfo().then(({ code }) => {
if (code == 200) {
if (logoutPath) {
const hasLogoutPath = toHomeByLogoutPath(logoutPath);
router.push({ path: hasLogoutPath });
} else {
router.push({ path: path });
}
}
});
}
</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>