jh-admin/addon/team/model/Commission.php

298 lines
13 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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;
}
}