286 lines
12 KiB
PHP
286 lines
12 KiB
PHP
<?php
|
||
/**
|
||
* SaaSMall商城系统 - 团队十年电商经验汇集巨献!
|
||
* =========================================================
|
||
* Copy right 2019-2029 成都SAAS云科技有限公司, 保留所有权利。
|
||
* ----------------------------------------------
|
||
* 官方网址: https://www.gobuysaas.com
|
||
* =========================================================
|
||
*/
|
||
|
||
namespace addon\commission\model;
|
||
|
||
|
||
use addon\commission\job\PartnerSettlementJob;
|
||
use app\model\BaseModel;
|
||
use think\Exception;
|
||
use think\facade\Db;
|
||
use think\facade\Queue;
|
||
|
||
/**
|
||
* Common: 合伙人用户相关
|
||
* Author: wu-hui
|
||
* Time: 2024/05/08 14:05
|
||
* Class Partner
|
||
* @package addon\commission\model
|
||
*/
|
||
class Partner extends BaseModel{
|
||
/**
|
||
* Common: 获取合伙人佣金周期记录
|
||
* Author: wu-hui
|
||
* Time: 2024/05/09 10:50
|
||
* @param $page
|
||
* @param $params
|
||
* @param $siteId
|
||
* @return array
|
||
*/
|
||
public function getPageList($page, $params, $siteId){
|
||
// 判断:不是总平台 仅显示当前店铺相关抽成记录
|
||
if($siteId != $this->adminSiteId) $params['site_id'] = $siteId;
|
||
// 生成查询条件
|
||
$where = [];
|
||
if(isset($params['site_id']) && $params['site_id'] !== '') $where[] = ['a.site_id','=',$params['site_id']];
|
||
// 关联查询
|
||
$join = [
|
||
[ 'site s', 's.site_id = a.site_id', 'left' ]
|
||
];
|
||
$field = [
|
||
'a.*',
|
||
's.site_name',
|
||
's.contacts_name',
|
||
];
|
||
$result = model('commission_partner_cycle')->pageList($where, $field,'a.id DESC',$page,PAGE_LIST_ROWS,'a',$join);
|
||
$result['is_admin'] = $siteId == $this->adminSiteId;
|
||
|
||
return $this->success($result);
|
||
}
|
||
/**
|
||
* Common: 获取合伙人佣金分红记录
|
||
* Author: wu-hui
|
||
* Time: 2024/05/09 10:53
|
||
* @param $page
|
||
* @param $params
|
||
* @return array
|
||
*/
|
||
public function getLogPageList($page, $params){
|
||
// 生成查询条件
|
||
$where = [];
|
||
if(isset($params['member_id']) && $params['member_id'] !== '') $where[] = ['a.member_id','=',$params['member_id']];
|
||
if(isset($params['site_id']) && $params['site_id'] !== '') $where[] = ['a.site_id','=',$params['site_id']];
|
||
if(isset($params['cycle_id']) && $params['cycle_id'] !== '') $where[] = ['a.cycle_id','=',$params['cycle_id']];
|
||
// 关联查询
|
||
$join = [
|
||
[ 'member m', 'm.member_id = a.member_id', 'left' ],
|
||
];
|
||
$field = [
|
||
'a.*',
|
||
'm.nickname',
|
||
'm.username',
|
||
'm.headimg',
|
||
];
|
||
$result = model('commission_partner')->pageList($where,$field,'id DESC',$page,PAGE_LIST_ROWS, 'a', $join);
|
||
|
||
return $this->success($result);
|
||
}
|
||
|
||
|
||
/**
|
||
* Common: 合伙人佣金结算 - 开始
|
||
* Author: wu-hui
|
||
* Time: 2024/05/08 16:23
|
||
*/
|
||
public function settlementInit(){
|
||
Db::startTrans();
|
||
try{
|
||
// 获取总平台配置信息
|
||
$config = (new Setting())->getConfig();
|
||
// 获取周期时间 0=天;1=周;2=月
|
||
if($config['partner_cycle'] == 1) [$startTime,$endTime] = getTimeStamp('last_week');// 周
|
||
else if($config['partner_cycle'] == 2) [$startTime,$endTime] = getTimeStamp('last_month');// 月
|
||
else [$startTime,$endTime] = getTimeStamp('yesterday');// 天
|
||
|
||
|
||
// [$startTime,$endTime] = getTimeStamp('today');// TODO:调试使用...
|
||
|
||
|
||
// 获取全部子平台 然后循环处理
|
||
$insertData = [];// 明细记录
|
||
$cycleIds = [];// 周期ids
|
||
$siteList = model('site')->getList([],'site_id,site_name');
|
||
foreach($siteList as $siteInfo){
|
||
// 获取子平台配置信息
|
||
$subConfig = (new Setting())->getConfig((int)$siteInfo['site_id']);
|
||
// 判断:是否允许执行
|
||
$isRunResult = $this->settlementIsRun($subConfig, $siteInfo);
|
||
if((int)$isRunResult['code'] != 0){
|
||
// trace([
|
||
// 'msg' => $isRunResult['message'],
|
||
// 'site_id' => (int)$siteInfo['site_id'],
|
||
// ], '子平台循环处理 - 是否允许执行 - 跳出');
|
||
continue;
|
||
}
|
||
// 获取分红金额信息 并且判断是否大于0
|
||
$moneyInfo = $this->getTotalMoney($siteInfo, $startTime, $endTime);
|
||
if((float)$moneyInfo['reality_money'] <= 0){
|
||
// trace([
|
||
// 'site_id' => (int)$siteInfo['site_id'],
|
||
// 'money_info' => $moneyInfo
|
||
// ], '子平台循环处理 - 实际分红金额为0');
|
||
model('commission_record')->update(['partner_status' =>1],[
|
||
[ 'create_time', 'between', [ date("Y-m-d H:i:s",$startTime), date("Y-m-d H:i:s",$endTime) ] ],
|
||
['partner_status','=', 0],
|
||
['site_id','=', $siteInfo['site_id']],
|
||
]);
|
||
continue;
|
||
}
|
||
// 获取用户权重值信息
|
||
$userList = $this->getHoldList($endTime, $siteInfo);
|
||
$totalWeightValue = (float)array_sum($userList);// 总权重值
|
||
if($totalWeightValue <= 0) {
|
||
trace([
|
||
'site_id' => (int)$siteInfo['site_id'],
|
||
'totalWeightValue' => $totalWeightValue
|
||
], '子平台循环处理 - 总权重值为0');
|
||
model('commission_record')->update(['partner_status' =>2],[
|
||
[ 'create_time', 'between', [ date("Y-m-d H:i:s",$startTime), date("Y-m-d H:i:s",$endTime) ] ],
|
||
['partner_status','=', 0],
|
||
['site_id','=', $siteInfo['site_id']],
|
||
]);
|
||
continue;
|
||
}
|
||
// 记录周期分红信息
|
||
$cycleId = model('commission_partner_cycle')->add([
|
||
'site_id' => (int)$siteInfo['site_id'],
|
||
'total_commission' => $moneyInfo['total_money'],
|
||
'refund_money' => $moneyInfo['refund_money'],
|
||
'reality_money' => $moneyInfo['reality_money'],
|
||
'total_weight_value' => $totalWeightValue,
|
||
'total_people' => count($userList),
|
||
'start_time' => $startTime,
|
||
'end_time' => $endTime,
|
||
]);
|
||
$cycleIds[] = $cycleId;
|
||
// 循环处理所有用户
|
||
foreach($userList as $memberId => $weightValue){
|
||
// 添加贡献分享分红信息记录 这里必须进行100的偏移计算
|
||
$radio = (float)sprintf("%.2f",($weightValue / $totalWeightValue) * 100);// 佣金比例
|
||
$money = (float)sprintf("%.2f",($moneyInfo['reality_money'] * $radio) / 100);// 实际获得佣金
|
||
if($money > 0){
|
||
$insertData[] = [
|
||
'site_id' => (int)$siteInfo['site_id'],
|
||
'member_id' => $memberId,
|
||
'cycle_id' => $cycleId,
|
||
'money' => $money,
|
||
'hold_contribution' => $totalWeightValue,
|
||
'total_contribution' => $weightValue,
|
||
'proportion' => $radio,
|
||
];
|
||
}
|
||
}
|
||
model('commission_record')->update(['partner_status' =>1],[
|
||
['create_time', 'between', [ date("Y-m-d H:i:s",$startTime), date("Y-m-d H:i:s",$endTime) ] ],
|
||
['partner_status','=', 0],
|
||
['site_id','=', $siteInfo['site_id']],
|
||
]);
|
||
}
|
||
// 记录分红信息 并且开始结算
|
||
if(count($insertData) > 0){
|
||
model('commission_partner')->addList($insertData);
|
||
// 合伙人佣金结算
|
||
Queue::push(PartnerSettlementJob::class,[
|
||
'cycle_ids' => $cycleIds
|
||
]);
|
||
}
|
||
|
||
Db::commit();
|
||
}catch(Exception $e){
|
||
Db::rollback();
|
||
|
||
trace($e->getMessage(), '合伙人佣金结算 - 错误');
|
||
}
|
||
}
|
||
/**
|
||
* Common: 合伙人佣金结算 - 判断是否继续允许;获取分佣金额
|
||
* Author: wu-hui
|
||
* Time: 2024/05/08 14:56
|
||
* @param $subConfig
|
||
* @param $siteInfo
|
||
* @return array|void
|
||
*/
|
||
private function settlementIsRun($subConfig, $siteInfo){
|
||
// 判断:是否开启
|
||
if($subConfig['switch'] != 1) return $this->error('','未开启平台抽成');
|
||
// 下一个周期结束时间获取
|
||
$upCycleEndTime = model('commission_partner_cycle')->getMax(['site_id'=>$siteInfo['site_id']], 'end_time');
|
||
if($subConfig['partner_cycle'] == 1) {
|
||
// 周 获取下一周开始时间
|
||
$monday = strtotime('Monday this week', $upCycleEndTime);
|
||
$lastRunTime = strtotime(date("Y-m-d 00:00:00",$monday)." +1 week");
|
||
}
|
||
else if($subConfig['partner_cycle'] == 2) {
|
||
// 月 获取下一月开始时间
|
||
$lastRunTime = strtotime(date("Y-m-1 00:00:00",$upCycleEndTime)." +1 month");
|
||
}
|
||
else{
|
||
// 天 获取下一天开始时间
|
||
$lastRunTime = strtotime(date("Y-m-d 00:00:00",$upCycleEndTime)." +1 day");
|
||
}
|
||
// 判断:时间上是否允许继续执行(上一个周期结束时间存在 & 当前时间小于下一个周期结束时间 禁止继续执行)
|
||
if((int)$upCycleEndTime > 0 && time() < $lastRunTime) {
|
||
$msg = "执行时间错误(上一个周期结束时间".date('Y-m-d H:i:s',$upCycleEndTime).",下一个周期结束时间".date('Y-m-d H:i:s',$lastRunTime).")";
|
||
return $this->error('',$msg);
|
||
}
|
||
|
||
return $this->success('允许执行');
|
||
}
|
||
/**
|
||
* Common: 合伙人佣金结算 - 获取指定平台时间段内的总佣金信息
|
||
* Author: wu-hui
|
||
* Time: 2024/05/08 15:47
|
||
* @param $siteInfo
|
||
* @param $startTime
|
||
* @param $endTime
|
||
* @return array
|
||
*/
|
||
public function getTotalMoney($siteInfo, $startTime, $endTime){
|
||
// 总佣金
|
||
$moneyInfo['total_money'] = (float)model('commission_record')->getSum([
|
||
[ 'create_time', 'between', [ date("Y-m-d H:i:s",$startTime), date("Y-m-d H:i:s",$endTime) ] ],
|
||
['partner_status','=', 0],
|
||
['site_id','=', $siteInfo['site_id']],
|
||
], 'partner_money');
|
||
// 获取退款金额
|
||
$refundMoneyInfo = model('commission_record')->getInfo([
|
||
[ 'create_time', 'between', [ date("Y-m-d H:i:s",$startTime), date("Y-m-d H:i:s",$endTime) ] ],
|
||
['partner_status','=', 0],
|
||
['site_id','=', $siteInfo['site_id']],
|
||
],'sum((partner_money * refund_ratio / 100)) as refund_money');
|
||
$moneyInfo['refund_money'] = sprintf("%.2f",$refundMoneyInfo['refund_money'] ?? 0);
|
||
// 实际金额
|
||
$moneyInfo['reality_money'] = (float)sprintf("%.3f",(float)$moneyInfo['total_money'] - (float)$moneyInfo['refund_money']);
|
||
|
||
return $moneyInfo;
|
||
}
|
||
/**
|
||
* Common: 合伙人佣金结算 - 获取截止结束时用户持有权重值
|
||
* Author: wu-hui
|
||
* Time: 2024/05/08 16:08
|
||
* @param $endTime
|
||
* @param $siteInfo
|
||
* @return array
|
||
*/
|
||
private function getHoldList($endTime, $siteInfo){
|
||
$idList = model('commission_weight_value_log')->getList([
|
||
[ 'create_time', '<=', date("Y-m-d H:i:s",$endTime)],
|
||
['site_id','=', $siteInfo['site_id']],
|
||
],'max(id) as max_id,CONCAT(member_id,"_", level_id) as group_key','','a',[],'group_key');
|
||
$ids = array_column($idList,'max_id');
|
||
$list = model('commission_weight_value_log')->getList([
|
||
['id', 'in', $ids],
|
||
],'member_id,sum(change_after) as change_after','','a',[],'member_id');
|
||
|
||
return array_column($list,'change_after','member_id');
|
||
}
|
||
|
||
|
||
} |