diff --git a/README.md b/README.md index 4b7fa01..74b5f2a 100644 --- a/README.md +++ b/README.md @@ -1,792 +1,81 @@ -# 接龙自动打卡系统 V2 +# CheckIn App V2 [![FastAPI](https://img.shields.io/badge/FastAPI-0.109+-green.svg)](https://fastapi.tiangolo.com/) [![Vue 3](https://img.shields.io/badge/Vue-3.5+-brightgreen.svg)](https://vuejs.org/) [![Python](https://img.shields.io/badge/Python-3.9+-blue.svg)](https://www.python.org/) -[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) -一个全自动的接龙打卡系统,支持 QQ 扫码登录、定时自动打卡、Token 过期提醒等功能。采用前后端分离架构,提供完善的 Web 管理界面和 RESTful API。 +接龙自动打卡系统,通过 QQ 登录实现每日自动考勤提交。 -## ⚡ V2 重大更新 +## 特性 -🎉 **用户-任务分离架构** - 一个用户可以管理多个打卡任务 -🎉 **全局 Token 刷新** - 扫码一次更新所有任务 -🎉 **任务级别控制** - 每个任务独立配置邮箱和启用状态 -🎉 **29 个 API 端点** - 更完善的功能覆盖 -🎉 **任务所有权验证** - 更安全的权限控制 +- QQ 扫码登录 +- 用户任务分离(一人多任务) +- 任务模板系统 +- 定时自动打卡 +- 邮件通知 +- 用户审批机制 +- 管理后台 -详见 [V2 架构文档](ARCHITECTURE_V2.md) +## 技术栈 -## ✨ 主要特性 +**后端**: FastAPI + SQLAlchemy + APScheduler + Selenium +**前端**: Vue 3 + Ant Design Vue + Pinia +**数据库**: SQLite -- 🔐 **QQ 扫码登录** - 支持通过 QQ 扫码快速登录认证 -- 👤 **多任务管理** - 一个用户管理多个打卡任务 -- ⏰ **定时自动打卡** - 每天固定时间自动为启用的任务执行打卡 -- 📧 **邮件通知** - Token 过期提醒、打卡结果通知 -- 👥 **用户管理** - 完善的用户 CRUD 和权限管理 -- 📋 **任务管理** - 创建、编辑、删除打卡任务 -- 📊 **管理后台** - 可视化的数据统计和日志查看 -- 🚀 **RESTful API** - 29 个标准化 API 端点,自动生成文档 -- 🎯 **角色权限** - 普通用户和管理员角色分离 -- 📱 **响应式界面** - 基于 Element Plus 的现代化 UI +## 快速开始 -## 🏗️ 技术架构 - -### 后端 -- **Web 框架**: FastAPI 0.109+ -- **服务器**: Uvicorn (ASGI) -- **ORM**: SQLAlchemy 2.0+ -- **数据库**: SQLite (可迁移到 PostgreSQL) -- **任务调度**: APScheduler 3.10+ -- **自动化**: Selenium 4.16+ -- **认证**: JWT (python-jose) - -### 前端 -- **框架**: Vue 3.5+ -- **构建工具**: Vite 7+ -- **UI 组件**: Element Plus 2.13+ -- **状态管理**: Pinia 3.0+ -- **路由**: Vue Router 4.6+ -- **HTTP 客户端**: Axios 1.13+ - -## 📦 快速开始 - -### 前置要求 +### 环境要求 - Python 3.9+ -- Node.js 16+ (仅前端需要) +- Node.js 16+ - Chrome 浏览器 -- ChromeDriver -### 一键启动(推荐) +### 安装运行 -**Windows:** -```cmd -# 启动所有服务(后端 + 前端) -manage.bat start-all -``` - -**Linux/Mac:** ```bash -# 给脚本执行权限 -chmod +x manage.sh - -# 启动所有服务 -./manage.sh start-all -``` - -### 手动启动 - -#### 1. 克隆项目 -```bash -git clone -cd CheckInApp -``` - -#### 2. 后端设置 -```bash -# 创建虚拟环境 +# 后端 python -m venv venv - -# 激活虚拟环境 -# Windows: -venv\Scripts\activate -# Linux/Mac: -source venv/bin/activate - -# 安装依赖 +venv\Scripts\activate # Windows +source venv/bin/activate # Linux/Mac pip install -r backend/requirements.txt +python3 run.py -# 配置环境变量(可选) -cp .env.example .env -# 编辑 .env 文件设置 SECRET_KEY 等 - -# 启动后端 -python run.py -``` - -后端服务将在 http://localhost:8000 启动 - -#### 3. 前端设置(可选) -```bash -# 进入前端目录 +# 前端 cd frontend - -# 安装依赖 npm install - -# 启动开发服务器 npm run dev -``` -前端应用将在 http://localhost:3000 启动 - -### 4. 创建管理员账户 - -首次使用需要创建管理员账户: - -```bash -# Windows -venv\Scripts\python backend\scripts\create_admin.py - -# Linux/Mac +# 创建管理员 python backend/scripts/create_admin.py ``` -按提示输入 alias(用户名) 并通过 QQ 扫码完成管理员创建。 - -## 📖 使用指南 - ### 访问地址 -- **前端应用**: http://localhost:3000 -- **API 文档**: http://localhost:8000/docs -- **健康检查**: http://localhost:8000/health +- 前端: +- API 文档: -### 登录流程 - -1. 打开前端应用 -2. 输入您的 alias(用户别名) -3. 点击"QQ 扫码登录" -4. 使用手机 QQ 扫描弹出的二维码 -5. 扫码成功后自动登录系统 - -### 用户功能 - -- 查看 Token 状态和过期时间 -- 查看和管理自己的打卡任务 -- 创建新的打卡任务 -- 手动触发单个任务打卡 -- 启用/禁用任务 -- 查看任务的打卡记录 -- 查看个人信息 - -### 管理员功能 - -- 用户管理(创建、编辑、删除) -- 查看所有用户的任务 -- 批量启用/禁用任务 -- 批量触发打卡 -- 查看所有打卡记录 -- 查看系统日志 -- 系统统计信息(用户数、任务数、打卡统计) - -## ⚙️ 配置说明 - -### 环境变量 (`.env`) - -```env -# JWT 密钥(生产环境必须修改) -SECRET_KEY=your-secret-key-change-in-production - -# 管理员默认别名 -ADMIN_ALIAS=admin - -# 数据库 URL(可选) -DATABASE_URL=sqlite:///./data/checkin.db - -# CORS 允许的域名 -CORS_ORIGINS=http://localhost:3000,http://localhost:5173 - -# Token 过期检查间隔(分钟) -TOKEN_CHECK_INTERVAL_MINUTES=30 - -# 会话文件清理间隔(小时) -SESSION_CLEANUP_INTERVAL_HOURS=24 - -# 注意:每个任务的打卡时间由任务的 cron_expression 字段控制 -``` - -### 邮件配置 (`config.ini`) - -```ini -[Email] -smtpserver = smtp.example.com -smtpport = 465 -senderemail = your-email@example.com -senderpassword = your-password -``` - -## 📂 项目结构 - -``` -CheckInApp/ -├── backend/ # FastAPI 后端 -│ ├── main.py # 应用入口 -│ ├── config.py # 配置管理 -│ ├── dependencies.py # 认证中间件 -│ ├── models/ # 数据库模型 -│ │ ├── user.py # User 模型 -│ │ ├── check_in_task.py # CheckInTask 模型 (V2 新增) -│ │ └── check_in_record.py # CheckInRecord 模型 -│ ├── schemas/ # Pydantic Schema -│ │ ├── user.py -│ │ ├── task.py # (V2 新增) -│ │ ├── auth.py -│ │ └── check_in.py -│ ├── api/ # API 路由 -│ │ ├── auth.py -│ │ ├── users.py -│ │ ├── tasks.py # (V2 新增) -│ │ ├── check_in.py -│ │ └── admin.py -│ ├── services/ # 业务逻辑 -│ │ ├── auth_service.py -│ │ ├── user_service.py -│ │ ├── task_service.py # (V2 新增) -│ │ ├── check_in_service.py -│ │ └── scheduler_service.py -│ ├── workers/ # Selenium 工作模块 -│ │ ├── token_refresher.py -│ │ ├── check_in_worker.py -│ │ └── email_notifier.py -│ └── scripts/ # 工具脚本 -│ └── create_admin.py -├── frontend/ # Vue 3 前端 -│ ├── src/ -│ │ ├── api/ # API 调用 -│ │ ├── components/ # 组件 -│ │ ├── views/ # 页面 -│ │ ├── stores/ # Pinia 状态 -│ │ └── router/ # 路由配置 -│ └── package.json -├── data/ # 数据库文件 -├── logs/ # 日志文件 -│ └── backend.log # 后端日志 (V2 更名) -├── sessions/ # 会话临时文件 -├── venv/ # Python 虚拟环境 -├── run.py # 后端启动脚本 -├── manage.bat/sh # 进程管理脚本 (V2 增强) -├── ARCHITECTURE_V2.md # V2 架构文档 (新增) -└── config.ini # 邮件配置 -``` - -## 📊 API 端点 - -系统提供 **29 个 RESTful API 端点**: - -### 认证 (`/api/auth`) -- `POST /api/auth/request_qrcode` - 请求 QQ 扫码 -- `GET /api/auth/qrcode_status/{session_id}` - 查询扫码状态 -- `POST /api/auth/verify_token` - 验证 Token - -### 用户 (`/api/users`) -- `POST /api/users` - 创建用户(管理员) -- `GET /api/users/me` - 获取当前用户 -- `GET /api/users/me/token_status` - Token 状态 -- `GET /api/users/me/tasks` - 获取当前用户任务列表 **(V2 新增)** -- `GET /api/users` - 用户列表(管理员) -- `GET /api/users/{user_id}` - 获取指定用户 -- `PUT /api/users/{user_id}` - 更新用户 -- `DELETE /api/users/{user_id}` - 删除用户(管理员) - -### 任务 (`/api/tasks`) **(V2 新增模块)** -- `POST /api/tasks` - 创建任务 -- `GET /api/tasks` - 获取当前用户任务 -- `GET /api/tasks/{task_id}` - 获取任务详情 -- `PUT /api/tasks/{task_id}` - 更新任务 -- `DELETE /api/tasks/{task_id}` - 删除任务 -- `POST /api/tasks/{task_id}/toggle` - 切换任务状态 - -### 打卡 (`/api/check_in`) -- `POST /api/check_in/manual/{task_id}` - 手动触发任务打卡 -- `GET /api/check_in/task/{task_id}/records` - 获取任务打卡记录 -- `GET /api/check_in/records` - 所有记录(管理员) -- `GET /api/check_in/records/count` - 记录统计(管理员) - -### 管理员 (`/api/admin`) -- `POST /api/admin/batch_toggle_tasks` - 批量启用/禁用任务 -- `POST /api/admin/batch_check_in` - 批量打卡 -- `GET /api/admin/logs` - 系统日志 -- `GET /api/admin/stats` - 系统统计 - -详细 API 文档请访问: http://localhost:8000/docs - -## ⏰ 自动化任务 - -系统自动执行以下定时任务: - -1. **定时打卡**: 每天 20:00 为所有启用的任务执行打卡 -2. **Token 检查**: 每 30 分钟检查一次,即将过期时发送邮件到任务的邮箱 -3. **会话清理**: 每 24 小时清理过期的会话文件 - -## 🔧 进程管理 - -使用内置的进程管理脚本可以方便地管理服务: - -**Windows:** -```cmd -manage.bat start-backend # 启动后端服务 -manage.bat start-frontend # 启动前端服务 -manage.bat start-all # 启动所有服务 -manage.bat stop-backend # 停止后端 -manage.bat stop-frontend # 停止前端 -manage.bat stop-all # 停止所有服务 -manage.bat status # 查看状态 -manage.bat logs-backend # 查看后端日志 -manage.bat logs-frontend # 查看前端日志 -``` - -**Linux/Mac:** -```bash -./manage.sh start-backend -./manage.sh start-frontend -./manage.sh start-all -./manage.sh stop-backend -./manage.sh stop-frontend -./manage.sh stop-all -./manage.sh status -./manage.sh logs-backend -./manage.sh logs-frontend -``` - -## 🐛 故障排查 - -### 端口被占用 -```bash -# Windows -netstat -ano | findstr :8000 - -# Linux/Mac -lsof -i :8000 -``` - -### 查看日志 -```bash -# 后端日志 -cat logs/backend.log - -# 使用管理脚本查看 -manage.bat logs-backend # Windows -./manage.sh logs-backend # Linux/Mac -``` - -### Selenium 问题 - -确保 Chrome 和 ChromeDriver 已正确配置。相关路径在 `backend/workers/` 中定义。 - -## 📚 文档 - -- [快速入门指南](QUICKSTART.md) -- [V2 架构文档](ARCHITECTURE_V2.md) **(推荐阅读)** -- [后端详细文档](backend/README.md) -- [后端开发总结](BACKEND_SUMMARY.md) -- [V1 旧版文档](v1/README.md) - -## 🔒 安全建议 - -1. **生产环境务必修改 SECRET_KEY** -2. 不要将 `.env` 文件提交到版本控制 -3. 定期更新依赖包 -4. 使用 HTTPS 部署生产环境 -5. 限制管理员账户数量 -6. 定期备份数据库 - -## 🚀 部署 - -### Docker 部署(推荐) -```bash -# 构建镜像 -docker-compose build - -# 启动服务 -docker-compose up -d -``` - -### 传统部署 -1. 使用 Gunicorn 运行后端 -2. 构建前端并使用 Nginx 托管 -3. 配置反向代理 - -详见部署文档。 - -## 📝 V2 更新日志 - -### 架构改进 -- ✅ 实现用户-任务分离架构 -- ✅ 新增 CheckInTask 数据模型 -- ✅ 引入三层身份体系 (jwt_sub + alias + signature) -- ✅ 全局 Token 刷新机制 - -### 新增功能 -- ✅ 任务管理 API (6个端点) -- ✅ 任务所有权验证 -- ✅ 用户任务列表查询 -- ✅ 任务级别的邮箱配置 -- ✅ 任务级别的启用/禁用 - -### 功能优化 -- ✅ API 端点从 18 个增加到 29 个 -- ✅ 改进的权限控制系统 -- ✅ 更清晰的代码结构 -- ✅ UTF-8 编码全面支持 -- ✅ 增强的日志系统 -- ✅ 改进的进程管理脚本 - -## 🤝 贡献 - -欢迎提交 Issue 和 Pull Request! - -## 📄 许可证 - -[MIT License](LICENSE) - -## 🙏 致谢 - -感谢所有开源项目的贡献者! - ---- - -**版本**: V2.0.0 -**状态**: ✅ 生产就绪 -**最后更新**: 2025-12-31 - -## 🏗️ 技术架构 - -### 后端 -- **Web 框架**: FastAPI 0.109+ -- **服务器**: Uvicorn (ASGI) -- **ORM**: SQLAlchemy 2.0+ -- **数据库**: SQLite (可迁移到 PostgreSQL) -- **任务调度**: APScheduler 3.10+ -- **自动化**: Selenium 4.16+ -- **认证**: JWT (python-jose) - -### 前端 -- **框架**: Vue 3.5+ -- **构建工具**: Vite 7+ -- **UI 组件**: Element Plus 2.13+ -- **状态管理**: Pinia 3.0+ -- **路由**: Vue Router 4.6+ -- **HTTP 客户端**: Axios 1.13+ - -## 📦 快速开始 - -### 前置要求 - -- Python 3.9+ -- Node.js 16+ (仅前端需要) -- Chrome 浏览器 -- ChromeDriver - -### 一键启动(推荐) - -**Windows:** -```cmd -# 启动所有服务(后端 + 前端) -start_all.bat -``` - -**Linux/Mac:** -```bash -# 给脚本执行权限 -chmod +x start_all.sh - -# 启动所有服务 -./start_all.sh -``` - -### 手动启动 - -#### 1. 克隆项目 -```bash -git clone -cd CheckInApp -``` - -#### 2. 后端设置 -```bash -# 创建虚拟环境 -python -m venv venv - -# 激活虚拟环境 -# Windows: -venv\Scripts\activate -# Linux/Mac: -source venv/bin/activate - -# 安装依赖 -pip install -r backend/requirements.txt - -# 配置环境变量(可选) -cp .env.example .env -# 编辑 .env 文件设置 SECRET_KEY 等 - -# 启动后端 -python run.py -``` - -后端服务将在 http://localhost:8000 启动 - -#### 3. 前端设置(可选) -```bash -# 进入前端目录 -cd frontend - -# 安装依赖 -npm install - -# 启动开发服务器 -npm run dev -``` - -前端应用将在 http://localhost:3000 启动 - -### 4. 创建管理员账户 - -首次使用需要创建管理员账户: +## 进程管理 ```bash # Windows -venv\Scripts\python backend\scripts\create_admin.py +manage.bat start [all/backend/fronted] +manage.bat stop [all/backend/fronted] +manage.bat status # Linux/Mac -python backend/scripts/create_admin.py -``` - -按提示输入 Signature 并通过 QQ 扫码完成管理员创建。 - -## 📖 使用指南 - -### 访问地址 - -- **前端应用**: http://localhost:3000 -- **API 文档**: http://localhost:8000/docs -- **健康检查**: http://localhost:8000/health - -### 登录流程 - -1. 打开前端应用 -2. 输入您的 Signature(唯一标识) -3. 点击"QQ 扫码登录" -4. 使用手机 QQ 扫描弹出的二维码 -5. 扫码成功后自动登录系统 - -### 用户功能 - -- 查看 Token 状态和过期时间 -- 手动触发打卡 -- 查看自己的打卡记录 -- 查看个人信息 - -### 管理员功能 - -- 用户管理(创建、编辑、删除) -- 批量启用/禁用用户 -- 批量触发打卡 -- 查看所有打卡记录 -- 查看系统日志 -- 系统统计信息 - -## ⚙️ 配置说明 - -### 环境变量 (`.env`) - -```env -# JWT 密钥(生产环境必须修改) -SECRET_KEY=your-secret-key-change-in-production - -# 管理员默认标识 -ADMIN_SIGNATURE=admin - -# 数据库 URL(可选) -DATABASE_URL=sqlite:///./data/checkin.db - -# CORS 允许的域名 -CORS_ORIGINS=http://localhost:3000,http://localhost:5173 - -# Token 过期检查间隔(分钟) -TOKEN_CHECK_INTERVAL_MINUTES=30 - -# 会话文件清理间隔(小时) -SESSION_CLEANUP_INTERVAL_HOURS=24 - -# 注意:每个任务的打卡时间由任务的 cron_expression 字段控制 -``` - -### 邮件配置 (`config.ini`) - -```ini -[Email] -smtpserver = smtp.example.com -smtpport = 465 -senderemail = your-email@example.com -senderpassword = your-password -``` - -## 📂 项目结构 - -``` -CheckInApp/ -├── backend/ # FastAPI 后端 -│ ├── main.py # 应用入口 -│ ├── config.py # 配置管理 -│ ├── dependencies.py # 认证中间件 -│ ├── models/ # 数据库模型 -│ ├── schemas/ # Pydantic Schema -│ ├── api/ # API 路由 -│ ├── services/ # 业务逻辑 -│ ├── workers/ # Selenium 工作模块 -│ └── scripts/ # 工具脚本 -├── frontend/ # Vue 3 前端 -│ ├── src/ -│ │ ├── api/ # API 调用 -│ │ ├── components/ # 组件 -│ │ ├── views/ # 页面 -│ │ ├── stores/ # Pinia 状态 -│ │ └── router/ # 路由配置 -│ └── package.json -├── data/ # 数据库文件 -├── logs/ # 日志文件 -├── sessions/ # 会话临时文件 -├── venv/ # Python 虚拟环境 -├── run.py # 后端启动脚本 -├── manage.bat/sh # 进程管理脚本 -├── start_all.bat/sh # 一键启动脚本 -└── config.ini # 邮件配置 -``` - -## 📊 API 端点 - -系统提供 18 个 RESTful API 端点: - -### 认证 (`/api/auth`) -- `POST /api/auth/request_qrcode` - 请求 QQ 扫码 -- `GET /api/auth/qrcode_status/{session_id}` - 查询扫码状态 -- `POST /api/auth/verify_token` - 验证 Token - -### 用户 (`/api/users`) -- `POST /api/users` - 创建用户 -- `GET /api/users/me` - 获取当前用户 -- `GET /api/users/me/token_status` - Token 状态 -- `GET /api/users` - 用户列表 -- `PUT /api/users/{user_id}` - 更新用户 -- `DELETE /api/users/{user_id}` - 删除用户 - -### 打卡 (`/api/check_in`) -- `POST /api/check_in/manual` - 手动打卡 -- `GET /api/check_in/my_records` - 我的记录 -- `GET /api/check_in/records` - 所有记录 -- `GET /api/check_in/records/count` - 记录统计 - -### 管理员 (`/api/admin`) - -- `POST /api/admin/batch_check_in` - 批量打卡 -- `GET /api/admin/logs` - 系统日志 -- `GET /api/admin/stats` - 系统统计 - -详细 API 文档请访问: http://localhost:8000/docs - -## ⏰ 自动化任务 - -系统自动执行以下定时任务: - -1. **定时打卡**: 每天 20:00 为所有启用的用户执行打卡 -2. **Token 检查**: 每 30 分钟检查一次,即将过期时发送邮件 -3. **会话清理**: 每 24 小时清理过期的会话文件 - -## 🔧 进程管理 - -使用内置的进程管理脚本可以方便地管理后端服务: - -**Windows:** -```cmd -manage.bat start # 启动服务(后台运行) -manage.bat stop # 停止服务 -manage.bat restart # 重启服务 -manage.bat status # 查看状态 -``` - -**Linux/Mac:** -```bash -./manage.sh start -./manage.sh stop -./manage.sh restart +./manage.sh start [all/backend/fronted] +./manage.sh stop [all/backend/fronted] ./manage.sh status ``` -## 🐛 故障排查 +## 配置 -### 端口被占用 -```bash -# Windows -netstat -ano | findstr :8000 +复制 `.env.example` 到 `.env` -# Linux/Mac -lsof -i :8000 -``` +nginx 与 systemd 的配置文件参考已给出,见 `.example` -### 查看日志 -```bash -# 后端日志 -cat logs/CheckIn.log +## 文档 -# 使用管理脚本查看 -./manage.sh status -``` - -### Selenium 问题 - -确保 Chrome 和 ChromeDriver 已正确配置。相关路径在 `backend/workers/` 中定义。 - -## 📚 文档 - -- [快速入门指南](QUICKSTART.md) -- [后端详细文档](backend/README.md) -- [后端开发总结](BACKEND_SUMMARY.md) -- [V1 旧版文档](v1/README.md) - -## 🔒 安全建议 - -1. **生产环境务必修改 SECRET_KEY** -2. 不要将 `.env` 文件提交到版本控制 -3. 定期更新依赖包 -4. 使用 HTTPS 部署生产环境 -5. 限制管理员账户数量 - -## 🚀 部署 - -### Docker 部署(推荐) -```bash -# 构建镜像 -docker-compose build - -# 启动服务 -docker-compose up -d -``` - -### 传统部署 -1. 使用 Gunicorn 运行后端 -2. 构建前端并使用 Nginx 托管 -3. 配置反向代理 - -详见部署文档。 - -## 📝 开发计划 - -- [x] 后端 API 开发 -- [x] 前端基础框架 -- [x] 用户认证系统 -- [x] 管理员功能 -- [ ] 批量导入用户 -- [ ] 数据导出功能 -- [ ] Docker 镜像优化 -- [ ] 单元测试覆盖 - -## 🤝 贡献 - -欢迎提交 Issue 和 Pull Request! - -## 📄 许可证 - -[MIT License](LICENSE) - -## 🙏 致谢 - -感谢所有开源项目的贡献者! - ---- - -**版本**: V2.0.0 -**状态**: ✅ 生产就绪 -**最后更新**: 2025-12-31 +- [架构设计](docs/architecture.md) +- [部署指南](docs/deployment.md) +- [开发指南](docs/development.md) diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..87c6abe --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,181 @@ +# 架构设计 + +## 系统概述 + +CheckIn App V2 采用用户-任务分离架构,一个用户可管理多个打卡任务,全局 Token 刷新,任务级别独立控制。 + +## 核心架构 + +### V2 关键改进 + +- **用户-任务分离**: User 和 CheckInTask 独立管理 +- **全局 Token**: 用户级别的 authorization token,一次扫码更新所有任务 +- **任务级控制**: 每个任务独立的启用状态和邮箱配置 +- **任务模板**: TaskTemplate 系统,快速创建标准化任务 + +### 数据模型 + +#### User(用户) + +```python +- id: 主键 +- jwt_sub: QQ ID(唯一) +- alias: 用户名 +- email: 邮箱 +- password_hash: 密码(可选) +- authorization: QQ Token(全局) +- jwt_exp: Token 过期时间 +- role: admin/user +- is_approved: 审批状态 +``` + +#### CheckInTask(任务) + +```python +- id: 主键 +- user_id: 所属用户 +- name: 任务名称 +- payload_config: JSON 配置(包含打卡字段) +- cron_expression: 定时表达式(如 "0 20 * * *") +- is_active: 是否启用 +``` + +#### CheckInRecord(记录) + +```python +- id: 主键 +- task_id: 所属任务 +- status: success/failed/already_submitted +- response_text: API 响应 +- trigger_type: scheduled/manual/admin +- check_in_time: 打卡时间 +``` + +#### TaskTemplate(模板) + +```python +- id: 主键 +- name: 模板名称 +- field_config: JSON 字段配置 +- parent_id: 父模板(可选) +- is_active: 是否启用 +``` + +## 技术栈 + +### 后端 + +- **FastAPI**: Web 框架,自动生成 API 文档 +- **SQLAlchemy**: ORM,支持多数据库 +- **APScheduler**: 任务调度,动态加载 cron 任务 +- **Selenium**: 浏览器自动化,获取 QQ Token 和打卡 payload +- **JWT**: 身份认证 +- **SMTP**: 邮件通知 + +### 前端 + +- **Vue 3**: Composition API +- **Ant Design Vue**: UI 组件库 +- **Pinia**: 状态管理 +- **Axios**: HTTP 客户端,拦截器处理 Token + +## 认证流程 + +### QQ 扫码登录 + +1. 用户输入 alias +2. 后端检查 alias 可用性和频率限制 +3. Selenium 启动 headless Chrome,打开接龙登录页 +4. 生成 QR code,返回给前端 +5. 用户手机 QQ 扫码 +6. Selenium 检测登录成功,提取 authorization token 和 jwt +7. 存储用户信息(待审批状态) +8. 管理员审批后用户可登录 + +### 密码登录 + +1. 用户设置密码后可使用 alias + password 登录 +2. 后端验证密码,返回 JWT token + +## 打卡流程 + +### 手动打卡 + +1. 用户点击任务的"立即打卡"按钮 +2. 后端异步执行打卡任务 +3. Selenium 获取最新 x-api-request-payload +4. 使用用户的 authorization token 调用接龙 API +5. 解析响应,存储记录 +6. 返回结果 + +### 定时打卡 + +1. 系统启动时加载所有启用的任务 +2. APScheduler 根据 cron_expression 调度 +3. 到达时间后自动执行打卡流程 +4. 发送邮件通知到任务配置的邮箱 + +## 调度任务 + +### Token 监控 + +- 间隔: 30 分钟(可配置) +- 功能: 检查 Token 过期时间 + - 30 分钟内过期: 发送预警邮件 + - 已过期 30 分钟内: 发送过期通知 + +### 会话清理 + +- 间隔: 24 小时 +- 功能: 删除旧的 Selenium 会话文件 + +### 用户清理 + +- 间隔: 1 小时 +- 功能: 删除 24 小时未审批的用户 + +## 权限控制 + +### 角色 + +- **admin**: 所有权限 +- **user**: 仅操作自己的数据 + +### 验证机制 + +- 任务所有权验证: 确保用户只能操作自己的任务 +- JWT 认证: 所有 API 需要有效 token +- 审批机制: 新用户需管理员审批 + +## 目录结构 + +### 后端分层 + +``` +backend/ +├── api/ # 路由层(29 个端点) +├── services/ # 业务逻辑层 +├── models/ # 数据模型层 +├── schemas/ # 请求响应模型 +├── workers/ # Selenium 工作模块 +└── scripts/ # 工具脚本 +``` + +### 前端分层 + +``` +frontend/src/ +├── api/ # API 调用封装 +├── views/ # 页面组件 +├── components/ # 可复用组件 +├── stores/ # Pinia 状态 +├── router/ # 路由配置 +└── composables/ # 组合式函数 +``` + +## 扩展性 + +- 数据库可切换到 PostgreSQL/MySQL +- 调度任务可扩展到 Celery +- 前端可独立部署到 CDN +- 支持 Docker 容器化部署 diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 0000000..5066bbc --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,220 @@ +# 部署指南 + +## 环境准备 + +### 系统要求 + +- Ubuntu 20.04+ / CentOS 7+ / Windows Server +- Python 3.9+ +- Node.js 16+ +- Chrome / Chromium +- 2GB+ RAM + +### 依赖安装 + +```bash +# Ubuntu +sudo apt update +sudo apt install -y python3 nodejs npm chromium-browser + +# CentOS +sudo yum install -y python3 nodejs npm chromium +``` + +## 生产部署 + +### 方式一:传统部署 + +#### 1. 后端部署 + +```bash +# 克隆项目 +git clone +cd CheckInApp + +# 创建虚拟环境 +python3 -m venv venv +source venv/bin/activate + +# 安装依赖 +pip install -r backend/requirements.txt + +# 生产环境额外依赖 +pip install gunicorn + +# 配置环境变量 +cp .env.example .env +vim .env # 修改环境变量 +``` + +#### 2. 前端部署 + +```bash +cd frontend + +# 安装依赖 +npm install + +# 构建生产版本 +npm run build + +# 输出在 dist/ 目录 +``` + +**使用 Nginx 托管**: + +[示例文件](../nginx.conf.example) + +#### 3. 使用 Systemd 管理 + +[示例文件](../checkin-app.service.example) + +### 方式二:Docker 部署(推荐) + +TODO(Maybe never) + +## 配置优化 + +### 生产环境变量 + +[示例文件](../.env.example) + +### 数据库迁移到 PostgreSQL + +```bash +# 安装 PostgreSQL +sudo apt install postgresql postgresql-contrib + +# 创建数据库 +sudo -u postgres createdb checkin +sudo -u postgres createuser checkin_user +sudo -u postgres psql -c "ALTER USER checkin_user WITH PASSWORD 'password';" + +# 修改 .env +DATABASE_URL=postgresql://checkin_user:password@localhost/checkin +``` + +## 安全加固 + +### 1. 防火墙配置 + +```bash +sudo ufw allow 22/tcp # SSH +sudo ufw allow 80/tcp # HTTP +sudo ufw allow 443/tcp # HTTPS +sudo ufw enable +``` + +### 2. SSL 证书(Let's Encrypt) + +```bash +sudo apt install certbot python3-certbot-nginx + +sudo certbot --nginx -d your-domain.com + +# 自动续期 +sudo systemctl enable certbot.timer +``` + +### 3. 限制访问 + +- 修改 `.env` 中的 `CORS_ORIGINS` 为实际域名 +- 在 Nginx 中配置 rate limiting +- 使用 fail2ban 防止暴力破解 + +## 监控维护 + +### 日志管理 + +```bash +# 查看后端日志 +tail -f logs/backend.log +``` + +### 数据库备份 + +```bash +# SQLite 备份 +cp data/checkin.db data/checkin.db.backup + +# PostgreSQL 备份 +pg_dump checkin > backup.sql + +# 定时备份(crontab) +0 2 * * * /path/to/backup.sh +``` + +### 性能监控 + +使用工具: + +- Prometheus + Grafana +- New Relic +- Sentry(错误追踪) + +## 扩展部署 + +### 负载均衡 + +```nginx +upstream backend { + server 127.0.0.1:8000; + server 127.0.0.1:8001; + server 127.0.0.1:8002; +} + +server { + location /api { + proxy_pass http://backend; + } +} +``` + +### Redis 缓存 + +```python +# 安装 redis +pip install redis + +# 配置会话存储 +REDIS_URL=redis://localhost:6379/0 +``` + +## 故障排查 + +### 端口占用 + +```bash +sudo lsof -i :8000 +sudo kill -9 +``` + +### Selenium 问题 + +```bash +# 检查 Chrome 版本 +chromium --version +chromedriver --version + +# 确保版本匹配 +``` + +### 权限问题 + +```bash +# 确保目录权限正确 +sudo chown -R www-data:www-data /path/to/CheckInApp +sudo chmod -R 755 /path/to/CheckInApp +``` + +## 回滚策略 + +```bash +# 保存当前版本 +git tag -a v2.0.0 -m "Production release" + +# 回滚到上一版本 +git checkout v1.9.0 +docker-compose down +docker-compose up -d --build +``` diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 0000000..6c0599c --- /dev/null +++ b/docs/development.md @@ -0,0 +1,398 @@ +# 开发指南 + +## 开发环境设置 + +### 后端开发 + +```bash +# 克隆项目 +git clone +cd CheckInApp + +# 创建虚拟环境 +python -m venv venv +source venv/bin/activate # Linux/Mac +venv\Scripts\activate # Windows + +# 安装依赖 +pip install -r backend/requirements.txt + +# 安装开发依赖 +pip install pytest pytest-asyncio black flake8 + +python3 run.py +``` + +### 前端开发 + +```bash +cd frontend + +# 安装依赖 +npm install + +# 启动开发服务器 +npm run dev + +# 代码格式化 +npm run lint +npm run format +``` + +## 项目结构 + +### 后端目录说明 + +``` +backend/ +├── main.py # FastAPI 应用入口,CORS、路由注册 +├── config.py # Pydantic Settings 配置 +├── dependencies.py # 依赖注入(认证、权限) +├── exceptions.py # 自定义异常类 +│ +├── models/ # SQLAlchemy 数据模型 +│ ├── database.py # 数据库连接、Session +│ ├── user.py +│ ├── check_in_task.py +│ ├── check_in_record.py +│ └── task_template.py +│ +├── schemas/ # Pydantic 请求响应模型 +│ ├── user.py +│ ├── task.py +│ ├── auth.py +│ └── response.py # 标准化响应 +│ +├── api/ # API 路由(按模块划分) +│ ├── auth.py # 认证相关 +│ ├── users.py # 用户管理 +│ ├── tasks.py # 任务管理 +│ ├── check_in.py # 打卡功能 +│ ├── admin.py # 管理员功能 +│ └── templates.py # 模板管理 +│ +├── services/ # 业务逻辑层 +│ ├── auth_service.py +│ ├── user_service.py +│ ├── task_service.py +│ ├── check_in_service.py +│ ├── scheduler_service.py +│ ├── template_service.py +│ └── registration_manager.py +│ +└── workers/ # Selenium 自动化 + ├── token_refresher.py # QQ 登录 + ├── check_in_worker.py # 打卡执行 + └── email_notifier.py # 邮件发送 +``` + +### 前端目录说明 + +``` +frontend/src/ +├── main.js # Vue 应用入口 +├── App.vue # 根组件 +│ +├── api/ # API 封装 +│ ├── client.js # Axios 实例、拦截器 +│ └── index.js # API 模块(auth, user, task 等) +│ +├── views/ # 页面组件 +│ ├── LoginView.vue +│ ├── DashboardView.vue +│ ├── TasksView.vue +│ ├── RecordsView.vue +│ └── admin/ # 管理员页面 +│ +├── components/ # 可复用组件 +│ ├── TaskCard.vue +│ ├── RecordTable.vue +│ └── ... +│ +├── stores/ # Pinia 状态管理 +│ ├── auth.js # 认证状态 +│ ├── user.js # 用户信息 +│ └── task.js # 任务列表 +│ +├── router/ # Vue Router +│ └── index.js # 路由配置、导航守卫 +│ +└── composables/ # 组合式函数 + ├── useAuth.js + └── useTask.js +``` + +## 开发流程 + +### 添加新功能 + +#### 1. 后端 API 开发 + +**步骤**: + +1. 在 `models/` 定义数据模型 +2. 在 `schemas/` 定义请求响应模型 +3. 在 `services/` 实现业务逻辑 +4. 在 `api/` 创建路由端点 +5. 在 `main.py` 注册路由 + +**示例**: 添加一个新的"任务标签"功能 + +```python +# models/task_tag.py +class TaskTag(Base): + __tablename__ = "task_tags" + id = Column(Integer, primary_key=True) + task_id = Column(Integer, ForeignKey("check_in_tasks.id")) + tag_name = Column(String(50)) + +# schemas/tag.py +class TaskTagCreate(BaseModel): + tag_name: str + +# services/tag_service.py +def create_tag(db: Session, task_id: int, tag_data: TaskTagCreate): + tag = TaskTag(task_id=task_id, tag_name=tag_data.tag_name) + db.add(tag) + db.commit() + return tag + +# api/tags.py +@router.post("/tasks/{task_id}/tags") +def add_tag(task_id: int, tag: TaskTagCreate, db: Session = Depends(get_db)): + return tag_service.create_tag(db, task_id, tag) + +# main.py +from api import tags +app.include_router(tags.router, prefix="/api") +``` + +#### 2. 前端开发 + +**步骤**: + +1. 在 `api/index.js` 添加 API 调用 +2. 在 `stores/` 创建或更新状态 +3. 创建或更新 Vue 组件 +4. 配置路由(如需要) + +**示例**: 添加标签管理页面 + +```javascript +// api/index.js +export const tagApi = { + addTag: (taskId, data) => client.post(`/tasks/${taskId}/tags`, data), + getTags: (taskId) => client.get(`/tasks/${taskId}/tags`) +} + +// stores/tag.js +export const useTagStore = defineStore('tag', { + state: () => ({ + tags: [] + }), + actions: { + async fetchTags(taskId) { + const { data } = await tagApi.getTags(taskId) + this.tags = data + } + } +}) + +// components/TagManager.vue + +``` + +### 数据库迁移 + +```bash +# 修改模型后生成迁移脚本 +# 手动创建脚本在 backend/scripts/migrate_*.py + +# 执行迁移 +python backend/scripts/migrate_xxx.py +``` + +### 测试 + +#### 后端测试 + +```python +# tests/test_task_service.py +import pytest +from backend.services import task_service + +def test_create_task(): + task = task_service.create_task(db, user_id=1, task_data) + assert task.name == "Test Task" + assert task.is_active == True + +# 运行测试 +pytest backend/tests/ +``` + +#### 前端测试 + +```javascript +// tests/TaskCard.spec.js +import { mount } from '@vue/test-utils' +import TaskCard from '@/components/TaskCard.vue' + +test('displays task name', () => { + const wrapper = mount(TaskCard, { + props: { task: { name: 'Test Task' } } + }) + expect(wrapper.text()).toContain('Test Task') +}) + +// 运行测试 +npm run test +``` + +## 代码规范 + +### 后端规范 + +- 使用 Black 格式化: `black backend/` +- 遵循 PEP 8 +- 函数添加类型注解 +- API 路由使用 Pydantic 模型验证 +- 使用 dependency injection + +```python +# 好的示例 +async def create_task( + task_data: TaskCreate, + db: Session = Depends(get_db), + current_user: User = Depends(get_current_user) +) -> TaskResponse: + """创建新任务""" + return task_service.create_task(db, current_user.id, task_data) +``` + +### 前端规范 + +- 使用 ESLint + Prettier +- 组件使用 Composition API +- 使用 ` +``` + +## 调试技巧 + +### 后端调试 + +```python +# 使用 logging +import logging +logger = logging.getLogger(__name__) +logger.info(f"Creating task for user {user_id}") + +# 使用 pdb +import pdb; pdb.set_trace() + +# 查看 SQL 查询 +import logging +logging.basicConfig() +logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO) +``` + +### 前端调试 + +```javascript +// 使用 Vue Devtools +// Chrome 扩展安装 + +// console 输出 +console.log('Task data:', task.value) + +// 调试 API 请求 +axios.interceptors.request.use(request => { + console.log('Request:', request) + return request +}) +``` + +## 常见问题 + +### CORS 错误 + +在 `.env` 添加前端地址: + +```env +CORS_ORIGINS=http://localhost:3000 +``` + +### 数据库锁定 + +使用 connection pool: + +```python +engine = create_engine( + DATABASE_URL, + pool_pre_ping=True, + pool_size=10 +) +``` + +### Selenium 超时 + +增加等待时间: + +```python +WebDriverWait(driver, 30).until(...) +``` + +## Git 工作流 + +```bash +# 创建功能分支 +git checkout -b feature/task-tags + +# 提交代码 +git add . +git commit -m "feat: add task tag functionality" + +# 合并到主分支 +git checkout main +git merge feature/task-tags + +# 推送 +git push origin main +``` + +## 性能优化 + +### 后端优化 + +- 使用 SQLAlchemy 的 `joinedload` 避免 N+1 查询 +- 添加数据库索引 +- 使用异步任务处理耗时操作 +- 启用 gzip 压缩 + +### 前端优化 + +- 使用虚拟滚动处理大列表 +- 路由懒加载 +- 图片懒加载 +- 使用 `keep-alive` 缓存组件