Files
SaaS2/docs/待办事项管理系统开发指南.md
RUI 4edd9768cc
Some checks failed
Next.js CI/CD 流水线 / deploy (push) Failing after 40s
0607.6
2025-06-07 16:41:21 +08:00

8.8 KiB
Raw Blame History

待办事项管理系统开发指南

作者: 阿瑞
版本: v1.0
技术栈: Next.js 15 + React 19 + TypeScript + Ant Design 5.x + MongoDB + Socket.IO
完成时间: 2024年

📋 系统概述

本系统是一个支持实时协作的团队待办事项管理系统具备完整的CRUD操作、实时通知、状态管理、评论系统等功能。

🎯 核心功能

  1. 待办事项管理

    • 创建、编辑、删除待办事项
    • 状态管理(待处理、进行中、已完成、已取消)
    • 优先级设置(低、中、高、紧急)
    • 进度跟踪0-100%
    • 置顶功能
  2. 团队协作

    • 多人分配办理
    • 实时同步更新
    • 团队成员管理
    • 操作历史记录
  3. 实时通知系统

    • Socket.IO实时通信
    • 确认型通知机制
    • 操作者排除逻辑
    • 通知去重机制
  4. 界面优化

    • 分组折叠显示
    • 压缩布局设计
    • 状态确认对话框
    • 响应式界面

🏗️ 技术架构

前端架构

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); // 本地计算
}

问题3Socket事件名称转换错误

原因: 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

📝 总结

本待办事项管理系统通过现代化的技术栈和精心设计的架构,实现了高效的团队协作功能。关键成功因素包括:

  1. 实时性: Socket.IO确保所有操作实时同步
  2. 易用性: 压缩布局和直观的操作方式
  3. 可靠性: 完整的错误处理和通知机制
  4. 扩展性: 模块化设计便于功能扩展

系统已在生产环境中稳定运行,为团队协作提供了强有力的支持。


本文档记录了完整的开发过程和关键技术决策,可作为类似系统开发的参考指南。