公开日历站点:同时展示阳历 / 阴历,界面简洁,支持 Web 与移动端。
- 这是一个日历站点
- 界面上显示阳历和阴历两种日期信息
- 界面上默认显示当前年、月表,当前日期用红框框起来
- 非工作日的周末用浅红色背景
- 法定节假日用稍微深色些的红色背景
- 用户可以点击年、月、日来选择日期
- 日历表格上要显示传统节假日及二十四节气信息
- 界面保持简洁风格
- 年份选择范围从 1900~未来 3 年
- 支持 web 和移动端
| 层 | 选型 |
|---|---|
| 前端 | 最新稳定 React + TypeScript + Vite + Ant Design |
| 后端 | 最新稳定 FastAPI + Python,uv 管理依赖 |
| 数据 | SQLite(挂载 calendar.db,法定假日 / 调休) |
| 农历节气 | 算法计算(lunar-python),不入库 |
| 部署 | 云服务器 + Docker Compose + Nginx |
| 版本控制 | Git |
前端原则:代码简洁、少抽象,尽量用 antd,降低维护成本。
- 厚后端、薄前端:日历数据由 API 组装;前端只负责展示与配色。
- 前后端零实现耦合:唯一契约是稳定的 HTTP/JSON;技术栈可独立演进。
- OpenAPI 为契约源,接口带版本前缀
/api/v1。 - 展示规则在前端(红框、背景色);文案与业务标记在后端。
浏览器 → Nginx(静态 + 限流 + 反代)
├─ / → Vite SPA(交互万年历,Ant Design)
├─ /y/ /jieqi/ /fangjia/ /sitemap.xml → FastAPI HTML(专题 SEO)
└─ /api/v1 → FastAPI JSON
/ 是原来的交互日历,不要用 Jinja 首页替换。专题页由 FastAPI + Jinja2 输出可抓取 HTML。首页 SEO 靠 index.html 的 meta / FAQ JSON-LD / noscript。manifest.json / sw.js 走静态文件,禁止 SPA try_files 回落到 index.html。
| 接口 | 作用 |
|---|---|
GET /api/v1/health |
健康检查 |
GET /api/v1/meta |
minYear / maxYear |
GET /api/v1/calendar?year=&month= |
月视图格子数据 |
月响应字段:
lunarYearMonth:农历年月(如丙午年六月),供页头展示
格子字段(语义冻结):
date:YYYY-MM-DDday:公历日lunarText:农历文案lunarYearMonth:该日农历年月(如丙午年六月)festival:传统节日(无则为null)solarTerm:二十四节气(无则为null)isWeekend:是否自然周末isLegalHoliday:是否法定节假日isMakeupWorkday:是否调休补班isCurrentMonth:是否属于查询月
约定:
- 兼容变更可新增字段;删改字段或改语义必须上
/api/v2。 - 统一错误体:
{ "code": "...", "message": "..." }。 - 前端不感知 SQLite / 算法库;后端不感知 React / antd。
- Nginx:按 IP 限流。
- FastAPI:应用层限流,超限返回
429,code为RATE_LIMITED。 - 参数严格校验;按月结果可短时缓存。
- 不对外暴露后端端口;不在前端藏密钥。
- SQLite:法定假日、调休上班日(挂载的
calendar.db,勿提交进仓库)。 - 算法库:农历、节气、传统节日文案。
- React + antd:年月选择、月历网格、选中态、周末/假日样式、响应式。
cd backend
uv sync
uv run uvicorn app.main:app --reload --port 9000cd frontend
npm install
npm run devdocker compose up --build -dcalendarsite/
├── backend/ # FastAPI + uv + SQLite + lunar-python
├── frontend/ # React + Vite + TypeScript + Ant Design
├── docker-compose.yml
└── README.md
- Python 版本:3.14(与本机 uv 环境一致)
- 农历库:
lunar-python(sxtwl在 3.14 上无法编译,故改用纯 Python 实现) - 运行时法定假日的唯一真相源是挂载的
calendar.db(勿提交进仓库) backend/app/data/holidays.bootstrap.json仅在首次启动且holiday_days为空时灌入;库里一旦有行就不再读取。改 json 不会改线上假日- 新增或修改假日年份:用 ops API(
OPS_TOKEN/X-Ops-Token),或直接改挂载的calendar.db。不要编造尚未公布的年份