From 806020211c46dbea8a2ef321e78d54fb001057a0 Mon Sep 17 00:00:00 2001 From: gerson <1405270578@qq.com> Date: 星期四, 04 七月 2024 00:22:48 +0800 Subject: [PATCH] 路由和请求均可唤起登录弹窗 --- src/layout/navBars/breadcrumb/user.vue | 3 src/utils/request.ts | 15 + src/views/error/404.vue | 5 src/layout/main/classic.vue | 19 - src/router/backEnd.ts | 38 --- src/api/menu/menuData.ts | 2 src/layout/component/sidebar/waterLeftAside/asideTitle.vue | 109 +++++++--- src/types/mitt.d.ts | 16 - src/main.ts | 17 src/stores/userInfo.ts | 2 /dev/null | 272 --------------------------- src/router/route.ts | 22 -- src/layout/upgrade/index.vue | 2 src/router/index.ts | 26 + 14 files changed, 135 insertions(+), 413 deletions(-) diff --git a/src/api/menu/menuData.ts b/src/api/menu/menuData.ts index 4a39973..af4d3ae 100644 --- a/src/api/menu/menuData.ts +++ b/src/api/menu/menuData.ts @@ -1,4 +1,4 @@ -export const MenuData = [ +export const menuData = [ { Children: [], ID: '1805430930840621056', diff --git a/src/layout/component/sidebar/waterLeftAside/asideTitle.vue b/src/layout/component/sidebar/waterLeftAside/asideTitle.vue index e2ee3e1..a4dd752 100644 --- a/src/layout/component/sidebar/waterLeftAside/asideTitle.vue +++ b/src/layout/component/sidebar/waterLeftAside/asideTitle.vue @@ -12,32 +12,29 @@ <span class="font-medium text-sm text-white tracking-wide">{{ item.title }}</span> </div> </div> - <div class="user_text"> + <div class="user_text" v-if="isLoginStatus"> <div class="user_head"> <span ><span - ><span class="user-head">T</span><span class="identifying"><!----></span></span - ><span class="user_name"> tc </span></span - ><span - ><span><i class="ywicon icon-fold text-white" @click="showExitLogin"></i></span + ><span class="user-head">{{ firstUserCharacter }}</span><span class="identifying"><!----></span></span + ><span class="user_name"> {{ userName }} </span></span + ><span ref="toggleExitLoginBtnRef" + ><span + class="ywicon text-white" + :class="{ 'icon-fold': !state.isShowExitLogin, 'icon-unfold': state.isShowExitLogin }" + @click="toggleShowExitLogin" + ></span ></span> </div> - <!-- <div class="pop_up actived" v-show="state.isShowExitLogin"> - <div class="exit" @click="handleExitClose"><i class="ywicon icon-tuichu"></i> 閫�鍑虹櫥褰�</div> - </div> --> - </div> - <!-- <div class="user_login"> - <p class="text-white font-medium text-sm text-center">鎮ㄦ洿濂界殑AI鍔╂墜锛�</p> - <div class="set-login" @click="login"> - <span class="text-stone-100 font-medium text-sm text-center">{{ state.isShowLogin ? '鐧诲綍 / 娉ㄥ唽' : '浼氬憳鐧诲綍' }}</span> + <div class="pop_up actived" v-show="state.isShowExitLogin"> + <div class="exit" @click="logoutClick"><i class="ywicon icon-tuichu"></i> 閫�鍑虹櫥褰�</div> </div> </div> - <div class="offices"> - <div class="officeText"> - <img :src="'/static/images/wave/Waveform.png'" alt="" class="pl-2.5 pr-2.5 w-4 h-4" style="box-sizing: content-box" /> - <span class="font-medium text-sm text-white tracking-wide">Office 鏅鸿兘鍔╂墜</span> + <div v-else class="user_login"> + <div class="set-login" @click="openLoginDlg"> + <span class="text-stone-100 font-medium text-sm text-center">鐧诲綍 / 娉ㄥ唽</span> </div> - </div> --> + </div> </div> <div class="pc-login" v-show="state.isShowLogin"> <div class="login_box"> @@ -52,7 +49,6 @@ <el-input v-model="state.loginForm.pwd" type="password" autocomplete="off" clearable /> </el-form-item> </el-form> - <div class="set-pwd">蹇樿瀵嗙爜 ?</div> <div class="mt-[115px]"> <el-button type="primary" @click="onSubmit" class="set-login_btn">鐧诲綍</el-button> </div> @@ -62,9 +58,24 @@ </template> <script setup lang="ts"> -import { reactive } from 'vue'; +import type { FormInstance } from 'element-plus'; +import { computed, onMounted, reactive, ref, watchEffect } from 'vue'; +import { PostLogin } from '/@/api/ai/user'; import router from '/@/router'; +import { accessSessionKey, userNameKey } from '/@/utils/request'; import { gotoRoute } from '/@/utils/route'; +import { Local } from '/@/utils/storage'; +import emitter from '/@/utils/mitt'; + +const loginFormRef = ref<FormInstance>(null); +const isLoginStatus = ref(!!Local.get(accessSessionKey)); + +const userName = ref(''); +const firstUserCharacter =computed(()=>userName.value?.[0]?.toUpperCase()); +watchEffect(()=>{ + if(!isLoginStatus.value)return; + userName.value = Local.get(userNameKey) +}) let state = reactive({ asideTitleList: [ { @@ -99,31 +110,65 @@ }, }); const loginRules = reactive({ - account: [{ required: true, message: '蹇呭~椤�', trigger: 'blur' }], - pwd: [{ required: true, message: '蹇呭~椤�', trigger: 'blur' }], + account: [{ required: true, message: '璇疯緭鍏ヨ处鍙�', trigger: 'blur' }], + pwd: [{ required: true, message: '璇疯緭鍏ュ瘑鐮�', trigger: 'blur' }], }); const handleClick = (item) => { gotoRoute({ name: item.routerName }); }; //鐧诲綍 -const login = () => { +const openLoginDlg = async () => { state.isShowLogin = true; }; const handleClose = () => { state.isShowLogin = false; }; //鐧诲綍 -const onSubmit = () => {}; -const currentRoute = router.currentRoute; -//鏄惁鏄剧ず閫�鍑虹櫥褰曞脊绐� -const showExitLogin = () => { - state.isShowExitLogin = true; -}; -//鍏抽棴閫�鍑虹櫥褰曞脊绐� -const handleExitClose = () => { - state.isShowExitLogin = false; +const onSubmit = async () => { + const isValid = await loginFormRef.value.validate().catch(() => {}); + if (!isValid) return; + const res = await PostLogin({ + user: state.loginForm.account, + pass: state.loginForm.pwd, + }); + Local.set(accessSessionKey, res.hswatersession); + Local.set(userNameKey,state.loginForm.account); state.isShowLogin = false; + isLoginStatus.value = true; + window.location.reload(); }; + +const currentRoute = router.currentRoute; + +//鏄惁鏄剧ず閫�鍑虹櫥褰曞脊绐梒polar.top/login +const toggleShowExitLogin = () => { + state.isShowExitLogin = !state.isShowExitLogin; +}; +//閫�鍑虹櫥褰� +const logoutClick = () => { + state.isShowExitLogin = false; + isLoginStatus.value = false; + Local.remove(accessSessionKey); + +}; +const toggleExitLoginBtnRef = ref<HTMLDivElement>(null); + +const listenClickOtherExit = (e) => { + if (toggleExitLoginBtnRef.value !== e.target && !toggleExitLoginBtnRef.value?.contains(e.target)) { + state.isShowExitLogin = false; + } +}; + +onMounted(() => { + emitter.on('openLoginDlg', () => { + if(state.isShowLogin || isLoginStatus.value)return; + openLoginDlg(); + }); + + emitter.on('logout', () => {}); + + document.addEventListener('click', listenClickOtherExit); +}); </script> <style scoped lang="scss"> .aisde-title { diff --git a/src/layout/main/classic.vue b/src/layout/main/classic.vue index 3d6a98d..98df273 100644 --- a/src/layout/main/classic.vue +++ b/src/layout/main/classic.vue @@ -8,29 +8,12 @@ import { storeToRefs } from 'pinia'; import { computed, defineAsyncComponent, nextTick, onMounted, ref, watch } from 'vue'; import { useRoute } from 'vue-router'; -import { PostLogin } from '/@/api/ai/user'; import { useThemeConfig } from '/@/stores/themeConfig'; -import { Local } from '/@/utils/storage'; - -const login = () => { - return PostLogin({ - user: 'tc', - pass: 'a', - }).then((res)=>{ - const hswatersession = res.hswatersession; - Local.set('hswatersession',hswatersession); - }); -}; // 寮曞叆缁勪欢 const LayoutMain = defineAsyncComponent(async () => { - try { - await login(); - } finally { - // eslint-disable-next-line no-unsafe-finally - return import('/@/layout/component/main.vue'); - } + return import('/@/layout/component/main.vue'); }); // 瀹氫箟鍙橀噺鍐呭 diff --git a/src/layout/navBars/breadcrumb/user.vue b/src/layout/navBars/breadcrumb/user.vue index 8644827..b0d847c 100644 --- a/src/layout/navBars/breadcrumb/user.vue +++ b/src/layout/navBars/breadcrumb/user.vue @@ -173,7 +173,6 @@ }, }) .then(async () => { - console.log('馃殌 ~ reload',); // 娓呴櫎缂撳瓨/token绛� clearAccessTokens(); // 浣跨敤 reload 鏃讹紝涓嶉渶瑕佽皟鐢� resetRoute() 閲嶇疆璺敱 @@ -196,8 +195,6 @@ themeConfig.value.globalComponentSize = size; Local.set('themeConfig', themeConfig.value); initI18nOrSize('globalComponentSize', 'disabledSize'); - console.log('馃殌 ~ reload',); - window.location.reload(); }; //閫氱煡涓績 diff --git a/src/layout/upgrade/index.vue b/src/layout/upgrade/index.vue index e70b159..6dd350d 100644 --- a/src/layout/upgrade/index.vue +++ b/src/layout/upgrade/index.vue @@ -64,8 +64,6 @@ state.btnTxt = t('message.upgrade.btnTwoLoading'); setTimeout(() => { Local.clear(); - console.log('馃殌 ~ reload',); - window.location.reload(); Local.set('version', state.version); }, 2000); diff --git a/src/main.ts b/src/main.ts index c5453ca..20fd4a5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,16 +1,16 @@ import { createApp } from 'vue'; -import pinia from '/@/stores/index'; import App from '/@/App.vue'; -import router from '/@/router/index'; import { directive } from '/@/directive/index'; import { i18n } from '/@/i18n/index'; +import router from '/@/router/index'; +import pinia from '/@/stores/index'; import other from '/@/utils/other'; -import ElementPlus from 'element-plus'; -import '/@/theme/index.scss'; -import VueGridLayout from 'vue-grid-layout'; import * as ElementPlusIconsVue from '@element-plus/icons-vue'; +import ElementPlus from 'element-plus'; +import VueGridLayout from 'vue-grid-layout'; import { initBackEndControlRoutes } from './router/backEnd'; +import '/@/theme/index.scss'; const app = createApp(App); for (const [key, component] of Object.entries(ElementPlusIconsVue)) { @@ -18,7 +18,8 @@ } directive(app); other.elSvg(app); -app.use(pinia).use(router).use(ElementPlus).use(i18n).use(VueGridLayout).mount('#app'); -initBackEndControlRoutes() -console.log('馃殌 ~nihao ',); \ No newline at end of file +(async function () { + await initBackEndControlRoutes(); + app.use(pinia).use(router).use(ElementPlus).use(i18n).use(VueGridLayout).mount('#app'); +})(); diff --git a/src/router/backEnd.ts b/src/router/backEnd.ts index 2ea9bd4..078e7d8 100644 --- a/src/router/backEnd.ts +++ b/src/router/backEnd.ts @@ -1,6 +1,4 @@ -import { ElMessage } from 'element-plus'; import type { RouteRecordRaw } from 'vue-router'; -import { MenuData } from '../api/menu/menuData'; import { parseMenuTree, useMenuApi } from '/@/api/menu/index'; import { formatFlatteningRoutes, formatTwoStageRoutes, router } from '/@/router/index'; import { pathMap } from '/@/router/pathMap'; @@ -9,10 +7,8 @@ import { useRequestOldRoutes } from '/@/stores/requestOldRoutes'; import { useRoutesList } from '/@/stores/routesList'; import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes'; -import { useUserInfo } from '/@/stores/userInfo'; -import { NextLoading } from '/@/utils/loading'; -import { accessSessionKey, clearAccessTokens } from '/@/utils/request'; -import { Local } from '/@/utils/storage'; +import { menuData } from '../api/menu/menuData'; + // 鍚庣鎺у埗璺敱 @@ -38,15 +34,14 @@ */ export async function initBackEndControlRoutes() { // 鐣岄潰 loading 鍔ㄧ敾寮�濮嬫墽琛� - if (window.nextLoading === undefined) NextLoading.start(); + // if (window.nextLoading === undefined) NextLoading.start(); // 鏃� token 鍋滄鎵ц涓嬩竴姝� // if (!Local.get(accessSessionKey)) return false; // 瑙﹀彂鍒濆鍖栫敤鎴蜂俊鎭� pinia // https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP // await useUserInfo().setUserInfos(); // 鑾峰彇璺敱鑿滃崟鏁版嵁 - const menuData = (await getBackEndControlRoutes()) as any; - const formattedTreeMenu = parseMenuTree(menuData, pathMap); + const formattedTreeMenu = parseMenuTree(menuData as any, pathMap); // 鏃犵櫥褰曟潈闄愭椂锛屾坊鍔犲垽鏂� // https://gitee.com/lyt-top/vue-next-admin/issues/I64HVO // if (res.data.length <= 0) return Promise.resolve(true); @@ -105,31 +100,6 @@ router.addRoute(route); }); } - -/** - * 璇锋眰鍚庣璺敱鑿滃崟鎺ュ彛 - * @description isRequestRoutes 涓� true锛屽垯寮�鍚悗绔帶鍒惰矾鐢� - * @returns 杩斿洖鍚庣璺敱鑿滃崟鏁版嵁 - */ -export async function getBackEndControlRoutes() { - // 妯℃嫙 admin 涓� test - - return MenuData; - // const auth = userInfos.value.roles[0]; - // 绠$悊鍛� admin - // if (auth === 'admin') return menuApi.getAdminMenu(); - // 鍏跺畠鐢ㄦ埛 test - // else return menuApi.getTestMenu(); -} - -/** - * 閲嶆柊璇锋眰鍚庣璺敱鑿滃崟鎺ュ彛 - * @description 鐢ㄤ簬鑿滃崟绠$悊鐣岄潰鍒锋柊鑿滃崟锛堟湭杩涜娴嬭瘯锛� - * @description 璺緞锛�/src/views/system/menu/component/addMenu.vue - */ -// export async function setBackEndControlRefreshRoutes() { -// await getBackEndControlRoutes(); -// } /** * 鍚庣璺敱 component 杞崲 diff --git a/src/router/index.ts b/src/router/index.ts index 44ff9db..7ce9f91 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,17 +1,14 @@ -import NProgress from 'nprogress'; import 'nprogress/nprogress.css'; import { storeToRefs } from 'pinia'; import { createRouter, createWebHashHistory } from 'vue-router'; import { MenuTypeEnum } from '/@/api/menu/type'; -import { initBackEndControlRoutes } from '/@/router/backEnd'; -import { initFrontEndControlRoutes } from '/@/router/frontEnd'; import { notFoundAndNoPower, staticRoutes } from '/@/router/route'; import pinia from '/@/stores/index'; import { useKeepALiveNames } from '/@/stores/keepAliveNames'; -import { useRoutesList } from '/@/stores/routesList'; import { useThemeConfig } from '/@/stores/themeConfig'; -import { accessSessionKey, clearAccessTokens } from '/@/utils/request'; -import { Local } from '/@/utils/storage'; +import { Local } from '../utils/storage'; +import { accessSessionKey } from '../utils/request'; +import emitter from '../utils/mitt'; /** * 1銆佸墠绔帶鍒惰矾鐢辨椂锛歩sRequestRoutes 涓� false锛岄渶瑕佸啓 roles锛岄渶瑕佽蛋 setFilterRoute 鏂规硶銆� @@ -95,8 +92,21 @@ } // 璺敱鍔犺浇鍓� - - +router.beforeEach((to, from, next) => { + const accessSession = Local.get(accessSessionKey); + if (!accessSession) { + emitter.emit('openLoginDlg'); + if(to.name==='Home'){ + next(); + }else{ + next({ + name: 'Home', + }); + } + + } + next(); +}); // 璺敱鍔犺浇鍚� // 瀵煎嚭璺敱 diff --git a/src/router/route.ts b/src/router/route.ts index f73d6be..5051790 100644 --- a/src/router/route.ts +++ b/src/router/route.ts @@ -27,7 +27,7 @@ isIframe?: boolean; roles?: string[]; icon?: string; - showTitle?:boolean; + showTitle?: boolean; } } @@ -82,22 +82,4 @@ * @description 鍓嶇鎺у埗鐩存帴鏀� dynamicRoutes 涓殑璺敱锛屽悗绔帶鍒朵笉闇�瑕佷慨鏀癸紝璇锋眰鎺ュ彛璺敱鏁版嵁鏃讹紝浼氳鐩� dynamicRoutes 绗竴涓《绾� children 鐨勫唴瀹癸紙鍏ㄥ睆锛屼笉鍖呭惈 layout 涓殑璺敱鍑哄彛锛� * @returns 杩斿洖璺敱鑿滃崟鏁版嵁 */ -export const staticRoutes: Array<RouteRecordRaw> = [ - { - path: '/login', - name: 'login', - // 涓嶅悓杞欢缂栫爜浣跨敤涓嶅悓鐨勭櫥褰曢〉 - component: () => { - switch (window.globalConfig.Auth.SoftWareCode) { - case 'CH_web': - return import('/@/views/login/index_ch.vue'); - - default: - return import('/@/views/login/index_ch.vue'); - } - }, - meta: { - title: '鐧诲綍', - }, - }, -]; +export const staticRoutes: Array<RouteRecordRaw> = []; diff --git a/src/stores/userInfo.ts b/src/stores/userInfo.ts index 70600ae..4785741 100644 --- a/src/stores/userInfo.ts +++ b/src/stores/userInfo.ts @@ -39,8 +39,6 @@ } else { clearAccessTokens(); window.location.reload(); - console.log('馃殌 ~ reload',); - return; } }, 0); diff --git a/src/types/mitt.d.ts b/src/types/mitt.d.ts index 479ea4a..91343ec 100644 --- a/src/types/mitt.d.ts +++ b/src/types/mitt.d.ts @@ -23,18 +23,14 @@ openShareTagsView?: string; onTagsViewRefreshRouterView?: T; onCurrentContextmenuClick?: T; - refreshTestStandard?: T; - refreshTestGrade?: T; - x6CellPropertyChange?: T; - x6ViewPropertyChange?: T; - refreshFaultGroup?: T; - refreshFault?: T; - refreshMethodDefinition?: T; - // 鏇存柊鏁呴殰浜嬩欢 contentName - updateFaultContentName: T; + + //#region ====================== ai ====================== updateChatInput: T; - + /** @description 寮瑰嚭鐧诲綍瀵硅瘽妗� */ + openLoginDlg:T; + /** @description 閫�鍑虹櫥褰� */ + logout:T; //#endregion }; diff --git a/src/utils/request.ts b/src/utils/request.ts index 1be35f1..37b9574 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -1,6 +1,8 @@ import type { AxiosInstance, AxiosRequestConfig } from 'axios'; import axios from 'axios'; import { ElMessage } from 'element-plus'; +import emitter from './mitt'; +import { debounce } from './util'; import { AUTH_URL, MAIN_URL, SECONDARY_URL } from '/@/constants'; import { Local, Session } from '/@/utils/storage'; // import JSONbig from 'json-bigint'; @@ -12,6 +14,10 @@ } //#endregion +const openLoginDlg = debounce(() => { + emitter.emit('openLoginDlg'); +}); + const initRequestInterceptor = (request: AxiosInstance) => { // 娣诲姞璇锋眰鎷︽埅鍣� request.interceptors.request.use( @@ -21,6 +27,8 @@ if (accessSession) { // 灏� token 娣诲姞鍒拌姹傛姤鏂囧ご涓� config.headers['hswatersession'] = accessSession; + } else { + openLoginDlg(); } return config; }, @@ -55,9 +63,8 @@ if (!serveData.json_ok) { switch (serveData?.err_code) { case ErrorCode.Auth: - // clearAccessTokens(); - // window.location.reload(); - break; + openLoginDlg(); + throw '鏉冮檺楠岃瘉澶辫触'; } const msg = serveData.json_msg ?? ''; @@ -132,6 +139,8 @@ const domainPrefix = subDomainName ? `${subDomainName}-` : ''; // token 閿畾涔� export const accessSessionKey = domainPrefix + 'access-session'; +export const userNameKey = domainPrefix + 'userName'; + export const refreshAccessTokenKey = `x-${accessSessionKey}`; // userInfo閿畾涔� diff --git a/src/views/error/404.vue b/src/views/error/404.vue index 0b7d899..886a1c1 100644 --- a/src/views/error/404.vue +++ b/src/views/error/404.vue @@ -23,6 +23,7 @@ </template> <script setup lang="ts" name="notFound"> +import { onMounted } from 'vue'; import { useRouter } from 'vue-router'; // 瀹氫箟鍙橀噺鍐呭 @@ -32,6 +33,10 @@ const onGoHome = () => { router.push('/'); }; + +onMounted(()=>{ +}) +const currentRoute = router.currentRoute.value </script> <style scoped lang="scss"> diff --git a/src/views/login/component/account.vue b/src/views/login/component/account.vue deleted file mode 100644 index 9f1a7d9..0000000 --- a/src/views/login/component/account.vue +++ /dev/null @@ -1,358 +0,0 @@ -<template> - <el-form size="large" ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" class="login-content-form"> - <el-form-item class="login-animation1"> - <el-input - text - :placeholder="$t('message.account.accountPlaceholder1')" - v-model="state.ruleForm.account" - clearable - autocomplete="username" - > - <template #prefix> - <el-icon class="el-input__icon"><ele-User /></el-icon> - </template> - </el-input> - </el-form-item> - <el-form-item class="login-animation2"> - <el-input - :type="state.isShowPassword ? 'text' : 'password'" - :placeholder="$t('message.account.accountPlaceholder2')" - v-model="state.ruleForm.password" - autocomplete="current-password" - > - <template #prefix> - <el-icon class="el-input__icon"><ele-Unlock /></el-icon> - </template> - <template #suffix> - <i - class="iconfont el-input__icon login-content-password" - :class="state.isShowPassword ? 'icon-yincangmima' : 'icon-xianshimima'" - @click="state.isShowPassword = !state.isShowPassword" - > - </i> - </template> - </el-input> - </el-form-item> - <el-form-item class="login-animation3"> - <el-col :span="15"> - <el-input - text - maxlength="4" - :placeholder="$t('message.account.accountPlaceholder3')" - v-model="state.ruleForm.code" - clearable - autocomplete="off" - > - <template #prefix> - <el-icon class="el-input__icon"><ele-Position /></el-icon> - </template> - </el-input> - </el-col> - <el-col :span="1"></el-col> - <el-col :span="8"> - <div class="login-content-code"> - <img - class="login-content-code-img" - @click="getCaptcha" - width="130px" - height="38px" - :src="state.captchaImage" - style="cursor: pointer" - /> - </div> - </el-col> - </el-form-item> - <el-form-item class="login-animation4"> - <el-button type="primary" class="login-content-submit" round v-waves @click="onSignIn" :loading="state.loading.signIn"> - <span>{{ $t('message.account.accountBtnText') }}</span> - </el-button> - </el-form-item> - </el-form> -</template> - -<script setup lang="ts" name="loginAccount"> -import { reactive, ref, computed, onMounted, onUnmounted } from 'vue'; -import { useRoute, useRouter } from 'vue-router'; -import { ElMessage, FormInstance } from 'element-plus'; -import { useI18n } from 'vue-i18n'; -import Cookies from 'js-cookie'; -import { storeToRefs } from 'pinia'; -import { useThemeConfig } from '/@/stores/themeConfig'; -import { useUserInfo } from '/@/stores/userInfo'; -import { initFrontEndControlRoutes } from '/@/router/frontEnd'; -import { initBackEndControlRoutes } from '/@/router/backEnd'; -import { Session, Local } from '/@/utils/storage'; -import { formatAxis } from '/@/utils/formatTime'; -import { NextLoading } from '/@/utils/loading'; -import { GetCaptcha, GetVerifyCaptcha, LoginSoftware, GetRolesListByUserID } from '/@/api/login/index'; -import profileMan from '/@/assets/profile/man.svg'; -import { accessTokenKey, clearAccessTokens } from '/@/utils/request'; - -// 瀹氫箟鍙橀噺鍐呭 -const { t } = useI18n(); -const storesThemeConfig = useThemeConfig(); -const { themeConfig } = storeToRefs(storesThemeConfig); -const route = useRoute(); -const router = useRouter(); -const ruleFormRef = ref<FormInstance>(); -const state = reactive({ - isShowPassword: false, - ruleForm: { - account: '', - password: '', - code: '', - codeId: 0, - }, - captchaImage: '', - loading: { - signIn: false, - }, - rules: { - account: [{ required: true, message: '璇疯緭鍏ョ敤鎴峰悕', trigger: 'blur' }], - password: [{ required: true, message: '璇疯緭鍏ュ瘑鐮�', trigger: 'blur' }], - code: [{ required: true, message: '璇疯緭鍏ラ獙璇佺爜', trigger: 'blur' }], - }, -}); - -const pressEnterLogin = (ev: KeyboardEvent) => { - if (ev.key === 'Enter') { - onSignIn(); - } -}; - -onMounted(() => { - getCaptcha(); - ruleFormRef.value?.$el.addEventListener('keypress', pressEnterLogin); -}); -onUnmounted(() => { - ruleFormRef.value?.$el.removeEventListener('keypress', pressEnterLogin); -}); -// 鏃堕棿鑾峰彇 -const currentTime = computed(() => { - return formatAxis(new Date()); -}); -// 鑾峰彇楠岃瘉鐮� -const getCaptcha = async () => { - state.ruleForm.code = ''; - - const res = await GetCaptcha(); - if (res?.Code === 0) { - if (res.Data) { - state.ruleForm.codeId = Number(res.Data.Id); - state.captchaImage = 'data:text/html;base64,' + res.Data.Img; - } else { - ElMessage.error('鑾峰彇楠岃瘉鐮佸け璐�'); - } - } else { - ElMessage.error('鑾峰彇楠岃瘉鐮佸け璐�' + (res?.Message ? `锛�${JSON.stringify(res.Message)}` : '')); - } -}; -// 鏍¢獙楠岃瘉鐮� -const verifyCaptcha = async () => { - let params = { - Id: state.ruleForm.codeId, - Code: state.ruleForm.code, - }; - const res = await GetVerifyCaptcha(params); - if (res?.Code === 0) { - return res.Data; - } else { - ElMessage.error('楠岃瘉鐮佹牎楠屽け璐ワ紒' + (res?.Message ? `锛�${JSON.stringify(res.Message)}` : '')); - return false; - } - // return new Promise((resolve, reject) => { - // let params = { - // Id: state.ruleForm.codeId, - // Code: state.ruleForm.code, - // }; - // axios - // .get(LOGIN_API_URL + '/Auth/Tool/VerifyCaptcha@V1.0', { - // params, - // }) - // .then((res: any) => { - // resolve(res.data.Data); - // }) - // .catch((err: any) => { - // reject(err); - // }); - // apiSysAuthCaptchaRuleGet(params) - // .then((res: any) => { - // resolve(res.Data); - // }) - // .catch((err: any) => { - // reject(err); - // }); - // }); -}; -// 鐧诲綍 -const onSignIn = async () => { - ruleFormRef.value.validate(async (valid: boolean) => { - if (!valid) return false; - // 鏍¢獙楠岃瘉鐮� - let isPassCaptcha = await verifyCaptcha(); - if (!isPassCaptcha) { - getCaptcha(); - ElMessage.error('楠岃瘉鐮侀敊璇�,璇烽噸鏂拌緭鍏ワ紒'); - return; - } - let params = { - SoftWare: (window as any).globalConfig.Auth.SoftWareCode, - LoginName: state.ruleForm.account, - LoginPwd: state.ruleForm.password, - Message: (window as any).globalConfig.Auth.Message, - }; - - const res = await LoginSoftware(params); - if (res?.Code === 0) { - if (res.Data) { - if (res.Data?.Token == undefined) { - getCaptcha(); // 閲嶆柊鑾峰彇楠岃瘉鐮� - ElMessage.error('鐧诲綍澶辫触锛岃妫�鏌ヨ处鍙凤紒'); - return; - } - // 缂撳瓨access-token - Local.set(accessTokenKey, res.Data?.Token); - - // admin 椤甸潰鏉冮檺鏍囪瘑锛屽搴旇矾鐢� meta.roles锛岀敤浜庢帶鍒惰矾鐢辩殑鏄剧ず/闅愯棌 - let adminRoles: Array<string> = []; - if (res.Data.User?.ID) { - const res1 = await GetRolesListByUserID({ - UserID: res.Data.User.ID, - }); - if (res?.Code === 0) { - adminRoles = (res1.Data || []) as []; - } else { - ElMessage.error('鑾峰彇鐢ㄦ埛瑙掕壊澶辫触' + (res?.Message ? `锛�${JSON.stringify(res.Message)}` : '')); - } - } - - // admin 鎸夐挳鏉冮檺鏍囪瘑 - let adminAuthBtnList: Array<string> = ['btn.add', 'btn.del', 'btn.edit', 'btn.link']; - let userName = res.Data.User.Name; - const userInfos = { - SoftWare: res.Data.Software, - User: res.Data.User, - userName: userName, - photo: profileMan, - time: new Date().getTime(), - roles: adminRoles, - authBtnList: adminAuthBtnList, - }; - await useUserInfo().setUserInfos(userInfos); //缂撳瓨鐢ㄦ埛淇℃伅 - - state.loading.signIn = true; - if (!themeConfig.value.isRequestRoutes) { - // 鍓嶇鎺у埗璺敱锛�2銆佽娉ㄦ剰鎵ц椤哄簭 - const isNoPower = await initFrontEndControlRoutes(); - // console.log(isNoPower,172) - signInSuccess(isNoPower); - } else { - // 妯℃嫙鍚庣鎺у埗璺敱锛宨sRequestRoutes 涓� true锛屽垯寮�鍚悗绔帶鍒惰矾鐢� - // 娣诲姞瀹屽姩鎬佽矾鐢憋紝鍐嶈繘琛� router 璺宠浆锛屽惁鍒欏彲鑳芥姤閿� No match found for location with path "/" - const isNoPower = await initBackEndControlRoutes(); - // 鎵ц瀹� initBackEndControlRoutes锛屽啀鎵ц signInSuccess - // console.log(isNoPower,178) - signInSuccess(isNoPower); - } - } else { - ElMessage.error('鐧诲綍澶辫触锛岃妫�鏌ヨ处鍙凤紒'); - } - } else { - ElMessage.error('鐧诲綍澶辫触锛岃妫�鏌ヨ处鍙凤紒' + (res?.Message ? `锛�${JSON.stringify(res.Message)}` : '')); - } - - // 鐧诲綍鏍¢獙 - // await apiSysAuthLoginPost(params) - // .then(async (res: any) => { - - // }) - // .catch((err: any) => { - // console.log(err); - // }); - }); -}; -// 鐧诲綍鎴愬姛鍚庣殑璺宠浆 -const signInSuccess = (isNoPower: boolean | undefined) => { - if (isNoPower) { - ElMessage.warning('鎮ㄦ病鏈夌櫥褰曟潈闄�'); - clearAccessTokens(); - } else { - // 鍒濆鍖栫櫥褰曟垚鍔熸椂闂撮棶鍊欒 - let currentTimeInfo = currentTime.value; - // 鐧诲綍鎴愬姛锛岃烦鍒拌浆棣栭〉 - // 濡傛灉鏄鍒剁矘璐寸殑璺緞锛岄潪棣栭〉/鐧诲綍椤碉紝閭d箞鐧诲綍鎴愬姛鍚庨噸瀹氬悜鍒板搴旂殑璺緞涓� - // console.log(route.query, 199); - if (route.query?.redirect) { - router.push({ - path: <string>route.query?.redirect, - query: Object.keys(<string>route.query?.params).length > 0 ? JSON.parse(<string>route.query?.params) : '', - }); - } else { - router.push('/'); - } - // 鐧诲綍鎴愬姛鎻愮ず - const signInText = t('message.signInText'); - ElMessage.success(`${currentTimeInfo}锛�${signInText}`); - // 娣诲姞 loading锛岄槻姝㈢涓�娆¤繘鍏ョ晫闈㈡椂鍑虹幇鐭殏绌虹櫧 - NextLoading.start(); - } - state.loading.signIn = false; -}; - -</script> - -<style scoped lang="scss"> -.login-content-form { - margin-top: 20px; - - @for $i from 1 through 4 { - .login-animation#{$i} { - opacity: 0; - animation-name: error-num; - animation-duration: 0.5s; - animation-fill-mode: forwards; - animation-delay: calc($i/10) + s; - } - } - - .login-content-password { - display: inline-block; - width: 20px; - cursor: pointer; - - &:hover { - color: #909399; - } - } - - .login-content-code { - display: flex; - align-items: center; - justify-content: space-around; - - .login-content-code-img { - width: 100%; - height: 40px; - line-height: 40px; - background-color: #ffffff; - border: 1px solid rgb(220, 223, 230); - cursor: pointer; - transition: all ease 0.2s; - border-radius: 4px; - user-select: none; - - &:hover { - border-color: #c0c4cc; - transition: all ease 0.2s; - } - } - } - - .login-content-submit { - width: 100%; - letter-spacing: 2px; - font-weight: 300; - margin-top: 15px; - } -} -</style> diff --git a/src/views/login/index_ch.vue b/src/views/login/index_ch.vue deleted file mode 100644 index 015e166..0000000 --- a/src/views/login/index_ch.vue +++ /dev/null @@ -1,272 +0,0 @@ -<template> - <div class="h100 relative"> - <div class="login-container flex h100"> - <div class="login-left"> - <div class="login-left-logo"> - <img :src="logoMini" /> - <div class="login-left-logo-text"> - <span>{{ getThemeConfig.globalViceTitle }}</span> - <span class="login-left-logo-text-msg">{{ getThemeConfig.globalViceTitleMsg }}</span> - </div> - </div> - <div class="login-left-img"> - <img :src="loginMain" /> - </div> - <img :src="loginBg" class="login-left-waves" /> - </div> - <div class="login-right flex"> - <div class="login-right-warp flex-margin"> - <span class="login-right-warp-one"></span> - <span class="login-right-warp-two"></span> - <div class="login-right-warp-mian"> - <div class="login-right-warp-main-title">{{ getThemeConfig.globalTitle }} 娆㈣繋鎮紒</div> - <div class="login-right-warp-main-form"> - <div v-if="!state.isScan"> - <el-tabs v-model="state.tabsActiveName"> - <el-tab-pane :label="$t('message.label.one1')" name="account"> - <Account /> - </el-tab-pane> - <el-tab-pane :label="$t('message.label.two2')" name="mobile" disabled> - <Mobile /> - </el-tab-pane> - </el-tabs> - </div> - <Scan v-if="state.isScan" /> - <div class="login-content-main-sacn" @click="scanClick"> - <i class="iconfont" :class="state.isScan ? 'icon-diannao1' : 'icon-barcode-qr'"></i> - <div class="login-content-main-sacn-delta"></div> - </div> - </div> - </div> - </div> - </div> - </div> - <LayoutFooter class="footer absolute" v-if="isFooter" /> - </div> -</template> - -<script setup lang="ts" name="loginIndex"> -import { defineAsyncComponent, onMounted, reactive, computed, ref } from 'vue'; -import { storeToRefs } from 'pinia'; -import { useThemeConfig } from '/@/stores/themeConfig'; -import { NextLoading } from '/@/utils/loading'; -const storesThemeConfig = useThemeConfig(); -const { themeConfig } = storeToRefs(storesThemeConfig); -import { useRoute } from 'vue-router'; - -// 寮曞叆缁勪欢 -const Account = defineAsyncComponent(() => import('/@/views/login/component/account.vue')); -const Mobile = defineAsyncComponent(() => import('/@/views/login/component/mobile.vue')); -const Scan = defineAsyncComponent(() => import('/@/views/login/component/scan.vue')); -const LayoutFooter = defineAsyncComponent(() => import('/@/layout/footer/index.vue')); -const route = useRoute(); - -// 璁剧疆 footer 鏄剧ず/闅愯棌 -const isFooter = computed(() => { - return themeConfig.value.isFooter && !route.meta.isIframe; -}); -const state = reactive({ - tabsActiveName: 'account', - isScan: false, -}); - -// 鑾峰彇甯冨眬閰嶇疆淇℃伅 -const getThemeConfig = computed(() => { - return themeConfig.value; -}); -const loginMain = window.globalConfig.SoftWareInfo.loginMain; -const logoMini = window.globalConfig.SoftWareInfo.logoMini; -const loginBg = window.globalConfig.SoftWareInfo.loginBg; -// 椤甸潰鍔犺浇鏃� -onMounted(() => { - NextLoading.done(); -}); - -const scanClick = () => { - // state.isScan = !state.isScan; - return; -}; -</script> - -<style scoped lang="scss"> -.login-container { - height: 100%; - background: var(--el-color-white); - .login-left { - flex: 1; - position: relative; - background-color: rgba(211, 239, 255, 1); - margin-right: 100px; - .login-left-logo { - display: flex; - align-items: center; - position: absolute; - top: 50px; - left: 80px; - z-index: 1; - animation: logoAnimation 0.3s ease; - img { - width: 52px; - height: 52px; - } - .login-left-logo-text { - display: flex; - flex-direction: column; - span { - margin-left: 10px; - font-size: 28px; - color: #26a59a; - } - .login-left-logo-text-msg { - font-size: 12px; - color: #32a99e; - } - } - } - .login-left-img { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 100%; - height: 52%; - img { - width: 100%; - height: 100%; - animation: error-num 0.6s ease; - } - } - .login-left-waves { - position: absolute; - top: 0; - right: -100px; - } - } - .login-right { - width: 700px; - .login-right-warp { - border: 1px solid var(--el-color-primary-light-3); - border-radius: 3px; - width: 500px; - height: 500px; - position: relative; - overflow: hidden; - background-color: var(--el-color-white); - .login-right-warp-one, - .login-right-warp-two { - position: absolute; - display: block; - width: inherit; - height: inherit; - &::before, - &::after { - content: ''; - position: absolute; - z-index: 1; - } - } - .login-right-warp-one { - &::before { - filter: hue-rotate(0deg); - top: 0px; - left: 0; - width: 100%; - height: 3px; - background: linear-gradient(90deg, transparent, var(--el-color-primary)); - animation: loginLeft 3s linear infinite; - } - &::after { - filter: hue-rotate(60deg); - top: -100%; - right: 2px; - width: 3px; - height: 100%; - background: linear-gradient(180deg, transparent, var(--el-color-primary)); - animation: loginTop 3s linear infinite; - animation-delay: 0.7s; - } - } - .login-right-warp-two { - &::before { - filter: hue-rotate(120deg); - bottom: 2px; - right: -100%; - width: 100%; - height: 3px; - background: linear-gradient(270deg, transparent, var(--el-color-primary)); - animation: loginRight 3s linear infinite; - animation-delay: 1.4s; - } - &::after { - filter: hue-rotate(300deg); - bottom: -100%; - left: 0px; - width: 3px; - height: 100%; - background: linear-gradient(360deg, transparent, var(--el-color-primary)); - animation: loginBottom 3s linear infinite; - animation-delay: 2.1s; - } - } - .login-right-warp-mian { - display: flex; - flex-direction: column; - height: 100%; - .login-right-warp-main-title { - height: 130px; - line-height: 130px; - font-size: 27px; - text-align: center; - letter-spacing: 3px; - animation: logoAnimation 0.3s ease; - animation-delay: 0.3s; - color: var(--el-text-color-primary); - } - .login-right-warp-main-form { - flex: 1; - padding: 0 50px 50px; - .login-content-main-sacn { - position: absolute; - top: 0; - right: 0; - width: 50px; - height: 50px; - overflow: hidden; - cursor: pointer; - transition: all ease 0.3s; - color: var(--el-color-primary); - &-delta { - position: absolute; - width: 35px; - height: 70px; - z-index: 2; - top: 2px; - right: 21px; - background: var(--el-color-white); - transform: rotate(-45deg); - } - &:hover { - opacity: 1; - transition: all ease 0.3s; - color: var(--el-color-primary) !important; - } - i { - width: 47px; - height: 50px; - display: inline-block; - font-size: 48px; - position: absolute; - right: 1px; - top: 0px; - } - } - } - } - } - } -} - -.footer { - bottom: 0; -} -</style> -- Gitblit v1.9.3