dev add method link
Test Workflow / test (push) Has been cancelled

This commit is contained in:
2026-05-05 13:44:49 +07:00
parent 6793bbfc5c
commit bb43b6ef4f
8 changed files with 328 additions and 4 deletions
@@ -3,13 +3,21 @@ package ru.soune.nocopy.service.dockview;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.dto.docviewer.DocViewerRequest;
import ru.soune.nocopy.dto.docviewer.DockViewResponse;
import ru.soune.nocopy.dto.docviewer.DockViewStatsResponse;
import ru.soune.nocopy.entity.docviewer.DockView;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.repository.DockViewRepository;
import ru.soune.nocopy.repository.FileEntityRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.geo.GeoCountryService;
import java.time.LocalDateTime;
import java.util.*;
@@ -22,6 +30,12 @@ public class DockViewService {
private final DockViewRepository dockViewRepository;
private final GeoCountryService geoCountryService;
private final FileEntityRepository fileEntityRepository;
private final UserRepository userRepository;
@Transactional
public DockView createDockView(DocViewerRequest request, Long userId) {
DockView dockView = new DockView();
@@ -65,6 +79,86 @@ public class DockViewService {
.build();
}
public List<DockViewStatsResponse> getStatsByFileIds(List<String> fileIds) {
List<Object[]> statsList = dockViewRepository.findViewsStatsByFileIds(fileIds);
Map<String, Object[]> statsMap = statsList.stream()
.collect(Collectors.toMap(
stats -> (String) stats[0],
stats -> stats
));
return fileIds.stream()
.map(fileId -> {
Object[] stats = statsMap.get(fileId);
if (stats == null) {
return DockViewStatsResponse.builder()
.fileId(fileId)
.totalViews(0L)
.uniqueIps(0L)
.uniqueUsers(0L)
.firstViewDate(null)
.lastViewDate(null)
.build();
}
return DockViewStatsResponse.builder()
.fileId((String) stats[0])
.totalViews((Long) stats[1])
.uniqueIps((Long) stats[2])
.uniqueUsers((Long) stats[3])
.lastViewDate((LocalDateTime) stats[4])
.firstViewDate((LocalDateTime) stats[5])
.build();
})
.collect(Collectors.toList());
}
public DockViewStatsResponse getOpenLastHistory(int page, int size, String sortDirection, String sortBy,
List<String> fileIds) {
Pageable pageable = PageRequest.of(page, size,
Sort.by(Sort.Direction.fromString(sortDirection), sortBy));
Page<DockView> dockViews = dockViewRepository.findAllByFileId(pageable, fileIds);
if (dockViews.isEmpty()) {
return DockViewStatsResponse.builder()
.build();
}
List<DockViewResponse> history = new ArrayList<>();
for (DockView dockView: dockViews) {
String country = geoCountryService.getCountryByIp(dockView.getViewerIp());
String city = geoCountryService.getCityByIp(dockView.getViewerIp());
LocalDateTime createdAt = dockView.getCreatedAt();
String fileId = dockView.getFileId();
FileEntity file = fileEntityRepository.findByFileId(fileId);
Long viewerId = dockView.getViewerId();
User viewer = userRepository.findById(viewerId).orElse(null);
DockViewResponse response = DockViewResponse.builder()
.city(city)
.country(country)
.viewDate(createdAt)
.document(file.getOriginalFileName())
.viewer(viewer == null ? "guest" : viewer.getFullName())
.build();
history.add(response);
}
return DockViewStatsResponse.builder()
.history(history)
.pageNumber(dockViews.getNumber())
.pageSize(dockViews.getSize())
.totalPages(dockViews.getTotalPages())
.totalElements(dockViews.getTotalElements())
.build();
}
public DockViewStatsResponse getBasicStatsByFileId(String fileId) {
long totalViews = dockViewRepository.countByFileId(fileId);
long uniqueIps = dockViewRepository.countUniqueIpsByFileId(fileId);
@@ -2,6 +2,7 @@ package ru.soune.nocopy.service.geo;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.model.CountryResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
@@ -15,11 +16,17 @@ import java.net.InetAddress;
@Slf4j
public class GeoCountryService {
private final DatabaseReader dbReader;
private final DatabaseReader countryDbReader;
private final DatabaseReader cityDbReader;
public GeoCountryService() throws IOException {
Resource resource = new ClassPathResource("geo/GeoLite2-Country.mmdb");
this.dbReader = new DatabaseReader.Builder(resource.getInputStream()).build();
this.countryDbReader = new DatabaseReader.Builder(resource.getInputStream()).build();
Resource cityResource = new ClassPathResource("geo/GeoLite2-City.mmdb");
this.cityDbReader = new DatabaseReader.Builder(cityResource.getInputStream()).build();
}
public String getCountryName(String input) {
@@ -44,12 +51,48 @@ public class GeoCountryService {
}
}
public String getCityByIp(String ip) {
try {
InetAddress ipAddress = InetAddress.getByName(ip);
CityResponse response = cityDbReader.city(ipAddress);
return response.getCity().getName();
} catch (Exception e) {
log.error("Failed to get city for IP: {}", ip, e);
return "UNKNOWN";
}
}
public String getCountryByIp(String ip) {
try {
InetAddress ipAddress = InetAddress.getByName(ip);
CountryResponse response = countryDbReader.country(ipAddress);
return response.getCountry().getName();
} catch (Exception e) {
log.error("Failed to get country for IP: {}", ip, e);
return "UNKNOWN";
}
}
public String getCountryCodeByIp(String ip) {
try {
InetAddress ipAddress = InetAddress.getByName(ip);
CountryResponse response = countryDbReader.country(ipAddress);
return response.getCountry().getIsoCode();
} catch (Exception e) {
log.error("Failed to get country code for IP: {}", ip, e);
return "UNKNOWN";
}
}
private CountryResponse extractCountry(String input) throws IOException, GeoIp2Exception {
String domain = extractDomain(input);
InetAddress ip = InetAddress.getByName(domain);
return dbReader.country(ip);
return countryDbReader.country(ip);
}
private String extractDomain(String input) {