feat:路由系统

main
向文可 4 years ago
parent 2752f7f731
commit 77c09a4b48

@ -24,10 +24,11 @@ export function getUserInfo() {
}); });
} }
// 获取权限列表 // 获取权限列表
export function getPermission() { export function getPermission(params) {
return request({ return request({
url: '/u-admin/uc/ucPermission/listUserMenu', url: '/u-admin/uc/ucPermission/listUserMenu',
method: 'get', method: 'get',
params,
}); });
} }
// 退出登录 // 退出登录

@ -16,9 +16,9 @@
box-shadow: @layout-shadow; box-shadow: @layout-shadow;
:deep(.el-scrollbar__view) { :deep(.el-scrollbar__view) {
width: 100%; width: 100%;
min-height: 100%; height: 100%;
> * { > * {
display: inline-block; // BFC // display: inline-block; // BFC
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: @layout-space-large; padding: @layout-space-large;

@ -40,6 +40,9 @@
transition: opacity 0.3s; transition: opacity 0.3s;
} }
} }
:deep(*) {
white-space: nowrap;
}
.title { .title {
width: 100%; width: 100%;
height: @layout-header-height; height: @layout-header-height;

@ -3,7 +3,7 @@
<el-avatar :src="userInfo?.avatar" /> <el-avatar :src="userInfo?.avatar" />
<el-dropdown size="middle" @command="handleCommand"> <el-dropdown size="middle" @command="handleCommand">
<span class="el-dropdown-link"> <span class="el-dropdown-link">
<span>{{ userInfo?.username }}</span> <span>{{ userInfo?.nickname || userInfo?.username }}</span>
<XIcon class="el-icon--right" name="ArrowDown" /> <XIcon class="el-icon--right" name="ArrowDown" />
</span> </span>
<template #dropdown> <template #dropdown>
@ -18,7 +18,7 @@
<script setup> <script setup>
const store = useStore(); const store = useStore();
const userInfo = computed(() => store.state.local.userInfo); const userInfo = computed(() => store.state.auth.userInfo);
const handleCommand = (command) => { const handleCommand = (command) => {
switch (command) { switch (command) {
case 'logout': case 'logout':

@ -27,38 +27,7 @@ Object.values(modules).forEach((mod) => {
dynamicRoutes.push(...mod.default); dynamicRoutes.push(...mod.default);
}); });
export const routes = [ export const routes = [];
...globalRoutes,
{
path: '/',
name: 'App',
redirect: { name: 'Home' },
component: () => import('@/layouts/default.vue'),
meta: {
layout: true,
},
children: [
{
path: '/home',
name: 'Home',
component: () => import('@/views/home/index.vue'),
meta: {
title: '首页',
icon: 'home-line',
},
},
],
},
...dynamicRoutes,
{
path: '/:pathMatch(.*)*',
redirect: '/404',
name: 'NotFound',
meta: {
global: true,
},
},
];
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
@ -69,22 +38,17 @@ import store from '@/store';
router.onError((error, to) => { router.onError((error, to) => {
console.info('[router] error', error, to); console.info('[router] error', error, to);
}); });
import debug from '@/utils/debug';
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
if (!from.matched.length) { if (!from.matched.length) {
store.loadCache(); store.loadCache();
} }
// if (!store.state.auth.userInfo) { if (store.state.local.token) {
// await store.dispatch('auth/getUserInfo'); if (!store.state.auth.permission.length) {
// } await store.dispatch('auth/getUserInfo');
// if (!store.state.auth.permission.length) { await store.dispatch('auth/getPermission');
// await store.dispatch('auth/getPermission'); next({ ...to, replace: true });
// }
if (to.matched.length) {
console.info(`[router] from ${from.name} to ${to.name}`);
if (to.meta.global) {
next();
} else { } else {
console.info(`[router] from ${from.name} to ${to.name}`);
const deep = (route) => { const deep = (route) => {
let child = (route.children || []).find((item) => !item.meta?.hidden); let child = (route.children || []).find((item) => !item.meta?.hidden);
return child?.children?.length ? deep(child?.children) : child?.name; return child?.children?.length ? deep(child?.children) : child?.name;
@ -101,6 +65,10 @@ router.beforeEach(async (to, from, next) => {
store.commit('layout/addTab', to); store.commit('layout/addTab', to);
} }
} }
} else if (to.meta.global) {
next();
} else {
next({ name: 'Login' });
} }
}); });
@ -111,6 +79,17 @@ export const reset = (routers) => {
router.getRoutes().forEach((item) => { router.getRoutes().forEach((item) => {
router.removeRoute(item.name); router.removeRoute(item.name);
}); });
flat(routers).forEach(router.addRoute); flat([
...globalRoutes,
...routers,
{
path: '/:pathMatch(.*)*',
redirect: '/404',
name: 'NotFound',
meta: {
global: true,
},
},
]).forEach(router.addRoute);
console.info('[router] reset', router.getRoutes()); console.info('[router] reset', router.getRoutes());
}; };

@ -1,23 +1,7 @@
import { getUserInfo, getPermission } from '@/api/auth'; import { getUserInfo, getPermission, sendSmsCode, login } from '@/api/auth';
import { ElMessage } from '@/plugins/element-plus'; import { ElMessage } from '@/plugins/element-plus';
const sms = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, 1000);
});
};
const login = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
token: 'eyJhbGciOiJSUzI1NiJ9.eyJ1aWQiOjEzMjI1LCJwaG9uZSI6IjEzMjAyMDkwNjAxIiwibG9naW5UeXBlIjo1LCJ1c2VyTm8iOiIxMzIyNSIsIm5pY2tuYW1lIjoi5b-D5LmL5omA5ZCRIiwiZGVwdElkIjpudWxsLCJleHAiOjE2Nzg5NzI5NjksInVzZXJuYW1lIjoiTUNBLTMzYTkifQ.bDgxrGWUYW1iGLQidoj3q4lBXTlI0zKMBslIjN5LuvyLE4O8LPfFFYh33nAlevKuey_tqYQSWn0Cvm81Ywuksn70lGyy5-BEBbLUQCXaFKaWXujc2FzWFIvPHzAXfF16aUzyKkCppR5tfLDQz5cimLHAQBw24Ar69UCMiYJjN8E',
});
}, 1000);
});
};
import router, { reset as resetRoutes } from '@/router'; import router, { reset as resetRoutes } from '@/router';
const modules = import.meta.glob('../views/*/*.vue'); const viewComponents = import.meta.glob('../../views/**/*.vue');
const state = () => ({ const state = () => ({
userInfo: null, userInfo: null,
permission: [], permission: [],
@ -40,7 +24,7 @@ const mutations = {
}, },
}; };
if (!route.path.startsWith('/')) { if (!route.path.startsWith('/')) {
route.path = parent.path + route.path; route.path = parent.path + '/' + route.path;
} }
route.meta.menu = route.path.replaceAll(/\/:[^?]+\?/g, ''); route.meta.menu = route.path.replaceAll(/\/:[^?]+\?/g, '');
let activeMenu = route.meta.activeMenu; let activeMenu = route.meta.activeMenu;
@ -52,12 +36,15 @@ const mutations = {
if (route.component === 'Layout') { if (route.component === 'Layout') {
route.component = () => import('@/layouts/default.vue'); route.component = () => import('@/layouts/default.vue');
} else { } else {
let path = `../views/${route.component}`; let path = `../../views/${route.component}`;
if (!path.endsWith('.vue')) { if (!path.endsWith('.vue')) {
path += '.vue'; path += '.vue';
} }
let alias = path.replace(/\.vue$/, '/index.vue'); let alias = path.replace(/\.vue$/, '/index.vue');
route.component = modules[path] || modules[alias]; route.component = viewComponents[path] || viewComponents[alias];
if (!route.component) {
route.component = () => import('@/views/global/404.vue');
}
} }
} }
route.children = convert(item.children || [], route); route.children = convert(item.children || [], route);
@ -66,12 +53,12 @@ const mutations = {
}); });
}; };
state.permission = convert(data); state.permission = convert(data);
// resetRoutes(state.permission); resetRoutes(state.permission);
}, },
}; };
const actions = { const actions = {
sms: async ({ commit }, data) => { sms: async ({ commit }, data) => {
let res = await sms(data); let res = await sendSmsCode(data);
if (res) { if (res) {
ElMessage.success('验证码已发送'); ElMessage.success('验证码已发送');
commit('local/sendMessage', {}, { root: true }); commit('local/sendMessage', {}, { root: true });
@ -96,7 +83,7 @@ const actions = {
router.push({ name: 'Login' }); router.push({ name: 'Login' });
}, },
getPermission: async ({ commit }) => { getPermission: async ({ commit }) => {
let res = await getPermission(); let res = await getPermission({ systemCode: 'msb_shop_admin' });
if (res) { if (res) {
commit('setPermission', res); commit('setPermission', res);
} else { } else {

@ -1,4 +1,4 @@
import router, { routes } from '@/router'; import router from '@/router';
const state = () => ({ const state = () => ({
activeAside: null, activeAside: null,
collapseAside: false, collapseAside: false,
@ -9,10 +9,10 @@ const state = () => ({
breakcrumbList: [], breakcrumbList: [],
}); });
const getters = { const getters = {
asideList: () => { asideList: (state, getters, rootState) => {
const deep = (arr) => const deep = (arr) =>
arr.flatMap((item) => (item.meta?.layout ? deep(item.children || []) : item.meta?.global ? [] : item)); arr.flatMap((item) => (item.meta?.layout ? deep(item.children || []) : item.meta?.global ? [] : item));
return deep(routes); return deep(rootState.auth.permission);
}, },
collapseAside: (state) => state.collapseAside || state.menuList.length < 2, collapseAside: (state) => state.collapseAside || state.menuList.length < 2,
activeAsideName: (state, getters) => getters.asideList.find((item) => item.name === state.activeAside)?.meta.title, activeAsideName: (state, getters) => getters.asideList.find((item) => item.name === state.activeAside)?.meta.title,

@ -54,8 +54,8 @@
<style lang="less" scoped> <style lang="less" scoped>
.container { .container {
width: 100vw; width: 100%;
height: 100vh; height: 100%;
background: #000 url('~/global/login-bgp.png') center center / 100% 100% no-repeat; background: #000 url('~/global/login-bgp.png') center center / 100% 100% no-repeat;
display: flex; display: flex;
justify-content: center; justify-content: center;

@ -36,7 +36,7 @@
const form = reactive({ msg: '123' }); const form = reactive({ msg: '123' });
</script> </script>
<style lang="less"> <style lang="less" scoped>
.container { .container {
height: 2000px !important; height: 2000px !important;
} }

@ -0,0 +1,7 @@
<template>
<div>权限列表</div>
</template>
<script setup></script>
<style lang="less" scoped></style>

@ -0,0 +1,7 @@
<template>
<div>角色列表</div>
</template>
<script setup></script>
<style lang="less" scoped></style>

@ -0,0 +1,7 @@
<template>
<div>用户列表</div>
</template>
<script setup></script>
<style lang="less" scoped></style>
Loading…
Cancel
Save