本系列记录从零搭建一个日历系统的完整过程,从需求分析到最终上线。第一篇聊需求和技术选型。
为什么需要日历系统
企业内部的日程管理通常有定制需求:
- 需要和内部 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 周。接下来的文章会按开发进度逐步展开每个模块的实现细节。下一篇先聊数据库设计——日历系统的数据模型是最关键的基础,设计好了后面会顺畅很多。