SubscribeController.php 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. namespace App\Http\Controllers\User;
  3. use App\Http\Controllers\Controller;
  4. use App\Models\UserSubscribe;
  5. use App\Models\UserSubscribeLog;
  6. use App\Services\ProxyService;
  7. use App\Utils\IP;
  8. use Illuminate\Http\RedirectResponse;
  9. use Illuminate\Http\Request;
  10. use Redirect;
  11. class SubscribeController extends Controller
  12. {
  13. private static ?int $subType;
  14. private ProxyService $proxyServer;
  15. public function getSubscribeByCode(Request $request, string $code): RedirectResponse|string
  16. { // 通过订阅码获取订阅信息
  17. preg_match('/[0-9A-Za-z]+/', $code, $matches, PREG_UNMATCHED_AS_NULL);
  18. if (empty($matches) || empty($code)) {
  19. return Redirect::route('login');
  20. }
  21. $code = $matches[0];
  22. self::$subType = is_numeric($request->input('type')) ? $request->input('type') : null;
  23. // 检查订阅码是否有效
  24. $subscribe = UserSubscribe::whereCode($code)->first();
  25. $this->proxyServer = new ProxyService;
  26. if (! $subscribe) {
  27. $this->failed(trans('errors.subscribe.unknown'));
  28. }
  29. if ($subscribe->status !== 1) {
  30. $this->failed(trans('errors.subscribe.sub_banned'));
  31. }
  32. $user = $subscribe->user;
  33. if (! $user) { // 检查用户是否有效
  34. $this->failed(trans('errors.subscribe.user'));
  35. }
  36. if ($user->status === -1) {
  37. $this->failed(trans('errors.subscribe.user_disabled'));
  38. }
  39. if ($user->enable !== 1) {
  40. if ($user->ban_time) {
  41. $this->failed(trans('errors.subscribe.banned_until', ['time' => $user->ban_time]));
  42. }
  43. $unusedTraffic = $user->transfer_enable - $user->used_traffic;
  44. if ($unusedTraffic <= 0) {
  45. $this->failed(trans('errors.subscribe.out'));
  46. }
  47. if ($user->expiration_date < date('Y-m-d')) {
  48. $this->failed(trans('errors.subscribe.expired'));
  49. }
  50. $this->failed(trans('errors.subscribe.question'));
  51. }
  52. $this->proxyServer->setUser($user);
  53. $subscribe->increment('times'); // 更新访问次数
  54. $this->subscribeLog($subscribe->id, IP::getClientIp(), json_encode(['Host' => $request->getHost(), 'User-Agent' => $request->userAgent()])); // 记录每次请求
  55. return $this->proxyServer->getProxyText(strtolower($request->input('target') ?? ($request->userAgent() ?? '')), self::$subType);
  56. }
  57. private function failed(string $text): void
  58. { // 抛出错误的节点信息,用于兼容防止客户端订阅失败
  59. $this->proxyServer->failedProxyReturn($text, self::$subType ?? 1);
  60. }
  61. private function subscribeLog(int $subscribeId, ?string $ip, string $headers): void
  62. { // 写入订阅访问日志
  63. $log = new UserSubscribeLog;
  64. $log->user_subscribe_id = $subscribeId;
  65. $log->request_ip = $ip;
  66. $log->request_time = now();
  67. $log->request_header = $headers;
  68. $log->save();
  69. }
  70. }