feat(pokemon): allow duplicate display IDs to support multiple forms

Drop unique index on display_id to allow multiple forms under the same Pokopia number.
Include sort_order in queries to ensure stable sorting for duplicate display IDs.
This commit is contained in:
2026-05-12 19:19:05 +08:00
parent 8caa95e78e
commit 231a7bb313
3 changed files with 14 additions and 13 deletions

View File

@@ -29,7 +29,7 @@
- 全局搜索 API 只返回公开浏览所需的最小结果字段结果类型、ID、展示标题、目标 URL、可选摘要和可选图片用户搜索结果只使用公开 Profile 所需的 `id``displayName` 和目标 URL不返回邮箱、角色、权限、Referral、编辑审计、审核原因、token/hash、内部字段或调试信息。
- 用户界面只展示业务数据和设计内的文案,不展示提示词、计划、调试信息、字段内部名或修改说明。
- 可编辑 Wiki 内容必须记录创建者、最后编辑者、创建时间、最后编辑时间和编辑历史。
- 除 Pokemon 外,列表顺序由 `sort_order` 控制,默认按创建时间旧到新初始化,排序值按 10 递增以便后续插入和拖拽排序Pokemon 列表按 Pokopia 展示 ID`display_id`)升序展示,不提供手动排序。
- 除 Pokemon 外,列表顺序由 `sort_order` 控制,默认按创建时间旧到新初始化,排序值按 10 递增以便后续插入和拖拽排序Pokemon 列表按 Pokopia 展示 ID`display_id`)升序展示,同一展示 ID 下按 `sort_order` 和内部 `id` 稳定排序,不提供手动排序。
## 国际化
@@ -559,7 +559,7 @@ Pokemon 可配置:
- `/event-pokemon` 展示 Event Pokemon 列表。
- 两个列表复用 Pokemon 筛选、卡片和详情行为,但列表请求必须按 `is_event_item` 分开读取。
Pokemon 的 Pokopia 展示 ID 普通 Pokemon 和 Event Pokemon 之间可以重复,例如允许同时存在普通 `#1 妙蛙种子` 和 Event `#1 毽子草`。数据库要求同一个 `display_id + is_event_item` 组合唯一;前端路由和实体关联必须继续使用内部 `id`,不能使用展示 ID 作为路由或外键。Fetch 得到的官方 data ID 必须与展示 ID 分开保存;例如 Zorua 的官方 data ID 为 `570` 时,用户把 Pokopia 展示 ID 改成 `123` 后仍应通过 `/pokemon/570` 访问该 Pokemon`/pokemon/123` 只代表内部 ID 为 `123` 的其他 Pokemon。普通 Pokemon 和 Event Pokemon 不会同时存在同一个内部系统 ID当 Event Pokemon 关联官方 data 时,内部 ID 同样使用官方 data Pokemon ID。
Pokemon 的 Pokopia 展示 ID 可以重复,用于支持同一 Pokopia 编号下的多个形态,例如允许普通 `#41 Tangrowth` 和普通 `#41 Professor Tangrowth` 同时存在;普通 Pokemon 和 Event Pokemon 之间可以重复展示 ID,例如普通 `#1 妙蛙种子` 和 Event `#1 毽子草``is_event_item` 只表示普通 Pokemon / Event Pokemon 分流,不能用于标记特殊形态。数据库要求 `display_id` 唯一;前端路由和实体关联必须继续使用内部 `id`,不能使用展示 ID 作为路由或外键。Fetch 得到的官方 data ID 必须与展示 ID 分开保存;例如 Zorua 的官方 data ID 为 `570` 时,用户把 Pokopia 展示 ID 改成 `123` 后仍应通过 `/pokemon/570` 访问该 Pokemon`/pokemon/123` 只代表内部 ID 为 `123` 的其他 Pokemon。普通 Pokemon 和 Event Pokemon 不会同时存在同一个内部系统 ID当 Event Pokemon 关联官方 data 时,内部 ID 同样使用官方 data Pokemon ID。同一列表内展示 ID 相同的 Pokemon 按 `sort_order` 和内部 `id` 稳定排序。
Pokemon 编辑表单使用标签页组织字段:
@@ -608,7 +608,7 @@ Pokemon 列表功能:
- 按喜欢的东西筛选:
- 满足任意条件
- 满足全部条件
- 按 Pokopia 展示 ID`display_id`)升序展示;内部 `id` 仅用于路由、外键和稳定排序兜底
- 按 Pokopia 展示 ID`display_id`)升序展示;展示 ID 可重复,同一展示 ID 下按 `sort_order` 和内部 `id` 稳定排序;内部 `id` 仅用于路由、外键和稳定排序兜底
- 列表首屏只读取一页数据;滚动到列表底部时继续读取下一页,不一次性加载全部 Pokemon。
- Pokemon 列表卡片只展示 Pokemon 图片和下方的 `#ID 名称`;不展示喜欢的环境、属性、特长、喜欢的东西或编辑元信息。
- Pokemon 卡片在已配置图片时展示所选图片缩略图;未配置图片时保留默认 Poké Ball 标记。
@@ -1356,7 +1356,7 @@ API 暴露边界:
- `GET /api/admin/ai-moderation`
- `PUT /api/admin/ai-moderation`
- `PUT /api/admin/system-wordings/:key`
- 物品、材料单、栖息地的列表排序需要对应实体的 `order` 权限Pokemon 按 Pokopia 展示 ID`display_id`)排序,不提供列表排序 API 或 Admin 手动排序入口。
- 物品、材料单、栖息地的列表排序需要对应实体的 `order` 权限Pokemon 按 Pokopia 展示 ID`display_id``sort_order`、内部 `id` 排序,不提供列表排序 API 或 Admin 手动排序入口。
## 开发与验证