更新oa代码
This commit is contained in:
@@ -33,16 +33,15 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { useAllDataStore } from '@/stores';
|
||||
import { getAllMenus, getTenantMenus } from '@/api/menu';
|
||||
import { useAllDataStore, useMenuStore } from '@/stores';
|
||||
import MenuTreeItem from './MenuTreeItem.vue';
|
||||
|
||||
const emit = defineEmits(['menu-click']);
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const list = ref([]);
|
||||
const loading = ref(true);
|
||||
const menuStore = useMenuStore();
|
||||
const loading = computed(() => menuStore.loading);
|
||||
|
||||
const store = useAllDataStore();
|
||||
const isCollapse = computed(() => store.state.isCollapse);
|
||||
@@ -192,43 +191,31 @@ const transformMenuData = (menus) => {
|
||||
return rootMenus;
|
||||
};
|
||||
|
||||
// 获取菜单数据
|
||||
// 获取菜单数据(从 store)
|
||||
const fetchMenus = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
// 获取用户信息,判断登录类型
|
||||
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}');
|
||||
const loginType = userInfo.type; // "user" 或 "employee"
|
||||
const roleId = userInfo.role; // 角色ID
|
||||
|
||||
let res;
|
||||
if (loginType === "employee" && roleId) {
|
||||
// 员工登录,使用getTenantMenus接口
|
||||
res = await getTenantMenus(roleId);
|
||||
} else {
|
||||
// 用户登录,使用getAllMenus接口
|
||||
res = await getAllMenus();
|
||||
}
|
||||
|
||||
if (res && res.success && res.data) {
|
||||
const menuData = res.data;
|
||||
// 转换并排序菜单数据
|
||||
const transformedMenus = transformMenuData(menuData);
|
||||
list.value = transformedMenus;
|
||||
} else {
|
||||
console.error('获取菜单失败:', res?.message || '未知错误');
|
||||
list.value = [];
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
await menuStore.fetchMenus();
|
||||
// 菜单数据会自动通过 computed 更新
|
||||
} catch (error) {
|
||||
console.error('获取菜单异常:', error);
|
||||
list.value = [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 监听 store 中的菜单数据变化,自动转换格式
|
||||
const list = computed(() => {
|
||||
const menuData = menuStore.menus;
|
||||
if (!menuData || menuData.length === 0) {
|
||||
return [];
|
||||
}
|
||||
// 转换并排序菜单数据
|
||||
return transformMenuData(menuData);
|
||||
});
|
||||
|
||||
// 监听菜单缓存刷新事件的处理函数(需要在外部定义以便在 onUnmounted 中使用)
|
||||
const handleMenuRefresh = () => {
|
||||
fetchMenus();
|
||||
};
|
||||
|
||||
// 组件挂载时初始化主题监听和获取菜单
|
||||
onMounted(() => {
|
||||
// 初始化主题监听
|
||||
@@ -250,7 +237,7 @@ onMounted(() => {
|
||||
}, 100);
|
||||
|
||||
// 监听菜单缓存刷新事件
|
||||
window.addEventListener('menu-cache-refreshed', fetchMenus);
|
||||
window.addEventListener('menu-cache-refreshed', handleMenuRefresh);
|
||||
});
|
||||
|
||||
// 组件卸载时清理事件监听
|
||||
@@ -258,7 +245,7 @@ onUnmounted(() => {
|
||||
if (themeObserver) {
|
||||
themeObserver.disconnect();
|
||||
}
|
||||
window.removeEventListener('menu-cache-refreshed', fetchMenus);
|
||||
window.removeEventListener('menu-cache-refreshed', handleMenuRefresh);
|
||||
});
|
||||
|
||||
// 计算属性:统一排序所有菜单项(不再区分有无子菜单)
|
||||
|
||||
@@ -59,10 +59,9 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onUnmounted } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { useAllDataStore } from "@/stores";
|
||||
import { useAllDataStore, useMenuStore } from "@/stores";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { User, SwitchButton, Sunny, Moon, Refresh } from '@element-plus/icons-vue';
|
||||
import { getAllMenus, getTenantMenus } from '@/api/menu';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const router = useRouter();
|
||||
@@ -80,104 +79,36 @@ interface Breadcrumb {
|
||||
path: string;
|
||||
}
|
||||
|
||||
const menuList = ref<Menu[]>([]);
|
||||
const menuStore = useMenuStore();
|
||||
const cacheLoading = ref(false);
|
||||
const MENU_CACHE_KEY = 'menu_cache';
|
||||
|
||||
// 从缓存加载菜单
|
||||
function loadMenuFromCache(): Menu[] | null {
|
||||
try {
|
||||
const cached = localStorage.getItem(MENU_CACHE_KEY);
|
||||
if (cached) {
|
||||
const menuData = JSON.parse(cached);
|
||||
// 检查缓存是否过期(可选:设置过期时间,这里暂时不设置)
|
||||
return menuData;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load menu from cache', error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// 使用 store 中的菜单数据
|
||||
const menuList = computed(() => menuStore.menus);
|
||||
|
||||
// 保存菜单到缓存
|
||||
function saveMenuToCache(menus: Menu[]) {
|
||||
try {
|
||||
localStorage.setItem(MENU_CACHE_KEY, JSON.stringify(menus));
|
||||
} catch (error) {
|
||||
console.error('Failed to save menu to cache', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 从API加载菜单
|
||||
async function loadMenuFromAPI(updateCache = true) {
|
||||
try {
|
||||
// 获取用户信息,判断登录类型
|
||||
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}');
|
||||
const loginType = userInfo.type; // "user" 或 "employee"
|
||||
const roleId = userInfo.role; // 角色ID
|
||||
|
||||
let res;
|
||||
if (loginType === "employee" && roleId) {
|
||||
// 员工登录,使用getTenantMenus接口
|
||||
res = await getTenantMenus(roleId);
|
||||
} else {
|
||||
// 用户登录,使用getAllMenus接口
|
||||
res = await getAllMenus();
|
||||
}
|
||||
|
||||
const menus = res.data || [];
|
||||
if (updateCache && menus.length > 0) {
|
||||
saveMenuToCache(menus);
|
||||
}
|
||||
return menus;
|
||||
} catch (error) {
|
||||
console.error('Failed to load menu from API', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// 加载菜单(优先从缓存)
|
||||
// 加载菜单(从 store)
|
||||
async function loadMenu() {
|
||||
// 先尝试从缓存加载
|
||||
const cachedMenus = loadMenuFromCache();
|
||||
if (cachedMenus && cachedMenus.length > 0) {
|
||||
menuList.value = cachedMenus;
|
||||
// 异步更新缓存(后台更新,不阻塞UI)
|
||||
loadMenuFromAPI(true).then(menus => {
|
||||
if (menus.length > 0) {
|
||||
menuList.value = menus;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 缓存不存在,从API加载
|
||||
menuList.value = await loadMenuFromAPI(true);
|
||||
}
|
||||
await menuStore.fetchMenus();
|
||||
}
|
||||
|
||||
// 更新缓存(手动刷新)
|
||||
async function refreshCache() {
|
||||
cacheLoading.value = true;
|
||||
try {
|
||||
const menus = await loadMenuFromAPI(true);
|
||||
if (menus.length > 0) {
|
||||
menuList.value = menus;
|
||||
|
||||
// 重新加载动态路由
|
||||
const { loadAndAddDynamicRoutes, resetDynamicRoutes } = await import('@/router/index');
|
||||
// 重置路由加载状态,强制重新加载
|
||||
resetDynamicRoutes();
|
||||
await loadAndAddDynamicRoutes();
|
||||
|
||||
// 等待路由完全加载(给Vue Router一些时间更新路由表)
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
|
||||
// 触发菜单刷新事件,通知CommonAside组件刷新菜单
|
||||
window.dispatchEvent(new CustomEvent('menu-cache-refreshed'));
|
||||
|
||||
ElMessage.success('菜单缓存和路由更新成功');
|
||||
} else {
|
||||
ElMessage.warning('未获取到菜单数据');
|
||||
}
|
||||
await menuStore.refreshMenus();
|
||||
|
||||
// 重新加载动态路由
|
||||
const { loadAndAddDynamicRoutes, resetDynamicRoutes } = await import('@/router/index');
|
||||
// 重置路由加载状态,强制重新加载
|
||||
resetDynamicRoutes();
|
||||
await loadAndAddDynamicRoutes();
|
||||
|
||||
// 等待路由完全加载(给Vue Router一些时间更新路由表)
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
|
||||
// 触发菜单刷新事件,通知CommonAside组件刷新菜单
|
||||
window.dispatchEvent(new CustomEvent('menu-cache-refreshed'));
|
||||
|
||||
ElMessage.success('菜单缓存和路由更新成功');
|
||||
} catch (error) {
|
||||
console.error('Failed to refresh cache', error);
|
||||
ElMessage.error('更新缓存失败,请检查网络连接');
|
||||
@@ -260,7 +191,7 @@ const handleCommand = async (command) => {
|
||||
localStorage.removeItem('active_tab');
|
||||
sessionStorage.removeItem('tabs_list');
|
||||
// 清除菜单缓存
|
||||
localStorage.removeItem(MENU_CACHE_KEY);
|
||||
menuStore.resetMenus();
|
||||
|
||||
// 重置 tabs store 状态
|
||||
const { useTabsStore } = await import('@/stores');
|
||||
|
||||
Reference in New Issue
Block a user