using System.Collections.Concurrent; namespace AgriculturalPlatform.Api.Services; /// 手机传图上传会话(内存存储,10 分钟过期) public sealed class MobileUploadSession { public string Code { get; init; } = string.Empty; public DateTime CreatedAt { get; init; } = DateTime.Now; public StoredFile? Front { get; set; } public StoredFile? Back { get; set; } public IdCardOcrResult? FrontOcr { get; set; } public IdCardOcrResult? BackOcr { get; set; } public bool Done { get; set; } } /// 手机传图上传会话存储(单机内存版,后续可换 Redis) public sealed class MobileUploadSessionStore { private static readonly TimeSpan Expire = TimeSpan.FromMinutes(10); private readonly ConcurrentDictionary _sessions = new(); public string Create() { Cleanup(); var code = Guid.NewGuid().ToString("N")[..8].ToUpperInvariant(); _sessions[code] = new MobileUploadSession { Code = code }; return code; } public MobileUploadSession? Get(string code) { if (string.IsNullOrWhiteSpace(code)) return null; return _sessions.TryGetValue(code.Trim().ToUpperInvariant(), out var s) ? s : null; } public void Remove(string code) => _sessions.TryRemove(code, out _); private void Cleanup() { var now = DateTime.Now; foreach (var kv in _sessions) { if (now - kv.Value.CreatedAt > Expire) _sessions.TryRemove(kv.Key, out _); } } }