fix: 修复 Flutter 前端多项功能 + 后端运动计划 API
- Android 添加相机/存储权限,拍照和相册功能可用 - AI 回复支持 Markdown 渲染(加粗/表格不再显示**乱码) - 附件按钮接线,支持拍照/相册/文件选择 - 智能体面板按钮全部接线(拍照/上传/手动录入/导航) - 侧边栏 AI 录入后自动刷新健康数据 - 运动计划页增加创建按钮 + 打卡功能 - 后端运动计划支持 AI 创建和打卡(Tool Calling) - 修复 CreateExercisePlanRequest JSON 反序列化
This commit is contained in:
@@ -470,13 +470,44 @@ public static class AiChatEndpoints
|
||||
private static async Task<object> ExecuteManageExercise(AppDbContext db, Guid userId, JsonElement args)
|
||||
{
|
||||
var action = args.TryGetProperty("action", out var a) ? a.GetString()! : "query";
|
||||
if (action != "query") return new { success = false, message = "运动计划管理暂未实现" };
|
||||
switch (action)
|
||||
{
|
||||
case "create":
|
||||
var weekStart = args.TryGetProperty("week_start_date", out var wsd) ? DateOnly.Parse(wsd.GetString()!) : DateOnly.FromDateTime(DateTime.Now);
|
||||
var plan = new ExercisePlan { Id = Guid.NewGuid(), UserId = userId, WeekStartDate = weekStart };
|
||||
if (args.TryGetProperty("items", out var items))
|
||||
{
|
||||
foreach (var item in items.EnumerateArray())
|
||||
{
|
||||
plan.Items.Add(new ExercisePlanItem
|
||||
{
|
||||
Id = Guid.NewGuid(), DayOfWeek = item.GetProperty("day_of_week").GetInt32(),
|
||||
ExerciseType = item.GetProperty("exercise_type").GetString() ?? "散步",
|
||||
DurationMinutes = item.GetProperty("duration_minutes").GetInt32(),
|
||||
IsRestDay = item.TryGetProperty("is_rest_day", out var rd) && rd.GetBoolean(),
|
||||
});
|
||||
}
|
||||
}
|
||||
db.ExercisePlans.Add(plan);
|
||||
await db.SaveChangesAsync();
|
||||
return new { success = true, plan_id = plan.Id };
|
||||
|
||||
var plan = await db.ExercisePlans.Where(p => p.UserId == userId)
|
||||
.OrderByDescending(p => p.WeekStartDate).FirstOrDefaultAsync();
|
||||
if (plan == null) return new { found = false };
|
||||
var items = await db.ExercisePlanItems.Where(i => i.PlanId == plan.Id).OrderBy(i => i.DayOfWeek).ToListAsync();
|
||||
return new { found = true, plan_id = plan.Id, items = items.Select(i => new { i.DayOfWeek, i.ExerciseType, i.DurationMinutes, i.IsCompleted }) };
|
||||
case "checkin":
|
||||
var itemId = args.TryGetProperty("item_id", out var iid) ? iid.GetGuid() : Guid.Empty;
|
||||
var exerciseItem = await db.ExercisePlanItems.FindAsync([itemId]);
|
||||
if (exerciseItem == null) return new { success = false, message = "条目不存在" };
|
||||
exerciseItem.IsCompleted = true;
|
||||
exerciseItem.CompletedAt = DateTime.UtcNow;
|
||||
await db.SaveChangesAsync();
|
||||
return new { success = true };
|
||||
|
||||
default: // query
|
||||
var existingPlan = await db.ExercisePlans.Where(p => p.UserId == userId)
|
||||
.OrderByDescending(p => p.WeekStartDate).FirstOrDefaultAsync();
|
||||
if (existingPlan == null) return new { found = false };
|
||||
var exerciseItems = await db.ExercisePlanItems.Where(i => i.PlanId == existingPlan.Id).OrderBy(i => i.DayOfWeek).ToListAsync();
|
||||
return new { found = true, plan_id = existingPlan.Id, items = exerciseItems.Select(i => new { i.Id, i.DayOfWeek, i.ExerciseType, i.DurationMinutes, i.IsCompleted }) };
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<string> BuildPatientContext(AppDbContext db, Guid userId, CancellationToken ct)
|
||||
|
||||
@@ -271,5 +271,15 @@ public sealed record CreateMedicationRequest(string Name, string? Dosage, Medica
|
||||
public sealed record CreateConsultationRequest(Guid DoctorId);
|
||||
public sealed record SendMessageRequest(string Content);
|
||||
|
||||
public sealed record CreateExercisePlanRequest(DateOnly WeekStartDate, List<ExerciseItemDto>? Items);
|
||||
public sealed record ExerciseItemDto(int DayOfWeek, string ExerciseType, int DurationMinutes, bool IsRestDay);
|
||||
public sealed class CreateExercisePlanRequest
|
||||
{
|
||||
public DateOnly WeekStartDate { get; init; }
|
||||
public List<ExerciseItemDto>? Items { get; init; }
|
||||
}
|
||||
public sealed class ExerciseItemDto
|
||||
{
|
||||
public int DayOfWeek { get; init; }
|
||||
public string ExerciseType { get; init; } = "";
|
||||
public int DurationMinutes { get; init; }
|
||||
public bool IsRestDay { get; init; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user