import { defineStore } from 'pinia'; import { ref, computed } from 'vue'; import request from '@/utils/request'; export interface MenuApiConfig { // 接口URL apiUrl?: string; // 请求方法 method?: 'GET' | 'POST'; // 请求参数 params?: Record; // 数据提取路径,从接口响应中提取数量的路径 dataPath?: string; // 是否为父级菜单(数字由子菜单汇总而来,不调用接口) isParent?: boolean; // 子菜单路径列表(仅当isParent为true时有效) children?: string[]; } export const useSideNumStore = defineStore('sideNum', () => { // 存储每个菜单路径对应的气泡数量 const menuCounts = ref>({}); // 存储每个菜单路径对应的接口配置 const menuApiConfigs = ref>({}); // 获取指定菜单路径的气泡数量 const getMenuCount = (menuPath: string): number => { const config = menuApiConfigs.value[menuPath]; // 如果是父级菜单,计算子菜单数量总和 if (config && config.isParent && config.children) { return config.children.reduce((total, childPath) => { return total + (menuCounts.value[childPath] || 0); }, 0); } // 普通菜单直接返回存储的数量 return menuCounts.value[menuPath] || 0; }; // 获取所有有数量的菜单项 const getActiveMenus = computed(() => { const activeMenus: Record = {}; // 遍历所有已配置的菜单 Object.keys(menuApiConfigs.value).forEach((key) => { const config = menuApiConfigs.value[key]; let count = 0; if (config.isParent && config.children) { // 父级菜单:使用存储的值,如果没有则计算子菜单总和 count = menuCounts.value[key] || config.children.reduce((total, childPath) => { return total + (menuCounts.value[childPath] || 0); }, 0); } else { // 普通菜单:直接使用存储的值 count = menuCounts.value[key] || 0; } if (count > 0) { activeMenus[key] = count; } }); return activeMenus; }); // 获取总的未处理数量 const getTotalCount = computed(() => { // 只计算非父级菜单的数量,避免重复计算 return Object.keys(menuApiConfigs.value).reduce((total, menuPath) => { const config = menuApiConfigs.value[menuPath]; if (!config.isParent) { return total + (menuCounts.value[menuPath] || 0); } return total; }, 0); }); // 设置菜单接口配置 const setMenuApiConfig = (menuPath: string, config: MenuApiConfig) => { menuApiConfigs.value[menuPath] = { method: 'GET', dataPath: 'data.count', // 默认数据路径 isParent: false, // 默认不是父级菜单 ...config }; }; // 设置父级菜单配置(数字由子菜单汇总) const setParentMenuConfig = (menuPath: string, children: string[]) => { menuApiConfigs.value[menuPath] = { apiUrl: '', // 父级菜单不需要接口URL isParent: true, children: children }; }; // 批量设置多个父级菜单的配置项 const setMultipleParentConfigs = (configs: Record) => { Object.keys(configs).forEach((menuPath) => { setParentMenuConfig(menuPath, configs[menuPath]); }); }; // 批量设置多个菜单的接口配置 const setMultipleApiConfigs = (configs: Record) => { Object.keys(configs).forEach((menuPath) => { setMenuApiConfig(menuPath, configs[menuPath]); }); }; // 更新指定菜单的气泡数量 const updateMenuCount = (menuPath: string, count: number) => { menuCounts.value[menuPath] = Math.max(0, count); // 确保数量不为负数 // 自动更新包含此子菜单的父级菜单数量 Object.keys(menuApiConfigs.value).forEach((parentPath) => { const config = menuApiConfigs.value[parentPath]; if (config.isParent && config.children && config.children.includes(menuPath)) { // 重新计算父级菜单数量 const parentCount = config.children.reduce((total, childPath) => { return total + (menuCounts.value[childPath] || 0); }, 0); menuCounts.value[parentPath] = parentCount; } }); }; // 清空指定菜单的气泡数量 const clearMenuCount = (menuPath: string) => { menuCounts.value[menuPath] = 0; // 自动更新包含此子菜单的父级菜单数量 Object.keys(menuApiConfigs.value).forEach((parentPath) => { const config = menuApiConfigs.value[parentPath]; if (config.isParent && config.children && config.children.includes(menuPath)) { // 重新计算父级菜单数量 const parentCount = config.children.reduce((total, childPath) => { return total + (menuCounts.value[childPath] || 0); }, 0); menuCounts.value[parentPath] = parentCount; } }); }; // 清空所有菜单的气泡数量 const clearAllCounts = () => { menuCounts.value = {}; }; // 从接口响应中提取数量 const extractCountFromResponse = (response: any): number => { try { if (response.code === 200) { return response.data; } } catch { return 0; } }; // 获取指定菜单的数量(调用接口) const fetchMenuCount = async (menuPath: string): Promise => { const config = menuApiConfigs.value[menuPath]; if (!config) { console.warn(`菜单路径 ${menuPath} 没有配置接口信息`); return 0; } console.log(menuPath, '========'); // 如果是父级菜单,不调用接口,直接返回子菜单数量总和 if (config.isParent) { return getMenuCount(menuPath); } try { const response = await makeApiRequest(config); const count = extractCountFromResponse(response); updateMenuCount(menuPath, count); return count; } catch (error) { console.error(`获取菜单 ${menuPath} 数量失败:`, error); return 0; } }; // 发起API请求 const makeApiRequest = async (config: MenuApiConfig): Promise => { const { apiUrl, method = 'GET', params } = config; if (method === 'GET') { return await request.get(apiUrl, { params }); } else { return await request.post(apiUrl, params); } }; // 刷新指定菜单的数量(立即调用接口) const refreshMenuCount = async (menuPath: string): Promise => { return fetchMenuCount(menuPath); }; // 刷新所有菜单的数量 const refreshAllCounts = async (): Promise => { // 只刷新非父级菜单的数量 const nonParentMenus = Object.keys(menuApiConfigs.value).filter((menuPath) => !menuApiConfigs.value[menuPath].isParent); const promises = nonParentMenus.map((menuPath) => fetchMenuCount(menuPath)); await Promise.allSettled(promises); // 刷新完子菜单后,更新所有父级菜单的数量 Object.keys(menuApiConfigs.value).forEach((menuPath) => { const config = menuApiConfigs.value[menuPath]; if (config.isParent && config.children) { // 父级菜单数量 = 子菜单数量总和 const parentCount = config.children.reduce((total, childPath) => { return total + (menuCounts.value[childPath] || 0); }, 0); // 将计算的数量存储到menuCounts中 menuCounts.value[menuPath] = parentCount; } }); }; // 重置Store状态 const resetStore = () => { menuCounts.value = {}; menuApiConfigs.value = {}; }; return { // 状态 menuCounts, menuApiConfigs, // 计算属性 getActiveMenus, getTotalCount, // 方法 getMenuCount, setMenuApiConfig, setParentMenuConfig, setMultipleApiConfigs, updateMenuCount, clearMenuCount, clearAllCounts, extractCountFromResponse, fetchMenuCount, makeApiRequest, refreshMenuCount, refreshAllCounts, resetStore, setMultipleParentConfigs }; });