Become a sponsor

概述
分类管理支持树形分类数据,可用于文章分类、商品分类等场景。继承 BaseTenantLogic 实现租户隔离。
| 特性 | 说明 |
|---|---|
| 基类 | BaseTenantLogic(租户隔离) |
| 唯一校验 | category_name + parent_id 复合唯一(同一父级下名称不可重复) |
| 删除校验 | beforeDelete 检查子分类和关联文章 |
| 模糊搜索 | category_name |
| 精确匹配 | parent_id |
CREATE TABLE `think_category` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`category_name` varchar(100) NOT NULL COMMENT '分类名称',
`category_code` varchar(100) DEFAULT NULL COMMENT '分类编码',
`parent_id` int DEFAULT 0 COMMENT '上级ID',
`sort` int DEFAULT 0 COMMENT '排序',
`note` varchar(100) DEFAULT NULL COMMENT '分类备注',
`create_user` varchar(50) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT (now()) COMMENT '创建时间',
`update_user` varchar(50) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT (now()) COMMENT '更新时间',
`is_delete` int DEFAULT 0 COMMENT '删除标识:0-正常 1-已删除',
PRIMARY KEY (`id`)
) COMMENT = '文章分类表';| 方法 | 路径 | 权限码 | 说明 |
|---|---|---|---|
| GET | /api/category/page | sys:category:page | 分页列表 |
| GET | /api/category/list | sys:category:list | 全量列表 |
| GET | /api/category/detail/:id | sys:category:detail | 详情 |
| POST | /api/category/add | sys:category:add | 新增 |
| PUT | /api/category/update | sys:category:update | 修改 |
| DELETE | /api/category/delete/:id | sys:category:delete | 删除 |
| DELETE | /api/category/batchDelete | sys:category:batchDelete | 批量删除 |
// app/logic/CategoryLogic.php
class CategoryLogic extends BaseTenantLogic
{
protected string $modelClass = Category::class;
protected array $pageLikeFields = ['category_name'];
protected array $pageEqFields = ['parent_id'];
protected array $pageOrderBy = [
['field' => 'tenant_id', 'type' => 'asc'],
['field' => 'sort', 'type' => 'asc'],
];
/**
* 唯一性校验字段
*
* 同一父级下分类名称不可重复
*
* @var array
*/
protected array $uniqueFields = [['category_name', 'parent_id']];
/**
* 删除前处理:检查子分类和关联文章
*
* @param int $id 待删除的分类 ID
* @return void
* @throws \Exception 当存在子分类或关联文章时抛出
*/
protected function beforeDelete(int $id): void
{
$childCount = Category::where('parent_id', $id)->count();
if ($childCount > 0) {
throw new \Exception('该分类下存在子分类,不可删除');
}
$articleCount = Article::where('category_id', $id)->count();
if ($articleCount > 0) {
throw new \Exception('该分类下存在文章,不可删除');
}
}
}// app/controller/CategoryController.php
class CategoryController extends BaseController
{
protected CategoryLogic $logic;
protected function initialize(): void
{
$this->logic = new CategoryLogic();
}
#[Log('分类管理-查询分页记录', Log::TYPE_QUERY)]
#[Permission('sys:category:page', '分类分页')]
public function page(): Json
{
return parent::_index($this->logic);
}
#[Log('分类管理-查询树形列表', Log::TYPE_QUERY)]
#[Permission('sys:category:list', '分类列表')]
public function list(): Json
{
return parent::_list($this->logic);
}
#[Log('分类管理-新增记录', Log::TYPE_ADD, '新增分类:{category_name}')]
#[Permission('sys:category:add', '添加分类')]
public function add(): Json
{
try {
$id = $this->logic->add($this->getJsonBody());
return $this->success(['id' => $id], '添加成功');
} catch (\Exception $e) {
return $this->fail($e->getMessage());
}
}
#[Log('分类管理-修改记录', Log::TYPE_UPDATE, '修改分类ID:{id}')]
#[Permission('sys:category:update', '修改分类')]
public function update(): Json
{
$data = $this->getJsonBody();
$id = $data['id'] ?? 0;
if (empty($id)) return $this->fail('缺少id参数');
try {
$this->logic->update($id, $data);
return $this->success(null, '修改成功');
} catch (\Exception $e) {
return $this->fail($e->getMessage());
}
}
#[Log('分类管理-删除记录', Log::TYPE_DELETE, '删除分类ID:{id}')]
#[Permission('sys:category:delete', '删除分类')]
public function delete(int $id): Json
{
return parent::_remove($this->logic, $id);
}
#[Log('分类管理-批量删除', Log::TYPE_DELETE)]
#[Permission('sys:category:delete', '删除分类')]
public function batchDelete(): Json
{
$ids = $this->getJsonBody()['ids'] ?? [];
return parent::_batchRemove($this->logic, $ids);
}
}复合唯一性
分类的唯一性校验使用复合格式 [['category_name', 'parent_id']],表示同一父级下分类名称不可重复,但不同父级下可以有同名分类。