- 新增管理员角色(手机号12345678910),管理员可增删医生、查看患者 - 注册页重构:去掉角色选择+审核码,改为选医生+填姓名 - 医生端点按DoctorId过滤患者,Patient↔Doctor关系建立 - Doctor/DoctorProfile/User实体新增关联字段 - JSON循环引用修复(IgnoreCycles) - /api/doctors改为公开接口 - 登录闪屏修复+原生Android启动页 - 输入框全局白底+灰框 - 蓝牙重连同步修复 - Web端(doctor_web+health_app/web)全部删除 - 全局UI改版:白底企业风,新配色和组件系统 - 新品牌图标和启动图
94 lines
4.6 KiB
C#
94 lines
4.6 KiB
C#
using Health.WebApi.Hubs;
|
|
|
|
namespace Health.WebApi.Endpoints;
|
|
|
|
public static class ConsultationEndpoints
|
|
{
|
|
public static void MapConsultationEndpoints(this WebApplication app)
|
|
{
|
|
// 医生列表(注册时无需登录)
|
|
app.MapGet("/api/doctors", async (AppDbContext db) =>
|
|
{
|
|
var doctors = await db.Doctors.Where(d => d.IsActive).Select(d => new { d.Id, d.Name, d.Title, d.Department, d.Introduction }).ToListAsync();
|
|
return Results.Ok(new { code = 0, data = doctors, message = (string?)null });
|
|
});
|
|
|
|
var group = app.MapGroup("/api").RequireAuthorization();
|
|
|
|
group.MapGet("/consultations", async (HttpContext http, AppDbContext db) =>
|
|
{
|
|
var userId = GetUserId(http);
|
|
var consultations = await db.Consultations.Where(c => c.UserId == userId).OrderByDescending(c => c.CreatedAt).ToListAsync();
|
|
return Results.Ok(new { code = 0, data = consultations, message = (string?)null });
|
|
});
|
|
|
|
group.MapPost("/consultations", async (CreateConsultationRequest req, HttpContext http, AppDbContext db, CancellationToken ct) =>
|
|
{
|
|
var userId = GetUserId(http);
|
|
var consultation = new Consultation
|
|
{
|
|
Id = Guid.NewGuid(), UserId = userId, DoctorId = req.DoctorId,
|
|
Status = ConsultationStatus.AiTalking,
|
|
Month = DateTime.UtcNow.Year * 100 + DateTime.UtcNow.Month,
|
|
};
|
|
db.Consultations.Add(consultation);
|
|
await db.SaveChangesAsync(ct);
|
|
return Results.Ok(new { code = 0, data = new { consultation.Id }, message = (string?)null });
|
|
});
|
|
|
|
group.MapGet("/consultations/{id:guid}/messages", async (Guid id, string? after, HttpContext http, AppDbContext db, CancellationToken ct) =>
|
|
{
|
|
var userId = GetUserId(http);
|
|
var query = db.ConsultationMessages.Where(m => m.ConsultationId == id && m.Consultation.UserId == userId);
|
|
if (Guid.TryParse(after, out var afterId))
|
|
query = query.Where(m => m.Id.CompareTo(afterId) > 0);
|
|
var messages = await query.OrderBy(m => m.CreatedAt).Take(50).Select(m => new { m.Id, SenderType = m.SenderType.ToString(), m.SenderName, m.Content, m.CreatedAt }).ToListAsync(ct);
|
|
return Results.Ok(new { code = 0, data = messages, message = (string?)null });
|
|
});
|
|
|
|
group.MapPost("/consultations/{id:guid}/messages", async (Guid id, SendMessageRequest req, HttpContext http, AppDbContext db, IHubContext<Hubs.ConsultationHub> hubContext, CancellationToken ct) =>
|
|
{
|
|
var userId = GetUserId(http);
|
|
var msg = new ConsultationMessage { Id = Guid.NewGuid(), ConsultationId = id, SenderType = ConsultationSenderType.User, Content = req.Content, SenderName = null, CreatedAt = DateTime.UtcNow };
|
|
db.ConsultationMessages.Add(msg);
|
|
|
|
// 用户发消息后,状态从 AiTalking → WaitingDoctor
|
|
var consultation = await db.Consultations.FirstOrDefaultAsync(c => c.Id == id, ct);
|
|
if (consultation != null && consultation.Status == ConsultationStatus.AiTalking)
|
|
{
|
|
consultation.Status = ConsultationStatus.WaitingDoctor;
|
|
}
|
|
|
|
await db.SaveChangesAsync(ct);
|
|
|
|
// 通过 SignalR 广播给问诊房间(医生端实时接收)
|
|
await hubContext.Clients.Group(id.ToString()).SendAsync("ReceiveMessage", new
|
|
{
|
|
msg.Id,
|
|
consultationId = id.ToString(),
|
|
senderType = "User",
|
|
senderName = (string?)null,
|
|
content = req.Content,
|
|
msg.CreatedAt
|
|
});
|
|
|
|
return Results.Ok(new { code = 0, data = new { msg.Id }, message = (string?)null });
|
|
});
|
|
|
|
group.MapGet("/user/consultation-quota", async (HttpContext http, AppDbContext db) =>
|
|
{
|
|
var userId = GetUserId(http);
|
|
var now = DateTime.UtcNow;
|
|
var currentPeriod = now.Year * 100 + now.Month;
|
|
var used = await db.Consultations.CountAsync(c => c.UserId == userId && c.Month == currentPeriod);
|
|
return Results.Ok(new { code = 0, data = new { total = 3, used, remaining = 3 - used }, 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 CreateConsultationRequest(Guid DoctorId);
|
|
public sealed record SendMessageRequest(string Content);
|