- 新增用户通知 outbox 流水线(EfUserNotificationPipeline)与后台投递 worker - 通知中心页面及前端通知服务接入 - 健康指标异常、用药/运动提醒等事件统一产出站内通知 - 健康档案结构化手术史、用药提醒扫描、医生/用户端点等配套调整 - AppDbContext 注册通知相关实体
69 lines
3.0 KiB
C#
69 lines
3.0 KiB
C#
using System.Text;
|
||
using Health.Application.HealthArchives;
|
||
using Health.Application.HealthRecords;
|
||
using Health.Application.Medications;
|
||
|
||
namespace Health.Application.AI;
|
||
|
||
public sealed class PatientContextService(
|
||
IHealthArchiveService archives,
|
||
IHealthRecordService healthRecords,
|
||
IMedicationService medications) : IPatientContextService
|
||
{
|
||
private readonly IHealthArchiveService _archives = archives;
|
||
private readonly IHealthRecordService _healthRecords = healthRecords;
|
||
private readonly IMedicationService _medications = medications;
|
||
|
||
public async Task<string> BuildAsync(Guid userId, CancellationToken ct)
|
||
{
|
||
var archive = await _archives.GetAsync(userId, ct);
|
||
var recentRecords = (await _healthRecords.GetRecordsAsync(userId, null, 30, ct)).Take(10).ToList();
|
||
var activeMedications = await _medications.ListActiveAsync(userId, ct);
|
||
|
||
var sb = new StringBuilder();
|
||
if (archive != null)
|
||
{
|
||
if (!string.IsNullOrEmpty(archive.Diagnosis)) sb.AppendLine($"诊断: {archive.Diagnosis}");
|
||
if (archive.Surgeries.Count > 0)
|
||
sb.AppendLine($"手术: {string.Join(";", archive.Surgeries.Select(s => $"{s.Type} ({s.Date})"))}");
|
||
else if (!string.IsNullOrEmpty(archive.SurgeryType))
|
||
sb.AppendLine($"手术: {archive.SurgeryType} ({archive.SurgeryDate})");
|
||
if (archive.ChronicDiseases.Count > 0) sb.AppendLine($"慢病史: {string.Join(", ", archive.ChronicDiseases)}");
|
||
if (!string.IsNullOrEmpty(archive.FamilyHistory)) sb.AppendLine($"家族病史: {archive.FamilyHistory}");
|
||
if (archive.Allergies.Count > 0) sb.AppendLine($"过敏: {string.Join(", ", archive.Allergies)}");
|
||
if (archive.DietRestrictions.Count > 0) sb.AppendLine($"饮食限制: {string.Join(", ", archive.DietRestrictions)}");
|
||
}
|
||
|
||
if (activeMedications.Count > 0)
|
||
{
|
||
sb.AppendLine("当前用药:");
|
||
foreach (var medication in activeMedications.Take(20))
|
||
{
|
||
var times = medication.TimeOfDay.Count > 0
|
||
? string.Join("/", medication.TimeOfDay.Select(t => t.ToString("HH:mm")))
|
||
: "未设置时间";
|
||
sb.AppendLine($" {medication.Name} {medication.Dosage ?? ""} {medication.Frequency} {times}");
|
||
}
|
||
}
|
||
|
||
if (recentRecords.Count > 0)
|
||
{
|
||
sb.AppendLine("近期健康数据:");
|
||
foreach (var record in recentRecords)
|
||
sb.AppendLine($" {record.Type}: {RecordValue(record)} ({record.RecordedAt:MM-dd HH:mm})");
|
||
}
|
||
|
||
return sb.ToString();
|
||
}
|
||
|
||
private static string RecordValue(HealthRecordDto record) => record.Type switch
|
||
{
|
||
"BloodPressure" => $"{record.Systolic}/{record.Diastolic}",
|
||
"HeartRate" => $"{record.Value}次/分",
|
||
"Glucose" => $"{record.Value}",
|
||
"SpO2" => $"{record.Value}%",
|
||
"Weight" => $"{record.Value}kg",
|
||
_ => "—"
|
||
};
|
||
}
|