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

46 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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`
-`accessState``free``unlocked_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` 保持一致」的安全模式,避免在不同字段中混放全文与预览内容。
- 涉及付费内容时,优先在后端用「权限判断 + 统一内容裁剪」实现安全边界,前端只根据状态选择展示预览还是全文。