「爪印之约」--- 基于FastAPI+原生JS的宠物收养管理系统,从前端到后端的全栈实战
📖 目录
- 一、项目背景
- 二、技术栈与架构
- 三、数据库设计
- 四、核心功能详解
- 五、安全机制
- 六、AI智能助手
- 七、OSS文件存储
- 八、项目亮点
- 九、快速启动
- 十、总结与展望
一、项目背景
「爪印之约」 是一个面向宠物救助站与收养者的全流程管理平台。随着城市流浪动物数量逐年增加,传统的线下收养模式效率低下、信息不透明,收养者和救助站之间缺少一个高效、可信的桥梁。
本系统围绕 宠物收养 和 寄养服务 两大核心场景,提供从宠物浏览、点赞收藏、收养/寄养申请、管理员审核到宠物接回的全流程线上化能力。
🎯 目标用户:普通爱宠人士(浏览宠物+提交申请),救助站工作人员(审核管理),超级管理员(角色分配)
二、技术栈与架构
2.1 技术选型
| 层级 | 技术 | 说明 |
|---|---|---|
| 后端框架 | FastAPI (Python 3.12+) | 高性能异步 Web 框架,自动生成 OpenAPI 文档 |
| ORM | SQLAlchemy 2.0+ | Python 最流行的 ORM,支持连接池、延迟加载 |
| 数据库 | MySQL 5.7+ | 关系型数据库,通过 PyMySQL 驱动连接 |
| 认证 | JWT (HS256) + bcrypt | Token 认证 + 密码哈希加密 |
| 文件存储 | 阿里云 OSS | 私有 Bucket + 签名 URL 临时访问 |
| 缓存限流 | cacheout (LFUCache) | LFU 策略缓存,按用户独立限制 API 频率 |
| 前端 | 原生 HTML5 + CSS3 + JS(ES6+) + Axios | 零框架依赖,治愈系轻奢设计风格 |
| AI 对话 | Dify AI Workflow API | 宠物收养知识问答智能助手 |
2.2 分层架构
项目采用 企业级 8 层标准分包架构,职责单一、层层解耦:
┌──────────────────────────────────────────────────────────────┐
│ 前端层 (Presentation) │
│ 原生 HTML/CSS/JS + Axios 拦截器 + localStorage Token 管理 │
├──────────────────────────────────────────────────────────────┤
│ 路由/控制器层 (Controller) │
│ auth_controller user_controller pet_controller │
│ adoption_controller foster_service_controller ... │
├──────────────────────────────────────────────────────────────┤
│ 业务逻辑层 (Service) │
│ auth_service user_service pet_service │
│ adoption_service like_service oss_service │
├──────────────────────────────────────────────────────────────┤
│ 数据访问层 (CRUD) │
│ user_crud pet_crud adoption_crud like_crud │
├──────────────────────────────────────────────────────────────┤
│ 数据模型层 (Model) │
│ User Pet Adoption PetLike FosterServiceApplication │
│ PetReturn (SQLAlchemy ORM 映射) │
├──────────────────────────────────────────────────────────────┤
│ 基础设施层 │
│ database.py settings.py exceptions.py enums.py │
│ MySQL + 阿里云 OSS + Dify AI │
└──────────────────────────────────────────────────────────────┘
调用关系:
浏览器 HTTP 请求
→ Controller(接收请求、参数校验)
→ Service(业务逻辑判断、流程控制)
→ CRUD(原子化数据库操作)
→ Model(ORM 映射)
→ MySQL
三、数据库设计
系统包含 6 张数据表,关系如下:
1:N
1:N
1:N
1:N
1:N
1:N
1:N
users
adoptions
pets
pet_likes
foster_service_applications
pet_returns
3.1 表关系说明
| 关系 | 类型 | 说明 |
|---|---|---|
| User → Adoption | 1:N | 一个用户可提交多个收养/寄养申请 |
| Pet → Adoption | 1:N | 一个宠物可被多人申请 |
| User → PetLike | 1:N | 一个用户可以点赞多个宠物 |
| Pet → PetLike | 1:N | 一个宠物可以被多人点赞 |
| User + Pet → PetLike | 唯一约束 | 一个用户对一个宠物只能点赞一次 |
| User → FosterServiceApplication | 1:N | 一个用户可提交多个寄养服务申请 |
| FosterServiceApplication → PetReturn | 1:N | 一个寄养服务可产生接回请求 |
| User → PetReturn | 1:N | 一个用户可提交多个接回请求 |
3.2 核心表结构
users(用户表)--- 角色字段实现三权分立:
python
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, autoincrement=True)
email = Column(String(100), unique=True, index=True, nullable=False)
hashed_password = Column(String(100), nullable=False)
role = Column(String(20), default="general") # super_admin / staff / general
is_active = Column(Boolean, default=True)
frequency_max = Column(Integer, default=600) # API 频率限制
pets(宠物表)--- 核心业务实体:
python
class Pet(Base):
__tablename__ = "pets"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(50), nullable=False)
species = Column(String(20), nullable=False) # cat / dog / other
status = Column(String(20), default="available") # available / pending / adopted
image_url = Column(String(255)) # OSS 对象键
四、核心功能详解
4.1 用户登录与注册(JWT 认证)
完整流程:
用户输入邮箱+密码
→ POST /api/token (Form 格式)
→ auth_service.authenticate_and_create_token()
├─ user_crud.get_user_by_email() → 查找用户
├─ bcrypt.checkpw() → 密码校验(统一返回"邮箱或密码错误"防枚举攻击)
├─ 检查 is_active → 账号停用检查
└─ jwt.encode({sub: email, exp}) → HS256 签名生成 Token
→ 响应:{access_token, token_type: "bearer", expires_in: 7200}
前端存储:
localStorage.setItem('token', access_token)
Axios 拦截器自动注入:Authorization: Bearer {token}
注册流程:
python
# user_service.py - register_user()
def register_user(db, email, password, username):
# 1. 检查邮箱唯一性
# 2. bcrypt.hashpw() 加密密码(截断至72字节,bcrypt限制)
# 3. 默认用户名 = 邮箱@前缀
# 4. 写入数据库,默认 role="general",is_active=True
🔐 安全设计:登录失败统一返回"邮箱或密码错误",不区分邮箱不存在还是密码错误,防止用户枚举攻击。
4.2 宠物浏览与多维搜索
python
# pet_crud.py - get_pets() 支持 6 维筛选 + 中文关键词映射
def get_pets(db, skip, limit, species, status, gender, keyword):
query = db.query(Pet)
if species: query = query.filter(Pet.species == species)
if status: query = query.filter(Pet.status == status)
if keyword:
# 中文映射:"猫/猫咪"→cat, "狗/狗狗"→dog, "公/雄性"→male 等
query = query.filter(or_(
Pet.name.contains(keyword),
Pet.breed.contains(keyword),
Pet.description.contains(keyword)
))
return query.offset(skip).limit(limit).all()
性能优化:点赞数通过一次 SQL 聚合查询批量获取,避免 N+1 问题:
python
# like_crud.py
def get_likes_count_batch(db, pet_ids):
return db.query(PetLike.pet_id, func.count(PetLike.id))\
.filter(PetLike.pet_id.in_(pet_ids)).group_by(PetLike.pet_id).all()
4.3 收养申请全流程
普通用户:
宠物详情页 → 点击「申请收养」
→ /adoption_form.html?pet_id={id}
→ 填写表单(收养原因、居住情况、养宠经验、陪伴时间等)
→ POST /api/adoptions/
管理员:
管理后台 → 申请审核 Tab
→ 查看详情(弹窗)
→ PUT /api/adoptions/{id}/review {status: "approved", review_comment: "..."}
→ 审核通过自动将宠物状态更新为 adopted
业务校验链:
python
# adoption_service.py - create_adoption_application()
def create_adoption_application(db, user_id, pet_id, data):
pet = pet_crud.get_pet_by_id(db, pet_id)
if not pet: raise NotFoundError("宠物不存在")
if pet.status != "available": raise BusinessError("宠物不可收养")
# 同一用户对同一宠物只能申请一次
if adoption_crud.check_user_already_applied(db, user_id, pet_id):
raise BusinessError("您已提交过该宠物的收养申请")
# ...创建记录
4.4 寄养服务与宠物接回
寄养服务支持:
- 🐱 宠物信息:名称、种类、品种、年龄、性别、体重
- 🏠 寄养信息:起止日期、寄养原因、特殊需求
- 🍖 食品套餐:无需/标准粮(¥50)/优质粮(¥80)/高端定制粮(¥120)
- 💉 健康服务:狂犬疫苗(¥100)、驱虫(¥80)、体检(¥200) 等
前端实时计算预估费用,health_services 通过 JSON.stringify() 序列化存储。
接回流程要求寄养状态为 approved 方可发起,且同一时间只能有一条进行中的接回请求。
4.5 管理员后台 + 三权角色管理
| 角色 | role 值 | 权限 |
|---|---|---|
| 普通用户 | general |
浏览宠物、提交申请、修改个人信息 |
| 工作人员 | staff / admin |
管理宠物、审核申请、管理普通用户 |
| 超级管理员 | super_admin |
所有权限 + 修改用户角色(提升/降级) |
超级管理员角色管理:
python
# user_service.py - update_user_role()
def update_user_role(db, user_id, role):
if role not in ("staff", "general"):
raise ParamsError("角色只能是 staff 或 general")
# 不能将任何人提升为 super_admin,也不能降级 super_admin
# 只有系统启动时自动创建的 admin@petadoption.com 是超管
五、安全机制
5.1 多层防护体系
| 层级 | 机制 | 实现 |
|---|---|---|
| 密码安全 | bcrypt 哈希 + 72字节截断 | utils/password.py |
| 认证安全 | JWT HS256 签名,7200min 过期 | utils/jwt.py |
| 权限安全 | 3级依赖注入:get_current_user / require_admin / require_super_admin |
services/auth_service.py |
| 频率安全 | LFU 缓存按用户独立限流(默认600次/60s) | cacheout.LFUCache |
| 存储安全 | 阿里云 OSS 私有 Bucket + 签名 URL(1小时过期) | services/oss_service.py |
| 前端安全 | XSS 防护(escapeHtml),Token 自动过期处理 |
static/js/ |
5.2 JWT 认证 + 权限依赖注入
python
# FastAPI Depends 依赖链
def get_current_user(db, token):
payload = decode_access_token(token) # 1. 解析JWT
user = user_crud.get_user_by_email(db, payload["sub"]) # 2. 查用户
if cache.get(token) > user.frequency_max: # 3. 频率限制
raise UnauthorizedError("请求过于频繁")
return user
def require_admin(current_user = Depends(get_current_user)):
if current_user.role not in ("super_admin", "staff"):
raise HTTPException(403, "需要管理员权限")
return current_user
def require_super_admin(current_user = Depends(get_current_user)):
if current_user.role != "super_admin":
raise HTTPException(403, "需要超级管理员权限")
return current_user
# 路由使用
@router.delete("/{pet_id}")
def delete_pet(..., _ = Depends(require_admin)):
...
5.3 前端 Token 管理
javascript
// Axios 请求拦截器 --- 自动携带 Token
api.interceptors.request.use(config => {
const token = localStorage.getItem('token');
if (token) config.headers.Authorization = `Bearer ${token}`;
return config;
});
// Axios 响应拦截器 --- 401/403 自动处理
api.interceptors.response.use(
response => response,
error => {
if (error.response?.status === 401) {
localStorage.removeItem('token');
window.location.href = '/login.html';
}
return Promise.reject(error);
}
);
六、AI 智能助手
基于 Dify AI Workflow API 实现的悬浮式智能聊天助手:
javascript
// ai-assistant.js --- IIFE 封装,避免全局变量污染
(function() {
const DIFY_API_URL = 'https://api.dify.ai/v1/workflows/run';
const DIFY_API_KEY = 'app-xxx';
// 支持 blocking(同步)和 streaming(流式SSE)两种模式
async function callDifyAPI(query) {
const response = await fetch(DIFY_API_URL, {
method: 'POST',
headers: { 'Authorization': `Bearer ${DIFY_API_KEY}` },
body: JSON.stringify({
inputs: { query },
response_mode: 'blocking',
user: getUserId() // 自动生成唯一标识
})
});
// 解析输出,支持多种字段名:text → answer → output → result
}
})();
功能特点:
- 🎨 右下角悬浮 Widget,点击展开聊天窗口
- 💬 支持流式输出(逐字显示)
- 🔒 XSS 防护(
escapeHtml自动转义) - ⚡ 60秒超时保护
- 📋 预设快捷问题
七、OSS 文件存储
7.1 图片处理流程
python
# oss_service.py
def upload_image(file_content, pet_id, filename):
object_key = f"pets/{pet_id}/{filename}"
processed = process_image(file_content, size=400) # 自动处理
bucket.put_object_from_file(object_key, processed)
return object_key
def process_image(file_content, size=400):
# 1. 转换为 RGB 模式(避免 PNG/CMYK 兼容问题)
# 2. 中心裁剪为正方形(取宽高中较小边)
# 3. 缩放到 400×400(宠物)/ 200×200(头像)
# 4. JPEG 格式输出,质量 85%(平衡清晰度和文件大小)
7.2 私有 Bucket + 签名 URL
python
# 数据库只存 object_key,访问时动态生成签名 URL
def get_signed_url(object_key, expire=3600):
return bucket.sign_url('GET', object_key, expire)
# URL 1小时后自动失效,防止图片盗链
八、项目亮点
| 亮点 | 说明 |
|---|---|
| 🏗️ 企业级分包架构 | 8层解耦:Controller→Service→CRUD→Model,职责单一、易于维护 |
| 🔒 三权分立角色体系 | super_admin / staff / general,依赖注入实现细粒度权限控制 |
| 🎨 治愈系UI设计 | CSS变量主题化、毛玻璃导航栏、颗粒纹理质感、爪印摇摆动画 |
| 🤖 AI 智能助手 | 基于 Dify Workflow,支持流式输出,XSS 安全防护 |
| ☁️ OSS 私有存储 | 图片自动裁剪压缩,签名 URL 防盜链 |
| 📊 批量查询优化 | 点赞数一次 SQL 聚合获取,避免 N+1 问题 |
| 🔍 中文关键词搜索 | 自动映射中文→数据库值(如"猫"/"猫咪"→cat) |
| 🛡️ 多层安全防护 | bcrypt + JWT + LFU限流 + 防枚举攻击 + 统一异常处理 |
九、快速启动
9.1 环境要求
- Python 3.12+
- MySQL 5.7+
- (可选)阿里云 OSS + Dify AI API Key
9.2 启动步骤
bash
# 1. 安装依赖
pip install -r requirements.txt
# 2. 配置 .env 文件
DATABASE_URL=mysql+pymysql://root:password@localhost:3306/pet_adoption
JWT_SECRET_KEY=your-secret-key
OSS_ACCESS_KEY_ID=xxx # 可选
OSS_ACCESS_KEY_SECRET=xxx # 可选
OSS_BUCKET_NAME=xxx # 可选
# 3. 启动服务
uvicorn main:app --reload --host 0.0.0.0 --port 8000
# 4. 访问系统
# 前端:http://localhost:8000/
# API文档:http://localhost:8000/docs
# 5. 默认超级管理员
# 邮箱:admin@petadoption.com
# 密码:admin123
9.3 项目目录结构
pet_adoption_system/
├── main.py # 应用入口(路由注册、中间件、启动事件)
├── database.py # 数据库连接(引擎、会话、连接池)
├── settings.py # 全局配置(JWT密钥、数据库URL、OSS配置)
├── requirements.txt # 依赖清单
│
├── models/model.py # 6张数据表 ORM 定义
├── schemas/ # Pydantic 请求/响应模型
├── controllers/ # FastAPI 路由层
├── services/ # 业务逻辑层
├── crud/ # 数据库操作层
├── utils/ # 工具函数(JWT、密码加密)
├── common/ # 公共模块(枚举、异常、统一响应)
├── config/oss_config.py # OSS 配置
└── static/ # 前端静态文件(治愈系UI)
├── css/style.css
├── js/api.js # Axios 封装
├── js/ai-assistant.js # AI 助手组件
└── *.html # 10个页面
十、总结与展望
10.1 项目小结
「爪印之约」是一个从 数据库设计 → API 开发 → 前端渲染 → 安全加固 的全栈实战项目。核心实现了:
- ✅ 用户认证体系:JWT + bcrypt,统一异常处理
- ✅ 三权角色管理:super_admin / staff / general,依赖注入权限校验
- ✅ 宠物全生命周期管理:录入 → 浏览 → 点赞 → 收养申请 → 审核 → 已收养
- ✅ 寄养服务闭环:申请 → 审核 → 接回请求 → 审核完成
- ✅ AI 智能助手:悬浮 Widget,支持流式对话
- ✅ OSS 图片管理:私有 Bucket,自动裁剪压缩,签名 URL 访问
- ✅ 多层安全防护:限流、防枚举、XSS 防护、Token 自动过期
10.3 页面展示
以下是用户页面的基本展示,还有管理员以及超级管理员的页面未展示,想看完整效果可以上github拉取,自己配环境,跑项目。






10.2 后续优化方向
| 方向 | 说明 |
|---|---|
| 📋 标准 RBAC 改造 | 当前角色是硬编码的,后续可将角色-权限-资源建模,实现超级管理员动态分配权限 |
| 📱 移动端适配 | 完善响应式布局,支持手机端完整操作 |
| 📊 数据统计面板 | 收养率、寄养率、用户活跃度等可视化报表 |
| 🔔 消息通知 | 申请状态变更时邮件/站内信通知用户 |
| 🧪 单元测试 | 补充 pytest 测试用例,覆盖核心业务逻辑 |
📌 项目地址:[GitHub 仓库链接https://github.com/Shawn-zhou2004/pet_adoption\]
💬 如有任何问题或建议,欢迎在评论区交流讨论!
本文发布于 CSDN,转载请注明出处。