/// 订单通知 library; import 'dart:convert'; import 'package:easy_refresh/easy_refresh.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:loopin/IM/im_service.dart'; import 'package:loopin/behavior/custom_scroll_behavior.dart'; import 'package:loopin/components/empty_tip.dart'; import 'package:loopin/components/network_or_asset_image.dart'; import 'package:loopin/models/conversation_type.dart'; import 'package:loopin/models/notify_message.type.dart'; import 'package:loopin/pages/my/merchant/balance/balance.dart'; import 'package:loopin/pages/my/merchant/balance/controller.dart'; import 'package:loopin/styles/index.dart'; import 'package:loopin/utils/index.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart'; // order, 订单 class OrderNotify extends StatefulWidget { const OrderNotify({super.key}); @override State createState() => OrderNotifyState(); } class OrderNotifyState extends State with SingleTickerProviderStateMixin { bool isLoading = false; // 是否在加载中 RxBool hasMore = true.obs; // 是否还有更多数据 String page = ''; ///------------------- V2TimConversation? conv; RxList msgList = [].obs; @override void initState() { super.initState(); if (Get.arguments != null && Get.arguments is V2TimConversation) { // 如果有参数 conv = Get.arguments as V2TimConversation; logger.e('lastmsg:$conv'); final lastmsg = conv?.lastMessage; if (lastmsg != null) { msgList.add(lastmsg); getMsgData(); } } } @override void dispose() { cleanUnRead(); super.dispose(); } void cleanUnRead() async { if ((conv?.unreadCount ?? 0) > 0) { await ImService.instance.clearConversationUnreadCount(conversationID: conv?.conversationID ?? ''); } } // 分页获取全部数据 Future getMsgData() async { // 获取最旧一条消息作为游标 V2TimMessage? lastRealMsg; lastRealMsg = msgList.last; final res = await ImService.instance.getHistoryMessageList( userID: ConversationType.order.name, // userID为固定的order lastMsg: lastRealMsg, ); if (res.success && res.data != null) { msgList.addAll(res.data!); logger.e(msgList); if (res.data!.isEmpty) { hasMore.value = false; } logger.i('聊天数据加载成功'); } else { logger.e('聊天数据加载失败:${res.desc}'); } } // 下拉刷新 Future handleRefresh() async { await Future.delayed(Duration(seconds: 5)); setState(() {}); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[50], appBar: AppBar( centerTitle: true, forceMaterialTransparency: true, bottom: PreferredSize( preferredSize: Size.fromHeight(1.0), child: Container( color: Colors.grey[300], height: 1.0, ), ), title: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), child: Row( mainAxisSize: MainAxisSize.min, children: [ const SizedBox(width: 4), Text( '订单通知', style: TextStyle( color: Colors.black, fontSize: 16, fontWeight: FontWeight.bold, ), ), ], ), ), actions: [], ), body: ScrollConfiguration( behavior: CustomScrollBehavior().copyWith(scrollbars: false), child: Column( children: [ Expanded( child: EasyRefresh.builder( callLoadOverOffset: 20, //触底距离 callRefreshOverOffset: 20, // 下拉距离 header: ClassicHeader( dragText: '下拉刷新', armedText: '释放刷新', readyText: '加载中...', processingText: '加载中...', processedText: '加载完成', failedText: '加载失败,请重试', messageText: '最后更新于 %T', ), footer: ClassicFooter( dragText: '加载更多', armedText: '释放加载', readyText: '加载中...', processingText: '加载中...', processedText: '加载完成', noMoreText: '没有更多了~', failedText: '加载失败,请重试', messageText: '最后更新于 %T', ), onRefresh: () async { await handleRefresh(); }, onLoad: () async { if (hasMore.value) { await getMsgData(); return hasMore.value ? IndicatorResult.success : IndicatorResult.noMore; } }, childBuilder: (context, physics) { return Obx( () { if (msgList.isEmpty) return EmptyTip(); return ListView.builder( shrinkWrap: true, physics: physics, itemCount: msgList.length, itemBuilder: (context, index) { //检测cloudCustomData /// 订单编号[orderID] /// 订单金额[amount] /// 商品名称[name] /// 商品描述[describe] /// 商品价格[price] /// 商品主图[pic] //----正式数据 V2TimMessage msg = msgList[index]; // V2TimCustomElem element = msgList[index].customElem; final cloudCustomData = msgList[index].cloudCustomData ?? ''; logger.w(cloudCustomData); final desc = msgList[index].customElem?.desc; String? jsonData = msgList[index].customElem?.data; logger.e(msgList[index].toJson()); jsonData = (jsonData == null || jsonData.isEmpty) ? '{"faceUrl":"","nickName":"data为空","userID":"213213"}' : jsonData; var item = jsonDecode(jsonData); if (item is Map) { item = jsonDecode(jsonData); } else { // 如果不是 Map,兜底处理 item = { "faceUrl": "", "nickName": "数据异常", "userID": "", }; } final showName = conv?.showName ?? '未知'; // logger.w(element.toJson()); // ----测试数据 // final jsonData = '{"faceUrl":"","nickName":"测试昵称","userID":"213213"}'; // final item = jsonDecode(jsonData); // 数据 // final desc = '您购买的巧克力已经下单成功您购买的巧克力已经下单成功您购买的巧克力已经下单成功'; // final cloudCustomData = 'orderRefund'; // V2TimMessage msg = V2TimMessage(elemType: 2, isRead: index > 2 ? true : false); // ----------- return Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0), child: Row( children: [ Expanded( child: InkWell( onTap: () async { if (cloudCustomData == NotifyMessageTypeConstants.orderWithDraw || cloudCustomData == NotifyMessageTypeConstants.orderRecharge) { // 去余额 Get.put(BalanceController()); Get.to(() => Balance()); } else { // 点击去订单详情 Get.toNamed('/order/detail', arguments: {'orderId': item['orderID']}); } }, child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), elevation: 2, child: Padding( padding: const EdgeInsets.all(10.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 顶部:头像 + 商品名 Row( children: [ ClipOval( child: NetworkOrAssetImage( imageUrl: msg.faceUrl, width: 25, height: 25, ), ), const SizedBox(width: 8), Expanded( child: Text( showName, // item['name'] ?? '未知商品名称', // cloudCustomData == NotifyMessageTypeConstants.orderWithDraw // ? (conv?.showName ?? '未知') // : ((item['name'] as String?) ?? '未知商品名称'), maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.normal, color: Colors.black54, ), ), ), ], ), const SizedBox(height: 8), const Divider(height: 1, thickness: 1, color: Color(0xFFE0E0E0)), const SizedBox(height: 4), Text( _transLabel(cloudCustom: cloudCustomData, status: item['status']), maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( color: Colors.black, fontSize: 16.0, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 2), // 时间 Text( Utils.formatTime(msg.timestamp ?? DateTime.now().millisecondsSinceEpoch ~/ 1000), style: TextStyle( color: Colors.grey[600], fontSize: 12, ), ), const SizedBox(height: 8), // 内容:描述 + 时间 + 图片 Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ // 商品首图 Visibility( visible: item['pic'] != null && item['pic'].toString().isNotEmpty, child: NetworkOrAssetImage( imageUrl: item['pic'], placeholderAsset: 'assets/images/bk.jpg', width: 50, height: 50, ), ), SizedBox( width: 8, ), // 商品描述 Expanded( child: Text( desc ?? '未知描述', maxLines: 2, overflow: TextOverflow.ellipsis, style: const TextStyle(color: Colors.black87, fontSize: 12.0), ), ), const SizedBox(width: 20), // 未读角标 Visibility( visible: !(msg.isRead ?? true), child: FStyle.badge(0, isdot: true), ), ], ), SizedBox( height: 8, ), const Divider(height: 1, thickness: 1, color: Color(0xFFE0E0E0)), Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 8.0), child: Row( children: [ const Text('查看详情'), const Spacer(), const Icon(Icons.arrow_forward_ios, size: 16, color: Colors.grey), ], ), ), ], ), ), ), ), ), ], ), ); }, ); }, ); }, ), ), ], ), ), ); } /// 解析标签 String _transLabel({required String cloudCustom, String? status}) { // var str = status == null ? '未知状态' : status == '1' ? '成功' : '失败'; if (NotifyMessageTypeConstants.orderPay == cloudCustom) { return '下单成功'; } else if (NotifyMessageTypeConstants.orderRecharge == cloudCustom) { return '充值成功'; } else if (NotifyMessageTypeConstants.orderRefund == cloudCustom) { return '退款$str'; } else if (NotifyMessageTypeConstants.orderWithDraw == cloudCustom) { return '提现$str'; } else { return '未知action'; } } }