library; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:loopin/service/http.dart'; import 'package:loopin/api/shop_api.dart'; import 'package:shirne_dialog/shirne_dialog.dart'; import 'package:loopin/components/my_toast.dart'; import '../../behavior/custom_scroll_behavior.dart'; class SellerOrderDetail extends StatefulWidget { const SellerOrderDetail({super.key}); @override State createState() => _SellerOrderDetailState(); } class _SellerOrderDetailState extends State with SingleTickerProviderStateMixin { late String ? _orderId; late String ?_writeOffCodeId; dynamic orderGoodsInfo; bool _isLoading = true; // 添加加载状态 @override void initState() { super.initState(); _orderId = Get.arguments['orderId'] ?? ''; // 从商家订单列表进入此页面,此时带着订单id _writeOffCodeId = Get.arguments['writeOffCodeId'] ?? ''; // 从扫码核销进入此页面,此时带着核销码 if(_orderId != null){ getOrderDetailByOrderId(_orderId); }else if(_writeOffCodeId != null){ getOrderDetailByWriteOffId(_writeOffCodeId); } } @override void dispose() { super.dispose(); } // 获取订单详情信息,根据订单id void getOrderDetailByOrderId(orderId) async { try { setState(() { _isLoading = true; }); final res = await Http.get('${ShopApi.goodsOrderDetail}/$orderId'); debugPrint(res['data'].toString(), wrapWidth: 600); setState(() { orderGoodsInfo = res['data']; _isLoading = false; }); } catch (e) { setState(() { _isLoading = false; }); MyDialog.toast('获取订单详情失败'); } } // 获取订单详情信息,根据核销码 void getOrderDetailByWriteOffId(code) async { try { setState(() { _isLoading = true; }); final res = await Http.get('${ShopApi.getWriteOffDetail}?code=$code'); print('订单详情-------------->${res['data']}'); setState(() { orderGoodsInfo = res['data']; _isLoading = false; }); } catch (e) { setState(() { _isLoading = false; }); MyDialog.toast('获取订单详情失败'); } } // 确认核销订单 void _confirmVerifyCode () async { late String writeOffCode; if(_orderId != null){ // 商家可以直接从订单详情获取核销码,并过滤后进行核销 var verificationCodesList = orderGoodsInfo['verificationCodes']; if (verificationCodesList != null && verificationCodesList.isNotEmpty) { // 过滤可用的核销码(status为0) List newVerifyList = verificationCodesList.where((item) => item['status'] == 0).toList(); if (newVerifyList.isNotEmpty) { writeOffCode = newVerifyList[0]['code'] ?? ''; } else { return MyToast().tip( title: '暂无可用的核销码', position: 'center', type: 'error', ); } } else { return MyToast().tip( title: '暂无可用的核销码', position: 'center', type: 'error', ); } }else if(_writeOffCodeId != null){ writeOffCode = _writeOffCodeId?? ''; } try { final res = await Http.get('${ShopApi.confirmWriteOff}?code=$writeOffCode'); debugPrint(res['data'].toString(), wrapWidth: 600); MyToast().tip( title: '核销成功', position: 'center', type: 'error', ); } catch (e) { } } // 获取订单状态文本 String getOrderStatusText(int status) { switch (status) { case 0: return '待付款'; case 1: return '待核销'; case 2: return '已完成'; case 3: return '已关闭'; case 4: return '退款中'; case 5: return '已退款'; case 6: return '已取消'; default: return '未知状态'; } } // 获取订单状态颜色 Color getOrderStatusColor(int status) { switch (status) { case 0: return Colors.grey; case 1: return Colors.blue; case 2: return Colors.green; case 3: return Colors.red; case 4: return Colors.orange; case 5: return Colors.grey; case 6: return Colors.grey; default: return Colors.black; } } // 获取商品信息列表 List getProductInfoList() { // 优先使用 items 字段 if (orderGoodsInfo?['items'] != null && orderGoodsInfo!['items'] is List) { return orderGoodsInfo!['items']; } // 如果 items 为空,使用 productInfo 字段 if (orderGoodsInfo?['productInfo'] != null && orderGoodsInfo!['productInfo'] is List) { return orderGoodsInfo!['productInfo']; } // 如果都为空,返回空列表 return []; } // 获取第一个商品信息 dynamic getFirstProductInfo() { final productList = getProductInfoList(); return productList.isNotEmpty ? productList[0] : null; } // 构建商品图片 Widget _buildProductImage(dynamic productInfo) { final picUrl = productInfo?['pic']; if (picUrl == null || picUrl.isEmpty) { return Container( width: 80.0, height: 80.0, decoration: BoxDecoration( color: Colors.grey[100], borderRadius: BorderRadius.circular(8.0), ), child: Icon( Icons.shopping_bag_outlined, size: 40.0, color: Colors.grey[400], ), ); } return Image.network( picUrl, width: 80.0, height: 80.0, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Container( width: 80.0, height: 80.0, decoration: BoxDecoration( color: Colors.grey[100], borderRadius: BorderRadius.circular(8.0), ), child: Icon( Icons.shopping_bag_outlined, size: 40.0, color: Colors.grey[400], ), ); }, loadingBuilder: (context, child, loadingProgress) { if (loadingProgress == null) return child; return Container( width: 80.0, height: 80.0, decoration: BoxDecoration( color: Colors.grey[100], borderRadius: BorderRadius.circular(8.0), ), child: Center( child: CircularProgressIndicator( value: loadingProgress.expectedTotalBytes != null ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes! : null, ), ), ); }, ); } // 构建商品列表 Widget _buildProductList() { final productList = getProductInfoList(); if (productList.isEmpty) { return Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: Text( '暂无商品信息', style: TextStyle(color: Colors.grey, fontSize: 14), ), ); } return Column( children: productList.map((product) { return Padding( padding: const EdgeInsets.only(bottom: 12.0), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildProductImage(product), SizedBox(width: 10.0), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( product?['productName']?.toString() ?? '未知商品', maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 14), ), SizedBox(height: 8), Row( children: [ Text( '¥${product?['salePrice']?.toString() ?? '0.00'}', style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold), ), Spacer(), Text( 'x${product?['buyNum']?.toString() ?? '1'}', style: TextStyle(color: Colors.grey), ), ], ), ], ), ) ], ), ); }).toList(), ); } // 构建底部按钮 Widget buildBottomButtons() { if (orderGoodsInfo == null) return SizedBox.shrink(); int orderStatus = orderGoodsInfo?['status'] ?? 0; switch (orderStatus) { case 0: // 待付款 return Row( mainAxisAlignment: MainAxisAlignment.end, children: [], ); case 1: // 待核销 return Row( mainAxisAlignment: MainAxisAlignment.end, children: [ const SizedBox(width: 10.0), ElevatedButton( onPressed: () { _confirmVerifyCode(); }, style: ButtonStyle( backgroundColor: WidgetStateProperty.all(Color(0xFFFF5000)), foregroundColor: WidgetStateProperty.all(Colors.white), ), child: const Text('确认核销'), ), ], ); case 2: // 已完成 return Row( mainAxisAlignment: MainAxisAlignment.end, children: [], ); case 3: // 已关闭 return Row( mainAxisAlignment: MainAxisAlignment.end, children: [], ); case 4: // 退款中 return Row( mainAxisAlignment: MainAxisAlignment.end, children: [], ); case 5: // 已退款 return Row( mainAxisAlignment: MainAxisAlignment.end, children: [], ); case 6: // 已取消 return Row( mainAxisAlignment: MainAxisAlignment.end, children: [], ); default: return SizedBox.shrink(); } } Widget emptyTip() { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( 'assets/images/empty.png', width: 100.0, ), SizedBox(height: 16), Text( '还没有订单信息~', style: TextStyle(color: Colors.grey, fontSize: 12.0), ) ], ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[50], appBar: AppBar( backgroundColor: Color(0xFFFF5000), foregroundColor: Colors.white, title: Text('订单详情'), titleSpacing: 1.0, ), body: _isLoading ? Center(child: CircularProgressIndicator()) : orderGoodsInfo == null ? emptyTip() : ScrollConfiguration( behavior: CustomScrollBehavior().copyWith(scrollbars: false), child: ListView( physics: BouncingScrollPhysics(), padding: EdgeInsets.all(10.0), children: [ if (orderGoodsInfo?['status'] == 0) Container( padding: EdgeInsets.all(12.0), margin: EdgeInsets.only(bottom: 10.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15.0), boxShadow: [ BoxShadow( color: Colors.black.withAlpha(10), offset: Offset(0.0, 1.0), blurRadius: 1.0, spreadRadius: 0.0, ), ], ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.info, size: 16.0, color: Colors.orange, ), SizedBox(width: 4), Text( getOrderStatusText(orderGoodsInfo?['status'] ?? 0), style: TextStyle(color: Colors.orange), ), SizedBox(width: 4), ], ), SizedBox(height: 4), ], ), ), // 商品信息 Container( margin: EdgeInsets.only(bottom: 10.0), padding: EdgeInsets.all(10.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15.0), boxShadow: [ BoxShadow( color: Colors.black.withAlpha(10), offset: Offset(0.0, 1.0), blurRadius: 1.0, spreadRadius: 0.0, ), ], ), child: Column( children: [ Row( children: [ Spacer(), Text( getOrderStatusText(orderGoodsInfo?['status'] ?? 0), style: TextStyle( color: getOrderStatusColor(orderGoodsInfo?['status'] ?? 0), fontWeight: FontWeight.bold, ), ) ], ), SizedBox(height: 10), _buildProductList(), ], ), ), // 订单信息 Container( margin: EdgeInsets.only(bottom: 10.0), padding: EdgeInsets.all(10.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15.0), boxShadow: [ BoxShadow( color: Colors.black.withAlpha(10), offset: Offset(0.0, 1.0), blurRadius: 1.0, spreadRadius: 0.0, ), ], ), child: Column( children: [ Row( children: [ Text( '订单信息', style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold), ), Spacer(), InkWell( child: Icon( Icons.copy, color: Colors.grey, size: 18.0, ), onTap: () async { await Clipboard.setData(ClipboardData(text: _orderId??'')); MyDialog.toast('订单已复制到剪切板', icon: Icon(Icons.check_circle)); }, ) ], ), SizedBox(height: 10), Column( children: [ _buildOrderInfoRow('订单号', orderGoodsInfo?['orderId']?.toString() ?? ''), _buildOrderInfoRow('下单时间', orderGoodsInfo?['createTime']?.toString() ?? ''), _buildOrderInfoRow('购买数量', _calculateTotalQuantity().toString()), _buildOrderInfoRow('订单金额', '¥${orderGoodsInfo?['totalAmount']?.toString() ?? '0.00'}'), _buildOrderInfoRow('实付金额', '¥${orderGoodsInfo?['payAmount']?.toString() ?? '0.00'}'), ], ) ], ), ), ], ), ), // 底部固定按钮 bottomNavigationBar: orderGoodsInfo == null ? null : SafeArea( minimum: const EdgeInsets.all(10), child: Container( height: 60.0, color: Colors.white, padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0), // child: buildBottomButtons(), ), ), ); } // 计算总购买数量 int _calculateTotalQuantity() { final productList = getProductInfoList(); int total = 0; for (var product in productList) { total += (product?['buyNum'] as int? ?? 0); } return total; } Widget _buildOrderInfoRow(String label, String value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6.0), child: Row( children: [ Text( label, style: TextStyle(color: Colors.grey, fontSize: 13), ), Spacer(), Text(value, style: TextStyle(fontSize: 13)), ], ), ); } }