refactor: ♻️ 优化登录逻辑代码

This commit is contained in:
jqtmviyu 2025-03-30 20:15:58 +08:00
parent b4bf0e05de
commit 63b3adfa2c
2 changed files with 123 additions and 123 deletions

View File

@ -1,24 +1,68 @@
# resource-manage
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
## 部分业务逻辑
### 登录流程
```mermaid
graph TD;
A[前置路由守卫] --> B{ query.token 是否存在?}
%% TAPD 登录流程
B -->|是| C[清除本地 token]
C --> D[调用 fetchToken]
D --> E{获取 token 成功?}
E -->|是| F[保存 token 到 localStorage<br/>重定向并移除 URL token 参数]
E -->|否| G[处理登录失败]
%% 无 token 流程
B -->|否| H{检查 Vuex 和 localStorage<br/>是否有 token?}
H -->|都没有| I[显示 token 错误<br/>中断导航]
%% 恢复 token 流程
H -->|localStorage 有 Vuex 没有| J[恢复 token 到 Vuex]
J --> L
%% 加载路由流程
H -->|Vuex 有| L{检查动态路由是否为空?}
L -->|是| M[获取路由资源]
M --> N[生成动态路由]
N --> O{是否为管理员?}
O -->|是| P[添加系统设置路由]
O -->|否| Q[继续导航]
P --> Q
L -->|否| Q
%% 登录失败处理
G --> R{是否不在白名单?}
R -->|是| S[跳转到登录失败页面<br/>中断导航]
R -->|否| T[提示点击TAPD导航栏刷新<br/>中断导航]
```

View File

@ -3,7 +3,7 @@ import VueRouter from "vue-router";
import store from "@/index/store";
import { generateIndexRouter } from "./generateIndexRouter";
import systemSettings from './systemSettings'
// import { accessTokenError } from "@/index/utils/errorModal";
import { accessTokenError } from "@/index/utils/errorModal";
// hack router push callback
const originalPush = VueRouter.prototype.push;
@ -34,130 +34,86 @@ const router = new VueRouter({
let dynamicRoutes = [];
router.beforeEach(async(to, from, next)=>{
// 1. 从tapd进来, 重定向路由参数带token
// if(to.query.token){
// // 1.1 先删除本地存储
// Vue.ls.remove('token')
// // 1.2 设置token
// const tmp_token = to.query.token
// let formData = new FormData()
// formData.append("tmp_token", tmp_token)
// await store.dispatch('user/getToken', formData)
// if(store.state.user.token){
// // 1.2.1 能拿到正式token,保存token
// Vue.ls.set('token',store.state.user.token)
// // 跳转,去掉路由参数
// next({ path: to.path })
// }else{
// // 1.2.2 拿不到token
// // 1.2.2.1 判断是不是因为没有添加进白名单
// if(store.state.user.loginFailed){
// next({path: '/loginFailed'})
// }else{
// // 1.2.2.2 判断是否已弹提示
// if(!Vue.prototype.$closeModalFun){
// Vue.prototype.$closeModalFun = accessTokenError('获取token失败请点击左边导航栏应用“资源管理”重试。')
// }
// next(false)
// }
// }
// }else{
// 2. 不是从tapd进来
// 2.1 检查token
// if(!store.state.user.token && !store.state.user.loginFailed){
// const token = Vue.ls.get('token')
// if(token){
// store.commit('user/changeToken', token)
// }else {
// if(!Vue.prototype.$closeModalFun){
// Vue.prototype.$closeModalFun = accessTokenError('获取token失败请点击左边导航栏应用“资源管理”重试。')
// }
// // 拿不到token, 弹窗并停止
// next(false)
// }
// }
store.commit('user/changeToken', '123456')
// 2.2 没有路由, 生成路由
if ( store.state.user.token && dynamicRoutes.length === 0) {
// 获取用户信息
await store.dispatch('user/getUserInfo')
store
.dispatch("user/getRoutesResource")
.then((routesResource) => {
dynamicRoutes = generateIndexRouter(routesResource)
router.addRoutes(dynamicRoutes)
// 是管理员, 添加设置页面路由
if(store.state.user.isAdmin){
router.addRoutes([systemSettings]);
}
})
.catch((err) => {
Vue.prototype.$error("请求用户资源失败");
console.log(err)
next(false)
})
router.beforeEach(async (to, from, next) => {
const { token: queryToken } = to.query;
const userState = store.state.user;
// const storageToken = Vue.ls.get("token");
const storageToken = Vue.ls.get("token")||'123test'; // 离线状态测试用
// 1. 从 TAPD 入口进来, 更新token并重定向
if (queryToken) return handleTapdLogin(queryToken, to, next);
// 2. Vuex 和本地存储都没有 token处理登录失败情况, 结束导航
if (!userState.token && !storageToken) return handleNoToken(next);
// 3. Vuex 没有 token但 localStorage 有,恢复 token
if (!userState.token && storageToken) restoreToken(storageToken);
// 4. Vuex 有 token但还没有动态路由获取用户资源, 生成动态路由
if (userState.token && dynamicRoutes.length === 0) loadRoutes(userState.isAdmin, next);
// 5. 放行
next();
});
/** 处理从 TAPD 入口进来的情况 */
async function handleTapdLogin(queryToken, to, next) {
Vue.ls.remove("token"); // 清除本地 token
if (await fetchToken(queryToken)) {
Vue.ls.set("token", store.state.user.token);
return next({ path: to.path, query: {} }); // 移除 URL 中的 token 参数
}
return handleLoginFailure(next);
}
/** 通过临时 token 获取正式 token */
async function fetchToken(tmpToken) {
const formData = new FormData();
formData.append("tmp_token", tmpToken);
await store.dispatch("user/getToken", formData);
return Boolean(store.state.user.token);
}
/** 处理没有 token 的情况 */
function handleNoToken(next) {
showTokenError();
next(false);
}
/** 从 localStorage 恢复 token */
function restoreToken(token) {
store.commit("user/changeToken", token);
}
/** 生成并加载动态路由 */
async function loadRoutes(isAdmin, next) {
try {
const routesResource = await store.dispatch("user/getRoutesResource");
dynamicRoutes = generateIndexRouter(routesResource);
router.addRoutes(dynamicRoutes);
if (isAdmin) {
router.addRoutes([systemSettings]);
}
// 2.4 已有路由
next()
// }
} catch (err) {
Vue.prototype.$error("请求用户资源失败");
console.error(err);
next(false);
}
}
/** 处理登录失败情况 */
function handleLoginFailure(next) {
return store.state.user.loginFailed ? next({ path: "/loginFailed" }) : showTokenError(next);
}
// if(!store.state.token){
// // if(false){
// const CURRENT_USER = localStorage.getItem('uid') || to.query["CURRENT-USER"];
// // debugger
// store.commit('saveUid', CURRENT_USER);
// localStorage.setItem('uid', CURRENT_USER);
// const token = localStorage.getItem('token');
// if(token){
// store.commit('changeToken', token);
// localStorage.removeItem('token');
// next({ path: to.path });
// }else{
// const tmp_token = to.query.token;
// if (tmp_token) {
// let formData = new FormData();
// formData.append("tmp_token", tmp_token);
// await store.dispatch('getToken', formData);
// if(store.state.token){
// // localStorage.setItem('token',store.state.token);
// next({ path: to.path });
// }else{
// if(!Vue.prototype.$closeModalFun){
// Vue.prototype.$closeModalFun = accessTokenError('获取token失败请点击左边导航栏应用“资源管理”重试。');
// }
// next(false);
// }
// }else{
// if(!Vue.prototype.$closeModalFun){
// Vue.prototype.$closeModalFun = accessTokenError('获取临时token失败请点击左边导航栏应用“资源管理”重试。');
// }
// next(false);
// }
// }
// }else{
// if (dynamicRoutes.length === 0) {
// store
// .dispatch("user/getRoutesResource")
// .then((routesResource) => {
// dynamicRoutes = generateIndexRouter(routesResource);
// router.addRoutes(dynamicRoutes);
// if(store.state.isAdmin){
// router.addRoutes([systemSettings]);
// }
// next({ path: to.path, query: to.query });
// })
// .catch((err) => {
// Vue.prototype.$error("请求用户资源失败");
// console.log(err);
// next(false);
// });
// } else {
// next();
// }
// }
})
/** 显示 token 相关的错误提示 */
function showTokenError() {
if (!Vue.prototype.$closeModalFun) {
Vue.prototype.$closeModalFun = accessTokenError("获取 token 失败,请点击左边导航栏应用“资源管理”重试。");
}
}
export default router;