product->total * $data['quantity']; //问卷总数 UserModel::currency7($data['user_id'],$questionnaire_count,\app\enum\BalanceType::PRODUCT_BUY,'购买产品'); $user = UserModel::find($data["user_id"]); //设置定时任务发放问卷,马上发放第一天的,然后每隔24小时发放一次,发放到第$data->product->days天 $assign_count = $data->product->assign_count; addJob([ 'action' => 'assign', 'user_id' => $data['user_id'], 'order_id' => $data['id'], 'amount' => $assign_count, ],'Questionnaire'); //$data = //用户消费统计更新 cache_add('user_consume_total_'.$data['user_id'],$data['amount']); $parent_id = $this->get_parent_id($data['user_id']); if($parent_id){ // 销售奖励(直推) // $reward = bcmul($data['amount'] ,2,0); // UserModel::score($parent_id ,$reward,\app\enum\BalanceType::SALES_REWARD,$data['id']); // cache_add('user_sales_reward_'.$parent_id,$reward); //销售奖励 $ancestorIds = Db::name('user_team')->where('descendant_id',$data['user_id']) ->column('ancestor_id'); if(!empty($ancestorIds)){ // 批量累加上级业绩 Db::name('user_extend')->whereIn('user_id',$ancestorIds)->where('user_id','<>',$data['user_id'])->update([ 'sales' => Db::raw('sales+'.$data['amount']) ]); $users = Db::name('user')->whereIn('id',$ancestorIds)->where('group',2)->column('id'); // 销售奖励(渠道) foreach($users as $uid){ $reward = bcmul($data['amount'] ,8,0); UserModel::score($uid ,$reward,\app\enum\BalanceType::SALES_REWARD,$data['id']); cache_add('user_sales_reward_'.$uid,$reward); //销售奖励 } } return $data; // 业绩与等级批量更新(事务内:所有上级的 sales 与 role_id) $this->updateAncestorsSalesAndLevel($data['user_id'],$data['amount']); //我的用户表有role_id:角色ID,id:用户ID,详细可以查看\app\model\User的属性 //$data['user_id'] //购买人ID //$data['amount'] //交易金额 //$data['role_id'] //用户角色 //上级user_id查询用$this->get_parent_id($user_id) //$parent_user_role_id = \app\model\User::where('id',$this->get_parent_id($data['user_id']))->value('role_id'); //用户余额增加使用 User::money(用户ID,增加的金额,\app\enum\BalanceType::SALES_REWARD,$data['id']); // 分佣规则 //从当前用户 // 代理佣金总和是交易金额的10% // 极差收益,type=\app\enum\BalanceType::SALES_REWARD // 极差收益总和是交易金额的20% // 最多只能10个人分,如果上级用户级别小于上一个分润的人的级别,就跳过他,继续找下一个,始终补满10个人,直到级别等于10或者上级为空的时候才停止 // 每个人分润的比例是(极差收益比例-已经分出去的比例)*极差收益总和 //代码写在这里,不能去掉我的注释 $distributed_users = jicha($data['user_id'],$data['amount'],[0,0.02,0.04,0.06,0.08,0.1]); foreach($distributed_users as $k=>$v){ UserModel::money($v['user_id'],$v['amount'],\app\enum\BalanceType::SALES_REWARD,$data['id']); cache_add('user_income_total_'.$v['user_id'],$v['amount']); //收入统计 cache_add('user_sales_reward_'.$v['user_id'],$v['amount']); //销售奖励 } } return $data; } // 批量更新所有上级的业绩并根据阈值升级角色(单事务) private function updateAncestorsSalesAndLevel($user_id,$delta_sales){ Db::startTrans(); try{ // 取出所有上级ID $ancestorIds = Db::name('user_team')->where('descendant_id',$user_id)->column('ancestor_id'); if(empty($ancestorIds)){ Db::commit(); return; } // 批量累加上级业绩 Db::name('user_extend')->whereIn('user_id',$ancestorIds)->update([ 'sales' => Db::raw('sales+'.$delta_sales) ]); // 读取更新后的 sales 和当前 role_id $extends = Db::name('user_extend')->whereIn('user_id',$ancestorIds)->column('sales','user_id'); $roles = Db::name('user')->whereIn('id',$ancestorIds)->column('role_id','id'); $levelArr = [0,5000,10000,50000,100000,200000]; $maxIdx = count($levelArr)-1; $upgradeMap = []; foreach($extends as $uid=>$sales){ cache_add('user_consume_reward_'.$uid,$sales);//个人消费统计 cache_add('team_consume_total_'.$uid,$sales); //团队总业绩 // 计算应达的最高等级 $newLevel = 0; for($i=$maxIdx;$i>=0;$i--){ if($sales >= $levelArr[$i]){ $newLevel = $i; break; } } $current = isset($roles[$uid]) ? (int)$roles[$uid] : 0; if($newLevel > $current){ $upgradeMap[$uid] = $newLevel; } } // 批量升级(按新等级分组,可减少语句数) if(!empty($upgradeMap)){ $levelToUsers = []; foreach($upgradeMap as $uid=>$lvl){ $levelToUsers[$lvl][] = $uid; } foreach($levelToUsers as $lvl=>$uids){ Db::name('user')->whereIn('id',$uids)->where('group',2)->where('role_id','<',$lvl)->update(['role_id'=>$lvl]); } } Db::commit(); }catch(\Throwable $e){ Db::rollback(); throw $e; } } function get_parent_id($user_id){ if($this->debug){ return $this->userinfo[''.$user_id]['parent_id']; } return get_parent_id($user_id); } function log($str){ $args = func_get_args(); if(is_string($args[0])){ $str = call_user_func_array('sprintf',$args); if($this->debug){ return print_r($str); } log_alert($str); }else{ $str = json_encode($args); if($this->debug){ return print_r($str); } log_alert($str); } } }