From efe5cf83c02d9dcf43777aabaf444466a10be1b9 Mon Sep 17 00:00:00 2001 From: wuhui_zzw <1760308791@qq.com> Date: Thu, 28 Dec 2023 15:43:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=EF=BC=9A=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E6=8A=BD=E6=88=90=20-=20=E5=90=88=E4=BC=99=E4=BA=BA=E4=BD=A3?= =?UTF-8?q?=E9=87=91=E5=91=A8=E6=9C=9F=E7=BB=93=E7=AE=97(=E6=AF=8F?= =?UTF-8?q?=E5=91=A8=E6=9C=9F=E7=BB=93=E7=AE=97=E8=AE=B0=E5=BD=95=EF=BC=8C?= =?UTF-8?q?=E6=9C=AA=E5=AE=9E=E9=99=85=E7=BB=93=E7=AE=97=E5=88=B0=E8=B4=A6?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/command/platformCommission.php | 39 ++++++ app/common.php | 71 ++++++++++ .../PartnerSettlementCycleDao.php | 19 +++ .../PartnerSettlementDao.php | 19 +++ .../platformCommission/PartnerSettlement.php | 23 ++++ .../PartnerSettlementCycle.php | 23 ++++ .../PartnerSettlementCycleRepository.php | 124 ++++++++++++++++++ .../PartnerSettlementRepository.php | 17 +++ .../platformCommission/RecordRepository.php | 14 ++ .../WeightValueLogRepository.php | 24 +++- app/controller/api/Auth.php | 40 +----- config/console.php | 2 + route/api.php | 2 +- 13 files changed, 376 insertions(+), 41 deletions(-) create mode 100644 app/command/platformCommission.php create mode 100644 app/common/dao/store/platformCommission/PartnerSettlementCycleDao.php create mode 100644 app/common/dao/store/platformCommission/PartnerSettlementDao.php create mode 100644 app/common/model/store/platformCommission/PartnerSettlement.php create mode 100644 app/common/model/store/platformCommission/PartnerSettlementCycle.php create mode 100644 app/common/repositories/store/platformCommission/PartnerSettlementCycleRepository.php create mode 100644 app/common/repositories/store/platformCommission/PartnerSettlementRepository.php diff --git a/app/command/platformCommission.php b/app/command/platformCommission.php new file mode 100644 index 0000000..a411397 --- /dev/null +++ b/app/command/platformCommission.php @@ -0,0 +1,39 @@ +setName('platformCommission') + ->addArgument('run_type', Argument::OPTIONAL, "运行类型") + ->setDescription('平台抽成相关任务'); + } + + protected function execute(Input $input,Output $output){ + // 参数获取 + $runType = trim($input->getArgument('run_type')); + $runType = $runType ?: ''; + // 根据类型执行对应的操作 + switch($runType){ + // 合伙人佣金结算 + case 'commission_partner_settlement': + Log::info('合伙人佣金结算 - 开始处理'); + app()->make(PartnerSettlementCycleRepository::class)->settlementInit(); + break; + default: + Log::info('平台抽成计划任务 - 错误 - 不明确的执行内容'); + break; + } + // $output->writeln('接收参数:'. $runType); + // $output->writeln('success'); + } +} diff --git a/app/common.php b/app/common.php index d39c21e..f7781be 100644 --- a/app/common.php +++ b/app/common.php @@ -1247,3 +1247,74 @@ if (!function_exists('camelize')) { return ltrim(str_replace(" ", "", ucwords($string)), $separator ); } } +// 根据类型获取对应的时间戳 +if (!function_exists('getTimeStamp')) { + function getTimeStamp($type){ + $startTime = $endTime =0; + #year=本年,month=本月,today=今日,yesterday=昨日,last_week=上周,week=本周,quarter=季度,half_a_year=半年,last_month=上一个月 + switch($type){ + // 本年 + case "year": + $startTime = strtotime(date("Y-1-1"));// 本年1号0点 + $endTime = strtotime(date("Y-1-1"). " +1 year");// 下一年1号0点 + break; + // 本月 + case "month": + $startTime = strtotime(date("Y-m-1"));// 本月1号0点 + $endTime = strtotime(date("Y-m-1"). " +1 month ");// 下一个月1号0点 + break; + // 今日 + case "today": + $startTime = strtotime(date("Y-m-d"));// 今日0点 + $endTime = strtotime(date("Y-m-d"). " +1 day ");// 明日0点 + break; + // 昨日 + case "yesterday": + $startTime = strtotime(date("Y-m-d"). " -1 day ");// 昨日0点 + $endTime = strtotime(date("Y-m-d"));// 今日0点 + break; + // 上周 + case "last_week": + $week = date('w') == 0 ? 7 : date('w'); + $startTime = strtotime('today -' . ($week - 1) . 'day -1 week');// 上周一 0点 + $endTime = strtotime('today +' . (8 - $week) . 'day -1 week');// 本周一 0点 + break; + // 本周 + case "week": + $week = date('w') == 0 ? 7 : date('w'); + $startTime = strtotime('today -' . ($week - 1) . 'day');// 本周一 0点 + $endTime = strtotime('today +' . (8 - $week) . 'day');// 下周一 0点 + break; + // 季度 + case "quarter": + $currentMonth = date('n'); // 获取当前月份 + $currentQuarter = ceil($currentMonth / 3); // 计算当前是第几个季度 + $currentYear = date('Y'); // 获取当前年份 + // 本季度开始时间 + $startTime = strtotime(($currentQuarter - 1) * 3 . ' months', strtotime("$currentYear-01-01")); + // 下一个季度开始时间 + $endTime = strtotime(($currentQuarter * 3) . ' months', strtotime("$currentYear-01-01")); + break; + // 上半年/下半年 + case "half_a_year": + $currentMonth = date('n'); // 获取当前月份 + $currentYear = date('Y'); // 获取当前年份 + if($currentMonth <= 6){ + // 获取上半年时间 + $startTime = strtotime("$currentYear-01-01");// 本年1号 0点 + $endTime = strtotime("$currentYear-07-01");// 本年7月1号 0点 + }else{ + // 获取下半年时间 + $startTime = strtotime("$currentYear-07-01");// 本年7月1号 0点 + $endTime = strtotime("$currentYear-01-01 +1 years");// 明年1号 0点 + } + break; + // 上一个月 + case "last_month": + $startTime = strtotime(date("Y-m-1")." -1 month");// 上一个月1号0点 + $endTime = strtotime(date("Y-m-1"));// 本月1号0点 + break; + } + return [$startTime,$endTime]; + } +} diff --git a/app/common/dao/store/platformCommission/PartnerSettlementCycleDao.php b/app/common/dao/store/platformCommission/PartnerSettlementCycleDao.php new file mode 100644 index 0000000..d484b87 --- /dev/null +++ b/app/common/dao/store/platformCommission/PartnerSettlementCycleDao.php @@ -0,0 +1,19 @@ +dao = $dao; + } + /** + * Common: 合伙人结算 - 开始 + * Author: wu-hui + * Time: 2023/12/28 15:22 + */ + public function settlementInit(){ + $this->set = app()->make(RecordRepository::class)->getBaseConfig(); + Db::startTrans(); + try{ + // 获取周期时间 0=天;1=周;2=月 + if($this->set['commission_partner_cycle'] == 1) [$this->startTime,$this->endTime] = getTimeStamp('last_week');// 周 + else if($this->set['commission_partner_cycle'] == 2) [$this->startTime,$this->endTime] = getTimeStamp('last_month');// 月 + else [$this->startTime,$this->endTime] = getTimeStamp('yesterday');// 天 + // 判断:是否允许执行 + $this->settlementIsRun(); + // 佣金分红计算并且记录 + $this->settlementBonusHandle(); + + Db::commit(); + }catch(Exception $e){ + Db::rollback(); + Log::info('合伙人佣金结算 - 错误:'.$e->getMessage()); + } + } + /** + * Common: 合伙人结算 - 判断是否继续允许;获取分佣金额 + * Author: wu-hui + * Time: 2023/12/28 14:23 + * @throws Exception + */ + private function settlementIsRun(){ + $time = time(); + // 判断:是否开启 + if($this->set['is_open'] != 1) throw new Exception('未开启平台抽成'); + // 下一个周期结束时间 + $upCycleEndTime = PartnerSettlementCycle::max('end_time'); + if($this->set['commission_partner_cycle'] == 1) { + // 周 获取下一周开始时间 + $monday = strtotime('Monday this week', $upCycleEndTime); + $lastRunTime = strtotime(date("Y-m-d 00:00:00",$monday)." +1 week"); + } + else if($this->set['commission_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($upCycleEndTime > 0 && $time < $lastRunTime) { + $upCycleEndDate = date('Y-m-d H:i:s',$upCycleEndTime); + $nextCycleEndDate = date('Y-m-d H:i:s',$lastRunTime); + throw new Exception("执行时间错误(上一个周期结束时间{$upCycleEndDate},下一个周期结束时间{$nextCycleEndDate})"); + } + // 判断:分红总金额是否大于0 + $this->totalCommission = (float)app()->make(RecordRepository::class)->getTotalCommission($this->startTime,$this->endTime); + if($this->totalCommission <= 0) throw new Exception('分红总金额为0'); + } + /** + * Common: 合伙人结算 - 佣金计算并且记录 + * Author: wu-hui + * Time: 2023/12/28 15:22 + * @return bool + * @throws Exception + */ + private function settlementBonusHandle(){ + $userList = app()->make(WeightValueLogRepository::class)->getHoldList($this->endTime); + $totalWeightValue = (float)array_sum($userList);// 总权重值 + if($totalWeightValue <= 0) throw new Exception('不存在分红用户或截至当前周期结束时间总共的权重值为0'); + // 记录周期分红信息 + $cycleId = PartnerSettlementCycle::insertGetId([ + 'total_commission' => $this->totalCommission, + 'total_weight_value' => $totalWeightValue, + 'total_people' => count($userList), + 'start_time' => $this->startTime, + 'end_time' => $this->endTime, + ]); + // 循环处理所有用户 + $logInsertData = [];// 明细记录 + foreach($userList as $userId => $weightValue){ + // 添加贡献分享分红信息记录 这里必须进行100的偏移计算 + $radio = (float)sprintf("%.2f",($weightValue / $totalWeightValue) * 100);// 佣金比例 + $money = (float)sprintf("%.2f",($this->totalCommission * $radio) / 100);// 实际获得佣金 + if($money > 0){ + $logInsertData[] = [ + 'uid' => $userId, + 'cycle_id' => $cycleId, + 'money' => $money, + 'hold_contribution' => $totalWeightValue, + 'total_contribution' => $weightValue, + 'proportion' => $radio, + ]; + } + } + + PartnerSettlement::insertAll($logInsertData); + return true; + } + + +} diff --git a/app/common/repositories/store/platformCommission/PartnerSettlementRepository.php b/app/common/repositories/store/platformCommission/PartnerSettlementRepository.php new file mode 100644 index 0000000..df7b605 --- /dev/null +++ b/app/common/repositories/store/platformCommission/PartnerSettlementRepository.php @@ -0,0 +1,17 @@ +dao = $dao; + } + + +} diff --git a/app/common/repositories/store/platformCommission/RecordRepository.php b/app/common/repositories/store/platformCommission/RecordRepository.php index 558baec..8fc139f 100644 --- a/app/common/repositories/store/platformCommission/RecordRepository.php +++ b/app/common/repositories/store/platformCommission/RecordRepository.php @@ -100,6 +100,20 @@ class RecordRepository extends BaseRepository{ return compact('count','list'); } + /** + * Common: 获取指定时间内总合伙人佣金 + * Author: wu-hui + * Time: 2023/12/28 14:22 + * @param $startTime + * @param $endTime + * @return float + */ + public function getTotalCommission($startTime,$endTime):float{ + return (float)$this->dao->getSearch([]) + ->whereBetweenTime('create_time', $startTime, $endTime) + ->sum('commission_partner_money'); + } + diff --git a/app/common/repositories/store/platformCommission/WeightValueLogRepository.php b/app/common/repositories/store/platformCommission/WeightValueLogRepository.php index 22afe0d..f82b241 100644 --- a/app/common/repositories/store/platformCommission/WeightValueLogRepository.php +++ b/app/common/repositories/store/platformCommission/WeightValueLogRepository.php @@ -44,8 +44,30 @@ class WeightValueLogRepository extends BaseRepository{ return compact('count','list'); } + /** + * Common: 根据截止时间 获取用户权重值持有信息 + * Author: wu-hui + * Time: 2023/12/28 14:59 + * @param $endTime + * @return array + */ + public function getHoldList($endTime):array{ + $idList = $this->dao->getSearch([]) + ->field('max(id) as max_id,CONCAT(uid,"_", brokerage_level) as group_key') + ->where('create_time','<=',date("Y-m-d H:i:s",$endTime)) + ->group('group_key') + ->select() + ->toArray(); + $ids = array_column($idList,'max_id'); + $list = $this->dao->getSearch([]) + ->field('uid,sum(change_after) as change_after') + ->whereIn('id',$ids) + ->group('uid') + ->select() + ->toArray(); - + return array_column($list,'change_after','uid'); + } diff --git a/app/controller/api/Auth.php b/app/controller/api/Auth.php index 3d7a672..4dd5335 100644 --- a/app/controller/api/Auth.php +++ b/app/controller/api/Auth.php @@ -6,31 +6,19 @@ namespace app\controller\api; -use app\common\model\store\platformCommission\WeightValue; -use app\common\model\store\platformCommission\WeightValueLog; -use app\common\model\system\merchant\Merchant; -use app\common\repositories\store\order\StoreGroupOrderRepository; + use app\common\repositories\store\order\StoreOrderRepository; use app\common\repositories\store\order\StoreRefundOrderRepository; -use app\common\repositories\store\platformCommission\RecordRepository; -use app\common\repositories\store\platformCommission\WeightValueRepository; -use app\common\repositories\system\merchant\MerchantRepository; -use app\common\repositories\system\notice\SystemNoticeConfigRepository; -use app\common\repositories\user\UserBillRepository; -use app\common\repositories\user\UserBrokerageRepository; use app\common\repositories\user\UserRepository; use app\common\repositories\user\UserSignRepository; use app\common\repositories\wechat\RoutineQrcodeRepository; use app\common\repositories\wechat\WechatUserRepository; -use app\jobs\store\platformCommission\GiveWeightValueJob; use app\validate\api\ChangePasswordValidate; use app\validate\api\UserAuthValidate; use crmeb\basic\BaseController; -use crmeb\jobs\UserBrokerageLevelJob; use crmeb\services\MiniProgramService; use crmeb\services\SmsService; use crmeb\services\WechatService; -use crmeb\services\WechatTemplateMessageService; use Exception; use Firebase\JWT\JWT; use Gregwar\Captcha\CaptchaBuilder; @@ -42,9 +30,6 @@ use think\db\exception\DbException; use think\db\exception\ModelNotFoundException; use think\exception\ValidateException; use think\facade\Cache; -use think\facade\Log; -use think\facade\Queue; -use crmeb\jobs\SendSmsJob; /** * Class Auth @@ -54,29 +39,6 @@ use crmeb\jobs\SendSmsJob; */ class Auth extends BaseController { - public function test(){ - - // 分销商升级模拟 - // $user = app()->make(UserRepository::class)->get(327706); - // $res = app()->make(UserBrokerageRepository::class)->incV2($user, [ - // 'type' => 'pay_num', - // 'inc' => 0 - // ]); - // debug(['升级结果'=>$res]); - - // $userList = app()->make(WeightValueRepository::class)->getUserHoldList(327706); - // debug(['用户列表'=>$userList]); - // 订单支付成功 触发购买商品赠送上级权重值 - // Queue::push(GiveWeightValueJob::class,[ - // 'uid' => 327706, - // 'group_order_id' => 133 - // ]); - - - - - - } /** * @param UserRepository $repository diff --git a/config/console.php b/config/console.php index d2ae6a8..52ff723 100644 --- a/config/console.php +++ b/config/console.php @@ -29,5 +29,7 @@ return [ 'clear:cache' => 'app\command\clearCache', //更新热卖榜单 'change:hotTop' => 'app\command\changeHotTop', + // 平台抽成相关任务 + 'platformCommission' => 'app\command\platformCommission', ], ]; diff --git a/route/api.php b/route/api.php index c248891..50fb00a 100644 --- a/route/api.php +++ b/route/api.php @@ -12,7 +12,7 @@ use app\common\middleware\RequestLockMiddleware; use think\facade\Route; Route::group('api/', function () { - Route::any('test', 'api.Auth/test'); + Route::any('test', 'api.Test/test'); //强制登录 Route::group(function () { Route::group('v2', function () {