belongsTo('app\\common\\model\\plus\\bonus\\Grade', 'grade_id', 'grade_id'); } /** * 关联会员记录表 * @return \think\model\relation\BelongsTo */ public function user() { return $this->belongsTo('app\\common\\model\\user\\User'); } /** * 关联推荐人表 * @return \think\model\relation\BelongsTo */ public function referee() { return $this->belongsTo('app\\common\\model\\user\\User', 'referee_id', 'user_id'); } /** * 关联排位上级 * @return \think\model\relation\BelongsTo */ public function parent() { return $this->belongsTo('app\\common\\model\\user\\User', 'parent_id', 'user_id'); } /** * 推荐的人员 * @return \think\model\relation\HasMany */ public function agentuser() { return $this->hasMany('app\\common\\model\\plus\\agent\\User', 'referee_id', 'user_id') ->order(['create_time' => 'desc']) ->withlimit(1); } /** * 详情 */ public static function detail($user_id, $with = ['user', 'referee']) { return (new static())->with($with)->find($user_id); } /** * 是否为队长 */ public static function isBonusUser($user_id) { $team = self::detail($user_id); return !!$team && !$team['is_delete']; } /** * 新增分红用户记录 * @param $user_id * @param $data * @return bool */ public static function add($user_id, $data) { /* 排位规则: 1、直推的第一第二个人都往自己这条线下排 2、直推的第三个人起从总线开始,从上往下,从左往右找空位进行排位。 */ //如果是第一个分红用户,生成预留排位 if(!(new static())->count()) { return self::addTheFirst($user_id, $data); } $model = static::detail($user_id); //如果是新增 if(!$model) { $model = new static; //获取直推上级 $referee_id = agentRefereeModel::getRefereeUserId($user_id, 1); //获取直推上级推荐的人数 /*$direct_child_num = $referee_id ? self::getDirectNum($referee_id) : 0;*/ $parent_id=0; if ($referee_id) { $parent_id=self::getParentId([$referee_id]); } if ($parent_id) { $parent = static::detail($parent_id); //如果自己名下已经被排满,继续往下找 if ($parent['child_num'] == 3) { //获取起始横向排位 $level_num_first = ($parent['level_num'] - 1) * 3 + 1; $parent = self::checkUserChild($level_num_first, 3, $parent['tree_level'] + 1); } } else { //规则2:查找有空缺的三叉树 $parent = (new static())->where('child_num', '<', 3) /*->where('user_id', "<>", $referee_id)*/ ->order(['tree_level' => 'asc', 'level_num' => 'asc'])->find(); } $data['parent_id'] = $parent['user_id']; $data['order_num'] = $parent['child_num'] + 1; //三叉树内的位置 $data['tree_level'] = $parent['tree_level'] + 1; //竖向层级 $data['level_num'] = ($parent['level_num'] - 1) * 3 + $data['order_num']; //所在层的横向排序位置 $parent->save([ 'user_id' => $parent['user_id'], 'grade_id' => Grade::getDefaultGradeId(), 'child_num' => $parent['child_num'] + 1 ]); } $user=UserModel::detail($user_id); if ($model->save(array_merge([ 'user_id' => $user_id, 'is_delete' => 0, 'purchase_count' => $user['purchase_count'], 'grade_id' => Grade::getDefaultGradeId(), 'app_id' => $data['app_id'] ], $data))) { //记录分红层级关系 RefereeModel::createRelation($user_id, $data['parent_id']); } return true; } /** * 获取团队里公排下级未被排满的id */ public static function getParentId($referee) { $user=(new static())->where('user_id', 'in', $referee)->where('child_num', '<', 3)->find(); if ($user) { return $user['user_id']; } $subordinate=(new self())->where('parent_id', 'in', $referee)->column('user_id'); return self::getParentId($subordinate); } /** * 添加第一个分红用户 */ private static function addTheFirst($user_id, $data) { $model = new static; $data['parent_id'] = 0; $data['order_num'] = 1; //三叉树内的位置 $data['tree_level'] = 1; //竖向层级 $data['level_num'] = 1; //所在层的横向排序位置 $data['child_num'] = 3; //直属排位 $model->save(array_merge([ 'user_id' => $user_id, 'is_delete' => 0, 'app_id' => $data['app_id'] ], $data)); //记录分红层级关系 RefereeModel::createRelation($user_id, $data['parent_id']); //生成12个预留排位 for ($i=1; $i <= 3; $i++) { $user = UserModel::create([ 'open_id' => $i, 'reg_source' => 'sys', 'nickName' => '预留' . $i, 'app_id' => $data['app_id'] ]); $new_user_id = $user->user_id; $model->create([ 'user_id' => $new_user_id, 'is_delete' => 0, 'app_id' => $data['app_id'], 'parent_id' => $user_id, 'order_num' => $i, 'tree_level' => 2, 'level_num' => $i ]); //记录分红层级关系 RefereeModel::createRelation($new_user_id, $user_id); for ($j=1; $j <= 3; $j++) { $user = UserModel::create([ 'open_id' => $i . '_' . $j, 'reg_source' => 'sys', 'nickName' => '预留' . $i . '_' . $j, 'app_id' => $data['app_id'] ]); $child_user_id = $user->user_id; $model->create([ 'user_id' => $child_user_id, 'is_delete' => 0, 'app_id' => $data['app_id'], 'parent_id' => $new_user_id, 'order_num' => $j, 'tree_level' => 3, 'level_num' => ($i - 1) * 3 + $j ]); $model->save([ 'user_id' => $new_user_id, 'child_num' => $j ]); RefereeModel::createRelation($child_user_id, $new_user_id); } } return true; } public function addTheFirst4() { $model = new self; $grade_id=GradeModel::getDefaultGradeId(); if ($model->where('tree_level',4)->count()){ return true; } //记录分红层级关系 $i=4; $userList=$model->where('tree_level',3)->select(); $k=0; foreach ($userList as $tree){ $new_user_id=$tree['user_id']; for ($j=1; $j <= 3; $j++) { $k++; $user = UserModel::create([ 'open_id' => $i . '_' .$k, 'reg_source' => 'sys', 'nickName' => '预留' . $i . '_' . $k, 'grade_id'=>$grade_id, 'app_id' => 10142 ]); $child_user_id = $user->user_id; $model->create([ 'user_id' => $child_user_id, 'is_delete' => 0, 'app_id' => 10142, 'parent_id' => $new_user_id, 'order_num' => $j, 'tree_level' => 4, 'level_num' => $k ]); $model->where('user_id',$new_user_id)->save([ 'user_id' => $new_user_id, 'child_num' => $j ]); RefereeModel::createRelation($child_user_id, $new_user_id); } } return true; } /** * 查找横向位置内符合条件的用户 * @param $level_num_first 查找的横向起始位置 * @param $search_num 查找的数量,用于计算横向结束位置 */ private static function checkUserChild($level_num_first, $search_num, $tree_level) { //结束位置的序号 // log_write('level_num_first:'.$level_num_first); $level_num_end = $level_num_first + ($search_num - 1); //log_write($level_num_end); $user = (new static())->where('child_num', '<', 3) ->where('level_num', '>=', $level_num_first) ->where('level_num', '<=', $level_num_end) ->where('tree_level', '=', $tree_level) ->order(['level_num' => 'asc'])->find(); if($user) { //log_write($user); return $user; } else { $new_level_num_first = ($level_num_first - 1) * 3 + 1; $new_search_num = $search_num * 3; $new_tree_level = $tree_level + 1; return self::checkUserChild($new_level_num_first, $new_search_num, $new_tree_level); } } /** * 发放队长佣金 * @param $user_id * @param $money * @return bool */ public static function grantMoney($user_id, $money, $money_type,$purchase_count = 0) { $money_type_arr = ['10' => '直推奖', '20' => '业绩奖', '30' => '直推收益补贴']; $is_expire = User::isExpire($user_id); // 队长详情 $model = static::detail($user_id); if (!$model) { return false; } if ($model['is_delete']){ return false; } if ($money_type == 20){ if ($model['purchase_count']<$purchase_count){ $model->where('user_id', '=', $user_id)->inc('freeze_money_second', $money)->update(); }else{ $model->where('user_id', '=', $user_id)->inc('money', $money)->update(); } }else{ $model->where('user_id', '=', $user_id)->inc('money', $money)->update(); } //直推人数 /*$direct_num = self::getDirectNum($user_id); //如果是业绩奖并且用户没有直推下级,则冻结其业绩奖 if ($money_type == 20) { //前三个直推每推一个解冻一个,直推>=3并且符合不冻结条件时解冻全部 if (($direct_num > 0 && $direct_num <= 3 && PerformanceModel::getPerformanceCount($user_id, true) <= $direct_num) || self::isBackFreezeAll($user_id)) { // 如果排位过期,也冻结 by lyzflash 2013.01.14 if ($is_expire) { $model->where('user_id', '=', $user_id)->inc('freeze_money_second', $money)->update(); } else { // 累积队长可提现分红 $model->where('user_id', '=', $user_id)->inc('money', $money)->update(); } } else { // 冻结 $model->where('user_id', '=', $user_id)->inc('freeze_money_second', $money)->update(); } // 排位不过期才能解冻业绩分红 by lyzflash 2023.01.26 if ($direct_num > 3 && $model['freeze_money_second'] > 0 && !$is_expire) { self::backFreezeMoneySecond($user_id, $direct_num); } } else { // 累积队长可提现分红(直推奖) $model->where('user_id', '=', $user_id)->inc('money', $money)->update(); } //直推奖时,判断要不要解冻业绩分红 // 排位不过期才能解冻业绩分红 by lyzflash 2023.01.26 if ($money_type == 10 && !$is_expire) { self::backFreezeMoneySecond($user_id, $direct_num); }*/ // 记录队长资金明细 Capital::add([ 'user_id' => $user_id, 'flow_type' => 10, 'money' => $money, 'money_type' => $money_type, 'describe' => '订单分红结算-' . $money_type_arr[$money_type], 'app_id' => $model['app_id'], ]); return true; } /** * 获取直推用户id */ public static function getFirstUserId($user_id) { $model = static::detail($user_id); return !empty($model['referee_id']) ? (self::isBonusUser($model['referee_id']) ? $model['referee_id'] : 0) : 0; } /** * 获取业绩奖用户id */ public static function getSecondUserId($user_id, $begin_num, $order) { /// 复购情况:根据复购次数逐级向上查找 $user = static::detail($user_id); // 如果没有上级,则自己获得业绩奖 if (empty($user['parent_id'])) { return 0; } // 根据复购次数确定向上查找的层级 // 复购1次:向上1级 // 复购2次:向上2级 // 复购n次:向上n级(最多不超过存在的层级) $targetUserId = $user_id; $levelsToGoUp = (new OrderModel)::getUserOrderCounti($user_id); // 逐级向上查找 for ($i = 0; $i < $levelsToGoUp; $i++) { $currentUser = static::detail($targetUserId); if (!empty($currentUser['parent_id'])) { $targetUserId = $currentUser['parent_id']; } else { return false; // 如果已经到顶级,停止向上查找 break; } } // 记录业绩分配 if ($targetUserId != $user_id) { // 上级获得业绩奖 self::addPerformance($targetUserId, $order, 1); } else { $targetUserId=0; // 自己获得业绩奖 self::addPerformance($user_id, $order, 1); } return $targetUserId; } /** * 获取 $order_count / 2 位置的用户 */ public static function getMulParentUserId($user_id, $multiple) { $parent_id = (new self)->where(compact('user_id'))->value('parent_id'); if (empty($parent_id)) { return $user_id; } if ($multiple <= 1) { return $parent_id; } $multiple--; return self::getMulParentUserId($parent_id, $multiple); } /** * 获取我的三叉树用户 */ public static function getTreeUser($user_id) { $model = new static; return $model->where('parent_id', '=', $user_id)->order(['order_num' => 'asc'])->select(); } /** * 获取用户直推人数 */ public static function getDirectNum($user_id) { return (new static())->where('referee_id', '=', $user_id)->count(); } /** * 排位是否失效 */ public static function isExpire($user_id) { $team = self::detail($user_id); if (!$team) { return false; } $setting = Setting::getItem('basic', $team['app_id']); return !!$team && $team['is_expire'] && $team['is_permanent'] == 0 && $setting['expire_day'] > 0; } /** * 排位是否失效 */ public static function getExpireTime($user_id) { $user = self::detail($user_id); if (!$user) { return 0; } $setting = Setting::getItem('basic', $user['app_id']); if ($user['tree_level'] <= 3 || $user['is_permanent']) { $remain_time = '永久'; } else { $time = $user['agent_time'] ? $user['agent_time'] : strtotime($user['create_time']); $remain_time = abs(intval((($time + 86400 * $setting['expire_day']) - time()) / 86400)); } return $remain_time; } /** * 更新队长直推人的最新时间 */ public static function updateAgentTime($user_id) { $user = self::detail($user_id); if ($user) { return $user->save([ 'agent_time' => time(), 'is_expire' => 0 // 取消过期 ]); } return true; } /** * 添加业绩轮询计数 */ private static function addPerformance($user_id, $order, $is_own) { return PerformanceModel::add([ 'user_id' => $order['user_id'], 'order_id' => $order['order_id'], 'performance_id' => $user_id, 'is_own' => $is_own, 'app_id' => $order['app_id'] ]); } /** * 解冻业绩分红 * $direct_num 直推人数 */ private static function backFreezeMoneySecond($user_id, $direct_num) { $model = static::detail($user_id); if($model['freeze_money_second'] <= 0) { return true; } //符合解冻全部业绩条件时 if (self::isBackFreezeAll($user_id)) { $money = $model['freeze_money_second']; } else { if ($direct_num > 3) { return true; } $money = $model['freeze_money_second'] >= 2000 ? 2000 : $model['freeze_money_second']; } return $model->save([ 'money' => $model['money'] + $money, 'freeze_money_second' => $model['freeze_money_second'] - $money, ]); } /** * 是否能全部解冻 * 条件:最开始直推的3人全部完成3个直推 * 2022.09新条件:直推的任意3人全部完成3个直推 */ private static function isBackFreezeAll($user_id) { $total = (new agentUserModel)->where('referee_id', '=', $user_id) ->where('first_num', '>=', 3) ->where('is_delete', '=', 0) ->count(); if ($total < 3) { return false; } return true; } /** * 提现打款成功:累积提现佣金 */ public static function totalMoney($user_id, $money) { $model = self::detail($user_id); return $model->save([ 'freeze_money' => $model['freeze_money'] - $money, 'total_money' => $model['total_money'] + $money, ]); } /** * 提现驳回:解冻队长资金 */ public static function backFreezeMoney($user_id, $money) { $model = self::detail($user_id); return $model->save([ 'money' => $model['money'] + $money, 'freeze_money' => $model['freeze_money'] - $money, ]); } /** * 获取补贴用户id */ public static function getSubsidyUserId($user_id) { $bonusUser = self::detail($user_id); if (!empty($bonusUser['referee_id'])){ return $bonusUser['referee_id']; } return 0; } }