wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import type { PageDef, ScenarioPageRef, UserScenario, UserScenariosConfig } from "../config/types.js";
import { loadPagesConfig, loadUserScenariosConfig, writeUserScenariosConfig } from "../config/loadConfig.js";
 
export const STAYTIME_MIN = 5;
export const STAYTIME_MAX = 86400;
 
function isValidStaytime(n: number): boolean {
  return Number.isInteger(n) && n >= STAYTIME_MIN && n <= STAYTIME_MAX;
}
 
function pagesById(): Record<string, PageDef> {
  const cfg = loadPagesConfig();
  const map: Record<string, PageDef> = {};
  for (const p of cfg.pages) {
    map[p.id] = p;
  }
  return map;
}
 
function ensureUser(cfg: UserScenariosConfig, username: string): void {
  if (!cfg.users[username]) {
    cfg.users[username] = { scenarios: [] };
  }
}
 
function newScenarioId(): string {
  const rnd = Math.random().toString(36).slice(2, 10);
  return `u_${Date.now()}_${rnd}`;
}
 
export function listUserScenarios(username: string): UserScenario[] {
  const cfg = loadUserScenariosConfig();
  return cfg.users[username]?.scenarios ?? [];
}
 
export function deleteUserScenario(
  username: string,
  scenarioId: string
): { ok: true } | { ok: false; error: string } {
  const cfg = loadUserScenariosConfig();
  ensureUser(cfg, username);
  const before = cfg.users[username].scenarios.length;
  cfg.users[username].scenarios = cfg.users[username].scenarios.filter(
    (s) => s.id !== scenarioId
  );
  if (cfg.users[username].scenarios.length === before) {
    return { ok: false, error: "未找到该场景" };
  }
  writeUserScenariosConfig(cfg);
  return { ok: true };
}
 
export function createUserScenario(
  username: string,
  name: string,
  pageRefs: ScenarioPageRef[]
): { ok: true; scenario: UserScenario } | { ok: false; error: string } {
  const nm = String(name ?? "").trim();
  if (!nm) {
    return { ok: false, error: "场景名称不能为空" };
  }
  if (!Array.isArray(pageRefs) || !pageRefs.length) {
    return { ok: false, error: "至少选择 1 个 page" };
  }
 
  const pages = pagesById();
  for (const r of pageRefs) {
    if (!r?.pageId || !pages[r.pageId]) {
      return { ok: false, error: `pageId 不存在:${String(r?.pageId ?? "")}` };
    }
    if (!isValidStaytime(r.staytime)) {
      return {
        ok: false,
        error: `停留时间须为 ${STAYTIME_MIN}~${STAYTIME_MAX} 的整数(秒)`,
      };
    }
  }
 
  const cfg = loadUserScenariosConfig();
  ensureUser(cfg, username);
  const exists = cfg.users[username].scenarios.some((s) => s.name === nm);
  if (exists) {
    return { ok: false, error: "该用户下已存在同名场景" };
  }
 
  const firstPage = pages[pageRefs[0].pageId];
  const scenario: UserScenario = {
    id: newScenarioId(),
    name: nm,
    image: firstPage?.image ?? "",
    pages: pageRefs,
    createdAtMs: Date.now(),
  };
  cfg.users[username].scenarios.unshift(scenario);
  writeUserScenariosConfig(cfg);
  return { ok: true, scenario };
}