日历系统开发(一):需求分析与技术选型

本系列记录从零搭建一个日历系统的完整过程,从需求分析到最终上线。第一篇聊需求和技术选型。

为什么需要日历系统

企业内部的日程管理通常有定制需求:

  • 需要和内部 OA 系统深度集成
  • 需要支持自定义的日程类型和审批流程
  • 需要精细的权限控制(部门级、项目组级)
  • 现有方案的 API 限制导致二次开发困难

调研开源方案(如 Radicale、Baikal 等 CalDAV 服务端),功能偏基础,改造成本高。在定制需求较多的场景下,自研是更灵活的选择。

核心功能

MVP 版本的功能需求:

基础日程管理

  • 日程 CRUD(创建、查看、编辑、删除)
  • 日历视图(月视图、周视图、日视图)
  • 全天事件和时间段事件
  • 日程颜色标记和分类

重复事件

  • 支持日/周/月/年重复
  • 支持自定义重复规则(如"每月第二个周三")
  • 单次修改和整体修改
  • 遵循 RFC 5545 的 RRULE 规范

提醒

  • 多种提醒方式(站内通知、邮件、webhook)
  • 自定义提醒时间(事件前 5 分钟/15 分钟/1 小时等)
  • 重复事件的提醒处理

协作功能

  • 邀请参与者
  • 参与者状态(接受/拒绝/待定)
  • 日历共享(只读/可编辑)
  • 空闲/忙碌查询

日历同步

  • CalDAV 协议支持(可选,优先级低)
  • iCalendar 格式导入导出
  • 与外部日历订阅同步

技术选型

后端

组件 选型 理由
语言/框架 Java 17 + Spring Boot 2.7 Java 生态成熟,Spring Boot 上手快
数据库 PostgreSQL 14 对时间类型支持好,有 tstzrange
缓存 Redis 7 会议室查询、空闲时间查询缓存
消息队列 RabbitMQ 提醒消息投递
搜索 PostgreSQL 全文搜索 MVP 阶段够用,后续考虑 ES

选 PostgreSQL 而不是 MySQL,最重要的原因是 PostgreSQL 对时间和时区的处理更好。timestamptz 类型自动处理时区转换,tstzrange 可以直接做时间范围查询和冲突检测。

前端

组件 选型 理由
框架 Vue 3 + TypeScript 现代前端开发体验
UI 库 Element Plus 组件丰富
日历组件 FullCalendar 功能完整,支持多种视图
状态管理 Pinia Vue 3 官方推荐
HTTP Axios 标准选择

FullCalendar 是目前最好的日历 UI 组件库,支持月/周/日视图,拖拽创建和编辑事件,和 Vue 3 集成也很方便。

基础设施

组件 选型
容器化 Docker + Docker Compose
CI/CD GitLab CI
监控 Prometheus + Grafana
日志 ELK

系统架构

整体是标准的前后端分离架构:

                    ┌──────────┐
                    │  Nginx   │
                    │ (反向代理) │
                    └────┬─────┘
                         │
              ┌──────────┼──────────┐
              │                     │
     ┌────────▼────────┐  ┌────────▼────────┐
     │   Vue 3 前端     │  │  Spring Boot    │
     │  (FullCalendar)  │  │   REST API      │
     └─────────────────┘  └───┬────┬────┬───┘
                              │    │    │
                    ┌─────────┘    │    └─────────┐
                    │              │              │
             ┌──────▼──────┐ ┌────▼─────┐ ┌─────▼──────┐
             │ PostgreSQL  │ │  Redis   │ │ RabbitMQ   │
             │  (主数据库)  │ │  (缓存)  │ │ (消息队列)  │
             └─────────────┘ └──────────┘ └──────┬─────┘
                                                 │
                                          ┌──────▼──────┐
                                          │ 通知服务     │
                                          │ (邮件/webhook)│
                                          └─────────────┘

后端按模块划分:

  • calendar-api:REST API 层,处理 HTTP 请求
  • calendar-service:业务逻辑层
  • calendar-dal:数据访问层
  • calendar-common:公共模型和工具
  • calendar-notification:通知服务(独立部署)

开发排期建议

可以分几个阶段推进:

第一阶段(4 周):基础 CRUD

  • 数据库设计和建表
  • 日程 CRUD API
  • 前端基础日历视图
  • 用户认证集成

第二阶段(3 周):重复事件

  • RRULE 解析和存储
  • 重复事件的展开和查询
  • 单次修改(exception)处理

第三阶段(2 周):提醒和通知

  • 提醒调度服务
  • 邮件和站内通知
  • RabbitMQ 消息投递

第四阶段(3 周):协作功能

  • 参与者邀请和状态管理
  • 日历共享和权限
  • 空闲/忙碌查询

第五阶段(2 周):测试和上线

  • 集成测试
  • 性能测试
  • 灰度发布

总计约 14 周。接下来的文章会按开发进度逐步展开每个模块的实现细节。下一篇先聊数据库设计——日历系统的数据模型是最关键的基础,设计好了后面会顺畅很多。