UserController.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controllers\WebAPI;
  4. use App\Controllers\BaseController;
  5. use App\Models\DetectLog;
  6. use App\Models\Ip;
  7. use App\Models\Node;
  8. use App\Models\User;
  9. use App\Services\DB;
  10. use App\Utils\ResponseHelper;
  11. use App\Utils\Tools;
  12. use Illuminate\Database\Eloquent\Builder;
  13. use Psr\Http\Message\ResponseInterface;
  14. use Slim\Http\ServerRequest;
  15. use Slim\Http\Response;
  16. final class UserController extends BaseController
  17. {
  18. /**
  19. * GET /mod_mu/users
  20. *
  21. * @param ServerRequest $request
  22. * @param Response $response
  23. * @param array $args
  24. *
  25. * @return ResponseInterface
  26. */
  27. public function index(Request $request, Response $response, array $args): ResponseInterface
  28. {
  29. $node_id = $request->getQueryParam('node_id');
  30. $node = Node::find($node_id);
  31. if ($node === null) {
  32. return $response->withJson([
  33. 'ret' => 0,
  34. ]);
  35. }
  36. $node->update(['node_heartbeat' => \time()]);
  37. if (($node->node_bandwidth_limit !== 0) && $node->node_bandwidth_limit < $node->node_bandwidth) {
  38. return $response->withJson([
  39. 'ret' => 1,
  40. 'data' => [],
  41. ]);
  42. }
  43. $users_raw = User::where('is_banned', 0)
  44. ->where('expire_in', '>', date('Y-m-d H:i:s'))
  45. ->where(static function (Builder $query) use ($node): void {
  46. $query->whereRaw(
  47. 'class >= ? AND IF(? = 0, 1, node_group = ?)',
  48. [$node->node_class, $node->node_group, $node->node_group]
  49. )->orWhere('is_admin', 1);
  50. })
  51. ->get();
  52. if (\in_array($node->sort, [11, 14])) {
  53. $key_list = [
  54. 'id', 'node_connector', 'node_speedlimit', 'node_iplimit', 'uuid', 'alive_ip',
  55. ];
  56. } else {
  57. $key_list = [
  58. 'id', 'node_connector', 'node_speedlimit', 'node_iplimit', 'method', 'port', 'passwd', 'alive_ip',
  59. ];
  60. }
  61. $alive_ip = (new Ip())->getUserAliveIpCount();
  62. $users = [];
  63. foreach ($users_raw as $user_raw) {
  64. if (isset($alive_ip[strval($user_raw->id)]) && $user_raw->node_connector !== 0) {
  65. $user_raw->alive_ip = $alive_ip[strval($user_raw->id)];
  66. }
  67. if ($user_raw->transfer_enable <= $user_raw->u + $user_raw->d) {
  68. if ($_ENV['keep_connect'] === true) {
  69. // 流量耗尽用户限速至 1Mbps
  70. $user_raw->node_speedlimit = 1;
  71. } else {
  72. continue;
  73. }
  74. }
  75. $user_raw = Tools::keyFilter($user_raw, $key_list);
  76. $users[] = $user_raw;
  77. }
  78. return ResponseHelper::etagJson($request, $response, [
  79. 'ret' => 1,
  80. 'data' => $users,
  81. ]);
  82. }
  83. /**
  84. * POST /mod_mu/users/traffic
  85. *
  86. * @param ServerRequest $request
  87. * @param Response $response
  88. * @param array $args
  89. *
  90. * @return ResponseInterface
  91. */
  92. public function addTraffic(Request $request, Response $response, array $args): ResponseInterface
  93. {
  94. $data = \json_decode($request->getBody()->__toString());
  95. if (!$data || !\is_array($data?->data)) {
  96. return $response->withJson([
  97. 'ret' => 0,
  98. ]);
  99. }
  100. $data = $data->data;
  101. $node_id = $request->getQueryParam('node_id');
  102. $node = Node::find($node_id);
  103. if ($node === null) {
  104. return $response->withJson([
  105. 'ret' => 0,
  106. ]);
  107. }
  108. $pdo = DB::getPdo();
  109. $stat = $pdo->prepare('UPDATE user SET t = UNIX_TIMESTAMP(), u = u + ?, d = d + ?, transfer_total = transfer_total + ? WHERE id = ?');
  110. $rate = (float) $node->traffic_rate;
  111. $sum = 0;
  112. foreach ($data as $log) {
  113. $u = $log?->u;
  114. $d = $log?->d;
  115. $user_id = $log?->user_id;
  116. if ($user_id) {
  117. $stat->execute([(int) ($u * $rate), (int) ($d * $rate), (int) ($u + $d), $user_id]);
  118. }
  119. $sum += $u + $d;
  120. }
  121. $node->increment('node_bandwidth', $sum);
  122. $node->online_user = count($data);
  123. $node->save();
  124. return $response->withJson([
  125. 'ret' => 1,
  126. 'data' => 'ok',
  127. ]);
  128. }
  129. /**
  130. * POST /mod_mu/users/aliveip
  131. *
  132. * @param ServerRequest $request
  133. * @param Response $response
  134. * @param array $args
  135. *
  136. * @return ResponseInterface
  137. */
  138. public function addAliveIp(Request $request, Response $response, array $args): ResponseInterface
  139. {
  140. $data = \json_decode($request->getBody()->__toString());
  141. if (!$data || !\is_array($data?->data)) {
  142. return $response->withJson([
  143. 'ret' => 0,
  144. ]);
  145. }
  146. $data = $data->data;
  147. $node_id = $request->getQueryParam('node_id');
  148. if ($node_id === null || !Node::where('id', $node_id)->exists()) {
  149. return $response->withJson([
  150. 'ret' => 0,
  151. ]);
  152. }
  153. foreach ($data as $log) {
  154. $ip = (string) $log?->ip;
  155. $userid = (int) $log?->user_id;
  156. Ip::insert([
  157. 'userid' => $userid,
  158. 'nodeid' => $node_id,
  159. 'ip' => $ip,
  160. 'datetime' => \time(),
  161. ]);
  162. }
  163. return $response->withJson([
  164. 'ret' => 1,
  165. 'data' => 'ok',
  166. ]);
  167. }
  168. /**
  169. * POST /mod_mu/users/detectlog
  170. *
  171. * @param ServerRequest $request
  172. * @param Response $response
  173. * @param array $args
  174. *
  175. * @return ResponseInterface
  176. */
  177. public function addDetectLog(Request $request, Response $response, array $args): ResponseInterface
  178. {
  179. $data = \json_decode($request->getBody()->__toString());
  180. if (!$data || !\is_array($data?->data)) {
  181. return $response->withJson([
  182. 'ret' => 0,
  183. ]);
  184. }
  185. $data = $data->data;
  186. $node_id = $request->getQueryParam('node_id');
  187. if ($node_id === null || !Node::where('id', $node_id)->exists()) {
  188. return $response->withJson([
  189. 'ret' => 0,
  190. ]);
  191. }
  192. foreach ($data as $log) {
  193. $list_id = (int) $log?->list_id;
  194. $user_id = (int) $log?->user_id;
  195. DetectLog::insert([
  196. 'user_id' => $user_id,
  197. 'list_id' => $list_id,
  198. 'node_id' => $node_id,
  199. 'datetime' => \time(),
  200. ]);
  201. }
  202. return $response->withJson([
  203. 'ret' => 1,
  204. 'data' => 'ok',
  205. ]);
  206. }
  207. }