初始化

This commit is contained in:
2026-03-02 13:44:38 +08:00
commit 05b785083c
677 changed files with 58662 additions and 0 deletions

View 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('', []);
}
}

View 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,
]);
}
}

View 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);
}
}

View 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
]);
}
}