gcx/frontend/genex-mobile/lib/features/message/presentation/pages/message_page.dart

216 lines
5.6 KiB
Dart
Raw 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';
import '../../../../app/theme/app_colors.dart';
import '../../../../app/theme/app_typography.dart';
import '../../../../app/theme/app_spacing.dart';
import '../../../../shared/widgets/empty_state.dart';
/// A8. 消息模块
///
/// 交易通知、系统公告、券到期提醒、价格提醒
/// 分类Tab + 消息详情
class MessagePage extends StatefulWidget {
const MessagePage({super.key});
@override
State<MessagePage> createState() => _MessagePageState();
}
class _MessagePageState extends State<MessagePage>
with SingleTickerProviderStateMixin {
late TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 4, vsync: this);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('消息'),
actions: [
TextButton(
onPressed: () {},
child: Text('全部已读', style: AppTypography.labelSmall.copyWith(
color: AppColors.primary,
)),
),
],
bottom: TabBar(
controller: _tabController,
tabs: const [
Tab(text: '全部'),
Tab(text: '交易'),
Tab(text: '到期'),
Tab(text: '公告'),
],
),
),
body: TabBarView(
controller: _tabController,
children: [
_buildMessageList(all: true),
_buildMessageList(type: MessageType.transaction),
_buildMessageList(type: MessageType.expiry),
_buildMessageList(type: MessageType.announcement),
],
),
);
}
Widget _buildMessageList({bool all = false, MessageType? type}) {
if (type == MessageType.announcement) {
return EmptyState.noMessages();
}
final messages = _mockMessages
.where((m) => all || m.type == type)
.toList();
return ListView.separated(
padding: const EdgeInsets.symmetric(vertical: 8),
itemCount: messages.length,
separatorBuilder: (_, __) => const Divider(indent: 76),
itemBuilder: (context, index) {
final msg = messages[index];
return _buildMessageItem(msg);
},
);
}
Widget _buildMessageItem(_MockMessage msg) {
return ListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 4),
leading: Container(
width: 44,
height: 44,
decoration: BoxDecoration(
color: _iconBgColor(msg.type),
shape: BoxShape.circle,
),
child: Icon(_iconData(msg.type), size: 22, color: _iconColor(msg.type)),
),
title: Row(
children: [
Expanded(
child: Text(msg.title, style: AppTypography.labelMedium.copyWith(
fontWeight: msg.isRead ? FontWeight.w400 : FontWeight.w600,
)),
),
Text(msg.time, style: AppTypography.caption),
],
),
subtitle: Padding(
padding: const EdgeInsets.only(top: 4),
child: Text(
msg.body,
style: AppTypography.bodySmall,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
trailing: !msg.isRead
? Container(
width: 8,
height: 8,
decoration: const BoxDecoration(
color: AppColors.primary,
shape: BoxShape.circle,
),
)
: null,
onTap: () {
Navigator.pushNamed(context, '/message/detail');
},
);
}
IconData _iconData(MessageType type) {
switch (type) {
case MessageType.transaction:
return Icons.swap_horiz_rounded;
case MessageType.expiry:
return Icons.access_time_rounded;
case MessageType.price:
return Icons.trending_up_rounded;
case MessageType.announcement:
return Icons.campaign_rounded;
}
}
Color _iconColor(MessageType type) {
switch (type) {
case MessageType.transaction:
return AppColors.primary;
case MessageType.expiry:
return AppColors.warning;
case MessageType.price:
return AppColors.success;
case MessageType.announcement:
return AppColors.info;
}
}
Color _iconBgColor(MessageType type) {
return _iconColor(type).withValues(alpha: 0.1);
}
}
enum MessageType { transaction, expiry, price, announcement }
class _MockMessage {
final String title;
final String body;
final String time;
final MessageType type;
final bool isRead;
const _MockMessage(this.title, this.body, this.time, this.type, this.isRead);
}
const _mockMessages = [
_MockMessage(
'购买成功',
'您已成功购买 星巴克 \$25 礼品卡,共花费 \$21.25',
'14:32',
MessageType.transaction,
false,
),
_MockMessage(
'券即将到期',
'您持有的 Target \$30 折扣券 将于3天后到期请及时使用',
'10:15',
MessageType.expiry,
false,
),
_MockMessage(
'价格提醒',
'您关注的 Amazon \$100 购物券 当前价格已降至 \$82低于您设定的提醒价格',
'昨天',
MessageType.price,
true,
),
_MockMessage(
'出售成交',
'您挂单出售的 Nike \$80 运动券 已成功售出,收入 \$68.00',
'02/07',
MessageType.transaction,
true,
),
_MockMessage(
'核销成功',
'Walmart \$50 生活券 已在门店核销成功',
'02/06',
MessageType.transaction,
true,
),
];