diff --git a/src/main/java/ru/soune/nocopy/entity/file/FileEntity.java b/src/main/java/ru/soune/nocopy/entity/file/FileEntity.java index 5872a3a..a21ceb0 100644 --- a/src/main/java/ru/soune/nocopy/entity/file/FileEntity.java +++ b/src/main/java/ru/soune/nocopy/entity/file/FileEntity.java @@ -6,8 +6,10 @@ import lombok.*; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import ru.soune.nocopy.entity.monitoring.FileMonitoringEntity; import java.time.LocalDateTime; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @Data @@ -94,6 +96,10 @@ public class FileEntity { @JsonIgnore private ImageHashEntity imageHash; + @OneToMany(mappedBy = "file", fetch = FetchType.LAZY) + @JsonIgnore + private List monitorings; + @PrePersist public void prePersist() { if (this.supportId == null) { diff --git a/src/main/java/ru/soune/nocopy/handler/FileEntityHandler.java b/src/main/java/ru/soune/nocopy/handler/FileEntityHandler.java index 0a15f1d..423c618 100644 --- a/src/main/java/ru/soune/nocopy/handler/FileEntityHandler.java +++ b/src/main/java/ru/soune/nocopy/handler/FileEntityHandler.java @@ -4,6 +4,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; 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.Component; import ru.soune.nocopy.dto.*; import ru.soune.nocopy.dto.file.*; @@ -230,46 +233,21 @@ public class FileEntityHandler implements RequestHandler { Long userId = authService.useUserAuthToken(fileRequest.getToken()); int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1; int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20; - String sortBy = fileRequest.getSortBy() != null ? fileRequest.getSortBy() : "fileName"; - SortOrder sortOrder = SortOrder.fromString(fileRequest.getSortOrder()); - - FileResponse allFiles = fileEntityService.getUserFiles(userId, 1, 1000, request.getVersion()); - - String searchQuery = fileRequest.getQuery() != null ? fileRequest.getQuery().toLowerCase().trim() : ""; - String[] searchTerms = searchQuery.split("\\s+"); - String filterType = fileRequest.getType(); - String dateFilter = fileRequest.getDateFilter(); - - List filteredFiles = allFiles.getFiles().stream() - .filter(f -> matchesSearch(f, searchTerms, searchQuery, filterType)) - .filter(f -> matchesDateFilter(f, dateFilter)) - .collect(Collectors.toList()); - - Comparator comparator = getComparator(sortBy, sortOrder); - filteredFiles.sort(comparator); - - int start = (page - 1) * pageSize; - int end = Math.min(start + pageSize, filteredFiles.size()); - - if (start >= filteredFiles.size()) { - return createEmptyResponse(request, page, pageSize, sortBy, sortOrder.getValue()); - } - - List paginatedFiles = filteredFiles.subList(start, end); - long totalSize = paginatedFiles.stream() - .mapToLong(FileEntityResponse::getFileSize) - .sum(); + Sort sort = Sort.by(fileRequest.getSortOrder().equalsIgnoreCase("desc") ? Sort.Direction.DESC : + Sort.Direction.ASC, sortBy); + Pageable pageable = PageRequest.of(page, pageSize, sort); + FileResponse userFiles = fileEntityService.getUserFiles(userId, pageable, request.getVersion()); FileListResponse response = FileListResponse.builder() - .files(paginatedFiles) - .totalCount(filteredFiles.size()) - .totalSize(totalSize) - .formattedTotalSize(fileEntityService.formatFileSize(totalSize)) + .files(userFiles.getFiles()) + .totalCount(userFiles.getTotalCount()) + .totalSize(userFiles.getTotalSize()) + .formattedTotalSize(fileEntityService.formatFileSize(userFiles.getTotalSize())) .page(page) .pageSize(pageSize) .sortBy(sortBy) - .sortOrder(sortOrder.getValue()) + .sortOrder(fileRequest.getSortOrder()) .build(); return new BaseResponse(request.getMsgId(), @@ -289,6 +267,73 @@ public class FileEntityHandler implements RequestHandler { } } + /** + * + * private BaseResponse handleSearchFiles(BaseRequest request, FileEntityRequest fileRequest) { + * try { + * Long userId = authService.useUserAuthToken(fileRequest.getToken()); + * int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1; + * int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20; + * + * String sortBy = fileRequest.getSortBy() != null ? fileRequest.getSortBy() : "fileName"; + * SortOrder sortOrder = SortOrder.fromString(fileRequest.getSortOrder()); + * + * FileResponse allFiles = fileEntityService.getUserFiles(userId, 1, 1000, request.getVersion()); + * + * String searchQuery = fileRequest.getQuery() != null ? fileRequest.getQuery().toLowerCase().trim() : ""; + * String[] searchTerms = searchQuery.split("\\s+"); + * String filterType = fileRequest.getType(); + * String dateFilter = fileRequest.getDateFilter(); + * + * List filteredFiles = allFiles.getFiles().stream() + * .filter(f -> matchesSearch(f, searchTerms, searchQuery, filterType)) + * .filter(f -> matchesDateFilter(f, dateFilter)) + * .collect(Collectors.toList()); + * + * Comparator comparator = getComparator(sortBy, sortOrder); + * filteredFiles.sort(comparator); + * + * int start = (page - 1) * pageSize; + * int end = Math.min(start + pageSize, filteredFiles.size()); + * + * if (start >= filteredFiles.size()) { + * return createEmptyResponse(request, page, pageSize, sortBy, sortOrder.getValue()); + * } + * + * List paginatedFiles = filteredFiles.subList(start, end); + * long totalSize = paginatedFiles.stream() + * .mapToLong(FileEntityResponse::getFileSize) + * .sum(); + * + * FileListResponse response = FileListResponse.builder() + * .files(paginatedFiles) + * .totalCount(filteredFiles.size()) + * .totalSize(totalSize) + * .formattedTotalSize(fileEntityService.formatFileSize(totalSize)) + * .page(page) + * .pageSize(pageSize) + * .sortBy(sortBy) + * .sortOrder(sortOrder.getValue()) + * .build(); + * + * return new BaseResponse(request.getMsgId(), + * MessageCode.SUCCESS.getCode(), + * MessageCode.SUCCESS.getDescription(), + * response); + * + * } catch (NotFoundAuthToken e) { + * return new BaseResponse(request.getMsgId(), + * MessageCode.INVALID_TOKEN.getCode(), + * "Authentication required", null); + * } catch (Exception e) { + * log.error("Error searching files", e); + * return new BaseResponse(request.getMsgId(), + * MessageCode.FILE_UPLOAD_ERROR.getCode(), + * "Failed to search files: " + e.getMessage(), null); + * } + * } + */ + private boolean matchesDateFilter(FileEntityResponse file, String dateFilter) { if (dateFilter == null || dateFilter.isEmpty()) { return true; diff --git a/src/main/java/ru/soune/nocopy/repository/FileEntityRepository.java b/src/main/java/ru/soune/nocopy/repository/FileEntityRepository.java index e54e23b..b4efb96 100644 --- a/src/main/java/ru/soune/nocopy/repository/FileEntityRepository.java +++ b/src/main/java/ru/soune/nocopy/repository/FileEntityRepository.java @@ -10,6 +10,7 @@ import ru.soune.nocopy.entity.file.FileEntity; import ru.soune.nocopy.entity.file.FileStatus; import ru.soune.nocopy.entity.file.ProtectionStatus; +import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -78,4 +79,20 @@ public interface FileEntityRepository extends JpaRepository @Query("SELECT f FROM FileEntity f WHERE f.userId = :userId AND f.status IN :statuses") List findByStatuses(Long userId, @Param("statuses") List statuses); + + @Query("SELECT DISTINCT f FROM FileEntity f " + + "LEFT JOIN FileMonitoringEntity m ON f.id = m.file.id " + + "WHERE f.userId IN :userIds " + + "AND f.status IN :statuses") + Page findFiles( + @Param("userIds") List userIds, + @Param("statuses") List statuses, + Pageable pageable); + + @Query("SELECT SUM(f.fileSize) FROM FileEntity f " + + "WHERE f.userId IN :userIds " + + "AND f.status IN :statuses") + Long sumFileSize( + @Param("userIds") List userIds, + @Param("statuses") List statuses); } diff --git a/src/main/java/ru/soune/nocopy/service/file/FileEntityService.java b/src/main/java/ru/soune/nocopy/service/file/FileEntityService.java index 441cf53..bcb8c25 100644 --- a/src/main/java/ru/soune/nocopy/service/file/FileEntityService.java +++ b/src/main/java/ru/soune/nocopy/service/file/FileEntityService.java @@ -3,6 +3,8 @@ package ru.soune.nocopy.service.file; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.soune.nocopy.dto.file.FileEntityResponse; @@ -104,6 +106,34 @@ public class FileEntityService { return allFiles; } + @Transactional(readOnly = true) + public FileResponse getUserFiles(Long userId, Pageable pageable, int version) { + User user = userRepository.findById(userId).orElseThrow(); + List users = user.getCompany() != null ? + userRepository.findByCompanyId(user.getCompany().getId()) : List.of(user); + List statusesForSearch = List.of(FileStatus.ACTIVE, FileStatus.BLOCKED, FileStatus.MODERATION); + + Page files = fileEntityRepository.findFiles(users.stream().map(User::getId).toList(), + statusesForSearch, pageable); + + Long totalSize = fileEntityRepository.sumFileSize( + users.stream().map(User::getId).toList(), + statusesForSearch); + + List filesToResponse = files.stream() + .map(file -> convertToResponse(file, version)) + .toList(); + + return FileResponse.builder() + .files(filesToResponse) + .totalCount((int) files.getTotalElements()) + .totalSize(totalSize != null ? totalSize : 0L) + .formattedTotalSize(formatFileSize(totalSize != null ? totalSize : 0L)) + .page(pageable.getPageNumber() + 1) + .pageSize(pageable.getPageSize()) + .build(); + } + @Transactional(readOnly = true) public FileResponse getUserFiles(Long userId, int page, int pageSize, int version) { User user = userRepository.findById(userId).orElseThrow();