新增支付流程,新增支付页面等待倒计时,自动检查订单状态等
This commit is contained in:
@@ -11,7 +11,7 @@ import '../../../utils/kr_common_util.dart';
|
||||
import '../../../localization/app_translations.dart';
|
||||
import '../../../utils/kr_log_util.dart';
|
||||
|
||||
/// 订单状态控制器
|
||||
/// 订单状态控制器(参考 Tauri 项目实现)
|
||||
class KROrderStatusController extends GetxController {
|
||||
/// API服务
|
||||
final KRSubscribeApi kr_subscribeApi = KRSubscribeApi();
|
||||
@@ -23,7 +23,7 @@ class KROrderStatusController extends GetxController {
|
||||
final RxBool kr_isLoading = true.obs;
|
||||
|
||||
/// 支付URL
|
||||
final String kr_paymentUrl = Get.arguments['url'] as String;
|
||||
final String kr_paymentUrl = Get.arguments['url'] as String? ?? '';
|
||||
|
||||
/// 订单信息
|
||||
final String kr_order = Get.arguments['order'];
|
||||
@@ -31,9 +31,27 @@ class KROrderStatusController extends GetxController {
|
||||
/// 支付方式类型
|
||||
final String kr_paymentType = Get.arguments['payment_type'] as String;
|
||||
|
||||
/// Checkout 类型(url, qr, stripe)
|
||||
final String kr_checkoutType = Get.arguments['checkout_type'] as String? ?? 'url';
|
||||
|
||||
/// 定时器
|
||||
Timer? kr_timer;
|
||||
|
||||
/// 倒计时定时器
|
||||
Timer? kr_countdownTimer;
|
||||
|
||||
/// 15分钟倒计时(毫秒)
|
||||
final RxInt kr_countdown = (15 * 60 * 1000).obs;
|
||||
|
||||
/// 格式化的倒计时字符串
|
||||
final RxString kr_formattedCountdown = '15:00'.obs;
|
||||
|
||||
/// 订单创建时间(用于计算倒计时)
|
||||
DateTime? kr_orderCreatedAt;
|
||||
|
||||
/// 上次刷新时间
|
||||
int kr_lastRefreshTime = 0;
|
||||
|
||||
/// 订单状态常量
|
||||
static const int kr_statusPending = 1; // 待支付
|
||||
static const int kr_statusPaid = 2; // 已支付
|
||||
@@ -53,129 +71,221 @@ class KROrderStatusController extends GetxController {
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
print('═══════════════════════════════════════');
|
||||
print('📊 订单状态页面初始化');
|
||||
print(' 订单号: $kr_order');
|
||||
print(' 支付方式: $kr_paymentType');
|
||||
print(' Checkout类型: $kr_checkoutType');
|
||||
print('═══════════════════════════════════════');
|
||||
|
||||
// 立即查询一次订单状态,获取创建时间
|
||||
kr_checkPaymentStatus();
|
||||
// 启动轮询和倒计时
|
||||
kr_startCheckingPaymentStatus();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
// 只有在非余额支付且有支付URL时才处理支付跳转
|
||||
if (kr_paymentUrl.isNotEmpty && kr_paymentType != 'balance') {
|
||||
if (Platform.isAndroid || Platform.isIOS) {
|
||||
// 移动端使用 WebView
|
||||
Get.toNamed(
|
||||
Routes.KR_WEBVIEW,
|
||||
arguments: {
|
||||
'url': kr_paymentUrl,
|
||||
'order': kr_order,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
// 桌面端使用外部浏览器
|
||||
final Uri uri = Uri.parse(kr_paymentUrl);
|
||||
launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||
}
|
||||
}
|
||||
// 注意:支付链接已经在购买流程中打开了,这里不再重复打开
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
print('🔚 订单状态页面关闭,清理定时器');
|
||||
kr_timer?.cancel();
|
||||
kr_countdownTimer?.cancel();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
/// 开始检查支付状态
|
||||
/// 开始检查支付状态(参考 Tauri 项目:5秒轮询一次)
|
||||
void kr_startCheckingPaymentStatus() {
|
||||
// 根据支付方式类型设置不同的查询间隔
|
||||
final Duration interval = kr_paymentType == 'balance'
|
||||
? const Duration(seconds: 2) // 余额支付每2秒查询一次
|
||||
: const Duration(seconds: 5); // 其他支付方式每5秒查询一次
|
||||
|
||||
kr_timer = Timer.periodic(interval, (timer) {
|
||||
print('🔄 启动支付状态轮询(每5秒检查一次)');
|
||||
|
||||
// 状态轮询:每5秒检查一次订单状态
|
||||
kr_timer = Timer.periodic(const Duration(seconds: 5), (timer) {
|
||||
kr_checkPaymentStatus();
|
||||
});
|
||||
|
||||
// 倒计时更新:每1秒更新一次UI显示
|
||||
kr_countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||
kr_updateCountdown();
|
||||
});
|
||||
}
|
||||
|
||||
/// 检查支付状态
|
||||
/// 更新倒计时(参考 Tauri 项目)
|
||||
void kr_updateCountdown() {
|
||||
if (kr_orderCreatedAt == null) {
|
||||
// 订单创建时间还未获取,显示默认倒计时
|
||||
kr_formattedCountdown.value = '15:00';
|
||||
print('⏱️ 倒计时更新: 等待订单创建时间...');
|
||||
return;
|
||||
}
|
||||
|
||||
final now = DateTime.now().millisecondsSinceEpoch;
|
||||
final createdAt = kr_orderCreatedAt!.millisecondsSinceEpoch;
|
||||
final targetTime = createdAt + (15 * 60 * 1000); // 15分钟后
|
||||
|
||||
final timeLeft = targetTime - now;
|
||||
|
||||
print('⏱️ 倒计时调试信息:');
|
||||
print(' 当前时间(ms): $now');
|
||||
print(' 创建时间(ms): $createdAt');
|
||||
print(' 目标时间(ms): $targetTime');
|
||||
print(' 剩余时间(ms): $timeLeft');
|
||||
print(' 剩余时间(秒): ${(timeLeft / 1000).floor()}');
|
||||
|
||||
if (timeLeft > 0) {
|
||||
kr_countdown.value = timeLeft;
|
||||
// 格式化倒计时:MM:SS
|
||||
final minutes = (timeLeft / 60000).floor();
|
||||
final seconds = ((timeLeft % 60000) / 1000).floor();
|
||||
kr_formattedCountdown.value = '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
|
||||
print(' 格式化倒计时: ${kr_formattedCountdown.value}');
|
||||
} else {
|
||||
// 倒计时结束,订单超时
|
||||
kr_countdown.value = 0;
|
||||
kr_formattedCountdown.value = '00:00';
|
||||
kr_countdownTimer?.cancel();
|
||||
kr_timer?.cancel();
|
||||
|
||||
print('⏱️ 订单支付超时(15分钟)');
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.closedTitle;
|
||||
kr_statusDescription.value = '订单已超时,请重新下单';
|
||||
kr_isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查支付状态(使用公开接口,参考 Tauri 项目)
|
||||
Future<void> kr_checkPaymentStatus() async {
|
||||
final now = DateTime.now().millisecondsSinceEpoch;
|
||||
|
||||
try {
|
||||
final result = await kr_subscribeApi.kr_orderDetail(kr_order);
|
||||
print('🔍 检查订单状态 [${kr_order}]');
|
||||
|
||||
// 使用公开接口查询订单状态
|
||||
final result = await kr_subscribeApi.kr_queryOrderStatus(kr_order);
|
||||
|
||||
result.fold(
|
||||
(error) {
|
||||
KRLogUtil.kr_e('检查支付状态失败: $error', tag: 'OrderStatusController');
|
||||
print('❌ 查询失败: ${error.msg}');
|
||||
KRLogUtil.kr_e('检查支付状态失败: ${error.msg}', tag: 'OrderStatusController');
|
||||
kr_isLoading.value = false;
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.checkFailedTitle;
|
||||
kr_statusDescription.value = AppTranslations.kr_orderStatus.checkFailedDescription;
|
||||
kr_statusIcon.value = 'payment_success';
|
||||
},
|
||||
(kr_orderStatus) {
|
||||
KRLogUtil.kr_i('检查支付状态: ${kr_orderStatus.toJson()}', tag: 'OrderStatusController');
|
||||
// 保存订单创建时间(用于倒计时)
|
||||
if (kr_orderCreatedAt == null && kr_orderStatus.kr_createdAt > 0) {
|
||||
// 判断是秒级还是毫秒级时间戳
|
||||
// 如果时间戳大于10位数字,说明是毫秒级
|
||||
final timestamp = kr_orderStatus.kr_createdAt;
|
||||
final isMilliseconds = timestamp > 10000000000; // 大于10位数说明是毫秒级
|
||||
|
||||
kr_orderCreatedAt = DateTime.fromMillisecondsSinceEpoch(
|
||||
isMilliseconds ? timestamp : timestamp * 1000
|
||||
);
|
||||
|
||||
print('📅 订单创建时间: ${kr_orderCreatedAt}');
|
||||
print('📅 原始时间戳: $timestamp');
|
||||
print('📅 时间戳类型: ${isMilliseconds ? "毫秒级" : "秒级"}');
|
||||
print('📅 转换后时间戳(ms): ${kr_orderCreatedAt!.millisecondsSinceEpoch}');
|
||||
}
|
||||
|
||||
print('📊 订单状态: ${kr_orderStatus.kr_status} (${_getStatusName(kr_orderStatus.kr_status)})');
|
||||
|
||||
switch (kr_orderStatus.kr_status) {
|
||||
case kr_statusPending:
|
||||
// 待支付状态,继续轮询
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.pendingTitle;
|
||||
kr_statusDescription.value = AppTranslations.kr_orderStatus.pendingDescription;
|
||||
kr_statusDescription.value = '${AppTranslations.kr_orderStatus.pendingDescription}\n剩余时间: ${kr_formattedCountdown.value}';
|
||||
kr_statusIcon.value = 'payment_success';
|
||||
break;
|
||||
|
||||
case kr_statusPaid:
|
||||
// 已支付状态,继续轮询直到完成
|
||||
print('✅ 订单已支付,等待确认...');
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.paidTitle;
|
||||
kr_statusDescription.value = AppTranslations.kr_orderStatus.paidDescription;
|
||||
kr_statusIcon.value = 'payment_success';
|
||||
break;
|
||||
|
||||
case kr_statusFinished:
|
||||
// 订单完成
|
||||
print('🎉 订单完成!停止轮询');
|
||||
kr_isPaymentSuccess.value = true;
|
||||
kr_isLoading.value = false;
|
||||
kr_timer?.cancel();
|
||||
kr_countdownTimer?.cancel();
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.successTitle;
|
||||
kr_statusDescription.value = AppTranslations.kr_orderStatus.successDescription;
|
||||
kr_statusIcon.value = 'payment_success';
|
||||
// 发送支付成功事件
|
||||
KREventBus().kr_sendMessage(KRMessageType.kr_payment);
|
||||
break;
|
||||
|
||||
case kr_statusClose:
|
||||
// 订单已关闭
|
||||
print('❌ 订单已关闭');
|
||||
kr_isLoading.value = false;
|
||||
kr_timer?.cancel();
|
||||
kr_countdownTimer?.cancel();
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.closedTitle;
|
||||
kr_statusDescription.value = AppTranslations.kr_orderStatus.closedDescription;
|
||||
kr_statusIcon.value = 'payment_success';
|
||||
break;
|
||||
|
||||
case kr_statusFailed:
|
||||
// 支付失败
|
||||
print('❌ 支付失败');
|
||||
kr_isLoading.value = false;
|
||||
kr_timer?.cancel();
|
||||
kr_countdownTimer?.cancel();
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.failedTitle;
|
||||
kr_statusDescription.value = AppTranslations.kr_orderStatus.failedDescription;
|
||||
kr_statusIcon.value = 'payment_success';
|
||||
break;
|
||||
|
||||
default:
|
||||
// 未知状态
|
||||
print('⚠️ 未知状态: ${kr_orderStatus.kr_status}');
|
||||
kr_isLoading.value = false;
|
||||
kr_timer?.cancel();
|
||||
kr_countdownTimer?.cancel();
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.unknownTitle;
|
||||
kr_statusDescription.value = AppTranslations.kr_orderStatus.unknownDescription;
|
||||
kr_statusIcon.value = 'payment_success';
|
||||
break;
|
||||
}
|
||||
|
||||
kr_lastRefreshTime = now;
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
print('❌ 异常: $error');
|
||||
KRLogUtil.kr_e('检查支付状态失败: $error', tag: 'OrderStatusController');
|
||||
kr_isLoading.value = false;
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.checkFailedTitle;
|
||||
kr_statusDescription.value = AppTranslations.kr_orderStatus.checkFailedDescription;
|
||||
kr_statusIcon.value = 'payment_success';
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查支付状态
|
||||
Future<void> kr_checkPaymentStatusWithRetry() async {
|
||||
try {
|
||||
// ... 其他代码 ...
|
||||
} catch (err) {
|
||||
KRLogUtil.kr_e('检查支付状态失败: $err', tag: 'OrderStatusController');
|
||||
/// 获取状态名称(用于日志)
|
||||
String _getStatusName(int status) {
|
||||
switch (status) {
|
||||
case kr_statusPending:
|
||||
return '待支付';
|
||||
case kr_statusPaid:
|
||||
return '已支付';
|
||||
case kr_statusClose:
|
||||
return '已关闭';
|
||||
case kr_statusFailed:
|
||||
return '支付失败';
|
||||
case kr_statusFinished:
|
||||
return '已完成';
|
||||
default:
|
||||
return '未知';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user