<?php
|
|
namespace app\common\model\plus\bonus;
|
|
use app\common\model\BaseModel;
|
use app\common\model\plus\bonus\Order as OrderModel;
|
use app\common\model\plus\bonus\Referee as RefereeModel;
|
use app\common\model\user\Grade as GradeModel;
|
use app\common\model\user\User as UserModel;
|
//use app\common\model\plus\bonus\Order as OrderModel;
|
use app\common\model\plus\bonus\Performance as PerformanceModel;
|
use app\common\model\plus\agent\Referee as agentRefereeModel;
|
use app\common\model\plus\agent\User as agentUserModel;
|
|
/**
|
* 队长用户模型
|
*/
|
class User extends BaseModel
|
{
|
protected $name = 'bonus_user';
|
protected $pk = 'user_id';
|
|
/**
|
* 关联会员等级表
|
*/
|
public function grade()
|
{
|
return $this->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;
|
}
|
|
}
|