From f52ce6db3cecbb5e5ec038c6bc084b70042efa13 Mon Sep 17 00:00:00 2001 From: vladp Date: Fri, 6 Feb 2026 01:01:34 +0700 Subject: [PATCH 1/2] dev add referral --- build.gradle | 2 + referral/src/main/kotlin/Referral.kt | 2 +- referral/src/main/kotlin/ReferralRepo.kt | 20 ++-- referral/src/main/kotlin/ReferralService.kt | 10 +- .../nocopy/configuration/ReferralConfig.java | 16 ++++ .../nocopy/dto/referral/ReferralRequest.java | 19 ++++ .../soune/nocopy/dto/register/RegRequest.java | 2 + .../soune/nocopy/handler/ReferralHandler.java | 91 +++++++++++++++++++ .../nocopy/handler/RegRequestHandler.java | 6 ++ .../referral/ReferralLevelProviderImpl.java | 31 +++++++ .../service/referral/ReferralRepoImpl.java | 75 +++++++++++++++ 11 files changed, 258 insertions(+), 16 deletions(-) create mode 100644 src/main/java/ru/soune/nocopy/configuration/ReferralConfig.java create mode 100644 src/main/java/ru/soune/nocopy/dto/referral/ReferralRequest.java create mode 100644 src/main/java/ru/soune/nocopy/handler/ReferralHandler.java create mode 100644 src/main/java/ru/soune/nocopy/service/referral/ReferralLevelProviderImpl.java create mode 100644 src/main/java/ru/soune/nocopy/service/referral/ReferralRepoImpl.java diff --git a/build.gradle b/build.gradle index 677e8c6..f7926a3 100644 --- a/build.gradle +++ b/build.gradle @@ -63,6 +63,8 @@ dependencies { implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.12.0' + implementation project(':referral') + } tasks.named('test') { diff --git a/referral/src/main/kotlin/Referral.kt b/referral/src/main/kotlin/Referral.kt index 0dd336b..f51b54e 100644 --- a/referral/src/main/kotlin/Referral.kt +++ b/referral/src/main/kotlin/Referral.kt @@ -2,7 +2,7 @@ package ru.soune interface Referral { - val userId: String + val userId: Long val referralLink: String val inviter: String? val currentLevel: String diff --git a/referral/src/main/kotlin/ReferralRepo.kt b/referral/src/main/kotlin/ReferralRepo.kt index 54a6c49..7a48039 100644 --- a/referral/src/main/kotlin/ReferralRepo.kt +++ b/referral/src/main/kotlin/ReferralRepo.kt @@ -2,32 +2,32 @@ package ru.soune interface ReferralRepo { - fun getUserReferralLink(userId: String): String + fun getUserReferralLink(userId: Long): String fun getUserIdByLink(link: String): String - fun getInviterIdForUser(userId: String): String? + fun getInviterIdForUser(userId: Long): Long? - fun getReferralLevelForUser(userId: String): String + fun getReferralLevelForUser(userId: Long): String - fun getReferralByUserId(userId: String): Referral + fun getReferralByUserId(userId: Long): Referral - fun getReferralInvitees(userId: String, pageSize: Int, pageNumber: Int): List + fun getReferralInvitees(userId: Long, pageSize: Int, pageNumber: Int): List // создаем новую запись в БД fun createReferralEntity(entity: Referral) // прибавить к totalIncome и availableIncome значение transferAmount - fun increaseIncome(userId: String, transferAmount: Int) + fun increaseIncome(userId: Long, transferAmount: Int) // установить active в true - fun activateUser(userId: String): Boolean + fun activateUser(userId: Long): Boolean // посчитать записи, у которых inviter == userId и active == true - fun getActiveInviteeForUser(userId: String): Int + fun getActiveInviteeForUser(userId: Long): Int // посчитать записи, у которых inviter == userId - fun getTotalInviteeForUser(userId: String): Int + fun getTotalInviteeForUser(userId: Long): Int - fun upgradeReferralLevelForUser(userId: String, newLevelId: String) + fun upgradeReferralLevelForUser(userId: Long, newLevelId: String) } \ No newline at end of file diff --git a/referral/src/main/kotlin/ReferralService.kt b/referral/src/main/kotlin/ReferralService.kt index bae3dc0..2ff40ee 100644 --- a/referral/src/main/kotlin/ReferralService.kt +++ b/referral/src/main/kotlin/ReferralService.kt @@ -5,7 +5,7 @@ class ReferralService( private val referralRepo: ReferralRepo, ) { - fun onRegister(userId: String, inviterReferralLink: String?) { + fun onRegister(userId: Long, inviterReferralLink: String?) { val initialReferralLevel = referralLevelProvider.getInitialReferralLevelId() val referralLink = referralRepo.getUserReferralLink(userId) val inviter = inviterReferralLink?.let(referralRepo::getUserIdByLink) @@ -24,7 +24,7 @@ class ReferralService( referralRepo.createReferralEntity(referral) } - fun onUserAccountRefill(userId: String, transferAmount: Int) { + fun onUserAccountRefill(userId: Long, transferAmount: Int) { val wasActivated = referralRepo.activateUser(userId) val inviterId = referralRepo.getInviterIdForUser(userId) ?: return val currentInviterLevel = referralRepo.getReferralLevelForUser(inviterId) @@ -47,11 +47,11 @@ class ReferralService( referralLevelProvider.getAvailableReferralLevels() - fun getReferralLevelForUser(userId: String): ReferralLevel = + fun getReferralLevelForUser(userId: Long): ReferralLevel = referralRepo.getReferralLevelForUser(userId) .let { referralLevelProvider.getReferralLevelById(it) } - fun getReferralStatForUser(userId: String): ReferralStat { + fun getReferralStatForUser(userId: Long): ReferralStat { var referral = referralRepo.getReferralByUserId(userId) return ReferralStat( totalInvitee = referralRepo.getTotalInviteeForUser(userId), @@ -62,6 +62,6 @@ class ReferralService( ) } - fun getInviteeForUser(userId: String, pageSize: Int, pageNumber: Int): List = + fun getInviteeForUser(userId: Long, pageSize: Int, pageNumber: Int): List = referralRepo.getReferralInvitees(userId, pageSize, pageNumber) } \ No newline at end of file diff --git a/src/main/java/ru/soune/nocopy/configuration/ReferralConfig.java b/src/main/java/ru/soune/nocopy/configuration/ReferralConfig.java new file mode 100644 index 0000000..160e707 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/configuration/ReferralConfig.java @@ -0,0 +1,16 @@ +package ru.soune.nocopy.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.soune.ReferralLevelProvider; +import ru.soune.ReferralRepo; +import ru.soune.ReferralService; + +@Configuration +public class ReferralConfig { + + @Bean + public ReferralService referralService(ReferralLevelProvider referralLevelProvider, ReferralRepo referralRepo) { + return new ReferralService(referralLevelProvider, referralRepo); + } +} diff --git a/src/main/java/ru/soune/nocopy/dto/referral/ReferralRequest.java b/src/main/java/ru/soune/nocopy/dto/referral/ReferralRequest.java new file mode 100644 index 0000000..8185f14 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/dto/referral/ReferralRequest.java @@ -0,0 +1,19 @@ +package ru.soune.nocopy.dto.referral; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.soune.nocopy.entity.user.AuthToken; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class ReferralRequest { + private String token; + private Integer amount; + private Integer pageSize; + private Integer pageNumber; + private String action; +} diff --git a/src/main/java/ru/soune/nocopy/dto/register/RegRequest.java b/src/main/java/ru/soune/nocopy/dto/register/RegRequest.java index d9b630b..15d1c47 100644 --- a/src/main/java/ru/soune/nocopy/dto/register/RegRequest.java +++ b/src/main/java/ru/soune/nocopy/dto/register/RegRequest.java @@ -29,4 +29,6 @@ public class RegRequest { private String password; private String authToken; + + private String referralLink; } diff --git a/src/main/java/ru/soune/nocopy/handler/ReferralHandler.java b/src/main/java/ru/soune/nocopy/handler/ReferralHandler.java new file mode 100644 index 0000000..9213bf2 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/handler/ReferralHandler.java @@ -0,0 +1,91 @@ +package ru.soune.nocopy.handler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import ru.soune.ReferralInvitee; +import ru.soune.ReferralLevel; +import ru.soune.ReferralService; +import ru.soune.ReferralStat; +import ru.soune.nocopy.dto.BaseRequest; +import ru.soune.nocopy.dto.BaseResponse; +import ru.soune.nocopy.dto.MessageCode; +import ru.soune.nocopy.dto.referral.ReferralRequest; +import ru.soune.nocopy.entity.user.AuthToken; +import ru.soune.nocopy.repository.AuthTokenRepository; + +import java.util.List; +import java.util.Map; + + +@Component +@RequiredArgsConstructor +public class ReferralHandler implements RequestHandler { + + private final ReferralService referralService; + + private final AuthTokenRepository authTokenRepository; + + private final ObjectMapper mapper = new ObjectMapper(); + + @Override + public BaseResponse handle(BaseRequest request) throws Exception { + ReferralRequest referralRequest = mapper.convertValue(request.getMessageBody(), ReferralRequest.class); + String action = referralRequest.getAction(); + String token = referralRequest.getToken(); + AuthToken authToken = authTokenRepository.findByToken(token).orElseThrow(); + + switch (action) { + case "refill": + return handleRefill(request, authToken.getUser().getId(), referralRequest.getAmount()); + case "levels": + return handleReferralLevels(request); + case "level": + return handleUserLevel(request, authToken.getUser().getId()); + case "userStats" : + return handleUserStats(request, authToken.getUser().getId()); + case "invitees": + return handleInvitees(referralRequest, request, authToken.getUser().getId()); + } + + return null; + } + + + private BaseResponse handleRefill(BaseRequest request, Long userId, Integer amount) { + referralService.onUserAccountRefill(userId, amount); + + return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription(), Map.of("account", "refill")); + } + + private BaseResponse handleReferralLevels(BaseRequest request) { + List referralLevels = referralService.getReferralLevels(); + + return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription(), referralLevels); + + } + + private BaseResponse handleUserLevel(BaseRequest request, Long userId) { + ReferralLevel referralLevelForUser = referralService.getReferralLevelForUser(userId); + + return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription(), referralLevelForUser); + } + + private BaseResponse handleUserStats(BaseRequest request, Long userId) { + ReferralStat referralStatForUser = referralService.getReferralStatForUser(userId); + + return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription(), referralStatForUser); + } + + private BaseResponse handleInvitees(ReferralRequest referralRequest, BaseRequest request, Long userId) { + List inviteeForUser = referralService.getInviteeForUser(userId, referralRequest.getPageSize(), + referralRequest.getPageNumber()); + + return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription(), inviteeForUser); + } +} diff --git a/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java b/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java index 6718fca..5c62223 100644 --- a/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java +++ b/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java @@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; +import ru.soune.ReferralService; import ru.soune.nocopy.dto.*; import ru.soune.nocopy.dto.register.RegAnswer; import ru.soune.nocopy.dto.register.RegRequest; @@ -34,6 +35,9 @@ public class RegRequestHandler implements RequestHandler { private final EmailService emailService; + //TODO add when add all referall +// private final ReferralService referralService; + @Override public BaseResponse handle(BaseRequest request) throws ValidationException { RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class); @@ -81,6 +85,8 @@ public class RegRequestHandler implements RequestHandler { regAnswer.setToken(token); regAnswer.setVerified(true); regAnswer.setActive(true); + //TODO add when add all referall +// referralService.onRegister(authToken.getUser().getId(), regRequest.getReferralLink()); return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), MessageCode.SUCCESS.getDescription(), regAnswer); diff --git a/src/main/java/ru/soune/nocopy/service/referral/ReferralLevelProviderImpl.java b/src/main/java/ru/soune/nocopy/service/referral/ReferralLevelProviderImpl.java new file mode 100644 index 0000000..3bc2fdf --- /dev/null +++ b/src/main/java/ru/soune/nocopy/service/referral/ReferralLevelProviderImpl.java @@ -0,0 +1,31 @@ +package ru.soune.nocopy.service.referral; + +import org.springframework.stereotype.Component; +import ru.soune.ReferralLevel; +import ru.soune.ReferralLevelProvider; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class ReferralLevelProviderImpl implements ReferralLevelProvider { + + @Override + public List getAvailableReferralLevels() { + // TODO + + return new ArrayList(); + } + + @Override + public String getInitialReferralLevelId() { + return "bronze"; + } + + @Override + public ReferralLevel getReferralLevelById(String levelId) { + // TODO + + return null; + } +} \ No newline at end of file diff --git a/src/main/java/ru/soune/nocopy/service/referral/ReferralRepoImpl.java b/src/main/java/ru/soune/nocopy/service/referral/ReferralRepoImpl.java new file mode 100644 index 0000000..ac9cdf5 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/service/referral/ReferralRepoImpl.java @@ -0,0 +1,75 @@ +package ru.soune.nocopy.service.referral; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.springframework.stereotype.Repository; +import ru.soune.Referral; +import ru.soune.ReferralInvitee; +import ru.soune.ReferralRepo; + +import java.util.List; + +@Repository +public class ReferralRepoImpl implements ReferralRepo { + + @Override + public String getUserIdByLink(String link) { + // TODO + return ""; + } + + @Override + public @NotNull String getUserReferralLink(long userId) { + return ""; + } + + @Override + public @Nullable Long getInviterIdForUser(long userId) { + return 0L; + } + + @Override + public @NotNull String getReferralLevelForUser(long userId) { + return ""; + } + + @Override + public @NotNull Referral getReferralByUserId(long userId) { + return null; + } + + @Override + public @NotNull List getReferralInvitees(long userId, int pageSize, int pageNumber) { + return List.of(); + } + + @Override + public void createReferralEntity(@NotNull Referral entity) { + + } + + @Override + public void increaseIncome(long userId, int transferAmount) { + + } + + @Override + public boolean activateUser(long userId) { + return false; + } + + @Override + public int getActiveInviteeForUser(long userId) { + return 0; + } + + @Override + public int getTotalInviteeForUser(long userId) { + return 0; + } + + @Override + public void upgradeReferralLevelForUser(long userId, @NotNull String newLevelId) { + + } +} -- 2.54.0 From a7e94639d2d03cc16891cb9580bda9f12abb6d27 Mon Sep 17 00:00:00 2001 From: vladp Date: Fri, 6 Feb 2026 19:27:25 +0700 Subject: [PATCH 2/2] NC_BACK-36_1 --- referral/src/main/kotlin/Referral.kt | 2 +- referral/src/main/kotlin/ReferralRepo.kt | 2 +- referral/src/main/kotlin/ReferralService.kt | 1 + referral/src/main/kotlin/ReferralStat.kt | 1 + .../nocopy/configuration/HandlerConfig.java | 4 +- .../nocopy/dto/referral/ReferralRequest.java | 1 - .../nocopy/entity/referral/Referral.java | 37 ++++ .../entity/referral/ReferralLevelEntity.java | 21 +++ .../soune/nocopy/handler/ReferralHandler.java | 1 - .../nocopy/handler/RegRequestHandler.java | 7 +- .../repository/ReferralJpaRepository.java | 40 ++++ .../repository/ReferralLevelRepository.java | 13 ++ .../referral/ReferralLevelProviderImpl.java | 62 +++++- .../service/referral/ReferralRepoImpl.java | 178 ++++++++++++++++-- 14 files changed, 340 insertions(+), 30 deletions(-) create mode 100644 src/main/java/ru/soune/nocopy/entity/referral/Referral.java create mode 100644 src/main/java/ru/soune/nocopy/entity/referral/ReferralLevelEntity.java create mode 100644 src/main/java/ru/soune/nocopy/repository/ReferralJpaRepository.java create mode 100644 src/main/java/ru/soune/nocopy/repository/ReferralLevelRepository.java diff --git a/referral/src/main/kotlin/Referral.kt b/referral/src/main/kotlin/Referral.kt index f51b54e..4b65d8a 100644 --- a/referral/src/main/kotlin/Referral.kt +++ b/referral/src/main/kotlin/Referral.kt @@ -4,7 +4,7 @@ interface Referral { val userId: Long val referralLink: String - val inviter: String? + val inviter: Long? val currentLevel: String val totalIncome: Int val availableIncome: Int diff --git a/referral/src/main/kotlin/ReferralRepo.kt b/referral/src/main/kotlin/ReferralRepo.kt index 7a48039..17c36cd 100644 --- a/referral/src/main/kotlin/ReferralRepo.kt +++ b/referral/src/main/kotlin/ReferralRepo.kt @@ -4,7 +4,7 @@ interface ReferralRepo { fun getUserReferralLink(userId: Long): String - fun getUserIdByLink(link: String): String + fun getUserIdByLink(link: String): Long? fun getInviterIdForUser(userId: Long): Long? diff --git a/referral/src/main/kotlin/ReferralService.kt b/referral/src/main/kotlin/ReferralService.kt index 2ff40ee..489e149 100644 --- a/referral/src/main/kotlin/ReferralService.kt +++ b/referral/src/main/kotlin/ReferralService.kt @@ -59,6 +59,7 @@ class ReferralService( totalIncome = referral.totalIncome, availableIncome = referral.availableIncome, holdBalance = referral.holdBalance, + referralLink = referral.referralLink ) } diff --git a/referral/src/main/kotlin/ReferralStat.kt b/referral/src/main/kotlin/ReferralStat.kt index 554a723..d9e6ae5 100644 --- a/referral/src/main/kotlin/ReferralStat.kt +++ b/referral/src/main/kotlin/ReferralStat.kt @@ -6,4 +6,5 @@ data class ReferralStat( val totalIncome: Int, val availableIncome: Int, val holdBalance: Int, + val referralLink: String, ) \ No newline at end of file diff --git a/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java b/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java index b2d7862..933ee69 100644 --- a/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java +++ b/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java @@ -22,7 +22,8 @@ public class HandlerConfig { AuthRequestHandler authRequestHandler, CompanyHandler companyHandler, TariffHandler tariffHandler, - TariffInfoHandler tariffInfoHandler + TariffInfoHandler tariffInfoHandler, + ReferralHandler referralHandler ) { Map map = new HashMap<>(); map.put(20001, login); @@ -36,6 +37,7 @@ public class HandlerConfig { map.put(30000, companyHandler); map.put(30001, tariffHandler); map.put(30002, tariffInfoHandler); + map.put(30003, referralHandler); return map; } diff --git a/src/main/java/ru/soune/nocopy/dto/referral/ReferralRequest.java b/src/main/java/ru/soune/nocopy/dto/referral/ReferralRequest.java index 8185f14..d22a4f9 100644 --- a/src/main/java/ru/soune/nocopy/dto/referral/ReferralRequest.java +++ b/src/main/java/ru/soune/nocopy/dto/referral/ReferralRequest.java @@ -4,7 +4,6 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import ru.soune.nocopy.entity.user.AuthToken; @Data @AllArgsConstructor diff --git a/src/main/java/ru/soune/nocopy/entity/referral/Referral.java b/src/main/java/ru/soune/nocopy/entity/referral/Referral.java new file mode 100644 index 0000000..d3d1036 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/entity/referral/Referral.java @@ -0,0 +1,37 @@ +package ru.soune.nocopy.entity.referral; + + +import jakarta.persistence.*; +import lombok.Data; +import org.springframework.data.annotation.CreatedDate; +import java.time.LocalDateTime; + +@Entity +@Table(name = "referrals") +@Data +public class Referral { + @Id + private Long userId; + + @Column(name = "referral_link", unique = true, nullable = false) + private String referralLink; + + @Column(name = "inviter_id") + private Long inviterId; + + @Column(name = "level_id") + private String levelId = "bronze"; + + @Column(name = "total_income") + private int totalIncome = 0; + + @Column(name = "is_active") + private boolean isActive = false; + + @CreatedDate + @Column(name = "created_at", updatable = false, nullable = false) + private LocalDateTime createdAt = LocalDateTime.now(); + + @Column(name = "hold_balance") + private int holdBalance = 0; +} diff --git a/src/main/java/ru/soune/nocopy/entity/referral/ReferralLevelEntity.java b/src/main/java/ru/soune/nocopy/entity/referral/ReferralLevelEntity.java new file mode 100644 index 0000000..9562db3 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/entity/referral/ReferralLevelEntity.java @@ -0,0 +1,21 @@ +package ru.soune.nocopy.entity.referral; + +import jakarta.persistence.*; +import lombok.Data; + +@Entity +@Table(name = "referral_levels") +@Data +public class ReferralLevelEntity { + @Id + private String id; + + @Column(nullable = false) + private String name; + + @Column(name = "min_invitees") + private int minInvitees; + + @Column(name = "reward_percentage") + private int rewardPercentage; +} diff --git a/src/main/java/ru/soune/nocopy/handler/ReferralHandler.java b/src/main/java/ru/soune/nocopy/handler/ReferralHandler.java index 9213bf2..902b022 100644 --- a/src/main/java/ru/soune/nocopy/handler/ReferralHandler.java +++ b/src/main/java/ru/soune/nocopy/handler/ReferralHandler.java @@ -51,7 +51,6 @@ public class ReferralHandler implements RequestHandler { return null; } - private BaseResponse handleRefill(BaseRequest request, Long userId, Integer amount) { referralService.onUserAccountRefill(userId, amount); diff --git a/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java b/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java index 5c62223..58a6221 100644 --- a/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java +++ b/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java @@ -35,8 +35,7 @@ public class RegRequestHandler implements RequestHandler { private final EmailService emailService; - //TODO add when add all referall -// private final ReferralService referralService; + private final ReferralService referralService; @Override public BaseResponse handle(BaseRequest request) throws ValidationException { @@ -85,8 +84,8 @@ public class RegRequestHandler implements RequestHandler { regAnswer.setToken(token); regAnswer.setVerified(true); regAnswer.setActive(true); - //TODO add when add all referall -// referralService.onRegister(authToken.getUser().getId(), regRequest.getReferralLink()); + + referralService.onRegister(authToken.getUser().getId(), regRequest.getReferralLink()); return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), MessageCode.SUCCESS.getDescription(), regAnswer); diff --git a/src/main/java/ru/soune/nocopy/repository/ReferralJpaRepository.java b/src/main/java/ru/soune/nocopy/repository/ReferralJpaRepository.java new file mode 100644 index 0000000..db9c703 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/repository/ReferralJpaRepository.java @@ -0,0 +1,40 @@ +package ru.soune.nocopy.repository; + +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; +import ru.soune.nocopy.entity.referral.Referral; +import java.util.List; + +@Repository +public interface ReferralJpaRepository extends JpaRepository { + Referral findByReferralLink(String link); + + Referral findByUserId(Long userId); + + List findByInviterId(Long inviterId); + + @Query("SELECT r FROM Referral r WHERE r.inviterId = :userId AND r.isActive = true") + List findByInviterId(Long inviterId, Pageable pageable); + + @Modifying + @Query("UPDATE Referral r SET r.totalIncome = r.totalIncome + :amount WHERE r.userId = :userId") + void increaseIncome(@Param("userId") Long userId, @Param("amount") int amount); + + @Modifying + @Query("UPDATE Referral r SET r.levelId = :newLevelId WHERE r.userId = :userId") + void updateLevel(@Param("userId") Long userId, @Param("newLevelId") String newLevelId); + + @Modifying + @Query("UPDATE Referral r SET r.isActive = true WHERE r.userId = :userId") + void activateUser(@Param("userId") Long userId); + + @Query("SELECT COUNT(r) FROM Referral r WHERE r.inviterId = :userId AND r.isActive = true") + int countActiveInvitees(@Param("userId") Long userId); + + @Query("SELECT COUNT(r) FROM Referral r WHERE r.inviterId = :userId") + int countTotalInvitees(@Param("userId") Long userId); +} diff --git a/src/main/java/ru/soune/nocopy/repository/ReferralLevelRepository.java b/src/main/java/ru/soune/nocopy/repository/ReferralLevelRepository.java new file mode 100644 index 0000000..7a02874 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/repository/ReferralLevelRepository.java @@ -0,0 +1,13 @@ +package ru.soune.nocopy.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import ru.soune.nocopy.entity.referral.ReferralLevelEntity; + +import java.util.List; + +@Repository +public interface ReferralLevelRepository extends JpaRepository { + List findAllByOrderByMinInviteesAsc(); + ReferralLevelEntity findById(String id); +} diff --git a/src/main/java/ru/soune/nocopy/service/referral/ReferralLevelProviderImpl.java b/src/main/java/ru/soune/nocopy/service/referral/ReferralLevelProviderImpl.java index 3bc2fdf..f714ab7 100644 --- a/src/main/java/ru/soune/nocopy/service/referral/ReferralLevelProviderImpl.java +++ b/src/main/java/ru/soune/nocopy/service/referral/ReferralLevelProviderImpl.java @@ -1,20 +1,29 @@ package ru.soune.nocopy.service.referral; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import ru.soune.ReferralLevel; import ru.soune.ReferralLevelProvider; +import ru.soune.nocopy.entity.referral.ReferralLevelEntity; +import ru.soune.nocopy.repository.ReferralLevelRepository; + -import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; @Component +@RequiredArgsConstructor public class ReferralLevelProviderImpl implements ReferralLevelProvider { + private final ReferralLevelRepository referralLevelRepository; + @Override public List getAvailableReferralLevels() { - // TODO + List entities = referralLevelRepository.findAll(); - return new ArrayList(); + return entities.stream() + .map(this::createReferralLevel) + .collect(Collectors.toList()); } @Override @@ -24,8 +33,51 @@ public class ReferralLevelProviderImpl implements ReferralLevelProvider { @Override public ReferralLevel getReferralLevelById(String levelId) { - // TODO + return createReferralLevel(referralLevelRepository.findById(levelId)); + } - return null; + private ReferralLevel createReferralLevel(ReferralLevelEntity entity) { + return new ReferralLevel() { + @Override + public String getId() { + return entity.getId(); + } + + @Override + public String getName() { + return entity.getName(); + } + + @Override + public int getShare() { + return entity.getRewardPercentage(); + } + + @Override + public int getMinInvitee() { + return entity.getMinInvitees(); + } + + @Override + public int getMaxInvitee() { + switch (entity.getId()) { + case "bronze": return 9; + case "silver": return 49; + case "gold": return 99; + case "platinum": return Integer.MAX_VALUE; + default: return Integer.MAX_VALUE; + } + } + + @Override + public String getNext() { + switch (entity.getId()) { + case "bronze": return "silver"; + case "silver": return "gold"; + case "gold": return "platinum"; + default: return null; + } + } + }; } } \ No newline at end of file diff --git a/src/main/java/ru/soune/nocopy/service/referral/ReferralRepoImpl.java b/src/main/java/ru/soune/nocopy/service/referral/ReferralRepoImpl.java index ac9cdf5..b97b566 100644 --- a/src/main/java/ru/soune/nocopy/service/referral/ReferralRepoImpl.java +++ b/src/main/java/ru/soune/nocopy/service/referral/ReferralRepoImpl.java @@ -1,75 +1,221 @@ package ru.soune.nocopy.service.referral; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; import ru.soune.Referral; import ru.soune.ReferralInvitee; import ru.soune.ReferralRepo; +import ru.soune.nocopy.entity.user.User; +import ru.soune.nocopy.repository.ReferralJpaRepository; +import ru.soune.nocopy.repository.UserRepository; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; import java.util.List; +import java.util.UUID; @Repository +@RequiredArgsConstructor +@Slf4j +@Transactional public class ReferralRepoImpl implements ReferralRepo { - @Override - public String getUserIdByLink(String link) { - // TODO - return ""; - } + private final ReferralJpaRepository referralRepository; + + private final UserRepository userRepository; @Override public @NotNull String getUserReferralLink(long userId) { - return ""; + ru.soune.nocopy.entity.referral.Referral referral = + referralRepository.findByUserId(userId); + + if (referral != null && referral.getReferralLink() != null && + !referral.getReferralLink().isEmpty()) { + return referral.getReferralLink(); + } + + String newLink = "ref-" + userId + "-" + UUID.randomUUID().toString().substring(0, 8); + + if (referral == null) { + referral = new ru.soune.nocopy.entity.referral.Referral(); + referral.setUserId(userId); + referral.setLevelId("bronze"); + referral.setActive(false); + } + + referral.setReferralLink(newLink); + + referralRepository.save(referral); + + return newLink; + } + + @Override + public @NotNull Long getUserIdByLink(@NotNull String link) { + ru.soune.nocopy.entity.referral.Referral referral = referralRepository.findByReferralLink(link); + return referral != null ? referral.getUserId() : 0L; } @Override public @Nullable Long getInviterIdForUser(long userId) { - return 0L; + ru.soune.nocopy.entity.referral.Referral referral = referralRepository.findByUserId(userId); + return referral != null ? referral.getInviterId() : 0L; } @Override public @NotNull String getReferralLevelForUser(long userId) { - return ""; + ru.soune.nocopy.entity.referral.Referral referral = referralRepository.findByUserId(userId); + return referral != null ? referral.getLevelId() : ""; } @Override public @NotNull Referral getReferralByUserId(long userId) { - return null; + ru.soune.nocopy.entity.referral.Referral entity = referralRepository.findByUserId(userId); + + if (entity == null) { + return createDefaultReferral(userId); + } + + return new Referral() { + @Override + public long getUserId() { return entity.getUserId(); } + + @Override + public String getReferralLink() { return entity.getReferralLink(); } + + @Override + public Long getInviter() { + return entity.getInviterId() != null ? entity.getInviterId() : 0L; + } + + @Override + public String getCurrentLevel() { return entity.getLevelId(); } + + @Override + public int getTotalIncome() { return entity.getTotalIncome(); } + + @Override + public int getAvailableIncome() { + Integer holdBalance = entity.getHoldBalance(); + return entity.getTotalIncome() - (holdBalance != null ? holdBalance : 0); + } + + @Override + public int getHoldBalance() { + Integer holdBalance = entity.getHoldBalance(); + return holdBalance != null ? holdBalance : 0; + } + + @Override + public boolean getActive() { return entity.isActive(); } + }; + } + + private Referral createDefaultReferral(long userId) { + return new Referral() { + @Override + public long getUserId() { return userId; } + + @Override + public String getReferralLink() { return ""; } + + @Override + public Long getInviter() { return 0L; } + + @Override + public String getCurrentLevel() { return "bronze"; } + + @Override + public int getTotalIncome() { return 0; } + + @Override + public int getAvailableIncome() { return 0; } + + @Override + public int getHoldBalance() { return 0; } + + @Override + public boolean getActive() { return false; } + }; } @Override public @NotNull List getReferralInvitees(long userId, int pageSize, int pageNumber) { - return List.of(); + Pageable pageable = PageRequest.of(pageNumber, pageSize); + List referrals = referralRepository.findByInviterId(userId, pageable); + + List result = new ArrayList<>(); + + for (ru.soune.nocopy.entity.referral.Referral referral : referrals) { + User user = userRepository.findById(referral.getUserId()).orElse(null); + + String email = user != null ? user.getEmail() : ""; + boolean isActive = referral.isActive(); + String regDate = referral.getCreatedAt() != null ? + referral.getCreatedAt().toString() : ""; + + try { + Constructor constructor = ReferralInvitee.class.getDeclaredConstructor( + String.class, boolean.class, String.class + ); + ReferralInvitee invitee = constructor.newInstance(email, isActive, regDate); + result.add(invitee); + } catch (Exception e) { + e.printStackTrace(); + } + } + + return result; } @Override public void createReferralEntity(@NotNull Referral entity) { + ru.soune.nocopy.entity.referral.Referral referral = new ru.soune.nocopy.entity.referral.Referral(); + referral.setUserId(entity.getUserId()); + referral.setReferralLink(entity.getReferralLink()); + referral.setInviterId(entity.getInviter()); + referral.setLevelId(entity.getCurrentLevel()); + referral.setTotalIncome(entity.getTotalIncome()); + referral.setHoldBalance(entity.getHoldBalance()); + referral.setActive(entity.getActive()); + referralRepository.save(referral); } @Override public void increaseIncome(long userId, int transferAmount) { - + referralRepository.increaseIncome(userId, transferAmount); } @Override public boolean activateUser(long userId) { - return false; + try { + referralRepository.activateUser(userId); + return true; + } catch (Exception e) { + return false; + } } @Override public int getActiveInviteeForUser(long userId) { - return 0; + return referralRepository.countActiveInvitees(userId); } @Override public int getTotalInviteeForUser(long userId) { - return 0; + return referralRepository.countTotalInvitees(userId); } @Override public void upgradeReferralLevelForUser(long userId, @NotNull String newLevelId) { - + referralRepository.updateLevel(userId, newLevelId); } -} +} \ No newline at end of file -- 2.54.0