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:
parent
a7206eef2e
commit
9cf1bbbbd3
|
|
@ -81,37 +81,55 @@ class _ContractSigningPageState extends ConsumerState<ContractSigningPage> {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 加载签署任务
|
/// 加载签署任务(带重试机制,解决竞态问题)
|
||||||
Future<void> _loadTask() async {
|
Future<void> _loadTask() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
_errorMessage = null;
|
_errorMessage = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
const maxRetries = 5;
|
||||||
final service = ref.read(contractSigningServiceProvider);
|
const retryDelay = Duration(milliseconds: 500);
|
||||||
final task = await service.getTask(widget.orderNo);
|
|
||||||
|
|
||||||
setState(() {
|
for (int attempt = 1; attempt <= maxRetries; attempt++) {
|
||||||
_task = task;
|
try {
|
||||||
_isLoading = false;
|
final service = ref.read(contractSigningServiceProvider);
|
||||||
_remainingSeconds = task.remainingSeconds;
|
final task = await service.getTask(widget.orderNo);
|
||||||
_hasScrolledToBottom = task.scrolledToBottomAt != null;
|
|
||||||
_hasAcknowledged = task.acknowledgedAt != null;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 启动倒计时
|
setState(() {
|
||||||
_startCountdown();
|
_task = task;
|
||||||
|
_isLoading = false;
|
||||||
|
_remainingSeconds = task.remainingSeconds;
|
||||||
|
_hasScrolledToBottom = task.scrolledToBottomAt != null;
|
||||||
|
_hasAcknowledged = task.acknowledgedAt != null;
|
||||||
|
});
|
||||||
|
|
||||||
// 加载 PDF
|
// 启动倒计时
|
||||||
if (task.status != ContractSigningStatus.signed) {
|
_startCountdown();
|
||||||
_loadPdf();
|
|
||||||
|
// 加载 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';
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue