
1. 项目背景与核心需求校园餐饮服务一直存在高峰期排队时间长、菜品信息不透明、支付方式单一等问题。这个项目正是为了解决这些痛点通过构建一个同时支持小程序和Web端的同构点餐平台让师生能够随时随地进行线上点餐、支付和取餐。我在实际开发中发现同构架构的最大优势在于能够复用大部分业务逻辑代码。比如用户认证、订单处理、支付对接等核心功能在小程序和Web端可以共享同一套Python后端代码。这不仅提高了开发效率也保证了不同终端用户体验的一致性。2. 技术架构设计2.1 前后端分离架构我们采用了经典的前后端分离架构后端Python Django REST Framework前端微信小程序 Web端(React/Vue)数据库MySQL Redis缓存选择Django REST Framework是因为它提供了完善的API开发工具和认证机制。实测下来DRF的序列化器和视图集能极大简化数据交互逻辑的开发。2.2 同构实现方案同构的核心在于API设计。我们定义了统一的RESTful接口规范/api/v1/menus # 获取菜单 /api/v1/orders # 订单操作 /api/v1/payments # 支付处理小程序和Web端都调用相同的API端点只是根据平台特性做了不同的UI适配。比如小程序使用微信支付Web端支持支付宝和微信支付两种方式。3. 核心功能实现3.1 用户认证系统考虑到校园环境的特殊性我们实现了三种登录方式微信授权登录小程序端学号密码登录Web端访客模式仅限浏览# Django认证示例 from rest_framework.authtoken.models import Token def login(request): user authenticate(usernameusername, passwordpassword) if user: token, _ Token.objects.get_or_create(useruser) return Response({token: token.key})注意访客模式下需要特别注意权限控制避免未登录用户访问敏感接口。3.2 菜品展示与搜索我们设计了多维度菜品展示按食堂/档口分类热门推荐个性化推荐基于历史订单搜索功能支持关键词搜索菜品标签筛选辣/甜/素食等价格区间过滤# 搜索视图示例 class MenuSearchView(APIView): def get(self, request): queryset Menu.objects.all() # 关键词过滤 if q in request.GET: queryset queryset.filter(name__icontainsrequest.GET[q]) # 价格过滤 if min_price in request.GET: queryset queryset.filter(price__gterequest.GET[min_price]) # 分页处理 paginator Paginator(queryset, 20) page paginator.page(request.GET.get(page, 1)) serializer MenuSerializer(page, manyTrue) return Response(serializer.data)3.3 购物车与订单系统购物车设计考虑了校园场景的特殊需求支持多食堂菜品合并下单预定取餐时间选择订单备注忌口、加辣等订单状态流转待支付 → 已支付 → 制作中 → 待取餐 → 已完成重要提示订单超时未支付需要设计自动取消机制通常设置为15分钟。4. 支付系统集成4.1 微信支付对接小程序端必须使用微信支付我们使用官方SDK进行集成from wechatpayv3 import WeChatPay wechatpay WeChatPay( appidwx123456789, mchid1230000109, keyyour-api-key, cert_snyour-cert-sn, private_keypath/to/your/key.pem ) def create_wxpay_order(order_id, amount, openid): resp wechatpay.pay( description校园点餐, out_trade_noorder_id, amountamount, payer{openid: openid} ) return resp[prepay_id]4.2 Web端支付方案Web端需要同时支持微信支付和支付宝# 支付宝支付示例 from alipay import AliPay alipay AliPay( appid2021000116651234, app_notify_urlNone, app_private_key_stringopen(private_key.txt).read(), alipay_public_key_stringopen(alipay_public_key.txt).read(), sign_typeRSA2 ) def create_alipay_order(order_id, amount): order_string alipay.api_alipay_trade_page_pay( out_trade_noorder_id, total_amountstr(amount), subject校园点餐, return_urlhttps://yourdomain.com/pay/return, notify_urlhttps://yourdomain.com/pay/notify ) return https://openapi.alipay.com/gateway.do? order_string5. 性能优化实践5.1 数据库优化针对高并发场景我们采取了以下措施添加适当的数据库索引使用select_related/prefetch_related减少查询次数热点数据缓存# 使用缓存示例 from django.core.cache import cache def get_menu_list(): key menu_list data cache.get(key) if not data: data list(Menu.objects.all().select_related(canteen)) cache.set(key, data, timeout3600) return data5.2 异步任务处理将耗时操作放入Celery异步任务订单状态通知支付结果处理数据统计报表生成# Celery任务示例 app.task def process_payment_notify(payment_data): try: order Order.objects.get(idpayment_data[out_trade_no]) if payment_data[total_amount] order.amount: order.status paid order.save() send_order_notify.delay(order.id) except Exception as e: logger.error(fPayment process error: {str(e)})6. 安全防护措施6.1 常见安全防护SQL注入防护使用ORM或参数化查询XSS防护模板自动转义 内容安全策略CSRF防护Django内置中间件 小程序端自定义header校验6.2 支付安全支付环节需要特别注意金额校验前端后端双重校验支付结果异步通知验证订单状态幂等性处理# 支付结果验证示例 def verify_wxpay_notify(data): try: result wechatpay.decrypt_callback(data) if result[trade_state] SUCCESS: return True except Exception as e: logger.error(fVerify wechatpay failed: {str(e)}) return False7. 部署与运维7.1 服务器部署我们使用Nginx Gunicorn部署Django应用server { listen 80; server_name api.yourdomain.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /static/ { alias /path/to/your/static/files; } }7.2 小程序部署注意事项域名备案必须HTTPS配置合法业务域名微信支付商户号绑定8. 踩坑经验分享微信小程序登录会话过期问题解决方案实现token自动刷新机制关键代码def refresh_token(old_token): try: token Token.objects.get(keyold_token) new_token Token.objects.create(usertoken.user) token.delete() return new_token.key except Token.DoesNotExist: raise AuthenticationFailed(Invalid token)高并发下的库存扣减问题超卖现象解决方案使用select_for_update悲观锁from django.db import transaction transaction.atomic def reduce_inventory(menu_id, quantity): menu Menu.objects.select_for_update().get(idmenu_id) if menu.stock quantity: menu.stock - quantity menu.save() return True return False支付结果通知处理教训必须实现幂等性处理改进增加支付记录表通过transaction_id去重这个项目让我深刻体会到同构架构在跨平台开发中的优势。特别是在校园这种相对封闭的环境中通过统一的后台管理系统和数据分析平台食堂经营者可以更好地掌握销售情况优化菜品结构。而对学生来说节省排队时间、提前了解菜品信息确实提升了校园生活体验。