package com.pcloud.book.group.biz.impl;

import com.alibaba.fastjson.JSONObject;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.pcloud.appcenter.app.dto.AppDto;
import com.pcloud.appcenter.base.dto.AppPriceCacheDTO;
import com.pcloud.appcenter.cache.service.AppPriceCacheService;
import com.pcloud.audioapp.audioLesson.service.AudioLessonService;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.biz.BookBiz;
import com.pcloud.book.book.dao.BookDao;
import com.pcloud.book.book.dto.BookDto;
import com.pcloud.book.book.set.BookSet;
import com.pcloud.book.consumer.app.AppConsr;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.raystask.MainLineConsr;
import com.pcloud.book.consumer.resource.ProductConsr;
import com.pcloud.book.consumer.settlement.BookConsr;
import com.pcloud.book.consumer.settlement.SettlementConsr;
import com.pcloud.book.consumer.trade.TradeConsr;
import com.pcloud.book.consumer.user.AdviserConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.biz.BookGroupBiz;
import com.pcloud.book.group.biz.BookGroupClassifyBiz;

import com.pcloud.book.group.dao.*;
import com.pcloud.book.group.dto.*;
import com.pcloud.book.group.entity.BookGroup;
import com.pcloud.book.group.entity.JoinGroupCipher;
import com.pcloud.book.group.entity.TempletRelevance;
import com.pcloud.book.group.enums.LargTempletEnum;
import com.pcloud.book.group.vo.StatisticVO;

import com.pcloud.book.group.biz.GroupQrcodeBiz;

import com.pcloud.book.group.dao.AppClickRecordDao;
import com.pcloud.book.group.dao.AppTouchRecordDao;
import com.pcloud.book.group.dao.BookGroupClassifyDao;
import com.pcloud.book.group.dao.BookGroupDao;

import com.pcloud.book.group.vo.ClassifyAndGroupCountVO;

import com.pcloud.book.group.dto.*;
import com.pcloud.book.group.entity.BookGroup;

import com.pcloud.book.group.vo.*;
import com.pcloud.book.keywords.dao.BookKeywordDao;
import com.pcloud.book.keywords.enums.ReplyTypeEnum;
import com.pcloud.book.keywords.vo.ListKeywordVO;
import com.pcloud.book.util.common.ThreadPoolUtils;
import com.pcloud.channelcenter.qrcode.dto.GroupQrcodeVO;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.biz.MessageBiz;
import com.pcloud.common.core.constant.ProductTypeConstant;
import com.pcloud.common.core.constant.SystemCode;
import com.pcloud.common.core.dto.SendNotifyDto;
import com.pcloud.common.core.enums.NotifyOriginTypeEnum;
import com.pcloud.common.dto.ResponseDto;
import com.pcloud.common.dto.StoreFlowInfoDto;
import com.pcloud.common.entity.UploadResultInfo;
import com.pcloud.common.enums.AppTypeEnum;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.page.PageBean;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.*;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.QrcodeUtils;
import com.pcloud.common.utils.ResponseHandleUtil;
import com.pcloud.common.utils.export.excel.ExcelExportor;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.common.utils.zip.CompressUtils;
import com.pcloud.facade.tradecenter.dto.*;
import com.pcloud.labelcenter.label.service.LabelService;
import com.pcloud.liveapp.live.dto.ProductIdSearchDto;
import com.pcloud.liveapp.live.service.TimeTableService;
import com.pcloud.resourcecenter.product.dto.AddAppProductParamDTO;
import com.pcloud.resourcecenter.product.dto.ProductDto;
import com.pcloud.resourcecenter.product.dto.ProductTypeDto;
import com.pcloud.resourcecenter.product.dto.SpecificationDto;
import com.pcloud.resourcecenter.product.dto.UpdateAppProductParamDTO;
import com.pcloud.resourcecenter.product.entity.Product;
import com.pcloud.resourcecenter.product.service.ProductService;
import com.pcloud.resourcecenter.store.constants.StoreCons;

import com.pcloud.settlementcenter.record.dto.GetGroupClassifyIncomeDTO;
import com.pcloud.settlementcenter.record.dto.GetGroupQrcodeIncomeDTO;
import com.pcloud.settlementcenter.record.dto.GroupRescourceIncomeParamDTO;
import com.pcloud.settlementcenter.record.dto.ProductStaticUnderAppMapDTO;
import com.pcloud.settlementcenter.record.service.SettlementService;
import com.pcloud.videolesson.schedule.service.ScheduleService;
import com.pcloud.wechatgroup.group.dto.GroupMemberStatisDTO;
import com.pcloud.wechatgroup.group.service.GroupMemberService;

import com.pcloud.wechatgroup.selfrobot.dto.SelfRobotDTO;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.sun.tools.doclets.formats.html.markup.HtmlStyle.title;

/**
 * Description 社群书群二维码业务逻辑层接口实现类
 * Created by PENG on 2019/4/17.
 */
@Component("bookGroupBiz")
public class BookGroupBizImpl implements BookGroupBiz {
    private static final Logger LOGGER = LoggerFactory.getLogger(BookGroupBizImpl.class);

    private final static String DEFAULT_PRODUCT_COVER_IMG = "https://oss.5rs.me/oss/uploadfe/png/1c5da08d2c9598a5f0b0252acb84d8b8.png";

    @Value("${book.group.qrcode.domain}")
    private String bookGroupQrcodeDomain;

    @Autowired
    private BookGroupDao bookGroupDao;
    @Autowired
    private LabelService labelService;
    @Autowired
    private ProductService productService;
    @Autowired
    private AdviserConsr adviserConsr;
    @Autowired
    private BookBiz bookBiz;
    @Autowired
    private BookSet bookSet;
    @Autowired
    private BookDao bookDao;
    @Autowired
    private SettlementService settlementService;
    @Autowired
    private BookGroupClassifyBiz bookGroupClassifyBiz;
    @Autowired
    private GroupMemberService groupMemberService;
    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;
    @Autowired
    private AppTouchRecordDao appTouchRecordDao;
    @Autowired
    private AppClickRecordDao appClickRecordDao;
    @Autowired
    private SettlementConsr settlementConsr;
    @Autowired
    private TradeConsr tradeConsr;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private ProductConsr productConsr;
    @Autowired
    private MainLineConsr mainLineConsr;
    @Autowired
    private MessageBiz messageBiz;
    @Autowired
    private BookGroupClassifyDao bookGroupClassifyDao;
    @Autowired
    private BookKeywordDao bookKeywordDao;
    @Autowired
    private AudioLessonService audioLessonService;
    @Autowired
    private ScheduleService scheduleService;
    @Autowired
    private TimeTableService timeTableService;
    @Autowired
    private AppPriceCacheService appPriceCacheService;
    @Autowired
    private TempletRelevanceDao templetRelevanceDao;
    @Autowired
    private JoinGroupCipherDao joinGroupCipherDao;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private WeixinQrcodeDao weixinQrcodeDao;
    @Autowired
    private BookConsr bookConsr;
    @Autowired
    private GroupQrcodeBiz groupQrcodeBiz;



    @Override
    public BookGroupDTO getDTOByBookId(Long bookId, Long channelId, Long adviserId) {
        return bookGroupDao.getDTOByBookId(bookId, channelId, adviserId);
    }

    /**
     * 创建社群书时生成群二维码
     */
    @Override
    @ParamLog("创建社群书时生成群二维码")
    @Transactional(rollbackFor = Exception.class)
    public BookGroup createBookGroupAfterCreateBook(Long bookId, Long channelId, Long adviserId, Integer addType, Long sceneId) throws BizException {
        BookGroup bookGroup = new BookGroup();
        bookGroup.setBookId(bookId);
        bookGroup.setChannelId(channelId);
        bookGroup.setCreateUser(adviserId);
        Boolean isShowBookName = bookGroupDao.getIsShowBookName(adviserId);
        if (isShowBookName != null) {
            bookGroup.setIsShowBookName(isShowBookName);
        }
        if (addType != null && addType == 1) {
            GroupQrcodeVO groupQrcodeVO;
            if (sceneId != null) {
                //将图书下某个二维码替换成社群码
                groupQrcodeVO = qrcodeSceneConsr.setQrcodeToGroup(sceneId);
            } else {
                //创建公众号二维码
                groupQrcodeVO = qrcodeSceneConsr.createWxGroupQrcode(bookId, channelId, adviserId);
            }
            if (groupQrcodeVO == null) {
                throw new BookBizException(BookBizException.ERROR, "二维码生成失败！");
            }
            bookGroup.setGroupQrcodeUrl(groupQrcodeVO.getQrcodeUrl());
            bookGroup.setSceneId(groupQrcodeVO.getSceneId());
            bookGroupDao.insert(bookGroup);
        } else {
            bookGroupDao.insert(bookGroup);
            String groupQrcodeUrl = QrcodeUtils.createWithMargin(bookGroupQrcodeDomain + "/" + bookGroup.getId(), 1);
            BookGroup group = new BookGroup();
            group.setId(bookGroup.getId());
            group.setGroupQrcodeUrl(groupQrcodeUrl);
            bookGroupDao.update(group);
            bookGroup.setGroupQrcodeUrl(groupQrcodeUrl);
        }
        if (null != bookId && !bookId.equals(0L)) {
            mainLineConsr.sendAddBookGroupTask(bookId, adviserId);
        }
        return bookGroup;
    }

    /**
     * 获取社群书群二维码信息
     */
    @Override
    public BookGroupDTO getBookGroupInfo(Long bookGroupId) throws BizException {
        BookGroupDTO bookGroupDTO = bookGroupDao.getDTOById(bookGroupId);
        if (null == bookGroupDTO) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "群二维码不存在！");
        }
        List<Long> labelIds = new ArrayList<>();
        if (null != bookGroupDTO.getProLabelId()) {
            labelIds.add(bookGroupDTO.getProLabelId());
        }
        if (null != bookGroupDTO.getDepLabelId()) {
            labelIds.add(bookGroupDTO.getDepLabelId());
        }
        if (null != bookGroupDTO.getPurLabelId()) {
            labelIds.add(bookGroupDTO.getPurLabelId());
        }
        if (!ListUtils.isEmpty(labelIds)) {
            Map<Long, String> labelMap = ResponseHandleUtil.parseMap(labelService.getLabelName(labelIds), Long.class, String.class);
            if (!MapUtils.isEmpty(labelMap)) {
                if (null != bookGroupDTO.getProLabelId() && labelMap.containsKey(bookGroupDTO.getProLabelId())) {
                    bookGroupDTO.setProLabelName(labelMap.get(bookGroupDTO.getProLabelId()));
                }
                if (null != bookGroupDTO.getDepLabelId() && labelMap.containsKey(bookGroupDTO.getDepLabelId())) {
                    bookGroupDTO.setDepLabelName(labelMap.get(bookGroupDTO.getDepLabelId()));
                }
                if (null != bookGroupDTO.getPurLabelId() && labelMap.containsKey(bookGroupDTO.getPurLabelId())) {
                    bookGroupDTO.setPurLabelName(labelMap.get(bookGroupDTO.getPurLabelId()));
                }
            }
        }
        BookDto bookDto = bookBiz.getBaseById(bookGroupDTO.getBookId());
        if (null != bookDto) {
            bookDto.setBookName(null != bookDto.getBookName() ? StringUtil.addBracket(bookDto.getBookName()) : null);
            bookGroupDTO.setBookInfo(bookDto);
        }
        return bookGroupDTO;
    }

    @Override
    public Map<Long, BookGroupDTO> getBookGroupInfoByIds(List<Long> bookGroupIds) throws BizException {
        if (ListUtils.isEmpty(bookGroupIds)) {
            return null;
        }
        List<BookGroupDTO> list = bookGroupDao.getDTOByIds(bookGroupIds);
        List<Long> bookIds = list.stream().map(BookGroupDTO::getBookId).collect(Collectors.toList());
        Map<Long, BookDto> mapByIds = bookDao.getMapByIds(bookIds);
        if (ListUtils.isEmpty(list)) {
            return null;
        }
        list.forEach(e ->{
            if (!MapUtils.isEmpty(mapByIds) && mapByIds.get(e.getBookId()) != null){
                e.setBookName(mapByIds.get(e.getBookId()).getBookName());
                e.setIsbn(mapByIds.get(e.getBookId()).getIsbn());
                e.setBookNumber("BK" + e.getBookId());
            }
        });
        return list.stream().collect(Collectors.toMap(BookGroupDTO::getId, dto -> dto));
    }

    /**
     * 获取社群书群二维码信息
     */
    @Override
    public BookGroupDTO getBookGroupInfo4Wechat(Long bookGroupId) throws BizException {
        BookGroupDTO bookGroupDTO = bookGroupDao.getDTOById(bookGroupId);
        if (bookGroupDTO != null && bookGroupDTO.getBookId() != null
                && bookGroupDTO.getIsShowBookName() != null && bookGroupDTO.getIsShowBookName()) {
            BookDto bookDto = bookDao.getBaseById(bookGroupDTO.getBookId());
            if (bookDto != null) {
                bookGroupDTO.setBookName(bookDto.getBookName());
            }
        }
        return bookGroupDTO;
    }

    /**
     * 获取社群书群二维码信息
     */
    @Override
    public BookGroupDTO getBookGroupInfoByBookId(Long bookId, Long channelId, Long adviserId, Integer addType, Long sceneId) throws BizException {
        BookGroupDTO bookGroupDTO = null;
        if (!bookId.equals(0L)) {
            bookGroupDTO = bookGroupDao.getDTOByBookId(bookId, channelId, adviserId);
        }
        if (null == bookGroupDTO) {
            BookGroup bookGroup = this.createBookGroupAfterCreateBook(bookId, channelId, adviserId, addType, sceneId);
            bookGroupDTO = new BookGroupDTO();
            bookGroupDTO.setId(bookGroup.getId());
            bookGroupDTO.setBookId(bookId);
            bookGroupDTO.setChannelId(channelId);
            bookGroupDTO.setGroupQrcodeUrl(bookGroup.getGroupQrcodeUrl());
            bookGroupDTO.setCreateUser(adviserId);
        } else {
            // 当书籍存在时根据前端传的addType来决定用什么码替换addType=1公众号码，其他为自建码
            BookGroup group = new BookGroup();
            group.setId(bookGroupDTO.getId());
            // 更新为微信码
            if (addType != null && addType == 1) {
                //创建公众号二维码
                GroupQrcodeVO groupQrcodeVO = qrcodeSceneConsr.createWxGroupQrcode(bookId, channelId, adviserId);
                if (groupQrcodeVO == null) {
                    throw new BookBizException(BookBizException.ERROR, "二维码生成失败！");
                }
                group.setSceneId(groupQrcodeVO.getSceneId());
                group.setGroupQrcodeUrl(groupQrcodeVO.getQrcodeUrl());
                bookGroupDao.update(group);
                // 展示返回最新生成的
                bookGroupDTO.setGroupQrcodeUrl(groupQrcodeVO.getQrcodeUrl());
            }
            // 更新为自建码
            if (addType != null && addType == 2) {
                // 如果是恢复书籍，且选择自建码则清空sceneId
                if (null != bookGroupDTO.getSceneId() && bookGroupDTO.getSceneId() > 0) {
                    group.setSceneId(0L);
                    final Boolean haveQrcode = this.isHaveQrcode(bookId, channelId, adviserId);
                    // 如果之前是公众号二维码则要重新生成自有码
                    if (!haveQrcode) {
                        String groupQrcodeUrl = QrcodeUtils.createWithMargin(bookGroupQrcodeDomain + "/" + bookGroupDTO.getId(), 1);
                        group.setGroupQrcodeUrl(groupQrcodeUrl);
                        // 展示返回最新生成的
                        bookGroupDTO.setGroupQrcodeUrl(groupQrcodeUrl);
                    }
                    bookGroupDao.update(group);
                }
            }
        }
        List<Long> labelIds = new ArrayList<>();
        if (null != bookGroupDTO.getProLabelId()) {
            labelIds.add(bookGroupDTO.getProLabelId());
        }
        if (null != bookGroupDTO.getDepLabelId()) {
            labelIds.add(bookGroupDTO.getDepLabelId());
        }
        if (null != bookGroupDTO.getPurLabelId()) {
            labelIds.add(bookGroupDTO.getPurLabelId());
        }
        if (!ListUtils.isEmpty(labelIds)) {
            Map<Long, String> labelMap = ResponseHandleUtil.parseMap(labelService.getLabelName(labelIds), Long.class, String.class);
            if (!MapUtils.isEmpty(labelMap)) {
                if (null != bookGroupDTO.getProLabelId() && labelMap.containsKey(bookGroupDTO.getProLabelId())) {
                    bookGroupDTO.setProLabelName(labelMap.get(bookGroupDTO.getProLabelId()));
                }
                if (null != bookGroupDTO.getDepLabelId() && labelMap.containsKey(bookGroupDTO.getDepLabelId())) {
                    bookGroupDTO.setDepLabelName(labelMap.get(bookGroupDTO.getDepLabelId()));
                }
                if (null != bookGroupDTO.getPurLabelId() && labelMap.containsKey(bookGroupDTO.getPurLabelId())) {
                    bookGroupDTO.setPurLabelName(labelMap.get(bookGroupDTO.getPurLabelId()));
                }
            }
        }
        BookDto bookDto = bookBiz.getBaseById(bookId);
        if (null != bookDto) {
            bookDto.setBookName(null != bookDto.getBookName() ? StringUtil.addBracket(bookDto.getBookName()) : null);
            bookGroupDTO.setBookInfo(bookDto);
        }
        return bookGroupDTO;
    }

    /**
     * 更新群二维码信息
     */
    @Override
    @ParamLog(value = "更新群二维码信息", isAfterReturn = false)
    @Transactional(rollbackFor = Exception.class)
    public void updateBookGroup(BookGroup bookGroup) throws BizException {
        if (null == bookGroup.getId() || StringUtil.isEmpty(bookGroup.getGroupQrcodeName()) || null == bookGroup.getProLabelId()
                || null == bookGroup.getDepLabelId() || null == bookGroup.getPurLabelId() || StringUtil.isEmpty(bookGroup.getJoinTitle())
                || StringUtil.isEmpty(bookGroup.getJoinSlogan()) ) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "参数有误！");
        }
        BookGroup group = bookGroupDao.getById(bookGroup.getId());
        if (null == group) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "群二维码不存在！");
        }
        if (null == group.getProductId()) {
            AddAppProductParamDTO addAppProductParamDTO = new AddAppProductParamDTO();
            addAppProductParamDTO.setAppProCode(ProductTypeConstant.BOOK_GROUP);
            addAppProductParamDTO.setAppProName(bookGroup.getGroupQrcodeName());
            addAppProductParamDTO.setCoverImg(DEFAULT_PRODUCT_COVER_IMG);
            addAppProductParamDTO.setPartyId(group.getCreateUser());
            addAppProductParamDTO.setChannelId(group.getChannelId());
            Long agentId = adviserConsr.getAgentIdByAdviser(group.getCreateUser());
            addAppProductParamDTO.setAgentId(agentId);
            Product product = ResponseHandleUtil.parseResponse(productService.postAddBookGroupProduct(addAppProductParamDTO), Product.class);
            if (null == product) {
                throw new BookBizException(BookBizException.DB_DML_FAIL, "操作失败！");
            }
            bookGroup.setProductId(product.getProductId());
        } else {
            UpdateAppProductParamDTO updateAppProductParamDTO = new UpdateAppProductParamDTO();
            updateAppProductParamDTO.setProductId(group.getProductId());
            updateAppProductParamDTO.setChannelId(group.getChannelId());
            updateAppProductParamDTO.setAppProName(bookGroup.getGroupQrcodeName());
            ResponseHandleUtil.parseResponse(productService.postUpdateBookGroupProduct(updateAppProductParamDTO), Product.class);
        }
        bookGroupDao.update(bookGroup);
    }

    /**
     * 根据书刊ID删除
     */
    @Override
    @ParamLog(value = "根据书刊ID删除", isAfterReturn = false)
    @Transactional(rollbackFor = Exception.class)
    public void deleteByBookId(Long bookId, Long channelId, Long adviserId) throws BizException {
        bookGroupDao.deleteByBookId(bookId, channelId, adviserId);
    }

    /**
     * 根据书刊ID恢复
     */
    @Override
    @ParamLog(value = "根据书刊ID恢复", isAfterReturn = false)
    @Transactional(rollbackFor = Exception.class)
    public void recoverByBookId(Long bookId, Long channelId, Long adviserId) throws BizException {
        bookGroupDao.recoverByBookId(bookId, channelId, adviserId);
    }

    /**
     * 关联社群码和社群书
     */
    @Override
    @ParamLog("关联社群码和社群书")
    @Transactional(rollbackFor = Exception.class)
    public void linkBookGroup(Long bookId, Long bookGroupId, Long adviserId) throws BizException {
        BookGroupDTO bookGroupDTO = getBookGroupInfo4Wechat(bookGroupId);
        if (null == bookGroupDTO || bookGroupDTO.getIsDelete() || !bookGroupDTO.getCreateUser().equals(adviserId)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "社群码不存在或已删除！");
        }
        if (null != bookGroupDTO.getBookId() && !bookGroupDTO.getBookId().equals(0L)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "社群码已关联其他社群书！");
        }
        BookGroupDTO dto = bookGroupDao.getDTOByBookId(bookId, bookGroupDTO.getChannelId(), adviserId);
        if (null != dto) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "该社群书已经添加过其他社群码！");
        }
        BookGroup bookGroup = new BookGroup();
        bookGroup.setBookId(bookId);
        bookGroup.setId(bookGroupId);
        long result = bookGroupDao.linkBookGroup(bookGroup);
        if (result <= 0) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "关联社群书失败！");
        }
    }

    /**
     * 根据社群码ID获取书名
     */
    @Override
    public Map<String, Object> getBookNameByBookGroupId(Long bookGroupId) throws BizException {
        Map<String, Object> result = new HashMap<>();
        BookGroupDTO bookGroupDTO = bookGroupDao.getDTOById(bookGroupId);
        if (null != bookGroupDTO && null != bookGroupDTO.getBookId()) {
            BookDto bookDto = bookBiz.getBaseById(bookGroupDTO.getBookId());
            if (null != bookDto) {
                result.put("bookName", StringUtil.addBracket(bookDto.getBookName()));
            }
            result.put("isDelete", bookGroupDTO.getIsDelete());
        } else {
            result.put("isDelete", true);
        }
        return result;
    }

    /**
     * 获取社群书列表(编辑)
     */
    @Override
    public PageBean listBookGroup4Adviser(Map<String, Object> paramMap, PageParam pageParam, Long adviserId) throws BizException {
        PageBean pageBean = bookDao.listPage(pageParam, paramMap, "listBookGroup4Adviser");
        if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBean(0, 0, new ArrayList<>());
        }
        // 设置是否被冻结
        bookSet.setFreezeStatus(pageBean.getRecordList());
        // 填充社群书数据
        List<Long> bookGroupIds = new ArrayList<>();
        pageBean.getRecordList().forEach(obj -> bookGroupIds.add(((BookDto) obj).getBookGroupId()));
        ResponseEntity<ResponseDto<Map<Long, BigDecimal>>> responseEntity = settlementService.getWXGroupIncomeByAdviser(bookGroupIds, adviserId);
        Map<Long, BigDecimal> incomeMap = ResponseHandleUtil.parseMap(responseEntity, Long.class, BigDecimal.class);
        Map<Long, BookGroupStatisticDTO> statisMap = bookGroupClassifyBiz.getBookGroupStatistic(bookGroupIds);
        Map<Long, Integer> scanMap = ResponseHandleUtil.parseMap(groupMemberService.getScanUserCountByGroup(bookGroupIds), Long.class, Integer.class);
        for (Object object : pageBean.getRecordList()) {
            BookDto bookDto = (BookDto) object;
            Long bookGroupId = bookDto.getBookGroupId();
            bookDto.setGroupQrcodeLink(bookGroupQrcodeDomain + "/" + bookGroupId);
            bookDto.setBookName(null != bookDto.getBookName() ? StringUtil.addBracket(bookDto.getBookName()) : null);
            if (!MapUtils.isEmpty(statisMap) && statisMap.containsKey(bookGroupId)) {
                BookGroupStatisticDTO dto = statisMap.get(bookGroupId);
                bookDto.setClassifyCount(null != dto.getClassifyCount() ? dto.getClassifyCount().longValue() : 0L);
                bookDto.setGroupCount(null != dto.getGroupNumber() ? dto.getGroupNumber().longValue() : 0L);
                bookDto.setGroupPersonCount(null != dto.getUserNumber() ? dto.getUserNumber().longValue() : 0L);
            } else {
                bookDto.setClassifyCount(0L);
                bookDto.setGroupPersonCount(0L);
                bookDto.setGroupCount(0L);
            }
            if (!MapUtils.isEmpty(scanMap) && scanMap.containsKey(bookGroupId)) {
                bookDto.setScanCount(null != scanMap.get(bookGroupId) ? scanMap.get(bookGroupId).longValue() : 0L);
            } else {
                bookDto.setScanCount(0L);
            }
            if (!MapUtils.isEmpty(incomeMap) && incomeMap.containsKey(bookGroupId)) {
                BigDecimal income = incomeMap.get(bookGroupId);
                bookDto.setTotalIncome(null != income ? income.setScale(2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
            } else {
                bookDto.setTotalIncome(BigDecimal.ZERO);
            }
        }
        return pageBean;
    }

    @Override
    public PageBean listBookGroup4Channel(Long channelId, ListBookGroup4ChannelParamVO listBookGroup4ChannelParamVO) {
        Integer currentPage = listBookGroup4ChannelParamVO.getCurrentPage();
        Integer numPerPage = listBookGroup4ChannelParamVO.getNumPerPage();
        if (currentPage == null || numPerPage == null || currentPage < 0 || numPerPage < 0) {
            throw BookBizException.PAGE_PARAM_DELETION;
        }
        PageParam pageParam = new PageParam(currentPage, numPerPage);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("channelId", channelId);
        paramMap.put("keywords", listBookGroup4ChannelParamVO.getKeywords());
        paramMap.put("isFundBook", listBookGroup4ChannelParamVO.getIsFundBook());
        String startTime = listBookGroup4ChannelParamVO.getStartTime();
        String endTime = listBookGroup4ChannelParamVO.getEndTime();
        if (startTime != null){
            paramMap.put("startTime", startTime + " 00:00:00");
        }
        if (endTime != null){
            paramMap.put("endTime", endTime + " 23:59:59");
        }
        PageBean listBookGroup4Channel = bookDao.listPage(pageParam, paramMap, "listBookGroup4Channel");
        List<Long> bookGroupIds = new ArrayList<>();
        listBookGroup4Channel.getRecordList().forEach(e -> {
            ListBook4ChannelVO listBook4ChannelVO = (ListBook4ChannelVO) e;
            bookGroupIds.add(listBook4ChannelVO.getBookGroupId());
        });
        if(ListUtils.isEmpty(bookGroupIds)){
            return new PageBean(0, 0, new ArrayList<>());
        }
        Map<Long, BookGroupStatisticDTO> statisMap = bookGroupClassifyBiz.getBookGroupStatistic(bookGroupIds);
        listBookGroup4Channel.getRecordList().forEach( e ->{
            ListBook4ChannelVO listBook4ChannelVO = (ListBook4ChannelVO) e;
            if (!MapUtils.isEmpty(statisMap) && statisMap.containsKey(listBook4ChannelVO.getBookGroupId())) {
                BookGroupStatisticDTO dto = statisMap.get(listBook4ChannelVO.getBookGroupId());
                listBook4ChannelVO.setClassifyNum(null != dto.getClassifyCount() ? dto.getClassifyCount().longValue() : 0L);
                listBook4ChannelVO.setTotalNum(null != dto.getUserNumber() ? dto.getUserNumber().longValue() : 0L);
            }else {
                listBook4ChannelVO.setClassifyNum(0L);
                listBook4ChannelVO.setTotalNum(0L);
            }
        });

        return listBookGroup4Channel;
    }

    /**
     * 获取社群书列表(编辑)
     */
    @Override
    public List<BookDto> listSimpleBookGroup4Adviser(Map<String, Object> paramMap) throws BizException {
        return bookDao.listSimpleBookGroup4Adviser(paramMap);
    }

    /**
     * 获取社群书列表(编辑)
     */
    @Override
    public PageBean listSimpleBookGroup4Adviser(Map<String, Object> paramMap, PageParam pageParam) throws BizException {
        return bookDao.listPage(pageParam, paramMap, "listSimpleBookGroup4Adviser");
    }

    /**
     * 获取未创建社群码的书刊列表
     */
    @Override
    public PageBean listBook4CreateBookGroup(Map<String, Object> paramMap, PageParam pageParam, Long adviserId) throws BizException {
        PageBean pageBean = bookDao.listPage(pageParam, paramMap, "listBook4CreateBookGroup");
        if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBean(0, 0, new ArrayList<>());
        }
        return pageBean;
    }

    @Override
    @ParamLog("获取社群码名称以及商品标识")
    public QrcodeNameAndProIdDTO getQrcodeNameAndProId(Long bookGroupId) throws BizException {
        return bookGroupDao.getQrcodeNameAndProId(bookGroupId);
    }

    @Override
    @ParamLog("获取排序类型")
    public Integer getRankType(Long bookGroupId) throws BizException {
        return bookGroupDao.getRankType(bookGroupId);
    }

    @Override
    @ParamLog("更新排序类型")
    public void updateRankType(Long bookGroupId, Integer rankType) throws BizException {
        bookGroupDao.updateRankType(bookGroupId, rankType);
    }

    /**
     * 编辑获取社群码总数量
     */
    @Override
    public Map<String, Object> getTotalBookGroupCount(Long adviserId) throws BizException {
        Map<String, Object> result = new HashMap<>();
        Integer bookGroupCount = bookGroupDao.getBookGroupCount(adviserId);
        result.put("bookGroupCount", bookGroupCount);
        return result;
    }

    @Override
    public String getSpareQr(Long bookGroupId) {
        return bookGroupDao.getSpareQr(bookGroupId);
    }

    @Override
    public BookGroupDTO getBaseInfoBySceneId(Long sceneId) {
        BookGroupDTO bookGroupDTO = bookGroupDao.getBaseInfoBySceneId(sceneId);
        if (bookGroupDTO != null) {
            bookGroupDTO.setUrl(bookGroupQrcodeDomain + "/" + bookGroupDTO.getId());
        }
        return bookGroupDTO;
    }

    @Override
    public void updatePersonQrcode(PersonalQrcodeDTO personalQrcodeDTO) {
        if (personalQrcodeDTO == null || personalQrcodeDTO.getNewQrcodeUrl() == null ||
                personalQrcodeDTO.getOldQrcodeUrl() == null){
            throw new BookBizException(BookBizException.ERROR,"参数缺失");
        }
        bookGroupDao.updatePersonQrcode(personalQrcodeDTO);
    }

    @Override
    @ParamLog("是否是特殊的出版社")
    public Boolean isSpecialAgent(Long agentId) {
        return bookGroupDao.isSpecialAgent(agentId);
    }

    @Override
    public Boolean isHaveQrcode(Long bookId, Long channelId, Long adviserId) {
        BookGroupDTO bookGroupDTO = bookGroupDao.getDTOByBookId(bookId, channelId, adviserId);
        return bookGroupDTO != null && null == bookGroupDTO.getSceneId();
    }

    @ParamLog("获取应用统计")
    @Override
    public PageBeanNew<AppStatisticsDTO> getAppStatistics(Integer currentPage, Integer numPerPage, Long bookGroupId, Long qrcodeId, Long partyId) {
        PageParam pageParam = new PageParam(currentPage, numPerPage);
        Map<String, Object> map = new HashMap<>();
        map.put("bookGroupId", bookGroupId);
        map.put("qrcodeId", qrcodeId);
        PageBeanNew<AppStatisticsDTO> pageBeanNew = appTouchRecordDao.listPageNew(pageParam, map, "getAppTouchStatistics");
        List<AppStatisticsDTO> appStatisticsDTOS = pageBeanNew.getRecordList();
        if (ListUtils.isEmpty(appStatisticsDTOS)) {
            return pageBeanNew;
        }
        List<Long> serveIds = appStatisticsDTOS.stream().filter(s -> s.getServeId() != null).map(AppStatisticsDTO::getServeId).collect(Collectors.toList());
        //获取点击次数
        List<AppStatisticsDTO> appClickStatisticsDTOS = appClickRecordDao.getClickStatisticsByServeIds(serveIds, qrcodeId, bookGroupId);
        Map<Long, Integer> clickCountMap = new HashMap<>();
        if (!ListUtils.isEmpty(appClickStatisticsDTOS)) {
            for (AppStatisticsDTO in : appClickStatisticsDTOS) {
                clickCountMap.put(in.getServeId(), in.getClickCount());
            }
        }
        List<Long> productIds = appStatisticsDTOS.stream().filter(s -> s.getServeId() != null && "PRODUCT".equalsIgnoreCase(s.getServeType())).map(AppStatisticsDTO::getServeId).collect(Collectors.toList());
        List<Long> appIds = appStatisticsDTOS.stream().filter(s -> s.getServeId() != null && "APP".equalsIgnoreCase(s.getServeType())).map(AppStatisticsDTO::getServeId).collect(Collectors.toList());
        //获取详情
        Map<Long, AppDto> appDtoMap = appConsr.mapByIds(appIds);
        Map<Long, ProductDto> productDtoMap = productConsr.getProBasesByIds(productIds);


        List<AppPriceCacheDTO> appPriceCacheDTOS = new ArrayList<>();
        for (Long appId : appIds) {
            if (appDtoMap.get(appId) != null) {
                AppPriceCacheDTO appPriceCacheDTO = new AppPriceCacheDTO();
                appPriceCacheDTO.setAppTypeEnum(AppTypeEnum.APP_TYPE_MAP.get(appDtoMap.get(appId).getTypeCode()));
                appPriceCacheDTO.setAppId(appId);
                appPriceCacheDTOS.add(appPriceCacheDTO);
            }
        }
        Map<Long, BigDecimal> appPriceMap = ResponseHandleUtil.parseMapResponse(appPriceCacheService.getCaches(appPriceCacheDTOS), Long.class, BigDecimal.class);
        //结算接口
        Map<Long, BigDecimal> productIncomeMap = settlementConsr.getAdviserIncomeByCondition(productIds, "PRODUCT", partyId, qrcodeId, bookGroupId);
        Map<Long, BigDecimal> appIncomeMap = settlementConsr.getAdviserIncomeByCondition(appIds, "APP", partyId, qrcodeId, bookGroupId);
        //交易接口
        WechatGroupDto wechatGroupDtoP = new WechatGroupDto();
        wechatGroupDtoP.setBookGroupId(bookGroupId);
        wechatGroupDtoP.setIds(productIds);
        wechatGroupDtoP.setPartyId(partyId);
        wechatGroupDtoP.setType("PRODUCT");
        wechatGroupDtoP.setQrcodeId(qrcodeId);
        WechatGroupDto wechatGroupDtoA = new WechatGroupDto();
        wechatGroupDtoA.setBookGroupId(bookGroupId);
        wechatGroupDtoA.setIds(appIds);
        wechatGroupDtoA.setPartyId(partyId);
        wechatGroupDtoA.setType("APP");
        wechatGroupDtoA.setQrcodeId(qrcodeId);
        Map<Long, GroupMoneyDto> productSaleMap = tradeConsr.getQrGroupSaleMoney(wechatGroupDtoP);
        Map<Long, GroupMoneyDto> appSaleMap = tradeConsr.getQrGroupSaleMoney(wechatGroupDtoA);
        for (AppStatisticsDTO appStatisticsDTO : appStatisticsDTOS) {
            Long id = appStatisticsDTO.getServeId();
            String type = appStatisticsDTO.getServeType();
            Integer clickCount = clickCountMap.get(id);
            if (clickCount == null) {
                clickCount = 0;
            }
            appStatisticsDTO.setClickCount(clickCount);
            Integer buyCount = 0;
            Double incomeAmount = 0D;
            Double saleAmount = 0D;
            if ("PRODUCT".equalsIgnoreCase(type)) {
                if (productIncomeMap.get(id) != null) {
                    incomeAmount = productIncomeMap.get(id).doubleValue();
                }
                appStatisticsDTO.setIncomeAmount(incomeAmount);
                if (productSaleMap.get(id) != null) {
                    saleAmount = productSaleMap.get(id).getSaleMoney();
                    buyCount = productSaleMap.get(id).getSaleCount().intValue();
                }
                appStatisticsDTO.setSaleAmount(saleAmount);
                appStatisticsDTO.setBuyCount(buyCount);
                if (productDtoMap != null && productDtoMap.get(id) != null) {
                    ProductDto productDto = productDtoMap.get(id);
                    appStatisticsDTO.setServeName(productDto.getProductName());
                    appStatisticsDTO.setImage(productDto.getCoverImg());
                    ProductTypeDto productTypeDto = productDto.getProductTypeDto();
                    if (productTypeDto != null) {
                        appStatisticsDTO.setTypeName(productTypeDto.getTypeName());
                    }
                    List<SpecificationDto> specificationDtos = productDto.getSpecification();
                    if (!ListUtils.isEmpty(specificationDtos)) {
                        SpecificationDto specificationDto = specificationDtos.get(0);
                        if (specificationDto != null) {
                            appStatisticsDTO.setDealPrice(specificationDto.getDealPrice());
                            appStatisticsDTO.setRetailPrice(specificationDto.getAdvisePrice());
                        }
                    }
                }
            }
            if ("APP".equalsIgnoreCase(type)) {
                if (appIncomeMap.get(id) != null) {
                    incomeAmount = appIncomeMap.get(id).doubleValue();
                }
                appStatisticsDTO.setIncomeAmount(incomeAmount);
                GroupMoneyDto groupMoneyDtoApp = appSaleMap.get(id);
                if (groupMoneyDtoApp != null) {
                    saleAmount = groupMoneyDtoApp.getSaleMoney();
                    buyCount = groupMoneyDtoApp.getSaleCount().intValue();
                }
                appStatisticsDTO.setSaleAmount(saleAmount);
                appStatisticsDTO.setBuyCount(buyCount);
                if (appDtoMap != null && appDtoMap.get(id) != null) {
                    AppDto appDto = appDtoMap.get(id);
                    appStatisticsDTO.setTypeName(appDto.getTypeName());
                    appStatisticsDTO.setServeName(appDto.getTitle());
                    appStatisticsDTO.setImage(appDto.getSquareImg());
                }
                if (appPriceMap != null) {
                    if (appPriceMap.get(id) != null) {
                        appStatisticsDTO.setRetailPrice(appPriceMap.get(id).doubleValue());
                        appStatisticsDTO.setDealPrice(0D);
                    }
                }
            }
            if (buyCount == null || buyCount == 0 || clickCount == null || clickCount == 0) {
                appStatisticsDTO.setBuyRate(0D);
            } else {
                appStatisticsDTO.setBuyRate(new BigDecimal(buyCount.doubleValue() / clickCount).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
            }
        }
        //处理音频、视频、直播课的逻辑
        dealOtherSale(appStatisticsDTOS,productDtoMap,bookGroupId,qrcodeId,partyId);
        return pageBeanNew;
    }

    @ParamLog("处理音频、视频、直播课的逻辑")
    private void dealOtherSale(List<AppStatisticsDTO> appStatisticsDTOS, Map<Long, ProductDto> productDtoMap, Long bookGroupId, Long qrcodeId, Long partyId) {
        if (productDtoMap == null || productDtoMap.values() == null || productDtoMap.values().isEmpty()) {
            return;
        }
        //视频课，音频课，直播课特殊处理
        List<Long> videoProductIds = new ArrayList<>();
        List<Long> audioProductIds = new ArrayList<>();
        List<Long> liveProductIds = new ArrayList<>();
        List<ProductDto> productDtos = new ArrayList<>(productDtoMap.values());
        if (!ListUtils.isEmpty(productDtos)) {
            for (ProductDto productDto : productDtos) {
                ProductTypeDto productTypeDto=productDto.getProductTypeDto();
                String productTypeCode="";
                if (productTypeDto!=null){
                    productTypeCode=productTypeDto.getTypeCode();
                }
                String[] videoTypes = {"VIDEO_COURSE", "VIDEO_SCHEDULE"};
                if (Arrays.asList(videoTypes).contains(productTypeCode)) {
                    videoProductIds.add(productDto.getProductId());
                }
                String[] audioTypes = {"AUDIOAPP", "AUDIO_RESOURCE", "AUDIO_SCHEDULE", "AUDIO_COURSE"};
                if (Arrays.asList(audioTypes).contains(productTypeCode)) {
                    audioProductIds.add(productDto.getProductId());
                }
                String[] liveTypes = {"LIVE", "SCHEDULE"};
                if (Arrays.asList(liveTypes).contains(productTypeCode)) {
                    liveProductIds.add(productDto.getProductId());
                }
            }
        }
        Map<Long, List<Long>> videoPProductMapIds = new HashMap<>();
        Map<Long, List<Long>> audioPProductMapIds = new HashMap<>();
        Map<Long, List<Long>> livePProductMapIds = new HashMap<>();
        //视频课
        if (!ListUtils.isEmpty(videoProductIds)) {
            videoPProductMapIds = ResponseHandleUtil.parseMapList(scheduleService.getCourseProductIdByIds(videoProductIds, "PRODUCT"), Long.class, Long.class);
        }
        //音频课
        if (!ListUtils.isEmpty(audioProductIds)) {
            audioPProductMapIds = ResponseHandleUtil.parseMapList(audioLessonService.getProIdsByIds(audioProductIds, "PRODUCT"), Long.class, Long.class);
        }
        //直播课
        if (!ListUtils.isEmpty(liveProductIds)) {
            ProductIdSearchDto productIdSearchDto=new ProductIdSearchDto();
            productIdSearchDto.setIds(liveProductIds);
            productIdSearchDto.setType("PRODUCT");
            livePProductMapIds = ResponseHandleUtil.parseMapList(timeTableService.getCoursePidsUnderTable(productIdSearchDto), Long.class, Long.class);
        }
        List<Long> valProductIds = new ArrayList<>();
        fillProductIdsFromLL(valProductIds,videoPProductMapIds);
        fillProductIdsFromLL(valProductIds,audioPProductMapIds);
        fillProductIdsFromLL(valProductIds,livePProductMapIds);
        if (!ListUtils.isEmpty(valProductIds)){
            //调交易中心获取交易额信息
            WechatGroupDto wechatGroupDtoP = new WechatGroupDto();
            wechatGroupDtoP.setBookGroupId(bookGroupId);
            wechatGroupDtoP.setIds(valProductIds);
            wechatGroupDtoP.setPartyId(partyId);
            wechatGroupDtoP.setType("PRODUCT");
            wechatGroupDtoP.setQrcodeId(qrcodeId);
            Map<Long, GroupMoneyDto> productSaleMap = tradeConsr.getQrGroupSaleMoney(wechatGroupDtoP);
            Map<Long, BigDecimal> productIncomeMap = settlementConsr.getAdviserIncomeByCondition(valProductIds, "PRODUCT", partyId, qrcodeId, bookGroupId);
            SpeWechatGroupDto speWechatGroupDto=new SpeWechatGroupDto();
            speWechatGroupDto.setBookGroupId(bookGroupId);
            speWechatGroupDto.setPartyId(partyId);
            speWechatGroupDto.setQrcodeId(qrcodeId);
            Map<Long,List<Long>> map=new HashMap<>();
            map.putAll(videoPProductMapIds);
            map.putAll(audioPProductMapIds);
            map.putAll(livePProductMapIds);
            speWechatGroupDto.setProductIdMap(map);
            Map<Long, GroupMoneyDto> forBuyCountMap = tradeConsr.getSpeQrGroupSaleMoney(speWechatGroupDto);
            Map<Long, Double> proSaleMap = new HashMap<>();
            Map<Long, Double> proIncomeMap = new HashMap<>();
            if (productSaleMap.values() != null && !productSaleMap.values().isEmpty()) {
                dealSale(videoProductIds, videoPProductMapIds, productSaleMap, proSaleMap, productIncomeMap, proIncomeMap);
                dealSale(audioProductIds, audioPProductMapIds, productSaleMap, proSaleMap, productIncomeMap, proIncomeMap);
                dealSale(liveProductIds, livePProductMapIds, productSaleMap, proSaleMap, productIncomeMap, proIncomeMap);
                for (AppStatisticsDTO appStatisticsDTO : appStatisticsDTOS) {
                    Long id = appStatisticsDTO.getServeId();
                    String type = appStatisticsDTO.getServeType();
                    if ("PRODUCT".equalsIgnoreCase(type)) {
                        Integer toAddCount = 0;
                        GroupMoneyDto groupMoneyDto = forBuyCountMap.get(id);
                        if (groupMoneyDto != null && groupMoneyDto.getSaleCount() != null) {
                            toAddCount = groupMoneyDto.getSaleCount().intValue();
                        }
                        addProductSale(id, productDtoMap, proSaleMap, proIncomeMap, toAddCount, appStatisticsDTO);
                    }
                }
            }
        }
    }

    private void addProductSale(Long id, Map<Long, ProductDto> productDtoMap, Map<Long, Double> proSaleMap, Map<Long, Double> proIncomeMap, Integer toAddCount, AppStatisticsDTO appStatisticsDTO) {
        ProductDto productDto = productDtoMap.get(id);
        String[] videoTypes = {"VIDEO_COURSE", "VIDEO_SCHEDULE"};
        String[] audioTypes = {"AUDIOAPP", "AUDIO_RESOURCE", "AUDIO_SCHEDULE", "AUDIO_COURSE"};
        String[] liveTypes = {"LIVE", "SCHEDULE"};
        String typeCode = "";
        if (productDto != null && productDto.getProductTypeDto() != null) {
            typeCode = productDto.getProductTypeDto().getTypeCode();
        }
        if (productDto != null && (Arrays.asList(videoTypes).contains(typeCode)
                || Arrays.asList(audioTypes).contains(typeCode)
                || Arrays.asList(liveTypes).contains(typeCode))) {
            Double toAdd = proSaleMap.get(id);
            Double incomeToAdd = proIncomeMap.get(id);
            if (toAdd != null) {
                Double oldSale = appStatisticsDTO.getSaleAmount();
                if (oldSale == null) {
                    oldSale = 0D;
                }
                appStatisticsDTO.setSaleAmount(oldSale + toAdd);
            }
            if (incomeToAdd != null) {
                Double oldIncome = appStatisticsDTO.getIncomeAmount();
                if (oldIncome == null) {
                    oldIncome = 0D;
                }
                appStatisticsDTO.setIncomeAmount(oldIncome + incomeToAdd);
            }
            if (toAddCount != null) {
                Integer oldBuy = appStatisticsDTO.getBuyCount();
                if (oldBuy == null) {
                    oldBuy = 0;
                }
                appStatisticsDTO.setBuyCount(oldBuy + toAddCount);
                Integer buyCount = appStatisticsDTO.getBuyCount();
                Integer clickCount = appStatisticsDTO.getClickCount();
                //重新设置购买率
                if (buyCount == null || buyCount == 0 || clickCount == null || clickCount == 0) {
                    appStatisticsDTO.setBuyRate(0D);
                } else {
                    appStatisticsDTO.setBuyRate(new BigDecimal(buyCount.doubleValue() / clickCount).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                }
            }
        }
    }

    private void dealSale(List<Long> ids, Map<Long,List<Long>> productMapIds, Map<Long,GroupMoneyDto> productSaleMap, Map<Long,Double> saleMap, Map<Long, BigDecimal> productIncomeMap, Map<Long, Double> incomeMap) {
        if (!ListUtils.isEmpty(ids)) {
            for (Long id : ids) {
                List<Long> productIds = productMapIds.get(id);
                if (!ListUtils.isEmpty(productIds)) {
                    Double saleMoney = 0D;
                    Long  saleCount = 0L;
                    Double incomeMoney = 0D;
                    for (Long productId : productIds) {
                        GroupMoneyDto groupMoneyDto = productSaleMap.get(productId);
                        if (groupMoneyDto != null) {
                            if (groupMoneyDto.getSaleMoney() != null) {
                                saleMoney = saleMoney + groupMoneyDto.getSaleMoney();
                            }
                            if (groupMoneyDto.getSaleCount() != null) {
                                saleCount = saleCount + groupMoneyDto.getSaleCount();
                            }
                        }
                        if (productIncomeMap != null && productIncomeMap.get(productId) != null) {
                            incomeMoney = incomeMoney + productIncomeMap.get(productId).doubleValue();
                        }
                    }
                    saleMap.put(id, saleMoney);
                    incomeMap.put(id, incomeMoney);
                }
            }
        }
    }

    private void fillProductIdsFromLL(List<Long> productIds,Map<Long, List<Long>> map){
        if (map != null && !map.values().isEmpty()) {
            List<List<Long>> ll = new ArrayList<>(map.values());
            for (List<Long> l : ll) {
                if (!ListUtils.isEmpty(l)) {
                    productIds.addAll(l);
                }
            }
        }
    }
    @Override
    public void exportGroupQrcode4Adviser(Map<String, Object> paramMap, Long adviserId) {
        ThreadPoolUtils.EXPORT_THREAD_POOL.execute(() -> {
            // 生成文件名
            String fileName = "社群码导出_" + DateUtils.getShortDateStr();
            Boolean isSuccess = true;
            String zipUrl = "";
            try {
                Map<String, List<String[]>> zipFileMap = new HashMap<>();
                List<String[]> qrcodePicUrls = new ArrayList<String[]>();
                // 设置查询参数
                List<BookDto> bookDtos = bookDao.listBookGroup4Adviser(paramMap);
                if (ListUtils.isEmpty(bookDtos)) {
                    return;
                }
                Integer noName = 0;
                for (BookDto bookDto : bookDtos) {
                    String bookName = null != bookDto.getBookName() ? StringUtil.addBracket(bookDto.getBookName()) : null;
                    String groupQrcodeName = bookDto.getGroupQrcodeName();
                    String qrcodeUrl = bookDto.getGroupQrcodeUrl() == null ? null : bookDto.getGroupQrcodeUrl().replace("oss.5rs.me", "file.5rs.me");
                    String qrcodeName;
                    if (!StringUtil.isEmpty(bookName)) {
                        qrcodeName = bookName;
                        if (!StringUtil.isEmpty(groupQrcodeName)) {
                            qrcodeName = qrcodeName + groupQrcodeName;
                        }
                    } else {
                        if (!StringUtil.isEmpty(groupQrcodeName)) {
                            qrcodeName = groupQrcodeName;
                        } else {
                            noName = noName + 1;
                            qrcodeName = "未命名" + noName;
                        }
                    }
                    // 加入二维码图片
                    String[] qrcodePicurl = {qrcodeName, qrcodeUrl};
                    qrcodePicUrls.add(qrcodePicurl);
                }
                zipFileMap.put(fileName, qrcodePicUrls);
                UploadResultInfo zipUrlInfo = CompressUtils.zipByCatalog(zipFileMap, fileName);
                zipUrl = zipUrlInfo != null ? zipUrlInfo.getUrl() : null;

            } catch (Exception e) {
                LOGGER.error("生成导出文件失败", e);
                isSuccess = false;
            }
            // 发送消息
            if (isSuccess) {
                JSONObject content = new JSONObject();
                content.put("commitTime", DateUtils.formatDate(new Date()));
                content.put("type", "社群码导出");
                SendNotifyDto sendNotifyDto = new SendNotifyDto();
                sendNotifyDto.setCreatedTime(new Date());
                sendNotifyDto.setFromId(adviserId);
                sendNotifyDto.setToId(adviserId);
                sendNotifyDto.setNotifyContent(content.toJSONString());
                sendNotifyDto.setSystemCode(SystemCode.adviser.code);
                sendNotifyDto.setTypeCode("qrcode_download");
                sendNotifyDto.setResourceId(zipUrl);
                sendNotifyDto.setFileName(fileName);
                sendNotifyDto.setOriginType(NotifyOriginTypeEnum.BOOK_GROUP.value);
                try {
                    messageBiz.sendLetter(sendNotifyDto);
                } catch (Exception e) {
                    LOGGER.error("【站内信(消)】发送站内信.[sendLetter]:" + e.getMessage(), e);
                }
            }
        });
    }

    @ParamLog("根据bookId获取社群书分类等统计")
    @Override
    public StatisticVO getBookGroupStatistics(Long bookId) {
        return bookGroupClassifyDao.getBookGroupStatistics(bookId);
    }

    @ParamLog("根据bookId获取社群书分类和关键词等统计信息")
    @Override
    public List<ClassifyKeywordDTO> getBookGroupKeywordStatistics(Long bookId) {
        List<ClassifyKeywordDTO> classifyKeywordDTOS = bookGroupClassifyDao.getClassifyStatistics(bookId);
        if (!ListUtils.isEmpty(classifyKeywordDTOS)) {
            List<Long> classifyIds = classifyKeywordDTOS.stream().map(ClassifyKeywordDTO::getClassifyId).collect(Collectors.toList());
            List<ListKeywordVO> listKeywordVOS = bookKeywordDao.getKeywordsByClassifyIds(classifyIds,bookId);
            List<Long> appIds = listKeywordVOS.stream().filter(s -> "APP".equalsIgnoreCase(s.getServeType())).map(ListKeywordVO::getServeId).collect(Collectors.toList());
            Map<Long, AppDto> appDtoMap = appConsr.mapByIds(appIds);
            List<AppPriceCacheDTO> appPriceCacheDTOS = new ArrayList<>();
            for (Long appId : appIds) {
                if (appDtoMap.get(appId) != null) {
                    AppPriceCacheDTO appPriceCacheDTO = new AppPriceCacheDTO();
                    appPriceCacheDTO.setAppId(appId);
                    appPriceCacheDTO.setAppTypeEnum(AppTypeEnum.APP_TYPE_MAP.get(appDtoMap.get(appId).getTypeCode()));
                    appPriceCacheDTOS.add(appPriceCacheDTO);
                }
            }
            Map<Long, BigDecimal> appPriceMap = ResponseHandleUtil.parseMapResponse(appPriceCacheService.getCaches(appPriceCacheDTOS), Long.class, BigDecimal.class);
            List<Long> productIds = listKeywordVOS.stream().filter(s -> "PRODUCT".equalsIgnoreCase(s.getServeType())).map(ListKeywordVO::getServeId).collect(Collectors.toList());
            Map<Long, ProductDto> productDtoMap = productConsr.getProBasesByIds(productIds);
            Map<Long, Boolean> isSuperMap = productConsr.getIsSuperByProductIdList(productIds);
            for (ListKeywordVO listKeywordVO : listKeywordVOS) {
                if (ReplyTypeEnum.APP.value.equals(listKeywordVO.getReplyType())) {
                    if ("APP".equalsIgnoreCase(listKeywordVO.getServeType())) {
                        Long appId = listKeywordVO.getServeId();
                        AppDto appDto = appDtoMap.get(appId);
                        if (appDto != null) {
                            listKeywordVO.setTypeCode(appDto.getTypeCode());
                        }
                        if (appPriceMap != null) {
                            if (appPriceMap.get(appId) != null) {
                                listKeywordVO.setRetailPrice(appPriceMap.get(appId).doubleValue());
                                listKeywordVO.setDealPrice(0D);
                            }
                        }
                        listKeywordVO.setApSource("APP");
                    }
                    if ("PRODUCT".equalsIgnoreCase(listKeywordVO.getServeType())) {
                        Long productId = listKeywordVO.getServeId();
                        ProductDto productDto = productDtoMap.get(productId);
                        if (productDto != null) {
                            listKeywordVO.setTypeCode(productDto.getProductTypeCode());
                            List<SpecificationDto> specificationDtos = productDto.getSpecification();
                            if (!ListUtils.isEmpty(specificationDtos)) {
                                SpecificationDto specificationDto = specificationDtos.get(0);
                                if (specificationDto != null) {
                                    listKeywordVO.setRetailPrice(specificationDto.getAdvisePrice());
                                    listKeywordVO.setDealPrice(specificationDto.getDealPrice());
                                }
                            }
                        }
                        //判断是否为超级作者作品
                        if (isSuperMap != null && isSuperMap.get(productId) != null && isSuperMap.get(productId)) {
                            listKeywordVO.setApSource("SUPER_PRODUCT");
                        } else {
                            listKeywordVO.setApSource("PRODUCT");
                        }
                    }
                }
            }
            Map<Long,List<ListKeywordVO>> listMap=listKeywordVOS.stream().collect(Collectors.groupingBy(ListKeywordVO::getClassifyId));
            List<ListKeywordVO> bookKewordList = listKeywordVOS.stream().filter(s -> s.getClassifyId() == 0).collect(Collectors.toList());
            for (ClassifyKeywordDTO classifyKeywordDTO : classifyKeywordDTOS) {
                List<ListKeywordVO> list = listMap.get(classifyKeywordDTO.getClassifyId());
                if (list==null){
                    list=new ArrayList<>();
                }
                if (!ListUtils.isEmpty(bookKewordList)){
                    list.addAll(bookKewordList);
                }
                classifyKeywordDTO.setListKeywordVOS(list);
            }
        }
        return classifyKeywordDTOS;
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("更新是否显示书名")
    @Override
    public void updateIsShowBookName(Boolean isShowBookName, Long partyId) {
        bookGroupDao.updateIsShowBookName(isShowBookName,partyId);
    }

    @ParamLog("获取是否显示书名")
    @Override
    public Boolean getIsShowBookName(Long partyId) {
        return bookGroupDao.getIsShowBookName(partyId);
    }


    @Transactional(rollbackFor = Exception.class)
    @ParamLog("删除社群码")
    @Override
    public void deleteBookGroup(Long bookGroupId) {
        if (bookGroupId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "参数不能为空");
        }
        BookGroupDTO dto = bookGroupDao.getDTOById(bookGroupId);
        if (dto == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "没有该数据！");
        }
        if (dto.getBookId() != null && !new Long(0L).equals(dto.getBookId())) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "该社群码已经绑定图书！");
        }
        ClassifyAndGroupCountVO classifyAndGroupCount = bookGroupClassifyBiz.getClassifyAndGroupCount(bookGroupId);
        if (classifyAndGroupCount != null
                && ((classifyAndGroupCount.getClassifyCount() != null && classifyAndGroupCount.getClassifyCount() > 0)
                || (classifyAndGroupCount.getGroupCount() != null && classifyAndGroupCount.getGroupCount() > 0))) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "该社群码下已有分类！");
        }
        bookGroupDao.deleteByBookGroupId(bookGroupId);
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("根据分类id获取个人二维码信息")
    @Override
    public OwnAltQrcodeInfoDTO getOwnAltQrcodeInfoDTOByClassifyId(Long wechatUserId, Long classifyId) {
        OwnAltQrcodeInfoDTO ownAltQrcodeInfoDTO = new OwnAltQrcodeInfoDTO();
        //根据分类id查询社群码信息
        ClassifyDTO classifyDTO = bookGroupClassifyDao.getById(classifyId);
        if (classifyDTO == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "没有该分类");
        }
        Long bookId = classifyDTO.getBookId();
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("bookId", bookId);
        paramMap.put("adviserId", classifyDTO.getCreateUser());
        paramMap.put("channelId", classifyDTO.getChannelId());
        BookDto bookDto = bookDao.getById(paramMap);
        Long templetId = bookDto.getTempletId();
        //根据分类id获取大类
        TempletRelevance templetRelevance = templetRelevanceDao.getByTempletId(templetId);
        LOGGER.info("根据分类id获取大类templetRelevance" + templetRelevance.toString());
        Integer largeTemplet = templetRelevance.getLargeTemplet();
        SelfRobotDTO selfRobotDTO = wechatGroupConsr.getAvailableRobot(wechatUserId, largeTemplet, classifyId);
        if (selfRobotDTO == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "未找到机器人!");
        }
        ownAltQrcodeInfoDTO.setAltHeadUrl(selfRobotDTO.getHeadPic());
        ownAltQrcodeInfoDTO.setAltId(selfRobotDTO.getWxId());
        ownAltQrcodeInfoDTO.setAltNickName(selfRobotDTO.getNickName());
        ownAltQrcodeInfoDTO.setAltQrcodeUrl(selfRobotDTO.getQrcodeUrl());
        ownAltQrcodeInfoDTO.setAltHeadUrl(selfRobotDTO.getHeadPic());
        //获取之前是否有没有使用的暗号
        JoinGroupCipher joinGroupCipher = joinGroupCipherDao.getByWechatUserId(wechatUserId, classifyId);
        String cipher;
        if (joinGroupCipher != null) {
            cipher = joinGroupCipher.getCipher();
        } else {
            //新增暗号
            cipher = UUIDUitl.generateShort();
            //查重，如果有重复，再次生成
            JoinGroupCipher joinGroupCipherHas = joinGroupCipherDao.getByCipher(cipher);
            if (joinGroupCipherHas != null) {
                cipher = UUIDUitl.generateShort();
            }
            cipher = "RAYS_" + cipher;
            JoinGroupCipher joinGroupCipherNew = new JoinGroupCipher();
            joinGroupCipherNew.setCipher(cipher);
            joinGroupCipherNew.setWechatUserId(wechatUserId);
            joinGroupCipherNew.setClassifyId(classifyId);
            joinGroupCipherNew.setAltId(selfRobotDTO.getWxId());
            joinGroupCipherDao.insert(joinGroupCipherNew);
        }
        ownAltQrcodeInfoDTO.setCipher(cipher);
        return ownAltQrcodeInfoDTO;
    }

    @ParamLog("获取暗号状态")
    @Override
    public Integer getCipherState(String cipher) {
        Integer state;
        if (StringUtil.isEmpty(cipher)) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "参数不能为空！");
        }
        JoinGroupCipher joinGroupCipher = joinGroupCipherDao.getByCipher(cipher);
        if (joinGroupCipher == null) {
            //暗号错误
            state = 2;
        } else if (joinGroupCipher.getHasUsed() != null && joinGroupCipher.getHasUsed()) {
            //已使用
            state = 1;
        } else {
            //未使用
            state = 0;
        }
        return state;
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("获取暗号状态为已使用")
    @Override
    public void updateCipherStateToUsed(String cipher, String wxId) {
        if (StringUtil.isEmpty(cipher) || StringUtil.isEmpty(wxId)) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "参数不能为空！");
        }
        joinGroupCipherDao.updateCipherStateToUsed(cipher,wxId);
    }

    @ParamLog("获取个人二维码方式群已使用和未使用数量")
    @Override
    public GroupUseDTO getGroupUse(List<String> altIds) {
            if (ListUtils.isEmpty(altIds)) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "参数不能为空！");
        }
        GroupUseDTO groupUseDTO = new GroupUseDTO();
        Integer notUsed = weixinQrcodeDao.countByState(0, altIds);
        Integer hasUsed = weixinQrcodeDao.countByState(1, altIds);
        Integer full = weixinQrcodeDao.countByState(2, altIds);
        groupUseDTO.setHasUsed(hasUsed + full);
        groupUseDTO.setNotUsed(notUsed);
        return groupUseDTO;
    }

    @ParamLog("获取所有的大类分类")
    @Override
    public List<LargeTempletDTO> getAllLargTemplet() {
        List<LargeTempletDTO> list = new ArrayList<>();
        for (LargTempletEnum largTempletEnum : LargTempletEnum.values()) {
            LargeTempletDTO largeTempletDTO = new LargeTempletDTO();
            largeTempletDTO.setLargeTemplet(largTempletEnum.code);
            largeTempletDTO.setName(largTempletEnum.name);
            list.add(largeTempletDTO);
        }
        return list;
    }

    @ParamLog("根据微信id和机器人id获取分类集合")
    @Override
    public List<JoinGroupCipherDTO> getClassifyIdsByWxIdAndAltId(String wxId, String altId) {
        if (StringUtil.isEmpty(wxId) || StringUtil.isEmpty(altId)) {
            return new ArrayList<>();
        }
        List<JoinGroupCipherDTO> list = joinGroupCipherDao.getClassifyIdsByWxIdAndAltId(wxId, altId);
        return CollectionUtils.isEmpty(list) ? Lists.newArrayList() : list;
    }

    @ParamLog("获取暗号基本信息")
    @Override
    public GroupCipherDTO getJoinGroupCipher(String cipher) {
        if (StringUtil.isEmpty(cipher)) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "参数不能为空！");
        }
        JoinGroupCipher joinGroupCipher = joinGroupCipherDao.getByCipher(cipher);
        if (joinGroupCipher != null) {
            GroupCipherDTO groupCipherDTO = new GroupCipherDTO();
            BeanUtils.copyProperties(joinGroupCipher, groupCipherDTO);
            return groupCipherDTO;
        }
        return null;
    }

    @ParamLog("为信息流批量获取社群书基本信息")
    @Override
    public Map<Long, StoreFlowInfoDto> getFlowInfoByBookGroupIds(List<Long> bookGroupIds) {
        Map<Long, StoreFlowInfoDto> result = new HashMap<>();
        if (ListUtils.isEmpty(bookGroupIds)) {
            return null;
        }
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("bookGroupIds", bookGroupIds);
        List<Object> listBook4ChannelVOS = bookDao.listBy(paramMap, "getBookGroupInfo4Channel");
        if(ListUtils.isEmpty(bookGroupIds)){
            return new HashMap<>();
        }
        Map<Long, BookGroupStatisticDTO> statisMap = bookGroupClassifyBiz.getBookGroupStatistic(bookGroupIds);
        listBook4ChannelVOS.forEach( e ->{
            ListBook4ChannelVO listBook4ChannelVO = (ListBook4ChannelVO) e;
            StoreFlowInfoDto storeFlowInfoDto = new StoreFlowInfoDto();
            storeFlowInfoDto.setOriginId(listBook4ChannelVO.getBookGroupId());
            storeFlowInfoDto.setOriginType(StoreCons.OriginTypeEnum.BOOK_GROUP.getCode());
            storeFlowInfoDto.setCoverImg(listBook4ChannelVO.getCoverImg());
            storeFlowInfoDto.setTitle(listBook4ChannelVO.getBookName());
            if (!MapUtils.isEmpty(statisMap) && statisMap.containsKey(listBook4ChannelVO.getBookGroupId())) {
                BookGroupStatisticDTO dto = statisMap.get(listBook4ChannelVO.getBookGroupId());
                storeFlowInfoDto.setResourceNum(null != dto.getClassifyCount() ? dto.getClassifyCount() : 0);
                storeFlowInfoDto.setResourceItemNum(null != dto.getUserNumber() ? dto.getUserNumber() : 0);
            }else {
                storeFlowInfoDto.setResourceNum(0);
                storeFlowInfoDto.setResourceItemNum(0);
            }
            result.put(listBook4ChannelVO.getBookGroupId(), storeFlowInfoDto);
        });
        return result;
    }

    @ParamLog("获取指定条数社群书基本信息")
    @Override
    public Map<Long, StoreFlowInfoDto> getBookGroupInfoByChannelId(Long channelId, Integer itemNum) {
        Map<Long, StoreFlowInfoDto> result = new HashMap<>();
        PageParam pageParam = new PageParam(0, itemNum);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("channelId", channelId);
        PageBean listBookGroup4Channel = bookDao.listPage(pageParam, paramMap, "listBookGroup4Channel");
        List<Long> bookGroupIds = new ArrayList<>();
        listBookGroup4Channel.getRecordList().forEach(e -> {
            ListBook4ChannelVO listBook4ChannelVO = (ListBook4ChannelVO) e;
            bookGroupIds.add(listBook4ChannelVO.getBookGroupId());
        });
        if(ListUtils.isEmpty(bookGroupIds)){
            return new HashMap<>();
        }
        Map<Long, BookGroupStatisticDTO> statisMap = bookGroupClassifyBiz.getBookGroupStatistic(bookGroupIds);
        listBookGroup4Channel.getRecordList().forEach( e ->{
            ListBook4ChannelVO listBook4ChannelVO = (ListBook4ChannelVO) e;
            StoreFlowInfoDto storeFlowInfoDto = new StoreFlowInfoDto();
            storeFlowInfoDto.setOriginId(listBook4ChannelVO.getBookGroupId());
            storeFlowInfoDto.setOriginType(StoreCons.OriginTypeEnum.BOOK_GROUP.getCode());
            storeFlowInfoDto.setCoverImg(listBook4ChannelVO.getCoverImg());
            storeFlowInfoDto.setTitle(listBook4ChannelVO.getBookName());
            if (!MapUtils.isEmpty(statisMap) && statisMap.containsKey(listBook4ChannelVO.getBookGroupId())) {
                BookGroupStatisticDTO dto = statisMap.get(listBook4ChannelVO.getBookGroupId());
                storeFlowInfoDto.setResourceNum(null != dto.getClassifyCount() ? dto.getClassifyCount() : 0);
                storeFlowInfoDto.setResourceItemNum(null != dto.getUserNumber() ? dto.getUserNumber() : 0);
            }else {
                storeFlowInfoDto.setResourceNum(0);
                storeFlowInfoDto.setResourceItemNum(0);
            }
            result.put(listBook4ChannelVO.getBookGroupId(), storeFlowInfoDto);
        });
        return result;
    }


    @Override
    @ParamLog("知识商城获取社群书信息")
    public PageBeanNew<StoreFlowInfoDto> listBookGroup4KnowledgeMall(Long channelId, int currentPage, int numPerPage) {
        List<StoreFlowInfoDto> results = new ArrayList<>();
        PageParam pageParam = new PageParam(currentPage, numPerPage);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("channelId", channelId);
        PageBeanNew<ListBook4ChannelVO> resultInfos = bookDao.listPageNew(pageParam, paramMap, "listBookGroup4Channel");
        List<Long> bookGroupIds = resultInfos.getRecordList().stream().map(ListBook4ChannelVO::getBookGroupId).collect(Collectors.toList());
        if(ListUtils.isEmpty(bookGroupIds)){
            return new PageBeanNew(currentPage, numPerPage, 0, new ArrayList<>());
        }
        Map<Long, BookGroupStatisticDTO> statisMap = bookGroupClassifyBiz.getBookGroupStatistic(bookGroupIds);
        for (ListBook4ChannelVO listBook4ChannelVO : resultInfos.getRecordList()) {
            StoreFlowInfoDto storeFlowInfoDto = new StoreFlowInfoDto();
            storeFlowInfoDto.setOriginId(listBook4ChannelVO.getBookGroupId());
            storeFlowInfoDto.setOriginType(StoreCons.OriginTypeEnum.BOOK_GROUP.getCode());
            storeFlowInfoDto.setCoverImg(listBook4ChannelVO.getCoverImg());
            storeFlowInfoDto.setTitle(listBook4ChannelVO.getBookName());
            if (!MapUtils.isEmpty(statisMap) && statisMap.containsKey(listBook4ChannelVO.getBookGroupId())) {
                BookGroupStatisticDTO dto = statisMap.get(listBook4ChannelVO.getBookGroupId());
                storeFlowInfoDto.setResourceNum(null != dto.getClassifyCount() ? dto.getClassifyCount() : 0);
                storeFlowInfoDto.setResourceItemNum(null != dto.getUserNumber() ? dto.getUserNumber() : 0);
            } else {
                storeFlowInfoDto.setResourceNum(0);
                storeFlowInfoDto.setResourceItemNum(0);
            }
            results.add(storeFlowInfoDto);
        }
        return new PageBeanNew<>(currentPage, numPerPage, resultInfos.getTotalCount(), results);
    }

    @ParamLog("获取用户购买或者参与过的社群书信息")
    @Override
    public PageBeanNew<GroupStoreMyPayDto> getUserBrowseGroup4KnowLedgeMall(Long channelId, Long wechatUserId, Integer currentPage, Integer numPerPage) {
        List<GroupStoreMyPayDto> results = new ArrayList<>();
        PageParam pageParam = new PageParam(currentPage, numPerPage);
        List<Long> bookGroupIds = Lists.newArrayList();
        bookGroupIds = tradeConsr.getBuyBookGroupIdList(channelId, wechatUserId);
        Map<String, Object> paramMap = new HashMap<>();
        if(ListUtils.isEmpty(bookGroupIds)){
            return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        }
        paramMap.put("bookGroupIds", bookGroupIds);
        PageBeanNew<ListBook4ChannelVO> resultInfos = bookDao.listPageNew(pageParam, paramMap, "getBookGroupInfo4Channel");
        List<Long> groupIds = resultInfos.getRecordList().stream().map(ListBook4ChannelVO::getBookGroupId).collect(Collectors.toList());
        if(ListUtils.isEmpty(bookGroupIds)){
            return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        }
        Map<Long, BookGroupStatisticDTO> statisMap = bookGroupClassifyBiz.getBookGroupStatistic(groupIds);
        for (ListBook4ChannelVO listBook4ChannelVO : resultInfos.getRecordList()) {
            GroupStoreMyPayDto groupStoreMyPayDto = new GroupStoreMyPayDto();
            groupStoreMyPayDto.setOriginId(listBook4ChannelVO.getBookGroupId());
            groupStoreMyPayDto.setOriginType(StoreCons.OriginTypeEnum.BOOK_GROUP.getCode());
            groupStoreMyPayDto.setCoverImg(listBook4ChannelVO.getCoverImg());
            groupStoreMyPayDto.setOriginName(listBook4ChannelVO.getBookName());
            if (!MapUtils.isEmpty(statisMap) && statisMap.containsKey(listBook4ChannelVO.getBookGroupId())) {
                BookGroupStatisticDTO dto = statisMap.get(listBook4ChannelVO.getBookGroupId());
                groupStoreMyPayDto.setResourceNum(null != dto.getClassifyCount() ? dto.getClassifyCount() : 0);
                groupStoreMyPayDto.setResourceItemNum(null != dto.getUserNumber() ? dto.getUserNumber() : 0);
            } else {
                groupStoreMyPayDto.setResourceNum(0);
                groupStoreMyPayDto.setResourceItemNum(0);
            }
            results.add(groupStoreMyPayDto);
        }
        return new PageBeanNew<>(currentPage, numPerPage, resultInfos.getTotalCount(), results);
    }


    @Override
    public BookGroupStatisticsDTO getBookGroupStatisByBookGroupId(Long bookGroupId) {
        Map<Long, BookGroupStatisticDTO> bookGroupStatisticMap = bookGroupClassifyBiz.getBookGroupStatistic(Arrays.asList(bookGroupId));
        BookGroupStatisticsDTO bookGroupStatisticsDTO = new BookGroupStatisticsDTO();
        Long appCount = appTouchRecordDao.getCountByBokkGroupId(bookGroupId, "APP");
        Long productCount = appTouchRecordDao.getCountByBokkGroupId(bookGroupId, "PRODUCT");
        if (MapUtils.isEmpty(bookGroupStatisticMap)){
            bookGroupStatisticsDTO.setClassifyCount(0L);
            bookGroupStatisticsDTO.setGroupPersonNum(0L);
            bookGroupStatisticsDTO.setWxGroupCount(0L);
            bookGroupStatisticsDTO.setPromAppCount(appCount);
            bookGroupStatisticsDTO.setPromProductCount(productCount);
            return bookGroupStatisticsDTO;
        }
        bookGroupStatisticsDTO.setClassifyCount(bookGroupStatisticMap.get(bookGroupId).getClassifyCount().longValue());
        bookGroupStatisticsDTO.setGroupPersonNum(bookGroupStatisticMap.get(bookGroupId).getUserNumber().longValue());
        bookGroupStatisticsDTO.setWxGroupCount(bookGroupStatisticMap.get(bookGroupId).getGroupNumber().longValue());
        bookGroupStatisticsDTO.setPromAppCount(appCount);
        bookGroupStatisticsDTO.setPromProductCount(productCount);
        return bookGroupStatisticsDTO;
    }

    @Override
    public PageBeanNew<ResourcesStatisticVO> getGroupIncomeStatic(GroupIncomeStaticParamVO groupIncomeStaticParamVO, Long adviserId) {
        Long bookGroupId = groupIncomeStaticParamVO.getBookGroupId();
        Integer currentPage = groupIncomeStaticParamVO.getCurrentPage();
        Integer numPerPage = groupIncomeStaticParamVO.getNumPerPage();
        String type = groupIncomeStaticParamVO.getType();
        Long classifyId = groupIncomeStaticParamVO.getClassifyId();
        Long wxGroupId = groupIncomeStaticParamVO.getWxGroupId();
        if (currentPage==null||currentPage<0||numPerPage==null||numPerPage<=0){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"分页参数错误！");
        }
        if (bookGroupId==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"社群码id不能为空！");
        }
        if (type==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"类型不能为空");
        }
        PageParam pageParam = new PageParam(currentPage, numPerPage);
        Map<String, Object> map = new HashMap<>();
        map.put("bookGroupId", bookGroupId);
        map.put("type", type);
        if (null != classifyId){
            map.put("classifyId", classifyId);
        }
        if (null != wxGroupId){
            map.put("qrcodeId", wxGroupId);
        }
        PageBeanNew<ResourcesStatisticVO> pageBeanNew = appClickRecordDao.listPageNew(pageParam, map, "getClickStatistics");
        List<ResourcesStatisticVO> recordList = pageBeanNew.getRecordList();
        if (ListUtils.isEmpty(recordList)){
            return pageBeanNew;
        }
        //填充数据
        setInfo(recordList,bookGroupId,classifyId,wxGroupId,type,adviserId);
        return pageBeanNew;
    }

    void setInfo(List<ResourcesStatisticVO> recordList,Long bookGroupId,Long classifyId, Long qrcodeId, String type,Long partyId){
        List<Long> rescourceIds = recordList.stream().map(ResourcesStatisticVO::getRescourceId).collect(Collectors.toList());
//        map.put("rescourceIds",rescourceIds);
        GroupRescourceIncomeParamDTO groupRescourceIncomeParamDTO = new GroupRescourceIncomeParamDTO();
        groupRescourceIncomeParamDTO.setBookGroupId(bookGroupId);
        groupRescourceIncomeParamDTO.setClassifyId(classifyId);
        groupRescourceIncomeParamDTO.setQrcodeId(qrcodeId);
        groupRescourceIncomeParamDTO.setType(type);
        groupRescourceIncomeParamDTO.setRescourceIds(rescourceIds);
        groupRescourceIncomeParamDTO.setRoleId(5L);
        groupRescourceIncomeParamDTO.setPartyId(partyId);
        Map<Long, BigDecimal> rescourceIncome = bookConsr.getRescourceIncome(groupRescourceIncomeParamDTO);
        GroupIncomeSearchDto groupIncomeSearchDto = new GroupIncomeSearchDto();
        groupIncomeSearchDto.setBookGroupId(bookGroupId);
        groupIncomeSearchDto.setClassifyId(classifyId);
        groupIncomeSearchDto.setIds(rescourceIds);
        groupIncomeSearchDto.setQrcodeId(qrcodeId);
        groupIncomeSearchDto.setTypeCode(type);
        Map<Long, GroupMoneyDto> saleDetail4Group = tradeConsr.getSaleDetail4Group(groupIncomeSearchDto);
        Map<Long, AppDto> appDtoMap;
        Map<Long, ProductDto> productDtoMap;
        if ("APP".equals(type)){
            appDtoMap = appConsr.mapByIds(rescourceIds);
            recordList.forEach(e ->{
                if (!MapUtils.isEmpty(appDtoMap) && null != appDtoMap.get(e.getRescourceId())){
                    e.setRescourceName(appDtoMap.get(e.getRescourceId()).getTitle());
                }
                if (!MapUtils.isEmpty(saleDetail4Group) && null != saleDetail4Group.get(e.getRescourceId())){
                    e.setSaleCount(saleDetail4Group.get(e.getRescourceId()).getSaleCount());
                    e.setTotalSale(new BigDecimal(saleDetail4Group.get(e.getRescourceId()).getSaleMoney()));
                }else {
                    e.setSaleCount(0L);
                    e.setTotalSale(BigDecimal.ZERO);
                }
                e.setType("APP");
                if (null == rescourceIncome.get(e.getRescourceId())){
                    e.setTotalIncome(BigDecimal.ZERO);
                }else {
                    e.setTotalIncome(rescourceIncome.get(e.getRescourceId()));
                }
            });
        }else {
            productDtoMap = productConsr.getProBasesByIds(rescourceIds);
            recordList.forEach(e ->{
                if (!MapUtils.isEmpty(productDtoMap) && null != productDtoMap.get(e.getRescourceId())){
                    e.setRescourceName(productDtoMap.get(e.getRescourceId()).getProductName());
                }
                e.setType("PRODUCT");
                if (null == rescourceIncome.get(e.getRescourceId())){
                    e.setTotalIncome(BigDecimal.ZERO);
                }else {
                    e.setTotalIncome(rescourceIncome.get(e.getRescourceId()));
                }
                if (!MapUtils.isEmpty(saleDetail4Group) && null != saleDetail4Group.get(e.getRescourceId())){
                    e.setSaleCount(saleDetail4Group.get(e.getRescourceId()).getSaleCount());
                    e.setTotalSale(new BigDecimal(saleDetail4Group.get(e.getRescourceId()).getSaleMoney()));
                }else {
                    e.setSaleCount(0L);
                    e.setTotalSale(BigDecimal.ZERO);
                }
            });
        }
    }

    @Override
    public List<GroupScanTrendVO> getGroupScanTrend(GroupScanTrendParamVO groupScanTrendParamVO, Long adviserId) {
        Integer dayNum = groupScanTrendParamVO.getDayNum();
        if (dayNum == null) {
            groupScanTrendParamVO.setDayNum(30);
            dayNum = 30;
        }
        Date startDate = groupScanTrendParamVO.getStartDate();
        Date endDate = groupScanTrendParamVO.getEndDate();
        Long bookGroupId = groupScanTrendParamVO.getBookGroupId();
        Long classifyId = groupScanTrendParamVO.getClassifyId();
        Long wxGroupId = groupScanTrendParamVO.getWxGroupId();
        List<Date> dateList = settlementConsr.getDateList(dayNum, startDate, endDate);
        List<GroupScanTrendVO> groupScanTrendVOS = appClickRecordDao.getClickTrend(groupScanTrendParamVO);
        List<Date> collect = groupScanTrendVOS.stream().map(GroupScanTrendVO::getDate).collect(Collectors.toList());
        List<ClassifyPayDetailDto> groupBuyCount = tradeConsr.getGroupBuyCount(bookGroupId, classifyId, wxGroupId, startDate, endDate);
        List<String> tradeDate = groupBuyCount.stream().map(ClassifyPayDetailDto::getDivideDate).collect(Collectors.toList());
        if (dateList.size() > groupScanTrendVOS.size()) {
            dateList.forEach(e -> {
                if (!collect.contains(e)) {
                    GroupScanTrendVO groupScanTrendVO = new GroupScanTrendVO();
                    groupScanTrendVO.setDate(e);
                    groupScanTrendVO.setScanCount(0L);
                    groupScanTrendVOS.add(groupScanTrendVO);
                }
            });
        }
        if (ListUtils.isEmpty(groupBuyCount)){
            groupScanTrendVOS.forEach( e -> e.setBuyCount(0L));
        }else {
            groupScanTrendVOS.forEach(e -> {
                for (ClassifyPayDetailDto classifyPayDetailDto : groupBuyCount) {
                    if (DateUtils.formatDate(e.getDate()).equals(classifyPayDetailDto.getDivideDate())) {
                        e.setBuyCount(classifyPayDetailDto.getBuyCount());
                    } else {
                        e.setBuyCount(0L);
                    }
                }
            });
        }

        return groupScanTrendVOS;
    }

    @Override
    public PageBeanNew<GroupStatisticVO> getClassifyStatistic(Long bookGroupId, Long adviserId, Integer currentPage, Integer numPerPage) {
        PageParam pageParam = new PageParam(currentPage,numPerPage);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("bookGroupId",bookGroupId);
        PageBeanNew<GroupStatisticVO> pageClassify = bookGroupClassifyDao.listPageNew(pageParam, paramMap, "pageClassify");
        List<GroupStatisticVO> recordList = pageClassify.getRecordList();
        if (ListUtils.isEmpty(recordList)){
            return new PageBeanNew<>();
        }
        List<Long> classifyIds = recordList.stream().map(GroupStatisticVO::getClassifyId).collect(Collectors.toList());
        if (ListUtils.isEmpty(classifyIds)){
            return new PageBeanNew<>();
        }
        Map<Long, ClickClassifyDTO> longClickClassifyDTOMap = bookGroupClassifyDao.mapClickClassify(classifyIds);
        GetGroupClassifyIncomeDTO getGroupClassifyIncomeDTO = new GetGroupClassifyIncomeDTO();
        getGroupClassifyIncomeDTO.setClassifyIds(classifyIds);
        getGroupClassifyIncomeDTO.setPartyId(adviserId);
        getGroupClassifyIncomeDTO.setRoleId(5L);
        Map<Long, BigDecimal> classifyIncome = bookConsr.getClassifyIncome(getGroupClassifyIncomeDTO);
        Map<Long, Long> mapMemberCount = wechatGroupConsr.getclassifyMemberCount(classifyIds);
        recordList.forEach(e ->{

            if (longClickClassifyDTOMap.get(e.getClassifyId()) != null){
                Long count = longClickClassifyDTOMap.get(e.getClassifyId()).getCount()==null?0L:longClickClassifyDTOMap.get(e.getClassifyId()).getCount();
                e.setClickCount(count);
            }
            if (BigDecimal.ZERO.compareTo(e.getPrice()) ==0){
                e.setIsFree(1);
            }else {
                e.setIsFree(0);
            }
            if (!MapUtils.isEmpty(classifyIncome)){
                e.setIncome(classifyIncome.get(e.getClassifyId()));
            }else {
                e.setIncome(BigDecimal.ZERO);
            }
            if (!MapUtils.isEmpty(mapMemberCount)){
                e.setInGroupPersonCount(mapMemberCount.get(e.getClassifyId()));
            }else {
                e.setInGroupPersonCount(0L);
            }
        });
        return pageClassify;
    }

    @Override
    public List<WxGroupStatisticVO> getQrcodeStatistic(Long bookGroupId, Long classifyId, Long adviserId) {
        List<ClassifyQrcodeVO> qrcodeByClassify = groupQrcodeBiz.getQrcodeByClassify(bookGroupId, classifyId);
        if (ListUtils.isEmpty(qrcodeByClassify)){
            return new ArrayList<>();
        }
        List<Long> qrcodeIds = qrcodeByClassify.stream().map(ClassifyQrcodeVO::getId).collect(Collectors.toList());
        List<String> wxGroupIds = qrcodeByClassify.stream().map(ClassifyQrcodeVO::getWeixinGroupId).collect(Collectors.toList());
        GetGroupQrcodeIncomeDTO getGroupQrcodeIncomeDTO = new GetGroupQrcodeIncomeDTO();
        getGroupQrcodeIncomeDTO.setRoleId(5L);
        getGroupQrcodeIncomeDTO.setQrcodeIds(qrcodeIds);
        getGroupQrcodeIncomeDTO.setPartyId(adviserId);
        Map<Long, BigDecimal> qrcodeIncome = bookConsr.getQrcodeIncome(getGroupQrcodeIncomeDTO);
        Map<String, GroupMemberStatisDTO> groupMemberStatisDTOMap = wechatGroupConsr.listGroupMemberStatisInfo(wxGroupIds);
        List<WxGroupStatisticVO> wxGroupStatisticVOS = new ArrayList<>();
        qrcodeByClassify.forEach(e ->{
            WxGroupStatisticVO wxGroupStatisticVO = new WxGroupStatisticVO();
            wxGroupStatisticVO.setCreatedTime(e.getCreatedTime());
            wxGroupStatisticVO.setGroupPersonCount(e.getUserNumber().longValue());
            if (MapUtils.isEmpty(qrcodeIncome)){
                wxGroupStatisticVO.setIncome(BigDecimal.ZERO);
            }else {
                wxGroupStatisticVO.setIncome(qrcodeIncome.get(e.getId()));
            }
            if (MapUtils.isEmpty(groupMemberStatisDTOMap)){
                wxGroupStatisticVO.setInGroupPersonCount(0L);
            }else {
                wxGroupStatisticVO.setInGroupPersonCount(groupMemberStatisDTOMap.get(e.getWeixinGroupId()).getJoinCount().longValue());
            }
            wxGroupStatisticVO.setQrcodeId(e.getId());
            wxGroupStatisticVO.setWxGroupName(e.getGroupName());
            wxGroupStatisticVOS.add(wxGroupStatisticVO);
        });

        return wxGroupStatisticVOS;
    }

    @Override
    public TotalRescourceDataVO getTotalRescourceData(Long bookGroupId, Long adviserId, Long classifyId, Long qrcodeId, String type) {
        TotalRescourceDataVO totalRescourceDataVO = new TotalRescourceDataVO();
        List<Long> rescourceIds = appClickRecordDao.getRescourceIds(bookGroupId, classifyId, qrcodeId, type);
        Long rescourceTotalClick = appClickRecordDao.getRescourceTotalClick(bookGroupId, classifyId, qrcodeId, type);
        totalRescourceDataVO.setClickCount(rescourceTotalClick == null?0L:rescourceTotalClick);
        GroupRescourceIncomeParamDTO groupRescourceIncomeParamDTO = new GroupRescourceIncomeParamDTO();
        groupRescourceIncomeParamDTO.setBookGroupId(bookGroupId);
        groupRescourceIncomeParamDTO.setClassifyId(classifyId);
        groupRescourceIncomeParamDTO.setQrcodeId(qrcodeId);
        groupRescourceIncomeParamDTO.setType(type);
        groupRescourceIncomeParamDTO.setRescourceIds(rescourceIds);
        groupRescourceIncomeParamDTO.setPartyId(adviserId);
        groupRescourceIncomeParamDTO.setRoleId(5L);
        BigDecimal rescourceTotalIncome = bookConsr.getRescourceTotalIncome(groupRescourceIncomeParamDTO);
        totalRescourceDataVO.setTotalIncome(rescourceTotalIncome == null?BigDecimal.ZERO:rescourceTotalIncome);
        BigDecimal totalSale = tradeConsr.getTotalSale(bookGroupId, classifyId, qrcodeId, type);
        totalRescourceDataVO.setTotalSale(totalSale);
        return totalRescourceDataVO;
    }

    @Override
    public Map<String, String> exportRescourceIncomeData(Long bookGroupId, Long adviserId) {
        List<StatisticsIncomeDto> appStatisticsIncomeDtos = new ArrayList<>();
        List<StatisticsIncomeDto> productStatisticsIncomeDtos = new ArrayList<>();
        List<ResourcesStatisticVO> appClickStatistics = appClickRecordDao.getClickStatistics(bookGroupId, null, null, "APP");
        List<ResourcesStatisticVO> productClickStatistics = appClickRecordDao.getClickStatistics(bookGroupId, null, null, "PRODUCT");
        if (!ListUtils.isEmpty(appClickStatistics)){
            setInfo(appClickStatistics, bookGroupId, null, null, "APP", adviserId);
            //获取挂在应用下的商品信息
            ProductStaticUnderAppMapDTO productStaticUnderAppMapDTO = new ProductStaticUnderAppMapDTO();
            productStaticUnderAppMapDTO.setBookGroupId(bookGroupId);
            productStaticUnderAppMapDTO.setAppIds(appClickStatistics.stream().map(ResourcesStatisticVO::getRescourceId).collect(Collectors.toList()));
            productStaticUnderAppMapDTO.setPartyId(adviserId);
            productStaticUnderAppMapDTO.setRoleId(5L);
//            Map<Long, List<com.pcloud.settlementcenter.record.dto.ResourcesStatisticVO>> productStaticUnderApp = settlementConsr.getProductStaticUnderApp(productStaticUnderAppMapDTO);
//            Map<Long, List<StatisticsIncomeDto>> productStaticUnderAppMap = copy(productStaticUnderApp,bookGroupId);
            appClickStatistics.forEach(e ->{
                StatisticsIncomeDto statisticsIncomeDto = new StatisticsIncomeDto();
                statisticsIncomeDto.setAppId(e.getRescourceId());
                statisticsIncomeDto.setBookGroupId(bookGroupId);
                statisticsIncomeDto.setIncome(e.getTotalIncome());
                statisticsIncomeDto.setAppName(e.getRescourceName());
                statisticsIncomeDto.setSaleCounts(e.getSaleCount().intValue());
                statisticsIncomeDto.setSaleMoney(e.getTotalSale());
                statisticsIncomeDto.setScanCounts(e.getBrowseCount().intValue());
//                statisticsIncomeDto.setItemList(productStaticUnderAppMap.get(e.getRescourceId()));
                appStatisticsIncomeDtos.add(statisticsIncomeDto);
            });

        }
        if (!ListUtils.isEmpty(productClickStatistics)){
            setInfo(productClickStatistics, bookGroupId, null, null, "PRODUCT", adviserId);
            productClickStatistics.forEach(e ->{
                StatisticsIncomeDto statisticsIncomeDto = new StatisticsIncomeDto();
                statisticsIncomeDto.setProductId(e.getRescourceId());
                statisticsIncomeDto.setBookGroupId(bookGroupId);
                statisticsIncomeDto.setIncome(e.getTotalIncome());
                statisticsIncomeDto.setProductName(e.getRescourceName());
                statisticsIncomeDto.setSaleCounts(e.getSaleCount().intValue());
                statisticsIncomeDto.setSaleMoney(e.getTotalSale());
                statisticsIncomeDto.setScanCounts(e.getBrowseCount().intValue());
                productStatisticsIncomeDtos.add(statisticsIncomeDto);
            });
        }

        TotalRescourceDataVO appTotalRescourceData = getTotalRescourceData(bookGroupId, null, null, null, "APP");
        StatisticsIncomeDto appSumStatistics = setResourceSumStatistics(appTotalRescourceData);
        TotalRescourceDataVO productTotalRescourceData = getTotalRescourceData(bookGroupId, null, null, null, "PRODUCT");
        StatisticsIncomeDto productSumStatistics = setResourceSumStatistics(productTotalRescourceData);
        Map<String, Object> dataMap = new HashMap<>();
        BookGroupDTO bookGroupDTO = bookGroupDao.getDTOById(bookGroupId);
        if (bookGroupDTO == null){
            bookGroupDTO = new BookGroupDTO();
        }
        String groupQrcodeName = bookGroupDTO.getGroupQrcodeName()== null?" ":bookGroupDTO.getGroupQrcodeName();
        String title = "社群码" + groupQrcodeName + "的收益列表";
        dataMap.put("appIncomeList", appStatisticsIncomeDtos);
        dataMap.put("productIncomeList", productStatisticsIncomeDtos);
        dataMap.put("title", title);
        dataMap.put("appSumStatistics", appSumStatistics);
        dataMap.put("productSumStatistics", productSumStatistics);
        String today = DateUtils.formatDate(DateUtils.nowTimeStamp(), DateUtils.DATE_FORMAT_DATEONLY);
        String fileName = title+ "-" + today;
        String filePath = "";
        try {
            LOGGER.info("生成Excel【START】");
            filePath = ExcelExportor.uploadExcel(this.getClass(), dataMap, "template_bookGroupStatistics.ftl");
            LOGGER.info("生成Excel【END】" + filePath);
        } catch (Exception e) {
            LOGGER.error("生成Excel异常+++" + e.getMessage(), e);
            throw new BookBizException(BookBizException.ERROR, "导出失败，请联系管理员");
        }
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("fileName", fileName);
        resultMap.put("fileUrl", filePath);

        return resultMap;
    }

    private StatisticsIncomeDto setResourceSumStatistics(TotalRescourceDataVO totalRescourceDataVO){
        if (totalRescourceDataVO == null){
            return new StatisticsIncomeDto();
        }
        Long clickCount = totalRescourceDataVO.getClickCount();
        BigDecimal totalIncome = totalRescourceDataVO.getTotalIncome();
        BigDecimal totalSale = totalRescourceDataVO.getTotalSale();
        StatisticsIncomeDto statisticsIncomeDto = new StatisticsIncomeDto();
        statisticsIncomeDto.setScanCounts(clickCount.intValue());
        statisticsIncomeDto.setIncome(totalIncome);
        statisticsIncomeDto.setSaleMoney(totalSale);
        return statisticsIncomeDto;
    }

    private Map<Long, List<StatisticsIncomeDto>> copy(Map<Long, List<com.pcloud.settlementcenter.record.dto.ResourcesStatisticVO>> productStaticUnderApp,Long bookGroupId){
        Map<Long, List<StatisticsIncomeDto>> productStaticUnderAppMap = new HashMap<>();
        if (MapUtils.isEmpty(productStaticUnderApp)){
            return productStaticUnderAppMap;
        }
        List<StatisticsIncomeDto> productStatisticsIncomeDtos = new ArrayList<>();
        productStaticUnderApp.forEach((k,v) ->{
            v.forEach(e ->{
                StatisticsIncomeDto statisticsIncomeDto = new StatisticsIncomeDto();
                statisticsIncomeDto.setProductId(e.getRescourceId());
                statisticsIncomeDto.setIncome(e.getTotalIncome());
                statisticsIncomeDto.setProductName(e.getRescourceName());
                statisticsIncomeDto.setSaleCounts(e.getSaleCount() == null ? 0 : e.getSaleCount().intValue());
                statisticsIncomeDto.setSaleMoney(e.getTotalSale());
                statisticsIncomeDto.setScanCounts(e.getBrowseCount() == null? 0 :e.getBrowseCount().intValue());
                productStatisticsIncomeDtos.add(statisticsIncomeDto);
            });
            productStaticUnderAppMap.put(k,productStatisticsIncomeDtos);
        });
        return productStaticUnderAppMap;
    }

    @Override
    public Map<Long, Long> getResourcesBrowseCount(ResourceBrowseParamDto resourceBrowseParamDto) {
        Map<Long, Long> resultMap = new HashMap<>();
        Long bookGroupId = resourceBrowseParamDto.getBookGroupId();
        Long classifyId = resourceBrowseParamDto.getClassifyId();
        Long qrcodeId = resourceBrowseParamDto.getQrcodeId();
        String typeCode = resourceBrowseParamDto.getTypeCode();
        List<Long> ids = resourceBrowseParamDto.getIds();
        if (ListUtils.isEmpty(ids)){
            return resultMap;
        }
        Map<String, Object> map = new HashMap<>();
        map.put("bookGroupId", bookGroupId);
        map.put("classifyId", classifyId);
        map.put("qrcodeId", qrcodeId);
        map.put("type", typeCode);
        map.put("rescourceIds", ids);
        Map<Long, ResourceClickVO> resourceClick = appClickRecordDao.getResourceClick(map);
        if (MapUtils.isEmpty(resourceClick)){
            return resultMap;
        }
        resourceClick.forEach((k,v) ->{
            resultMap.put(k,v.getClickCount());
        });
        return resultMap;
    }


}
