TanzCMS开源CMS系统

列表分页

TanzCMS 官方文档示例,展示模板标签、开放 API、内容管理和部署说明。

更新:2026-05-31 02:44:13 浏览:4

前台列表搜索筛选分页规范

本文记录前台、会员中心和插件前台列表类页面的统一查询规范。目标是让搜索、筛选和分页从一开始就按同一套边界实现,避免每个页面慢了以后再专项补丁。

一、适用范围

适用于以下页面:

  • 前台首页内容区、栏目页、列表页、搜索页、标签页、归档页。
  • 会员中心列表,例如投稿、订单、收藏、资产流水。
  • 插件前台列表,例如订单查询、充值记录、下载记录。
  • 后台列表另有后台 CRUD 和后台性能规范,但索引、分页和搜索原则保持一致。

不适用于:

  • 详情页正文读取。
  • 后台编辑页完整表单数据。
  • 导入、迁移、索引重建、批处理命令。

二、基本原则

列表页默认只查当前页需要展示的轻字段,不默认读取正文、大 JSON、大附件列表或完整模型扩展数据。需要详情数据时进入详情页或显式批量读取当前页数据。

搜索和筛选必须先明确作用域:

  • 内容模型列表走 ContentQuerycontent_search_idxcontent_field_idx
  • 会员自身列表先限定 member_idseller_member_id 或当前会员可见范围。
  • 插件业务列表优先使用插件自身快照字段和业务索引,不为了显示内容标题而回查核心内容表。

能用索引表达的条件必须走索引。缺字段索引、缺搜索索引、缺业务索引时,处理方式是补迁移、重建索引或修复测试数据,不在业务代码里退回全表模糊查询。

三、搜索规范

内容搜索:

  • 标题、摘要、关键词、正文摘要走 content_search_idx
  • 中文模糊搜索优先使用已验证的 FULLTEXT ngram 单列组合索引。
  • ID、slug、订单号、手机号、邮箱等精确模式走 BTree 或业务专用索引。
  • 搜索参数不得传 SQL 片段,只能传声明式参数。
  • 前台搜索结果数量以 content_search_idx 为准,不直接以 content_itemsLIKE 结果作为页面结果。线上排查“原表有 15 条、搜索页只有 5 条”时,必须同时检查 content_search_idx 是否同步;索引不一致时先执行 tanzcms:search-rebuild,不要把所有差异都归因到页面缓存。
  • 中文关键词如“合击”应走可控的 LIKE/索引搜索路径,避免被 MySQL 全文分词差异截断。修改搜索逻辑后,必须用原表计数、搜索索引计数和前台页面结果三者对照。

搜索与筛选边界:

  • 搜索框提交的是关键词搜索,例如 /search/合击.html 表示标题或指定搜索字段包含“合击”。
  • 筛选按钮提交的是字段筛选,例如 /search?version_type=392 表示“版本类型字段等于合击”。
  • 两者不是同一个条件。筛选按钮不应默认继承当前搜索关键词,否则会变成“标题包含合击 AND 版本类型等于合击”,导致结果看起来被错误缩小。
  • 官方 xin001 这类筛选区应只保留筛选项之间的联动参数,如 buy_typeengineversion_type;不要在筛选链接里写 keyword=$keyword,除非需求明确要求组合搜索。

会员中心订单搜索:

  • 会员订单页已经限定当前买家或卖家,不走全站内容搜索。
  • 订单号类关键词走 order_no/payment_order_no 前缀匹配。
  • 普通关键词在当前会员范围内匹配订单快照 subject/order_no/payment_order_no
  • 不在会员中心订单列表里 join 正文表或核心内容表补搜索条件。

会员投稿搜索:

  • 当前阶段会员投稿页没有搜索框,默认只验收分页。
  • 后续如新增投稿搜索,应先限定当前会员,再按标题前缀、状态、栏目等索引字段筛选。
  • 需要搜索正文时应另建搜索索引或进入内容搜索体系,不直接扫 member_post_data

四、筛选规范

内容字段筛选:

  • 字段必须在模型字段中声明可筛选,并写入 content_field_idx
  • 多字段组合筛选由查询服务解析字段元数据后生成索引查询。
  • 未命中字段索引定义时直接报结构问题,不 join 模型数据表兜底。
  • 高频稳定字段可以进入热字段升级候选,但必须走 IndexAdvisor、DDL 预览、审计和 EXPLAIN ANALYZE 验收。

业务表筛选:

  • 会员、订单、资产、充值、下载等插件业务表应按真实业务查询建立组合索引。
  • 列表筛选应尽量使用状态、会员、时间、订单号、业务类型这类低成本字段。
  • 任意文本模糊筛选必须先限定可控范围,例如当前会员、当前商家、当前时间窗口。

五、分页规范

普通列表第一页可以使用精确总数。第一页返回数量小于每页数量时,可以直接判定总数,避免额外 COUNT(*)

深分页按页面类型处理:

  • 后台管理列表:优先优化,不轻易拦截用户;使用轻字段、覆盖索引、降序索引和延迟关联。
  • 前台栏目、标签、归档:属于有限参数空间,可保留较深页,配合缓存、sitemap、noindex 或软限制。
  • 前台搜索、组合筛选、任意参数页:属于无限参数空间,必须有预算、缓存、告警或限制。
  • RSS、API、批量接口:优先使用游标、时间范围或 ID 边界。
  • 会员中心列表:先限定当前会员或卖家,再按 member_id,idseller_member_id,id 等复合索引分页。

大表深分页推荐模式:

  1. 用覆盖索引按当前筛选条件取当前页 ID。
  2. 再按 ID 读取当前页展示字段。
  3. 按 ID 结果恢复排序。

这适用于后台内容列表、会员订单、会员投稿等“当前页展示字段多于索引字段”的场景。

首页、栏目页和搜索页可以用懒加载改善首屏和滚动体验,但分页口径与每次加载数量要分开:

  • pagesize 决定分页总页数和 {$pages}
  • limitnum 决定单次查询返回多少条。
  • chunk 可用于同一页内分批加载,例如首页按 pagesize=300 计算分页,但首屏 limit=50,下拉时继续请求 chunk=2、3... 每批 50 条。
  • 这种场景仍然请求完整页面模板,由前端从完整页面里取 data-infinite-list,不要为了每批 50 条新建 rows 片段模板。

六、rows 片段边界

fragment=rowslist_rows.htmlsearch_rows.html 这类片段不是主题必备项,也不是性能验收默认项。

默认规则:不要新增 rows 片段。首页、栏目页、列表页和搜索页本身已经能通过 {content}{search}pagepagesizechunk 和主题 JS 完成分页、筛选和懒加载。

只有用户明确要求“单独的局部片段接口”或插件明确需要局部刷新端点时,才允许设计 fragment=rows。默认主题不保留 index_rows.htmllist_rows.htmlsearch_rows.htmlpartials/*_rows.html 这类历史片段;不能因为懒加载、无限滚动或性能担忧,就主动新增 rows 模板或控制器里的 rows 分支。

默认性能探针不请求 rows 片段,避免把一个未启用的交互当成性能问题。主题没有 rows 片段时,不应因为探针访问 fragment=rows 而被判失败。

不允许的做法:

  • HomeControllerCategoryControllerSearchController 中为单个主题硬编码 fragment=rows 分支。
  • 在主题里新增 *_rows.html 后再让完整页面依赖它。
  • 为了少传头尾而绕过正常模板渲染、栏目模板配置或权限边界。
  • 把 rows 片段缺失当作线上性能、缓存或模板错误。

如果主题启用了 rows 片段,则该片段应:

  • 只输出当前页行内容,不输出完整头尾和整页布局。
  • 默认不做精确总数统计,除非交互确实需要。
  • 使用与完整页面一致的查询参数和权限边界。
  • 由主题自身或交互功能提供测试,不作为所有主题的通用必测项。

上线排查时要区分这些缓存和索引:

  • 页面响应头 X-TanzCMS-Page-Cache: HIT/MISS 只说明页面响应缓存是否命中。
  • 模板源文件已更新但页面仍输出旧 HTML 时,检查 storage/framework/tanzcms/templatestemplate-tagstemplate-controlstemplate-expressions,并考虑 PHP-FPM OPcache。
  • 搜索结果数量不对时,先对照 content_itemscontent_search_idx,必要时重建搜索索引;字段筛选结果不对时,对照 content_field_idx,必要时重建字段索引。
  • 后台“清所有缓存”不能替代 PHP-FPM/OPcache 重启,也不能修复未同步的搜索索引。

目标站点排查时,应先核对模板源文件、搜索索引、字段索引和模板缓存。需要执行命令时,应在目标站点根目录使用当前站点实际 PHP CLI,并按站点实际主题名、模型和关键词调整参数。不要把示例路径或服务管理命令照搬到不同服务器。

七、验收方式

默认前台性能验收覆盖:

  • 首页。
  • 栏目第一页和栏目深分页。
  • 搜索页。
  • 搜索 + 筛选组合页。
  • 详情页。
  • 会员登录、注册、会员中心。
  • 会员投稿列表和深分页。
  • 会员订单列表、深分页、搜索。
  • 插件前台关键页面。

rows 片段、特殊筛选页、特殊插件页面只在功能启用时加入专项探针。

验收时可使用:

php artisan tanzcms:frontend-hotpath-probe --json
php artisan tanzcms:performance-baseline --after-id=日志ID --fail-on-warning
php artisan tanzcms:performance-assert --after-id=日志ID --min-samples=1

验收结论必须基于真实日志、真实 SQL 和实际响应大小,不使用“估计、预估、大概”作为性能判断。