// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Models\AccountCountModel; use App\Models\AccountLogModel; use App\Models\FinanceModel; use App\Models\MemberModel; use App\Services\BaseService; use App\Services\ConfigService; use App\Services\RedisService; use Illuminate\Support\Facades\DB; /** * 平台账户(财务)-服务类 * @author laravel开发员 * @since 2020/11/12 * Class ActionLogService * @package App\Services\Common */ class FinanceService extends BaseService { protected static $instance=null; /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 * FinanceService constructor. */ public function __construct() { $this->model = new FinanceModel(); } /** * 静态入口 * @return static|null */ public static function make() { if (!self::$instance) { self::$instance = (new static()); } return self::$instance; } /** * @param $params * @param int $pageSize * @return array */ public function getDataList($params, $pageSize = 15) { $where = ['a.mark' => 1]; $status = isset($params['status'])? $params['status'] : 0; $type = isset($params['type'])? $params['type'] : 0; if($status>0){ $where['a.status'] = $status; } if($type>0){ $where['a.type'] = $type; } $list = $this->model->from('finance as a') ->where($where) ->where(function ($query) use($params){ // 日期 $date = isset($params['date']) ? $params['date'] : []; $start = isset($date[0])? $date[0] : ''; $end = isset($date[1])? $date[1] : ''; $end = $start>=$end? '' : $end; if ($start) { $query->where('a.create_time','>=', strtotime($start)); } if($end){ $query->where('a.create_time','<', strtotime($end)); } }) ->select(['a.*']) ->orderBy('a.create_time','desc') ->paginate($pageSize > 0 ? $pageSize : 9999999); $list = $list? $list->toArray() :[]; if($list){ foreach($list['data'] as &$item){ $item['create_time'] = $item['create_time']? datetime($item['create_time'],'Y-m-d H.i.s') : ''; } } return [ 'pageSize'=> $pageSize, 'total'=>isset($list['total'])? $list['total'] : 0, 'list'=> isset($list['data'])? $list['data'] : [] ]; } /** * 平台结算 * @param $money * @param int $changeType 交易类型:1-进账,2-出账 * @param int $type 类型:1-消费,2-佣金,3-充值提现转账,4-退款,99-其他 * @param int $coinType 币种类型: 1-USDT,2-星豆 * @return mixed */ public function saveLog($userId, $money, $changeType = 1, $type=1, $coinType = 1) { $date = date('Y-m-d'); $info = $this->model->where(['user_id'=> $userId,'date'=> $date,'type'=> $type,'mark'=>1])->first(); if(!$info){ $data = ['user_id'=>$userId,'date'=> $date,'type'=>$type,'create_time'=>time(),'update_time'=> time(),'status'=>1]; if($changeType==1){ $data['income'] = $money; }else{ $data['expend'] = $money; } return $this->model->insertGetId($data); }else{ if($changeType == 1){ $info->income += $money; }else{ $info->expend += $money; } return $info->save(); } } /** * 升级收益结算 * @param $userId 升级用户ID * @param $userInfo 升级用户信息:parents-上级,points-上级节点,parent_id-推荐人,member_level-升级用户等级 * @param $usdt 升级消费的USDT * @param $orderNo 升级记录单号 * @param string $remark 升级项目备注说明 * @return bool */ public function settleBonus($userId, $userInfo, $usdt, $orderNo, $remark='') { $parents = isset($userInfo['parents'])? $userInfo['parents'] : ''; // 上级 $points = isset($userInfo['points'])? $userInfo['points'] : ''; // 挂靠节点 $parentId = isset($userInfo['parent_id'])? $userInfo['parent_id'] : 0; $userLevel = isset($userInfo['member_level'])? $userInfo['member_level'] : 0; // 用户等级 RedisService::set("caches:bonus:temp_{$userId}_{$orderNo}", ['info'=> $userInfo,'usdt'=> $usdt,'remark'=> $remark], 6 * 3600); if($userLevel<=0){ $this->error = 2607; return false; } DB::beginTransaction(); // TODO 直推奖励结算 if($usdt>0 && $parentId>0){ $parentInfo = MemberModel::where(['id'=> $parentId,'mark'=>1]) ->select(['id','usdt','balance','wait_score']) ->first(); $rate1 = ConfigService::make()->getConfigByCode('award_push_rate',0); $rate1 = $rate1>0 && $rate1 <100? $rate1 : 0; $bonusUsdt1 = moneyFormat($usdt * $rate1/100, 4); if($parentInfo && $bonusUsdt1>0){ // 账户进账 $updateData = [ 'usdt'=> DB::raw("usdt + {$bonusUsdt1}"), 'upgrade_profit_total'=>DB::raw("upgrade_profit_total + {$bonusUsdt1}"), // 升级累计收益 'update_time'=>time() ]; if(!MemberModel::where(['id'=> $parentId,'mark'=>1])->update($updateData)){ DB::rollBack(); $this->error = 2601; return false; } // 收益明细 $log = [ 'user_id' => $parentId, 'source_id' => $userId, 'source_order_no' => $orderNo, 'type' => 12, 'coin_type' => 1, 'user_type'=> 1, 'money' => $bonusUsdt1, 'actual_money' => $bonusUsdt1, 'balance' => isset($parentInfo['usdt'])? $parentInfo['usdt'] : 0, 'create_time' => time(), 'update_time' => time(), 'remark' => $remark, 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2602; return false; } // TODO 平台流水(拨出对应比例USDT) FinanceService::make()->saveLog(0, $bonusUsdt1, 2); } } // TODO 点对点奖励收益结算 (会员升级数必须小于等于节点会员层数,即按同层给奖励) $points = $points? explode(',', $points) : []; $points = array_filter($points); $pointId = isset($points[$userLevel-1])? $points[$userLevel-1] : 0; if($points && count($points) >= $userLevel && $pointId>0){ // TODO 当前会员升级为N级,且N层上级节点会员等级>=升级会员等级时奖励点对点奖励(否则等级烧伤) $pointInfo = MemberModel::where(['id'=> $pointId,'mark'=>1]) ->select(['id','usdt','balance','member_level','wait_score']) ->first(); $pointLevel = isset($pointInfo['member_level'])? $pointInfo['member_level'] : 0; $rate2 = ConfigService::make()->getConfigByCode('award_node_rate',0); $rate2 = $rate2>0 && $rate2 <100? $rate2 : 0; $bonusUsdt2 = moneyFormat($usdt * $rate2/100, 4); if($pointInfo && $bonusUsdt2>0){ if($pointLevel>= $userLevel){ // 账户进账 $updateData = [ 'usdt'=> DB::raw("usdt + {$bonusUsdt2}"), 'upgrade_profit_total'=>DB::raw("upgrade_profit_total + {$bonusUsdt2}"), // 升级累计收益 'update_time'=>time() ]; if(!MemberModel::where(['id'=> $pointId,'mark'=>1])->update($updateData)){ DB::rollBack(); $this->error = 2603; return false; } // 收益明细 $log = [ 'user_id' => $parentId, 'source_id' => $userId, 'source_order_no' => $orderNo, 'type' => 14, 'coin_type' => 1, 'user_type'=> 1, 'money' => $bonusUsdt2, 'actual_money' => $bonusUsdt2, 'balance' => isset($pointInfo['usdt'])? $pointInfo['usdt'] : 0, 'create_time' => time(), 'update_time' => time(), 'remark' => $remark, 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2604; return false; } // TODO 平台流水(拨出对应比例USDT) FinanceService::make()->saveLog(0, $bonusUsdt2, 2); } // 烧伤明细处理(不进账) else{ $log = [ 'user_id' => $parentId, 'source_id' => $userId, 'source_order_no' => $orderNo, 'type' => 97, 'coin_type' => 1, 'user_type'=> 1, 'money' => $bonusUsdt2, 'actual_money' => $bonusUsdt2, 'balance' => isset($pointInfo['usdt'])? $pointInfo['usdt'] : 0, 'create_time' => time(), 'update_time' => time(), 'remark' => $remark, 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2604; return false; } } } } // TODO 管理奖结算(往上找最近的等级为5的倍数且等级大于升级用户的顺位用户,奖励管理奖) $parents = $parents? explode(',', $parents) : []; $parents = array_filter($parents); if($parents){ $awardIndex = -1; $logs = []; // 明细和烧伤明细 foreach ($parents as $k => $pid){ $parentInfo = MemberModel::where(['id'=> $parentId,'mark'=>1]) ->select(['id','usdt','balance','member_level','wait_score']) ->first(); $parentLevel = isset($parentInfo['member_level'])? $parentInfo['member_level'] : 0; $rate3 = ConfigService::make()->getConfigByCode('award_manage_rate',0); $rate3 = $rate3>0 && $rate3 <100? $rate3 : 0; $bonusUsdt3 = moneyFormat($usdt * $rate3/100, 4); if($parentLevel>= $userLevel && ($parentLevel%5==0)){ $awardIndex = $k; if($bonusUsdt3>0){ // 账户进账 $updateData = [ 'usdt'=> DB::raw("usdt + {$bonusUsdt3}"), 'upgrade_profit_total'=>DB::raw("upgrade_profit_total + {$bonusUsdt3}"), // 升级累计收益 'update_time'=>time() ]; if(!MemberModel::where(['id'=> $pid,'mark'=>1])->update($updateData)){ DB::rollBack(); $this->error = 2605; return false; } // 收益明细 $logs[] = [ 'user_id' => $pid, 'source_id' => $userId, 'source_order_no' => $orderNo, 'type' => 13, 'coin_type' => 1, 'user_type'=> 1, 'money' => $bonusUsdt3, 'actual_money' => $bonusUsdt3, 'balance' => isset($parentInfo['usdt'])? $parentInfo['usdt'] : 0, 'create_time' => time(), 'update_time' => time(), 'remark' => $remark, 'status' => 1, 'mark' => 1, ]; } } // (已经找到) 剩下的管理奖烧伤 else if($awardIndex>=0){ // 管理烧伤明细 $logs[] = [ 'user_id' => $pid, 'source_id' => $userId, 'source_order_no' => $orderNo, 'type' => 98, 'coin_type' => 1, 'user_type'=> 1, 'money' => $bonusUsdt3, 'actual_money' => $bonusUsdt3, 'balance' => isset($parentInfo['usdt'])? $parentInfo['usdt'] : 0, 'create_time' => time(), 'update_time' => time(), 'remark' => $remark, 'status' => 1, 'mark' => 1, ]; } // 还没找到,即等级条件不满足,等级烧伤 else { // 等级烧伤明细 $logs[] = [ 'user_id' => $pid, 'source_id' => $userId, 'source_order_no' => $orderNo, 'type' => 97, 'coin_type' => 1, 'user_type'=> 1, 'money' => $bonusUsdt3, 'actual_money' => $bonusUsdt3, 'balance' => isset($parentInfo['usdt'])? $parentInfo['usdt'] : 0, 'create_time' => time(), 'update_time' => time(), 'remark' => $remark, 'status' => 1, 'mark' => 1, ]; } } if($logs && !AccountLogModel::insert($logs)){ DB::rollBack(); $this->error = 2606; return false; } } DB::commit(); $this->error = 2608; return true; } /** * 任务算力奖励 * @param $userId 用户ID * @param $power 算力 * @param $type 类型 * @param int $sourceId 任务ID * @param string $remark 备注说明 * @return false */ public function settleTaskPower($userId, $power, $type, $sourceId=0, $remark='') { if($power<=0){ $this->error = 2014; return false; } $userInfo = MemberModel::where(['id'=> $userId, 'status'=>1,'mark'=>1]) ->select(['id','nickname','usdt','power_num','status']) ->first(); $userPower = isset($userInfo['power_num'])? $userInfo['power_num'] : 0; if(empty($userInfo) || $userId<=0) { $this->error = 1041; return false; } DB::beginTransaction(); // 更新账户算力 $updateData = ['power_num'=> DB::raw("power_num + {$power}"),'update_time'=>time()]; if(!MemberModel::where(['id'=> $userId])->update($updateData)){ DB::rollBack(); $this->error = 1042; return false; } // 明细 $orderNo = get_order_num('TS'); $log = [ 'user_id' => $userId, 'source_id' => $sourceId, 'source_order_no' => $orderNo, 'type' => $type?$type:99, 'coin_type' => 3, 'user_type'=> 1, 'money' => $power, 'actual_money' => $power, 'balance' => $userPower, 'create_time' => time(), 'update_time' => time(), 'remark' => $remark? $remark : '算力奖励', 'status' => 1, 'mark' => 1, ]; if (!AccountLogModel::insertGetId($log)) { $this->error = 2407; DB::rollBack(); return false; } DB::commit(); // 算力统计 AccountLogService::make()->saveCount($userId, $power, 1); // 站内消息 $dateTime = date('Y-m-d H:i:s'); MessageService::make()->pushMessage($userId, $log['remark'] , "您在{$dateTime}(UTC+8){$log['remark']}{$power}算力已到账,请及时查看账户!!!",3); } /** * 订单结算 * @param $orderInfo 订单信息 * @param $orderXdTotal 星豆数量 * @param int $userId * @return bool */ public function settleOrder($orderInfo, $orderXdTotal, $userId=0) { //$orderXdTotal = isset($orderInfo['xd_total'])?$orderInfo['xd_total'] : 0; $orderId = isset($orderInfo['id'])?$orderInfo['id'] : 0; $orderNo = isset($orderInfo['order_no'])?$orderInfo['order_no'] : ''; $orderUserId = isset($orderInfo['user_id'])?$orderInfo['user_id'] : 0; $orderMerchUid = isset($orderInfo['merch_uid'])?$orderInfo['merch_uid'] : 0; if(empty($orderId) || empty($orderUserId)){ $this->error = 2912; return true; } if($orderXdTotal <= 0){ $this->error = 3005; return true; } $cacheKey = "caches:settle:{$userId}_{$orderNo}"; if(RedisService::get($cacheKey)){ $this->error = 3002; return true; } // 奖励待返积分、算力 $awardWaitScore = isset($orderInfo['award_wait_score'])?$orderInfo['award_wait_score'] : 0; $awardPowerNum = isset($orderInfo['award_power_num'])?$orderInfo['award_power_num'] : 0; // 订单用户信息 $userInfo = MemberModel::with(['parent']) ->where(['id'=> $orderUserId,'mark'=> 1,'status'=> 1]) ->select(['id','nickname','pay_password','balance','usdt','power_num','wait_score','parent_id','parents']) ->first(); $userInfo = $userInfo? $userInfo->toArray() : []; $parentInfo = isset($userInfo['parent'])? $userInfo['parent'] : []; $parentId = isset($userInfo['parent_id'])? $userInfo['parent_id'] : 0; $userXd = isset($userInfo['balance'])? floatval($userInfo['balance']) : 0.00; $userWaitScore = isset($userInfo['wait_score'])? floatval($userInfo['wait_score']) : 0.00; $userPowerNum = isset($userInfo['power_num'])? floatval($userInfo['power_num']) : 0.00; if(empty($userInfo)){ $this->error = 3003; RedisService::clear($cacheKey); return true; } // 推荐用户奖励(从用户奖励中扣除) $inviteAwardWaitScore = 0; $userAwardWaitScore = $awardWaitScore; $parentStatus = isset($parentInfo['status'])? $parentInfo['status'] : 0; if($parentInfo && $parentStatus==1 && $awardWaitScore>0){ // 奖励上级待返积分 $inviteWaitScoreRate = ConfigService::make()->getConfigByCode('cost_award_invite_wait_score',0); $inviteWaitScoreRate = $inviteWaitScoreRate>0 && $inviteWaitScoreRate<100? $inviteWaitScoreRate : 0; $inviteAwardWaitScore = moneyFormat($awardWaitScore * $inviteWaitScoreRate/100, 2); $userAwardWaitScore = moneyFormat($awardWaitScore - $inviteAwardWaitScore, 2); } // 没有佣金 if($userAwardWaitScore<=0 && $userPowerNum<=0){ $this->error = 3004; RedisService::clear($cacheKey); return true; } // TODO 结算处理 DB::beginTransaction(); // TODO 订单商户佣金结算 if ($orderMerchUid > 0){ $merchantUserInfo = MemberModel::where(['id'=> $orderMerchUid,'mark'=>1]) ->select(['id','balance','wait_score','usdt','status']) ->first(); // 商户佣金计算入账 $settleRate = ConfigService::make()->getConfigByCode('merchant_settle_usdt_rate'); $settleRate = $settleRate>0? min(100, $settleRate) : 100; $settleXd = moneyFormat($orderXdTotal * $settleRate/100, 2); $xdPrice = ConfigService::make()->getConfigByCode('xd_price',100); $xdPrice = $xdPrice>0 && $xdPrice<10000? $xdPrice : 100; $settleUsdt = moneyFormat($settleXd/$xdPrice, 2); if($settleUsdt>0 && $merchantUserInfo){ $updateData = ['usdt'=> DB::raw("usdt + {$settleUsdt}"),'update_time'=>time()]; if(!MemberModel::where(['id'=> $orderMerchUid])->update($updateData)){ DB::rollBack(); $this->error = 1042; return false; } // 明细 $merchantUsdt = isset($merchantUserInfo['usdt'])? $merchantUserInfo['usdt'] : 0; $log = [ 'user_id' => $orderMerchUid, 'source_id' => $orderUserId, 'source_order_no' => $orderNo, 'type' => 10, 'coin_type' => 1, 'user_type'=> 1, 'money' => $settleUsdt, 'actual_money' => $settleUsdt, 'balance' => $merchantUsdt, 'create_time' => time(), 'update_time' => time(), 'remark' => "推荐商品佣金奖励", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } } } // TODO 购买用户奖励结算 $updateData = [ 'wait_score'=>DB::raw("wait_score + {$userAwardWaitScore}"), // 用户待返积分奖励 'power_num'=>DB::raw("power_num + {$awardPowerNum}"), // 算力奖励 'update_time'=>time() ]; if(!MemberModel::where(['id'=> $userId])->update($updateData)){ DB::rollBack(); $this->error = 1042; RedisService::clear($cacheKey); return false; } // 待返积分奖励明细 if($userAwardWaitScore>0){ $log = [ 'user_id' => $orderUserId, 'source_id' => $orderId, 'source_order_no' => $orderNo, 'type' => 9, 'coin_type' => 5, 'user_type'=> 1, 'money' => $userAwardWaitScore, 'actual_money' => $userAwardWaitScore, 'balance' => $userWaitScore, 'create_time' => time(), 'update_time' => time(), 'remark' => "商城消费奖励", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } // 用户消息 $dateTime = date('Y-m-d H:i:s'); $message = "您在{$dateTime}(UTC+8)完成商城消费,获得待返积分奖励已到账:\n消费星豆:{$orderXdTotal}\n奖励积分:{$userAwardWaitScore}\n奖励前:{$userWaitScore}"; MessageService::make()->pushMessage($userId, '商城消费待返积分奖励', $message,3); } // 算力奖励明细 if($awardPowerNum>0){ $log = [ 'user_id' => $orderUserId, 'source_id' => $orderId, 'source_order_no' => $orderNo, 'type' => 9, 'coin_type' => 3, 'user_type'=> 1, 'money' => $awardPowerNum, 'actual_money' => $awardPowerNum, 'balance' => $userPowerNum, 'create_time' => time(), 'update_time' => time(), 'remark' => "商城消费奖励", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } // 用户消息 $dateTime = date('Y-m-d H:i:s'); $message = "您在{$dateTime}(UTC+8)完成商城消费,获得算力奖励已到账:\n消费星豆:{$orderXdTotal}\n奖励算力:{$awardPowerNum}\n奖励前:{$userPowerNum}"; MessageService::make()->pushMessage($userId, '商城消费算力奖励', $message,3); // 算力统计 AccountLogService::make()->saveCount($userId, $userPowerNum, 1); } // TODO 推荐用户待返积分奖励明细 if($inviteAwardWaitScore>0 && $parentId>0 && $parentId != $orderUserId){ $updateData = [ 'wait_score'=>DB::raw("wait_score + {$inviteAwardWaitScore}"), // 推荐用户待返积分奖励 'update_time'=>time() ]; if(!MemberModel::where(['id'=> $parentId])->update($updateData)){ DB::rollBack(); $this->error = 2028; RedisService::clear($cacheKey); return false; } // 明细 $parentWaitScore = isset($parentInfo['wait_score'])? $parentInfo['wait_score'] : 0; $log = [ 'user_id' => $parentId, 'source_id' => $orderUserId, 'source_order_no' => $orderNo, 'type' => 9, 'coin_type' => 5, 'user_type'=> 1, 'money' => $inviteAwardWaitScore, 'actual_money' => $inviteAwardWaitScore, 'balance' => $parentWaitScore, 'create_time' => time(), 'update_time' => time(), 'remark' => "推荐用户商城消费奖励", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } // 用户消息 $dateTime = date('Y-m-d H:i:s'); $message = "您在{$dateTime}(UTC+8)获得推荐用户【{$userId}】商城消费,待返积分奖励已到账:\n消费星豆:{$orderXdTotal}\n奖励积分:{$inviteAwardWaitScore}\n奖励前:{$parentWaitScore}"; MessageService::make()->pushMessage($userId, '推荐用户商城消费奖励', $message,3); } DB::commit(); RedisService::clear($cacheKey); return true; } /** * 每日平台发放积分 * @return bool */ public function grantScore() { $cacheKey = "caches:platform:grant_score"; if(RedisService::get($cacheKey.'_lock')){ $this->error = 3006; return false; } $dayScore = ConfigService::make()->getConfigByCode('xb_day_num',0); // 每日发放 $dayScore = $dayScore>0 && $dayScore<=10000000? $dayScore : 0; $xlTotal = ConfigService::make()->getConfigByCode('xl_total',0); // 总发放 $xlTotal = $xlTotal? $xlTotal : 0; if($xlTotal<=0 || $dayScore <= 0 || $dayScore > $xlTotal){ $this->error = 3007; return false; } // 发放用户 RedisService::set($cacheKey.'_lock', date('Y-m-d H:i:s'), rand(30,60)); $date = date('Y-m-d',strtotime('-1 day')); $model = AccountCountModel::from('account_counts as a') ->leftJoin('member as b','b.id','=','a.user_id') ->leftJoin('member_level as c','c.id','=','b.member_level') ->where(['a.date'=>$date,'a.type'=>1]); $countModel = clone $model; $powerDayTotal = $countModel->sum('a.money'); $settleUsers = $model->where('b.score_grant_at','<',date('Y-m-d')) ->select(['a.user_id','a.type','a.money','b.member_level','b.supper_point','b.score','c.power_multiple']) ->orderBy('a.create_time','asc') ->groupBy('a.user_id') ->limit(rand(200,500)) ->get(); $settleUsers = $settleUsers? $settleUsers->toArray() : []; if($settleUsers){ RedisService::set($cacheKey.'_'.date('YmdHis'), ['power'=> $powerDayTotal,'users'=>$settleUsers], 7200); foreach($settleUsers as $item){ $dayPower = isset($item['money'])? $item['money'] : 0; $userId = isset($item['user_id'])? $item['user_id'] : 0; $powerRate = isset($item['power_multiple']) && $item['power_multiple']? $item['power_multiple'] : 1; $userSettleScore = moneyFormat(($dayPower * $powerRate)/$powerDayTotal * $dayScore, 2); if($userSettleScore>0 && $userId>0){ // 节点分红积分奖励 $nodeScore = 0; $nodeName = '节点会员'; $nodeId = isset($item['supper_point'])? $item['supper_point'] : 0; if($nodeId>0){ $nodeInfo = MemberNodeService::make()->getNodeInfo($nodeId); $scoreRate = isset($nodeInfo['score_rate'])? $nodeInfo['score_rate'] : 0; if($scoreRate>0 && $scoreRate<100){ $nodeName = isset($nodeInfo['name']) && $nodeInfo['name']? $nodeInfo['name'] : '节点会员'; $nodeScore = moneyFormat($userSettleScore * $scoreRate/100, 2); } } // 结算发放积分 $totalScore = moneyFormat($userSettleScore + $nodeScore,2); DB::beginTransaction(); $updateData = [ 'score'=> DB::raw("score + {$totalScore}"), 'score_grant_at'=> date('Y-m-d H:i:s'), 'update_time'=> time(), ]; if(!MemberModel::where(['id'=> $userId])->update($updateData)){ DB::rollBack(); $this->error = 3007; continue; } // 明细 $userScore = isset($item['score'])? $item['score'] : 0; $log = [ 'user_id' => $userId, 'source_id' => 0, 'source_order_no' => get_order_num('SC'), 'type' => 9, 'coin_type' => 4, 'user_type'=> 1, 'money' => $userSettleScore, 'actual_money' => $userSettleScore, 'balance' => $userScore, 'create_time' => time(), 'update_time' => time(), 'remark' => "每日发放积分", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; continue; } if($nodeScore>0){ $userScore += $userSettleScore; $log = [ 'user_id' => $userId, 'source_id' => 0, 'source_order_no' => get_order_num('SC'), 'type' => 9, 'coin_type' => 4, 'user_type'=> 1, 'money' => $nodeScore, 'actual_money' => $nodeScore, 'balance' => moneyFormat($userScore + $userSettleScore,4), 'create_time' => time(), 'update_time' => time(), 'remark' => "{$nodeName}会员每日积分分红", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; continue; } } DB::commit(); // 用户消息 $dateTime = date('Y-m-d H:i:s'); $message = "您在{$dateTime}(UTC+8)获得平台每日积分发放已到账:\n发放积分:{$dayScore}\n到账积分:{$userSettleScore}\n发放前:{$userScore}\n节点会员:{$nodeName}\n节点分红:{$nodeScore}"; MessageService::make()->pushMessage($userId, '每日积分发放', $message,3); } } RedisService::clear($cacheKey.'_lock'); }else{ // 结算完 RedisService::set($cacheKey.'_lock', date('Y-m-d H:i:s'), 86400); } return ['count'=> count($settleUsers),'power'=>$powerDayTotal,'day_score'=>$dayScore,'xl_total'=> $xlTotal]; } /** * 每日返还待返积分 * @return bool */ public function returnWaitScore() { $cacheKey = "caches:platform:wait_score"; if(RedisService::get($cacheKey.'_lock')){ $this->error = 3006; return false; } // 每日日返还待返积分数量 $scoreToXdRate = ConfigService::make()->getConfigByCode('wait_score_to_xd_rate',10000); $scoreToXdRate = $scoreToXdRate>0 && $scoreToXdRate<1000000? $scoreToXdRate : 10000; $returnScore = ConfigService::make()->getConfigByCode('day_wait_score_num',0); $returnScore = $returnScore>0 && $returnScore<500000? $returnScore : 0; if($returnScore <= 0 || $scoreToXdRate<=0){ $this->error = 3009; return false; } RedisService::set($cacheKey.'_lock', date('Y-m-d H:i:s'),rand(30,60)); $users = MemberModel::where(['mark'=>1]) ->where('wait_score','>',0) ->where('wait_score_return_at','<',date('Y-m-d')) ->select(['id','usdt','score','balance','wait_score']) ->orderBy('create_time','asc') ->limit(rand(200,500)) ->get(); $users = $users? $users->toArray() : []; if($users){ $dateTime = date('Y-m-d H:i:s'); RedisService::set($cacheKey, ['return'=>$returnScore,'users'=>$users,'date'=>$dateTime], 86400); foreach($users as $item){ $userXd = isset($item['balance'])? $item['balance'] : 0; $waitScore = isset($item['wait_score'])? $item['wait_score'] : 0; $userId = isset($item['id'])? $item['id'] : 0; $settleScore = $waitScore >= $returnScore? $returnScore : $waitScore; // 不足每日返还则还完 $settleXd = moneyFormat($settleScore/$scoreToXdRate, 2); // 不足每日返还则还完 if($settleScore>0){ DB::beginTransaction(); $updateData = [ 'wait_score'=> DB::raw("wait_score - {$settleScore}"), // 扣除待返积分 'balance'=> DB::raw("balance + {$settleXd}"), // 返还星豆数量 'wait_score_return_at'=> date('Y-m-d H:i:s'), 'update_time'=> time(), ]; if(!MemberModel::where(['id'=> $userId])->update($updateData)){ DB::rollBack(); $this->error = 3007; continue; } // 待返积分明细 $orderNo = get_order_num('FS'); if($settleScore){ $log = [ 'user_id' => $userId, 'source_id' => 0, 'source_order_no' => $orderNo, 'type' => 24, 'coin_type' => 5, 'user_type'=> 1, 'money' => -$settleScore, 'actual_money' => -$settleScore, 'balance' => $waitScore, 'create_time' => time(), 'update_time' => time(), 'remark' => "每日待返积分返还星豆", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; continue; } } // 星豆明细 if($settleXd){ $log = [ 'user_id' => $userId, 'source_id' => 0, 'source_order_no' => $orderNo, 'type' => 24, 'coin_type' => 2, 'user_type'=> 1, 'money' => $settleXd, 'actual_money' => $settleXd, 'balance' => $userXd, 'create_time' => time(), 'update_time' => time(), 'remark' => "每日待返积分返还星豆", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; continue; } } DB::commit(); // 用户消息 $dateTime = date('Y-m-d H:i:s'); $message = "您在{$dateTime}(UTC+8)获得每日积分返还已到账:\n返还积分:{$settleScore}\n返还前:{$waitScore}\n返还星豆:{$settleXd} \n返还前:{$userXd} 星豆\n"; MessageService::make()->pushMessage($userId, '每日积分返还星豆奖励', $message,3); } } RedisService::clear($cacheKey.'_lock'); }else{ RedisService::set($cacheKey.'_lock', date('Y-m-d H:i:s'), 86400); } return ['count'=> count($users),'return'=> $returnScore]; } /** * 全球分红 * @return bool */ public function globalBonus() { $cacheKey = "caches:platform:global_bonus"; if(RedisService::get($cacheKey.'_lock')){ $this->error = 3006; return false; } // 昨日业绩 $date = date('Y-m-d', strtotime('-1 day')); $model = AccountCountModel::from('account_counts as a') ->leftJoin('member as b','b.id','=','a.user_id') ->where(['a.date'=>$date,'a.type'=>2]); $countModel1 = clone $model; // 普通节点 $countModel2 = clone $model; // 超级节点 $node1Total = $countModel1->where(['b.supper_point'=>1])->sum('a.money'); $node2Total = $countModel2->where(['b.supper_point'=>2])->sum('a.money'); // 无任何节点业绩 if($node1Total <= 0 && $node2Total <= 0){ $this->error = 3010; return false; } // 结算用户 $users = MemberModel::from('member as a') ->leftJoin('member_nodes as b','b.id','=','a.supper_point') ->leftJoin('member_level as c','c.id','=','a.member_level') ->where('a.supper_point','>',0) ->where('a.global_bonus_at','<',date('Y-m-d')) ->where(['a.mark'=>1]) ->select(['a.id','a.balance','a.usdt','a.supper_point','a.parent_id','a.member_level','c.global_bonus_rate','b.name']) ->orderBy('a.supper_point','asc') ->orderBy('a.id','asc') ->limit(rand(200,500)) ->get(); $users = $users? $users->toArray() : []; $success = 0; if($users) { $dateTime = date('Y-m-d H:i:s'); RedisService::set($cacheKey, ['node1Total'=>$node1Total,'node2Total'=>$node2Total,'users'=>$users,'date'=>$dateTime], 86400); foreach ($users as $item){ $userUsdt = isset($item['usdt'])? $item['usdt'] : 0; $userId = isset($item['id'])? $item['id'] : 0; $userSupperPoint = isset($item['supper_point'])? $item['supper_point'] : 0; $bonusRate = isset($item['global_bonus_rate'])? $item['global_bonus_rate'] : 0; if($bonusRate<=0 || $bonusRate>=100 || $userSupperPoint<=0){ continue; } // 个人昨日业绩 $userPerformance = AccountLogService::make()->getTotal($userId, $date,2); // 团队昨日业绩 $teamPerformance = AccountLogService::make()->getTeamTotal($userId, $date,2); // 普通节点 $nodeTotal = 0; if($userSupperPoint==1){ $nodeTotal = $node1Total; } // 超级节点 else if($userSupperPoint == 2){ $nodeTotal = $node2Total; } $bonusUsdt = moneyFormat(($teamPerformance/$nodeTotal) * $bonusRate/100,4); if($bonusUsdt>0){ DB::beginTransaction(); $updateData = [ 'usdt'=> DB::raw("usdt + {$bonusUsdt}"), // 奖励USDT 'global_bonus_at'=> date('Y-m-d H:i:s'), 'update_time'=> time(), ]; if(!MemberModel::where(['id'=> $userId])->update($updateData)){ DB::rollBack(); $this->error = 3007; continue; } // 待返积分明细 $orderNo = get_order_num('GU'); $log = [ 'user_id' => $userId, 'source_id' => 0, 'source_order_no' => $orderNo, 'type' => 15, 'coin_type' => 5, 'user_type'=> 1, 'money' => $bonusUsdt, 'actual_money' => $bonusUsdt, 'balance' => $userUsdt, 'create_time' => time(), 'update_time' => time(), 'remark' => "全球分红奖励", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; continue; } // 平台财务 FinanceService::make()->saveLog(0,$bonusUsdt,2); // 用户消息 $dateTime = date('Y-m-d H:i:s'); $nodeName = isset($item['name'])? $item['name'] :''; $message = "您在{$dateTime}(UTC+8)获得全球分红奖励已到账:\n奖励金额:{$bonusUsdt}\n奖励前:{$userUsdt}\n节点类型:{$nodeName}\n个人算力:{$userPerformance}\n团队算力:{$teamPerformance}\n节点算力:{$nodeTotal}"; MessageService::make()->pushMessage($userId, '全球分红奖励', $message,3); } } RedisService::clear($cacheKey.'_lock'); }else{ RedisService::set($cacheKey.'_lock', date('Y-m-d H:i:s'), 86400); } return ['count'=>count($users),'success'=> $success]; } }