Backend: .NET 10 + PostgreSQL + EF Core + JWT + SignalR Frontend patient: React 19 + TypeScript + Vite (mobile H5) Frontend doctor: React 19 + TypeScript + Vite (desktop web)
81 lines
2.9 KiB
C#
81 lines
2.9 KiB
C#
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);
|