@@ -290,7 +290,7 @@ server_name dev-admin.not-copy.com;
|
|||||||
ssl_certificate_key /etc/letsencrypt/live/dev-admin.not-copy.com/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/dev-admin.not-copy.com/privkey.pem;
|
||||||
|
|
||||||
location /api/ {
|
location /api/ {
|
||||||
proxy_pass http://localhost:3001;
|
proxy_pass http://localhost:8082;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ public class HandlerConfig {
|
|||||||
UserInfoHandler userInfoHandler,
|
UserInfoHandler userInfoHandler,
|
||||||
NotificationHandler notificationHandler,
|
NotificationHandler notificationHandler,
|
||||||
UserVerificationHandler userVerificationHandler,
|
UserVerificationHandler userVerificationHandler,
|
||||||
LawCaseHandler lawCaseHandler
|
LawCaseHandler lawCaseHandler,
|
||||||
|
TokenOperationHandler tokenOperationHandler
|
||||||
) {
|
) {
|
||||||
Map<Integer, RequestHandler> map = new HashMap<>();
|
Map<Integer, RequestHandler> map = new HashMap<>();
|
||||||
map.put(20001, login);
|
map.put(20001, login);
|
||||||
@@ -66,6 +67,7 @@ public class HandlerConfig {
|
|||||||
map.put(30015, notificationHandler);
|
map.put(30015, notificationHandler);
|
||||||
map.put(30016, userVerificationHandler);
|
map.put(30016, userVerificationHandler);
|
||||||
map.put(30017, lawCaseHandler);
|
map.put(30017, lawCaseHandler);
|
||||||
|
map.put(30018, tokenOperationHandler);
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public class PaymentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
paymentService.changeAutoRenewal(authService.useUserAuthToken(tokenHeader), renewal);
|
paymentService.changeAutoRenewal(authService.useUserAuthToken(tokenHeader), renewal);
|
||||||
return ResponseEntity.ok(Map.of("message", "Auto-renewal disabled"));
|
return ResponseEntity.ok(Map.of("message", "Auto-renewal changed:" + renewal));
|
||||||
} catch (UserNotFoundException e) {
|
} catch (UserNotFoundException e) {
|
||||||
return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||||||
.body(Map.of("error", e.getMessage()));
|
.body(Map.of("error", e.getMessage()));
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public enum MessageCode {
|
|||||||
TARIFF_IS_NOT_FOUND(0, "Tariff is not found"),
|
TARIFF_IS_NOT_FOUND(0, "Tariff is not found"),
|
||||||
VALIDATION_ERROR(2, "Validation error"),
|
VALIDATION_ERROR(2, "Validation error"),
|
||||||
RESOURCE_NOT_FOUND(4, "Resource not found"),
|
RESOURCE_NOT_FOUND(4, "Resource not found"),
|
||||||
|
OPERATION_NOT_FOUND(4, "Operation not found"),
|
||||||
INTERNAL_ERROR(4, "Internal server error"),
|
INTERNAL_ERROR(4, "Internal server error"),
|
||||||
COMPANY_NOT_FOUND(4, "Company not found"),
|
COMPANY_NOT_FOUND(4, "Company not found"),
|
||||||
PAYMENT_NOT_FOUND(4, "Payment not found"),
|
PAYMENT_NOT_FOUND(4, "Payment not found"),
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package ru.soune.nocopy.dto.tokenoperation;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.TokenOperation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class TokenOperationPageDto {
|
||||||
|
|
||||||
|
@JsonProperty("content")
|
||||||
|
private List<TokenOperation> content;
|
||||||
|
|
||||||
|
@JsonProperty("page_number")
|
||||||
|
private int pageNumber;
|
||||||
|
|
||||||
|
@JsonProperty("page_size")
|
||||||
|
private int pageSize;
|
||||||
|
|
||||||
|
@JsonProperty("total_elements")
|
||||||
|
private long totalElements;
|
||||||
|
|
||||||
|
@JsonProperty("total_pages")
|
||||||
|
private int totalPages;
|
||||||
|
|
||||||
|
@JsonProperty("is_last")
|
||||||
|
private boolean last;
|
||||||
|
|
||||||
|
@JsonProperty("is_first")
|
||||||
|
private boolean first;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package ru.soune.nocopy.dto.tokenoperation;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.OperationType;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TokenOperationRequest {
|
||||||
|
|
||||||
|
@JsonProperty("action")
|
||||||
|
private String action;
|
||||||
|
|
||||||
|
@JsonProperty("token")
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
@JsonProperty("operation_id")
|
||||||
|
private Long operationId;
|
||||||
|
|
||||||
|
@JsonProperty("operation_type")
|
||||||
|
private OperationType operationType;
|
||||||
|
|
||||||
|
@JsonProperty("spent")
|
||||||
|
private Long spent;
|
||||||
|
|
||||||
|
@JsonProperty("page")
|
||||||
|
private Integer page = 0;
|
||||||
|
|
||||||
|
@JsonProperty("size")
|
||||||
|
private Integer size = 20;
|
||||||
|
|
||||||
|
@JsonProperty("sort_by")
|
||||||
|
private String sortBy = "createdAt";
|
||||||
|
|
||||||
|
@JsonProperty("sort_direction")
|
||||||
|
private String sortDirection = "desc";
|
||||||
|
|
||||||
|
@JsonProperty("min_spent")
|
||||||
|
private Long minSpent;
|
||||||
|
|
||||||
|
@JsonProperty("max_spent")
|
||||||
|
private Long maxSpent;
|
||||||
|
|
||||||
|
@JsonProperty("updates")
|
||||||
|
private Object updates;
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package ru.soune.nocopy.dto.tokenoperation;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
public class TokenOperationResponse {
|
||||||
|
|
||||||
|
@JsonProperty("success")
|
||||||
|
private Boolean success;
|
||||||
|
|
||||||
|
@JsonProperty("message")
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
@JsonProperty("data")
|
||||||
|
private Object data;
|
||||||
|
|
||||||
|
@JsonProperty("total_elements")
|
||||||
|
private Long totalElements;
|
||||||
|
|
||||||
|
@JsonProperty("total_pages")
|
||||||
|
private Integer totalPages;
|
||||||
|
|
||||||
|
@JsonProperty("current_page")
|
||||||
|
private Integer currentPage;
|
||||||
|
|
||||||
|
@JsonProperty("page_size")
|
||||||
|
private Integer pageSize;
|
||||||
|
|
||||||
|
@JsonProperty("statistics")
|
||||||
|
private Map<String, Object> statistics;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package ru.soune.nocopy.entity.tokenoperation;
|
||||||
|
|
||||||
|
public enum OperationType {
|
||||||
|
SEARCH("search"), MONITORING("monitoring"), CREATE_LEGAL_CASE("legal_case"),
|
||||||
|
FILE_UPLOAD("file_upload"), GLOBAL_SEARCH("global_search");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private OperationType(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package ru.soune.nocopy.entity.tokenoperation;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.*;
|
||||||
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Table(name = "token_operation")
|
||||||
|
@Entity
|
||||||
|
@Setter @Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class TokenOperation {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(name = "operation_type")
|
||||||
|
private OperationType operationType;
|
||||||
|
|
||||||
|
@Column(name = "user_id")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Column(name = "spent")
|
||||||
|
private Long spent;
|
||||||
|
|
||||||
|
@CreationTimestamp
|
||||||
|
@Column(name = "created_at", updatable = false)
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import ru.soune.nocopy.dto.MessageCode;
|
|||||||
import ru.soune.nocopy.dto.file.ImageSearchRequest;
|
import ru.soune.nocopy.dto.file.ImageSearchRequest;
|
||||||
import ru.soune.nocopy.dto.file.YandexSearchResponse;
|
import ru.soune.nocopy.dto.file.YandexSearchResponse;
|
||||||
import ru.soune.nocopy.entity.file.FileEntity;
|
import ru.soune.nocopy.entity.file.FileEntity;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.OperationType;
|
||||||
import ru.soune.nocopy.exception.NotValidFieldException;
|
import ru.soune.nocopy.exception.NotValidFieldException;
|
||||||
import ru.soune.nocopy.repository.FileEntityRepository;
|
import ru.soune.nocopy.repository.FileEntityRepository;
|
||||||
import ru.soune.nocopy.service.file.CheckCounterService;
|
import ru.soune.nocopy.service.file.CheckCounterService;
|
||||||
@@ -117,7 +118,8 @@ public class ImageFoundRequestHandler implements RequestHandler {
|
|||||||
log.info("Results only from Yandex: {} images", allUniqueImages.size());
|
log.info("Results only from Yandex: {} images", allUniqueImages.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
tariffInfoService.writeOffTokens(fileEntity.getUserId(), TariffConstants.TOKEN_VALUE_FOR_SEARCH);
|
tariffInfoService.writeOffTokens(fileEntity.getUserId(), TariffConstants.TOKEN_VALUE_FOR_SEARCH,
|
||||||
|
OperationType.SEARCH);
|
||||||
checkCounterService.incrementCheckCount(fileEntity.getUserId(), fileEntity.getMimeType());
|
checkCounterService.incrementCheckCount(fileEntity.getUserId(), fileEntity.getMimeType());
|
||||||
|
|
||||||
int page = imageSearchRequest.getPage() != null ? imageSearchRequest.getPage() : 1;
|
int page = imageSearchRequest.getPage() != null ? imageSearchRequest.getPage() : 1;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import ru.soune.nocopy.dto.complaint.PaginatedResponse;
|
|||||||
import ru.soune.nocopy.entity.complaint.LawCase;
|
import ru.soune.nocopy.entity.complaint.LawCase;
|
||||||
import ru.soune.nocopy.entity.complaint.LawCasePriority;
|
import ru.soune.nocopy.entity.complaint.LawCasePriority;
|
||||||
import ru.soune.nocopy.entity.complaint.LawCaseType;
|
import ru.soune.nocopy.entity.complaint.LawCaseType;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.OperationType;
|
||||||
import ru.soune.nocopy.entity.user.User;
|
import ru.soune.nocopy.entity.user.User;
|
||||||
import ru.soune.nocopy.exception.NotValidFieldException;
|
import ru.soune.nocopy.exception.NotValidFieldException;
|
||||||
import ru.soune.nocopy.exception.TariffNotFoundException;
|
import ru.soune.nocopy.exception.TariffNotFoundException;
|
||||||
@@ -114,7 +115,7 @@ public class LawCaseHandler implements RequestHandler {
|
|||||||
|
|
||||||
private BaseResponse createLawCase(Long userId, LawCaseRequest lawCaseRequest, BaseRequest request) {
|
private BaseResponse createLawCase(Long userId, LawCaseRequest lawCaseRequest, BaseRequest request) {
|
||||||
try {
|
try {
|
||||||
tariffInfoService.writeOffTokens(userId, TariffConstants.LEGAL_COST);
|
tariffInfoService.writeOffTokens(userId, TariffConstants.LEGAL_COST, OperationType.CREATE_LEGAL_CASE);
|
||||||
} catch (TariffNotFoundException e) {
|
} catch (TariffNotFoundException e) {
|
||||||
return new BaseResponse(request.getMsgId(), MessageCode.USER_NOT_HAVE_TOKEN.getCode(),
|
return new BaseResponse(request.getMsgId(), MessageCode.USER_NOT_HAVE_TOKEN.getCode(),
|
||||||
MessageCode.USER_NOT_HAVE_TOKEN.getDescription(),
|
MessageCode.USER_NOT_HAVE_TOKEN.getDescription(),
|
||||||
|
|||||||
@@ -0,0 +1,472 @@
|
|||||||
|
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.BaseRequest;
|
||||||
|
import ru.soune.nocopy.dto.BaseResponse;
|
||||||
|
import ru.soune.nocopy.dto.MessageCode;
|
||||||
|
import ru.soune.nocopy.dto.tokenoperation.TokenOperationPageDto;
|
||||||
|
import ru.soune.nocopy.dto.tokenoperation.TokenOperationRequest;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.OperationType;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.TokenOperation;
|
||||||
|
import ru.soune.nocopy.service.register.AuthService;
|
||||||
|
import ru.soune.nocopy.service.tokenoperation.TokenOperationService;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TokenOperationHandler implements RequestHandler {
|
||||||
|
private final TokenOperationService tokenOperationService;
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
private final AuthService authService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseResponse handle(BaseRequest request) throws Exception {
|
||||||
|
log.info("Handling TokenOperation request: msg_id={}, version={}",
|
||||||
|
request.getMsgId(), request.getVersion());
|
||||||
|
|
||||||
|
try {
|
||||||
|
TokenOperationRequest tokenRequest = objectMapper.convertValue(
|
||||||
|
request.getMessageBody(),
|
||||||
|
TokenOperationRequest.class
|
||||||
|
);
|
||||||
|
|
||||||
|
String action = tokenRequest.getAction();
|
||||||
|
if (action == null) {
|
||||||
|
return new BaseResponse(
|
||||||
|
request.getMsgId(),
|
||||||
|
MessageCode.INVALID_ACTION.getCode(),
|
||||||
|
MessageCode.INVALID_ACTION.getDescription(),
|
||||||
|
Map.of("error", "Action is required")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (action.toLowerCase()) {
|
||||||
|
case "get_list":
|
||||||
|
return handleGetList(request.getMsgId(), tokenRequest);
|
||||||
|
case "get_by_id":
|
||||||
|
return handleGetById(request.getMsgId(), tokenRequest);
|
||||||
|
case "get_by_user":
|
||||||
|
return handleGetByUser(request.getMsgId(), tokenRequest);
|
||||||
|
case "create":
|
||||||
|
return handleCreate(request.getMsgId(), tokenRequest);
|
||||||
|
case "update":
|
||||||
|
return handleUpdate(request.getMsgId(), tokenRequest);
|
||||||
|
case "delete":
|
||||||
|
return handleDelete(request.getMsgId(), tokenRequest);
|
||||||
|
case "delete_all_by_user":
|
||||||
|
return handleDeleteAllByUser(request.getMsgId(), tokenRequest);
|
||||||
|
case "get_stats":
|
||||||
|
return handleGetStats(request.getMsgId(), tokenRequest);
|
||||||
|
case "filter":
|
||||||
|
return handleFilter(request.getMsgId(), tokenRequest);
|
||||||
|
default:
|
||||||
|
return new BaseResponse(
|
||||||
|
request.getMsgId(),
|
||||||
|
MessageCode.INVALID_ACTION.getCode(),
|
||||||
|
MessageCode.INVALID_ACTION.getDescription(),
|
||||||
|
Map.of("available_actions",
|
||||||
|
"get_list, get_by_id, get_by_user, create, update, " +
|
||||||
|
"delete, delete_all_by_user, get_stats, filter")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error handling TokenOperation request", e);
|
||||||
|
return new BaseResponse(
|
||||||
|
request.getMsgId(),
|
||||||
|
MessageCode.INTERNAL_ERROR.getCode(),
|
||||||
|
MessageCode.INTERNAL_ERROR.getDescription(),
|
||||||
|
Map.of("error", e.getMessage())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseResponse handleGetList(Integer msgId, TokenOperationRequest request) {
|
||||||
|
if (request.getToken() == null) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.USER_NOT_FOUND.getCode(),
|
||||||
|
MessageCode.USER_NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "User ID is required")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Long userId = authService.useUserAuthToken(request.getToken());
|
||||||
|
|
||||||
|
try {
|
||||||
|
Page<TokenOperation> page = tokenOperationService.findByUserId(
|
||||||
|
userId,
|
||||||
|
request.getPage() != null ? request.getPage() : 0,
|
||||||
|
request.getSize() != null ? request.getSize() : 20
|
||||||
|
);
|
||||||
|
|
||||||
|
TokenOperationPageDto pageDto = TokenOperationPageDto.builder()
|
||||||
|
.content(page.getContent())
|
||||||
|
.pageNumber(page.getNumber())
|
||||||
|
.pageSize(page.getSize())
|
||||||
|
.totalElements(page.getTotalElements())
|
||||||
|
.totalPages(page.getTotalPages())
|
||||||
|
.last(page.isLast())
|
||||||
|
.first(page.isFirst())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Map<String, Object> responseData = new HashMap<>();
|
||||||
|
responseData.put("operations", pageDto);
|
||||||
|
responseData.put("total_elements", page.getTotalElements());
|
||||||
|
responseData.put("total_pages", page.getTotalPages());
|
||||||
|
responseData.put("current_page", page.getNumber());
|
||||||
|
responseData.put("page_size", page.getSize());
|
||||||
|
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.SUCCESS.getCode(),
|
||||||
|
MessageCode.SUCCESS.getDescription(),
|
||||||
|
responseData
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error getting token operations list", e);
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.INTERNAL_ERROR.getCode(),
|
||||||
|
MessageCode.INTERNAL_ERROR.getDescription(),
|
||||||
|
Map.of("error", "Error getting operations: " + e.getMessage())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseResponse handleGetById(Integer msgId, TokenOperationRequest request) {
|
||||||
|
log.info("Getting token operation by id: {}", request.getOperationId());
|
||||||
|
|
||||||
|
if (request.getOperationId() == null) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.OPERATION_NOT_FOUND.getCode(),
|
||||||
|
MessageCode.OPERATION_NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "Operation ID is required")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
TokenOperation operation = tokenOperationService.findById(request.getOperationId());
|
||||||
|
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.SUCCESS.getCode(),
|
||||||
|
MessageCode.SUCCESS.getDescription(),
|
||||||
|
operation
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (jakarta.persistence.EntityNotFoundException e) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.NOT_FOUND.getCode(),
|
||||||
|
MessageCode.NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "Operation not found with id: " + request.getOperationId())
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error getting token operation by id", e);
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.INTERNAL_ERROR.getCode(),
|
||||||
|
MessageCode.INTERNAL_ERROR.getDescription(),
|
||||||
|
Map.of("error", e.getMessage())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseResponse handleGetByUser(Integer msgId, TokenOperationRequest request) {
|
||||||
|
return handleGetList(msgId, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseResponse handleCreate(Integer msgId, TokenOperationRequest request) {
|
||||||
|
if (request.getToken() == null) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.AUTH_TOKEN_NOT_FOUND.getCode(),
|
||||||
|
MessageCode.AUTH_TOKEN_NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "User ID is required")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Long userId = authService.useUserAuthToken(request.getToken());
|
||||||
|
|
||||||
|
try {
|
||||||
|
TokenOperation operation = tokenOperationService.create(
|
||||||
|
request.getOperationType(),
|
||||||
|
userId,
|
||||||
|
request.getSpent()
|
||||||
|
);
|
||||||
|
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.SUCCESS.getCode(),
|
||||||
|
MessageCode.SUCCESS.getDescription(),
|
||||||
|
operation
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error creating token operation", e);
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.INTERNAL_ERROR.getCode(),
|
||||||
|
MessageCode.INTERNAL_ERROR.getDescription(),
|
||||||
|
Map.of("error", "Error creating operation: " + e.getMessage())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseResponse handleUpdate(Integer msgId, TokenOperationRequest request) {
|
||||||
|
log.info("Updating token operation: {}", request.getOperationId());
|
||||||
|
|
||||||
|
if (request.getOperationId() == null) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.OPERATION_NOT_FOUND.getCode(),
|
||||||
|
MessageCode.OPERATION_NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "Operation ID is required")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
TokenOperation existing = tokenOperationService.findById(request.getOperationId());
|
||||||
|
|
||||||
|
if (request.getOperationType() != null) {
|
||||||
|
existing.setOperationType(request.getOperationType());
|
||||||
|
}
|
||||||
|
if (request.getSpent() != null) {
|
||||||
|
existing.setSpent(request.getSpent());
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenOperation updated = tokenOperationService.update(request.getOperationId(), existing);
|
||||||
|
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.SUCCESS.getCode(),
|
||||||
|
MessageCode.SUCCESS.getDescription(),
|
||||||
|
updated
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (jakarta.persistence.EntityNotFoundException e) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.NOT_FOUND.getCode(),
|
||||||
|
MessageCode.NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "Operation not found with id: " + request.getOperationId())
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error updating token operation", e);
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.INTERNAL_ERROR.getCode(),
|
||||||
|
MessageCode.INTERNAL_ERROR.getDescription(),
|
||||||
|
Map.of("error", "Error updating operation: " + e.getMessage())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseResponse handleDelete(Integer msgId, TokenOperationRequest request) {
|
||||||
|
log.info("Deleting token operation: {}", request.getOperationId());
|
||||||
|
|
||||||
|
if (request.getOperationId() == null) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.OPERATION_NOT_FOUND.getCode(),
|
||||||
|
MessageCode.OPERATION_NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "Operation ID is required")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
tokenOperationService.deleteById(request.getOperationId());
|
||||||
|
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.SUCCESS.getCode(),
|
||||||
|
MessageCode.SUCCESS.getDescription(),
|
||||||
|
Map.of("message", "Operation deleted successfully",
|
||||||
|
"operation_id", request.getOperationId())
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (jakarta.persistence.EntityNotFoundException e) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.NOT_FOUND.getCode(),
|
||||||
|
MessageCode.NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "Operation not found with id: " + request.getOperationId())
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error deleting token operation", e);
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.INTERNAL_ERROR.getCode(),
|
||||||
|
MessageCode.INTERNAL_ERROR.getDescription(),
|
||||||
|
Map.of("error", "Error deleting operation: " + e.getMessage())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseResponse handleDeleteAllByUser(Integer msgId, TokenOperationRequest request) {
|
||||||
|
if (request.getToken() == null) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.AUTH_TOKEN_NOT_FOUND.getCode(),
|
||||||
|
MessageCode.AUTH_TOKEN_NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "User ID is required")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Long userId = authService.useUserAuthToken(request.getToken());
|
||||||
|
|
||||||
|
try {
|
||||||
|
tokenOperationService.deleteByUserId(userId);
|
||||||
|
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.SUCCESS.getCode(),
|
||||||
|
MessageCode.SUCCESS.getDescription(),
|
||||||
|
Map.of("message", "All operations deleted successfully for user",
|
||||||
|
"user_id", userId)
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error deleting all operations for user", e);
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.INTERNAL_ERROR.getCode(),
|
||||||
|
MessageCode.INTERNAL_ERROR.getDescription(),
|
||||||
|
Map.of("error", "Error deleting operations: " + e.getMessage())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseResponse handleGetStats(Integer msgId, TokenOperationRequest request) {
|
||||||
|
if (request.getToken() == null) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.AUTH_TOKEN_NOT_FOUND.getCode(),
|
||||||
|
MessageCode.AUTH_TOKEN_NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "User ID is required")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Long userId = authService.useUserAuthToken(request.getToken());
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.USER_NOT_FOUND.getCode(),
|
||||||
|
MessageCode.USER_NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "User ID is required")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Map<String, Long> statsByType = new HashMap<>();
|
||||||
|
long totalSpent = 0L;
|
||||||
|
|
||||||
|
for (OperationType type : OperationType.values()) {
|
||||||
|
Long spent = tokenOperationService.getTotalSpentByUserAndType(userId, type);
|
||||||
|
statsByType.put(type.name().toLowerCase(), spent != null ? spent : 0L);
|
||||||
|
totalSpent += spent != null ? spent : 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> statistics = new HashMap<>();
|
||||||
|
statistics.put("user_id", userId);
|
||||||
|
statistics.put("total_spent", totalSpent);
|
||||||
|
statistics.put("total_operations", tokenOperationService.countByUserId(userId));
|
||||||
|
statistics.put("stats_by_type", statsByType);
|
||||||
|
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.SUCCESS.getCode(),
|
||||||
|
MessageCode.SUCCESS.getDescription(),
|
||||||
|
statistics
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error getting statistics", e);
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.INTERNAL_ERROR.getCode(),
|
||||||
|
MessageCode.INTERNAL_ERROR.getDescription(),
|
||||||
|
Map.of("error", "Error getting statistics: " + e.getMessage())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseResponse handleFilter(Integer msgId, TokenOperationRequest request) {
|
||||||
|
if (request.getToken() == null) {
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.AUTH_TOKEN_NOT_FOUND.getCode(),
|
||||||
|
MessageCode.AUTH_TOKEN_NOT_FOUND.getDescription(),
|
||||||
|
Map.of("error", "User ID is required")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Long userId = authService.useUserAuthToken(request.getToken());
|
||||||
|
|
||||||
|
try {
|
||||||
|
Page<TokenOperation> page = tokenOperationService.findByFilters(
|
||||||
|
userId,
|
||||||
|
request.getOperationType(),
|
||||||
|
request.getMinSpent(),
|
||||||
|
request.getMaxSpent(),
|
||||||
|
request.getPage() != null ? request.getPage() : 0,
|
||||||
|
request.getSize() != null ? request.getSize() : 20,
|
||||||
|
request.getSortBy() != null ? request.getSortBy() : "createdAt",
|
||||||
|
request.getSortDirection() != null ? request.getSortDirection() : "desc"
|
||||||
|
);
|
||||||
|
|
||||||
|
TokenOperationPageDto pageDto = TokenOperationPageDto.builder()
|
||||||
|
.content(page.getContent())
|
||||||
|
.pageNumber(page.getNumber())
|
||||||
|
.pageSize(page.getSize())
|
||||||
|
.totalElements(page.getTotalElements())
|
||||||
|
.totalPages(page.getTotalPages())
|
||||||
|
.last(page.isLast())
|
||||||
|
.first(page.isFirst())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Map<String, Object> responseData = new HashMap<>();
|
||||||
|
responseData.put("operations", pageDto);
|
||||||
|
responseData.put("total_elements", page.getTotalElements());
|
||||||
|
responseData.put("total_pages", page.getTotalPages());
|
||||||
|
responseData.put("current_page", page.getNumber());
|
||||||
|
responseData.put("page_size", page.getSize());
|
||||||
|
|
||||||
|
responseData.put("applied_filters", Map.of(
|
||||||
|
"user_id",userId != null ? userId : "all",
|
||||||
|
"operation_type", request.getOperationType() != null ? request.getOperationType() : "all",
|
||||||
|
"min_spent", request.getMinSpent() != null ? request.getMinSpent() : "none",
|
||||||
|
"max_spent", request.getMaxSpent() != null ? request.getMaxSpent() : "none"
|
||||||
|
));
|
||||||
|
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.SUCCESS.getCode(),
|
||||||
|
MessageCode.SUCCESS.getDescription(),
|
||||||
|
responseData
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error filtering operations", e);
|
||||||
|
return new BaseResponse(
|
||||||
|
msgId,
|
||||||
|
MessageCode.INTERNAL_ERROR.getCode(),
|
||||||
|
MessageCode.INTERNAL_ERROR.getDescription(),
|
||||||
|
Map.of("error", "Error filtering operations: " + e.getMessage())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package ru.soune.nocopy.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.OperationType;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.TokenOperation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface TokenOperationRepository extends JpaRepository<TokenOperation, Long> {
|
||||||
|
Page<TokenOperation> findAll(Pageable pageable);
|
||||||
|
|
||||||
|
List<TokenOperation> findByUserId(Long userId);
|
||||||
|
|
||||||
|
Page<TokenOperation> findByUserId(Long userId, Pageable pageable);
|
||||||
|
|
||||||
|
Page<TokenOperation> findByOperationType(OperationType operationType, Pageable pageable);
|
||||||
|
|
||||||
|
@Query("SELECT t FROM TokenOperation t WHERE " +
|
||||||
|
"(:userId IS NULL OR t.userId = :userId) AND " +
|
||||||
|
"(:operationType IS NULL OR t.operationType = :operationType) AND " +
|
||||||
|
"(:minSpent IS NULL OR t.spent >= :minSpent) AND " +
|
||||||
|
"(:maxSpent IS NULL OR t.spent <= :maxSpent)")
|
||||||
|
Page<TokenOperation> findByFilters(
|
||||||
|
@Param("userId") Long userId,
|
||||||
|
@Param("operationType") OperationType operationType,
|
||||||
|
@Param("minSpent") Long minSpent,
|
||||||
|
@Param("maxSpent") Long maxSpent,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
|
||||||
|
@Query("SELECT SUM(t.spent) FROM TokenOperation t WHERE t.userId = :userId AND t.operationType = :operationType")
|
||||||
|
Long sumSpentByUserAndType(@Param("userId") Long userId, @Param("operationType") OperationType operationType);
|
||||||
|
|
||||||
|
Long countByUserId(Long userId);
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
import ru.soune.nocopy.dto.file.UploadProgressResponse;
|
import ru.soune.nocopy.dto.file.UploadProgressResponse;
|
||||||
import ru.soune.nocopy.entity.file.*;
|
import ru.soune.nocopy.entity.file.*;
|
||||||
import ru.soune.nocopy.entity.notification.NotificationType;
|
import ru.soune.nocopy.entity.notification.NotificationType;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.OperationType;
|
||||||
import ru.soune.nocopy.exception.*;
|
import ru.soune.nocopy.exception.*;
|
||||||
import ru.soune.nocopy.repository.FileEntityRepository;
|
import ru.soune.nocopy.repository.FileEntityRepository;
|
||||||
import ru.soune.nocopy.repository.FileUploadSessionRepository;
|
import ru.soune.nocopy.repository.FileUploadSessionRepository;
|
||||||
@@ -441,7 +442,7 @@ public class FileUploadServiceImpl implements FileUploadService {
|
|||||||
if (status != FileStatus.TEMP) {
|
if (status != FileStatus.TEMP) {
|
||||||
String fileType = session.getFileType();
|
String fileType = session.getFileType();
|
||||||
|
|
||||||
tariffInfoService.writeOffTokens(session.getUserId(), costService.protectFileCost(fileType));
|
tariffInfoService.writeOffTokens(session.getUserId(), costService.protectFileCost(fileType), OperationType.FILE_UPLOAD);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sessionRepository.save(session);
|
sessionRepository.save(session);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import ru.soune.nocopy.entity.notification.NotificationMessage;
|
|||||||
import ru.soune.nocopy.entity.notification.NotificationType;
|
import ru.soune.nocopy.entity.notification.NotificationType;
|
||||||
import ru.soune.nocopy.entity.tarif.TariffInfo;
|
import ru.soune.nocopy.entity.tarif.TariffInfo;
|
||||||
import ru.soune.nocopy.entity.tarif.TariffType;
|
import ru.soune.nocopy.entity.tarif.TariffType;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.OperationType;
|
||||||
import ru.soune.nocopy.entity.user.User;
|
import ru.soune.nocopy.entity.user.User;
|
||||||
import ru.soune.nocopy.exception.TariffNotFoundException;
|
import ru.soune.nocopy.exception.TariffNotFoundException;
|
||||||
import ru.soune.nocopy.repository.FileMonitoringRepository;
|
import ru.soune.nocopy.repository.FileMonitoringRepository;
|
||||||
@@ -66,7 +67,7 @@ public class MonitoringSearchService {
|
|||||||
TariffDTO tariffMonitoring = tariffService.getTariffByType(TariffType.valueOf(monitoringType.name()));
|
TariffDTO tariffMonitoring = tariffService.getTariffByType(TariffType.valueOf(monitoringType.name()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
tariffInfoService.writeOffTokens(monitoring.getUserId(), tariffMonitoring.getTokens());
|
tariffInfoService.writeOffTokens(monitoring.getUserId(), tariffMonitoring.getTokens(), OperationType.MONITORING);
|
||||||
|
|
||||||
boolean useYandex = searchProperties.getEngines().getOrDefault("yandex",
|
boolean useYandex = searchProperties.getEngines().getOrDefault("yandex",
|
||||||
new SearchProperties.EngineConfig()).isEnabled();
|
new SearchProperties.EngineConfig()).isEnabled();
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import ru.soune.nocopy.entity.notification.NotificationType;
|
|||||||
import ru.soune.nocopy.entity.search.GlobalSearchResult;
|
import ru.soune.nocopy.entity.search.GlobalSearchResult;
|
||||||
import ru.soune.nocopy.entity.search.GlobalSearchTask;
|
import ru.soune.nocopy.entity.search.GlobalSearchTask;
|
||||||
import ru.soune.nocopy.entity.search.SearchStatus;
|
import ru.soune.nocopy.entity.search.SearchStatus;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.OperationType;
|
||||||
import ru.soune.nocopy.repository.FileEntityRepository;
|
import ru.soune.nocopy.repository.FileEntityRepository;
|
||||||
import ru.soune.nocopy.repository.GlobalSearchResultRepository;
|
import ru.soune.nocopy.repository.GlobalSearchResultRepository;
|
||||||
import ru.soune.nocopy.repository.GlobalSearchTaskRepository;
|
import ru.soune.nocopy.repository.GlobalSearchTaskRepository;
|
||||||
@@ -59,7 +60,7 @@ public class GlobalSearchAsyncProcessor {
|
|||||||
FileEntity file = fileEntityRepository.findById(uuid)
|
FileEntity file = fileEntityRepository.findById(uuid)
|
||||||
.orElseThrow(() -> new RuntimeException("File not found: " + uuid));
|
.orElseThrow(() -> new RuntimeException("File not found: " + uuid));
|
||||||
|
|
||||||
tariffInfoService.writeOffTokens(userId, TariffConstants.TOKEN_VALUE_FOR_SEARCH);
|
tariffInfoService.writeOffTokens(userId, TariffConstants.TOKEN_VALUE_FOR_SEARCH, OperationType.GLOBAL_SEARCH);
|
||||||
GlobalSearchResult result = processFile(file, taskId, userId);
|
GlobalSearchResult result = processFile(file, taskId, userId);
|
||||||
globalSearchResultRepository.save(result);
|
globalSearchResultRepository.save(result);
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ import ru.soune.nocopy.entity.tarif.Tariff;
|
|||||||
import ru.soune.nocopy.entity.tarif.TariffInfo;
|
import ru.soune.nocopy.entity.tarif.TariffInfo;
|
||||||
import ru.soune.nocopy.entity.tarif.TariffStatus;
|
import ru.soune.nocopy.entity.tarif.TariffStatus;
|
||||||
import ru.soune.nocopy.entity.tarif.TariffType;
|
import ru.soune.nocopy.entity.tarif.TariffType;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.OperationType;
|
||||||
import ru.soune.nocopy.entity.user.User;
|
import ru.soune.nocopy.entity.user.User;
|
||||||
import ru.soune.nocopy.exception.TariffNotFoundException;
|
import ru.soune.nocopy.exception.TariffNotFoundException;
|
||||||
import ru.soune.nocopy.repository.TariffInfoRepository;
|
import ru.soune.nocopy.repository.TariffInfoRepository;
|
||||||
import ru.soune.nocopy.repository.TariffRepository;
|
import ru.soune.nocopy.repository.TariffRepository;
|
||||||
import ru.soune.nocopy.repository.UserRepository;
|
import ru.soune.nocopy.repository.UserRepository;
|
||||||
import ru.soune.nocopy.service.mail.EmailService;
|
import ru.soune.nocopy.service.mail.EmailService;
|
||||||
|
import ru.soune.nocopy.service.tokenoperation.TokenOperationService;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -35,6 +37,8 @@ public class TariffInfoService {
|
|||||||
|
|
||||||
private EmailService emailService;
|
private EmailService emailService;
|
||||||
|
|
||||||
|
private TokenOperationService tokenOperationService;
|
||||||
|
|
||||||
public TariffInfo createTariffInfo(LocalDateTime startTariff, LocalDateTime endTariff, TariffStatus tariffStatus,
|
public TariffInfo createTariffInfo(LocalDateTime startTariff, LocalDateTime endTariff, TariffStatus tariffStatus,
|
||||||
Integer tokens) {
|
Integer tokens) {
|
||||||
TariffInfo tariffInfo = new TariffInfo();
|
TariffInfo tariffInfo = new TariffInfo();
|
||||||
@@ -48,7 +52,7 @@ public class TariffInfoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Transactional
|
// @Transactional
|
||||||
public void writeOffTokens(long userId, Integer value) throws MessagingException, IOException {
|
public void writeOffTokens(long userId, Integer value, OperationType operationType) throws MessagingException, IOException {
|
||||||
User user = userRepository.findById(userId).orElseThrow();
|
User user = userRepository.findById(userId).orElseThrow();
|
||||||
|
|
||||||
TariffInfo activeTariffInfo;
|
TariffInfo activeTariffInfo;
|
||||||
@@ -60,6 +64,8 @@ public class TariffInfoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeOffTokensForTariff(activeTariffInfo, value);
|
writeOffTokensForTariff(activeTariffInfo, value);
|
||||||
|
|
||||||
|
tokenOperationService.create(operationType, userId, Long.valueOf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeOffTokensForTariff(TariffInfo activeTariffInfo, Integer value) throws MessagingException, IOException {
|
public void writeOffTokensForTariff(TariffInfo activeTariffInfo, Integer value) throws MessagingException, IOException {
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
package ru.soune.nocopy.service.tokenoperation;
|
||||||
|
|
||||||
|
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.entity.tokenoperation.OperationType;
|
||||||
|
import ru.soune.nocopy.entity.tokenoperation.TokenOperation;
|
||||||
|
import ru.soune.nocopy.repository.TokenOperationRepository;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityNotFoundException;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public class TokenOperationService {
|
||||||
|
|
||||||
|
private final TokenOperationRepository repository;
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public TokenOperation create(OperationType operationType, Long userId, Long spent) {
|
||||||
|
TokenOperation tokenOperation = new TokenOperation();
|
||||||
|
|
||||||
|
tokenOperation.setOperationType(operationType);
|
||||||
|
tokenOperation.setUserId(userId);
|
||||||
|
tokenOperation.setSpent(spent);
|
||||||
|
tokenOperation.setCreatedAt(LocalDateTime.now());
|
||||||
|
|
||||||
|
return repository.save(tokenOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TokenOperation findById(Long id) {
|
||||||
|
log.debug("Finding token operation by id: {}", id);
|
||||||
|
return repository.findById(id)
|
||||||
|
.orElseThrow(() -> new EntityNotFoundException("TokenOperation not found with id: " + id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Page<TokenOperation> findAll(int page, int size, String sortBy, String direction) {
|
||||||
|
log.debug("Finding all operations with pagination: page={}, size={}, sortBy={}, dir={}",
|
||||||
|
page, size, sortBy, direction);
|
||||||
|
|
||||||
|
Sort sort = direction.equalsIgnoreCase("desc")
|
||||||
|
? Sort.by(sortBy).descending()
|
||||||
|
: Sort.by(sortBy).ascending();
|
||||||
|
|
||||||
|
Pageable pageable = PageRequest.of(page, size, sort);
|
||||||
|
return repository.findAll(pageable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Page<TokenOperation> findByFilters(
|
||||||
|
Long userId,
|
||||||
|
OperationType operationType,
|
||||||
|
Long minSpent,
|
||||||
|
Long maxSpent,
|
||||||
|
int page,
|
||||||
|
int size,
|
||||||
|
String sortBy,
|
||||||
|
String direction) {
|
||||||
|
|
||||||
|
log.debug("Finding by filters: userId={}, type={}, minSpent={}, maxSpent={}",
|
||||||
|
userId, operationType, minSpent, maxSpent);
|
||||||
|
|
||||||
|
Sort sort = Sort.by(Sort.Direction.fromString(direction), sortBy);
|
||||||
|
Pageable pageable = PageRequest.of(page, size, sort);
|
||||||
|
|
||||||
|
return repository.findByFilters(userId, operationType, minSpent, maxSpent, pageable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Page<TokenOperation> findByUserId(Long userId, int page, int size) {
|
||||||
|
log.debug("Finding operations for user id: {}", userId);
|
||||||
|
Pageable pageable = PageRequest.of(page, size, Sort.by("id").descending());
|
||||||
|
return repository.findByUserId(userId, pageable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public TokenOperation update(Long id, TokenOperation updatedOperation) {
|
||||||
|
log.info("Updating token operation with id: {}", id);
|
||||||
|
|
||||||
|
TokenOperation existing = findById(id);
|
||||||
|
|
||||||
|
existing.setOperationType(updatedOperation.getOperationType());
|
||||||
|
existing.setUserId(updatedOperation.getUserId());
|
||||||
|
existing.setSpent(updatedOperation.getSpent());
|
||||||
|
|
||||||
|
return repository.save(existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deleteById(Long id) {
|
||||||
|
log.info("Deleting token operation with id: {}", id);
|
||||||
|
|
||||||
|
if (!repository.existsById(id)) {
|
||||||
|
throw new EntityNotFoundException("TokenOperation not found with id: " + id);
|
||||||
|
}
|
||||||
|
repository.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deleteByUserId(Long userId) {
|
||||||
|
log.warn("Deleting all operations for user id: {}", userId);
|
||||||
|
List<TokenOperation> userOps = repository.findByUserId(userId);
|
||||||
|
repository.deleteAll(userOps);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTotalSpentByUserAndType(Long userId, OperationType type) {
|
||||||
|
Long sum = repository.sumSpentByUserAndType(userId, type);
|
||||||
|
return sum != null ? sum : 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long countByUserId(Long userId) {
|
||||||
|
return repository.countByUserId(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user