fix: diet capture flow - 去掉多余页面,点击直接拍照

- 点击"拍照识别/上传照片"直接打开相机/相册,不再跳转多余选择页
- DietCapturePage 去掉重复的拍照按钮,只保留分析结果展示
- 新增 dietActionProvider 处理拍饮食触发
- 修复 initState reset 导致结果页被清空的 bug
- 修复 IP 地址恢复问题
This commit is contained in:
MingNian
2026-06-08 14:39:45 +08:00
parent 287eab80a9
commit 714adc2d51
5 changed files with 40 additions and 69 deletions

View File

@@ -230,7 +230,7 @@ class DietCapturePage extends ConsumerStatefulWidget {
class _DietCapturePageState extends ConsumerState<DietCapturePage> {
@override void initState() {
super.initState();
Future.microtask(() => ref.read(dietProvider.notifier).reset());
// 不 reset — 图片由 home_page 传入,这里只做展示
}
@override
@@ -242,74 +242,12 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
title: const Text('拍饮食'),
centerTitle: true,
),
body: state.imagePath == null ? _buildCaptureView(context, ref) : _buildResultView(context, ref),
body: state.imagePath == null
? const Center(child: Text('请从首页拍摄或选择食物照片', style: TextStyle(color: Color(0xFF999999))))
: _buildResultView(context, ref),
);
}
Widget _buildCaptureView(BuildContext context, WidgetRef ref) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 180,
height: 180,
decoration: BoxDecoration(
color: const Color(0xFFF0F2FF),
borderRadius: BorderRadius.circular(90),
border: Border.all(color: const Color(0xFF8B9CF7), width: 2),
),
child: const Icon(Icons.camera_alt, size: 48, color: Color(0xFF8B9CF7)),
),
const SizedBox(height: 24),
const Text('拍摄或上传您的餐食照片', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500)),
const SizedBox(height: 8),
const Text('AI将识别食物并分析营养成分', style: TextStyle(fontSize: 14, color: Color(0xFF999999))),
const SizedBox(height: 40),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_captureBtn(context, ref, Icons.camera_alt, '拍照', ImageSource.camera),
const SizedBox(width: 24),
_captureBtn(context, ref, Icons.photo_library, '相册', ImageSource.gallery),
],
),
],
),
);
}
Widget _captureBtn(BuildContext context, WidgetRef ref, IconData icon, String label, ImageSource source) {
return Column(
children: [
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: const Color(0xFFFEFEFF),
borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(20), blurRadius: 8, offset: const Offset(0, 2))],
),
child: IconButton(
icon: Icon(icon, size: 32, color: const Color(0xFF8B9CF7)),
onPressed: () => _pickImage(context, ref, source),
),
),
const SizedBox(height: 8),
Text(label, style: const TextStyle(fontSize: 14, color: Color(0xFF666666))),
],
);
}
Future<void> _pickImage(BuildContext context, WidgetRef ref, ImageSource source) async {
final picker = ImagePicker();
final picked = await picker.pickImage(source: source, imageQuality: 80, maxWidth: 1024, maxHeight: 1024);
if (picked != null) {
ref.read(dietProvider.notifier).setImage(picked.path);
ref.read(dietProvider.notifier).analyzeImage();
}
}
// ─────────── 设计常量(与项目整体色调一致)───────────
static const _kPrimary = AppTheme.primary; // #6C5CE7
static const _kPrimaryLight = AppTheme.primaryLight; // #EDEAFF