主题开发文档更新记录

2026-11-05

  • 校正最低运行版本为 Halo 2.26.0+,明确 Base、市场版 Base 与 Pro 能力边界。
  • 基础专栏、自定义评论区、支付订单导出归入 Base,不将自动续费字段当作上线能力。
  • 修复旧示例的错误 API 前缀、POST 访问检查、套餐 displayName、章节 locked 和分页返回形状。
  • 明确服务端正文过滤、签名评论凭证、公开内容可见性、用户缓存隔离和支付确认边界。
  • 主题文件不等于路由注册,示例区分自定义页面、原生页面和控制台 UC。
  • Finder 方法/组件属性/CSS 变量与 HTTP 合同提供可重复生成的维护流程。
  • 公开技能仓库支持 npx skills 安装、校验和通过 Halo MCP 同步文档。

历史记录

以下记录描述历史版本的变更,不覆盖本文档当前规范。涉及已变更的版本要求、组件参数或能力归属时,以当前指南与合同为准。

主题开发文档更新日志

2026-09-04 - Pro 静态资源与文章付费墙圆角

  • 明确 Base 使用 know-sphere.*,Pro 使用 know-sphere-pro.*,主题应通过 getPluginInfo() 获取资源 URL。
  • 新增 --ks-paywall-article-radius,默认继承 --ks-border-radius-lg,用于适配主题卡片圆角。
  • 定时开放组件改为无卡片布局,骨架内容前置,保留翻页时钟,并将开放时间改为普通文本。

2025-05-14 - 会员权益自动生成 & API 字段补充

变更内容

MembershipVo 新增字段

  • levelColor: 会员等级主题色(String,如 #3B82F6)
  • levelIcon: 会员等级图标(String,如 ri-vip-crown-line)
  • benefits: 权益列表(List<String>,自动生成 + 等级配置的权益合并)

MembershipPlanVo 新增字段

  • levelColor: 等级主题色
  • levelIcon: 等级图标
  • levelBenefits: 等级权益列表(来自关联等级的手动配置)
  • allBenefits: 完整权益列表(自动生成 + 等级权益 + 套餐权益合并去重)

权益自动生成逻辑

系统会根据等级的结构化字段自动生成权益描述:

  1. 根据 accessScope 生成内容访问描述(如"可访问全部付费内容"、"可访问 N 个专属分类内容")
  2. 统计该等级可解锁的会员专属内容数量(如"可解锁 15 篇会员专属内容")
  3. 根据 priority > 1 生成"包含所有低等级会员权益"
  4. 合并等级手动配置的权益

主题端使用建议

  • 展示套餐权益时,推荐使用 allBenefits 字段(已合并所有来源)
  • 展示会员状态权益时,使用 benefits 字段
  • 可通过 levelColor 和 levelIcon 实现等级视觉差异化

文档更新

  • 更新 finder-api-guide.md 中 getMembershipStatus() 和 listMembershipPlans() 的返回字段说明和示例
  • 更新 cheatsheet.md 中 MembershipVo / MembershipPlanVo 字段表和代码片段

2024-03-22 - 文档体系重构(v2.0.0)

背景

为让想自己开发主题的用户能快速上手,对主题开发文档进行了整体重构,新增了 4 份面向新手的实战文档,并重写了文档导航页。

新增文档

1. getting-started.md - 快速上手指南 ⭐

  • 从零开始、30 分钟跑通最小可用主题
  • 包含 6 步实操流程:引入资源 → 版本识别 → 付费文章页 → 用户中心 → 明暗模式 → 调试
  • 汇总 5 个最常见的开发坑位及解决方案
  • 提供可一键复制的 post.html 最小模板

2. theme-scaffold.md - 主题脚手架参考 ⭐

  • 推荐的完整主题目录结构
  • 可直接复制的 theme.yaml / layout.html / post.html / ks-membership.html / uc/dashboard.html / uc/checkin.html 示例
  • 核心的 ks-overrides.css 示例(主题色与明暗模式适配)
  • 上线前的测试清单

3. cheatsheet.md - 速查表 ⭐

  • 一页纸速查所有常用 Finder API 方法调用方式
  • 所有主要 VO 的字段表
  • HTTP API 端点速查(按 Public / UC / Console 分类)
  • 7 个 Lit 组件的属性、事件、CSS 变量
  • 所有 CSS 变量分类速查(全局 + 付费墙 + 签到 + 倒计时 + 评论区)
  • 9 个"一行搞定"的常用任务代码片段

4. faq.md - 常见问题 ⭐

  • 按主题分类:开发环境 / Finder API / Lit 组件 / 付费墙与权限 / 版本与 Feature Gate / 样式与暗黑模式 / 性能 / 支付流程 / 调试技巧 / 兼容性
  • 每个问题都有明确的解决方案与代码示例

修订

  • README.md 完全重写,按「场景驱动」方式重新组织导航
  • 补充 Plugin Info API 在所有相关文档中的介绍
  • 更新 Halo 最低版本要求到 2.24.0
  • 明确 Base / Pro feature gate 的 14 + 7 个功能列表

文档结构变化

重构前:

README · api-guide · api-permissions-guide · base-theme-guide
· finder-api-guide · pro-theme-guide · theme-homepage-*
· theme-integration-guide · theme-pages-guide

重构后:

快速入门: getting-started · theme-scaffold · cheatsheet · faq
深度集成: theme-integration-guide · theme-pages-guide · base/pro-theme-guide
API 参考: api-guide · finder-api-guide · api-permissions-guide
首页设计: theme-homepage-*

2024-03-16 - 重大修正

修正内容

1. Finder API 方法签名修正

所有 Finder API 方法已按照后端实际实现进行修正:

  • checkAccess() - 返回 AccessCheckVo,包含完整的访问控制信息
  • getMembershipStatus() - 返回 MembershipVo,包含会员等级和有效期信息
  • listMembershipPlans() - 返回 MembershipPlanVo 列表
  • listMyOrders() - 返回 OrderVo 列表,包含订单详细信息
  • listMyPurchases() - 返回 UserAccessVo 列表
  • listColumns() - 返回 ColumnVo 列表
  • getColumnDetail() - 返回 ColumnDetailVo,包含章节和进度信息
  • getUserProgress() - 返回 UserProgressVo
  • getDripStatus() - 返回 UserDripStatusVo
  • getDistributorProfile() - 返回 DistributorVo
  • getDistributorStatistics() - 返回 DistributionStatisticsVo
  • getRatingStatistics() - 返回 RatingStatisticsVo
  • getCommentRewardStatistics() - 返回 RewardStatisticsVo

2. VO 字段名修正

所有 VO 类的字段名已与 Java 后端定义完全一致:

AccessCheckVo:

  • hasAccess (boolean) - 是否有访问权限
  • accessType (String) - 访问类型
  • requirePayment (boolean) - 是否需要付费
  • price (BigDecimal) - 价格
  • previewRatio (Integer) - 试看比例
  • previewLength (Integer) - 试看字数
  • validDays (Integer) - 有效天数
  • scheduledAccessAt (Instant) - 定时访问时间
  • resolvedTargetType (String) - 命中的规则目标类型
  • resolvedTargetName (String) - 命中的规则目标名称
  • purchaseTargetType (String) - 下单目标类型
  • purchaseTargetName (String) - 下单目标名称

MembershipVo:

  • active (boolean) - 是否为会员
  • levelName (String) - 会员等级名称
  • levelDisplayName (String) - 会员等级显示名称
  • levelPriority (Integer) - 会员等级优先级
  • planName (String) - 套餐名称
  • startAt (Instant) - 开始时间
  • expireAt (Instant) - 过期时间
  • remainingDays (Integer) - 剩余天数,-1表示永久
  • autoRenew (Boolean) - 是否自动续费

ColumnVo:

  • name (String) - 专栏名称(metadata.name)
  • displayName (String) - 专栏显示名称
  • description (String) - 专栏简介
  • cover (String) - 封面图
  • categoryName (String) - 关联分类名称
  • authorUsername (String) - 作者用户名
  • price (BigDecimal) - 专栏价格
  • originalPrice (BigDecimal) - 原价
  • allowChapterPurchase (Boolean) - 是否允许单章购买
  • chapterPrice (BigDecimal) - 单章价格
  • enabled (Boolean) - 是否启用
  • sortOrder (Integer) - 排序权重
  • phase (String) - 状态
  • articleCount (Integer) - 文章数
  • subscriberCount (Integer) - 订阅数
  • totalViews (Long) - 总阅读量
  • purchased (Boolean) - 用户是否已购买
  • progressPercent (Integer) - 用户学习进度百分比

ChapterVo:

  • name (String) - Post metadata.name
  • title (String) - Post spec.title
  • slug (String) - Post spec.slug
  • permalink (String) - Post status.permalink
  • publishTime (Instant) - 发布时间
  • published (Boolean) - 是否已发布
  • isFreePreview (Boolean) - 是否免费试读
  • isRead (Boolean) - 用户是否已阅读
  • priority (Integer) - 排序优先级
  • tags (List) - 章节标签
  • isPendingUnlock (Boolean) - 是否为待解锁章节
  • authorUsername (String) - 文章作者用户名
  • dripStatus (String) - 滴灌状态
  • unlockTime (Instant) - 待解锁章节的预计解锁时间

UserProgressVo:

  • columnName (String) - 专栏名称
  • lastReadPostName (String) - 最后阅读的章节名称
  • lastReadPostTitle (String) - 最后阅读的章节标题
  • lastReadAt (Instant) - 最后阅读时间
  • completedCount (Integer) - 已完成章节数
  • totalCount (Integer) - 总章节数
  • progressPercent (Integer) - 学习进度百分比
  • readPostNames (List) - 已阅读的章节列表

DistributorVo:

  • name (String) - 分销员名称
  • username (String) - 用户名
  • displayName (String) - 显示名称
  • avatar (String) - 头像
  • promotionCode (String) - 推广码
  • level (String) - 等级
  • phase (String) - 状态
  • parentUsername (String) - 上级用户名
  • totalCommission (BigDecimal) - 总佣金
  • pendingCommission (BigDecimal) - 待结算佣金
  • withdrawnAmount (BigDecimal) - 已提现金额
  • directCount (Integer) - 直推人数
  • teamCount (Integer) - 团队人数
  • orderCount (Integer) - 订单数
  • createdAt (Instant) - 创建时间
  • approvedAt (Instant) - 审核通过时间

3. Thymeleaf 语法修正

所有示例模板已修正为标准 Thymeleaf 语法:

变量输出:

<!-- 正确 -->
[[${variable}]]
<span th:text="${variable}"></span>
<span th:utext="${variable}"></span>

<!-- 错误 -->
${variable}

条件判断:

<!-- 正确 -->
<div th:if="${condition}">...</div>
<div th:unless="${condition}">...</div>
<div th:if="${vo.active}">...</div>
<div th:if="${vo.active == true}">...</div>
<div th:if="${vo != null}">...</div>

<!-- 错误 -->
<div th:if="condition">...</div>

属性设置:

<!-- 正确 -->
<img th:src="${image}" th:alt="${title}">
<div th:attr="data-id=${id},data-name=${name}">

<!-- 错误 -->
<img src="${image}" alt="${title}">

Mono/Flux 调用:

<!-- 正确 -->
${knowSphereFinder.checkAccess('post', 'post-123').block()}
${knowSphereFinder.listColumns(1, 10).collectList().block()}

<!-- 错误 -->
${knowSphereFinder.checkAccess('post', 'post-123')}
${knowSphereFinder.listColumns(1, 10)}

空值检查:

<!-- 正确 -->
<div th:if="${vo != null && vo.field != null}">
  [[${vo.field}]]
</div>

<!-- 错误 -->
<div th:if="${vo.field}">
  [[${vo.field}]]
</div>

4. 时间类型修正

所有时间字段已从 LocalDateTime 修正为 Instant:

<!-- 正确 -->
<span th:if="${order.createdAt != null}">
  [[${#temporals.format(order.createdAt, 'yyyy-MM-dd HH:mm:ss')}]]
</span>

<!-- Instant 类型的字段 -->
- AccessCheckVo.scheduledAccessAt
- MembershipVo.startAt, expireAt
- OrderVo.createdAt, paidAt, completedAt, refundedAt
- UserAccessVo.orderCompletedAt, effectiveAt, purchasedAt, expireAt
- ChapterVo.publishTime, unlockTime
- UserProgressVo.lastReadAt
- UserDripStatusVo.subscriptionAnchor, nextUnlockTime
- DistributorVo.createdAt, approvedAt

文档结构

base-theme-guide.md

  • 快速开始
  • Finder API(访问控制、会员系统、用户中心)
  • Lit 组件(ks-paywall, ks-payment-modal, ks-checkin-calendar, ks-countdown)
  • 暗黑模式适配
  • CSS 变量系统
  • 最佳实践

pro-theme-guide.md

  • 专栏系统(列表、详情、章节、进度、滴灌)
  • 任务系统(可用任务、用户任务)
  • 分销系统(分销员信息、统计、推广链接、二维码)
  • 内容评分(评分统计、Top 列表)
  • 评论打赏(打赏统计、批量查询)
  • 最佳实践

验证清单

  •  所有 Finder API 方法签名与后端一致
  •  所有 VO 字段名与 Java 类定义一致
  •  所有 Thymeleaf 示例使用标准语法
  •  所有时间类型使用 Instant
  •  所有示例包含空值检查
  •  所有示例包含 .block() 或 .collectList().block()
  •  所有布尔值判断正确
  •  所有数字格式化正确
  •  所有时间格式化正确

注意事项

  1. 在模板中使用 Finder API 时,必须调用 .block() 或 .collectList().block() 获取结果
  2. 始终检查返回值是否为 null
  3. 使用 th:if="${vo.field != null}" 检查字段是否存在
  4. 使用 [[${variable}]] 或 th:text="${variable}" 输出变量
  5. 时间字段使用 #temporals.format() 格式化
  6. 金额字段使用 #numbers.formatDecimal() 格式化
  7. 布尔值判断使用 th:if="${vo.active}" 或 th:if="${vo.active == true}"