diff --git a/backend/src/Health.Infrastructure/AI/ai_clients.cs b/backend/src/Health.Infrastructure/AI/ai_clients.cs index 72a808a..10780e1 100644 --- a/backend/src/Health.Infrastructure/AI/ai_clients.cs +++ b/backend/src/Health.Infrastructure/AI/ai_clients.cs @@ -119,6 +119,7 @@ public sealed class VisionClient(HttpClient http, IConfiguration config) { Model = _model, Messages = messages, MaxTokens = maxTokens, Stream = false, Temperature = 0.1f, VlHighResolutionImages = true, + EnableThinking = false, }; var json = JsonSerializer.Serialize(request, _jsonOptions); diff --git a/backend/src/Health.Infrastructure/AI/ai_contracts.cs b/backend/src/Health.Infrastructure/AI/ai_contracts.cs index 15de093..4cbee8a 100644 --- a/backend/src/Health.Infrastructure/AI/ai_contracts.cs +++ b/backend/src/Health.Infrastructure/AI/ai_contracts.cs @@ -13,6 +13,9 @@ public sealed class ChatCompletionRequest [System.Text.Json.Serialization.JsonPropertyName("vl_high_resolution_images")] public bool VlHighResolutionImages { get; set; } + + [System.Text.Json.Serialization.JsonPropertyName("enable_thinking")] + public bool? EnableThinking { get; set; } } public sealed class ChatMessage diff --git a/health_app/lib/pages/chart/trend_page.dart b/health_app/lib/pages/chart/trend_page.dart index aa00b7b..df1d668 100644 --- a/health_app/lib/pages/chart/trend_page.dart +++ b/health_app/lib/pages/chart/trend_page.dart @@ -27,6 +27,7 @@ class _TrendPageState extends ConsumerState { {'key': 'heart_rate', 'label': '心率', 'color': Color(0xFFF59E0B)}, {'key': 'glucose', 'label': '血糖', 'color': Color(0xFF4F6EF7)}, {'key': 'spo2', 'label': '血氧', 'color': Color(0xFF20C997)}, + {'key': 'weight', 'label': '体重', 'color': Color(0xFF845EF7)}, ]; static const _units = { @@ -34,6 +35,7 @@ class _TrendPageState extends ConsumerState { 'heart_rate': 'bpm', 'glucose': 'mmol/L', 'spo2': '%', + 'weight': 'kg', }; static const _names = { @@ -41,6 +43,7 @@ class _TrendPageState extends ConsumerState { 'heart_rate': '心率', 'glucose': '血糖', 'spo2': '血氧', + 'weight': '体重', }; String get _unit => _units[_selected] ?? ''; @@ -60,7 +63,7 @@ class _TrendPageState extends ConsumerState { setState(() => _loading = true); try { final api = ref.read(apiClientProvider); - final types = ['BloodPressure', 'HeartRate', 'Glucose', 'SpO2']; + final types = ['BloodPressure', 'HeartRate', 'Glucose', 'SpO2', 'Weight']; final all = >[]; for (final t in types) { try { @@ -110,7 +113,9 @@ class _TrendPageState extends ConsumerState { ? 'HeartRate' : _selected == 'glucose' ? 'Glucose' - : 'SpO2'; + : _selected == 'spo2' + ? 'SpO2' + : 'Weight'; setState(() { _filtered = _allRecords.where((r) => r['type'] == typeName).toList(); _filtered.sort( @@ -200,7 +205,9 @@ class _TrendPageState extends ConsumerState { ? 'HeartRate' : _selected == 'glucose' ? 'Glucose' - : 'SpO2', + : _selected == 'spo2' + ? 'SpO2' + : 'Weight', 'source': 'Manual', 'recordedAt': DateTime.now().toUtc().toIso8601String(), 'unit': _unit, @@ -607,9 +614,10 @@ class _TrendPageState extends ConsumerState { borderRadius: BorderRadius.circular(10), ), child: Center( - child: Text( + child: Icon( _getMetricIcon(_selected), - style: const TextStyle(fontSize: 21), + size: 21, + color: _color, ), ), ), @@ -667,18 +675,20 @@ class _TrendPageState extends ConsumerState { ); } - String _getMetricIcon(String key) { + IconData _getMetricIcon(String key) { switch (key) { case 'blood_pressure': - return '🫀'; + return Icons.monitor_heart_outlined; case 'heart_rate': - return '💓'; + return Icons.favorite_border; case 'glucose': - return '🩸'; + return Icons.water_drop_outlined; case 'spo2': - return '🫁'; + return Icons.air_outlined; + case 'weight': + return Icons.monitor_weight_outlined; default: - return '📊'; + return Icons.show_chart; } } }