Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Tankaikai
2025-03-20 15:03:24 +08:00
4 changed files with 67 additions and 54 deletions

View File

@@ -32,7 +32,7 @@ public class DebounceAspect {
// 用于存储基于方法和入参情况的上次执行时间,结构为:方法签名 -> (入参值 -> 上次执行时间) // 用于存储基于方法和入参情况的上次执行时间,结构为:方法签名 -> (入参值 -> 上次执行时间)
private static final ConcurrentHashMap<String, ConcurrentHashMap<Object, Long>> executionTimeMap = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<String, ConcurrentHashMap<Object, Long>> executionTimeMap = new ConcurrentHashMap<>();
private static final ReentrantLock lock = new ReentrantLock(); private static final ReentrantLock LOCK = new ReentrantLock();
@Around("logPointCut()") @Around("logPointCut()")
public Object aroundDebounce(ProceedingJoinPoint joinPoint) throws Throwable { public Object aroundDebounce(ProceedingJoinPoint joinPoint) throws Throwable {
@@ -95,7 +95,7 @@ public class DebounceAspect {
public void cleanExpiredRecords() { public void cleanExpiredRecords() {
long expirationTime = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(10); long expirationTime = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(10);
lock.lock(); LOCK.lock();
try { try {
for (Entry<String, ConcurrentHashMap<Object, Long>> outerEntry : executionTimeMap.entrySet()) { for (Entry<String, ConcurrentHashMap<Object, Long>> outerEntry : executionTimeMap.entrySet()) {
String methodSignature = outerEntry.getKey(); String methodSignature = outerEntry.getKey();
@@ -112,7 +112,7 @@ public class DebounceAspect {
} }
} }
} finally { } finally {
lock.unlock(); LOCK.unlock();
} }
} }
} }

View File

@@ -10,6 +10,9 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.lang.reflect.Method; import java.lang.reflect.Method;
/**
* @author ww
*/
public class SpelUtil { public class SpelUtil {
/** /**
* 用于SpEL表达式解析. * 用于SpEL表达式解析.

View File

@@ -45,6 +45,11 @@ public class InviteAchievement implements Serializable {
* 达标次数 * 达标次数
*/ */
private Integer count; private Integer count;
/**
* 已领取奖励次数
*/
private Integer giveAwardCount;
/** /**
* 是否首次达标 * 是否首次达标

View File

@@ -46,6 +46,9 @@ import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -85,6 +88,9 @@ public class TempOrdersTask {
private final SysUserMoneyDetailsService sysUserMoneyDetailsService; private final SysUserMoneyDetailsService sysUserMoneyDetailsService;
private final UserInfoService userInfoService; private final UserInfoService userInfoService;
private static final ConcurrentHashMap<String, Lock> idLocks = new ConcurrentHashMap<>();
private Logger logger = LoggerFactory.getLogger(getClass()); private Logger logger = LoggerFactory.getLogger(getClass());
public TempOrdersTask(InviteAchievementService inviteAchievementService, CourseService courseService, SysUserMoneyDetailsService sysUserMoneyDetailsService, UserInfoService userInfoService) { public TempOrdersTask(InviteAchievementService inviteAchievementService, CourseService courseService, SysUserMoneyDetailsService sysUserMoneyDetailsService, UserInfoService userInfoService) {
@@ -168,6 +174,7 @@ public class TempOrdersTask {
UserEntity user = userService.selectUserById(order.getUserId()); UserEntity user = userService.selectUserById(order.getUserId());
UserEntity byUser = userService.queryByInvitationCodeOrUserId(user.getInviterUserId(), user.getInviterCode()); UserEntity byUser = userService.queryByInvitationCodeOrUserId(user.getInviterUserId(), user.getInviterCode());
// UserEntity byUser = userService.queryByInvitationCode(user.getInviterCode()); // UserEntity byUser = userService.queryByInvitationCode(user.getInviterCode());
if (byUser != null) { if (byUser != null) {
ApiAccessLimitUtil.runFunAndCheckKey(() -> { ApiAccessLimitUtil.runFunAndCheckKey(() -> {
@@ -315,7 +322,7 @@ public class TempOrdersTask {
moneyDetailsQuery.eq(UserMoneyDetails::getClassify, 6); moneyDetailsQuery.eq(UserMoneyDetails::getClassify, 6);
moneyDetailsQuery.eq(UserMoneyDetails::getUserId, sourceUser.getUserId()); moneyDetailsQuery.eq(UserMoneyDetails::getUserId, sourceUser.getUserId());
moneyDetailsQuery.eq(UserMoneyDetails::getByUserId, user.getUserId()); moneyDetailsQuery.eq(UserMoneyDetails::getByUserId, user.getUserId());
moneyDetailsQuery.ge(UserMoneyDetails::getCreateTime, beginOfDay); moneyDetailsQuery.eq(UserMoneyDetails::getCreateTime, beginOfDay);
int count = userMoneyDetailsService.count(moneyDetailsQuery); int count = userMoneyDetailsService.count(moneyDetailsQuery);
if (count > 0) { if (count > 0) {
logger.info("用户: {} 今日已领取奖励", user.getUserId()); logger.info("用户: {} 今日已领取奖励", user.getUserId());
@@ -348,68 +355,57 @@ public class TempOrdersTask {
* 计算分享达标奖励 * 计算分享达标奖励
*/ */
private void calcInviteStandardAward(UserEntity sourceUser) { private void calcInviteStandardAward(UserEntity sourceUser) {
Set<Long> byUserIdList = inviteAchievementService.list(new LambdaQueryWrapper<InviteAchievement>().eq(InviteAchievement::getUserId, sourceUser.getUserId()) // 获取该 id 对应的锁,如果不存在则创建一个新的锁
.eq(InviteAchievement::getState, 1).select(InviteAchievement::getTargetUserId)).stream().map(InviteAchievement::getTargetUserId).collect(Collectors.toSet()); Lock lock = idLocks.computeIfAbsent(sourceUser.getUserId().toString(), k -> new ReentrantLock());
int inviteCount;
if (byUserIdList.isEmpty()) { // 尝试获取锁,如果获取失败则表示该 id 正在执行,直接返回
if (!lock.tryLock()) {
logger.error("分享达标奖励正在执行,跳过: {}", sourceUser.getUserId());
return; return;
} }
List<UserInfo> list = userInfoService.list(new LambdaQueryWrapper<UserInfo>().in(UserInfo::getUserId, byUserIdList).isNotNull(UserInfo::getAccountNo).select(UserInfo::getCertNo)); try {
logger.info("邀请用户实名信息: {}", list.stream().map(UserInfo::getCertNo).collect(Collectors.toSet())); Set<Long> byUserIdList = inviteAchievementService.list(new LambdaQueryWrapper<InviteAchievement>().eq(InviteAchievement::getUserId, sourceUser.getUserId())
UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, sourceUser.getUserId()).select(UserInfo::getCertNo)); .eq(InviteAchievement::getState, 1).select(InviteAchievement::getTargetUserId)).stream().map(InviteAchievement::getTargetUserId).collect(Collectors.toSet());
Set<String> collect = userInfoService.list(new LambdaQueryWrapper<UserInfo>().in(UserInfo::getUserId, byUserIdList).isNotNull(UserInfo::getAccountNo).select(UserInfo::getCertNo)) if (byUserIdList.isEmpty()) {
.stream().map(UserInfo::getCertNo).collect(Collectors.toSet()); return;
// 去除与本人身份信息相同的用户
if (!collect.isEmpty() && userInfo != null && StrUtil.isNotBlank(userInfo.getCertNo())) {
collect.remove(userInfo.getCertNo());
}
inviteCount = collect.size();
logger.info("邀请达标人员: {}", inviteCount);
// 查询所有已开启的奖励
List<CompletAward> completAwardList = completAwardService.list(new QueryWrapper<CompletAward>().eq("status", 1));
if (completAwardList.isEmpty()) {
logger.info("未开启分享达标奖励");
return;
}
// 遍历奖励,寻找最低达标人数
int minInviteCount = completAwardList.get(0).getInviteCount();
for (CompletAward completAward : completAwardList) {
if (completAward.getInviteCount() < minInviteCount) {
minInviteCount = completAward.getInviteCount();
} }
} UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, sourceUser.getUserId()).select(UserInfo::getCertNo));
Set<String> collect = userInfoService.list(new LambdaQueryWrapper<UserInfo>().in(UserInfo::getUserId, byUserIdList).isNotNull(UserInfo::getAccountNo).select(UserInfo::getCertNo))
// 如果邀请人数小于最低达标人数,则不发放奖励 .stream().map(UserInfo::getCertNo).collect(Collectors.toSet());
if (inviteCount < minInviteCount) { // 去除与本人身份信息相同的用户
logger.info("邀请人数: {} 小于最低达标人数: {}", inviteCount, minInviteCount); if (!collect.isEmpty() && userInfo != null && StrUtil.isNotBlank(userInfo.getCertNo())) {
return; collect.remove(userInfo.getCertNo());
} }
int inviteCount = collect.size();
// 查询是否开启分享循环奖励
int isLoop = Integer.parseInt(commonRepository.findOne(932).getValue());
// 遍历奖励,发放奖励
for (CompletAward completAward : completAwardList) {
QueryWrapper<UserMoneyDetails> moneyDetailsQuery = new QueryWrapper<>();
moneyDetailsQuery.eq("classify", 6);
moneyDetailsQuery.eq("user_id", sourceUser.getUserId());
moneyDetailsQuery.eq("source_id", completAward.getId());
// 奖励次数
int awardCount = userMoneyDetailsService.count(moneyDetailsQuery);
// 查询所有已开启的奖励
CompletAward completAward = completAwardService.getById(1);
if (completAward == null) {
logger.error("分享达标奖励未配置");
return;
}
// 如果邀请人数小于最低达标人数,则不发放奖励
if (inviteCount < completAward.getInviteCount()) {
return;
}
// 查询是否开启分享循环奖励
int isLoop = Integer.parseInt(commonRepository.findOne(932).getValue());
InviteAchievement inviteAchievement = inviteAchievementService.getByUserId(sourceUser.getUserId());
// 发放奖励
int awardCount = inviteAchievement.getGiveAwardCount();
// 如果未开启循环奖励,并且已经发放过奖励,则跳过 // 如果未开启循环奖励,并且已经发放过奖励,则跳过
if (isLoop != 1 && awardCount > 0) { if (isLoop != 1 && awardCount > 0) {
logger.info("奖励已发放: {}, 用户: {}, 奖励类型: {}", completAward.getId(), sourceUser.getUserId(), completAward.getId()); return;
continue;
} }
// 计算获取奖励次数 // 计算获取奖励次数 邀请达标人员 / 邀请人数
int awardNum = inviteCount / completAward.getInviteCount(); int awardNum = inviteCount / completAward.getInviteCount();
if (isLoop != 1) { if (isLoop != 1) {
awardNum = 1; awardNum = 1;
} }
if (awardNum - awardCount <= 0) {
return;
}
for (int i = 0; i < awardNum - awardCount; i++) { for (int i = 0; i < awardNum - awardCount; i++) {
switch (completAward.getType()) { switch (completAward.getType()) {
case 1: case 1:
@@ -430,6 +426,15 @@ public class TempOrdersTask {
break; break;
} }
} }
// 更新邀请达标奖励次数
inviteAchievementService.update(null, new LambdaUpdateWrapper<InviteAchievement>()
.eq(InviteAchievement::getId, inviteAchievement.getId())
.set(InviteAchievement::getGiveAwardCount, inviteAchievement.getGiveAwardCount() + (awardNum - awardCount)));
} catch (Exception e) {
logger.error("分享达标额外奖励发放失败,用户: {}", sourceUser.getUserId(), e);
} finally {
lock.unlock();
idLocks.remove(sourceUser.getUserId().toString());
} }
} }
} }