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

import com.alibaba.fastjson.JSONObject;
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.SettlementConsr;
import com.pcloud.book.consumer.trade.TradeConsr;
import com.pcloud.book.consumer.user.AdviserConsr;
import com.pcloud.book.group.biz.BookGroupBiz;
import com.pcloud.book.group.biz.BookGroupClassifyBiz;
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.dto.AppStatisticsDTO;
import com.pcloud.book.group.dto.BookGroupDTO;
import com.pcloud.book.group.dto.BookGroupStatisticDTO;
import com.pcloud.book.group.dto.ClassifyKeywordDTO;
import com.pcloud.book.group.dto.QrcodeNameAndProIdDTO;
import com.pcloud.book.group.entity.BookGroup;
import com.pcloud.book.group.vo.StatisticVO;
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.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.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.QrcodeUtils;
import com.pcloud.common.utils.ResponseHandleUtil;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.common.utils.zip.CompressUtils;
import com.pcloud.facade.tradecenter.dto.GroupMoneyDto;
import com.pcloud.facade.tradecenter.dto.SpeWechatGroupDto;
import com.pcloud.facade.tradecenter.dto.WechatGroupDto;
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.settlementcenter.record.service.SettlementService;
import com.pcloud.videolesson.schedule.service.ScheduleService;
import com.pcloud.wechatgroup.group.service.GroupMemberService;

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 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.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 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;


    @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);
        if (ListUtils.isEmpty(list)) {
            return null;
        }
        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()) || StringUtil.isEmpty(bookGroup.getPersonalQrcodeUrl())) {
            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 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
    @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);
            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<>();
            if (productSaleMap.values() != null && !productSaleMap.values().isEmpty()) {
                dealSale(videoProductIds, videoPProductMapIds, productSaleMap, proSaleMap);
                dealSale(audioProductIds, audioPProductMapIds, productSaleMap, proSaleMap);
                dealSale(liveProductIds, livePProductMapIds, productSaleMap, proSaleMap);
                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, toAddCount, appStatisticsDTO);
                    }
                }
            }
        }
    }

    private void addProductSale(Long id, Map<Long, ProductDto> productDtoMap, Map<Long, Double> proSaleMap, 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);
            if (toAdd != null) {
                Double oldSale = appStatisticsDTO.getSaleAmount();
                if (oldSale == null) {
                    oldSale = 0D;
                }
                appStatisticsDTO.setSaleAmount(oldSale + toAdd);
            }
            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) {
        if (!ListUtils.isEmpty(ids)) {
            for (Long id : ids) {
                List<Long> productIds = productMapIds.get(id);
                if (!ListUtils.isEmpty(productIds)) {
                    Double saleMoney = 0D;
                    Long  saleCount = 0L;
                    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();
                            }
                        }
                    }
                    saleMap.put(id, saleMoney);
                }
            }
        }
    }

    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);
    }

}
