first commit

This commit is contained in:
CN-JS-HuiBai
2026-04-07 16:54:24 +08:00
commit 2c6a38c80d
399 changed files with 42205 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Http\Controllers\V1\Guest;
use App\Http\Controllers\Controller;
use App\Services\Plugin\HookManager;
use App\Utils\Dict;
use App\Utils\Helper;
use Illuminate\Support\Facades\Http;
class CommController extends Controller
{
public function config()
{
$data = [
'tos_url' => admin_setting('tos_url'),
'is_email_verify' => (int) admin_setting('email_verify', 0) ? 1 : 0,
'is_invite_force' => (int) admin_setting('invite_force', 0) ? 1 : 0,
'email_whitelist_suffix' => (int) admin_setting('email_whitelist_enable', 0)
? Helper::getEmailSuffix()
: 0,
'is_captcha' => (int) admin_setting('captcha_enable', 0) ? 1 : 0,
'captcha_type' => admin_setting('captcha_type', 'recaptcha'),
'recaptcha_site_key' => admin_setting('recaptcha_site_key'),
'recaptcha_v3_site_key' => admin_setting('recaptcha_v3_site_key'),
'recaptcha_v3_score_threshold' => admin_setting('recaptcha_v3_score_threshold', 0.5),
'turnstile_site_key' => admin_setting('turnstile_site_key'),
'app_description' => admin_setting('app_description'),
'app_url' => admin_setting('app_url'),
'logo' => admin_setting('logo'),
// 保持向后兼容
'is_recaptcha' => (int) admin_setting('captcha_enable', 0) ? 1 : 0,
];
$data = HookManager::filter('guest_comm_config', $data);
return $this->success($data);
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Http\Controllers\V1\Guest;
use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Services\OrderService;
use App\Services\PaymentService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Services\Plugin\HookManager;
class PaymentController extends Controller
{
public function notify($method, $uuid, Request $request)
{
HookManager::call('payment.notify.before', [$method, $uuid, $request]);
try {
$paymentService = new PaymentService($method, null, $uuid);
$verify = $paymentService->notify($request->input());
if (!$verify) {
HookManager::call('payment.notify.failed', [$method, $uuid, $request]);
return $this->fail([422, 'verify error']);
}
HookManager::call('payment.notify.verified', $verify);
if (!$this->handle($verify['trade_no'], $verify['callback_no'])) {
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']);
}
}
private function handle($tradeNo, $callbackNo)
{
$order = Order::where('trade_no', $tradeNo)->first();
if (!$order) {
return $this->fail([400202, 'order is not found']);
}
if ($order->status !== Order::STATUS_PENDING)
return true;
$orderService = new OrderService($order);
if (!$orderService->paid($callbackNo)) {
return false;
}
HookManager::call('payment.notify.success', $order);
return true;
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers\V1\Guest;
use App\Http\Controllers\Controller;
use App\Http\Resources\PlanResource;
use App\Models\Plan;
use App\Services\PlanService;
use Auth;
use Illuminate\Http\Request;
class PlanController extends Controller
{
protected $planService;
public function __construct(PlanService $planService)
{
$this->planService = $planService;
}
public function fetch(Request $request)
{
$plan = $this->planService->getAvailablePlans();
return $this->success(PlanResource::collection($plan));
}
}

View File

@@ -0,0 +1,126 @@
<?php
namespace App\Http\Controllers\V1\Guest;
use App\Exceptions\ApiException;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Services\Plugin\HookManager;
use App\Services\TelegramService;
use App\Services\UserService;
use Illuminate\Http\Request;
class TelegramController extends Controller
{
protected ?object $msg = null;
protected TelegramService $telegramService;
protected UserService $userService;
public function __construct(TelegramService $telegramService, UserService $userService)
{
$this->telegramService = $telegramService;
$this->userService = $userService;
}
public function webhook(Request $request): void
{
$expectedToken = md5(admin_setting('telegram_bot_token'));
if ($request->input('access_token') !== $expectedToken) {
throw new ApiException('access_token is error', 401);
}
$data = $request->json()->all();
$this->formatMessage($data);
$this->formatChatJoinRequest($data);
$this->handle();
}
private function handle(): void
{
if (!$this->msg)
return;
$msg = $this->msg;
$this->processBotName($msg);
try {
HookManager::call('telegram.message.before', [$msg]);
$handled = HookManager::filter('telegram.message.handle', false, [$msg]);
if (!$handled) {
HookManager::call('telegram.message.unhandled', [$msg]);
}
HookManager::call('telegram.message.after', [$msg]);
} catch (\Exception $e) {
HookManager::call('telegram.message.error', [$msg, $e]);
$this->telegramService->sendMessage($msg->chat_id, $e->getMessage());
}
}
private function processBotName(object $msg): void
{
$commandParts = explode('@', $msg->command);
if (count($commandParts) === 2) {
$botName = $this->getBotName();
if ($commandParts[1] === $botName) {
$msg->command = $commandParts[0];
}
}
}
private function getBotName(): string
{
$response = $this->telegramService->getMe();
return $response->result->username;
}
private function formatMessage(array $data): void
{
if (!isset($data['message']['text']))
return;
$message = $data['message'];
$text = explode(' ', $message['text']);
$this->msg = (object) [
'command' => $text[0],
'args' => array_slice($text, 1),
'chat_id' => $message['chat']['id'],
'message_id' => $message['message_id'],
'message_type' => 'message',
'text' => $message['text'],
'is_private' => $message['chat']['type'] === 'private',
];
if (isset($message['reply_to_message']['text'])) {
$this->msg->message_type = 'reply_message';
$this->msg->reply_text = $message['reply_to_message']['text'];
}
}
private function formatChatJoinRequest(array $data): void
{
$joinRequest = $data['chat_join_request'] ?? null;
if (!$joinRequest)
return;
$chatId = $joinRequest['chat']['id'] ?? null;
$userId = $joinRequest['from']['id'] ?? null;
if (!$chatId || !$userId)
return;
$user = User::where('telegram_id', $userId)->first();
if (!$user) {
$this->telegramService->declineChatJoinRequest($chatId, $userId);
return;
}
if (!$this->userService->isAvailable($user)) {
$this->telegramService->declineChatJoinRequest($chatId, $userId);
return;
}
$this->telegramService->approveChatJoinRequest($chatId, $userId);
}
}