fix(mobile-app): 合同签署页面添加重试机制解决竞态问题

前端在支付完成后立即请求合同签署任务,但后端 Kafka 事件可能还未完成
任务创建。添加最多5次重试,使用指数退避策略(500ms * attempt)。

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-25 04:01:25 -08:00
parent a7206eef2e
commit 9cf1bbbbd3
1 changed files with 39 additions and 21 deletions

View File

@ -81,37 +81,55 @@ class _ContractSigningPageState extends ConsumerState<ContractSigningPage> {
super.dispose();
}
///
///
Future<void> _loadTask() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final service = ref.read(contractSigningServiceProvider);
final task = await service.getTask(widget.orderNo);
const maxRetries = 5;
const retryDelay = Duration(milliseconds: 500);
setState(() {
_task = task;
_isLoading = false;
_remainingSeconds = task.remainingSeconds;
_hasScrolledToBottom = task.scrolledToBottomAt != null;
_hasAcknowledged = task.acknowledgedAt != null;
});
for (int attempt = 1; attempt <= maxRetries; attempt++) {
try {
final service = ref.read(contractSigningServiceProvider);
final task = await service.getTask(widget.orderNo);
//
_startCountdown();
setState(() {
_task = task;
_isLoading = false;
_remainingSeconds = task.remainingSeconds;
_hasScrolledToBottom = task.scrolledToBottomAt != null;
_hasAcknowledged = task.acknowledgedAt != null;
});
// PDF
if (task.status != ContractSigningStatus.signed) {
_loadPdf();
//
_startCountdown();
// PDF
if (task.status != ContractSigningStatus.signed) {
_loadPdf();
}
return; // 退
} catch (e) {
debugPrint('[ContractSigningPage] 加载任务失败 (尝试 $attempt/$maxRetries): $e');
// "任务不存在"
//
if (attempt < maxRetries && e.toString().contains('不存在')) {
debugPrint('[ContractSigningPage] 等待 ${retryDelay.inMilliseconds}ms 后重试...');
await Future.delayed(retryDelay * attempt); // 退
continue;
}
//
setState(() {
_isLoading = false;
_errorMessage = '加载签署任务失败: $e';
});
return;
}
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = '加载签署任务失败: $e';
});
}
}