commit
74bf56b879
@ -2,18 +2,17 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
// if not login, redirect to login
|
||||
if (! Auth::guard('admin')->check()) {
|
||||
if (!Auth::guard('admin')->check()) {
|
||||
return view('admin.login');
|
||||
} else {
|
||||
$servers = Server::where('status', '!=', 'up')->get();
|
||||
@ -27,7 +26,8 @@ public function login(Request $request)
|
||||
// attempt to login
|
||||
if (Auth::guard('admin')->attempt($request->only(['email', 'password']), $request->has('remember'))) {
|
||||
// if success, redirect to home
|
||||
return redirect()->intended('/');
|
||||
// return redirect()->intended('admin.index');
|
||||
return redirect()->route('admin.index');
|
||||
} else {
|
||||
// if fail, redirect to login with error message
|
||||
return redirect()->back()->withErrors(['message' => '用户名或密码错误'])->withInput();
|
||||
|
@ -2,17 +2,17 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Support\Frp;
|
||||
use App\Models\Server;
|
||||
use Illuminate\View\View;
|
||||
use App\Jobs\ServerCheckJob;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use App\Jobs\ServerCheckJob;
|
||||
use App\Models\Server;
|
||||
use App\Support\Frp;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ServerController extends Controller
|
||||
{
|
||||
@ -30,20 +30,10 @@ public function index()
|
||||
return view('admin.servers.index', compact('servers'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('admin.servers.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
@ -67,78 +57,6 @@ public function store(Request $request)
|
||||
return redirect()->route('admin.servers.edit', $server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param Server $server
|
||||
* @return RedirectResponse|View
|
||||
*/
|
||||
public function show(Server $server)
|
||||
{
|
||||
try {
|
||||
$serverInfo = (object) (new Frp($server))->serverInfo();
|
||||
} catch (RequestException $e) {
|
||||
Log::error($e->getMessage());
|
||||
|
||||
return redirect()->route('admin.servers.index')->with('error', '服务器连接失败。');
|
||||
}
|
||||
|
||||
return view('admin.servers.show', compact('server'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param Server $server
|
||||
* @return View
|
||||
*/
|
||||
public function edit(Server $server)
|
||||
{
|
||||
$serverInfo = (object) (new Frp($server))->serverInfo();
|
||||
|
||||
return view('admin.servers.edit', compact('server', 'serverInfo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param Server $server
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function update(Request $request, Server $server)
|
||||
{
|
||||
if (! $request->has('status')) {
|
||||
$request->merge(['allow_http' => $request->has('allow_http') ? true : false]);
|
||||
$request->merge(['allow_https' => $request->has('allow_https') ? true : false]);
|
||||
$request->merge(['allow_tcp' => $request->has('allow_tcp') ? true : false]);
|
||||
$request->merge(['allow_udp' => $request->has('allow_udp') ? true : false]);
|
||||
$request->merge(['allow_stcp' => $request->has('allow_stcp') ? true : false]);
|
||||
$request->merge(['allow_xtcp' => $request->has('allow_xtcp') ? true : false]);
|
||||
$request->merge(['allow_sudp' => $request->has('allow_sudp') ? true : false]);
|
||||
$request->merge(['is_china_mainland' => $request->has('is_china_mainland') ? true : false]);
|
||||
}
|
||||
|
||||
$data = $request->all();
|
||||
|
||||
$server->update($data);
|
||||
|
||||
return redirect()->route('admin.servers.index')->with('success', '服务器成功更新。');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param Server $server
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function destroy(Server $server)
|
||||
{
|
||||
$server->delete();
|
||||
|
||||
return redirect()->route('admin.servers.index')->with('success', '服务器成功删除。');
|
||||
}
|
||||
|
||||
public function rules($id = null)
|
||||
{
|
||||
return [
|
||||
@ -165,6 +83,88 @@ public function rules($id = null)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('admin.servers.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param Server $server
|
||||
* @return RedirectResponse|View
|
||||
*/
|
||||
public function show(Server $server)
|
||||
{
|
||||
try {
|
||||
$serverInfo = (object)(new Frp($server))->serverInfo();
|
||||
} catch (RequestException $e) {
|
||||
Log::error($e->getMessage());
|
||||
|
||||
return redirect()->route('admin.servers.index')->with('error', '服务器连接失败。');
|
||||
}
|
||||
|
||||
return view('admin.servers.show', compact('server'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param Server $server
|
||||
* @return View
|
||||
*/
|
||||
public function edit(Server $server)
|
||||
{
|
||||
$serverInfo = (object)(new Frp($server))->serverInfo();
|
||||
|
||||
return view('admin.servers.edit', compact('server', 'serverInfo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param Server $server
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function update(Request $request, Server $server)
|
||||
{
|
||||
if (!$request->has('status')) {
|
||||
$request->merge(['allow_http' => $request->has('allow_http') ? true : false]);
|
||||
$request->merge(['allow_https' => $request->has('allow_https') ? true : false]);
|
||||
$request->merge(['allow_tcp' => $request->has('allow_tcp') ? true : false]);
|
||||
$request->merge(['allow_udp' => $request->has('allow_udp') ? true : false]);
|
||||
$request->merge(['allow_stcp' => $request->has('allow_stcp') ? true : false]);
|
||||
$request->merge(['allow_xtcp' => $request->has('allow_xtcp') ? true : false]);
|
||||
$request->merge(['allow_sudp' => $request->has('allow_sudp') ? true : false]);
|
||||
$request->merge(['is_china_mainland' => $request->has('is_china_mainland') ? true : false]);
|
||||
}
|
||||
|
||||
$data = $request->all();
|
||||
|
||||
$server->update($data);
|
||||
|
||||
return redirect()->route('admin.servers.index')->with('success', '服务器成功更新。');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param Server $server
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function destroy(Server $server)
|
||||
{
|
||||
$server->delete();
|
||||
|
||||
return redirect()->route('admin.servers.index')->with('success', '服务器成功删除。');
|
||||
}
|
||||
|
||||
public function checkServer($id = null)
|
||||
{
|
||||
if (is_null($id)) {
|
||||
@ -228,11 +228,11 @@ public function scanTunnel($server_id)
|
||||
private function cacheProxies($proxies)
|
||||
{
|
||||
foreach ($proxies as $proxy) {
|
||||
if (! isset($proxy['name'])) {
|
||||
if (!isset($proxy['name'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cache_key = 'frpTunnel_data_'.$proxy['name'];
|
||||
$cache_key = 'frpTunnel_data_' . $proxy['name'];
|
||||
|
||||
Cache::put($cache_key, $proxy, 86400);
|
||||
}
|
||||
@ -240,7 +240,7 @@ private function cacheProxies($proxies)
|
||||
|
||||
public function getTunnel($name)
|
||||
{
|
||||
$cache_key = 'frpTunnel_data_'.$name;
|
||||
$cache_key = 'frpTunnel_data_' . $name;
|
||||
|
||||
return Cache::get($cache_key);
|
||||
}
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Tunnel;
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Tunnel;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class TunnelController extends Controller
|
||||
{
|
||||
@ -31,7 +31,7 @@ public function index(Request $request)
|
||||
}
|
||||
|
||||
if ($request->{$key}) {
|
||||
$hosts = $hosts->where($key, 'LIKE', '%'.$value.'%');
|
||||
$hosts = $hosts->where($key, 'LIKE', '%' . $value . '%');
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ public function index(Request $request)
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param Tunnel $tunnel
|
||||
* @param Tunnel $tunnel
|
||||
* @return View
|
||||
*/
|
||||
public function show(Tunnel $tunnel)
|
||||
@ -58,8 +58,8 @@ public function show(Tunnel $tunnel)
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param Tunnel $tunnel
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param Tunnel $tunnel
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function update(Request $request, Tunnel $tunnel)
|
||||
@ -76,7 +76,7 @@ public function update(Request $request, Tunnel $tunnel)
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param Tunnel $host
|
||||
* @param Tunnel $host
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function destroy(Tunnel $host)
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
@ -25,7 +25,7 @@ public function index(Request $request)
|
||||
continue;
|
||||
}
|
||||
if ($request->{$key}) {
|
||||
$users = $users->where($key, 'LIKE', '%'.$value.'%');
|
||||
$users = $users->where($key, 'LIKE', '%' . $value . '%');
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ public function update(Request $request, User $user)
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param User $user
|
||||
* @param User $user
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function destroy(User $user)
|
||||
|
@ -2,13 +2,14 @@
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\WHMCS;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class TicketController extends Controller
|
||||
{
|
||||
public function submit(Request $request, string $provider) {
|
||||
public function submit(Request $request, string $provider)
|
||||
{
|
||||
$request->validate([
|
||||
'title' => 'required',
|
||||
'content' => 'required',
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\WHMCS;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
|
||||
class TrafficController extends Controller
|
||||
@ -87,7 +87,6 @@ public function charge(Request $request, string $provider)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,14 +2,13 @@
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Models\Tunnel;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\TunnelRequest;
|
||||
use App\Models\Server;
|
||||
use App\Models\Tunnel;
|
||||
use App\Support\Frp;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class TunnelController extends Controller
|
||||
{
|
||||
@ -176,7 +175,8 @@ public function show(TunnelRequest $tunnelRequest, Tunnel $tunnel)
|
||||
return $this->success($tunnel);
|
||||
}
|
||||
|
||||
public function close(TunnelRequest $tunnelRequest, Tunnel $tunnel) {
|
||||
public function close(TunnelRequest $tunnelRequest, Tunnel $tunnel)
|
||||
{
|
||||
unset($tunnelRequest);
|
||||
$tunnel->close();
|
||||
return $this->noContent();
|
||||
|
@ -7,11 +7,6 @@
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function user(Request $request)
|
||||
{
|
||||
return $this->success($request->user('sanctum'));
|
||||
}
|
||||
|
||||
public function create(Request $request)
|
||||
{
|
||||
$name = date('Y-m-d H:i:s');
|
||||
@ -22,6 +17,11 @@ public function create(Request $request)
|
||||
]);
|
||||
}
|
||||
|
||||
public function user(Request $request)
|
||||
{
|
||||
return $this->success($request->user('sanctum'));
|
||||
}
|
||||
|
||||
public function deleteAll(Request $request)
|
||||
{
|
||||
$request->user()->tokens()->delete();
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Http\Controllers\Application;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class UserController extends Controller
|
||||
@ -33,14 +33,6 @@ public function show(User $user)
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
@ -67,4 +59,12 @@ public function addTraffic(Request $request, User $user)
|
||||
'message' => 'success',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ public function callback(Request $request): RedirectResponse
|
||||
'redirect_uri' => config('oauth.callback_uri'),
|
||||
'code' => $request->input('code'),
|
||||
],
|
||||
// 'verify' => false,
|
||||
])->getBody();
|
||||
} catch (GuzzleException $e) {
|
||||
}
|
||||
@ -59,6 +60,7 @@ public function callback(Request $request): RedirectResponse
|
||||
'Accept' => 'application/json',
|
||||
'Authorization' => 'Bearer ' . $authorize->access_token,
|
||||
],
|
||||
// 'verify' => false
|
||||
])->getBody();
|
||||
} catch (GuzzleException $e) {
|
||||
}
|
||||
|
@ -68,11 +68,19 @@ private function request($action, $params = []): ?array
|
||||
], $params);
|
||||
|
||||
|
||||
$http = Http::asForm()->post($this->url . '/includes/api.php', $params)->throw();
|
||||
|
||||
$response = $http->body();
|
||||
$json = $http->json();
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $this->url . '/includes/api.php');
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt(
|
||||
$ch,
|
||||
CURLOPT_POSTFIELDS,
|
||||
http_build_query($params)
|
||||
);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$json = json_decode($response, true);
|
||||
|
||||
if (is_null($json)) {
|
||||
Log::error('WHMCS response is not valid JSON', [$response]);
|
||||
|
@ -9,7 +9,8 @@
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"laravel/framework": "^10.0",
|
||||
"laravel/sanctum": "^3.2",
|
||||
"laravel/tinker": "^2.8"
|
||||
"laravel/tinker": "^2.8",
|
||||
"twbs/bootstrap": "5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
|
58
composer.lock
generated
58
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "38e7ef326635a7b2292aab6f0e872fbe",
|
||||
"content-hash": "f39ffd8da21666501191e102ff07ba3d",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
@ -5191,6 +5191,62 @@
|
||||
},
|
||||
"time": "2023-01-03T09:29:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twbs/bootstrap",
|
||||
"version": "v5.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twbs/bootstrap.git",
|
||||
"reference": "60098ac499d30aa50575b0b7137391c06ef25429"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twbs/bootstrap/zipball/60098ac499d30aa50575b0b7137391c06ef25429",
|
||||
"reference": "60098ac499d30aa50575b0b7137391c06ef25429",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"replace": {
|
||||
"twitter/bootstrap": "self.version"
|
||||
},
|
||||
"type": "library",
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Otto",
|
||||
"email": "markdotto@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Jacob Thornton",
|
||||
"email": "jacobthornton@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
|
||||
"homepage": "https://getbootstrap.com/",
|
||||
"keywords": [
|
||||
"JS",
|
||||
"css",
|
||||
"framework",
|
||||
"front-end",
|
||||
"mobile-first",
|
||||
"responsive",
|
||||
"sass",
|
||||
"web"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twbs/bootstrap/issues",
|
||||
"source": "https://github.com/twbs/bootstrap/tree/v5.3.0"
|
||||
},
|
||||
"time": "2023-05-30T15:15:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "vlucas/phpdotenv",
|
||||
"version": "v5.5.0",
|
||||
|
@ -85,7 +85,7 @@
|
||||
|
|
||||
*/
|
||||
|
||||
'locale' => 'en',
|
||||
'locale' => 'zh',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -1 +1 @@
|
||||
import{r as l,o as t,c as o,a as e,t as v,j as y,v as w,F as b,e as C,b as p,g as f,l as B}from"./app-426d2bdb.js";import{i as m}from"./http-419d7b2b.js";const G=e("div",null,[e("h3",null,"流量充值")],-1),N=e("h5",null,"您要充值多少元的流量?",-1),T=f(" 每 GB 价格: "),U=f(" 元。 "),D={class:"input-group mb-3"},F=e("div",{class:"input-group-append"},[e("span",{class:"input-group-text"},"GB")],-1),M={key:0},j=f("大约 "),E=["textContent"],L=f(" 元。"),P={key:0},R=e("h5",{class:"mt-3"},"您将要使用哪个平台充值?",-1),S=e("p",null,"如果您在选中的平台没有账号,我们将会帮您自动创建一个。",-1),q={class:"form-group form-check"},z=["id","value"],A=["textContent","for"],H={key:1},I=e("h5",{class:"mt-3"},"暂时没有可用的",-1),J=[I],K={key:2},O=e("h5",{class:"mt-3"},"让我们来选择支付方式。",-1),Q=e("p",null,"在支付后,您的流量大概需要数秒钟到账。",-1),W={class:"form-group form-check"},X=["id","value"],Y=["textContent","for"],Z={key:3},$=["textContent","disabled"],ee={key:0},te={key:1,class:"mt-3"},oe=e("h5",null,"完成",-1),ne=e("p",null,"如果您浏览器没有打开新的创建,请点击以下链接来打开。",-1),se=["href"],ie={name:"Charge",setup(le){const g=l(0),u=l([]),i=l(""),r=l({}),d=l(""),c=l(10),h=l(""),_=l(!1);m.get("price").then(s=>{g.value=s.data.price_per_gb}),m.get("providers").then(s=>{u.value=s.data,u.value.length>0&&(i.value=u.value[0],x())});function x(){m.get("providers/"+i.value+"/payments").then(s=>{r.value=s.data,r.value.length>0&&(d.value=r.value[0].name)})}function V(){_.value=!0,m.post("providers/"+i.value+"/charge",{payment:d.value,traffic:c.value}).then(s=>{h.value=s.data.redirect_url,setTimeout(()=>{window.open(h.value,"_blank")})}).finally(()=>{_.value=!1})}return(s,a)=>(t(),o(b,null,[G,e("div",null,[N,e("p",null,[T,e("span",null,v(g.value),1),U]),e("div",D,[y(e("input",{autofocus:"",type:"number",class:"form-control",placeholder:"输入您要的流量 (单位: GB)","onUpdate:modelValue":a[0]||(a[0]=n=>c.value=n)},null,512),[[w,c.value]]),F]),c.value?(t(),o("div",M,[e("p",null,[j,e("span",{textContent:v(c.value*g.value)},null,8,E),L]),u.value?(t(),o("div",P,[R,S,(t(!0),o(b,null,C(u.value,n=>(t(),o("div",q,[y(e("input",{type:"radio",class:"form-check-input",name:"provider",id:"providers_"+n,value:n,"onUpdate:modelValue":a[1]||(a[1]=k=>i.value=k),onChange:x},null,40,z),[[B,i.value,void 0,{value:!0}]]),e("label",{textContent:v(n),class:"form-check-label",for:"providers_"+n},null,8,A)]))),256))])):(t(),o("div",H,J)),r.value?(t(),o("div",K,[O,Q,(t(!0),o(b,null,C(r.value,n=>(t(),o("div",W,[y(e("input",{type:"radio",class:"form-check-input",name:"payment",id:"payments_"+n.name,"onUpdate:modelValue":a[2]||(a[2]=k=>d.value=k),value:n.name},null,8,X),[[B,d.value]]),e("label",{textContent:v(n.title),class:"form-check-label",for:"payments_"+n.name},null,8,Y)]))),256))])):p("",!0),d.value?(t(),o("div",Z,[e("button",{class:"btn btn-primary mt-3",onClick:V,textContent:v(_.value?"请稍后":"立即支付"),disabled:_.value},null,8,$)])):p("",!0)])):p("",!0)]),_.value?(t(),o("p",ee,"正在创建订单...")):p("",!0),h.value?(t(),o("div",te,[oe,ne,e("a",{href:h.value,class:"link",target:"_blank"},"支付",8,se)])):p("",!0)],64))}};export{ie as default};
|
||||
import{r as l,o as t,c as o,a as e,t as v,j as y,v as w,F as b,e as C,b as p,g as f,l as B}from"./app-b63b1aed.js";import{i as m}from"./http-eca01039.js";const G=e("div",null,[e("h3",null,"流量充值")],-1),N=e("h5",null,"您要充值多少元的流量?",-1),T=f(" 每 GB 价格: "),U=f(" 元。 "),D={class:"input-group mb-3"},F=e("div",{class:"input-group-append"},[e("span",{class:"input-group-text"},"GB")],-1),M={key:0},j=f("大约 "),E=["textContent"],L=f(" 元。"),P={key:0},R=e("h5",{class:"mt-3"},"您将要使用哪个平台充值?",-1),S=e("p",null,"如果您在选中的平台没有账号,我们将会帮您自动创建一个。",-1),q={class:"form-group form-check"},z=["id","value"],A=["textContent","for"],H={key:1},I=e("h5",{class:"mt-3"},"暂时没有可用的",-1),J=[I],K={key:2},O=e("h5",{class:"mt-3"},"让我们来选择支付方式。",-1),Q=e("p",null,"在支付后,您的流量大概需要数秒钟到账。",-1),W={class:"form-group form-check"},X=["id","value"],Y=["textContent","for"],Z={key:3},$=["textContent","disabled"],ee={key:0},te={key:1,class:"mt-3"},oe=e("h5",null,"完成",-1),ne=e("p",null,"如果您浏览器没有打开新的创建,请点击以下链接来打开。",-1),se=["href"],ie={name:"Charge",setup(le){const g=l(0),u=l([]),i=l(""),r=l({}),d=l(""),c=l(10),h=l(""),_=l(!1);m.get("price").then(s=>{g.value=s.data.price_per_gb}),m.get("providers").then(s=>{u.value=s.data,u.value.length>0&&(i.value=u.value[0],x())});function x(){m.get("providers/"+i.value+"/payments").then(s=>{r.value=s.data,r.value.length>0&&(d.value=r.value[0].name)})}function V(){_.value=!0,m.post("providers/"+i.value+"/charge",{payment:d.value,traffic:c.value}).then(s=>{h.value=s.data.redirect_url,setTimeout(()=>{window.open(h.value,"_blank")})}).finally(()=>{_.value=!1})}return(s,a)=>(t(),o(b,null,[G,e("div",null,[N,e("p",null,[T,e("span",null,v(g.value),1),U]),e("div",D,[y(e("input",{autofocus:"",type:"number",class:"form-control",placeholder:"输入您要的流量 (单位: GB)","onUpdate:modelValue":a[0]||(a[0]=n=>c.value=n)},null,512),[[w,c.value]]),F]),c.value?(t(),o("div",M,[e("p",null,[j,e("span",{textContent:v(c.value*g.value)},null,8,E),L]),u.value?(t(),o("div",P,[R,S,(t(!0),o(b,null,C(u.value,n=>(t(),o("div",q,[y(e("input",{type:"radio",class:"form-check-input",name:"provider",id:"providers_"+n,value:n,"onUpdate:modelValue":a[1]||(a[1]=k=>i.value=k),onChange:x},null,40,z),[[B,i.value,void 0,{value:!0}]]),e("label",{textContent:v(n),class:"form-check-label",for:"providers_"+n},null,8,A)]))),256))])):(t(),o("div",H,J)),r.value?(t(),o("div",K,[O,Q,(t(!0),o(b,null,C(r.value,n=>(t(),o("div",W,[y(e("input",{type:"radio",class:"form-check-input",name:"payment",id:"payments_"+n.name,"onUpdate:modelValue":a[2]||(a[2]=k=>d.value=k),value:n.name},null,8,X),[[B,d.value]]),e("label",{textContent:v(n.title),class:"form-check-label",for:"payments_"+n.name},null,8,Y)]))),256))])):p("",!0),d.value?(t(),o("div",Z,[e("button",{class:"btn btn-primary mt-3",onClick:V,textContent:v(_.value?"请稍后":"立即支付"),disabled:_.value},null,8,$)])):p("",!0)])):p("",!0)]),_.value?(t(),o("p",ee,"正在创建订单...")):p("",!0),h.value?(t(),o("div",te,[oe,ne,e("a",{href:h.value,class:"link",target:"_blank"},"支付",8,se)])):p("",!0)],64))}};export{ie as default};
|
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
import{r as s,o as a,c as t,a as r,F as l,e as c,t as n}from"./app-426d2bdb.js";const _=r("h3",null,"客户端下载",-1),d={class:"table table-bordered mt-3"},p=r("thead",null,[r("tr",null,[r("th",null,"名称"),r("th",null,"架构"),r("th",null,"下载")])],-1),u=["href"],g={name:"Downloads",setup(m){const o=s([{name:"Windows Frpc",arch:"amd64",url:"https://r2.laecloud.com/MEFrpRelease/MirrorEdgeFrp_0.46.1_beta_windows_amd64.zip"},{name:"Windows Frpc",arch:"i386",url:"https://r2.laecloud.com/MEFrpRelease/MirrorEdgeFrp_0.46.1_beta_windows_386.zip"},{name:"Linux Frpc amd64",arch:"amd64",url:"https://r2.laecloud.com/MEFrpRelease/frp_MirrorEdgeFrp_0.46.1_beta_linux_amd64.tar.gz"},{name:"Linux Frpc arm64",arch:"arm64",url:"https://r2.laecloud.com/MEFrpRelease/frp_MirrorEdgeFrp_0.46.1_beta_linux_arm64.tar.gz"},{name:"Darwin Frpc amd64",arch:"amd64",url:"https://r2.laecloud.com/MEFrpRelease/frp_MirrorEdgeFrp_0.46.1_beta_darwin_amd64.tar.gz"},{name:"Darwin Frpc arm64",arch:"arm64",url:"https://r2.laecloud.com/MEFrpRelease/frp_MirrorEdgeFrp_0.46.1_beta_darwin_arm64.tar.gz"}]);return(h,F)=>(a(),t(l,null,[_,r("table",d,[p,r("tbody",null,[(a(!0),t(l,null,c(o.value,e=>(a(),t("tr",null,[r("td",null,n(e.name),1),r("td",null,n(e.arch),1),r("td",null,[r("a",{href:e.url},"下载",8,u)])]))),256))])])],64))}};export{g as default};
|
1
public/build/assets/Downloads-5f629c5d.js
Normal file
1
public/build/assets/Downloads-5f629c5d.js
Normal file
@ -0,0 +1 @@
|
||||
import{r as o,o as n,c as t,a as r,F as l,e as c,t as p}from"./app-b63b1aed.js";const m=r("h3",null,"客户端下载",-1),u={class:"table table-bordered mt-3"},e=r("thead",null,[r("tr",null,[r("th",null,"名称"),r("th",null,"架构"),r("th",null,"下载")])],-1),h=["href"],x={name:"Downloads",setup(s){const d=o([{name:"Windows Frpc",arch:"amd64",url:"https://download.muhanfrp.cn/frp_0.46.1_windows_amd64.zip"},{name:"Windows Frpc",arch:"i386",url:"https://download.muhanfrp.cn/frp_0.46.1_windows_386.zip"},{name:"Linux Frpc i386",arch:"i386",url:"https://download.muhanfrp.cn/frp_0.46.1_linux_386.tar.gz"},{name:"Linux Frpc amd64",arch:"amd64",url:"https://download.muhanfrp.cn/frp_0.46.1_linux_amd64.tar.gz"},{name:"Linux Frpc arm32",arch:"arm32",url:"https://download.muhanfrp.cn/frp_0.46.1_linux_arm32.tar.gz"},{name:"Linux Frpc arm64",arch:"arm64",url:"https://download.muhanfrp.cn/frp_0.46.1_linux_arm64.tar.gz"},{name:"Darwin Frpc amd64",arch:"amd64",url:"https://download.muhanfrp.cn/frp_0.46.1_darwin_amd64.tar.gz"},{name:"Darwin Frpc arm64",arch:"arm64",url:"https://download.muhanfrp.cn/frp_0.46.1_darwin_arm64.tar.gz"},{name:"Freebsd Frpc i386",arch:"i386",url:"https://download.muhanfrp.cn/frp_0.46.1_freebsd_386.tar.gz"},{name:"Freebsd Frpc arm64",arch:"arm64",url:"https://download.muhanfrp.cn/frp_0.46.1_freebsd_amd64.tar.gz"},{name:"Mips Frpc i386",arch:"i386",url:"https://download.muhanfrp.cn/frp_0.46.1_linux_mips.tar.gz"},{name:"Mips Frpc amd64",arch:"amd64",url:"https://download.muhanfrp.cn/frp_0.46.1_linux_mips64.tar.gz"},{name:"Mipsle Frpc i386",arch:"i386",url:"https://download.muhanfrp.cn/frp_0.46.1_linux_mipsle.tar.gz"},{name:"Mipsle Frpc amd64",arch:"amd64",url:"https://download.muhanfrp.cn/frp_0.46.1_linux_mips64le.tar.gz"},{name:"Riscv Frpc amd64",arch:"amd64",url:"https://download.muhanfrp.cn/frp_0.46.1_linux_riscv64.tar.gz"},{name:"android-v0.39.1.1 Frpc 图形客户端",arch:"android",url:"https://download.muhanfrp.cn/frpc_android-v0.39.1.1.apk"},{name:"android-v0.31.2 Frpc 图形客户端",arch:"android",url:"https://download.muhanfrp.cn/FRP.apk"},{name:"Termux 客户端 ",arch:"android",url:"https://download.muhanfrp.cn/com.termux_118.apk"},{name:"Windows PortIO_Python 图形客户端",arch:"86-64",url:"https://download.muhanfrp.cn/PortIO_Client.zip"},{name:"Windows PortIO_Client_CLI_Python 命令行图形客户端",arch:"86-64",url:"https://download.muhanfrp.cn/PortIO_Client_CLI.exe"},{name:"Windows PortIO_Pascal 图形客户端",arch:"86-64",url:"https://download.muhanfrp.cn/pioc_windows_x86_64.zip"},{name:"Linux PortIO_Pascal 图形客户端",arch:"86-64",url:"https://download.muhanfrp.cn/pioc_linux_x86_64.tar.gz"}]);return(i,f)=>(n(),t(l,null,[m,r("table",u,[e,r("tbody",null,[(n(!0),t(l,null,c(d.value,a=>(n(),t("tr",null,[r("td",null,p(a.name),1),r("td",null,p(a.arch),1),r("td",null,[r("a",{href:a.url},"下载",8,h)])]))),256))])])],64))}};export{x as default};
|
@ -1 +1 @@
|
||||
import{i as d}from"./http-419d7b2b.js";import{r as p,d as _,o as s,c as r,a as e,F as c,e as i,t as o,f as h,w as u,g as m}from"./app-426d2bdb.js";const v=e("h3",null,"隧道列表",-1),k={class:"table table-hover"},f=e("thead",null,[e("tr",null,[e("th",{scope:"col"},"ID"),e("th",{scope:"col"},"名称"),e("th",{scope:"col"},"协议"),e("th",{scope:"col"},"本地地址"),e("th",{scope:"col"},"远程端口/域名"),e("th",{scope:"col"},"服务器"),e("th",{scope:"col"},"状态")])],-1),g={key:0},x={key:1},y={key:0,class:"text-success"},b={key:1,class:"text-danger"},V={name:"Index",setup(w){const a=p([{id:"0",protocol:"",server:{server_address:"",server_port:"",name:""},run_id:""}]);return d.get("tunnels").then(l=>{a.value=l.data,console.log(a.value)}),(l,B)=>{const n=_("router-link");return s(),r(c,null,[v,e("table",k,[f,e("tbody",null,[(s(!0),r(c,null,i(a.value,t=>(s(),r("tr",null,[e("th",null,o(t.id),1),e("td",null,[h(n,{to:{name:"tunnels.show",params:{id:t.id}}},{default:u(()=>[m(o(t.name),1)]),_:2},1032,["to"])]),e("td",null,o(t.protocol.toString().toUpperCase()),1),e("td",null,o(t.local_address),1),e("td",null,[t.protocol==="http"||t.protocol==="https"?(s(),r("span",g,o(t.custom_domain),1)):(s(),r("span",x,o(t.server.server_address)+":"+o(t.remote_port),1))]),e("td",null,o(t.server.name),1),e("td",null,[t.run_id?(s(),r("span",y,"在线")):(s(),r("span",b,"离线"))])]))),256))])])],64)}}};export{V as default};
|
||||
import{i as d}from"./http-eca01039.js";import{r as p,d as _,o as s,c as r,a as e,F as c,e as i,t as o,f as h,w as u,g as m}from"./app-b63b1aed.js";const v=e("h3",null,"隧道列表",-1),k={class:"table table-hover"},f=e("thead",null,[e("tr",null,[e("th",{scope:"col"},"ID"),e("th",{scope:"col"},"名称"),e("th",{scope:"col"},"协议"),e("th",{scope:"col"},"本地地址"),e("th",{scope:"col"},"远程端口/域名"),e("th",{scope:"col"},"服务器"),e("th",{scope:"col"},"状态")])],-1),g={key:0},x={key:1},y={key:0,class:"text-success"},b={key:1,class:"text-danger"},V={name:"Index",setup(w){const a=p([{id:"0",protocol:"",server:{server_address:"",server_port:"",name:""},run_id:""}]);return d.get("tunnels").then(l=>{a.value=l.data,console.log(a.value)}),(l,B)=>{const n=_("router-link");return s(),r(c,null,[v,e("table",k,[f,e("tbody",null,[(s(!0),r(c,null,i(a.value,t=>(s(),r("tr",null,[e("th",null,o(t.id),1),e("td",null,[h(n,{to:{name:"tunnels.show",params:{id:t.id}}},{default:u(()=>[m(o(t.name),1)]),_:2},1032,["to"])]),e("td",null,o(t.protocol.toString().toUpperCase()),1),e("td",null,o(t.local_address),1),e("td",null,[t.protocol==="http"||t.protocol==="https"?(s(),r("span",g,o(t.custom_domain),1)):(s(),r("span",x,o(t.server.server_address)+":"+o(t.remote_port),1))]),e("td",null,o(t.server.name),1),e("td",null,[t.run_id?(s(),r("span",y,"在线")):(s(),r("span",b,"离线"))])]))),256))])])],64)}}};export{V as default};
|
@ -1 +1 @@
|
||||
import{i as o}from"./http-419d7b2b.js";import{r as u,o as l,c,a as e,t as n,u as i,b as d,F as h}from"./app-426d2bdb.js";const p=e("div",null,[e("h3",null,"欢迎")],-1),k={class:"mt-3"},f={key:0,class:"mt-3"},v=e("h3",null,"实名认证",-1),b=e("p",null," 注意,您没有完成实名认证,请点击下方按钮完成实名认证,否则您只能使用中国大陆以外的隧道。 ",-1),g=e("a",{class:"btn btn-primary",target:"_blank",href:"https://oauth.laecloud.com/real_name"},"实名认证",-1),y=e("h3",null,"访问密钥",-1),x={class:"mt-3"},B={key:0,class:"text-success"},A={name:"Index",setup(T){const r=window.Base.SiteName,s=u({name:"loading...",traffic:""}),a=u("");o.get("user").then(t=>{s.value=t.data});function _(){o.post("tokens").then(t=>{a.value=t.data.token})}function m(){o.delete("tokens").then(t=>{alert("所有 Token 删除成功。")})}return(t,w)=>(l(),c(h,null,[p,e("div",k,[e("p",null,"用户名: "+n(s.value.name),1),e("p",null,"剩余流量: "+n(s.value.traffic)+" GB",1)]),s.value.realnamed?d("",!0):(l(),c("div",f,[v,b,g,e("p",null,"在实名认证后,请重新登录 "+n(i(r))+"。",1)])),y,e("div",x,[e("p",null," 访问密钥是用于访问 "+n(i(r))+" API 的密钥,您可以使用它来开发自己的客户端。 ",1),a.value?(l(),c("p",B,"获取成功,请妥善保管您的 Token: "+n(a.value),1)):d("",!0),e("button",{class:"btn btn-primary",onClick:_}," 获取新密钥 "),e("button",{class:"btn btn-danger",style:{"margin-left":"5px"},onClick:m}," 删除所有密钥 ")])],64))}};export{A as default};
|
||||
import{i as o}from"./http-eca01039.js";import{r as u,o as l,c,a as e,t as n,u as i,b as d,F as h}from"./app-b63b1aed.js";const p=e("div",null,[e("h3",null,"欢迎")],-1),k={class:"mt-3"},f={key:0,class:"mt-3"},v=e("h3",null,"实名认证",-1),b=e("p",null," 注意,您没有完成实名认证,请点击下方按钮完成实名认证,否则您只能使用中国大陆以外的隧道。 ",-1),g=e("a",{class:"btn btn-primary",target:"_blank",href:"https://oauth.laecloud.com/real_name"},"实名认证",-1),y=e("h3",null,"访问密钥",-1),x={class:"mt-3"},B={key:0,class:"text-success"},A={name:"Index",setup(T){const r=window.Base.SiteName,s=u({name:"loading...",traffic:""}),a=u("");o.get("user").then(t=>{s.value=t.data});function _(){o.post("tokens").then(t=>{a.value=t.data.token})}function m(){o.delete("tokens").then(t=>{alert("所有 Token 删除成功。")})}return(t,w)=>(l(),c(h,null,[p,e("div",k,[e("p",null,"用户名: "+n(s.value.name),1),e("p",null,"剩余流量: "+n(s.value.traffic)+" GB",1)]),s.value.realnamed?d("",!0):(l(),c("div",f,[v,b,g,e("p",null,"在实名认证后,请重新登录 "+n(i(r))+"。",1)])),y,e("div",x,[e("p",null," 访问密钥是用于访问 "+n(i(r))+" API 的密钥,您可以使用它来开发自己的客户端。 ",1),a.value?(l(),c("p",B,"获取成功,请妥善保管您的 Token: "+n(a.value),1)):d("",!0),e("button",{class:"btn btn-primary",onClick:_}," 获取新密钥 "),e("button",{class:"btn btn-danger",style:{"margin-left":"5px"},onClick:m}," 删除所有密钥 ")])],64))}};export{A as default};
|
@ -1,4 +1,4 @@
|
||||
import{i as Tl}from"./http-419d7b2b.js";import{r as tm,m as em,i as cL,n as pL,o as rm,c as am,a as Ke,t as kh,b as dL,F as gL}from"./app-426d2bdb.js";/*! *****************************************************************************
|
||||
import{i as Tl}from"./http-eca01039.js";import{r as tm,m as em,i as cL,n as pL,o as rm,c as am,a as Ke,t as kh,b as dL,F as gL}from"./app-b63b1aed.js";/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
@ -1 +1 @@
|
||||
import{i}from"./http-419d7b2b.js";import{r as s,o as c,c as f,a as e,t as r}from"./app-426d2bdb.js";const o=e("h3",null,"流量补给",-1),u={key:0},d={key:1},h={name:"Sign",setup(_){const a=s({last_sign_at:null,traffic:0});i.get("user").then(t=>{a.value.traffic=t.data.traffic});function l(){i.post("traffic").then(t=>{a.value=t.data;let n=`获得了 ${t.data.traffic} GB 流量!`;t.data.traffic===0&&(n="没有获得流量~"),alert(n)}).finally(()=>{i.get("user").then(t=>{a.value.traffic=t.data.traffic}).finally(()=>{})})}return(t,n)=>(c(),f("div",null,[o,e("div",null,[e("p",null,"当前流量: "+r(a.value.traffic)+"GB",1),a.value.is_signed?(c(),f("div",u,"今日已签到")):(c(),f("div",d,[e("button",{class:"btn btn-primary",onClick:l},"试试手气")]))])]))}};export{h as default};
|
||||
import{i}from"./http-eca01039.js";import{r as s,o as c,c as f,a as e,t as r}from"./app-b63b1aed.js";const o=e("h3",null,"流量补给",-1),u={key:0},d={key:1},h={name:"Sign",setup(_){const a=s({last_sign_at:null,traffic:0});i.get("user").then(t=>{a.value.traffic=t.data.traffic});function l(){i.post("traffic").then(t=>{a.value=t.data;let n=`获得了 ${t.data.traffic} GB 流量!`;t.data.traffic===0&&(n="没有获得流量~"),alert(n)}).finally(()=>{i.get("user").then(t=>{a.value.traffic=t.data.traffic}).finally(()=>{})})}return(t,n)=>(c(),f("div",null,[o,e("div",null,[e("p",null,"当前流量: "+r(a.value.traffic)+"GB",1),a.value.is_signed?(c(),f("div",u,"今日已签到")):(c(),f("div",d,[e("button",{class:"btn btn-primary",onClick:l},"试试手气")]))])]))}};export{h as default};
|
@ -1 +1 @@
|
||||
import{_ as w,r as c,o as t,c as o,a as e,j as m,v as k,b as r,F as f,e as I,t as b,g as x,l as S,p as B,q as N}from"./app-426d2bdb.js";import{i as y}from"./http-419d7b2b.js";const a=_=>(B("data-v-04d8426c"),_=_(),N(),_),U=a(()=>e("div",null,[e("h3",null,"发工单")],-1)),D=a(()=>e("h5",null,"有遇到什么问题吗?",-1)),F=x(" 您可以选择以下常见问题: "),M=x(" "),j={class:"input-group mb-3"},q={key:0,class:"input-group"},E={key:1},L={key:0},R=a(()=>e("h5",{class:"mt-3"},"选择发工单的平台",-1)),z=a(()=>e("p",null,"如果您在选中的平台没有账号,我们将会帮您自动创建一个。",-1)),A={class:"form-group form-check"},G=["id","value"],H=["textContent","for"],J={key:1},K=a(()=>e("h5",{class:"mt-3"},"暂时没有可用的提供商",-1)),O=[K],P={key:2},Q=["textContent","disabled"],W={key:0},X={key:1,class:"mt-3"},Y=a(()=>e("h5",null,"完成",-1)),Z=a(()=>e("p",null,"如果您浏览器没有打开新的创建,请点击以下链接来打开。",-1)),$=["href"],ee={name:"Ticket",setup(_){const u=c([]),v=c(""),l=c(""),n=c(""),p=c(""),d=c(!1);y.get("providers").then(h=>{u.value=h.data,u.value.length>0&&(v.value=u.value[0])});function g(){d.value=!0,y.post("providers/"+v.value+"/ticket",{title:l.value,content:n.value}).then(h=>{p.value=h.data.redirect_url,setTimeout(()=>{window.open(p.value,"_blank")})}).finally(()=>{d.value=!1})}function C(){l.value="域名 {你的域名} 过白。",n.value="您好,我的域名已备案,请将我的域名 {你的域名} 加入白名单,谢谢。"}function T(){l.value="{节点} 的隧道无法连接。",n.value="您好,这个节点无法连接,请检查。"}return(h,i)=>(t(),o(f,null,[U,e("div",null,[D,e("div",{class:"mb-3"},[F,e("a",{onClick:C,class:"link"},"域名白名单"),M,e("a",{onClick:T,class:"link"},"映射问题")]),e("div",j,[m(e("input",{autofocus:"",type:"text",class:"form-control",placeholder:"简要概述您遇到的问题","onUpdate:modelValue":i[0]||(i[0]=s=>l.value=s)},null,512),[[k,l.value]])]),l.value?(t(),o("div",q,[m(e("textarea",{class:"form-control","onUpdate:modelValue":i[1]||(i[1]=s=>n.value=s),placeholder:"详细说明您遇到的问题..."},null,512),[[k,n.value]])])):r("",!0),l.value?(t(),o("div",E,[u.value?(t(),o("div",L,[R,z,(t(!0),o(f,null,I(u.value,s=>(t(),o("div",A,[m(e("input",{type:"radio",class:"form-check-input",name:"provider",id:"providers_"+s,value:s,"onUpdate:modelValue":i[2]||(i[2]=V=>v.value=V)},null,8,G),[[S,v.value,void 0,{value:!0}]]),e("label",{textContent:b(s),class:"form-check-label",for:"providers_"+s},null,8,H)]))),256))])):(t(),o("div",J,O)),n.value?(t(),o("div",P,[e("button",{class:"btn btn-primary mt-3",onClick:g,textContent:b(d.value?"请稍后":"创建工单"),disabled:d.value},null,8,Q)])):r("",!0)])):r("",!0)]),d.value?(t(),o("p",W,"正在打开工单...")):r("",!0),p.value?(t(),o("div",X,[Y,Z,e("a",{href:p.value,class:"link",target:"_blank"},"打开工单",8,$)])):r("",!0)],64))}},se=w(ee,[["__scopeId","data-v-04d8426c"]]);export{se as default};
|
||||
import{_ as w,r as c,o as t,c as o,a as e,j as m,v as k,b as r,F as f,e as I,t as b,g as x,l as S,p as B,q as N}from"./app-b63b1aed.js";import{i as y}from"./http-eca01039.js";const a=_=>(B("data-v-04d8426c"),_=_(),N(),_),U=a(()=>e("div",null,[e("h3",null,"发工单")],-1)),D=a(()=>e("h5",null,"有遇到什么问题吗?",-1)),F=x(" 您可以选择以下常见问题: "),M=x(" "),j={class:"input-group mb-3"},q={key:0,class:"input-group"},E={key:1},L={key:0},R=a(()=>e("h5",{class:"mt-3"},"选择发工单的平台",-1)),z=a(()=>e("p",null,"如果您在选中的平台没有账号,我们将会帮您自动创建一个。",-1)),A={class:"form-group form-check"},G=["id","value"],H=["textContent","for"],J={key:1},K=a(()=>e("h5",{class:"mt-3"},"暂时没有可用的提供商",-1)),O=[K],P={key:2},Q=["textContent","disabled"],W={key:0},X={key:1,class:"mt-3"},Y=a(()=>e("h5",null,"完成",-1)),Z=a(()=>e("p",null,"如果您浏览器没有打开新的创建,请点击以下链接来打开。",-1)),$=["href"],ee={name:"Ticket",setup(_){const u=c([]),v=c(""),l=c(""),n=c(""),p=c(""),d=c(!1);y.get("providers").then(h=>{u.value=h.data,u.value.length>0&&(v.value=u.value[0])});function g(){d.value=!0,y.post("providers/"+v.value+"/ticket",{title:l.value,content:n.value}).then(h=>{p.value=h.data.redirect_url,setTimeout(()=>{window.open(p.value,"_blank")})}).finally(()=>{d.value=!1})}function C(){l.value="域名 {你的域名} 过白。",n.value="您好,我的域名已备案,请将我的域名 {你的域名} 加入白名单,谢谢。"}function T(){l.value="{节点} 的隧道无法连接。",n.value="您好,这个节点无法连接,请检查。"}return(h,i)=>(t(),o(f,null,[U,e("div",null,[D,e("div",{class:"mb-3"},[F,e("a",{onClick:C,class:"link"},"域名白名单"),M,e("a",{onClick:T,class:"link"},"映射问题")]),e("div",j,[m(e("input",{autofocus:"",type:"text",class:"form-control",placeholder:"简要概述您遇到的问题","onUpdate:modelValue":i[0]||(i[0]=s=>l.value=s)},null,512),[[k,l.value]])]),l.value?(t(),o("div",q,[m(e("textarea",{class:"form-control","onUpdate:modelValue":i[1]||(i[1]=s=>n.value=s),placeholder:"详细说明您遇到的问题..."},null,512),[[k,n.value]])])):r("",!0),l.value?(t(),o("div",E,[u.value?(t(),o("div",L,[R,z,(t(!0),o(f,null,I(u.value,s=>(t(),o("div",A,[m(e("input",{type:"radio",class:"form-check-input",name:"provider",id:"providers_"+s,value:s,"onUpdate:modelValue":i[2]||(i[2]=V=>v.value=V)},null,8,G),[[S,v.value,void 0,{value:!0}]]),e("label",{textContent:b(s),class:"form-check-label",for:"providers_"+s},null,8,H)]))),256))])):(t(),o("div",J,O)),n.value?(t(),o("div",P,[e("button",{class:"btn btn-primary mt-3",onClick:g,textContent:b(d.value?"请稍后":"创建工单"),disabled:d.value},null,8,Q)])):r("",!0)])):r("",!0)]),d.value?(t(),o("p",W,"正在打开工单...")):r("",!0),p.value?(t(),o("div",X,[Y,Z,e("a",{href:p.value,class:"link",target:"_blank"},"打开工单",8,$)])):r("",!0)],64))}},se=w(ee,[["__scopeId","data-v-04d8426c"]]);export{se as default};
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
import{s as a,m as n}from"./app-426d2bdb.js";let t=a.create({baseURL:"/api",timeout:1e4,headers:{"X-Requested-With":"XMLHttpRequest","X-CSRF-TOKEN":document.querySelector('meta[name="csrf-token"]').getAttribute("content")}});t.interceptors.request.use(e=>(e.headers,e.headers.Accept="application/json",e),e=>(console.error(e),Promise.reject(e)));t.interceptors.response.use(e=>Promise.resolve(e),e=>{console.error("axios error",e);let s=[];e.response.data.data&&(s=e.response.data.data),e.response.data.message&&(s=e.response.data.message),e.response.data.error&&(s=e.response.data.error.message),e.response.status===429?alert("请求次数过多"):e.response.status===401||(e.response.status===404?n.push({name:"index"}):s.length!==0&&alert(s))});export{t as i};
|
||||
import{s as a,m as n}from"./app-b63b1aed.js";let t=a.create({baseURL:"/api",timeout:1e4,headers:{"X-Requested-With":"XMLHttpRequest","X-CSRF-TOKEN":document.querySelector('meta[name="csrf-token"]').getAttribute("content")}});t.interceptors.request.use(e=>(e.headers,e.headers.Accept="application/json",e),e=>(console.error(e),Promise.reject(e)));t.interceptors.response.use(e=>Promise.resolve(e),e=>{console.error("axios error",e);let s=[];e.response.data.data&&(s=e.response.data.data),e.response.data.message&&(s=e.response.data.message),e.response.data.error&&(s=e.response.data.error.message),e.response.status===429?alert("请求次数过多"):e.response.status===401||(e.response.status===404?n.push({name:"index"}):s.length!==0&&alert(s))});export{t as i};
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"_http-419d7b2b.js": {
|
||||
"file": "assets/http-419d7b2b.js",
|
||||
"_http-eca01039.js": {
|
||||
"file": "assets/http-eca01039.js",
|
||||
"imports": [
|
||||
"resources/js/app.js"
|
||||
]
|
||||
@ -40,21 +40,21 @@
|
||||
"resources/js/views/Charge.vue",
|
||||
"resources/js/views/Ticket.vue"
|
||||
],
|
||||
"file": "assets/app-426d2bdb.js",
|
||||
"file": "assets/app-b63b1aed.js",
|
||||
"isEntry": true,
|
||||
"src": "resources/js/app.js"
|
||||
},
|
||||
"resources/js/views/Charge.vue": {
|
||||
"file": "assets/Charge-3c0346d5.js",
|
||||
"file": "assets/Charge-742f0fb0.js",
|
||||
"imports": [
|
||||
"resources/js/app.js",
|
||||
"_http-419d7b2b.js"
|
||||
"_http-eca01039.js"
|
||||
],
|
||||
"isDynamicEntry": true,
|
||||
"src": "resources/js/views/Charge.vue"
|
||||
},
|
||||
"resources/js/views/Downloads.vue": {
|
||||
"file": "assets/Downloads-1fe05572.js",
|
||||
"file": "assets/Downloads-5f629c5d.js",
|
||||
"imports": [
|
||||
"resources/js/app.js"
|
||||
],
|
||||
@ -62,18 +62,18 @@
|
||||
"src": "resources/js/views/Downloads.vue"
|
||||
},
|
||||
"resources/js/views/Index.vue": {
|
||||
"file": "assets/Index-9cef052a.js",
|
||||
"file": "assets/Index-9900345d.js",
|
||||
"imports": [
|
||||
"_http-419d7b2b.js",
|
||||
"_http-eca01039.js",
|
||||
"resources/js/app.js"
|
||||
],
|
||||
"isDynamicEntry": true,
|
||||
"src": "resources/js/views/Index.vue"
|
||||
},
|
||||
"resources/js/views/Sign.vue": {
|
||||
"file": "assets/Sign-152c9e31.js",
|
||||
"file": "assets/Sign-e61967c6.js",
|
||||
"imports": [
|
||||
"_http-419d7b2b.js",
|
||||
"_http-eca01039.js",
|
||||
"resources/js/app.js"
|
||||
],
|
||||
"isDynamicEntry": true,
|
||||
@ -87,36 +87,36 @@
|
||||
"css": [
|
||||
"assets/Ticket-41ca6517.css"
|
||||
],
|
||||
"file": "assets/Ticket-fb342565.js",
|
||||
"file": "assets/Ticket-d9bf034e.js",
|
||||
"imports": [
|
||||
"resources/js/app.js",
|
||||
"_http-419d7b2b.js"
|
||||
"_http-eca01039.js"
|
||||
],
|
||||
"isDynamicEntry": true,
|
||||
"src": "resources/js/views/Ticket.vue"
|
||||
},
|
||||
"resources/js/views/Tunnels/Create.vue": {
|
||||
"file": "assets/Create-5885dd13.js",
|
||||
"file": "assets/Create-5fe9455d.js",
|
||||
"imports": [
|
||||
"resources/js/app.js",
|
||||
"_http-419d7b2b.js"
|
||||
"_http-eca01039.js"
|
||||
],
|
||||
"isDynamicEntry": true,
|
||||
"src": "resources/js/views/Tunnels/Create.vue"
|
||||
},
|
||||
"resources/js/views/Tunnels/Index.vue": {
|
||||
"file": "assets/Index-3dd3acd6.js",
|
||||
"file": "assets/Index-2516cda8.js",
|
||||
"imports": [
|
||||
"_http-419d7b2b.js",
|
||||
"_http-eca01039.js",
|
||||
"resources/js/app.js"
|
||||
],
|
||||
"isDynamicEntry": true,
|
||||
"src": "resources/js/views/Tunnels/Index.vue"
|
||||
},
|
||||
"resources/js/views/Tunnels/Show.vue": {
|
||||
"file": "assets/Show-f0c4e11e.js",
|
||||
"file": "assets/Show-f5a80327.js",
|
||||
"imports": [
|
||||
"_http-419d7b2b.js",
|
||||
"_http-eca01039.js",
|
||||
"resources/js/app.js"
|
||||
],
|
||||
"isDynamicEntry": true,
|
||||
|
@ -1,10 +1,20 @@
|
||||
<x-app-layout>
|
||||
@if (count($servers) > 0)
|
||||
<h1>不在线或维护中的服务器</h1>
|
||||
<h3>不在线或维护中的服务器</h3>
|
||||
|
||||
@foreach ($servers as $server)
|
||||
<x-Server-View :server="$server" :url="route('admin.servers.edit', $server->id)" />
|
||||
<x-Server-View :server="$server" :url="route('admin.servers.edit', $server->id)"/>
|
||||
@endforeach
|
||||
@else
|
||||
<div class="text-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="currentColor"
|
||||
class="bi bi-check-circle" viewBox="0 0 16 16">
|
||||
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
|
||||
<path
|
||||
d="M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z"/>
|
||||
</svg>
|
||||
<h4 class="mt-3">服务器一切正常</h4>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</x-app-layout>
|
||||
|
@ -1,19 +1,29 @@
|
||||
<x-app-layout>
|
||||
<div>
|
||||
<h1>登录</h1>
|
||||
<div class="container">
|
||||
<h3>登录</h3>
|
||||
|
||||
<form action="{{ route('admin.login') }}" method="POST">
|
||||
@csrf
|
||||
|
||||
{{-- email --}}
|
||||
<input type="text" name="email" placeholder="邮箱">
|
||||
{{-- password --}}
|
||||
<input type="password" name="password" placeholder="密码">
|
||||
{{-- remember --}}
|
||||
<input type="checkbox" name="remember" id="remember">
|
||||
<label for="remember">记住我</label>
|
||||
{{-- submit --}}
|
||||
<button type="submit">登录</button>
|
||||
<form action="{{ route('admin.login') }}" method="POST" class="mt-3">
|
||||
@csrf
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
登录
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<input type="text" name="email" placeholder="邮箱" class="form-control">
|
||||
</div>
|
||||
<div class="col">
|
||||
<input type="password" name="password" placeholder="密码" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<input type="checkbox" name="remember" id="remember" class="form-check-input">
|
||||
<label for="remember" class="form-check-label">记住我</label>
|
||||
</div>
|
||||
<button class="mt-3 btn btn-primary" type="submit">登录</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
|
@ -1,19 +1,17 @@
|
||||
<x-app-layout>
|
||||
|
||||
|
||||
<form action="{{ route('admin.servers.store') }}" method="post">
|
||||
@csrf
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>服务器</h3>
|
||||
<h4>服务器</h4>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="serverName" class="form-label">服务器名称</label>
|
||||
<input type="text" required class="form-control" id="serverName" placeholder="输入服务器名称,它将会被搜索到"
|
||||
name="name">
|
||||
name="name">
|
||||
</div>
|
||||
|
||||
<h3>Frps 信息</h3>
|
||||
<h4>Frps 信息</h4>
|
||||
<div class="mb-3">
|
||||
<label for="serverAddr" class="form-label">Frps 地址</label>
|
||||
<input type="text" required class="form-control" id="serverAddr" name="server_address">
|
||||
@ -32,48 +30,48 @@
|
||||
|
||||
<div class="col">
|
||||
|
||||
<h3>Frps Dashboard 配置</h3>
|
||||
<h4>Frps Dashboard 配置</h4>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="dashboardPort" class="form-label">端口</label>
|
||||
<input type="text" required class="form-control" id="dashboardPort" name="dashboard_port"
|
||||
value="7500">
|
||||
value="7500">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="dashboardUser" class="form-label">登录用户名</label>
|
||||
<input type="text" required class="form-control" id="dashboardUser" name="dashboard_user"
|
||||
value="admin">
|
||||
value="admin">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="dashboardPwd" class="form-label">密码</label>
|
||||
<input type="text" required class="form-control" id="dashboardPwd" name="dashboard_password"
|
||||
value="admin">
|
||||
value="admin">
|
||||
</div>
|
||||
|
||||
<h3>端口范围限制</h3>
|
||||
<h4>端口范围限制</h4>
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
<input type="text" required class="form-control" placeholder="最小端口,比如: 10000" name="min_port"
|
||||
value="10000">
|
||||
<input type="text" required class="form-control" placeholder="最大端口,比如: 65535" name="max_port"
|
||||
value="65535">
|
||||
<input type="text" required class="form-control" placeholder="最小端口, 比如: 10000" name="min_port"
|
||||
value="10000">
|
||||
<input type="text" required class="form-control" placeholder="最大端口, 比如: 65535" name="max_port"
|
||||
value="65535">
|
||||
</div>
|
||||
|
||||
<h3>最多隧道数量</h3>
|
||||
<h4>最多隧道数量</h4>
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
<input type="text" required class="form-control" placeholder="最多隧道数量,比如:1024个隧道"
|
||||
name="max_tunnels">
|
||||
<input type="text" required class="form-control" placeholder="最多隧道数量, 比如: 1024个隧道"
|
||||
name="max_tunnels">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>隧道协议限制</h3>
|
||||
<div class="col">
|
||||
<h4>隧道协议限制</h4>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_http" value="1" id="allow_http">
|
||||
<label class="form-check-label" for="allow_http">
|
||||
允许 HTTP
|
||||
</label>
|
||||
<br />
|
||||
超文本传输协议
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
@ -99,7 +97,7 @@
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_stcp" value="1"
|
||||
id="allow_stcp">
|
||||
id="allow_stcp">
|
||||
<label class="form-check-label" for="allow_stcp">
|
||||
允许 STCP
|
||||
</label>
|
||||
@ -107,24 +105,29 @@
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_xtcp" value="1"
|
||||
id="allow_xtcp">
|
||||
id="allow_xtcp">
|
||||
<label class="form-check-label" for="allow_xtcp">
|
||||
允许 XTCP
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<p>服务器是否位于中国大陆</p>
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
{{-- checkbox --}}
|
||||
<input type="checkbox" name="is_china_mainland" value="1" id="is_china_mainland">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_sudp" value="1"
|
||||
id="allow_sudp">
|
||||
<label class="form-check-label" for="allow_sudp">
|
||||
允许 SUDP
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check mt-3">
|
||||
<input class="form-check-input" type="checkbox" name="is_china_mainland" value="1"
|
||||
id="is_china_mainland">
|
||||
<label class="form-check-label" for="is_china_mainland">
|
||||
服务器是否位于中国大陆
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="col-auto">
|
||||
<div class="d-grid mt-3">
|
||||
<button type="submit" class="btn btn-primary mb-3">新建服务器</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -13,312 +13,302 @@
|
||||
</div>
|
||||
</nav> --}}
|
||||
|
||||
<div class="tab-content" id="nav-tabContent">
|
||||
<div class="tab-pane fade" id="nav-settings" role="tabpanel">
|
||||
<div class="row mt-3">
|
||||
<div class="col">
|
||||
<form action="{{ route('admin.servers.update', $server->id) }}" method="post">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<h3>服务器</h3>
|
||||
{{-- <div class="tab-content" id="nav-tabContent">--}}
|
||||
{{-- <div class="tab-pane fade" id="nav-settings" role="tabpanel">--}}
|
||||
<form action="{{ route('admin.servers.update', $server->id) }}" method="post">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h4>服务器</h4>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="serverName" class="form-label">服务器名称</label>
|
||||
<input type="text" required value="{{ $server->name }}" class="form-control"
|
||||
id="serverName" placeholder="输入服务器名称,它将会被搜索到" name="name">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="serverKey" class="form-label">鉴权 Key</label>
|
||||
<input type="text" required value="{{ $server->key }}" class="form-control"
|
||||
id="serverKey" name="key">
|
||||
</div>
|
||||
|
||||
<h3>Frps 信息</h3>
|
||||
<div class="mb-3">
|
||||
<label for="serverAddr" class="form-label">Frps 地址</label>
|
||||
<input type="text" required value="{{ $server->server_address }}" class="form-control"
|
||||
id="serverAddr" name="server_address">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="serverPort" class="form-label">Frps 端口</label>
|
||||
<input type="text" required value="{{ $server->server_port }}" class="form-control"
|
||||
id="serverPort" name="server_port">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="serverToken" class="form-label">Frps 令牌</label>
|
||||
<input type="text" required value="{{ $server->token }}" class="form-control"
|
||||
id="serverToken" name="token">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="serverName" class="form-label">服务器名称</label>
|
||||
<input type="text" required class="form-control" id="serverName" placeholder="输入服务器名称,它将会被搜索到"
|
||||
name="name" value="{{ $server->name }}">
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="mb-3">
|
||||
<label for="serverKey" class="form-label">鉴权 Key</label>
|
||||
<input type="text" required value="{{ $server->key }}" class="form-control"
|
||||
id="serverKey" name="key">
|
||||
</div>
|
||||
|
||||
<h3>Frps Dashboard 配置</h3>
|
||||
<h4>Frps 信息</h4>
|
||||
<div class="mb-3">
|
||||
<label for="serverAddr" class="form-label">Frps 地址</label>
|
||||
<input type="text" required class="form-control" id="serverAddr" name="server_address"
|
||||
value="{{ $server->server_address }}">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="dashboardPort" class="form-label">端口</label>
|
||||
<input type="text" required value="{{ $server->dashboard_port }}" class="form-control"
|
||||
id="dashboardPort" name="dashboard_port">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="serverPort" class="form-label">Frps 端口</label>
|
||||
<input type="text" required class="form-control" id="serverPort" name="server_port"
|
||||
value="{{ $server->server_port }}">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="dashboardUser" class="form-label">登录用户名</label>
|
||||
<input type="text" required value="{{ $server->dashboard_user }}" class="form-control"
|
||||
id="dashboardUser" name="dashboard_user">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="serverToken" class="form-label">Frps 令牌</label>
|
||||
<input type="text" required class="form-control" id="serverToken" name="token"
|
||||
value="{{ $server->token }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="dashboardPwd" class="form-label">密码</label>
|
||||
<input type="text" required value="{{ $server->dashboard_password }}" class="form-control"
|
||||
id="dashboardPwd" name="dashboard_password">
|
||||
</div>
|
||||
<div class="col">
|
||||
|
||||
<h3>端口范围限制</h3>
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
<input type="text" value="{{ $server->min_port }}" required class="form-control"
|
||||
placeholder="最小端口,比如:1024" name="min_port">
|
||||
<input type="text" value="{{ $server->max_port }}" required class="form-control"
|
||||
placeholder="最大端口,比如:65535" name="max_port">
|
||||
</div>
|
||||
<h4>Frps Dashboard 配置</h4>
|
||||
|
||||
<h3>最多隧道数量</h3>
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
<input type="text" value="{{ $server->max_tunnels }}" required class="form-control"
|
||||
placeholder="最多隧道数量,比如:1024个隧道" name="max_tunnels">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="dashboardPort" class="form-label">端口</label>
|
||||
<input type="text" required class="form-control" id="dashboardPort" name="dashboard_port"
|
||||
value="{{ $server->dashboard_port }}">
|
||||
</div>
|
||||
|
||||
<h3>隧道协议限制</h3>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_http" value="1" id="allow_http"
|
||||
@if ($server->allow_http) checked @endif>
|
||||
<label class="form-check-label" for="allow_http">
|
||||
允许 HTTP
|
||||
</label>
|
||||
<br />
|
||||
超文本传输协议
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="dashboardUser" class="form-label">登录用户名</label>
|
||||
<input type="text" required class="form-control" id="dashboardUser" name="dashboard_user"
|
||||
value="{{ $server->dashboard_user }}">
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_https" value="1"
|
||||
id="allow_https" @if ($server->allow_https) checked @endif>
|
||||
<label class="form-check-label" for="allow_https">
|
||||
允许 HTTPS
|
||||
</label>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="dashboardPwd" class="form-label">密码</label>
|
||||
<input type="text" required class="form-control" id="dashboardPwd" name="dashboard_password"
|
||||
value="{{ $server->dashboard_password }}">
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_tcp" value="1"
|
||||
id="allow_tcp" @if ($server->allow_tcp) checked @endif>
|
||||
<label class="form-check-label" for="allow_tcp">
|
||||
允许 TCP
|
||||
</label>
|
||||
</div>
|
||||
<h4>端口范围限制</h4>
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
<input type="text" required class="form-control" placeholder="最小端口, 比如: 10000" name="min_port"
|
||||
value="{{ $server->min_port }}">
|
||||
<input type="text" required class="form-control" placeholder="最大端口, 比如: 65535" name="max_port"
|
||||
value="{{ $server->max_port }}">
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_udp" value="1"
|
||||
id="allow_udp" @if ($server->allow_udp) checked @endif>
|
||||
<label class="form-check-label" for="allow_udp">
|
||||
允许 UDP
|
||||
</label>
|
||||
</div>
|
||||
<h4>最多隧道数量</h4>
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
<input type="text" required class="form-control" placeholder="最多隧道数量, 比如: 1024个隧道"
|
||||
name="max_tunnels" value="{{ $server->max_tunnels }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_stcp" value="1"
|
||||
id="allow_stcp" @if ($server->allow_stcp) checked @endif>
|
||||
<label class="form-check-label" for="allow_stcp">
|
||||
允许 STCP
|
||||
</label>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>隧道协议限制</h4>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_http" value="1"
|
||||
@if ($server->allow_http) checked @endif id="allow_http">
|
||||
<label class="form-check-label" for="allow_http">
|
||||
允许 HTTP
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_xtcp" value="1"
|
||||
id="allow_xtcp" @if ($server->allow_xtcp) checked @endif>
|
||||
<label class="form-check-label" for="allow_xtcp">
|
||||
允许 XTCP
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_https" value="1"
|
||||
@if ($server->allow_https) checked @endif id="allow_https">
|
||||
<label class="form-check-label" for="allow_https">
|
||||
允许 HTTPS
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_sudp" value="1"
|
||||
id="allow_sudp" @if ($server->allow_sudp) checked @endif>
|
||||
<label class="form-check-label" for="allow_sudp">
|
||||
允许 SUDP
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_tcp" value="1"
|
||||
@if ($server->allow_tcp) checked @endif id="allow_tcp">
|
||||
<label class="form-check-label" for="allow_tcp">
|
||||
允许 TCP
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
{{-- checkbox --}}
|
||||
<input type="checkbox" value="1" name="is_china_mainland"
|
||||
id="is_china_mainland" @if ($server->is_china_mainland) checked @endif>
|
||||
<span>服务器是否位于中国大陆</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_udp" value="1"
|
||||
@if ($server->allow_udp) checked @endif id="allow_udp">
|
||||
<label class="form-check-label" for="allow_udp">
|
||||
允许 UDP
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_stcp" value="1"
|
||||
@if ($server->allow_stcp) checked @endif
|
||||
id="allow_stcp">
|
||||
<label class="form-check-label" for="allow_stcp">
|
||||
允许 STCP
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_xtcp" value="1"
|
||||
@if ($server->allow_xtcp) checked @endif
|
||||
id="allow_xtcp">
|
||||
<label class="form-check-label" for="allow_xtcp">
|
||||
允许 XTCP
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_sudp" value="1"
|
||||
id="allow_sudp" @if ($server->allow_sudp) checked @endif>
|
||||
<label class="form-check-label" for="allow_sudp">
|
||||
允许 SUDP
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="col-auto">
|
||||
<button type="submit" class="btn btn-primary mb-3">保存更改</button>
|
||||
</form>
|
||||
<div class="form-check mt-3">
|
||||
<input class="form-check-input" type="checkbox" name="is_china_mainland" value="1"
|
||||
id="is_china_mainland">
|
||||
<label class="form-check-label" for="is_china_mainland">
|
||||
服务器是否位于中国大陆
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<form class="d-inline" action="{{ route('admin.servers.destroy', $server->id) }}" method="post">
|
||||
@method('DELETE')
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-danger mb-3"
|
||||
onclick="confirm('确定删除这个服务器吗?删除后将无法恢复,与此关联的隧道将一并删除。') ? true : event.preventDefault()">删除服务器</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="d-grid mt-3">
|
||||
<button type="submit" class="btn btn-primary mb-3">保存更改</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form action="{{ route('admin.servers.destroy', $server->id) }}" method="post">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit"
|
||||
class="btn btn-danger mb-3"
|
||||
onclick="confirm('确定删除这个服务器吗?删除后将无法恢复,与此关联的隧道将一并删除。') ? true : event.preventDefault()"
|
||||
>
|
||||
删除服务器
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="tab-pane fade show active" id="nav-info" role="tabpanel">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Frps 版本</td>
|
||||
<td>{{ $serverInfo->version ?? 0 }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>绑定端口</td>
|
||||
<td>{{ $serverInfo->bind_port ?? 0 }}</td>
|
||||
</tr>
|
||||
@if ($serverInfo->bind_udp_port ?? 0)
|
||||
<tr>
|
||||
<td>UDP 端口</td>
|
||||
<td>{{ $serverInfo->bind_udp_port ?? 0 }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
<tr>
|
||||
<td>HTTP 端口</td>
|
||||
<td>{{ $serverInfo->vhost_http_port ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>HTTPS 端口</td>
|
||||
<td>{{ $serverInfo->vhost_https_port ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>KCP 端口</td>
|
||||
<td>{{ $serverInfo->kcp_bind_port ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
@if (!empty($serverInfo->subdomain_host))
|
||||
<tr>
|
||||
<td>子域名</td>
|
||||
<td>{{ $serverInfo->subdomain_host ?? 0 }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
<tr>
|
||||
<td>Max PoolCount</td>
|
||||
<td>{{ $serverInfo->max_pool_count ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Max Ports Peer Client</td>
|
||||
<td>{{ $serverInfo->max_ports_per_client ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Heartbeat timeout</td>
|
||||
<td>{{ $serverInfo->heart_beat_timeout ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>自启动以来总入流量</td>
|
||||
<td>{{ unitConversion($serverInfo->total_traffic_in ?? 0) }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>自启动以来总出流量</td>
|
||||
<td>{{ unitConversion($serverInfo->total_traffic_out ?? 0) }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>客户端数量</td>
|
||||
<td>{{ $serverInfo->client_counts ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>当前连接数量</td>
|
||||
<td>{{ $serverInfo->cur_conns ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($server->status == 'down')
|
||||
<span style="color: red">无法连接到服务器。</span>
|
||||
<form action="{{ route('admin.servers.update', $server->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="status" value="up" />
|
||||
<button type="submit">强制标记为在线</button>
|
||||
</form>
|
||||
@else
|
||||
<span style="color: green">正常</span>
|
||||
|
||||
<form action="{{ route('admin.servers.update', $server->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="status" value="down" />
|
||||
<button type="submit">标记为离线</button>
|
||||
</form>
|
||||
<table class="mt-3 table table-hover text-center table-bordered">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Frps 版本</td>
|
||||
<td>{{ $serverInfo->version ?? 0 }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>绑定端口</td>
|
||||
<td>{{ $serverInfo->bind_port ?? 0 }}</td>
|
||||
</tr>
|
||||
@if ($serverInfo->bind_udp_port ?? 0)
|
||||
<tr>
|
||||
<td>UDP 端口</td>
|
||||
<td>{{ $serverInfo->bind_udp_port ?? 0 }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
<tr>
|
||||
<td>HTTP 端口</td>
|
||||
<td>{{ $serverInfo->vhost_http_port ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
@if ($server->status == 'maintenance')
|
||||
<span style="color: red">维护中</span>
|
||||
<tr>
|
||||
<td>HTTPS 端口</td>
|
||||
<td>{{ $serverInfo->vhost_https_port ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
<form action="{{ route('admin.servers.update', $server->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="status" value="down" />
|
||||
<button type="submit">取消维护</button>
|
||||
</form>
|
||||
@else
|
||||
<form action="{{ route('admin.servers.update', $server->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="status" value="maintenance" />
|
||||
<button type="submit">开始维护</button>
|
||||
</form>
|
||||
<tr>
|
||||
<td>KCP 端口</td>
|
||||
<td>{{ $serverInfo->kcp_bind_port ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
@if (!empty($serverInfo->subdomain_host))
|
||||
<tr>
|
||||
<td>子域名</td>
|
||||
<td>{{ $serverInfo->subdomain_host ?? 0 }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('admin.servers.destroy', $server->id) }}" method="POST">
|
||||
<tr>
|
||||
<td>Max PoolCount</td>
|
||||
<td>{{ $serverInfo->max_pool_count ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Max Ports Peer Client</td>
|
||||
<td>{{ $serverInfo->max_ports_per_client ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Heartbeat timeout</td>
|
||||
<td>{{ $serverInfo->heart_beat_timeout ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>自启动以来总入流量</td>
|
||||
<td>{{ unitConversion($serverInfo->total_traffic_in ?? 0) }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>自启动以来总出流量</td>
|
||||
<td>{{ unitConversion($serverInfo->total_traffic_out ?? 0) }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>客户端数量</td>
|
||||
<td>{{ $serverInfo->client_counts ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>当前连接数量</td>
|
||||
<td>{{ $serverInfo->cur_conns ?? 0 }}</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@if ($server->status == 'down')
|
||||
<h4 class="text-danger">无法连接到服务器</h4>
|
||||
<form action="{{ route('admin.servers.update', $server->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit">删除</button>
|
||||
@method('PUT')
|
||||
<input type="hidden" name="status" value="up"/>
|
||||
<button type="submit" class="btn btn-danger mb-2">强制标记为在线</button>
|
||||
</form>
|
||||
@else
|
||||
<span class="text-success">正常</span>
|
||||
|
||||
<div class="tab-pane fade" id="nav-frps" role="tabpanel">
|
||||
<textarea readonly class="form-control" rows="20" cols="80">[common]
|
||||
<form action="{{ route('admin.servers.update', $server->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="status" value="down"/>
|
||||
<button type="submit" class="btn btn-danger mb-2">标记为离线</button>
|
||||
</form>
|
||||
@endif
|
||||
|
||||
|
||||
@if ($server->status == 'maintenance')
|
||||
<span class="text-danger">维护中</span>
|
||||
|
||||
<form action="{{ route('admin.servers.update', $server->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="status" value="down"/>
|
||||
<button type="submit" class="btn btn-warning mb-2">取消维护</button>
|
||||
</form>
|
||||
@else
|
||||
<form action="{{ route('admin.servers.update', $server->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="status" value="maintenance"/>
|
||||
<button type="submit" class="btn btn-warning mb-2">开始维护</button>
|
||||
</form>
|
||||
@endif
|
||||
<div class="alert alert-primary">
|
||||
将这些内容放入: frps.ini
|
||||
</div>
|
||||
<textarea readonly class="form-control mb-3" rows="20" cols="80">[common]
|
||||
bind_port = {{ $server->server_port }}
|
||||
bind_udp_port = {{ $server->server_port }}
|
||||
@if ($server->server_port + 1 > 65535)
|
||||
kcp_bind_port = {{ $server->server_port - 1 }}
|
||||
@else
|
||||
kcp_bind_port = {{ $server->server_port + 1 }}
|
||||
@endif
|
||||
@if ($server->server_port + 1 > 65535)
|
||||
kcp_bind_port = {{ $server->server_port - 1 }}
|
||||
@else
|
||||
kcp_bind_port = {{ $server->server_port + 1 }}
|
||||
@endif
|
||||
token = {{ $server->token }}
|
||||
@if ($server->allow_http)
|
||||
vhost_http_port = 80
|
||||
@endif
|
||||
@if ($server->allow_https)
|
||||
vhost_https_port = 443
|
||||
@endif
|
||||
|
||||
@if ($server->allow_http)
|
||||
vhost_http_port = 80
|
||||
@endif
|
||||
@if ($server->allow_https)
|
||||
vhost_https_port = 443
|
||||
@endif
|
||||
dashboard_port = {{ $server->dashboard_port }}
|
||||
dashboard_user = {{ $server->dashboard_user }}
|
||||
dashboard_pwd = {{ $server->dashboard_password }}
|
||||
@ -328,9 +318,5 @@
|
||||
path = {{ $server->key }}
|
||||
ops = NewProxy
|
||||
|
||||
</textarea>
|
||||
将这些文件放入: frps.ini
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</textarea>
|
||||
</x-app-layout>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<x-app-layout>
|
||||
|
||||
<a href="{{ route('admin.servers.create') }}">添加 Frps 服务器</a>
|
||||
<div class="list-group mt-3">
|
||||
<div class="mt-3">
|
||||
@foreach ($servers as $server)
|
||||
<x-Server-View :server="$server" :url="route('admin.servers.edit', $server->id)" />
|
||||
<x-Server-View :server="$server" :url="route('admin.servers.edit', $server->id)"/>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
<a href="{{ route('admin.servers.edit', $server->id) }}">编辑服务器</a>
|
||||
|
||||
<p>
|
||||
服务器地址: {{ $server->server_address }} <br />
|
||||
允许的协议列表: <br />
|
||||
服务器地址: {{ $server->server_address }} <br/>
|
||||
允许的协议列表: <br/>
|
||||
{{ $server->allow_http ? 'HTTP' : ' ' }}
|
||||
{{ $server->allow_https ? 'HTTPS' : ' ' }}
|
||||
{{ $server->allow_tcp ? 'TCP' : ' ' }}
|
||||
@ -21,81 +21,83 @@
|
||||
<p>端口号范围: {{ $server->min_port }} ~ {{ $server->max_port }} </p>
|
||||
<p>隧道数量: {{ $server->tunnels }} / {{ $server->max_tunnels }} </p>
|
||||
|
||||
<p>客户端数量:{{ $serverInfo->client_counts ?? 0 }},连接数:{{ $serverInfo->cur_conns ?? 0 }},进站流量:{{ unitConversion($serverInfo->total_traffic_in ?? 0) }},出站流量:{{ unitConversion($serverInfo->total_traffic_out ?? 0) }},
|
||||
<p>客户端数量:{{ $serverInfo->client_counts ?? 0 }},连接数:{{ $serverInfo->cur_conns ?? 0 }}
|
||||
,进站流量:{{ unitConversion($serverInfo->total_traffic_in ?? 0) }}
|
||||
,出站流量:{{ unitConversion($serverInfo->total_traffic_out ?? 0) }},
|
||||
{{ $serverInfo->version ?? '离线' }}。
|
||||
</p>
|
||||
|
||||
{{--
|
||||
<h3>使用这个服务器创建隧道</h3>
|
||||
{{--
|
||||
<h3>使用这个服务器创建隧道</h3>
|
||||
|
||||
<form action="{{ route('tunnels.store') }}" method="POST">
|
||||
@csrf
|
||||
<input type="hidden" name="server_id" value="{{ $server->id }}" />
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" name="name">
|
||||
<label>隧道名称</label>
|
||||
</div>
|
||||
<form action="{{ route('tunnels.store') }}" method="POST">
|
||||
@csrf
|
||||
<input type="hidden" name="server_id" value="{{ $server->id }}" />
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" name="name">
|
||||
<label>隧道名称</label>
|
||||
</div>
|
||||
|
||||
<select class="form-select" name="protocol" id="protocol">
|
||||
<option selected>选择协议</option>
|
||||
<option value="http" @if (!$user->verified_at) disabled @endif>HTTP</option>
|
||||
<option value="https" @if (!$user->verified_at) disabled @endif>HTTPS</option>
|
||||
<option value="tcp">TCP</option>
|
||||
<option value="udp">UDP</option>
|
||||
<option value="stcp">STCP</option>
|
||||
</select>
|
||||
<select class="form-select" name="protocol" id="protocol">
|
||||
<option selected>选择协议</option>
|
||||
<option value="http" @if (!$user->verified_at) disabled @endif>HTTP</option>
|
||||
<option value="https" @if (!$user->verified_at) disabled @endif>HTTPS</option>
|
||||
<option value="tcp">TCP</option>
|
||||
<option value="udp">UDP</option>
|
||||
<option value="stcp">STCP</option>
|
||||
</select>
|
||||
|
||||
<div class="form-floating mb-3 mt-3">
|
||||
<input type="text" class="form-control" name="local_address">
|
||||
<label>本地地址</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3 mt-3">
|
||||
<input type="text" class="form-control" name="local_address">
|
||||
<label>本地地址</label>
|
||||
</div>
|
||||
|
||||
<div class="form-floating mb-3 hidden" id="remote">
|
||||
<input type="text" class="form-control" name="remote_port">
|
||||
<label>远程端口</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3 hidden" id="remote">
|
||||
<input type="text" class="form-control" name="remote_port">
|
||||
<label>远程端口</label>
|
||||
</div>
|
||||
|
||||
<div class="form-floating mb-3 hidden" id="domain">
|
||||
<input type="text" class="form-control" name="custom_domain">
|
||||
<label>域名</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3 hidden" id="domain">
|
||||
<input type="text" class="form-control" name="custom_domain">
|
||||
<label>域名</label>
|
||||
</div>
|
||||
|
||||
<div class="form-floating mb-3 hidden" id="sk">
|
||||
<input type="text" class="form-control" name="sk">
|
||||
<label>STCP 密钥</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3 hidden" id="sk">
|
||||
<input type="text" class="form-control" name="sk">
|
||||
<label>STCP 密钥</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">创建</button>
|
||||
<button type="submit" class="btn btn-primary">创建</button>
|
||||
|
||||
</form> --}}
|
||||
{{--
|
||||
<script>
|
||||
const protocol = document.getElementById('protocol');
|
||||
protocol.addEventListener('change', () => {
|
||||
let val = protocol.value;
|
||||
</form> --}}
|
||||
{{--
|
||||
<script>
|
||||
const protocol = document.getElementById('protocol');
|
||||
protocol.addEventListener('change', () => {
|
||||
let val = protocol.value;
|
||||
|
||||
function hide(id) {
|
||||
document.getElementById(id).style.display = 'none';
|
||||
}
|
||||
function hide(id) {
|
||||
document.getElementById(id).style.display = 'none';
|
||||
}
|
||||
|
||||
function show(id) {
|
||||
document.getElementById(id).style.display = 'block';
|
||||
}
|
||||
function show(id) {
|
||||
document.getElementById(id).style.display = 'block';
|
||||
}
|
||||
|
||||
if (val == 'http' || val == 'https') {
|
||||
hide('sk')
|
||||
hide('remote')
|
||||
show('domain')
|
||||
} else if (val == 'tcp' || val == 'udp') {
|
||||
hide('sk')
|
||||
hide('domain')
|
||||
show('remote')
|
||||
} else if (val == 'stcp') {
|
||||
hide('sk')
|
||||
hide('domain')
|
||||
show('sk')
|
||||
}
|
||||
})
|
||||
</script> --}}
|
||||
if (val == 'http' || val == 'https') {
|
||||
hide('sk')
|
||||
hide('remote')
|
||||
show('domain')
|
||||
} else if (val == 'tcp' || val == 'udp') {
|
||||
hide('sk')
|
||||
hide('domain')
|
||||
show('remote')
|
||||
} else if (val == 'stcp') {
|
||||
hide('sk')
|
||||
hide('domain')
|
||||
show('sk')
|
||||
}
|
||||
})
|
||||
</script> --}}
|
||||
|
||||
</x-app-layout>
|
||||
|
@ -1,100 +1,104 @@
|
||||
<x-app-layout>
|
||||
<h1>隧道</h1>
|
||||
<h3>隧道</h3>
|
||||
|
||||
<form name="filter">
|
||||
Host ID: <input type="text" name="host_id" value="{{ Request::get('host_id') }}" />
|
||||
名称: <input type="text" name="name" value="{{ Request::get('name') }}" />
|
||||
<div class="input-group">
|
||||
<input type="text" name="id" value="{{ Request::get('id') }}" class="form-control" placeholder="主机 ID"/>
|
||||
<input type="text" name="name" value="{{ Request::get('name') }}" class="form-control" placeholder="名称"/>
|
||||
|
||||
<select name="protocol">
|
||||
<option value="">协议</option>
|
||||
<option value="http" @if (Request::get('protocol') == 'http') selected @endif>HTTP</option>
|
||||
<option value="https" @if (Request::get('protocol') == 'https') selected @endif>HTTPS</option>
|
||||
<option value="tcp" @if (Request::get('protocol') == 'tcp') selected @endif>TCP</option>
|
||||
<option value="udp" @if (Request::get('protocol') == 'udp') selected @endif>UDP</option>
|
||||
<option value="xtcp" @if (Request::get('protocol') == 'xtcp') selected @endif>XTCP</option>
|
||||
<option value="stcp" @if (Request::get('protocol') == 'stcp') selected @endif>STCP</option>
|
||||
<option value="sudp" @if (Request::get('protocol') == 'sudp') selected @endif>SUDP</option>
|
||||
</select>
|
||||
<select name="protocol" class="form-select">
|
||||
<option value="">协议</option>
|
||||
<option value="http" @if (Request::get('protocol') == 'http') selected @endif>HTTP</option>
|
||||
<option value="https" @if (Request::get('protocol') == 'https') selected @endif>HTTPS</option>
|
||||
<option value="tcp" @if (Request::get('protocol') == 'tcp') selected @endif>TCP</option>
|
||||
<option value="udp" @if (Request::get('protocol') == 'udp') selected @endif>UDP</option>
|
||||
<option value="xtcp" @if (Request::get('protocol') == 'xtcp') selected @endif>XTCP</option>
|
||||
<option value="stcp" @if (Request::get('protocol') == 'stcp') selected @endif>STCP</option>
|
||||
<option value="sudp" @if (Request::get('protocol') == 'sudp') selected @endif>SUDP</option>
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
<button type="submit">筛选</button>
|
||||
<button type="submit" class="btn btn-primary">筛选</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<p>总计: {{ $count }}</p>
|
||||
<div class="alert alert-primary mt-3" role="alert">
|
||||
总计: {{ $count }}
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<table class="mt-3 table table-hover text-center table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>名称</th>
|
||||
<th>客户</th>
|
||||
<th>状态</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>创建时间</th>
|
||||
<th>更新时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>名称</th>
|
||||
<th>客户</th>
|
||||
<th>状态</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>创建时间</th>
|
||||
<th>更新时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
||||
<tbody>
|
||||
@foreach ($hosts as $host)
|
||||
<tr>
|
||||
<td>{{ $host->host_id }}</td>
|
||||
<td>{{ $host->name }}</td>
|
||||
<td>{{ $host->user->name }}</td>
|
||||
<td>{{ $host->status }}</td>
|
||||
@php($cache = Cache::get('frpTunnel_data_' . $host->client_token, ['status' => 'offline']))
|
||||
<td>{{ strtoupper($host->protocol) }}</td>
|
||||
<td>{{ $host->local_address }}</td>
|
||||
@foreach ($hosts as $host)
|
||||
<tr>
|
||||
<td>{{ $host->id }}</td>
|
||||
<td>{{ $host->name }}</td>
|
||||
<td>{{ $host->user->name }}</td>
|
||||
<td>{{ $host->status }}</td>
|
||||
@php($cache = Cache::get('frpTunnel_data_' . $host->client_token, ['status' => 'offline']))
|
||||
<td>{{ strtoupper($host->protocol) }}</td>
|
||||
<td>{{ $host->local_address }}</td>
|
||||
|
||||
@if ($host->protocol == 'http' || $host->protocol == 'https')
|
||||
<td>{{ $host->custom_domain }}</td>
|
||||
@else
|
||||
<td>{{ $host->server->server_address . ':' . $host->remote_port }}</td>
|
||||
@if ($host->protocol == 'http' || $host->protocol == 'https')
|
||||
<td>{{ $host->custom_domain }}</td>
|
||||
@else
|
||||
<td>{{ $host->server->server_address . ':' . $host->remote_port }}</td>
|
||||
@endif
|
||||
|
||||
<td>{{ $cache['cur_conns'] ?? 0 }}</td>
|
||||
<td>{{ unitConversion($cache['today_traffic_in'] ?? 0) }}</td>
|
||||
<td>{{ unitConversion($cache['today_traffic_out'] ?? 0) }}</td>
|
||||
|
||||
<td><a href="{{ route('admin.servers.show', $host->server->id) }}">{{ $host->server->name }}</a></td>
|
||||
|
||||
<td>
|
||||
@if($host->locked_reason)
|
||||
<span class="text-danger">被锁定,因为 {{ $host->locked_reason }}</span>
|
||||
<br/>
|
||||
@endif
|
||||
@if ($cache['status'] === 'online')
|
||||
<span class="text-success">在线</span>
|
||||
@else
|
||||
<span class="text-danger">离线</span>
|
||||
@endif
|
||||
</td>
|
||||
|
||||
<td>{{ $cache['cur_conns'] ?? 0 }}</td>
|
||||
<td>{{ unitConversion($cache['today_traffic_in'] ?? 0) }}</td>
|
||||
<td>{{ unitConversion($cache['today_traffic_out'] ?? 0) }}</td>
|
||||
<td>{{ $host->created_at }}</td>
|
||||
<td>{{ $host->updated_at }}</td>
|
||||
<td>
|
||||
<a href="{{ route('admin.tunnels.show', ['tunnel' => $host]) }}"
|
||||
class="btn btn-sm btn-primary">编辑</a>
|
||||
|
||||
<form action="{{ route('admin.tunnels.destroy', ['tunnel' => $host]) }}" method="POST"
|
||||
onsubmit="return confirm('真的要删除吗?')">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-danger">删除</button>
|
||||
</form>
|
||||
</td>
|
||||
|
||||
<td><a href="{{ route('admin.servers.show', $host->server->id) }}">{{ $host->server->name }}</a></td>
|
||||
|
||||
<td>
|
||||
@if($host->locked_reason)
|
||||
<span class="text-danger">被锁定,因为 {{ $host->locked_reason }}</span>
|
||||
<br />
|
||||
@endif
|
||||
@if ($cache['status'] === 'online')
|
||||
<span class="text-success">在线</span>
|
||||
@else
|
||||
<span class="text-danger">离线</span>
|
||||
@endif
|
||||
</td>
|
||||
|
||||
<td>{{ $host->created_at }}</td>
|
||||
<td>{{ $host->updated_at }}</td>
|
||||
<td>
|
||||
<a href="{{ route('admin.tunnels.show', ['tunnel' => $host]) }}">编辑</a>
|
||||
|
||||
<form action="{{ route('admin.tunnels.destroy', ['tunnel' => $host]) }}" method="POST"
|
||||
onsubmit="return confirm('真的要删除吗?')">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit">删除</button>
|
||||
</form>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
@ -2,37 +2,38 @@
|
||||
|
||||
@php($cache = Cache::get('frpTunnel_data_' . $tunnel->client_token, []))
|
||||
|
||||
<p> 隧道状态:
|
||||
<p>隧道状态:
|
||||
@if ($cache['status'] ?? false === 'online')
|
||||
<span style="color: green">在线</span>
|
||||
<span class="text-success">在线</span>
|
||||
@else
|
||||
<span style="color: red">离线</span>
|
||||
<span class="text-danger">离线</span>
|
||||
@endif
|
||||
</p>
|
||||
|
||||
<p> 连接数:{{ $cache['cur_conns'] ?? 0 }}</p>
|
||||
<p> 下载流量:{{ unitConversion($cache['today_traffic_in'] ?? 0) }}</p>
|
||||
<p> 上载流量:{{ unitConversion($cache['today_traffic_out'] ?? 0) }}</p>
|
||||
<p>连接数: {{ $cache['cur_conns'] ?? 0 }}</p>
|
||||
<p>下载流量: {{ unitConversion($cache['today_traffic_in'] ?? 0) }}</p>
|
||||
<p>上载流量: {{ unitConversion($cache['today_traffic_out'] ?? 0) }}</p>
|
||||
|
||||
<hr />
|
||||
<hr/>
|
||||
<p>如果填写锁定原因,隧道将会立即下线,并且客户端无法登录。</p>
|
||||
<form action="{{ route('admin.tunnels.update', $tunnel) }}" method="POST">
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
<input type="text" name="locked_reason" @if($tunnel->locked_reason) value="{{$tunnel->locked_reason}}" @endif placeholder="留空解除" />
|
||||
<button type="submit">确定</button>
|
||||
<div class="input-group">
|
||||
<input type="text" name="locked_reason" @if($tunnel->locked_reason) value="{{$tunnel->locked_reason}}"
|
||||
@endif placeholder="留空解除" class="form-control"/>
|
||||
<button type="submit" class="btn btn-primary">确定</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
{{-- @if ($host->protocol == 'http' || $host->protocol == 'https')
|
||||
<h3>网页截图</h3>
|
||||
<img src="" />
|
||||
@endif --}}
|
||||
|
||||
<h3>配置文件</h3>
|
||||
<textarea id="config" cols="80" rows="20" readonly="readonly"></textarea>
|
||||
<h4 class="mt-3 mb-3">配置文件</h4>
|
||||
<textarea id="config" cols="80" rows="20" readonly class="form-control"></textarea>
|
||||
<script>
|
||||
let tunnel_config = {!! $tunnel !!}
|
||||
// let put_config()
|
||||
|
@ -1,54 +1,65 @@
|
||||
<x-app-layout>
|
||||
<h1>已经发现的客户</h1>
|
||||
<h3>已经发现的客户</h3>
|
||||
|
||||
<p>总计: {{ $count }}</p>
|
||||
<div class="alert alert-primary mt-3" role="alert">
|
||||
总计: {{ $count }}
|
||||
</div>
|
||||
|
||||
|
||||
<form name="filter">
|
||||
用户 ID: <input type="text" name="id" value="{{ Request::get('id') }}" />
|
||||
名称: <input type="text" name="name" value="{{ Request::get('name') }}" />
|
||||
邮箱: <input type="text" name="email" value="{{ Request::get('email') }}" />
|
||||
|
||||
<button type="submit">筛选</button>
|
||||
<div class="input-group">
|
||||
<input type="text" name="id" value="{{ Request::get('id') }}" class="form-control" placeholder="用户 ID"/>
|
||||
<input type="text" name="name" value="{{ Request::get('name') }}" class="form-control" placeholder="名称"/>
|
||||
<input type="email" name="email" value="{{ Request::get('email') }}" class="form-control"
|
||||
placeholder="邮箱"/>
|
||||
<button type="submit" class="btn btn-primary">筛选</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<table>
|
||||
<table class="mt-3 table table-hover text-center table-bordered">
|
||||
{{-- 表头 --}}
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>名称</th>
|
||||
<th>邮箱</th>
|
||||
<th>剩余流量</th>
|
||||
{{-- <th>发现时间</th>
|
||||
<th>更新时间</th> --}}
|
||||
{{-- <th>操作</th> --}}
|
||||
</tr>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>名称</th>
|
||||
<th>邮箱</th>
|
||||
<th>剩余流量</th>
|
||||
{{-- <th>发现时间</th>
|
||||
<th>更新时间</th> --}}
|
||||
{{-- <th>操作</th> --}}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
{{-- 表内容 --}}
|
||||
<tbody>
|
||||
@foreach ($users as $user)
|
||||
<tr>
|
||||
<td>{{ $user->id }}</td>
|
||||
<td>{{ $user->name }}</td>
|
||||
<td>{{ $user->email }}</td>
|
||||
<td><input type="text" value="{{ $user->traffic ?? 0 }}"
|
||||
onchange="updateTraffic({{ $user->id }}, this)" /> GB</td>
|
||||
{{-- <td>{{ $user->created_at }}</td>
|
||||
<td>{{ $user->updated_at }}</td> --}}
|
||||
{{-- <td>
|
||||
<a href="{{ route('user.show', $user) }}">查看</a>
|
||||
<a href="{{ route('user.edit', $user) }}">编辑</a>
|
||||
<form action="{{ route('user.destroy', $user) }}" method="POST">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit">删除</button>
|
||||
</form>
|
||||
</td> --}}
|
||||
</tr>
|
||||
@endforeach
|
||||
@foreach ($users as $user)
|
||||
<tr>
|
||||
<td>{{ $user->id }}</td>
|
||||
<td>{{ $user->name }}</td>
|
||||
<td>{{ $user->email }}</td>
|
||||
<td>
|
||||
<div class="input-group">
|
||||
<input type="text"
|
||||
value="{{ $user->traffic ?? 0 }}"
|
||||
onchange="updateTraffic({{ $user->id }}, this)"
|
||||
class="form-control"/>
|
||||
<span class="input-group-text">GB</span>
|
||||
</div>
|
||||
</td>
|
||||
{{-- <td>{{ $user->created_at }}</td>
|
||||
<td>{{ $user->updated_at }}</td> --}}
|
||||
{{-- <td>
|
||||
<a href="{{ route('user.show', $user) }}">查看</a>
|
||||
<a href="{{ route('user.edit', $user) }}">编辑</a>
|
||||
<form action="{{ route('user.destroy', $user) }}" method="POST">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit">删除</button>
|
||||
</form>
|
||||
</td> --}}
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -78,7 +89,7 @@ function updateTraffic(userId, input) {
|
||||
traffic: input.value
|
||||
}));
|
||||
|
||||
xhr.onload = function() {
|
||||
xhr.onload = function () {
|
||||
if (xhr.status != 200) {
|
||||
alert(`Error ${xhr.status}: ${xhr.statusText}`);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navMenu"
|
||||
aria-controls="navMenu" aria-expanded="false" aria-label="Toggle navigation">
|
||||
aria-controls="navMenu" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
@ -34,15 +34,16 @@
|
||||
@if (auth()->user()->is_admin)
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" aria-current="page"
|
||||
href="{{ route('servers.create') }}">创建服务器</a>
|
||||
href="{{ route('servers.create') }}">创建服务器</a>
|
||||
</li>
|
||||
@endif
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" aria-current="page" href="{{ route('tunnels.create') }}">创建隧道</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" role="button" data-bs-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<a class="nav-link dropdown-toggle" role="button" data-bs-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
{{ auth()->user()->name }}
|
||||
</a>
|
||||
|
||||
@ -50,7 +51,7 @@
|
||||
<a class="dropdown-item" href="{{ route('servers.index') }}">服务器列表</a>
|
||||
<a class="dropdown-item" href="{{ route('tunnels.index') }}">隧道列表</a>
|
||||
<a class="dropdown-item" href="#"
|
||||
onclick="axios.post(route('login.logout')).then(() => {window.location.reload()})">
|
||||
onclick="axios.post(route('login.logout')).then(() => {window.location.reload()})">
|
||||
注销 <span x-html="config.app_html"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<hr />
|
||||
<hr/>
|
||||
<div>
|
||||
<a href="{{ $url }}" class="list-group-item list-group-item-action">
|
||||
{{-- <div class="d-flex w-100 justify-content-between">
|
||||
@ -6,24 +6,31 @@
|
||||
<small class="text-muted">{{ $server->updated_at->diffForHumans() }}</small>
|
||||
</div> --}}
|
||||
{{-- <p class="mb-1"></p> --}}
|
||||
{{ $server->name }}
|
||||
<br />
|
||||
<h4>{{ $server->name }}</h4>
|
||||
{{ $server->updated_at->diffForHumans() }}
|
||||
</a>
|
||||
|
||||
<p>
|
||||
@if ($server->status == "down")
|
||||
<span class="text-danger">服务器状态 down</span>
|
||||
@else
|
||||
<span class="text-success">服务器状态 up</span>
|
||||
@endif
|
||||
</p>
|
||||
|
||||
<small class="text-muted">
|
||||
<p>状态: {{ $server->status }}</p>
|
||||
服务器地址: {{ $server->server_address }}, 支持的协议:
|
||||
{{ $server->allow_http ? 'HTTP' : ' ' }}
|
||||
{{ $server->allow_https ? 'HTTPS' : ' ' }}
|
||||
{{ $server->allow_tcp ? 'TCP' : ' ' }}
|
||||
{{ $server->allow_udp ? 'UDP' : ' ' }}
|
||||
{{ $server->allow_STCP ? 'STCP' : ' ' }}。
|
||||
服务器位于@if ($server->is_china_mainland)
|
||||
<span style="color: green">中国大陆</span>
|
||||
服务器位于
|
||||
@if ($server->is_china_mainland)
|
||||
<span class="text-success">中国大陆</span>
|
||||
@else
|
||||
<span style="color: red">境外</span>
|
||||
<span class="text-danger">境外</span>
|
||||
@endif
|
||||
</small>
|
||||
</div>
|
||||
<hr />
|
||||
<hr/>
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
|
||||
<body>
|
||||
<span>欢迎使用: {{ config('app.display_name') }}</span>
|
||||
<span>欢迎使用: {{ config('app.display_name') }}</span>
|
||||
|
||||
<a href="{{ route('login') }}">登录</a>
|
||||
<a href="{{ route('login') }}">登录</a>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -8,65 +8,98 @@
|
||||
|
||||
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
|
||||
|
||||
<title>{{ config('app.name', 'LAE') }}</title>
|
||||
<title>{{ config('app.name', 'LAE') }} 后台</title>
|
||||
|
||||
@vite(['vendor/twbs/bootstrap/dist/css/bootstrap.min.css', 'vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js'])
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="top">
|
||||
@auth
|
||||
<h3 style="text-align: center">{{ config('app.display_name') }} 后台</h3>
|
||||
{{-- 顶部横向菜单 --}}
|
||||
<div class="top-menu">
|
||||
<ul>
|
||||
<li><a href="/">首页</a></li>
|
||||
<li><a href="{{ route('admin.users.index') }}">用户</a></li>
|
||||
<li><a href="{{ route('admin.tunnels.index') }}">隧道</a></li>
|
||||
<li><a href="{{ route('admin.servers.index') }}">服务器</a></li>
|
||||
<li><a href="{{ route('logout') }}">退出</a></li>
|
||||
</ul>
|
||||
<div id="top">
|
||||
@auth
|
||||
<nav class="navbar navbar-expand-lg bg-body-tertiary shadow-sm">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="{{ route('admin.index') }}">{{ config('app.display_name') }} 后台</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.index') }}">首页</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.users.index') }}">用户</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.tunnels.index') }}">隧道</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.servers.index') }}">服务器</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav ml-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="javascript:location.reload()">重新加载</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
{{ \Illuminate\Support\Facades\Auth::user()->email }}
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a class="dropdown-item" href="{{ route('index') }}">
|
||||
客户首页
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown-divider"></li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="{{ route('admin.logout') }}">
|
||||
退出登录
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endauth
|
||||
</nav>
|
||||
@endauth
|
||||
</div>
|
||||
{{-- display error --}}
|
||||
|
||||
{{-- if has success --}}
|
||||
@if (session('success'))
|
||||
<p style="color: green">
|
||||
{{ session('success') }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
@if (session('error'))
|
||||
<p style="color: red">
|
||||
{{ session('error') }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
@if ($errors->any())
|
||||
<div>
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li style="color: red;">{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
{{-- display error --}}
|
||||
@endif
|
||||
|
||||
{{-- if has success --}}
|
||||
@if (session('success'))
|
||||
<p style="color: green">
|
||||
{{ session('success') }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
@if (session('error'))
|
||||
<p style="color: red">
|
||||
{{ session('error') }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
@if ($errors->any())
|
||||
<div>
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li style="color: red;">{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<button onclick="location.reload()">重新加载</button>
|
||||
<button onclick="location.reload()">重新加载</button>
|
||||
<button onclick="location.reload()">重新加载</button>
|
||||
<button onclick="location.reload()">重新加载</button>
|
||||
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="min-h-screen bg-gray-100">
|
||||
{{-- 摆烂 --}}
|
||||
<!-- Page Content -->
|
||||
<main>
|
||||
{{ $slot }}
|
||||
</main>
|
||||
</div>
|
||||
<div class="container mt-4">
|
||||
{{-- 摆烂 --}}
|
||||
<!-- Page Content -->
|
||||
<main>
|
||||
{{ $slot }}
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
@ -2,10 +2,10 @@
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
|
||||
<meta name="format-detection" content="telephone=no"/>
|
||||
|
||||
<title>{{ config('app.display_name') }}</title>
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user