Kaynağa Gözat

模块4:自然灾害与防护包功能模块

xst 4 yıl önce
ebeveyn
işleme
bb54fc00ef

+ 23 - 1
pom.xml

@@ -22,15 +22,32 @@
             <artifactId>spring-boot-starter</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.3.2</version>
+        </dependency>
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
-            <optional>true</optional>
+            <version>1.18.20</version>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.vaadin.external.google</groupId>
+                    <artifactId>android-json</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
         </dependency>
 		
 		        <!--热部署工具dev-tools-->
@@ -135,6 +152,11 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.7.22</version>
+        </dependency>
 
     </dependencies>
 

+ 46 - 0
src/main/java/com/td/boss/game/complayerdog/pojo/Disaster.java

@@ -0,0 +1,46 @@
+package com.td.boss.game.complayerdog.pojo;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 自然灾害与防护包功能模块
+ */
+@Entity
+@Table(name = "com_player_dsaster")
+@Data
+public class Disaster implements Serializable {
+    @Id
+    @GeneratedValue(strategy= GenerationType.IDENTITY)
+    private long id;
+    /**
+     * 灾难名称
+     */
+    private String name;
+    private Integer type;
+    /**
+     * 伤害 会减产50%
+     */
+    private int damage;
+
+    /**
+     * 防御 90%概率防御灾难
+     */
+    private double defend;
+
+    /**
+     * 防护截止时间
+     */
+    private Date buyProtectedTime;
+
+    /**
+     * 本次灾难是否激活防护
+     */
+    private boolean activityProtect;
+    private String userId;
+    private Date createTime;
+    private Date updateTime;
+}

+ 10 - 0
src/main/java/com/td/boss/game/complayerdog/repository/ComPlayerDisasterRepository.java

@@ -0,0 +1,10 @@
+package com.td.boss.game.complayerdog.repository;
+
+import com.td.boss.common.repository.CommonRepository;
+import com.td.boss.game.complayerdog.pojo.Disaster;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ComPlayerDisasterRepository extends CommonRepository<Disaster, String> {
+
+}

+ 9 - 0
src/main/java/com/td/boss/game/complayerdog/service/ComPlayerDisasterService.java

@@ -0,0 +1,9 @@
+package com.td.boss.game.complayerdog.service;
+
+import com.td.boss.common.service.CommonService;
+import com.td.boss.game.complayerdog.pojo.Disaster;
+import com.td.boss.game.complayerdog.vo.DisasterVo;
+
+public interface ComPlayerDisasterService  extends CommonService<DisasterVo, Disaster, String> {
+      DisasterVo getAttack(String userId);
+}

+ 158 - 0
src/main/java/com/td/boss/game/complayerdog/service/ComPlayerDisasterServiceImpl.java

@@ -0,0 +1,158 @@
+package com.td.boss.game.complayerdog.service;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.json.JSONUtil;
+import com.td.boss.common.pojo.Result;
+import com.td.boss.common.service.CommonServiceImpl;
+import com.td.boss.game.complayerdog.pojo.Disaster;
+import com.td.boss.game.complayerdog.repository.ComPlayerDisasterRepository;
+import com.td.boss.game.complayerdog.vo.DisasterVo;
+import com.td.boss.util.DappUtil;
+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;
+import javax.persistence.criteria.Root;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+@Transactional
+public class ComPlayerDisasterServiceImpl extends CommonServiceImpl<DisasterVo, Disaster, String> implements ComPlayerDisasterService {
+    @Autowired
+    private ComPlayerDisasterRepository comPlayerDisasterRepository;
+
+    @Override
+    public DisasterVo getAttack(String userId) {
+        //todo 比如1个月不上线怎么办
+        //todo 防护模式未实现
+        log.info("灾难模式");
+        DisasterVo disasterVo = null;
+        //如果本周内还有灾难
+        if (getDisasterNum(userId) > 0) {
+            //随机获取一种灾难方式灾难对象
+            disasterVo = getDisasterList(userId).get(RandomUtil.randomInt(0, 1));
+            //查看该灾难是否有防护,如果有防护需要按照防护几率计算是否防御住灾害了
+            if (disasterVo.getIsBuyProtected()) {
+                double v = RandomUtil.randomDouble(0, 1);
+                log.info("灾难几率:{}", v);
+                if (v > Convert.toDouble("0.1")) {
+                    disasterVo.setActivityProtect(true);
+                } else {
+                    disasterVo.setActivityProtect(false);
+                }
+            }
+            log.info("灾难结果:{}", JSONUtil.toJsonStr(disasterVo));
+            Disaster disaster = new Disaster();
+            BeanUtil.copyProperties(disasterVo, disaster);
+            //入库
+            //todo 应该还有个减产的接口
+            comPlayerDisasterRepository.save(disaster);
+        }
+        log.info("灾难结果:{}", "本周无灾难了");
+        return disasterVo;
+    }
+
+    private List<DisasterVo> getDisasterList(String userId) {
+        //todo 这里需要优化使用枚举获取
+        //查询有效防护时间
+        Date ziran_protected = cn.hutool.core.date.DateUtil.parse("2022-03-30");
+        Date yeshow_protected = cn.hutool.core.date.DateUtil.parse("2022-03-30");
+
+        List<DisasterVo> disasterList = new ArrayList<>();
+        disasterList.add(new DisasterVo("自然灾害", ziran_protected));
+        disasterList.add(new DisasterVo("野兽", yeshow_protected));
+
+        disasterList.forEach(a -> {
+            a.setDamage(50);
+            a.setDefend(90);
+            a.setUserId(userId);
+            a.setCreateTime(new Date());
+        });
+
+        log.info("灾难列表:{}", JSONUtil.toJsonStr(disasterList));
+        return disasterList;
+    }
+
+    /**
+     * 获得本周剩余灾难数量
+     *
+     * @param userId
+     * @return
+     */
+    private int getDisasterNum(String userId) {
+        //读取接口 获取 那种情况 这个接口实际是返回的上周数据。所以什么时候啦都不会变。
+        //本周开始时间为周日到周六,期间获取的不会变化,这周获取的是上周的数据
+        Map<String, Object> cntPayAndSwapAmount = DappUtil.getCntPayAndSwapAmount(userId);
+        log.info("接口返回支付兑换结果:{}", JSONUtil.toJsonStr(cntPayAndSwapAmount));
+        // 总支付cnt
+        Double pay_amount = Convert.toDouble(cntPayAndSwapAmount.get("pay_amount"));
+        // 总兑换cnt
+        Double swap_amount = Convert.toDouble(cntPayAndSwapAmount.get("swap_amount"));
+
+        //本周内已出现灾难次数
+        long countByWeek = getCountByWeek(userId);
+        //本周内应该出现的灾难次数
+        int disasterTimes = getDisasterTimes(pay_amount, swap_amount);
+        log.info("本周内应该出现的灾难次数:{},本周内已出现灾难次数:{}", disasterTimes, countByWeek);
+        return disasterTimes - Convert.toInt(countByWeek);
+    }
+
+    /**
+     * 本周内已出现灾难次数
+     *
+     * @param userId
+     * @return
+     */
+    public long getCountByWeek(String userId) {
+        Date now = new Date();
+        DateTime begin = DateUtil.beginOfWeek(now);
+        DateTime end = DateUtil.endOfWeek(now);
+        Specification querySpecifi = new Specification<Disaster>() {
+            @Override
+            public Predicate toPredicate(Root<Disaster> 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));
+                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+            }
+        };
+        long count = comPlayerDisasterRepository.count(querySpecifi);
+        log.info("count:{}", count);
+        return count;
+    }
+
+    /**
+     * a)当某个村长所属农场的支出小于等于收入30%时,按照正常频率,每周出现1次
+     * b)当某个村长所属农场的支出大于收入30%时,每周出现2次
+     * c)当某个村长所属农场的支出大于收入50%时,每周出现4次
+     * d)当某个村长所属农场的支出大于收入80%时,每周出现6次
+     * 支出对应pay_amount,收入对应swap_amount
+     *
+     * @param pay_amount  支出对应
+     * @param swap_amount 收入对应
+     */
+    private int getDisasterTimes(Double pay_amount, Double swap_amount) {
+        if (pay_amount > swap_amount * 0.8) {
+            return 6;
+        } else if (pay_amount > swap_amount * 0.5) {
+            return 4;
+        } else if (pay_amount > swap_amount * 0.3) {
+            return 2;
+        } else {
+            return 1;
+        }
+    }
+}

+ 56 - 0
src/main/java/com/td/boss/game/complayerdog/vo/DisasterVo.java

@@ -0,0 +1,56 @@
+package com.td.boss.game.complayerdog.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 灾难
+ */
+@Data
+public class DisasterVo implements Serializable {
+    public DisasterVo() {
+    }
+
+    public DisasterVo(String name,Date buyProtectedTime) {
+        this.name = name;
+        this.buyProtectedTime=buyProtectedTime;
+    }
+
+    /**
+     * 灾难名称
+     */
+    private String name;
+    /**
+     * 伤害 会减产50%
+     */
+    private int damage;
+
+    /**
+     * 防御 90%概率防御灾难
+     */
+    private int defend;
+
+    /**
+     * 防护截止时间
+     */
+    private Date buyProtectedTime;
+
+    /**
+     * 本次灾难是否激活防护
+     */
+    private boolean activityProtect;
+
+    private String userId;
+
+    private Date createTime;
+    /**
+     * 是否购买防护并且没到期
+     *
+     * @return
+     */
+    public boolean getIsBuyProtected() {
+        return new Date().before(buyProtectedTime);
+    }
+}

+ 27 - 6
src/main/java/com/td/boss/game/complayerland/controller/ComPlayerLandController.java

@@ -1,5 +1,11 @@
 package com.td.boss.game.complayerland.controller;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.json.JSON;
+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;
@@ -7,6 +13,8 @@ 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.complayerdog.service.ComPlayerDisasterService;
+import com.td.boss.game.complayerdog.vo.DisasterVo;
 import com.td.boss.game.complayergoods.pojo.ComPlayerGoods;
 import com.td.boss.game.complayergoods.service.ComPlayerGoodsService;
 import com.td.boss.game.complayergoods.vo.ComPlayerGoodsVo;
@@ -19,10 +27,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.util.CopyUtil;
-import com.td.boss.util.DateUtil;
-import com.td.boss.util.UUIDUtil;
+import com.td.boss.util.*;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.RandomUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;
@@ -53,6 +60,9 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
     @Autowired
     private ComExplainLandService comExplainLandService;
 
+    @Autowired
+    private ComPlayerDisasterService comPlayerDisasterService;
+
 
     /**
      * 获取用户土地
@@ -153,10 +163,10 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
      */
     @GetMapping("getCanStealDetailList")
     public Result<List<ComPlayerLandAndPlantVo>> getCanStealListFunction(
-                                                                 @RequestParam(value = "userId") String userId,
-                                                                 @RequestParam(value = "otherUserId") String otherUserId) {
+            @RequestParam(value = "userId") String userId,
+            @RequestParam(value = "otherUserId") String otherUserId) {
 
-        List<ComPlayerLandAndCanSteal> comPlayerLands = comPlayerLandService.findCanStealByUserIdAndOtherUserId(userId,otherUserId);
+        List<ComPlayerLandAndCanSteal> comPlayerLands = comPlayerLandService.findCanStealByUserIdAndOtherUserId(userId, otherUserId);
         List<ComPlayerLandAndPlantVo> _simpleVoList = CopyUtil.copyList(comPlayerLands, ComPlayerLandAndPlantVo.class);
         List<ComPlayerLandAndPlantVo> _list = new ArrayList<>();
         try {
@@ -435,4 +445,15 @@ public class ComPlayerLandController extends CommonController<ComPlayerLandVo, C
 
         return Result.of(comPlayerLands);
     }
+
+
+    /**
+     * 灾难
+     */
+    @GetMapping("getAttack")
+    @Transactional(rollbackFor = Exception.class)
+    public Result<DisasterVo> getAttack(@RequestParam(value = "userId") String userId) {
+        DisasterVo attack = comPlayerDisasterService.getAttack(userId);
+        return Result.of(attack, attack != null);
+    }
 }

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

@@ -23,6 +23,7 @@ import java.io.InputStreamReader;
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.text.SimpleDateFormat;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
@@ -83,6 +84,42 @@ public class DappUtil {
         }
     }
 
+    /**
+     * 根据村民ID找到所属村的cnt总支付和总兑换数量(模块4)
+     * {
+     *     "code": 200,
+     *     "msg": "success",
+     *     "data": 0
+     * }
+     */
+    public static Map<String,Object> getCntPayAndSwapAmount(String userId){
+
+        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
+        form.add("id", userId);
+        //验证地址
+        String onlineUrl = "https://yt.landownership.live/api/game/cntPayAndSwapAmount";
+        String testUrl = "https://wp.landownership.live/api/game/cntPayAndSwapAmount";
+        String DAppUrl = DappUtil.getEnv().equals("prod") ? onlineUrl : testUrl;
+        log.info("根据村民ID找到所属村的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 (Map) response.get("data");
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            return new HashMap<>();
+            //e.printStackTrace();
+        }
+    }
 
 }

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

@@ -47,9 +47,9 @@ spring:
 
   #数据库配置
   datasource:
-    url: jdbc:mysql://42.192.165.168:3306/dragon_town?serverTimezone=GMT%2B8&characterEncoding=utf-8
+    url: jdbc:mysql://123.57.252.53:6688/dragon_town?serverTimezone=GMT%2B8&characterEncoding=utf-8
     username: root #dragon_town #root
-    password:  9ab8fad748dead93 #zddeiBmp8c5T6TR6 #9ab8fad748dead93
+    password:  FzCebFq6Xy0CDTXJ #zddeiBmp8c5T6TR6 #9ab8fad748dead93
     driver-class-name: com.mysql.cj.jdbc.Driver
     hikari:
       minimum-idle: 5
@@ -61,9 +61,9 @@ spring:
       connection-test-query: SELECT 1
 
   redis:
-    host: 42.192.165.168
+    host: 123.57.252.53
     port: 6379
-    password: abc123456abc-test
+    password: heihei
     data: #工程中只是把redis作为缓存,并未使用redis作为数据持久化存储源repository使用.
       redis:
         repositories:

+ 16 - 1
src/test/java/com/td/boss/BossApplicationTests.java

@@ -1,13 +1,28 @@
 package com.td.boss;
 
+import com.td.boss.common.pojo.Result;
+import com.td.boss.game.complayerdog.vo.DisasterVo;
+import com.td.boss.game.complayerland.controller.ComPlayerLandController;
 import org.junit.jupiter.api.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;
 
-@SpringBootTest
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
 class BossApplicationTests {
 
+    @Autowired
+    private ComPlayerLandController comPlayerLandController;
+
     @Test
     void contextLoads() {
+
     }
 
+    @Test
+    void attack(){
+        Result<DisasterVo> attack = comPlayerLandController.getAttack("1002");
+    }
 }