feat:更新个人主页模块

This commit is contained in:
2025-11-24 19:56:13 +08:00
parent 97e7a6f44b
commit 8cff5228ae
18 changed files with 443 additions and 197 deletions

View File

@@ -30,7 +30,7 @@ class _HomePage extends State<HomePage> {
);
},
),
actions: [AppActions()],
actions: [AppActions(pageIndex: _currentIndex)],
),
// backgroundColor: Color(0xFFF5F5F5),
drawer: AppDrawer(),

View File

@@ -63,6 +63,10 @@ class _LoginPage extends State<LoginPage> {
SPUtil.set('token', token);
}
void handleUserInfo(User user) {
SPUtil.set('userId', user.id);
}
void loginClick() async {
setState(() {
_isLoading = true;
@@ -78,6 +82,7 @@ class _LoginPage extends State<LoginPage> {
ToastUtil.success('登录成功');
handleRememberState();
handleTokenState(session.saToken.tokenValue);
handleUserInfo(session.userInfo);
LoadingDialog.hide(context);
Navigator.pushNamed(context, '/home');

View File

@@ -84,7 +84,7 @@ class _MomentPageState extends State<MomentPage> {
itemCount: provider.momentList.length,
separatorBuilder: (context, index) => SizedBox(height: 8),
itemBuilder: (context, index) {
return MomentCard(moment: provider.momentList[index]);
return MomentCard(moment: provider.momentList[index], isUser: false);
},
);
}

View File

@@ -32,6 +32,7 @@ class _MomentFormPageState extends State<MomentFormPage> {
return FormBuilderTextField(
name: _contentField,
initialValue: provider.momentFormItem.content,
focusNode: _focusNode,
maxLines: 5,
minLines: 3,
@@ -110,7 +111,7 @@ class _MomentFormPageState extends State<MomentFormPage> {
_buildContentField(provider),
const SizedBox(height: 8),
buildFormLabel(context: context, text: '上传图片', isRequired: false),
buildFormLabel(context: context, text: '上传图片最多9张', isRequired: false),
const SizedBox(height: 8),
_buildImageField(provider),
const SizedBox(height: 8),
@@ -218,7 +219,6 @@ class _MomentFormPageState extends State<MomentFormPage> {
onPressed: () => Navigator.pop(context),
),
),
backgroundColor: const Color(0xFFF5F5F5),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(10),

View File

@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:flutter_common/utils/sp_utils.dart';
import 'package:flutter_common/widget/common_widget.dart';
import 'package:food_hub_app/provider/food_provider.dart';
import 'package:food_hub_app/widgets/moment/card.dart';
import 'package:provider/provider.dart';
class MomentUserPage extends StatefulWidget {
const MomentUserPage({super.key});
@override
State<MomentUserPage> createState() => _MomentUserPageState();
}
class _MomentUserPageState extends State<MomentUserPage> {
@override
void initState() {
super.initState();
// 初始化加载数据
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<FoodProvider>().queryMomentByUserId(SPUtil.getInt('userId'));
});
}
Widget _buildMomentList(FoodProvider provider) {
return ListView.separated(
itemCount: provider.momentList.length,
separatorBuilder: (context, index) => SizedBox(height: 8),
itemBuilder: (context, index) {
return MomentCard(moment: provider.momentList[index], isUser: true);
},
);
}
@override
Widget build(BuildContext context) {
final provider = context.watch<FoodProvider>();
// 空状态显示
if (provider.momentList.isEmpty) {
return buildEmptyData();
}
return Scaffold(
appBar: AppBar(
title: Text('我的朋友圈', style: const TextStyle(color: Colors.white)),
backgroundColor: Theme.of(context).colorScheme.primary,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => Navigator.pop(context),
),
),
backgroundColor: const Color(0xFFF5F5F5),
body:
provider.isLoading
? buildLoadingIndicator()
: Padding(
padding: const EdgeInsets.all(10),
child: CommonCard(child: _buildMomentList(provider)),
),
);
}
}

View File

@@ -1,15 +1,209 @@
import 'package:flutter/material.dart';
import 'package:flutter_common/utils/date_utils.dart';
import 'package:flutter_common/utils/sp_utils.dart';
import 'package:flutter_common/widget/common_widget.dart';
import 'package:flutter_common/widget/dialog_widget.dart';
import 'package:food_hub_app/config/app_config.dart';
import 'package:food_hub_app/models/session.dart';
import 'package:food_hub_app/provider/user_provider.dart';
import 'package:food_hub_app/widgets/common/index.dart';
import 'package:provider/provider.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
class ProfilePage extends StatefulWidget {
const ProfilePage({super.key});
@override
State<ProfilePage> createState() => _ProfilePage();
State<ProfilePage> createState() => ProfilePageState();
}
class _ProfilePage extends State<ProfilePage>{
class ProfilePageState extends State<ProfilePage> {
@override
void initState() {
super.initState();
// 初始化加载数据
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<UserProvider>().refreshUser(SPUtil.getInt('userId'));
});
}
Widget _buildAvatar(User user) {
if (user.avatar!.isEmpty) {
return TDAvatar(
size: TDAvatarSize.large,
type: TDAvatarType.customText,
shape: TDAvatarShape.circle,
backgroundColor: Theme.of(context).colorScheme.primary,
text: user.username.isNotEmpty ? user.username[0] : '?',
);
} else {
return TDAvatar(
size: TDAvatarSize.large,
type: TDAvatarType.normal,
fit: BoxFit.contain,
avatarUrl: '${AppConfig.imageBaseUrl}/${user.avatar}',
);
}
}
Widget _buildInfoItem({required IconData icon, required String text}) {
final colors = Theme.of(context).colorScheme;
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, size: 16, color: colors.primary),
const SizedBox(width: 6),
Text(text),
],
);
}
Widget _buildFunctionButton({
required IconData icon,
required String text,
required VoidCallback onTap,
}) {
final colors = Theme.of(context).colorScheme;
return ListTile(
contentPadding: EdgeInsets.zero,
leading: Icon(icon, color: colors.primary),
title: Text(text),
trailing: Icon(Icons.arrow_forward_ios, size: 16, color: colors.primary),
onTap: onTap,
);
}
Widget _buildBasicInfo(User user) {
return CommonCard(
child: Column(
children: [
_buildAvatar(user),
const SizedBox(height: 8),
Text(
user.username,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
if (user.tags != null && user.tags!.isNotEmpty)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children:
user.tags!.map((tag) => buildTag(context, tag)).toList(),
),
if (user.tags != null && user.tags!.isNotEmpty)
const SizedBox(height: 8),
Wrap(
spacing: 8,
runSpacing: 8,
children: [
if (user.area != null && user.area!.length >= 2)
_buildInfoItem(
icon: Icons.location_on,
text: '${user.area![0]}-${user.area![1]}',
),
if (user.birthDate != null)
_buildInfoItem(
icon: Icons.cake,
text: formatDate(user.birthDate!),
),
if (user.job != null && user.job!.isNotEmpty)
_buildInfoItem(icon: Icons.work, text: user.job!),
if (user.phoneNumber != null && user.phoneNumber!.isNotEmpty)
_buildInfoItem(
icon: Icons.phone_android,
text: user.phoneNumber!,
),
if (user.email != null && user.email!.isNotEmpty)
_buildInfoItem(icon: Icons.email, text: user.email!),
],
),
if (user.description != null && user.description!.isNotEmpty)
const SizedBox(height: 8),
if (user.description != null && user.description!.isNotEmpty)
Text(user.description!),
],
),
);
}
void _onTapMoment() {
Navigator.pushNamed(context, '/momentUser');
}
Widget _buildFunctionButtons() {
return CommonCard(
child: Column(
children: [
_buildFunctionButton(
icon: Icons.account_circle,
text: '基本资料',
onTap: () {
// 跳转到编辑资料页面
// LogUtils.i('点击编辑资料');
},
),
const Divider(height: 1),
_buildFunctionButton(
icon: Icons.group_outlined,
text: '朋友圈',
onTap: _onTapMoment,
),
const Divider(height: 1),
_buildFunctionButton(
icon: Icons.favorite,
text: '我的收藏',
onTap: () {
// 跳转到浏览历史页面
// LogUtils.i('点击浏览历史');
},
),
const Divider(height: 1),
_buildFunctionButton(
icon: Icons.lock,
text: '更改密码',
onTap: () {
// 跳转到帮助与反馈页面
// LogUtils.i('点击帮助与反馈');
},
),
const Divider(height: 1),
_buildFunctionButton(
icon: Icons.exit_to_app,
text: '退出登录',
onTap: () {
showConfirmDialog(context, '确认要退出吗?');
},
),
],
),
);
}
Widget _buildContent(UserProvider provider) {
final user = provider.currentUser;
return Column(
children: [
SizedBox(width: double.infinity, child: _buildBasicInfo(user)),
const SizedBox(height: 16),
_buildFunctionButtons(),
],
);
}
@override
Widget build(BuildContext context) {
return const Center(child: Text("个人主页"));
final provider = context.watch<UserProvider>();
return Stack(
children: [
if (provider.isLoading)
buildLoadingIndicator()
else if (provider.error.isNotEmpty)
Text(provider.error)
else
_buildContent(provider),
],
);
}
}