Controller.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Components\Client\Text;
  4. use App\Components\Client\URLSchemes;
  5. use App\Models\NodeDailyDataFlow;
  6. use App\Models\NodeHourlyDataFlow;
  7. use App\Models\UserDailyDataFlow;
  8. use App\Models\UserDataFlowLog;
  9. use App\Models\UserHourlyDataFlow;
  10. use DB;
  11. use Exception;
  12. use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
  13. use Illuminate\Foundation\Bus\DispatchesJobs;
  14. use Illuminate\Foundation\Validation\ValidatesRequests;
  15. use Illuminate\Routing\Controller as BaseController;
  16. use RuntimeException;
  17. use Str;
  18. class Controller extends BaseController
  19. {
  20. use AuthorizesRequests;
  21. use DispatchesJobs;
  22. use ValidatesRequests;
  23. // 类似Linux中的tail命令
  24. public function tail($file, $n, $base = 5)
  25. {
  26. $fileLines = $this->countLine($file);
  27. if ($fileLines < 15000) {
  28. return false;
  29. }
  30. $fp = fopen($file, 'rb+');
  31. assert($n > 0);
  32. $pos = $n + 1;
  33. $lines = [];
  34. while (count($lines) <= $n) {
  35. try {
  36. fseek($fp, -$pos, SEEK_END);
  37. } catch (Exception $e) {
  38. break;
  39. }
  40. $pos *= $base;
  41. while (! feof($fp)) {
  42. array_unshift($lines, fgets($fp));
  43. }
  44. }
  45. return array_slice($lines, 0, $n);
  46. }
  47. /**
  48. * 计算文件行数.
  49. *
  50. * @param $file
  51. *
  52. * @return int
  53. */
  54. public function countLine($file): int
  55. {
  56. $fp = fopen($file, 'rb');
  57. $i = 0;
  58. while (! feof($fp)) {
  59. //每次读取2M
  60. if ($data = fread($fp, 1024 * 1024 * 2)) {
  61. //计算读取到的行数
  62. $num = substr_count($data, "\n");
  63. $i += $num;
  64. }
  65. }
  66. fclose($fp);
  67. return $i;
  68. }
  69. // 将Base64图片转换为本地图片并保存
  70. public function base64ImageSaver($base64_image_content): ?string
  71. {
  72. // 匹配出图片的格式
  73. if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) {
  74. $type = $result[2];
  75. $directory = date('Ymd');
  76. $path = '/assets/images/qrcode/'.$directory.'/';
  77. // 检查是否有该文件夹,如果没有就创建,并给予最高权限
  78. if (! file_exists(public_path($path))
  79. && ! mkdir($concurrentDirectory = public_path($path), 0755, true)
  80. && ! is_dir($concurrentDirectory)) {
  81. throw new RuntimeException(sprintf('Directory "%s" was not created', $concurrentDirectory));
  82. }
  83. $fileName = Str::random(18).".{$type}";
  84. if (file_put_contents(public_path($path.$fileName), base64_decode(str_replace($result[1], '', $base64_image_content)))) {
  85. chmod(public_path($path.$fileName), 0744);
  86. return $path.$fileName;
  87. }
  88. }
  89. return '';
  90. }
  91. // 节点信息
  92. public function getUserNodeInfo(array $server, bool $is_url): ?string
  93. {
  94. switch ($server['type']) {
  95. case'shadowsocks':
  96. $data = $is_url ? URLSchemes::buildShadowsocks($server) : Text::buildShadowsocks($server);
  97. break;
  98. case 'shadowsocksr':
  99. $data = $is_url ? URLSchemes::buildShadowsocksr($server) : Text::buildShadowsocksr($server);
  100. break;
  101. case 'v2ray':
  102. $data = $is_url ? URLSchemes::buildVmess($server) : Text::buildVmess($server);
  103. break;
  104. case 'trojan':
  105. $data = $is_url ? URLSchemes::buildTrojan($server) : Text::buildTrojan($server);
  106. break;
  107. default:
  108. }
  109. return $data ?? null;
  110. }
  111. // 流量使用图表
  112. public function dataFlowChart($id, $is_node = false): array
  113. {
  114. if ($is_node) {
  115. $currentFlow = UserDataFlowLog::whereNodeId($id);
  116. $hourlyFlow = NodeHourlyDataFlow::whereNodeId($id);
  117. $dailyFlow = NodeDailyDataFlow::whereNodeId($id);
  118. } else {
  119. $currentFlow = UserDataFlowLog::whereUserId($id);
  120. $hourlyFlow = UserHourlyDataFlow::userHourly($id);
  121. $dailyFlow = UserDailyDataFlow::userDaily($id);
  122. }
  123. $currentFlow = $currentFlow->where('log_time', '>=', strtotime(date('Y-m-d H:00')))->sum(DB::raw('u + d'));
  124. $hourlyFlow = $hourlyFlow->whereDate('created_at', date('Y-m-d'))->pluck('total', 'created_at')->toArray();
  125. $dailyFlow = $dailyFlow->whereMonth('created_at', date('n'))->pluck('total', 'created_at')->toArray();
  126. // 节点一天内的流量
  127. $hourlyData = array_fill(0, date('G') + 1, 0);
  128. foreach ($hourlyFlow as $date => $dataFlow) {
  129. $hourlyData[date('G', strtotime($date))] = round($dataFlow / GB, 3);
  130. }
  131. $hourlyData[date('G') + 1] = round($currentFlow / GB, 3);
  132. // 节点一个月内的流量
  133. $dailyData = array_fill(0, date('j'), 0);
  134. foreach ($dailyFlow as $date => $dataFlow) {
  135. $dailyData[date('j', strtotime($date)) - 1] = round($dataFlow / GB, 3);
  136. }
  137. $dailyData[date('j', strtotime(now())) - 1] = round((array_sum($hourlyFlow) + $currentFlow) / GB, 3);
  138. return [
  139. 'trafficDaily' => json_encode($dailyData),
  140. 'trafficHourly' => json_encode($hourlyData),
  141. 'monthDays' => json_encode(range(1, date('j'), 1)), // 本月天数
  142. 'dayHours' => json_encode(range(0, date('G') + 1, 1)), // 本日小时
  143. ];
  144. }
  145. }