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>
This commit is contained in:
@@ -160,17 +160,19 @@ MVP 只开放亚洲 6 城市,直入城市选择页,不启用完整多级导
|
|||||||
| `childType` | string\|null | 子节点类型:`country` / `region` / `city` / null |
|
| `childType` | string\|null | 子节点类型:`country` / `region` / `city` / null |
|
||||||
| `childIds` | string[] | 当前可消费的子节点 id(仅已启用的) |
|
| `childIds` | string[] | 当前可消费的子节点 id(仅已启用的) |
|
||||||
| `pageSize` | number | 每页格子数,默认 9 |
|
| `pageSize` | number | 每页格子数,默认 9 |
|
||||||
| `isEnabled` | boolean | 当前版本是否启用 |
|
| `status` | string | `'active'`(当前可运行)/ `'planned'`(未来规划) |
|
||||||
| `isUnlockedByDefault` | boolean | 是否默认解锁 |
|
| `isUnlockedByDefault` | boolean | 是否默认解锁 |
|
||||||
|
|
||||||
分页通过 `shared/pagination.js` 的 `paginate(childIds, pageSize)` 动态计算,不手写 page 常量。
|
分页通过 `shared/pagination.js` 的 `paginate(childIds, pageSize)` 动态计算,不手写 page 常量。
|
||||||
|
|
||||||
|
Framework Ready: 全量 6 洲 48 国 127 城市的 catalog 已搭好,扩城市只需加 CityManifest + 改 status 为 active。
|
||||||
|
|
||||||
**数据文件分层:**
|
**数据文件分层:**
|
||||||
|
|
||||||
| 文件 | 用途 | 是否进入 runtime |
|
| 文件 | 用途 | 是否进入 runtime |
|
||||||
|------|------|-----------------|
|
|------|------|-----------------|
|
||||||
| `navigation/runtime-nav.js` | 当前版本可消费的导航节点 | ✅ 是 |
|
| `navigation/runtime-nav.js` | 当前版本可消费的导航节点(从 world-catalog 自动过滤) | ✅ 是 |
|
||||||
| `navigation/future-catalog.js` | 未来版本城市/国家/地区规划 | ❌ 否 |
|
| `navigation/world-catalog.js` | 全量世界导航规划(含 active + planned) | ✅ 是(runtime-nav 从中过滤 active 节点) |
|
||||||
| `navigation/nav-schema.js` | NavNode schema 定义 + 验证 | ✅ 是(类型定义) |
|
| `navigation/nav-schema.js` | NavNode schema 定义 + 验证 | ✅ 是(类型定义) |
|
||||||
| `docs/city-roadmap.md` | 全量 127 城市路线图 | ❌ 否 |
|
| `docs/city-roadmap.md` | 全量 127 城市路线图 | ❌ 否 |
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @deprecated 亚洲国家列表已移入 navigation/future-catalog.js
|
* @deprecated 亚洲国家列表已移入 navigation/world-catalog.js
|
||||||
* MVP 阶段亚洲直接列出城市,不经过国家层。
|
* MVP 阶段亚洲直接列出城市,不经过国家层。
|
||||||
*/
|
*/
|
||||||
export { asiaCountryPlan as asiaCountries } from '../navigation/future-catalog.js'
|
import { getCatalogChildren } from '../navigation/world-catalog.js'
|
||||||
|
export const asiaCountries = getCatalogChildren('asia')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @deprecated 国家城市列表已移入 navigation/future-catalog.js
|
* @deprecated 国家城市列表已移入 navigation/world-catalog.js
|
||||||
*/
|
*/
|
||||||
import { asiaCountryPlan } from '../navigation/future-catalog.js'
|
import { getCatalogNode } from '../navigation/world-catalog.js'
|
||||||
export const japanCities = asiaCountryPlan.find(c => c.id === 'japan')
|
export const japanCities = getCatalogNode('japan')
|
||||||
export default japanCities
|
export default japanCities
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
/**
|
|
||||||
* Future Catalog — 未来版本导航规划
|
|
||||||
*
|
|
||||||
* 这些节点不进入当前 runtime 消费链路。
|
|
||||||
* 当新版本上线新城市时,将对应节点移入 runtime-nav.js 并设 isEnabled: true。
|
|
||||||
* 引用的 cityId 可能尚不存在对应 CityManifest。
|
|
||||||
*/
|
|
||||||
|
|
||||||
// V1.1: 中国一线城市扩展
|
|
||||||
export const v11_china_cities = ['shanghai', 'guangzhou', 'chengdu', 'shenzhen', 'hangzhou', 'chongqing']
|
|
||||||
|
|
||||||
// V1.2: 中国二线 A
|
|
||||||
export const v12_china_cities = ['wuhan', 'xian', 'changsha', 'nanjing', 'harbin', 'xiamen']
|
|
||||||
|
|
||||||
// V1.3: 欧洲热门
|
|
||||||
export const v13_europe_cities = ['paris', 'london', 'rome', 'barcelona', 'prague', 'amsterdam']
|
|
||||||
|
|
||||||
// 中国地区划分(V1.1+ 启用国家→地区→城市导航时使用)
|
|
||||||
export const chinaRegionPlan = [
|
|
||||||
{ id: 'north_china', name: '华北', cityIds: ['beijing', 'tianjin', 'shijiazhuang', 'taiyuan', 'hohhot'] },
|
|
||||||
{ id: 'northeast', name: '东北', cityIds: ['shenyang', 'changchun', 'harbin', 'dalian'] },
|
|
||||||
{ id: 'east_china', name: '华东', cityIds: ['shanghai', 'nanjing', 'hangzhou', 'hefei', 'fuzhou', 'nanchang', 'jinan', 'suzhou', 'xiamen', 'qingdao', 'ningbo'] },
|
|
||||||
{ id: 'central_china', name: '华中', cityIds: ['zhengzhou', 'wuhan', 'changsha'] },
|
|
||||||
{ id: 'south_china', name: '华南', cityIds: ['guangzhou', 'shenzhen', 'nanning', 'haikou', 'sanya'] },
|
|
||||||
{ id: 'southwest', name: '西南', cityIds: ['chengdu', 'chongqing', 'guiyang', 'kunming', 'lhasa'] },
|
|
||||||
{ id: 'northwest', name: '西北', cityIds: ['xian', 'lanzhou', 'xining', 'yinchuan', 'urumqi'] },
|
|
||||||
{ id: 'hk_macao_tw', name: '港澳台', cityIds: ['hongkong', 'macao', 'taipei'] },
|
|
||||||
]
|
|
||||||
|
|
||||||
// 全部亚洲国家(V1.1+ 启用)
|
|
||||||
export const asiaCountryPlan = [
|
|
||||||
{ id: 'china', name: '中国', hasRegions: true, totalCities: 41 },
|
|
||||||
{ id: 'japan', name: '日本', cityIds: ['tokyo', 'osaka', 'kyoto', 'sapporo'] },
|
|
||||||
{ id: 'korea', name: '韩国', cityIds: ['seoul', 'busan', 'jeju'] },
|
|
||||||
{ id: 'thailand', name: '泰国', cityIds: ['bangkok', 'chiangmai', 'phuket'] },
|
|
||||||
{ id: 'singapore_country', name: '新加坡', cityIds: ['singapore'] },
|
|
||||||
{ id: 'vietnam', name: '越南', cityIds: ['hanoi', 'hochiminh'] },
|
|
||||||
{ id: 'malaysia', name: '马来西亚', cityIds: ['kualalumpur', 'malacca'] },
|
|
||||||
{ id: 'indonesia', name: '印度尼西亚', cityIds: ['jakarta', 'bali'] },
|
|
||||||
{ id: 'philippines', name: '菲律宾', cityIds: ['manila'] },
|
|
||||||
{ id: 'india', name: '印度', cityIds: ['delhi', 'mumbai'] },
|
|
||||||
{ id: 'uae', name: '阿联酋', cityIds: ['dubai'] },
|
|
||||||
{ id: 'turkey', name: '土耳其', cityIds: ['istanbul'] },
|
|
||||||
{ id: 'israel', name: '以色列', cityIds: ['jerusalem'] },
|
|
||||||
{ id: 'nepal', name: '尼泊尔', cityIds: ['kathmandu'] },
|
|
||||||
{ id: 'cambodia', name: '柬埔寨', cityIds: ['siemreap'] },
|
|
||||||
{ id: 'sri_lanka', name: '斯里兰卡', cityIds: ['colombo'] },
|
|
||||||
{ id: 'myanmar', name: '缅甸', cityIds: ['yangon'] },
|
|
||||||
{ id: 'mongolia', name: '蒙古', cityIds: ['ulaanbaatar'] },
|
|
||||||
]
|
|
||||||
@@ -15,15 +15,16 @@
|
|||||||
* @property {'country'|'region'|'city'|null} childType - 子节点类型
|
* @property {'country'|'region'|'city'|null} childType - 子节点类型
|
||||||
* @property {string[]} childIds - 当前可消费的子节点 id(仅已启用的)
|
* @property {string[]} childIds - 当前可消费的子节点 id(仅已启用的)
|
||||||
* @property {number} pageSize - 每页格子数,默认 9
|
* @property {number} pageSize - 每页格子数,默认 9
|
||||||
* @property {boolean} isEnabled - 当前版本是否启用
|
* @property {'active'|'planned'} status - 'active'(当前可运行)/ 'planned'(未来规划)
|
||||||
* @property {boolean} isUnlockedByDefault - 是否默认解锁
|
* @property {boolean} isUnlockedByDefault - 是否默认解锁
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// schema 验证函数
|
// schema 验证函数
|
||||||
export function validateNavNode(node) {
|
export function validateNavNode(node) {
|
||||||
const required = ['type', 'id', 'name', 'nameEn', 'sortOrder', 'themeColor', 'childType', 'childIds', 'pageSize', 'isEnabled', 'isUnlockedByDefault']
|
const required = ['type', 'id', 'name', 'nameEn', 'sortOrder', 'themeColor', 'childType', 'childIds', 'pageSize', 'status', 'isUnlockedByDefault']
|
||||||
const validTypes = ['continent', 'country', 'region', 'city-group']
|
const validTypes = ['continent', 'country', 'region', 'city-group']
|
||||||
const validChildTypes = ['country', 'region', 'city', null]
|
const validChildTypes = ['country', 'region', 'city', null]
|
||||||
|
const validStatuses = ['active', 'planned']
|
||||||
|
|
||||||
const errors = []
|
const errors = []
|
||||||
for (const key of required) {
|
for (const key of required) {
|
||||||
@@ -33,5 +34,6 @@ export function validateNavNode(node) {
|
|||||||
if (!validChildTypes.includes(node.childType)) errors.push(`invalid childType: ${node.childType}`)
|
if (!validChildTypes.includes(node.childType)) errors.push(`invalid childType: ${node.childType}`)
|
||||||
if (!Array.isArray(node.childIds)) errors.push('childIds must be array')
|
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 (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
|
return errors
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,110 +1,42 @@
|
|||||||
/**
|
/**
|
||||||
* Runtime Navigation — MVP
|
* Runtime Navigation — 从 world-catalog 自动生成
|
||||||
*
|
*
|
||||||
* 只包含当前版本已启用、childIds 均指向已存在实体的节点。
|
* 只包含 status === 'active' 的节点。
|
||||||
* MVP 导航:直入亚洲城市页,6 城市平铺。
|
* MVP 阶段手动覆写亚洲的 childType 为 'city'(跳过国家层),
|
||||||
* V1.1+ 启用完整洲→国家→地区→城市多级导航时,在此文件追加节点。
|
* V1.1+ 切换为 catalog 默认的 'country'。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const runtimeNavNodes = [
|
import { worldCatalog } from './world-catalog.js'
|
||||||
// ── MVP: 只有 1 个洲,直接列出 6 城市 ──
|
|
||||||
{
|
// MVP 覆写:亚洲直接指向城市,不经过国家层
|
||||||
type: 'continent',
|
const MVP_OVERRIDES = {
|
||||||
id: 'asia',
|
asia: {
|
||||||
parentId: null,
|
childType: 'city',
|
||||||
name: '亚洲',
|
|
||||||
nameEn: 'Asia',
|
|
||||||
sortOrder: 1,
|
|
||||||
themeColor: '#FF6B6B',
|
|
||||||
childType: 'city', // MVP: 直接指向城市,跳过国家层
|
|
||||||
childIds: ['beijing', 'tokyo', 'bangkok', 'seoul', 'singapore', 'istanbul'],
|
childIds: ['beijing', 'tokyo', 'bangkok', 'seoul', 'singapore', 'istanbul'],
|
||||||
pageSize: 9,
|
|
||||||
isEnabled: true,
|
|
||||||
isUnlockedByDefault: true,
|
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// ── 未启用的洲(占位,UI 显示锁定态) ──
|
function buildRuntimeNav() {
|
||||||
{
|
const activeNodes = worldCatalog.filter(n => n.status === 'active')
|
||||||
type: 'continent',
|
return activeNodes.map(node => {
|
||||||
id: 'europe',
|
const override = MVP_OVERRIDES[node.id]
|
||||||
parentId: null,
|
if (override) {
|
||||||
name: '欧洲',
|
return { ...node, ...override }
|
||||||
nameEn: 'Europe',
|
}
|
||||||
sortOrder: 2,
|
return { ...node }
|
||||||
themeColor: '#6B8CFF',
|
})
|
||||||
childType: 'country',
|
}
|
||||||
childIds: [], // 无可消费子节点
|
|
||||||
pageSize: 9,
|
export const runtimeNavNodes = buildRuntimeNav()
|
||||||
isEnabled: false,
|
|
||||||
isUnlockedByDefault: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'continent',
|
|
||||||
id: 'north_america',
|
|
||||||
parentId: null,
|
|
||||||
name: '北美洲',
|
|
||||||
nameEn: 'North America',
|
|
||||||
sortOrder: 3,
|
|
||||||
themeColor: '#FFB347',
|
|
||||||
childType: 'country',
|
|
||||||
childIds: [],
|
|
||||||
pageSize: 9,
|
|
||||||
isEnabled: false,
|
|
||||||
isUnlockedByDefault: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'continent',
|
|
||||||
id: 'south_america',
|
|
||||||
parentId: null,
|
|
||||||
name: '南美洲',
|
|
||||||
nameEn: 'South America',
|
|
||||||
sortOrder: 4,
|
|
||||||
themeColor: '#4ECDC4',
|
|
||||||
childType: 'country',
|
|
||||||
childIds: [],
|
|
||||||
pageSize: 9,
|
|
||||||
isEnabled: false,
|
|
||||||
isUnlockedByDefault: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'continent',
|
|
||||||
id: 'africa',
|
|
||||||
parentId: null,
|
|
||||||
name: '非洲',
|
|
||||||
nameEn: 'Africa',
|
|
||||||
sortOrder: 5,
|
|
||||||
themeColor: '#F7DC6F',
|
|
||||||
childType: 'country',
|
|
||||||
childIds: [],
|
|
||||||
pageSize: 9,
|
|
||||||
isEnabled: false,
|
|
||||||
isUnlockedByDefault: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'continent',
|
|
||||||
id: 'oceania',
|
|
||||||
parentId: null,
|
|
||||||
name: '大洋洲',
|
|
||||||
nameEn: 'Oceania',
|
|
||||||
sortOrder: 6,
|
|
||||||
themeColor: '#82E0AA',
|
|
||||||
childType: 'country',
|
|
||||||
childIds: [],
|
|
||||||
pageSize: 9,
|
|
||||||
isEnabled: false,
|
|
||||||
isUnlockedByDefault: false,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
// ── 便捷查询 ──
|
|
||||||
export function getNavNode(id) {
|
export function getNavNode(id) {
|
||||||
return runtimeNavNodes.find(n => n.id === id) || null
|
return runtimeNavNodes.find(n => n.id === id) || null
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEnabledRoots() {
|
export function getEnabledRoots() {
|
||||||
return runtimeNavNodes.filter(n => n.parentId === null && n.isEnabled)
|
return runtimeNavNodes.filter(n => n.parentId === null)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getChildren(parentId) {
|
export function getChildren(parentId) {
|
||||||
return runtimeNavNodes.filter(n => n.parentId === parentId && n.isEnabled)
|
return runtimeNavNodes.filter(n => n.parentId === parentId)
|
||||||
}
|
}
|
||||||
|
|||||||
164
js/content/navigation/world-catalog.js
Normal file
164
js/content/navigation/world-catalog.js
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
/**
|
||||||
|
* World Catalog — 全量世界导航规划
|
||||||
|
*
|
||||||
|
* 所有节点使用统一 NavNode schema。
|
||||||
|
* status: 'active' = 当前版本可运行(有对应真实内容)
|
||||||
|
* status: 'planned' = 未来版本规划(无对应内容,不进入 runtime)
|
||||||
|
*
|
||||||
|
* 扩展新城市时:
|
||||||
|
* 1. 创建城市 CityManifest 文件
|
||||||
|
* 2. 将对应节点 status 改为 'active'
|
||||||
|
* 3. runtime-nav.js 会自动过滤出 active 节点
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const worldCatalog = [
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
// 洲级
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
{
|
||||||
|
type: 'continent', id: 'asia', parentId: null,
|
||||||
|
name: '亚洲', nameEn: 'Asia', sortOrder: 1, themeColor: '#FF6B6B',
|
||||||
|
childType: 'country',
|
||||||
|
childIds: ['china', 'japan', 'korea', 'thailand', 'singapore_country', 'vietnam', 'malaysia', 'indonesia', 'philippines', 'india', 'uae', 'turkey', 'israel', 'nepal', 'cambodia', 'sri_lanka', 'myanmar', 'mongolia'],
|
||||||
|
pageSize: 9, status: 'active', isUnlockedByDefault: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'continent', id: 'europe', parentId: null,
|
||||||
|
name: '欧洲', nameEn: 'Europe', sortOrder: 2, themeColor: '#6B8CFF',
|
||||||
|
childType: 'country',
|
||||||
|
childIds: ['france', 'uk', 'italy', 'spain', 'germany', 'netherlands', 'switzerland', 'austria', 'czech', 'greece', 'russia', 'portugal', 'norway', 'sweden', 'denmark', 'finland', 'iceland', 'hungary'],
|
||||||
|
pageSize: 9, status: 'planned', isUnlockedByDefault: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'continent', id: 'north_america', parentId: null,
|
||||||
|
name: '北美洲', nameEn: 'North America', sortOrder: 3, themeColor: '#FFB347',
|
||||||
|
childType: 'country',
|
||||||
|
childIds: ['usa', 'canada', 'mexico'],
|
||||||
|
pageSize: 9, status: 'planned', isUnlockedByDefault: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'continent', id: 'south_america', parentId: null,
|
||||||
|
name: '南美洲', nameEn: 'South America', sortOrder: 4, themeColor: '#4ECDC4',
|
||||||
|
childType: 'country',
|
||||||
|
childIds: ['brazil', 'argentina', 'peru', 'chile', 'colombia'],
|
||||||
|
pageSize: 9, status: 'planned', isUnlockedByDefault: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'continent', id: 'africa', parentId: null,
|
||||||
|
name: '非洲', nameEn: 'Africa', sortOrder: 5, themeColor: '#F7DC6F',
|
||||||
|
childType: 'country',
|
||||||
|
childIds: ['egypt', 'south_africa', 'morocco', 'kenya'],
|
||||||
|
pageSize: 9, status: 'planned', isUnlockedByDefault: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'continent', id: 'oceania', parentId: null,
|
||||||
|
name: '大洋洲', nameEn: 'Oceania', sortOrder: 6, themeColor: '#82E0AA',
|
||||||
|
childType: 'country',
|
||||||
|
childIds: ['australia', 'new_zealand'],
|
||||||
|
pageSize: 9, status: 'planned', isUnlockedByDefault: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
// 亚洲国家(18 国)
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
// MVP active: 中国/日本/韩国/泰国/新加坡/土耳其各有 1 个 active 城市
|
||||||
|
{ type: 'country', id: 'china', parentId: 'asia', name: '中国', nameEn: 'China', sortOrder: 1, themeColor: '#CC2936', childType: 'region', childIds: ['north_china', 'northeast', 'east_china', 'central_china', 'south_china', 'southwest', 'northwest', 'hk_macao_tw'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'japan', parentId: 'asia', name: '日本', nameEn: 'Japan', sortOrder: 2, themeColor: '#E84057', childType: 'city', childIds: ['tokyo', 'osaka', 'kyoto', 'sapporo'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'korea', parentId: 'asia', name: '韩国', nameEn: 'South Korea', sortOrder: 3, themeColor: '#4A90D9', childType: 'city', childIds: ['seoul', 'busan', 'jeju'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'thailand', parentId: 'asia', name: '泰国', nameEn: 'Thailand', sortOrder: 4, themeColor: '#FFB347', childType: 'city', childIds: ['bangkok', 'chiangmai', 'phuket'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'singapore_country', parentId: 'asia', name: '新加坡', nameEn: 'Singapore', sortOrder: 5, themeColor: '#00A896', childType: 'city', childIds: ['singapore'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'vietnam', parentId: 'asia', name: '越南', nameEn: 'Vietnam', sortOrder: 6, themeColor: '#E74C3C', childType: 'city', childIds: ['hanoi', 'hochiminh'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'malaysia', parentId: 'asia', name: '马来西亚', nameEn: 'Malaysia', sortOrder: 7, themeColor: '#3498DB', childType: 'city', childIds: ['kualalumpur', 'malacca'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'indonesia', parentId: 'asia', name: '印度尼西亚', nameEn: 'Indonesia', sortOrder: 8, themeColor: '#E67E22', childType: 'city', childIds: ['jakarta', 'bali'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'philippines', parentId: 'asia', name: '菲律宾', nameEn: 'Philippines', sortOrder: 9, themeColor: '#2ECC71', childType: 'city', childIds: ['manila'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'india', parentId: 'asia', name: '印度', nameEn: 'India', sortOrder: 10, themeColor: '#FF9933', childType: 'city', childIds: ['delhi', 'mumbai'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'uae', parentId: 'asia', name: '阿联酋', nameEn: 'UAE', sortOrder: 11, themeColor: '#C0A062', childType: 'city', childIds: ['dubai'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'turkey', parentId: 'asia', name: '土耳其', nameEn: 'Turkey', sortOrder: 12, themeColor: '#1A5276', childType: 'city', childIds: ['istanbul'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'israel', parentId: 'asia', name: '以色列', nameEn: 'Israel', sortOrder: 13, themeColor: '#5DADE2', childType: 'city', childIds: ['jerusalem'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'nepal', parentId: 'asia', name: '尼泊尔', nameEn: 'Nepal', sortOrder: 14, themeColor: '#DC143C', childType: 'city', childIds: ['kathmandu'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'cambodia', parentId: 'asia', name: '柬埔寨', nameEn: 'Cambodia', sortOrder: 15, themeColor: '#1E8449', childType: 'city', childIds: ['siemreap'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'sri_lanka', parentId: 'asia', name: '斯里兰卡', nameEn: 'Sri Lanka', sortOrder: 16, themeColor: '#8E44AD', childType: 'city', childIds: ['colombo'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'myanmar', parentId: 'asia', name: '缅甸', nameEn: 'Myanmar', sortOrder: 17, themeColor: '#F4D03F', childType: 'city', childIds: ['yangon'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'mongolia', parentId: 'asia', name: '蒙古', nameEn: 'Mongolia', sortOrder: 18, themeColor: '#2980B9', childType: 'city', childIds: ['ulaanbaatar'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
// 中国地区(8 区)
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
{ type: 'region', id: 'north_china', parentId: 'china', name: '华北', nameEn: 'North China', sortOrder: 1, themeColor: '#CC2936', childType: 'city', childIds: ['beijing', 'tianjin', 'shijiazhuang', 'taiyuan', 'hohhot'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'region', id: 'northeast', parentId: 'china', name: '东北', nameEn: 'Northeast', sortOrder: 2, themeColor: '#5DADE2', childType: 'city', childIds: ['shenyang', 'changchun', 'harbin', 'dalian'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'region', id: 'east_china', parentId: 'china', name: '华东', nameEn: 'East China', sortOrder: 3, themeColor: '#2ECC71', childType: 'city', childIds: ['shanghai', 'nanjing', 'hangzhou', 'hefei', 'fuzhou', 'nanchang', 'jinan', 'suzhou', 'xiamen', 'qingdao', 'ningbo'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'region', id: 'central_china', parentId: 'china', name: '华中', nameEn: 'Central China', sortOrder: 4, themeColor: '#E67E22', childType: 'city', childIds: ['zhengzhou', 'wuhan', 'changsha'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'region', id: 'south_china', parentId: 'china', name: '华南', nameEn: 'South China', sortOrder: 5, themeColor: '#FF6B6B', childType: 'city', childIds: ['guangzhou', 'shenzhen', 'nanning', 'haikou', 'sanya'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'region', id: 'southwest', parentId: 'china', name: '西南', nameEn: 'Southwest', sortOrder: 6, themeColor: '#9B59B6', childType: 'city', childIds: ['chengdu', 'chongqing', 'guiyang', 'kunming', 'lhasa'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'region', id: 'northwest', parentId: 'china', name: '西北', nameEn: 'Northwest', sortOrder: 7, themeColor: '#F4D03F', childType: 'city', childIds: ['xian', 'lanzhou', 'xining', 'yinchuan', 'urumqi'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'region', id: 'hk_macao_tw', parentId: 'china', name: '港澳台', nameEn: 'HK, Macao & Taiwan', sortOrder: 8, themeColor: '#E74C3C', childType: 'city', childIds: ['hongkong', 'macao', 'taipei'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
// 欧洲国家(18 国)
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
{ type: 'country', id: 'france', parentId: 'europe', name: '法国', nameEn: 'France', sortOrder: 1, themeColor: '#3B5998', childType: 'city', childIds: ['paris', 'nice'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'uk', parentId: 'europe', name: '英国', nameEn: 'United Kingdom', sortOrder: 2, themeColor: '#C0392B', childType: 'city', childIds: ['london', 'edinburgh'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'italy', parentId: 'europe', name: '意大利', nameEn: 'Italy', sortOrder: 3, themeColor: '#27AE60', childType: 'city', childIds: ['rome', 'milan', 'venice', 'florence'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'spain', parentId: 'europe', name: '西班牙', nameEn: 'Spain', sortOrder: 4, themeColor: '#E74C3C', childType: 'city', childIds: ['madrid', 'barcelona'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'germany', parentId: 'europe', name: '德国', nameEn: 'Germany', sortOrder: 5, themeColor: '#2C3E50', childType: 'city', childIds: ['berlin', 'munich'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'netherlands', parentId: 'europe', name: '荷兰', nameEn: 'Netherlands', sortOrder: 6, themeColor: '#FF6600', childType: 'city', childIds: ['amsterdam'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'switzerland', parentId: 'europe', name: '瑞士', nameEn: 'Switzerland', sortOrder: 7, themeColor: '#E74C3C', childType: 'city', childIds: ['zurich'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'austria', parentId: 'europe', name: '奥地利', nameEn: 'Austria', sortOrder: 8, themeColor: '#C0392B', childType: 'city', childIds: ['vienna'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'czech', parentId: 'europe', name: '捷克', nameEn: 'Czech Republic', sortOrder: 9, themeColor: '#2980B9', childType: 'city', childIds: ['prague'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'greece', parentId: 'europe', name: '希腊', nameEn: 'Greece', sortOrder: 10, themeColor: '#0D5EAF', childType: 'city', childIds: ['athens'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'russia', parentId: 'europe', name: '俄罗斯', nameEn: 'Russia', sortOrder: 11, themeColor: '#C0392B', childType: 'city', childIds: ['moscow', 'stpetersburg'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'portugal', parentId: 'europe', name: '葡萄牙', nameEn: 'Portugal', sortOrder: 12, themeColor: '#27AE60', childType: 'city', childIds: ['lisbon'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'norway', parentId: 'europe', name: '挪威', nameEn: 'Norway', sortOrder: 13, themeColor: '#2980B9', childType: 'city', childIds: ['oslo'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'sweden', parentId: 'europe', name: '瑞典', nameEn: 'Sweden', sortOrder: 14, themeColor: '#F1C40F', childType: 'city', childIds: ['stockholm'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'denmark', parentId: 'europe', name: '丹麦', nameEn: 'Denmark', sortOrder: 15, themeColor: '#C0392B', childType: 'city', childIds: ['copenhagen'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'finland', parentId: 'europe', name: '芬兰', nameEn: 'Finland', sortOrder: 16, themeColor: '#2980B9', childType: 'city', childIds: ['helsinki'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'iceland', parentId: 'europe', name: '冰岛', nameEn: 'Iceland', sortOrder: 17, themeColor: '#2C3E50', childType: 'city', childIds: ['reykjavik'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'hungary', parentId: 'europe', name: '匈牙利', nameEn: 'Hungary', sortOrder: 18, themeColor: '#27AE60', childType: 'city', childIds: ['budapest'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
// 北美国家(3 国)
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
{ type: 'country', id: 'usa', parentId: 'north_america', name: '美国', nameEn: 'United States', sortOrder: 1, themeColor: '#3B5998', childType: 'city', childIds: ['newyork', 'losangeles', 'sanfrancisco', 'lasvegas', 'washington', 'chicago', 'miami'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'canada', parentId: 'north_america', name: '加拿大', nameEn: 'Canada', sortOrder: 2, themeColor: '#E74C3C', childType: 'city', childIds: ['vancouver', 'toronto', 'montreal'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'mexico', parentId: 'north_america', name: '墨西哥', nameEn: 'Mexico', sortOrder: 3, themeColor: '#27AE60', childType: 'city', childIds: ['mexicocity', 'cancun'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
// 南美国家(5 国)
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
{ type: 'country', id: 'brazil', parentId: 'south_america', name: '巴西', nameEn: 'Brazil', sortOrder: 1, themeColor: '#F1C40F', childType: 'city', childIds: ['rio', 'saopaulo'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'argentina', parentId: 'south_america', name: '阿根廷', nameEn: 'Argentina', sortOrder: 2, themeColor: '#5DADE2', childType: 'city', childIds: ['buenosaires'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'peru', parentId: 'south_america', name: '秘鲁', nameEn: 'Peru', sortOrder: 3, themeColor: '#E74C3C', childType: 'city', childIds: ['lima', 'cusco'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'chile', parentId: 'south_america', name: '智利', nameEn: 'Chile', sortOrder: 4, themeColor: '#2980B9', childType: 'city', childIds: ['santiago'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'colombia', parentId: 'south_america', name: '哥伦比亚', nameEn: 'Colombia', sortOrder: 5, themeColor: '#F39C12', childType: 'city', childIds: ['bogota'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
// 非洲国家(4 国)
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
{ type: 'country', id: 'egypt', parentId: 'africa', name: '埃及', nameEn: 'Egypt', sortOrder: 1, themeColor: '#F39C12', childType: 'city', childIds: ['cairo'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'south_africa', parentId: 'africa', name: '南非', nameEn: 'South Africa', sortOrder: 2, themeColor: '#27AE60', childType: 'city', childIds: ['capetown'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'morocco', parentId: 'africa', name: '摩洛哥', nameEn: 'Morocco', sortOrder: 3, themeColor: '#E74C3C', childType: 'city', childIds: ['marrakech'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'kenya', parentId: 'africa', name: '肯尼亚', nameEn: 'Kenya', sortOrder: 4, themeColor: '#2C3E50', childType: 'city', childIds: ['nairobi', 'mombasa'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
// 大洋洲国家(2 国)
|
||||||
|
// ═══════════════════════════════════════
|
||||||
|
{ type: 'country', id: 'australia', parentId: 'oceania', name: '澳大利亚', nameEn: 'Australia', sortOrder: 1, themeColor: '#F39C12', childType: 'city', childIds: ['sydney', 'melbourne'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
{ type: 'country', id: 'new_zealand', parentId: 'oceania', name: '新西兰', nameEn: 'New Zealand', sortOrder: 2, themeColor: '#2C3E50', childType: 'city', childIds: ['auckland', 'queenstown'], pageSize: 9, status: 'planned', isUnlockedByDefault: false },
|
||||||
|
]
|
||||||
|
|
||||||
|
// ── 查询工具 ──
|
||||||
|
export function getCatalogNode(id) {
|
||||||
|
return worldCatalog.find(n => n.id === id) || null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCatalogChildren(parentId) {
|
||||||
|
return worldCatalog.filter(n => n.parentId === parentId).sort((a, b) => a.sortOrder - b.sortOrder)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getActiveNodes() {
|
||||||
|
return worldCatalog.filter(n => n.status === 'active')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPlannedNodes() {
|
||||||
|
return worldCatalog.filter(n => n.status === 'planned')
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @deprecated 中国地区数据已移入 navigation/future-catalog.js
|
* @deprecated 中国地区数据已移入 navigation/world-catalog.js
|
||||||
* 仅在 V1.1+ 启用国家→地区导航后使用。
|
* 仅在 V1.1+ 启用国家→地区导航后使用。
|
||||||
*/
|
*/
|
||||||
export { chinaRegionPlan as chinaRegions } from '../navigation/future-catalog.js'
|
import { getCatalogChildren } from '../navigation/world-catalog.js'
|
||||||
|
export const chinaRegions = getCatalogChildren('china')
|
||||||
|
|||||||
Reference in New Issue
Block a user