package com.xuqm.push.service; import com.xuqm.push.entity.DeviceTokenEntity; import com.xuqm.push.repository.DeviceTokenRepository; import com.xuqm.push.service.provider.PushProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @Service public class PushDispatcher { private static final Logger log = LoggerFactory.getLogger(PushDispatcher.class); private final DeviceTokenRepository tokenRepository; private final Map providers; public PushDispatcher(DeviceTokenRepository tokenRepository, List providerList) { this.tokenRepository = tokenRepository; this.providers = providerList.stream() .collect(Collectors.toMap(PushProvider::vendorName, p -> p)); } @Async public void pushToUser(String appId, String userId, String title, String body, String payload) { List tokens = tokenRepository.findByAppIdAndUserId(appId, userId); for (DeviceTokenEntity t : tokens) { PushProvider provider = providers.get(t.getVendor().name()); if (provider != null) { boolean ok = provider.send(t.getToken(), title, body, payload); log.info("Push to {}@{} via {}: {}", userId, appId, t.getVendor(), ok ? "OK" : "FAIL"); } } } public void registerToken(String appId, String userId, DeviceTokenEntity.Vendor vendor, String token) { Optional existing = tokenRepository.findByAppIdAndUserIdAndVendor(appId, userId, vendor); DeviceTokenEntity entity = existing.orElseGet(() -> { DeviceTokenEntity e = new DeviceTokenEntity(); e.setId(UUID.randomUUID().toString()); e.setAppId(appId); e.setUserId(userId); e.setVendor(vendor); e.setCreatedAt(LocalDateTime.now()); return e; }); entity.setToken(token); entity.setUpdatedAt(LocalDateTime.now()); tokenRepository.save(entity); } }