Browse Source

🔄 Dynamic Loading of DDNS Class

BrettonYe 1 year ago
parent
commit
70c7510028

+ 6 - 1
app/Http/Controllers/Admin/SystemController.php

@@ -15,6 +15,7 @@ use App\Http\Requests\Admin\SystemRequest;
 use App\Models\Config;
 use App\Notifications\Custom;
 use App\Services\TelegramService;
+use App\Utils\DDNS;
 use Auth;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\RedirectResponse;
@@ -28,7 +29,11 @@ class SystemController extends Controller
     // 系统设置
     public function index()
     {
-        return view('admin.config.system', array_merge(['payments' => $this->getPayment(), 'captcha' => $this->getCaptcha()], Config::pluck('value', 'name')->toArray()));
+        return view('admin.config.system', array_merge([
+            'payments' => $this->getPayment(),
+            'captcha' => $this->getCaptcha(),
+            'ddns_labels' => (new DDNS())->getLabels(),
+        ], Config::pluck('value', 'name')->toArray()));
     }
 
     private function getPayment(): array

+ 34 - 21
app/Http/Controllers/AdminController.php

@@ -16,6 +16,7 @@ use App\Models\ReferralLog;
 use App\Models\SsConfig;
 use App\Models\User;
 use App\Models\UserHourlyDataFlow;
+use Cache;
 use DB;
 use Illuminate\Http\JsonResponse;
 use Log;
@@ -30,34 +31,50 @@ class AdminController extends Controller
     public function index()
     {
         $past = strtotime('-'.sysConfig('expire_days').' days');
-        $dailyTrafficUsage = NodeHourlyDataFlow::whereDate('created_at', date('Y-m-d'))->sum(DB::raw('u + d'));
+        $today = today();
+
+        $stats = Cache::remember('user_stats', now()->addMinutes(5), function () use ($today, $past) {
+            $dailyTrafficUsage = NodeHourlyDataFlow::whereDate('created_at', $today)->sum(DB::raw('u + d'));
+
+            return [
+                'activeUserCount' => User::where('t', '>=', $past)->count(), // 活跃用户数
+                'inactiveUserCount' => User::whereEnable(1)->where('t', '<', $past)->count(), // 不活跃用户数
+                'expireWarningUserCount' => User::whereBetween('expired_at', [$today, today()->addDays(sysConfig('expire_days'))])->count(), // 临近过期用户数
+                'largeTrafficUserCount' => User::whereRaw('(u + d)/transfer_enable >= 0.9')->where('status', '<>', -1)->count(), // 流量使用超过90%的用户
+                'flowAbnormalUserCount' => count((new UserHourlyDataFlow)->trafficAbnormal()), // 1小时内流量异常用户
+                'monthlyTrafficUsage' => formatBytes(NodeDailyDataFlow::whereMonth('created_at', now()->month)->sum(DB::raw('u + d'))),
+                'dailyTrafficUsage' => $dailyTrafficUsage ? formatBytes($dailyTrafficUsage) : 0,
+                'totalTrafficUsage' => formatBytes(NodeDailyDataFlow::sum(DB::raw('u + d'))),
+            ];
+        });
 
         return view('admin.index', [
             'totalUserCount' => User::count(), // 总用户数
-            'todayRegister' => User::whereDate('created_at', date('Y-m-d'))->count(), // 今日注册用户
+            'todayRegister' => User::whereDate('created_at', $today)->count(), // 今日注册用户
             'enableUserCount' => User::whereEnable(1)->count(), // 有效用户数
-            'activeUserCount' => User::where('t', '>=', $past)->count(), // 活跃用户数,
-            'payingUserCount' => Order::whereStatus(2)->where('goods_id', '<>', null)->whereIsExpire(0)->where('amount', '>', 0)->pluck('user_id')->unique()->count(), // 付费用户数
-            'inactiveUserCount' => User::whereEnable(1)->whereBetween('t', [1, $past])->count(), // 不活跃用户数
-            'onlineUserCount' => User::where('t', '>=', strtotime('-10 minutes'))->count(), // 10分钟内在线用户数
-            'expireWarningUserCount' => User::whereBetween('expired_at', [date('Y-m-d'), date('Y-m-d', strtotime(sysConfig('expire_days').' days'))])->count(), // 临近过期用户数
-            'largeTrafficUserCount' => User::whereRaw('(u + d)/transfer_enable >= 0.9')->where('status', '<>', -1)->count(), // 流量使用超过90%的用户
-            'flowAbnormalUserCount' => count((new UserHourlyDataFlow)->trafficAbnormal()), // 1小时内流量异常用户
+            'activeUserCount' => $stats['activeUserCount'],
+            'payingUserCount' => User::has('paidOrders')->count(), // 付费用户数
+            'payingNewUserCount' => User::whereDate('created_at', $today)->has('paidOrders')->count(), // 不活跃用户数
+            'inactiveUserCount' => $stats['inactiveUserCount'],
+            'onlineUserCount' => User::where('t', '>=', strtotime('-10 minutes'))->count(), // 10分钟内在线用户数,
+            'expireWarningUserCount' => $stats['expireWarningUserCount'],
+            'largeTrafficUserCount' => $stats['largeTrafficUserCount'],
+            'flowAbnormalUserCount' => $stats['flowAbnormalUserCount'],
             'nodeCount' => Node::count(),
             'abnormalNodeCount' => Node::whereStatus(0)->count(),
-            'monthlyTrafficUsage' => formatBytes(NodeDailyDataFlow::whereMonth('created_at', date('n'))->sum(DB::raw('u + d'))),
-            'dailyTrafficUsage' => $dailyTrafficUsage ? formatBytes($dailyTrafficUsage) : 0,
-            'totalTrafficUsage' => formatBytes(NodeDailyDataFlow::sum(DB::raw('u + d'))),
+            'monthlyTrafficUsage' => $stats['monthlyTrafficUsage'],
+            'dailyTrafficUsage' => $stats['dailyTrafficUsage'],
+            'totalTrafficUsage' => $stats['totalTrafficUsage'],
             'totalCredit' => User::where('credit', '<>', 0)->sum('credit') / 100,
             'totalWaitRefAmount' => ReferralLog::whereIn('status', [0, 1])->sum('commission') / 100,
-            'todayWaitRefAmount' => ReferralLog::whereIn('status', [0, 1])->whereDate('created_at', date('Y-m-d'))->sum('commission') / 100,
+            'todayWaitRefAmount' => ReferralLog::whereIn('status', [0, 1])->whereDate('created_at', $today)->sum('commission') / 100,
             'totalRefAmount' => ReferralApply::whereStatus(2)->sum('amount') / 100,
             'totalOrder' => Order::count(),
-            'todayOrder' => Order::whereDate('created_at', date('Y-m-d'))->count(),
+            'todayOrder' => Order::whereDate('created_at', $today)->count(),
             'totalOnlinePayOrder' => Order::where('pay_type', '<>', 0)->count(),
-            'todayOnlinePayOrder' => Order::where('pay_type', '<>', 0)->whereDate('created_at', date('Y-m-d'))->count(),
+            'todayOnlinePayOrder' => Order::where('pay_type', '<>', 0)->whereDate('created_at', $today)->count(),
             'totalSuccessOrder' => Order::whereIn('status', [2, 3])->count(),
-            'todaySuccessOrder' => Order::whereIn('status', [2, 3])->whereDate('created_at', date('Y-m-d'))->count(),
+            'todaySuccessOrder' => Order::whereIn('status', [2, 3])->whereDate('created_at', $today)->count(),
         ]);
     }
 
@@ -89,11 +106,7 @@ class AdminController extends Controller
         $filename = '邀请码'.date('Ymd').'.xlsx';
 
         $spreadsheet = new Spreadsheet();
-        $spreadsheet->getProperties()
-            ->setCreator('ProxyPanel')
-            ->setLastModifiedBy('ProxyPanel')
-            ->setTitle('邀请码')
-            ->setSubject('邀请码');
+        $spreadsheet->getProperties()->setCreator('ProxyPanel')->setLastModifiedBy('ProxyPanel')->setTitle('邀请码')->setSubject('邀请码');
 
         try {
             $spreadsheet->setActiveSheetIndex(0);

+ 28 - 21
app/Utils/DDNS.php

@@ -2,17 +2,10 @@
 
 namespace App\Utils;
 
-use App\Utils\DDNS\AliYun;
-use App\Utils\DDNS\Baidu;
-use App\Utils\DDNS\CloudFlare;
-use App\Utils\DDNS\DigitalOcean;
-use App\Utils\DDNS\DNSPod;
-use App\Utils\DDNS\GoDaddy;
-use App\Utils\DDNS\Namecheap;
-use App\Utils\DDNS\Namesilo;
 use App\Utils\Library\Templates\DNS;
-use InvalidArgumentException;
+use Cache;
 use Log;
+use ReflectionClass;
 
 /**
  * Class DDNS 域名解析.
@@ -21,19 +14,19 @@ class DDNS
 {
     private DNS $dns;
 
-    public function __construct(private readonly string $domain)
+    public function __construct(private readonly ?string $domain = null)
     {
-        $this->dns = match (sysConfig('ddns_mode')) {
-            'aliyun' => new AliYun($domain),
-            'namesilo' => new Namesilo($domain),
-            'dnspod' => new DNSPod($domain),
-            'cloudflare' => new CloudFlare($domain),
-            'godaddy' => new GoDaddy($domain),
-            'namecheap' => new Namecheap($domain),
-            'digitalocean' => new DigitalOcean($domain),
-            'baidu' => new Baidu($domain),
-            default => throw new InvalidArgumentException('Invalid DDNS mode configuration'),
-        };
+        if ($domain) {
+            foreach (glob(app_path('Utils/DDNS').'/*.php') as $file) {
+                $class = 'App\\Utils\\DDNS\\'.basename($file, '.php');
+                $reflectionClass = new ReflectionClass($class);
+
+                if (sysConfig('ddns_mode') === $reflectionClass->getConstant('KEY')) {
+                    $this->dns = new $class($domain);
+                    break;
+                }
+            }
+        }
     }
 
     public function destroy(string $type = '', string $ip = ''): void
@@ -62,4 +55,18 @@ class DDNS
             Log::warning("【DDNS】添加:$ip => $this->domain 类型:$type 失败,请手动设置!");
         }
     }
+
+    public function getLabels(): array
+    {
+        return Cache::rememberForever('ddns_get_Labels_'.app()->getLocale(), static function () {
+            $labels[trans('common.status.closed')] = '';
+            foreach (glob(app_path('Utils/DDNS').'/*.php') as $file) {
+                $class = 'App\\Utils\\DDNS\\'.basename($file, '.php');
+                $reflectionClass = new ReflectionClass($class);
+                $labels[$reflectionClass->getConstant('LABEL')] = $reflectionClass->getConstant('KEY');
+            }
+
+            return $labels;
+        });
+    }
 }

+ 4 - 0
app/Utils/DDNS/AliYun.php

@@ -14,6 +14,10 @@ class AliYun implements DNS
     //  开发依据: https://api.aliyun.com/document/Alidns/2015-01-09/overview
     private const API_ENDPOINT = 'https://alidns.aliyuncs.com/';
 
+    public const KEY = 'aliyun';
+
+    public const LABEL = 'Alibaba Cloud | 阿里云';
+
     private string $accessKeyID;
 
     private string $accessKeySecret;

+ 4 - 0
app/Utils/DDNS/Baidu.php

@@ -14,6 +14,10 @@ class Baidu implements DNS
     // 开发依据: https://cloud.baidu.com/doc/DNS/index.html
     private const API_ENDPOINT = 'https://dns.baidubce.com';
 
+    public const KEY = 'baidu';
+
+    public const LABEL = 'Baidu AI Cloud | 百度智能云';
+
     private string $secretId;
 
     private string $secretKey;

+ 4 - 0
app/Utils/DDNS/CloudFlare.php

@@ -14,6 +14,10 @@ class CloudFlare implements DNS
     // 开发依据: https://developers.cloudflare.com/api/
     private string $apiEndpoint;
 
+    public const KEY = 'cloudflare';
+
+    public const LABEL = 'CloudFlare';
+
     private array $auth;
 
     public function __construct(private readonly string $subdomain)

+ 4 - 0
app/Utils/DDNS/DNSPod.php

@@ -14,6 +14,10 @@ class DNSPod implements DNS
     // 开发依据: https://docs.dnspod.cn/api/
     private const API_ENDPOINT = 'https://dnspod.tencentcloudapi.com';
 
+    public const KEY = 'dnspod';
+
+    public const LABEL = 'Tencent Cloud | DNSPod | 腾讯云';
+
     private string $secretId;
 
     private string $secretKey;

+ 4 - 0
app/Utils/DDNS/DigitalOcean.php

@@ -14,6 +14,10 @@ class DigitalOcean implements DNS
     //  开发依据:https://docs.digitalocean.com/products/networking/dns/how-to/manage-records/
     private const API_ENDPOINT = 'https://api.digitalocean.com/v2/domains';
 
+    public const KEY = 'digitalocean';
+
+    public const LABEL = 'DigitalOcean';
+
     private string $accessKeySecret;
 
     private array $domainInfo;

+ 4 - 0
app/Utils/DDNS/GoDaddy.php

@@ -14,6 +14,10 @@ class GoDaddy implements DNS
     //  开发依据: https://developer.godaddy.com/doc/endpoint/domains
     private const API_ENDPOINT = 'https://api.godaddy.com/v1/domains/';
 
+    public const KEY = 'godaddy';
+
+    public const LABEL = 'GoDaddy';
+
     private string $accessKeyID;
 
     private string $accessKeySecret;

+ 4 - 0
app/Utils/DDNS/Namecheap.php

@@ -15,6 +15,10 @@ class Namecheap implements DNS
     //  开发依据: https://www.namecheap.com/support/api/methods/
     private const API_ENDPOINT = 'https://api.namecheap.com/xml.response';
 
+    public const KEY = 'namecheap';
+
+    public const LABEL = 'Namecheap';
+
     private string $accessKeyID;
 
     private string $accessKeySecret;

+ 4 - 0
app/Utils/DDNS/Namesilo.php

@@ -13,6 +13,10 @@ class Namesilo implements DNS
     // 开发依据: https://www.namesilo.com/api-reference
     private const API_ENDPOINT = 'https://www.namesilo.com/api/';
 
+    public const KEY = 'namesilo';
+
+    public const LABEL = 'Namesilo';
+
     private string $apiKey;
 
     private array $domainInfo;

+ 0 - 6
resources/lang/en/admin.php

@@ -776,12 +776,6 @@ return [
             'before' => 'Pre-registration activation',
             'after' => 'Activate after registration',
         ],
-        'ddns' => [
-            'namesilo' => 'Namesilo',
-            'aliyun' => 'AliCloud/Aliyun',
-            'dnspod' => 'DNSPod',
-            'cloudflare' => 'CloudFlare',
-        ],
         'captcha' => [
             'standard' => 'Standard',
             'geetest' => 'Geetest',

+ 0 - 10
resources/lang/zh_CN/admin.php

@@ -776,16 +776,6 @@ return [
             'before' => '注册前激活',
             'after' => '注册后激活',
         ],
-        'ddns' => [
-            'namesilo' => 'Namesilo',
-            'aliyun' => '阿里云(国际&国内)',
-            'dnspod' => 'DNSPod',
-            'cloudflare' => 'CloudFlare',
-            'godaddy' => 'GoDaddy',
-            'namecheap' => 'Namecheap',
-            'digitalocean' => 'DigitalOcean',
-            'baidu' => '百度智能云',
-        ],
         'captcha' => [
             'standard' => '普通验证码',
             'geetest' => '极 验',

+ 1 - 1
resources/views/admin/config/system.blade.php

@@ -130,7 +130,7 @@
                             <x-system.input code="v2ray_tls_provider" :value="$v2ray_tls_provider"/>
                         </x-system.tab-pane>
                         <x-system.tab-pane id="extend">
-                            <x-system.select code="ddns_mode" :list="[trans('common.status.closed') => '', trans('admin.system.ddns.namesilo') => 'namesilo', trans('admin.system.ddns.aliyun') => 'aliyun', trans('admin.system.ddns.dnspod') =>  'dnspod', trans('admin.system.ddns.cloudflare') => 'cloudflare', trans('admin.system.ddns.godaddy') => 'godaddy', trans('admin.system.ddns.namecheap') => 'namecheap', trans('admin.system.ddns.digitalocean') => 'digitalocean', trans('admin.system.ddns.baidu') => 'baidu']"/>
+                            <x-system.select code="ddns_mode" :list="$ddns_labels"/>
                             <x-system.input code="ddns_key" :value="$ddns_key"/>
                             <x-system.input code="ddns_secret" :value="$ddns_secret"/>
                             <hr class="col-lg-12">