初始化
This commit is contained in:
240
app/api/controller/v1/GameController.php
Normal file
240
app/api/controller/v1/GameController.php
Normal file
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller\v1;
|
||||
|
||||
use addons\webman\model\DrawRecord;
|
||||
use addons\webman\model\Game;
|
||||
use addons\webman\model\GamePlatform;
|
||||
use addons\webman\model\Prize;
|
||||
use app\exception\GameException;
|
||||
use app\exception\PlayerCheckException;
|
||||
use app\service\DrawService;
|
||||
use app\service\game\GameServiceFactory;
|
||||
use Illuminate\Support\Str;
|
||||
use Respect\Validation\Exceptions\AllOfException;
|
||||
use Respect\Validation\Validator as v;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
|
||||
class GameController
|
||||
{
|
||||
/** 排除验签 */
|
||||
protected $noNeedSign = ['gametest'];
|
||||
|
||||
/**
|
||||
* 登录游戏返回游戏地址
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function loginGame(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$validator = v::key('platform_id', v::notEmpty()->intVal()->setName(trans('platform_id', [], 'message')))
|
||||
->key('game_code', v::stringVal()->setName(trans('game_code', [], 'message')))
|
||||
->key('app_type', v::notEmpty()->intVal()->in([
|
||||
GameServiceFactory::DEVICE_TYPE_WEB,
|
||||
GameServiceFactory::DEVICE_TYPE_IOS,
|
||||
GameServiceFactory::DEVICE_TYPE_ANDROID,
|
||||
])->setName(trans('app_type', [], 'message')));
|
||||
|
||||
$data = $request->all();
|
||||
/** @var GamePlatform $gamePlatform */
|
||||
$gamePlatform = GamePlatform::query()->find($data['platform_id']);
|
||||
if (empty($gamePlatform)) {
|
||||
return jsonFailResponse(trans('game_platform_not_found', [], 'message'));
|
||||
}
|
||||
if ($gamePlatform->status == 0) {
|
||||
return jsonFailResponse(trans('game_platform_disabled', [], 'message'));
|
||||
}
|
||||
/** @var Game $game */
|
||||
$game = Game::query()
|
||||
->whereHas('gamePlatform', function ($query) {
|
||||
$query->where('status', 1)->whereNull('deleted_at');
|
||||
})
|
||||
->where('platform_id', $data['platform_id'])
|
||||
->where('game_code', $data['game_code'])
|
||||
->first();
|
||||
if (empty($game)) {
|
||||
return jsonFailResponse(trans('game_not_found', [], 'message'));
|
||||
}
|
||||
if ($game->status == 0) {
|
||||
return jsonFailResponse(trans('game_disabled', [], 'message'));
|
||||
}
|
||||
$lang = locale();
|
||||
$lang = Str::replace('_', '-', $lang);
|
||||
try {
|
||||
$validator->assert($data);
|
||||
$res = GameServiceFactory::createService(strtoupper($gamePlatform->name), $player)->login(
|
||||
[
|
||||
'CallBackUrl' => '',
|
||||
'lang' => $lang,
|
||||
'gameCode' => $game->game_code,
|
||||
'appType' => $data['app_type'],
|
||||
'platformGameType' => $game->platform_game_type
|
||||
]
|
||||
);
|
||||
if ($player->wallet->money > 0) {
|
||||
GameServiceFactory::createService(strtoupper($gamePlatform->name), $player)->balanceTransferOut();
|
||||
}
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
} catch (\Exception $e) {
|
||||
return jsonFailResponse($e->getMessage());
|
||||
}
|
||||
if ($gamePlatform->name == 'MEGA888') {
|
||||
$response = [
|
||||
'link_game' => $res['url'],
|
||||
'jump_url' => 'lobbymegarelease://',
|
||||
'jump_url_android' => 'lobbymegarelease://?account='.$res['account'].'&password='.$res['password'],
|
||||
'jump_url_ios' => 'lobbymegarelease://account='.$res['account'].'&password='.$res['password'],
|
||||
'account' => $res['account'],
|
||||
'password' => $res['password'],
|
||||
];
|
||||
} elseif ($gamePlatform->name == 'KISS918') {
|
||||
$response = [
|
||||
'link_game' => $res['url'],
|
||||
'jump_url_android' => 'lobbykiss://lobbykiss?account='.$res['account'].'&password='.$res['password'],
|
||||
'jump_url_ios' => 'lobbykissgame://account='.$res['account'].'&password='.$res['password'],
|
||||
'account' => $res['account'],
|
||||
'password' => $res['password'],
|
||||
];
|
||||
} else {
|
||||
$response = ['link_game' => $res];
|
||||
}
|
||||
return jsonSuccessResponse('success',$response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 游戏列表
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function gameList(Request $request): Response
|
||||
{
|
||||
checkPlayer();
|
||||
$validator = v::key('game_type', v::notEmpty()->intVal()->setName(trans('game_type', [], 'message')), false)
|
||||
->key('is_hot', v::optional(v::in([0, 1]))->setName(trans('is_hot', [], 'message')), false);
|
||||
|
||||
$data = $request->all();
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
$size = $data['size'] ?? 20;
|
||||
$query = Game::query()
|
||||
->with(['gamePlatform' => function ($query) {
|
||||
$query->select(['id', 'name', 'status']);
|
||||
}])
|
||||
->whereHas('gamePlatform', function ($query) {
|
||||
$query->where('status', 1)->whereNull('deleted_at');
|
||||
})
|
||||
->where('status', 1)
|
||||
->where('is_online', 1)
|
||||
->when(!empty($data['game_type']), function ($query) use ($data) {
|
||||
$query->where('game_type', $data['game_type']);
|
||||
})
|
||||
->when(isset($data['is_hot']) && is_numeric($data['is_hot']), function ($query) use ($data) {
|
||||
$query->where('is_hot', $data['is_hot']);
|
||||
})
|
||||
->when(isset($data['platform_id']) && is_numeric($data['platform_id']), function ($query) use ($data) {
|
||||
$query->where('platform_id', $data['platform_id']);
|
||||
});
|
||||
$list = $query->select(['id', 'platform_id', 'game_code', 'game_type', 'game_image', 'name', 'status', 'player_num_range', 'is_hot', 'is_new', 'sort'])
|
||||
->forPage($data['page'] ?? 1, $size)
|
||||
->orderBy('sort', 'desc')
|
||||
->orderBy('id', 'desc')
|
||||
->get();
|
||||
$totalGames = $query->count();
|
||||
/** @var Game $game */
|
||||
foreach ($list as $game) {
|
||||
$game->player_num_range = empty($game->player_num_range) ? 0 : getGamePlayerNum($game->id, $game->player_num_range);
|
||||
}
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'list' => $list,
|
||||
'game_platform' => GamePlatform::query()->where('status', 1)->select(['id', 'title'])->get(),
|
||||
'current_page' => $data['page'] ?? 1,
|
||||
'total_page' => ceil($totalGames / $size)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 奖品列表
|
||||
*/
|
||||
public function getPrizeList(Request $request)
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$prizes = Prize::query()
|
||||
->select('pic', 'name', 'id', 'type')
|
||||
->where('department_id', $player->department_id)
|
||||
->where('status', 1)
|
||||
->orderBy('probability')
|
||||
->get()
|
||||
->toArray();
|
||||
$data = [
|
||||
'point' => $player->wallet->money,
|
||||
'description' => Game::query()->where('id', $player->channel->game_id)->value('description'),
|
||||
'prize_list' => $prizes,
|
||||
];
|
||||
return jsonSuccessResponse('success',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 抽奖
|
||||
*/
|
||||
public function lottery(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
if ($player->wallet->money <= 0) {
|
||||
return jsonFailResponse('玩家暂无抽奖机会', [], 1000);
|
||||
}
|
||||
$drawService = new DrawService();
|
||||
$result = $drawService->execute($player, $player->channel->game_id, $player->department_id, $request->getRealIp());
|
||||
return jsonSuccessResponse('success',$result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 抽奖记录
|
||||
*/
|
||||
public function getDrawRecords(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
|
||||
->key('size', v::intVal()->setName(trans('size', [], 'message')))
|
||||
->key('start_date', v::stringVal()->setName(trans('start_date', [], 'message')))
|
||||
->key('end_date', v::stringVal()->setName(trans('end_date', [], 'message')));
|
||||
$data = $request->all();
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
$size = $data['size'] ?? 20;
|
||||
|
||||
$query = DrawRecord::query()
|
||||
->where('department_id', $player->department_id)
|
||||
->where('uid', $player->id)
|
||||
->where('game_id', $player->channel->game_id)
|
||||
->whereBetween('created_at', [$data['start_date'],date('Y-m-d', strtotime("{$data['end_date']} +1 days"))]);
|
||||
$record = clone $query;
|
||||
$list = $query
|
||||
->select('consume', 'prize_pic', 'prize_name', 'prize_type', 'draw_time', 'ip')
|
||||
->forPage($data['page'] ?? 1, $data['size'] ?? 10)
|
||||
->orderBy('id', 'desc')
|
||||
->get()
|
||||
->toArray();
|
||||
$totalRecords = $record->count();
|
||||
return jsonSuccessResponse('success', [
|
||||
'list' => $list,
|
||||
'total_page' => ceil($totalRecords / $size)
|
||||
]);
|
||||
}
|
||||
|
||||
public function gametest(Request $request): Response
|
||||
{
|
||||
return jsonSuccessResponse('', []);
|
||||
}
|
||||
}
|
||||
751
app/api/controller/v1/IndexController.php
Normal file
751
app/api/controller/v1/IndexController.php
Normal file
@@ -0,0 +1,751 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller\v1;
|
||||
|
||||
use addons\webman\model\Activity;
|
||||
use addons\webman\model\ActivityContent;
|
||||
use addons\webman\model\BankList;
|
||||
use addons\webman\model\Broadcast;
|
||||
use addons\webman\model\Channel;
|
||||
use addons\webman\model\ChannelRechargeSetting;
|
||||
use addons\webman\model\Currency;
|
||||
use addons\webman\model\Notice;
|
||||
use addons\webman\model\PlayerBank;
|
||||
use addons\webman\model\PlayerDeliveryRecord;
|
||||
use addons\webman\model\PlayerRechargeRecord;
|
||||
use addons\webman\model\PlayerWalletTransfer;
|
||||
use addons\webman\model\PlayerWithdrawRecord;
|
||||
use app\exception\GameException;
|
||||
use app\exception\PlayerCheckException;
|
||||
use Exception;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
use Respect\Validation\Exceptions\AllOfException;
|
||||
use Respect\Validation\Validator as v;
|
||||
use support\Db;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use Tinywan\Jwt\JwtToken;
|
||||
|
||||
class IndexController
|
||||
{
|
||||
/** 排除验签 */
|
||||
protected $noNeedSign = [];
|
||||
|
||||
/**
|
||||
* 登出接口
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function logout(): Response
|
||||
{
|
||||
checkPlayer();
|
||||
if (JwtToken::clear()) {
|
||||
return jsonSuccessResponse('success');
|
||||
}
|
||||
|
||||
return jsonFailResponse(trans('logout_failed', [], 'message'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加银行卡
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws GameException
|
||||
* @throws PlayerCheckException
|
||||
*/
|
||||
public function addBankCard(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('bank_name', v::optional(v::stringType()->length(1, 100)->setName(trans('bank_name', [], 'message'))))
|
||||
->key('account', v::optional(v::stringType()->length(1, 255)->setName(trans('bank_account', [], 'message'))))
|
||||
->key('account_name', v::optional(v::stringType()->length(1, 100)->setName(trans('bank_account_name', [], 'message'))))
|
||||
->key('bank_code', v::optional(v::stringType()->length(1, 100)->setName(trans('bank_code', [], 'message'))))
|
||||
->key('wallet_address', v::optional(v::stringType()->length(1, 255)->setName(trans('wallet_address', [], 'message'))))
|
||||
->key('qr_code', v::optional(v::stringType()->setName(trans('qr_code', [], 'message'))));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
if (!empty($data['account']) && PlayerBank::query()->where('account', $data['account'])
|
||||
->where('pay_type', $player->channel->pay_type)->exists()) {
|
||||
return jsonFailResponse(trans('bank_card_has_bind', [], 'message'));
|
||||
}
|
||||
$payType = $player->channel->pay_type;
|
||||
|
||||
//USDT判断
|
||||
if (!empty($data['wallet_address'])) {
|
||||
$payType = 4;
|
||||
if (PlayerBank::query()->where('wallet_address', $data['wallet_address'])->where('pay_type', 4)->exists()) {
|
||||
return jsonFailResponse(trans('bank_card_has_bind', [], 'message'));
|
||||
}
|
||||
}
|
||||
$bankNum = PlayerBank::query()
|
||||
->where('player_id', $player->id)
|
||||
->where('status', 1)
|
||||
->where('pay_type', $player->channel->pay_type)
|
||||
->count();
|
||||
if ($bankNum > 2) {
|
||||
return jsonFailResponse(trans('bank_card_max_three', [], 'message'));
|
||||
}
|
||||
$playerBank = new PlayerBank();
|
||||
$playerBank->player_id = $player->id;
|
||||
$playerBank->bank_name = $data['bank_name'];
|
||||
$playerBank->account = $data['account'];
|
||||
$playerBank->account_name = $data['account_name'];
|
||||
$playerBank->wallet_address = $data['wallet_address'] ?? '';
|
||||
$playerBank->qr_code = $data['qr_code'] ?? '';
|
||||
$playerBank->bank_code = $data['bank_code'];
|
||||
$playerBank->pay_type = $payType;
|
||||
if (!$playerBank->save()) {
|
||||
return jsonFailResponse(trans('add_bank_card_fail', [], 'message'));
|
||||
}
|
||||
|
||||
return jsonSuccessResponse(trans('add_bank_card_success', [], 'message'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改银行卡
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws GameException
|
||||
* @throws PlayerCheckException
|
||||
*/
|
||||
public function editBankCard(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('bank_name', v::notEmpty()->stringType()->length(1, 100)->setName(trans('bank_name', [], 'message')))
|
||||
->key('account_name', v::notEmpty()->stringType()->length(1, 100)->setName(trans('bank_account_name', [], 'message')))
|
||||
->key('bank_code', v::notEmpty()->stringType()->length(1, 100)->setName(trans('bank_code', [], 'message')))
|
||||
->key('id', v::notEmpty()->stringType()->length(1, 100)->setName(trans('id', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
if (PlayerBank::query()->where('player_id', $player->id)->where('status', 1)->count() > 2) {
|
||||
return jsonFailResponse(trans('bank_card_max_three', [], 'message'));
|
||||
}
|
||||
$playerBank = PlayerBank::query()->find($data['id']);
|
||||
if ($playerBank->player_id != $player->id) {
|
||||
return jsonFailResponse(trans('edit_bank_card_fail', [], 'message'));
|
||||
}
|
||||
$playerBank->bank_name = $data['bank_name'];
|
||||
$playerBank->account = $data['account'];
|
||||
$playerBank->account_name = $data['account_name'];
|
||||
$playerBank->bank_code = $data['bank_code'];
|
||||
if (!$playerBank->save()) {
|
||||
return jsonFailResponse(trans('edit_bank_card_fail', [], 'message'));
|
||||
}
|
||||
return jsonSuccessResponse(trans('edit_bank_card_success', [], 'message'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 银行卡列表
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function bankCardList(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
|
||||
->key('size', v::intVal()->setName(trans('size', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'bank_list' => PlayerBank::query()
|
||||
->where('player_id', $player->id)
|
||||
->where('status', 1)
|
||||
->where('pay_type', $player->channel->pay_type)
|
||||
->whereNull('deleted_at')
|
||||
->select(['id', 'bank_name', 'account', 'account_name'])
|
||||
->forPage($data['page'] ?? 1, $data['size'] ?? 10)
|
||||
->orderBy('created_at', 'desc')
|
||||
->get()
|
||||
->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 银行卡列表
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException|\think\Exception
|
||||
*/
|
||||
public function bankList(): Response
|
||||
{
|
||||
$player = checkPlayer(false);
|
||||
return jsonSuccessResponse('success', [
|
||||
'bank_list' => BankList::query()
|
||||
->select(['bank_name', 'bank_code'])
|
||||
->where('pay_type', $player->channel->pay_type)
|
||||
->where('type', '!=', 1)
|
||||
->whereNull('deleted_at')
|
||||
->get()
|
||||
->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除银行卡
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function deleteBankCard(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('id', v::intVal()->notEmpty()->setName(trans('bank_card_id', [], 'message')));
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
|
||||
$bankCard = PlayerBank::withTrashed()->where('player_id', $player->id)->where('id', $data['id'])->first();
|
||||
if (!$bankCard) {
|
||||
return jsonFailResponse(trans('bank_card_not_found', [], 'message'));
|
||||
}
|
||||
if ($bankCard->status == 0) {
|
||||
return jsonFailResponse(trans('bank_card_disabled', [], 'message'));
|
||||
}
|
||||
if (!empty($bankCard->deleted_at)) {
|
||||
return jsonFailResponse(trans('bank_card_deleted', [], 'message'));
|
||||
}
|
||||
$bankCard->delete();
|
||||
|
||||
return jsonSuccessResponse(trans('success', [], 'message'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传支付凭证
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws GameException
|
||||
* @throws PlayerCheckException
|
||||
*/
|
||||
public function uploadCertificate(Request $request): Response
|
||||
{
|
||||
checkPlayer();
|
||||
$file = $request->file('certificate');
|
||||
$filePath = '';
|
||||
if ($file && $file->isValid()) {
|
||||
if ($file->getSize() > 3 * 1024 * 1024) {
|
||||
return jsonFailResponse(trans('image_upload_size_fail', ['{size}' => '3M'], 'message'));
|
||||
}
|
||||
$allowedExtensions = ['png', 'jpg', 'jpeg'];
|
||||
$extension = $file->getUploadExtension();
|
||||
if (!in_array($extension, $allowedExtensions)) {
|
||||
return jsonFailResponse(trans('image_upload_fail', [], 'message'));
|
||||
}
|
||||
$savePath = '/storage/certificate/' . date("Ymd", time()) . "/";
|
||||
$newPath = public_path() . $savePath;
|
||||
if (!file_exists($newPath)) {
|
||||
//检查是否有该文件夹,如果没有就创建,并给予最高权限
|
||||
mkdir($newPath, 0755, true);
|
||||
}
|
||||
$extension = $file->getUploadExtension();
|
||||
$filename = time() . '_' . uniqid() . ".{$extension}"; //文件名
|
||||
$newPath = $newPath . $filename;
|
||||
$file->move($newPath);
|
||||
$filePath = env('APP_URL', 'http://127.0.0.1:8787') . $savePath . $filename;
|
||||
}
|
||||
if (!$filePath) {
|
||||
return jsonFailResponse(trans('failed_to_upload_recharge_voucher', [], 'message'));
|
||||
}
|
||||
|
||||
return jsonSuccessResponse('success', ['file_path' => $filePath]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家充值
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function playerRecharge(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('id', v::notEmpty()->intVal()->setName(trans('recharge_setting_id', [], 'message')))
|
||||
->key('certificate', v::notEmpty()->url()->notEmpty()->setName(trans('certificate', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
|
||||
$rechargeRecord = PlayerRechargeRecord::where('player_id', $player->id)
|
||||
->where('status', PlayerRechargeRecord::STATUS_WAIT)
|
||||
->where('type', PlayerRechargeRecord::TYPE_REGULAR)
|
||||
->first();
|
||||
if (!empty($rechargeRecord)) {
|
||||
return jsonFailResponse(trans('has_not_unfinished_recharge', [], 'message'));
|
||||
}
|
||||
/** @var Channel $channel */
|
||||
$channel = Channel::where('department_id', $player->department_id)->first();
|
||||
if (empty($channel)) {
|
||||
return jsonFailResponse(trans('channel_not_found', [], 'message'));
|
||||
}
|
||||
if ($channel->recharge_status == 0) {
|
||||
return jsonFailResponse(trans('recharge_closed', [], 'message'));
|
||||
}
|
||||
$lang = locale();
|
||||
$lang = Str::replace('_', '-', $lang);
|
||||
/** @var ChannelRechargeSetting $channelRechargeSetting */
|
||||
$channelRechargeSetting = ChannelRechargeSetting::with(['channel_recharge_method' => function ($query) use ($lang) {
|
||||
$query->select(['id', 'account', 'currency'])->with(['methodLang' => function ($query) use ($lang) {
|
||||
$query->select(['id', 'bank_name', 'sub_bank', 'owner', 'name', 'method_id', 'lang'])->where('lang', $lang);
|
||||
}]);
|
||||
}])->whereHas('channel_recharge_method', function ($query) {
|
||||
$query->whereNull('deleted_at')->where('status', 1);
|
||||
})
|
||||
->where('department_id', $player->department_id)
|
||||
->where('status', 1)
|
||||
->where('id', $data['id'])
|
||||
->whereNull('deleted_at')
|
||||
->first();
|
||||
if (empty($channelRechargeSetting)) {
|
||||
return jsonFailResponse(trans('channel_recharge_setting_not_found', [], 'message'));
|
||||
}
|
||||
try {
|
||||
$allCoins = bcadd($channelRechargeSetting->coins_num, $channelRechargeSetting->gift_coins, 2);
|
||||
// 生成充值订单
|
||||
$playerRechargeRecord = new PlayerRechargeRecord();
|
||||
$playerRechargeRecord->player_id = $player->id;
|
||||
$playerRechargeRecord->department_id = $player->department_id;
|
||||
$playerRechargeRecord->tradeno = createOrderNo();
|
||||
$playerRechargeRecord->player_name = $player->name ?? '';
|
||||
$playerRechargeRecord->money = $channelRechargeSetting->money;
|
||||
$playerRechargeRecord->inmoney = $channelRechargeSetting->money;
|
||||
$playerRechargeRecord->setting_id = $channelRechargeSetting->id;
|
||||
$playerRechargeRecord->coins = $channelRechargeSetting->coins_num;
|
||||
$playerRechargeRecord->gift_coins = $channelRechargeSetting->gift_coins;
|
||||
$playerRechargeRecord->currency = $channelRechargeSetting->channel_recharge_method->currency;
|
||||
$playerRechargeRecord->type = $channelRechargeSetting->type;
|
||||
$playerRechargeRecord->status = PlayerRechargeRecord::STATUS_RECHARGING;
|
||||
$playerRechargeRecord->certificate = $data['certificate'] ?? '';
|
||||
$playerRechargeRecord->bank_name = $channelRechargeSetting->channel_recharge_method->methodLang[0]['bank_name'] ?? '';
|
||||
$playerRechargeRecord->sub_bank = $channelRechargeSetting->channel_recharge_method->methodLang[0]['sub_bank'] ?? '';
|
||||
$playerRechargeRecord->owner = $channelRechargeSetting->channel_recharge_method->methodLang[0]['owner'] ?? '';
|
||||
$playerRechargeRecord->account = $channelRechargeSetting->channel_recharge_method->account;
|
||||
$playerRechargeRecord->chip_amount = bcmul($allCoins, $channelRechargeSetting->chip_multiple, 2);
|
||||
$playerRechargeRecord->save();
|
||||
} catch (Exception $e) {
|
||||
return jsonFailResponse($e->getMessage());
|
||||
}
|
||||
|
||||
sendSocketMessage('private-admin_group-channel-' . request()->department_id, [
|
||||
'msg_type' => 'player_examine_recharge_order',
|
||||
'id' => $rechargeRecord->id,
|
||||
'player_id' => $player->id,
|
||||
'player_name' => $player->name,
|
||||
'player_phone' => $player->phone,
|
||||
'money' => $playerRechargeRecord->money,
|
||||
'status' => $playerRechargeRecord->status,
|
||||
'tradeno' => $playerRechargeRecord->tradeno,
|
||||
]);
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'tradeno' => $playerRechargeRecord->tradeno,
|
||||
'order_id' => $playerRechargeRecord->id,
|
||||
'money' => $playerRechargeRecord->money,
|
||||
'coins' => $allCoins,
|
||||
'currency' => $playerRechargeRecord->currency,
|
||||
'status' => $playerRechargeRecord->status,
|
||||
'created_at' => strtotime($playerRechargeRecord->created_at),
|
||||
'recharge_setting' => $channelRechargeSetting
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提现记录
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function cashOutList(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
|
||||
->key('size', v::intVal()->setName(trans('size', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
$size = $data['size'] ?? 10;
|
||||
$totalRecords = PlayerWithdrawRecord::query()
|
||||
->where('player_id', $player->id)
|
||||
->count();
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'list' => PlayerWithdrawRecord::where('player_id', $player->id)
|
||||
->select(['id', 'coins', 'after_coins', 'created_at', 'status'])
|
||||
->forPage($data['page'] ?? 1, $data['size'] ?? 10)
|
||||
->orderBy('created_at', 'desc')
|
||||
->get()
|
||||
->toArray(),
|
||||
'total_page' => ceil($totalRecords / $size)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家提现
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function playerWithdrawal(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('amount', v::intVal()->notEmpty()->min(100)->setName(trans('withdrawal_amount', [], 'message')))
|
||||
->key('bank_id', v::intVal()->setName(trans('withdrawal_bank', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
/** @var Channel $channel */
|
||||
$channel = Channel::where('department_id', $player->department_id)->first();
|
||||
if ($player->status_withdraw != 1) {
|
||||
return jsonFailResponse(trans('player_withdraw_closed', [], 'message'));
|
||||
}
|
||||
if ($player->wallet->money < $data['amount']) {
|
||||
return jsonFailResponse(trans('insufficient_balance', [], 'message'));
|
||||
}
|
||||
if ($channel->withdraw_status == 0) {
|
||||
return jsonFailResponse(trans('self_withdraw_closed', [], 'message'));
|
||||
}
|
||||
if (empty($data['bank_id'])) {
|
||||
return jsonFailResponse(trans('please_select_player_bank', [], 'message'));
|
||||
}
|
||||
/** @var Currency $currency */
|
||||
$currency = Currency::where('identifying', $channel->currency)->where('status', 1)->whereNull('deleted_at')->first();
|
||||
if (empty($currency)) {
|
||||
return jsonFailResponse(trans('currency_no_setting', [], 'message'));
|
||||
}
|
||||
/** @var PlayerBank $playerBank */
|
||||
$playerBank = PlayerBank::where('id', $data['bank_id'])->where('player_id', $player->id)->where('status', 1)->whereNull('deleted_at')->first();
|
||||
if (empty($playerBank)) {
|
||||
return jsonFailResponse(trans('player_bank_not_found', [], 'message'));
|
||||
}
|
||||
if ($player->must_chip_amount > $player->chip_amount) {
|
||||
return jsonFailResponse(trans('must_chip_amount_incomplete', [], 'message'));
|
||||
}
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$money = bcdiv($data['amount'], $currency->ratio, 2);
|
||||
// 生成订单
|
||||
$playerWithdrawRecord = new PlayerWithdrawRecord();
|
||||
$beforeGameAmount = $player->wallet->money;
|
||||
// 玩家钱包扣减
|
||||
$player->wallet->money = bcsub($player->wallet->money, $data['amount'], 2);
|
||||
$playerWithdrawRecord->player_id = $player->id;
|
||||
$playerWithdrawRecord->department_id = $player->department_id;
|
||||
$playerWithdrawRecord->tradeno = createOrderNo();
|
||||
$playerWithdrawRecord->player_name = $player->name ?? '';
|
||||
$playerWithdrawRecord->player_phone = $player->phone ?? '';
|
||||
$playerWithdrawRecord->money = $money;
|
||||
$playerWithdrawRecord->coins = $data['amount'];
|
||||
$playerWithdrawRecord->after_coins = $player->wallet->money;
|
||||
$playerWithdrawRecord->fee = 0;
|
||||
$playerWithdrawRecord->inmoney = bcsub($playerWithdrawRecord->money, $playerWithdrawRecord->fee, 2); // 实际提现金额
|
||||
$playerWithdrawRecord->currency = $channel->currency;
|
||||
$playerWithdrawRecord->bank_name = $playerBank->bank_name;
|
||||
$playerWithdrawRecord->account = $playerBank->account;
|
||||
$playerWithdrawRecord->account_name = $playerBank->account_name;
|
||||
$playerWithdrawRecord->type = PlayerWithdrawRecord::TYPE_SELF;
|
||||
$playerWithdrawRecord->status = PlayerWithdrawRecord::STATUS_WAIT;
|
||||
$playerWithdrawRecord->save();
|
||||
|
||||
// 更新玩家统计
|
||||
$player->player_extend->withdraw_amount = bcadd($player->player_extend->withdraw_amount, $playerWithdrawRecord->coins, 2);
|
||||
$player->push();
|
||||
//寫入金流明細
|
||||
$playerDeliveryRecord = new PlayerDeliveryRecord;
|
||||
$playerDeliveryRecord->player_id = $playerWithdrawRecord->player_id;
|
||||
$playerDeliveryRecord->department_id = $playerWithdrawRecord->department_id;
|
||||
$playerDeliveryRecord->target = $playerWithdrawRecord->getTable();
|
||||
$playerDeliveryRecord->target_id = $playerWithdrawRecord->id;
|
||||
$playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_WITHDRAWAL;
|
||||
$playerDeliveryRecord->source = 'channel_withdrawal';
|
||||
$playerDeliveryRecord->amount = $playerWithdrawRecord->coins;
|
||||
$playerDeliveryRecord->amount_before = $beforeGameAmount;
|
||||
$playerDeliveryRecord->amount_after = $player->wallet->money;
|
||||
$playerDeliveryRecord->tradeno = $playerWithdrawRecord->tradeno ?? '';
|
||||
$playerDeliveryRecord->remark = $playerWithdrawRecord->remark ?? '';
|
||||
$playerDeliveryRecord->save();
|
||||
DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
return jsonFailResponse(trans('system_error', [], 'message') . $e->getMessage());
|
||||
}
|
||||
|
||||
$notice = new Notice();
|
||||
$notice->department_id = $playerWithdrawRecord->department_id;
|
||||
$notice->player_id = $playerWithdrawRecord->player_id;
|
||||
$notice->source_id = $playerWithdrawRecord->id;
|
||||
$notice->type = Notice::TYPE_EXAMINE_WITHDRAW;
|
||||
$notice->receiver = Notice::RECEIVER_DEPARTMENT;
|
||||
$notice->is_private = 0;
|
||||
$notice->title = '渠道提现待审核';
|
||||
$notice->content = '提现订单待审核,玩家' . (empty($playerWithdrawRecord->player_name) ? $playerWithdrawRecord->player_name : $playerWithdrawRecord->player_phone) . ', 提现游戏点: ' . $playerWithdrawRecord->point . ' 提现金额: ' . $playerWithdrawRecord->money;
|
||||
$notice->save();
|
||||
|
||||
if ($playerWithdrawRecord->status == PlayerWithdrawRecord::STATUS_FAIL) {
|
||||
return jsonFailResponse(trans('withdraw_fail', [], 'message'));
|
||||
}
|
||||
sendSocketMessage('private-admin_group-channel-' . $channel->department_id, [
|
||||
'msg_type' => 'player_create_withdraw_order',
|
||||
'id' => $playerWithdrawRecord->id,
|
||||
'player_id' => $player->id,
|
||||
'player_name' => $player->name,
|
||||
'player_phone' => $player->phone,
|
||||
'money' => $playerWithdrawRecord->money,
|
||||
'status' => $playerWithdrawRecord->status,
|
||||
'tradeno' => $playerWithdrawRecord->tradeno,
|
||||
]);
|
||||
return jsonSuccessResponse('success', [
|
||||
'tradeno' => $playerWithdrawRecord->tradeno,
|
||||
'order_id' => $playerWithdrawRecord->id,
|
||||
'money' => $playerWithdrawRecord->money,
|
||||
'currency' => $playerWithdrawRecord->currency,
|
||||
'status' => $playerWithdrawRecord->status,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页活动
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function homeActivity(): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$list = Activity::query()
|
||||
->where('department_id', $player->department_id)
|
||||
->where('status', 1)
|
||||
->limit(3)
|
||||
->orderBy('sort', 'desc')
|
||||
->get();
|
||||
|
||||
$lang = locale();
|
||||
$lang = Str::replace('_', '-', $lang);
|
||||
$activityList = [];
|
||||
/** @var Activity $activity */
|
||||
foreach ($list as $activity) {
|
||||
/** @var ActivityContent $activityContent */
|
||||
$activityContent = $activity->activity_content->where('lang', $lang)->first();
|
||||
if ($activity->type == Activity::TYPE_CUSTOM) {
|
||||
if (strtotime($activity->start_time) > time() || strtotime($activity->end_time) < time()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ($activity->type == Activity::TYPE_CYCLE) {
|
||||
if ($activity->cycle_type == 'Week' && $activity->cycle_data != Carbon::now()->dayOfWeek) {
|
||||
continue;
|
||||
}
|
||||
if ($activity->cycle_type == 'Month' && $activity->cycle_data != Carbon::now()->day) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$activityList[] = [
|
||||
'id' => $activity->id,
|
||||
'start_time' => $activity->start_time,
|
||||
'end_time' => $activity->end_time,
|
||||
'name' => $activityContent->name ?? '',
|
||||
'lang' => $activityContent->lang,
|
||||
'picture' => $activityContent->picture ?? '',
|
||||
'recharge_id' => $activity->recharge_id,
|
||||
'method_id' => $activity->channelRechargeSetting->method_id,
|
||||
];
|
||||
}
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'list' => $activityList,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* cash in记录
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function cashInList(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
|
||||
->key('size', v::intVal()->setName(trans('size', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
$size = $data['size'] ?? 10;
|
||||
$totalRecords = PlayerRechargeRecord::query()
|
||||
->where('player_id', $player->id)
|
||||
->count();
|
||||
$list = PlayerRechargeRecord::leftJoin('player_delivery_record as pdr',function ($join){
|
||||
$join->on( 'pdr.target_id', '=', 'player_recharge_record.id')
|
||||
->where('pdr.type', '=', PlayerDeliveryRecord::TYPE_RECHARGE);
|
||||
})->where('player_recharge_record.player_id', $player->id)
|
||||
->select(['player_recharge_record.id', 'player_recharge_record.status', 'player_recharge_record.coins', 'pdr.amount_after', 'player_recharge_record.created_at'])
|
||||
->forPage($data['page'] ?? 1, $data['size'] ?? 10)
|
||||
->orderBy('player_recharge_record.created_at', 'desc')
|
||||
->get()
|
||||
->toArray();
|
||||
foreach ($list as &$item) {
|
||||
$item['created_at'] = Carbon::parse($item['created_at'])->format('Y/m/d H:i');
|
||||
$item['amount_after'] = round($item['amount_after'], 2);
|
||||
}
|
||||
return jsonSuccessResponse('success', [
|
||||
'list' => $list,
|
||||
'total_page' => ceil($totalRecords / $size)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息列表
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function noticeList(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
|
||||
->key('size', v::intVal()->setName(trans('size', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
$noticeList = Notice::query()
|
||||
->leftJoin('player_withdraw_record', 'player_withdraw_record.id', '=', 'notice.source_id')
|
||||
->select(['notice.id', 'notice.player_id', 'notice.title', 'notice.type', 'notice.content', 'notice.created_at', 'player_withdraw_record.status', 'player_withdraw_record.money'])
|
||||
->where('notice.player_id', $player->id)
|
||||
->where('notice.receiver', Notice::RECEIVER_PLAYER)
|
||||
->where('notice.is_private', 1)
|
||||
->whereNull('notice.deleted_at')
|
||||
->forPage($data['page'], $data['size'])
|
||||
->orderBy('notice.status', 'asc')
|
||||
->orderBy('notice.id', 'desc')
|
||||
->get();
|
||||
foreach ($noticeList as &$item) {
|
||||
$item['title'] = trans('title.' . $item->type.'.'.$item->status,
|
||||
['{point}' => $item->money],
|
||||
'notice');
|
||||
$item['content'] = trans('content.' . $item->type.'.'.$item->status,
|
||||
['{point}' => $item->money],
|
||||
'notice');
|
||||
}
|
||||
// 更新为已读状态
|
||||
Notice::where('status', 0)
|
||||
->where('receiver', Notice::RECEIVER_PLAYER)
|
||||
->where('is_private', 1)
|
||||
->where('player_id', $player->id)
|
||||
->whereNull('deleted_at')
|
||||
->update([
|
||||
'status' => 1
|
||||
]);
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'list' => $noticeList
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 渠道信息
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function channelInfo(): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
return jsonSuccessResponse('success', [
|
||||
'channel_info' => Channel::query()
|
||||
->where('department_id', $player->department_id)
|
||||
->first(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提现记录
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function withdrawList(Request $request): Response
|
||||
{
|
||||
checkPlayer();
|
||||
$date = date('Y-m-d');
|
||||
$list = PlayerWithdrawRecord::with('player:id,uuid,phone')
|
||||
->where('status', 2)
|
||||
->whereDate('finish_time', $date)
|
||||
->select(['money', 'player_id', 'updated_at'])
|
||||
->orderBy('finish_time', 'desc')
|
||||
->get()
|
||||
->toArray();
|
||||
foreach ($list as &$item) {
|
||||
$PlayerWalletTransfer = PlayerWalletTransfer::query()->where('player_id', $item['player_id'])
|
||||
->where('type', PlayerWalletTransfer::TYPE_IN)
|
||||
->where('created_at', '<=', $item['updated_at'])
|
||||
->orderBy('id', 'desc')
|
||||
->first();
|
||||
$item['game'] = $PlayerWalletTransfer->gamePlatform->title;
|
||||
}
|
||||
unset($item);
|
||||
$copyList = [];
|
||||
$broadcast = Broadcast::query()
|
||||
->select('title','num','phone','updated_at')
|
||||
->where('status', 1)
|
||||
->where('type', 1)
|
||||
->wheredate('date', $date)
|
||||
->get()
|
||||
->toArray();
|
||||
foreach ($broadcast as $item) {
|
||||
$copyList[] = [
|
||||
'money' => $item['num'],
|
||||
'player_id' => 0,
|
||||
'updated_at' => $item['updated_at'],
|
||||
'player' => [
|
||||
'id' => 0,
|
||||
'uuid' => 0,
|
||||
'phone' => $item['phone'],
|
||||
],
|
||||
'game' => $item['title']
|
||||
];
|
||||
}
|
||||
$data = array_merge($list, $copyList);
|
||||
$key = array_column($data,'updated_at');
|
||||
array_multisort($key, SORT_DESC, $data);
|
||||
return jsonSuccessResponse('success', [
|
||||
'list' => $data,
|
||||
]);
|
||||
}
|
||||
}
|
||||
1251
app/api/controller/v1/PlayerController.php
Normal file
1251
app/api/controller/v1/PlayerController.php
Normal file
@@ -0,0 +1,1251 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller\v1;
|
||||
|
||||
use addons\webman\model\BankList;
|
||||
use addons\webman\model\Channel;
|
||||
use addons\webman\model\ChannelRechargeMethod;
|
||||
use addons\webman\model\ChannelRechargeSetting;
|
||||
use addons\webman\model\Currency;
|
||||
use addons\webman\model\DrawRecord;
|
||||
use addons\webman\model\Game;
|
||||
use addons\webman\model\PlayerRechargeRecord;
|
||||
use addons\webman\model\Notice;
|
||||
use addons\webman\model\Player;
|
||||
use addons\webman\model\PlayerBank;
|
||||
use addons\webman\model\PlayerDeliveryRecord;
|
||||
use addons\webman\model\PlayerWithdrawRecord;
|
||||
use addons\webman\model\Prize;
|
||||
use addons\webman\model\SepayRecharge;
|
||||
use app\exception\PromoterCheckException;
|
||||
use app\exception\GameException;
|
||||
use app\exception\PlayerCheckException;
|
||||
use app\service\SklPayServices;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
use Respect\Validation\Exceptions\AllOfException;
|
||||
use Respect\Validation\Validator as v;
|
||||
use support\Db;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use think\Exception;
|
||||
use Tinywan\Jwt\JwtToken;
|
||||
use addons\webman\model\PhoneSmsLog;
|
||||
use support\Redis;
|
||||
use Webman\Push\PushException;
|
||||
|
||||
class PlayerController
|
||||
{
|
||||
/** 排除验签 */
|
||||
protected $noNeedSign = [];
|
||||
|
||||
/**
|
||||
* 登录接口
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function login(Request $request): Response
|
||||
{
|
||||
$validator = v::key('phone', v::stringType()->notEmpty()->setName(trans('phone', [], 'message')))
|
||||
->key('type', v::in([1, 2])->notEmpty()->setName(trans('type', [], 'message')))
|
||||
->key('code', v::stringType()->setName(trans('code', [], 'message')), false)
|
||||
->key('password', v::stringType()->setName(trans('password', [], 'message')), false);
|
||||
$data = $request->all();
|
||||
try {
|
||||
$validator->assert($data);
|
||||
//手机号规则
|
||||
if(!validateMalaysianPhoneNumber($data['phone'])){
|
||||
throw new Exception(trans('phone_val_error', [], 'message'));
|
||||
}
|
||||
$pattern = '/(\+60|60|0060)01\d{8,9}/';
|
||||
if (preg_match($pattern, $data['phone'])) {
|
||||
$data['phone'] = substr_replace($data['phone'], '601', 0, 4);
|
||||
}
|
||||
/** @var Player $player */
|
||||
$player = Player::where('phone', $data['phone'])
|
||||
->where('department_id', request()->department_id)
|
||||
->first();
|
||||
if(empty($player)){
|
||||
throw new Exception(trans('player_not_found', [], 'message'));
|
||||
}
|
||||
//密码登录
|
||||
if($data['type'] == 1){
|
||||
if(!isset($data['password']) || !password_verify($data['password'],$player->password)){
|
||||
throw new Exception(trans('password_error', [], 'message'));
|
||||
}
|
||||
}else{
|
||||
//验证码错误
|
||||
$phone_code = Redis::get(setSmsKey($data['phone'], PhoneSmsLog::TYPE_LOGIN));
|
||||
if(!$phone_code){
|
||||
throw new Exception(trans('phone_sms_expire', [], 'message'));
|
||||
}
|
||||
if(!isset($data['code']) || empty($data['code']) || $phone_code != $data['code']){
|
||||
throw new Exception(trans('phone_sms_error', [], 'message'));
|
||||
}
|
||||
}
|
||||
if ($player->status == Player::STATUS_STOP) {
|
||||
throw new Exception(trans('account_stop', [], 'message'));
|
||||
}
|
||||
$player->last_login = date('Y-m-d H:i:s');
|
||||
addLoginRecord($player->id);
|
||||
} catch (AllOfException $e) {
|
||||
throw new Exception(getValidationMessages($e));
|
||||
} catch (Exception $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'token' => JwtToken::generateToken([
|
||||
'id' => $player->id,
|
||||
'avatar' => $player->avatar,
|
||||
'name' => $player->name,
|
||||
'type' => $player->type,
|
||||
'currency' => $player->currency,
|
||||
'recommended_code' => $player->recommended_code,
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号注册
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function phoneRegister(Request $request): Response
|
||||
{
|
||||
$data = $request->all();
|
||||
$validator = v::key('phone', v::stringType()->notEmpty()->setName(trans('phone', [], 'message')))
|
||||
->key('code', v::stringType()->setName(trans('code', [], 'message')))
|
||||
->key('password', v::stringType()->setName(trans('password', [], 'message')))
|
||||
->key('confim_password', v::stringType()->setName(trans('confim_password', [], 'message')))
|
||||
->key('nickname', v::stringType()->setName(trans('nickname', [], 'message')));
|
||||
try {
|
||||
$validator->assert($data);
|
||||
//网页注册
|
||||
if(!empty($data['web_register']) && empty($data['recommended_code'])){
|
||||
throw new Exception(trans('recommend_player_not_found', [], 'message'));
|
||||
}
|
||||
//手机号规则
|
||||
if(!validateMalaysianPhoneNumber($data['phone'])){
|
||||
throw new Exception(trans('phone_val_error', [], 'message'));
|
||||
}
|
||||
$pattern = '/(\+60|60|0060)01\d{8,9}/';
|
||||
if (preg_match($pattern, $data['phone'])) {
|
||||
$data['phone'] = substr_replace($data['phone'], '601', 0, 4);
|
||||
}
|
||||
//两次密码不一致
|
||||
if($data['password'] != $data['confim_password']){
|
||||
throw new Exception(trans('confim_password_differ', [], 'message'));
|
||||
}
|
||||
//验证码错误
|
||||
$phone_code = Redis::get(setSmsKey($data['phone'], PhoneSmsLog::TYPE_REGISTER));
|
||||
if(!$phone_code){
|
||||
throw new Exception(trans('phone_sms_expire', [], 'message'));
|
||||
}
|
||||
if(!isset($data['code']) || empty($data['code']) || $phone_code != $data['code']){
|
||||
throw new Exception(trans('phone_sms_error', [], 'message'));
|
||||
}
|
||||
/** @var Player $player */
|
||||
$player = Player::where('phone', $data['phone'])
|
||||
->where('department_id', request()->department_id)
|
||||
->first();
|
||||
//手机号已被注册
|
||||
if($player){
|
||||
throw new Exception(trans('phone_has_registered', [], 'message'));
|
||||
}
|
||||
$create_player['phone'] = $data['phone'];
|
||||
$create_player['password'] = $data['password'];
|
||||
$create_player['name'] = $data['nickname'];
|
||||
$player = createPlayer(request()->department_id,$create_player);
|
||||
} catch (AllOfException $e) {
|
||||
throw new Exception(getValidationMessages($e));
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(trans('create_player_fail', [], 'message') . $e->getMessage());
|
||||
}
|
||||
return jsonSuccessResponse('success', [
|
||||
'token' => JwtToken::generateToken([
|
||||
'id' => $player->id,
|
||||
'avatar' => $player->avatar,
|
||||
'name' => $player->name,
|
||||
'type' => $player->type,
|
||||
'currency' => $player->currency,
|
||||
'recommended_code' => $player->recommended_code,
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 忘记密码
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function forgetPassword(Request $request): Response
|
||||
{
|
||||
$data = $request->all();
|
||||
$validator = v::key('phone', v::stringType()->notEmpty()->setName(trans('phone', [], 'message')))
|
||||
->key('code', v::stringType()->setName(trans('code', [], 'message')))
|
||||
->key('password', v::stringType()->setName(trans('password', [], 'message')))
|
||||
->key('confim_password', v::stringType()->setName(trans('confim_password', [], 'message')));
|
||||
try {
|
||||
$validator->assert($data);
|
||||
//手机号规则
|
||||
if(!validateMalaysianPhoneNumber($data['phone'])){
|
||||
throw new Exception(trans('phone_val_error', [], 'message'));
|
||||
}
|
||||
$pattern = '/(\+60|60|0060)01\d{8,9}/';
|
||||
if (preg_match($pattern, $data['phone'])) {
|
||||
$data['phone'] = substr_replace($data['phone'], '601', 0, 4);
|
||||
}
|
||||
//两次密码不一致
|
||||
if($data['password'] != $data['confim_password']){
|
||||
throw new Exception(trans('confim_password_differ', [], 'message'));
|
||||
}
|
||||
//验证码错误
|
||||
$phone_code = Redis::get(setSmsKey($data['phone'], PhoneSmsLog::TYPE_CHANGE_PASSWORD));
|
||||
if(!$phone_code){
|
||||
throw new Exception(trans('phone_sms_expire', [], 'message'));
|
||||
}
|
||||
if(!isset($data['code']) || empty($data['code']) || $phone_code != $data['code']){
|
||||
throw new Exception(trans('phone_sms_error', [], 'message'));
|
||||
}
|
||||
|
||||
/** @var Player $player */
|
||||
$player = Player::where('phone', $data['phone'])
|
||||
->where('department_id', request()->department_id)
|
||||
->first();
|
||||
if(empty($player)){
|
||||
throw new Exception(trans('player_not_found', [], 'message'));
|
||||
}
|
||||
$player->password = $data['password'];
|
||||
$player->push();
|
||||
} catch (AllOfException $e) {
|
||||
throw new Exception(getValidationMessages($e));
|
||||
} catch (Exception $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
return jsonSuccessResponse(trans('password_revise_suc', [], 'message'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送验证码
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function sendMsg(Request $request): Response
|
||||
{
|
||||
$data = $request->all();
|
||||
$validator = v::key('phone', v::stringType()->notEmpty()->setName(trans('phone', [], 'message')))
|
||||
->key('type', v::stringType()->setName(trans('type', [], 'message')), false);
|
||||
try {
|
||||
$validator->assert($data);
|
||||
//手机号规则
|
||||
if(!validateMalaysianPhoneNumber($data['phone'])){
|
||||
throw new Exception(trans('phone_val_error', [], 'message'));
|
||||
}
|
||||
$pattern = '/(\+60|60|0060)01\d{8,9}/';
|
||||
if (preg_match($pattern, $data['phone'])) {
|
||||
$data['phone'] = substr_replace($data['phone'], '601', 0, 4);
|
||||
}
|
||||
if ($data['type'] == 1 || $data['type'] == 3) {
|
||||
$player = Player::query()->where('phone', $data['phone'])->first();
|
||||
if(empty($player)){
|
||||
throw new Exception(trans('player_not_found', [], 'message'));
|
||||
}
|
||||
}
|
||||
$env = config('app.env');
|
||||
$config = config('sms');
|
||||
$code = ($env == 'pro' ? random_int(10000, 99999) : config('sms.default_code'));
|
||||
//发送验证码
|
||||
$params = [
|
||||
"userId" => $config['userId'],
|
||||
"account"=> $config['account'],
|
||||
"password"=> $config['password'],
|
||||
"mobile"=> $data['phone'],
|
||||
"content"=> '【Samsung88】您的验证码为'.$code.',5分钟内有效。',
|
||||
"sendTime"=> "",
|
||||
"action"=> "sendhy",
|
||||
"custom"=> "1"
|
||||
];
|
||||
$result = doCurl($config['aliwy_url'], $params);
|
||||
if($result['code'] == 200 && $result['data']['status'] == 'Success'){
|
||||
$key = setSmsKey($data['phone'], $data['type']);
|
||||
$phoneSmsLog = new PhoneSmsLog();
|
||||
$phoneSmsLog->player_id = isset($data['player_id']) ? $data['player_id'] : 0;
|
||||
$phoneSmsLog->code = $code;
|
||||
$phoneSmsLog->phone = $data['phone'];
|
||||
$phoneSmsLog->send_times = 1;
|
||||
$phoneSmsLog->type = $data['type'];
|
||||
$phoneSmsLog->expire_time = date("Y-m-d H:i:s", time() + 300);
|
||||
$phoneSmsLog->response = $result ? json_encode($result) : '';
|
||||
Redis::set($key, $code, 'EX', 300);
|
||||
$phoneSmsLog->status = 1;
|
||||
$phoneSmsLog->save();
|
||||
}else{
|
||||
throw new Exception($result['data']['message']);
|
||||
}
|
||||
} catch (AllOfException $e) {
|
||||
throw new Exception(getValidationMessages($e));
|
||||
}catch (Exception $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
return jsonSuccessResponse(trans('phone_sms_send_success', [], 'message'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws GameException
|
||||
* @throws PlayerCheckException
|
||||
*/
|
||||
public function playerInfo(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
|
||||
$prizes = Prize::query()
|
||||
->select('pic', 'name', 'id', 'type')
|
||||
->where('department_id', $player->department_id)
|
||||
->where('status', 1)
|
||||
->orderBy('probability')
|
||||
->get()
|
||||
->toArray();
|
||||
$game = Game::query()->select('description', 'game_url')->first();
|
||||
return jsonSuccessResponse('success', [
|
||||
'id' => $player->id,
|
||||
'phone' => $player->phone,
|
||||
'avatar' => $player->avatar,
|
||||
'currency' => $player->currency,
|
||||
'uuid' => $player->uuid,
|
||||
'money' => $player->wallet->money,
|
||||
'name' => $player->name,
|
||||
'recharge_amount' => $player->player_extend->recharge_amount ?? 0,
|
||||
'game_description' => $game->description,
|
||||
'game_url' => $game->game_url,
|
||||
'prize_list' => $prizes,
|
||||
'bank_list' => PlayerBank::query()
|
||||
->select('id', 'bank_name', 'account', 'account_name', 'bank_code')
|
||||
->where('player_id', $player->id)
|
||||
->where('status', 1)
|
||||
->where('pay_type', '!=', 4)
|
||||
->get(),
|
||||
'usdt' => PlayerBank::query()
|
||||
->select('id', 'wallet_address', 'qr_code')
|
||||
->where('player_id', $player->id)
|
||||
->where('status', 1)
|
||||
->where('pay_type', 4)
|
||||
->first(),
|
||||
'whats_app' => Channel::query()->where('department_id', $player->department_id)->value('telegram_url'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取充值列表
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function rechargeList(): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$lang = locale();
|
||||
$lang = Str::replace('_', '-', $lang);
|
||||
$channelRechargeMethod = ChannelRechargeMethod::query()
|
||||
->with(['methodLang' => function ($query) use ($lang) {
|
||||
$query->select(['id', 'bank_name', 'sub_bank', 'owner', 'name', 'method_id', 'lang'])->where('lang', $lang);
|
||||
}])
|
||||
->where('status', 1)
|
||||
->where('department_id', $player->department_id)
|
||||
->orderBy('created_at', 'desc')
|
||||
->select(['id', 'account', 'currency'])
|
||||
->get();
|
||||
$list = [];
|
||||
/** @var ChannelRechargeMethod $item */
|
||||
foreach ($channelRechargeMethod as $item) {
|
||||
$list[] = [
|
||||
'id' => $item->id,
|
||||
'account' => $item->account,
|
||||
'currency' => $item->currency,
|
||||
'name' => $item->methodLang[0]['name'] ?? '',
|
||||
'bank_name' => $item->methodLang[0]['bank_name'] ?? '',
|
||||
'sub_bank' => $item->methodLang[0]['sub_bank'] ?? '',
|
||||
'owner' => $item->methodLang[0]['sub_bank'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'list' => $list,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取充值项列表
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function rechargeSettingList(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('method_id', v::oneOf(v::intVal(), v::equals(''))->setName(trans('method_id', [], 'message')), false)
|
||||
->key('setting_id', v::oneOf(v::intVal(), v::equals(''))->setName(trans('setting_id', [], 'message')), false)
|
||||
->key('type', v::in([ChannelRechargeSetting::TYPE_REGULAR, ChannelRechargeSetting::TYPE_ACTIVITY, ''])->setName(trans('recharge_type', [], 'message')), false);
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
$list = ChannelRechargeSetting::query()
|
||||
->whereHas('channel_recharge_method', function ($query) {
|
||||
$query->where('status', 1);
|
||||
})
|
||||
->when(!empty($data['method_id']), function ($query) use ($data) {
|
||||
$query->where('method_id', $data['method_id']);
|
||||
})
|
||||
->when(!empty($data['setting_id']), function ($query) use ($data) {
|
||||
$query->where('id', $data['setting_id']);
|
||||
})
|
||||
->when(!empty($data['type']), function ($query) use ($data) {
|
||||
$query->where('type', $data['type']);
|
||||
})
|
||||
->where('department_id', $player->department_id)
|
||||
->where('status', 1)
|
||||
->orderBy('coins_num', 'asc')
|
||||
->select(['id', 'title', 'chip_multiple', 'coins_num', 'money', 'type', 'method_id'])
|
||||
->get();
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'list' => $list,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 充值详情
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function rechargeInfo(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('id', v::intVal()->notEmpty()->setName(trans('recharge_id', [], 'message')));
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
$lang = locale();
|
||||
$lang = Str::replace('_', '-', $lang);
|
||||
/** @var ChannelRechargeSetting $recharge */
|
||||
$recharge = ChannelRechargeSetting::query()
|
||||
->with(['channel_recharge_method' => function ($query) use ($lang) {
|
||||
$query->select(['id', 'account', 'currency'])->with(['methodLang' => function ($query) use ($lang) {
|
||||
$query->select(['id', 'bank_name', 'sub_bank', 'owner', 'name', 'method_id', 'lang'])->where('lang', $lang);
|
||||
}]);
|
||||
}])
|
||||
->where('department_id', $player->department_id)
|
||||
->where('id', $data['id'])
|
||||
->select(['id', 'title', 'chip_multiple', 'coins_num', 'gift_coins', 'money', 'type', 'method_id', 'status'])
|
||||
->first();
|
||||
|
||||
if (!$recharge) {
|
||||
return jsonFailResponse(trans('recharge_setting_not_found', [], 'message'));
|
||||
}
|
||||
if ($recharge->status == 0) {
|
||||
return jsonFailResponse(trans('recharge_setting_disabled', [], 'message'));
|
||||
}
|
||||
|
||||
return jsonSuccessResponse(trans('success', [], 'message'), [
|
||||
'recharge_setting' => $recharge
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑玩家名称
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function editPlayerName(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('player_name', v::stringVal()->length(1, 50)->setName(trans('player_name', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
if (Player::withTrashed()->where('name', $data['player_name'])->where('id', '!=', $player->id)->exists()) {
|
||||
return jsonFailResponse(trans('player_name_has_exist', [], 'message'));
|
||||
}
|
||||
$player->name = $data['player_name'] ?? '';
|
||||
$player->save();
|
||||
|
||||
return jsonSuccessResponse('success');
|
||||
}
|
||||
|
||||
/**
|
||||
* 數據中心
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function giftCenter(): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'chip_amount' => $player->chip_amount,
|
||||
'must_chip_amount' => $player->must_chip_amount,
|
||||
'coins' => $player->wallet->money,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取四方充值列表
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function seRechargeList(): Response
|
||||
{
|
||||
$player = checkPlayer(false);
|
||||
$list = SepayRecharge::query()->where('department_id', $player->department_id)
|
||||
->where('status', 1)
|
||||
->orderBy('money')
|
||||
->select(['id', 'title', 'coins_num', 'gift_coins', 'first_coins', 'money'])
|
||||
->get()->toArray();
|
||||
$time = date('H:i:s');
|
||||
foreach ($list as &$value){
|
||||
$value['P2PDEPOSIT'] = 0;
|
||||
$value['DUITNOWP2P'] = 0;
|
||||
if ($value['money'] >= 5 && $value['money'] <= 1000) {
|
||||
$value['P2PDEPOSIT'] = 1;
|
||||
if ($time >= '23:50:00' || $time <= '01:05:00') {
|
||||
$value['P2PDEPOSIT'] = 0;
|
||||
}
|
||||
}
|
||||
if ($value['money'] >= 30 && $value['money'] <= 20000) {
|
||||
$value['DUITNOWP2P'] = 1;
|
||||
}
|
||||
$firstRecharge = PlayerRechargeRecord::query()
|
||||
->where('player_id', $player->id)
|
||||
->where('status', 2)
|
||||
->where('setting_id', $value['id'])
|
||||
->first();
|
||||
if ($firstRecharge) {
|
||||
$value['first_coins'] = '0.00';
|
||||
}
|
||||
}
|
||||
unset($value);
|
||||
$bankList = [];
|
||||
$bankSelect = 0;
|
||||
|
||||
if (in_array($player->channel->pay_type, [2, 3])) {
|
||||
$bankSelect = 1;
|
||||
$bankList = BankList::query()
|
||||
->select(['bank_name', 'bank_code'])
|
||||
->where('pay_type', $player->channel->pay_type)
|
||||
->where('type', 1)
|
||||
->whereNull('deleted_at')
|
||||
->get()
|
||||
->toArray();
|
||||
}
|
||||
$rechargeSetting = ChannelRechargeMethod::query()
|
||||
->with('methodLang')
|
||||
->select(['id', 'account', 'wallet_address', 'qr_code', 'type'])
|
||||
->where('department_id', $player->department_id)
|
||||
->where('status', 1)
|
||||
->get()->toArray();
|
||||
foreach ($rechargeSetting as &$item) {
|
||||
if ($item['type'] == 1) {
|
||||
$item['name'] = 'artificial';
|
||||
} else {
|
||||
$item['name'] = 'usdt';
|
||||
}
|
||||
}
|
||||
unset($item);
|
||||
$rechargeSetting[] = [
|
||||
'name' => 'SKL',
|
||||
'type' => 3,
|
||||
];
|
||||
return jsonSuccessResponse('success', [
|
||||
'list' => $list,
|
||||
'bank_select' => $bankSelect,
|
||||
'bank_list' => $bankList,
|
||||
'recharge_setting' => $rechargeSetting
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家充值
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException
|
||||
* @throws GameException
|
||||
*/
|
||||
public function seRecharge(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('amount', v::notEmpty()->intVal()->setName(trans('recharge_amount', [], 'message')))
|
||||
->key('type', v::notEmpty()->intVal()->setName(trans('type', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
/** @var Channel $channel */
|
||||
$channel = Channel::where('department_id', $player->department_id)->first();
|
||||
if (empty($channel)) {
|
||||
return jsonFailResponse(trans('channel_not_found', [], 'message'));
|
||||
}
|
||||
/** @var SepayRecharge $sepayInfo */
|
||||
$sepayInfo = SepayRecharge::query()->where('department_id', $player->department_id)
|
||||
->where('money', $data['amount'])->first();
|
||||
$firstCoins = 0;
|
||||
$allCoins = $data['amount'];
|
||||
if(!empty($sepayInfo)) {
|
||||
if ($sepayInfo->first_coins > 0) {
|
||||
$firstRecharge = PlayerRechargeRecord::query()
|
||||
->where('player_id', $player->id)
|
||||
->where('status', 2)
|
||||
->where('setting_id', $sepayInfo->id)
|
||||
->doesntExist();
|
||||
if ($firstRecharge) {
|
||||
$firstCoins = $sepayInfo->first_coins;
|
||||
}
|
||||
}
|
||||
$allCoins = bcadd($sepayInfo->coins_num, $firstCoins, 2);
|
||||
}
|
||||
$orderNo = createOrderNo();
|
||||
// 生成充值订单
|
||||
$playerRechargeRecord = new PlayerRechargeRecord();
|
||||
$playerRechargeRecord->player_id = $player->id;
|
||||
$playerRechargeRecord->department_id = $player->department_id;
|
||||
$playerRechargeRecord->tradeno = $orderNo;
|
||||
$playerRechargeRecord->player_name = $player->name ?? '';
|
||||
$playerRechargeRecord->money = $data['amount'];
|
||||
$playerRechargeRecord->inmoney = $data['amount'];
|
||||
$playerRechargeRecord->setting_id = $sepayInfo->id ?? 0;
|
||||
$playerRechargeRecord->coins = $data['amount'];
|
||||
$playerRechargeRecord->gift_coins = $firstCoins;
|
||||
$playerRechargeRecord->currency = 'RM';
|
||||
//手动支付
|
||||
if ($data['type'] == 1) {
|
||||
$playerRechargeRecord->type = PlayerRechargeRecord::TYPE_REGULAR;
|
||||
$playerRechargeRecord->status = PlayerRechargeRecord::STATUS_WAIT;
|
||||
$playerRechargeRecord->save();
|
||||
//USDT支付
|
||||
} elseif ($data['type'] == 2) {
|
||||
$rate = ChannelRechargeMethod::query()
|
||||
->where('department_id', $player->department_id)
|
||||
->where('type', 2)
|
||||
->value('rate');
|
||||
$playerRechargeRecord->rate = $rate;
|
||||
$playerRechargeRecord->currency = 'USDT';
|
||||
$playerRechargeRecord->type = PlayerRechargeRecord::TYPE_REGULAR;
|
||||
$playerRechargeRecord->status = PlayerRechargeRecord::STATUS_WAIT;
|
||||
$playerRechargeRecord->save();
|
||||
//三方支付
|
||||
}elseif ($data['type'] == 3) {
|
||||
if ($data['payment_code'] == 'DUITNOWP2P') {
|
||||
$paymentCode = 'QR';
|
||||
} else {
|
||||
$paymentCode = $data['bank_code'];
|
||||
}
|
||||
$params = [
|
||||
'amount' => $data['amount'],
|
||||
'paymentCode' => $paymentCode,
|
||||
'name' => 'ggl-ds ' . $player->uuid,
|
||||
'orderNo' => $orderNo,
|
||||
];
|
||||
$res = (new SklPayServices())->deposit($params);
|
||||
|
||||
if (!isset($res['status']) && empty($res['code'])) {
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$pay_url = $res['transaction_link'];
|
||||
$playerRechargeRecord->payment_method = $params['paymentCode'] == 'QR' ? 'QR' : 'P2P';
|
||||
$playerRechargeRecord->external_reference = $res['transaction_id'];
|
||||
$playerRechargeRecord->type = PlayerRechargeRecord::TYPE_REGULAR;
|
||||
$playerRechargeRecord->status = PlayerRechargeRecord::STATUS_WAIT;
|
||||
$playerRechargeRecord->remark = 'SKL99';
|
||||
$playerRechargeRecord->save();
|
||||
DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
return jsonFailResponse($e->getMessage());
|
||||
}
|
||||
return jsonSuccessResponse('success', ['pay_url' => $pay_url]);
|
||||
} else {
|
||||
return jsonFailResponse($res['error']);
|
||||
}
|
||||
}
|
||||
|
||||
sendSocketMessage('private-admin_group-channel-' . request()->department_id, [
|
||||
'msg_type' => 'player_examine_recharge_order',
|
||||
'id' => $playerRechargeRecord->id,
|
||||
'player_id' => $player->id,
|
||||
'player_name' => $player->name,
|
||||
'player_phone' => $player->phone,
|
||||
'money' => $playerRechargeRecord->money,
|
||||
'status' => $playerRechargeRecord->status,
|
||||
'tradeno' => $playerRechargeRecord->tradeno,
|
||||
]);
|
||||
|
||||
$rechargeSetting = ChannelRechargeMethod::query()
|
||||
->with('methodLang')
|
||||
->select(['id', 'account', 'wallet_address', 'qr_code', 'type'])
|
||||
->where('department_id', $player->department_id)
|
||||
->where('status', 1)
|
||||
->where('type', $data['type'])
|
||||
->get()->toArray();
|
||||
return jsonSuccessResponse('success', [
|
||||
'tradeno' => $playerRechargeRecord->tradeno,
|
||||
'order_id' => $playerRechargeRecord->id,
|
||||
'money' => $playerRechargeRecord->money,
|
||||
'coins' => $allCoins,
|
||||
'currency' => $playerRechargeRecord->currency,
|
||||
'status' => $playerRechargeRecord->status,
|
||||
'created_at' => strtotime($playerRechargeRecord->created_at),
|
||||
'recharge_setting' => $rechargeSetting
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成充值
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException
|
||||
* @throws PushException|GameException
|
||||
*/
|
||||
public function completeRecharge(Request $request): Response {
|
||||
$player = checkPlayer();
|
||||
$data = $request->post();
|
||||
$validator = v::key('id', v::notEmpty()->intVal()->setName(trans('recharge_record_id', [], 'message')))
|
||||
->key('certificate', v::notEmpty()->stringVal()->setName(trans('certificate', [], 'message')));
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
/** @var PlayerRechargeRecord $rechargeRecord */
|
||||
$rechargeRecord = PlayerRechargeRecord::query()
|
||||
->where('player_id', $player->id)
|
||||
->where('id', $data['id'])
|
||||
->first();
|
||||
if (empty($rechargeRecord)) {
|
||||
return jsonFailResponse(trans('recharge_record_not_found', [], 'message'));
|
||||
}
|
||||
switch ($rechargeRecord->status) {
|
||||
case PlayerRechargeRecord::STATUS_RECHARGING:
|
||||
return jsonFailResponse(trans('recharge_record_review_in_progress', [], 'message'));
|
||||
case PlayerRechargeRecord::STATUS_RECHARGED_SUCCESS:
|
||||
return jsonFailResponse(trans('recharge_completed', [], 'message'));
|
||||
case PlayerRechargeRecord::STATUS_RECHARGED_FAIL:
|
||||
return jsonFailResponse(trans('recharge_failed', [], 'message'));
|
||||
case PlayerRechargeRecord::STATUS_RECHARGED_CANCEL:
|
||||
return jsonFailResponse(trans('player_has_cancelled_recharge', [], 'message'));
|
||||
case PlayerRechargeRecord::STATUS_RECHARGED_REJECT:
|
||||
return jsonFailResponse(trans('recharge_order_review_failed', [], 'message'));
|
||||
case PlayerRechargeRecord::STATUS_RECHARGED_SYSTEM_CANCEL:
|
||||
return jsonFailResponse(trans('system_cancels_order', [], 'message'));
|
||||
}
|
||||
$rechargeRecord->status = PlayerRechargeRecord::STATUS_RECHARGING;
|
||||
$rechargeRecord->certificate = $data['certificate'];
|
||||
$rechargeRecord->save();
|
||||
|
||||
sendSocketMessage('private-admin_group-channel-' . $player->department_id, [
|
||||
'msg_type' => 'player_examine_recharge_order',
|
||||
'id' => $rechargeRecord->id,
|
||||
'player_id' => $player->id,
|
||||
'player_name' => $player->name,
|
||||
'player_phone' => $player->phone,
|
||||
'money' => $rechargeRecord->money,
|
||||
'status' => $rechargeRecord->status,
|
||||
'tradeno' => $rechargeRecord->tradeno,
|
||||
]);
|
||||
|
||||
return jsonSuccessResponse('success');
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家提现
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException
|
||||
* @throws GameException
|
||||
*/
|
||||
public function seWithdrawal(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('amount', v::intVal()->notEmpty()->min(100)->max(20000)->setName(trans('withdrawal_amount', [], 'message')))
|
||||
->key('bank_id', v::intVal()->setName(trans('withdrawal_bank', [], 'message')))
|
||||
->key('type', v::intVal()->setName(trans('type', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
|
||||
/** @var Channel $channel */
|
||||
$channel = Channel::where('department_id', $player->department_id)->first();
|
||||
if ($player->status_withdraw != 1) {
|
||||
return jsonFailResponse(trans('player_withdraw_closed', [], 'message'));
|
||||
}
|
||||
if ($player->wallet->money < $data['amount']) {
|
||||
return jsonFailResponse(trans('insufficient_balance', [], 'message'));
|
||||
}
|
||||
if ($channel->withdraw_status == 0) {
|
||||
return jsonFailResponse(trans('self_withdraw_closed', [], 'message'));
|
||||
}
|
||||
if (empty($data['bank_id'])) {
|
||||
return jsonFailResponse(trans('please_select_player_bank', [], 'message'));
|
||||
}
|
||||
/** @var Currency $currency */
|
||||
$currency = Currency::where('identifying', $channel->currency)->where('status', 1)->whereNull('deleted_at')->first();
|
||||
if (empty($currency)) {
|
||||
return jsonFailResponse(trans('currency_no_setting', [], 'message'));
|
||||
}
|
||||
/** @var PlayerBank $playerBank */
|
||||
$playerBank = PlayerBank::where('id', $data['bank_id'])
|
||||
->where('player_id', $player->id)
|
||||
->where('status', 1)
|
||||
->whereNull('deleted_at')
|
||||
->first();
|
||||
if (empty($playerBank)) {
|
||||
return jsonFailResponse(trans('player_bank_not_found', [], 'message'));
|
||||
}
|
||||
//计算汇率
|
||||
$money = bcdiv($data['amount'], $currency->ratio, 2);
|
||||
//大于5000需要后台审核
|
||||
/*if ($money >= 5000) {
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$money = bcdiv($data['amount'], $currency->ratio, 2);
|
||||
// 生成订单
|
||||
$playerWithdrawRecord = new PlayerWithdrawRecord();
|
||||
$beforeGameAmount = $player->wallet->money;
|
||||
// 玩家钱包扣减
|
||||
$player->wallet->money = bcsub($player->wallet->money, $data['amount'], 2);
|
||||
$playerWithdrawRecord->player_id = $player->id;
|
||||
$playerWithdrawRecord->department_id = $player->department_id;
|
||||
$playerWithdrawRecord->tradeno = createOrderNo();
|
||||
$playerWithdrawRecord->player_name = $player->name ?? '';
|
||||
$playerWithdrawRecord->player_phone = $player->phone ?? '';
|
||||
$playerWithdrawRecord->money = $money;
|
||||
$playerWithdrawRecord->coins = $data['amount'];
|
||||
$playerWithdrawRecord->after_coins = $player->wallet->money;
|
||||
$playerWithdrawRecord->fee = 0;
|
||||
$playerWithdrawRecord->inmoney = bcsub($playerWithdrawRecord->money, $playerWithdrawRecord->fee, 2); // 实际提现金额
|
||||
$playerWithdrawRecord->currency = $channel->currency;
|
||||
$playerWithdrawRecord->bank_name = $playerBank->bank_name;
|
||||
$playerWithdrawRecord->bank_code = $playerBank->bank_code;
|
||||
$playerWithdrawRecord->account = $playerBank->account;
|
||||
$playerWithdrawRecord->account_name = $playerBank->account_name;
|
||||
$playerWithdrawRecord->type = PlayerWithdrawRecord::TYPE_SELF;
|
||||
$playerWithdrawRecord->status = PlayerWithdrawRecord::STATUS_WAIT;
|
||||
$playerWithdrawRecord->save();
|
||||
|
||||
// 更新玩家统计
|
||||
$player->player_extend->withdraw_amount = bcadd($player->player_extend->withdraw_amount, $playerWithdrawRecord->coins, 2);
|
||||
$player->push();
|
||||
//寫入金流明細
|
||||
$playerDeliveryRecord = new PlayerDeliveryRecord;
|
||||
$playerDeliveryRecord->player_id = $playerWithdrawRecord->player_id;
|
||||
$playerDeliveryRecord->department_id = $playerWithdrawRecord->department_id;
|
||||
$playerDeliveryRecord->target = $playerWithdrawRecord->getTable();
|
||||
$playerDeliveryRecord->target_id = $playerWithdrawRecord->id;
|
||||
$playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_WITHDRAWAL;
|
||||
$playerDeliveryRecord->source = 'channel_withdrawal';
|
||||
$playerDeliveryRecord->amount = $playerWithdrawRecord->coins;
|
||||
$playerDeliveryRecord->amount_before = $beforeGameAmount;
|
||||
$playerDeliveryRecord->amount_after = $player->wallet->money;
|
||||
$playerDeliveryRecord->tradeno = $playerWithdrawRecord->tradeno ?? '';
|
||||
$playerDeliveryRecord->remark = $playerWithdrawRecord->remark ?? '';
|
||||
$playerDeliveryRecord->save();
|
||||
DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
return jsonFailResponse(trans('system_error', [], 'message') . $e->getMessage());
|
||||
}
|
||||
|
||||
$notice = new Notice();
|
||||
$notice->department_id = $playerWithdrawRecord->department_id;
|
||||
$notice->player_id = $playerWithdrawRecord->player_id;
|
||||
$notice->source_id = $playerWithdrawRecord->id;
|
||||
$notice->type = Notice::TYPE_EXAMINE_WITHDRAW;
|
||||
$notice->receiver = Notice::RECEIVER_DEPARTMENT;
|
||||
$notice->is_private = 0;
|
||||
$notice->title = '渠道提现待审核';
|
||||
$notice->content = '提现订单待审核,玩家' . (empty($playerWithdrawRecord->player_name) ? $playerWithdrawRecord->player_name : $playerWithdrawRecord->player_phone) . ', 提现游戏点: ' . $playerWithdrawRecord->point . ' 提现金额: ' . $playerWithdrawRecord->money;
|
||||
$notice->save();
|
||||
|
||||
if ($playerWithdrawRecord->status == PlayerWithdrawRecord::STATUS_FAIL) {
|
||||
return jsonFailResponse(trans('withdraw_fail', [], 'message'));
|
||||
}
|
||||
sendSocketMessage('private-admin_group-channel-' . $channel->department_id, [
|
||||
'msg_type' => 'player_create_withdraw_order',
|
||||
'id' => $playerWithdrawRecord->id,
|
||||
'player_id' => $player->id,
|
||||
'player_name' => $player->name,
|
||||
'player_phone' => $player->phone,
|
||||
'money' => $playerWithdrawRecord->money,
|
||||
'status' => $playerWithdrawRecord->status,
|
||||
'tradeno' => $playerWithdrawRecord->tradeno,
|
||||
]);
|
||||
return jsonSuccessResponse('success', [
|
||||
'tradeno' => $playerWithdrawRecord->tradeno,
|
||||
'order_id' => $playerWithdrawRecord->id,
|
||||
'money' => $playerWithdrawRecord->money,
|
||||
'currency' => $playerWithdrawRecord->currency,
|
||||
'status' => $playerWithdrawRecord->status,
|
||||
]);
|
||||
}*/
|
||||
|
||||
// 生成订单
|
||||
$orderNo = createOrderNo();
|
||||
$playerWithdrawRecord = new PlayerWithdrawRecord();
|
||||
$beforeGameAmount = $player->wallet->money;
|
||||
// 玩家钱包扣减
|
||||
$player->wallet->money = bcsub($player->wallet->money, $data['amount'], 2);
|
||||
$playerWithdrawRecord->player_id = $player->id;
|
||||
$playerWithdrawRecord->department_id = $player->department_id;
|
||||
$playerWithdrawRecord->tradeno = $orderNo;
|
||||
$playerWithdrawRecord->player_name = $player->name ?? '';
|
||||
$playerWithdrawRecord->player_phone = $player->phone ?? '';
|
||||
$playerWithdrawRecord->money = $money;
|
||||
$playerWithdrawRecord->coins = $data['amount'];
|
||||
$playerWithdrawRecord->after_coins = $player->wallet->money;
|
||||
$playerWithdrawRecord->fee = 0;
|
||||
$playerWithdrawRecord->inmoney = bcsub($playerWithdrawRecord->money, $playerWithdrawRecord->fee, 2); // 实际提现金额
|
||||
$playerWithdrawRecord->currency = $channel->currency;
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
//银行卡提现
|
||||
if ($data['type'] == 1) {
|
||||
$playerWithdrawRecord->bank_name = $playerBank->bank_name;
|
||||
$playerWithdrawRecord->bank_code = $playerBank->bank_code;
|
||||
$playerWithdrawRecord->account = $playerBank->account;
|
||||
$playerWithdrawRecord->account_name = $playerBank->account_name;
|
||||
$playerWithdrawRecord->type = PlayerWithdrawRecord::TYPE_SELF;
|
||||
$playerWithdrawRecord->status = PlayerWithdrawRecord::STATUS_WAIT;
|
||||
$playerWithdrawRecord->save();
|
||||
//USDT提现
|
||||
} elseif ($data['type'] == 2) {
|
||||
$rate = ChannelRechargeMethod::query()
|
||||
->where('department_id', $player->department_id)
|
||||
->where('type', 2)
|
||||
->value('rate');
|
||||
$playerWithdrawRecord->rate = $rate;
|
||||
$playerWithdrawRecord->currency = 'USDT';
|
||||
$playerWithdrawRecord->wallet_address = $playerBank->wallet_address;
|
||||
$playerWithdrawRecord->qr_code = $playerBank->qr_code;
|
||||
$playerWithdrawRecord->type = PlayerWithdrawRecord::TYPE_USDT;
|
||||
$playerWithdrawRecord->status = PlayerWithdrawRecord::STATUS_WAIT;
|
||||
$playerWithdrawRecord->save();
|
||||
//三方提现
|
||||
} else {
|
||||
$params = [
|
||||
'amount' => $money,
|
||||
'bankCode' => $playerBank->bank_code,
|
||||
'bankAccountNo' => $playerBank->account,
|
||||
'bankAccountName' => $playerBank->account_name,
|
||||
'orderNo' => $orderNo,
|
||||
];
|
||||
$res = (new SklPayServices())->payout($params);
|
||||
if ($res['code'] == 'success') {
|
||||
$playerWithdrawRecord->bank_name = $playerBank->bank_name;
|
||||
$playerWithdrawRecord->bank_code = $playerBank->bank_code;
|
||||
$playerWithdrawRecord->account = $playerBank->account;
|
||||
$playerWithdrawRecord->account_name = $playerBank->account_name;
|
||||
$playerWithdrawRecord->talk_tradeno = $res['data']['reference_number'];
|
||||
$playerWithdrawRecord->type = PlayerWithdrawRecord::TYPE_SKLPAYOUT;
|
||||
$playerWithdrawRecord->status = PlayerWithdrawRecord::STATUS_WAIT;
|
||||
$playerWithdrawRecord->save();
|
||||
} else {
|
||||
return jsonFailResponse($res['error']);
|
||||
}
|
||||
}
|
||||
DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
return jsonFailResponse(trans('system_error', [], 'message') . $e->getMessage());
|
||||
}
|
||||
|
||||
// 更新玩家统计
|
||||
$player->player_extend->withdraw_amount = bcadd($player->player_extend->withdraw_amount, $playerWithdrawRecord->coins, 2);
|
||||
$player->push();
|
||||
|
||||
//寫入金流明細
|
||||
$playerDeliveryRecord = new PlayerDeliveryRecord;
|
||||
$playerDeliveryRecord->player_id = $playerWithdrawRecord->player_id;
|
||||
$playerDeliveryRecord->department_id = $playerWithdrawRecord->department_id;
|
||||
$playerDeliveryRecord->target = $playerWithdrawRecord->getTable();
|
||||
$playerDeliveryRecord->target_id = $playerWithdrawRecord->id;
|
||||
$playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_WITHDRAWAL;
|
||||
$playerDeliveryRecord->source = 'channel_withdrawal';
|
||||
$playerDeliveryRecord->amount = $playerWithdrawRecord->coins;
|
||||
$playerDeliveryRecord->amount_before = $beforeGameAmount;
|
||||
$playerDeliveryRecord->amount_after = $player->wallet->money;
|
||||
$playerDeliveryRecord->tradeno = $playerWithdrawRecord->tradeno ?? '';
|
||||
$playerDeliveryRecord->remark = '';
|
||||
$playerDeliveryRecord->save();
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'tradeno' => $playerWithdrawRecord->tradeno,
|
||||
'money' => $playerWithdrawRecord->money,
|
||||
'currency' => $playerWithdrawRecord->currency,
|
||||
'status' => $playerWithdrawRecord->status,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 玩家账变记录
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|PromoterCheckException
|
||||
*/
|
||||
public function playerDeliveryRecord(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer(false);
|
||||
$validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
|
||||
->key('type', v::stringVal()->setName(trans('date_type', [], 'message')))
|
||||
->key('size', v::intVal()->setName(trans('size', [], 'message')));
|
||||
$data = $request->all();
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
try {
|
||||
$playerDeliveryRecordModel = PlayerDeliveryRecord::where('player_id', $player->id);
|
||||
switch ($data['type']) {
|
||||
case 'today': // 今天
|
||||
$playerDeliveryRecordModel->whereDate('created_at', date('Y-m-d'));
|
||||
break;
|
||||
case 'week': // 本周
|
||||
$playerDeliveryRecordModel->where('created_at', '>=', \Carbon\Carbon::today()->startOfWeek())->where('created_at', '<=', Carbon::today()->endOfWeek());
|
||||
break;
|
||||
case 'month': // 本月
|
||||
$playerDeliveryRecordModel->where('created_at', '>=', Carbon::today()->firstOfMonth())->where('created_at', '<=', Carbon::today()->endOfMonth());
|
||||
break;
|
||||
case 'sub_month': // 上月
|
||||
$playerDeliveryRecordModel->where('created_at', '>=', Carbon::today()->subMonth()->firstOfMonth())->where('created_at', '<=', Carbon::today()->subMonth()->endOfMonth());
|
||||
break;
|
||||
default:
|
||||
$playerDeliveryRecordModel->whereDate('created_at', date('Y-m-d'));
|
||||
break;
|
||||
}
|
||||
$inType = implode(',', [
|
||||
PlayerDeliveryRecord::TYPE_MODIFIED_AMOUNT_ADD,
|
||||
PlayerDeliveryRecord::TYPE_PRESENT_IN,
|
||||
PlayerDeliveryRecord::TYPE_GAME_IN,
|
||||
PlayerDeliveryRecord::TYPE_ACTIVITY_BONUS,
|
||||
PlayerDeliveryRecord::TYPE_REGISTER_PRESENT,
|
||||
PlayerDeliveryRecord::TYPE_PROFIT,
|
||||
PlayerDeliveryRecord::TYPE_LOTTERY,
|
||||
]);
|
||||
$outType = implode(',', [
|
||||
PlayerDeliveryRecord::TYPE_PRESENT_OUT,
|
||||
PlayerDeliveryRecord::TYPE_GAME_OUT,
|
||||
PlayerDeliveryRecord::TYPE_MODIFIED_AMOUNT_DEDUCT,
|
||||
]);
|
||||
$totalModel = clone $playerDeliveryRecordModel;
|
||||
$totalData = $totalModel->selectRaw('sum(IF(type in (' . $inType . '), amount, 0)) as total_in, sum(IF(type in (' . $outType . '), amount, 0)) as total_out, sum(IF(type = ' . PlayerDeliveryRecord::TYPE_WITHDRAWAL . ', amount, 0)) as total_withdrawal, sum(IF(type = ' . PlayerDeliveryRecord::TYPE_WITHDRAWAL_BACK . ', amount, 0)) as total_withdrawal_back, sum(IF(type = ' . PlayerDeliveryRecord::TYPE_RECHARGE . ', amount, 0)) as total_recharge')->first();
|
||||
|
||||
$playerDeliveryRecord = $playerDeliveryRecordModel->forPage($data['page'], $data['size'])
|
||||
->orderBy('id', 'desc')
|
||||
->get();
|
||||
$list = [];
|
||||
/** @var PlayerDeliveryRecord $item */
|
||||
foreach ($playerDeliveryRecord as $item) {
|
||||
switch ($item->type) {
|
||||
case PlayerDeliveryRecord::TYPE_MODIFIED_AMOUNT_ADD:
|
||||
$item->target = trans('target.modified_amount_add', [], 'message');
|
||||
break;
|
||||
case PlayerDeliveryRecord::TYPE_PRESENT_IN:
|
||||
$item->target = trans('target.present_in', [], 'message');
|
||||
break;
|
||||
case PlayerDeliveryRecord::TYPE_PRESENT_OUT:
|
||||
$item->target = trans('target.present_out', [], 'message');
|
||||
$item->amount = '-' . $item->amount;
|
||||
break;
|
||||
case PlayerDeliveryRecord::TYPE_GAME_OUT:
|
||||
$item->target = trans('target.machine_up', [], 'message');
|
||||
$item->amount = '-' . $item->amount;
|
||||
break;
|
||||
case PlayerDeliveryRecord::TYPE_GAME_IN:
|
||||
$item->target = trans('target.machine_down', [], 'message');
|
||||
break;
|
||||
case PlayerDeliveryRecord::TYPE_RECHARGE:
|
||||
switch ($item->source) {
|
||||
case 'artificial_recharge':
|
||||
$item->target = trans('target.artificial_recharge', [], 'message');
|
||||
break;
|
||||
case 'self_recharge':
|
||||
$item->target = trans('target.self_recharge', [], 'message');
|
||||
break;
|
||||
case 'talk_recharge':
|
||||
$item->target = trans('target.talk_recharge', [], 'message');
|
||||
break;
|
||||
case 'coin_recharge':
|
||||
$item->target = trans('target.coin_recharge', [], 'message');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PlayerDeliveryRecord::TYPE_WITHDRAWAL:
|
||||
switch ($item['source']) {
|
||||
case 'artificial_withdrawal':
|
||||
$item->target = trans('target.artificial_withdrawal', [], 'message');
|
||||
break;
|
||||
case 'talk_withdrawal':
|
||||
$item->target = trans('target.talk_withdrawal', [], 'message');
|
||||
break;
|
||||
case 'channel_withdrawal':
|
||||
$item->target = trans('target.channel_withdrawal', [], 'message');
|
||||
break;
|
||||
}
|
||||
$item->amount = '-' . $item->amount;
|
||||
break;
|
||||
case PlayerDeliveryRecord::TYPE_MODIFIED_AMOUNT_DEDUCT:
|
||||
$item->target = trans('target.modified_amount_deduct', [], 'message');
|
||||
$item->amount = '-' . $item->amount;
|
||||
break;
|
||||
case PlayerDeliveryRecord::TYPE_WITHDRAWAL_BACK:
|
||||
$item->target = trans('target.withdrawal_back', [], 'message');
|
||||
break;
|
||||
case PlayerDeliveryRecord::TYPE_ACTIVITY_BONUS:
|
||||
$item->target = trans('target.activity_bonus', [], 'message');
|
||||
break;
|
||||
case PlayerDeliveryRecord::TYPE_REGISTER_PRESENT:
|
||||
$item->target = trans('target.register_present', [], 'message');
|
||||
break;
|
||||
case PlayerDeliveryRecord::TYPE_PROFIT:
|
||||
$item->target = trans('target.profit', [], 'message');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$list[] = [
|
||||
'id' => $item->id,
|
||||
'amount' => $item->amount,
|
||||
'source' => $item->target,
|
||||
'amount_after' => $item->amount_after,
|
||||
'created_at' => date('Y-m-d H:i:s', strtotime($item->created_at)),
|
||||
];
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return jsonFailResponse($e->getMessage());
|
||||
}
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'list' => $list,
|
||||
'player' => [
|
||||
'uuid' => $player->uuid,
|
||||
'name' => $player->name,
|
||||
'promoter_uuid' => $player->uuid,
|
||||
],
|
||||
'total_data' => [
|
||||
'total_in' => $totalData['total_in'] ?? 0,
|
||||
'total_out' => $totalData['total_out'] ?? 0,
|
||||
'total_withdrawal' => bcsub($totalData['total_withdrawal'] ?? 0, $totalData['total_withdrawal_back'] ?? 0, 2),
|
||||
'total_recharge' => $totalData['total_recharge'] ?? 0,
|
||||
],
|
||||
'date_type' => [
|
||||
'today' => Carbon::today()->format('Y-m-d'),
|
||||
'week' => Carbon::today()->startOfWeek()->format('Y-m-d') . '~' . Carbon::today()->endOfWeek()->format('Y-m-d'),
|
||||
'month' => Carbon::today()->firstOfMonth()->format('Y-m-d') . '~' . Carbon::today()->endOfMonth()->format('Y-m-d'),
|
||||
'sub_month' => Carbon::today()->subMonth()->firstOfMonth()->format('Y-m-d') . '~' . Carbon::today()->subMonth()->endOfMonth()->format('Y-m-d'),
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 游戏记录
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function gameRecord(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
|
||||
->key('size', v::intVal()->setName(trans('size', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
|
||||
$records = DrawRecord::query()
|
||||
->select('prize_pic', 'prize_name', 'prize_type', 'draw_time', 'ip')
|
||||
->where('uid', $player->id)
|
||||
->orderBy('id', 'desc')
|
||||
->forPage($data['page'], $data['size'])
|
||||
->get()
|
||||
->toArray();
|
||||
return jsonSuccessResponse('success', $records);
|
||||
}
|
||||
|
||||
/**
|
||||
* 充提记录
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws PlayerCheckException|GameException
|
||||
*/
|
||||
public function depositWithdrawalRecord(Request $request): Response
|
||||
{
|
||||
$player = checkPlayer();
|
||||
$data = $request->all();
|
||||
$validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
|
||||
->key('size', v::intVal()->setName(trans('size', [], 'message')))
|
||||
->key('type', v::intVal()->setName(trans('type', [], 'message')))
|
||||
->key('start_date', v::stringVal()->setName(trans('start_date', [], 'message')))
|
||||
->key('end_date', v::stringVal()->setName(trans('end_date', [], 'message')));
|
||||
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
// 1. 构建充值查询
|
||||
$rechargeQuery = DB::table('player_recharge_record')
|
||||
->select('money', 'created_at', 'status', DB::raw("1 as type"))
|
||||
->where('player_id', $player->id)
|
||||
->whereBetween('created_at', [$data['start_date'],date('Y-m-d', strtotime("{$data['end_date']} +1 days"))]);
|
||||
|
||||
// 2. 构建提现查询
|
||||
$withdrawQuery = DB::table('player_withdraw_record')
|
||||
->select('money', 'created_at', 'status', DB::raw("2 as type"))
|
||||
->where('player_id', $player->id)
|
||||
->whereBetween('created_at', [$data['start_date'],date('Y-m-d', strtotime("{$data['end_date']} +1 days"))]);
|
||||
// 3. 根据类型参数过滤
|
||||
if ($data['type'] == 1) {
|
||||
$query = $rechargeQuery;
|
||||
} elseif ($data['type'] == 2) {
|
||||
$query = $withdrawQuery;
|
||||
} else {
|
||||
$query = $rechargeQuery->unionAll($withdrawQuery);
|
||||
}
|
||||
// 4. 处理排序和分页
|
||||
$records = DB::table(DB::raw("({$query->toSql()}) as combined_transactions"))
|
||||
->mergeBindings($query) // 重要:合并 SQL 绑定参数
|
||||
->orderBy('created_at', 'desc')
|
||||
->forPage($data['page'], $data['size'])
|
||||
->get()->toArray();
|
||||
return jsonSuccessResponse('success', $records);
|
||||
}
|
||||
}
|
||||
42
app/api/controller/v1/VersionController.php
Normal file
42
app/api/controller/v1/VersionController.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller\v1;
|
||||
|
||||
use addons\webman\model\AppVersion;
|
||||
use Exception;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
|
||||
class VersionController
|
||||
{
|
||||
/**
|
||||
* 登录接口
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getAppUpdate(Request $request): Response
|
||||
{
|
||||
// 更新比较时,查询的是版本标识,大于传入的版本标识时,返回新版本的数据
|
||||
$version_key = $request->header('app-version-key', '');
|
||||
// 传入检测的系统
|
||||
$system_key = $request->header('system-key', '');
|
||||
if (empty($version_key) || empty($system_key)) {
|
||||
return jsonFailResponse(trans('incomplete_parameters', [], 'message'));
|
||||
}
|
||||
$data = AppVersion::query()
|
||||
->where('app_version_key', '>=', $version_key)
|
||||
->where(['status' => 1])
|
||||
->where('status', 1)
|
||||
->where('system_key', $system_key)
|
||||
->where('department_id', request()->department_id)
|
||||
->whereDate('regular_update', '<', date("Y-m-d H:i:s", time()))
|
||||
->select(['id', 'system_key', 'app_version', 'app_version_key', 'apk_url', 'hot_update_url', 'force_update', 'hot_update', 'regular_update', 'update_content', 'notes'])
|
||||
->orderBy('id', 'desc')
|
||||
->first();
|
||||
|
||||
return jsonSuccessResponse('success', [
|
||||
'data' => $data
|
||||
]);
|
||||
}
|
||||
}
|
||||
50
app/exception/ApiHandler.php
Normal file
50
app/exception/ApiHandler.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
namespace app\exception;
|
||||
|
||||
use Respect\Validation\Exceptions\NestedValidationException;
|
||||
use Respect\Validation\Exceptions\ValidationException;
|
||||
use Throwable;
|
||||
use Tinywan\Jwt\Exception\JwtTokenException;
|
||||
use Tinywan\Jwt\Exception\JwtTokenExpiredException;
|
||||
use Webman\Exception\ExceptionHandler;
|
||||
use Webman\Http\Request;
|
||||
use Webman\Http\Response;
|
||||
|
||||
/**
|
||||
* Class Handler
|
||||
* @package support\exception
|
||||
*/
|
||||
class ApiHandler extends ExceptionHandler
|
||||
{
|
||||
public $dontReport = [
|
||||
NestedValidationException::class,
|
||||
ValidationException::class,
|
||||
];
|
||||
|
||||
public function render(Request $request, Throwable $exception): Response
|
||||
{
|
||||
if ($exception instanceof JwtTokenExpiredException || $exception instanceof JwtTokenException) {
|
||||
return json([
|
||||
'code' => 401,
|
||||
'msg' => $exception->getMessage()
|
||||
]);
|
||||
}
|
||||
return json([
|
||||
'code' => $exception->getCode(),
|
||||
'msg' => $exception->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
6
app/exception/GameException.php
Normal file
6
app/exception/GameException.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace app\exception;
|
||||
|
||||
class GameException extends \Exception
|
||||
{
|
||||
}
|
||||
6
app/exception/PlayerCheckException.php
Normal file
6
app/exception/PlayerCheckException.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace app\exception;
|
||||
|
||||
class PlayerCheckException extends \Exception
|
||||
{
|
||||
}
|
||||
7
app/exception/PromoterCheckException.php
Normal file
7
app/exception/PromoterCheckException.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace app\exception;
|
||||
|
||||
class PromoterCheckException extends \Exception
|
||||
{
|
||||
}
|
||||
260
app/external/ExternalApiController.php
vendored
Normal file
260
app/external/ExternalApiController.php
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
namespace app\external;
|
||||
|
||||
use addons\webman\model\Broadcast;
|
||||
use addons\webman\model\Notice;
|
||||
use addons\webman\model\PlayerGamePlatform;
|
||||
use addons\webman\model\PlayerRechargeRecord;
|
||||
use addons\webman\model\Player;
|
||||
use addons\webman\model\PlayerDeliveryRecord;
|
||||
use addons\webman\model\PlayerWithdrawRecord;
|
||||
use app\service\game\MeGa888ServiceInterface;
|
||||
use app\service\OnePayServices;
|
||||
use app\service\SePayServices;
|
||||
use app\service\SklPayServices;
|
||||
use Respect\Validation\Exceptions\AllOfException;
|
||||
use Respect\Validation\Validator as v;
|
||||
use support\Db;
|
||||
use support\Request;
|
||||
use support\Log;
|
||||
use support\Response;
|
||||
use Webman\Push\PushException;
|
||||
use Webman\RedisQueue\Redis;
|
||||
|
||||
class ExternalApiController
|
||||
{
|
||||
/** 排除 */
|
||||
protected $noNeedSign = [];
|
||||
|
||||
/**
|
||||
* 网页注册
|
||||
* @return Response
|
||||
*/
|
||||
public function login(): Response
|
||||
{
|
||||
return view('login/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* app下载
|
||||
* @return Response
|
||||
*/
|
||||
public function download(): Response
|
||||
{
|
||||
return view('login/download');
|
||||
}
|
||||
|
||||
/**
|
||||
* SKL支付回调
|
||||
* @param Request $request
|
||||
* @return string
|
||||
* @throws PushException
|
||||
*/
|
||||
public function sklRechargeNotify(Request $request): string
|
||||
{
|
||||
$data = $request->all();
|
||||
if ($data['status'] && $data['invoice_no']) {
|
||||
/** @var PlayerRechargeRecord $playerRechargeRecord */
|
||||
$playerRechargeRecord = PlayerRechargeRecord::query()->where('tradeno', $data['invoice_no'])->where('status', 0)->first();
|
||||
if(empty($playerRechargeRecord) || $playerRechargeRecord->money != $data['amount']){
|
||||
return 'FAIL';
|
||||
}
|
||||
if ($data['status'] == 'SUCCESS') {
|
||||
if ($playerRechargeRecord->gift_coins > 0) {
|
||||
$firstRecharge = PlayerRechargeRecord::query()
|
||||
->where('player_id', $playerRechargeRecord->player_id)
|
||||
->where('status', 2)
|
||||
->where('setting_id', $playerRechargeRecord->setting_id)
|
||||
->first();
|
||||
if ($firstRecharge) {
|
||||
$playerRechargeRecord->gift_coins = 0;
|
||||
}
|
||||
}
|
||||
$addMoney = bcadd($playerRechargeRecord->coins, $playerRechargeRecord->gift_coins, 2);
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
/** @var Player $player */
|
||||
$player = Player::query()->find($playerRechargeRecord->player_id);
|
||||
$playerRechargeRecord->status = PlayerRechargeRecord::STATUS_RECHARGED_SUCCESS;
|
||||
$playerRechargeRecord->finish_time = date("Y-m-d H:i:s");
|
||||
$playerRechargeRecord->notify_result = json_encode($data);
|
||||
$playerRechargeRecord->save();
|
||||
$beforeGameAmount = $player->wallet->money;
|
||||
// 更新钱包
|
||||
$player->wallet->money = bcadd($player->wallet->money, $addMoney, 2);
|
||||
$player->player_extend->recharge_amount = bcadd($player->player_extend->recharge_amount, $addMoney, 2);
|
||||
$player->push();
|
||||
//寫入金流明細
|
||||
$playerDeliveryRecord = new PlayerDeliveryRecord;
|
||||
$playerDeliveryRecord->player_id = $player->id;
|
||||
$playerDeliveryRecord->department_id = $player->department_id;
|
||||
$playerDeliveryRecord->target = $playerRechargeRecord->getTable();
|
||||
$playerDeliveryRecord->target_id = $playerRechargeRecord->id;
|
||||
$playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_RECHARGE;
|
||||
$playerDeliveryRecord->source = 'self_recharge';
|
||||
$playerDeliveryRecord->amount = $addMoney;
|
||||
$playerDeliveryRecord->amount_before = $beforeGameAmount;
|
||||
$playerDeliveryRecord->amount_after = $player->wallet->money;
|
||||
$playerDeliveryRecord->tradeno = '';
|
||||
$playerDeliveryRecord->remark = '';
|
||||
$playerDeliveryRecord->save();
|
||||
DB::commit();
|
||||
sendSocketMessage('private-recharge_withdrawal', [
|
||||
'msg_type' => 'recharge',
|
||||
'player_id' => $player->id,
|
||||
'amount' => $player->wallet->money,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
Log::info('sklRecharge', (array)$data);
|
||||
return json_encode(['status' => 'RECEIVED']);
|
||||
}
|
||||
return json_encode(['status' => 'RECEIVED']);
|
||||
} else {
|
||||
$playerRechargeRecord->status = PlayerRechargeRecord::STATUS_RECHARGED_FAIL;
|
||||
$playerRechargeRecord->cancel_time = date('Y-m-d H:i:s');
|
||||
$playerRechargeRecord->notify_result = json_encode($data);
|
||||
$playerRechargeRecord->save();
|
||||
return json_encode(['status' => 'RECEIVED']);
|
||||
}
|
||||
} else {
|
||||
return json_encode(['status' => 'RECEIVED']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SKL代付回调
|
||||
* @param Request $request
|
||||
* @return string
|
||||
*/
|
||||
public function sklWithdrawalNotify(Request $request): string
|
||||
{
|
||||
$data = $request->all();
|
||||
if ($data['status'] && $data['invoice_no']) {
|
||||
//查询订单是否存在
|
||||
/** @var PlayerWithdrawRecord $playerWithdrawRecord */
|
||||
$playerWithdrawRecord = PlayerWithdrawRecord::query()->where('tradeno', $data['invoice_no'])->where('status', 1)->first();
|
||||
if(empty($playerWithdrawRecord) || $playerWithdrawRecord->money != $data['amount']){
|
||||
return 'FAIL';
|
||||
}
|
||||
if ($data['status'] == 'SUCCESS') {
|
||||
$playerWithdrawRecord->status = PlayerWithdrawRecord::STATUS_SUCCESS;
|
||||
$playerWithdrawRecord->finish_time = date('Y-m-d H:i:s');
|
||||
$playerWithdrawRecord->notify_result = json_encode($data);
|
||||
$playerWithdrawRecord->talk_tradeno = $data['transferOut_id'];
|
||||
$playerWithdrawRecord->save();
|
||||
$broadcast = Broadcast::query()
|
||||
->where('type', 2)
|
||||
->where('status', 1)
|
||||
->where('min_money', '<=', $data['amount'])
|
||||
->first();
|
||||
if (isset($broadcast)){
|
||||
$queue = 'broadcast_tasks';
|
||||
$broadcast_data = [
|
||||
'user_id' => substr($playerWithdrawRecord->player->phone, 2),
|
||||
'money' => $data['amount']
|
||||
];
|
||||
for ($i = 0; $i < $broadcast->copy_num; $i++) {
|
||||
Redis::send($queue, $broadcast_data);
|
||||
}
|
||||
}
|
||||
$notice = new Notice();
|
||||
$notice->department_id = $playerWithdrawRecord->player->department_id;
|
||||
$notice->player_id = $playerWithdrawRecord->player_id;
|
||||
$notice->source_id = $playerWithdrawRecord->id;
|
||||
$notice->type = Notice::TYPE_WITHDRAW;
|
||||
$notice->receiver = Notice::RECEIVER_PLAYER;
|
||||
$notice->is_private = 1;
|
||||
$notice->title = '下分成功';
|
||||
$notice->content = '本次申请已成功处理,下分 ' . $playerWithdrawRecord->money . ' ,请查收。 ';
|
||||
$notice->save();
|
||||
return json_encode(['status' => 'RECEIVED']);
|
||||
} else {
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
/** @var Player $player */
|
||||
$player = Player::query()->find($playerWithdrawRecord->player_id);
|
||||
$playerWithdrawRecord->status = PlayerWithdrawRecord::STATUS_FAIL;
|
||||
$playerWithdrawRecord->cancel_time = date('Y-m-d H:i:s');
|
||||
$playerWithdrawRecord->notify_result = json_encode($data);
|
||||
$playerWithdrawRecord->talk_tradeno = $data['transferOut_id'];
|
||||
$playerWithdrawRecord->save();
|
||||
$beforeGameAmount = $player->wallet->money;
|
||||
// 更新钱包
|
||||
$player->wallet->money = bcadd($player->wallet->money, $playerWithdrawRecord->coins, 2);
|
||||
$player->push();
|
||||
//寫入金流明細
|
||||
$playerDeliveryRecord = new PlayerDeliveryRecord;
|
||||
$playerDeliveryRecord->player_id = $player->id;
|
||||
$playerDeliveryRecord->department_id = $player->department_id;
|
||||
$playerDeliveryRecord->target = $playerWithdrawRecord->getTable();
|
||||
$playerDeliveryRecord->target_id = $playerWithdrawRecord->id;
|
||||
$playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_WITHDRAWAL_BACK;
|
||||
$playerDeliveryRecord->source = 'channel_withdrawal';
|
||||
$playerDeliveryRecord->amount = $playerWithdrawRecord->coins;
|
||||
$playerDeliveryRecord->amount_before = $beforeGameAmount;
|
||||
$playerDeliveryRecord->amount_after = $player->wallet->money;
|
||||
$playerDeliveryRecord->tradeno = '';
|
||||
$playerDeliveryRecord->remark = '提现失败返还金额';
|
||||
$playerDeliveryRecord->save();
|
||||
$notice = new Notice();
|
||||
$notice->department_id = $player->department_id;
|
||||
$notice->player_id = $player->id;
|
||||
$notice->source_id = $playerWithdrawRecord->id;
|
||||
$notice->type = Notice::TYPE_WITHDRAW;
|
||||
$notice->receiver = Notice::RECEIVER_PLAYER;
|
||||
$notice->is_private = 1;
|
||||
$notice->title = '下分失败';
|
||||
$notice->content = '本次申请下分 ' . $playerWithdrawRecord->money . ' 已退回,请查收。 ';
|
||||
$notice->save();
|
||||
DB::commit();
|
||||
sendSocketMessage('private-recharge_withdrawal', [
|
||||
'msg_type' => 'withdrawal',
|
||||
'player_id' => $player->id,
|
||||
'amount' => $player->wallet->money,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
Log::info('sklWithdrawal', (array)$data);
|
||||
return json_encode(['status' => 'RECEIVED']);
|
||||
}
|
||||
return json_encode(['status' => 'RECEIVED']);
|
||||
}
|
||||
} else {
|
||||
return json_encode(['status' => 'RECEIVED']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SKL订单查询
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function sklQuery(Request $request): Response
|
||||
{
|
||||
$validator = v::key('transactionId', v::stringType()->notEmpty()->setName(trans('certificate', [], 'message')));
|
||||
$data = $request->get();
|
||||
try {
|
||||
$validator->assert($data);
|
||||
} catch (AllOfException $e) {
|
||||
return jsonFailResponse(getValidationMessages($e));
|
||||
}
|
||||
$params = [
|
||||
'orderNo' => $data['transactionId'],
|
||||
];
|
||||
$res = (new SklPayServices())->query($params);
|
||||
if ($res['status'] == 'SUCCESS') {
|
||||
return view('skl/detail_success');
|
||||
} elseif ($res['status'] == 'FAILED') {
|
||||
return view('skl/detail_fail');
|
||||
} elseif ($res['status'] == 'PENDING_QR') {
|
||||
return view('skl/detail_paying');
|
||||
} elseif ($res['status'] == 'VERIFIED') {
|
||||
return view('skl/detail_paying');
|
||||
} else {
|
||||
return view('sepay/detail_fail');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
14
app/external/view/login/download.html
vendored
Normal file
14
app/external/view/login/download.html
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<!-- <link rel="icon" type="image/svg+xml" href="/vite.svg" />-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>SamSung88</title>
|
||||
<script type="module" crossorigin src="/external/assets/index-DrUgyNgB.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/external/assets/index-DB4XlpIQ.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
14
app/external/view/login/index.html
vendored
Normal file
14
app/external/view/login/index.html
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<!-- <link rel="icon" type="image/svg+xml" href="/vite.svg" />-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>SamSung88</title>
|
||||
<script type="module" crossorigin src="/external/assets/index-BZ3xB-zH.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/external/assets/index-DB4XlpIQ.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
126
app/external/view/sepay/detail.html
vendored
Normal file
126
app/external/view/sepay/detail.html
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>页面</title>
|
||||
<style>
|
||||
/* 页面整体居中 */
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 20px;
|
||||
margin: 10px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 按钮图标样式 */
|
||||
img {
|
||||
margin-right: 8px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* 隐藏按钮 */
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
// 获取 URL 中的参数
|
||||
function getUrlParameter(name) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get(name);
|
||||
}
|
||||
|
||||
// 页面加载后根据 URL 参数决定显示的按钮
|
||||
window.onload = function () {
|
||||
const status = getUrlParameter('status');
|
||||
const orderNo = getUrlParameter('orderNo');
|
||||
|
||||
// 填充订单号
|
||||
if (orderNo) {
|
||||
document.getElementById('orderNoField').innerHTML = `订单号: ${orderNo}`;
|
||||
document.getElementById('orderNoField1').innerHTML = `订单号: ${orderNo}`;
|
||||
document.getElementById('orderNoField2').innerHTML = `订单号: ${orderNo}`;
|
||||
} else {
|
||||
document.getElementById('orderNoField').innerHTML = '订单号: 未找到';
|
||||
}
|
||||
|
||||
// 根据 type 参数设置按钮
|
||||
const closeButton = document.getElementById('closeButton');
|
||||
const refreshButton = document.getElementById('refreshButton');
|
||||
const loadButton = document.getElementById('loadButton');
|
||||
|
||||
closeButton.classList.add('hidden');
|
||||
refreshButton.classList.add('hidden');
|
||||
loadButton.classList.add('hidden');
|
||||
|
||||
if (status == '1') {
|
||||
closeButton.classList.remove('hidden');
|
||||
} else if (status == '2') {
|
||||
refreshButton.classList.remove('hidden');
|
||||
} else if (status == '3') {
|
||||
loadButton.classList.remove('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
// 关闭页面
|
||||
function closePage() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
// 刷新页面
|
||||
function refreshPage() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// 加载页面内容
|
||||
function loadContent() {
|
||||
alert('加载内容');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- <h1>按钮操作</h1> -->
|
||||
|
||||
<div id="closeButton" class="hidden">
|
||||
<img src="./img/icon01.png" alt="关闭" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">支付成功</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField"></strong></div>
|
||||
<button style="background-color: #1ab56a;margin-top: 30px;" onclick="closePage()">返回游戏</button>
|
||||
</div>
|
||||
<div id="refreshButton" class="hidden">
|
||||
<img src="./img/icon02.png" alt="关闭" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">支付失败</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField1"></strong></div>
|
||||
<button style="background-color: #ca2f11;margin-top: 30px;" onclick="closePage()">返回游戏</button>
|
||||
</div>
|
||||
<div id="loadButton" class="hidden">
|
||||
<img src="./img/icon03.png" alt="刷新" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">获取支付状态中...</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField2"></strong></div>
|
||||
<button style="background-color: #d78e0e;margin-top: 30px;" onclick="refreshPage()">刷新状态</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
91
app/external/view/sepay/detail_fail.html
vendored
Normal file
91
app/external/view/sepay/detail_fail.html
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>页面</title>
|
||||
<style>
|
||||
/* 页面整体居中 */
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 20px;
|
||||
margin: 10px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 按钮图标样式 */
|
||||
img {
|
||||
margin-right: 8px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
// 获取 URL 中的参数
|
||||
function getUrlParameter(name) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get(name);
|
||||
}
|
||||
|
||||
// 页面加载后根据 URL 参数决定显示的按钮
|
||||
window.onload = function () {
|
||||
const orderNo = getUrlParameter('orderNo');
|
||||
|
||||
// 填充订单号
|
||||
if (orderNo) {
|
||||
document.getElementById('orderNoField').innerHTML = `订单号: ${orderNo}`;
|
||||
} else {
|
||||
document.getElementById('orderNoField').innerHTML = '订单号: 未找到';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// 关闭页面
|
||||
function closePage() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
// 刷新页面
|
||||
function refreshPage() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// 加载页面内容
|
||||
function loadContent() {
|
||||
alert('加载内容');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- <h1>按钮操作</h1> -->
|
||||
|
||||
<div id="refreshButton" class="hidden">
|
||||
<img src="./img/icon02.png" alt="关闭" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">支付失败</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField"></strong></div>
|
||||
<button style="background-color: #ca2f11;margin-top: 30px;" onclick="closePage()">返回游戏</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
90
app/external/view/sepay/detail_paying.html
vendored
Normal file
90
app/external/view/sepay/detail_paying.html
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>页面</title>
|
||||
<style>
|
||||
/* 页面整体居中 */
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 20px;
|
||||
margin: 10px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 按钮图标样式 */
|
||||
img {
|
||||
margin-right: 8px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
// 获取 URL 中的参数
|
||||
function getUrlParameter(name) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get(name);
|
||||
}
|
||||
|
||||
// 页面加载后根据 URL 参数决定显示的按钮
|
||||
window.onload = function () {
|
||||
const orderNo = getUrlParameter('orderNo');
|
||||
// 填充订单号
|
||||
if (orderNo) {
|
||||
document.getElementById('orderNoField').innerHTML = `订单号: ${orderNo}`;
|
||||
} else {
|
||||
document.getElementById('orderNoField').innerHTML = '订单号: 未找到';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// 关闭页面
|
||||
function closePage() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
// 刷新页面
|
||||
function refreshPage() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// 加载页面内容
|
||||
function loadContent() {
|
||||
alert('加载内容');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- <h1>按钮操作</h1> -->
|
||||
|
||||
<div id="loadButton" class="hidden">
|
||||
<img src="./img/icon03.png" alt="刷新" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">获取支付状态中...</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField"></strong></div>
|
||||
<button style="background-color: #d78e0e;margin-top: 30px;" onclick="refreshPage()">刷新状态</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
91
app/external/view/sepay/detail_success.html
vendored
Normal file
91
app/external/view/sepay/detail_success.html
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>页面</title>
|
||||
<style>
|
||||
/* 页面整体居中 */
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 20px;
|
||||
margin: 10px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 按钮图标样式 */
|
||||
img {
|
||||
margin-right: 8px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
// 获取 URL 中的参数
|
||||
function getUrlParameter(name) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get(name);
|
||||
}
|
||||
|
||||
// 页面加载后根据 URL 参数决定显示的按钮
|
||||
window.onload = function () {
|
||||
const orderNo = getUrlParameter('orderNo');
|
||||
|
||||
// 填充订单号
|
||||
if (orderNo) {
|
||||
document.getElementById('orderNoField').innerHTML = `订单号: ${orderNo}`;
|
||||
} else {
|
||||
document.getElementById('orderNoField').innerHTML = '订单号: 未找到';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// 关闭页面
|
||||
function closePage() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
// 刷新页面
|
||||
function refreshPage() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// 加载页面内容
|
||||
function loadContent() {
|
||||
alert('加载内容');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- <h1>按钮操作</h1> -->
|
||||
|
||||
<div id="closeButton">
|
||||
<img src="./img/icon01.png" alt="关闭" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">支付成功</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField"></strong></div>
|
||||
<button style="background-color: #1ab56a;margin-top: 30px;" onclick="closePage()">返回游戏</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
126
app/external/view/skl/detail.html
vendored
Normal file
126
app/external/view/skl/detail.html
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>页面</title>
|
||||
<style>
|
||||
/* 页面整体居中 */
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 20px;
|
||||
margin: 10px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 按钮图标样式 */
|
||||
img {
|
||||
margin-right: 8px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* 隐藏按钮 */
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
// 获取 URL 中的参数
|
||||
function getUrlParameter(name) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get(name);
|
||||
}
|
||||
|
||||
// 页面加载后根据 URL 参数决定显示的按钮
|
||||
window.onload = function () {
|
||||
const status = getUrlParameter('status');
|
||||
const orderNo = getUrlParameter('orderNo');
|
||||
|
||||
// 填充订单号
|
||||
if (orderNo) {
|
||||
document.getElementById('transactionId').innerHTML = `订单号: ${orderNo}`;
|
||||
document.getElementById('orderNoField1').innerHTML = `订单号: ${orderNo}`;
|
||||
document.getElementById('orderNoField2').innerHTML = `订单号: ${orderNo}`;
|
||||
} else {
|
||||
document.getElementById('orderNoField').innerHTML = '订单号: 未找到';
|
||||
}
|
||||
|
||||
// 根据 type 参数设置按钮
|
||||
const closeButton = document.getElementById('closeButton');
|
||||
const refreshButton = document.getElementById('refreshButton');
|
||||
const loadButton = document.getElementById('loadButton');
|
||||
|
||||
closeButton.classList.add('hidden');
|
||||
refreshButton.classList.add('hidden');
|
||||
loadButton.classList.add('hidden');
|
||||
|
||||
if (status == '1') {
|
||||
closeButton.classList.remove('hidden');
|
||||
} else if (status == '2') {
|
||||
refreshButton.classList.remove('hidden');
|
||||
} else if (status == '3') {
|
||||
loadButton.classList.remove('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
// 关闭页面
|
||||
function closePage() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
// 刷新页面
|
||||
function refreshPage() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// 加载页面内容
|
||||
function loadContent() {
|
||||
alert('加载内容');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- <h1>按钮操作</h1> -->
|
||||
|
||||
<div id="closeButton" class="hidden">
|
||||
<img src="./img/icon01.png" alt="关闭" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">支付成功</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField"></strong></div>
|
||||
<button style="background-color: #1ab56a;margin-top: 30px;" onclick="closePage()">返回游戏</button>
|
||||
</div>
|
||||
<div id="refreshButton" class="hidden">
|
||||
<img src="./img/icon02.png" alt="关闭" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">支付失败</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField1"></strong></div>
|
||||
<button style="background-color: #ca2f11;margin-top: 30px;" onclick="closePage()">返回游戏</button>
|
||||
</div>
|
||||
<div id="loadButton" class="hidden">
|
||||
<img src="./img/icon03.png" alt="刷新" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">获取支付状态中...</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField2"></strong></div>
|
||||
<button style="background-color: #d78e0e;margin-top: 30px;" onclick="refreshPage()">刷新状态</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
97
app/external/view/skl/detail_fail.html
vendored
Normal file
97
app/external/view/skl/detail_fail.html
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>页面</title>
|
||||
<style>
|
||||
/* 页面整体居中 */
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 20px;
|
||||
margin: 10px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 按钮图标样式 */
|
||||
img {
|
||||
margin-right: 8px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
// 获取 URL 中的参数
|
||||
function getInvoiceNoFromUrl(name) {
|
||||
try {
|
||||
const fullUrl = window.location.href;
|
||||
const params = new URL(fullUrl).searchParams;
|
||||
const rawValue = params.get(name);
|
||||
if (!rawValue) return "";
|
||||
return rawValue.split("?")[0];
|
||||
} catch (err) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
// 页面加载后根据 URL 参数决定显示的按钮
|
||||
window.onload = function () {
|
||||
const orderNo = getInvoiceNoFromUrl('invoiceNo');
|
||||
|
||||
// 填充订单号
|
||||
if (orderNo) {
|
||||
document.getElementById('orderNoField').innerHTML = `订单号: ${orderNo}`;
|
||||
} else {
|
||||
document.getElementById('orderNoField').innerHTML = '订单号: 未找到';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// 关闭页面
|
||||
function closePage() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
// 刷新页面
|
||||
function refreshPage() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// 加载页面内容
|
||||
function loadContent() {
|
||||
alert('加载内容');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- <h1>按钮操作</h1> -->
|
||||
|
||||
<div id="refreshButton" class="hidden">
|
||||
<img src="../img/icon02.png" alt="关闭" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">支付失败</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField"></strong></div>
|
||||
<button style="background-color: #ca2f11;margin-top: 30px;" onclick="closePage()">返回游戏</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
97
app/external/view/skl/detail_paying.html
vendored
Normal file
97
app/external/view/skl/detail_paying.html
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>页面</title>
|
||||
<style>
|
||||
/* 页面整体居中 */
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 20px;
|
||||
margin: 10px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 按钮图标样式 */
|
||||
img {
|
||||
margin-right: 8px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
// 获取 URL 中的参数
|
||||
function getInvoiceNoFromUrl(name) {
|
||||
try {
|
||||
const fullUrl = window.location.href;
|
||||
const params = new URL(fullUrl).searchParams;
|
||||
const rawValue = params.get(name);
|
||||
if (!rawValue) return "";
|
||||
return rawValue.split("?")[0];
|
||||
} catch (err) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
// 页面加载后根据 URL 参数决定显示的按钮
|
||||
window.onload = function () {
|
||||
const orderNo = getInvoiceNoFromUrl('invoiceNo');
|
||||
|
||||
// 填充订单号
|
||||
if (orderNo) {
|
||||
document.getElementById('orderNoField').innerHTML = `订单号: ${orderNo}`;
|
||||
} else {
|
||||
document.getElementById('orderNoField').innerHTML = '订单号: 未找到';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// 关闭页面
|
||||
function closePage() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
// 刷新页面
|
||||
function refreshPage() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// 加载页面内容
|
||||
function loadContent() {
|
||||
alert('加载内容');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- <h1>按钮操作</h1> -->
|
||||
|
||||
<div id="loadButton" class="hidden">
|
||||
<img src="../img/icon03.png" alt="刷新" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">获取支付状态中...</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField"></strong></div>
|
||||
<button style="background-color: #d78e0e;margin-top: 30px;" onclick="refreshPage()">刷新状态</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
97
app/external/view/skl/detail_success.html
vendored
Normal file
97
app/external/view/skl/detail_success.html
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>页面</title>
|
||||
<style>
|
||||
/* 页面整体居中 */
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 20px;
|
||||
margin: 10px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 按钮图标样式 */
|
||||
img {
|
||||
margin-right: 8px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
// 获取 URL 中的参数
|
||||
function getInvoiceNoFromUrl(name) {
|
||||
try {
|
||||
const fullUrl = window.location.href;
|
||||
const params = new URL(fullUrl).searchParams;
|
||||
const rawValue = params.get(name);
|
||||
if (!rawValue) return "";
|
||||
return rawValue.split("?")[0];
|
||||
} catch (err) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
// 页面加载后根据 URL 参数决定显示的按钮
|
||||
window.onload = function () {
|
||||
const orderNo = getInvoiceNoFromUrl('invoiceNo');
|
||||
|
||||
// 填充订单号
|
||||
if (orderNo) {
|
||||
document.getElementById('orderNoField').innerHTML = `订单号: ${orderNo}`;
|
||||
} else {
|
||||
document.getElementById('orderNoField').innerHTML = '订单号: 未找到';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// 关闭页面
|
||||
function closePage() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
// 刷新页面
|
||||
function refreshPage() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// 加载页面内容
|
||||
function loadContent() {
|
||||
alert('加载内容');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- <h1>按钮操作</h1> -->
|
||||
|
||||
<div id="closeButton">
|
||||
<img src="../img/icon01.png" alt="关闭" style="width: 200px;height: 200px;">
|
||||
<div style="font-size: 18px;margin-top: 30px;">支付成功</div>
|
||||
<div style="font-size: 18px;margin-top: 30px;"><strong id="orderNoField"></strong></div>
|
||||
<button style="background-color: #1ab56a;margin-top: 30px;" onclick="closePage()">返回游戏</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1379
app/functions.php
Normal file
1379
app/functions.php
Normal file
@@ -0,0 +1,1379 @@
|
||||
<?php
|
||||
/**
|
||||
* Here is your custom functions.
|
||||
*/
|
||||
|
||||
use addons\webman\Admin;
|
||||
use addons\webman\model\Channel;
|
||||
use addons\webman\model\ChannelFinancialRecord;
|
||||
use addons\webman\model\CommissionRecord;
|
||||
use addons\webman\model\GamePlatform;
|
||||
use addons\webman\model\PhoneSmsLog;
|
||||
use addons\webman\model\Player;
|
||||
use addons\webman\model\PlayerBankruptcyRecord;
|
||||
use addons\webman\model\PlayerChipRecord;
|
||||
use addons\webman\model\PlayerDeliveryRecord;
|
||||
use addons\webman\model\PlayerExtend;
|
||||
use addons\webman\model\PlayerLoginRecord;
|
||||
use addons\webman\model\PlayerMoneyEditLog;
|
||||
use addons\webman\model\PlayerPlatformCash;
|
||||
use addons\webman\model\PlayerRechargeRecord;
|
||||
use addons\webman\model\PlayerRegisterRecord;
|
||||
use addons\webman\model\PlayerWalletTransfer;
|
||||
use addons\webman\model\PlayerWithdrawRecord;
|
||||
use addons\webman\model\PlayGameRecord;
|
||||
use addons\webman\model\PromoterProfitSettlementRecord;
|
||||
use addons\webman\model\SystemSetting;
|
||||
use app\exception\GameException;
|
||||
use app\exception\PlayerCheckException;
|
||||
use app\service\game\GameServiceFactory;
|
||||
use Carbon\Carbon;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Illuminate\Support\Arr;
|
||||
use Respect\Validation\Exceptions\AllOfException;
|
||||
use support\Cache;
|
||||
use support\Db;
|
||||
use support\Log;
|
||||
use support\Model;
|
||||
use support\Response;
|
||||
use think\Exception;
|
||||
use Tinywan\Jwt\JwtToken;
|
||||
use Webman\Push\Api;
|
||||
use Webman\Push\PushException;
|
||||
use WebmanTech\LaravelHttpClient\Facades\Http;
|
||||
use Workbunny\WebmanIpAttribution\Exceptions\IpAttributionException;
|
||||
use Workbunny\WebmanIpAttribution\Location;
|
||||
use addons\webman\model\PlayerPromoter;
|
||||
use addons\webman\model\PromoterProfitRecord;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param string $message
|
||||
* @return Response
|
||||
*/
|
||||
function jsonSuccessResponse(string $message = '', array $data = []): Response
|
||||
{
|
||||
return new Response(200, ['Content-Type' => 'application/json'], json_encode([
|
||||
'code' => 200,
|
||||
'msg' => $message,
|
||||
'data' => $data,
|
||||
], JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param string $message
|
||||
* @param integer $code
|
||||
* @return Response
|
||||
*/
|
||||
function jsonFailResponse(string $message = '', array $data = [], int $code = 100): Response
|
||||
{
|
||||
return new Response(200, ['Content-Type' => 'application/json'], json_encode([
|
||||
'code' => $code,
|
||||
'msg' => $message,
|
||||
'data' => $data,
|
||||
], JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成唯一邀请码
|
||||
* @return string
|
||||
*/
|
||||
function createCode(): string
|
||||
{
|
||||
|
||||
$code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
$rand = $code[rand(0, 25)] . strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));
|
||||
|
||||
for ($a = md5($rand, true), $s = '0123456789ABCDEFGHIJKLMNOPQRSTUV', $d = '', $f = 0; $f < 8; $g = ord($a[$f]), $d .= $s[($g ^ ord($a[$f + 8])) - $g & 0x1F], $f++) ;
|
||||
|
||||
return $d;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证消息
|
||||
* @param AllOfException $e
|
||||
* @return mixed
|
||||
*/
|
||||
function getValidationMessages(AllOfException $e)
|
||||
{
|
||||
$message = $e->getMessages([
|
||||
'notOptional' => trans('required', [], 'validator'),
|
||||
'notEmpty' => trans('required', [], 'validator'),
|
||||
'email' => trans('email', [], 'validator'),
|
||||
'idCard' => trans('idCard', [], 'validator'),
|
||||
'url' => trans('url', [], 'validator'),
|
||||
'number' => trans('number', [], 'validator'),
|
||||
'integer' => trans('integer', [], 'validator'),
|
||||
'float' => trans('float', [], 'validator'),
|
||||
'mobile' => trans('mobile', [], 'validator'),
|
||||
'length' => trans('length', [], 'validator'),
|
||||
'alpha' => trans('alpha', [], 'validator'),
|
||||
'alnum' => trans('alnum', [], 'validator'),
|
||||
'alphaDash' => trans('alphaDash', [], 'validator'),
|
||||
'chs' => trans('chs', [], 'validator'),
|
||||
'chsAlpha' => trans('chsAlpha', [], 'validator'),
|
||||
'chsAlphaNum' => trans('chsAlphaNum', [], 'validator'),
|
||||
'chsDash' => trans('chsDash', [], 'validator'),
|
||||
'equals' => trans('equals', [], 'validator'),
|
||||
'in' => trans('in', [], 'validator'),
|
||||
'image' => trans('image', [], 'validator'),
|
||||
'creditCard' => trans('creditCard', [], 'validator'),
|
||||
'digit' => trans('digit', [], 'validator'),
|
||||
'base64' => trans('base64', [], 'validator'),
|
||||
'arrayVal' => trans('arrayVal', [], 'validator'),
|
||||
])['key'];
|
||||
$message = is_array($message) ? Arr::first($message) : $message;
|
||||
|
||||
return $message ?? trans('validation_error', [], 'message');
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成uuid
|
||||
* @return string
|
||||
*/
|
||||
function gen_uuid(): string
|
||||
{
|
||||
do {
|
||||
$timestamp = time();
|
||||
$randomNumber = str_pad(rand(0, 9999), 4, '0', STR_PAD_LEFT);
|
||||
$uniqueNumericId = substr($timestamp, -5) . $randomNumber;
|
||||
|
||||
} while (Player::query()->where('uuid', $uniqueNumericId)->withTrashed()->exists());
|
||||
|
||||
return $uniqueNumericId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 金额转换
|
||||
* @param $number
|
||||
* @return float|int
|
||||
*/
|
||||
function floorToCoinsSecondNumber($number)
|
||||
{
|
||||
return floor($number * 100) / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户登录信息
|
||||
* @param $id
|
||||
* @return PlayerLoginRecord|Model
|
||||
*/
|
||||
function addLoginRecord($id)
|
||||
{
|
||||
$ip = request()->getRealIp();
|
||||
if (!empty($ip)) {
|
||||
try {
|
||||
$location = new Location();
|
||||
$result = $location->getLocation($ip);
|
||||
} catch (IpAttributionException $exception) {
|
||||
Log::error('获取ip信息错误');
|
||||
}
|
||||
}
|
||||
$country_name = ($result['country'] ?? '') . ($result['city'] ?? '');
|
||||
$domain = isset($_SERVER['HTTP_ORIGIN']) ? parse_url($_SERVER['HTTP_ORIGIN']) : null;
|
||||
|
||||
return PlayerLoginRecord::create([
|
||||
'player_id' => $id,
|
||||
'login_domain' => !empty($domain) ? $domain['host'] : null,
|
||||
'ip' => $ip,
|
||||
'country_name' => $country_name,
|
||||
'city_name' => $result['city'] ?? '',
|
||||
'remark' => $request->remark ?? null,
|
||||
'department_id' => request()->department_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户注册信息
|
||||
* @param $id
|
||||
* @param $type
|
||||
* @param $department_id
|
||||
* @return PlayerRegisterRecord|Model
|
||||
*/
|
||||
function addRegisterRecord($id, $type, $department_id)
|
||||
{
|
||||
$ip = request()->getRealIp();
|
||||
if (!empty($ip)) {
|
||||
try {
|
||||
$location = new Location();
|
||||
$result = $location->getLocation($ip);
|
||||
} catch (IpAttributionException $exception) {
|
||||
Log::error('获取ip信息错误');
|
||||
}
|
||||
}
|
||||
$country_name = ($result['country'] ?? '') . ($result['city'] ?? '');
|
||||
$domain = isset($_SERVER['HTTP_ORIGIN']) ? parse_url($_SERVER['HTTP_ORIGIN']) : null;
|
||||
|
||||
return PlayerRegisterRecord::create([
|
||||
'player_id' => $id,
|
||||
'register_domain' => !empty($domain) ? $domain['host'] : null,
|
||||
'ip' => $ip,
|
||||
'country_name' => $country_name,
|
||||
'city_name' => $result['city'] ?? '',
|
||||
'device' => 'app',
|
||||
'type' => $type,
|
||||
'department_id' => $department_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存头像到本地
|
||||
* @param $avatar
|
||||
* @return string
|
||||
*/
|
||||
function saveAvatar($avatar): string
|
||||
{
|
||||
if (empty($avatar)) {
|
||||
return '';
|
||||
}
|
||||
try {
|
||||
if (strpos($avatar, 'http://') === 0 || strpos($avatar, 'https://') === 0) {
|
||||
$client = new Client(['verify' => false]); //忽略SSL错误
|
||||
$fileName = md5($avatar) . '.jpg';
|
||||
$path = public_path() . '/storage/avatar/';
|
||||
if (!is_dir($path) && !mkdir($path, 0777, true)) {
|
||||
throw new Exception('创建文件夹失败');
|
||||
}
|
||||
$client->request('GET', $avatar, ['sink' => public_path('/storage/avatar/' . $fileName)]);
|
||||
} else {
|
||||
throw new Exception('网络地址错误');
|
||||
}
|
||||
} catch (Exception|GuzzleException $e) {
|
||||
Log::error('保存头像错误' . $e->getMessage());
|
||||
return '';
|
||||
}
|
||||
|
||||
return '/storage/avatar/' . $fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成唯一单号
|
||||
* @return string
|
||||
*/
|
||||
function createOrderNo(): string
|
||||
{
|
||||
|
||||
$yCode = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
|
||||
return $yCode[intval(date('Y')) - 2011] . strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置短信key
|
||||
* @param string $phone 手机号
|
||||
* @param int $type 模式 1 为修改密码短信
|
||||
* @return string
|
||||
*/
|
||||
function setSmsKey(string $phone, int $type): string
|
||||
{
|
||||
switch ($type) {
|
||||
case PhoneSmsLog::TYPE_LOGIN:
|
||||
return 'sms-login' . $phone;
|
||||
case PhoneSmsLog::TYPE_REGISTER:
|
||||
return 'sms-register' . $phone;
|
||||
case PhoneSmsLog::TYPE_CHANGE_PASSWORD:
|
||||
return 'sms-change-password' . $phone;
|
||||
case PhoneSmsLog::TYPE_CHANGE_PAY_PASSWORD:
|
||||
return 'sms-change-pay-password' . $phone;
|
||||
case PhoneSmsLog::TYPE_CHANGE_PHONE:
|
||||
return 'sms-change-phone' . $phone;
|
||||
case PhoneSmsLog::TYPE_BIND_NEW_PHONE:
|
||||
return 'sms-type-bind-new-phone' . $phone;
|
||||
case PhoneSmsLog::TYPE_TALK_BIND:
|
||||
return 'sms-type-talk-bind' . $phone;
|
||||
default:
|
||||
return 'sms-' . $phone;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证短信
|
||||
* @param string $country_code 国家编号
|
||||
* @param string $phone 手机号
|
||||
* @param string $code 验证码
|
||||
* @param int $type 类型
|
||||
* @return string
|
||||
*/
|
||||
function verifySMS(string $country_code, string $phone, string $code, int $type): string
|
||||
{
|
||||
switch ($country_code) {
|
||||
case PhoneSmsLog::COUNTRY_CODE_JP:
|
||||
$phone = ltrim($phone, '0');
|
||||
break;
|
||||
case PhoneSmsLog::COUNTRY_CODE_MY:
|
||||
$phone = ltrim($phone, '0');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$phoneCode = Cache::get(setSmsKey($phone, $type));
|
||||
|
||||
return $phoneCode == $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取短信消息
|
||||
* @param int $type 模式 1 为修改密码短信
|
||||
* @param string $source 来源
|
||||
* @return string
|
||||
*/
|
||||
function getContent(int $type, string $source): string
|
||||
{
|
||||
switch ($type) {
|
||||
case PhoneSmsLog::TYPE_LOGIN:
|
||||
return config($source . '-sms.login_content');
|
||||
case PhoneSmsLog::TYPE_REGISTER:
|
||||
return config($source . '-sms.register_content');
|
||||
case PhoneSmsLog::TYPE_CHANGE_PASSWORD:
|
||||
return config($source . '-sms.change_password_content');
|
||||
case PhoneSmsLog::TYPE_CHANGE_PAY_PASSWORD:
|
||||
return config($source . '-sms.change_pay_password');
|
||||
case PhoneSmsLog::TYPE_CHANGE_PHONE:
|
||||
return config($source . '-sms.change_phone');
|
||||
case PhoneSmsLog::TYPE_BIND_NEW_PHONE:
|
||||
return config($source . '-sms.bind_new_phone');
|
||||
case PhoneSmsLog::TYPE_TALK_BIND:
|
||||
return config($source . '-sms.talk_bind');
|
||||
default:
|
||||
return config($source . '-sms.sm_content');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提现订单回滚
|
||||
* @param PlayerWithdrawRecord $playerWithdrawRecord
|
||||
* @param string $rejectReason
|
||||
* @param int $withdrawStatus
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
function withdrawBack(PlayerWithdrawRecord $playerWithdrawRecord, string $rejectReason = '', int $withdrawStatus = PlayerWithdrawRecord::STATUS_PENDING_REJECT): string
|
||||
{
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
// 更新提现订单
|
||||
$playerWithdrawRecord->status = $withdrawStatus;
|
||||
$playerWithdrawRecord->reject_reason = $rejectReason;
|
||||
$playerWithdrawRecord->finish_time = date('Y-m-d H:i:s');
|
||||
$playerWithdrawRecord->user_id = Admin::id() ?? 0;
|
||||
$playerWithdrawRecord->user_name = !empty(Admin::user()) ? Admin::user()->username : '';
|
||||
// 更新玩家钱包
|
||||
$beforeGameAmount = $playerWithdrawRecord->player->wallet->money;
|
||||
$playerWithdrawRecord->player->wallet->money = bcadd($playerWithdrawRecord->player->wallet->money, $playerWithdrawRecord->coins, 2);
|
||||
// 跟新玩家统计
|
||||
$playerWithdrawRecord->player->player_extend->withdraw_amount = bcsub($playerWithdrawRecord->player->player_extend->withdraw_amount, $playerWithdrawRecord->coins, 2);
|
||||
$playerWithdrawRecord->push();
|
||||
//寫入金流明細
|
||||
$playerDeliveryRecord = new PlayerDeliveryRecord;
|
||||
$playerDeliveryRecord->player_id = $playerWithdrawRecord->player_id;
|
||||
$playerDeliveryRecord->department_id = $playerWithdrawRecord->department_id;
|
||||
$playerDeliveryRecord->target = $playerWithdrawRecord->getTable();
|
||||
$playerDeliveryRecord->target_id = $playerWithdrawRecord->id;
|
||||
$playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_WITHDRAWAL_BACK;
|
||||
$playerDeliveryRecord->source = 'withdraw_back';
|
||||
$playerDeliveryRecord->amount = $playerWithdrawRecord->coins;
|
||||
$playerDeliveryRecord->amount_before = $beforeGameAmount;
|
||||
$playerDeliveryRecord->amount_after = $playerWithdrawRecord->player->wallet->money;
|
||||
$playerDeliveryRecord->tradeno = $playerWithdrawRecord->tradeno ?? '';
|
||||
$playerDeliveryRecord->remark = $playerWithdrawRecord->remark ?? '';
|
||||
$playerDeliveryRecord->save();
|
||||
|
||||
DB::commit();
|
||||
sendSocketMessage('private-recharge_withdrawal', [
|
||||
'msg_type' => 'withdrawal',
|
||||
'player_id' => $playerWithdrawRecord->player_id,
|
||||
'amount' => $playerWithdrawRecord->player->wallet->money,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加渠道财务操作
|
||||
* @param $target
|
||||
* @param $action
|
||||
* @return void
|
||||
*/
|
||||
function saveChannelFinancialRecord($target, $action)
|
||||
{
|
||||
$channelFinancialRecord = new ChannelFinancialRecord();
|
||||
$channelFinancialRecord->action = $action;
|
||||
$channelFinancialRecord->department_id = Admin::user()->department_id ?? 0;
|
||||
$channelFinancialRecord->player_id = $target->player_id ?? 0;
|
||||
$channelFinancialRecord->target = $target->getTable();
|
||||
$channelFinancialRecord->target_id = $target->id;
|
||||
$channelFinancialRecord->user_id = Admin::id() ?? 0;
|
||||
$channelFinancialRecord->tradeno = $target->tradeno ?? '';
|
||||
$channelFinancialRecord->user_name = Admin::user()->username ?? '';
|
||||
$channelFinancialRecord->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传base64图片
|
||||
* @param $img
|
||||
* @param $path
|
||||
* @return false|string
|
||||
*/
|
||||
function uploadBaseImg($img, $path)
|
||||
{
|
||||
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $img, $result)) {
|
||||
$type = $result[2];//图片后缀
|
||||
$savePath = '/storage/' . $path . '/' . date("Ymd", time()) . "/";
|
||||
$newPath = public_path() . $savePath;
|
||||
if (!file_exists($newPath)) {
|
||||
//检查是否有该文件夹,如果没有就创建,并给予最高权限
|
||||
mkdir($newPath, 0755, true);
|
||||
}
|
||||
|
||||
$filename = time() . '_' . uniqid() . ".{$type}"; //文件名
|
||||
$newPath = $newPath . $filename;
|
||||
//写入操作
|
||||
if (file_put_contents($newPath, base64_decode(str_replace($result[1], '', $img)))) {
|
||||
return env('APP_URL', 'http://127.0.0.1:8787') . $savePath . $filename;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查充值订单取消超时订单
|
||||
* @throws Exception
|
||||
*/
|
||||
function cancelRecharge()
|
||||
{
|
||||
/** @var SystemSetting $setting */
|
||||
$setting = SystemSetting::where('status', 1)->where('feature', 'recharge_order_expiration')->first();
|
||||
if (!empty($setting)) {
|
||||
$playerRechargeRecord = PlayerRechargeRecord::where('type', PlayerRechargeRecord::TYPE_REGULAR)
|
||||
->where('status', PlayerRechargeRecord::STATUS_WAIT)
|
||||
->where('created_at', '<', Carbon::now()->subMinutes($setting->num))
|
||||
->get();
|
||||
/** @var PlayerRechargeRecord $order */
|
||||
foreach ($playerRechargeRecord as $order) {
|
||||
$order->status = PlayerRechargeRecord::STATUS_RECHARGED_SYSTEM_CANCEL;
|
||||
$order->cancel_time = date('Y-m-d H:i:s');
|
||||
$order->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送socket消息
|
||||
* @param $channels
|
||||
* @param $content
|
||||
* @param string $form
|
||||
* @return bool|string
|
||||
* @throws PushException
|
||||
*/
|
||||
function sendSocketMessage($channels, $content, string $form = 'system')
|
||||
{
|
||||
try {
|
||||
// 发送进入保留状态消息
|
||||
$api = new Api(
|
||||
config('plugin.webman.push.app.api'),
|
||||
config('plugin.webman.push.app.app_key'),
|
||||
config('plugin.webman.push.app.app_secret')
|
||||
);
|
||||
return $api->trigger($channels, 'message', [
|
||||
'from_uid' => $form,
|
||||
'content' => json_encode($content)
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
Log::error('sendSocketMessage', [$e->getMessage()]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取渠道信息
|
||||
* @param $siteId
|
||||
* @return array
|
||||
*/
|
||||
function getChannel($siteId): array
|
||||
{
|
||||
$cacheKey = "channel_" . $siteId;
|
||||
$channel = Cache::get($cacheKey);
|
||||
if (empty($channel)) {
|
||||
$channel = Channel::where('id', $siteId)->whereNull('deleted_at')->first()->toArray();
|
||||
if (!empty($channel)) {
|
||||
$cacheKey = "channel_" . $channel->site_id;
|
||||
Cache::set($cacheKey, $channel->toArray());
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
return $channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取堆栈信息
|
||||
* @return void
|
||||
*/
|
||||
function getStackList(): void
|
||||
{
|
||||
$line = [];
|
||||
$debugList = array_reverse(debug_backtrace());
|
||||
foreach ($debugList as $key => $val) {
|
||||
$class = $val['class'] ?? "";
|
||||
$arg = $val['args'];
|
||||
$parameter = '';
|
||||
$stringLine = '';
|
||||
if (!empty($arg) && is_array($arg)) {
|
||||
foreach ($arg as $v) {
|
||||
$className = $v;
|
||||
if (is_object($v)) {
|
||||
$className = get_class($v);
|
||||
} elseif (is_array($v)) {
|
||||
$className = json_encode($v);
|
||||
}
|
||||
$parameter .= $className . ',';
|
||||
}
|
||||
}
|
||||
$stringLine .= '程序执行' . $key . ':=>';
|
||||
$stringLine .= '[1.所在文件(' . $val['file'] . ')],';
|
||||
$stringLine .= '[2.函数调用情况[第' . $val['line'] . '行]:' . $class . '->' . $val['function'] . '(' . $parameter . ')]' . "\n";
|
||||
$line[] = $stringLine;
|
||||
}
|
||||
Log::error("堆栈信息", $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取毫秒级
|
||||
* @return float
|
||||
*/
|
||||
function millisecond(): float
|
||||
{
|
||||
list($millisecond, $sec) = explode(' ', microtime());
|
||||
return (float)sprintf('%.0f', (floatval($millisecond) + floatval($sec)) * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建玩家
|
||||
* @param $departmentId
|
||||
* @param $data
|
||||
* @return Player
|
||||
* @throws Exception
|
||||
*/
|
||||
function createPlayer($departmentId, $data): Player
|
||||
{
|
||||
/** @var Channel $channel */
|
||||
$channel = Channel::where('department_id', $departmentId)->first();
|
||||
if (empty($channel)) {
|
||||
throw new Exception(trans('channel_not_found', [], 'message'));
|
||||
}
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$count = Player::whereBetween('created_at', [date('Y-m-d') . ' 00:00:00', date('Y-m-d') . ' 23:59:59'])->count('*');
|
||||
if (empty($data['avatar'])) {
|
||||
$defAvatars = config('def_avatar') ?? [];
|
||||
$randomKey = array_rand($defAvatars);
|
||||
$randomAvatar = $defAvatars[$randomKey] ?? '';
|
||||
} else {
|
||||
$randomAvatar = $data['avatar'];
|
||||
}
|
||||
$player = new Player();
|
||||
$player->uuid = gen_uuid();
|
||||
$player->type = Player::TYPE_PLAYER;
|
||||
$player->currency = $channel->currency;
|
||||
$player->department_id = $channel->department_id;
|
||||
$player->avatar = $randomAvatar;
|
||||
$player->device_number = $data['device_number'] ?? '';
|
||||
$player->name = $data['name'] ?? 'channel_' . $departmentId . date('Ymd') . $count;
|
||||
$player->facebook_id = $data['facebook_id'] ?? '';
|
||||
$player->phone = $data['phone'] ?? '';
|
||||
if(isset($data['password'])){
|
||||
$player->password = $data['password'];
|
||||
}
|
||||
if(isset($data['recommend_id'])){
|
||||
$player->recommend_id = $data['recommend_id'];
|
||||
}
|
||||
$player->recommended_code = $data['recommended_code'] ?? '';
|
||||
$player->status = Player::STATUS_ENABLE;
|
||||
$player->recommend_code = createCode();
|
||||
$player->save();
|
||||
|
||||
addPlayerExtend($player, [
|
||||
'email' => $data['email'] ?? ''
|
||||
]);
|
||||
|
||||
addRegisterRecord($player->id, PlayerRegisterRecord::TYPE_CLIENT, $player->department_id);
|
||||
DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
Log::error(trans('register_player_failed', [], 'message') . $e->getMessage());
|
||||
throw new Exception();
|
||||
}
|
||||
unset($player->password);
|
||||
return $player;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 增加玩家扩展信息
|
||||
* @param Player $player
|
||||
* @param array $extend
|
||||
* @return void
|
||||
*/
|
||||
function addPlayerExtend(Player $player, array $extend = [])
|
||||
{
|
||||
$registerPresent = SystemSetting::where('feature', 'register_present')->where('status', 1)->value('num') ?? 0;
|
||||
$playerPlatformCash = new PlayerPlatformCash();
|
||||
$playerPlatformCash->player_id = $player->id;
|
||||
$playerPlatformCash->platform_id = PlayerPlatformCash::PLATFORM_SELF;
|
||||
$playerPlatformCash->money = $registerPresent;
|
||||
$playerPlatformCash->save();
|
||||
|
||||
$playerExtend = new PlayerExtend();
|
||||
$playerExtend->player_id = $player->id;
|
||||
$playerExtend->email = $extend['email'];
|
||||
$playerExtend->save();
|
||||
|
||||
if (isset($registerPresent) && $registerPresent > 0) {
|
||||
//添加玩家钱包日志
|
||||
$playerMoneyEditLog = new PlayerMoneyEditLog;
|
||||
$playerMoneyEditLog->player_id = $player->id;
|
||||
$playerMoneyEditLog->department_id = $player->department_id;
|
||||
$playerMoneyEditLog->type = PlayerMoneyEditLog::TYPE_INCREASE;
|
||||
$playerMoneyEditLog->action = PlayerMoneyEditLog::OTHER;
|
||||
$playerMoneyEditLog->tradeno = date('YmdHis') . rand(10000, 99999);
|
||||
$playerMoneyEditLog->currency = $player->currency;
|
||||
$playerMoneyEditLog->money = $registerPresent;
|
||||
$playerMoneyEditLog->inmoney = $registerPresent;
|
||||
$playerMoneyEditLog->remark = '';
|
||||
$playerMoneyEditLog->user_id = Admin::id() ?? 0;
|
||||
$playerMoneyEditLog->user_name = !empty(Admin::user()) ? Admin::user()->toArray()['username'] : trans('system_automatic', [], 'message');
|
||||
$playerMoneyEditLog->save();
|
||||
//寫入金流明細
|
||||
$playerDeliveryRecord = new PlayerDeliveryRecord;
|
||||
$playerDeliveryRecord->player_id = $player->id;
|
||||
$playerDeliveryRecord->department_id = $player->department_id;
|
||||
$playerDeliveryRecord->target = $playerMoneyEditLog->getTable();
|
||||
$playerDeliveryRecord->target_id = $playerMoneyEditLog->id;
|
||||
$playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_REGISTER_PRESENT;
|
||||
$playerDeliveryRecord->source = 'register_present';
|
||||
$playerDeliveryRecord->amount = $playerMoneyEditLog->money;
|
||||
$playerDeliveryRecord->amount_before = 0;
|
||||
$playerDeliveryRecord->amount_after = $registerPresent;
|
||||
$playerDeliveryRecord->tradeno = $playerMoneyEditLog->tradeno ?? '';
|
||||
$playerDeliveryRecord->remark = $playerMoneyEditLog->remark ?? '';
|
||||
$playerDeliveryRecord->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Player
|
||||
* @throws GameException
|
||||
* @throws PlayerCheckException
|
||||
* @throws \Exception
|
||||
*/
|
||||
function checkPlayer(): Player
|
||||
{
|
||||
$departmentId = request()->department_id;
|
||||
$id = JwtToken::getCurrentId();
|
||||
/** @var Player $player */
|
||||
$player = Player::where('id', $id)->where('department_id', $departmentId)->first();
|
||||
if (empty($player)) {
|
||||
throw new PlayerCheckException(trans('player_not_fount', [], 'message'), 100);
|
||||
}
|
||||
|
||||
if ($player->status == Player::STATUS_STOP) {
|
||||
throw new PlayerCheckException(trans('player_stop', [], 'message'), 100);
|
||||
}
|
||||
|
||||
return $player;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 组装请求
|
||||
* @param string $url
|
||||
* @param array $params
|
||||
* @return array|mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
function doCurl(string $url, array $params = [])
|
||||
{
|
||||
$response = Http::timeout(7)
|
||||
->contentType('application/json')
|
||||
->accept('application/json')
|
||||
->asJson()
|
||||
->post($url, $params);
|
||||
if (!$response->ok()) {
|
||||
throw new Exception(trans('system_busy', [], 'message'));
|
||||
}
|
||||
$data = $response->json();
|
||||
if (empty($data)) {
|
||||
throw new Exception(trans('system_busy', [], 'message'));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装请求
|
||||
* @param $id
|
||||
* @param array $range
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
function getGamePlayerNum($id, array $range = [])
|
||||
{
|
||||
$cacheKey = 'game_player_num_' . $id;
|
||||
$playerNum = Cache::get($cacheKey);
|
||||
if ($playerNum === null) {
|
||||
$playerNum = rand($range[0] ?? 0, $range[1] ?? 0);
|
||||
Cache::set($cacheKey, $playerNum, 30 * 60);
|
||||
}
|
||||
|
||||
return $playerNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分润结算
|
||||
* @return void
|
||||
*/
|
||||
function commissionSettlement()
|
||||
{
|
||||
$date = Carbon::now()->subDay()->format('Y-m-d');
|
||||
$data = PlayGameRecord::query()
|
||||
->selectRaw('SUM(bet) - SUM(win) AS damage_amount, player_id, parent_player_id, department_id,sum(deficit) as deficit')
|
||||
->whereDate('created_at', $date)
|
||||
->where('status', 0)
|
||||
->groupBy('player_id', 'parent_player_id', 'department_id')
|
||||
->get();
|
||||
Log::info('分润结算开始------------------');
|
||||
if ($data->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 提取父玩家ID
|
||||
$playerIds = $data->pluck('parent_player_id')->unique()->toArray();
|
||||
// 获取玩家数据
|
||||
$players = Player::query()
|
||||
->with(['player_extend'])
|
||||
->whereIn('id', $playerIds)
|
||||
->get()
|
||||
->keyBy('id');
|
||||
// 获取系统设置
|
||||
$systemSettingMap = SystemSetting::query()
|
||||
->where('status', 1)
|
||||
->where('feature', 'commission_setting')
|
||||
->get()
|
||||
->keyBy('department_id');
|
||||
$commissionRecord = [];
|
||||
$unsettledCommissionAmount = [];
|
||||
foreach ($data->toArray() as $item) {
|
||||
/** @var SystemSetting $systemSettingData */
|
||||
//边玩边赚,只返给上级
|
||||
$systemSettingData = $systemSettingMap->get($item['department_id']);
|
||||
if(empty($systemSettingData)){
|
||||
continue;
|
||||
}
|
||||
$systemSetting = json_decode($systemSettingData->content, true);
|
||||
if ($item['deficit'] == 0) {
|
||||
continue;
|
||||
}
|
||||
if ($systemSetting && !empty($systemSetting['commission_damage']) && is_numeric($systemSetting['commission_damage']) && $systemSetting['commission_damage'] > 0) {
|
||||
$commissionAmount = max(bcmul($item['damage_amount'], bcdiv($systemSetting['commission_damage'], 100, 2), 2), 0);
|
||||
/** @var Player $player */
|
||||
$player = $players->get($item['parent_player_id']);
|
||||
if ($player) {
|
||||
$commissionRecord[] = [
|
||||
'player_id' => $item['player_id'],
|
||||
'department_id' => $item['department_id'],
|
||||
'parent_player_id' => $item['parent_player_id'],
|
||||
'recharge_amount' => 0,
|
||||
'chip_amount' => 0,
|
||||
'total_amount' => $player->player_extend->commission_amount,
|
||||
'damage_amount' => $item['damage_amount'],
|
||||
'amount' => $commissionAmount,
|
||||
'ratio' => $systemSetting['commission_damage'],
|
||||
'date' => $date,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
|
||||
if (!isset($unsettledCommissionAmount[$item['parent_player_id']])) {
|
||||
$unsettledCommissionAmount[$item['parent_player_id']] = $commissionAmount;
|
||||
} else {
|
||||
$unsettledCommissionAmount[$item['parent_player_id']] = bcadd($unsettledCommissionAmount[$item['parent_player_id']], $commissionAmount, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 前天发生账变的玩家
|
||||
$playerList = Player::with(['wallet'])
|
||||
->whereHas('wallet', function ($query) use ($date) {
|
||||
$query->where('updated_at', '>=', $date . ' 00:00:00');
|
||||
})
|
||||
->get();
|
||||
// 账变记录
|
||||
$playerDeliveryRecords = collect(PlayerDeliveryRecord::whereDate('updated_at', '2024-11-26')
|
||||
->groupBy('player_id')
|
||||
->whereIn('type', [
|
||||
PlayerDeliveryRecord::TYPE_MODIFIED_AMOUNT_ADD,
|
||||
PlayerDeliveryRecord::TYPE_MODIFIED_AMOUNT_DEDUCT,
|
||||
PlayerDeliveryRecord::TYPE_REGISTER_PRESENT,
|
||||
PlayerDeliveryRecord::TYPE_GAME_OUT,
|
||||
PlayerDeliveryRecord::TYPE_GAME_IN,
|
||||
PlayerDeliveryRecord::TYPE_RECHARGE,
|
||||
])
|
||||
->get([
|
||||
DB::raw("SUM(if(`type`=" . PlayerDeliveryRecord::TYPE_MODIFIED_AMOUNT_ADD . ",`amount`,0)) as admin_add_amount"),
|
||||
DB::raw("SUM(if(`type`=" . PlayerDeliveryRecord::TYPE_MODIFIED_AMOUNT_DEDUCT . ",`amount`,0)) as admin_deduct_amount"),
|
||||
DB::raw("SUM(if(`type`=" . PlayerDeliveryRecord::TYPE_REGISTER_PRESENT . ",`amount`,0)) as present_amount"),
|
||||
DB::raw("SUM(if(`type`=" . PlayerDeliveryRecord::TYPE_RECHARGE . ",`amount`,0)) as recharge_amount"),
|
||||
'player_id'
|
||||
])->toArray())
|
||||
->keyBy('player_id')
|
||||
->toArray();
|
||||
// 提现记录
|
||||
$playerWithdrawRecord = collect(PlayerWithdrawRecord::whereDate('updated_at', $date)
|
||||
->where('status', PlayerWithdrawRecord::STATUS_SUCCESS)
|
||||
->groupBy('player_id')
|
||||
->get([
|
||||
DB::raw('SUM(`money`) as withdraw_amount'),
|
||||
'player_id'
|
||||
]))
|
||||
->keyBy('player_id')
|
||||
->toArray();
|
||||
/** @var Player $player */
|
||||
foreach ($playerList as $player) {
|
||||
$change = [
|
||||
'recharge_amount' => $playerDeliveryRecords[$player->id]['recharge_amount'] ?? 0,
|
||||
'admin_add_amount' => $playerDeliveryRecords[$player->id]['admin_add_amount'] ?? 0,
|
||||
'admin_deduct_amount' => $playerDeliveryRecords[$player->id]['admin_deduct_amount'] ?? 0,
|
||||
'present_amount' => $playerDeliveryRecords[$player->id]['present_amount'] ?? 0,
|
||||
'bonus_amount' => $playerDeliveryRecords[$player->id]['bonus_amount'] ?? 0,
|
||||
'withdraw_amount' => $playerWithdrawRecord[$player->id]['withdraw_amount'] ?? 0,
|
||||
'date' => $date,
|
||||
];
|
||||
$change_list[$player->id] = $change;
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$playerUpdates = [];
|
||||
$playerDeliveryRecord = [];
|
||||
$promoterProfitRecords = []; // 保存所有的PromoterProfitRecord
|
||||
foreach ($unsettledCommissionAmount as $key => $amount) {
|
||||
/** @var Player $player */
|
||||
$player = $players->get($key);
|
||||
if ($player) {
|
||||
$commissionAmount = bcadd($amount, $player->player_extend->unsettled_commission_amount, 2);
|
||||
if ($commissionAmount > 0) {
|
||||
$player->player_extend->commission_amount = bcadd($player->player_extend->commission_amount, $commissionAmount, 2);
|
||||
$player->player_extend->unsettled_commission_amount = 0;
|
||||
$beforeAmount = $player->wallet->money;
|
||||
$player->wallet->money = bcadd($player->wallet->money, $commissionAmount, 2);
|
||||
$playerDeliveryRecord[] = [
|
||||
'player_id' => $player->id,
|
||||
'department_id' => $player->department_id,
|
||||
'target' => 'commission_record',
|
||||
'target_id' => 0,
|
||||
'type' => PlayerDeliveryRecord::TYPE_COMMISSION,
|
||||
'source' => 'commission',
|
||||
'amount' => $commissionAmount,
|
||||
'amount_before' => $beforeAmount,
|
||||
'amount_after' => $player->wallet->money,
|
||||
'tradeno' => '',
|
||||
'remark' => '',
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
} else {
|
||||
$player->player_extend->unsettled_commission_amount = $commissionAmount;
|
||||
}
|
||||
$playerUpdates[] = $player;
|
||||
}
|
||||
}
|
||||
if (!empty($playerUpdates)) {
|
||||
/** @var Player $player */
|
||||
foreach ($playerUpdates as $player) {
|
||||
$player->push();
|
||||
}
|
||||
}
|
||||
if (!empty($commissionRecord)) {
|
||||
CommissionRecord::query()->insert($commissionRecord);
|
||||
}
|
||||
if (!empty($playerDeliveryRecord)) {
|
||||
PlayerDeliveryRecord::query()->insert($playerDeliveryRecord);
|
||||
}
|
||||
PlayGameRecord::query()
|
||||
->whereDate('created_at', $date)
|
||||
->update([
|
||||
'status' => 1,
|
||||
'action_at' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
foreach ($data as $value) {
|
||||
$up_ids = [];
|
||||
//玩家为代理
|
||||
if(isset($value->player->player_promoter->path)){
|
||||
$path = $value->player->player_promoter->path;
|
||||
$up_ids = explode(',',$path);
|
||||
//代理不给自己返利
|
||||
array_pop($up_ids);
|
||||
}else{
|
||||
//查询玩家无限上级
|
||||
if(isset($value->player->recommend_id)){
|
||||
$path = PlayerPromoter::where('player_id',$value->player->recommend_id)->value('path');
|
||||
$up_ids = explode(',',$path);
|
||||
}else{
|
||||
//未绑定上级的玩家不参与返利计算
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$up_list = PlayerPromoter::whereIn('player_id',$up_ids)->orderBy('id','asc')->get();
|
||||
foreach($up_list as $k => &$up_val){
|
||||
$player_profit_amount = 0;//直属玩家提供的分润
|
||||
$diff_ratio = 0;//每级代理获得的分润比例
|
||||
if(isset($up_list[$k+1])){
|
||||
//上级代理获得的返利比例
|
||||
$diff_ratio = bcsub($up_val->ratio, $up_list[$k+1]->ratio, 2);
|
||||
}else{
|
||||
$diff_ratio = $up_val->ratio;
|
||||
$player_profit_amount = bcdiv(bcmul($diff_ratio, $value->deficit, 2),100,2);
|
||||
}
|
||||
$rebate = bcdiv(bcmul($diff_ratio, $value->deficit, 2),100,2);
|
||||
//更新推广员信息表
|
||||
$up_val->player_profit_amount = bcadd($up_val->player_profit_amount,$player_profit_amount,2);//直属玩家提供的分润
|
||||
$up_val->profit_amount = bcadd($up_val->profit_amount,$rebate,2);//总分润
|
||||
$team_withdraw_total_amount = isset($change_list[$up_val->player_id]['withdraw_amount']) ? $change_list[$up_val->player_id]['withdraw_amount'] : 0;
|
||||
$up_val->team_withdraw_total_amount = bcadd($up_val->team_withdraw_total_amount, $team_withdraw_total_amount, 2);
|
||||
$team_recharge_total_amount = isset($change_list[$up_val->player_id]['recharge_amount']) ? $change_list[$up_val->player_id]['recharge_amount'] : 0;
|
||||
$up_val->team_recharge_total_amount = bcadd($up_val->team_recharge_total_amount, $team_recharge_total_amount, 2);
|
||||
$up_val->total_profit_amount = bcadd($up_val->total_profit_amount, $rebate, 2);
|
||||
$up_val->team_total_profit_amount = bcadd($up_val->team_total_profit_amount, bcmul($value->deficit,bcdiv($up_val->ratio,100,2), 2),2);
|
||||
$up_val->team_profit_amount = bcadd($up_val->team_profit_amount, bcmul($value->deficit,bcdiv($up_val->ratio,100,2), 2), 2);
|
||||
|
||||
$up_val->save();
|
||||
$promoter_profit_record = [];
|
||||
$promoter_profit_record['player_id'] = $value->player_id;//玩家id
|
||||
$promoter_profit_record['department_id'] = $up_val->department_id;
|
||||
$promoter_profit_record['promoter_player_id'] = $up_val->player_id;//获得分润的id
|
||||
$promoter_profit_record['source_player_id'] = $value->player->recommend_id;//玩家上级id
|
||||
$promoter_profit_record['withdraw_amount'] = isset($change_list[$up_val->player_id]['withdraw_amount']) ? $change_list[$up_val->player_id]['withdraw_amount'] : 0;
|
||||
$promoter_profit_record['recharge_amount'] = isset($change_list[$up_val->player_id]['recharge_amount']) ? $change_list[$up_val->player_id]['recharge_amount'] : 0;
|
||||
$promoter_profit_record['bonus_amount'] = isset($change_list[$up_val->player_id]['bonus_amount']) ? $change_list[$up_val->player_id]['bonus_amount'] : 0;
|
||||
$promoter_profit_record['admin_deduct_amount'] = isset($change_list[$up_val->player_id]['admin_deduct_amount']) ? $change_list[$up_val->player_id]['admin_deduct_amount'] : 0;
|
||||
$promoter_profit_record['admin_add_amount'] = isset($change_list[$up_val->player_id]['admin_add_amount']) ? $change_list[$up_val->player_id]['admin_add_amount'] : 0;
|
||||
$promoter_profit_record['present_amount'] = isset($change_list[$up_val->player_id]['present_amount']) ? $change_list[$up_val->player_id]['present_amount'] : 0;
|
||||
$promoter_profit_record['ratio'] = $up_val->ratio;
|
||||
$promoter_profit_record['actual_ratio'] = $diff_ratio;
|
||||
$promoter_profit_record['date'] = $date;
|
||||
$promoter_profit_record['model'] = PromoterProfitRecord::MODEL_TASK;
|
||||
$promoter_profit_record['profit_amount'] = $rebate;
|
||||
$promoter_profit_record['player_profit_amount'] = $player_profit_amount;
|
||||
$created_at = Carbon::now();
|
||||
$promoter_profit_record['created_at'] = $created_at;
|
||||
$promoter_profit_record['updated_at'] = $created_at;
|
||||
$promoterProfitRecords[] = $promoter_profit_record;
|
||||
|
||||
}
|
||||
unset($up_val);
|
||||
}
|
||||
PromoterProfitRecord::insert($promoterProfitRecords);
|
||||
DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
Log::error('CommissionSettlement', [$e->getMessage(), $e->getTraceAsString()]);
|
||||
}
|
||||
Log::info('分润结算结束------------------');
|
||||
}
|
||||
|
||||
/**
|
||||
* 客损返水结算
|
||||
* @return void
|
||||
*/
|
||||
function damageRebate()
|
||||
{
|
||||
$date = Carbon::now()->subDay()->format('Y-m-d');
|
||||
$data = CommissionRecord::query()->where('date', $date)->get();
|
||||
Log::info('客损返水结算------------------');
|
||||
if ($data->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 提取玩家ID
|
||||
$playerIds = $data->pluck('player_id')->unique()->toArray();
|
||||
// 获取玩家数据
|
||||
$players = Player::query()
|
||||
->with(['wallet', 'player_level'])
|
||||
->whereIn('id', $playerIds)
|
||||
->get()
|
||||
->keyBy('id');
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
/** @var CommissionRecord $item */
|
||||
foreach ($data as $item) {
|
||||
/** @var Player $player */
|
||||
$player = $players->get($item->player_id);
|
||||
$playerLevel = $player->player_level;
|
||||
if (!empty($playerLevel) && $playerLevel->damage_rebate_ratio > 0 && $item->damage_amount > 0) {
|
||||
$damageAmount = bcmul($item->damage_amount, $playerLevel->damage_rebate_ratio, 2);
|
||||
$beforeGameAmount = $player->wallet->money;
|
||||
if ($damageAmount > 0) {
|
||||
// 更新钱包
|
||||
$player->wallet->money = bcadd($player->wallet->money, $damageAmount, 2);
|
||||
if ($playerLevel->chip_multiple) {
|
||||
$chipAmount = bcmul($damageAmount, $playerLevel->chip_multiple);
|
||||
if ($chipAmount) {
|
||||
$beforeMustChipAmount = $player->must_chip_amount;
|
||||
$player->must_chip_amount = bcadd($player->must_chip_amount, $chipAmount, 2);
|
||||
// 记录打码量明细
|
||||
$playerChipRecord = new PlayerChipRecord();
|
||||
$playerChipRecord->player_id = $player->id;
|
||||
$playerChipRecord->department_id = $player->department_id;
|
||||
$playerChipRecord->type = PlayerChipRecord::TYPE_INC;
|
||||
$playerChipRecord->record_type = PlayerChipRecord::RECORD_TYPE_BET_REBATE;
|
||||
$playerChipRecord->amount = $chipAmount;
|
||||
|
||||
$playerChipRecord->chip_amount = 0;
|
||||
$playerChipRecord->before_chip_amount = $player->chip_amount;
|
||||
$playerChipRecord->after_chip_amount = $player->chip_amount;
|
||||
|
||||
$playerChipRecord->must_chip_amount = $chipAmount;
|
||||
$playerChipRecord->before_must_chip_amount = $beforeMustChipAmount;
|
||||
$playerChipRecord->after_must_chip_amount = $player->must_chip_amount;
|
||||
|
||||
$playerChipRecord->source_type = CommissionRecord::class;
|
||||
$playerChipRecord->source_id = $item->id;
|
||||
$playerChipRecord->save();
|
||||
}
|
||||
}
|
||||
// 根据打码量返水玩家
|
||||
$playerDeliveryRecord = new PlayerDeliveryRecord;
|
||||
$playerDeliveryRecord->player_id = $player->id;
|
||||
$playerDeliveryRecord->department_id = $player->department_id;
|
||||
$playerDeliveryRecord->target = $item->getTable();
|
||||
$playerDeliveryRecord->target_id = $item->id;
|
||||
$playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_DAMAGE_REBATE;
|
||||
$playerDeliveryRecord->source = 'damage_rebate';
|
||||
$playerDeliveryRecord->amount = $damageAmount;
|
||||
$playerDeliveryRecord->amount_before = $beforeGameAmount;
|
||||
$playerDeliveryRecord->amount_after = $player->wallet->money;
|
||||
$playerDeliveryRecord->tradeno = '';
|
||||
$playerDeliveryRecord->remark = '';
|
||||
$playerDeliveryRecord->save();
|
||||
}
|
||||
}
|
||||
$player->push();
|
||||
}
|
||||
DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
Log::error('damageRebate', [$e->getMessage(), $e->getTraceAsString()]);
|
||||
}
|
||||
Log::info('客损返水结算结束------------------');
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家等级选项
|
||||
* @return array
|
||||
*/
|
||||
function playerLevelOptions(): array
|
||||
{
|
||||
$options = [];
|
||||
for ($i = 0; $i <= 13; $i++) {
|
||||
if ($i == 0) {
|
||||
$options[$i] = admin_trans('player.no_level');
|
||||
} else {
|
||||
$options[$i] = admin_trans('player.level.' . $i);
|
||||
}
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动生成密码
|
||||
* @return string
|
||||
*/
|
||||
function generateRandomPassword(): string
|
||||
{
|
||||
$uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
$lowercase = 'abcdefghijklmnopqrstuvwxyz';
|
||||
$numbers = '0123456789';
|
||||
|
||||
$password = '';
|
||||
|
||||
$password .= $uppercase[rand(0, strlen($uppercase) - 1)];
|
||||
|
||||
$password .= $lowercase[rand(0, strlen($lowercase) - 1)];
|
||||
|
||||
$password .= $numbers[rand(0, strlen($numbers) - 1)];
|
||||
|
||||
$length = rand(7, 12); // Random length between 7 and 12
|
||||
$remainingLength = $length - 3;
|
||||
|
||||
$allChars = $uppercase . $lowercase . $numbers;
|
||||
|
||||
for ($i = 0; $i < $remainingLength; $i++) {
|
||||
$password .= $allChars[rand(0, strlen($allChars) - 1)];
|
||||
}
|
||||
|
||||
return str_shuffle($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成用户名
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
function generateUniqueUsername(int $length = 10): string
|
||||
{
|
||||
$characters = 'abcdefghijklmnopqrstuvwxyz0123456789'; // 可选的字符集合
|
||||
$uniqueUsername = ''; // 初始化唯一用户名
|
||||
|
||||
// 生成不重复的用户名
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$uniqueUsername .= $characters[rand(0, strlen($characters) - 1)];
|
||||
}
|
||||
|
||||
return $uniqueUsername;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 组装请求
|
||||
* @param string $url
|
||||
* @param array $params
|
||||
* @return array|mixed|null
|
||||
* @throws Exception
|
||||
*/
|
||||
function dogGetCurl(string $url, array $params = [])
|
||||
{
|
||||
$response = Http::timeout(7)
|
||||
->contentType('application/json')
|
||||
->accept('application/json')
|
||||
->asJson()
|
||||
->get($url, $params);
|
||||
if (!$response->ok()) {
|
||||
throw new Exception(trans('system_busy', [], 'message'));
|
||||
}
|
||||
$data = $response->json();
|
||||
if (empty($data)) {
|
||||
throw new Exception(trans('system_busy', [], 'message'));
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置推广员
|
||||
* @param $id
|
||||
* @param $ratio
|
||||
* @param $name
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
function setPromoter($id, $ratio, $name,$recommend_id): bool
|
||||
{
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
/** @var Player $player */
|
||||
$player = Player::find($id);
|
||||
if (empty($player)) {
|
||||
throw new Exception(trans('player_not_found', [], 'message'));
|
||||
}
|
||||
if (!empty($player->player_promoter)) {
|
||||
throw new Exception(trans('player_is_promoter', [], 'message'));
|
||||
}
|
||||
if ($player->status == Player::STATUS_STOP) {
|
||||
throw new Exception(trans('player_stop', [], 'message'));
|
||||
}
|
||||
if($recommend_id != $player->recommend_id){
|
||||
throw new Exception(trans('not_sub_recommend_player', [], 'message'));
|
||||
}
|
||||
$promoter = new PlayerPromoter();
|
||||
|
||||
/** @var PlayerPromoter $parentPromoter */
|
||||
$parentPromoter = PlayerPromoter::where('player_id', $player->recommend_id)->first();
|
||||
$maxRatio = $parentPromoter->ratio ?? 100;
|
||||
if ($ratio > $maxRatio) {
|
||||
throw new Exception(trans('ratio_max_error', ['{max_ratio}' => $maxRatio], 'message'));
|
||||
}
|
||||
|
||||
$orgPromoter = $player->is_promoter;
|
||||
$path = [];
|
||||
if (isset($parentPromoter->path) && !empty($parentPromoter->path)) {
|
||||
$path = explode(',', $parentPromoter->path);
|
||||
}
|
||||
$path[] = $player->id;
|
||||
$promoter->ratio = $ratio;
|
||||
$promoter->player_id = $player->id;
|
||||
$promoter->recommend_id = $parentPromoter->player_id ?? 0;
|
||||
$promoter->department_id = $player->department_id;
|
||||
$promoter->name = !empty($name) ? $name : $player->name;
|
||||
$promoter->path = implode(',', $path);
|
||||
$promoter->save();
|
||||
// 更新玩家信息
|
||||
$player->is_promoter = 1;
|
||||
$player->recommend_code = createCode();
|
||||
$player->save();
|
||||
$parentPromoter && $orgPromoter == 0 && $parentPromoter->increment('team_num');
|
||||
DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证手机号格式
|
||||
* @param $phoneNumber
|
||||
* @return true
|
||||
*/
|
||||
function validateMalaysianPhoneNumber($phoneNumber): bool
|
||||
{
|
||||
$pattern = '/^(01\d{8,9}|(\+60|60|0060)(0?1)\d{8,9})$/';
|
||||
return preg_match($pattern, $phoneNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* post表单请求
|
||||
* @param string $url
|
||||
* @param array $params
|
||||
* @return array|mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
function doFormCurl(string $url, array $params = [])
|
||||
{
|
||||
$response = Http::timeout(10)->asForm()->post($url, $params);
|
||||
if (!$response->ok()) {
|
||||
throw new Exception(trans('system_busy', [], 'message'));
|
||||
}
|
||||
$data = $response->json();
|
||||
if (empty($data)) {
|
||||
throw new Exception(trans('system_busy', [], 'message'));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 结算
|
||||
* @param $id
|
||||
* @param int $userId
|
||||
* @param string $userName
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
function doSettlement($id, int $userId = 0, string $userName = '')
|
||||
{
|
||||
/** @var PlayerPromoter $playerPromoter */
|
||||
$playerPromoter = PlayerPromoter::where('player_id', $id)->first();
|
||||
if (empty($playerPromoter)) {
|
||||
throw new Exception(trans('profit_amount_not_found', [], 'message'));
|
||||
}
|
||||
if ($playerPromoter->status == 0) {
|
||||
throw new Exception(trans('player_promoter_has_disable', [], 'message'));
|
||||
}
|
||||
if (!isset($playerPromoter->profit_amount)) {
|
||||
throw new Exception(trans('profit_amount_not_found', [], 'message'));
|
||||
}
|
||||
$profitAmount = PromoterProfitRecord::where('status', PromoterProfitRecord::STATUS_UNCOMPLETED)
|
||||
->where('promoter_player_id', $id)
|
||||
->first([
|
||||
DB::raw('SUM(`withdraw_amount`) as total_withdraw_amount'),
|
||||
DB::raw('SUM(`recharge_amount`) as total_recharge_amount'),
|
||||
DB::raw('SUM(`bonus_amount`) as total_bonus_amount'),
|
||||
DB::raw('SUM(`admin_deduct_amount`) as total_admin_deduct_amount'),
|
||||
DB::raw('SUM(`admin_add_amount`) as total_admin_add_amount'),
|
||||
DB::raw('SUM(`present_amount`) as total_present_amount'),
|
||||
DB::raw('SUM(`profit_amount`) as total_profit_amount'),
|
||||
DB::raw('SUM(`player_profit_amount`) as total_player_profit_amount'),
|
||||
])
|
||||
->toArray();
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$promoterProfitSettlementRecord = new PromoterProfitSettlementRecord();
|
||||
$promoterProfitSettlementRecord->department_id = $playerPromoter->player->department_id;
|
||||
$promoterProfitSettlementRecord->promoter_player_id = $playerPromoter->player_id;
|
||||
$promoterProfitSettlementRecord->total_withdraw_amount = $profitAmount['total_withdraw_amount'] ?? 0;
|
||||
$promoterProfitSettlementRecord->total_recharge_amount = $profitAmount['total_recharge_amount'] ?? 0;
|
||||
$promoterProfitSettlementRecord->total_bonus_amount = $profitAmount['total_bonus_amount'] ?? 0;
|
||||
$promoterProfitSettlementRecord->total_admin_deduct_amount = $profitAmount['total_admin_deduct_amount'] ?? 0;
|
||||
$promoterProfitSettlementRecord->total_admin_add_amount = $profitAmount['total_admin_add_amount'] ?? 0;
|
||||
$promoterProfitSettlementRecord->total_present_amount = $profitAmount['total_present_amount'] ?? 0;
|
||||
$promoterProfitSettlementRecord->total_profit_amount = $profitAmount['total_profit_amount'] ?? 0;
|
||||
$promoterProfitSettlementRecord->total_player_profit_amount = $profitAmount['total_player_profit_amount'] ?? 0;
|
||||
$promoterProfitSettlementRecord->last_profit_amount = $playerPromoter->last_profit_amount;
|
||||
$promoterProfitSettlementRecord->adjust_amount = $playerPromoter->adjust_amount;
|
||||
$promoterProfitSettlementRecord->type = PromoterProfitSettlementRecord::TYPE_SETTLEMENT;
|
||||
$promoterProfitSettlementRecord->tradeno = createOrderNo();
|
||||
$promoterProfitSettlementRecord->user_id = $userId;
|
||||
$promoterProfitSettlementRecord->user_name = $userName;
|
||||
$settlement = $amount = bcadd($promoterProfitSettlementRecord->total_profit_amount,
|
||||
$promoterProfitSettlementRecord->adjust_amount, 2);
|
||||
if ($amount > 0) {
|
||||
if ($playerPromoter->settlement_amount < 0) {
|
||||
$diffAmount = bcadd($amount, $playerPromoter->settlement_amount, 2);
|
||||
$settlement = max($diffAmount, 0);
|
||||
}
|
||||
}
|
||||
$promoterProfitSettlementRecord->actual_amount = $settlement;
|
||||
$promoterProfitSettlementRecord->save();
|
||||
// 更新结算报表
|
||||
PromoterProfitRecord::where('status', PromoterProfitRecord::STATUS_UNCOMPLETED)
|
||||
->where('promoter_player_id', $id)
|
||||
->update([
|
||||
'status' => PromoterProfitRecord::STATUS_COMPLETED,
|
||||
'settlement_time' => date('Y-m-d H:i:s'),
|
||||
'settlement_tradeno' => $promoterProfitSettlementRecord->tradeno,
|
||||
'settlement_id' => $promoterProfitSettlementRecord->id,
|
||||
]);
|
||||
// 结算后这些数据清零
|
||||
$playerPromoter->profit_amount = 0;
|
||||
$playerPromoter->player_profit_amount = 0;
|
||||
$playerPromoter->team_recharge_total_amount = 0;
|
||||
$playerPromoter->team_withdraw_total_amount = 0;
|
||||
$playerPromoter->adjust_amount = 0;
|
||||
// 更新数据
|
||||
$playerPromoter->team_profit_amount = bcsub($playerPromoter->team_profit_amount,
|
||||
$promoterProfitSettlementRecord->total_profit_amount, 2);
|
||||
$playerPromoter->last_profit_amount = $settlement;
|
||||
$playerPromoter->settlement_amount = bcadd($playerPromoter->settlement_amount, $amount, 2);
|
||||
$playerPromoter->team_settlement_amount = bcadd($playerPromoter->team_settlement_amount,
|
||||
$promoterProfitSettlementRecord->total_profit_amount, 2);
|
||||
$playerPromoter->last_settlement_time = date('Y-m-d', strtotime('-1 day'));
|
||||
|
||||
if (!empty($playerPromoter->path)) {
|
||||
PlayerPromoter::where('player_id', '!=', $playerPromoter->player_id)
|
||||
->whereIn('player_id', explode(',', $playerPromoter->path))
|
||||
->update([
|
||||
'team_profit_amount' => DB::raw("team_profit_amount - {$promoterProfitSettlementRecord->total_profit_amount}"),
|
||||
'team_settlement_amount' => DB::raw("team_settlement_amount + $promoterProfitSettlementRecord->total_profit_amount"),
|
||||
]);
|
||||
}
|
||||
if ($settlement > 0) {
|
||||
// 增加钱包余额
|
||||
$amountBefore = $playerPromoter->player->wallet->money;
|
||||
$amountAfter = bcadd($amountBefore, $settlement, 2);
|
||||
$playerDeliveryRecord = new PlayerDeliveryRecord;
|
||||
$playerDeliveryRecord->player_id = $playerPromoter->player_id;
|
||||
$playerDeliveryRecord->department_id = $playerPromoter->department_id;
|
||||
$playerDeliveryRecord->target = $promoterProfitSettlementRecord->getTable();
|
||||
$playerDeliveryRecord->target_id = $promoterProfitSettlementRecord->id;
|
||||
$playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_PROFIT;
|
||||
$playerDeliveryRecord->source = 'profit';
|
||||
$playerDeliveryRecord->amount = $settlement;
|
||||
$playerDeliveryRecord->amount_before = $amountBefore;
|
||||
$playerDeliveryRecord->amount_after = $amountAfter;
|
||||
$playerDeliveryRecord->tradeno = $promoterProfitSettlementRecord->tradeno ?? '';
|
||||
$playerDeliveryRecord->remark = '';
|
||||
$playerDeliveryRecord->save();
|
||||
$playerPromoter->player->wallet->money = $amountAfter;
|
||||
}
|
||||
$playerPromoter->push();
|
||||
DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollback();
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
25
app/middleware/AccessControl.php
Normal file
25
app/middleware/AccessControl.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace app\middleware;
|
||||
|
||||
use Webman\Http\Request;
|
||||
use Webman\Http\Response;
|
||||
use Webman\MiddlewareInterface;
|
||||
|
||||
class AccessControl implements MiddlewareInterface
|
||||
{
|
||||
public function process(Request $request, callable $handler): Response
|
||||
{
|
||||
// 如果是opitons请求则返回一个空的响应,否则继续向洋葱芯穿越,并得到一个响应
|
||||
$response = $request->method() == 'OPTIONS' ? response('') : $handler($request);
|
||||
|
||||
// 给响应添加跨域相关的http头
|
||||
$response->withHeaders([
|
||||
'Access-Control-Allow-Credentials' => 'true',
|
||||
'Access-Control-Allow-Origin' => $request->header('origin', '*'),
|
||||
'Access-Control-Allow-Methods' => $request->header('access-control-request-method', '*'),
|
||||
'Access-Control-Allow-Headers' => $request->header('access-control-request-headers', '*'),
|
||||
]);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
57
app/middleware/AppVersionMiddleware.php
Normal file
57
app/middleware/AppVersionMiddleware.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use addons\webman\model\AppVersion;
|
||||
use Webman\Http\Request;
|
||||
use Webman\Http\Response;
|
||||
use Webman\MiddlewareInterface;
|
||||
|
||||
/**
|
||||
* 站点验证中间件
|
||||
* Class SiteAuthMiddleware
|
||||
* @package app\middleware
|
||||
*/
|
||||
class AppVersionMiddleware implements MiddlewareInterface
|
||||
{
|
||||
public function process(Request $request, callable $handler): Response
|
||||
{
|
||||
// 更新比较时,查询的是版本标识,大于传入的版本标识时,返回新版本的数据
|
||||
$versionKey = $request->header('app-version-key');
|
||||
$systemKey = $request->header('system-key');
|
||||
// 传入检测的系统
|
||||
if (empty($versionKey) || empty($systemKey)) {
|
||||
return jsonFailResponse('缺少版本号或版本标识');
|
||||
}
|
||||
$data = AppVersion::query()
|
||||
->where('app_version_key', '>', $versionKey)
|
||||
->where(['status' => 1])
|
||||
->where('status', 1)
|
||||
->where('force_update', 1)
|
||||
->where('system_key', $systemKey)
|
||||
->where('department_id', request()->department_id)
|
||||
->whereDate('regular_update', '<', date("Y-m-d H:i:s", time()))
|
||||
->select(['id', 'system_key', 'app_version', 'app_version_key', 'apk_url', 'hot_update_url', 'force_update', 'hot_update', 'regular_update', 'update_content', 'notes'])
|
||||
->orderBy('id', 'desc')
|
||||
->first();
|
||||
if (!empty($data)) {
|
||||
return jsonFailResponse('有新版本', [
|
||||
'data' => $data
|
||||
], 406);
|
||||
}
|
||||
|
||||
return $handler($request);
|
||||
}
|
||||
}
|
||||
35
app/middleware/ExternalAppMiddleware.php
Normal file
35
app/middleware/ExternalAppMiddleware.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use addons\webman\model\ExternalApp;
|
||||
use Tinywan\Jwt\JwtToken;
|
||||
use Webman\Http\Request;
|
||||
use Webman\Http\Response;
|
||||
use Webman\MiddlewareInterface;
|
||||
|
||||
class ExternalAppMiddleware implements MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function process(Request $request, callable $handler): Response
|
||||
{
|
||||
try {
|
||||
$id = JwtToken::getCurrentId();
|
||||
// 验证授权应用
|
||||
/** @var ExternalApp $externalApp */
|
||||
$externalApp = ExternalApp::where('id', base64_decode($id))->whereNull('deleted_at')->where('status', 1)->first();
|
||||
if (empty($externalApp)) {
|
||||
throw new \Exception('应用不存在');
|
||||
}
|
||||
// 验证服务器ip
|
||||
if (!empty($externalApp->white_ip) && !in_array(request()->getRealIp(), explode(',', $externalApp->white_ip))) {
|
||||
throw new \Exception('IP认证不通过');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return jsonFailResponse($e->getMessage(), [], 0);
|
||||
}
|
||||
return $handler($request);
|
||||
}
|
||||
}
|
||||
17
app/middleware/Lang.php
Normal file
17
app/middleware/Lang.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace app\middleware;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Webman\Http\Request;
|
||||
use Webman\Http\Response;
|
||||
use Webman\MiddlewareInterface;
|
||||
|
||||
class Lang implements MiddlewareInterface
|
||||
{
|
||||
public function process(Request $request, callable $handler): Response
|
||||
{
|
||||
$lang = $request->header('Lang') ?? 'zh_CN';
|
||||
locale(session('lang', Str::replace('-', '_', $lang)));
|
||||
return $handler($request);
|
||||
}
|
||||
}
|
||||
61
app/middleware/SiteAuthMiddleware.php
Normal file
61
app/middleware/SiteAuthMiddleware.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use addons\webman\model\Channel;
|
||||
use support\Cache;
|
||||
use Webman\Http\Request;
|
||||
use Webman\Http\Response;
|
||||
use Webman\MiddlewareInterface;
|
||||
|
||||
/**
|
||||
* 站点验证中间件
|
||||
* Class SiteAuthMiddleware
|
||||
* @package app\middleware
|
||||
*/
|
||||
class SiteAuthMiddleware implements MiddlewareInterface
|
||||
{
|
||||
public function process(Request $request, callable $handler): Response
|
||||
{
|
||||
// 站点标识
|
||||
$siteId = $request->header('Site-Id');
|
||||
// 排除接口
|
||||
if ($request->path() == '/api/v1/talk-pay-notify') {
|
||||
return $handler($request);
|
||||
}
|
||||
if (empty($siteId)) {
|
||||
return response('fail', 400);
|
||||
}
|
||||
$cacheKey = "channel_" . $siteId;
|
||||
$channel = Cache::get($cacheKey);
|
||||
if (empty($channel)) {
|
||||
/** @var Channel $channel */
|
||||
$channel = Channel::where('site_id', $siteId)->whereNull('deleted_at')->first();
|
||||
if (!empty($channel)) {
|
||||
$cacheKey = "channel_" . $channel->site_id;
|
||||
Cache::set($cacheKey, $channel->toArray());
|
||||
} else {
|
||||
return response('fail', 400);
|
||||
}
|
||||
}
|
||||
if ($channel['status'] == 0 || !empty($channel['deleted_at'])) {
|
||||
return response('fail', 400);
|
||||
}
|
||||
$request->department_id = $channel['department_id'];
|
||||
$request->site_id = $siteId;
|
||||
|
||||
return $handler($request);
|
||||
}
|
||||
}
|
||||
42
app/middleware/StaticFile.php
Normal file
42
app/middleware/StaticFile.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use Webman\Http\Request;
|
||||
use Webman\Http\Response;
|
||||
use Webman\MiddlewareInterface;
|
||||
|
||||
/**
|
||||
* Class StaticFile
|
||||
* @package app\middleware
|
||||
*/
|
||||
class StaticFile implements MiddlewareInterface
|
||||
{
|
||||
public function process(Request $request, callable $next): Response
|
||||
{
|
||||
// Access to files beginning with. Is prohibited
|
||||
if (strpos($request->path(), '/.') !== false) {
|
||||
return response('<h1>403 forbidden</h1>', 403);
|
||||
}
|
||||
/** @var Response $response */
|
||||
$response = $next($request);
|
||||
// Add cross domain HTTP header
|
||||
/*$response->withHeaders([
|
||||
'Access-Control-Allow-Origin' => '*',
|
||||
'Access-Control-Allow-Credentials' => 'true',
|
||||
]);*/
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
35
app/queue/redis/CancelRecharge.php
Normal file
35
app/queue/redis/CancelRecharge.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace app\queue\redis;
|
||||
|
||||
use addons\webman\model\PlayerRechargeRecord;
|
||||
use ExAdmin\ui\traits\queueProgress;
|
||||
use think\Exception;
|
||||
use Webman\RedisQueue\Consumer;
|
||||
|
||||
class CancelRecharge implements Consumer
|
||||
{
|
||||
use queueProgress;
|
||||
|
||||
public $queue = 'cancel_recharge';
|
||||
|
||||
public $connection = 'default';
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @throws Exception
|
||||
*/
|
||||
public function consume($data)
|
||||
{
|
||||
/** @var PlayerRechargeRecord $playerRechargeRecord */
|
||||
$playerRechargeRecord = PlayerRechargeRecord::where('type', PlayerRechargeRecord::TYPE_REGULAR)
|
||||
->where('status', PlayerRechargeRecord::STATUS_WAIT)
|
||||
->where('id', $data['id'])
|
||||
->first();
|
||||
if (!empty($playerRechargeRecord)) {
|
||||
$playerRechargeRecord->status = PlayerRechargeRecord::STATUS_RECHARGED_SYSTEM_CANCEL;
|
||||
$playerRechargeRecord->cancel_time = date('Y-m-d H:i:s');
|
||||
$playerRechargeRecord->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
27
app/queue/redis/SendBroadcasts.php
Normal file
27
app/queue/redis/SendBroadcasts.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace app\queue\redis;
|
||||
|
||||
use support\Log;
|
||||
use Webman\Push\PushException;
|
||||
use Webman\RedisQueue\Consumer;
|
||||
|
||||
class SendBroadcasts implements Consumer
|
||||
{
|
||||
// 要消费的队列名
|
||||
public $queue = 'broadcast_tasks';
|
||||
|
||||
// 连接名,对应 plugin/webman/redis-queue/redis.php 里的连接`
|
||||
public $connection = 'default';
|
||||
|
||||
// 消费
|
||||
public function consume($data)
|
||||
{
|
||||
// 无需反序列化
|
||||
try {
|
||||
sendSocketMessage('broadcast', $data);
|
||||
} catch (PushException $e) {
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
16
app/service/BaseSmsServices.php
Normal file
16
app/service/BaseSmsServices.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace app\service;
|
||||
/**
|
||||
* 发送短信接口
|
||||
*/
|
||||
interface BaseSmsServices
|
||||
{
|
||||
/**
|
||||
* 发送短信
|
||||
* @param string $phone
|
||||
* @param int $type
|
||||
* @return mixed
|
||||
*/
|
||||
public function send(string $phone, int $type);
|
||||
}
|
||||
158
app/service/DrawService.php
Normal file
158
app/service/DrawService.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
// 抽奖核心服务
|
||||
namespace app\service;
|
||||
|
||||
use addons\webman\model\DrawRecord;
|
||||
use addons\webman\model\Game;
|
||||
use addons\webman\model\Prize;
|
||||
use Exception;
|
||||
use support\Db;
|
||||
use support\Log;
|
||||
|
||||
class DrawService
|
||||
{
|
||||
/**
|
||||
* 执行抽奖
|
||||
* @param $player
|
||||
* @param int $gameId
|
||||
* @param int $departmentId
|
||||
* @param string $ip 用户IP
|
||||
* @return array 抽奖结果
|
||||
*/
|
||||
public function execute( $player, int $gameId, int $departmentId, string $ip): array
|
||||
{
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
// 1. 查询有效奖品(加行锁防止并发问题)
|
||||
$prizes = Prize::query()->where('game_id', $gameId)
|
||||
->where('department_id', $departmentId)
|
||||
->where('status', 1)
|
||||
->where('total_remaining', '>', 0)
|
||||
->where('daily_remaining', '>', 0)
|
||||
->lockForUpdate()
|
||||
->get()
|
||||
->toArray();
|
||||
|
||||
if (empty($prizes)) {
|
||||
DB::rollBack();
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => '当前游戏不可用'
|
||||
];
|
||||
}
|
||||
|
||||
$game = Game::query()->select('id', 'game_type', 'consume')->where('id', $gameId)->first()->toArray();
|
||||
// 2. 计算中奖结果
|
||||
$result = $this->calculateWinning($player,$prizes, $game['consume']);
|
||||
$prizeId = $result['prize_id'];
|
||||
$prizeName = $result['prize_name'];
|
||||
$prizeType = $result['prize_type'];
|
||||
|
||||
$game['department_id'] = $departmentId;
|
||||
// 3. 记录抽奖信息
|
||||
$this->createRecord($player->id, $result, $game, $ip);
|
||||
|
||||
if ($result['prize_type'] == 3) {
|
||||
$message = '很遗憾,未中奖';
|
||||
} else {
|
||||
$message = '恭喜获得' . $prizeName;
|
||||
}
|
||||
DB::commit();
|
||||
return [
|
||||
'prize_id' => $prizeId,
|
||||
'prize_name' => $prizeName,
|
||||
'prize_type' => $prizeType,
|
||||
'consume' => $game['consume'],
|
||||
'message' => $message
|
||||
];
|
||||
} catch (Exception $e) {
|
||||
DB::rollBack();
|
||||
Log::error("抽奖失败:{$e->getMessage()}", [
|
||||
'user_id' => $player->id,
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => '抽奖过程异常,请稍后再试'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算中奖结果
|
||||
* @param array $prizes 有效奖品列表
|
||||
* @return array 中奖信息
|
||||
* @throws Exception
|
||||
*/
|
||||
private function calculateWinning($player, array $prizes, $consume): array
|
||||
{
|
||||
// 计算总概率权重
|
||||
$totalProb = array_sum(array_column($prizes, 'probability'));
|
||||
if ($totalProb <= 0) {
|
||||
return ['prize_id' => null, 'type' => Prize::PRIZE_TYPE_LOSE, 'prize_name' => '未中奖', 'prize_pic' => null];
|
||||
}
|
||||
$player->wallet->decrement('money', $consume);
|
||||
// 生成随机数(0到总权重之间)
|
||||
$random = mt_rand(1, $totalProb * 10000) / 10000; // 提高精度
|
||||
|
||||
$currentSum = 0;
|
||||
foreach ($prizes as $prize) {
|
||||
$currentSum += $prize['probability'];
|
||||
if ($random <= $currentSum) {
|
||||
// 检查并扣减库存
|
||||
$this->deductStock($prize['id']);
|
||||
return [
|
||||
'prize_id' => $prize['id'],
|
||||
'prize_type' => $prize['type'],
|
||||
'prize_name' => $prize['name'],
|
||||
'prize_pic' => $prize['pic']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return ['prize_id' => null, 'type' => Prize::PRIZE_TYPE_LOSE, 'prize_name' => '未中奖', 'prize_pic' => null];
|
||||
}
|
||||
|
||||
/**
|
||||
* 扣减库存
|
||||
* @param int $prizeId 奖品ID
|
||||
* @throws Exception
|
||||
*/
|
||||
private function deductStock(int $prizeId): void
|
||||
{
|
||||
$prize = Prize::query()->findOrFail($prizeId);
|
||||
|
||||
// 再次检查库存(防止并发超卖)
|
||||
if ($prize->total_remaining <= 0 || $prize->daily_remaining <= 0) {
|
||||
throw new \Exception("奖品库存不足");
|
||||
}
|
||||
|
||||
$prize->decrement('total_remaining');
|
||||
$prize->decrement('daily_remaining');
|
||||
$prize->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建抽奖记录
|
||||
* @param int $userId 用户ID
|
||||
* @param array|null $prize 奖品
|
||||
* @param string $ip IP地址
|
||||
*/
|
||||
private function createRecord(int $userId, ?array $prize, array $game, string $ip): void
|
||||
{
|
||||
DrawRecord::query()->create([
|
||||
'uid' => $userId,
|
||||
'prize_id' => $prize['prize_id'],
|
||||
'prize_type' => $prize['prize_type'],
|
||||
'prize_name' => $prize['prize_name'],
|
||||
'prize_pic' => $prize['prize_pic'],
|
||||
'game_id' => $game['id'],
|
||||
'consume' => $game['consume'],
|
||||
'game_type' => $game['game_type'],
|
||||
'department_id' => $game['department_id'],
|
||||
'draw_time' => date('Y-m-d H:i:s'),
|
||||
'ip' => $ip
|
||||
]);
|
||||
}
|
||||
}
|
||||
103
app/service/JpSmsServicesServices.php
Normal file
103
app/service/JpSmsServicesServices.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
// 日本手机号发送短信
|
||||
namespace app\service;
|
||||
|
||||
use addons\webman\model\PhoneSmsLog;
|
||||
use Exception;
|
||||
use Illuminate\Support\Str;
|
||||
use support\Cache;
|
||||
use WebmanTech\LaravelHttpClient\Facades\Http;
|
||||
|
||||
class JpSmsServicesServices implements BaseSmsServices
|
||||
{
|
||||
// 应用key
|
||||
private $appKey = '';
|
||||
// 应用代码
|
||||
private $appcode = '';
|
||||
// 应用秘钥
|
||||
private $appSecret = '';
|
||||
// domain
|
||||
private $domain = '';
|
||||
// 过期时间
|
||||
public $expireTime = 120;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->domain = config('jp-sms.domain');
|
||||
$this->appKey = config('jp-sms.app_key');
|
||||
$this->appcode = config('jp-sms.appcode');
|
||||
$this->appSecret = config('jp-sms.app_secret');
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行请求
|
||||
* @param string $api 接口
|
||||
* @param array $params 参数
|
||||
* @return mixed
|
||||
*/
|
||||
public function doCurl(string $api, array $params)
|
||||
{
|
||||
$result = Http::timeout(10)->get($this->domain . $api, $params);
|
||||
|
||||
return json_decode($result, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日本供应商短信发送
|
||||
* @param $phone
|
||||
* @param $type
|
||||
* @param int $playerId
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function send($phone, $type, int $playerId = 0): bool
|
||||
{
|
||||
$env = config('app.env');
|
||||
$api = config('jp-sms.batchSend');
|
||||
$code = ($env == 'pro' ? random_int(10000, 99999) : config('sms.default_code'));
|
||||
$key = setSmsKey($phone, $type);
|
||||
$uid = gen_uuid();
|
||||
$msg = Str::replaceFirst('{code}', $code, getContent($type, 'jp'));
|
||||
//驗證通過
|
||||
if ($env == 'pro') {
|
||||
$result = $this->doCurl($api, [
|
||||
'appKey' => $this->appKey,
|
||||
'appcode' => $this->appcode,
|
||||
'appSecret' => $this->appSecret,
|
||||
'uid' => $uid,
|
||||
'phone' => PhoneSmsLog::COUNTRY_CODE_JP . $phone,
|
||||
'msg' => $msg
|
||||
]);
|
||||
} else {
|
||||
$result = $env;
|
||||
}
|
||||
$phoneSmsLog = new PhoneSmsLog();
|
||||
$phoneSmsLog->player_id = $playerId;
|
||||
$phoneSmsLog->code = $code;
|
||||
$phoneSmsLog->phone = PhoneSmsLog::COUNTRY_CODE_JP . $phone;
|
||||
$phoneSmsLog->uid = $uid;
|
||||
$phoneSmsLog->send_times = 1;
|
||||
$phoneSmsLog->type = $type;
|
||||
$phoneSmsLog->expire_time = date("Y-m-d H:i:s", time() + $this->expireTime);
|
||||
$phoneSmsLog->response = $result ? json_encode($result) : '';
|
||||
if ($env == 'pro') {
|
||||
if (isset($result) && $result['code'] == '00000') {
|
||||
if (isset($result['result']) && $result['result'][0]['status'] == '00000') {
|
||||
Cache::set($key, $code, $this->expireTime);
|
||||
$phoneSmsLog->status = 1;
|
||||
$phoneSmsLog->save();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Cache::set($key, $code, $this->expireTime);
|
||||
$phoneSmsLog->status = 1;
|
||||
$phoneSmsLog->save();
|
||||
return true;
|
||||
}
|
||||
$phoneSmsLog->status = 0;
|
||||
$phoneSmsLog->save();
|
||||
|
||||
throw new Exception(trans('phone_code_send_failed', [], 'message'));
|
||||
}
|
||||
}
|
||||
147
app/service/OnePayServices.php
Normal file
147
app/service/OnePayServices.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
// 日本手机号发送短信
|
||||
namespace app\service;
|
||||
|
||||
use app\exception\GameException;
|
||||
use support\Log;
|
||||
use WebmanTech\LaravelHttpClient\Facades\Http;
|
||||
|
||||
class OnePayServices
|
||||
{
|
||||
// 应用key
|
||||
private $merchantId = '';
|
||||
// 应用代码
|
||||
private $key = '';
|
||||
// 应用秘钥
|
||||
private $domain = '';
|
||||
// domain
|
||||
private $notifyUrl = '';
|
||||
private $payoutNotifyUrl = '';
|
||||
private $returnUrl = '';
|
||||
// 过期时间
|
||||
public $expireTime = 180;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->merchantId = config('one_pay.merchantId');
|
||||
$this->key = config('one_pay.key');
|
||||
$this->api_key = config('one_pay.api_key');
|
||||
$this->domain = config('one_pay.domain');
|
||||
$this->notifyUrl = config('one_pay.notifyUrl');
|
||||
$this->payoutNotifyUrl = config('one_pay.payoutNotifyUrl');
|
||||
$this->returnUrl = config('one_pay.returnUrl');
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行请求
|
||||
* @param string $api 接口
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function doCurl(string $api, array $params): array
|
||||
{
|
||||
$result = Http::timeout(10)->asForm()->post($this->domain.$api, $params);
|
||||
Log::channel('pay_log')->info('onepay:'.$api,json_decode($result, true));
|
||||
return json_decode($result, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建签名
|
||||
* @throws GameException
|
||||
*/
|
||||
public function getAuth(): string
|
||||
{
|
||||
$data = [
|
||||
'username' => $this->merchantId,
|
||||
'api_key' => $this->api_key,
|
||||
];
|
||||
$result = $this->doCurl('merchant/auth',$data);
|
||||
if ($result['status'] == 'true') {
|
||||
return $result['auth'];
|
||||
} else {
|
||||
throw new GameException($result['message'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建签名
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function calculateSignature(array $params): string
|
||||
{
|
||||
ksort($params);
|
||||
$signature_string = '';
|
||||
foreach ($params as $key => $value) {
|
||||
$signature_string .= $key . ':' . $value . '&';
|
||||
}
|
||||
$signature_string .= 'key:' . $this->key;
|
||||
return strtoupper(md5($signature_string));
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证返回签名
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function verifySign(array $params): string
|
||||
{
|
||||
return md5($this->key.$params['order_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 存款
|
||||
* @param array $params 参数
|
||||
* @throws GameException
|
||||
*/
|
||||
public function deposit(array $params): array
|
||||
{
|
||||
$data = [
|
||||
'username' => $params['uuid'],
|
||||
'auth' => $this->getAuth(),
|
||||
'amount' => $params['amount'],
|
||||
'currency' => 'MYR',
|
||||
'orderid' => $params['orderNo'],
|
||||
'email' => $params['email'],
|
||||
'phone_number' => $params['phone'],
|
||||
'redirect_url' => $this->returnUrl.'?orderNo='.$params['orderNo'],
|
||||
'pay_method' => $params['paymentCode'],
|
||||
'callback_url' => $this->notifyUrl,
|
||||
];
|
||||
if ($data['pay_method'] == 'online_banking') {
|
||||
$data['bank_id'] = $params['bank_id'];
|
||||
}
|
||||
return $this->doCurl('merchant/generate_orders',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 代付
|
||||
* @param array $params 参数
|
||||
* @throws GameException
|
||||
*/
|
||||
public function payout(array $params): array
|
||||
{
|
||||
$data = [
|
||||
'auth' => $this->getAuth(),
|
||||
'amount' => $params['amount'],
|
||||
'currency' => 'MYR',
|
||||
'orderid' => $params['orderNo'],
|
||||
'bank_id' => $params['bankCode'],
|
||||
'holder_name' => $params['bankAccountName'],
|
||||
'account_no' => $params['bankAccountNo'],
|
||||
'callback_url' => $this->payoutNotifyUrl,
|
||||
];
|
||||
return $this->doCurl('merchant/withdraw_orders',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单查询
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function query(array $params): array
|
||||
{
|
||||
$data = [
|
||||
'username' => $this->merchantId,
|
||||
'id' => $params['orderNo'],
|
||||
];
|
||||
return $this->doCurl('merchant/check_status',$data);
|
||||
}
|
||||
|
||||
}
|
||||
130
app/service/SePayServices.php
Normal file
130
app/service/SePayServices.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
// 日本手机号发送短信
|
||||
namespace app\service;
|
||||
|
||||
use support\Log;
|
||||
use WebmanTech\LaravelHttpClient\Facades\Http;
|
||||
|
||||
class SePayServices
|
||||
{
|
||||
// 应用key
|
||||
private $merchantId = '';
|
||||
// 应用代码
|
||||
private $key = '';
|
||||
// 应用秘钥
|
||||
private $domain = '';
|
||||
// domain
|
||||
private $notifyUrl = '';
|
||||
private $payoutNotifyUrl = '';
|
||||
private $returnUrl = '';
|
||||
// 过期时间
|
||||
public $expireTime = 180;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->merchantId = config('se-pay.merchantId');
|
||||
$this->key = config('se-pay.MD5');
|
||||
$this->domain = config('se-pay.domain');
|
||||
$this->notifyUrl = config('se-pay.notifyUrl');
|
||||
$this->payoutNotifyUrl = config('se-pay.payoutNotifyUrl');
|
||||
$this->returnUrl = config('se-pay.returnUrl');
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行请求
|
||||
* @param string $api 接口
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function doCurl(string $api, array $params): array
|
||||
{
|
||||
$result = Http::timeout(10)->asForm()->post($this->domain.$api, $params);
|
||||
Log::channel('pay_log')->info('sepay:'.$api,json_decode($result, true));
|
||||
return json_decode($result, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建签名
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function calculateSignature(array $params): string
|
||||
{
|
||||
ksort($params);
|
||||
$signature_string = '';
|
||||
foreach ($params as $key => $value) {
|
||||
$signature_string .= $key . ':' . $value . '&';
|
||||
}
|
||||
$signature_string .= 'key:' . $this->key;
|
||||
return strtoupper(md5($signature_string));
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证返回签名
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function verifySign(array $params): string
|
||||
{
|
||||
ksort($params);
|
||||
unset($params['signMsg']);
|
||||
$signature_string = '';
|
||||
foreach ($params as $key => $value) {
|
||||
$signature_string .= $key . ':' . $value . '&';
|
||||
}
|
||||
$signature_string .= 'key:' . $this->key;
|
||||
return strtoupper(md5($signature_string));
|
||||
}
|
||||
|
||||
/**
|
||||
* 存款
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function deposit(array $params): array
|
||||
{
|
||||
$params['notifyUrl'] = $this->notifyUrl;
|
||||
$params['returnUrl'] = $this->returnUrl.'?orderNo='.$params['orderNo'];
|
||||
$request_str = base64_encode(json_encode($params));
|
||||
$data = [
|
||||
'merchantNo' => $this->merchantId,
|
||||
'request' => $request_str,
|
||||
'version' => '1.0',
|
||||
];
|
||||
$signature = $this->calculateSignature($data);
|
||||
$data['signMsg'] = $signature;
|
||||
return $this->doCurl('qrh5',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 代付
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function payout(array $params): array
|
||||
{
|
||||
$params['notifyUrl'] = $this->payoutNotifyUrl;
|
||||
$request_str = base64_encode(json_encode($params));
|
||||
$data = [
|
||||
'merchantNo' => $this->merchantId,
|
||||
'request' => $request_str,
|
||||
'version' => '1.0',
|
||||
];
|
||||
$signature = $this->calculateSignature($data);
|
||||
$data['signMsg'] = $signature;
|
||||
return $this->doCurl('payout',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单查询
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function query(array $params): array
|
||||
{
|
||||
$request_str = base64_encode(json_encode($params));
|
||||
$data = [
|
||||
'merchantNo' => $this->merchantId,
|
||||
'request' => $request_str,
|
||||
'version' => '1.0',
|
||||
];
|
||||
$signature = $this->calculateSignature($data);
|
||||
$data['signMsg'] = $signature;
|
||||
return $this->doCurl('query',$data);
|
||||
}
|
||||
|
||||
}
|
||||
96
app/service/SklPayServices.php
Normal file
96
app/service/SklPayServices.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
// 日本手机号发送短信
|
||||
namespace app\service;
|
||||
|
||||
use app\exception\GameException;
|
||||
use support\Log;
|
||||
use WebmanTech\LaravelHttpClient\Facades\Http;
|
||||
|
||||
class SklPayServices
|
||||
{
|
||||
// 应用key
|
||||
private $merchantId = '';
|
||||
// 应用代码
|
||||
private $api_key = '';
|
||||
// 应用秘钥
|
||||
private $domain = '';
|
||||
// domain
|
||||
private $notifyUrl = '';
|
||||
private $payoutNotifyUrl = '';
|
||||
private $returnUrl = '';
|
||||
// 过期时间
|
||||
public $expireTime = 180;
|
||||
/**
|
||||
* @var array|mixed|null
|
||||
*/
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->merchantId = config('skl_pay.merchantId');
|
||||
$this->api_key = config('skl_pay.api_key');
|
||||
$this->domain = config('skl_pay.domain');
|
||||
$this->notifyUrl = config('skl_pay.notifyUrl');
|
||||
$this->payoutNotifyUrl = config('skl_pay.payoutNotifyUrl');
|
||||
$this->returnUrl = config('skl_pay.returnUrl');
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行请求
|
||||
* @param string $api 接口
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function doCurl(string $api, array $params): array
|
||||
{
|
||||
$result = Http::timeout(10)->asJson()->post($this->domain.$api, $params);
|
||||
Log::channel('pay_log')->info('sklpay:'.$api,json_decode($result, true));
|
||||
return json_decode($result, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 存款
|
||||
* @param array $params 参数
|
||||
* @throws GameException
|
||||
*/
|
||||
public function deposit(array $params): array
|
||||
{
|
||||
$data = [
|
||||
'api_token' => $this->api_key,
|
||||
'amount' => $params['amount'],
|
||||
'gateway' => $params['paymentCode'],
|
||||
'pusername' => $params['name'],
|
||||
'invoice_no' => $params['orderNo'],
|
||||
];
|
||||
return $this->doCurl('/api/transaction/init',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 代付
|
||||
* @param array $params 参数
|
||||
* @throws GameException
|
||||
*/
|
||||
public function payout(array $params): array
|
||||
{
|
||||
$data = [
|
||||
'api_token' => $this->api_key,
|
||||
'amount' => $params['amount'],
|
||||
'to_bank' => $params['bankCode'],
|
||||
'to_bank_account_no' => $params['bankAccountNo'],
|
||||
'account_holder' => $params['bankAccountName'],
|
||||
'invoice_no' => $params['orderNo'],
|
||||
];
|
||||
return $this->doCurl('/api/transfer_out/init',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单查询
|
||||
* @param array $params 参数
|
||||
*/
|
||||
public function query(array $params): array
|
||||
{
|
||||
$data = [
|
||||
'transaction_id' => $params['orderNo'],
|
||||
];
|
||||
return $this->doCurl('/api/transaction/get_status',$data);
|
||||
}
|
||||
|
||||
}
|
||||
41
app/service/SmsServicesServices.php
Normal file
41
app/service/SmsServicesServices.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
namespace app\service;
|
||||
|
||||
|
||||
use addons\webman\model\PhoneSmsLog;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* 短信服务
|
||||
*/
|
||||
class SmsServicesServices
|
||||
{
|
||||
/**
|
||||
* @param int $countryCode
|
||||
* @param string $phone
|
||||
* @param int $type
|
||||
* @param int $playerId
|
||||
* @param string $name
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function sendSms(int $countryCode, string $phone, int $type, int $playerId = 0, string $name = ''): bool
|
||||
{
|
||||
$openCountryCode = config('sms.open_country_code');
|
||||
if (!in_array($countryCode, $openCountryCode)) {
|
||||
$openCountryName = '';
|
||||
foreach ($openCountryCode as $item) {
|
||||
$openCountryName .= ',' . trans('country_code_name.' . $item, [], 'message');
|
||||
}
|
||||
throw new Exception(trans('currently_open_countries_and_regions', ['{openCountryCode}', $openCountryName], 'message'));
|
||||
}
|
||||
switch ($countryCode) {
|
||||
case PhoneSmsLog::COUNTRY_CODE_TW:
|
||||
return (new TwSmsServicesServices())->send($phone, $type, $playerId, $name);
|
||||
case PhoneSmsLog::COUNTRY_CODE_JP:
|
||||
return (new JpSmsServicesServices())->send($phone, $type, $playerId);
|
||||
default:
|
||||
throw new Exception(trans('country_code_error', [], 'message'));
|
||||
}
|
||||
}
|
||||
}
|
||||
121
app/service/TwSmsServicesServices.php
Normal file
121
app/service/TwSmsServicesServices.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
// 台湾手机号发送短信
|
||||
namespace app\service;
|
||||
|
||||
use addons\webman\model\PhoneSmsLog;
|
||||
use Exception;
|
||||
use Illuminate\Support\Str;
|
||||
use support\Cache;
|
||||
use support\Log;
|
||||
use WebmanTech\LaravelHttpClient\Facades\Http;
|
||||
|
||||
class TwSmsServicesServices implements BaseSmsServices
|
||||
{
|
||||
// 使⽤者帳號
|
||||
private $username = '';
|
||||
// 使⽤者密碼
|
||||
private $password = '';
|
||||
// domain
|
||||
private $domain = '';
|
||||
// 过期时间
|
||||
public $expireTime = 300;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->domain = config('tw-sms.domain');
|
||||
$this->username = config('tw-sms.username');
|
||||
$this->password = config('tw-sms.password');
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行请求
|
||||
* @param string $api 接口
|
||||
* @param array $params 参数
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function doCurl(string $api, array $params)
|
||||
{
|
||||
$result = Http::timeout(10)->post($this->domain . $api . '?' . http_build_query($params));
|
||||
if ($result->ok()) {
|
||||
$arr = preg_split('/[;\r\n]+/s', $result->body());
|
||||
$data = [];
|
||||
foreach ($arr as $item) {
|
||||
$arr = explode('=', $item);
|
||||
if (!empty($arr) && isset($arr[0]) && isset($arr[1])) {
|
||||
$data[$arr[0]] = $arr[1];
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
throw new Exception(trans('phone_code_send_failed', [], 'message'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 日本供应商短信发送
|
||||
* @param $phone
|
||||
* @param $type
|
||||
* @param int $playerId
|
||||
* @param string $name
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function send($phone, $type, int $playerId = 0, string $name = ''): bool
|
||||
{
|
||||
$env = config('app.env');
|
||||
$api = config('tw-sms.sm_send_api');
|
||||
$code = ($env == 'pro' ? random_int(10000, 99999) : config('sms.default_code'));
|
||||
$key = setSmsKey($phone, $type);
|
||||
$uid = gen_uuid();
|
||||
$msg = Str::replaceFirst('{code}', $code, getContent($type, 'tw'));
|
||||
//驗證通過
|
||||
if ($env == 'pro') {
|
||||
$result = $this->doCurl($api, [
|
||||
'username' => $this->username,
|
||||
'password' => $this->password,
|
||||
'dstaddr' => $phone,
|
||||
'destname' => $name,
|
||||
'dlvtime' => '',
|
||||
'vldtime' => $this->expireTime,
|
||||
'smbody' => $msg,
|
||||
'CharsetURL' => 'UTF-8',
|
||||
]);
|
||||
Log::info('短信发送结果', [$result]);
|
||||
} else {
|
||||
$result = $env;
|
||||
}
|
||||
$phoneSmsLog = new PhoneSmsLog();
|
||||
$phoneSmsLog->player_id = $playerId;
|
||||
$phoneSmsLog->code = $code;
|
||||
$phoneSmsLog->phone = PhoneSmsLog::COUNTRY_CODE_TW . $phone;
|
||||
$phoneSmsLog->uid = $uid;
|
||||
$phoneSmsLog->send_times = 1;
|
||||
$phoneSmsLog->type = $type;
|
||||
$phoneSmsLog->expire_time = date("Y-m-d H:i:s", time() + $this->expireTime);
|
||||
$phoneSmsLog->response = $result ? json_encode($result) : '';
|
||||
if ($env == 'pro') {
|
||||
if (isset($result['statuscode'])) {
|
||||
/* 0 預約傳送中1 已送達業者2 已送達業者4 已送達⼿機5 內容有錯誤6 ⾨號有錯誤7 簡訊已停⽤8 逾時無送達9 預約已取消*/
|
||||
switch ($result['statuscode']) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '4':
|
||||
Cache::set($key, $code, $this->expireTime);
|
||||
$phoneSmsLog->status = 1;
|
||||
$phoneSmsLog->save();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Cache::set($key, $code, $this->expireTime);
|
||||
$phoneSmsLog->status = 1;
|
||||
$phoneSmsLog->save();
|
||||
return true;
|
||||
}
|
||||
$phoneSmsLog->status = 0;
|
||||
$phoneSmsLog->save();
|
||||
|
||||
throw new Exception(trans('phone_code_send_failed', [], 'message'));
|
||||
}
|
||||
}
|
||||
759
app/service/game/BigGamingServiceInterface.php
Normal file
759
app/service/game/BigGamingServiceInterface.php
Normal file
@@ -0,0 +1,759 @@
|
||||
<?php
|
||||
|
||||
namespace app\service\game;
|
||||
|
||||
use addons\webman\model\Game;
|
||||
use addons\webman\model\GamePlatform;
|
||||
use addons\webman\model\GameType;
|
||||
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 BigGamingServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
private $apiDomain;
|
||||
private $domain;
|
||||
private $appId;
|
||||
private $appSecret;
|
||||
private $loginId;
|
||||
private $sn;
|
||||
private $adminUser;
|
||||
private $secretCode;
|
||||
|
||||
public $gameType = [
|
||||
'2' => 'Casino',
|
||||
'5' => 'Fishing',
|
||||
'8' => 'Bingo',
|
||||
'1' => 'Slot',
|
||||
];
|
||||
|
||||
public $localGameType = [
|
||||
'2' => '2',//赌场
|
||||
'4' => '4',//捕鱼
|
||||
'5' => '5',//真人视讯
|
||||
];
|
||||
|
||||
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->sn = $config['sn'];
|
||||
$this->adminUser = $config['admin_user'];
|
||||
$this->secretCode = base64_encode(sha1($config['admin_pass'], true));
|
||||
$this->platform = GamePlatform::query()->where('name', $type)->first();
|
||||
if (!empty($player)) {
|
||||
$this->player = $player;
|
||||
$this->getLoginId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求url
|
||||
* @return string
|
||||
*/
|
||||
public function createUrl(): string
|
||||
{
|
||||
return $this->apiDomain;
|
||||
}
|
||||
|
||||
//生成签名
|
||||
public function createSign($params): string
|
||||
{
|
||||
$str = '';
|
||||
foreach ($params as $v) {
|
||||
$str .= $v;
|
||||
}
|
||||
return md5($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求数据
|
||||
* @param $postData
|
||||
* @param $method
|
||||
* @return array
|
||||
*/
|
||||
public function buildParams($postData, $method): array
|
||||
{
|
||||
return array(
|
||||
"jsonrpc" => "2.0",
|
||||
"method" => $method,
|
||||
"params" => $postData,
|
||||
"id" => $this->player->uuid ?? uniqid()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建代理账号
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function createAgent()
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => 'testagent123',
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
unset($params['secretKey']);
|
||||
$params['password'] = '123456ss';
|
||||
$postData = $this->buildParams($params, 'open.agent.create');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['result']) && empty($result['error'])){
|
||||
return $result;
|
||||
}else{
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新游戏列表
|
||||
* @return false
|
||||
*/
|
||||
public function getSimpleGameList(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家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 = [
|
||||
'random' => $data['uuid'],
|
||||
'sn' => $this->sn,
|
||||
'secretCode' => $this->secretCode,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$params['loginId'] = $data['uuid'];
|
||||
$params['nickname'] = $data['name'];
|
||||
$params['agentLoginId'] = $this->adminUser;
|
||||
unset($params['secretCode']);
|
||||
$postData = $this->buildParams($params, 'open.user.create');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['result']) && empty($result['error'])){
|
||||
$playerGamePlatform = new PlayerGamePlatform();
|
||||
$playerGamePlatform->player_id = $this->player->id;
|
||||
$playerGamePlatform->platform_id = $this->platform->id;
|
||||
$playerGamePlatform->player_name = $data['name'];
|
||||
$playerGamePlatform->player_code = $result['result']['loginId'];
|
||||
$playerGamePlatform->save();
|
||||
$this->loginId = $playerGamePlatform->player_code;
|
||||
return $result;
|
||||
}else{
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家信息
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|Exception
|
||||
*/
|
||||
public function getPlayer()
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => $this->loginId,
|
||||
'secretCode' => $this->secretCode,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
unset($params['secretCode']);
|
||||
$postData = $this->buildParams($params, 'open.user.get');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['result']) && empty($result['error'])){
|
||||
return $result;
|
||||
}else{
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家进入游戏
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function login(array $data = []): string
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => $this->loginId,
|
||||
'secretCode' => $this->secretCode,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$params['isMobileUrl'] = 1;
|
||||
unset($params['secretCode']);
|
||||
$postData = $this->buildParams($params, 'open.video.game.url');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result['result'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家游戏平台余额
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getBalance()
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => $this->loginId,
|
||||
'secretCode' => $this->secretCode,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
unset($params['secretCode']);
|
||||
$postData = $this->buildParams($params, 'open.balance.get');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (empty($result['error'])){
|
||||
return $result['result'];
|
||||
}else{
|
||||
throw new GameException('Big Gaming System Error,Please contact the administrator', 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
|
||||
}
|
||||
|
||||
/**
|
||||
* 游戏平台转入玩家钱包
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
$balance = $this->getBalance();
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, -$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 ($amount == 0) {
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward);
|
||||
return true;
|
||||
}
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => $this->loginId,
|
||||
'amount' => $amount,
|
||||
'secretCode' => $this->secretCode,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
unset($params['secretCode']);
|
||||
$postData = $this->buildParams($params, 'open.balance.transfer');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询额度转移纪录
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getTransferList(string $startTime = '', string $endTime = '', int $page = 1, int $pageSize = 15)
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
$params['loginId'] = $this->loginId;
|
||||
$params['startTime'] = $startTime;
|
||||
$params['endTime'] = $endTime;
|
||||
$params['timeZone'] = 1;
|
||||
unset($params['secretKey']);
|
||||
$postData = $this->buildParams($params, 'open.balance.transfer.query');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询注单统计结果
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getOrderSum(string $startTime = '', string $endTime = '', int $page = 1, int $pageSize = 500)
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
$params['loginIds'] = [$this->loginId];
|
||||
$params['startTime'] = $startTime;
|
||||
$params['endTime'] = $endTime;
|
||||
unset($params['secretKey']);
|
||||
$postData = $this->buildParams($params, 'open.sn.order.sum');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按玩家统计注单
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getUserOrderSum(string $startTime = '', string $endTime = '')
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
$params['startTime'] = $startTime;
|
||||
$params['endTime'] = $endTime;
|
||||
unset($params['secretKey']);
|
||||
$postData = $this->buildParams($params, 'open.user.order.sum');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result['result'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家游戏记录
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getUserGameRecord(string $startTime = '', string $endTime = '')
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => $this->loginId,
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
$params['startTime'] = $startTime;
|
||||
$params['endTime'] = $endTime;
|
||||
unset($params['secretKey']);
|
||||
$postData = $this->buildParams($params, 'open.video.round.query');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result['result'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家游戏记录
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function handleOrderHistories()
|
||||
{
|
||||
try {
|
||||
$page = 1;
|
||||
$list = [];
|
||||
$timezone = new DateTimeZone('America/New_York');
|
||||
$start = new DateTime('-6 minutes', $timezone);
|
||||
$end = new DateTime('-5 minutes', $timezone);
|
||||
$startTime = $start->format('Y-m-d H:i:s');
|
||||
$endTime = $end->format('Y-m-d H:i:s');
|
||||
$data = $this->getAgentOrderRecord($startTime, $endTime, $page);
|
||||
$fishData = $this->getUserFishOrderRecord($startTime, $endTime, $page);
|
||||
if (!empty($data['result'])) {
|
||||
$total = $data['result']['total'] ?? 0;
|
||||
if ($total > 0) {
|
||||
$pageSize = 200;
|
||||
if (!empty($data['result']['items'])) {
|
||||
foreach ($data['result']['items'] as $item) {
|
||||
$list[] = [
|
||||
'uuid' => $item['loginId'],
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $item['playNameEn'],
|
||||
'bet' => abs($item['bAmount']),
|
||||
'win' => $item['aAmount'],
|
||||
'order_no' => $item['orderId'],
|
||||
'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE),
|
||||
'platform_action_at' => $item['lastUpdateTime'],
|
||||
'game_type' => 5,
|
||||
'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->getAgentOrderRecord($startTime,$endTime,$page);
|
||||
if (!empty($nextData['result']['items'])) {
|
||||
foreach ($nextData['result']['items'] as $item) {
|
||||
$list[] = [
|
||||
'uuid' => $item['loginId'],
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $item['playNameEn'],
|
||||
'bet' => abs($item['bAmount']),
|
||||
'win' => $item['aAmount'],
|
||||
'order_no' => $item['orderId'],
|
||||
'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE),
|
||||
'platform_action_at' => $item['lastUpdateTime'],
|
||||
'game_type' => 5,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($fishData['result'])) {
|
||||
$fishTotal = $fishData['result']['total'] ?? 0;
|
||||
if ($fishTotal > 0) {
|
||||
$pageSize = 200;
|
||||
if (!empty($fishData['result']['items'])) {
|
||||
foreach ($fishData['result']['items'] as $item) {
|
||||
$list[] = [
|
||||
'uuid' => $item['loginId'],
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $item['gameType'],
|
||||
'bet' => abs($item['betAmount']),
|
||||
'win' => $item['calcAmount'],
|
||||
'order_no' => $item['betId'],
|
||||
'original_data' => json_encode($item, JSON_UNESCAPED_UNICODE),
|
||||
'platform_action_at' => $item['orderTimeBj'],
|
||||
'game_type' => 4,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
}
|
||||
}
|
||||
if ($fishTotal > $pageSize) {
|
||||
$totalPages = ceil($fishTotal / $pageSize);
|
||||
for ($page = 2; $page <= $totalPages; $page++) {
|
||||
$nextFishData = $this->getUserFishOrderRecord($startTime,$endTime,$page);
|
||||
if (!empty($nextFishData['result']['items'])) {
|
||||
foreach ($nextFishData['result']['items'] as $item) {
|
||||
$list[] = [
|
||||
'uuid' => $item['loginId'],
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $item['gameType'],
|
||||
'bet' => abs($item['betAmount']),
|
||||
'win' => $item['calcAmount'],
|
||||
'order_no' => $item['betId'],
|
||||
'original_data' => json_encode($item, JSON_UNESCAPED_UNICODE),
|
||||
'platform_action_at' => $item['orderTimeBj'],
|
||||
'game_type' => 4,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家注单
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getUserOrderRecord(string $startTime = '', string $endTime = '', $page = 1)
|
||||
{
|
||||
$pageSize = 200;
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
$params['startTime'] = $startTime;
|
||||
$params['endTime'] = $endTime;
|
||||
$params['pageIndex'] = $page;
|
||||
$params['pageSize'] = $pageSize;
|
||||
unset($params['secretKey']);
|
||||
$postData = $this->buildParams($params, 'open.order.query');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家注单详情
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getUserOrderDetail($orderId)
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'orderId' => $orderId,
|
||||
'reqTime' => date('Y-m-d H:i:s'),
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
unset($params['secretKey']);
|
||||
$postData = $this->buildParams($params, 'open.sn.video.order.detail');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result['result'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家注单详情地址
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getUserOrderDetailUrl($orderId)
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'orderId' => $orderId,
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
unset($params['secretKey']);
|
||||
$postData = $this->buildParams($params, 'open.sn.video.order.detail.url.get');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
|
||||
return $result['result'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家捕鱼注单
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getUserFishOrderRecord(string $startTime = '', string $endTime = '', $page = 1)
|
||||
{
|
||||
$pageSize = 200;
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
$params['gameType'] = 1;
|
||||
$params['agentLoginId'] = $this->adminUser;
|
||||
$params['startTime'] = $startTime;
|
||||
$params['endTime'] = $endTime;
|
||||
$params['pageIndex'] = $page;
|
||||
$params['pageSize'] = $pageSize;
|
||||
unset($params['secretKey']);
|
||||
$postData = $this->buildParams($params, 'open.order.bg.query');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询代理注单
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getAgentOrderRecord(string $startTime = '', string $endTime = '', $page = 1)
|
||||
{
|
||||
$pageSize = 200;
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'secretCode' => $this->secretCode,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$params['agentLoginId'] = $this->adminUser;
|
||||
$params['startTime'] = $startTime;
|
||||
$params['endTime'] = $endTime;
|
||||
$params['pageIndex'] = $page;
|
||||
$params['pageSize'] = $pageSize;
|
||||
unset($params['secretCode']);
|
||||
$postData = $this->buildParams($params, 'open.order.agent.query');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询投注限红盘口
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getLimitations()
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'time' => date('Y-m-d H:i:s'),
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
unset($params['secretKey']);
|
||||
$postData = $this->buildParams($params, 'open.game.limitations.get');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改投注限红盘口
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function setLimitations($value)
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'time' => date('Y-m-d H:i:s'),
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
$params['loginId'] = $this->loginId;
|
||||
$params['value'] = $value;
|
||||
unset($params['secretKey']);
|
||||
$postData = $this->buildParams($params, 'open.game.limitations.set');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取限红盘口列表
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getLimitationsList()
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'time' => date('Y-m-d H:i:s'),
|
||||
'secretKey' => $this->appSecret,
|
||||
];
|
||||
$params['sign'] = $this->createSign($params);
|
||||
unset($params['secretKey']);
|
||||
$postData = $this->buildParams($params, 'open.game.limitations.list');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
371
app/service/game/CSServiceInterface.php
Normal file
371
app/service/game/CSServiceInterface.php
Normal file
@@ -0,0 +1,371 @@
|
||||
<?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 Exception;
|
||||
use support\Log;
|
||||
use support\Response;
|
||||
|
||||
class CSServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
public $successCode = '0';
|
||||
/** @var PlayerGamePlatform $playerGamePlatform */
|
||||
public $playerGamePlatform;
|
||||
public $gameType = [
|
||||
'CB' => 'CARD & BOARDGAME',
|
||||
'ES' => 'E-GAMES',
|
||||
'SB' => 'SPORTBOOK',
|
||||
'LC' => 'LIVE-CASINO',
|
||||
'SL' => 'SLOTS',
|
||||
'LK' => 'LOTTO',
|
||||
'FH' => 'FISH HUNTER',
|
||||
'PK' => 'POKER',
|
||||
'MG' => 'MINI GAME',
|
||||
'OT' => 'OTHERS'
|
||||
];
|
||||
public $failCode = [
|
||||
'61' => '货币不兼容',
|
||||
'70' => '集成系统余额不足',
|
||||
'71' => '单据号不正确',
|
||||
'72' => '余额不足',
|
||||
'73' => '转账金额不正确',
|
||||
'74' => '转账金额不能多过两个小数点 0.00',
|
||||
'75' => '不允许在游戏中进行转移',
|
||||
'81' => '会员账号不存在',
|
||||
'82' => '会员账号已存在',
|
||||
'83' => '代理号已存在',
|
||||
'90' => '请求参数不正确',
|
||||
'91' => '代理号不正确',
|
||||
'92' => '供应商代号不正确',
|
||||
'93' => '请求参数类型不正确',
|
||||
'94' => '账号不正确',
|
||||
'95' => '密码不正确',
|
||||
'96' => '旧密码不正确',
|
||||
'97' => '请求链接/域名不正确',
|
||||
'98' => '账号/密码错误',
|
||||
'99' => '加密错误',
|
||||
'600' => '前期检验失败。 存款/取款 操作已被无视',
|
||||
'601' => '此产品的存款 功能暂时停用维修',
|
||||
'602' => '此产品的取款 功能暂时停用维修',
|
||||
'603' => '即将执行在线系统维护,为了避免维护时导致的系统不稳定,转账API暂时停止(暂停时间大约5~10分钟,若提早完毕会提早解放)',
|
||||
'992' => '平台不兼容请求的游戏类型',
|
||||
'991' => '代理号已冻结',
|
||||
'994' => '接口访问被禁止',
|
||||
'995' => '平台未开通',
|
||||
'996' => '平台不支持',
|
||||
'998' => '请联系客服',
|
||||
'999' => '系统维护中',
|
||||
'9999' => '未知错误',
|
||||
'-987' => '交易单号不存在;产品不支持',
|
||||
'-997' => '系统错误,请联络客服。',
|
||||
'-998' => '集成系统接口余额不足',
|
||||
'-999' => '接口错误',
|
||||
];
|
||||
private $apiDomain;
|
||||
private $providerCode;
|
||||
private $appId;
|
||||
private $appSecret;
|
||||
private $path = [
|
||||
'createPlayer' => '/createMember.aspx',
|
||||
'getGameList' => '/getGameList.aspx',
|
||||
'getBalance' => '/getBalance.aspx',
|
||||
'getLoginH5' => '/launchGames.aspx',
|
||||
'getDLoginH5' => '/launchDGames.ashx',
|
||||
'changePassword' => '/changePassword.aspx',
|
||||
'checkAgentCredit' => '/checkAgentCredit.aspx',
|
||||
'checkMemberProductUsername' => '/checkMemberProductUsername.aspx',
|
||||
'launchAPP' => '/launchAPP.ashx',
|
||||
'checkTransaction' => '/checkTransaction.ashx',
|
||||
'setBalanceTransfer' => '/makeTransfer.aspx',
|
||||
'getDailyWager' => '/getDailyWager.ashx',
|
||||
'fetchArchieve' => '/fetchArchieve.aspx',
|
||||
'markbyjson' => '/markbyjson.aspx',
|
||||
'markArchieve' => '/markArchieve.ashx',
|
||||
'getGameRecord' => '/fetchbykey.aspx',
|
||||
];
|
||||
private $lang = [
|
||||
'zh-CN' => 'zh-ch',
|
||||
'en' => 'en_us',
|
||||
'zh_tc' => 'zh_tc',
|
||||
'en-us' => 'en-us',
|
||||
'id' => 'id',
|
||||
'th' => 'th',
|
||||
'my' => 'my',
|
||||
'vi' => 'vi',
|
||||
'fi_fi' => 'fi_fi',
|
||||
'kr_ko' => 'kr_ko',
|
||||
'hi_hi' => 'hi_hi',
|
||||
'br_po' => 'br_po',
|
||||
'lo_la' => 'lo_la',
|
||||
'cam_dia' => 'cam_dia', // 柬埔寨语
|
||||
];
|
||||
|
||||
/**
|
||||
* @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->appSecret = $config['app_secret'];
|
||||
$this->apiDomain = $config['api_domain'];
|
||||
$this->providerCode = $config['provider_code'];
|
||||
$this->platform = GamePlatform::query()->where('name', $type)->first();
|
||||
if (!empty($player)) {
|
||||
$this->player = $player;
|
||||
/** @var PlayerGamePlatform $playerGamePlatform */
|
||||
$playerGamePlatform = $this->player->playerGamePlatform->where('platform_id', $this->platform->id)->first();
|
||||
if (empty($playerGamePlatform)) {
|
||||
$this->createPlayer();
|
||||
} else {
|
||||
$this->playerGamePlatform = $playerGamePlatform;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建玩家 MD5(operatorcode + username +secret_key)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function createPlayer()
|
||||
{
|
||||
$userName = mb_strtolower($this->providerCode . generateUniqueUsername());
|
||||
$params = [
|
||||
'operatorcode' => $this->appId,
|
||||
'username' => $userName,
|
||||
];
|
||||
$params['signature'] = mb_strtoupper(md5($this->appId . $userName . $this->appSecret));
|
||||
$res = dogGetCurl($this->createUrl('createPlayer'), $params);
|
||||
if ($res['errCode'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['errCode']], 0);
|
||||
}
|
||||
$playerGamePlatform = new PlayerGamePlatform();
|
||||
$playerGamePlatform->player_id = $this->player->id;
|
||||
$playerGamePlatform->platform_id = $this->platform->id;
|
||||
$playerGamePlatform->player_name = $this->player->name;
|
||||
$playerGamePlatform->player_code = $userName;
|
||||
$playerGamePlatform->player_password = generateRandomPassword();
|
||||
$playerGamePlatform->save();
|
||||
$this->playerGamePlatform = $playerGamePlatform;
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求url
|
||||
* @param $method
|
||||
* @return string
|
||||
*/
|
||||
public function createUrl($method): string
|
||||
{
|
||||
return $this->apiDomain . $this->path[$method];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家游戏平台帐号接口 MD5(operatorcode + providercode + username + secret_key)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getPlayer()
|
||||
{
|
||||
$params = [
|
||||
'operatorcode' => $this->appId,
|
||||
'providercode' => $this->providerCode,
|
||||
'username' => $this->playerGamePlatform->player_code,
|
||||
];
|
||||
$params['signature'] = mb_strtoupper(md5($this->appId . $this->providerCode . $this->playerGamePlatform->player_code . $this->appSecret));
|
||||
$res = dogGetCurl($this->createUrl('checkMemberProductUsername'), $params);
|
||||
if ($res['errCode'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['errCode']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏列表 MD5(operatorcode.toLower() + providercode.toUpper() + secret_key)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getSimpleGameList()
|
||||
{
|
||||
$params = [
|
||||
'providercode' => $this->providerCode,
|
||||
'operatorcode' => $this->appId,
|
||||
'lang' => 'en',
|
||||
'html' => '0',
|
||||
'reformatJson' => 'yes',
|
||||
];
|
||||
$params['signature'] = strtoupper(md5(mb_strtolower($this->appId) . mb_strtoupper($this->providerCode) . $this->appSecret));
|
||||
$data = dogGetCurl($this->createUrl('getGameList'), $params);
|
||||
if ($data['errCode'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['errCode']], 0);
|
||||
}
|
||||
if (!empty($data['gamelist'])) {
|
||||
$gameList = json_decode($data['gamelist'], true);
|
||||
foreach ($gameList as $game) {
|
||||
try {
|
||||
Game::query()->updateOrCreate(
|
||||
[
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $game['g_code']
|
||||
],
|
||||
[
|
||||
'platform_game_type' => $game['p_type'],
|
||||
'game_data' => json_encode($game),
|
||||
'name' => $game['gameName']['gameName_enus'] ?? '',
|
||||
'game_image' => $game['imgFileName'] ?? '',
|
||||
]
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录游戏MD5(operatorcode + password + providercode + type + username + secret_key)
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function login(array $data = []): string
|
||||
{
|
||||
$params = [
|
||||
'operatorcode' => $this->appId,
|
||||
'providercode' => $this->providerCode,
|
||||
'username' => $this->playerGamePlatform->player_code,
|
||||
'password' => $this->playerGamePlatform->player_password,
|
||||
'type' => $data['platformGameType'],
|
||||
'gameid' => $data['gameCode'] ?? 0,
|
||||
'lang' => 'en',
|
||||
'html5' => 1,
|
||||
];
|
||||
$params['signature'] = mb_strtoupper(md5($this->appId . $this->playerGamePlatform->player_password . $this->providerCode . $data['platformGameType'] . $this->playerGamePlatform->player_code . $this->appSecret));
|
||||
$res = dogGetCurl($this->createUrl('getLoginH5'), $params);
|
||||
|
||||
if ($res['errCode'] != $this->successCode) {
|
||||
Log::error($this->failCode[$res['errCode']], ['res' => $res]);
|
||||
throw new GameException($this->failCode[$res['errCode']], 0);
|
||||
}
|
||||
return $res['gameUrl'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, intval($this->player->wallet->money));
|
||||
}
|
||||
|
||||
/**
|
||||
* 资金转账接口MD5(amount + operatorcode + password + providercode + referenceid + type + username + secret_key)
|
||||
* @param $type
|
||||
* @param float $amount
|
||||
* @return array|mixed|null
|
||||
* @throws GameException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
protected function setBalanceTransfer($type, float $amount = 0)
|
||||
{
|
||||
if ($type == PlayerWalletTransfer::TYPE_OUT) {
|
||||
$platformType = 0;
|
||||
} else {
|
||||
$platformType = 1;
|
||||
}
|
||||
|
||||
$no = createOrderNo();
|
||||
$params = [
|
||||
'operatorcode' => $this->appId,
|
||||
'providercode' => $this->providerCode,
|
||||
'username' => $this->playerGamePlatform->player_code,
|
||||
'password' => $this->playerGamePlatform->player_password,
|
||||
'referenceid' => $no,
|
||||
'type' => $platformType,
|
||||
'amount' => $amount
|
||||
];
|
||||
$params['signature'] = mb_strtoupper(md5($amount . $this->appId . $this->playerGamePlatform->player_password . $this->providerCode . $no . $platformType . $this->playerGamePlatform->player_code . $this->appSecret));
|
||||
$res = dogGetCurl($this->createUrl('setBalanceTransfer'), $params);
|
||||
if ($res['errCode'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['errCode']], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, 0, $res['innerCode'] ?? '');
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
$balance = $this->getBalance();
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, $balance['balance'] ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取玩家餘額信息
|
||||
* 簽名密鑰方式 MD5(operatorcode + password + providercode + username + secret_key)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getBalance()
|
||||
{
|
||||
$params = [
|
||||
'operatorcode' => $this->appId,
|
||||
'providercode' => $this->providerCode,
|
||||
'username' => $this->playerGamePlatform->player_code,
|
||||
'password' => $this->playerGamePlatform->player_password
|
||||
];
|
||||
$params['signature'] = mb_strtoupper(md5($this->appId . $this->playerGamePlatform->player_password . $this->providerCode . $this->playerGamePlatform->player_code . $this->appSecret));
|
||||
$res = dogGetCurl($this->createUrl('getBalance'), $params);
|
||||
if ($res['errCode'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['errCode']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 依據時間獲取遊戲紀錄
|
||||
* MD5 (Id+Method+SN+StartTime+EndTime+APISecretKey)
|
||||
* @param int $pageIndex
|
||||
* @param string $startTime
|
||||
* @param string $endTime
|
||||
* @return array|mixed|null
|
||||
* @throws GameException
|
||||
*/
|
||||
public function getGameRecordByTime(int $pageIndex = 1, string $startTime = '', string $endTime = '')
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取玩家遊戲歷史紀錄
|
||||
* MD5 (Id+Method+SN+APISecretKey)
|
||||
* @return array|mixed|null
|
||||
* @throws GameException
|
||||
*/
|
||||
public function getGameRecord()
|
||||
{
|
||||
}
|
||||
}
|
||||
141
app/service/game/GameServiceFactory.php
Normal file
141
app/service/game/GameServiceFactory.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace app\service\game;
|
||||
|
||||
use addons\webman\model\GamePlatform;
|
||||
use addons\webman\model\Player;
|
||||
use addons\webman\model\PlayerDeliveryRecord;
|
||||
use addons\webman\model\PlayerWalletTransfer;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* 游戏服务工厂
|
||||
*/
|
||||
class GameServiceFactory
|
||||
{
|
||||
const TYPE_LUCKY365 = 'LUCKY365'; // lucky365
|
||||
const TYPE_BIGGAMING = 'BIGGAMING'; // BigGaming
|
||||
const TYPE_JILI = 'JILI'; // jili
|
||||
const TYPE_MEGA888 = 'MEGA888'; // Mega888
|
||||
const TYPE_KISS918 = 'KISS918'; // Kiss918
|
||||
const TYPE_JDB = 'JDB'; // JDB
|
||||
const TYPE_PRAGMATIC = 'PRAGMATIC'; // PRAGMATIC
|
||||
const TYPE_MARIOCLUB = 'MARIOCLUB'; // MARIOCLUB
|
||||
const TYPE_JOKER = 'JOKER'; // JOKER
|
||||
const TYPE_LIONKING = 'LIONKING'; // LionKing
|
||||
const TYPE_MONKEY_KING = 'MONKEYKING'; // monkey king
|
||||
const TYPE_ASIAGAMING = 'ASIAGAMING'; // AsiaGaming
|
||||
const TYPE_TFGAMING = 'TFGAMING'; // TfGaming
|
||||
const TYPE_IBC = 'IBC'; // IBC
|
||||
const TYPE_PLAYSTAR = 'PLAYSTAR'; // PlayStar
|
||||
const TYPE_AWC68 = 'AWC68'; // AWC68
|
||||
const TYPE_GAMEPLAY = 'GAMEPLAY'; // GamePlay
|
||||
const TYPE_NEXTSPIN = 'NEXTSPIN'; // GamePlay
|
||||
const TYPE_WMCASINO = 'WMCASINO'; // WMcasino
|
||||
const TYPE_SPADEGAMING = 'SPADEGAMING'; // SpadeGaming
|
||||
const TYPE_FUNKYGAME = 'FUNKYGAME'; // FunkyGame
|
||||
const TYPE_R5 = 'R5'; // R5
|
||||
const TYPE_JK = 'JK'; // JK
|
||||
|
||||
const DEVICE_TYPE_WEB = 1; // web
|
||||
const DEVICE_TYPE_IOS = 2; // ios
|
||||
const DEVICE_TYPE_ANDROID = 3; // android
|
||||
|
||||
/** @var Player $player */
|
||||
public $player;
|
||||
/** @var GamePlatform $platform */
|
||||
public $platform;
|
||||
|
||||
/**
|
||||
* 创建服务
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function createService(string $type, $player = null): GameServiceInterface
|
||||
{
|
||||
switch ($type) {
|
||||
case self::TYPE_LUCKY365:
|
||||
return new Lucky365ServiceInterface(self::TYPE_LUCKY365, $player);
|
||||
case self::TYPE_JILI:
|
||||
return new JiLiServiceInterface(self::TYPE_JILI, $player);
|
||||
case self::TYPE_MEGA888:
|
||||
return new MeGa888ServiceInterface(self::TYPE_MEGA888, $player);
|
||||
case self::TYPE_BIGGAMING:
|
||||
return new BigGamingServiceInterface(self::TYPE_BIGGAMING, $player);
|
||||
case self::TYPE_KISS918:
|
||||
return new Kiss918ServiceInterface(self::TYPE_KISS918, $player);
|
||||
case self::TYPE_JDB:
|
||||
return new JDBServiceInterface(self::TYPE_JDB, $player);
|
||||
case self::TYPE_PRAGMATIC:
|
||||
return new PragmaticServiceInterface(self::TYPE_PRAGMATIC, $player);
|
||||
case self::TYPE_MARIOCLUB:
|
||||
return new MarioClubServiceInterface(self::TYPE_MARIOCLUB, $player);
|
||||
case self::TYPE_JOKER:
|
||||
return new JokerServiceInterface(self::TYPE_JOKER, $player);
|
||||
case self::TYPE_NEXTSPIN:
|
||||
return new NextSpinServiceInterface(self::TYPE_NEXTSPIN, $player);
|
||||
case self::TYPE_MONKEY_KING:
|
||||
return new MonkeyKingServiceInterface(self::TYPE_MONKEY_KING, $player);
|
||||
case self::TYPE_LIONKING:
|
||||
return new LionKingServiceInterface(self::TYPE_LIONKING, $player);
|
||||
case self::TYPE_ASIAGAMING:
|
||||
case self::TYPE_TFGAMING:
|
||||
case self::TYPE_IBC:
|
||||
case self::TYPE_PLAYSTAR:
|
||||
case self::TYPE_AWC68:
|
||||
case self::TYPE_GAMEPLAY:
|
||||
case self::TYPE_WMCASINO:
|
||||
case self::TYPE_SPADEGAMING:
|
||||
case self::TYPE_FUNKYGAME:
|
||||
case self::TYPE_R5:
|
||||
case self::TYPE_JK:
|
||||
return new CSServiceInterface($type, $player);
|
||||
default:
|
||||
throw new Exception("未知的游戏服务类型: $type");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 报错平台转出/入记录
|
||||
* @param int $type
|
||||
* @param float $amount
|
||||
* @param float $reward
|
||||
* @param string $platformNo
|
||||
* @return void
|
||||
*/
|
||||
public function createWalletTransfer(int $type = 1, float $amount = 0, float $reward = 0, string $platformNo = '')
|
||||
{
|
||||
$playerWalletTransfer = new PlayerWalletTransfer();
|
||||
$playerWalletTransfer->player_id = $this->player->id;
|
||||
$playerWalletTransfer->platform_id = $this->platform->id;
|
||||
$playerWalletTransfer->department_id = $this->player->department_id;
|
||||
$playerWalletTransfer->type = $type;
|
||||
$playerWalletTransfer->amount = abs($amount);
|
||||
$playerWalletTransfer->reward = abs($reward);
|
||||
$playerWalletTransfer->platform_no = $platformNo;
|
||||
$playerWalletTransfer->tradeno = createOrderNo();
|
||||
$playerWalletTransfer->save();
|
||||
$beforeGameAmount = $this->player->wallet->money;
|
||||
$playerDeliveryRecord = new PlayerDeliveryRecord;
|
||||
if ($type == PlayerWalletTransfer::TYPE_OUT) {
|
||||
$this->player->wallet->money = 0;
|
||||
$playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_GAME_OUT;
|
||||
}
|
||||
if ($type == PlayerWalletTransfer::TYPE_IN) {
|
||||
$this->player->wallet->money = bcadd($this->player->wallet->money, bcadd(abs($amount), abs($reward), 2), 2);
|
||||
$playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_GAME_IN;
|
||||
}
|
||||
$this->player->push();
|
||||
//寫入金流明細
|
||||
$playerDeliveryRecord->player_id = $playerWalletTransfer->player_id;
|
||||
$playerDeliveryRecord->department_id = $playerWalletTransfer->department_id;
|
||||
$playerDeliveryRecord->target = $playerWalletTransfer->getTable();
|
||||
$playerDeliveryRecord->target_id = $playerWalletTransfer->id;
|
||||
$playerDeliveryRecord->source = 'play_game';
|
||||
$playerDeliveryRecord->amount = $playerWalletTransfer->amount;
|
||||
$playerDeliveryRecord->amount_before = $beforeGameAmount;
|
||||
$playerDeliveryRecord->amount_after = $this->player->wallet->money;
|
||||
$playerDeliveryRecord->tradeno = '';
|
||||
$playerDeliveryRecord->remark = '';
|
||||
$playerDeliveryRecord->save();
|
||||
}
|
||||
}
|
||||
30
app/service/game/GameServiceInterface.php
Normal file
30
app/service/game/GameServiceInterface.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace app\service\game;
|
||||
|
||||
interface GameServiceInterface
|
||||
{
|
||||
/**
|
||||
* 创建玩家
|
||||
* @return mixed
|
||||
*/
|
||||
public function createPlayer();
|
||||
|
||||
/**
|
||||
* 获取玩家信息
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPlayer();
|
||||
|
||||
/**
|
||||
* 获取游戏列表
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSimpleGameList();
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @return mixed
|
||||
*/
|
||||
public function login();
|
||||
}
|
||||
511
app/service/game/JDBServiceInterface.php
Normal file
511
app/service/game/JDBServiceInterface.php
Normal file
@@ -0,0 +1,511 @@
|
||||
<?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 Exception;
|
||||
use support\Response;
|
||||
|
||||
class JDBServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
public $successCode = '0000';
|
||||
public $loginId;
|
||||
public $gameType = [
|
||||
'10' => 'Slot',
|
||||
'12' => 'Casino',
|
||||
'13' => 'Arcade',
|
||||
'16' => 'Fishing'
|
||||
];
|
||||
public $failCode = [
|
||||
'0000' => '成功',
|
||||
'9999' => '失敗',
|
||||
'9001' => '未授權訪問',
|
||||
'9002' => '域名為空或域名長度小於 2',
|
||||
'9003' => '域名驗證失敗。',
|
||||
'9004' => '加密數據為空或加密數據的長度等於 0。',
|
||||
'9005' => '斷言(SAML)未通過時間戳驗證。',
|
||||
'9006' => '從加密數據中提取 SAML 參數失敗。',
|
||||
'9007' => '未知操作。',
|
||||
'9008' => '與之前的值相同。',
|
||||
'9009' => '超時。',
|
||||
'9010' => '讀取超時。',
|
||||
'9011' => '重複交易。',
|
||||
'9012' => '請稍後再試。',
|
||||
'9013' => '系統正在維護。',
|
||||
'9014' => '檢測到多帳戶登錄。',
|
||||
'9015' => '數據不存在。',
|
||||
'9016' => '無效令牌。',
|
||||
'9019' => '請求速率限制超過。',
|
||||
'9020' => '每次登錄只能獲得一次遊戲票。',
|
||||
'9021' => '違反一次性會話策略。',
|
||||
'9022' => '遊戲正在維護。',
|
||||
'9023' => '不支持的貨幣。',
|
||||
'9024' => '贏取倍數必須大於或等於 10 倍。',
|
||||
'9025' => '不支持重放遊戲。',
|
||||
'9026' => '获胜金额应大于0。',
|
||||
'9027' => '不支持演示。',
|
||||
'8000' => '輸入參數錯誤,請檢查您的參數是否正確。',
|
||||
'8001' => '參數不能為空。',
|
||||
'8002' => '參數必須是正整數。',
|
||||
'8003' => '參數不能為負數。',
|
||||
'8005' => '日期秒格式錯誤',
|
||||
'8006' => '時間不符合。',
|
||||
'8007' => '參數只能使用數字。',
|
||||
'8008' => '找不到參數。',
|
||||
'8009' => '時間間隔超過允許範圍。',
|
||||
'8010' => '參數長度太長。',
|
||||
'8013' => '日期分鐘格式參數錯誤。',
|
||||
'8014' => '參數不得超過指定的小數位。',
|
||||
'7001' => '找不到指定的父 ID。',
|
||||
'7002' => '父級已暫停。',
|
||||
'7003' => '父級已鎖定。',
|
||||
'7004' => '父級已關閉。',
|
||||
'7405' => '您已登出!',
|
||||
'7501' => '找不到用戶 ID。',
|
||||
'7502' => '用戶已暫停。',
|
||||
'7503' => '用戶已鎖定。',
|
||||
'7504' => '用戶已關閉。',
|
||||
'7505' => '用戶未在玩遊戲。',
|
||||
'7506' => '演示帳戶已滿。',
|
||||
'7601' => '無效的用戶 ID。請僅使用 a-z、0-9 之間的字符。',
|
||||
'7602' => '帳戶已存在。請選擇其他用戶 ID。',
|
||||
'7603' => '無效的用戶名。',
|
||||
'7604' => '密碼必須至少 6 個字符,包含 1 個字母和 1 個數字。',
|
||||
'7605' => '無效的操作代碼。請僅使用數字 2、3、4、5。',
|
||||
'6001' => '您的現金餘額不足以取款。',
|
||||
'6002' => '用戶餘額為零。',
|
||||
'6003' => '取款金額為負。',
|
||||
'6004' => '重複轉帳。',
|
||||
'6005' => '重複的序列號。',
|
||||
'6009' => '存款金額超過上限。',
|
||||
'6010' => '餘額超過上限。',
|
||||
'6011' => '分配的信用額超過上限。',
|
||||
'6012' => '序列號正在進行中。',
|
||||
'6901' => '用戶正在玩遊戲,不允許轉移餘額。'
|
||||
];
|
||||
private $apiDomain;
|
||||
private $domain;
|
||||
private $iv;
|
||||
private $key;
|
||||
private $dc;
|
||||
private $parent;
|
||||
private $lang = [
|
||||
'zh-CN' => 'cn',
|
||||
'zh-TW' => 'cn',
|
||||
'jp' => 'jpn',
|
||||
'en' => 'en',
|
||||
'th' => 'th',
|
||||
'vi' => 'vi',
|
||||
'kr_ko' => 'ko',
|
||||
'id' => 'id',
|
||||
];
|
||||
|
||||
public $localGameType = [
|
||||
'0' => '1',//斯洛
|
||||
'32' => '1',//斯洛
|
||||
'50' => '1',//斯洛
|
||||
'55' => '1',//斯洛
|
||||
'57' => '1',//斯洛
|
||||
'58' => '1',//斯洛
|
||||
'66' => '1',//斯洛
|
||||
'80' => '1',//斯洛
|
||||
'90' => '1',//斯洛
|
||||
'130' => '1',//斯洛
|
||||
'7' => '4',//捕鱼
|
||||
'31' => '4',//捕鱼
|
||||
'70' => '4',//捕鱼
|
||||
'59' => '4',//捕鱼
|
||||
'67' => '4',//捕鱼
|
||||
'91' => '4',//捕鱼
|
||||
'8' => '8',//宾果
|
||||
'12' => '8',//宾果
|
||||
'60' => '8',//宾果
|
||||
'9' => '8',//宾果
|
||||
'22' => '8',//宾果
|
||||
'30' => '8',//宾果
|
||||
'56' => '8',//宾果
|
||||
'75' => '8',//宾果
|
||||
'81' => '8',//宾果
|
||||
'92' => '8',//宾果
|
||||
'131' => '8',//宾果
|
||||
'120' => '8',//宾果
|
||||
'18' => '2',//赌场
|
||||
'93' => '2',//赌场
|
||||
'132' => '2',//赌场
|
||||
'41' => '5',//真人视讯
|
||||
'101' => '5',//真人视讯
|
||||
];
|
||||
|
||||
/**
|
||||
* @param Player|null $player
|
||||
* @param $type
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct($type, Player $player = null)
|
||||
{
|
||||
$config = config('game_platform.' . $type);
|
||||
$this->iv = $config['iv'];
|
||||
$this->apiDomain = $config['api_domain'].'/apiRequest.do';
|
||||
$this->domain = $config['domain'];
|
||||
$this->key = $config['key'];
|
||||
$this->dc = $config['dc'];
|
||||
$this->parent = $config['admin_user'];
|
||||
$this->platform = GamePlatform::query()->where('name', $type)->first();
|
||||
if (!empty($player)) {
|
||||
$this->player = $player;
|
||||
$this->getLoginId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求数据
|
||||
* @param $source
|
||||
* @return string
|
||||
*/
|
||||
public function padString($source): string
|
||||
{
|
||||
$paddingChar = ' ';
|
||||
$size = 16;
|
||||
$x = strlen($source) % $size;
|
||||
$padLength = $size - $x;
|
||||
$source .= str_repeat($paddingChar, $padLength);
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求数据
|
||||
* @param $params
|
||||
* @return array
|
||||
*/
|
||||
public function buildParams($params): array
|
||||
{
|
||||
$data = $this->padString(json_encode($params));
|
||||
$encryptData = openssl_encrypt($data, 'AES-128-CBC', $this->key, OPENSSL_NO_PADDING, $this->iv);
|
||||
$reqBase64 = base64_encode($encryptData);
|
||||
return [
|
||||
'dc' => $this->dc,
|
||||
'x' => str_replace(array('+','/','=') , array('-','_','') , $reqBase64)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @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|\think\Exception
|
||||
*/
|
||||
public function createPlayer(array $data = [])
|
||||
{
|
||||
$params = [
|
||||
'action' => 12,
|
||||
'ts' => round(microtime(true) * 1000),
|
||||
'lang' => 'cn',
|
||||
'parent' => $this->parent,
|
||||
'uid' => $this->player->uuid,
|
||||
'name' => $this->player->name ?: $this->player->uuid
|
||||
];
|
||||
$request = $this->buildParams($params);
|
||||
$res = doFormCurl($this->apiDomain, $request);
|
||||
if ($res['status'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['status']], 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 $res;
|
||||
}
|
||||
|
||||
public function getPlayer()
|
||||
{
|
||||
// TODO: Implement getPlayer() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏摘要MD5 (id+method+sn+APlSecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getSimpleGameList()
|
||||
{
|
||||
$params = [
|
||||
'action' => 49,
|
||||
'ts' => round(microtime(true) * 1000),
|
||||
'parent' => $this->parent,
|
||||
'lang' => 'en',
|
||||
];
|
||||
$request = $this->buildParams($params);
|
||||
$res = doFormCurl($this->apiDomain, $request);
|
||||
if ($res['status'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['status']], 0);
|
||||
}
|
||||
$insertData = [];
|
||||
if (!empty($res['data'])) {
|
||||
foreach ($res['data'] as $data) {
|
||||
foreach($data['list'] as $item){
|
||||
$insertData[] = [
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $item['mType'],
|
||||
'platform_game_type' => $data['gType'],
|
||||
'game_type' => $this->localGameType[$data['gType']],
|
||||
'name' => $item['name'],
|
||||
'game_image' => $item['image'],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($insertData)) {
|
||||
Game::query()->upsert($insertData, ['platform_id', 'game_code']);
|
||||
}
|
||||
return $insertData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏摘要MD5 (id+method+sn+APlSecretKey)
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function login(array $data = []): string
|
||||
{
|
||||
$params = [
|
||||
'action' => 11,
|
||||
'ts' => round(microtime(true) * 1000),
|
||||
'lang' => $this->lang[$data['lang']] ?? 'en',
|
||||
'uid' => $this->loginId,
|
||||
'gType' => $data['platformGameType'],
|
||||
'mType' => $data['gameCode'],
|
||||
'windowMode' => 2,
|
||||
'isAPP' => true,
|
||||
];
|
||||
// if($data['platformGameType'] || $data['gameCode']){
|
||||
// $params['gType'] = $data['platformGameType'];
|
||||
// $params['mType'] = $data['gameCode'];
|
||||
// $params['windowMode'] = 2;
|
||||
// $params['isAPP'] = true;
|
||||
// }
|
||||
$request = $this->buildParams($params);
|
||||
$res = doFormCurl($this->apiDomain, $request);
|
||||
if ($res['status'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['status']], 0);
|
||||
}
|
||||
return $res['path'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转入游戏平台玩家钱包
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
//提现之前把用户踢下线
|
||||
if($this->checkPlay()){
|
||||
$this->userLogout();
|
||||
sleep(1);
|
||||
}
|
||||
$balance = $this->getBalance();
|
||||
if($balance == 0){
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer(PlayerWalletTransfer::TYPE_IN, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, $balance ? -$balance : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 轉帳進出額度
|
||||
* @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)
|
||||
{
|
||||
$params = [
|
||||
'action' => 19,
|
||||
'ts' => round(microtime(true) * 1000),
|
||||
'parent' => $this->parent,
|
||||
'uid' => $this->loginId,
|
||||
'serialNo' => createOrderNo(),
|
||||
'amount' => $amount ?? 0,
|
||||
];
|
||||
$request = $this->buildParams($params);
|
||||
$res = doFormCurl($this->apiDomain, $request);
|
||||
if ($res['status'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['status']], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取玩家餘額信息
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getBalance()
|
||||
{
|
||||
$params = [
|
||||
'action' => 15,
|
||||
'ts' => round(microtime(true) * 1000),
|
||||
'parent' => $this->parent,
|
||||
'uid' => $this->loginId,
|
||||
];
|
||||
|
||||
$request = $this->buildParams($params);
|
||||
$res = doFormCurl($this->apiDomain, $request);
|
||||
if ($res['status'] != $this->successCode) {
|
||||
throw new GameException('JDB System Error,Please contact the administrator', 0);
|
||||
}
|
||||
|
||||
return $res['data'][0]['balance'] ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家状态
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function checkPlay(): bool
|
||||
{
|
||||
$params = [
|
||||
'action' => 52,
|
||||
'ts' => round(microtime(true) * 1000),
|
||||
'parent' => $this->parent,
|
||||
'uid' => $this->loginId,
|
||||
];
|
||||
|
||||
$request = $this->buildParams($params);
|
||||
$res = doFormCurl($this->apiDomain, $request);
|
||||
//游戏中
|
||||
if($res['status'] == $this->successCode){
|
||||
return true;
|
||||
}
|
||||
//不在游戏中
|
||||
if($res['status'] == 7505){
|
||||
return false;
|
||||
}
|
||||
throw new GameException($this->failCode[$res['status']], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家踢下线
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function userLogout(): bool
|
||||
{
|
||||
$params = [
|
||||
'action' => 17,
|
||||
'ts' => round(microtime(true) * 1000),
|
||||
'parent' => $this->parent,
|
||||
'uid' => $this->loginId,
|
||||
];
|
||||
|
||||
$request = $this->buildParams($params);
|
||||
$res = doFormCurl($this->apiDomain, $request);
|
||||
if ($res['status'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['status']], 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得區間內遊戲紀錄
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function handleOrderHistories(): array
|
||||
{
|
||||
$list = [];
|
||||
try {
|
||||
$data = $this->getGameHistories();
|
||||
if (!empty($data)) {
|
||||
foreach ($data as $item) {
|
||||
if ($item['gType'] == 9 && !empty($item['hasGamble'])) {
|
||||
$item['bet'] = $item['gambleBet'];
|
||||
}
|
||||
$list[] = [
|
||||
'uuid' => $item['playerId'],
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $item['mtype'],
|
||||
'bet' => abs($item['bet']),
|
||||
'win' => max($item['win'], 0),
|
||||
'order_no' => $item['historyId'],
|
||||
'game_type' => $item['gType'],
|
||||
'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE),
|
||||
'platform_action_at' => date('Y-m-d H:i:s', strtotime($item['lastModifyTime'])),
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得區間內遊戲紀錄
|
||||
* @return array
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameHistories(): array
|
||||
{
|
||||
$params = [
|
||||
'action' => 29,
|
||||
'ts' => round(microtime(true) * 1000),
|
||||
'parent' => $this->parent,
|
||||
'starttime' => date('d-m-Y H:i:00', strtotime('-5 minutes')),
|
||||
'endtime' => date('d-m-Y H:i:00', strtotime('-4 minutes')),
|
||||
];
|
||||
$request = $this->buildParams($params);
|
||||
$res = doFormCurl($this->apiDomain, $request);
|
||||
if ($res['status'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['status']], 0);
|
||||
}
|
||||
return $res['data'] ?? [];
|
||||
}
|
||||
}
|
||||
529
app/service/game/JiLiServiceInterface.php
Normal file
529
app/service/game/JiLiServiceInterface.php
Normal file
@@ -0,0 +1,529 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
}
|
||||
465
app/service/game/JokerServiceInterface.php
Normal file
465
app/service/game/JokerServiceInterface.php
Normal file
@@ -0,0 +1,465 @@
|
||||
<?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 Exception;
|
||||
use support\Log;
|
||||
use support\Response;
|
||||
|
||||
class JokerServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
private $apiDomain;
|
||||
private $domain;
|
||||
private $appId;
|
||||
private $appSecret;
|
||||
public $loginId;
|
||||
|
||||
public $gameType = [
|
||||
'ECasino' => 'Casino',
|
||||
'Fishing' => 'Fishing',
|
||||
'Bingo' => 'Bingo',
|
||||
'Slot' => 'Slot',
|
||||
];
|
||||
|
||||
public $localGameType = [
|
||||
'ECasino' => '2',
|
||||
'Fishing' => '4',
|
||||
'Bingo' => '8',
|
||||
'Slot' => '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' => '系統錯誤',
|
||||
];
|
||||
|
||||
private $lang = [
|
||||
'zh-CN' => 'zh_ch',
|
||||
'en' => 'en_us',
|
||||
'zh_tc' => 'zh_tc',
|
||||
'th_th' => 'th_th',
|
||||
'Ma_my' => 'Ma_my',
|
||||
'vi_nam' => 'vi_nam',
|
||||
'Fi_fi' => 'Fi_fi',
|
||||
'Kr_ko' => 'Kr_ko',
|
||||
'Hi_hi' => 'Hi_hi',
|
||||
'My_mar' => 'My_mar',
|
||||
'Br_po' => 'Br_po',
|
||||
'cam_dia' => 'cam_dia', // 柬埔寨语
|
||||
];
|
||||
|
||||
/**
|
||||
* @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($signature): string
|
||||
{
|
||||
return $this->apiDomain."?AppID=".$this->appId."&Signature=".$signature;
|
||||
}
|
||||
|
||||
public function createSign($params): string
|
||||
{
|
||||
ksort($params);
|
||||
$signature = urlencode(base64_encode(hash_hmac("sha1", urldecode(http_build_query($params,'', '&')), $this->appSecret, TRUE)));
|
||||
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新游戏列表
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getSimpleGameList()
|
||||
{
|
||||
$params = [
|
||||
'Method' => 'ListGames',
|
||||
'Timestamp' => time(),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$result = doCurl($this->createUrl($signature), $params);
|
||||
if (isset($result['ListGames'])) {
|
||||
foreach ($result['ListGames'] as $game) {
|
||||
Game::query()->updateOrCreate(
|
||||
[
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $game['GameCode'],
|
||||
],
|
||||
[
|
||||
'platform_game_type' => $game['GameType'],
|
||||
'game_type' => $this->localGameType[$game['GameType']],
|
||||
'name' => $game['GameName'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}else{
|
||||
throw new GameException($result['Message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏列表
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGamesList()
|
||||
{
|
||||
$params = [
|
||||
'Method' => 'ListGames',
|
||||
'Timestamp' => time(),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$result = doCurl($this->createUrl($signature), $params);
|
||||
if (isset($result['ListGames'])) {
|
||||
return $result;
|
||||
}else{
|
||||
throw new GameException($result['Message'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏列表
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function playFreeGame()
|
||||
{
|
||||
$params = [
|
||||
'Method' => 'PLAY',
|
||||
'Username' => $this->player->name,
|
||||
'Timestamp' => time(),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$result = doCurl($this->createUrl($signature), $params);
|
||||
if (isset($result['Token'])) {
|
||||
return $forwardUrl = $this->domain."?token=".$result['Token']."&game=1jeqx59c7ztqg&mobile=false";
|
||||
}else{
|
||||
throw new GameException($result['Message'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩游戏
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function playGame()
|
||||
{
|
||||
$params = [
|
||||
'Method' => 'PLAY',
|
||||
'Username' => $this->player->name,
|
||||
'RequestID' => createOrderNo(),
|
||||
'Amount' => $amount,
|
||||
'Timestamp' => time(),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$result = doCurl($this->createUrl($signature), $params);
|
||||
if (isset($result['Token'])) {
|
||||
return $forwardUrl = $this->domain."?token=".$result['Token']."&game=1jeqx59c7ztqg&mobile=false";
|
||||
}else{
|
||||
throw new GameException($result['Message'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getLoginId()
|
||||
{
|
||||
/** @var PlayerGamePlatform $playerGamePlatform */
|
||||
$playerGamePlatform = $this->player->playerGamePlatform->where('platform_id', $this->platform->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 = [
|
||||
'Method' => 'CU',
|
||||
'Username' => $data['uuid'],
|
||||
'Timestamp' => time(),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$res = doCurl($this->createUrl($signature), $params);
|
||||
if (empty($res['Status']) || $res['Status'] != 'OK') {
|
||||
Log::error($res['Message'], ['res' => $res]);
|
||||
throw new GameException($res['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 $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|Exception
|
||||
*/
|
||||
public function getPlayer()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetPlayer',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$data = doCurl($this->createUrl('getPlayer'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家进入游戏
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function login(array $data = []): string
|
||||
{
|
||||
$params = [
|
||||
'Method' => 'PLAY',
|
||||
'Username' => $this->loginId,
|
||||
'RequestID' => createOrderNo(),
|
||||
'Amount' => 0,
|
||||
'Timestamp' => time(),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$res = doCurl($this->createUrl($signature), $params);
|
||||
if (empty($res['Token'])) {
|
||||
Log::error($res['Message'], ['res' => $res]);
|
||||
throw new GameException($res['Message'], 0);
|
||||
}
|
||||
if (!empty($data['gameCode'])) {
|
||||
$link = $this->domain.'?token='.$res['Token'].'&game='.$data['gameCode'].'&mobile=1&lang=en';
|
||||
}else{
|
||||
$link = $this->domain . ($res['data']['loginUrl'] ?? '') . '&' . $parametersValue;
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置用户状态
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function setPlayerStatus($status)
|
||||
{
|
||||
|
||||
$params = [
|
||||
'Method' => 'SS',
|
||||
'Username' => $this->loginId,
|
||||
'Status' => $status,
|
||||
'Timestamp' => time(),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$res = doCurl($this->createUrl($signature), $params);
|
||||
if ($res['Status'] != 'OK') {
|
||||
throw new GameException($this->failCode[$res['Status']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家游戏平台余额
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getBalance()
|
||||
{
|
||||
|
||||
$params = [
|
||||
'Method' => 'GC',
|
||||
'Username' => $this->loginId,
|
||||
'Timestamp' => time(),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$res = doCurl($this->createUrl($signature), $params);
|
||||
|
||||
if (empty($res['Credit']) && !empty($res['Message'])) {
|
||||
throw new GameException($res['Message'], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
|
||||
}
|
||||
|
||||
/**
|
||||
* 游戏平台转入玩家钱包
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
$params = [
|
||||
'Method' => 'WAC',
|
||||
'Username' => $this->loginId,
|
||||
'Timestamp' => time(),
|
||||
'RequestID' => createOrderNo(),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$res = doCurl($this->createUrl($signature), $params);
|
||||
|
||||
if (empty($res['RequestID']) || $res['RequestID'] != $params['RequestID'] || $res['Amount'] == 0) {
|
||||
throw new GameException($res['Message'], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer(PlayerWalletTransfer::TYPE_IN, $res['Amount'], 0, $res['RequestID'] ?? '');
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 轉帳進出額度
|
||||
* 簽名密鑰方式 MD5 (Id+Method+SN+LoginId+APISecretKey)
|
||||
* @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 ($amount == 0 && $reward == 0) {
|
||||
throw new GameException('转出/入金额错误', 0);
|
||||
}
|
||||
|
||||
$params = [
|
||||
'Method' => 'TC',
|
||||
'Username' => $this->loginId,
|
||||
'Timestamp' => time(),
|
||||
'RequestID' => createOrderNo(),
|
||||
'Amount' => $amount,
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$res = doCurl($this->createUrl($signature), $params);
|
||||
|
||||
if (empty($res['RequestID']) || $res['RequestID'] != $params['RequestID']) {
|
||||
// Log::error($res['Message'], ['res' => $res]);
|
||||
throw new GameException($res['Message'], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward, $res['RequestID'] ?? '');
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 依據時間獲取遊戲紀錄
|
||||
* MD5 (Id+Method+SN+StartTime+EndTime+APISecretKey)
|
||||
* @param int $pageIndex
|
||||
* @param string $startTime
|
||||
* @param string $endTime
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameRecordByTime(string $startTime = '', string $endTime = '')
|
||||
{
|
||||
$params = [
|
||||
'Method' => 'TSM',
|
||||
'StartDate' => $startTime,
|
||||
'EndDate' => $endTime,
|
||||
'NextId' => '',
|
||||
'Delay' => 0,
|
||||
'Timestamp' => time(),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$res = doCurl($this->createUrl($signature), $params);
|
||||
|
||||
// if (empty($res['data'])) {
|
||||
// throw new GameException($res['Message'], 0);
|
||||
// }
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
389
app/service/game/Kiss918ServiceInterface.php
Normal file
389
app/service/game/Kiss918ServiceInterface.php
Normal file
@@ -0,0 +1,389 @@
|
||||
<?php
|
||||
|
||||
namespace app\service\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 Exception;
|
||||
use support\Response;
|
||||
|
||||
class Kiss918ServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
private $apiDomain;
|
||||
private $domain;
|
||||
private $auth;
|
||||
private $appSecret;
|
||||
public $loginId;
|
||||
public $password;
|
||||
|
||||
public $gameType = [
|
||||
'2' => 'Casino',
|
||||
'5' => 'Fishing',
|
||||
'8' => 'Bingo',
|
||||
'1' => 'Slot',
|
||||
];
|
||||
|
||||
public $localGameType = [
|
||||
'2' => '2',//赌场
|
||||
'5' => '4',//捕鱼
|
||||
'8' => '2',//宾果
|
||||
'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' => '系統錯誤',
|
||||
];
|
||||
private $admin_user;
|
||||
|
||||
/**
|
||||
* @param Player|null $player
|
||||
* @param $type
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct($type, Player $player = null)
|
||||
{
|
||||
$config = config('game_platform.' . $type);
|
||||
$this->auth = $config['auth'];
|
||||
$this->admin_user = $config['admin_user'];
|
||||
$this->apiDomain = $config['api_domain'];
|
||||
$this->recordApi = $config['record_api'];
|
||||
$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();
|
||||
}
|
||||
}
|
||||
|
||||
public function createSign($params): string
|
||||
{
|
||||
$str = implode('', $params);
|
||||
return strtoupper(md5(strtolower($str)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新游戏列表
|
||||
* @return false
|
||||
*/
|
||||
public function getSimpleGameList(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家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)) {
|
||||
$this->password = $playerGamePlatform->player_password;
|
||||
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 = [])
|
||||
{
|
||||
$time = round(microtime(true)*1000);
|
||||
$randomParams = [
|
||||
'action' => 'RandomUserName',
|
||||
'userName' => $this->admin_user,
|
||||
'time' => $time,
|
||||
'authcode' => $this->auth,
|
||||
];
|
||||
$signature = $this->createSign([$this->auth, $randomParams['userName'], $time ,$this->appSecret]);
|
||||
$randomParams['sign'] = $signature;
|
||||
$randomUser = dogGetCurl($this->apiDomain.'ashx/account/account.ashx', $randomParams);;
|
||||
if(!$randomUser['success'] || empty($randomUser['account'])){
|
||||
throw new GameException($randomUser['msg'], 0);
|
||||
}
|
||||
$password = uniqid();
|
||||
$params = [
|
||||
'action' => 'addUser',
|
||||
'agent' => $this->admin_user,
|
||||
'PassWd' => $password,
|
||||
'pwdtype' => 1,
|
||||
'userName' => $randomUser['account'],
|
||||
'Name' => $data['name'],
|
||||
'Tel' => $this->player->phone ?? '',
|
||||
'Memo' => $data['name'],
|
||||
'UserType' => 1,
|
||||
'time' => $time,
|
||||
'authcode' => $this->auth,
|
||||
];
|
||||
$signature = $this->createSign([$this->auth, $params['userName'], $time ,$this->appSecret]);
|
||||
$params['sign'] = $signature;
|
||||
$result = dogGetCurl($this->apiDomain.'ashx/account/account.ashx', $params);;
|
||||
if ($result['code'] == 0 && $result['success']) {
|
||||
$playerGamePlatform = new PlayerGamePlatform();
|
||||
$playerGamePlatform->player_id = $this->player->id;
|
||||
$playerGamePlatform->platform_id = $this->platform->id;
|
||||
$playerGamePlatform->player_name = $data['name'];
|
||||
$playerGamePlatform->player_code = $randomUser['account'];
|
||||
$playerGamePlatform->player_password = $password;
|
||||
$playerGamePlatform->save();
|
||||
$this->loginId = $playerGamePlatform->player_code;
|
||||
$this->password = $playerGamePlatform->player_password;
|
||||
return $result;
|
||||
}else{
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家
|
||||
* @return array|mixed|Response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getPlayer()
|
||||
{
|
||||
$time = round(microtime(true)*1000);
|
||||
$params = [
|
||||
'action' => 'getUserInfo',
|
||||
'userName' => $this->loginId,
|
||||
'time' => $time,
|
||||
'authcode' => $this->auth,
|
||||
];
|
||||
$signature = $this->createSign([$this->auth, $this->loginId, $time ,$this->appSecret]);
|
||||
$params['sign'] = $signature;
|
||||
$result = dogGetCurl($this->apiDomain.'ashx/account/account.ashx', $params);
|
||||
if($result['success']){
|
||||
return $result;
|
||||
}else{
|
||||
throw new GameException('Kiss 918 System Error,Please contact the administrator', 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家进入游戏
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function login(array $data = []): array
|
||||
{
|
||||
return ['url' => 'https://yop1.918kiss.com/', 'account' => $this->loginId, 'password' => $this->password];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家游戏平台余额
|
||||
* @return string|null
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getBalance(): string
|
||||
{
|
||||
$playerInfo = $this->getPlayer();
|
||||
return $playerInfo['MoneyNum'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
if($this->player->wallet->money <= 0){
|
||||
return true;
|
||||
}
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
|
||||
}
|
||||
|
||||
/**
|
||||
* 游戏平台转入玩家钱包
|
||||
* @return array|mixed|null
|
||||
* @throws Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
$balance = $this->getBalance();
|
||||
if($balance == 0){
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer(PlayerWalletTransfer::TYPE_IN, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, -$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)
|
||||
{
|
||||
$time = round(microtime(true)*1000);
|
||||
$params = [
|
||||
'action' => 'setServerScore',
|
||||
'orderid' => date('YmdHis').uniqid(),
|
||||
'scoreNum' => $amount,
|
||||
'userName' => $this->loginId,
|
||||
'ActionUser' => $this->loginId,
|
||||
'ActionIp' => request()->getRealIp(),
|
||||
'time' => $time,
|
||||
'authcode' => $this->auth,
|
||||
];
|
||||
$signature = $this->createSign([$this->auth, $this->loginId, $time ,$this->appSecret]);
|
||||
$params['sign'] = $signature;
|
||||
$result = dogGetCurl($this->apiDomain.'ashx/account/setScore.ashx', $params);
|
||||
if($result['code'] != 0 || !$result['success']){
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward, $params['orderid']);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询游戏纪录
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameRecordList(string $startTime = '', string $endTime = '', $uuid, int $page = 1, int $pageSize = 1000)
|
||||
{
|
||||
$time = round(microtime(true)*1000);
|
||||
$params = [
|
||||
'pageIndex' => $page,
|
||||
'pageSize' => $pageSize,
|
||||
'userName' => $this->loginId,
|
||||
'sDate' => $startTime,
|
||||
'eDate' => $endTime,
|
||||
'time' => $time,
|
||||
'authcode' => $this->auth,
|
||||
];
|
||||
$signature = $this->createSign([$this->auth, $this->loginId, $time ,$this->appSecret]);
|
||||
$params['sign'] = $signature;
|
||||
$result = dogGetCurl($this->apiDomain, $params);
|
||||
if($result['code'] == 0 || !$result['success']){
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询全部玩家账单
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getReportRecord(string $startTime = '', string $endTime = '')
|
||||
{
|
||||
$time = round(microtime(true)*1000);
|
||||
$params = [
|
||||
'userName' => $this->admin_user,
|
||||
'sDate' => $startTime,
|
||||
'eDate' => $endTime,
|
||||
'Type' => 'ServerTotalReport',
|
||||
'time' => $time,
|
||||
'authcode' => $this->auth,
|
||||
];
|
||||
$signature = $this->createSign([$this->auth, $this->admin_user, $time ,$this->appSecret]);
|
||||
$params['sign'] = $signature;
|
||||
$result = dogGetCurl($this->recordApi.'ashx/AgentTotalReport.ashx', $params);
|
||||
if(!$result['success'] && !empty($result['results'])){
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
return $result['results'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单个玩家单日输赢
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getAccountReport(string $startTime = '', string $endTime = '', $playerCode)
|
||||
{
|
||||
$time = round(microtime(true)*1000);
|
||||
$params = [
|
||||
'userName' => $playerCode,
|
||||
'sDate' => $startTime,
|
||||
'eDate' => $endTime,
|
||||
'time' => $time,
|
||||
'authcode' => $this->auth,
|
||||
];
|
||||
$signature = $this->createSign([$this->auth, $playerCode, $time ,$this->appSecret]);
|
||||
$params['sign'] = $signature;
|
||||
$result = dogGetCurl($this->apiDomain.'ashx/AccountReport.ashx', $params);
|
||||
if($result['code'] == 0 || !$result['success']){
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家游戏记录
|
||||
* @return array
|
||||
*/
|
||||
public function handleOrderHistories(): array
|
||||
{
|
||||
try {
|
||||
$list = [];
|
||||
$startTime = date('Y-m-d');
|
||||
$endTime = date('Y-m-d');
|
||||
$data = $this->getReportRecord($startTime, $endTime);
|
||||
if (!empty($data)) {
|
||||
foreach ($data as $item) {
|
||||
$list[] = [
|
||||
'player_code' => $item['Account'],
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => 'Kiss918',
|
||||
'bet' => $item['press'],
|
||||
'win' => $item['win'],
|
||||
'order_no' => $item['idx'].date('Ymd'),
|
||||
'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE),
|
||||
'platform_action_at' => $startTime,
|
||||
'game_type' => 1,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return [];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
}
|
||||
435
app/service/game/LionKingServiceInterface.php
Normal file
435
app/service/game/LionKingServiceInterface.php
Normal file
@@ -0,0 +1,435 @@
|
||||
<?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 Exception;
|
||||
use support\Log;
|
||||
use support\Response;
|
||||
|
||||
class LionKingServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
private $apiDomain;
|
||||
private $domain;
|
||||
private $appId;
|
||||
private $appSecret;
|
||||
private $path = [
|
||||
'createPlayer' => '/UserInfo/CreatePlayer',
|
||||
'getPlayer' => '/UserInfo/GetPlayer',
|
||||
'getGameList' => '/Game/GetGameList',
|
||||
'getSimpleGameList' => '/Game/GetSimpleGameList',
|
||||
'getLoginH5' => '/UserInfo/GetLoginH5',
|
||||
'setPlayerStatus' => '/UserInfo/SetPlayerStatus',
|
||||
'getBalance' => '/Account/GetBalance',
|
||||
'setBalanceTransfer' => '/Account/SetBalanceTransfer',
|
||||
'getGameRecordByTime' => '/Game/GetGameRecordByTime',
|
||||
'getGameRecord' => '/Game/GetGameRecord',
|
||||
'removeRecords' => '/Game/RemoveRecords',
|
||||
];
|
||||
|
||||
public $successCode = 'S100';
|
||||
|
||||
public $loginId;
|
||||
|
||||
public $gameType = [
|
||||
'10' => 'Slot',
|
||||
'12' => 'Casino',
|
||||
'13' => 'Arcade',
|
||||
'16' => 'Fishing'
|
||||
];
|
||||
|
||||
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' => '系統錯誤',
|
||||
];
|
||||
|
||||
private $lang = [
|
||||
'zh-CN' => 'zh_ch',
|
||||
'en' => 'en_us',
|
||||
'zh_tc' => 'zh_tc',
|
||||
'th_th' => 'th_th',
|
||||
'Ma_my' => 'Ma_my',
|
||||
'vi_nam' => 'vi_nam',
|
||||
'Fi_fi' => 'Fi_fi',
|
||||
'Kr_ko' => 'Kr_ko',
|
||||
'Hi_hi' => 'Hi_hi',
|
||||
'My_mar' => 'My_mar',
|
||||
'Br_po' => 'Br_po',
|
||||
'cam_dia' => 'cam_dia', // 柬埔寨语
|
||||
];
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getLoginId()
|
||||
{
|
||||
/** @var PlayerGamePlatform $playerGamePlatform */
|
||||
$playerGamePlatform = $this->player->playerGamePlatform->where('platform_id', $this->platform->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 = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'CreatePlayer',
|
||||
'SN' => $this->appId,
|
||||
'PlayerCode' => $data['uuid'],
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['PlayerName'] = $data['uuid'];
|
||||
$res = doCurl($this->createUrl('createPlayer'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 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 $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建玩家
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|Exception
|
||||
*/
|
||||
public function getPlayer()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetPlayer',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$data = doCurl($this->createUrl('getPlayer'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏摘要MD5 (id+method+sn+APlSecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getSimpleGameList()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetSimpleGameList',
|
||||
'SN' => $this->appId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$data = doCurl($this->createUrl('getSimpleGameList'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
if (!empty($data['data']['games'])) {
|
||||
foreach ($data['data']['games'] as $game) {
|
||||
Game::query()->updateOrCreate(
|
||||
[
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $game['gameCode'],
|
||||
],
|
||||
[
|
||||
'platform_game_type' => $game['type'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏摘要MD5 (id+method+sn+APlSecretKey)
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function login(array $data = []): string
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetLoginH5',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$res = doCurl($this->createUrl('getLoginH5'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
Log::error($this->failCode[$res['code']], ['res' => $res]);
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
$responseH5 = [
|
||||
'Language' => $this->lang[$data['lang']] ?? 'ch',
|
||||
"GameId" => $data['gameCode'],
|
||||
'CallbackAddress' => $data['callBackUrl'] ?? '',
|
||||
"AppType" => $data['appType'] ?? 1,
|
||||
"DeviceType" => 1,
|
||||
];
|
||||
$jsonString = json_encode($responseH5);
|
||||
$parametersValue = base64_encode($jsonString);
|
||||
$link = $this->domain . '/linkgame' . ($res['data']['loginUrl'] ?? '') . '&' . $parametersValue;
|
||||
if (!empty($data['gameCode'])) {
|
||||
$link .= '&' . $data['gameCode'];
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* 設置登入玩家狀態。當玩家處於禁用狀態,該玩家無法在平台進行任何操作,如果玩家在遊戲進行中該玩家將會自動退出遊戲。
|
||||
* 簽名密鑰方式 Md5(Id+Method+SN+LoginId+APISecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function setPlayerStatus($status)
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetSimpleGameList',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['Status'] = $status;
|
||||
$data = doCurl($this->createUrl('setPlayerStatus'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取玩家餘額信息
|
||||
* 簽名密鑰方式 MD5 (Id+Method+SN+LoginId+APISecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getBalance()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetBalance',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$data = doCurl($this->createUrl('getBalance'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
$balance = $this->getBalance();
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, !empty($balance['data']['result']) ? -$balance['data']['result'] : 0, !empty($balance['data']['reward']) ? -$balance['data']['reward'] : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 轉帳進出額度
|
||||
* 簽名密鑰方式 MD5 (Id+Method+SN+LoginId+APISecretKey)
|
||||
* @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 ($amount == 0 && $reward == 0) {
|
||||
throw new GameException('转出/入金额错误', 0);
|
||||
}
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'SetBalanceTransfer',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['Amount'] = $amount;
|
||||
$params['Reward'] = $reward;
|
||||
$res = doCurl($this->createUrl('setBalanceTransfer'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward, $res['data']['refId'] ?? '');
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 依據時間獲取遊戲紀錄
|
||||
* MD5 (Id+Method+SN+StartTime+EndTime+APISecretKey)
|
||||
* @param int $pageIndex
|
||||
* @param string $startTime
|
||||
* @param string $endTime
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameRecordByTime(int $pageIndex = 1, string $startTime = '', string $endTime = '')
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetGameRecordByTime',
|
||||
'SN' => $this->appId,
|
||||
'StartTime' => $startTime,
|
||||
'EndTime' => $endTime,
|
||||
];
|
||||
$pageSize = 500;
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['PageSize'] = $pageSize;
|
||||
$params['PageIndex'] = $pageIndex;
|
||||
$res = doCurl($this->createUrl('getGameRecordByTime'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取玩家遊戲歷史紀錄
|
||||
* MD5 (Id+Method+SN+APISecretKey)
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameRecord()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetGameRecord',
|
||||
'SN' => $this->appId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$res = doCurl($this->createUrl('getGameRecord'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刪除遊戲紀錄
|
||||
* MD5 (Id+Method+SN+IdsToBeRemoved+APISecretKey)
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function removeRecords($idsToBeRemoved)
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'RemoveRecords',
|
||||
'SN' => $this->appId,
|
||||
'IdsToBeRemoved' => implode(',', $idsToBeRemoved),
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$res = doCurl($this->createUrl('removeRecords'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function createSign($params): string
|
||||
{
|
||||
return md5(implode('', $params) . $this->appSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求url
|
||||
* @param $method
|
||||
* @return string
|
||||
*/
|
||||
public function createUrl($method): string
|
||||
{
|
||||
return $this->apiDomain . $this->path[$method];
|
||||
}
|
||||
}
|
||||
444
app/service/game/Lucky365ServiceInterface.php
Normal file
444
app/service/game/Lucky365ServiceInterface.php
Normal file
@@ -0,0 +1,444 @@
|
||||
<?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 Exception;
|
||||
use support\Log;
|
||||
use support\Response;
|
||||
|
||||
class Lucky365ServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
private $apiDomain;
|
||||
private $domain;
|
||||
private $appId;
|
||||
private $appSecret;
|
||||
private $path = [
|
||||
'createPlayer' => '/UserInfo/CreatePlayer',
|
||||
'getPlayer' => '/UserInfo/GetPlayer',
|
||||
'getGameList' => '/Game/GetGameList',
|
||||
'getSimpleGameList' => '/Game/GetSimpleGameList',
|
||||
'getLoginH5' => '/UserInfo/GetLoginH5',
|
||||
'setPlayerStatus' => '/UserInfo/SetPlayerStatus',
|
||||
'getBalance' => '/Account/GetBalance',
|
||||
'setBalanceTransfer' => '/Account/SetBalanceTransfer',
|
||||
'getGameRecordByTime' => '/Game/GetGameRecordByTime',
|
||||
'getGameRecord' => '/Game/GetGameRecord',
|
||||
'removeRecords' => '/Game/RemoveRecords',
|
||||
];
|
||||
|
||||
public $successCode = 'S100';
|
||||
|
||||
public $loginId;
|
||||
|
||||
public $gameType = [
|
||||
'10' => 'Slot',
|
||||
'12' => 'Casino',
|
||||
'13' => 'Arcade',
|
||||
'16' => 'Fishing'
|
||||
];
|
||||
|
||||
public $localGameType = [
|
||||
'10' => '1',
|
||||
'12' => '2',
|
||||
'13' => '3',
|
||||
'16' => '4',
|
||||
];
|
||||
|
||||
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' => '系統錯誤',
|
||||
];
|
||||
|
||||
private $lang = [
|
||||
'zh-CN' => 'zh_ch',
|
||||
'en' => 'en_us',
|
||||
'zh_tc' => 'zh_tc',
|
||||
'th_th' => 'th_th',
|
||||
'Ma_my' => 'Ma_my',
|
||||
'vi_nam' => 'vi_nam',
|
||||
'Fi_fi' => 'Fi_fi',
|
||||
'Kr_ko' => 'Kr_ko',
|
||||
'Hi_hi' => 'Hi_hi',
|
||||
'My_mar' => 'My_mar',
|
||||
'Br_po' => 'Br_po',
|
||||
'cam_dia' => 'cam_dia', // 柬埔寨语
|
||||
];
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'CreatePlayer',
|
||||
'SN' => $this->appId,
|
||||
'PlayerCode' => $data['uuid'],
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['PlayerName'] = $data['uuid'];
|
||||
$res = doCurl($this->createUrl('createPlayer'), $params);
|
||||
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 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 $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建玩家
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|Exception
|
||||
*/
|
||||
public function getPlayer()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetPlayer',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$data = doCurl($this->createUrl('getPlayer'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏摘要MD5 (id+method+sn+APlSecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getSimpleGameList()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetSimpleGameList',
|
||||
'SN' => $this->appId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$data = doCurl($this->createUrl('getSimpleGameList'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
if (!empty($data['data']['games'])) {
|
||||
foreach ($data['data']['games'] as $game) {
|
||||
Game::query()->updateOrCreate(
|
||||
[
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $game['gameCode'],
|
||||
],
|
||||
[
|
||||
'platform_game_type' => $game['type'],
|
||||
'game_type' => $this->localGameType[$game['type']],
|
||||
'name' => $game['gameName'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏摘要MD5 (id+method+sn+APlSecretKey)
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function login(array $data = []): string
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetLoginH5',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$res = doCurl($this->createUrl('getLoginH5'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
Log::error($this->failCode[$res['code']], ['res' => $res]);
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
$responseH5 = [
|
||||
'Language' => $this->lang[$data['lang']] ?? 'ch',
|
||||
"GameId" => $data['gameCode'],
|
||||
'CallbackAddress' => $data['callBackUrl'] ?? '',
|
||||
"AppType" => $data['appType'] ?? 1,
|
||||
"DeviceType" => 1,
|
||||
];
|
||||
$jsonString = json_encode($responseH5);
|
||||
$parametersValue = base64_encode($jsonString);
|
||||
|
||||
if (!empty($data['gameCode'])) {
|
||||
$link = $this->domain .'/linkgame'. ($res['data']['loginUrl'] ?? '') . '&' . $parametersValue . '&' . $data['gameCode'];
|
||||
}else{
|
||||
$link = $this->domain . ($res['data']['loginUrl'] ?? '') . '&' . $parametersValue;
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* 設置登入玩家狀態。當玩家處於禁用狀態,該玩家無法在平台進行任何操作,如果玩家在遊戲進行中該玩家將會自動退出遊戲。
|
||||
* 簽名密鑰方式 Md5(Id+Method+SN+LoginId+APISecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function setPlayerStatus($status)
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetSimpleGameList',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['Status'] = $status;
|
||||
$data = doCurl($this->createUrl('setPlayerStatus'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取玩家餘額信息
|
||||
* 簽名密鑰方式 MD5 (Id+Method+SN+LoginId+APISecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getBalance()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetBalance',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$data = doCurl($this->createUrl('getBalance'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException('Lucky365 System Error,Please contact the administrator', 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
$balance = $this->getBalance();
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, !empty($balance['data']['result']) ? -$balance['data']['result'] : 0, !empty($balance['data']['reward']) ? -$balance['data']['reward'] : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 轉帳進出額度
|
||||
* 簽名密鑰方式 MD5 (Id+Method+SN+LoginId+APISecretKey)
|
||||
* @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)
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'SetBalanceTransfer',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['Amount'] = $amount;
|
||||
$params['Reward'] = $reward;
|
||||
$res = doCurl($this->createUrl('setBalanceTransfer'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward, $res['data']['refId'] ?? '');
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 依據時間獲取遊戲紀錄
|
||||
* MD5 (Id+Method+SN+StartTime+EndTime+APISecretKey)
|
||||
* @param int $pageIndex
|
||||
* @param string $startTime
|
||||
* @param string $endTime
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameRecordByTime(int $pageIndex = 1, string $startTime = '', string $endTime = '')
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetGameRecordByTime',
|
||||
'SN' => $this->appId,
|
||||
'StartTime' => $startTime,
|
||||
'EndTime' => $endTime,
|
||||
];
|
||||
$pageSize = 500;
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['PageSize'] = $pageSize;
|
||||
$params['PageIndex'] = $pageIndex;
|
||||
$res = doCurl($this->createUrl('getGameRecordByTime'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取玩家遊戲歷史紀錄
|
||||
* MD5 (Id+Method+SN+APISecretKey)
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameRecord()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetGameRecord',
|
||||
'SN' => $this->appId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$res = doCurl($this->createUrl('getGameRecord'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刪除遊戲紀錄
|
||||
* MD5 (Id+Method+SN+IdsToBeRemoved+APISecretKey)
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function removeRecords($idsToBeRemoved)
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'RemoveRecords',
|
||||
'SN' => $this->appId,
|
||||
'IdsToBeRemoved' => implode(',', $idsToBeRemoved),
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$res = doCurl($this->createUrl('removeRecords'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function createSign($params): string
|
||||
{
|
||||
return md5(implode('', $params) . $this->appSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求url
|
||||
* @param $method
|
||||
* @return string
|
||||
*/
|
||||
public function createUrl($method): string
|
||||
{
|
||||
return $this->apiDomain . $this->path[$method];
|
||||
}
|
||||
}
|
||||
411
app/service/game/MarioClubServiceInterface.php
Normal file
411
app/service/game/MarioClubServiceInterface.php
Normal file
@@ -0,0 +1,411 @@
|
||||
<?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 MarioClubServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
private $apiDomain;
|
||||
private $appId;
|
||||
private $appSecret;
|
||||
public $loginId;
|
||||
|
||||
public $gameType = [
|
||||
'2' => 'Casino',
|
||||
'5' => 'Fishing',
|
||||
'8' => 'Bingo',
|
||||
'1' => 'Slot',
|
||||
];
|
||||
|
||||
public $localGameType = [
|
||||
'FISHING' => '4',//捕鱼
|
||||
'SLOT' => '1',//斯洛
|
||||
'1' => '1',
|
||||
'4' => '4',
|
||||
];
|
||||
|
||||
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->appSecret = $config['app_secret'];
|
||||
$this->platform = GamePlatform::query()->where('name', $type)->first();
|
||||
if (!empty($player)) {
|
||||
$this->player = $player;
|
||||
$this->getLoginId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名
|
||||
* @param $time
|
||||
* @return string
|
||||
*/
|
||||
public function createSign($time): string
|
||||
{
|
||||
return md5($this->appId.$time.$this->appSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新游戏列表
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getSimpleGameList()
|
||||
{
|
||||
$time = time();
|
||||
$params = [
|
||||
'api_id' => $this->appId,
|
||||
'timestamp' => $time,
|
||||
];
|
||||
$params['sign'] = $this->createSign($time);
|
||||
$result = doFormCurl($this->apiDomain.'/getGames',$params);
|
||||
if ($result['code'] == 0 && !empty($result['gameList'])) {
|
||||
foreach ($result['gameList'] as $game) {
|
||||
Game::query()->updateOrCreate(
|
||||
[
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $game['gameCode'],
|
||||
],
|
||||
[
|
||||
'platform_game_type' => $game['gameType'],
|
||||
'game_type' => $this->localGameType[$game['gameType']] ?? '',
|
||||
'name' => $game['gameName'],
|
||||
'game_image' => $game['gameIconUrl']
|
||||
]
|
||||
);
|
||||
}
|
||||
}else{
|
||||
throw new GameException($result['Message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏列表
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGamesList()
|
||||
{
|
||||
$time = time();
|
||||
$params = [
|
||||
'api_id' => $this->appId,
|
||||
'timestamp' => $time,
|
||||
];
|
||||
$params['sign'] = $this->createSign($time);
|
||||
$result = doFormCurl($this->apiDomain.'/getGames',$params);
|
||||
if ($result['code'] == 0 && !empty($result['gameList'])) {
|
||||
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 = [])
|
||||
{
|
||||
$time = time();
|
||||
$params = [
|
||||
'api_id' => $this->appId,
|
||||
'timestamp' => $time,
|
||||
'user_id' => $data['uuid'],
|
||||
];
|
||||
$params['sign'] = $this->createSign($time);
|
||||
$result = doFormCurl($this->apiDomain.'/api/acc/created',$params);
|
||||
|
||||
if ($result['code'] != 0) {
|
||||
Log::error($result['msg'], ['res' => $result]);
|
||||
throw new GameException($result['msg'], 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()
|
||||
{
|
||||
$time = time();
|
||||
$params = [
|
||||
'api_id' => $this->appId,
|
||||
'timestamp' => $time,
|
||||
'user_id' => $this->loginId,
|
||||
'language' => 'en',
|
||||
];
|
||||
$params['sign'] = $this->createSign($time);
|
||||
$result = doFormCurl($this->apiDomain.'/api/acc/gameLogIn',$params);
|
||||
if ($result['code'] != 0) {
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家进入游戏
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function login(array $data = []): string
|
||||
{
|
||||
$time = time();
|
||||
$params = [
|
||||
'api_id' => $this->appId,
|
||||
'timestamp' => $time,
|
||||
'user_id' => $this->loginId,
|
||||
'game_code' => $data['gameCode'],
|
||||
'language' => 'en',
|
||||
];
|
||||
$params['sign'] = $this->createSign($time);
|
||||
$result = doFormCurl($this->apiDomain.'/api/acc/gameLogIn',$params);
|
||||
if ($result['code'] == 0 && !empty($result['gameUrl'])) {
|
||||
$link = $result['gameUrl'];
|
||||
}else{
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家游戏平台余额
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getBalance()
|
||||
{
|
||||
$time = time();
|
||||
$params = [
|
||||
'api_id' => $this->appId,
|
||||
'timestamp' => $time,
|
||||
'user_id' => $this->loginId,
|
||||
];
|
||||
$params['sign'] = $this->createSign($time);
|
||||
$result = doFormCurl($this->apiDomain.'/api/acc/getBalance',$params);
|
||||
if ($result['code'] != 0) {
|
||||
throw new GameException('MarioClub System Error,Please contact the administrator', 0);
|
||||
}
|
||||
return $result['balance'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
|
||||
}
|
||||
|
||||
/**
|
||||
* 游戏平台转入玩家钱包
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
$balance = $this->getBalance();
|
||||
if($balance == 0){
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer(PlayerWalletTransfer::TYPE_IN, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, $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 == 1) {
|
||||
$action = 'deposit';
|
||||
} else {
|
||||
$action = 'withdraw';
|
||||
}
|
||||
$time = time();
|
||||
$params = [
|
||||
'api_id' => $this->appId,
|
||||
'timestamp' => $time,
|
||||
'user_id' => $this->loginId,
|
||||
'amount' => $amount,
|
||||
'action' => $action,
|
||||
];
|
||||
$params['sign'] = $this->createSign($time);
|
||||
$result = doFormCurl($this->apiDomain.'/api/acc/updateBalance',$params);
|
||||
if ($result['code'] != 0) {
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward, $result['transId'] ?? '');
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询额度转移纪录
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getTransferList(string $startTime = '', string $endTime = '', int $page = 1, int $pageSize = 10)
|
||||
{
|
||||
$time = time();
|
||||
$params = [
|
||||
'api_id' => $this->appId,
|
||||
'timestamp' => $time,
|
||||
'user_id' => $this->loginId,
|
||||
'date_from' => date('d/m/Y', strtotime($startTime)),
|
||||
'date_to' => date('d/m/Y', strtotime($endTime)),
|
||||
];
|
||||
$params['sign'] = $this->createSign($time);
|
||||
$result = doFormCurl($this->apiDomain.'/api/acc/getTransactionLog',$params);
|
||||
if ($result['code'] != 0) {
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
return $result['walletLogDTO'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询游戏纪录
|
||||
* @param string $startTime
|
||||
* @param string $endTime
|
||||
* @return array
|
||||
* @throws GameException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function getGameRecordList(string $startTime = '', string $endTime = ''): array
|
||||
{
|
||||
$time = time();
|
||||
$params = [
|
||||
'api_id' => $this->appId,
|
||||
'timestamp' => $time,
|
||||
'date_from' => $startTime,
|
||||
'date_to' => $endTime,
|
||||
];
|
||||
$params['sign'] = $this->createSign($time);
|
||||
$result = doFormCurl($this->apiDomain.'/api/acc/getGameLog',$params);
|
||||
if ($result['code'] != 0) {
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
return $result['userGameLogDTO'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家游戏记录
|
||||
* @return array
|
||||
*/
|
||||
public function handleOrderHistories(): array
|
||||
{
|
||||
try {
|
||||
$list = [];
|
||||
$startTime = date('d/m/Y H:i:s', strtotime('-3 minutes'));
|
||||
$endTime = date('d/m/Y H:i:s', strtotime('-2 minutes'));
|
||||
$data = $this->getGameRecordList($startTime, $endTime);
|
||||
if (!empty($data)) {
|
||||
foreach ($data as $item) {
|
||||
$list[] = [
|
||||
'uuid' => $item['loginId'],
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $item['gameCode'],
|
||||
'bet' => $item['betAmount'],
|
||||
'win' => bcadd($item['betAmount'], $item['winAmount'], 2),
|
||||
'order_no' => $item['logId'],
|
||||
'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE),
|
||||
'platform_action_at' => date('Y-m-d H:i:s', $item['createdDate']/1000),
|
||||
'game_type' => $item['gameTypeId'],
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
}
|
||||
472
app/service/game/MeGa888ServiceInterface.php
Normal file
472
app/service/game/MeGa888ServiceInterface.php
Normal file
@@ -0,0 +1,472 @@
|
||||
<?php
|
||||
|
||||
namespace app\service\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 Exception;
|
||||
use support\Response;
|
||||
|
||||
class MeGa888ServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
private $apiDomain;
|
||||
private $appId;
|
||||
public $appSecret;
|
||||
private $sn;
|
||||
public $loginId;
|
||||
public $password;
|
||||
|
||||
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->appSecret = $config['app_secret'];
|
||||
$this->sn = $config['sn'];
|
||||
$this->platform = GamePlatform::query()->where('name', $type)->first();
|
||||
if (!empty($player)) {
|
||||
$this->player = $player;
|
||||
$this->getLoginId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求url
|
||||
* @return string
|
||||
*/
|
||||
public function createUrl(): string
|
||||
{
|
||||
return $this->apiDomain;
|
||||
}
|
||||
|
||||
//生成签名
|
||||
public function createSign($params): string
|
||||
{
|
||||
$str = '';
|
||||
foreach ($params as $v) {
|
||||
$str .= $v;
|
||||
}
|
||||
return md5($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求数据
|
||||
* @param $postData
|
||||
* @param $method
|
||||
* @return array
|
||||
*/
|
||||
function buildParams($postData, $method): array
|
||||
{
|
||||
return array(
|
||||
"jsonrpc" => "2.0",
|
||||
"method" => $method,
|
||||
"params" => $postData,
|
||||
"id" => $this->player->uuid ?? uniqid()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载地址
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getDownload()
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'secretCode' => $this->appSecret,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$params['agentLoginId'] = $this->appId;
|
||||
$postData = $this->buildParams($params, 'open.mega.app.url.download');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if(!empty($result['result'])){
|
||||
return $result['result'];
|
||||
}else{
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新游戏列表
|
||||
* @return false
|
||||
*/
|
||||
public function getSimpleGameList(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家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)) {
|
||||
$this->password = $playerGamePlatform->player_password;
|
||||
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 = [
|
||||
'random' => $data['uuid'] ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'secretCode' => $this->appSecret,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$params['agentLoginId'] = $this->appId;
|
||||
$params['nickname'] = $data['name'];
|
||||
$postData = $this->buildParams($params, 'open.mega.user.create');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['result']) && empty($result['error'])) {
|
||||
$playerGamePlatform = new PlayerGamePlatform();
|
||||
$playerGamePlatform->player_id = $this->player->id;
|
||||
$playerGamePlatform->platform_id = $this->platform->id;
|
||||
$playerGamePlatform->player_name = $data['name'];
|
||||
$playerGamePlatform->player_code = $result['result']['loginId'];
|
||||
$playerGamePlatform->player_password = uniqid();
|
||||
$playerGamePlatform->save();
|
||||
$this->loginId = $playerGamePlatform->player_code;
|
||||
$this->password = $playerGamePlatform->player_password;
|
||||
return $result;
|
||||
}else{
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家信息
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|Exception
|
||||
*/
|
||||
public function getPlayer()
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => $this->loginId,
|
||||
'secretCode' => $this->appSecret,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$postData = $this->buildParams($params, 'open.mega.user.get');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['result']) && empty($result['error'])) {
|
||||
return $result;
|
||||
}else{
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家进入游戏
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws GameException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function login(array $data = []): array
|
||||
{
|
||||
return ['url' => $this->getDownload(), 'account' => $this->loginId, 'password' => $this->password];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家游戏平台余额
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getBalance()
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => $this->loginId,
|
||||
'secretCode' => $this->appSecret,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$postData = $this->buildParams($params, 'open.mega.balance.get');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (empty($result['error'])) {
|
||||
return $result['result'];
|
||||
}else{
|
||||
throw new GameException('MeGa888 System Error,Please contact the administrator', 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
|
||||
}
|
||||
|
||||
/**
|
||||
* 游戏平台转入玩家钱包
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
if($this->getBalance() == 0){
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer(PlayerWalletTransfer::TYPE_IN, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return $this->autoTransfer();
|
||||
}
|
||||
|
||||
/**
|
||||
* 轉帳進出額度
|
||||
* @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)
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => $this->loginId,
|
||||
'amount' => $amount,
|
||||
'secretCode' => $this->appSecret,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$postData = $this->buildParams($params, 'open.mega.balance.transfer');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动下分
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function autoTransfer()
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => $this->loginId,
|
||||
'secretCode' => $this->appSecret,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$postData = $this->buildParams($params, 'open.mega.balance.auto.transfer.out');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer(PlayerWalletTransfer::TYPE_IN, $result['result'], 0);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询额度转移纪录
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getTransferList(string $startTime = '', string $endTime = '', int $page = 1, int $pageSize = 15)
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'secretCode' => $this->appSecret,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$params['loginId'] = $this->loginId;
|
||||
$params['agentLoginId'] = $this->appId;
|
||||
$params['startTime'] = $startTime;
|
||||
$params['endTime'] = $endTime;
|
||||
$params['timeZone'] = 1;
|
||||
$postData = $this->buildParams($params, 'open.mega.balance.transfer.query');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家游戏记录
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getUserGameRecord(string $startTime = '', string $endTime = '')
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => $this->loginId,
|
||||
'secretCode' => $this->appSecret,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$params['startTime'] = $startTime;
|
||||
$params['endTime'] = $endTime;
|
||||
$params['timeZone'] = 1;
|
||||
$postData = $this->buildParams($params, 'open.mega.player.game.log.url.get');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result['result'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询全部玩家账单
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getReportRecord(string $startTime = '', string $endTime = '')
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'agentLoginId' => $this->appId,
|
||||
'secretCode' => $this->appSecret,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$params['startTime'] = $startTime;
|
||||
$params['endTime'] = $endTime;
|
||||
$params['timeZone'] = 1;
|
||||
$params['type'] = 1;
|
||||
$postData = $this->buildParams($params, 'open.mega.player.total.report');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result['result'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取电子游戏注单分页列表
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameOrderById(string $startTime = '', string $endTime = '')
|
||||
{
|
||||
$params = [
|
||||
'random' => $this->player->uuid ?? uniqid(),
|
||||
'sn' => $this->sn,
|
||||
'loginId' => $this->loginId,
|
||||
'secretCode' => $this->appSecret,
|
||||
];
|
||||
$params['digest'] = $this->createSign($params);
|
||||
$params['startTime'] = $startTime;
|
||||
$params['endTime'] = $endTime;
|
||||
$params['timeZone'] = 1;
|
||||
$postData = $this->buildParams($params, 'open.mega.game.order.page');
|
||||
$result = doCurl($this->apiDomain,$postData);
|
||||
if (!empty($result['error'])) {
|
||||
throw new GameException($result['error']['message'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家游戏记录
|
||||
* @return array
|
||||
*/
|
||||
public function handleOrderHistories(): array
|
||||
{
|
||||
try {
|
||||
$list = [];
|
||||
$startTime = date('Y-m-d');
|
||||
$endTime = date('Y-m-d');
|
||||
$data = $this->getReportRecord($startTime, $endTime);
|
||||
if (!empty($data)) {
|
||||
foreach ($data as $item) {
|
||||
$list[] = [
|
||||
'player_code' => $item['loginId'],
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => 'MeGa888',
|
||||
'bet' => $item['bet'],
|
||||
'win' => $item['win'],
|
||||
'order_no' => $item['userId'].date('Ymd'),
|
||||
'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE),
|
||||
'platform_action_at' => $startTime,
|
||||
'game_type' => 1,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
444
app/service/game/MonkeyKingServiceInterface.php
Normal file
444
app/service/game/MonkeyKingServiceInterface.php
Normal file
@@ -0,0 +1,444 @@
|
||||
<?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 Exception;
|
||||
use support\Log;
|
||||
use support\Response;
|
||||
|
||||
class MonkeyKingServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
public $successCode = 'S100';
|
||||
public $loginId;
|
||||
public $gameType = [
|
||||
'10' => 'Slot',
|
||||
'12' => 'Casino',
|
||||
'13' => 'Arcade',
|
||||
'16' => 'Fishing'
|
||||
];
|
||||
public $failCode = [
|
||||
'S200' => '重復請求',
|
||||
'150001' => '無效的簽名',
|
||||
'150002' => '無效的SN',
|
||||
'150003' => '無效的參數',
|
||||
'150004' => '無效的貨幣',
|
||||
'150005' => '玩家已存在',
|
||||
'150006' => '玩家不存在',
|
||||
'150007' => '次级代理不存在',
|
||||
'150008' => '執行失敗',
|
||||
'150009' => '無效的方法',
|
||||
'150010' => '無效的用戶狀態',
|
||||
'150011' => '玩家狀態無需更新',
|
||||
'150012' => '超出數據範圍',
|
||||
'150013' => '無匹配數據',
|
||||
'150014' => '登入位置被禁止',
|
||||
'150015' => '分數不足夠',
|
||||
'150016' => '不支持禮碼',
|
||||
'150017' => '交易流水號不得重複',
|
||||
'150018' => '系統繁忙',
|
||||
'150019' => '日期時間各式錯誤',
|
||||
'150020' => '超出時間限制範圍(開始時間與結束時間之間不能大於120分鐘)',
|
||||
];
|
||||
private $apiDomain;
|
||||
private $domain;
|
||||
private $appId;
|
||||
private $appSecret;
|
||||
private $path = [
|
||||
'createPlayer' => '/UserInfo/CreatePlayer',
|
||||
'getPlayer' => '/UserInfo/GetPlayer',
|
||||
'getGameList' => '/Game/GetGameList',
|
||||
'getSimpleGameList' => '/Game/GetSimpleGameList',
|
||||
'getLoginH5' => '/UserInfo/GetLoginH5',
|
||||
'setPlayerStatus' => '/UserInfo/SetPlayerStatus',
|
||||
'getBalance' => '/Account/GetBalance',
|
||||
'setBalanceTransfer' => '/Account/SetBalanceTransfer',
|
||||
'getGameRecordByTime' => '/Game/GetGameRecordByTime',
|
||||
'getGameRecord' => '/Game/GetGameRecord',
|
||||
'removeRecords' => '/Game/RemoveRecords',
|
||||
];
|
||||
private $lang = [
|
||||
'zh-CN' => 'zh-ch',
|
||||
'en' => 'en_us',
|
||||
'zh_tc' => 'zh_tc',
|
||||
'en-us' => 'en-us',
|
||||
'id' => 'id',
|
||||
'th' => 'th',
|
||||
'my' => 'my',
|
||||
'vi' => 'vi',
|
||||
'fi_fi' => 'fi_fi',
|
||||
'kr_ko' => 'kr_ko',
|
||||
'hi_hi' => 'hi_hi',
|
||||
'br_po' => 'br_po',
|
||||
'lo_la' => 'lo_la',
|
||||
'cam_dia' => 'en_us', // 柬埔寨语
|
||||
];
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getLoginId()
|
||||
{
|
||||
/** @var PlayerGamePlatform $playerGamePlatform */
|
||||
$playerGamePlatform = $this->player->playerGamePlatform->where('platform_id', $this->platform->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|\think\Exception
|
||||
*/
|
||||
public function createPlayer(array $data = [])
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'CreatePlayer',
|
||||
'SN' => $this->appId,
|
||||
'PlayerCode' => $data['uuid'],
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['PlayerName'] = $data['uuid'];
|
||||
Log::info('MonkeyKing请求参数', [$params]);
|
||||
$res = doCurl($this->createUrl('createPlayer'), $params);
|
||||
Log::info('MonkeyKing请求返回数据', [$res]);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 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 $res;
|
||||
}
|
||||
|
||||
public function createSign($params): string
|
||||
{
|
||||
return md5(implode('', $params) . $this->appSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求url
|
||||
* @param $method
|
||||
* @return string
|
||||
*/
|
||||
public function createUrl($method): string
|
||||
{
|
||||
return $this->apiDomain . $this->path[$method];
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建玩家
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getPlayer()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetPlayer',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
Log::info('MonkeyKing请求参数', [$params]);
|
||||
$data = doCurl($this->createUrl('getPlayer'), $params);
|
||||
Log::info('MonkeyKing请求返回数据', [$data]);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏摘要MD5 (id+method+sn+APlSecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getSimpleGameList()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetSimpleGameList',
|
||||
'SN' => $this->appId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
Log::info('MonkeyKing请求参数', [$params]);
|
||||
$data = doCurl($this->createUrl('getSimpleGameList'), $params);
|
||||
Log::info('MonkeyKing请求返回数据', [$data]);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
if (!empty($data['data']['games'])) {
|
||||
foreach ($data['data']['games'] as $game) {
|
||||
Game::query()->updateOrCreate(
|
||||
[
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $game['gameCode'],
|
||||
'platform_game_type' => $game['type'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏摘要MD5 (id+method+sn+APlSecretKey)
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function login(array $data = []): string
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetLoginH5',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
Log::info('MonkeyKing请求参数', [$params]);
|
||||
$res = doCurl($this->createUrl('getLoginH5'), $params);
|
||||
Log::info('MonkeyKing请求返回数据', [$res]);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
$responseH5 = [
|
||||
'Language' => $this->lang[$data['lang']] ?? 'ch',
|
||||
"GameId" => $data['gameCode'],
|
||||
'CallbackAddress' => $data['callBackUrl'] ?? '',
|
||||
"AppType" => $data['appType'] ?? 1,
|
||||
"DeviceType" => 1,
|
||||
];
|
||||
$jsonString = json_encode($responseH5);
|
||||
$parametersValue = base64_encode($jsonString);
|
||||
|
||||
return $this->domain . '/linkgame' . ($res['data']['loginUrl'] ?? '') . '&' . $parametersValue . '&' . $data['gameCode'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 設置登入玩家狀態。當玩家處於禁用狀態,該玩家無法在平台進行任何操作,如果玩家在遊戲進行中該玩家將會自動退出遊戲。
|
||||
* 簽名密鑰方式 Md5(Id+Method+SN+LoginId+APISecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function setPlayerStatus($status)
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetSimpleGameList',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['Status'] = $status;
|
||||
Log::info('MonkeyKing请求参数', [$params]);
|
||||
$data = doCurl($this->createUrl('setPlayerStatus'), $params);
|
||||
Log::info('MonkeyKing请求返回数据', [$data]);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
|
||||
}
|
||||
|
||||
/**
|
||||
* 轉帳進出額度
|
||||
* 簽名密鑰方式 MD5 (Id+Method+SN+LoginId+APISecretKey)
|
||||
* @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 ($amount == 0 && $reward == 0) {
|
||||
throw new GameException('转出/入金额错误', 0);
|
||||
}
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'SetBalanceTransfer',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['Amount'] = $amount;
|
||||
$params['Reward'] = $reward;
|
||||
Log::info('MonkeyKing请求参数', [$params]);
|
||||
$res = doCurl($this->createUrl('setBalanceTransfer'), $params);
|
||||
Log::info('MonkeyKing请求返回数据', [$res]);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
Log::error($this->failCode[$res['code']], ['res' => $res]);
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward, $res['data']['refId'] ?? '');
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
$balance = $this->getBalance();
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, !empty($balance['data']['result']) ? -$balance['data']['result'] : 0, !empty($balance['data']['reward']) ? -$balance['data']['reward'] : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取玩家餘額信息
|
||||
* 簽名密鑰方式 MD5 (Id+Method+SN+LoginId+APISecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getBalance()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetBalance',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
Log::info('MonkeyKing请求参数', [$params]);
|
||||
$data = doCurl($this->createUrl('getBalance'), $params);
|
||||
Log::info('MonkeyKing请求返回数据', [$data]);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 依據時間獲取遊戲紀錄
|
||||
* MD5 (Id+Method+SN+StartTime+EndTime+APISecretKey)
|
||||
* @param int $pageIndex
|
||||
* @param string $startTime
|
||||
* @param string $endTime
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameRecordByTime(int $pageIndex = 1, string $startTime = '', string $endTime = '')
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetGameRecordByTime',
|
||||
'SN' => $this->appId,
|
||||
'StartTime' => $startTime,
|
||||
'EndTime' => $endTime,
|
||||
];
|
||||
$pageSize = 500;
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['PageSize'] = $pageSize;
|
||||
$params['PageIndex'] = $pageIndex;
|
||||
Log::info('MonkeyKing请求参数', [$params]);
|
||||
$res = doCurl($this->createUrl('getGameRecordByTime'), $params);
|
||||
Log::info('MonkeyKing请求返回数据', [$res]);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取玩家遊戲歷史紀錄
|
||||
* MD5 (Id+Method+SN+APISecretKey)
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameRecord()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetGameRecord',
|
||||
'SN' => $this->appId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
Log::info('MonkeyKing请求参数', [$params]);
|
||||
$res = doCurl($this->createUrl('getGameRecord'), $params);
|
||||
Log::info('MonkeyKing请求返回数据', [$res]);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刪除遊戲紀錄
|
||||
* MD5 (Id+Method+SN+IdsToBeRemoved+APISecretKey)
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function removeRecords($idsToBeRemoved)
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'RemoveRecords',
|
||||
'SN' => $this->appId,
|
||||
'IdsToBeRemoved' => implode(',', $idsToBeRemoved),
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
Log::info('MonkeyKing请求参数', [$params]);
|
||||
$res = doCurl($this->createUrl('removeRecords'), $params);
|
||||
Log::info('MonkeyKing请求返回数据', [$res]);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
504
app/service/game/NextSpinServiceInterface.php
Normal file
504
app/service/game/NextSpinServiceInterface.php
Normal file
@@ -0,0 +1,504 @@
|
||||
<?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 Exception;
|
||||
use support\Log;
|
||||
use support\Response;
|
||||
|
||||
class NextSpinServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
private $apiDomain;
|
||||
private $domain;
|
||||
private $appId;
|
||||
private $appSecret;
|
||||
private $path = [
|
||||
'ListGames' => 'ListGames',//获取游戏列表
|
||||
'createPlayer' => '/UserInfo/CreatePlayer',
|
||||
'getPlayer' => '/UserInfo/GetPlayer',
|
||||
'getGameList' => '/Game/GetGameList',
|
||||
'getSimpleGameList' => '/Game/GetSimpleGameList',
|
||||
'getLoginH5' => '/UserInfo/GetLoginH5',
|
||||
'setPlayerStatus' => '/UserInfo/SetPlayerStatus',
|
||||
'getBalance' => '/Account/GetBalance',
|
||||
'setBalanceTransfer' => '/Account/SetBalanceTransfer',
|
||||
'getGameRecordByTime' => '/Game/GetGameRecordByTime',
|
||||
'getGameRecord' => '/Game/GetGameRecord',
|
||||
'removeRecords' => '/Game/RemoveRecords',
|
||||
];
|
||||
|
||||
public $successCode = 'S100';
|
||||
|
||||
public $loginId;
|
||||
|
||||
public $gameType = [
|
||||
'AD' => 'Casino',
|
||||
'SM' => 'Fishing',
|
||||
];
|
||||
|
||||
public $localGameType = [
|
||||
'AD' => '2',
|
||||
'SM' => '4',
|
||||
];
|
||||
|
||||
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' => '系統錯誤',
|
||||
];
|
||||
|
||||
private $lang = [
|
||||
'zh-CN' => 'zh_ch',
|
||||
'en' => 'en_us',
|
||||
'zh_tc' => 'zh_tc',
|
||||
'th_th' => 'th_th',
|
||||
'Ma_my' => 'Ma_my',
|
||||
'vi_nam' => 'vi_nam',
|
||||
'Fi_fi' => 'Fi_fi',
|
||||
'Kr_ko' => 'Kr_ko',
|
||||
'Hi_hi' => 'Hi_hi',
|
||||
'My_mar' => 'My_mar',
|
||||
'Br_po' => 'Br_po',
|
||||
'cam_dia' => 'cam_dia', // 柬埔寨语
|
||||
];
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
}
|
||||
|
||||
public function httpRequest($url,$api,$method = 'POST',$fields)
|
||||
{
|
||||
$fields = json_encode(["merchantCode"=> "ZCH6747",
|
||||
"serialNo"=>"20240722224255982841"]);
|
||||
$curl = curl_init();
|
||||
curl_setopt_array($curl, [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_ENCODING => "",
|
||||
CURLOPT_MAXREDIRS => 10,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||
CURLOPT_CUSTOMREQUEST => $method,
|
||||
CURLOPT_POSTFIELDS => $fields,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
"API: $api",
|
||||
"Accept: */*",
|
||||
"Accept-Encoding: gzip, deflate, br",
|
||||
"Connection: keep-alive",
|
||||
"Content-Type: application/json",
|
||||
"DataType: JSON",
|
||||
"User-Agent: PostmanRuntime-ApipostRuntime/1.1.0"
|
||||
],
|
||||
]);
|
||||
$response = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
$data = json_decode($response,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新游戏列表
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getSimpleGameList()
|
||||
{
|
||||
$api = 'getGames';
|
||||
$method = 'POST';
|
||||
$serialNo = createOrderNo();
|
||||
$fields = json_encode([
|
||||
"merchantCode" => $this->appId,
|
||||
"serialNo" => $serialNo
|
||||
]);
|
||||
|
||||
$result = $this->httpRequest($this->apiDomain,$api,$method,$fields);
|
||||
if (isset($result['games']) && $result['code'] == 0) {
|
||||
foreach ($result['games'] as $game) {
|
||||
Game::query()->updateOrCreate(
|
||||
[
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $game['gameCode'],
|
||||
],
|
||||
[
|
||||
'platform_game_type' => $game['category'],
|
||||
'game_type' => $this->localGameType[$game['category']],
|
||||
'name' => $game['gameName'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}else{
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏列表
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGamesList()
|
||||
{
|
||||
$api = 'getGames';
|
||||
$method = 'POST';
|
||||
$serialNo = createOrderNo();
|
||||
$fields = json_encode([
|
||||
"merchantCode" => $this->appId,
|
||||
"serialNo" => $serialNo
|
||||
]);
|
||||
|
||||
$result = $this->httpRequest($this->apiDomain,$api,$method,$fields);
|
||||
if (isset($result['games']) && $result['code'] == 0) {
|
||||
return $result['games'];
|
||||
}else{
|
||||
throw new GameException($result['msg'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩游戏
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function playGame()
|
||||
{
|
||||
$params = [
|
||||
'Method' => 'PLAY',
|
||||
'Username' => $this->player->name,
|
||||
'RequestID' => createOrderNo(),
|
||||
'Amount' => $amount,
|
||||
'Timestamp' => time(),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
|
||||
$result = doCurl($this->createUrl($signature), $params);
|
||||
if (isset($result['Token'])) {
|
||||
return $forwardUrl = $this->domain."?token=".$result['Token']."&game=1jeqx59c7ztqg&mobile=false";
|
||||
}else{
|
||||
throw new GameException($result['Message'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getLoginId()
|
||||
{
|
||||
/** @var PlayerGamePlatform $playerGamePlatform */
|
||||
$playerGamePlatform = $this->player->playerGamePlatform->where('platform_id', $this->platform->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 = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'CreatePlayer',
|
||||
'SN' => $this->appId,
|
||||
'PlayerCode' => $data['uuid'],
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['PlayerName'] = $data['uuid'];
|
||||
$res = doCurl($this->createUrl('createPlayer'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 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 $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建玩家
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|Exception
|
||||
*/
|
||||
public function getPlayer()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetPlayer',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$data = doCurl($this->createUrl('getPlayer'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏摘要MD5 (id+method+sn+APlSecretKey)
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function login(array $data = []): string
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetLoginH5',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$res = doCurl($this->createUrl('getLoginH5'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
Log::error($this->failCode[$res['code']], ['res' => $res]);
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
$responseH5 = [
|
||||
'Language' => $this->lang[$data['lang']] ?? 'ch',
|
||||
"GameId" => $data['gameCode'],
|
||||
'CallbackAddress' => $data['callBackUrl'] ?? '',
|
||||
"AppType" => $data['appType'] ?? 1,
|
||||
"DeviceType" => 1,
|
||||
];
|
||||
$jsonString = json_encode($responseH5);
|
||||
$parametersValue = base64_encode($jsonString);
|
||||
$link = $this->domain . '/linkgame' . ($res['data']['loginUrl'] ?? '') . '&' . $parametersValue;
|
||||
if (!empty($data['gameCode'])) {
|
||||
$link .= '&' . $data['gameCode'];
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* 設置登入玩家狀態。當玩家處於禁用狀態,該玩家無法在平台進行任何操作,如果玩家在遊戲進行中該玩家將會自動退出遊戲。
|
||||
* 簽名密鑰方式 Md5(Id+Method+SN+LoginId+APISecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function setPlayerStatus($status)
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetSimpleGameList',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['Status'] = $status;
|
||||
$data = doCurl($this->createUrl('setPlayerStatus'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取玩家餘額信息
|
||||
* 簽名密鑰方式 MD5 (Id+Method+SN+LoginId+APISecretKey)
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getBalance()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetBalance',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$data = doCurl($this->createUrl('getBalance'), $params);
|
||||
if ($data['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$data['code']], 0);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
$balance = $this->getBalance();
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, !empty($balance['data']['result']) ? -$balance['data']['result'] : 0, !empty($balance['data']['reward']) ? -$balance['data']['reward'] : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 轉帳進出額度
|
||||
* 簽名密鑰方式 MD5 (Id+Method+SN+LoginId+APISecretKey)
|
||||
* @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 ($amount == 0 && $reward == 0) {
|
||||
throw new GameException('转出/入金额错误', 0);
|
||||
}
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'SetBalanceTransfer',
|
||||
'SN' => $this->appId,
|
||||
'LoginId' => $this->loginId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['Amount'] = $amount;
|
||||
$params['Reward'] = $reward;
|
||||
$res = doCurl($this->createUrl('setBalanceTransfer'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward, $res['data']['refId'] ?? '');
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 依據時間獲取遊戲紀錄
|
||||
* MD5 (Id+Method+SN+StartTime+EndTime+APISecretKey)
|
||||
* @param int $pageIndex
|
||||
* @param string $startTime
|
||||
* @param string $endTime
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameRecordByTime(int $pageIndex = 1, string $startTime = '', string $endTime = '')
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetGameRecordByTime',
|
||||
'SN' => $this->appId,
|
||||
'StartTime' => $startTime,
|
||||
'EndTime' => $endTime,
|
||||
];
|
||||
$pageSize = 500;
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$params['PageSize'] = $pageSize;
|
||||
$params['PageIndex'] = $pageIndex;
|
||||
$res = doCurl($this->createUrl('getGameRecordByTime'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取玩家遊戲歷史紀錄
|
||||
* MD5 (Id+Method+SN+APISecretKey)
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGameRecord()
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'GetGameRecord',
|
||||
'SN' => $this->appId,
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$res = doCurl($this->createUrl('getGameRecord'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刪除遊戲紀錄
|
||||
* MD5 (Id+Method+SN+IdsToBeRemoved+APISecretKey)
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function removeRecords($idsToBeRemoved)
|
||||
{
|
||||
$params = [
|
||||
'ID' => createOrderNo(),
|
||||
'Method' => 'RemoveRecords',
|
||||
'SN' => $this->appId,
|
||||
'IdsToBeRemoved' => implode(',', $idsToBeRemoved),
|
||||
];
|
||||
$params['Signature'] = $this->createSign($params);
|
||||
$res = doCurl($this->createUrl('removeRecords'), $params);
|
||||
if ($res['code'] != $this->successCode) {
|
||||
throw new GameException($this->failCode[$res['code']], 0);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
473
app/service/game/PragmaticServiceInterface.php
Normal file
473
app/service/game/PragmaticServiceInterface.php
Normal file
@@ -0,0 +1,473 @@
|
||||
<?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 support\Log;
|
||||
use support\Response;
|
||||
use WebmanTech\LaravelHttpClient\Facades\Http;
|
||||
|
||||
class PragmaticServiceInterface extends GameServiceFactory implements GameServiceInterface
|
||||
{
|
||||
public $method = 'POST';
|
||||
private $apiDomain;
|
||||
private $domain;
|
||||
private $appId;
|
||||
private $appSecret;
|
||||
private $secureLogin;
|
||||
private $providerId;
|
||||
public $loginId;
|
||||
|
||||
public $gameType = [
|
||||
'2' => 'Casino',
|
||||
'5' => 'Fishing',
|
||||
'8' => 'Bingo',
|
||||
'1' => 'Slot',
|
||||
];
|
||||
|
||||
public $localGameType = [
|
||||
'2' => '2',//赌场
|
||||
'5' => '4',//捕鱼
|
||||
'8' => '8',//宾果
|
||||
'vs' => '1',//斯洛
|
||||
'lg' => '5',//真人游戏
|
||||
];
|
||||
|
||||
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->apiDomain = $config['api_domain'];
|
||||
$this->domain = $config['domain'];
|
||||
$this->appId = $config['name'];
|
||||
$this->secureLogin = $config['secure_login'];
|
||||
$this->providerId = $config['provider_id'];
|
||||
$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
|
||||
{
|
||||
ksort($params);
|
||||
return md5(http_build_query($params, '', '&') . $this->appSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新游戏列表
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getSimpleGameList()
|
||||
{
|
||||
$params = [
|
||||
'secureLogin' => $this->secureLogin,
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
$params['hash'] = $signature;
|
||||
$result = doFormCurl($this->createUrl('/IntegrationService/v3/http/CasinoGameAPI/getCasinoGames/'), $params);
|
||||
if ($result['error'] == 0 && !empty($result['gameList'])) {
|
||||
foreach ($result['gameList'] as $game) {
|
||||
if ($game['gameTypeID'] != 'vs') {
|
||||
continue;
|
||||
}
|
||||
Game::query()->updateOrCreate(
|
||||
[
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $game['gameID'],
|
||||
],
|
||||
[
|
||||
'platform_game_type' => $game['gameTypeID'],
|
||||
'game_type' => $this->localGameType[$game['gameTypeID']],
|
||||
'name' => $game['gameName'],
|
||||
// 'game_image' => $this->apiDomain.'/gs2c/common/lobby/v1/apps/slots-lobby-assets/'.$game['gameID'].'/'.$game['gameID'].'_325x234_NB.png'
|
||||
]
|
||||
);
|
||||
}
|
||||
}else{
|
||||
throw new GameException($result['description'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏列表
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getGamesList()
|
||||
{
|
||||
$params = [
|
||||
'secureLogin' => $this->secureLogin,
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
$params['hash'] = $signature;
|
||||
$result = doFormCurl($this->createUrl('/IntegrationService/v3/http/CasinoGameAPI/getCasinoGames/'), $params);
|
||||
if ($result['error'] == 0 && !empty($result['gameList'])) {
|
||||
return $result;
|
||||
}else{
|
||||
throw new GameException($result['description'], 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 = [
|
||||
'secureLogin' => $this->secureLogin,
|
||||
'externalPlayerId' => $data['uuid'],
|
||||
'currency' => 'MYR',
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
$params['hash'] = $signature;
|
||||
$result = doFormCurl($this->createUrl('/IntegrationService/v3/http/CasinoGameAPI/player/account/create/'), $params);
|
||||
if ($result['error'] != 0 || empty($result['playerId'])) {
|
||||
Log::error($result['description'], ['res' => $result]);
|
||||
throw new GameException($result['description'], 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 false
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getPlayer(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家进入游戏
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function login(array $data = []): string
|
||||
{
|
||||
$params = [
|
||||
'secureLogin' => $this->secureLogin,
|
||||
'externalPlayerId' => $this->loginId,
|
||||
'gameId' => $data['gameCode'],
|
||||
'language' => 'en',
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
$params['hash'] = $signature;
|
||||
$result = doFormCurl($this->createUrl('/IntegrationService/v3/http/CasinoGameAPI/game/start/'), $params);
|
||||
if ($result['error'] == 0 && !empty($result['gameURL'])) {
|
||||
$link = $result['gameURL'];
|
||||
}else{
|
||||
throw new GameException($result['description'], 0);
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家游戏平台余额
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function getBalance()
|
||||
{
|
||||
$params = [
|
||||
'secureLogin' => $this->secureLogin,
|
||||
'externalPlayerId' => $this->loginId,
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
$params['hash'] = $signature;
|
||||
$result = doFormCurl($this->createUrl('/IntegrationService/v3/http/CasinoGameAPI/balance/current/'), $params);
|
||||
if ($result['error'] != 0) {
|
||||
throw new GameException('Pragmatic System Error,Please contact the administrator', 0);
|
||||
}
|
||||
return $result['balance'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家钱包转入游戏平台
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferOut()
|
||||
{
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
|
||||
}
|
||||
|
||||
/**
|
||||
* 游戏平台转入玩家钱包
|
||||
* @return array|mixed|null
|
||||
* @throws GameException|\think\Exception
|
||||
*/
|
||||
public function balanceTransferIn()
|
||||
{
|
||||
$balance = $this->getBalance();
|
||||
if($balance == 0){
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer(PlayerWalletTransfer::TYPE_IN, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, $balance ? -$balance : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 轉帳進出額度
|
||||
* @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)
|
||||
{
|
||||
$params = [
|
||||
'secureLogin' => $this->secureLogin,
|
||||
'externalPlayerId' => $this->loginId,
|
||||
'externalTransactionId' => createOrderNo(),
|
||||
'amount' => $amount,
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
$params['hash'] = $signature;
|
||||
$result = doFormCurl($this->createUrl('/IntegrationService/v3/http/CasinoGameAPI/balance/transfer/'), $params);
|
||||
if ($result['error'] != 0) {
|
||||
throw new GameException($result['description'], 0);
|
||||
}
|
||||
// 记录玩家钱包转出转入记录
|
||||
$this->createWalletTransfer($type, $amount, $reward, $result['transactionId'] ?? '');
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转账记录
|
||||
* @param $startTime
|
||||
* @return array|mixed|null
|
||||
* @throws GameException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
protected function transferTransactions($startTime)
|
||||
{
|
||||
$params = [
|
||||
'secureLogin' => $this->secureLogin,
|
||||
//'timepoint' => $startTime ?? round(microtime(true) * 1000),
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
$params['hash'] = $signature;
|
||||
$result = doFormCurl($this->createUrl('/IntegrationService/v3/http/CasinoGameAPI/balance/transfer/transactions/'), $params);
|
||||
if ($result['error'] != 0) {
|
||||
throw new GameException($result['description'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* 踢出游戏
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|Exception
|
||||
*/
|
||||
public function terminateSession()
|
||||
{
|
||||
$params = [
|
||||
'secureLogin' => $this->secureLogin,
|
||||
'externalPlayerId' => $this->loginId,
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
$params['hash'] = $signature;
|
||||
$result = doFormCurl($this->createUrl('/IntegrationService/v3/http/CasinoGameAPI/game/session/terminate'), $params);
|
||||
if ($result['error'] == 0) {
|
||||
throw new GameException($result['description'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重播链接
|
||||
* @return array|mixed|Response
|
||||
* @throws GameException|Exception
|
||||
*/
|
||||
public function replayLink($roundId)
|
||||
{
|
||||
$params = [
|
||||
'secureLogin' => $this->secureLogin,
|
||||
'externalPlayerId' => $this->loginId,
|
||||
'roundId' => $roundId,
|
||||
];
|
||||
$signature = $this->createSign($params);
|
||||
$params['hash'] = $signature;
|
||||
$result = doFormCurl($this->createUrl('/IntegrationService/v3/http/ReplayAPI/getSharedLink'), $params);
|
||||
if ($result['error'] == 0) {
|
||||
throw new GameException($result['description'], 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询游戏纪录
|
||||
* @return array
|
||||
*/
|
||||
public function getGameRecordList(): array
|
||||
{
|
||||
$params = [
|
||||
'login' => $this->secureLogin,
|
||||
'password' => $this->appSecret,
|
||||
'timepoint' => round(microtime(true) * 1000) - 90000,
|
||||
];
|
||||
$query = http_build_query($params, '', '&');
|
||||
$url = $this->createUrl('/IntegrationService/v3/DataFeeds/gamerounds/finished/?' . $query);
|
||||
$response = Http::timeout(10)->get($url);
|
||||
$result = $response->body();
|
||||
return $this->parseCustomCsv($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* CSV转数组
|
||||
* @param $input
|
||||
* @return array
|
||||
*/
|
||||
public function parseCustomCsv($input): array
|
||||
{
|
||||
$lines = explode("\n", trim($input)); // 分割为行数组
|
||||
|
||||
// 解析timepoint
|
||||
$timepoint = (int) substr($lines[0], strpos($lines[0], '=') + 1);
|
||||
array_shift($lines); // 移除timepoint行
|
||||
|
||||
// 处理CSV部分
|
||||
$header = str_getcsv(array_shift($lines)); // 获取标题行
|
||||
$result = [
|
||||
'timepoint' => $timepoint,
|
||||
'data' => []
|
||||
];
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$row = str_getcsv($line);
|
||||
if (count($row) !== count($header)) continue; // 跳过列数不匹配的行
|
||||
|
||||
// 组合关联数组并转换数据类型
|
||||
$entry = array_combine($header, array_map(function($value) {
|
||||
if ($value === 'null') return null; // 转换null字符串
|
||||
if (is_numeric($value)) { // 转换数字类型
|
||||
return (strpos($value, '.') !== false) ? (float)$value : (int)$value;
|
||||
}
|
||||
return $value;
|
||||
}, $row));
|
||||
|
||||
$result['data'][] = $entry;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询玩家游戏记录
|
||||
* @return array
|
||||
*/
|
||||
public function handleOrderHistories(): array
|
||||
{
|
||||
try {
|
||||
$list = [];
|
||||
$data = $this->getGameRecordList();
|
||||
if (!empty($data['data'])) {
|
||||
foreach ($data['data'] as $item) {
|
||||
$list[] = [
|
||||
'uuid' => $item['extPlayerID'],
|
||||
'platform_id' => $this->platform->id,
|
||||
'game_code' => $item['gameID'],
|
||||
'bet' => $item['bet'],
|
||||
'win' => $item['win'],
|
||||
'order_no' => $item['playSessionID'],
|
||||
'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE),
|
||||
'platform_action_at' => date('Y-m-d H:i:s', strtotime($item['endDate'])),
|
||||
'game_type' => 'vs',
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user