import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../providers/order_provider.dart'; import '../theme.dart'; import '../l10n/app_localizations.dart'; import '../widgets/skeleton.dart'; class OrderDetailPage extends ConsumerStatefulWidget { final String orderId; const OrderDetailPage({super.key, required this.orderId}); @override ConsumerState createState() => _OrderDetailPageState(); } class _OrderDetailPageState extends ConsumerState { @override void initState() { super.initState(); Future.microtask(() { ref.read(orderProvider.notifier).getDetail(widget.orderId); }); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; final state = ref.watch(orderProvider); final order = state.currentOrder; if (order == null) { return Scaffold( backgroundColor: AppColors.background, appBar: AppBar(title: Text(l10n.orderDetail)), body: const DetailPageSkeleton(), ); } return Scaffold( backgroundColor: AppColors.background, appBar: AppBar(title: Text(l10n.orderDetail)), body: SingleChildScrollView( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildStatusHeader(order), const SizedBox(height: 20), _buildProductCard(order, l10n), const SizedBox(height: 20), _buildCustomerCard(order, l10n), const SizedBox(height: 20), _buildPaymentCard(order, l10n), const SizedBox(height: 20), _buildInfoCard(order, l10n), ], ), ), ); } Widget _buildStatusHeader(order) { return Container( padding: const EdgeInsets.all(24), decoration: BoxDecoration( gradient: AppGradients.primary, borderRadius: BorderRadius.circular(20), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(20), ), child: Text( order.statusText, style: const TextStyle( color: Colors.white, fontSize: 13, fontWeight: FontWeight.w600, ), ), ), const Spacer(), Text( order.orderNo, style: TextStyle( fontSize: 14, color: Colors.white.withOpacity(0.8), fontFamily: 'monospace', ), ), ], ), const SizedBox(height: 20), Text( '¥${order.amount.toStringAsFixed(2)}', style: const TextStyle( fontSize: 36, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(height: 8), Text( order.productName, style: TextStyle( fontSize: 16, color: Colors.white.withOpacity(0.9), ), ), ], ), ); } Widget _buildProductCard(order, AppLocalizations l10n) { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( l10n.productInfo, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.textPrimary, ), ), const SizedBox(height: 16), Row( children: [ Container( width: 64, height: 64, decoration: BoxDecoration( color: AppColors.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: const Icon(Icons.image, color: AppColors.primary, size: 28), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( order.productName, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.textPrimary, ), ), const SizedBox(height: 6), Text( '${l10n.quantity}: x${order.quantity}', style: TextStyle( fontSize: 14, color: AppColors.textSecondary, ), ), const SizedBox(height: 4), Text( '${l10n.unitPrice}: ¥${(order.amount / order.quantity).toStringAsFixed(2)}', style: TextStyle( fontSize: 13, color: AppColors.textTertiary, ), ), ], ), ), ], ), ], ), ); } Widget _buildCustomerCard(order, AppLocalizations l10n) { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), ), child: Column( children: [ _buildInfoRow(l10n.customerName, order.customerName, Icons.person_outline), const Divider(height: 24), _buildInfoRow(l10n.contactPhone, order.customerPhone, Icons.phone_outlined), if (order.scenicSpot != null) ...[ const Divider(height: 24), _buildInfoRow(l10n.belongScenic, order.scenicSpot!, Icons.place_outlined), ], ], ), ); } Widget _buildPaymentCard(order, AppLocalizations l10n) { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( l10n.paymentInfo, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.textPrimary, ), ), const SizedBox(height: 16), _buildPaymentRow(l10n.orderAmount, '¥${order.amount.toStringAsFixed(2)}', isBold: true), const SizedBox(height: 8), _buildPaymentRow(l10n.actualAmount, '¥${order.amount.toStringAsFixed(2)}'), if (order.paidAt != null) ...[ const SizedBox(height: 8), _buildPaymentRow( l10n.paymentTime, '${order.paidAt!.month}/${order.paidAt!.day} ${order.paidAt!.hour.toString().padLeft(2, '0')}:${order.paidAt!.minute.toString().padLeft(2, '0')}', ), ], ], ), ); } Widget _buildPaymentRow(String label, String value, {bool isBold = false}) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( label, style: TextStyle( fontSize: 14, color: isBold ? AppColors.textPrimary : AppColors.textSecondary, ), ), Text( value, style: TextStyle( fontSize: 15, fontWeight: isBold ? FontWeight.w600 : FontWeight.w400, color: isBold ? AppColors.primary : AppColors.textPrimary, ), ), ], ); } Widget _buildInfoCard(order, AppLocalizations l10n) { return Container( width: double.infinity, padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( l10n.orderInfo, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.textPrimary, ), ), const SizedBox(height: 16), _buildInfoRow(l10n.orderNo, order.orderNo, Icons.tag), const Divider(height: 24), _buildInfoRow(l10n.createTime, _formatDateTime(order.createdAt), Icons.access_time), if (order.verifiedAt != null) ...[ const Divider(height: 24), _buildInfoRow(l10n.verifyTime, _formatDateTime(order.verifiedAt!), Icons.check_circle_outline), ], if (order.refundedAt != null) ...[ const Divider(height: 24), _buildInfoRow(l10n.refundTime, _formatDateTime(order.refundedAt!), Icons.replay), ], if (order.verifyCode != null) ...[ const Divider(height: 24), _buildInfoRow(l10n.verifyCode, order.verifyCode!, Icons.qr_code), ], if (order.remark != null) ...[ const Divider(height: 24), _buildInfoRow(l10n.remark, order.remark!, Icons.notes), ], ], ), ); } Widget _buildInfoRow(String label, String value, IconData icon) { return Row( children: [ Icon(icon, size: 18, color: AppColors.primary), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: TextStyle(fontSize: 12, color: AppColors.textTertiary), ), const SizedBox(height: 2), Text( value, style: TextStyle( fontSize: 15, fontWeight: FontWeight.w500, color: AppColors.textPrimary, ), ), ], ), ), ], ); } String _formatDateTime(DateTime dt) { return '${dt.year}-${dt.month.toString().padLeft(2, '0')}-${dt.day.toString().padLeft(2, '0')} ${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}'; } }