初始化
This commit is contained in:
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());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user