소스 검색

fix : 发码器代码完成提交01

bilingfeng 5 달 전
부모
커밋
1ae8570216
19개의 변경된 파일660개의 추가작업 그리고 101개의 파일을 삭제
  1. 1 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java
  2. 10 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/constant/RedisKeyConstant.java
  3. 33 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/api/GameGiftPackApi.java
  4. 0 36
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/api/SmsController.java
  5. 10 6
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/GameGiftPackCodeUpdateParam.java
  6. 24 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/vo/GameGiftPackCodeLogVO.java
  7. 36 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/vo/GameGiftPackLinkLogVO.java
  8. 11 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IGameGiftPackCodeLogService.java
  9. 10 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IGameGiftPackLinkLogService.java
  10. 14 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IRoleOperateService.java
  11. 281 10
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/GameGiftPackCodeLogServiceImpl.java
  12. 43 22
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/GameGiftPackCodeServiceImpl.java
  13. 89 18
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/GameGiftPackLinkLogServiceImpl.java
  14. 40 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/RoleOperateServiceImpl.java
  15. 1 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/SmsServiceImpl.java
  16. 16 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/utils/RedisUtil.java
  17. 5 0
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GameGiftPackCode.java
  18. 16 6
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GameGiftPackCodeLog.java
  19. 20 0
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GameGiftPackLinkLog.java

+ 1 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java

@@ -23,7 +23,7 @@ public class ManageApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(ManageApplication.class, args);
-        System.out.println("赞象Manage服务启动成功 < (发码器后台代码提交10・・)ノ(._.`) \n" +
+        System.out.println("赞象Manage服务启动成功 < (发码器代码完成提交01・・)ノ(._.`) \n" +
                 "___  ___  ___   _   _   ___  _____  _____ \n" +
                 "|  \\/  | / _ \\ | \\ | | / _ \\|  __ \\|  ___|\n" +
                 "| .  . |/ /_\\ \\|  \\| |/ /_\\ \\ |  \\/| |__  \n" +

+ 10 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/constant/RedisKeyConstant.java

@@ -46,4 +46,14 @@ public class RedisKeyConstant {
      * 手机验证码缓存key
      */
     public static final String SMS_PHONE_KEY = RedisKeyConstant.REDIS_PREFIX + "sms_phone";
+
+    /**
+     * 游戏礼包码缓存key
+     */
+    public static final String GAME_GIFT_PACK_CODE = RedisKeyConstant.REDIS_PREFIX + "game_gift_pack_code_";
+
+    /**
+     * 游戏礼包码线程锁缓存key
+     */
+    public static final String GAME_GIFT_PACK_LOCK = RedisKeyConstant.REDIS_PREFIX + "game_gift_pack_lock_";
 }

+ 33 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/api/GameGiftPackApi.java

@@ -1,7 +1,10 @@
 package com.zanxiang.game.module.manage.controller.api;
 
+import com.github.sd4324530.jtuple.Tuple2;
 import com.zanxiang.game.module.manage.pojo.params.GameGiftPackLinkLogPushParam;
+import com.zanxiang.game.module.manage.service.IGameGiftPackCodeLogService;
 import com.zanxiang.game.module.manage.service.IGameGiftPackLinkLogService;
+import com.zanxiang.game.module.manage.service.ISmsService;
 import com.zanxiang.module.util.pojo.ResultVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -25,9 +28,15 @@ import java.util.Map;
 @RequestMapping("/api/game/gift/pack")
 public class GameGiftPackApi {
 
+    @Autowired
+    private ISmsService smsService;
+
     @Autowired
     private IGameGiftPackLinkLogService gameGiftPackLinkLogService;
 
+    @Autowired
+    private IGameGiftPackCodeLogService gameGiftPackCodeLogService;
+
     @ApiOperation(value = "链接访问记录推送提交")
     @PostMapping(value = "/link/log/push")
     @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Long.class)})
@@ -36,9 +45,32 @@ public class GameGiftPackApi {
     }
 
     @ApiOperation(value = "获取游戏区服列表")
-    @GetMapping(value = "/source/game/server")
+    @GetMapping(value = "/game/source/server")
     @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Long.class)})
     public ResultVO<Map<String, String>> getSourceGameServer(@RequestParam Long linkLogId) {
         return ResultVO.ok(gameGiftPackLinkLogService.getSourceGameServer(linkLogId));
     }
+
+    @ApiOperation(value = "游戏玩家角色验证")
+    @GetMapping(value = "/role/check")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Long.class)})
+    public ResultVO<Map<String, Object>> gameUserRoleCheck(@RequestParam Long linkLogId, @RequestParam String serverId,
+                                                           @RequestParam String roleName) {
+        return ResultVO.ok(gameGiftPackLinkLogService.gameUserRoleCheck(linkLogId, serverId, roleName));
+    }
+
+    @ApiOperation(value = "手机验证码发送")
+    @GetMapping(value = "/phone/code/send")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Boolean.class)})
+    public ResultVO<Boolean> randomCodeSend(@RequestParam String phoneNumber) {
+        return ResultVO.ok(smsService.randomCodeSend(phoneNumber));
+    }
+
+    @ApiOperation(value = "领取礼包码")
+    @GetMapping(value = "/code/send")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Tuple2.class)})
+    public ResultVO<Tuple2<Boolean, String>> codeSend(@RequestParam Long linkId, @RequestParam String userPhone,
+                                                      @RequestParam String randomCode) {
+        return ResultVO.ok(gameGiftPackCodeLogService.getGiftPackCode(linkId, userPhone, randomCode));
+    }
 }

+ 0 - 36
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/api/SmsController.java

@@ -1,36 +0,0 @@
-package com.zanxiang.game.module.manage.controller.api;
-
-import com.zanxiang.game.module.manage.service.ISmsService;
-import com.zanxiang.module.util.pojo.ResultVO;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * @author : lingfeng
- * @time : 2024-11-04
- * @description : 手机短信接口
- */
-@Slf4j
-@Api(tags = {"手机短信接口"})
-@RestController
-@RequestMapping("/api/sms")
-public class SmsController {
-
-    @Autowired
-    private ISmsService smsService;
-
-    @ApiOperation(value = "手机验证码发送")
-    @GetMapping(value = "/random/code/send")
-    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Boolean.class)})
-    public ResultVO<Boolean> randomCodeSend(@RequestParam String phoneNumber) {
-        return ResultVO.ok(smsService.randomCodeSend(phoneNumber));
-    }
-}

+ 10 - 6
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/GameGiftPackCodeUpdateParam.java

@@ -3,6 +3,8 @@ package com.zanxiang.game.module.manage.pojo.params;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
 import java.util.List;
 
 /**
@@ -14,14 +16,16 @@ import java.util.List;
 public class GameGiftPackCodeUpdateParam {
 
     /**
-     * 礼包码id列表
+     * 链接id
      */
-    @ApiModelProperty(notes = "礼包码id列表, 必传数组")
-    private List<Long> ids;
+    @NotNull(message = "链接id不可为空")
+    @ApiModelProperty(notes = "链接id")
+    private Long linkId;
 
     /**
-     * 是否有效
+     * 礼包码id列表
      */
-    @ApiModelProperty(notes = "是否有效, 必传")
-    private Boolean enabled;
+    @NotEmpty(message = "礼包码id列表不可为空")
+    @ApiModelProperty(notes = "礼包码id列表, 必传数组")
+    private List<Long> ids;
 }

+ 24 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/vo/GameGiftPackCodeLogVO.java

@@ -25,12 +25,36 @@ public class GameGiftPackCodeLogVO {
     @ApiModelProperty(notes = "礼包码")
     private String code;
 
+    /**
+     * 领取结果
+     */
+    @ApiModelProperty(notes = "领取结果")
+    private String msg;
+
+    /**
+     * 用户手机号
+     */
+    @ApiModelProperty(notes = "用户手机号")
+    private String userPhone;
+
     /**
      * 玩家id
      */
     @ApiModelProperty(notes = "玩家id")
     private Integer userId;
 
+    /**
+     * 区服id
+     */
+    @ApiModelProperty(notes = "玩家id")
+    private String serverId;
+
+    /**
+     * 区服名称
+     */
+    @ApiModelProperty(notes = "玩家id")
+    private String serverName;
+
     /**
      * 角色id
      */

+ 36 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/vo/GameGiftPackLinkLogVO.java

@@ -37,6 +37,42 @@ public class GameGiftPackLinkLogVO {
     @ApiModelProperty(notes = "企微用户id")
     private String externalUserId;
 
+    /**
+     * 玩家id
+     */
+    @ApiModelProperty(notes = "玩家id")
+    private Long userId;
+
+    /**
+     * 区服id
+     */
+    @ApiModelProperty(notes = "区服id")
+    private String serverId;
+
+    /**
+     * 区服名称
+     */
+    @ApiModelProperty(notes = "区服名称")
+    private String serverName;
+
+    /**
+     * 角色id
+     */
+    @ApiModelProperty(notes = "角色id")
+    private String roleId;
+
+    /**
+     * 角色名称
+     */
+    @ApiModelProperty(notes = "角色名称")
+    private String roleName;
+
+    /**
+     * 礼包领取记录id
+     */
+    @ApiModelProperty(notes = "礼包领取记录id")
+    private Long codeLogId;
+
     /**
      * 创建时间
      */

+ 11 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IGameGiftPackCodeLogService.java

@@ -2,6 +2,7 @@ package com.zanxiang.game.module.manage.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.sd4324530.jtuple.Tuple2;
 import com.zanxiang.game.module.manage.pojo.params.GameGiftPackCodeLogListParam;
 import com.zanxiang.game.module.manage.pojo.vo.GameGiftPackCodeLogVO;
 import com.zanxiang.game.module.mybatis.entity.GameGiftPackCodeLog;
@@ -20,4 +21,14 @@ public interface IGameGiftPackCodeLogService extends IService<GameGiftPackCodeLo
      * @return : 返回访问记录列表
      */
     IPage<GameGiftPackCodeLogVO> list(GameGiftPackCodeLogListParam param);
+
+    /**
+     * 领取礼包码
+     *
+     * @param linkId     : 访问记录id
+     * @param userPhone  : 用户手机号
+     * @param randomCode : 验证码
+     * @return : 返回礼包码或者错误信息
+     */
+    Tuple2<Boolean, String> getGiftPackCode(Long linkId, String userPhone, String randomCode);
 }

+ 10 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IGameGiftPackLinkLogService.java

@@ -23,6 +23,16 @@ public interface IGameGiftPackLinkLogService extends IService<GameGiftPackLinkLo
      */
     Long linkVisitLogPush(String url);
 
+    /**
+     * 角色验证
+     *
+     * @param linkLogId : 访问记录id
+     * @param serverId  : 区服id
+     * @param roleName  : 角色名称
+     * @return : 返回验证结果
+     */
+    Map<String, Object> gameUserRoleCheck(Long linkLogId, String serverId, String roleName);
+
     /**
      * 分页查新访问记录
      *

+ 14 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IRoleOperateService.java

@@ -2,6 +2,7 @@ package com.zanxiang.game.module.manage.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.zanxiang.game.module.manage.pojo.params.RoleOperateParam;
+import com.zanxiang.game.module.mybatis.entity.GameGiftPackLinkLog;
 import com.zanxiang.game.module.mybatis.entity.RoleOperate;
 
 /**
@@ -14,6 +15,13 @@ import com.zanxiang.game.module.mybatis.entity.RoleOperate;
  */
 public interface IRoleOperateService extends IService<RoleOperate> {
 
+    /**
+     * 角色操作表根据发码器更新
+     *
+     * @param gameGiftPackLinkLog : 发码器访问记录
+     */
+    void roleOperateUpdate(GameGiftPackLinkLog gameGiftPackLinkLog);
+
     /**
      * 玩家是否加企微
      *
@@ -23,5 +31,11 @@ public interface IRoleOperateService extends IService<RoleOperate> {
      */
     boolean userAddCorpWechat(Long gameId, Long userId);
 
+    /**
+     * 角色操作表修改
+     *
+     * @param param : 参数
+     * @return : 返回修改结果
+     */
     boolean modify(RoleOperateParam param);
 }

+ 281 - 10
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/GameGiftPackCodeLogServiceImpl.java

@@ -1,21 +1,40 @@
 package com.zanxiang.game.module.manage.service.impl;
 
+import com.alibaba.nacos.common.utils.CollectionUtils;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.sd4324530.jtuple.Tuple2;
+import com.zanxiang.game.back.base.pojo.enums.OrderStatusEnum;
+import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
+import com.zanxiang.game.module.manage.pojo.dto.GameGiftPackConditionDTO;
+import com.zanxiang.game.module.manage.pojo.dto.UserDTO;
 import com.zanxiang.game.module.manage.pojo.params.GameGiftPackCodeLogListParam;
 import com.zanxiang.game.module.manage.pojo.vo.GameGiftPackCodeLogVO;
-import com.zanxiang.game.module.manage.service.IGameGiftPackCodeLogService;
-import com.zanxiang.game.module.manage.service.IGameUserRoleService;
-import com.zanxiang.game.module.mybatis.entity.GameGiftPackCodeLog;
+import com.zanxiang.game.module.manage.service.*;
+import com.zanxiang.game.module.manage.utils.RedisUtil;
+import com.zanxiang.game.module.mybatis.entity.*;
 import com.zanxiang.game.module.mybatis.mapper.GameGiftPackCodeLogMapper;
+import com.zanxiang.module.redis.service.IDistributedLockComponent;
+import com.zanxiang.module.util.JsonUtil;
 import com.zanxiang.module.util.bean.BeanUtil;
+import com.zanxiang.module.util.exception.BaseException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.util.Strings;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import reactor.util.function.Tuple2;
+import org.springframework.transaction.support.TransactionTemplate;
 
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  * @author : lingfeng
@@ -26,19 +45,271 @@ import java.time.LocalTime;
 public class GameGiftPackCodeLogServiceImpl extends ServiceImpl<GameGiftPackCodeLogMapper, GameGiftPackCodeLog> implements IGameGiftPackCodeLogService {
 
     @Autowired
-    private IGameUserRoleService gameUserRoleService;
+    private ISmsService smsService;
+
+    @Autowired
+    private IUserService userService;
+
+    @Autowired
+    private IOrderService orderService;
+
+    @Autowired
+    private RedisUtil<String> redisUtil;
+
+    @Autowired
+    private IGameServerService gameServerService;
+
+    @Autowired
+    private IRoleOperateService roleOperateService;
+
+    @Autowired
+    private TransactionTemplate transactionTemplate;
+
+    @Autowired
+    private IUserLoginLogService userLoginLogService;
+
+    @Autowired
+    private IGameGiftPackCodeService gameGiftPackCodeService;
+
+    @Autowired
+    private IGameGiftPackLinkService gameGiftPackLinkService;
+
+    @Autowired
+    private IDistributedLockComponent distributedLockComponent;
+
+    @Autowired
+    private IGameGiftPackLinkLogService gameGiftPackLinkLogService;
 
     @Override
     public IPage<GameGiftPackCodeLogVO> list(GameGiftPackCodeLogListParam param) {
-        return page(param.toPage(), new QueryWrapper<GameGiftPackCodeLog>().lambda()
+        IPage<GameGiftPackCodeLog> codeLogIPage = page(param.toPage(), new QueryWrapper<GameGiftPackCodeLog>().lambda()
                 .eq(GameGiftPackCodeLog::getLinkId, param.getLinkId())
                 .ge(param.getCreateBeginTime() != null, GameGiftPackCodeLog::getCreateTime, param.getCreateBeginTime() == null ? null : LocalDateTime.of(param.getCreateBeginTime(), LocalTime.MIN))
                 .le(param.getCreateEndTime() != null, GameGiftPackCodeLog::getCreateTime, param.getCreateEndTime() == null ? null : LocalDateTime.of(param.getCreateEndTime(), LocalTime.MAX))
-                .orderByDesc(GameGiftPackCodeLog::getCreateTime)
-        ).convert(log -> BeanUtil.copy(log, GameGiftPackCodeLogVO.class));
+                .orderByDesc(GameGiftPackCodeLog::getCreateTime));
+        IPage<GameGiftPackCodeLogVO> result = new Page<>(codeLogIPage.getCurrent(), codeLogIPage.getSize(), codeLogIPage.getTotal());
+        if (CollectionUtils.isNotEmpty(codeLogIPage.getRecords())) {
+            List<GameGiftPackCodeLog> records = codeLogIPage.getRecords();
+            List<String> serverIds = records.stream().map(GameGiftPackCodeLog::getServerId).collect(Collectors.toList());
+            Map<String, String> gameServerMap = gameServerService.list(new LambdaQueryWrapper<GameServer>()
+                    .eq(GameServer::getIsSourceServer, Boolean.TRUE)
+                    .in(GameServer::getServerId, serverIds)
+            ).stream().collect(Collectors.toMap(GameServer::getServerId, GameServer::getServerName));
+            result.setRecords(this.toVOBatch(records, gameServerMap));
+        }
+        return result;
+    }
+
+    private List<GameGiftPackCodeLogVO> toVOBatch(List<GameGiftPackCodeLog> codeLogList, Map<String, String> gameServerMap) {
+        return codeLogList.stream().map(codeLog -> {
+            GameGiftPackCodeLogVO gameGiftPackCodeLogVO = BeanUtil.copy(codeLog, GameGiftPackCodeLogVO.class);
+            String userPhone = codeLog.getUserPhone();
+            String phoneNum = userPhone.substring(0, 3) + " **** " + userPhone.substring(userPhone.length() - 4);
+            gameGiftPackCodeLogVO.setUserPhone(phoneNum);
+            gameGiftPackCodeLogVO.setServerName(gameServerMap.get(codeLog.getServerId()));
+            return gameGiftPackCodeLogVO;
+        }).collect(Collectors.toList());
+    }
+
+    @Override
+    public Tuple2<Boolean, String> getGiftPackCode(Long linkId, String userPhone, String randomCode) {
+        //线程锁key
+        String lockKey = RedisKeyConstant.GAME_GIFT_PACK_LOCK + userPhone;
+        //线程锁 5 分钟, 防止同一用户重复请求
+        if (!distributedLockComponent.doLock(lockKey, 0L, 5L, TimeUnit.MINUTES)) {
+            throw new BaseException("操作频繁, 请稍后重试");
+        }
+        GameGiftPackLinkLog gameGiftPackLinkLog = gameGiftPackLinkLogService.getById(linkId);
+        assert gameGiftPackLinkLog != null : "参数错误, 链接访问日志信息不存在";
+        //判断验证是通过的
+        Long userId = gameGiftPackLinkLog.getUserId();
+        assert StringUtils.isNoneBlank(userId == null ? null : userId.toString(), gameGiftPackLinkLog.getServerId(),
+                gameGiftPackLinkLog.getRoleId(), gameGiftPackLinkLog.getRoleName()) : "参数错误, 链接访问记录信息缺失";
+        //获取礼包码, 且执行释放锁动作
+        try {
+            return this.getRandomCode(randomCode, userPhone, gameGiftPackLinkLog);
+        } finally {
+            distributedLockComponent.unlock(lockKey);
+        }
+    }
+
+    private Tuple2<Boolean, String> getRandomCode(String randomCode, String userPhone, GameGiftPackLinkLog linkLog) {
+        //手机验证码校验
+        smsService.randomCodeCheck(userPhone, randomCode);
+        //查询记录, 判断是否重复领取, 重复领取直接返回之前领取的礼包码
+        Tuple2<Boolean, String> repeatCheck = this.repeatCheck(linkLog);
+        if (repeatCheck.first) {
+            return Tuple2.with(Boolean.TRUE, repeatCheck.second);
+        }
+        //异步更新角色操作表
+        roleOperateService.roleOperateUpdate(linkLog);
+        //构造记录
+        GameGiftPackCodeLog gameGiftPackCodeLog = this.transform(linkLog, userPhone);
+        //从缓存中获取一个礼包码id, 如果缓存中不存在则是领完了
+        String codeId = redisUtil.popOfSet(RedisKeyConstant.GAME_GIFT_PACK_CODE + linkLog.getId());
+        if (Strings.isBlank(codeId)) {
+            String msg = "该礼包已被领取完, 请联系客服小姐姐领取其他礼包";
+            gameGiftPackCodeLog.setMsg(msg);
+            super.save(gameGiftPackCodeLog);
+            return Tuple2.with(Boolean.FALSE, msg);
+        }
+        //查询礼包码具体信息, 礼包码必须存在, 且未被领取, 否则数据错误
+        GameGiftPackCode gameGiftPackCode = gameGiftPackCodeService.getById(Long.valueOf(codeId));
+        assert gameGiftPackCode != null && !gameGiftPackCode.getIsSend() : "礼包码数据错误, 请联系客服小姐姐处理";
+        //判断是否满足领取条件
+        Tuple2<Boolean, String> conditionCheck = this.conditionCheck(linkLog);
+        //设置判定消息
+        gameGiftPackCodeLog.setMsg(conditionCheck.second);
+        //判定不通过, 返回错误消息提示
+        if (!conditionCheck.first) {
+            super.save(gameGiftPackCodeLog);
+            return Tuple2.with(Boolean.FALSE, "角色不满足该礼包领取条件, 请联系客服领取其他礼包");
+        }
+        //成功领取礼包码记录数据更新
+        this.codeSendUpdate(gameGiftPackCode, linkLog, gameGiftPackCodeLog);
+        //返回礼包码
+        return Tuple2.with(Boolean.TRUE, gameGiftPackCode.getCode());
+    }
+
+    private Tuple2<Boolean, String> repeatCheck(GameGiftPackLinkLog gameGiftPackLinkLog) {
+        GameGiftPackCodeLog giftPackCodeLog = super.getOne(new LambdaQueryWrapper<GameGiftPackCodeLog>()
+                .eq(GameGiftPackCodeLog::getLinkId, gameGiftPackLinkLog.getLinkId())
+                .eq(GameGiftPackCodeLog::getGameId, gameGiftPackLinkLog.getGameId())
+                .eq(GameGiftPackCodeLog::getRoleId, gameGiftPackLinkLog.getRoleId())
+                .isNotNull(GameGiftPackCodeLog::getCode));
+        return Tuple2.with(giftPackCodeLog != null, giftPackCodeLog != null ? giftPackCodeLog.getCode() : null);
+    }
+
+    private void codeSendUpdate(GameGiftPackCode gameGiftPackCode, GameGiftPackLinkLog gameGiftPackLinkLog,
+                                GameGiftPackCodeLog gameGiftPackCodeLog) {
+        //在同一个事物中进行表更新
+        transactionTemplate.execute(status -> {
+            //礼包码领取状态修改保存
+            gameGiftPackCode.setIsSend(Boolean.TRUE);
+            gameGiftPackCodeService.updateById(gameGiftPackCode);
+            //领取记录修改保存
+            gameGiftPackCodeLog.setCode(gameGiftPackCode.getCode());
+            super.save(gameGiftPackCodeLog);
+            //更新链接访问日志关联id
+            gameGiftPackLinkLog.setCodeLogId(gameGiftPackCodeLog.getId());
+            gameGiftPackLinkLog.setUpdateTime(LocalDateTime.now());
+            gameGiftPackLinkLogService.updateById(gameGiftPackLinkLog);
+            return Boolean.TRUE;
+        });
+    }
+
+    private GameGiftPackCodeLog transform(GameGiftPackLinkLog gameGiftPackLinkLog, String userPhone) {
+        return GameGiftPackCodeLog.builder()
+                .linkId(gameGiftPackLinkLog.getLinkId())
+                .userPhone(userPhone)
+                .gameId(gameGiftPackLinkLog.getGameId())
+                .userId(gameGiftPackLinkLog.getUserId())
+                .serverId(gameGiftPackLinkLog.getServerId())
+                .roleId(gameGiftPackLinkLog.getRoleId())
+                .roleName(gameGiftPackLinkLog.getRoleName())
+                .corpId(gameGiftPackLinkLog.getCorpId())
+                .corpUserId(gameGiftPackLinkLog.getCorpUserId())
+                .externalUserId(gameGiftPackLinkLog.getExternalUserId())
+                .linkLogId(gameGiftPackLinkLog.getId())
+                .createTime(LocalDateTime.now())
+                .build();
+    }
+
+    private Tuple2<Boolean, String> conditionCheck(GameGiftPackLinkLog gameGiftPackLinkLog) {
+        GameGiftPackLink giftPackLink = gameGiftPackLinkService.getById(gameGiftPackLinkLog.getLinkId());
+        assert giftPackLink != null : "参数错误, 礼包链接信息不存在";
+        String codeCheck = giftPackLink.getCodeCheck();
+        if (Strings.isBlank(codeCheck)) {
+            return Tuple2.with(Boolean.TRUE, "领取成功, 礼包码领取条件 - 不存在");
+        }
+        GameGiftPackConditionDTO conditionDTO = JsonUtil.toObj(codeCheck, GameGiftPackConditionDTO.class);
+        //当前时间
+        LocalDateTime nowTime = LocalDateTime.now();
+        //注册时间区间判断
+        if (!this.regTimeCheck(nowTime, gameGiftPackLinkLog, conditionDTO.getRegTime())) {
+            return Tuple2.with(Boolean.FALSE, "注册时间区间 - 判定不通过");
+        }
+        //未登录时间区间判断
+        if (!this.unLoginCheck(nowTime, gameGiftPackLinkLog, conditionDTO.getUnLogin())) {
+            return Tuple2.with(Boolean.FALSE, "未登录时间区间 - 判定不通过");
+        }
+        //付费区间判断
+        if (!this.payCheck(gameGiftPackLinkLog, conditionDTO.getPay())) {
+            return Tuple2.with(Boolean.FALSE, "付费区间判断 - 判定不通过");
+        }
+        //判定通过
+        return Tuple2.with(Boolean.TRUE, "领取成功, 礼包码领取条件 - 全部判定通过");
+    }
+
+    private boolean regTimeCheck(LocalDateTime nowTime, GameGiftPackLinkLog gameGiftPackLinkLog,
+                                 GameGiftPackConditionDTO.RangeBean regTimeBean) {
+        //缺少条件参数, 无法判定, 直接返回通过
+        if (regTimeBean == null || regTimeBean.getMin() == null || regTimeBean.getMax() == null) {
+            return true;
+        }
+        //查询玩家信息注册时间
+        UserDTO userDTO = userService.getById(gameGiftPackLinkLog.getUserId());
+        //玩家信息为空, 无法判定是否满足条件, 返回不通过
+        if (userDTO == null || userDTO.getCreateTime() == null) {
+            return false;
+        }
+        //玩家注册时间
+        LocalDateTime userRegTime = userDTO.getCreateTime();
+        //计算时间区间
+        LocalDateTime startTime = nowTime.minusMinutes(regTimeBean.getMin());
+        LocalDateTime endTime = nowTime.plusMinutes(regTimeBean.getMax());
+        //返回判定
+        return userRegTime.isAfter(startTime) && userRegTime.isBefore(endTime);
+    }
+
+    private boolean unLoginCheck(LocalDateTime nowTime, GameGiftPackLinkLog gameGiftPackLinkLog,
+                                 GameGiftPackConditionDTO.RangeBean unLoginBean) {
+        //缺少条件参数, 直接返回通过
+        if (unLoginBean == null || unLoginBean.getMin() == null || unLoginBean.getMax() == null) {
+            return true;
+        }
+        //查询玩家最后登录时间
+        UserLoginLog userLoginLog = userLoginLogService.getOne(new LambdaQueryWrapper<UserLoginLog>()
+                .eq(UserLoginLog::getUserId, gameGiftPackLinkLog.getUserId())
+                .eq(UserLoginLog::getGameId, gameGiftPackLinkLog.getGameId())
+                .eq(UserLoginLog::getRoleId, gameGiftPackLinkLog.getRoleId())
+                .orderByDesc(UserLoginLog::getCreateTime)
+                .last("limit 1"));
+        //登录记录为空, 无法判定是否满足条件, 返回不通过
+        if (userLoginLog == null || userLoginLog.getCreateTime() == null) {
+            return false;
+        }
+        //最后登录时间
+        LocalDateTime lastLoginTime = userLoginLog.getCreateTime();
+        //计算时间区间
+        LocalDateTime startTime = nowTime.minusMinutes(unLoginBean.getMin());
+        LocalDateTime endTime = nowTime.plusMinutes(unLoginBean.getMax());
+        //返回判定
+        return lastLoginTime.isBefore(startTime) || lastLoginTime.isAfter(endTime);
     }
 
-    public Tuple2<Boolean, String> gameRoleCheck(String gameServerId, String roleName) {
-        return null;
+    private boolean payCheck(GameGiftPackLinkLog gameGiftPackLinkLog, GameGiftPackConditionDTO.RangeBean payBean) {
+        //缺少条件参数, 无法判定, 直接返回通过
+        if (payBean == null || payBean.getMin() == null || payBean.getMax() == null) {
+            return true;
+        }
+        //查询玩家支付成功的订单信息
+        List<Order> userOrderList = orderService.list(new LambdaQueryWrapper<Order>()
+                .select(Order::getRealAmount)
+                .eq(Order::getUserId, gameGiftPackLinkLog.getUserId())
+                .eq(Order::getGameId, gameGiftPackLinkLog.getGameId())
+                .eq(Order::getRoleId, gameGiftPackLinkLog.getRoleId())
+                .eq(Order::getStatus, OrderStatusEnum.SUCCESS_PAY.getValue()));
+        //充值订单为空, 返回不通过
+        if (CollectionUtils.isEmpty(userOrderList)) {
+            return false;
+        }
+        //玩家充值总金额
+        BigDecimal userPaySum = userOrderList.stream().map(Order::getRealAmount)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        //返回判定
+        return userPaySum.compareTo(BigDecimal.valueOf(payBean.getMin())) >= 0
+                && userPaySum.compareTo(BigDecimal.valueOf(payBean.getMax())) <= 0;
     }
 }

+ 43 - 22
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/GameGiftPackCodeServiceImpl.java

@@ -9,28 +9,29 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.erp.base.ErpServer;
 import com.zanxiang.erp.base.rpc.ISysUserRpc;
 import com.zanxiang.erp.security.util.SecurityUtil;
+import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
 import com.zanxiang.game.module.manage.pojo.params.GameGiftPackCodeAddParam;
 import com.zanxiang.game.module.manage.pojo.params.GameGiftPackCodeListParam;
 import com.zanxiang.game.module.manage.pojo.params.GameGiftPackCodeUpdateParam;
 import com.zanxiang.game.module.manage.pojo.vo.GameGiftPackCodeVO;
 import com.zanxiang.game.module.manage.service.IGameGiftPackCodeService;
 import com.zanxiang.game.module.manage.service.IGameGiftPackLinkService;
+import com.zanxiang.game.module.manage.utils.RedisUtil;
 import com.zanxiang.game.module.mybatis.entity.GameGiftPackCode;
 import com.zanxiang.game.module.mybatis.entity.GameGiftPackLink;
 import com.zanxiang.game.module.mybatis.mapper.GameGiftPackCodeMapper;
 import com.zanxiang.module.util.bean.BeanUtil;
+import com.zanxiang.module.util.exception.BaseException;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.logging.log4j.util.Strings;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
 import java.time.LocalTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -48,17 +49,21 @@ public class GameGiftPackCodeServiceImpl extends ServiceImpl<GameGiftPackCodeMap
     @Autowired
     private IGameGiftPackLinkService gameGiftPackLinkService;
 
+    @Autowired
+    private RedisUtil<String> redisUtil;
+
     @Override
     public IPage<GameGiftPackCodeVO> list(GameGiftPackCodeListParam param) {
         IPage<GameGiftPackCode> giftPackLinkIPage = page(param.toPage(), new QueryWrapper<GameGiftPackCode>().lambda()
                 .eq(GameGiftPackCode::getLinkId, param.getLinkId())
+                .eq(GameGiftPackCode::getEnabled, Boolean.TRUE)
                 .eq(Strings.isNotBlank(param.getCode()), GameGiftPackCode::getCode, param.getCode())
                 .eq(param.getEnabled() != null, GameGiftPackCode::getEnabled, param.getEnabled())
                 .ge(param.getCreateBeginTime() != null, GameGiftPackCode::getCreateTime, param.getCreateBeginTime() == null ? null : LocalDateTime.of(param.getCreateBeginTime(), LocalTime.MIN))
                 .le(param.getCreateEndTime() != null, GameGiftPackCode::getCreateTime, param.getCreateEndTime() == null ? null : LocalDateTime.of(param.getCreateEndTime(), LocalTime.MAX))
                 .ge(param.getUpdateBeginTime() != null, GameGiftPackCode::getUpdateTime, param.getUpdateBeginTime() == null ? null : LocalDateTime.of(param.getUpdateBeginTime(), LocalTime.MIN))
                 .le(param.getUpdateEndTime() != null, GameGiftPackCode::getUpdateTime, param.getUpdateEndTime() == null ? null : LocalDateTime.of(param.getUpdateEndTime(), LocalTime.MAX))
-                .orderByDesc(GameGiftPackCode::getUpdateTime));
+                .orderByDesc(GameGiftPackCode::getCreateTime));
         IPage<GameGiftPackCodeVO> result = new Page<>(giftPackLinkIPage.getCurrent(), giftPackLinkIPage.getSize(), giftPackLinkIPage.getTotal());
         if (CollectionUtils.isNotEmpty(giftPackLinkIPage.getRecords())) {
             result.setRecords(this.toVOBatch(giftPackLinkIPage.getRecords()));
@@ -83,6 +88,7 @@ public class GameGiftPackCodeServiceImpl extends ServiceImpl<GameGiftPackCodeMap
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public boolean addGiftPackCode(GameGiftPackCodeAddParam param) {
         //查询礼包码链接信息
         GameGiftPackLink gameGiftPackLink = gameGiftPackLinkService.getOne(new LambdaQueryWrapper<GameGiftPackLink>()
@@ -101,31 +107,46 @@ public class GameGiftPackCodeServiceImpl extends ServiceImpl<GameGiftPackCodeMap
         //构造新的礼包码
         List<GameGiftPackCode> saveList = param.getCodeList().stream()
                 .filter(code -> !existCodeList.contains(code))
-                .map(code -> GameGiftPackCode.builder()
-                        .linkId(param.getLinkId())
-                        .gameId(param.getGameId())
-                        .code(code)
-                        .enabled(Boolean.TRUE)
-                        .createBy(SecurityUtil.getUserId())
-                        .createTime(LocalDateTime.now())
-                        .updateTime(LocalDateTime.now())
-                        .build())
+                .map(code -> this.transform(param, code))
                 .collect(Collectors.toList());
         //保存返回
-        return super.saveBatch(saveList);
+        super.saveBatch(saveList);
+        //将礼包码主键添加到缓存
+        String[] codeIdArray = saveList.stream().map(GameGiftPackCode::getId).map(Object::toString).toArray(String[]::new);
+        if (redisUtil.addToSet(RedisKeyConstant.GAME_GIFT_PACK_CODE + param.getLinkId(), codeIdArray)) {
+            return true;
+        }
+        throw new BaseException("添加礼包码异常, 添加到缓存失败列表");
+    }
+
+    private GameGiftPackCode transform(GameGiftPackCodeAddParam param, String code) {
+        return GameGiftPackCode.builder()
+                .linkId(param.getLinkId())
+                .gameId(param.getGameId())
+                .code(code)
+                .enabled(Boolean.TRUE)
+                .isSend(Boolean.FALSE)
+                .createBy(SecurityUtil.getUserId())
+                .createTime(LocalDateTime.now())
+                .updateTime(LocalDateTime.now())
+                .build();
     }
 
     @Override
     public boolean updateGiftPackCode(GameGiftPackCodeUpdateParam param) {
+        String giftPackCodeKey = RedisKeyConstant.GAME_GIFT_PACK_CODE + param.getLinkId();
+        String[] giftPackCodeIdArray = param.getIds().stream()
+                .filter(id -> redisUtil.isMemberInSet(giftPackCodeKey, String.valueOf(id)))
+                .map(Object::toString)
+                .toArray(String[]::new);
+        //先从缓存中移除
+        redisUtil.removeOfSet(giftPackCodeKey, giftPackCodeIdArray);
+        List<Long> giftPackCodeIdList = Arrays.stream(giftPackCodeIdArray).map(Long::parseLong).collect(Collectors.toList());
         return super.update(new LambdaUpdateWrapper<GameGiftPackCode>()
-                .set(GameGiftPackCode::getEnabled, param.getEnabled())
+                .set(GameGiftPackCode::getEnabled, Boolean.FALSE)
                 .set(GameGiftPackCode::getUpdateBy, SecurityUtil.getUserId())
                 .set(GameGiftPackCode::getUpdateTime, LocalDateTime.now())
-                .in(GameGiftPackCode::getId, param.getIds())
+                .in(GameGiftPackCode::getId, giftPackCodeIdList)
         );
     }
-}
-
-
-
-
+}

+ 89 - 18
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/GameGiftPackLinkLogServiceImpl.java

@@ -1,24 +1,20 @@
 package com.zanxiang.game.module.manage.service.impl;
 
-import com.alibaba.nacos.common.utils.CollectionUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.game.module.manage.pojo.dto.GameDTO;
 import com.zanxiang.game.module.manage.pojo.params.GameGiftPackLinkLogListParam;
 import com.zanxiang.game.module.manage.pojo.vo.GameGiftPackLinkLogVO;
-import com.zanxiang.game.module.manage.service.IGameGiftPackLinkLogService;
-import com.zanxiang.game.module.manage.service.IGameGiftPackLinkService;
-import com.zanxiang.game.module.manage.service.IGameServerService;
-import com.zanxiang.game.module.manage.service.IGameService;
-import com.zanxiang.game.module.mybatis.entity.GameGiftPackLink;
-import com.zanxiang.game.module.mybatis.entity.GameGiftPackLinkLog;
-import com.zanxiang.game.module.mybatis.entity.GameServer;
+import com.zanxiang.game.module.manage.service.*;
+import com.zanxiang.game.module.mybatis.entity.*;
 import com.zanxiang.game.module.mybatis.mapper.GameGiftPackLinkLogMapper;
 import com.zanxiang.module.util.bean.BeanUtil;
 import com.zanxiang.module.util.exception.BaseException;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.util.Strings;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -29,6 +25,7 @@ import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
@@ -47,17 +44,41 @@ public class GameGiftPackLinkLogServiceImpl extends ServiceImpl<GameGiftPackLink
     @Autowired
     private IGameServerService gameServerService;
 
+    @Autowired
+    private IRoleOperateService roleOperateService;
+
+    @Autowired
+    private IGameUserRoleService gameUserRoleService;
+
     @Autowired
     private IGameGiftPackLinkService gameGiftPackLinkService;
 
     @Override
     public IPage<GameGiftPackLinkLogVO> list(GameGiftPackLinkLogListParam param) {
-        return page(param.toPage(), new QueryWrapper<GameGiftPackLinkLog>().lambda()
+        IPage<GameGiftPackLinkLog> linkLogIPage = page(param.toPage(), new QueryWrapper<GameGiftPackLinkLog>().lambda()
                 .eq(GameGiftPackLinkLog::getLinkId, param.getLinkId())
                 .ge(param.getCreateBeginTime() != null, GameGiftPackLinkLog::getCreateTime, param.getCreateBeginTime() == null ? null : LocalDateTime.of(param.getCreateBeginTime(), LocalTime.MIN))
                 .le(param.getCreateEndTime() != null, GameGiftPackLinkLog::getCreateTime, param.getCreateEndTime() == null ? null : LocalDateTime.of(param.getCreateEndTime(), LocalTime.MAX))
-                .orderByDesc(GameGiftPackLinkLog::getCreateTime)
-        ).convert(log -> BeanUtil.copy(log, GameGiftPackLinkLogVO.class));
+                .orderByDesc(GameGiftPackLinkLog::getCreateTime));
+        IPage<GameGiftPackLinkLogVO> result = new Page<>(linkLogIPage.getCurrent(), linkLogIPage.getSize(), linkLogIPage.getTotal());
+        if (CollectionUtils.isNotEmpty(linkLogIPage.getRecords())) {
+            List<GameGiftPackLinkLog> records = linkLogIPage.getRecords();
+            List<String> serverIds = records.stream().map(GameGiftPackLinkLog::getServerId).collect(Collectors.toList());
+            Map<String, String> gameServerMap = gameServerService.list(new LambdaQueryWrapper<GameServer>()
+                    .in(GameServer::getServerId, serverIds)
+                    .eq(GameServer::getIsSourceServer, Boolean.TRUE)
+            ).stream().collect(Collectors.toMap(GameServer::getServerId, GameServer::getServerName));
+            result.setRecords(this.toVOBatch(records, gameServerMap));
+        }
+        return result;
+    }
+
+    private List<GameGiftPackLinkLogVO> toVOBatch(List<GameGiftPackLinkLog> linkLogList, Map<String, String> gameServerMap) {
+        return linkLogList.stream().map(linkLog -> {
+            GameGiftPackLinkLogVO gameGiftPackCodeLogVO = BeanUtil.copy(linkLog, GameGiftPackLinkLogVO.class);
+            gameGiftPackCodeLogVO.setServerName(gameServerMap.get(linkLog.getServerId()));
+            return gameGiftPackCodeLogVO;
+        }).collect(Collectors.toList());
     }
 
     @Override
@@ -75,12 +96,60 @@ public class GameGiftPackLinkLogServiceImpl extends ServiceImpl<GameGiftPackLink
         ).stream().collect(Collectors.toMap(GameServer::getServerId, GameServer::getServerName));
     }
 
+    @Override
+    public Map<String, Object> gameUserRoleCheck(Long linkLogId, String serverId, String roleName) {
+        //查询访问日志
+        GameGiftPackLinkLog gameGiftPackLinkLog = super.getById(linkLogId);
+        assert gameGiftPackLinkLog != null : "参数错误, 链接访问日志信息不存在";
+        //构造返回结果
+        Map<String, Object> resultMap = new HashMap<>();
+        //查询角色
+        List<GameUserRole> gameUserRoleList = gameUserRoleService.list(new LambdaQueryWrapper<GameUserRole>()
+                .eq(GameUserRole::getGameId, gameGiftPackLinkLog.getGameId())
+                .eq(GameUserRole::getServerId, serverId)
+                .eq(GameUserRole::getRoleName, roleName));
+        //角色查询结果不存在, 或者为多个
+        if (gameUserRoleList.size() != 1) {
+            resultMap.put("result", Boolean.FALSE);
+            resultMap.put("msg", "角色名称检测不通过");
+            return resultMap;
+        }
+        //角色信息
+        GameUserRole gameUserRole = gameUserRoleList.get(0);
+        //查询是否已经绑定手机号
+        RoleOperate roleOperate = roleOperateService.getOne(new LambdaQueryWrapper<RoleOperate>()
+                .eq(RoleOperate::getGameId, gameUserRole.getGameId())
+                .eq(RoleOperate::getServerId, gameUserRole.getServerId())
+                .eq(RoleOperate::getRoleId, gameUserRole.getRoleId()));
+        String userPhone = Strings.isBlank(roleOperate.getUserPhone()) ? null : roleOperate.getUserPhone();
+        //返回结果
+        resultMap.put("result", Boolean.TRUE);
+        resultMap.put("msg", "角色名称检测成功");
+        resultMap.put("roleId", gameUserRole.getRoleId());
+        if (Strings.isNotBlank(userPhone)) {
+            resultMap.put("userPhone", userPhone);
+        }
+        //更新链接访问记录
+        gameGiftPackLinkLog.setUserId(gameUserRole.getUserId());
+        gameGiftPackLinkLog.setServerId(gameUserRole.getServerId());
+        gameGiftPackLinkLog.setRoleId(gameUserRole.getRoleId());
+        gameGiftPackLinkLog.setRoleName(gameUserRole.getRoleName());
+        gameGiftPackLinkLog.setUpdateTime(LocalDateTime.now());
+        super.updateById(gameGiftPackLinkLog);
+        return resultMap;
+    }
+
     @Override
     public Long linkVisitLogPush(String url) {
         Map<String, String> urlParameter = this.getUrlParameter(url);
+        String linkUrl = urlParameter.get("linkUrl");
         String gameId = urlParameter.get("gameId");
         String codeType = urlParameter.get("codeType");
-        if (CollectionUtils.isMapEmpty(urlParameter) || StringUtils.isAnyEmpty(gameId, codeType)) {
+        String corpId = urlParameter.get("corpId");
+        String corpUserId = urlParameter.get("corpUserId");
+        String externalUserId = urlParameter.get("externalUserId");
+        //参数判断
+        if (StringUtils.isAnyEmpty(linkUrl, gameId, codeType, corpId, corpUserId, externalUserId)) {
             throw new BaseException("非法链接请求, 链接参数解析异常");
         }
         //查询链接信息
@@ -89,20 +158,22 @@ public class GameGiftPackLinkLogServiceImpl extends ServiceImpl<GameGiftPackLink
                 .eq(GameGiftPackLink::getCodeType, codeType));
         assert gameGiftPackLink != null : "非法链接请求, 链接信息不存在";
         //构造
-        GameGiftPackLinkLog gameGiftPackLinkLog = this.transform(gameGiftPackLink, urlParameter);
+        GameGiftPackLinkLog gameGiftPackLinkLog = this.transform(gameGiftPackLink, linkUrl, corpId, corpUserId, externalUserId);
         super.save(gameGiftPackLinkLog);
         return gameGiftPackLinkLog.getId();
     }
 
-    private GameGiftPackLinkLog transform(GameGiftPackLink gameGiftPackLink, Map<String, String> urlParameter) {
+    private GameGiftPackLinkLog transform(GameGiftPackLink gameGiftPackLink, String linkUrl, String corpId,
+                                          String corpUserId, String externalUserId) {
         return GameGiftPackLinkLog.builder()
                 .linkId(gameGiftPackLink.getId())
-                .linkUrl(urlParameter.get("linkUrl"))
+                .linkUrl(linkUrl)
                 .gameId(gameGiftPackLink.getGameId())
-                .corpId(urlParameter.get("corpId"))
-                .corpUserId(urlParameter.get("corpUserId"))
-                .externalUserId(urlParameter.get("externalUserId"))
+                .corpId(corpId)
+                .corpUserId(corpUserId)
+                .externalUserId(externalUserId)
                 .createTime(LocalDateTime.now())
+                .updateTime(LocalDateTime.now())
                 .build();
     }
 

+ 40 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/RoleOperateServiceImpl.java

@@ -5,8 +5,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.erp.security.util.SecurityUtil;
 import com.zanxiang.game.module.manage.pojo.params.RoleOperateParam;
 import com.zanxiang.game.module.manage.service.IRoleOperateService;
+import com.zanxiang.game.module.mybatis.entity.GameGiftPackLinkLog;
 import com.zanxiang.game.module.mybatis.entity.RoleOperate;
 import com.zanxiang.game.module.mybatis.mapper.RoleOperateMapper;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -25,6 +27,44 @@ import java.util.stream.Collectors;
 @Service
 public class RoleOperateServiceImpl extends ServiceImpl<RoleOperateMapper, RoleOperate> implements IRoleOperateService {
 
+    @Async
+    @Override
+    public void roleOperateUpdate(GameGiftPackLinkLog gameGiftPackLinkLog) {
+        RoleOperate roleOperate = super.getOne(new LambdaQueryWrapper<RoleOperate>()
+                .eq(RoleOperate::getGameId, gameGiftPackLinkLog.getGameId())
+                .eq(RoleOperate::getServerId, gameGiftPackLinkLog.getServerId())
+                .eq(RoleOperate::getUserId, gameGiftPackLinkLog.getUserId())
+                .eq(RoleOperate::getRoleId, gameGiftPackLinkLog.getRoleId()));
+        if (roleOperate == null) {
+            roleOperate = this.transform(gameGiftPackLinkLog);
+        } else {
+            roleOperate.setCorpId(gameGiftPackLinkLog.getCorpId());
+            roleOperate.setExternalUserId(gameGiftPackLinkLog.getExternalUserId());
+            roleOperate.setAddCorpUserId(gameGiftPackLinkLog.getCorpUserId());
+            roleOperate.setIsAddCorpWechat(1);
+            roleOperate.setUpdateBy(RoleOperate.SYSTEM_OPERATE);
+            roleOperate.setUpdateTime(LocalDateTime.now());
+        }
+        super.saveOrUpdate(roleOperate);
+    }
+
+    private RoleOperate transform(GameGiftPackLinkLog gameGiftPackLinkLog) {
+        return RoleOperate.builder()
+                .gameId(gameGiftPackLinkLog.getGameId())
+                .serverId(gameGiftPackLinkLog.getServerId())
+                .userId(gameGiftPackLinkLog.getUserId())
+                .roleId(gameGiftPackLinkLog.getRoleId())
+                .corpId(gameGiftPackLinkLog.getCorpId())
+                .externalUserId(gameGiftPackLinkLog.getExternalUserId())
+                .addCorpUserId(gameGiftPackLinkLog.getCorpUserId())
+                .isAddCorpWechat(1)
+                .createBy(RoleOperate.SYSTEM_OPERATE)
+                .createTime(LocalDateTime.now())
+                .updateBy(RoleOperate.SYSTEM_OPERATE)
+                .updateTime(LocalDateTime.now())
+                .build();
+    }
+
     @Override
     public boolean userAddCorpWechat(Long gameId, Long userId) {
         return super.count(new LambdaQueryWrapper<RoleOperate>()

+ 1 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/SmsServiceImpl.java

@@ -36,7 +36,7 @@ public class SmsServiceImpl implements ISmsService {
         String smsKey = RedisKeyConstant.SMS_PHONE_KEY + "_" + phoneNumber;
         assert Strings.isBlank(redisUtil.getCache(smsKey)) : "验证码已发送请稍后再试";
         //发送验证码
-        String randomCode = RandomUtil.randomNumbers(6);
+        String randomCode = RandomUtil.randomNumbers(4);
         //发送短信验证码
         this.smsSendApi(randomCode, phoneNumber);
         //发送成功设置缓存, 时效5分钟

+ 16 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/utils/RedisUtil.java

@@ -128,6 +128,22 @@ public class RedisUtil<T> {
         return false;
     }
 
+    /**
+     * set集合随机删除元素, 且返回删除的结果
+     *
+     * @param key : 缓存key
+     * @return : 返回删除的值
+     */
+    public T popOfSet(String key) {
+        try {
+            SetOperations<String, T> setOperations = redisTemplate.opsForSet();
+            return setOperations.pop(key);
+        } catch (Exception e) {
+            log.error("Set随机删除失败,key : {}, e : {}", key, e.getMessage());
+        }
+        return null;
+    }
+
     /**
      * 判断元素是否存在于set集合
      *

+ 5 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GameGiftPackCode.java

@@ -49,6 +49,11 @@ public class GameGiftPackCode implements Serializable {
      */
     private Boolean enabled;
 
+    /**
+     * 是否发送
+     */
+    private Boolean isSend;
+
     /**
      * 创建者
      */

+ 16 - 6
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GameGiftPackCodeLog.java

@@ -34,11 +34,21 @@ public class GameGiftPackCodeLog implements Serializable {
      */
     private String code;
 
+    /**
+     * 领取失败原因
+     */
+    private String msg;
+
     /**
      * 链接id
      */
     private Long linkId;
 
+    /**
+     * 用户手机号
+     */
+    private String userPhone;
+
     /**
      * 游戏id
      */
@@ -47,7 +57,12 @@ public class GameGiftPackCodeLog implements Serializable {
     /**
      * 玩家id
      */
-    private Integer userId;
+    private Long userId;
+
+    /**
+     * 区服id
+     */
+    private String serverId;
 
     /**
      * 角色id
@@ -83,9 +98,4 @@ public class GameGiftPackCodeLog implements Serializable {
      * 创建时间
      */
     private LocalDateTime createTime;
-
-    /**
-     * 更新时间
-     */
-    private LocalDateTime updateTime;
 }

+ 20 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GameGiftPackLinkLog.java

@@ -44,6 +44,26 @@ public class GameGiftPackLinkLog implements Serializable {
      */
     private Long gameId;
 
+    /**
+     * 玩家id
+     */
+    private Long userId;
+
+    /**
+     * 区服id
+     */
+    private String serverId;
+
+    /**
+     * 角色id
+     */
+    private String roleId;
+
+    /**
+     * 角色名称
+     */
+    private String roleName;
+
     /**
      * 企业id
      */