diff --git a/dating-agency-mall-constant/src/main/java/com/qniao/dam/domian/aggregate/walletaccount/constant/TradeTypeEnum.java b/dating-agency-mall-constant/src/main/java/com/qniao/dam/domian/aggregate/walletaccount/constant/TradeTypeEnum.java index 7e29301..5bc9202 100644 --- a/dating-agency-mall-constant/src/main/java/com/qniao/dam/domian/aggregate/walletaccount/constant/TradeTypeEnum.java +++ b/dating-agency-mall-constant/src/main/java/com/qniao/dam/domian/aggregate/walletaccount/constant/TradeTypeEnum.java @@ -22,6 +22,8 @@ public enum TradeTypeEnum { PLATFORM_SERVICE_FEE(201, "平台服务费"), + RAFFLE_PRIZE_ACTIVITY_WINNING(202, "抽奖活动奖励"), + WITHDRAW(202, "提现"); @EnumValue diff --git a/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/rpaw/entity/RafflePrizeActivityWinning.java b/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/rpaw/entity/RafflePrizeActivityWinning.java index b986963..fe4aaf0 100644 --- a/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/rpaw/entity/RafflePrizeActivityWinning.java +++ b/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/rpaw/entity/RafflePrizeActivityWinning.java @@ -2,6 +2,8 @@ package com.qniao.dam.domain.aggregate.rpaw.entity; import com.baomidou.mybatisplus.annotation.TableName; import com.qniao.dam.domian.aggregate.rpa.constant.RafflePrizeActivityConditionEnum; +import com.qniao.dam.domian.aggregate.rpc.constant.PrizeCategoryEnum; +import com.qniao.dam.domian.aggregate.rpc.constant.PrizeTypeEnum; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; @@ -31,6 +33,12 @@ public class RafflePrizeActivityWinning extends Entity { @ApiModelProperty("备注") private String remark; + } diff --git a/dating-agency-mall-event/src/main/java/com/qniao/dam/domian/aggregate/rpaw/event/RafflePrizeActivityWinningDrawnEvent.java b/dating-agency-mall-event/src/main/java/com/qniao/dam/domian/aggregate/rpaw/event/RafflePrizeActivityWinningDrawnEvent.java new file mode 100644 index 0000000..29b6f49 --- /dev/null +++ b/dating-agency-mall-event/src/main/java/com/qniao/dam/domian/aggregate/rpaw/event/RafflePrizeActivityWinningDrawnEvent.java @@ -0,0 +1,19 @@ +package com.qniao.dam.domian.aggregate.rpaw.event; + +import com.qniao.domain.BaseDomainEvent; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author Zpj + * @date 2025/1/14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RafflePrizeActivityWinningDrawnEvent extends BaseDomainEvent { + + private Long id; + +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/rpaw/user/RafflePrizeActivityWinningUserCommandController.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/rpaw/user/RafflePrizeActivityWinningUserCommandController.java new file mode 100644 index 0000000..6893723 --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/rpaw/user/RafflePrizeActivityWinningUserCommandController.java @@ -0,0 +1,32 @@ +package com.qniao.dam.api.command.rpaw.user; + +import com.qniao.dam.api.command.rpaw.user.request.UserDrawRafflePrizeActivityWinningDto; +import com.qniao.dam.api.command.rpaw.user.response.UserDrawRafflePrizeActivityWinningVo; +import com.qniao.dam.application.service.rpaw.RafflePrizeActivityWinningApplicationService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * @author Zpj + * @date 2025/1/14 + */ +@Api(tags = "抽奖活动中奖信息") +@RestController +@RequestMapping("user") +public class RafflePrizeActivityWinningUserCommandController { + + @Resource + private RafflePrizeActivityWinningApplicationService rafflePrizeActivityWinningApplicationService; + + @ApiOperation("用户抽奖") + @PostMapping("draw/raffle-prize-activity-winning") + public UserDrawRafflePrizeActivityWinningVo userDrawRafflePrizeActivityWinning(@RequestBody @Valid UserDrawRafflePrizeActivityWinningDto dto, + @RequestParam("userId") Long userId) { + return rafflePrizeActivityWinningApplicationService.draw(dto.getRafflePrizeActivityWinningId()); + } + +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/rpaw/user/request/UserDrawRafflePrizeActivityWinningDto.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/rpaw/user/request/UserDrawRafflePrizeActivityWinningDto.java new file mode 100644 index 0000000..7e894d6 --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/rpaw/user/request/UserDrawRafflePrizeActivityWinningDto.java @@ -0,0 +1,16 @@ +package com.qniao.dam.api.command.rpaw.user.request; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author Zpj + * @date 2025/1/14 + */ +@Data +public class UserDrawRafflePrizeActivityWinningDto { + + @ApiModelProperty("抽奖标识") + private Long rafflePrizeActivityWinningId; + +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/rpaw/user/response/UserDrawRafflePrizeActivityWinningVo.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/rpaw/user/response/UserDrawRafflePrizeActivityWinningVo.java new file mode 100644 index 0000000..2372c1a --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/rpaw/user/response/UserDrawRafflePrizeActivityWinningVo.java @@ -0,0 +1,28 @@ +package com.qniao.dam.api.command.rpaw.user.response; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author Zpj + * @date 2025/1/14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserDrawRafflePrizeActivityWinningVo { + + @ApiModelProperty("中奖的抽奖活动项标识") + @JsonSerialize(using = ToStringSerializer.class) + private Long rafflePrizeActivityItemId; + + @ApiModelProperty("中奖产品") + private String rafflePrizeConfigName; + + @ApiModelProperty("奖励值") + private String rewardValue; +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/handler/rpaw/RafflePrizeActivityWinningEventHandler.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/handler/rpaw/RafflePrizeActivityWinningEventHandler.java new file mode 100644 index 0000000..4a0c553 --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/handler/rpaw/RafflePrizeActivityWinningEventHandler.java @@ -0,0 +1,77 @@ +package com.qniao.dam.application.handler.rpaw; + +import cn.hutool.core.collection.CollUtil; +import com.google.common.eventbus.Subscribe; +import com.qniao.dam.domain.aggregate.order.entity.Order; +import com.qniao.dam.domain.aggregate.revenuereward.entity.RevenueReward; +import com.qniao.dam.domain.aggregate.revenuereward.valueobj.RevenueRewardAssociateOrderRecord; +import com.qniao.dam.domain.aggregate.revenuereward.valueobj.RevenueRewardRecord; +import com.qniao.dam.domain.aggregate.rpaw.entity.RafflePrizeActivityWinning; +import com.qniao.dam.domain.aggregate.walletaccount.entity.WalletAccount; +import com.qniao.dam.domain.aggregate.walletaccount.valueobj.WalletAccountRecord; +import com.qniao.dam.domain.service.revenuereward.AcquireRevenueRewardDomainService; +import com.qniao.dam.domian.aggregate.rpaw.event.RafflePrizeActivityWinningDrawnEvent; +import com.qniao.dam.domian.aggregate.rpc.constant.PrizeCategoryEnum; +import com.qniao.dam.domian.aggregate.walletaccount.constant.IdentityTypeEnum; +import com.qniao.dam.domian.aggregate.walletaccount.constant.TradeTypeEnum; +import com.qniao.dam.infrastructure.persistent.dao.rpaw.RafflePrizeActivityWinningDao; +import com.qniao.dam.query.revenuereward.RevenueRewardQueryService; +import com.qniao.dam.query.walletaccount.WalletAccountQueryService; +import com.qniao.domain.BaseApplicationService; +import com.qniao.framework.exception.BizException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Zpj + * @date 2025/1/14 + */ +@Service +@Slf4j +public class RafflePrizeActivityWinningEventHandler extends BaseApplicationService { + + @Resource + private RafflePrizeActivityWinningDao rafflePrizeActivityWinningDao; + @Resource + private WalletAccountQueryService walletAccountQueryService; + @Resource + private RevenueRewardQueryService revenueRewardQueryService; + @Resource + private AcquireRevenueRewardDomainService acquireRevenueRewardDomainService; + + @Subscribe + private void handle(RafflePrizeActivityWinningDrawnEvent event) { + try { + RafflePrizeActivityWinning winning = rafflePrizeActivityWinningDao.selectById(event.getId()); + //todo 暂时只有金额 + if (PrizeCategoryEnum.MATCHMAKER_STAY_FRANCHISE_FEE.equals(winning.getPrizeCategory())) { + BigDecimal earnings = new BigDecimal(winning.getRewardValue()); + + //收益信息 + RevenueReward revenueReward = revenueRewardQueryService.queryByType(winning.getUserId(), IdentityTypeEnum.INDIVIDUAL); + + RevenueRewardRecord revenueRewardRecord = RevenueRewardRecord.build(TradeTypeEnum.RAFFLE_PRIZE_ACTIVITY_WINNING, earnings, BigDecimal.ZERO, + BigDecimal.ZERO, earnings, earnings); + revenueRewardRecord.setContent("抽奖活动奖励"); + revenueReward.setRecordList(Collections.singletonList(revenueRewardRecord)); + + //钱包 + WalletAccount walletAccount = walletAccountQueryService.queryByType(winning.getUserId(), IdentityTypeEnum.INDIVIDUAL); + BigDecimal originalBalance = walletAccount.getTotalBalance(); + walletAccount.setAvailableBalance(walletAccount.getAvailableBalance().add(earnings)); + walletAccount.setTotalBalance(walletAccount.getAvailableBalance().add(walletAccount.getFrozenBalance())); + WalletAccountRecord record = WalletAccountRecord.build(TradeTypeEnum.RAFFLE_PRIZE_ACTIVITY_WINNING, earnings, true, originalBalance, walletAccount.getTotalBalance()); + walletAccount.setRecordList(Collections.singletonList(record)); + acquireRevenueRewardDomainService.handle(revenueReward, walletAccount); + } + } catch (Exception e) { + log.error("抽奖事件处理异常", e); + } + } +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/rpa/RafflePrizeActivityApplicationService.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/rpa/RafflePrizeActivityApplicationService.java index 7000fff..a0b2259 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/rpa/RafflePrizeActivityApplicationService.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/rpa/RafflePrizeActivityApplicationService.java @@ -2,11 +2,16 @@ package com.qniao.dam.application.service.rpa; import com.qniao.dam.domain.aggregate.rpa.RafflePrizeActivityAggregate; import com.qniao.dam.domain.aggregate.rpa.entity.RafflePrizeActivity; +import com.qniao.dam.domain.aggregate.rpa.entity.RafflePrizeActivityItem; +import com.qniao.dam.domain.aggregate.rpa.repository.RafflePrizeActivityRepository; import com.qniao.dam.infrastructure.persistent.dao.rpa.RafflePrizeActivityDao; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.Objects; +import java.util.Random; @Service public class RafflePrizeActivityApplicationService { @@ -15,6 +20,8 @@ public class RafflePrizeActivityApplicationService { private RafflePrizeActivityAggregate rafflePrizeActivityAggregate; @Resource private RafflePrizeActivityDao rafflePrizeActivityDao; + @Resource + private RafflePrizeActivityRepository rafflePrizeActivityRepository; public void create(RafflePrizeActivity rafflePrizeActivity) { rafflePrizeActivity.setEnable(false); @@ -36,4 +43,27 @@ public class RafflePrizeActivityApplicationService { rafflePrizeActivityAggregate.edit(rafflePrizeActivity); } } + + public RafflePrizeActivityItem draw(Long id) { + RafflePrizeActivity rafflePrizeActivity = rafflePrizeActivityRepository.load(id); + int num = rafflePrizeActivity.getItemList().stream() + .map(RafflePrizeActivityItem::getWinningRate).reduce(BigDecimal.ZERO, BigDecimal::add) + .multiply(BigDecimal.valueOf(100)) + .setScale(0, RoundingMode.HALF_UP).intValue(); + Random random = new Random(); + BigDecimal randomWinningRate = BigDecimal.valueOf(random.nextInt(num)).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); + RafflePrizeActivityItem matchItem = null; + BigDecimal totalWinningRate = BigDecimal.ZERO; + for (RafflePrizeActivityItem item : rafflePrizeActivity.getItemList()) { + totalWinningRate = totalWinningRate.add(item.getWinningRate()); + if (totalWinningRate.compareTo(randomWinningRate) >= 0) { + matchItem = item; + break; + } + } + if (Objects.isNull(matchItem)) { + matchItem = rafflePrizeActivity.getItemList().get(0); + } + return matchItem; + } } \ No newline at end of file diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/rpaw/RafflePrizeActivityWinningApplicationService.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/rpaw/RafflePrizeActivityWinningApplicationService.java index e8f7fa5..f66736b 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/rpaw/RafflePrizeActivityWinningApplicationService.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/rpaw/RafflePrizeActivityWinningApplicationService.java @@ -1,26 +1,63 @@ package com.qniao.dam.application.service.rpaw; +import com.qniao.dam.api.command.rpaw.user.response.UserDrawRafflePrizeActivityWinningVo; +import com.qniao.dam.application.service.rpa.RafflePrizeActivityApplicationService; +import com.qniao.dam.domain.aggregate.rpa.entity.RafflePrizeActivity; +import com.qniao.dam.domain.aggregate.rpa.entity.RafflePrizeActivityItem; +import com.qniao.dam.domain.aggregate.rpa.repository.RafflePrizeActivityRepository; import com.qniao.dam.domain.aggregate.rpaw.RafflePrizeActivityWinningAggregate; import com.qniao.dam.domain.aggregate.rpaw.entity.RafflePrizeActivityWinning; +import com.qniao.dam.domain.aggregate.rpc.entity.RafflePrizeConfig; +import com.qniao.dam.infrastructure.persistent.dao.rpaw.RafflePrizeActivityWinningDao; +import com.qniao.dam.infrastructure.persistent.dao.rpc.RafflePrizeConfigDao; +import com.qniao.domain.BaseApplicationService; +import com.qniao.domain.BaseDomainEvent; +import com.qniao.framework.exception.BizException; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.util.Objects; @Service -public class RafflePrizeActivityWinningApplicationService { +public class RafflePrizeActivityWinningApplicationService extends BaseApplicationService { @Resource private RafflePrizeActivityWinningAggregate rafflePrizeActivityWinningAggregate; + @Resource + private RafflePrizeActivityWinningDao rafflePrizeActivityWinningDao; + @Resource + private RafflePrizeActivityApplicationService rafflePrizeActivityApplicationService; + @Resource + private RafflePrizeConfigDao rafflePrizeConfigDao; - public void create(RafflePrizeActivityWinning rafflePrizeActivityWinning) { - rafflePrizeActivityWinningAggregate.create(rafflePrizeActivityWinning); - } - - public void edit(RafflePrizeActivityWinning rafflePrizeActivityWinning) { - rafflePrizeActivityWinningAggregate.edit(rafflePrizeActivityWinning); - } - - public void delete(Long id) { - rafflePrizeActivityWinningAggregate.delete(id); + public UserDrawRafflePrizeActivityWinningVo draw(Long id) { + UserDrawRafflePrizeActivityWinningVo vo = null; + RafflePrizeActivityWinning winning = rafflePrizeActivityWinningDao.selectById(id); + if (Objects.nonNull(winning)) { + if (winning.getIsDraw()) { + //已经抽奖 + throw new BizException("您已经使用了本次抽奖机会"); + } else { + //执行抽奖 + RafflePrizeActivityItem rafflePrizeActivityItem = rafflePrizeActivityApplicationService.draw(winning.getRafflePrizeActivityId()); + RafflePrizeConfig rafflePrizeConfig = rafflePrizeConfigDao.selectById(rafflePrizeActivityItem.getRafflePrizeConfigId()); + winning.setPrizeType(rafflePrizeConfig.getPrizeType()); + winning.setPrizeCategory(rafflePrizeConfig.getPrizeCategory()); + winning.setRafflePrizeConfigName(rafflePrizeConfig.getPrizeName()); + winning.setIsDraw(true); + winning.setDrawTime(LocalDateTime.now()); + //todo + BigDecimal reward = rafflePrizeConfig.getPrizePct().multiply(new BigDecimal(winning.getMaxReward())) + .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); + winning.setRewardValue(reward.stripTrailingZeros().toPlainString()); + BaseDomainEvent event = rafflePrizeActivityWinningAggregate.draw(winning); + this.sendEvent(event); + vo = new UserDrawRafflePrizeActivityWinningVo(rafflePrizeActivityItem.getId(), winning.getRafflePrizeConfigName(), winning.getRewardValue()); + } + } + return vo; } } \ No newline at end of file diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/rpaw/RafflePrizeActivityWinningAggregate.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/rpaw/RafflePrizeActivityWinningAggregate.java index 5ea1700..26157e4 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/rpaw/RafflePrizeActivityWinningAggregate.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/rpaw/RafflePrizeActivityWinningAggregate.java @@ -2,6 +2,8 @@ package com.qniao.dam.domain.aggregate.rpaw; import com.qniao.dam.domain.aggregate.rpaw.entity.RafflePrizeActivityWinning; import com.qniao.dam.domain.aggregate.rpaw.repository.RafflePrizeActivityWinningRepository; +import com.qniao.dam.domian.aggregate.rpaw.event.RafflePrizeActivityWinningDrawnEvent; +import com.qniao.domain.BaseDomainEvent; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -28,4 +30,9 @@ public class RafflePrizeActivityWinningAggregate { public void delete(Long id) { repository.delete(id); } + + public BaseDomainEvent draw(RafflePrizeActivityWinning entity) { + repository.save(entity); + return new RafflePrizeActivityWinningDrawnEvent(entity.getId()); + } }