业务描述:
无限层级分享返利,每层按照流水和一定的返利系数逐层往上返利,相信大家在处理此类业务的时候多多少少有点头大,横向的层级,和纵向的关系都需要考虑,涉及到数据存储和大量计算,不管是整个树的宽度还是高度,随着时间的推移都将很是庞大,在业务实际运算中,一般会限制层级的计算,因为如果层级计算过多,顶端的数值将会越来越小,没有意义。
数据存储设计的好坏直接关系到后台的查询及前端的各种展示,例如:查找某个用户有多少个直属下级,有多少个非直属下级,每天通过直属下级获得返利是多少,每天通过非直属下级获得的返利是多少,某个用户每一层的用户是哪些,何时计算用户每天的返利情况,某个用户的所有上层分享者是谁 等等。这些才是业务比较关键的点。
如果按照横向每一层级计算,查找是个问题,如何查到每个层级的每个用户,而且一般是是从下往上返利,想想都头大
如果按照纵向的处理此类业务从下往上倒是一个比较好的处理办法,把横向的业务逻辑转换经纵向的业务逻辑。
分享模型:
业务举例:
逻辑处理:
处理此类业务的关键是邀请用户进来的时候,要判断出几个关键信息,初始化邀请基本信息表,上级邀请关系链,记录所有上级直属下级,非直属下级数量,初始化用户自身邀请信息,返利汇汇总信息等.
邀请基本信息表:
上级邀请关系链:
增加所有纵向从上往上直属,非属下级数量:
记录直属上级信息,记录所有上级当天直属下级,非直属下级数量,这个一般有缓存记录即可,供后台和前端展示。
获取邀请者的下级关系连层级-》用户
public function getLowerUids($user_id,$level=1,&$treelist=[]){ if(empty($user_id)){ return []; } $aInvite = $this->odb->table('xxxxxx')->where("user_id in (".$user_id.")")->field("invite_user_id")->select(); if($aInvite){ $atmp = array_column($aInvite,"invite_user_id"); $treelist[$level] = $atmp; $user_ids = implode(",",$atmp); $this->getLowerUids($user_ids,$level+1,$treelist); } return $treelist; }
获取邀请者的上级关系连层级-》用户
public function getLastUids($user_id,&$treelist=[]){ if(empty($user_id)){ return []; } $inviteid = $this->odb->table('xxxxx')->where("invite_user_id=".$user_id)->getField('user_id'); if($inviteid){ $treelist[] = $inviteid; $this->getLastUids($inviteid,$treelist); } return $treelist; }
二,返利相关
用户每日流水不在详细记录,目前采取的方法是每个用户每天只会记录一条用户(对于数据量特别大的时候这个逻辑可能会有问题)或者超时,要采用其它方案,消息队列之类异步发放。
需要记录每个人每天通过不同的下级锋利的流水和返利
需要统计历史通过直属下级和非直属下级获得的返利汇总
需要记录每个用户当天实时下级流水和返利情况
未完待续