fix: VLM识别修复 + 饮食CRUD + 侧边栏美化 + UI优化

- VLM: ChatMessage.Content string→object, 修复视觉content双重序列化
- 饮食: diet/medication端点 record→手动JSON解析, 修复循环引用
- 饮食记录: 左滑删除 + 去评分 + AI饮食评语(DeepSeek)
- 侧边栏: 功能区统一Row+Expanded, 服务包compact模式
- 历史对话: 点击加载历史消息
- 登录页: 居中布局, 去底部空白
- UI: 主色加深#6C5CE7, maxWidth:1024防图片超大
This commit is contained in:
MingNian
2026-06-04 16:27:03 +08:00
parent c44917b8e9
commit b944a31983
12 changed files with 413 additions and 305 deletions

View File

@@ -13,27 +13,52 @@ public static class MedicationEndpoints
return Results.Ok(new { code = 0, data = meds, message = (string?)null });
});
group.MapPost("/", async (CreateMedicationRequest req, HttpContext http, AppDbContext db, CancellationToken ct) =>
group.MapPost("/", async (HttpRequest request, HttpContext http, AppDbContext db, CancellationToken ct) =>
{
var userId = GetUserId(http);
request.EnableBuffering();
using var reader = new StreamReader(request.Body);
var body = await reader.ReadToEndAsync(ct);
request.Body.Position = 0;
using var json = JsonDocument.Parse(body);
var root = json.RootElement;
var med = new Medication
{
Id = Guid.NewGuid(), UserId = userId, Name = req.Name, Dosage = req.Dosage,
Frequency = req.Frequency, TimeOfDay = req.TimeOfDay ?? [],
StartDate = req.StartDate, EndDate = req.EndDate, IsActive = true, Source = req.Source,
Id = Guid.NewGuid(), UserId = userId,
Name = root.GetProperty("name").GetString()!,
Dosage = root.TryGetProperty("dosage", out var dg) ? dg.GetString() : null,
Frequency = Enum.TryParse<MedicationFrequency>(root.TryGetProperty("frequency", out var f) ? f.GetString() : "Daily", out var freq) ? freq : MedicationFrequency.Daily,
Source = Enum.TryParse<MedicationSource>(root.TryGetProperty("source", out var s) ? s.GetString() : "Manual", out var src) ? src : MedicationSource.Manual,
IsActive = true,
};
if (root.TryGetProperty("timeOfDay", out var tod))
med.TimeOfDay = tod.EnumerateArray().Select(t => TimeOnly.Parse(t.GetString()!)).ToList();
if (root.TryGetProperty("startDate", out var sd))
med.StartDate = DateOnly.TryParse(sd.GetString(), out var d) ? d : null;
if (root.TryGetProperty("endDate", out var ed))
med.EndDate = DateOnly.TryParse(ed.GetString(), out var d2) ? d2 : null;
db.Medications.Add(med);
await db.SaveChangesAsync(ct);
return Results.Ok(new { code = 0, data = new { med.Id }, message = (string?)null });
});
group.MapPut("/{id:guid}", async (Guid id, CreateMedicationRequest req, HttpContext http, AppDbContext db, CancellationToken ct) =>
group.MapPut("/{id:guid}", async (Guid id, HttpRequest request, HttpContext http, AppDbContext db, CancellationToken ct) =>
{
var userId = GetUserId(http);
var med = await db.Medications.FirstOrDefaultAsync(m => m.Id == id && m.UserId == userId, ct);
if (med == null) return Results.Ok(new { code = 40004, message = "不存在" });
med.Name = req.Name; med.Dosage = req.Dosage; med.Frequency = req.Frequency;
med.TimeOfDay = req.TimeOfDay ?? med.TimeOfDay; med.StartDate = req.StartDate; med.EndDate = req.EndDate;
request.EnableBuffering();
using var reader = new StreamReader(request.Body);
var body = await reader.ReadToEndAsync(ct);
request.Body.Position = 0;
using var json = JsonDocument.Parse(body);
var root = json.RootElement;
if (root.TryGetProperty("name", out var n)) med.Name = n.GetString()!;
if (root.TryGetProperty("dosage", out var dg2)) med.Dosage = dg2.GetString();
if (root.TryGetProperty("frequency", out var f2) && Enum.TryParse<MedicationFrequency>(f2.GetString(), out var freq2)) med.Frequency = freq2;
if (root.TryGetProperty("timeOfDay", out var tod2)) med.TimeOfDay = tod2.EnumerateArray().Select(t => TimeOnly.Parse(t.GetString()!)).ToList();
if (root.TryGetProperty("startDate", out var sd2) && DateOnly.TryParse(sd2.GetString(), out var d3)) med.StartDate = d3;
if (root.TryGetProperty("endDate", out var ed2) && DateOnly.TryParse(ed2.GetString(), out var d4)) med.EndDate = d4;
med.UpdatedAt = DateTime.UtcNow;
await db.SaveChangesAsync(ct);
return Results.Ok(new { code = 0, data = new { success = true }, message = (string?)null });
@@ -88,4 +113,3 @@ public static class MedicationEndpoints
Guid.TryParse(http.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value, out var id) ? id : Guid.Empty;
}
public sealed record CreateMedicationRequest(string Name, string? Dosage, MedicationFrequency Frequency, List<TimeOnly>? TimeOfDay, DateOnly? StartDate, DateOnly? EndDate, MedicationSource Source);