|
@@ -0,0 +1,327 @@
|
|
|
|
|
+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";
|
|
|
|
|
+ @PersistenceContext
|
|
|
|
|
+ private EntityManager em;
|
|
|
|
|
+
|
|
|
|
|
+ @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;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取所有工具列表,方便用户选择使用哪种工具来获取幸运值
|
|
|
|
|
+ *
|
|
|
|
|
+ * @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() {
|
|
|
|
|
+ String land_tools = comConfigService.selectByKey(levelUp);
|
|
|
|
|
+ return JSONUtil.toList(land_tools, ComPlayersLuckyLandLevelUpVo.class);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 使用的工具 获得幸运值,12小时获取一次
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param userId
|
|
|
|
|
+ * @param toolId
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Result useLuckyTools(String userId, Integer toolId, Integer landId) {
|
|
|
|
|
+ if (toolId == null || toolId.equals(0)) {
|
|
|
|
|
+ return Result.of(null, false, "无效工具");
|
|
|
|
|
+ }
|
|
|
|
|
+ ComPlayersLuckyToolsVo tools = getLandTools().stream().filter(a -> a.getId().equals(toolId)).findFirst().orElse(null);
|
|
|
|
|
+ if (tools == null || tools.isEnable() == false) {
|
|
|
|
|
+ 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());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ComPlayersAttri playersAttri = comPlayersAttriRepository.findByUserId(userId).orElse(null);
|
|
|
|
|
+ if (playersAttri == null) {
|
|
|
|
|
+ return Result.of(null, false, "无效用户");
|
|
|
|
|
+ }
|
|
|
|
|
+ //验证工具是否可用:每隔一段时间才可使用
|
|
|
|
|
+ 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() + "后使用工具");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ //写入使用工具明细
|
|
|
|
|
+ ComPlayersLucky comPlayersLucky = new ComPlayersLucky();
|
|
|
|
|
+ comPlayersLucky.setAfterLucky(playersAttri.getLucky() + tools.getToolLucky());
|
|
|
|
|
+ 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(playersAttri.getLucky() + tools.getToolLucky());
|
|
|
|
|
+ comPlayersAttriRepository.save(playersAttri);
|
|
|
|
|
+ return Result.of(null, true, "使用工具成功");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 土地升级
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param userId
|
|
|
|
|
+ * @param levelId
|
|
|
|
|
+ * @param landId
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Result<?> landLevelUp(String userId, Integer levelId, Integer landId) {
|
|
|
|
|
+
|
|
|
|
|
+ ComPlayersAttri playersAttri = comPlayersAttriRepository.findByUserId(userId).orElse(null);
|
|
|
|
|
+ if (playersAttri == null) {
|
|
|
|
|
+ return Result.of(null, false, "无效领取");
|
|
|
|
|
+ }
|
|
|
|
|
+ Optional<ComPlayersLuckyLandLevelUpVo> levelLand = getLandLevelUp().stream().filter(a -> a.getId().equals(levelId)).findFirst();
|
|
|
|
|
+ if (levelLand.isPresent() == false) {
|
|
|
|
|
+ return Result.of(null, false, "升级失败,无效升级!");
|
|
|
|
|
+ }
|
|
|
|
|
+ ComPlayerLand land = comPlayerLandRepository.findByUserIdAndConfigLandId(userId, landId).orElse(null);
|
|
|
|
|
+ if (land == null) {
|
|
|
|
|
+ return Result.of(null, false, "升级失败,无效土地!");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (land.getLandLevel() >= levelId) {
|
|
|
|
|
+ return Result.of(null, false, "升级失败,无效级别!");
|
|
|
|
|
+ }
|
|
|
|
|
+ //土地租赁到期了,不能升级
|
|
|
|
|
+ if (getEndTime(land.getLeaseTime(), land.getLeaseDate()).before(new Date())) {
|
|
|
|
|
+ return Result.of(null, false, "升级失败,土地已到期!");
|
|
|
|
|
+ }
|
|
|
|
|
+ //剩余幸运值
|
|
|
|
|
+ int sub = Convert.toInt(NumberUtil.sub(playersAttri.getLucky(), levelLand.get().getCostLucky()));
|
|
|
|
|
+ if (sub < 0) {
|
|
|
|
|
+ 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());
|
|
|
|
|
+ }
|
|
|
|
|
+ //写入使用工具明细
|
|
|
|
|
+ ComPlayersLucky comPlayersLucky = new ComPlayersLucky();
|
|
|
|
|
+ comPlayersLucky.setAfterLucky(sub);
|
|
|
|
|
+ comPlayersLucky.setBeforeLucky(playersAttri.getLucky());
|
|
|
|
|
+ comPlayersLucky.setAmount(levelLand.get().getCostLucky());
|
|
|
|
|
+ comPlayersLucky.setLuckyType(ComPlayerLuckyLogEnum.level.getCode());
|
|
|
|
|
+ comPlayersLucky.setLuckyName(levelLand.get().getName());
|
|
|
|
|
+ comPlayersLucky.setLevelId(levelId);
|
|
|
|
|
+ comPlayersLucky.setLandId(landId);
|
|
|
|
|
+ comPlayersLucky.setUserId(userId);
|
|
|
|
|
+ comPlayersLucky.setCreateTime(new Date());
|
|
|
|
|
+ repository.save(comPlayersLucky);
|
|
|
|
|
+
|
|
|
|
|
+ //更新用户剩余幸运值
|
|
|
|
|
+ playersAttri.setLucky(sub);
|
|
|
|
|
+ comPlayersAttriRepository.save(playersAttri);
|
|
|
|
|
+
|
|
|
|
|
+ //更新土地级别
|
|
|
|
|
+ land.setLandLevel(levelId);
|
|
|
|
|
+ comPlayerLandRepository.save(land);
|
|
|
|
|
+ return Result.of(null, true, "升级成功");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 兑换snb
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param userId
|
|
|
|
|
+ * @param luckNum 消耗幸运值数量
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ 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);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取土地到期时间
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param beginTime 租赁时间
|
|
|
|
|
+ * @param type //租赁的日期,1是3个月,2是1年,3是5年
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ private Date getEndTime(Date beginTime, int type) {
|
|
|
|
|
+ if (type == 1) {
|
|
|
|
|
+ return DateUtil.date(beginTime).offset(DateField.MONTH, 3);
|
|
|
|
|
+ } else if (type == 2) {
|
|
|
|
|
+ return DateUtil.date(beginTime).offset(DateField.YEAR, 1);
|
|
|
|
|
+ } else if (type == 3) {
|
|
|
|
|
+ return DateUtil.date(beginTime).offset(DateField.YEAR, 5);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return beginTime;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|