Initial commit: HealthManager full-stack health management platform

Backend: .NET 10 + PostgreSQL + EF Core + JWT + SignalR
Frontend patient: React 19 + TypeScript + Vite (mobile H5)
Frontend doctor: React 19 + TypeScript + Vite (desktop web)
This commit is contained in:
MingNian
2026-05-20 16:18:56 +08:00
commit 435af55c4a
215 changed files with 18595 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
using System.Security.Claims;
using HealthManager.Application.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace HealthManager.WebApi.Controllers;
[ApiController]
[Route("api/medications")]
[Authorize]
public class MedicationController(MedicationService medicationService) : ControllerBase
{
private Guid UserId => Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
private string Role => User.FindFirstValue(ClaimTypes.Role)!;
[HttpGet]
public async Task<IActionResult> GetMedications()
{
var targetUserId = UserId;
if (Role == "doctor" && Request.Query.ContainsKey("patientId"))
targetUserId = Guid.Parse(Request.Query["patientId"]!);
var medications = await medicationService.GetUserMedicationsAsync(targetUserId);
return Ok(medications.Select(m => new
{
m.Id, m.UserId, m.DrugName, m.Dosage, m.Frequency, m.TimeSlots,
m.StartDate, m.EndDate, m.Notes, m.Status, m.CreatedAt,
}));
}
[HttpPost]
public async Task<IActionResult> AddMedication([FromBody] MedicationCreateRequest request)
{
var med = await medicationService.AddAsync(UserId, request.DrugName, request.Dosage,
request.Frequency, request.TimeSlots, request.StartDate, request.EndDate, request.Notes);
return Ok(new { med.Id, med.DrugName, med.Dosage, med.Frequency, med.Status });
}
[HttpGet("{id:guid}")]
public async Task<IActionResult> GetMedication(Guid id)
{
var med = await medicationService.GetByIdAsync(id);
if (med == null) return NotFound(new { message = "药品不存在" });
return Ok(new
{
med.Id, med.UserId, med.DrugName, med.Dosage, med.Frequency, med.TimeSlots,
med.StartDate, med.EndDate, med.Notes, med.Status, med.CreatedAt,
});
}
[HttpGet("{id:guid}/records")]
public async Task<IActionResult> GetRecords(Guid id)
{
var records = await medicationService.GetRecordsAsync(id);
return Ok(records.Select(r => new
{
r.Id, r.MedicationId, r.TimeSlot, r.TakenAt, r.IsTaken, r.SkippedReason, r.CreatedAt,
}));
}
[HttpPost("{id:guid}/take")]
public async Task<IActionResult> MarkTaken(Guid id, [FromBody] MarkTakenRequest request)
{
var record = await medicationService.MarkTakenAsync(id, UserId, request.TimeSlot);
return Ok(new { record.Id, record.TimeSlot, record.TakenAt, record.IsTaken });
}
[HttpGet("{id:guid}/adherence")]
public async Task<IActionResult> GetAdherence(Guid id)
{
var rate = await medicationService.GetAdherenceRateAsync(id);
return Ok(new { medicationId = id, rate });
}
}
public record MedicationCreateRequest(
string DrugName, string Dosage, string Frequency,
List<string> TimeSlots, DateOnly StartDate, DateOnly? EndDate, string? Notes);
public record MarkTakenRequest(string TimeSlot);