diff --git a/app/admin/controller/v1/ArticleCategory.php b/app/admin/controller/v1/ArticleCategory.php index bb6ddb65..2012a848 100644 --- a/app/admin/controller/v1/ArticleCategory.php +++ b/app/admin/controller/v1/ArticleCategory.php @@ -20,6 +20,7 @@ class ArticleCategory ]); $categorys = ArticleCategoryModel::field([ 'id', + 'pid', 'name' ]) ->language(request()->lang_id) @@ -31,16 +32,14 @@ class ArticleCategory }) ->order('sort', 'asc') ->select(); - return success('获取成功', $categorys); + return success('获取成功', array_to_tree($categorys, 0, 'pid', 1, false)); } // 分类分页列表 public function index() { $param = request()->param([ - 'name', - 'page/d' => 1, - 'limit/d' => 10, + 'name' ]); $category = ArticleCategoryModel::withoutField([ @@ -54,12 +53,9 @@ class ArticleCategory } }) ->order('sort', 'asc') - ->paginate([ - 'page' => $param['page'], - 'list_rows' => $param['limit'] - ]); + ->select(); - return success('获取成功', $category); + return success('获取成功', array_to_tree($category, 0, 'pid', 1, false)); } // 分类详情 @@ -80,13 +76,14 @@ class ArticleCategory { $post = request()->post([ 'name', + 'pid', 'sort' => 0, 'is_show' => 1 ]); $data = array_merge($post, ['language_id' => request()->lang_id]); $valiate = new ArticleCategoryValidate; - if (!$valiate->check($data)) { + if (!$valiate->scene('add')->check($data)) { return error($valiate->getError()); } @@ -103,6 +100,7 @@ class ArticleCategory $id = request()->param('id'); $put = request()->put([ 'name', + 'pid', 'sort', 'is_show' ]); diff --git a/app/admin/validate/v1/ArticleCategoryValidate.php b/app/admin/validate/v1/ArticleCategoryValidate.php index b334b61f..efe019be 100644 --- a/app/admin/validate/v1/ArticleCategoryValidate.php +++ b/app/admin/validate/v1/ArticleCategoryValidate.php @@ -3,6 +3,8 @@ declare (strict_types = 1); namespace app\admin\validate\v1; +use app\admin\model\v1\ArticleModel; +use think\facade\Db; use think\Validate; class ArticleCategoryValidate extends Validate @@ -14,8 +16,10 @@ class ArticleCategoryValidate extends Validate * @var array */ protected $rule = [ + 'id' => 'require|integer', 'language_id' => 'require|integer', 'name' => 'require|unique:article_category,name^language_id|max:64', + 'pid' => 'integer"different:id|checkPidNotBeChildren', // 验证pid 'sort' => 'require|integer', 'is_show' => 'require|in:0,1', 'seo_title' => 'max:255', @@ -30,17 +34,54 @@ class ArticleCategoryValidate extends Validate * @var array */ protected $message = [ - 'language_id.require' => '语言ID不能为空', - 'language_id.integer' => '语言ID必须为整数', - 'name.require' => '分类名称不能为空', - 'name.unique' => '分类名称已存在', - 'name.max' => '分类名称最多64个字符', - 'sort.require' => '排序不能为空', - 'sort.integer' => '排序必须为整数', - 'is_show.require' => '是否显示不能为空', - 'is_show.in' => '是否显示值必须为0或1', - 'seo_title.max' => 'SEO标题最多255个字符', - 'seo_keywords.max' => 'SEO关键词最多255个字符', - 'seo_desc.max' => 'SEO描述最多255个字符', + 'id.require' => '分类ID不能为空', + 'id.integer' => '分类ID必须为整数', + 'language_id.require' => '语言ID不能为空', + 'language_id.integer' => '语言ID必须为整数', + 'name.require' => '分类名称不能为空', + 'name.unique' => '分类名称已存在', + 'name.max' => '分类名称最多64个字符', + 'pid.integer' => '父级分类ID必须为整数', + 'pid.different' => '父级分类ID不能为自身', + 'pid.checkPidNotBeChildren' => '父级分类不能为子分类', + 'sort.require' => '排序不能为空', + 'sort.integer' => '排序必须为整数', + 'is_show.require' => '是否显示不能为空', + 'is_show.in' => '是否显示值必须为0或1', + 'seo_title.max' => 'SEO标题最多255个字符', + 'seo_keywords.max' => 'SEO关键词最多255个字符', + 'seo_desc.max' => 'SEO描述最多255个字符', ]; + + // 验证pid + protected function checkPidNotBeChildren($value, $rule, $data = []) + { + if ($value == 0) { + return true; + } + $table_name = (new ArticleModel)->getTable(); + $children = Db::query( + preg_replace( + '/\s+/u', + ' ', + "WITH RECURSIVE article_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 article_tree_by t ON t.id = k.pid + ) + SELECT id FROM article_tree_by WHERE id <> {$data['id']};" + ) + ); + if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) { + return false; + } + + return true; + } + + // 新增分类验证场景 + protected function sceneAdd() + { + $this->remove('id', 'require|integer')->remove('pid', 'different|checkPidNotBeChildren'); + } }