简介
本开发文档围绕 DouPHP 的“案例管理”模块,系统阐述后台管理、前台展示与 API 三端的实现方式。内容覆盖案例的增删改查、分类体系、SEO 优化、访问统计、评论集成、图片画廊关联等能力;并给出创建案例、获取详情、筛选列表的代码级调用路径与最佳实践建议,帮助开发者快速定位与扩展。
项目结构
案例模块采用前后端分离的控制器分层设计:
- 后台管理:admin/controller/cases 提供案例与分类的 CRUD 与批量操作
- 前台展示:front/controller/cases 负责列表、详情、导航、面包屑与 SEO
- API 接口:api/controller/cases 提供移动端或第三方调用的数据接口
- 模型与服务:admin/front 下的 model 与 service 承载数据访问与业务逻辑
graph TB
subgraph "后台管理"
AC["CasesController<br/>admin/controller/cases"]
CC["CategoryController<br/>admin/controller/cases"]
end
subgraph "前台展示"
FC["CasesController<br/>front/controller/cases"]
end
subgraph "API 接口"
AIC["CasesController<br/>api/controller/cases"]
end
subgraph "模型与服务"
AMS["CasesService<br/>admin/service/cases"]
ACS["CategoryService<br/>admin/service/cases"]
FM["CasesModel<br/>front/model/cases"]
FCM["CasesCategoryModel<br/>front/model/cases"]
end
AC --> AMS
CC --> ACS
FC --> FM
FC --> FCM
AIC --> FM
AIC --> FCM
核心组件
- 后台案例控制器:负责案例列表、新增、编辑、更新、删除与批量操作,表单校验由请求对象完成,业务规则交由服务层处理
- 后台分类控制器:负责案例分类的树形管理与维护
- 前台案例控制器:负责案例列表、详情渲染,集成导航、面包屑、SEO、Schema 结构化数据与评论模块
- API 案例控制器:对外暴露案例列表与详情接口,支持分页、归档与分类过滤
- 模型与服务:封装数据查询、构建视图数据、访问统计、分类树/平铺等通用能力
架构总览
案例模块遵循“控制器-服务-模型”的分层架构,控制器仅做参数接收与响应组装,复杂逻辑下沉至 Service,数据访问由 Model 承担。前台与 API 共享同一份 Service/Model 能力,保证行为一致。
sequenceDiagram
participant U as "用户/客户端"
participant F as "前台控制器<br/>front/controller/cases"
participant S as "案例服务<br/>front/admin service"
participant M as "案例模型<br/>front/model/cases"
participant C as "分类模型<br/>front/model/cases"
U->>F : 请求案例列表/详情
F->>S : 构建列表/详情数据
S->>M : 查询案例含分页/归档/筛选
M-->>S : 返回案例集合
S->>C : 读取分类树/信息
C-->>S : 返回分类数据
S-->>F : 组装后的数据
F-->>U : 渲染页面/JSON 响应
详细组件分析
后台案例管理(CRUD 与批量)
- 列表:支持按分类、关键词、页码筛选,返回分页数据与分类树
- 新增/编辑:表单校验由 CasesFormRequest 完成;新增时支持草稿 token;编辑时加载多语言按钮配置
- 更新/删除:更新重定向回编辑页;删除走统一删除结果处理器
- 批量操作:通过 action 方法集中处理批量状态变更等
flowchart TD
Start(["进入后台案例列表"]) --> Query["解析分类/关键词/页码"]
Query --> BuildList["调用服务构建列表数据"]
BuildList --> Render["渲染 cases.htm 模板"]
Render --> Action{"选择操作?"}
Action --> |新增| Create["生成草稿Token并渲染表单"]
Action --> |编辑| Edit["校验ID并加载编辑数据"]
Action --> |删除| Destroy["校验ID并执行删除"]
Action --> |批量| Batch["提交批量动作"]
Create --> Store["保存并跳转编辑"]
Edit --> Update["更新并重定向"]
Destroy --> Done(["完成"])
Batch --> Done
后台案例分类管理
- 列表:以树形结构展示所有分类
- 新增/编辑:支持多语言字段(名称、关键词、描述)
- 删除:级联处理子分类与关联案例
classDiagram
class CategoryController {
+index()
+create()
+store()
+edit()
+update()
+destroy()
}
class CategoryService {
+buildCategoryDefaultData()
+insert(data, adminId)
+buildCategoryEditData(catId)
+update(data, adminId)
+delete(catId, post)
}
CategoryController --> CategoryService : "依赖"
前台案例展示(列表/详情/SEO/评论)
- 列表:支持分类、日期归档、分页;注入导航、面包屑、SEO 标题/关键词/描述;提供相关案例
- 详情:记录点击量、加载评论、生成 Schema 结构化数据、输出多语言元信息
- 路由兼容:同时支持 slug、id、category_slug、year/month 等多维路由参数
sequenceDiagram
participant B as "浏览器"
participant F as "前台控制器"
participant S as "案例服务"
participant M as "案例模型"
participant N as "导航/面包屑"
participant SEO as "SEO工具"
B->>F : GET /cases/category/{slug}
F->>N : 构建导航/面包屑
F->>S : buildCasesListData(分类/归档/分页)
S->>M : 查询案例集合
M-->>S : 返回列表
S-->>F : 组装数据
F->>SEO : 生成标题/关键词/描述
F-->>B : 渲染 cases_category.dwt
API 案例接口(列表/详情)
- 列表:支持分类、归档、分页;返回分类树与当前分类信息
- 详情:返回案例详情、自定义字段、评论分页数据;自动累计点击
sequenceDiagram
participant App as "客户端"
participant API as "API控制器"
participant S as "案例服务"
participant M as "案例模型"
App->>API : GET /api/cases?id=xx&category_id=yy&page=1
API->>S : buildCasesListData(...)
S->>M : 查询案例
M-->>S : 返回数据
S-->>API : 组装结果
API-->>App : JSON 成功响应
模型与数据访问
- 前台案例模型:提供列表、详情、相关案例、推荐案例等查询方法
- 前台分类模型:提供树形与扁平化分类数据
- 后台模型:用于后台管理界面数据准备与操作
classDiagram
class CasesModel {
+related(catId, limit)
+lift(id, catId)
+...其他查询方法
}
class CasesCategoryModel {
+tree(catId)
+flat(excludeId)
}
class CasesService {
+buildCasesListData(...)
+buildCasesShowData(id)
+recordCasesView(id)
+findCategoryById(catId)
}
CasesService --> CasesModel : "使用"
CasesService --> CasesCategoryModel : "使用"
依赖关系分析
- 控制器对服务层的强依赖:所有业务逻辑集中在 Service,便于复用与测试
- 模型间解耦:前台与后台分别拥有独立模型,避免耦合
- 外部依赖:导航、面包屑、SEO、Schema、评论模块通过 Facade/Service 注入,保持松耦合
graph LR
AC["后台案例控制器"] --> AS["后台案例服务"]
CC["后台分类控制器"] --> CS["后台分类服务"]
FC["前台案例控制器"] --> FS["前台案例服务"]
AIC["API案例控制器"] --> FS
FS --> FM["前台案例模型"]
FS --> FCM["前台分类模型"]
性能与缓存
- 分页与归档:列表页默认分页大小可配置,归档按年月维度聚合,减少大表扫描
- 访问统计:详情页在读取后累加点击数,建议将写操作异步化以降低首屏延迟
- 分类树/扁平化:分类数据频繁读取,建议在服务层增加内存缓存或静态缓存键,降低重复查询
- 图片与媒体:案例详情中的图片建议使用懒加载与 CDN,结合缩略图策略提升首屏速度
- 评论模块:按需加载,避免阻塞主流程
故障排查指南
- 非法 ID:编辑/删除时若 ID 无效,会抛出领域异常并返回上一页,检查路由参数与权限
- 页面不存在:当分类或案例未找到时,抛出“页面错误”异常并返回首页,确认路由映射与数据是否存在
- 表单校验失败:由 CasesFormRequest/CategoryFormRequest 统一拦截,检查字段白名单与规则
- 批量操作失败:检查 action 方法的参数与权限,确认后端是否返回预期结果
结论
案例管理模块以清晰的分层架构实现了后台管理、前台展示与 API 的统一能力。通过服务层抽象与模型解耦,既保证了功能完整性,又具备良好的可扩展性。结合 SEO、评论、导航与分页归档,提供了完善的用户体验与运维能力。
附录:API参考与使用示例
后台管理接口(Web 表单)
- 案例列表:GET /admin/cases?category_id=&keyword=&page=
- 说明:按分类、关键词、页码筛选,返回分页数据与分类树
- 参考路径:admin/controller/cases/CasesController.php:65-84
- 新增案例:POST /admin/cases/create
- 说明:提交表单数据,支持草稿 token,成功后跳转到编辑页
- 参考路径:admin/controller/cases/CasesController.php:125-135
- 编辑案例:GET /admin/cases/edit?id=
- 说明:加载案例信息与多语言按钮配置
- 参考路径:admin/controller/cases/CasesController.php:143-167
- 更新案例:POST /admin/cases/update
- 说明:校验通过后更新并重定向
- 参考路径:admin/controller/cases/CasesController.php:180-186
- 删除案例:POST /admin/cases/destroy?id=
- 说明:删除单条案例,返回统一删除结果
- 参考路径:admin/controller/cases/CasesController.php:195-203
- 批量操作:POST /admin/cases/action
- 说明:批量修改状态等操作
- 参考路径:admin/controller/cases/CasesController.php:212-217
前台展示接口(Web 页面)
- 案例列表:GET /cases/category/{category_slug}?page=
- 说明:支持分类、归档、分页;返回导航、面包屑、SEO 与相关案例
- 参考路径:front/controller/cases/CasesController.php:84-150
- 案例详情:GET /cases/detail/{id}
- 说明:记录点击、加载评论、生成 Schema 与 SEO 信息
- 参考路径:front/controller/cases/CasesController.php:158-234
API 接口(JSON)
- 案例列表:GET /api/cases?id=&category_id=&category_slug=&year=&month=&page=
- 说明:返回标题、分类信息、案例列表与分类树
- 参考路径:api/controller/cases/CasesController.php:56-98
- 案例详情:GET /api/cases?id=&category_slug=&slug=&page=
- 说明:返回案例详情、自定义字段与评论分页
- 参考路径:api/controller/cases/CasesController.php:106-130
代码级调用示例(路径引用)
- 创建案例(后台):
- 参考路径:admin/controller/cases/CasesController.php:125-135
- 获取案例详情(前台):
- 参考路径:front/controller/cases/CasesController.php:158-234
- 筛选案例列表(前台/API):
- 参考路径:front/controller/cases/CasesController.php:84-150
- 参考路径:api/controller/cases/CasesController.php:56-98
[以上示例均为路径引用,不包含具体代码内容]