<!-- @format --> <template> <div style="height: 100%"> <a-layout style="height: 100%"> <!-- <a-layout-header class="home_header" style="position: relative"> --> <!-- <ns-icon class="test" name="login" size="64" style="width: 220px" /> --> <!-- <img v-else :src="themeConfig.logoUrl" style="width: 220px; height: 48px" /> --> <!-- </a-layout-header> --> <a-layout-content class="center-content" :style="{ background: `url(${ themeConfig.bgImageUrl ? themeConfig.bgImageUrl : '/asset/image/login/background.png' }) no-repeat `, backgroundSize: 'cover', }"> <div class="lg_card"> <h1 class="lg_card_title">{{ configStore.projectName }}</h1> <p v-show="!errorShow" style="height: 8px"></p> <p v-show="errorShow" class="lg_card_error">{{ errorMsg }}</p> <a-form name="basic" :model="formState" @finish="submit"> <a-form-item name="userName" :rules="[{ required: true, message: '请输入用户名' }]"> <!-- <p class="lg_card_tip">用户名/手机号</p> --> <a-input class="loginInfo" placeholder="用户名" v-model:value="userName"> <template #prefix> <ns-icon class="loginIcon" name="userName" size="19" style="margin-right: 20px" /> </template> </a-input> </a-form-item> <a-form-item name="password" :rules="[{ required: true, message: '请输入密码' }]"> <!-- <p class="lg_card_tip">密码</p> --> <a-input-password class="loginInfo" placeholder="密码" v-model:value="password"> <template #prefix> <ns-icon class="loginIcon" name="passWord" size="19" style="margin-right: 20px" /> </template> </a-input-password> </a-form-item> <a-form-item name="code"> <!-- 验证码 --> <a-input v-model:value="code" placeholder="验证码" class="loginInfo"> <template #prefix> <ns-icon class="loginIcon" name="verifyIcon" size="19" style="margin-right: 20px" /> </template> <template #addonAfter> <ns-verify @get-code="onGetCode" ref="verifyRef" /> </template> </a-input> </a-form-item> <!-- <a-form-item name="remember"> --> <!-- 记住密码 --> <a-checkbox v-model:checked="isRemember" class="loginInfo">记住密码</a-checkbox> <!-- </a-form-item> --> <a-form-item> <a-button html-type="submit" :loading="loading" type="primary" class="loginInfo"> 登录 </a-button> </a-form-item> </a-form> </div> </a-layout-content> <!-- <a-layout-footer>Copyright 2021 xu科技 All Rights Reserved</a-layout-footer> --> </a-layout> </div> </template> <script lang="ts"> import { defineComponent, onMounted, reactive, ref } from 'vue'; import { useRouter } from 'vue-router'; import { appConfigStore } from '/nerv-lib/saas/store/modules/app-config'; import { authorizationService } from '/nerv-base/store/modules/authorization-service'; import { Cookies } from '/nerv-lib/util/cookie'; import { storeToRefs } from 'pinia'; import { NsMessage } from '/nerv-lib/component'; export default defineComponent({ name: 'UserLogin', setup() { const url = ref('/asset/image/login/background.png'); const userName = ref<string>(''); const password = ref<string>(''); const logUrl = ref<string>(''); const bgUrl = ref<string>(''); const errorMsg = ref<string>(''); const errorShow = ref<boolean>(false); const router = useRouter(); const title = ref<string>(''); const initUrl = ref(''); const verifyCode = ref(''); const code = ref(); const verifyRef = ref(); const isRemember = ref(false); title.value = '账号登录'; // title.value = appConfig.title ? appConfig.title : '账号登录'; const loading = ref<boolean>(false); const configStore = appConfigStore(); const formState = reactive({ userName, password, code }); const { getThemeConfig: themeConfig, projectName } = storeToRefs(configStore); const useAuthorization = authorizationService(); const rememberFunc = (data) => { console.log(isRemember.value); if (!isRemember.value) return; localStorage.setItem('LOGIN_INFO', data); }; onMounted(() => { const data = localStorage.getItem('LOGIN_INFO'); if (data) { const { accountNo, password: pwd } = JSON.parse(data); userName.value = accountNo; password.value = pwd; formState.userName = userName.value; formState.password = password.value; } }); const submit = (value): void => { console.log(value); let data = JSON.stringify({ accountNo: userName.value.trim(), password: password.value.trim(), }); validator(null, value.code) .then(() => { // 记住密码 rememberFunc(data); loading.value = true; async function logins() { try { const res = await configStore.userLogin(JSON.parse(data)); verifyRef.value?.reload(); if (res.data?.token) { if (res.data?.token) { Cookies.set(`${import.meta.env.VITE_PUBLIC_PATH}-nervsid`, res.data?.token); } const info = await configStore.userInfo(); info.data ? window.sessionStorage.setItem( import.meta.env.VITE_PUBLIC_PATH, JSON.stringify(info.data), ) : ''; loading.value = false; if (configStore.enablePermissions) { const res = await configStore.userResource(info); res?.data.sort((a, b) => { return a.sort - b.sort; }); console.log(res.data); if (configStore.customApplication) { await useAuthorization.initMenuResource(); } initUrl.value = ''; const dealInitUrl = (item) => { if (item.type === 'menus' && item.menus && item.menus?.length !== 0) { dealInitUrl(item.menus[0]); } else { if (item.type === 'noChildrenMenu') { initUrl.value = configStore.resourceName ? item.code.replace(configStore.resourceName, '') : item.code; } } }; if (configStore.resourceName) { const initResource = []; res.data.forEach((item) => { if (item.code.includes(configStore.resourceName)) { initResource.push(item); } }); dealInitUrl(initResource[0]); } else { dealInitUrl(res.data[0]); } // dealInitUrl(res.data[0]); useAuthorization.updateUserResource(res.data); const initRouterList = useAuthorization.getInitRouterList; router.push({ name: initRouterList.length === 0 ? 'error403' : res.data[0]['code'], }); } else { router.replace({ name: 'root' }); } } } catch (err) { console.log(err); loading.value = false; } } logins(); }) .catch((flag) => { if (flag) { NsMessage.error('请输入正确的验证码'); verifyRef.value?.reload(); } else { NsMessage.error('请输入验证码'); } }); }; const checkoutLogo = (): void => { logUrl.value = ''; }; const checkoutBg = (): void => { Math.random() > 0.5 ? (url.value = 'src/assetimg/background.jpg') : (url.value = 'src/assetimg/background.png'); }; const onGetCode = (res) => { verifyCode.value = res; }; const validator = (rule, value) => { if (!value) return Promise.reject(false); if (value?.toLocaleLowerCase() !== verifyCode.value.toLocaleLowerCase()) return Promise.reject(true); return Promise.resolve(); }; return { validator, formState, projectName, onGetCode, code, title, themeConfig, url, loading, userName, password, submit, errorMsg, bgUrl, logUrl, checkoutLogo, checkoutBg, errorShow, configStore, isRemember, verifyRef, }; }, created() { const _this = this; window.sessionStorage.clear(); document.onkeydown = function (e) { const key = window.event === undefined ? e.keyCode : window.event.keyCode; key === 13 ? _this.submit() : ''; }; }, beforeUnmount() { document.onkeydown = function (e) {}; }, mounted() { // if (Cookies.get(`${import.meta.env.VITE_PUBLIC_PATH}-nervsid`) !== undefined) { // this.$router.push('/home'); // } }, }); </script> <style lang="less" scoped> .home_header { height: 64px !important; display: flex; align-items: center; } :deep(.center-content) { // background: url('/asset/image/login/background.png') center center no-repeat; // background-size: cover; // background-position-y: -120px; margin: 0; } .icon { color: @primary-color !important; // background: #000; // min-height: 25px; // min-width: 25px; // display: flex; // justify-content: center; // align-items: center; // border-radius: 50%; } // .lg_card .loginIcon { // color: @primary-color !important; // } .ant-layout-header { min-height: 64px; // background: #fff !important; } .ant-layout-content { height: calc(100vh - 112px); width: 100%; min-height: 400px; display: flex; align-items: center; justify-content: flex-end; padding-right: 10%; } .ant-layout-footer { max-height: 48px; min-height: 48px; font-size: 14px; font-weight: 400; color: #8f8f8f; padding: 0; display: flex; align-items: center; justify-content: center; } .lg_card { width: 500px; height: fit-content; background: #e4f5ff; box-shadow: 0 2px 18px 0 rgba(124, 184, 254, 1), 0 0 32px 0 rgba(124, 184, 254, 1), 0px 14px 60px rgba(64, 210, 252, 0.12), inset -7.07px -8.43px 38px rgba(73, 105, 255, 0.25); border-radius: 6px; padding: 50px; border-radius: 10px; border: 3px solid rgba(255, 255, 255, 1); .lg_card_tip { color: #a7b6c9; margin-bottom: 12px; } .loginInfo { height: 48px; width: 100%; // margin-bottom: 24px; font-size: 16px !important; :deep(.ant-input) { font-size: 16px !important; } :deep(.ant-input-group) { height: 100%; .ant-input-affix-wrapper { height: 100%; } .ant-input-group-addon { padding: 0; } } } .loginInfo:last-child { // margin-bottom: 16px; } .loginInfo:nth-child(4) { width: fit-content; // margin-bottom: 0px; // height: 20px !important; } } .lg_card .lg_card_title { text-align: center; font-size: 32px; font-weight: 700; letter-spacing: 0px; line-height: 42px; color: @primary-color; text-align: center; vertical-align: top; } .lg_card_error { text-align: left; color: #e00e12; font-size: 16px; } .lg_card .loginIcon { color: @primary-color !important; } </style>