فهرست منبع

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

xst 4 سال پیش
والد
کامیت
c8b659bb6e

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

@@ -18,4 +18,6 @@ public class ComPlayerDisaster implements Serializable {
     private String log;
     private String userId;
     private Date createTime;
+    private Date beginTime;
+    private Date endTime;
 }

+ 7 - 8
src/main/java/com/td/boss/game/complayerland/repository/ComPlayerDisasterLogRepository.java

@@ -3,21 +3,20 @@ package com.td.boss.game.complayerland.repository;
 import com.td.boss.common.repository.CommonRepository;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisasterLog;
 import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 
-import java.util.Date;
 import java.util.List;
 
 @Repository
 public interface ComPlayerDisasterLogRepository extends CommonRepository<ComPlayerDisasterLog, String> {
 
-    @Query(value = "select * from com_player_dsaster_log where user_id = ?1 and `is_show`=0",nativeQuery=true)
-    List<ComPlayerDisasterLog> getUnShow(String userId);
-//
-    //todo sql不对
-    @Query(value = "select * from com_player_dsaster_log where  `is_enabled`=0 and disaster_time between :beginTime and :endTime" ,nativeQuery=true)
-    List<ComPlayerDisasterLog> getUnEnabled(@Param("beginTime") Date beginTime,@Param("endTime") Date endTime);
+    /**
+     * 获取已发生未读的灾难集合
+     * @param userId
+     * @return
+     */
+    @Query(value = "select * from com_player_dsaster_log where user_id = ?1 and `is_show`=0 and `is_enabled`=1",nativeQuery=true)
+    List<ComPlayerDisasterLog> getUnShowAndEnabled(String userId);
 
     ComPlayerDisasterLog findByUserId(String userId);
 }

+ 28 - 0
src/main/java/com/td/boss/game/complayerland/scheduled/ComPlayerDisasterDateUtil.java

@@ -0,0 +1,28 @@
+package com.td.boss.game.complayerland.scheduled;
+
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.date.Week;
+
+import java.util.Date;
+
+public class ComPlayerDisasterDateUtil {
+
+    public static Date getBegin() {
+        Date now = new Date();
+        if (Week.SUNDAY == DateUtil.dayOfWeekEnum(now)) {
+            return DateUtil.beginOfDay(now);
+        } else {
+            return DateUtil.beginOfWeek(now).offset(DateField.DAY_OF_WEEK, -1);
+        }
+    }
+
+    public static Date getEnd() {
+        Date now = new Date();
+        if (Week.SUNDAY == DateUtil.dayOfWeekEnum(now)) {
+            return DateUtil.endOfDay(now).offset(DateField.DAY_OF_WEEK, 6);
+        } else {
+            return DateUtil.endOfWeek(now).offset(DateField.DAY_OF_WEEK, -1);
+        }
+    }
+}

+ 35 - 0
src/main/java/com/td/boss/game/complayerland/scheduled/ComPlayerDisasterDayTask.java

@@ -0,0 +1,35 @@
+package com.td.boss.game.complayerland.scheduled;
+
+import com.td.boss.game.complayerland.pojo.ComPlayerDisasterLog;
+import com.td.boss.game.complayerland.service.ComPlayerDisasterLogService;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.JobExecutionContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+import java.util.List;
+
+@Slf4j
+@EnableScheduling
+public class ComPlayerDisasterDayTask extends QuartzJobBean {
+
+    @Autowired
+    private ComPlayerDisasterLogService comPlayerDisasterLogService;
+
+    @Override
+    protected void executeInternal(JobExecutionContext jobExecutionContext) {
+        log.info("触发灾难周期任务开始");
+        //把今天灾难的明细取出来。按照用户编号计算是否有防护。
+        List<ComPlayerDisasterLog> disasterLogList = comPlayerDisasterLogService.getTodayDisasterUnEnabledList();
+        log.info("触发每天灾难任务:{}个", disasterLogList.size());
+        for (ComPlayerDisasterLog disasterLog : disasterLogList) {
+            try {
+                comPlayerDisasterLogService.ComPlayerDisasterDayTask(disasterLog);
+            } catch (Exception e) {
+                log.error("触发灾难周期任务异常(天):" + e.getMessage());
+            }
+        }
+        log.info("触发灾难周期任务结束");
+    }
+}

+ 0 - 22
src/main/java/com/td/boss/game/complayerland/scheduled/ComPlayerDisasterTask.java

@@ -1,22 +0,0 @@
-package com.td.boss.game.complayerland.scheduled;
-
-import cn.hutool.core.date.DateUtil;
-import com.td.boss.game.complayerland.service.ComPlayerDisasterLogService;
-import org.quartz.JobExecutionContext;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.scheduling.quartz.QuartzJobBean;
-
-
-@EnableScheduling
-public class ComPlayerDisasterTask extends QuartzJobBean {
-
-    @Autowired
-    private ComPlayerDisasterLogService comPlayerDisasterLogService;
-
-    @Override
-    protected void executeInternal(JobExecutionContext jobExecutionContext) {
-//        comPlayerDisasterLogService.getDisaster("1002");
-        System.out.println("测试:" + DateUtil.date());
-    }
-}

+ 40 - 0
src/main/java/com/td/boss/game/complayerland/scheduled/ComPlayerDisasterWeekTask.java

@@ -0,0 +1,40 @@
+package com.td.boss.game.complayerland.scheduled;
+
+import com.td.boss.game.complayerland.service.ComPlayerDisasterLogService;
+import com.td.boss.game.complayers.service.ComPlayersService;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.JobExecutionContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+@EnableScheduling
+public class ComPlayerDisasterWeekTask extends QuartzJobBean {
+
+    @Autowired
+    private ComPlayerDisasterLogService comPlayerDisasterLogService;
+    @Autowired
+    private ComPlayersService comPlayersService;
+
+    @Override
+    protected void executeInternal(JobExecutionContext jobExecutionContext) {
+        log.info("每周拉取灾难数据周期任务开始");
+        List<String> userIds = new ArrayList<>();
+        userIds.add("1002");
+        //todo 测试后 改回去
+        //List<String> userIds = comPlayersService.findUserIds();
+        log.info("拉取灾难接口数据周期任务数量:{}个", userIds.size());
+        for (String userId : userIds) {
+            try {
+                comPlayerDisasterLogService.asyncDisaster(userId);
+            } catch (Exception e) {
+                log.error("触发灾难周期任务异常(周):" + e.getMessage());
+            }
+        }
+        log.info("每周拉取灾难数据周期任务开始");
+    }
+}

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

@@ -7,35 +7,58 @@ import org.springframework.context.annotation.Configuration;
 @Configuration
 public class QuartzConfig {
 
-    private static String JOB_GROUP_NAME = "JOBGROUP_ComPlayerDisaster";
-    private static String TRIGGER_GROUP_NAME = "TRIGGERGROUP_ComPlayerDisaster";
+//    private static String JOB_GROUP_NAME = "JOBGROUP_ComPlayerDisaster";
+//    private static String TRIGGER_GROUP_NAME = "TRIGGERGROUP_ComPlayerDisaster";
+
+    private static String WeekTrigger = "0 0/1 * * * ?";
+    private static String DayTrigger = "0/5 * * * * ?";
+//    //每周日1点
+//    private static String WeekTrigger = "0 0 1 ? * SUN";
+//    //每天6点
+//    private static String DayTrigger = "0 0 6 * * ? *";
 
-    /**
-     * 定时任务1:
-     * 同步用户信息Job(任务详情)
-     */
     @Bean
-    public JobDetail syncUserJobDetail() {
-        JobDetail jobDetail = JobBuilder.newJob(ComPlayerDisasterTask.class)
-                .withIdentity("syncUserJobDetail", JOB_GROUP_NAME)
+    public JobDetail syncDisasterWeekDetail() {
+        JobDetail jobDetail = JobBuilder.newJob(ComPlayerDisasterWeekTask.class)
+//                .withIdentity("syncUserJobDetail", JOB_GROUP_NAME)
                 .storeDurably() //即使没有Trigger关联时,也不需要删除该JobDetail
                 .build();
         return jobDetail;
     }
 
-    /**
-     * 定时任务1:
-     * 同步用户信息Job(触发器)
-     */
     @Bean
-    public Trigger syncUserJobTrigger() {
+    public Trigger syncDisasterWeekTrigger() {
+        //每隔5秒执行一次
+        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(WeekTrigger);
+
+        //创建触发器
+        Trigger trigger = TriggerBuilder.newTrigger()
+                .forJob(syncDisasterWeekDetail())
+//                .withIdentity("syncUserJobTrigger", TRIGGER_GROUP_NAME)
+                .withSchedule(cronScheduleBuilder)
+                .build();
+        return trigger;
+    }
+
+
+    @Bean
+    public JobDetail syncDisasterDayJobDetail() {
+        JobDetail jobDetail = JobBuilder.newJob(ComPlayerDisasterDayTask.class)
+//                .withIdentity("syncDisasterDayJobDetail", JOB_GROUP_NAME)
+                .storeDurably()
+                .build();
+        return jobDetail;
+    }
+
+    @Bean
+    public Trigger syncDisasterDayTrigger() {
         //每隔5秒执行一次
-        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/2 * * * ?");
+        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(DayTrigger);
 
         //创建触发器
         Trigger trigger = TriggerBuilder.newTrigger()
-                .forJob(syncUserJobDetail())
-                .withIdentity("syncUserJobTrigger", TRIGGER_GROUP_NAME)
+                .forJob(syncDisasterDayJobDetail())
+//                .withIdentity("syncDisasterDayTrigger", TRIGGER_GROUP_NAME)
                 .withSchedule(cronScheduleBuilder)
                 .build();
         return trigger;

+ 12 - 2
src/main/java/com/td/boss/game/complayerland/service/ComPlayerDisasterLogService.java

@@ -11,11 +11,21 @@ public interface ComPlayerDisasterLogService extends CommonService<ComPlayerDisa
     /**
      * 灾难模式周任务:同步每个用户上周收入支出
      */
-    void ComPlayerDisasterWeekTask();
+    void asyncDisaster(String userId);
+
+
+    /**
+     * 获取今天的灾难,并且没有触发过的灾难
+     *
+     * @return
+     */
+    List<ComPlayerDisasterLog> getTodayDisasterUnEnabledList();
+
     /**
      * 灾难模式天任务:触发所有用户今日灾难和保护机制
      */
-    void ComPlayerDisasterDayTask();
+    void ComPlayerDisasterDayTask(ComPlayerDisasterLog disasterLog);
+
     /**
      * 获取经历的灾难记录
      *

+ 111 - 89
src/main/java/com/td/boss/game/complayerland/service/ComPlayerDisasterLogServiceImpl.java

@@ -1,11 +1,9 @@
 package com.td.boss.game.complayerland.service;
 
-import cn.hutool.core.convert.Convert;
 import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateRange;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.EnumUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.json.JSONUtil;
@@ -14,11 +12,10 @@ import com.td.boss.game.complayerland.pojo.ComPlayerDisaster;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisasterLog;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisasterProtected;
 import com.td.boss.game.complayerland.repository.ComPlayerDisasterLogRepository;
+import com.td.boss.game.complayerland.scheduled.ComPlayerDisasterDateUtil;
 import com.td.boss.game.complayerland.vo.ComPlayerDisasterEnum;
-import com.td.boss.game.complayerland.vo.ComPlayerDisasterProtectedVo;
 import com.td.boss.game.complayerland.vo.ComPlayerDisasterLogVo;
 import com.td.boss.game.complayers.service.ComPlayersService;
-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;
@@ -42,9 +39,6 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
     @Autowired
     private ComPlayerDisasterProtectedService comPlayerDisasterProtectedService;
 
-    @Autowired
-    private ComPlayersService comPlayersService;
-
     @Autowired
     private ComPlayerDisasterService disasterService;
 
@@ -66,60 +60,83 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
      */
     @Override
     public List<ComPlayerDisasterLog> getHistory(String userId) {
-        log.info("获取灾难记录:{}", userId);
-        List<ComPlayerDisasterLog> list = comPlayerDisasterLogRepository.getUnShow(userId).stream().sorted(Comparator.comparing(ComPlayerDisasterLog::getCreateTime)).collect(Collectors.toList());
+        //获取已发生未读的灾难集合
+        List<ComPlayerDisasterLog> list = comPlayerDisasterLogRepository.getUnShowAndEnabled(userId).stream().sorted(Comparator.comparing(ComPlayerDisasterLog::getCreateTime)).collect(Collectors.toList());
         log.info("获取灾难记录:{}", JSONUtil.toJsonStr(list));
+        //设置成已读
         list.forEach(a -> a.setShow(true));
         comPlayerDisasterLogRepository.saveAll(list);
         return list;
     }
 
-    /**
-     * 灾难模式周任务:同步每个用户上周收入支出
-     */
-    @Override
-    public void ComPlayerDisasterWeekTask() {
-        List<String> userIds = new ArrayList<>();
-        userIds.add("1002");
-        //todo 测试后 改回去
-        //List<String> userIds = comPlayersService.findUserIds();
-        for (String userId : userIds) {
-            asyncDisaster(userId);
-        }
-    }
+    //region 灾难模式周任务:同步每个用户上周收入支出
 
     /**
-     * 同步每个用户上周收入支出
+     * 定时任务核心方法 同步每个用户上周收入支出
+     * 灾难模式每周统计一次,如果这个期间新用户也需要这个功能。新注册的用户直接调用该方法。
+     *
      * @param userId
      */
-    private void asyncDisaster(String userId) {
-        //同步上周收入支出数据
+    @Transactional
+    @Override
+    public void asyncDisaster(String userId) {
+        //同步“链端接口”上周“收入支出数据”到数据库
         ComPlayerDisaster comPlayerDisaster = disasterService.save(userId);
-        //生成灾难记录记录
+        //如果从链端接口拉到数据了。那么就计算灾难发生明细
         if (comPlayerDisaster != null) {
             //本周内应该出现的灾难次数
             int disasterTimes = getDisasterTimes(comPlayerDisaster.getPayment(), comPlayerDisaster.getIncome());
+            log.info("用户编号:{}本周发生灾难:{}次", userId, disasterTimes);
 
+            //获得本周还剩下几天可以发生灾难,每周从周日到下周6
             Date now = new Date();
-            DateRange dayRange = DateUtil.range(now, DateUtil.endOfWeek(now).offset(DateField.DAY_OF_WEEK,-1), DateField.DAY_OF_WEEK);
+            DateRange dayRange = DateUtil.range(now, ComPlayerDisasterDateUtil.getEnd(), DateField.DAY_OF_WEEK);
             List<Date> hasDisasterDay = new ArrayList<>();
             while (dayRange.hasNext()) {
                 hasDisasterDay.add(dayRange.next());
             }
-            //发生灾难的时间点(本周具体哪天灾难)
+            //发生灾难的时间点(本周具体哪天灾难),从可发生灾难【时间集合】中随机取【x】个时间点进行灾难
             List<Date> realDisasterDayList = RandomUtil.randomEleList(hasDisasterDay, disasterTimes);
-            //生成灾难对象
+            log.info("用户编号:{}本周发生灾难时间点:{}", userId, JSONUtil.toJsonStr(realDisasterDayList));
+
+            //生成灾难明细记录
             List<ComPlayerDisasterLog> disasterLogList = getComPlayerDisasterLogVoList(userId, comPlayerDisaster.getId(), realDisasterDayList);
+            log.info("用户编号:{}本周发生灾难明细:{}", userId, JSONUtil.toJsonStr(disasterLogList));
 
+            //灾难明细持久化
             comPlayerDisasterLogRepository.saveAll(disasterLogList);
         }
     }
 
     /**
-     * 生成灾难对象
-     * @param userId 用户id
+     * 获得本周灾难次数
+     * 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;
+        }
+    }
+
+    /**
+     * 根据用户编号和灾难时间点 生成灾难表
+     *
+     * @param userId                   用户id
      * @param ComPlayerDisasterTableId 主表id
-     * @param realDisasterDayList 发生灾难的时间点(本周具体哪天灾难)
+     * @param realDisasterDayList      发生灾难的时间点(本周具体哪天灾难)
      * @return
      */
     private List<ComPlayerDisasterLog> getComPlayerDisasterLogVoList(String userId, long ComPlayerDisasterTableId, List<Date> realDisasterDayList) {
@@ -127,8 +144,8 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
         ComPlayerDisasterLog disasterLog;
         for (Date disasterDay : realDisasterDayList) {
             //随机获取一种灾难方式灾难对象
-            List<String> disasterEnumFields =  (List)EnumUtil.getFieldValues(ComPlayerDisasterEnum.class, "msg");
-            ComPlayerDisasterEnum disasterEnum = EnumUtil.likeValueOf(ComPlayerDisasterEnum.class,RandomUtil.randomEle(disasterEnumFields)) ;
+            List<String> disasterEnumFields = (List) EnumUtil.getFieldValues(ComPlayerDisasterEnum.class, "msg");
+            ComPlayerDisasterEnum disasterEnum = EnumUtil.likeValueOf(ComPlayerDisasterEnum.class, RandomUtil.randomEle(disasterEnumFields));
 
             disasterLog = new ComPlayerDisasterLog();
             disasterLog.setDsasterId(ComPlayerDisasterTableId);
@@ -145,73 +162,78 @@ public class ComPlayerDisasterLogServiceImpl extends CommonServiceImpl<ComPlayer
         }
         return list;
     }
+    //endregion
+
+    //region 灾难模式天任务:触发所有用户今日灾难和保护机制
 
     /**
      * 灾难模式天任务:触发所有用户今日灾难和保护机制
      */
+    @Transactional
     @Override
-    public void ComPlayerDisasterDayTask() {
+    public void ComPlayerDisasterDayTask(ComPlayerDisasterLog disasterLog) {
         Date now = new Date();
-        DateTime begin = DateUtil.beginOfDay(now);
-        DateTime end = DateUtil.endOfDay(now);
-        //把今天灾难的明细取出来。按照用户编号计算是否有防护。
-        List<ComPlayerDisasterLog> disasterLogList = comPlayerDisasterLogRepository.getUnEnabled(begin, end);
-        for (ComPlayerDisasterLog disasterLog : disasterLogList) {
-            if (!disasterLog.isEnabled()) {
-                //查询当前人员购买防护历史记录
-                List<ComPlayerDisasterProtected> protectList = comPlayerDisasterProtectedService.getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(disasterLog.getUserId());
-                log.info("防护历史记录:{}", JSONUtil.toJsonStr(protectList));
-                //防护到期时间
-                Date protectedDate = protectList.stream()
-                        .filter(a -> disasterLog.getDsasterType().equals(a.getDsasterType()))
-                        .sorted(Comparator.comparing(ComPlayerDisasterProtected::getProtectTime).reversed())
-                        .map(ComPlayerDisasterProtected::getProtectTime)
-                        .findFirst().orElse(DateUtil.parse(null));
-
-                disasterLog.setProtectTime(protectedDate);
-                disasterLog.setEnabled(true);
-                disasterLog.setUpdateTime(now);
-                if (protectedDate!=null&&now.before(protectedDate)) {
-                    int randomProtect = RandomUtil.randomInt(0, 101);
-                    log.info("灾难几率:{}", randomProtect);
-                    if (randomProtect > (100 - defend)) {
-                        disasterLog.setProtect(true);
-                    } else {
-                        disasterLog.setProtect(false);
-                    }
-                }
-
-                log.info("灾难结果:{}", JSONUtil.toJsonStr(disasterLog));
-                comPlayerDisasterLogRepository.save(disasterLog);
-                //todo 应该还有个减产的接口,此处但是先不做
-                if (!disasterLog.isProtect()) {
-
-                }
-            } else {
-                log.info("[{}]灾难结果:{}", disasterLog.getUserId(), "灾难不可重复出发");
+        //查询当前人员购买防护历史记录
+        List<ComPlayerDisasterProtected> protectList = comPlayerDisasterProtectedService.getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(disasterLog.getUserId());
+        log.info("用户编号:{},防护历史记录:{}", disasterLog.getUserId(), JSONUtil.toJsonStr(protectList));
+        //获得对应灾难类型的防护记录    并得到这个 防护到期时间
+        Date protectedDate = protectList.stream()
+                .filter(a -> disasterLog.getDsasterType().equals(a.getDsasterType()))
+                .sorted(Comparator.comparing(ComPlayerDisasterProtected::getProtectTime).reversed())
+                .map(ComPlayerDisasterProtected::getProtectTime)
+                .findFirst().orElse(DateUtil.parse(null));
+
+        log.info("用户编号:{},灾难:{},防护到期时间:{}", disasterLog.getUserId(), JSONUtil.toJsonStr(disasterLog), protectedDate);
+
+        //存储防护到期时间,可能是null代表没有购买过防护
+        disasterLog.setProtectTime(protectedDate);
+        //设置本次灾难已经发生
+        disasterLog.setEnabled(true);
+        //灾难具体触发时间,代表每天的周期任务时间
+        disasterLog.setUpdateTime(now);
+        //默认是没有防护的
+        disasterLog.setProtect(false);
+
+        //如果没有防护或者防护到期。则直接发生灾难进行减产
+        if (protectedDate != null && now.before(protectedDate)) {
+            int randomProtect = RandomUtil.randomInt(0, 101);
+            log.info("灾难几率:{}", randomProtect);
+            if (randomProtect > (100 - defend)) {
+                disasterLog.setProtect(true);
             }
         }
+
+        log.info("灾难日志:{}", JSONUtil.toJsonStr(disasterLog));
+        comPlayerDisasterLogRepository.save(disasterLog);
+        //todo 应该还有个减产的接口,此处但是先不做
+        if (!disasterLog.isProtect()) {
+            log.info("灾难结果:减产");
+        } else {
+            log.info("灾难结果:已防御");
+        }
+
     }
 
     /**
-     * a)当某个村长所属农场的支出小于等于收入30%时,按照正常频率,每周出现1次
-     * b)当某个村长所属农场的支出大于收入30%时,每周出现2次
-     * c)当某个村长所属农场的支出大于收入50%时,每周出现4次
-     * d)当某个村长所属农场的支出大于收入80%时,每周出现6次
-     * 支出对应pay_amount,收入对应swap_amount
+     * 获取今天的灾难,并且没有触发过的灾难
      *
-     * @param pay_amount  支出对应
-     * @param swap_amount 收入对应
+     * @return
      */
-    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;
-        }
+    @Override
+    public List<ComPlayerDisasterLog> getTodayDisasterUnEnabledList() {
+        Date now = new Date();
+        DateTime begin = DateUtil.beginOfDay(now);
+        DateTime end = DateUtil.endOfDay(now);
+        Specification specification = new Specification<ComPlayerDisasterLog>() {
+            @Override
+            public Predicate toPredicate(Root<ComPlayerDisasterLog> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+                List<Predicate> predicates = new ArrayList<>();
+                predicates.add(criteriaBuilder.between(root.get("disasterTime"), begin, end));
+                predicates.add(criteriaBuilder.equal(root.get("isEnabled"), 0));
+                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+            }
+        };
+        return comPlayerDisasterLogRepository.findAll(specification);
     }
+    //endregion
 }

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

@@ -8,5 +8,5 @@ import java.util.List;
 
 public interface ComPlayerDisasterProtectedService extends CommonService<ComPlayerDisasterProtectedVo, ComPlayerDisasterProtected, String> {
 
-    public List<ComPlayerDisasterProtected> getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(String userId);
+    List<ComPlayerDisasterProtected> getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(String userId);
 }

+ 5 - 4
src/main/java/com/td/boss/game/complayerland/service/ComPlayerDisasterService.java

@@ -4,13 +4,14 @@ import com.td.boss.common.service.CommonService;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisaster;
 import com.td.boss.game.complayerland.vo.ComPlayerDisasterVo;
 
-import java.util.Date;
 
 public interface ComPlayerDisasterService extends CommonService<ComPlayerDisasterVo, ComPlayerDisaster, String> {
 
     /**
-     * 收入支出比例的时间周期 这个确定是上周的数据
-     * 本周开始时间为周日到周六,期间获取的不会变化,这周获取的是上周的数据
+     * 同步“链端接口”上周“收入支出数据”到数据库
+     *
+     * @param userId
+     * @return
      */
-    ComPlayerDisaster save(String userId );
+    ComPlayerDisaster save(String userId);
 }

+ 50 - 17
src/main/java/com/td/boss/game/complayerland/service/ComPlayerDisasterServiceImpl.java

@@ -1,18 +1,27 @@
 package com.td.boss.game.complayerland.service;
 
 import cn.hutool.core.convert.Convert;
+import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.json.JSONUtil;
 import com.td.boss.common.service.CommonServiceImpl;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisaster;
 import com.td.boss.game.complayerland.repository.ComPlayerDisasterRepository;
+import com.td.boss.game.complayerland.scheduled.ComPlayerDisasterDateUtil;
 import com.td.boss.game.complayerland.vo.ComPlayerDisasterVo;
 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 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
@@ -22,39 +31,63 @@ public class ComPlayerDisasterServiceImpl extends CommonServiceImpl<ComPlayerDis
     @Autowired
     private ComPlayerDisasterRepository repository;
 
+    /**
+     * 同步“链端接口”上周“收入支出数据”到数据库
+     * 本周开始时间为周日到周六,期间获取的不会变化,这周获取的是上周的数据
+     *
+     * @param userId
+     * @return
+     */
     @Override
     public ComPlayerDisaster save(String userId) {
-        Date now = new Date();
-        Date begin = DateUtil.beginOfWeek(now);
-        Date end = DateUtil.endOfWeek(now);
-        if (exists(begin, end)) {
+        Date begin = ComPlayerDisasterDateUtil.getBegin();
+        Date end = ComPlayerDisasterDateUtil.getEnd();
+        log.info("灾难模式周同步数据[{}],begin:{},end:{},now:{}", userId, begin, end, DateUtil.format(new Date(), "yyyy-MM-dd hh:mm:ss"));
+        if (exists(userId, begin, end)) {
+            log.info("灾难模式周同步数据[{}]已经同步过了", userId);
             return null;
         }
-        ComPlayerDisaster data = getData(userId);
+        ComPlayerDisaster data = getData(userId, begin, end);
         return repository.saveAndFlush(data);
     }
 
-    private ComPlayerDisaster getData(String userId) {
-        //读取接口 获取 那种情况 这个接口实际是返回的上周数据。所以什么时候啦都不会变。
-        //本周开始时间为周日到周六,期间获取的不会变化,这周获取的是上周的数据
-        //所以 支出对应pay_amount,收入对应swap_amount
-        Map<String, Object> cntPayAndSwapAmount = DappUtil.getCntPayAndSwapAmount(userId);
-        log.info("接口返回支付兑换结果:{}", JSONUtil.toJsonStr(cntPayAndSwapAmount));
+    /**
+     * 所以 支出对应pay_amount,收入对应swap_amount
+     * @param userId
+     * @param beginTime
+     * @param endTime
+     * @return
+     */
+    private ComPlayerDisaster getData(String userId, Date beginTime, Date endTime) {
+        Map response = DappUtil.getCntPayAndSwapAmount(userId);
+        log.info("接口返回支付兑换结果:{}", JSONUtil.toJsonStr(response));
+        Map<String, Object> cntPayAndSwapAmount = (Map) response.get("data");
+
         // 总支付cnt
-        Double pay_amount = Convert.toDouble(cntPayAndSwapAmount.get("pay_amount"));
+        Double pay_amount = Convert.toDouble(cntPayAndSwapAmount.get("pay_amount"), 0d);
         // 总兑换cnt
-        Double swap_amount = Convert.toDouble(cntPayAndSwapAmount.get("swap_amount"));
+        Double swap_amount = Convert.toDouble(cntPayAndSwapAmount.get("swap_amount"), 0d);
         ComPlayerDisaster comPlayerDisaster = new ComPlayerDisaster();
         comPlayerDisaster.setCreateTime(new Date());
         comPlayerDisaster.setUserId(userId);
         comPlayerDisaster.setIncome(swap_amount);
         comPlayerDisaster.setPayment(pay_amount);
-        comPlayerDisaster.setLog(JSONUtil.toJsonStr(cntPayAndSwapAmount));
+        comPlayerDisaster.setLog(JSONUtil.toJsonStr(response));
+        comPlayerDisaster.setBeginTime(beginTime);
+        comPlayerDisaster.setEndTime(endTime);
         return comPlayerDisaster;
     }
 
-    private boolean exists(Date begin, Date end) {
-        //todo 根据时间验证是否有数据
-        return false;
+    private boolean exists(String userId, 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));
+                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+            }
+        };
+        return repository.count(specification) > 0;
     }
 }

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

@@ -92,7 +92,7 @@ public class DappUtil {
      *     "data": 0
      * }
      */
-    public static Map<String,Object> getCntPayAndSwapAmount(String userId){
+    public static Map getCntPayAndSwapAmount(String userId){
 
         MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
         form.add("id", userId);
@@ -114,7 +114,7 @@ public class DappUtil {
             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");
+            return response;
         } catch (Exception e) {
             log.error(e.getMessage());
             return new HashMap<>();

+ 0 - 13
src/main/resources/application.yml

@@ -33,19 +33,6 @@ spring:
   #打印SQL
   jpa:
     show-sql: true
-    properties:
-      hibernate:
-        format_sql: true
-
-logging:
-  level:
-    org:
-      hibernate:
-        type:
-          descriptor:
-            sql:
-              BasicBinder=trace:
-    root: debug
 
 
 # token 参数

+ 0 - 5
src/main/resources/logback-spring.xml

@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration debug="false">
-    <logger name="org.hibernate.SQL" level="DEBUG"/>
     <!--日志文件主目录:这里${user.home}为当前服务器用户主目录-->
     <property name="LOG_HOME" value="${user.home}/log"/>
     <!--日志文件名称:这里spring.application.name表示工程名称-->
@@ -69,10 +68,6 @@
         <logger level="WARN" name="com.netflix"/>
         <logger level="DEBUG" name="org.hibernate.SQL"/>
 
-        <logger name="org.hibernate.engine.QueryParameters" level="DEBUG"/>
-        <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG"/>
-        <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE"/>
-
     </springProfile>
     <springProfile name="dev">
         <!--root节点 全局日志级别,用来指定最基础的日志输出级别-->

+ 18 - 5
src/test/java/com/td/boss/ComPlayerDisasterLogTests.java

@@ -1,5 +1,6 @@
 package com.td.boss;
 
+import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateUtil;
 import com.td.boss.game.complayerland.pojo.ComPlayerDisasterLog;
 import com.td.boss.game.complayerland.service.ComPlayerDisasterProtectedService;
@@ -11,6 +12,7 @@ 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.Date;
 import java.util.List;
 
@@ -35,7 +37,15 @@ class ComPlayerDisasterLogTests {
         comPlayerDisasterProtected.setUserId(userId);
         comPlayerDisasterProtected.setDsasterType(ComPlayerDisasterEnum.ziran.getCode());
         comPlayerDisasterProtected.setDsasterName(ComPlayerDisasterEnum.ziran.getMsg());
-        comPlayerDisasterProtected.setProtectTime(DateUtil.parse("2022-03-30 00:00:00"));
+        comPlayerDisasterProtected.setProtectTime(DateUtil.date(new Date()).offset(DateField.DAY_OF_WEEK, 30));
+        comPlayerDisasterProtectedService.save(comPlayerDisasterProtected);
+
+        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);
     }
 
@@ -52,11 +62,14 @@ class ComPlayerDisasterLogTests {
      * 测试灾难模式
      */
     @Test
-    void ComPlayerDisasterWeekTask(){
-        comPlayerDisasterLogService.ComPlayerDisasterWeekTask();
+    void ComPlayerDisasterWeekTask() {
+        comPlayerDisasterLogService.asyncDisaster(userId);
     }
+
     @Test
-    void ComPlayerDisasterDayTask(){
-        comPlayerDisasterLogService.ComPlayerDisasterDayTask();
+    void ComPlayerDisasterDayTask() {
+        for (ComPlayerDisasterLog disasterLog : comPlayerDisasterLogService.getTodayDisasterUnEnabledList()) {
+            comPlayerDisasterLogService.ComPlayerDisasterDayTask(disasterLog);
+        }
     }
 }