简介
本文件面向 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 简洁。
- 通过审计日志记录关键操作,便于追溯与合规。