diff --git a/update-service/src/main/java/com/xuqm/update/controller/AppStoreController.java b/update-service/src/main/java/com/xuqm/update/controller/AppStoreController.java index 01605c0..a85d1dc 100644 --- a/update-service/src/main/java/com/xuqm/update/controller/AppStoreController.java +++ b/update-service/src/main/java/com/xuqm/update/controller/AppStoreController.java @@ -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 submitting = submissionService.getSubmittingStores(versionId); + if (!submitting.isEmpty()) { + List requested = storeTypes != null ? storeTypes : submitting; // null means all targets + List conflict = submitting.stream().filter(requested::contains).toList(); + if (!conflict.isEmpty()) { + throw new IllegalStateException("以下渠道正在上传中,请等待完成后再试: " + String.join(", ", conflict)); + } + } + AppVersionEntity v = storeService.markSubmitted(versionId, storeTypes, submitMode, diff --git a/update-service/src/main/java/com/xuqm/update/service/StoreSubmissionService.java b/update-service/src/main/java/com/xuqm/update/service/StoreSubmissionService.java index ee8c7d9..4311fa6 100644 --- a/update-service/src/main/java/com/xuqm/update/service/StoreSubmissionService.java +++ b/update-service/src/main/java/com/xuqm/update/service/StoreSubmissionService.java @@ -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 getSubmittingStores(String versionId) { + AppVersionEntity v = versionRepo.findById(versionId).orElse(null); + if (v == null || v.getStoreReviewStatus() == null || v.getStoreReviewStatus().isBlank()) { + return List.of(); + } + try { + Map reviewMap = mapper.readValue(v.getStoreReviewStatus(), new TypeReference<>() {}); + List submitting = new ArrayList<>(); + for (Map.Entry 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 {