| package com.pt.service; |
| |
| import com.pt.entity.PeerInfoEntity; |
| import com.pt.entity.TorrentMeta; |
| import com.pt.entity.TorrentStats; |
| import com.pt.exception.ResourceNotFoundException; |
| import com.pt.repository.PeerInfoRepository; |
| import com.pt.repository.TorrentMetaRepository; |
| import com.pt.repository.TorrentStatsRepository; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.stereotype.Service; |
| import org.springframework.stereotype.Repository; |
| import org.springframework.transaction.annotation.Transactional; |
| |
| import java.time.LocalDateTime; |
| import java.util.List; |
| import java.util.Optional; |
| |
| @Service |
| public class TorrentStatsService { |
| |
| @Autowired |
| private PeerInfoRepository peerInfoRepository; |
| |
| @Autowired |
| private TorrentStatsRepository statsRepository; |
| |
| @Autowired |
| private TorrentMetaRepository torrentMetaRepository; |
| |
| @Autowired |
| public TorrentStatsService(TorrentStatsRepository statsRepository) { |
| this.statsRepository = statsRepository; |
| } |
| |
| /** |
| * 增加种子完成次数 |
| * |
| * @param torrentId 种子ID |
| */ |
| @Transactional |
| public void incrementCompletedCount(Long torrentId) { |
| // 1. 检查统计记录是否存在 |
| if (!statsRepository.findByTorrentId(torrentId).isPresent()) { |
| // 创建新的统计记录 |
| TorrentStats newStats = new TorrentStats(); |
| newStats.setTorrentId(torrentId); |
| newStats.setCompletedCount(1); |
| newStats.setLastUpdated(LocalDateTime.now()); |
| statsRepository.save(newStats); |
| return; |
| } |
| |
| // 2. 原子操作增加完成次数 |
| statsRepository.incrementCompletedCount(torrentId); |
| |
| // 3. 更新最后更新时间 |
| statsRepository.updateLastUpdatedToNow(torrentId); |
| } |
| /** |
| * 创建新的统计记录 |
| */ |
| private TorrentStats createNewStats(Long torrentId) { |
| TorrentStats stats = new TorrentStats(); |
| stats.setTorrentId(torrentId); |
| stats.setSeederCount(0); |
| stats.setLeecherCount(0); |
| stats.setCompletedCount(0); |
| return statsRepository.save(stats); |
| } |
| |
| // 每次客户端上报状态时调用 |
| @Transactional |
| public void updateTorrentStats(String infoHash) { |
| // 1. 获取当前种子的peer信息 |
| List<PeerInfoEntity> peers = peerInfoRepository.findByInfoHash(infoHash); |
| |
| // 2. 统计各类人数 |
| int seeders = 0; |
| int leechers = 0; |
| int completed = 0; |
| |
| for (PeerInfoEntity peer : peers) { |
| if ("seeding".equals(peer.getStatus()) && peer.isActive() == 1) { |
| seeders++; |
| } else if ("downloading".equals(peer.getStatus()) && peer.isActive() == 1) { |
| leechers++; |
| } |
| |
| if ("completed".equals(peer.getStatus())) { |
| completed++; |
| } |
| } |
| |
| // 3. 更新统计记录 |
| Optional<TorrentMeta> optionalMeta = torrentMetaRepository.findByInfoHash(infoHash); |
| if (optionalMeta.isEmpty()) { |
| // 处理找不到 info_hash 的情况 |
| throw new IllegalArgumentException("Invalid info_hash: not found in database"); |
| } |
| |
| TorrentMeta meta = optionalMeta.get(); |
| |
| TorrentStats stats = statsRepository.findByTorrentId(meta.getId()) |
| .orElse(new TorrentStats()); |
| |
| stats.setTorrentId(meta.getId()); |
| stats.setSeederCount(seeders); |
| stats.setLeecherCount(leechers); |
| stats.setCompletedCount(completed); |
| stats.setLastUpdated(LocalDateTime.now()); |
| |
| statsRepository.save(stats); |
| } |
| |
| // 获取种子统计信息 |
| public TorrentStats getTorrentStats(Long torrentId) { |
| return statsRepository.findByTorrentId(torrentId) |
| .orElseThrow(() -> new ResourceNotFoundException("Stats not found")); |
| } |
| |
| // 新增方法 |
| public List<TorrentStats> getTopSeededTorrents(int limit) { |
| return statsRepository.findTopBySeederCount(limit); |
| } |
| |
| public List<TorrentStats> getRecentActiveTorrents(int limit) { |
| return statsRepository.findRecentActiveTorrents(limit); |
| } |
| |
| public List<TorrentStats> getBatchStats(List<Long> torrentIds) { |
| return statsRepository.findByTorrentIds(torrentIds); |
| } |
| } |