refactor: 重构规范部分代码、邮件队列增加失败重试、去除多个支付方式、更新依赖

This commit is contained in:
xboard
2024-04-10 00:51:03 +08:00
parent ec63e05575
commit 4c6c7182e2
50 changed files with 421 additions and 1005 deletions

View File

@@ -4,8 +4,8 @@ namespace App\Http\Controllers\V1\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\ConfigSave;
use App\Jobs\SendEmailJob;
use App\Models\Setting;
use App\Services\MailService;
use App\Services\TelegramService;
use App\Utils\Dict;
use Illuminate\Http\Request;
@@ -33,7 +33,7 @@ class ConfigController extends Controller
public function testSendMail(Request $request)
{
$obj = new SendEmailJob([
$mailLog = MailService::sendEmail([
'email' => $request->user['email'],
'subject' => 'This is xboard test email',
'template_name' => 'notify',
@@ -45,7 +45,7 @@ class ConfigController extends Controller
]);
return response([
'data' => true,
'log' => $obj->handle()
'log' => $mailLog
]);
}

View File

@@ -160,13 +160,13 @@ class OrderController extends Controller
$order->total_amount = $request->input('total_amount');
if ($order->period === 'reset_price') {
$order->type = 4;
$order->type = Order::TYPE_RESET_TRAFFIC;
} else if ($user->plan_id !== NULL && $order->plan_id !== $user->plan_id) {
$order->type = 3;
$order->type = Order::TYPE_UPGRADE;
} else if ($user->expired_at > time() && $order->plan_id == $user->plan_id) {
$order->type = 2;
$order->type = Order::TYPE_RENEWAL;
} else {
$order->type = 1;
$order->type = Order::TYPE_NEW_PURCHASE;
}
$orderService->setInvite($user);

View File

@@ -19,8 +19,7 @@ class GroupController extends Controller
return $this->success([ServerGroup::find($request->input('group_id'))]);
}
$serverGroups = ServerGroup::get();
$serverService = new ServerService();
$servers = $serverService->getAllServers();
$servers = ServerService::getAllServers();
foreach ($serverGroups as $k => $v) {
$serverGroups[$k]['user_count'] = User::where('group_id', $v['id'])->count();
$serverGroups[$k]['server_count'] = 0;

View File

@@ -12,8 +12,7 @@ class ManageController extends Controller
{
public function getNodes(Request $request)
{
$serverService = new ServerService();
return $this->success($serverService->getAllServers());
return $this->success(ServerService::getAllServers());
}
public function sort(Request $request)

View File

@@ -2,12 +2,10 @@
namespace App\Http\Controllers\V1\Admin\Server;
use App\Exceptions\ApiException;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\ServerTrojanSave;
use App\Http\Requests\Admin\ServerTrojanUpdate;
use App\Models\ServerTrojan;
use App\Services\ServerService;
use Illuminate\Http\Request;
class TrojanController extends Controller
@@ -75,10 +73,4 @@ class TrojanController extends Controller
ServerTrojan::create($server->toArray());
return $this->success(true);
}
public function viewConfig(Request $request)
{
$serverService = new ServerService();
$config = $serverService->getTrojanConfig($request->input('node_id'), 23333);
return $this->success($config);
}
}

View File

@@ -80,7 +80,7 @@ class TicketController extends Controller
]);
try {
$ticket = Ticket::findOrFail($request->input('id'));
$ticket->status = 1;
$ticket->status = Ticket::STATUS_CLOSED;
$ticket->save();
return $this->success(true);
} catch (ModelNotFoundException $e) {

View File

@@ -17,8 +17,7 @@ class AppController extends Controller
$user = $request->user;
$userService = new UserService();
if ($userService->isAvailable($user)) {
$serverService = new ServerService();
$servers = $serverService->getAvailableServers($user);
$servers = ServerService::getAvailableServers($user);
}
$defaultConfig = base_path() . '/resources/rules/app.clash.yaml';
$customConfig = base_path() . '/resources/rules/custom.app.clash.yaml';

View File

@@ -65,8 +65,7 @@ class ClientController extends Controller
$region = $geo['region'] ?? null;
// 获取服务器列表
$serverService = new ServerService();
$servers = $serverService->getAvailableServers($user);
$servers = ServerService::getAvailableServers($user);
// 判断不满足,不满足的直接过滤掉
$serversFiltered = collect($servers)->reject(function ($server) use ($typesArr, $filterArr, $region, $supportHy2){

View File

@@ -17,14 +17,15 @@ class PaymentController extends Controller
try {
$paymentService = new PaymentService($method, null, $uuid);
$verify = $paymentService->notify($request->input());
if (!$verify) return $this->fail([422,'verify error']);
if (!$verify)
return $this->fail([422, 'verify error']);
if (!$this->handle($verify['trade_no'], $verify['callback_no'])) {
return $this->fail([400,'handle error']);
return $this->fail([400, 'handle error']);
}
return (isset($verify['custom_result']) ? $verify['custom_result'] : 'success');
} catch (\Exception $e) {
\Log::error($e);
return $this->fail([500,'fail']);
return $this->fail([500, 'fail']);
}
}
@@ -32,9 +33,10 @@ class PaymentController extends Controller
{
$order = Order::where('trade_no', $tradeNo)->first();
if (!$order) {
return $this->fail([400202,'order is not found']);
return $this->fail([400202, 'order is not found']);
}
if ($order->status !== 0) return true;
if ($order->status !== Order::STATUS_PENDING)
return true;
$orderService = new OrderService($order);
if (!$orderService->paid($callbackNo)) {
return false;

View File

@@ -13,24 +13,23 @@ class TelegramController extends Controller
protected $commands = [];
protected $telegramService;
public function __construct(Request $request)
public function __construct(TelegramService $telegramService)
{
if ($request->input('access_token') !== md5(admin_setting('telegram_bot_token'))) {
throw new ApiException('access_token is error', 401);
}
$this->telegramService = new TelegramService();
$this->telegramService = $telegramService;
}
public function webhook(Request $request)
{
if ($request->input('access_token') !== md5(admin_setting('telegram_bot_token'))) {
throw new ApiException('access_token is error', 401);
}
$data = json_decode(get_request_content(),true);
$this->formatMessage($data);
$this->formatChatJoinRequest($data);
$this->handle();
}
public function handle()
private function handle()
{
if (!$this->msg) return;
$msg = $this->msg;
@@ -68,7 +67,7 @@ class TelegramController extends Controller
}
}
public function getBotName()
private function getBotName()
{
$response = $this->telegramService->getMe();
return $response->result->username;

View File

@@ -2,7 +2,6 @@
namespace App\Http\Controllers\V1\Passport;
use App\Exceptions\ApiException;
use App\Helpers\ResponseEnum;
use App\Http\Controllers\Controller;
use App\Http\Requests\Passport\AuthForget;

View File

@@ -18,16 +18,6 @@ use Illuminate\Support\Facades\Cache;
class DeepbworkController extends Controller
{
CONST V2RAY_CONFIG = '{"log":{"loglevel":"debug","access":"access.log","error":"error.log"},"api":{"services":["HandlerService","StatsService"],"tag":"api"},"dns":{},"stats":{},"inbounds":[{"port":443,"protocol":"vmess","settings":{"clients":[]},"sniffing":{"enabled":true,"destOverride":["http","tls"]},"streamSettings":{"network":"tcp"},"tag":"proxy"},{"listen":"127.0.0.1","port":23333,"protocol":"dokodemo-door","settings":{"address":"0.0.0.0"},"tag":"api"}],"outbounds":[{"protocol":"freedom","settings":{}},{"protocol":"blackhole","settings":{},"tag":"block"}],"routing":{"rules":[{"type":"field","inboundTag":"api","outboundTag":"api"}]},"policy":{"levels":{"0":{"handshake":4,"connIdle":300,"uplinkOnly":5,"downlinkOnly":30,"statsUserUplink":true,"statsUserDownlink":true}}}}';
public function __construct(Request $request)
{
$token = $request->input('token');
if (empty($token)) {
throw new ApiException('token is null');
}
if ($token !== admin_setting('server_token')) {
throw new ApiException('token is error');
}
}
// 后端获取用户
public function user(Request $request)
@@ -39,8 +29,7 @@ class DeepbworkController extends Controller
return $this->fail([400,'节点不存在']);
}
Cache::put(CacheKey::get('SERVER_VMESS_LAST_CHECK_AT', $server->id), time(), 3600);
$serverService = new ServerService();
$users = $serverService->getAvailableUsers($server->group_id);
$users = ServerService::getAvailableUsers($server->group_id);
$result = [];
foreach ($users as $user) {
$user->v2ray_user = [

View File

@@ -17,17 +17,6 @@ use Illuminate\Support\Facades\Cache;
*/
class ShadowsocksTidalabController extends Controller
{
public function __construct(Request $request)
{
$token = $request->input('token');
if (empty($token)) {
throw new ApiException('token is null');
}
if ($token !== admin_setting('server_token')) {
throw new ApiException('token is error');
}
}
// 后端获取用户
public function user(Request $request)
{
@@ -38,8 +27,7 @@ class ShadowsocksTidalabController extends Controller
return $this->fail([400,'节点不存在']);
}
Cache::put(CacheKey::get('SERVER_SHADOWSOCKS_LAST_CHECK_AT', $server->id), time(), 3600);
$serverService = new ServerService();
$users = $serverService->getAvailableUsers($server->group_id);
$users = ServerService::getAvailableUsers($server->group_id);
$result = [];
foreach ($users as $user) {
array_push($result, [

View File

@@ -17,17 +17,7 @@ use Illuminate\Support\Facades\Cache;
*/
class TrojanTidalabController extends Controller
{
CONST TROJAN_CONFIG = '{"run_type":"server","local_addr":"0.0.0.0","local_port":443,"remote_addr":"www.taobao.com","remote_port":80,"password":[],"ssl":{"cert":"server.crt","key":"server.key","sni":"domain.com"},"api":{"enabled":true,"api_addr":"127.0.0.1","api_port":10000}}';
public function __construct(Request $request)
{
$token = $request->input('token');
if (empty($token)) {
throw new ApiException('token is null');
}
if ($token !== admin_setting('server_token')) {
throw new ApiException('token is error');
}
}
const TROJAN_CONFIG = '{"run_type":"server","local_addr":"0.0.0.0","local_port":443,"remote_addr":"www.taobao.com","remote_port":80,"password":[],"ssl":{"cert":"server.crt","key":"server.key","sni":"domain.com"},"api":{"enabled":true,"api_addr":"127.0.0.1","api_port":10000}}';
// 后端获取用户
public function user(Request $request)
@@ -36,11 +26,10 @@ class TrojanTidalabController extends Controller
$nodeId = $request->input('node_id');
$server = ServerTrojan::find($nodeId);
if (!$server) {
return $this->fail([400,'节点不存在']);
return $this->fail([400, '节点不存在']);
}
Cache::put(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $server->id), time(), 3600);
$serverService = new ServerService();
$users = $serverService->getAvailableUsers($server->group_id);
$users = ServerService::getAvailableUsers($server->group_id);
$result = [];
foreach ($users as $user) {
$user->trojan_user = [
@@ -50,8 +39,8 @@ class TrojanTidalabController extends Controller
array_push($result, $user);
}
$eTag = sha1(json_encode($result));
if (strpos($request->header('If-None-Match'), $eTag) !== false ) {
return response(null,304);
if (strpos($request->header('If-None-Match'), $eTag) !== false) {
return response(null, 304);
}
return response([
'msg' => 'ok',
@@ -92,7 +81,7 @@ class TrojanTidalabController extends Controller
$request->validate([
'node_id' => 'required',
'local_port' => 'required'
],[
], [
'node_id.required' => '节点ID不能为空',
'local_port.required' => '本地端口不能为空'
]);
@@ -100,10 +89,10 @@ class TrojanTidalabController extends Controller
$json = $this->getTrojanConfig($request->input('node_id'), $request->input('local_port'));
} catch (\Exception $e) {
\Log::error($e);
return $this->fail([500,'配置获取失败']);
return $this->fail([500, '配置获取失败']);
}
return(json_encode($json, JSON_UNESCAPED_UNICODE));
return (json_encode($json, JSON_UNESCAPED_UNICODE));
}
private function getTrojanConfig(int $nodeId, int $localPort)

View File

@@ -2,7 +2,6 @@
namespace App\Http\Controllers\V1\Server;
use App\Exceptions\ApiException;
use App\Http\Controllers\Controller;
use App\Services\ServerService;
use App\Services\UserService;
@@ -10,40 +9,23 @@ use App\Utils\CacheKey;
use App\Utils\Helper;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
class UniProxyController extends Controller
{
private $nodeType;
private $nodeInfo;
private $nodeId;
private $serverService;
public function __construct(ServerService $serverService, Request $request)
{
$this->serverService = $serverService;
$this->nodeId = $request->input('node_id');
$this->nodeType = $request->input('node_type');
$this->nodeInfo = $this->serverService->getServer($this->nodeId, $this->nodeType);
if(!$this->nodeInfo) {
throw new ApiException('server is not exist', 500);
};
}
// 后端获取用户
public function user(Request $request)
{
ini_set('memory_limit', -1);
Cache::put(CacheKey::get('SERVER_' . strtoupper($this->nodeType) . '_LAST_CHECK_AT', $this->nodeInfo->id), time(), 3600);
$users = $this->serverService->getAvailableUsers($this->nodeInfo->group_id);
$users = $users->toArray();
Cache::put(CacheKey::get('SERVER_' . strtoupper($request->input('node_type')) . '_LAST_CHECK_AT', $request->input('node_id')), time(), 3600);
$users = ServerService::getAvailableUsers($request->input('node_info')->group_id)->toArray();
$response['users'] = $users;
$eTag = sha1(json_encode($response));
if (strpos($request->header('If-None-Match'), $eTag) !== false ) {
if (strpos($request->header('If-None-Match'), $eTag) !== false) {
return response(null, 304);
};
}
return response($response)->header('ETag', "\"{$eTag}\"");
}
@@ -51,14 +33,18 @@ class UniProxyController extends Controller
// 后端提交数据
public function push(Request $request)
{
$data = get_request_content();
$data = json_decode($data, true);
$data = $request->validate([
"*.0" => 'integer',
"*.1" => 'integer'
]);
$nodeType = $request->input('node_type');
$nodeId = $request->input('node_id');
// 增加单节点多服务器统计在线人数
$ip = $request->ip();
$id = $request->input("id");
$time = time();
$cacheKey = CacheKey::get('MULTI_SERVER_' . strtoupper($this->nodeType) . '_ONLINE_USER', $this->nodeInfo->id);
$cacheKey = CacheKey::get('MULTI_SERVER_' . strtoupper($nodeType) . '_ONLINE_USER', $nodeId);
// 1、获取节点节点在线人数缓存
$onlineUsers = Cache::get($cacheKey) ?? [];
@@ -87,91 +73,92 @@ class UniProxyController extends Controller
Cache::put($cacheKey, $onlineUsers, 3600);
$online_user = $onlineCollection->sum('online_user');
Cache::put(CacheKey::get('SERVER_' . strtoupper($this->nodeType) . '_ONLINE_USER', $this->nodeInfo->id), $online_user, 3600);
Cache::put(CacheKey::get('SERVER_' . strtoupper($this->nodeType) . '_LAST_PUSH_AT', $this->nodeInfo->id), time(), 3600);
Cache::put(CacheKey::get('SERVER_' . strtoupper($nodeType) . '_ONLINE_USER', $nodeId), $online_user, 3600);
Cache::put(CacheKey::get('SERVER_' . strtoupper($nodeType) . '_LAST_PUSH_AT', $nodeId), time(), 3600);
$userService = new UserService();
$userService->trafficFetch($this->nodeInfo->toArray(), $this->nodeType, $data , $ip);
$userService->trafficFetch($request->input('node_info')->toArray(), $nodeType, $data, $ip);
return $this->success(true);
}
// 后端获取配置
public function config(Request $request)
{
switch ($this->nodeType) {
$nodeType = $request->input('node_type');
$nodeInfo = $request->input('node_info');
switch ($nodeType) {
case 'shadowsocks':
$response = [
'server_port' => $this->nodeInfo->server_port,
'cipher' => $this->nodeInfo->cipher,
'obfs' => $this->nodeInfo->obfs,
'obfs_settings' => $this->nodeInfo->obfs_settings
'server_port' => $nodeInfo->server_port,
'cipher' => $nodeInfo->cipher,
'obfs' => $nodeInfo->obfs,
'obfs_settings' => $nodeInfo->obfs_settings
];
if ($this->nodeInfo->cipher === '2022-blake3-aes-128-gcm') {
$response['server_key'] = Helper::getServerKey($this->nodeInfo->created_at, 16);
if ($nodeInfo->cipher === '2022-blake3-aes-128-gcm') {
$response['server_key'] = Helper::getServerKey($nodeInfo->created_at, 16);
}
if ($this->nodeInfo->cipher === '2022-blake3-aes-256-gcm') {
$response['server_key'] = Helper::getServerKey($this->nodeInfo->created_at, 32);
if ($nodeInfo->cipher === '2022-blake3-aes-256-gcm') {
$response['server_key'] = Helper::getServerKey($nodeInfo->created_at, 32);
}
break;
case 'vmess':
$response = [
'server_port' => $this->nodeInfo->server_port,
'network' => $this->nodeInfo->network,
'networkSettings' => $this->nodeInfo->networkSettings,
'tls' => $this->nodeInfo->tls
'server_port' => $nodeInfo->server_port,
'network' => $nodeInfo->network,
'networkSettings' => $nodeInfo->networkSettings,
'tls' => $nodeInfo->tls
];
break;
case 'trojan':
$response = [
'host' => $this->nodeInfo->host,
'server_port' => $this->nodeInfo->server_port,
'server_name' => $this->nodeInfo->server_name,
'network' => $this->nodeInfo->network,
'networkSettings' => $this->nodeInfo->networkSettings,
'host' => $nodeInfo->host,
'server_port' => $nodeInfo->server_port,
'server_name' => $nodeInfo->server_name,
'network' => $nodeInfo->network,
'networkSettings' => $nodeInfo->networkSettings,
];
break;
case 'hysteria':
$response = [
'version' => $this->nodeInfo->version,
'host' => $this->nodeInfo->host,
'server_port' => $this->nodeInfo->server_port,
'server_name' => $this->nodeInfo->server_name,
'up_mbps' => $this->nodeInfo->up_mbps,
'down_mbps' => $this->nodeInfo->down_mbps,
'obfs' => $this->nodeInfo->is_obfs ? Helper::getServerKey($this->nodeInfo->created_at, 16) : null
'version' => $nodeInfo->version,
'host' => $nodeInfo->host,
'server_port' => $nodeInfo->server_port,
'server_name' => $nodeInfo->server_name,
'up_mbps' => $nodeInfo->up_mbps,
'down_mbps' => $nodeInfo->down_mbps,
'obfs' => $nodeInfo->is_obfs ? Helper::getServerKey($nodeInfo->created_at, 16) : null
];
break;
case "vless":
$response = [
'server_port' => $this->nodeInfo->server_port,
'network' => $this->nodeInfo->network,
'network_settings' => $this->nodeInfo->network_settings,
'networkSettings' => $this->nodeInfo->network_settings,
'tls' => $this->nodeInfo->tls,
'flow' => $this->nodeInfo->flow,
'tls_settings' => $this->nodeInfo->tls_settings
'server_port' => $nodeInfo->server_port,
'network' => $nodeInfo->network,
'network_settings' => $nodeInfo->network_settings,
'networkSettings' => $nodeInfo->network_settings,
'tls' => $nodeInfo->tls,
'flow' => $nodeInfo->flow,
'tls_settings' => $nodeInfo->tls_settings
];
break;
}
$response['base_config'] = [
'push_interval' => (int)admin_setting('server_push_interval', 60),
'pull_interval' => (int)admin_setting('server_pull_interval', 60)
'push_interval' => (int) admin_setting('server_push_interval', 60),
'pull_interval' => (int) admin_setting('server_pull_interval', 60)
];
if ($this->nodeInfo['route_id']) {
$response['routes'] = $this->serverService->getRoutes($this->nodeInfo['route_id']);
if ($nodeInfo['route_id']) {
$response['routes'] = ServerService::getRoutes($nodeInfo['route_id']);
}
$eTag = sha1(json_encode($response));
if (strpos($request->header('If-None-Match'), $eTag) !== false ) {
return response(null,304);
if (strpos($request->header('If-None-Match'), $eTag) !== false) {
return response(null, 304);
}
return response($response)->header('ETag', "\"{$eTag}\"");
}
// 后端提交在线数据
public function alive(Request $request)
{
// 后端提交在线数据
public function alive(Request $request)
{
return $this->success(true);
}
}
}

View File

@@ -73,7 +73,7 @@ class TicketController extends Controller
if (!$ticket) {
return $this->fail([400202,'工单不存在']);
}
$ticket->status = 1;
$ticket->status = Ticket::STATUS_CLOSED;
if (!$ticket->save()) {
return $this->fail([500, '工单关闭失败']);
}

View File

@@ -8,8 +8,6 @@ use App\Models\User;
use App\Services\ServerService;
use App\Services\UserService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
class ServerController extends Controller
{
@@ -19,8 +17,7 @@ class ServerController extends Controller
$servers = [];
$userService = new UserService();
if ($userService->isAvailable($user)) {
$serverService = new ServerService();
$servers = $serverService->getAvailableServers($user);
$servers = ServerService::getAvailableServers($user);
}
$eTag = sha1(json_encode(array_column($servers, 'cache_key')));
if (strpos($request->header('If-None-Match'), $eTag) !== false ) {

View File

@@ -118,7 +118,7 @@ class TicketController extends Controller
if (!$ticket) {
return $this->fail([400, __('Ticket does not exist')]);
}
$ticket->status = 1;
$ticket->status = Ticket::STATUS_CLOSED;
if (!$ticket->save()) {
return $this->fail([500, __('Close failed')]);
}