BaseController.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. namespace App\Http\Controllers\Api\WebApi;
  3. use App\Models\Node;
  4. use App\Models\User;
  5. use Illuminate\Http\JsonResponse;
  6. use Illuminate\Http\Request;
  7. use Log;
  8. use Response;
  9. use Validator;
  10. class BaseController
  11. {
  12. // 上报节点心跳信息
  13. public function setNodeStatus(Request $request, Node $node): JsonResponse
  14. {
  15. //Log::info('上报节点心跳信息-'.var_export($request->all(), true));
  16. $validator = Validator::make($request->all(), ['cpu' => 'required', 'mem' => 'required', 'disk' => 'required', 'uptime' => 'required|numeric']);
  17. if ($validator->fails()) {
  18. return $this->returnData('上报节点心跳信息失败,请检查字段');
  19. }
  20. $data = array_map('intval', $validator->validated());
  21. //
  22. if ($node->heartbeats()->create([
  23. 'uptime' => $data['uptime'],//
  24. 'load' => implode(' ', [$data['cpu'] / 100, $data['mem'] / 100, $data['disk'] / 100]),
  25. 'log_time' => time(),
  26. ])) {
  27. return $this->returnData('上报节点心跳信息成功', 'success', 200);
  28. }
  29. return $this->returnData('生成节点心跳信息失败');
  30. }
  31. // 返回数据
  32. public function returnData(string $message, string $status = 'fail', int $code = 400, array $data = [], array $addition = null): JsonResponse
  33. {
  34. $etag = self::abortIfNotModified($data);
  35. $data = ['status' => $status, 'code' => $code, 'data' => $data, 'message' => $message];
  36. if (isset($addition)) {
  37. $data = array_merge($data, $addition);
  38. }
  39. return Response::json($data)->header('ETAG', $etag)->setStatusCode($code);
  40. }
  41. // 检查数据是否有变动
  42. private static function abortIfNotModified($data): string
  43. {
  44. $req = request();
  45. // Only for "GET" method
  46. if (! $req->isMethod('GET')) {
  47. return '';
  48. }
  49. $etag = sha1(json_encode($data));
  50. if ($etag === $req->header('IF-NONE-MATCH')) {
  51. abort(304);
  52. }
  53. return $etag;
  54. }
  55. // 上报节点在线IP
  56. public function setNodeOnline(Request $request, Node $node): JsonResponse
  57. {
  58. $validator = Validator::make($request->all(), ['*.uid' => 'required|numeric|exists:user,id', '*.ip' => 'required|string']);
  59. if ($validator->fails()) {
  60. return $this->returnData('上报节点在线用户IP信息失败,请检查字段');
  61. }
  62. $onlineCount = 0;
  63. foreach ($validator->validated() as $input) { // 处理节点在线IP数据
  64. $formattedData[] = ['user_id' => $input['uid'], 'ip' => $input['ip'], 'port' => User::find($input['uid'])->port, 'created_at' => time()];
  65. $onlineCount++;
  66. }
  67. if (isset($formattedData) && ! $node->onlineIps()->createMany($formattedData)) { // 生成节点在线IP数据
  68. return $this->returnData('生成节点在线用户IP信息失败');
  69. }
  70. if ($node->onlineLogs()->create(['online_user' => $onlineCount, 'log_time' => time()])) { // 生成节点在线人数数据
  71. return $this->returnData('上报节点在线情况成功', 'success', 200);
  72. }
  73. return $this->returnData('生成节点在线情况失败');
  74. }
  75. // 上报用户流量日志
  76. public function setUserTraffic(Request $request, Node $node): JsonResponse
  77. {
  78. $validator = Validator::make($request->all(), ['*.uid' => 'required|numeric|exists:user,id', '*.upload' => 'required|numeric', '*.download' => 'required|numeric']);
  79. if ($validator->fails()) {
  80. return $this->returnData('上报用户流量日志失败,请检查字段');
  81. }
  82. foreach ($validator->validated() as $input) { // 处理用户流量数据
  83. $rate = $node->traffic_rate;
  84. $u = $input['upload'] * $rate;
  85. $d = $input['download'] * $rate;
  86. $formattedData[] = ['user_id' => $input['uid'], 'u' => $u, 'd' => $d, 'rate' => $rate, 'traffic' => flowAutoShow($u + $d), 'log_time' => time()];
  87. }
  88. if (isset($formattedData) && $logs = $node->userDataFlowLogs()->createMany($formattedData)) { // 生成用户流量数据
  89. foreach ($logs as $log) { // 更新用户流量数据
  90. $user = $log->user;
  91. $user->update(['u' => $user->u + $log->u, 'd' => $user->d + $log->d, 't' => time()]);
  92. }
  93. return $this->returnData('上报用户流量日志成功', 'success', 200);
  94. }
  95. return $this->returnData('生成用户流量日志失败');
  96. }
  97. // 获取节点的审计规则
  98. public function getNodeRule(Node $node): JsonResponse
  99. {
  100. // 节点未设置任何审计规则
  101. if ($ruleGroup = $node->ruleGroup) {
  102. foreach ($ruleGroup->rules as $rule) {
  103. $data[] = [
  104. 'id' => $rule->id,
  105. 'type' => $rule->type_api_label,
  106. 'pattern' => $rule->pattern,
  107. ];
  108. }
  109. return $this->returnData('获取节点审计规则成功', 'success', 200, ['mode' => $ruleGroup->type ? 'reject' : 'allow', 'rules' => $data ?? []]);
  110. }
  111. // 放行
  112. return $this->returnData('获取节点审计规则成功', 'success', 200, ['mode' => 'all', 'rules' => $data ?? []]);
  113. }
  114. // 上报用户触发审计规则记录
  115. public function addRuleLog(Request $request, Node $node): JsonResponse
  116. {
  117. $validator = Validator::make($request->all(), ['uid' => 'required|numeric|exists:user,id', 'rule_id' => 'required|numeric|exists:rule,id', 'reason' => 'required']);
  118. if ($validator->fails()) {
  119. return $this->returnData('上报用户触发审计规则日志失败,请检查字段');
  120. }
  121. $data = $validator->validated();
  122. if ($node->ruleLogs()->create(['user_id' => $data['uid'], 'rule_id' => $data['rule_id'], 'reason' => $data['reason']])) {
  123. return $this->returnData('上报用户触发审计规则日志成功', 'success', 200);
  124. }
  125. return $this->returnData('上报用户触发审计规则日志失败');
  126. }
  127. }