This commit is contained in:
zhutao
2025-09-01 16:24:34 +08:00
parent b110d1439c
commit bdfd051a47
8 changed files with 284 additions and 241 deletions

View File

@@ -1,9 +1,14 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:remixicon/remixicon.dart'; import 'package:remixicon/remixicon.dart';
import '../page/home/home_page.dart'; import '../page/home/home_page.dart';
import '../page/profile/my/my_page.dart'; import '../page/profile/my/my_page.dart';
import '../page/record/list/record_list_page.dart'; import '../page/record/list/record_list_page.dart';
import '../providers/user_store.dart';
import '../router/config/route_paths.dart';
import 'tabbar.dart'; import 'tabbar.dart';
class LayoutPage extends StatefulWidget { class LayoutPage extends StatefulWidget {
@@ -41,6 +46,44 @@ class _LayoutPageState extends State<LayoutPage> {
), ),
]; ];
@override
void initState() {
super.initState();
_init();
}
void _init() async {
UserStore userStore = context.read<UserStore>();
await userStore.init();
print(userStore.profile.toString());
if (userStore.profile.qStatus != 1) {
showCupertinoDialog(
context: context,
builder: (_) => CupertinoAlertDialog(
title: Text("Complete Your Profile"),
content: Text("Lets get to know you better! Please take a quick survey to personalize your experience."),
actions: [
CupertinoDialogAction(
child: Text("Take Survey"),
onPressed: () {
context.pop();
_goEditProfile();
},
),
],
),
);
}
}
void _goEditProfile() async {
var isUpload = await context.push(RoutePaths.myEdit);
if (isUpload == true) {
UserStore userStore = context.read<UserStore>();
userStore.init();
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(

View File

@@ -1,3 +1,4 @@
import 'package:food_health/providers/user_store.dart';
import 'package:food_health/router/routes.dart'; import 'package:food_health/router/routes.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
@@ -12,6 +13,7 @@ void main() {
MultiProvider( MultiProvider(
providers: [ providers: [
ChangeNotifierProvider(create: (context) => AppStore()), ChangeNotifierProvider(create: (context) => AppStore()),
ChangeNotifierProvider(create: (context) => UserStore()),
], ],
child: MyApp(), child: MyApp(),
), ),

View File

@@ -1,12 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:food_health/api/dto/profile_options_dto.dart'; import 'package:food_health/api/dto/profile_options_dto.dart';
import 'package:food_health/api/dto/user_profile_dto.dart';
import 'package:food_health/api/endpoints/profile_api.dart'; import 'package:food_health/api/endpoints/profile_api.dart';
import 'package:food_health/config/theme/custom_colors.dart'; import 'package:food_health/config/theme/custom_colors.dart';
import 'package:food_health/page/profile/edit/widget/food_allergies.dart'; import 'package:food_health/page/profile/edit/widget/food_allergies.dart';
import 'package:food_health/providers/user_store.dart';
import 'package:food_health/widgets/common/app_backend.dart'; import 'package:food_health/widgets/common/app_backend.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:remixicon/remixicon.dart'; import 'package:remixicon/remixicon.dart';
import 'data/state.dart'; import 'data/state.dart';
@@ -14,9 +15,7 @@ import 'widget/dietary_preferences.dart';
import 'widget/health_profile.dart'; import 'widget/health_profile.dart';
class MyEditPage extends StatefulWidget { class MyEditPage extends StatefulWidget {
final UserProfileDto userProfile; const MyEditPage({super.key});
const MyEditPage({super.key, required this.userProfile});
@override @override
State<MyEditPage> createState() => _MyEditPageState(); State<MyEditPage> createState() => _MyEditPageState();
@@ -57,7 +56,8 @@ class _MyEditPageState extends State<MyEditPage> {
} }
void _init() async { void _init() async {
selectionState = SelectionState(widget.userProfile); UserStore userStore = context.read<UserStore>();
selectionState = SelectionState(userStore.profile);
var res = await getProfileOptionsApi(); var res = await getProfileOptionsApi();
setState(() { setState(() {
_options = res; _options = res;
@@ -91,10 +91,21 @@ class _MyEditPageState extends State<MyEditPage> {
if (_loading) { if (_loading) {
return Center(child: CircularProgressIndicator()); return Center(child: CircularProgressIndicator());
} }
return Scaffold( return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, __) async {
if (didPop) return;
if (selectionState.userProfile.qStatus == 1) {
context.pop();
}
},
child: Scaffold(
body: AppBackend( body: AppBackend(
child: Column(
children: [
Expanded(
child: ListView( child: ListView(
padding: EdgeInsets.only(top: 30), padding: EdgeInsets.only(top: 20),
children: [ children: [
buildHeader(), buildHeader(),
buildStep(), buildStep(),
@@ -120,8 +131,11 @@ class _MyEditPageState extends State<MyEditPage> {
}, },
), ),
), ),
],
),
),
Container( Container(
margin: EdgeInsets.only(top: 30), margin: EdgeInsets.only(top: 20),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@@ -161,6 +175,7 @@ class _MyEditPageState extends State<MyEditPage> {
], ],
), ),
), ),
),
); );
} }

View File

@@ -1,12 +1,9 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:food_health/api/dto/user_profile_dto.dart';
import 'package:food_health/api/endpoints/profile_api.dart';
import 'package:food_health/config/theme/custom_colors.dart'; import 'package:food_health/config/theme/custom_colors.dart';
import 'package:go_router/go_router.dart'; import 'package:food_health/providers/user_store.dart';
import 'package:provider/provider.dart';
import 'package:remixicon/remixicon.dart'; import 'package:remixicon/remixicon.dart';
import '../../../router/config/route_paths.dart';
import 'widget/title_card.dart'; import 'widget/title_card.dart';
import 'widget/user_card.dart'; import 'widget/user_card.dart';
@@ -18,56 +15,6 @@ class MyPage extends StatefulWidget {
} }
class _MyPageState extends State<MyPage> with AutomaticKeepAliveClientMixin { class _MyPageState extends State<MyPage> with AutomaticKeepAliveClientMixin {
UserProfileDto _userProfile = UserProfileDto();
@override
void initState() {
super.initState();
_init();
}
void _init() async {
var res = await getUserProfileApi();
setState(() {
_userProfile = res;
});
_showEditProfile();
}
void _goEdit() async {
var isUpload = await context.push(RoutePaths.myEdit, extra: _userProfile);
if (isUpload == true) {
_init();
}
}
void _showEditProfile() {
if (_userProfile.qStatus != 1) {
showCupertinoDialog(
context: context,
builder: (_) => CupertinoAlertDialog(
title: Text("Complete Your Profile"),
content: Text("Lets get to know you better! Please take a quick survey to personalize your experience."),
actions: [
CupertinoDialogAction(
child: Text("Not Now"),
onPressed: () {
context.pop();
},
),
CupertinoDialogAction(
child: Text("Take Survey"),
onPressed: () {
context.pop();
_goEdit();
},
),
],
),
);
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
@@ -75,41 +22,55 @@ class _MyPageState extends State<MyPage> with AutomaticKeepAliveClientMixin {
child: ListView( child: ListView(
padding: EdgeInsets.all(15), padding: EdgeInsets.all(15),
children: [ children: [
UserCard( UserCard(),
detail: _userProfile, Consumer<UserStore>(
onEdit: _goEdit, builder: (context, store, _) {
), return Column(
Column(
children: [ children: [
TitleCard( TitleCard(
title: "Food Allergies", title: "Food Allergies",
icon: Icon( icon: Icon(
RemixIcons.shield_line, RemixIcons.shield_line,
color: Theme.of(context).colorScheme.danger, color: Theme
.of(context)
.colorScheme
.danger,
), ),
child: buildTagList( child: buildTagList(
emptyText: "No allergies reported", emptyText: "No allergies reported",
tags: _userProfile.foodAllergiesList, tags: store.profile.foodAllergiesList,
color: Theme.of(context).colorScheme.danger, color: Theme
.of(context)
.colorScheme
.danger,
), ),
), ),
TitleCard( TitleCard(
title: "No preferences", title: "No preferences",
icon: Icon( icon: Icon(
RemixIcons.heart_line, RemixIcons.heart_line,
color: Theme.of(context).colorScheme.success, color: Theme
.of(context)
.colorScheme
.success,
), ),
child: buildTagList( child: buildTagList(
emptyText: "No dietary preferences reported", emptyText: "No dietary preferences reported",
tags: _userProfile.dietaryPreferencesList, tags: store.profile.dietaryPreferencesList,
color: Theme.of(context).colorScheme.success, color: Theme
.of(context)
.colorScheme
.success,
), ),
), ),
TitleCard( TitleCard(
title: "Medical Information", title: "Medical Information",
icon: Icon( icon: Icon(
RemixIcons.user_line, RemixIcons.user_line,
color: Theme.of(context).colorScheme.primary, color: Theme
.of(context)
.colorScheme
.primary,
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -122,8 +83,11 @@ class _MyPageState extends State<MyPage> with AutomaticKeepAliveClientMixin {
margin: EdgeInsets.only(bottom: 10), margin: EdgeInsets.only(bottom: 10),
child: buildTagList( child: buildTagList(
emptyText: "No medical conditions reported", emptyText: "No medical conditions reported",
tags: _userProfile.medicalInformationList, tags: store.profile.medicalInformationList,
color: Theme.of(context).colorScheme.primary, color: Theme
.of(context)
.colorScheme
.primary,
), ),
), ),
Container( Container(
@@ -132,13 +96,18 @@ class _MyPageState extends State<MyPage> with AutomaticKeepAliveClientMixin {
), ),
buildTagList( buildTagList(
emptyText: "No medications reported", emptyText: "No medications reported",
tags: _userProfile.currentMedicationsList, tags: store.profile.currentMedicationsList,
color: Theme.of(context).colorScheme.primary, color: Theme
.of(context)
.colorScheme
.primary,
), ),
], ],
), ),
), ),
], ],
);
}
), ),
], ],
), ),

View File

@@ -5,6 +5,7 @@ import 'package:food_health/api/dto/user_profile_dto.dart';
import 'package:food_health/api/endpoints/user_api.dart'; import 'package:food_health/api/endpoints/user_api.dart';
import 'package:food_health/config/theme/custom_colors.dart'; import 'package:food_health/config/theme/custom_colors.dart';
import 'package:food_health/providers/app_store.dart'; import 'package:food_health/providers/app_store.dart';
import 'package:food_health/providers/user_store.dart';
import 'package:food_health/router/config/route_paths.dart'; import 'package:food_health/router/config/route_paths.dart';
import 'package:food_health/utils/common.dart'; import 'package:food_health/utils/common.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@@ -12,22 +13,19 @@ import 'package:provider/provider.dart';
import 'package:remixicon/remixicon.dart'; import 'package:remixicon/remixicon.dart';
class UserCard extends StatefulWidget { class UserCard extends StatefulWidget {
final UserProfileDto detail; const UserCard({super.key});
final Function() onEdit;
const UserCard({
super.key,
required this.detail,
required this.onEdit,
});
@override @override
State<UserCard> createState() => _UserCardState(); State<UserCard> createState() => _UserCardState();
} }
class _UserCardState extends State<UserCard> { class _UserCardState extends State<UserCard> {
void _goEdit() { void _goEditProfile() async {
widget.onEdit(); var isUpload = await context.push(RoutePaths.myEdit);
if (isUpload == true && mounted) {
UserStore userStore = context.read<UserStore>();
userStore.init();
}
} }
///退出登陆 ///退出登陆
@@ -105,24 +103,26 @@ class _UserCardState extends State<UserCard> {
), ),
], ],
), ),
child: Column( child: Consumer<UserStore>(
builder: (context, store, _) {
return Column(
children: [ children: [
avatarWidget(), avatarWidget(),
Container( Container(
margin: const EdgeInsets.only(top: 12), margin: const EdgeInsets.only(top: 12),
child: Text(getNotEmpty(widget.detail.name) ?? "user", style: Theme.of(context).textTheme.titleMedium), child: Text(getNotEmpty(store.profile.name) ?? "user", style: Theme.of(context).textTheme.titleMedium),
), ),
Container( Container(
margin: const EdgeInsets.only(top: 5), margin: const EdgeInsets.only(top: 5),
child: Text(widget.detail.email ?? "", style: Theme.of(context).textTheme.labelMedium), child: Text(store.profile.email ?? "", style: Theme.of(context).textTheme.labelMedium),
), ),
buildTitledTags( buildTitledTags(
title: "Age Range", title: "Age Range",
tag: getNotEmpty(widget.detail.ageRange), tag: getNotEmpty(store.profile.ageRange),
), ),
buildTitledTags( buildTitledTags(
title: "Activity Level", title: "Activity Level",
tag: getNotEmpty(widget.detail.activityLevel), tag: getNotEmpty(store.profile.activityLevel),
), ),
SizedBox(height: 20), SizedBox(height: 20),
btnItem( btnItem(
@@ -137,7 +137,7 @@ class _UserCardState extends State<UserCard> {
], ],
), ),
), ),
onTap: _goEdit, onTap: _goEditProfile,
), ),
btnItem( btnItem(
title: "Logout", title: "Logout",
@@ -156,6 +156,8 @@ class _UserCardState extends State<UserCard> {
), ),
), ),
], ],
);
},
), ),
); );
} }

View File

@@ -1,6 +1,7 @@
import 'package:food_health/providers/app_store.dart'; import 'package:food_health/providers/app_store.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:food_health/providers/user_store.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';

View File

@@ -0,0 +1,14 @@
import 'package:flutter/cupertino.dart';
import 'package:food_health/api/dto/user_profile_dto.dart';
import 'package:food_health/api/endpoints/profile_api.dart';
class UserStore with ChangeNotifier {
UserProfileDto profile = UserProfileDto();
//初始化数据
Future<void> init() async {
var res = await getUserProfileApi();
profile = res;
notifyListeners();
}
}

View File

@@ -8,10 +8,7 @@ List<RouteType> serverRoutes = [
RouteType( RouteType(
path: RoutePaths.myEdit, path: RoutePaths.myEdit,
child: (state) { child: (state) {
var extra = state.extra as dynamic; return MyEditPage();
return MyEditPage(
userProfile: extra,
);
}, },
), ),