From a3cd829a7d72cdd879255bb95a1ecc4e0005b495 Mon Sep 17 00:00:00 2001 From: BrettonYe Date: Mon, 6 May 2024 00:21:30 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=AA=F0=9F=8F=BC=20Improve=20Code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Admin/UserController.php | 2 +- app/Models/User.php | 8 ++ app/Utils/CurrencyExchange.php | 128 ++++++++---------- app/Utils/Helpers.php | 40 +++--- config/services.php | 1 + public/update/ssr-win-4.0.xml | 0 resources/lang/en.json | 2 + resources/views/admin/index.blade.php | 5 + 8 files changed, 94 insertions(+), 92 deletions(-) delete mode 100644 public/update/ssr-win-4.0.xml diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 298b569b..419c270f 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -67,7 +67,7 @@ class UserController extends Controller // 不活跃用户 $request->whenFilled('paying', function () use ($query) { - $payingUser = Order::whereStatus(2)->where('goods_id', '<>', null)->whereIsExpire(0)->where('amount', '>', 0)->pluck('user_id')->unique(); + $payingUser = Order::whereStatus(2)->whereNotNull('goods_id')->whereIsExpire(0)->where('amount', '>', 0)->pluck('user_id')->unique(); $query->whereIn('id', $payingUser); }); diff --git a/app/Models/User.php b/app/Models/User.php index ed1d816a..97f4c77b 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -308,6 +308,14 @@ class User extends Authenticatable return $this->hasMany(Order::class); } + public function paidOrders() + { + return $this->hasMany(Order::class)->where('status', 2) + ->whereNotNull('goods_id') + ->where('is_expire', 0) + ->where('amount', '>', 0); + } + public function routeNotificationForTelegram() { return $this->telegram_user_id; diff --git a/app/Utils/CurrencyExchange.php b/app/Utils/CurrencyExchange.php index 01dbd47e..ae281d56 100644 --- a/app/Utils/CurrencyExchange.php +++ b/app/Utils/CurrencyExchange.php @@ -12,7 +12,7 @@ class CurrencyExchange { private static PendingRequest $basicRequest; - private static array $apis = ['fixer', 'exchangerateApi', 'wise', 'currencyData', 'exchangeRatesData', 'duckduckgo', 'wsj', 'valutafx', 'baidu', 'unionpay', 'exchangerate', 'jsdelivrFile', 'it120', 'k780']; + private static array $apis = ['fixer', 'exchangerateApi', 'wise', 'currencyData', 'exchangeRatesData', 'duckduckgo', 'wsj', 'xRates', 'valutafx', 'baidu', 'unionpay', 'jsdelivrFile', 'it120', 'k780']; /** * @param string $target target Currency @@ -22,9 +22,7 @@ class CurrencyExchange */ public static function convert(string $target, float|int $amount, ?string $base = null): ?float { - if ($base === null) { - $base = (string) sysConfig('standard_currency'); - } + $base = $base ?? (string) sysConfig('standard_currency'); $cacheKey = "Currency_{$base}_{$target}_ExRate"; if (Cache::has($cacheKey)) { @@ -34,7 +32,7 @@ class CurrencyExchange foreach (self::$apis as $api) { try { - $rate = self::callApis($api, $base, $target); + $rate = self::$api($base, $target); if ($rate !== null) { Cache::put($cacheKey, $rate, Day); @@ -42,8 +40,6 @@ class CurrencyExchange } } catch (Exception $e) { Log::error("[$api] 币种汇率信息获取报错: ".$e->getMessage()); - - continue; } } @@ -55,24 +51,20 @@ class CurrencyExchange self::$basicRequest = Http::timeout(15)->withOptions(['http_errors' => false])->withUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'); } - private static function callApis(string $api, string $base, string $target): ?float + public static function unionTest(string $target, ?string $base = null): void { - return match ($api) { - 'exchangerateApi' => self::exchangerateApi($base, $target), - 'k780' => self::k780($base, $target), - 'it120' => self::it120($base, $target), - 'exchangerate' => self::exchangerate($base, $target), - 'fixer' => self::fixer($base, $target), - 'currencyData' => self::currencyData($base, $target), - 'exchangeRatesData' => self::exchangeRatesData($base, $target), - 'jsdelivrFile' => self::jsdelivrFile($base, $target), - 'duckduckgo' => self::duckduckgo($base, $target), - 'wise' => self::wise($base, $target), - 'wsj' => self::wsj($base, $target), - 'valutafx' => self::valutafx($base, $target), - 'unionpay' => self::unionpay($base, $target), - 'baidu' => self::baidu($base, $target), - }; + $base = $base ?? (string) sysConfig('standard_currency'); + self::setClient(); + foreach (self::$apis as $api) { + try { + echo $api.': '.self::$api($base, $target).PHP_EOL; + } catch (Exception $e) { + echo $api.': error'.PHP_EOL; + Log::error("[$api] 币种汇率信息获取报错: ".$e->getMessage()); + + continue; + } + } } private static function exchangerateApi(string $base, string $target): ?float @@ -87,7 +79,7 @@ class CurrencyExchange if ($data['result'] === 'success') { return $key ? $data['conversion_rate'] : $data['rates'][$target]; } - Log::emergency('[CurrencyExchange]exchangerateApi exchange failed with following message: '.$data['error-type']); + Log::emergency('[CurrencyExchange]exchangerateApi exchange failed with following message: '.$data['error-type'] ?? ''); } else { Log::emergency('[CurrencyExchange]exchangerateApi request failed '.var_export($response, true)); } @@ -114,42 +106,29 @@ class CurrencyExchange private static function it120(string $base, string $target): ?float { // Reference: https://www.it120.cc/help/fnun8g.html - $response = self::$basicRequest->get("https://api.it120.cc/gooking/forex/rate?fromCode=$target&toCode=$base"); - if ($response->ok()) { - $data = $response->json(); + $key = config('services.currency.it120_key'); + if ($key) { + $response = self::$basicRequest->get("https://api.it120.cc/$key/forex/rate?fromCode=$target&toCode=$base"); + if ($response->ok()) { + $data = $response->json(); - if ($data['code'] === 0) { - return $data['data']['rate']; + if ($data['code'] === 0) { + return $data['data']['rate']; + } + Log::emergency('[CurrencyExchange]it120 exchange failed with following message: '.$data['msg']); + } else { + Log::emergency('[CurrencyExchange]it120 request failed'.var_export($response, true)); } - Log::emergency('[CurrencyExchange]it120 exchange failed with following message: '.$data['msg']); - } else { - Log::emergency('[CurrencyExchange]it120 request failed'.var_export($response, true)); } return null; } - private static function exchangerate(string $base, string $target): ?float - { // Reference: https://exchangerate.host/#/ - $response = self::$basicRequest->get("https://api.exchangerate.host/latest?base=$base&symbols=$target"); - if ($response->ok()) { - $data = $response->json(); - - if ($data['success'] && $data['base'] === $base) { - return $data['rates'][$target]; - } - Log::emergency('[CurrencyExchange]exchangerate exchange failed with following message: '.$data['error-type']); - } - Log::emergency('[CurrencyExchange]exchangerate request failed'); - - return null; - } - private static function fixer(string $base, string $target): ?float { // Reference: https://apilayer.com/marketplace/fixer-api RATE LIMIT: 100 Requests / Monthly!!!! $key = config('services.currency.apiLayer_key'); if ($key) { - $response = self::$basicRequest->withHeaders(['apikey' => $key])->get("https://api.apilayer.com/fixer/latest?symbols=$target&base=$base"); + $response = self::$basicRequest->withHeader('apikey', $key)->get("https://api.apilayer.com/fixer/latest?symbols=$target&base=$base"); if ($response->ok()) { $data = $response->json(); @@ -170,7 +149,7 @@ class CurrencyExchange { // Reference: https://apilayer.com/marketplace/currency_data-api RATE LIMIT: 100 Requests / Monthly $key = config('services.currency.apiLayer_key'); if ($key) { - $response = self::$basicRequest->withHeaders(['apikey' => $key])->get("https://api.apilayer.com/currency_data/live?source=$base¤cies=$target"); + $response = self::$basicRequest->withHeader('apikey', $key)->get("https://api.apilayer.com/currency_data/live?source=$base¤cies=$target"); if ($response->ok()) { $data = $response->json(); @@ -209,11 +188,11 @@ class CurrencyExchange private static function jsdelivrFile(string $base, string $target): ?float { // Reference: https://github.com/fawazahmed0/currency-api - $response = self::$basicRequest->get('https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies/'.strtolower($base).'/'.strtolower($target).'.min.json'); + $response = self::$basicRequest->get('https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/'.strtolower($base).'.min.json'); if ($response->ok()) { $data = $response->json(); - return $data[strtolower($target)]; + return $data[strtolower($base)][strtolower($target)]; } return null; @@ -225,7 +204,7 @@ class CurrencyExchange if ($response->ok()) { $data = $response->json(); - return $data['conversion']['converted-amount']; + return $data['to'][0]['mid']; } return null; @@ -233,7 +212,7 @@ class CurrencyExchange private static function wise(string $base, string $target): ?float { // Reference: https://wise.com/zh-cn/currency-converter/ - $response = self::$basicRequest->withHeaders(['Authorization' => 'Basic OGNhN2FlMjUtOTNjNS00MmFlLThhYjQtMzlkZTFlOTQzZDEwOjliN2UzNmZkLWRjYjgtNDEwZS1hYzc3LTQ5NGRmYmEyZGJjZA=='])->get("https://api.wise.com/v1/rates?source=$base&target=$target"); + $response = self::$basicRequest->withHeader('Authorization', 'Basic OGNhN2FlMjUtOTNjNS00MmFlLThhYjQtMzlkZTFlOTQzZDEwOjliN2UzNmZkLWRjYjgtNDEwZS1hYzc3LTQ5NGRmYmEyZGJjZA==')->get("https://api.wise.com/v1/rates?source=$base&target=$target"); if ($response->ok()) { $data = $response->json(); @@ -256,13 +235,28 @@ class CurrencyExchange return null; } + private static function xRates(string $base, string $target): ?float + { // Reference: https://www.x-rates.com/ + $response = self::$basicRequest->get("https://www.x-rates.com/calculator/?from=$base&to=$target&amount=1"); + if ($response->ok()) { + $data = $response->body(); + preg_match('/([\d.]+)/', $data, $matches); + + return $matches[1]; + } + + return null; + } + private static function valutafx(string $base, string $target): ?float { // Reference: https://www.valutafx.com/convert/ $response = self::$basicRequest->get("https://www.valutafx.com/api/v2/rates/lookup?isoTo=$target&isoFrom=$base&amount=1"); if ($response->ok()) { $data = $response->json(); - return $data['Rate']; + if (! $data['ErrorMessage']) { + return $data['Rate']; + } } return null; @@ -285,29 +279,17 @@ class CurrencyExchange } private static function baidu(string $base, string $target): ?float - { // Reference: https://www.unionpayintl.com/cn/rate/ - $response = self::$basicRequest->get("https://finance.pae.baidu.com/vapi/async?from_money=$base&to_money=$target&srcid=5293"); + { + $response = self::$basicRequest->get("https://finance.pae.baidu.com/vapi/async/v1?from_money=$base&to_money=$target&srcid=5293"); if ($response->ok()) { $data = $response->json(); - return $data['Result'][0]['DisplayData']['resultData']['tplData']['money2_num']; + if ($data['ResultCode'] !== -1) { + return $data['Result'][0]['DisplayData']['resultData']['tplData']['money2_num']; + } } return null; } - - public static function unionTest(string $target, ?string $base = null): void - { - self::setClient(); - foreach (self::$apis as $api) { - try { - echo $api.': '.self::callApis($api, $base, $target).PHP_EOL; - } catch (Exception $e) { - Log::error("[$api] 币种汇率信息获取报错: ".$e->getMessage()); - - continue; - } - } - } } diff --git a/app/Utils/Helpers.php b/app/Utils/Helpers.php index aa832230..79f65cb2 100644 --- a/app/Utils/Helpers.php +++ b/app/Utils/Helpers.php @@ -12,6 +12,7 @@ use App\Models\UserDataModifyLog; use App\Models\UserLoginLog; use App\Models\UserSubscribe; use Log; +use RuntimeException; use Str; class Helpers @@ -75,27 +76,30 @@ class Helpers public static function getPort(): int { // 获取一个有效端口 - if (sysConfig('is_rand_port')) { - $port = self::getRandPort(); - } else { - $port = (int) sysConfig('min_port'); - $exists_port = array_merge(User::where('port', '>=', $port)->pluck('port')->toArray(), self::$denyPorts); + $minPort = (int) sysConfig('min_port'); + $maxPort = (int) sysConfig('max_port'); + $isRandPort = sysConfig('is_rand_port'); + $occupiedPorts = array_merge(User::where('port', '!=', 0)->pluck('port')->toArray(), self::$denyPorts); - while (in_array($port, $exists_port, true)) { - $port++; - } + $totalPorts = $maxPort - $minPort + 1; + $availablePortsCount = $totalPorts - count($occupiedPorts); + + if ($availablePortsCount === 0) { + throw new RuntimeException('No available port found.'); } - return $port; - } - - private static function getRandPort(): int - { // 获取一个随机端口 - $port = random_int(sysConfig('min_port'), sysConfig('max_port')); - $exists_port = array_merge(User::where('port', '<>', 0)->pluck('port')->toArray(), self::$denyPorts); - - while (in_array($port, $exists_port, true)) { - $port = random_int(sysConfig('min_port'), sysConfig('max_port')); + if ($isRandPort) { + do { + $port = random_int($minPort, $maxPort); + } while (in_array($port, $occupiedPorts, true)); + } else { + $port = $minPort; + while (in_array($port, $occupiedPorts, true)) { + $port++; + if ($port > $maxPort) { + throw new RuntimeException('No available port found.'); + } + } } return $port; diff --git a/config/services.php b/config/services.php index 986386eb..7dde544c 100644 --- a/config/services.php +++ b/config/services.php @@ -98,6 +98,7 @@ return [ 'currency' => [ 'exchangerate-api_key' => env('EXCAHNGERATE_API_KEY'), 'apiLayer_key' => env('API_LAYER_API_KEY'), + 'it120_key' => env('IT120_KEY'), ], ]; diff --git a/public/update/ssr-win-4.0.xml b/public/update/ssr-win-4.0.xml deleted file mode 100644 index e69de29b..00000000 diff --git a/resources/lang/en.json b/resources/lang/en.json index 0a6fc07f..74b7fe27 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -40,6 +40,8 @@ "[Auto Task] Blocked service: Abnormal traffic within 1 hour": "[Auto Task] Blocked service: Abnormal traffic within 1 hour", "[Auto Task] Blocked service: Run out of traffic": "[Auto Task] Blocked service: Run out of traffic", "[Auto Task] Blocked Subscription: Subscription with abnormal requests within 24 hours": "[Auto Task] Blocked Subscription: Subscription with abnormal requests within 24 hours", + "[Auto Task] Unblocked Service: Account ban expired": "[Auto Task] Unblocked service: Account ban expired", + "[Auto Task] Unblocked Service: Account has available data traffic": "[Auto Task] Unblocked service: Account has available data traffic", "[Daily Task] Account Expiration: Block Login & Clear Account": "[Daily Task] Account Expiration: Block Login & Clear Account", "[Daily Task] Account Expiration: Stop Service": "[Daily Task] Account Expiration: Stop Service", "[Daily Task] Reset Account Traffic, Next Reset Date: :date": "[Daily Task] Reset Account Traffic, Next Reset Date: :date", diff --git a/resources/views/admin/index.blade.php b/resources/views/admin/index.blade.php index a49aea8b..6e7cb055 100644 --- a/resources/views/admin/index.blade.php +++ b/resources/views/admin/index.blade.php @@ -46,6 +46,11 @@ {{ trans('admin.dashboard.paid_users') }}
{{$payingUserCount}} + @if ($payingNewUserCount) + + {{$payingNewUserCount}} + + @endif