家族经验值增加逻辑重写

This commit is contained in:
tianfeng 2025-12-25 12:10:48 +08:00
parent 45dd82a866
commit a4b8da5a8f
6 changed files with 134 additions and 144 deletions

View File

@ -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);
}
/**
* 创建家族规则条件.
*

View File

@ -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);
}

View File

@ -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) {

View File

@ -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<FamilyLevelConfig> levelConfigs = getFamilyLevelConfigs();

View File

@ -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

View File

@ -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)