xst пре 4 година
родитељ
комит
463ab98d2e
45 измењених фајлова са 1635 додато и 345 уклоњено
  1. 1 0
      README.md
  2. 1 1
      pom.xml
  3. 17 0
      src/main/java/com/td/boss/BossApplication.java
  4. 3 0
      src/main/java/com/td/boss/config/enums/ResultEnum.java
  5. 2 0
      src/main/java/com/td/boss/game/commallother/pojo/ComMallOther.java
  6. 2 0
      src/main/java/com/td/boss/game/commallother/vo/ComMallOtherSimpleVo.java
  7. 2 0
      src/main/java/com/td/boss/game/commallother/vo/ComMallOtherVo.java
  8. 13 9
      src/main/java/com/td/boss/game/commallseed/controller/ComMallSeedController.java
  9. 9 0
      src/main/java/com/td/boss/game/complayerdog/controller/ComPlayerDogController.java
  10. 239 228
      src/main/java/com/td/boss/game/complayergoods/controller/ComPlayerGoodsController.java
  11. 100 0
      src/main/java/com/td/boss/game/complayerland/controller/ComPlayerLandController.java
  12. 6 6
      src/main/java/com/td/boss/game/complayerland/scheduled/QuartzConfig.java
  13. 91 3
      src/main/java/com/td/boss/game/complayerland/service/ComPlayerDisasterLogServiceImpl.java
  14. 7 0
      src/main/java/com/td/boss/game/complayerland/service/ComPlayerLandService.java
  15. 9 0
      src/main/java/com/td/boss/game/complayerland/service/ComPlayerLandServiceImpl.java
  16. 3 0
      src/main/java/com/td/boss/game/complayerprofit/pojo/ComPlayerProfit.java
  17. 2 0
      src/main/java/com/td/boss/game/complayerprofit/repository/ComPlayerProfitRepository.java
  18. 29 5
      src/main/java/com/td/boss/game/complayerprofit/service/ComPlayerProfitService.java
  19. 138 9
      src/main/java/com/td/boss/game/complayerprofit/service/ComPlayerProfitServiceImpl.java
  20. 5 1
      src/main/java/com/td/boss/game/complayerprofit/vo/ComPlayerProfitVo.java
  21. 67 0
      src/main/java/com/td/boss/game/comsnbapply/controller/ComSnbApplyController.java
  22. 27 0
      src/main/java/com/td/boss/game/comsnbapply/pojo/ComSnbApply.java
  23. 18 0
      src/main/java/com/td/boss/game/comsnbapply/repository/ComSnbApplyRepository.java
  24. 72 0
      src/main/java/com/td/boss/game/comsnbapply/scheduled/BackService.java
  25. 35 0
      src/main/java/com/td/boss/game/comsnbapply/scheduled/IPCondition.java
  26. 17 0
      src/main/java/com/td/boss/game/comsnbapply/service/ComSnbApplyService.java
  27. 38 0
      src/main/java/com/td/boss/game/comsnbapply/service/ComSnbApplyServiceImpl.java
  28. 25 0
      src/main/java/com/td/boss/game/comsnbapply/vo/ComSnbApplySimpleVo.java
  29. 23 0
      src/main/java/com/td/boss/game/comsnbapply/vo/ComSnbApplyVo.java
  30. 53 4
      src/main/java/com/td/boss/game/comsnbfreeze/controller/ComSnbFreezeController.java
  31. 89 73
      src/main/java/com/td/boss/game/comusers/controller/ComUsersController.java
  32. 33 0
      src/main/java/com/td/boss/sys/sysGame/controller/sysGamePropertyController.java
  33. 1 0
      src/main/java/com/td/boss/sys/sysGame/controller/sysGameUsersController.java
  34. 15 0
      src/main/java/com/td/boss/sys/syssettingtask/controller/SysSettingTaskController.java
  35. 21 0
      src/main/java/com/td/boss/sys/syssettingtask/pojo/SysSettingTask.java
  36. 9 0
      src/main/java/com/td/boss/sys/syssettingtask/repository/SysSettingTaskRepository.java
  37. 8 0
      src/main/java/com/td/boss/sys/syssettingtask/service/SysSettingTaskService.java
  38. 36 0
      src/main/java/com/td/boss/sys/syssettingtask/service/SysSettingTaskServiceImpl.java
  39. 17 0
      src/main/java/com/td/boss/sys/syssettingtask/vo/SysSettingTaskVo.java
  40. 7 6
      src/main/java/com/td/boss/util/CodeDOM.java
  41. 21 0
      src/main/java/com/td/boss/util/RedisData.java
  42. 32 0
      src/main/java/com/td/boss/util/SysSettingTaskUtil.java
  43. 22 0
      src/main/resources/static/sys/aComApplySNBToCNT/css/applySNBToCNT.css
  44. 196 0
      src/main/resources/static/sys/aComApplySNBToCNT/js/applySNBToCNT.js
  45. 74 0
      src/main/resources/view/sys/aComApplySNBToCNT/applySNBToCNT.html

+ 1 - 0
README.md

@@ -1,4 +1,5 @@
 # 后端的大概说明:
+## 可使用的编辑器IDEA 2019.2.4
 ## 1.前端对应的api主要在com.td.boss.game 目录下。开发此目录下的control
 <p align='center'>
 <img src='images/1.png' title='images' style='max-width:600px'></img>

+ 1 - 1
pom.xml

@@ -25,7 +25,7 @@
         <dependency>
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>
-            <version>5.3.2</version>
+            <version>5.7.22</version>
         </dependency>
         <dependency>
             <groupId>org.projectlombok</groupId>

+ 17 - 0
src/main/java/com/td/boss/BossApplication.java

@@ -4,6 +4,8 @@ import com.td.boss.game.comusers.service.ComUsersService;
 import com.td.boss.sys.sysmenu.vo.SysMenuVo;
 import com.td.boss.sys.syssetting.service.SysSettingService;
 import com.td.boss.sys.syssetting.vo.SysSettingVo;
+import com.td.boss.sys.syssettingtask.service.SysSettingTaskService;
+import com.td.boss.sys.syssettingtask.vo.SysSettingTaskVo;
 import com.td.boss.sys.sysshortcutmenu.service.SysShortcutMenuService;
 import com.td.boss.sys.sysshortcutmenu.vo.SysShortcutMenuVo;
 import com.td.boss.sys.sysuser.service.SysUserService;
@@ -69,6 +71,9 @@ class IndexController {
     @Autowired
     private SysSettingService sysSettingService;
 
+    @Autowired
+    private SysSettingTaskService sysSettingTaskService;
+
     @Autowired
     private SysUserMenuService sysUserMenuService;
 
@@ -99,6 +104,10 @@ class IndexController {
                 SysSettingVo sysSettingVo = sysSettingService.get("1").getData();
                 SysSettingUtil.setSysSettingMap(sysSettingVo);
 
+                //系统启动时获取数据库数据,设置到公用静态集合sysSettingTaskMap
+                SysSettingTaskVo sysSettingTaskVo = sysSettingTaskService.get("1").getData();
+                SysSettingTaskUtil.setSysSettingTaskMap(sysSettingTaskVo);
+
                 //获取本机内网IP
                 log.info("启动成功:" + "http://" + InetAddress.getLocalHost().getHostAddress() + ":" + port + contextPath);
             } catch (UnknownHostException e) {
@@ -118,6 +127,10 @@ class IndexController {
         //系统信息
         modelAndView.addObject("sys", SysSettingUtil.getSysSetting());
 
+        //系统审查信息
+        modelAndView.addObject("sysSettingTask", SysSettingTaskUtil.getSysSettingTask());
+
+
         //后端公钥
         String publicKey = RsaUtil.getPublicKey();
         log.info("login后端公钥:" + publicKey);
@@ -146,6 +159,10 @@ class IndexController {
         //系统信息
         modelAndView.addObject("sys", SysSettingUtil.getSysSetting());
 
+        //系统审查信息
+        modelAndView.addObject("sysSettingTask", SysSettingTaskUtil.getSysSettingTask());
+
+
         //登录用户
         SysUserVo sysUserVo = sysUserService.findByLoginName(SecurityUtil.getLoginUser().getUsername()).getData();
         sysUserVo.setPassword(null);//隐藏部分属性

+ 3 - 0
src/main/java/com/td/boss/config/enums/ResultEnum.java

@@ -53,6 +53,9 @@ public enum ResultEnum {
     WALLET_SNB_SUCCESS_NOT_ZERO(603,"snb不可操作"),
     WALLET_SNB_SIGN_ERROR(604,"钱包SNB参数签名错误!"),
 
+    APPLY_SNB_AMOUNT_ERROR(605,"snb参数错误!"),
+    APPLY_SNB_TOO_MUCH(606,"snb申请过多,待审核完成后再申请!"),
+
     //土地数据
     LAND_DATA_ERROR(701,"土地数据不能初始化!"),
     LAND_NOT_LEASE(702,"土地未租赁!"),

+ 2 - 0
src/main/java/com/td/boss/game/commallother/pojo/ComMallOther.java

@@ -21,6 +21,8 @@ public class ComMallOther implements Serializable {
 
     private Integer priceSnb;//
 
+    private Integer priceCnt;//新增一个cnt字段
+
     private Integer amount;//库存数量
 
     private String itemDescribe;//描述一下生产周期

+ 2 - 0
src/main/java/com/td/boss/game/commallother/vo/ComMallOtherSimpleVo.java

@@ -18,6 +18,8 @@ public class ComMallOtherSimpleVo  implements Serializable {
 
     private Integer priceSnb;//
 
+    private Integer priceCnt;//新增一个cnt字段
+
     private Integer amount;//库存数量
 
     private String itemDescribe;//描述一下生产周期

+ 2 - 0
src/main/java/com/td/boss/game/commallother/vo/ComMallOtherVo.java

@@ -16,6 +16,8 @@ public class ComMallOtherVo extends PageCondition implements Serializable {
 
     private Integer priceSnb;//
 
+    private Integer priceCnt;//新增一个cnt字段
+
     private Integer amount;//库存数量
 
     private String itemDescribe;//描述一下生产周期

+ 13 - 9
src/main/java/com/td/boss/game/commallseed/controller/ComMallSeedController.java

@@ -56,6 +56,7 @@ public class ComMallSeedController extends CommonController<ComMallSeedVo, ComMa
 
     @Autowired
     private RedisLock redisLock;
+
     /**
      * 获取商城种子
      *
@@ -84,11 +85,14 @@ public class ComMallSeedController extends CommonController<ComMallSeedVo, ComMa
             @RequestParam(value = "payAmount") Integer payAmount,
             @RequestParam(value = "seedId") Integer seedId
     ) {
-
+        //校验如果前台输入负数
+        Map map = new HashMap();
+        if(payAmount<=0){
+            return Result.of(map, false, ResultEnum.SEED_PLAY_ERROR.getMessage(), ResultEnum.SEED_PLAY_ERROR.getCode());
+        }
         // 处理itemType,种子id ,获取种子类型,设置种子不同的数据
         Integer itemType = seedId;
         ComMallSeedVo seedVo = comMallSeedService.findById(seedId);
-        Map map = new HashMap();
         if (seedVo == null) {
 
             map.put("msg", "非法操作:所修改的种子不存在服务器中!");
@@ -114,16 +118,16 @@ public class ComMallSeedController extends CommonController<ComMallSeedVo, ComMa
 
             //todo 操作snb数量
             ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
-            if (comUsersVo.getSnb() < payAmount) {
+            if ( comUsersVo.getSnb() < payAmount || comUsersVo.getSnb()<=0) {
                 map.put("msg", "账户snb不足");
                 //WALLET_SNB_INSUFFICIENT_QUANTITY(602,"snb不足以支付!")
                 return Result.of(map, false, ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getMessage(), ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getCode());
             }
             //如果数量够,写入修改对应操作
-            Integer _oldSnb = comUsersVo.getSnb();
-            Integer _snb = comUsersVo.getSnb() - payAmount;
+            Integer _oldSnb =  comUsersVo.getSnb();
+            Integer _snb =  comUsersVo.getSnb() - payAmount;
             comUsersVo.setSnb(_snb);
-            comUsersService.save(comUsersVo);
+            comUsersService.save( comUsersVo);
 
             //合法操作记录到仓库中
             ComPlayerGoods entityVo = comPlayerGoodsService.findByUserIdAndIndexAndType(userId, itemType, 0);
@@ -166,13 +170,13 @@ public class ComMallSeedController extends CommonController<ComMallSeedVo, ComMa
             //不涉及交易的设置为0
             _snbTran.setTranAmountPart(0d);
             _snbTran.setTranSnbPart(0d);
-            _snbTran.setBeforeSnbPart(comUsersVo.getSnbPart());
-            _snbTran.setAfterSnbPart(comUsersVo.getSnbPart());
+            _snbTran.setBeforeSnbPart( comUsersVo.getSnbPart());
+            _snbTran.setAfterSnbPart( comUsersVo.getSnbPart());
             comSnbTranService.save(_snbTran);
 
             redisLock.unlock(_redisKey, String.valueOf(time));
             map.put("seed", entityVo.getGoodsIndex());
-            map.put("snb",comUsersVo.getSnb());
+            map.put("snb", comUsersVo.getSnb());
             return Result.of(map);
         }catch (Exception e) {
             redisLock.unlock(_redisKey, String.valueOf(time));

+ 9 - 0
src/main/java/com/td/boss/game/complayerdog/controller/ComPlayerDogController.java

@@ -85,6 +85,10 @@ public class ComPlayerDogController extends CommonController<ComPlayerDogVo, Com
             }
 
             ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
+            if(comUsersVo.getSnb()<=0){
+                return Result.of(map, false, ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getMessage(), ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getCode());
+            }
+
             Double _allSnb = DoubleUtil.add(comUsersVo.getSnb().doubleValue(), comUsersVo.getSnbPart());
             //如果有snb,扣除对应的snb
             Integer _allSnbMaxInt = (int) Math.floor(_allSnb);
@@ -215,6 +219,11 @@ public class ComPlayerDogController extends CommonController<ComPlayerDogVo, Com
             }
             //todo 操作snb数量
             ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
+            if(comUsersVo.getSnb()<=0){
+                redisLock.unlock(_redisKey, String.valueOf(time));
+                return Result.of(map, false, ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getMessage(), ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getCode());
+            }
+
             /**
              * todo 购买狗粮时候snb变动
              */

+ 239 - 228
src/main/java/com/td/boss/game/complayergoods/controller/ComPlayerGoodsController.java

@@ -375,6 +375,8 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
      * <p>
      * <p>
      * 收获时候,操作用户snb时候,需要加锁,防止用户收取时候遗漏计算snb
+     * 狗只有被隐藏状态下才会咬人,小偷被咬才会损失SNB或者体力;
+     * 无论是否被咬,小偷的收获不会改变
      *
      * @param otherUserId
      * @param otherLandId
@@ -411,13 +413,17 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
                 if (_needConsumption > 0) {
                     //口粮足够,工作
                     _dogWork = true;
-                    //狗存在并工作,获取狗的数据
-                    ComMallOtherVo _mallDogData = comMallOtherService.get(_otherDogVo.getOtherIndex()).getData();
-                    Double _triggerPro = _mallDogData.getTriggerPro();//触发概率
-                    if (new Random().nextDouble() <= _triggerPro) {
-                        //被狗咬了
-                        _wasTheDogBitten = true;
+                    //todo 隐藏状态下才会触发咬人
+                    if (_otherDogVo.getIsShow().equals(0)) {
+                        //狗存在并工作,获取狗的数据
+                        ComMallOtherVo _mallDogData = comMallOtherService.get(_otherDogVo.getOtherIndex()).getData();
+                        Double _triggerPro = _mallDogData.getTriggerPro();//触发概率
+                        if (new Random().nextDouble() <= _triggerPro) {
+                            //被狗咬了
+                            _wasTheDogBitten = true;
+                        }
                     }
+
                 }
             }
 
@@ -431,7 +437,7 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
             //todo 判断打狗棒是否到期
             long _stickRunDay = DateUtil.getDays(DateUtil.getNowDate().getTime() - _beatDogStick.getEffectiveStartTime().getTime());
             int _stickRemainingDay = _beatDogStick.getEffectiveDay() - (int) _stickRunDay;
-            if(_stickRemainingDay>0){
+            if (_stickRemainingDay > 0) {
                 //持有打狗棒
                 _holdTheStick = true;
             }
@@ -600,6 +606,7 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
             comPlayerProfit.setProfitRatio(profitConfig);
             comPlayerProfit.setStealRatio(_stealRatio);
             comPlayerProfit.setFinalRatio(finallyGetRatioConfig);
+            comPlayerProfit.setLossType(0);
             ComPlayerProfitVo comPlayerProfitVo = CopyUtil.copy(comPlayerProfit, ComPlayerProfitVo.class);
             comPlayerProfitService.save(comPlayerProfitVo);
 
@@ -744,227 +751,227 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
      * @param otherUserId
      * @return
      */
-    @PostMapping("stealAllFruit")
-    @ResponseBody
-    @Transactional(rollbackFor = Exception.class)
-    public Result<Map> stealAllFruitFunction(
-            @RequestParam(value = "userId") String userId,
-            @RequestParam(value = "otherUserId") String otherUserId) {
-
-        Map map = new HashMap();
-
-        //获取数据库相关配置
-        ComSettingVo comSettingVo = comSettingService.get("1").getData();
-        if (comSettingVo.equals(null)) {
-            return Result.of(null, false, ResultEnum.SETTING_IS_NULL.getMessage(), ResultEnum.SETTING_IS_NULL.getCode());
-        }
-        //todo 后台可配置,获取一个链上数据
-        Integer _configStrength = comSettingVo.getMaxStrength(), _chainStrength = DappUtil.getChildrenCount(userId);
-        //前端的显示,输出一个不小于0的体力值
-        Integer _maxStrength = _configStrength + _chainStrength;
-        //1.先判断用户是否有足够的体力,根据snb判断。2. 收取到果实,扣除用户一个体力值
-        ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
-        ComPlayersAttriVo playersAttribute = comPlayersAttriService.findByUserId(userId);
-        Integer _out = _maxStrength - Math.abs(playersAttribute.getStrength());
-        if (comUsersVo.getSnb() < comSettingVo.getDeductSnb()) {
-            //判断是否有双倍体力
-            if (_out < comSettingVo.getSnbUnitStrength()) {
-                map.put("msg", "需要双倍体力:" + comSettingVo.getSnbUnitStrength());
-                return Result.of(map, false, ResultEnum.PLAYER_ATTRIBUTE_STRENGTH_IS_NOT.getMessage(), ResultEnum.PLAYER_ATTRIBUTE_STRENGTH_IS_NOT.getCode());
-            }
-        } else {
-            //正常判断体力
-            if (_out < comSettingVo.getUnitStrength()) {
-                map.put("msg", "需要单倍体力:" + comSettingVo.getUnitStrength());
-                return Result.of(map, false, ResultEnum.PLAYER_ATTRIBUTE_STRENGTH_IS_NOT.getMessage(), ResultEnum.PLAYER_ATTRIBUTE_STRENGTH_IS_NOT.getCode());
-            }
-        }
-
-        List<Map> _stealLandInfos = new ArrayList<>();
-        Double _finalStealAmountSum = 0d;
-        //todo 偷取用户的对象信息等id
-        List<ComPlayerLandAndCanSteal> otherPlayerLandAndCanSteal = comPlayerLandService.findCanStealByUserIdAndOtherUserId(userId, otherUserId);
-        //List<ComPlayerLand> otherPlayerLands = comPlayerLandService.findAllByCanStealOtherLands(userId, otherUserId);
-        List<ComPlayerLand> otherPlayerLands = new ArrayList<>();
-        for (int i = 0; i < otherPlayerLandAndCanSteal.size(); i++) {
-            if (otherPlayerLandAndCanSteal.get(i).getCanSteal().equals(1)) {
-                otherPlayerLands.add(CopyUtil.copy(otherPlayerLandAndCanSteal.get(i), ComPlayerLand.class));
-            }
-        }
-        if (otherPlayerLands.size() == 0) {
-            return Result.of(null, false, ResultEnum.LAND_CAN_STEAL_IS_ZERO.getMessage(), ResultEnum.LAND_CAN_STEAL_IS_ZERO.getCode());
-        }
-
-        for (int i = 0; i < otherPlayerLands.size(); i++) {
-            ComPlayerLand otherPlayerLand = otherPlayerLands.get(i);
-            //获取当前种植的种子
-            ComMallSeedVo comMallSeedVo = comMallSeedService.findById(otherPlayerLand.getPlantId());
-            //需要redis 加锁
-            long time = System.currentTimeMillis() + RedisData.getPlayerGoodsTimeout();
-            //获取用户的plantFlag,因为之前的用户没有设置这个flag,所以设为第一次,用 userId 和 landId 组合成key
-            String _redisKey = otherPlayerLand.getPlantFlag();
-            if (!StringUtils.hasText(_redisKey)) {
-                //return Result.of(null, false, ResultEnum.LAND_PLANT_FLAG_IS_NULL.getMessage(), ResultEnum.LAND_PLANT_FLAG_IS_NULL.getCode());
-                _redisKey = otherPlayerLand.getUserId() + "or" + otherPlayerLand.getConfigLandId();
-            }
-            try {
-                if (!redisLock.lock(_redisKey, String.valueOf(time))) {
-                    //如果有冲突锁,跳过
-                    continue;
-                }
-                //todo 如果当前人员偷窃水果。记录一个信息,存储当前玩家已偷过的水果的信息
-                //计算一个偷取的收获量, 租赁倍数* 租赁日期下的产量
-                Integer _otherAmount = 0;
-                if (otherPlayerLand.getLeaseDate().equals(1)) {
-                    _otherAmount = otherPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest1();
-                } else if (otherPlayerLand.getLeaseDate().equals(2)) {
-                    _otherAmount = otherPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest2();
-                } else if (otherPlayerLand.getLeaseDate().equals(3)) {
-                    _otherAmount = otherPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest3();
-                }
-                //todo 拿出计算利润,收获量减去种子的成本(snb)后的百分之30 ,后面需要后台可调整
-                Integer _profit = _otherAmount - otherPlayerLand.getLeaseMultiple() * comMallSeedVo.getPriceSnb();
-                // 配置的参数。这里先直接定义
-                Double profitConfig = comSettingVo.getProfit(), stealRatioMaxConfig = comSettingVo.getStealMaxRatio(), stealRatioMinConfig = comSettingVo.getStealMinRatio(), finallyGetRatioConfig = comSettingVo.getFinalRatio();
-                Double _stealRatio = new Random().nextDouble() * DoubleUtil.sub(stealRatioMaxConfig, stealRatioMinConfig) + stealRatioMinConfig;// 1%-3%
-                //todo 被偷取的人扣除 一个损失量,初利润算 _profit
-                Double _stolenAmount = DoubleUtil.mul(_profit.doubleValue(), _stealRatio);
-                //这里根据plantFlag判断目标用户当前种植被偷取完,看下是否需要处理更新前端信息,暂不处理
-                Double _sumStolen = comPlayerProfitService.getStolenSumByOtherUserIdAndPlantFlag(otherUserId, _redisKey);
-                //todo 这里的可偷利润应该是最大值,用户不能超过这个,需要限制判断
-                Double _maxAmount = DoubleUtil.mul(_profit.doubleValue(), profitConfig); //可偷取的利润
-                //1 一键 就是 _sumStolen>_maxAmount 或者 _sumStolen == _maxAmount ,被偷完了
-                if (!DoubleUtil.compare(_sumStolen, _maxAmount).equals(-1)) {
-                    // 需要redis 解锁
-                    redisLock.unlock(_redisKey, String.valueOf(time));
-                    //记录一个不可偷取的状态
-                    otherPlayerLand.setPlantSteal(0);
-                    comPlayerLandService.save(CopyUtil.copy(otherPlayerLand, ComPlayerLandVo.class));
-                    continue;
-                }
-                //计算剩下可偷利润的差,防止过多偷取用户利润 _stolenAmount
-                Double _diff = Math.abs(DoubleUtil.sub(_maxAmount, _sumStolen));
-                if (DoubleUtil.compare(_stolenAmount, _diff).equals(1)) {
-                    //_stolenAmount>_diff
-                    _stolenAmount = _diff;
-                }
-                //最终偷窃人获取的是偷取的是目标用户损失量的10% finallyGetRatioConfig
-                Double _finalStealAmount = DoubleUtil.mul(_stolenAmount, finallyGetRatioConfig);
-                //偷窃后,系统回收部分
-                Double _lostStealAmount = DoubleUtil.sub(1d, finallyGetRatioConfig) * _stolenAmount;
-                //果实 Type =1
-                //todo 增加一个字段处理背包果实,拿出当前用户背包果实
-                ComPlayerGoods comPlayerGoods = comPlayerGoodsService.findByUserIdAndIndexAndType(userId, comMallSeedVo.getHarvestId(), 1);
-                Double _beforeStealAmount = 0.0;
-                if (comPlayerGoods == null) {
-                    //背包增加收取到别的用户对应的类型数量。比如当前是偷取到的果实
-                    comPlayerGoods = new ComPlayerGoods();
-                    comPlayerGoods.setUserId(userId);
-                    comPlayerGoods.setGoodsIndex(comMallSeedVo.getHarvestId());
-                    comPlayerGoods.setGoodsType(1);
-                    comPlayerGoods.setName(comMallSeedVo.getHarvestName());
-                    //用种子的picture
-                    comPlayerGoods.setPictureName(comMallSeedVo.getPicture());
-                    //amount 设置0
-                    comPlayerGoods.setAmount(0);
-                    comPlayerGoods.setAmountPart(_finalStealAmount);
-                    _beforeStealAmount = 0.0;
-                } else {
-                    _beforeStealAmount = comPlayerGoods.getAmountPart();
-                    //修改偷取字段
-                    comPlayerGoods.setAmountPart(DoubleUtil.add(comPlayerGoods.getAmountPart(), _finalStealAmount));
-                }
-                ComPlayerGoodsVo comPlayerGoodsVo = CopyUtil.copy(comPlayerGoods, ComPlayerGoodsVo.class);
-                comPlayerGoodsService.save(comPlayerGoodsVo);
-
-                //todo 偷窃损失,处理目标用户收取果实时候,减扣一部分被偷取的数量
-                ComPlayerProfit comPlayerProfit = new ComPlayerProfit();
-                comPlayerProfit.setUserId(userId);
-                comPlayerProfit.setTargetId(otherUserId);
-                comPlayerProfit.setPlantFlag(_redisKey);
-                comPlayerProfit.setLandId(otherPlayerLand.getConfigLandId());
-                comPlayerProfit.setLeaseMultiple(otherPlayerLand.getLeaseMultiple());
-                comPlayerProfit.setLeaseDate(otherPlayerLand.getLeaseDate());
-                comPlayerProfit.setHarvest(_otherAmount);
-                comPlayerProfit.setProfit(_profit.doubleValue());//目标用户可偷的初始利润值
-                comPlayerProfit.setStolen(_stolenAmount);//目标用户被偷的数量
-                comPlayerProfit.setFinalSteal(_finalStealAmount);//用户最终偷取的量,是被偷的数量 10%左右
-                comPlayerProfit.setProfitAfter(DoubleUtil.sub(_profit.doubleValue(), DoubleUtil.add(_stolenAmount, _sumStolen))); //可偷的减去被偷的
-                //记录相关比例
-                comPlayerProfit.setProfitRatio(profitConfig);
-                comPlayerProfit.setStealRatio(_stealRatio);
-                comPlayerProfit.setFinalRatio(finallyGetRatioConfig);
-                ComPlayerProfitVo comPlayerProfitVo = CopyUtil.copy(comPlayerProfit, ComPlayerProfitVo.class);
-                comPlayerProfitService.save(comPlayerProfitVo);
-
-                //todo 记录一个收获的操作日志,这里由于偷取果实是有小数点的,小数点处理成整数,单位 暂定5位 100000
-                //      这里的数量都与偷窃知道相关。amountPart,注意不是果实实际总数 amount
-                ComPlayerLog _playerLog = new ComPlayerLog();
-                _playerLog.setUserId(userId);
-                _playerLog.setTId(comMallSeedVo.getHarvestId());
-                _playerLog.setTName(comMallSeedVo.getHarvestName());
-                _playerLog.setTType(6);//偷取果实时候,type设置6
-                //偷水果时候这部分数据应该是不变的
-                _playerLog.setTAmount(0);
-                _playerLog.setBeforeAmount(comPlayerGoods.getAmount());
-                _playerLog.setAfterAmount(comPlayerGoods.getAmount());
-                //偷取用户果实时候,收取时候信息记录
-                _playerLog.setBeforePart(_beforeStealAmount);
-                _playerLog.setTPart(_finalStealAmount);
-                _playerLog.setTLoss(_lostStealAmount); //损失的部分
-                _playerLog.setAfterPart(comPlayerGoods.getAmountPart());
-                _playerLog.setLMultiple(otherPlayerLand.getLeaseMultiple());
-                ComPlayerLogVo _playerLogVo = CopyUtil.copy(_playerLog, ComPlayerLogVo.class);
-                comPlayerLogService.save(_playerLogVo);
-
-                //todo 成功收取记录一个土地id
-                Map _landMap = new HashMap();
-                //记录一个id
-                _landMap.put("landId", otherPlayerLand.getConfigLandId());
-                //
-                _landMap.put("stealAmount", _finalStealAmount);
-
-                //固定成本
-                _landMap.put("cost", otherPlayerLand.getLeaseMultiple() * comMallSeedVo.getPriceSnb());
-                //当前利润
-                _landMap.put("profit", _profit);
-                //打印一个比例
-                _landMap.put("profitRatio", profitConfig);
-                _landMap.put("intervalStealRatio", _stealRatio);
-                _landMap.put("finallyGetRatioConfig", finallyGetRatioConfig);
-
-                _finalStealAmountSum = DoubleUtil.add(_finalStealAmount, _finalStealAmountSum);
-                _stealLandInfos.add(_landMap);
-                // 需要redis 解锁
-                redisLock.unlock(_redisKey, String.valueOf(time));
-            } catch (Exception e) {
-                // 需要redis 解锁
-                redisLock.unlock(_redisKey, String.valueOf(time));
-                throw new RuntimeException(e.getMessage());
-            }
-        }
-
-        map.put("msg", "偷取果实.");
-        map.put("steals", _stealLandInfos);
-        map.put("stealSum", _finalStealAmountSum);
-
-        if (_stealLandInfos.size() > 0) {
-            //todo 体力值可以后台配置
-            Integer _addStrength = comUsersVo.getSnb() < comSettingVo.getDeductSnb() ? comSettingVo.getSnbUnitStrength() : comSettingVo.getUnitStrength();
-            playersAttribute.setStrength(playersAttribute.getStrength() + _addStrength);
-            comPlayersAttriService.save(playersAttribute);
-            ComPlayersAttriSimpleVo comPlayersAttriSimpleVo = CopyUtil.copy(playersAttribute, ComPlayersAttriSimpleVo.class);
-            //前端的显示,输出一个不小于0的体力值
-            Integer _outEnd = _maxStrength - Math.abs(playersAttribute.getStrength());
-            comPlayersAttriSimpleVo.setCurrentStrength(_outEnd < 0 ? 0 : _outEnd);
-            //最大值是配置的值和链上数据的值相加
-            comPlayersAttriSimpleVo.setMaxStrength(_maxStrength);
-
-            map.put("playerAttribute", comPlayersAttriSimpleVo);
-        }
-
-        return Result.of(map);
-    }
+//    @PostMapping("stealAllFruit")
+//    @ResponseBody
+//    @Transactional(rollbackFor = Exception.class)
+//    public Result<Map> stealAllFruitFunction(
+//            @RequestParam(value = "userId") String userId,
+//            @RequestParam(value = "otherUserId") String otherUserId) {
+//
+//        Map map = new HashMap();
+//
+//        //获取数据库相关配置
+//        ComSettingVo comSettingVo = comSettingService.get("1").getData();
+//        if (comSettingVo.equals(null)) {
+//            return Result.of(null, false, ResultEnum.SETTING_IS_NULL.getMessage(), ResultEnum.SETTING_IS_NULL.getCode());
+//        }
+//        //todo 后台可配置,获取一个链上数据
+//        Integer _configStrength = comSettingVo.getMaxStrength(), _chainStrength = DappUtil.getChildrenCount(userId);
+//        //前端的显示,输出一个不小于0的体力值
+//        Integer _maxStrength = _configStrength + _chainStrength;
+//        //1.先判断用户是否有足够的体力,根据snb判断。2. 收取到果实,扣除用户一个体力值
+//        ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
+//        ComPlayersAttriVo playersAttribute = comPlayersAttriService.findByUserId(userId);
+//        Integer _out = _maxStrength - Math.abs(playersAttribute.getStrength());
+//        if (comUsersVo.getSnb() < comSettingVo.getDeductSnb()) {
+//            //判断是否有双倍体力
+//            if (_out < comSettingVo.getSnbUnitStrength()) {
+//                map.put("msg", "需要双倍体力:" + comSettingVo.getSnbUnitStrength());
+//                return Result.of(map, false, ResultEnum.PLAYER_ATTRIBUTE_STRENGTH_IS_NOT.getMessage(), ResultEnum.PLAYER_ATTRIBUTE_STRENGTH_IS_NOT.getCode());
+//            }
+//        } else {
+//            //正常判断体力
+//            if (_out < comSettingVo.getUnitStrength()) {
+//                map.put("msg", "需要单倍体力:" + comSettingVo.getUnitStrength());
+//                return Result.of(map, false, ResultEnum.PLAYER_ATTRIBUTE_STRENGTH_IS_NOT.getMessage(), ResultEnum.PLAYER_ATTRIBUTE_STRENGTH_IS_NOT.getCode());
+//            }
+//        }
+//
+//        List<Map> _stealLandInfos = new ArrayList<>();
+//        Double _finalStealAmountSum = 0d;
+//        //todo 偷取用户的对象信息等id
+//        List<ComPlayerLandAndCanSteal> otherPlayerLandAndCanSteal = comPlayerLandService.findCanStealByUserIdAndOtherUserId(userId, otherUserId);
+//        //List<ComPlayerLand> otherPlayerLands = comPlayerLandService.findAllByCanStealOtherLands(userId, otherUserId);
+//        List<ComPlayerLand> otherPlayerLands = new ArrayList<>();
+//        for (int i = 0; i < otherPlayerLandAndCanSteal.size(); i++) {
+//            if (otherPlayerLandAndCanSteal.get(i).getCanSteal().equals(1)) {
+//                otherPlayerLands.add(CopyUtil.copy(otherPlayerLandAndCanSteal.get(i), ComPlayerLand.class));
+//            }
+//        }
+//        if (otherPlayerLands.size() == 0) {
+//            return Result.of(null, false, ResultEnum.LAND_CAN_STEAL_IS_ZERO.getMessage(), ResultEnum.LAND_CAN_STEAL_IS_ZERO.getCode());
+//        }
+//
+//        for (int i = 0; i < otherPlayerLands.size(); i++) {
+//            ComPlayerLand otherPlayerLand = otherPlayerLands.get(i);
+//            //获取当前种植的种子
+//            ComMallSeedVo comMallSeedVo = comMallSeedService.findById(otherPlayerLand.getPlantId());
+//            //需要redis 加锁
+//            long time = System.currentTimeMillis() + RedisData.getPlayerGoodsTimeout();
+//            //获取用户的plantFlag,因为之前的用户没有设置这个flag,所以设为第一次,用 userId 和 landId 组合成key
+//            String _redisKey = otherPlayerLand.getPlantFlag();
+//            if (!StringUtils.hasText(_redisKey)) {
+//                //return Result.of(null, false, ResultEnum.LAND_PLANT_FLAG_IS_NULL.getMessage(), ResultEnum.LAND_PLANT_FLAG_IS_NULL.getCode());
+//                _redisKey = otherPlayerLand.getUserId() + "or" + otherPlayerLand.getConfigLandId();
+//            }
+//            try {
+//                if (!redisLock.lock(_redisKey, String.valueOf(time))) {
+//                    //如果有冲突锁,跳过
+//                    continue;
+//                }
+//                //todo 如果当前人员偷窃水果。记录一个信息,存储当前玩家已偷过的水果的信息
+//                //计算一个偷取的收获量, 租赁倍数* 租赁日期下的产量
+//                Integer _otherAmount = 0;
+//                if (otherPlayerLand.getLeaseDate().equals(1)) {
+//                    _otherAmount = otherPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest1();
+//                } else if (otherPlayerLand.getLeaseDate().equals(2)) {
+//                    _otherAmount = otherPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest2();
+//                } else if (otherPlayerLand.getLeaseDate().equals(3)) {
+//                    _otherAmount = otherPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest3();
+//                }
+//                //todo 拿出计算利润,收获量减去种子的成本(snb)后的百分之30 ,后面需要后台可调整
+//                Integer _profit = _otherAmount - otherPlayerLand.getLeaseMultiple() * comMallSeedVo.getPriceSnb();
+//                // 配置的参数。这里先直接定义
+//                Double profitConfig = comSettingVo.getProfit(), stealRatioMaxConfig = comSettingVo.getStealMaxRatio(), stealRatioMinConfig = comSettingVo.getStealMinRatio(), finallyGetRatioConfig = comSettingVo.getFinalRatio();
+//                Double _stealRatio = new Random().nextDouble() * DoubleUtil.sub(stealRatioMaxConfig, stealRatioMinConfig) + stealRatioMinConfig;// 1%-3%
+//                //todo 被偷取的人扣除 一个损失量,初利润算 _profit
+//                Double _stolenAmount = DoubleUtil.mul(_profit.doubleValue(), _stealRatio);
+//                //这里根据plantFlag判断目标用户当前种植被偷取完,看下是否需要处理更新前端信息,暂不处理
+//                Double _sumStolen = comPlayerProfitService.getStolenSumByOtherUserIdAndPlantFlag(otherUserId, _redisKey);
+//                //todo 这里的可偷利润应该是最大值,用户不能超过这个,需要限制判断
+//                Double _maxAmount = DoubleUtil.mul(_profit.doubleValue(), profitConfig); //可偷取的利润
+//                //1 一键 就是 _sumStolen>_maxAmount 或者 _sumStolen == _maxAmount ,被偷完了
+//                if (!DoubleUtil.compare(_sumStolen, _maxAmount).equals(-1)) {
+//                    // 需要redis 解锁
+//                    redisLock.unlock(_redisKey, String.valueOf(time));
+//                    //记录一个不可偷取的状态
+//                    otherPlayerLand.setPlantSteal(0);
+//                    comPlayerLandService.save(CopyUtil.copy(otherPlayerLand, ComPlayerLandVo.class));
+//                    continue;
+//                }
+//                //计算剩下可偷利润的差,防止过多偷取用户利润 _stolenAmount
+//                Double _diff = Math.abs(DoubleUtil.sub(_maxAmount, _sumStolen));
+//                if (DoubleUtil.compare(_stolenAmount, _diff).equals(1)) {
+//                    //_stolenAmount>_diff
+//                    _stolenAmount = _diff;
+//                }
+//                //最终偷窃人获取的是偷取的是目标用户损失量的10% finallyGetRatioConfig
+//                Double _finalStealAmount = DoubleUtil.mul(_stolenAmount, finallyGetRatioConfig);
+//                //偷窃后,系统回收部分
+//                Double _lostStealAmount = DoubleUtil.sub(1d, finallyGetRatioConfig) * _stolenAmount;
+//                //果实 Type =1
+//                //todo 增加一个字段处理背包果实,拿出当前用户背包果实
+//                ComPlayerGoods comPlayerGoods = comPlayerGoodsService.findByUserIdAndIndexAndType(userId, comMallSeedVo.getHarvestId(), 1);
+//                Double _beforeStealAmount = 0.0;
+//                if (comPlayerGoods == null) {
+//                    //背包增加收取到别的用户对应的类型数量。比如当前是偷取到的果实
+//                    comPlayerGoods = new ComPlayerGoods();
+//                    comPlayerGoods.setUserId(userId);
+//                    comPlayerGoods.setGoodsIndex(comMallSeedVo.getHarvestId());
+//                    comPlayerGoods.setGoodsType(1);
+//                    comPlayerGoods.setName(comMallSeedVo.getHarvestName());
+//                    //用种子的picture
+//                    comPlayerGoods.setPictureName(comMallSeedVo.getPicture());
+//                    //amount 设置0
+//                    comPlayerGoods.setAmount(0);
+//                    comPlayerGoods.setAmountPart(_finalStealAmount);
+//                    _beforeStealAmount = 0.0;
+//                } else {
+//                    _beforeStealAmount = comPlayerGoods.getAmountPart();
+//                    //修改偷取字段
+//                    comPlayerGoods.setAmountPart(DoubleUtil.add(comPlayerGoods.getAmountPart(), _finalStealAmount));
+//                }
+//                ComPlayerGoodsVo comPlayerGoodsVo = CopyUtil.copy(comPlayerGoods, ComPlayerGoodsVo.class);
+//                comPlayerGoodsService.save(comPlayerGoodsVo);
+//
+//                //todo 偷窃损失,处理目标用户收取果实时候,减扣一部分被偷取的数量
+//                ComPlayerProfit comPlayerProfit = new ComPlayerProfit();
+//                comPlayerProfit.setUserId(userId);
+//                comPlayerProfit.setTargetId(otherUserId);
+//                comPlayerProfit.setPlantFlag(_redisKey);
+//                comPlayerProfit.setLandId(otherPlayerLand.getConfigLandId());
+//                comPlayerProfit.setLeaseMultiple(otherPlayerLand.getLeaseMultiple());
+//                comPlayerProfit.setLeaseDate(otherPlayerLand.getLeaseDate());
+//                comPlayerProfit.setHarvest(_otherAmount);
+//                comPlayerProfit.setProfit(_profit.doubleValue());//目标用户可偷的初始利润值
+//                comPlayerProfit.setStolen(_stolenAmount);//目标用户被偷的数量
+//                comPlayerProfit.setFinalSteal(_finalStealAmount);//用户最终偷取的量,是被偷的数量 10%左右
+//                comPlayerProfit.setProfitAfter(DoubleUtil.sub(_profit.doubleValue(), DoubleUtil.add(_stolenAmount, _sumStolen))); //可偷的减去被偷的
+//                //记录相关比例
+//                comPlayerProfit.setProfitRatio(profitConfig);
+//                comPlayerProfit.setStealRatio(_stealRatio);
+//                comPlayerProfit.setFinalRatio(finallyGetRatioConfig);
+//                ComPlayerProfitVo comPlayerProfitVo = CopyUtil.copy(comPlayerProfit, ComPlayerProfitVo.class);
+//                comPlayerProfitService.save(comPlayerProfitVo);
+//
+//                //todo 记录一个收获的操作日志,这里由于偷取果实是有小数点的,小数点处理成整数,单位 暂定5位 100000
+//                //      这里的数量都与偷窃知道相关。amountPart,注意不是果实实际总数 amount
+//                ComPlayerLog _playerLog = new ComPlayerLog();
+//                _playerLog.setUserId(userId);
+//                _playerLog.setTId(comMallSeedVo.getHarvestId());
+//                _playerLog.setTName(comMallSeedVo.getHarvestName());
+//                _playerLog.setTType(6);//偷取果实时候,type设置6
+//                //偷水果时候这部分数据应该是不变的
+//                _playerLog.setTAmount(0);
+//                _playerLog.setBeforeAmount(comPlayerGoods.getAmount());
+//                _playerLog.setAfterAmount(comPlayerGoods.getAmount());
+//                //偷取用户果实时候,收取时候信息记录
+//                _playerLog.setBeforePart(_beforeStealAmount);
+//                _playerLog.setTPart(_finalStealAmount);
+//                _playerLog.setTLoss(_lostStealAmount); //损失的部分
+//                _playerLog.setAfterPart(comPlayerGoods.getAmountPart());
+//                _playerLog.setLMultiple(otherPlayerLand.getLeaseMultiple());
+//                ComPlayerLogVo _playerLogVo = CopyUtil.copy(_playerLog, ComPlayerLogVo.class);
+//                comPlayerLogService.save(_playerLogVo);
+//
+//                //todo 成功收取记录一个土地id
+//                Map _landMap = new HashMap();
+//                //记录一个id
+//                _landMap.put("landId", otherPlayerLand.getConfigLandId());
+//                //
+//                _landMap.put("stealAmount", _finalStealAmount);
+//
+//                //固定成本
+//                _landMap.put("cost", otherPlayerLand.getLeaseMultiple() * comMallSeedVo.getPriceSnb());
+//                //当前利润
+//                _landMap.put("profit", _profit);
+//                //打印一个比例
+//                _landMap.put("profitRatio", profitConfig);
+//                _landMap.put("intervalStealRatio", _stealRatio);
+//                _landMap.put("finallyGetRatioConfig", finallyGetRatioConfig);
+//
+//                _finalStealAmountSum = DoubleUtil.add(_finalStealAmount, _finalStealAmountSum);
+//                _stealLandInfos.add(_landMap);
+//                // 需要redis 解锁
+//                redisLock.unlock(_redisKey, String.valueOf(time));
+//            } catch (Exception e) {
+//                // 需要redis 解锁
+//                redisLock.unlock(_redisKey, String.valueOf(time));
+//                throw new RuntimeException(e.getMessage());
+//            }
+//        }
+//
+//        map.put("msg", "偷取果实.");
+//        map.put("steals", _stealLandInfos);
+//        map.put("stealSum", _finalStealAmountSum);
+//
+//        if (_stealLandInfos.size() > 0) {
+//            //todo 体力值可以后台配置
+//            Integer _addStrength = comUsersVo.getSnb() < comSettingVo.getDeductSnb() ? comSettingVo.getSnbUnitStrength() : comSettingVo.getUnitStrength();
+//            playersAttribute.setStrength(playersAttribute.getStrength() + _addStrength);
+//            comPlayersAttriService.save(playersAttribute);
+//            ComPlayersAttriSimpleVo comPlayersAttriSimpleVo = CopyUtil.copy(playersAttribute, ComPlayersAttriSimpleVo.class);
+//            //前端的显示,输出一个不小于0的体力值
+//            Integer _outEnd = _maxStrength - Math.abs(playersAttribute.getStrength());
+//            comPlayersAttriSimpleVo.setCurrentStrength(_outEnd < 0 ? 0 : _outEnd);
+//            //最大值是配置的值和链上数据的值相加
+//            comPlayersAttriSimpleVo.setMaxStrength(_maxStrength);
+//
+//            map.put("playerAttribute", comPlayersAttriSimpleVo);
+//        }
+//
+//        return Result.of(map);
+//    }
 
 
     /**
@@ -984,6 +991,10 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
             @RequestParam(value = "fruitId") Integer fruitId,
             @RequestParam(value = "amount") Integer amount) {
 
+        //防止输入负数
+        if (amount <= 0) {
+            return Result.of(null, false, ResultEnum.FRUIT_AMOUNT_ERROR.getMessage(), ResultEnum.FRUIT_AMOUNT_ERROR.getCode());
+        }
         //
         ComFruitVo comFruitVo = comFruitService.findById(fruitId);
 

+ 100 - 0
src/main/java/com/td/boss/game/complayerland/controller/ComPlayerLandController.java

@@ -1,5 +1,7 @@
 package com.td.boss.game.complayerland.controller;
 
+import cn.hutool.core.util.RandomUtil;
+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;
@@ -8,12 +10,14 @@ import com.td.boss.game.comexplainland.vo.ComExplainLandVo;
 import com.td.boss.game.commallseed.service.ComMallSeedService;
 import com.td.boss.game.commallseed.vo.ComMallSeedVo;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisasterLog;
+import com.td.boss.game.complayerland.pojo.ComPlayerDisasterProtected;
 import com.td.boss.game.complayerland.service.ComPlayerDisasterLogService;
 import com.td.boss.game.complayergoods.pojo.ComPlayerGoods;
 import com.td.boss.game.complayergoods.service.ComPlayerGoodsService;
 import com.td.boss.game.complayergoods.vo.ComPlayerGoodsVo;
 import com.td.boss.game.complayerland.pojo.ComPlayerLand;
 import com.td.boss.game.complayerland.pojo.ComPlayerLandAndCanSteal;
+import com.td.boss.game.complayerland.service.ComPlayerDisasterProtectedService;
 import com.td.boss.game.complayerland.vo.ComPlayerLandAndPlantVo;
 import com.td.boss.game.complayerland.vo.ComPlayerLandAndUserInfoVo;
 import com.td.boss.game.complayerland.vo.ComPlayerLandSimpleVo;
@@ -21,6 +25,9 @@ import com.td.boss.game.complayerland.vo.ComPlayerLandVo;
 import com.td.boss.game.complayerland.service.ComPlayerLandService;
 import com.td.boss.game.complayerlog.service.ComPlayerLogService;
 import com.td.boss.game.complayerlog.vo.ComPlayerLogVo;
+import com.td.boss.game.complayerprofit.pojo.ComPlayerProfit;
+import com.td.boss.game.complayerprofit.service.ComPlayerProfitService;
+import com.td.boss.game.complayerprofit.vo.ComPlayerProfitVo;
 import com.td.boss.util.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -56,6 +63,15 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
     @Autowired
     private ComPlayerDisasterLogService comPlayerDisasterLogService;
 
+    @Autowired
+    private ComPlayerDisasterProtectedService disasterProtectedService;
+
+
+    @Autowired
+    private ComPlayerProfitService comPlayerProfitService;
+
+    @Autowired
+    private RedisLock redisLock;
 
     /**
      * 获取用户土地
@@ -77,6 +93,7 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
         List<ComPlayerLandAndPlantVo> _simpleVoList = CopyUtil.copyList(comPlayerLands, ComPlayerLandAndPlantVo.class);
         List<ComPlayerLandAndPlantVo> _list = new ArrayList<>();
 
+
         try {
             _simpleVoList.stream().map(e -> {
                 ComPlayerLandAndPlantVo comPlayerLandAndPlantVo = e;
@@ -126,6 +143,8 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                         //说明可以收获了
                         comPlayerLandAndPlantVo.setPlantDaysRemaining(0);
                         comPlayerLandAndPlantVo.setPlantHoursRemaining(0);
+                        //生成第一次受灾
+                        _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
                     } else {
                         comPlayerLandAndPlantVo.setPlantDaysRemaining(DateUtil.getDays(diff).intValue());
                         comPlayerLandAndPlantVo.setPlantHoursRemaining(DateUtil.getHours(diff).intValue());
@@ -195,6 +214,9 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                         //说明可以收获了
                         comPlayerLandAndPlantVo.setPlantDaysRemaining(0);
                         comPlayerLandAndPlantVo.setPlantHoursRemaining(0);
+                        //生成第一次受灾
+                        _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
+
                     } else {
                         comPlayerLandAndPlantVo.setPlantDaysRemaining(DateUtil.getDays(diff).intValue());
                         comPlayerLandAndPlantVo.setPlantHoursRemaining(DateUtil.getHours(diff).intValue());
@@ -283,6 +305,8 @@ 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);
             //土地数据不存在
@@ -353,6 +377,9 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
             //生成一个标识,用来识别种植
             comPlayerLand.setPlantFlag(UUIDUtil.getUUID());
 
+            //重新种植后,重新设置一个可以偷的标识
+            comPlayerLand.setPlantSteal(1);
+
             //comPlayerLand.setLandDescribe();
             ComPlayerLandVo comPlayerLandVo = CopyUtil.copy(comPlayerLand, ComPlayerLandVo.class);
             comPlayerLandService.save(comPlayerLandVo);
@@ -407,6 +434,11 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                 //说明可以收获了
                 comPlayerLandAndPlantVo.setPlantDaysRemaining(0);
                 comPlayerLandAndPlantVo.setPlantHoursRemaining(0);
+
+                //生成第一次受灾
+                _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
+
+
             } else {
                 comPlayerLandAndPlantVo.setPlantDaysRemaining(DateUtil.getDays(diff).intValue());
                 comPlayerLandAndPlantVo.setPlantHoursRemaining(DateUtil.getHours(diff).intValue());
@@ -442,6 +474,7 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
 
     /**
      * 获得某个用个 灾难情况
+     *
      * @param userId
      * @return
      */
@@ -451,4 +484,71 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
         List<ComPlayerDisasterLog> history = comPlayerDisasterLogService.getHistory(userId);
         return Result.of(history);
     }
+
+
+    private void _InitFirstDisasterProfit(ComPlayerLandAndPlantVo comPlayerLandAndPlantVo, ComMallSeedVo comMallSeedVo) {
+        //这里处理一次判断是否发生过第一次灾难
+        //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 = com.td.boss.util.DateUtil.getOldDateAddDay(comPlayerLandAndPlantVo.getPlantStart(), comPlayerLandAndPlantVo.getPlantMature());
+            long randomDate = 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;
+                }
+            }
+            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));
+                //如果没有防护或者防护到期。则直接发生灾难进行减产
+                if (_protectedDate != null && disasterDate.before(_protectedDate)) {
+                    //灾难的随机时间比防护包时间后,说明防护包到期
+                    //成熟的时候触发第一次自然灾难
+                    ComPlayerProfitVo naturalProfitVo = comPlayerProfitService.addFirstDisasterAndLoss(CopyUtil.copy(comPlayerLandAndPlantVo, ComPlayerLand.class),
+                            comMallSeedVo, 2, _allLossProfit);
+                    //多次执行需要加上当前操作的利润
+                    _allLossProfit += naturalProfitVo.getStolen();
+                }
+            }
+            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);
+//                    //多次执行需要加上当前操作的利润
+//                    _allLossProfit += beastProfitVo.getStolen();
+                }
+            }
+        }
+    }
 }

+ 6 - 6
src/main/java/com/td/boss/game/complayerland/scheduled/QuartzConfig.java

@@ -10,12 +10,12 @@ public class QuartzConfig {
 //    private static String JOB_GROUP_NAME = "JOBGROUP_ComPlayerDisaster";
 //    private static String TRIGGER_GROUP_NAME = "TRIGGERGROUP_ComPlayerDisaster";
 
-    private static String WeekTrigger = "0 0/1 * * * ?";
-    private static String DayTrigger = "0/5 * * * * ?";
-//    //每周日1点
-//    private static String WeekTrigger = "0 0 1 ? * SUN";
-//    //每天6点
-//    private static String DayTrigger = "0 0 6 * * ? *";
+    //private static String WeekTrigger = "0 0/1 * * * ?";
+    //private static String DayTrigger = "0/5 * * * * ?";
+    //每周日1点
+    private static String WeekTrigger = "0 0 1 ? * SUN";
+    //每天6点
+    private static String DayTrigger = "0 0 6 * * ? *";
 
     @Bean
     public JobDetail syncDisasterWeekDetail() {

+ 91 - 3
src/main/java/com/td/boss/game/complayerland/service/ComPlayerDisasterLogServiceImpl.java

@@ -9,18 +9,29 @@ import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.json.JSONUtil;
 import com.td.boss.common.service.CommonServiceImpl;
+import com.td.boss.game.commallseed.service.ComMallSeedService;
+import com.td.boss.game.commallseed.vo.ComMallSeedVo;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisaster;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisasterLog;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisasterProtected;
+import com.td.boss.game.complayerland.pojo.ComPlayerLand;
 import com.td.boss.game.complayerland.repository.ComPlayerDisasterLogRepository;
 import com.td.boss.game.complayerland.scheduled.ComPlayerDisasterDateUtil;
 import com.td.boss.game.complayerland.vo.ComPlayerDisasterEnum;
 import com.td.boss.game.complayerland.vo.ComPlayerDisasterLogVo;
+import com.td.boss.game.complayerprofit.pojo.ComPlayerProfit;
+import com.td.boss.game.complayerprofit.service.ComPlayerProfitService;
+import com.td.boss.game.complayerprofit.vo.ComPlayerProfitVo;
+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 lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Predicate;
@@ -41,6 +52,18 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
     @Autowired
     private ComPlayerDisasterService disasterService;
 
+    @Autowired
+    private ComPlayerLandService comPlayerLandService;
+
+    @Autowired
+    private ComPlayerProfitService comPlayerProfitService;
+
+    @Autowired
+    private ComMallSeedService comMallSeedService;
+
+    @Autowired
+    private RedisLock redisLock;
+
     /**
      * 伤害 会减产50%
      */
@@ -197,9 +220,10 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
         if (protectedDate != null && now.before(protectedDate)) {
             int randomProtect = RandomUtil.randomInt(0, 101);
             log.info("灾难几率:{}", randomProtect);
-            if (randomProtect > (100 - defend)) {
-                disasterLog.setProtect(true);
-            }
+            //todo 先注释这个防护,这里触发的灾难默认是不防护的
+            //if (randomProtect > (100 - defend)) {
+            //    disasterLog.setProtect(true);
+            //}
         }
 
         log.info("灾难日志:{}", JSONUtil.toJsonStr(disasterLog));
@@ -207,6 +231,70 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
         //todo 减产接口 减产逻辑
         if (!disasterLog.isProtect()) {
             log.info("灾难结果:减产");
+            //todo 插入受灾减产数据
+            long time = System.currentTimeMillis() + RedisData.getPlayerDisastersFirstTimeout();
+            //查找用户的全部土地
+            List<ComPlayerLand> comPlayerLands = comPlayerLandService.findAllByUserIdAndPlantAndMature(disasterLog.getUserId());
+            for (int i = 0; i < comPlayerLands.size(); i++) {
+                ComPlayerLand _comPlayerLand = comPlayerLands.get(i);
+                ComMallSeedVo comMallSeedVo = comMallSeedService.findById(_comPlayerLand.getPlantId());
+
+                //这里处理一次判断是否发生过第一次灾难
+                //todo 添加一个灾难损失,灾难损失的时间点是种植开始到成熟阶段的一个随机时间
+                // 加个锁判断,是否在其他地方触发了这次灾难计算(自解锁)
+                String _disasterKey = RedisData.getPlayerDisastersFirstKey() + _comPlayerLand.getPlantFlag();
+                if (redisLock.lock(_disasterKey, String.valueOf(time))) {
+                    //灾难发生时间
+                    Date endDate = com.td.boss.util.DateUtil.getOldDateAddDay(_comPlayerLand.getPlantStart(), _comPlayerLand.getPlantMature());
+                    long randomDate = RandomUtil.randomLong(_comPlayerLand.getPlantStart().getTime(), endDate.getTime());
+                    Date disasterDate = new Date(randomDate);
+                    //获取损失的数据
+                    List<ComPlayerProfit> comPlayerProfits = comPlayerProfitService.findByUserIdAndPlantFlagAndLandId(_comPlayerLand.getUserId(), _comPlayerLand.getPlantFlag(), _comPlayerLand.getConfigLandId());
+                    //todo 总共受损的数量
+                    Double _allLossProfit = 0d;
+                    boolean isNaturalProfit = false, isBeastProfit = false;
+                    Integer _disasterCount = 0;
+                    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;
+                            //出现灾难的次数
+                            _disasterCount++;
+                        } else if (_profit.getLossType().equals(3)) {
+                            isBeastProfit = true;
+                            //出现灾难的次数
+                            _disasterCount++;
+                        }
+                    }
+                    log.info("用户编号:{},防护历史记录:{}", _comPlayerLand.getUserId(), JSONUtil.toJsonStr(protectList));
+                    //获得对应灾难类型的防护记录    并得到这个 防护到期时间. 自然灾害类型
+                    //如果没有防护或者防护到期。则直接发生灾难进行减产
+                    if (!isNaturalProfit && protectedDate != null && disasterDate.before(protectedDate)) {
+                        //灾难的随机时间比防护包时间后,说明防护包到期
+                        //成熟的时候触发第一次自然灾难
+                        ComPlayerProfitVo naturalProfitVo = comPlayerProfitService.addFirstDisasterAndLoss(CopyUtil.copy(_comPlayerLand, ComPlayerLand.class),
+                                comMallSeedVo, 2, _allLossProfit);
+                        //多次执行需要加上当前操作的利润
+                        _allLossProfit += naturalProfitVo.getStolen();
+                    }
+                    if (!isBeastProfit && protectedDate != null && disasterDate.before(protectedDate)) {
+                        //灾难的随机时间比防护包时间后,说明防护包到期
+                        //成熟的时候触发第一次自然灾难
+                        ComPlayerProfitVo beastProfitVo =  comPlayerProfitService.addFirstDisasterAndLoss(CopyUtil.copy(_comPlayerLand, ComPlayerLand.class),
+                                comMallSeedVo, 3, _allLossProfit);
+                        //多次执行需要加上当前操作的利润
+                        _allLossProfit += beastProfitVo.getStolen();
+                    }
+
+                    //todo 添加一条单独减产的数据 ,对应灾难
+                    comPlayerProfitService.addOtherDisasterAndLoss(CopyUtil.copy(_comPlayerLand, ComPlayerLand.class),
+                            comMallSeedVo, disasterLog.getDsasterType(), _allLossProfit, _disasterCount);
+                }
+
+            }
+
+
         } else {
             log.info("灾难结果:已防御");
         }

+ 7 - 0
src/main/java/com/td/boss/game/complayerland/service/ComPlayerLandService.java

@@ -14,6 +14,13 @@ public interface ComPlayerLandService extends CommonService<ComPlayerLandVo, Com
 
     List<ComPlayerLand> findAllByUserId(String userId);
 
+    /**
+     * 返回一个已种植并且成熟的列表
+     * @param userId
+     * @return
+     */
+    List<ComPlayerLand> findAllByUserIdAndPlantAndMature(String userId);
+
     //获取可以偷取的土地用户,用于首页偷菜列表显示,返回一个不包括自己的列表
     List<ComPlayerLandAndUserInfoVo> findAllByCanStealNotSelf(String userId, Pageable pageable);
 

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

@@ -41,6 +41,15 @@ public class ComPlayerLandServiceImpl extends CommonServiceImpl<ComPlayerLandVo,
     }
 
 
+    @Override
+    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);
+        List list = nativeQuery.getResultList();
+        return list;
+    }
+
     @Override
     public List<ComPlayerLandAndUserInfoVo> findAllByCanStealNotSelf(String userId, Pageable pageable) {
         List<Object> objects = comPlayerLandRepository.findAllIsStealComPlayerLandAndUserInfo(userId, pageable);

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

@@ -40,6 +40,9 @@ public class ComPlayerProfit implements Serializable {
 
     private Double finalRatio;//最后用户可收取的利润比例,目前是设置 10%
 
+    private Integer lossType;//损失的类型,默认是0:被偷取果实,1:自然灾难,2:野兽
+
+
     private Date createTime;//
 
     private Date updateTime;//

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

@@ -26,6 +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);
+
     @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);
 }

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

@@ -1,6 +1,7 @@
 package com.td.boss.game.complayerprofit.service;
 
-import com.td.boss.common.service.*;
+import com.td.boss.common.service.CommonService;
+import com.td.boss.game.commallseed.vo.ComMallSeedVo;
 import com.td.boss.game.complayerland.pojo.ComPlayerLand;
 import com.td.boss.game.complayerprofit.pojo.ComPlayerProfit;
 import com.td.boss.game.complayerprofit.vo.ComPlayerProfitVo;
@@ -11,18 +12,41 @@ public interface ComPlayerProfitService extends CommonService<ComPlayerProfitVo,
 
     /**
      * 获取被偷取的信息,表里面 targetId 对应自己的用户的 userId
+     *
      * @param userId
      * @param plantFlag
      * @param landId
      * @return
      */
-    List<ComPlayerProfit> findByUserIdAndPlantFlagAndLandId(String userId,String plantFlag,Integer landId);
+    List<ComPlayerProfit> findByUserIdAndPlantFlagAndLandId(String userId, String plantFlag, Integer landId);
 
-    ComPlayerProfit findByUserIdAndPlantFlag(String userId,String plantFlag);
+    ComPlayerProfit findByUserIdAndPlantFlag(String userId, String plantFlag);
 
-    ComPlayerProfit findByUserIdAndOtherUserIdAndPlantFlag(String userId,String otherUserId, String plantFlag);
+    ComPlayerProfit findByUserIdAndOtherUserIdAndPlantFlag(String userId, String otherUserId, String plantFlag);
+
+    ComPlayerProfit findByUserIdAndTargetIdAndLandIdAndPlantFlag(String userId, String targetId, Integer configLandId, String plantFlag);
+
+    /**
+     * 根据灾难类型进行调用,犹豫灾难只发生一次,所以lossType对于flag只有一条数据
+     * @param plantFlag
+     * @param lossType {2:自然灾难,3:野兽灾难}
+     * @return
+     */
+    ComPlayerProfit findByPlantFlagAndLossType(String plantFlag,Integer lossType);
 
-    ComPlayerProfit findByUserIdAndTargetIdAndLandIdAndPlantFlag(String userId,String targetId,Integer configLandId, String plantFlag);
 
     Double getStolenSumByOtherUserIdAndPlantFlag(String otherUserId, String plantFlag);
+
+    /**
+     * 必然灾难减扣
+     * @param comPlayerLand
+     * @param comMallSeedVo
+     * @param lossType
+     * @param allLossProfit
+     * @return
+     */
+    ComPlayerProfitVo addFirstDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType,Double allLossProfit);
+
+    ComPlayerProfitVo addOtherDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType, Double allLossProfit,Integer disasterCount);
+
 }

+ 138 - 9
src/main/java/com/td/boss/game/complayerprofit/service/ComPlayerProfitServiceImpl.java

@@ -1,47 +1,176 @@
 package com.td.boss.game.complayerprofit.service;
 
 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.complayerprofit.pojo.ComPlayerProfit;
 import com.td.boss.game.complayerprofit.vo.ComPlayerProfitVo;
 import com.td.boss.game.complayerprofit.repository.ComPlayerProfitRepository;
+import com.td.boss.util.CopyUtil;
+import com.td.boss.util.DoubleUtil;
 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.List;
 
 @Service
 @Transactional
-public class ComPlayerProfitServiceImpl extends CommonServiceImpl<ComPlayerProfitVo, ComPlayerProfit, String> implements ComPlayerProfitService{
+public class ComPlayerProfitServiceImpl extends CommonServiceImpl<ComPlayerProfitVo, ComPlayerProfit, String> implements ComPlayerProfitService {
 
     @PersistenceContext
     private EntityManager em;
     @Autowired
     private ComPlayerProfitRepository comPlayerProfitRepository;
 
+    @Autowired
+    private ComPlayerProfitService comPlayerProfitService;
+
     @Override
     public List<ComPlayerProfit> findByUserIdAndPlantFlagAndLandId(String userId, String plantFlag, Integer landId) {
-        return comPlayerProfitRepository.findByTargetIdAndPlantFlagAndLandId(userId,plantFlag,landId);
+        return comPlayerProfitRepository.findByTargetIdAndPlantFlagAndLandId(userId, plantFlag, landId);
     }
 
     @Override
-    public ComPlayerProfit findByUserIdAndPlantFlag(String userId,String plantFlag) {
-        return comPlayerProfitRepository.findByUserIdAndPlantFlag(userId,plantFlag).orElse(null);
+    public ComPlayerProfit findByUserIdAndPlantFlag(String userId, String plantFlag) {
+        return comPlayerProfitRepository.findByUserIdAndPlantFlag(userId, plantFlag).orElse(null);
     }
+
     @Override
-    public ComPlayerProfit findByUserIdAndOtherUserIdAndPlantFlag(String userId,String otherUserId, String plantFlag) {
-        return comPlayerProfitRepository.findByUserIdAndTargetIdAndPlantFlag(userId,otherUserId,plantFlag).orElse(null);
+    public ComPlayerProfit findByUserIdAndOtherUserIdAndPlantFlag(String userId, String otherUserId, String plantFlag) {
+        return comPlayerProfitRepository.findByUserIdAndTargetIdAndPlantFlag(userId, otherUserId, plantFlag).orElse(null);
     }
 
 
     @Override
-    public ComPlayerProfit findByUserIdAndTargetIdAndLandIdAndPlantFlag(String userId,String targetId, Integer configLandId, String plantFlag) {
-        return comPlayerProfitRepository.findByUserIdAndTargetIdAndLandIdAndPlantFlag(userId,targetId,configLandId,plantFlag).orElse(null);
+    public ComPlayerProfit findByUserIdAndTargetIdAndLandIdAndPlantFlag(String userId, String targetId, Integer configLandId, String plantFlag) {
+        return comPlayerProfitRepository.findByUserIdAndTargetIdAndLandIdAndPlantFlag(userId, targetId, configLandId, plantFlag).orElse(null);
+    }
+
+    @Override
+    public ComPlayerProfit findByPlantFlagAndLossType(String plantFlag, Integer lossType) {
+        return comPlayerProfitRepository.findByPlantFlagAndLossType(plantFlag, lossType).orElse(null);
     }
 
     @Override
     public Double getStolenSumByOtherUserIdAndPlantFlag(String otherUserId, String plantFlag) {
-        return comPlayerProfitRepository.getStolenSumByTargetIdAndPlantFlag(otherUserId,plantFlag);
+        return comPlayerProfitRepository.getStolenSumByTargetIdAndPlantFlag(otherUserId, plantFlag);
+    }
+
+
+    @Override
+    public ComPlayerProfitVo addFirstDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType, Double allLossProfit) {
+
+        //对应土地灾害损失
+        ComPlayerProfit comPlayerProfit = new ComPlayerProfit();
+        //最终减扣的利润
+        Double _endReduceProfit = 0d;
+        //计算一个偷取的收获量, 租赁倍数* 租赁日期下的产量
+        Integer _otherAmount = 0;
+        if (comPlayerLand.getLeaseDate().equals(1)) {
+            _otherAmount = comPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest1();
+        } else if (comPlayerLand.getLeaseDate().equals(2)) {
+            _otherAmount = comPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest2();
+        } else if (comPlayerLand.getLeaseDate().equals(3)) {
+            _otherAmount = comPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest3();
+        }
+        //todo 拿出全部利润
+        Integer _profit = _otherAmount - comPlayerLand.getLeaseMultiple() * comMallSeedVo.getPriceSnb();
+        //todo 计算减产,第一次灾难按利润的 50% 减产,两次就是减到 0 了。
+
+        //必然发生的灾难,减产50%
+        Double _reduceProfit = DoubleUtil.mul(_profit.doubleValue(), 0.5);
+        // 100 - 80 = 20
+        Double _residualProfit = DoubleUtil.sub(_profit.doubleValue(), allLossProfit);
+        //剩余利润减去当前需要减产的利润值
+        Double _tempProfit = DoubleUtil.sub(_residualProfit, _reduceProfit);
+        if (DoubleUtil.compare(_tempProfit, 0.0).equals(1)) {
+            //还有利润,
+            _endReduceProfit = _reduceProfit;
+        }
+
+        comPlayerProfit.setUserId(comPlayerLand.getUserId()); //损失记录的用户id
+        comPlayerProfit.setTargetId(comPlayerLand.getUserId()); //目标是自己
+        comPlayerProfit.setPlantFlag(comPlayerLand.getPlantFlag());
+        comPlayerProfit.setLandId(comPlayerLand.getConfigLandId());
+        comPlayerProfit.setLeaseMultiple(comPlayerLand.getLeaseMultiple());
+        comPlayerProfit.setLeaseDate(comPlayerLand.getLeaseDate());
+        comPlayerProfit.setHarvest(_otherAmount); // todo
+        comPlayerProfit.setProfit(_profit.doubleValue());//todo 目标用户可偷的初始利润值
+        comPlayerProfit.setStolen(_endReduceProfit);//todo 目标用户被灾害减产对应的数量
+        comPlayerProfit.setFinalSteal(_endReduceProfit);//
+        comPlayerProfit.setProfitAfter(DoubleUtil.add(allLossProfit, _endReduceProfit)); //当前损失的利润加上当前扣减的
+
+        //记录相关比例,损失利润的百分之50
+        comPlayerProfit.setProfitRatio(0.5);
+        comPlayerProfit.setStealRatio(0.5);
+        comPlayerProfit.setFinalRatio(1.0);
+        comPlayerProfit.setLossType(lossType);
+        ComPlayerProfitVo comPlayerProfitVo = CopyUtil.copy(comPlayerProfit, ComPlayerProfitVo.class);
+        comPlayerProfitService.save(comPlayerProfitVo);
+
+        return comPlayerProfitVo;
+    }
+
+
+    @Override
+    public ComPlayerProfitVo addOtherDisasterAndLoss(ComPlayerLand comPlayerLand, ComMallSeedVo comMallSeedVo, Integer lossType, Double allLossProfit, Integer disasterCount) {
+
+        //对应土地灾害损失
+        ComPlayerProfit comPlayerProfit = new ComPlayerProfit();
+        //最终减扣的利润
+        Double _endReduceProfit = 0d;
+        //计算一个偷取的收获量, 租赁倍数* 租赁日期下的产量
+        Integer _otherAmount = 0;
+        if (comPlayerLand.getLeaseDate().equals(1)) {
+            _otherAmount = comPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest1();
+        } else if (comPlayerLand.getLeaseDate().equals(2)) {
+            _otherAmount = comPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest2();
+        } else if (comPlayerLand.getLeaseDate().equals(3)) {
+            _otherAmount = comPlayerLand.getLeaseMultiple() * comMallSeedVo.getHarvest3();
+        }
+        //todo 拿出全部利润
+        Integer _profit = _otherAmount - comPlayerLand.getLeaseMultiple() * comMallSeedVo.getPriceSnb();
+        //todo 计算减产,第一次灾难按利润的 50% 减产,两次就是减到 0 了。
+
+        //额外发生的灾难,按照次数计算减产 50% 发生已经发生1次计算后当次等于 25%,
+        double _startRatio = 1.0;
+        for(int i = disasterCount;i>0;i--){
+            _startRatio =  DoubleUtil.mul(_startRatio,0.5);
+        }
+        Double _reduceProfit = DoubleUtil.mul(_profit.doubleValue(), _startRatio);
+        // 100 - 80 = 20
+        Double _residualProfit = DoubleUtil.sub(_profit.doubleValue(), allLossProfit);
+        //剩余利润减去当前需要减产的利润值
+        Double _tempProfit = DoubleUtil.sub(_residualProfit, _reduceProfit);
+        if (DoubleUtil.compare(_tempProfit, 0.0).equals(1)) {
+            //还有利润,
+            _endReduceProfit = _reduceProfit;
+        }
+
+        comPlayerProfit.setUserId(comPlayerLand.getUserId()); //损失记录的用户id
+        comPlayerProfit.setTargetId(comPlayerLand.getUserId()); //目标是自己
+        comPlayerProfit.setPlantFlag(comPlayerLand.getPlantFlag());
+        comPlayerProfit.setLandId(comPlayerLand.getConfigLandId());
+        comPlayerProfit.setLeaseMultiple(comPlayerLand.getLeaseMultiple());
+        comPlayerProfit.setLeaseDate(comPlayerLand.getLeaseDate());
+        comPlayerProfit.setHarvest(_otherAmount); // todo
+        comPlayerProfit.setProfit(_profit.doubleValue());//todo 目标用户可偷的初始利润值
+        comPlayerProfit.setStolen(_endReduceProfit);//todo 目标用户被灾害减产对应的数量
+        comPlayerProfit.setFinalSteal(_endReduceProfit);//
+        comPlayerProfit.setProfitAfter(DoubleUtil.add(allLossProfit, _endReduceProfit)); //当前损失的利润加上当前扣减的
+
+        //记录相关比例,损失利润的 _startRatio 相关比例
+        comPlayerProfit.setProfitRatio(_startRatio);
+        comPlayerProfit.setStealRatio(_startRatio);
+        comPlayerProfit.setFinalRatio(1.0);
+        comPlayerProfit.setLossType(lossType);
+        ComPlayerProfitVo comPlayerProfitVo = CopyUtil.copy(comPlayerProfit, ComPlayerProfitVo.class);
+        comPlayerProfitService.save(comPlayerProfitVo);
+
+        return comPlayerProfitVo;
     }
 }

+ 5 - 1
src/main/java/com/td/boss/game/complayerprofit/vo/ComPlayerProfitVo.java

@@ -1,6 +1,8 @@
 package com.td.boss.game.complayerprofit.vo;
 
-import com.td.boss. common.pojo.PageCondition;import lombok.Data;
+import com.td.boss.common.pojo.PageCondition;
+import lombok.Data;
+
 import java.io.Serializable;
 import java.util.Date;
 
@@ -36,6 +38,8 @@ public class ComPlayerProfitVo extends PageCondition implements Serializable {
 
     private Double finalRatio;//最后用户可收取的利润比例,目前是设置 10%
 
+    private Integer lossType;//损失的类型,默认是0:被偷取果实,1:自然灾难,2:野兽
+
     private Date createTime;//
 
     private Date updateTime;//

+ 67 - 0
src/main/java/com/td/boss/game/comsnbapply/controller/ComSnbApplyController.java

@@ -0,0 +1,67 @@
+package com.td.boss.game.comsnbapply.controller;
+
+import com.td.boss.common.controller.*;
+import com.td.boss.common.pojo.PageInfo;
+import com.td.boss.common.pojo.Result;
+import com.td.boss.config.enums.ResultEnum;
+import com.td.boss.game.comsnbapply.pojo.ComSnbApply;
+import com.td.boss.game.comsnbapply.vo.ComSnbApplySimpleVo;
+import com.td.boss.game.comsnbapply.vo.ComSnbApplyVo;
+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.DoubleUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+import java.util.List;
+
+@RestController
+@RequestMapping("/game/comSnbApply/")
+public class ComSnbApplyController extends CommonController<ComSnbApplyVo, ComSnbApply, String> {
+    @Autowired
+    private ComSnbApplyService comSnbApplyService;
+
+    @Autowired
+    private ComUsersService comUsersService;
+
+
+    @GetMapping("getPage")
+    public Result<PageInfo<ComSnbApplyVo>> getPageFunction(@RequestParam(value = "userId") String userId) {
+        ComSnbApplyVo comSnbApplyVo = new ComSnbApplyVo();
+        comSnbApplyVo.setUserId(userId);
+        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);
+        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.setSnb(applyAmount);
+        comSnbApplyVo.setSnbDescribe("applySnbToCnt,发起兑换记录snb!");
+        comSnbApplyVo.setIsState(0);
+        comSnbApplyVo.setCreateTime(new Date());
+        comSnbApplyVo.setUpdateTime(new Date());
+        //保存成功之后,刷新列表
+        return comSnbApplyService.save(comSnbApplyVo);
+    }
+}

+ 27 - 0
src/main/java/com/td/boss/game/comsnbapply/pojo/ComSnbApply.java

@@ -0,0 +1,27 @@
+package com.td.boss.game.comsnbapply.pojo;
+
+import lombok.Data;
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+@Entity
+@Table(name = "com_snb_apply")
+@Data
+public class ComSnbApply implements Serializable {
+    @Id
+    private String id;//
+
+    private String userId;//
+
+    private Integer snb;//游戏的snb
+
+    private Integer isState;//0:申请中,1:申请通过,2:申请驳回
+
+    private String snbDescribe;//
+
+    private Date createTime;//
+
+    private Date updateTime;//
+
+}

+ 18 - 0
src/main/java/com/td/boss/game/comsnbapply/repository/ComSnbApplyRepository.java

@@ -0,0 +1,18 @@
+package com.td.boss.game.comsnbapply.repository;
+
+import com.td.boss.common.repository.*;
+import com.td.boss.game.comsnbapply.pojo.ComSnbApply;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+public interface ComSnbApplyRepository extends CommonRepository<ComSnbApply, String> {
+
+    List<ComSnbApply> findAllByUserIdAndIsState(String userId, Integer isState);
+
+    Optional<ComSnbApply> findByUserIdAndSnbAndIsState(String userId,Integer snb,Integer isState);
+
+    List<ComSnbApply> findAllByUserId(String userId);
+}

+ 72 - 0
src/main/java/com/td/boss/game/comsnbapply/scheduled/BackService.java

@@ -0,0 +1,72 @@
+package com.td.boss.game.comsnbapply.scheduled;
+
+import cn.hutool.core.date.DateUtil;
+import com.td.boss.game.comsnbapply.service.ComSnbApplyService;
+import com.td.boss.game.comsnbapply.vo.ComSnbApplyVo;
+import com.td.boss.sys.syssetting.pojo.SysSetting;
+import com.td.boss.sys.syssettingtask.pojo.SysSettingTask;
+import com.td.boss.sys.syssettingtask.service.SysSettingTaskService;
+import com.td.boss.sys.syssettingtask.vo.SysSettingTaskVo;
+import com.td.boss.util.RedisData;
+import com.td.boss.util.RedisLock;
+import com.td.boss.util.SysSettingTaskUtil;
+import com.td.boss.util.SysSettingUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 后台定时任务
+ *
+ * @author:slambb
+ * @date:2022/3/15
+ */
+@Service
+@Slf4j
+@Conditional(IPCondition.class)
+public class BackService {
+
+    @Autowired
+    private ComSnbApplyService comSnbApplyService;
+
+    @Autowired
+    private RedisLock redisLock;
+
+    @PostConstruct
+    public void init(){
+        log.info("apply snb run task...");
+    }
+
+    @Scheduled(cron = "0/10 * * * * *")
+    public void scheduleTask(){
+        //log.info("task running....");
+        //todo 处理是否自动审查
+        if("N".equals(SysSettingTaskUtil.getSysSettingTask().getApplyAutoExamine())){
+            return;
+        }
+        long time = System.currentTimeMillis() + RedisData.getAutoApplyTimeout();
+        String _redisKey = "LOCK:COM_SNB_APPLY:AUTO";
+        if (!redisLock.lock(_redisKey, String.valueOf(time))) {
+            log.info("正在自动审查中..!");
+            return;
+        }
+        //进入自动审核,看看后面是否需要限制数量
+        ComSnbApplyVo getComSnbApplyVo = new ComSnbApplyVo();
+        getComSnbApplyVo.setIsState(0);//查找正在申请中的数据,isState = 0;
+        List<ComSnbApplyVo> comSnbApplyVos = comSnbApplyService.list(getComSnbApplyVo).getData();
+        log.info("审查任务数量:{}个", comSnbApplyVos.size());
+        for (ComSnbApplyVo comSnbApplyVo : comSnbApplyVos) {
+            //全部给通过
+            comSnbApplyVo.setIsState(1);
+            comSnbApplyService.save(comSnbApplyVo);
+        }
+        redisLock.unlock(_redisKey, String.valueOf(time));
+        log.info("正在自动审查中任务结束");
+    }
+}

+ 35 - 0
src/main/java/com/td/boss/game/comsnbapply/scheduled/IPCondition.java

@@ -0,0 +1,35 @@
+package com.td.boss.game.comsnbapply.scheduled;
+
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+import java.net.InetAddress;
+
+/**
+ * 判断是否为本机ip
+ *
+ * @author:slambb
+ * @date:2022/3/15
+ */
+@Slf4j
+public class IPCondition implements Condition {
+
+    @Override
+    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
+        String runTaskIP = conditionContext.getEnvironment().getProperty("applySNB.task.ip");
+        String localIP = this.getLocalIP();
+
+        log.info("local ip: {} , run Task IP: {}" ,localIP , runTaskIP);
+
+        return runTaskIP.equals(localIP);
+    }
+
+    @SneakyThrows
+    public String getLocalIP(){
+        InetAddress address = InetAddress.getLocalHost();
+        return address.getHostAddress();
+    }
+}

+ 17 - 0
src/main/java/com/td/boss/game/comsnbapply/service/ComSnbApplyService.java

@@ -0,0 +1,17 @@
+package com.td.boss.game.comsnbapply.service;
+
+import com.td.boss.common.service.*;
+import com.td.boss.game.comsnbapply.pojo.ComSnbApply;
+import com.td.boss.game.comsnbapply.vo.ComSnbApplyVo;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface ComSnbApplyService extends CommonService<ComSnbApplyVo, ComSnbApply, String> {
+
+    List<ComSnbApply> findAllByUserIdAndIsState(String userId,Integer isState);
+
+    ComSnbApply findByUserIdAndSnbAndIsState(String userId,Integer snb,Integer isState);
+
+    List<ComSnbApply> findAllByUserId(String userId);
+}

+ 38 - 0
src/main/java/com/td/boss/game/comsnbapply/service/ComSnbApplyServiceImpl.java

@@ -0,0 +1,38 @@
+package com.td.boss.game.comsnbapply.service;
+
+import com.td.boss.common.service.*;
+import com.td.boss.game.comsnbapply.pojo.ComSnbApply;
+import com.td.boss.game.comsnbapply.vo.ComSnbApplyVo;
+import com.td.boss.game.comsnbapply.repository.ComSnbApplyRepository;
+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.List;
+
+@Service
+@Transactional
+public class ComSnbApplyServiceImpl extends CommonServiceImpl<ComSnbApplyVo, ComSnbApply, String> implements ComSnbApplyService{
+
+    @PersistenceContext
+    private EntityManager em;
+    @Autowired
+    private ComSnbApplyRepository comSnbApplyRepository;
+
+
+    @Override
+    public List<ComSnbApply> findAllByUserIdAndIsState(String userId, Integer isState) {
+        return comSnbApplyRepository.findAllByUserIdAndIsState(userId, isState);
+    }
+
+    @Override
+    public ComSnbApply findByUserIdAndSnbAndIsState(String userId, Integer snb, Integer isState) {
+        return comSnbApplyRepository.findByUserIdAndSnbAndIsState(userId, snb, isState).orElse(null);
+    }
+
+    @Override
+    public List<ComSnbApply> findAllByUserId(String userId) {
+        return comSnbApplyRepository.findAllByUserId(userId);
+    }
+}

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

@@ -0,0 +1,25 @@
+package com.td.boss.game.comsnbapply.vo;
+
+import com.td.boss.common.pojo.PageCondition;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class ComSnbApplySimpleVo implements Serializable {
+    private String id;//
+
+    private String userId;//
+
+    private Integer snb;//游戏的snb
+
+    private Integer isState;//0:申请中,1:申请通过,2:申请驳回
+
+    private String snbDescribe;//
+
+    private Date createTime;//
+
+    private Date updateTime;//
+
+}

+ 23 - 0
src/main/java/com/td/boss/game/comsnbapply/vo/ComSnbApplyVo.java

@@ -0,0 +1,23 @@
+package com.td.boss.game.comsnbapply.vo;
+
+import com.td.boss. common.pojo.PageCondition;import lombok.Data;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class ComSnbApplyVo extends PageCondition implements Serializable {
+    private String id;//
+
+    private String userId;//
+
+    private Integer snb;//游戏的snb
+
+    private Integer isState;//0:申请中,1:申请通过,2:申请驳回
+
+    private String snbDescribe;//
+
+    private Date createTime;//
+
+    private Date updateTime;//
+
+}

+ 53 - 4
src/main/java/com/td/boss/game/comsnbfreeze/controller/ComSnbFreezeController.java

@@ -1,5 +1,6 @@
 package com.td.boss.game.comsnbfreeze.controller;
 
+import cn.hutool.core.date.DateField;
 import com.td.boss.common.controller.*;
 import com.td.boss.common.pojo.Result;
 import com.td.boss.config.enums.ResultEnum;
@@ -16,9 +17,15 @@ 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.ComPlayerLand;
+import com.td.boss.game.complayerland.service.ComPlayerDisasterProtectedService;
 import com.td.boss.game.complayerland.service.ComPlayerLandService;
+import com.td.boss.game.complayerland.vo.ComPlayerDisasterEnum;
+import com.td.boss.game.complayerland.vo.ComPlayerDisasterProtectedVo;
 import com.td.boss.game.complayerland.vo.ComPlayerLandSimpleVo;
 import com.td.boss.game.complayerland.vo.ComPlayerLandVo;
+import com.td.boss.game.comsnbapply.pojo.ComSnbApply;
+import com.td.boss.game.comsnbapply.service.ComSnbApplyService;
+import com.td.boss.game.comsnbapply.vo.ComSnbApplyVo;
 import com.td.boss.game.comsnbfreeze.pojo.ComSnbFreeze;
 import com.td.boss.game.comsnbfreeze.vo.ComSnbFreezeSimpleVo;
 import com.td.boss.game.comsnbfreeze.vo.ComSnbFreezeVo;
@@ -69,11 +76,17 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
     @Autowired
     private ComSnbTranService comSnbTranService;
 
+    @Autowired
+    private ComPlayerDisasterProtectedService comPlayerDisasterProtectedService;
+
+    @Autowired
+    private ComSnbApplyService comSnbApplyService;
 
     @Autowired
     private RedisLock redisLock;
 
 
+
     /**
      * 获取用户神农呗 snb,前端用户调用
      *
@@ -116,10 +129,20 @@ 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){
+            map.put("msg", "snb小于等于0,记录异常!");
+            return Result.of(map);
+        }
+        //todo 新增一个判断当前交易是否存在对应snb通过审核的
+        ComSnbApply comSnbApply = comSnbApplyService.findByUserIdAndSnbAndIsState(id.toString(),snbAmount,1);
+        if(comSnbApply == null){
+            map.put("msg", "此交易未通过审核,返回给用户账户待用户提交审核");
+            return Result.of(map);
+        }
 
         //拿出用户对应的数据
         ComUsersVo comUsersVo = comUsersService.findByUserId(id.toString());
-        if (comUsersVo.getSnb() < snbAmount) {
+        if (comUsersVo.getSnb() <= 0 || comUsersVo.getSnb() < snbAmount) {
             map.put("msg", "账户snb不足");
             //WALLET_SNB_INSUFFICIENT_QUANTITY(602,"snb不足以支付!")
             //return Result.of(map, false, ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getMessage(), ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getCode());
@@ -140,11 +163,14 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
             }
             comUsersService.save(comUsersVo);
             redisLock.unlock(_redisKey, String.valueOf(time));
-        }catch (Exception e){
+        } catch (Exception e) {
             redisLock.unlock(_redisKey, String.valueOf(time));
             map.put("msg", "保存账户数据失败!");
             return Result.of(map);
         }
+        //此操作进入冻结流程,处理申请列表对应的数据状态
+        comSnbApply.setIsState(3);
+        comSnbApplyService.save(CopyUtil.copy(comSnbApply, ComSnbApplyVo.class));
 
         //记录操作的snb,
         ComSnbFreezeVo entityVo = new ComSnbFreezeVo();
@@ -212,6 +238,11 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
         }
 
         ComSnbFreezeVo comSnbFreezeVo = comSnbFreezeService.findById(snbId);
+        if(comSnbFreezeVo.getSnb()<=0){
+            map.put("msg", "snb是小于0?");
+            return Result.of(map);
+        }
+
         if (!comSnbFreezeVo.getIsSuccess().equals(0)) {
             //交易状态是0才可以进行下一步操作
             //WALLET_SNB_SUCCESS_NOT_ZERO(603,"snb不可操作"),
@@ -244,7 +275,7 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
                 }
                 comUsersService.save(comUsersVo);
                 redisLock.unlock(_redisKey, String.valueOf(time));
-            }catch (Exception e){
+            } catch (Exception e) {
                 redisLock.unlock(_redisKey, String.valueOf(time));
                 map.put("msg", "保存账户数据失败!");
                 return Result.of(map);
@@ -446,8 +477,26 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
 
             } else if (comCntOrderVo.getPayType().equals(2)) {
                 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);
+
             } else if (comCntOrderVo.getPayType().equals(3)) {
                 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);
             } else if (comCntOrderVo.getPayType().equals(4)) {
 
                 // 验证种子价格是否和服务器一样,不一样判定非法操作
@@ -455,7 +504,7 @@ public class ComSnbFreezeController extends CommonController<ComSnbFreezeVo, Com
                 Double _backCNT = Double.parseDouble(pay_amount);
                 // 处理itemType,种子id ,获取种子类型,设置种子不同的数据
                 // todo 直接处理种子id
-                Integer itemType =  Integer.parseInt(item_type);
+                Integer itemType = Integer.parseInt(item_type);
                 ComMallSeedVo seedVo = comMallSeedService.findById(itemType);
                 if (seedVo == null) {
                     comCntOrderVo.setCntDescribe("非法操作:所修改的种子不存在服务器中!当前购买种子id:" + itemType);

+ 89 - 73
src/main/java/com/td/boss/game/comusers/controller/ComUsersController.java

@@ -102,42 +102,42 @@ public class ComUsersController extends CommonController<ComUsersVo, ComUsers, S
      * @param loginId
      * @return
      */
-    @Deprecated
-    @GetMapping("loginToken")
-    public Result<Map> userLogin(@RequestParam(value = "loginId", required = false) String loginId) {
-        log.info("login active:" + active);
-        String userId;
-        if (active.equals("dev")) {
-            //if(loginId == null || !loginId.equals("1")){
-            //    return Result.of(null,false,"请输入参数 loginId = '1' ",ResultEnum.NO_PARAMETERS_CARRIED.getCode());
-            //}
-            //如果测试环境中,提供测试账号
-            userId = loginId;
-        } else {
-            // 正式环境
-            userId = loginId;
-        }
-
-        ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
-
-        if (comUsersVo == null) {
-            //如果没有用户信息
-            comUsersVo = new ComUsersVo();
-            comUsersVo.setUserId(userId);
-            comUsersVo.setGold(0);
-            comUsersVo.setDiamond(0);
-            comUsersVo.setCnt(0);
-            comUsersVo.setSnb(0);
-            comUsersService.save(comUsersVo);
-        }
-
-        //生成token
-        final String token = jwtTokenUtil.generateToken(comUsersVo.getUserId());
-        Map map = new HashMap();
-        map.put("active", active);
-        map.put("token", token);
-        return Result.of(map);
-    }
+    //@Deprecated
+    //@GetMapping("loginToken")
+    //public Result<Map> userLogin(@RequestParam(value = "loginId", required = false) String loginId) {
+    //    log.info("login active:" + active);
+    //    String userId;
+    //    if (active.equals("dev")) {
+    //        //if(loginId == null || !loginId.equals("1")){
+    //        //    return Result.of(null,false,"请输入参数 loginId = '1' ",ResultEnum.NO_PARAMETERS_CARRIED.getCode());
+    //        //}
+    //        //如果测试环境中,提供测试账号
+    //        userId = loginId;
+    //    } else {
+    //        // 正式环境
+    //        userId = loginId;
+    //    }
+    //
+    //    ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
+    //
+    //    if (comUsersVo == null) {
+    //        //如果没有用户信息
+    //        comUsersVo = new ComUsersVo();
+    //        comUsersVo.setUserId(userId);
+    //        comUsersVo.setGold(0);
+    //        comUsersVo.setDiamond(0);
+    //        comUsersVo.setCnt(0);
+    //        comUsersVo.setSnb(0);
+    //        comUsersService.save(comUsersVo);
+    //    }
+    //
+    //    //生成token
+    //    final String token = jwtTokenUtil.generateToken(comUsersVo.getUserId());
+    //    Map map = new HashMap();
+    //    map.put("active", active);
+    //    map.put("token", token);
+    //    return Result.of(map);
+    //}
 
 
     /**
@@ -359,44 +359,60 @@ public class ComUsersController extends CommonController<ComUsersVo, ComUsers, S
     }
 
 
-    @PostMapping("setUserInfo")
-    public Result<Map> setUserInfo(@RequestParam(value = "userId") String userId,
-                                   @RequestParam(value = "cnt") Integer cnt,
-                                   @RequestParam(value = "snb") Integer snb,
-                                   @RequestParam(value = "gold") Integer gold,
-                                   @RequestParam(value = "diamond") Integer diamond) {
-        Map map = new HashMap();
-        ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
-        if (comUsersVo == null) {
-            return Result.of(null, false, ResultEnum.USER_DOES_NOT_EXIST.getMessage(), ResultEnum.USER_DOES_NOT_EXIST.getCode());
-        }
-
-        comUsersVo.setCnt(cnt);
-        comUsersVo.setSnb(snb);
-        comUsersVo.setGold(gold);
-        comUsersVo.setDiamond(diamond);
-        comUsersService.save(comUsersVo);
-        map.put("gold", comUsersVo.getGold());
-        map.put("diamond", comUsersVo.getDiamond());
-        map.put("CNT", comUsersVo.getCnt());
-        map.put("SNB", comUsersVo.getSnb());
-        map.put("address", comUsersVo.getAddress());
-        return Result.of(map);
-    }
+//    @PostMapping("setUserInfo")
+//    public Result<Map> setUserInfo(@RequestParam(value = "userId") String userId,
+//                                   @RequestParam(value = "cnt") Integer cnt,
+//                                   @RequestParam(value = "snb") Integer snb,
+//                                   @RequestParam(value = "gold") Integer gold,
+//                                   @RequestParam(value = "diamond") Integer diamond) {
+//        Map map = new HashMap();
+//        ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
+//        if (comUsersVo == null) {
+//            return Result.of(null, false, ResultEnum.USER_DOES_NOT_EXIST.getMessage(), ResultEnum.USER_DOES_NOT_EXIST.getCode());
+//        }
+//
+//        comUsersVo.setCnt(cnt);
+//        comUsersVo.setSnb(snb);
+//        comUsersVo.setGold(gold);
+//        comUsersVo.setDiamond(diamond);
+//        comUsersService.save(comUsersVo);
+//        map.put("gold", comUsersVo.getGold());
+//        map.put("diamond", comUsersVo.getDiamond());
+//        map.put("CNT", comUsersVo.getCnt());
+//        map.put("SNB", comUsersVo.getSnb());
+//        map.put("address", comUsersVo.getAddress());
+//        return Result.of(map);
+//    }
 
 
     //推送数据接口
-    @ResponseBody
-    @RequestMapping("/playback/{cid}")
-    public Result<Map> pushToWeb(@PathVariable String cid, String message) {
-        Map<String, Object> result = new HashMap<>();
-        try {
-            DappWSServer.sendInfo(message, cid);
-            result.put("id", cid);
-            result.put("msg", message);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return Result.of(result);
-    }
+    //@ResponseBody
+    //@RequestMapping("/playback/{cid}")
+    //public Result<Map> pushToWeb(@PathVariable String cid, String message) {
+    //    Map<String, Object> result = new HashMap<>();
+    //    try {
+    //        DappWSServer.sendInfo(message, cid);
+    //        result.put("id", cid);
+    //        result.put("msg", message);
+    //    } catch (IOException e) {
+    //        e.printStackTrace();
+    //    }
+    //    return Result.of(result);
+    //}
+
+
+    //@PostMapping("setUserDiamond")
+    //public Result<Map> setUserDiamond(@RequestParam(value = "userId") String userId,
+    //                               @RequestParam(value = "diamond") Integer diamond) {
+    //    Map map = new HashMap();
+    //    ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
+    //    if (comUsersVo == null) {
+    //        return Result.of(null, false, ResultEnum.USER_DOES_NOT_EXIST.getMessage(), ResultEnum.USER_DOES_NOT_EXIST.getCode());
+    //    }
+    //    comUsersVo.setDiamond(diamond);
+    //    comUsersService.save(comUsersVo);
+    //    map.put("diamond", comUsersVo.getDiamond());
+    //    map.put("address", comUsersVo.getAddress());
+    //    return Result.of(map);
+    //}
 }

+ 33 - 0
src/main/java/com/td/boss/sys/sysGame/controller/sysGamePropertyController.java

@@ -20,12 +20,15 @@ import com.td.boss.game.commallseed.service.ComMallSeedService;
 import com.td.boss.game.commallseed.vo.ComMallSeedVo;
 import com.td.boss.game.complayergoods.service.ComPlayerGoodsService;
 import com.td.boss.game.complayergoods.vo.ComPlayerGoodsTypeSumVo;
+import com.td.boss.game.comsnbapply.service.ComSnbApplyService;
+import com.td.boss.game.comsnbapply.vo.ComSnbApplyVo;
 import com.td.boss.game.comsnbtran.service.ComSnbTranService;
 import com.td.boss.game.comsnbtran.vo.ComSnbTranDateVo;
 import com.td.boss.game.comsnbtran.vo.ComSnbTranTranTypeSumVo;
 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.SysSettingTaskUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -62,6 +65,10 @@ public class sysGamePropertyController extends CommonController<ComUsersVo, ComU
     private ComFruitService comFruitService;
 
 
+    @Autowired
+    private ComSnbApplyService comSnbApplyService;
+
+
     @GetMapping("CNTAndSNB")
     public ModelAndView CNTAndSNB(){
 
@@ -228,4 +235,30 @@ public class sysGamePropertyController extends CommonController<ComUsersVo, ComU
     public Result saveFruitConfig(ComFruitVo comFruitVo){
         return comFruitService.save(comFruitVo);
     }
+
+
+
+
+    @GetMapping("applySnbToCntView")
+    public ModelAndView usersApplySnbToCnt(){
+        return new ModelAndView("sys/aComApplySNBToCNT/applySNBToCNT","sysSettingTask", SysSettingTaskUtil.getSysSettingTask());
+    }
+
+
+    @PostMapping("findApplySnbToCntPage")
+    @Decrypt
+    @Encrypt
+    public Result<PageInfo<ComSnbApplyVo>> findUsersApplySnbToCnt(ComSnbApplyVo comSnbApplyVo){
+        return comSnbApplyService.page(comSnbApplyVo);
+    }
+
+
+    @PostMapping("updateApplySnbToCntData")
+    @Decrypt
+    @Encrypt
+    public Result<ComSnbApplyVo> updateApplySnbToCntData(ComSnbApplyVo comSnbApplyVo){
+        return comSnbApplyService.save(comSnbApplyVo);
+    }
+
+
 }

+ 1 - 0
src/main/java/com/td/boss/sys/sysGame/controller/sysGameUsersController.java

@@ -18,6 +18,7 @@ import com.td.boss.game.complayerlog.service.ComPlayerLogService;
 import com.td.boss.game.complayerlog.vo.ComPlayerLogVo;
 import com.td.boss.game.complayerprofit.service.ComPlayerProfitService;
 import com.td.boss.game.complayerprofit.vo.ComPlayerProfitVo;
+import com.td.boss.game.comsnbapply.vo.ComSnbApplyVo;
 import com.td.boss.game.comsnbtran.service.ComSnbTranService;
 import com.td.boss.game.comsnbtran.vo.ComSnbTranVo;
 import com.td.boss.game.comusers.pojo.ComUsers;

+ 15 - 0
src/main/java/com/td/boss/sys/syssettingtask/controller/SysSettingTaskController.java

@@ -0,0 +1,15 @@
+package com.td.boss.sys.syssettingtask.controller;
+
+import com.td.boss.common.controller.*;
+import com.td.boss.sys.syssettingtask.pojo.SysSettingTask;
+import com.td.boss.sys.syssettingtask.vo.SysSettingTaskVo;
+import com.td.boss.sys.syssettingtask.service.SysSettingTaskService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/sys/sysSettingTask/")
+public class SysSettingTaskController extends CommonController<SysSettingTaskVo, SysSettingTask, String> {
+    @Autowired
+    private SysSettingTaskService sysSettingTaskService;
+}

+ 21 - 0
src/main/java/com/td/boss/sys/syssettingtask/pojo/SysSettingTask.java

@@ -0,0 +1,21 @@
+package com.td.boss.sys.syssettingtask.pojo;
+
+import lombok.Data;
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+@Entity
+@Table(name = "sys_setting_task")
+@Data
+public class SysSettingTask implements Serializable {
+    @Id
+    private String id;//表id
+
+    private String applyAutoExamine;//是否自动审查 Y/N
+
+    private Date createTime;//创建时间
+
+    private Date updateTime;//修改时间
+
+}

+ 9 - 0
src/main/java/com/td/boss/sys/syssettingtask/repository/SysSettingTaskRepository.java

@@ -0,0 +1,9 @@
+package com.td.boss.sys.syssettingtask.repository;
+
+import com.td.boss.common.repository.*;
+import com.td.boss.sys.syssettingtask.pojo.SysSettingTask;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface SysSettingTaskRepository extends CommonRepository<SysSettingTask, String> {
+}

+ 8 - 0
src/main/java/com/td/boss/sys/syssettingtask/service/SysSettingTaskService.java

@@ -0,0 +1,8 @@
+package com.td.boss.sys.syssettingtask.service;
+
+import com.td.boss.common.service.*;
+import com.td.boss.sys.syssettingtask.pojo.SysSettingTask;
+import com.td.boss.sys.syssettingtask.vo.SysSettingTaskVo;
+
+public interface SysSettingTaskService extends CommonService<SysSettingTaskVo, SysSettingTask, String> {
+}

+ 36 - 0
src/main/java/com/td/boss/sys/syssettingtask/service/SysSettingTaskServiceImpl.java

@@ -0,0 +1,36 @@
+package com.td.boss.sys.syssettingtask.service;
+
+import com.td.boss.common.pojo.Result;
+import com.td.boss.common.service.*;
+import com.td.boss.sys.syssetting.vo.SysSettingVo;
+import com.td.boss.sys.syssettingtask.pojo.SysSettingTask;
+import com.td.boss.sys.syssettingtask.vo.SysSettingTaskVo;
+import com.td.boss.sys.syssettingtask.repository.SysSettingTaskRepository;
+import com.td.boss.util.SysSettingTaskUtil;
+import com.td.boss.util.SysSettingUtil;
+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;
+
+@Service
+@Transactional
+public class SysSettingTaskServiceImpl extends CommonServiceImpl<SysSettingTaskVo, SysSettingTask, String> implements SysSettingTaskService{
+
+    @PersistenceContext
+    private EntityManager em;
+    @Autowired
+    private SysSettingTaskRepository sysSettingTaskRepository;
+
+    @Override
+    public Result<SysSettingTaskVo> save(SysSettingTaskVo entityVo) {
+        //调用父类
+        Result<SysSettingTaskVo> result = super.save(entityVo);
+
+        //更新系统设置时同步更新公用静态集合sysSettingTaskMap
+         SysSettingTaskUtil.setSysSettingTaskMap(result.getData());
+
+        return result;
+    }
+}

+ 17 - 0
src/main/java/com/td/boss/sys/syssettingtask/vo/SysSettingTaskVo.java

@@ -0,0 +1,17 @@
+package com.td.boss.sys.syssettingtask.vo;
+
+import com.td.boss. common.pojo.PageCondition;import lombok.Data;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class SysSettingTaskVo extends PageCondition implements Serializable {
+    private String id;//表id
+
+    private String applyAutoExamine;//是否自动审查 Y/N
+
+    private Date createTime;//创建时间
+
+    private Date updateTime;//修改时间
+
+}

+ 7 - 6
src/main/java/com/td/boss/util/CodeDOM.java

@@ -532,11 +532,12 @@ public class CodeDOM {
        // String[] tables = {"sys_user","sys_menu","sys_authority","sys_user_menu","sys_user_authority","sys_shortcut_menu","sys_setting"};
        // String[] tables = {"com_player_goods","com_players","com_users","com_rewards"};
        // String[] tables = {"com_wallet","com_cnt_order","com_mall_seed","com_player_goods","com_player_land","com_config_land","com_fruit","com_snb_tran"};
-       // "com_player_log" ,"com_explain_land","com_player_profit","com_players_attri","com_setting","com_player_dog","com_mall_other"
-       // String[] tables = {"com_mall_food"};
-       // for (String table : tables) {
-       //     String msg = new CodeDOM(table).create();
-       //     System.out.println(msg);
-       // }
+       // "com_player_log" ,"com_explain_land","com_player_profit","com_players_attri","com_setting","com_player_dog","com_mall_other","com_mall_food"
+       // "com_snb_apply"
+        String[] tables = {"sys_setting_task"};
+        for (String table : tables) {
+            String msg = new CodeDOM(table).create();
+            System.out.println(msg);
+        }
     }
 }

+ 21 - 0
src/main/java/com/td/boss/util/RedisData.java

@@ -31,6 +31,20 @@ public class RedisData {
         return PLAYER_GOODS_TIMEOUT;
     }
 
+    /**
+     * 60s 第一次触发灾难锁
+     */
+    private static final int PLAYER_DISASTERS_FIRST_TIMEOUT = 60 * 1000; //超时时间 60s
+    public static int getPlayerDisastersFirstTimeout() {
+        return PLAYER_DISASTERS_FIRST_TIMEOUT;
+    }
+
+    private static final String PLAYER_DISASTERS_FIRST_KEY = "DISASTERS_FIRST";
+    public static String getPlayerDisastersFirstKey() {
+        return PLAYER_DISASTERS_FIRST_KEY;
+    }
+
+
     /**
      * 1h 灾难模块锁
      */
@@ -62,4 +76,11 @@ public class RedisData {
     public static int getPlayerLandLevelupTimeout() {
         return PLAYER_LAND_LEVELUP_TIMEOUT;
     }
+    /**
+     * 20s 自动审核锁
+     */
+    private static final int AUTO_APPLY_TIMEOUT = 1000 * 20;
+    public static int getAutoApplyTimeout () {
+        return AUTO_APPLY_TIMEOUT;
+    }
 }

+ 32 - 0
src/main/java/com/td/boss/util/SysSettingTaskUtil.java

@@ -0,0 +1,32 @@
+package com.td.boss.util;
+
+import com.td.boss.sys.syssetting.vo.SysSettingVo;
+import com.td.boss.sys.syssettingtask.pojo.SysSettingTask;
+import com.td.boss.sys.syssettingtask.vo.SysSettingTaskVo;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 系统设置工具类
+ * 系统启动时获取数据库数据,设置到公用静态集合sysSettingMap
+ * 更新系统设置时同步更新公用静态集合sysSettingMap
+ */
+public class SysSettingTaskUtil {
+
+    //使用线程安全的ConcurrentHashMap来存储系统设置
+    private static ConcurrentHashMap<String, SysSettingTaskVo> sysSettingTaskMap = new ConcurrentHashMap<>();
+
+    //从公用静态集合sysSettingTaskMap获取系统设置
+    public static SysSettingTaskVo getSysSettingTask(){
+        return sysSettingTaskMap.get("sysSettingTask");
+    }
+
+    //更新公用静态集合sysSettingTaskMap
+    public static void setSysSettingTaskMap(SysSettingTaskVo sysSettingTaskVo){
+        if(sysSettingTaskMap.isEmpty()){
+            sysSettingTaskMap.put("sysSettingTask",sysSettingTaskVo);
+        }else{
+            sysSettingTaskMap.replace("sysSettingTask",sysSettingTaskVo);
+        }
+    }
+}

+ 22 - 0
src/main/resources/static/sys/aComApplySNBToCNT/css/applySNBToCNT.css

@@ -0,0 +1,22 @@
+body {
+    padding: 20px;
+    background-color: #F2F2F2;
+}
+
+.layui-form-label {
+    width: 120px !important;
+}
+
+.layui-input-block {
+    display: -webkit-box !important;
+}
+
+.layui-table-tool-temp {
+    padding-right: 0;
+}
+
+#queryByLoginName {
+    display: unset;
+    width: 100px;
+    margin-left: 10px;
+}

+ 196 - 0
src/main/resources/static/sys/aComApplySNBToCNT/js/applySNBToCNT.js

@@ -0,0 +1,196 @@
+let tableApplySNBToCNT;
+let tree;
+let startDate = new Date(new Date(new Date().toLocaleDateString()).getTime()),
+    endDate = new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1);
+let snbStartDate = startDate, snbEndDate = endDate;
+
+layui.use(['element', 'form', 'table', 'layer', 'laydate', 'tree', 'util'], function () {
+    let table = layui.table;
+    let form = layui.form;//select、单选、复选等依赖form
+    let element = layui.element; //导航的hover效果、二级菜单等功能,需要依赖element模块
+    let laydate = layui.laydate;
+    tree = layui.tree;
+    let height = document.documentElement.clientHeight;
+
+    tableApplySNBToCNT = table.render({
+        elem: '#applySnbTable'
+        , url: ctx + "/sys/sysProperty/findApplySnbToCntPage"
+        , method: 'POST'
+        //请求前参数处理
+        , request: {
+            pageName: 'page' //页码的参数名称,默认:page
+            , limitName: 'rows' //每页数据量的参数名,默认:limit
+        }
+        , where: {
+            startTime: commonUtil.parseTime(snbStartDate),
+            endTime: commonUtil.parseTime(snbEndDate)
+        }
+        , response: {
+            statusName: 'flag' //规定数据状态的字段名称,默认:code
+            , statusCode: true //规定成功的状态码,默认:0
+            , msgName: 'msg' //规定状态信息的字段名称,默认:msg
+            , countName: 'records' //规定数据总数的字段名称,默认:count
+            , dataName: 'rows' //规定数据列表的字段名称,默认:data
+        }
+        //响应后数据处理
+        , parseData: function (res) { //res 即为原始返回的数据
+            var data = res.data;
+            console.log("返回的地址数据:", data);
+            //这里应该是反回一个用户,后台做成了页面数据。但是只带一条数据
+            return {
+                "flag": res.flag, //解析接口状态
+                "msg": res.msg, //解析提示文本
+                "records": data.records, //解析数据长度
+                "rows": data.rows //解析数据列表
+            };
+        }
+        , toolbar: '#applySnbTableToolbarDemo'
+        , title: 'SNB申请列表'
+        , cols: [
+            [
+                {type: 'checkbox', fixed: 'left'},
+                {
+                    field: 'isState', title: '申请状态', sort: true, templet: function (d) {
+                        if (d.isState == 0) {
+                            return '<span style="color: green">申请中</span>';
+                        } else if (d.isState == 1) {
+                            return '<span style="color: green">申请成功</span>';
+                        } else if (d.isState == 2) {
+                            return '<span style="color: red ">申请驳回</span>';
+                        } else if (d.isState == 3) {
+                            return '<span style="color: red ">进入兑换流程</span>';
+                        } else {
+                            return '待添加:' + d.isState;
+                        }
+                    }
+                }
+                , {field: 'id', title: 'ID'}
+                , {field: 'userId', title: '用户id'}
+                , {field: 'snb', title: '申请的Snb',sort: true}
+                , {field: 'snbDescribe', title: '描述'}
+                , {field: 'createTime', title: '创建时间',sort: true}
+                , {field: 'updateTime', title: '更新时间',sort: true}
+                , {fixed: 'right', title: '操作', toolbar: '#barDemo', width: 150}
+            ]]
+        , defaultToolbar: ['', 'exports', 'print']
+        , page: true
+        , height: height
+        , cellMinWidth: 80
+    });
+
+    //radio checkbox
+    $("#sysSettingTaskForm").find("[name='applyAutoExamine'][value='" + $("#applyAutoExamine").val() + "']").attr("checked", true);
+    form.render();
+
+    //头工具栏事件
+    table.on('toolbar(test)', function (obj) {
+        let data = obj.data;
+        switch (obj.event) {
+            case 'applySnbTableReload':
+                searchSNBFromDate();
+                break;
+            case 'getCheckData':
+                let checkStatus1 = table.checkStatus('applySnbTable'),data1 = checkStatus1.data;
+                layer.alert(JSON.stringify(data1));
+                break;
+            case 'getCheckLength':
+                let checkStatus2 = table.checkStatus('applySnbTable'),data2 = checkStatus2.data;
+                layer.msg('选中了:'+ data2.length + ' 个');
+                break;
+            case 'isAll':
+                let checkStatus3 = table.checkStatus('applySnbTable');
+                layer.msg(checkStatus3.isAll ? '全选': '未全选')
+                break;
+        }
+    });
+
+    //监听行工具事件
+    table.on('tool(test)', function (obj) {
+        let data = obj.data;
+        switch (obj.event) {
+            case 'edit':
+                //编辑
+                console.log("edit");
+                //回显操作表单
+                // $("#comUserForm").form(data);
+                // form.render();
+                break;
+            case 'agree':
+                if (!data.id) {
+                    layer.msg("编辑列表不存在", {icon: 2, time: 1000}, function () {
+                    });
+                    return;
+                }
+                data.isState = 1;   //同意申请 1
+                $.post(ctx + "/sys/sysProperty/updateApplySnbToCntData", data, function (res) {
+                    if (!res.flag) {
+                        layer.msg(res.msg, {icon: 2, time: 2000}, function () {
+                        });
+                        return;
+                    }
+                    obj.update(res.data);
+                });
+                break;
+            case 'reject':
+                if (!data.id) {
+                    layer.msg("编辑列表不存在", {icon: 2, time: 1000}, function () {
+                    });
+                    return;
+                }
+                data.isState = 2;       //驳回申请 2
+                $.post(ctx + "/sys/sysProperty/updateApplySnbToCntData", data, function (res) {
+                    if (!res.flag) {
+                        layer.msg(res.msg, {icon: 2, time: 2000}, function () {
+                        });
+                        return;
+                    }
+                    obj.update(res.data);
+                });
+                break;
+        }
+    });
+
+    laydate.render({
+        elem: '#applySnbTableDate'
+        , type: 'datetime'
+        , value: commonUtil.parseTime(snbStartDate) + ' - ' + commonUtil.parseTime(snbEndDate)
+        , isInitValue: true
+        , range: true
+        , done: function (_value, _date, _endDate) {
+            let _array = _value.split(' - ');
+            snbStartDate = _array[0];
+            snbEndDate = _array[1];
+            searchSNBFromDate();
+        }
+    });
+});
+
+function searchSNBFromDate() {
+    tableApplySNBToCNT.reload({
+        page: false
+        , method: 'POST'
+        , url: ctx + "/sys/sysProperty/findApplySnbToCntPage"
+        , where: {
+            startTime: commonUtil.parseTime(snbStartDate),
+            endTime: commonUtil.parseTime(snbEndDate)
+        }
+        , done: function (res, curr, count) {
+            // console.log(res, curr, count);
+            // this.where={};
+            //不清空,有问题:搜索条件会保留
+            //清空,  有问题:分页的时候没有搜索条件了,分页会受到影响
+        }
+    });
+}
+
+/**
+ * 提交保存
+ */
+function sysSettingTaskFormSave() {
+    let serializeObject = $("#sysSettingTaskForm").serializeObject();
+    $.post(ctx + "/sys/sysSettingTask/save", serializeObject, function (data) {
+        layer.msg("修改成功!", {icon: 1, time: 2000}, function () {});
+        $("#sysSettingTaskForm").form(data.data);
+        $("#applyAutoExamine").val(data.data.applyAutoExamine)
+    });
+}

+ 74 - 0
src/main/resources/view/sys/aComApplySNBToCNT/applySNBToCNT.html

@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<!--解决idea thymeleaf 表达式模板报红波浪线-->
+<!--suppress ALL -->
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+    <!-- 引入公用部分 -->
+    <script th:replace="common/head::static"></script>
+    <!-- 游戏数据用户相关样式 -->
+    <link th:href="@{/sys/aComApplySNBToCNT/css/applySNBToCNT.css}" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div class="layui-row layui-col-space15">
+    <div class="layui-col-md12">
+        <div class="layui-card">
+            <div class="layui-card-header">
+                <label class="layui-form-label" >筛选日期:</label>
+                <div class="layui-input-inline" style="width: 300px;">
+                    <input type="text" class="layui-input" id="applySnbTableDate" placeholder=" - ">
+                </div>
+            </div>
+            <div class="layui-card-body">
+                <form id="sysSettingTaskForm" class="layui-form layui-form-pane">
+                    <div class="layui-form-item  layui-form-text">
+                        <label class="layui-form-label">是否开启自动审查</label>
+                        <div class="layui-input-block">
+                            <input id="applyAutoExamine" th:value="${sysSettingTask.applyAutoExamine}"  hidden="hidden"/>
+                            <input type="radio" name="applyAutoExamine" value="Y" title="是">
+                            <input type="radio" name="applyAutoExamine" value="N" title="否">
+                        </div>
+                    </div>
+                    <div class="layui-form-item  layui-form-text">
+                        <label class="layui-form-label">更新时间</label>
+                        <div class="layui-input-block">
+                            <input type="text" name="updateTime" th:value="${#dates.format(sysSettingTask.updateTime, 'yyyy-MM-dd HH:mm:ss')}" autocomplete="off"
+                                   placeholder="更新时间"
+                                   class="layui-input" readonly="readonly" disabled="disabled">
+                        </div>
+                    </div>
+                    <div class="layui-form-item">
+                        <div class="layui-input-block">
+                            <a class="layui-btn" onclick="sysSettingTaskFormSave()">修改</a>
+                        </div>
+                    </div>
+                    <!-- 隐藏域 -->
+                    <input type="text" name="id"  th:value="${sysSettingTask.id}" hidden="hidden"/>
+                    <input type="text" name="createTime"  th:value="${#dates.format(sysSettingTask.createTime, 'yyyy-MM-dd HH:mm:ss')}" hidden="hidden"/>
+                </form>
+            </div>
+            <div class="layui-card-body">
+                <!-- 表格主体 -->
+                <table class="layui-hide" id="applySnbTable" lay-filter="test"></table>
+
+                <!-- 模板 -->
+                <script type="text/html" id="applySnbTableToolbarDemo">
+                    <div class="layui-btn-container">
+                        <button class="layui-btn" lay-event="applySnbTableReload">刷新</button>
+                        <button class="layui-btn" lay-event="getCheckData">获取选中行数据</button>
+                        <button class="layui-btn" lay-event="getCheckLength">获取选中数目</button>
+                        <button class="layui-btn" lay-event="isAll">验证是否全选</button>
+                    </div>
+                </script>
+
+                <script type="text/html" id="barDemo">
+                    <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="agree">同意</a>
+                    <a class="layui-btn layui-btn-xs" lay-event="reject">驳回</a>
+                </script>
+            </div>
+        </div>
+    </div>
+</div>
+</body>
+<!-- js -->
+<script th:src="@{/sys/aComApplySNBToCNT/js/applySNBToCNT.js}"></script>
+</html>