手机版

PHP仿微信发红包领红包效果

时间:2021-09-13 来源:互联网 编辑:宝哥软件园 浏览:

近期项目需要在聊天的基础上新增红包功能,需求:仿微信(不含留言),但只能使用余额发红包。于是多次使用微信红包,了解各种交互界面及业务需求,如展示信息、分类(个人,群普通,群拼手气)、个数限制(100)、金额限制(200)、过期时间(24小时)等等,然后着手开发,下面提及的基本全是提供给应用端的接口,毕竟我是phper。

一、设计数据表如下

CREATE TABLE ` red _ packet `(` id ' int(10)无符号非空自动增量,`用户标识'整数(10)无符号非空默认值“0”注释用户id ',' for _ id ' int(10)无符号非空默认值“0”注释发放对象(用户或群id)'、` pay_status` tinyint(1)无符号非空默认值“0”注释支付状态:0未支付,1已支付、` type` tinyint(1)无符号非空默认值“0”注释类型:1、个人,2、群普通,3、群拼手气,` intro ` varchar(255)NOT NULL DEFAULT ' ' COMMENT '简介,` number` tinyint(1)无符号非空默认值“0”注释个数,'总货币'十进制(10,2)无符号非空默认值' 0.0 '注释'总金额,` single_money` decimal(10,2)无符号非空默认值' 0.0 '注释'单个红包金额(群拼手气时为0)',' return_money '十进制(10,2)无符号非空默认值' 0.0 '注释'退还金额,` is_cli_handle` tinyint(1)无符号非空默认值"0"注释是否经过硬币指示器(硬币水平指示器的缩写)命令行界面(批处理脚本的命令行界面)退款处理:0否,1是、“expand _ time”中等整数(1)无符号非空默认值“0”注释领取消耗时间,` add_time` int(10)无符号非空默认值“0”注释创建时间,` pay_time` int(10)无符号非空默认值“0”注释支付时间,PRIMARY KEY (`id `),KEY `user_id` (`user_id `),KEY `pay_status` (`pay_status `),KEY ` pay _ time `)(` pay _ time `)ENGINE=Innodb DEFAULT CHARSET=utf8 COMMENT='红包发放表; CREATE TABLE ` red _ packet _ log `(` id ' int(10)无符号非空自动增量,` RP _ id '整数(10)无符号非空默认值“0”注释红包id ',' user _ id ' int(10)无符号非空默认值“0”注释领取人'身份证','钱'十进制(10,2)无符号非空默认值' 0.0 '注释'领取金额,` is_good` tinyint(1)无符号非空默认值“0”注释是否手气最佳:0否,1是,` add_time` int(10)无符号非空默认值“0”注释添加时间,` update_time` int(10)无符号非空默认值“0”注释领取时间,PRIMARY KEY (`id `),KEY ` RP _ id `(` RP _ id `))ENGINE=Innodb DEFAULT CHARSET=utf8 COMMENT='红包领取日志表;二、发红包

由于支付成功之后,红包就马上发到聊天界面了,所以在左图"塞钱进红包"时,就把红包信息插入红色数据包表(支付状态未支付),并分配好金额、计算手气打乱后插入red_packet_log表(领取人和领取时间为空),右图"确认支付"成功之后,更新红色数据包表的支付状态,然后发出红包。

三、领红包(这里只针对群红包进行分析)

请用自己的大脑来弥补领取红包的各种前提条件。这里我们说一个并发的群里抢红包的问题(几十个人群里抢到几个红包)通过引入MQ来解决。发红包时,将红包数量依次写入MQ。比如发三个红包的时候,依次写1、2、3。抓取红包时,从MQ取值,得到数字表示你在抓取哪个红包,对应red_packet_log表中的哪个红包。下一步是更新red_packet_log表的收件人和时间,以及余额加钱并记录流水,然后返回收款结果;如果拿不到数字,当然意味着没有抢到红包,直接会得到“慢手”界面。前期考虑将red_packet_log表的主键写入MQ,通过排序可以保存哪些日志记录,但这会使“收集花费的时间”字段的更新更加麻烦;使用MQ存储数字,可以直接比较是否是最后一个红包(获得的数字和红包数量),然后更新消费时间。

微信红包的领取结果页面(即查看幸运页面)有很多种:个人和团体的结果不同,发红包的人和领红包的人看到的东西不同,个人和团体红包过期后的提示不同等。这里没有列出这些页面,但基本上都是基于检查数据库的界面。

四是需求变化,增加第三方支付

说到第三方支付,就要提到同步和异步回拨,以及回拨时间差。同步回拨成功后,app会发出红包(app的支付同步回拨直接调用回拨)。如果此时异步回拨慢了一两秒,用户就会抢到付款状态为0的红包。如果app端调用长连接接口检查异步回调是否成功,然后发出红包,用户体验相对较差。

#引入中间状态alter table ` red _ packet `修改列` pay _ status ` tinyint (1)未签名不为空默认0备注'支付状态:0未支付,1已支付,2等待接收' AFTER `for_id ',添加列` pay _ type`tinyint (1)不为空默认0备注'支付方式:0未知,1支付宝,2微信,3银联' after`pay _ status ', add column ` trade _ No ` varchar(30)not null default ' ' comment '第三方支付交易号' AFTER ` pay _ type ' Alter table ` red _ packet _ log ` add column ` is _ into _ account ` tinyint(1)未签名not null default 0 comment '收到:0 No,1是' AFTER ` is _ good '; 用户抢红包时,is_into_account的值根据pay_status确定;

同步回呼app时,调用接口将支付状态pay_status改为2;

异步回调服务器时,pay _ pay _ status变为1,找到is_into_account=1的red_packet_log记录进行处理。

但是在以上三个步骤中,red_packet的查询必须进行FOR UPDATE操作,否则会在执行时间和顺序上出现问题,导致部分red_packet_log记录无法入账,is _ into _ account=0;此外,锁机制会让用户抓取红包非常慢,因为锁必须被释放。

改进如下:(不针对整个过程中的更新)

用户抢红包时,is_into_account的值根据pay_status确定;

同步回呼app时,调用接口将支付状态pay_status改为2;

异步回调服务器时,将pay _ pay _ status改为1,将红包id(red_packet主键)放入MQ;

后台自动脚本,从MQ获取红包id后,处理红包is_into_account=0的记录,然后延时5秒再次将红包id写入MQ进行二次处理,确保所有数据都收到。

5.红包过期并退款

这是一个自动脚本。根据red_packet表中的pay_time判断钱是否已经超过24小时,还没有收款,返回用户余额。

版权声明:PHP仿微信发红包领红包效果是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。