/**
 *
 */
package com.pcloud.book.book.biz.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import com.alibaba.fastjson.JSONObject;
import com.pcloud.analysisengine.qrcode.dto.BookTimeSourceDto;
import com.pcloud.appcenter.assist.dto.AssistTempletDTO;
import com.pcloud.appcenter.base.exception.AppBizException;
import com.pcloud.book.applet.biz.AppletBookClassifyBiz;
import com.pcloud.book.applet.entity.AppletUserLabelRelation;
import com.pcloud.book.applet.enums.LabelTypeEnum;
import com.pcloud.book.base.enums.BookFreezeEnum;
import com.pcloud.book.base.enums.BookStatusEnum;
import com.pcloud.book.base.enums.BookTypeEnum;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.biz.BookAdviserBiz;
import com.pcloud.book.book.biz.BookAppBiz;
import com.pcloud.book.book.biz.BookBiz;
import com.pcloud.book.book.biz.BookFreezeBiz;
import com.pcloud.book.book.biz.BookFundBiz;
import com.pcloud.book.book.biz.BookProductBiz;
import com.pcloud.book.book.biz.BookResourceBiz;
import com.pcloud.book.book.cache.BookCache;
import com.pcloud.book.book.constant.BookConstant;
import com.pcloud.book.book.dao.BookAdviserDao;
import com.pcloud.book.book.dao.BookDao;
import com.pcloud.book.book.dao.BookLabelDao;
import com.pcloud.book.book.dao.BookRaysClassifyDao;
import com.pcloud.book.book.dto.AdviserBookInfoDTO;
import com.pcloud.book.book.dto.BookAdviserDto;
import com.pcloud.book.book.dto.BookAdviserUpdateTimeDTO;
import com.pcloud.book.book.dto.BookAssocCount;
import com.pcloud.book.book.dto.BookCoverImgUpdateDTO;
import com.pcloud.book.book.dto.BookDetialDTO;
import com.pcloud.book.book.dto.BookDto;
import com.pcloud.book.book.dto.BookFreezeDto;
import com.pcloud.book.book.dto.BookFundDto;
import com.pcloud.book.book.dto.BookInfo4AnlysicsDTO;
import com.pcloud.book.book.dto.BookInfoAnalysicsDTO;
import com.pcloud.book.book.dto.BookInfoAndAuthStatusDTO;
import com.pcloud.book.book.dto.BookNameUpdateDTO;
import com.pcloud.book.book.entity.Book;
import com.pcloud.book.book.entity.BookAdviser;
import com.pcloud.book.book.entity.BookLabel;
import com.pcloud.book.book.set.BookSet;
import com.pcloud.book.book.tools.BookTools;
import com.pcloud.book.book.vo.BookQualifyVO;
import com.pcloud.book.book.vo.BookSaleVO;
import com.pcloud.book.book.vo.ListNoAuthBookParam;
import com.pcloud.book.book.vo.ListNoAuthGroupBookParam;
import com.pcloud.book.book.vo.SearchBookVO;
import com.pcloud.book.book.vo.request.BookQualifyInfoVO;
import com.pcloud.book.book.vo.request.BookSearchParamVO;
import com.pcloud.book.book.dto.BookUniqueNumberDTO;
import com.pcloud.book.book.vo.request.UpdateBookRobotProcessDto;
import com.pcloud.book.consumer.analysisengine.SceneRecordConsr;
import com.pcloud.book.consumer.app.AssistTempletConsr;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.common.ExportConsr;
import com.pcloud.book.consumer.isbn.IsbnConsr;
import com.pcloud.book.consumer.message.MessageConsr;
import com.pcloud.book.consumer.raystask.MainLineConsr;
import com.pcloud.book.consumer.user.AdviserConsr;
import com.pcloud.book.consumer.user.AgentConsr;
import com.pcloud.book.consumer.user.ChannelConsr;
import com.pcloud.book.consumer.user.PartyConsr;
import com.pcloud.book.consumer.wechat.WechatConsr;
import com.pcloud.book.copyright.biz.BookAuthInfoBiz;
import com.pcloud.book.copyright.vo.BookAuthInfoVO;
import com.pcloud.book.es.biz.ESBookAndAdviserBiz;
import com.pcloud.book.es.entity.ESBookAndAdviser;
import com.pcloud.book.group.biz.BookGroupBiz;
import com.pcloud.book.group.dao.BookAppletSceneDao;
import com.pcloud.book.group.dao.BookGroupDao;
import com.pcloud.book.group.dto.BookGroupDTO;
import com.pcloud.book.group.entity.BookAppletScene;
import com.pcloud.book.group.enums.JoinGroupTypeEnum;
import com.pcloud.book.mq.producer.BookMQProducer;
import com.pcloud.book.rightsSetting.mapper.RightsSettingBookRelationMapper;
import com.pcloud.book.util.common.ThreadPoolUtils;
import com.pcloud.channelcenter.wechat.dto.BookServeParamVO;
import com.pcloud.channelcenter.wechat.vo.BookServeVO;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.constant.AgentTypeEnum;
import com.pcloud.common.core.constant.SystemCode;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.exceptions.ExportException;
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.cache.redis.JedisClusterUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.commoncenter.export.service.ExportService;
import com.pcloud.usercenter.party.adviser.dto.AdviserBaseInfoDto;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @描述：书籍业务层接口实现类
 * @作者：songx
 * @创建时间：2016年12月23日,下午3:00:08 @版本：1.0
 */
@Service("bookBiz")
public class BookBizImpl implements BookBiz {

    /**
     *
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(BookBizImpl.class);
    private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(5);
    @Autowired
    private BookDao bookDao;
    @Autowired
    private BookFundBiz bookFundBiz;
    @Autowired
    private BookProductBiz bookProductBiz;
    @Autowired
    private BookAppBiz bookAppBiz;
    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;
    @Autowired
    private BookAdviserBiz bookAdviserBiz;
    @Autowired
    private BookSet bookSet;
    @Autowired
    private ChannelConsr channelConsr;
    @Autowired
    private IsbnConsr isbnConsr;
    @Autowired
    private BookResourceBiz bookResourceBiz;
    @Autowired
    private BookCache bookCache;
    @Autowired
    private SceneRecordConsr sceneRecordConsr;
    @Autowired
    private AgentConsr agentConsr;
    @Autowired
    private AdviserConsr adviserConsr;
    @Autowired
    private PartyConsr partyConsr;
    @Autowired
    private BookFreezeBiz bookFreezeBiz;
    @Autowired
    private AssistTempletConsr assistTempletConsr;
    @Autowired
    private BookMQProducer bookMQProducer;
    @Autowired
    private BookAuthInfoBiz bookAuthInfoBiz;
    @Autowired
    private MainLineConsr mainLineConsr;
    @Autowired
    private BookGroupBiz bookGroupBiz;
    @Autowired
    private BookLabelDao bookLabelDao;

    @Autowired
    private ExportService exportService;
    @Autowired
    private ExportConsr exportConsr;
    @Autowired
    private MessageConsr messageConsr;
    @Autowired
    private ESBookAndAdviserBiz esBookAndAdviserBiz;
    @Autowired
    private BookGroupDao bookGroupDao;
    @Autowired
    private BookRaysClassifyDao bookRaysClassifyDao;

    @Autowired
    private BookAppletSceneDao bookAppletSceneDao;

    @Autowired
    private BookAdviserDao bookAdviserDao;


    @Autowired
    private WechatConsr wechatConsr;
    @Autowired
    private RightsSettingBookRelationMapper rightsSettingBookRelationMapper;


    @Autowired
    private AppletBookClassifyBiz appletBookClassifyBiz;






    /**
     * 创建书籍,同时建立与编辑的推广关系
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BookDto create(Book book, String systemCode) throws BizException {
        LOGGER.info("【书籍基础】创建书籍基础信息,<START>.[book]:{};systemCode:{}", book, systemCode);
        this.checkAddParam(book);
        // 判断书籍ISBN码是否存在,同时判断书籍ISBN码是否符合规范
        if (this.isbnExists(book.getTypeCode(), book.getIsbn(), book.getSerialNumber())) {
            throw new BookBizException(BookBizException.DB_SELECT_MORE, "书刊已存在");
        }

        if (SystemCode.adviser.code.equalsIgnoreCase(systemCode) &&
                (Objects.isNull(book.getTempletId()) || Objects.isNull(book.getSecondTempletId()))) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊分类");
        }

        bookDao.insert(book);
        esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(book.getBookId()));
        BookDto bookDto = bookDao.getByIsbnAndSnum(book.getIsbn(), book.getSerialNumber());
        bookDto.setBookId(book.getBookId());
        bookDto.setTempletId(book.getTempletId());
        bookDto.setSecondTempletId(book.getSecondTempletId());
        // 如果是编辑创建的书籍、默认建立编辑与书籍的推广关系
        if (SystemCode.adviser.code.equalsIgnoreCase(systemCode)) {
            setBookAdviserRelation(book);
        }
        // 书籍总数缓存加1
        bookCache.incrObject(BookConstant.BOOK_CACHE + "PLATFORM_BOOK_COUNT");
        return bookDto;
    }

    /**
     * 校验参数
     */
    private void checkAddParam(Book book) throws BizException {
        if (StringUtil.isEmpty(book.getIsbn())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "书籍ISBN码不能为空");
        }
        if (StringUtil.isEmpty(book.getBookName())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "书籍名称不能为空");
        }
        if (StringUtil.isEmpty(book.getTypeCode())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "类型编码不能为空");
        }
        if (StringUtil.isEmpty(book.getPublishDate())) {
            book.setPublishDate(null);
        }
        if (StringUtil.isEmpty(book.getSerialNumber())) {
            book.setSerialNumber(null);
        }
    }

    /**
     * 修改书籍
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Book book) throws BizException {
        LOGGER.info("【书籍基础】修改书籍基础信息,<PARAM>.[book]={}", book);
        // 校验参数
        this.checkParam(book);
        //获取图书基本信息
        BookDto bookDto = this.getBaseById(book.getBookId());
        checkIsUpdateCoverImgAndSendTopic(bookDto, book.getCoverImg());
        checkIsUpdateBookNameAndSendTopic(bookDto, book.getBookName());
        bookDao.update(book);
        esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(book.getBookId()));
        // 清除redis中数据
        bookCache.clearRedisByBook(book.getBookId(), book.getIsbn(), book.getSerialNumber());
    }

    @ParamLog("校验是否修改图书名称并发送修改名称topic")
    private void checkIsUpdateBookNameAndSendTopic(BookDto oldBook, String newBookName) {
        if (newBookName != null && !newBookName.equalsIgnoreCase(oldBook.getBookName())) {
            BookNameUpdateDTO bookNameUpdateDTO = new BookNameUpdateDTO();
            bookNameUpdateDTO.setBookId(oldBook.getBookId());
            bookNameUpdateDTO.setBookName(newBookName);
            bookMQProducer.sendUpdateBookNameTopic(bookNameUpdateDTO);
        }
    }

    @ParamLog("校验是否修改图书封面图并发送修改封面图topic")
    void checkIsUpdateCoverImgAndSendTopic(BookDto oldBook, String newCoverImg) {
        if (newCoverImg != null && !newCoverImg.equalsIgnoreCase(oldBook.getCoverImg())) {
            BookCoverImgUpdateDTO bookCoverImgUpdateDTO = new BookCoverImgUpdateDTO();
            bookCoverImgUpdateDTO.setBookId(oldBook.getBookId());
            bookCoverImgUpdateDTO.setCoverImg(newCoverImg);
            bookMQProducer.sendUpdateBookCoverImgTopic(bookCoverImgUpdateDTO);
        }
    }

    /**
     * 修改书籍封面图
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCoverImg(Book book) throws BizException {
        LOGGER.info("【书籍基础】修改书籍基础信息,<PARAM>.[book]=" + book);
        // 获取图书基本信息校验是否默认图书
        BookDto bookDto = this.getBaseById(book.getBookId());
        if (BookConstant.DEFAULT_BOOK_ISBN.equals(bookDto.getIsbn())
                && StringUtils.isEmpty(bookDto.getSerialNumber())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "默认图书不能修改！");
        }
        bookDao.updateCoverImg(book);
        esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(book.getBookId()));
        checkIsUpdateCoverImgAndSendTopic(bookDto, book.getCoverImg());
        // 清除redis中数据
        bookCache.clearRedisByBook(bookDto.getBookId(), bookDto.getIsbn(), bookDto.getSerialNumber());
    }

    /**
     * 修改书籍(编辑)
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BookDto updateByAdviser(Book book) throws BizException {
        LOGGER.info("【书籍基础】修改书籍基础信息,<PARAM>.[book]=" + book);
        checkParam(book);
        // 设置编辑书刊关联关系
        setBookAdviserRelation(book);
        if (BookConstant.DEFAULT_BOOK_ISBN.equals(book.getIsbn()) && StringUtils.isEmpty(book.getSerialNumber())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "默认图书不能修改！");
        }
        // 修改书籍
        bookDao.update(book);
        esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(book.getBookId()));
        BookDto bookDto = new BookDto();
        bookDto.setBookId(book.getBookId());
        bookDto.setTempletId(book.getTempletId());
        bookDto.setSecondTempletId(book.getSecondTempletId());
        // 清除redis中数据
        bookCache.clearRedisByBook(book.getBookId(), book.getIsbn(), book.getSerialNumber());
        checkIsUpdateCoverImgAndSendTopic(bookDto, book.getCoverImg());
        checkIsUpdateBookNameAndSendTopic(bookDto, book.getBookName());
        return bookDto;
    }

    /**
     * 校验参数
     */
    private void checkParam(Book book) throws BizException {
        if (StringUtil.isEmpty(book.getIsbn())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "书籍ISBN码不能为空");
        }
        if (StringUtil.isEmpty(book.getBookName())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "书籍名称不能为空");
        }
        if (BookTypeEnum.BOOK.value.equalsIgnoreCase(book.getTypeCode())) {
            if (!StringUtils.isEmpty(book.getPublishDate())) {
                try {
                    DateUtils.StringToShortDate(book.getPublishDate());
                } catch (Exception e) {
                    LOGGER.warn("【书籍-编辑】参数校验:时间格式非法,<ERROR>:" + e.getMessage(), e);
                    throw new BookBizException(BookBizException.TIME_FORMAT_ERROR, "出版时间格式非法");
                }
            }
        }
        if (StringUtil.isEmpty(book.getPublishDate())) {
            book.setPublishDate(null);
        }
        if (StringUtil.isEmpty(book.getSerialNumber())) {
            book.setSerialNumber(null);
        }
        if (StringUtil.isEmpty(book.getCoverImg())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "图书封面图不能为空");
        }
        if (BookConstant.DEFAULT_BOOK_ISBN.equals(book.getIsbn()) && StringUtils.isEmpty(book.getSerialNumber())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "默认图书不能修改！");
        }
        //modify 20200601 /book/update 平台端去掉校验
       /* if (Objects.isNull(book.getTempletId()) || Objects.isNull(book.getSecondTempletId())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊分类");
        }*/
    }

    /**
     * 删除书籍
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long bookId, Long deleteUserId) throws BizException {
        LOGGER.info("【书籍基础】删除书籍,<PARAM>.[bookId]=" + bookId + "[deleteUserId]=" + deleteUserId);
        if (bookId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择要删除的书刊");
        }
        BookDto book = getBaseById(bookId);
        if (BookConstant.DEFAULT_BOOK_ISBN.equals(book.getIsbn()) && StringUtils.isEmpty(book.getSerialNumber())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "默认图书不能删除！");
        }
        // 判断是否有基金
        List<BookFundDto> bookFundList = bookFundBiz.getByBookId(bookId);
        if (!ListUtils.isEmpty(bookFundList)) {
            throw new BookBizException(BookBizException.ERROR, "该书刊已经有基金支持，不能删除！");
        }
        // 判断当前和以后图书是否被冻结
        List<BookFreezeDto> bookFreezeList = bookFreezeBiz.getFreezeInfo(bookId);
        if (!ListUtils.isEmpty(bookFreezeList)) {
            throw new BookBizException(BookBizException.ERROR, "该书刊已经被冻结，不能删除！");
        }

        // 删除书籍与编辑关联关系
        bookAdviserBiz.deleteByBook(bookId);
        // 删除图书
        Integer result = bookDao.deleteBook(bookId, deleteUserId);
        esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(book.getBookId()));
        if (result == 0) {
            throw BookBizException.DB_DELETE_RESULT_0;
        }
        // 发送书籍删除topic
        bookSet.sendBookDeleteTopic(bookId);
        // 书籍总数缓存减1
        bookCache.decrObject(BookConstant.BOOK_CACHE + "PLATFORM_BOOK_COUNT");
        // 清除缓存
        bookCache.clearRedisByBook(bookId, book.getIsbn(), book.getSerialNumber());
    }

    /**
     * 批量删除书籍
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletes(String bookIdStrs, Long deleteUserId) throws BizException {
        LOGGER.info("【书籍基础】批量删除书籍,<PARAM>.[bookIdStrs]=" + bookIdStrs + "[deleteUserId]=" + deleteUserId);
        if (StringUtil.isEmpty(bookIdStrs)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择要删除的书刊");
        }
        List<Long> bookIds = Arrays.asList(bookIdStrs.split(",")).stream().map(s -> Long.parseLong(s.trim()))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(bookIds)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择要删除的书刊");
        }

        // 判断当前和以后基金是否被冻结
        List<BookFreezeDto> bookFreezeList = bookFreezeBiz.listFreezeInfo(bookIds);
        if (!ListUtils.isEmpty(bookFreezeList)) {
            throw new BookBizException(BookBizException.ERROR, "所选书刊中有一部分书刊已经被冻结，不能删除！");
        }

        Integer result = bookDao.deleteByIds(bookIds, deleteUserId);
        esBookAndAdviserBiz.updateBookAndAdviserToES(bookIds);
        if (result == 0) {
            throw BookBizException.DB_DELETE_RESULT_0;
        }

        // 发送书籍批量删除topic
        bookSet.sendBooksDeleteTopic(bookIds);

        // 书籍总数缓存减去相应大小
        Integer bookCount = bookCache.getBookCountToRedis();
        if (null == bookCount || bookCount.equals(0)) {
            bookCount = bookCount - bookIds.size();
        }
        // 清除并将数据存入redis
        bookCache.delBookCountToRedis();
        bookCache.setBookCountToRedis(bookCount);
    }

    /**
     * 获取书籍基础信息
     */
    @Override
    public BookDto getBaseById(Long bookId) throws BizException {
        LOGGER.info("【书籍基础】获取书籍基础信息,<PARAM>.[bookId]=" + bookId);
        if (bookId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
        }
        // 从redis获取书籍信息
        BookDto bookDto = bookCache.getBookToRedis(bookId);
        if (null == bookDto) {
            bookDto = bookDao.getBaseById(bookId);
            BookAdviserDto bookAdviserDto = bookAdviserBiz.getOneMainBook(bookId);
            if (null != bookDto && null != bookAdviserDto){
                bookDto.setTempletId(bookAdviserDto.getTempletId());
                bookSet.setFirstTemplateName(bookDto);
            }
            // 将数据存入redis
            bookCache.setBookToRedis(bookDto);
        }
        return bookDto == null ? new BookDto() : bookDto;
    }

    /**
     * 调用外部接口新增书籍信息
     */
    public void insertBook(String isbn) {
        try {
            // 调用外部接口获取该图书的基本信息
            Book bookInfo = isbnConsr.getBook(isbn);
            if (bookInfo != null && bookInfo.getIsbn() != null) {
                // 添加书籍信息(设置添加人为平台)
                bookInfo.setCreatedUser(0l);
                try {
                    bookDao.insert(bookInfo);
                    esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(bookInfo.getBookId()));
                } catch (Exception e) {
                    LOGGER.error("书刊已存在" + e.getMessage(), e);
                }
            }
        } catch (Exception e) {
            LOGGER.error("ISBN新增书籍失败！" + e.getMessage(), e);
        }
    }

    /**
     * 根据ISBN获取书刊信息
     */
    @Override
    public BookDto getByIsbn(String isbn, String serialNumber) throws BizException {
        LOGGER.info("【书刊基础】根据ISBN获取书刊信息,<START>.[isbn]=" + isbn);
        if (StringUtil.isEmpty(isbn)) {
            throw new AppBizException(AppBizException.PARAM_IS_NULL, "请选择书刊");
        }
        if (StringUtils.isEmpty(serialNumber)) {
            serialNumber = null;
        }
        // 从redis获取书刊信息
        BookDto bookDto = bookCache.getBookToRedisByIsbn(isbn, serialNumber);
        if (bookDto == null) {
            bookDto = bookDao.getByIsbnAndSnumContainsDelete(isbn, serialNumber);
            // 将数据存入redis
            bookCache.setBookToRedisByIsbn(bookDto);
        }
        return bookDto;
    }

    /**
     * 判断ISBN是否存在
     */
    @Override
    public Boolean isbnExists(String typeCode, String isbn, String serialNumber) throws BizException {
        LOGGER.info("【书籍基础】判断ISBN是否存在,<START>.[isbn]=" + isbn + ",[typeCode]=" + typeCode);
        if (StringUtil.isEmpty(isbn)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "ISBN码不能为空");
        }
        if (StringUtil.isEmpty(typeCode)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "书籍类型不能为空");
        }
        if (StringUtil.isEmpty(serialNumber)) {
            serialNumber = null;
        }

        // 校验书号
        bookSet.checkISBN(typeCode, isbn);
        BookDto bookDto = bookDao.getByIsbnAndSnum(isbn, serialNumber);
        return bookDto != null;
    }

    /**
     * 获取单个书籍基础信息(包含统计信息)
     */
    @Override
    public BookDto getById(Long bookId, Long adviserId, Long channelId) throws BizException {
        LOGGER.info("【书籍基础】获取单个书籍基础信息(包含统计信息),<START>.[bookId]=" + bookId + ",[adviserId]=" + adviserId
                + ",[channelId]=" + channelId);
        if (bookId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
        }
        if (channelId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择运营平台");
        }
        BookDto bookDto = null;
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("bookId", bookId);
        paramMap.put("adviserId", adviserId);
        paramMap.put("channelId", channelId);
        bookDto = bookDao.getById(paramMap);
        if (bookDto == null) {
            return new BookDto();
        }
        // 设置渠道信息
        bookDto.setChannelId(channelId);
        bookDto.setChannelName(channelConsr.getNameById(channelId));
        // 设置主编辑信息
        Long mainAdviserId = bookAdviserBiz.getMainAdviserId(bookId, channelId);
        bookSet.setMainEditorInfo(bookDto, mainAdviserId);
        // 设置是否冻结
        bookSet.setFreezeStatus(bookDto);
        //	设置模板名字
        bookSet.setTemplateName(bookDto);
        // 设置专业深度目的标签
        bookSet.setProDepPurLabelName(bookDto);
        // 设置唯一编号
        bookDto.setUniqueNumber("BK" + bookDto.getBookId());
        // 设置二维码个数
        bookDto.setQrcodeCount(qrcodeSceneConsr.getBookQRCountByMap(adviserId, channelId, bookId));
        return bookDto;
    }

    /**
     * 获取单个书籍基础信息(包含统计信息)
     */
    @Override
    public BookDto getById4Platform(Long bookId, Long adviserId, Long channelId) throws BizException {
        LOGGER.info("【书籍基础】获取单个书籍基础信息,<START>.[bookId]=" + bookId + ",[adviserId]=" + adviserId
                + ",[channelId]=" + channelId);
        if (bookId == null || channelId == null || adviserId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "参数有误！");
        }
        BookDto bookDto = null;
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("bookId", bookId);
        paramMap.put("adviserId", adviserId);
        paramMap.put("channelId", channelId);
        bookDto = bookDao.getById(paramMap);
        if (bookDto == null) {
            return new BookDto();
        }
        bookDto.setAdviserId(adviserId);
        bookDto.setChannelId(channelId);
        String adviserName = adviserConsr.getNameById(adviserId);
        bookDto.setAdviserName(adviserName);
        Long agentId = adviserConsr.getAgentIdByAdviser(adviserId);
        Map<Long, String> agentNameMap = agentConsr.getNames(Collections.singletonList(agentId));
        if (!MapUtils.isEmpty(agentNameMap) && agentNameMap.containsKey(agentId)) {
            bookDto.setAgentName(agentNameMap.get(agentId));
        }
        return bookDto;
    }

    /**
     * 批量获取书籍信息
     */
    @Override
    public Map<Long, BookDto> getListByIds(List<Long> bookIds) throws BizException {
        LOGGER.info("【书籍基础】批量获取书籍信息,<PARAM>.[bookIds]=" + bookIds.toString());
        if (bookIds == null || bookIds.isEmpty()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
        }
        Map<Long, BookDto> bookMap = null;
        try {
            bookMap = bookDao.getMapByIds(bookIds);
            if (bookMap == null) {
                bookMap = Maps.newHashMap();
            }
        } catch (Exception e) {
            LOGGER.error("【书籍基础】批量获取书籍信息,<ERROR>.[bookDao.getMapByIds]:" + e.getMessage(), e);
            throw BizException.DB_SELECT_IS_FAIL;
        }
        return bookMap;
    }

    /**
     * 批量获取书籍信息（书名 与书刊序号 封面图）
     */
    @Override
    public Map<Long, BookDto> listBaseByIds(List<Long> bookIds) throws BizException {
        LOGGER.info("【书籍基础】批量获取书籍信息（书名 与书刊序号 封面图）,<PARAM>.[bookIds]=" + bookIds);
        if (bookIds == null || bookIds.isEmpty()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
        }
        Map<Long, BookDto> bookMap;
        try {
            bookMap = bookDao.listBaseMapByIds(bookIds);
            if (bookMap == null) {
                bookMap = Maps.newHashMap();
            }
        } catch (Exception e) {
            LOGGER.error("【书籍基础】批量获取书籍信息（书名 与书刊序号 封面图）,<ERROR>.[bookDao.listBaseByIds]:" + e.getMessage(), e);
            throw BizException.DB_SELECT_IS_FAIL;
        }
        return bookMap;
    }

    @Override
    public Map<String, BookDto> listDetailByIds(BookDetialDTO bookDetialDTO) throws BizException {
        Map<String, BookDto> bookMap = null;
        if (null != bookDetialDTO && !(null == bookDetialDTO || ListUtils.isEmpty(bookDetialDTO.getBookIds()) || ListUtils.isEmpty(bookDetialDTO.getChannelId()))) {
            Map<String, Object> paramMap = Maps.newHashMap();
            paramMap.put("bookIds", bookDetialDTO.getBookIds());
            paramMap.put("channelIds", bookDetialDTO.getChannelId());
            paramMap.put("adviserId", bookDetialDTO.getAdviserId());
            List<BookDto> bookDtos = bookDao.listDetailByIds(paramMap);
            if (!ListUtils.isEmpty(bookDtos)) {
                bookMap = Maps.newHashMap();
                for (BookDto bookDto : bookDtos) {
                    bookMap.put(bookDto.getChannelId() + "_" + bookDto.getBookId(), bookDto);
                }
            }
        }
        return bookMap;
    }

    /**
     * 获取书籍列表
     */
    @Override
    public PageBeanNew<BookDto> getListPage(String isbn, String bookName, String publish, String fundName,
            String serialNumber, Integer isCurrentMonth, Integer currentPage, Integer numPerPage) throws BizException {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("isbn", isbn != null && "".equals(isbn.trim()) ? null : isbn);
        paramMap.put("bookName", bookName != null && "".equals(bookName.trim()) ? null : bookName);
        paramMap.put("publish", publish != null && "".equals(publish.trim()) ? null : publish);
        paramMap.put("fundName", fundName != null && "".equals(fundName.trim()) ? null : fundName);
        paramMap.put("serialNumber", serialNumber != null && "".equals(serialNumber.trim()) ? null : serialNumber);
        paramMap.put("isCurrentMonth", isCurrentMonth);
        paramMap.put("currentPage", currentPage * numPerPage);
        paramMap.put("numPerPage", numPerPage);

        if(!StringUtil.isEmpty(bookName)){
            String[] bookNameList = bookName.trim().split("\\s+");
            paramMap.put("bookNameList",Lists.newArrayList(bookNameList));
        }

        List<BookDto> bookList = bookDao.getListPage4Platform(paramMap);

        // 获取平台端所有账号用户名
        Map<Long, String> pcloudUserMap = partyConsr.getAllUserLoginName(0L, SystemCode.pcloud.code);
        if (!ListUtils.isEmpty(bookList) && !pcloudUserMap.isEmpty()) {
            for (BookDto bookDto : bookList) {
                List<BookFundDto> bookFunds = bookDto.getBookFunds();
                Integer freezeStatus = BookFreezeEnum.WAIT_FREEZE.value;
                boolean isFundSupport = false;
                BookFreezeDto bf = bookFreezeBiz.getById(bookDto.getBookId());
                String transferor = bf == null ? null : bf.getTransferor();
                if (!ListUtils.isEmpty(bookFunds)) {
                    for (BookFundDto bookFundDto : bookFunds) {
                        if (StringUtil.isEmpty(transferor)) {
                            transferor = bookFundDto.getTransferor();
                        }
                        Date startTime = bookFundDto.getStartTime();
                        Date endTime = bookFundDto.getEndTime();
                        if (new Date().before(startTime)) {
                            bookFundDto.setButton(2);
                            freezeStatus = BookFreezeEnum.NO_FREEZE.value;
                        } else if (new Date().after(startTime) && new Date().before(endTime)) {
                            bookFundDto.setButton(1);
                            freezeStatus = BookFreezeEnum.NO_FREEZE.value;
                        } else {
                            bookFundDto.setButton(0);
                        }
                        Long opearateUserId = bookFundDto.getLastModifiedUser();
                        if (pcloudUserMap.containsKey(opearateUserId)) {
                            bookFundDto.setOperateUserName(pcloudUserMap.get(opearateUserId));
                        }
                        if (new Date().before(endTime)) {
                            isFundSupport = true;
                        }
                    }
                    bookDto.setIsHaveFund(true);
                }
                bookDto.setTransferor(transferor);
                bookDto.setIsFundSupport(isFundSupport);
                bookDto.setFreezeStatus(freezeStatus);
            }
        }
        int totalCount;
        if (StringUtil.isEmpty(isbn) && StringUtil.isEmpty(bookName) && StringUtil.isEmpty(publish)
                && StringUtil.isEmpty(fundName) && StringUtil.isEmpty(serialNumber) && null == isCurrentMonth) {
            totalCount = this.getAllBookCount();
        } else {
            totalCount = bookDao.getBookCount4Platform(paramMap);
        }
        if (!ListUtils.isEmpty(bookList)) {
            bookSet.setPageDetailInfo4Platform(bookList);
        }
        PageBeanNew<BookDto> result = new PageBeanNew<>();
        result.setCurrentPage(currentPage);
        result.setNumPerPage(numPerPage);
        result.setRecordList(bookList);
        result.setTotalCount(totalCount);
        return result;
    }

    /**
     * 获取书籍总数信息
     * @return
     */
    public int getAllBookCount() {
        Integer bookCount = bookCache.getBookCountToRedis();
        if (null == bookCount || bookCount < 10) {
            try {
                bookCount = bookDao.getAllBookCount();
                // 将数据存入redis
                bookCache.setBookCountToRedis(bookCount);
            } catch (Exception e) {
                LOGGER.error("【书籍基础】获取书籍总数信息,<ERROR>.[getAllBookCount]:" + e.getMessage(), e);
                throw BizException.DB_SELECT_IS_FAIL;
            }
        }
        return bookCount;
    }

    /**
     * 获取书籍列表(编辑)
     */
    @Override
    public PageBean getListPage4Adviser(Map<String, Object> paramMap, PageParam pageParam, Long adviserId, Integer hasQrcode) throws BizException {
        LOGGER.info("【书籍应用】获取书籍列表,<START>.[paramMap]=" + paramMap);
        PageBean pageBean = bookDao.listPage(pageParam, paramMap, "getListPage4Adviser");
        if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBean(0, 0, new ArrayList<>());
        }
        if (null != hasQrcode && 1 == hasQrcode) {
            List<Long> channelIds = BookTools.listChannelIds(pageBean.getRecordList());
            List<com.pcloud.channelcenter.qrcode.dto.BookDto> bookIds = qrcodeSceneConsr.getQrcodeBookIds(channelIds, adviserId);
            if (ListUtils.isEmpty(bookIds)){
                return new PageBean(0, 0, new ArrayList<>());
            }
            paramMap.put("bookIds", bookIds);
            pageBean = bookDao.listPage(pageParam, paramMap, "getListPage4Adviser");
            if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
                return new PageBean(0, 0, new ArrayList<>());
            }
        }
        // 填充渠道基础信息
        bookSet.setChannelInfoList(pageBean.getRecordList());
        bookSet.setBookSvUvPv4Object(pageBean.getRecordList());
        // 填充模板信息
        bookSet.setTemplateName(pageBean.getRecordList());
        // 设置是否被冻结
        bookSet.setFreezeStatus(pageBean.getRecordList());
        // 设置图书是否关联二维码
        bookSet.setIsRelationQrcodeAndCount(pageBean.getRecordList(), adviserId);
        //设置图书收益
        bookSet.setBookIncome(pageBean.getRecordList());
        // 设置二维码相关信息
        bookSet.setQrInfo(pageBean.getRecordList());
        //社群书相关信息
        bookSet.setBookGroupInfo(pageBean.getRecordList());
        return pageBean;
    }

    @ParamLog(description = "首页展示正在做的图书", isAfterReturn = false)
    @Override
    public List<BookDto> getList4Adviser(Long adviserId, Integer num, Boolean isPrint) throws BizException {
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("adviserId", adviserId);
        paramMap.put("num", num);
        paramMap.put("isPrint", isPrint);
        paramMap.put("isbns", BookConstant.DEFAULT_BOOK_ISBN);
        List<BookDto> bookDtos = bookDao.getList4Adviser(paramMap);
        if (!ListUtils.isEmpty(bookDtos)) {
            // 填充渠道基础信息
            bookSet.setChannelInfoList(Lists.newArrayList(bookDtos));
            bookSet.setBookSvUvPv4Object(Lists.newArrayList(bookDtos));
            // 填充模板信息
            bookSet.setTemplateName(Lists.newArrayList(bookDtos));
            // 设置是否被冻结
            bookSet.setFreezeStatus(Lists.newArrayList(bookDtos));
            // 设置图书是否关联二维码
            bookSet.setIsRelationQrcodeAndCount(Lists.newArrayList(bookDtos), adviserId);
            //设置图书收益
            bookSet.setBookIncome(Lists.newArrayList(bookDtos));
            // 设置二维码相关信息
            bookSet.setQrInfo(Lists.newArrayList(bookDtos));
            // 填充社群码相关信息
            bookSet.seBookGroupInfo(Lists.newArrayList(bookDtos));
        }
        return bookDtos;
    }

    /**
     * 微信端获取书籍列表(编辑)
     */
    @Override
    public PageBean getListPage4Wechat(Map<String, Object> paramMap, PageParam pageParam, Long adviserId)
            throws BizException {
        LOGGER.info("【书籍应用】微信端获取书籍列表,<START>.[paramMap]=" + paramMap);
        PageBean pageBean = bookDao.listPage(pageParam, paramMap, "getListPage4Adviser");
        if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBean(0, 0, new ArrayList<>());
        }
        // 填充渠道基础信息
        bookSet.setPageDetailInfo4Wechat(pageBean.getRecordList(), adviserId);
        // 设置图书扫码量读者量浏览量
        bookSet.setBookSvUvPv4Object(pageBean.getRecordList());
        // 填充模板信息
        bookSet.setTemplateName(pageBean.getRecordList());
        // 设置冻结状态
        bookSet.setFreezeStatus(pageBean.getRecordList());
        return pageBean;
    }

    /**
     * 获取书籍详细信息
     */
    @Override
    public BookDto getDetailById(Long bookId, Long adviserId, Long channelId) throws BizException {
        LOGGER.info("【书籍应用】获取书籍详细信息,<START>.[bookId]=" + bookId + ",[channelId]=" + channelId + ",[adviserId]="
                + adviserId);
        if (bookId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
        }
        if (channelId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择运营平台");
        }
        // 如果编辑标识为空，取配置该书籍的编辑的top1
        if (adviserId == null) {
            adviserId = bookAdviserBiz.getAdviserTop1(bookId, channelId);
        }
        // 获取书籍基本信息
        BookDto bookDto = this.getBaseById(bookId);
        if (BookTypeEnum.JOURNAL.value.equals(bookDto.getTypeCode())) {
            // 获取运营名称
            String channelName = channelConsr.getNameById(channelId);
            bookDto.setChannelName(channelName);
            bookDto.setAgentType(agentConsr.getAgentType(channelId, SystemCode.channel.code));
        }
        // 填充书籍关联的问答
        bookDto.setProducts(bookProductBiz.getQaListById(bookId, adviserId, channelId));
        return bookDto;
    }

    /**
     * 根据名称获取ID
     */
    @Override
    public List<Long> getIdsByName(String bookName) throws BizException {
        LOGGER.info("【书籍顾问】根据名称获取ID,<START>.[bookName]=" + bookName);
        if (StringUtil.isEmpty(bookName)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请输入书籍名称");
        }
        List<Long> bookIds = null;
        try {
            bookIds = bookDao.getIdsByName(bookName);
            if (bookIds == null) {
                bookIds = Lists.newArrayList();
            }
        } catch (Exception e) {
            LOGGER.error("【书籍-顾问】根据名称获取ID,<ERROR>.[getIdsByName]:" + e.getMessage(), e);
            throw BizException.DB_SELECT_IS_FAIL;
        }
        return bookIds;
    }

    /**
     * 根据名称获取ID
     */
    @Override
    public List<Long> getIdsByName(String bookName, Long adviserId) throws BizException {
        LOGGER.info("【书籍顾问】根据名称获取ID,<START>.[bookName|adviserId]=" + bookName + "|" + adviserId);
        if (StringUtil.isEmpty(bookName)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请输入书籍名称");
        }
        if (adviserId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请输入编辑ID");
        }
        List<Long> bookIds = null;
        try {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("bookName", bookName);
            paramMap.put("adviserId", adviserId);
            bookIds = bookDao.getIdsByNameMap(paramMap);
            if (bookIds == null) {
                bookIds = Lists.newArrayList();
            }
        } catch (Exception e) {
            LOGGER.error("【书籍-顾问】根据名称获取ID,<ERROR>.[getIdsByNameMap]:" + e.getMessage(), e);
            throw BizException.DB_SELECT_IS_FAIL;
        }
        return bookIds;
    }

    /**
     * 图书收益，获取单个书籍基础信息(包含统计信息)
     */
    @Override
    public BookDto getById4Profit(Long bookId, Long adviserId, Long channelId) throws BizException {
        LOGGER.info("【图书收益】获取单个书籍基础信息(包含统计信息),<PARAM>.[bookId]=" + bookId + ",[adviserId]=" + adviserId
                + ",[channelId]=" + channelId);
        if (bookId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
        }
        if (channelId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择运营平台");
        }
        BookDto bookDto = this.getBaseById(bookId);
        if (bookDto.getBookId() == null) {
            return bookDto;
        }
        // 获取第一次扫描时间
        BookTimeSourceDto bookTimeSourceDto = sceneRecordConsr.getBookScanInfo(bookId, channelId, adviserId);
        if (bookTimeSourceDto != null) {
            bookDto.setFirstScanDate(bookTimeSourceDto.getScanTimes());
            bookDto.setFirstSceneName(bookTimeSourceDto.getSceneName());
        }
        // 设置渠道名称
        bookDto.setChannelName(channelConsr.getNameById(channelId));
        return bookDto;
    }

    /**
     * 判断isbn是否存在,存在返回书籍信息
     * @throws IOException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BookDto isbnExistsOrGetInfo(Book book) {
        LOGGER.info("【书籍基础】判断ISBN是否存在,<PARAM>.[isbn]=" + book.getIsbn());
        // 校验书号合法性
        bookSet.checkISBN(book.getTypeCode(), book.getIsbn());
        if (StringUtils.isEmpty(book.getSerialNumber())) {
            book.setSerialNumber(null);
        }
        // 获取最近书刊信息
        BookDto journalDto = bookDao.getByIsbn(book.getIsbn());
        if (BookTypeEnum.BOOK.value.equals(book.getTypeCode()) && journalDto == null) {
            try {
                // 调用外部接口查询书籍信息
                insertBook(book.getIsbn());
                journalDto = bookDao.getByIsbn(book.getIsbn());
            } catch (Exception e) {
                LOGGER.error("【书刊基础】根据ISBN获取书刊信息,<ERROR>.[getByJournIsbn]:" + e.getMessage(), e);
                throw BizException.DB_SELECT_IS_FAIL;
            }
        }

        if (null != journalDto) {
            BookDto journal = bookDao.getByIsbnAndSnum(book.getIsbn(), book.getSerialNumber());
            if (journal != null) {
                journalDto = journal;
            }
        }

        return journalDto;
    }

    /**
     * 创建书籍顾问关联关系
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setBookAdviserRelation(Book book) throws BizException {
        BookAdviser bookAdviser = new BookAdviser();
        bookAdviser.setBookId(book.getBookId());
        bookAdviser.setAdviserId(book.getCreatedUser());
        bookAdviser.setChannelId(book.getChannelId());
        bookAdviser.setCreatedUser(book.getCreatedUser());
        bookAdviser.setSerialNumber(book.getSerialNumber());// 设置刊物序号
        bookAdviser.setTempletId(book.getTempletId());
        bookAdviser.setSecondTempletId(book.getSecondTempletId());
        bookAdviserBiz.create(bookAdviser);
    }

    /**
     * 获取书籍基本信息
     */
    @Override
    public BookDto getBaseInfoById4Wechat(Long bookId) {
        LOGGER.info("【书籍-应用-微信】获取书籍基本信息,<START>.[bookId]=" + bookId);
        if (bookId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
        }
        // 获取书籍基本信息
        BookDto bookDto = this.getBaseById(bookId);
        return bookDto;
    }

    /**
     * 根据ISBN获取期刊分页列表
     */
    @Override
    public PageBean getJournalPageByIsbn(PageParam pageParam, String typeCode, String isbn, Long channelId,
            Long wechatUserId) {
        LOGGER.info("【书籍-书刊管理-微信】根据ISBN获取期刊分页列表getJournalPageByIsbn,<START>.[isbn]=" + isbn);
        if (isbn == null || "".equals(isbn.toLowerCase().trim())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "isbn不存在!");
        }
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("typeCode", typeCode);
        paramMap.put("isbn", isbn);
        paramMap.put("channelId", channelId);
        PageBean pageBean = bookDao.listPage(pageParam, paramMap, "getJournalPage4Adviser");
        if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBean();
        }
        // 设置是否加入书架
        bookSet.setIsHaveAddBookcase(pageBean.getRecordList(), wechatUserId);
        // 设置模板名称
        bookSet.setTemplateName(pageBean.getRecordList());
        return pageBean;
    }

    /**
     * 获取书刊列表（微信客户端）
     */
    @Override
    public PageBean listPage4Wechat(PageParam pageParam, Long channelId, Long wechatUserId) {
        LOGGER.info("【书籍-书刊管理-微信】分页获取书刊列表,<START>.[channelId]=" + channelId);
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("channelId", channelId);
        PageBean pageBean = bookDao.listPage(pageParam, paramMap, "listPage4Wechat");
        if (pageBean == null || pageBean.getRecordList().isEmpty()) {
            return new PageBean();
        }
        // 设置是否加入书架
        bookSet.setIsHaveAddBookcase(pageBean.getRecordList(), wechatUserId);
        // 设置图书扫码量读者量浏览量
        bookSet.setBookSvUvPv4Object(pageBean.getRecordList());
        // 设置模板名称(图书类型)
        bookSet.setTemplateName(pageBean.getRecordList());
        return pageBean;
    }

    /**
     * 根据ISBN码获取书籍详情（包含二维码个数，应用个数，商品个数）
     */
    @Override
    public BookDto getDetailByIsbn(String isbn, String serialNumber) {
        LOGGER.info("根据ISBN码获取书籍详情（包含二维码个数，应用个数，商品个数）,isbn=" + isbn);
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("isbn", isbn);
        paramMap.put("serialNumber", serialNumber);
        // 获取书籍基本信息
        BookDto bookDto = bookDao.getDetailByIsbn(paramMap);
        if (bookDto != null) {
            Map<String, Object> qrMap = qrcodeSceneConsr.getQr4Book(bookDto.getBookId());
            if (qrMap != null) {
                bookDto.setQrcodeCount((Integer) qrMap.get("qrCount"));
                bookDto.setLatestQrcode((String) qrMap.get("qrcodeUrl"));
            }
        }
        return bookDto;
    }

    /**
     * 获取书刊信息
     */
    @Override
    public List<Object> listBook(Long adviserId, Integer number) {
        LOGGER.info("【书籍-首页】 获取书刊信息,<START>.[adviserId]=" + adviserId + "number" + number);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("adviserId", adviserId);
        paramMap.put("number", number);
        List<Object> books = bookDao.listBy(paramMap, "listBook");
        // 填充渠道基础信息
        bookSet.setChannelInfoList(books);
        // 设置图书扫码量读者量浏览量
        bookSet.setBookSvUvPv4Object(books);
        // 设置模板名称(图书类型)
        bookSet.setTemplateName(books);
        return books;
    }

    /**
     * 获取书刊信息 app - 编辑
     */
    @Override
    public PageBean listBook4App(Long adviserId, PageParam pageParam, String bookName) {
        LOGGER.info("【书籍-首页】 获取书刊信息,<START>.[adviserId]=" + adviserId + "pageParam" + pageParam);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("adviserId", adviserId);
        paramMap.put("bookName", bookName);
        PageBean pageBean = null;
        try {
            pageBean = bookDao.listPage(pageParam, paramMap, "listBook4App");
        } catch (Exception e) {
            LOGGER.error("【书籍-首页】获取书籍列表,<ERROR>.[listPage]:" + e.getMessage(), e);
            throw BizException.DB_SELECT_IS_FAIL;
        }
        if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBean();
        }
        // 设置模板名称(图书类型)
        bookSet.setTemplateName(pageBean.getRecordList());
        // 设置图书扫码量读者量浏览量
        bookSet.setBookSvUvPv4Object(pageBean.getRecordList());
        // 设置基金状态
        bookSet.setFreezeStatus(pageBean.getRecordList());
        return pageBean;
    }

    /**
     * 书刊列表-出版端
     */
    @Override
    public PageBean listPage4Agent(PageParam pageParam, Map<String, Object> paramMap, Long agentId) {
        LOGGER.info("书刊列表-出版端,<START>.[paramMap]=" + paramMap + ",agentId" + agentId);
        List<Long> adviserIds = adviserConsr.getIdsByNameAndAgentId(agentId, (String) paramMap.get("bookName"));
        List<Long> agent4AdviserIds = adviserConsr.getIdsByNameAndAgentId(agentId, null);
        paramMap.put("adviserIds", adviserIds);
        paramMap.put("agent4AdviserIds", agent4AdviserIds);
        if (ListUtils.isEmpty(agent4AdviserIds)) {
            return new PageBean(0, 0, new ArrayList<>());
        }
        PageBean pageBean = bookDao.listPage(pageParam, paramMap, "listPage4Agent");
        if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBean();
        }
        // 填充渠道基础信息
        bookSet.setChannelInfoList(pageBean.getRecordList());
        // 设置编辑名称
        bookSet.setAdviserName4BookDto(pageBean.getRecordList());
        // 设置图书扫码量读者量浏览量
        bookSet.setBookSvUvPv4Object(pageBean.getRecordList());
        // 设置冻结状态
        bookSet.setFreezeStatus(pageBean.getRecordList());
        // 设置模板名称(图书类型)
        bookSet.setTemplateName(pageBean.getRecordList());
        if (agentId.equals(getAgentIdByType())) {
            //	设置待审核二维码个数
            bookSet.setAuditWaitNum(pageBean.getRecordList());
        }
        return pageBean;
    }

    /**
     * 获取应用关联图书
     */
    @Override
    public List<BookDto> listBookByAppId(Long appId, Long channelId) {
        LOGGER.info("【编辑书刊】获取应用关联图书,<START>.[appId]=" + appId + ",[channelId]=" + channelId);
        try {
            Map<String, Object> paramMap = Maps.newHashMap();
            paramMap.put("appId", appId);
            paramMap.put("channelId", channelId);
            return bookDao.listBookByAppId(paramMap);
        } catch (Exception e) {
            LOGGER.error("【编辑书刊】获取应用关联图书,<ERROR>.[listBookByAppId]:" + e.getMessage(), e);
            throw new BookBizException(BookBizException.DB_DML_FAIL, "获取应用关联图书失败");
        }
    }

    /**
     * 书刊回收站列表（30天内删除的书刊列表）
     */
    @Override
    public PageBean listPageDelete4Adviser(Long adviserId, PageParam pageParam) {
        LOGGER.info("【编辑书刊】书刊回收站列表,<START>.[adviserId]=" + adviserId);
        PageBean pageBean = null;
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("adviserId", adviserId);
        try {
            pageBean = bookDao.listPage(pageParam, paramMap, "listPageDelete4Adviser");
        } catch (Exception e) {
            LOGGER.error("【编辑书刊】书刊回收站列表,<ERROR>.[listPageDelete4Adviser]:" + e.getMessage(), e);
            throw BizException.DB_SELECT_IS_FAIL;
        }
        // 填充渠道基础信息
        bookSet.setChannelInfoList(pageBean.getRecordList());
        // 设置图书扫码量读者量浏览量
        bookSet.setBookSvUvPv4Object(pageBean.getRecordList());
        // 设置图书类型
        bookSet.setTemplateName(pageBean.getRecordList());
        return pageBean;
    }

    /**
     * 获取图书关联统计个数(商品，应用，资源)
     */
    @Override
    public BookAssocCount getCount4BookAssoc(Long bookId, Long channelId, Long adviserId) {
        LOGGER.info("【编辑书刊】获取图书关联统计个数(商品，应用，资源),<START>.[bookId]=" + bookId + ",channelId=" + channelId);
        BookAssocCount bookAssocCount = new BookAssocCount();
        bookAssocCount.setResourceCount(bookResourceBiz.getResourceCount(adviserId, bookId, channelId));
        bookAssocCount.setProductCount(bookProductBiz.getProCount(adviserId, bookId, channelId));
        bookAssocCount.setSuperProCount(bookProductBiz.getSuperProCount(adviserId, bookId, channelId));
        bookAssocCount.setAppCount(bookAppBiz.getAppCount(adviserId, bookId, channelId));
        return bookAssocCount;
    }

    /**
     * 导出出版下所有书刊excel表（出版端）
     */
    @Override
    public void exportBookToExcel(Long agentId) {
        LOGGER.info("导出出版下所有书刊excel表（出版端），agentId=" + agentId);
        // 获取代理下所有编辑
        List<Long> adviserIds = adviserConsr.getByAgentId(agentId);
        if (ListUtils.isEmpty(adviserIds)) {
            throw new BookBizException(BookBizException.ERROR, "您还没有图书！");
        }
        ThreadPoolUtils.OTHER_THREAD_POOL.execute(new Runnable() {
            public void run() {
                Date sendDate = new Date();
                try {
                    // 获取出版下所有二维码
                    Map<String, Object> param = new HashMap<String, Object>();
                    param.put("adviserIds", adviserIds);
                    // 获取默认书籍
                    BookDto book = getByIsbn("9787507600000", null);
                    if (book != null) {
                        param.put("bookId", book.getBookId());
                    }
                    // 获取图书总数除RAYS现代纸书
                    Integer count = bookDao.getAllBookCount4Agent(param);
                    List<Object[]> dataList = new ArrayList<Object[]>();
                    if (count > BookConstant.BOOK_SELECT_COUNT) {
                        for (int i = 0, titalCount = (count + BookConstant.BOOK_SELECT_COUNT - 1)
                                / BookConstant.BOOK_SELECT_COUNT; i < titalCount; i++) {
                            param.put("currentPage", i * BookConstant.BOOK_SELECT_COUNT);
                            param.put("numPerPage", BookConstant.BOOK_SELECT_COUNT);
                            List<Object> agentBook = bookDao.listBy(param, "getAllBook4Agent");
                            List<Object[]> excelData = bookSet.getExcelData(agentBook);
                            dataList.addAll(excelData);
                            agentBook.clear();
                            excelData.clear();
                        }
                    } else {
                        List<Object> agentBook = bookDao.listBy(param, "getAllBook4Agent");
                        List<Object[]> excelData = bookSet.getExcelData(agentBook);
                        dataList.addAll(excelData);
                    }
                    // 生成excel
                    String url = bookSet.createExcel(dataList);
                    if (!StringUtils.isEmpty(url)) {
                        // 发送站内信
                        bookSet.sendBookExportLetter(agentId, url, sendDate);
                    }
                } catch (Exception e) {
                    LOGGER.error("生成导出文件失败", e);
                }
            }
        });

    }

    /**
     * 根据isbn获取图书信息
     */
    @Override
    public Map<Long, BookDto> listByIsbn(String isbn) {
        LOGGER.info("根据isbn获取图书信息isbn=" + isbn);
        Map<Long, BookDto> bookMap = bookDao.listByIsbn(isbn);
        LOGGER.info("根据isbn获取图书信息END");
        return bookMap;
    }

    /**
     * 图书列表（平台端）
     */
    @Override
    public PageBean listBookClassify(PageParam pageParam, Map<String, Object> paramMap) {
        LOGGER.info("图书列表（平台端）<START>,paramMap=" + paramMap);
        PageBean pageBean = bookDao.listPage(pageParam, paramMap, "listBookClassify", "listBookClassifyCount");
        if (pageBean != null) {
            // 设置编辑名称,手机号
            bookSet.setAdviserInfo4BookDto(pageBean.getRecordList());
            // 设置图书读者量、扫码量、浏览量
            bookSet.setBookSvUvPv4Object(pageBean.getRecordList());
            // 设置书刊分类
            bookSet.setTemplateName(pageBean.getRecordList());
            // 设置运营平台名称
            bookSet.setChannelInfoList(pageBean.getRecordList());
            // 设置出版社名称
            bookSet.setAgentId4BookDto(pageBean.getRecordList());
            bookSet.setAgentName4BookDto(pageBean.getRecordList());
            // 设置图书收益
            bookSet.setBookIncome(pageBean.getRecordList());
        } else {
            pageBean = new PageBean();
        }
        return pageBean;
    }

    @ParamLog("导出图书列表（平台端）")
    @Override
    public void exportBookClassify(Map<String, Object> paramMap) {
        Long count = bookDao.listBookClassifyCount(paramMap);
        if (count <= 0) {
            throw new BookBizException(BookBizException.ERROR, "图书列表为空！");
        }
        ThreadPoolUtils.EXPORT_THREAD_POOL.execute(() -> {
            try {
                List<Object> list = new ArrayList<>();
                Integer cu = BookConstant.BOOK_SELECT_COUNT;
                Integer p = (count.intValue() / cu) + 1;
                for (int i = 0; i < p; i++) {
                    PageBean page = listBookClassify(new PageParam(i, cu), paramMap);
                    list.addAll(page.getRecordList());
                }
                List<Object[]> dataList = bookSet.getExcelData4Platform(list);
                String url = bookSet.createExcel(dataList);
                if (!StringUtils.isEmpty(url)) {
                    // 发送站内信
                    bookSet.sendBookExportLetter4Platform(-1L, url, new Date());
                }
            } catch (Exception e) {
                LOGGER.error("导出图书列表（平台端）生成导出文件失败", e);
            }
        });
    }

    /**
     * 导出平台下所有书刊excel表（平台端）
     */
    @Override
    public void exportBookToExcel4Platform() {

        List<Object> platformBook = bookDao.listBy(null, "getAllBook4Platform");
        if (ListUtils.isEmpty(platformBook)) {
            throw new BookBizException(BookBizException.ERROR, "您还没有图书！");
        }

        EXECUTOR_SERVICE.execute(new Runnable() {
            public void run() {
                Date sendDate = new Date();
                try {
                    // 获取出版下所有二维码
                    Map<String, Object> param = new HashMap<String, Object>();
                    // 获取默认书籍
                    BookDto book = getByIsbn("9787507600000", null);
                    if (book != null) {
                        param.put("bookId", book.getBookId());
                    }
                    // 获取图书总数除RAYS现代纸书
                    Integer count = bookDao.getAllBookCount4Platform(param);
                    List<Object[]> dataList = new ArrayList<Object[]>();
                    if (count > BookConstant.BOOK_SELECT_COUNT) {
                        for (int i = 0, titalCount = (count + BookConstant.BOOK_SELECT_COUNT - 1)
                                / BookConstant.BOOK_SELECT_COUNT; i < titalCount; i++) {
                            param.put("currentPage", i * BookConstant.BOOK_SELECT_COUNT);
                            param.put("numPerPage", BookConstant.BOOK_SELECT_COUNT);
                            List<Object> partPlatformBook = bookDao.listBy(param, "getAllBook4Platform");

                            // 设置编辑名称
                            bookSet.setAdviserName4BookDto(partPlatformBook);
                            // 设置图书读者量、扫码量、浏览量
                            bookSet.setBookSvUvPv4Object(partPlatformBook);
                            // 设置书刊分类
                            bookSet.setTemplateName(partPlatformBook);
                            // 设置运营平台名称
                            bookSet.setChannelInfoList(partPlatformBook);
                            // 设置图书收益
                            bookSet.setBookIncome(partPlatformBook);

                            List<Object[]> excelData = bookSet.getExcelData4Platform(partPlatformBook);
                            dataList.addAll(excelData);
                            partPlatformBook.clear();
                            excelData.clear();
                        }
                    } else {
                        List<Object> partPlatformBook = bookDao.listBy(param, "getAllBook4Platform");

                        // 设置编辑名称
                        bookSet.setAdviserName4BookDto(partPlatformBook);
                        // 设置图书读者量、扫码量、浏览量
                        bookSet.setBookSvUvPv4Object(partPlatformBook);
                        // 设置书刊分类
                        bookSet.setTemplateName(partPlatformBook);
                        // 设置运营平台名称
                        bookSet.setChannelInfoList(partPlatformBook);
                        // 设置图书收益
                        bookSet.setBookIncome(partPlatformBook);

                        List<Object[]> excelData = bookSet.getExcelData4Platform(partPlatformBook);
                        dataList.addAll(excelData);
                    }
                    // 生成excel
                    String url = bookSet.createExcel(dataList);
                    if (!StringUtils.isEmpty(url)) {
                        // 发送站内信
                        bookSet.sendBookExportLetter4Platform(-1L, url, sendDate);
                    }
                } catch (Exception e) {
                    LOGGER.error("生成导出文件失败", e);
                }
            }
        });

    }


    /**
     * 获取图书基本信息（编辑 - 运营 - 图书）
     */
    @Override
    public BookDto getBookById(Long adviserId, Long channelId, Long bookId) {
        LOGGER.info(
                "获取图书基本信息（编辑 - 运营 - 图书）<START>adviserId=" + adviserId + "channelId=" + channelId + "bookId=" + bookId);
        BookDto bookDto = this.getBaseById(bookId);
        if (bookDto != null) {
            // 获取图书类型
            Long templetId = bookDao.getTempletId(adviserId, channelId, bookId);
            bookDto.setTempletId(templetId);
            // 设置图书类型名称
            bookSet.setTemplateName(bookDto);
        }
        return bookDto;
    }

    /**
     * 根据ISBN获取书刊信息
     */
    @Override
    public BookDto getByIsbnAndTypeCode(String isbn, String typeCode) throws BizException {
        LOGGER.info("【书刊基础】根据ISBN获取书刊信息,<START>.[isbn]=" + isbn + "typeCode=" + typeCode);
        if (StringUtil.isEmpty(isbn)) {
            throw new AppBizException(AppBizException.PARAM_IS_NULL, "请选择书刊");
        }
        BookDto bookDto = bookDao.getByIsbn(isbn);
    /*	if (BookTypeEnum.BOOK.value.equals(typeCode) && bookDto == null) {
            // 调用外部接口查询书籍信息
			insertBook(isbn);
			bookDto = bookDao.getByIsbn(isbn);
		}*/
        return bookDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BookDto create4Adviser(Book book) {
        LOGGER.info("编辑新增图书book=" + book);
        this.checkAddParam(book);
        if (book.getChannelId() == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择运营平台");
        }
        if (Objects.isNull(book.getTempletId()) || Objects.isNull(book.getSecondTempletId())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊分类");
        }
        // 校验书号
        bookSet.checkISBN(book.getTypeCode(), book.getIsbn());
        BookDto bookDto = bookDao.getByIsbnAndSnum(book.getIsbn(), book.getSerialNumber());
        if (bookDto == null) {
            // 图书不存在，新增图书
            bookDao.insert(book);
            esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(book.getBookId()));
        } else {
            // 图书已存在
            book.setLastModifiedUser(book.getCreatedUser());
            book.setBookId(bookDto.getBookId());
        }
        // 查看现代纸书是否存在
        final BookGroupDTO dtoByBookId = bookGroupBiz.getDTOByBookId(book.getBookId(), book.getChannelId(), book.getCreatedUser());
        // 新增图书与编辑关联关系
        createBookAdviserRelation(book);
        /*BookGroup bookGroup = null;
        if (null != book.getIsBookGroup() && book.getIsBookGroup()) {
            bookGroup = bookGroupBiz.createBookGroupAfterCreateBook(book.getBookId(), book.getChannelId(), book.getCreatedUser());
        }*/
        // 图书不存在，新增图书，图书数量加1
        if (bookDto == null) {
            // 书籍总数缓存加1
            bookCache.incrObject(BookConstant.BOOK_CACHE + "PLATFORM_BOOK_COUNT");
        } else {
            // 主编辑才能修改书刊信息
            Long mainAdviserId = bookAdviserBiz.getMainAdviserId(book.getBookId(), book.getChannelId());
            if (book.getCreatedUser().equals(mainAdviserId)) {
                checkIsUpdateCoverImgAndSendTopic(bookDto, book.getCoverImg());
                checkIsUpdateBookNameAndSendTopic(bookDto, book.getBookName());
                // 修改图书基本信息
                bookDao.updateByAdviser(book);
                esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(book.getBookId()));
                // 周任务书刊埋点
                mainLineConsr.sendAddBookTask(bookDto.getBookId(), book.getCreatedUser());
                // 清除redis中数据
                bookCache.clearRedisByBook(book.getBookId(), book.getIsbn(), book.getSerialNumber());
            }
        }
        bookDto = bookDao.getByIsbnAndSnum(book.getIsbn(), book.getSerialNumber());
        bookDto.setChannelId(book.getChannelId());
        /*if (null != bookGroup) {
            bookDto.setBookGroupId(bookGroup.getId());
            bookDto.setGroupQrcodeUrl(bookGroup.getGroupQrcodeUrl());
        }*/
        // 关联社群码和社群书信息
        if (null != book.getIsBookGroup() && book.getIsBookGroup() && null != book.getBookGroupId()) {
            bookGroupBiz.linkBookGroup(book.getBookId(), book.getBookGroupId(), book.getCreatedUser());
        }
        bookDto.setIsDelete(null == dtoByBookId ? 1 : dtoByBookId.getIsDelete() ? 1 : 0);
        return bookDto;
    }


    /**
     * 修改图书与图书类型
     * @param book
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBookAndBookType(Book book) {
        LOGGER.info("修改图书基本信息与类型book=" + book);
        this.checkParam(book);
        //获取图书基本信息
        BookDto bookDto = this.getBaseById(book.getBookId());
        checkIsUpdateCoverImgAndSendTopic(bookDto, book.getCoverImg());
        checkIsUpdateBookNameAndSendTopic(bookDto, book.getBookName());
        // 修改图书基本信息
        bookDao.updateByAdviser(book);
        esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(book.getBookId()));
        // 清除redis中数据
        bookCache.clearRedisByBook(book.getBookId(), book.getIsbn(), book.getSerialNumber());
        //修改图书类型
        bookAdviserBiz.updateBookTemplet(book);
        //更新小睿分类
        bookGroupBiz.updateBookGroupRaysClassify(book);
        LOGGER.info("修改图书基本信息与类型[END]");
    }

    /**
     * 新增图书与编辑关联关系
     * @param book
     */
    void createBookAdviserRelation(Book book) {
        BookAdviser bookAdviser = new BookAdviser();
        bookAdviser.setBookId(book.getBookId());
        bookAdviser.setAdviserId(book.getCreatedUser());
        bookAdviser.setChannelId(book.getChannelId());
        bookAdviser.setCreatedUser(book.getCreatedUser());
        bookAdviser.setTempletId(book.getTempletId());
        bookAdviser.setSecondTempletId(book.getSecondTempletId());
        bookAdviser.setSubLabelId(book.getSubLabelId());
        bookAdviser.setGraLabelId(book.getGraLabelId());
        bookAdviser.setAreaLabelId(book.getAreaLabelId());
        bookAdviser.setVerLabelId(book.getVerLabelId());
        bookAdviser.setProLabelId(book.getProLabelId());
        bookAdviser.setDepLabelId(book.getDepLabelId());
        bookAdviser.setPurLabelId(book.getPurLabelId());
        bookAdviser.setVolLabelId(book.getVolLabelId());
        if(book.getIsBookGroup()!=null&&book.getIsBookGroup()){
            bookAdviser.setIsOpenRobotProcess(1);
        }else{
            bookAdviser.setIsOpenRobotProcess(0);
        }
        bookAdviserBiz.create(bookAdviser);
    }

    @Override
    public Boolean checkISBN4App(String isbn) {
        bookSet.checkISBNEx(BookTypeEnum.BOOK.value, isbn);
        return true;
    }

    Long getAgentIdByType() {
        Long checkAgentId = agentConsr.getAgentIdByType(AgentTypeEnum.AGENT_TYPE_WYS.getCode());
        return checkAgentId;
    }

    /**
     * 根据渠道ID分页获取图书列表
     */
    @ParamLog(description = "根据渠道ID分页获取图书列表")
    @Override
    public PageBean getBookBaseInfoListByChannelId4Adviser(Long partyId, Long channelId, PageParam pageParam, String name) throws BizException {
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("adviserId", partyId);
        paramMap.put("channelId", channelId);
        paramMap.put("name", name);
        /*paramMap.put("typeCode",BookTypeEnum.BOOK.value);*/
        PageBean pageBean = bookDao.listPage(pageParam, paramMap, "getListPage4Adviser");
        if (null == pageBean || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBean(0, 0, Lists.newArrayList());
        } else {
            // 设置模板名字
            bookSet.setTemplateName(pageBean.getRecordList());
        }
        return pageBean;
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog(description = "根据ID修改时间")
    @Override
    public void updateTimeById(Long bookId) throws BizException {
        if (null == bookId) {
            return;
        }
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("bookId", bookId);
        bookDao.updateTimeById(paramMap);
        esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(bookId));
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog(description = "批量根据ID修改时间")
    @Override
    public void updateTimeByIds(BookAdviserUpdateTimeDTO bookAdviserUpdateTimeDTO) throws BizException {
        if (ListUtils.isEmpty(bookAdviserUpdateTimeDTO.getBookIds()) && null == bookAdviserUpdateTimeDTO.getBookId()) {
            return;
        }
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("adviserId", bookAdviserUpdateTimeDTO.getAdviserId());
        paramMap.put("channelId", bookAdviserUpdateTimeDTO.getChannelId());
        if (null != bookAdviserUpdateTimeDTO.getBookId()) {
            paramMap.put("bookId", bookAdviserUpdateTimeDTO.getBookId());
        } else {
            paramMap.put("bookIds", bookAdviserUpdateTimeDTO.getBookIds());
        }
        bookDao.updateTimeByIds(paramMap);
        if (null != bookAdviserUpdateTimeDTO.getBookId()) {
            esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(bookAdviserUpdateTimeDTO.getBookId()));
        } else {
            esBookAndAdviserBiz.updateBookAndAdviserToES(bookAdviserUpdateTimeDTO.getBookIds());
        }
    }

    @ParamLog(description = "获取书刊信息")
    @Override
    public Map<String, BookInfoAnalysicsDTO> getBookInfoBy(List<BookInfoAnalysicsDTO> bookInfoAnalysicsDTOS, String
            monthDate) throws BizException {
        Map<String, BookInfoAnalysicsDTO> bookInfoAnalysicsDTOMap = null;
        if (!ListUtils.isEmpty(bookInfoAnalysicsDTOS)) {
            List<Long> bookIds = Lists.newArrayList();
            List<Long> adviserIds = Lists.newArrayList();
            List<Long> channelIds = Lists.newArrayList();
            for (BookInfoAnalysicsDTO bookInfoAnalysicsDTO : bookInfoAnalysicsDTOS) {
                bookIds.add(bookInfoAnalysicsDTO.getBookId());
                adviserIds.add(bookInfoAnalysicsDTO.getAdviserId());
                channelIds.add(bookInfoAnalysicsDTO.getChannelId());
            }
            Map<String, Object> paramMap = Maps.newHashMap();
            if (!ListUtils.isEmpty(bookIds)) {
                paramMap.put("bookIds", bookIds);
            }
            if (!ListUtils.isEmpty(adviserIds)) {
                paramMap.put("adviserIds", adviserIds);
            }
            if (!ListUtils.isEmpty(channelIds)) {
                paramMap.put("channelIds", channelIds);
            }
            if (!StringUtil.isEmpty(monthDate)) {
                paramMap.put("statisTime", monthDate);
            }
            List<BookInfoAnalysicsDTO> bookInfoAnalysicsDTOList = bookDao.getBookInfoBy(paramMap);
            if (!ListUtils.isEmpty(bookInfoAnalysicsDTOList)) {
                bookInfoAnalysicsDTOMap = Maps.newHashMap();
                for (BookInfoAnalysicsDTO bookInfoAnalysicsDTO : bookInfoAnalysicsDTOList) {
                    String key = bookInfoAnalysicsDTO.getBookId() + "_" + bookInfoAnalysicsDTO.getChannelId() + "_" + bookInfoAnalysicsDTO.getAdviserId();
                    bookInfoAnalysicsDTOMap.put(key, bookInfoAnalysicsDTO);
                }
            }
        }

        return bookInfoAnalysicsDTOMap;
    }

    @Override
    public Long getBookTempletIdId(Long adviserId, Long channelId, Long bookId) {
        // 获取图书类型
        Long templetId = bookDao.getTempletId(adviserId, channelId, bookId);
        return templetId;
    }

    @ParamLog(description = "获取书刊信息--分析引擎内部接口")
    @Override
    public Map<Long, BookInfo4AnlysicsDTO> getBookAnalysis(List<Long> bookIds, String monthDate) throws BizException {
        if (ListUtils.isEmpty(bookIds)) {
            return null;
        }
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("bookIds", bookIds);
        if (!StringUtil.isEmpty(monthDate)) {
            paramMap.put("monthDate", monthDate);
        }
        Map<Long, BookInfo4AnlysicsDTO> resultMap = null;
        List<BookInfo4AnlysicsDTO> bookList = bookDao.getBookAnalysis(paramMap);
        if (!ListUtils.isEmpty(bookList)) {
            resultMap = bookList.stream().collect(Collectors.toMap(BookInfo4AnlysicsDTO::getBookId, bookInfo4AnlysicsDTO -> bookInfo4AnlysicsDTO));
        }
        return resultMap;
    }

    @Override
    public PageBean getListPage4PC(PageParam pageParam, String name) throws BizException {
        Map<String, Object> paramMap = Maps.newHashMap();
        if (!StringUtil.isEmpty(name)) {
            paramMap.put("name", name);
        }
        return bookDao.listPage(pageParam, paramMap, "getBookBaseInfo");
    }

    @Override
    @ParamLog("未设置版权保护的图书")
    public PageBeanNew listNoAuthBook(ListNoAuthBookParam listNoAuthBookParam, Long adviserId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("adviserId", adviserId);
        paramMap.put("isMainEditor", listNoAuthBookParam.getIsMainEditor());
        paramMap.put("isFundSupport", listNoAuthBookParam.getIsFundSupport());
        paramMap.put("channelId", listNoAuthBookParam.getChannelId());
        paramMap.put("name", listNoAuthBookParam.getName() != null && "".equals(listNoAuthBookParam.getName().trim()) ? null : listNoAuthBookParam.getName());
        paramMap.put("typeCode", listNoAuthBookParam.getTypeCode() != null && "".equals(listNoAuthBookParam.getTypeCode().trim()) ? null : listNoAuthBookParam.getTypeCode());
        paramMap.put("templetId", listNoAuthBookParam.getTempletId());
        paramMap.put("secondTempletIds", Optional.ofNullable(listNoAuthBookParam.getSecondTempletId()).map(Lists::newArrayList).orElse(Lists.newArrayList()));
        PageParam pageParam = new PageParam(listNoAuthBookParam.getCurrentPage(), listNoAuthBookParam.getNumPerPage());
        PageBeanNew pageBean = bookDao.listPageNew(pageParam, paramMap, "listNoAuthBook");
        if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBeanNew(listNoAuthBookParam.getCurrentPage(), listNoAuthBookParam.getNumPerPage(), new ArrayList<>());
        }
        //设置类型名称
        bookSet.setTempletNames(pageBean.getRecordList());
        //设置运营平台名称
        bookSet.setChannelName(pageBean.getRecordList());
        return pageBean;
    }

    @Override
    @ParamLog("未设置版权保护的社群书")
    public PageBeanNew listNoAuthGroupBook(ListNoAuthGroupBookParam listNoAuthGroupBookParam, Long adviserId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("adviserId", adviserId);
        paramMap.put("channelId", listNoAuthGroupBookParam.getChannelId());
        paramMap.put("name", listNoAuthGroupBookParam.getName() != null && "".equals(listNoAuthGroupBookParam.getName().trim()) ? null : listNoAuthGroupBookParam.getName());
        paramMap.put("typeCode", listNoAuthGroupBookParam.getTypeCode() != null && "".equals(listNoAuthGroupBookParam.getTypeCode().trim()) ? null : listNoAuthGroupBookParam.getTypeCode());
        paramMap.put("templetId", listNoAuthGroupBookParam.getTempletId());
        paramMap.put("secondTempletIds", Optional.ofNullable(listNoAuthGroupBookParam.getSecondTempletId()).map(Lists::newArrayList).orElse(Lists.newArrayList()));
        PageParam pageParam = new PageParam(listNoAuthGroupBookParam.getCurrentPage(), listNoAuthGroupBookParam.getNumPerPage());
        PageBeanNew pageBean = bookDao.listPageNew(pageParam, paramMap, "listNoAuthGroupBook");
        if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBeanNew(listNoAuthGroupBookParam.getCurrentPage(), listNoAuthGroupBookParam.getNumPerPage(), new ArrayList<>());
        }
        //设置类型名称
        bookSet.setTempletNames(pageBean.getRecordList());
        //设置运营平台名称
        bookSet.setChannelName(pageBean.getRecordList());
        return pageBean;
    }

    @Override
    @ParamLog("获取图书基本信息与授权状态")
    public BookInfoAndAuthStatusDTO getBaseAndAuthStatus(Long bookId, Long channelId, Long adviserId) {
        BookDto book = getBaseById(bookId);
        if (book == null)
            return null;
        //获取编辑是否删除这本书
        BookAdviserDto bookAdviser = bookAdviserBiz.getBase(bookId, channelId, adviserId);
        BookInfoAndAuthStatusDTO bookInfoAndAuthStatusDTO = new BookInfoAndAuthStatusDTO();
        BeanUtils.copyProperties(book, bookInfoAndAuthStatusDTO);
        //获取授权状态
        BookAuthInfoVO infoByBook = bookAuthInfoBiz.getInfoByBook(bookId, channelId, adviserId, null);
        if (infoByBook != null) {
            BeanUtils.copyProperties(infoByBook, bookInfoAndAuthStatusDTO);
        }
        bookInfoAndAuthStatusDTO.setIsDelete(bookAdviser == null ? BookStatusEnum.BookDeleteStatus.DELETE.value : bookAdviser.getIsDelete());
        return bookInfoAndAuthStatusDTO;
    }

    @ParamLog("根据书名或ISBN编号获取书id集合")
    @Override
    public List<Long> getIdsByNameOrISBN(String keyword, Long adviserId) {
        LOGGER.info("【书籍顾问】根据书名或ISBN编号获取书id集合,<START>.[keyword|adviserId]=" + keyword + "|" + adviserId);
        if (StringUtil.isEmpty(keyword)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请输入关键词");
        }
        if (adviserId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请输入编辑ID");
        }
        List<Long> bookIds ;
        try {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("keyword", keyword);
            paramMap.put("adviserId", adviserId);
            bookIds = bookDao.getIdsByNameOrISBN(paramMap);
            if (bookIds == null) {
                bookIds = Lists.newArrayList();
            }
        } catch (Exception e) {
            LOGGER.error("【书籍-顾问】根据书名或ISBN编号获取书id集合,<ERROR>.[getIdsByNameOrISBN]:" + e.getMessage(), e);
            throw BizException.DB_SELECT_IS_FAIL;
        }
        return bookIds;
    }

    @Override
    public PageBeanNew<AdviserBookInfoDTO> getListPage4SelfBookGroup(Integer currentPage, Integer numPerPage, String name,Long adviserId, Long graLabelId, Long subLabelId, Long verLabelId, Long areaLabelId) {
        Map<String, Object> paramMap = new HashMap<>();
        if (!StringUtil.isEmpty(name)) {
            paramMap.put("name", name);
        }
        if (adviserId != null) {
            paramMap.put("adviserId", adviserId);
        }
        paramMap.put("joinGroupTypes", Arrays.asList(JoinGroupTypeEnum.ROBOT.getCode(),JoinGroupTypeEnum.AI_ROBOT.getCode(),
                JoinGroupTypeEnum.XIAORUI.getCode()));
        paramMap.put("graLabelId",graLabelId);
        paramMap.put("subLabelId",subLabelId);
        paramMap.put("verLabelId",verLabelId);
        paramMap.put("areaLabelId",areaLabelId);
        PageBeanNew<AdviserBookInfoDTO> pageBean = bookDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "getListPage4BookGroup");
        if (null == pageBean || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        }
        List<AdviserBookInfoDTO> list = pageBean.getRecordList();
        List<Long> adviserIds = list.stream().filter(s -> s.getAdviserId() != null).map(AdviserBookInfoDTO::getAdviserId).distinct().collect(Collectors.toList());
        Map<Long, AdviserBaseInfoDto> adviserMap = adviserConsr.getAdviserId2AdviserInfoDtoMap(adviserIds);
        for (AdviserBookInfoDTO dto : list) {
            if (!MapUtils.isEmpty(adviserMap) && null != dto.getAdviserId() && adviserMap.containsKey(dto.getAdviserId())) {
                AdviserBaseInfoDto adviserBaseInfoDto = adviserMap.get(dto.getAdviserId());
                if (null != adviserBaseInfoDto){
                    dto.setAdviserName(adviserBaseInfoDto.getPartyName());
                    dto.setAgentName(adviserBaseInfoDto.getAgentName());
                }
            }
        }
        return pageBean;
    }

    @ParamLog("获取书籍标签")
    @Override
    public Map<Integer, List<BookLabel>> getBookLabels(Long partyId) {
        Map<Integer, List<BookLabel>> map = new HashMap<>();
        List<BookLabel> bookLabels = bookLabelDao.getAll(partyId);
        if (!ListUtils.isEmpty(bookLabels)) {
            map = bookLabels.stream().collect(Collectors.groupingBy(BookLabel::getType));
        }
        return map;
    }

    @ParamLog("书刊收益列表--出版端")
    @Override
    public PageBeanNew<BookSaleVO> listPageIncomeDetail(PageParam pageParam, Map<String, Object> paramMap, Long agentId) {
        List<Long> adviserIds = adviserConsr.getIdsByNameAndAgentId(agentId, (String) paramMap.get("keyWord"));
        List<Long> agent4AdviserIds = adviserConsr.getIdsByNameAndAgentId(agentId, null);
        paramMap.put("adviserIds", adviserIds);
        paramMap.put("agent4AdviserIds", agent4AdviserIds);
        if (ListUtils.isEmpty(agent4AdviserIds)) {
            return new PageBeanNew<>(0, 0, new ArrayList<>());
        }
        PageBeanNew<BookSaleVO> pageNew = bookDao.listPageNew(pageParam, paramMap, "listIncomePage4Agent");
        //填充收益
        bookSet.setAgentSalesInfo(pageNew.getRecordList(),agentId);
        return pageNew;
    }

    @ParamLog("导出书刊收益导出--出版端")
    @Override
    public void exportBookIncomeDetail(Map<String, Object> paramMap, Long agentId, Long partyId, String systemCode) {
        //导出数据
        if (paramMap == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "参数错误！");
        }
        List<Long> adviserIds = adviserConsr.getIdsByNameAndAgentId(agentId, (String) paramMap.get("keyWord"));
        List<Long> agent4AdviserIds = adviserConsr.getIdsByNameAndAgentId(agentId, null);
        paramMap.put("adviserIds", adviserIds);
        paramMap.put("agent4AdviserIds", agent4AdviserIds);
        Long count = bookDao.countIncomePage4Agent(paramMap);
        if(count>1500){
            throw new ExportException(ExportException.OPERATE_ERROR, "数量超过限制，请添加条件再导出！");
        }
        ThreadPoolUtils.EXPORT_THREAD_POOL.execute(() -> {
            try{
                List<BookSaleVO> list = new ArrayList<>();
                Integer cu = 100;
                Integer p = (count.intValue() / cu) + 1;
                for (int i = 0; i < p; i++) {
                    PageBeanNew<BookSaleVO> pageBeanNew=listPageIncomeDetail(new PageParam(i,cu), paramMap, agentId);
                    List<BookSaleVO> bookSaleVOS=pageBeanNew.getRecordList();
                    list.addAll(bookSaleVOS);
                }
                List<Object[]> dataList = new ArrayList<>();
                for (int i = 0, size = list.size(); i < size; i++) {
                    BookSaleVO bookSaleVO = list.get(i);
                    Object[] obj = new Object[9];
                    obj[0] = i + 1;
                    obj[1] = bookSaleVO.getBookName();
                    obj[2] = bookSaleVO.getIsbn();
                    if (bookSaleVO.getIsFundSupport()==true){
                        obj[3] = "是";
                    }else{
                        obj[3] = "否";
                    }
                    obj[4] = bookSaleVO.getAdviserName();
                    obj[5] = bookSaleVO.getChannelName();
                    if (bookSaleVO.getAgentBookIncomeDTO()!=null){
                        obj[6] = bookSaleVO.getAgentBookIncomeDTO().getBookIncome();
                        obj[7] = bookSaleVO.getAgentBookIncomeDTO().getAdviserIncome();
                        obj[8] = bookSaleVO.getAgentBookIncomeDTO().getAgentIncome();
                    }
                    dataList.add(obj);
                }
                Date date = new Date();
                String[] rowsName = {"序号", "书刊名称", "书刊号", "是否基金书", "主编辑", "运营平台", "销售总额", "编辑收益", "出版社收益"};
                String fileName = "书刊收益统计--" + DateUtils.getStrFormTime("yyyyMMdd", date);
                String fileUrl = exportConsr.exportExcel(fileName, rowsName, dataList);
                String letterType = "book_download";
                String content = String.format("{\"commitTime\":\"%s\",\"type\":\"%s\"}", DateUtils.formatDate(date), fileName);
                messageConsr.sendLetter(partyId, partyId, content, systemCode, letterType, fileUrl, fileName);
            }catch (Exception e) {
                LOGGER.error("exportBookIncomeDetail+++paramMap=" + paramMap.toString() + "systemCode=" + systemCode + "partyId=" + partyId);
            }
        });
    }

    @ParamLog("根据书名模糊匹配，获得所有book_id")
    @Override
    public List<Long> getBookIdsByBookName(String bookName) {
        LOGGER.info("根据书名模糊匹配，获得所有book_id,<START>.[bookName]=" + bookName);
        if (StringUtil.isEmpty(bookName)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请输入书名");
        }
        List<Long> bookIds;
        try {
            bookIds = bookDao.getBookIdsByBookName(bookName);
            if (bookIds == null) {
                bookIds = Lists.newArrayList();
            }
        } catch (Exception e) {
            LOGGER.error("根据书名模糊匹配，获得所有book_id,<ERROR>.[getBookIdsByBookName]:" + e.getMessage(), e);
            throw BizException.DB_SELECT_IS_FAIL;
        }
        return bookIds;
    }

    @ParamLog("平台端获取编辑书刊")
    @Override
    public PageBeanNew<BookDto> getAdviserBooks4Pcloud(String keyword, Long agentId, Long templetId, Long secondTempletId, String typeCode, Integer currentPage, Integer numPerPage) {
        String redisKey=BookConstant.ADVISER_BOOK_CACHE + "_" + keyword + "_" + agentId + "_" + templetId
                + "_" + secondTempletId + "_" + typeCode + "_" + currentPage + "_" + numPerPage;
        String data = JedisClusterUtils.get(redisKey);
        //加缓存
        if(StringUtil.isNotBlank(data)){
            PageBeanNew pageBeanNew = JSONObject.parseObject(data, PageBeanNew.class);
            if(null!=pageBeanNew) {
                return pageBeanNew;
            }
        }
        Map<String,Object> map=new HashMap<>();
        map.put("keyword",keyword);
        map.put("templetId",templetId);
        map.put("secondTempletId",secondTempletId);
        map.put("typeCode",typeCode);
        if (agentId != null){
            List<Long> adviserIds = adviserConsr.getIdsByNameAndAgentId(agentId, null);
            if (ListUtils.isEmpty(adviserIds)){
                map.put("adviserIds",Arrays.asList(-1L));
            }else {
                map.put("adviserIds",adviserIds);
            }
        }
        if(!StringUtil.isEmpty(keyword)) {
            // 模糊匹配编辑名称
            List<Long> adviserIds = adviserConsr.getAdviserIdsByName(keyword);
            map.put("adviserIds4Name", adviserIds);
        }
        PageBeanNew<BookDto> page = bookDao.listPageNew(new PageParam(currentPage, numPerPage), map, "getAdviserBooks4Pcloud", "getAdviserBooksCount4Pcloud");
        fillBookInfo(page.getRecordList());
        if(!ListUtils.isEmpty(page.getRecordList())) {
            JedisClusterUtils.set(redisKey, JSONObject.toJSONString(page), 3600);
        }
        return page;
    }

    @ParamLog("获取编辑书刊H5")
    @Override
    public PageBeanNew<BookDto> getAdviserBooks4H5(String grayStatus, String keyword, Long templetId, Long secondTempletId,
                                                   Integer currentPage, Integer numPerPage) {
        Page<ESBookAndAdviser> esPage = esBookAndAdviserBiz.getAdviserBooks4ES(StringUtils.isEmpty(grayStatus) ? "0" : grayStatus,keyword
                , templetId, secondTempletId, currentPage, numPerPage);
        List<ESBookAndAdviser> esBookAndAdvisers=esPage.getContent();
        if (ListUtils.isEmpty(esBookAndAdvisers)){
            return new PageBeanNew<>();
        }
        List<BookDto> bookDtos=changeToBookDto(esBookAndAdvisers);
        fillOtherBookInfo(bookDtos);
        fillBookInfo(bookDtos);
        PageBeanNew<BookDto> page=new PageBeanNew<>(currentPage,numPerPage,(int)esPage.getTotalElements(),bookDtos);
        return page;
    }

    @ParamLog("转化为bookDto")
    private List<BookDto> changeToBookDto(List<ESBookAndAdviser> esBookAndAdvisers) {
        List<BookDto> bookDtos=new ArrayList<>();
        for (ESBookAndAdviser esBookAndAdviser:esBookAndAdvisers){
            BookDto bookDto=new BookDto();
            BeanUtils.copyProperties(esBookAndAdviser, bookDto);
            bookDto.setBookId(esBookAndAdviser.getBookId()==null?null:new Long(esBookAndAdviser.getBookId()));
            bookDto.setBookAdviserId(esBookAndAdviser.getBookAdviserId()==null?null:new Long(esBookAndAdviser.getBookAdviserId()));
            bookDto.setAdviserId(esBookAndAdviser.getAdviserId()==null?null:new Long(esBookAndAdviser.getAdviserId()));
            bookDto.setChannelId(esBookAndAdviser.getChannelId()==null?null:new Long(esBookAndAdviser.getChannelId()));
            bookDto.setTempletId(esBookAndAdviser.getTempletId()==null?null:new Long(esBookAndAdviser.getTempletId()));
            bookDto.setSecondTempletId(esBookAndAdviser.getSecondTempletId()==null?null:new Long(esBookAndAdviser.getSecondTempletId()));
            bookDto.setIsMainEditor(esBookAndAdviser.getIsMainEditor());
            bookDto.setTypeCode(esBookAndAdviser.getTypeCode());
            bookDto.setIsbn(esBookAndAdviser.getIsbn());
            bookDto.setBookName(esBookAndAdviser.getBookName());
            bookDto.setLastModifiedDate(esBookAndAdviser.getLastModifiedDate());
            bookDto.setGraLabelId(esBookAndAdviser.getGraLabelId());
            bookDto.setSubLabelId(esBookAndAdviser.getSubLabelId());
            bookDto.setAreaLabelId(esBookAndAdviser.getAreaLabelId());
            bookDto.setVerLabelId(esBookAndAdviser.getVerLabelId());
            bookDtos.add(bookDto);
        }
        return bookDtos;
    }

    private void fillOtherBookInfo(List<BookDto> bookDtos) {
        if (ListUtils.isEmpty(bookDtos)){
            return;
        }
        List<Long> bookIds=bookDtos.stream().filter(s->s.getBookId()!=null).map(BookDto::getBookId).distinct().collect(Collectors.toList());
        Map<Long, BookDto> bookDtoMap = bookDao.getMapByBookIds(bookIds);
        for (BookDto dto:bookDtos){
            BookDto bookDto=bookDtoMap.get(dto.getBookId());
            if (bookDto==null){
                continue;
            }
            dto.setRemark(bookDto.getRemark());
            dto.setAuthor(bookDto.getAuthor());
            dto.setPublish(bookDto.getPublish());
            dto.setPublishDate(bookDto.getPublishDate());
            dto.setCoverImg(bookDto.getCoverImg());
            dto.setOriginName(bookDto.getOriginName());
            dto.setBookPrice(bookDto.getBookPrice());
            dto.setIssn(bookDto.getIssn());
            dto.setSerialNumber(bookDto.getSerialNumber());
            dto.setTypeName(bookDto.getTypeName());
            dto.setUniqueNumber("BK"+dto.getBookId());
        }

    }

    @Override
    public PageBeanNew<BookDto> getBookAndServeList4Channel(Integer currentPage, Integer numPerPage, Long channelId,String name,
            Integer isFundSupport, String startDate, String endDate) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("channelId", channelId);
        paramMap.put("name", name);
        paramMap.put("startDate", startDate);
        paramMap.put("endDate", endDate);
        paramMap.put("isFundSupport", isFundSupport);
        PageBeanNew<BookDto> pageBeanNew = bookDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "getBookAndServeList4Channel");
        if (null==pageBeanNew || ListUtils.isEmpty(pageBeanNew.getRecordList())){
            return new PageBeanNew<>(currentPage,numPerPage,0,new ArrayList<>());
        }
        List<BookDto> bookDtos = pageBeanNew.getRecordList();
        List<Long> adviserIds = bookDtos.stream().filter(s->s.getAdviserId()!=null).map(BookDto::getAdviserId).distinct().collect(Collectors.toList());
        Map<Long, String> nameMap = adviserConsr.getNames(adviserIds);
        for (BookDto bookDto : bookDtos){
            if (!MapUtils.isEmpty(nameMap) && nameMap.containsKey(bookDto.getAdviserId())){
                bookDto.setAdviserName(nameMap.get(bookDto.getAdviserId()));
            }
            BookServeParamVO bookServeParamVO = new BookServeParamVO();
            bookServeParamVO.setChannelId(channelId);
            bookServeParamVO.setAdviserId(bookDto.getAdviserId());
            bookServeParamVO.setBookId(bookDto.getBookId());
            List<BookServeVO> bookServeVOS = qrcodeSceneConsr.listBookServe(bookServeParamVO);
            List<Object> objects = new ArrayList<>();
            objects.addAll(bookServeVOS);
            bookDto.setResourceFiles(objects);
            bookDto.setResourceCount(bookServeVOS.size());
        }
        return pageBeanNew;
    }

    @ParamLog("获取书刊")
    @Override
    public BookDto getAdviserBook(Long bookId, Long adviserId, Long channelId) {
        if (bookId==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数有误");
        }
        if (adviserId==null||channelId==null||adviserId<=0||channelId<=0){
            return bookDao.getBaseById(bookId);
        }
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("bookId", bookId);
        paramMap.put("adviserId", adviserId);
        paramMap.put("channelId", channelId);
        BookDto bookDto = bookDao.getById(paramMap);
        if (bookDto == null) {
            return new BookDto();
        }
        Integer joinGroupType = bookGroupDao.getJoinGroupType(paramMap);
        if(null!=joinGroupType && JoinGroupTypeEnum.XIAORUI.getCode().equals(joinGroupType)){
            Long classifyId = bookRaysClassifyDao.getClassifyIdByBookTemplateId(bookDto.getTempletId());
            bookDto.setClassifyId(null!=classifyId ? classifyId.intValue():null);
        }
        //	设置模板名字
        List<Long> templetIds = new ArrayList<>();
        if(bookDto.getTempletId()!=null) {
            templetIds.add(bookDto.getTempletId());
        }
        if(bookDto.getSecondTempletId()!=null) {
            templetIds.add(bookDto.getSecondTempletId());
        }
        Map<Long, AssistTempletDTO> assistTempletDTOMap = assistTempletConsr.mapByIds(templetIds);
        Long secondTempletId = bookDto.getSecondTempletId();
        Long templetId = bookDto.getTempletId();
        if (secondTempletId!=null&&assistTempletDTOMap!=null) {
            AssistTempletDTO templetDTO = assistTempletDTOMap.get(secondTempletId);
            bookDto.setSecondTempletName(Optional.ofNullable(templetDTO).map(AssistTempletDTO::getTempletName).orElse(null));
        }
        if (templetId!=null&&assistTempletDTOMap!=null) {
            AssistTempletDTO templetDTO = assistTempletDTOMap.get(templetId);
            bookDto.setTempletName(Optional.ofNullable(templetDTO).map(AssistTempletDTO::getTempletName).orElse(null));
        }
        return bookDto;
    }

    @ParamLog("填充书刊信息")
    private void fillBookInfo(List<BookDto> list) {
        if (ListUtils.isEmpty(list)){
            return;
        }
        //填充出版社信息
        List<Long> adviserIds=list.stream().filter(s->s.getAdviserId()!=null).map(BookDto::getAdviserId).distinct().collect(Collectors.toList());
        Map<Long, AdviserBaseInfoDto> infoDtoMap = adviserConsr.getAdviserId2AdviserInfoDtoMap(adviserIds);
        List<Long> templetIds = new ArrayList<>();
        list.forEach(BookDto -> {
            if (Objects.nonNull(BookDto.getTempletId())) {
                templetIds.add(BookDto.getTempletId());
            }
            if (Objects.nonNull(BookDto.getSecondTempletId())) {
                templetIds.add(BookDto.getSecondTempletId());
            }
        });
        Map<Long, AssistTempletDTO> assistTempletDTOMap = assistTempletConsr.mapByIds(templetIds);
        list.forEach(bookDto -> {
            Long secondTempletId = bookDto.getSecondTempletId();
            Long templetId = bookDto.getTempletId();
            if (secondTempletId!=null&&assistTempletDTOMap!=null) {
                AssistTempletDTO templetDTO = assistTempletDTOMap.get(secondTempletId);
                bookDto.setSecondTempletName(Optional.ofNullable(templetDTO).map(AssistTempletDTO::getTempletName).orElse(null));
            }
            if (templetId!=null&&assistTempletDTOMap!=null) {
                AssistTempletDTO templetDTO = assistTempletDTOMap.get(templetId);
                bookDto.setTempletName(Optional.ofNullable(templetDTO).map(AssistTempletDTO::getTempletName).orElse(null));
            }
            Long adviserId=bookDto.getAdviserId();
            if (infoDtoMap!=null){
                AdviserBaseInfoDto infoDto = infoDtoMap.get(adviserId);
                if (infoDto!=null){
                    bookDto.setAgentId(infoDto.getAgentId());
                    bookDto.setAgentName(infoDto.getAgentName());
                    bookDto.setAdviserName(infoDto.getPartyName());
                }
            }
        });

    }

    @Override
    public List<Long> getBookIdsByIsbn(String isbn) {
        return bookDao.getBookIdsByIsbn(isbn);
    }

    @Override
    public void updateBookQualifyInfo(BookQualifyInfoVO bookQualifyInfo, Long adviserId) {
        Map<String,Object> map=new HashMap<>();
        map.put("bookIds",bookQualifyInfo.getBookIds());
        map.put("adviserId",adviserId);
        map.put("isShowQualifyInfo",bookQualifyInfo.getIsShowQualifyInfo());
        bookDao.updateBookQualifyInfo(map);
    }

    @Override
    public PageBeanNew<BookQualifyVO> getAddBookQualifyList(Integer currentPage, Integer numPerPage, String name, Integer isShowQualifyInfo,Long adviserId) {
        Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("isShowQualifyInfo", isShowQualifyInfo);
            paramMap.put("name", name);
            paramMap.put("adviserId", adviserId);
            PageBeanNew<BookQualifyVO> pageBeanNew = bookDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "getAddBookQualifyList");
            if (null==pageBeanNew || ListUtils.isEmpty(pageBeanNew.getRecordList())){
                return new PageBeanNew<>(currentPage,numPerPage,0,new ArrayList<>());
            }
        return pageBeanNew;
    }

    @Override
    public SearchBookVO getBookInfoByBookGroupId(Long bookGroupId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("bookGroupId", bookGroupId);
        SearchBookVO bookVO=bookDao.getBookInfoByBookGroupId(paramMap);
        if(bookVO!=null) {
            //通过agentId查找出版社名称
            List<Long> agentIds = new ArrayList<>();
            agentIds.add(bookVO.getAgentId());
            Map<Long, String> names = agentConsr.getNames(agentIds);
            String name = names.get(bookVO.getAgentId());
            bookVO.setAgentName(name);
            //通过编辑id查找编辑名称
            List<Long> adviserIds = new ArrayList<>();
            adviserIds.add(bookVO.getAdviserId());
            Map<Long, String> map = adviserConsr.getNames(adviserIds);
            String adviserName = map.get(bookVO.getAdviserId());
            bookVO.setAdviserName(adviserName);
        }
        return bookVO;
    }

    @Override
    public void updateIsOpenRobotProcess(Long adviserId, UpdateBookRobotProcessDto robotProcessDto) {
        Map<String,Object> map=new HashMap<>();
        map.put("bookId",robotProcessDto.getBookId());
        map.put("adviserId",adviserId);
        map.put("isOpenRobotProcess",robotProcessDto.getIsOpenRobotProcess());
        bookDao.updateIsOpenRobotProcess(map);
    }

    @Override
    public void updateIsOpenRobotProcess4Now(Long adviserId, UpdateBookRobotProcessDto robotProcessDto) {
        Map<String,Object> map=new HashMap<>();
        map.put("bookId",robotProcessDto.getBookId());
        map.put("adviserId",adviserId);
        map.put("isOpenRobotProcess",robotProcessDto.getIsOpenRobotProcess());
        bookDao.updateIsOpenRobotProcess(map);
        //根据channelId和bookId获取书下面所有自建码，在根据自建码的senceId创建小程序二维码
        List<Long> sceneIds=qrcodeSceneConsr.getAliQrByBookId(robotProcessDto.getBookId());
        if(!ListUtils.isEmpty(sceneIds)) {
            createBookGroupAppletUrl(robotProcessDto.getBookId(), robotProcessDto.getChannelId(), adviserId, sceneIds);
        }

    }

    @Override
    public PageBeanNew<BookDto> getAdviserBooks4Rights(String keyword, Long agentId, Long templetId, Long secondTempletId, String typeCode,
            Integer currentPage, Integer numPerPage) {
        Map<String,Object> map=new HashMap<>();
        map.put("keyword",keyword);
        map.put("templetId",templetId);
        map.put("secondTempletId",secondTempletId);
        map.put("typeCode",typeCode);
        if (agentId != null){
            List<Long> adviserIds = adviserConsr.getIdsByNameAndAgentId(agentId, null);
            if (ListUtils.isEmpty(adviserIds)){
                map.put("adviserIds", Collections.singletonList(-1L));
            }else {
                map.put("adviserIds",adviserIds);
            }
        }
        if(!StringUtil.isEmpty(keyword)) {
            // 模糊匹配编辑名称
            List<Long> adviserIds = adviserConsr.getAdviserIdsByName(keyword);
            map.put("adviserIds4Name", adviserIds);
        }
        //获取已被权益选择的书刊
        List<Long> bookIds = rightsSettingBookRelationMapper.getAllBookIds();
        if (!ListUtils.isEmpty(bookIds)){
            map.put("ignoreBookIds", bookIds);
        }
        PageBeanNew<BookDto> page = bookDao.listPageNew(new PageParam(currentPage, numPerPage), map, "getAdviserBooks4Rights");
        fillBookInfo(page.getRecordList());
        return page;
    }

    public void createBookGroupAppletUrl(Long bookId, Long channelId, Long adviserId,List<Long> sceneIds){
        BookAdviserDto bookAdviserDto = bookAdviserDao.getBase(bookId,channelId,adviserId);
        Long raysClassifyId = bookRaysClassifyDao.getClassifyIdByBookTemplateId(bookAdviserDto.getTempletId());
        String page=null;//小程序跳转页 todo
        List<BookAppletScene> list=new ArrayList<>();
        for (Long sceneId:sceneIds){
            //通过sceneId查询是否已经存在，如果已经存在就不创建
            BookAppletScene appletScene = bookAppletSceneDao.getBySceneId(sceneId);
            if(appletScene!=null){
                continue;
            }
            String appletId = createOneAppletId();
            BookAppletScene applet = bookAppletSceneDao.getByAppletId(appletId);
            while (null != applet) {
                appletId = createOneAppletId();
                applet = bookAppletSceneDao.getByAppletId(appletId);
            }
            String url = wechatConsr.create4MiniApp(777L, appletId, null, page);
            BookAppletScene bookAppletScene = new BookAppletScene();
            bookAppletScene.setRaysClassifyId(raysClassifyId);
            bookAppletScene.setAppletId(appletId);
            bookAppletScene.setAppletUrl(url);
            bookAppletScene.setSceneId(sceneId);
            list.add(bookAppletScene);
        }
        bookAppletSceneDao.insert(list);

    }

    @ParamLog("生成一个小程序id")
    private String createOneAppletId() {
        Random random = new Random();
        String charStr = "0123456789abcdefghijklmnopqrstuvwxyz";
        String s = "";
        for (int i = 0; i < 20; i++) {
            int index = random.nextInt(charStr.length());
            s = s + charStr.charAt(index);
        }
        return s;
    }

    @Override
    public PageBeanNew<BookDto> getAdviserBooks4Applet(BookSearchParamVO bookSearchParamVO) {
        List<Long> templetIds = new ArrayList<>();
        if (null != bookSearchParamVO.getBookClassifyId()) {
            templetIds = appletBookClassifyBiz.getRelationBookTempletByBookClassify(bookSearchParamVO.getBookClassifyId());
        }
        List<Long> graLabelIds = new ArrayList<>();
        List<Long> subLabelIds = new ArrayList<>();
        List<Long> scecondTempletIds = new ArrayList<>();
        if (!ListUtils.isEmpty(bookSearchParamVO.getAppletUserLabelIdList())) {
            Long appletUserLabelId = bookSearchParamVO.getAppletUserLabelIdList().get(0);//先支持一个标签
            List<AppletUserLabelRelation> relations = appletBookClassifyBiz.getByAppletUserLabelId(appletUserLabelId);
            if (!ListUtils.isEmpty(relations)) {
                for (AppletUserLabelRelation relation : relations) {
                    if (relation.getLabelType().equals(LabelTypeEnum.grade_label.code)) {
                        graLabelIds.add(relation.getBookLabelId());
                    } else if (relation.getLabelType().equals(LabelTypeEnum.subject_label.code)) {
                        subLabelIds.add(relation.getBookLabelId());
                    } else if (relation.getLabelType().equals(LabelTypeEnum.sceond_templet.code)){
                        scecondTempletIds.add(relation.getBookLabelId());
                    }
                }
            }
        }
        String grayStatus = StringUtils.isEmpty(bookSearchParamVO.getGrayStatus()) ? "0" : bookSearchParamVO.getGrayStatus();
        String keyword = bookSearchParamVO.getKeyword();
        Integer currentPage = bookSearchParamVO.getCurrentPage();
        Integer numPerPage = bookSearchParamVO.getNumPerPage();
        Page<ESBookAndAdviser> esPage = esBookAndAdviserBiz.getESAdviserBooks4Applet(grayStatus, keyword, templetIds, graLabelIds, subLabelIds, currentPage, numPerPage,scecondTempletIds);
        List<ESBookAndAdviser> esBookAndAdvisers = esPage.getContent();
        if (ListUtils.isEmpty(esBookAndAdvisers)) {
            return new PageBeanNew<>(currentPage,numPerPage,0,new ArrayList<>());
        }
        List<BookDto> bookDtos = changeToBookDto(esBookAndAdvisers);
        fillOtherBookInfo(bookDtos);
        fillBookInfo(bookDtos);
        PageBeanNew<BookDto> page = new PageBeanNew<>(currentPage, numPerPage, (int) esPage.getTotalElements(), bookDtos);
        return page;
    }

    @ParamLog("获取书籍标签")
    @Override
    public Map<Integer, List<BookLabel>> getBookLabels4Erp() {
        Map<Integer, List<BookLabel>> map = new HashMap<>();
        List<BookLabel> bookLabels = bookLabelDao.getAll(0L);
        if (!ListUtils.isEmpty(bookLabels)) {
            map = bookLabels.stream().collect(Collectors.groupingBy(BookLabel::getType));
        }
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void relateUniqueNumber4Erp(List<BookUniqueNumberDTO> bookUniqueNumberVos) {
        if(ListUtils.isEmpty(bookUniqueNumberVos)){
            return;
        }
        bookDao.relateUniqueNumber4Erp(bookUniqueNumberVos);
    }
}
