11
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-16 21:47:20 +08:00
parent 2456c10c63
commit 09d4c0c31b
79 changed files with 11873 additions and 2341 deletions

View File

@@ -0,0 +1,844 @@
# AI 原生 Agent-First 八锚点共创流程 PRD
更新时间:`2026-04-16`
## 0. 文档目的
这份 PRD 用于把“八个剧情锚点”从一个抽象方法,落成当前自定义世界创作体系里可直接编码的 Agent 共创流程。
本文件重点回答的问题不是:
- 八个锚点分别叫什么
- 玩家要不要一上来全部填完
而是:
**如何让玩家通过和 Agent 共创,在低压力、低表单感的体验里,被启发、被总结、被校准,逐步完成这八个锚点的稳定设定。**
这份 PRD 默认建立在现有 `Agent-First 自定义世界创作工具` 主链之上,不新建一套独立系统,不新开一条独立创作产品线,而是在现有创作工作区中,把“锚点收集阶段”升级成更强的共创体验。
---
## 1. 产品定义
## 1.1 一句话定义
让玩家通过与一个懂 RPG 剧情策划方法的 Agent 对话,在自然聊天中逐步明确作品方向、玩家视角、剧情发动机和世界统一母题;同时由 Express 后端把这些聊天沉淀成结构化八锚点状态,并支持确认、锁定、补缺和进入后续世界底稿生成。
## 1.2 产品定位
这不是“八题问卷生成器”。
这也不是“无限闲聊陪聊器”。
它应当是:
**一个会启发玩家表达、会主动总结当前理解、会识别缺口并只追问关键问题、最终把共创结果沉淀成结构化创作锚点的 Agent 共创流程。**
## 1.3 目标用户
目标用户仍然是当前自定义世界创作工具的三类创作者,但本流程更偏向解决其中两类人的起步问题:
1. 轻创作者
- 有模糊灵感,但不知道先想什么
2. 中度创作者
- 有一些设定点子,但缺少把设定收束成可运行剧情骨架的方法
重度创作者也可使用本流程,但他们更关心的是:
- Agent 是否会少问废话
- 摘要是否准确
- 锚点是否可编辑、可锁定、可回看
## 1.4 成功标准
这个流程上线后,必须同时满足:
1. 玩家不需要面对一整页字段,也能在 `5~12` 分钟内形成一版可用的八锚点底稿。
2. Agent 不会机械地把八个锚点逐条盘问,而是根据玩家已有表达做提炼和补缺。
3. 每个锚点都能被区分为 `已确认 / Agent 推断 / 待补充 / 已锁定` 四种状态。
4. 玩家在任意时刻都能看懂“现在这个世界已经定了什么、还有什么没定、Agent 正在为什么追问”。
5. 当前锚点状态能直接进入下一阶段,生成世界底稿、关键角色、关键地点和主线第一幕。
6. 所有锚点状态更新、确认、锁定、冲突判断和完成度裁决都在 Express 后端完成,前端只负责表现和输入。
## 1.5 本次不做什么
本次 PRD 明确不做:
1. 不把八个锚点做成固定顺序的硬表单。
2. 不让 Agent 一上来抛出 `8` 个问题要求用户逐条回答。
3. 不让前端本地判断“锚点是否完整”或“是否可以进入下一阶段”。
4. 不要求玩家在这一阶段直接填写全量角色卡、地点卡、阵营卡和章节卡。
5. 不把长背景、世界编年史、底层运行结构暴露给玩家做首轮输入。
---
## 2. 设计背景
## 2.1 现有最小锚点方案的问题
现有文档已经证明,“最小锚点 + AI 初稿卡 + 系统托管层”方向是对的。
但如果直接把锚点做成显式卡片或显式问题列表,会出现 4 个体验问题:
1. 玩家会有表单焦虑
- 明明只是有一个灵感,却像在填写策划需求单
2. 玩家会误以为每个字段都必须一次写对
- 导致迟迟不敢开始
3. Agent 容易退化成“礼貌复读机”
- 只是复述玩家说过的话,没有真实推进创作
4. 锚点层级混乱时,玩家会觉得问题很多但抓不住重点
- 不知道先定体验,还是先定设定,还是先定剧情
## 2.2 新方案的核心判断
更合理的方式不是让玩家“填写八个锚点”,而是让 Agent 围绕八个锚点做 3 件事:
1. 启发
- 帮玩家把模糊灵感说出来
2. 总结
- 把玩家已经表达的内容收束成清晰锚点
3. 补缺
- 只追问当前最影响后续生成质量的缺口
也就是说:
**八个锚点应该是后台结构,不应该原样等于前台交互。**
---
## 3. 八锚点模型
## 3.1 八锚点定义
本流程采用以下八个锚点作为底层结构:
1. `世界承诺`
- 这个世界最吸引玩家体验的核心承诺
2. `玩家幻想`
- 玩家扮演谁、追求什么、害怕失去什么
3. `主题边界`
- 作品气质、审美方向、禁忌边界
4. `玩家切入口`
- 玩家从什么身份、困境和局面进入故事
5. `核心冲突`
- 当前世界最主要的明面冲突与隐藏危机
6. `关键关系`
- 最能制造情感张力和选择代价的关系骨架
7. `暗线与揭示节奏`
- 哪些真相暂不揭露、后续如何层层展开
8. `标志元素与硬规则`
- 反复出现的物件、制度、能力、仪式和不可擅改规则
## 3.2 八锚点不是同级提问列表,而是三层结构
为了让 Agent 的追问顺序更自然,八锚点在系统内部应分成三层:
### 第一层:方向盘层
1. 世界承诺
2. 玩家幻想
3. 主题边界
### 第二层:剧情发动机层
4. 玩家切入口
5. 核心冲突
6. 关键关系
7. 暗线与揭示节奏
### 第三层:世界统一层
8. 标志元素与硬规则
这个分层的意义是:
1. Agent 先帮玩家说清“这部作品想让人爽什么”
2. 再说清“故事靠什么往前推”
3. 最后再把“这个世界为什么像同一个世界”收束起来
---
## 4. 产品目标
## 4.1 玩家体验目标
这套流程必须让玩家在主观体验上感受到:
1. 我不是在填表,我是在和一个懂行的搭档一起把脑子里的世界说清楚。
2. Agent 不是在审问我,而是在帮我抓重点。
3. 每聊一两轮,我都能明显看到这个世界变得更成形。
4. 如果我一开始只说了一个模糊点子Agent 也能把我带进状态。
5. 如果我说得已经很多Agent 不会浪费时间问明显问题。
## 4.2 业务目标
这套流程必须同时提升:
1. 起步转化率
- 更多玩家愿意真正开始创作
2. 锚点完整率
- 更多 session 能进入世界底稿生成阶段
3. 底稿质量稳定性
- 后续生成的角色、地点、主线第一幕更聚焦,不发散
4. 可控性
- 锚点状态清晰、可回看、可锁定、可修改
---
## 5. 核心原则
## 5.1 先让玩家表达,再让 Agent 命名
玩家不需要先理解“世界承诺”“主题边界”“暗线节奏”这些术语。
前台交互里Agent 应该优先用生活化说法启发玩家,例如:
- 你最想让玩家在这个世界里爽到什么
- 你更想做悲壮、诡异、浪漫还是狠一点的味道
- 玩家一开场最先卷进什么麻烦
- 这个世界最容易让人记住的东西是什么
等玩家表达后,再由系统把内容归档到对应锚点。
## 5.2 每次只追问当前最高杠杆缺口
当多个锚点都不完整时Agent 不应平均追问。
系统必须基于优先级只选择当前最影响后续生成质量的 `1~2` 个问题。
默认优先级如下:
1. 世界承诺
2. 玩家幻想
3. 玩家切入口
4. 核心冲突
5. 主题边界
6. 关键关系
7. 标志元素与硬规则
8. 暗线与揭示节奏
原因不是暗线不重要,而是:
- 暗线通常应建立在前面几层已稳定的前提上
- 太早问暗线,容易让新玩家卡住
## 5.3 Agent 必须周期性总结,而不是只追问
如果连续两轮都只是在问问题,玩家会感觉自己被采访。
因此 Agent 必须在关键节点做“短总结”,明确告诉玩家:
1. 我目前理解你这个世界是什么
2. 哪些已经比较稳
3. 接下来只差什么就能往下走
## 5.4 显式区分确认与推断
Agent 可以根据玩家的话做合理推断,但不能把推断伪装成已确认事实。
系统和 UI 都必须把锚点拆成:
1. 玩家已明确确认
2. Agent 根据上下文推断
3. 还缺信息
4. 已锁定不可自动改写
## 5.5 先收束,再展开
这一阶段的目标不是把世界写满,而是把方向盘和剧情发动机装好。
因此 Agent 在八锚点阶段不应主动输出:
- 大量全新角色
- 大量地点
- 多章主线
- 长篇编年史
除非玩家主动要求。
---
## 6. 整体流程体验
## 6.1 总流程概览
八锚点共创阶段分成 6 个小阶段:
1. `灵感接住`
2. `方向盘收束`
3. `剧情发动机补齐`
4. `世界统一母题收束`
5. `共识确认`
6. `进入世界底稿生成`
---
## 7. 阶段设计
## 7.1 阶段 A灵感接住
### 目标
让玩家用最低压力开始,不要求结构化表达。
### 触发方式
玩家进入现有创作工作区后Agent 第一条消息不展示八锚点清单,不展示术语定义,而是给出一个轻启动入口。
推荐首条引导语方向:
1. 你可以直接说一个灵感画面
2. 也可以说一个你想做的题材混搭
3. 也可以说你想让玩家体验到的感觉
### Agent 行为要求
1. 允许玩家只说一句不完整的话
2. 优先识别其中已经透露出的锚点线索
3. 不急着问全套问题
4. 第一轮回复必须同时包含:
- 对灵感的理解与接住
- 一段不超过 `3` 点的当前提炼
- 下一个最关键问题
### 体验要求
玩家发完第一句后,必须立刻感到:
- 被理解了
- 世界已经开始成形了
- 下一步很容易答
## 7.2 阶段 B方向盘收束
### 目标
收束三件事:
1. 世界承诺
2. 玩家幻想
3. 主题边界
### Agent 行为要求
这一阶段的问题应该围绕“作品想让玩家爽什么、沉什么、怕什么”展开,而不是先问大量设定名词。
推荐提问策略:
1. 优先问体验差异
- “你最想让这个世界在哪一点上和同类不一样?”
2. 再问玩家代入
- “玩家在这里最想成为什么样的人?”
3. 最后问气质边界
- “你更想要狠一点、暖一点、诡一点,还是史诗一点?”
### 阶段完成定义
当系统判断以下条件同时满足时,阶段 B 完成:
1. 世界承诺非空,且有至少 `1` 条体验差异
2. 玩家幻想包含 `身份或追求``失去恐惧或代价`
3. 主题边界至少包含 `1` 条风格方向与 `1` 条禁忌边界
## 7.3 阶段 C剧情发动机补齐
### 目标
补齐:
1. 玩家切入口
2. 核心冲突
3. 关键关系
4. 暗线与揭示节奏
### Agent 行为要求
这一阶段不能抽象空问,而要从“开场局面”入手。
推荐顺序:
1. 玩家一进来先遇到什么麻烦
2. 这个麻烦背后连着什么更大的矛盾
3. 谁和谁之间最有火药味或亏欠感
4. 这世界有没有什么真相不想一开始就亮出来
### 特别要求
如果玩家已经自然说出了一部分角色、阵营、旧案Agent 应先总结再追问,不得无视已有信息重复提问。
### 阶段完成定义
当系统判断以下条件同时满足时,阶段 C 完成:
1. 玩家切入口包含 `身份/局面/动机` 中至少 `2`
2. 核心冲突包含 `1` 条明面冲突和 `1` 条隐藏危机
3. 至少有 `2` 条关键关系骨架
4. 暗线与揭示节奏至少明确 `1` 条隐藏真相和 `1` 条延后揭示意图
## 7.4 阶段 D世界统一母题收束
### 目标
明确:
1. 标志元素
2. 硬规则
### Agent 行为要求
不要用“请列举标志元素”这种空问法。
应从玩家已经说过的世界里抽取候选,再请玩家确认或替换,例如:
- “我感觉你这个世界的记忆点可能会落在失控神谕、债契纹印和会吃人的旧城制度上,这个方向对吗?”
### 阶段完成定义
1. 至少确认 `2~5` 个标志元素
2. 至少确认 `1~3` 条硬规则
## 7.5 阶段 E共识确认
### 目标
把前面多轮对话沉淀成一份可以被玩家直接确认的八锚点摘要。
### Agent 行为要求
Agent 必须输出一份结构化但仍然易读的摘要,分成三类:
1. 已确认
2. 我的推断
3. 还可补强
同时只问玩家一个问题:
**“这版底子你要先锁定,还是还想继续打磨某一块?”**
### 阶段完成定义
玩家执行以下任一动作即可:
1. 确认进入下一阶段
2. 锁定部分锚点后进入下一阶段
3. 指定某个锚点继续精修
## 7.6 阶段 F进入世界底稿生成
### 目标
把八锚点状态提交给后端,生成首轮世界底稿包。
### 本阶段产物
系统至少生成:
1. 世界标题与摘要
2. `3~5` 个关键角色卡
3. `2~4` 个势力卡
4. `4~6` 个关键地点卡
5. `3~5` 条世界线程
6. 主线第一幕简稿
---
## 8. Agent 回复策略
## 8.1 单轮回复结构
八锚点阶段中Agent 的标准回复结构应尽量稳定为:
1. `接住`
- 一句话表明理解到玩家当前表达的重点
2. `提炼`
-`2~4` 条短句总结已浮现的锚点
3. `补缺`
- 只问 `1` 个主问题,必要时附 `1` 个轻量补充问法
## 8.2 禁止行为
这一阶段禁止 Agent 出现以下回复模式:
1. 连续大段夸赞,没有实质推进
2. 把玩家原话换个说法重复一遍就结束
3. 一次抛出 `5` 个以上问题
4. 在锚点未稳定前自动生成成批设定
5. 把推断写成已确认事实
## 8.3 提问模板原则
提问模板必须符合:
1. 生活化
2. 可口语回答
3. 不要求术语知识
4. 一次只推进一个认知动作
例如:
- 好问题:
- “你最想让玩家在这个世界里上瘾的是哪种感觉?”
- “玩家一开场是被追、被困、被误认,还是自己主动撞进去?”
- 坏问题:
- “请详细描述你的主题母题、叙事支柱、隐性线索分发策略与世界统一意象。”
---
## 9. 前台交互设计
## 9.1 总体原则
沿用现有创作工作区,不新开页面。
只在现有 Agent 工作区中新增更明确的锚点反馈区和阶段反馈区。
## 9.2 工作区组成
八锚点阶段的工作区默认包含三块:
1. `左侧或主区:聊天流`
- 玩家输入
- Agent 回复
- 阶段性总结
2. `侧边摘要区:当前世界底子`
- 以易读摘要展示八锚点当前状态
3. `底部操作区:下一步动作`
- 继续聊
- 确认这一版
- 锁定当前理解
- 指定重聊某个锚点
## 9.3 摘要区展示规则
摘要区不展示长解释,不堆技术词。
每个锚点只展示:
1. 标题
2. 一行摘要
3. 状态标签
状态标签仅允许:
1. `已确认`
2. `推断中`
3. `待补充`
4. `已锁定`
## 9.4 阶段提示
工作区应始终用一句短提示明确当前阶段,例如:
- 正在帮你收束作品方向
- 正在补齐剧情冲突和关系发动机
- 正在确认这个世界最有记忆点的母题
禁止在 UI 上默认显示大段规则说明文字。
---
## 10. 后端结构设计
## 10.1 真实状态源
Express 后端必须作为唯一真实状态源,负责:
1. 解析聊天消息
2. 更新八锚点结构
3. 计算锚点状态
4. 生成下一轮提问建议
5. 生成阶段性摘要
6. 判断是否进入下一阶段
## 10.2 结构化状态模型
建议新增或扩展 `creatorIntent``eightAnchorDraft` 结构,至少包含:
```ts
type AnchorStatus = 'missing' | 'inferred' | 'confirmed' | 'locked';
type AnchorField<T> = {
value: T | null;
status: AnchorStatus;
confidence: number;
sourceMessageIds: string[];
summary: string;
openQuestions: string[];
};
type EightAnchorDraft = {
worldPromise: AnchorField<WorldPromiseValue>;
playerFantasy: AnchorField<PlayerFantasyValue>;
themeBoundary: AnchorField<ThemeBoundaryValue>;
playerEntryPoint: AnchorField<PlayerEntryPointValue>;
coreConflict: AnchorField<CoreConflictValue>;
keyRelationships: AnchorField<KeyRelationshipValue[]>;
hiddenLines: AnchorField<HiddenLineValue>;
iconicElements: AnchorField<IconicElementValue>;
phase: 'spark' | 'direction' | 'engine' | 'motif' | 'review' | 'ready';
readyForFoundationDraft: boolean;
};
```
## 10.3 每个锚点的最小字段
### 世界承诺
- `hook`
- `differentiator`
- `desiredExperience`
### 玩家幻想
- `playerRole`
- `corePursuit`
- `fearOfLoss`
### 主题边界
- `toneKeywords`
- `aestheticDirectives`
- `forbiddenDirectives`
### 玩家切入口
- `openingIdentity`
- `openingProblem`
- `entryMotivation`
### 核心冲突
- `surfaceConflicts`
- `hiddenCrisis`
- `firstTouchedConflict`
### 关键关系
- `pairs`
- `relationshipType`
- `secretOrCost`
### 暗线与揭示节奏
- `hiddenTruths`
- `misdirectionHints`
- `revealPacing`
### 标志元素与硬规则
- `iconicMotifs`
- `institutionsOrArtifacts`
- `hardRules`
## 10.4 更新策略
每轮聊天后,后端需要依次执行:
1. 从用户消息中提取可能涉及的锚点更新
2. 判断新增内容是确认、补充还是冲突
3. 生成新的锚点摘要
4. 重新计算缺口优先级
5. 产出下一轮 Agent 回复所需的:
- 当前理解
- 待补问题
- 禁止重复问的问题
- 推荐阶段标签
## 10.5 冲突处理
如果玩家后续表达与已确认锚点冲突,系统不得静默覆盖。
必须生成显式冲突状态,并让 Agent 用自然语言确认,例如:
- “你前面更像想做冷硬末日,现在这轮开始偏浪漫奇谭了,我先不自动改,想确认你是准备转方向,还是只想让其中一条支线更柔一点?”
---
## 11. 完成度判断
## 11.1 锚点完成度
每个锚点都需要有自己的完成度判断函数。
完成度不等于“字段不为空”,而是要判断其是否足以支持下一阶段生成。
例如:
- 世界承诺只有“修仙世界”不能算完成
- 世界承诺如果是“一个靠借寿续命维持秩序的仙朝里,玩家要在飞升诱惑和众生寿债之间做选择”,则可判定为高完成度
## 11.2 阶段完成判定
系统不要求八个锚点都达到满分才允许进入下一阶段。
建议阈值:
1. 方向盘层全部至少为 `confirmed` 或高置信 `inferred`
2. 核心冲突必须为 `confirmed`
3. 玩家切入口必须至少高置信 `inferred`
4. 关键关系至少有 `2`
5. 标志元素至少有 `2`
满足以上条件即可进入 `ready`
---
## 12. 示例体验脚本
## 12.1 正常起步示例
玩家输入:
“我想做一个有点像修仙版黑帮世界的东西,大家靠供奉某种会回应愿望的古神器活着,但越许愿越会被改写。”
Agent 不应回复成八问表:
- 世界一句话是什么
- 玩家身份是什么
- 主题气质是什么
而应回复成:
1. 先接住这个灵感
2. 提炼:
- 世界承诺像是“高代价许愿修仙”
- 标志元素已经浮现出“古神器”和“愿望改写”
- 核心冲突隐约是“活下去必须许愿,但许愿会失去自我”
3. 再只问一个高杠杆问题:
- “你更想让玩家一开始就是这个秩序里的既得利益者,还是一个被它逼到角落的人?”
## 12.2 已说很多时的示例
如果玩家已经连续说了 `3` 大段设定Agent 下一轮应优先总结,而不是继续散问。
推荐动作:
1. 给出一版八锚点缩略摘要
2. 标明哪些是推断
3. 只指出当前最影响后续生成质量的一个缺口
---
## 13. 与后续阶段的衔接
## 13.1 输入给世界底稿生成阶段的内容
八锚点阶段结束后,后续世界底稿生成必须直接吃结构化 `eightAnchorDraft`,而不是重新从聊天全文读一遍。
## 13.2 后续可编辑范围
进入世界底稿阶段后,创作者默认优先精修:
1. 关键角色
2. 核心冲突与线程
3. 关键地点
4. 主线第一幕
八锚点继续作为全局约束存在。
---
## 14. 埋点与评估
## 14.1 关键埋点
至少记录:
1. 首轮消息后是否进入第二轮
2. 每个锚点首次从 `missing` 变成 `inferred` 的时间
3. 每个锚点首次被玩家确认的时间
4. 会话进入 `ready` 所需轮数
5. 玩家在共识确认阶段选择:
- 继续打磨
- 锁定并继续
- 放弃
## 14.2 质量评估指标
上线后重点观察:
1. 平均完成锚点数
2. 进入底稿生成阶段的比例
3. 玩家主动修改摘要的比例
4. 后续生成内容是否出现发散或跑偏
5. 玩家是否频繁抱怨“Agent 老在问我已经说过的东西”
---
## 15. 实现拆分建议
## 15.1 第一阶段
先做最小闭环:
1. 八锚点结构化状态
2. 锚点状态标签
3. 单轮提炼 + 单问题追问
4. 共识确认摘要
5. 进入下一阶段的后端判定
## 15.2 第二阶段
再补:
1. 冲突检测
2. 更细的完成度评分
3. 阶段提示语
4. 指定锚点重聊
5. 锁定后禁止自动改写
## 15.3 第三阶段
继续补:
1. 更强的 Agent 提问策略
2. 更丰富的摘要模板
3. 基于锚点的底稿质量评估
4. 对不同题材的提问风格适配
---
## 16. 验收标准
本 PRD 对应功能完成后,至少必须满足:
1. 玩家只输入一段模糊灵感时Agent 能给出有效提炼和一个高杠杆追问。
2. 玩家连续多轮输入后,八锚点摘要会持续更新,不只是聊天记录增长。
3. 工作区能稳定显示每个锚点的当前状态。
4. Agent 不会在同一锚点已高置信完成后继续反复追问。
5. 玩家可明确确认当前理解、锁定部分锚点或指定某个锚点继续打磨。
6. 八锚点状态能被后端判定为 `ready` 并进入世界底稿生成。
7. 前端不承担锚点完成度判断、冲突裁决和下一步阶段判断。
8. 相关测试、`check:encoding` 通过。
---
## 17. 一句话结论
八锚点真正应该做成的,不是一套问卷,也不是一堆字段,而是:
**一个由 Agent 主导的启发式共创流程:先接住灵感,再提炼方向,再补齐剧情发动机,最后把玩家和 Agent 的共识沉淀成可运行的世界底子。**

View File

@@ -0,0 +1,147 @@
# “我的”Tab 历史浏览 PRD
更新时间:`2026-04-16`
## 0. 目标
把“历史浏览”从本地浏览记录升级成账号级内容回访能力,让玩家能找回最近看过的作品,并支持跨设备同步。
---
## 1. 当前现状与问题
当前仓库里 `platformBrowseHistory.ts` 采用 `localStorage` 方案,存在明显限制:
1. 仅本机可见
2. 浏览记录上限固定且不可运营
3. 删除缓存后全部丢失
4. 无法用于账号级推荐和召回
---
## 2. 本期范围
## 2.1 本期要做
1. 账号级历史浏览记录
2. 历史浏览列表接口
3. 浏览记录去重与排序
4. 清空历史入口
## 2.2 本期不做
1. 浏览历史搜索
2. 收藏夹合并
3. 基于历史的复杂推荐页
---
## 3. 详细设计
## 3.1 记录时机
用户进入公开作品详情页时写入浏览记录。
不写入的场景:
- 草稿世界
- 未真正打开详情的列表曝光
## 3.2 列表规则
每条记录展示:
- 世界名
- 作者名
- 摘要
- 封面
- 最近浏览时间
排序:
-`visitedAt` 倒序
去重:
- 同一用户对同一作品只保留最近一次
## 3.3 管理动作
支持:
1. 点击记录进入作品详情
2. 清空全部浏览历史
首期不做单条删除,避免交互复杂化。
---
## 4. 后端设计
## 4.1 数据模型
建议新增:
### `user_browse_history`
- `id`
- `user_id`
- `owner_user_id`
- `profile_id`
- `world_name`
- `subtitle`
- `summary_text`
- `cover_image_src`
- `theme_mode`
- `author_display_name`
- `visited_at`
并对 `user_id + owner_user_id + profile_id` 做唯一约束或 upsert。
## 4.2 接口
### `POST /api/profile/browse-history`
用途:
- 进入作品详情时写入记录
### `GET /api/profile/browse-history`
返回:
- 浏览历史列表
### `DELETE /api/profile/browse-history`
用途:
- 清空当前账号浏览历史
---
## 5. 迁移策略
为了兼容当前本地历史:
1. 用户首次登录后可尝试把本地历史批量上报一次
2. 服务端落库成功后,以服务端历史为主
3. 本地历史保留为短期兜底缓存,不再作为主数据源
---
## 6. 前端实现要求
1. “我的”页优先读服务端历史
2. 清空历史前给出确认
3. 空态保持轻量,不写规则说明
4. 失败时保留当前列表,不做闪断
---
## 7. 验收标准
1. 浏览详情后能在历史浏览中看到记录
2. 同一作品重复浏览只保留最新一条
3. 跨设备登录后可看到同一份历史
4. 清空后列表立即刷新

View File

@@ -0,0 +1,154 @@
# “我的”Tab 我的数据看板 PRD
更新时间:`2026-04-16`
## 0. 目标
把“剩余叙世币 / 总游戏时长 / 玩过作品”这一排信息卡,从静态数字展示升级成稳定的个人数据看板,让玩家在进入“我的”页时一眼知道自己的账号资产和游玩投入。
---
## 1. 当前现状与问题
当前三个数字来源并不统一:
1. 叙世币来自当前存档上下文,不等于账号总资产
2. 总游戏时长依赖当前快照,不代表全账号累计
3. 玩过作品当前几乎是硬编码推导,不是真实统计
这会导致“我的”页看到的数据不可信。
---
## 2. 本期范围
## 2.1 本期要做
1. 账号级数据聚合接口
2. 三张核心数据卡
3. 数据更新时间策略
4. 点击卡片查看明细的扩展位
## 2.2 本期不做
1. 成就系统
2. 排行榜
3. 全量行为分析页
---
## 3. 指标定义
## 3.1 剩余叙世币
定义:
- 当前账号可立即消费的叙世币余额
不使用:
- 当前单个存档里的临时货币数值
## 3.2 总游戏时长
定义:
- 当前账号下所有正式游玩会话累计时长
规则:
- 只累计进入有效游戏流程的时长
- 后台挂机超阈值后停止累计
## 3.3 玩过作品
定义:
- 当前账号实际进入过可游玩世界并产生有效游玩记录的去重作品数
去重键建议:
- `ownerUserId + profileId`
---
## 4. 详细设计
## 4.1 交互
三张卡片默认仅展示数字和标题。
点击行为:
1. 叙世币卡
- 打开资产流水抽屉
2. 总游戏时长卡
- 打开游玩统计抽屉
3. 玩过作品卡
- 打开玩过作品列表
如果本期不做明细页,点击可先无动作,但必须预留可扩展事件位。
## 4.2 展示规则
1. 数字过大时做单位缩略展示
2. 进入页面先展示骨架屏
3. 数据请求失败时展示降级文案,不展示假数字
---
## 5. 后端设计
## 5.1 聚合模型
建议新增账号聚合视图或服务:
- `wallet_balance`
- `total_play_time_ms`
- `played_world_count`
- `updated_at`
## 5.2 接口
### `GET /api/profile/dashboard`
返回:
- `walletBalance`
- `totalPlayTimeMs`
- `playedWorldCount`
- `updatedAt`
### `GET /api/profile/wallet-ledger`
返回:
- 叙世币流水列表
### `GET /api/profile/play-stats`
返回:
- 游玩时长分布
- 玩过作品列表摘要
---
## 6. 数据来源要求
1. 钱包余额从后端钱包台账聚合
2. 游戏时长从运行时会话日志或快照汇总
3. 玩过作品数从有效游玩记录去重计算
禁止继续采用:
- 仅从当前存档快照直接读取全部看板数据
---
## 7. 验收标准
1. 三个核心指标都能按账号稳定返回
2. 切换设备后看板数据一致
3. 没有存档时也能正常展示账号级数据
4. 数据加载失败时页面表现可控

View File

@@ -0,0 +1,104 @@
# “我的”Tab 功能 PRD 索引
更新时间:`2026-04-16`
## 0. 目标
基于当前仓库里 `src/components/game-shell/PlatformHomeView.tsx` 已经存在的 “我的” Tab 首屏结构,把页面内每个功能入口都拆成可独立开发、可独立排期、可直接进入编码的 PRD。
这次不是重新发明一个新的个人中心系统,而是遵守当前项目约束:
1. 尽量复用现有平台首页与账号体系
2. 前端只负责表现,逻辑、校验、数据归属全部交给 Express 后端
3. 移动端优先,桌面端兼容
4. UI 保持清爽,不在界面默认堆规则说明文案
---
## 1. 当前“我的”Tab 功能拆分
当前页面可拆成以下 `9` 个独立功能:
1. 账号资料与身份卡
2. 会员中心与充值
3. 我的数据看板
4. 最近游玩
5. 历史浏览
6. 邀请好友
7. 填邀请码
8. 玩家社区
9. 设置与账号安全
---
## 2. PRD 文件清单
1. [MY_TAB_PROFILE_IDENTITY_CARD_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_PROFILE_IDENTITY_CARD_PRD_2026-04-16.md)
2. [MY_TAB_MEMBERSHIP_CENTER_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_MEMBERSHIP_CENTER_PRD_2026-04-16.md)
3. [MY_TAB_DATA_DASHBOARD_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_DATA_DASHBOARD_PRD_2026-04-16.md)
4. [MY_TAB_RECENT_PLAY_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_RECENT_PLAY_PRD_2026-04-16.md)
5. [MY_TAB_BROWSE_HISTORY_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_BROWSE_HISTORY_PRD_2026-04-16.md)
6. [MY_TAB_INVITE_FRIENDS_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_INVITE_FRIENDS_PRD_2026-04-16.md)
7. [MY_TAB_INVITE_CODE_REDEMPTION_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_INVITE_CODE_REDEMPTION_PRD_2026-04-16.md)
8. [MY_TAB_PLAYER_COMMUNITY_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_PLAYER_COMMUNITY_PRD_2026-04-16.md)
9. [MY_TAB_SETTINGS_AND_SECURITY_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_SETTINGS_AND_SECURITY_PRD_2026-04-16.md)
---
## 3. 推荐开发顺序
建议按下面顺序推进,避免后续返工:
1. 账号资料与身份卡
2. 设置与账号安全
3. 最近游玩
4. 历史浏览
5. 我的数据看板
6. 会员中心与充值
7. 邀请好友
8. 填邀请码
9. 玩家社区
原因:
- `1 + 2` 复用现有账号系统最多,最容易先落地
- `3 + 4 + 5` 直接增强“我的”页内容密度,短期收益高
- `6 + 7` 涉及商业化和关系绑定,依赖结算与奖励台账
- `8` 最适合放在平台内容层能力稳定后再做
---
## 4. 模块边界约束
### 4.1 前端边界
- `PlatformHomeView` 继续作为“我的”Tab 首屏承载层
- 优先采用现有面板、抽屉、弹窗,不新建独立大系统
- 页面只展示后端返回的状态,不自行计算结论型业务状态
### 4.2 后端边界
- 用户资料、会员、资产、邀请、浏览历史、账号安全全部统一进 Express 后端
- 不允许继续把历史浏览、邀请码状态、会员权益状态仅存本地
- 用户相关聚合数据必须按账号隔离
### 4.3 数据边界
- 所有“我的”数据都必须与正式账号绑定
- 微信待绑定手机号状态下,只展示最小必要的账户与安全入口
- 涉及奖励、货币、权益的变更必须有流水
---
## 5. 结果要求
这组 PRD 交付后,开发层应能直接回答下面问题:
1. 这个功能入口点哪里打开
2. 用户看见什么
3. 前端调用什么接口
4. 后端存什么数据
5. 什么状态能操作,什么状态不能操作
6. 怎么验收算完成
如果后续继续扩写实现计划,建议直接以这 9 份 PRD 为母文档,不再重新发散一套新的“个人中心总方案”。

View File

@@ -0,0 +1,160 @@
# “我的”Tab 填邀请码 PRD
更新时间:`2026-04-16`
## 0. 目标
把“填邀请码”做成用户激活早期的一次性绑定动作,完成:
1. 输入邀请码
2. 校验邀请码是否可用
3. 绑定邀请关系
4. 发放被邀请奖励
---
## 1. 当前现状与问题
当前页面有“填邀请码”按钮,但没有成型规则。最容易踩坑的点是:
1. 什么时候还能填
2. 一个账号能不能改绑
3. 邀请人与被邀请人奖励何时发
如果不先写清楚,后续很容易出现刷奖励和投诉问题。
---
## 2. 本期范围
## 2.1 本期要做
1. 邀请码填写弹窗
2. 邀请关系校验
3. 一次性绑定规则
4. 绑定成功后的奖励发放
## 2.2 本期不做
1. 改绑邀请人
2. 申诉人工修正流程
3. 活动邀请码多类型扩展
---
## 3. 业务规则
## 3.1 填写时机
邀请码只允许在下面时间窗内填写:
1. 新账号注册后
2. 且尚未绑定过任何邀请码
3. 且未超过首个有效周期,例如 `7`
## 3.2 不允许情况
以下情况不可填写:
1. 已绑定过邀请码
2. 用自己的邀请码填写
3. 已超过填写时效
4. 邀请码失效或不存在
## 3.3 绑定结果
绑定成功后:
1. 写入邀请关系
2. 发放被邀请用户奖励
3. 更新邀请人待结算或已结算状态
邀请码绑定后不可撤销、不可修改。
---
## 4. 详细设计
## 4.1 页面结构
弹窗内容仅保留:
1. 输入框
2. 提交按钮
3. 当前可否填写状态
不默认写长篇规则说明。
必要提示采用短句:
- 已绑定,无法修改
- 该邀请码不可用
- 绑定成功
## 4.2 交互
1. 输入邀请码
2. 点击确认绑定
3. 服务端校验
4. 返回成功或失败状态
成功后:
- 按钮置灰
- 展示绑定的邀请人昵称或摘要
---
## 5. 后端设计
## 5.1 数据模型
复用:
- `user_invite_codes`
- `user_referral_relations`
- `user_reward_ledger`
并为被邀请方增加:
- `invited_by_user_id`
- `invite_bound_at`
## 5.2 接口
### `GET /api/referrals/redeem-status`
返回:
- 是否还能填写
- 已绑定邀请人摘要
- 填写截止时间
### `POST /api/referrals/redeem-code`
入参:
- `inviteCode`
出参:
- `ok`
- `inviterSummary`
- `rewardSummary`
---
## 6. 前端实现要求
1. 已绑定状态下直接展示结果,不再显示输入表单
2. 提交中不能重复点击
3. 服务端失败原因要原样映射成短提示
---
## 7. 验收标准
1. 符合条件的新账号可以成功绑定邀请码
2. 同一账号不能重复绑定
3. 不能填写自己的邀请码
4. 奖励发放结果可追踪

View File

@@ -0,0 +1,167 @@
# “我的”Tab 邀请好友 PRD
更新时间:`2026-04-16`
## 0. 目标
把“邀请好友”做成正式的拉新入口,首期目标是:
1. 用户能拿到自己的专属邀请码或邀请链接
2. 能方便地复制或分享
3. 邀请成功后双方奖励可核算
---
## 1. 当前现状与问题
当前“邀请好友”仅是快捷入口按钮,没有:
1. 专属邀请码
2. 分享载体
3. 邀请关系记录
4. 奖励发放规则
因此无法真正产生拉新闭环。
---
## 2. 本期范围
## 2.1 本期要做
1. 邀请好友弹窗
2. 专属邀请码与邀请链接
3. 复制、系统分享、二维码三种分享方式
4. 邀请进度与奖励状态
## 2.2 本期不做
1. 多级分销
2. 战队拉新活动
3. 社交平台深度回流分析
---
## 3. 业务规则
## 3.1 邀请主体
只有正式激活账号可以邀请好友。
待绑定手机号账号不可邀请。
## 3.2 邀请标识
每个账号拥有:
1. 一个固定邀请码
2. 一个可分享邀请链接
邀请码与账号一一绑定,不允许频繁重置。
## 3.3 邀请成功判定
被邀请用户满足以下条件才算成功:
1. 首次注册或首次完成正式激活
2. 首次绑定邀请码成功
3. 完成至少一次有效进入游戏或创建世界动作
这样可以过滤纯注册刷量。
## 3.4 奖励
首期奖励建议采用可控方案:
1. 邀请人获得叙世币
2. 被邀请人获得新手奖励
所有奖励必须走台账,不允许前端本地加值。
---
## 4. 详细设计
## 4.1 页面内容
邀请弹窗展示:
1. 我的邀请码
2. 复制按钮
3. 系统分享按钮
4. 二维码展示
5. 已邀请人数
6. 待达成奖励数量
7. 已到账奖励
## 4.2 交互
1. 点击复制
- 复制邀请码和邀请链接
2. 点击分享
- 触发浏览器分享或复制兜底
3. 点击二维码
- 放大查看
---
## 5. 后端设计
## 5.1 数据模型
建议新增:
### `user_invite_codes`
- `user_id`
- `invite_code`
- `status`
- `created_at`
### `user_referral_relations`
- `inviter_user_id`
- `invitee_user_id`
- `invite_code`
- `bound_at`
- `activated_at`
- `reward_status`
### `user_reward_ledger`
- `user_id`
- `reward_type`
- `amount`
- `source_type`
- `source_id`
- `created_at`
## 5.2 接口
### `GET /api/referrals/invite-center`
返回:
- 邀请码
- 邀请链接
- 分享二维码地址
- 邀请统计
- 奖励统计
---
## 6. 前端实现要求
1. 邀请入口采用轻量弹窗,不跳新系统页
2. 邀请码展示必须可直接复制
3. 二维码图片由后端或统一服务生成
4. 所有奖励数字以服务端返回为准
---
## 7. 验收标准
1. 用户能看到自己的邀请码与邀请链接
2. 可以一键复制或分享
3. 邀请成功后能看到正确统计
4. 奖励到账后叙世币余额同步变化

View File

@@ -0,0 +1,209 @@
# “我的”Tab 会员中心与充值 PRD
更新时间:`2026-04-16`
## 0. 目标
把顶部“会员充值”按钮落成正式可运营的会员中心最小闭环,首期只解决三件事:
1. 看清当前会员状态
2. 购买或续费会员
3. 理解会员能得到的实际权益
会员中心不做复杂商城,不做满屏促销文案,保持轻量、清爽、可直接支付。
---
## 1. 当前现状与问题
当前页面已有“会员充值”按钮,但本质上还是视觉占位,缺少:
1. 会员等级定义
2. 权益结构
3. 订单与支付状态
4. 到期时间与续费逻辑
这样会导致按钮可见但不可运营。
---
## 2. 本期范围
## 2.1 本期要做
1. 会员中心弹窗/抽屉
2. 当前会员状态展示
3. 可购买套餐展示
4. 下单与支付状态查询
5. 充值成功后的权益生效
## 2.2 本期不做
1. 积分商城
2. 限时活动页
3. 礼包组合购
4. 多级会员体系
---
## 3. 会员定义
首期只保留两种状态:
1. `普通用户`
2. `叙世会员`
会员权益首期建议控制在直接可编码的范围:
1. 每日额外叙世币领取额度
2. 高级世界模板或创作槽位
3. 更高的云存档上限
4. 会员专属标识
权益必须都是能被后端明确判定和下发的,不允许先写模糊营销描述。
---
## 4. 详细设计
## 4.1 入口与打开方式
点击“会员充值”按钮后:
1. 打开会员中心抽屉
2. 顶部显示当前会员状态
3. 中部显示权益卡片
4. 底部显示套餐与购买按钮
## 4.2 页面内容
页面展示模块:
1. 当前状态
2. 到期时间
3. 可用权益
4. 套餐列表
5. 最近订单状态
不展示:
- 大段充值说明
- 复杂规则 FAQ
- 无法立即购买的灰色功能墙
## 4.3 套餐结构
首期套餐建议:
1. `月卡`
2. `季卡`
3. `年卡`
每个套餐展示:
- 套餐名
- 价格
- 到账权益
- 生效周期
## 4.4 支付状态
订单状态至少支持:
- `pending`
- `paid`
- `failed`
- `closed`
- `refunded`
支付成功后:
1. 刷新会员状态
2. 刷新叙世币余额
3. 刷新权益标签
---
## 5. 后端设计
## 5.1 数据模型
建议新增:
### `membership_products`
- `product_id`
- `product_name`
- `duration_days`
- `price_cents`
- `status`
- `benefit_json`
### `user_memberships`
- `user_id`
- `membership_type`
- `started_at`
- `expires_at`
- `status`
### `membership_orders`
- `order_id`
- `user_id`
- `product_id`
- `amount_cents`
- `order_status`
- `payment_channel`
- `paid_at`
- `created_at`
## 5.2 接口
### `GET /api/membership/center`
返回:
- 当前会员状态
- 到期时间
- 套餐列表
- 权益列表
- 最近订单摘要
### `POST /api/membership/orders`
入参:
- `productId`
- `paymentChannel`
出参:
- `orderId`
- `payParams`
- `orderStatus`
### `GET /api/membership/orders/:orderId`
用途:
- 查询支付结果
---
## 6. 前端实现要求
1. 会员中心复用现有模态层,不新增独立系统页
2. 移动端默认单列套餐卡片
3. 支付中状态不能重复点单
4. 支付成功后从后端重新拉取状态,不靠前端假更新
---
## 7. 验收标准
1. 普通用户能看到可买套餐
2. 已开通会员能看到当前到期时间
3. 支付成功后权益立即生效
4. 续费不会覆盖错误时间
5. 没有空按钮和假入口

View File

@@ -0,0 +1,159 @@
# “我的”Tab 玩家社区 PRD
更新时间:`2026-04-16`
## 0. 目标
把“玩家社区”做成轻量社区入口,但不额外新造一个庞杂社交系统。首期目标是复用当前平台内容能力,提供:
1. 官方动态
2. 玩家讨论入口
3. 热门作品讨论聚合
---
## 1. 设计原则
这个社区功能必须遵守两个前提:
1. 优先复用已有平台作品与账号体系
2. 不在首期直接做完整好友社交网
所以首期社区不是“朋友圈”,而是“内容讨论与官方动态聚合层”。
---
## 2. 本期范围
## 2.1 本期要做
1. 社区入口页
2. 官方公告流
3. 玩家讨论话题流
4. 作品详情页下的讨论聚合跳转
## 2.2 本期不做
1. 好友私聊
2. 社区发帖富文本编辑器
3. 点赞排行榜
4. 群组系统
---
## 3. 信息架构
首期社区入口页建议拆成三个轻量分区:
1. 官方
2. 热门讨论
3. 最近作品讨论
点击“玩家社区”后,不跳全新站外页面,优先打开站内社区抽屉或二级视图。
---
## 4. 详细设计
## 4.1 官方区
展示:
- 官方公告
- 版本更新摘要
- 活动预告
每条内容只显示:
- 标题
- 摘要
- 时间
## 4.2 热门讨论区
展示:
- 讨论标题
- 关联作品
- 回复数
- 最近活跃时间
## 4.3 作品讨论区
当前平台已有作品广场与作品详情,因此社区首期优先绑定作品:
1. 每个公开作品可有讨论串
2. 社区页聚合热门作品讨论
3. 作品详情页可跳到该讨论串
---
## 5. 后端设计
## 5.1 数据模型
建议新增:
### `community_posts`
- `id`
- `author_user_id`
- `category`
- `related_profile_id`
- `title`
- `content_text`
- `status`
- `created_at`
- `updated_at`
### `community_replies`
- `id`
- `post_id`
- `author_user_id`
- `content_text`
- `status`
- `created_at`
### `community_announcements`
- `id`
- `title`
- `summary`
- `content_text`
- `published_at`
- `status`
## 5.2 接口
### `GET /api/community/home`
返回:
- 官方动态列表
- 热门讨论列表
- 最近作品讨论列表
### `GET /api/community/posts/:postId`
用途:
- 读取帖子与回复
---
## 6. 前端实现要求
1. 社区页保持内容导向,不做复杂社交关系页
2. 移动端优先采用流式卡片
3. 非登录用户只可浏览,发言必须登录
4. 敏感内容审核状态全部由后端控制
---
## 7. 验收标准
1. 用户可以从“我的”页进入社区入口
2. 可以看到官方动态和热门讨论
3. 作品讨论与作品详情存在双向跳转
4. 不需要新增独立社交系统就能跑通首期体验

View File

@@ -0,0 +1,212 @@
# “我的”Tab 账号资料与身份卡 PRD
更新时间:`2026-04-16`
## 0. 目标
把“我的”页顶部资料卡从一个静态展示块升级成正式的用户身份入口,承载:
1. 头像编辑
2. 昵称编辑
3. 叙世号展示与复制
4. 登录方式与绑定状态展示
5. 进入资料编辑抽屉
这个模块的作用不是做安全设置总入口,而是把“我是谁”展示清楚,并提供最轻量的资料编辑。
---
## 1. 当前现状与问题
当前页面已经展示:
- 头像占位
- 昵称
- 叙世号
- 登录方式
- 绑定状态
但存在几个问题:
1. 头像按钮和昵称编辑按钮都直接打开账号弹窗,信息架构混在一起
2. 头像当前只是视觉壳,没有真正的上传与裁剪能力
3. 昵称缺少明确的编辑规则与唯一性策略
4. 叙世号只是前端拼接值,不适合长期作为正式公开识别码
---
## 2. 产品范围
## 2.1 本期要做
1. 用户身份卡展示
2. 资料编辑抽屉
3. 头像上传、裁切、保存
4. 昵称编辑、校验、保存
5. 叙世号固定生成与复制
6. 登录方式与账号状态标签展示
## 2.2 本期不做
1. 个性签名
2. 主页装扮
3. 自定义头像框
4. 社交主页公开页
---
## 3. 信息架构
## 3.1 首屏卡片内容
资料卡固定展示:
- 用户头像
- 用户昵称
- `叙世号`
- 登录方式标签
- 账号状态标签
- 资料编辑入口
资料卡不展示:
- 大段规则说明
- 安全告警明细
- 设备管理
- 审计日志
这些内容统一放到“设置与账号安全”。
## 3.2 交互结构
点击区域行为如下:
1. 点击头像
- 打开“编辑资料”抽屉,并默认聚焦头像编辑区域
2. 点击昵称右侧编辑按钮
- 打开“编辑资料”抽屉,并默认聚焦昵称输入框
3. 点击叙世号复制按钮
- 直接复制,并给出轻提示
4. 点击登录方式/状态标签
- 不跳页,不弹复杂说明
---
## 4. 详细设计
## 4.1 头像
头像规则:
1. 默认使用系统首字头像
2. 用户上传后替换为正式头像
3. 上传后进入正方形裁切
4. 服务端生成 `256x256` 主图和 `96x96` 缩略图
5. 超过大小或格式限制时直接拦截
支持格式:
- `jpg`
- `png`
- `webp`
限制:
- 单文件最大 `5MB`
- 裁切结果统一为正方形
## 4.2 昵称
昵称规则:
1. 长度 `2-20` 个字符
2. 允许中文、英文、数字、下划线
3. 不允许空白昵称
4. 不要求全站唯一,但要允许后端做敏感词审核
5. 审核失败时返回明确错误
## 4.3 叙世号
叙世号规则:
1. 作为公开可复制识别码
2. 用户创建后固定生成,不允许用户修改
3. 格式统一,例如:`SY-8F29A13C`
4. 后端生成并返回,不再由前端临时拼接
## 4.4 账号状态标签
状态只显示短标签:
- `手机号登录`
- `微信登录`
- `待绑定手机号`
- `已激活`
不在资料卡里展开规则说明。
---
## 5. 后端设计
## 5.1 数据模型
建议扩展 `users` 或新增 `user_profiles`
- `user_id`
- `public_user_code`
- `display_name`
- `avatar_asset_id`
- `avatar_url`
- `avatar_thumb_url`
- `updated_at`
## 5.2 接口
### `GET /api/profile/me`
返回:
- `displayName`
- `avatarUrl`
- `avatarThumbUrl`
- `publicUserCode`
- `loginMethod`
- `bindingStatus`
### `PATCH /api/profile/me`
入参:
- `displayName`
- `avatarAssetId`
出参:
- 更新后的资料对象
### `POST /api/profile/avatar/upload-token`
用途:
- 获取头像上传凭证或上传地址
---
## 6. 前端实现要求
1. 资料编辑优先做成底部抽屉或轻量弹窗,不新开独立页面
2. 移动端头像、昵称、复制按钮必须单手可操作
3. 保存按钮固定在抽屉底部
4. 保存中展示明确 loading 态
5. 成功后即时回写顶部资料卡
---
## 7. 验收标准
1. 用户可以上传并保存头像
2. 用户可以修改昵称并实时看到更新
3. 叙世号由后端返回,复制后可正常使用
4. 未登录或待绑定状态下,不出现无效编辑入口
5. 页面不出现冗长规则说明文案

View File

@@ -0,0 +1,126 @@
# “我的”Tab 最近游玩 PRD
更新时间:`2026-04-16`
## 0. 目标
把“最近游玩”从单一继续游戏卡片扩成账号级最近游玩模块,让玩家可以快速回到最近推进过的作品和存档节点。
---
## 1. 当前现状与问题
当前“最近游玩”仅基于一个本地快照推导:
1. 只支持一个最近记录
2. 只要本地没有快照就没有内容
3. 无法跨设备同步
4. 无法区分多个世界和多个角色
这不符合平台化后的用户预期。
---
## 2. 本期范围
## 2.1 本期要做
1. 最近游玩列表
2. 继续游玩主动作
3. 进入作品详情或继续冒险
4. 跨设备同步最近记录
## 2.2 本期不做
1. 多存档槽管理全量页面
2. 手动置顶
3. 存档备注与重命名
---
## 3. 详细设计
## 3.1 展示结构
首屏展示 `1-5` 条最近游玩卡片。
每张卡片展示:
- 世界名
- 当前角色名
- 最近摘要
- 最近游玩时间
- 继续按钮
移动端优先横向滑动卡片,桌面端可显示为横向列表或双列卡片。
## 3.2 点击行为
1. 点击卡片主体
- 进入作品详情页,展示继续入口和存档摘要
2. 点击继续按钮
- 直接恢复最近游玩存档
如果该存档已失效:
- 给出“存档不可恢复”的明确提示
- 引导回到作品详情或重新开始
## 3.3 排序规则
`lastPlayedAt` 倒序。
若同一作品下存在多个存档:
- 只展示最近一次有效记录
---
## 4. 后端设计
## 4.1 数据模型
建议在存档或游玩记录层增加聚合:
- `user_id`
- `world_owner_user_id`
- `profile_id`
- `save_id`
- `world_name`
- `character_name`
- `continue_digest`
- `cover_image_src`
- `last_played_at`
- `is_resume_available`
## 4.2 接口
### `GET /api/profile/recent-plays`
返回:
- 最近游玩列表
### `POST /api/runtime/saves/:saveId/resume`
用途:
- 校验并恢复指定存档
---
## 5. 前端实现要求
1. 继续游玩动作必须走后端校验
2. 不允许前端自行拼装恢复上下文
3. 列表为空时展示轻量空态
4. 卡片摘要最多显示三行,保持“我的”页清爽
---
## 6. 验收标准
1. 最近游玩可以展示多个最近记录
2. 不同设备登录同一账号时列表一致
3. 点击继续后能恢复到正确存档
4. 无效存档不会让前端直接报错白屏

View File

@@ -0,0 +1,202 @@
# “我的”Tab 设置与账号安全 PRD
更新时间:`2026-04-16`
## 0. 目标
把“设置”入口正式定义为账号安全中心,统一承载:
1. 账号基础信息查看
2. 当前安全状态
3. 登录设备管理
4. 更换手机号
5. 最近账号操作记录
6. 退出登录与退出全部设备
这个模块直接建立在当前仓库已有的账号接口之上,是“我的”页最优先落地的正式功能。
---
## 1. 当前现状
当前仓库已具备以下基础能力:
1. `GET /api/auth/risk-blocks`
2. `GET /api/auth/sessions`
3. `GET /api/auth/audit-logs`
4. `POST /api/auth/phone/change`
5. `POST /api/auth/logout`
6. `POST /api/auth/logout-all`
7. `POST /api/auth/sessions/:sessionId/revoke`
说明当前账号安全不是从零开始,而是缺少稳定的信息架构和最终产品定义。
---
## 2. 产品范围
## 2.1 本期要做
1. 设置与账号安全弹窗
2. 安全状态展示
3. 登录设备管理
4. 更换手机号
5. 操作记录查看
6. 退出当前设备
7. 退出全部设备
## 2.2 本期不做
1. 修改密码正式入口
2. 实名认证
3. 邮箱绑定
4. 多因子认证
---
## 3. 信息架构
设置中心建议固定为五段:
1. 账号概况
2. 当前安全状态
3. 登录设备
4. 更换手机号
5. 账号操作记录
底部保留两个危险操作按钮:
1. 退出登录
2. 退出全部设备
---
## 4. 详细设计
## 4.1 账号概况
展示:
- 登录方式
- 手机号脱敏值
- 微信绑定状态
- 账号状态
这里只看信息,不做大编辑动作。
## 4.2 当前安全状态
展示当前账号命中的风控保护:
- 手机号保护
- 当前网络保护
每条状态可执行:
- 解除保护
解除动作必须经过后端校验。
## 4.3 登录设备
每条设备展示:
- 设备类型
- 最近活跃时间
- 到期时间
- IP 脱敏信息
- 是否当前设备
非当前设备支持:
- 踢下线
## 4.4 更换手机号
流程:
1. 输入新手机号
2. 获取验证码
3. 如有需要,完成人机校验
4. 输入验证码
5. 提交修改
规则:
1. 新号码不能等于当前号码
2. 已被其他账号绑定的号码不可用
3. 风控命中时必须遵循现有保护逻辑
## 4.5 操作记录
展示最近账号行为:
- 登录
- 绑定手机号
- 更换手机号
- 退出登录
- 踢设备
- 触发图形验证码
- 风险保护
---
## 5. 前后端职责边界
## 5.1 前端职责
1. 展示状态
2. 收集输入
3. 呈现 loading / success / error
## 5.2 后端职责
1. 风控判断
2. 图形验证码触发
3. 会话列表返回
4. 设备撤销
5. 日志审计
6. 手机号换绑
前端不允许自己决定:
- 是否需要验证码
- 是否允许解除风控
- 是否允许换绑
---
## 6. 接口对齐
首期优先复用现有接口:
1. `GET /api/auth/me`
2. `GET /api/auth/risk-blocks`
3. `POST /api/auth/risk-blocks/:scopeType/lift`
4. `GET /api/auth/sessions`
5. `POST /api/auth/sessions/:sessionId/revoke`
6. `GET /api/auth/audit-logs`
7. `POST /api/auth/phone/change`
8. `POST /api/auth/logout`
9. `POST /api/auth/logout-all`
如需补充,只增加展示层所缺的聚合字段,不重建接口体系。
---
## 7. 前端实现要求
1. 设置继续采用当前账号弹窗基础形态即可
2. 移动端优先底部弹层,桌面端可居中弹窗
3. 更换手机号区域默认折叠
4. 危险操作按钮与普通按钮必须明显区分
---
## 8. 验收标准
1. 用户能看到当前账号安全信息
2. 能查看并管理登录设备
3. 能按规则更换手机号
4. 能查看最近账号操作记录
5. 退出登录和退出全部设备都能稳定生效