| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- /*
- Copyright (C) 2025 QuantumNous
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
- For commercial licensing, please contact support@quantumnous.com
- */
- import { useState, useEffect, useMemo, useContext } from 'react';
- import { StatusContext } from '../../context/Status';
- import { API } from '../../helpers';
- // 创建一个全局事件系统来同步所有useSidebar实例
- const sidebarEventTarget = new EventTarget();
- const SIDEBAR_REFRESH_EVENT = 'sidebar-refresh';
- export const useSidebar = () => {
- const [statusState] = useContext(StatusContext);
- const [userConfig, setUserConfig] = useState(null);
- const [loading, setLoading] = useState(true);
- // 默认配置
- const defaultAdminConfig = {
- chat: {
- enabled: true,
- playground: true,
- chat: true,
- },
- console: {
- enabled: true,
- detail: true,
- token: true,
- log: true,
- midjourney: true,
- task: true,
- },
- personal: {
- enabled: true,
- topup: true,
- personal: true,
- },
- admin: {
- enabled: true,
- channel: true,
- models: true,
- redemption: true,
- user: true,
- setting: true,
- },
- };
- // 获取管理员配置
- const adminConfig = useMemo(() => {
- if (statusState?.status?.SidebarModulesAdmin) {
- try {
- const config = JSON.parse(statusState.status.SidebarModulesAdmin);
- return config;
- } catch (error) {
- return defaultAdminConfig;
- }
- }
- return defaultAdminConfig;
- }, [statusState?.status?.SidebarModulesAdmin]);
- // 加载用户配置的通用方法
- const loadUserConfig = async () => {
- try {
- setLoading(true);
- const res = await API.get('/api/user/self');
- if (res.data.success && res.data.data.sidebar_modules) {
- let config;
- // 检查sidebar_modules是字符串还是对象
- if (typeof res.data.data.sidebar_modules === 'string') {
- config = JSON.parse(res.data.data.sidebar_modules);
- } else {
- config = res.data.data.sidebar_modules;
- }
- setUserConfig(config);
- } else {
- // 当用户没有配置时,生成一个基于管理员配置的默认用户配置
- // 这样可以确保权限控制正确生效
- const defaultUserConfig = {};
- Object.keys(adminConfig).forEach((sectionKey) => {
- if (adminConfig[sectionKey]?.enabled) {
- defaultUserConfig[sectionKey] = { enabled: true };
- // 为每个管理员允许的模块设置默认值为true
- Object.keys(adminConfig[sectionKey]).forEach((moduleKey) => {
- if (
- moduleKey !== 'enabled' &&
- adminConfig[sectionKey][moduleKey]
- ) {
- defaultUserConfig[sectionKey][moduleKey] = true;
- }
- });
- }
- });
- setUserConfig(defaultUserConfig);
- }
- } catch (error) {
- // 出错时也生成默认配置,而不是设置为空对象
- const defaultUserConfig = {};
- Object.keys(adminConfig).forEach((sectionKey) => {
- if (adminConfig[sectionKey]?.enabled) {
- defaultUserConfig[sectionKey] = { enabled: true };
- Object.keys(adminConfig[sectionKey]).forEach((moduleKey) => {
- if (moduleKey !== 'enabled' && adminConfig[sectionKey][moduleKey]) {
- defaultUserConfig[sectionKey][moduleKey] = true;
- }
- });
- }
- });
- setUserConfig(defaultUserConfig);
- } finally {
- setLoading(false);
- }
- };
- // 刷新用户配置的方法(供外部调用)
- const refreshUserConfig = async () => {
- // 移除adminConfig的条件限制,直接刷新用户配置
- await loadUserConfig();
- // 触发全局刷新事件,通知所有useSidebar实例更新
- sidebarEventTarget.dispatchEvent(new CustomEvent(SIDEBAR_REFRESH_EVENT));
- };
- // 加载用户配置
- useEffect(() => {
- // 只有当管理员配置加载完成后才加载用户配置
- if (Object.keys(adminConfig).length > 0) {
- loadUserConfig();
- }
- }, [adminConfig]);
- // 监听全局刷新事件
- useEffect(() => {
- const handleRefresh = () => {
- if (Object.keys(adminConfig).length > 0) {
- loadUserConfig();
- }
- };
- sidebarEventTarget.addEventListener(SIDEBAR_REFRESH_EVENT, handleRefresh);
- return () => {
- sidebarEventTarget.removeEventListener(SIDEBAR_REFRESH_EVENT, handleRefresh);
- };
- }, [adminConfig]);
- // 计算最终的显示配置
- const finalConfig = useMemo(() => {
- const result = {};
- // 确保adminConfig已加载
- if (!adminConfig || Object.keys(adminConfig).length === 0) {
- return result;
- }
- // 如果userConfig未加载,等待加载完成
- if (!userConfig) {
- return result;
- }
- // 遍历所有区域
- Object.keys(adminConfig).forEach((sectionKey) => {
- const adminSection = adminConfig[sectionKey];
- const userSection = userConfig[sectionKey];
- // 如果管理员禁用了整个区域,则该区域不显示
- if (!adminSection?.enabled) {
- result[sectionKey] = { enabled: false };
- return;
- }
- // 区域级别:用户可以选择隐藏管理员允许的区域
- // 当userSection存在时检查enabled状态,否则默认为true
- const sectionEnabled = userSection ? userSection.enabled !== false : true;
- result[sectionKey] = { enabled: sectionEnabled };
- // 功能级别:只有管理员和用户都允许的功能才显示
- Object.keys(adminSection).forEach((moduleKey) => {
- if (moduleKey === 'enabled') return;
- const adminAllowed = adminSection[moduleKey];
- // 当userSection存在时检查模块状态,否则默认为true
- const userAllowed = userSection
- ? userSection[moduleKey] !== false
- : true;
- result[sectionKey][moduleKey] =
- adminAllowed && userAllowed && sectionEnabled;
- });
- });
- return result;
- }, [adminConfig, userConfig]);
- // 检查特定功能是否应该显示
- const isModuleVisible = (sectionKey, moduleKey = null) => {
- if (moduleKey) {
- return finalConfig[sectionKey]?.[moduleKey] === true;
- } else {
- return finalConfig[sectionKey]?.enabled === true;
- }
- };
- // 检查区域是否有任何可见的功能
- const hasSectionVisibleModules = (sectionKey) => {
- const section = finalConfig[sectionKey];
- if (!section?.enabled) return false;
- return Object.keys(section).some(
- (key) => key !== 'enabled' && section[key] === true,
- );
- };
- // 获取区域的可见功能列表
- const getVisibleModules = (sectionKey) => {
- const section = finalConfig[sectionKey];
- if (!section?.enabled) return [];
- return Object.keys(section).filter(
- (key) => key !== 'enabled' && section[key] === true,
- );
- };
- return {
- loading,
- adminConfig,
- userConfig,
- finalConfig,
- isModuleVisible,
- hasSectionVisibleModules,
- getVisibleModules,
- refreshUserConfig,
- };
- };
|