|
|
@@ -0,0 +1,319 @@
|
|
|
+package com.td.boss.game.complayersattri.service;
|
|
|
+
|
|
|
+import cn.hutool.core.convert.Convert;
|
|
|
+import cn.hutool.core.date.DateField;
|
|
|
+import cn.hutool.core.date.DateTime;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.util.NumberUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.td.boss.common.pojo.Result;
|
|
|
+import com.td.boss.common.service.ComConfigService;
|
|
|
+import com.td.boss.common.service.CommonServiceImpl;
|
|
|
+import com.td.boss.config.enums.ResultEnum;
|
|
|
+import com.td.boss.game.complayerland.pojo.ComPlayerLand;
|
|
|
+import com.td.boss.game.complayerland.repository.ComPlayerLandRepository;
|
|
|
+import com.td.boss.game.complayersattri.enums.ComPlayerLuckyLogEnum;
|
|
|
+import com.td.boss.game.complayersattri.pojo.ComPlayersAttri;
|
|
|
+import com.td.boss.game.complayersattri.pojo.ComPlayersLucky;
|
|
|
+import com.td.boss.game.complayersattri.repository.ComPlayersAttriRepository;
|
|
|
+import com.td.boss.game.complayersattri.repository.ComPlayersLuckyRepository;
|
|
|
+import com.td.boss.game.complayersattri.vo.ComPlayersLuckyLandLevelUpVo;
|
|
|
+import com.td.boss.game.complayersattri.vo.ComPlayersLuckyToolsVo;
|
|
|
+import com.td.boss.game.complayersattri.vo.ComPlayersLuckyVo;
|
|
|
+import com.td.boss.game.comsnbtran.service.ComSnbTranService;
|
|
|
+import com.td.boss.game.comsnbtran.vo.ComSnbTranVo;
|
|
|
+import com.td.boss.game.comusers.service.ComUsersService;
|
|
|
+import com.td.boss.game.comusers.vo.ComUsersVo;
|
|
|
+import com.td.boss.util.RedisData;
|
|
|
+import com.td.boss.util.RedisLock;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import javax.persistence.EntityManager;
|
|
|
+import javax.persistence.PersistenceContext;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Optional;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+@Transactional
|
|
|
+public class ComPlayersLuckyServiceImpl extends CommonServiceImpl<ComPlayersLuckyVo, ComPlayersLucky, Integer> implements ComPlayersLuckyService {
|
|
|
+
|
|
|
+ private String toolskey = "land_tools";
|
|
|
+ private String levelUp = "land_level";
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ComConfigService comConfigService;
|
|
|
+ @Autowired
|
|
|
+ private ComPlayersLuckyRepository repository;
|
|
|
+ @Autowired
|
|
|
+ private ComPlayersAttriRepository comPlayersAttriRepository;
|
|
|
+ @Autowired
|
|
|
+ private ComPlayerLandRepository comPlayerLandRepository;
|
|
|
+ @Autowired
|
|
|
+ private ComUsersService comUsersService;
|
|
|
+ @Autowired
|
|
|
+ private ComSnbTranService comSnbTranService;
|
|
|
+ @Autowired
|
|
|
+ private RedisLock redisLock;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用的工具 获得幸运值,12小时获取一次
|
|
|
+ *
|
|
|
+ * @param userId
|
|
|
+ * @param toolId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Result useLuckyTools(String userId, Integer toolId, Integer landId) {
|
|
|
+ //验证工具是否存在
|
|
|
+ ComPlayersLuckyToolsVo tools = getLandTools().stream().filter(a -> a.getId().equals(toolId)).findFirst().orElse(null);
|
|
|
+ if (tools == null || tools.isEnable() == false) {
|
|
|
+ return Result.of(null, false, "无效工具");
|
|
|
+ }
|
|
|
+ //验证土地是否存在
|
|
|
+ ComPlayerLand comPlayerLand = comPlayerLandRepository.findById(landId).orElse(null);
|
|
|
+ if (comPlayerLand == null || comPlayerLand.getUserId().equals(userId) == false) {
|
|
|
+ return Result.of(null, false, "升级失败,无效土地!");
|
|
|
+ }
|
|
|
+ //土地租赁到期了,不能使用工具
|
|
|
+ if (comPlayerLand.getLeaseTime().before(new Date())) {
|
|
|
+ return Result.of(null, false, "升级失败,土地已到期!");
|
|
|
+ }
|
|
|
+ //验证用户是否存在
|
|
|
+ ComPlayersAttri playersAttri = comPlayersAttriRepository.findByUserId(userId).orElse(null);
|
|
|
+ if (playersAttri == null) {
|
|
|
+ return Result.of(null, false, "无效用户");
|
|
|
+ }
|
|
|
+
|
|
|
+ long time = System.currentTimeMillis() + RedisData.getPlayerLandToolTimeout();
|
|
|
+ String _redisKey = "LOCK:COM_PLAYER_LAND_TOOL:" + userId;
|
|
|
+ if (!redisLock.lock(_redisKey, String.valueOf(time))) {
|
|
|
+ return Result.of(null, false, ResultEnum.LAND_USE_TOOL.getMessage(), ResultEnum.LAND_USE_TOOL.getCode());
|
|
|
+ }
|
|
|
+ //验证工具是否可用:每隔一段时间才可使用
|
|
|
+ Optional<ComPlayersLucky> lastComPlayersLuckyLog = repository.findFirstByUserIdOrderByCreateTimeDesc(userId);
|
|
|
+ if (lastComPlayersLuckyLog.isPresent()) {
|
|
|
+ DateTime nextTime = DateUtil.offset(lastComPlayersLuckyLog.get().getCreateTime(), DateField.HOUR_OF_DAY, tools.getUseHour());
|
|
|
+ if (nextTime.isAfter(new Date())) {
|
|
|
+ return Result.of(null, false, "请在" + nextTime.toDateStr() + "后使用工具");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ int afterLucky = playersAttri.getLucky() + tools.getToolLucky();
|
|
|
+ //写入使用工具明细
|
|
|
+ ComPlayersLucky comPlayersLucky = new ComPlayersLucky();
|
|
|
+ comPlayersLucky.setAfterLucky(afterLucky);
|
|
|
+ comPlayersLucky.setBeforeLucky(playersAttri.getLucky());
|
|
|
+ comPlayersLucky.setAmount(tools.getToolLucky());
|
|
|
+ comPlayersLucky.setLuckyType(ComPlayerLuckyLogEnum.tool.getCode());
|
|
|
+ comPlayersLucky.setToolsId(toolId);
|
|
|
+ comPlayersLucky.setUserId(userId);
|
|
|
+ comPlayersLucky.setLevelId(0);
|
|
|
+ comPlayersLucky.setLandId(landId);
|
|
|
+ comPlayersLucky.setLuckyName(tools.getToolName());
|
|
|
+ comPlayersLucky.setCreateTime(new Date());
|
|
|
+ repository.save(comPlayersLucky);
|
|
|
+
|
|
|
+ //更新幸运值
|
|
|
+ playersAttri.setLucky(afterLucky);
|
|
|
+ comPlayersAttriRepository.save(playersAttri);
|
|
|
+ return Result.of(null, true, "使用工具成功");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 土地升级
|
|
|
+ *
|
|
|
+ * @param userId
|
|
|
+ * @param levelId
|
|
|
+ * @param landId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Result<?> landLevelUp(String userId, Integer levelId, Integer landId) {
|
|
|
+ //验证土地级别是否存在
|
|
|
+ ComPlayersLuckyLandLevelUpVo landLevelUpVo = getLandLevelUp().stream().filter(a -> a.getId().equals(levelId)).findFirst().orElse(null);
|
|
|
+ if (landLevelUpVo == null) {
|
|
|
+ return Result.of(null, false, "升级失败,无效升级!");
|
|
|
+ }
|
|
|
+ //验证土地是否存在
|
|
|
+ ComPlayerLand comPlayerLand = comPlayerLandRepository.findById(landId).orElse(null);
|
|
|
+ if (comPlayerLand == null || comPlayerLand.getUserId().equals(userId) == false) {
|
|
|
+ return Result.of(null, false, "升级失败,无效土地!");
|
|
|
+ }
|
|
|
+ //验证 将要升级的土地级别是否大于当前土地级别
|
|
|
+ if (comPlayerLand.getLandLevel() >= levelId) {
|
|
|
+ return Result.of(null, false, "升级失败,无效级别!");
|
|
|
+ }
|
|
|
+ //土地租赁到期了,不能升级
|
|
|
+ if (comPlayerLand.getLeaseTime().before(new Date())) {
|
|
|
+ return Result.of(null, false, "升级失败,土地已到期!");
|
|
|
+ }
|
|
|
+
|
|
|
+ long time = System.currentTimeMillis() + RedisData.getPlayerLandLevelupTimeout();
|
|
|
+ String _redisKey = "LOCK:COM_PLAYER_LAND_LEVELUP:" + userId;
|
|
|
+ if (!redisLock.lock(_redisKey, String.valueOf(time))) {
|
|
|
+ return Result.of(null, false, ResultEnum.LAND_LAND_LEVELUPPING.getMessage(), ResultEnum.LAND_LAND_LEVELUPPING.getCode());
|
|
|
+ }
|
|
|
+ //验证用户是否存在
|
|
|
+ ComPlayersAttri playersAttri = comPlayersAttriRepository.findByUserId(userId).orElse(null);
|
|
|
+ if (playersAttri == null) {
|
|
|
+ return Result.of(null, false, "升级失败");
|
|
|
+ }
|
|
|
+ //验证幸运值是否够用
|
|
|
+ int sub = Convert.toInt(NumberUtil.sub(playersAttri.getLucky(), landLevelUpVo.getCostLucky()));
|
|
|
+ if (sub < 0) {
|
|
|
+ return Result.of(null, false, "升级失败,幸运值不足!");
|
|
|
+ }
|
|
|
+ //写入使用工具明细
|
|
|
+ ComPlayersLucky comPlayersLucky = new ComPlayersLucky();
|
|
|
+ comPlayersLucky.setAfterLucky(sub);
|
|
|
+ comPlayersLucky.setBeforeLucky(playersAttri.getLucky());
|
|
|
+ comPlayersLucky.setAmount(landLevelUpVo.getCostLucky());
|
|
|
+ comPlayersLucky.setLuckyType(ComPlayerLuckyLogEnum.level.getCode());
|
|
|
+ comPlayersLucky.setLuckyName(landLevelUpVo.getName());
|
|
|
+ comPlayersLucky.setLevelId(levelId);
|
|
|
+ comPlayersLucky.setLandId(landId);
|
|
|
+ comPlayersLucky.setUserId(userId);
|
|
|
+ comPlayersLucky.setCreateTime(new Date());
|
|
|
+ repository.save(comPlayersLucky);
|
|
|
+
|
|
|
+ //更新用户剩余幸运值
|
|
|
+ playersAttri.setLucky(sub);
|
|
|
+ comPlayersAttriRepository.save(playersAttri);
|
|
|
+
|
|
|
+ //更新土地级别
|
|
|
+ comPlayerLand.setLandLevel(levelId);
|
|
|
+ comPlayerLandRepository.save(comPlayerLand);
|
|
|
+ return Result.of(null, true, "升级成功");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 兑换snb
|
|
|
+ *
|
|
|
+ * @param userId
|
|
|
+ * @param luckNum 消耗幸运值数量
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Result<?> toSNB(String userId, Integer luckNum) {
|
|
|
+ //兑换snb倍数
|
|
|
+ int snb = Convert.toInt(comConfigService.selectByKey("land_luck_tosnb"), 0);
|
|
|
+ if (luckNum < 1000) {
|
|
|
+ return Result.of(null, false, "幸运值满1000才能兑换SNB");
|
|
|
+ }
|
|
|
+ if (luckNum > 100000) {
|
|
|
+ return Result.of(null, false, "幸运值最多不能大于100000");
|
|
|
+ }
|
|
|
+ if (luckNum % snb != 0) {
|
|
|
+ return Result.of(null, false, StrUtil.format("幸运值必须为{}的倍数", snb));
|
|
|
+ }
|
|
|
+ ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
|
|
|
+ if (comUsersVo == null || StrUtil.isBlank(comUsersVo.getAddress())) {
|
|
|
+ return Result.of(null, false, "未找到用户或钱包地址");
|
|
|
+ }
|
|
|
+ long time = System.currentTimeMillis() + RedisData.getSnbTimeout();
|
|
|
+ String redisKey = StrUtil.format("SNB_SAVE_{}", userId);
|
|
|
+ // redis锁
|
|
|
+ if (!redisLock.lock(redisKey, String.valueOf(time))) {
|
|
|
+ return Result.of(null, false, ResultEnum.SEED_SALE_SAVE_LOCK.getMessage(), ResultEnum.SEED_SALE_SAVE_LOCK.getCode());
|
|
|
+ }
|
|
|
+ //获得snb用户对象
|
|
|
+ ComUsersVo player = comUsersService.findByUserId(userId);
|
|
|
+ //获得幸运值用户对象
|
|
|
+ ComPlayersAttri playersAttri = comPlayersAttriRepository.findByUserId(userId).orElse(null);
|
|
|
+ if (playersAttri == null || player == null) {
|
|
|
+ return Result.of(null, false, "无效用户");
|
|
|
+ }
|
|
|
+ //剩余幸运值
|
|
|
+ int num = playersAttri.getLucky() - luckNum;
|
|
|
+ if (num < 0) {
|
|
|
+ return Result.of(null, false, "幸运值不足!");
|
|
|
+ }
|
|
|
+ //兑换snb数量
|
|
|
+ int snbNum = luckNum / snb;
|
|
|
+ //插入明细
|
|
|
+ mingxi(userId, luckNum, playersAttri.getLucky(), player.getSnb(), snbNum);
|
|
|
+
|
|
|
+ //更新用户snb
|
|
|
+ player.setSnb(player.getSnb() + snbNum);
|
|
|
+ comUsersService.save(player);
|
|
|
+
|
|
|
+ //更新用户幸运值
|
|
|
+ playersAttri.setLucky(num);
|
|
|
+ comPlayersAttriRepository.save(playersAttri);
|
|
|
+ return Result.of(null, true, StrUtil.format("成功兑换{}个snb,消耗{}个幸运值", snbNum, luckNum));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param userId
|
|
|
+ * @param luckNum 消耗的幸运值
|
|
|
+ * @param beforeLuck 兑换前的幸运值
|
|
|
+ * @param beforeSNB 兑换前的snb数量
|
|
|
+ * @param snbNum 兑换snb的数量
|
|
|
+ */
|
|
|
+ private void mingxi(String userId, int luckNum, int beforeLuck, int beforeSNB, int snbNum) {
|
|
|
+ //记录幸运值明细
|
|
|
+ ComPlayersLucky comPlayersLucky = new ComPlayersLucky();
|
|
|
+ comPlayersLucky.setAfterLucky(beforeLuck - luckNum);
|
|
|
+ comPlayersLucky.setBeforeLucky(beforeLuck);
|
|
|
+ comPlayersLucky.setAmount(luckNum);
|
|
|
+ comPlayersLucky.setLuckyType(ComPlayerLuckyLogEnum.cnb.getCode());
|
|
|
+ comPlayersLucky.setLuckyName(ComPlayerLuckyLogEnum.cnb.getMsg());
|
|
|
+ comPlayersLucky.setLevelId(0);
|
|
|
+ comPlayersLucky.setLandId(0);
|
|
|
+ comPlayersLucky.setToolsId(0);
|
|
|
+ comPlayersLucky.setUserId(userId);
|
|
|
+ comPlayersLucky.setCreateTime(new Date());
|
|
|
+ comPlayersLucky = repository.save(comPlayersLucky);
|
|
|
+
|
|
|
+
|
|
|
+ //记录snb明细
|
|
|
+ ComSnbTranVo snbTran = new ComSnbTranVo();
|
|
|
+ //记录兑换id
|
|
|
+ snbTran.setTranId(Convert.toStr(comPlayersLucky.getId()));
|
|
|
+ snbTran.setUserId(userId);
|
|
|
+ snbTran.setTranName("兑换SNB");
|
|
|
+ snbTran.setTranType(9);
|
|
|
+ snbTran.setTranAmount(snbNum);
|
|
|
+ snbTran.setTranDescribe(StrUtil.format("user幸运值兑换SNB、本次兑换:{},消耗:{}幸运值", snbNum, luckNum));
|
|
|
+ snbTran.setIsAdd(1);
|
|
|
+ snbTran.setBeforeSnb(beforeSNB);
|
|
|
+ snbTran.setTranSnb(snbNum);
|
|
|
+ snbTran.setAfterSnb(beforeSNB + snbNum);
|
|
|
+ snbTran.setCreateTime(new Date());
|
|
|
+ snbTran.setTranSnbPart(0d);
|
|
|
+ snbTran.setAfterSnbPart(0d);
|
|
|
+ snbTran.setBeforeSnbPart(0d);
|
|
|
+ snbTran.setTranAmountPart(0d);
|
|
|
+ snbTran.setTranPrice(0);
|
|
|
+ comSnbTranService.save(snbTran);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取所有工具列表,方便用户选择使用哪种工具来获取幸运值
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<ComPlayersLuckyToolsVo> getLandTools() {
|
|
|
+ String land_tools = comConfigService.selectByKey(toolskey);
|
|
|
+ return JSONUtil.toList(land_tools, ComPlayersLuckyToolsVo.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取土地升级列表
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<ComPlayersLuckyLandLevelUpVo> getLandLevelUp() {
|
|
|
+ return comConfigService.selectLandLevel();
|
|
|
+ }
|
|
|
+}
|