# 📍 Footprint - 打卡定位系统 一个基于 Node.js + React 的全栈打卡定位应用,支持记录地理位置、心情和备注,并为高级用户提供完整的 API 访问。 ## ✨ 功能特性 ### 基础功能 - 🌍 **地理定位打卡** - 使用浏览器 Geolocation API 获取当前位置 - 🕐 **时间记录** - 自动记录打卡时间 - 😊 **心情记录** - 8种心情选项(开心、平静、难过、生气、疲惫、思考、喜爱、兴奋) - 📝 **备注功能** - 可添加文字备注 - 🗺️ **地图展示** - 在地图上可视化所有打卡记录 - 📊 **统计信息** - 查看总打卡次数、打卡天数等统计数据 ### 高级功能 - 🔐 **OAuth2 认证** - 支持 Google 和 GitHub 登录 - ⭐ **高级用户系统** - 免费升级获取 API 访问权限 - 🔑 **API Key 管理** - 为高级用户生成专属 API 密钥 - 📡 **REST API** - 导出打卡数据(支持 JSON、CSV、GeoJSON 格式) - 📚 **API 文档** - 内置完整的 API 使用文档和示例代码 - 🐳 **Docker 支持** - 一键容器化部署 ## 🛠️ 技术栈 ### 后端 - **Node.js** + **Express** - Web 框架 - **SQLite** (better-sqlite3) - 轻量级数据库 - **Passport.js** - OAuth2 认证 - **JWT** - Token 认证 - **Helmet** - 安全防护 - **Morgan** - 日志记录 ### 前端 - **React** 18 - UI 框架 - **React Router** - 路由管理 - **Axios** - HTTP 客户端 - **Leaflet** + **React-Leaflet** - 地图组件 - **Tailwind CSS** - 样式框架 - **date-fns** - 日期处理 ### 部署 - **Docker** + **Docker Compose** - 容器化 - **Nginx** - 前端静态文件服务 ## 📦 项目结构 ``` footprint/ ├── backend/ # 后端服务 │ ├── src/ │ │ ├── config/ # 配置文件(数据库、Passport) │ │ ├── controllers/ # 控制器 │ │ ├── middleware/ # 中间件(认证) │ │ ├── routes/ # 路由 │ │ └── index.js # 入口文件 │ ├── database/ # SQLite 数据库文件 │ ├── package.json │ ├── Dockerfile │ └── .env.example # 环境变量示例 │ ├── frontend/ # 前端应用 │ ├── public/ │ ├── src/ │ │ ├── components/ # React 组件 │ │ ├── pages/ # 页面组件 │ │ ├── services/ # API 服务 │ │ ├── utils/ # 工具函数(地理定位) │ │ ├── App.js # 主应用 │ │ └── index.js # 入口文件 │ ├── package.json │ ├── Dockerfile │ └── nginx.conf # Nginx 配置 │ ├── docker-compose.yml # Docker Compose 配置 ├── .gitignore └── README.md ``` ## 🚀 快速开始 ### 前置要求 - Node.js 18+ - npm 或 yarn - Docker 和 Docker Compose(可选,用于容器化部署) ### 方式一:本地开发 #### 1. 克隆项目并安装依赖 ```bash # 安装后端依赖 cd backend npm install # 安装前端依赖 cd ../frontend npm install ``` #### 2. 配置环境变量 在 `backend` 目录下创建 `.env` 文件: ```bash cp .env.example .env ``` 编辑 `.env` 文件,配置 OAuth2 凭据: ```env # Google OAuth2 GOOGLE_CLIENT_ID=你的Google客户端ID GOOGLE_CLIENT_SECRET=你的Google客户端密钥 # GitHub OAuth2 GITHUB_CLIENT_ID=你的GitHub客户端ID GITHUB_CLIENT_SECRET=你的GitHub客户端密钥 ``` **获取 OAuth2 凭据:** - Google: https://console.cloud.google.com/ - GitHub: https://github.com/settings/developers #### 3. 初始化数据库 ```bash cd backend npm run init-db ``` #### 4. 启动服务 ```bash # 启动后端(在 backend 目录) npm run dev # 启动前端(在 frontend 目录,新终端) cd ../frontend npm start ``` 访问: - 前端: http://localhost:3000 - 后端: http://localhost:5000 ### 方式二:Docker 部署 #### 1. 配置环境变量 在项目根目录创建 `.env` 文件(或修改 docker-compose.yml): ```env JWT_SECRET=your-jwt-secret-key SESSION_SECRET=your-session-secret GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-client-secret GITHUB_CLIENT_ID=your-github-client-id GITHUB_CLIENT_SECRET=your-github-client-secret ``` #### 2. 构建并启动容器 ```bash docker-compose up -d ``` #### 3. 查看日志 ```bash docker-compose logs -f ``` #### 4. 停止服务 ```bash docker-compose down ``` 访问: - 前端: http://localhost:3000 - 后端: http://localhost:5000 ## 📖 API 文档 ### 认证 所有高级 API 需要在请求头中包含 API Key: ``` X-API-Key: your-api-key ``` ### 端点 #### 1. 获取所有打卡记录 ``` GET /api/v1/checkins ``` **查询参数:** - `format` - 返回格式: `json` | `csv` | `geojson` (默认: json) - `start_date` - 开始日期 (可选) - `end_date` - 结束日期 (可选) - `limit` - 返回数量 (默认: 1000) **示例:** ```bash curl -X GET "http://localhost:5000/api/v1/checkins?format=json" \ -H "X-API-Key: your-api-key" ``` #### 2. 获取统计信息 ``` GET /api/v1/stats ``` **示例:** ```bash curl -X GET "http://localhost:5000/api/v1/stats" \ -H "X-API-Key: your-api-key" ``` ### Python 示例 ```python import requests API_KEY = "your-api-key" BASE_URL = "http://localhost:5000/api/v1" headers = {"X-API-Key": API_KEY} # 获取 JSON 格式数据 response = requests.get(f"{BASE_URL}/checkins", headers=headers) data = response.json() # 下载 CSV response = requests.get(f"{BASE_URL}/checkins?format=csv", headers=headers) with open("checkins.csv", "w") as f: f.write(response.text) # 下载 GeoJSON(可导入地图软件) response = requests.get(f"{BASE_URL}/checkins?format=geojson", headers=headers) with open("checkins.geojson", "w") as f: f.write(response.text) ``` ### JavaScript 示例 ```javascript const API_KEY = "your-api-key"; const BASE_URL = "http://localhost:5000/api/v1"; // 获取打卡记录 fetch(`${BASE_URL}/checkins`, { headers: { 'X-API-Key': API_KEY } }) .then(res => res.json()) .then(data => console.log(data)); ``` ## 🔒 安全性 - ✅ Helmet.js 安全头 - ✅ CORS 跨域保护 - ✅ 速率限制 - ✅ JWT Token 认证 - ✅ API Key 认证 - ✅ OAuth2 第三方登录 - ✅ 环境变量管理敏感信息 ## 📱 多客户端支持 ### Web 浏览器 直接访问部署的网址即可使用。 ### 移动端 由于使用响应式设计,可以在移动浏览器中使用。 ### 第三方应用 使用高级用户 API,任何客户端都可以集成: - 移动 App - 桌面应用 - 命令行工具 - 自动化脚本 ## 🤝 贡献 欢迎提交 Issue 和 Pull Request! ## 📄 许可证 MIT License ## 🙏 致谢 - [OpenStreetMap](https://www.openstreetmap.org/) - 地图数据 - [Leaflet](https://leafletjs.com/) - 地图库 - [Tailwind CSS](https://tailwindcss.com/) - CSS 框架