文档目录
文章管理页面

简介

本文面向 DouPHP 小程序“文章管理页面”的开发与维护,覆盖文章列表页的分类展示、搜索过滤、分页加载,以及文章详情页的富文本渲染、图片处理、分享功能。文档同时给出数据结构设计、缓存与性能优化方案、SEO 实现要点、移动端兼容性建议与常见问题解决方案,帮助开发者快速落地并持续优化。

项目结构

围绕文章能力的前后端关键位置如下:

  • 前端控制器与服务:负责路由解析、分页、分类筛选、归档、详情构建、点击统计、SEO 注入等。
  • 模型层:文章与分类的数据访问、关联查询、格式化(附件 URL、时间、自定义属性)与多语言支持。
  • 小程序端:文章详情页通过 mp-html 组件渲染富文本内容,使用 http 服务获取数据,配置分享标题。
  • SEO:结构化数据与页面元信息生成。
graph TB
subgraph "小程序端"
MP_TS["article.ts"]
MP_WXML["article.wxml"]
MP_HTML["mp-html 组件"]
end
subgraph "Web 前台"
CTRL["ArticleController"]
SVC["ArticleService"]
MODEL_A["Article 模型"]
MODEL_C["ArticleCategory 模型"]
SEO["SchemaService"]
end
MP_TS --> |"HTTP 请求"| CTRL
MP_WXML --> MP_HTML
CTRL --> SVC
SVC --> MODEL_A
SVC --> MODEL_C
CTRL --> SEO

核心组件

  • 文章控制器(ArticleController)
    • 列表/分类/归档:解析路由参数、分页、构建分类信息与面包屑、SEO 元信息、返回视图数据。
    • 详情:校验 ID、构建详情数据、记录点击量、组装评论(可选)、输出 Schema 与视图数据。
  • 文章服务(ArticleService)
    • 列表数据:按分类、归档、默认排序进行分页,构造精简列表项(含 URL、分类信息、摘要截断)。
    • 详情数据:查找已发布文章,将内容经 Markdown 渲染器转换为 HTML。
    • 分类查询与点击统计:提供分类单行与点击量自增。
  • 文章模型(Article / ArticleCategory)
    • 列表读取走 AR:with('category') 批量取分类;casts 格式化 image/defined/created_at;prefetchers 预热 url/多语言/附件;translatable 覆写 title/content/description/keywords 当前语言值。
    • 列表 Presenter 字段(url/name/description/cate_info/add_time_short/time)由 concerns trait 经 accessor + $appends 承接。
  • 小程序文章详情页
    • 通过 http 调用 article.show 接口,设置页面标题与分享标题,使用 mp-html 渲染富文本内容。
  • SEO 结构化数据
    • 为文章页生成 Article 类型 JSON-LD,包含标题、封面、发布时间、作者、发布者、主页面等信息。

架构总览

下图展示了从小程序到 Web 前台再到模型与 SEO 的完整调用链。

sequenceDiagram
participant MP as "小程序 article.ts"
participant CTRL as "ArticleController"
participant SVC as "ArticleService"
participant MOD as "Article/ArticleCategory"
participant SEO as "SchemaService"
MP->>CTRL : GET /article/show?id=...
CTRL->>SVC : buildArticleShowData(id)
SVC->>MOD : findPublishedById(id)
MOD-->>SVC : 文章实体
SVC->>SVC : 内容转HTML(MarkdownRenderer)
SVC-->>CTRL : 文章数据
CTRL->>SVC : recordArticleView(id)
CTRL->>SEO : article(article, cateInfo)
SEO-->>CTRL : JSON-LD
CTRL-->>MP : {article, defined}
MP->>MP : 设置分享标题

详细组件分析

文章列表页(分类/归档/分页)

  • 分类与归档
    • 通过路由参数解析分类 ID 与日期归档(年/月),归档时强制全部分类语境。
    • 构建分类树与面包屑,用于导航与 SEO。
  • 分页
    • 每页条数来自配置,默认 10;分页 URL 根据是否归档动态生成。
  • 列表数据
    • 批量预加载分类,格式化附件、时间、自定义属性;摘要截断;附加分类 URL 与名称。
  • 搜索过滤
    • 侧栏搜索框回填全站搜索关键词 q(需通过安全校验),实际检索逻辑由全局搜索模块承担;列表页仅做回填与上下文传递。
flowchart TD
Start(["进入列表页"]) --> Parse["解析路由参数<br/>分类ID/年/月/页码"]
Parse --> Archive{"是否归档?"}
Archive --> |是| SetCat["设置分类为全部分类"]
Archive --> |否| KeepCat["保持原分类"]
SetCat --> Query["查询文章列表<br/>with(category)+分页"]
KeepCat --> Query
Query --> BuildList["构造列表项<br/>URL/摘要/分类信息"]
BuildList --> Render["渲染视图/分页/面包屑/SEO"]
Render --> End(["完成"])

文章详情页(富文本/图片/分享)

  • 数据获取
    • 控制器校验 ID,服务层查找已发布文章并渲染内容为 HTML。
    • 记录点击量,生成 SEO 结构化数据。
  • 富文本渲染
    • 小程序端使用 mp-html 组件渲染 article.content 的 HTML。
    • 若需要自定义样式或安全过滤,可在 mp-html 组件中扩展。
  • 图片处理
    • 图片资源以附件形式存储,模型 casts 会将其转为可用 URL;建议在 mp-html 中启用懒加载与尺寸适配。
  • 分享
    • 页面 onLoad 时设置分享标题为文章标题;onShareAppMessage 返回标题。
sequenceDiagram
participant MP as "小程序 article.ts"
participant WXML as "article.wxml"
participant HTML as "mp-html"
participant CTRL as "ArticleController"
participant SVC as "ArticleService"
MP->>CTRL : GET /article/show?id=...
CTRL->>SVC : buildArticleShowData(id)
SVC-->>CTRL : {title,content,...}
CTRL-->>MP : {article, defined}
MP->>WXML : 绑定 article.title/content
WXML->>HTML : content="{{article.content}}"
HTML-->>WXML : 渲染富文本
MP->>MP : onShareAppMessage(title)

文章数据模型与字段

  • 文章模型(Article)
    • 表名:article
    • 列表格式化:image→附件URL、defined→键值对、created_at→Y-m-d
    • 附加字段:add_time_short、time、name、description、url、favorites、cate_info
    • 多语言字段:title、content、description、keywords(随当前语言覆写)
  • 分类模型(ArticleCategory)
    • 提供 tree() 等方法用于构建分类树与导航。
  • 列表项字段(Presenter)
    • id、category_id、title、defined、image、created_at、add_time_short、time、click、description、url、cate_info(category_id/name/url)
classDiagram
class Article {
+int category_id
+int click
+attachment image
+defined defined_pairs
+datetime created_at
+string[] translatable
+string[] appends
+published()
+filterByCategory(catId)
+filterByArchive(archive)
+applyDefaultOrder()
+paginate(pageSize, page, url)
}
class ArticleCategory {
+tree(catId)
+whereKey(id)
}
Article --> ArticleCategory : "with('category')"

SEO 与结构化数据

  • 页面标题、关键词、描述由 SeoResolver 基于分类与文章内容生成。
  • 文章页注入 Article 类型 JSON-LD,包含 headline、image、datePublished、author、publisher、mainEntityOfPage 等。

依赖关系分析

  • 控制器依赖服务与 SEO 组件,服务依赖模型与 Markdown 渲染器。
  • 小程序依赖 http 服务与 mp-html 组件。
  • 模型依赖 ORM、附件系统、多语言与时间格式化。
graph LR
MP_TS["article.ts"] --> HTTP["http 服务"]
MP_WXML["article.wxml"] --> MPHTML["mp-html 组件"]
CTRL["ArticleController"] --> SVC["ArticleService"]
SVC --> MODEL_A["Article"]
SVC --> MODEL_C["ArticleCategory"]
CTRL --> SEO["SchemaService"]

性能与缓存策略

  • 列表性能
    • 使用 with('category') 批量加载分类,避免 N+1 查询。
    • 分页限制返回条数,摘要截断减少传输体积。
    • 附件 URL 在模型层统一转换,避免重复计算。
  • 图片优化
    • 建议使用 mp-html 的图片懒加载与自适应尺寸;服务端可结合云存储或 CDN 提供缩略图与压缩版本。
  • 内容预加载
    • 列表页可预取下一页首条文章的关键字段(id/title/image),提升跳转体验。
  • 离线缓存
    • 列表数据可使用本地存储短期缓存(如最近浏览的分类列表),结合版本号或时间戳控制失效。
  • 富文本渲染
    • 将内容在服务端渲染为 HTML 后下发,减少小程序端解析开销;必要时在 mp-html 中启用增量渲染。
  • 点击统计
    • 详情页在控制器中异步更新点击量,避免阻塞渲染。

用户体验设计

  • 阅读进度保存
    • 在小程序端监听滚动事件,将当前滚动位置写入本地存储;返回时恢复进度。
  • 字体大小调整
    • 提供字体大小设置,持久化至本地存储;在 mp-html 中通过 CSS 变量或样式类切换。
  • 夜间模式
    • 通过主题切换改变背景与文字颜色;mp-html 支持自定义样式,可注入夜间主题。
  • 分享体验
    • 设置合理的分享标题与封面图;确保分享卡片信息准确。

常见问题与排错

  • 大文件图片优化
    • 问题:大图导致加载慢、内存占用高。
    • 解决:服务端压缩与裁剪;小程序端懒加载;CDN 加速;按需加载缩略图。
  • 富文本安全过滤
    • 问题:XSS 风险。
    • 解决:服务端对内容进行白名单过滤;mp-html 启用安全模式;避免执行脚本。
  • 移动端兼容性
    • 问题:不同机型渲染差异。
    • 解决:使用响应式布局;测试主流设备;在 mp-html 中适配样式。
  • 列表分页异常
    • 问题:页码错误或数据为空。
    • 解决:检查路由参数与分页配置;确认分类与归档条件;查看日志定位。
  • 分享标题为空
    • 问题:分享标题未设置。
    • 解决:确保 onLoad 时正确设置 wx.setStorageSync('shareTitle');检查 API 返回字段。

结论

DouPHP 的文章模块在前端控制器、服务层与模型层形成了清晰的职责划分:控制器负责路由与视图数据组装,服务层专注业务逻辑与数据格式化,模型层提供高效的数据访问与多语言支持。小程序端通过 mp-html 渲染富文本,配合 http 服务与分享机制,提供了良好的阅读与传播体验。结合本文的性能优化与用户体验建议,可进一步提升文章页面的加载速度、可读性与可维护性。

附录:数据模型与字段说明

  • 文章字段
    • id:主键
    • category_id:分类 ID
    • title:标题(多语言)
    • content:内容(Markdown,服务端转 HTML)
    • description:描述(多语言,用于 SEO 与摘要)
    • keywords:关键词(多语言,用于 SEO)
    • image:封面图(附件 URL)
    • defined:自定义属性(键值对)
    • created_at:创建时间(格式化)
    • click:点击量
  • 列表项字段(Presenter)
    • add_time_short:短显示时间
    • time:时间标签
    • name:文章名称(可能为别名或标题)
    • url:详情页链接
    • cate_info:分类信息(category_id/name/url)
  • 分类字段
    • name:分类名称(多语言)
    • keywords:分类关键词(多语言)
    • description:分类描述(多语言)
    • parent_id:父分类 ID
添加日期:2026-10-05