文档目录
内容管理服务

简介

本文件面向 DouPHP 框架的内容管理服务,聚焦文章、案例、课程、下载等“内容型”模块的统一管理模式与服务实现。文档从系统架构、数据流、处理逻辑、集成点、错误处理与性能特性等方面展开,并给出关键流程的可视化图示与代码级引用路径,帮助读者快速理解并扩展新的内容类型与管理复杂业务。

项目结构

DouPHP 采用分层与模块化组织:

  • 后台管理:admin/controller、admin/service、admin/model、admin/request、admin/view 等
  • 前台展示:front/controller、front/service、front/model、front/view 等
  • 核心能力:core/service(附件、Markdown、审计、路由资源构建等)、core/orm、core/foundation 等
  • 主题与模板:theme/* 与 front/theme 下的模板与扩展加载机制

内容管理在后台以 Service 层统一封装 CRUD、批量操作、二次确认、日志记录;在前台以 Model 层提供查询构造器、列表字段增强、SEO 与多语言支持;附件通过 AttachmentService 统一管理上传、草稿认领、URL 生成等。

graph TB
A["后台控制器<br/>admin/controller"] --> B["后台服务<br/>admin/service/*"]
B --> C["后台模型<br/>admin/model/*"]
B --> D["附件服务<br/>core/service/attachment"]
B --> E["Markdown渲染<br/>core/service/content"]
B --> F["审计日志<br/>core/service/admin"]
G["前台模型<br/>front/model/*"] --> H["模板引擎<br/>front/service/init/ThemeExtensionLoader"]
B --> I["ORM/数据库"]
G --> I

图表来源

  • RouteResourceBuilder.php:53-79
  • ThemeExtensionLoader.php:56-69

章节来源

  • RouteResourceBuilder.php:53-79
  • ThemeExtensionLoader.php:56-69

核心组件

  • 后台服务层:ArticleService、CourseService、CasesService 等,负责列表组装、新增/更新/删除、批量操作、二次确认、日志记录。
  • 前台模型层:Article 等模型,提供发布状态过滤、默认排序、列表字段增强、SEO 与多语言字段覆写、预取优化。
  • 附件服务:AttachmentService,统一处理上传、草稿认领、内容图片拉取、URL 生成、画廊等。
  • 路由资源构建:RouteResourceBuilder 提供标准 RESTful 动作映射,便于统一资源路由。
  • 分类服务:各模块 CategoryService 提供分类增删改查与删除保护(占用/子类检查 + 二次确认)。
  • 搜索与索引:DocService 中演示了关键词搜索的轻量先匹配再主查询策略,可借鉴到内容模块。
  • 模板扩展:ThemeExtensionLoader 在主题扩展文件中注入 Portal 启动与自定义扩展逻辑。

章节来源

  • ArticleService.php:1-314
  • CourseService.php:1-315
  • CasesService.php:1-313
  • AttachmentService.php:32-62
  • RouteResourceBuilder.php:53-79
  • CategoryService.php(下载分类):176-203
  • CategoryService.php(课程分类):177-212
  • CategoryService.php(视频分类):177-212
  • DocService.php:69-243
  • ThemeExtensionLoader.php:56-69

架构总览

内容管理的典型请求链路如下:

  • 后台:Controller → Service → Model → ORM/DB;同时调用附件服务、Markdown 渲染、审计日志。
  • 前台:Controller → Model(AR 查询、casts、prefetchers、translatable)→ 模板引擎渲染。
sequenceDiagram
participant Admin as "后台控制器"
participant Svc as "后台服务"
participant Att as "附件服务"
participant MD as "Markdown渲染"
participant Aud as "审计日志"
participant DB as "数据库"
Admin->>Svc : 提交新增/更新
Svc->>Att : 存储正文图片/主图
Svc->>MD : 预览或格式化内容
Svc->>DB : 创建/更新记录
Svc->>Aud : 写入操作日志
DB-->>Svc : 返回结果
Svc-->>Admin : 返回消息与跳转

图表来源

  • ArticleService.php:129-173
  • CourseService.php:128-177
  • CasesService.php:128-176
  • AttachmentService.php:32-62

详细组件分析

文章管理(Article)

  • 列表数据:按分类与关键词过滤,分页并附加 category 关联,输出模板所需字段。
  • 新增流程:清洗内容、可选本地化远程图片、写入记录、上传主图、认领草稿、记录日志。
  • 编辑流程:读取原始列值、格式化时间、Markdown 预览、defined 参数解析。
  • 删除流程:二次确认分支,确认后删除并记录日志。
  • 批量操作:批量删除与批量转移分类。
flowchart TD
Start(["进入新增"]) --> Clean["清洗内容XSS"]
Clean --> Remote{"是否包含远程图片?"}
Remote --> |是| LocalImg["拉取并本地化图片"]
Remote --> |否| SaveRecord["创建文章记录"]
LocalImg --> SaveRecord
SaveRecord --> UploadMain["上传主图"]
UploadMain --> ClaimDraft["认领草稿"]
ClaimDraft --> Log["记录审计日志"]
Log --> End(["完成"])

图表来源

  • ArticleService.php:129-173

章节来源

  • ArticleService.php:55-100
  • ArticleService.php:102-127
  • ArticleService.php:129-173
  • ArticleService.php:175-200
  • ArticleService.php:202-243
  • ArticleService.php:245-312

前台文章模型(Article)

  • 列表增强:casts 格式化 image/defined/created_at;appends 附加 url/name/description/cate_info 等。
  • SEO 与多语言:translatable 覆盖 title/content/description/keywords。
  • 预取优化:prefetchers 预热 url、language、attachment,减少 N+1。
  • 查询构造:scopePublished、scopeFilterByArchive、scopeImageNotEmpty、scopeApplyDefaultOrder。
classDiagram
class Article {
+table "article"
+casts "image, defined, created_at"
+appends "url,name,description,cate_info"
+translatable "title,content,description,keywords"
+prefetchers "url,language,attachment"
+moduleSchema()
+categoryClass()
+category()
+findPublishedById(id)
+scopePublished(query)
+scopeFilterByArchive(query, archive)
+scopeImageNotEmpty(query)
+scopeApplyDefaultOrder(query)
}

图表来源

  • Article.php(前台模型):40-176

章节来源

  • Article.php(前台模型):40-176

课程管理(Course)

  • 与文章类似的服务结构:列表、默认表单、新增、编辑、删除、批量操作。
  • 新增时同样处理内容清洗、远程图片本地化、主图上传、草稿认领与审计日志。
sequenceDiagram
participant Ctl as "课程控制器"
participant Svc as "课程服务"
participant Att as "附件服务"
participant DB as "数据库"
Ctl->>Svc : insert(data, draftToken, adminId)
Svc->>Att : storeDraftContentImages / store(main)
Svc->>DB : create course
Svc->>Att : claimByToken
Svc-->>Ctl : newId

图表来源

  • CourseService.php:128-177

章节来源

  • CourseService.php:54-99
  • CourseService.php:101-126
  • CourseService.php:128-177
  • CourseService.php:179-244
  • CourseService.php:246-313

案例管理(Cases)

  • 服务结构与文章、课程一致,体现统一的内容管理范式。
  • 新增/更新均包含内容清洗、远程图片本地化、主图上传、草稿认领与审计日志。

章节来源

  • CasesService.php:54-99
  • CasesService.php:101-126
  • CasesService.php:128-176
  • CasesService.php:178-242
  • CasesService.php:244-311

分类管理(Category)

  • 删除保护:若分类下有记录或存在子分类,抛出业务异常阻止删除。
  • 二次确认:未携带 confirm 时返回前端确认信息,携带 confirm 后执行删除。
  • 清理附属:删除图标附件、语言数据、导航项等。
flowchart TD
Enter["进入删除分类"] --> CheckExist{"分类存在?"}
CheckExist --> |否| ThrowErr["抛出业务异常"]
CheckExist --> |是| CheckUsed{"是否有记录?"}
CheckUsed --> |是| ThrowErr
CheckUsed --> |否| CheckChild{"是否有子分类?"}
CheckChild --> |是| ThrowErr
CheckChild --> |否| Confirm{"是否二次确认?"}
Confirm --> |否| ReturnConfirm["返回确认信息"]
Confirm --> |是| Cleanup["清理附件/语言/导航"]
Cleanup --> Delete["删除分类"]
Delete --> Log["记录审计日志"]
Log --> Done["完成"]

图表来源

  • CategoryService.php(下载分类):176-203
  • CategoryService.php(课程分类):177-212
  • CategoryService.php(视频分类):177-212

章节来源

  • CategoryService.php(下载分类):176-203
  • CategoryService.php(课程分类):177-212
  • CategoryService.php(视频分类):177-212

标签系统与 SEO 优化

  • 标签系统:可通过 tag 模块与内容关联(如 article_tag、course_tag 等),在服务层进行读写与聚合。
  • SEO 优化:前台模型 translatable 字段包含 keywords,用于详情页 SEO;列表页可通过自定义字段与 URL 访问器提升可读性与分享效果。
  • 内容导出:模型 moduleSchema 声明 sitemap/llms 导出能力,便于搜索引擎收录。

章节来源

  • Article.php(前台模型):75-94
  • Article.php(前台模型):65-73

内容审核

  • 状态字段:status 控制发布状态(如已发布/待审/隐藏),前台 scopePublished 仅返回已发布内容。
  • 后台操作:Service 层在新增/更新时可设置 status,配合权限与审批流程实现审核闭环。

章节来源

  • Article.php(前台模型):116-136

与模板引擎、搜索引擎、缓存系统的集成

  • 模板引擎:ThemeExtensionLoader 在主题扩展文件中注入 Portal 启动与自定义扩展逻辑,便于模板层获取上下文与数据。
  • 搜索引擎:可参考 DocService 的关键词搜索策略,先轻量查询匹配 ID,再按 ID 过滤主查询,降低 IO 压力。
  • 缓存系统:Model prefetchers 与附件 URL 生成可结合缓存键(如 cacheTag)减少重复计算;列表页可使用分页与字段裁剪提升性能。

章节来源

  • ThemeExtensionLoader.php:56-69
  • DocService.php:69-243
  • AttachmentService.php:32-62

依赖关系分析

  • 服务层依赖:
    • 附件服务:store/storeDraftContentImages/storeContentImages/claimByToken/url
    • Markdown 渲染:toHtml
    • 审计日志:writeAdminLog
    • ORM/数据库:Model::create/find/update/destroy/paginate
  • 路由资源:
    • RouteResourceBuilder 定义 index/create/store/show/edit/update/destroy 的标准映射,便于统一资源路由。
graph LR
Svc["后台服务"] --> Att["附件服务"]
Svc --> MD["Markdown渲染"]
Svc --> Aud["审计日志"]
Svc --> ORM["ORM/数据库"]
Rb["路由资源构建"] --> Svc

图表来源

  • ArticleService.php:129-173
  • RouteResourceBuilder.php:53-79

章节来源

  • RouteResourceBuilder.php:53-79

性能考虑

  • 列表查询:使用 with('category') 批量加载关联,避免 N+1;field 裁剪只取必要字段;applyDefaultOrder 统一排序。
  • 搜索优化:参考 DocService 的“先轻量匹配 ID,再主查询过滤”的策略,减少大表扫描。
  • 附件 URL:使用 attachment()->url 与缓存标签,减少重复计算与磁盘 IO。
  • 模板渲染:prefetchers 预热 url/language/attachment,提升列表渲染速度。

故障排查指南

  • 常见异常:
    • 非法参数:DomainException 提示非法请求,检查 adminId、id、draftToken 等必填参数。
    • 记录不存在:删除/更新前需校验记录是否存在,避免空指针与无效操作。
    • 分类删除受阻:当分类被占用或有子分类时,抛出业务异常,需先处理依赖项。
  • 日志定位:
    • 审计日志:writeAdminLog 记录创建/更新/删除行为,便于追踪变更历史。
    • 附件问题:检查 upload 目录权限、临时文件清理、草稿认领 token 有效性。
  • 调试建议:
    • 开启调试模式查看 SQL 与异常堆栈。
    • 使用分页与字段裁剪验证查询性能。
    • 对关键词搜索增加索引与分词策略。

章节来源

  • ArticleService.php:141-173
  • CourseService.php:141-177
  • CasesService.php:140-176
  • CategoryService.php(下载分类):176-203

结论

DouPHP 的内容管理服务通过统一的 Service 层与 Model 层设计,实现了文章、案例、课程、下载等内容类型的标准化 CRUD、分类管理、标签与 SEO 优化、内容审核等功能。附件服务与 Markdown 渲染、审计日志、路由资源构建等核心能力深度集成,形成高内聚、低耦合的架构。借助 DocService 的搜索策略与 Model 的预取优化,系统在大规模内容场景下具备良好的可扩展性与性能表现。

附录:扩展与最佳实践

  • 新增内容类型步骤:
    • 创建后台 Service:参照 ArticleService/CourseService/CasesService,实现列表、默认表单、新增、更新、删除、批量操作。
    • 创建前台 Model:定义 table、casts、appends、translatable、prefetchers、moduleSchema,提供 scope 与关联。
    • 配置路由:利用 RouteResourceBuilder 的标准动作映射,注册资源路由。
    • 集成附件与 Markdown:在新增/更新中处理内容清洗、远程图片本地化、主图上传与草稿认领。
    • 分类管理:实现 CategoryService,提供删除保护与二次确认。
    • SEO 与导出:在 modelSchema 中声明 sitemap/llms 导出能力,完善 keywords 与 URL 访问器。
  • 最佳实践:
    • 始终使用 field 裁剪与 with 批量加载,避免 N+1。
    • 对关键词搜索采用“先轻量匹配 ID,再主查询过滤”的策略。
    • 使用 attachment()->cacheTag 与模板缓存键,减少重复计算。
    • 在 Service 层集中处理业务规则与异常,保持 Controller 简洁。
    • 通过审计日志记录关键操作,便于追溯与合规。
添加日期:2026-10-05