diff --git a/docs/API_ACCESS.md b/docs/API_ACCESS.md index 934a5a6..cd985f4 100644 --- a/docs/API_ACCESS.md +++ b/docs/API_ACCESS.md @@ -26,6 +26,7 @@ - `tenant-platform` 的“服务配置”只认租户 `app.id` - `tenant-platform` 的“IM 管理”必须带 `appKey` +- `tenant-platform` 的“离线推送 / 版本管理”只需要一次开通,平台差异配置在各自的管理页里维护,不再按 Android / iOS / 鸿蒙分别申请开通 - `im-service` 代码里沿用旧参数名 `appId`,但这是历史命名,调用方传的是 `appKey` ## 初始化管理员账号 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 b20037f..1f90d47 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 @@ -39,19 +39,21 @@ public class FeatureServiceManager { } List normalized = new ArrayList<>(); - services.stream() - .filter(service -> service.getServiceType() == FeatureServiceEntity.ServiceType.IM) - .findFirst() - .ifPresent(normalized::add); - services.stream() - .filter(service -> service.getServiceType() != FeatureServiceEntity.ServiceType.IM) - .forEach(normalized::add); + for (FeatureServiceEntity.ServiceType serviceType : List.of( + FeatureServiceEntity.ServiceType.IM, + FeatureServiceEntity.ServiceType.PUSH, + FeatureServiceEntity.ServiceType.UPDATE)) { + services.stream() + .filter(service -> service.getServiceType() == serviceType) + .findFirst() + .ifPresent(normalized::add); + } return normalized.isEmpty() ? services : normalized; } /** * Submit an activation request. Disabling is immediate; enabling requires ops approval. - * IM is app-wide, so duplicate checks ignore platform. + * IM / PUSH / UPDATE are app-wide, so duplicate checks ignore platform. */ @Transactional public ServiceActivationRequestEntity submitActivationRequest( @@ -60,20 +62,13 @@ public class FeatureServiceManager { FeatureServiceEntity.ServiceType serviceType, String applyReason) { - if (serviceType == FeatureServiceEntity.ServiceType.IM) { + if (isAppWideService(serviceType)) { requestRepository.findFirstByAppIdAndServiceTypeOrderByCreatedAtDesc(appId, serviceType) .ifPresent(req -> { if (req.getStatus() == Status.PENDING) { throw new BusinessException(400, "已有待审核的开通申请,请等待运营人员处理"); } }); - } else { - requestRepository.findFirstByAppIdAndPlatformAndServiceTypeOrderByCreatedAtDesc(appId, platform, serviceType) - .ifPresent(req -> { - if (req.getStatus() == Status.PENDING) { - throw new BusinessException(400, "已有待审核的开通申请,请等待运营人员处理"); - } - }); } ServiceActivationRequestEntity req = new ServiceActivationRequestEntity(); @@ -93,7 +88,7 @@ public class FeatureServiceManager { @Transactional public FeatureServiceEntity disable(String appId, FeatureServiceEntity.Platform platform, FeatureServiceEntity.ServiceType serviceType) { - if (serviceType == FeatureServiceEntity.ServiceType.IM) { + if (isAppWideService(serviceType)) { List services = repository.findByAppIdAndServiceType(appId, serviceType); if (services.isEmpty()) { throw new BusinessException(404, "服务未开通"); @@ -125,17 +120,19 @@ public class FeatureServiceManager { req.setReviewedAt(LocalDateTime.now()); requestRepository.save(req); - if (req.getServiceType() == FeatureServiceEntity.ServiceType.IM) { + if (isAppWideService(req.getServiceType())) { List services = repository.findByAppIdAndServiceType(req.getAppId(), req.getServiceType()); if (services.isEmpty()) { - FeatureServiceEntity created = new FeatureServiceEntity(); - created.setId(UUID.randomUUID().toString()); - created.setAppId(req.getAppId()); - created.setPlatform(req.getPlatform()); - created.setServiceType(req.getServiceType()); - created.setEnabled(true); - created.setCreatedAt(LocalDateTime.now()); - repository.save(created); + for (FeatureServiceEntity.Platform platform : FeatureServiceEntity.Platform.values()) { + FeatureServiceEntity created = new FeatureServiceEntity(); + created.setId(UUID.randomUUID().toString()); + created.setAppId(req.getAppId()); + created.setPlatform(platform); + created.setServiceType(req.getServiceType()); + created.setEnabled(true); + created.setCreatedAt(LocalDateTime.now()); + repository.save(created); + } } else { services.forEach(service -> service.setEnabled(true)); repository.saveAll(services); @@ -366,6 +363,12 @@ public class FeatureServiceManager { }; } + private boolean isAppWideService(FeatureServiceEntity.ServiceType serviceType) { + return serviceType == FeatureServiceEntity.ServiceType.IM + || serviceType == FeatureServiceEntity.ServiceType.PUSH + || serviceType == FeatureServiceEntity.ServiceType.UPDATE; + } + private JsonNode readConfigNode(String appId, FeatureServiceEntity.Platform platform, FeatureServiceEntity.ServiceType serviceType) { diff --git a/update-service/src/main/java/com/xuqm/update/config/SecurityConfig.java b/update-service/src/main/java/com/xuqm/update/config/SecurityConfig.java index f30457a..122ee36 100644 --- a/update-service/src/main/java/com/xuqm/update/config/SecurityConfig.java +++ b/update-service/src/main/java/com/xuqm/update/config/SecurityConfig.java @@ -1,5 +1,7 @@ package com.xuqm.update.config; +import com.xuqm.common.security.JwtAuthFilter; +import com.xuqm.common.security.JwtUtil; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; @@ -8,6 +10,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; @@ -18,6 +21,12 @@ import java.util.List; @EnableWebSecurity public class SecurityConfig { + private final JwtUtil jwtUtil; + + public SecurityConfig(JwtUtil jwtUtil) { + this.jwtUtil = jwtUtil; + } + @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http @@ -35,6 +44,7 @@ public class SecurityConfig { ).permitAll() .anyRequest().authenticated() ) + .addFilterBefore(new JwtAuthFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class) .httpBasic(AbstractHttpConfigurer::disable) .formLogin(AbstractHttpConfigurer::disable); return http.build();