RelayController.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <?php
  2. namespace App\Controllers\Admin;
  3. use App\Models\Relay;
  4. use App\Models\Node;
  5. use App\Models\User;
  6. use App\Utils\Tools;
  7. use App\Services\Auth;
  8. use App\Controllers\AdminController;
  9. use Ozdemir\Datatables\Datatables;
  10. use App\Utils\DatatablesHelper;
  11. class RelayController extends AdminController
  12. {
  13. public function index($request, $response, $args)
  14. {
  15. $table_config['total_column'] = array("op" => "操作", "id" => "ID", "user_id" => "用户ID",
  16. "user_name" => "用户名", "source_node_name" => "起源节点",
  17. "dist_node_name" => "目标节点", "port" => "端口", "priority" => "优先级");
  18. $table_config['default_show_column'] = array();
  19. foreach ($table_config['total_column'] as $column => $value) {
  20. array_push($table_config['default_show_column'], $column);
  21. }
  22. $table_config['ajax_url'] = 'relay/ajax';
  23. return $this->view()->assign('table_config', $table_config)->display('admin/relay/index.tpl');
  24. }
  25. public function create($request, $response, $args)
  26. {
  27. $user = Auth::getUser();
  28. $source_nodes = Node::where('sort', 10)->orderBy('name')->get();
  29. $dist_nodes = Node::where(
  30. function ($query) {
  31. $query->Where('sort', 0)
  32. ->orWhere('sort', 10);
  33. }
  34. )->orderBy('name')->get();
  35. return $this->view()->assign('source_nodes', $source_nodes)->assign('dist_nodes', $dist_nodes)->display('admin/relay/add.tpl');
  36. }
  37. public function add($request, $response, $args)
  38. {
  39. $dist_node_id = $request->getParam('dist_node');
  40. $source_node_id = $request->getParam('source_node');
  41. $port = $request->getParam('port');
  42. $priority = $request->getParam('priority');
  43. $user_id = $request->getParam('user_id');
  44. $source_node = Node::where('id', $source_node_id)->first();
  45. if ($source_node == null) {
  46. $rs['ret'] = 0;
  47. $rs['msg'] = "起源节点错误。";
  48. return $response->getBody()->write(json_encode($rs));
  49. }
  50. $dist_node = Node::where('id', $dist_node_id)->first();
  51. if ($dist_node == null) {
  52. $rs['ret'] = 0;
  53. $rs['msg'] = "目标节点错误。";
  54. return $response->getBody()->write(json_encode($rs));
  55. }
  56. $rule = new Relay();
  57. $rule->user_id = $user_id;
  58. $rule->dist_node_id = $dist_node_id;
  59. $dist_node_ip = Tools::getRelayNodeIp($source_node, $dist_node);
  60. $rule->dist_ip = $dist_node_ip;
  61. $rule->source_node_id = $source_node_id;
  62. $rule->port = $port;
  63. $rule->priority = $priority;
  64. if ($user_id == 0) {
  65. $ruleset = Relay::all();
  66. } else {
  67. $ruleset = Relay::where('user_id', $user_id)->orwhere('user_id', 0)->get();
  68. }
  69. $maybe_rule_id = Tools::has_conflict_rule($rule, $ruleset, 0, $rule->source_node_id);
  70. if ($maybe_rule_id != 0) {
  71. $rs['ret'] = 0;
  72. $rs['msg'] = "您即将添加的规则与规则 ID:".$maybe_rule_id." 冲突!";
  73. if ($maybe_rule_id == -1) {
  74. $rs['msg'] = "您即将添加的规则可能会造成冲突!";
  75. }
  76. return $response->getBody()->write(json_encode($rs));
  77. }
  78. if (!$rule->save()) {
  79. $rs['ret'] = 0;
  80. $rs['msg'] = "添加失败";
  81. return $response->getBody()->write(json_encode($rs));
  82. }
  83. $rs['ret'] = 1;
  84. $rs['msg'] = "添加成功";
  85. return $response->getBody()->write(json_encode($rs));
  86. }
  87. public function edit($request, $response, $args)
  88. {
  89. $id = $args['id'];
  90. $user = Auth::getUser();
  91. $rule = Relay::where('id', $id)->first();
  92. if ($rule == null) {
  93. exit(0);
  94. }
  95. $source_nodes = Node::where('sort', 10)->orderBy('name')->get();
  96. $dist_nodes = Node::where(
  97. function ($query) {
  98. $query->Where('sort', 0)
  99. ->orWhere('sort', 10);
  100. }
  101. )->orderBy('name')->get();
  102. return $this->view()->assign('rule', $rule)->assign('source_nodes', $source_nodes)->assign('dist_nodes', $dist_nodes)->display('admin/relay/edit.tpl');
  103. }
  104. public function update($request, $response, $args)
  105. {
  106. $id = $args['id'];
  107. $rule = Relay::where('id', $id)->first();
  108. if ($rule == null) {
  109. exit(0);
  110. }
  111. $dist_node_id = $request->getParam('dist_node');
  112. $source_node_id = $request->getParam('source_node');
  113. $port = $request->getParam('port');
  114. $user_id = $request->getParam('user_id');
  115. $priority = $request->getParam('priority');
  116. $source_node = Node::where('id', $source_node_id)->first();
  117. if ($source_node == null && $source_node_id != 0) {
  118. $rs['ret'] = 0;
  119. $rs['msg'] = "起源节点 ID 错误。";
  120. return $response->getBody()->write(json_encode($rs));
  121. }
  122. $dist_node = Node::where('id', $dist_node_id)->first();
  123. if ($dist_node == null) {
  124. $rs['ret'] = 0;
  125. $rs['msg'] = "目标节点 ID 错误。";
  126. return $response->getBody()->write(json_encode($rs));
  127. }
  128. $rule->user_id = $user_id;
  129. $rule->dist_node_id = $dist_node_id;
  130. $dist_node_ip = Tools::getRelayNodeIp($source_node, $dist_node);
  131. $rule->dist_ip = $dist_node_ip;
  132. $rule->source_node_id = $source_node_id;
  133. $rule->port = $port;
  134. $rule->priority = $priority;
  135. if ($user_id == 0) {
  136. $ruleset = Relay::all();
  137. } else {
  138. $ruleset = Relay::where('user_id', $user_id)->orwhere('user_id', 0)->get();
  139. }
  140. $maybe_rule_id = Tools::has_conflict_rule($rule, $ruleset, $rule->id, $rule->source_node_id);
  141. if ($maybe_rule_id != 0) {
  142. $rs['ret'] = 0;
  143. $rs['msg'] = "您即将添加的规则与规则 ID:".$maybe_rule_id." 冲突!";
  144. if ($maybe_rule_id == -1) {
  145. $rs['msg'] = "您即将添加的规则可能会造成冲突!";
  146. }
  147. return $response->getBody()->write(json_encode($rs));
  148. }
  149. if (!$rule->save()) {
  150. $rs['ret'] = 0;
  151. $rs['msg'] = "修改失败";
  152. return $response->getBody()->write(json_encode($rs));
  153. }
  154. $rs['ret'] = 1;
  155. $rs['msg'] = "修改成功";
  156. return $response->getBody()->write(json_encode($rs));
  157. }
  158. public function delete($request, $response, $args)
  159. {
  160. $id = $request->getParam('id');
  161. $user = Auth::getUser();
  162. $rule = Relay::where('id', $id)->first();
  163. if ($rule == null) {
  164. exit(0);
  165. }
  166. if (!$rule->delete()) {
  167. $rs['ret'] = 0;
  168. $rs['msg'] = "删除失败";
  169. return $response->getBody()->write(json_encode($rs));
  170. }
  171. $rs['ret'] = 1;
  172. $rs['msg'] = "删除成功";
  173. return $response->getBody()->write(json_encode($rs));
  174. }
  175. public function path_search($request, $response, $args)
  176. {
  177. $uid=$args["id"];
  178. $user = User::find($uid);
  179. if ($user == null) {
  180. $pathset = new \ArrayObject();
  181. return $this->view()->assign('pathset', $pathset)->display('admin/relay/search.tpl');
  182. }
  183. $nodes = Node::where(
  184. function ($query) use ($user) {
  185. $query->Where("node_group", "=", $user->node_group)
  186. ->orWhere("node_group", "=", 0);
  187. }
  188. )->where("sort", "=", 10)->where("node_class", "<=", $user->class)->orderBy('name')->get();
  189. $pathset = new \ArrayObject();
  190. $relay_rules = Relay::where('user_id', $user->id)->orwhere('user_id', 0)->get();
  191. $mu_nodes = Node::where('sort', 9)->where('node_class', '<=', $user->class)->where("type", "1")->where(
  192. function ($query) use ($user) {
  193. $query->where("node_group", "=", $user->node_group)
  194. ->orWhere("node_group", "=", 0);
  195. }
  196. )->get();
  197. foreach ($nodes as $node) {
  198. if ($node->mu_only == 0) {
  199. $relay_rule = Tools::pick_out_relay_rule($node->id, $user->port, $relay_rules);
  200. if ($relay_rule != null) {
  201. $pathset = Tools::insertPathRule($relay_rule, $pathset, $user->port);
  202. }
  203. }
  204. if ($node->custom_rss == 1) {
  205. foreach ($mu_nodes as $mu_node) {
  206. $mu_user = User::where('port', '=', $mu_node->server)->first();
  207. if ($mu_user == null) {
  208. continue;
  209. }
  210. if (!($mu_user->class >= $node->node_class && ($node->node_group == 0 || $node->node_group == $mu_user->node_group))) {
  211. continue;
  212. }
  213. if ($mu_user->is_multi_user != 2) {
  214. $relay_rule = Tools::pick_out_relay_rule($node->id, $mu_user->port, $relay_rules);
  215. if ($relay_rule != null) {
  216. $pathset = Tools::insertPathRule($relay_rule, $pathset, $mu_user->port);
  217. }
  218. }
  219. }
  220. }
  221. }
  222. foreach ($pathset as $path) {
  223. foreach ($pathset as $index => $single_path) {
  224. if ($path != $single_path && $path->port == $single_path->port) {
  225. if ($single_path->end_node->id == $path->begin_node->id) {
  226. $path->begin_node = $single_path->begin_node;
  227. if ($path->begin_node->isNodeAccessable() == false) {
  228. $path->path = '<font color="#FF0000">'.$single_path->begin_node->name.'</font>'." → ".$path->path;
  229. $path->status = "阻断";
  230. } else {
  231. $path->path = $single_path->begin_node->name." → ".$path->path;
  232. $path->status = "通畅";
  233. }
  234. $pathset->offsetUnset($index);
  235. continue;
  236. }
  237. if ($path->end_node->id == $single_path->begin_node->id) {
  238. $path->end_node = $single_path->end_node;
  239. if ($single_path->end_node->isNodeAccessable() == false) {
  240. $path->path = $path->path." → ".'<font color="#FF0000">'.$single_path->end_node->name.'</font>';
  241. $path->status = "阻断";
  242. } else {
  243. $path->path = $path->path." → ".$single_path->end_node->name;
  244. }
  245. $pathset->offsetUnset($index);
  246. continue;
  247. }
  248. }
  249. }
  250. }
  251. return $this->view()->assign('pathset', $pathset)->display('admin/relay/search.tpl');
  252. }
  253. public function ajax_relay($request, $response, $args)
  254. {
  255. $datatables = new Datatables(new DatatablesHelper());
  256. $datatables->query('Select relay.id as op,relay.id,relay.user_id,user.user_name,source_node.name as source_node_name,dist_node.name as dist_node_name,relay.port,relay.priority from relay,user,ss_node as source_node,ss_node as dist_node WHERE (relay.user_id = user.id or relay.user_id = 0) and source_node.id = relay.source_node_id and dist_node.id = relay.dist_node_id group by id');
  257. $datatables->edit('op', function ($data) {
  258. return '<a class="btn btn-brand" href="/admin/relay/'.$data['id'].'/edit">编辑</a>
  259. <a class="btn btn-brand-accent" id="delete" value="'.$data['id'].'" href="javascript:void(0);" onClick="delete_modal_show(\''.$data['id'].'\')">删除</a>';
  260. });
  261. $datatables->edit('user_name', function ($data) {
  262. return ($data['user_id'] == 0 ? '全体用户' : $data['user_name']);
  263. });
  264. $body = $response->getBody();
  265. $body->write($datatables->generate());
  266. }
  267. }