ar_tourism_flutter_unity/lib/pages/message/message copy.dart
2025-05-14 17:04:13 +08:00

416 lines
13 KiB
Dart

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../apis/app.dart';
import '../../components/appbar.dart';
class MessagePage extends StatefulWidget {
const MessagePage({super.key});
@override
State<MessagePage> createState() => _MessagePageState();
}
class _MessagePageState extends State<MessagePage> {
bool isLoading = true;
int currentPage = 1;
int totalCount = 0;
int guanzhuUnreadCount = 0;
int likeUnreadCount = 0;
int systemUnreadCount = 0;
final ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
_scrollController.addListener(_onScroll);
// 修改初始化加载方式
WidgetsBinding.instance.addPostFrameCallback((_) {
_initData();
});
}
@override
void dispose() {
_scrollController.removeListener(_onScroll);
_scrollController.dispose();
super.dispose();
}
// 初始化数据
Future<void> _initData() async {
await Future.wait([
getMsgList(),
getNewFollowCount(),
getLikeCount(),
]);
}
// 获取系统未读消息数
int _getSystemUnreadCount() {
return messages.where((msg) => msg['status'] == '0').length;
}
// 获取总未读消息数
int getTotalUnreadCount() {
return guanzhuUnreadCount + likeUnreadCount + _getSystemUnreadCount();
}
// 更新SharedPreferences中的未读消息数
Future<void> _updateUnreadMessageCount() async {
if (!mounted) return;
final prefs = await SharedPreferences.getInstance();
await prefs.setInt('unreadMessageCount', getTotalUnreadCount());
}
// 修改获取新增关注人数接口
Future<void> getNewFollowCount() async {
try {
final res = await userApi.getNewFollow();
if (!mounted) return;
if (res['code'] == 200) {
setState(() {
guanzhuUnreadCount = res['data'];
});
_updateUnreadMessageCount();
} else {
throw Exception('获取关注人数失败: ${res['msg']}');
}
} catch (e) {
debugPrint('获取关注人数错误: $e');
}
}
// 修改获取喜爱数接口
Future<void> getLikeCount() async {
try {
final res = await userApi.getAddLikeNum();
if (!mounted) return;
if (res['code'] == 200) {
setState(() {
likeUnreadCount = res['data'];
});
_updateUnreadMessageCount();
} else {
throw Exception('获取喜爱数失败: ${res['msg']}');
}
} catch (e) {
debugPrint('获取喜爱数错误: $e');
}
}
List<dynamic> messages = [];
// List<dynamic> messages = [];
Future<void> getMsgList({int page = 1}) async {
setState(() => isLoading = true);
try {
var result = await userApi.getSystemMessage(
page: page,
pageSize: 10,
);
debugPrint("getMsgList response: $result");
if (!mounted) return;
if (result['code'] == 200) {
setState(() {
if (page == 1) {
// 转换每个消息对象为Map<String, dynamic>
messages = (result['rows'] as List).map((item) => {
'id': item['id']?.toString() ?? '',
'type': item['type']?.toString() ?? '',
'createTime': item['createTime']?.toString() ?? '',
'status': item['status']?.toString() ?? '',
'detail': item['detail']?.toString() ?? '',
}).toList();
} else {
// 转换并添加新的消息
final newMessages = (result['rows'] as List).map((item) => {
'id': item['id']?.toString() ?? '',
'type': item['type']?.toString() ?? '',
'createTime': item['createTime']?.toString() ?? '',
'status': item['status']?.toString() ?? '',
'detail': item['detail']?.toString() ?? '',
}).toList();
messages.addAll(newMessages);
}
totalCount = result['total'] ?? 0;
currentPage = page;
systemUnreadCount = _getSystemUnreadCount();
});
_updateUnreadMessageCount();
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('获取消息列表失败: ${e.toString()}')),
);
}
} finally {
if (mounted) {
setState(() => isLoading = false);
}
}
}
String _formatDateTime(String dateTimeString) {
DateTime dateTime = DateTime.parse(dateTimeString).toLocal();
return '${dateTime.year}-${dateTime.month}-${dateTime.day} ${dateTime.hour}:${dateTime.minute}:${dateTime.second}'; // 格式化为 年月日 时分秒
}
void _onScroll() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
_loadMore();
}
}
Future<void> _loadMore() async {
if (!isLoading && messages.length < totalCount) {
await getMsgList(page: currentPage + 1);
}
}
@override
Widget build(BuildContext context) {
// if (isLoading) {
// return const Scaffold(
// body: Center(
// child: CircularProgressIndicator(),
// ),
// );
// }
// if (!isLoggedIn) {
// return const SizedBox.shrink();
// }
return Scaffold(
appBar: const CustomAppBar(title: '消息', showLeading: false),
body: Container(
height: MediaQuery.of(context).size.height,
decoration: const BoxDecoration(color: Color(0xff0C0C16)),
child: RefreshIndicator(
onRefresh: () async {
await _initData();
},
child: ListView(
controller: _scrollController,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () async {
if (!mounted) return;
Navigator.pushNamed(context, '/guanZhu').then((_) async {
// 进入关注页面后,清除关注未读数
setState(() {
guanzhuUnreadCount = 0;
});
await _updateUnreadMessageCount();
});
},
child: _buildIconWithBadge(
icon: 'images/guanzhu.png',
label: '关注',
unreadCount: guanzhuUnreadCount,
),
),
GestureDetector(
onTap: () async {
if (!mounted) return;
Navigator.pushNamed(context, '/recevieLike').then((_) async {
// 进入喜爱页面后,清除喜爱未读数
setState(() {
likeUnreadCount = 0;
});
await _updateUnreadMessageCount();
});
},
child: _buildIconWithBadge(
icon: 'images/like.png',
label: '喜爱',
unreadCount: likeUnreadCount,
),
),
],
),
),
const Divider(color: Color(0xff1D1D27)),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: messages.length,
itemBuilder: (context, index) {
final message = messages[index];
return GestureDetector(
onTap: () async {
final result = await Navigator.pushNamed(
context,
'/messageDetail',
arguments: message['id'],
);
if (result != null) {
// 从消息详情页返回后,立即刷新消息列表
await getMsgList(page: 1);
await getNewFollowCount();
await getLikeCount();
}
},
child: _buildMessageItem(message),
);
},
),
if (messages.isNotEmpty)
Container(
padding: const EdgeInsets.symmetric(vertical: 16),
alignment: Alignment.center,
child: messages.length < totalCount
? const SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(
strokeWidth: 2.0,
color: Colors.white,
),
)
: const Text(
'已经到底啦',
style: TextStyle(
color: Colors.grey,
fontSize: 14,
),
),
),
],
),
),
),
);
}
Widget _buildIconWithBadge({
required String icon,
required String label,
required int unreadCount,
}) {
return Stack(
children: [
Column(
children: [
Image.asset(icon, width: 50, height: 50),
const SizedBox(height: 10),
Text(label,
style: const TextStyle(color: Color(0xffC1C1C1), fontSize: 14)),
],
),
if (unreadCount > 0)
Positioned(
right: 0,
top: 0,
child: Container(
padding: const EdgeInsets.all(4),
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: Text(
'$unreadCount',
style: const TextStyle(color: Colors.white, fontSize: 12),
),
),
),
],
);
}
Widget _buildMessageItem(Map<String, dynamic> message) {
// 确保所有字段都是String类型
final String type = message['type'] ?? '';
final String createTime = message['createTime'] ?? '';
final String detail = message['detail'] ?? '';
final String status = message['status'] ?? '';
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Image.asset('images/notice.png', width: 50, height: 50),
const SizedBox(width: 8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
type == '3' || type == '5'
? '审核消息'
: type == '4'
? '退款消息'
: '系统消息',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color(0xffC1C1C1),
),
),
Text(
createTime.isNotEmpty ? _formatDateTime(createTime) : '',
style: const TextStyle(
fontSize: 12,
color: Color(0xff72767C),
),
),
],
),
const SizedBox(height: 4),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
detail,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 14,
color: Color(0xff72767C),
),
),
),
if (status == '0')
Container(
margin: const EdgeInsets.only(left: 8),
padding: const EdgeInsets.all(5),
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: const Text(
'1',
style: TextStyle(color: Colors.white, fontSize: 12),
),
),
],
),
],
),
),
],
),
);
}
}