Initial commit: 健康管家 AI 健康陪伴助手
- Backend: .NET 10 Minimal API + EF Core + PostgreSQL - Frontend: Flutter + Riverpod + GoRouter + Dio - AI: DeepSeek LLM + Qwen VLM (OpenAI-compatible) - Auth: SMS + JWT (access/refresh tokens) - Features: AI chat, health tracking, medication management, diet analysis, exercise plans, doctor consultations, report analysis
This commit is contained in:
89
backend/src/Health.WebApi/Endpoints/UserEndpoints.cs
Normal file
89
backend/src/Health.WebApi/Endpoints/UserEndpoints.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using Health.Infrastructure.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
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.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) return Results.Ok(new { code = 40004, message = "档案不存在" });
|
||||
|
||||
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);
|
||||
var user = await db.Users.FindAsync([userId], ct);
|
||||
if (user != null) { db.Users.Remove(user); await db.SaveChangesAsync(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);
|
||||
Reference in New Issue
Block a user