diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 5e18e20..8a900b8 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,6 +2,7 @@ namespace App\Console; +use App\Jobs\Cost; use Illuminate\Console\Scheduling\Schedule; use App\Http\Controllers\Admin\ServerController; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; @@ -17,7 +18,7 @@ protected function schedule(Schedule $schedule): void (new ServerController())->checkServer(); })->everyMinute()->name('FrpServer')->withoutOverlapping()->onOneServer(); - // $schedule->job(new Cost())->hourly()->name('FrpServerCost')->withoutOverlapping()->onOneServer(); + $schedule->job(new Cost())->hourly()->name('FrpServerCost')->withoutOverlapping()->onOneServer(); // every three days // $schedule->job(new ReviewWebsiteJob())->daily()->name('reviewWebsiteJob')->withoutOverlapping()->onOneServer(); diff --git a/app/Http/Controllers/Api/PortManagerController.php b/app/Http/Controllers/Api/PortManagerController.php index 34a7f93..b8258bf 100644 --- a/app/Http/Controllers/Api/PortManagerController.php +++ b/app/Http/Controllers/Api/PortManagerController.php @@ -34,6 +34,12 @@ public function handler(Request $request, $key) return $this->failed('此服务器暂时不接受新的连接。'); } + // cache + $cache_key = 'frpTunnel_data_' . $request->input('content')['proxy_name'] . '_lock'; + if (Cache::has($cache_key)) { + return $this->failed('此隧道正在被操作,请稍后再试。'); + } + // Search tunnel $host = Tunnel::where('client_token', $request->input('content')['proxy_name'])->where('server_id', $server->id)->first(); if (is_null($host)) { diff --git a/app/Http/Controllers/Api/TunnelController.php b/app/Http/Controllers/Api/TunnelController.php index f2f1753..ea7f2f5 100644 --- a/app/Http/Controllers/Api/TunnelController.php +++ b/app/Http/Controllers/Api/TunnelController.php @@ -2,12 +2,14 @@ namespace App\Http\Controllers\Api; -use App\Http\Controllers\Controller; -use App\Http\Requests\TunnelRequest; use App\Models\Server; use App\Models\Tunnel; -use Illuminate\Http\Request; use Illuminate\Support\Str; +use Illuminate\Http\Request; +use App\Http\Controllers\Controller; +use App\Http\Requests\TunnelRequest; +use App\Support\Frp; +use Illuminate\Support\Facades\Cache; class TunnelController extends Controller { @@ -150,7 +152,21 @@ public function store(Request $request) public function show(TunnelRequest $tunnelRequest, Tunnel $tunnel) { unset($tunnelRequest); + + $tunnel->load('server'); + $tunnel['config'] = $tunnel->getConfig(); + + $frp = new Frp($tunnel->server); + $traffic = $frp->traffic($tunnel->client_token) ?? []; + + if (!$traffic) { + $traffic = []; + } + + + $tunnel['traffic'] = $traffic; + return $this->success($tunnel); } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 02a4406..bb27177 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -12,6 +12,7 @@ public function index(Request $request) return view('spa'); } - return view('index'); + return redirect()->route('login'); + // return view('index'); } } diff --git a/app/Http/Controllers/SpaController.php b/app/Http/Controllers/SpaController.php deleted file mode 100644 index 1eca838..0000000 --- a/app/Http/Controllers/SpaController.php +++ /dev/null @@ -1,15 +0,0 @@ -http = Http::remote('remote')->asForm(); - - Server::with('hosts')->where('status', 'up')->whereNot('price_per_gb', 0)->chunk(100, function ($servers) { + Server::with('tunnels')->where('status', 'up')->chunk(100, function ($servers) { foreach ($servers as $server) { - // $ServerCheckJob = new ServerCheckJob($server->id); - // $ServerCheckJob->handle(); - foreach ($server->hosts as $host) { + foreach ($server->tunnels as $host) { $host->load('user'); Log::debug('------------'); @@ -41,15 +33,11 @@ public function handle_old() Log::debug('属于用户: ' . $host->user->name); $cache_key = 'frpTunnel_data_' . $host->client_token; - // $tunnel = 'frp_user_' . $host->client_token; - // $tunnel_user_id = Cache::get($tunnel); $tunnel_data = Cache::get($cache_key, null); if (!is_null($tunnel_data)) { $traffic = ($tunnel_data['today_traffic_in'] ?? 0) + ($tunnel_data['today_traffic_out'] ?? 0); - // $traffic = 1073741824 * 10; - Log::debug('本次使用的流量: ' . round($traffic / 1024 / 1024 / 1024, 2) ?? 0); $day = date('d'); @@ -63,7 +51,6 @@ public function handle_old() $used_traffic_gb = round($used_traffic / 1024 / 1024 / 1024, 2); - // Log::debug('上次使用的流量: ' . $used_traffic); Log::debug('上次使用的流量 GB: ' . $used_traffic_gb); $used_traffic = $traffic - $used_traffic; @@ -73,47 +60,11 @@ public function handle_old() $left_traffic = 0; - if ($host->user->free_traffic > 0) { - Log::debug('开始扣除免费流量时的 used_traffic: ' . round($used_traffic / 1024 / 1024 / 1024, 2)); - - $user_free_traffic = round($host->user->free_traffic * 1024 * 1024 * 1024, 2); - - Log::debug('用户免费流量: ' . round($user_free_traffic / 1024 / 1024 / 1024, 2)); - - // $used_traffic -= $user_free_traffic; - // $used_traffic = abs($used_traffic); - - Log::debug('扣除免费流量时的 used_traffic: ' . $used_traffic / 1024 / 1024 / 1024); - - // 获取剩余 - $left_traffic = $user_free_traffic - $used_traffic; - - Log::debug('计算后剩余的免费流量: ' . $left_traffic / 1024 / 1024 / 1024); - - // 保存 - - if ($left_traffic < 0) { - $left_traffic = 0; - } - - // 保留两位小数 - $left_traffic = round($left_traffic / 1024 / 1024 / 1024, 2); - - $host->user->free_traffic = $left_traffic; - $host->user->save(); - } $used_traffic = abs($used_traffic); Log::debug('实际用量:' . $used_traffic / 1024 / 1024 / 1024); - // $used_traffic -= $server->free_traffic * 1024 * 1024 * 1024; - // // $used_traffic = abs($used_traffic); - - // Log::debug('服务器免费流量: ' . $server->free_traffic * 1024 * 1024 * 1024); - - // Log::debug('使用的流量(减去服务器免费流量): ' . $used_traffic); - if ($used_traffic > 0 && $left_traffic == 0) { Log::debug('此时 used_traffic: ' . $used_traffic); @@ -124,24 +75,10 @@ public function handle_old() $gb = round($traffic, 2); - // 计算价格 - $cost = $traffic * $host->server->price_per_gb; - $cost = abs($cost); + Log::debug('此时 traffic: ' . $traffic); - // 记录到日志 - // if local - // if (config('app.env') == 'local') { - Log::debug('计费:' . $host->server->name . ' ' . $host->name . ' ' . $gb . 'GB ' . $cost . ' 的 CNY 消耗'); - // } - - // 如果计费金额大于 0,则扣费 - if ($cost > 0) { - // 发送扣费请求 - $this->http->post('hosts/' . $host->host_id . '/cost', [ - 'amount' => $cost, - 'description' => $host->name . ' 的 ' . $gb . ' GB 流量费用。', - ]); - } + // lock for update + $host->user->balance -= $traffic * $host->user->cost; } } } diff --git a/app/Models/Tunnel.php b/app/Models/Tunnel.php index 0cc5c98..820c4e8 100644 --- a/app/Models/Tunnel.php +++ b/app/Models/Tunnel.php @@ -56,6 +56,9 @@ public function close() $cache_key = 'frpTunnel_data_' . $this->client_token; Cache::forget($cache_key); + $cache_key = 'frpTunnel_data_' . $this->client_token . '_lock'; + Cache::put($cache_key, 1, 30); + $this->run_id = null; $this->saveQuietly(); } diff --git a/app/Models/User.php b/app/Models/User.php index 10f66bc..9b072e9 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -22,7 +22,7 @@ class User extends Authenticatable 'name', 'email', 'password', - 'auth_code' + 'traffic' ]; /** diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 444fafb..1d58bb5 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -17,6 +17,9 @@ public function up(): void $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); + + $table->bigInteger('traffic')->default(0)->comment('流量'); + $table->rememberToken(); $table->timestamps(); }); diff --git a/resources/js/views/Index.vue b/resources/js/views/Index.vue index a123933..67f2f1f 100644 --- a/resources/js/views/Index.vue +++ b/resources/js/views/Index.vue @@ -1,24 +1,24 @@ diff --git a/resources/js/views/Tunnels/Active.vue b/resources/js/views/Tunnels/Active.vue deleted file mode 100644 index f7c8a34..0000000 --- a/resources/js/views/Tunnels/Active.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/resources/js/views/Tunnels/Index.vue b/resources/js/views/Tunnels/Index.vue index 7b25271..73a5de8 100644 --- a/resources/js/views/Tunnels/Index.vue +++ b/resources/js/views/Tunnels/Index.vue @@ -9,9 +9,9 @@ 协议 本地地址 远程端口/域名 - 连接数 + 服务器 状态 @@ -52,9 +52,9 @@ - 0 - 0.000 Bytes + {{ tunnel.server.name }} diff --git a/resources/js/views/Tunnels/Show.vue b/resources/js/views/Tunnels/Show.vue index 7cb51dd..e05552c 100644 --- a/resources/js/views/Tunnels/Show.vue +++ b/resources/js/views/Tunnels/Show.vue @@ -4,7 +4,7 @@
-
+
@@ -16,6 +16,10 @@
+ +

强制下线

@@ -34,6 +38,7 @@ import { onMounted, onUnmounted, ref } from "vue"; import http from "../../plugins/http"; import router from "../../plugins/router"; import * as echarts from "echarts"; +import Humanize from 'humanize-plus' const showChart = ref(false); let chart = undefined; @@ -128,11 +133,13 @@ let chartOptions = { function initChart() { let chartDom = document.getElementById("chart"); + chart = echarts.init(chartDom, { backgroundColor: "transparent", renderer: "svg", }); + chartOptions && chart.setOption(chartOptions); } @@ -147,7 +154,9 @@ function deleteTunnel() { } function kickTunnel() { - http.post(`/tunnels/${tunnel_id}/close`); + http.post(`/tunnels/${tunnel_id}/close`).then(() => { + refresh(); + }); } function refresh() { @@ -160,8 +169,12 @@ function refresh() { // console.log(res.data); if (res.data.traffic) { + + console.log(res.data.traffic) + console.log(showChart.value) + if (!showChart.value) { - // initChart() + initChart() showChart.value = true; } diff --git a/resources/views/admin/users/index.blade.php b/resources/views/admin/users/index.blade.php index 9bf4fbf..23b4eb0 100644 --- a/resources/views/admin/users/index.blade.php +++ b/resources/views/admin/users/index.blade.php @@ -57,7 +57,7 @@