文档目录
常见问题系统

简介

本文件面向开发者,系统化说明 DouPHP 常见问题(FAQ)模块的技术实现与扩展方式。内容覆盖分类管理、问题编辑、答案发布、搜索查询、SEO 优化、展示逻辑、缓存机制、导入导出、批量操作与版本管理等高级能力,并提供可操作的扩展指引,帮助快速定制字段、集成富文本编辑器、实现多语言支持等。

项目结构

FAQ 模块遵循前后端分离的控制器-服务-模型分层组织:

  • 后台入口:admin/controller/faq/FaqController.php
  • 前台入口:front/controller/faq/FaqController.php
  • 业务服务:admin/service/faq/FaqService.php、front/service/faq/FaqService.php
  • 数据模型:admin/model/faq/FaqModel.php、front/model/faq/FaqModel.php
  • 表单校验:admin/request/faq/FaqFormRequest.php
  • 路由:admin/route/faq.php、front/route/faq.php
  • 模板:theme/default/faq.dwt
  • 多语言:languages/zh_cn/lang.php
graph TB
subgraph "后台"
AC["Admin FaqController"]
ASvc["Admin FaqService"]
AModel["Admin FaqModel"]
AReq["FaqFormRequest"]
end
subgraph "前台"
FC["Front FaqController"]
FSvc["Front FaqService"]
FModel["Front FaqModel"]
end
subgraph "公共"
Tpl["faq.dwt"]
Lang["lang.php"]
end
AC --> ASvc
ASvc --> AModel
AC --> AReq
FC --> FSvc
FSvc --> FModel
FC --> Tpl
AC --> Lang
FC --> Lang

核心组件

  • 后台控制器:负责列表、新增、编辑、删除、批量操作等页面渲染与请求处理,调用服务层完成业务。
  • 前台控制器:负责 FAQ 列表页渲染、分类过滤、分页、面包屑与 SEO 信息注入。
  • 服务层:封装分类树构建、问题列表组装、搜索过滤、状态管理、SEO 相关数据准备等。
  • 模型层:提供数据库访问、条件查询、分页、统计等基础能力。
  • 表单校验:集中定义字段白名单与规则,统一在控制器中通过 Request 注入使用。
  • 模板与语言:主题模板渲染页面,语言包提供文案。

架构总览

FAQ 模块采用“控制器-服务-模型”三层架构,配合路由与模板完成端到端流程。后台侧重管理与批量操作,前台侧重展示与 SEO。

sequenceDiagram
participant U as "用户"
participant AR as "后台路由"
participant AC as "后台控制器"
participant AS as "后台服务"
participant AM as "后台模型"
participant FR as "前台路由"
participant FC as "前台控制器"
participant FS as "前台服务"
participant FM as "前台模型"
participant T as "模板"
U->>AR : 访问后台FAQ列表
AR->>AC : index()
AC->>AS : buildFaqListData(class, keyword, page)
AS->>AM : 查询分类/问题/分页
AM-->>AS : 数据集合
AS-->>AC : 视图数据
AC->>T : 渲染faq.htm
U->>FR : 访问前台FAQ列表
FR->>FC : index()
FC->>FS : buildFaqListData(class, page)
FS->>FM : 查询分类/问题/分页
FM-->>FS : 数据集合
FS-->>FC : 视图数据
FC->>T : 渲染faq.dwt

详细组件分析

后台控制器:FAQ 管理

  • 列表:接收 class、keyword、page,调用服务层构建列表数据并渲染。
  • 新增/编辑:加载默认或已有数据,渲染表单;提交时由表单校验器验证后交由服务层持久化。
  • 删除:参数校验后调用服务层执行删除。
  • 批量操作:接收批量动作参数,调用服务层统一处理。
flowchart TD
Start(["进入后台FAQ"]) --> List["列表页<br/>index()"]
List --> |筛选| BuildList["buildFaqListData()"]
BuildList --> RenderList["渲染faq.htm"]
List --> Create["新增<br/>create()/store()"]
Create --> Validate["FaqFormRequest 校验"]
Validate --> Save["insert()"]
Save --> Redirect["重定向到编辑页"]
List --> Edit["编辑<br/>edit()/update()"]
Edit --> Validate
Validate --> Update["update()"]
Update --> Redirect
List --> Delete["删除<br/>destroy()"]
Delete --> DelSvc["delete()"]
List --> Batch["批量<br/>action()"]
Batch --> BatchSvc["action()"]

前台控制器:FAQ 展示

  • 列表:解析路由参数 class 与 page,调用服务层构建列表数据,注入面包屑与 SEO 信息,渲染模板。
  • 布局变量:注入关键词、描述、导航菜单等全局信息。
sequenceDiagram
participant C as "浏览器"
participant R as "前台路由"
participant FC as "前台控制器"
participant FS as "前台服务"
participant FM as "前台模型"
participant V as "模板"
C->>R : GET /faq?class=xxx&page=1
R->>FC : index()
FC->>FS : buildFaqListData(class, page)
FS->>FM : 查询分类/问题/分页
FM-->>FS : 数据
FS-->>FC : 视图数据
FC->>V : 渲染faq.dwt

服务层:业务逻辑与状态管理

  • 分类树形结构:按层级组织分类,便于前端侧边栏与筛选。
  • 问题列表与搜索:支持按分类、关键词、分页组合查询。
  • 状态管理:维护问题的可见性、置顶、推荐等状态流转。
  • SEO 数据:为前台页面生成标题、关键词、描述等元信息。
  • 批量操作:支持启用/禁用、删除、置顶等批量动作。
classDiagram
class AdminFaqService {
+buildFaqListData(class, keyword, page) array
+buildFaqDefaultData() array
+buildFaqEditData(id) array
+insert(data) int
+update(data) bool
+delete(id, post) array
+action(post) array
}
class FrontFaqService {
+buildFaqListData(class, page) array
}
class AdminFaqModel {
+listByClass(class) array
+search(keyword) array
+paginate(page) array
}
class FrontFaqModel {
+listByClass(class) array
+search(keyword) array
+paginate(page) array
}
AdminFaqService --> AdminFaqModel : "读写数据"
FrontFaqService --> FrontFaqModel : "读取数据"

模型层:数据访问与查询

  • 分类树:递归或层级查询,返回可用于前端渲染的树形结构。
  • 列表与搜索:支持按分类、关键词、状态、时间范围等条件组合查询。
  • 分页:统一的分页接口,返回数据集与分页信息。
  • 统计:可选的计数与聚合,用于列表摘要或仪表盘。

表单校验:安全与一致性

  • 白名单与规则:集中定义字段类型、长度、必填等规则。
  • 场景绑定:按方法名自动绑定 scene,确保新增与更新规则一致。
  • 错误处理:校验失败抛出领域异常,由统一入口捕获并提示。

路由与模板

  • 后台路由:将 URL 映射到控制器方法,支持列表、新增、编辑、删除、批量操作。
  • 前台路由:将 FAQ 列表与分类页映射到控制器方法。
  • 模板:faq.dwt 负责渲染分类、问题列表、分页与 SEO 信息。

依赖关系分析

  • 控制器依赖服务层,服务层依赖模型层,形成清晰的单向依赖。
  • 前台控制器依赖导航、面包屑与 SEO 解析器,增强页面体验与搜索引擎友好度。
  • 表单校验器作为横切关注点,被控制器按需注入。
graph LR
AC["Admin FaqController"] --> ASvc["Admin FaqService"]
FC["Front FaqController"] --> FSvc["Front FaqService"]
ASvc --> AModel["Admin FaqModel"]
FSvc --> FModel["Front FaqModel"]
FC --> Nav["NavigationBuilder"]
FC --> Breadcrumb["BreadcrumbBuilder"]
FC --> Seo["SeoResolver"]
AC --> AReq["FaqFormRequest"]

性能与缓存

  • 列表查询优化:
    • 使用索引字段进行筛选(如分类 ID、状态、更新时间)。
    • 分页限制返回条数,避免全表扫描。
    • 关键词搜索结合全文索引或分词库提升匹配效率。
  • 分类树缓存:
    • 分类结构变化不频繁,可在服务层引入缓存键(如 faq_category_tree),设置合理过期策略。
  • 页面级缓存:
    • 对静态或低频更新的 FAQ 列表页启用页面缓存,减少重复计算。
  • 资源压缩与懒加载:
    • 模板中图片与脚本按需加载,减少首屏体积。
  • 监控与日志:
    • 记录慢查询与异常,定位性能瓶颈。

故障排查指南

  • 非法字符校验失败:
    • 前台路由参数包含非法字符会抛出领域异常,检查输入过滤逻辑。
  • 表单校验失败:
    • 查看 FaqFormRequest 的规则定义,确认字段类型与必填项。
  • 数据不存在:
    • 编辑或删除时若 ID 无效或服务层返回空,需检查路由参数与权限。
  • 批量操作失败:
    • 检查传入的动作与 ID 列表格式,确认服务层 action 方法实现。

结论

FAQ 模块以清晰的分层架构实现分类管理、问题编辑、答案发布、搜索查询与 SEO 优化。通过服务层封装业务逻辑、模型层专注数据访问、控制器负责请求与响应,配合表单校验与模板渲染,提供了稳定可扩展的基础能力。建议在高频查询处引入缓存与索引,持续优化性能与用户体验。

附录:开发示例与扩展方案

自定义 FAQ 字段

  • 在表单校验器中添加新字段规则,确保类型与长度符合预期。
  • 在服务层的 insert/update 方法中处理新字段的写入与回显。
  • 在模板中渲染新字段,并在列表与详情页展示。

集成富文本编辑器

  • 在表单模板中嵌入富文本编辑器组件,确保提交时正确序列化 HTML。
  • 在服务层保存前进行内容清洗与安全检查,防止 XSS。
  • 在前台模板中安全渲染富文本内容。

实现多语言支持

  • 在语言包中添加 FAQ 相关文案键值。
  • 在控制器与模板中使用语言函数获取对应文案。
  • 根据当前语言环境动态切换显示内容。

搜索算法与查询优化

  • 关键词搜索:
    • 使用 LIKE 或全文索引进行模糊匹配,结合分词提升准确率。
    • 对高频搜索词建立缓存,减少重复查询。
  • 分类筛选:
    • 基于分类 ID 进行精确匹配,利用索引加速。
  • 分页与排序:
    • 按更新时间或热度排序,结合分页减少数据传输量。

导入导出与批量操作

  • 导入:
    • 提供 CSV/Excel 模板,服务端解析并批量插入,记录失败行与原因。
  • 导出:
    • 按分类、状态、时间范围导出数据,支持分页流式输出。
  • 批量操作:
    • 支持启用/禁用、删除、置顶等动作,事务保证一致性。

版本管理与审计

  • 版本控制:
    • 每次更新创建新版本记录,保留历史快照,支持回滚。
  • 审计日志:
    • 记录操作人、时间、变更字段,便于追踪与合规。

配置与路由

  • 后台路由:
    • 配置 FAQ 管理相关路由,确保控制器方法正确映射。
  • 前台路由:
    • 配置 FAQ 列表与分类页路由,支持分页与参数传递。
添加日期:2026-10-05