fix: prevent duplicate store submissions by adding SUBMITTING state guard
- Add SUBMITTING to skip guard in executeSubmitAsync to prevent concurrent uploads - Add getSubmittingStores() public method to check SUBMITTING state - Add controller-level check to reject submissions when stores are already uploading - Prevents VIVO/Honor 'app is under review' errors from duplicate uploads Co-Authored-By: Claude <noreply@anthropic.com>
这个提交包含在:
父节点
786051510b
当前提交
a6da4f3560
@ -121,6 +121,17 @@ public class AppStoreController {
|
||||
if (scheduledPublishAtText != null && !scheduledPublishAtText.isBlank()) {
|
||||
scheduledPublishAt = java.time.LocalDateTime.parse(scheduledPublishAtText);
|
||||
}
|
||||
|
||||
// Reject if any requested store is already uploading (SUBMITTING state)
|
||||
List<String> submitting = submissionService.getSubmittingStores(versionId);
|
||||
if (!submitting.isEmpty()) {
|
||||
List<String> requested = storeTypes != null ? storeTypes : submitting; // null means all targets
|
||||
List<String> conflict = submitting.stream().filter(requested::contains).toList();
|
||||
if (!conflict.isEmpty()) {
|
||||
throw new IllegalStateException("以下渠道正在上传中,请等待完成后再试: " + String.join(", ", conflict));
|
||||
}
|
||||
}
|
||||
|
||||
AppVersionEntity v = storeService.markSubmitted(versionId,
|
||||
storeTypes,
|
||||
submitMode,
|
||||
|
||||
@ -184,7 +184,8 @@ public class StoreSubmissionService {
|
||||
try {
|
||||
// Skip stores already in active review to avoid duplicate submissions
|
||||
String activeState = currentStoreState(v.getStoreReviewStatus(), storeType);
|
||||
if ("UNDER_REVIEW".equals(activeState) || "APPROVED".equals(activeState)) {
|
||||
if ("UNDER_REVIEW".equals(activeState) || "APPROVED".equals(activeState)
|
||||
|| "SUBMITTING".equals(activeState)) {
|
||||
skippedCount.incrementAndGet();
|
||||
log.info("Skipping {} for version={} batchId={} — already in state {}",
|
||||
storeType, versionId, batchId, activeState);
|
||||
@ -1254,6 +1255,37 @@ public class StoreSubmissionService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns store types that are currently in SUBMITTING state for the given version.
|
||||
* Used by the controller to reject duplicate submission requests.
|
||||
*/
|
||||
public List<String> getSubmittingStores(String versionId) {
|
||||
AppVersionEntity v = versionRepo.findById(versionId).orElse(null);
|
||||
if (v == null || v.getStoreReviewStatus() == null || v.getStoreReviewStatus().isBlank()) {
|
||||
return List.of();
|
||||
}
|
||||
try {
|
||||
Map<String, Object> reviewMap = mapper.readValue(v.getStoreReviewStatus(), new TypeReference<>() {});
|
||||
List<String> submitting = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : reviewMap.entrySet()) {
|
||||
String store = entry.getKey();
|
||||
String state = "";
|
||||
if (entry.getValue() instanceof Map<?, ?> m) {
|
||||
Object s = m.get("state");
|
||||
state = s instanceof String str ? str : "";
|
||||
} else if (entry.getValue() instanceof String s) {
|
||||
state = s;
|
||||
}
|
||||
if ("SUBMITTING".equals(state)) {
|
||||
submitting.add(store);
|
||||
}
|
||||
}
|
||||
return submitting;
|
||||
} catch (Exception e) {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void sweepStuckSubmittingForVersion(String versionId, String matchBatchId, String failReason) {
|
||||
try {
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户