import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../controllers/payment_controller.dart'; class PaymentView extends GetView { const PaymentView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], appBar: AppBar( backgroundColor: isDarkMode ? Colors.black : Colors.white, elevation: 0.5, title: Text( '支付测试', style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), centerTitle: true, leading: IconButton( icon: Icon( Icons.arrow_back_ios, color: isDarkMode ? Colors.white : Colors.black, ), onPressed: () => Get.back(), ), ), body: SafeArea( top: false, child: SingleChildScrollView( padding: EdgeInsets.all(16.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildTestInfoCard(isDarkMode), SizedBox(height: 20.h), _buildPaymentMethodSelector(isDarkMode), SizedBox(height: 20.h), _buildAmountSelector(isDarkMode), SizedBox(height: 20.h), _buildPaymentButton(isDarkMode), SizedBox(height: 20.h), _buildStatusCard(isDarkMode), SizedBox(height: 20.h), _buildInstructions(isDarkMode), ], ), ), ), ); } /// 测试信息卡片 Widget _buildTestInfoCard(bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900] : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '测试订单信息', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), SizedBox(height: 12.h), Obx(() => _buildInfoRow( '商品ID', controller.testProductId.value, isDarkMode)), SizedBox(height: 8.h), _buildInfoRow('商品描述', '微信支付测试', isDarkMode), SizedBox(height: 8.h), Obx(() => _buildInfoRow( '支付金额', '¥${controller.testAmount.value.toStringAsFixed(2)}', isDarkMode)), ], ), ); } /// 信息行 Widget _buildInfoRow(String label, String value, bool isDarkMode) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 80.w, child: Text( '$label:', style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.grey[400] : Colors.grey[600], ), ), ), Expanded( child: Text( value, style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white : Colors.black, ), ), ), ], ); } /// 金额选择器 Widget _buildAmountSelector(bool isDarkMode) { final amounts = [0.01, 0.10, 1.00, 10.00]; return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900] : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '选择测试金额', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), SizedBox(height: 12.h), Wrap( spacing: 12.w, runSpacing: 8.h, children: amounts.map((amount) { return Obx(() => GestureDetector( onTap: () => controller.updateTestAmount(amount), child: Container( padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), decoration: BoxDecoration( color: controller.testAmount.value == amount ? Colors.blue[600] : (isDarkMode ? Colors.grey[800] : Colors.grey[200]), borderRadius: BorderRadius.circular(20.r), ), child: Text( '¥${amount.toStringAsFixed(2)}', style: TextStyle( fontSize: 14.sp, color: controller.testAmount.value == amount ? Colors.white : (isDarkMode ? Colors.white : Colors.black), ), ), ), )); }).toList(), ), ], ), ); } /// 支付方式选择器 Widget _buildPaymentMethodSelector(bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900] : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '选择支付方式', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), SizedBox(height: 16.h), // 移除外层的 Obx,因为内部的 _buildPaymentMethodOption 已经有 Obx 了 Column( children: [ _buildPaymentMethodOption( method: 1, title: '微信支付', icon: Icons.wechat, iconColor: Colors.green, isDarkMode: isDarkMode, ), SizedBox(height: 12.h), _buildPaymentMethodOption( method: 2, title: '支付宝支付', icon: Icons.account_balance_wallet, iconColor: Colors.blue, isDarkMode: isDarkMode, ), ], ), ], ), ); } /// 支付方式选项 Widget _buildPaymentMethodOption({ required int method, required String title, required IconData icon, required Color iconColor, required bool isDarkMode, }) { return Obx(() => GestureDetector( onTap: () => controller.selectPaymentMethod(method), child: Container( padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: controller.selectedPaymentMethod.value == method ? (isDarkMode ? Colors.blue.withOpacity(0.2) : Colors.blue.withOpacity(0.1)) : (isDarkMode ? Colors.grey[800] : Colors.grey[100]), borderRadius: BorderRadius.circular(8.r), border: Border.all( color: controller.selectedPaymentMethod.value == method ? Colors.blue : Colors.transparent, width: 1.5, ), ), child: Row( children: [ Icon( icon, color: iconColor, size: 24.sp, ), SizedBox(width: 12.w), Expanded( child: Text( title, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w500, color: isDarkMode ? Colors.white : Colors.black, ), ), ), if (controller.selectedPaymentMethod.value == method) Icon( Icons.check_circle, color: Colors.blue, size: 20.sp, ), ], ), ), )); } /// 支付按钮 Widget _buildPaymentButton(bool isDarkMode) { return Obx(() => Container( width: double.infinity, height: 50.h, child: ElevatedButton( onPressed: controller.isLoading.value ? null : () { controller.processPayment(); }, style: ElevatedButton.styleFrom( backgroundColor: controller.isLoading.value ? Colors.grey : (controller.selectedPaymentMethod.value == 1 ? Colors.green : Colors.blue), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), elevation: 2, ), child: controller.isLoading.value ? Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: 20.w, height: 20.w, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.white), ), ), SizedBox(width: 12.w), Text( '支付中...', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: Colors.white, ), ), ], ) : Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( controller.selectedPaymentMethod.value == 1 ? Icons.wechat : Icons.account_balance_wallet, color: Colors.white, size: 20.sp, ), SizedBox(width: 8.w), Text( controller.selectedPaymentMethod.value == 1 ? '微信支付 ¥${controller.testAmount.value.toStringAsFixed(2)}' : '支付宝支付 ¥${controller.testAmount.value.toStringAsFixed(2)}', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: Colors.white, ), ), ], ), ), )); } /// 状态卡片 Widget _buildStatusCard(bool isDarkMode) { return Obx(() { if (controller.paymentStatus.value.isEmpty) { return const SizedBox.shrink(); } final isError = controller.errorMessage.value.isNotEmpty; return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isError ? (isDarkMode ? Colors.red[900] : Colors.red[50]) : (isDarkMode ? Colors.green[900] : Colors.green[50]), borderRadius: BorderRadius.circular(12.r), border: Border.all( color: isError ? Colors.red[300]! : Colors.green[300]!, width: 1, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( isError ? Icons.error : Icons.check_circle, color: isError ? Colors.red[600] : Colors.green[600], size: 20.w, ), SizedBox(width: 8.w), Text( '支付状态', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isError ? Colors.red[600] : Colors.green[600], ), ), ], ), SizedBox(height: 8.h), Text( controller.paymentStatus.value, style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white : Colors.black, ), ), if (controller.errorMessage.value.isNotEmpty) ...[ SizedBox(height: 8.h), Text( '错误信息: ${controller.errorMessage.value}', style: TextStyle( fontSize: 12.sp, color: Colors.red[600], ), ), ], SizedBox(height: 12.h), SizedBox( width: double.infinity, child: OutlinedButton( onPressed: controller.resetStatus, style: OutlinedButton.styleFrom( side: BorderSide( color: isError ? Colors.red[600]! : Colors.green[600]!, ), ), child: Text( '重新测试', style: TextStyle( color: isError ? Colors.red[600] : Colors.green[600], ), ), ), ), ], ), ); }); } /// 使用说明 Widget _buildInstructions(bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900] : Colors.blue[50], borderRadius: BorderRadius.circular(12.r), border: Border.all( color: Colors.blue[200]!, width: 1, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.info_outline, color: Colors.blue[600], size: 20.w, ), SizedBox(width: 8.w), Text( '使用说明', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: Colors.blue[600], ), ), ], ), SizedBox(height: 12.h), Text( '1. 选择测试金额(建议使用0.01元进行测试)\n' '2. 点击"发起微信支付"按钮\n' '3. 系统将调用微信支付SDK\n' '4. 在微信中完成支付流程\n' '5. 返回应用查看支付结果\n\n' '注意:这是测试环境,实际不会产生真实扣费', style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.grey[300] : Colors.grey[700], height: 1.5, ), ), ], ), ); } }