validate([ 'group_id' => 'required', 'route_id' => 'nullable|array', 'name' => 'required', 'parent_id' => 'nullable|integer', 'host' => 'required', 'port' => 'required', 'server_port' => 'required', 'tls' => 'required|in:0,1,2', 'tls_settings' => 'nullable|array', 'flow' => 'nullable|in:xtls-rprx-vision', 'network' => 'required', 'network_settings' => 'nullable|array', 'tags' => 'nullable|array', 'rate' => 'required', 'show' => 'nullable|in:0,1', 'sort' => 'nullable' ]); if (isset($params['tls']) && (int)$params['tls'] === 2) { $keyPair = SodiumCompat::crypto_box_keypair(); $params['tls_settings'] = $params['tls_settings'] ?? []; if (!isset($params['tls_settings']['public_key'])) { $params['tls_settings']['public_key'] = Helper::base64EncodeUrlSafe(SodiumCompat::crypto_box_publickey($keyPair)); } if (!isset($params['tls_settings']['private_key'])) { $params['tls_settings']['private_key'] = Helper::base64EncodeUrlSafe(SodiumCompat::crypto_box_secretkey($keyPair)); } } if ($request->input('id')) { $server = ServerVless::find($request->input('id')); if (!$server) { abort(500, '服务器不存在'); } try { $server->update($params); } catch (\Exception $e) { abort(500, '保存失败'); } return response([ 'data' => true ]); } if (!ServerVless::create($params)) { abort(500, '创建失败'); } return response([ 'data' => true ]); } public function drop(Request $request) { if ($request->input('id')) { $server = ServerVless::find($request->input('id')); if (!$server) { abort(500, '节点ID不存在'); } } return response([ 'data' => $server->delete() ]); } public function update(Request $request) { $params = $request->validate([ 'show' => 'nullable|in:0,1', ]); $server = ServerVless::find($request->input('id')); if (!$server) { abort(500, '该服务器不存在'); } try { $server->update($params); } catch (\Exception $e) { abort(500, '保存失败'); } return response([ 'data' => true ]); } public function copy(Request $request) { $server = ServerVless::find($request->input('id')); $server->show = 0; if (!$server) { abort(500, '服务器不存在'); } if (!ServerVless::create($server->toArray())) { abort(500, '复制失败'); } return response([ 'data' => true ]); } }