1. 项目背景与核心需求
校园流浪猫问题一直是高校管理中的痛点。每到毕业季,总会有大量被遗弃的宠物猫在校园内游荡,它们面临着食物短缺、疾病传播和意外伤害的风险。与此同时,许多爱猫学生又苦于宿舍管理规定无法亲自收养。这个矛盾催生了我们开发"校园流浪猫收养捐赠系统"的想法。
这个系统的核心价值在于搭建了一个连接三类角色的平台:
- 流浪猫发现者:可以提交猫咪信息、健康状况和位置
- 潜在领养者:能够浏览可领养的猫咪并提交申请
- 爱心捐赠者:可以为猫咪医疗、绝育等费用提供资金支持
技术选型上,我们采用Python+Django作为后端,微信小程序作为前端入口。这种组合主要基于以下考虑:
- 微信小程序的天然优势:无需安装、即用即走,特别适合校园场景的快速传播
- Python生态的成熟性:Django框架提供了完善的Admin后台,便于非技术人员管理内容
- 开发成本控制:团队成员对Python和微信小程序都有一定基础,学习曲线平缓
2. 系统架构设计
2.1 技术栈全景图
整个系统采用经典的三层架构:
code复制微信小程序前端 -> Django REST API -> MySQL数据库
↑
微信云开发(可选)
前端选择微信小程序而非H5的主要原因是:
- 更好的用户体验:加载更快,支持更多原生API
- 更低的推广成本:通过校园微信群即可快速传播
- 更完善的生态:支付、定位、消息通知等接口开箱即用
后端选择Django而非Flask的考虑:
- 内置Admin后台:方便动保社团管理领养申请
- ORM成熟度:对数据库操作更安全规范
- 社区支持:遇到问题更容易找到解决方案
2.2 数据库设计要点
核心数据表包括:
- 猫咪信息表(cat_info)
python复制class CatInfo(models.Model):
CAT_GENDER_CHOICES = (
('M', '公'),
('F', '母'),
)
name = models.CharField(max_length=20)
gender = models.CharField(max_length=1, choices=CAT_GENDER_CHOICES)
age = models.PositiveSmallIntegerField() # 单位:月
color = models.CharField(max_length=20)
health_status = models.TextField()
location = models.CharField(max_length=100)
is_sterilized = models.BooleanField(default=False)
found_time = models.DateTimeField(auto_now_add=True)
avatar = models.ImageField(upload_to='cat_avatars/')
- 领养申请表(adoption_application)
python复制class AdoptionApplication(models.Model):
STATUS_CHOICES = (
('P', '待审核'),
('A', '已通过'),
('R', '已拒绝'),
)
cat = models.ForeignKey(CatInfo, on_delete=models.CASCADE)
applicant = models.ForeignKey(User, on_delete=models.CASCADE)
apply_time = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=1, choices=STATUS_CHOICES, default='P')
home_environment = models.TextField() # 家庭环境描述
experience = models.TextField() # 养宠经验
- 捐赠记录表(donation_record)
python复制class DonationRecord(models.Model):
donor = models.ForeignKey(User, on_delete=models.CASCADE)
amount = models.DecimalField(max_digits=10, decimal_places=2)
donate_time = models.DateTimeField(auto_now_add=True)
purpose = models.CharField(max_length=100) # 指定用途
payment_id = models.CharField(max_length=64) # 微信支付单号
注意:实际部署时应将图片等静态资源托管到CDN,避免数据库膨胀。我们使用Django-storages配合阿里云OSS实现。
3. 微信小程序关键实现
3.1 用户认证流程优化
校园场景下,我们采用"微信身份+学号验证"的双重认证机制:
- 首次进入小程序时获取微信openid
- 提交学号和姓名(与学校数据库比对)
- 生成自定义登录态token(JWT实现)
python复制# Django后端生成token的示例
import jwt
from datetime import datetime, timedelta
def generate_token(user):
payload = {
'user_id': user.id,
'student_id': user.student_id,
'exp': datetime.utcnow() + timedelta(days=7)
}
return jwt.encode(payload, SECRET_KEY, algorithm='HS256')
3.2 猫咪信息展示页
采用分页加载+条件筛选的设计:
javascript复制// 小程序端加载猫咪列表
Page({
data: {
cats: [],
page: 1,
filters: {
gender: '',
ageRange: [0, 120], // 月为单位
isSterilized: null
}
},
loadMore: function() {
wx.request({
url: 'https://api.example.com/cats/',
data: {
page: this.data.page,
...this.data.filters
},
success: (res) => {
this.setData({
cats: [...this.data.cats, ...res.data.results],
page: this.data.page + 1
})
}
})
}
})
3.3 微信支付集成
捐赠功能的核心是微信支付接口调用:
python复制# Django后端创建支付订单
import random
import time
from wechatpayv3 import WeChatPay, WeChatPayType
wechatpay = WeChatPay(
appid='wx123456789',
mchid='1900000109',
private_key='...',
cert_serial_no='...',
apiv3_key='...'
)
def create_donation_order(user, amount):
out_trade_no = f'D{int(time.time())}{random.randint(1000,9999)}'
description = f'流浪猫救助捐赠-{amount}元'
resp = wechatpay.pay(
description=description,
out_trade_no=out_trade_no,
amount=amount*100,
payer={'openid': user.openid}
)
return resp['prepay_id']
避坑提示:微信支付金额单位为分,需要将元转换为分。测试环境务必使用沙箱账号,避免产生真实交易。
4. 后台管理功能实现
4.1 Django Admin定制化
默认Admin后台无法满足复杂审核需求,我们进行了深度定制:
python复制# admin.py
class AdoptionApplicationAdmin(admin.ModelAdmin):
list_display = ('cat', 'applicant', 'status', 'apply_time')
list_filter = ('status', 'cat__location')
actions = ['approve_applications']
def approve_applications(self, request, queryset):
queryset.update(status='A')
for app in queryset:
send_template_message(app.applicant.openid, '领养申请通过通知')
def get_queryset(self, request):
qs = super().get_queryset(request)
if not request.user.is_superuser:
return qs.filter(status='P')
return qs
4.2 自动化任务设计
使用Celery实现三个关键自动化任务:
- 领养进度提醒:申请超过3天未处理时通知管理员
- 健康打卡提醒:成功领养后每月提醒领养人提交猫咪近况
- 捐赠使用公示:每月生成资金使用报告并推送
python复制# tasks.py
from celery import shared_task
from django.core.mail import send_mail
@shared_task
def check_pending_applications():
from datetime import datetime, timedelta
from .models import AdoptionApplication
threshold = datetime.now() - timedelta(days=3)
pending = AdoptionApplication.objects.filter(
status='P',
apply_time__lte=threshold
)
if pending.exists():
send_mail(
'有待处理的领养申请',
f'有{pending.count()}条申请超过3天未处理',
'noreply@example.com',
['admin@example.com']
)
5. 部署与运维实践
5.1 服务器环境配置
推荐使用Ubuntu 20.04 LTS + Nginx + uWSGI方案:
bash复制# 安装基础依赖
sudo apt update
sudo apt install -y python3-pip python3-dev libmysqlclient-dev nginx
# 配置虚拟环境
python3 -m venv /opt/venv
source /opt/venv/bin/activate
pip install -r requirements.txt
# uWSGI配置示例(uwsgi.ini)
[uwsgi]
module = adoptcat.wsgi:application
master = true
processes = 5
socket = adoptcat.sock
chmod-socket = 666
vacuum = true
die-on-term = true
5.2 微信小程序审核要点
通过审核需要特别注意:
- 类目选择:必须选择"公益"或"宠物"类目
- 内容规范:不得出现募捐相关字眼,改用"支持救助"
- 隐私协议:必须明确说明学号等信息的用途
- 支付说明:捐赠必须注明"非公益募捐,自愿支持"
5.3 监控与日志
我们采用Sentry+Prometheus的方案:
python复制# settings.py
LOGGING = {
'version': 1,
'handlers': {
'sentry': {
'level': 'ERROR',
'class': 'sentry_sdk.integrations.logging.EventHandler',
},
},
'loggers': {
'django': {
'handlers': ['sentry'],
'level': 'ERROR',
'propagate': False,
},
},
}
6. 项目演进与优化方向
在实际运行三个月后,我们发现几个需要改进的点:
-
领养匹配算法:目前是简单的时间排序,计划加入:
- 地理位置优先(同校区优先)
- 经验匹配(有养猫经验者优先)
- 猫咪性格考量(活泼/安静匹配申请人生活方式)
-
健康档案系统:
- 对接宠物医院API直接同步体检记录
- 使用IPFS存储猫咪的医疗影像资料
- 区块链存证重要医疗记录
-
社区功能增强:
- 领养人互助论坛
- 线下活动报名系统
- 猫咪成长相册共享
一个特别实用的经验是:在猫咪信息采集阶段,我们开发了标准化表单工具,志愿者通过小程序上传时,系统会自动:
- 从照片中提取主要毛色(使用OpenCV颜色识别)
- 估算年龄范围(基于牙齿和体型特征)
- 生成唯一的猫咪ID(二维码项圈)
这套系统在清华大学试点期间,成功为47只流浪猫找到了新家,募集医疗资金2.3万元。最关键的是建立了一套可持续的校园流浪动物管理机制,而不是一次性的活动。
