# 6.7 文章管理 :::tip 概述 文章管理模块支持富文本内容编辑、封面图上传、分类关联。继承 BaseTenantLogic 实现租户隔离,并配置了数据权限(按创建人过滤)。 ::: ## 模块特点 | 特性 | 说明 | |------|------| | 基类 | BaseTenantLogic(租户隔离) | | 文件字段 | cover(封面图),保存到 article 目录 | | 富文本字段 | content(文章内容),自动处理临时文件 | | 枚举映射 | status → article_status 字典(0=正常 1=下架) | | 数据权限 | dataScopeUserField='create_user',按创建人过滤 | | 模糊搜索 | title、author | | 精确匹配 | category_id、status | ## API 接口 | 方法 | 路径 | 权限码 | 说明 | |------|------|--------|------| | GET | `/api/article/page` | sys:article:page | 分页列表 | | GET | `/api/article/list` | - | 全量列表 | | GET | `/api/article/detail/:id` | sys:article:detail | 详情 | | POST | `/api/article/add` | sys:article:add | 新增 | | PUT | `/api/article/update` | sys:article:update | 修改 | | DELETE | `/api/article/delete/:id` | sys:article:delete | 删除 | | DELETE | `/api/article/batchDelete` | sys:article:batchDelete | 批量删除 | ## 核心代码 ```php // app/logic/ArticleLogic.php class ArticleLogic extends BaseTenantLogic { /** * 关联的模型类 * * @var string */ protected string $modelClass = Article::class; /** * 需要自动处理的文件上传字段 * * @var array */ protected array $fileFields = ['cover']; /** * 文件保存的子目录 * * @var string */ protected string $fileSaveDir = 'article'; /** * LIKE 模糊匹配字段 * * @var array */ protected array $pageLikeFields = ['title', 'author']; /** * 精确匹配字段 * * @var array */ protected array $pageEqFields = ['category_id', 'status']; /** * 默认排序规则 * * @var array */ protected array $pageOrderBy = [ ['field' => 'tenant_id', 'type' => 'asc'], ['field' => 'sort', 'type' => 'asc'], ]; /** * 枚举显示名映射 * * @var array */ protected array $serializeMaps = [ 'status' => 'article_status', ]; /** * 富文本字段 * * @var array */ protected array $contentFields = ['content']; /** * 数据权限:归属字段名(用于按创建人过滤) * * @var string */ protected string $dataScopeUserField = 'create_user'; } ``` ### Controller 代码 ```php // app/controller/ArticleController.php class ArticleController extends BaseController { protected ArticleLogic $logic; protected function initialize(): void { $this->logic = new ArticleLogic(); } #[Log('文章管理-查询分页记录', Log::TYPE_QUERY)] #[Permission('sys:article:page', '文章分页')] public function page(): Json { return parent::_index($this->logic); } #[Log('文章管理-新增记录', Log::TYPE_ADD, '新增文章:{title}')] #[Permission('sys:article: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:article: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:article:delete', '删除文章')] public function delete(int $id): Json { return parent::_remove($this->logic, $id); } #[Log('文章管理-批量删除', Log::TYPE_DELETE)] #[Permission('sys:article:delete', '删除文章')] public function batchDelete(): Json { $ids = $this->getJsonBody()['ids'] ?? []; return parent::_batchRemove($this->logic, $ids); } } ``` :::tip 数据权限 文章模块配置了 `dataScopeUserField = 'create_user'`,普通用户只能看到自己创建的文章。管理员(data_scope=1)可看到全部文章。 ::: :::warning 富文本处理 content 字段配置为富文本字段后,新增/修改时会自动处理内容中的临时文件:解析 `` 标签的 src,临时文件迁移到正式目录,替换为 `[IMG_URL]` 占位符。读取时自动替换为实际域名。 :::