529 lines
18 KiB
PHP
529 lines
18 KiB
PHP
<?php
|
||
|
||
namespace app\service\game;
|
||
|
||
use addons\webman\model\Game;
|
||
use addons\webman\model\GamePlatform;
|
||
use addons\webman\model\Player;
|
||
use addons\webman\model\PlayerGamePlatform;
|
||
use addons\webman\model\PlayerWalletTransfer;
|
||
use app\exception\GameException;
|
||
use DateTime;
|
||
use DateTimeZone;
|
||
use Exception;
|
||
use Illuminate\Support\Str;
|
||
use support\Log;
|
||
use support\Response;
|
||
|
||
class JiLiServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||
{
|
||
public $method = 'POST';
|
||
private $apiDomain;
|
||
private $domain;
|
||
private $appId;
|
||
private $appSecret;
|
||
public $loginId;
|
||
|
||
public $gameType = [
|
||
'2' => 'Casino',
|
||
'5' => 'Fishing',
|
||
'8' => 'Bingo',
|
||
'1' => 'Slot',
|
||
];
|
||
|
||
public $localGameType = [
|
||
'2' => '2',//赌场
|
||
'5' => '4',//捕鱼
|
||
'8' => '8',//宾果
|
||
'1' => '1',//斯洛
|
||
];
|
||
|
||
public $failCode = [
|
||
'S200' => '重復請求',
|
||
'F0001' => '無效的簽名',
|
||
'F0002' => '無效的SN',
|
||
'F0003' => '無效的參數',
|
||
'F0004' => '無效的貨幣',
|
||
'F0005' => '玩家已存在',
|
||
'F0006' => '玩家不存在',
|
||
'F0007' => '會員不存在',
|
||
'F0008' => '執行失敗',
|
||
'F0009' => '無效的方法',
|
||
'F0010' => '無效的用戶狀態',
|
||
'F0011' => '玩家狀態無需更新',
|
||
'F0012' => '超出數據範圍',
|
||
'F0013' => '無匹配數據',
|
||
'F0014' => '登入位置被禁止',
|
||
'F0015' => '分數不足夠',
|
||
'F0016' => '不支持禮碼',
|
||
'F0017' => '交易流水號不得重複',
|
||
'F0018' => '系統繁忙',
|
||
'F0019' => '日期時間各式錯誤',
|
||
'F0020' => '超出時間限制範圍(開始時間與結束時間之間不能大於120分鐘)',
|
||
'F0021' => '執行取消',
|
||
'M0001' => '系統維護',
|
||
'M0002' => '系統錯誤',
|
||
];
|
||
|
||
/**
|
||
* @param Player|null $player
|
||
* @param $type
|
||
* @throws Exception
|
||
*/
|
||
public function __construct($type, Player $player = null)
|
||
{
|
||
$config = config('game_platform.' . $type);
|
||
$this->appId = $config['app_id'];
|
||
$this->apiDomain = $config['api_domain'];
|
||
$this->domain = $config['domain'];
|
||
$this->appSecret = $config['app_secret'];
|
||
$this->platform = GamePlatform::query()->where('name', $type)->first();
|
||
if (!empty($player)) {
|
||
$this->player = $player;
|
||
$this->getLoginId();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 生成请求url
|
||
* @param $method
|
||
* @return string
|
||
*/
|
||
public function createUrl($method): string
|
||
{
|
||
return $this->apiDomain.$method;
|
||
}
|
||
|
||
public function createSign($params): string
|
||
{
|
||
$date = new DateTime('now', new DateTimeZone('UTC'));
|
||
$date->setTimezone(new DateTimeZone('America/Puerto_Rico'));
|
||
$key_g = md5($date->format('ymj').$this->appId.$this->appSecret);
|
||
$paramStr = urldecode(http_build_query($params));
|
||
$key = mt_rand(100000,999999).MD5($paramStr.$key_g).mt_rand(100000,999999);
|
||
return $key;
|
||
}
|
||
|
||
/**
|
||
* 更新游戏列表
|
||
* @return array|mixed|Response
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
public function getSimpleGameList()
|
||
{
|
||
$params = [
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
$result = doFormCurl($this->createUrl('GetGameList'), $params);
|
||
if ($result['ErrorCode'] == 0 && !empty($result['Data'])) {
|
||
foreach ($result['Data'] as $game) {
|
||
if($game['GameCategoryId'] == 3){
|
||
continue;
|
||
}
|
||
Game::query()->updateOrCreate(
|
||
[
|
||
'platform_id' => $this->platform->id,
|
||
'game_code' => $game['GameId'],
|
||
],
|
||
[
|
||
'platform_game_type' => $game['GameCategoryId'],
|
||
'game_type' => $this->localGameType[$game['GameCategoryId']],
|
||
'name' => $game['name']['en-US'],
|
||
]
|
||
);
|
||
}
|
||
}else{
|
||
throw new GameException($result['Message'], 0);
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 获取游戏列表
|
||
* @return array|mixed|Response
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
public function getGamesList()
|
||
{
|
||
$params = [
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
$result = doFormCurl($this->createUrl('GetGameList'), $params);
|
||
if ($result['ErrorCode'] == 0 && !empty($result['Data'])) {
|
||
return $result;
|
||
}else{
|
||
throw new GameException($result['Message'], 0);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取玩家ID
|
||
* @throws Exception
|
||
*/
|
||
protected function getLoginId()
|
||
{
|
||
/** @var PlayerGamePlatform $playerGamePlatform */
|
||
$playerGamePlatform = PlayerGamePlatform::query()->where('platform_id', $this->platform->id)->where('player_id',$this->player->id)->first();
|
||
if (!empty($playerGamePlatform)) {
|
||
return $this->loginId = $playerGamePlatform->player_code;
|
||
}
|
||
return $this->createPlayer([
|
||
'uuid' => $this->player->uuid,
|
||
'name' => $this->player->name,
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 创建玩家
|
||
* @param array $data
|
||
* @return array|mixed|Response
|
||
* @throws GameException|Exception
|
||
*/
|
||
public function createPlayer(array $data = [])
|
||
{
|
||
$params = [
|
||
'Account' => $data['uuid'],
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
$result = doFormCurl($this->createUrl('CreateMember'), $params);
|
||
|
||
if (!in_array($result['ErrorCode'],[0,101])) {
|
||
Log::error($result['Message'], ['res' => $result]);
|
||
throw new GameException($result['Message'], 0);
|
||
}
|
||
$playerGamePlatform = new PlayerGamePlatform();
|
||
$playerGamePlatform->player_id = $this->player->id;
|
||
$playerGamePlatform->platform_id = $this->platform->id;
|
||
$playerGamePlatform->player_name = $data['name'];
|
||
$playerGamePlatform->player_code = $data['uuid'];
|
||
$playerGamePlatform->save();
|
||
$this->loginId = $playerGamePlatform->player_code;
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 获取玩家
|
||
* @return array|mixed|Response
|
||
* @throws GameException|Exception
|
||
*/
|
||
public function getPlayer()
|
||
{
|
||
$params = [
|
||
'Accounts' => $this->loginId,
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
$result = doFormCurl($this->createUrl('GetMemberInfo'), $params);
|
||
if ($result['ErrorCode'] != 0) {
|
||
throw new GameException($result['Message'], 0);
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 玩家进入游戏
|
||
* @param array $data
|
||
* @return string
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
public function login(array $data = []): string
|
||
{
|
||
$params = [
|
||
'Account'=> $this->loginId,
|
||
'GameId'=> intval($data['gameCode']),
|
||
'Lang'=> $data['lang'],
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
$result = doFormCurl($this->createUrl('LoginWithoutRedirect'), $params);
|
||
if ($result['ErrorCode'] == 0 && !empty($result['Data'])) {
|
||
$link = $result['Data'];
|
||
}else{
|
||
throw new GameException($result['Message'], 0);
|
||
}
|
||
return $link;
|
||
}
|
||
|
||
/**
|
||
* 获取玩家游戏平台余额
|
||
* @return array|mixed|Response
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
public function getBalance()
|
||
{
|
||
$params = [
|
||
'Accounts' => $this->loginId,
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
$result = doFormCurl($this->createUrl('GetMemberInfo'), $params);
|
||
if ($result['ErrorCode'] != 0) {
|
||
throw new GameException('JiLi System Error,Please contact the administrator', 0);
|
||
}
|
||
return bcdiv($result['Data'][0]['Balance'], 100 , 2);
|
||
}
|
||
|
||
/**
|
||
* 玩家钱包转入游戏平台
|
||
* @return array|mixed|null
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
public function balanceTransferOut()
|
||
{
|
||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, $this->player->wallet->money);
|
||
}
|
||
|
||
/**
|
||
* 游戏平台转入玩家钱包
|
||
* @return array|mixed|null
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
public function balanceTransferIn()
|
||
{
|
||
$balance = $this->getBalance();
|
||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $balance);
|
||
}
|
||
|
||
/**
|
||
* 轉帳進出額度
|
||
* @param $type
|
||
* @param float $amount
|
||
* @param float $reward
|
||
* @return array|mixed|null
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
protected function setBalanceTransfer($type, float $amount = 0, float $reward = 0)
|
||
{
|
||
|
||
if ($type == 2 && $amount == 0 && $reward == 0) {
|
||
throw new GameException('转出/入金额错误', 0);
|
||
}
|
||
$params = [
|
||
'Account' => $this->loginId,
|
||
'TransactionId' => createOrderNo(),
|
||
'Amount' => $amount,
|
||
'TransferType' => $type,
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
$result = doFormCurl($this->createUrl('ExchangeTransferByAgentId'), $params);
|
||
if ($result['ErrorCode'] != 0) {
|
||
throw new GameException($result['Message'], 0);
|
||
}
|
||
if($type == 1){
|
||
$type = 2;
|
||
}else{
|
||
$type = 1;
|
||
}
|
||
// 记录玩家钱包转出转入记录
|
||
$this->createWalletTransfer($type, $amount, $reward, $result['Data']['TransactionId'] ?? '');
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 查询额度转移纪录
|
||
* @return array|mixed|Response
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
public function getTransferList(string $startTime = '', string $endTime = '', int $page = 1, int $pageSize = 10)
|
||
{
|
||
$params = [
|
||
'StartTime' => $startTime,
|
||
'EndTime' => $endTime,
|
||
'Page' => $page,
|
||
'PageLimit' => $pageSize,
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
$result = doFormCurl($this->createUrl('GetTransferRecordByTime'), $params);
|
||
if ($result['ErrorCode'] != 0) {
|
||
throw new GameException($result['Message'], 0);
|
||
}
|
||
return $result['Data'];
|
||
}
|
||
|
||
/**
|
||
* 查询一笔额度转移纪录
|
||
* @return array|mixed|Response
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
public function getTransferById(string $transactionId)
|
||
{
|
||
$params = [
|
||
'TransactionId' => $transactionId,
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
$result = doFormCurl($this->createUrl('CheckTransferByTransactionId'), $params);
|
||
if ($result['ErrorCode'] != 0) {
|
||
throw new GameException($result['Message'], 0);
|
||
}
|
||
return $result['Data'];
|
||
}
|
||
|
||
/**
|
||
* 查询游戏纪录
|
||
* @return array|mixed|Response
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
public function getGameRecordList(string $startTime = '', string $endTime = '', int $page = 1, int $pageSize = 10000, int $gameId = null)
|
||
{
|
||
$params = [
|
||
'StartTime' => $startTime,
|
||
'EndTime' => $endTime,
|
||
'Page' => $page,
|
||
'PageLimit' => $pageSize,
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
if(!empty($gameId)){
|
||
$params['GameId'] = $gameId;
|
||
}
|
||
$result = doFormCurl($this->createUrl('GetBetRecordByTime'), $params);
|
||
if ($result['ErrorCode'] != 0) {
|
||
throw new GameException($result['Message'], 0);
|
||
}
|
||
return $result['Data'];
|
||
}
|
||
|
||
/**
|
||
* 查询指定游戏记录详情
|
||
* @return array|mixed|Response
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
public function getGameRecordById(string $wagersId)
|
||
{
|
||
$params = [
|
||
'WagersId' => $wagersId,
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
$lang = locale();
|
||
$lang = Str::replace('_', '-', $lang);
|
||
$params['Lang'] = $lang;
|
||
$result = doFormCurl($this->createUrl('GetGameDetailUrl'), $params);
|
||
if ($result['ErrorCode'] != 0) {
|
||
throw new GameException($result['Message'], 0);
|
||
}
|
||
return $result['Data'];
|
||
}
|
||
|
||
/**
|
||
* 查询指定玩家游戏记录
|
||
* @return array|mixed|Response
|
||
* @throws GameException|\think\Exception
|
||
*/
|
||
public function getUserGameRecord(string $startTime = '', string $endTime = '', int $page = 1, int $pageSize = 10, int $gameId = null, int $gameType = null)
|
||
{
|
||
$params = [
|
||
'StartTime' => $startTime,
|
||
'EndTime' => $endTime,
|
||
'Page' => $page,
|
||
'PageLimit' => $pageSize,
|
||
'Account' => $this->loginId,
|
||
'AgentId' => $this->appId
|
||
];
|
||
$signature = $this->createSign($params);
|
||
$params['Key'] = $signature;
|
||
if(!empty($gameId)){
|
||
$params['GameId'] = $gameId;
|
||
}
|
||
if(!empty($gameType)){
|
||
$params['GameType'] = $gameType;
|
||
}
|
||
$lang = locale();
|
||
$lang = Str::replace('_', '-', $lang);
|
||
$params['Lang'] = $lang;
|
||
$result = doFormCurl($this->createUrl('GetUserBetRecordByTime'), $params);
|
||
if ($result['ErrorCode'] != 0) {
|
||
throw new GameException($result['Message'], 0);
|
||
}
|
||
return $result['Data'];
|
||
}
|
||
|
||
/**
|
||
* 查询玩家游戏记录
|
||
* @param string $startTime
|
||
* @param string $endTime
|
||
* @return array
|
||
*/
|
||
public function handleOrderHistories(string $startTime = '', string $endTime = ''): array
|
||
{
|
||
try {
|
||
$page = 1;
|
||
$list = [];
|
||
$timezone = new DateTimeZone('Etc/GMT+4');
|
||
$start = new DateTime('-6 minutes', $timezone);
|
||
$end = new DateTime('-5 minutes', $timezone);
|
||
$startTime = $start->format('Y-m-d\TH:i:s');
|
||
$endTime = $end->format('Y-m-d\TH:i:s');
|
||
$data = $this->getGameRecordList($startTime, $endTime, $page);
|
||
if (!empty($data['Result'])) {
|
||
$total = $data['Pagination']['TotalNumber'] ?? 0;
|
||
if ($total > 0) {
|
||
$pageSize = 10000;
|
||
if (!empty($data['Result'])) {
|
||
foreach ($data['Result'] as $item) {
|
||
$list[] = [
|
||
'uuid' => $item['Account'],
|
||
'platform_id' => $this->platform->id,
|
||
'game_code' => $item['GameId'],
|
||
'bet' => abs(bcdiv($item['Turnover'], 100, 2)),
|
||
'win' => bcdiv($item['PayoffAmount'],100, 2),
|
||
'order_no' => $item['WagersId'],
|
||
'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE),
|
||
'platform_action_at' => date('Y-m-d H:i:s', strtotime($item['SettlementTime'])),
|
||
'game_type' => $item['GameCategoryId'],
|
||
'created_at' => date('Y-m-d H:i:s'),
|
||
'updated_at' => date('Y-m-d H:i:s'),
|
||
];
|
||
|
||
}
|
||
}
|
||
if ($total > $pageSize) {
|
||
$totalPages = ceil($total / $pageSize);
|
||
for ($page = 2; $page <= $totalPages; $page++) {
|
||
$nextData = $this->getGameRecordList($startTime,$endTime,$page);
|
||
if (!empty($nextData['Result'])) {
|
||
foreach ($nextData['Result'] as $item) {
|
||
$list[] = [
|
||
'uuid' => $item['Account'],
|
||
'platform_id' => $this->platform->id,
|
||
'game_code' => $item['GameId'],
|
||
'bet' => abs(bcdiv($item['Turnover'], 100, 2)),
|
||
'win' => bcdiv($item['PayoffAmount'],100, 2),
|
||
'order_no' => $item['WagersId'],
|
||
'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE),
|
||
'platform_action_at' => date('Y-m-d H:i:s', strtotime($item['SettlementTime'])),
|
||
'game_type' => $item['GameCategoryId'],
|
||
'created_at' => date('Y-m-d H:i:s'),
|
||
'updated_at' => date('Y-m-d H:i:s'),
|
||
];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} catch (Exception $e) {
|
||
return [];
|
||
}
|
||
|
||
return $list;
|
||
}
|
||
|
||
} |