优化数据隔离,进行权限控制
This commit is contained in:
@@ -68,6 +68,21 @@ export function Layout({ children, userRole = 'developer' }: LayoutProps) {
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 路由变化时,检查并更新应用模块
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
try {
|
||||
const reviewType = sessionStorage.getItem('reviewType');
|
||||
console.log('Layout 路由变化, reviewType:', reviewType, '路径:', location.pathname);
|
||||
if (reviewType && REVIEW_TYPE_TO_APP[reviewType]) {
|
||||
setSelectedApp(REVIEW_TYPE_TO_APP[reviewType]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('路由变化时获取reviewType失败:', error);
|
||||
}
|
||||
}
|
||||
}, [location.pathname]);
|
||||
|
||||
const toggleSidebar = () => {
|
||||
const newState = !sidebarCollapsed;
|
||||
setSidebarCollapsed(newState);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Link, useLocation } from '@remix-run/react';
|
||||
import { Link, useLocation, useNavigate } from '@remix-run/react';
|
||||
import type { UserRole } from '~/root';
|
||||
|
||||
interface MenuItem {
|
||||
@@ -44,31 +44,24 @@ export function Sidebar({ onToggle, collapsed, userRole, selectedApp = 'contract
|
||||
const location = useLocation();
|
||||
const [expandedMenus, setExpandedMenus] = useState<Record<string, boolean>>({});
|
||||
const [currentApp, setCurrentApp] = useState<string>(selectedApp);
|
||||
const navigate = useNavigate();
|
||||
|
||||
// 组件挂载后从 sessionStorage 读取初始 reviewType
|
||||
useEffect(() => {
|
||||
try {
|
||||
const reviewType = sessionStorage.getItem('reviewType');
|
||||
// console.log('初始 reviewType:', reviewType);
|
||||
if (reviewType) {
|
||||
setCurrentApp(reviewType);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('读取 reviewType 失败:', error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 从 sessionStorage 获取 reviewType 并设置当前应用模块
|
||||
useEffect(() => {
|
||||
// 初始加载时获取 reviewType
|
||||
const updateReviewType = () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const reviewType = sessionStorage.getItem('reviewType');
|
||||
if (reviewType) {
|
||||
setCurrentApp(reviewType);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 首次执行
|
||||
updateReviewType();
|
||||
|
||||
// 设置轮询,每秒检查一次 reviewType 变化
|
||||
const intervalId = setInterval(updateReviewType, 1000);
|
||||
|
||||
// 添加自定义事件监听
|
||||
const handleReviewTypeChange = () => {
|
||||
updateReviewType();
|
||||
};
|
||||
|
||||
// 监听 sessionStorage 变化
|
||||
// 监听 sessionStorage 变化(主要用于多标签页情况)
|
||||
const handleStorageChange = (e: StorageEvent) => {
|
||||
if (e.key === 'reviewType' && e.newValue) {
|
||||
setCurrentApp(e.newValue);
|
||||
@@ -76,23 +69,23 @@ export function Sidebar({ onToggle, collapsed, userRole, selectedApp = 'contract
|
||||
};
|
||||
|
||||
// 添加事件监听器
|
||||
window.addEventListener('reviewTypeChange', handleReviewTypeChange);
|
||||
window.addEventListener('storage', handleStorageChange);
|
||||
|
||||
return () => {
|
||||
clearInterval(intervalId);
|
||||
window.removeEventListener('reviewTypeChange', handleReviewTypeChange);
|
||||
window.removeEventListener('storage', handleStorageChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 监听路由变化,重新检查 reviewType
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
try {
|
||||
const reviewType = sessionStorage.getItem('reviewType');
|
||||
// console.log('路由变化, 检查 reviewType:', reviewType, '路径:', location.pathname);
|
||||
if (reviewType) {
|
||||
setCurrentApp(reviewType);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('路由变化时读取 reviewType 失败:', error);
|
||||
}
|
||||
}, [location.pathname]);
|
||||
|
||||
@@ -110,26 +103,6 @@ export function Sidebar({ onToggle, collapsed, userRole, selectedApp = 'contract
|
||||
path: '/home',
|
||||
icon: 'ri-home-line'
|
||||
},
|
||||
{
|
||||
id: 'contract-template',
|
||||
title: '合同模板',
|
||||
path: '/contract-template',
|
||||
icon: 'ri-file-search-line',
|
||||
children: [
|
||||
{
|
||||
id: 'contract-search-ai',
|
||||
title: '智能搜索',
|
||||
path: '/contract-template/search',
|
||||
icon: 'ri-search-line'
|
||||
},
|
||||
{
|
||||
id: 'contract-list',
|
||||
title: '合同列表',
|
||||
path: '/contract-template/list',
|
||||
icon: 'ri-folder-line'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'file-management',
|
||||
title: '文件管理',
|
||||
@@ -178,6 +151,7 @@ export function Sidebar({ onToggle, collapsed, userRole, selectedApp = 'contract
|
||||
id: 'rule-new',
|
||||
title: '新增评查点',
|
||||
path: '/rules-new',
|
||||
requiredRole: 'developer',
|
||||
icon: 'ri-add-circle-line'
|
||||
},
|
||||
// {
|
||||
@@ -188,6 +162,26 @@ export function Sidebar({ onToggle, collapsed, userRole, selectedApp = 'contract
|
||||
// }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'contract-template',
|
||||
title: '合同模板',
|
||||
path: '/contract-template',
|
||||
icon: 'ri-file-search-line',
|
||||
children: [
|
||||
{
|
||||
id: 'contract-search-ai',
|
||||
title: '智能搜索',
|
||||
path: '/contract-template/search',
|
||||
icon: 'ri-search-line'
|
||||
},
|
||||
{
|
||||
id: 'contract-list',
|
||||
title: '合同列表',
|
||||
path: '/contract-template/list',
|
||||
icon: 'ri-folder-line'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'system-settings',
|
||||
title: '系统设置',
|
||||
@@ -270,6 +264,7 @@ export function Sidebar({ onToggle, collapsed, userRole, selectedApp = 'contract
|
||||
|
||||
// 获取当前应用模式下应显示的菜单ID列表
|
||||
const visibleMenuIds = APP_MENU_MAP[currentApp as keyof typeof APP_MENU_MAP] || APP_MENU_MAP['contract'];
|
||||
// console.log('当前应用模式:', currentApp, '可见菜单ID:', visibleMenuIds);
|
||||
|
||||
// 根据用户角色和当前应用模式过滤菜单项
|
||||
const filteredMenuItems = menuItems.filter(item => {
|
||||
@@ -289,7 +284,19 @@ export function Sidebar({ onToggle, collapsed, userRole, selectedApp = 'contract
|
||||
return (
|
||||
<div className={`sidebar ${collapsed ? 'collapsed' : ''}`}>
|
||||
<div className="py-6 px-4 border-b border-gray-100 flex justify-between items-center">
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center"
|
||||
onClick={() => {
|
||||
navigate('/');
|
||||
}}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
navigate('/');
|
||||
}
|
||||
}}
|
||||
>
|
||||
<img src="/logo.svg" alt="智慧法务" className="w-12 h-12 mr-2" />
|
||||
{!collapsed && <h2 className="text-lg font-medium">智慧法务</h2>}
|
||||
</div>
|
||||
@@ -309,9 +316,6 @@ export function Sidebar({ onToggle, collapsed, userRole, selectedApp = 'contract
|
||||
<i className={`${APP_ICON_MAP[currentApp] || 'ri-file-list-2-fill'} mr-2 text-xl`}></i>
|
||||
<span className="font-medium">{APP_NAME_MAP[currentApp] || '合同管理'}</span>
|
||||
</div>
|
||||
<div className="text-xs text-gray-500 mt-1">
|
||||
当前模块: {APP_NAME_MAP[currentApp] || '合同管理'}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user