diff --git a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/family/FamilyRestController.java b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/family/FamilyRestController.java index 4afb73e5..51fd0958 100644 --- a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/family/FamilyRestController.java +++ b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/family/FamilyRestController.java @@ -237,19 +237,6 @@ public class FamilyRestController extends BaseController { return familyService.memberUserInfo(cmd); } - /** - * 家族每日任务. - * - * @eo.name 家族每日任务. - * @eo.url /trigger-daily-task - * @eo.method get - * @eo.request-type formdata - */ -// @GetMapping("/trigger-daily-task") - public void triggerDailyTask(FamilyDailyTaskCmd cmd) { - familyService.triggerDailyTask(cmd); - } - /** * 创建家族规则条件. * diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyDailyTaskExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyDailyTaskExe.java index c21971f7..78ec6eb0 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyDailyTaskExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyDailyTaskExe.java @@ -61,8 +61,8 @@ public class FamilyDailyTaskExe { private void addExpAndTaskRecord(FamilyDailyTaskEnum taskEnum, FamilyMemberInfo member, FamilyDailyTaskCmd cmd) { - familyCommon.familyBusinessProcessing(member.getMemberUserId(), member.getSysOrigin(), - taskEnum.getExp()); +// familyCommon.familyBusinessProcessing(member.getMemberUserId(), member.getSysOrigin(), +// taskEnum.getExp()); addFamilyDailyTaskRecord(cmd, member); } diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/gift/strategy/GiftCountStrategy.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/gift/strategy/GiftCountStrategy.java index 638b5c17..b76dba29 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/gift/strategy/GiftCountStrategy.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/gift/strategy/GiftCountStrategy.java @@ -204,7 +204,7 @@ public class GiftCountStrategy implements GiftStrategy { // 家族 -// processFamily(runningWater, isLuckyGift, luckyGiftRatio); + processFamily(runningWater, isLuckyGift, luckyGiftRatio); giftGiveRunningWaterService.addLog(runningWater.getId(), "结束:礼物统计相关"); } @@ -617,12 +617,9 @@ public class GiftCountStrategy implements GiftStrategy { private void processFamily(GiftGiveRunningWater runningWater, boolean isLuckyGift, BigDecimal luckyGiftRatio) { + Long actualAmount = getActualAmount(isLuckyGift, runningWater.getGiftValue().getActualAmount(), luckyGiftRatio); - familyCommon.familyBusinessProcessing(runningWater.getUserId() - , runningWater.getSysOrigin() - , getActualAmount(isLuckyGift - , runningWater.getGiftValue().getActualAmount() - , luckyGiftRatio)); + familyCommon.addFamilyExpAndLevelUp(runningWater.getUserId(), runningWater.getSysOrigin(), actualAmount); } private boolean checkWeekStar(GiftValue giftValue) { diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/common/family/FamilyCommon.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/common/family/FamilyCommon.java index 38392e60..77453929 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/common/family/FamilyCommon.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/common/family/FamilyCommon.java @@ -130,89 +130,126 @@ public class FamilyCommon { } /** - * 处理家族业务 + * 增加家族经验值并处理升级 * * @param userId 用户userId - * @param sysOrigin 系统 - * @param giftExp 礼物总价值 + * @param sysOrigin 系统平台 + * @param exp 经验值 */ - public void familyBusinessProcessing(Long userId, String sysOrigin, Long giftExp) { - try { - if (!isExistFamilyByUserId(userId)) { + public void addFamilyExpAndLevelUp(Long userId, String sysOrigin, Long exp) { + FamilyMemberInfo member = getFamilyMember(userId); + if (Objects.isNull(member)) { + return; + } + + String lockKey = "family:level:lock:" + member.getFamilyId(); + int maxRetry = 5; + int retryCount = 0; + + while (retryCount < maxRetry) { + try { + boolean locked = redisService.setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS); + if (locked) { + try { + processExpAndLevelUpWithLock(member, sysOrigin, exp); + return; + } finally { + redisService.delete(lockKey); + } + } + + retryCount++; + if (retryCount < maxRetry) { + Thread.sleep(100 * retryCount); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.error("获取家族升级锁被中断,FamilyId:{}", member.getFamilyId()); + return; + } catch (Exception ex) { + log.error("FamilyCommon.addFamilyExpAndLevelUp.userId:{},{}", userId, Throwables.getStackTraceAsString(ex)); return; } + } + + log.error("获取家族升级锁失败,重试{}次后放弃,FamilyId:{},userId:{},exp:{}", maxRetry, member.getFamilyId(), userId, exp); + } + + /** + * 在分布式锁保护下处理经验值和升级 + */ + private void processExpAndLevelUpWithLock(FamilyMemberInfo member, String sysOrigin, Long exp) { + FamilyBaseInfo familyBaseInfo = familyBaseInfoService.getById(member.getFamilyId()); + if (Objects.isNull(familyBaseInfo)) { + return; + } - FamilyMemberInfo member = getFamilyMember(userId); - if (Objects.isNull(member)) { - return; - } - FamilyBaseInfo familyBaseInfo = familyBaseInfoService.getById(member.getFamilyId()); - if (Objects.isNull(familyBaseInfo)) { - return; + String regionId = userRegionGateway.getRegionId(familyBaseInfo.getCreateUser()); + if (StringUtils.isBlank(regionId)) { + return; + } + + FamilyDetailsDTO currentLevel = getFamilyDetails(sysOrigin, member.getFamilyId()); + if (StringUtils.isBlank(sysOrigin) || Objects.isNull(currentLevel) || StringUtils.isBlank(currentLevel.getLevelKey())) { + log.error("增加家族经验失败,FamilyId:{}", member.getFamilyId()); + return; + } + + processExpAndLevelUp(member, currentLevel, exp, sysOrigin, regionId); + } + + /** + * 处理经验值增加和升级逻辑 + */ + private void processExpAndLevelUp(FamilyMemberInfo member, FamilyDetailsDTO currentLevel, + Long exp, String sysOrigin, String regionId) { + + long remainingExp = exp; + FamilyDetailsDTO levelInfo = currentLevel; + + while (remainingExp > 0) { + FamilyLevelConfig nextLevel = getNewLevel(sysOrigin, levelInfo); + + if (Objects.isNull(nextLevel)) { + addExpWithoutLevelUp(member, levelInfo, remainingExp, regionId); + break; } - String regionId = userRegionGateway.getRegionId(familyBaseInfo.getCreateUser()); - if (StringUtils.isBlank(regionId)) { - return; + long currentLevelCompleteExp = levelInfo.getLevelExp(); + long currentFamilyExp = familyLevelExpService.getExp(levelInfo.getFamilyId(), levelInfo.getFamilyLevelId()).longValue(); + long expNeeded = currentLevelCompleteExp - currentFamilyExp; + + if (remainingExp < expNeeded) { + addExpWithoutLevelUp(member, levelInfo, remainingExp, regionId); + break; } - FamilyDetailsDTO oldLevel = getFamilyDetails(sysOrigin, member.getFamilyId()); - if (StringUtils.isBlank(sysOrigin) || Objects.isNull(oldLevel) || StringUtils - .isBlank(oldLevel.getLevelKey())) { - log.error("家族升级失败,FamilyId:{}", member.getFamilyId()); - return; - } - FamilyLevelConfig newLevel = getNewLevel(sysOrigin, oldLevel); - - if (Objects.isNull(newLevel)) { - //已经是最高等级,无法再升级了 - grandTotalExp(giftExp, member, oldLevel, regionId); - return; - } - - long currentLevelCompleteExp = oldLevel.getLevelExp(); - long currentFamilyExp = familyLevelExpService.getExp(oldLevel.getFamilyId(), - oldLevel.getFamilyLevelId()).longValue(); - - if (ltLevelUpExp(giftExp, currentLevelCompleteExp, currentFamilyExp)) { - grandTotalExp(giftExp, member, oldLevel, regionId); - return; - } - - if (isPreciseLevelUp(giftExp, currentLevelCompleteExp, currentFamilyExp)) { - familyLevelUp(member, newLevel, giftExp, regionId); - return; - } - - long lackExp = getLackExp(currentLevelCompleteExp, currentFamilyExp); - familyLevelUp(member, newLevel, lackExp, regionId); - - // 升级后还剩余经验,则将剩余经验值继续升级 - familyBusinessProcessing(member.getMemberUserId(), sysOrigin, giftExp - lackExp); - - } catch (Exception ex) { - log.error("FamilyManager.familyBusinessProcessing.userId:{},{}", userId, - Throwables.getStackTraceAsString(ex)); + performLevelUp(member, nextLevel, expNeeded, regionId); + remainingExp -= expNeeded; + + levelInfo = getFamilyDetails(sysOrigin, member.getFamilyId()); } } /** - * 升级家族 - * - * @param member 成员 - * @param newLevel 新等级 - * @param lackExp 缺少的经验值 + * 增加经验值但不升级 */ - private void familyLevelUp(FamilyMemberInfo member, FamilyLevelConfig newLevel, Long lackExp, - String regionId) { - - addFamilyExpIncreaseRecord(lackExp, member, newLevel.getId()); - - expAccumulate(member, lackExp, regionId); + private void addExpWithoutLevelUp(FamilyMemberInfo member, FamilyDetailsDTO currentLevel, Long exp, String regionId) { + addFamilyExpIncreaseRecord(exp, member, currentLevel.getFamilyLevelId()); + expAccumulate(member, exp, regionId); + } + /** + * 执行升级操作 + */ + private void performLevelUp(FamilyMemberInfo member, FamilyLevelConfig newLevel, Long exp, String regionId) { + addFamilyExpIncreaseRecord(exp, member, newLevel.getId()); + expAccumulate(member, exp, regionId); updateFamily(member, newLevel); } + + /** * 更新家族 * @@ -224,14 +261,8 @@ public class FamilyCommon { // 家族升级 familyLevelUp(member, newLevel); - // 移除全部家族旧荣誉饰品 - removeFamilyAllProps(member.getFamilyId(), newLevel); - - // 发送给全部家族用户新荣誉饰品 - sendFamilyProps(member.getFamilyId(), newLevel); - // 更新家族等级缓存数据 - cacheFamilyLevel(member.getSysOrigin() + member.getFamilyId(), newLevel, member.getFamilyId()); +// cacheFamilyLevel(member.getSysOrigin() + member.getFamilyId(), newLevel, member.getFamilyId()); } /** @@ -390,13 +421,10 @@ public class FamilyCommon { * @param exp 经验值 */ private void expAccumulate(FamilyMemberInfo member, Long exp, String regionId) { + familyWeekExpService.incrThisWeekExp(member.getSysOrigin(), member.getFamilyId(), regionId, exp); + familyMemberWeekExpService.incrExp(member.getSysOrigin(), member.getFamilyId(),member.getMemberUserId(), exp); - familyWeekExpService.incrThisWeekExp(member.getSysOrigin(), member.getFamilyId(), regionId, - exp); - familyMonthExpService.incrThisMonthExp(member.getSysOrigin(), member.getFamilyId(), regionId, - exp); - familyMemberWeekExpService.incrExp(member.getSysOrigin(), member.getFamilyId(), - member.getMemberUserId(), exp); +// familyMonthExpService.incrThisMonthExp(member.getSysOrigin(), member.getFamilyId(), regionId, exp); } /** @@ -495,8 +523,6 @@ public class FamilyCommon { .setFamilyId(familyId); fillFamilyDetails(levelConfig, levelCacheCO); - - familyLevelCacheService.setFamilyLevelData(key, levelCacheCO); } /** @@ -626,27 +652,9 @@ public class FamilyCommon { return Objects.equals(memberRole, FamilyRoleEnum.MEMBER.name()); } - /** - * 升级缺少的经验值 - * - * @param currentLevelCompleteExp 当前等级完整经验值 - * @param currentFamilyExp 家族现有经验值 - * @return 升级所需经验值 - */ - private long getLackExp(long currentLevelCompleteExp, long currentFamilyExp) { - if (currentFamilyExp == 0) { - return currentLevelCompleteExp; - } - return currentLevelCompleteExp - currentFamilyExp; - } - /** - * 不多不少精准经验值升级 - */ - private boolean isPreciseLevelUp(long giftExp, long currentLevelCompleteExp, - long currentFamilyExp) { - return giftExp + currentFamilyExp - currentLevelCompleteExp == 0; - } + + private PropsSourceRecord getPropsSourceById(Long id) { if (Objects.isNull(id)) { @@ -655,11 +663,7 @@ public class FamilyCommon { return propsSourceRecordService.getById(id); } - private void grandTotalExp(Long giftExp, FamilyMemberInfo member, - FamilyDetailsDTO oldLevel, String regionId) { - addFamilyExpIncreaseRecord(giftExp, member, oldLevel.getFamilyLevelId()); - expAccumulate(member, giftExp, regionId); - } + private BadgePictureConfig getByBadgeId(String sysOrigin, Long badgeId) { if (Objects.isNull(badgeId) || StringUtils.isBlank(sysOrigin)) { @@ -691,10 +695,6 @@ public class FamilyCommon { ); } - private boolean ltLevelUpExp(long giftExp, long currentLevelCompleteExp, long currentFamilyExp) { - return giftExp + currentFamilyExp < currentLevelCompleteExp; - } - public void deleteFamilyAwardByUserId(Long userId) { List levelConfigs = getFamilyLevelConfigs(); diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyLevelExpServiceImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyLevelExpServiceImpl.java index b7b9bdf3..0862d77e 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyLevelExpServiceImpl.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyLevelExpServiceImpl.java @@ -67,23 +67,28 @@ public class FamilyLevelExpServiceImpl extends if (Objects.isNull(familyId) || Objects.isNull(familyLevelId)) { return; } - FamilyLevelExp balance = query().select(FamilyLevelExp::getId) + + boolean updated = update() + .setSql("exp=exp+" + exp) .eq(FamilyLevelExp::getFamilyId, familyId) .eq(FamilyLevelExp::getFamilyLevelId, familyLevelId) - .last(PageConstant.LIMIT_ONE) - .getOne(); - if (Objects.isNull(balance) || Objects.isNull(balance.getId())) { - save(new FamilyLevelExp() - .setFamilyId(familyId) - .setFamilyLevelId(familyLevelId) - .setExp(exp) - ); - return; - } - update() - .setSql("exp=exp+" + exp) - .eq(FamilyLevelExp::getId, balance.getId()) .execute(); + + if (updated) { + try { + save(new FamilyLevelExp() + .setFamilyId(familyId) + .setFamilyLevelId(familyLevelId) + .setExp(exp) + ); + } catch (Exception e) { + update() + .setSql("exp=exp+" + exp) + .eq(FamilyLevelExp::getFamilyId, familyId) + .eq(FamilyLevelExp::getFamilyLevelId, familyLevelId) + .execute(); + } + } } @Override diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyWeekExpServiceImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyWeekExpServiceImpl.java index 9555862f..17e67e4b 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyWeekExpServiceImpl.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyWeekExpServiceImpl.java @@ -7,6 +7,7 @@ import com.red.circle.other.infra.database.rds.entity.family.FamilyWeekExp; import com.red.circle.other.infra.database.rds.service.family.FamilyWeekExpService; import com.red.circle.tool.core.collection.CollectionUtils; import com.red.circle.tool.core.date.LocalDateUtils; +import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils; import com.red.circle.tool.core.text.StringUtils; import java.util.List; import java.util.Objects; @@ -33,7 +34,7 @@ public class FamilyWeekExpServiceImpl extends return; } - Integer dateSplit = LocalDateUtils.nowWeekMondayToInteger(); + Integer dateSplit = ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt(); FamilyWeekExp familyWeekExp = query() .select(FamilyWeekExp::getId)