| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- 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<string, any>;
- // 数据提取路径,从接口响应中提取数量的路径
- dataPath?: string;
- // 是否为父级菜单(数字由子菜单汇总而来,不调用接口)
- isParent?: boolean;
- // 子菜单路径列表(仅当isParent为true时有效)
- children?: string[];
- }
- export const useSideNumStore = defineStore('sideNum', () => {
- // 存储每个菜单路径对应的气泡数量
- const menuCounts = ref<Record<string, number>>({});
- // 存储每个菜单路径对应的接口配置
- const menuApiConfigs = ref<Record<string, MenuApiConfig>>({});
- // 获取指定菜单路径的气泡数量
- 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<string, number> = {};
- // 遍历所有已配置的菜单
- 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<string, string[]>) => {
- Object.keys(configs).forEach((menuPath) => {
- setParentMenuConfig(menuPath, configs[menuPath]);
- });
- };
- // 批量设置多个菜单的接口配置
- const setMultipleApiConfigs = (configs: Record<string, MenuApiConfig>) => {
- 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<number> => {
- 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<any> => {
- 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<number> => {
- return fetchMenuCount(menuPath);
- };
- // 刷新所有菜单的数量
- const refreshAllCounts = async (): Promise<void> => {
- // 只刷新非父级菜单的数量
- 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
- };
- });
|