footprint/README.md

306 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 📍 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 框架