|
|
|
@ -3,6 +3,7 @@ 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/services/version_update_service.dart'; |
|
|
|
import '../../../data/models/goods.dart'; |
|
|
|
import 'package:flutter_dotenv/flutter_dotenv.dart'; |
|
|
|
import '../../../data/services/network/dio_manager.dart'; |
|
|
|
@ -39,10 +40,20 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
/// 子类实现:返回商品列表(统一使用 DBGoods) |
|
|
|
Future<List<DBGoods>> fetchProducts(); |
|
|
|
|
|
|
|
/// 统一入口:不指定支付方式时,跳转到支付页面交由用户选择 |
|
|
|
/// 统一入口:根据后端配置决定是否弹出支付方式选择面板 |
|
|
|
Future<void> purchase(DBGoods item) async { |
|
|
|
final method = await _showPayMethodSheet(); |
|
|
|
// 读取渠道配置 |
|
|
|
final enabled = _getEnabledPayMethods(); |
|
|
|
|
|
|
|
// 无配置或多个渠道:弹出选择面板 |
|
|
|
_PayMethod? method; |
|
|
|
if (enabled.length != 1) { |
|
|
|
method = await _showPayMethodSheet(enabled); |
|
|
|
if (method == null) return; |
|
|
|
} else { |
|
|
|
// 仅一个渠道:直接走对应支付 |
|
|
|
method = enabled.first; |
|
|
|
} |
|
|
|
|
|
|
|
bool ok = false; |
|
|
|
String failMsg = '支付失败,请重试'; |
|
|
|
@ -75,8 +86,73 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// 底部弹窗:选择支付方式 |
|
|
|
Future<_PayMethod?> _showPayMethodSheet() async { |
|
|
|
/// 解析后端 paychannels 并结合平台过滤可用支付方式 |
|
|
|
List<_PayMethod> _getEnabledPayMethods() { |
|
|
|
try { |
|
|
|
final paychannels = |
|
|
|
VersionUpdateService.to.cachedAppInfo?.paychannels ?? ''; |
|
|
|
final raw = paychannels |
|
|
|
.split(',') |
|
|
|
.map((e) => e.trim().toLowerCase()) |
|
|
|
.where((e) => e.isNotEmpty) |
|
|
|
.toList(); |
|
|
|
|
|
|
|
final bool isIOS = GetPlatform.isIOS && !kIsWeb; |
|
|
|
final bool isAndroid = GetPlatform.isAndroid && !kIsWeb; |
|
|
|
|
|
|
|
final List<_PayMethod> methods = []; |
|
|
|
for (final ch in raw) { |
|
|
|
switch (ch) { |
|
|
|
case 'wxpay': |
|
|
|
case 'wechat': |
|
|
|
methods.add(_PayMethod.wechat); |
|
|
|
break; |
|
|
|
case 'alipay': |
|
|
|
methods.add(_PayMethod.alipay); |
|
|
|
break; |
|
|
|
case 'paypal': |
|
|
|
methods.add(_PayMethod.paypal); |
|
|
|
break; |
|
|
|
case 'apple': |
|
|
|
if (isIOS) methods.add(_PayMethod.apple); |
|
|
|
break; |
|
|
|
case 'google': |
|
|
|
if (isAndroid) methods.add(_PayMethod.google); |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 若后端未下发或全部被平台过滤,则回退为展示所有平台支持的方式 |
|
|
|
if (methods.isEmpty) { |
|
|
|
final fallback = <_PayMethod>[ |
|
|
|
_PayMethod.wechat, |
|
|
|
_PayMethod.alipay, |
|
|
|
_PayMethod.paypal |
|
|
|
]; |
|
|
|
if (isIOS) fallback.add(_PayMethod.apple); |
|
|
|
if (isAndroid) fallback.add(_PayMethod.google); |
|
|
|
return fallback; |
|
|
|
} |
|
|
|
return methods; |
|
|
|
} catch (_) { |
|
|
|
// 任意异常则回退为旧逻辑:展示所有 |
|
|
|
final bool isIOS = GetPlatform.isIOS && !kIsWeb; |
|
|
|
final bool isAndroid = GetPlatform.isAndroid && !kIsWeb; |
|
|
|
final fallback = <_PayMethod>[ |
|
|
|
_PayMethod.wechat, |
|
|
|
_PayMethod.alipay, |
|
|
|
_PayMethod.paypal |
|
|
|
]; |
|
|
|
if (isIOS) fallback.add(_PayMethod.apple); |
|
|
|
if (isAndroid) fallback.add(_PayMethod.google); |
|
|
|
return fallback; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// 底部弹窗:选择支付方式(仅展示后端允许的渠道) |
|
|
|
Future<_PayMethod?> _showPayMethodSheet(List<_PayMethod> allowed) async { |
|
|
|
final context = Get.context; |
|
|
|
final isDark = |
|
|
|
context != null && Theme.of(context).brightness == Brightness.dark; |
|
|
|
@ -121,6 +197,7 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
Row( |
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
|
|
|
children: [ |
|
|
|
if (allowed.contains(_PayMethod.wechat)) |
|
|
|
GestureDetector( |
|
|
|
onTap: () => Get.back(result: _PayMethod.wechat), |
|
|
|
child: Column( |
|
|
|
@ -131,8 +208,9 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
height: 56, |
|
|
|
decoration: BoxDecoration( |
|
|
|
shape: BoxShape.circle, |
|
|
|
color: |
|
|
|
isDark ? Colors.white10 : Colors.black12, |
|
|
|
color: isDark |
|
|
|
? Colors.white10 |
|
|
|
: Colors.black12, |
|
|
|
border: Border.all( |
|
|
|
color: isDark |
|
|
|
? Colors.white24 |
|
|
|
@ -153,6 +231,7 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
if (allowed.contains(_PayMethod.alipay)) |
|
|
|
GestureDetector( |
|
|
|
onTap: () => Get.back(result: _PayMethod.alipay), |
|
|
|
child: Column( |
|
|
|
@ -163,8 +242,9 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
height: 56, |
|
|
|
decoration: BoxDecoration( |
|
|
|
shape: BoxShape.circle, |
|
|
|
color: |
|
|
|
isDark ? Colors.white10 : Colors.black12, |
|
|
|
color: isDark |
|
|
|
? Colors.white10 |
|
|
|
: Colors.black12, |
|
|
|
border: Border.all( |
|
|
|
color: isDark |
|
|
|
? Colors.white24 |
|
|
|
@ -185,6 +265,7 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
if (allowed.contains(_PayMethod.paypal)) |
|
|
|
GestureDetector( |
|
|
|
onTap: () => Get.back(result: _PayMethod.paypal), |
|
|
|
child: Column( |
|
|
|
@ -195,8 +276,9 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
height: 56, |
|
|
|
decoration: BoxDecoration( |
|
|
|
shape: BoxShape.circle, |
|
|
|
color: |
|
|
|
isDark ? Colors.white10 : Colors.black12, |
|
|
|
color: isDark |
|
|
|
? Colors.white10 |
|
|
|
: Colors.black12, |
|
|
|
border: Border.all( |
|
|
|
color: isDark |
|
|
|
? Colors.white24 |
|
|
|
@ -219,7 +301,7 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
if (isIOS) |
|
|
|
if (isIOS && allowed.contains(_PayMethod.apple)) |
|
|
|
GestureDetector( |
|
|
|
onTap: () => Get.back(result: _PayMethod.apple), |
|
|
|
child: Column( |
|
|
|
@ -255,7 +337,7 @@ abstract class GoodsBaseController extends GetxController { |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
if (isAndroid) |
|
|
|
if (isAndroid && allowed.contains(_PayMethod.google)) |
|
|
|
GestureDetector( |
|
|
|
onTap: () => Get.back(result: _PayMethod.google), |
|
|
|
child: Column( |
|
|
|
|