|
|
|
@ -1,10 +1,12 @@ |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
import 'package:get/get.dart'; |
|
|
|
import 'package:voitrans/data/models/user_Info.dart'; |
|
|
|
import '../../../routes/app_routes.dart'; |
|
|
|
import '../../../data/services/pay_service.dart'; |
|
|
|
import '../../../data/models/goods.dart'; |
|
|
|
import 'package:flutter_dotenv/flutter_dotenv.dart'; |
|
|
|
import '../../../data/services/network/dio_manager.dart'; |
|
|
|
import '../../../data/services/network/api.dart'; |
|
|
|
|
|
|
|
/// goods 模块基础控制器,封装通用的商品加载与支付流程 |
|
|
|
abstract class GoodsBaseController extends GetxController { |
|
|
|
@ -238,7 +240,21 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
onResult?.call(false, '创建微信订单失败'); |
|
|
|
return false; |
|
|
|
} |
|
|
|
return _payService.wechatPay(paymentData: paymentData, onResult: onResult); |
|
|
|
final orderId = |
|
|
|
paymentData['orderId'] as String? ?? _payService.lastOrderId; |
|
|
|
return _payService.wechatPay( |
|
|
|
paymentData: paymentData, |
|
|
|
onResult: (success, msg) async { |
|
|
|
// 先透传给外部回调 |
|
|
|
onResult?.call(success, msg); |
|
|
|
if (success) { |
|
|
|
await _confirmOrderAndShow(orderId, |
|
|
|
channel: '微信', initialMessage: msg); |
|
|
|
} else { |
|
|
|
_showPayResultDialog(false, msg ?? '支付失败'); |
|
|
|
} |
|
|
|
}, |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
/// 指定支付宝支付(直接下单并拉起支付宝) |
|
|
|
@ -256,7 +272,142 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
onResult?.call(false, '创建支付宝订单失败'); |
|
|
|
return false; |
|
|
|
} |
|
|
|
return _payService.alipay(orderInfo: orderInfo, onResult: onResult); |
|
|
|
final orderId = _payService.lastOrderId; // 创建订单时已缓存 |
|
|
|
return _payService.alipay( |
|
|
|
orderInfo: orderInfo, |
|
|
|
onResult: (success, msg) async { |
|
|
|
onResult?.call(success, msg); |
|
|
|
if (success) { |
|
|
|
await _confirmOrderAndShow(orderId, |
|
|
|
channel: '支付宝', initialMessage: msg); |
|
|
|
} else { |
|
|
|
_showPayResultDialog(false, msg ?? '支付失败'); |
|
|
|
} |
|
|
|
}, |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
Future<void> _confirmOrderAndShow(String? orderId, |
|
|
|
{required String channel, String? initialMessage}) async { |
|
|
|
// 若无法获取订单号,直接弹成功提示但提醒稍后刷新 |
|
|
|
if (orderId == null || orderId.isEmpty) { |
|
|
|
_showPayResultDialog(true, '${channel}支付成功,订单处理中,请稍后查看。'); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
String message = initialMessage ?? '${channel}支付成功'; |
|
|
|
bool success = false; |
|
|
|
try { |
|
|
|
// 简单轮询回查,避免回调延迟 |
|
|
|
for (int i = 0; i < 5; i++) { |
|
|
|
final resp = await Api.payaskorder({'order_id': orderId}); |
|
|
|
print("查询订单 resp: $resp"); |
|
|
|
final order = resp?['order'] as Map<String, dynamic>?; |
|
|
|
final user = resp?['user'] as Map<String, dynamic>?; |
|
|
|
if (order != null && user != null) { |
|
|
|
final orderStatus = order["status"]; |
|
|
|
if (orderStatus == 1) { |
|
|
|
User.instance.updateUserInfo(user); |
|
|
|
success = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
await Future.delayed(const Duration(milliseconds: 1500)); |
|
|
|
} |
|
|
|
|
|
|
|
// 若标记成功但未拿到用户信息,使用token登录接口回拉用户资料,确保额度刷新 |
|
|
|
if (success) { |
|
|
|
try { |
|
|
|
final response = await Api.tokenlogin(); |
|
|
|
if (response is Map && response['user'] is Map<String, dynamic>) { |
|
|
|
User.instance |
|
|
|
.updateUserInfo(response['user'] as Map<String, dynamic>); |
|
|
|
} |
|
|
|
} catch (_) {} |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
message = '查询支付结果异常: $e'; |
|
|
|
} |
|
|
|
_showPayResultDialog(success, message); |
|
|
|
} |
|
|
|
|
|
|
|
void _showPayResultDialog(bool success, String message) { |
|
|
|
final context = Get.context; |
|
|
|
final isDark = |
|
|
|
context != null && Theme.of(context).brightness == Brightness.dark; |
|
|
|
Get.dialog( |
|
|
|
Dialog( |
|
|
|
insetPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 24), |
|
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), |
|
|
|
backgroundColor: isDark ? Colors.grey[900] : Colors.white, |
|
|
|
child: Padding( |
|
|
|
padding: const EdgeInsets.all(20), |
|
|
|
child: Column( |
|
|
|
mainAxisSize: MainAxisSize.min, |
|
|
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
|
|
children: [ |
|
|
|
Row( |
|
|
|
children: [ |
|
|
|
Container( |
|
|
|
width: 48, |
|
|
|
height: 48, |
|
|
|
decoration: BoxDecoration( |
|
|
|
color: success |
|
|
|
? (isDark ? Colors.green[800] : Colors.green[100]) |
|
|
|
: (isDark ? Colors.red[800] : Colors.red[100]), |
|
|
|
borderRadius: BorderRadius.circular(12), |
|
|
|
), |
|
|
|
child: Icon( |
|
|
|
success ? Icons.check_circle : Icons.error, |
|
|
|
color: |
|
|
|
success ? Colors.green[600] : Colors.redAccent[200], |
|
|
|
size: 28, |
|
|
|
), |
|
|
|
), |
|
|
|
const SizedBox(width: 12), |
|
|
|
Expanded( |
|
|
|
child: Column( |
|
|
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
|
|
children: [ |
|
|
|
Text( |
|
|
|
success ? '支付成功' : '支付失败', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 18, |
|
|
|
fontWeight: FontWeight.w700, |
|
|
|
color: isDark ? Colors.white : Colors.black, |
|
|
|
), |
|
|
|
), |
|
|
|
const SizedBox(height: 6), |
|
|
|
Text( |
|
|
|
message, |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 13, |
|
|
|
color: isDark ? Colors.white70 : Colors.grey[700], |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
const SizedBox(height: 16), |
|
|
|
Divider(color: isDark ? Colors.white24 : Colors.black12), |
|
|
|
const SizedBox(height: 12), |
|
|
|
Row( |
|
|
|
mainAxisAlignment: MainAxisAlignment.end, |
|
|
|
children: [ |
|
|
|
TextButton( |
|
|
|
onPressed: () => Get.back(), |
|
|
|
child: const Text('知道了'), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
barrierDismissible: true, |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
/// 指定 PayPal 支付(创建订单并打开授权链接) |
|
|
|
|