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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeException;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.pcloud.advertising.advertising.dto.AdvertisingSpaceDTO;
import com.pcloud.advertising.advertising.dto.AdvertisingSpaceItemDTO;
import com.pcloud.analysisengine.browse.dto.BrowseRecordStatisticDTO;
import com.pcloud.appcenter.app.dto.AppDto;
import com.pcloud.book.applet.biz.AppletBooklistBiz;
import com.pcloud.book.applet.biz.AppletGroupSearchRecordBiz;
import com.pcloud.book.applet.biz.AppletRecordAggrStatisBiz;
import com.pcloud.book.applet.biz.AppletThirdResourcesBiz;
import com.pcloud.book.applet.dto.AppletGroupStatementDTO;
import com.pcloud.book.applet.dto.AppletOuterBooklistDTO;
import com.pcloud.book.applet.dto.GroupActivity4AppletDTO;
import com.pcloud.book.applet.entity.AppletThirdResources;
import com.pcloud.book.base.constants.MqConstants;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.biz.BookAdviserBiz;
import com.pcloud.book.book.biz.BookBiz;
import com.pcloud.book.book.constant.BookConstant;
import com.pcloud.book.book.dto.BookAdviserDto;
import com.pcloud.book.book.dto.BookDto;
import com.pcloud.book.book.dto.OpenRecommendVO;
import com.pcloud.book.book.dto.RaysSceneCatalogDto;
import com.pcloud.book.book.entity.Book;
import com.pcloud.book.book.enums.WxworkQrcodeType;
import com.pcloud.book.book.vo.BookLinkVO;
import com.pcloud.book.book.vo.response.BookQrcodeWxworkResponseVO;
import com.pcloud.book.consumer.advsertising.AdvertisingConsr;
import com.pcloud.book.consumer.analysisengine.BrowseRecordConsr;
import com.pcloud.book.consumer.app.AppConsr;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.combinedmarketing.MemberActivityConsr;
import com.pcloud.book.consumer.content.ResourceConsr;
import com.pcloud.book.consumer.erp.ErpConsr;
import com.pcloud.book.consumer.function.FunctionConsr;
import com.pcloud.book.consumer.promotion.PromotionConsr;
import com.pcloud.book.consumer.raystask.AdviserTaskConsr;
import com.pcloud.book.consumer.reader.ReaderConsr;
import com.pcloud.book.consumer.resource.ProductConsr;
import com.pcloud.book.consumer.shareimage.ShareImageConsr;
import com.pcloud.book.consumer.trade.TradeConsr;
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.MerchantConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.consumer.wxwork.WxworkConsr;
import com.pcloud.book.copyright.biz.BookAuthServeBiz;
import com.pcloud.book.es.biz.ESBookAndAdviserBiz;
import com.pcloud.book.group.biz.BookGroupBiz;
import com.pcloud.book.group.biz.MultiChannelContentBiz;
import com.pcloud.book.group.biz.ResourcePageBiz;
import com.pcloud.book.group.biz.ResourcePageBookstoreBiz;
import com.pcloud.book.group.biz.ResourcePageOuterLinkBiz;
import com.pcloud.book.group.constant.ResourcePageConstants;
import com.pcloud.book.group.constant.ResourcePageConstants.ServeTypeEnum;
import com.pcloud.book.group.dao.BookAppletSceneDao;
import com.pcloud.book.group.dao.BookGroupDao;
import com.pcloud.book.group.dao.ResourcePageCollectDao;
import com.pcloud.book.group.dao.ResourcePageColumnDao;
import com.pcloud.book.group.dao.ResourcePageCourseDao;
import com.pcloud.book.group.dao.ResourcePageDao;
import com.pcloud.book.group.dao.ResourcePageItemDao;
import com.pcloud.book.group.dao.ResourcePageModelDao;
import com.pcloud.book.group.dao.ResourcePageNavigationDao;
import com.pcloud.book.group.dao.ResourcePagePicDao;
import com.pcloud.book.group.dao.ResourcePageToolDao;
import com.pcloud.book.group.dao.ResourcePageWxworkDao;
import com.pcloud.book.group.dao.ResourceRecomManageDao;
import com.pcloud.book.group.dto.AddBookGroupServeDTO;
import com.pcloud.book.group.dto.BookGroupDTO;
import com.pcloud.book.group.dto.BookGroupServeCountDTO;
import com.pcloud.book.group.dto.BookGroupServeDTO;
import com.pcloud.book.group.dto.BookServeDTO;
import com.pcloud.book.group.dto.MemberActivityBookSetDTO;
import com.pcloud.book.group.dto.MessagServeDTO;
import com.pcloud.book.group.dto.MultiChannelContentDTO;
import com.pcloud.book.group.dto.NavigationParamDTO;
import com.pcloud.book.group.dto.OwnQrcodeMessageDTO;
import com.pcloud.book.group.dto.ResourcePageCourseDTO;
import com.pcloud.book.group.dto.ResourcePageDTO;
import com.pcloud.book.group.dto.ResourcePageShareDto;
import com.pcloud.book.group.dto.ResourcePageUrlDTO;
import com.pcloud.book.group.dto.WxworkPageFixedDTO;
import com.pcloud.book.group.entity.BookAppletScene;
import com.pcloud.book.group.entity.BookGroup;
import com.pcloud.book.group.entity.BookGroupServe;
import com.pcloud.book.group.entity.ResourcePage;
import com.pcloud.book.group.entity.ResourcePageBookstore;
import com.pcloud.book.group.entity.ResourcePageCollect;
import com.pcloud.book.group.entity.ResourcePageColumn;
import com.pcloud.book.group.entity.ResourcePageCourse;
import com.pcloud.book.group.entity.ResourcePageFolder;
import com.pcloud.book.group.entity.ResourcePageFolderItem;
import com.pcloud.book.group.entity.ResourcePageItem;
import com.pcloud.book.group.entity.ResourcePageMarketingActivity;
import com.pcloud.book.group.entity.ResourcePageModel;
import com.pcloud.book.group.entity.ResourcePageNavigation;
import com.pcloud.book.group.entity.ResourcePageOuterLink;
import com.pcloud.book.group.entity.ResourcePagePic;
import com.pcloud.book.group.entity.ResourcePageShare;
import com.pcloud.book.group.entity.ResourcePageTool;
import com.pcloud.book.group.entity.ResourcePageWxwork;
import com.pcloud.book.group.entity.ResourceRecomManage;
import com.pcloud.book.group.enums.IMaskFlag;
import com.pcloud.book.group.enums.JoinGroupTypeEnum;
import com.pcloud.book.group.enums.PageLandingPageTypeEnum;
import com.pcloud.book.group.enums.QrcodeJumpType;
import com.pcloud.book.group.enums.ResourcePageFixtureTypeEnum;
import com.pcloud.book.group.enums.ResourcePageSwitchConfigEnum;
import com.pcloud.book.group.mapper.ResourcePageFolderItemMapper;
import com.pcloud.book.group.mapper.ResourcePageFolderMapper;
import com.pcloud.book.group.mapper.ResourcePageMarketingActivityMapper;
import com.pcloud.book.group.mapper.ResourcePageShareMapper;
import com.pcloud.book.group.tools.SendWeixinRequestTools;
import com.pcloud.book.group.vo.CrmContactQrcodeVO;
import com.pcloud.book.group.vo.RecommendServeVO;
import com.pcloud.book.group.vo.ResourceColumnAndServeVO;
import com.pcloud.book.group.vo.ResourcePageBookstoreVO;
import com.pcloud.book.group.vo.ResourcePageFolderItemVO;
import com.pcloud.book.group.vo.ResourcePageFolderVO;
import com.pcloud.book.group.vo.ResourcePageItemResourceVO;
import com.pcloud.book.group.vo.ResourcePageItemVO;
import com.pcloud.book.group.vo.ResourcePageMarketingActivityVO;
import com.pcloud.book.group.vo.ResourcePageOneServe;
import com.pcloud.book.group.vo.ResourcePageShareParam;
import com.pcloud.book.group.vo.ResourcePageVO;
import com.pcloud.book.group.vo.UpdateResourceColumnVO;
import com.pcloud.book.group.vo.UpdateResourcePageVO;
import com.pcloud.book.group.vo.WxworkPageCreateVO;
import com.pcloud.book.group.vo.WxworkPageVO;
import com.pcloud.book.recommend.biz.BookRecommendBiz;
import com.pcloud.book.recommend.dto.RecommendServeDto;
import com.pcloud.book.rightsSetting.biz.RightsSettingBiz;
import com.pcloud.book.skill.biz.PcloudGroupActivityBiz;
import com.pcloud.book.util.common.ThreadPoolUtils;
import com.pcloud.book.util.common.YesOrNoEnums;
import com.pcloud.book.util.properties.BookProps;
import com.pcloud.channelcenter.base.constants.MessageFromTypeEnum;
import com.pcloud.channelcenter.qrcode.dto.BookSceneIdListDTO;
import com.pcloud.channelcenter.qrcode.dto.GroupQrcodeVO;
import com.pcloud.channelcenter.qrcode.dto.QrcodeSceneDto;
import com.pcloud.channelcenter.qrcode.entity.NftBookState;
import com.pcloud.channelcenter.qrcode.entity.QrcodeTemp;
import com.pcloud.channelcenter.wechat.dto.AccountSettingDto;
import com.pcloud.channelcenter.wechat.entity.AccountSetting;
import com.pcloud.combinedmarketing.memberActivity.dto.ActivityBaseInfoWithPriceDTO;
import com.pcloud.common.constant.LinkServeConstant;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.constant.AdviserTaskConstants;
import com.pcloud.common.core.constant.MQTopicProducer;
import com.pcloud.common.core.constant.ProductTypeConstant;
import com.pcloud.common.core.constant.SystemCode;
import com.pcloud.common.enums.AppTypeEnum;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.BeanUtils;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.NumberUtil;
import com.pcloud.common.utils.QrcodeUtils;
import com.pcloud.common.utils.ServeLinkUtils;
import com.pcloud.common.utils.UUIDUitl;
import com.pcloud.common.utils.cache.redis.JedisClusterUtils;
import com.pcloud.common.utils.json.JSONUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.contentcenter.resource.dto.ResourceDTO;
import com.pcloud.facade.wxwork.contact.vo.WxContactWayVO;
import com.pcloud.function.douluo.dto.AppTaskDTO;
import com.pcloud.message.common.enums.YesNoEnums;
import com.pcloud.promotion.couponsnew.dto.CouponsNewDto;
import com.pcloud.readercenter.common.enums.YesOrNoNumEnum;
import com.pcloud.readercenter.userlabel.dto.UserGradeLabelIdDTO;
import com.pcloud.resourcecenter.product.dto.ProductDto;
import com.pcloud.resourcecenter.product.dto.ProductLabelDto;
import com.pcloud.resourcecenter.store.dto.SinglePageInfoDTO;
import com.pcloud.usercenter.party.adviser.dto.AdviserBaseInfoDto;
import com.pcloud.wechatgroup.wxwork.dto.WxworkGroupQrcodeBaseDTO;
import io.vavr.control.Try;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static com.pcloud.book.group.constant.ResourcePageConstants.DL_BOOK_SERVES_CACHE;

/**
 * @ClassName com.pcloud.book.group.biz.impl.ResourcePageBizImpl
 * @Author zhuyajie
 * @Description 自有码H5页面
 * @Date 2021/3/26 15:57
 * @Version 1.0
 **/
@Component
@Slf4j
public class ResourcePageBizImpl implements ResourcePageBiz {

    private static final Logger LOGGER = LoggerFactory.getLogger(ResourcePageBizImpl.class);

    @Autowired
    private ResourcePageDao resourcePageDao;
    @Autowired
    private ResourcePageColumnDao resourcePageColumnDao;
    @Autowired
    private ResourcePageItemDao resourcePageItemDao;
    @Autowired
    private BookGroupBiz bookGroupBiz;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private ProductConsr productConsr;
    @Autowired
    private PcloudGroupActivityBiz pcloudGroupActivityBiz;
    @Autowired
    private AppletBooklistBiz appletBooklistBiz;
    @Autowired
    private RightsSettingBiz rightsSettingBiz;
    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;
    @Autowired
    private BookGroupDao bookGroupDao;
    @Autowired
    private AppletThirdResourcesBiz appletThirdResourcesBiz;
    @Autowired
    private BookBiz bookBiz;
    @Autowired
    private AgentConsr agentConsr;
    @Autowired
    private AdviserConsr adviserConsr;
    @Autowired
    private BookAppletSceneDao bookAppletSceneDao;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private ResourcePageCollectDao resourcePageCollectDao;
    @Autowired
    private AdviserTaskConsr adviserTaskConsr;
    @Autowired
    private AdvertisingConsr advertisingConsr;
    @Autowired
    private ESBookAndAdviserBiz esBookAndAdviserBiz;
    @Autowired
    private ResourcePageToolDao resourcePageToolDao;
    @Autowired
    private ReaderConsr readerConsr;
    @Autowired
    private ResourcePageCourseDao resourcePageCourseDao;
    @Autowired
    private BrowseRecordConsr browseRecordConsr;
    @Autowired
    private ChannelConsr channelConsr;
    @Autowired
    private AppletGroupSearchRecordBiz appletGroupSearchRecordBiz;
    @Autowired
    private MerchantConsr merchantConsr;
    @Autowired
    private AppletRecordAggrStatisBiz appletRecordAggrStatisBiz;
    @Autowired
    private ResourceRecomManageDao resourceRecomManageDao;
    @Autowired
    private ResourcePageBookstoreBiz resourcePageBookstoreBiz;
    @Autowired
    private ResourcePageNavigationDao resourcePageNavigationDao;
    @Autowired
    private ResourcePagePicDao resourcePagePicDao;
    @Autowired
    private TradeConsr tradeConsr;
    @Autowired
    private MemberActivityConsr memberActivityConsr;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private BookAdviserBiz bookAdviserBiz;
    @Autowired
    private BookRecommendBiz bookRecommendBiz;
    @Autowired
    private ResourcePageWxworkDao resourcePageWxworkDao;
    @Autowired
    private ShareImageConsr shareImageConsr;
    @Autowired
    private WxworkConsr wxworkConsr;
    @Autowired
    private ErpConsr erpConsr;
    @Autowired
    private ResourcePageShareMapper shareMapper;
    @Autowired
    private FunctionConsr functionConsr;
    @Autowired
    private ResourcePageModelDao resourcePageModelDao;
    @Autowired
    private ResourceConsr resourceConsr;
    @Autowired
    private BookAuthServeBiz bookAuthServeBiz;
    @Autowired
    private ResourcePageOuterLinkBiz resourcePageOuterLinkBiz;
    @Autowired
    private MultiChannelContentBiz multiChannelContentBiz;
    @Autowired
    private ResourcePageFolderMapper resourcePageFolderMapper;
    @Autowired
    private ResourcePageFolderItemMapper resourcePageFolderItemMapper;
    @Autowired
    private ResourcePageMarketingActivityMapper resourcePageMarketingActivityMapper;
    @Autowired
    private PromotionConsr promotionConsr;


    @Value("${book.share.defaultTitle}")
    private String defaultShareTitle;
    @Value("${book.share.defaultContent}")
    private String defaultShareContent;
    @Value("${book.share.defaultImgUrl}")
    private String defaultShareImgUrl;
    @Value("${nft.book}")
    private List<Long> nftBookId;
    @Value("${nft.resourcePageId}")
    private  Long pageId;
    @Value("${nft.naviId}")
    private  Long  naviId;
    @Value("${nft.sceneId}")
    private  Long nftSceneId;
    @Value("${nft.bookGroupId}")
    private  Long  nftBookGroupId;
    @Value("${system.env}")
    private String envStr;
    public static final String   nftReleaseLockKey = "CHANNELCENTER:NFT:RELEASE";
    @Value("${one_serve_rule_version}")
    private  Long oneServeRuleVersion;

    @Override
    public Long updateResourcePage(UpdateResourcePageVO updateResourcePageVO) {
        if (null == updateResourcePageVO.getBookGroupId() && null == updateResourcePageVO.getSceneId()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数缺失");
        }
        //处理上邮项目 不更新
        ResourcePage bySceneId = null;
        if (null != updateResourcePageVO.getBookGroupId()) {
            bySceneId = resourcePageDao.getByBookGroupId(updateResourcePageVO.getBookGroupId());
        } else if (null != updateResourcePageVO.getSceneId()) {
            bySceneId =  resourcePageDao.getBySceneId(updateResourcePageVO.getSceneId());
        }
        //上邮临时处理方案
        if (null != bySceneId && null != bySceneId.getBookId() && null != JedisClusterUtils.hget(nftReleaseLockKey, bySceneId.getBookId().toString())) {
            NftBookState nftBookState = JedisClusterUtils.hgetJson2Class(nftReleaseLockKey, bySceneId.getBookId().toString(), NftBookState.class);
            if (null != updateResourcePageVO.getBookGroupId()) {
                if (null != nftBookState.getNftBookGroupId() && !nftBookState.getNftBookGroupId().equals(updateResourcePageVO.getBookGroupId())) {
                    throw new BizException(BizException.PARAM_IS_NULL.getCode(), "此二维码需统一配置资源, 请勿单独配置");
                }
            } else if (null != updateResourcePageVO.getSceneId()) {
                if (null != nftBookState.getNftSceneId() && !nftBookState.getNftSceneId().equals(updateResourcePageVO.getSceneId())) {
                    throw new BizException(BizException.PARAM_IS_NULL.getCode(), "此二维码需统一配置资源, 请勿单独配置");
                }
            }
        }
        if (null != updateResourcePageVO.getBookGroupId()) {
           return this.updatePageByBookGroupId(updateResourcePageVO);
        } else if (null != updateResourcePageVO.getSceneId()) {
            return this.updatePageBySceneId(updateResourcePageVO);
        }
        return null;
    }

    private void checkOpenRays(Long bookId, Integer openRaysState) {
        if (openRaysState != 1) {
            return;
        }
        if (null == bookId || bookId == 0) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "二维码未关联书刊， 不能开启小睿流程");
        }
    }

    private Long updatePageBySceneId(UpdateResourcePageVO updateResourcePageVO){
        Long sceneId = updateResourcePageVO.getSceneId();
        ResourcePage resourcePage = resourcePageDao.getBySceneId(sceneId);
        //互助和打卡导航加到图书服务中配置，由前端控制是否配置
        if (null != updateResourcePageVO.getOpenRays()) {
            this.updateResourcePageModel(resourcePage.getId(),updateResourcePageVO.getResourcePageModelList(),resourcePage.getCreateUser());
        }
        updateResourcePageVO.setOpenRays(updateResourcePageVO.getOpenRays() == null ? 0 : updateResourcePageVO.getOpenRays());
        QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getById(sceneId);
        int switchConfig = IMaskFlag.Helper.of()
                .state(ResourcePageSwitchConfigEnum.SHOW_SELF, updateResourcePageVO.getShowSelf())
                .state(ResourcePageSwitchConfigEnum.SHOW_COLLECT, updateResourcePageVO.getShowCollect())
                .state(ResourcePageSwitchConfigEnum.SHOW_SHARE, updateResourcePageVO.getShowShare())
                .state(ResourcePageSwitchConfigEnum.NEW_EDITOR, updateResourcePageVO.getNewEditor())
                .getFlagVal();
        if (null == resourcePage) {
            resourcePage = new ResourcePage();
            BeanUtils.copyProperties(updateResourcePageVO, resourcePage);
            resourcePage.setSwitchConfig(switchConfig);
            resourcePage.setQrcodeUrl(null == qrcodeSceneDto?null:qrcodeSceneDto.getQrcodeUrl());
            //同步bookGroupId
            if (null == resourcePage.getBookGroupId()) {
                resourcePage.setBookGroupId(getBookGroupIdBySceneId(qrcodeSceneDto));
            }
            resourcePage.setBookId(null == qrcodeSceneDto?null:qrcodeSceneDto.getAdviserBookId());
            resourcePage.setChannelId(null == qrcodeSceneDto?null:qrcodeSceneDto.getChannelPartyId());
            //校验能否开启小睿
            this.checkOpenRays(resourcePage.getBookId(), updateResourcePageVO.getOpenRays());
            resourcePageDao.insert(resourcePage);
            //加到缓存中
            addResourcePageToRedis(resourcePage);
        } else {
            resourcePage.setStyle(updateResourcePageVO.getStyle());
            resourcePage.setOpenRays(updateResourcePageVO.getOpenRays());
            resourcePage.setOpenFood(updateResourcePageVO.getOpenFood());
            resourcePage.setShowBook(updateResourcePageVO.getShowBook());
            resourcePage.setBookCover(updateResourcePageVO.getBookCover());
            resourcePage.setBookId(null == qrcodeSceneDto?null:qrcodeSceneDto.getAdviserBookId());
            resourcePage.setChannelId(null == qrcodeSceneDto?null:qrcodeSceneDto.getChannelPartyId());
            resourcePage.setSwitchConfig(switchConfig);
            //同步bookGroupId
            if (null == resourcePage.getBookGroupId()) {
                resourcePage.setBookGroupId(getBookGroupIdBySceneId(qrcodeSceneDto));
            }
            //校验能否开启小睿
            this.checkOpenRays(resourcePage.getBookId(), updateResourcePageVO.getOpenRays());
            resourcePage.setBackgroundImg(updateResourcePageVO.getBackgroundImg());
            resourcePage.setFontColor(updateResourcePageVO.getFontColor());
            resourcePage.setWatermark(updateResourcePageVO.getWatermark());
            resourcePage.setWatermarkStyle(updateResourcePageVO.getWatermarkStyle());
            resourcePage.setTransparency(updateResourcePageVO.getTransparency());
            resourcePage.setIsShowPrice(updateResourcePageVO.getIsShowPrice());
            resourcePageDao.update(resourcePage);
            //删除缓存中
            delResourcePageToRedis(resourcePage);
        }
        if (updateResourcePageVO.getOpenRays() == 1) {
            //小程序码
            BookAppletScene appletScene = bookAppletSceneDao.getBySceneId(sceneId);
            if (null == appletScene) {
                BookAppletScene bookAppletScene = new BookAppletScene();
                bookAppletScene.setSceneId(sceneId);
                bookAppletScene.setAppletId(UUIDUitl.generateString(20));
                bookAppletScene.setAccountSettingId(BookProps.getMiniOfficialAccountsId());
                bookAppletSceneDao.insert(bookAppletScene);
            }
            //同一本书其他码下关闭小睿流程,查出要关闭的资源页，然后更新
            List<ResourcePage> otherPageRaysOpen = resourcePageDao.getOtherPageRaysOpen(resourcePage.getBookId(), resourcePage.getChannelId(), resourcePage.getCreateUser(), sceneId, null);
            //删除修改过的二维码缓存
            if(CollUtil.isNotEmpty(otherPageRaysOpen)){
                otherPageRaysOpen.forEach(e->{
                    delResourcePageToRedis(e);
                    ResourcePage page = new ResourcePage();
                    page.setId(e.getId());
                    page.setOpenRays(0);
                    resourcePageDao.update(page);
                });
            }
        } else {
            //删除小程序默认导航
            this.deleteAppletDefaultNavigation(resourcePage.getId());
        }
        Long resourcePageId = resourcePage.getId();
        ThreadPoolUtils.OTHER_THREAD_POOL.execute(()-> esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(resourcePageId)));
        //更新二维码是否一个资源配置
      //  ThreadPoolUtils.OTHER_POOL.execute(()->{
            this.updateQrcodeOneServe(updateResourcePageVO.getBookGroupId(),updateResourcePageVO.getSceneId(),null);
     //   });
        return resourcePage.getId();
    }

    private void addResourcePageToRedis(ResourcePage resourcePage) {
        ResourcePageDTO resourcePageDTO=new ResourcePageDTO();
        BeanUtil.copyProperties(resourcePage,resourcePageDTO);
        if(null!=resourcePage.getSceneId()) {
            JedisClusterUtils.hset2Json(BookConstant.RESOURCE_PAGE_BY_SCENE_ID,resourcePage.getSceneId().toString(),resourcePageDTO);
            JedisClusterUtils.expire(BookConstant.RESOURCE_PAGE_BY_SCENE_ID, 3600 * 24);
        }
        if(null!=resourcePage.getBookGroupId()) {
            JedisClusterUtils.hset2Json(BookConstant.RESOURCE_PAGE_BY_BOOK_GROUP_ID,resourcePage.getBookGroupId().toString(),resourcePageDTO);
            JedisClusterUtils.expire(BookConstant.RESOURCE_PAGE_BY_BOOK_GROUP_ID, 3600 * 24);
        }
    }

    private void delResourcePageToRedis(ResourcePage resourcePage) {
        if(null!=resourcePage.getSceneId()) {
            JedisClusterUtils.hdel(BookConstant.RESOURCE_PAGE_BY_SCENE_ID,resourcePage.getSceneId().toString());
            ThreadPoolUtils.OTHER_THREAD_POOL.execute(()->qrcodeSceneConsr.deleteParseRedis(resourcePage.getSceneId(),null));
        }
        if(null!=resourcePage.getBookGroupId()) {
            JedisClusterUtils.hdel(BookConstant.RESOURCE_PAGE_BY_BOOK_GROUP_ID,resourcePage.getBookGroupId().toString());
            ThreadPoolUtils.OTHER_THREAD_POOL.execute(()->qrcodeSceneConsr.deleteParseRedis(null,resourcePage.getBookGroupId()));
        }
    }

    private Long getBookGroupIdBySceneId(QrcodeSceneDto qrcodeSceneDto) {
        if (null == qrcodeSceneDto || StringUtil.isEmpty(qrcodeSceneDto.getQrcodeType())
                || StringUtil.isEmpty(qrcodeSceneDto.getSceneCode())) {
            return null;
        }
        if ("own".equalsIgnoreCase(qrcodeSceneDto.getQrcodeType())) {
            String bookGroupId = qrcodeSceneDto.getSceneCode().replace("own","").replace("OWN","");
            if (NumberUtil.isNumber(bookGroupId)) {
                return Long.valueOf(bookGroupId);
            }
        }
        return null;
    }

    private Long updatePageByBookGroupId(UpdateResourcePageVO updateResourcePageVO) {
        Long bookGroupId = updateResourcePageVO.getBookGroupId();
        ResourcePage resourcePage = resourcePageDao.getByBookGroupId(bookGroupId);
        //互助和打卡导航加到图书服务中配置，由前端控制是否配置
        if (null != updateResourcePageVO.getOpenRays()) {
            this.updateResourcePageModel(resourcePage.getId(),updateResourcePageVO.getResourcePageModelList(),resourcePage.getCreateUser());
        }
        updateResourcePageVO.setOpenRays(updateResourcePageVO.getOpenRays() == null ? 0 : updateResourcePageVO.getOpenRays());
        BookGroupDTO dto = bookGroupDao.getDTOById(bookGroupId);
        int switchConfig = IMaskFlag.Helper.of()
                .state(ResourcePageSwitchConfigEnum.SHOW_SELF, updateResourcePageVO.getShowSelf())
                .state(ResourcePageSwitchConfigEnum.SHOW_COLLECT, updateResourcePageVO.getShowCollect())
                .state(ResourcePageSwitchConfigEnum.SHOW_SHARE, updateResourcePageVO.getShowShare())
                .state(ResourcePageSwitchConfigEnum.NEW_EDITOR, updateResourcePageVO.getNewEditor())
                .getFlagVal();
        if (null == resourcePage) {
            resourcePage = new ResourcePage();
            BeanUtils.copyProperties(updateResourcePageVO, resourcePage);
            resourcePage.setQrcodeUrl(null == dto? null: dto.getGroupQrcodeUrl());
            resourcePage.setBookId(null == dto?null:dto.getBookId());
            resourcePage.setChannelId(null == dto?null:dto.getChannelId());
            resourcePage.setSwitchConfig(switchConfig);
            //校验能否开启小睿
            this.checkOpenRays(resourcePage.getBookId(), updateResourcePageVO.getOpenRays());
            resourcePageDao.insert(resourcePage);
            //加到缓存中
            addResourcePageToRedis(resourcePage);
        } else {
            resourcePage.setSwitchConfig(switchConfig);
            resourcePage.setStyle(updateResourcePageVO.getStyle());
            resourcePage.setOpenRays(updateResourcePageVO.getOpenRays());
            resourcePage.setShowBook(updateResourcePageVO.getShowBook());
            //校验能否开启小睿
            this.checkOpenRays(resourcePage.getBookId(), updateResourcePageVO.getOpenRays());
            resourcePage.setBookCover(updateResourcePageVO.getBookCover());
            resourcePage.setBackgroundImg(updateResourcePageVO.getBackgroundImg());
            resourcePage.setBookId(null == dto?null:dto.getBookId());
            resourcePage.setChannelId(null == dto?null:dto.getChannelId());
            resourcePage.setFontColor(updateResourcePageVO.getFontColor());
            resourcePage.setWatermark(updateResourcePageVO.getWatermark());
            resourcePage.setWatermarkStyle(updateResourcePageVO.getWatermarkStyle());
            resourcePage.setTransparency(updateResourcePageVO.getTransparency());
            resourcePage.setIsShowPrice(updateResourcePageVO.getIsShowPrice());
            resourcePageDao.update(resourcePage);
            //删除缓存中
            delResourcePageToRedis(resourcePage);
        }
        if (updateResourcePageVO.getOpenRays() == 1) {
            //小程序码
            BookAppletScene appletScene = bookAppletSceneDao.getByBookGroupId(bookGroupId);
            if (null == appletScene) {
                BookAppletScene bookAppletScene = new BookAppletScene();
                bookAppletScene.setBookGroupId(bookGroupId);
                bookAppletScene.setAppletId(UUIDUitl.generateString(20));
                bookAppletScene.setAccountSettingId(BookProps.getMiniOfficialAccountsId());
                bookAppletSceneDao.insert(bookAppletScene);
            }
            //同一本书其他码下关闭小睿流程,查出要关闭的资源页，然后更新
            List<ResourcePage> otherPageRaysOpen = resourcePageDao.getOtherPageRaysOpen(resourcePage.getBookId(), resourcePage.getChannelId(), resourcePage.getCreateUser(), null, bookGroupId);
            //删除修改过的二维码缓存
            if(CollUtil.isNotEmpty(otherPageRaysOpen)){
                otherPageRaysOpen.forEach(e->{
                    delResourcePageToRedis(e);
                    ResourcePage page = new ResourcePage();
                    page.setId(e.getId());
                    page.setOpenRays(0);
                    resourcePageDao.update(page);
                });
            }
        } else {
            //删除小程序默认导航
            this.deleteAppletDefaultNavigation(resourcePage.getId());
        }
        Long resourcePageId = resourcePage.getId();
        ThreadPoolUtils.OTHER_THREAD_POOL.execute(()-> esBookAndAdviserBiz.updateBookAndAdviserToES(Collections.singletonList(resourcePageId)));
        //更新二维码是否一个资源配置
       // ThreadPoolUtils.OTHER_POOL.execute(()->{
            this.updateQrcodeOneServe(updateResourcePageVO.getBookGroupId(),updateResourcePageVO.getSceneId(),null);
      //  });
        return resourcePage.getId();
    }


    @Override
    public ResourcePage createDefaultResourcePage(Long bookGroupId, Long adviserId, Long sceneId, Integer openRays, Integer landingPageType) {
        ResourcePage resourcePage = new ResourcePage();
        resourcePage.setBookGroupId(bookGroupId);
        resourcePage.setStyle(1);
        resourcePage.setOpenRays(openRays);
        resourcePage.setShowBook(1);
        resourcePage.setCreateUser(adviserId);
        resourcePage.setSceneId(sceneId);
        //落地页类型，默认本书服务页
        landingPageType = null == landingPageType? PageLandingPageTypeEnum.RESOURCE.getCode():landingPageType;
        resourcePage.setLandingPageType(landingPageType);
        //预览二维码,取原有二维码
        if (null != bookGroupId) {
            BookGroupDTO dto = bookGroupDao.getDTOById(bookGroupId);
            resourcePage.setQrcodeUrl(null == dto?null:dto.getGroupQrcodeUrl());
            resourcePage.setBookId(null == dto?null:dto.getBookId());
            resourcePage.setChannelId(null == dto?null:dto.getChannelId());
        } else if (null != sceneId) {
            QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getById(sceneId);
            resourcePage.setQrcodeUrl(null == qrcodeSceneDto?null:qrcodeSceneDto.getQrcodeUrl());
            //同步bookGroupId
            resourcePage.setBookGroupId(getBookGroupIdBySceneId(qrcodeSceneDto));
            resourcePage.setBookId(null == qrcodeSceneDto?null:qrcodeSceneDto.getAdviserBookId());
            resourcePage.setChannelId(null == qrcodeSceneDto?null:qrcodeSceneDto.getChannelPartyId());
        }
        resourcePage.setSwitchConfig(
                IMaskFlag.Helper.of()
                        .defaultState(ResourcePageSwitchConfigEnum.SHOW_SELF)
                        .defaultState(ResourcePageSwitchConfigEnum.SHOW_COLLECT)
                        .defaultState(ResourcePageSwitchConfigEnum.SHOW_SHARE)
                        .defaultState(ResourcePageSwitchConfigEnum.NEW_EDITOR)
                        .getFlagVal()
        );
        resourcePageDao.insert(resourcePage);
        //加入缓存
        addResourcePageToRedis(resourcePage);
        if (PageLandingPageTypeEnum.RESOURCE.getCode().equals(landingPageType) || PageLandingPageTypeEnum.SINGLE_RESOURCE.getCode().equals(landingPageType)) {
            //本书服务页添加默认导航
            this.addDefaultBookServeNavigation(resourcePage.getId());
        }
        return resourcePage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateResourceColumn(UpdateResourceColumnVO updateResourceColumnVO) throws BizException {
        updateResourceColumnVO.setShowMore(updateResourceColumnVO.getShowMore() != null && updateResourceColumnVO.getShowMore());
        //栏目校验
        this.checkResourceColumn(updateResourceColumnVO);
        //新增修改栏目
        Long resourcePageColumnId = this.createOrUpdateColumn(updateResourceColumnVO);
        //栏目资源
        resourcePageItemDao.deleteByPageColumnId(resourcePageColumnId);
        if (ResourcePageConstants.ColumnTypeEnum.OFFICIAL_ACCOUNT.getCode().equals(updateResourceColumnVO.getColumnType())) {
            //公众号栏目
            createOfficialAccountUrl(resourcePageColumnId, updateResourceColumnVO);
            return;
        }
        // 新版通用组件
        if (ResourcePageConstants.ColumnTypeEnum.COMMON_COMPONENT.getCode().equals(updateResourceColumnVO.getColumnType())){
            updateResourceColumnVO.getItemVOList().stream()
                    // save resource_page_folder and resource_page_folder_item, then return serve_id
                    .peek(x -> saveNewCommonComponent(x.getResourcePageFolder(), updateResourceColumnVO, resourcePageColumnId))
                    // fill serve_id
                    .forEach(x->x.setServeId(x.getResourcePageFolder().getId()));
        }

        // 过滤外链
        List<ResourcePageOuterLink> addOuterLink = updateResourceColumnVO.getItemVOList().stream().filter(this::checkIsOutLink)
                .map(ResourcePageItemVO::getResourcePageOuterLink).peek(this::checkOutLinkParam).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(addOuterLink)) {
            addOuterLink.forEach(e -> e.setResourceColumnId(resourcePageColumnId));
            resourcePageOuterLinkBiz.batchInsert(addOuterLink);
        }
        // 新增多渠道
        List<MultiChannelContentDTO> multiChannelContentDTOS = updateResourceColumnVO.getItemVOList().stream().filter(this::checkIsMultiChannel)
                .map(ResourcePageItemVO::getMultiChannelContent).peek(this::checkMultiChannelParam).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(multiChannelContentDTOS)) {
           multiChannelContentBiz.batchInsert(multiChannelContentDTOS);
        }
        //作品id
        List<Long> productIds4Shelve = updateResourceColumnVO.getItemVOList().stream().filter(s->s.getServeType().equals(ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue())).map(ResourcePageItemVO::getServeId).distinct().collect(Collectors.toList());
        if (!ListUtils.isEmpty(updateResourceColumnVO.getItemVOList())) {
            List<ResourcePageItemVO> itemVOList = updateResourceColumnVO.getItemVOList();
            List<ResourcePageItem> itemList = new ArrayList<>();
            for (ResourcePageItemVO itemVO : itemVOList) {
                ResourcePageItem item = new ResourcePageItem();
                BeanUtils.copyProperties(itemVO, item);
                item.setResourcePageColumnId(resourcePageColumnId);
                item.setResourcePageId(updateResourceColumnVO.getResourcePageId());
                item.setCreateUser(updateResourceColumnVO.getCreateUser());
                //根据展示数量设置是否展示
                item.setIsShow(true);
                if (updateResourceColumnVO.getShowMore() && itemList.indexOf(item) + 1 > updateResourceColumnVO.getShowCount()) {
                    item.setIsShow(false);
                }
                //编辑书刊链接
                if (ResourcePageConstants.ServeTypeEnum.ADVISER_BOOK.getValue().equals(itemVO.getServeType())) {
                    BookLinkVO linkVO = new BookLinkVO();
                    linkVO.setBookId(itemVO.getServeId());
                    linkVO.setLinkFrom(itemVO.getLinkFrom());
                    linkVO.setLinkUrl(itemVO.getLinkUrl());
                    bookBiz.updateBookLink(linkVO, updateResourceColumnVO.getCreateUser());
                }
                //图片位
                if (ResourcePageConstants.ColumnTypeEnum.PICTURE.getCode().equals(updateResourceColumnVO.getColumnType())) {
                    item.setLogoUrl(updateResourceColumnVO.getLogoUrl());
                }
                //外链
                if (ResourcePageConstants.ColumnTypeEnum.OUTER_LINK.getCode().equals(updateResourceColumnVO.getColumnType())) {
                    item.setServeId(itemVO.getResourcePageOuterLink().getId());
                }
                //多渠道
                if (ResourcePageConstants.ColumnTypeEnum.MULTI_CHANNEL.getCode().equals(updateResourceColumnVO.getColumnType())) {
                    item.setServeId(itemVO.getMultiChannelContent().getId());
                }
                itemList.add(item);
            }
            resourcePageItemDao.insert(itemList);
        }
        if (!ListUtils.isEmpty(productIds4Shelve)){
            //作品自动上架
            ThreadPoolUtils.RESOURCE_POOL.execute(()->{
                Long channelId = updateResourceColumnVO.getChannelId();
                if (null == channelId) {
                    channelId = getChannelIdFromUrl(updateResourceColumnVO.getItemVOList().get(0).getLinkUrl());
                }
                Map<Long, String> offShelvesMap = productConsr.productAutoOnShelves(channelId, productIds4Shelve);
                if (!MapUtils.isEmpty(offShelvesMap)) {
                    //已下架的作品重新上架
                    List<Long> proIds = new ArrayList<>(offShelvesMap.keySet());
                    productConsr.setOffShelvesProductOnShelves(channelId, proIds);
                }
            });
        }
    }

    private void saveNewCommonComponent(ResourcePageFolderVO resourcePageFolderVO, UpdateResourceColumnVO updateResourceColumnVO, Long resourcePageColumnId) {
        if (!Objects.equals(resourcePageFolderVO.getJumpType(), 3) && CollUtil.isEmpty(resourcePageFolderVO.getFolderItemList())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "资源配置参数缺失！");
        }
        ResourcePageFolder resourcePageFolder = BeanUtil.copyProperties(resourcePageFolderVO, ResourcePageFolder.class);
        resourcePageFolder.setResourcePageId(updateResourceColumnVO.getResourcePageId());
        resourcePageFolder.setResourcePageColumnId(resourcePageColumnId);
        resourcePageFolder.setCreateUser(updateResourceColumnVO.getCreateUser());
        resourcePageFolderMapper.insert(resourcePageFolder);
        resourcePageFolderVO.setId(resourcePageFolder.getId());

        // 处理外链
        List<ResourcePageOuterLink> addOuterLink = resourcePageFolderVO.getFolderItemList().stream()
                .filter(this::checkIsOutLink)
                .map(ResourcePageFolderItemVO::getResourcePageOuterLink).peek(this::checkOutLinkParam).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(addOuterLink)) {
            addOuterLink.forEach(e -> e.setResourceColumnId(resourcePageColumnId));
            resourcePageOuterLinkBiz.batchInsert(addOuterLink);
        }

        // 新增多渠道
        List<MultiChannelContentDTO> multiChannelContentDTOS = resourcePageFolderVO.getFolderItemList().stream()
                .filter(this::checkIsMultiChannel)
                .map(ResourcePageFolderItemVO::getMultiChannelContent)
                .peek(this::checkMultiChannelParam)
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(multiChannelContentDTOS)) {
            multiChannelContentBiz.batchInsert(multiChannelContentDTOS);
        }

        //作品id
        List<Long> productIds4Shelve = resourcePageFolderVO.getFolderItemList().stream().filter(s -> s.getServeType().equals(ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue()))
                .map(ResourcePageFolderItemVO::getServeId).distinct().collect(Collectors.toList());
        if (!ListUtils.isEmpty(resourcePageFolderVO.getFolderItemList())) {
            List<ResourcePageFolderItemVO> itemVOList = resourcePageFolderVO.getFolderItemList();
            List<ResourcePageFolderItem> itemList = new ArrayList<>();
            for (ResourcePageFolderItemVO itemVO : itemVOList) {
                ResourcePageFolderItem item = new ResourcePageFolderItem();
                BeanUtils.copyProperties(itemVO, item);
                item.setResourcePageId(updateResourceColumnVO.getResourcePageId());
                item.setResourcePageColumnId(resourcePageColumnId);
                item.setFolderId(resourcePageFolder.getId());
                item.setCreateUser(updateResourceColumnVO.getCreateUser());
                //根据展示数量设置是否展示
                item.setIsShow(1);
                if (updateResourceColumnVO.getShowMore() && itemList.indexOf(item) + 1 > updateResourceColumnVO.getShowCount()) {
                    item.setIsShow(0);
                }
                //编辑书刊链接
                if (ResourcePageConstants.ServeTypeEnum.ADVISER_BOOK.getValue().equals(itemVO.getServeType())) {
                    BookLinkVO linkVO = new BookLinkVO();
                    linkVO.setBookId(itemVO.getServeId());
                    linkVO.setLinkFrom(itemVO.getLinkFrom());
                    linkVO.setLinkUrl(itemVO.getLinkUrl());
                    bookBiz.updateBookLink(linkVO, updateResourceColumnVO.getCreateUser());
                }
                //图片位
                if (ResourcePageConstants.ColumnTypeEnum.PICTURE.getCode().equals(updateResourceColumnVO.getColumnType())) {
                    item.setLogoUrl(updateResourceColumnVO.getLogoUrl());
                }
                //外链
                if (ResourcePageConstants.ColumnTypeEnum.OUTER_LINK.getCode().equals(updateResourceColumnVO.getColumnType())) {
                    item.setServeId(itemVO.getResourcePageOuterLink().getId());
                }
                //多渠道
                if (ResourcePageConstants.ColumnTypeEnum.MULTI_CHANNEL.getCode().equals(updateResourceColumnVO.getColumnType())) {
                    item.setServeId(itemVO.getMultiChannelContent().getId());
                }
                itemList.add(item);
            }
            resourcePageFolderItemMapper.batchInsert(itemList);
        }
        if (!ListUtils.isEmpty(productIds4Shelve)) {
            //作品自动上架
            ThreadPoolUtils.RESOURCE_POOL.execute(() -> {
                Long channelId = updateResourceColumnVO.getChannelId();
                if (null == channelId) {
                    channelId = getChannelIdFromUrl(updateResourceColumnVO.getItemVOList().get(0).getLinkUrl());
                }
                Map<Long, String> offShelvesMap = productConsr.productAutoOnShelves(channelId, productIds4Shelve);
                if (!MapUtils.isEmpty(offShelvesMap)) {
                    //已下架的作品重新上架
                    List<Long> proIds = new ArrayList<>(offShelvesMap.keySet());
                    productConsr.setOffShelvesProductOnShelves(channelId, proIds);
                }
            });
        }
    }

    private boolean checkIsMultiChannel(ResourcePageFolderItemVO resourcePageFolderItemVO) {
        return Objects.nonNull(resourcePageFolderItemVO) &&
                Objects.equals(ServeTypeEnum.MULTI_CHANNEL.getValue(), resourcePageFolderItemVO.getServeType())
                && Objects.nonNull(resourcePageFolderItemVO.getMultiChannelContent());
    }

    private boolean checkIsOutLink(@NotNull ResourcePageFolderItemVO resourcePageFolderItemVO) {
        return Objects.nonNull(resourcePageFolderItemVO) &&
                Objects.equals(ServeTypeEnum.OUTER_LINK.getValue(), resourcePageFolderItemVO.getServeType())
                && Objects.nonNull(resourcePageFolderItemVO.getResourcePageOuterLink());
    }

    private void checkMultiChannelParam(MultiChannelContentDTO multiChannelContentDTO) {
        if (Objects.isNull(multiChannelContentDTO.getChannelType())) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "请选择多渠道渠道！");
        }
        if (CollUtil.isEmpty(multiChannelContentDTO.getMultiChannelContentItems())) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "配置内容不能为null");
        }
    }

    private void checkOutLinkParam(ResourcePageOuterLink resourcePageOuterLink) {

        if (Objects.isNull(resourcePageOuterLink.getOriginId())) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "请选择外链渠道！");
        }

        if (StringUtils.isBlank(resourcePageOuterLink.getJumpUrl())) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "跳转链接不能为空！");
        }

        if (StringUtils.length(resourcePageOuterLink.getJumpUrl()) > 300) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "跳转链接超过最大长度限制【300】！");
        }
    }

    private boolean checkIsOutLink(@Nullable ResourcePageItemVO resourcePageItemVO) {
        return Objects.nonNull(resourcePageItemVO) &&
                Objects.equals(ServeTypeEnum.OUTER_LINK.getValue(), resourcePageItemVO.getServeType())
                && Objects.nonNull(resourcePageItemVO.getResourcePageOuterLink());
    }

    private boolean checkIsMultiChannel(@Nullable ResourcePageItemVO resourcePageItemVO) {
        return Objects.nonNull(resourcePageItemVO) &&
                Objects.equals(ServeTypeEnum.MULTI_CHANNEL.getValue(), resourcePageItemVO.getServeType())
                && Objects.nonNull(resourcePageItemVO.getMultiChannelContent());
    }

    private void checkResourceColumn(UpdateResourceColumnVO updateResourceColumnVO) throws BizException {
        if (null != updateResourceColumnVO.getShowMore() && updateResourceColumnVO.getShowMore() && null == updateResourceColumnVO.getShowCount()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少展示更多数量");
        }
        if (ListUtils.isEmpty(updateResourceColumnVO.getItemVOList())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, updateResourceColumnVO.getColumnName()+"缺少资源");
        }
        List<String> typeCodes = Arrays.asList(ResourcePageConstants.ServeTypeEnum.APP.getValue(), ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue());
        for (ResourcePageItemVO itemVO : updateResourceColumnVO.getItemVOList()) {
            if (ResourcePageConstants.ServeTypeEnum.ADVISER_BOOK.getValue().equals(itemVO.getServeType()) &&
                    (null == itemVO.getLinkFrom() || StringUtil.isEmpty(itemVO.getLinkUrl()))) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少书刊链接来源");
            }

            if (!(StringUtils.equalsAny(itemVO.getServeType(),
                    ResourcePageConstants.ServeTypeEnum.OFFICIAL_ACCOUNT.getValue(),
                    ResourcePageConstants.ServeTypeEnum.OUTER_LINK.getValue(),
                    ResourcePageConstants.ServeTypeEnum.MULTI_CHANNEL.getValue(),
                    ResourcePageConstants.ServeTypeEnum.FOLDER.getValue()
            )) && (null == itemVO.getServeId() || StringUtil.isEmpty(itemVO.getServeType()))) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少资源id或类型");
            }
            if (typeCodes.contains(itemVO.getServeType()) && StringUtil.isEmpty(itemVO.getLinkUrl())) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少资源链接");
            }
            if (ResourcePageConstants.ServeTypeEnum.OFFICIAL_ACCOUNT.getValue().equals(itemVO.getServeType())) {
                if (null == itemVO.getQrcodeShowType()) {
                    //默认类型：平铺
                    itemVO.setQrcodeShowType(ResourcePageConstants.QrcodeShowTypeEnum.TILED.getCode());
                }
            }
        }
        checkResourceColumn4NewComponent(updateResourceColumnVO, typeCodes);
    }

    private void checkResourceColumn4NewComponent(UpdateResourceColumnVO updateResourceColumnVO, List<String> typeCodes) {
        // 新版通用组件参数校验
        List<ResourcePageFolderItemVO> resourcePageFolderItems = Optional.ofNullable(updateResourceColumnVO.getItemVOList())
                .map(x -> x.stream().filter(Objects::nonNull).map(ResourcePageItemVO::getResourcePageFolder).collect(Collectors.toList()))
                .map(x -> x.stream().filter(Objects::nonNull).map(ResourcePageFolderVO::getFolderItemList).flatMap(Collection::stream).filter(Objects::nonNull).collect(Collectors.toList()))
                .orElse(Collections.emptyList());
        if (resourcePageFolderItems.isEmpty()) {
            return;
        }
        for (ResourcePageItemVO itemVO : resourcePageFolderItems) {
            if (ServeTypeEnum.ADVISER_BOOK.getValue().equals(itemVO.getServeType()) &&
                    (null == itemVO.getLinkFrom() || StringUtil.isEmpty(itemVO.getLinkUrl()))) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少书刊链接来源");
            }
            if (!(ServeTypeEnum.OFFICIAL_ACCOUNT.getValue().equals(itemVO.getServeType()) ||
                    ServeTypeEnum.OUTER_LINK.getValue().equals(itemVO.getServeType()) ||
                    ServeTypeEnum.FOLDER.getValue().equals(itemVO.getServeType()) ||
                    ServeTypeEnum.MULTI_CHANNEL.getValue().equals(itemVO.getServeType()))
                    && (null == itemVO.getServeId() || StringUtil.isEmpty(itemVO.getServeType()))) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少资源id或类型");
            }
            if (typeCodes.contains(itemVO.getServeType()) && StringUtil.isEmpty(itemVO.getLinkUrl())) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少资源链接");
            }
            if (ServeTypeEnum.OFFICIAL_ACCOUNT.getValue().equals(itemVO.getServeType())) {
                if (null == itemVO.getQrcodeShowType()) {
                    //默认类型：平铺
                    itemVO.setQrcodeShowType(ResourcePageConstants.QrcodeShowTypeEnum.TILED.getCode());
                }
            }
        }
    }

    @ParamLog("新增/修改栏目")
    private Long createOrUpdateColumn(UpdateResourceColumnVO updateResourceColumnVO) {
        ResourcePageColumn resourcePageColumn = new ResourcePageColumn();
        BeanUtils.copyProperties(updateResourceColumnVO, resourcePageColumn);
        if (null == updateResourceColumnVO.getResourcePageColumnId()) {
            if (null == resourcePageColumn.getColumnSeq()) {
                Integer maxSeq = resourcePageColumnDao.getMaxSeq(updateResourceColumnVO.getResourcePageId(), updateResourceColumnVO.getNavigationId());
                resourcePageColumn.setColumnSeq(maxSeq + 1);
            }
            //默认导航
            if (null == updateResourceColumnVO.getNavigationId()) {
                ResourcePageNavigation navigation = resourcePageNavigationDao.getByType(updateResourceColumnVO.getResourcePageId(),ResourcePageConstants.NavigationTypeEnum.BOOK_SERVE.getCode());
                resourcePageColumn.setNavigationId(navigation.getId());
            }
            resourcePageColumnDao.insert(resourcePageColumn);
        } else {
            resourcePageColumn.setId(updateResourceColumnVO.getResourcePageColumnId());
            resourcePageColumnDao.update(resourcePageColumn);
        }
        return resourcePageColumn.getId();
    }

    @ParamLog("生成公众号码")
    private void createOfficialAccountUrl(Long resourcePageColumnId, UpdateResourceColumnVO updateResourceColumnVO) {
        ResourcePageItemVO itemVO = updateResourceColumnVO.getItemVOList().get(0);
        ResourcePage resourcePage = resourcePageDao.getById(updateResourceColumnVO.getResourcePageId());
        if (null == resourcePage) {
            return;
        }
        if (ResourcePageConstants.QrcodeShowTypeEnum.TILED.getCode().equals(itemVO.getQrcodeShowType())) {
            //平铺方式
            createTiledQrcode(resourcePage, updateResourceColumnVO, resourcePageColumnId);
        } else {
            //弹窗方式
            Long officialAccountsId;
            ResourcePageItem item = new ResourcePageItem();
            item.setResourcePageColumnId(resourcePageColumnId);
            item.setResourcePageId(updateResourceColumnVO.getResourcePageId());
            item.setCreateUser(updateResourceColumnVO.getCreateUser());
            item.setLogoUrl(itemVO.getLogoUrl());
            item.setGuideContent(itemVO.getGuideContent());
            item.setServeType(ResourcePageConstants.ServeTypeEnum.OFFICIAL_ACCOUNT.getValue());
            item.setSeqNum(1);
            item.setIsShow(true);
            item.setQrcodeSource(ResourcePageConstants.QrcodeSourceEnum.OFFICIAL_ACCOUNT.value);
            if (null == itemVO.getAccountSettingId()) {
                officialAccountsId = BookProps.getOperateOfficalId();
            } else {
                officialAccountsId = itemVO.getAccountSettingId();
            }
            item.setServeId(officialAccountsId);
            item.setAccountSettingId(officialAccountsId);
            item.setLinkUrl(itemVO.getLinkUrl());
            item.setQrcodeShowType(itemVO.getQrcodeShowType());
            item.setQrcodeSource(itemVO.getQrcodeSource() == null ? ResourcePageConstants.QrcodeSourceEnum.OFFICIAL_ACCOUNT.value : itemVO.getQrcodeSource());
            resourcePageItemDao.insert(item);
        }
    }

    /**
     * 公众号二维码-平铺方式
     * @author：zhuyajie
     * @date：2021/8/23 15:50
     *  * @param null
     */
    private void createTiledQrcode(ResourcePage resourcePage, UpdateResourceColumnVO updateResourceColumnVO, Long resourcePageColumnId) {
        String qrcodeUrl;
        String url = null;
        ResourcePageItemVO itemVO = updateResourceColumnVO.getItemVOList().get(0);
        Long officialSceneId = resourcePage.getOfficialSceneId();
        if(ResourcePageConstants.QrcodeSourceEnum.OFFICIAL_ACCOUNT.value.equals(itemVO.getQrcodeSource())){
            if (null == officialSceneId) {
                officialSceneId = this.createOfficialScene(resourcePage.getBookGroupId(), resourcePage.getSceneId());
                if (null == officialSceneId) {
                    throw new BookBizException(BookBizException.ERROR, "二维码生成失败！");
                }
                resourcePage.setOfficialSceneId(officialSceneId);
                resourcePageDao.update(resourcePage);
                //删除缓存
                delResourcePageToRedis(resourcePage);
            }
            QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getById(officialSceneId);
            qrcodeUrl = qrcodeSceneDto.getQrcodeUrl();
            url = qrcodeSceneDto.getUrl();
        } else {
            qrcodeUrl = itemVO.getLinkUrl();
            String tmpDirPath = FileUtil.getTmpDirPath();
            if (!tmpDirPath.endsWith(File.separator)) {
                tmpDirPath = tmpDirPath + File.separator;
            }
            File file = FileUtil.touch(tmpDirPath + UUIDUitl.generateShort() + ".png");
            HttpUtil.downloadFile(qrcodeUrl, file);
            try {
                url = QrCodeUtil.decode(file);
            } catch (QrCodeException e){
                log.info("解析二维码图片失败，qrcodeUrl：{}", qrcodeUrl);
            }
        }

        ResourcePageItem item = new ResourcePageItem();
        item.setResourcePageColumnId(resourcePageColumnId);
        item.setResourcePageId(updateResourceColumnVO.getResourcePageId());
        item.setCreateUser(updateResourceColumnVO.getCreateUser());
        item.setLogoUrl(itemVO.getLogoUrl());
        item.setGuideContent(itemVO.getGuideContent());
        item.setServeType(ResourcePageConstants.ServeTypeEnum.OFFICIAL_ACCOUNT.getValue());
        item.setSeqNum(1);
        item.setIsShow(true);
        item.setServeId(officialSceneId);
        item.setQrcodeSource(itemVO.getQrcodeSource() == null ? ResourcePageConstants.QrcodeSourceEnum.OFFICIAL_ACCOUNT.value : itemVO.getQrcodeSource());
        item.setQrcodeShowType(itemVO.getQrcodeShowType());
        qrcodeUrl = this.getLogoQrcode(url, itemVO.getLogoUrl(), qrcodeUrl);
        item.setLinkUrl(qrcodeUrl);
        resourcePageItemDao.insert(item);
    }

    /**
     * 生成带logo的二维码
     * @author：zhuyajie
     * @date：2021/8/23 15:43
     *  * @param null
     */
    private String getLogoQrcode(String url, String logoUrl, String qrcodeUrl) {
        if (StringUtil.isEmpty(logoUrl) || StringUtil.isEmpty(qrcodeUrl) || StringUtil.isEmpty(url)) {
            return qrcodeUrl;
        }
        //生成黑白logo二维码
        try {
            qrcodeUrl = QrcodeUtils.createLogoQr(url, logoUrl, 0xFF000000, 1);
        } catch (BizException e) {
            log.error("生成黑白logo二维码失败"+e.getMessage(), e);
        }
        return qrcodeUrl;
    }

    /**
     * 生成公众号二维码
     * @author：zhuyajie
     * @date：2021/4/13 10:14
     *  * @param null
     */
    private Long createOfficialScene(Long bookGroupId, Long sceneId) {
        if (null == bookGroupId && null == sceneId) {
            return null;
        }
        Long bookId = null;
        Long channelId = null;
        Long adviserId = null;
        if (null != bookGroupId) {
            BookGroupDTO bookGroupDTO = bookGroupDao.getDTOById(bookGroupId);
            if (null == bookGroupDTO) {
                throw new BookBizException(BookBizException.ERROR,"RAYS码不存在");
            }
            //是否创建过公众号码
            if (null != bookGroupDTO.getSceneId()) {
                return bookGroupDTO.getSceneId();
            }
            bookId = bookGroupDTO.getBookId();
            channelId = bookGroupDTO.getChannelId();
            adviserId = bookGroupDTO.getCreateUser();
        } else if (null != sceneId) {
            QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getById(sceneId);
            if (null == qrcodeSceneDto) {
                throw new BookBizException(BookBizException.ERROR,"自建码不存在");
            }
            bookId = qrcodeSceneDto.getAdviserBookId();
            channelId = qrcodeSceneDto.getChannelPartyId();
            adviserId = qrcodeSceneDto.getCreatedByUserLogin();
        }
        if (null != bookId && null != channelId && null != adviserId) {
            GroupQrcodeVO groupQrcodeVO = qrcodeSceneConsr.createWxGroupQrcode(bookId, channelId, adviserId);
            if (groupQrcodeVO == null) {
                throw new BookBizException(BookBizException.ERROR, "二维码生成失败！");
            }
            if (null != bookGroupId) {
                BookGroup group = new BookGroup();
                group.setId(bookGroupId);
                group.setSceneId(groupQrcodeVO.getSceneId());
                bookGroupDao.update(group);
            }
            return groupQrcodeVO.getSceneId();
        }
        return null;
    }

    @Override
    public ResourcePageVO getResourcePageByBookGroupIdOrSceneId(Long bookGroupId, Long adviserId, Long sceneId) {
        if (null == bookGroupId && null == sceneId) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数缺失");
        }
        ResourcePageVO resourcePageVO = new ResourcePageVO();
        Long bookId = null;
        if (null != bookGroupId) {
            bookId = resourcePageDao.getBookIdByBookGroupId(bookGroupId);
        } else if (null != sceneId) {
            bookId =  resourcePageDao.getBookIdBySceneId(sceneId);
        }
        //上邮临时处理方案
        if (null != bookId && null != JedisClusterUtils.hget(nftReleaseLockKey, bookId.toString())) {
            if (null != bookGroupId) {
                bookGroupId = JedisClusterUtils.hgetJson2Class(nftReleaseLockKey, bookId.toString(), NftBookState.class).getNftBookGroupId();
            } else if (null != sceneId) {
                sceneId = JedisClusterUtils.hgetJson2Class(nftReleaseLockKey, bookId.toString(), NftBookState.class).getNftSceneId();;
            }
        }
        if (null != bookGroupId) {
            ResourcePage resourcePage = resourcePageDao.getByBookGroupId(bookGroupId);
            if (null == resourcePage) {
                resourcePage = this.createDefaultResourcePage(bookGroupId, adviserId, null, 0, null);
            }
            BeanUtils.copyProperties(resourcePage, resourcePageVO);
            BookGroupDTO bookGroupDTO = bookGroupBiz.getBookInfo(bookGroupId);
            if (null != bookGroupDTO) {
                resourcePageVO.setBookImg(bookGroupDTO.getBookImg());
                resourcePageVO.setBookName(bookGroupDTO.getBookName());
                resourcePageVO.setBookCover(bookGroupDTO.getBookImg());
            }
            BookGroupDTO dto = bookGroupDao.getDTOById(bookGroupId);
            if (null != dto) {
                resourcePageVO.setBookId(dto.getBookId());
                resourcePageVO.setAdviserId(dto.getCreateUser());
                resourcePageVO.setChannelId(dto.getChannelId());
                //预览码放原有的二维码
                resourcePageVO.setQrcodeUrl(dto.getGroupQrcodeUrl());
                resourcePageVO.setQrcodeLink(dto.getGroupQrcodeLink());
            }
            IMaskFlag.Helper helper = IMaskFlag.Helper.of(resourcePage.getSwitchConfig());
            resourcePageVO.setShowSelf(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_SELF));
            resourcePageVO.setShowCollect(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_COLLECT));
            resourcePageVO.setShowShare(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_SHARE));
            resourcePageVO.setNewEditor(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.NEW_EDITOR));
        } else {
            ResourcePage resourcePage = resourcePageDao.getBySceneId(sceneId);
            if (null == resourcePage) {
                resourcePage = this.createDefaultResourcePage(null, adviserId, sceneId, 0, null);
            }
            BeanUtils.copyProperties(resourcePage, resourcePageVO);
            resourcePageVO.setBookId(resourcePage.getBookId());
            resourcePageVO.setAdviserId(resourcePage.getCreateUser());
            resourcePageVO.setChannelId(resourcePage.getChannelId());
            BookDto bookDto = bookBiz.getBaseById(resourcePage.getBookId());
            resourcePageVO.setBookImg(bookDto.getCoverImg());
            resourcePageVO.setBookCover(bookDto.getCoverImg());
            resourcePageVO.setBookName(bookDto.getBookName());
            QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getById(sceneId);
            //预览取原有二维码
            resourcePageVO.setQrcodeUrl(qrcodeSceneDto.getQrcodeUrl());
            resourcePageVO.setQrcodeLink(qrcodeSceneDto.getUrl());
            IMaskFlag.Helper helper = IMaskFlag.Helper.of(resourcePage.getSwitchConfig());
            resourcePageVO.setShowSelf(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_SELF));
            resourcePageVO.setShowCollect(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_COLLECT));
            resourcePageVO.setShowShare(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_SHARE));
            resourcePageVO.setNewEditor(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.NEW_EDITOR));
        }
        Map<Long, AdviserBaseInfoDto> agentMap = adviserConsr.getAdviserId2AdviserInfoDtoMap(Arrays.asList(adviserId));
        if (!MapUtils.isEmpty(agentMap)) {
            resourcePageVO.setAgentName(agentMap.get(adviserId).getAgentName());
        }
        // 加载实体书购买
        this.fillBookStore(resourcePageVO);
        // 加载固定项
        this.fillFixture(resourcePageVO);
        //加载导航
        this.fillNavigation(resourcePageVO, null);
        //加载图书标准服务
        this.fillResourcePageModel(resourcePageVO, null);
        // 加载营销活动
        fillResourcePageMarketingActivity(resourcePageVO,null);
        return resourcePageVO;
    }

    private void fillResourcePageMarketingActivity(ResourcePageVO resourcePageVO,Long wechatUserId) {
        List<ResourcePageMarketingActivityVO> activities = resourcePageMarketingActivityMapper.listByResourcePageId(resourcePageVO.getId());
        if (activities.isEmpty()) {
            return;
        }

        if (StringUtils.equals(activities.get(0).getServeType(), ResourcePageFixtureTypeEnum.COUPONS.name())) {
            fillCoupon(activities, wechatUserId);
        }else if (StringUtils.equals(activities.get(0).getServeType(), ServeTypeEnum.APP.getValue())) {
            fillAppProductServe(activities, wechatUserId);
        }
        resourcePageVO.setResourcePageMarketingActivityList(activities);
    }

    private void fillCoupon(List<ResourcePageMarketingActivityVO> resourcePageMarketingActivities, Long wechatUserId) {
        List<Long> couponIds = resourcePageMarketingActivities.stream().map(ResourcePageMarketingActivityVO::getServeId).collect(Collectors.toList());
        Map<Long, CouponsNewDto> couponsNewMap = promotionConsr.mapByCouponIds(couponIds, wechatUserId);
        for (int i = resourcePageMarketingActivities.size() - 1; i >= 0; i--) {
            ResourcePageMarketingActivityVO vo = resourcePageMarketingActivities.get(i);
            CouponsNewDto couponsNewDto = couponsNewMap.get(vo.getServeId());
            if (couponsNewDto.getState() == -1) {
                resourcePageMarketingActivities.remove(vo);
            }
            vo.setCouponsNewDto(couponsNewDto);
        }
    }

    @ParamLog("加载图书标准服务")
    private void fillResourcePageModel(ResourcePageVO resourcePageVO,  Long wechatUserId) {
        resourcePageVO.setResourcePageModelList(new ArrayList<>());
        if (null == resourcePageVO || null == resourcePageVO.getId()) {
            return;
        }
        List<ResourcePageModel> modelList = resourcePageModelDao.getByPaegId(resourcePageVO.getId());
        if (ListUtils.isEmpty(modelList)) {
            return;
        }
        List<String> serveTypes = Arrays.asList(ResourcePageConstants.ServeTypeEnum.APP.getValue(), ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue());
        List<Long> serveIds = modelList.stream().filter(x -> serveTypes.contains(x.getServeType()) && x.getServeId() != null
                && x.getServeId()>0).map(x -> x.getServeId()).collect(Collectors.toList());
        // 对象转换查跳转链接
        Map<String, List<ResourcePageItemVO>> itemVOMap = new HashMap<>();
        if(CollUtil.isNotEmpty(serveIds)){
            List<ResourcePageItemVO> list = CollUtil.toList();
            for (ResourcePageModel model : modelList) {
                if(!serveTypes.contains(model.getServeType()) || null == model.getServeId() || model.getServeId() <= 0){
                    continue;
                }
                ResourcePageItemVO itemVO = new ResourcePageItemVO();
                itemVO.setServeId(model.getServeId());
                itemVO.setServeType(model.getServeType());
                itemVO.setLinkUrl(model.getLinkUrl());
                itemVO.setTypeCode(model.getTypeCode());
                itemVO.setCreateUser(model.getCreateUser());
                list.add(itemVO);
            }
            // 填充应用跳转信息
            this.fillAppProductServe(list, wechatUserId);
            itemVOMap = list.stream().collect(Collectors.groupingBy(x -> String.join("-",x.getServeId().toString(),x.getServeType())));
        }
        // 填充参数
        for (ResourcePageModel model : modelList) {
            String key = null==model.getServeId()?"0":String.join("-",model.getServeId().toString(),model.getServeType());
            if(!MapUtils.isEmpty(itemVOMap) && itemVOMap.containsKey(key)){
                ResourcePageItemVO itemVO = itemVOMap.get(key).get(0);
                model.setTypeCode(itemVO.getTypeCode());
                model.setTypeName(itemVO.getTypeName());
                model.setHasThirdLink(itemVO.getHasThirdLink());
                model.setHasOfficialAccountsTool(itemVO.getHasOfficialAccountsTool());
                model.setResultUrl(itemVO.getResultUrl());
                model.setServeName(itemVO.getServeName());
                model.setServePic(itemVO.getServePic());
            } else {
                model.setHasThirdLink(true);
                model.setHasOfficialAccountsTool(false);
                model.setResultUrl(model.getLinkUrl());
            }
        }
        resourcePageVO.setResourcePageModelList(modelList);
    }

    /**
     * 加载导航
     */
    private void fillNavigation(ResourcePageVO resourcePageVO, Long wechatUserId) {
        if(resourcePageVO == null || resourcePageVO.getId() == null){
            return;
        }
        Long resourcePageId = resourcePageVO.getId();
        //进本书服务页 查导航
        if (PageLandingPageTypeEnum.RESOURCE.getCode().equals(resourcePageVO.getLandingPageType()) || PageLandingPageTypeEnum.SINGLE_RESOURCE.getCode().equals(resourcePageVO.getLandingPageType())) {
            List<ResourcePageNavigation> navigations = resourcePageNavigationDao.getByPageId(resourcePageId);
            if (ListUtils.isEmpty(navigations)) {
                this.addDefaultBookServeNavigation(resourcePageId);
                navigations = resourcePageNavigationDao.getByPageId(resourcePageId);
            }
            //pc端数据展示，客户端功能跳转
            if (null == wechatUserId || ResourcePageConstants.NavigationJumpType.FUNCTION.getCode().equals(resourcePageVO.getNavigationJumpType())) {
                // 加载跳转数据
                this.fillCustomServe(navigations, wechatUserId);
            }
            resourcePageVO.setNavigationList(navigations);
        }
    }

    /**
     * 加载菜单跳转应用数据
     */
    private void fillCustomServe(List<ResourcePageNavigation> navigations, Long wechatUserId) {
        if(CollUtil.isEmpty(navigations)){
            return;
        }
        List<Long> appIds = navigations.stream().filter(x -> ObjectUtil.equal(ResourcePageConstants.NavigationTypeEnum.CUSTOM_SERVE.getCode(), x.getNavigationType()) && ObjectUtil.equal("APP", x.getServeType())).map(x -> x.getServeId()).collect(Collectors.toList());
        if(CollUtil.isEmpty(appIds)){
            return;
        }
        // 对象转换
        List<ResourcePageItemVO> list = CollUtil.toList();
        for (ResourcePageNavigation navigation : navigations) {
            if(ObjectUtil.notEqual(ResourcePageConstants.NavigationTypeEnum.CUSTOM_SERVE.getCode(), navigation.getNavigationType())
                    || ObjectUtil.notEqual("APP", navigation.getServeType())){
                continue;
            }
            ResourcePageItemVO itemVO = new ResourcePageItemVO();
            itemVO.setServeId(navigation.getServeId());
            itemVO.setServeType(navigation.getServeType());
            itemVO.setLinkUrl(navigation.getLinkUrl());
            itemVO.setTypeCode(navigation.getTypeCode());
            itemVO.setCreateUser(navigation.getCreateUser());
            list.add(itemVO);
        }
        // 填充应用跳转信息
        this.fillAppProductServe(list, wechatUserId);
        Map<Long, ResourcePageItemVO> itemVOMap = list.stream().collect(Collectors.toMap(x -> x.getServeId(), Function.identity(), (v1, v2) -> v1));
        // 填充参数
        for (ResourcePageNavigation navigation : navigations) {
            if(ObjectUtil.notEqual(ResourcePageConstants.NavigationTypeEnum.CUSTOM_SERVE.getCode(), navigation.getNavigationType())
                    || ObjectUtil.notEqual("APP", navigation.getServeType()) || !itemVOMap.containsKey(navigation.getServeId())){
                continue;
            }
            ResourcePageItemVO itemVO = itemVOMap.get(navigation.getServeId());
            navigation.setServeName(itemVO.getServeName());
            navigation.setServePic(itemVO.getServePic());
            navigation.setTypeCode(itemVO.getTypeCode());
            navigation.setTypeName(itemVO.getTypeName());
            navigation.setHasThirdLink(itemVO.getHasThirdLink());
            navigation.setHasOfficialAccountsTool(itemVO.getHasOfficialAccountsTool());
            navigation.setResultUrl(itemVO.getResultUrl());
        }
    }

    /**
     * 加载实体书购买
     */
    private void fillBookStore(ResourcePageVO resourcePageVO) {
        if(resourcePageVO == null || resourcePageVO.getId() == null){
            return;
        }
        List<ResourcePageBookstoreVO> resourcePageBookstoreList = resourcePageBookstoreBiz.getByResourcePageId(resourcePageVO.getId(), resourcePageVO.getChannelId(), null, ResourcePageFixtureTypeEnum.BOOKSTORE);
        resourcePageVO.setResourcePageBookstoreList(resourcePageBookstoreList);
    }

    /**
     * 加载固定项
     */
    private void fillFixture(ResourcePageVO resourcePageVO) {
        if(resourcePageVO == null || resourcePageVO.getId() == null){
            return;
        }
        List<ResourcePageBookstoreVO> resourcePageBookstoreList = resourcePageBookstoreBiz.getByResourcePageId(resourcePageVO.getId(), resourcePageVO.getChannelId(), null, ResourcePageFixtureTypeEnum.COUPONS);
        resourcePageVO.setResourcePageCouponList(resourcePageBookstoreList);
    }

    @Override
    public List<ResourceColumnAndServeVO> getColumnAndServeListByPageId(Long resourcePageId, Long wechatUserId, Long bookId, Long adviserId, Long channelId, Integer enableAdverting, Long navigationId) {
        List<ResourceColumnAndServeVO> serveVOS = resourcePageColumnDao.getColumnListByPageId(resourcePageId, navigationId,null);
        if (CollUtil.isNotEmpty(serveVOS)) {
            List<ResourcePageItemVO> itemVOList;
            if (null != wechatUserId) {
                itemVOList = resourcePageItemDao.getResourcePageItemByPageId(resourcePageId, true);
            } else {
                itemVOList = resourcePageItemDao.getResourcePageItemByPageId(resourcePageId, null);
            }
            if (CollUtil.isNotEmpty(itemVOList)) {
                //二维码类型
                fillQrcodeType(resourcePageId, itemVOList);
                Map<String, List<ResourcePageItemVO>> listMap = itemVOList.stream().collect(Collectors.groupingBy(ResourcePageItemVO::getServeType));
                itemVOList = new ArrayList<>();
                //应用和作品提出来一起查
                List<ResourcePageItemVO> itemAppAndProductVOList = new ArrayList<>();
                // collect resource_page_folder
                List<ResourcePageItemVO> folderResourcePageItemVOList = new ArrayList<>();
                //过滤一些资源,重新排序
                for (Map.Entry<String, List<ResourcePageItemVO>> entry : listMap.entrySet()) {
                    if(ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(entry.getKey()) || ServeTypeEnum.PRODUCT.getValue().equals(entry.getKey())){
                        itemAppAndProductVOList.addAll(entry.getValue());
                        continue;
                    }
                    if (ServeTypeEnum.FOLDER.getValue().equals(entry.getKey())){
                        folderResourcePageItemVOList.addAll(entry.getValue());
                        continue;
                    }
                    this.fillResourceByType(entry.getValue(), wechatUserId, entry.getKey());
                    itemVOList.addAll(entry.getValue());
                }
                if(CollUtil.isNotEmpty(itemAppAndProductVOList)){
                    fillAppProductServe(itemAppAndProductVOList, wechatUserId);
                    itemVOList.addAll(itemAppAndProductVOList);
                }
                if (!folderResourcePageItemVOList.isEmpty()){
                    fillResourcePageFolder(folderResourcePageItemVOList, wechatUserId);
                    itemVOList.addAll(folderResourcePageItemVOList);
                }
                itemVOList.sort(Comparator.comparing(ResourcePageItemVO::getId));

                List<ResourceColumnAndServeVO> removeColumns = setPageColumnOther(serveVOS, itemVOList);

                if (!ListUtils.isEmpty(removeColumns)) {
                    serveVOS.removeAll(removeColumns);
                }
            }
        }
        if(CollUtil.isEmpty(serveVOS)){
            serveVOS = CollUtil.toList();
        }
        // 填充广告
        this.fillAdvertising(serveVOS, bookId, adviserId, channelId, enableAdverting);
        return serveVOS;
    }

    private void fillResourcePageFolder(List<ResourcePageItemVO> folderResourcePageItemVOList, Long wechatUserId) {
        Map<Long, ResourcePageItemVO> resourcePageItemVOMap = folderResourcePageItemVOList.stream().filter(Objects::nonNull)
                .collect(Collectors.toMap(ResourcePageItemVO::getServeId, Function.identity()));
        if (CollUtil.isEmpty(resourcePageItemVOMap)) {
            return;
        }
        Map<Long, ResourcePageFolderVO> resourcePageFolderVOMap = resourcePageFolderMapper.selectByPrimaryKeys(resourcePageItemVOMap.keySet()).stream()
                .collect(Collectors.toMap(ResourcePageFolderVO::getId, Function.identity()));
        if (CollUtil.isEmpty(resourcePageItemVOMap)) {
            return;
        }

        for (ResourcePageItemVO resourcePageItemVO : folderResourcePageItemVOList) {
            resourcePageItemVO.setResourcePageFolder(resourcePageFolderVOMap.get(resourcePageItemVO.getServeId()));
        }

        Optional<Map<Long, List<ResourcePageFolderItemVO>>> resourcePageFolderItemVOMapOpt = Optional.of(resourcePageFolderItemMapper.listByFolderIds(resourcePageFolderVOMap.keySet()))
                .map(x -> x.stream().collect(Collectors.groupingBy(ResourcePageFolderItemVO::getFolderId)));
        if (!resourcePageFolderItemVOMapOpt.isPresent()) {
            return;
        }
        resourcePageFolderItemVOMapOpt.get().forEach((k, v) -> {
            ResourcePageFolderVO resourcePageFolderVO = resourcePageFolderVOMap.get(k);
            if (resourcePageFolderVO != null) {
                resourcePageFolderVO.setFolderItemList(v);
            }
        });

        // app/product和其他类型资源拆分填充
        List<ResourcePageFolderItemVO> appProductItems = new ArrayList<>();
        List<ResourcePageFolderItemVO> otherItems = new ArrayList<>();
        resourcePageFolderItemVOMapOpt.get()
                .values()
                .stream()
                .flatMap(Collection::stream)
                .forEach(x-> splitFolderItemVOS(appProductItems, otherItems, x));

        if (CollUtil.isNotEmpty(appProductItems)) {
            appProductItems.get(0).setCreateUser(folderResourcePageItemVOList.get(0).getCreateUser());
            fillAppProductServe(appProductItems, wechatUserId);
        }
        if (CollUtil.isNotEmpty(otherItems)) {
            Map<String, List<ResourcePageFolderItemVO>> folderItemMap = otherItems.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(ResourcePageFolderItemVO::getServeType));
            folderItemMap.forEach((k, v) -> fillResourceByType(v, wechatUserId, k));
        }
    }

    private static void splitFolderItemVOS(List<ResourcePageFolderItemVO> appProductItems, List<ResourcePageFolderItemVO> otherItems, ResourcePageFolderItemVO x) {
        if (StringUtils.equalsAny(x.getServeType(),ServeTypeEnum.APP.getValue(),ServeTypeEnum.PRODUCT.getValue())){
            appProductItems.add(x);
        }else {
            otherItems.add(x);
        }
    }

    private void fillAppProductResourcePageFolderItem(List<ResourcePageFolderItemVO> pageFolderItemVOS, Long wechatUserId, Long adviserId) {
        List<Long> appIds = new ArrayList<>();
        List<Long> productIds = new ArrayList<>();
        List<Long> courseProductIds = new ArrayList<>();
        List<Long> nonCourseProductIds = new ArrayList<>();
        List<Long> channelIds=new ArrayList<>();
        for (ResourcePageFolderItemVO pageFolderItemVO : pageFolderItemVOS) {
            Long serveId = pageFolderItemVO.getServeId();
            Long channelId = getChannelIdFromUrl(pageFolderItemVO.getLinkUrl());
            if(null!=channelId && !channelIds.contains(channelId)){
                channelIds.add(channelId);
            }
            if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(pageFolderItemVO.getServeType()) && !appIds.contains(serveId)) {
                appIds.add(serveId);
                continue;
            }
            if (ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(pageFolderItemVO.getServeType())) {
                if (!productIds.contains(serveId)) {
                    productIds.add(serveId);
                }
                if (courseProductTypeCodes.contains(pageFolderItemVO.getTypeCode())) {
                    courseProductIds.add(serveId);
                } else {
                    nonCourseProductIds.add(serveId);
                }
            }
        }

        // 提交应用作品信息查询任务
        CompletableFuture<Map<Long, AppDto>> queryAppTask = CompletableFuture.supplyAsync(() -> appConsr.mapBaseWithPriceByIds(appIds));
        CompletableFuture<Map<Long, ProductDto>> queryProductTask = CompletableFuture.supplyAsync(() -> productConsr.getProductBasesByIds4Book(productIds));
        // 提交用户相关信息查询任务
        CompletableFuture<Map<Long, Long>> queryAppOfficialTask = CompletableFuture.supplyAsync(() -> wechatUserId != null ? appConsr.getPayOfficialAccountsToolByAppIds(appIds) : Collections.emptyMap());
        CompletableFuture<Map<Long, AccountSettingDto>> queryOfficialTask = CompletableFuture.supplyAsync(() -> wechatUserId != null ? channelConsr.listWechatAccountInfo(channelIds) : Collections.emptyMap());
        CompletableFuture<Map<String, Boolean>> queryAppBuyTask = CompletableFuture.supplyAsync(() -> wechatUserId != null ? tradeConsr.mapAppProductBuyStateOpt(wechatUserId, appIds, nonCourseProductIds) : Collections.emptyMap());
        CompletableFuture<Map<Long, Boolean>> queryProductBuyTask = CompletableFuture.supplyAsync(() -> wechatUserId != null ? tradeConsr.mapCourseProductBuyStateOpt(wechatUserId, courseProductIds) : Collections.emptyMap());

        // 等待查询任务结果返回
        Map<Long, AppDto> appDtoMap = Try.of(() -> queryAppTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用应用中心获取应用信息错误:" + e.getMessage(), e)).getOrElse(Collections.emptyMap());
        Map<Long, ProductDto> productDtoMap = Try.of(() -> queryProductTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用资源中心获取商品信息错误:" + e.getMessage(), e)).getOrElse(Collections.emptyMap());
        Map<Long, Long> appOfficialAccountToolMap = Try.of(() -> queryAppOfficialTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用查应用关联的公众号工具的付费公众号失败:" + e.getMessage(), e)).getOrElse(Collections.emptyMap());
        Map<Long, AccountSettingDto> channelAccountSettingDtoMap = Try.of(() -> queryOfficialTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用资源中心获取商品信息错误:" + e.getMessage(), e)).getOrElse(Collections.emptyMap());
        Map<String, Boolean> buyStateMap = Try.of(() -> queryAppBuyTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用交易中心查询是否购买失败:" + e.getMessage(), e)).getOrElse(Collections.emptyMap());
        Map<Long, Boolean> courseBuyStateMap = Try.of(() -> queryProductBuyTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用交易中心查询课程是否购买错误失败:" + e.getMessage(), e)).getOrElse(Collections.emptyMap());


        // 循环填充
        Map<Long, Long> defaultChannelIdMap = new HashMap<>();
        for (ResourcePageFolderItemVO itemVO : pageFolderItemVOS) {
            Long serveId = itemVO.getServeId();
            String serveType = itemVO.getServeType();
            if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(serveType)
                    && !MapUtils.isEmpty(appDtoMap) && appDtoMap.containsKey(serveId)) {
                AppDto appDto = appDtoMap.get(itemVO.getServeId());
                itemVO.setServeName(appDto.getTitle());
                itemVO.setServePic(appDto.getSquareImg());
                itemVO.setTypeCode(appDto.getTypeCode());
                itemVO.setTypeName(appDto.getTypeName());
                itemVO.setTransverseImg(appDto.getTransverseImg());
                //这两个价格不统一，不确定取哪个字段
                Double price = null == appDto.getPrice() ? 0d : appDto.getPrice();
                if (price.equals(0d)) {
                    price = null == appDto.getRetailPrice() ? 0d : appDto.getRetailPrice().doubleValue();
                }
                itemVO.setPrice(price);
                itemVO.setHasThirdLink(StringUtil.isNotEmpty(appDto.getTurnUrl()));
                //标记应用共享状态
                itemVO.setAppCreateUser(appDto.getCreatedUser());
                itemVO.setShareState(appDto.getShareState());
            } else if (ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(serveType)
                    && !MapUtils.isEmpty(productDtoMap) && productDtoMap.containsKey(serveId)) {
                ProductDto productDto = productDtoMap.get(itemVO.getServeId());
                itemVO.setServeName(productDto.getProductName());
                itemVO.setServePic(productDto.getCoverImg());
                if (productDto.getProductTypeDto() != null) {
                    itemVO.setTypeCode(productDto.getProductTypeDto().getTypeCode());
                    itemVO.setTypeName(productDto.getProductTypeDto().getTypeName());
                }
                if (!ListUtils.isEmpty(productDto.getSpecification())) {
                    itemVO.setPrice(productDto.getSpecification().get(0).getAdvisePrice());
                }
                itemVO.setTransverseImg(StringUtil.isEmpty(productDto.getPicture1())?
                        getDefaultBigPic(itemVO.getTypeCode()): productDto.getPicture1());
                itemVO.setHasThirdLink(StringUtil.isNotEmpty(productDto.getSkipUrl()));
            } else {
                continue;
            }
            if (null == itemVO.getPrice()) {
                itemVO.setPrice(0d);
            }
            Long channelId = getChannelIdFromUrl(itemVO.getLinkUrl());
            if (null == channelId) {
                log.info(itemVO.getServeName() + "无运营平台, serveId=" + itemVO.getServeId());
                if(defaultChannelIdMap.containsKey(adviserId)){
                    channelId = defaultChannelIdMap.get(adviserId);
                    if(null!=channelId){
                        channelId = adviserConsr.getDefaultChannel(adviserId);
                    }
                }else {
                    channelId = adviserConsr.getDefaultChannel(adviserId);
                    if (null != channelId) {
                        defaultChannelIdMap.put(adviserId, channelId);
                    }
                }
            }
            itemVO.setChannelId(channelId);
            setResourceFolderItemLink4Wechat(itemVO, channelAccountSettingDtoMap, appOfficialAccountToolMap, Collections.emptyMap());
            if (null != wechatUserId) {
                itemVO.setBuyState(false);
                if (!MapUtils.isEmpty(buyStateMap)) {
                    if(ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(serveType)){
                        String key="PRODUCT"+serveId;
                        if(buyStateMap.containsKey(key)){
                            itemVO.setBuyState(buyStateMap.get(key));
                        }
                    }else if(ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(serveType)){
                        String key="APP"+serveId;
                        if(buyStateMap.containsKey(key)){
                            itemVO.setBuyState(buyStateMap.get(key));
                        }
                    }
                }
                if (!MapUtils.isEmpty(courseBuyStateMap) && courseBuyStateMap.containsKey(serveId)
                        && ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(itemVO.getServeType())) {
                    itemVO.setBuyState(courseBuyStateMap.get(serveId));
                }
            }
        }
    }

    private void setResourceFolderItemLink4Wechat(ResourcePageFolderItemVO itemVO, Map<Long, AccountSettingDto> channelAccountSettingDtoMap,
                                                  Map<Long, Long> appOfficialAccountToolMap, Map<Long, AccountSetting> accountSettingMap) {
        if (itemVO.getLinkUrl().startsWith("http")) {
            itemVO.setResultUrl(itemVO.getLinkUrl());
            return;
        }
        AccountSettingDto accountSettingDto = new AccountSettingDto();
        //有应用配了付费公众号工具,取公众号工具的公众号域名， 没有就根据渠道id取
        if (!MapUtils.isEmpty(appOfficialAccountToolMap) && appOfficialAccountToolMap.containsKey(itemVO.getServeId())) {
            Long accountSettingId = appOfficialAccountToolMap.get(itemVO.getServeId());
            AccountSetting accountSetting = accountSettingMap.get(accountSettingId);
            if (null == accountSetting) {
                accountSetting = qrcodeSceneConsr.getAppInfo(accountSettingId);
                accountSettingMap.put(accountSettingId, accountSetting);
            }
            BeanUtils.copyProperties(accountSetting, accountSettingDto);
            itemVO.setHasOfficialAccountsTool(true);

        } else {
            Long channelId = itemVO.getChannelId();
            accountSettingDto = channelAccountSettingDtoMap.get(channelId);
            if (accountSettingDto == null) {
                accountSettingDto = qrcodeSceneConsr.getWechatInfo(channelId);
                channelAccountSettingDtoMap.put(channelId, accountSettingDto);
            }
            itemVO.setHasOfficialAccountsTool(false);
        }
        if (null == accountSettingDto) {
            throw new BookBizException(BookBizException.ERROR, itemVO.getServeName() + "未设置公众号");
        }
        String resultLinkUrl = SendWeixinRequestTools.splitUrl(accountSettingDto, itemVO.getLinkUrl());
        itemVO.setResultUrl(resultLinkUrl);
    }

    /**
     * 二维码类型
     */
    private void fillQrcodeType(Long resourcePageId, List<ResourcePageItemVO> itemVOList) {
        String qrcodeType = "";
        ResourcePage resourcePage = resourcePageDao.getById(resourcePageId);
        if (null == resourcePage || ListUtils.isEmpty(itemVOList)) {
           return;
        }
        Integer jumpType = null;
        if (null != resourcePage.getBookGroupId()) {
            qrcodeType = "own";
            BookGroupDTO bookGroupDTO = bookGroupDao.getDTOById(resourcePage.getBookGroupId());
            jumpType = null == bookGroupDTO? null:bookGroupDTO.getJumpType();
        } else if (null != resourcePage.getSceneId()) {
            QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getById(resourcePage.getSceneId());
            qrcodeType = null == qrcodeSceneDto?"ali":qrcodeSceneDto.getQrcodeType();
        }
        for (ResourcePageItemVO itemVO:itemVOList) {
            itemVO.setQrcodeType(qrcodeType);
            itemVO.setJumpType(jumpType);
        }
    }
    /**
     * 填充广告
     */
    private void fillAdvertising(List<ResourceColumnAndServeVO> serveVOS, Long bookId, Long adviserId, Long channelId, Integer enableAdverting) {
        if(serveVOS == null || bookId == null || adviserId == null || channelId == null || !YesOrNoEnums.YES.getValue().equals(enableAdverting)){
            return;
        }
        try {
            List<AdvertisingSpaceDTO> h5Advertising = advertisingConsr.getH5Advertising(bookId, adviserId, channelId);
            if(CollUtil.isEmpty(h5Advertising)){
                return;
            }
            for (AdvertisingSpaceDTO adDto : h5Advertising) {
                List<AdvertisingSpaceItemDTO> itemList = adDto.getAdvertisingSpaceItemList();
                if(CollUtil.isEmpty(itemList)){
                    continue;
                }
                ResourceColumnAndServeVO serveVO = new ResourceColumnAndServeVO();
                serveVO.setIsAdvertising(true);
                serveVO.setColumnFormat(2); // 宽图
                serveVO.setColumnSeq(0);
                serveVO.setShowMore(YesNoEnums.NO.code);
                serveVO.setThemeStyle(adDto.getThemeStyle());
                serveVO.setAdPosition(adDto.getAdPosition());
                serveVO.setMasterId(adDto.getMasterId());
                serveVO.setAdvertisingSpaceId(adDto.getId());
                serveVO.setAdvertisingItemList(itemList);
                AdvertisingSpaceItemDTO item = itemList.get(0);
                if("H5_SERVE_RESOURCE".equalsIgnoreCase(adDto.getAdPosition())){
                    serveVO.setColumnName(item.getColumnTitle());
                    serveVO.setColumnMarker(item.getColumnMarker());
                    serveVO.setColumnSeq(getColumnSeq(item.getColumnSeq()));
                } else {
                    serveVO.setColumnName(item.getAdTitle());
                }
                serveVOS.add(serveVO);
            }
        }  catch (Exception e){
            log.error("[fillAdvertising] H5 填充广告失败，err：{}", e.getMessage(), e);
        }
    }

    private Integer getColumnSeq(Integer columnSeq) {
        if(columnSeq == null){
            return 0;
        }
        if(columnSeq == -1){
            return 9999;
        }
        return columnSeq;
    }

    @ParamLog("按类型填充资源")
    private void fillResourceByType(List<? extends ResourcePageItemVO> itemVOS, Long wechatUserId, String serveType) {
        if (ListUtils.isEmpty(itemVOS)) {
            return;
        }
        if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(serveType)) {
            fillAppProductServe(itemVOS, wechatUserId);
        } else if (ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(serveType)) {
            fillAppProductServe(itemVOS, wechatUserId);
        } else if (ResourcePageConstants.ServeTypeEnum.OFFICIAL_ACCOUNT.getValue().equals(serveType)) {
            fillOfficialAccount(itemVOS, wechatUserId);
        } else if (ResourcePageConstants.ServeTypeEnum.BOOKLIST.getValue().equals(serveType)) {
            fillBooklistServe(itemVOS);
        } else if (ResourcePageConstants.ServeTypeEnum.ADVISER_BOOK.getValue().equals(serveType)) {
            fillAdviserBook(itemVOS);
        } else if (ResourcePageConstants.ServeTypeEnum.GROUP_ACTIVITY.getValue().equals(serveType)) {
            fillGroupServe(itemVOS);
        } else if (ResourcePageConstants.ServeTypeEnum.THIRD_RESOURCE.getValue().equals(serveType)) {
            fillThirdResource(itemVOS);
        } else if (ResourcePageConstants.ServeTypeEnum.WXWORK_GROUP.getValue().equals(serveType)) {
            fillWxworkGroup(itemVOS);
        } else if (ResourcePageConstants.ServeTypeEnum.MEMBER_ACTIVITY.getValue().equals(serveType)) {
            fillMemberActivity(itemVOS, wechatUserId);
        } else if (ServeTypeEnum.SHOP.getValue().equals(serveType)) {
            fillChannelShop(itemVOS);
        } else if (ServeTypeEnum.RESOURCE.getValue().equals(serveType)) {
            fillFileResource(itemVOS, wechatUserId);
        }
    }

    @ParamLog("填充文件素材")
    private void fillFileResource(List<? extends ResourcePageItemVO> itemVOS, Long wechatUserId) {
        log.info("填充文件素材");
        if (ListUtils.isEmpty(itemVOS)) {
            return;
        }
        List<Long> serveIds = itemVOS.stream().filter(s->ServeTypeEnum.RESOURCE.getValue().equals(s.getServeType())).map(ResourcePageItemVO::getServeId).distinct().collect(Collectors.toList());
        Map<Long, ResourceDTO> resourceDTOMap = resourceConsr.mapResourceByIds(serveIds, false, false);
        if (MapUtils.isEmpty(resourceDTOMap)) {
            return;
        }
        Long channelId = null;
        if (null != itemVOS.get(0).getResourcePageId()) {
            ResourcePage resourcePage = resourcePageDao.getById(itemVOS.get(0).getResourcePageId());
            channelId = resourcePage.getChannelId();
        }
        if (null == channelId) {
            channelId = getChannelIdFromUrl(itemVOS.get(0).getLinkUrl());
        }
        if (null == channelId){
            channelId = adviserConsr.getDefaultChannel(itemVOS.get(0).getCreateUser());
        }
        AccountSettingDto accountSettingDto = new AccountSettingDto();
        if (null != wechatUserId) {
            accountSettingDto = qrcodeSceneConsr.getWechatInfo(channelId);
        }
        for (ResourcePageItemVO itemVO : itemVOS) {
            if (!ServeTypeEnum.RESOURCE.getValue().equals(itemVO.getServeType())) {
                continue;
            }
            ResourceDTO resourceDTO = resourceDTOMap.get(itemVO.getServeId());
            itemVO.setTypeName("素材");
            if (null != resourceDTO) {
                itemVO.setServeName(resourceDTO.getResourceName());
            }
            itemVO.setChannelId(channelId);
            setFileResourceDefaultPic(itemVO);
            if (null != wechatUserId) {
                String resultLinkUrl = itemVO.getLinkUrl();
                if (!itemVO.getLinkUrl().startsWith("http")) {
                    resultLinkUrl = SendWeixinRequestTools.splitUrl(accountSettingDto, itemVO.getLinkUrl());
                }
                itemVO.setResultUrl(resultLinkUrl);
            }
        }
    }

    private void setFileResourceDefaultPic(ResourcePageItemVO itemVO) {
        if (null == itemVO || null == itemVO.getTypeCode()) {
            return;
        }
        if ("AUDIO".equals(itemVO.getTypeCode())) {
            itemVO.setServePic("https://oss.5rs.me/oss/uploadfe/png/bf415da05f8ba18c15fb750bea77e307.png");
            itemVO.setTransverseImg("https://oss.5rs.me/oss/uploadfe/png/db6407cdb660b9f082da8155ae2e0599.png");
        } else if ("VIDEO".equals(itemVO.getTypeCode())) {
            itemVO.setServePic("https://oss.5rs.me/oss/uploadfe/png/b957f4c0b3901fff7a698a8b9af7793d.png");
            itemVO.setTransverseImg("https://oss.5rs.me/oss/uploadfe/png/5e05173b3e0605d225f0b2b7482143d4.png");
        } else {
            itemVO.setServePic("https://oss.5rs.me/oss/uploadfe/png/b4cf9c2aadf4b851bc96db5a30e85b13.png");
            itemVO.setTransverseImg("https://oss.5rs.me/oss/uploadfe/png/bab7de5ca544b0dede6c8b3ea150e97b.png");
        }
    }

    @ParamLog("填充运营商城")
    private void fillChannelShop(List<? extends ResourcePageItemVO> itemVOS) {
        log.info("填充运营商城");
        if (ListUtils.isEmpty(itemVOS)) {
            return;
        }
        List<Long> serveIds = itemVOS.stream().map(ResourcePageItemVO::getServeId).distinct().collect(Collectors.toList());
        Map<Long, SinglePageInfoDTO> singlePageDTOMap = productConsr.mapSinglePageByIds(serveIds);
        if (MapUtils.isEmpty(singlePageDTOMap)) {
            return;
        }
        for (ResourcePageItemVO itemVO : itemVOS) {
            SinglePageInfoDTO singlePageDTO = singlePageDTOMap.get(itemVO.getServeId());
            itemVO.setTypeName("运营商城");
            if (null != singlePageDTO) {
                itemVO.setServeName(singlePageDTO.getSinglePageName());
                itemVO.setServePic(singlePageDTO.getHeadUrl());
                itemVO.setTransverseImg(singlePageDTO.getImgUrl());
            }
            itemVO.setResultUrl(itemVO.getLinkUrl());
        }
    }

    @ParamLog("填充平台会员活动")
    private void fillMemberActivity(List<? extends ResourcePageItemVO> itemVOS, Long wechatUserId) {
        log.info("填充平台会员活动");
        if (ListUtils.isEmpty(itemVOS)) {
            return;
        }
        List<Long> serveIds = itemVOS.stream().map(ResourcePageItemVO::getServeId).distinct().collect(Collectors.toList());
        Map<Long, ActivityBaseInfoWithPriceDTO> baseInfoDTOMap = memberActivityConsr.mapMemberActivityByUser(serveIds,wechatUserId);
        if (MapUtils.isEmpty(baseInfoDTOMap)) {
            return;
        }
        for (ResourcePageItemVO itemVO : itemVOS) {
            ActivityBaseInfoWithPriceDTO baseInfoDTO = baseInfoDTOMap.get(itemVO.getServeId());
            itemVO.setTypeName("平台会员活动");
            itemVO.setActivityBaseInfo(baseInfoDTO);
            if (null != baseInfoDTO) {
                itemVO.setServeName(baseInfoDTO.getTitle());
                itemVO.setServePic(baseInfoDTO.getSquareImg());
                itemVO.setRemark(baseInfoDTO.getRemark());
                itemVO.setTransverseImg(baseInfoDTO.getTransverseImg());
                itemVO.setPrice(baseInfoDTO.getMarketPrice().doubleValue());
            }
        }
    }

    @ParamLog("填充企业微信群")
    private void fillWxworkGroup(List<? extends ResourcePageItemVO> itemVOS) {
        log.info("填充企业微信群");
        if (ListUtils.isEmpty(itemVOS)) {
            return;
        }
        List<Long> serveIds = itemVOS.stream().map(ResourcePageItemVO::getServeId).distinct().collect(Collectors.toList());
        Map<Long, WxworkGroupQrcodeBaseDTO> groupDtoMap = wechatGroupConsr.mapWxworkGroupQrcode(serveIds);
        List<ResourcePageItemVO> removeList = new ArrayList<>();
        for (ResourcePageItemVO itemVO : itemVOS) {
            if (MapUtils.isEmpty(groupDtoMap) || !groupDtoMap.containsKey(itemVO.getServeId())) {
                removeList.add(itemVO);
                continue;
            }
            WxworkGroupQrcodeBaseDTO wxworkGroupQrcodeBaseDTO = groupDtoMap.get(itemVO.getServeId());
            if (null == wxworkGroupQrcodeBaseDTO) {
                continue;
            }
            BookQrcodeWxworkResponseVO responseVO = new BookQrcodeWxworkResponseVO();
            responseVO.setWxworkQrcodeId(itemVO.getServeId());
            responseVO.setWxworkQrcodeType(WxworkQrcodeType.GROUP_QRCODE.getCode());
            responseVO.setWxworkQrcodeName(wxworkGroupQrcodeBaseDTO.getGroupQrcodeName());
            responseVO.setInvitationRays(wxworkGroupQrcodeBaseDTO.getInvitationRays());
            responseVO.setWxworkQrcodeUrl(wxworkGroupQrcodeBaseDTO.getGroupQrcodeUrl());
            responseVO.setGroupName(wxworkGroupQrcodeBaseDTO.getGroupQrcodeName());
            responseVO.setGroupDesc(wxworkGroupQrcodeBaseDTO.getInvitationRays());
            responseVO.setUrl(wxworkGroupQrcodeBaseDTO.getUrl());
            responseVO.setClassifyName(wxworkGroupQrcodeBaseDTO.getClassifyName());
            //头像列表从缓存里取
            List<String> headUrlList = appletGroupSearchRecordBiz.getHeadUrlList(9, itemVO.getServeId());
            responseVO.setHeadUrlList(headUrlList);
            List<AppletGroupStatementDTO> statementDTOList = appletGroupSearchRecordBiz
                    .getStatementList(9, headUrlList, itemVO.getServeId());
            responseVO.setStatementDTOList(statementDTOList);

            itemVO.setTypeName("社群");
            itemVO.setBookQrcodeWxworkResponseVO(responseVO);
        }
        itemVOS.removeAll(removeList);
    }

    @ParamLog("填充第三方资源")
    private void fillThirdResource(List<? extends ResourcePageItemVO> itemVOS) {
        log.info("填充第三方资源");
        if (ListUtils.isEmpty(itemVOS)) {
            return;
        }
        List<Long> serveIds = itemVOS.stream().map(ResourcePageItemVO::getServeId).distinct().collect(Collectors.toList());
        Map<Long, AppletThirdResources> resourcesMap = appletThirdResourcesBiz.getAppletMapByIds(serveIds);
        if (MapUtils.isEmpty(resourcesMap)) {
            return;
        }
        for (ResourcePageItemVO itemVO : itemVOS) {
            AppletThirdResources resources = resourcesMap.get(itemVO.getServeId());
            if (null != resources) {
                itemVO.setTypeName("第三方资源");
                itemVO.setAppletThirdResources(resources);
            }
        }
    }

    @ParamLog("填充编辑书刊链接")
    private void fillAdviserBook(List<? extends ResourcePageItemVO> itemVOS) {
        log.info("填充编辑书刊链接");
        if (ListUtils.isEmpty(itemVOS)) {
            return;
        }
        Long adviserId = itemVOS.get(0).getCreateUser();
        List<Long> serveIds = itemVOS.stream().map(ResourcePageItemVO::getServeId).distinct().collect(Collectors.toList());
        Map<Long, BookLinkVO> bookLinkMap = bookBiz.getBookLinkMap(adviserId, serveIds);
        if (MapUtils.isEmpty(bookLinkMap)) {
            return;
        }
        for (ResourcePageItemVO itemVO : itemVOS) {
            BookLinkVO bookLinkVO = bookLinkMap.get(itemVO.getServeId());
            if (null != bookLinkVO) {
                itemVO.setTypeName("编辑书刊");
                itemVO.setBookName(bookLinkVO.getBookName());
                itemVO.setLinkFrom(bookLinkVO.getLinkFrom());
                itemVO.setCoverImg(bookLinkVO.getCoverImg());
                itemVO.setIsbn(bookLinkVO.getIsbn());
                itemVO.setUniqueNumber(bookLinkVO.getUniqueNumber());
                itemVO.setPublish(bookLinkVO.getPublish());
            }
        }
    }

    @ParamLog("填充公众号二维码")
    private void fillOfficialAccount(List<? extends ResourcePageItemVO> itemVOS, Long wechatUserId) {
        log.info("填充公众号二维码");
        if (ListUtils.isEmpty(itemVOS)) {
            return;
        }
        List<ResourcePageItemVO> removeList = new ArrayList<>();
        for (ResourcePageItemVO itemVO : itemVOS) {
            itemVO.setTypeName("公众号");
            if (ResourcePageConstants.QrcodeShowTypeEnum.TILED.getCode().equals(itemVO.getQrcodeShowType())) {
                //平铺方式
                itemVO.setResultUrl(itemVO.getLinkUrl());
                //原始二维码
                if(ResourcePageConstants.QrcodeSourceEnum.OFFICIAL_ACCOUNT.value.equals(itemVO.getQrcodeSource())){
                    QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getOnlySceneInfoById(itemVO.getServeId());
                    itemVO.setLinkUrl(qrcodeSceneDto.getQrcodeUrl());
                }
            } else {
                //弹窗方式,在客户端栏目中不展示
                if (null != wechatUserId) {
                    removeList.add(itemVO);
                    continue;
                }
                Long accountSettingId = itemVO.getAccountSettingId();
                if (null == accountSettingId) {
                    accountSettingId = BookProps.getOperateOfficalId();
                    itemVO.setAccountSettingId(accountSettingId);
                }
                AccountSetting accountSetting = qrcodeSceneConsr.getAppInfo(accountSettingId);
                itemVO.setAccountSettingName(null == accountSetting?null:accountSetting.getBaseAppName());
                if (BookProps.getOperateOfficalId().equals(accountSettingId)) {
                    itemVO.setLinkUrl(accountSetting.getQrcodeUrl());
                }
            }
        }
        if (!ListUtils.isEmpty(removeList)) {
            itemVOS.removeAll(removeList);
        }
    }

    private final static List<String> courseProductTypeCodes = Arrays.asList("VIDEO_SCHEDULE", "VIDEO_COURSE", "AUDIO_COURSE", "AUDIO_SCHEDULE", "LIVE");

    private void fillAppProductServe(List<? extends ResourcePageItemVO> itemVOS, Long wechatUserId) {
        log.info("填充应用作品");
        Long adviserId = itemVOS.get(0).getCreateUser();
        List<Long> appIds = new ArrayList<>();
        List<Long> productIds = new ArrayList<>();
        List<Long> courseProductIds = new ArrayList<>();
        List<Long> nonCourseProductIds = new ArrayList<>();
        List<Long> channelIds = new ArrayList<>();
        for (ResourcePageItemVO pageFolderItemVO : itemVOS) {
            Long serveId = pageFolderItemVO.getServeId();
            Long channelId = getChannelIdFromUrl(pageFolderItemVO.getLinkUrl());
            if (null != channelId && !channelIds.contains(channelId)) {
                channelIds.add(channelId);
            }
            if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(pageFolderItemVO.getServeType()) && !appIds.contains(serveId)) {
                appIds.add(serveId);
                continue;
            }
            if (ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(pageFolderItemVO.getServeType())) {
                if (!productIds.contains(serveId)) {
                    productIds.add(serveId);
                }
                if (courseProductTypeCodes.contains(pageFolderItemVO.getTypeCode())) {
                    courseProductIds.add(serveId);
                } else {
                    nonCourseProductIds.add(serveId);
                }
            }
        }

        // 提交应用作品信息查询任务
        CompletableFuture<Map<Long, AppDto>> queryAppTask = CompletableFuture.supplyAsync(() -> appConsr.mapBaseWithPriceByIds(appIds));
        CompletableFuture<Map<Long, ProductDto>> queryProductTask = CompletableFuture.supplyAsync(() -> productConsr.getProductBasesByIds4Book(productIds));
        // 提交用户相关信息查询任务
        CompletableFuture<Map<Long, Long>> queryAppOfficialTask = CompletableFuture.supplyAsync(() -> wechatUserId != null ? appConsr.getPayOfficialAccountsToolByAppIds(appIds) : new HashMap<>());
        CompletableFuture<Map<Long, AccountSettingDto>> queryOfficialTask = CompletableFuture.supplyAsync(() -> wechatUserId != null ? channelConsr.listWechatAccountInfo(channelIds) : new HashMap<>());
        CompletableFuture<Map<String, Boolean>> queryAppBuyTask = CompletableFuture.supplyAsync(() -> wechatUserId != null ? tradeConsr.mapAppProductBuyStateOpt(wechatUserId, appIds, nonCourseProductIds) : new HashMap<>());
        CompletableFuture<Map<Long, Boolean>> queryProductBuyTask = CompletableFuture.supplyAsync(() -> wechatUserId != null ? tradeConsr.mapCourseProductBuyStateOpt(wechatUserId, courseProductIds) : new HashMap<>());

        // 等待查询任务结果返回
        Map<Long, AppDto> appDtoMap = Try.of(() -> queryAppTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用应用中心获取应用信息错误:" + e.getMessage(), e)).getOrElse(new HashMap<>());
        Map<Long, ProductDto> productDtoMap = Try.of(() -> queryProductTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用资源中心获取商品信息错误:" + e.getMessage(), e)).getOrElse(new HashMap<>());
        Map<Long, Long> appOfficialAccountToolMap = Try.of(() -> queryAppOfficialTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用查应用关联的公众号工具的付费公众号失败:" + e.getMessage(), e)).getOrElse(new HashMap<>());
        Map<Long, AccountSettingDto> channelAccountSettingDtoMap = Try.of(() -> queryOfficialTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用资源中心获取商品信息错误:" + e.getMessage(), e)).getOrElse(new HashMap<>());
        Map<String, Boolean> buyStateMap = Try.of(() -> queryAppBuyTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用交易中心查询是否购买失败:" + e.getMessage(), e)).getOrElse(new HashMap<>());
        Map<Long, Boolean> courseBuyStateMap = Try.of(() -> queryProductBuyTask.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS))
                .onFailure(e -> log.error("调用交易中心查询课程是否购买错误失败:" + e.getMessage(), e)).getOrElse(new HashMap<>());


        // 循环填充
        Map<Long, Long> defaultChannelIdMap = new HashMap<>();
        for (ResourcePageItemVO itemVO : itemVOS) {
            Long serveId = itemVO.getServeId();
            String serveType = itemVO.getServeType();
            if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(serveType)
                    && !MapUtils.isEmpty(appDtoMap) && appDtoMap.containsKey(serveId)) {
                AppDto appDto = appDtoMap.get(itemVO.getServeId());
                itemVO.setServeName(appDto.getTitle());
                itemVO.setServePic(appDto.getSquareImg());
                itemVO.setTypeCode(appDto.getTypeCode());
                itemVO.setTypeName(appDto.getTypeName());
                itemVO.setTransverseImg(appDto.getTransverseImg());
                //这两个价格不统一，不确定取哪个字段
                Double price = null == appDto.getPrice() ? 0d : appDto.getPrice();
                if (price.equals(0d)) {
                    price = null == appDto.getRetailPrice() ? 0d : appDto.getRetailPrice().doubleValue();
                }
                itemVO.setPrice(price);
                itemVO.setHasThirdLink(StringUtil.isNotEmpty(appDto.getTurnUrl()));
                //标记应用共享状态
                itemVO.setAppCreateUser(appDto.getCreatedUser());
                itemVO.setShareState(appDto.getShareState());
            } else if (ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(serveType)
                    && !MapUtils.isEmpty(productDtoMap) && productDtoMap.containsKey(serveId)) {
                ProductDto productDto = productDtoMap.get(itemVO.getServeId());
                itemVO.setServeName(productDto.getProductName());
                itemVO.setServePic(productDto.getCoverImg());
                if (productDto.getProductTypeDto() != null) {
                    itemVO.setTypeCode(productDto.getProductTypeDto().getTypeCode());
                    itemVO.setTypeName(productDto.getProductTypeDto().getTypeName());
                }
                if (!ListUtils.isEmpty(productDto.getSpecification())) {
                    itemVO.setPrice(productDto.getSpecification().get(0).getAdvisePrice());
                }
                itemVO.setTransverseImg(StringUtil.isEmpty(productDto.getPicture1()) ?
                        getDefaultBigPic(itemVO.getTypeCode()) : productDto.getPicture1());
                itemVO.setHasThirdLink(StringUtil.isNotEmpty(productDto.getSkipUrl()));
            } else {
                continue;
            }
            if (null == itemVO.getPrice()) {
                itemVO.setPrice(0d);
            }
            Long channelId = getChannelIdFromUrl(itemVO.getLinkUrl());
            if (null == channelId) {
                log.info(itemVO.getServeName() + "无运营平台, serveId=" + itemVO.getServeId());
                if (defaultChannelIdMap.containsKey(adviserId)) {
                    channelId = defaultChannelIdMap.get(adviserId);
                    if (null != channelId) {
                        channelId = adviserConsr.getDefaultChannel(adviserId);
                    }
                } else {
                    channelId = adviserConsr.getDefaultChannel(adviserId);
                    if (null != channelId) {
                        defaultChannelIdMap.put(adviserId, channelId);
                    }
                }
            }
            itemVO.setChannelId(channelId);
            setResourceLink4Wechat(itemVO, channelAccountSettingDtoMap, appOfficialAccountToolMap, new HashMap<>());
            if (null != wechatUserId) {
                itemVO.setBuyState(false);
                if (!MapUtils.isEmpty(buyStateMap)) {
                    if (ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(serveType)) {
                        String key = "PRODUCT" + serveId;
                        if (buyStateMap.containsKey(key)) {
                            itemVO.setBuyState(buyStateMap.get(key));
                        }
                    } else if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(serveType)) {
                        String key = "APP" + serveId;
                        if (buyStateMap.containsKey(key)) {
                            itemVO.setBuyState(buyStateMap.get(key));
                        }
                    }
                }
                if (!MapUtils.isEmpty(courseBuyStateMap) && courseBuyStateMap.containsKey(serveId)
                        && ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(itemVO.getServeType())) {
                    itemVO.setBuyState(courseBuyStateMap.get(serveId));
                }
            }
        }
    }

    /**
     * 客户端处理链接
     * @author：zhuyajie
     * @date：2021/6/10 11:20
     *  * @param null
     */
    private void setResourceLink4Wechat(ResourcePageItemVO itemVO, Map<Long, AccountSettingDto> channelAccountSettingDtoMap,
                                        Map<Long, Long> appOfficialAccountToolMap, Map<Long, AccountSetting> accountSettingMap) {
        if (itemVO.getLinkUrl().startsWith("http")) {
            itemVO.setResultUrl(itemVO.getLinkUrl());
            return;
        }
        AccountSettingDto accountSettingDto = new AccountSettingDto();
        //有应用配了付费公众号工具,取公众号工具的公众号域名， 没有就根据渠道id取
        if (!MapUtils.isEmpty(appOfficialAccountToolMap) && appOfficialAccountToolMap.containsKey(itemVO.getServeId())) {
            Long accountSettingId = appOfficialAccountToolMap.get(itemVO.getServeId());
            AccountSetting accountSetting = accountSettingMap.get(accountSettingId);
            if (null == accountSetting) {
                accountSetting = qrcodeSceneConsr.getAppInfo(accountSettingId);
                accountSettingMap.put(accountSettingId, accountSetting);
            }
            BeanUtils.copyProperties(accountSetting, accountSettingDto);
            itemVO.setHasOfficialAccountsTool(true);

        } else {
            Long channelId = itemVO.getChannelId();
            accountSettingDto = channelAccountSettingDtoMap.get(channelId);
            if (accountSettingDto == null) {
                accountSettingDto = qrcodeSceneConsr.getWechatInfo(channelId);
                channelAccountSettingDtoMap.put(channelId, accountSettingDto);
            }
            itemVO.setHasOfficialAccountsTool(false);
        }
        if (null == accountSettingDto) {
            throw new BookBizException(BookBizException.ERROR, itemVO.getServeName() + "未设置公众号");
        }
        String resultLinkUrl = SendWeixinRequestTools.splitUrl(accountSettingDto, itemVO.getLinkUrl());
        itemVO.setResultUrl(resultLinkUrl);
    }


    private Long getChannelIdFromUrl(String url) {
        Long channelId = null;
        if (url.contains("/C")) {
            url = url.substring(url.indexOf("/C") + 2);
            url = url.substring(0, url.indexOf("/"));
            if (!StringUtil.isEmpty(url) && NumberUtil.isNumber(url)) {
                channelId = Long.valueOf(url);
            }
        }
        return channelId;
    }

    @ParamLog("填充社群")
    private void fillGroupServe(List<? extends ResourcePageItemVO> itemVOS) {
        log.info("填充社群");
        if (ListUtils.isEmpty(itemVOS)) {
            return;
        }
        List<ResourcePageItemVO> removeList = new ArrayList<>();
        List<Long> serveIds = itemVOS.stream().map(ResourcePageItemVO::getServeId).distinct().collect(Collectors.toList());
        Map<Long, GroupActivity4AppletDTO> groupDtoMap = pcloudGroupActivityBiz.getGroupActivityMap(serveIds);
        for (ResourcePageItemVO itemVO : itemVOS) {
            if (MapUtils.isEmpty(groupDtoMap) || !groupDtoMap.containsKey(itemVO.getServeId())) {
                removeList.add(itemVO);
                continue;
            }
            GroupActivity4AppletDTO groupActivity4AppletDTO = groupDtoMap.get(itemVO.getServeId());
            if (null == groupActivity4AppletDTO) {
                continue;
            }
            itemVO.setTypeName("社群");
            groupActivity4AppletDTO.setGroupName(groupActivity4AppletDTO.getName());
            groupActivity4AppletDTO.setGroupDesc(groupActivity4AppletDTO.getCutDesc());
            itemVO.setActivity4AppletDTO(groupActivity4AppletDTO);
            rightsSettingBiz.fillThirdGroupHeadList(groupActivity4AppletDTO);
        }
        itemVOS.removeAll(removeList);
    }

    @ParamLog("填充平台书单")
    private void fillBooklistServe(List<? extends ResourcePageItemVO> itemVOS) {
        log.info("填充平台书单");
        if (ListUtils.isEmpty(itemVOS)) {
            return;
        }
        List<Long> serveIds = itemVOS.stream().map(ResourcePageItemVO::getServeId).distinct().collect(Collectors.toList());
        Map<Long, AppletOuterBooklistDTO> outerBooklistDTOMap = appletBooklistBiz.getByIds(serveIds);
        if (MapUtils.isEmpty(outerBooklistDTOMap)) {
            return;
        }
        for (ResourcePageItemVO itemVO : itemVOS) {
            AppletOuterBooklistDTO outerBooklistDTO = outerBooklistDTOMap.get(itemVO.getServeId());
            if (null != outerBooklistDTO) {
                itemVO.setTypeName("平台书单");
                itemVO.setAppletOuterBooklistDTO(outerBooklistDTO);
            }
        }
    }

    @Override
    public ResourcePageVO getResourcePageByBookId(Long bookId, Long channelId, Long adviserId, Long wechatUserId) {
        ResourcePageVO resourcePageVO = new ResourcePageVO();
        ResourcePage resourcePage = resourcePageDao.getByBookId(bookId, channelId, adviserId);
        if (null != resourcePage) {
            BeanUtils.copyProperties(resourcePage, resourcePageVO);
        }
        BookDto bookDto = bookBiz.getBaseById(bookId);
        if (null != bookDto) {
            resourcePageVO.setBookImg(bookDto.getCoverImg());
            resourcePageVO.setBookName(bookDto.getBookName());
        }
        Map<Long, AdviserBaseInfoDto> agentMap = adviserConsr.getAdviserId2AdviserInfoDtoMap(Arrays.asList(adviserId));
        if (!MapUtils.isEmpty(agentMap)) {
            resourcePageVO.setAgentName(agentMap.get(adviserId).getAgentName());
        }
        if (null != wechatUserId) {
            //查收藏状态
            Integer collectState = 0;
            if (null != resourcePageVO && null != resourcePageVO.getId()) {
                Integer collect = resourcePageCollectDao.getCollectStateByUser(wechatUserId, resourcePageVO.getId());
                collectState = null == collect ? 0 : 1;
            }
            resourcePageVO.setCollectState(collectState);
        }
        if(resourcePageVO != null){
            AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(channelId);
            if(accountSettingDto != null){
                resourcePageVO.setAccountSettingId(accountSettingDto.getAccountSettingId());
            }
            resourcePageVO.setChannelId(channelId);

            if(resourcePageVO.getId() != null){
                // 实体店铺
                resourcePageVO.setResourcePageBookstoreList(resourcePageBookstoreBiz.getByResourcePageId(resourcePageVO.getId(), resourcePageVO.getChannelId(), wechatUserId, ResourcePageFixtureTypeEnum.BOOKSTORE));
                // 优惠券
                resourcePageVO.setResourcePageCouponList(resourcePageBookstoreBiz.getByResourcePageId(resourcePageVO.getId(), resourcePageVO.getChannelId(), wechatUserId, ResourcePageFixtureTypeEnum.COUPONS));
            }
        }
        // 加载实体书购买
        this.fillBookStore(resourcePageVO);
        // 加载固定项
        this.fillFixture(resourcePageVO);
        //加载导航
        this.fillNavigation(resourcePageVO, wechatUserId);
        //加载图书标准服务
        this.fillResourcePageModel(resourcePageVO, wechatUserId);
        return resourcePageVO;
    }


    @Override
    public PageBeanNew<ResourcePageItemVO> listPageResourcePageItem(Integer currentPage, Integer numPerPage, Long resourcePageColumnId,
                                                                    Long wechatUserId, Long officialAccountsId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("resourcePageColumnId", resourcePageColumnId);
        ResourcePageColumn resourcePageColumn = resourcePageColumnDao.getById(resourcePageColumnId);
        if (null == resourcePageColumn) {
            return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        }
        PageBeanNew<ResourcePageItemVO> pageBeanNew = resourcePageItemDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "getResourcePageItemByColumnId");
        if (ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, pageBeanNew.getTotalCount(), new ArrayList<>());
        }
        Map<String, List<ResourcePageItemVO>> listMap = pageBeanNew.getRecordList().stream().collect(Collectors.groupingBy(ResourcePageItemVO::getServeType));
        for (Map.Entry<String, List<ResourcePageItemVO>> entry : listMap.entrySet()) {
            if (StringUtils.equals(ServeTypeEnum.FOLDER.getValue(), entry.getKey())) {
                fillResourcePageFolder(entry.getValue(), wechatUserId);
                continue;
            }
            //二维码类型
            fillQrcodeType(resourcePageColumn.getResourcePageId(), entry.getValue());
            fillResourceByType(entry.getValue(), wechatUserId, entry.getKey());
        }
        //填充自定义图片
        fillSelfPic(pageBeanNew.getRecordList());
        ResourcePage byId = resourcePageDao.getById(resourcePageColumn.getResourcePageId());
        try {
            fillJumpUrl(pageBeanNew.getRecordList(), wechatUserId, resourcePageColumn.getResourcePageId(), officialAccountsId, byId.getBookId(), byId.getCreateUser(), byId.getChannelId());
        } catch (Exception e) {
            log.error("fillJumpUrl失败：{}",e.getMessage());
        }
        return pageBeanNew;
    }

    private void fillSelfPic(List<ResourcePageItemVO> resourcePageItemVOList) {
        if (ListUtils.isEmpty(resourcePageItemVOList)) {
            return;
        }
         resourcePageItemVOList.stream().forEach(e -> {
            if (!StringUtil.isEmpty(e.getSelfSmallPic())) {
                e.setServePic(e.getSelfSmallPic());
                e.setCoverImg(e.getSelfSmallPic());
            }
            if (!StringUtil.isEmpty(e.getSelfBigPic())) {
                e.setTransverseImg(e.getSelfBigPic());
            }
            if (!StringUtil.isEmpty(e.getSelfServeName())) {
                e.setServeName(e.getSelfServeName());
            }
        });
    }

    @Override
    public ResourcePage getPageByBookGroupId(Long bookGroupId) {
        return resourcePageDao.getByBookGroupId(bookGroupId);
    }

    @Override
    public List<Map<String, Object>> getColumnAndServeTypeList() {
        List<Map<String, Object>> list = new ArrayList<>();
        for (ResourcePageConstants.ColumnTypeEnum columnTypeEnum : ResourcePageConstants.ColumnTypeEnum.values()) {
            Map<String, Object> map = new HashMap<>();
            map.put("code", columnTypeEnum.getCode());
            map.put("name", columnTypeEnum.getName());
            List<Map<String, Object>> serveTypeList = new ArrayList<>();
            for (String serveType : columnTypeEnum.getServes()) {
                Map<String, Object> serveTypeMap = new HashMap<>();
                serveTypeMap.put("code", serveType);
                serveTypeMap.put("name", ResourcePageConstants.ServeTypeEnum.getNameByValue(serveType));
                serveTypeList.add(serveTypeMap);
            }
            map.put("serveTypeList", serveTypeList);
            list.add(map);
        }
        return list;
    }

    @Override
    public void updateColumnSeq(Long resourcePageColumnId, String moveType) {
        ResourcePageColumn resourcePageColumn = resourcePageColumnDao.getById(resourcePageColumnId);
        if (null == resourcePageColumn) {
            throw new BookBizException(BookBizException.ERROR, "该栏目不存在！");
        }
        Long resourcePageId = resourcePageColumn.getResourcePageId();
        Integer columnSeq = resourcePageColumn.getColumnSeq();
        Long navigationId = resourcePageColumn.getNavigationId();
        //获取要调换的栏目
        ResourcePageColumn column = resourcePageColumnDao.getColumByMoveType(moveType, resourcePageId, columnSeq, navigationId);
        if (null == column) {
            return;
        }
        //调换序号
        resourcePageColumnDao.updateColumnSeqNum(resourcePageColumnId, column.getColumnSeq());
        resourcePageColumnDao.updateColumnSeqNum(column.getId(), columnSeq);
        // 修改该单页面的更新时间
        resourcePageDao.updatePageUpdateTime(resourcePageId);
        //同步RAYS码资源配置
        ResourcePage resourcePage = resourcePageDao.getById(resourcePageId);
        this.updateOwnMessage4Qr(null == resourcePage? null : resourcePage.getSceneId());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteColumnById(Long resourcePageColumnId) {
        ResourcePageColumn column = resourcePageColumnDao.getById(resourcePageColumnId);
        if (null == column) {
            return;
        }
        //删除资源配置
        resourcePageItemDao.deleteByPageColumnId(resourcePageColumnId);
        //删除栏目
        resourcePageColumnDao.deleteById(resourcePageColumnId);
        //栏目重新排序
        this.updateSeq4Batch(column.getResourcePageId(), column.getNavigationId());
        //同步RAYS码资源配置
        ResourcePage resourcePage = resourcePageDao.getPageByColumnId(resourcePageColumnId);
        this.updateOwnMessage4Qr(null == resourcePage? null : resourcePage.getSceneId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long updateResourcePageAndColumn(UpdateResourcePageVO updateResourcePageVO) {
        Long resourcePageId = this.updateResourcePage(updateResourcePageVO);
        ResourcePage page = resourcePageDao.getById(resourcePageId);
        //当前所有栏目
        List<Long> originColumnIds = resourcePageColumnDao.getColumnIdsByPageId(resourcePageId);
        //删除栏目资源
        resourcePageItemDao.deleteByPageId(resourcePageId);
        // 删除新版通用组件配置
        delete4NewComponentFolderByColumnIds(originColumnIds);
        if (!ListUtils.isEmpty(updateResourcePageVO.getColumnVOS())) {
            List<UpdateResourceColumnVO> list = updateResourcePageVO.getColumnVOS();
            List<Long> columnIds = new ArrayList<>();
            List<ResourcePageItemVO> accountItemVOS = new ArrayList<>();
            for (UpdateResourceColumnVO columnVO : list) {
                columnVO.setResourcePageId(resourcePageId);
                columnVO.setCreateUser(updateResourcePageVO.getCreateUser());
                columnVO.setChannelId(page.getChannelId());
                columnVO.setColumnSeq(list.indexOf(columnVO) + 1);
                if (null != columnVO.getResourcePageColumnId()) {
                    columnIds.add(columnVO.getResourcePageColumnId());
                }
                //栏目校验
                this.checkResourceColumn(columnVO);
                //公众号栏目
                if (ResourcePageConstants.ColumnTypeEnum.OFFICIAL_ACCOUNT.getCode().equals(columnVO.getColumnType())) {
                    accountItemVOS.addAll(columnVO.getItemVOList());
                }
            }
            //检查弹窗公众号配置数量
            if (!ListUtils.isEmpty(accountItemVOS)) {
                List<ResourcePageItemVO> popupItems = accountItemVOS.stream().filter(s->
                        ResourcePageConstants.QrcodeShowTypeEnum.POPUP.getCode().equals(s.getQrcodeShowType())).collect(Collectors.toList());
                if (popupItems.size()>1) {
                    throw new BookBizException(BookBizException.PARAM_IS_NULL, "弹窗式公众号只能配置一个");
                }
            }
            for (UpdateResourceColumnVO columnVO : list) {
                this.updateResourceColumn(columnVO);
            }
            if (!ListUtils.isEmpty(columnIds)) {
                originColumnIds.removeAll(columnIds);
            }
        }
        if (!ListUtils.isEmpty(originColumnIds)) {
            //删除剩余栏目
            resourcePageColumnDao.deleteByIds(originColumnIds);
        }

        // 更新图书封面
        this.updateBookCover(page, updateResourcePageVO);

        // 更新实体书购买
        this.updateResourcePageBookstore(resourcePageId, updateResourcePageVO.getResourcePageBookstoreList(), ResourcePageFixtureTypeEnum.BOOKSTORE);
        // 更新优惠券
        this.updateResourcePageBookstore(resourcePageId, updateResourcePageVO.getResourcePageCouponList(), ResourcePageFixtureTypeEnum.COUPONS);
        // 更新营销活动
        this.updateResourcePageMarketingActivity(resourcePageId, updateResourcePageVO.getResourcePageMarketingActivityList());
        //图书标准服务
        this.updateResourcePageModel(resourcePageId,updateResourcePageVO.getResourcePageModelList(),page.getCreateUser());

        //发送编辑任务queue
        adviserTaskConsr.sendAdviserTaskQueue(updateResourcePageVO.getCreateUser(), AdviserTaskConstants.TargetTypeEnum.QRCODE.getValue(),
                page.getBookGroupId() == null ? page.getSceneId() : page.getBookGroupId(),
                AdviserTaskConstants.OperateTypeEnum.CONFIGURE_RESOURCE.getValue());
        //同步RAYS码资源配置
        this.updateOwnMessage4Qr(updateResourcePageVO.getSceneId());
        ThreadPoolUtils.RESOURCE_POOL.execute(()->{
            this.sendMemberActivityQueue(resourcePageId);
        });
        //更新会员商品渠道
        ThreadPoolUtils.UPDATE_PRODUCT_CHANNEL.execute(()->{
            this.updateMemberActivityChannel(updateResourcePageVO.getColumnVOS(),page.getChannelId());
        });
        //删除缓存
        JedisClusterUtils.del("FUNCTION:DOULUO_APP");
        JedisClusterUtils.del(DL_BOOK_SERVES_CACHE + updateResourcePageVO.getSceneId());
        //updateQrcodeOneServe(updateResourcePageVO);
        //更新二维码是否一个资源配置,异步会有时候没能及时更新。如果非要异步。线程先休息2s再执行
        //ThreadPoolUtils.OTHER_POOL.execute(()->{
            this.updateQrcodeOneServe(updateResourcePageVO.getBookGroupId(),updateResourcePageVO.getSceneId(),null);
       // });
        return resourcePageId;
    }

    private void updateResourcePageMarketingActivity(Long resourcePageId, List<ResourcePageMarketingActivity> resourcePageMarketingActivityList) {
        resourcePageMarketingActivityMapper.deleteByResourcePageId(resourcePageId);
        if (CollUtil.isNotEmpty(resourcePageMarketingActivityList)) {
            resourcePageMarketingActivityList.forEach(x->x.setResourcePageId(resourcePageId));
            resourcePageMarketingActivityMapper.batchInsert(resourcePageMarketingActivityList);
        }
    }

    private void delete4NewComponentFolderByColumnIds(List<Long> columnIds) {
        if (CollUtil.isEmpty(columnIds)) {
            return;
        }
        resourcePageFolderMapper.deleteByColumnIds(columnIds);
        resourcePageFolderItemMapper.deleteByColumnIds(columnIds);
    }

    @Override
    public void updateQrcodeOneServe(Long bookGroupId, Long sceneId, Boolean ignoreRays) {
        try {
            String jumpUrl = getQrcodeOneServe(bookGroupId, sceneId, ignoreRays);
            Integer isOneServeJump=0;
            if(StrUtil.isNotBlank(jumpUrl)){
                isOneServeJump=1;
            }
            qrcodeSceneConsr.updateQrcodeOneServeRule(sceneId,isOneServeJump,jumpUrl,oneServeRuleVersion);
        } catch (BizException e) {
            LOGGER.warn("修改一码一资源直接跳转失败"+e.getMsg());
        }

    }

    @Override
    public String getQrcodeOneServe(Long bookGroupId,Long sceneId,Boolean ignoreRays) {
        String jumpUrl= null;
        try {
            if(null==ignoreRays){
                ignoreRays=true;
            }
            // 1007143  判断逻辑见hasOneResource接口
            // 满足以下条件则进入自动跳转流程
      /*  reslut.navigationJumpType !== 2 &&     			// 菜单类型不是2
                data.oneServe &&                    				// 只有一个资源
                data.resultUrl && 													// 这个资源有跳转地址
                !qrcodeInfo.isDisable && 										// 当前二维码不是禁用状态
                codeUseStatus === 1 && 						  				// 授权码状态为1
                !raysToolCodeArr.includes(data.typeCode) && // 该应用不是rays工具*/
         //因为在hasOneResource方法中没有wechatuserId在填充资源信息的时候会跳过。所以要有一个。
            ResourcePageOneServe oneServe = hasOneResource(bookGroupId, sceneId, 0L, ignoreRays);
            //此处授权码状态为1，只能放到前端校验。因为需要先授权。所以这一类的二维码在渠道分发跳转要提出来还是跳转到落地页
            //菜单类型不是2   &&  只有一个资源 && 这个资源有跳转地址
            if(null!=oneServe.getOneServe() && oneServe.getOneServe() && null!=oneServe.getNavigationJumpType() && oneServe.getNavigationJumpType() != 2
                  && StrUtil.isNotBlank(oneServe.getResultUrl())){
                QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getOnlySceneInfoById(sceneId);
                //当前二维码不是禁用状态
                if(null!=qrcodeSceneDto && null!=qrcodeSceneDto.getIsDisable() && qrcodeSceneDto.getIsDisable()==0){
                    //该应用不是rays工具
                    List<String> typeCodes = appConsr.getRaysAppTypeCodes();
                    if(CollUtil.isEmpty(typeCodes) || (null!=oneServe.getTypeCode() && !typeCodes.contains(oneServe.getTypeCode()))){
                        //更新
                        jumpUrl=oneServe.getResultUrl();
                        // url处理
                        // 是否做url处理
                        Boolean isTransfer =false;
                        if(null!=oneServe.getHasOfficialAccountsTool()){
                            isTransfer=!oneServe.getHasOfficialAccountsTool();
                        }
                        //前端代码
                        /*if(bookGroupId && data.jumpType === 7) {
                            isTransfer = false;
                        }*/
                        if(null!=oneServe.getJumpType() && oneServe.getJumpType() == 7) {
                            if(isGroupId(bookGroupId)) {
                                isTransfer = false;
                            }
                        }
                        // qrcodeType === 'ali' 原有自有码 own下面的RAYS码，不作处理
                        if(null!=oneServe.getQrcodeType() && "ali".equalsIgnoreCase(oneServe.getQrcodeType())) {
                            isTransfer = false;
                        }
                        //  化学工业出版社有限公司,只配置一个文章类型的 链接不做处理
                        if(null!=oneServe.getTypeCode() && "ARTICLE".equalsIgnoreCase(oneServe.getTypeCode()) && oneServe.getAdviserId()!=null &&  oneServe.getAdviserId()== 1000021984L) {
                            isTransfer = false;
                        }
                        jumpUrl = getServiceWebviewUrl(jumpUrl, isTransfer);
                    }
                }
            }
        } catch (BizException e) {
           LOGGER.warn("判断是否符合二维码一个资源逻辑失败"+e.getMsg());
        }
        return jumpUrl;
    }

    public Boolean isGroupId(Long bookGroupId){
        Boolean isGroup=false;
        if(null==bookGroupId){
            return false;
        }
        //根据joinGroupType判断二维码类型
        Map<String, Object> map = bookGroupBiz.getBookNameByBookGroupId(bookGroupId);
        Boolean isDelete = (Boolean) map.get("isDelete");
        if (isDelete) {
            return false;
        }
        Integer joinGroupType = (Integer) map.get("joinGroupType");
        if (JoinGroupTypeEnum.XIAORUI.getCode().equals(joinGroupType)) {
            Integer jumpType = (Integer) map.get("jumpType");
            //自定义链接
            if (QrcodeJumpType.H5_SELF_URL.getCode().equals(jumpType)) {
                if (null != map.get("jumpUrl")) {
                   return false;
                }
            }
            return true;
        }
        return isGroup;
    }

    public String getServiceWebviewUrl(String url, Boolean isTransfer) {
        if(null==isTransfer){
            isTransfer=true;
        }
        Long originAccountId=null;
        String accountString = ReUtil.get("W(\\d*)", url, 0);
        if (StrUtil.isNotBlank(accountString)) {
            String w = accountString.replaceAll("W", "");
            if(null!=w && NumberUtil.isNumber(w)){
                originAccountId = Long.valueOf(w);
            }
        }
        // url拼接 加traceId。放到渠道分发里面做。

        // 无须更换域名
        if(!isTransfer) {
            return url;
        }
        //小蓝书支付跳转到自己的商户号,不做处理
         List<Long> xiaoLanShuList = CollUtil.toList(65777L, 65842L, 65957L, 65961L, 66046L, 66047L, 66049L, 66050L, 66069L, 66070L, 66076L, 66078L, 66079L, 66107L, 66134L);
        if(xiaoLanShuList.contains(originAccountId)) {
            return url;
        }

        //阿法迪支付到自己的商户号
        if(null!=originAccountId && originAccountId == 66043L) {
            String productDomain = "https://weixin76043.raystime.com/";
            if(isRaysLink(url)) {
                url = aFaDiExchangeLinkDomain(url, productDomain,null);
            }
        } else {
            // 如果链接是rays链接
            if(isRaysLink(url)) {
                url = exchangeLinkDomain(url, getProductDomain(),null);
            }
        }
        return url;
    }

    // 是不是rays链接
    public Boolean isRaysLink(String url) {
      return ReUtil.contains("^(https|http)?://weixin\\w+[.]",url) || ReUtil.contains("^(https|http)?://(app\\w*)[.]",url);
    }

    public static final  String  DOMAIN_REG = "^(https|http)?://([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}(\\/)";

    // 阿法迪单独特殊处理（临时方案）
    public String aFaDiExchangeLinkDomain(String url,String domain,Boolean isReplaceAccountId) {
        if(null==isReplaceAccountId){
            isReplaceAccountId=true;
        }
        Long officialAccountId = 66043L;
        if(!domain.endsWith("/")) {
            domain += '/';
        }
        url =  ReUtil.replaceAll(url, DOMAIN_REG, domain);
        return isReplaceAccountId ? url.replaceAll("/W(\\d+)/C", "/W"+officialAccountId+"/C") : url;
    }

    // url处理
    public String exchangeLinkDomain(String url,String domain,Boolean isReplaceAccountId) {
        if(null==isReplaceAccountId){
            isReplaceAccountId=true;
        }
        if(!domain.endsWith("/")) {
            domain += '/';
        }
        url =  ReUtil.replaceAll(url, DOMAIN_REG, domain);
        // OFFICIAL_ACCOUNT_ID 测试23， uat35515, 生产23
        return isReplaceAccountId ? url.replaceAll("/W(\\d+)/C", "/W"+getOffAccount()+"/C") : url;
    }

    public Long getOffAccount(){
        if ("pro".equals(envStr)) {
            return 23L;
        } else if ("uat".equalsIgnoreCase(envStr)) {
            return 35515L;
        } else if ("test".equalsIgnoreCase(envStr)) {
            return 23L;
        }
        return 23L;
    }

    public String getProductDomain(){
        if ("pro".equals(envStr)) {
            return "https://weixin23.5rs.me";
        } else if ("uat".equalsIgnoreCase(envStr)) {
            return "https://weixin35515.raysyun.com";
        } else if ("test".equalsIgnoreCase(envStr)) {
            return "https://weixin23.raysgo.com";
        }
        return null;
    }


    // 更新图书封面
    private void updateBookCover(ResourcePage page, UpdateResourcePageVO updateResourcePageVO) {
        if (StrUtil.isNotBlank(updateResourcePageVO.getBookCover()) && Objects.nonNull(page)) {
            Long bookId;
            if (Objects.nonNull(page.getBookGroupId())) {
                BookGroupDTO bookGroupDto = bookGroupDao.getDTOById(page.getBookGroupId());
                bookId = bookGroupDto.getBookId();
            } else {
                bookId = channelConsr.getBookId4SceneId(page.getSceneId());
            }
            BookDto bookDto = bookBiz.getBaseById(bookId);
            boolean isDefaultBook = StringUtils.isEmpty(bookDto.getSerialNumber()) && BookConstant.DEFAULT_BOOK_ISBN.equals(bookDto.getIsbn());
            if (bookId != null && !isDefaultBook) {
                Book book = new Book();
                book.setBookId(bookId);
                book.setLastModifiedUser(updateResourcePageVO.getCreateUser());
                book.setCoverImg(updateResourcePageVO.getBookCover());
                bookBiz.updateCoverImg(book);
            }
        }
    }


    //更新会员商品渠道
    private void updateMemberActivityChannel(List<UpdateResourceColumnVO> columnVOS, Long channelId) {
        if (ListUtils.isEmpty(columnVOS) || null == channelId) {
            return;
        }
        List<UpdateResourceColumnVO> memberActivitys = columnVOS.stream().filter(e -> ResourcePageConstants.ColumnTypeEnum.MEMBER_ACTIVITY.getCode().equals(e.getColumnType())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(memberActivitys) && null !=  memberActivitys.get(0) &&
                null != memberActivitys.get(0).getItemVOList() && null != memberActivitys.get(0).getItemVOList().get(0)) {
            UpdateResourceColumnVO updateResourceColumnVO = memberActivitys.get(0);
            Long serveId = updateResourceColumnVO.getItemVOList().get(0).getServeId();
            List<Long> productIds = memberActivityConsr.getProductIdsByMemberActivity(serveId);
            if (CollUtil.isNotEmpty(productIds)) {
                autoOnChannel(BookProps.getDefaultChannelId(), productIds);
                //上架书刊渠道
                autoOnChannel(channelId, productIds);
            }
        }
    }

    @ParamLog("图书标准服务")
    private void updateResourcePageModel(Long resourcePageId, List<ResourcePageModel> resourcePageModelList, Long createUser) {
        if (null == resourcePageId) {
            return;
        }
        resourcePageModelDao.deleteByPageId(resourcePageId);
        if (!ListUtils.isEmpty(resourcePageModelList)) {
            resourcePageModelList.forEach(s -> {
                s.setResourcePageId(resourcePageId);
                s.setCreateUser(createUser);
            });
            resourcePageModelDao.insert(resourcePageModelList);
        }
    }

    private void autoOnChannel(Long channelId, List<Long> productIds) {
        //上架默认渠道
        Map<Long, String> longStringMap = productConsr.productAutoOnShelves(channelId, productIds);
        //删除手动下架的商品
        if (CollUtil.isNotEmpty(longStringMap)) {
            Iterator<Long> iterator = productIds.iterator();
            while (iterator.hasNext()) {
                Long next = iterator.next();
                if (longStringMap.keySet().contains(next)) {
                    iterator.remove();
                }
            }
            if (CollUtil.isNotEmpty(productIds)) {
                productConsr.productAutoOnShelves(BookProps.getDefaultChannelId(), productIds);
            }
        }
    }

    private void updateResourcePageBookstore(Long resourcePageId, List<ResourcePageBookstore> resourcePageBookstoreList, ResourcePageFixtureTypeEnum fixtureTypeEnum) {
        resourcePageBookstoreBiz.deleteByResourcePageId(resourcePageId, fixtureTypeEnum.fixtureType);
        if (CollUtil.isNotEmpty(resourcePageBookstoreList)) {
            for (ResourcePageBookstore bookstore : resourcePageBookstoreList) {
                bookstore.setResourcePageId(resourcePageId);
            }
            resourcePageBookstoreBiz.insert(resourcePageBookstoreList);
        }
    }

    /**
     * 配置会员活动，发topic
     * @author：zhuyajie
     * @date：2021/9/24 11:29
     *  * @param null
     */
    private void sendMemberActivityQueue(Long resourcePageId) {
        List<ResourcePageItemVO> itemVOS = resourcePageItemDao.getResourcePageItemByPageId(resourcePageId,null);
        if (ListUtils.isEmpty(itemVOS)) {
            return;
        }
        List<Long> activityIds = itemVOS.stream().filter(s->ResourcePageConstants.ServeTypeEnum.MEMBER_ACTIVITY.getValue().equals(s.getServeType())).map(ResourcePageItemVO::getServeId).distinct().collect(Collectors.toList());
        if (ListUtils.isEmpty(activityIds)){
            return;
        }
        ResourcePage resourcePage = resourcePageDao.getById(resourcePageId);
        MemberActivityBookSetDTO memberActivityBookSetDTO = new MemberActivityBookSetDTO();
        memberActivityBookSetDTO.setBookId(resourcePage.getBookId());
        memberActivityBookSetDTO.setAdviserId(resourcePage.getCreateUser());
        memberActivityBookSetDTO.setActivityIds(activityIds);
        amqpTemplate.convertAndSend(MQTopicProducer.EXCHAGE, MQTopicProducer.MEMBER_ACTIVITY_BOOK_SET, memberActivityBookSetDTO);
    }

    @Override
    public ResourcePageVO getResourcePageByBookGroupIdOrSceneId4Wechat(Long bookGroupId, Long wechatUserId, Long sceneId) {
        if (null == bookGroupId && null == sceneId) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数缺失");
        }
        Long bookId = null;
        if (null != bookGroupId) {
            bookId = resourcePageDao.getBookIdByBookGroupId(bookGroupId);
        } else if (null != sceneId) {
            bookId =  resourcePageDao.getBookIdBySceneId(sceneId);
        }
        //上邮临时处理方案
        if (null != bookId && null != JedisClusterUtils.hget(nftReleaseLockKey, bookId.toString())) {
            if (null != bookGroupId) {
                bookGroupId = JedisClusterUtils.hgetJson2Class(nftReleaseLockKey, bookId.toString(), NftBookState.class).getNftBookGroupId();
            } else if (null != sceneId) {
                sceneId = JedisClusterUtils.hgetJson2Class(nftReleaseLockKey, bookId.toString(), NftBookState.class).getNftSceneId();;
            }
        }
        ResourcePageVO pageVO = new ResourcePageVO();
        if (null != bookGroupId) {
            pageVO = getResourcePageByBookGroupId4Wechat(bookGroupId, wechatUserId);
        } else if (null != sceneId) {
            pageVO = getResourcePageBySceneId4Wechat(sceneId);
        }
        ResourcePageVO resourcePageVO = pageVO;
        if (null != resourcePageVO.getId()) {
            //查收藏状态
            Integer collectState = resourcePageCollectDao.getCollectStateByUser(wechatUserId, resourcePageVO.getId());
            resourcePageVO.setCollectState(null == collectState ? 0 : 1);
        }
        // 实体店铺
        CompletableFuture<List<ResourcePageBookstoreVO>> storeFuture = CompletableFuture.supplyAsync(() -> {
            return resourcePageBookstoreBiz.getByResourcePageId(resourcePageVO.getId(), resourcePageVO.getChannelId(), wechatUserId, ResourcePageFixtureTypeEnum.BOOKSTORE);
        });
        // 优惠券
        CompletableFuture<List<ResourcePageBookstoreVO>> couponFuture = CompletableFuture.supplyAsync(() -> {
            return resourcePageBookstoreBiz.getByResourcePageId(resourcePageVO.getId(), resourcePageVO.getChannelId(), wechatUserId, ResourcePageFixtureTypeEnum.COUPONS);
        });
        //加载导航
        CompletableFuture<Void> navigationFuture = CompletableFuture.runAsync(() -> {
            this.fillNavigation(resourcePageVO, wechatUserId);
        });
        //加载企业微信落地页信息
        CompletableFuture<Void> wxworkPageFuture = CompletableFuture.runAsync(() -> {
            this.fillWxworkPage(resourcePageVO);
        });
        //扫码推送二维码名称权限状态
        CompletableFuture<Integer> pushTextFuture = CompletableFuture.supplyAsync(() -> {
            return qrcodeSceneConsr.getPushTextOpenStatus(resourcePageVO.getAdviserId());
        });
        //加载图书标准服务
        CompletableFuture<Void> modelFuture = CompletableFuture.runAsync(() -> {
            this.fillResourcePageModel(resourcePageVO, wechatUserId);
        });
        CompletableFuture.allOf(storeFuture, couponFuture, navigationFuture, wxworkPageFuture, pushTextFuture, modelFuture).join();
        List<ResourcePageBookstoreVO> bookstoreVOS = new ArrayList<>();
        List<ResourcePageBookstoreVO> couponVOS = new ArrayList<>();
        Integer pushTextPermission = 0;
        try {
            bookstoreVOS = storeFuture.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS);
            couponVOS = couponFuture.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS);
            pushTextPermission = pushTextFuture.get(ThreadPoolUtils.REMOTE_TIME_OUT, TimeUnit.SECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
           log.error("查询实体店铺/优惠券失败"+e.getMessage(),e);
        }
        resourcePageVO.setResourcePageBookstoreList(bookstoreVOS);
        resourcePageVO.setResourcePageCouponList(couponVOS);
        resourcePageVO.setPushTextOpenStatus(pushTextPermission);
        fillResourcePageMarketingActivity(resourcePageVO, wechatUserId);
        return resourcePageVO;
    }

    @ParamLog("加载企业微信落地页信息")
    private void fillWxworkPage(ResourcePageVO resourcePageVO) {
        if(resourcePageVO == null || resourcePageVO.getId() == null){
            return;
        }
        Long resourcePageId = resourcePageVO.getId();
        if (PageLandingPageTypeEnum.WXWORK.getCode().equals(resourcePageVO.getLandingPageType())) {
            resourcePageVO.setWxworkPageVO(getWxworkPageByPageId(resourcePageId, true));
        }
    }

    @ParamLog("根据bookGroupId查资源页信息")
    private ResourcePageVO getResourcePageByBookGroupId4Wechat(Long bookGroupId, Long wechatUserId) {
        ResourcePageVO resourcePageVO = new ResourcePageVO();
        resourcePageVO.setBookGroupId(bookGroupId);
        BookGroupDTO bookGroupDTO = bookGroupDao.getDTOById(bookGroupId);
        if (null != bookGroupDTO) {
            resourcePageVO.setBookId(bookGroupDTO.getBookId());
            resourcePageVO.setAdviserId(bookGroupDTO.getCreateUser());
            resourcePageVO.setChannelId(bookGroupDTO.getChannelId());
            resourcePageVO.setQrcodeName(bookGroupDTO.getGroupQrcodeName());
            resourcePageVO.setAgentName(agentConsr.getNameById(bookGroupDTO.getAgentId()));
            BookDto bookDto = bookBiz.getBaseById(bookGroupDTO.getBookId());
            if (null != bookDto) {
                resourcePageVO.setBookImg(bookDto.getCoverImg());
                resourcePageVO.setBookName(bookDto.getBookName());
            }
        }
        resourcePageVO.setLastReadTime(DateUtils.formatDate(new Date()));
        //小程序
        String appletId = bookAppletSceneDao.getAppletIdByBookGroupId(bookGroupId);
        resourcePageVO.setAppletId(appletId);
        ResourcePage resourcePage = resourcePageDao.getByBookGroupId(bookGroupId);
        if (null != resourcePage) {
            resourcePageVO.setShowBook(resourcePage.getShowBook());
            resourcePageVO.setOpenRays(resourcePage.getOpenRays());
            resourcePageVO.setStyle(resourcePage.getStyle());
            resourcePageVO.setQrcodeUrl(resourcePage.getQrcodeUrl());
            resourcePageVO.setId(resourcePage.getId());
            resourcePageVO.setBookCover(resourcePage.getBookCover());
            resourcePageVO.setBackgroundImg(resourcePage.getBackgroundImg());
            resourcePageVO.setNavigationColor(resourcePage.getNavigationColor());
            resourcePageVO.setNavigationFormat(resourcePage.getNavigationFormat());
            resourcePageVO.setFontColor(resourcePage.getFontColor());
            resourcePageVO.setWatermark(resourcePage.getWatermark());
            resourcePageVO.setWatermarkStyle(resourcePage.getWatermarkStyle());
            resourcePageVO.setLandingPageType(resourcePage.getLandingPageType());
            resourcePageVO.setTransparency(resourcePage.getTransparency());
            resourcePageVO.setIsShowPrice(resourcePage.getIsShowPrice());
            IMaskFlag.Helper helper = IMaskFlag.Helper.of(resourcePage.getSwitchConfig());
            resourcePageVO.setShowSelf(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_SELF));
            resourcePageVO.setShowCollect(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_COLLECT));
            resourcePageVO.setShowShare(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_SHARE));
            resourcePageVO.setNewEditor(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.NEW_EDITOR));
        }
        return resourcePageVO;
    }

    @ParamLog("根据SceneId查资源页信息")
    private ResourcePageVO getResourcePageBySceneId4Wechat(Long sceneId) {
        ResourcePageVO resourcePageVO = new ResourcePageVO();
        resourcePageVO.setSceneId(sceneId);
        Future<Map<Long, QrcodeSceneDto>> qrcodeFuture = ThreadPoolUtils.RESOURCE_POOL.submit(()->{
            return qrcodeSceneConsr.listBaseInfoByIds(Arrays.asList(sceneId));
        });
        ResourcePage resourcePage = resourcePageDao.getBySceneId(sceneId);
        if (null != resourcePage) {
            resourcePageVO.setShowBook(resourcePage.getShowBook());
            resourcePageVO.setOpenRays(resourcePage.getOpenRays());
            resourcePageVO.setOpenFood(resourcePage.getOpenFood());
            resourcePageVO.setStyle(resourcePage.getStyle());
            resourcePageVO.setQrcodeUrl(resourcePage.getQrcodeUrl());
            resourcePageVO.setId(resourcePage.getId());
            resourcePageVO.setBookCover(resourcePage.getBookCover());
            resourcePageVO.setBackgroundImg(resourcePage.getBackgroundImg());
            resourcePageVO.setNavigationColor(resourcePage.getNavigationColor());
            resourcePageVO.setNavigationFormat(resourcePage.getNavigationFormat());
            resourcePageVO.setFontColor(resourcePage.getFontColor());
            resourcePageVO.setWatermark(resourcePage.getWatermark());
            resourcePageVO.setWatermarkStyle(resourcePage.getWatermarkStyle());
            resourcePageVO.setLandingPageType(resourcePage.getLandingPageType());
            resourcePageVO.setTransparency(resourcePage.getTransparency());
            resourcePageVO.setNavigationJumpType(resourcePage.getNavigationJumpType());
            resourcePageVO.setIsShowPrice(resourcePage.getIsShowPrice());
            IMaskFlag.Helper helper = IMaskFlag.Helper.of(resourcePage.getSwitchConfig());
            resourcePageVO.setShowSelf(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_SELF));
            resourcePageVO.setShowCollect(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_COLLECT));
            resourcePageVO.setShowShare(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.SHOW_SHARE));
            resourcePageVO.setNewEditor(helper.checkFlagEnable(ResourcePageSwitchConfigEnum.NEW_EDITOR));
        }
        //小程序
        resourcePageVO.setAppletId(bookAppletSceneDao.getAppletIdBySceneId(sceneId));

        Map<Long, QrcodeSceneDto> qrcodeSceneDtoMap = new HashMap<>();
        try {
            qrcodeSceneDtoMap = qrcodeFuture.get(ThreadPoolUtils.REMOTE_TIME_OUT,TimeUnit.SECONDS);
        }catch (Exception e) {
            log.error("查二维码失败"+e.getMessage(),e);
        }
        if (!MapUtils.isEmpty(qrcodeSceneDtoMap) && qrcodeSceneDtoMap.containsKey(sceneId)) {
            QrcodeSceneDto qrcodeSceneDto = qrcodeSceneDtoMap.get(sceneId);
            Long bookId = qrcodeSceneDto.getAdviserBookId();
            resourcePageVO.setBookId(bookId);
            resourcePageVO.setAdviserId(qrcodeSceneDto.getCreatedByUserLogin());
            resourcePageVO.setChannelId(qrcodeSceneDto.getChannelPartyId());
            resourcePageVO.setQrcodeName(qrcodeSceneDto.getSceneName());
            if (null != bookId) {
                BookDto bookDto = bookBiz.getBaseById(bookId);
                if (null != bookDto) {
                    resourcePageVO.setBookImg(bookDto.getCoverImg());
                    resourcePageVO.setBookName(bookDto.getBookName());
                }
            }
        }
        Long adviserId = resourcePageVO.getAdviserId();
        CompletableFuture<Map<Long, AdviserBaseInfoDto>> agentFuture = CompletableFuture.supplyAsync(() -> {
            return adviserConsr.getAdviserId2AdviserInfoDtoMap(null == adviserId?new ArrayList<>():Arrays.asList(adviserId));
        });
        CompletableFuture<AccountSettingDto> accountSettingFuture = CompletableFuture.supplyAsync(() -> {
            return qrcodeSceneConsr.getWechatInfo(resourcePageVO.getChannelId());
        });

        CompletableFuture.allOf(agentFuture, accountSettingFuture).join();

        Map<Long, AdviserBaseInfoDto> agentMap = new HashMap<>();
        AccountSettingDto accountSettingDto = new AccountSettingDto();
        try {
            agentMap = agentFuture.get(ThreadPoolUtils.REMOTE_TIME_OUT,TimeUnit.SECONDS);
            accountSettingDto = accountSettingFuture.get(ThreadPoolUtils.REMOTE_TIME_OUT,TimeUnit.SECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            log.error("查询出版社/公众号失败"+e.getMessage(),e);
        }
        if (!MapUtils.isEmpty(agentMap)) {
            resourcePageVO.setAgentName(Optional.ofNullable(agentMap.get(adviserId)).orElseGet(AdviserBaseInfoDto::new).getAgentName());
        }
        if(accountSettingDto != null){
            resourcePageVO.setAccountSettingId(accountSettingDto.getAccountSettingId());
        }
        return resourcePageVO;
    }

    /**
     * 栏目重新排序
     * @author：zhuyajie
     * @date：2021/4/14 10:37
     *  * @param null
     */
    private void updateSeq4Batch(Long resourcePageId, Long navigationId) {
        List<ResourceColumnAndServeVO> serveVOS = resourcePageColumnDao.getColumnListByPageId(resourcePageId, navigationId,null);
        if (ListUtils.isEmpty(serveVOS)) {
            return;
        }
        for (ResourceColumnAndServeVO serveVO : serveVOS) {
            serveVO.setColumnSeq(serveVOS.indexOf(serveVO) + 1);
        }
        resourcePageColumnDao.updateSeq4Batch(serveVOS);
    }

    @Override
    public Integer getResourceCounts(Long bookId, Long adviserId, Long channelId) {
        ResourcePage resourcePage = resourcePageDao.getByBookId(bookId, channelId, adviserId);
        if (null == resourcePage) {
            return 0;
        }
        Integer count = resourcePageItemDao.getResourceCounts(resourcePage.getId());
        return count;
    }

    @Override
    public List<BookGroupServe> getServeListByBookGroupId(Long bookGroupId) {
        return resourcePageItemDao.getServeListByBookGroupId(bookGroupId);
    }

    @Override
    public void batchUpdateResourceUrl(List<Long> sceneIdList) {
        if (ListUtils.isEmpty(sceneIdList)) {
            return;
        }
        List<ResourcePageUrlDTO> itemList = resourcePageItemDao.getServeUrl4Update(sceneIdList);
        if (ListUtils.isEmpty(itemList)) {
            return;
        }
        List<ResourcePageUrlDTO> updateList = new ArrayList<>();
        for (ResourcePageUrlDTO dto : itemList) {
            if (StringUtil.isEmpty(dto.getLinkUrl())) {
                continue;
            }
            String url = dto.getLinkUrl();
            //sceneId参数不对
            if (url.contains("sceneId")) {
                String sceneParam = url.substring(url.indexOf("sceneId"));
                if (sceneParam.contains("&")) {
                    sceneParam = sceneParam.substring(0, sceneParam.indexOf("&"));
                }
                if (!StringUtil.isEmpty(sceneParam)) {
                    String newParam = "sceneId=" + dto.getSceneId();
                    url = url.replace(sceneParam, newParam);
                }
            } else {
                //不含sceneId
                if (url.contains("?")) {
                    url = url + "&sceneId=" + dto.getSceneId();
                } else {
                    url = url + "?sceneId=" + dto.getSceneId();
                }
            }
            dto.setLinkUrl(url);
            updateList.add(dto);
        }
        if (!ListUtils.isEmpty(updateList)) {
            resourcePageItemDao.batchUpdateServeUrlById(updateList);
        }
    }

    @Override
    public ResourcePageVO getResourcePageByBookIdAndChannelId(Long bookId, Long channelId) {
        ResourcePageVO resourcePageVO = new ResourcePageVO();
        ResourcePage resourcePage = resourcePageDao.getByBookId(bookId, channelId, null);
        if (null != resourcePage) {
            BeanUtils.copyProperties(resourcePage, resourcePageVO);
        }
        return resourcePageVO;
    }


    private String getDefaultBigPic(String productTypeCode) {
       if (StringUtil.isEmpty(productTypeCode)) {
           return null;
       }
       if (ProductTypeConstant.ATTENDANCE_TASK.equalsIgnoreCase(productTypeCode)) {
           return "https://oss.5rs.me/oss/uploadfe/jpg/439fc2ce08a39581591f0d51784cf1ce.jpg";
       } else if (ProductTypeConstant.QANEWS.equalsIgnoreCase(productTypeCode)) {
           return "https://file.5rs.me/oss/uploadfe/jpg/9476eaf59a23eef05e67b10fb8c3e987.jpg";
       } else if (ProductTypeConstant.SUBJECTNOTE_APP.equalsIgnoreCase(productTypeCode)) {
           return "https://oss.5rs.me/oss/uploadfe/png/7828df80a6f236f5c5534152a2371075.png";
       } else if (ProductTypeConstant.LIVE.equalsIgnoreCase(productTypeCode)) {
           return "https://oss.5rs.me/oss/uploadfe/jpg/675e741e5a40e01b9fc4dd22de6f6bc4.jpg";
       }
       return null;
    }

    @Override
    public List<BookGroupServe> getServeListByBookGroupAndSceneIds(List<Long> bookGroupIds, List<Long> sceneIds) {
        List<BookGroupServe> list = new ArrayList<>();
        List<BookGroupServe> bookGroupServeList = new ArrayList<>();
        if (!ListUtils.isEmpty(bookGroupIds)) {
            bookGroupServeList = resourcePageItemDao.getServeListByBookGroupIds(bookGroupIds);
        }
        List<BookGroupServe> sceneServeList = new ArrayList<>();
        if (!ListUtils.isEmpty(sceneIds)) {
            sceneServeList = resourcePageItemDao.getServeListBySceneIds(sceneIds);
        }
        list.addAll(ListUtils.isEmpty(bookGroupServeList) ? new ArrayList<>() : bookGroupServeList);
        list.addAll(ListUtils.isEmpty(sceneServeList) ? new ArrayList<>() : sceneServeList);
        return list;
    }

    @Override
    public ResourcePageOneServe hasOneResource(Long bookGroupId, Long sceneId, Long wechatUserId, Boolean ignoreRays) {
        ignoreRays = BooleanUtils.toBoolean(ignoreRays);
        ResourcePageOneServe pageOneServe = new ResourcePageOneServe();
        pageOneServe.setBookGroupId(bookGroupId);
        pageOneServe.setSceneId(sceneId);
        pageOneServe.setOneServe(false);
        ResourcePage resourcePage = null;
        if (null != bookGroupId) {
            resourcePage = resourcePageDao.getByBookGroupId(bookGroupId);
            BookGroupDTO bookGroupDTO = bookGroupDao.getDTOById(bookGroupId);
            pageOneServe.setJumpType(null == bookGroupDTO? null:bookGroupDTO.getJumpType());
            pageOneServe.setQrcodeType("own");
        } else if (null != sceneId) {
            resourcePage = resourcePageDao.getBySceneId(sceneId);
            QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getOnlySceneInfoById(sceneId);
            pageOneServe.setQrcodeType(null == qrcodeSceneDto?"ali":qrcodeSceneDto.getQrcodeType());
        }
        if (null != resourcePage) {
            Long resourcePageId = resourcePage.getId();
            pageOneServe.setResourcePageId(resourcePageId);
            pageOneServe.setAdviserId(resourcePage.getCreateUser());
            pageOneServe.setNavigationJumpType(resourcePage.getNavigationJumpType());
            //只配置了1个应用作品，且不开启小睿
            ResourcePageItemVO itemVO = resourcePageItemDao.checkOneServeItemByPageId(resourcePageId, ignoreRays);
            ResourcePageItemVO folderItemVO = resourcePageFolderItemMapper.checkOneServeItemByPageId(resourcePageId, ignoreRays);
            // 同时只能存在一个应用作品
            if (BooleanUtils.xor(new boolean[]{Objects.nonNull(itemVO), Objects.nonNull(folderItemVO)})) {
                itemVO = Optional.ofNullable(itemVO).orElse(folderItemVO);
                pageOneServe.setOneServe(!StringUtils.equalsAny(itemVO.getTypeCode(), "PHOTOGRAPH", "AI_TIKU", "APPLET_CLOCK", "APPLET_QA", "APPLET_WORD"));
                if (itemVO.getServeType().equals(ServeTypeEnum.RESOURCE.getValue())) {
                    fillFileResource(Arrays.asList(itemVO), wechatUserId);
                } else {
                    fillAppProductServe(Arrays.asList(itemVO), wechatUserId);
                }
                pageOneServe.setServeId(itemVO.getServeId());
                pageOneServe.setServeType(itemVO.getServeType());
                pageOneServe.setLinkUrl(itemVO.getLinkUrl());
                pageOneServe.setTypeCode(itemVO.getTypeCode());
                pageOneServe.setResultUrl(itemVO.getResultUrl());
                pageOneServe.setHasThirdLink(itemVO.getHasThirdLink());
                pageOneServe.setServeName(itemVO.getServeName());
                pageOneServe.setPrice(itemVO.getPrice());
                pageOneServe.setHasOfficialAccountsTool(itemVO.getHasOfficialAccountsTool());
            }
        }
        return pageOneServe;
    }

    @Override
    public Map<Long, List<BookGroupServeDTO>> mapSceneServeList(List<Long> sceneIds) {
        Map<Long, List<BookGroupServeDTO>> map = new HashMap<>();
        if (ListUtils.isEmpty(sceneIds)) {
            return map;
        }
        List<BookGroupServe> sceneServeList = resourcePageItemDao.getServeListBySceneIds(sceneIds);
        if (ListUtils.isEmpty(sceneServeList)) {
            return map;
        }
        List<ResourcePageItemVO> itemVOS = new ArrayList<>();
        sceneServeList.stream().forEach(s->{
            ResourcePageItemVO itemVO = new ResourcePageItemVO();
            itemVO.setServeId(s.getServeId());
            itemVO.setServeType(s.getServeType());
            itemVO.setLinkUrl(s.getServeUrl());
            itemVO.setTypeCode(s.getTypeCode());
            itemVO.setSceneId(s.getSceneId());
            itemVO.setResourcePageId(s.getResourcePageId());
            itemVOS.add(itemVO);
        });
        fillAppProductServe(itemVOS, null);
        fillFileResource(itemVOS,null);
        List<BookGroupServeDTO> serveDTOS = new ArrayList<>();
        for (ResourcePageItemVO itemVO: itemVOS) {
            BookGroupServeDTO serveDTO = new BookGroupServeDTO();
            serveDTO.setServeId(itemVO.getServeId());
            serveDTO.setServeType(itemVO.getServeType());
            serveDTO.setServeUrl(itemVO.getLinkUrl());
            serveDTO.setTypeCode(itemVO.getTypeCode());
            serveDTO.setServeName(itemVO.getServeName());
            serveDTO.setPicUrl(itemVO.getServePic());
            serveDTO.setTransverseImg(itemVO.getTransverseImg());
            serveDTO.setTypeName(itemVO.getTypeName());
            serveDTO.setSceneId(itemVO.getSceneId());
            serveDTOS.add(serveDTO);
        }
        map = serveDTOS.stream().collect(Collectors.groupingBy(BookGroupServeDTO::getSceneId));
        return map;
    }

    @Override
    public ResourcePage getPageByOfficialScene(Long officialSceneId) {
        return resourcePageDao.getPageByOfficialScene(officialSceneId);
    }

    @Override
    public void addCollectRecord(ResourcePageCollect resourcePageCollect) {
        if (null == resourcePageCollect.getResourcePageId() || null == resourcePageCollect.getCollectState()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少参数");
        }
        resourcePageCollectDao.insert(resourcePageCollect);
    }

    /**
     * 同步RAYS码资源配置
     * @author：zhuyajie
     * @date：2021/4/28 10:42
     *  * @param null
     */
    private void updateOwnMessage4Qr(Long sceneId) {
        log.info("同步RAYS码资源配置，sceneId=" + sceneId);
        if (null == sceneId) {
            return;
        }
        OwnQrcodeMessageDTO ownMessageDTO = new OwnQrcodeMessageDTO();
        ownMessageDTO.setSceneId(sceneId);
        //消息队列处理
        amqpTemplate.convertAndSend(MQTopicProducer.EXCHAGE, MqConstants.OWN_MESSAGE_4QRCODE, ownMessageDTO);
    }


    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    /**
     * 需要同步到channel的资源
     * @author：zhuyajie
     * @date：2021/9/28 10:12
     *  * @param null
     */
    @Override
    public List<MessagServeDTO> getServeListBySceneId4QrUpdate(Long sceneId) {
        List<ResourcePageItemVO> itemVOS = resourcePageItemDao.getServeListBySceneId4QrUpdate(sceneId);
        itemVOS = ListUtils.isEmpty(itemVOS)?new ArrayList<>():itemVOS;
        List<ResourcePageItemVO> folderItemVOS = resourcePageFolderItemMapper.getServeListBySceneId4QrUpdate(sceneId);
        itemVOS.addAll(ListUtils.isEmpty(folderItemVOS)?new ArrayList<>():folderItemVOS);
        itemVOS = itemVOS.stream().filter(Objects::nonNull)
                .sorted(Comparator.comparing(ResourcePageItemVO::getColumnSeq)
                        .thenComparing(
                                x->Optional.ofNullable(x.getFolderNum()).orElse(Integer.MAX_VALUE)
                        ).thenComparing(ResourcePageItemVO::getServeId))
                .filter(distinctByKey(ResourcePageItemVO::getServeId))
                .collect(Collectors.toList());

        if (ListUtils.isEmpty(itemVOS)) {
            return new ArrayList<>();
        }
        Map<String, List<ResourcePageItemVO>> listMap = itemVOS.stream().collect(Collectors.groupingBy(ResourcePageItemVO::getServeType));
        for (Map.Entry<String, List<ResourcePageItemVO>> entry : listMap.entrySet()) {
            this.fillResourceByType(entry.getValue(), null, entry.getKey());
        }
        List<MessagServeDTO> messages = new ArrayList<>();
        for (ResourcePageItemVO itemVO: itemVOS) {
            MessagServeDTO message = new MessagServeDTO();
            message.setFromId(itemVO.getServeId());
            message.setFromType(itemVO.getTypeCode());
            message.setUrl(itemVO.getLinkUrl());
            message.setCoverImg(itemVO.getServePic());
            message.setPosterPicUrl(itemVO.getTransverseImg());
            message.setTitle(itemVO.getServeName());
            message.setShortTitle(itemVO.getTypeName());
            message.setTypeCode(itemVO.getServeType());
            messages.add(message);
        }
        return messages;
    }

    @Override
    public void batchAddResource(List<AddBookGroupServeDTO> list, Long adviserId) {
        if (ListUtils.isEmpty(list) || null == adviserId) {
            return;
        }
        for (AddBookGroupServeDTO bookGroupServeDTO : list) {
            this.addResource(bookGroupServeDTO, adviserId);
        }
    }

    private void addResource(AddBookGroupServeDTO addBookGroupServeDTO, Long adviserId) {
        if (null == addBookGroupServeDTO || null == addBookGroupServeDTO.getSceneId()) {
            return;
        }
        Long sceneId = addBookGroupServeDTO.getSceneId();
        ResourcePage resourcePage = resourcePageDao.getBySceneId(sceneId);
        if (null == resourcePage) {
            resourcePage = this.createDefaultResourcePage(null, adviserId, sceneId, 0, null);
        }
        Long resourcePageId = resourcePage.getId();
        // 配置资源支持指定栏目
        Integer columnType = Optional.ofNullable(addBookGroupServeDTO.getColumnType()).orElse(ResourcePageConstants.ColumnTypeEnum.APP_PRODUCT.getCode());
        //第一个可配置资源的导航
        Long navigationId=null;
        List<Integer> navigationTypes = Arrays.asList(ResourcePageConstants.NavigationTypeEnum.BOOK_SERVE.getCode(),
                ResourcePageConstants.NavigationTypeEnum.CUSTOM.getCode());
        List<ResourcePageNavigation> navigations = resourcePageNavigationDao.getByPageId(resourcePageId);
        for (ResourcePageNavigation navigation:navigations) {
            if (navigationTypes.contains(navigation.getNavigationType())) {
                navigationId = navigation.getId();
                break;
            }
        }
        if (null == navigationId) {
            navigationId = this.addDefaultBookServeNavigation(resourcePageId);
        }
        //获取该导航最后一个应用作品栏目
        List<ResourcePageColumn> columnList = resourcePageColumnDao.getByNavigation(navigationId);
        List<ResourcePageColumn> columns = columnList.stream().filter(s->columnType.equals(s.getColumnType())).collect(Collectors.toList());
        ResourcePageColumn column = null;
        List<ResourcePageItemVO> itemVOS = new ArrayList<>();
        if (!ListUtils.isEmpty(columns)) {
            column = columns.get(columns.size()-1);
            itemVOS = resourcePageItemDao.getResourcePageItemByColumnId(column.getId());
        }
        //资源
        ResourcePageItemVO vo = new ResourcePageItemVO();
        BeanUtils.copyProperties(addBookGroupServeDTO, vo);
        vo.setLinkUrl(addBookGroupServeDTO.getServeUrl());
        vo.setSeqNum(itemVOS.size() + 1);
        itemVOS.add(vo);
        //更新栏目
        UpdateResourceColumnVO columnVO = getColumnVO4ColumnType(columnType);
        if (Objects.nonNull(column)) {
            columnVO.setColumnFormat(column.getColumnFormat());
            columnVO.setColumnName(column.getColumnName());
            columnVO.setResourcePageColumnId(column.getId());
            columnVO.setShowMore(column.getShowMore());
            columnVO.setShowCount(column.getShowCount());
        }
        columnVO.setColumnType(columnType);
        columnVO.setCreateUser(adviserId);
        columnVO.setItemVOList(itemVOS);
        columnVO.setResourcePageId(resourcePageId);
        columnVO.setNavigationId(navigationId);
        this.updateResourceColumn(columnVO);
        this.updateQrcodeOneServe(null,addBookGroupServeDTO.getSceneId(),null);
    }

    private UpdateResourceColumnVO getColumnVO4ColumnType(Integer columnType) {
        UpdateResourceColumnVO columnVO = new UpdateResourceColumnVO();
        if (columnType == 7) {
            columnVO.setColumnFormat(2);
            columnVO.setColumnName("RAYS工具");
        } else {
            columnVO.setColumnFormat(1);
            columnVO.setColumnName("应用作品");
        }
        columnVO.setShowMore(false);
        return columnVO;
    }

    @Override
    public List<Long> getOpenRaysSceneIds(List<Long> sceneIds) {
        if (ListUtils.isEmpty(sceneIds)) {
            return new ArrayList<>();
        }
        return resourcePageDao.getOpenRaysSceneIds(sceneIds);
    }

    @Override
    public void batchUpdateSceneIdByBookGroup(List<AddBookGroupServeDTO> list) {
        if(ListUtils.isEmpty(list)) {
            return;
        }
        resourcePageDao.batchUpdateSceneIdByBookGroup(list);
    }

    @Override
    public List<Long> getSceneIdsByResourceId(Long resourceId) {
        //慎用。这个接口是给删除作品的时候用的
        //获取的同时。会删掉配置的资源。
        List<Long> result=resourcePageDao.getSceneIdsByResourceId(resourceId);
        if(CollectionUtil.isNotEmpty(result)){
            //删除配置的资源
            resourcePageItemDao.deleteByServeId(resourceId);
        }
        return result;
    }

    @Override
    public void batchUpdateBookId(List<BookSceneIdListDTO> requestDto) {
        if (ListUtils.isEmpty(requestDto)) {
            return;
        }
        List<BookSceneIdListDTO> sceneIdListDTOS = qrcodeSceneConsr.listSceneIds4Book(requestDto);
        if (ListUtils.isEmpty(sceneIdListDTOS)) {
            return;
        }
        for (BookSceneIdListDTO dto : sceneIdListDTOS) {
            List<Long> sceneIds = dto.getSceneIds();
            if (!ListUtils.isEmpty(sceneIds)) {
                resourcePageDao.updateBookBySceneIds(sceneIds, dto.getBookId(), dto.getChannelId());
                //删除缓存
                List<ResourcePage> list = resourcePageDao.getBySceneIds(sceneIds);
                if(CollUtil.isNotEmpty(list)){
                    list.forEach(e->{
                        delResourcePageToRedis(e);
                    });
                }
            }
        }
    }

    @Override
    public List<BookServeDTO> getBookAndBookGroupServeIds(Long adviserId, Long bookId, Long channelId) {
        ResourcePage resourcePage = resourcePageDao.getByBookId(bookId, channelId, adviserId);
        if (null == resourcePage) {
            return new ArrayList<>();
        }
        List<BookServeDTO> itemVOS = resourcePageItemDao.getAppServeByPage(resourcePage.getId());
        return itemVOS;
    }

    @Override
    public List<ResourcePageTool> getToolListByUser(Long wechatUserId, Long officialAccountsId) {
        Long gradeLabel = getUserGrade(wechatUserId, officialAccountsId);
        return resourcePageToolDao.getByUserLabel(gradeLabel);
    }

    @Override
    public List<Map<String, Object>> getResourceSourceTypeList(Long wechatUserId, Long officialAccountsId) {
        Long gradeLabel = getUserGrade(wechatUserId, officialAccountsId);
        for (ResourcePageConstants.CrowdSourceEnum crowdSourceEnum : ResourcePageConstants.CrowdSourceEnum.values()) {
            List<Integer> crowdTypes = Arrays.asList(crowdSourceEnum.getCrowdTypes());
            if (crowdTypes.contains(gradeLabel.intValue())) {
                List<Map<String, Object>> list = new ArrayList<>();
                for (ResourcePageConstants.ResourceSourceTypeEnum sourceTypeEnum : crowdSourceEnum.getSourceTypes()) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("sourceType", sourceTypeEnum.getCode());
                    map.put("sourceName", sourceTypeEnum.getName());
                    list.add(map);
                }
                return list;
            }
        }
        return new ArrayList<>();
    }

    @Override
    public Long getUserGrade(Long wechatUserId, Long officialAccountsId) {
        UserGradeLabelIdDTO userGradeLabelIdDTO = readerConsr.getUserGrade(wechatUserId, officialAccountsId);
        Long gradeLabel = 1L;
        if (null != userGradeLabelIdDTO && null != userGradeLabelIdDTO.getLabelId()) {
            gradeLabel = (null == userGradeLabelIdDTO.getParentId() ||
                    userGradeLabelIdDTO.getParentId() == 0) ? userGradeLabelIdDTO.getLabelId() : userGradeLabelIdDTO.getParentId();
        }
        return gradeLabel;
    }

    @Override
    public void insertCourseStatistic() {
        List<String> typeCodes = Arrays.asList("SCHEDUE", "VIDEO_SCHEDULE", "VIDEO", "LIVE_TIMETABLE");
        List<BrowseRecordStatisticDTO> statisticDTOS = browseRecordConsr.getResourceTopIn7Day4H5(typeCodes);
        if (ListUtils.isEmpty(statisticDTOS)) {
            return;
        }
        resourcePageCourseDao.deleteAll();
        List<ResourcePageCourse> courses = new ArrayList<>();
        for (BrowseRecordStatisticDTO dto:statisticDTOS) {
            ResourcePageCourse course = new ResourcePageCourse();
            course.setServeId(dto.getBrowseId());
            course.setServeName(dto.getBrowseName());
            course.setServeType(dto.getType());
            course.setTypeCode(dto.getTypeCode());
            course.setTypeName(dto.getTypeName());
            course.setAgentId(dto.getAgencyId());
            course.setChannelId(dto.getChannelId());
            course.setProLabelId(dto.getProLableId());
            course.setDepLableId(dto.getDepLableId());
            course.setPurLabelId(dto.getPurLableId());
            course.setBrowseCount(dto.getBrowseCount());
            courses.add(course);
        }
        resourcePageCourseDao.insert(courses);
    }

    @Override
    public PageBeanNew<ResourcePageCourseDTO> listCourseByUser(Long wechatUserId, Long officialAccountsId, Integer currentPage, Integer numPerPage) {
        UserGradeLabelIdDTO userGradeLabelIdDTO = readerConsr.getUserGrade(wechatUserId, officialAccountsId);
        Long gradeLabel = 11L;
        if(userGradeLabelIdDTO!=null &&  userGradeLabelIdDTO.getLabelId()!=null){
            gradeLabel =  userGradeLabelIdDTO.getLabelId();
        }
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("userGradeLabelId", gradeLabel);
        paramMap.put("sourceFrom", ResourcePageConstants.RecommendResourceFromEnum.HOT_COURSE.getCode());
        PageBeanNew<ResourcePageCourseDTO> pageBeanNew = resourcePageCourseDao.listPageNew(new PageParam(currentPage,numPerPage), paramMap,"listCourseByGradeLabelId");
        if (ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return new PageBeanNew<>(currentPage,numPerPage,pageBeanNew.getTotalCount(),new ArrayList<>());
        }
        List<ResourcePageCourseDTO> dtos = pageBeanNew.getRecordList();
        List<Long> appIds = new ArrayList<>();
        List<Long> productIds = new ArrayList<>();
        for (ResourcePageCourseDTO dto : dtos) {
            Long serveId = dto.getServeId();
            if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(dto.getServeType()) && !appIds.contains(serveId)) {
                appIds.add(serveId);
            }
            if (ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(dto.getServeType()) && !productIds.contains(serveId)) {
                productIds.add(serveId);
            }
        }
        Map<Long, AppDto> appDtoMap = appConsr.mapBaseByIds(appIds);
        Map<Long, ProductDto> productDtoMap = productConsr.getProBasesByIds(productIds);
        Long accountSettingId = BookProps.getOperateOfficalId();
        AccountSetting accountSetting = channelConsr.getAppInfo(accountSettingId);
        for (ResourcePageCourseDTO courseDTO : dtos) {
            Long serveId = courseDTO.getServeId();
            String serveType = courseDTO.getServeType();
            if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(serveType)
                    && !MapUtils.isEmpty(appDtoMap) && appDtoMap.containsKey(serveId)) {
                AppDto appDto = appDtoMap.get(courseDTO.getServeId());
                if (StringUtil.isEmpty(courseDTO.getServePic())) {
                    courseDTO.setServePic(appDto.getSquareImg());
                }
                courseDTO.setTransverseImg(appDto.getTransverseImg());
                courseDTO.setProLabelName(appDto.getProLabelName());
                courseDTO.setDepLabelName(appDto.getDepLabelName());
                courseDTO.setPurLabelName(appDto.getPurLabelName());
                //跳转链接
                String turnUrl = ServeLinkUtils.getCompleteLink(ResourcePageConstants.ServeTypeEnum.APP.getValue(), appDto.getTypeCode(),  appDto.getAppId().toString(),
                        appDto.getSceneCode(), appDto.getChannelId().toString(), appDto.getCreatedUser().toString(), null, accountSettingId.toString(),
                        accountSetting.getProtocol(), accountSetting.getDomain(), accountSetting.getFirstDomain(),
                        null != accountSetting.getRandom() ? accountSetting.getRandom().toString() : null);
                courseDTO.setResultUrl(turnUrl);

            } else if (ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(serveType)
                    && !MapUtils.isEmpty(productDtoMap) && productDtoMap.containsKey(serveId)) {
                ProductDto productDto = productDtoMap.get(courseDTO.getServeId());
                if (StringUtil.isEmpty(courseDTO.getServePic())) {
                    courseDTO.setServePic(productDto.getCoverImg());
                }
                courseDTO.setTransverseImg(StringUtil.isEmpty(productDto.getPicture1())?
                        getDefaultBigPic(courseDTO.getTypeCode()): productDto.getPicture1());
                List<ProductLabelDto> labelDtos = productDto.getProductLabels();
                if (!ListUtils.isEmpty(labelDtos)) {
                    courseDTO.setProLabelName(labelDtos.get(0).getProLabelName());
                    courseDTO.setDepLabelName(labelDtos.get(0).getDepLabelName());
                    courseDTO.setPurLabelName(labelDtos.get(0).getPurLabelName());
                }
                //跳转链接
                String turnUrl = ServeLinkUtils.getCompleteLink(ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue(), courseDTO.getTypeCode(), productDto.getProductId().toString(),
                        productDto.getProductSceneCode(), courseDTO.getChannelId().toString(), null, null, accountSettingId.toString(),
                        accountSetting.getProtocol(), accountSetting.getDomain(), accountSetting.getFirstDomain(),
                        null != accountSetting.getRandom() ? accountSetting.getRandom().toString() : null);
                courseDTO.setResultUrl(turnUrl);
            }
        }
        return pageBeanNew;
    }

    @Override
    public Long getGradeByGradeLabelId(Long graLabelId) {
        return resourcePageCourseDao.getGradeByGradeLabelId(graLabelId);
    }

    @Override
    public Long getGradeByDepLabelId(Long depLabelId) {
        return resourcePageCourseDao.getGradeByDepLabelId(depLabelId);
    }

    @Override
    public Boolean isOpenRaysBook(Long bookId, Long channelId, Long adviserId) {
        return resourcePageDao.isOpenRaysBook(bookId, channelId, adviserId);
    }

    @Override
    public Map<String, Object> getUserNewState(Long wechatUserId) {
        Integer notNew = resourcePageCollectDao.getUserIsNotNew(wechatUserId);
        Boolean isNew = notNew > 0 ? false : true;
        Map<String, Object> map = new HashMap<>();
        map.put("isNew", isNew);
        return map;
    }

    @Override
    public void addNewUserRecord(ResourcePageCollect resourcePageCollect) {
        if (null == resourcePageCollect.getIsNew()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少用户状态");
        }
        resourcePageCollectDao.insert(resourcePageCollect);
    }

    @Override
    public Boolean isOpenRaysScene(Long sceneId, Long bookGroupId) {
        ResourcePage resourcePage;
        if (null != sceneId) {
            resourcePage = resourcePageDao.getBySceneId(sceneId);
        } else if (null != bookGroupId) {
            resourcePage = resourcePageDao.getByBookGroupId(bookGroupId);
        } else {
            return false;
        }
        Integer openRays = (null == resourcePage || null == resourcePage.getOpenRays()) ? 0 : resourcePage.getOpenRays();
        return openRays > 0 ? true : false;
    }

    @Override
    public List<String> mapCatalogBook(List<Long> bookIds, Long adviserId) {
        List<Long> sceneIds = bookGroupDao.mapCatalogBook(bookIds,adviserId);
        if (CollUtil.isEmpty(sceneIds)) {
            return new ArrayList<>();
        }
        return channelConsr.getCatalog4SceneIds(sceneIds);
    }

    @Override
    public List<RaysSceneCatalogDto> listRaysSceneCatalogDto(List<Long> sceneIds) {
        return Optional.ofNullable(bookGroupDao.listRaysSceneCatalogDto(sceneIds)).orElse(new ArrayList<>());
    }


    @Override
    public Map<String, BookGroupServeCountDTO> mapRaysCodeServeCount(List<Long> adviserIds, List<Long> bookIds, List<Long> channelIds) {
        if(CollectionUtils.isEmpty(adviserIds) || CollectionUtils.isEmpty(bookIds) || CollectionUtils.isEmpty(channelIds)){
            return new HashMap<>();
        }
        return resourcePageDao.mapRaysCodeServeCount(adviserIds, bookIds, channelIds);
    }
    @Override
    public List<ResourcePageVO> getAllBook4OpenFood() {
        List<ResourcePageVO> resourcePageList = resourcePageDao.getAllBook4OpenFood();
        if(CollUtil.isEmpty(resourcePageList)){
            return CollUtil.toList();
        }
        List<Long> bookIds = resourcePageList.stream().map(x -> x.getBookId()).collect(Collectors.toList());
        if(CollUtil.isEmpty(bookIds)){
            return CollUtil.toList();
        }
        Map<Long, BookDto> mapBook = bookBiz.getListByIds(bookIds);
        for (ResourcePageVO vo : resourcePageList) {
            Long bookId = vo.getBookId();
            BookDto bookDto = mapBook.get(bookId);
            if(bookDto == null){
                continue;
            }
            vo.setBookName(bookDto.getBookName());
            vo.setBookImg(bookDto.getCoverImg());
        }
        return resourcePageList;
    }


    @Override
    public  Map<String, Object> hasOfficialAccountsTool(Long resourcePageId) {
        //是否有应用配了付费公众号工具
        List<Long> appIds = resourcePageItemDao.getAppIdsByPageId(resourcePageId);
        Boolean hasOfficialAccountsTool = false;
        Map<Long, Long> map = appConsr.getPayOfficialAccountsToolByAppIds(appIds);
        if (!MapUtils.isEmpty(map)) {
            hasOfficialAccountsTool = true;
        }
        Map<String, Object> result = new HashMap<>();
        result.put("hasOfficialAccountsTool", hasOfficialAccountsTool);
        return result;
    }

    @Override
    public void updateBookId(Long bookId, Long sceneId) {
        ResourcePage resourcePage = resourcePageDao.getBySceneId(sceneId);
        if (null != resourcePage) {
            resourcePageDao.updateBookIdBySceneId(bookId, sceneId);
            //删除缓存
            List<ResourcePage> list = resourcePageDao.getBySceneIds(CollUtil.newArrayList(sceneId));
            if(CollUtil.isNotEmpty(list)){
                list.forEach(e->{
                    delResourcePageToRedis(e);
                });
            }
        }
        QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getById(sceneId);
        Long bookGroupId = this.getBookGroupIdBySceneId(qrcodeSceneDto);
        if (null != bookGroupId) {
            bookGroupDao.updateBookIdById(bookGroupId, bookId);
        }
    }


    @Override
    public PageBeanNew listRecommendCourse4Pcloud(Integer currentPage, Integer numPerPage, String query) {
        //热门课程
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("query", query);
        paramMap.put("sourceFrom", ResourcePageConstants.RecommendResourceFromEnum.HOT_COURSE.getCode());
        PageBeanNew<ResourcePageCourseDTO> pageBeanNew = resourcePageCourseDao.listPageNew(new PageParam(currentPage,numPerPage), paramMap,"listCourse4Pcloud");
        if (ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return pageBeanNew;
        }
        fillHotCourse4Pcloud(pageBeanNew.getRecordList());
        return pageBeanNew;
    }

    @Override
    public PageBeanNew listRecommendResource4Pcloud(Integer currentPage, Integer numPerPage, String query, Integer sourceFrom) {
        if (null == sourceFrom) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数缺失");
        }
        if (ListUtils.isEmpty(ResourcePageConstants.RecommendResourceFromEnum.getSourceTypesByCode(sourceFrom))) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数有误");
        }
        //育儿宝库/搜教辅资料
        PageBeanNew  pageBeanNew = appletRecordAggrStatisBiz.getResource4H54Pcloud(currentPage, numPerPage, query, sourceFrom);
        return pageBeanNew;
    }

    @Override
    public void updateRecommendResource4Pcloud(ResourceRecomManage resourceRecomManage) {
        if (null == resourceRecomManage || null == resourceRecomManage.getSourceFrom()
                || null == resourceRecomManage.getServeId()
                || StringUtil.isEmpty(resourceRecomManage.getServeType())
                || null == resourceRecomManage.getTypeCode()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数缺失");
        }
        resourceRecomManageDao.deleteByServe(resourceRecomManage.getServeId(), resourceRecomManage.getServeType(),
                resourceRecomManage.getSourceFrom());
        if (null == resourceRecomManage.getShowState()) {
            resourceRecomManage.setShowState(1);
        }
        resourceRecomManageDao.insert(resourceRecomManage);
    }

    @Override
    public Map<Long, ResourceRecomManage> mapResourceRecomManage(List<Long> serveIds, String serveType, Integer sourceFrom) {
        if (ListUtils.isEmpty(serveIds) || StringUtil.isEmpty(serveType) || null == sourceFrom) {
            return new HashMap<>();
        }
        Map<Long, ResourceRecomManage> manageMap = resourceRecomManageDao.mapResourceRecomManage(serveIds, serveType, sourceFrom);
        return manageMap;
    }

    @Override
    public List<BookServeDTO> getBookAllServeIdsIncludeUrl(Long adviserId, Long bookId, Long channelId) {
        AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(channelId);
        if (null == accountSettingDto){
            return new ArrayList<>();
        }
        List<BookServeDTO> list = resourcePageItemDao.getBookAllServeIds(adviserId, bookId, channelId);
        if (ListUtils.isEmpty(list)) {
            return list;
        }
        for (BookServeDTO bookServeDTO:list) {
            String url = SendWeixinRequestTools.splitUrl(accountSettingDto, bookServeDTO.getUrl());
            bookServeDTO.setUrl(url);
        }
        return list;
    }

    /**
     * 热门课程
     * @author：zhuyajie
     * @date：2021/7/9 15:30
     *  * @param null
     */
    private void fillHotCourse4Pcloud(List<ResourcePageCourseDTO> recordList) {
        if (ListUtils.isEmpty(recordList)) {
            return;
        }
        List<Long> appIds = new ArrayList<>();
        List<Long> productIds = new ArrayList<>();
        for (ResourcePageCourseDTO dto : recordList) {
            Long serveId = dto.getServeId();
            if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(dto.getServeType()) && !appIds.contains(serveId)) {
                appIds.add(serveId);
            }
            if (ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(dto.getServeType()) && !productIds.contains(serveId)) {
                productIds.add(serveId);
            }
        }
        Map<Long, AppDto> appDtoMap = appConsr.mapBaseByIds(appIds);
        List<Long> adviserIds = MapUtils.isEmpty(appDtoMap)?new ArrayList<>():appDtoMap.values().stream().map(AppDto::getCreatedUser).distinct().collect(Collectors.toList());
        Map<Long, String> adviserMap = adviserConsr.getNames(adviserIds);
        Map<Long, ProductDto> productDtoMap = productConsr.getProBasesByIds(productIds);
        List<Long> merchantIds = MapUtils.isEmpty(productDtoMap)?new ArrayList<>():productDtoMap.values().stream().map(ProductDto::getCreatedUser).distinct().collect(Collectors.toList());
        Map<Long, String> merchantMap = merchantConsr.getNamesByIdList(merchantIds);
        for (ResourcePageCourseDTO courseDTO : recordList) {
            Long serveId = courseDTO.getServeId();
            String serveType = courseDTO.getServeType();
            if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(serveType)
                    && !MapUtils.isEmpty(appDtoMap) && appDtoMap.containsKey(serveId)) {
                AppDto appDto = appDtoMap.get(serveId);
                //平台端没给封面，取原有封面
                if (StringUtil.isEmpty(courseDTO.getServePic())) {
                    courseDTO.setServePic(appDto.getSquareImg());
                }
                courseDTO.setProLabelName(appDto.getProLabelName());
                courseDTO.setDepLabelName(appDto.getDepLabelName());
                courseDTO.setPurLabelName(appDto.getPurLabelName());
                courseDTO.setServeCreateUserId(appDto.getCreatedUser());
                //应用创建人名称
                if (!MapUtils.isEmpty(adviserMap) && adviserMap.containsKey(appDto.getCreatedUser())) {
                    courseDTO.setServeCreateUserName(adviserMap.get(appDto.getCreatedUser()));
                }
            } else if (ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(serveType)
                    && !MapUtils.isEmpty(productDtoMap) && productDtoMap.containsKey(serveId)) {
                ProductDto productDto = productDtoMap.get(serveId);
                if (StringUtil.isEmpty(courseDTO.getServePic())) {
                    courseDTO.setServePic(productDto.getCoverImg());
                }
                List<ProductLabelDto> labelDtos = productDto.getProductLabels();
                if (!ListUtils.isEmpty(labelDtos)) {
                    courseDTO.setProLabelName(labelDtos.get(0).getProLabelName());
                    courseDTO.setDepLabelName(labelDtos.get(0).getDepLabelName());
                    courseDTO.setPurLabelName(labelDtos.get(0).getPurLabelName());
                }
                courseDTO.setServeCreateUserId(productDto.getCreatedUser());
                if (!MapUtils.isEmpty(merchantMap) && merchantMap.containsKey(productDto.getCreatedUser())) {
                    courseDTO.setServeCreateUserName(merchantMap.get(productDto.getCreatedUser()));
                }
            }
        }
    }

    /**
     * 删除小程序默认导航
     * @author：zhuyajie
     * @date：2021/8/27 16:01
     *  * @param null
     */
    private void deleteAppletDefaultNavigation(Long resourcePageId) {
        //书友互助、阅读打卡
        List<Integer> types = ResourcePageConstants.APPLET_DEFAULT_NAVIGATIONS;
        for (Integer type :types){
            resourcePageNavigationDao.deleteNavigation(resourcePageId, type);
        }
    }


    /**
     * 添加本书配套导航
     * @author：zhuyajie
     * @date：2021/8/16 14:40
     *  * @param null
     */
    private Long addDefaultBookServeNavigation(Long resourcePageId) {
        ResourcePageNavigation resourcePageNavigation = resourcePageNavigationDao.getByType(resourcePageId,ResourcePageConstants.NavigationTypeEnum.BOOK_SERVE.getCode());
        if (null != resourcePageNavigation) {
            return null;
        }
        ResourcePage resourcePage = resourcePageDao.getById(resourcePageId);
        if (null == resourcePage) {
            return null;
        }
        ResourcePageNavigation navigation = new ResourcePageNavigation();
        navigation.setCreateUser(resourcePage.getCreateUser());
        navigation.setNavigationName(ResourcePageConstants.NavigationTypeEnum.BOOK_SERVE.getName());
        navigation.setNavigationSeq(1);
        navigation.setNavigationType(ResourcePageConstants.NavigationTypeEnum.BOOK_SERVE.getCode());
        navigation.setResourcePageId(resourcePageId);
        resourcePageNavigationDao.insert(navigation);
        return navigation.getId();
    }


    /**
     * 删除导航
     * @author：zhuyajie
     * @date：2021/8/17 17:15
     *  * @param null
     */
    private void deleteNavigation(Long navigationId) {
        ResourcePageNavigation resourcePageNavigation = resourcePageNavigationDao.getById(navigationId);
        if (null == resourcePageNavigation) {
            return;
        }
        List<Integer> types = Arrays.asList(ResourcePageConstants.NavigationTypeEnum.BOOK_SERVE.getCode());
        if (types.contains(resourcePageNavigation.getNavigationType())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"该导航不能删除");
        }
        resourcePageNavigationDao.deleteById(navigationId);
        //栏目
        List<ResourcePageColumn> resourcePageColumns = resourcePageColumnDao.getByNavigation(navigationId);
        if (!ListUtils.isEmpty(resourcePageColumns)) {
            for (ResourcePageColumn resourcePageColumn:resourcePageColumns) {
                //删除资源配置
                resourcePageItemDao.deleteByPageColumnId(resourcePageColumn.getId());
                //删除栏目
                resourcePageColumnDao.deleteById(resourcePageColumn.getId());
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveNavigation(NavigationParamDTO navigationParamDTO) {
        //参数校验
        this.checkNavigationList(navigationParamDTO);
        List<ResourcePageNavigation> originNavigationList = resourcePageNavigationDao.getByPageId(navigationParamDTO.getResourcePageId());
        //待删除导航
        List<Long> ids4Remove = ListUtils.isEmpty(originNavigationList) ? new ArrayList<>() : originNavigationList.stream().map(ResourcePageNavigation::getId).collect(Collectors.toList());
        for (ResourcePageNavigation navigation : navigationParamDTO.getNavigationList()) {
            if (null != navigation.getId()) {
                //修改
                resourcePageNavigationDao.update(navigation);
                if (!ListUtils.isEmpty(ids4Remove)) {
                    ids4Remove.remove(navigation.getId());
                }
            } else {
                //新增
                resourcePageNavigationDao.insert(navigation);
            }
        }
        //需要删除的导航
        if (!ListUtils.isEmpty(ids4Remove)) {
            for (Long navigationId : ids4Remove) {
                this.deleteNavigation(navigationId);
            }
            //同步RAYS码资源配置
            ResourcePage resourcePage = resourcePageDao.getById(navigationParamDTO.getResourcePageId());
            this.updateOwnMessage4Qr(null == resourcePage ? null : resourcePage.getSceneId());
        }
        //修改导航样式，版式，菜单跳转模式
        resourcePageDao.updateNavigationFormat(navigationParamDTO.getResourcePageId(), navigationParamDTO.getNavigationColor(),navigationParamDTO.getNavigationFormat(), navigationParamDTO.getNavigationJumpType());
    }

    private void checkNavigationList(NavigationParamDTO navigationParamDTO) {
        if (null == navigationParamDTO) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数缺失");
        }
        if (null == navigationParamDTO.getResourcePageId()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少resourcePageId");
        }
        if (ListUtils.isEmpty(navigationParamDTO.getNavigationList())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少导航");
        }
        List<String> names = new ArrayList<>();
        for (ResourcePageNavigation navigation:navigationParamDTO.getNavigationList()){
            navigation.setCreateUser(navigationParamDTO.getCreateUser());
            navigation.setResourcePageId(navigationParamDTO.getResourcePageId());
            this.checkNavigation(navigation);
            names.add(navigation.getNavigationName().trim());
        }
        if (names.size()<navigationParamDTO.getNavigationList().size()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"导航名称重复");
        }

    }

    private void checkNavigation(ResourcePageNavigation navigation) {
        if (null == navigation) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数缺失");
        }
        if (StringUtil.isEmpty(navigation.getNavigationName().trim())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少导航名称");
        }
        if (null == navigation.getResourcePageId()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少resourcePageId");
        }
        if (null == navigation.getNavigationSeq()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少排序值");
        }
        if (null == navigation.getNavigationType()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少导航类型");
        }
        List<Integer> types = Arrays.asList(ResourcePageConstants.NavigationTypeEnum.BOOK_SERVE.getCode(),ResourcePageConstants.NavigationTypeEnum.APPLET_QA.getCode());
        if (types.contains(navigation.getNavigationType()) && null == navigation.getId()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少导航id");
        }
    }

    @Override
    public void addNavigationPic(ResourcePagePic resourcePagePic) {
        if (StringUtil.isEmpty(resourcePagePic.getPicUrl())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少图片");
        }
        if (null == resourcePagePic.getAdviserId()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少编辑id");
        }
        resourcePagePic.setIsDefault(0);
        resourcePagePic.setType(1);
        resourcePagePicDao.insert(resourcePagePic);
    }

    @Override
    public void deleteNavigationPic(Long id) {
        ResourcePagePic resourcePagePic = resourcePagePicDao.getById(id);
        if (null == resourcePagePic) {
            return;
        }
        if (1 == resourcePagePic.getIsDefault()) {
            throw new BookBizException(BookBizException.ERROR,"默认图片不能删除");
        }
        resourcePagePicDao.deleteById(id);
    }

    @Override
    public PageBeanNew<ResourcePagePic> listNavigationPic(Long adviserId, Integer currentPage, Integer numPerPage) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("adviserId", adviserId);
        paramMap.put("type", 1);
        return resourcePagePicDao.listPageNew(new PageParam(currentPage,numPerPage), paramMap,"getByType");
    }

    @Override
    public void batchUpdateColumnSeq(List<Long> navigationIds) {
        if (ListUtils.isEmpty(navigationIds)) {
            return;
        }
        for (Long navigationId:navigationIds){
            ResourcePageNavigation navigation = resourcePageNavigationDao.getById(navigationId);
            if (null != navigation) {
                this.updateSeq4Batch(navigation.getResourcePageId(), navigationId);
            }
        }
    }

    @Override
    public ResourcePageItemVO getPopupQrcode4Wechat(Long resourcePageId, Long wechatUserId) {
        Boolean popupState = false;
        ResourcePageItemVO pageItemVO = resourcePageItemDao.getPopupQrcodeItem(resourcePageId);
        if (null == pageItemVO) {
            pageItemVO = new ResourcePageItemVO();
            pageItemVO.setPopupState(popupState);
            return pageItemVO;
        }
        String logoUrl = pageItemVO.getLogoUrl();
        Long accountSettingId = pageItemVO.getAccountSettingId();
        if (null == accountSettingId) {
            accountSettingId = BookProps.getOperateOfficalId();
        }
        QrcodeTemp qrcodeTemp = new QrcodeTemp();
        qrcodeTemp.setAccountSettingId(accountSettingId);
        qrcodeTemp.setCreatedUser(wechatUserId);
        qrcodeTemp.setPageId(resourcePageId);
        String qrcodeUrl = null;
        try {
            qrcodeUrl = qrcodeSceneConsr.createTempQrcode4H5(qrcodeTemp);
        } catch (Exception e) {
            log.warn("H5生成临时二维码失败"+e.getMessage());
            pageItemVO = new ResourcePageItemVO();
            pageItemVO.setPopupState(popupState);
            return pageItemVO;
        }
        //todo 每个人生成的码都缓存下来。如果公众号id。或者logoUrl变了。要删缓存。临时二维码有效期30天
        String tempKey=BookConstant.PAGE_ID_TEMP_CODE_CACHE+resourcePageId+"-"+accountSettingId+"-"+wechatUserId;
        String logoUrlKey=BookConstant.PAGE_ID_LOGOURL_CACHE+resourcePageId+"-"+accountSettingId+"-"+wechatUserId;
        String pageKey=BookConstant.PAGE_ID_CODE_CACHE+resourcePageId+"-"+accountSettingId+"-"+wechatUserId;
        if (!StringUtil.isEmpty(qrcodeUrl) && !StringUtil.isEmpty(logoUrl)) {
            String cacheQrcodeUrl = JedisClusterUtils.get(tempKey);
            String cacheLogoUrl = JedisClusterUtils.get(logoUrlKey);
            //qrcodeUrl 变了要重新生成
            if(StrUtil.isBlank(cacheQrcodeUrl)){
                JedisClusterUtils.set(tempKey,qrcodeUrl,60*60*24*30);
            }else{
                //如果缓存里面有值。然后就从缓存里面拿的和新拿到的qrcodeUrl比较。如果不同。说明原来的临时二维码到期了。重新生成了。那么都要重新生成一次
                if(!cacheQrcodeUrl.equalsIgnoreCase(qrcodeUrl)){
                    //重新生成
                    JedisClusterUtils.set(tempKey,qrcodeUrl,60*60*24*30);
                    qrcodeUrl = getQrcodeUrl(logoUrl, qrcodeUrl);
                    JedisClusterUtils.set(pageKey,qrcodeUrl,60*60*24*30);
                }
            }
            //logoUrl 变了也要重新生成
            if(StrUtil.isBlank(cacheLogoUrl)){
                JedisClusterUtils.set(logoUrlKey,qrcodeUrl,60*60*24*30);
            }else{
                //如果缓存里面有值。然后就从缓存里面拿的和新拿到的logoUrl比较。如果不同。说明变了logoUrl了。那么都要重新生成一次
                if(!cacheLogoUrl.equalsIgnoreCase(logoUrl)){
                    //重新生成
                    JedisClusterUtils.set(logoUrlKey,logoUrl,60*60*24*30);
                    qrcodeUrl = getQrcodeUrl(logoUrl, qrcodeUrl);
                    JedisClusterUtils.set(pageKey,qrcodeUrl,60*60*24*30);
                }
            }
            String cachePageUrl = JedisClusterUtils.get(pageKey);
            if(StrUtil.isNotBlank(cachePageUrl)){
                qrcodeUrl= cachePageUrl;
            }else {
                //添加Logo
                qrcodeUrl = getQrcodeUrl(logoUrl, qrcodeUrl);
                JedisClusterUtils.set(pageKey,qrcodeUrl,60*60*24*30);
            }
        }
        pageItemVO.setResultUrl(qrcodeUrl);
        if (!StringUtil.isEmpty(qrcodeUrl)) {
            popupState = true;
        }
        pageItemVO.setPopupState(popupState);
        pageItemVO.setLinkUrl(null);
        return pageItemVO;
    }

    private String getQrcodeUrl(String logoUrl, String qrcodeUrl) {
        String url = "";
        String tmpDirPath = FileUtil.getTmpDirPath();
        if (!tmpDirPath.endsWith(File.separator)) {
            tmpDirPath = tmpDirPath + File.separator;
        }
        File file = FileUtil.touch(tmpDirPath + UUIDUitl.generateShort() + ".png");
        HttpUtil.downloadFile(qrcodeUrl, file);
        try {
            url = QrCodeUtil.decode(file);
        } catch (QrCodeException e){
            log.info("解析二维码图片失败，qrcodeUrl：{}", qrcodeUrl);
        }
        qrcodeUrl = this.getLogoQrcode(url, logoUrl, qrcodeUrl);
        return qrcodeUrl;
    }

    @Override
    public ResourcePageDTO getResourcePageById(Long resourcePageId) {
        ResourcePageDTO resourcePageDTO = new ResourcePageDTO();
        ResourcePage resourcePage = resourcePageDao.getById(resourcePageId);
        if (null != resourcePage){
            BeanUtils.copyProperties(resourcePage, resourcePageDTO);
            if (null != resourcePage.getSceneId()) {
                QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getById(resourcePage.getSceneId());
                resourcePageDTO.setUrl(null == qrcodeSceneDto?null:qrcodeSceneDto.getUrl());
            } else if (null != resourcePage.getBookGroupId()) {
                BookGroupDTO dto = bookGroupDao.getDTOById(resourcePage.getBookGroupId());
                resourcePageDTO.setUrl(null == dto?null:dto.getGroupQrcodeLink());
            }
        }
        return resourcePageDTO;
    }


    @Override
    public List<String> getConfiguredRaysAppTypeCode(Long resourcePageColumnId) {
        return resourcePageItemDao.getConfiguredRaysAppTypeCode(resourcePageColumnId);
    }

    @Override
    public Boolean checkBookChildGrade(Long bookId, Long adviserId, Long channelId) {
        //获取书刊匹配的年级标签
        BookAdviserDto bookAdviserDto = bookAdviserBiz.getBase(bookId, channelId, adviserId);
        if (null == bookAdviserDto) {
            return false;
        }
        Long gradeId = null;
        if (null != bookAdviserDto.getGraLabelId()) {
            gradeId = this.getGradeByGradeLabelId(bookAdviserDto.getGraLabelId());
        }
        if (null != bookAdviserDto.getDepLabelId()) {
            gradeId = this.getGradeByDepLabelId(bookAdviserDto.getDepLabelId());
        }
        if (null == gradeId) {
            return false;
        }
        //小学段所有年级
        List<Long> gradeLabelIds = readerConsr.getUserGradeIdByParentId(2L);
        if (!ListUtils.isEmpty(gradeLabelIds) && gradeLabelIds.contains(gradeId)) {
            return true;
        }
        return false;
    }

    /**
     * 查询书刊推荐资源
     */
    @Override
    public List<RecommendServeVO> getBookRecommendServe(Long wechatUserId, Long bookId, Long adviserId, Long channelId,Long sceneId) {
        //1.首先查书刊是否开启了资源推荐
        OpenRecommendVO openRecommend=getRecommend(bookId,adviserId,channelId,sceneId);
        if(null==openRecommend || null==openRecommend.getIsOpenRecommend() || 0==openRecommend.getIsOpenRecommend()){
            return null;
        }
        //2.从系统数据表里面查到推荐资源，填充资源信息
        List<RecommendServeDto> serveList = bookRecommendBiz.getById(bookId, channelId, adviserId, openRecommend.getRecommendFromType());
        if(CollUtil.isEmpty(serveList)){
            return null;
        }
        //3.填充服务信息。以及channel对应的公众号信息
        List<RecommendServeVO> result = getRecommendServeVOS(channelId, serveList);
        return result;
    }

    private OpenRecommendVO getRecommend(Long bookId, Long adviserId, Long channelId,Long sceneId){
        OpenRecommendVO openRecommend=null;
        if (null != bookId) {
            openRecommend =  bookAdviserBiz.getOpenRecommend(null, bookId, adviserId, channelId);
        } else if (null != sceneId) {
            //根据sceneId获取二维码信息
            Map<Long, QrcodeSceneDto> qrcodeSceneDtoMap = qrcodeSceneConsr.listBaseInfoByIds(Lists.newArrayList(sceneId));
            if (MapUtils.isEmpty(qrcodeSceneDtoMap) || null == qrcodeSceneDtoMap.get(sceneId)) {
                return null;
            }
            QrcodeSceneDto qrcodeSceneDto = qrcodeSceneDtoMap.get(sceneId);
            if (null == qrcodeSceneDto || null == qrcodeSceneDto.getAdviserBookId()) {
                return null;
            }
            openRecommend = bookAdviserBiz.getOpenRecommend(null,qrcodeSceneDto.getAdviserBookId(), qrcodeSceneDto.getCreatedByUserLogin(),qrcodeSceneDto.getChannelPartyId());
        }
        return openRecommend;
    }

    /**
     *  客户端-查询应用或作品推荐资源
     */
    @Override
    public List<RecommendServeVO> getAppRecommendServe(Long wechatUserId, Long bookId, Long adviserId, Long channelId, Long serveId, String serveType,Long sceneId) {
        //1.首先查书刊是否开启了资源推荐
        OpenRecommendVO openRecommend=getRecommend(bookId,adviserId,channelId,sceneId);
        if(null==openRecommend || null==openRecommend.getIsOpenRecommend() || 0==openRecommend.getIsOpenRecommend()){
            return null;
        }
        //2.从系统数据表里面查到推荐资源，填充资源信息
        List<RecommendServeDto> serveList = bookRecommendBiz.getByServeId(adviserId,serveId,serveType,openRecommend.getRecommendFromType());
        if(CollUtil.isEmpty(serveList)){
            return null;
        }
        //3.填充服务信息。以及channel对应的公众号信息
        List<RecommendServeVO> result = getRecommendServeVOS(channelId, serveList);
        return result;
    }

    private List<RecommendServeVO> getRecommendServeVOS(Long channelId, List<RecommendServeDto> serveList) {
        List<Long> superMerchantIdList = merchantConsr.getSuperMerchantIdList();
        List<Long> superProductIds = new ArrayList<>();
        List<Long> appIds = new ArrayList<>();
        List<Long> productIds = new ArrayList<>();
        serveList.stream().forEach(e -> {
            if ("APP".equalsIgnoreCase(e.getServeType())) {
                appIds.add(e.getServeId());
            }
            if ("PRODUCT".equalsIgnoreCase(e.getServeType())) {
                productIds.add(e.getServeId());
            }
        });
        Map<Long, AppDto> appDtoMap = appConsr.getBaseByIds(appIds);
        Map<Long, ProductDto> productDtoMap = productConsr.getProBasesByIds(productIds);
        List<Long> channelIds=new ArrayList<>();
       /* if(CollUtil.isNotEmpty(appDtoMap)){
            for (AppDto appDto : appDtoMap.values()) {
                if(null!=appDto.getChannelId()){
                    channelIds.add(appDto.getChannelId());
                }
            }
        }
        if(CollUtil.isNotEmpty(productDtoMap)){
            for (ProductDto productDto : productDtoMap.values()) {
                if(null!=productDto.getChannelId()){
                    channelIds.add(productDto.getChannelId());
                }
            }
        }*/
        Map<Long, AccountSettingDto> map = channelConsr.listWechatAccountInfo(Lists.newArrayList(channelId));
        List<RecommendServeVO> result = new ArrayList<>();
        RecommendServeVO recommendServeVO;
        for (RecommendServeDto dto : serveList) {
            if (StrUtil.isBlank(dto.getServeType()) || null == dto.getServeId()) {
                continue;
            }
            recommendServeVO = new RecommendServeVO();
            if ("APP".equalsIgnoreCase(dto.getServeType()) && CollUtil.isNotEmpty(appDtoMap) && appDtoMap.containsKey(dto.getServeId())) {
                AppDto appDto = appDtoMap.get(dto.getServeId());
                recommendServeVO.setServeId(dto.getServeId());
                recommendServeVO.setServeType("APP");
                if (null != appDto) {
                    if(null!=appDto.getIsDelete() && YesOrNoNumEnum.YES.getValue().equals(appDto.getIsDelete())){
                        continue;
                    }
                    if(null!=appDto.getAuditState() && !YesOrNoNumEnum.YES.getValue().equals(appDto.getAuditState())){
                        continue;
                    }
                    recommendServeVO.setServeName(appDto.getTitle());
                    recommendServeVO.setServePic(appDto.getSquareImg());
                    recommendServeVO.setTransverseImg(appDto.getTransverseImg());
                    recommendServeVO.setTypeCode(appDto.getTypeCode());
                    recommendServeVO.setTypeName(appDto.getTypeName());
                    recommendServeVO.setPrice(null == appDto.getRetailPrice() ? new BigDecimal(0) : appDto.getRetailPrice());
                    recommendServeVO.setHasThirdLink(!StringUtil.isEmpty(appDto.getTurnUrl()) ? true : false);
                }
            }
            if ("PRODUCT".equalsIgnoreCase(dto.getServeType()) && CollUtil.isNotEmpty(productDtoMap) && productDtoMap.containsKey(dto.getServeId())) {
                ProductDto productDto = productDtoMap.get(dto.getServeId());
                recommendServeVO.setServeId(dto.getServeId());
                recommendServeVO.setServeType("PRODUCT");
                if (null != productDto) {
                    if(CollUtil.isNotEmpty(superMerchantIdList) && superMerchantIdList.contains(productDto.getCreatedUser())){
                        superProductIds.add(productDto.getProductId());
                    }
                    if(null!=productDto.getIsDelete() && YesOrNoNumEnum.YES.getValue().equals(productDto.getIsDelete())){
                        continue;
                    }
                    if(null!=productDto.getSaleState() && !"1".equals(productDto.getSaleState())){
                        continue;
                    }
                    if(null!=productDto.getSaleStartDate() && productDto.getSaleStartDate().after(new Date())){
                        continue;
                    }
                    if(null!=productDto.getSaleEndDate() && productDto.getSaleEndDate().before(new Date())){
                        continue;
                    }
                    recommendServeVO.setServeName(productDto.getProductName());
                    recommendServeVO.setServePic(productDto.getCoverImg());
                    recommendServeVO.setTransverseImg(productDto.getPicture1());
                    recommendServeVO.setTypeCode(productDto.getProductTypeCode());
                    recommendServeVO.setTypeName(productDto.getProductTypeName());
                    if (productDto.getProductTypeDto() != null) {
                        recommendServeVO.setTypeCode(productDto.getProductTypeDto().getTypeCode());
                        recommendServeVO.setTypeName(productDto.getProductTypeDto().getTypeName());
                    }
                    if (!ListUtils.isEmpty(productDto.getSpecification())) {
                        Double advisePrice = productDto.getSpecification().get(0).getAdvisePrice();
                        recommendServeVO.setPrice(new BigDecimal(advisePrice));
                    }
                    recommendServeVO.setTransverseImg(StringUtil.isEmpty(productDto.getPicture1()) ?
                            getDefaultBigPic(recommendServeVO.getTypeCode()) : productDto.getPicture1());
                    recommendServeVO.setHasThirdLink(!StringUtil.isEmpty(productDto.getSkipUrl()) ? true : false);
                }
            }
            if(StrUtil.isBlank(recommendServeVO.getServeName())){
                continue;
            }
            if (CollUtil.isNotEmpty(map) && map.containsKey(channelId)) {
                recommendServeVO.setChannelId(channelId);
                AccountSettingDto  accountSettingDto = map.get(channelId);
                if (null != accountSettingDto) {
                    recommendServeVO.setAccountSettingId(accountSettingDto.getAccountSettingId());
                    recommendServeVO.setAppDomain("weixin" + (accountSettingDto.getRandom() == null ? accountSettingDto.getAccountSettingId() : accountSettingDto.getRandom()) + "." + accountSettingDto.getFirstDomain());
                    recommendServeVO.setDomain(accountSettingDto.getDomain());
                    recommendServeVO.setFirstDomain(accountSettingDto.getFirstDomain());
                    recommendServeVO.setRandom(accountSettingDto.getRandom());
                    recommendServeVO.setProtocol(accountSettingDto.getProtocol());
                }
            }
            result.add(recommendServeVO);
        }
        //超级作者作品自动上架
        if(CollUtil.isNotEmpty(superProductIds)){
            ThreadPoolUtils.OTHER_POOL.execute(()-> {
                productConsr.productAutoOnShelves(channelId,superProductIds);
            });
        }
        return result;
    }

    @Override
    public void updateLandingPageType(Long sceneId, Integer landingPageType) {
        ResourcePage resourcePage = resourcePageDao.getBySceneId(sceneId);
        if (null == resourcePage || null == landingPageType) {
            return;
        }
        if (null != resourcePage.getLandingPageType() && resourcePage.getLandingPageType().equals(landingPageType)) {
            return;
        }
        resourcePage.setLandingPageType(landingPageType);
        resourcePage.setOpenRays(0);
        resourcePage.setOpenFood(0);
        resourcePageDao.update(resourcePage);
        //删除缓存
        delResourcePageToRedis(resourcePage);
        ThreadPoolUtils.RESOURCE_POOL.execute(()->{
            //同步到chanelcenter
            qrcodeSceneConsr.updateLandingPageType(sceneId, landingPageType);
            //清空之前的配置资源
            if (PageLandingPageTypeEnum.WXWORK.getCode().equals(landingPageType)) {
                List<ResourcePageNavigation> navigations = resourcePageNavigationDao.getByPageId(resourcePage.getId());
                List<Long> navigationIds = navigations.stream().filter(s->!s.getNavigationType().equals(ResourcePageConstants.NavigationTypeEnum.BOOK_SERVE.getCode())).map(ResourcePageNavigation::getId).collect(Collectors.toList());
                if (!ListUtils.isEmpty(navigationIds)) {
                    for (Long id:navigationIds) {
                        this.deleteNavigation(id);
                    }
                }
                // TODO@guiq 删除新版组件
                resourcePageBookstoreBiz.deleteByResourcePageId(resourcePage.getId(), null);
            }
        });
    }

    @Override
    public void createWxworkPage(WxworkPageCreateVO wxworkPageCreateVO) {
        this.checkWxworkPageCreate(wxworkPageCreateVO);
        Long resourcePageId = wxworkPageCreateVO.getResourcePageId();
        Integer templateType = wxworkPageCreateVO.getTemplateType();

        ResourcePageWxwork resourcePageWxwork = new ResourcePageWxwork();
        BeanUtils.copyProperties(wxworkPageCreateVO,resourcePageWxwork);
        //自定义存下高度
        // 新版直接存储自定义配置到 fixed_set 字段
        if (ResourcePageConstants.WxworkPageTemplateTypeEnum.CUSTOM.getCode().equals(templateType)) {
            resourcePageWxwork.setFixedSet(JSON.toJSONString(wxworkPageCreateVO.getConfig()));
        } else if (null != wxworkPageCreateVO.getFixedDTO()) { //资源模板参数json存放
            resourcePageWxwork.setFixedSet(JSONUtils.toJsonString(wxworkPageCreateVO.getFixedDTO()));
        }
        ResourcePageWxwork pageWxwork = resourcePageWxworkDao.getByPageId(resourcePageId);
        if (null != pageWxwork) {
            resourcePageWxwork.setId(pageWxwork.getId());
            resourcePageWxworkDao.update(resourcePageWxwork);
        } else {
            resourcePageWxworkDao.insert(resourcePageWxwork);
        }

        if (ResourcePageConstants.WxworkPageTemplateTypeEnum.CUSTOM.getCode().equals(templateType)) {
            ResourcePage resourcePage = resourcePageDao.getById(resourcePageId);
            if (resourcePage == null || resourcePage.getSceneId() == null) {
                return;
            }
            ResourcePageShare resourcePageShare = shareMapper.selectByResourcePageId(resourcePage.getSceneId());
            if (resourcePageShare == null) {
                ResourcePageShare pageShare = new ResourcePageShare();
                pageShare.setCreateUser(wxworkPageCreateVO.getCreateUser());
                pageShare.setUpdateUser(wxworkPageCreateVO.getCreateUser());
                String shareTitle = Optional.ofNullable(wxworkPageCreateVO.getConfig()).map(x -> x.get("title")).map(String.class::cast).filter(StringUtils::isNotBlank).orElse("书童小睿");
                pageShare.setShareTitle(shareTitle);
                pageShare.setShareImgUrl(StringUtils.isBlank(defaultShareImgUrl) ? "https://file.5rs.me/oss/uploadfe/png/782544053039e776b5379878a18de70e.png" : defaultShareImgUrl);
                pageShare.setShareContent(StringUtils.isBlank(defaultShareContent) ? "我找到这本书「完整版」配套服务了，推荐给你" : defaultShareContent);
                pageShare.setQrcodeId(resourcePage.getSceneId());
                shareMapper.insert(pageShare);
            }
        }

        /*if (ResourcePageConstants.WxworkPageTemplateTypeEnum.CUSTOM.getCode().equals(templateType)) {
            //生成图片更新到数据库
            HtmlDto htmlDto = new HtmlDto();
            htmlDto.setHeight(wxworkPageCreateVO.getHeight());
            htmlDto.setWidth(750);
            htmlDto.setHtmlCode(wxworkPageCreateVO.getHtml());
            htmlDto.setSnapshot(Long.toString(System.currentTimeMillis()));
            ThreadPoolUtils.RESOURCE_POOL.execute(()->{
                String url = shareImageConsr.toJPGByChrome(htmlDto);
                if (!StringUtil.isEmpty(url)) {
                    resourcePageWxwork.setHtmlPic(url);
                    resourcePageWxworkDao.update(resourcePageWxwork);
                }
            });
        }*/

    }

    private void checkWxworkPageCreate(WxworkPageCreateVO wxworkPageCreateVO) {
        if (null == wxworkPageCreateVO.getResourcePageId()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少资源页id");
        }
        if (null == wxworkPageCreateVO.getTemplateType()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少模板类型");
        }
        Integer templateType = wxworkPageCreateVO.getTemplateType();
        if (!Objects.equals(ResourcePageConstants.WxworkPageTemplateTypeEnum.CUSTOM.getCode(), templateType)
                && (null == wxworkPageCreateVO.getQrcodeType() || null == wxworkPageCreateVO.getQrcodeId())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择二维码");
        }
        if (ResourcePageConstants.WxworkPageTemplateTypeEnum.FIXED_NORMAL.getCode().equals(templateType)) {
            if (null == wxworkPageCreateVO.getGuide()|| null == wxworkPageCreateVO.getDisplayBook()) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少参数");
            }
        } else if (ResourcePageConstants.WxworkPageTemplateTypeEnum.CUSTOM.getCode().equals(templateType)) {
            if (CollectionUtil.isEmpty(wxworkPageCreateVO.getConfig())) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少参数");
            }
        } else if (null == wxworkPageCreateVO.getFixedDTO()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少参数");
        }
    }

    @Override
    public WxworkPageVO getWxworkPageByPageId(Long resourcePageId, Boolean isWechat) {
        WxworkPageVO wxworkPageVO = new WxworkPageVO();
        wxworkPageVO.setResourcePageId(resourcePageId);
        ResourcePageWxwork pageWxwork = resourcePageWxworkDao.getByPageId(resourcePageId);
        if (null == pageWxwork) {
            return wxworkPageVO;
        }
        BeanUtils.copyProperties(pageWxwork, wxworkPageVO);
        if (!StringUtil.isEmpty(pageWxwork.getFixedSet())) {
            if (ResourcePageConstants.WxworkPageTemplateTypeEnum.CUSTOM.getCode().equals(pageWxwork.getTemplateType())) {
                if (BooleanUtils.isTrue(pageWxwork.getOldTemplate())) {
                    wxworkPageVO.setFixedDTO(JSONUtils.jsonToBean(pageWxwork.getFixedSet(), WxworkPageFixedDTO.class));
                    wxworkPageVO.setHeight(wxworkPageVO.getFixedDTO().getHeight());
                } else {
                    wxworkPageVO.setConfig(JSON.parseObject(pageWxwork.getFixedSet()));
                }
            } else {
                wxworkPageVO.setFixedDTO(JSONUtils.jsonToBean(pageWxwork.getFixedSet(), WxworkPageFixedDTO.class));
            }
        }

        Integer qrcodeType = pageWxwork.getQrcodeType();
        Long qrcodeId = pageWxwork.getQrcodeId();
        if (!isWechat && null != qrcodeId) {
            String qrcodeName = "";
            if (ResourcePageConstants.WxworkPageQrcodeTypeEnum.CRM_QRCODE.getCode().equals(qrcodeType)) {
                CrmContactQrcodeVO crmContactQrcodeVO = erpConsr.getContactQrcodeNameById4Adviser(qrcodeId);
                qrcodeName = null == crmContactQrcodeVO ? null : crmContactQrcodeVO.getContactQrcodeName();
            } else if (ResourcePageConstants.WxworkPageQrcodeTypeEnum.SOP_GROUP_QRCODE.getCode().equals(qrcodeType)) {
                WxworkGroupQrcodeBaseDTO groupQrcodeBaseDTO = wechatGroupConsr.getWxworkGroupQrcodeBaseById(qrcodeId);
                qrcodeName = null == groupQrcodeBaseDTO?null:groupQrcodeBaseDTO.getGroupQrcodeName();
            } else if (ResourcePageConstants.WxworkPageQrcodeTypeEnum.WXWORK_QRCODE.getCode().equals(qrcodeType)) {
                WxContactWayVO wxContactWayVO = wxworkConsr.getContactWayById(pageWxwork.getCreateUser(), SystemCode.adviser.getCode(),qrcodeId);
                qrcodeName = null == wxContactWayVO?null:wxContactWayVO.getRemark();
            }
            wxworkPageVO.setQrcodeName(qrcodeName);
        }
        return wxworkPageVO;
    }

    @Override
    public ResourcePageDTO getResourcePageByQrcode(Long sceneId, Long bookGroupId) {
        ResourcePage resourcePage = null;
        if (null != sceneId) {
            resourcePage = resourcePageDao.getBySceneId(sceneId);
        } else if (null != bookGroupId) {
            resourcePage = resourcePageDao.getByBookGroupId(bookGroupId);
        }
        ResourcePageDTO dto = new ResourcePageDTO();
        if (null == resourcePage) {
            dto.setOpenRays(0);
            dto.setOpenFood(0);
            dto.setLandingPageType(1);
        } else {
            BeanUtils.copyProperties(resourcePage, dto);
        }
        return dto;
    }

    @Override
    public List<ResourceColumnAndServeVO> getColumnAndServeListByPageId4Wechat(Long resourcePageId, Long wechatUserId, Long bookId,
                                                                               Long adviserId, Long channelId, Integer enableAdverting,
                                                                               Long navigationId, Long officialAccountsId) {
        List<ResourceColumnAndServeVO> resourceColumnAndServeVOS = this.getColumnAndServeListByPageId(resourcePageId, wechatUserId, bookId,
                adviserId, channelId, enableAdverting, navigationId);
        //填充自定义图片
        if (ListUtils.isEmpty(resourceColumnAndServeVOS)) {
            return new ArrayList<>();
        }
        List<ResourcePageItemVO> resourcePageItemVOList = new ArrayList<>();
        resourceColumnAndServeVOS.stream().forEach(e -> {
            if (!ListUtils.isEmpty(e.getItemVOList())) {
                resourcePageItemVOList.addAll(e.getItemVOList());
            }
        });
        if (ListUtils.isEmpty(resourcePageItemVOList)) {
            return new ArrayList<>();
        }
        fillSelfPic(resourcePageItemVOList);
        //填充跳转地址
        try {
            fillJumpUrl(resourcePageItemVOList, wechatUserId, resourcePageId, officialAccountsId,bookId, adviserId, channelId);
        } catch (Exception e) {
            log.error("book.fillJumpUrl失败");
        }
        resourcePageItemVOList.stream().forEach(e -> {
            if (!StringUtil.isEmpty(e.getSelfSmallPic())) {
                e.setServePic(e.getSelfSmallPic());
                e.setCoverImg(e.getSelfSmallPic());
            }
            if (!StringUtil.isEmpty(e.getSelfBigPic())) {
                e.setTransverseImg(e.getSelfBigPic());
            }
            if (!StringUtil.isEmpty(e.getSelfServeName())) {
                e.setServeName(e.getSelfServeName());
            }
        });
        return resourceColumnAndServeVOS;
    }

    private void fillJumpUrl(List<ResourcePageItemVO> resourcePageItemVOList, Long wechatUserId, Long resourcePageId, Long officialAccountsId, Long bookId, Long adviserId, Long channelId) {
        if (CollUtil.isEmpty(resourcePageItemVOList)) {
            return;
        }
        List<Long> serveIds = resourcePageItemVOList.stream().map(f -> f.getServeId()).collect(Collectors.toList());
        List<Long> appIds = resourcePageItemVOList.stream().filter(e -> MessageFromTypeEnum.APP.value.equals(e.getServeType()) &&
                LinkServeConstant.APPLINK.contains(e.getTypeCode())).map(f -> f.getServeId()).collect(Collectors.toList());
        List<Long> productIds = resourcePageItemVOList.stream().filter(e -> MessageFromTypeEnum.PRODUCT.value.equals(e.getServeType()) &&
                LinkServeConstant.PRODUCTLINK.contains(e.getTypeCode())).map(f -> f.getServeId()).collect(Collectors.toList());

        if (CollUtil.isEmpty(appIds) && CollUtil.isEmpty(productIds)) {
            return;
        }
        Map<Long, ProductDto> productDtoMap = new HashMap<>();
        CompletableFuture<Map<Long, ProductDto>> productDtoMapFuture = null;
        Map<Long, AppDto> appDtoMap = new HashMap<>();
        CompletableFuture<Map<Long, AppDto>> appDtoMappFuture = null;
        Map<String, Boolean> bookAuthMap = null;
        CompletableFuture<Map<String, Boolean>>  bookAuthMapFuture = null;
        ResourcePage byId = resourcePageDao.getById(resourcePageId);
        if (null == byId || null == byId.getSceneId()) {
            return;
        }
        if(CollUtil.isNotEmpty(appIds)) {
            appDtoMappFuture = CompletableFuture.supplyAsync(() -> appConsr.mapByIds4AuditPass(appIds), ThreadPoolUtils.FILL_APPLET_RECORD);
         }
        if(CollUtil.isNotEmpty(productIds)) {
            productDtoMapFuture = CompletableFuture.supplyAsync(() -> productConsr.getProBasesByIds(productIds), ThreadPoolUtils.FILL_APPLET_RECORD);
         }
        if(CollUtil.isNotEmpty(serveIds)) {
            bookAuthMapFuture = CompletableFuture.supplyAsync(() -> bookAuthServeBiz.listIsOpen4ServeIdsAndBookId(bookId,adviserId, channelId, serveIds), ThreadPoolUtils.FILL_APPLET_RECORD);
         }
        if(CollUtil.isNotEmpty(serveIds)) {
            try {
                bookAuthMap = bookAuthMapFuture.get();
            } catch (InterruptedException | ExecutionException e) {
                log.warn("获取书刊信息失败 [BookBizImpl.getAdviserBook] ERR:{}", e.getMessage(), e);
            }
        }
        if(CollUtil.isNotEmpty(appIds)) {
            try {
                appDtoMap = appDtoMappFuture.get();
            } catch (InterruptedException | ExecutionException e) {
                log.warn("获取书刊信息失败 [BookBizImpl.getAdviserBook] ERR:{}", e.getMessage(), e);
            }
            Map<Long, AppDto> finalAppDtoMap = appDtoMap;
            Map<String, Boolean> finalBookAuthMap = bookAuthMap;
            resourcePageItemVOList.stream().forEach(e -> {
                if (MessageFromTypeEnum.APP.value.equals(e.getServeType()) &&LinkServeConstant.APPLINK.contains(e.getTypeCode()) &&
                        CollUtil.isNotEmpty(finalAppDtoMap) && null != finalAppDtoMap.get(e.getServeId())) {
                    AppDto appDto = finalAppDtoMap.get(e.getServeId());
                    if (appDto != null && !StringUtil.isEmpty(appDto.getTurnUrl())) {
                        if (appDto.getTurnUrl().contains("5rs.me/") || appDto.getTurnUrl().contains("raysgo.com/") || appDto.getTurnUrl().contains("raysyun.com/")
                                || null == wechatUserId) {
                            e.setResultUrl(appDto.getTurnUrl());
                        } else {
                            if (CollUtil.isEmpty(finalBookAuthMap) || null == finalBookAuthMap.get(MessageFromTypeEnum.APP.value + appDto.getAppId()) || false == finalBookAuthMap.get(MessageFromTypeEnum.APP.value + appDto.getAppId())) {
                                //外链跳转到指定中间页
                                String jumpUrl =  BookProps.getProductDomain() + "transfer?offId=" + officialAccountsId + "&appId=" + appDto.getAppId() + "&url=" +
                                        URLEncoder.encode(appDto.getTurnUrl()) + "&sceneId=" + byId.getSceneId() + "&wechatUserId=" + wechatUserId;
                                e.setResultUrl(jumpUrl);
                            }

                        }
                    }
                }
                //填充版权保护状态
                if (MessageFromTypeEnum.APP.value.equals(e.getServeType())) {
                    if (!MapUtils.isEmpty(finalBookAuthMap) && finalBookAuthMap.containsKey(MessageFromTypeEnum.APP.value + e.getServeId())) {
                        e.setBookAuthState(finalBookAuthMap.get(MessageFromTypeEnum.APP.value + e.getServeId()));
                    } else {
                        e.setBookAuthState(false);
                    }
                }
            });
        }
        if(CollUtil.isNotEmpty(productIds)) {
            try {
                productDtoMap = productDtoMapFuture.get();
            } catch (InterruptedException | ExecutionException e) {
                log.warn("获取书刊信息失败 [BookBizImpl.getAdviserBook] ERR:{}", e.getMessage(), e);
            }
            Map<Long, ProductDto> finalProductDtoMap = productDtoMap;
            Map<String, Boolean> finalBookAuthMap1 = bookAuthMap;
            resourcePageItemVOList.stream().forEach(e -> {
                if ( MessageFromTypeEnum.PRODUCT.value.equals(e.getServeType()) && LinkServeConstant.PRODUCTLINK.contains(e.getTypeCode()) &&
                        CollUtil.isNotEmpty(finalProductDtoMap) && null != finalProductDtoMap.get(e.getServeId())) {
                    ProductDto productDto = finalProductDtoMap.get(e.getServeId());
                    if (productDto != null && !StringUtil.isEmpty(productDto.getSkipUrl())) {
                        Double adviserPrice = CollUtil.isNotEmpty(productDto.getSpecification()) ? productDto.getSpecification().get(0).getAdvisePrice(): 0;
                        if (productDto.getSkipUrl().contains("5rs.me/") || productDto.getSkipUrl().contains("raysgo.com/") || productDto.getSkipUrl().contains("raysyun.com/"))  {
                            e.setResultUrl(productDto.getSkipUrl());
                        } else if (null != wechatUserId && adviserPrice.equals(0D) ){
                            if (CollUtil.isEmpty(finalBookAuthMap1) || null == finalBookAuthMap1.get(MessageFromTypeEnum.PRODUCT.value +  e.getServeId()) || false == finalBookAuthMap1.get(MessageFromTypeEnum.PRODUCT.value +  e.getServeId())) {
                                //外链跳转到指定中间页
                                String jumpUrl =  BookProps.getProductDomain() + "transfer?offId=" + officialAccountsId + "&"  + "&url=" +
                                        URLEncoder.encode(productDto.getSkipUrl()) + "&sceneId=" + byId.getSceneId() + "&wechatUserId=" + wechatUserId + "&productId=" + e.getServeId() ;
                                e.setResultUrl(jumpUrl);
                            }
                        }
                    }
                }
                //填充版权保护状态
                if (MessageFromTypeEnum.PRODUCT.value.equals(e.getServeType())) {
                    if (!MapUtils.isEmpty(finalBookAuthMap1) && finalBookAuthMap1.containsKey(MessageFromTypeEnum.PRODUCT.value + e.getServeId())) {
                        e.setBookAuthState(finalBookAuthMap1.get(MessageFromTypeEnum.PRODUCT.value + e.getServeId()));
                    } else {
                        e.setBookAuthState(false);
                    }
                }
            });
        }
    }

    @Override
    public List<Integer> getColumnTypeByPageId4Wechat(Long resourcePageId, Long wechatUserId, Long bookId, Long adviserId, Long channelId, Integer enableAdverting, Long navigationId) {
        List<Integer> columnIdList = resourcePageColumnDao.getColumnIdListByPageId(resourcePageId, navigationId);
        if(CollUtil.isEmpty(columnIdList)){
            columnIdList=new ArrayList<>();
        }
        columnIdList.add(0);
        return columnIdList;
    }

    //优化  此处把模块分开调接口  通过columnType
    @Override
    public List<ResourceColumnAndServeVO> getColumnAndServeListByPageId4WechatV2(Long resourcePageId, Long wechatUserId, Long bookId, Long adviserId,
                                                                                 Long channelId, Integer enableAdverting, Long navigationId, Integer columnType, Long officialAccountsId) {
        List<ResourceColumnAndServeVO> serveVOS=new ArrayList<>();
        if(null!= columnType && columnType!=0) {
            serveVOS = resourcePageColumnDao.getColumnListByPageId(resourcePageId, navigationId, columnType);
            if (CollUtil.isNotEmpty(serveVOS)) {
                List<Long> pageColumnIds = serveVOS.stream().filter(a -> null != a.getResourcePageColumnId()).map(a -> a.getResourcePageColumnId()).collect(Collectors.toList());
                if(CollUtil.isEmpty(pageColumnIds)){
                    return new ArrayList<>();
                }
                List<ResourcePageItemVO> itemVOList;
                if (null != wechatUserId) {
                    itemVOList = resourcePageItemDao.getResourcePageItemByPageColumnId(resourcePageId, pageColumnIds,true);
                } else {
                    itemVOList = resourcePageItemDao.getResourcePageItemByPageColumnId(resourcePageId, pageColumnIds,null);
                }
                if (CollUtil.isNotEmpty(itemVOList)) {
                    Map<Long, List<ResourcePageItemVO>> columnResourceMap = itemVOList.stream().collect(Collectors.groupingBy(ResourcePageItemVO::getResourcePageColumnId));
                    if(CollUtil.isEmpty(columnResourceMap)){
                        return new ArrayList<>();
                    }
                    //这儿优化。如果应用作品很多。然后有显示更多。则只取显示的数量
                    List<ResourcePageItemVO> itemList=new ArrayList<>();
                    try {
                        for (ResourceColumnAndServeVO serveVO : serveVOS) {
                            if(CollUtil.isNotEmpty(columnResourceMap) && columnResourceMap.containsKey(serveVO.getResourcePageColumnId())){
                                List<ResourcePageItemVO> resourcePageItemVOS = columnResourceMap.get(serveVO.getResourcePageColumnId());
                                if(CollUtil.isNotEmpty(resourcePageItemVOS)) {
                                    if (null != serveVO.getShowMore() && YesOrNoEnums.YES.getValue().equals(serveVO.getShowMore())) {
                                        if (null != serveVO.getShowCount() && serveVO.getShowCount() > 0) {
                                            itemList.addAll(resourcePageItemVOS.subList(0, serveVO.getShowCount()));
                                        }
                                    } else {
                                        itemList.addAll(resourcePageItemVOS);
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.warn("应用作品填充显示更多错误"+e.getMessage());
                        itemList=itemVOList;
                    }
                    itemVOList=itemList;
                    //二维码类型
                    fillQrcodeType(resourcePageId, itemVOList);
                    Map<String, List<ResourcePageItemVO>> listMap = itemVOList.stream().collect(Collectors.groupingBy(ResourcePageItemVO::getServeType));
                    itemVOList = new ArrayList<>();
                    //应用和作品提出来一起查
                    List<ResourcePageItemVO> itemAppAndProductVOList = new ArrayList<>();
                    List<ResourcePageItemVO> resourcePageFolderVOList = new ArrayList<>();
                    //过滤一些资源,重新排序
                    for (Map.Entry<String, List<ResourcePageItemVO>> entry : listMap.entrySet()) {
                        if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(entry.getKey()) || ServeTypeEnum.PRODUCT.getValue().equals(entry.getKey())) {
                            itemAppAndProductVOList.addAll(entry.getValue());
                            continue;
                        }
                        if (ServeTypeEnum.FOLDER.getValue().equals(entry.getKey())) {
                            resourcePageFolderVOList.addAll(entry.getValue());
                            continue;
                        }
                        this.fillResourceByType(entry.getValue(), wechatUserId, entry.getKey());
                        itemVOList.addAll(entry.getValue());
                    }
                    if (CollUtil.isNotEmpty(itemAppAndProductVOList)) {
                        fillAppProductServe(itemAppAndProductVOList, wechatUserId);
                        itemVOList.addAll(itemAppAndProductVOList);
                    }
                    if (!resourcePageFolderVOList.isEmpty()){
                        fillResourcePageFolder(resourcePageFolderVOList,wechatUserId);
                        itemVOList.addAll(resourcePageFolderVOList);
                    }
                    itemVOList.sort(Comparator.comparing(ResourcePageItemVO::getId));

                    List<ResourceColumnAndServeVO> removeColumns = setPageColumnOther(serveVOS, itemVOList);

                    if (!ListUtils.isEmpty(removeColumns)) {
                        serveVOS.removeAll(removeColumns);
                    }
                }
            }
            if (CollUtil.isEmpty(serveVOS)) {
                serveVOS = CollUtil.toList();
            }
        }else {
            this.fillAdvertising(serveVOS, bookId, adviserId, channelId, enableAdverting);
        }
        //填充自定义图片
        if (ListUtils.isEmpty(serveVOS)) {
            return new ArrayList<>();
        }
        List<ResourcePageItemVO> resourcePageItemVOList = new ArrayList<>();
        serveVOS.stream().forEach(e -> {
            if (!ListUtils.isEmpty(e.getItemVOList())) {
                resourcePageItemVOList.addAll(e.getItemVOList());
            }
        });
        fillOuterLink(resourcePageItemVOList);
        fillSelfPic(resourcePageItemVOList);
        try {
            fillJumpUrl(resourcePageItemVOList, wechatUserId, resourcePageId, officialAccountsId, bookId, adviserId, channelId);
        } catch (Exception e) {
            log.error("fillJumpUrl失败：{}",e.getMessage());
        }
        return serveVOS;
    }

    public  void fillOuterLink(List<ResourcePageItemVO> resourcePageItemVOList) {
        if (CollUtil.isEmpty(resourcePageItemVOList)) {
            return;
        }
        List<Long> resourcePageOuterLinkIds = resourcePageItemVOList.stream().filter(s -> ServeTypeEnum.OUTER_LINK.getValue().
                equals(s.getServeType())).map(e -> e.getServeId()).collect(Collectors.toList());
         if (CollUtil.isEmpty(resourcePageOuterLinkIds)) {
            return;
        }
         List<ResourcePageOuterLink> resourcePageOuterLinks = resourcePageOuterLinkBiz.selectList(resourcePageOuterLinkIds);
         if (CollUtil.isEmpty(resourcePageOuterLinks)) {
             return;
         }
        Map<Long, ResourcePageOuterLink> resourcePageOuterLinkMap = resourcePageOuterLinks.stream().collect(Collectors.toMap(ResourcePageOuterLink::getId, Function.identity(), (K1, K2) -> (K1)));
        resourcePageItemVOList.stream().forEach(e -> e.setResourcePageOuterLink(resourcePageOuterLinkMap.get(e.getServeId())));
    }

    /**
     * @Description  设置栏目其他信息
     * @Author zhuyajie
     * @Date 13:13 2022/3/17
     **/
    private List<ResourceColumnAndServeVO> setPageColumnOther(List<ResourceColumnAndServeVO> serveVOS,List<ResourcePageItemVO> itemVOList) {
        List<ResourceColumnAndServeVO> removeColumns = new ArrayList<>();
        // 填充外链
        fillOuterLink(itemVOList);
        //填充多渠道
        fillMultiChannel(itemVOList);
        Map<Long, List<ResourcePageItemVO>> columnMap = itemVOList.stream().collect(Collectors.groupingBy(ResourcePageItemVO::getResourcePageColumnId));
        for (ResourceColumnAndServeVO columnAndServeVO : serveVOS) {
            List<ResourcePageItemVO> itemVOS = columnMap.get(columnAndServeVO.getResourcePageColumnId());
            //去掉没内容的栏目
            if (ListUtils.isEmpty(itemVOS)) {
                removeColumns.add(columnAndServeVO);
                continue;
            }
            columnAndServeVO.setItemVOList(itemVOS);
            String serveType = itemVOS.get(0).getServeType();
            if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(serveType) ||
                    ResourcePageConstants.ServeTypeEnum.PRODUCT.getValue().equals(serveType) ||
                    ServeTypeEnum.RESOURCE.getValue().equals(serveType)) {
                serveType = "APP/PRODUCT";
            }
            columnAndServeVO.setServeType(serveType);
            //图片位
            if (ResourcePageConstants.ColumnTypeEnum.PICTURE.getCode().equals(columnAndServeVO.getColumnType())) {
                columnAndServeVO.setLogoUrl(itemVOS.get(0).getLogoUrl());
            }
        }
        return removeColumns;
    }

    private void fillMultiChannel(List<ResourcePageItemVO> resourcePageItemVOList) {
        if (CollUtil.isEmpty(resourcePageItemVOList)) {
            return;
        }
        List<Long> multiChannelContentIds = resourcePageItemVOList.stream().filter(s -> ServeTypeEnum.MULTI_CHANNEL.getValue().
                equals(s.getServeType())).map(e -> e.getServeId()).collect(Collectors.toList());
        if (CollUtil.isEmpty(multiChannelContentIds)) {
            return;
        }
        List<MultiChannelContentDTO> multiChannelContentDTOS = multiChannelContentBiz.selectList(multiChannelContentIds);
        if (CollUtil.isEmpty(multiChannelContentDTOS)) {
            return;
        }
        Map<Long, MultiChannelContentDTO> multiChannelContentDTOMap = multiChannelContentDTOS.stream().collect(Collectors.toMap(MultiChannelContentDTO::getId, Function.identity(), (K1, K2) -> (K1)));
        resourcePageItemVOList.stream().forEach(e -> e.setMultiChannelContent(multiChannelContentDTOMap.get(e.getServeId())));
    }

    @Override
    public Integer saveShareConfig(ResourcePageShareParam param) {
        checkShareParam(param);
        shareMapper.save(buildNewShareConfig(param));
        return YesOrNoEnums.YES.getValue();
    }

    private ResourcePageShare buildNewShareConfig(ResourcePageShareParam param) {
        ResourcePageShare pageShare = new ResourcePageShare();
        pageShare.setCreateUser(param.getAdviserId());
        pageShare.setUpdateUser(param.getAdviserId());
        pageShare.setShareTitle(param.getShareTitle());
        pageShare.setShareImgUrl(param.getShareImgUrl());
        pageShare.setShareContent(param.getShareContent());
        pageShare.setQrcodeId(param.getQrcodeId());
        return pageShare;
    }

    private void checkShareParam(ResourcePageShareParam param) {
        if (Optional.ofNullable(param.getQrcodeId()).orElse(0L) < 1) {
            throw new BizException(BizException.PARAM_DELETION.getCode(), "二维码编号无效");
        }
        if(StringUtils.isBlank(param.getShareTitle())){
            throw new BizException(BizException.PARAM_DELETION.getCode(), "分享标题无效");
        }
        if(StringUtils.isBlank(param.getShareContent())){
            throw new BizException(BizException.PARAM_DELETION.getCode(), "分享内容无效");
        }
        if (StringUtils.isBlank(param.getShareImgUrl()) || !param.getShareImgUrl().startsWith("http")) {
            throw new BizException(BizException.PARAM_DELETION.getCode(), "分享小图链接无效");
        }
    }

    @Override
    public ResourcePageShareDto getShareConfig(Long qrCodeId) {
        if (Optional.ofNullable(qrCodeId).orElse(0L) < 1) {
            throw new BizException(BizException.PARAM_DELETION.getCode(), "二维码编号无效");
        }
        ResourcePageShareDto shareDto = shareMapper.selectDtoByPrimaryKey(qrCodeId);
        if(shareDto==null){
            return getDefaultShareConfig(qrCodeId);
        }
        return shareMapper.selectDtoByPrimaryKey(qrCodeId);
    }

    private ResourcePageShareDto getDefaultShareConfig(Long qrCodeId) {
        ResourcePageShareDto shareDto = new ResourcePageShareDto();
        shareDto.setQrcodeId(qrCodeId);
        shareDto.setShareTitle(StringUtils.isBlank(defaultShareTitle) ? "书童小睿" : defaultShareTitle);
        shareDto.setShareContent(StringUtils.isBlank(defaultShareContent) ? "我找到这本书「完整版」配套服务了，推荐给你" : defaultShareContent);
        shareDto.setShareImgUrl(StringUtils.isBlank(defaultShareImgUrl) ? "https://file.5rs.me/oss/uploadfe/png/782544053039e776b5379878a18de70e.png" : defaultShareImgUrl);
        return shareDto;
    }

    @Override
    public Map<Long, Boolean> mapWxworkStateBySceneIds(List<Long> sceneIds) {
        if (ListUtils.isEmpty(sceneIds)) {
            return new HashMap<>();
        }
        List<Long> list = resourcePageWxworkDao.getWxworkBySceneIds(sceneIds);
        if (ListUtils.isEmpty(list)) {
            return new HashMap<>();
        }
        Map<Long,Boolean> map = new HashMap<>();
        for (Long sceneId : list) {
            map.put(sceneId, true);
        }
        return map;
    }

    @Override
    public List<BookGroupServe> getResourcePageList4Erp(List<Long> sceneIds) {
        List<BookGroupServe> resourcePageList4Erp = resourcePageItemDao.getResourcePageList4Erp(sceneIds);
        return CollUtil.defaultIfEmpty(resourcePageList4Erp, CollUtil.toList());
    }

    @Override
    public List<ResourcePageItemVO> getServerList4Wechat(Long wechatUserId, Long sceneId) {
        String redisKey = StrUtil.join(":", DL_BOOK_SERVES_CACHE, sceneId);
        List<ResourcePageItemVO> itemVOList = JedisClusterUtils.hgetJson2List(redisKey, String.valueOf(wechatUserId), ResourcePageItemVO.class);
         if (CollUtil.isEmpty(itemVOList)) {
            ResourcePage bySceneId = resourcePageDao.getBySceneId(sceneId);
            if (null == bySceneId) {
                return new ArrayList<>();
            }
            itemVOList = resourcePageItemDao.getResourcePageItemByPageId(bySceneId.getId(), true);
//            //如果mapSceneId 不为null  则直接替换其中的精品文章
//            try {
//                replaceArticle(itemVOList, mapSceneId);
//            } catch (Exception e) {
//               log.warn("斗罗更换精品文章失败sceneId：{}", sceneId);
//            }
            if(CollUtil.isEmpty(itemVOList)) {
                return new ArrayList<>();
            }
            if (CollUtil.isNotEmpty(itemVOList)) {
                //二维码类型
                Map<String, List<ResourcePageItemVO>> listMap = itemVOList.stream().collect(Collectors.groupingBy(ResourcePageItemVO::getServeType));
                itemVOList = new ArrayList<>();
                //应用和作品提出来一起查
                List<ResourcePageItemVO> itemAppAndProductVOList = new ArrayList<>();
                //过滤一些资源,重新排序
                for (Map.Entry<String, List<ResourcePageItemVO>> entry : listMap.entrySet()) {
                    if (ResourcePageConstants.ServeTypeEnum.APP.getValue().equals(entry.getKey()) || ServeTypeEnum.PRODUCT.getValue().equals(entry.getKey())) {
                        itemAppAndProductVOList.addAll(entry.getValue());
                        continue;
                    }
                    this.fillResourceByType(entry.getValue(), wechatUserId, entry.getKey());
                    itemVOList.addAll(entry.getValue());
                }
                if (CollUtil.isNotEmpty(itemAppAndProductVOList)) {
                    fillAppProductServe(itemAppAndProductVOList, wechatUserId);
                    //暂不返回 直接根据typecode进行判断
                    //fillTaskType(itemAppAndProductVOList);
                    itemVOList.addAll(itemAppAndProductVOList);
                }
                itemVOList.sort(Comparator.comparing(ResourcePageItemVO::getId));
            }
             setChannel(itemVOList);
             fillTaskType(itemVOList, wechatUserId);
             fillPageType(itemVOList, bySceneId.getBookId());
        }
        if (CollUtil.isNotEmpty(itemVOList)) {
            JedisClusterUtils.hset2Json(redisKey, String.valueOf(wechatUserId), itemVOList);
            JedisClusterUtils.expire(redisKey, 3600 * 14);
        }
        return itemVOList;
    }

    private void fillPageType(List<ResourcePageItemVO> itemVOList, Long bookId) {
        // 处理斗罗系列书二维码映射
        //添加页面版本
        String pageType = JedisClusterUtils.hget("FUNCTION:DOULUO_BOOK_MAP", bookId.toString());
        if (StrUtil.isNotBlank(pageType)) {
            itemVOList.stream().filter(x -> Objects.nonNull(x) && Objects.nonNull(x.getResultUrl()))
                    .forEach(e -> e.setResultUrl(e.getResultUrl() + "&pageType=" + pageType));
        }
    }


    private void replaceArticle(List<ResourcePageItemVO> itemVOList, Long mapSceneId) {
        if (CollUtil.isEmpty(itemVOList) || null == mapSceneId) {
            return;
        }
        ResourcePage bySceneId = resourcePageDao.getBySceneId(mapSceneId);
        if (null == bySceneId) {
            return;
        }
        List<ResourcePageItemVO> itemVOList4Map = resourcePageItemDao.getResourcePageItemByPageId(bySceneId.getId(), true);
        if (CollUtil.isEmpty(itemVOList4Map)) {
            return;
        }
        Optional<ResourcePageItemVO> first = itemVOList4Map.stream().filter(e -> AppTypeEnum.ARTICLE.value.equals(e.getTypeCode())).findFirst();
         if (!first.isPresent()) {
            return;
        }
        itemVOList.forEach(e -> {
            if (AppTypeEnum.ARTICLE.value.equals(e.getTypeCode())) {
               BeanUtil.copyProperties(first.get(), e);
            }
        });
    }

    private void setChannel(List<ResourcePageItemVO> itemVOList) {
        String key = "BOOK:DOULUO:SET:CHANNEL:STATE";
        if(JedisClusterUtils.exists(key)) {
            return;
        }
        if (CollUtil.isEmpty(itemVOList)) {
            return;
        }
        itemVOList.forEach(e -> {
            String resultUrl = e.getResultUrl();
            if (StrUtil.isBlank(resultUrl)) {
                return;
            }
            if (resultUrl.contains("/C")) {
                String firstResultUrl = resultUrl.substring(0,resultUrl.indexOf("/C"));
                String lastResultUrl = resultUrl.substring(resultUrl.indexOf("/C") + 2);
                lastResultUrl = lastResultUrl.substring(lastResultUrl.indexOf("/"));
                resultUrl = firstResultUrl + "/C" + BookProps.getDefaultChannelId() +  lastResultUrl;
                e.setResultUrl(resultUrl);
            }

        });
    }


    private void fillTaskType(List<ResourcePageItemVO> itemAppAndProductVOList, Long wechatUserId) {
        if (CollUtil.isEmpty(itemAppAndProductVOList)) {
            return;
        }
        //填充斗罗任务类型
        List<AppTaskDTO> appTaskDTOs =   functionConsr.getAppTaskList();
        if (CollUtil.isEmpty(appTaskDTOs)) {
            return;
        }
        Map<Long, Integer> appTaskMap = appTaskDTOs.stream().collect(Collectors.toMap(AppTaskDTO::getAppId, AppTaskDTO::getTaskType, (k1, k2) -> k1));
        itemAppAndProductVOList.forEach(item -> {
            if (CollUtil.isNotEmpty(appTaskMap) && null != appTaskMap.get(item.getServeId())) {
                item.setTaskType(appTaskMap.get(item.getServeId()));
            }
            //如果是高清大图 判断是否可以打开
            if (AppTypeEnum.IMAGE.value.equals(item.getTypeCode())) {
                if (functionConsr.checkIsUnlock(item.getServeId(), wechatUserId)) {
                    item.setBuyState(true);
                };
            }
        });

    }

    @Override
    public List<ResourcePageItemResourceVO> listQrOneResourceByBook(Long sceneId, Long wechatUserId) {
        if (null == sceneId) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数缺失");
        }
        ResourcePage resourcePage = resourcePageDao.getBySceneId(sceneId);
        if (null == resourcePage || null == resourcePage.getBookId() || null == resourcePage.getCreateUser()) {
            return new ArrayList<>();
        }
        List<ResourcePageItemResourceVO> list = resourcePageItemDao.listQrOneResourceByBook(resourcePage.getBookId(), resourcePage.getCreateUser());
        if (ListUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<Long> resourceIds = list.stream().map(ResourcePageItemResourceVO::getServeId).distinct().collect(Collectors.toList());
        Map<Long, ResourceDTO> resourceDTOMap = resourceConsr.mapResourceByIds(resourceIds, true, true);
        if (MapUtils.isEmpty(resourceDTOMap)) {
            return new ArrayList<>();
        }
        List<ResourcePageItemResourceVO> resourceVOS = new ArrayList<>();
        for (ResourcePageItemResourceVO vo:list) {
            ResourceDTO dto = resourceDTOMap.get(vo.getServeId());
            if (null == dto) {
                continue;
            }
            vo.setTypeName(dto.getTypeName());
            vo.setResourceName(dto.getResourceName());
            vo.setFileId(dto.getFileId());
            vo.setFileCategory(dto.getFileCategory());
            vo.setDuration(dto.getDuration());
            vo.setFileSize(dto.getFileSize());
            vo.setFileType(dto.getFileType());
            vo.setFileUrl(dto.getFileUrl());
            vo.setConvertState(dto.getConvertState());
            vo.setResourceOfficeItemDTOs(dto.getResourceOfficeItemDTOs());
            vo.setResourcePdfItems(dto.getResourcePdfItems());
            resourceVOS.add(vo);
        }
        return resourceVOS;
    }

    @Override
    public Map<Long, BookGroupServeCountDTO> mapQrServeCount(List<Long> sceneIds) {
        if (ListUtils.isEmpty(sceneIds)) {
            return new HashMap<>();
        }
        return resourcePageItemDao.mapQrServeCount(sceneIds);
    }

    @Override
    public Integer getNavigationCount(Long bookGroupId, Long wechatUserId, Long sceneId) {
        if (null == bookGroupId && null == sceneId) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数缺失");
        }
        Long bookId = null;
        if (null != bookGroupId) {
            bookId = resourcePageDao.getBookIdByBookGroupId(bookGroupId);
        } else if (null != sceneId) {
            bookId =  resourcePageDao.getBookIdBySceneId(sceneId);
        }
        //上邮临时处理方案
        if (null != bookId && null != JedisClusterUtils.hget(nftReleaseLockKey, bookId.toString())) {
            if (null != bookGroupId) {
                bookGroupId = JedisClusterUtils.hgetJson2Class(nftReleaseLockKey, bookId.toString(), NftBookState.class).getNftBookGroupId();
            } else if (null != sceneId) {
                sceneId = JedisClusterUtils.hgetJson2Class(nftReleaseLockKey, bookId.toString(), NftBookState.class).getNftSceneId();;
            }
        }
        ResourcePage resourcePage = new ResourcePage();
        if (null != bookGroupId) {
            resourcePage = resourcePageDao.getByBookGroupId(bookGroupId);
        } else if (null != sceneId) {
            resourcePage = resourcePageDao.getBySceneId(sceneId);
        }
        if(resourcePage == null || resourcePage.getId() == null){
            return 0;
        }
        Long resourcePageId = resourcePage.getId();
        //进本书服务页 查导航
        Integer count=0;
        if (PageLandingPageTypeEnum.RESOURCE.getCode().equals(resourcePage.getLandingPageType()) || PageLandingPageTypeEnum.SINGLE_RESOURCE.getCode().equals(resourcePage.getLandingPageType())) {
            count = resourcePageNavigationDao.countByPageId(resourcePageId);
            if (null==count || count<1) {
               count=1;
            }
        }
        return count;
    }

    @Override
    public void deleteDouluoCache(Long sceneId, List<Long> mapSceneIds, Long wechatUserId) {
        if (null == sceneId) {
            return;
        }
        String redisKey = StrUtil.join(":", DL_BOOK_SERVES_CACHE, sceneId);
        if (CollUtil.isEmpty(mapSceneIds)) {
            JedisClusterUtils.del(redisKey);
        } else {
            String[] fields = mapSceneIds.stream().map(e -> StrUtil.join(":",wechatUserId, e.toString())).collect(Collectors.toList()).stream().toArray(String[]::new);
            JedisClusterUtils.hdel(redisKey, fields);
        }

    }

    @Override
    public List<ResourcePageFolderItemVO> getFolderItemList(Long wechatUserId, Long folderId) {
        List<ResourcePageFolderItemVO> folderItemVOS = resourcePageFolderItemMapper.listByFolderIds(Collections.singletonList(folderId));
        if (CollUtil.isEmpty(folderItemVOS)) {
            return new ArrayList<>();
        }

        List<ResourcePageFolderItemVO> appProductItems = new ArrayList<>();
        List<ResourcePageFolderItemVO> otherItems = new ArrayList<>();
        folderItemVOS.forEach(x-> splitFolderItemVOS(appProductItems, otherItems, x));

        if (CollUtil.isNotEmpty(appProductItems)) {
            appProductItems.get(0).setCreateUser(folderItemVOS.get(0).getCreateUser());
            fillAppProductServe(appProductItems, wechatUserId);
        }

        if (CollUtil.isNotEmpty(otherItems)) {
            Map<String, List<ResourcePageFolderItemVO>> folderItemMap = otherItems.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(ResourcePageFolderItemVO::getServeType));
            folderItemMap.forEach((k, v) -> fillResourceByType(v, wechatUserId, k));
        }
        return folderItemVOS;
    }

    @Override
    public int updateDeleteBySceneId(Long sceneId, Integer isDelete) {
        return resourcePageDao.updateDeleteBySceneId(sceneId, isDelete);
    }
}
