邀请码 列表和统计功能完善

This commit is contained in:
tianfeng 2025-10-22 11:23:17 +08:00
parent 88ef879b22
commit 815f42db27
11 changed files with 583 additions and 11 deletions

View File

@ -12,6 +12,8 @@ import com.red.circle.other.app.dto.cmd.activity.InviteUserActivityLimitCmd;
import com.red.circle.other.app.service.activity.InviteUserActivityService;
import com.red.circle.other.app.dto.cmd.activity.BindInviteCodeCmd;
import com.red.circle.other.app.dto.clientobject.activity.InviteCodeCO;
import com.red.circle.other.app.dto.clientobject.activity.InviteIncomeStatisticsCO;
import com.red.circle.other.app.dto.clientobject.activity.ValidInviteUserCO;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
@ -173,4 +175,32 @@ public class InviteUserActivityRestController {
inviteUserActivityService.bindInviteCode(cmd);
}
/**
* 邀请收益统计.
*
* @eo.name 邀请收益统计
* @eo.url /income/statistics
* @eo.method get
* @eo.request-type formdata
*/
@GetMapping("/income/statistics")
public InviteIncomeStatisticsCO getIncomeStatistics(AppExtCommand cmd) {
InviteIncomeStatisticsCO statistics = inviteUserActivityService.getIncomeStatistics(cmd);
return statistics;
}
/**
* 有效邀请用户列表.
*
* @eo.name 有效邀请用户列表
* @eo.url /valid/invite/users
* @eo.method get
* @eo.request-type formdata
*/
@GetMapping("/valid/invite/users")
public List<ValidInviteUserCO> getValidInviteUsers(AppExtCommand cmd) {
List<ValidInviteUserCO> users = inviteUserActivityService.getValidInviteUsers(cmd);
return users;
}
}

View File

@ -6,6 +6,7 @@ import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.rds.entity.user.user.UserInviteUser;
import com.red.circle.other.infra.database.rds.service.user.user.UserInviteUserService;
import com.red.circle.other.infra.enums.user.InviteTypeEnum;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import lombok.RequiredArgsConstructor;
@ -40,45 +41,81 @@ public class BindInviteCodeExe {
public void execute(BindInviteCodeCmd cmd) {
Long userId = cmd.getReqUserId();
String inviteCode = cmd.getInviteCode();
String inviteType = cmd.getInviteType();
String sysOrigin = cmd.getReqSysOrigin().getOrigin();
log.info("开始绑定邀请码, userId={}, inviteCode={}", userId, inviteCode);
log.info("开始绑定邀请码, userId={}, inviteCode={}, inviteType={}", userId, inviteCode, inviteType);
// 1. 校验用户是否存在
// 1. 校验inviteType是否合法
if (!InviteTypeEnum.LOTTERY.getCode().equals(inviteType) &&
!InviteTypeEnum.REGISTER.getCode().equals(inviteType)) {
throw new RuntimeException("Invalid invitation type, must be LOTTERY or REGISTER");
}
// 3. 校验用户是否存在
UserProfile userProfile = userProfileGateway.getByUserId(userId);
if (userProfile == null) {
throw new RuntimeException("The user does not exist.");
}
// 2. 校验是否已绑定过邀请人
List<UserInviteUser> existingInvite = userInviteUserService.query().eq(UserInviteUser::getUserId, userId).list();
// 4. 校验是否已绑定过邀请人userId=邀请人, inviteUserId=被邀请人
// 当前用户作为被邀请人查询 inviteUserId=当前用户
List<UserInviteUser> existingInvite = userInviteUserService.query()
.eq(UserInviteUser::getInviteUserId, userId) // 当前用户作为被邀请人
.list();
if (existingInvite != null && !existingInvite.isEmpty()) {
throw new RuntimeException("The inviter has been bound before and cannot be bound again");
}
// 3. 根据邀请码查找邀请人
// 5. 根据邀请码查找邀请人
UserProfile inviterProfile = inviteCodeService.getUserProfileByInviteCode(inviteCode);
if (inviterProfile == null) {
throw new RuntimeException("The invitation code is invalid and the corresponding user was not found");
}
// 4. 校验不能邀请自己
// 6. 校验不能邀请自己
if (Objects.equals(userId, inviterProfile.getId())) {
throw new RuntimeException("You cannot bind your own invitation code");
}
// 5. 保存邀请关系
// 再次校验如果当前用户已经绑定了其他邀请人则不能再绑定
// 这里是双重校验确保数据一致性
List<UserInviteUser> doubleCheck = userInviteUserService.query()
.eq(UserInviteUser::getInviteUserId, userId)
.list();
if (doubleCheck != null && !doubleCheck.isEmpty()) {
Long existingInviterId = doubleCheck.get(0).getUserId();
log.warn("用户已绑定邀请人,不能重复绑定, userId={}, existingInviterId={}, newInviterId={}",
userId, existingInviterId, inviterProfile.getId());
throw new RuntimeException("You have already bound an inviter and cannot bind again");
}
// 校验双向绑定如果邀请人已经被当前用户邀请过则不能再绑定
// 如果 inviterProfile 已经是当前用户的被邀请人则不能让 inviterProfile 成为当前用户的邀请人
// 查询userId=当前用户, inviteUserId=邀请人检查当前用户是否已经邀请过这个邀请人
List<UserInviteUser> reverseInvite = userInviteUserService.query()
.eq(UserInviteUser::getUserId, userId) // 当前用户作为邀请人
.eq(UserInviteUser::getInviteUserId, inviterProfile.getId()) // 邀请人作为被邀请人
.list();
if (reverseInvite != null && !reverseInvite.isEmpty()) {
log.warn("不能双向绑定,该用户已被当前用户邀请过, userId={}, inviterUserId={}",
userId, inviterProfile.getId());
throw new RuntimeException("Cannot bind bidirectionally, this user has already been invited by you");
}
// 7. 保存邀请关系userId=邀请人, inviteUserId=被邀请人
UserInviteUser inviteUser = new UserInviteUser();
inviteUser.setId(IdWorkerUtils.getId());
inviteUser.setSysOrigin(sysOrigin);
inviteUser.setUserId(userId);
inviteUser.setInviteUserId(inviterProfile.getId());
inviteUser.setUserId(inviterProfile.getId()); // 邀请人
inviteUser.setInviteUserId(userId); // 被邀请人当前用户
inviteUser.setInviteType(inviteType); // 使用传入的inviteType
inviteUser.setCreateTime(TimestampUtils.now());
inviteUser.setUpdateTime(TimestampUtils.now());
userInviteUserService.save(inviteUser);
log.info("绑定邀请码成功, userId={}, inviterUserId={}, inviteCode={}",
userId, inviterProfile.getId(), inviteCode);
log.info("绑定邀请码成功, userId={}, inviterUserId={}, inviteCode={}, inviteType={}",
userId, inviterProfile.getId(), inviteCode, inviteType);
}
}

View File

@ -0,0 +1,163 @@
package com.red.circle.other.app.command.activity;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.other.app.dto.clientobject.activity.InviteIncomeStatisticsCO;
import com.red.circle.other.infra.database.rds.dao.user.user.InviteUserRechargeCommissionDAO;
import com.red.circle.other.infra.database.rds.dao.user.user.UserInviteUserDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.InviteUserRechargeCommission;
import com.red.circle.other.infra.database.rds.entity.user.user.UserInviteUser;
import com.red.circle.other.infra.enums.user.InviteTypeEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;
/**
* 获取邀请收益统计执行器
*
* 表结构说明
* user_invite_user: userId(邀请人), inviteUserId(被邀请人)
* user_invite_user_recharge_commission: userId(被邀请人-充值人), inviteUserId(邀请人-获得佣金人)
*
* @author system
* @date 2025-01-22
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class GetIncomeStatisticsExe {
private final UserInviteUserDAO userInviteUserDAO;
private final InviteUserRechargeCommissionDAO inviteUserRechargeCommissionDAO;
/**
* 执行获取邀请收益统计
*
* @param cmd 命令
* @return 收益统计
*/
public InviteIncomeStatisticsCO execute(AppExtCommand cmd) {
Long userId = cmd.getReqUserId();
// 查询当前用户邀请的所有用户userId=邀请人
List<UserInviteUser> allInvites = userInviteUserDAO.selectList(
new LambdaQueryWrapper<UserInviteUser>()
.eq(UserInviteUser::getUserId, userId) // userId是邀请人
);
// 筛选有效邀请
List<Long> validInvitedUserIds = getValidInvitedUserIds(allInvites);
// 计算总收益
BigDecimal totalIncome = calculateTotalIncome(userId, validInvitedUserIds);
// 计算今日收益
BigDecimal todayIncome = calculateTodayIncome(userId, validInvitedUserIds);
InviteIncomeStatisticsCO statistics = new InviteIncomeStatisticsCO();
statistics.setTotalIncome(totalIncome);
statistics.setTodayIncome(todayIncome);
statistics.setValidInviteCount(validInvitedUserIds.size());
log.info("邀请收益统计, userId={}, totalIncome={}, todayIncome={}, validCount={}",
userId, totalIncome, todayIncome, validInvitedUserIds.size());
return statistics;
}
/**
* 获取有效邀请用户ID列表
*/
private List<Long> getValidInvitedUserIds(List<UserInviteUser> allInvites) {
return allInvites.stream()
.filter(this::isValidInvite)
.map(UserInviteUser::getInviteUserId) // inviteUserId是被邀请人
.collect(Collectors.toList());
}
/**
* 判断是否为有效邀请
*/
private boolean isValidInvite(UserInviteUser invite) {
String inviteType = invite.getInviteType();
// LOTTERY类型直接算有效
if (InviteTypeEnum.LOTTERY.getCode().equals(inviteType)) {
return true;
}
// REGISTER类型需要检查充值记录
if (InviteTypeEnum.REGISTER.getCode().equals(inviteType)) {
// userId=邀请人, inviteUserId=被邀请人
return hasValidRecharge(invite.getInviteUserId(), invite.getUserId());
}
return false;
}
/**
* 检查是否有有效充值记录commission > 0
* @param invitedUserId 被邀请人 ID充值的人
* @param inviterUserId 邀请人 ID获得佣金的人
*/
private boolean hasValidRecharge(Long invitedUserId, Long inviterUserId) {
Long count = inviteUserRechargeCommissionDAO.selectCount(
new LambdaQueryWrapper<InviteUserRechargeCommission>()
.eq(InviteUserRechargeCommission::getUserId, invitedUserId) // 被邀请人
.eq(InviteUserRechargeCommission::getInviteUserId, inviterUserId) // 邀请人
.gt(InviteUserRechargeCommission::getCommission, BigDecimal.ZERO)
);
return count != null && count > 0;
}
/**
* 计算总收益
*/
private BigDecimal calculateTotalIncome(Long inviterUserId, List<Long> validInvitedUserIds) {
if (validInvitedUserIds.isEmpty()) {
return BigDecimal.ZERO;
}
List<InviteUserRechargeCommission> commissions = inviteUserRechargeCommissionDAO.selectList(
new LambdaQueryWrapper<InviteUserRechargeCommission>()
.eq(InviteUserRechargeCommission::getInviteUserId, inviterUserId)
.in(InviteUserRechargeCommission::getUserId, validInvitedUserIds)
);
return commissions.stream()
.map(InviteUserRechargeCommission::getCommission)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* 计算今日收益
*/
private BigDecimal calculateTodayIncome(Long inviterUserId, List<Long> validInvitedUserIds) {
if (validInvitedUserIds.isEmpty()) {
return BigDecimal.ZERO;
}
LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
List<InviteUserRechargeCommission> todayCommissions = inviteUserRechargeCommissionDAO.selectList(
new LambdaQueryWrapper<InviteUserRechargeCommission>()
.eq(InviteUserRechargeCommission::getInviteUserId, inviterUserId)
.in(InviteUserRechargeCommission::getUserId, validInvitedUserIds)
.ge(InviteUserRechargeCommission::getCreateTime, Timestamp.valueOf(todayStart))
.le(InviteUserRechargeCommission::getCreateTime, Timestamp.valueOf(todayEnd))
);
return todayCommissions.stream()
.map(InviteUserRechargeCommission::getCommission)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}

View File

@ -0,0 +1,179 @@
package com.red.circle.other.app.command.activity;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.other.app.dto.clientobject.activity.ValidInviteUserCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.rds.dao.user.user.InviteUserRechargeCommissionDAO;
import com.red.circle.other.infra.database.rds.dao.user.user.UserInviteUserDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.InviteUserRechargeCommission;
import com.red.circle.other.infra.database.rds.entity.user.user.UserInviteUser;
import com.red.circle.other.infra.enums.user.InviteTypeEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 获取有效邀请用户列表执行器
*
* 表结构说明
* user_invite_user: userId(邀请人), inviteUserId(被邀请人)
* user_invite_user_recharge_commission: userId(被邀请人-充值人), inviteUserId(邀请人-获得佣金人)
*
* @author system
* @date 2025-01-22
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class GetValidInviteUsersExe {
private final UserInviteUserDAO userInviteUserDAO;
private final InviteUserRechargeCommissionDAO inviteUserRechargeCommissionDAO;
private final UserProfileGateway userProfileGateway;
// 邀请关系有效期天数
private static final int VALID_DAYS = 30;
/**
* 执行获取有效邀请用户列表
*
* @param cmd 命令
* @return 有效邀请用户列表
*/
public List<ValidInviteUserCO> execute(AppExtCommand cmd) {
Long inviterUserId = cmd.getReqUserId(); // 邀请人ID
// 查询当前用户邀请的所有用户userId=邀请人
List<UserInviteUser> allInvites = userInviteUserDAO.selectList(
new LambdaQueryWrapper<UserInviteUser>()
.eq(UserInviteUser::getUserId, inviterUserId) // userId是邀请人
.orderByDesc(UserInviteUser::getCreateTime)
);
if (allInvites.isEmpty()) {
return new ArrayList<>();
}
// 筛选有效邀请
List<UserInviteUser> validInvites = allInvites.stream()
.filter(this::isValidInvite)
.collect(Collectors.toList());
if (validInvites.isEmpty()) {
return new ArrayList<>();
}
// 获取被邀请用户ID列表inviteUserId
List<Long> invitedUserIds = validInvites.stream()
.map(UserInviteUser::getInviteUserId) // inviteUserId是被邀请人
.collect(Collectors.toList());
// 批量查询用户信息
Map<Long, UserProfile> userProfileMap = userProfileGateway.mapByUserIds(new HashSet<>(invitedUserIds));
// 批量查询佣金信息inviteUserId=邀请人userId=被邀请人
List<InviteUserRechargeCommission> commissions = inviteUserRechargeCommissionDAO.selectList(
new LambdaQueryWrapper<InviteUserRechargeCommission>()
.eq(InviteUserRechargeCommission::getInviteUserId, inviterUserId) // 邀请人
.in(InviteUserRechargeCommission::getUserId, invitedUserIds) // 被邀请人
);
Map<Long, BigDecimal> commissionMap = commissions.stream()
.collect(Collectors.groupingBy(
InviteUserRechargeCommission::getUserId, // 被邀请人ID
Collectors.reducing(BigDecimal.ZERO,
InviteUserRechargeCommission::getCommission,
BigDecimal::add)
));
// 组装返回数据
List<ValidInviteUserCO> result = new ArrayList<>();
for (UserInviteUser invite : validInvites) {
ValidInviteUserCO userCO = buildValidInviteUserCO(invite, userProfileMap, commissionMap);
result.add(userCO);
}
log.info("有效邀请用户列表, inviterUserId={}, validCount={}", inviterUserId, result.size());
return result;
}
/**
* 判断是否为有效邀请
*/
private boolean isValidInvite(UserInviteUser invite) {
String inviteType = invite.getInviteType();
// LOTTERY类型直接算有效
if (InviteTypeEnum.LOTTERY.getCode().equals(inviteType)) {
return true;
}
// REGISTER类型需要检查充值记录
if (InviteTypeEnum.REGISTER.getCode().equals(inviteType)) {
// userId=邀请人, inviteUserId=被邀请人
return hasValidRecharge(invite.getInviteUserId(), invite.getUserId());
}
return false;
}
/**
* 检查是否有有效充值记录commission > 0
* @param invitedUserId 被邀请人ID充值的人
* @param inviterUserId 邀请人ID获得佣金的人
*/
private boolean hasValidRecharge(Long invitedUserId, Long inviterUserId) {
long count = inviteUserRechargeCommissionDAO.selectCount(
new LambdaQueryWrapper<InviteUserRechargeCommission>()
.eq(InviteUserRechargeCommission::getUserId, invitedUserId) // 被邀请人
.eq(InviteUserRechargeCommission::getInviteUserId, inviterUserId) // 邀请人
.gt(InviteUserRechargeCommission::getCommission, BigDecimal.ZERO)
);
return count > 0;
}
/**
* 构建有效邀请用户CO
*/
private ValidInviteUserCO buildValidInviteUserCO(
UserInviteUser invite,
Map<Long, UserProfile> userProfileMap,
Map<Long, BigDecimal> commissionMap) {
Long invitedUserId = invite.getInviteUserId(); // 被邀请人ID
ValidInviteUserCO userCO = new ValidInviteUserCO();
userCO.setInvitedUserId(invitedUserId);
userCO.setInviteType(invite.getInviteType());
userCO.setInviteTime(invite.getCreateTime());
// 设置用户账号
UserProfile userProfile = userProfileMap.get(invitedUserId);
if (userProfile != null) {
userCO.setInvitedUserAccount(userProfile.getAccount());
}
// 计算剩余天数
LocalDateTime inviteTime = invite.getCreateTime().toLocalDateTime();
LocalDateTime expireTime = inviteTime.plusDays(VALID_DAYS);
long remainingDays = ChronoUnit.DAYS.between(LocalDateTime.now(), expireTime);
userCO.setRemainingDays(Math.max(0, (int) remainingDays));
// 设置提供的收益
BigDecimal income = commissionMap.getOrDefault(invitedUserId, BigDecimal.ZERO);
userCO.setProvideIncome(income);
return userCO;
}
}

View File

@ -18,8 +18,12 @@ import com.red.circle.other.app.dto.clientobject.activity.InviteUserCO;
import com.red.circle.other.app.dto.clientobject.activity.InviteUserCommissionDetailsCO;
import com.red.circle.other.app.command.activity.GetMyInviteCodeExe;
import com.red.circle.other.app.command.activity.BindInviteCodeExe;
import com.red.circle.other.app.command.activity.GetIncomeStatisticsExe;
import com.red.circle.other.app.command.activity.GetValidInviteUsersExe;
import com.red.circle.other.app.dto.cmd.activity.BindInviteCodeCmd;
import com.red.circle.other.app.dto.clientobject.activity.InviteCodeCO;
import com.red.circle.other.app.dto.clientobject.activity.InviteIncomeStatisticsCO;
import com.red.circle.other.app.dto.clientobject.activity.ValidInviteUserCO;
import com.red.circle.other.app.dto.cmd.activity.InviteUserActivityLimitCmd;
import java.util.List;
import lombok.RequiredArgsConstructor;
@ -47,6 +51,8 @@ public class InviteUserActivityServiceImpl implements InviteUserActivityService
private final InviteActivityExtractedListCmdExe inviteActivityExtractedListCmdExe;
private final GetMyInviteCodeExe getMyInviteCodeExe;
private final BindInviteCodeExe bindInviteCodeExe;
private final GetIncomeStatisticsExe getIncomeStatisticsExe;
private final GetValidInviteUsersExe getValidInviteUsersExe;
@Override
public InviteUserActivitySummaryCO getSummary(AppExtCommand cmd) {
@ -98,4 +104,14 @@ public class InviteUserActivityServiceImpl implements InviteUserActivityService
public void bindInviteCode(BindInviteCodeCmd cmd) {
bindInviteCodeExe.execute(cmd);
}
@Override
public InviteIncomeStatisticsCO getIncomeStatistics(AppExtCommand cmd) {
return getIncomeStatisticsExe.execute(cmd);
}
@Override
public List<ValidInviteUserCO> getValidInviteUsers(AppExtCommand cmd) {
return getValidInviteUsersExe.execute(cmd);
}
}

View File

@ -0,0 +1,35 @@
package com.red.circle.other.app.dto.clientobject.activity;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 邀请收益统计CO
*
* @author system
* @date 2025-01-22
*/
@Data
@Accessors(chain = true)
public class InviteIncomeStatisticsCO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 总收益
*/
private BigDecimal totalIncome;
/**
* 今日收益
*/
private BigDecimal todayIncome;
/**
* 有效邀请用户数量
*/
private Integer validInviteCount;
}

View File

@ -0,0 +1,51 @@
package com.red.circle.other.app.dto.clientobject.activity;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
/**
* 有效邀请用户CO
*
* @author system
* @date 2025-01-22
*/
@Data
@Accessors(chain = true)
public class ValidInviteUserCO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 被邀请用户ID
*/
private Long invitedUserId;
/**
* 被邀请用户账号
*/
private String invitedUserAccount;
/**
* 邀请类型LOTTERY-抽奖, REGISTER-注册
*/
private String inviteType;
/**
* 剩余天数
*/
private Integer remainingDays;
/**
* 提供的收益
*/
private BigDecimal provideIncome;
/**
* 邀请时间
*/
private Timestamp inviteTime;
}

View File

@ -18,4 +18,10 @@ public class BindInviteCodeCmd extends AppExtCommand {
@NotBlank(message = "邀请码不能为空")
private String inviteCode;
/**
* 邀请类型LOTTERY-抽奖类型, REGISTER-注册类型
*/
@NotBlank(message = "邀请类型不能为空")
private String inviteType;
}

View File

@ -12,6 +12,8 @@ import com.red.circle.other.app.dto.clientobject.activity.InviteUserCommissionDe
import com.red.circle.other.app.dto.cmd.activity.InviteUserActivityLimitCmd;
import com.red.circle.other.app.dto.cmd.activity.BindInviteCodeCmd;
import com.red.circle.other.app.dto.clientobject.activity.InviteCodeCO;
import com.red.circle.other.app.dto.clientobject.activity.InviteIncomeStatisticsCO;
import com.red.circle.other.app.dto.clientobject.activity.ValidInviteUserCO;
import java.util.List;
/**
@ -70,4 +72,14 @@ public interface InviteUserActivityService {
* 绑定邀请码.
*/
void bindInviteCode(BindInviteCodeCmd cmd);
/**
* 邀请收益统计.
*/
InviteIncomeStatisticsCO getIncomeStatistics(AppExtCommand cmd);
/**
* 有效邀请用户列表.
*/
List<ValidInviteUserCO> getValidInviteUsers(AppExtCommand cmd);
}

View File

@ -46,4 +46,10 @@ public class UserInviteUser extends TimestampBaseEntity {
*/
@TableField("invite_user_id")
private Long inviteUserId;
/**
* 邀请类型LOTTERY-抽奖类型, REGISTER-注册类型
*/
@TableField("invite_type")
private String inviteType;
}

View File

@ -0,0 +1,37 @@
package com.red.circle.other.infra.enums.user;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 邀请类型枚举
*
* @author system
* @date 2025-01-22
*/
@Getter
@AllArgsConstructor
public enum InviteTypeEnum {
/**
* 抽奖类型 - 直接算有效邀请
*/
LOTTERY("LOTTERY", "抽奖类型"),
/**
* 注册类型 - 需要充值才算有效邀请
*/
REGISTER("REGISTER", "注册类型");
private final String code;
private final String desc;
public static InviteTypeEnum fromCode(String code) {
for (InviteTypeEnum type : values()) {
if (type.code.equals(code)) {
return type;
}
}
return null;
}
}