我的微信公众号项目
微信公众号加上 web 端。
微信功能:处理各种微信推送事件的逻辑:比如关注、取消关注、通过推荐人关注、解析文本、分享到朋友圈、微信支付等
其他主要功能:多账号系统、流量充值、积分系统、卡券系统、大转盘、拼图游戏。
熟悉了微信公众号的开发流程,开发过程中的微信参数以及微信配置都是我自己去微信上拿到的,比如 access_token,商户号之类的。
提交代码到开源项目python微信sdk
项目初期接手,之前有两拨人做过。为了适配web端,进行了很大的重构。之前的项目架构也不合理。比如通过 openid 作为外键,现在是使用 user。
多账号系统
数据库设计
class UserProfile(BaseModel): """用户信息 必填""" user = models.OneToOneField(User, related_name='user_profile', verbose_name='用户名') class UserWechatProfile(BaseModel): """储存用户的微信相关信息 选填""" user = models.OneToOneField(User, related_name='user_wechat_profile', verbose_name='手机号') # 关联自带的User结构
然后在各个model添加各自需要的字段,比如 `UserWechatProfile` model,很多都是关注后微信推送来的信息,这个在 web 端就不存在。
问:如何添加其他的,比如通过微博登录
增加 model: `UserWeiBoProfile` 里面存放 user 也是 OneToOneField 的关系,然后是一些基本字段以及微博特有的字段。
验证
通过不同的方式登陆
微信上登陆
微信网页授权后能获取用户的 openid,通过 openid 在UserWechatProfile查找,得到user,然后登陆
web端登陆
验证手机验证码后,通过手机号在 UserProfile查找到 user,然后登陆
以上两者的具体实现方式:自定义 Django `AUTHENTICATION_BACKENDS`,然后将路径添加到 settings.AUTHENTICATION_BACKENDS 里面。
class WeixinAccessTokenAuthenticationBackend(object): """在公众号内使用 openid 登录,不需要再次输入账号密码""" def authenticate(self, openid=None, access_token=None): """ :param openid: :param access_token: 微信网页授权的 access_token, 每个 openid 一个 :return: None or User """ try: user_wechat_profile = UserWechatProfile.objects.get(openid=openid) except User.DoesNotExist: return None return user_wechat_profile.user def get_user(self, user_id): try: user = User.objects.get(pk=user_id) except User.DoesNotExist: return return user
调用时需要显式传递参数
user = authenticate(openid=openid)
积分系统
数据库结构
UserProfile 中有一个 points 字段
TallyBook model 用来记录积分的变动
其他用到积分的地方:流量订单
防作弊
增加积分
扣除积分
我的另一篇文章:如何防止别人抓包重放攻击
卡券系统
数据库结构
流量券套餐:用户可以购买的流量券种类
用户流量券
用户购买流量券的订单
流量券使用记录
业务逻辑
通过 redis 防止重复使用
根据手机号码、运营商拆分充值。比如 电信没有2G流量,那么拆分成两个 1G 流量充值
大转盘
数据库结构
奖品名称、抽取几率、是否是奖品、获奖积分
抽奖的流程
前端发送抽奖请求
验证是否能抽奖
验证抽奖次数、验证积分是否足够
进行抽奖
求得奖品的概率总和 pro_sum
遍历奖品queryset
生成随机数
如果生成的随机数<=奖品的概率,则中奖
否则,pro_sum 减去奖品的概率,进行下一次抽奖
返回前端
前端根据返回的奖品名称,对应到一个角度范围,然后让指针停在这个范围里面
拼图游戏
传递一系列的图片 urls 给前端
前端提交获取积分的请求
验证获取积分的请求
获取积分前先要买门票
获取了第一关的积分才能获取第二关的积分