改进
This commit is contained in:
parent
7f5bd004a2
commit
fe04c15a07
@ -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();
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ public function index(Request $request)
|
||||
return view('spa');
|
||||
}
|
||||
|
||||
return view('index');
|
||||
return redirect()->route('login');
|
||||
// return view('index');
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SpaController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
// return view('spa');
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Host;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@ -10,30 +9,23 @@
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class Cost implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
private $http;
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle_old()
|
||||
public function handle()
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class User extends Authenticatable
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
'auth_code'
|
||||
'traffic'
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -1,24 +1,24 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Index</h1>
|
||||
<p>Index page</p>
|
||||
<p>Current time: {{ time }}</p>
|
||||
<h1>欢迎</h1>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>用户名: {{ user.name }}</p>
|
||||
<div class="mt-3">
|
||||
<p>用户名: {{ user.name }}</p>
|
||||
<p>剩余流量: {{ user.traffic }}GB</p>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import http from '../plugins/http'
|
||||
const time = ref(new Date().toLocaleTimeString());
|
||||
|
||||
|
||||
const user = ref({
|
||||
name: 'loading...'
|
||||
|
||||
name: 'loading...',
|
||||
traffic: ''
|
||||
})
|
||||
|
||||
http.get('user').then((res) => {
|
||||
@ -26,9 +26,4 @@ http.get('user').then((res) => {
|
||||
})
|
||||
|
||||
|
||||
http.get('tunnels').then((res) => {
|
||||
console.log(res.data)
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
@ -1,3 +0,0 @@
|
||||
<template>
|
||||
<h1>您名下的隧道</h1>
|
||||
</template>
|
@ -9,9 +9,9 @@
|
||||
<th scope="col">协议</th>
|
||||
<th scope="col">本地地址</th>
|
||||
<th scope="col">远程端口/域名</th>
|
||||
<th scope="col">连接数</th>
|
||||
<!-- <th scope="col">连接数</th>
|
||||
<th scope="col">下载流量</th>
|
||||
<th scope="col">上载流量</th>
|
||||
<th scope="col">上载流量</th> -->
|
||||
<th scope="col">服务器</th>
|
||||
<th scope="col">状态</th>
|
||||
</tr>
|
||||
@ -52,9 +52,9 @@
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td>0</td>
|
||||
<td>0.000 Bytes</td>
|
||||
<!-- <td>0</td>
|
||||
<td>0.000 Bytes</td>
|
||||
<td>0.000 Bytes</td> -->
|
||||
|
||||
<td>{{ tunnel.server.name }}</td>
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div v-show="chart" id="chart" style="height: 400px"></div>
|
||||
<div id="chart" style="height: 400px"></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@ -16,6 +16,10 @@
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<!-- <div v-if="tunnel.tunnel">
|
||||
|
||||
</div> -->
|
||||
|
||||
<div v-if="tunnel.run_id" class="mb-3">
|
||||
<h2>强制下线</h2>
|
||||
<button class="btn btn-primary" @click="kickTunnel()">强制下线</button>
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@
|
||||
|
||||
<script>
|
||||
function updateTraffic(userId, input) {
|
||||
const url = '/users/' + userId
|
||||
const url = '/admin/users/' + userId
|
||||
// xml http request
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('PATCH', url);
|
||||
|
Loading…
Reference in New Issue
Block a user