Files
soul-yongping/.cursor/agent/后端工程师/evolution/2026-03-13.md
2026-03-14 14:37:17 +08:00

2.9 KiB
Raw Blame History

2026-03-13 - 文章详情预览统一与内容安全

问题 / 场景

  • 文章详情目前小程序侧只展示约 20% 内容作为预览,再引导用户付费解锁。
  • 历史实现中前端本地按 20% 计算预览,后端曾同时返回外层 content(预览)和 data.content(全文),存在「接口约定不统一」和「误用 data.content 泄露全文」的风险。
  • 需求:统一由后端按业务规则截取预览(改为 50%),小程序只按「是否已付费」选择用预览还是全文;未付费时,无论字段层级都不能拿到全文。

解决方案

  • internal/handler/book.go 中调整章节预览逻辑:
    • previewContent 改为按字符数取正文前 50%total/2),同时保证预览不少于 100 个字符;
    • 预览结尾统一追加 ……(购买后阅读完整内容) 作为提示文案。
  • findChapterAndRespond 中统一内容返回策略:
    • 先根据 system_config.free_chapters / chapter_config.freeChapters / chapters.is_free / price 判断章节是否免费;
    • 免费章节:returnContent = ch.Content(全文);
    • 付费章节:
      • checkUserChapterAccess 判断用户已购买 / VIP / 全书:returnContent = ch.Content(全文);
      • 否则:returnContent = previewContent(ch.Content)(仅预览);
    • 构造响应时,将 chForResponse.Content = returnContent,并通过:
      • 外层 content: returnContent
      • 内层 data: chForResponse(其中 content 也为 returnContent
      • 确保未授权用户在任意字段上都拿不到完整正文。

与前端的接口约定

  • 小程序阅读页通过 userId 查询章节详情,accessManager 基于返回的章节信息与用户购买状态计算 accessState
    • accessStatefreeunlocked_purchased 时,前端使用 res.data.content ?? res.content 渲染全文;
    • accessState 为未登录 / 未购买时,前端只使用 res.content 渲染预览。
  • 预览比例完全由后端控制(当前为 50%),小程序不再自行用 20% 做二次截断,只是把后端提供的预览完整展示出来。

代码位置

  • 后端:
    • soul-api/internal/handler/book.go
  • 小程序(前端配合):
    • miniprogram/pages/read/read.js
    • miniprogram/pages/read/read.wxml

对后续开发的约定

  • 预览长度(包括比例、最小字符数、提示文案)统一由后端控制;如需调整比例,只需修改 previewContent,保持接口字段含义不变。
  • 任何需要「只返回部分内容预览」的场景,应优先复用「外层 content + 内层 data.content 保持一致」的安全模式,避免在不同字段中混放全文与预览内容。
  • 涉及付费内容时,优先在后端用「权限判断 + 统一内容裁剪」实现安全边界,前端只根据状态选择展示预览还是全文。