feat(message): add message center module (Phase 5)
Implement the complete message center with: - Database migrations for message_templates, messages, message_subscriptions tables - erp-message crate with entities, DTOs, services, handlers - Message CRUD, send, read/unread tracking, soft delete - Template management with variable interpolation - Subscription preferences with DND support - Frontend: messages page, notification panel, unread count badge - Server integration with module registration and routing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,17 +1,18 @@
|
||||
import { Layout, Menu, theme, Avatar, Space, Dropdown, Button } from 'antd';
|
||||
import NotificationPanel from '../components/NotificationPanel';
|
||||
import {
|
||||
HomeOutlined,
|
||||
UserOutlined,
|
||||
SafetyOutlined,
|
||||
ApartmentOutlined,
|
||||
BellOutlined,
|
||||
SettingOutlined,
|
||||
MenuFoldOutlined,
|
||||
MenuUnfoldOutlined,
|
||||
PartitionOutlined,
|
||||
LogoutOutlined,
|
||||
MessageOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useAppStore } from '../stores/app';
|
||||
import { useAuthStore } from '../stores/auth';
|
||||
|
||||
@@ -23,6 +24,7 @@ const menuItems = [
|
||||
{ key: '/roles', icon: <SafetyOutlined />, label: '权限管理' },
|
||||
{ key: '/organizations', icon: <ApartmentOutlined />, label: '组织架构' },
|
||||
{ key: '/workflow', icon: <PartitionOutlined />, label: '工作流' },
|
||||
{ key: '/messages', icon: <MessageOutlined />, label: '消息中心' },
|
||||
{ key: '/settings', icon: <SettingOutlined />, label: '系统设置' },
|
||||
];
|
||||
|
||||
@@ -31,6 +33,8 @@ export default function MainLayout({ children }: { children: React.ReactNode })
|
||||
const { user, logout } = useAuthStore();
|
||||
const { token } = theme.useToken();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const currentPath = location.pathname || '/';
|
||||
|
||||
const userMenuItems = [
|
||||
{
|
||||
@@ -64,7 +68,7 @@ export default function MainLayout({ children }: { children: React.ReactNode })
|
||||
theme="dark"
|
||||
mode="inline"
|
||||
items={menuItems}
|
||||
defaultSelectedKeys={['/']}
|
||||
selectedKeys={[currentPath]}
|
||||
onClick={({ key }) => navigate(key)}
|
||||
/>
|
||||
</Sider>
|
||||
@@ -87,7 +91,7 @@ export default function MainLayout({ children }: { children: React.ReactNode })
|
||||
/>
|
||||
</Space>
|
||||
<Space size="middle">
|
||||
<BellOutlined style={{ fontSize: 18, cursor: 'pointer' }} />
|
||||
<NotificationPanel />
|
||||
<Dropdown menu={{ items: userMenuItems }} placement="bottomRight">
|
||||
<Space style={{ cursor: 'pointer' }}>
|
||||
<Avatar icon={<UserOutlined />} />
|
||||
|
||||
Reference in New Issue
Block a user