V3Controller.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. <?php
  2. namespace App\Http\Controllers\Api\Client;
  3. use App\Http\Controllers\ClientController;
  4. use App\Http\Controllers\Controller;
  5. use App\Models\AppUpdate;
  6. use App\Models\Node;
  7. use App\Models\User;
  8. use App\Models\UserSubscribe;
  9. use Arr;
  10. use Auth;
  11. use Helpers;
  12. use Illuminate\Http\Request;
  13. use Session;
  14. use Illuminate\Support\Facades\Redis;
  15. use App\Models\Sms;
  16. use Validator;
  17. use Hash;
  18. use App\Models\NodeOnlineLog;
  19. use DB;
  20. class V3Controller extends Controller
  21. {
  22. public function __construct()
  23. {
  24. $this->middleware('auth:api')->except('login','refreshByUser', 'register', 'shop', 'getConfig','version','buy','ClashConfig','getsysconfig');
  25. auth()->shouldUse('api');
  26. }
  27. //生成配置
  28. public function ClashConfig(Request $request){
  29. $code = $request->input('code');
  30. // 检查订阅码是否有效
  31. $subscribe = UserSubscribe::whereCode($code)->first();
  32. if (! $subscribe) {
  33. return response()->json(['ret' => 0, 'msg' => trans('error.subscribe.unknown')], 200);
  34. }
  35. if ($subscribe->status !== 1) {
  36. return response()->json(['ret' => 0, 'msg' => trans('error.subscribe.sub_baned')], 200);
  37. }
  38. // 检查用户是否有效
  39. $user = $subscribe->user;
  40. if (!$user) {
  41. return response()->json(['ret' => 0, 'msg' => trans('error.subscribe.user')], 200);
  42. }
  43. if ($user->status === -1) {
  44. return response()->json(['ret' => 0, 'msg' => trans('error.subscribe.user_disable')], 200);
  45. }
  46. // 获取这个账号可用节点
  47. $query = $user->nodes()->whereIsSubscribe(1);
  48. // if ($this->subType === 1) {
  49. // $query = $query->whereIn('type', [1, 4]);
  50. // } elseif ($this->subType) {
  51. // $query = $query->whereType($this->subType);
  52. // }
  53. $nodeList = $query->orderByDesc('sort')->orderBy('id')->get();
  54. if (empty($nodeList)) {
  55. return $this->failed(trans('error.subscribe.none'));
  56. }
  57. $servers = [];
  58. foreach ($nodeList as $node) {
  59. $servers[] = $node->config($user);
  60. }
  61. $servers = Arr::shuffle($servers);
  62. return (new ClientController)->config("clash", $user, $servers);
  63. }
  64. //登陆
  65. public function login(Request $request)
  66. {
  67. $validator = Validator::make($request->all(), [
  68. 'email' => 'required|email',
  69. 'password' => 'required|string|min:6',
  70. ]);
  71. if ($validator->fails()) {
  72. return response()->json(['ret' => 0, 'msg' => $validator->errors()->all()], 200);
  73. }
  74. if ($token = auth()->attempt($validator->validated())) {
  75. return $this->createNewToken($request,$token);
  76. }
  77. return response()->json(['ret' => 0, 'msg' => "账号或密码错误"], 200);
  78. }
  79. protected function createNewToken($request,$token)
  80. {
  81. $user = auth()->user();
  82. //判断到期
  83. $expireTime = $user["expired_at"];
  84. // if ($expireTime < date('Y-m-d H:i:s')){
  85. // return response()->json(['ret' => 445, 'msg' => "用户到期,请即使续费"], 200);
  86. // }
  87. // $usedTraffic = $user->usedTraffic();
  88. // if ($usedTraffic >= $user["transfer_enable"]){
  89. // return response()->json(['ret' => 446, 'msg' => "流量已经用完,联系客服免费重置流量"], 200);
  90. // }
  91. $userinfo = $user->profile();
  92. if (empty($userinfo)){
  93. return response()->json(['ret' => 0, 'msg' => "错误"]);
  94. }
  95. $data = [
  96. 'access_token' => $token,
  97. 'user' => $userinfo,
  98. 'tutorial' => 'https://ruanjian.xiazi.buzz/',
  99. 'swoftdownload' => 'https://app.xiazai1.xyz/',
  100. 'affurl' => 'https://user.viptwo.xyz/logintoreferral?email='.$request->input('email') . '&password='.$request->input('password'),
  101. 'user_login_url' => 'https://user.viptwo.xyz/logina?email='.$request->input('email') . '&password='.$request->input('password'),
  102. 'user_buy' => 'https://user.viptwo.xyz/logina?email='.$request->input('email') . '&password='.$request->input('password'),
  103. 'user_ticket' => 'https://user.viptwo.xyz/logintoticket?email='.$request->input('email') . '&password='.$request->input('password'),
  104. 'clash_config' => route('SProxy_config', ['code'=>$userinfo['code']]),
  105. ];
  106. return response()->json(['ret' => 1, 'msg' => "请求成功",'data'=>$data], 200);
  107. }
  108. //正在获取系统配置
  109. public function getsysconfig(Request $request){
  110. $url = "rj.viptwo.top";
  111. $tag = $request->input('email');
  112. if (!isset($tag)){
  113. $data = [
  114. 'affurl' => 'https://user.vipthree.xyz/logintoreferral', //推广
  115. 'user_login_url' => 'https://'.$url.'/logina', //购买 和登陆
  116. 'user_login_url_ke' => 'https://'.$url.'/logina', //购买和登陆
  117. 'user_buy' => 'https://'.$url.'/logina', //
  118. 'user_ticket' => 'https://'.$url.'/logintoticket',
  119. 'user_reg' => 'https://'.$url.'/register',
  120. 'user_reset' => 'https://'.$url.'/reset',
  121. 'user_tutorial' => 'https://app.xiazai1.xyz/', //在线客服
  122. 'user_rofile' => 'https://'.$url.'/Loginprofile',
  123. 'user_download' => 'https://app.xiazai1.xyz/',
  124. 'tag' => 0,
  125. ];
  126. return response()->json(['ret' => 1, 'msg' => "请求成功",'data'=>$data], 200);
  127. }
  128. else {
  129. $data = [
  130. 'affurl' => 'https://user.vipthree.xyz/logintoreferral?email='.$request->input('email') . '&password='.$request->input('password'),
  131. 'affurl_ke' => 'https://user.vipthree.xyz/logintoreferral',
  132. 'user_login_url' => 'https://'.$url.'/logina?email='.$request->input('email') . '&password='.$request->input('password'),
  133. 'user_login_url_ke' => 'https://'.$url.'/logina',
  134. 'user_buy' => 'https://'.$url.'/logina?email='.$request->input('email') . '&password='.$request->input('password'),
  135. 'user_ticket' => 'https://'.$url.'/logintoticket?email='.$request->input('email') . '&password='.$request->input('password'),
  136. 'user_ticket_ke' => 'https://'.$url.'/logintoticket',
  137. 'user_reg' => 'https://'.$url.'/register',
  138. 'user_reset' => 'https://'.$url.'/reset',
  139. 'user_tutorial' => 'https://app.xiazai1.xyz/',
  140. 'user_rofile' => 'https://'.$url.'/Loginprofile',
  141. 'user_download' => 'https://app.xiazai1.xyz/',
  142. 'tag' => 1,
  143. ];
  144. return response()->json(['ret' => 1, 'msg' => "请求成功",'data'=>$data], 200);
  145. }
  146. }
  147. //刷新token
  148. public function refresh()
  149. {
  150. $user = auth()->user();
  151. $userinfo = $user->profile();
  152. if (empty($userinfo)){
  153. return response()->json(['ret' => 0, 'msg' => "错误"]);
  154. }
  155. $data = [
  156. 'access_token' => auth()->refresh(),
  157. 'user' => $userinfo,
  158. 'affurl' => route('register', ['aff' => Auth::id()]),
  159. 'tutorial' => 'https://user.viptwo.xyz/',
  160. 'swoftdownload' => 'https://app.xiazai1.xyz/',
  161. 'clash_config' => route('SProxy_config', ['code'=>$userinfo['code']]),
  162. ];
  163. return response()->json(['ret' => 1, 'msg' => "请求成功",'data'=>$data], 200);
  164. }
  165. public function refreshByUser(Request $request)
  166. {
  167. $email = $request->input("email");
  168. $password = $request->input("password");
  169. $userinfo = User::where('email','=',$email)->first();
  170. if (empty($userinfo)){
  171. return response()->json(['ret' => 0, 'msg' => "错误"]);
  172. }
  173. $users = [
  174. 'email' => $email,
  175. 'password' =>$password
  176. ];
  177. $token = auth()->attempt($users);
  178. $data = [
  179. 'access_token' => $token,
  180. 'user' => $userinfo,
  181. 'affurl' => route('register', ['aff' => $userinfo["id"]]),
  182. 'tutorial' => 'https://user.viptwo.xyz/',
  183. 'swoftdownload' => 'https://app.xiazai1.xyz/',
  184. 'clash_config' => route('SProxy_config', ['code'=>$userinfo['code']]),
  185. ];
  186. return response()->json(['ret' => 1, 'msg' => "请求成功",'data'=>$data], 200);
  187. }
  188. public function version(Request $request){
  189. $tag = $request->input("tag");
  190. $appversion = $request->input("appverion");
  191. $version = AppUpdate::where('appname','=',$tag)->first();
  192. if (empty($version)){
  193. return response()->json(['ret' => 0, 'msg' => "获取版本失败"]);
  194. }
  195. if(version_compare($version["appversion"],$appversion,">")){
  196. $version["versionupdate"] = 1;
  197. return response()->json(['ret' => 1, 'data' => $version], 200);
  198. }
  199. return response()->json(['ret' => 0, 'msg' => "没有新版本"]);
  200. }
  201. //用户验证
  202. public function authUser(Request $request){
  203. $user = auth()->user();
  204. $userinfo = $user->profile();
  205. $is_debug = $request->input('debug');
  206. $query = $user->nodes()->with(['labels', 'level_table','onlineLogs']);
  207. $nodeList = $query->orderByDesc('sort')->orderBy('id')->get();
  208. if ($is_debug == 1){
  209. //return $nodeList[0]["status"] == 1;
  210. $firstnode = [];
  211. foreach ($nodeList as $node) {
  212. // 在线人数
  213. $online_log = $node->onlineLogs()->where('log_time', '>=', strtotime('-1 minutes'))->latest('log_time')->first();
  214. $node->online_users = $online_log->online_user ?? 0;
  215. if (strpos($node->country_code,'hk') !== false && $node->status == 1){
  216. $firstnode[] = $node;
  217. }
  218. }
  219. if (empty($firstnode)) {
  220. // 查找其他国家的第一个
  221. foreach ($nodeList as $node) {
  222. // 在线人数
  223. $online_log = $node->onlineLogs()->where('log_time', '>=', strtotime('-1 minutes'))->latest('log_time')->first();
  224. $node->online_users = $online_log->online_user ?? 0;
  225. if ( $node->status == 1){
  226. $firstnode[] = $node;
  227. }
  228. }
  229. }
  230. //找到人数最小的
  231. $min["key"] = "";
  232. $min["value"] = 0;
  233. $keys = "online_users";
  234. $midormax = $this->phpMaxMin($firstnode,$keys);
  235. $servers = [];
  236. foreach ($firstnode as $key => $v ){
  237. if($key == $midormax["min"]["key"])
  238. {
  239. $servers = $v->config($user);
  240. $servers[$keys] = $firstnode[$key][$keys];
  241. }
  242. }
  243. return $servers;
  244. }
  245. if (empty($userinfo)){
  246. return response()->json(['ret' => 0, 'msg' => "错误"]);
  247. }
  248. //判断到期
  249. $expireTime = $user["expired_at"];
  250. if ($expireTime < date('Y-m-d H:i:s')){
  251. return response()->json(['ret' => 445, 'msg' => "用户到期,请续费"], 200);
  252. }
  253. $usedTraffic = $user->usedTraffic();
  254. if ($usedTraffic >= $userinfo["transfer_enable"]){
  255. return response()->json(['ret' => 446, 'msg' => "流量已经用完,联系客服免费重置流量"], 200);
  256. }
  257. if ($userinfo["enable"] == 0){
  258. return response()->json(['ret' => 446, 'msg' => "账号禁用1个小时内流量超过30G,1个小时后自动解封"], 200);
  259. }
  260. //获取节点
  261. $query = $user->nodes()->with(['labels', 'level_table','onlineLogs']);
  262. $nodeList = $query->orderByDesc('sort')->orderBy('id')->get();
  263. $firstnode = [];
  264. foreach ($nodeList as $node) {
  265. // 在线人数
  266. $online_log = $node->onlineLogs()->where('log_time', '>=', strtotime('-1 minutes'))->latest('log_time')->first();
  267. $node->online_users = $online_log->online_user ?? 0;
  268. if (strpos($node->country_code,'hk') !== false && $node->status == 1){
  269. $firstnode[] = $node;
  270. }
  271. }
  272. if (empty($firstnode)) {
  273. // 查找其他国家的第一个
  274. foreach ($nodeList as $node) {
  275. // 在线人数
  276. $online_log = $node->onlineLogs()->where('log_time', '>=', strtotime('-1 minutes'))->latest('log_time')->first();
  277. $node->online_users = $online_log->online_user ?? 0;
  278. if ( $node->status == 1){
  279. $firstnode[] = $node;
  280. }
  281. }
  282. }
  283. //找到人数最小的
  284. $min["key"] = "";
  285. $min["value"] = 0;
  286. $keys = "online_users";
  287. $midormax = $this->phpMaxMin($firstnode,$keys);
  288. $servers = [];
  289. foreach ($firstnode as $key => $v ){
  290. if($key == $midormax["min"]["key"])
  291. {
  292. $servers = $v->config($user);
  293. $servers[$keys] = $firstnode[$key][$keys];
  294. }
  295. }
  296. return response()->json(['ret' => 1, 'data' => $servers], 200);
  297. }
  298. //获取节点
  299. public function nodeList(int $id = null)
  300. {
  301. $user = auth()->user();
  302. $query = $user->nodes()->with(['labels', 'level_table','onlineLogs']);
  303. $nodeList = $query->where("type",'!=',2)->orderByDesc('sort')->orderBy('id')->get();
  304. //var_dump($nodes); die();
  305. if (isset($id)) {
  306. $nodes = $user->nodes()->get();
  307. $node = $nodes->find($id);
  308. if (empty($node)) {
  309. return response()->json([], 204);
  310. }
  311. return response()->json($node->config($user));
  312. }
  313. $temp = array();
  314. $servers = [];
  315. $firstnode = [];
  316. foreach ($nodeList as $node) {
  317. // 在线人数
  318. $online_log = $node->onlineLogs()->where('log_time', '>=', strtotime('-5 minutes'))->latest('log_time')->first();
  319. $node->online_users = $online_log->online_user ?? 0;
  320. $firstnode[] = $node;
  321. }
  322. foreach ($firstnode as $key => $val){
  323. $servers[] = $val->config($user);
  324. $servers[$key]["ip"] = $firstnode[$key]["ip"];
  325. $servers[$key]["online_users"] = $firstnode[$key]["online_users"];
  326. $servers[$key]["country_code"] = $firstnode[$key]["country_code"];
  327. }
  328. return response()->json(['ret' => 1, 'data' => $servers]);
  329. }
  330. public function phpMaxMin($arr = [],$keys = ''){
  331. $max['key'] = '';
  332. $max['value'] = '';
  333. $min['key'] = '';
  334. $min['value'] = '';
  335. foreach ($arr as $key => $val){
  336. if($max['key'] === ''){
  337. $max['key'] = $key;
  338. $max['value'] = $val[$keys];
  339. }
  340. if((int)$max['value'] < $val[$keys]){
  341. $max['key'] = $key;
  342. $max['value'] = $val[$keys];
  343. }
  344. if($min['key'] === ''){
  345. $min['key'] = $key;
  346. $min['value'] = $val[$keys];
  347. }
  348. if((int)$min['value'] > $val[$keys]){
  349. $min['key'] = $key;
  350. $min['value'] = $val[$keys];
  351. }
  352. }
  353. $array['max'] = $max;
  354. $array['min'] = $min;
  355. return $array;
  356. }
  357. }