feat: 完善仪表盘最近访问区块内容(来自 @Bull-BCLS)

This commit is contained in:
Charles7c 2023-09-11 23:00:01 +08:00
parent 36d38aec16
commit 36fda57d49
5 changed files with 100 additions and 9 deletions

View File

@ -32,6 +32,12 @@ export interface DashboardAnnouncementRecord {
type: number; type: number;
} }
export interface DashboardRecentlyVisitedRecord {
title?: string;
path: string;
icon?: string;
}
export function getTotal() { export function getTotal() {
return axios.get<DashboardTotalRecord>(`${BASE_URL}/total`); return axios.get<DashboardTotalRecord>(`${BASE_URL}/total`);
} }

View File

@ -1,7 +1,13 @@
import { createRouter, createWebHistory } from 'vue-router'; import {
createRouter,
createWebHistory,
RouteRecordNormalized,
} from 'vue-router';
import { useAppStore } from '@/store';
import NProgress from 'nprogress'; // progress bar import NProgress from 'nprogress'; // progress bar
import 'nprogress/nprogress.css'; import 'nprogress/nprogress.css';
import { DashboardRecentlyVisitedRecord } from '@/api/common/dashboard';
import { appRoutes, fixedRoutes, demoRoutes } from './routes'; import { appRoutes, fixedRoutes, demoRoutes } from './routes';
import { REDIRECT_MAIN, NOT_FOUND_ROUTE } from './routes/base'; import { REDIRECT_MAIN, NOT_FOUND_ROUTE } from './routes/base';
import createRouteGuard from './guard'; import createRouteGuard from './guard';
@ -36,4 +42,47 @@ const router = createRouter({
createRouteGuard(router); createRouteGuard(router);
router.afterEach((to) => {
const allMenuList = useAppStore().appAsyncMenusAll as RouteRecordNormalized[];
const toMenu = allMenuList.find((m) => to.path === m.path) || undefined;
if (toMenu === undefined) {
return;
}
const recentlyVisitedList = window.localStorage.getItem('recently-visited');
let copyRecentlyVisitedList: DashboardRecentlyVisitedRecord[];
if (recentlyVisitedList === null) {
copyRecentlyVisitedList = [];
} else {
copyRecentlyVisitedList = JSON.parse(recentlyVisitedList);
}
// 是否有重复点击的菜单
copyRecentlyVisitedList.forEach(
(item: DashboardRecentlyVisitedRecord, index: number) => {
if (item.path === to.path) {
copyRecentlyVisitedList.splice(index, 1);
}
}
);
// 最多存储 3 个
const menuMeta = toMenu?.meta;
const recentlyVisited: DashboardRecentlyVisitedRecord = {
title: menuMeta?.locale,
path: to.path,
icon: menuMeta?.icon,
};
copyRecentlyVisitedList.reverse();
copyRecentlyVisitedList.push(recentlyVisited);
copyRecentlyVisitedList.reverse();
if (copyRecentlyVisitedList.length >= 4) {
copyRecentlyVisitedList = copyRecentlyVisitedList.splice(0, 3);
}
window.localStorage.setItem(
'recently-visited',
JSON.stringify(copyRecentlyVisitedList)
);
});
export default router; export default router;

View File

@ -6,6 +6,19 @@ import defaultSettings from '@/config/settings.json';
import { listRoute } from '@/api/auth/login'; import { listRoute } from '@/api/auth/login';
import { AppState } from './types'; import { AppState } from './types';
const recursionMenu = (
appMenu: RouteRecordNormalized[],
list: Array<RouteRecordNormalized>
) => {
appMenu.forEach((item) => {
const childrenAppMenu = item.children as RouteRecordNormalized[];
if (childrenAppMenu != null && childrenAppMenu.length > 0) {
recursionMenu(childrenAppMenu, list);
} else {
list.push(item);
}
});
};
const useAppStore = defineStore('app', { const useAppStore = defineStore('app', {
state: (): AppState => ({ ...defaultSettings }), state: (): AppState => ({ ...defaultSettings }),
@ -19,6 +32,14 @@ const useAppStore = defineStore('app', {
appAsyncMenus(state: AppState): RouteRecordNormalized[] { appAsyncMenus(state: AppState): RouteRecordNormalized[] {
return state.serverMenu as unknown as RouteRecordNormalized[]; return state.serverMenu as unknown as RouteRecordNormalized[];
}, },
appAsyncMenusAll(state: AppState): RouteRecordNormalized[] {
const menuList: RouteRecordNormalized[] = [];
recursionMenu(
state.serverMenu as unknown as RouteRecordNormalized[],
menuList
);
return menuList;
},
}, },
actions: { actions: {

View File

@ -88,6 +88,6 @@
<style scoped lang="less"> <style scoped lang="less">
.general-card { .general-card {
min-height: 568px; min-height: 566.14px;
} }
</style> </style>

View File

@ -7,13 +7,18 @@
> >
<div style="margin-bottom: -1rem"> <div style="margin-bottom: -1rem">
<a-row :gutter="8"> <a-row :gutter="8">
<a-col v-for="link in links" :key="link.text" :span="8" class="wrapper"> <a-col
v-for="link in links"
:key="link.title"
:span="8"
class="wrapper"
>
<div @click="router.replace({ path: link.path })"> <div @click="router.replace({ path: link.path })">
<div class="icon"> <div class="icon">
<svg-icon :icon-class="link.icon" /> <svg-icon :icon-class="link.icon" />
</div> </div>
<a-typography-paragraph class="text"> <a-typography-paragraph class="text">
{{ link.text }} {{ link.title }}
</a-typography-paragraph> </a-typography-paragraph>
</div> </div>
</a-col> </a-col>
@ -23,14 +28,24 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { DashboardRecentlyVisitedRecord } from '@/api/common/dashboard';
const router = useRouter(); const router = useRouter();
const links = [ const links = ref<DashboardRecentlyVisitedRecord[]>();
{ text: '在线用户', icon: 'anonymity', path: '/monitor/online' },
{ text: '代码生成', icon: 'code', path: '/tool/generator' }, /**
{ text: '角色管理', icon: 'safe', path: '/system/role' }, * 加载最近访问菜单列表
]; */
onMounted(() => {
const recentlyVisitedList = window.localStorage.getItem('recently-visited');
if (recentlyVisitedList === null) {
links.value = [];
} else {
links.value = JSON.parse(recentlyVisitedList);
}
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>