diff --git a/src/App.jsx b/src/App.jsx index 0c41c6e..f3529a3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -4,22 +4,50 @@ import { checkAuthThunk } from './store/auth/auth.thunk'; import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { login } from './store/auth/auth.slice'; +import { initWebSocket, closeWebSocket } from './services/websocket'; +import { setWebSocketConnected } from './store/notificationCenter/notificationCenter.slice'; function App() { const navigate = useNavigate(); const dispatch = useDispatch(); const { user } = useSelector((state) => state.auth); + const { isConnected } = useSelector((state) => state.notificationCenter); + // 检查用户认证状态 useEffect(() => { handleCheckAuth(); }, [dispatch]); + // 管理WebSocket连接 + useEffect(() => { + console.log(user, isConnected); + + // 如果用户已认证但WebSocket未连接,则初始化连接 + if (user && !isConnected) { + initWebSocket() + .then(() => { + // dispatch(setWebSocketConnected(true)); + // console.log('WebSocket connection initialized'); + }) + .catch((error) => { + console.error('Failed to initialize WebSocket connection:', error); + }); + } + + // 组件卸载或用户登出时关闭WebSocket连接 + return () => { + if (isConnected) { + closeWebSocket(); + dispatch(setWebSocketConnected(false)); + } + }; + }, [user, isConnected, dispatch]); + const handleCheckAuth = async () => { console.log('app handleCheckAuth'); try { await dispatch(checkAuthThunk()).unwrap(); - console.log('user', user); if (!user) navigate('/login'); } catch (error) { console.log('error', error); diff --git a/src/components/CreateKnowledgeBaseModal.jsx b/src/components/CreateKnowledgeBaseModal.jsx index 0ace1d9..c03059a 100644 --- a/src/components/CreateKnowledgeBaseModal.jsx +++ b/src/components/CreateKnowledgeBaseModal.jsx @@ -1,6 +1,17 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import SvgIcon from './SvgIcon'; +// 部门和组别的映射关系 +const departmentGroups = { + 技术部: ['开发组', '测试组', '运维组', '架构组', '安全组'], + 产品部: ['产品规划组', '用户研究组', '交互设计组', '项目管理组'], + 市场部: ['品牌推广组', '市场调研组', '客户关系组', '社交媒体组'], + 行政部: ['人事组', '财务组', '行政管理组', '后勤组'], +}; + +// 部门列表 +const departments = Object.keys(departmentGroups); + /** * 创建知识库模态框组件 * @param {Object} props @@ -13,22 +24,38 @@ import SvgIcon from './SvgIcon'; * @param {Function} props.onSubmit - 提交表单的回调函数 * @param {Object} props.currentUser - 当前用户信息 */ -const CreateKnowledgeBaseModal = ({ - show, - formData, - formErrors, - isSubmitting, - onClose, - onChange, +const CreateKnowledgeBaseModal = ({ + show, + formData, + formErrors, + isSubmitting, + onClose, + onChange, onSubmit, - currentUser + currentUser, }) => { - if (!show) return null; - // 根据用户角色确定可以创建的知识库类型 const isAdmin = currentUser?.role === 'admin'; const isLeader = currentUser?.role === 'leader'; - + + // 获取当前用户的部门和组别 + const userDepartment = currentUser?.department || ''; + + // 可选的组别列表 + const [availableGroups, setAvailableGroups] = useState([]); + + // 当部门变化时更新可用的组别 + useEffect(() => { + if (formData.department && departmentGroups[formData.department]) { + setAvailableGroups(departmentGroups[formData.department]); + } else { + setAvailableGroups([]); + } + }, [formData.department]); + + // 提前返回需要放在所有 Hooks 之后 + if (!show) return null; + // 获取当前用户可以创建的知识库类型 const getAvailableTypes = () => { if (isAdmin) { @@ -37,22 +64,24 @@ const CreateKnowledgeBaseModal = ({ { value: 'leader', label: 'Leader 级知识库' }, { value: 'member', label: 'Member 级知识库' }, { value: 'private', label: '私有知识库' }, - { value: 'secret', label: '保密知识库' } + { value: 'secret', label: '保密知识库' }, ]; } else if (isLeader) { return [ { value: 'member', label: 'Member 级知识库' }, - { value: 'private', label: '私有知识库' } + { value: 'private', label: '私有知识库' }, ]; } else { - return [ - { value: 'private', label: '私有知识库' } - ]; + return [{ value: 'private', label: '私有知识库' }]; } }; const availableTypes = getAvailableTypes(); + // 判断是否需要选择组别 + const isMemberTypeSelected = formData.type === 'member'; + const needSelectGroup = isMemberTypeSelected; + return (
{formErrors.type}
} -
- - -
-
- - -
+ + {/* 仅当不是私有知识库时才显示部门选项 */} + {formData.type !== 'private' && ( +
+ + {isAdmin ? ( + // 管理员可以选择任意部门 + + ) : ( + // 非管理员显示只读字段 + + )} + {formErrors.department && ( +
{formErrors.department}
+ )} +
+ )} + + {/* 仅当不是私有知识库时才显示组别选项 */} + {formData.type !== 'private' && ( +
+ + {isAdmin || (isLeader && needSelectGroup) ? ( + // 管理员可以选择任意组别,组长只能选择自己部门下的组别 + + ) : ( + // 普通用户显示只读字段 + + )} + {formErrors.group &&
{formErrors.group}
} +
+ )}
- {displayedNotifications.map((notification) => ( -
-
-
- -
-
-
-
{notification.title}
- {notification.time} + {displayedNotifications.length === 0 ? ( +
+ +

暂无通知

+
+ ) : ( + displayedNotifications.map((notification) => ( +
+
+
+
-

{notification.content}

-
- {notification.hasDetail && ( - - )} +
+
+
+ {notification.title} +
+ {notification.time} +
+

{notification.content}

+
+ {notification.hasDetail && ( + + )} + {!notification.isRead && ( + + )} +
-
- ))} -
-
- + )) + )}
+ {notifications.length > 5 && ( +
+ +
+ )}
{/* 使用滑动面板组件 */} diff --git a/src/components/Pagination.jsx b/src/components/Pagination.jsx index c819887..e16ab79 100644 --- a/src/components/Pagination.jsx +++ b/src/components/Pagination.jsx @@ -24,7 +24,7 @@ const Pagination = ({ currentPage, totalPages, pageSize, onPageChange, onPageSiz