fix:登录增加记住密码 优化路由逻辑
This commit is contained in:
@@ -110,12 +110,13 @@ const router = useRouter();
|
||||
const route = useRoute();
|
||||
const userStore = useUserStore();
|
||||
const tokenManager = TokenManager.getInstance();
|
||||
const KEEP_KEY = "keep_login_remember";
|
||||
const loginFormRef = ref<FormInstance>();
|
||||
const loading = ref(false);
|
||||
|
||||
const loginForm = reactive({
|
||||
username: "18280362106",
|
||||
password: "123456789",
|
||||
username: "",
|
||||
password: "",
|
||||
remember:false
|
||||
});
|
||||
|
||||
@@ -159,22 +160,46 @@ const handleLogin = async () => {
|
||||
userStore.setToken(refresh_token);
|
||||
// 获取用户信息
|
||||
userStore.setUserInfo(userInfo);
|
||||
// TODO:记住密码功能
|
||||
// 记住密码功能
|
||||
if (loginForm.remember) {
|
||||
const saveInfo = {
|
||||
username: loginForm.username,
|
||||
password: loginForm.password // TODO:密码要加密才行
|
||||
};
|
||||
tokenManager.setToken(KEEP_KEY, JSON.stringify(saveInfo));
|
||||
} else {
|
||||
// 如果用户取消勾选,则移除
|
||||
tokenManager.removeToken(KEEP_KEY);
|
||||
}
|
||||
|
||||
ElMessage.success("登录成功");
|
||||
|
||||
// 跳转到首页或之前访问的页面
|
||||
const redirect = (route.query.redirect as string) || "/";
|
||||
router.push(redirect);
|
||||
const redirect = (route.query.redirect as string);
|
||||
router.push({path:'/',query:redirect});
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error("Login error:", error);
|
||||
ElMessage.error(error.error || "登录失败,请稍后重试");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
const savedInfo = tokenManager.getToken(KEEP_KEY);
|
||||
if (savedInfo) {
|
||||
try {
|
||||
const { username, password } = JSON.parse(savedInfo);
|
||||
loginForm.username = username;
|
||||
loginForm.password = password;
|
||||
loginForm.remember = true;
|
||||
} catch (e) {
|
||||
console.error("解析记住的密码失败", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -128,6 +128,29 @@ const transformRoutes = (
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 递归查找路由配置中的第一个有效路径(叶子节点)
|
||||
*/
|
||||
const getFirstValidPath = (routes: RouteRecordRaw[], parentPath: string = "") => {
|
||||
for (const route of routes) {
|
||||
// 拼接当前层级的完整路径
|
||||
let currentPath = route.path.startsWith("/")
|
||||
? route.path
|
||||
: `${parentPath}/${route.path}`.replace(/\/+/g, "/");
|
||||
|
||||
// 如果有子路由,继续递归,并将当前路径传下去
|
||||
if (route.children && route.children.length > 0) {
|
||||
const childPath = getFirstValidPath(route.children, currentPath);
|
||||
if (childPath) return childPath;
|
||||
}
|
||||
|
||||
// 如果是叶子节点(有组件),返回拼接好的完整路径
|
||||
if (route.component) {
|
||||
return currentPath;
|
||||
}
|
||||
}
|
||||
return "/";
|
||||
};
|
||||
|
||||
// 添加动态路由
|
||||
const addDynamicRoutes = async () => {
|
||||
@@ -140,7 +163,7 @@ const addDynamicRoutes = async () => {
|
||||
|
||||
try {
|
||||
// 从后端获取路由菜单数据 (这边需要区分 后台的菜单 和用户的菜单)
|
||||
let allRoutes:any[] = [];
|
||||
let allRoutes: any[] = [];
|
||||
if (userStore.isBackendUser) {
|
||||
// const backendResponse = await getRouteMenus();
|
||||
const backendResponse = [];
|
||||
@@ -149,10 +172,12 @@ const addDynamicRoutes = async () => {
|
||||
code: "stage",
|
||||
name: "管理中心",
|
||||
icon: "",
|
||||
meta:{
|
||||
title:'管理中心'
|
||||
meta: {
|
||||
title: "管理中心",
|
||||
},
|
||||
children: Object.keys(backendResponse).length ? backendResponse : mockBackendMenuData,
|
||||
children: Object.keys(backendResponse).length
|
||||
? backendResponse
|
||||
: mockBackendMenuData,
|
||||
},
|
||||
];
|
||||
} else {
|
||||
@@ -222,7 +247,7 @@ router.beforeEach(async (to, _from, next) => {
|
||||
// 未登录,重定向到登录页
|
||||
next({
|
||||
path: "/login",
|
||||
query: { redirect: to.fullPath }, // 保存当前路径,登录后可以跳转回来
|
||||
query: { redirect: to.fullPath },
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -232,15 +257,29 @@ router.beforeEach(async (to, _from, next) => {
|
||||
try {
|
||||
// 加载动态路由
|
||||
await addDynamicRoutes();
|
||||
// 路由加载完成后,重新导航到目标路由
|
||||
next({ ...to, replace: true });
|
||||
console.log("当前完整路由表:", router.getRoutes());
|
||||
const redirect = to.query.redirect as string;
|
||||
|
||||
if (to.path === "/" || to.path === "/login") {
|
||||
const redirect = to.query.redirect as string;
|
||||
const firstPath = getFirstValidPath(userStore.routes);
|
||||
const targetPath = (redirect && redirect !== '/') ? redirect : firstPath;
|
||||
next({ path: targetPath, replace: true });
|
||||
} else {
|
||||
// 路由加载完成后,重新导航到目标路由
|
||||
next({ ...to, replace: true });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Route loading error:", error);
|
||||
next("/login");
|
||||
}
|
||||
} else {
|
||||
// 路由已加载,直接放行
|
||||
next();
|
||||
if (to.path === "/") {
|
||||
const firstPath = getFirstValidPath(userStore.routes);
|
||||
next({ path: firstPath, replace: true });
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -2,11 +2,16 @@ class TokenManager {
|
||||
private static instance: TokenManager | null = null;
|
||||
private storage: Storage;
|
||||
|
||||
private constructor(storageType: 'localStorage' | 'sessionStorage' = 'localStorage') {
|
||||
this.storage = storageType === 'localStorage' ? localStorage : sessionStorage;
|
||||
private constructor(
|
||||
storageType: "localStorage" | "sessionStorage" = "localStorage"
|
||||
) {
|
||||
this.storage =
|
||||
storageType === "localStorage" ? localStorage : sessionStorage;
|
||||
}
|
||||
|
||||
public static getInstance(storageType: 'localStorage' | 'sessionStorage' = 'localStorage'): TokenManager {
|
||||
public static getInstance(
|
||||
storageType: "localStorage" | "sessionStorage" = "localStorage"
|
||||
): TokenManager {
|
||||
if (!TokenManager.instance) {
|
||||
TokenManager.instance = new TokenManager(storageType);
|
||||
}
|
||||
@@ -25,9 +30,13 @@ class TokenManager {
|
||||
this.storage.removeItem(key);
|
||||
}
|
||||
clearStorage(): void {
|
||||
this.storage.clear();
|
||||
const PROTECT_PREFIX = "keep_";
|
||||
Object.keys(this.storage).forEach((key) => {
|
||||
if (!key.startsWith(PROTECT_PREFIX)) {
|
||||
this.storage.removeItem(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default TokenManager;
|
||||
Reference in New Issue
Block a user