import type {
|
PageDef,
|
Scenario,
|
ScenarioCategory,
|
ScenarioPage,
|
ScenarioPageRef,
|
SystemScenario,
|
SystemScenarioCategory,
|
UserScenario,
|
} from "../config/types.js";
|
import {
|
loadPagesConfig,
|
loadSystemScenariosConfig,
|
loadUserScenariosConfig,
|
} from "../config/loadConfig.js";
|
|
export type ScenarioKey = string;
|
|
export type ScenarioSource = "system" | "user";
|
|
export type ScenarioKeyParts =
|
| { source: "system"; scenarioId: string }
|
| { source: "user"; scenarioId: string };
|
|
export function toScenarioKey(source: ScenarioSource, scenarioId: string): ScenarioKey {
|
return (source === "system" ? "s:" : "u:") + scenarioId;
|
}
|
|
export function parseScenarioKey(input: string): ScenarioKeyParts {
|
const raw = String(input || "").trim();
|
if (raw.startsWith("s:")) return { source: "system", scenarioId: raw.slice(2) };
|
if (raw.startsWith("u:")) return { source: "user", scenarioId: raw.slice(2) };
|
// 兼容旧链接:不带前缀的都视为 system
|
return { source: "system", scenarioId: raw };
|
}
|
|
function pageMap(): Record<string, PageDef> {
|
const cfg = loadPagesConfig();
|
const map: Record<string, PageDef> = {};
|
for (const p of cfg.pages) {
|
map[p.id] = p;
|
}
|
return map;
|
}
|
|
function expandPages(refs: ScenarioPageRef[], pagesById: Record<string, PageDef>): ScenarioPage[] {
|
return refs
|
.map((r) => {
|
const def = pagesById[r.pageId];
|
if (!def) return null;
|
return {
|
id: def.id,
|
title: def.title,
|
boardUrl: def.boardUrl,
|
staytime: r.staytime,
|
} satisfies ScenarioPage;
|
})
|
.filter((x): x is ScenarioPage => x !== null);
|
}
|
|
export type HomeScenario = {
|
id: ScenarioKey;
|
name: string;
|
image: string;
|
};
|
|
export type HomeCategory = {
|
id: string;
|
name: string;
|
scenarios: HomeScenario[];
|
};
|
|
export function loadHomeCatalogForUser(username: string): HomeCategory[] {
|
const pagesById = pageMap();
|
const sys = loadSystemScenariosConfig();
|
const users = loadUserScenariosConfig();
|
const userScenarios = users.users[username]?.scenarios ?? [];
|
|
const sysCats: HomeCategory[] = (sys.categories ?? []).map(
|
(c: SystemScenarioCategory) => ({
|
id: c.id,
|
name: c.name,
|
scenarios: (c.scenarios ?? []).map((s: SystemScenario) => ({
|
id: toScenarioKey("system", s.id),
|
name: s.name,
|
image: s.image,
|
})),
|
}));
|
|
const my: HomeCategory = {
|
id: "my",
|
name: "我的场景",
|
scenarios: userScenarios.map((s: UserScenario) => ({
|
id: toScenarioKey("user", s.id),
|
name: s.name,
|
image: s.image || (pagesById[s.pages[0]?.pageId]?.image ?? ""),
|
})),
|
};
|
|
return my.scenarios.length ? [my, ...sysCats] : sysCats;
|
}
|
|
export function buildScenarioImageMapForUser(username: string): Record<string, string> {
|
const map: Record<string, string> = {};
|
const cats = loadHomeCatalogForUser(username);
|
for (const c of cats) {
|
for (const s of c.scenarios) {
|
map[s.id] = s.image;
|
}
|
}
|
return map;
|
}
|
|
export type ResolvedScenario = {
|
source: ScenarioSource;
|
scenario: Scenario;
|
};
|
|
export function resolveScenarioForUser(
|
username: string,
|
scenarioKey: string
|
): ResolvedScenario | null {
|
const pagesById = pageMap();
|
const key = parseScenarioKey(scenarioKey);
|
|
if (key.source === "system") {
|
const sys = loadSystemScenariosConfig();
|
for (const cat of sys.categories) {
|
for (const sc of cat.scenarios) {
|
if (sc.id !== key.scenarioId) continue;
|
const pages = expandPages(sc.pages, pagesById);
|
return {
|
source: "system",
|
scenario: {
|
id: toScenarioKey("system", sc.id),
|
name: sc.name,
|
image: sc.image,
|
pages,
|
},
|
};
|
}
|
}
|
return null;
|
}
|
|
const users = loadUserScenariosConfig();
|
const mine = users.users[username]?.scenarios ?? [];
|
const sc = mine.find((x) => x.id === key.scenarioId);
|
if (!sc) return null;
|
const pages = expandPages(sc.pages, pagesById);
|
return {
|
source: "user",
|
scenario: {
|
id: toScenarioKey("user", sc.id),
|
name: sc.name,
|
image: sc.image,
|
pages,
|
},
|
};
|
}
|
|
/** 仅用于 view 的 slide 构建(boardUrl 在路由里再拼 dataEasePublicBase) */
|
export function scenarioToSlides(sc: Scenario): Array<{
|
id: string;
|
title: string;
|
staytime: number;
|
boardUrl: string;
|
}> {
|
return sc.pages.map((p) => ({
|
id: p.id,
|
title: p.title,
|
staytime: p.staytime,
|
boardUrl: p.boardUrl,
|
}));
|
}
|
|