diff --git a/tenant-service/src/main/java/com/xuqm/tenant/config/PrivateTenantBootstrapInitializer.java b/tenant-service/src/main/java/com/xuqm/tenant/config/PrivateTenantBootstrapInitializer.java index c1b2020..e592aaf 100644 --- a/tenant-service/src/main/java/com/xuqm/tenant/config/PrivateTenantBootstrapInitializer.java +++ b/tenant-service/src/main/java/com/xuqm/tenant/config/PrivateTenantBootstrapInitializer.java @@ -89,6 +89,11 @@ public class PrivateTenantBootstrapInitializer implements ApplicationRunner { if (app == null) { provisioningService.ensureApp(bootstrapAppKey, true); log.info("[PRIVATE] Bootstrap app created: {}", bootstrapAppKey); + } else if (!app.isDefault() || app.isDeletable()) { + app.setDefault(true); + app.setDeletable(false); + appRepository.save(app); + log.info("[PRIVATE] Bootstrap app marked as system app: {}", bootstrapAppKey); } } } diff --git a/tenant-service/src/main/java/com/xuqm/tenant/config/SdkAppInitializer.java b/tenant-service/src/main/java/com/xuqm/tenant/config/SdkAppInitializer.java index bbd5030..649d7eb 100644 --- a/tenant-service/src/main/java/com/xuqm/tenant/config/SdkAppInitializer.java +++ b/tenant-service/src/main/java/com/xuqm/tenant/config/SdkAppInitializer.java @@ -1,6 +1,9 @@ package com.xuqm.tenant.config; +import com.xuqm.tenant.entity.AppEntity; +import com.xuqm.tenant.repository.AppRepository; import com.xuqm.tenant.service.SdkAppProvisioningService; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; @@ -9,13 +12,42 @@ import org.springframework.stereotype.Component; public class SdkAppInitializer implements ApplicationRunner { private final SdkAppProvisioningService provisioningService; + private final PrivateDeploymentProperties deployProps; + private final AppRepository appRepository; - public SdkAppInitializer(SdkAppProvisioningService provisioningService) { + @Value("${sdk.bootstrap-app-key:ak_demo_chat}") + private String bootstrapAppKey; + + @Value("${sdk.im-platform-app-key:ak_409e217e4aa14254ad73ad3c}") + private String imPlatformAppKey; + + public SdkAppInitializer(SdkAppProvisioningService provisioningService, + PrivateDeploymentProperties deployProps, + AppRepository appRepository) { this.provisioningService = provisioningService; + this.deployProps = deployProps; + this.appRepository = appRepository; } @Override public void run(ApplicationArguments args) { - provisioningService.ensureBootstrapApp(); + migrateExistingSystemApps(); + if (!deployProps.isPrivate()) { + provisioningService.ensureBootstrapApp(); + } + } + + private void migrateExistingSystemApps() { + markSystemApp(bootstrapAppKey); + markSystemApp(imPlatformAppKey); + } + + private void markSystemApp(String appKey) { + AppEntity app = appRepository.findByAppKey(appKey).orElse(null); + if (app != null && (!app.isDefault() || app.isDeletable())) { + app.setDefault(true); + app.setDeletable(false); + appRepository.save(app); + } } } diff --git a/tenant-service/src/main/java/com/xuqm/tenant/service/AppService.java b/tenant-service/src/main/java/com/xuqm/tenant/service/AppService.java index ccab18b..3d61943 100644 --- a/tenant-service/src/main/java/com/xuqm/tenant/service/AppService.java +++ b/tenant-service/src/main/java/com/xuqm/tenant/service/AppService.java @@ -33,7 +33,9 @@ public class AppService { } public List listByTenant(String tenantId) { - return appRepository.findByTenantId(tenantId); + return appRepository.findByTenantId(tenantId).stream() + .filter(app -> !app.isDefault()) + .toList(); } public AppEntity getByAppKey(String appKey, String tenantId) { diff --git a/tenant-service/src/main/java/com/xuqm/tenant/service/SdkAppProvisioningService.java b/tenant-service/src/main/java/com/xuqm/tenant/service/SdkAppProvisioningService.java index 6caf44f..f6870e0 100644 --- a/tenant-service/src/main/java/com/xuqm/tenant/service/SdkAppProvisioningService.java +++ b/tenant-service/src/main/java/com/xuqm/tenant/service/SdkAppProvisioningService.java @@ -88,6 +88,8 @@ public class SdkAppProvisioningService { app.setAppKey(appKey); app.setAppSecret(generateSecret()); app.setCreatedAt(LocalDateTime.now()); + app.setDefault(true); + app.setDeletable(false); app = appRepository.save(app); if (bootstrapDefaults) { diff --git a/update-service/src/main/java/com/xuqm/update/controller/GlobalExceptionHandler.java b/update-service/src/main/java/com/xuqm/update/controller/GlobalExceptionHandler.java index 6eccf7a..6238145 100644 --- a/update-service/src/main/java/com/xuqm/update/controller/GlobalExceptionHandler.java +++ b/update-service/src/main/java/com/xuqm/update/controller/GlobalExceptionHandler.java @@ -46,13 +46,8 @@ public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity> handle(Exception ex) { log.error("Unhandled exception", ex); - String detail = ex.getClass().getSimpleName() + ": " + ex.getMessage(); - Throwable cause = ex.getCause(); - if (cause != null) { - detail += " | caused by: " + cause.getClass().getSimpleName() + ": " + cause.getMessage(); - } return ResponseEntity.internalServerError() - .body(ApiResponse.error(500, detail)); + .body(ApiResponse.error(500, "服务器内部错误")); } private HttpStatus resolveStatus(int code) { diff --git a/update-service/src/main/java/com/xuqm/update/repository/AppPublishConfigRepository.java b/update-service/src/main/java/com/xuqm/update/repository/AppPublishConfigRepository.java index 9544176..ef3464b 100644 --- a/update-service/src/main/java/com/xuqm/update/repository/AppPublishConfigRepository.java +++ b/update-service/src/main/java/com/xuqm/update/repository/AppPublishConfigRepository.java @@ -6,5 +6,5 @@ import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; public interface AppPublishConfigRepository extends JpaRepository { - Optional findByAppKey(String appKey); + Optional findTopByAppKeyOrderByUpdatedAtDesc(String appKey); } diff --git a/update-service/src/main/java/com/xuqm/update/repository/AppStoreConfigRepository.java b/update-service/src/main/java/com/xuqm/update/repository/AppStoreConfigRepository.java index 1fb0e0c..0e7a43e 100644 --- a/update-service/src/main/java/com/xuqm/update/repository/AppStoreConfigRepository.java +++ b/update-service/src/main/java/com/xuqm/update/repository/AppStoreConfigRepository.java @@ -12,5 +12,5 @@ public interface AppStoreConfigRepository extends JpaRepository findByAppKeyAndEnabled(String appKey, boolean enabled); - Optional findByAppKeyAndStoreType(String appKey, AppStoreConfigEntity.StoreType storeType); + Optional findTopByAppKeyAndStoreTypeOrderByUpdatedAtDesc(String appKey, AppStoreConfigEntity.StoreType storeType); } diff --git a/update-service/src/main/java/com/xuqm/update/service/AppStoreService.java b/update-service/src/main/java/com/xuqm/update/service/AppStoreService.java index d4a331d..16c9eb3 100644 --- a/update-service/src/main/java/com/xuqm/update/service/AppStoreService.java +++ b/update-service/src/main/java/com/xuqm/update/service/AppStoreService.java @@ -69,7 +69,7 @@ public class AppStoreService { AppStoreConfigEntity.StoreType storeType, String configJson, boolean enabled) { - boolean isCreate = configRepo.findByAppKeyAndStoreType(appKey, storeType).isEmpty(); + boolean isCreate = configRepo.findTopByAppKeyAndStoreTypeOrderByUpdatedAtDesc(appKey, storeType).isEmpty(); AppStoreConfigEntity entity = configRepo .findByAppKeyAndStoreType(appKey, storeType) .orElseGet(AppStoreConfigEntity::new); @@ -97,7 +97,7 @@ public class AppStoreService { } public void deleteConfig(String appKey, AppStoreConfigEntity.StoreType storeType) { - configRepo.findByAppKeyAndStoreType(appKey, storeType).ifPresent(cfg -> { + configRepo.findTopByAppKeyAndStoreTypeOrderByUpdatedAtDesc(appKey, storeType).ifPresent(cfg -> { configRepo.delete(cfg); operationLogService.record( appKey, @@ -245,7 +245,7 @@ public class AppStoreService { } public Map getReviewWebhookConfig(String appKey) throws Exception { - AppStoreConfigEntity cfg = configRepo.findByAppKeyAndStoreType( + AppStoreConfigEntity cfg = configRepo.findTopByAppKeyAndStoreTypeOrderByUpdatedAtDesc( appKey, AppStoreConfigEntity.StoreType.REVIEW_WEBHOOK).orElse(null); if (cfg == null || !cfg.isEnabled() || cfg.getConfigJson() == null || cfg.getConfigJson().isBlank()) { return Map.of(); @@ -257,7 +257,7 @@ public class AppStoreService { if (storeType == null || storeType == AppStoreConfigEntity.StoreType.REVIEW_WEBHOOK) { return ""; } - return configRepo.findByAppKeyAndStoreType(appKey, storeType) + return configRepo.findTopByAppKeyAndStoreTypeOrderByUpdatedAtDesc(appKey, storeType) .filter(AppStoreConfigEntity::isEnabled) .map(AppStoreConfigEntity::getConfigJson) .map(this::extractJumpUrl) diff --git a/update-service/src/main/java/com/xuqm/update/service/PublishConfigService.java b/update-service/src/main/java/com/xuqm/update/service/PublishConfigService.java index e9429d0..dff0b12 100644 --- a/update-service/src/main/java/com/xuqm/update/service/PublishConfigService.java +++ b/update-service/src/main/java/com/xuqm/update/service/PublishConfigService.java @@ -45,7 +45,7 @@ public class PublishConfigService { } public AppPublishConfigEntity getConfig(String appKey) { - return configRepository.findByAppKey(appKey).orElseGet(() -> { + return configRepository.findTopByAppKeyOrderByUpdatedAtDesc(appKey).orElseGet(() -> { AppPublishConfigEntity entity = new AppPublishConfigEntity(); entity.setId(UUID.randomUUID().toString()); entity.setAppKey(appKey); @@ -56,7 +56,7 @@ public class PublishConfigService { } public AppPublishConfigEntity saveConfig(String appKey, Map body) { - AppPublishConfigEntity entity = configRepository.findByAppKey(appKey).orElseGet(AppPublishConfigEntity::new); + AppPublishConfigEntity entity = configRepository.findTopByAppKeyOrderByUpdatedAtDesc(appKey).orElseGet(AppPublishConfigEntity::new); if (entity.getId() == null) { entity.setId(UUID.randomUUID().toString()); entity.setAppKey(appKey); @@ -71,7 +71,7 @@ public class PublishConfigService { } public JsonNode getConfigNode(String appKey) { - AppPublishConfigEntity entity = configRepository.findByAppKey(appKey).orElse(null); + AppPublishConfigEntity entity = configRepository.findTopByAppKeyOrderByUpdatedAtDesc(appKey).orElse(null); if (entity == null || entity.getConfigJson() == null || entity.getConfigJson().isBlank()) { try { return objectMapper.readTree(defaultConfigJson()); 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 3eacc15..907520f 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 @@ -398,7 +398,7 @@ public class StoreSubmissionService { for (String storeType : targets) { AppStoreConfigEntity cfg; try { - cfg = configRepo.findByAppKeyAndStoreType(v.getAppKey(), + cfg = configRepo.findTopByAppKeyAndStoreTypeOrderByUpdatedAtDesc(v.getAppKey(), AppStoreConfigEntity.StoreType.valueOf(storeType)).orElse(null); } catch (Exception e) { results.add(StoreRemoteState.failed( @@ -694,7 +694,7 @@ public class StoreSubmissionService { if (!isUnderReview && !isRejected) continue; AppStoreConfigEntity cfg; try { - cfg = configRepo.findByAppKeyAndStoreType(v.getAppKey(), + cfg = configRepo.findTopByAppKeyAndStoreTypeOrderByUpdatedAtDesc(v.getAppKey(), AppStoreConfigEntity.StoreType.valueOf(storeType)).orElse(null); } catch (Exception e) { continue; @@ -779,7 +779,7 @@ public class StoreSubmissionService { for (String storeType : targets) { AppStoreConfigEntity cfg; try { - cfg = configRepo.findByAppKeyAndStoreType(v.getAppKey(), + cfg = configRepo.findTopByAppKeyAndStoreTypeOrderByUpdatedAtDesc(v.getAppKey(), AppStoreConfigEntity.StoreType.valueOf(storeType)).orElse(null); } catch (Exception e) { results.add(StoreRemoteState.failed(