using BoardApp.Config;
|
|
namespace BoardApp.Services;
|
|
public sealed class ScenarioService
|
{
|
private readonly BoardConfigLoader _cfg;
|
|
public ScenarioService(BoardConfigLoader cfg)
|
{
|
_cfg = cfg;
|
}
|
|
public sealed record HomeScenario(string Id, string Name, string Image);
|
public sealed record HomeCategory(string Id, string Name, List<HomeScenario> Scenarios);
|
|
public enum ScenarioSource
|
{
|
System,
|
User
|
}
|
|
public static string ToScenarioKey(ScenarioSource source, string scenarioId)
|
=> (source == ScenarioSource.System ? "s:" : "u:") + scenarioId;
|
|
public sealed record ScenarioKeyParts(ScenarioSource Source, string ScenarioId);
|
|
public static ScenarioKeyParts ParseScenarioKey(string input)
|
{
|
var raw = (input ?? "").Trim();
|
if (raw.StartsWith("s:")) return new ScenarioKeyParts(ScenarioSource.System, raw[2..]);
|
if (raw.StartsWith("u:")) return new ScenarioKeyParts(ScenarioSource.User, raw[2..]);
|
return new ScenarioKeyParts(ScenarioSource.System, raw);
|
}
|
|
private Dictionary<string, PageDef> PageMap()
|
{
|
var cfg = _cfg.LoadPagesConfig();
|
var map = new Dictionary<string, PageDef>(StringComparer.Ordinal);
|
foreach (var p in cfg.Pages)
|
{
|
map[p.Id] = p;
|
}
|
return map;
|
}
|
|
public List<HomeCategory> LoadHomeCatalogForUser(string username)
|
{
|
var pagesById = PageMap();
|
var sys = _cfg.LoadSystemScenariosConfig();
|
var users = _cfg.LoadUserScenariosConfig();
|
users.Users.TryGetValue(username, out var u);
|
var userScenarios = u?.Scenarios ?? new List<UserScenario>();
|
|
var sysCats = sys.Categories.Select(c => new HomeCategory(
|
c.Id,
|
c.Name,
|
(c.Scenarios ?? new List<SystemScenario>())
|
.Select(s => new HomeScenario(ToScenarioKey(ScenarioSource.System, s.Id), s.Name, s.Image))
|
.ToList()
|
)).ToList();
|
|
var my = new HomeCategory(
|
"my",
|
"我的场景",
|
userScenarios.Select(s =>
|
{
|
var img = s.Image;
|
if (string.IsNullOrWhiteSpace(img))
|
{
|
var first = s.Pages.FirstOrDefault();
|
if (first is not null && pagesById.TryGetValue(first.PageId, out var pd))
|
{
|
img = pd.Image;
|
}
|
}
|
return new HomeScenario(ToScenarioKey(ScenarioSource.User, s.Id), s.Name, img ?? "");
|
}).ToList()
|
);
|
|
return my.Scenarios.Count > 0 ? new List<HomeCategory> { my }.Concat(sysCats).ToList() : sysCats;
|
}
|
|
public Dictionary<string, string> BuildScenarioImageMapForUser(string username)
|
{
|
var map = new Dictionary<string, string>(StringComparer.Ordinal);
|
var cats = LoadHomeCatalogForUser(username);
|
foreach (var c in cats)
|
{
|
foreach (var s in c.Scenarios)
|
{
|
map[s.Id] = s.Image;
|
}
|
}
|
return map;
|
}
|
|
public sealed record ScenarioPage(string Id, string Title, string BoardUrl, int Staytime);
|
public sealed record Scenario(string Id, string Name, string Image, List<ScenarioPage> Pages);
|
|
public sealed record ResolvedScenario(ScenarioSource Source, Scenario Scenario);
|
|
private static List<ScenarioPage> ExpandPages(IEnumerable<ScenarioPageRef> refs, Dictionary<string, PageDef> pagesById)
|
{
|
var list = new List<ScenarioPage>();
|
foreach (var r in refs)
|
{
|
if (r is null) continue;
|
if (!pagesById.TryGetValue(r.PageId, out var def)) continue;
|
list.Add(new ScenarioPage(def.Id, def.Title, def.BoardUrl, r.Staytime));
|
}
|
return list;
|
}
|
|
public ResolvedScenario? ResolveScenarioForUser(string username, string scenarioKey)
|
{
|
var pagesById = PageMap();
|
var key = ParseScenarioKey(scenarioKey);
|
|
if (key.Source == ScenarioSource.System)
|
{
|
var sys = _cfg.LoadSystemScenariosConfig();
|
foreach (var cat in sys.Categories)
|
{
|
foreach (var sc in cat.Scenarios)
|
{
|
if (!string.Equals(sc.Id, key.ScenarioId, StringComparison.Ordinal)) continue;
|
var pages = ExpandPages(sc.Pages, pagesById);
|
return new ResolvedScenario(
|
ScenarioSource.System,
|
new Scenario(ToScenarioKey(ScenarioSource.System, sc.Id), sc.Name, sc.Image, pages)
|
);
|
}
|
}
|
return null;
|
}
|
|
var users = _cfg.LoadUserScenariosConfig();
|
if (!users.Users.TryGetValue(username, out var u)) return null;
|
var mine = u.Scenarios ?? new List<UserScenario>();
|
var usc = mine.FirstOrDefault(x => string.Equals(x.Id, key.ScenarioId, StringComparison.Ordinal));
|
if (usc is null) return null;
|
var upages = ExpandPages(usc.Pages, pagesById);
|
return new ResolvedScenario(
|
ScenarioSource.User,
|
new Scenario(ToScenarioKey(ScenarioSource.User, usc.Id), usc.Name, usc.Image, upages)
|
);
|
}
|
}
|
|