Forráskód Böngészése

1.添加受灾结果计算,
2.添加审核部分接口操作

slambb 4 éve
szülő
commit
e0174ec20d

+ 5 - 5
pom.xml

@@ -155,11 +155,11 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
-        <dependency>
-            <groupId>cn.hutool</groupId>
-            <artifactId>hutool-all</artifactId>
-            <version>5.7.22</version>
-        </dependency>
+        <!--<dependency>-->
+        <!--    <groupId>cn.hutool</groupId>-->
+        <!--    <artifactId>hutool-all</artifactId>-->
+        <!--    <version>5.7.22</version>-->
+        <!--</dependency>-->
 
     </dependencies>
 

+ 5 - 1
src/main/java/com/td/boss/config/enums/ResultEnum.java

@@ -21,6 +21,7 @@ public enum ResultEnum {
     SETTING_IS_NULL(306,"配置信息不存在"),
     //redis部分
     REDIS_IS_LOCK(307,"操作过于频繁,稍后再试!"),
+    REDIS_IS_LOCK_ERROR(308,"操作失败,稍后再试!"),
     //用户数据
     USER_DOES_NOT_EXIST(400,"不能存在用户信息!"),
     USER_ENERGY_IS_INSUFFICIENT(401,"用户能量不足!"),
@@ -56,7 +57,7 @@ public enum ResultEnum {
     APPLY_SNB_AMOUNT_ERROR(605,"snb参数错误!"),
     APPLY_SNB_TOO_MUCH(606,"snb申请过多,待审核完成后再申请!"),
     APPLY_SNB_HAS_APPLY(607,"已有一笔snb申请中,待审核完成后再申请!"),
-
+    APPLY_SNB_STATE_ERROR(608,"状态信息错误!"),
     //土地数据
     LAND_DATA_ERROR(701,"土地数据不能初始化!"),
     LAND_NOT_LEASE(702,"土地未租赁!"),
@@ -75,6 +76,9 @@ public enum ResultEnum {
     LAND_USE_TOOL(714,"该土地正在使用工具中!"),
     LAND_LAND_LEVELUPPING(715,"该土地正在升级中!"),
 
+    //土地受灾中,稍后重试!
+    LAND_DISATER_LOCK(715,"土地正在遭受灾害,稍后重试!"),
+
 
     //种子数据不能存在
     SEED_DATA_ERROR(801,"种子数据不存在!"),

+ 103 - 19
src/main/java/com/td/boss/game/complayergoods/controller/ComPlayerGoodsController.java

@@ -255,10 +255,21 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
             //return Result.of(null, false, ResultEnum.LAND_PLANT_FLAG_IS_NULL.getMessage(), ResultEnum.LAND_PLANT_FLAG_IS_NULL.getCode());
             _redisKey = comPlayerLand.getUserId() + "or" + comPlayerLand.getConfigLandId();
         }
+        //受灾时候,不给收获
+        String _disasterKey = RedisData.getPlayerDisastersFirstKey() + comPlayerLand.getConfigLandId() + comPlayerLand.getUserId();
+        long _disasterTime = System.currentTimeMillis() + RedisData.getPlayerDisastersFirstTimeout();
+
         Map map = new HashMap();
         //todo 总共偷去的数量
         Double _stealProfits = 0d;
+        //todo 灾难影响的数量
+        Double _disasterProfits = 0d;
         try {
+            //加一层受灾锁
+            if (!redisLock.lock(_disasterKey, String.valueOf(_disasterTime))) {
+                return Result.of(null, false, ResultEnum.LAND_DISATER_LOCK.getMessage(), ResultEnum.LAND_DISATER_LOCK.getCode());
+            }
+
             // 如果存在plantFlag 说明是新种植的
             if (!redisLock.lock(_redisKey, String.valueOf(time))) {
                 return Result.of(null, false, ResultEnum.LAND_STEAL_LOCK.getMessage(), ResultEnum.LAND_STEAL_LOCK.getCode());
@@ -285,9 +296,9 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
             // 配置的参数。这里先直接定义
             Double profitConfig = comSettingVo.getProfit(), stealRatioMaxConfig = comSettingVo.getStealMaxRatio(), stealRatioMinConfig = comSettingVo.getStealMinRatio(), finallyGetRatioConfig = comSettingVo.getFinalRatio();
             Double landLevelInCome = getLandLevelInCome(comPlayerLand, comMallSeedVo.getPriceSnb());
-            Double _profitDouble = DoubleUtil.add(_profit.doubleValue(),landLevelInCome);
+            Double _profitDouble = DoubleUtil.add(_profit.doubleValue(), landLevelInCome);
             Double _residualProfit = DoubleUtil.mul(_profitDouble, DoubleUtil.sub(1d, profitConfig));//如果 profitConfig 0.2,剩余利润就是0.8;
-            Double _stealAmount = DoubleUtil.sub(_profitDouble, _residualProfit); //可偷取的利润
+            //Double _stealAmount = DoubleUtil.sub(_profitDouble, _residualProfit); //可偷取的利润
 
             //todo 计算总共损失的数量
             List<ComPlayerProfit> comPlayerProfits = comPlayerProfitService.findByUserIdAndPlantFlagAndLandId(userId, _redisKey, comPlayerLand.getConfigLandId());
@@ -295,21 +306,29 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
                 ComPlayerProfit temp = comPlayerProfits.get(i);
                 _stealProfits = DoubleUtil.add(_stealProfits, temp.getStolen());
             }
-            Double _userHarvestPart = DoubleUtil.sub(_stealAmount, _stealProfits);
+            // Double _userHarvestPart = DoubleUtil.sub(_stealAmount, _stealProfits);
+            Double _userHarvestPart = DoubleUtil.sub(_profitDouble, _stealProfits);
+            Double _endLossProfits = 0d;
             if (_userHarvestPart < 0.0) {
                 //差值不能为负数
                 _userHarvestPart = 0d;
                 //相当于被偷取全部利润,这里返回一个被偷去的全部利润值
-                map.put("lossAmount", _stealAmount);
+                //map.put("lossAmount", _stealAmount);
+                map.put("lossAmount", _profitDouble);
+                _endLossProfits = _profitDouble;
             } else {
                 //todo 返回一个被偷的数量
                 map.put("lossAmount", _stealProfits);
+                _endLossProfits = _stealProfits;
             }
 
+            //上面计算被偷的,下面计算灾难影响的
+
+
             //todo 利润
             _amount -= _profit;
-            //用户收取的对应数量,固定收入+被偷取后剩余的部分
-            _amountPart = DoubleUtil.add(_residualProfit, _userHarvestPart);
+            //用户收取的对应数量,固定收入+被偷取后剩余的部分 (改成全部影响利润了。没有固定收入)
+            _amountPart = _userHarvestPart;// DoubleUtil.add(_residualProfit, _userHarvestPart);
             //果实 Type =1
             ComPlayerGoods comPlayerGoodsSimpleVo = comPlayerGoodsService.findByUserIdAndIndexAndType(userId, comMallSeedVo.getHarvestId(), 1);
             Integer _beforeAmount = 0;
@@ -355,7 +374,7 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
             _playerLog.setAfterAmount(comPlayerGoodsSimpleVo.getAmount());
             //收取时候信息记录
             _playerLog.setTPart(_amountPart);
-            _playerLog.setTLoss(_stealProfits); //损失的部分
+            _playerLog.setTLoss(_endLossProfits); //(_stealProfits); //损失的部分
             _playerLog.setBeforePart(_beforeProfitPart);
             _playerLog.setAfterPart(_afterProfitPart);
             _playerLog.setLMultiple(comPlayerLand.getLeaseMultiple());
@@ -364,9 +383,11 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
 
             //对应的,存在plantFlag则解锁
             redisLock.unlock(_redisKey, String.valueOf(time));
+            redisLock.unlock(_disasterKey, String.valueOf(_disasterTime));
         } catch (Exception e) {
             //对应的,存在plantFlag则解锁
             redisLock.unlock(_redisKey, String.valueOf(time));
+            redisLock.unlock(_disasterKey, String.valueOf(_disasterTime));
             throw new RuntimeException(e.getMessage());
         }
         map.put("msg", "成功收取果实!");
@@ -507,7 +528,17 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
         //需要redis 加锁
         long time = System.currentTimeMillis() + RedisData.getPlayerGoodsTimeout();
 
+        //受灾时候,不给收获
+        String _disasterKey = RedisData.getPlayerDisastersFirstKey() + otherPlayerLand.getConfigLandId() + otherPlayerLand.getUserId();
+        long _disasterTime = System.currentTimeMillis() + RedisData.getPlayerDisastersFirstTimeout();
+
+
         try {
+            //加一层受灾锁
+            if (!redisLock.lock(_disasterKey, String.valueOf(_disasterTime))) {
+                return Result.of(null, false, ResultEnum.LAND_DISATER_LOCK.getMessage(), ResultEnum.LAND_DISATER_LOCK.getCode());
+            }
+
             if (!redisLock.lock(_redisSNBKey, String.valueOf(time))) {
                 //如果有snb冲突锁
                 return Result.of(null, false, ResultEnum.USER_LOGIN_LOCK.getMessage(), ResultEnum.USER_LOGIN_LOCK.getCode());
@@ -530,7 +561,7 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
             //todo 拿出计算利润,收获量减去种子的成本(snb)后的百分之30 ,后面需要后台可调整
             Double landLevelInCome = getLandLevelInCome(otherPlayerLand, comMallSeedVo.getPriceSnb());
             Integer _profitInt = _otherAmount - otherPlayerLand.getLeaseMultiple() * comMallSeedVo.getPriceSnb();
-            Double _profit =  DoubleUtil.add(_profitInt.doubleValue(),landLevelInCome);
+            Double _profit = DoubleUtil.add(_profitInt.doubleValue(), landLevelInCome);
             // 配置的参数。这里先直接定义
             // 需要根据 狗是否生效,小偷是否装备打狗棒来确定参数
             Double profitConfig = _dogWork ? comSettingVo.getProfitDog() : comSettingVo.getProfit(),
@@ -543,27 +574,70 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
             if (_dogWork) {
                 _stealRatio = _holdTheStick ? comSettingVo.getStealRatioHasStick() : comSettingVo.getStealRatioNoStick();
             }
-            Double _stolenAmount = DoubleUtil.mul(_profit.doubleValue(), _stealRatio);
+            Double _stolenAmount = DoubleUtil.mul(_profit, _stealRatio);
             //这里根据plantFlag判断目标用户当前种植被偷取完,记录更新用户 comPlayerLand plantSteal 字段;保存一个偷取状态
-            Double _sumStolen = comPlayerProfitService.getStolenSumByOtherUserIdAndPlantFlag(otherUserId, _redisKey);
+            //这里只拿去被偷的利润,灾难扣除的不算再这里,但是总利润需要限制计算
+            //Double _sumStolen = comPlayerProfitService.getStolenSumByOtherUserIdAndPlantFlagAndLossType(otherUserId, _redisKey,0);
+            Double _sumStolen = 0d,_allStolen = 0d;
+            List<ComPlayerProfit> comPlayerProfits = comPlayerProfitService.findByUserIdAndPlantFlagAndLandId(otherUserId, _redisKey, otherPlayerLand.getConfigLandId());
+            for (int i = 0; i < comPlayerProfits.size(); i++) {
+                ComPlayerProfit temp = comPlayerProfits.get(i);
+                if(temp.getLossType().equals(0)){
+                    //偷取时候的利润总和
+                    _sumStolen = DoubleUtil.add(_sumStolen, temp.getStolen());
+                }
+                //当前全部损失的利润
+                _allStolen = DoubleUtil.add(_allStolen, temp.getStolen());
+            }
+
             //todo 这里的可偷利润应该是最大值,用户不能超过这个,需要限制判断
-            Double _maxAmount = DoubleUtil.mul(_profit.doubleValue(), profitConfig); //可偷取的利润
+            Double _maxAmount = DoubleUtil.mul(_profit, profitConfig); //可偷取的利润
             //1 单偷操作 就是 _sumStolen>_maxAmount 或者 _sumStolen == _maxAmount ,被偷完了
-            if (!DoubleUtil.compare(_sumStolen, _maxAmount).equals(-1)) {
+            //if (!DoubleUtil.compare(_sumStolen, _maxAmount).equals(-1)) {
+            //    // 需要redis 解锁
+            //    redisLock.unlock(_redisKey, String.valueOf(time));
+            //    redisLock.unlock(_redisSNBKey, String.valueOf(time));
+            //    redisLock.unlock(_disasterKey, String.valueOf(_disasterTime));
+            //    //记录一个不可偷取的状态
+            //    otherPlayerLand.setPlantSteal(0);
+            //    comPlayerLandService.save(CopyUtil.copy(otherPlayerLand, ComPlayerLandVo.class));
+            //    map.put("plant_steal", otherPlayerLand.getPlantSteal());
+            //    return Result.of(map, false, ResultEnum.LAND_CAN_STEAL_IS_MAX.getMessage(), ResultEnum.LAND_CAN_STEAL_IS_MAX.getCode());
+            //}
+            //计算剩下可偷利润的差,防止过多偷取用户利润 _stolenAmount
+            //Double _diff = Math.abs(DoubleUtil.sub(_maxAmount, _sumStolen));
+            Double _diff = DoubleUtil.sub(_maxAmount, _sumStolen);
+            Boolean isUpdateCanSteal = false;
+            if (DoubleUtil.compare(_diff,0.0).equals(1)) {
+                if(DoubleUtil.compare(_stolenAmount, _diff).equals(1)){
+                    _stolenAmount = _diff;
+                    isUpdateCanSteal = true;
+                }
+            }else{
+                _stolenAmount = 0d;
+                isUpdateCanSteal = true;
+            }
+            //这里需要拦截处理最终偷取的利润,比如 总利润_profit=530(可能会加上收益),
+            // _allStolen + _stolenAmount 不能大于总利润
+            Double _endLossProfit = DoubleUtil.add(_allStolen,_stolenAmount);
+            Double _endLossDiff = DoubleUtil.sub(_profit,_endLossProfit);
+            if(!DoubleUtil.compare(_sumStolen, _maxAmount).equals(-1) || DoubleUtil.compare(_endLossDiff,0.0).equals(-1)){
+                //如果差值为零
                 // 需要redis 解锁
                 redisLock.unlock(_redisKey, String.valueOf(time));
                 redisLock.unlock(_redisSNBKey, String.valueOf(time));
+                redisLock.unlock(_disasterKey, String.valueOf(_disasterTime));
                 //记录一个不可偷取的状态
                 otherPlayerLand.setPlantSteal(0);
                 comPlayerLandService.save(CopyUtil.copy(otherPlayerLand, ComPlayerLandVo.class));
                 map.put("plant_steal", otherPlayerLand.getPlantSteal());
                 return Result.of(map, false, ResultEnum.LAND_CAN_STEAL_IS_MAX.getMessage(), ResultEnum.LAND_CAN_STEAL_IS_MAX.getCode());
             }
-            //计算剩下可偷利润的差,防止过多偷取用户利润 _stolenAmount
-            Double _diff = Math.abs(DoubleUtil.sub(_maxAmount, _sumStolen));
-            if (DoubleUtil.compare(_stolenAmount, _diff).equals(1)) {
-                //_stolenAmount>_diff
-                _stolenAmount = _diff;
+            if(isUpdateCanSteal){
+                //记录一个不可偷取的状态
+                otherPlayerLand.setPlantSteal(0);
+                comPlayerLandService.save(CopyUtil.copy(otherPlayerLand, ComPlayerLandVo.class));
+                map.put("plant_steal", otherPlayerLand.getPlantSteal());
             }
             //最终偷窃人获取的是偷取的是目标用户损失量的10% finallyGetRatioConfig
             Double _finalStealAmount = DoubleUtil.mul(_stolenAmount, finallyGetRatioConfig);
@@ -603,15 +677,20 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
             comPlayerProfit.setLeaseMultiple(otherPlayerLand.getLeaseMultiple());
             comPlayerProfit.setLeaseDate(otherPlayerLand.getLeaseDate());
             comPlayerProfit.setHarvest(_otherAmount);
-            comPlayerProfit.setProfit(_profit.doubleValue());//目标用户可偷的初始利润值
+            comPlayerProfit.setProfit(_profit);//目标用户可偷的初始利润值
             comPlayerProfit.setStolen(_stolenAmount);//目标用户被偷的数量
             comPlayerProfit.setFinalSteal(_finalStealAmount);//用户最终偷取的量,是被偷的数量 10%左右
-            comPlayerProfit.setProfitAfter(DoubleUtil.sub(_profit.doubleValue(), DoubleUtil.add(_stolenAmount, _sumStolen))); //可偷的减去被偷的
+            comPlayerProfit.setProfitAfter(DoubleUtil.sub(_profit, DoubleUtil.add(_stolenAmount, _sumStolen))); //可偷的减去被偷的
             //记录相关比例
             comPlayerProfit.setProfitRatio(profitConfig);
             comPlayerProfit.setStealRatio(_stealRatio);
             comPlayerProfit.setFinalRatio(finallyGetRatioConfig);
             comPlayerProfit.setLossType(0);
+
+            //
+            comPlayerProfit.setDsasterId(-10L);
+            comPlayerProfit.setAddedPart(landLevelInCome);
+
             ComPlayerProfitVo comPlayerProfitVo = CopyUtil.copy(comPlayerProfit, ComPlayerProfitVo.class);
             comPlayerProfitService.save(comPlayerProfitVo);
 
@@ -736,11 +815,14 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
 
             //解除snb锁
             redisLock.unlock(_redisSNBKey, String.valueOf(time));
+
+            redisLock.unlock(_disasterKey, String.valueOf(_disasterTime));
             return Result.of(map);
         } catch (Exception e) {
             // 需要redis 解锁
             redisLock.unlock(_redisKey, String.valueOf(time));
             redisLock.unlock(_redisSNBKey, String.valueOf(time));
+            redisLock.unlock(_disasterKey, String.valueOf(_disasterTime));
             throw new RuntimeException(e.getMessage());
         }
 
@@ -979,8 +1061,10 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
 //    }
     @Autowired
     private ComConfigService comConfigService;
+
     /**
      * 获得土地级别收益,普通土地最后结果为0
+     *
      * @param comPlayerLand
      * @param priceSnb
      * @return

+ 77 - 66
src/main/java/com/td/boss/game/complayerland/controller/ComPlayerLandController.java

@@ -140,7 +140,7 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                         //说明可以收获了
                         comPlayerLandAndPlantVo.setPlantDaysRemaining(0);
                         comPlayerLandAndPlantVo.setPlantHoursRemaining(0);
-                        //生成第一次受灾
+                        //生成第一次受灾 获取用户土地 getList
                         _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
                     } else {
                         comPlayerLandAndPlantVo.setPlantDaysRemaining(DateUtil.getDays(diff).intValue());
@@ -156,7 +156,8 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
             }).collect(Collectors.toList());
 
         } catch (Exception e) {
-            throw new RuntimeException(e.getMessage());
+            //throw new RuntimeException(e.getMessage());
+            return  Result.of(null,false,"服务器繁忙,请刷新游戏重新进入!",ResultEnum.REDIS_IS_LOCK.getCode());
         }
 
         return Result.of(_list);
@@ -211,7 +212,7 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                         //说明可以收获了
                         comPlayerLandAndPlantVo.setPlantDaysRemaining(0);
                         comPlayerLandAndPlantVo.setPlantHoursRemaining(0);
-                        //生成第一次受灾
+                        //生成第一次受灾 getCanStealDetailList
                         _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
 
                     } else {
@@ -302,8 +303,6 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
             @RequestParam(value = "landId") Integer landId,
             @RequestParam(value = "seedId") Integer seedId) {
 
-        long time = System.currentTimeMillis() + RedisData.getPlayerDisastersFirstTimeout();
-
         try {
             ComPlayerLand comPlayerLand = comPlayerLandService.findByUserIdAndLandId(userId, landId);
             //土地数据不存在
@@ -432,7 +431,7 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                 comPlayerLandAndPlantVo.setPlantDaysRemaining(0);
                 comPlayerLandAndPlantVo.setPlantHoursRemaining(0);
 
-                //生成第一次受灾
+                //生成第一次受灾 plant
                 _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
 
 
@@ -495,8 +494,8 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                 .sorted(Comparator.comparing(ComPlayerDisasterProtected::getProtectTime).reversed())
                 .findFirst().orElse(null);
         Map map = new HashMap();
-        map.put("naturalProtected",CopyUtil.copy(_naturalDisasterProtected, ComPlayerDisasterProtectedSimpleVo.class));
-        map.put("beastProtected",CopyUtil.copy(_beastDisasterProtected, ComPlayerDisasterProtectedSimpleVo.class));
+        map.put("naturalProtected",_naturalDisasterProtected == null? null: CopyUtil.copy(_naturalDisasterProtected, ComPlayerDisasterProtectedSimpleVo.class));
+        map.put("beastProtected",_beastDisasterProtected == null? null:CopyUtil.copy(_beastDisasterProtected, ComPlayerDisasterProtectedSimpleVo.class));
         return Result.of(map);
     }
 
@@ -505,73 +504,85 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
         //todo 添加一个灾难损失,灾难损失的时间点是种植开始到成熟阶段的一个随机时间
         // 加个锁判断,是否在其他地方触发了这次灾难计算(自解锁)
         long time = System.currentTimeMillis() + RedisData.getPlayerDisastersFirstTimeout();
-        String _disasterKey = RedisData.getPlayerDisastersFirstKey() + comPlayerLandAndPlantVo.getPlantFlag();
-        if (redisLock.lock(_disasterKey, String.valueOf(time))) {
-            //查询当前人员购买防护历史记录
-            List<ComPlayerDisasterProtected> protectList = disasterProtectedService.getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(comPlayerLandAndPlantVo.getUserId());
-
-            //灾难发生时间
-            Date endDate = DateUtil.getOldDateAddDay(comPlayerLandAndPlantVo.getPlantStart(), comPlayerLandAndPlantVo.getPlantMature());
-            //log.info(comPlayerLandAndPlantVo.getPlantStart().getTime() + "= " + endDate.getTime());
-            long randomDate =comPlayerLandAndPlantVo.getPlantStart().compareTo(endDate) == 0?
-                    endDate.getTime(): RandomUtil.randomLong(comPlayerLandAndPlantVo.getPlantStart().getTime(), endDate.getTime());
-            Date disasterDate = new Date(randomDate);
-            //获取损失的数据
-            List<ComPlayerProfit> comPlayerProfits = comPlayerProfitService.findByUserIdAndPlantFlagAndLandId(comPlayerLandAndPlantVo.getUserId(), comPlayerLandAndPlantVo.getPlantFlag(), comPlayerLandAndPlantVo.getConfigLandId());
-            //todo 总共受损的数量
-            Double _allLossProfit = 0d;
-            boolean isNaturalProfit = false, isBeastProfit = false;
-            for (int j = 0; j < comPlayerProfits.size(); j++) {
-                ComPlayerProfit _profit = comPlayerProfits.get(j);
-                _allLossProfit = DoubleUtil.add(_allLossProfit, _profit.getStolen());
-                if (_profit.getLossType().equals(2)) {
-                    isNaturalProfit = true;
-                } else if (_profit.getLossType().equals(3)) {
-                    isBeastProfit = true;
+        String _disasterKey = RedisData.getPlayerDisastersFirstKey() + comPlayerLandAndPlantVo.getConfigLandId() + comPlayerLandAndPlantVo.getUserId();
+        try {
+            if (redisLock.lock(_disasterKey, String.valueOf(time))) {
+                //查询当前人员购买防护历史记录
+                List<ComPlayerDisasterProtected> protectList = disasterProtectedService.getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(comPlayerLandAndPlantVo.getUserId());
+
+                //灾难发生时间
+                Date endDate = DateUtil.getOldDateAddDay(comPlayerLandAndPlantVo.getPlantStart(), comPlayerLandAndPlantVo.getPlantMature());
+                //log.info(comPlayerLandAndPlantVo.getPlantStart().getTime() + "= " + endDate.getTime());
+                long randomDate =comPlayerLandAndPlantVo.getPlantStart().compareTo(endDate) == 0?
+                        endDate.getTime(): RandomUtil.randomLong(comPlayerLandAndPlantVo.getPlantStart().getTime(), endDate.getTime());
+                Date disasterDate = new Date(randomDate);
+                //获取损失的数据
+                List<ComPlayerProfit> comPlayerProfits = comPlayerProfitService.findByUserIdAndPlantFlagAndLandId(comPlayerLandAndPlantVo.getUserId(), comPlayerLandAndPlantVo.getPlantFlag(), comPlayerLandAndPlantVo.getConfigLandId());
+                //todo 总共受损的数量
+                Double _allLossProfit = 0d;
+                boolean isNaturalProfit = false, isBeastProfit = false;
+                for (int j = 0; j < comPlayerProfits.size(); j++) {
+                    ComPlayerProfit _profit = comPlayerProfits.get(j);
+                    _allLossProfit = DoubleUtil.add(_allLossProfit, _profit.getStolen());
+                    if (_profit.getLossType().equals(2)) {
+                        if(DoubleUtil.compare(-1D, _profit.getDsasterId().doubleValue()).equals(0)){
+                            isNaturalProfit = true;
+                        }
+                    } else if (_profit.getLossType().equals(3)) {
+                        if(DoubleUtil.compare(-1D, _profit.getDsasterId().doubleValue()).equals(0)){
+                            isBeastProfit = true;
+                        }
+                    }
                 }
-            }
-            log.info("用户编号:{},防护历史记录:{}", comPlayerLandAndPlantVo.getUserId(), JSONUtil.toJsonStr(protectList));
-            //获得对应灾难类型的防护记录    并得到这个 防护到期时间. 自然灾害类型
-            //如果没有防护或者防护到期。则直接发生灾难进行减产
-            if (!isNaturalProfit) {
-                Date _protectedDate = protectList.stream()
-                        .filter(a -> a.getDsasterType().equals(2))
-                        .sorted(Comparator.comparing(ComPlayerDisasterProtected::getProtectTime).reversed())
-                        .map(ComPlayerDisasterProtected::getProtectTime)
-                        .findFirst().orElse(cn.hutool.core.date.DateUtil.parse(null));
+                log.info("用户编号:{},防护历史记录:{}", comPlayerLandAndPlantVo.getUserId(), JSONUtil.toJsonStr(protectList));
+                //获得对应灾难类型的防护记录    并得到这个 防护到期时间. 自然灾害类型
                 //如果没有防护或者防护到期。则直接发生灾难进行减产
-                if (_protectedDate != null && disasterDate.before(_protectedDate)) {
-                    //灾难的随机时间比防护包时间后,说明防护包到期
-                    //成熟的时候触发第一次自然灾难
-                    ComPlayerProfitVo naturalProfitVo = comPlayerProfitService.addFirstDisasterAndLoss(CopyUtil.copy(comPlayerLandAndPlantVo, ComPlayerLand.class),
-                            comMallSeedVo, 2, _allLossProfit);
-                    //多次执行需要加上当前操作的利润
-                    _allLossProfit += naturalProfitVo.getStolen();
-
-                    //添加自然灾害灾难记录
-                    comPlayerDisasterLogService.addDisasterEnable(comPlayerLandAndPlantVo.getUserId(),-1L,2,_protectedDate);
+
+                if (!isNaturalProfit) {
+                    Date _protectedDate = protectList.stream()
+                            .filter(a -> a.getDsasterType().equals(2))
+                            .sorted(Comparator.comparing(ComPlayerDisasterProtected::getProtectTime).reversed())
+                            .map(ComPlayerDisasterProtected::getProtectTime)
+                            .findFirst().orElse(cn.hutool.core.date.DateUtil.parse(null));
+                    //如果没有防护或者防护到期。则直接发生灾难进行减产
+                    if (_protectedDate == null || disasterDate.after(_protectedDate)) {
+                        //灾难的随机时间比防护包时间后,说明防护包到期
+                        //成熟的时候触发第一次自然灾难
+                        ComPlayerProfitVo naturalProfitVo = comPlayerProfitService.addFirstDisasterAndLoss(CopyUtil.copy(comPlayerLandAndPlantVo, ComPlayerLand.class),
+                                comMallSeedVo, 2, _allLossProfit,-1);
+                        //多次执行需要加上当前操作的利润
+                        _allLossProfit += naturalProfitVo.getStolen();
+
+                        //添加自然灾害灾难记录
+                        comPlayerDisasterLogService.addDisasterEnable(comPlayerLandAndPlantVo.getUserId(),-1L,2,_protectedDate);
+                    }
                 }
-            }
-            if (!isBeastProfit) {
-                Date _protectedDate = protectList.stream()
-                        .filter(a -> a.getDsasterType().equals(3))
-                        .sorted(Comparator.comparing(ComPlayerDisasterProtected::getProtectTime).reversed())
-                        .map(ComPlayerDisasterProtected::getProtectTime)
-                        .findFirst().orElse(cn.hutool.core.date.DateUtil.parse(null));
-                //如果没有防护或者防护到期。则直接发生灾难进行减产
-                if (_protectedDate != null && disasterDate.before(_protectedDate)) {
-                    //灾难的随机时间比防护包时间后,说明防护包到期
-                    //成熟的时候触发第一次自然灾难
-                    ComPlayerProfitVo beastProfitVo = comPlayerProfitService.addFirstDisasterAndLoss(CopyUtil.copy(comPlayerLandAndPlantVo, ComPlayerLand.class),
-                            comMallSeedVo, 3, _allLossProfit);
+                if (!isBeastProfit) {
+                    Date _protectedDate = protectList.stream()
+                            .filter(a -> a.getDsasterType().equals(3))
+                            .sorted(Comparator.comparing(ComPlayerDisasterProtected::getProtectTime).reversed())
+                            .map(ComPlayerDisasterProtected::getProtectTime)
+                            .findFirst().orElse(cn.hutool.core.date.DateUtil.parse(null));
+                    //如果没有防护或者防护到期。则直接发生灾难进行减产
+                    if (_protectedDate == null || disasterDate.after(_protectedDate)) {
+                        //灾难的随机时间比防护包时间后,说明防护包到期
+                        //成熟的时候触发第一次自然灾难
+                        ComPlayerProfitVo beastProfitVo = comPlayerProfitService.addFirstDisasterAndLoss(CopyUtil.copy(comPlayerLandAndPlantVo, ComPlayerLand.class),
+                                comMallSeedVo, 3, _allLossProfit,-1);
 //                    //多次执行需要加上当前操作的利润
 //                    _allLossProfit += beastProfitVo.getStolen();
 
-                    //添加野兽灾害灾难记录
-                    comPlayerDisasterLogService.addDisasterEnable(comPlayerLandAndPlantVo.getUserId(),-1L,3,_protectedDate);
+                        //添加野兽灾害灾难记录
+                        comPlayerDisasterLogService.addDisasterEnable(comPlayerLandAndPlantVo.getUserId(),-1L,3,_protectedDate);
 
+                    }
                 }
+
+                redisLock.unlock(_disasterKey, String.valueOf(time));
             }
+        } catch (Exception e) {
+            log.error("触发_InitFirstDisasterProfit异:" + e.getMessage());
         }
+
     }
 }

+ 30 - 17
src/main/java/com/td/boss/game/complayerland/service/ComPlayerDisasterLogServiceImpl.java

@@ -67,7 +67,7 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
     /**
      * 伤害 会减产50%
      */
-    private int damage = 50;
+    private int damage = 40;
 
     /**
      * 防御 90%概率防御灾难
@@ -242,8 +242,13 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
                 //这里处理一次判断是否发生过第一次灾难
                 //todo 添加一个灾难损失,灾难损失的时间点是种植开始到成熟阶段的一个随机时间
                 // 加个锁判断,是否在其他地方触发了这次灾难计算(自解锁)
-                String _disasterKey = RedisData.getPlayerDisastersFirstKey() + _comPlayerLand.getPlantFlag();
-                if (redisLock.lock(_disasterKey, String.valueOf(time))) {
+                String _disasterKey = RedisData.getPlayerDisastersFirstKey() + _comPlayerLand.getConfigLandId() + _comPlayerLand.getUserId();
+                try {
+                    if (!redisLock.lock(_disasterKey, String.valueOf(time))) {
+                        log.info("锁住key:"+_disasterKey);
+                       continue;
+                    }
+
                     //灾难发生时间
                     Date endDate = com.td.boss.util.DateUtil.getOldDateAddDay(_comPlayerLand.getPlantStart(), _comPlayerLand.getPlantMature());
                     long randomDate = _comPlayerLand.getPlantStart().compareTo(endDate) == 0 ?
@@ -260,11 +265,15 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
                         ComPlayerProfit _profit = comPlayerProfits.get(j);
                         _allLossProfit = DoubleUtil.add(_allLossProfit, _profit.getStolen());
                         if (_profit.getLossType().equals(2)) {
-                            isNaturalProfit = true;
+                            if(DoubleUtil.compare(-1D, _profit.getDsasterId().doubleValue()).equals(0)){
+                                isNaturalProfit = true;
+                            }
                             //出现灾难的次数
                             _disasterCount++;
                         } else if (_profit.getLossType().equals(3)) {
-                            isBeastProfit = true;
+                            if(DoubleUtil.compare(-1D, _profit.getDsasterId().doubleValue()).equals(0)){
+                                isBeastProfit = true;
+                            }
                             //出现灾难的次数
                             _disasterCount++;
                         }
@@ -272,38 +281,40 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
                     log.info("用户编号:{},防护历史记录:{}", _comPlayerLand.getUserId(), JSONUtil.toJsonStr(protectList));
                     //获得对应灾难类型的防护记录    并得到这个 防护到期时间. 自然灾害类型
                     //如果没有防护或者防护到期。则直接发生灾难进行减产
-                    if (!isNaturalProfit && protectedDate != null && disasterDate.before(protectedDate)) {
+                    if (!isNaturalProfit && (protectedDate == null || disasterDate.after(protectedDate))) {
                         //灾难的随机时间比防护包时间后,说明防护包到期
                         //成熟的时候触发第一次自然灾难
                         ComPlayerProfitVo naturalProfitVo = comPlayerProfitService.addFirstDisasterAndLoss(CopyUtil.copy(_comPlayerLand, ComPlayerLand.class),
-                                comMallSeedVo, 2, _allLossProfit);
+                                comMallSeedVo, 2, _allLossProfit,-1);
                         //多次执行需要加上当前操作的利润
                         _allLossProfit += naturalProfitVo.getStolen();
 
                         //添加自然灾害灾难记录
-                        addDisasterEnable(_comPlayerLand.getUserId(),-1L,2,protectedDate);
+                        addDisasterEnable(_comPlayerLand.getUserId(), -1L, 2, protectedDate);
 
                     }
-                    if (!isBeastProfit && protectedDate != null && disasterDate.before(protectedDate)) {
+                    if (!isBeastProfit && (protectedDate == null || disasterDate.after(protectedDate))) {
                         //灾难的随机时间比防护包时间后,说明防护包到期
                         //成熟的时候触发第一次自然灾难
                         ComPlayerProfitVo beastProfitVo = comPlayerProfitService.addFirstDisasterAndLoss(CopyUtil.copy(_comPlayerLand, ComPlayerLand.class),
-                                comMallSeedVo, 3, _allLossProfit);
+                                comMallSeedVo, 3, _allLossProfit,-1);
                         //多次执行需要加上当前操作的利润
                         _allLossProfit += beastProfitVo.getStolen();
 
                         //添加野兽灾害灾难记录
-                        addDisasterEnable(_comPlayerLand.getUserId(),-1L,3,protectedDate);
+                        addDisasterEnable(_comPlayerLand.getUserId(), -1L, 3, protectedDate);
                     }
 
                     //todo 添加一条单独减产的数据 ,对应灾难
                     comPlayerProfitService.addOtherDisasterAndLoss(CopyUtil.copy(_comPlayerLand, ComPlayerLand.class),
-                            comMallSeedVo, disasterLog.getDsasterType(), _allLossProfit, _disasterCount);
-                }
+                            comMallSeedVo, disasterLog.getDsasterType(), _allLossProfit, _disasterCount,disasterLog.getDsasterId());
 
+                    redisLock.unlock(_disasterKey, String.valueOf(time));
+                } catch (Exception e) {
+                    redisLock.unlock(_disasterKey, String.valueOf(time));
+                    log.error("额外灾难加锁异常:" + e.getMessage());
+                }
             }
-
-
         } else {
             log.info("灾难结果:已防御");
         }
@@ -334,9 +345,9 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
 
 
     @Override
-    public ComPlayerDisasterLog addDisasterEnable(String userId, long disasterTableId,Integer disasterType, Date disasterDay) {
+    public ComPlayerDisasterLog addDisasterEnable(String userId, long disasterTableId, Integer disasterType, Date disasterDay) {
 
-        ComPlayerDisasterEnum disasterEnum = EnumUtil.getEnumAt(ComPlayerDisasterEnum.class,disasterType);
+        ComPlayerDisasterEnum disasterEnum = EnumUtil.likeValueOf(ComPlayerDisasterEnum.class, disasterType);
         ComPlayerDisasterLog disasterLog = new ComPlayerDisasterLog();
         disasterLog.setDsasterId(disasterTableId);
         disasterLog.setDsasterName(disasterEnum.getMsg());
@@ -348,6 +359,8 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
         disasterLog.setShow(false);
         disasterLog.setEnabled(true);
         disasterLog.setDisasterTime(disasterDay);
+
+        save(CopyUtil.copy(disasterLog, ComPlayerDisasterLogVo.class));
         return disasterLog;
     }
 }

+ 1 - 1
src/main/java/com/td/boss/game/complayerland/service/ComPlayerLandServiceImpl.java

@@ -45,7 +45,7 @@ public class ComPlayerLandServiceImpl extends CommonServiceImpl<ComPlayerLandVo,
     public List<ComPlayerLand> findAllByUserIdAndPlantAndMature(String userId) {
         String sql = "SELECT  a.* FROM com_player_land AS a \n" +
                 "WHERE a.user_id = "+userId+" AND a.is_lease = 1 AND a.is_plant = 1 AND DATE_ADD(a.plant_start,INTERVAL a.plant_mature DAY) <= NOW() AND a.lease_time > NOW()";
-        Query nativeQuery = em.createNativeQuery(sql, ComPlayerLandAndCanSteal.class);
+        Query nativeQuery = em.createNativeQuery(sql, ComPlayerLand.class);
         List list = nativeQuery.getResultList();
         return list;
     }

+ 3 - 0
src/main/java/com/td/boss/game/complayerprofit/pojo/ComPlayerProfit.java

@@ -42,6 +42,9 @@ public class ComPlayerProfit implements Serializable {
 
     private Integer lossType;//损失的类型,默认是0:被偷取果实,1:自然灾难,2:野兽
 
+    private Long dsasterId;//遭受的攻击id,-1 代表必然灾害
+
+    private Double addedPart;//增值部分
 
     private Date createTime;//
 

+ 3 - 3
src/main/java/com/td/boss/game/complayerprofit/repository/ComPlayerProfitRepository.java

@@ -26,8 +26,8 @@ public interface ComPlayerProfitRepository extends CommonRepository<ComPlayerPro
 
     Optional<ComPlayerProfit> findByUserIdAndTargetIdAndLandIdAndPlantFlag(String userId, String targetId, Integer landId, String plantFlag);
 
-    Optional<ComPlayerProfit> findByPlantFlagAndLossType(String plantFlag,Integer lossType);
+    Optional<ComPlayerProfit> findByPlantFlagAndLossTypeAndDsasterId(String plantFlag,Integer lossType,long dsasterId);
 
-    @Query(value = "SELECT IFNULL(sum(u.stolen), 0.0) AS sum FROM  com_player_profit u  where u.target_id=:targetId and u.plant_flag = :plantFlag", nativeQuery = true)
-    Double getStolenSumByTargetIdAndPlantFlag(String targetId,String plantFlag);
+    @Query(value = "SELECT IFNULL(sum(u.stolen), 0.0) AS sum FROM  com_player_profit u  where u.target_id=:targetId and u.plant_flag = :plantFlag and u.loss_type = :lossType", nativeQuery = true)
+    Double getStolenSumByTargetIdAndPlantFlagAndLossType(String targetId,String plantFlag,Integer lossType);
 }

+ 4 - 4
src/main/java/com/td/boss/game/complayerprofit/service/ComPlayerProfitService.java

@@ -32,10 +32,10 @@ public interface ComPlayerProfitService extends CommonService<ComPlayerProfitVo,
      * @param lossType {2:自然灾难,3:野兽灾难}
      * @return
      */
-    ComPlayerProfit findByPlantFlagAndLossType(String plantFlag,Integer lossType);
+    ComPlayerProfit findByPlantFlagAndLossTypeAndDsasterId(String plantFlag,Integer lossType,long dsasterId);
 
 
-    Double getStolenSumByOtherUserIdAndPlantFlag(String otherUserId, String plantFlag);
+    Double getStolenSumByOtherUserIdAndPlantFlagAndLossType(String otherUserId, String plantFlag,Integer lossType);
 
     /**
      * 必然灾难减扣
@@ -45,8 +45,8 @@ public interface ComPlayerProfitService extends CommonService<ComPlayerProfitVo,
      * @param allLossProfit
      * @return
      */
-    ComPlayerProfitVo addFirstDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType,Double allLossProfit);
+    ComPlayerProfitVo addFirstDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType,Double allLossProfit,long _dsasterId);
 
-    ComPlayerProfitVo addOtherDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType, Double allLossProfit,Integer disasterCount);
+    ComPlayerProfitVo addOtherDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType, Double allLossProfit,Integer disasterCount,long _dsasterId);
 
 }

+ 49 - 20
src/main/java/com/td/boss/game/complayerprofit/service/ComPlayerProfitServiceImpl.java

@@ -5,6 +5,8 @@ import com.td.boss.common.service.*;
 import com.td.boss.game.commallseed.pojo.ComMallSeed;
 import com.td.boss.game.commallseed.vo.ComMallSeedVo;
 import com.td.boss.game.complayerland.pojo.ComPlayerLand;
+import com.td.boss.game.complayerland.service.ComPlayerLandService;
+import com.td.boss.game.complayerland.vo.ComPlayerLandVo;
 import com.td.boss.game.complayerprofit.pojo.ComPlayerProfit;
 import com.td.boss.game.complayerprofit.vo.ComPlayerProfitVo;
 import com.td.boss.game.complayerprofit.repository.ComPlayerProfitRepository;
@@ -31,6 +33,9 @@ public class ComPlayerProfitServiceImpl extends CommonServiceImpl<ComPlayerProfi
     @Autowired
     private ComPlayerProfitService comPlayerProfitService;
 
+    @Autowired
+    private ComPlayerLandService comPlayerLandService;
+
     @Override
     public List<ComPlayerProfit> findByUserIdAndPlantFlagAndLandId(String userId, String plantFlag, Integer landId) {
         return comPlayerProfitRepository.findByTargetIdAndPlantFlagAndLandId(userId, plantFlag, landId);
@@ -53,18 +58,18 @@ public class ComPlayerProfitServiceImpl extends CommonServiceImpl<ComPlayerProfi
     }
 
     @Override
-    public ComPlayerProfit findByPlantFlagAndLossType(String plantFlag, Integer lossType) {
-        return comPlayerProfitRepository.findByPlantFlagAndLossType(plantFlag, lossType).orElse(null);
+    public ComPlayerProfit findByPlantFlagAndLossTypeAndDsasterId(String plantFlag, Integer lossType,long dsaterId) {
+        return comPlayerProfitRepository.findByPlantFlagAndLossTypeAndDsasterId(plantFlag, lossType,dsaterId).orElse(null);
     }
 
     @Override
-    public Double getStolenSumByOtherUserIdAndPlantFlag(String otherUserId, String plantFlag) {
-        return comPlayerProfitRepository.getStolenSumByTargetIdAndPlantFlag(otherUserId, plantFlag);
+    public Double getStolenSumByOtherUserIdAndPlantFlagAndLossType(String otherUserId, String plantFlag,Integer lossType) {
+        return comPlayerProfitRepository.getStolenSumByTargetIdAndPlantFlagAndLossType(otherUserId, plantFlag,lossType);
     }
 
 
     @Override
-    public ComPlayerProfitVo addFirstDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType, Double allLossProfit) {
+    public ComPlayerProfitVo addFirstDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType, Double allLossProfit ,long _dsasterId) {
 
         //对应土地灾害损失
         ComPlayerProfit comPlayerProfit = new ComPlayerProfit();
@@ -86,12 +91,13 @@ public class ComPlayerProfitServiceImpl extends CommonServiceImpl<ComPlayerProfi
         //todo 计算减产,第一次灾难按利润的 50% 减产,两次就是减到 0 了。
 
         //必然发生的灾难,减产50%
-        Double _reduceProfit = DoubleUtil.mul(_profit, 0.5);
+        Double _firstRatio = 0.4d;
+        Double _reduceProfit = DoubleUtil.mul(_profit, _firstRatio);
         // 100 - 80 = 20
         Double _residualProfit = DoubleUtil.sub(_profit, allLossProfit);
         //剩余利润减去当前需要减产的利润值
         Double _tempProfit = DoubleUtil.sub(_residualProfit, _reduceProfit);
-        if (DoubleUtil.compare(_tempProfit, 0.0).equals(1)) {
+        if (!DoubleUtil.compare(_tempProfit, 0.0).equals(-1)) {
             //还有利润,
             _endReduceProfit = _reduceProfit;
         }
@@ -106,13 +112,17 @@ public class ComPlayerProfitServiceImpl extends CommonServiceImpl<ComPlayerProfi
         comPlayerProfit.setProfit(_profit);//todo 目标用户可偷的初始利润值
         comPlayerProfit.setStolen(_endReduceProfit);//todo 目标用户被灾害减产对应的数量
         comPlayerProfit.setFinalSteal(_endReduceProfit);//
-        comPlayerProfit.setProfitAfter(DoubleUtil.add(allLossProfit, _endReduceProfit)); //当前损失的利润加上当前扣减的
+        comPlayerProfit.setProfitAfter(DoubleUtil.sub(_profit.doubleValue(), DoubleUtil.add(allLossProfit, _endReduceProfit))); //可偷的减去被偷的(包括灾难)
 
-        //记录相关比例,损失利润的百分之50
-        comPlayerProfit.setProfitRatio(0.5);
-        comPlayerProfit.setStealRatio(0.5);
+        //记录相关比例,损失利润的百分之40
+        comPlayerProfit.setProfitRatio(_firstRatio);
+        comPlayerProfit.setStealRatio(_firstRatio);
         comPlayerProfit.setFinalRatio(1.0);
         comPlayerProfit.setLossType(lossType);
+
+        comPlayerProfit.setDsasterId(_dsasterId);
+        comPlayerProfit.setAddedPart(landLevelInCome);
+
         ComPlayerProfitVo comPlayerProfitVo = CopyUtil.copy(comPlayerProfit, ComPlayerProfitVo.class);
         comPlayerProfitService.save(comPlayerProfitVo);
 
@@ -121,7 +131,7 @@ public class ComPlayerProfitServiceImpl extends CommonServiceImpl<ComPlayerProfi
 
 
     @Override
-    public ComPlayerProfitVo addOtherDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType, Double allLossProfit, Integer disasterCount) {
+    public ComPlayerProfitVo addOtherDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType, Double allLossProfit, Integer disasterCount,long _dsasterId) {
 
         //对应土地灾害损失
         ComPlayerProfit comPlayerProfit = new ComPlayerProfit();
@@ -140,22 +150,37 @@ public class ComPlayerProfitServiceImpl extends CommonServiceImpl<ComPlayerProfi
         Double landLevelInCome = getLandLevelInCome(comPlayerLand, comMallSeedVo.getPriceSnb());
         Integer _profitInt = _otherAmount - comPlayerLand.getLeaseMultiple() * comMallSeedVo.getPriceSnb();
         Double _profit =  DoubleUtil.add(_profitInt.doubleValue(),landLevelInCome);
-        //todo 计算减产,第一次灾难按利润的 50% 减产,两次就是减到 0 了
+        //todo 计算减产,第一次灾难按利润的 100 减产 50,两次就是 50 减到 25
 
         //额外发生的灾难,按照次数计算减产 50% 发生已经发生1次计算后当次等于 25%,
-        double _startRatio = 1.0;
+        double _startRatio = 1;
         for(int i = disasterCount;i>0;i--){
             _startRatio =  DoubleUtil.mul(_startRatio,0.5);
         }
         Double _reduceProfit = DoubleUtil.mul(_profit, _startRatio);
         // 100 - 80 = 20
         Double _residualProfit = DoubleUtil.sub(_profit, allLossProfit);
-        //剩余利润减去当前需要减产的利润值
-        Double _tempProfit = DoubleUtil.sub(_residualProfit, _reduceProfit);
-        if (DoubleUtil.compare(_tempProfit, 0.0).equals(1)) {
-            //还有利润,
-            _endReduceProfit = _reduceProfit;
+        //判断当前是否还存在可减去的利润
+        if(DoubleUtil.compare(_residualProfit,0.0).equals(1)){
+            //存在
+            //剩余利润减去当前需要减产的利润值
+            Double _tempProfit = DoubleUtil.sub(_residualProfit, _reduceProfit);
+            if (DoubleUtil.compare(_tempProfit, 0.0).equals(-1)) {
+                //负数说明全部被扣完
+                _endReduceProfit = _residualProfit;
+
+                //更新一下土地状态为不可偷窃状态
+                comPlayerLand.setPlantSteal(0);
+                comPlayerLandService.save(CopyUtil.copy(comPlayerLand, ComPlayerLandVo.class));
+
+            }else{
+                _endReduceProfit = _reduceProfit;
+            }
         }
+        //else{
+        //    //不存在则默认是0
+        //}
+
 
         comPlayerProfit.setUserId(comPlayerLand.getUserId()); //损失记录的用户id
         comPlayerProfit.setTargetId(comPlayerLand.getUserId()); //目标是自己
@@ -167,13 +192,17 @@ public class ComPlayerProfitServiceImpl extends CommonServiceImpl<ComPlayerProfi
         comPlayerProfit.setProfit(_profit);//todo 目标用户可偷的初始利润值
         comPlayerProfit.setStolen(_endReduceProfit);//todo 目标用户被灾害减产对应的数量
         comPlayerProfit.setFinalSteal(_endReduceProfit);//
-        comPlayerProfit.setProfitAfter(DoubleUtil.add(allLossProfit, _endReduceProfit)); //当前损失的利润加上当前扣减的
+        comPlayerProfit.setProfitAfter(DoubleUtil.sub(_profit.doubleValue(), DoubleUtil.add(allLossProfit, _endReduceProfit))); //可偷的减去被偷的(包括灾难)
 
         //记录相关比例,损失利润的 _startRatio 相关比例
         comPlayerProfit.setProfitRatio(_startRatio);
         comPlayerProfit.setStealRatio(_startRatio);
         comPlayerProfit.setFinalRatio(1.0);
         comPlayerProfit.setLossType(lossType);
+
+        comPlayerProfit.setDsasterId(_dsasterId);
+        comPlayerProfit.setAddedPart(landLevelInCome);
+
         ComPlayerProfitVo comPlayerProfitVo = CopyUtil.copy(comPlayerProfit, ComPlayerProfitVo.class);
         comPlayerProfitService.save(comPlayerProfitVo);
 

+ 4 - 0
src/main/java/com/td/boss/game/complayerprofit/vo/ComPlayerProfitVo.java

@@ -40,6 +40,10 @@ public class ComPlayerProfitVo extends PageCondition implements Serializable {
 
     private Integer lossType;//损失的类型,默认是0:被偷取果实,1:自然灾难,2:野兽
 
+    private Long dsasterId;//遭受的攻击id,-1 代表必然灾害
+
+    private Double addedPart;//增值部分
+
     private Date createTime;//
 
     private Date updateTime;//

+ 100 - 28
src/main/java/com/td/boss/game/comsnbapply/controller/ComSnbApplyController.java

@@ -11,12 +11,16 @@ import com.td.boss.game.comsnbapply.service.ComSnbApplyService;
 import com.td.boss.game.comusers.pojo.ComUsers;
 import com.td.boss.game.comusers.service.ComUsersService;
 import com.td.boss.game.comusers.vo.ComUsersVo;
+import com.td.boss.util.CopyUtil;
 import com.td.boss.util.DoubleUtil;
+import com.td.boss.util.RedisData;
+import com.td.boss.util.RedisLock;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.Date;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @RestController
 @RequestMapping("/game/comSnbApply/")
@@ -27,6 +31,9 @@ public class ComSnbApplyController extends CommonController<ComSnbApplyVo, ComSn
     @Autowired
     private ComUsersService comUsersService;
 
+    @Autowired
+    private RedisLock redisLock;
+
 
     @GetMapping("getPage")
     public Result<PageInfo<ComSnbApplyVo>> getPageFunction(@RequestParam(value = "userId") String userId,
@@ -41,39 +48,104 @@ public class ComSnbApplyController extends CommonController<ComSnbApplyVo, ComSn
         return comSnbApplyService.page(comSnbApplyVo);
     }
 
+
     @PostMapping("applySnbToCnt")
     public Result<ComSnbApplyVo> applySnbToCntFunction(@RequestParam(value = "userId") String userId,
                                                        @RequestParam(value = "applyAmount") Integer applyAmount) {
-        //判断输入数量,不能为负数
-        if (applyAmount <= 0) {
-            return Result.of(null, false, ResultEnum.APPLY_SNB_AMOUNT_ERROR.getMessage(), ResultEnum.APPLY_SNB_AMOUNT_ERROR.getCode());
-        }
-        // 判断当前是否累加超过当前用户的snb
-        List<ComSnbApply> comSnbApplies = comSnbApplyService.findAllByUserIdAndIsState(userId, 0);
-        for (int i = 0; i < comSnbApplies.size(); i++) {
-            if(applyAmount.equals(comSnbApplies.get(i).getSnb())){
-                return Result.of(null, false, ResultEnum.APPLY_SNB_HAS_APPLY.getMessage(), ResultEnum.APPLY_SNB_HAS_APPLY.getCode());
+        //加个锁
+        String _redisKey = "applySnbToCnt:" + userId;
+        //todo snb冻结加锁
+        long time = System.currentTimeMillis() + RedisData.getUserApplyTimeout();
+
+        try {
+            // 防止重复操作
+            if (!redisLock.lock(_redisKey, String.valueOf(time))) {
+                return Result.of(null, false, ResultEnum.REDIS_IS_LOCK.getMessage(), ResultEnum.REDIS_IS_LOCK.getCode());
             }
-        }
-        Integer _applySnb = comSnbApplies.stream().mapToInt(ComSnbApply::getSnb).sum();
-        //加上当前的
-        _applySnb += applyAmount;
-
-        ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
-        double _allSnbDouble = DoubleUtil.add(comUsersVo.getSnb().doubleValue(), comUsersVo.getSnbPart());
-        if (DoubleUtil.compare(_allSnbDouble, _applySnb.doubleValue()).equals(-1)) {
-            return Result.of(null, false, ResultEnum.APPLY_SNB_TOO_MUCH.getMessage(), ResultEnum.APPLY_SNB_TOO_MUCH.getCode());
+
+            //判断输入数量,不能为负数
+            if (applyAmount <= 0) {
+                return Result.of(null, false, ResultEnum.APPLY_SNB_AMOUNT_ERROR.getMessage(), ResultEnum.APPLY_SNB_AMOUNT_ERROR.getCode());
+            }
+            // 判断当前是否累加超过当前用户的snb
+            List<ComSnbApply> comSnbApplies = comSnbApplyService.findAllByUserIdAndIsState(userId, 0);
+            List<ComSnbApply> comSnbApplies2 = comSnbApplyService.findAllByUserIdAndIsState(userId, 1);
+            comSnbApplies2.stream().sequential().collect(Collectors.toCollection(() -> comSnbApplies));
+
+            for (int i = 0; i < comSnbApplies.size(); i++) {
+                if (applyAmount.equals(comSnbApplies.get(i).getSnb())) {
+                    return Result.of(null, false, ResultEnum.APPLY_SNB_HAS_APPLY.getMessage(), ResultEnum.APPLY_SNB_HAS_APPLY.getCode());
+                }
+            }
+            Integer _applySnb = comSnbApplies.stream().mapToInt(ComSnbApply::getSnb).sum();
+            //加上当前的
+            _applySnb += applyAmount;
+
+            ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
+            double _allSnbDouble = DoubleUtil.add(comUsersVo.getSnb().doubleValue(), comUsersVo.getSnbPart());
+            if (DoubleUtil.compare(_allSnbDouble, _applySnb.doubleValue()).equals(-1)) {
+                return Result.of(null, false, ResultEnum.APPLY_SNB_TOO_MUCH.getMessage(), ResultEnum.APPLY_SNB_TOO_MUCH.getCode());
+            }
+
+            ComSnbApplyVo comSnbApplyVo = new ComSnbApplyVo();
+            comSnbApplyVo.setUserId(userId);
+            comSnbApplyVo.setAddress(comUsersVo.getAddress());
+            comSnbApplyVo.setSnb(applyAmount);
+            comSnbApplyVo.setSnbDescribe("applySnbToCnt,发起兑换记录snb!");
+            comSnbApplyVo.setIsState(0);
+            comSnbApplyVo.setCreateTime(new Date());
+            comSnbApplyVo.setUpdateTime(new Date());
+
+
+            //保存成功之后,刷新列表
+            return comSnbApplyService.save(comSnbApplyVo);
+        } catch (Exception e) {
+            return Result.of(null, false, ResultEnum.REDIS_IS_LOCK_ERROR.getMessage(), ResultEnum.REDIS_IS_LOCK_ERROR.getCode());
+        } finally {
+            redisLock.unlock(_redisKey, String.valueOf(time));
         }
 
-        ComSnbApplyVo comSnbApplyVo = new ComSnbApplyVo();
-        comSnbApplyVo.setUserId(userId);
-        comSnbApplyVo.setAddress(comUsersVo.getAddress());
-        comSnbApplyVo.setSnb(applyAmount);
-        comSnbApplyVo.setSnbDescribe("applySnbToCnt,发起兑换记录snb!");
-        comSnbApplyVo.setIsState(0);
-        comSnbApplyVo.setCreateTime(new Date());
-        comSnbApplyVo.setUpdateTime(new Date());
-        //保存成功之后,刷新列表
-        return comSnbApplyService.save(comSnbApplyVo);
+
+    }
+
+
+    @PostMapping("checkApplySnbToCnt")
+    public Result<ComSnbApplySimpleVo> checkApplySnbToCntFunction(@RequestParam(value = "userId") String userId,
+                                                                  @RequestParam(value = "certificateId") String certificateId) {
+        //加个锁
+        String _redisKey = "checkApplySnbToCnt:" + userId;
+        //todo snb冻结加锁
+        long time = System.currentTimeMillis() + RedisData.getUserApplyTimeout();
+        try {
+            // 防止重复操作
+            if (!redisLock.lock(_redisKey, String.valueOf(time))) {
+                return Result.of(null, false, ResultEnum.REDIS_IS_LOCK.getMessage(), ResultEnum.REDIS_IS_LOCK.getCode());
+            }
+
+            ComSnbApplyVo comSnbApplyVo = comSnbApplyService.get(certificateId).getData();
+            if (!comSnbApplyVo.getIsState().equals(1)) {
+                return Result.of(null, false, ResultEnum.APPLY_SNB_STATE_ERROR.getMessage(), ResultEnum.APPLY_SNB_STATE_ERROR.getCode());
+            }
+            //判断申请的snb
+            if(comSnbApplyVo.getSnb()<= 0){
+                comSnbApplyVo.setIsState(2);
+                comSnbApplyService.save(comSnbApplyVo);
+                return Result.of(null, false, ResultEnum.APPLY_SNB_AMOUNT_ERROR.getMessage(), ResultEnum.APPLY_SNB_AMOUNT_ERROR.getCode());
+            }
+            ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
+            double _allSnbDouble = DoubleUtil.add(comUsersVo.getSnb().doubleValue(), comUsersVo.getSnbPart());
+
+            if (DoubleUtil.compare(_allSnbDouble,0.0).equals(1) && DoubleUtil.compare(_allSnbDouble, comSnbApplyVo.getSnb().doubleValue()).equals(-1)) {
+                //snb不足时候
+                comSnbApplyVo.setIsState(2);
+                comSnbApplyService.save(comSnbApplyVo);
+                return Result.of(null, false, ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getMessage(), ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getCode());
+            }
+            return Result.of(CopyUtil.copy(comSnbApplyVo, ComSnbApplySimpleVo.class));
+        } catch (Exception e) {
+            return Result.of(null, false, ResultEnum.REDIS_IS_LOCK_ERROR.getMessage(), ResultEnum.REDIS_IS_LOCK_ERROR.getCode());
+        } finally {
+            redisLock.unlock(_redisKey, String.valueOf(time));
+        }
     }
 }

+ 0 - 2
src/main/java/com/td/boss/game/comsnbapply/vo/ComSnbApplySimpleVo.java

@@ -10,8 +10,6 @@ import java.util.Date;
 public class ComSnbApplySimpleVo implements Serializable {
     private String id;//
 
-    private String userId;//
-
     private Integer snb;//游戏的snb
 
     private Integer isState;//0:申请中,1:申请通过,2:申请驳回

+ 74 - 29
src/main/java/com/td/boss/game/comsnbfreeze/controller/ComSnbFreezeController.java

@@ -1,6 +1,7 @@
 package com.td.boss.game.comsnbfreeze.controller;
 
 import cn.hutool.core.date.DateField;
+import cn.hutool.json.JSONUtil;
 import com.td.boss.common.controller.*;
 import com.td.boss.common.pojo.Result;
 import com.td.boss.config.enums.ResultEnum;
@@ -19,6 +20,7 @@ import com.td.boss.game.complayergoods.pojo.ComPlayerGoods;
 import com.td.boss.game.complayergoods.service.ComPlayerGoodsService;
 import com.td.boss.game.complayergoods.vo.ComPlayerGoodsSimpleVo;
 import com.td.boss.game.complayergoods.vo.ComPlayerGoodsVo;
+import com.td.boss.game.complayerland.pojo.ComPlayerDisasterProtected;
 import com.td.boss.game.complayerland.pojo.ComPlayerLand;
 import com.td.boss.game.complayerland.service.ComPlayerDisasterProtectedService;
 import com.td.boss.game.complayerland.service.ComPlayerLandService;
@@ -37,10 +39,7 @@ 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.CopyUtil;
-import com.td.boss.util.DateUtil;
-import com.td.boss.util.RedisData;
-import com.td.boss.util.RedisLock;
+import com.td.boss.util.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -90,6 +89,8 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
 
     @Autowired
     private ComMallOtherService comMallOtherService;
+    @Autowired
+    private ComPlayerDisasterProtectedService disasterProtectedService;
 
 
     /**
@@ -134,13 +135,13 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
             //return Result.of(map, false, ResultEnum.WALLET_SNB_SIGN_ERROR.getMessage(), ResultEnum.WALLET_SNB_SIGN_ERROR.getCode());
             return Result.of(map);
         }
-        if(snbAmount <= 0){
+        if (snbAmount <= 0) {
             map.put("msg", "snb小于等于0,记录异常!");
             return Result.of(map);
         }
         //todo 新增一个判断当前交易是否存在对应snb通过审核的
-        ComSnbApply comSnbApply = comSnbApplyService.findByUserIdAndSnbAndIsState(id.toString(),snbAmount,1);
-        if(comSnbApply == null){
+        ComSnbApply comSnbApply = comSnbApplyService.findByUserIdAndSnbAndIsState(id.toString(), snbAmount, 1);
+        if (comSnbApply == null) {
             comSnbApply.setIsState(2);
             comSnbApplyService.save(CopyUtil.copy(comSnbApply, ComSnbApplyVo.class));
             map.put("msg", "此交易未通过审核,返回给用户账户待用户提交审核");
@@ -247,7 +248,7 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
         }
 
         ComSnbFreezeVo comSnbFreezeVo = comSnbFreezeService.findById(snbId);
-        if(comSnbFreezeVo.getSnb()<=0){
+        if (comSnbFreezeVo.getSnb() <= 0) {
             map.put("msg", "snb是小于0?");
             return Result.of(map);
         }
@@ -373,11 +374,11 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
             comCntOrderVo.setPayType(pay_type);
             comCntOrderVo.setTxHash(tx_hash);
 
-            if (Double.parseDouble(pay_amount) <= 0) {
+            if (DoubleUtil.compare(Double.parseDouble(pay_amount), 0d).equals(-1)) {
                 comCntOrderVo.setCntDescribe("非法操作pay_amount CNT:" + pay_amount);
                 comCntOrderService.save(comCntOrderVo);
                 result.put("msg", "非法操作!");
-                 return Result.of(result);
+                return Result.of(result);
             }
 
             if (comCntOrderVo.getPayType().equals(1) //3个月
@@ -495,13 +496,13 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
             } else if (comCntOrderVo.getPayType().equals(2)) {
                 //获取当前防护包价格,判断
                 ComMallOther comMallOther = comMallOtherService.findByOtherType(2);
-                if(comMallOther == null){
+                if (comMallOther == null) {
                     comCntOrderVo.setCntDescribe("非法操作 comMallOther is null");
                     comCntOrderService.save(comCntOrderVo);
                     result.put("msg", "商品不存在!");
                     return Result.of(result);
                 }
-                if(!comMallOther.getPriceCnt().equals(pay_amount)){
+                if (!comMallOther.getPriceCnt().equals(Integer.parseInt(pay_amount))) {
                     comCntOrderVo.setCntDescribe("非法操作 pay_amount !");
                     comCntOrderService.save(comCntOrderVo);
                     result.put("msg", "pay_amount error!");
@@ -509,24 +510,44 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
                 }
                 comCntOrderVo.setCntDescribe("自然灾害防护");
                 // todo 每购买一次防护,插入一条记录 ?
-                ComPlayerDisasterProtectedVo comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
-                comPlayerDisasterProtected.setCreateTime(new Date());
-                comPlayerDisasterProtected.setUserId(id.toString());
-                comPlayerDisasterProtected.setDsasterType(ComPlayerDisasterEnum.ziran.getCode());
-                comPlayerDisasterProtected.setDsasterName(ComPlayerDisasterEnum.ziran.getMsg());
-                comPlayerDisasterProtected.setProtectTime(cn.hutool.core.date.DateUtil.date(new Date()).offset(DateField.DAY_OF_WEEK, 30));
-                comPlayerDisasterProtectedService.save(comPlayerDisasterProtected);
+                List<ComPlayerDisasterProtected> protectList = disasterProtectedService.getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(id.toString());
+                log.info("用户编号:{},防护历史记录:{}", id.toString(), JSONUtil.toJsonStr(protectList));
+                //获得对应灾难类型的防护记录    并得到这个 防护到期时间
+                ComPlayerDisasterProtected _disasterProtected = protectList.stream()
+                        .filter(a -> a.getDsasterType().equals(2))
+                        .sorted(Comparator.comparing(ComPlayerDisasterProtected::getProtectTime).reversed())
+                        .findFirst().orElse(null);
+                Date now = new Date();
+                if(_disasterProtected == null || now.after(_disasterProtected.getProtectTime())){
+                    //如果不存在或者过期
+                    ComPlayerDisasterProtectedVo comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
+                    comPlayerDisasterProtected.setCreateTime(now);
+                    comPlayerDisasterProtected.setUserId(id.toString());
+                    comPlayerDisasterProtected.setDsasterType(ComPlayerDisasterEnum.ziran.getCode());
+                    comPlayerDisasterProtected.setDsasterName(ComPlayerDisasterEnum.ziran.getMsg());
+                    comPlayerDisasterProtected.setProtectTime(DateUtil.getOldDateAddDay(now,comMallOther.getEffectiveDay()));
+                    comPlayerDisasterProtectedService.save(comPlayerDisasterProtected);
+                } else {
+                    //存在还未过期,把时间叠加到新的数据上面去
+                    ComPlayerDisasterProtectedVo comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
+                    comPlayerDisasterProtected.setCreateTime(now);
+                    comPlayerDisasterProtected.setUserId(id.toString());
+                    comPlayerDisasterProtected.setDsasterType(ComPlayerDisasterEnum.ziran.getCode());
+                    comPlayerDisasterProtected.setDsasterName(ComPlayerDisasterEnum.ziran.getMsg());
+                    comPlayerDisasterProtected.setProtectTime(DateUtil.getOldDateAddDay(_disasterProtected.getProtectTime(),comMallOther.getEffectiveDay()));
+                    comPlayerDisasterProtectedService.save(comPlayerDisasterProtected);
+                }
 
             } else if (comCntOrderVo.getPayType().equals(3)) {
                 //获取当前防护包价格,判断
                 ComMallOther comMallOther = comMallOtherService.findByOtherType(3);
-                if(comMallOther == null){
+                if (comMallOther == null) {
                     comCntOrderVo.setCntDescribe("非法操作 comMallOther is null");
                     comCntOrderService.save(comCntOrderVo);
                     result.put("msg", "商品不存在!");
                     return Result.of(result);
                 }
-                if(!comMallOther.getPriceCnt().equals(pay_amount)){
+                if (!comMallOther.getPriceCnt().equals(Integer.parseInt(pay_amount))) {
                     comCntOrderVo.setCntDescribe("非法操作 pay_amount !");
                     comCntOrderService.save(comCntOrderVo);
                     result.put("msg", "pay_amount error!");
@@ -534,14 +555,38 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
                 }
                 comCntOrderVo.setCntDescribe("野兽防护");
                 // todo 每购买一次防护,插入一条记录 ?
-                ComPlayerDisasterProtectedVo comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
-                comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
-                comPlayerDisasterProtected.setCreateTime(new Date());
-                comPlayerDisasterProtected.setUserId(id.toString());
-                comPlayerDisasterProtected.setDsasterType(ComPlayerDisasterEnum.yeshou.getCode());
-                comPlayerDisasterProtected.setDsasterName(ComPlayerDisasterEnum.yeshou.getMsg());
-                comPlayerDisasterProtected.setProtectTime(cn.hutool.core.date.DateUtil.date(new Date()).offset(DateField.DAY_OF_WEEK, -30));
-                comPlayerDisasterProtectedService.save(comPlayerDisasterProtected);
+                List<ComPlayerDisasterProtected> protectList = disasterProtectedService.getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(id.toString());
+                log.info("用户编号:{},防护历史记录:{}", id.toString(), JSONUtil.toJsonStr(protectList));
+                //获得对应灾难类型的防护记录    并得到这个 防护到期时间
+                ComPlayerDisasterProtected _disasterProtected = protectList.stream()
+                        .filter(a -> a.getDsasterType().equals(3))
+                        .sorted(Comparator.comparing(ComPlayerDisasterProtected::getProtectTime).reversed())
+                        .findFirst().orElse(null);
+                Date now = new Date();
+                if(_disasterProtected == null || now.after(_disasterProtected.getProtectTime())){
+                    //如果不存在或者过期
+                    ComPlayerDisasterProtectedVo comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
+                    comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
+                    comPlayerDisasterProtected.setCreateTime(now);
+                    comPlayerDisasterProtected.setUserId(id.toString());
+                    comPlayerDisasterProtected.setDsasterType(ComPlayerDisasterEnum.yeshou.getCode());
+                    comPlayerDisasterProtected.setDsasterName(ComPlayerDisasterEnum.yeshou.getMsg());
+                    comPlayerDisasterProtected.setProtectTime(DateUtil.getOldDateAddDay(now,comMallOther.getEffectiveDay()));
+                    comPlayerDisasterProtectedService.save(comPlayerDisasterProtected);
+
+                } else {
+                    //存在还未过期,把时间叠加到新的数据上面去
+                    ComPlayerDisasterProtectedVo comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
+                    comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
+                    comPlayerDisasterProtected.setCreateTime(now);
+                    comPlayerDisasterProtected.setUserId(id.toString());
+                    comPlayerDisasterProtected.setDsasterType(ComPlayerDisasterEnum.yeshou.getCode());
+                    comPlayerDisasterProtected.setDsasterName(ComPlayerDisasterEnum.yeshou.getMsg());
+                    comPlayerDisasterProtected.setProtectTime(DateUtil.getOldDateAddDay(_disasterProtected.getProtectTime(),comMallOther.getEffectiveDay()));
+                    comPlayerDisasterProtectedService.save(comPlayerDisasterProtected);
+
+                }
+
             } else if (comCntOrderVo.getPayType().equals(4)) {
 
                 // 验证种子价格是否和服务器一样,不一样判定非法操作

+ 10 - 2
src/main/java/com/td/boss/util/RedisData.java

@@ -32,9 +32,9 @@ public class RedisData {
     }
 
     /**
-     * 60s 第一次触发灾难锁
+     * 10s 第一次触发灾难锁
      */
-    private static final int PLAYER_DISASTERS_FIRST_TIMEOUT = 60 * 1000; //超时时间 60s
+    private static final int PLAYER_DISASTERS_FIRST_TIMEOUT = 10 * 1000; //超时时间 10s
     public static int getPlayerDisastersFirstTimeout() {
         return PLAYER_DISASTERS_FIRST_TIMEOUT;
     }
@@ -83,4 +83,12 @@ public class RedisData {
     public static int getAutoApplyTimeout () {
         return AUTO_APPLY_TIMEOUT;
     }
+
+    /**
+     * 20s 用户申请锁
+     */
+    private static final int USER_APPLY_TIMEOUT = 1000 * 20;
+    public static int getUserApplyTimeout () {
+        return USER_APPLY_TIMEOUT;
+    }
 }

+ 1 - 1
src/main/resources/application.yml

@@ -77,7 +77,7 @@ captcha:
   enable: false
 
 apply:
-  ip: 192.168.0.109
+  ip:  "" #183.52.205.93
 
 ---
 ##### dev 配置 #######

+ 1 - 1
src/test/java/com/td/boss/ComPlayerDisasterLogTests.java

@@ -30,7 +30,7 @@ class ComPlayerDisasterLogTests {
     @Autowired
     private ComCntToSnbService comCntToSnbService;
 
-    private String userId = "1002";
+    private String userId = "4";
 
     /**
      * 防护灾难