# aed_data **Repository Path**: liu-tieshan/aed_data ## Basic Information - **Project Name**: aed_data - **Description**: API调用获取一定范围的qed设备数据 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-18 - **Last Updated**: 2026-09-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AED API 开放平台 AED(自动体外除颤器)设备数据 API 开放平台,为公益性质的 AED 设备位置查询服务提供标准化的 API 接口。 ## 项目简介 AED 生命守护者 API 平台是一个基于 FastAPI 构建的 AED 设备数据开放平台,旨在帮助开发者快速获取附近 AED 设备的位置信息,支持设备查询、状态管理、工单上报等功能。 ### 核心功能 - **附近 AED 设备查询**:基于地理位置查找附近的 AED 设备 - **设备信息管理**:查看设备详细信息、状态管理 - **API 密钥管理**:用户自主创建、管理 API 访问密钥 - **用量统计**:实时查看 API 调用次数和配额使用情况 - **多语言 SDK**:提供 Python 和 JavaScript 官方 SDK - **微信登录**:支持微信扫码登录 - **工单上报**:公众可上报 AED 设备问题 - **安全加固**:登录失败锁定、IP频率限制、bcrypt密码加密、双Token机制 ## 技术架构 ### 后端技术栈 - **框架**:FastAPI 0.109.2 - **数据库**:MySQL 8.0 + SQLAlchemy 2.0.25 - **缓存/限流**:Redis 5.0.1 - **短信服务**:阿里云短信服务 - **邮件服务**:支持邮件验证码绑定 ### 前端技术栈 - **页面**:原生 HTML/CSS/JavaScript - **图表**:ECharts 5.4.3 - **通信**:Fetch API ### SDK 支持 - Python 3.7+ - JavaScript/TypeScript (Node.js & 浏览器) ## 项目结构 ``` aed_data/ ├── backend/ │ ├── app/ │ │ ├── routers/ # API 路由模块 │ │ │ ├── devices.py # 设备管理 API │ │ │ ├── aed_api.py # AED 开放 API │ │ │ ├── auth.py # 用户认证 API │ │ │ ├── wechat.py # 微信登录 API │ │ │ ├── apikey.py # API 密钥管理 │ │ │ ├── usage.py # 用量统计 API │ │ │ ├── reports.py # 工单管理 API │ │ │ ├── notifications.py # 站内通知 API │ │ │ └── sdks.py # SDK 下载 API │ │ ├── models/ # 数据库模型 │ │ ├── schemas/ # Pydantic 数据模型 │ │ ├── services/ # 业务服务 │ │ │ ├── sms.py # 短信服务 │ │ │ ├── email.py # 邮件服务 │ │ │ ├── notification.py # 通知服务 │ │ │ └── rate_limiter.py # 限流服务 │ │ ├── config.py # 配置管理 │ │ ├── database.py # 数据库连接 │ │ └── main.py # 应用入口 │ ├── data/ # 数据库脚本 │ │ ├── 01_schema.sql # 数据库结构 │ │ ├── 02_seed.sql # 种子数据 │ │ └── 03_refresh_aed_device.sql # 设备数据刷新 │ ├── sdks/ # SDK 源码 │ │ ├── python/ # Python SDK │ │ └── javascript/ # JavaScript SDK │ ├── test/ # 测试脚本 │ ├── requirements.txt # Python 依赖 │ └── .env # 环境变量配置 ├── frontend/ │ ├── css/ # 样式文件 │ ├── js/ # JavaScript 文件 │ ├── images/ # 图片资源 │ ├── api-platform.html # API 开放平台主页 │ ├── login.html # 登录页面 │ └── wechat-callback.html # 微信回调页面 └── README.md ``` ## API 接口列表 ### 基础信息 - **API 前缀**:`/v1` - **文档地址**:`/docs`(Swagger UI) - **备用文档**:`/redoc`(ReDoc) ### 认证相关 `/v1/auth` | 接口 | 方法 | 说明 | |------|------|------| | `/auth/login` | POST | 用户登录 | | `/auth/register` | POST | 用户注册 | | `/auth/send-code` | POST | 发送验证码 | | `/auth/logout` | POST | 退出登录 | | `/auth/refresh-token` | POST | 刷新 Access Token | | `/auth/check-mobile/{mobile}` | GET | 检查手机号是否存在 | | `/auth/profile` | PUT | 更新用户资料 | | `/auth/bind-email` | POST | 绑定邮箱 | | `/auth/bind-phone` | POST | 绑定手机 | | `/auth/send-phone-code` | POST | 发送手机验证码 | ### 微信登录 `/v1/auth/wechat` | 接口 | 方法 | 说明 | |------|------|------| | `/auth/wechat/config` | GET | 获取微信配置 | | `/auth/wechat/callback` | POST | 微信登录回调 | ### 设备管理 `/v1/devices` | 接口 | 方法 | 说明 | |------|------|------| | `/devices/` | GET | 获取设备列表(分页) | | `/devices/{device_id}` | GET | 获取设备详情 | | `/devices/nearby` | GET | 获取附近设备 | ### AED 开放 API `/v1/aed`(需 API Key) | 接口 | 方法 | 说明 | |------|------|------| | `/aed/` | GET | 获取设备列表 | | `/aed/{device_id}` | GET | 获取设备详情 | | `/aed/nearby` | GET | 获取附近 AED 设备 | ### API Key 管理 `/v1/api-keys` | 接口 | 方法 | 说明 | |------|------|------| | `/api-keys/` | GET | 获取 API Key 列表 | | `/api-keys/` | POST | 创建新的 API Key | | `/api-keys/{key_id}` | PUT | 更新 API Key 名称 | | `/api-keys/{key_id}` | DELETE | 删除 API Key | | `/api-keys/{key_id}/status` | PATCH | 启用/停用 API Key | | `/api-keys/{key_id}/regenerate-secret` | GET | 重置 API Secret | ### 用量统计 `/v1/usage` | 接口 | 方法 | 说明 | |------|------|------| | `/usage/stats` | GET | 获取用量统计 | | `/usage/consume` | POST | 消耗调用次数 | | `/usage/trend` | GET | 获取调用趋势 | ### 工单管理 `/v1/reports` | 接口 | 方法 | 说明 | |------|------|------| | `/reports/` | POST | 创建上报工单 | | `/reports/tickets` | GET | 获取工单列表 | | `/reports/tickets/{ticket_id}` | GET | 获取工单详情 | ### 站内通知 `/v1/notifications` | 接口 | 方法 | 说明 | |------|------|------| | `/notifications/` | GET | 获取通知列表 | | `/notifications/unread-count` | GET | 获取未读数量 | | `/notifications/{id}/read` | POST | 标记已读 | | `/notifications/read-all` | POST | 全部标记已读 | ## 快速开始 ### 环境要求 - Python 3.7+ - MySQL 5.7+ 或 8.0+ - Redis 5.0+ - Node.js(可选,用于前端开发) ### 1. 配置环境变量 复制 `.env.example` 为 `.env` 并修改配置: ```bash cd backend cp .env.example .env ``` 主要配置项: ```env # 数据库配置 DATABASE_URL=mysql+pymysql://user:password@host:3306/aed_system # 微信登录配置(可选) WECHAT_APPID=your_wechat_appid WECHAT_SECRET=your_wechat_secret # 阿里云短信配置(可选) ALIBABA_CLOUD_ACCESS_KEY_ID=your_access_key_id ALIBABA_CLOUD_ACCESS_KEY_SECRET=your_access_key_secret SMS_SIGN_NAME=AED 生命守护者 SMS_TEMPLATE_CODE=100001 # Redis 配置 REDIS_HOST=localhost REDIS_PORT=6379 ``` ### 2. 初始化数据库 ```bash # 连接 MySQL 执行数据库脚本 mysql -u root -p < backend/data/01_schema.sql mysql -u root -p < backend/data/02_seed.sql ``` ### 3. 安装后端依赖 ```bash cd backend pip install -r requirements.txt ``` ### 4. 启动服务 ```bash cd backend uvicorn app.main:app --reload --host 0.0.0.0 --port 8001 ``` 服务启动后,访问: - API 平台:http://localhost:8001/ - API 文档:http://localhost:8001/docs ### 5. 前端部署 前端为纯静态文件,可直接使用 Nginx 或任何静态服务器部署: ```nginx server { listen 80; server_name your-domain.com; root /path/to/aed_data/frontend; index index.html; } ``` ## API 使用示例 ### 获取附近 AED 设备 **请求** ```bash curl -X GET "http://localhost:8001/v1/aed/nearby?latitude=31.23&longitude=121.47&radius=5000" \ -H "X-API-Key: your_api_key_here" ``` **响应** ```json { "total": 2, "devices": [ { "id": 1, "sn_code": "AED001", "provider_name": "某品牌", "address": "上海市浦东新区xx路xx号", "lat": 31.234567, "lng": 121.456789, "status": 1 } ] } ``` ## SDK 使用 ### Python SDK ```bash pip install aed-sdk ``` ```python from aed_sdk import AEDClient client = AEDClient(api_key="your_api_key_here") # 获取附近 AED 设备 result = client.get_nearby_aed( latitude=31.23, longitude=121.47, radius=5000 ) print(f"附近有 {result['total']} 台 AED 设备") ``` ### JavaScript SDK ```bash npm install aed-sdk ``` ```javascript import { AEDClient } from 'aed-sdk'; const client = new AEDClient({ apiKey: 'your_api_key_here' }); const result = await client.getNearbyAED({ latitude: 31.23, longitude: 121.47, radius: 5000 }); console.log(`附近有 ${result.total} 台 AED 设备`); ``` ## 配额与限制 | 等级 | 每月配额 | QPS | QPM | QPD | |------|----------|-----|-----|-----| | 免费版 | 500 次 | 2 | 5 | 30 | - **QPS**:每秒请求数 - **QPM**:每分钟请求数 - **QPD**:每天请求数 配额每月 1 日自动重置。 ## 安全机制 ### 登录安全 | 机制 | 说明 | |------|------| | **登录失败锁定** | 连续 5 次登录失败锁定 15 分钟 | | **密码加密** | bcrypt 加密存储(成本因子 12) | | **双 Token 机制** | Access Token(15 分钟)+ Refresh Token(7 天) | | **自动密码升级** | 老用户登录时自动升级密码为 bcrypt 格式 | ### 注册安全 | 机制 | 说明 | |------|------| | **IP 频率限制** | 同一 IP 1 小时内最多 3 次注册 | | **验证码限制** | 同一 IP 1 小时内最多 10 次发送验证码 | | **手机号唯一** | 已注册手机号不能重复注册 | ### 操作日志 | 记录类型 | 说明 | |---------|------| | 登录/登出 | 记录用户登录和退出时间 | | 用户名变更 | 记录用户名修改历史 | | 邮箱变更 | 记录邮箱修改历史 | | 手机号变更 | 记录手机号修改历史 | | 头像变更 | 记录头像修改历史 | ### 数据库清理 系统启动时自动清理过期数据: | 数据类型 | 保留时间 | |---------|---------| | 过期的 Token | 7 天 | | 撤销的 Token | 7 天 | | 登录失败记录 | 7 天 | | IP 注册日志 | 30 天 | | 用户操作日志 | 90 天 | 手动清理 API:`POST /v1/admin/cleanup` ## 数据库表结构 | 表名 | 说明 | |------|------| | `sys_user` | 系统用户表 | | `aed_device` | AED 设备表 | | `aed_status_history` | 设备状态变更历史 | | `auth_refresh_token` | 认证刷新令牌 | | `report_ticket` | 公众上报工单 | | `audit_record` | 审核记录 | | `provider_upload_batch` | 商家批量上传批次 | | `provider_upload_item` | 商家批量上传明细 | | `api_key` | API 密钥表 | | `user_usage_quota` | 用户配额表 | | `user_api_call_log` | API 调用日志 | | `user_notification` | 用户通知表 | | `user_login_failures` | 用户登录失败记录 | | `ip_register_logs` | IP注册频率限制日志 | | `user_action_logs` | 用户操作日志 | ## 开发指南 ### 添加新的 API 路由 1. 在 `app/routers/` 目录下创建新的路由文件 2. 定义路由并实现业务逻辑 3. 在 `app/main.py` 中注册路由 ```python # app/routers/example.py from fastapi import APIRouter, Depends from app.database import get_db router = APIRouter(prefix="/example", tags=["示例"]) @router.get("/") def get_example(db=Depends(get_db)): return {"message": "Hello AED"} ``` ```python # app/main.py from app.routers import example app.include_router(example.router, prefix=settings.api_prefix) ``` ### 添加新的数据模型 1. 在 `app/models/__init__.py` 中添加模型类 2. 在 `app/schemas/__init__.py` 中添加对应的 Pydantic 模型 ## 注意事项 1. **API Key 安全**:API Key 生成后只显示一次,请妥善保存 2. **短信服务**:需要配置阿里云短信服务才能发送验证码 3. **微信登录**:需要配置微信开放平台应用才能使用 4. **数据初始化**:生产环境请根据需要修改数据库脚本中的测试数据 ## License 本项目仅供学习交流使用,AED 数据来源于公开数据。