banxiang/lib/screens/medical_screen.dart
2026-02-17 16:10:18 +08:00

237 lines
9.8 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
class MedicalScreen extends StatelessWidget {
const MedicalScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('医疗健康')),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Hospital selection
const Text('选择医院', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)),
const SizedBox(height: 12),
_hospitalCard(context, '四川大学华西医院', '三甲', '距您5.2km', '028-85422114'),
_hospitalCard(context, '四川省人民医院', '三甲', '距您3.8km', '028-87394243'),
_hospitalCard(context, '成都市第一人民医院', '三甲', '距您2.1km', '028-86660016'),
const SizedBox(height: 24),
// Departments
const Text('常见科室', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)),
const SizedBox(height: 12),
Wrap(
spacing: 12, runSpacing: 12,
children: ['心内科', '骨科', '消化内科', '神经内科', '内分泌科', '眼科', '耳鼻喉科', '皮肤科'].map((dept) {
return GestureDetector(
onTap: () => _showDoctors(context, dept),
child: Container(
width: (MediaQuery.of(context).size.width - 64) / 4,
height: 64,
decoration: BoxDecoration(
color: const Color(0xFFF5F5F5),
borderRadius: BorderRadius.circular(12),
),
child: Center(child: Text(dept, style: const TextStyle(fontSize: 14), textAlign: TextAlign.center)),
),
);
}).toList(),
),
const SizedBox(height: 24),
// Online consultation
const Text('在线问诊', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)),
const SizedBox(height: 12),
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Row(
children: [
Icon(Icons.chat, color: Color(0xFF4CAF50)),
SizedBox(width: 8),
Text('图文问诊', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
Spacer(),
Text('¥19.9/次', style: TextStyle(fontSize: 16, color: Color(0xFFF44336), fontWeight: FontWeight.w600)),
],
),
const SizedBox(height: 8),
const Text('描述症状上传照片专业医生2小时内回复', style: TextStyle(fontSize: 14, color: Color(0xFF999999))),
const SizedBox(height: 12),
SizedBox(
width: double.infinity, height: 44,
child: ElevatedButton(
onPressed: () => _showConsultationDialog(context),
style: ElevatedButton.styleFrom(backgroundColor: const Color(0xFF4CAF50)),
child: const Text('开始问诊'),
),
),
],
),
),
),
const SizedBox(height: 12),
const Center(
child: Text('⚠️ 仅供参考,不构成医疗建议', style: TextStyle(fontSize: 12, color: Color(0xFF999999))),
),
],
),
),
);
}
Widget _hospitalCard(BuildContext context, String name, String level, String distance, String phone) {
return Card(
margin: const EdgeInsets.only(bottom: 8),
child: ListTile(
onTap: () => _showDoctors(context, '心内科'),
leading: CircleAvatar(backgroundColor: const Color(0xFFE8F5E9), child: Text(level, style: const TextStyle(fontSize: 12, color: Color(0xFF4CAF50)))),
title: Text(name, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
subtitle: Text('$distance 📞 $phone', style: const TextStyle(fontSize: 13, color: Color(0xFF999999))),
trailing: const Icon(Icons.chevron_right),
),
);
}
void _showDoctors(BuildContext context, String dept) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(16))),
builder: (ctx) => DraggableScrollableSheet(
initialChildSize: 0.7, minChildSize: 0.4, maxChildSize: 0.9,
expand: false,
builder: (_, controller) => Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Text('$dept - 医生列表', style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
),
Expanded(
child: ListView(
controller: controller,
padding: const EdgeInsets.symmetric(horizontal: 16),
children: [
_doctorTile(ctx, '王教授', '主任医师', 4.9, '高血压、冠心病', '50'),
_doctorTile(ctx, '李医生', '副主任医师', 4.7, '心律失常、心力衰竭', '35'),
_doctorTile(ctx, '张医生', '主治医师', 4.5, '心肌病、心脏瓣膜病', '25'),
],
),
),
],
),
),
);
}
Widget _doctorTile(BuildContext context, String name, String title, double rating, String specialty, String fee) {
return Card(
margin: const EdgeInsets.only(bottom: 12),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const CircleAvatar(radius: 24, backgroundColor: Color(0xFFE3F2FD), child: Icon(Icons.person, color: Color(0xFF1976D2))),
const SizedBox(width: 12),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(children: [
Text(name, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
const SizedBox(width: 8),
Text(title, style: const TextStyle(fontSize: 14, color: Color(0xFF999999))),
]),
Row(children: [
const Icon(Icons.star, size: 16, color: Color(0xFFFFC107)),
Text(' $rating', style: const TextStyle(fontSize: 14, color: Color(0xFF666666))),
]),
],
),
const Spacer(),
Text('¥$fee', style: const TextStyle(fontSize: 18, color: Color(0xFFF44336), fontWeight: FontWeight.w600)),
],
),
const SizedBox(height: 8),
Text('擅长:$specialty', style: const TextStyle(fontSize: 14, color: Color(0xFF666666))),
const SizedBox(height: 12),
Row(
children: [
_slotChip('明天 9:00'),
const SizedBox(width: 8),
_slotChip('后天 14:00'),
const SizedBox(width: 8),
_slotChip('周五 9:00'),
],
),
],
),
),
);
}
Widget _slotChip(String text) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration(
color: const Color(0xFFE3F2FD),
borderRadius: BorderRadius.circular(8),
),
child: Text(text, style: const TextStyle(fontSize: 13, color: Color(0xFF1976D2))),
);
}
void _showConsultationDialog(BuildContext context) {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: const Text('在线问诊'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const TextField(
maxLines: 3,
decoration: InputDecoration(hintText: '请描述您的症状...', hintStyle: TextStyle(fontSize: 16)),
),
const SizedBox(height: 12),
const Text('支持上传最多3张图片', style: TextStyle(fontSize: 14, color: Color(0xFF999999))),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(3, (i) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Container(
width: 60, height: 60,
decoration: BoxDecoration(
color: const Color(0xFFF5F5F5),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: const Color(0xFFDDDDDD)),
),
child: const Icon(Icons.add_photo_alternate, color: Color(0xFF999999)),
),
)),
),
],
),
actions: [
TextButton(onPressed: () => Navigator.pop(ctx), child: const Text('取消')),
ElevatedButton(
onPressed: () {
Navigator.pop(ctx);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('问诊已提交医生将在2小时内回复', style: TextStyle(fontSize: 16)), backgroundColor: Color(0xFF4CAF50)),
);
},
child: const Text('支付 ¥19.9'),
),
],
),
);
}
}