From 1d2ce3ebe3ea070c81d8a4e204facfe25db4a7d6 Mon Sep 17 00:00:00 2001 From: jsasg <735273025@qq.com> Date: Thu, 6 Mar 2025 17:55:50 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BF=AE=E6=94=B9=E5=AF=BC?= =?UTF-8?q?=E8=88=AA=E7=88=B6=E7=BA=A7=E4=B8=8D=E8=83=BD=E4=B8=BA=E8=87=AA?= =?UTF-8?q?=E8=BA=AB=E6=88=96=E5=AD=90=E5=AF=BC=E8=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validate/v1/NavigationItemValidate.php | 62 ++++++++++++++----- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/app/admin/validate/v1/NavigationItemValidate.php b/app/admin/validate/v1/NavigationItemValidate.php index bf2dbff7..4da9e1bb 100644 --- a/app/admin/validate/v1/NavigationItemValidate.php +++ b/app/admin/validate/v1/NavigationItemValidate.php @@ -3,6 +3,8 @@ declare (strict_types = 1); namespace app\admin\validate\v1; +use app\admin\model\v1\SysNavigationItemModel; +use think\facade\Db; use think\Validate; class NavigationItemValidate extends Validate @@ -16,7 +18,7 @@ class NavigationItemValidate extends Validate protected $rule = [ 'id' => 'require|integer', 'nav_id' => 'require|integer', - 'pid' => 'integer', + 'pid' => 'integer|different:id|checkPidNotBeChildren', 'name' => 'require|max:64', 'icon' => 'max:64', 'link_type' => 'require|integer', @@ -33,23 +35,51 @@ class NavigationItemValidate extends Validate * @var array */ protected $message = [ - 'id.require' => 'ID不能为空', - 'id.integer' => 'ID必须为整数', - 'nav_id.require' => '导航ID不能为空', - 'nav_id.integer' => '导航ID必须为整数', - 'pid.integer' => '父级ID必须为整数', - 'name.require' => '导航名称不能为空', - 'name.max' => '导航名称最多不能超过64个字符', - 'icon.max' => '图标最多不能超过64个字符', - 'link_type.require' => '链接类型不能为空', - 'link_type.integer' => '链接类型必须为整数', - 'link.max' => '链接最多不能超过255个字符', - 'sort.integer' => '排序必须为整数', - 'blank.in' => '是否新窗口打开只能是0或1', - 'status.require' => '状态不能为空', - 'status.in' => '状态只能是1或-1', + 'id.require' => 'ID不能为空', + 'id.integer' => 'ID必须为整数', + 'nav_id.require' => '导航ID不能为空', + 'nav_id.integer' => '导航ID必须为整数', + 'pid.integer' => '父级ID必须为整数', + 'pid.different' => '父级ID不能为自身', + 'pid.checkPidNotBeChildren' => '父级ID不能为自身的子导航', + 'name.require' => '导航名称不能为空', + 'name.max' => '导航名称最多不能超过64个字符', + 'icon.max' => '图标最多不能超过64个字符', + 'link_type.require' => '链接类型不能为空', + 'link_type.integer' => '链接类型必须为整数', + 'link.max' => '链接最多不能超过255个字符', + 'sort.integer' => '排序必须为整数', + 'blank.in' => '是否新窗口打开只能是0或1', + 'status.require' => '状态不能为空', + 'status.in' => '状态只能是1或-1', ]; + // 验证pid + protected function checkPidNotBeChildren($value, $rule, $data = []) + { + if ($value == 0) { + return true; + } + $table_name = (new SysNavigationItemModel)->getTable(); + $children = Db::query( + preg_replace( + '/\s+/u', + ' ', + "WITH RECURSIVE tree_by AS ( + SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']} + UNION ALL + SELECT k.id, k.pid FROM $table_name k INNER JOIN tree_by t ON t.id = k.pid + ) + SELECT id FROM tree_by WHERE id <> {$data['id']};" + ) + ); + if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) { + return false; + } + + return true; + } + // 定义场景 protected $scene = [ 'add' => ['nav_id', 'pid', 'name', 'icon', 'link_type', 'link', 'sort', 'blank', 'status'],