123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- <?php
- // +----------------------------------------------------------------------
- // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
- // +----------------------------------------------------------------------
- // | Author: 萤火科技 <admin@yiovo.com>
- // +----------------------------------------------------------------------
- declare (strict_types=1);
- namespace app\common\service\commission;
- use app\api\model\ConfigPercent;
- use app\api\model\Order;
- use app\api\model\User;
- use app\api\model\user\CommissionsDetail;
- use app\common\library\helper;
- use app\common\model\GoodsSku;
- use app\common\model\ShopIdentity;
- use app\common\model\Shops;
- use app\common\model\store\Setting;
- use app\common\service\BaseService;
- use app\common\service\Message;
- use think\db\exception\DataNotFoundException;
- use think\db\exception\DbException;
- use think\db\exception\ModelNotFoundException;
- use think\facade\Db;
- use think\facade\Log;
- use think\facade\Queue;
- /**
- * 待结算佣金服务类
- * 1.待分佣记录是用队列写入,2.分佣结算是定时任务,30秒清算一次,3.每日奖励金是执行计划crontab,每天凌晨一次,4.每月奖励金结算是执行计划crontab在次月的20日凌晨结算
- * Class Complete
- * @package app\common\service\order
- */
- class RecordWaitCommission extends BaseService
- {
- /**
- * 获取门店参与分佣的人与角色
- * @param $shopId
- * @param $staffId
- * @return array
- * @throws DataNotFoundException
- * @throws DbException
- * @throws ModelNotFoundException
- */
- private function getShopUser($shopId,$staffId): ?array
- {
- $md = new ShopIdentity();
- $pers = $md->field('shop_id,role_id as role,fc_percent as percent')->where('shop_id',$shopId)->select();
- $pers = $pers?$pers->toArray():[];
- $shop = Shops::find($shopId);
- if(!$shop)return null;
- $roles = array_column($pers,'role');
- //获取新增身份的用户
- $cUsers = \app\common\model\User::getCommissionUsers($shopId,$roles);
- //加入店老板分佣比例
- $pers[] = ['shop_id'=>$shopId,'role'=>User::SHOP_BOSS,'percent'=>$shop->boss_percent];
- $pers[] = ['shop_id'=>$shopId,'role'=>User::SHOP_MG,'percent'=>$shop->manager_percent];
- //加入店员分佣比例
- $pers[] = ['shop_id'=>$shopId,'role'=>User::SHOP_SELLER,'percent'=>$shop->staff_percent];
- $pers = array_column($pers,null,'role');
- //加入店员
- $cUsers[] = ['user_id'=>$shop->boss_user_id,'role'=>User::SHOP_BOSS];
- if ($shop->manager_user_id){
- $cUsers[] = ['user_id'=>$shop->manager_user_id,'role'=>User::SHOP_MG];
- }
- $cUsers[] = ['user_id'=>$staffId,'role'=>User::SHOP_SELLER];
- return ['pers'=>$pers,'cUsers'=>$cUsers];
- }
- /**
- * Notes:计算商品预计分佣
- * Author: zhangs
- * DateTime: 2021/10/9 11:09
- * @param $goodsInfo
- * @param $userInfo
- * @return string
- */
- public function calcFcYjAmount($goodsInfo, $userInfo) {
- if (!$userInfo) {
- return '0.00';
- }
- $goodsSku = GoodsSku::where('goods_id', $goodsInfo['goods_id'])->order('goods_price', 'asc')->find();
- $percents = ConfigPercent::find(1);
- $ticketRate = $percents->ticket_rate;
- $platformRate = $goodsSku['platform_rate'] > 0 ? $goodsSku['platform_rate'] : $percents->platform_rate;
- $staff_percent = $percents->getAttr('staff_percent'); // 店员
- $manager_percent = $percents->getAttr('manager_percent'); // 店长
- $boss_percent = $percents->getAttr('boss_percent'); // 店老板
- $pool = ($goodsInfo['goods_price_min'] - $goodsSku['clearing_price'] - $goodsInfo['goods_price_min']*$ticketRate/100)*$platformRate/100;
- $money = '0.00';
- if ($userInfo->role == User::SHOP_SELLER) {
- // 推荐人是店员
- $money = helper::bcadd($pool * $staff_percent/100,0,2);
- } elseif ($userInfo->role == User::SHOP_MG) {
- // 推荐人是店长
- // $money = helper::bcadd($pool * $manager_percent/100,0,2);
- } elseif ($userInfo->role == User::SHOP_BOSS) {
- // 推荐人是店老板
- // $money = helper::bcadd($pool * $boss_percent/100,0,2);
- }
- return $money;
- }
- /**
- * 待结算店员分销佣金
- * @param $pool
- * @param $cUsers
- * @param $percents
- * @param $orderId
- * @param $shopId
- * @param $buyerId
- * @param $orderCreateTime
- * @return bool
- * @throws \Exception
- */
- private function handleWaitShopSellerCommission($pool,$cUsers,$percents,$orderId,$shopId,$buyerId,$orderCreateTime): bool
- {
- $data = [];
- foreach ($cUsers as $cUser){
- $percent = $percents[$cUser['role']]['percent'];
- $money = helper::bcadd($pool * $percent/100,0,4);
- $data[] = ['user_id'=>$cUser['user_id'],
- 'clearing_money'=>$money,
- 'order_id'=>$orderId,
- 'shop_id'=>$shopId,
- 'role'=>$cUser['role'],
- 'buyer_user_id'=>$buyerId,
- 'commission_percent'=>$percent,
- 'order_create_time'=>$orderCreateTime,
- 'order_sale_volume'=>$pool
- ];
- }
- if (count($data)){
- $model = new \app\common\model\user\CommissionsDetail();
- $model->saveAll($data);
- }
- return true;
- }
- /**
- * 订单支付回调成功时,将待分佣明细job加入队列执行
- * @param $orderId
- * @return bool
- */
- public function recordWaitCommission($orderId){
- $jobHandlerClassName = 'app\job\recordWaitCommissionsDetail';
- $jobQueueName = "orderWaitCommissionsQueue";
- //数组数据
- $orderData = [
- 'orderId' => $orderId,
- ];
- $isPushed = Queue::push($jobHandlerClassName, $orderData ,$jobQueueName);
- //$isPushed = Queue::later(5, $jobHandlerClassName, $orderData, $jobQueueName);
- if( $isPushed !== false ){
- return true;
- }else{
- log_record('加队列失败,orderId:'.$orderId);
- return false;
- }
- }
- //todo 1.下单时订单商品快照表需要记录分享者的id,
- //todo 2.需要在下单成功后变更用户的推荐人信息和门店信息
- /**
- * 待结算佣金计算,需要在支付回调完成时调用这个方法去记录待结算的佣金详情,在售后期结束后调用结算
- * @param $orderId
- * @return bool
- * @throws DataNotFoundException
- * @throws DbException
- * @throws ModelNotFoundException
- */
- public function waitGiveOutCommission(int $orderId){
- Log::error('Job wait orderId:'.$orderId);
- $order = Order::where(['order_id'=>$orderId,'commission_settlement_status'=>10])->find();
- if (empty($order)){
- return true;
- }
- $orderCreateTime = strtotime($order['create_time']);
- //如果订单退单退货,不执行分佣
- $buyerId = $order->user_id;
- $ratios = Setting::getItem('distributor_grade', 10001)['distributor'];
- $buyerUser = User::where('is_delete',0)->find($buyerId);
- Db::startTrans();
- try{
- //商品加入购物车时需要记录分享者id,商品推荐人
- $staffUserId = (int)$order['staff_user_id'];
- if ($staffUserId == $buyerId){
- throwError('自分享无分佣');
- }
- //pool = 实付金额 + 现金米卡抵扣金额 - 运费
- $poolTemp = helper::bcadd($order['pay_price'] , $order['rice_card_money'],4);
- $pool = helper::bcsub($poolTemp , $order['express_price'],4);
- if ($pool <= 0){
- throwError('金额有误');
- }
- Log::info('Job orderId:'.$orderId.',pool:'.$pool.',staffUserId:'.$staffUserId);
- //如果商品有推荐人
- $staffUser = null;
- $shopId = 0;
- if ($staffUserId > 0){
- $shopId = $order['staff_shop_id'];
- $staffUser = User::where('is_delete',0)
- ->field('user_id,role,shop_id,upper_user_id,seller_grade')
- ->find($staffUserId);
- if (!$staffUser){
- throwError('推广人用户不存在A');
- }
- }else{
- //店长、店老板、店内新增身份,店员自己购买都不分佣
- if (in_array($buyerUser->role,[2,3,4,5])){
- throwError('买家角色不支持分佣');
- }
- if (in_array($buyerUser->role,[1,99]) && isset($buyerUser->upper_user_id) && $buyerUser->upper_user_id > 0 ){
- $staffUser = User::where('is_delete',0)
- ->field('user_id,role,shop_id,upper_user_id,seller_grade')
- ->find($buyerUser->upper_user_id);
- if (!$staffUser){
- throwError('推广人用户不存在B');
- }
- if (!in_array($staffUser->role,[User::COMMISSION_USER,User::SHOP_SELLER])){
- throwError('推广人不支持分佣');
- }
- $shopId = $staffUser['shop_id'];
- }else{
- throwError('买家无上级A');
- }
- }
- if (empty($staffUser)){
- throwError('买家无上级B');
- }
- if ($staffUser->role == User::SHOP_SELLER){
- $flag = $this->getShopUser($shopId,$staffUser->user_id);
- if (!$flag){
- throwError('门店员工获取异常,shopId:'.$shopId);
- }
- $cUsers = $flag['cUsers'];
- $percents = $flag['pers'];
- $flag1 = $this->handleWaitShopSellerCommission($pool,$cUsers,$percents,$orderId,$shopId,$buyerId,$orderCreateTime);
- if (!$flag1){
- throwError('写门店分佣失败');
- }
- }
- if ($staffUser->role == User::COMMISSION_USER){
- $levelOneRate = $ratios[$staffUser->seller_grade-1]['first_commission']??0;
- $money = helper::bcadd($pool * $levelOneRate/100,0,4);
- //dd($order);
- if (CommissionsDetail::addNewCommission($staffUser->user_id,$orderId,$orderCreateTime,$money,0,$buyerId,User::COMMISSION_USER,1,$staffUser->seller_grade,$levelOneRate,$pool) === false){
- throwError('写分销员一级分佣失败');
- }
- //二级佣金
- if ($staffUser->upper_user_id >0){
- $secondUser = \app\common\model\User::where('is_delete',0)->find($staffUser->upper_user_id);
- if ($secondUser && $secondUser->role == User::COMMISSION_USER){
- $levelTwoRate = $ratios[$secondUser->seller_grade-1]['second_commission']??0;
- $money1 = helper::bcadd($pool * $levelTwoRate/100,0,4);
- if ( CommissionsDetail::addNewCommission($staffUser->upper_user_id,$orderId,$orderCreateTime,$money1,0,$buyerId,User::COMMISSION_USER,2,$secondUser->seller_grade,$levelTwoRate,$pool) === false){
- throwError('写分销员二级分佣失败');
- }
- }
- }
- }
- //订单佣金结算状态改为待结算
- $order->commission_settlement_status = 0;
- $order->save();
- Db::commit();
- }catch(\Exception $e){
- Db::rollback();
- $msg = 'Job orderId:'.$orderId.':'.$e->getMessage();
- Log::error($msg);
- Message::wxRobot($msg);
- return false;
- }
- return true;
- }
- }
|