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,71 @@
using System.Security.Claims;
using HealthManager.Application.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace HealthManager.WebApi.Controllers;
[ApiController]
[Route("api/consultations")]
[Authorize]
public class ConsultationController(ConsultationService consultationService) : ControllerBase
{
private Guid UserId => Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
private string Role => User.FindFirstValue(ClaimTypes.Role)!;
[HttpGet("doctors")]
public async Task<IActionResult> GetDoctors([FromQuery] string? department)
{
var doctors = await consultationService.GetDoctorsAsync(department);
return Ok(doctors.Select(d => new
{
d.Id, d.Name, d.Department, d.Title, d.Specialty, d.Introduction, d.AvatarUrl,
}));
}
[HttpGet]
public async Task<IActionResult> GetConsultations()
{
var consultations = Role == "doctor"
? await consultationService.GetDoctorConsultationsAsync(UserId)
: await consultationService.GetPatientConsultationsAsync(UserId);
return Ok(consultations.Select(c => new
{
c.Id, c.PatientId, c.DoctorId,
PatientName = c.Patient?.Name,
DoctorName = c.Doctor?.Name,
c.Subject, c.Status, c.StartedAt, c.ClosedAt, c.Summary,
}));
}
[HttpPost]
public async Task<IActionResult> StartConsultation([FromBody] StartConsultationRequest request)
{
var consultation = await consultationService.StartAsync(UserId, request.DoctorId, request.Subject);
return Ok(new { consultation.Id, consultation.PatientId, consultation.DoctorId, consultation.Status });
}
[HttpGet("{id:guid}/messages")]
public async Task<IActionResult> GetMessages(Guid id)
{
var messages = await consultationService.GetMessagesAsync(id);
return Ok(messages.Select(m => new
{
m.Id, m.SenderId, m.SenderRole, m.ContentType, m.Content,
m.ImageUrl, m.IsRead, m.CreatedAt,
SenderName = m.Sender?.Name,
}));
}
[HttpPost("{id:guid}/messages")]
public async Task<IActionResult> SendMessage(Guid id, [FromBody] SendMessageRequest request)
{
var message = await consultationService.SendMessageAsync(id, UserId, Role, request.Content,
request.ContentType, request.ImageUrl);
return Ok(new { message.Id, message.SenderId, message.SenderRole, message.Content, message.CreatedAt });
}
}
public record StartConsultationRequest(Guid DoctorId, string Subject);
public record SendMessageRequest(string Content, string ContentType = "text", string? ImageUrl = null);