Преглед на файлове

Merge branch 'master' of http://81.70.224.233:10080/slambb/FragrantTown_Server_Local

slambb преди 3 години
родител
ревизия
5c12ce6982
променени са 44 файла, в които са добавени 1157 реда и са изтрити 67 реда
  1. 0 5
      pom.xml
  2. 1 1
      src/main/java/com/td/boss/common/pojo/ComConfig.java
  3. 2 0
      src/main/java/com/td/boss/common/service/ComConfigService.java
  4. 18 4
      src/main/java/com/td/boss/common/service/ComConfigServiceImpl.java
  5. 8 0
      src/main/java/com/td/boss/config/enums/ResultEnum.java
  6. 1 0
      src/main/java/com/td/boss/game/comconfigland/pojo/ComConfigLand.java
  7. 5 0
      src/main/java/com/td/boss/game/comconfigland/vo/ComConfigLandVo.java
  8. 5 0
      src/main/java/com/td/boss/game/comexplainland/pojo/ComExplainLand.java
  9. 5 0
      src/main/java/com/td/boss/game/comexplainland/vo/ComExplainLandVo.java
  10. 3 0
      src/main/java/com/td/boss/game/commallseed/controller/ComMallSeedController.java
  11. 53 0
      src/main/java/com/td/boss/game/complayercultivate/controller/ComPlayerCultivateController.java
  12. 56 0
      src/main/java/com/td/boss/game/complayercultivate/pojo/ComPlayerCultivate.java
  13. 11 0
      src/main/java/com/td/boss/game/complayercultivate/repository/ComPlayerCultivateRepository.java
  14. 41 0
      src/main/java/com/td/boss/game/complayercultivate/serivce/ComPlayerCultivateSerivce.java
  15. 276 0
      src/main/java/com/td/boss/game/complayercultivate/serivce/ComPlayerCultivateSerivceImpl.java
  16. 10 0
      src/main/java/com/td/boss/game/complayercultivate/vo/ComPlayerCultivateSeedVo.java
  17. 50 0
      src/main/java/com/td/boss/game/complayercultivate/vo/ComPlayerCultivateVo.java
  18. 16 1
      src/main/java/com/td/boss/game/complayergoods/controller/ComPlayerGoodsController.java
  19. 5 1
      src/main/java/com/td/boss/game/complayergoods/pojo/ComPlayerGoods.java
  20. 3 4
      src/main/java/com/td/boss/game/complayergoods/repository/ComPlayerGoodsRepository.java
  21. 6 7
      src/main/java/com/td/boss/game/complayergoods/service/ComPlayerGoodsServiceImpl.java
  22. 7 2
      src/main/java/com/td/boss/game/complayergoods/vo/ComPlayerGoodsVo.java
  23. 63 11
      src/main/java/com/td/boss/game/complayerland/controller/ComPlayerLandController.java
  24. 1 1
      src/main/java/com/td/boss/game/complayerland/pojo/ComPlayerDisasterProtected.java
  25. 2 0
      src/main/java/com/td/boss/game/complayerland/pojo/ComPlayerLand.java
  26. 14 0
      src/main/java/com/td/boss/game/complayerland/service/ComPlayerDisasterProtectedService.java
  27. 30 0
      src/main/java/com/td/boss/game/complayerland/service/ComPlayerDisasterProtectedServiceImpl.java
  28. 5 0
      src/main/java/com/td/boss/game/complayerland/vo/ComPlayerLandAndPlantVo.java
  29. 5 0
      src/main/java/com/td/boss/game/complayerland/vo/ComPlayerLandVo.java
  30. 4 0
      src/main/java/com/td/boss/game/complayerlog/repository/ComPlayerLogRepository.java
  31. 7 0
      src/main/java/com/td/boss/game/complayerlog/service/ComPlayerLogService.java
  32. 145 1
      src/main/java/com/td/boss/game/complayerlog/service/ComPlayerLogServiceImpl.java
  33. 2 2
      src/main/java/com/td/boss/game/complayersattri/controller/ComPlayersLuckyController.java
  34. 4 1
      src/main/java/com/td/boss/game/complayersattri/repository/ComPlayersLuckyRepository.java
  35. 1 1
      src/main/java/com/td/boss/game/complayersattri/service/ComPlayersLuckyService.java
  36. 24 5
      src/main/java/com/td/boss/game/complayersattri/service/ComPlayersLuckyServiceImpl.java
  37. 2 0
      src/main/java/com/td/boss/game/complayersattri/vo/ComPlayersLuckyToolsVo.java
  38. 76 0
      src/main/java/com/td/boss/util/DappUtil.java
  39. 8 0
      src/main/java/com/td/boss/util/RedisData.java
  40. 12 4
      src/main/resources/application.yml
  41. 128 0
      src/test/java/com/td/boss/ComPlayerCultivateTests.java
  42. 6 15
      src/test/java/com/td/boss/ComPlayerDisasterLogTests.java
  43. 21 0
      src/test/java/com/td/boss/ComPlayerLogTests.java
  44. 15 1
      src/test/java/com/td/boss/ComPlayerLuckyTests.java

+ 0 - 5
pom.xml

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

+ 1 - 1
src/main/java/com/td/boss/common/pojo/ComConfig.java

@@ -7,7 +7,7 @@ import java.io.Serializable;
 
 @Entity
 @Data
-@Table(name = "com_players_lucky_tools")
+@Table(name = "com_config")
 public class ComConfig implements Serializable {
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)

+ 2 - 0
src/main/java/com/td/boss/common/service/ComConfigService.java

@@ -8,4 +8,6 @@ public interface ComConfigService {
     String selectByKey(String key);
 
     List<ComPlayersLuckyLandLevelUpVo> selectLandLevel();
+
+    <T> List<T> selectByKey(String key, Class<T> clazz);
 }

+ 18 - 4
src/main/java/com/td/boss/common/service/ComConfigServiceImpl.java

@@ -23,7 +23,7 @@ public class ComConfigServiceImpl implements ComConfigService {
     private ComConfigRepository repository;
 
     private List<ComConfig> list() {
-        List<ComConfig> list = null;
+        List<ComConfig> list;
         String s = redisTemplate.opsForValue().get(redisKey);
         if (StrUtil.isBlank(s)) {
             list = repository.list();
@@ -39,15 +39,29 @@ public class ComConfigServiceImpl implements ComConfigService {
         List<ComConfig> list = list();
         return list.stream().filter(a -> a.getConfigKey().equals(key)).map(a -> a.getConfigValue()).findFirst().orElse("");
     }
+
+    /**
+     * 获取种植土地级别配置
+     *
+     * @return
+     */
     @Override
     public List<ComPlayersLuckyLandLevelUpVo> selectLandLevel() {
-        String levelUp = "land_level";
-        List<ComConfig> list = list();
-        String land_tools = list.stream().filter(a -> a.getConfigKey().equals(levelUp)).map(a -> a.getConfigValue()).findFirst().orElse("");
+        String land_tools = selectByKey("land_level");
         if (StrUtil.isBlank(land_tools)) {
             return new ArrayList<>();
         } else {
             return JSONUtil.toList(land_tools, ComPlayersLuckyLandLevelUpVo.class);
         }
     }
+
+    @Override
+    public <T> List<T> selectByKey(String key, Class<T> clazz) {
+        String json = selectByKey(key);
+        if (StrUtil.isBlank(json)) {
+            return new ArrayList<>();
+        } else {
+            return JSONUtil.toList(json, clazz);
+        }
+    }
 }

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

@@ -100,6 +100,14 @@ public enum ResultEnum {
     FOOD_DOT_NOT(811,"狗粮不足!"),
 
     SEED_SALE_SAVE_LOCK(810,"操作繁忙,出售失败,稍后再试!"),
+    SEED_NO_LAND_ERROR(812,"种子土地不匹配!"),
+    SEED_LAND_TIME_ERROR(813,"土地租赁时间不足!"),
+
+    LAND_NO_TIMES_ERROR(814,"次数不足,租赁失败!"),
+    FOOD_NO_TYPE_ERROR(815,"粮食和养殖类型不匹配!"),
+    LAND_NO_PLANT_ERROR(816,"土地未养殖,喂养失败!"),
+    FOOD_NO_ERROR(817,"未找到养料!"),
+    FOOD_REPEAT_ERROR(818,"今日已喂养!"),
     //装备相关
     MALL_OTHER_IS_NULL(810,"商城装备不存在!"),
     MALL_OTHER_IS_HAVE(811,"商城装备已经存在!"),

+ 1 - 0
src/main/java/com/td/boss/game/comconfigland/pojo/ComConfigLand.java

@@ -51,4 +51,5 @@ public class ComConfigLand implements Serializable {
 
     private Date updateTime;//
 
+    private Integer mallType;
 }

+ 5 - 0
src/main/java/com/td/boss/game/comconfigland/vo/ComConfigLandVo.java

@@ -46,4 +46,9 @@ public class ComConfigLandVo  implements Serializable { //extends PageCondition
 
     private Date updateTime;//
 
+    /**
+     * 需求 牧场养殖渔场,新增字段,
+     * 原有需求种地值0 牧场1 养殖2 淡水区3 海水区4
+     */
+    private Integer mallType;
 }

+ 5 - 0
src/main/java/com/td/boss/game/comexplainland/pojo/ComExplainLand.java

@@ -44,4 +44,9 @@ public class ComExplainLand implements Serializable {
 
     private Date updateTime;//
 
+    /**
+     * 需求 牧场养殖渔场,新增字段,
+     * 原有需求种地值0 牧场1 养殖2 淡水区3 海水区4
+     */
+    private Integer mallType;
 }

+ 5 - 0
src/main/java/com/td/boss/game/comexplainland/vo/ComExplainLandVo.java

@@ -40,4 +40,9 @@ public class ComExplainLandVo extends PageCondition implements Serializable {
 
     private Date updateTime;//
 
+    /**
+     * 需求 牧场养殖渔场,新增字段,
+     * 原有需求种地值0 牧场1 养殖2 淡水区3 海水区4
+     */
+    private Integer mallType;
 }

+ 3 - 0
src/main/java/com/td/boss/game/commallseed/controller/ComMallSeedController.java

@@ -1,5 +1,6 @@
 package com.td.boss.game.commallseed.controller;
 
+import cn.hutool.core.convert.Convert;
 import com.alibaba.fastjson.JSONObject;
 import com.td.boss.common.controller.*;
 import com.td.boss.common.pojo.Result;
@@ -143,6 +144,8 @@ public class ComMallSeedController extends CommonController<ComMallSeedVo, ComMa
                 entityVo.setName(seedVo.getName());
                 entityVo.setPictureName(seedVo.getPicture());
                 entityVo.setUserId(userId);
+                //[xst]此处新增获取种子的类型
+                entityVo.setMallType(Convert.toInt(seedVo.getMallType(),0));
             } else {
                 Integer _amount = entityVo.getAmount() + _paySeedAmount;
                 entityVo.setAmount(_amount);

+ 53 - 0
src/main/java/com/td/boss/game/complayercultivate/controller/ComPlayerCultivateController.java

@@ -0,0 +1,53 @@
+package com.td.boss.game.complayercultivate.controller;
+
+import cn.hutool.core.convert.Convert;
+import com.td.boss.common.pojo.Result;
+import com.td.boss.config.enums.ResultEnum;
+import com.td.boss.game.comexplainland.service.ComExplainLandService;
+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.complayercultivate.serivce.ComPlayerCultivateSerivce;
+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.service.ComPlayerLandService;
+import com.td.boss.game.complayerland.vo.ComPlayerLandAndPlantVo;
+import com.td.boss.game.complayerland.vo.ComPlayerLandVo;
+import com.td.boss.game.complayerlog.service.ComPlayerLogService;
+import com.td.boss.game.complayerlog.vo.ComPlayerLogVo;
+import com.td.boss.util.CopyUtil;
+import com.td.boss.util.DateUtil;
+import com.td.boss.util.UUIDUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+
+
+/**
+ * 放牧\养殖\渔场
+ */
+@RestController
+@Slf4j
+@RequestMapping("/game/comPlayerCultivate/")
+public class ComPlayerCultivateController {
+    @Autowired
+    private ComPlayerCultivateSerivce comPlayerCultivateSerivce;
+
+    /**
+     * 解锁某个土地 【牧场养殖渔场】
+     * @param userId
+     * @param configLandId
+     * @return
+     */
+    @PostMapping("payLand")
+    @Transactional(rollbackFor = Exception.class)
+    public Result<?> payLand(@RequestParam(value = "userId") String userId,
+                                                   @RequestParam(value = "configLandId") Integer configLandId) {
+        return comPlayerCultivateSerivce.payLand(userId, configLandId);
+    }
+}

+ 56 - 0
src/main/java/com/td/boss/game/complayercultivate/pojo/ComPlayerCultivate.java

@@ -0,0 +1,56 @@
+package com.td.boss.game.complayercultivate.pojo;
+
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author :
+ * @date : 2022-3-19
+ * @desc : 放牧养殖渔场租赁表
+ */
+@Entity
+@Data
+@Table(name="com_player_cultivate")
+public class ComPlayerCultivate implements Serializable{
+    /**  */
+    @Id
+    @GeneratedValue(strategy= GenerationType.IDENTITY)
+    private Integer id ;
+    /**
+     * 用户id
+     */
+    private String userId;
+    /**
+     * 土地id
+     */
+    private Integer landId;
+    /**
+     * 土地id
+     */
+    private Integer configLandId;
+    /**
+     * 需求 牧场养殖渔场,新增字段,
+     * 原有需求种地值0 牧场1 养殖2 淡水区3 海水区4
+     */
+    private Integer landType;
+    /**
+     * 土地名称
+     */
+    private Integer amount;
+    /**
+     * 是否正在使用
+     */
+    private Date activtyTime;
+    /**
+     * 土地租赁创建时间
+     */
+    private Date createTime;
+    /**
+     * 土地租赁截止日期
+     */
+    private double snb;
+}

+ 11 - 0
src/main/java/com/td/boss/game/complayercultivate/repository/ComPlayerCultivateRepository.java

@@ -0,0 +1,11 @@
+package com.td.boss.game.complayercultivate.repository;
+
+import com.td.boss.common.repository.CommonRepository;
+import com.td.boss.game.complayercultivate.pojo.ComPlayerCultivate;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ComPlayerCultivateRepository extends CommonRepository<ComPlayerCultivate, Integer> {
+
+    long countComPlayerCultivateByUserIdAndLandTypeAndConfigLandId(String userId,Integer landType,Integer configLandId);
+}

+ 41 - 0
src/main/java/com/td/boss/game/complayercultivate/serivce/ComPlayerCultivateSerivce.java

@@ -0,0 +1,41 @@
+package com.td.boss.game.complayercultivate.serivce;
+
+import com.td.boss.common.pojo.Result;
+import java.util.Date;
+
+public interface ComPlayerCultivateSerivce {
+
+    /**
+     * 解锁某个土地 【牧场养殖渔场】
+     * @param userId
+     * @param configLandId
+     * @return
+     */
+    Result<?> payLand(String userId, Integer configLandId);
+
+    /**
+     * 获取租赁机会
+     *
+     * @param userId
+     * @return
+     */
+    Integer getTimes(String userId);
+
+    /**
+     * 养殖 喂粮,一天不喂延迟2天
+     * @param userId
+     * @param configLandId
+     * @return
+     */
+    Result<?> buyFood(String userId, Integer configLandId);
+
+    /**
+     * 获得养殖类种子实际成熟日期:正常成熟天数+延期天数(一次不喂延迟2天)
+     * 成熟时间的具体值 (取时间差(今天-种植当天)-喂的次数)*2
+     *
+     * @return 延期后的成熟期
+     */
+    Date getHarvestTime(String userId, Integer configLandId);
+
+    Integer getHarvestDays(String userId, Integer configLandId);
+}

+ 276 - 0
src/main/java/com/td/boss/game/complayercultivate/serivce/ComPlayerCultivateSerivceImpl.java

@@ -0,0 +1,276 @@
+package com.td.boss.game.complayercultivate.serivce;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateUtil;
+import com.td.boss.common.pojo.Result;
+import com.td.boss.common.service.ComConfigService;
+import com.td.boss.config.enums.ResultEnum;
+import com.td.boss.game.comconfigland.pojo.ComConfigLand;
+import com.td.boss.game.comconfigland.service.ComConfigLandService;
+import com.td.boss.game.comexplainland.service.ComExplainLandService;
+import com.td.boss.game.comexplainland.vo.ComExplainLandVo;
+import com.td.boss.game.complayercultivate.pojo.ComPlayerCultivate;
+import com.td.boss.game.complayercultivate.repository.ComPlayerCultivateRepository;
+import com.td.boss.game.complayercultivate.vo.ComPlayerCultivateSeedVo;
+import com.td.boss.game.complayercultivate.vo.ComPlayerCultivateVo;
+import com.td.boss.game.complayerland.pojo.ComPlayerDisaster;
+import com.td.boss.game.complayerland.pojo.ComPlayerLand;
+import com.td.boss.game.complayerland.service.ComPlayerLandService;
+import com.td.boss.game.comsnbtran.vo.ComSnbTranVo;
+import com.td.boss.game.comusers.service.ComUsersService;
+import com.td.boss.game.comusers.vo.ComUsersVo;
+import com.td.boss.util.DappUtil;
+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 org.springframework.util.StringUtils;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Service
+@Slf4j
+@Transactional
+public class ComPlayerCultivateSerivceImpl implements ComPlayerCultivateSerivce {
+
+    @Autowired
+    private ComPlayerLandService comPlayerLandService;
+    @Autowired
+    private ComExplainLandService comExplainLandService;
+    @Autowired
+    private ComConfigLandService comConfigLandService;
+    @Autowired
+    private ComPlayerCultivateRepository cultivateRepository;
+    @Autowired
+    private ComConfigService comConfigService;
+    @Autowired
+    private ComUsersService comUsersService;
+    @Autowired
+    private RedisLock redisLock;
+
+    /**
+     * 解锁某个土地 【牧场养殖渔场】
+     * @param userId
+     * @param configLandId
+     * @return
+     */
+    @Transactional
+    @Override
+    public Result<?> payLand(String userId, Integer configLandId) {
+        //根据土地config id查找,对应ConfigLandId ,
+        ComConfigLand comConfigLand = comConfigLandService.findById(configLandId);
+        //如果土地等于不能初始化,或者已经种植,不能进行购买
+        if (comConfigLand == null || comConfigLand.getIsInit().equals(0) || comConfigLand.getIsPlant().equals(1)) {
+            return Result.of(null, false, ResultEnum.LAND_DATA_ERROR.getMessage(), ResultEnum.LAND_DATA_ERROR.getCode());
+        }
+        ComPlayerLand comPlayerLand = comPlayerLandService.findByUserIdAndLandId(userId, configLandId);
+
+        String _redisKey = comPlayerLand.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 = comPlayerLand.getUserId() + "or" + comPlayerLand.getConfigLandId();
+        }
+        long landTime = System.currentTimeMillis() + RedisData.getLandTimeout();
+        if (!redisLock.lock(_redisKey, String.valueOf(landTime))) {
+            log.info("锁住key:" + _redisKey);
+            return ErrorResult("操作频繁!");
+        }
+        try {
+            if (getTimes(userId) <= 0) {
+                return Result.of(null, false, ResultEnum.LAND_NO_TIMES_ERROR.getMessage(), ResultEnum.LAND_NO_TIMES_ERROR.getCode());
+            }
+            if (comPlayerLand == null) {
+                //创建新土地
+                comPlayerLand = new ComPlayerLand();
+                comPlayerLand.setConfigLandId(comConfigLand.getId());
+                comPlayerLand.setUserId(userId);
+                comPlayerLand.setName(comConfigLand.getName());
+                //todo 续租问题,如果用户续租,保留之前的状态
+                //初始化一下未种植参数
+                comPlayerLand.setIsPlant(0);
+                comPlayerLand.setCreateTime(new Date());
+                comPlayerLand.setPlantSteal(1);
+                comPlayerLand.setMallType(comConfigLand.getMallType());
+
+                comPlayerLand.setLandDescribe("每次租赁1个月");
+                comPlayerLand.setLeaseMultiple(1);
+                comPlayerLand.setLeaseDate(1);
+                //设置租赁日期
+                comPlayerLand.setLeaseTime(DateUtil.offset(new Date(), DateField.MONTH, 1));
+                //租赁土地
+                comPlayerLand.setIsLease(1);
+                comPlayerLand.setUpdateTime(new Date());
+                //记录一下租赁费用
+                comPlayerLand.setRentalExpenses(1.0d);
+                comPlayerLandService.AddComPlayerLand(comPlayerLand);
+            }
+            return Result.of(comPlayerLand, true, "租赁成功");
+        } catch (Exception e) {
+        } finally {
+            redisLock.unlock(_redisKey, String.valueOf(landTime));
+        }
+        return ErrorResult("租赁失败!");
+    }
+
+    /**
+     * 获取租赁机会
+     *
+     * @param userId
+     * @return
+     */
+    @Override
+    public Integer getTimes(String userId) {
+        Integer totalcount = DappUtil.getChildrenBuyLandAmount(userId);
+        long nowcount = comPlayerLandService.findAllByUserId(userId).stream()
+                .filter(a -> a.getMallType() != null && a.getMallType() > 0).count();
+        ComExplainLandVo comExplainLandVo = new ComExplainLandVo();
+        comExplainLandVo.setUserId(userId);
+        Result<List<ComExplainLandVo>> list = comExplainLandService.list(comExplainLandVo);
+        long historycount = list.getData().stream().filter(a -> a.getMallType() != null && a.getMallType() > 0).count();
+        return totalcount - Convert.toInt(nowcount) - Convert.toInt(historycount);
+    }
+
+    /**
+     * 喂粮
+     *
+     * @param userId
+     * @param configLandId
+     * @return
+     */
+    @Transactional
+    @Override
+    public Result<?> buyFood(String userId, Integer configLandId) {
+        //获得本次喂的数量
+        ComPlayerLand comPlayerLand = comPlayerLandService.findByUserIdAndLandId(userId, configLandId);
+        //土地数据不存在
+        if (comPlayerLand == null) {
+            return Result.of(null, false, ResultEnum.LAND_DATA_ERROR.getMessage(), ResultEnum.LAND_DATA_ERROR.getCode());
+        }
+        if (!comPlayerLand.getIsLease().equals(1)) {
+            return Result.of(null, false, ResultEnum.LAND_NOT_LEASE.getMessage(), ResultEnum.LAND_NOT_LEASE.getCode());
+        }
+        if (Integer.valueOf(0).equals(comPlayerLand.getMallType()) ) {
+            return Result.of(null, false, ResultEnum.FOOD_NO_TYPE_ERROR.getMessage(), ResultEnum.FOOD_NO_TYPE_ERROR.getCode());
+        }
+        Integer buyAmount = comPlayerLand.getLeaseMultiple();
+        //todo 操作snb数量
+        ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
+        if (comUsersVo.getSnb() <= 0) {
+            return Result.of(null, false, ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getMessage(), ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getCode());
+        }
+        if (Integer.valueOf(0).equals(comPlayerLand.getIsPlant())) {
+            return Result.of(null, false, ResultEnum.LAND_NO_PLANT_ERROR.getMessage(), ResultEnum.LAND_NO_PLANT_ERROR.getCode());
+        }
+        //通过判断土地类型,获取喂粮饲料
+        List<ComPlayerCultivateSeedVo> SeedList = comConfigService.selectByKey("cultivate_food", ComPlayerCultivateSeedVo.class);
+        ComPlayerCultivateSeedVo seedVo = SeedList.stream().filter(a -> a.getSeedId().equals(comPlayerLand.getMallType())).findFirst().orElse(null);
+        if (seedVo == null) {
+            return Result.of(null, false, ResultEnum.FOOD_NO_ERROR.getMessage(), ResultEnum.FOOD_NO_ERROR.getCode());
+        }
+        //判断今天是否已经喂过
+        Date begin = DateUtil.beginOfDay(new Date());
+        Date end = DateUtil.endOfDay(new Date());
+        if (exists(userId, comPlayerLand.getMallType(), configLandId, begin, end)) {
+            return Result.of(null, false, ResultEnum.FOOD_REPEAT_ERROR.getMessage(), ResultEnum.FOOD_REPEAT_ERROR.getCode());
+        }
+        long time = System.currentTimeMillis() + RedisData.getPlayerCultivateBuyFoodTimeout();
+        String _redisKey = "LOCK:COM_PLAYER_CULTIVATE_BUYFOOD:" + userId;
+        if (!redisLock.lock(_redisKey, String.valueOf(time))) {
+            log.info("锁住key:" + _redisKey);
+            return ErrorResult("操作频繁!");
+        }
+        try {
+            ComSnbTranVo _snbTran = new ComSnbTranVo();
+            _snbTran.setBeforeSnb(comUsersVo.getSnb());
+            _snbTran.setBeforeSnbPart(comUsersVo.getSnbPart());
+            //计算
+            Double _allSnb = DoubleUtil.add(comUsersVo.getSnb().doubleValue(), comUsersVo.getSnbPart());
+            //如果有snb,扣除对应的snb
+            Integer _allSnbMaxInt = (int) Math.floor(_allSnb);
+            //这个价格需要从配置里取
+            double _needPrice = buyAmount * seedVo.getSeedSNB();
+            if (_allSnbMaxInt < _needPrice) {
+                return Result.of(null, false, ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getMessage(), ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getCode());
+            }
+            double _tranSnb = _allSnbMaxInt - _needPrice;
+            comUsersVo.setSnb(Convert.toInt(_tranSnb));
+            Double _SnbPart = DoubleUtil.sub(_allSnb, Math.floor(_allSnb));
+            comUsersVo.setSnbPart(_SnbPart);
+            //记录修改的数据
+            comUsersService.save(comUsersVo);
+
+            ComPlayerCultivate comPlayerCultivate = new ComPlayerCultivate();
+            comPlayerCultivate.setLandId(comPlayerLand.getId());
+            comPlayerCultivate.setLandType(comPlayerLand.getMallType());
+            comPlayerCultivate.setUserId(userId);
+            comPlayerCultivate.setCreateTime(new Date());
+            comPlayerCultivate.setConfigLandId(configLandId);
+            comPlayerCultivate.setAmount(buyAmount);
+            comPlayerCultivate.setActivtyTime(new Date());
+            comPlayerCultivate.setSnb(_needPrice);
+            cultivateRepository.save(comPlayerCultivate);
+            return Result.of(null, true, "成功");
+        } catch (Exception e) {
+        } finally {
+            redisLock.unlock(_redisKey, String.valueOf(time));
+        }
+        return ErrorResult("喂养失败!");
+    }
+
+    /**
+     * 获得养殖类种子实际成熟日期:正常成熟天数+延期天数(一次不喂延迟2天)
+     * 成熟时间的具体值 (取时间差(今天-种植当天)-喂的次数)*2
+     *
+     * @return 延期后的成熟期
+     */
+    @Override
+    public Date getHarvestTime(String userId, Integer configLandId) {
+        ComPlayerLand comPlayerLand = comPlayerLandService.findByUserIdAndLandId(userId, configLandId);
+        Integer harvestDays = getHarvestDays(userId, configLandId);
+        return DateUtil.offset(comPlayerLand.getPlantStart(), DateField.DAY_OF_YEAR, harvestDays);
+    }
+
+    @Override
+    public Integer getHarvestDays(String userId, Integer configLandId) {
+        ComPlayerLand comPlayerLand = comPlayerLandService.findByUserIdAndLandId(userId, configLandId);
+        //实际上一共喂几次
+        long times = cultivateRepository.countComPlayerCultivateByUserIdAndLandTypeAndConfigLandId(userId, comPlayerLand.getMallType(), configLandId);
+        //从当天到现在。一共过了几天
+        long days = DateUtil.betweenDay(new Date(), comPlayerLand.getPlantStart(), true)+1;
+        //延期追加天数
+        long l = (days - times) * 2;
+        //延期后的日期=成熟期+追加天数
+        //当天也算一天。过了0点就是新的一天
+        return Convert.toInt(l, 0) + comPlayerLand.getPlantMature()-1;
+    }
+
+    private boolean exists(String userId, Integer landType, Integer configLandId, Date begin, Date end) {
+        Specification specification = new Specification<ComPlayerDisaster>() {
+            @Override
+            public Predicate toPredicate(Root<ComPlayerDisaster> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+                List<Predicate> predicates = new ArrayList<>();
+                predicates.add(criteriaBuilder.between(root.get("createTime"), begin, end));
+                predicates.add(criteriaBuilder.equal(root.get("userId"), userId));
+                predicates.add(criteriaBuilder.equal(root.get("landType"), landType));
+                predicates.add(criteriaBuilder.equal(root.get("configLandId"), configLandId));
+                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+            }
+        };
+        return cultivateRepository.count(specification) > 0;
+    }
+
+    private Result<?> ErrorResult(String msg) {
+        return Result.of(null, false, msg);
+    }
+}

+ 10 - 0
src/main/java/com/td/boss/game/complayercultivate/vo/ComPlayerCultivateSeedVo.java

@@ -0,0 +1,10 @@
+package com.td.boss.game.complayercultivate.vo;
+
+import lombok.Data;
+
+@Data
+public class ComPlayerCultivateSeedVo {
+    private Integer seedId;
+    private String seedName;
+    private double seedSNB;
+}

+ 50 - 0
src/main/java/com/td/boss/game/complayercultivate/vo/ComPlayerCultivateVo.java

@@ -0,0 +1,50 @@
+package com.td.boss.game.complayercultivate.vo;
+
+
+import lombok.Data;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author :
+ * @date : 2022-3-19
+ * @desc : 放牧养殖渔场租赁表
+ */
+@Data
+public class ComPlayerCultivateVo implements Serializable {
+
+    private Integer id;
+    /**
+     * 用户id
+     */
+    private String userId;
+    /**
+     * 土地id
+     */
+    private Integer landId;
+    /**
+     * 土地id
+     */
+    private Integer configLandId;
+    /**
+     * 需求 牧场养殖渔场,新增字段,
+     * 原有需求种地值0 牧场1 养殖2 淡水区3 海水区4
+     */
+    private Integer landType;
+    /**
+     * 土地名称
+     */
+    private Integer amount;
+    /**
+     * 是否正在使用
+     */
+    private Date activtyTime;
+    /**
+     * 土地租赁创建时间
+     */
+    private Date createTime;
+    /**
+     * 土地租赁截止日期
+     */
+    private double snb;
+}

+ 16 - 1
src/main/java/com/td/boss/game/complayergoods/controller/ComPlayerGoodsController.java

@@ -16,6 +16,7 @@ import com.td.boss.game.commallother.service.ComMallOtherService;
 import com.td.boss.game.commallother.vo.ComMallOtherVo;
 import com.td.boss.game.commallseed.service.ComMallSeedService;
 import com.td.boss.game.commallseed.vo.ComMallSeedVo;
+import com.td.boss.game.complayercultivate.serivce.ComPlayerCultivateSerivce;
 import com.td.boss.game.complayerdog.pojo.ComPlayerDog;
 import com.td.boss.game.complayerdog.service.ComPlayerDogService;
 import com.td.boss.game.complayerdog.vo.ComPlayerDogVo;
@@ -100,6 +101,9 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
     @Autowired
     private ComMallOtherService comMallOtherService;
 
+    @Autowired
+    private ComPlayerCultivateSerivce comPlayerCultivateSerivce;
+
 
     @Autowired
     private RedisLock redisLock;
@@ -231,6 +235,11 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
             return Result.of(null, false, ResultEnum.SEED_DATA_ERROR.getMessage(), ResultEnum.SEED_DATA_ERROR.getCode());
         }
 
+        //todo [牧场养殖渔场需求] 如果是养殖类的,计算延期后的成熟期
+        if (comPlayerLand.getMallType() > 0) {
+            Integer days = comPlayerCultivateSerivce.getHarvestDays(userId, comPlayerLand.getConfigLandId());
+            comMallSeedVo.setMaturity(days);
+        }
         // 收获,同时重置土地状态,先判断是否成熟
         //当前时间减去 成熟期,判断是否成熟
         Date _harvestTime = DateUtil.getNowDateMinusDay(comMallSeedVo.getMaturity());
@@ -346,7 +355,8 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
                 comPlayerGoodsSimpleVo.setPictureName(comMallSeedVo.getPicture());
                 comPlayerGoodsSimpleVo.setAmount(_amount);
                 comPlayerGoodsSimpleVo.setAmountPart(_amountPart);
-
+                //todo [牧场养殖渔场需求] 养殖收获果实时保存果实类型
+                comPlayerGoodsSimpleVo.setMallType(Convert.toInt(comMallSeedVo.getMallType()));
                 _beforeAmount = 0;
                 _beforeProfitPart = 0d;
                 _afterProfitPart = comPlayerGoodsSimpleVo.getAmountPart();
@@ -528,6 +538,10 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
         }
         // 判断是否成熟
         Date _harvestTime = DateUtil.getNowDateMinusDay(comMallSeedVo.getMaturity());
+        //todo [牧场养殖渔场需求] 如果是养殖类的,成熟期需要单独计算
+        if (otherPlayerLand.getMallType() > 0) {
+            _harvestTime = comPlayerCultivateSerivce.getHarvestTime(userId, otherPlayerLand.getConfigLandId());
+        }
         // 两个时间差, 逻辑是_harvestTime 时间慢慢接近种植时间
         long diff = otherPlayerLand.getPlantStart().getTime() - _harvestTime.getTime();
         if (diff > 0) {
@@ -583,6 +597,7 @@ public class ComPlayerGoodsController extends CommonController<ComPlayerGoodsVo,
             }
             //获取当前种植的种子
             //ComMallSeedVo comMallSeedVo = comMallSeedService.findById(otherPlayerLand.getPlantId());
+
             //todo 如果当前人员偷窃水果。记录一个信息,存储当前玩家已偷过的水果的信息
             //计算一个偷取的收获量, 租赁倍数* 租赁日期下的产量
             Integer _otherAmount = 0;

+ 5 - 1
src/main/java/com/td/boss/game/complayergoods/pojo/ComPlayerGoods.java

@@ -27,5 +27,9 @@ public class ComPlayerGoods implements Serializable {
     private Double amountPart;//部分数量,处理收取其他用户数据为主
 
     private Date createTime;
-
+    /**
+     * 需求 牧场养殖渔场,新增字段,
+     * 原有需求种地值0 牧场1 养殖2 淡水区3 海水区4
+     */
+    private Integer mallType;
 }

+ 3 - 4
src/main/java/com/td/boss/game/complayergoods/repository/ComPlayerGoodsRepository.java

@@ -1,9 +1,8 @@
 package com.td.boss.game.complayergoods.repository;
 
-import com.td.boss.common.repository.*;
+import com.td.boss.common.repository.CommonRepository;
 import com.td.boss.game.complayergoods.pojo.ComPlayerGoods;
 import com.td.boss.game.complayergoods.vo.ComPlayerGoodsTypeSumVo;
-import com.td.boss.game.complayergoods.vo.ComPlayerGoodsVo;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
 
@@ -13,12 +12,12 @@ import java.util.Optional;
 @Repository
 public interface ComPlayerGoodsRepository extends CommonRepository<ComPlayerGoods, String> {
 
-    Optional<ComPlayerGoods> findByUserIdAndGoodsIndexAndGoodsType(String userId, Integer index , Integer type);
+    Optional<ComPlayerGoods> findByUserIdAndGoodsIndexAndGoodsType(String userId, Integer index, Integer type);
 
 
     List<ComPlayerGoods> findAllByUserId(String userId);
 
-
+    Optional<ComPlayerGoods> findFirstByUserIdOrderByCreateTimeDesc(String userId);
 
     /**
      * 返回一个降序的goods_type统计

+ 6 - 7
src/main/java/com/td/boss/game/complayergoods/service/ComPlayerGoodsServiceImpl.java

@@ -1,15 +1,14 @@
 package com.td.boss.game.complayergoods.service;
 
-import com.td.boss.common.service.*;
+import com.td.boss.common.service.CommonServiceImpl;
 import com.td.boss.game.complayergoods.pojo.ComPlayerGoods;
-import com.td.boss.game.complayergoods.vo.ComPlayerGoodsSimpleVo;
+import com.td.boss.game.complayergoods.repository.ComPlayerGoodsRepository;
 import com.td.boss.game.complayergoods.vo.ComPlayerGoodsTypeSumVo;
 import com.td.boss.game.complayergoods.vo.ComPlayerGoodsVo;
-import com.td.boss.game.complayergoods.repository.ComPlayerGoodsRepository;
-import com.td.boss.util.CopyUtil;
 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;
@@ -17,7 +16,7 @@ import java.util.Optional;
 
 @Service
 @Transactional
-public class ComPlayerGoodsServiceImpl extends CommonServiceImpl<ComPlayerGoodsVo, ComPlayerGoods, String> implements ComPlayerGoodsService{
+public class ComPlayerGoodsServiceImpl extends CommonServiceImpl<ComPlayerGoodsVo, ComPlayerGoods, String> implements ComPlayerGoodsService {
 
     @PersistenceContext
     private EntityManager em;
@@ -26,8 +25,8 @@ public class ComPlayerGoodsServiceImpl extends CommonServiceImpl<ComPlayerGoodsV
 
 
     @Override
-    public ComPlayerGoods findByUserIdAndIndexAndType(String userId,Integer index, Integer type) {
-        Optional<ComPlayerGoods>  comPlayerGoods = comPlayerGoodsRepository.findByUserIdAndGoodsIndexAndGoodsType(userId,index,type);
+    public ComPlayerGoods findByUserIdAndIndexAndType(String userId, Integer index, Integer type) {
+        Optional<ComPlayerGoods> comPlayerGoods = comPlayerGoodsRepository.findByUserIdAndGoodsIndexAndGoodsType(userId, index, type);
         return comPlayerGoods.orElse(null);
     }
 

+ 7 - 2
src/main/java/com/td/boss/game/complayergoods/vo/ComPlayerGoodsVo.java

@@ -1,6 +1,7 @@
 package com.td.boss.game.complayergoods.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;
 
@@ -23,5 +24,9 @@ public class ComPlayerGoodsVo extends PageCondition implements Serializable {
     private Double amountPart;//部分数量,处理收取其他用户数据为主
 
     private Date createTime;
-
+    /**
+     * 需求 牧场养殖渔场,新增字段,
+     * 原有需求种地值0 牧场1 养殖2 淡水区3 海水区4
+     */
+    private Integer mallType;
 }

+ 63 - 11
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.convert.Convert;
+import cn.hutool.core.date.DateField;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.json.JSONUtil;
 import com.td.boss.common.controller.*;
@@ -9,6 +11,7 @@ import com.td.boss.game.comexplainland.service.ComExplainLandService;
 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.complayercultivate.serivce.ComPlayerCultivateSerivce;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisasterLog;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisasterProtected;
 import com.td.boss.game.complayerland.service.ComPlayerDisasterLogService;
@@ -62,8 +65,8 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
 
     @Autowired
     private ComPlayerDisasterProtectedService disasterProtectedService;
-
-
+    @Autowired
+    private ComPlayerCultivateSerivce comPlayerCultivateSerivce;
     @Autowired
     private ComPlayerProfitService comPlayerProfitService;
 
@@ -110,6 +113,8 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                     comExplainLandVo.setExplainDescribe("获取土地列表时:土地租赁过期回收");
                     comExplainLandVo.setCreateTime(new Date());
                     comExplainLandVo.setUpdateTime(new Date());
+                    //todo [牧场养殖渔场需求] 新加土地类型
+                    comExplainLandVo.setMallType(e.getMallType());
                     comExplainLandService.save(comExplainLandVo);
                     //过期了不做后续操作
                     return null;
@@ -132,6 +137,12 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                     //当前时间 > 种植时间+成熟期  = 说明可以收获了
                     //获取当前时间 - 植物的成熟期 = 收获时间,收获时间 >= 种植时间,即可以收获
                     Date _harvestTime = DateUtil.getNowDateMinusDay(comMallSeedVo.getMaturity());
+
+                    //todo [牧场养殖渔场需求] 如果是养殖类的,成熟期需要单独计算
+                    if (e.getMallType() > 0) {
+                        _harvestTime = comPlayerCultivateSerivce.getHarvestTime(userId, e.getConfigLandId());
+                    }
+
                     // 两个时间差, 逻辑是_harvestTime 时间慢慢接近种植时间
                     long diff = comPlayerLandAndPlantVo.getPlantStart().getTime() - _harvestTime.getTime();
                     //种植的剩余时间毫秒
@@ -140,8 +151,13 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                         //说明可以收获了
                         comPlayerLandAndPlantVo.setPlantDaysRemaining(0);
                         comPlayerLandAndPlantVo.setPlantHoursRemaining(0);
-                        //生成第一次受灾 获取用户土地 getList
-                        _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
+
+                        //todo [牧场养殖渔场需求]如果不是养殖,是传统种植才会有灾害
+                        if (e.getMallType() == 0) {
+                            //生成第一次受灾 获取用户土地 getList
+                            _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
+                        }
+
                     } else {
                         comPlayerLandAndPlantVo.setPlantDaysRemaining(DateUtil.getDays(diff).intValue());
                         comPlayerLandAndPlantVo.setPlantHoursRemaining(DateUtil.getHours(diff).intValue());
@@ -204,6 +220,11 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                     //当前时间 > 种植时间+成熟期  = 说明可以收获了
                     //获取当前时间 - 植物的成熟期 = 收获时间,收获时间 >= 种植时间,即可以收获
                     Date _harvestTime = DateUtil.getNowDateMinusDay(comMallSeedVo.getMaturity());
+                    //todo [牧场养殖渔场需求] 如果是养殖类的,成熟期需要单独计算
+                    if (e.getMallType() > 0) {
+                        _harvestTime = comPlayerCultivateSerivce.getHarvestTime(userId, e.getConfigLandId());
+                    }
+
                     // 两个时间差, 逻辑是_harvestTime 时间慢慢接近种植时间
                     long diff = comPlayerLandAndPlantVo.getPlantStart().getTime() - _harvestTime.getTime();
                     //种植的剩余时间毫秒
@@ -212,8 +233,11 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                         //说明可以收获了
                         comPlayerLandAndPlantVo.setPlantDaysRemaining(0);
                         comPlayerLandAndPlantVo.setPlantHoursRemaining(0);
-                        //生成第一次受灾 getCanStealDetailList
-                        _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
+                        //todo [牧场养殖渔场需求]如果不是养殖,是传统种植才会有灾害
+                        if (e.getMallType() == 0) {
+                            //生成第一次受灾 获取用户土地 getList
+                            _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
+                        }
 
                     } else {
                         comPlayerLandAndPlantVo.setPlantDaysRemaining(DateUtil.getDays(diff).intValue());
@@ -301,7 +325,8 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
     public Result<ComPlayerLandAndPlantVo> plantFunction(
             @RequestParam(value = "userId") String userId,
             @RequestParam(value = "landId") Integer landId,
-            @RequestParam(value = "seedId") Integer seedId) {
+            @RequestParam(value = "seedId") Integer seedId,
+            @RequestParam(value = "amount", required = false, defaultValue = "1") Integer amount) {
 
         try {
             ComPlayerLand comPlayerLand = comPlayerLandService.findByUserIdAndLandId(userId, landId);
@@ -342,6 +367,26 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
             if (comMallSeedVo == null) {
                 return Result.of(null, false, ResultEnum.SEED_DATA_ERROR.getMessage(), ResultEnum.SEED_DATA_ERROR.getCode());
             }
+
+            //todo [牧场养殖渔场需求] 判断种子类型和种子土地是否一样
+            if (comMallSeedVo.getMallType().equals(comPlayerLand.getMallType())) {
+                return Result.of(null, false, ResultEnum.LAND_NOT_LEASE.getMessage(), ResultEnum.LAND_NOT_LEASE.getCode());
+            }
+            //todo [牧场养殖渔场需求] 特有业务
+            if (comPlayerLand.getMallType() > 0) {
+                //如果剩余时间不足。不允许放养
+                if (comPlayerLand.getLeaseTime().getTime() - (cn.hutool.core.date.DateUtil.date(DateUtil.getNowDate()).offset(DateField.DAY_OF_YEAR, comMallSeedVo.getMaturity())).getTime() < 0) {
+                    return Result.of(null, false, "剩余租赁时间不足!");
+                }
+                //验证该土地最大种植数量
+                int[] amountlimit = new int[]{50, 100, 200, 200};
+                if (amount > amountlimit[comPlayerLand.getMallType() - 1]) {
+                    return Result.of(null, false, "超出最大养殖数量!");
+                }
+                //lease_multiple租赁倍数 填入实际养殖数量
+                comPlayerLand.setLeaseMultiple(amount);
+            }
+
             //todo 背包种子减去 土地当前的倍数,需要多倍播种,即消耗多个种子
             ComPlayerGoods comPlayerGoodsSimpleVo = comPlayerGoodsService.findByUserIdAndIndexAndType(userId, comMallSeedVo.getHarvestId(), 0);
             //先拿到一个 before
@@ -417,10 +462,16 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
             //返回一个租赁时间毫秒
             comPlayerLandAndPlantVo.setLeaseDaysMill(leaseDaysMill);
 
+            //todo [牧场养殖渔场需求] 如果是养殖类的,计算延期后的成熟期
+            if (comPlayerLand.getMallType() > 0) {
+                Integer days = comPlayerCultivateSerivce.getHarvestDays(userId, comPlayerLand.getConfigLandId());
+                comMallSeedVo.setMaturity(days);
+            }
             //种子时间
             //当前时间 > 种植时间+成熟期  = 说明可以收获了
             //获取当前时间 - 植物的成熟期 = 收获时间,收获时间 >= 种植时间,即可以收获
             Date _harvestTime = DateUtil.getNowDateMinusDay(comMallSeedVo.getMaturity());
+
             // 两个时间差, 逻辑是_harvestTime 时间慢慢接近种植时间
             long diff = comPlayerLandAndPlantVo.getPlantStart().getTime() - _harvestTime.getTime();
             //种植的剩余时间毫秒
@@ -430,10 +481,11 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
                 //说明可以收获了
                 comPlayerLandAndPlantVo.setPlantDaysRemaining(0);
                 comPlayerLandAndPlantVo.setPlantHoursRemaining(0);
-
-                //生成第一次受灾 plant
-                _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
-
+                //todo [牧场养殖渔场需求]如果不是养殖,是传统种植才会有灾害
+                if (comPlayerLand.getMallType() > 0) {
+                    //生成第一次受灾 plant
+                    _InitFirstDisasterProfit(comPlayerLandAndPlantVo, comMallSeedVo);
+                }
 
             } else {
                 comPlayerLandAndPlantVo.setPlantDaysRemaining(DateUtil.getDays(diff).intValue());

+ 1 - 1
src/main/java/com/td/boss/game/complayerland/pojo/ComPlayerDisasterProtected.java

@@ -20,7 +20,7 @@ public class ComPlayerDisasterProtected implements Serializable {
     private Integer dsasterType;
 
     /**
-     * 保护时间
+     * 保护时间 到期时间
      */
     private Date protectTime;
     private String userId;

+ 2 - 0
src/main/java/com/td/boss/game/complayerland/pojo/ComPlayerLand.java

@@ -49,4 +49,6 @@ public class ComPlayerLand implements Serializable {
     private Date updateTime;
 
     private Integer landLevel;//土地级别
+
+    private Integer mallType;
 }

+ 14 - 0
src/main/java/com/td/boss/game/complayerland/service/ComPlayerDisasterProtectedService.java

@@ -2,11 +2,25 @@ package com.td.boss.game.complayerland.service;
 
 import com.td.boss.common.service.CommonService;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisasterProtected;
+import com.td.boss.game.complayerland.vo.ComPlayerDisasterEnum;
 import com.td.boss.game.complayerland.vo.ComPlayerDisasterProtectedVo;
 
 import java.util.List;
 
 public interface ComPlayerDisasterProtectedService extends CommonService<ComPlayerDisasterProtectedVo, ComPlayerDisasterProtected, String> {
 
+    /**
+     * 获取购买过的历史防护
+     * @param userId
+     * @return
+     */
     List<ComPlayerDisasterProtected> getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(String userId);
+
+    /**
+     * 购买灾难防护 自动延长时间
+     * @param userId 购买者
+     * @param comPlayerDisasterEnum 购买类型
+     * @param days 购买天数
+     */
+    void append(String userId, ComPlayerDisasterEnum comPlayerDisasterEnum, Integer days);
 }

+ 30 - 0
src/main/java/com/td/boss/game/complayerland/service/ComPlayerDisasterProtectedServiceImpl.java

@@ -1,13 +1,18 @@
 package com.td.boss.game.complayerland.service;
 
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateUtil;
 import com.td.boss.common.service.CommonServiceImpl;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisasterProtected;
 import com.td.boss.game.complayerland.repository.ComPlayerDisasterProtectedRepository;
+import com.td.boss.game.complayerland.vo.ComPlayerDisasterEnum;
 import com.td.boss.game.complayerland.vo.ComPlayerDisasterProtectedVo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Comparator;
+import java.util.Date;
 import java.util.List;
 
 @Slf4j
@@ -18,10 +23,35 @@ public class ComPlayerDisasterProtectedServiceImpl extends CommonServiceImpl<Com
 
     /**
      * 按照用户编号获取 防护灾难 记录
+     *
      * @param userId
      * @return
      */
     public List<ComPlayerDisasterProtected> getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(String userId) {
         return repository.getComPlayerDisasterProtectedsByUserId(userId);
     }
+
+    /**
+     * 购买灾难防护 自动延长时间
+     * @param userId 购买者
+     * @param comPlayerDisasterEnum 购买类型
+     * @param days 购买天数
+     */
+    public void append(String userId, ComPlayerDisasterEnum comPlayerDisasterEnum, Integer days) {
+        //获取购买过的历史防护
+        List<ComPlayerDisasterProtected> protectedList = getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(userId);
+        //获取 当前类型 防护时间 倒叙第一条作为最后防御时间
+        Date protectTime = protectedList.stream()
+                .filter(a -> a.getDsasterType().equals(comPlayerDisasterEnum.getCode()))
+                .sorted(Comparator.comparing(ComPlayerDisasterProtected::getProtectTime).reversed())
+                .map(ComPlayerDisasterProtected::getProtectTime).findFirst().orElse(new Date());
+
+        ComPlayerDisasterProtectedVo comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
+        comPlayerDisasterProtected.setCreateTime(new Date());
+        comPlayerDisasterProtected.setUserId(userId);
+        comPlayerDisasterProtected.setDsasterType(comPlayerDisasterEnum.getCode());
+        comPlayerDisasterProtected.setDsasterName(comPlayerDisasterEnum.getMsg());
+        comPlayerDisasterProtected.setProtectTime(DateUtil.date(protectTime).offset(DateField.DAY_OF_YEAR, days));
+        save(comPlayerDisasterProtected);
+    }
 }

+ 5 - 0
src/main/java/com/td/boss/game/complayerland/vo/ComPlayerLandAndPlantVo.java

@@ -62,4 +62,9 @@ public class ComPlayerLandAndPlantVo implements Serializable {
     private Integer canSteal; //这个是当前用户的偷取状态
 
     private Integer landLevel;//土地级别
+    /**
+     * 需求 牧场养殖渔场,新增字段,
+     * 原有需求种地值0 牧场1 养殖2 淡水区3 海水区4
+     */
+    private Integer mallType;
 }

+ 5 - 0
src/main/java/com/td/boss/game/complayerland/vo/ComPlayerLandVo.java

@@ -46,4 +46,9 @@ public class ComPlayerLandVo extends PageCondition implements Serializable {
     private Date updateTime;
 
     private Integer landLevel;//土地级别
+    /**
+     * 需求 牧场养殖渔场,新增字段,
+     * 原有需求种地值0 牧场1 养殖2 淡水区3 海水区4
+     */
+    private Integer mallType;
 }

+ 4 - 0
src/main/java/com/td/boss/game/complayerlog/repository/ComPlayerLogRepository.java

@@ -2,8 +2,12 @@ package com.td.boss.game.complayerlog.repository;
 
 import com.td.boss.common.repository.*;
 import com.td.boss.game.complayerlog.pojo.ComPlayerLog;
+import com.td.boss.game.complayersattri.pojo.ComPlayersLucky;
 import org.springframework.stereotype.Repository;
 
+import java.util.Optional;
+
 @Repository
 public interface ComPlayerLogRepository extends CommonRepository<ComPlayerLog, Integer> {
+    Optional<ComPlayerLog> findFirstByUserIdOrderByCreateTimeDesc(String userId);
 }

+ 7 - 0
src/main/java/com/td/boss/game/complayerlog/service/ComPlayerLogService.java

@@ -5,4 +5,11 @@ import com.td.boss.game.complayerlog.pojo.ComPlayerLog;
 import com.td.boss.game.complayerlog.vo.ComPlayerLogVo;
 
 public interface ComPlayerLogService extends CommonService<ComPlayerLogVo, ComPlayerLog, Integer> {
+
+    /**
+     * 断电损耗
+     *
+     * @param userId 用户id
+     */
+    void powerLoss(String userId);
 }

+ 145 - 1
src/main/java/com/td/boss/game/complayerlog/service/ComPlayerLogServiceImpl.java

@@ -1,21 +1,165 @@
 package com.td.boss.game.complayerlog.service;
 
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.date.format.AbstractDateBasic;
+import cn.hutool.core.math.MathUtil;
+import cn.hutool.core.util.NumberUtil;
 import com.td.boss.common.service.*;
+import com.td.boss.game.complayergoods.pojo.ComPlayerGoods;
+import com.td.boss.game.complayergoods.repository.ComPlayerGoodsRepository;
 import com.td.boss.game.complayerlog.pojo.ComPlayerLog;
 import com.td.boss.game.complayerlog.vo.ComPlayerLogVo;
 import com.td.boss.game.complayerlog.repository.ComPlayerLogRepository;
+import com.td.boss.util.CopyUtil;
+import com.td.boss.util.DoubleUtil;
+import com.td.boss.util.UUIDUtil;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.jdbc.metadata.OracleUcpDataSourcePoolMetadata;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 @Transactional
-public class ComPlayerLogServiceImpl extends CommonServiceImpl<ComPlayerLogVo, ComPlayerLog, Integer> implements ComPlayerLogService{
+public class ComPlayerLogServiceImpl extends CommonServiceImpl<ComPlayerLogVo, ComPlayerLog, Integer> implements ComPlayerLogService {
 
     @PersistenceContext
     private EntityManager em;
     @Autowired
     private ComPlayerLogRepository comPlayerLogRepository;
+    @Autowired
+    private ComPlayerGoodsRepository comPlayerGoodsRepository;
+
+    /**
+     * 7天没有操作仓库进入断电损耗期,最多持续8天
+     * 1.查询5种操作最后一次操作时间
+     * - 购买种子
+     * - 种植
+     * - 收取果实
+     * - 偷取果实
+     * - 卖出果实
+     * 2.计算并执行本次损耗
+     *
+     * @param userId 用户id
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void powerLoss(String userId) {
+        // 查询 [种植] [收取果实] [偷取果实] [卖出果实] 最后操作时间
+        ComPlayerLog comPlayerLog = comPlayerLogRepository.findFirstByUserIdOrderByCreateTimeDesc(userId).orElse(null);
+        // 查询 [购买种子] 最后操作时间,这里查询这张表是因为购买种子不会往 [com_player_log] 表写数据
+        ComPlayerGoods comPlayerGoods = comPlayerGoodsRepository.findFirstByUserIdOrderByCreateTimeDesc(userId).orElse(null);
+        // 这是个空号.
+        if (comPlayerLog == null && comPlayerGoods == null) {
+            return;
+        }
+        // 计算最后操作时间
+        Date lastOperationTime = lastOperationTime(comPlayerLog, comPlayerGoods);
+        System.out.println("最后操作时间:" + dateFormat(lastOperationTime));
+        // 计算服务器时间与最后操作时间差
+        Date serverDate = new Date();
+        long dayDiff = DateUtil.betweenDay(serverDate, lastOperationTime, false);
+        System.out.println("与服务器时间相差:" + dayDiff + "天");
+        // 7天未操作 并且 最多持续8天.
+        if (dayDiff < 7) {
+            System.out.println("未到7天不损耗");
+            return;
+        }
+        dayDiff = dayDiff > 14 ? 14 : dayDiff;
+        dayDiff = Math.abs(14 - 8 - dayDiff);
+        System.out.println("实际断电损耗:" + dayDiff + "天");
+
+        List<ComPlayerGoods> fruitList = comPlayerGoodsRepository.findAllByUserId(userId).stream().filter(a -> a.getGoodsType().equals(1)).collect(Collectors.toList());
+        if (fruitList.size() == 0) {
+            System.out.println("仓库无果实不损耗");
+            return;
+        }
+        // 批量更新仓库果实量
+        List<ComPlayerGoods> playerGoodsList = new ArrayList<>();
+        // 写入明细
+        List<ComPlayerLog> playerLogList = new ArrayList<>();
+
+        for (ComPlayerGoods goods : fruitList) {
+            // 操作仓库
+            int goodsBeforeAmount = goods.getAmount();
+            double goodsBeforePart = goods.getAmountPart();
+            //
+            double amount = (goodsBeforeAmount + goodsBeforePart) * (1 - NumberUtil.div(dayDiff, 100));
+            goods.setAmount((int) Math.floor(amount));
+            goods.setAmountPart(DoubleUtil.sub(amount, Math.floor(amount)));
+            goods.setCreateTime(serverDate);
+            playerGoodsList.add(goods);
+
+            // 写入明细
+            ComPlayerLog playerLog = new ComPlayerLog();
+            playerLog.setId(UUIDUtil.getUUID());
+            playerLog.setUserId(userId);
+            // 操作目标id,比如进入背包的是收获时候操作:水果
+            playerLog.setTId(goods.getGoodsIndex());
+            playerLog.setTName(goods.getName());
+            playerLog.setTPart(0d);
+            playerLog.setTAmount(0);
+            // 1=果实
+            playerLog.setTType(1);
+            playerLog.setBeforeAmount(goodsBeforeAmount);
+            playerLog.setBeforePart(goodsBeforePart);
+            // 交易后的数据
+            playerLog.setAfterAmount(goods.getAmount());
+            playerLog.setAfterPart(goods.getAmountPart());
+            // 收获时候,会有一个倍数
+            playerLog.setLMultiple(0);
+            // 损失
+            playerLog.setTLoss((goodsBeforeAmount + goodsBeforePart) * NumberUtil.div(dayDiff, 100));
+            playerLog.setCreateTime(serverDate);
+            playerLogList.add(playerLog);
+        }
+        comPlayerGoodsRepository.saveAll(playerGoodsList);
+        comPlayerLogRepository.saveAll(playerLogList);
+
+        System.out.println("损耗完成");
+    }
+
+    /**
+     * 获取最后一次操作时间
+     *
+     * @param comPlayerLog   交易日志
+     * @param comPlayerGoods 最后购买种子时间
+     * @return {@link Date}
+     */
+    private Date lastOperationTime(ComPlayerLog comPlayerLog, ComPlayerGoods comPlayerGoods) {
+        if (comPlayerLog == null) {
+            System.out.println("[comPlayerLog]表无记录. 最后操作时间:" + dateFormat(comPlayerGoods.getCreateTime()));
+            return comPlayerGoods.getCreateTime();
+        }
+        if (comPlayerGoods == null) {
+            System.out.println("[comPlayerGoods]表无记录. 最后操作时间:" + dateFormat(comPlayerLog.getCreateTime()));
+            return comPlayerLog.getCreateTime();
+        }
+
+        System.out.println("[comPlayerLog]表最后操作日期:" + dateFormat(comPlayerLog.getCreateTime()));
+        System.out.println("[comPlayerGoods]表最后操作日期:" + dateFormat(comPlayerGoods.getCreateTime()));
+        if (comPlayerGoods.getCreateTime().before(comPlayerLog.getCreateTime())) {
+            return comPlayerLog.getCreateTime();
+        } else {
+            return comPlayerGoods.getCreateTime();
+        }
+    }
+
+    /**
+     * 日期格式化
+     *
+     * @param date 日期
+     * @return {@link String}
+     */
+    private String dateFormat(Date date) {
+        return DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
+    }
 }

+ 2 - 2
src/main/java/com/td/boss/game/complayersattri/controller/ComPlayersLuckyController.java

@@ -22,8 +22,8 @@ public class ComPlayersLuckyController {
      * @return
      */
     @GetMapping("/tools")
-    public Result<?> getLandTools() {
-        return Result.of(service.getLandTools(), true, "查询成功");
+    public Result<?> getLandTools(String userId) {
+        return Result.of(service.getLandTools(userId), true, "查询成功");
     }
 
     /**

+ 4 - 1
src/main/java/com/td/boss/game/complayersattri/repository/ComPlayersLuckyRepository.java

@@ -4,9 +4,12 @@ import com.td.boss.common.repository.CommonRepository;
 import com.td.boss.game.complayersattri.pojo.ComPlayersLucky;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
 import java.util.Optional;
 
 @Repository
 public interface ComPlayersLuckyRepository extends CommonRepository<ComPlayersLucky, Integer> {
-    Optional<ComPlayersLucky> findFirstByUserIdOrderByCreateTimeDesc(String userId);
+    List<ComPlayersLucky> findAllByUserId(String userId);
+
+    Optional<ComPlayersLucky> findFirstByUserIdAndToolsIdOrderByCreateTimeDesc(String userId, Integer toolsId);
 }

+ 1 - 1
src/main/java/com/td/boss/game/complayersattri/service/ComPlayersLuckyService.java

@@ -43,7 +43,7 @@ public interface ComPlayersLuckyService extends CommonService<ComPlayersLuckyVo,
      *
      * @return
      */
-    List<ComPlayersLuckyToolsVo> getLandTools();
+    List<ComPlayersLuckyToolsVo> getLandTools(String userId);
 
     /**
      * 获取土地升级列表

+ 24 - 5
src/main/java/com/td/boss/game/complayersattri/service/ComPlayersLuckyServiceImpl.java

@@ -34,10 +34,10 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 import java.util.*;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -73,7 +73,7 @@ public class ComPlayersLuckyServiceImpl extends CommonServiceImpl<ComPlayersLuck
     @Transactional(rollbackFor = Exception.class)
     public Result useLuckyTools(String userId, Integer toolId, Integer landId) {
         //验证工具是否存在
-        ComPlayersLuckyToolsVo tools = getLandTools().stream().filter(a -> a.getId().equals(toolId)).findFirst().orElse(null);
+        ComPlayersLuckyToolsVo tools = getLandTools(userId).stream().filter(a -> a.getId().equals(toolId)).findFirst().orElse(null);
         if (tools == null || tools.isEnable() == false) {
             return Result.of(null, false, "无效工具");
         }
@@ -98,7 +98,7 @@ public class ComPlayersLuckyServiceImpl extends CommonServiceImpl<ComPlayersLuck
             return Result.of(null, false, ResultEnum.LAND_USE_TOOL.getMessage(), ResultEnum.LAND_USE_TOOL.getCode());
         }
         //验证工具是否可用:每隔一段时间才可使用
-        Optional<ComPlayersLucky> lastComPlayersLuckyLog = repository.findFirstByUserIdOrderByCreateTimeDesc(userId);
+        Optional<ComPlayersLucky> lastComPlayersLuckyLog = repository.findFirstByUserIdAndToolsIdOrderByCreateTimeDesc(userId, toolId);
         if (lastComPlayersLuckyLog.isPresent()) {
             DateTime nextTime = DateUtil.offset(lastComPlayersLuckyLog.get().getCreateTime(), DateField.HOUR_OF_DAY, tools.getUseHour());
             if (nextTime.isAfter(new Date())) {
@@ -319,9 +319,28 @@ public class ComPlayersLuckyServiceImpl extends CommonServiceImpl<ComPlayersLuck
      * @return
      */
     @Override
-    public List<ComPlayersLuckyToolsVo> getLandTools() {
+    public List<ComPlayersLuckyToolsVo> getLandTools(String userId) {
         String land_tools = comConfigService.selectByKey(toolskey);
-        return JSONUtil.toList(land_tools, ComPlayersLuckyToolsVo.class);
+        List<ComPlayersLuckyToolsVo> comPlayersLuckyToolsVos = JSONUtil.toList(land_tools, ComPlayersLuckyToolsVo.class).stream().filter(a->a.isEnable()).collect(Collectors.toList());
+        List<ComPlayersLucky> ComPlayersLuckyList = repository.findAllByUserId(userId);
+
+        for (ComPlayersLuckyToolsVo comPlayersLuckyToolsVo : comPlayersLuckyToolsVos) {
+            long canUseTime = 0;
+            //获取使用工具历史中最后一次记录
+            ComPlayersLucky firstByUserIdOrderByCreateTimeDesc = ComPlayersLuckyList.stream()
+                    .filter(a -> comPlayersLuckyToolsVo.getId().equals(a.getToolsId()))
+                    .sorted(Comparator.comparing(ComPlayersLucky::getCreateTime).reversed())
+                    .findFirst().orElse(null);
+
+            if (firstByUserIdOrderByCreateTimeDesc != null) {
+                DateTime offset = DateUtil.offset(firstByUserIdOrderByCreateTimeDesc.getCreateTime(), DateField.HOUR, comPlayersLuckyToolsVo.getUseHour());
+                if (offset.after(new Date())) {
+                    canUseTime = DateUtil.betweenMs(offset, new Date());
+                }
+            }
+            comPlayersLuckyToolsVo.setActivtyTime(canUseTime);
+        }
+        return comPlayersLuckyToolsVos;
     }
 
     /**

+ 2 - 0
src/main/java/com/td/boss/game/complayersattri/vo/ComPlayersLuckyToolsVo.java

@@ -24,4 +24,6 @@ public class ComPlayersLuckyToolsVo {
      */
     private Date createTime;
     private boolean isEnable;
+
+    private Long activtyTime;
 }

+ 76 - 0
src/main/java/com/td/boss/util/DappUtil.java

@@ -124,4 +124,80 @@ public class DappUtil {
         }
     }
 
+    /**
+     * 获取用户直推且有消费土地的人数量(模块7: 放牧与养殖)
+     * {
+     *     "code": 200,
+     *     "msg": "success",
+     *     "data": 0
+     * }
+     */
+    public static Integer getChildrenBuyLandCount(String userId){
+
+        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
+        form.add("id", userId);
+        //验证地址
+        String DAppChildrenCountOnlineUrl = "https://yt.landownership.live/api/game/getChildrenBuyLandCount";
+        String DAppChildrenCountTestUrl = "https://wp.landownership.live/api/game/getChildrenBuyLandCount";
+        String DAppUrl = DappUtil.getEnv().equals("prod") ? DAppChildrenCountOnlineUrl : DAppChildrenCountTestUrl;
+        log.info("获取用户直推且有消费土地的人数量:" + DAppUrl);
+        try {
+            RestTemplate restTemplate = new RestTemplate();
+            HttpHeaders headers = new HttpHeaders();
+            //设置content-type
+            MediaType type = MediaType.parseMediaType("multipart/form-data");
+            headers.setContentType(type);
+            // 以表单的方式提交
+            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+            //用HttpEntity封装整个请求报文
+
+            HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(form, headers);
+            Map response = restTemplate.postForObject(DAppUrl, files, Map.class);
+            log.info("response={}", response);
+            return (Integer) response.get("data");
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            return 0;
+            //e.printStackTrace();
+        }
+    }
+
+    /**
+     * 获取用户直推下级的消费土地的总cnt数额(模块9: 积分兑换种子)
+     * {
+     *     "code": 200,
+     *     "msg": "success",
+     *     "data": 0
+     * }
+     */
+    public static Integer getChildrenBuyLandAmount(String userId){
+
+        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
+        form.add("id", userId);
+        //验证地址
+        String DAppChildrenCountOnlineUrl = "https://yt.landownership.live/api/game/getChildrenBuyLandAmount";
+        String DAppChildrenCountTestUrl = "https://wp.landownership.live/api/game/getChildrenBuyLandAmount";
+        String DAppUrl = DappUtil.getEnv().equals("prod") ? DAppChildrenCountOnlineUrl : DAppChildrenCountTestUrl;
+        log.info("获取用户直推下级的消费土地的总cnt数额:" + DAppUrl);
+        try {
+            RestTemplate restTemplate = new RestTemplate();
+            HttpHeaders headers = new HttpHeaders();
+            //设置content-type
+            MediaType type = MediaType.parseMediaType("multipart/form-data");
+            headers.setContentType(type);
+            // 以表单的方式提交
+            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+            //用HttpEntity封装整个请求报文
+
+            HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(form, headers);
+            Map response = restTemplate.postForObject(DAppUrl, files, Map.class);
+            log.info("response={}", response);
+            return (Integer) response.get("data");
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            return 0;
+            //e.printStackTrace();
+        }
+    }
+
 }

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

@@ -99,4 +99,12 @@ public class RedisData {
     public static int getUserApplyTimeout () {
         return USER_APPLY_TIMEOUT;
     }
+
+    /**
+     * 5s 养殖模块
+     */
+    private static final int PLAYER_CULTIVATE_BUYFOOD_TIMEOUT = 5 * 1000; //超时时间 5s
+    public static int getPlayerCultivateBuyFoodTimeout() {
+        return PLAYER_CULTIVATE_BUYFOOD_TIMEOUT;
+    }
 }

+ 12 - 4
src/main/resources/application.yml

@@ -50,9 +50,9 @@ spring:
 
   #数据库配置
   datasource:
-    url: jdbc:mysql://42.192.165.168:3306/dragon_town?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=utf-8
+    url: jdbc:mysql://123.57.252.53:6688/dragon_town_320?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=utf-8
     username: root #dragon_town #root
-    password: 9ab8fad748dead93 #FzCebFq6Xy0CDTXJ #zddeiBmp8c5T6TR6
+    password: 7a829d0ecde828 #FzCebFq6Xy0CDTXJ #zddeiBmp8c5T6TR6
     driver-class-name: com.mysql.cj.jdbc.Driver
     hikari:
       minimum-idle: 5
@@ -64,14 +64,22 @@ spring:
       connection-test-query: SELECT 1
 
   redis:
-    host: 42.192.165.168 #123.57.252.53
+    host: 123.57.252.53 #123.57.252.53
     port: 6379
-    password: abc123456abc-test
+    password: heihei
     data: #工程中只是把redis作为缓存,并未使用redis作为数据持久化存储源repository使用.
       redis:
         repositories:
           enabled: false
 
+  # smart redisson
+  smart-redisson:
+    database: 12
+    server-address: 123.57.252.53:6379
+    password: heihei
+
+
+
 #是否需要输入验证码
 captcha:
   enable: false

+ 128 - 0
src/test/java/com/td/boss/ComPlayerCultivateTests.java

@@ -0,0 +1,128 @@
+package com.td.boss;
+
+import cn.hutool.json.JSONUtil;
+import com.td.boss.common.pojo.Result;
+import com.td.boss.game.comconfigland.service.ComConfigLandService;
+import com.td.boss.game.comconfigland.vo.ComConfigLandVo;
+import com.td.boss.game.commallfood.controller.ComMallFoodController;
+import com.td.boss.game.commallfood.vo.ComMallFoodSimpleVo;
+import com.td.boss.game.commallseed.controller.ComMallSeedController;
+import com.td.boss.game.commallseed.vo.ComMallSeedVo;
+import com.td.boss.game.complayercultivate.controller.ComPlayerCultivateController;
+import com.td.boss.game.complayercultivate.pojo.ComPlayerCultivate;
+import com.td.boss.game.complayercultivate.serivce.ComPlayerCultivateSerivce;
+import com.td.boss.game.complayerdog.controller.ComPlayerDogController;
+import com.td.boss.game.complayergoods.controller.ComPlayerGoodsController;
+import com.td.boss.game.complayerland.controller.ComPlayerLandController;
+import com.td.boss.game.complayerland.vo.ComPlayerLandAndPlantVo;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+import java.util.Map;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class ComPlayerCultivateTests {
+    private String userId = "1002";
+    private int configlandid = 25;
+    @Autowired
+    private ComPlayerLandController comPlayerLandController;
+    @Autowired
+    private ComMallSeedController comMallSeedController;
+    @Autowired
+    private ComPlayerGoodsController comPlayerGoodsController;
+    @Autowired
+    private ComConfigLandService comConfigLandService;
+    @Autowired
+    private ComPlayerCultivateController comPlayerCultivateController;
+    @Autowired
+    private ComPlayerCultivateSerivce comPlayerCultivateSerivce;
+
+    //需要测试 多天上线以后情况
+
+    //解锁某个土地 【新增功能】【测试完】
+    @Test
+    public void buyLand() {
+        Result<?> comPlayerLandAndPlantVoResult = comPlayerCultivateController.payLand(userId, 26);
+        print(comPlayerLandAndPlantVoResult);
+    }
+
+    //种种子选择放养数量 【修改完毕】【测试完】
+    @Test
+    public void plantFunction() {
+        //测试重复种植
+//        print(comPlayerLandController.plantFunction(userId, configlandid, 11, 1000));
+        //测试种植数量大于土地最大承受
+//        print(comPlayerLandController.plantFunction(userId, 26, 11, 1000));
+        //测试种植 包里没有的种子
+//        print(comPlayerLandController.plantFunction(userId, 26, 11, 20));
+        //测试种子数量不足
+//        print(comPlayerLandController.plantFunction(userId, 26, 10, 20));
+        print(comPlayerLandController.plantFunction(userId, 26, 10, 2));
+    }
+
+    //喂养就是购买粮食 【修改完毕】【测试完】
+    @Test
+    public void buyFood() {
+        //需要计算一下 有多少只动物。要喂多少天。就算一下一共花多少钱。还得插一个喂养明细。
+//       print( comPlayerDogController.addFoodFunction(userId,6,1));
+//       print( comPlayerCultivateSerivce.buyFood(userId, configlandid));
+//       print( comPlayerCultivateSerivce.buyFood(userId, 26));
+        print(comPlayerCultivateSerivce.buyFood(userId, 26));
+    }
+
+
+    //获取某个人所有土地 【修改完毕】【测试完】,需要查询喂养记录,重新计算成熟日期
+    @Test
+    public void getLandByUserId() {
+        Result<List<ComPlayerLandAndPlantVo>> landFunction = comPlayerLandController.getLandFunction(userId, null);
+        print(landFunction);
+    }
+
+    //偷果实 【修改完毕 待测试】
+    @Test
+    public void stealFruitFunction() {
+        comPlayerGoodsController.stealFruitFunction(userId, userId, configlandid);
+    }
+    //收货,成熟 【修改完毕 测试完】,一天不喂延长2天
+    @Test
+    public void addFruitFunction() {
+        comPlayerGoodsController.addFruitFunction(userId, 26);
+    }
+
+
+    //获取所有土地 【一点没变】【测试完】
+    @Test
+    public void getLands() {
+        Result<List<ComConfigLandVo>> list = comConfigLandService.list(new ComConfigLandVo());
+        print(list);
+    }
+
+    //获取所有种子列表 【一点没变】【测试完】
+    @Test
+    public void getSeed() {
+        Result<List<ComMallSeedVo>> snbFunction = comMallSeedController.getSNBFunction(userId);
+        print(snbFunction);
+    }
+
+    //购买种子【一点没变】【测试完】这块逻辑是只要钱够,种子id对就没问题
+    @Test
+    public void buySeeds() {
+        comMallSeedController.snbBuySeedsFunction(userId, 200, 10);
+    }
+
+    //购买种子,进入仓库【一点没变】【测试完】
+    @Test
+    public void getGood() {
+        Result<Map> seedAndFruitFunction = comPlayerGoodsController.getSeedAndFruitFunction(userId);
+        print(seedAndFruitFunction);
+    }
+
+    private void print(Result result) {
+        System.out.println(JSONUtil.toJsonStr(result.getData()));
+    }
+}

+ 6 - 15
src/test/java/com/td/boss/ComPlayerDisasterLogTests.java

@@ -37,21 +37,13 @@ class ComPlayerDisasterLogTests {
      */
     @Test
     void playerAddProtected() {
-        ComPlayerDisasterProtectedVo comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
-        comPlayerDisasterProtected.setCreateTime(new Date());
-        comPlayerDisasterProtected.setUserId(userId);
-        comPlayerDisasterProtected.setDsasterType(ComPlayerDisasterEnum.ziran.getCode());
-        comPlayerDisasterProtected.setDsasterName(ComPlayerDisasterEnum.ziran.getMsg());
-        comPlayerDisasterProtected.setProtectTime(DateUtil.date(new Date()).offset(DateField.DAY_OF_WEEK, 30));
-        comPlayerDisasterProtectedService.save(comPlayerDisasterProtected);
+        comPlayerDisasterProtectedService.append(userId,ComPlayerDisasterEnum.ziran,30);
 
-        comPlayerDisasterProtected = new ComPlayerDisasterProtectedVo();
-        comPlayerDisasterProtected.setCreateTime(new Date());
-        comPlayerDisasterProtected.setUserId(userId);
-        comPlayerDisasterProtected.setDsasterType(ComPlayerDisasterEnum.yeshou.getCode());
-        comPlayerDisasterProtected.setDsasterName(ComPlayerDisasterEnum.yeshou.getMsg());
-        comPlayerDisasterProtected.setProtectTime(DateUtil.date(new Date()).offset(DateField.DAY_OF_WEEK, -30));
-        comPlayerDisasterProtectedService.save(comPlayerDisasterProtected);
+        comPlayerDisasterProtectedService.append(userId,ComPlayerDisasterEnum.yeshou,30);
+
+        comPlayerDisasterProtectedService.append("1003",ComPlayerDisasterEnum.ziran,30);
+
+        comPlayerDisasterProtectedService.append("1003",ComPlayerDisasterEnum.yeshou,30);
     }
 
     /**
@@ -104,6 +96,5 @@ class ComPlayerDisasterLogTests {
 
         String json = JSONUtil.toJsonStr(comCntToSnbService.receiveByUserId("13"));
         System.out.println(json);
-
     }
 }

+ 21 - 0
src/test/java/com/td/boss/ComPlayerLogTests.java

@@ -0,0 +1,21 @@
+package com.td.boss;
+
+import com.td.boss.game.complayerlog.service.ComPlayerLogServiceImpl;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class ComPlayerLogTests {
+
+    @Autowired
+    private ComPlayerLogServiceImpl comPlayerLogService;
+
+    @Test
+    public void powerLoss() {
+        comPlayerLogService.powerLoss("1123");
+    }
+}

+ 15 - 1
src/test/java/com/td/boss/ComPlayerLuckyTests.java

@@ -2,7 +2,9 @@ package com.td.boss;
 
 import cn.hutool.json.JSONUtil;
 import com.td.boss.common.pojo.Result;
+import com.td.boss.common.service.ComConfigService;
 import com.td.boss.game.complayersattri.controller.ComPlayersLuckyController;
+import com.td.boss.game.complayersattri.vo.ComPlayersLuckyLandLevelUpVo;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -10,6 +12,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
+import java.util.List;
+
 /**
  * 工具模块
  */
@@ -23,9 +27,12 @@ public class ComPlayerLuckyTests {
     @Autowired
     ComPlayersLuckyController comPlayersLuckyController;
 
+    @Autowired
+    private ComConfigService configService;
+
     @Test
     public void getLandTools() {
-        Result<?> landTools = comPlayersLuckyController.getLandTools();
+        Result<?> landTools = comPlayersLuckyController.getLandTools(userId);
         System.out.println(JSONUtil.toJsonStr(landTools));
     }
 
@@ -100,4 +107,11 @@ public class ComPlayerLuckyTests {
         Result<?> result = comPlayersLuckyController.toSNB(userId, 50 * 20);
         System.out.println(JSONUtil.toJsonStr(result));
     }
+
+    @Test
+    public void getConfig(){
+        List<ComPlayersLuckyLandLevelUpVo> list = configService.selectLandLevel();
+        String json = JSONUtil.toJsonStr(list);
+        System.out.println(json);
+    }
 }