306 lines
6.8 KiB
Markdown
306 lines
6.8 KiB
Markdown
# 📍 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 框架
|