Browse Source

fix(system): 修复奖励重复领取问题并优化模板状态管理

- 修改了 ItermTypeLogEnum 中的代码值
- 在 RewardClaimsServiceImpl 中增加了 Redis 缓存机制,防止重复领取奖励
- 更新了 ScheduleConfigMapper 和 TournamentsTemplateMapper,增加了模板状态相关的操作
fugui001 4 months ago
parent
commit
98baf9a3ca

+ 4 - 4
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/enums/ItermTypeLogEnum.java

@@ -6,10 +6,10 @@ import lombok.Getter;
 public enum ItermTypeLogEnum {
 
     // 充值/奖励/报名/比赛
-    RECHARGE(0, "充值"),
-    EWARD(1, "奖励"),
-    SIGNUP(2, "报名"),
-    COMPETITION(3, "比赛");
+    RECHARGE(1, "充值"),
+    EWARD(2, "奖励"),
+    SIGNUP(3, "报名"),
+    COMPETITION(4, "比赛");
 
     private final int code;
     private final String description;

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/ScheduleConfigMapper.java

@@ -71,6 +71,7 @@ public interface ScheduleConfigMapper extends BaseMapperPlus<ScheduleConfig, Sch
                                     @Param("execTime") LocalTime execTime,
                                       @Param("currentConfigId") Long currentConfigId);
 
-
+    @InterceptorIgnore(tenantLine = "true")
+    int selExitConfigByTemplateId(@Param("templateId") Long templateId);
 
 }

+ 4 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/TournamentsTemplateMapper.java

@@ -54,5 +54,9 @@ public interface TournamentsTemplateMapper extends BaseMapperPlus<TournamentsTem
     void batchInsertTournamentBlindStructuresTemplate(@Param("tournamentId") Long tournamentId,
                                               @Param("blindStructureIds") List<Long> blindStructureIds);
 
+    @InterceptorIgnore(tenantLine = "true")
+    int updateUseTournamentTemplate(@Param("templateId") Long templateId);
+
+
 }
 

+ 20 - 10
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/impl/RewardClaimsServiceImpl.java

@@ -17,6 +17,7 @@ import org.dromara.business.mapper.*;
 import org.dromara.business.service.IItemsService;
 import org.dromara.business.service.IRewardClaimsService;
 import org.dromara.business.utils.ItemOperationLock;
+import org.dromara.common.core.constant.Constants;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -26,10 +27,13 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.redis.utils.RedisUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+
+import java.time.Duration;
 import java.util.*;
 
 /**
@@ -265,10 +269,17 @@ public class RewardClaimsServiceImpl implements IRewardClaimsService {
         try {
             // 1. 校验领取状态,防止重复领取
             RewardClaimsVo rewardClaimsVo = baseMapper.selectInfoById(bo.getId());
-            if (!Objects.equals(rewardClaimsVo.getClaimed(), 2L)) {
-                throw new IllegalArgumentException("该奖励已处理,请勿重复操作");
+            if (rewardClaimsVo.getClaimed()!=0L) {
+                throw new RuntimeException("该奖励已处理,请勿重复操作");
+            }
+            String rewardKey="reward:"+bo.getId();
+            if(RedisUtils.isExistsObject(rewardKey)){
+                throw new RuntimeException("该奖励已处理,请勿重复操作");
             }
 
+            // TODO 验证 在校验领取记录里面是否存在  奖励发放之后放入redis中 表示已经发放 SYSTEM
+            RedisUtils.setCacheObject(rewardKey, bo.getId(), Duration.ofMinutes(60*24));
+
             // 2. 解析 JSON 奖励数据(保留原始 Map 方式)
             String rewardJson = bo.getRewardJson();
             List<Map<String, Object>> list = objectMapper.readValue(
@@ -310,7 +321,7 @@ public class RewardClaimsServiceImpl implements IRewardClaimsService {
                 logEntry.setUserId(playerId);
                 logEntry.setType(1L);
                 logEntry.setBeforeNum(beforeNum.longValue());
-/*                logEntry.setItemType(ItermTypeLogEnum.COMPETITION.getCode());*/
+            /*    logEntry.setItemType(ItermTypeLogEnum.COMPETITION.getCode());*/
                 logEntry.setItemTypeText(itemsVo.getName());
                 logEntry.setRemark(itemsVo.getItemDesc());
                 playersItemsLogs.add(logEntry);
@@ -335,20 +346,19 @@ public class RewardClaimsServiceImpl implements IRewardClaimsService {
                 if (insertCount <= 0) {
                     throw new RuntimeException("道具发放失败");
                 }
+                // 7. 更新奖励记录状态
+                int rewardUpdateCount = baseMapper.updateUserRewardClaimed(bo.getId());
+                if (rewardUpdateCount <= 0) {
+                    throw new RuntimeException("更新奖励记录失败");
+                }
 
-
+               // TODO app收到消息  用户提交领取状态   审核  发放
                 // 6. 更新用户消息状态
                 int messageUpdateCount = userMessageStatusMapper.updateUserMessageClaimed(bo.getId());
                 if (messageUpdateCount <= 0) {
                     throw new RuntimeException("更新用户消息状态失败");
                 }
 
-                // 7. 更新奖励记录状态
-                int rewardUpdateCount = baseMapper.updateUserRewardClaimed(bo.getId());
-                if (rewardUpdateCount <= 0) {
-                    throw new RuntimeException("更新奖励记录失败");
-                }
-
             } finally {
                 ItemOperationLock.releaseLock(bo.getPlayerId()); // 确保释放锁
             }

+ 6 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/impl/ScheduleConfigServiceImpl.java

@@ -58,6 +58,8 @@ public class ScheduleConfigServiceImpl implements IScheduleConfigService {
 
     private final ScheduleTournamentsReletionMapper scheduleTournamentsReletionMapper;
 
+    private final  TournamentsTemplateMapper tournamentsTemplateMapper;
+
     /**
      * 查询排期配置:用于保存具体的排期实例配置
      *
@@ -210,7 +212,10 @@ public class ScheduleConfigServiceImpl implements IScheduleConfigService {
         // 6. ✅ 预生成执行计划
         generateExecutionPlan(configId, dto.getCreationSchemeCode(), startDate, endDate, dto.getRepeatTypes(), dto.getExecTimes());
 
-         return R.ok();
+        //7 模版变成已使用
+        tournamentsTemplateMapper.updateUseTournamentTemplate(dto.getTemplateId());
+
+        return R.ok();
     }
 
     private LocalDate calculateStartDate(String schemeCode) {

+ 25 - 8
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/impl/TournamentsTemplateServiceImpl.java

@@ -14,7 +14,6 @@ import org.dromara.business.domain.bo.TournamentBlindStructuresBo;
 import org.dromara.business.domain.bo.TournamentsBo;
 import org.dromara.business.domain.dto.ItemsPrizeDto;
 import org.dromara.business.domain.dto.TournamentsDto;
-import org.dromara.business.domain.enums.GameTemplateStatus;
 import org.dromara.business.domain.vo.*;
 import org.dromara.business.mapper.*;
 import org.dromara.business.service.ITournamentsTemplateService;
@@ -63,6 +62,8 @@ public class TournamentsTemplateServiceImpl implements ITournamentsTemplateServi
 
     private final ParticipantsMapper participantsMapper;
 
+    private final ScheduleConfigMapper scheduleConfigMapper;
+
     /**
      * 查询【请填写功能名称】
      *
@@ -112,8 +113,11 @@ public class TournamentsTemplateServiceImpl implements ITournamentsTemplateServi
             }
             tournamentsVo.setItemsPrizeList(itemsPrizeList);
 
-            String statusText= GameTemplateStatus.getDescriptionFromCode(tournamentsVo.getStatus());
-            tournamentsVo.setStatusText(statusText);
+            if(tournamentsVo.getStatus()==1L){
+                tournamentsVo.setStatusText("使用中");
+            }else if(tournamentsVo.getStatus()==2L){
+                tournamentsVo.setStatusText("未使用");
+            }
         }
         int totalSignNum = participantsMapper.selectParticipantsTotal(tournamentId);
         tournamentsVo.setSignNum(totalSignNum);
@@ -124,7 +128,7 @@ public class TournamentsTemplateServiceImpl implements ITournamentsTemplateServi
      * 分页查询【请填写功能名称】列表
      *
      * @param bo        查询条件
-     * @param pageQuery 分页参数
+     * @param pageQuery 分页参数2
      * @return 【请填写功能名称】分页列表
      */
     @Override
@@ -134,8 +138,13 @@ public class TournamentsTemplateServiceImpl implements ITournamentsTemplateServi
         List<TournamentsVo> records = result.getRecords();
         for (TournamentsVo record : records) {
             Long tournamentId = record.getId();
-            String statusText= GameTemplateStatus.getDescriptionFromCode(record.getStatus());
-            record.setStatusText(statusText);
+
+            if(record.getStatus()==1L){
+                record.setStatusText("使用中");
+            }else if(record.getStatus()==2L){
+                record.setStatusText("未使用");
+            }
+
             //赛事报名条件
             TournamentEntryConditionsVo tournamentEntryConditionsVo = tournamentEntryConditionsMapper.selectByTournamentInfoTemplate(tournamentId);
             if(tournamentEntryConditionsVo!=null){
@@ -272,6 +281,7 @@ public class TournamentsTemplateServiceImpl implements ITournamentsTemplateServi
 
             //比赛ID
             add.setTournamentsBiId(getCurrentDateTime()+bo.getGameType()+getRandomFourDigitNumber());
+            //未使用
             add.setStatus(2L);
             // 插入赛事主表
             boolean flag = baseMapper.insertTournamentTemplate(add) > 0;
@@ -402,6 +412,10 @@ public class TournamentsTemplateServiceImpl implements ITournamentsTemplateServi
     public Boolean updateByBo(TournamentsDto bo) {
         try {
 
+            if(scheduleConfigMapper.selExitConfigByTemplateId(bo.getId())>0){
+                throw new RuntimeException("该模版已经被自动化配置了");
+            }
+
             // 转换 BO -> Entity
             TournamentsTemplate update = new TournamentsTemplate();
             BeanUtils.copyProperties(bo, update);
@@ -469,8 +483,11 @@ public class TournamentsTemplateServiceImpl implements ITournamentsTemplateServi
      */
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if(isValid){
-            //TODO 做一些业务上的校验,判断是否需要校验
+         // todo 删除模版 需要校验是否已经被 自动化配置了
+        for (Long templateId : ids) {
+             if(scheduleConfigMapper.selExitConfigByTemplateId(templateId)>0){
+                 throw new RuntimeException("该模版已经被自动化配置了");
+             }
         }
         return baseMapper.deleteTournamentByIdsTemplate(ids) > 0;
     }

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/ScheduleConfigMapper.xml

@@ -146,4 +146,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         )
     </select>
 
+
+    <select id="selExitConfigByTemplateId" resultType="int">
+        SELECT COUNT(*)
+        FROM schedule_config sc  where  template_id=#{templateId}
+    </select>
+
+
 </mapper>

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/TournamentsTemplateMapper.xml

@@ -129,4 +129,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         tournament_id = tournament_id
     </insert>
 
+
+    <update id="updateUseTournamentTemplate">
+       UPDATE tournaments_template set status=1 WHERE id=#{templateId}
+    </update>
+
+
+
 </mapper>