fix: isolate private deployment databases and fix store review refresh bugs

application.yml — all services:
- Replace hardcoded jdbc:mysql://39.107.53.187 with ${SPRING_DATASOURCE_URL:fallback}
- Same for SPRING_DATASOURCE_USERNAME/PASSWORD
- im-service: replace hardcoded redisdev.xuqinmin.com with ${SPRING_DATA_REDIS_*}
  This ensures docker-compose environment overrides take effect; without these
  placeholders, Spring Boot's relaxed binding couldn't override the YAML values
  and the private deployment connected to production databases.

StoreSubmissionService.refreshStoreReviewStatus — two bugs fixed:
1. MI/UNDER_REVIEW_XIAOMI branch now guards against downgrading APPROVED state.
   Xiaomi's poll API returns UNDER_REVIEW_XIAOMI when the submitted version is
   not yet the live version, even after the store approves it. Previously this
   caused the manual refresh to overwrite a webhook-confirmed APPROVED with
   UNDER_REVIEW on every click.
2. When the poll returns APPROVED but currentSubmissionLive=false (another version
   is live on the store), no longer overwrite an existing APPROVED (from webhook)
   with nonCurrentRelease=true. The webhook is authoritative; the live version
   difference just means distribution is pending, not that this is a non-current
   release. Only adds nonCurrentRelease when transitioning FROM a non-APPROVED
   state (true pre-existing detection).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
XuqmGroup 2026-05-19 18:25:50 +08:00
父节点 9771663f00
当前提交 450a44de68
共有 6 个文件被更改,包括 52 次插入30 次删除

查看文件

@ -8,9 +8,9 @@ spring:
virtual:
enabled: true
datasource:
url: jdbc:mysql://39.107.53.187:3306/xuqm_file?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
username: xuqm
password: Xuqm@2026
url: ${SPRING_DATASOURCE_URL:jdbc:mysql://39.107.53.187:3306/xuqm_file?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true}
username: ${SPRING_DATASOURCE_USERNAME:xuqm}
password: ${SPRING_DATASOURCE_PASSWORD:Xuqm@2026}
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 2

查看文件

@ -5,9 +5,9 @@ spring:
application:
name: im-service
datasource:
url: jdbc:mysql://39.107.53.187:3306/xuqm_im?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
username: xuqm
password: Xuqm@2026
url: ${SPRING_DATASOURCE_URL:jdbc:mysql://39.107.53.187:3306/xuqm_im?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true}
username: ${SPRING_DATASOURCE_USERNAME:xuqm}
password: ${SPRING_DATASOURCE_PASSWORD:Xuqm@2026}
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5
@ -24,10 +24,10 @@ spring:
dialect: org.hibernate.dialect.MySQLDialect
data:
redis:
host: redisdev.xuqinmin.com
port: 6379
password: xuqinmin1022
database: 2
host: ${SPRING_DATA_REDIS_HOST:redisdev.xuqinmin.com}
port: ${SPRING_DATA_REDIS_PORT:6379}
password: ${SPRING_DATA_REDIS_PASSWORD:xuqinmin1022}
database: ${SPRING_DATA_REDIS_DATABASE:2}
timeout: 10s
lettuce:
pool:

查看文件

@ -5,9 +5,9 @@ spring:
application:
name: license-service
datasource:
url: jdbc:mysql://39.107.53.187:3306/pad_license?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
username: xuqm
password: Xuqm@2026
url: ${SPRING_DATASOURCE_URL:jdbc:mysql://39.107.53.187:3306/pad_license?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true}
username: ${SPRING_DATASOURCE_USERNAME:xuqm}
password: ${SPRING_DATASOURCE_PASSWORD:Xuqm@2026}
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5

查看文件

@ -5,9 +5,9 @@ spring:
application:
name: push-service
datasource:
url: jdbc:mysql://39.107.53.187:3306/xuqm_push?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
username: xuqm
password: Xuqm@2026
url: ${SPRING_DATASOURCE_URL:jdbc:mysql://39.107.53.187:3306/xuqm_push?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true}
username: ${SPRING_DATASOURCE_USERNAME:xuqm}
password: ${SPRING_DATASOURCE_PASSWORD:Xuqm@2026}
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5

查看文件

@ -803,24 +803,46 @@ public class StoreSubmissionService {
}
boolean isUnderReview = "UNDER_REVIEW".equals(existingState);
boolean isRejected = "REJECTED".equals(existingState);
boolean isApproved = "APPROVED".equals(existingState);
AppVersionEntity.StoreReviewState mappedState = mapToStoreReviewState(polled.getReviewState());
if (mappedState == AppVersionEntity.StoreReviewState.APPROVED) {
log.info("Manual refresh: {}/{} writing live state currentSubmissionLive={} nonCurrentRelease={} liveVersionName={} liveVersionCode={}",
v.getId(), storeType, polled.isCurrentSubmissionLive(), polled.isNonCurrentRelease(),
polled.getOnlineVersionName(), polled.getOnlineVersionCode());
storeService.updateStoreReviewLive(v.getId(), storeType, !polled.isCurrentSubmissionLive(),
buildLiveReason(polled), buildExtra(polled));
if (polled.isCurrentSubmissionLive()) {
// Submitted version is now live update with currentSubmissionLive=true
log.info("Manual refresh: {}/{} submitted version now live — updating", v.getId(), storeType);
storeService.updateStoreReviewLive(v.getId(), storeType, false,
buildLiveReason(polled), buildExtra(polled));
} else if (!isApproved) {
// Store has a different live version (preExisting) and we didn't have APPROVED yet.
// Mark as pre-existing live so UI shows which version is actually on the store.
log.info("Manual refresh: {}/{} pre-existing live detected currentSubmissionLive={} liveVersionCode={}",
v.getId(), storeType, false, polled.getOnlineVersionCode());
storeService.updateStoreReviewLive(v.getId(), storeType, true,
buildLiveReason(polled), buildExtra(polled));
} else {
// Already APPROVED (from webhook): version approved but pending distribution.
// Do NOT overwrite with nonCurrentRelease=true that would show a misleading
// "已上线(非本次发布)" label when the version is simply awaiting distribution.
log.debug("Manual refresh: {}/{} already APPROVED (webhook), store live version={} — pending distribution, no change",
v.getId(), storeType, polled.getOnlineVersionCode());
}
} else if ("MI".equals(storeType)
&& polled.getReviewState() == StoreRemoteState.ReviewState.UNDER_REVIEW_XIAOMI) {
if (!"UNDER_REVIEW".equals(existingState)) {
log.info("Manual refresh: {}/{} restoring Xiaomi UNDER_REVIEW from {}", v.getId(), storeType, existingState);
// MI API cannot distinguish "approved, awaiting distribution" from "under review"
// when the submitted version isn't live yet. Never downgrade an APPROVED state.
if (!isApproved && !"WITHDRAWN".equals(existingState)) {
if (!isUnderReview) {
log.info("Manual refresh: {}/{} restoring Xiaomi UNDER_REVIEW from {}", v.getId(), storeType, existingState);
}
storeService.updateStoreReview(v.getId(), storeType,
AppVersionEntity.StoreReviewState.UNDER_REVIEW,
"小米应用商店当前提交版本审核中");
} else {
log.debug("Manual refresh: {}/{} MI UNDER_REVIEW_XIAOMI polled but existing={} — no downgrade",
v.getId(), storeType, existingState);
}
storeService.updateStoreReview(v.getId(), storeType,
AppVersionEntity.StoreReviewState.UNDER_REVIEW,
"小米应用商店当前提交版本审核中");
} else if (isUnderReview || isRejected) {
if (mappedState != AppVersionEntity.StoreReviewState.UNDER_REVIEW
|| !"UNDER_REVIEW".equals(existingState)) {
|| !isUnderReview) {
log.info("Manual refresh: {}/{} writing {} from {}", v.getId(), storeType, mappedState, existingState);
storeService.updateStoreReview(v.getId(), storeType, mappedState, "手动刷新厂商审核状态");
}

查看文件

@ -5,9 +5,9 @@ spring:
application:
name: update-service
datasource:
url: jdbc:mysql://39.107.53.187:3306/xuqm_update?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
username: xuqm
password: Xuqm@2026
url: ${SPRING_DATASOURCE_URL:jdbc:mysql://39.107.53.187:3306/xuqm_update?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true}
username: ${SPRING_DATASOURCE_USERNAME:xuqm}
password: ${SPRING_DATASOURCE_PASSWORD:Xuqm@2026}
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5