Files
2026-06-15 14:50:15 +08:00

15 KiB
Raw Permalink Blame History

药箱后端开发文档

1. 项目概述

药箱(YaoXiang)是一个家庭药品与应急物资管理系统,后端采用 FastAPI 框架,提供 RESTful API 服务。

2. 技术栈

技术 版本 说明
Python 3.11+ 运行环境
FastAPI 0.104.1 Web 框架
SQLAlchemy 2.0.23 ORM 框架
Alembic 1.13.0 数据库迁移
SQLite - 数据库
Pydantic 2.5.2 数据验证
python-jose 3.3.0 JWT 认证
passlib 1.7.4 密码加密
OpenAI 1.6.1 AI 服务

3. 项目结构

backend/
├── app/                          # 主应用目录
│   ├── __init__.py
│   ├── main.py                   # FastAPI 应用入口
│   ├── config.py                 # 配置管理
│   ├── database.py               # 数据库连接
│   │
│   ├── api/                      # API 路由层
│   │   ├── router.py             # 路由汇总
│   │   └── v1/                   # API 版本 1
│   │       ├── auth.py           # 认证接口
│   │       ├── medicines.py      # 药品管理接口
│   │       ├── batches.py        # 批次管理接口
│   │       ├── categories.py     # 分类管理接口
│   │       ├── search.py         # 搜索接口
│   │       ├── notifications.py  # 通知接口
│   │       ├── ai.py             # AI 识别接口
│   │       ├── users.py          # 用户管理接口
│   │       └── settings.py       # 系统设置接口
│   │
│   ├── models/                   # SQLAlchemy 数据模型
│   │   ├── user.py               # 用户模型
│   │   ├── medicine.py           # 药品模型
│   │   ├── batch.py              # 批次模型
│   │   ├── category.py           # 分类模型
│   │   ├── audit_log.py          # 审计日志模型
│   │   ├── notification.py       # 通知模型
│   │   └── setting.py            # 设置模型
│   │
│   ├── schemas/                  # Pydantic 数据模式
│   │   ├── user.py
│   │   ├── medicine.py
│   │   ├── batch.py
│   │   ├── category.py
│   │   └── auth.py
│   │
│   ├── services/                 # 业务服务层
│   │   ├── auth.py               # 认证服务
│   │   ├── user.py               # 用户服务
│   │   ├── medicine.py           # 药品服务
│   │   ├── batch.py              # 批次服务
│   │   ├── category.py           # 分类服务
│   │   ├── audit.py              # 审计日志服务
│   │   └── notification.py       # 通知服务
│   │
│   ├── repositories/             # 数据访问层
│   │   ├── user.py
│   │   ├── medicine.py
│   │   ├── batch.py
│   │   ├── category.py
│   │   ├── audit_log.py
│   │   └── notification.py
│   │
│   ├── ai/                       # AI Provider 模块
│   │   ├── base.py               # 抽象基类
│   │   ├── openai_provider.py    # OpenAI 实现
│   │   └── manager.py            # Provider 管理器
│   │
│   ├── notifications/            # 通知系统
│   │   ├── base.py               # 抽象基类
│   │   ├── serverchan.py         # Server酱
│   │   ├── pushplus.py           # PushPlus
│   │   └── manager.py            # 通知管理器
│   │
│   ├── storage/                  # 文件存储
│   │   ├── base.py               # 抽象基类
│   │   ├── local.py              # 本地存储
│   │   └── manager.py            # 存储管理器
│   │
│   ├── core/                     # 核心功能
│   │   ├── security.py           # 安全工具 (JWT, 密码)
│   │   ├── deps.py               # 依赖注入
│   │   └── exceptions.py         # 异常处理
│   │
│   └── tasks/                    # 异步任务
│       └── expiry_check.py       # 到期检查任务
│
├── tests/                        # 测试目录
├── data/                         # 数据目录
├── requirements.txt              # Python 依赖
├── .env.example                  # 环境变量示例
└── .env                          # 环境变量配置

4. 快速开始

4.1 环境准备

# 进入后端目录
cd backend

# 创建虚拟环境 (可选)
python -m venv venv
venv\Scripts\activate  # Windows
# source venv/bin/activate  # Linux/Mac

# 安装依赖
pip install -r requirements.txt

4.2 配置环境变量

# 复制环境变量示例文件
cp .env.example .env

# 编辑 .env 文件,配置必要的参数

4.3 启动服务

# 开发模式启动
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

# 生产模式启动
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4

4.4 访问 API 文档

5. 配置说明

5.1 环境变量配置

变量名 默认值 说明
DATABASE_URL sqlite+aiosqlite:///./data/yaoxiang.db 数据库连接字符串
JWT_SECRET_KEY your-secret-key-change-in-production JWT 密钥
JWT_ALGORITHM HS256 JWT 算法
JWT_EXPIRATION_HOURS 24 JWT 过期时间(小时)
AI_PROVIDER openai AI 服务提供者
OPENAI_API_KEY - OpenAI API Key
OPENAI_MODEL gpt-4o OpenAI 模型
UPLOAD_DIR ./data/uploads 文件上传目录
CORS_ORIGINS http://localhost:5173 CORS 允许的源

5.2 AI Provider 配置

支持的 AI Provider

  • openai: OpenAI GPT-4o
  • gemini: Google Gemini
  • claude: Anthropic Claude
  • deepseek: DeepSeek
  • ollama: 本地 Ollama

6. 数据库设计

6.1 数据表

表名 说明
users 用户表
categories 分类表
medicines 药品表
batches 批次表
audit_logs 审计日志表
notifications 通知表
settings 系统设置表

6.2 核心表结构

users 表

CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    role VARCHAR(20) DEFAULT 'user',
    display_name VARCHAR(100),
    email VARCHAR(100),
    notification_level VARCHAR(20) DEFAULT 'normal',
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);

medicines 表

CREATE TABLE medicines (
    id INTEGER PRIMARY KEY,
    name VARCHAR(200) NOT NULL,
    generic_name VARCHAR(200),
    brand_name VARCHAR(200),
    manufacturer VARCHAR(200),
    specification VARCHAR(200),
    category_id INTEGER REFERENCES categories(id),
    indications TEXT,
    adult_dose TEXT,
    child_dose TEXT,
    contraindications TEXT,
    notes TEXT,
    image_front_path VARCHAR(500),
    image_expiry_path VARCHAR(500),
    image_leaflet_paths JSON,
    expiry_grace_days INTEGER DEFAULT 0,
    created_by INTEGER REFERENCES users(id),
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);

batches 表

CREATE TABLE batches (
    id INTEGER PRIMARY KEY,
    medicine_id INTEGER REFERENCES medicines(id),
    batch_no VARCHAR(100),
    production_date DATE,
    expiry_date DATE NOT NULL,
    quantity INTEGER DEFAULT 0,
    location VARCHAR(200),
    is_expired BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);

7. API 接口

7.1 认证接口

方法 路径 说明
POST /api/v1/auth/login 用户登录
GET /api/v1/auth/me 获取当前用户信息
PUT /api/v1/auth/password 修改密码

7.2 药品管理接口

方法 路径 说明 权限
GET /api/v1/medicines 获取药品列表 登录用户
GET /api/v1/medicines/{id} 获取药品详情 登录用户
POST /api/v1/medicines 创建药品 admin/user
PUT /api/v1/medicines/{id} 更新药品 admin/user
DELETE /api/v1/medicines/{id} 删除药品 admin

7.3 批次管理接口

方法 路径 说明 权限
GET /api/v1/batches/medicine/{medicine_id} 获取药品的所有批次 登录用户
GET /api/v1/batches/{id} 获取批次详情 登录用户
POST /api/v1/batches/medicine/{medicine_id} 创建批次 admin/user
PUT /api/v1/batches/{id} 更新批次 admin/user
DELETE /api/v1/batches/{id} 删除批次 admin
POST /api/v1/batches/{id}/dispense 取药 admin/user
POST /api/v1/batches/{id}/add-stock 入库 admin/user

7.4 分类管理接口

方法 路径 说明 权限
GET /api/v1/categories 获取分类列表 登录用户
GET /api/v1/categories/tree 获取分类树 登录用户
GET /api/v1/categories/{id} 获取分类详情 登录用户
POST /api/v1/categories 创建分类 admin
PUT /api/v1/categories/{id} 更新分类 admin
DELETE /api/v1/categories/{id} 删除分类 admin

7.5 搜索接口

方法 路径 说明
GET /api/v1/search?q=关键词 关键词搜索
POST /api/v1/search/natural 自然语言搜索

7.6 AI 识别接口

方法 路径 说明 权限
POST /api/v1/ai/recognize-medicine 识别药盒 admin/user
POST /api/v1/ai/recognize-dates 识别日期 admin/user
POST /api/v1/ai/recognize-leaflet 识别说明书 admin/user

7.7 用户管理接口

方法 路径 说明 权限
GET /api/v1/users 获取用户列表 admin
GET /api/v1/users/{id} 获取用户详情 admin
POST /api/v1/users 创建用户 admin
PUT /api/v1/users/{id} 更新用户 admin
DELETE /api/v1/users/{id} 删除用户 admin
POST /api/v1/users/{id}/reset-password 重置密码 admin

7.8 通知接口

方法 路径 说明
GET /api/v1/notifications 获取通知列表
PUT /api/v1/notifications/{id}/read 标记为已读
PUT /api/v1/notifications/read-all 全部标记为已读
DELETE /api/v1/notifications/{id} 删除通知

7.9 系统设置接口

方法 路径 说明 权限
GET /api/v1/settings 获取所有设置 admin
GET /api/v1/settings/{key} 获取单个设置 admin
PUT /api/v1/settings/{key} 更新设置 admin

8. 开发指南

8.1 添加新的 API 接口

  1. app/api/v1/ 目录下创建或修改路由文件
  2. 定义请求和响应的 Pydantic 模式
  3. 实现业务逻辑(服务层)
  4. app/api/router.py 中注册路由

示例:

# app/api/v1/example.py
from fastapi import APIRouter, Depends
from app.core.deps import get_current_user

router = APIRouter()

@router.get("/")
async def list_examples(current_user = Depends(get_current_user)):
    return {"message": "success"}

8.2 添加新的数据模型

  1. app/models/ 目录下创建模型文件
  2. 继承 Base
  3. 定义表名和字段
  4. app/models/__init__.py 中导入
# app/models/example.py
from sqlalchemy import Column, Integer, String
from app.database import Base

class Example(Base):
    __tablename__ = "examples"
    
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), nullable=False)

8.3 添加新的服务

  1. app/services/ 目录下创建服务文件
  2. 实现业务逻辑
  3. 使用 Repository 进行数据访问
# app/services/example.py
from sqlalchemy.ext.asyncio import AsyncSession
from app.repositories.example import ExampleRepository

class ExampleService:
    def __init__(self, db: AsyncSession):
        self.db = db
        self.repo = ExampleRepository(db)
    
    async def get_example(self, example_id: int):
        return await self.repo.get_by_id(example_id)

8.4 添加新的 AI Provider

  1. app/ai/ 目录下创建 Provider 文件
  2. 继承 VisionProviderTextProvider
  3. 实现抽象方法
  4. app/ai/manager.py 中注册
# app/ai/custom_provider.py
from app.ai.base import VisionProvider, VisionResult

class CustomVisionProvider(VisionProvider):
    async def recognize_medicine(self, image_bytes: bytes) -> VisionResult:
        # 实现识别逻辑
        return VisionResult(generic_name="药品名称")
    
    async def recognize_dates(self, image_bytes: bytes):
        # 实现日期识别
        pass

8.5 添加新的通知 Provider

  1. app/notifications/ 目录下创建 Provider 文件
  2. 继承 NotificationProvider
  3. 实现 sendvalidate_config 方法
# app/notifications/custom.py
from app.notifications.base import NotificationProvider

class CustomNotificationProvider(NotificationProvider):
    def __init__(self):
        self.config = "your-config"
    
    def validate_config(self) -> bool:
        return bool(self.config)
    
    async def send(self, title: str, content: str) -> bool:
        # 实现发送逻辑
        return True

9. 测试

9.1 运行测试

# 运行所有测试
pytest

# 运行特定测试
pytest tests/test_auth.py

# 运行带详细输出的测试
pytest -v

9.2 编写测试

# tests/test_example.py
import pytest
from httpx import AsyncClient

@pytest.mark.asyncio
async def test_health_check(client: AsyncClient):
    response = await client.get("/health")
    assert response.status_code == 200
    assert response.json()["status"] == "healthy"

10. 部署

10.1 Docker 部署

# Dockerfile
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

10.2 生产环境配置

# 设置环境变量
export DATABASE_URL=sqlite+aiosqlite:///./data/yaoxiang.db
export JWT_SECRET_KEY=your-production-secret-key
export DEBUG=false

# 启动服务
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4

11. 常见问题

11.1 数据库初始化失败

检查 data/ 目录是否存在,确保有写入权限。

11.2 AI 服务连接失败

检查 .env 文件中的 API Key 配置是否正确。

11.3 文件上传失败

检查 UPLOAD_DIR 配置的目录是否存在,确保有写入权限。

12. 扩展开发

12.1 添加新的通知渠道

参考 app/notifications/serverchan.py 实现新的通知 Provider。

12.2 添加新的 AI 能力

  1. 扩展 app/ai/base.py 中的抽象基类
  2. 实现新的 Provider
  3. app/ai/manager.py 中注册

12.3 添加新的定时任务

使用 APScheduler 添加定时任务:

from apscheduler.schedulers.asyncio import AsyncIOScheduler

scheduler = AsyncIOScheduler()

async def my_task():
    # 任务逻辑
    pass

scheduler.add_job(my_task, 'cron', hour=9, minute=0)
scheduler.start()