Files
AI-Health/backend/src/Health.WebApi/Endpoints/user_endpoints.cs

116 lines
6.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

namespace Health.WebApi.Endpoints;
/// <summary>
/// 用户与健康档案 API 端点
/// </summary>
public static class UserEndpoints
{
public static void MapUserEndpoints(this WebApplication app)
{
var group = app.MapGroup("/api/user").RequireAuthorization();
// 获取个人信息
group.MapGet("/profile", async (HttpContext http, AppDbContext db, CancellationToken ct) =>
{
var userId = GetUserId(http);
var user = await db.Users.Select(u => new
{
u.Id, u.Phone, u.Role, u.Name, u.Gender, BirthDate = u.BirthDate != null ? u.BirthDate.Value.ToString("yyyy-MM-dd") : null, u.AvatarUrl
}).FirstOrDefaultAsync(u => u.Id == userId, ct);
return Results.Ok(new { code = 0, data = user, message = (string?)null });
});
// 修改资料
group.MapPut("/profile", async (UpdateProfileRequest req, HttpContext http, AppDbContext db, CancellationToken ct) =>
{
var userId = GetUserId(http);
var user = await db.Users.FindAsync([userId], ct);
if (user == null) return Results.Ok(new { code = 40004, message = "用户不存在" });
user.Name = req.Name ?? user.Name;
user.Gender = req.Gender ?? user.Gender;
if (DateOnly.TryParse(req.BirthDate, out var bd)) user.BirthDate = bd;
user.UpdatedAt = DateTime.UtcNow;
await db.SaveChangesAsync(ct);
return Results.Ok(new { code = 0, data = new { success = true }, message = (string?)null });
});
// 获取健康档案
group.MapGet("/health-archive", async (HttpContext http, AppDbContext db, CancellationToken ct) =>
{
var userId = GetUserId(http);
var archive = await db.HealthArchives.FirstOrDefaultAsync(a => a.UserId == userId, ct);
return Results.Ok(new { code = 0, data = archive, message = (string?)null });
});
// 更新健康档案
group.MapPut("/health-archive", async (UpdateArchiveRequest req, HttpContext http, AppDbContext db, CancellationToken ct) =>
{
var userId = GetUserId(http);
var archive = await db.HealthArchives.FirstOrDefaultAsync(a => a.UserId == userId, ct);
if (archive == null)
{
archive = new HealthArchive { Id = Guid.NewGuid(), UserId = userId };
db.HealthArchives.Add(archive);
}
archive.Diagnosis = req.Diagnosis ?? archive.Diagnosis;
archive.SurgeryType = req.SurgeryType ?? archive.SurgeryType;
if (DateOnly.TryParse(req.SurgeryDate, out var sd)) archive.SurgeryDate = sd;
if (req.Allergies != null) archive.Allergies = req.Allergies;
if (req.DietRestrictions != null) archive.DietRestrictions = req.DietRestrictions;
if (req.ChronicDiseases != null) archive.ChronicDiseases = req.ChronicDiseases;
archive.FamilyHistory = req.FamilyHistory ?? archive.FamilyHistory;
archive.UpdatedAt = DateTime.UtcNow;
await db.SaveChangesAsync(ct);
return Results.Ok(new { code = 0, data = new { success = true }, message = (string?)null });
});
// 注销账号
group.MapDelete("/account", async (HttpContext http, AppDbContext db, CancellationToken ct) =>
{
var userId = GetUserId(http);
// 医生清除Doctor关联
var profile = await db.DoctorProfiles.FirstOrDefaultAsync(p => p.UserId == userId, ct);
if (profile?.DoctorId != null)
{
await db.Users.Where(u => u.DoctorId == profile!.DoctorId).ExecuteUpdateAsync(u => u.SetProperty(x => x.DoctorId, (Guid?)null), ct);
await db.Doctors.Where(d => d.Id == profile.DoctorId).ExecuteDeleteAsync(ct);
}
// 删除所有关联数据
await db.HealthRecords.Where(r => r.UserId == userId).ExecuteDeleteAsync(ct);
await db.MedicationLogs.Where(l => l.UserId == userId).ExecuteDeleteAsync(ct);
await db.Medications.Where(m => m.UserId == userId).ExecuteDeleteAsync(ct);
await db.DietFoodItems.Where(i => i.DietRecord!.UserId == userId).ExecuteDeleteAsync(ct);
await db.DietRecords.Where(d => d.UserId == userId).ExecuteDeleteAsync(ct);
await db.ExercisePlanItems.Where(i => i.Plan!.UserId == userId).ExecuteDeleteAsync(ct);
await db.ExercisePlans.Where(p => p.UserId == userId).ExecuteDeleteAsync(ct);
await db.Reports.Where(r => r.UserId == userId).ExecuteDeleteAsync(ct);
await db.ConversationMessages.Where(m => m.Conversation!.UserId == userId).ExecuteDeleteAsync(ct);
await db.Conversations.Where(c => c.UserId == userId).ExecuteDeleteAsync(ct);
await db.ConsultationMessages.Where(m => m.Consultation!.UserId == userId).ExecuteDeleteAsync(ct);
await db.Consultations.Where(c => c.UserId == userId).ExecuteDeleteAsync(ct);
await db.FollowUps.Where(f => f.UserId == userId).ExecuteDeleteAsync(ct);
await db.RefreshTokens.Where(t => t.UserId == userId).ExecuteDeleteAsync(ct);
await db.DeviceTokens.Where(t => t.UserId == userId).ExecuteDeleteAsync(ct);
await db.NotificationPreferences.Where(p => p.UserId == userId).ExecuteDeleteAsync(ct);
await db.HealthArchives.Where(a => a.UserId == userId).ExecuteDeleteAsync(ct);
await db.DoctorProfiles.Where(p => p.UserId == userId).ExecuteDeleteAsync(ct);
await db.Users.Where(u => u.Id == userId).ExecuteDeleteAsync(ct);
return Results.Ok(new { code = 0, data = new { success = true }, message = (string?)null });
});
}
private static Guid GetUserId(HttpContext http) =>
Guid.TryParse(http.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value, out var id) ? id : Guid.Empty;
}
public sealed record UpdateProfileRequest(string? Name, string? Gender, string? BirthDate);
public sealed record UpdateArchiveRequest(
string? Diagnosis, string? SurgeryType, string? SurgeryDate,
List<string>? Allergies, List<string>? DietRestrictions,
List<string>? ChronicDiseases, string? FamilyHistory);