298 lines
13 KiB
PHP
298 lines
13 KiB
PHP
<?php
|
||
/**
|
||
* SaaSMall商城系统 - 团队十年电商经验汇集巨献!
|
||
* =========================================================
|
||
* Copy right 2019-2029 成都SAAS云科技有限公司, 保留所有权利。
|
||
* ----------------------------------------------
|
||
* 官方网址: https://www.gobuysaas.com
|
||
* =========================================================
|
||
*/
|
||
|
||
namespace addon\team\model;
|
||
|
||
use addon\team\job\CommissionSettlementJob;
|
||
use app\model\BaseModel;
|
||
use app\model\NewBaseModel;
|
||
use think\Exception;
|
||
use think\facade\Db;
|
||
use think\facade\Queue;
|
||
|
||
class Commission extends BaseModel{
|
||
|
||
private $set = [];// 基本设置
|
||
private $currentLevelInfo = [];// 当前等级信息
|
||
private $prevLevelInfo = [];// 上一个领取奖励的等级信息
|
||
private $orderGoodsInfo = [];// 当前订单商品信息
|
||
private $equalLevelstratum = [];// 平级奖领取层级信息 二维数组 【键】等级id => 【值】已领取人数
|
||
private $accountList = [];// 流水信息列表
|
||
private $parentMemberInfo = [];// 当前上级信息
|
||
|
||
private $pipeMoney = null;//管理奖
|
||
|
||
/**
|
||
* Common: 佣金处理 - 开始处理
|
||
* Author: wu-hui
|
||
* Time: 2024/08/12 14:37
|
||
* @param $orderId
|
||
* @param $memberId
|
||
* @throws Exception
|
||
*/
|
||
public function commissionHandleInit($orderId, $memberId){
|
||
// 获取所有上级信息
|
||
$parentList = (new Member())->getAllParentTeamInfo($memberId);
|
||
if(count($parentList) <= 0) throw new Exception("不存在任何有效上级!");
|
||
// 获取店铺id及相关设置
|
||
$orderInfo = model('order')->getInfo([
|
||
['order_id', '=', $orderId]
|
||
],'site_id,order_from,order_from_name');
|
||
$this->set = (new Setting())->getConfig((int)$orderInfo['site_id']);
|
||
// 根据订单id 获取对应的订单商品列表
|
||
$orderGoodsList = model('order_goods')->getList([
|
||
['order_id', '=', $orderId]
|
||
],'site_id,order_goods_id,order_id,(real_goods_money + legumes_integral_money) as order_money');
|
||
|
||
// 获取所有可能用到的团队等级信息
|
||
$lvIds = array_filter(array_unique(array_column($parentList, 'level_id')));
|
||
$levelList = model('team_level')->getList([
|
||
['id' , 'in', $lvIds]
|
||
],'id,title,weight,commission_rate,commission_tier,same_level_rate,same_level_tier');
|
||
|
||
$levelList = array_column($levelList, null, 'id');
|
||
// 循环处理
|
||
foreach($orderGoodsList as $orderGoodsInfo){
|
||
$this->orderGoodsInfo = $orderGoodsInfo;// 初始化当前订单商品信息
|
||
$this->equalLevelstratum = [];//初始化 平级奖领取层级信息
|
||
$this->prevLevelInfo = [];//初始化 上一个领取奖励的等级信息
|
||
foreach($parentList as $parentKey => $parentInfo){
|
||
$this->parentMemberInfo = $parentInfo;
|
||
// 判断:如果当前用户没有等级信息 跳过
|
||
$currentLevelId = $parentInfo['level_id'] ?? 0;
|
||
if($currentLevelId <= 0) continue;
|
||
// 获取当前用户的团队等级信息
|
||
$this->currentLevelInfo = $levelList[$currentLevelId] ?? [];
|
||
if(empty($this->currentLevelInfo)) continue;// 不存在等级信息 跳过
|
||
// 处理相关奖励
|
||
$prevLevelInfo = $this->prevLevelInfo ?? [];
|
||
|
||
$this->teamRewards($prevLevelInfo);// 团队奖
|
||
$this->equalLevelReward($prevLevelInfo);// 平级奖
|
||
$this->teamManageReward($parentKey);// 管理奖
|
||
}
|
||
}
|
||
// 记录流水
|
||
if(count($this->accountList) > 0) {
|
||
model('team_account')->addList($this->accountList);
|
||
// 判断:当前订单是收银台订单 立即结算
|
||
if($orderInfo['order_from'] == 'cashier'){
|
||
Queue::push(CommissionSettlementJob::class,[
|
||
'order_id' => $orderId
|
||
]);
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Common: 佣金处理 - 团队奖励
|
||
* Author: wu-hui
|
||
* Time: 2024/08/12 14:26
|
||
* @param $prevLevelInfo
|
||
*/
|
||
private function teamRewards($prevLevelInfo){
|
||
// 判断:当前等级团队奖励是否已经发放
|
||
$commissionTier = $this->currentLevelInfo['commission_tier'] ?? 0;// 当前等级 团队奖励层级限制
|
||
$distanceLevel = ($this->parentMemberInfo['distance_level'] ?? 0) + 1;
|
||
$weight = $this->currentLevelInfo['weight'] ?? 0;// 当前等级权重
|
||
$prevLevelWeight = $prevLevelInfo['weight'] ?? 0;// 上一个等级权重
|
||
// 判断:(当前等级不限制层级 || 当前层级 小于等于 限制层级) && 当前用户等级权重 大于 上一个用户等级权重
|
||
if(($commissionTier == 0 || $commissionTier >= $distanceLevel) && $weight > $prevLevelWeight){
|
||
// 默认佣金抽成比例
|
||
$commissionRate = $rate = $this->currentLevelInfo['commission_rate'] ?? 0;
|
||
// 判断:如果开启级差 则奖励比例 = 当前等级比例 - 上一个等级的比例
|
||
if($this->set['is_differential'] == 1){
|
||
$prevCommissionRate = $prevLevelInfo['commission_rate'] ?? 0;
|
||
$commissionRate -= $prevCommissionRate;
|
||
}
|
||
// 流水信息生成
|
||
if($commissionRate > 0) $this->accountCreate((int)1, (float)$rate, (float)$commissionRate, (int)$distanceLevel);
|
||
// 刷新上一个奖励等级信息
|
||
$this->prevLevelInfo = $this->currentLevelInfo;
|
||
}
|
||
}
|
||
/**
|
||
* Common: 佣金处理 - 平级奖
|
||
* Author: wu-hui
|
||
* Time: 2024/08/12 14:26
|
||
* @param $prevLevelInfo
|
||
*/
|
||
private function equalLevelReward($prevLevelInfo){
|
||
$sameLevelTier = $this->currentLevelInfo['same_level_tier'] ?? 0;// 当前等级 平级奖层级限制
|
||
$currentLevelTier = $this->equalLevelstratum[$this->currentLevelInfo['id']] ?? 0;
|
||
$currentLevelTier += 1;
|
||
$weight = $this->currentLevelInfo['weight'] ?? 0;// 当前等级权重
|
||
$prevLevelWeight = $prevLevelInfo['weight'] ?? 0;// 上一个等级权重
|
||
// 判断:(当前等级不限制层级 || 当前层级小于等于限制层级) && 当前用户等级权重 等于 上一个用户等级权重
|
||
if(($sameLevelTier == 0 || $currentLevelTier <= $sameLevelTier) && $weight == $prevLevelWeight){
|
||
// 默认佣金抽成比例
|
||
$sameLevelRate = $this->currentLevelInfo['same_level_rate'] ?? 0;
|
||
// 流水信息生成
|
||
if($sameLevelRate > 0) $this->accountCreate((int)2, (float)$sameLevelRate, (float)$sameLevelRate, (int)$currentLevelTier);
|
||
// 刷新当前等级平级奖层级
|
||
$this->equalLevelstratum[$this->currentLevelInfo['id']] = $currentLevelTier;
|
||
// 刷新上一个奖励等级信息
|
||
$this->prevLevelInfo = $this->currentLevelInfo;
|
||
}
|
||
}
|
||
/**
|
||
* Common: 佣金处理 - 管理奖
|
||
* Author: ldy
|
||
* Time: 2024/08/20 11:59
|
||
* Interface teamManageReward
|
||
* @package addon\team\model
|
||
*/
|
||
private function teamManageReward(int $tier){
|
||
if($this->set['switch'] == 1 && $this->set['team_manage_rate'] > 0){
|
||
if(is_null($this->pipeMoney)){
|
||
$account_data = sprintf("%.2f",$this->orderGoodsInfo['order_money'] * $this->set['team_manage_rate'] / 100);
|
||
}else if($this->pipeMoney > 0){
|
||
$account_data = sprintf("%.2f",$this->pipeMoney * $this->set['team_manage_rate'] / 100);
|
||
}else{
|
||
return true;
|
||
}
|
||
if($account_data > 0){
|
||
$currentLevelTier = ++$tier;
|
||
$this->pipeMoney = $account_data;
|
||
$rate = sprintf("%.2f",100 / ($this->orderGoodsInfo['order_money'] / $account_data));
|
||
$this->accountCreate(3, (float)$rate, (float)$rate, (int)$currentLevelTier,$account_data);
|
||
}
|
||
|
||
}
|
||
}
|
||
/**
|
||
* Common: 佣金处理 - 流水信息生成
|
||
* Author: wu-hui
|
||
* Time: 2024/08/12 13:57
|
||
* @param int $type 佣金类型:1=团队奖励,2=平级奖
|
||
* @param float $rate 设置的佣金抽成比例
|
||
* @param float $useTate 实际使用的佣金抽成比例
|
||
* @param int $tier 奖励层级
|
||
* @param float $account_data 佣金全额(管理奖单独计算)
|
||
*/
|
||
private function accountCreate(int $type,float $rate,float $useTate,int $tier,float $account_data = 0.00){
|
||
$this->accountList[] = [
|
||
'account_type' => $type,
|
||
'account_data' => $account_data > 0 ? $account_data : sprintf("%.2f",$this->orderGoodsInfo['order_money'] * $useTate / 100),
|
||
'rate' => $rate,
|
||
'use_rate' => $useTate,
|
||
'site_id' => $this->orderGoodsInfo['site_id'],
|
||
'member_id' => $this->parentMemberInfo['member_id'],
|
||
'order_id' => $this->orderGoodsInfo['order_id'],
|
||
'order_goods_id' => $this->orderGoodsInfo['order_goods_id'],
|
||
'order_money' => $this->orderGoodsInfo['order_money'],
|
||
'tier' => $tier
|
||
];
|
||
}
|
||
/**
|
||
* Common: 订单团队佣金结算
|
||
* Author: wu-hui
|
||
* Time: 2024/08/12 16:39
|
||
* @param $orderId
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\DbException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
*/
|
||
public function commissionSettlement($orderId){
|
||
// 获取所有相关流水
|
||
$accountList = model('team_account')->getList([
|
||
['status', '=', 0],
|
||
['order_id', '=', $orderId]
|
||
],'id,account_data,member_id');
|
||
// 获取用户已经持有信息
|
||
$memberIds = array_column($accountList, 'member_id');
|
||
$userList = Db::name('member')
|
||
->field('commission_money,member_id')
|
||
->whereIn('member_id', $memberIds)
|
||
->select()
|
||
->toArray();
|
||
$userList = array_column($userList, null, 'member_id');
|
||
// 循环流水列表 结算信息
|
||
foreach($accountList as $singleInfo){
|
||
$userList[$singleInfo['member_id']]['commission_money'] += $singleInfo['account_data'];
|
||
}
|
||
// 修改
|
||
$newBaseModel = (new NewBaseModel(['table_name' => 'member', 'pk' => 'member_id']));
|
||
$userList = array_values($userList);
|
||
$newBaseModel->saveAll($userList);
|
||
// 已结算
|
||
model('team_account')->update(['status'=>1],[
|
||
['id', 'in', array_column($accountList, 'id')]
|
||
]);
|
||
}
|
||
|
||
|
||
/**
|
||
* Common: 获取佣金明细列表
|
||
* Author: wu-hui
|
||
* Time: 2024/08/12 14:57
|
||
* @param $params
|
||
* @param $siteId
|
||
* @return array
|
||
*/
|
||
public function getPageList($params, $siteId){
|
||
$page = $params['page'] ?? 1;
|
||
$pageLimit = $params['limit'] ?? PAGE_LIST_ROWS;
|
||
// 生成查询条件
|
||
$where = [
|
||
'a.site_id' => $siteId
|
||
];
|
||
if(isset($params['member_id']) && $params['member_id'] !== '') $where[] = ['a.member_id', '=', $params['member_id']];
|
||
if(isset($params['account_type']) && $params['account_type'] !== '') $where[] = ['a.account_type', '=', $params['account_type']];
|
||
if(isset($params['status']) && $params['status'] !== '') $where[] = ['a.status', '=', $params['status']];
|
||
$join = [
|
||
['member m', 'a.member_id = m.member_id', 'left'],
|
||
['order o', 'o.order_id = a.order_id', 'left'],
|
||
['order_goods og', 'og.order_goods_id = a.order_goods_id', 'left']
|
||
];
|
||
$field = 'a.*,m.nickname,m.username,m.headimg,o.order_no,og.sku_name';
|
||
$result = model('team_account')->pageList($where,$field,'a.id DESC',$page,$pageLimit,'a',$join);
|
||
|
||
return $this->success($result);
|
||
}
|
||
/**
|
||
* Common: 统计信息
|
||
* Author: wu-hui
|
||
* Time: 2024/08/13 9:26
|
||
* @param $memberId
|
||
* @return array
|
||
*/
|
||
public function statistics($memberId){
|
||
// 团队订单总数
|
||
$data['order_total'] = (float)model('team_account')->getCount([
|
||
['member_id', '=', $memberId]
|
||
],'order_id','a',[],'order_id');
|
||
// 团队奖收益
|
||
$data['team_award'] = (float)model('team_account')->getSum([
|
||
['account_type','=',1],
|
||
['status','in',[0,1]],
|
||
],'account_data');
|
||
// 平级奖收益
|
||
$data['same_level_award'] = (float)model('team_account')->getSum([
|
||
['account_type', '=', 2],
|
||
['status','in',[0,1]],
|
||
],'account_data');
|
||
// 团队人数
|
||
$siteId = model('member')->getValue([['member_id','=',$memberId]],'site_id');
|
||
$memberModel = new Member();
|
||
$data['team_people_num'] = (int)$memberModel->getPeopleNum($memberId, $siteId, 'team');
|
||
// 团队直推人数
|
||
$data['one_people_num'] = (int)$memberModel->getPeopleNum($memberId, $siteId);
|
||
// 总获得团队收益
|
||
$data['team_total_award'] = (float)sprintf("%.2f", $data['team_award'] + $data['same_level_award']);
|
||
|
||
return $data;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
}
|