ystx | dfd42b3 | 2025-06-07 13:26:52 +0800 | [diff] [blame^] | 1 | package com.pt.service; |
| 2 | |
| 3 | import com.pt.entity.PeerInfoEntity; |
| 4 | import com.pt.entity.TorrentStats; |
| 5 | import com.pt.exception.ResourceNotFoundException; |
| 6 | import com.pt.repository.PeerInfoRepository; |
| 7 | import com.pt.repository.TorrentMetaRepository; |
| 8 | import com.pt.repository.TorrentStatsRepository; |
| 9 | import org.springframework.beans.factory.annotation.Autowired; |
| 10 | import org.springframework.stereotype.Service; |
| 11 | import org.springframework.stereotype.Repository; |
| 12 | import org.springframework.transaction.annotation.Transactional; |
| 13 | |
| 14 | import java.time.LocalDateTime; |
| 15 | import java.util.List; |
| 16 | |
| 17 | @Service |
| 18 | public class TorrentStatsService { |
| 19 | |
| 20 | @Autowired |
| 21 | private PeerInfoRepository peerInfoRepository; |
| 22 | |
| 23 | @Autowired |
| 24 | private TorrentStatsRepository statsRepository; |
| 25 | |
| 26 | @Autowired |
| 27 | private TorrentMetaRepository torrentMetaRepository; |
| 28 | |
| 29 | @Autowired |
| 30 | public TorrentStatsService(TorrentStatsRepository statsRepository) { |
| 31 | this.statsRepository = statsRepository; |
| 32 | } |
| 33 | |
| 34 | /** |
| 35 | * 增加种子完成次数 |
| 36 | * |
| 37 | * @param torrentId 种子ID |
| 38 | */ |
| 39 | @Transactional |
| 40 | public void incrementCompletedCount(Long torrentId) { |
| 41 | // 1. 检查统计记录是否存在 |
| 42 | if (!statsRepository.findByTorrentId(torrentId).isPresent()) { |
| 43 | // 创建新的统计记录 |
| 44 | TorrentStats newStats = new TorrentStats(); |
| 45 | newStats.setTorrentId(torrentId); |
| 46 | newStats.setCompletedCount(1); |
| 47 | newStats.setLastUpdated(LocalDateTime.now()); |
| 48 | statsRepository.save(newStats); |
| 49 | return; |
| 50 | } |
| 51 | |
| 52 | // 2. 原子操作增加完成次数 |
| 53 | statsRepository.incrementCompletedCount(torrentId); |
| 54 | |
| 55 | // 3. 更新最后更新时间 |
| 56 | statsRepository.updateLastUpdatedToNow(torrentId); |
| 57 | } |
| 58 | /** |
| 59 | * 创建新的统计记录 |
| 60 | */ |
| 61 | private TorrentStats createNewStats(Long torrentId) { |
| 62 | TorrentStats stats = new TorrentStats(); |
| 63 | stats.setTorrentId(torrentId); |
| 64 | stats.setSeederCount(0); |
| 65 | stats.setLeecherCount(0); |
| 66 | stats.setCompletedCount(0); |
| 67 | return statsRepository.save(stats); |
| 68 | } |
| 69 | |
| 70 | // 每次客户端上报状态时调用 |
| 71 | @Transactional |
| 72 | public void updateTorrentStats(String infoHash) { |
| 73 | // 1. 获取当前种子的peer信息 |
| 74 | List<PeerInfoEntity> peers = peerInfoRepository.findByInfoHash(infoHash); |
| 75 | |
| 76 | // 2. 统计各类人数 |
| 77 | int seeders = 0; |
| 78 | int leechers = 0; |
| 79 | int completed = 0; |
| 80 | |
| 81 | for (PeerInfoEntity peer : peers) { |
| 82 | if ("seeding".equals(peer.getStatus()) && peer.isActive()) { |
| 83 | seeders++; |
| 84 | } else if ("downloading".equals(peer.getStatus()) && peer.isActive()) { |
| 85 | leechers++; |
| 86 | } |
| 87 | |
| 88 | if ("completed".equals(peer.getStatus())) { |
| 89 | completed++; |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | // 3. 更新统计记录 |
| 94 | TorrentStats stats = statsRepository.findByTorrentId( |
| 95 | torrentMetaRepository.findByInfoHash(infoHash).getId() |
| 96 | ).orElse(new TorrentStats()); |
| 97 | |
| 98 | stats.setTorrentId(torrentMetaRepository.findByInfoHash(infoHash).getId()); |
| 99 | stats.setSeederCount(seeders); |
| 100 | stats.setLeecherCount(leechers); |
| 101 | stats.setCompletedCount(completed); |
| 102 | stats.setLastUpdated(LocalDateTime.now()); |
| 103 | |
| 104 | statsRepository.save(stats); |
| 105 | } |
| 106 | |
| 107 | // 获取种子统计信息 |
| 108 | public TorrentStats getTorrentStats(Long torrentId) { |
| 109 | return statsRepository.findByTorrentId(torrentId) |
| 110 | .orElseThrow(() -> new ResourceNotFoundException("Stats not found")); |
| 111 | } |
| 112 | } |