import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../providers/data_providers.dart'; /// 饮食记录列表 class DietRecordListPage extends ConsumerWidget { const DietRecordListPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final service = ref.watch(dietServiceProvider); return Scaffold( appBar: AppBar(title: const Text('饮食记录')), body: FutureBuilder>>( future: service.getRecords(), builder: (ctx, snap) { if (snap.connectionState == ConnectionState.waiting) return const Center(child: CircularProgressIndicator()); if (!snap.hasData || snap.data!.isEmpty) return _empty(context, '饮食记录', '暂无饮食记录,可通过「拍饮食」录入'); return ListView.builder( itemCount: snap.data!.length, itemBuilder: (ctx, i) { final d = snap.data![i]; final items = (d['foodItems'] as List?)?.cast>() ?? []; return Card( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), child: ListTile( title: Text('${d['mealType'] ?? ''} ${d['totalCalories'] ?? 0}千卡'), subtitle: Text(items.map((f) => f['name']).join(' | ')), trailing: _starWidget(d['healthScore']), ), ); }, ); }, ), ); } Widget _starWidget(dynamic score) { final s = score is int ? score : 3; return Row(mainAxisSize: MainAxisSize.min, children: List.generate(5, (i) => Icon(Icons.star, size: 16, color: i < s ? const Color(0xFFF9A825) : Colors.grey[300]))); } } /// 运动计划页 class ExercisePlanPage extends ConsumerWidget { const ExercisePlanPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final plan = ref.watch(currentExercisePlanProvider); return Scaffold( appBar: AppBar(title: const Text('运动计划')), floatingActionButton: FloatingActionButton.extended( onPressed: () => _createDefaultPlan(ref), icon: const Icon(Icons.add), label: const Text('创建本周计划'), ), body: plan.when( data: (data) { if (data == null || data.isEmpty) return _empty(context, '运动计划', '暂无运动计划,点击右下角创建'); final items = (data['items'] as List?)?.cast>() ?? []; final weekDays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']; return ListView.builder( itemCount: items.length, itemBuilder: (ctx, i) { final item = items[i]; final day = item['dayOfWeek'] is int ? item['dayOfWeek'] as int : i; final isRest = item['isRestDay'] == true; final isDone = item['isCompleted'] == true; return ListTile( leading: Icon(isDone ? Icons.check_circle : Icons.circle_outlined, color: isDone ? const Color(0xFF43A047) : Colors.grey), title: Text('${weekDays[day]} ${isRest ? '休息日' : '${item['exerciseType']} ${item['durationMinutes']}分钟'}'), trailing: isDone ? null : IconButton(icon: const Icon(Icons.check, color: Color(0xFF43A047)), onPressed: () { _checkIn(ref, item['id']); }), ); }, ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (_, __) => _empty(context, '运动计划', '暂无运动计划,点击右下角创建'), ), ); } void _createDefaultPlan(WidgetRef ref) async { final service = ref.read(exerciseServiceProvider); final today = DateTime.now(); final monday = today.subtract(Duration(days: today.weekday - 1)); final items = List.generate(7, (i) => { 'dayOfWeek': i, 'exerciseType': i == 2 || i == 5 ? '休息' : '散步', 'durationMinutes': i == 2 || i == 5 ? 0 : 30, 'isRestDay': i == 2 || i == 5, }); await service.createPlan({ 'weekStartDate': '${monday.year}-${monday.month.toString().padLeft(2, '0')}-${monday.day.toString().padLeft(2, '0')}', 'items': items, }); ref.invalidate(currentExercisePlanProvider); } void _checkIn(WidgetRef ref, String itemId) async { final service = ref.read(exerciseServiceProvider); await service.checkIn(itemId); ref.invalidate(currentExercisePlanProvider); } } /// 复查列表 class FollowUpListPage extends ConsumerWidget { const FollowUpListPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) => _empty(context, '复查随访', '暂无复查安排'); } /// 健康档案 class HealthArchivePage extends ConsumerWidget { const HealthArchivePage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final service = ref.watch(userServiceProvider); return Scaffold( appBar: AppBar(title: const Text('健康档案')), body: FutureBuilder?>( future: service.getHealthArchive(), builder: (ctx, snap) { if (snap.connectionState == ConnectionState.waiting) return const Center(child: CircularProgressIndicator()); final data = snap.data; if (data == null || data.isEmpty) return _empty(context, '暂无健康档案', '可通过 AI 对话或手动填写'); return ListView( padding: const EdgeInsets.all(16), children: [ _Section(title: '基本信息', children: [ _Field('诊断', data['diagnosis']), _Field('手术类型', data['surgeryType']), _Field('手术日期', data['surgeryDate']), ]), _Section(title: '病史与限制', children: [ _Field('过敏史', _listStr(data['allergies'])), _Field('饮食限制', _listStr(data['dietRestrictions'])), _Field('慢性病史', _listStr(data['chronicDiseases'])), _Field('家族病史', data['familyHistory']), ]), ], ); }, ), ); } String _listStr(dynamic list) => list is List ? list.join('、') : '--'; } class _Section extends StatelessWidget { final String title; final List children; const _Section({required this.title, required this.children}); @override Widget build(BuildContext context) => Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding(padding: const EdgeInsets.only(bottom: 8, top: 16), child: Text(title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)))), ...children, ]); } class _Field extends StatelessWidget { final String label; final String? value; const _Field(this.label, this.value); @override Widget build(BuildContext context) => Padding( padding: const EdgeInsets.only(bottom: 6), child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(width: 80, child: Text('$label:', style: const TextStyle(fontSize: 14, color: Color(0xFF666666)))), Expanded(child: Text(value ?? '--', style: const TextStyle(fontSize: 14, color: Color(0xFF1A1A1A)))), ]), ); } /// 编辑资料 class EditProfilePage extends ConsumerStatefulWidget { const EditProfilePage({super.key}); @override ConsumerState createState() => _EditProfilePageState(); } class _EditProfilePageState extends ConsumerState { final _nameCtrl = TextEditingController(); final _genderCtrl = TextEditingController(); final _birthCtrl = TextEditingController(); @override void dispose() { _nameCtrl.dispose(); _genderCtrl.dispose(); _birthCtrl.dispose(); super.dispose(); } @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) => _load()); } void _load() async { final p = await ref.read(userServiceProvider).getProfile(); if (p != null && mounted) { setState(() { _nameCtrl.text = p['name'] ?? ''; _genderCtrl.text = p['gender'] ?? ''; _birthCtrl.text = p['birthDate'] ?? ''; }); } } Future _save() async { await ref.read(userServiceProvider).updateProfile(name: _nameCtrl.text, gender: _genderCtrl.text, birthDate: _birthCtrl.text); if (mounted) Navigator.pop(context); } @override Widget build(BuildContext context) => Scaffold( appBar: AppBar(title: const Text('编辑资料')), body: ListView(padding: const EdgeInsets.all(16), children: [ TextField(controller: _nameCtrl, decoration: const InputDecoration(labelText: '姓名')), const SizedBox(height: 16), TextField(controller: _genderCtrl, decoration: const InputDecoration(labelText: '性别')), const SizedBox(height: 16), TextField(controller: _birthCtrl, decoration: const InputDecoration(labelText: '出生日期', hintText: 'YYYY-MM-DD')), const SizedBox(height: 32), SizedBox(width: double.infinity, child: ElevatedButton(onPressed: _save, child: const Text('保存'))), ]), ); } /// 健康日历 class HealthCalendarPage extends ConsumerWidget { const HealthCalendarPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) => _empty(context, '健康日历', '暂无数据'); } /// 静态文本页 class StaticTextPage extends ConsumerWidget { final String type; const StaticTextPage({super.key, required this.type}); @override Widget build(BuildContext context, WidgetRef ref) { final titles = {'privacy': '隐私政策', 'terms': '服务协议', 'about': '关于'}; return Scaffold(appBar: AppBar(title: Text(titles[type] ?? '')), body: const Center(child: Padding(padding: EdgeInsets.all(16), child: Text('内容后期填充', style: TextStyle(color: Color(0xFF999999)))))); } } /// 设备管理(占位) class DeviceManagementPage extends ConsumerWidget { const DeviceManagementPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) => _empty(context, '设备管理', '暂无绑定设备'); } Widget _empty(BuildContext context, String title, String subtitle) => Scaffold( appBar: AppBar(title: Text(title)), body: Center(child: Column(mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.inbox_outlined, size: 64, color: Colors.grey[300]), const SizedBox(height: 12), Text(subtitle, style: Theme.of(context).textTheme.bodyMedium), ])), );