43 lines
1.7 KiB
C#
43 lines
1.7 KiB
C#
using System.Text.Json;
|
|
|
|
namespace WxAgent.Service;
|
|
|
|
public sealed record AccountBinding(string AccountId, int ProcessId, long WindowHandle, string? WechatId, string Nickname, DateTimeOffset BoundAt);
|
|
public sealed record UiTargetInfo(string TargetId, int ProcessId, long WindowHandle, string? Title, string? WechatId, string? Nickname, bool IsBound);
|
|
|
|
public sealed class AccountBindingStore(ServiceOptions options)
|
|
{
|
|
private readonly string path = Path.Combine(options.DataDirectory, "account-bindings.json");
|
|
private readonly object gate = new();
|
|
|
|
public IReadOnlyList<AccountBinding> ReadAll()
|
|
{
|
|
lock (gate)
|
|
{
|
|
if (!File.Exists(path)) return [];
|
|
try { return JsonSerializer.Deserialize<AccountBinding[]>(File.ReadAllText(path), ServiceHost.Json) ?? []; }
|
|
catch (JsonException) { return []; }
|
|
}
|
|
}
|
|
|
|
public AccountBinding? Get(string accountId)
|
|
{
|
|
var matches = ReadAll().Where(x => string.Equals(x.AccountId, accountId, StringComparison.OrdinalIgnoreCase)).ToArray();
|
|
return matches.Length == 1 ? matches[0] : null;
|
|
}
|
|
|
|
public void Replace(IEnumerable<AccountBinding> bindings)
|
|
{
|
|
var items = bindings.GroupBy(x => x.AccountId, StringComparer.OrdinalIgnoreCase).Select(x => x.Last()).ToArray();
|
|
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
|
|
lock (gate)
|
|
{
|
|
var temp = path + ".tmp";
|
|
File.WriteAllText(temp, JsonSerializer.Serialize(items, ServiceHost.Json));
|
|
File.Move(temp, path, true);
|
|
}
|
|
}
|
|
|
|
public void Remove(string accountId) => Replace(ReadAll().Where(x => !string.Equals(x.AccountId, accountId, StringComparison.OrdinalIgnoreCase)));
|
|
}
|