diff --git a/license-service/src/main/java/com/xuqm/license/service/DeviceService.java b/license-service/src/main/java/com/xuqm/license/service/DeviceService.java index 45fec5a..25ca01a 100644 --- a/license-service/src/main/java/com/xuqm/license/service/DeviceService.java +++ b/license-service/src/main/java/com/xuqm/license/service/DeviceService.java @@ -56,6 +56,9 @@ public class DeviceService { // Re-issue token String token = licenseAuthService.generateToken(appKey, deviceId, existing.getId()); String tokenHash = hashToken(token); + if (existing.getAppKey() == null || existing.getAppKey().isBlank()) { + existing.setAppKey(appKey); + } existing.setDeviceName(firstNonBlank(deviceName, existing.getDeviceName())); existing.setDeviceModel(firstNonBlank(deviceModel, existing.getDeviceModel())); existing.setDeviceVendor(firstNonBlank(deviceVendor, existing.getDeviceVendor())); diff --git a/tenant-service/src/main/java/com/xuqm/tenant/service/FeatureServiceManager.java b/tenant-service/src/main/java/com/xuqm/tenant/service/FeatureServiceManager.java index a0759ba..59ea440 100644 --- a/tenant-service/src/main/java/com/xuqm/tenant/service/FeatureServiceManager.java +++ b/tenant-service/src/main/java/com/xuqm/tenant/service/FeatureServiceManager.java @@ -11,8 +11,12 @@ import com.xuqm.tenant.entity.ServiceActivationRequestEntity.Status; import com.xuqm.tenant.repository.AppRepository; import com.xuqm.tenant.repository.FeatureServiceRepository; import com.xuqm.tenant.repository.ServiceActivationRequestRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionSynchronization; +import org.springframework.transaction.support.TransactionSynchronizationManager; import java.time.LocalDateTime; import java.util.ArrayList; @@ -22,22 +26,27 @@ import java.util.UUID; @Service public class FeatureServiceManager { + private static final Logger log = LoggerFactory.getLogger(FeatureServiceManager.class); + private final FeatureServiceRepository repository; private final ServiceActivationRequestRepository requestRepository; private final AppRepository appRepository; private final ObjectMapper objectMapper; private final LicenseServiceClient licenseServiceClient; + private final ImPlatformEventService imPlatformEventService; public FeatureServiceManager(FeatureServiceRepository repository, ServiceActivationRequestRepository requestRepository, AppRepository appRepository, ObjectMapper objectMapper, - LicenseServiceClient licenseServiceClient) { + LicenseServiceClient licenseServiceClient, + ImPlatformEventService imPlatformEventService) { this.repository = repository; this.requestRepository = requestRepository; this.appRepository = appRepository; this.objectMapper = objectMapper; this.licenseServiceClient = licenseServiceClient; + this.imPlatformEventService = imPlatformEventService; } public List listByApp(String appKey) { @@ -173,6 +182,7 @@ public class FeatureServiceManager { appRepository.findByAppKey(normalizedAppId).ifPresent(app -> licenseServiceClient.syncAppLicense(app.getAppKey(), app.getName(), 1, expiresAt)); } + sendActivationImNotification(req.getAppKey(), req.getServiceType().name(), "APPROVED", reviewNote); return req; } @@ -189,6 +199,7 @@ public class FeatureServiceManager { }); entity.setEnabled(true); repository.save(entity); + sendActivationImNotification(req.getAppKey(), req.getServiceType().name(), "APPROVED", reviewNote); return req; } @@ -205,7 +216,9 @@ public class FeatureServiceManager { req.setStatus(Status.REJECTED); req.setReviewNote(reviewNote); req.setReviewedAt(LocalDateTime.now()); - return requestRepository.save(req); + requestRepository.save(req); + sendActivationImNotification(req.getAppKey(), req.getServiceType().name(), "REJECTED", reviewNote); + return req; } public List listRequestsByApp(String appKey) { @@ -619,4 +632,28 @@ public class FeatureServiceManager { node.put(field, value.trim()); } } + + private void sendActivationImNotification(String appKey, String serviceType, String status, String reviewNote) { + // Send after transaction commits so the frontend refresh sees the updated DB state. + if (TransactionSynchronizationManager.isActualTransactionActive()) { + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + @Override + public void afterCommit() { + doSendActivationImNotification(appKey, serviceType, status, reviewNote); + } + }); + } else { + doSendActivationImNotification(appKey, serviceType, status, reviewNote); + } + } + + private void doSendActivationImNotification(String appKey, String serviceType, String status, String reviewNote) { + try { + imPlatformEventService.notifyServiceActivationChange( + new ImPlatformEventService.ServiceActivationEventRequest(appKey, serviceType, status, reviewNote)); + } catch (Exception e) { + log.warn("Failed to send service activation IM notification appKey={} serviceType={} status={}: {}", + appKey, serviceType, status, e.getMessage()); + } + } }