8.8 KiB
8.8 KiB
待办事项管理系统开发指南
作者: 阿瑞
版本: v1.0
技术栈: Next.js 15 + React 19 + TypeScript + Ant Design 5.x + MongoDB + Socket.IO
完成时间: 2024年
📋 系统概述
本系统是一个支持实时协作的团队待办事项管理系统,具备完整的CRUD操作、实时通知、状态管理、评论系统等功能。
🎯 核心功能
-
待办事项管理
- 创建、编辑、删除待办事项
- 状态管理(待处理、进行中、已完成、已取消)
- 优先级设置(低、中、高、紧急)
- 进度跟踪(0-100%)
- 置顶功能
-
团队协作
- 多人分配办理
- 实时同步更新
- 团队成员管理
- 操作历史记录
-
实时通知系统
- Socket.IO实时通信
- 确认型通知机制
- 操作者排除逻辑
- 通知去重机制
-
界面优化
- 分组折叠显示
- 压缩布局设计
- 状态确认对话框
- 响应式界面
🏗️ 技术架构
前端架构
src/
├── components/
│ └── TodoManager/ # 待办事项管理主组件
├── hooks/
│ └── useSocket.ts # Socket.IO通信钩子
├── types/
│ └── socket.ts # Socket类型定义
└── pages/
└── api/
├── socket.ts # Socket.IO服务器
└── todos/
└── [id].ts # 待办事项API
后端架构
MongoDB 数据库
├── Todo 集合
│ ├── 基本信息 (标题、描述、团队)
│ ├── 人员信息 (创建人、办理人员)
│ ├── 状态信息 (状态、优先级、进度)
│ ├── 时间信息 (开始时间、完成时间)
│ └── 协作信息 (评论、置顶、排序)
└── 实时通信层 (Socket.IO)
🔧 核心技术实现
1. 数据模型设计
// MongoDB Schema 定义
interface ITodo {
_id: string;
团队: string; // 所属团队ID
标题: string; // 待办事项标题
描述?: string; // 详细描述
创建人: { // 创建者信息
_id: string;
姓名: string;
头像?: string;
};
办理人员: Array<{ // 负责人列表
_id: string;
姓名: string;
头像?: string;
}>;
优先级: '低' | '中' | '高' | '紧急';
状态: '待处理' | '进行中' | '已完成' | '已取消';
开始时间?: Date;
完成时间?: Date;
完成进度: number; // 0-100
评论: ITodoComment[]; // 评论列表
排序: number; // 排序权重
是否置顶: boolean; // 置顶标记
createdAt: Date; // 创建时间
updatedAt: Date; // 更新时间
}
2. Socket.IO 实时通信
服务器端配置
// src/pages/api/socket.ts
const io = new ServerIO(httpServer, {
path: '/api/socket',
addTrailingSlash: false,
cors: {
origin: process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : false,
methods: ['GET', 'POST'],
},
});
// 房间管理
io.on('connection', (socket) => {
socket.on('join-team', (teamId: string) => {
const roomName = `team-${teamId}`;
socket.join(roomName);
// 确认加入成功
socket.emit('room-joined', { roomName, teamId });
});
});
客户端连接
// src/hooks/useSocket.ts
const socket = io({
path: '/api/socket',
autoConnect: true,
reconnection: true,
reconnectionDelay: 1000,
reconnectionAttempts: 5,
});
// 自动加入团队房间
socket.on('connect', () => {
if (userInfo?.团队?._id) {
socket.emit('join-team', userInfo.团队._id);
}
});
3. 关键业务逻辑
状态更新API
// src/pages/api/todos/[id].ts
case 'update-status':
const { 状态 } = req.body;
updatedTodo = await Todo.findByIdAndUpdate(
id,
{ 状态 },
{ new: true }
).populate([
{ path: '创建人', select: '姓名 头像' },
{ path: '办理人员', select: '姓名 头像' }
]);
// 发送实时通知
const targetUsers = [
...updatedTodo.办理人员.map(user => user._id.toString()),
updatedTodo.创建人._id.toString()
];
res.socket.server.io.to(`team-${updatedTodo.团队}`).emit(
'todo-status-changed',
{
type: 'TODO_STATUS_CHANGED',
data: updatedTodo,
message: `"${todo.标题}" 状态已更新为 "${状态}"`,
targetUsers,
creatorId: 操作人
}
);
通知处理逻辑
// src/hooks/useSocket.ts
const handleTodoNotification = (data, title, type = 'info') => {
const isTargetUser = data.targetUsers.includes(userInfo?._id || '');
const isCreator = data.creatorId === userInfo?._id;
// 显示通知(除操作者外)
if (isTargetUser && !isCreator) {
notification.open({
message: title,
description: data.message,
duration: 0, // 确认型通知
btn: React.createElement(Button, {
onClick: () => notification.destroy(key)
}, '知道了')
});
}
// 数据更新(包括操作者)
if (isTargetUser) {
window.dispatchEvent(new CustomEvent('todo-data-updated', {
detail: { type: data.type, data: data.data }
}));
}
};
🎨 界面设计特点
1. 压缩布局设计
- 卡片间距:8px
- 最小高度:120px
- 内边距:8px 12px
- 字体大小:12px-14px
2. 分组显示策略
const groupedTodos = useMemo(() => {
const groups = {
active: [] as ITodo[], // 待处理 + 进行中 (始终展开)
completed: [] as ITodo[], // 已完成 (默认折叠)
cancelled: [] as ITodo[] // 已取消 (默认折叠)
};
todos.forEach(todo => {
if (todo.状态 === '已完成') {
groups.completed.push(todo);
} else if (todo.状态 === '已取消') {
groups.cancelled.push(todo);
} else {
groups.active.push(todo);
}
});
return groups;
}, [todos]);
3. 操作按钮布局
- 18:6 比例布局(内容:操作)
- 垂直排列操作按钮
- 直接状态切换按钮
- 确认对话框机制
🔍 关键问题解决
问题1:操作者收不到自己操作的实时更新
原因: 通知逻辑中if (isTargetUser && !isCreator)阻止了操作者接收数据更新事件
解决方案: 分离通知显示和数据更新逻辑
// 显示通知(除操作者外)
if (isTargetUser && !isCreator) {
// 显示通知
}
// 数据更新(包括操作者)
if (isTargetUser) {
// 触发数据更新
}
问题2:统计数据显示0
原因: API统计数据结构问题
解决方案: 双重统计策略
// 优先使用API统计,备用本地计算
if (result.data.statistics?.statusCounts) {
setStats(result.data.statistics.statusCounts);
} else {
updateStats(todosData); // 本地计算
}
问题3:Socket事件名称转换错误
原因: replace('_', '-')只替换第一个下划线
解决方案: 使用全局替换
const eventName = notificationType.toLowerCase().replace(/_/g, '-');
📦 部署配置
1. 环境变量
MONGODB_URI=mongodb://localhost:27017/saas_db
NODE_ENV=development
2. 依赖安装
pnpm install socket.io
pnpm install mongoose
pnpm install antd
pnpm install dayjs
3. 启动命令
pnpm run dev
🚀 功能扩展建议
1. 短期优化
- 批量操作功能
- 导出功能(Excel/PDF)
- 高级搜索和筛选
- 时间轴视图
2. 中期扩展
- 移动端适配
- 离线同步支持
- 文件附件功能
- 甘特图视图
3. 长期规划
- AI智能推荐
- 语音转文字
- 视频会议集成
- 第三方集成(钉钉、企微等)
🔧 维护指南
1. 代码规范
- 使用TypeScript严格模式
- 遵循函数式编程模式
- 三级注释体系(文件/模块/代码行)
- 中文变量名和注释
2. 性能优化
- 使用React.memo防止不必要渲染
- 合理使用useMemo和useCallback
- Socket.IO通知去重机制
- 分页和虚拟滚动
3. 测试策略
- 单元测试(Jest + Testing Library)
- 集成测试(Socket.IO连接测试)
- E2E测试(Playwright)
- 性能测试(Lighthouse)
📝 总结
本待办事项管理系统通过现代化的技术栈和精心设计的架构,实现了高效的团队协作功能。关键成功因素包括:
- 实时性: Socket.IO确保所有操作实时同步
- 易用性: 压缩布局和直观的操作方式
- 可靠性: 完整的错误处理和通知机制
- 扩展性: 模块化设计便于功能扩展
系统已在生产环境中稳定运行,为团队协作提供了强有力的支持。
本文档记录了完整的开发过程和关键技术决策,可作为类似系统开发的参考指南。