=', $startTime]; } if (!empty($search['end_time'])) { $endTime = $search['end_time'] . " 23:59:59"; $where[] = ['users.created_at', '<=', $endTime]; } if (!empty($search['recharge_channel_group_id'])) { $where[] = ['users.recharge_channel_group_id', '=', $search['recharge_channel_group_id']]; } return $where; } /** * @description: 查询单条数据 * @param array $search * @return \App\Models\User|null */ public static function findOne(array $search): ?User { return static::$MODEL::where(self::getWhere($search))->first(); } /** * @description: 查询所有数据 * @param array $search * @return \Illuminate\Database\Eloquent\Collection */ public static function findAll(array $search = []) { return static::$MODEL::where(self::getWhere($search))->get(); } /** * @description: 分页查询 * @param array $search * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ /** @var list wallets 表排序字段(与 GET /admin/user 的 sort_field 一致) */ private const PAGINATE_WALLET_SORT_FIELDS = [ 'available_balance', 'frozen_balance', 'yuebao', 'wager_required', 'wager_completed', ]; /** @var list users 表排序字段 */ private const PAGINATE_USER_SORT_FIELDS = [ 'created_at', 'last_active_time', 'third_game_total_balance', ]; public static function paginate(array $search = [], $sortOrder = 'desc', $sortField = 'created_at') { $limit = isset($search['limit']) ? $search['limit'] : 15; $page = isset($search['page']) ? $search['page'] : 1; $where = self::getWhere($search); $total = static::$MODEL::where($where)->count(); $sortOrder = strtolower($sortOrder) === 'asc' ? 'asc' : 'desc'; $query = static::$MODEL::with(['wallet', 'level', 'agent']) ->leftJoin('wallets', 'users.member_id', '=', 'wallets.member_id') ->where($where); self::applyPaginateSort($query, $sortField, $sortOrder); $list = $query->select('users.*')->forPage($page, $limit)->get(); foreach ($list as &$item) { $item['total_consume'] = BalanceLog::getTotalConsume($item->member_id);//用户累计消费总额 $item['third_game_total_balance'] = data_get($item, 'third_game_total_balance'); // 当前周期打码量:wager_required 所需、wager_completed 当前打码量、wager_remaining 剩余打码量(提现后重置) foreach (WageringService::summary($item->wallet) as $key => $value) { $item[$key] = $value; } } return ['total' => $total, 'data' => $list]; } private static function applyPaginateSort($query, string $sortField, string $sortOrder): void { if ($sortField === 'total_consume') { $query->leftJoinSub(self::totalConsumeSubquery(), 'user_total_consume', 'users.member_id', '=', 'user_total_consume.member_id') ->orderBy('user_total_consume.total_consume', $sortOrder); } elseif ($sortField === 'wager_remaining') { $direction = $sortOrder === 'asc' ? 'ASC' : 'DESC'; $query->orderByRaw( "GREATEST(CAST(wallets.wager_required AS DECIMAL(20,4)) - CAST(wallets.wager_completed AS DECIMAL(20,4)), 0) {$direction}" ); } elseif (in_array($sortField, self::PAGINATE_WALLET_SORT_FIELDS, true)) { $query->orderBy("wallets.{$sortField}", $sortOrder); } elseif (in_array($sortField, self::PAGINATE_USER_SORT_FIELDS, true)) { $query->orderBy('users.' . $sortField, $sortOrder); } else { $query->orderBy('users.created_at', $sortOrder); } $query->orderByDesc('users.created_at')->orderByDesc('users.id'); } private static function totalConsumeSubquery() { return BalanceLog::query() ->select('member_id') ->groupBy('member_id') ->selectRaw( "GREATEST(ABS(COALESCE(SUM(CASE WHEN type = 1 AND change_type LIKE '%投注%' THEN amount ELSE 0 END), 0))" . " - COALESCE(SUM(CASE WHEN type = 1 AND change_type LIKE '%彩退款' THEN amount ELSE 0 END), 0), 0) AS total_consume" ); } //设置游戏ID public function setGameID($chatId, $gameId) { $gameId = trim($gameId); if (!$gameId) return ['chat_id' => $chatId, 'text' => '❌游戏ID设置失败,请输入正确的游戏ID']; if (User::where('game_id', $gameId)->where('member_id', '<>', $chatId)->first()) { return ['chat_id' => $chatId, 'text' => '❌游戏ID设置失败,游戏ID已绑定其他用户']; } $user = User::where('member_id', $chatId)->first(); $user->game_id = $gameId; $user->save(); return ['chat_id' => $chatId, 'text' => "✅ 游戏ID设置成功\n游戏ID:{$gameId}"]; } /** * @param Api $telegram * @param $data * @param $chatId * @param $firstName * @param $messageId * @return void * @throws TelegramSDKException */ public static function init(Api $telegram, $data, $chatId, $firstName, $messageId): void { $pattern = "/^setLanguage@@.*$/"; if (preg_match($pattern, $data)) { $language = preg_replace('/^setLanguage@@/', '', $data); $res = UserService::setLanguage($chatId, $language); $telegram->deleteMessage(['chat_id' => $chatId, 'message_id' => $messageId]); TelegramWebHook::setReplyKeyboard($chatId, $language); // $telegram->sendMessage($res); } } public static function getIsBanned($memberId) { $user = User::where('member_id', $memberId)->first(); return $user->is_banned == 1; } public static function setLanguage($chatId, $language): array { $userInfo = self::findOne(['member_id' => $chatId]); $userInfo->setLanguage($language); $userInfo->save(); App::setLocale($language); (new Home)->setMyCommands(); return self::getLanguages($chatId); } public static function getLanguages($chatId): array { $keyboard = [ [['text' => lang('en'), 'callback_data' => "setLanguage@@en"]], [['text' => lang('zh'), 'callback_data' => "setLanguage@@zh"]], [['text' => lang('vi'), 'callback_data' => "setLanguage@@vi"]], [['text' => lang('❌取消'), 'callback_data' => "message@@close"]], ]; return [ 'chat_id' => $chatId, 'text' => lang("请选择您的语言"), 'reply_markup' => json_encode(['inline_keyboard' => $keyboard]), 'protect_content' => true ]; } }