This commit is contained in:
@@ -3,15 +3,22 @@ package ru.soune.nocopy.handler;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.soune.nocopy.dto.*;
|
||||
import ru.soune.nocopy.dto.file.*;
|
||||
import ru.soune.nocopy.entity.file.FileAppeal;
|
||||
import ru.soune.nocopy.entity.file.FileEntity;
|
||||
import ru.soune.nocopy.entity.file.FileStatus;
|
||||
import ru.soune.nocopy.entity.file.ProtectionStatus;
|
||||
import ru.soune.nocopy.entity.file.moderation.ModerationLog;
|
||||
import ru.soune.nocopy.exception.FileEntityNotFoundException;
|
||||
import ru.soune.nocopy.exception.InvalidAppealException;
|
||||
import ru.soune.nocopy.exception.NotFoundAuthToken;
|
||||
import ru.soune.nocopy.repository.FileAppealRepository;
|
||||
import ru.soune.nocopy.repository.FileEntityRepository;
|
||||
import ru.soune.nocopy.repository.ModerationLogRepository;
|
||||
import ru.soune.nocopy.service.file.moderation.ModerationService;
|
||||
import ru.soune.nocopy.service.register.AuthService;
|
||||
import ru.soune.nocopy.service.file.FileEntityService;
|
||||
import ru.soune.nocopy.service.file.FileStatsService;
|
||||
@@ -35,6 +42,12 @@ public class FileEntityHandler implements RequestHandler {
|
||||
|
||||
private final FileEntityRepository fileEntityRepository;
|
||||
|
||||
private final ModerationService moderationService;
|
||||
|
||||
private final FileAppealRepository fileAppealRepository;
|
||||
|
||||
private final ModerationLogRepository moderationLogRepository;
|
||||
|
||||
@Override
|
||||
public BaseResponse handle(BaseRequest request) {
|
||||
try {
|
||||
@@ -60,6 +73,18 @@ public class FileEntityHandler implements RequestHandler {
|
||||
return handleProtectFile(request, fileRequest);
|
||||
case "delete_file":
|
||||
return handleDeleteFile(request, fileRequest);
|
||||
case "change_file_status":
|
||||
return handleChangeStatus(request, fileRequest);
|
||||
case "moderate_file":
|
||||
return handleModerateFile(request, fileRequest);
|
||||
case "submit_appeal":
|
||||
return handleSubmitAppeal(request, fileRequest);
|
||||
case "review_appeal":
|
||||
return handleReviewAppeal(request, fileRequest);
|
||||
case "user_appeals":
|
||||
return handleGetUserAppeals(request, fileRequest);
|
||||
case "files_for_moderation":
|
||||
return handleGetFilesForModeration(request, fileRequest);
|
||||
default:
|
||||
ActionResponse response = ActionResponse.builder()
|
||||
.action(action)
|
||||
@@ -183,6 +208,23 @@ public class FileEntityHandler implements RequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private BaseResponse handleChangeStatus(BaseRequest request, FileEntityRequest fileRequest) {
|
||||
FileStatus newStatus = fileRequest.getFileStatus();
|
||||
try {
|
||||
fileEntityService.changeFileStatus(newStatus ,fileRequest.getFileId());
|
||||
} catch (FileEntityNotFoundException e) {
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.FILE_NOT_FOUND.getCode(),
|
||||
MessageCode.FILE_NOT_FOUND.getDescription(),
|
||||
null);
|
||||
}
|
||||
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.SUCCESS.getCode(),
|
||||
MessageCode.SUCCESS.getDescription(),
|
||||
Map.of("new_status", newStatus));
|
||||
}
|
||||
|
||||
private BaseResponse handleSearchFiles(BaseRequest request, FileEntityRequest fileRequest) {
|
||||
try {
|
||||
Long userId = authService.useUserAuthToken(fileRequest.getToken());
|
||||
@@ -568,6 +610,333 @@ public class FileEntityHandler implements RequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private BaseResponse handleModerateFile(BaseRequest request, FileEntityRequest fileRequest) {
|
||||
try {
|
||||
//TODO добавить проверку на админа
|
||||
// Long moderatorId = authService.useAdminAuthToken(fileRequest.getToken());
|
||||
|
||||
ModerationActionRequest moderationRequest = ModerationActionRequest.builder()
|
||||
.fileId(fileRequest.getFileId())
|
||||
.newStatus(fileRequest.getFileStatus())
|
||||
.moderationReasonId(fileRequest.getModerationReasonId())
|
||||
.comment(fileRequest.getComment())
|
||||
.build();
|
||||
|
||||
//TODO set moderator ID
|
||||
moderationService.moderateFile(moderationRequest, 0L);
|
||||
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.SUCCESS.getCode(),
|
||||
"File moderated successfully",
|
||||
null);
|
||||
|
||||
} catch (SecurityException e) {
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.ACCESS_DENIED.getCode(),
|
||||
e.getMessage(),
|
||||
null);
|
||||
} catch (Exception e) {
|
||||
log.error("Error moderating file", e);
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.INVALID_FIELD.getCode(),
|
||||
"Failed to moderate file: " + e.getMessage(),
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
private BaseResponse handleSubmitAppeal(BaseRequest request, FileEntityRequest fileRequest) {
|
||||
try {
|
||||
Long userId = authService.useUserAuthToken(fileRequest.getToken());
|
||||
|
||||
AppealRequest appealRequest = AppealRequest.builder()
|
||||
.fileId(fileRequest.getFileId())
|
||||
.appealReason(fileRequest.getAppealReason())
|
||||
.additionalInfo(fileRequest.getAdditionalInfo())
|
||||
.build();
|
||||
|
||||
AppealResponse response = moderationService.submitAppeal(appealRequest, userId);
|
||||
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.SUCCESS.getCode(),
|
||||
"Appeal submitted successfully",
|
||||
response);
|
||||
|
||||
} catch (InvalidAppealException e) {
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.INVALID_FIELD.getCode(),
|
||||
e.getMessage(),
|
||||
null);
|
||||
} catch (Exception e) {
|
||||
log.error("Error submitting appeal", e);
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.INVALID_FIELD.getCode(),
|
||||
"Failed to submit appeal: " + e.getMessage(),
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
private BaseResponse handleReviewAppeal(BaseRequest request, FileEntityRequest fileRequest) {
|
||||
try {
|
||||
// TODO
|
||||
// Long moderatorId = authService.useAdminAuthToken(fileRequest.getToken());
|
||||
|
||||
String appealId = fileRequest.getAppealId();
|
||||
Boolean approve = fileRequest.getApprove();
|
||||
String comment = fileRequest.getComment();
|
||||
|
||||
if (appealId == null || approve == null) {
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.INVALID_FIELD.getCode(),
|
||||
"appealId and approve are required",
|
||||
null);
|
||||
}
|
||||
//TODO
|
||||
moderationService.reviewAppeal(appealId, approve, comment, 0L);
|
||||
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.SUCCESS.getCode(),
|
||||
"Appeal reviewed successfully",
|
||||
Map.of(
|
||||
"appealId", appealId,
|
||||
"approved", approve,
|
||||
"comment", comment
|
||||
));
|
||||
|
||||
} catch (SecurityException e) {
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.ACCESS_DENIED.getCode(),
|
||||
"Admin access required",
|
||||
null);
|
||||
} catch (IllegalStateException e) {
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.INVALID_FIELD.getCode(),
|
||||
e.getMessage(),
|
||||
null);
|
||||
} catch (Exception e) {
|
||||
log.error("Error reviewing appeal", e);
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.INVALID_FIELD.getCode(),
|
||||
"Failed to review appeal: " + e.getMessage(),
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение списка апелляций пользователя
|
||||
*/
|
||||
private BaseResponse handleGetUserAppeals(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;
|
||||
|
||||
Page<AppealResponse> appeals = moderationService.getUserAppeals(userId, page - 1, pageSize);
|
||||
|
||||
Map<String, Object> response = Map.of(
|
||||
"appeals", appeals.getContent(),
|
||||
"totalCount", appeals.getTotalElements(),
|
||||
"totalPages", appeals.getTotalPages(),
|
||||
"currentPage", page,
|
||||
"pageSize", pageSize);
|
||||
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.SUCCESS.getCode(),
|
||||
MessageCode.SUCCESS.getDescription(),
|
||||
response);
|
||||
|
||||
} catch (SecurityException e) {
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.INVALID_TOKEN.getCode(),
|
||||
"Authentication required",
|
||||
null);
|
||||
} catch (Exception e) {
|
||||
log.error("Error getting user appeals", e);
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.INVALID_FIELD.getCode(),
|
||||
"Failed to get appeals: " + e.getMessage(),
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение списка файлов на модерации
|
||||
*/
|
||||
private BaseResponse handleGetFilesForModeration(BaseRequest request, FileEntityRequest fileRequest) {
|
||||
try {
|
||||
//TODO
|
||||
// authService.useAdminAuthToken(fileRequest.getToken());
|
||||
|
||||
int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1;
|
||||
int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
|
||||
|
||||
Page<FileEntity> files = moderationService.getFilesForModeration(page - 1, pageSize);
|
||||
|
||||
List<Map<String, Object>> filesWithInfo = files.getContent().stream()
|
||||
.map(file -> {
|
||||
FileModerationInfo info = moderationService.getFileModerationInfo(file.getId());
|
||||
return Map.of(
|
||||
"fileId", file.getId(),
|
||||
"fileName", file.getOriginalFileName(),
|
||||
"userId", file.getUserId(),
|
||||
"status", file.getStatus().name(),
|
||||
"createdAt", file.getCreatedAt(),
|
||||
"fileSize", file.getFileSize(),
|
||||
"formattedSize", fileEntityService.formatFileSize(file.getFileSize()),
|
||||
"moderationInfo", Map.of(
|
||||
"hasActiveAppeal", info.getHasActiveAppeal(),
|
||||
"appealInfo", info.getActiveAppeal() != null ?
|
||||
Map.of(
|
||||
"appealId", info.getActiveAppeal().getAppealId(),
|
||||
"status", info.getActiveAppeal().getStatus(),
|
||||
"createdAt", info.getActiveAppeal().getCreatedAt()
|
||||
) : null
|
||||
)
|
||||
);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<String, Object> response = Map.of(
|
||||
"files", filesWithInfo,
|
||||
"totalCount", files.getTotalElements(),
|
||||
"totalPages", files.getTotalPages(),
|
||||
"currentPage", page,
|
||||
"pageSize", pageSize
|
||||
);
|
||||
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.SUCCESS.getCode(),
|
||||
MessageCode.SUCCESS.getDescription(),
|
||||
response);
|
||||
|
||||
} catch (SecurityException e) {
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.ACCESS_DENIED.getCode(),
|
||||
"Admin access required",
|
||||
null);
|
||||
} catch (Exception e) {
|
||||
log.error("Error getting files for moderation", e);
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.INVALID_FIELD.getCode(),
|
||||
"Failed to get files: " + e.getMessage(),
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение детальной информации о файле для модерации
|
||||
*/
|
||||
private BaseResponse handleGetFileModerationInfo(BaseRequest request, FileEntityRequest fileRequest) {
|
||||
try {
|
||||
// TODO
|
||||
// authService.useAdminAuthToken(fileRequest.getToken());
|
||||
|
||||
String fileId = fileRequest.getFileId();
|
||||
if (fileId == null) {
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.INVALID_FIELD.getCode(),
|
||||
"fileId is required",
|
||||
null);
|
||||
}
|
||||
|
||||
FileModerationInfo moderationInfo = moderationService.getFileModerationInfo(fileId);
|
||||
|
||||
FileEntity file = fileEntityRepository.findById(fileId)
|
||||
.orElseThrow(() -> new FileEntityNotFoundException(fileId));
|
||||
|
||||
Map<String, Object> fileInfoMap = new HashMap<>();
|
||||
fileInfoMap.put("id", file.getId());
|
||||
fileInfoMap.put("fileName", file.getOriginalFileName());
|
||||
fileInfoMap.put("storedFileName", file.getStoredFileName());
|
||||
fileInfoMap.put("fileSize", file.getFileSize());
|
||||
fileInfoMap.put("formattedSize", fileEntityService.formatFileSize(file.getFileSize()));
|
||||
fileInfoMap.put("mimeType", file.getMimeType());
|
||||
fileInfoMap.put("fileExtension", file.getFileExtension());
|
||||
fileInfoMap.put("checksum", file.getChecksum());
|
||||
fileInfoMap.put("status", file.getStatus() != null ? file.getStatus().name() : null);
|
||||
fileInfoMap.put("createdAt", file.getCreatedAt());
|
||||
fileInfoMap.put("updatedAt", file.getUpdatedAt());
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("fileInfo", fileInfoMap);
|
||||
response.put("moderationInfo", moderationInfo != null ? moderationInfo : new HashMap<>());
|
||||
response.put("moderationHistory", getModerationHistory(fileId));
|
||||
response.put("appeals", getFileAppeals(fileId));
|
||||
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.SUCCESS.getCode(),
|
||||
MessageCode.SUCCESS.getDescription(),
|
||||
response);
|
||||
|
||||
} catch (SecurityException e) {
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.ACCESS_DENIED.getCode(),
|
||||
"Admin access required",
|
||||
null);
|
||||
} catch (FileEntityNotFoundException e) {
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.FILE_NOT_FOUND.getCode(),
|
||||
e.getMessage(),
|
||||
null);
|
||||
} catch (Exception e) {
|
||||
log.error("Error getting file moderation info", e);
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
MessageCode.INVALID_FIELD.getCode(),
|
||||
"Failed to get file info: " + e.getMessage(),
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение истории модерации файла
|
||||
*/
|
||||
private List<Map<String, Object>> getModerationHistory(String fileId) {
|
||||
List<ModerationLog> logs = moderationLogRepository.findByFileIdOrderByCreatedAtDesc(fileId);
|
||||
if (logs == null || logs.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return logs.stream()
|
||||
.map(log -> {
|
||||
Map<String, Object> logMap = new HashMap<>();
|
||||
logMap.put("id", log.getId());
|
||||
logMap.put("moderatorId", log.getModeratorId());
|
||||
logMap.put("oldStatus", log.getOldStatus() != null ? log.getOldStatus().name() : null);
|
||||
logMap.put("newStatus", log.getNewStatus() != null ? log.getNewStatus().name() : null);
|
||||
logMap.put("reason", log.getReason());
|
||||
logMap.put("comment", log.getComment());
|
||||
logMap.put("createdAt", log.getCreatedAt());
|
||||
return logMap;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение всех апелляций файла
|
||||
*/
|
||||
private List<Map<String, Object>> getFileAppeals(String fileId) {
|
||||
List<FileAppeal> appeals = fileAppealRepository.findByFileId(fileId);
|
||||
if (appeals == null || appeals.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return appeals.stream()
|
||||
.map(appeal -> {
|
||||
Map<String, Object> appealMap = new HashMap<>();
|
||||
appealMap.put("id", appeal.getId());
|
||||
appealMap.put("userId", appeal.getUserId());
|
||||
appealMap.put("appealReason", appeal.getAppealReason());
|
||||
appealMap.put("additionalInfo", appeal.getAdditionalInfo());
|
||||
appealMap.put("status", appeal.getStatus() != null ? appeal.getStatus().name() : null);
|
||||
appealMap.put("adminComment", appeal.getAdminComment());
|
||||
appealMap.put("moderatorId", appeal.getModeratorId());
|
||||
appealMap.put("createdAt", appeal.getCreatedAt());
|
||||
appealMap.put("resolvedAt", appeal.getResolvedAt());
|
||||
return appealMap;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String formatFileSize(long size) {
|
||||
if (size < 1024) return size + " B";
|
||||
int exp = (int) (Math.log(size) / Math.log(1024));
|
||||
|
||||
Reference in New Issue
Block a user