feat: 全面UI改造 — 报告/饮食/运动/用药/侧边栏/对话流/胶囊

- 报告模块:重写AI解读页,统一白色卡片+三栏布局(指标→解读→医生审核);加删除功能+后端删接口;VLM自动识别报告类型生成中文标题;去五颜六色
- 饮食分析:全面重设计,暖橙主题配色,图片自适应,餐次emoji选择器,去紫色
- 运动确认卡片:修复duration_minutes JSON类型转换,支持中文数字识别(三十分钟/半小时→30);主区域只显示运动名,字段行改为横向排列
- 流式输出:简化为最基础逐字追加,去buffer+Timer+淡入动画
- 欢迎卡片:每智能体独立渐变色(青/橙/蓝/紫/绿/粉),加卡片入场滑入+淡入动画(600ms)
- 确认卡片:头部去紫色背景改浅灰白,字段行去图标改纯信息横排,编辑框去双重边框
- 用药管理:胶囊改TabBar,添加按钮改右下FAB;打卡按钮改对号圆圈形式;药丸图标白底
- 侧边栏:加VIP服务/保险栏+图标,标题字体放大;服务包去查看更多+去VIP金色标签
- 胶囊:首页智能体胶囊白底深色字; side胶囊加阴影
- 对话流:reverse=false,今日健康出现在顶部; 对话页input bar匹配主页面样式
- 其他:个人资料去紫色+去多余入口;设置页白底图标;蓝牙页加返回按钮;报告管理改名
- 后端:加DELETE /api/reports/{id}; 修复manage_exercise数据类型转换;AI提示优化中文数字
This commit is contained in:
MingNian
2026-06-10 23:46:45 +08:00
parent 63d2092c24
commit f6dd14be3b
28 changed files with 1153 additions and 1578 deletions

View File

@@ -135,8 +135,9 @@ public sealed class PromptManager
manage_exercise
- action="create", week_start_date="今天日期(YYYY-MM-DD)"
- items: [{"day_of_week":0-6(=0),"exercise_type":"散步","duration_minutes":30,"is_rest_day":false}, ...]
- 7
- "坚持10天"10"到6月20日"
- =30 =60 =30 =90 =80
- "一个月"=30 "一周"=7 "10天"=107
- "坚持X天/月/周"
- items
manage_medication

View File

@@ -1,5 +1,6 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.Text.Json;
using Health.Infrastructure.AI;
using Health.Infrastructure.AI.AgentHandlers;
@@ -402,6 +403,22 @@ public static class AiChatEndpoints
_ => "—"
};
// ── JSON 类型安全转换 ──
private static int _ToInt(object? v) => v switch
{
JsonElement je => je.ValueKind == JsonValueKind.Number ? je.GetInt32() : (int.TryParse(je.GetRawText().Trim('"'), out var i) ? i : 0),
int i => i,
long l => (int)l,
string s => int.TryParse(s, out var si) ? si : 0,
_ => 0
};
private static bool _ToBool(object? v) => v switch
{
JsonElement je => je.ValueKind == JsonValueKind.True || je.ValueKind == JsonValueKind.False ? je.GetBoolean() : false,
bool b => b,
_ => false
};
// ── 消息类型判断 ──
private static void _UpdateMessageTypeAndMetadata(string toolName, object toolResult, ref string messageType, ref Dictionary<string, object> metadata)
@@ -455,15 +472,14 @@ public static class AiChatEndpoints
if (resultDict != null)
{
metadata["type"] = "exercise";
metadata["value"] = "";
if (resultDict.TryGetValue("exercise_type", out var et))
metadata["value"] = et.ToString();
if (resultDict.TryGetValue("duration_minutes", out var dm) && dm is int mins)
metadata["unit"] = $"每天{mins}分钟";
if (resultDict.TryGetValue("day_count", out var dc) && dc is int days)
metadata["durationDays"] = days;
if (resultDict.TryGetValue("success", out var es) && es is bool eb && eb)
metadata["success"] = true;
resultDict.TryGetValue("exercise_type", out var et);
metadata["value"] = et?.ToString() ?? "";
resultDict.TryGetValue("duration_minutes", out var dm);
metadata["unit"] = dm != null ? $"每天{dm}分钟" : "";
resultDict.TryGetValue("day_count", out var dc);
if (dc != null) metadata["durationDays"] = dc.ToString();
resultDict.TryGetValue("success", out var ok);
metadata["success"] = ok?.ToString() == "True";
metadata["recordTime"] = DateTime.UtcNow.AddHours(8).ToString("MM月dd日 HH:mm");
}
break;

View File

@@ -16,6 +16,23 @@ public static class ReportEndpoints
return Results.Ok(new { code = 0, data = reports, message = (string?)null });
});
// 删除
group.MapDelete("/{id:guid}", async (Guid id, HttpContext http, AppDbContext db, CancellationToken ct) =>
{
var userId = GetUserId(http);
var report = await db.Reports.FirstOrDefaultAsync(r => r.Id == id && r.UserId == userId, ct);
if (report == null) return Results.Ok(new { code = 40004, message = "不存在" });
// 删除本地文件
if (!string.IsNullOrEmpty(report.FileUrl))
{
var filePath = Path.Combine(Directory.GetCurrentDirectory(), report.FileUrl.TrimStart('/'));
if (File.Exists(filePath)) File.Delete(filePath);
}
db.Reports.Remove(report);
await db.SaveChangesAsync(ct);
return Results.Ok(new { code = 0, message = "已删除" });
});
// 详情
group.MapGet("/{id:guid}", async (Guid id, HttpContext http, AppDbContext db, CancellationToken ct) =>
{