diff --git a/app/admin/controller/v1/ProductCategory.php b/app/admin/controller/v1/ProductCategory.php index 5ac45dc0..4d9d3e53 100644 --- a/app/admin/controller/v1/ProductCategory.php +++ b/app/admin/controller/v1/ProductCategory.php @@ -98,6 +98,9 @@ class ProductCategory if ($data['pid'] > 0) { $parent = $category->bypk($data['pid'])->find(); if (!empty($parent)) { + if (!empty($parent->path)) { + $data['path'] = $parent->path . ',' . $parent->id; + } $data['level'] = $parent->level + 1; } } @@ -145,6 +148,10 @@ class ProductCategory if ($data['pid'] != $category->pid) { $parent = ProductCategoryModel::bypk($data['pid'])->find(); if (!empty($parent)) { + $data['path'] = $parent->id; + if (!empty($parent->path)) { + $data['path'] = $parent->path . ',' . $data['path']; + } $data['level'] = $parent->level + 1; $updated_level = true; } @@ -156,21 +163,24 @@ class ProductCategory // 处理子分类层级 if ($updated_level) { - $this->handle_children($category->id, $data['level']); + $this->handle_children($category->id, $data['path'], $data['level']); } return success('操作成功'); } - private function handle_children($pid, $level) + private function handle_children($pid, $path, $level) { $children = ProductCategoryModel::pid($pid)->select(); if ($children->isEmpty()) { return; } foreach ($children as $child) { + if (!empty($path)) { + $child->path = $path. ','. $child->pid; + } $child->level = $level + 1; if ($child->save()) { - $this->handle_children($child->id, $child->level); + $this->handle_children($child->id, $child->path, $child->level); } } } diff --git a/app/admin/validate/v1/ProductCategoryValidate.php b/app/admin/validate/v1/ProductCategoryValidate.php index 52eaa7d0..d1bf3df3 100644 --- a/app/admin/validate/v1/ProductCategoryValidate.php +++ b/app/admin/validate/v1/ProductCategoryValidate.php @@ -66,20 +66,13 @@ class ProductCategoryValidate extends Validate if ($value == 0) { return true; } - $table_name = (new ProductCategoryModel)->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'))) { + // 如果pid和id相同,返回false + if ($value == $data['id']) { + return false; + } + // 如果pid是id的子分类,返回false + $children = ProductCategoryModel::whereRaw('FIND_IN_SET(:id, path)', ['id' => $data['id']])->column('id'); + if (!empty($children) && in_array($value, $children)) { return false; } diff --git a/app/common/model/ProductCategoryBaseModel.php b/app/common/model/ProductCategoryBaseModel.php index ad53062b..e103d48e 100644 --- a/app/common/model/ProductCategoryBaseModel.php +++ b/app/common/model/ProductCategoryBaseModel.php @@ -21,6 +21,7 @@ class ProductCategoryBaseModel extends BaseModel 'language_id' => 'int', 'unique_id' => 'string', 'pid' => 'int', + 'path' => 'string', 'name' => 'string', 'icon' => 'string', 'desc' => 'string', diff --git a/database/migrations/20241219090629_create_product_category.php b/database/migrations/20241219090629_create_product_category.php index dc322058..b9c0f04b 100644 --- a/database/migrations/20241219090629_create_product_category.php +++ b/database/migrations/20241219090629_create_product_category.php @@ -32,6 +32,7 @@ class CreateProductCategory extends Migrator $table->addColumn('language_id', 'integer', ['signed' => false, 'null' => false, 'comment' => '语言ID']) ->addColumn('unique_id', 'string', ['limit' => 64, 'null' => false, 'comment' => '唯一ID']) ->addColumn('pid', 'integer', ['signed' => false, 'null' => false, 'default' => 0, 'comment' => '父级ID']) + ->addColumn('path', 'string', ['limit' => 128, 'null' => true, 'default' => null, 'comment' => '层级路径']) ->addColumn('name', 'string', ['limit' => 64, 'null' => false, 'comment' => '分类名称']) ->addColumn('icon', 'string', ['limit' => 125, 'default' => null, 'comment' => '图标']) ->addColumn('desc', 'string', ['limit' => 255, 'default' => null, 'comment' => '描述信息'])