diff --git a/app/Http/Controllers/Admin/NodeController.php b/app/Http/Controllers/Admin/NodeController.php index b49daf8d..b58841d7 100644 --- a/app/Http/Controllers/Admin/NodeController.php +++ b/app/Http/Controllers/Admin/NodeController.php @@ -14,6 +14,7 @@ use App\Models\NodeCertificate; use App\Models\NodePing; use App\Models\RuleGroup; use App\Services\NodeService; +use Arr; use Exception; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -68,7 +69,9 @@ class NodeController extends Controller public function store(NodeRequest $request): JsonResponse { try { - $node = Node::create($request->except('_token', 'labels')); + $array = $request->validated(); + Arr::forget($array, ['labels']); + $node = Node::create($array); if ($node) { // 生成节点标签 @@ -104,10 +107,12 @@ class NodeController extends Controller public function update(NodeRequest $request, Node $node): JsonResponse { try { - // 更新节点标签 - $node->labels()->sync($request->input('labels')); + $array = $request->validated(); + Arr::forget($array, ['labels']); + if ($node->update($array)) { + // 更新节点标签 + $node->labels()->sync($request->input('labels')); - if ($node->update($request->except('_token', 'labels'))) { return Response::json(['status' => 'success', 'message' => '编辑成功']); } } catch (Exception $e) { @@ -182,9 +187,7 @@ class NodeController extends Controller // Ping节点延迟 public function pingNode(Node $node): JsonResponse { - $result = NetworkDetection::ping($node->is_ddns ? $node->server : $node->ip); - - if ($result) { + if ($result = NetworkDetection::ping($node->is_ddns ? $node->server : $node->ip)) { return Response::json([ 'status' => 'success', 'message' => [ diff --git a/app/Http/Controllers/Admin/SystemController.php b/app/Http/Controllers/Admin/SystemController.php index 9a85e73b..c82d09e5 100644 --- a/app/Http/Controllers/Admin/SystemController.php +++ b/app/Http/Controllers/Admin/SystemController.php @@ -4,11 +4,11 @@ namespace App\Http\Controllers\Admin; use App\Components\PushNotification; use App\Http\Controllers\Controller; +use App\Http\Requests\Admin\SystemRequest; use App\Models\Config; use App\Models\Label; use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; -use Illuminate\Http\Request; use Response; class SystemController extends Controller @@ -20,7 +20,7 @@ class SystemController extends Controller } // 设置系统扩展信息,例如客服、统计代码 - public function setExtend(Request $request): RedirectResponse + public function setExtend(SystemRequest $request): RedirectResponse { if ($request->hasFile('website_home_logo')) { $validator = validator()->make($request->all(), ['website_home_logo' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048']); @@ -53,29 +53,18 @@ class SystemController extends Controller } // 设置某个配置项 - public function setConfig(Request $request): JsonResponse + public function setConfig(SystemRequest $request): JsonResponse { $name = $request->input('name'); $value = $request->input('value'); - if (! $name) { - return Response::json(['status' => 'fail', 'message' => '设置失败:请求参数异常']); - } - - // 屏蔽异常配置 - if (! in_array($name, Config::pluck('name')->toArray(), true)) { - return Response::json(['status' => 'fail', 'message' => '设置失败:配置不存在']); - } - // 如果开启用户邮件重置密码,则先设置网站名称和网址 if ($value !== '0' && in_array($name, ['is_reset_password', 'is_activate_account', 'expire_warning', 'traffic_warning'], true)) { - $config = Config::find('website_name'); - if (! $config->value) { + if (! Config::find('website_url')->value) { return Response::json(['status' => 'fail', 'message' => '设置失败:启用该配置需要先设置【网站名称】']); } - $config = Config::find('website_url'); - if (! $config->value) { + if (! Config::find('website_url')->value) { return Response::json(['status' => 'fail', 'message' => '设置失败:启用该配置需要先设置【网站地址】']); } } @@ -146,9 +135,11 @@ class SystemController extends Controller } // 更新配置 - Config::find($name)->update(['value' => $value]); + if (Config::findOrFail($name)->update(['value' => $value])) { + return Response::json(['status' => 'success', 'message' => '修改成功']); + } - return Response::json(['status' => 'success', 'message' => '操作成功']); + return Response::json(['status' => 'fail', 'message' => '修改失败']); } // 推送通知测试 diff --git a/app/Http/Controllers/Admin/TicketController.php b/app/Http/Controllers/Admin/TicketController.php index a7387b6e..19c64691 100644 --- a/app/Http/Controllers/Admin/TicketController.php +++ b/app/Http/Controllers/Admin/TicketController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin; use App\Components\Helpers; use App\Http\Controllers\Controller; +use App\Http\Requests\Admin\TicketRequest; use App\Mail\closeTicket; use App\Mail\replyTicket; use App\Models\Ticket; @@ -37,34 +38,16 @@ class TicketController extends Controller } // 创建工单 - public function store(Request $request) + public function store(TicketRequest $request) { - $id = $request->input('id'); - $email = $request->input('email'); - $title = $request->input('title'); - $content = $request->input('content'); - - $user = User::find($id) ?: User::whereEmail($email)->first(); - - if (! $user) { - return Response::json(['status' => 'fail', 'message' => '用户不存在']); - } + $data = $request->validated(); + $user = User::find($data['id']) ?: User::whereEmail($data['email'])->first(); if ($user === Auth::user()) { return Response::json(['status' => 'fail', 'message' => '不能对自己发起工单']); } - if (empty($title) || empty($content)) { - return Response::json(['status' => 'fail', 'message' => '请输入标题和内容']); - } - - $obj = new Ticket(); - $obj->user_id = $user->id; - $obj->admin_id = Auth::id(); - $obj->title = $title; - $obj->content = $content; - - if ($obj->save()) { + if (Ticket::create(['user_id' => $user->id, 'admin_id' => auth()->id(), 'title' => $data['title'], 'content' => $data['content']])) { return Response::json(['status' => 'success', 'message' => '工单创建成功']); } diff --git a/app/Http/Requests/Admin/NodeRequest.php b/app/Http/Requests/Admin/NodeRequest.php index 2c3e3162..7829c53d 100644 --- a/app/Http/Requests/Admin/NodeRequest.php +++ b/app/Http/Requests/Admin/NodeRequest.php @@ -9,38 +9,47 @@ class NodeRequest extends FormRequest public function rules(): array { return [ - 'type' => 'required|between:1,3', - 'name' => 'required', - 'country_code' => 'required', + 'is_ddns' => 'required|boolean', + 'name' => 'required|string', 'server' => 'required_if:is_ddns,1|nullable|ends_with:'.implode(',', config('domains')), - 'push_port' => 'numeric|between:0,65535', - 'traffic_rate' => 'required|numeric|min:0', - 'level' => 'required|numeric|between:0,255', - 'speed_limit' => 'required|numeric|min:0', - 'client_limit' => 'required|numeric|min:0', - 'port' => 'nullable|numeric|between:0,65535', 'ip' => 'ipv4|required_if:is_ddns,0|nullable', 'ipv6' => 'nullable|ipv6', - 'relay_server' => 'required_if:is_relay,1', - 'relay_port' => 'required_if:is_relay,1|numeric|between:0,65535', - 'method' => 'required_if:type,1', - 'protocol' => 'required_if:type,1', - 'obfs' => 'required_if:type,1', - 'is_subscribe' => 'boolean', - 'is_ddns' => 'boolean', - 'is_relay' => 'boolean', - 'is_udp' => 'boolean', - 'detection_type' => 'between:0,3', - 'compatible' => 'boolean', - 'single' => 'boolean', + 'push_port' => 'numeric|between:0,65535', + 'traffic_rate' => 'required|numeric|min:0', + 'level' => 'required|numeric|exists:level,level', + 'rule_group_id' => 'nullable|exists:rule_group,id', + 'speed_limit' => 'required|numeric|min:0', + 'client_limit' => 'required|numeric|min:0', + 'labels' => 'nullable|exists:label,id', + 'country_code' => 'required|exists:country,code', + 'description' => 'nullable|string', 'sort' => 'required|numeric|between:0,255', - 'status' => 'boolean', + 'is_udp' => 'required|boolean', + 'status' => 'required|boolean', + 'type' => 'required|numeric|between:1,4', + 'method' => 'required_if:type,1,4|exists:ss_config,name', + 'protocol' => 'required_if:type,1,4|exists:ss_config,name', + 'protocol_param' => 'nullable|string', + 'obfs' => 'required_if:type,1,4|exists:ss_config,name', + 'obfs_param' => 'nullable|string', + 'compatible' => 'required|boolean', + 'is_subscribe' => 'required|boolean', + 'detection_type' => 'required|numeric|between:0,3', + 'single' => 'required|boolean', + 'port' => 'required_if:single,1|numeric|between:1,65535|nullable', + 'passwd' => 'required_if:single,1|string|nullable', 'v2_alter_id' => 'required_if:type,2|numeric|between:0,65535', 'v2_port' => 'required_if:type,2|numeric|between:0,65535', 'v2_method' => 'required_if:type,2', 'v2_net' => 'required_if:type,2', 'v2_type' => 'required_if:type,2', - 'v2_tls' => 'boolean', + 'v2_host' => 'string|nullable', + 'v2_path' => 'string|nullable', + 'v2_tls' => 'required_if:type,2|boolean', + 'tls_provider' => 'json|nullable', + 'is_relay' => 'required|boolean', + 'relay_server' => 'required_if:is_relay,1', + 'relay_port' => 'required_if:is_relay,1|numeric|between:1,65535', ]; } diff --git a/app/Http/Requests/Admin/SystemRequest.php b/app/Http/Requests/Admin/SystemRequest.php new file mode 100644 index 00000000..40a4b319 --- /dev/null +++ b/app/Http/Requests/Admin/SystemRequest.php @@ -0,0 +1,23 @@ + 'required|string|exists:config,name', + 'value' => 'nullable', + ]; + } + + public function messages() + { + return [ + 'name.exists' => '设置项目不存在于数据库', + ]; + } +} diff --git a/app/Http/Requests/Admin/TicketRequest.php b/app/Http/Requests/Admin/TicketRequest.php new file mode 100644 index 00000000..0effb00e --- /dev/null +++ b/app/Http/Requests/Admin/TicketRequest.php @@ -0,0 +1,18 @@ + 'required_without:email|exists:user,id|numeric|nullable', + 'email' => 'required_without:id|exists:user,email||nullable', + 'title' => 'required|string', + 'content' => 'required|string', + ]; + } +} diff --git a/resources/views/admin/node/info.blade.php b/resources/views/admin/node/info.blade.php index b7787899..8ab4f391 100644 --- a/resources/views/admin/node/info.blade.php +++ b/resources/views/admin/node/info.blade.php @@ -107,7 +107,6 @@ 国家/地区 - 请选择 @foreach($countries as $country) {{$country->code}} - {{$country->name}} @endforeach diff --git a/resources/views/admin/rule/index.blade.php b/resources/views/admin/rule/index.blade.php index 1b20ba36..8d693051 100644 --- a/resources/views/admin/rule/index.blade.php +++ b/resources/views/admin/rule/index.blade.php @@ -150,14 +150,6 @@ @can('admin.rule.store') // 添加规则 function addRule() { - $.post("{{route('admin.rule.store')}}", {}, function(ret) { - $('#add').modal('hide'); - if (ret.status === 'success') { - swal.fire({title: ret.message, icon: 'success', timer: 1000, showConfirmButton: false}).then(() => window.location.reload()); - } else { - swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload()); - } - }); $.ajax({ method: 'POST', url: "{{route('admin.rule.store')}}", diff --git a/resources/views/admin/ticket/index.blade.php b/resources/views/admin/ticket/index.blade.php index 4694b547..9328563d 100644 --- a/resources/views/admin/ticket/index.blade.php +++ b/resources/views/admin/ticket/index.blade.php @@ -177,18 +177,36 @@ confirmButtonText: '{{trans('home.ticket_confirm')}}', }).then((result) => { if (result.value) { - $.post('{{route('admin.ticket.store')}}', { - _token: '{{csrf_token()}}', - id: id, - email: email, - title: title, - content: content, - }, function(ret) { - if (ret.status === 'success') { - swal.fire({title: ret.message, icon: 'success', timer: 1000, showConfirmButton: false}).then(() => window.location.reload()); - } else { - swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload()); - } + $.ajax({ + method: 'POST', + url: "{{route('admin.ticket.store')}}", + data: { + _token: '{{csrf_token()}}', + id: id, + email: email, + title: title, + content: content, + }, + dataType: 'json', + success: function(ret) { + $('#add_ticket_modal').modal('hide'); + if (ret.status === 'success') { + swal.fire({title: ret.message, icon: 'success', timer: 1000, showConfirmButton: false}).then(() => window.location.reload()); + } else { + swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload()); + } + }, + error: function(data) { + $('#add_ticket_modal').modal('hide'); + let str = ''; + const errors = data.responseJSON; + if ($.isEmptyObject(errors) === false) { + $.each(errors.errors, function(index, value) { + str += '' + value + ''; + }); + swal.fire({title: '提示', html: str, icon: 'error', confirmButtonText: '{{trans('home.ticket_confirm')}}'}); + } + }, }); } }); diff --git a/resources/views/components/chat-unit.blade.php b/resources/views/components/chat-unit.blade.php index 90156b82..10828f1b 100644 --- a/resources/views/components/chat-unit.blade.php +++ b/resources/views/components/chat-unit.blade.php @@ -1,4 +1,9 @@ - + diff --git a/resources/views/user/layouts.blade.php b/resources/views/user/layouts.blade.php index cabd3f67..a3578e1e 100644 --- a/resources/views/user/layouts.blade.php +++ b/resources/views/user/layouts.blade.php @@ -175,7 +175,7 @@
diff --git a/resources/views/user/layouts.blade.php b/resources/views/user/layouts.blade.php index cabd3f67..a3578e1e 100644 --- a/resources/views/user/layouts.blade.php +++ b/resources/views/user/layouts.blade.php @@ -175,7 +175,7 @@