6.8 KiB
6.8 KiB
📍 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. 克隆项目并安装依赖
# 安装后端依赖
cd backend
npm install
# 安装前端依赖
cd ../frontend
npm install
2. 配置环境变量
在 backend 目录下创建 .env 文件:
cp .env.example .env
编辑 .env 文件,配置 OAuth2 凭据:
# Google OAuth2
GOOGLE_CLIENT_ID=你的Google客户端ID
GOOGLE_CLIENT_SECRET=你的Google客户端密钥
# GitHub OAuth2
GITHUB_CLIENT_ID=你的GitHub客户端ID
GITHUB_CLIENT_SECRET=你的GitHub客户端密钥
获取 OAuth2 凭据:
3. 初始化数据库
cd backend
npm run init-db
4. 启动服务
# 启动后端(在 backend 目录)
npm run dev
# 启动前端(在 frontend 目录,新终端)
cd ../frontend
npm start
访问:
方式二:Docker 部署
1. 配置环境变量
在项目根目录创建 .env 文件(或修改 docker-compose.yml):
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. 构建并启动容器
docker-compose up -d
3. 查看日志
docker-compose logs -f
4. 停止服务
docker-compose down
访问:
📖 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)
示例:
curl -X GET "http://localhost:5000/api/v1/checkins?format=json" \
-H "X-API-Key: your-api-key"
2. 获取统计信息
GET /api/v1/stats
示例:
curl -X GET "http://localhost:5000/api/v1/stats" \
-H "X-API-Key: your-api-key"
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 示例
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 - 地图数据
- Leaflet - 地图库
- Tailwind CSS - CSS 框架