first(); } public static function findAll(array $search = []) { return self::model()::where(self::getWhere($search))->get(); } public static function paginate(array $search = []) { $limit = isset($search['limit']) ? $search['limit'] : 10; $paginator = self::model()::where(self::getWhere($search)) ->orderBy('created_at', 'desc')->paginate($limit); return ['total' => $paginator->total(), 'data' => $paginator->items()]; } public function __construct() { $serviceCharge = Config::where('field', 'service_charge')->first()->val; $serviceCharge = floatval($serviceCharge); $this->serviceCharge = $serviceCharge; } public static function notify($data) { try { $telegram = new Api(config('services.telegram.token')); $telegram->sendMessage($data); } catch (TelegramSDKException $e) { return false; } return true; } //提现账单 public function bill($chatId, $firstName, $messageId = null, $page = 1, $limit = 5) { $list = Withdraw::where('member_id', $chatId) ->orderBy('id', 'desc') ->forPage($page, $limit) ->get(); $count = Withdraw::where('member_id', $chatId) ->whereIn('status', [0, 1]) ->count(); $status = [lang('等待放行'), lang('已到账'), lang("失败")]; $text = "👤 {$firstName}({$chatId}) " . lang("钱包提现记录") . "\n\n"; foreach ($list as $item) { $amount = floatval($item->amount); $balance = floatval($item->after_balance); $text .= "-------------------------------------\n"; $text .= "➖ {$amount} USDT\n" . lang("余额") . ":{$balance} \n"; $text .= lang("类别") . "类别:" . lang("提现") . "\n"; $text .= lang("状态") . ":{$status[$item->status]}\n"; if ($item->remark) { $text .= lang("说明") . ":{$item->remark}\n"; } $text .= lang("日期") . ":{$item->created_at}\n"; } if ($page > 1) { $keyboard[] = [ ['text' => lang("👆上一页"), 'callback_data' => "withdrawBillNextPage@@" . ($page - 1)] ]; } $allPage = ceil($count / $limit); if ($allPage > $page) { if ($page > 1) { $keyboard[count($keyboard) - 1][] = ['text' => lang("👇下一页"), 'callback_data' => "withdrawBillNextPage@@" . ($page + 1)]; } else { $keyboard[] = [ ['text' => lang("👇下一页"), 'callback_data' => "withdrawBillNextPage@@" . ($page + 1)] ]; } } $keyboard[] = [ ['text' => lang("↩️返回"), 'callback_data' => "withdraw@@home"] ]; return [ 'chat_id' => $chatId, 'text' => $text, 'message_id' => $messageId, 'reply_markup' => json_encode(['inline_keyboard' => $keyboard]) ]; } //删除地址 public static function delAddress($chatId, $id, $messageId) { Address::where('id', $id) ->where('member_id', $chatId)->delete(); return WithdrawService::getAddress($chatId, $messageId); } //地址详情 public static function addressDetails($chatId, $messageId, $id) { $text = lang("*TRC20 地址管理*") . "\n\n"; $address = Address::where('id', $id) ->where('member_id', $chatId)->first(); $text .= lang("地址") . ":{$address->address}\n"; $text .= lang("别名") . ":{$address->alias}"; $keyboard = [ [['text' => lang('❌删除该地址'), 'callback_data' => "withdrawAddress@@del{$id}"]], [['text' => lang('↩️返回列表'), 'callback_data' => 'withdraw@@address']] ]; return [ 'chat_id' => $chatId, 'parse_mode' => 'MarkdownV2', 'text' => $text, 'reply_markup' => json_encode(['inline_keyboard' => $keyboard]), 'message_id' => $messageId ]; } //输入别名 public static function inputAlias($chatId, $alias, $messageId) { if (mb_strlen($alias) > 20) { return [ 'chat_id' => $chatId, 'text' => lang("别名不能超过20个字,请重新输入"), 'reply_to_message_id' => $messageId, ]; } $address = Cache::get("{$chatId}_address"); $a = new Address(); $a->address = $address; $a->alias = $alias; $a->member_id = $chatId; $a->save(); Cache::delete("{$chatId}_address"); Cache::delete(get_step_key($chatId)); return self::getAddress($chatId, $messageId); } //用户输入TRC20地址 public static function inputAddress($chatId, $address, $messageId) { if (!preg_match('/^T[a-zA-Z1-9]{33}$/', $address)) { return [ 'chat_id' => $chatId, 'text' => lang("地址输入不正确,请重新输入TRC20地址"), 'reply_to_message_id' => $messageId, ]; } Cache::put("{$chatId}_address", $address); Cache::put(get_step_key($chatId), StepStatus::INPUT_ADDRESS_ALIAS); return [ 'chat_id' => $chatId, 'text' => lang("请输入地址别名,便于区分多个地址"), ]; } //添加地址 public static function addAddress($chatId, $messageId) { $text = lang('请输入新的TRC20地址') . "\n"; $keyboard = [[ ['text' => lang('❌取消'), 'callback_data' => "message@@close"], ]]; Cache::put(get_step_key($chatId), StepStatus::INPUT_ADDRESS_TRC20); return [ 'chat_id' => $chatId, 'text' => $text, 'message_id' => $messageId, 'reply_markup' => json_encode(['inline_keyboard' => $keyboard]) ]; } //地址管理 public static function getAddress($chatId, $messageId) { $text = lang("🏠 地址管理"); $text .= "\n--------------------------\n"; $list = Address::where('member_id', $chatId) ->get(); $keyboard = []; foreach ($list as $item) { $keyboard[] = [['text' => $item->alias, 'callback_data' => "withdrawAddress@@detail{$item->id}"]]; } if (count($list) < 5) { $keyboard[] = [['text' => lang("➕ 添加地址"), 'callback_data' => "withdrawAddress@@add"]]; } $keyboard[] = [['text' => lang("↩️返回"), 'callback_data' => "withdraw@@home"]]; return [ 'chat_id' => $chatId, 'text' => $text, 'message_id' => $messageId, 'reply_markup' => json_encode(['inline_keyboard' => $keyboard]) ]; } //设置提现地址 public function setAddress($chatId, $address) { $address = trim($address); if (!$address) return [['chat_id' => $chatId, 'text' => lang("提现地址不能为空")]]; $user = User::where('member_id', $chatId)->first(); $user->usdt = $address; $user->save(); $wallet = Wallet::where('member_id', $chatId)->first(); $temp = floatval($wallet->available_balance); $text = "✅ " . lang('提现地址已设置') . "\n\n"; $text .= lang("请发送提现金额") . "\n"; $text .= "💰 " . lang("当前可用USDT余额") . ":{$temp}\n"; $text .= "⚠️ " . lang('提现将收取') . "{$this->serviceCharge}" . lang("U作为手续费") . "\n"; $text .= "------------------------------------\n"; $text .= lang("例如您要提现100 USDT") . "\n"; $text .= lang("那么请发送:【提现】100") . "\n"; return [['chat_id' => $chatId, 'text' => $text]]; } public static function done($chatId, $messageId, $firstName) { $serviceCharge = (new WithdrawService())->serviceCharge; $amount = Cache::get("{$chatId}_WITHDRAW_MONEY", ''); $address = Cache::get("{$chatId}_WITHDRAW_ADDRESS", ''); if (!$amount || !$address) return WithdrawService::index($chatId, $firstName, $messageId); $real = bcsub($amount, $serviceCharge, 10); $real = floatval($real); if ($amount <= $serviceCharge) { return [ 'chat_id' => $chatId, 'text' => lang("⚠️提现不能少于") . "{$serviceCharge} USDT," . lang("请重试"), 'message_id' => $messageId ]; } $wallet = Wallet::where('member_id', $chatId)->first(); $temp = floatval($wallet->available_balance); // 汇率 $rate = Config::where('field', 'exchange_rate_rmb')->first()->val ?? 1; $rate_usdt_amount = bcdiv($temp, $rate, 2); // 钱包可用余额 折合USDT $rate_rmb_amount = bcmul($amount, $rate, 2); // 提现金额 折合RMB if ($amount > $rate_usdt_amount) { return [ 'chat_id' => $chatId, 'text' => lang("⚠️可用余额不足,请重试"), 'message_id' => $messageId ]; } $ru = RoomUser::where('member_id', $chatId) ->whereIn('status', [0, 1, 2, 3]) ->first(); if ($ru) { $text = lang("游戏未结算") . "\n"; $text .= "⚠️ " . lang("您还有进行中的游戏,所有游戏结算后方可提现") . "\n"; return [ 'chat_id' => $chatId, 'text' => $text, 'message_id' => $messageId, 'reply_markup' => json_encode(['inline_keyboard' => [[ ['text' => lang('进入房间'), 'callback_data' => "games@@home{$ru->room_id}"], ]]]) ]; } $wallet = Wallet::where('member_id', $chatId)->first(); $bl = new BalanceLog(); $bl->member_id = $chatId; $bl->amount = bcmul(($amount * -1), $rate, 10); // 扣除的金额 RMB $bl->before_balance = $wallet->available_balance; $wallet->available_balance = bcsub($wallet->available_balance, $rate_rmb_amount, 10); $wallet->save(); $bl->after_balance = $wallet->available_balance; $bl->change_type = lang('提现'); $withdraw = new Withdraw(); $withdraw->member_id = $chatId; $withdraw->amount = $amount; $withdraw->service_charge = $serviceCharge; $withdraw->to_account = $real; $withdraw->address = $address; $withdraw->exchange_rate = $rate; $withdraw->status = 0; $withdraw->after_balance = bcdiv($wallet->available_balance, $rate, 2); $withdraw->save(); $bl->related_id = $withdraw->id; $bl->save(); $temp = floatval($wallet->available_balance); $text = "✅ " . lang("提现申请已提交!") . "\n\n"; $text .= lang("钱包余额") . ":{$temp} RMB\n"; $text .= lang("汇率") . ":1 USDT = {$rate} RMB\n"; $text .= lang("剩余可用USDT余额") . ":" . number_format(bcdiv($temp, $rate, 2), 2) . " USDT\n"; $text .= lang("提现金额") . ":{$amount} USDT\n"; $text .= lang("实际到账") . ":{$real} USDT\n"; $text .= lang("手续费") . ":{$serviceCharge} USDT\n\n"; $text .= lang("⌛️请等待系统处理, 到账时间可能需要几分钟!") . "\n"; Cache::delete(get_step_key($chatId)); return [ 'chat_id' => $chatId, 'text' => $text, 'message_id' => $messageId, ]; } public static function chooseAddress($chatId, $firstName, $messageId, $id) { $serviceCharge = (new WithdrawService())->serviceCharge; $amount = Cache::get("{$chatId}_WITHDRAW_MONEY", ''); if (!$amount) return WithdrawService::index($chatId, $firstName, $messageId); $amount = floatval($amount); $real = bcsub($amount, $serviceCharge, 10); $real = floatval($real); $address = Address::where('id', $id) ->where('member_id', $chatId)->first(); $text = lang("请确认") . "\n\n"; $text .= lang('手续费') . ":{$serviceCharge} USDT\n"; $text .= lang("提现金额") . ":{$amount} USDT\n"; $text .= lang("实际到账") . ":{$real} USDT\n"; $text .= lang("提现地址") . ":{$address->address}\n"; $keyboard = [ [ ['text' => lang('✅ 确认'), 'callback_data' => "withdrawAddress@@done"], ], [ ['text' => lang('❌取消'), 'callback_data' => "message@@close"] ] ]; Cache::put("{$chatId}_WITHDRAW_ADDRESS", $address->address); return [ 'chat_id' => $chatId, 'text' => $text, 'message_id' => $messageId, 'reply_markup' => json_encode(['inline_keyboard' => $keyboard]) ]; } //用户输入提现金额 public function inputAmount($chatId, $amount, $messageId) { if (!preg_match('/^-?\d+(\.\d+)?$/', $amount)) { return [[ 'chat_id' => $chatId, 'text' => lang("金额输入不正确,请发送提现数字"), 'reply_to_message_id' => $messageId ]]; } $wallet = Wallet::where('member_id', $chatId)->first(); $temp = floatval($wallet->available_balance); // 汇率 $rate = Config::where('field', 'exchange_rate_rmb')->first()->val ?? 1; $rate_amount = bcdiv($temp, $rate, 2); if ($amount <= $this->serviceCharge) { return [[ 'chat_id' => $chatId, 'text' => lang("⚠️提现不能少于") . "{$this->serviceCharge} USDT," . lang('请重试'), 'reply_to_message_id' => $messageId ]]; } if ($amount > $rate_amount) { return [[ 'chat_id' => $chatId, 'text' => lang("可用余额不足,请重试"), 'reply_to_message_id' => $messageId ]]; } $ru = RoomUser::where('member_id', $chatId) ->whereIn('status', [0, 1, 2, 3]) ->first(); if ($ru) { $text = lang('*游戏未结算*')."\n"; $text .= lang("⚠️ 您还有进行中的游戏,所有游戏结算后方可提现")."\n"; return [[ 'chat_id' => $chatId, 'text' => $text, 'parse_mode' => 'MarkdownV2', 'reply_markup' => json_encode(['inline_keyboard' => [[ ['text' => lang('进入房间'), 'callback_data' => "games@@home{$ru->room_id}"], ]]]) ]]; } $list = Address::where('member_id', $chatId)->get(); $keyboard = []; foreach ($list as $item) { $keyboard[] = [['text' => $item->alias, 'callback_data' => "withdrawAddress@@choose{$item->id}"]]; } $keyboard[] = [ ['text' => lang("🏠 地址管理"), 'callback_data' => "withdraw@@address"], ['text' => lang('❌取消'), 'callback_data' => "message@@close"] ]; $text = lang('请直接选择下面的地址')."\n"; $text .= lang("⚠️提示:请务必确认提现地址正确无误,\n否则资金丢失将无法找回请自负!"); Cache::put("{$chatId}_WITHDRAW_MONEY", $amount); Cache::put(get_step_key($chatId), StepStatus::CHOOSE_WITHDRAW_ADDRESS); return [[ 'chat_id' => $chatId, 'text' => $text, 'reply_to_message_id' => $messageId, 'reply_markup' => json_encode(['inline_keyboard' => $keyboard]) ]]; } //申请提现 public function apply($chatId, $messageId) { $wallet = Wallet::where('member_id', $chatId)->first(); // 汇率 $rate = Config::where('field', 'exchange_rate_rmb')->first()->val ?? 1; $temp = floatval($wallet->available_balance); $amount = bcdiv($temp, $rate, 2); $text = lang("请发送提现金额"); $text .= "\n💰 ".lang('当前余额')."{$temp} RMB\n"; $text .= "⚠️".lang('汇率').":1 USDT = {$rate} RMB\n"; $text .= "💰 ".lang('当前可用USDT余额').":{$amount}\n"; $text .= "⚠️ ".lang('提现将收取')."{$this->serviceCharge}".lang('U作为手续费')."\n"; // $keyboard = [[ // ['text' => "🔙返回", 'callback_data' => "withdraw@@home"], // ]]; Cache::put(get_step_key($chatId), StepStatus::INPUT_WITHDRAW_MONEY); return [ 'chat_id' => $chatId, 'text' => $text, 'message_id' => $messageId, // 'reply_markup' => json_encode(['inline_keyboard' => $keyboard]) ]; } //提现管理 public static function index($chatId, $firstName, $messageId = null) { $wallet = Wallet::where('member_id', $chatId)->first(); $text = "👤 {$firstName}({$chatId})\n\n"; $text .= "💰钱包余额\n"; $temp = floatval($wallet->available_balance); $text .= "USDT:{$temp}\n"; $text .= "--------------------------\n"; $serviceAccount = Config::where('field', 'service_account')->first()->val; $keyboard = [ [ ['text' => '➕ 提现', 'callback_data' => "withdraw@@apply"], ['text' => '🧾 账单', 'callback_data' => "withdraw@@bill"] ], [ ['text' => lang("🏠 地址管理"), 'callback_data' => "withdraw@@address"], ['text' => lang('👩 客服帮助'), 'url' => "https://t.me/{$serviceAccount}"] ], [ ['text' => lang('❌取消'), 'callback_data' => "message@@close"], ] ]; return [ 'chat_id' => $chatId, 'text' => $text, 'message_id' => $messageId, 'reply_markup' => json_encode(['inline_keyboard' => $keyboard]) ]; } }