diff --git a/rc-service/rc-inner-api/wallet-inner/wallet-inner-model/src/main/java/com/red/circle/wallet/inner/model/enums/GoldOrigin.java b/rc-service/rc-inner-api/wallet-inner/wallet-inner-model/src/main/java/com/red/circle/wallet/inner/model/enums/GoldOrigin.java index 40392335..c95291ec 100644 --- a/rc-service/rc-inner-api/wallet-inner/wallet-inner-model/src/main/java/com/red/circle/wallet/inner/model/enums/GoldOrigin.java +++ b/rc-service/rc-inner-api/wallet-inner/wallet-inner-model/src/main/java/com/red/circle/wallet/inner/model/enums/GoldOrigin.java @@ -722,6 +722,16 @@ public enum GoldOrigin { * 房间红包 */ ROOM_RED_PACKET("Room red packet"), + + /** + * 家族宝箱贡献 + */ + FAMILY_BOX_CONTRIBUTE("Family box contribute"), + + /** + * 家族宝箱奖励 + */ + FAMILY_BOX_REWARD("Family box reward"), ; private final String desc; 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 f7c1b179..1b9ee400 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 @@ -9,6 +9,7 @@ import com.red.circle.other.app.dto.clientobject.family.FamilyCreateRulesCO; import com.red.circle.other.app.dto.clientobject.family.FamilyLeaderboardCO; import com.red.circle.other.app.dto.clientobject.family.FamilyLevelParentCacheCO; import com.red.circle.other.app.dto.clientobject.family.FamilyListCO; +import com.red.circle.other.app.dto.clientobject.family.FamilyBoxStatusCO; import com.red.circle.other.app.dto.clientobject.family.FamilyMemberCO; import com.red.circle.other.app.dto.clientobject.family.FamilyMsgListCO; import com.red.circle.other.app.dto.clientobject.family.MyFamilyApplyCO; @@ -18,6 +19,7 @@ import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO; import com.red.circle.other.app.dto.cmd.family.ApplyJoinFamilyCmd; import com.red.circle.other.app.dto.cmd.family.CancelFamilyApplyCmd; import com.red.circle.other.app.dto.cmd.family.ReapplyFamilyCmd; +import com.red.circle.other.app.dto.cmd.family.FamilyBoxClaimCmd; import com.red.circle.other.app.dto.cmd.family.FamilyAdminQueryCmd; import com.red.circle.other.app.dto.cmd.family.FamilyBaseInfoQueryCmd; import com.red.circle.other.app.dto.cmd.family.FamilyCreateCmd; @@ -228,6 +230,30 @@ public class FamilyRestController extends BaseController { familyService.userExit(cmd); } + /** + * 投入宝箱金币. + */ + @PostMapping("/box/contribute") + public void boxContribute(@RequestBody AppExtCommand cmd) { + familyService.boxContribute(cmd); + } + + /** + * 查询宝箱状态. + */ + @GetMapping("/box/status") + public FamilyBoxStatusCO boxStatus(AppExtCommand cmd) { + return familyService.boxStatus(cmd); + } + + /** + * 领取宝箱奖励. + */ + @PostMapping("/box/claim") + public void boxClaim(@RequestBody @Validated FamilyBoxClaimCmd cmd) { + familyService.boxClaim(cmd); + } + /** * 成员在家族中的基本信息. * diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyBoxClaimExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyBoxClaimExe.java new file mode 100644 index 00000000..cfe85bee --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyBoxClaimExe.java @@ -0,0 +1,87 @@ +package com.red.circle.other.app.command.family; + +import com.red.circle.common.business.core.enums.SysOriginPlatformEnum; +import com.red.circle.framework.core.asserts.ResponseAssert; +import com.red.circle.framework.core.response.CommonErrorCode; +import com.red.circle.other.app.dto.cmd.family.FamilyBoxClaimCmd; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxDaily; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxUserReward; +import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo; +import com.red.circle.other.infra.database.rds.service.family.FamilyBoxDailyService; +import com.red.circle.other.infra.database.rds.service.family.FamilyBoxUserContributeService; +import com.red.circle.other.infra.database.rds.service.family.FamilyBoxUserRewardService; +import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService; +import com.red.circle.other.infra.enums.family.FamilyBoxConfigEnum; +import com.red.circle.other.inner.asserts.FamilyErrorCode; +import com.red.circle.tool.core.tuple.PennyAmount; +import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient; +import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd; +import com.red.circle.wallet.inner.model.enums.GoldOrigin; +import java.time.LocalDate; +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * 领取宝箱奖励. + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class FamilyBoxClaimExe { + + private final FamilyMemberInfoService familyMemberInfoService; + private final FamilyBoxDailyService familyBoxDailyService; + private final FamilyBoxUserContributeService familyBoxUserContributeService; + private final FamilyBoxUserRewardService familyBoxUserRewardService; + private final WalletGoldClient walletGoldClient; + + @Transactional(rollbackFor = Exception.class) + public void execute(FamilyBoxClaimCmd cmd) { + + FamilyBoxConfigEnum config = FamilyBoxConfigEnum.getByLevel(cmd.getLevel()); + ResponseAssert.notNull(CommonErrorCode.DATA_ERROR, config); + + FamilyMemberInfo memberInfo = familyMemberInfoService.getFamilyMemberByUserId(cmd.getReqUserId()); + ResponseAssert.notNull(FamilyErrorCode.NOT_EXIST_FAMILY_INFO_DATA, memberInfo); + + LocalDate today = LocalDate.now(); + + ResponseAssert.isTrue(FamilyErrorCode.NOT_EXIST_FAMILY_INFO_DATA, + familyBoxUserContributeService.hasContributed(memberInfo.getFamilyId(), cmd.getReqUserId(), today)); + + FamilyBoxDaily dailyRecord = familyBoxDailyService.getByFamilyAndDate(memberInfo.getFamilyId(), today); + Integer contributeCount = Objects.nonNull(dailyRecord) ? dailyRecord.getContributeCount() : 0; + + ResponseAssert.isTrue(CommonErrorCode.DATA_ERROR, contributeCount >= config.getRequiredCount()); + + ResponseAssert.isFalse(FamilyErrorCode.REPEAT_APPLICATION, + familyBoxUserRewardService.hasClaimed(memberInfo.getFamilyId(), cmd.getReqUserId(), today, cmd.getLevel())); + + String recordId = memberInfo.getFamilyId() + "_" + cmd.getReqUserId() + "_" + today + "_" + cmd.getLevel(); + addUserGold(cmd.getReqUserId(), cmd.getReqSysOrigin().getOrigin(), config.getRewardGold(), recordId); + + familyBoxUserRewardService.save(new FamilyBoxUserReward() + .setFamilyId(memberInfo.getFamilyId()) + .setUserId(cmd.getReqUserId()) + .setBoxDate(today) + .setLevel(cmd.getLevel()) + .setRewardGold(config.getRewardGold()) + .setSysOrigin(cmd.getReqSysOrigin().getOrigin())); + } + + private void addUserGold(Long userId, String sysOrigin, Integer amount, String recordId) { + GoldReceiptCmd build = GoldReceiptCmd.builder() + .appIncome() + .userId(userId) + .amount(PennyAmount.ofDollar(amount.longValue())) + .eventId(recordId) + .sysOrigin(SysOriginPlatformEnum.valueOf(sysOrigin)) + .origin(GoldOrigin.FAMILY_BOX_REWARD) + .build(); + + walletGoldClient.changeBalance(build); + } +} diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyBoxContributeExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyBoxContributeExe.java new file mode 100644 index 00000000..21046187 --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyBoxContributeExe.java @@ -0,0 +1,75 @@ +package com.red.circle.other.app.command.family; + +import com.red.circle.common.business.core.enums.SysOriginPlatformEnum; +import com.red.circle.common.business.dto.cmd.AppExtCommand; +import com.red.circle.framework.core.asserts.ResponseAssert; +import com.red.circle.other.infra.common.family.FamilyCommon; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxUserContribute; +import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo; +import com.red.circle.other.infra.database.rds.service.family.FamilyBoxDailyService; +import com.red.circle.other.infra.database.rds.service.family.FamilyBoxUserContributeService; +import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService; +import com.red.circle.other.infra.enums.family.FamilyBoxConfigEnum; +import com.red.circle.other.inner.asserts.FamilyErrorCode; +import com.red.circle.tool.core.tuple.PennyAmount; +import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient; +import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd; +import com.red.circle.wallet.inner.model.enums.GoldOrigin; +import java.time.LocalDate; +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * 投入宝箱金币. + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class FamilyBoxContributeExe { + + private final FamilyCommon familyCommon; + private final FamilyMemberInfoService familyMemberInfoService; + private final FamilyBoxDailyService familyBoxDailyService; + private final FamilyBoxUserContributeService familyBoxUserContributeService; + private final WalletGoldClient walletGoldClient; + + @Transactional(rollbackFor = Exception.class) + public void execute(AppExtCommand cmd) { + + FamilyMemberInfo memberInfo = familyMemberInfoService.getFamilyMemberByUserId(cmd.getReqUserId()); + ResponseAssert.notNull(FamilyErrorCode.NOT_EXIST_FAMILY_INFO_DATA, memberInfo); + + LocalDate today = LocalDate.now(); + + ResponseAssert.isFalse(FamilyErrorCode.REPEAT_APPLICATION, + familyBoxUserContributeService.hasContributed(memberInfo.getFamilyId(), cmd.getReqUserId(), today)); + + String recordId = memberInfo.getFamilyId() + "_" + cmd.getReqUserId() + "_" + today; + consumeGold(cmd.getReqUserId(), cmd.getReqSysOrigin().getOrigin(), recordId); + + familyBoxUserContributeService.save(new FamilyBoxUserContribute() + .setFamilyId(memberInfo.getFamilyId()) + .setUserId(cmd.getReqUserId()) + .setBoxDate(today) + .setGoldAmount(FamilyBoxConfigEnum.CONTRIBUTE_GOLD) + .setSysOrigin(cmd.getReqSysOrigin().getOrigin())); + + familyBoxDailyService.incrementContributeCount( + memberInfo.getFamilyId(), today, cmd.getReqSysOrigin().getOrigin()); + } + + private void consumeGold(Long userId, String sysOrigin, String recordId) { + GoldReceiptCmd build = GoldReceiptCmd.builder() + .appExpenditure() + .userId(userId) + .amount(PennyAmount.ofDollar(FamilyBoxConfigEnum.CONTRIBUTE_GOLD.longValue())) + .eventId(recordId) + .sysOrigin(SysOriginPlatformEnum.valueOf(sysOrigin)) + .origin(GoldOrigin.FAMILY_BOX_CONTRIBUTE) + .build(); + walletGoldClient.changeBalance(build); + } +} diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyBoxStatusExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyBoxStatusExe.java new file mode 100644 index 00000000..a7274dc6 --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyBoxStatusExe.java @@ -0,0 +1,72 @@ +package com.red.circle.other.app.command.family; + +import com.google.common.collect.Lists; +import com.red.circle.common.business.dto.cmd.AppExtCommand; +import com.red.circle.framework.core.asserts.ResponseAssert; +import com.red.circle.other.app.dto.clientobject.family.FamilyBoxChestCO; +import com.red.circle.other.app.dto.clientobject.family.FamilyBoxStatusCO; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxDaily; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxUserReward; +import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo; +import com.red.circle.other.infra.database.rds.service.family.FamilyBoxDailyService; +import com.red.circle.other.infra.database.rds.service.family.FamilyBoxUserContributeService; +import com.red.circle.other.infra.database.rds.service.family.FamilyBoxUserRewardService; +import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService; +import com.red.circle.other.infra.enums.family.FamilyBoxConfigEnum; +import com.red.circle.other.inner.asserts.FamilyErrorCode; +import java.time.LocalDate; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +/** + * 查询宝箱状态. + */ +@Component +@RequiredArgsConstructor +public class FamilyBoxStatusExe { + + private final FamilyMemberInfoService familyMemberInfoService; + private final FamilyBoxDailyService familyBoxDailyService; + private final FamilyBoxUserContributeService familyBoxUserContributeService; + private final FamilyBoxUserRewardService familyBoxUserRewardService; + + public FamilyBoxStatusCO execute(AppExtCommand cmd) { + + FamilyMemberInfo memberInfo = familyMemberInfoService.getFamilyMemberByUserId(cmd.getReqUserId()); + ResponseAssert.notNull(FamilyErrorCode.NOT_EXIST_FAMILY_INFO_DATA, memberInfo); + + LocalDate today = LocalDate.now(); + + FamilyBoxDaily dailyRecord = familyBoxDailyService.getByFamilyAndDate(memberInfo.getFamilyId(), today); + Integer contributeCount = Objects.nonNull(dailyRecord) ? dailyRecord.getContributeCount() : 0; + + Boolean userContributed = familyBoxUserContributeService.hasContributed( + memberInfo.getFamilyId(), cmd.getReqUserId(), today); + + List claimedList = familyBoxUserRewardService.listByUserAndDate( + memberInfo.getFamilyId(), cmd.getReqUserId(), today); + + Set claimedLevels = claimedList.stream() + .map(FamilyBoxUserReward::getLevel) + .collect(Collectors.toSet()); + + List chests = Lists.newArrayList(); + for (FamilyBoxConfigEnum config : FamilyBoxConfigEnum.values()) { + chests.add(new FamilyBoxChestCO() + .setLevel(config.getLevel()) + .setRequiredCount(config.getRequiredCount()) + .setRewardGold(config.getRewardGold()) + .setUnlocked(contributeCount >= config.getRequiredCount()) + .setClaimed(claimedLevels.contains(config.getLevel()))); + } + + return new FamilyBoxStatusCO() + .setContributeCount(contributeCount) + .setUserContributed(userContributed) + .setChests(chests); + } +} diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/family/FamilyServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/family/FamilyServiceImpl.java index e6b75848..d2cae0b9 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/family/FamilyServiceImpl.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/family/FamilyServiceImpl.java @@ -29,11 +29,15 @@ import com.red.circle.other.app.command.family.MyFamilyApplyListExe; import com.red.circle.other.app.command.family.CancelFamilyApplyExe; import com.red.circle.other.app.command.family.ReapplyFamilyExe; import com.red.circle.other.app.command.family.FamilyListExe; +import com.red.circle.other.app.command.family.FamilyBoxContributeExe; +import com.red.circle.other.app.command.family.FamilyBoxStatusExe; +import com.red.circle.other.app.command.family.FamilyBoxClaimExe; import com.red.circle.other.app.dto.clientobject.family.FamilyBaseInfoCO; import com.red.circle.other.app.dto.clientobject.family.FamilyCreateRulesCO; import com.red.circle.other.app.dto.clientobject.family.FamilyLeaderboardCO; import com.red.circle.other.app.dto.clientobject.family.FamilyLevelParentCacheCO; import com.red.circle.other.app.dto.clientobject.family.FamilyListCO; +import com.red.circle.other.app.dto.clientobject.family.FamilyBoxStatusCO; import com.red.circle.other.app.dto.clientobject.family.FamilyMemberCO; import com.red.circle.other.app.dto.clientobject.family.FamilyMsgListCO; import com.red.circle.other.app.dto.clientobject.family.MyFamilyApplyCO; @@ -43,6 +47,7 @@ import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO; import com.red.circle.other.app.dto.cmd.family.ApplyJoinFamilyCmd; import com.red.circle.other.app.dto.cmd.family.CancelFamilyApplyCmd; import com.red.circle.other.app.dto.cmd.family.ReapplyFamilyCmd; +import com.red.circle.other.app.dto.cmd.family.FamilyBoxClaimCmd; import com.red.circle.other.app.dto.cmd.family.FamilyAdminQueryCmd; import com.red.circle.other.app.dto.cmd.family.FamilyBaseInfoQueryCmd; import com.red.circle.other.app.dto.cmd.family.FamilyCreateCmd; @@ -110,6 +115,9 @@ public class FamilyServiceImpl implements FamilyService { private final CancelFamilyApplyExe cancelFamilyApplyExe; private final ReapplyFamilyExe reapplyFamilyExe; private final FamilyListExe familyListExe; + private final FamilyBoxContributeExe familyBoxContributeExe; + private final FamilyBoxStatusExe familyBoxStatusExe; + private final FamilyBoxClaimExe familyBoxClaimExe; private final DistributedLockUtil distributedLockUtil; @Override @@ -269,4 +277,24 @@ public class FamilyServiceImpl implements FamilyService { return familyListExe.execute(cmd); } + @Override + public void boxContribute(AppExtCommand cmd) { + String key = "FAMILY_BOX_CONTRIBUTE" + ":" + cmd.getReqUserId(); + distributedLockUtil.executeWithLock(key, () -> { + familyBoxContributeExe.execute(cmd); + }); + } + + @Override + public FamilyBoxStatusCO boxStatus(AppExtCommand cmd) { + return familyBoxStatusExe.execute(cmd); + } + + @Override + public void boxClaim(FamilyBoxClaimCmd cmd) { + String key = "FAMILY_BOX_CLAIM" + ":" + cmd.getReqUserId(); + distributedLockUtil.executeWithLock(key, () -> { + familyBoxClaimExe.execute(cmd); + }); + } } diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/family/FamilyBoxChestCO.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/family/FamilyBoxChestCO.java new file mode 100644 index 00000000..3adb96f5 --- /dev/null +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/family/FamilyBoxChestCO.java @@ -0,0 +1,37 @@ +package com.red.circle.other.app.dto.clientobject.family; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 宝箱信息. + */ +@Data +@Accessors(chain = true) +public class FamilyBoxChestCO { + + /** + * 宝箱等级(1/2/3). + */ + private Integer level; + + /** + * 需要投入人数. + */ + private Integer requiredCount; + + /** + * 奖励金币数. + */ + private Integer rewardGold; + + /** + * 是否已解锁. + */ + private Boolean unlocked; + + /** + * 当前用户是否已领取. + */ + private Boolean claimed; +} diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/family/FamilyBoxStatusCO.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/family/FamilyBoxStatusCO.java new file mode 100644 index 00000000..48b65c8f --- /dev/null +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/family/FamilyBoxStatusCO.java @@ -0,0 +1,28 @@ +package com.red.circle.other.app.dto.clientobject.family; + +import lombok.Data; +import lombok.experimental.Accessors; +import java.util.List; + +/** + * 宝箱状态信息. + */ +@Data +@Accessors(chain = true) +public class FamilyBoxStatusCO { + + /** + * 当日投入人数. + */ + private Integer contributeCount; + + /** + * 当前用户是否已投入. + */ + private Boolean userContributed; + + /** + * 宝箱列表. + */ + private List chests; +} diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/cmd/family/FamilyBoxClaimCmd.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/cmd/family/FamilyBoxClaimCmd.java new file mode 100644 index 00000000..23c8b00e --- /dev/null +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/cmd/family/FamilyBoxClaimCmd.java @@ -0,0 +1,20 @@ +package com.red.circle.other.app.dto.cmd.family; + +import com.red.circle.common.business.dto.cmd.AppExtCommand; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 领取宝箱奖励. + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class FamilyBoxClaimCmd extends AppExtCommand { + + /** + * 宝箱等级(1/2/3). + */ + @NotNull(message = "宝箱等级不能为空") + private Integer level; +} diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/family/FamilyService.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/family/FamilyService.java index 47de1d65..9d0b4d7a 100644 --- a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/family/FamilyService.java +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/family/FamilyService.java @@ -155,4 +155,19 @@ public interface FamilyService { * 家族列表. */ PageResult familyList(FamilyListCmd cmd); + + /** + * 投入家族宝箱金币. + */ + void boxContribute(AppExtCommand cmd); + + /** + * 查询家族宝箱状态. + */ + FamilyBoxStatusCO boxStatus(AppExtCommand cmd); + + /** + * 领取家族宝箱奖励. + */ + void boxClaim(FamilyBoxClaimCmd cmd); } diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/dao/family/FamilyBoxDailyDAO.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/dao/family/FamilyBoxDailyDAO.java new file mode 100644 index 00000000..119ccbfb --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/dao/family/FamilyBoxDailyDAO.java @@ -0,0 +1,12 @@ +package com.red.circle.other.infra.database.rds.dao.family; + +import com.red.circle.framework.mybatis.dao.BaseDAO; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxDaily; +import org.apache.ibatis.annotations.Mapper; + +/** + * 家族宝箱每日记录 Mapper. + */ +public interface FamilyBoxDailyDAO extends BaseDAO { + +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/dao/family/FamilyBoxUserContributeDAO.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/dao/family/FamilyBoxUserContributeDAO.java new file mode 100644 index 00000000..f0d0b9bc --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/dao/family/FamilyBoxUserContributeDAO.java @@ -0,0 +1,12 @@ +package com.red.circle.other.infra.database.rds.dao.family; + +import com.red.circle.framework.mybatis.dao.BaseDAO; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxUserContribute; +import org.apache.ibatis.annotations.Mapper; + +/** + * 用户宝箱投入记录 Mapper. + */ +public interface FamilyBoxUserContributeDAO extends BaseDAO { + +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/dao/family/FamilyBoxUserRewardDAO.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/dao/family/FamilyBoxUserRewardDAO.java new file mode 100644 index 00000000..5fcaa977 --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/dao/family/FamilyBoxUserRewardDAO.java @@ -0,0 +1,12 @@ +package com.red.circle.other.infra.database.rds.dao.family; + +import com.red.circle.framework.mybatis.dao.BaseDAO; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxUserReward; +import org.apache.ibatis.annotations.Mapper; + +/** + * 用户宝箱领取记录 Mapper. + */ +public interface FamilyBoxUserRewardDAO extends BaseDAO { + +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/family/FamilyBoxDaily.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/family/FamilyBoxDaily.java new file mode 100644 index 00000000..37ab7215 --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/family/FamilyBoxDaily.java @@ -0,0 +1,53 @@ +package com.red.circle.other.infra.database.rds.entity.family; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.red.circle.framework.mybatis.entity.TimestampBaseEntity; +import java.time.LocalDate; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 家族宝箱每日记录表. + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("family_box_daily") +public class FamilyBoxDaily extends TimestampBaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 主键标识. + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 来源系统. + */ + @TableField("sys_origin") + private String sysOrigin; + + /** + * 家族ID. + */ + @TableField("family_id") + private Long familyId; + + /** + * 宝箱日期. + */ + @TableField("box_date") + private LocalDate boxDate; + + /** + * 当日投入人数. + */ + @TableField("contribute_count") + private Integer contributeCount; +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/family/FamilyBoxUserContribute.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/family/FamilyBoxUserContribute.java new file mode 100644 index 00000000..bca6a21f --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/family/FamilyBoxUserContribute.java @@ -0,0 +1,59 @@ +package com.red.circle.other.infra.database.rds.entity.family; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.red.circle.framework.mybatis.entity.TimestampBaseEntity; +import java.time.LocalDate; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 用户宝箱投入记录表. + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("family_box_user_contribute") +public class FamilyBoxUserContribute extends TimestampBaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 主键标识. + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 来源系统. + */ + @TableField("sys_origin") + private String sysOrigin; + + /** + * 家族ID. + */ + @TableField("family_id") + private Long familyId; + + /** + * 用户ID. + */ + @TableField("user_id") + private Long userId; + + /** + * 投入日期. + */ + @TableField("box_date") + private LocalDate boxDate; + + /** + * 投入金币数. + */ + @TableField("gold_amount") + private Integer goldAmount; +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/family/FamilyBoxUserReward.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/family/FamilyBoxUserReward.java new file mode 100644 index 00000000..a7c32485 --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/family/FamilyBoxUserReward.java @@ -0,0 +1,65 @@ +package com.red.circle.other.infra.database.rds.entity.family; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.red.circle.framework.mybatis.entity.TimestampBaseEntity; +import java.time.LocalDate; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 用户宝箱领取记录表. + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("family_box_user_reward") +public class FamilyBoxUserReward extends TimestampBaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 主键标识. + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 来源系统. + */ + @TableField("sys_origin") + private String sysOrigin; + + /** + * 家族ID. + */ + @TableField("family_id") + private Long familyId; + + /** + * 用户ID. + */ + @TableField("user_id") + private Long userId; + + /** + * 领取日期. + */ + @TableField("box_date") + private LocalDate boxDate; + + /** + * 宝箱等级(1/2/3). + */ + @TableField("level") + private Integer level; + + /** + * 奖励金币数. + */ + @TableField("reward_gold") + private Integer rewardGold; +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/FamilyBoxDailyService.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/FamilyBoxDailyService.java new file mode 100644 index 00000000..032a9a4e --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/FamilyBoxDailyService.java @@ -0,0 +1,15 @@ +package com.red.circle.other.infra.database.rds.service.family; + +import com.red.circle.framework.mybatis.service.BaseService; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxDaily; +import java.time.LocalDate; + +/** + * 家族宝箱每日记录 服务类. + */ +public interface FamilyBoxDailyService extends BaseService { + + FamilyBoxDaily getByFamilyAndDate(Long familyId, LocalDate boxDate); + + void incrementContributeCount(Long familyId, LocalDate boxDate, String sysOrigin); +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/FamilyBoxUserContributeService.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/FamilyBoxUserContributeService.java new file mode 100644 index 00000000..56537067 --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/FamilyBoxUserContributeService.java @@ -0,0 +1,13 @@ +package com.red.circle.other.infra.database.rds.service.family; + +import com.red.circle.framework.mybatis.service.BaseService; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxUserContribute; +import java.time.LocalDate; + +/** + * 用户宝箱投入记录 服务类. + */ +public interface FamilyBoxUserContributeService extends BaseService { + + Boolean hasContributed(Long familyId, Long userId, LocalDate boxDate); +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/FamilyBoxUserRewardService.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/FamilyBoxUserRewardService.java new file mode 100644 index 00000000..a7ce26e6 --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/FamilyBoxUserRewardService.java @@ -0,0 +1,16 @@ +package com.red.circle.other.infra.database.rds.service.family; + +import com.red.circle.framework.mybatis.service.BaseService; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxUserReward; +import java.time.LocalDate; +import java.util.List; + +/** + * 用户宝箱领取记录 服务类. + */ +public interface FamilyBoxUserRewardService extends BaseService { + + Boolean hasClaimed(Long familyId, Long userId, LocalDate boxDate, Integer level); + + List listByUserAndDate(Long familyId, Long userId, LocalDate boxDate); +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyBoxDailyServiceImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyBoxDailyServiceImpl.java new file mode 100644 index 00000000..5641f17d --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyBoxDailyServiceImpl.java @@ -0,0 +1,45 @@ +package com.red.circle.other.infra.database.rds.service.family.impl; + +import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl; +import com.red.circle.other.infra.database.rds.dao.family.FamilyBoxDailyDAO; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxDaily; +import com.red.circle.other.infra.database.rds.service.family.FamilyBoxDailyService; +import java.time.LocalDate; +import java.util.Objects; +import org.springframework.stereotype.Service; + +/** + * 家族宝箱每日记录 服务实现类. + */ +@Service +public class FamilyBoxDailyServiceImpl extends BaseServiceImpl + implements FamilyBoxDailyService { + + @Override + public FamilyBoxDaily getByFamilyAndDate(Long familyId, LocalDate boxDate) { + return query() + .eq(FamilyBoxDaily::getFamilyId, familyId) + .eq(FamilyBoxDaily::getBoxDate, boxDate) + .getOne(); + } + + @Override + public void incrementContributeCount(Long familyId, LocalDate boxDate, String sysOrigin) { + FamilyBoxDaily record = getByFamilyAndDate(familyId, boxDate); + + if (Objects.isNull(record)) { + record = new FamilyBoxDaily() + .setFamilyId(familyId) + .setBoxDate(boxDate) + .setSysOrigin(sysOrigin) + .setContributeCount(1); + save(record); + } else { + update() + .setSql("contribute_count = contribute_count + 1") + .eq(FamilyBoxDaily::getFamilyId, familyId) + .eq(FamilyBoxDaily::getBoxDate, boxDate) + .execute(); + } + } +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyBoxUserContributeServiceImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyBoxUserContributeServiceImpl.java new file mode 100644 index 00000000..9a2777f0 --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyBoxUserContributeServiceImpl.java @@ -0,0 +1,27 @@ +package com.red.circle.other.infra.database.rds.service.family.impl; + +import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl; +import com.red.circle.other.infra.database.rds.dao.family.FamilyBoxUserContributeDAO; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxUserContribute; +import com.red.circle.other.infra.database.rds.service.family.FamilyBoxUserContributeService; +import java.time.LocalDate; +import java.util.Objects; +import org.springframework.stereotype.Service; + +/** + * 用户宝箱投入记录 服务实现类. + */ +@Service +public class FamilyBoxUserContributeServiceImpl extends + BaseServiceImpl + implements FamilyBoxUserContributeService { + + @Override + public Boolean hasContributed(Long familyId, Long userId, LocalDate boxDate) { + return Objects.nonNull(query() + .eq(FamilyBoxUserContribute::getFamilyId, familyId) + .eq(FamilyBoxUserContribute::getUserId, userId) + .eq(FamilyBoxUserContribute::getBoxDate, boxDate) + .getOne()); + } +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyBoxUserRewardServiceImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyBoxUserRewardServiceImpl.java new file mode 100644 index 00000000..b82a1c85 --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/family/impl/FamilyBoxUserRewardServiceImpl.java @@ -0,0 +1,39 @@ +package com.red.circle.other.infra.database.rds.service.family.impl; + +import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl; +import com.red.circle.other.infra.database.rds.dao.family.FamilyBoxUserRewardDAO; +import com.red.circle.other.infra.database.rds.entity.family.FamilyBoxUserReward; +import com.red.circle.other.infra.database.rds.service.family.FamilyBoxUserRewardService; +import com.red.circle.tool.core.collection.CollectionUtils; +import java.time.LocalDate; +import java.util.List; +import java.util.Objects; +import org.springframework.stereotype.Service; + +/** + * 用户宝箱领取记录 服务实现类. + */ +@Service +public class FamilyBoxUserRewardServiceImpl extends + BaseServiceImpl + implements FamilyBoxUserRewardService { + + @Override + public Boolean hasClaimed(Long familyId, Long userId, LocalDate boxDate, Integer level) { + return Objects.nonNull(query() + .eq(FamilyBoxUserReward::getFamilyId, familyId) + .eq(FamilyBoxUserReward::getUserId, userId) + .eq(FamilyBoxUserReward::getBoxDate, boxDate) + .eq(FamilyBoxUserReward::getLevel, level) + .getOne()); + } + + @Override + public List listByUserAndDate(Long familyId, Long userId, LocalDate boxDate) { + return query() + .eq(FamilyBoxUserReward::getFamilyId, familyId) + .eq(FamilyBoxUserReward::getUserId, userId) + .eq(FamilyBoxUserReward::getBoxDate, boxDate) + .list(); + } +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/enums/family/FamilyBoxConfigEnum.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/enums/family/FamilyBoxConfigEnum.java new file mode 100644 index 00000000..b2c0f380 --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/enums/family/FamilyBoxConfigEnum.java @@ -0,0 +1,55 @@ +package com.red.circle.other.infra.enums.family; + +import lombok.Getter; + +/** + * 家族宝箱配置枚举. + */ +@Getter +public enum FamilyBoxConfigEnum { + + LEVEL_1(1, 5, 50, "宝箱1"), + LEVEL_2(2, 10, 50, "宝箱2"), + LEVEL_3(3, 20, 100, "宝箱3"); + + /** + * 等级. + */ + private final Integer level; + + /** + * 需要投入人数. + */ + private final Integer requiredCount; + + /** + * 奖励金币数. + */ + private final Integer rewardGold; + + /** + * 描述. + */ + private final String description; + + FamilyBoxConfigEnum(Integer level, Integer requiredCount, Integer rewardGold, String description) { + this.level = level; + this.requiredCount = requiredCount; + this.rewardGold = rewardGold; + this.description = description; + } + + public static FamilyBoxConfigEnum getByLevel(Integer level) { + for (FamilyBoxConfigEnum config : values()) { + if (config.level.equals(level)) { + return config; + } + } + return null; + } + + /** + * 投入金币固定数量. + */ + public static final Integer CONTRIBUTE_GOLD = 50; +}