SpringBoot 策略设计模式|工厂模式 项目实战

SpringBoot 策略设计模式|工厂模式 项目实战

    • 项目背景:
    • 修改前的代码
    • 改造后代码
    • 这里顺便记录一些小小的统计常用的工具方法 大家也可以使用呀~
  • 码字不易,转载注明。谢谢各位大佬啦

项目背景:

2C的一些项目中有些数据还是需要统计出来给用户来看的,项目中我们随着业务的不断增多项目逐渐臃肿不堪,而根据不同的业务逻辑去做统计的一些定时任务,也就成了重灾区,不同的业务给前端一坨Vo对象,再让去前端一个一个去对来对去,自己又是也就蒙圈了。

修改前的代码

接口类:

@GetMapping("info")
 public ResponseTO<MerchantSummaryVo, DefaultResponseErrorType> info(
@Valid @NotBlank(message = CommonConstants.INMNO_HEADER
                   + "不能为空") @RequestHeader(CommonConstants.INMNO_HEADER) String inMno) {
       try {
           return ok(merchantSummaryBiz.home(inMno));
       } catch (SystemException e) {
           log.error("{}经营数据概览异常: {}", inMno, e.getMessage());
           return error(DefaultResponseErrorType.ERROR, e.getMessage());
       } catch (Exception e) {
           log.error("{}经营数据概览异常: ", inMno, e);
           return error(DefaultResponseErrorType.ERROR, ResultErrorMessage.COMMON_ERR.getMessage());
       }
   }

内部实现类(这只是一个业务逻辑):

        MerchantSummaryVo merchantSummaryVo = new MerchantSummaryVo();
        *//** 1.累积数据 *//*
        MileMerchantSummary merchantSummary = summaryService.findByInMno(inMno);
        if (ObjectUtils.isEmpty(merchantSummary)) {
            return merchantSummaryVo;
        }
        // 总营业额
        merchantSummaryVo.setAmountTotal(AmountConvertUtils.twoScale(merchantSummary.getAmountTotalRecharge()).toPlainString());
        // 充值收入
        merchantSummaryVo.setRechargeAmountTotal(
                AmountConvertUtils.twoScale(merchantSummary.getRechargeAmountTotal()).toPlainString());
        // 非充值收入
        merchantSummaryVo.setUnRechargeAmountTotal(
                AmountConvertUtils.twoScale(merchantSummary.getUnRechargeAmountTotal()).toPlainString());
        // 充值会员消费人数
        merchantSummaryVo.setRechargeNumTotal(merchantSummary.getRechargeNumTotal());
        // 非充值会员消费人数
        merchantSummaryVo.setUnRechargeNumTotal(merchantSummary.getUnRechargeNumTotal());
        // 所有动态数据都是近7天
        MileMerchantStatisticInfo statisticInfo = statisticInfoService.findByInMnoAndType(inMno,
                CommonCodeStrEnum.STATISTIC_TYPE_R7.getCode());
        // 上7天
        MileMerchantStatisticInfo statisticInfoLast = statisticInfoService.findByInMnoAndType(inMno,
                CommonCodeStrEnum.STATISTIC_TYPE_L7.getCode());
        *//** 2.客流分析 *//*
        merchantSummaryVo.setConsumerFlowVo(this.consumerFlow(statisticInfo, statisticInfoLast, null));
        *//** 3.充值会员消费看板 *//*
        merchantSummaryVo.setRechargeVo(this.recharge(statisticInfo, statisticInfoLast));
        *//** 4.推广数据分析 *//*
        merchantSummaryVo.setSpreadVo(this.spread(merchantSummary, Boolean.FALSE));
        *//** 5.店铺交易概览 *//*
        merchantSummaryVo.setStoreVo(this.store(statisticInfo, statisticInfoLast, null));
        // 近30天
        statisticInfo = statisticInfoService.findByInMnoAndType(inMno, CommonCodeStrEnum.STATISTIC_TYPE_R30.getCode());
        return merchantSummaryVo;

是不是特别臃肿,当我们还需要一个别的需求的时候,我们还需要的再往这个方法中不停的添加逻辑,导致这个方法的很长。有人说到了:封装方法不就好了?? 那么我就会问你了。当你封装了一堆方法,别人怎么围护你写的代码,再来新的业务时候还需要重写掰扯原先的计算逻辑,再去修改代码,效率很低,不符合封闭开放的原则

改造后代码

所以我们要对他进行改造,我们经常用到的Web框架是Spring,而Spring的容器管理很强大,强大到你无法象想。
代码如下:
首先我们顶一个抽象策略类
这个用来抽象不同的业务所需要执行的方法(也就是策略设计模式中所谓的不同的算法簇)。
而第二个方法,只是对这个方法的一种定义,让我们的程序可以方便的找到自己应该执行的方法(算法簇)。

/* @Classname IActivityHandleStrategy
 * @Description 抽象活动统计策略类
 * @Date 2021/5/26 17:12
 * @Created by ZhuBo
 */
public interface IActivityHandleStrategy {

    /**
     * 执行拦截器
     * @param inMno
     * @return
     */
   MerchantSummaryVo handleReceipt(String inMno);

    /**
     * 经营数据类型
     * @return
     */
    String getTypeId();
}

看到代码中的Resource注解了么?我们还记得他的作用是什么?如果不记得同学要百度一下。这里先卖个关子。(自己动手去百度才会认真看。我这里就不解释了)
这个工厂类使用Spring从而动态的获取到对应的实体类,返回的对象

/**
 * @Classname HandleStrategyFactory
 * @Description 统计经营数据工厂类,生成统计实体
 * @Date 2021/5/26 17:43
 * @Created by 朱博
 */
@Component
public class ActivityHandleStrategyFactory {

    @Resource
    private List<IActivityHandleStrategy> iActivityHandleStrategies;

    @Autowired
    private MileDiscountCardMerchantService mileDiscountCardMerchantService;

    @Autowired
    private MileMerchantActivityService mileMerchantActivityService;

    /**
     * 获取具体的统计实体
     * @param inMno
     * @return IActivityHandleStrategy
     */
    public IActivityHandleStrategy getReceiptHandleStrategy(String inMno) {
        //Zhubo todo 这里需要优化
        int discountNum = mileDiscountCardMerchantService.existsDiscountActivity(inMno);
        int rechargeNum = mileMerchantActivityService.countByInMno(inMno);
        String type;
        if (discountNum > 0 && rechargeNum > 0) {
            type = StatisticsConstants.ALL_CARD;//全量统计
        } else if (discountNum > 0) {
            type = StatisticsConstants.DISCOUNT_CARD;//折扣会员卡统计
        } else if (rechargeNum > 0) {
            type = StatisticsConstants.RECHARGE_CARD;//储值会员统计
        } else {
            type = StatisticsConstants.NORMAL;//默认会员统计
        }
        Optional<IActivityHandleStrategy> first =
                iActivityHandleStrategies.stream().filter(service -> service.getTypeId().equals(type)).findFirst();
        return first.get();
    }


}

接下来我们没一个自己定义的策略类,都要去实现之前的策略抽象类,实现其中的具体的handleReceipt() 这个方法,这样我们就工厂类对其创造的对象从而执行具体的是实现。
通过这样的改造,我们实现了简单工厂模式+策略设计模式的实现,当我们产品小姐姐再一次提出新需求的时候,就不用再改原来的统计代码了,也是我们所说的对代码的侵入性不高,对于原有逻辑不具有影响性。

package com.suixingpay.mile.front.common.impl;

import com.google.common.collect.Lists;
import com.suixingpay.mile.constants.enums.CommonCodeStrEnum;
import com.suixingpay.mile.dao.entity.MileMerchantDayStatisticInfo;
import com.suixingpay.mile.dao.entity.MileMerchantStatisticInfo;
import com.suixingpay.mile.dao.entity.MileMerchantSummary;
import com.suixingpay.mile.front.common.abstarct.IActivityHandleStrategy;
import com.suixingpay.mile.front.service.*;
import com.suixingpay.mile.front.vo.*;
import com.suixingpay.mile.util.AmountConvertUtils;
import com.suixingpay.takin.util.collection.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * @Classname IAlleHandleStrategyImpl
 * @Description 全量数据统计
 * @Date 2021/5/26 18:31
 * @Created by 朱博
 */
@Component
public class IAllHandleStrategyImpl implements IActivityHandleStrategy {

	/******************对应的代码逻辑**********************/

    public final String ALL_CARD="ALL_CARD";

    @Override
    public String getTypeId() {
        return ALL_CARD;
    }

    @Autowired
    private MileMerchantSummaryService summaryService;

    @Autowired
    private MileMerchantStatisticInfoService statisticInfoService;

    @Autowired
    private MileMerchantDayStatisticInfoService dayStatisticInfoService;

    @Autowired
    private MileTradeRecordService tradeRecordService;

    @Override
    public MerchantSummaryVo handleReceipt(String inMno) {
        MerchantSummaryVo merchantSummaryVo = new MerchantSummaryVo();
        merchantSummaryVo.setDataType(ALL_CARD);
        MileMerchantSummary merchantSummary = summaryService.findByInMno(inMno);
        if (ObjectUtils.isEmpty(merchantSummary)) {
            merchantSummaryVo.setDataType(ALL_CARD);
                return merchantSummaryVo;
        }
        // 总营业额
        merchantSummaryVo.setAmountTotal(AmountConvertUtils.twoScale(merchantSummary.getAmountTotal()).toPlainString());
        // 累计充值金额
        merchantSummaryVo.setRechargeAmountTotal(
                AmountConvertUtils.twoScale(merchantSummary.getRechargeAmountTotal()).toPlainString());
        // 普通交易金额
        merchantSummaryVo.setUnRechargeAmountTotal(
                AmountConvertUtils.twoScale(merchantSummary.getUnRechargeAmountTotal()).toPlainString());
        // 打折卡消费金额
        merchantSummaryVo.setDiscountAmountTotal(AmountConvertUtils.twoScale(merchantSummary.getDiscountCardAmountTotal()).toPlainString());
        // 充值会员消费人数
        merchantSummaryVo.setRechargeNumTotal(merchantSummary.getRechargeNumTotal());
        // 折扣会员消费人数
        merchantSummaryVo.setDiscountCardNumTotal(merchantSummary.getDiscountCardNumTotal());
        // 非折扣会员消费人数(普通会员消费人数)
        merchantSummaryVo.setUnRechargeNumTotal(merchantSummary.getUnRechargeNumTotal());
        // 普通会员人数
        merchantSummaryVo.setNormalNum(merchantSummary.getNormalNum());
        // 储值会员人数
        merchantSummaryVo.setRechargeNum(merchantSummary.getRechrageNum());
        // 折扣会员人数
        merchantSummaryVo.setDiscountNum(merchantSummary.getDiscountNum());
        // 所有动态数据都是近7天
        MileMerchantStatisticInfo statisticInfo = statisticInfoService.findByInMnoAndType(inMno,
                CommonCodeStrEnum.STATISTIC_TYPE_R7.getCode());
        // 上7天
        MileMerchantStatisticInfo statisticInfoLast = statisticInfoService.findByInMnoAndType(inMno,
                CommonCodeStrEnum.STATISTIC_TYPE_L7.getCode());
        /** 2.客流分析(充值) */
        merchantSummaryVo.setConsumerFlowVo(this.consumerFlow(statisticInfo, statisticInfoLast, null));
        /** 4.充值会员消费看板 */
        merchantSummaryVo.setRechargeVo(this.recharge(statisticInfo, statisticInfoLast));
        /** 5.折扣会员消费看板 */
        merchantSummaryVo.setDiscountVo(this.disocunt(statisticInfo, statisticInfoLast));
        /** 6.推广数据分析(充值) */
        merchantSummaryVo.setSpreadVo(this.spread(merchantSummary, Boolean.FALSE));
        /** 7.推广数据分析(折扣卡) */
        merchantSummaryVo.setSpreadDiscountVo(this.spreadOfDiscountCard(merchantSummary,Boolean.FALSE));
        /** 8.店铺交易概览 */
        merchantSummaryVo.setStoreVo(this.storeOfDiscountCard(statisticInfo, statisticInfoLast, null));
        // 近30天
        statisticInfo = statisticInfoService.findByInMnoAndType(inMno, CommonCodeStrEnum.STATISTIC_TYPE_R30.getCode());
        MileMerchantStatisticInfo statisticInfoBy30 = statisticInfoService.findByInMnoAndType(inMno,
                CommonCodeStrEnum.STATISTIC_TYPE_R30.getCode());

        /** 10.近30天人均消费频次充值 */
        merchantSummaryVo.setCapitaComsumeVo(this.capitaComsume(statisticInfoBy30));
        /** 11.近30天客单价充值 */
        merchantSummaryVo.setUnitPriceVo(this.unitPrice(statisticInfoBy30));
        /** 12.近30天人均消费频次折扣 */
        merchantSummaryVo.setCapitaComsumeDiscountVo(this.capitaComsumeOfDisocount(statisticInfo));
        // 总营业额
        merchantSummaryVo.setAmountTotal(AmountConvertUtils.twoScale(merchantSummary.getAmountTotal()).toPlainString());
        return merchantSummaryVo;
    }

    /**
     * 客流分析(储值+折扣)
     *
     * @param statisticInfo 近N天数据
     * @param statisticInfoLast 上N天数据
     * @param dayStatisticInfoList 每日数据
     * @return
     */
    public MerchantSummaryConsumerFlowVo consumerFlow(MileMerchantStatisticInfo statisticInfo,
                                                      MileMerchantStatisticInfo statisticInfoLast, List<MileMerchantDayStatisticInfo> dayStatisticInfoList) {
        // 充值会员消费人数
        int rechargeConsumeNumTotal = statisticInfo.getRechargeConsumeNum();
        // 新增会员人数
        int newRechargeNumTotal = statisticInfo.getNewRechargeNum();
        // 非充值会员消费人数
        int unRechargeConsumeNumTotal = statisticInfo.getUnRechargeConsumeNum();
        // 新增普通会员人数
        int newUnRechargeNumTotal = statisticInfo.getNewUnRechargeNum();
        // 各数据坐标系数
        List<MerchantSummaryCoordinateVo> rechargeConsumeNumCoordinateVos = Lists.newArrayList();
        List<MerchantSummaryCoordinateVo> unRechargeConsumeNumCoordinateVos = Lists.newArrayList();
        List<MerchantSummaryCoordinateVo> newRechargeNumCoordinateVos = Lists.newArrayList();
        List<MerchantSummaryCoordinateVo> newUnRechargeNumCoordinateVos = Lists.newArrayList();
        if (ListUtils.isNotEmpty(dayStatisticInfoList)) {
            dayStatisticInfoList.stream().forEach(item -> {
                // 横轴日期处理
                String statisticDate = this.statisticDate(item);
                rechargeConsumeNumCoordinateVos.add(MerchantSummaryCoordinateVo.builder().horizontalAxis(statisticDate)
                        .verticalAxis(String.valueOf(item.getRechargeConsumeNum())).build());
                unRechargeConsumeNumCoordinateVos
                        .add(MerchantSummaryCoordinateVo.builder().horizontalAxis(statisticDate)
                                .verticalAxis(String.valueOf(item.getUnRechargeConsumeNum())).build());
                newRechargeNumCoordinateVos.add(MerchantSummaryCoordinateVo.builder().horizontalAxis(statisticDate)
                        .verticalAxis(String.valueOf(item.getNewRechargeNum())).build());
                newUnRechargeNumCoordinateVos.add(MerchantSummaryCoordinateVo.builder().horizontalAxis(statisticDate)
                        .verticalAxis(String.valueOf(item.getNewUnRechargeNum())).build());
            });
        }
        // 上周期
        // 充值会员消费人数
        int rechargeConsumeNumTotalLast = statisticInfoLast.getRechargeConsumeNum();
        // 新增会员人数
        int newRechargeNumTotalLast = statisticInfoLast.getNewRechargeNum();
        // 非充值会员消费人数
        int unRechargeConsumeNumTotalLast = statisticInfoLast.getUnRechargeConsumeNum();
        // 新增普通会员人数
        int newUnRechargeNumTotalLast = statisticInfoLast.getNewUnRechargeNum();
        MerchantSummaryConsumerFlowVo consumerFlowVo = new MerchantSummaryConsumerFlowVo();
        // 充值会员消费人数同比
        consumerFlowVo
                .setRechargeConsumeNumRatio(this.computeData(rechargeConsumeNumTotal, rechargeConsumeNumTotalLast));
        // 非充值会员消费人数同比
        consumerFlowVo.setUnRechargeConsumeNumRatio(
                this.computeData(unRechargeConsumeNumTotal, unRechargeConsumeNumTotalLast));
        // 新增会员人数同比
        consumerFlowVo.setNewRechargeNumRadio(this.computeData(newRechargeNumTotal, newRechargeNumTotalLast));
        // 普通会员人数同比
        consumerFlowVo.setNewUnRechargeNumRadio(this.computeData(newUnRechargeNumTotal, newUnRechargeNumTotalLast));
        consumerFlowVo.setRechargeConsumeNumTotal(rechargeConsumeNumTotal);
        consumerFlowVo.setUnRechargeConsumeNumTotal(unRechargeConsumeNumTotal);
        consumerFlowVo.setNewRechargeNumTotal(newRechargeNumTotal);
        consumerFlowVo.setNewUnRechargeNumTotal(newUnRechargeNumTotal);
        consumerFlowVo.setRechargeConsumeNumCoordinateVos(rechargeConsumeNumCoordinateVos);
        consumerFlowVo.setUnRechargeConsumeNumCoordinateVos(unRechargeConsumeNumCoordinateVos);
        consumerFlowVo.setNewRechargeNumCoordinateVos(newRechargeNumCoordinateVos);
        consumerFlowVo.setNewUnRechargeNumCoordinateVos(newUnRechargeNumCoordinateVos);
        
        //*************************************************** 折扣 ************************************************//
        // 本周期
        // 折扣消费人数
        int discountConsumeNum = statisticInfo.getDiscountConsumeNum();
        // 普通消费人数
        int unDiscountConsumeNum = statisticInfo.getUnRechargeConsumeNum();
        // 新增折扣卡消费人数
        int newDiscountConsumeNum = statisticInfo.getNewDiscountNum();
        // 新增普通会员人数
        int newUnDiscountConsumeNum = statisticInfo.getNewUnRechargeNum();

        // 各数据坐标系数
        List<MerchantSummaryCoordinateVo> unRechargeNumCoordinateVos = Lists.newArrayList();
        List<MerchantSummaryCoordinateVo> discountConsumeNumCoordinateVos = Lists.newArrayList();
        List<MerchantSummaryCoordinateVo> newDiscountNumCoordinateVos = Lists.newArrayList();
        List<MerchantSummaryCoordinateVo> newUnRechargeVos = Lists.newArrayList();
        if (ListUtils.isNotEmpty(dayStatisticInfoList)) {
            dayStatisticInfoList.stream().forEach(item -> {
                // 横轴日期处理
                String statisticDate = this.statisticDate(item);
                unRechargeNumCoordinateVos.add(MerchantSummaryCoordinateVo.builder().horizontalAxis(statisticDate)
                        .verticalAxis(String.valueOf(item.getUnRechargeConsumeNum())).build());
                discountConsumeNumCoordinateVos.add(MerchantSummaryCoordinateVo.builder().horizontalAxis(statisticDate)
                        .verticalAxis(String.valueOf(item.getDiscountConsumeNum())).build());
                newDiscountNumCoordinateVos.add(MerchantSummaryCoordinateVo.builder().horizontalAxis(statisticDate)
                        .verticalAxis(String.valueOf(item.getNewDiscountNum())).build());
                newUnRechargeVos.add(MerchantSummaryCoordinateVo.builder().horizontalAxis(statisticDate)
                        .verticalAxis(String.valueOf(item.getNewUnRechargeNum())).build());
            });
        }
        // 上周期
        // 折扣消费会员人数
        int discountConsumeNumLast = statisticInfoLast.getDiscountConsumeNum();
        // 普通消费人数
        int unDiscountConsumeNumLast = statisticInfoLast.getUnRechargeConsumeNum();
        // 新增折扣消费人数
        int newDiscountNumTotalLast = statisticInfoLast.getNewDiscountNum();
        // 新增普通会员人数
        int newUnDiscountConsumeNumLast = statisticInfoLast.getNewUnRechargeNum();

        // 折扣会员人数同比
        consumerFlowVo.setDiscountConsumeNumRatio(this.computeData(discountConsumeNum,discountConsumeNumLast));
        // 普通会员人数同比
        consumerFlowVo.setUnRechargeConsumeNumRatio(this.computeData(unDiscountConsumeNum,unDiscountConsumeNumLast));
        // 新增会员人数同比
        consumerFlowVo.setNewDiscountNumRadio(this.computeData(newDiscountConsumeNum, newDiscountNumTotalLast));
        // 新增普通人数同比
        consumerFlowVo.setNewUnRechargeNumRadio(this.computeData(newUnDiscountConsumeNum, newUnDiscountConsumeNumLast));

        consumerFlowVo.setDiscountConsumeNumTotal(discountConsumeNum);
        consumerFlowVo.setUnRechargeConsumeNumTotal(unDiscountConsumeNum);
        consumerFlowVo.setNewDiscountNumTotal(newDiscountConsumeNum);
        consumerFlowVo.setNewUnRechargeNumTotal(newUnDiscountConsumeNum);
        consumerFlowVo.setUnRechargeConsumeNumCoordinateVos(unRechargeNumCoordinateVos);
        consumerFlowVo.setDiscountConsumeNumCoordinateVos(discountConsumeNumCoordinateVos);
        consumerFlowVo.setNewUnRechargeNumCoordinateVos(newUnRechargeVos);
        consumerFlowVo.setNewDiscountNumCoordinateVos(newDiscountNumCoordinateVos);
        return consumerFlowVo;
    }
	/******************对应的代码逻辑**********************/
}

这里顺便记录一些小小的统计常用的工具方法 大家也可以使用呀~

    /**
     * 计算百分比
     *
     * @param recent 除数
     * @param last 被除数
     * @return 比例
     */
    private int computeData(int recent, int last) {
        if (0 == last) {
            if (0 != recent) {
                return 100;
            }
            return 0;
        }
        return new BigDecimal(recent).divide(new BigDecimal(last), 2, RoundingMode.DOWN).subtract(new BigDecimal(1))
                .multiply(new BigDecimal(100)).intValue();
    }

    /**
     * 横轴日期转换
     *
     * @param dayStatisticInfo 每日基础数据
     * @return
     */
    private String statisticDate(MileMerchantDayStatisticInfo dayStatisticInfo) {
        if (!ObjectUtils.isEmpty(dayStatisticInfo.getStatisticDate())) {
            return dayStatisticInfo.getStatisticDate().format(DateTimeFormatter.ofPattern("MM/dd"));
        }
        return StringUtils.EMPTY;
    }
    /**
     * 根据天数查询每日数据
     *
     * @param inMno
     * @param days 天数
     * @return
     */
    private List<MileMerchantDayStatisticInfo> conditionDayStatistic(String inMno, int days) {
        List<MileMerchantDayStatisticInfo> result = Lists.newArrayList();
        // 近7天每日数据
        LocalDate now = LocalDate.now();
        LocalDate lastDay = now.minusDays(days);
        List<MileMerchantDayStatisticInfo> dayStatisticInfos = dayStatisticInfoService.findByInMnoAndDate(inMno,
                lastDay.format(DateTimeFormatter.ISO_LOCAL_DATE), now.format(DateTimeFormatter.ISO_LOCAL_DATE));
        if (dayStatisticInfos.size() != days) {
            for (int i = days; i > 0; i--) {
                LocalDate date = now.minusDays(i);
                this.dayStatisticInfo(result, dayStatisticInfos, date);
            }
        } else {
            result.addAll(dayStatisticInfos);
        }
        return result;
    }
    /**
     * 根据月份查询每日数据
     *
     * @param inMno
     * @param month
     * @return
     */
    private List<MileMerchantDayStatisticInfo> monthForDayStatisticInfo(String inMno, LocalDate month) {
        List<MileMerchantDayStatisticInfo> result = Lists.newArrayList();
        // 当前月首日
        LocalDate first = month.with(TemporalAdjusters.firstDayOfMonth());
        // 下个月首日
        LocalDate last = first.plusMonths(1);
        long distance = ChronoUnit.DAYS.between(first, last);
        if (distance < 1) {
            return result;
        }
        List<MileMerchantDayStatisticInfo> dayStatisticInfos = dayStatisticInfoService.findByInMnoAndDate(inMno,
                first.format(DateTimeFormatter.ISO_LOCAL_DATE), last.format(DateTimeFormatter.ISO_LOCAL_DATE));
        Stream.iterate(first, d -> d.plusDays(1)).limit(distance)
                .forEach(f -> this.dayStatisticInfo(result, dayStatisticInfos, f));
        return result;
    }
    /**
     * 获取指定天的开始时间
     *
     * @param spaceDay
     * @return
     */
    private String obtainSpecifiedDayBeginTime(int spaceDay) {
        return LocalDateTime.of(LocalDate.now().minusDays(spaceDay), LocalTime.MIN)
                .format(DateTimeFormatter.ofPattern(DateUtils.DATE_FORMAT_DATETIME));
    }

    /**
     * 获取指定天的结束时间
     *
     * @param spaceDay
     * @return
     */
    private String obtainSpecifiedDayEndTime(int spaceDay) {
        return LocalDateTime.of(LocalDate.now().minusDays(spaceDay), LocalTime.MAX)
                .format(DateTimeFormatter.ofPattern(DateUtils.DATE_FORMAT_DATETIME));
    }

    /**
     * 获取指定月的开始时间
     *
     * @param day
     * @return
     */
    private String obtainSpecifiedMonthBeginTime(int day) {
        return LocalDateTime.now().minusDays(day).with(TemporalAdjusters.firstDayOfMonth()).withHour(0)
                .withMinute(0).withSecond(0).format(DateTimeFormatter.ofPattern(DateUtils.DATE_FORMAT_DATETIME));

    }

    /**
     * 获取指定月的结束时间
     *
     * @param day
     * @return
     */
    private String obtainSpecifiedMonthEndTime(int day) {
        return LocalDateTime.now().minusDays(day).with(TemporalAdjusters.lastDayOfMonth()).withHour(23)
                .withMinute(59).withSecond(59).format(DateTimeFormatter.ofPattern(DateUtils.DATE_FORMAT_DATETIME));
    }

    /**
     * 获取指定天指定月的结束时间
     *
     * @param day
     * @param month
     * @return
     */
    private String obtainSpecifiedMonthFilterEndTime(int day, int month) {
        return LocalDateTime.now().minusMonths(month).minusDays(day).with(TemporalAdjusters.lastDayOfMonth()).withHour(23)
                .withMinute(59).withSecond(59).format(DateTimeFormatter.ofPattern(DateUtils.DATE_FORMAT_DATETIME));
    }

码字不易,转载注明。谢谢各位大佬啦

你可能感兴趣的:(设计模式,spring,设计模式)