From 7f74b75456d77d26e85d117f5ae0564c2d8e05fc Mon Sep 17 00:00:00 2001 From: hokli <2629910752@qq.com> Date: Fri, 16 May 2025 18:57:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=B8=B8=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 金豆,任务 taskConstant --- .../accompany/common/status/BusiStatus.java | 8 ++ .../com/accompany/common/redis/RedisKey.java | 1 + .../constant/dailytask/DailyTaskConstant.java | 48 +++++++ .../constant/dailytask/DailyTaskTypeEnum.java | 34 +++++ .../constant/dailytask/GoldBeanBillType.java | 29 ++++ .../business/model/UserGoldBean.java | 34 +++++ .../business/model/UserGoldBeanBill.java | 50 +++++++ .../accompany/business/vo/DailyTaskVo.java | 29 ++++ .../vo/dailytask/DailyProgressContext.java | 25 ++++ .../vo/dailytask/DailyTaskContext.java | 17 +++ .../listener/CommonRecharge4ActListener.java | 12 ++ .../mybatismapper/UserGoldBeanBillMapper.java | 14 ++ .../mybatismapper/UserGoldBeanMapper.java | 20 +++ .../dailytask/AbstractDailyTaskHandler.java | 133 ++++++++++++++++++ .../service/dailytask/DailyTaskHandler.java | 23 +++ .../dailytask/DailyTaskHandlerRegistry.java | 28 ++++ .../service/dailytask/DailyTaskService.java | 92 ++++++++++++ .../annotation/DailyTaskHandlerType.java | 14 ++ .../handler/ChargeGoldNumHandler.java | 67 +++++++++ .../dailytask/handler/DailySignHandler.java | 38 +++++ .../dailytask/handler/PlayGameHandler.java | 58 ++++++++ .../handler/RecvLuckyGiftHandler.java | 51 +++++++ .../handler/RecvNomalGiftGoldHandler.java | 57 ++++++++ .../handler/RecvNomalGiftHandler.java | 52 +++++++ .../handler/RoomSendGiftHandler.java | 46 ++++++ .../dailytask/handler/UpMicHandler.java | 25 ++++ .../listener/DailyTaskGiftListener.java | 48 +++++++ .../usergoldbean/UserGoldBeanBillService.java | 20 +++ .../usergoldbean/UserGoldBeanService.java | 24 ++++ .../impl/UserGoldBeanBillServiceImpl.java | 42 ++++++ .../impl/UserGoldBeanServiceImpl.java | 132 +++++++++++++++++ .../sqlmappers/UserGoldBeanBillMapper.xml | 5 + .../sqlmappers/UserGoldBeanMapper.xml | 12 ++ .../dailytask/DailyTaskController.java | 39 +++++ .../consumer/GameMsgPushMessageConsumer.java | 15 +- 35 files changed, 1341 insertions(+), 1 deletion(-) create mode 100644 accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/DailyTaskConstant.java create mode 100644 accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/DailyTaskTypeEnum.java create mode 100644 accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/GoldBeanBillType.java create mode 100644 accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/model/UserGoldBean.java create mode 100644 accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/model/UserGoldBeanBill.java create mode 100644 accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/DailyTaskVo.java create mode 100644 accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/dailytask/DailyProgressContext.java create mode 100644 accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/dailytask/DailyTaskContext.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/mybatismapper/UserGoldBeanBillMapper.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/mybatismapper/UserGoldBeanMapper.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/AbstractDailyTaskHandler.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskHandler.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskHandlerRegistry.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskService.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/annotation/DailyTaskHandlerType.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/ChargeGoldNumHandler.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/DailySignHandler.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/PlayGameHandler.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvLuckyGiftHandler.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvNomalGiftGoldHandler.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvNomalGiftHandler.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RoomSendGiftHandler.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/UpMicHandler.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/listener/DailyTaskGiftListener.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/UserGoldBeanBillService.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/UserGoldBeanService.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/impl/UserGoldBeanBillServiceImpl.java create mode 100644 accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/impl/UserGoldBeanServiceImpl.java create mode 100644 accompany-business/accompany-business-service/src/main/resources/accompany/sqlmappers/UserGoldBeanBillMapper.xml create mode 100644 accompany-business/accompany-business-service/src/main/resources/accompany/sqlmappers/UserGoldBeanMapper.xml create mode 100644 accompany-business/accompany-business-web/src/main/java/com/accompany/business/controller/activity/dailytask/DailyTaskController.java diff --git a/accompany-base/accompany-common/src/main/java/com/accompany/common/status/BusiStatus.java b/accompany-base/accompany-common/src/main/java/com/accompany/common/status/BusiStatus.java index 6fe183f0d..6176eb1ed 100644 --- a/accompany-base/accompany-common/src/main/java/com/accompany/common/status/BusiStatus.java +++ b/accompany-base/accompany-common/src/main/java/com/accompany/common/status/BusiStatus.java @@ -949,6 +949,14 @@ public enum BusiStatus { USER_EVENT_BEGIN_SELECT(20513, "超过可选时间范围"), USER_EVENT_EXIST(20513, "该房间已经申请[时间范围]举办活动了"), USER_EVENT_GOLD_CONFIG_ERROR(20513, "GOLD_CONFIG_ERROR"), + + DAILY_RECEIVE_EXPIRE(20514, "领取失效,请刷新页面"), + + DAILY_RECEIVE_EXIST(20514, "已经领取过了"), + + DAILY_TASK_UNCOMPLETED(20514, "任务未完成,请刷新重试3"), + + DAILY_GOLDBEANNOTENOUGH(20514, "金豆餘額不足,请完成任务获取"), ; private final int value; diff --git a/accompany-base/accompany-core/src/main/java/com/accompany/common/redis/RedisKey.java b/accompany-base/accompany-core/src/main/java/com/accompany/common/redis/RedisKey.java index e9fae2b56..85599da05 100644 --- a/accompany-base/accompany-core/src/main/java/com/accompany/common/redis/RedisKey.java +++ b/accompany-base/accompany-core/src/main/java/com/accompany/common/redis/RedisKey.java @@ -1460,6 +1460,7 @@ public enum RedisKey { //小游戏token joy_token, + ; public String getKey() { diff --git a/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/DailyTaskConstant.java b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/DailyTaskConstant.java new file mode 100644 index 000000000..e88bca6ae --- /dev/null +++ b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/DailyTaskConstant.java @@ -0,0 +1,48 @@ +package com.accompany.business.constant.dailytask; + +import com.accompany.common.redis.BaseRedisKey; + +public interface DailyTaskConstant { + + enum ReceiveStatus { + UNCOMPLETED, + AVAILABLE, + RECEIVED, + } + + enum RedisKey implements BaseRedisKey { + task_receive_status,//日常任务领取状态 + task_status,// 日常任务完成状态 + lock_user_gold_bean, // 用户金豆分布式锁 + charge_gold,//日充值金币 + play_game,//游戏种类 + recv_gold_num,//收礼金币 + ; + + @Override + public String getKey() { + return "Daily:" + name(); + } + } + + + enum SignRedisKey implements BaseRedisKey { + sign_award_list, //签到奖励key + sign_index_seven_today_status, + sign_index_seven_sign_lock, + sign_christmas_sign_lock, + sign_index_seven_times, + sign_index_seven_repeat_device, + sign_device_limit, + sign_christmas_repeat_device, + sign_index_seven_repeat_ip, + sign_ip_limit, + + ; + + @Override + public String getKey() { + return "Sign:" + name(); + } + } +} diff --git a/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/DailyTaskTypeEnum.java b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/DailyTaskTypeEnum.java new file mode 100644 index 000000000..311d091bb --- /dev/null +++ b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/DailyTaskTypeEnum.java @@ -0,0 +1,34 @@ +package com.accompany.business.constant.dailytask; + +public enum DailyTaskTypeEnum { + + DAILY_SIGN(1, 100), ////每日签到 + UP_MIC(60, 1500),//"上麦聊天", + UP_MIC_120(120, 5000),//上麦聊天(0/120Mins) + PLAY_GAME(3, 6000),//参与小游戏(0/3) + CHARGE_GOLD_NUM(7000, 5000),//充值7000 + CHARGE_GOLD_NUM_5(35000, 30000),//充值35000 + CHARGE_GOLD_NUM_10(70000, 70000),//充值70000 + ROOM_SEND_GIFT(1, 8000),//房间送礼 + RECV_LUCKY_GIFT(1, 100),//收到Lucky/Bravo礼物 + RECV_NOMAL_GIFT(1, 4000),//收到普通礼物 + RECV_NOMAL_GIFT_GOLD(20000, 8000),//收到礼物(价值超过2w金币) + ; + + private final int reachNum;//达标数量 + private final int reachGoldBean;//奖励金豆数 + + DailyTaskTypeEnum(int reachNum, int reachGoldBean) { + this.reachNum = reachNum; + this.reachGoldBean = reachGoldBean; + } + + public int getReachNum() { + return reachNum; + } + + public int getReachGoldBean() { + return reachGoldBean; + } + +} diff --git a/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/GoldBeanBillType.java b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/GoldBeanBillType.java new file mode 100644 index 000000000..167dc5cee --- /dev/null +++ b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/constant/dailytask/GoldBeanBillType.java @@ -0,0 +1,29 @@ +package com.accompany.business.constant.dailytask; + +public enum GoldBeanBillType { + TASK_GAIN(1, "任务获取", (byte)1), + MALL_PAY(2, "商城购买", (byte)1), + ; + + private final int type; + private final String desc; + private final byte billType;//账单类型1-支出, 2-收入 + + GoldBeanBillType(int type, String desc, byte billType) { + this.type = type; + this.desc = desc; + this.billType = billType; + } + + public int getType() { + return type; + } + + public String getDesc() { + return desc; + } + + public byte getBillType() { + return billType; + } +} diff --git a/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/model/UserGoldBean.java b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/model/UserGoldBean.java new file mode 100644 index 000000000..54dbcc07d --- /dev/null +++ b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/model/UserGoldBean.java @@ -0,0 +1,34 @@ +package com.accompany.business.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 用户金豆表实体类 + * + * @author + * @since 2025-05-19 + */ +@Data +public class UserGoldBean implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 用户uid + */ + @TableId(value = "uid", type = IdType.NONE) + private Long uid; + /** + * 总金豆数量 + */ + private BigDecimal goldBean; + private Date updateTime; + + +} diff --git a/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/model/UserGoldBeanBill.java b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/model/UserGoldBeanBill.java new file mode 100644 index 000000000..8bdbc54a3 --- /dev/null +++ b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/model/UserGoldBeanBill.java @@ -0,0 +1,50 @@ +package com.accompany.business.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 用户金豆账单表实体类 + * + * @author + * @since 2025-05-19 + */ +@Data +public class UserGoldBeanBill implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + /** + * 用户uid + */ + private Long uid; + /** + * //账单类型1-支出, 2-收入 + */ + private Byte billType; + /** + * 类型1-任务领取,2商城购买 + */ + private Integer type; + /** + * objId + */ + private String objId; + private BigDecimal beforeBean; + private BigDecimal operateBean; + private BigDecimal afterBean; + /** + * 时间 + */ + private Date createTime; + private Date updateTime; + + +} diff --git a/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/DailyTaskVo.java b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/DailyTaskVo.java new file mode 100644 index 000000000..4802aeac9 --- /dev/null +++ b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/DailyTaskVo.java @@ -0,0 +1,29 @@ +package com.accompany.business.vo; + +import com.accompany.business.constant.dailytask.DailyTaskConstant; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Builder +@ApiModel +@Data +public class DailyTaskVo { + @ApiModelProperty("任务类型") + private DailyTaskTypeEnum taskType; + @ApiModelProperty("UNCOMPLETED-完成, AVAILABLE-可领取,RECEIVED-已领取") + private DailyTaskConstant.ReceiveStatus receiveStatus; + @ApiModelProperty("金豆数量") + private Integer goldBean; + @ApiModelProperty("到达数量") + private Long reachNum; + @ApiModelProperty("达标值") + private Integer standardValue; + private String todayDate; +} diff --git a/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/dailytask/DailyProgressContext.java b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/dailytask/DailyProgressContext.java new file mode 100644 index 000000000..f4a4716cb --- /dev/null +++ b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/dailytask/DailyProgressContext.java @@ -0,0 +1,25 @@ +package com.accompany.business.vo.dailytask; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Data +public class DailyProgressContext { + private Integer partitiionId; + private Long uid; + private Long recvUid; + private Long roomUid; + private String gameId; + private Long chargeGoldNum; + private Byte giftType; + private Long recvGoldNum; + private Date createTime; + +} diff --git a/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/dailytask/DailyTaskContext.java b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/dailytask/DailyTaskContext.java new file mode 100644 index 000000000..542129757 --- /dev/null +++ b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/vo/dailytask/DailyTaskContext.java @@ -0,0 +1,17 @@ +package com.accompany.business.vo.dailytask; + +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import lombok.Data; + +@Data +public class DailyTaskContext { + private final Long uid; + private final DailyTaskTypeEnum taskType; + private String todayDate; + private Integer partitionId; + + public DailyTaskContext(Long uid, DailyTaskTypeEnum taskType) { + this.uid = uid; + this.taskType = taskType; + } +} diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/event/listener/CommonRecharge4ActListener.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/event/listener/CommonRecharge4ActListener.java index b79fc1ca7..890e36795 100644 --- a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/event/listener/CommonRecharge4ActListener.java +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/event/listener/CommonRecharge4ActListener.java @@ -1,6 +1,9 @@ package com.accompany.business.event.listener; +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; import com.accompany.business.service.activity.h5.ActivityOfChargeService; +import com.accompany.business.service.dailytask.DailyTaskService; import com.accompany.business.service.invite.UserInviteFissionV2Service; import com.accompany.business.vo.charge.CommonRecharge4ActVo; import com.accompany.common.constant.Constant; @@ -26,6 +29,8 @@ public class CommonRecharge4ActListener implements ApplicationListener { + +} diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/mybatismapper/UserGoldBeanMapper.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/mybatismapper/UserGoldBeanMapper.java new file mode 100644 index 000000000..93333deb9 --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/mybatismapper/UserGoldBeanMapper.java @@ -0,0 +1,20 @@ +package com.accompany.business.mybatismapper; + +import com.accompany.business.model.UserGoldBean; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.math.BigDecimal; + +/** + * 用户金豆表 Mapper 接口 + * + * @author + * @since 2025-05-19 + */ +public interface UserGoldBeanMapper extends BaseMapper { + + int updateAddGoldBean(@Param("uid") Long uid, @Param("goldBean") BigDecimal goldBean); + + int updateSubGoldBean(@Param("uid") Long uid, @Param("goldBean") BigDecimal goldBean); +} diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/AbstractDailyTaskHandler.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/AbstractDailyTaskHandler.java new file mode 100644 index 000000000..2af401936 --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/AbstractDailyTaskHandler.java @@ -0,0 +1,133 @@ +package com.accompany.business.service.dailytask; + +import com.accompany.business.constant.dailytask.DailyTaskConstant; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.constant.dailytask.GoldBeanBillType; +import com.accompany.business.service.user.UsersService; +import com.accompany.business.service.usergoldbean.UserGoldBeanService; +import com.accompany.business.vo.DailyTaskVo; +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.vo.dailytask.DailyTaskContext; +import com.accompany.common.result.BusiResult; +import com.accompany.common.status.BusiStatus; +import com.accompany.common.utils.DateTimeUtil; +import com.accompany.core.enumeration.PartitionEnum; +import com.accompany.core.exception.ServiceException; +import com.accompany.core.model.Users; +import org.redisson.api.RBucket; +import org.redisson.api.RedissonClient; +import org.redisson.client.codec.IntegerCodec; +import org.springframework.beans.factory.annotation.Autowired; + +import java.math.BigDecimal; +import java.time.Duration; +import java.time.ZonedDateTime; +import java.util.Date; + +import static com.accompany.business.constant.dailytask.DailyTaskConstant.RedisKey.task_receive_status; +import static com.accompany.business.constant.dailytask.DailyTaskConstant.RedisKey.task_status; + +public abstract class AbstractDailyTaskHandler implements DailyTaskHandler { + @Autowired + protected UsersService usersService; + @Autowired + protected RedissonClient redissonClient; + @Autowired + private UserGoldBeanService userGoldBeanService; + + protected final int EXPIRE_DAY = 1; + + @Override + public DailyTaskVo handle(DailyTaskContext context){ + Users users = usersService.getUsersByUid(context.getUid()); + context.setTodayDate(this.getTodayDate(context.getUid(), new Date())); + context.setPartitionId(users.getPartitionId()); + return this.doHandle(context); + } + + /** + * 进度逻辑 + * @param progressContext + * @return + */ + @Override + public abstract void executeProgress(DailyProgressContext progressContext); + + /** + * 业务逻辑 + * @param context + * @return + */ + @Override + public abstract DailyTaskVo doHandle(DailyTaskContext context); + + /** + * 领取任务奖励 + * @param uid + * @param receiveDate + * @param dailyTaskTypeEnum + * @return + */ + @Override + public BusiResult receive(Long uid, String receiveDate, DailyTaskTypeEnum dailyTaskTypeEnum) { + DailyTaskContext dailyTaskContext = new DailyTaskContext(uid, dailyTaskTypeEnum); + DailyTaskVo dailyTaskVo = this.handle(dailyTaskContext); + if (!dailyTaskVo.getTodayDate().equals(receiveDate)) { + throw new ServiceException(BusiStatus.DAILY_RECEIVE_EXPIRE); + } + RBucket taskStatus = taskStatus(uid, receiveDate, dailyTaskTypeEnum); + if (taskStatus.isExists()) { + throw new ServiceException(BusiStatus.DAILY_RECEIVE_EXIST); + } + + Integer receiveStatus = receiveStatus(uid, receiveDate, dailyTaskTypeEnum) + .getAndSet(1, Duration.ofDays(EXPIRE_DAY)); + if (receiveStatus != null) { + throw new ServiceException(BusiStatus.DAILY_RECEIVE_EXIST); + } + userGoldBeanService.addGoldBean(uid, BigDecimal.valueOf(dailyTaskTypeEnum.getReachGoldBean()), + GoldBeanBillType.TASK_GAIN, String.valueOf(dailyTaskTypeEnum.ordinal())); + return BusiResult.success(); + } + + @Override + public String getTodayDate(Long uid, Date date) { + Users users = usersService.getUsersByUid(uid); + PartitionEnum partitionEnum = PartitionEnum.getByPartitionId(users.getPartitionId()); + ZonedDateTime zonedDateTime = DateTimeUtil.convertWithZoneId(date, partitionEnum.getZoneId()); + return zonedDateTime.format(DateTimeUtil.dateFormatter); + } + + /** + * 获取领取状态 + * @param uid + * @param todayDate + * @param taskType + * @return + */ + protected DailyTaskConstant.ReceiveStatus computeReceiveStatus(Long uid, String todayDate, DailyTaskTypeEnum taskType) { + if (!this.taskStatus(uid, todayDate, taskType).isExists()) { + return DailyTaskConstant.ReceiveStatus.UNCOMPLETED; + } + return this.receiveStatus(uid, todayDate, taskType).isExists() + ? DailyTaskConstant.ReceiveStatus.RECEIVED + : DailyTaskConstant.ReceiveStatus.AVAILABLE; + } + + private RBucket receiveStatus(Long uid, String todayDate, DailyTaskTypeEnum dailyTaskTypeEnum) { + return redissonClient.getBucket(task_receive_status.getKey(uid.toString(), dailyTaskTypeEnum.name(), + todayDate.replaceAll("-", "")), IntegerCodec.INSTANCE); + } + + /** + * 任务完成状态 + * @param uid + * @param todayDate + * @param dailyTaskTypeEnum + * @return + */ + protected RBucket taskStatus(Long uid, String todayDate, DailyTaskTypeEnum dailyTaskTypeEnum) { + return redissonClient.getBucket(task_status.getKey(uid.toString(), dailyTaskTypeEnum.name(), + todayDate.replaceAll("-", "")), IntegerCodec.INSTANCE); + } +} diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskHandler.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskHandler.java new file mode 100644 index 000000000..c225f6d26 --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskHandler.java @@ -0,0 +1,23 @@ +package com.accompany.business.service.dailytask; + + +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.vo.dailytask.DailyTaskContext; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.vo.DailyTaskVo; +import com.accompany.common.result.BusiResult; + +import java.util.Date; + +public interface DailyTaskHandler { + + void executeProgress(DailyProgressContext progressContext); + + DailyTaskVo handle(DailyTaskContext context); + + DailyTaskVo doHandle(DailyTaskContext context); + + BusiResult receive(Long uid, String receiveDate, DailyTaskTypeEnum dailyTaskTypeEnum); + + String getTodayDate(Long uid, Date date); +} \ No newline at end of file diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskHandlerRegistry.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskHandlerRegistry.java new file mode 100644 index 000000000..7a151ed5b --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskHandlerRegistry.java @@ -0,0 +1,28 @@ +package com.accompany.business.service.dailytask; + +import com.accompany.business.service.dailytask.annotation.DailyTaskHandlerType; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class DailyTaskHandlerRegistry { + + private final Map handlerMap = new HashMap<>(); + + public DailyTaskHandlerRegistry(List handlers) { + for (DailyTaskHandler handler : handlers) { + DailyTaskHandlerType annotation = handler.getClass().getAnnotation(DailyTaskHandlerType.class); + if (annotation != null) { + handlerMap.put(annotation.value(), handler); + } + } + } + + public DailyTaskHandler getHandler(DailyTaskTypeEnum taskType) { + return handlerMap.get(taskType); + } +} \ No newline at end of file diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskService.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskService.java new file mode 100644 index 000000000..c150be738 --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/DailyTaskService.java @@ -0,0 +1,92 @@ +package com.accompany.business.service.dailytask; + +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.vo.DailyTaskVo; +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.vo.dailytask.DailyTaskContext; +import com.accompany.common.result.BusiResult; +import com.accompany.common.status.BusiStatus; +import com.accompany.common.utils.StringUtils; +import com.accompany.core.exception.ServiceException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static com.accompany.business.constant.dailytask.DailyTaskTypeEnum.*; + +@Service +public class DailyTaskService { + + @Autowired + private DailyTaskHandlerRegistry taskHandlerRegistry; + + public DailyTaskVo executeDailyTask(DailyTaskTypeEnum contextTaskType, DailyTaskTypeEnum handlerTaskType, Long uid) { + DailyTaskHandler handler = taskHandlerRegistry.getHandler(handlerTaskType); + DailyTaskContext dailyTaskContext = new DailyTaskContext(uid, contextTaskType); + return handler.handle(dailyTaskContext); + } + + /** + * 刷新任务进度 + * + * @param taskType + * @param dailyProgressContext + */ + public void executeProgress(DailyTaskTypeEnum taskType, DailyProgressContext dailyProgressContext) { + DailyTaskHandler handler = taskHandlerRegistry.getHandler(taskType); + handler.executeProgress(dailyProgressContext); + } + + /** + * 领取积分 + * + * @param taskType + * @param uid + * @param todayDate + * @return + */ + public BusiResult executeReceive(DailyTaskTypeEnum taskType, Long uid, String todayDate) { + DailyTaskHandler handler = taskHandlerRegistry.getHandler(taskType); + if (handler == null || StringUtils.isEmpty(todayDate) || uid == null) { + throw new ServiceException(BusiStatus.PARAMERROR); + } + return handler.receive(uid, todayDate, taskType); + } + + /** + * 任务列表 + * + * @param uid + * @return + */ + public BusiResult> tasks(Long uid) { + List result = new ArrayList<>(); + result.add(this.executeDailyTask(DAILY_SIGN, DAILY_SIGN, uid)); + + result.add(this.executeDailyTask(UP_MIC, UP_MIC, uid)); + + result.add(this.executeDailyTask(UP_MIC_120, UP_MIC, uid)); + + result.add(this.executeDailyTask(PLAY_GAME, PLAY_GAME, uid)); + + result.add(this.executeDailyTask(CHARGE_GOLD_NUM, CHARGE_GOLD_NUM, uid)); + + result.add(this.executeDailyTask(CHARGE_GOLD_NUM_5, CHARGE_GOLD_NUM, uid)); + + result.add(this.executeDailyTask(CHARGE_GOLD_NUM_10, CHARGE_GOLD_NUM, uid)); + + result.add(this.executeDailyTask(ROOM_SEND_GIFT, ROOM_SEND_GIFT, uid)); + + result.add(this.executeDailyTask(RECV_LUCKY_GIFT, ROOM_SEND_GIFT, uid)); + + result.add(this.executeDailyTask(RECV_NOMAL_GIFT, ROOM_SEND_GIFT, uid)); + + result.add(this.executeDailyTask(RECV_NOMAL_GIFT_GOLD, ROOM_SEND_GIFT, uid)); + + return BusiResult.success(result); + } + +} \ No newline at end of file diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/annotation/DailyTaskHandlerType.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/annotation/DailyTaskHandlerType.java new file mode 100644 index 000000000..a1bc7c80e --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/annotation/DailyTaskHandlerType.java @@ -0,0 +1,14 @@ +package com.accompany.business.service.dailytask.annotation; + +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface DailyTaskHandlerType { + DailyTaskTypeEnum value(); +} \ No newline at end of file diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/ChargeGoldNumHandler.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/ChargeGoldNumHandler.java new file mode 100644 index 000000000..a12cbb4df --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/ChargeGoldNumHandler.java @@ -0,0 +1,67 @@ +package com.accompany.business.service.dailytask.handler; + +import com.accompany.business.constant.dailytask.DailyTaskConstant; +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.service.dailytask.AbstractDailyTaskHandler; +import com.accompany.business.vo.dailytask.DailyTaskContext; +import com.accompany.business.service.dailytask.annotation.DailyTaskHandlerType; +import com.accompany.business.vo.DailyTaskVo; +import com.accompany.core.model.Users; +import org.redisson.api.RBucket; +import org.redisson.api.RMap; +import org.redisson.api.RedissonClient; +import org.redisson.client.codec.IntegerCodec; +import org.redisson.client.codec.LongCodec; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.Date; + +import static com.accompany.business.constant.dailytask.DailyTaskConstant.RedisKey.charge_gold; + +@Component +@DailyTaskHandlerType(DailyTaskTypeEnum.CHARGE_GOLD_NUM) +public class ChargeGoldNumHandler extends AbstractDailyTaskHandler { + + @Override + public void executeProgress(DailyProgressContext progressContext) { + Long uid = progressContext.getUid(); + Integer partitionId = usersService.getUsersByUid(uid).getPartitionId(); + String todayDate = getTodayDate(uid, progressContext.getCreateTime()); + RMap dailyChargeGold = dailyChargeGold(partitionId, todayDate); + Long chargeGold = dailyChargeGold.addAndGet(uid, progressContext.getChargeGoldNum()); + dailyChargeGold.expire(Duration.ofDays(EXPIRE_DAY)); + chargeGold = chargeGold == null ? 0L : chargeGold; + if (chargeGold > DailyTaskTypeEnum.CHARGE_GOLD_NUM.getReachNum()) { + taskStatus(uid, todayDate, DailyTaskTypeEnum.CHARGE_GOLD_NUM).set(1, Duration.ofDays(EXPIRE_DAY)); + } + if (chargeGold > DailyTaskTypeEnum.CHARGE_GOLD_NUM_5.getReachNum()) { + taskStatus(uid, todayDate, DailyTaskTypeEnum.CHARGE_GOLD_NUM_5).set(1, Duration.ofDays(EXPIRE_DAY)); + } + if (chargeGold > DailyTaskTypeEnum.CHARGE_GOLD_NUM_10.getReachNum()) { + taskStatus(uid, todayDate, DailyTaskTypeEnum.CHARGE_GOLD_NUM_10).set(1, Duration.ofDays(EXPIRE_DAY)); + } + } + + @Override + public DailyTaskVo doHandle(DailyTaskContext context) { + DailyTaskTypeEnum taskType = context.getTaskType(); + Long uid = context.getUid(); + String todayDate = context.getTodayDate(); + Long chargeGold = dailyChargeGold(context.getPartitionId(), todayDate).getOrDefault(uid, 0L); + return DailyTaskVo.builder() + .todayDate(todayDate) + .standardValue(taskType.getReachNum()) + .reachNum(chargeGold) + .taskType(taskType) + .goldBean(taskType.getReachGoldBean()) + .receiveStatus(computeReceiveStatus(uid, todayDate, taskType)) + .build(); + } + + private RMap dailyChargeGold(Integer partitionId, String todayDate) { + return redissonClient.getMap(charge_gold.getKey(partitionId.toString(), todayDate), IntegerCodec.INSTANCE); + } +} diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/DailySignHandler.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/DailySignHandler.java new file mode 100644 index 000000000..e3bbd0918 --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/DailySignHandler.java @@ -0,0 +1,38 @@ +package com.accompany.business.service.dailytask.handler; + +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.service.dailytask.AbstractDailyTaskHandler; +import com.accompany.business.vo.dailytask.DailyTaskContext; +import com.accompany.business.service.dailytask.annotation.DailyTaskHandlerType; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.vo.DailyTaskVo; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.Date; + +@Component +@DailyTaskHandlerType(DailyTaskTypeEnum.DAILY_SIGN) +public class DailySignHandler extends AbstractDailyTaskHandler { + + @Override + public void executeProgress(DailyProgressContext progressContext) { + Long uid = progressContext.getUid(); + String todayDate = getTodayDate(uid, progressContext.getCreateTime()); + taskStatus(uid, todayDate, DailyTaskTypeEnum.DAILY_SIGN).set(1, Duration.ofDays(EXPIRE_DAY)); + } + + @Override + public DailyTaskVo doHandle(DailyTaskContext context) { + DailyTaskTypeEnum taskType = context.getTaskType(); + Long uid = context.getUid(); + String todayDate = context.getTodayDate(); + return DailyTaskVo.builder() + .todayDate(todayDate) + .standardValue(taskType.getReachNum()) + .taskType(taskType) + .goldBean(taskType.getReachGoldBean()) + .receiveStatus(computeReceiveStatus(uid, todayDate, taskType)) + .build(); + } +} \ No newline at end of file diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/PlayGameHandler.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/PlayGameHandler.java new file mode 100644 index 000000000..ad7057dae --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/PlayGameHandler.java @@ -0,0 +1,58 @@ +package com.accompany.business.service.dailytask.handler; + +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.service.dailytask.AbstractDailyTaskHandler; +import com.accompany.business.vo.dailytask.DailyTaskContext; +import com.accompany.business.service.dailytask.annotation.DailyTaskHandlerType; +import com.accompany.business.vo.DailyTaskVo; +import org.redisson.api.RBucket; +import org.redisson.api.RSet; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.Date; + +import static com.accompany.business.constant.dailytask.DailyTaskConstant.RedisKey.play_game; + +@Component +@DailyTaskHandlerType(DailyTaskTypeEnum.PLAY_GAME) +public class PlayGameHandler extends AbstractDailyTaskHandler { + + @Override + public void executeProgress(DailyProgressContext progressContext) { + Long uid = progressContext.getUid(); + String todayDate = getTodayDate(uid, progressContext.getCreateTime()); + RSet playGameCategory = playGameCategory(uid, todayDate); + String gameId = progressContext.getGameId(); + if (playGameCategory.contains(gameId)) { + return; + } + playGameCategory.add(gameId); + playGameCategory.expire(Duration.ofDays(EXPIRE_DAY)); + int size = playGameCategory.size(); + RBucket taskStatus = taskStatus(uid, todayDate, DailyTaskTypeEnum.PLAY_GAME); + if (size >= DailyTaskTypeEnum.PLAY_GAME.getReachNum()) { + taskStatus.set(1, Duration.ofDays(EXPIRE_DAY)); + } + } + + @Override + public DailyTaskVo doHandle(DailyTaskContext context) { + DailyTaskTypeEnum taskType = context.getTaskType(); + Long uid = context.getUid(); + String todayDate = context.getTodayDate(); + return DailyTaskVo.builder() + .todayDate(todayDate) + .reachNum((long)playGameCategory(uid, todayDate).size()) + .standardValue(taskType.getReachNum()) + .taskType(taskType) + .goldBean(taskType.getReachGoldBean()) + .receiveStatus(computeReceiveStatus(uid, todayDate, taskType)) + .build(); + } + + private RSet playGameCategory(Long uid, String todayDate) { + return redissonClient.getSet(play_game.getKey(uid.toString(), todayDate)); + } +} \ No newline at end of file diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvLuckyGiftHandler.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvLuckyGiftHandler.java new file mode 100644 index 000000000..41cb983f4 --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvLuckyGiftHandler.java @@ -0,0 +1,51 @@ +package com.accompany.business.service.dailytask.handler; + +import com.accompany.business.service.gift.GiftSendService; +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.service.dailytask.AbstractDailyTaskHandler; +import com.accompany.business.vo.dailytask.DailyTaskContext; +import com.accompany.business.service.dailytask.annotation.DailyTaskHandlerType; +import com.accompany.business.vo.DailyTaskVo; +import org.redisson.api.RBucket; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.Date; + +@Component +@DailyTaskHandlerType(DailyTaskTypeEnum.RECV_LUCKY_GIFT) +public class RecvLuckyGiftHandler extends AbstractDailyTaskHandler { + + @Autowired + private GiftSendService giftSendService; + + @Override + public void executeProgress(DailyProgressContext progressContext) { + Long uid = progressContext.getUid(); + String todayDate = getTodayDate(uid, progressContext.getCreateTime()); + RBucket taskStatus = taskStatus(uid, todayDate, DailyTaskTypeEnum.RECV_LUCKY_GIFT); + if (taskStatus.isExists()) { + return; + } + boolean luckyGift = giftSendService.isLuckyGift(progressContext.getGiftType()); + if (luckyGift) { + taskStatus(uid, todayDate, DailyTaskTypeEnum.RECV_LUCKY_GIFT).set(1, Duration.ofDays(EXPIRE_DAY)); + } + } + + @Override + public DailyTaskVo doHandle(DailyTaskContext context) { + DailyTaskTypeEnum taskType = context.getTaskType(); + Long uid = context.getUid(); + String todayDate = context.getTodayDate(); + return DailyTaskVo.builder() + .todayDate(todayDate) + .standardValue(taskType.getReachNum()) + .taskType(taskType) + .goldBean(taskType.getReachGoldBean()) + .receiveStatus(computeReceiveStatus(uid, todayDate, taskType)) + .build(); + } +} \ No newline at end of file diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvNomalGiftGoldHandler.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvNomalGiftGoldHandler.java new file mode 100644 index 000000000..36ee62364 --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvNomalGiftGoldHandler.java @@ -0,0 +1,57 @@ +package com.accompany.business.service.dailytask.handler; + +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.service.dailytask.AbstractDailyTaskHandler; +import com.accompany.business.vo.dailytask.DailyTaskContext; +import com.accompany.business.service.dailytask.annotation.DailyTaskHandlerType; +import com.accompany.business.vo.DailyTaskVo; +import org.redisson.api.RBucket; +import org.redisson.api.RMap; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.Date; + +import static com.accompany.business.constant.dailytask.DailyTaskConstant.RedisKey.recv_gold_num; +import static com.accompany.business.constant.dailytask.DailyTaskTypeEnum.RECV_NOMAL_GIFT_GOLD; + +@Component +@DailyTaskHandlerType(RECV_NOMAL_GIFT_GOLD) +public class RecvNomalGiftGoldHandler extends AbstractDailyTaskHandler { + + @Override + public void executeProgress(DailyProgressContext progressContext) { + Long uid = progressContext.getUid(); + String todayDate = getTodayDate(uid, progressContext.getCreateTime()); + RMap recvGoldNum = recvGoldNum(progressContext.getPartitiionId(), todayDate); + Long addAndGet = recvGoldNum.addAndGet(uid, progressContext.getRecvGoldNum()); + RBucket taskStatus = taskStatus(uid, todayDate, RECV_NOMAL_GIFT_GOLD); + if (taskStatus.isExists()) { + return; + } + if (addAndGet != null && addAndGet >= RECV_NOMAL_GIFT_GOLD.getReachNum()) { + taskStatus(uid, todayDate, DailyTaskTypeEnum.RECV_NOMAL_GIFT_GOLD).set(1, Duration.ofDays(EXPIRE_DAY)); + } + } + + @Override + public DailyTaskVo doHandle(DailyTaskContext context) { + DailyTaskTypeEnum taskType = context.getTaskType(); + Long uid = context.getUid(); + String todayDate = context.getTodayDate(); + RMap recvGoldNum = recvGoldNum(context.getPartitionId(), todayDate); + return DailyTaskVo.builder() + .todayDate(todayDate) + .reachNum(recvGoldNum.getOrDefault(uid, 0L)) + .standardValue(taskType.getReachNum()) + .taskType(taskType) + .goldBean(taskType.getReachGoldBean()) + .receiveStatus(computeReceiveStatus(uid, todayDate, taskType)) + .build(); + } + + private RMap recvGoldNum(Integer partitionId, String todayDate) { + return redissonClient.getMap(recv_gold_num.getKey(partitionId.toString(), todayDate)); + } +} diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvNomalGiftHandler.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvNomalGiftHandler.java new file mode 100644 index 000000000..76fc2739a --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RecvNomalGiftHandler.java @@ -0,0 +1,52 @@ +package com.accompany.business.service.dailytask.handler; + +import com.accompany.business.service.gift.GiftSendService; +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.service.dailytask.AbstractDailyTaskHandler; +import com.accompany.business.vo.dailytask.DailyTaskContext; +import com.accompany.business.service.dailytask.annotation.DailyTaskHandlerType; +import com.accompany.business.vo.DailyTaskVo; +import org.redisson.api.RBucket; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.Date; + +@Component +@DailyTaskHandlerType(DailyTaskTypeEnum.RECV_NOMAL_GIFT) +public class RecvNomalGiftHandler extends AbstractDailyTaskHandler { + + @Autowired + private GiftSendService giftSendService; + + @Override + public void executeProgress(DailyProgressContext progressContext) { + Long uid = progressContext.getUid(); + String todayDate = getTodayDate(uid, progressContext.getCreateTime()); + RBucket taskStatus = taskStatus(uid, todayDate, DailyTaskTypeEnum.RECV_NOMAL_GIFT); + if (taskStatus.isExists()) { + return; + } + boolean luckyGift = giftSendService.isLuckyGift(progressContext.getGiftType()); + if (luckyGift) { + return; + } + taskStatus(uid, todayDate, DailyTaskTypeEnum.RECV_NOMAL_GIFT).set(1, Duration.ofDays(EXPIRE_DAY)); + } + + @Override + public DailyTaskVo doHandle(DailyTaskContext context) { + DailyTaskTypeEnum taskType = context.getTaskType(); + Long uid = context.getUid(); + String todayDate = context.getTodayDate(); + return DailyTaskVo.builder() + .todayDate(todayDate) + .standardValue(taskType.getReachNum()) + .taskType(taskType) + .goldBean(taskType.getReachGoldBean()) + .receiveStatus(computeReceiveStatus(uid, todayDate, taskType)) + .build(); + } +} \ No newline at end of file diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RoomSendGiftHandler.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RoomSendGiftHandler.java new file mode 100644 index 000000000..0bf83bf83 --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/RoomSendGiftHandler.java @@ -0,0 +1,46 @@ +package com.accompany.business.service.dailytask.handler; + +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.service.dailytask.AbstractDailyTaskHandler; +import com.accompany.business.vo.dailytask.DailyTaskContext; +import com.accompany.business.service.dailytask.annotation.DailyTaskHandlerType; +import com.accompany.business.vo.DailyTaskVo; +import org.redisson.api.RBucket; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.Date; + +@Component +@DailyTaskHandlerType(DailyTaskTypeEnum.ROOM_SEND_GIFT) +public class RoomSendGiftHandler extends AbstractDailyTaskHandler { + + @Override + public void executeProgress(DailyProgressContext progressContext) { + Long uid = progressContext.getUid(); + String todayDate = getTodayDate(uid, progressContext.getCreateTime()); + RBucket taskStatus = taskStatus(uid, todayDate, DailyTaskTypeEnum.ROOM_SEND_GIFT); + if (taskStatus.isExists()) { + return; + } + if (progressContext.getRoomUid() == null) { + return; + } + taskStatus(uid, todayDate, DailyTaskTypeEnum.ROOM_SEND_GIFT).set(1, Duration.ofDays(EXPIRE_DAY)); + } + + @Override + public DailyTaskVo doHandle(DailyTaskContext context) { + DailyTaskTypeEnum taskType = context.getTaskType(); + Long uid = context.getUid(); + String todayDate = context.getTodayDate(); + return DailyTaskVo.builder() + .todayDate(todayDate) + .standardValue(taskType.getReachNum()) + .taskType(taskType) + .goldBean(taskType.getReachGoldBean()) + .receiveStatus(computeReceiveStatus(uid, todayDate, taskType)) + .build(); + } +} \ No newline at end of file diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/UpMicHandler.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/UpMicHandler.java new file mode 100644 index 000000000..ed1ed83f9 --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/handler/UpMicHandler.java @@ -0,0 +1,25 @@ +package com.accompany.business.service.dailytask.handler; + +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.business.service.dailytask.AbstractDailyTaskHandler; +import com.accompany.business.vo.dailytask.DailyTaskContext; +import com.accompany.business.service.dailytask.annotation.DailyTaskHandlerType; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.vo.DailyTaskVo; +import org.springframework.stereotype.Component; + +@Component +@DailyTaskHandlerType(DailyTaskTypeEnum.UP_MIC) +public class UpMicHandler extends AbstractDailyTaskHandler { + @Override + public void executeProgress(DailyProgressContext progressContext) { + Long uid = progressContext.getUid(); + String todayDate = getTodayDate(uid, progressContext.getCreateTime()); + } + + @Override + public DailyTaskVo doHandle(DailyTaskContext context) { + // 实现上麦聊天任务逻辑 + return null; + } +} diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/listener/DailyTaskGiftListener.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/listener/DailyTaskGiftListener.java new file mode 100644 index 000000000..075bae73d --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/dailytask/listener/DailyTaskGiftListener.java @@ -0,0 +1,48 @@ +package com.accompany.business.service.dailytask.listener; + +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.event.GiftMessageEvent; +import com.accompany.business.message.GiftMessage; +import com.accompany.business.service.dailytask.DailyTaskService; +import com.accompany.business.service.gift.GiftSendRecordService; +import com.accompany.business.vo.dailytask.DailyProgressContext; +import com.accompany.common.constant.Constant; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import java.util.Date; + +@Slf4j +@Component +public class DailyTaskGiftListener implements ApplicationListener { + + @Autowired + private DailyTaskService dailyTaskService; + + @Async + @Override + public void onApplicationEvent(GiftMessageEvent event) { + try { + GiftMessage giftMessage = (GiftMessage) event.getSource(); + DailyProgressContext dailyProgressContext = DailyProgressContext.builder() + .roomUid(giftMessage.getRoomUid()) + .uid(giftMessage.getSendUid()) + .recvUid(giftMessage.getRecvUid()) + .giftType(giftMessage.getGiftType()) + .recvGoldNum(giftMessage.getRealGoldNum()) + .createTime(new Date(giftMessage.getMessTime())) + .partitiionId(giftMessage.getPartitionId()) + .build(); + dailyTaskService.executeProgress(DailyTaskTypeEnum.RECV_LUCKY_GIFT, dailyProgressContext); + dailyTaskService.executeProgress(DailyTaskTypeEnum.RECV_NOMAL_GIFT_GOLD, dailyProgressContext); + dailyTaskService.executeProgress(DailyTaskTypeEnum.RECV_NOMAL_GIFT, dailyProgressContext); + dailyTaskService.executeProgress(DailyTaskTypeEnum.ROOM_SEND_GIFT, dailyProgressContext); + } catch (Exception e) { + log.error("DailyTaskGiftListener:e.getMessage:{}", e.getMessage(), e); + } + } +} diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/UserGoldBeanBillService.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/UserGoldBeanBillService.java new file mode 100644 index 000000000..7a1a5da93 --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/UserGoldBeanBillService.java @@ -0,0 +1,20 @@ +package com.accompany.business.service.usergoldbean; + +import com.accompany.business.constant.dailytask.GoldBeanBillType; +import com.accompany.business.model.UserGoldBean; +import com.accompany.business.model.UserGoldBeanBill; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.math.BigDecimal; + +/** + * 用户金豆账单表 服务类 + * + * @author + * @since 2025-05-19 + */ +public interface UserGoldBeanBillService extends IService { + + + int insertBill(Long uid, GoldBeanBillType goldBeanBillType, BigDecimal goldBean, String objId, UserGoldBean afterGoldBean); +} diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/UserGoldBeanService.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/UserGoldBeanService.java new file mode 100644 index 000000000..39e3dc8de --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/UserGoldBeanService.java @@ -0,0 +1,24 @@ +package com.accompany.business.service.usergoldbean; + +import com.accompany.business.constant.dailytask.GoldBeanBillType; +import com.accompany.business.model.UserGoldBean; +import com.accompany.business.model.UserPurse; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.math.BigDecimal; +import java.util.function.Consumer; + +/** + * 用户金豆表 服务类 + * + * @author + * @since 2025-05-19 + */ +public interface UserGoldBeanService extends IService { + + UserGoldBean queryUserGoldBean(Long uid); + + UserGoldBean addGoldBean(Long uid, BigDecimal goldBean, GoldBeanBillType goldBeanBillType, String objId); + + UserGoldBean subGoldBean(Long uid, BigDecimal goldBean, GoldBeanBillType goldBeanBillType, String objId); +} diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/impl/UserGoldBeanBillServiceImpl.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/impl/UserGoldBeanBillServiceImpl.java new file mode 100644 index 000000000..8ec62dbdb --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/impl/UserGoldBeanBillServiceImpl.java @@ -0,0 +1,42 @@ +package com.accompany.business.service.usergoldbean.impl; + +import com.accompany.business.constant.dailytask.GoldBeanBillType; +import com.accompany.business.model.UserGoldBean; +import com.accompany.business.model.UserGoldBeanBill; +import com.accompany.business.mybatismapper.UserGoldBeanBillMapper; +import com.accompany.business.service.usergoldbean.UserGoldBeanBillService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 用户金豆账单表 服务实现类 + * + * @author + * @since 2025-05-19 + */ +@Service +public class UserGoldBeanBillServiceImpl extends ServiceImpl implements UserGoldBeanBillService { + + + @Override + public int insertBill(Long uid, GoldBeanBillType goldBeanBillType, BigDecimal goldBean, String objId, UserGoldBean afterGoldBean) { + UserGoldBeanBill beanBill = new UserGoldBeanBill(); + beanBill.setBillType(goldBeanBillType.getBillType()); + beanBill.setType(goldBeanBillType.getType()); + beanBill.setUid(uid); + beanBill.setOperateBean(goldBean); + beanBill.setCreateTime(new Date()); + beanBill.setUpdateTime(beanBill.getCreateTime()); + beanBill.setObjId(objId); + if (goldBeanBillType.getBillType() == 1) { + beanBill.setBeforeBean(afterGoldBean.getGoldBean().add(goldBean)); + } else if (goldBeanBillType.getBillType() == 2) { + beanBill.setBeforeBean(afterGoldBean.getGoldBean().subtract(goldBean)); + } + beanBill.setAfterBean(afterGoldBean.getGoldBean()); + return 0; + } +} diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/impl/UserGoldBeanServiceImpl.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/impl/UserGoldBeanServiceImpl.java new file mode 100644 index 000000000..359ad872e --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/usergoldbean/impl/UserGoldBeanServiceImpl.java @@ -0,0 +1,132 @@ +package com.accompany.business.service.usergoldbean.impl; + +import com.accompany.business.constant.dailytask.DailyTaskConstant; +import com.accompany.business.constant.dailytask.GoldBeanBillType; +import com.accompany.business.model.UserGoldBean; +import com.accompany.business.mybatismapper.UserGoldBeanMapper; +import com.accompany.business.service.usergoldbean.UserGoldBeanBillService; +import com.accompany.business.service.usergoldbean.UserGoldBeanService; +import com.accompany.common.redis.RedisKey; +import com.accompany.common.status.BusiStatus; +import com.accompany.core.exception.ServiceException; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import lombok.extern.slf4j.Slf4j; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.function.Function; + +import static com.accompany.business.constant.dailytask.DailyTaskConstant.RedisKey.lock_user_gold_bean; +import static com.accompany.common.status.BusiStatus.DAILY_GOLDBEANNOTENOUGH; + + +/** + * 用户金豆表 服务实现类 + * + * @author + * @since 2025-05-19 + */ +@Slf4j +@Service +public class UserGoldBeanServiceImpl extends ServiceImpl implements UserGoldBeanService { + + @Autowired + private RedissonClient redissonClient; + + @Autowired + private UserGoldBeanBillService userGoldBeanBillService; + + @Override + public UserGoldBean queryUserGoldBean(Long uid) { + UserGoldBean userGoldBean = this.baseMapper.selectById(uid); + if (userGoldBean == null) { + userGoldBean = createUserGoldBean(uid); + } + return userGoldBean; + } + + @Override + public UserGoldBean addGoldBean(Long uid, BigDecimal goldBean, GoldBeanBillType goldBeanBillType, String objId) { + if (goldBean.doubleValue() < 0D) { + throw new ServiceException(BusiStatus.PARAMETERILLEGAL); + } + UserGoldBean after = withLock(uid, lock_user_gold_bean, userGoldBean -> { + log.info("addGoldBean 操作前,buss:{},userGoldBean:{}", goldBeanBillType.getDesc(), JSONObject.toJSONString(userGoldBean)); + int ret = baseMapper.updateAddGoldBean(uid, goldBean); + boolean result = SqlHelper.retBool(ret); + if (!result) { + throw new ServiceException(BusiStatus.SERVERBUSY); + } + userGoldBean.setGoldBean(userGoldBean.getGoldBean().add(goldBean)); + userGoldBean.setUpdateTime(new Date()); + log.info("addGoldBean 操作后,buss:{},userGoldBean:{}", goldBeanBillType.getDesc(), JSONObject.toJSONString(userGoldBean)); + return userGoldBean; + }); + + userGoldBeanBillService.insertBill(uid, goldBeanBillType, goldBean, objId, after); + return after; + } + + @Override + public UserGoldBean subGoldBean(Long uid, BigDecimal goldBean, GoldBeanBillType goldBeanBillType, String objId) { + if (goldBean.doubleValue() <= 0d) { + throw new ServiceException(BusiStatus.PARAMETERILLEGAL); + } + + String desc = goldBeanBillType.getDesc(); + UserGoldBean after = withLock(uid, lock_user_gold_bean, userGoldBean -> { + BigDecimal restDiamond = userGoldBean.getGoldBean().subtract(goldBean); + if (restDiamond.doubleValue() < 0d) { + throw new ServiceException(DAILY_GOLDBEANNOTENOUGH); + } + log.info("subGoldBean 操作前,buss:{},userPurse:{}", desc, JSONObject.toJSONString(userGoldBean)); + int ret = baseMapper.updateSubGoldBean(uid, goldBean); + boolean result = SqlHelper.retBool(ret); + if (!result) { + throw new ServiceException(BusiStatus.SERVERBUSY); + } + userGoldBean.setGoldBean(restDiamond); + userGoldBean.setUpdateTime(new Date()); + log.info("subGoldBean 操作后,buss:{},userPurse:{}", desc, JSONObject.toJSONString(userGoldBean)); + return userGoldBean; + }); + + userGoldBeanBillService.insertBill(uid, goldBeanBillType, goldBean, objId, after); + return after; + } + + private UserGoldBean createUserGoldBean(Long uid) { + UserGoldBean userGoldBean = new UserGoldBean(); + userGoldBean.setUid(uid); + userGoldBean.setGoldBean(BigDecimal.ZERO); + userGoldBean.setUpdateTime(new Date()); + save(userGoldBean); + return userGoldBean; + } + + + private R withLock(Long uid, DailyTaskConstant.RedisKey redisKey, Function function) { + String lockKey = redisKey.getKey(String.valueOf(uid)); + RLock lock = redissonClient.getLock(lockKey); + long startTime = System.currentTimeMillis(); + try { + lock.lock(); + long lockTime = System.currentTimeMillis() - startTime; + log.info("[金豆] uid {} starTime {} lockTime:{} ", uid, startTime, lockTime); + UserGoldBean userGoldBean = this.queryUserGoldBean(uid); + return function.apply(userGoldBean); + } finally { + long finishTime = System.currentTimeMillis() - startTime; + lock.unlock(); + long unlockTime = System.currentTimeMillis() - startTime; + log.info("[金豆] uid:{}, starTime {} finishTime:{} unlockTime:{}, ", uid, startTime, finishTime, unlockTime); + } + } + +} diff --git a/accompany-business/accompany-business-service/src/main/resources/accompany/sqlmappers/UserGoldBeanBillMapper.xml b/accompany-business/accompany-business-service/src/main/resources/accompany/sqlmappers/UserGoldBeanBillMapper.xml new file mode 100644 index 000000000..18e8554c0 --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/resources/accompany/sqlmappers/UserGoldBeanBillMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/accompany-business/accompany-business-service/src/main/resources/accompany/sqlmappers/UserGoldBeanMapper.xml b/accompany-business/accompany-business-service/src/main/resources/accompany/sqlmappers/UserGoldBeanMapper.xml new file mode 100644 index 000000000..6e2d8b83f --- /dev/null +++ b/accompany-business/accompany-business-service/src/main/resources/accompany/sqlmappers/UserGoldBeanMapper.xml @@ -0,0 +1,12 @@ + + + + + + update user_gold_bean set gold_bean = gold_bean + #{goldBean}, update_time=now() where uid=#{uid} + + + update user_gold_bean set gold_bean = gold_bean - #{goldBean}, update_time=now() where uid=#{uid} + + + diff --git a/accompany-business/accompany-business-web/src/main/java/com/accompany/business/controller/activity/dailytask/DailyTaskController.java b/accompany-business/accompany-business-web/src/main/java/com/accompany/business/controller/activity/dailytask/DailyTaskController.java new file mode 100644 index 000000000..d8f8de569 --- /dev/null +++ b/accompany-business/accompany-business-web/src/main/java/com/accompany/business/controller/activity/dailytask/DailyTaskController.java @@ -0,0 +1,39 @@ +package com.accompany.business.controller.activity.dailytask; + +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; +import com.accompany.business.service.dailytask.DailyTaskService; +import com.accompany.business.vo.DailyTaskVo; +import com.accompany.common.result.BusiResult; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static com.accompany.common.constant.ApplicationConstant.PublicParameters.PUB_UID; + +@RestController +@RequestMapping("/daily") +public class DailyTaskController { + @Autowired + private DailyTaskService dailyTaskService; + + @ApiOperation(value = "任务列表", httpMethod = "GET") + @GetMapping("/tasks") + public BusiResult> tasks(@RequestHeader(PUB_UID) Long uid) { + return dailyTaskService.tasks(uid); + } + + @ApiOperation(value = "领取", httpMethod = "POST") + @ApiImplicitParams({ + @ApiImplicitParam(name = "todayDate", value = "列表有传对应字段", required = true, dataType = "string", paramType = "query"), + @ApiImplicitParam(name = "taskType", value = "列表有传对应字段", required = true, dataType = "string", paramType = "query"), + }) + @PostMapping("/recv") + public BusiResult> recv(@RequestHeader(PUB_UID) Long uid, String todayDate, DailyTaskTypeEnum taskType) { + return dailyTaskService.executeReceive(taskType, uid, todayDate); + } + +} diff --git a/accompany-mq/accompany-mq-web/src/main/java/com/accompany/mq/consumer/GameMsgPushMessageConsumer.java b/accompany-mq/accompany-mq-web/src/main/java/com/accompany/mq/consumer/GameMsgPushMessageConsumer.java index 05f556bc0..152f65d8f 100644 --- a/accompany-mq/accompany-mq-web/src/main/java/com/accompany/mq/consumer/GameMsgPushMessageConsumer.java +++ b/accompany-mq/accompany-mq-web/src/main/java/com/accompany/mq/consumer/GameMsgPushMessageConsumer.java @@ -1,11 +1,14 @@ package com.accompany.mq.consumer; +import com.accompany.business.constant.dailytask.DailyTaskTypeEnum; import com.accompany.business.enums.resource.ResourceCodeEnum; import com.accompany.business.event.miniGame.MiniGameChangeCurrencyEvent; import com.accompany.business.message.BillMessage; import com.accompany.business.message.GameMsgMessage; +import com.accompany.business.service.dailytask.DailyTaskService; import com.accompany.business.service.game.BaseGameMessageService; import com.accompany.business.service.gift.BillMessageService; +import com.accompany.business.vo.dailytask.DailyProgressContext; import com.accompany.common.constant.Constant; import com.accompany.mq.constant.MqConstant; import com.accompany.mq.listener.AbstractMessageListener; @@ -26,15 +29,25 @@ public class GameMsgPushMessageConsumer extends AbstractMessageListener