// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Models\AccountLogModel; use App\Models\MemberLevelModel; use App\Models\MemberModel; use App\Models\MemberNodeModel; use App\Models\MemberSettingModel; use App\Services\BaseService; use App\Services\ConfigService; use App\Services\RedisService; use Illuminate\Support\Facades\DB; /** * 节点会员服务管理-服务类 * @author laravel开发员 * @since 2020/11/11 * @package App\Services\Common */ class MemberNodeService extends BaseService { protected static $instance=null; /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 * MemberSettingService constructor. */ public function __construct() { $this->model = new MemberNodeModel(); } /** * 静态入口 * @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, $field = '', $userId=0) { $where = ['a.mark' => 1,'a.status'=>1]; $field = $field? $field : 'lev_a.id,lev_a.name,lev_a.price,lev_a.upgrade_level_id,lev_b.global_bonus_rate,lev_a.limit_num,lev_a.box_num,lev_a.score_rate,lev_a.remark,lev_a.status'; $sortType = isset($params['sort_type']) ? $params['sort_type'] : 1; $order = 'id asc'; if($sortType == 1){ $order = 'lev_a.id asc'; } $list = $this->model->from('member_nodes as a') ->leftJoin('member_level as b','b.id','=','a.upgrade_level_id') ->where($where) ->selectRaw($field) ->orderByRaw($order) ->paginate($pageSize > 0 ? $pageSize : 9999999); $list = $list ? $list->toArray() : []; if ($list) { foreach ($list['data'] as &$item) { $item['level_box_num'] = (int)MemberLevelModel::where('id','<=', $item['upgrade_level_id'])->where(['status'=>1,'mark'=>1])->sum('box_num'); // 是否已购买 $buyLogId = AccountLogModel::where(['user_id'=> $userId,'source_id'=>$item['id'],'type'=>4,'status'=>1,'mark'=>1])->value('id'); $item['buy_status'] = $buyLogId? 1 : 0; } } return [ 'pageSize' => $pageSize, 'total' => isset($list['total']) ? $list['total'] : 0, 'list' => isset($list['data']) ? $list['data'] : [] ]; } /** * 购买节点 * @param $userId 用户ID * @param $params 节点参数:id-节点ID,pay_password-交易密码 * @return bool */ public function buyNode($userId, $params) { $nodeId = isset($params['id'])? intval($params['id']) : 0; $payPassword = isset($params['pay_password'])? trim($params['pay_password']) : ''; if($nodeId<=0){ $this->error = 2014; return false; } $cacheKey = "caches:members:nodes:buy_{$userId}_{$nodeId}"; if(RedisService::get($cacheKey.'_lock')){ $this->error = 1034; return false; } $nodeInfo = $this->model->from('member_nodes as a') ->leftJoin('member_level as b','b.id','=','a.upgrade_level_id') ->where(['a.id'=> $nodeId,'a.status'=>1,'a.mark'=>1]) ->select(['a.*','b.name as level_name']) ->first(); $price = isset($nodeInfo['price'])? floatval($nodeInfo['price']) : 0; $boxNum = isset($nodeInfo['box_num'])? intval($nodeInfo['box_num']) : 0; $upgradeLevelId = isset($nodeInfo['upgrade_level_id'])? intval($nodeInfo['upgrade_level_id']) : 0; $nodeName = isset($nodeInfo['name'])? $nodeInfo['name'] : ''; $levelName = isset($nodeInfo['level_name'])? $nodeInfo['level_name'] : ''; if(empty($nodeInfo) || $price<=0){ $this->error = 2501; return false; } $userInfo = MemberModel::where(['id'=> $userId,'mark'=>1]) ->select(['id','nickname','usdt','wait_score','parents','points','parent_id','member_level','power_num','trc_url','pay_password','status']) ->first(); $status = isset($userInfo['status'])? $userInfo['status'] : 0; $userUsdt = isset($userInfo['usdt'])? $userInfo['usdt'] : 0; $userPayPassword = isset($userInfo['pay_password'])? $userInfo['pay_password'] : ''; $userWaitScore = isset($userInfo['wait_score'])? $userInfo['wait_score'] : 0; $userPowerNum = isset($userInfo['power_num'])? $userInfo['power_num'] : 0; if(empty($userInfo) || $status != 1){ $this->error = 2024; return false; } // 是否已经购买过 if(AccountLogModel::where(['user_id'=> $userId,'source_id'=>$nodeId,'type'=>4,'status'=>1,'mark'=>1])->value('id')){ $this->error = 2502; return false; } // USDT余额是否足够 if($userUsdt < $price){ $this->error = 2035; return false; } // 交易密码 if(empty($userPayPassword)){ $this->error = 1040; return false; } if($userPayPassword != get_password($payPassword)){ $this->error = 2038; return false; } // 购买明细 RedisService::set($cacheKey, $params, rand(2,3)); $orderNo = get_order_num('VN'); DB::beginTransaction(); $log = [ 'user_id' => $userId, 'source_id' => $nodeId, 'source_order_no' => $orderNo, 'type' => 4, 'coin_type' => 1, 'user_type'=> 1, 'money' => -$price, 'actual_money' => -$price, 'balance' => $userUsdt, 'create_time' => time(), 'update_time' => time(), 'remark' => "购买{$nodeName}", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } // 待返积分明细 $xdPrice = ConfigService::make()->getConfigByCode('xd_price',100); $xdPrice = $xdPrice>0 && $xdPrice<=10000? $xdPrice : 100; $waitScoreRate = ConfigService::make()->getConfigByCode('node_award_score_rate', 200); $waitScoreRate = $waitScoreRate>0 && $waitScoreRate<=1000? $waitScoreRate : 0; $waitScore = moneyFormat($price * $xdPrice * $waitScoreRate/100, 2); if($waitScore>0){ $log = [ 'user_id' => $userId, 'source_id' => $nodeId, 'source_order_no' => $orderNo, 'type' => 9, 'coin_type' => 5, 'user_type'=> 1, 'money' => $waitScore, 'actual_money' => $waitScore, 'balance' => $userWaitScore, 'create_time' => time(), 'update_time' => time(), 'remark' => "购买{$nodeName}", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } } // 算力明细 $powerNum = $price; $log = [ 'user_id' => $userId, 'source_id' => $nodeId, 'source_order_no' => $orderNo, 'type' => 9, 'coin_type' => 3, 'user_type'=> 1, 'money' => $powerNum, 'actual_money' => $powerNum, 'balance' => $userPowerNum, 'create_time' => time(), 'update_time' => time(), 'remark' => "购买{$nodeName}", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } // 账户 $updateData = [ 'usdt'=> DB::raw("usdt - {$price}"), // 扣除USDT 'supper_point'=>$nodeId, 'member_level'=> $upgradeLevelId, // 直达等级 'box_num'=>DB::raw("box_num + {$boxNum}"), // 奖励盲盒数量 'wait_score'=>DB::raw("wait_score + {$waitScore}"), // 奖励盲盒数量 'power_num'=>DB::raw("power_num + {$powerNum}"), // 奖励盲盒数量 'update_time'=>time() ]; if(!MemberModel::where(['id'=> $userId])->update($updateData)){ DB::rollBack(); $this->error = 2036; RedisService::clear($cacheKey); return false; } // 消息 $dateTime = date('Y-m-d H:i:s'); $levelTip = $upgradeLevelId>0? ",并升级为{$levelName}" :''; MessageService::make()->pushMessage($userId,"购买{$nodeName}成功","您在{$dateTime}(UTC+8)成功支付{$price}USDT购买【{$nodeName}】{$levelTip}。",3); DB::commit(); // 算力统计 AccountLogService::make()->saveCount($userId, $powerNum, 1); // 业绩统计 AccountLogService::make()->saveCount($userId, $price, 2); // 结算收益奖励 FinanceService::make()->settleBonus($userId, $userInfo, $price, $orderNo, "购买{$nodeName}"); $this->error = 2503; RedisService::clear($cacheKey); return true; } /** * 节点详情信息 * @param $nodeId 节点ID * @return array|mixed */ public function getNodeInfo($nodeId) { $cacheKey = "caches:nodes:info:{$nodeId}"; $data = RedisService::get($cacheKey); if($data){ return $data; } $data = $this->model->where(['id'=>$nodeId,'mark'=>1,'status'=>1]) ->select(['id','name','price','score_rate','box_num']) ->first(); $data = $data?$data->toArray() : []; if($data){ RedisService::set($cacheKey, $data, rand(3600,7200)); } return $data; } }