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>
这个提交包含在:
XuqmGroup 2026-07-02 18:56:25 +08:00
父节点 786051510b
当前提交 a6da4f3560
共有 2 个文件被更改,包括 44 次插入1 次删除

查看文件

@ -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 {