规范:大纲行版式/初始适配口径 + 主干唯一性复核结论 + 节点游玩次数显示合计(§3.6.1/§3.6.3)
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled

This commit is contained in:
2026-10-07 12:37:19 +08:00
parent a7f781834a
commit ad21a2b367
@@ -460,6 +460,11 @@ A 路线里那个必须提前知道的互斥点已经按既有做法绕开:`cr
- **「累计创作世代数」在前端计算**:=本作品子树深度(子树最大代际 − 本作品代际),用详情页**已经请求的同一份 `/lineage` 数据**算,不新增请求、也不加服务端字段。
- **移动端形态**(跟随仓库既有窄断点,`useIsMobileViewport`):
- **默认大纲式缩进树**(`LineageOutlineList`):全宽行、层级用左缩进 + 肘形导线表达、主干链导线加粗用主题色;**无横向滚动**、无需缩放平移;行高 ≥44px,点击行 = 选中(无 hover)。
- **大纲行版式口径(2026-10-07 追加,来自真机截图复盘)**:
- **内容列限宽居中**:`.lineage-outline` 用 `max-width: 54rem` + `margin: 0 auto`,宽屏不再整屏出血(之前 1300px+ 横条、文字与「打开 / Fork」之间约 700px 死空白)。操作按钮是行的**最后一个子元素**,因此固定在**内容列右端**,不会飘到屏幕最右侧。
- **角标成组、永不叠印**:代际 / 主干 / 当前作品 / 父代-子代 四类角标统一放进 `.game-lineage-node__badges`(flex + gap + 可换行)。此前它们各自 `position: absolute`(代际左上、主干右上、「当前作品」在流内),在窄容器里会**互相叠印成乱码字形**(大纲行的「第 1 代」与「主干」);现在组内一律静态定位,重叠在结构上不可能发生。画布形态用同一组角标,只是整组作为封面左上角的浮层。
- **缩略图统一 16:9**:大纲行的封面与画布同一比例(16:9,4.5rem 宽),不再被角标撑成窄竖条;行用 `min-height: 3.5rem` 做统一基线,标题最多 2 行 clamp → 同层行等宽、跨行等高,连线端点一致。
- **信息密度**:代际 + 主干 + 当前作品 + 父代/子代 由「三行」收敛成**一行角标组**,标题 2 行 clamp、作者一行 → 每行比改版前少一行。
- **图谱视图为可选开关**(形态 B = **横版画布**,`orientation: 'horizontal'`:根在左、代际向右、兄弟分支沿纵向排开,窄屏上比顶→下更省横向空间):切到画布后支持拖拽平移 / 缩放;横版**不渲染左侧代际轴**,代际信息由节点自带角标承担。**初次进入按宽度适配**(整棵树横向看完;触及最小缩放时给出「可拖拽平移」提示),并把**当前作品**用最小位移拉进视口——贴最近的边,父代 / 兄弟仍留在视口里,不会出现「停在 100% 缩放、一个节点都看不到」的空屏。桌面仍为纵向画布 + 宽高同时适配并居中。
- **信息面板用 bottom sheet**:从底部升起(含简介 / 授权 / 核心改动说明 / 前往体验 / Fork 此版本),遮罩点击或关闭按钮收起;桌面保持画布右上浮层。
- **父代 / 子代区分与「只看父代与子代」开关**(2026-10-06 追加):
@@ -470,6 +475,8 @@ A 路线里那个必须提前知道的互斥点已经按既有做法绕开:`cr
- **筛选行口径**(2026-10-06 追加):`高亮整棵子树`复选框**已删除**——它恒为真、没有用户可见意义,子树高亮改为**恒定开启**(`collectLineageHighlight` 默认即含子树;页面不再持有该开关状态,也不再有恒为 `true` 的布尔往下传)。`改动类型`下拉**保留但禁用**并在旁边写明原因(`changeSummary` 是自由文本、服务端没有可枚举分类),不编造值域。
- **移动端门限豁免(2026-10-06)**:平台原有的「移动端仅支持作品展示」欢迎弹窗只看 `!isDesktopLayout`、忽略路由,会把公开只读的族谱树 / 共创主题页首屏盖住。现在按**显式白名单**豁免这三个 stage:`game-lineage` / `game-themes` / `game-theme`(清单在 `PlatformActiveMobileWelcomeDialog.tsx` 的 `MOBILE_WELCOME_EXEMPT_STAGES`,键名即 stage 名,不做前缀/范围匹配)。**创作 / 项目 / 发布 / 我的 / 平台首页仍保持门限**——那些才是「移动端不支持体验创作工具」的部分;弹窗文案未改(与豁免后的事实不矛盾:族谱与主题页本身就是作品展示)。
- **截断 / 空树 / 不可用父节点**在两种形态下都有降级:截断提示、空态、以及「原作品已不可用」的占位节点(可聚焦、不可点进详情、不展示被删作品标题与作者名)。
- **初始适配口径(2026-10-07 复核)**:初次进入按**宽高同时 fit**(`min(scaleX, scaleY)` + `FIT_PADDING`)并**水平垂直都居中**;若这个比例低于可读下限 `READABLE_MIN_SCALE = 0.6`,就**不强行全览**,改用可读缩放 + 平移,并给出明确提示「树较大:已按可读缩放显示(其余代际在视口外),拖拽平移查看,或点「适应窗口」看全树。」——两种情况下都**不会**在没有提示的前提下把最深的代际丢在视口外。窄屏「图谱视图」另按**宽度**适配(见上文)。
- **主干线唯一性复核(2026-10-07,真实数据)**:演示树 `共创演示·A0|星海工坊`(8 节点、`playCount` 全 0,仅 A111 = 1)实测 **每代恰好一个主干**:A0(0 代)/ A1(1 代)/ A11(2 代)/ A111(3 代);A2、A3、A12、A21 **都不是**主干。同代并列 0 热度时取「同代中**创建时间最早**」的那个(`/lineage` 契约即「代际升序、同代按创建时间升序」,布局只按输入顺序稳定取第一个),因此结果确定、不随渲染变化。**结论:主干逻辑未改**;新增「每代 isTrunk 数量恰好 1」的断言把它钉住(`lineageTreeLayout.test.ts`)。
#### 3.6.2 AGC 客户端:「共创」列表页与 Fork 工程确认页(2026-10-07 补充)
@@ -502,9 +509,14 @@ A 路线里那个必须提前知道的互斥点已经按既有做法绕开:`cr
| 口径 | 值 | 落点 |
| --- | --- | --- |
| 公开接口字段 `playCount` | **自身值**(服务端**不做**子树遍历) | `/lineage` 节点、`/derived` 节点、公开详情 DTO、我的作品列表 |
| **显示** | **子树合计** = 自身 + 全部后代,并给出分解(自身 M + 衍生 K) | 详情页 hero 与「共创」卡、主题页母版行、血缘图节点(若显示游玩数)、热门衍生栏 |
| **显示** | **子树合计** = 自身 + 全部后代,并给出分解(自身 M + 衍生 K) | 详情页 hero 与「共创」卡、主题页母版行、**族谱/血缘图节点(紧凑角标 `▶ N`,`title`/`aria-label` 注明含衍生)**、热门衍生栏 |
| **主干线判据 / 热度排序** | **自身值** | 族谱「每代热度最高」的主干线判据(裁定:主干线表达「**这一版自己**有多热」,用合计会让深层子树压制真正热的叶子)、热门衍生栏排序 |
- **族谱 / 血缘图节点也显示游玩次数(2026-10-07 用户口径追加)**:显示值 = 该节点的**子树合计**
(同一个 `collectLineagePlayCountTotals().total`,不另算一套),画布卡片与移动端大纲行都有;
呈现为与其它角标**同一行的紧凑 pill**(`▶ N`,全 0 也显示以保证列稳定),`title` / `aria-label`
写明「游玩次数(含衍生作品)」,因此**不撑高卡片、也不额外占一行**。
**主干线与「按热度排序」的判据仍用自身 `playCount`**——显示=合计、判据=自身,两处代码注释互相指认。
- **不在服务端加字段、也不让公开接口做子树遍历**(列表页会因此 N 次遍历,正是要省掉的算力成本):
客户端用**已经拿到的那棵树**一次自底向上遍历即可,纯函数 `collectLineagePlayCountTotals`
满足与 §3.11 贡献归集**同一条不变量** `total(W) = own(W) + Σ 直接子代 total(C)`,**零额外请求**。