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

import com.google.common.collect.Lists;
import com.pcloud.appcenter.assist.dto.AssistTempletDTO;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.dto.BookDto;
import com.pcloud.book.book.vo.SearchBookVO;
import com.pcloud.book.consumer.app.AssistTempletConsr;
import com.pcloud.book.consumer.reader.ReaderConsr;
import com.pcloud.book.consumer.user.AdviserConsr;
import com.pcloud.book.cultivate.biz.CultivateBiz;
import com.pcloud.book.cultivate.constant.CultivateConstant;
import com.pcloud.book.cultivate.dao.CultivateBookUserDao;
import com.pcloud.book.cultivate.dao.CultivateDao;
import com.pcloud.book.cultivate.dao.CultivateHoldSeatDao;
import com.pcloud.book.cultivate.dao.CultivateRecordDao;
import com.pcloud.book.cultivate.dao.CultivateRobotClassifyDao;
import com.pcloud.book.cultivate.dto.CreateCultivateDTO;
import com.pcloud.book.cultivate.dto.CultivateDTO;
import com.pcloud.book.cultivate.dto.DealHoldSeatFriendFishBallDTO;
import com.pcloud.book.cultivate.dto.EnergyConsumptionDTO;
import com.pcloud.book.cultivate.dto.EnergyConsumptionDelayDTO;
import com.pcloud.book.cultivate.dto.FishBallConversionDTO;
import com.pcloud.book.cultivate.dto.FishBallPickDTO;
import com.pcloud.book.cultivate.dto.FriendDTO;
import com.pcloud.book.cultivate.dto.GiveEnergyDTO;
import com.pcloud.book.cultivate.dto.HoldSeatDTO;
import com.pcloud.book.cultivate.dto.HoldTimeDTO;
import com.pcloud.book.cultivate.dto.SkillUseDTO;
import com.pcloud.book.cultivate.entity.Cultivate;
import com.pcloud.book.cultivate.entity.CultivateBookUser;
import com.pcloud.book.cultivate.entity.CultivateHoldSeat;
import com.pcloud.book.cultivate.entity.CultivateRecord;
import com.pcloud.book.cultivate.entity.CultivateRobotClassify;
import com.pcloud.book.cultivate.enums.CultivateChangeTypeEnum;
import com.pcloud.book.cultivate.enums.CultivateSkillTypeEnum;
import com.pcloud.book.cultivate.enums.FishBallChangeTypeEnum;
import com.pcloud.book.mq.delay.DelayMessageSender;
import com.pcloud.book.pcloudkeyword.biz.PcloudRobotBiz;
import com.pcloud.book.pcloudkeyword.biz.PcloudRobotClassifyBiz;
import com.pcloud.book.personal.biz.PersonalMedalBiz;
import com.pcloud.book.personal.dao.PersonalMedalDao;
import com.pcloud.book.personal.dao.PersonalMedalRecordDao;
import com.pcloud.book.personal.dto.PersonalMedalRecordDto;
import com.pcloud.book.personal.entity.PersonalMedal;
import com.pcloud.book.personal.entity.PersonalMedalRecord;
import com.pcloud.book.personal.entity.PersonalShareTemplate;
import com.pcloud.book.personal.mapper.PersonalShareTemplateMapper;
import com.pcloud.book.util.common.ThreadPoolUtils;
import com.pcloud.book.util.common.YesOrNoEnums;
import com.pcloud.common.constant.CacheConstant;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.mq.DelayQueueDTO;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.ResponseHandleUtil;
import com.pcloud.common.utils.cache.redis.JedisClusterUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.facade.shareimage.dto.HtmlDto;
import com.pcloud.facade.shareimage.facade.Htm2ImgService;
import com.pcloud.readercenter.wechat.entity.WechatUser;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import com.pcloud.usercenter.party.adviser.dto.AdviserBaseInfoDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.*;
import java.util.stream.Collectors;

@Component("cultivateBiz")
public class CultivateBizImpl implements CultivateBiz {

    @Autowired
    private CultivateDao cultivateDao;
    @Autowired
    private CultivateRobotClassifyDao cultivateRobotClassifyDao;
    @Autowired
    private DelayMessageSender delayMessageSender;
    @Autowired
    private CultivateRecordDao cultivateRecordDao;

    @Autowired
    private ReaderConsr readerConsr;

    @Autowired
    private PcloudRobotBiz pcloudRobotBiz;
    @Autowired
    private Htm2ImgService htm2ImgService;
    @Autowired
    private PcloudRobotClassifyBiz pcloudRobotClassifyBiz;
    @Autowired
    private PersonalShareTemplateMapper personalShareTemplateMapper;

    @Autowired
    private PersonalMedalDao personalMedalDao;

    @Autowired
    private PersonalMedalRecordDao personalMedalRecordDao;

    @Autowired
    private PersonalMedalBiz personalMedalBiz;
    @Autowired
    private CultivateBookUserDao cultivateBookUserDao;

    @Autowired
    private AssistTempletConsr assistTempletConsr;

    @Autowired
    private AdviserConsr adviserConsr;




    @Autowired
    private CultivateHoldSeatDao cultivateHoldSeatDao;







    @Transactional(rollbackFor = Exception.class)
    @ParamLog("新增养成")
    @Override
    public Long createCultivate(CreateCultivateDTO createCultivateDTO) {
        if (createCultivateDTO==null||createCultivateDTO.getWechatUserId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"wechatUserId为空！");
        }
        Long wechatUserId=createCultivateDTO.getWechatUserId();
        Cultivate old = cultivateDao.getByWechatUserId(wechatUserId);
        if (old!=null){
            throw new BookBizException(BookBizException.ERROR,"已有养成！");
        }
        Cultivate cultivate=new Cultivate();
        cultivate.setEnergy(CultivateConstant.INITIAL_ENERGY);
        cultivate.setStar(CultivateConstant.INITIAL_STAR);
        cultivate.setWechatUserId(wechatUserId);
        cultivate.setLighten(false);
        cultivate.setFishBall(0);
        cultivateDao.insert(cultivate);
        return cultivate.getId();
    }

    @ParamLog("获取养成")
    @Override
    public Cultivate getCultivate(Long wechatUserId) {
        if (wechatUserId==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"wechatUserId为空！");
        }
        Cultivate cultivate = cultivateDao.getByWechatUserId(wechatUserId);
        //TODO 计算等级勋章等，获取用户基本信息等
        return cultivate;
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("新增养成分类关联")
    @Override
    public void createCultivateRobotClassify(CultivateRobotClassify cultivateRobotClassify) {
        if (cultivateRobotClassify==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"cultivateRobotClassify为空！");
        }
        if (cultivateRobotClassify.getCultivateId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"cultivateId为空！");
        }
        if (cultivateRobotClassify.getRobotClassifyId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"robotClassifyId为空！");
        }
        if (cultivateRobotClassify.getWechatUserId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"用户id为空！");
        }
        //查询之前是否有
        CultivateRobotClassify byCondition = cultivateRobotClassifyDao.getByCondition(cultivateRobotClassify.getWechatUserId(), cultivateRobotClassify.getCultivateId(), cultivateRobotClassify.getRobotClassifyId());
        if (byCondition!=null){
            return;
        }
        cultivateRobotClassifyDao.insert(cultivateRobotClassify);
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("能量消耗")
    @Override
    public void energyConsumption(EnergyConsumptionDTO energyConsumptionDTO) {
        if (energyConsumptionDTO==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"energyConsumptionDTO为空！");
        }
        if (energyConsumptionDTO.getCultivateId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"养成id为空！");
        }
        if (energyConsumptionDTO.getEnergy()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"能量为空！");
        }
        if (energyConsumptionDTO.getWechatUserId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"用户id为空！");
        }
        Long wechatUserId=energyConsumptionDTO.getWechatUserId();
        Long cultivateId=energyConsumptionDTO.getCultivateId();
        Cultivate cultivate = cultivateDao.getById(cultivateId);
        if (cultivate==null){
            throw new BookBizException(BookBizException.ERROR,"没有养成！");
        }
        if (cultivate.getEnergy()<energyConsumptionDTO.getEnergy()){
            throw new BookBizException(BookBizException.ERROR,"能量不足，当前只有"+cultivate.getEnergy()+"能量");
        }
        cultivate.setEnergy(cultivate.getEnergy()-energyConsumptionDTO.getEnergy());
        //新增能量消耗记录
        CultivateRecord addEnergyRecord=new CultivateRecord();
        addEnergyRecord.setEnergyChange(-energyConsumptionDTO.getEnergy());
        addEnergyRecord.setCultivateId(cultivateId);
        addEnergyRecord.setChangeType(CultivateChangeTypeEnum.USE_ENERGY.code);
        addEnergyRecord.setWechatUserId(wechatUserId);
        Long recordId=createCultivateRecord(addEnergyRecord);
        if (!cultivate.getLighten()){
            //熄灭状态
            cultivate.setLighten(true);
            //加延时队列，到点熄灯，新增点亮记录
            addDelayEnergyConsumption(recordId,wechatUserId,energyConsumptionDTO.getEnergy());
            //新增点亮记录
            CultivateRecord liRecord=new CultivateRecord();
            liRecord.setWechatUserId(wechatUserId);
            liRecord.setCultivateId(cultivateId);
            liRecord.setChangeType(CultivateChangeTypeEnum.LIGHTEN.code);
            liRecord.setWechatUserId(wechatUserId);
            createCultivateRecord(liRecord);
        }
        cultivateDao.update(cultivate);
    }

    private void addDelayEnergyConsumption(Long cultivateRecordId,Long wechatUserId,Integer energy){
        EnergyConsumptionDelayDTO energyConsumptionDelayDTO=new EnergyConsumptionDelayDTO();
        energyConsumptionDelayDTO.setCultivateRecordId(cultivateRecordId);
        energyConsumptionDelayDTO.setEnergy(energy);
        DelayQueueDTO delayQueueDTONew = DelayQueueDTO.builder().key(wechatUserId.toString()).type(CultivateConstant.ENERGY_CONSUMPTION_DELAY).msg(energyConsumptionDelayDTO).timeout(energy*60*1000).build();
        delayMessageSender.send(delayQueueDTONew);
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("能量消耗延时处理")
    @Override
    public void dealDelayEnergyConsumption(DelayQueueDTO delayQueueDTO) {
        Long wechatUserId=new Long(delayQueueDTO.getKey());
        EnergyConsumptionDelayDTO consumptionDelayDTO= (EnergyConsumptionDelayDTO) delayQueueDTO.getMsg();
        Long recordId=consumptionDelayDTO.getCultivateRecordId();
        CultivateRecord cultivateRecord = cultivateRecordDao.getById(recordId);
        //判断该记录之前还有没有能量消耗，如果有继续点亮，如果没有，熄灯
        Integer afterEnergy = cultivateRecordDao.getEnergyConsumptionAfter(cultivateRecord.getId(), wechatUserId);
        Long cultivateId=cultivateRecord.getCultivateId();
        if (afterEnergy>0){
            //继续点亮，重新加延时队列
            CultivateRecord last=cultivateRecordDao.getLastEnergyConsumptionRecord(wechatUserId,cultivateId);
            addDelayEnergyConsumption(last.getId(),wechatUserId,afterEnergy);
        } else {
            //熄灯，收取银两
            Cultivate cultivate=cultivateDao.getById(cultivateId);
            cultivate.setLighten(false);
            //查询用户点灯之后收取过的银两数量
            Integer userGatherFishBall=cultivateRecordDao.getUserGatherFishBallCount(wechatUserId,cultivateId);
            //系统收取银两
            Integer allEnergy=0;
            CultivateRecord lastLighten = cultivateRecordDao.getLastLighten(wechatUserId, cultivateId);
            if (lastLighten!=null){
                //获取点灯之前的最后一次消耗能量记录
                CultivateRecord consumptionBefore =cultivateRecordDao.getLastEnergyConsumptionBefore(lastLighten.getId(),wechatUserId);
                if (consumptionBefore!=null){
                    Integer consumptionAfter = cultivateRecordDao.getEnergyConsumptionAfter(lastLighten.getId(), wechatUserId);
                    allEnergy=-consumptionBefore.getEnergyChange()+consumptionAfter;
                }
            }
            Integer currentAdd=allEnergy-userGatherFishBall;
            //减去被占座的部分之后
            DealHoldSeatFriendFishBallDTO deal = getHoldSeatFriendFishBall(cultivateId, currentAdd, lastLighten.getId());
            currentAdd=deal.getOwnHasFishBall();
            //占座好友分银两
            dealStayFriendFishBall(deal.getFriendFishBallMap(),cultivateId);
            cultivate.setFishBall(cultivate.getFishBall()+currentAdd);
            //产生收银两记录
            CultivateRecord hasFishBall=new CultivateRecord();
            hasFishBall.setCultivateId(cultivateId);
            hasFishBall.setWechatUserId(wechatUserId);
            hasFishBall.setChangeType(CultivateChangeTypeEnum.GET_FISH_BALL.code);
            hasFishBall.setFishBallChangeType(FishBallChangeTypeEnum.AUTO_CHANGE.value);
            hasFishBall.setFishBallChange(currentAdd);
            createCultivateRecord(hasFishBall);
            //熄灯,产生一条熄灯记录
            CultivateRecord quench=new CultivateRecord();
            quench.setWechatUserId(wechatUserId);
            quench.setCultivateId(cultivateId);
            quench.setChangeType(CultivateChangeTypeEnum.QUENCH.code);
            createCultivateRecord(quench);
            cultivateDao.update(cultivate);
        }
    }

    @ParamLog("获取被好友占座的能量值")
    private DealHoldSeatFriendFishBallDTO getHoldSeatFriendFishBall(Long cultivateId, Integer currentHas, Long lastLightenRecordId){
        //查询上次点灯之后被占座的记录集合
        List<CultivateRecord> records=cultivateRecordDao.getHoldSeatFriendList(cultivateId,lastLightenRecordId);
        //开始记录
        List<CultivateRecord> startRecords=records.stream().filter(s->CultivateChangeTypeEnum.HOLD_SEAT_BY_FRIEND.code.equals(s.getChangeType())).collect(Collectors.toList());
        //结束记录
        List<CultivateRecord> endRecords=records.stream().filter(s->CultivateChangeTypeEnum.FRIEND_EXIT_SEAT.code.equals(s.getChangeType())
                ||CultivateChangeTypeEnum.KICK_OUT_FRIEND_BY_SELF.code.equals(s.getChangeType())).collect(Collectors.toList());
        DealHoldSeatFriendFishBallDTO deal=new DealHoldSeatFriendFishBallDTO();
        deal.setCultivateId(cultivateId);
        deal.setOwnHasFishBall(currentHas);
        if (ListUtils.isEmpty(records)){
            return deal;
        }
        List<HoldTimeDTO> holdTimeDTOS=new ArrayList<>();
        Date now=new Date();
        List<Long> go=new ArrayList<>();
        for (CultivateRecord start:startRecords){
            //获取开始
            HoldTimeDTO holdTimeDTO=new HoldTimeDTO();
            holdTimeDTO.setStartHold(start.getCreateTime());
            holdTimeDTO.setFriendCultivateId(start.getFriendCultivateId());
            Date endHold=null;
            //循环获取结束
            for (CultivateRecord end:endRecords){
                if (end.getId()>start.getId()&&start.getFriendCultivateId().equals(end.getFriendCultivateId())&&!go.contains(end.getId())){
                    endHold=end.getCreateTime();
                    go.add(end.getId());
                    break;
                }
            }
            if (endHold==null){
                holdTimeDTO.setEndHold(now);
                holdTimeDTO.setStay(true);
            }else {
                holdTimeDTO.setEndHold(endHold);
                holdTimeDTO.setStay(false);
            }
            //增加一组占位开始和结束时间
            holdTimeDTOS.add(holdTimeDTO);
        }
        Double allFriendFishBall=0D;
        Map<Long,Double> friendFishBallMap=new HashMap<>();
        for (HoldTimeDTO holdTimeDTO:holdTimeDTOS){
            //一共呆的分钟数
            Double oneHoldSeatFishBall = (holdTimeDTO.getEndHold().getTime() - holdTimeDTO.getStartHold().getTime())/(1000*60)*CultivateConstant.HOLD_SEAT_PROPORTION;
            allFriendFishBall=allFriendFishBall+oneHoldSeatFishBall;
            //判断是否还在
            if (holdTimeDTO.getStay()){
                Long friendId=holdTimeDTO.getFriendCultivateId();
                if (friendFishBallMap.get(friendId)==null){
                    friendFishBallMap.put(friendId,oneHoldSeatFishBall);
                }else {
                    Double en=friendFishBallMap.get(friendId);
                    en=en+oneHoldSeatFishBall;
                    friendFishBallMap.put(friendId,en);
                }
            }
        }
        deal.setOwnHasFishBall(currentHas-allFriendFishBall.intValue());
        deal.setFriendFishBallMap(friendFishBallMap);
        return deal;
    }

    @ParamLog("给占座没走的好友分银两")
    private void dealStayFriendFishBall(Map<Long,Double> friendFishBallMap,Long cultivateId){
        //给没走的人分银两
        if (friendFishBallMap==null||MapUtils.isEmpty(friendFishBallMap)){
            return;
        }
        List<Long> stayFriendIds=new ArrayList<>(friendFishBallMap.keySet());
        List<Cultivate> friendCultivates = cultivateDao.getByCultivateIds(stayFriendIds);
        Map<Long,Cultivate> friendCultivateMap=new HashMap<>();
        for (Cultivate friend:friendCultivates){
            friendCultivateMap.put(friend.getId(),friend);
        }
        for (Long statFriendId:stayFriendIds){
            Integer fishBall=friendFishBallMap.get(statFriendId).intValue();
            Cultivate friend=friendCultivateMap.get(statFriendId);
            if (friend==null){
                continue;
            }
            friend.setFishBall(friend.getFishBall()+fishBall);
            //更新银两
            cultivateDao.update(friend);
            CultivateRecord record=new CultivateRecord();
            record.setChangeType(CultivateChangeTypeEnum.GET_FISH_BALL.code);
            record.setFishBallChangeType(FishBallChangeTypeEnum.FRIEND_LIGHTS_OUT_CHANGE.value);
            record.setFishBallChange(fishBall);
            record.setCultivateId(statFriendId);
            record.setFriendCultivateId(cultivateId);
            record.setWechatUserId(friend.getWechatUserId());
            //分银两记录
            createCultivateRecord(record);
            //好友灯熄灭记录
            CultivateRecord recordOut=new CultivateRecord();
            recordOut.setChangeType(CultivateChangeTypeEnum.FRIEND_LIGHTS_OUT.code);
            recordOut.setCultivateId(statFriendId);
            recordOut.setFriendCultivateId(cultivateId);
            recordOut.setWechatUserId(friend.getWechatUserId());
            createCultivateRecord(recordOut);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("银两兑换")
    @Override
    public void fishBallConversion(FishBallConversionDTO fishBallConversionDTO) {
        if (fishBallConversionDTO==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"fishBallConversionDTO为空！");
        }
        if (fishBallConversionDTO.getCultivateId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"养成id为空！");
        }
        if (fishBallConversionDTO.getFishBall()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"银两为空！");
        }
        if (fishBallConversionDTO.getWechatUserId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"用户id为空！");
        }
        Long wechatUserId=fishBallConversionDTO.getWechatUserId();
        Cultivate cultivate = cultivateDao.getById(fishBallConversionDTO.getCultivateId());
        if (cultivate==null){
            throw new BookBizException(BookBizException.ERROR,"没有养成！");
        }
        if (cultivate.getFishBall()<fishBallConversionDTO.getFishBall()){
            throw new BookBizException(BookBizException.ERROR,"银两不足，当前只有"+cultivate.getFishBall()+"银两");
        }
        if (fishBallConversionDTO.getFishBall()%100!=0){
            throw new BookBizException(BookBizException.ERROR,"请使用100的倍数");
        }

        //插入银两兑换记录
        CultivateRecord convertFishBall=new CultivateRecord();
        convertFishBall.setWechatUserId(wechatUserId);
        convertFishBall.setChangeType(CultivateChangeTypeEnum.FISH_BALL_CONVERT_STAR.code);
        convertFishBall.setCultivateId(fishBallConversionDTO.getCultivateId());
        convertFishBall.setFishBallChange(-fishBallConversionDTO.getFishBall());
        convertFishBall.setStarChange(fishBallConversionDTO.getFishBall()/100);
        createCultivateRecord(convertFishBall);
        //先插入记录在更新养成表书币数
        cultivate.setFishBall(cultivate.getFishBall()-fishBallConversionDTO.getFishBall());
        cultivate.setStar(cultivate.getStar()+fishBallConversionDTO.getFishBall()/100);
        cultivateDao.update(cultivate);
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("插入成长动态记录")
    @Override
    public Long createCultivateRecord(CultivateRecord cultivateRecord) {
        if (cultivateRecord==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"cultivateRecord为空！");
        }
        if (cultivateRecord.getCultivateId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"养成id为空！");
        }
        if (cultivateRecord.getWechatUserId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"用户id为空！");
        }
        Integer changeType=cultivateRecord.getChangeType();
        if (changeType==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"动态类型为空！");

        }
        if(changeType.equals(CultivateChangeTypeEnum.GET_FISH_BALL.code)){
            if (cultivateRecord.getFishBallChange()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"银两数为空！");

            }
            if (cultivateRecord.getFishBallChangeType()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"银两变化类型为空！");

            }
            cultivateRecord.setRemark("获得了"+cultivateRecord.getFishBallChange()+"个银两");
        }
        if(changeType.equals(CultivateChangeTypeEnum.LIGHTEN.code)){

            cultivateRecord.setRemark("灯已点亮，我有吃的了！");
        }
        if(changeType.equals(CultivateChangeTypeEnum.QUENCH.code)){

            cultivateRecord.setRemark("灯已熄灭,我看不见了小主，点亮我吧！");
        }

        if(changeType.equals(CultivateChangeTypeEnum.USE_ENERGY.code)){
            if(cultivateRecord.getEnergyChange()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"能量值为空！");
            }
            Integer hour=(-cultivateRecord.getEnergyChange())/60;
            Integer min=(-cultivateRecord.getEnergyChange())%60;
            if(hour>0) {
                cultivateRecord.setRemark("你已使用" + (-cultivateRecord.getEnergyChange()) + "能量值点亮" + hour + "小时" + (min != 0 ? min + "分钟" : ""));
            }else{
                cultivateRecord.setRemark("你已使用" + (-cultivateRecord.getEnergyChange()) + "能量值点亮" + min + "分钟");
            }
        }

        if(changeType.equals(CultivateChangeTypeEnum.USE_SKILL.code)){
            if(cultivateRecord.getSkillType()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"技能类型为空！");
            }
            String skill=CultivateSkillTypeEnum.getNameByCode(cultivateRecord.getSkillType());

            cultivateRecord.setRemark("你使用了"+skill+"技能，请添加小睿为好友后，回复您想要定制阅读的书名吧");
        }

        if(changeType.equals(CultivateChangeTypeEnum.FISH_BALL_CONVERT_STAR.code)){
            if(cultivateRecord.getStarChange()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"书币数量为空！");
            }
            cultivateRecord.setRemark("你已将"+cultivateRecord.getStarChange()*100+"个银两兑换了"+cultivateRecord.getStarChange()+"书币");
        }
        //赠送能量给好友
        if (changeType.equals(CultivateChangeTypeEnum.GIVE_ENERGY_TO_FRIEND.code)){
            if (cultivateRecord.getFriendCultivateId()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"好友养成id不能为空！");
            }
            if (cultivateRecord.getEnergyChange()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"能量不能为空！");
            }
            Cultivate friend = cultivateDao.getById(cultivateRecord.getFriendCultivateId());
            WechatUser wechatUser = readerConsr.getWechatUser(friend.getWechatUserId());
            cultivateRecord.setRemark("赠送好友"+wechatUser.getWechatUserNickname()+cultivateRecord.getEnergyChange()+"个能量。");
        }
        //被好友赠送能量
        if (changeType.equals(CultivateChangeTypeEnum.GET_ENERGY_BY_FRIEND.code)){
            if (cultivateRecord.getFriendCultivateId()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"好友养成id不能为空！");
            }
            if (cultivateRecord.getEnergyChange()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"能量不能为空！");
            }
            Cultivate friend = cultivateDao.getById(cultivateRecord.getFriendCultivateId());
            WechatUser wechatUser = readerConsr.getWechatUser(friend.getWechatUserId());
            cultivateRecord.setRemark("获得了好友"+wechatUser.getWechatUserNickname()+"赠送的"+cultivateRecord.getEnergyChange()+"个能量。");
        }
        //占好友座位
        if (changeType.equals(CultivateChangeTypeEnum.HOLD_FRIEND_SEAT.code)){
            if (cultivateRecord.getFriendCultivateId()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"好友养成id不能为空！");
            }
            Cultivate friend = cultivateDao.getById(cultivateRecord.getFriendCultivateId());
            WechatUser wechatUser = readerConsr.getWechatUser(friend.getWechatUserId());
            cultivateRecord.setRemark("我到好友"+wechatUser.getWechatUserNickname()+"这里占座学习啦，主人记得收银两哦。");
        }
        //被好友占座
        if (changeType.equals(CultivateChangeTypeEnum.HOLD_SEAT_BY_FRIEND.code)){
            if (cultivateRecord.getFriendCultivateId()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"好友养成id不能为空！");
            }
            Cultivate friend = cultivateDao.getById(cultivateRecord.getFriendCultivateId());
            WechatUser wechatUser = readerConsr.getWechatUser(friend.getWechatUserId());
            cultivateRecord.setRemark("好友"+wechatUser.getWechatUserNickname()+"过来抄作业了，赶紧阻止他。");
        }
        //退出好友座位
        if (changeType.equals(CultivateChangeTypeEnum.EXIT_FRIEND_SEAT.code)){
            if (cultivateRecord.getFriendCultivateId()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"好友养成id不能为空！");
            }
            Cultivate friend = cultivateDao.getById(cultivateRecord.getFriendCultivateId());
            WechatUser wechatUser = readerConsr.getWechatUser(friend.getWechatUserId());
            cultivateRecord.setRemark("我退出了好友"+wechatUser.getWechatUserNickname()+"书房座位，获得了"+cultivateRecord.getFishBallChange()+"个银两");
            cultivateRecord.setFishBallChange(null);
        }
        //好友退出我的座位
        if (changeType.equals(CultivateChangeTypeEnum.FRIEND_EXIT_SEAT.code)){
            if (cultivateRecord.getFriendCultivateId()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"好友养成id不能为空！");
            }
            Cultivate friend = cultivateDao.getById(cultivateRecord.getFriendCultivateId());
            WechatUser wechatUser = readerConsr.getWechatUser(friend.getWechatUserId());
            cultivateRecord.setRemark("好友"+wechatUser.getWechatUserNickname()+"退出了我的书房座位。");
        }
        //将好友踢出座位
        if (changeType.equals(CultivateChangeTypeEnum.KICK_OUT_FRIEND_BY_SELF.code)){
            if (cultivateRecord.getFriendCultivateId()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"好友养成id不能为空！");
            }
            Cultivate friend = cultivateDao.getById(cultivateRecord.getFriendCultivateId());
            WechatUser wechatUser = readerConsr.getWechatUser(friend.getWechatUserId());
            cultivateRecord.setRemark("发现有人来抄作业，我将"+wechatUser.getWechatUserNickname()+"请出了我的书房。");
        }
        //被好友踢出座位
        if (changeType.equals(CultivateChangeTypeEnum.KICK_OUT_BY_FRIEND.code)){
            if (cultivateRecord.getFriendCultivateId()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"好友养成id不能为空！");
            }
            Cultivate friend = cultivateDao.getById(cultivateRecord.getFriendCultivateId());
            WechatUser wechatUser = readerConsr.getWechatUser(friend.getWechatUserId());
            cultivateRecord.setRemark("占座被发现了，此处不留人，好友"+wechatUser.getWechatUserNickname()+"将我踢出了。");
        }
        //占座好友灯熄灭
        if (changeType.equals(CultivateChangeTypeEnum.FRIEND_LIGHTS_OUT.code)){
            if (cultivateRecord.getFriendCultivateId()==null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"好友养成id不能为空！");
            }
            Cultivate friend = cultivateDao.getById(cultivateRecord.getFriendCultivateId());
            WechatUser wechatUser = readerConsr.getWechatUser(friend.getWechatUserId());
            cultivateRecord.setRemark("好友"+wechatUser.getWechatUserNickname()+"灯已熄灭，主人快召回我吧。");
        }
        cultivateRecordDao.insert(cultivateRecord);
        if(changeType.equals(CultivateChangeTypeEnum.FISH_BALL_CONVERT_STAR.code)){
            Cultivate cultivate = cultivateDao.getByWechatUserId(cultivateRecord.getWechatUserId());
            Boolean isUp= isUpGrade(cultivate.getStar(),cultivate.getStar()+cultivateRecord.getStarChange());
            Integer  newStarCount=cultivate.getStar()+cultivateRecord.getStarChange();
            if(isUp){
                //插入升级记录
                CultivateRecord upGradeRecord=new CultivateRecord();
                upGradeRecord.setWechatUserId(cultivateRecord.getWechatUserId());
                upGradeRecord.setChangeType(CultivateChangeTypeEnum.UPGRADE.code);
                upGradeRecord.setCultivateId(cultivate.getId());
                //插入领取的勋章
                // 获取用户的书币数
                Integer starCount =cultivate.getStar()+cultivateRecord.getStarChange();
                // 查询当前数量的书币可以领取的勋章(过滤掉已领取的)
                List<Long> medalIds = personalMedalDao.getReceivingMedal(cultivateRecord.getWechatUserId(), starCount);
                if(!ListUtils.isEmpty(medalIds)){
                    // 插入可以领取的记录
                    PersonalMedalRecord medalRecord;
                    for (Long medalId : medalIds){
                        medalRecord = new PersonalMedalRecord();
                        medalRecord.setMedalId(medalId);
                        medalRecord.setWechatUserId(cultivateRecord.getWechatUserId());
                        medalRecord.setHasShow(YesOrNoEnums.YES.getValue());
                        // 插入领取记录
                        personalMedalRecordDao.insert(medalRecord);
                    }
                }
                if(CultivateConstant.second_MEDAL_STAR<=newStarCount&&newStarCount<CultivateConstant.third_MEDAL_STAR) {
                    upGradeRecord.setRemark("已成功升级LV2学有小成");
                }
                if(CultivateConstant.third_MEDAL_STAR<=newStarCount&&newStarCount<CultivateConstant.fourth_MEDAL_STAR) {
                    upGradeRecord.setRemark("已成功升级LV3渐入佳境");
                }
                if(CultivateConstant.fourth_MEDAL_STAR<=newStarCount&&newStarCount<CultivateConstant.fifth_MEDAL_STAR) {
                    upGradeRecord.setRemark("已成功升级LV4炉火纯青");
                }
                if(CultivateConstant.fifth_MEDAL_STAR<=newStarCount&&newStarCount<CultivateConstant.sixth_MEDAL_STAR) {
                    upGradeRecord.setRemark("已成功升级LV5学识渊博");
                }
                if(CultivateConstant.sixth_MEDAL_STAR<=newStarCount&&newStarCount<CultivateConstant.seventh_MEDAL_STAR) {
                    upGradeRecord.setRemark("已成功升级LV6学识渊博");
                }
                if(CultivateConstant.seventh_MEDAL_STAR<=newStarCount) {
                    upGradeRecord.setRemark("已成功升级LV7学亘古今");
                }
                cultivateRecordDao.insert(upGradeRecord);

            }


        }
        return cultivateRecord.getId();
    }



    @Override
    public void addUseSkillRecord(Long wechatUserId, SkillUseDTO skillUseDTO) {
        CultivateRecord cultivateRecord=new CultivateRecord();
        cultivateRecord.setChangeType(CultivateChangeTypeEnum.USE_SKILL.code);
        cultivateRecord.setCultivateId(skillUseDTO.getCultivateId());
        cultivateRecord.setSkillType(skillUseDTO.getSkillType());
        cultivateRecord.setWechatUserId(wechatUserId);
        createCultivateRecord(cultivateRecord);
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("银两摘取")
    @Override
    public void fishBallPick(FishBallPickDTO fishBallPickDTO) {
        if (fishBallPickDTO==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"银两摘取参数为空！");
        }
        if (fishBallPickDTO.getCultivateId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"养成Id为空！");
        }
        if (fishBallPickDTO.getFishBall()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"银两数量为空！");
        }
        if (fishBallPickDTO.getWechatUserId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"用户id为空！");
        }
        Long wechatUserId=fishBallPickDTO.getWechatUserId();
        Long cultivateId=fishBallPickDTO.getCultivateId();
        Cultivate cultivate = cultivateDao.getById(cultivateId);
        if (cultivate==null){
            throw new BookBizException(BookBizException.ERROR,"没有该养成！");
        }
        Integer notPick = getFishBallNotPick(cultivateId);
        if (notPick<=0){
            throw new BookBizException(BookBizException.ERROR,"没有可摘取的银两！");
        }
        cultivate.setFishBall(cultivate.getFishBall()+fishBallPickDTO.getFishBall());
        cultivateDao.update(cultivate);
        CultivateRecord cultivateRecord=new CultivateRecord();
        cultivateRecord.setWechatUserId(wechatUserId);
        cultivateRecord.setCultivateId(cultivateId);
        cultivateRecord.setChangeType(CultivateChangeTypeEnum.GET_FISH_BALL.code);
        cultivateRecord.setFishBallChangeType(FishBallChangeTypeEnum.USER_CHANGE.value);
        cultivateRecord.setFishBallChange(fishBallPickDTO.getFishBall());
        createCultivateRecord(cultivateRecord);
    }

    @ParamLog("获取现有未摘取银两")
    @Override
    public Integer getFishBallNotPick(Long cultivateId) {
        if (cultivateId==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"养成id为空！");
        }
        Cultivate cultivate = cultivateDao.getById(cultivateId);
        Long wechatUserId=cultivate.getWechatUserId();
        if (cultivate==null){
            throw new BookBizException(BookBizException.ERROR,"没有该养成！");
        }
        //熄灭状态
        if (!cultivate.getLighten()){
            return 0;
        }
        //查询上次点亮之后到现在的时间
        CultivateRecord lastLighten=cultivateRecordDao.getLastLighten(wechatUserId,cultivateId);
        if (lastLighten==null){
            return 0;
        }
        //一共产生的银两
        Integer proFishBall=(int)(new Date().getTime()-lastLighten.getCreateTime().getTime())/1000/60;
        //点亮期间已经摘取过的银两
        Integer gatherFishBallCount = cultivateRecordDao.getUserGatherFishBallCount(wechatUserId, cultivateId);
        //减去被占座的银两
        Integer fishBallNotPick=proFishBall-gatherFishBallCount;
        DealHoldSeatFriendFishBallDTO fishBall = getHoldSeatFriendFishBall(cultivateId, fishBallNotPick, lastLighten.getId());
        fishBallNotPick=fishBall.getOwnHasFishBall();
        return fishBallNotPick;
    }

    @Override
    public PageBeanNew<CultivateRecord> getCultivateRecordList(Long cultivateId, Long wechatUserId, Integer currentPage, Integer numPerPage) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("cultivateId", cultivateId);
        paramMap.put("wechatUserId", wechatUserId);
        PageBeanNew<CultivateRecord> pageBeanNew=cultivateRecordDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "getCultivateRecordList");
        if (pageBeanNew == null || ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, new ArrayList<>());
        }
        return pageBeanNew;
    }

    @Override
    public Long getLoginDays(Long wechatUserId) {
        WechatUser wechatUser = readerConsr.getWechatUser(wechatUserId);
        Long dateDiff = DateUtils.getDateDiff(wechatUser.getCreatedDate(), new Date());
        if(dateDiff==0){
            return 1L;
        }
        return dateDiff;
    }

    @Override
    public Integer getRanking(Long wechatUserId) {


        Integer ranking=0;
        List<Cultivate> list= cultivateDao.getAllOrderByStar();
        if(list==null||list.size()==0){
            return ranking;
        }

        for (int i=0;i<=list.size()-1;i++){
            Cultivate cultivate = list.get(i);
            if(cultivate.getWechatUserId().equals(wechatUserId)){
                ranking=i+1;
                return ranking;
            }
        }

        return ranking;
    }

    @Override
    @ParamLog("获取用户已获得勋章数据")
    public List<PersonalMedalRecordDto> getUserMedalList(Long wechatUserId) {
        List<PersonalMedalRecordDto> userMedalList = personalMedalRecordDao.getUserMedalList(wechatUserId);
        if(ListUtils.isEmpty(userMedalList)){
            return Lists.newArrayList();
        }
        return userMedalList;
    }

    @ParamLog("获取剩余亮灯时间")
    @Override
    public Integer getResidueLightTime(Long cultivateId) {
        if (cultivateId==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"养成id不能为空！");
        }
        //查询上次亮灯时间和亮灯之后的兑换的能量
        Cultivate cultivate = cultivateDao.getById(cultivateId);
        if (cultivate==null||!cultivate.getLighten()){
            return 0;
        }
        Long wechatUserId=cultivate.getWechatUserId();
        CultivateRecord lastLighten = cultivateRecordDao.getLastLighten(wechatUserId, cultivateId);
        if (lastLighten==null){
            return 0;
        }
        //获取点灯之前的最后一次消耗能量记录
        CultivateRecord consumptionBefore =cultivateRecordDao.getLastEnergyConsumptionBefore(lastLighten.getId(),wechatUserId);
        if (consumptionBefore==null){
            return 0;
        }
        Integer consumptionAfter = cultivateRecordDao.getEnergyConsumptionAfter(lastLighten.getId(), wechatUserId);
        Integer allEnergy=-consumptionBefore.getEnergyChange()+consumptionAfter;
        Integer time=allEnergy*60-(int)(new Date().getTime()-lastLighten.getCreateTime().getTime())/1000;
        if (time<=0){
            return 0;
        }
        return time;
    }

    @ParamLog("小睿养成读者喜好书籍")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long createCultivateBookUser(CultivateBookUser cultivateBookUser) {
        if (cultivateBookUser==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数为空！");
        }
        if (cultivateBookUser.getWechatUserId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"wechatUserId参数为空！");
        }
        if (StringUtil.isEmpty(cultivateBookUser.getBookName())){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"书名参数为空！");
        }
        if (cultivateBookUser.getReadType()==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"阅读类型参数为空！");
        }
        cultivateBookUserDao.insert(cultivateBookUser);
        return cultivateBookUser.getId();
    }

    @ParamLog("获取最后一次小睿养成读者喜好书籍")
    @Override
    public CultivateBookUser getLastCultivateBookUser(Long wechatUserId) {
        if (wechatUserId==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数为空！");
        }
        return cultivateBookUserDao.getLastCultivateBookUser(wechatUserId);
    }

    @Override
    public PageBeanNew<SearchBookVO> getBookSearchRecord(Long wechatUserId, Integer currentPage, Integer numPerPage) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("wechatUserId", wechatUserId);
        PageBeanNew<SearchBookVO> pageBeanNew=cultivateRecordDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "getBookSearchRecord");
        if (pageBeanNew == null || ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, new ArrayList<>());
        }

        //填充出版社信息
        List<Long> adviserIds=pageBeanNew.getRecordList().stream().filter(s->s.getAdviserId()!=null).map(SearchBookVO::getAdviserId).distinct().collect(Collectors.toList());
        Map<Long, AdviserBaseInfoDto> infoDtoMap = adviserConsr.getAdviserId2AdviserInfoDtoMap(adviserIds);
        List<Long> templetIds = new ArrayList<>();
        pageBeanNew.getRecordList().forEach(searchBookVO -> {

            if (Objects.nonNull(searchBookVO.getSecondTempletId())) {
                templetIds.add(searchBookVO.getSecondTempletId());
            }
        });
        Map<Long, AssistTempletDTO> assistTempletDTOMap = assistTempletConsr.mapByIds(templetIds);
        pageBeanNew.getRecordList().forEach(searchBookVO -> {
            Long secondTempletId = searchBookVO.getSecondTempletId();
            if (secondTempletId!=null&&assistTempletDTOMap!=null) {
                AssistTempletDTO templetDTO = assistTempletDTOMap.get(secondTempletId);
                searchBookVO.setSecondTempletName(Optional.ofNullable(templetDTO).map(AssistTempletDTO::getTempletName).orElse(null));
            }
            Long adviserId=searchBookVO.getAdviserId();
            if (infoDtoMap!=null){
                AdviserBaseInfoDto infoDto = infoDtoMap.get(adviserId);
                if (infoDto!=null){
                    searchBookVO.setAgentId(infoDto.getAgentId());
                    searchBookVO.setAgentName(infoDto.getAgentName());
                }
            }
        });
        return pageBeanNew;
    }



    @ParamLog("能量赠送")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void giveEnergy(GiveEnergyDTO giveEnergyDTO) {
        if (giveEnergyDTO==null||giveEnergyDTO.getCultivateId()==null
            ||giveEnergyDTO.getFriendCultivateId()==null||giveEnergyDTO.getEnergy()==null
            ||giveEnergyDTO.getEnergy()<0
        ){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"参数错误！");
        }
        String keyCh;
        if (giveEnergyDTO.getCultivateId()>giveEnergyDTO.getFriendCultivateId()){
            keyCh=giveEnergyDTO.getCultivateId()+"_"+giveEnergyDTO.getFriendCultivateId();
        }else {
            keyCh=giveEnergyDTO.getFriendCultivateId()+"_"+giveEnergyDTO.getCultivateId();
        }
        String key= CacheConstant.BOOK+"GIVE_ENERGY"+keyCh;
        if (JedisClusterUtils.setnx(key,giveEnergyDTO.getCultivateId().toString())){
            JedisClusterUtils.expire(key,10);
            try {
                Cultivate cultivate = cultivateDao.getById(giveEnergyDTO.getCultivateId());
                if (cultivate==null){
                    throw new BookBizException(BookBizException.PARAM_IS_ERROR,"账户为空！！");
                }
                if (cultivate.getEnergy()<giveEnergyDTO.getEnergy()){
                    throw new BookBizException(BookBizException.PARAM_IS_ERROR,"能量不足！");
                }
                Cultivate friendCultivate=cultivateDao.getById(giveEnergyDTO.getFriendCultivateId());
                if (friendCultivate==null){
                    throw new BookBizException(BookBizException.PARAM_IS_ERROR,"好友账户为空！！");
                }
                //自己账户减能量
                cultivate.setEnergy(cultivate.getEnergy()-giveEnergyDTO.getEnergy());
                cultivateDao.update(cultivate);
                //插入赠送能量记录
                CultivateRecord giveRecord=new CultivateRecord();
                giveRecord.setCultivateId(cultivate.getId());
                giveRecord.setChangeType(CultivateChangeTypeEnum.GIVE_ENERGY_TO_FRIEND.code);
                giveRecord.setFriendCultivateId(friendCultivate.getId());
                giveRecord.setEnergyChange(giveEnergyDTO.getEnergy());
                giveRecord.setWechatUserId(cultivate.getWechatUserId());
                createCultivateRecord(giveRecord);
                //好友账户增加
                friendCultivate.setEnergy(friendCultivate.getEnergy()+giveEnergyDTO.getEnergy());
                cultivateDao.update(friendCultivate);
                //插入被赠送能量记录
                CultivateRecord giveToRecord=new CultivateRecord();
                giveToRecord.setCultivateId(friendCultivate.getId());
                giveToRecord.setChangeType(CultivateChangeTypeEnum.GET_ENERGY_BY_FRIEND.code);
                giveToRecord.setFriendCultivateId(cultivate.getId());
                giveToRecord.setEnergyChange(giveEnergyDTO.getEnergy());
                giveToRecord.setWechatUserId(friendCultivate.getWechatUserId());
                createCultivateRecord(giveToRecord);
            } catch (Exception e){
                throw new BookBizException(BookBizException.ERROR,"该账户正在转账，请稍后！！");
            } finally {
                if (giveEnergyDTO.getCultivateId().toString().equals(JedisClusterUtils.get(key))){
                    JedisClusterUtils.del(key);
                }
            }
        }
    }

    @Override
    @ParamLog("分享")
    public String shareMedal(Long wechatUserId) {
        // 获取用户基本信息
        WechatUser wechatUser = readerConsr.getWechatUser(wechatUserId);
        Long loginDays =  getLoginDays(wechatUserId);
        List<PersonalMedal> baseMedalList = personalMedalBiz.getBaseMedalList();
        List<PersonalMedalRecordDto> personalMedalRecordDtos = new ArrayList<>();
        // TODO 换小程序二维码图片地址
        String projectQrcodeUrl="https://file.5rs.me/oss/uploadfe/jpg/5e586c6176e13b8806736581b9f641a0.jpg";
        //根据书币数获取勋章图片信息
        Cultivate cultivate = cultivateDao.getByWechatUserId(wechatUserId);
        if(CultivateConstant.FIRST_MEDAL_STAR<=cultivate.getStar()&&cultivate.getStar()<CultivateConstant.second_MEDAL_STAR) {
            PersonalMedalRecordDto personalMedalRecordDto=new PersonalMedalRecordDto();
            personalMedalRecordDto.setBigImgUrl(baseMedalList.get(0).getBigImgUrl());
            personalMedalRecordDtos.add(personalMedalRecordDto);
        }
        if(CultivateConstant.second_MEDAL_STAR<=cultivate.getStar()&&cultivate.getStar()<CultivateConstant.third_MEDAL_STAR) {
            for (int i=0;i<2 ;i++) {
                PersonalMedalRecordDto personalMedalRecordDto=new PersonalMedalRecordDto();
                personalMedalRecordDto.setLightImgUrl(baseMedalList.get(i).getLightImgUrl());
                personalMedalRecordDtos.add(personalMedalRecordDto);
            }
        }
        if(CultivateConstant.third_MEDAL_STAR<=cultivate.getStar()&&cultivate.getStar()<CultivateConstant.fourth_MEDAL_STAR) {
            for (int i=0;i<3 ;i++) {
                PersonalMedalRecordDto personalMedalRecordDto=new PersonalMedalRecordDto();
                personalMedalRecordDto.setLightImgUrl(baseMedalList.get(i).getLightImgUrl());
                personalMedalRecordDtos.add(personalMedalRecordDto);
            }
        }
        if(CultivateConstant.fourth_MEDAL_STAR<=cultivate.getStar()&&cultivate.getStar()<CultivateConstant.fifth_MEDAL_STAR) {
            for (int i=0;i<4 ;i++) {
                PersonalMedalRecordDto personalMedalRecordDto=new PersonalMedalRecordDto();
                personalMedalRecordDto.setLightImgUrl(baseMedalList.get(i).getLightImgUrl());
                personalMedalRecordDtos.add(personalMedalRecordDto);
            }
        }
        if(CultivateConstant.fifth_MEDAL_STAR<=cultivate.getStar()&&cultivate.getStar()<CultivateConstant.sixth_MEDAL_STAR) {
            for (int i=0;i<5 ;i++) {
                PersonalMedalRecordDto personalMedalRecordDto=new PersonalMedalRecordDto();
                personalMedalRecordDto.setLightImgUrl(baseMedalList.get(i).getLightImgUrl());
                personalMedalRecordDtos.add(personalMedalRecordDto);
            }
        }
        if(CultivateConstant.sixth_MEDAL_STAR<=cultivate.getStar()&&cultivate.getStar()<CultivateConstant.seventh_MEDAL_STAR){
            for (int i=0;i<6 ;i++) {
                PersonalMedalRecordDto personalMedalRecordDto=new PersonalMedalRecordDto();
                personalMedalRecordDto.setLightImgUrl(baseMedalList.get(i).getLightImgUrl());
                personalMedalRecordDtos.add(personalMedalRecordDto);
            }
        }

        if(CultivateConstant.seventh_MEDAL_STAR<=cultivate.getStar()){
            for (int i=0;i<7 ;i++) {
                PersonalMedalRecordDto personalMedalRecordDto=new PersonalMedalRecordDto();
                personalMedalRecordDto.setLightImgUrl(baseMedalList.get(i).getLightImgUrl());
                personalMedalRecordDtos.add(personalMedalRecordDto);
            }
        }
        if(wechatUser == null){
            throw new BizException(BizException.DB_DML_FAIL.getCode(), "未找到用户信息");
        }


        String html = null;
        if (personalMedalRecordDtos.size() == 1){
            //只生成大图
            html = buildMedalHtml4Big(personalMedalRecordDtos.get(0), wechatUser, projectQrcodeUrl,loginDays);
        }else {
            //多个小图
            html = buildMedalHtml4Little(personalMedalRecordDtos, wechatUser, projectQrcodeUrl,loginDays);
        }
        HtmlDto htmlDto=new HtmlDto();
        htmlDto.setHeight(1206);
        htmlDto.setWidth(750);
        htmlDto.setHtmlCode(html);
        htmlDto.setSnapshot(new Long(System.currentTimeMillis()).toString());
        return ResponseHandleUtil.parseResponse(htm2ImgService.toJPGByChrome(htmlDto),String.class);
    }

    private String buildMedalHtml4Little(List<PersonalMedalRecordDto> personalMedalRecordDtos, WechatUser wechatUser, String projectQrcodeUrl, Long loginDays) {
        PersonalShareTemplate personalShareTemplate = personalShareTemplateMapper.selectByPrimaryKey(2);
        String html = personalShareTemplate.getContent();
        html = html.replace("${headUrl}",wechatUser.getWechatUserHeadurl());
        html = html.replace("${nickName}",wechatUser.getWechatUserNickname());
        html = html.replace("${loginDays}",loginDays.toString());
        html = html.replace("${classifyQrcode}",projectQrcodeUrl);
        html = html.replace("${medalCount}",personalMedalRecordDtos.size()+"");
        StringBuffer medalImg = new StringBuffer();
        for(PersonalMedalRecordDto personalMedalRecordDto : personalMedalRecordDtos){
            Integer level= personalMedalRecordDtos.indexOf(personalMedalRecordDto)+1;
            //medalImg += "<img src='"+personalMedalRecordDto.getLightImgUrl()+"'class=\"medal medal-lv" + personalMedalRecordDtos.indexOf(personalMedalRecordDto)+1 + "\" />";
            medalImg.append("<div class='medal-container ");
            medalImg.append("medal-lv");
            medalImg.append(level);
            medalImg.append("'>");
            medalImg.append("<img src='");
            medalImg.append(personalMedalRecordDto.getLightImgUrl());
            medalImg.append("' class='medal' />");
            medalImg.append("</div>");
        }
        List<PersonalMedal> baseMedalList = personalMedalBiz.getBaseMedalList();
        for(int i=personalMedalRecordDtos.size();i<=baseMedalList.size()-1;i++){
            // medalImg +=  "<img src='"+baseMedalList.get(i).getGreyImgUrl()+"'class=\"medal\" />";
            medalImg.append("<div class='medal-container'>");
            medalImg.append("<img src='");
            medalImg.append(baseMedalList.get(i).getGreyImgUrl());
            medalImg.append("' class='medal' />");
            medalImg.append("</div>");
        }
        html = html.replace("${medalImgs}",medalImg);
        return  html;
    }

    private String buildMedalHtml4Big(PersonalMedalRecordDto personalMedalRecordDto, WechatUser wechatUser,String projectQrcodeUrl, Long loginDays) {
        PersonalShareTemplate personalShareTemplate = personalShareTemplateMapper.selectByPrimaryKey(1);
        String html = personalShareTemplate.getContent();
        html = html.replace("${headUrl}",wechatUser.getWechatUserHeadurl());
        html = html.replace("${nickName}",wechatUser.getWechatUserNickname());
        html = html.replace("${loginDays}",loginDays.toString());
        html = html.replace("${classifyQrcode}",projectQrcodeUrl);
        return  html;
    }

    @ParamLog("银两兑换后是否升级")
    private Boolean isUpGrade(Integer oldStarCounts,Integer newStarCounts){
        if(CultivateConstant.FIRST_MEDAL_STAR<=oldStarCounts&&oldStarCounts<CultivateConstant.second_MEDAL_STAR&&newStarCounts>=CultivateConstant.second_MEDAL_STAR) {
           return true;

        }
        if(CultivateConstant.second_MEDAL_STAR<=oldStarCounts&&oldStarCounts<CultivateConstant.third_MEDAL_STAR&&newStarCounts>=CultivateConstant.third_MEDAL_STAR) {
            return true;
        }
        if(CultivateConstant.third_MEDAL_STAR<=oldStarCounts&&oldStarCounts<CultivateConstant.fourth_MEDAL_STAR&&newStarCounts>=CultivateConstant.fourth_MEDAL_STAR) {
            return true;
        }
        if(CultivateConstant.fourth_MEDAL_STAR<=oldStarCounts&&oldStarCounts<CultivateConstant.fifth_MEDAL_STAR&&newStarCounts>=CultivateConstant.fifth_MEDAL_STAR) {
            return true;
        }
        if(CultivateConstant.fifth_MEDAL_STAR<=oldStarCounts&&oldStarCounts<CultivateConstant.sixth_MEDAL_STAR&&newStarCounts>=CultivateConstant.sixth_MEDAL_STAR) {
            return true;
        }
        return false;
    }


    @Override
    public List<FriendDTO> getFriendList(Long cultivateId) {
        //随机选十个好友。但是如果在其他好友占位，则占第一位
        //先找被占座的好友
        Long friendCultivateId = cultivateHoldSeatDao.getFriendCultivateIdById(cultivateId);
        List<Cultivate> cultivates=new ArrayList<>();
        if(null==friendCultivateId){
            //如果没有好友，随机选十个
            cultivates = cultivateDao.getRandomUserId(cultivateId, null);
        }else{
            //有占座，随机选九个
            Cultivate cultivate = cultivateDao.getById(friendCultivateId);
            cultivate.setSeq(0);
            cultivates.add(cultivate);
            List<Cultivate> randomUserId = cultivateDao.getRandomUserId(cultivateId, friendCultivateId);
            for (int i = 0; i < randomUserId.size(); i++) {
                Cultivate cultivate1 = randomUserId.get(i);
                cultivate1.setSeq(i+1);
                cultivates.add(cultivate1);
            }
            cultivates.sort(Comparator.comparingInt(a->a.getSeq()));
        }
        if(ListUtils.isEmpty(cultivates)){
            return new ArrayList<>();
        }
        List<Long> userIds = cultivates.stream().map(a -> a.getWechatUserId()).distinct().collect(Collectors.toList());
        List<Long> cultivateIds = cultivates.stream().map(a -> a.getId()).distinct().collect(Collectors.toList());
        Map<Long, WechatUser> userMap = readerConsr.getUserList(userIds);
        Map<Long, Integer> levelMap = buildLevalMap(cultivateIds);
        List<FriendDTO> list=new ArrayList<>();
        FriendDTO friendDTO=null;
        for (Cultivate cultivate : cultivates) {
            friendDTO=new FriendDTO();
            friendDTO.setCultivateId(cultivate.getId());
            friendDTO.setWechatUserId(cultivate.getWechatUserId());
            if(MapUtils.isNotEmpty(userMap) && userMap.containsKey(cultivate.getWechatUserId())){
                WechatUser wechatUser = userMap.get(cultivate.getWechatUserId());
                friendDTO.setHeadPic(null==wechatUser?null:wechatUser.getWechatUserHeadurl());
            }
            //是否在学习中
            friendDTO.setInSeat(false);
            if(null!=cultivateId ){
                if(null!=cultivate && cultivate.getId().equals(friendCultivateId)) {
                    friendDTO.setInSeat(true);
                }
            }
            friendDTO.setLevel(1);
            if(MapUtils.isNotEmpty(levelMap) && levelMap.containsKey(cultivate.getId())){
                Integer level = levelMap.get(cultivate.getId());
                friendDTO.setLevel(level);
            }
            list.add(friendDTO);
        }
        return list;
    }

    private Map<Long, Integer> buildLevalMap(List<Long> cultivateIds){
        List<Cultivate> cultivateList = cultivateDao.getByCultivateIds(cultivateIds);
        for (Cultivate cultivate : cultivateList) {
            Integer level = getLevel(cultivate.getStar());
            cultivate.setLevel(level);
        }
        Map<Long, Integer> LevelMap = cultivateList.stream().collect(Collectors.toMap(Cultivate::getId, Cultivate::getLevel, (v1, v2) -> v2));
        return LevelMap;
    }

    private Integer getLevel(Integer star){
        Integer level = 0;
        if (star <CultivateConstant.FIRST_MEDAL_STAR) {
            level = 0;
        } else if (star >= CultivateConstant.FIRST_MEDAL_STAR && star < CultivateConstant.second_MEDAL_STAR) {
            level = 1;
        } else if (star >= CultivateConstant.second_MEDAL_STAR && star < CultivateConstant.third_MEDAL_STAR) {
            level = 2;
        } else if (star >= CultivateConstant.third_MEDAL_STAR && star < CultivateConstant.fourth_MEDAL_STAR) {
            level = 3;
        } else if (star >= CultivateConstant.fourth_MEDAL_STAR && star < CultivateConstant.fifth_MEDAL_STAR) {
            level = 4;
        } else if (star >= CultivateConstant.fifth_MEDAL_STAR && star < CultivateConstant.sixth_MEDAL_STAR) {
            level = 5;
        } else if (star >= CultivateConstant.sixth_MEDAL_STAR && star < CultivateConstant.seventh_MEDAL_STAR) {
            level = 6;
        } else if (star >= CultivateConstant.seventh_MEDAL_STAR && star < CultivateConstant.eighth_MEDAL_STAR) {
            level = 7;
        } else {
            level = 8;
        }
        return level;
    }

    @Override
    @ParamLog("占座")
    @Transactional(rollbackFor = Exception.class)
    public void holdSeat(HoldSeatDTO holdSeatDTO) {
        if(null==holdSeatDTO || null==holdSeatDTO.getCultivateId() || null==holdSeatDTO.getFriendCultivateId()){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"参数错误！");
        }
        //占座之前要判断被占座的用户是否开灯或者是否还有空位
        Cultivate friendCultivate = cultivateDao.getById(holdSeatDTO.getFriendCultivateId());
        if(null!=friendCultivate && null!=friendCultivate.getLighten() && !friendCultivate.getLighten()){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"不能占位,当前好友未点亮！");
        }
        List<Long> cultivateIds = cultivateHoldSeatDao.getCultivateIdByFriendId(holdSeatDTO.getFriendCultivateId());
        if(!ListUtils.isEmpty(cultivateIds) && cultivateIds.size()>=2){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"不能占位,当前好友座位已被占满！");
        }
        ThreadPoolUtils.SIGN_OUT_THREAD_POOL.execute(()->{
            //占座之前如果已经在别人家学习，要先退出，再占位
            Long friendCultivateId = cultivateHoldSeatDao.getFriendCultivateIdById(holdSeatDTO.getCultivateId());
            if(null!=friendCultivateId){
                //已经在别人家学习,要先退出
                HoldSeatDTO holdSeatDTO1=new HoldSeatDTO();
                holdSeatDTO1.setCultivateId(holdSeatDTO.getCultivateId());
                holdSeatDTO1.setFriendCultivateId(friendCultivateId);
                this.signOut(holdSeatDTO1);
            }
        });
        CultivateHoldSeat holdSeat=new CultivateHoldSeat();
        BeanUtils.copyProperties(holdSeatDTO,holdSeat);
        cultivateHoldSeatDao.insert(holdSeat);
        //加占位记录
        CultivateRecord holdSeatRecord=new CultivateRecord();
        holdSeatRecord.setCultivateId(holdSeatDTO.getCultivateId());
        holdSeatRecord.setFriendCultivateId(holdSeat.getFriendCultivateId());
        holdSeatRecord.setChangeType(CultivateChangeTypeEnum.HOLD_FRIEND_SEAT.code);
        Cultivate cultivate = cultivateDao.getById(holdSeatDTO.getCultivateId());
        holdSeatRecord.setWechatUserId(cultivate.getWechatUserId());
        createCultivateRecord(holdSeatRecord);
        //加被占位记录
        CultivateRecord holdSeatByRecord=new CultivateRecord();
        holdSeatByRecord.setCultivateId(holdSeatDTO.getFriendCultivateId());
        holdSeatByRecord.setFriendCultivateId(holdSeat.getCultivateId());
        holdSeatByRecord.setChangeType(CultivateChangeTypeEnum.HOLD_SEAT_BY_FRIEND.code);
        Cultivate friend = cultivateDao.getById(holdSeatDTO.getFriendCultivateId());
        holdSeatByRecord.setWechatUserId(friend.getWechatUserId());
        createCultivateRecord(holdSeatByRecord);
        //改变是否在家状态
        cultivateDao.updateIsHome(0,holdSeatDTO.getCultivateId());
    }

    @Override
    @ParamLog("踢人")
    @Transactional(rollbackFor = Exception.class)
    public void kickPeople(HoldSeatDTO holdSeatDTO) {
        if(null==holdSeatDTO || null==holdSeatDTO.getCultivateId() || null==holdSeatDTO.getFriendCultivateId()){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"参数错误！");
        }
        // 1.算踢走这个人时候这个人的能量，并加上，然后主人能量获取速度变化。
        //其实主人此时收能量只需要时间*3减去两个人的能量。
        //注意 这里 CultivateId应该是踢人的人  FriendCultivateId是被踢的人
        Cultivate cultivate=cultivateDao.getById(holdSeatDTO.getCultivateId());
        Cultivate friend=cultivateDao.getById(holdSeatDTO.getFriendCultivateId());
        //拿踢人的人最后一次点亮记录和被踢人占座的时间比较
        CultivateRecord lastLighten = cultivateRecordDao.getLastLighten(cultivate.getWechatUserId(), holdSeatDTO.getCultivateId());
        CultivateHoldSeat cultivateHoldSeat = cultivateHoldSeatDao.getById(holdSeatDTO.getFriendCultivateId(), holdSeatDTO.getCultivateId());
        Integer proFishBall=0;
        Integer minute=0;
        if(null!=lastLighten && null!=cultivateHoldSeat && cultivateHoldSeat.getCreateTime().after(lastLighten.getCreateTime())){
            //如果是最后一次点灯之后进来的，计算就是进来到踢走这段时间的能量
            //一共产生的银两
            minute=(int)(new Date().getTime()-cultivateHoldSeat.getCreateTime().getTime())/1000/60;
        }else if(null!=lastLighten && null!=cultivateHoldSeat && cultivateHoldSeat.getCreateTime().before(lastLighten.getCreateTime())){
            //如果是最后一次点灯之前就在，计算就是点灯到踢走这段时间的能量
            //一共产生的银两
            minute =(int)(new Date().getTime()-lastLighten.getCreateTime().getTime())/1000/60;
        }else{
            minute=0;
        }
        //计算银两
        if(minute<=0){
            proFishBall=0;
        }else{
            proFishBall=((Double)(minute*0.3)).intValue();
        }
        friend.setFishBall(friend.getFishBall()+proFishBall);
        cultivateDao.update(friend);
        //加踢人的记录
        CultivateRecord kickRecord=new CultivateRecord();
        kickRecord.setCultivateId(holdSeatDTO.getCultivateId());
        kickRecord.setFriendCultivateId(holdSeatDTO.getFriendCultivateId());
        kickRecord.setWechatUserId(cultivate.getWechatUserId());
        kickRecord.setChangeType(CultivateChangeTypeEnum.KICK_OUT_FRIEND_BY_SELF.code);
        createCultivateRecord(kickRecord);
        //加被踢记录
        CultivateRecord byKickRecord=new CultivateRecord();
        byKickRecord.setCultivateId(holdSeatDTO.getFriendCultivateId());
        byKickRecord.setFriendCultivateId(holdSeatDTO.getCultivateId());
        byKickRecord.setWechatUserId(friend.getWechatUserId());
        byKickRecord.setChangeType(CultivateChangeTypeEnum.KICK_OUT_BY_FRIEND.code);
        createCultivateRecord(byKickRecord);

        //4.删除占位表数据
        cultivateHoldSeatDao.deleteById(holdSeatDTO.getFriendCultivateId(),holdSeatDTO.getCultivateId());

        //5.回到家 改变是否在家状态
        cultivateDao.updateIsHome(1,holdSeatDTO.getFriendCultivateId());
    }

    @Override
    @ParamLog("退出")
    @Transactional(rollbackFor = Exception.class)
    public Integer signOut(HoldSeatDTO holdSeatDTO) {
        if(null==holdSeatDTO || null==holdSeatDTO.getCultivateId() || null==holdSeatDTO.getFriendCultivateId()){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"参数错误！");
        }
        // 1.算退出这个人时候这个人的能量，并加上，然后主人能量获取速度变化。
        //其实主人此时收能量只需要时间*3减去两个人的能量。
        //注意 这里 CultivateId应该是占座的人  FriendCultivateId是被占座的人
        Cultivate cultivate=cultivateDao.getById(holdSeatDTO.getCultivateId());
        Cultivate friend=cultivateDao.getById(holdSeatDTO.getFriendCultivateId());
        //拿踢人的人最后一次点亮记录和被踢人占座的时间比较
        CultivateRecord lastLighten = cultivateRecordDao.getLastLighten(friend.getWechatUserId(), holdSeatDTO.getFriendCultivateId());
        CultivateHoldSeat cultivateHoldSeat = cultivateHoldSeatDao.getById(holdSeatDTO.getCultivateId(), holdSeatDTO.getFriendCultivateId());
        Integer proFishBall=0;
        Integer minute=0;
        //先计算
        if(null!=lastLighten && null!=cultivateHoldSeat && cultivateHoldSeat.getCreateTime().after(lastLighten.getCreateTime())){
            //如果是最后一次点灯之后进来的，计算就是进来到踢走这段时间的能量
            //一共产生的银两  每分钟1个。N个人分
            minute=(int)(new Date().getTime()-cultivateHoldSeat.getCreateTime().getTime())/1000/60;
        }else if(null!=lastLighten && null!=cultivateHoldSeat && cultivateHoldSeat.getCreateTime().before(lastLighten.getCreateTime())){
            //如果是最后一次点灯之前就在，计算就是点灯到踢走这段时间的能量
            //一共产生的银两
            minute =(int)(new Date().getTime()-lastLighten.getCreateTime().getTime())/1000/60;
        }else{
            minute=0;
        }
        //计算银两
        if(minute<=0){
            proFishBall=0;
        }else{
            proFishBall=((Double)(minute*0.3)).intValue();
        }
        cultivate.setFishBall(cultivate.getFishBall()+proFishBall);
        cultivateDao.update(cultivate);

        //加退出记录
        CultivateRecord exitRecord=new CultivateRecord();
        exitRecord.setCultivateId(holdSeatDTO.getCultivateId());
        exitRecord.setWechatUserId(cultivate.getWechatUserId());
        exitRecord.setChangeType(CultivateChangeTypeEnum.EXIT_FRIEND_SEAT.code);
        exitRecord.setFriendCultivateId(holdSeatDTO.getFriendCultivateId());
        exitRecord.setFishBallChange(proFishBall);
        createCultivateRecord(exitRecord);
        //加被退出记录
        CultivateRecord byExitRecord=new CultivateRecord();
        byExitRecord.setCultivateId(holdSeatDTO.getFriendCultivateId());
        byExitRecord.setWechatUserId(friend.getWechatUserId());
        byExitRecord.setChangeType(CultivateChangeTypeEnum.FRIEND_EXIT_SEAT.code);
        byExitRecord.setFriendCultivateId(holdSeatDTO.getCultivateId());
        createCultivateRecord(byExitRecord);
        //4.删除占位表数据
        cultivateHoldSeatDao.deleteById(holdSeatDTO.getCultivateId(),holdSeatDTO.getFriendCultivateId());

        //5.回到家 改变是否在家状态
        cultivateDao.updateIsHome(1,holdSeatDTO.getCultivateId());
        return proFishBall;
    }

    @Override
    @ParamLog("找回")
    public Long getBack(Long cultivateId) {
        Long friendCultivateId = cultivateHoldSeatDao.getFriendCultivateIdById(cultivateId);
        return friendCultivateId;
    }

    @Override
    @ParamLog("占座两个好友")
    public List<FriendDTO> getHoldSeatFriend(Long cultivateId) {
        List<Long> cultivateIdByFriendId = cultivateHoldSeatDao.getCultivateIdByFriendId(cultivateId);
        if(ListUtils.isEmpty(cultivateIdByFriendId)){
            return new ArrayList<>();
        }
        Map<Long, Integer> levelMap = buildLevalMap(cultivateIdByFriendId);
        List<Cultivate> cultivates = cultivateDao.getByCultivateIds(cultivateIdByFriendId);
        List<Long> userIds = Optional.ofNullable(cultivates.stream().map(a -> a.getWechatUserId()).collect(Collectors.toList())).orElse(new ArrayList<>());
        Map<Long, WechatUser> userMap = readerConsr.getUserList(userIds);
        List<FriendDTO> list=new ArrayList<>();
        FriendDTO friendDTO=null;
        for (Cultivate cultivate : cultivates) {
            friendDTO=new FriendDTO();
            friendDTO.setCultivateId(cultivate.getId());
            friendDTO.setWechatUserId(cultivate.getWechatUserId());
            if(MapUtils.isNotEmpty(userMap) && userMap.containsKey(cultivate.getWechatUserId())){
                WechatUser wechatUser = userMap.get(cultivate.getWechatUserId());
                friendDTO.setHeadPic(null==wechatUser?null:wechatUser.getWechatUserHeadurl());
            }
            friendDTO.setLevel(1);
            if(MapUtils.isNotEmpty(levelMap) && levelMap.containsKey(cultivate.getId())){
                Integer level = levelMap.get(cultivate.getId());
                friendDTO.setLevel(level);
            }
            list.add(friendDTO);
        }
        return list;
    }

    @Override
    @ParamLog("是否在学习中")
    public Boolean beforeHoldSeat(Long cultivateId) {
        Long friendCultivateIdById = cultivateHoldSeatDao.getFriendCultivateIdById(cultivateId);
        return null!=friendCultivateIdById?true:false;
    }

    @Override
    public CultivateDTO getCultivateBaseInfo(Long cultivateId) {
        if (cultivateId==null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"cultivateId为空！");
        }
        Cultivate cultivate = cultivateDao.getById(cultivateId);
        if(null==cultivate){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"未能找到当前用户！");
        }
        CultivateDTO cultivateDTO=new CultivateDTO();
        BeanUtils.copyProperties(cultivate,cultivateDTO);
        //TODO 计算等级勋章等，获取用户基本信息等
        WechatUser wechatUser = readerConsr.getWechatUser(cultivate.getWechatUserId());
        cultivateDTO.setPicUrl(null!=wechatUser?wechatUser.getWechatUserHeadurl():null);
        return cultivateDTO;
    }
}
