|
|
@@ -0,0 +1,208 @@
|
|
|
+package com.td.boss.game.complayerland.service;
|
|
|
+
|
|
|
+import cn.hutool.core.convert.Convert;
|
|
|
+import cn.hutool.core.date.DateTime;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.util.EnumUtil;
|
|
|
+import cn.hutool.core.util.RandomUtil;
|
|
|
+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.pojo.ComPlayerDisasterProtected;
|
|
|
+import com.td.boss.game.complayerland.repository.ComPlayerDisasterRepository;
|
|
|
+import com.td.boss.game.complayerland.vo.ComPlayerDisasterEnum;
|
|
|
+import com.td.boss.game.complayerland.vo.ComPlayerDisasterProtectedVo;
|
|
|
+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 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.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+@Transactional
|
|
|
+public class ComPlayerDisasterServiceImpl extends CommonServiceImpl<ComPlayerDisasterVo, ComPlayerDisaster, String> implements ComPlayerDisasterService {
|
|
|
+ @Autowired
|
|
|
+ private ComPlayerDisasterRepository comPlayerDisasterRepository;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ComPlayerDisasterProtectedService comPlayerDisasterProtectedService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 伤害 会减产50%
|
|
|
+ */
|
|
|
+ private int damage = 50;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 防御 90%概率防御灾难
|
|
|
+ */
|
|
|
+ private double defend = 90;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取经历的灾难记录
|
|
|
+ * @param userId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<ComPlayerDisaster> getHistory(String userId){
|
|
|
+ log.info("获取灾难记录:{}",userId);
|
|
|
+ List<ComPlayerDisaster> list=comPlayerDisasterRepository.getUnShow(userId).stream().sorted(Comparator.comparing(ComPlayerDisaster::getCreateTime)).collect(Collectors.toList());
|
|
|
+ log.info("获取灾难记录:{}",JSONUtil.toJsonStr(list));
|
|
|
+ list.forEach(a->a.setShow(true));
|
|
|
+ comPlayerDisasterRepository.saveAll(list);
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 灾难模块核心功能
|
|
|
+ * @param userId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public ComPlayerDisasterVo getDisaster(String userId) {
|
|
|
+ //todo 需要有个定时任务去处理,定期拉取所有人,然后执行
|
|
|
+ log.info("灾难模式:{}",userId);
|
|
|
+ ComPlayerDisasterVo comPlayerDisasterVo = null;
|
|
|
+ //如果本周内还有灾难
|
|
|
+ if (getDisasterNum(userId) > 0) {
|
|
|
+ //随机获取一种灾难方式灾难对象
|
|
|
+ comPlayerDisasterVo = getDisasterList(userId).get(RandomUtil.randomInt(0, 2));
|
|
|
+ //查看该灾难是否有防护,如果有防护需要按照防护几率计算是否防御住灾害了
|
|
|
+ if (comPlayerDisasterVo.getIsBuyProtected()) {
|
|
|
+ int randomProtect = RandomUtil.randomInt(0, 101);
|
|
|
+ log.info("灾难几率:{}", randomProtect);
|
|
|
+ if (randomProtect > (100 - defend)) {
|
|
|
+ comPlayerDisasterVo.setActivityProtect(true);
|
|
|
+ } else {
|
|
|
+ comPlayerDisasterVo.setActivityProtect(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("灾难结果:{}", JSONUtil.toJsonStr(comPlayerDisasterVo));
|
|
|
+ this.save(comPlayerDisasterVo);
|
|
|
+
|
|
|
+ //todo 应该还有个减产的接口,此处但是先不做
|
|
|
+ if (!comPlayerDisasterVo.isActivityProtect()) {
|
|
|
+
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.info("灾难结果:{}", "本周无灾难了");
|
|
|
+ }
|
|
|
+ return comPlayerDisasterVo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取灾难防护列表
|
|
|
+ *
|
|
|
+ * @param userId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<ComPlayerDisasterVo> getDisasterList(String userId) {
|
|
|
+ List<ComPlayerDisasterVo> disasterList = new ArrayList<>();
|
|
|
+ //查询当前人员购买防护历史记录
|
|
|
+ ComPlayerDisasterProtectedVo comPlayerDisasterProtectedVo = new ComPlayerDisasterProtectedVo();
|
|
|
+ comPlayerDisasterProtectedVo.setUserId(userId);
|
|
|
+ List<ComPlayerDisasterProtected> protectList = comPlayerDisasterProtectedService.getComPlayerDisasterProtectedByUserIdOrderByProtectTimeDesc(userId);
|
|
|
+ log.info("防护历史记录:{}", JSONUtil.toJsonStr(protectList));
|
|
|
+
|
|
|
+ //获得枚举列表
|
|
|
+ LinkedHashMap<String, ComPlayerDisasterEnum> enumMap = EnumUtil.getEnumMap(ComPlayerDisasterEnum.class);
|
|
|
+ for (String key : enumMap.keySet()) {
|
|
|
+ Date protectedDate = protectList.stream()
|
|
|
+ .filter(a -> enumMap.get(key).getCode().equals(a.getType()))
|
|
|
+ .sorted(Comparator.comparing(ComPlayerDisasterProtected::getProtectTime).reversed())
|
|
|
+ .map(ComPlayerDisasterProtected::getProtectTime)
|
|
|
+ .findFirst().orElse(DateUtil.parse(null));
|
|
|
+ ComPlayerDisasterVo comPlayerDisasterVo = new ComPlayerDisasterVo();
|
|
|
+ comPlayerDisasterVo.setName(enumMap.get(key).getMsg());
|
|
|
+ comPlayerDisasterVo.setType(enumMap.get(key).getCode());
|
|
|
+ comPlayerDisasterVo.setProtectTime(protectedDate);
|
|
|
+ comPlayerDisasterVo.setUserId(userId);
|
|
|
+ comPlayerDisasterVo.setDamage(damage);
|
|
|
+ comPlayerDisasterVo.setDefend(defend);
|
|
|
+ comPlayerDisasterVo.setCreateTime(new Date());
|
|
|
+ comPlayerDisasterVo.setShow(false);
|
|
|
+ disasterList.add(comPlayerDisasterVo);
|
|
|
+ }
|
|
|
+ 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<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()]));
|
|
|
+ }
|
|
|
+ };
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|