package com.slodon.b2b2c.controller.statistics.admin;

import com.slodon.b2b2c.core.controller.BaseController;
import com.slodon.b2b2c.core.response.JsonResult;
import com.slodon.b2b2c.core.response.PageVO;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.TimeUtil;
import com.slodon.b2b2c.core.util.WebUtil;
import com.slodon.b2b2c.enums.StatsTimeType;
import com.slodon.b2b2c.model.statistics.CategoryDayModel;
import com.slodon.b2b2c.model.statistics.GoodsDayModel;
import com.slodon.b2b2c.statistics.example.CategoryDayExample;
import com.slodon.b2b2c.statistics.example.GoodsDayExample;
import com.slodon.b2b2c.statistics.pojo.CategoryDay;
import com.slodon.b2b2c.statistics.pojo.GoodsDay;
import com.slodon.b2b2c.statistics.pojo.base.CategoryBase;
import com.slodon.b2b2c.statistics.pojo.base.GoodsBase;
import com.slodon.b2b2c.util.StatsModelUtil;
import com.slodon.b2b2c.vo.statistics.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;

@Api(tags = "admin-商品品类")
@RestController
@RequestMapping("v3/statistics/admin/category/analysis")
public class AdminCategoryAnalysisController extends BaseController {

    @Resource
    private CategoryDayModel categoryDayModel;
    @Resource
    private GoodsDayModel goodsDayModel;
    @Resource
    private StatsModelUtil statsModelUtil;

    @ApiOperation("TOP10品类销售趋势")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "sort", value = "排序:1-销售额；2-销量 默认不传按销售额降序")
    })
    @GetMapping("categorySalesRank")
    public JsonResult<List<CategoryChangeTrendVO>> categorySalesRank(HttpServletRequest request, Date startTime, Date endTime, Integer sort) {
        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, true);
        //如果查询24小时，先按天查询前十条数据
        StatsTimeType timeType2 = timeType;
        if (timeType == StatsTimeType.HOUR) {
            timeType2 = StatsTimeType.DAY;
        }
        List<? extends CategoryBase> list = statsModelUtil.getCategoryList(timeType2, startTime, endTime, sort, "sale");
        List<CategoryChangeTrendVO> vos = getCategorySalesRank(list, timeType, startTime, endTime);
        return SldResponse.success(vos);
    }

    @ApiOperation("品类销售额占比")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true)
    })
    @GetMapping("categorySaleAmountPercent")
    public JsonResult<List<CategoryPercentVO>> categorySaleAmountPercent(HttpServletRequest request, Date startTime, Date endTime) {
        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, false);
        List<? extends CategoryBase> list = statsModelUtil.getCategoryList(timeType, startTime, endTime, 1, "sale");
        List<CategoryPercentVO> vos = getCategorySaleAmountPercent(list);
        return SldResponse.success(vos);
    }

    @ApiOperation("品类退货占比")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true)
    })
    @GetMapping("categoryReturnNumPercent")
    public JsonResult<List<CategoryPercentVO>> categoryReturnNumPercent(HttpServletRequest request, Date startTime, Date endTime) {
        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, false);
        List<? extends CategoryBase> list = statsModelUtil.getCategoryList(timeType, startTime, endTime, 1, "sale");
        List<CategoryPercentVO> vos = getCategoryReturnNumPercent(list);
        return SldResponse.success(vos);
    }

    @ApiOperation("品类销售报表(按天)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "categoryName", value = "品类名称"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:stats_time-时间;order_submit_num-下单数;order_submit_amount-下单金额;" +
                    "order_pay_num-支付订单数;sale_amount-销售额;sale_amount-销售额占比;return_num-退单数;return_amount-退单金额;默认按时间降序排序"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("dayReport")
    public JsonResult<PageVO<CategoryReportDayVO>> dayReport(HttpServletRequest request, Date startTime, Date endTime, String categoryName,
                                                             @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                                             @RequestParam(value = "sort", required = false, defaultValue = "stats_time") String sort) {
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        CategoryDayExample example = new CategoryDayExample();
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setCategoryNameLike(categoryName);
        example.setOrderBy(sort + " " + type);
        List<CategoryDay> list = categoryDayModel.getCategoryDayList(example, pager);
        List<CategoryReportDayVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            //总销售额，用于计算各品类占比
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (CategoryDay categoryDay : list) {
                totalAmount = totalAmount.add(categoryDay.getSaleAmount());
            }
            if (totalAmount.compareTo(BigDecimal.ZERO) > 0) {
                for (CategoryDay categoryDay : list) {
                    CategoryReportDayVO vo = new CategoryReportDayVO(categoryDay);
                    BigDecimal per = categoryDay.getSaleAmount().multiply(new BigDecimal(100)).divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP);
                    vo.setSaleAmountPercent(per.toString() + "%");
                    vo.setGoodsName(getGoodsName(categoryDay.getCategoryId(), TimeUtil.getDayStartFormatYMDHMS(categoryDay.getStatsTime()),
                            TimeUtil.getDayEndFormatYMDHMS(categoryDay.getStatsTime())));
                    vos.add(vo);
                }
            }
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("品类销售报表(按品类)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "categoryName", value = "品类名称"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:orderSubmitAmount-下单金额;orderSubmitNum-下单数;orderPayNum-支付订单数;" +
                    "saleAmount-销售额;saleAmount-销售额占比;returnNum-退单数;returnAmount-退单金额;默认按下单金额降序排序"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("categoryReport")
    public JsonResult<PageVO<CategoryReportVO>> categoryReport(HttpServletRequest request, Date startTime, Date endTime, String categoryName,
                                                               @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                                               @RequestParam(value = "sort", required = false, defaultValue = "orderSubmitAmount") String sort) {
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        CategoryDayExample example = new CategoryDayExample();
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setCategoryNameLike(categoryName);
        example.setOrderBy(sort + " " + type);
        List<CategoryBase> list = categoryDayModel.getCategoryList(example, pager);
        List<CategoryReportVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            //总销售额，用于计算各品类占比
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (CategoryBase categoryBase : list) {
                totalAmount = totalAmount.add(categoryBase.getSaleAmount());
            }
            if (totalAmount.compareTo(BigDecimal.ZERO) > 0) {
                for (CategoryBase categoryBase : list) {
                    CategoryReportVO vo = new CategoryReportVO(categoryBase);
                    BigDecimal per = categoryBase.getSaleAmount().multiply(new BigDecimal(100)).divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP);
                    vo.setSaleAmountPercent(per.toString() + "%");
                    vo.setGoodsName(getGoodsName(categoryBase.getCategoryId(), startTime, endTime));
                    vos.add(vo);
                }
            }
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("导出报表(按天)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "categoryName", value = "品类名称"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:stats_time-时间;order_submit_num-下单数;order_submit_amount-下单金额;" +
                    "order_pay_num-支付订单数;sale_amount-销售额;sale_amount-销售额占比;return_num-退单数;return_amount-退单金额;默认按时间降序排序")
    })
    @GetMapping("dayExport")
    public JsonResult dayExport(HttpServletRequest request, HttpServletResponse response, Date startTime, Date endTime, String categoryName,
                                @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                @RequestParam(value = "sort", required = false, defaultValue = "stats_time") String sort) {
        CategoryDayExample example = new CategoryDayExample();
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setCategoryNameLike(categoryName);
        example.setOrderBy(sort + " " + type);
        List<CategoryDay> list = categoryDayModel.getCategoryDayList(example, null);
        List<CategoryReportDayVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            //总销售额，用于计算各品类占比
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (CategoryDay categoryDay : list) {
                totalAmount = totalAmount.add(categoryDay.getSaleAmount());
            }
            if (totalAmount.compareTo(BigDecimal.ZERO) > 0) {
                for (CategoryDay categoryDay : list) {
                    CategoryReportDayVO vo = new CategoryReportDayVO(categoryDay);
                    BigDecimal per = categoryDay.getSaleAmount().multiply(new BigDecimal(100)).divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP);
                    vo.setSaleAmountPercent(per.toString() + "%");
                    vo.setGoodsName(getGoodsName(categoryDay.getCategoryId(), TimeUtil.getDayStartFormatYMDHMS(categoryDay.getStatsTime()),
                            TimeUtil.getDayEndFormatYMDHMS(categoryDay.getStatsTime())));
                    vos.add(vo);
                }
            }
        }
        categoryDayModel.categoryReportDayExport(request, response, vos);
        return null;
    }

    @ApiOperation("导出报表(按品类)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "categoryName", value = "品类名称"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:orderSubmitAmount-下单金额;orderSubmitNum-下单数;orderPayNum-支付订单数;" +
                    "saleAmount-销售额;saleAmount-销售额占比;returnNum-退单数;returnAmount-退单金额;默认按下单金额降序排序")
    })
    @GetMapping("categoryExport")
    public JsonResult categoryExport(HttpServletRequest request, HttpServletResponse response, Date startTime, Date endTime, String categoryName,
                                     @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                     @RequestParam(value = "sort", required = false, defaultValue = "orderSubmitAmount") String sort) {
        CategoryDayExample example = new CategoryDayExample();
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setCategoryNameLike(categoryName);
        example.setOrderBy(sort + " " + type);
        List<CategoryBase> list = categoryDayModel.getCategoryList(example, null);
        List<CategoryReportVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            //总销售额，用于计算各品类占比
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (CategoryBase categoryBase : list) {
                totalAmount = totalAmount.add(categoryBase.getSaleAmount());
            }
            if (totalAmount.compareTo(BigDecimal.ZERO) > 0) {
                for (CategoryBase categoryBase : list) {
                    CategoryReportVO vo = new CategoryReportVO(categoryBase);
                    BigDecimal per = categoryBase.getSaleAmount().multiply(new BigDecimal(100)).divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP);
                    vo.setSaleAmountPercent(per.toString() + "%");
                    vo.setGoodsName(getGoodsName(categoryBase.getCategoryId(), startTime, endTime));
                    vos.add(vo);
                }
            }
        }
        categoryDayModel.categoryReportExport(request, response, vos);
        return null;
    }

    /**
     * 获取销冠商品名称
     *
     * @param categoryId
     * @param startTime
     * @param endTime
     * @return
     */
    public String getGoodsName(Integer categoryId, Date startTime, Date endTime) {
        String goodsName = null;
        GoodsDayExample example = new GoodsDayExample();
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setGoodsCategoryId1(categoryId);
        List<GoodsDay> list = goodsDayModel.getGoodsDayList(example, null);
        if (!CollectionUtils.isEmpty(list)) {
            //根据stream流获取最大销售额的对象
            GoodsDay goodsDay = list.stream().max(Comparator.comparing(GoodsBase::getSaleAmount)).get();
            goodsName = goodsDay.getGoodsName();
        }
        return goodsName;
    }

    /**
     * 品类退货占比
     *
     * @param list
     * @return
     */
    public List<CategoryPercentVO> getCategoryReturnNumPercent(List<? extends CategoryBase> list) {
        List<CategoryPercentVO> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            //总退货数，用于计算各品类占比
            Integer totalNum = 0;
            for (CategoryBase categoryBase : list) {
                totalNum += categoryBase.getReturnNum();
            }
            //如果为0直接返回空数组
            if (totalNum == 0) {
                return result;
            }

            //循环列表,构造返回数据
            if (list.size() <= 10) {
                //品类少于等于10个，直接记录各品类的销售占比
                for (CategoryBase categoryBase : list) {
                    if (categoryBase.getReturnNum() > 0) {
                        CategoryPercentVO vo = new CategoryPercentVO();
                        vo.setCategoryName(categoryBase.getCategoryName());
                        vo.setReturnNum(categoryBase.getReturnNum());
                        BigDecimal per = new BigDecimal(categoryBase.getReturnNum()).multiply(new BigDecimal(100)).divide(new BigDecimal(totalNum), 2, BigDecimal.ROUND_HALF_UP);
                        vo.setReturnNumPercent(per.toString() + "%");
                        result.add(vo);
                    }
                }
            } else {
                //品类大于10，记录前10个，剩余记为其他
                //其他品类占比
                Integer otherNum = totalNum;
                BigDecimal otherPer = new BigDecimal(100);
                for (int i = 0; i < list.size() && i < 10; i++) {
                    CategoryBase categoryBase = list.get(i);

                    if (categoryBase.getReturnNum() > 0) {
                        CategoryPercentVO vo = new CategoryPercentVO();
                        vo.setCategoryName(categoryBase.getCategoryName());
                        vo.setReturnNum(categoryBase.getReturnNum());
                        BigDecimal per = new BigDecimal(categoryBase.getReturnNum()).multiply(new BigDecimal(100)).divide(new BigDecimal(totalNum), 2, BigDecimal.ROUND_HALF_UP);
                        vo.setReturnNumPercent(per.toString() + "%");
                        result.add(vo);

                        //数据计算
                        otherNum = otherNum - categoryBase.getReturnNum();
                        otherPer = otherPer.subtract(per);
                    }
                }
                //其他
                if (otherNum > 0) {
                    CategoryPercentVO vo = new CategoryPercentVO();
                    vo.setCategoryName("其他");
                    vo.setReturnNum(otherNum);
                    vo.setReturnNumPercent(otherPer.toString() + "%");
                    result.add(vo);
                }
            }
        }
        return result;
    }

    /**
     * 品类销售额占比
     *
     * @param list
     * @return
     */
    public List<CategoryPercentVO> getCategorySaleAmountPercent(List<? extends CategoryBase> list) {
        List<CategoryPercentVO> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            //总销售额，用于计算各品类占比
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (CategoryBase categoryBase : list) {
                totalAmount = totalAmount.add(categoryBase.getSaleAmount());
            }
            //如果为0直接返回空数组
            if (totalAmount.compareTo(BigDecimal.ZERO) == 0) {
                return result;
            }

            //循环列表,构造返回数据
            if (list.size() <= 10) {
                //品类少于等于10个，直接记录各品类的销售占比
                for (CategoryBase categoryBase : list) {
                    if (categoryBase.getSaleAmount().compareTo(BigDecimal.ZERO) > 0) {
                        CategoryPercentVO vo = new CategoryPercentVO();
                        vo.setCategoryName(categoryBase.getCategoryName());
                        vo.setSaleAmount(categoryBase.getSaleAmount());
                        BigDecimal per = categoryBase.getSaleAmount().multiply(new BigDecimal(100)).divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP);
                        vo.setSaleAmountPercent(per.toString() + "%");
                        result.add(vo);
                    }
                }
            } else {
                //品类大于10，记录前10个，剩余记为其他
                //其他品类占比
                BigDecimal otherAmount = totalAmount;
                BigDecimal otherPer = new BigDecimal(100);
                for (int i = 0; i < list.size() && i < 10; i++) {
                    CategoryBase categoryBase = list.get(i);

                    if (categoryBase.getSaleAmount().compareTo(BigDecimal.ZERO) > 0) {
                        CategoryPercentVO vo = new CategoryPercentVO();
                        vo.setCategoryName(categoryBase.getCategoryName());
                        vo.setSaleAmount(categoryBase.getSaleAmount());
                        BigDecimal per = categoryBase.getSaleAmount().multiply(new BigDecimal(100)).divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP);
                        vo.setSaleAmountPercent(per.toString() + "%");
                        result.add(vo);

                        //数据计算
                        otherAmount = otherAmount.subtract(categoryBase.getSaleAmount());
                        otherPer = otherPer.subtract(per);
                    }
                }
                //其他
                if (otherAmount.compareTo(BigDecimal.ZERO) > 0) {
                    CategoryPercentVO vo = new CategoryPercentVO();
                    vo.setCategoryName("其他");
                    vo.setSaleAmount(otherAmount);
                    vo.setSaleAmountPercent(otherPer.toString() + "%");
                    result.add(vo);
                }
            }
        }
        return result;
    }

    /**
     * 变化趋势
     *
     * @param list
     * @return
     */
    public List<CategoryChangeTrendVO> getCategorySalesRank(List<? extends CategoryBase> list, StatsTimeType timeType, Date startTime, Date endTime) {
        List<CategoryChangeTrendVO> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            //按照统计时间分组
            Map<String, List<CategoryChangeTrendVO.CategoryTrendVO>> timeMap = new HashMap<>();
            //商品id集合
            StringBuilder categoryIds = new StringBuilder();
            for (CategoryBase categoryBase : list) {
                categoryIds.append(",").append(categoryBase.getCategoryId());
            }
            //查询销售信息
            List<SalesTrendVO> trendList = statsModelUtil.getCategoryTrendList(timeType, startTime, endTime, categoryIds.toString().substring(1));
            if (!CollectionUtils.isEmpty(trendList)) {
                switch (timeType) {
                    case HOUR:
                        timeMap = getCategoryHourList(trendList);
                        break;
                    case DAY:
                    case WEEK:
                    case MONTH:
                        timeMap = getCategoryDayList(trendList, startTime, endTime);
                        break;
                    case YEAR:
                        timeMap = getCategoryMonthList(trendList);
                        break;
                }
            }
            timeMap.forEach((statsTime, CategoryList) -> {
                CategoryChangeTrendVO vo = new CategoryChangeTrendVO();
                vo.setStatsTime(statsTime);
                vo.setCategoryList(CategoryList);
                result.add(vo);
            });
            Collections.sort(result);
        }
        return result;
    }

    /**
     * 获取24小时数据
     *
     * @param list
     * @return
     */
    public Map<String, List<CategoryChangeTrendVO.CategoryTrendVO>> getCategoryHourList(List<SalesTrendVO> list) {
        Map<String, List<CategoryChangeTrendVO.CategoryTrendVO>> result = new HashMap<>();
        if (CollectionUtils.isEmpty(list)) {
            return result;
        }
        //构造现有分类数据
        Map<Integer, SalesTrendVO> categoryMap = new HashMap<>();
        List<Integer> categoryIdList = new ArrayList<>();
        for (SalesTrendVO trendVO : list) {
            categoryMap.put(trendVO.getCategoryId(), trendVO);
            categoryIdList.add(trendVO.getCategoryId());
        }
        //构造现有时间段数据
        Map<String, SalesTrendVO> map = new HashMap<>();
        list.forEach(salesTrendVO -> {
            map.put(salesTrendVO.getStatsTime() + "," + salesTrendVO.getCategoryId(), salesTrendVO);
        });
        //构造全部时间段数据
        List<String> timeCategoryIdsList = new ArrayList<>();
        for (int i = 0; i < 24; i++) {
            String timeStr = i > 9 ? i + ":00" : "0" + i + ":00";
            categoryIdList.forEach(categoryId -> {
                timeCategoryIdsList.add(timeStr + "," + categoryId);
            });
        }
        //补充缺少的时间段数据
        timeCategoryIdsList.forEach(timeCategoryId -> {
            if (!map.containsKey(timeCategoryId)) {
                SalesTrendVO trendVO = categoryMap.get(Integer.parseInt(timeCategoryId.split(",")[1]));
                SalesTrendVO salesTrendVO = new SalesTrendVO(trendVO.getCategoryId(), trendVO.getCategoryName());
                salesTrendVO.setOrderPayAmount(new BigDecimal("0.00"));
                salesTrendVO.setOrderPayNum(0);
                map.put(timeCategoryId, salesTrendVO);
            }
        });
        //遍历全部时间段数据
        map.forEach((timeCategoryId, vo) -> {
            CategoryChangeTrendVO.CategoryTrendVO categoryTrendVO = new CategoryChangeTrendVO.CategoryTrendVO();
            categoryTrendVO.setCategoryId(vo.getCategoryId());
            categoryTrendVO.setCategoryName(vo.getCategoryName());
            categoryTrendVO.setSaleAmount(vo.getOrderPayAmount());
            categoryTrendVO.setSaleNum(vo.getOrderPayNum());

            String timeStr = timeCategoryId.split(",")[0];
            //按照统计时间分组
            if (result.containsKey(timeStr)) {
                result.get(timeStr).add(categoryTrendVO);
            } else {
                //分类列表
                List<CategoryChangeTrendVO.CategoryTrendVO> categoryList = new ArrayList<>();
                categoryList.add(categoryTrendVO);

                result.put(timeStr, categoryList);
            }
        });
        return result;
    }

    /**
     * 获取n天数据
     *
     * @param list
     * @param startTime
     * @param endTime
     * @return
     */
    public Map<String, List<CategoryChangeTrendVO.CategoryTrendVO>> getCategoryDayList(List<SalesTrendVO> list, Date startTime, Date endTime) {
        Map<String, List<CategoryChangeTrendVO.CategoryTrendVO>> result = new HashMap<>();
        if (CollectionUtils.isEmpty(list)) {
            return result;
        }
        //构造现有分类数据
        Map<Integer, SalesTrendVO> categoryMap = new HashMap<>();
        List<Integer> categoryIdList = new ArrayList<>();
        for (SalesTrendVO trendVO : list) {
            categoryMap.put(trendVO.getCategoryId(), trendVO);
            categoryIdList.add(trendVO.getCategoryId());
        }
        //构造现有时间段数据
        Map<String, SalesTrendVO> map = new HashMap<>();
        list.forEach(salesTrendVO -> {
            map.put(salesTrendVO.getStatsTime() + "," + salesTrendVO.getCategoryId(), salesTrendVO);
        });
        //构造全部时间段数据
        List<String> timeCategoryIdsList = new ArrayList<>();
        for (Date i = startTime; i.before(endTime); i = TimeUtil.getDayAgoDate(i, 1)) {
            String timeStr = TimeUtil.dealMonthAndDay(i);
            categoryIdList.forEach(goodsId -> {
                timeCategoryIdsList.add(timeStr + "," + goodsId);
            });
        }
        //补充缺少的时间段数据
        timeCategoryIdsList.forEach(timeCategoryId -> {
            if (!map.containsKey(timeCategoryId)) {
                SalesTrendVO trendVO = categoryMap.get(Integer.parseInt(timeCategoryId.split(",")[1]));
                SalesTrendVO salesTrendVO = new SalesTrendVO(trendVO.getCategoryId(), trendVO.getCategoryName());
                salesTrendVO.setOrderPayAmount(new BigDecimal("0.00"));
                salesTrendVO.setOrderPayNum(0);
                map.put(timeCategoryId, salesTrendVO);
            }
        });
        //遍历全部时间段数据
        map.forEach((timeCategoryId, vo) -> {
            CategoryChangeTrendVO.CategoryTrendVO categoryTrendVO = new CategoryChangeTrendVO.CategoryTrendVO();
            categoryTrendVO.setCategoryId(vo.getCategoryId());
            categoryTrendVO.setCategoryName(vo.getCategoryName());
            categoryTrendVO.setSaleAmount(vo.getOrderPayAmount());
            categoryTrendVO.setSaleNum(vo.getOrderPayNum());

            String timeStr = timeCategoryId.split(",")[0];
            //按照统计时间分组
            if (result.containsKey(timeStr)) {
                result.get(timeStr).add(categoryTrendVO);
            } else {
                //分类列表
                List<CategoryChangeTrendVO.CategoryTrendVO> categoryList = new ArrayList<>();
                categoryList.add(categoryTrendVO);

                result.put(timeStr, categoryList);
            }
        });
        return result;
    }

    /**
     * 获取12个月数据
     *
     * @param list
     * @return
     */
    public Map<String, List<CategoryChangeTrendVO.CategoryTrendVO>> getCategoryMonthList(List<SalesTrendVO> list) {
        Map<String, List<CategoryChangeTrendVO.CategoryTrendVO>> result = new HashMap<>();
        if (CollectionUtils.isEmpty(list)) {
            return result;
        }
        //构造现有分类数据
        Map<Integer, SalesTrendVO> categoryMap = new HashMap<>();
        List<Integer> categoryIdList = new ArrayList<>();
        for (SalesTrendVO trendVO : list) {
            categoryMap.put(trendVO.getCategoryId(), trendVO);
            categoryIdList.add(trendVO.getCategoryId());
        }
        //构造现有时间段数据
        Map<String, SalesTrendVO> map = new HashMap<>();
        list.forEach(salesTrendVO -> {
            map.put(salesTrendVO.getStatsTime() + "," + salesTrendVO.getCategoryId(), salesTrendVO);
        });
        //构造全部时间段数据
        List<String> timeCategoryIdsList = new ArrayList<>();
        for (int i = 1; i <= 12; i++) {
            String timeStr = i > 9 ? i + "" : "0" + i;
            categoryIdList.forEach(categoryId -> {
                timeCategoryIdsList.add(timeStr + "," + categoryId);
            });
        }
        //补充缺少的时间段数据
        timeCategoryIdsList.forEach(timeCategoryId -> {
            if (!map.containsKey(timeCategoryId)) {
                SalesTrendVO trendVO = categoryMap.get(Integer.parseInt(timeCategoryId.split(",")[1]));
                SalesTrendVO salesTrendVO = new SalesTrendVO(trendVO.getCategoryId(), trendVO.getCategoryName());
                salesTrendVO.setOrderPayAmount(new BigDecimal("0.00"));
                salesTrendVO.setOrderPayNum(0);
                map.put(timeCategoryId, salesTrendVO);
            }
        });
        //遍历全部时间段数据
        map.forEach((timeCategoryId, vo) -> {
            CategoryChangeTrendVO.CategoryTrendVO categoryTrendVO = new CategoryChangeTrendVO.CategoryTrendVO();
            categoryTrendVO.setCategoryId(vo.getCategoryId());
            categoryTrendVO.setCategoryName(vo.getCategoryName());
            categoryTrendVO.setSaleAmount(vo.getOrderPayAmount());
            categoryTrendVO.setSaleNum(vo.getOrderPayNum());

            String timeStr = timeCategoryId.split(",")[0];
            //按照统计时间分组
            if (result.containsKey(timeStr)) {
                result.get(timeStr).add(categoryTrendVO);
            } else {
                //分类列表
                List<CategoryChangeTrendVO.CategoryTrendVO> categoryList = new ArrayList<>();
                categoryList.add(categoryTrendVO);

                result.put(timeStr, categoryList);
            }
        });
        return result;
    }
}
