- 核心业务拆分为 Endpoint → Application Service → Repository 三层 - AI写入操作必须用户确认后才写库(确认卡片机制) - 报告/饮食/用药分析改为持久化任务队列(原子领取/重试/重启恢复) - 运动计划修复: 连续真实日期替代周模板 - 用药提醒去重 + 通知Outbox预留 - 认证收拢到AuthService, 管理员收拢到AdminService - AI会话加用户归属校验防串号 - 提示词调整为患者视角 - 开发假数据已关闭 - 21/21测试通过, 0警告0错误
39 lines
1.4 KiB
C#
39 lines
1.4 KiB
C#
using Health.Application.Medications;
|
|
|
|
namespace Health.WebApi.BackgroundServices;
|
|
|
|
public sealed class MedicationReminderService(
|
|
IServiceScopeFactory scopeFactory,
|
|
ILogger<MedicationReminderService> logger) : BackgroundService
|
|
{
|
|
private readonly IServiceScopeFactory _scopeFactory = scopeFactory;
|
|
private readonly ILogger<MedicationReminderService> _logger = logger;
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
_logger.LogInformation("用药提醒扫描生产者已启动");
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
using var scope = _scopeFactory.CreateScope();
|
|
var scanner = scope.ServiceProvider.GetRequiredService<IMedicationReminderScanner>();
|
|
var queue = scope.ServiceProvider.GetRequiredService<IMedicationReminderQueue>();
|
|
var tasks = await scanner.ScanAsync(DateTime.UtcNow, stoppingToken);
|
|
foreach (var task in tasks)
|
|
await queue.EnqueueAsync(task, stoppingToken);
|
|
}
|
|
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "用药提醒扫描异常");
|
|
}
|
|
|
|
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
|
|
}
|
|
}
|
|
}
|