dev add tariff and temp flag for files
Test Workflow / test (push) Successful in 2s

This commit is contained in:
vladp
2026-01-30 12:52:16 +07:00
parent fb5642db9e
commit 49dc19cd04
21 changed files with 612 additions and 24 deletions
@@ -60,14 +60,14 @@ public class FileStatsService {
private Long calculateTotalSize(List<FileEntity> files) {
return files.stream()
.filter(file -> file.getStatus() != FileStatus.DELETED)
.filter(file -> file.getStatus() != FileStatus.DELETED && file.getStatus() != FileStatus.TEMP)
.mapToLong(FileEntity::getFileSize)
.sum();
}
private Integer calculateTotalCount(List<FileEntity> files) {
return (int) files.stream()
.filter(file -> file.getStatus() != FileStatus.DELETED)
.filter(file -> file.getStatus() != FileStatus.DELETED && file.getStatus() != FileStatus.TEMP)
.count();
}
@@ -79,7 +79,7 @@ public class FileStatsService {
private Long calculateMediaSize(List<FileEntity> files, FileType fileType) {
return files.stream()
.filter(file -> file.getStatus() != FileStatus.DELETED)
.filter(file -> file.getStatus() != FileStatus.DELETED && file.getStatus() != FileStatus.TEMP)
.filter(file -> isFileType(file, fileType))
.mapToLong(FileEntity::getFileSize)
.sum();
@@ -87,7 +87,7 @@ public class FileStatsService {
private Integer calculateMediaCount(List<FileEntity> files, FileType fileType) {
return (int) files.stream()
.filter(file -> file.getStatus() != FileStatus.DELETED)
.filter(file -> file.getStatus() != FileStatus.DELETED && file.getStatus() != FileStatus.TEMP)
.filter(file -> isFileType(file, fileType))
.count();
}
@@ -2,6 +2,7 @@ package ru.soune.nocopy.service.file;
import org.springframework.web.multipart.MultipartFile;
import ru.soune.nocopy.dto.file.UploadProgressResponse;
import ru.soune.nocopy.entity.file.FileStatus;
import ru.soune.nocopy.entity.file.FileUploadSession;
import java.io.IOException;
@@ -18,5 +19,5 @@ public interface FileUploadService {
UploadProgressResponse getUploadProgress(String uploadId);
void completeFileProcessingAsync(FileUploadSession session);
void completeFileProcessingAsync(FileUploadSession session, FileStatus status);
}
@@ -215,7 +215,7 @@ public class FileUploadServiceImpl implements FileUploadService {
@Async("fileUploadTaskExecutor")
@Transactional
@Override
public void completeFileProcessingAsync(FileUploadSession session) {
public void completeFileProcessingAsync(FileUploadSession session, FileStatus status) {
try {
Path filePath = Paths.get(session.getFilePath());
String checksum = calculateChecksum(filePath);
@@ -231,7 +231,7 @@ public class FileUploadServiceImpl implements FileUploadService {
.checksum(checksum)
.uploadSessionId(session.getUploadId())
.protectionStatus(ProtectionStatus.PROCESSING)
.status(FileStatus.ACTIVE)
.status(status)
.build();
FileEntity saved = fileEntityRepository.save(fileEntity);
@@ -317,7 +317,9 @@ public class FileUploadServiceImpl implements FileUploadService {
session.setStatus(UploadStatus.COMPLETED);
session.setFilePath(finalFilePath);
completeFileProcessingAsync(session);
FileStatus status = findSimilar == 0 ? FileStatus.ACTIVE: FileStatus.TEMP;
completeFileProcessingAsync(session, status);
} else {
sessionRepository.save(session);
@@ -10,14 +10,20 @@ import ru.soune.nocopy.dto.register.LoginAnswer;
import ru.soune.nocopy.dto.register.LoginRequest;
import ru.soune.nocopy.dto.register.RegRequest;
import ru.soune.nocopy.entity.company.Company;
import ru.soune.nocopy.entity.tarif.TariffInfo;
import ru.soune.nocopy.entity.tarif.TariffType;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.Permission;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.NotFoundAuthToken;
import ru.soune.nocopy.exception.NotValidFieldException;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.repository.CompanyRepository;
import ru.soune.nocopy.repository.TariffInfoRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.file.CheckCounterService;
import ru.soune.nocopy.service.tariff.TariffInfoService;
import ru.soune.nocopy.service.tariff.TariffService;
import java.security.SecureRandom;
import java.time.LocalDateTime;
@@ -37,6 +43,10 @@ public class AuthService {
private final CheckCounterService checkCounterService;
private final TariffInfoRepository tariffInfoRepository;
private final TariffInfoService tariffInfoService;
private final SecureRandom secureRandom = new SecureRandom();
@Transactional
@@ -48,20 +58,20 @@ public class AuthService {
user.setActive(true);
user.setEmailVerified(true);
if (registerRequest.getCompanyName() != null &&
AccountType.valueOf(registerRequest.getAccountType().toUpperCase()).equals(AccountType.B2B)) {
Company company = new Company();
company.setCompanyName(registerRequest.getCompanyName());
AccountType accountType = AccountType.valueOf(registerRequest.getAccountType().toUpperCase());
companyRepository.save(company);
user.setCompany(company);
if (accountType == AccountType.B2B && registerRequest.getCompanyName() != null) {
createCompanyAccount(registerRequest, user);
} else {
createIndividualAccount(user);
}
if (registerRequest.getPhone() != null) {
user.setPhone(registerRequest.getPhone());
}
user.grantPermission(Permission.LOGIN_BIT);
User savedUser = userRepository.save(user);
AuthToken authToken = genereateAuthToken(savedUser);
@@ -138,4 +148,26 @@ public class AuthService {
secureRandom.nextBytes(bytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}
private void createCompanyAccount(RegRequest request, User user) {
Company company = new Company();
company.setCompanyName(request.getCompanyName());
TariffInfo companyTariff = tariffInfoService.createTariffInfo(TariffType.DEMO);
company.setTariffInfo(companyTariff);
companyRepository.save(company);
tariffInfoService.addTariffInfo(companyTariff);
user.setCompany(company);
user.grantPermission(Permission.COMPANY_SETTINGS_BIT);
}
private void createIndividualAccount(User user) {
TariffInfo personalTariff = tariffInfoService.createTariffInfo(TariffType.DEMO);
tariffInfoService.addTariffInfo(personalTariff);
user.setPersonalTariffInfo(personalTariff);
}
}
@@ -0,0 +1,15 @@
package ru.soune.nocopy.service.tariff;
public class TariffConstants {
public static final double DEMO_PRICE = 0;
public static final double BASIC_PRICE = 100;
public static final double START_PRICE = 200;
public static final double PRO_PRICE = 300;
public static final double ENTERPRISE_PRICE = 400;
public static final Integer DEMO_TOKENS = 10;
public static final Integer BASIC_TOKENS = 100;
public static final Integer START_TOKENS = 200;
public static final Integer PRO_TOKENS = 300;
public static final Integer ENTERPRISE_TOKENS = 400;
}
@@ -0,0 +1,105 @@
package ru.soune.nocopy.service.tariff;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.dto.tarriff.TariffInfoDTO;
import ru.soune.nocopy.entity.tarif.Tariff;
import ru.soune.nocopy.entity.tarif.TariffInfo;
import ru.soune.nocopy.entity.tarif.TariffStatus;
import ru.soune.nocopy.entity.tarif.TariffType;
import ru.soune.nocopy.exception.TariffNotFoundException;
import ru.soune.nocopy.repository.TariffInfoRepository;
import ru.soune.nocopy.repository.TariffRepository;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Service
@AllArgsConstructor
public class TariffInfoService {
private TariffInfoRepository tariffInfoRepository;
private TariffRepository tariffRepository;
public TariffInfo createTariffInfo(LocalDateTime startTariff, LocalDateTime endTariff, TariffStatus tariffStatus) {
TariffInfo tariffInfo = new TariffInfo();
tariffInfo.setStartTariff(startTariff);
tariffInfo.setStatus(tariffStatus);
tariffInfo.setEndTariff(endTariff);
return tariffInfoRepository.save(tariffInfo);
}
public TariffInfo createTariffInfo(TariffType tariffType) {
Tariff tariff = tariffRepository.findByType(tariffType).orElseThrow();
TariffInfo tariffInfo = createTariffInfo(LocalDateTime.now(), LocalDateTime.now().plusDays(30),
TariffStatus.ACTIVE);
tariffInfo.setTariff(tariff);
return tariffInfoRepository.save(tariffInfo);
}
public void addTariffInfo(TariffInfo tariffInfo) {
tariffInfoRepository.save(tariffInfo);
}
public List<TariffInfoDTO> getAllTariffInfos() {
return tariffInfoRepository.findAll()
.stream()
.map(this::convertToInfoDTO)
.collect(Collectors.toList());
}
public TariffInfoDTO getTariffInfoById(String id) {
return tariffInfoRepository.findById(id)
.map(this::convertToInfoDTO)
.orElseThrow(() -> new TariffNotFoundException("Tariff info not found"));
}
@Transactional
public TariffInfoDTO createTariffInfo(TariffInfoDTO tariffInfoDTO) {
TariffInfo tariffInfo = new TariffInfo();
updateTariffInfoFromDTO(tariffInfo, tariffInfoDTO);
return convertToInfoDTO(tariffInfoRepository.save(tariffInfo));
}
@Transactional
public TariffInfoDTO updateTariffInfo(String id, TariffInfoDTO tariffInfoDTO) {
TariffInfo tariffInfo = tariffInfoRepository.findById(id)
.orElseThrow(() -> new TariffNotFoundException("Tariff not found"));
updateTariffInfoFromDTO(tariffInfo, tariffInfoDTO);
return convertToInfoDTO(tariffInfoRepository.save(tariffInfo));
}
@Transactional
public void deleteTariffInfo(String id) {
tariffInfoRepository.deleteById(id);
}
private TariffInfoDTO convertToInfoDTO(TariffInfo tariffInfo) {
return new TariffInfoDTO(
tariffInfo.getId(),
tariffInfo.getStatus().name(),
tariffInfo.getStartTariff(),
tariffInfo.getEndTariff(),
tariffInfo.getTariff() != null ? tariffInfo.getTariff().getId() : null,
tariffInfo.getTariff() != null ? tariffInfo.getTariff().getName() : null
);
}
private void updateTariffInfoFromDTO(TariffInfo tariffInfo, TariffInfoDTO dto) {
tariffInfo.setStatus(TariffStatus.valueOf(dto.getStatus()));
tariffInfo.setStartTariff(dto.getStartTariff());
tariffInfo.setEndTariff(dto.getEndTariff());
if (dto.getTariffId() != null) {
Tariff tariff = tariffRepository.findById(dto.getTariffId())
.orElseThrow(() -> new TariffNotFoundException("Tariff not found"));
tariffInfo.setTariff(tariff);
}
}
}
@@ -0,0 +1,98 @@
package ru.soune.nocopy.service.tariff;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.entity.tarif.Tariff;
import ru.soune.nocopy.entity.tarif.TariffType;
import ru.soune.nocopy.repository.TariffRepository;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class TariffInitializationService {
private final TariffRepository tariffRepository;
@EventListener(ApplicationReadyEvent.class)
@Transactional
public void initializeDefaultTariffs() {
List<Tariff> existingTariffs = tariffRepository.findAll();
if (existingTariffs.isEmpty()) {
createDefaultTariffs();
} else {
Map<TariffType, Boolean> existingTypes = new HashMap<>();
existingTariffs.forEach(tariff -> existingTypes.put(TariffType.valueOf(tariff.getType()), true));
Arrays.stream(TariffType.values())
.filter(type -> !existingTypes.containsKey(type))
.forEach(this::createDefaultTariff);
}
}
private void createDefaultTariffs() {
Arrays.stream(TariffType.values())
.forEach(this::createDefaultTariff);
}
private void createDefaultTariff(TariffType type) {
Tariff tariff = new Tariff();
tariff.setType(type.name());
switch (type) {
case DEMO:
tariff.setName("Демо");
tariff.setPrice(TariffConstants.DEMO_PRICE);
tariff.setTokens(TariffConstants.DEMO_TOKENS);
tariff.setMaxFilesCount(10);
tariff.setDiskSize(1024L * 1024 * 100);
tariff.setMaxUsers(1L);
break;
case START:
tariff.setName("Стартовый");
tariff.setPrice(TariffConstants.START_PRICE);
tariff.setTokens(TariffConstants.START_TOKENS);
tariff.setMaxFilesCount(50);
tariff.setDiskSize(1024L * 1024 * 500);
tariff.setMaxUsers(3L);
break;
case BASIC:
tariff.setName("Базовый");
tariff.setPrice(TariffConstants.BASIC_PRICE);
tariff.setTokens(TariffConstants.BASIC_TOKENS);
tariff.setMaxFilesCount(200);
tariff.setDiskSize(1024L * 1024 * 1024 * 2L);
tariff.setMaxUsers(10L);
break;
case PRO:
tariff.setName("Профессиональный");
tariff.setPrice(TariffConstants.PRO_PRICE);
tariff.setTokens(TariffConstants.PRO_TOKENS);
tariff.setMaxFilesCount(1000);
tariff.setDiskSize(1024L * 1024 * 1024 * 10L);
tariff.setMaxUsers(25L);
break;
case ENTERPRISE:
tariff.setName("Корпоративный");
tariff.setPrice(TariffConstants.ENTERPRISE_PRICE);
tariff.setTokens(TariffConstants.ENTERPRISE_TOKENS);
tariff.setMaxFilesCount(5000);
tariff.setDiskSize(1024L * 1024 * 1024 * 50L);
tariff.setMaxUsers(100L);
break;
}
tariffRepository.save(tariff);
}
}
@@ -0,0 +1,98 @@
package ru.soune.nocopy.service.tariff;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.dto.tarriff.TariffDTO;
import ru.soune.nocopy.entity.tarif.Tariff;
import ru.soune.nocopy.entity.tarif.TariffType;
import ru.soune.nocopy.exception.TariffNotFoundException;
import ru.soune.nocopy.repository.TariffRepository;
import java.util.List;
import java.util.stream.Collectors;
@Service
@AllArgsConstructor
public class TariffService {
private final TariffRepository tariffRepository;
public Tariff addTariff(String tariffName, double price, String type, int tokens, long diskSize, long maxUsers,
int maxFilesCount) {
Tariff tariff = new Tariff();
tariff.setName(tariffName);
tariff.setPrice(price);
tariff.setType(type);
tariff.setTokens(tokens);
tariff.setDiskSize(diskSize);
tariff.setMaxUsers(maxUsers);
tariff.setMaxFilesCount(maxFilesCount);
return tariffRepository.save(tariff);
}
public List<TariffDTO> getAllTariffs() {
return tariffRepository.findAllByOrderByPriceAsc()
.stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
}
public TariffDTO getTariffById(Long id) {
return tariffRepository.findById(id)
.map(this::convertToDTO)
.orElseThrow(() -> new TariffNotFoundException("Tariff not found"));
}
public TariffDTO getTariffByType(TariffType type) {
return tariffRepository.findByType(type)
.map(this::convertToDTO)
.orElseThrow(() -> new TariffNotFoundException("Tariff not found"));
}
@Transactional
public TariffDTO createTariff(TariffDTO tariffDTO) {
Tariff tariff = new Tariff();
updateTariffFromDTO(tariff, tariffDTO);
return convertToDTO(tariffRepository.save(tariff));
}
@Transactional
public TariffDTO updateTariff(Long id, TariffDTO tariffDTO) {
Tariff tariff = tariffRepository.findById(id)
.orElseThrow(() -> new TariffNotFoundException("Tariff not found"));
updateTariffFromDTO(tariff, tariffDTO);
return convertToDTO(tariffRepository.save(tariff));
}
@Transactional
public void deleteTariff(Long id) {
tariffRepository.deleteById(id);
}
private TariffDTO convertToDTO(Tariff tariff) {
return new TariffDTO(
tariff.getId(),
tariff.getType(),
tariff.getName(),
tariff.getPrice(),
tariff.getTokens(),
tariff.getMaxFilesCount(),
tariff.getDiskSize(),
tariff.getMaxUsers()
);
}
private void updateTariffFromDTO(Tariff tariff, TariffDTO dto) {
tariff.setType(dto.getType());
tariff.setName(dto.getName());
tariff.setPrice(dto.getPrice());
tariff.setTokens(dto.getTokens());
tariff.setMaxFilesCount(dto.getMaxFilesCount());
tariff.setDiskSize(dto.getDiskSize());
tariff.setMaxUsers(dto.getMaxUsers());
}
}