SubscribeController.php 3.0 KB

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