Files
manpengan d7bea9aed5 nav: 全量 world-catalog + status active/planned 分层
- world-catalog.js: 6洲48国127城市全量 NavNode catalog
  - 统一 schema(isEnabled → status: active|planned)
  - 64 个 NavNode 覆盖所有洲/国家/地区
- runtime-nav.js: 从 catalog 自动过滤 active 节点
  - MVP_OVERRIDES 机制跳过国家层直连城市
  - V1.1+ 删除覆写即恢复完整层级
- 删除 future-catalog.js,旧 shim 指向 world-catalog
- game-design 2.3 更新 schema + Framework Ready 说明

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 23:37:17 +08:00

40 lines
2.0 KiB
JavaScript
Raw Permalink 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.
/**
* NavNode — 统一导航节点 schema
*
* 所有导航层级(洲/国家/地区/城市组)共用同一 shape。
* 分页通过 shared/pagination.js 的 paginate() 动态计算,不手写 page 常量。
*
* @typedef {Object} NavNode
* @property {'continent'|'country'|'region'|'city-group'} type
* @property {string} id - 全局唯一标识
* @property {string|null} parentId - 父节点 id洲级为 null
* @property {string} name - 中文名
* @property {string} nameEn - 英文名
* @property {number} sortOrder - 同级排序
* @property {string} themeColor - 主题色 HEX
* @property {'country'|'region'|'city'|null} childType - 子节点类型
* @property {string[]} childIds - 当前可消费的子节点 id仅已启用的
* @property {number} pageSize - 每页格子数,默认 9
* @property {'active'|'planned'} status - 'active'(当前可运行)/ 'planned'(未来规划)
* @property {boolean} isUnlockedByDefault - 是否默认解锁
*/
// schema 验证函数
export function validateNavNode(node) {
const required = ['type', 'id', 'name', 'nameEn', 'sortOrder', 'themeColor', 'childType', 'childIds', 'pageSize', 'status', 'isUnlockedByDefault']
const validTypes = ['continent', 'country', 'region', 'city-group']
const validChildTypes = ['country', 'region', 'city', null]
const validStatuses = ['active', 'planned']
const errors = []
for (const key of required) {
if (!(key in node)) errors.push(`missing field: ${key}`)
}
if (!validTypes.includes(node.type)) errors.push(`invalid type: ${node.type}`)
if (!validChildTypes.includes(node.childType)) errors.push(`invalid childType: ${node.childType}`)
if (!Array.isArray(node.childIds)) errors.push('childIds must be array')
if (node.parentId !== null && typeof node.parentId !== 'string') errors.push('parentId must be string or null')
if (!validStatuses.includes(node.status)) errors.push(`invalid status: ${node.status}, must be 'active' or 'planned'`)
return errors
}