package com.fdkankan.ucenter.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.common.constant.SceneConstant;
import com.fdkankan.common.constant.SceneKind;
import com.fdkankan.common.constant.SceneVersionType;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.util.*;
import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
import com.fdkankan.rabbitmq.util.RabbitMqProducer;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.ucenter.common.OssPath;
import com.fdkankan.ucenter.common.PageInfo;
import com.fdkankan.fyun.face.FYunFileServiceInterface;
import com.fdkankan.redis.util.RedisUtil;
import com.fdkankan.ucenter.common.SceneEnum;
import com.fdkankan.ucenter.common.SceneSourceUtil;
import com.fdkankan.ucenter.common.constants.ResultCodeMsg;
import com.fdkankan.ucenter.config.UcenterConfig;
import com.fdkankan.ucenter.config.ThreadPoolConfig;
import com.fdkankan.ucenter.constant.CameraConstant;
import com.fdkankan.ucenter.constant.LoginConstant;
import com.fdkankan.ucenter.entity.*;
import com.fdkankan.ucenter.httpClient.service.LaserService;
import com.fdkankan.ucenter.mapper.ISceneProMapper;
import com.fdkankan.ucenter.mapper.ISceneUpgradeMapper;
import com.fdkankan.ucenter.mq.common.MqQueueUtil;
import com.fdkankan.ucenter.service.*;
import com.fdkankan.ucenter.util.DateUserUtil;
import com.fdkankan.ucenter.util.SceneResourcePath;
import com.fdkankan.ucenter.vo.ResponseScene;
import com.fdkankan.ucenter.vo.request.RequestScene;
import com.fdkankan.ucenter.vo.request.SceneParam;
import com.fdkankan.ucenter.vo.response.*;

import java.io.File;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

/**
 * <p>
 * pro场景表 服务实现类
 * </p>
 *
 * @author 
 * @since 2022-07-04
 */
@Service
@Slf4j
public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro> implements ISceneProService {

    @Autowired
    private IUserService userService;
    @Autowired
    private ISceneCooperationService sceneCooperationService;
    @Autowired
    private IScenePlusService scenePlusService;
    @Autowired
    private ISceneService sceneService;
    @Autowired
    private LaserService fdkkLaserService;
    @Autowired
    private FYunFileServiceInterface fYunFileService;
    @Autowired
    private IUserIncrementService userIncrementService;
    @Autowired
    private IIncrementTypeService incrementTypeService;
    @Autowired
    private IScenePlusExtService scenePlusExtService;
    @Autowired
    private ISceneEditInfoService sceneEditInfoService;
    @Autowired
    private ICameraDetailService cameraDetailService;
    @Autowired
    ICameraService cameraService;
    @Autowired
    private IFolderService folderService;
    @Autowired
    private IFolderSceneService folderSceneService;
    @Autowired
    private ISceneCopyLogService sceneCopyLogService;
    @Autowired
    private IScene3dNumService scene3dNumService;
    @Autowired
    private ISceneProEditService sceneProEditService;
    @Autowired
    private SceneCommonService sceneCommonService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ISceneUpgradeMapper sceneUpgradeMapper;
    @Autowired
    private IInnerService innerService;
    @Autowired
    LaserService laserService;
    @Autowired
    private FYunFileServiceInterface fYunFileServiceInterface;
    @Autowired
    ISceneDelLogService sceneDelLogService;

    @Value("${queue.modeling.obj.modeling-pre}")
    private String queueObjModelingPre;

    @Autowired
    private RabbitMqProducer mqProducer;
    @Autowired
    ICameraTypeService cameraTypeService;

    @Override
    public HashMap<String, SceneNumVo> findSceneNumber(String token) {
        HashMap<String, SceneNumVo> hashMap = new HashMap<>();
        User user = userService.getByUserName(JwtUtil.getUsername(token));
//        SceneNumVo sceneNumVoKk = getSceneNumVoByType(Arrays.asList(1,2,12,13,14), user.getId());
//        Integer oldNum = sceneService.getCountByUserId(user.getId());
//        sceneNumVoKk.setSceneNum( oldNum + sceneNumVoKk.getSceneNum());
//        sceneNumVoKk.setTotalNum(oldNum + sceneNumVoKk.getTotalNum());
//
//        SceneNumVo sceneNumVoKj = getSceneNumVoByType(Collections.singletonList(3), user.getId());
//
//        SceneNumVo sceneNumVoSS = fdkkLaserService.getLaserSceneNumByUser(token,4);
//        SceneNumVo sceneNumVoSSObj = getSceneNumVoByObjType(Arrays.asList(4), user.getId());
//
//        SceneNumVo sceneNumVoSG = fdkkLaserService.getLaserSceneNumByUser(token,5);
//        SceneNumVo sceneNumVoSGObj = getSceneNumVoByObjType(Arrays.asList(5), user.getId());
//
//        SceneNumVo sceneNumVoE57 = fdkkLaserService.getLaserSceneNumByUser(token,57);
//        SceneNumVo sceneNumVoE57Obj = getSceneNumVoByObjType(Arrays.asList(57), user.getId());
//
//        SceneNumVo sceneNumVoSX = fdkkLaserService.getLaserSceneNumByUser(token,7);
//        hashMap.put("kk",sceneNumVoKk);
//        hashMap.put("kJ",sceneNumVoKj);
//        hashMap.put("SS",sceneNumVoSS);
//        hashMap.put("SS_OBJ",sceneNumVoSSObj);
//        hashMap.put("SG",sceneNumVoSG);
//        hashMap.put("SG_OBJ",sceneNumVoSGObj);
//        hashMap.put("e57",sceneNumVoE57);
//        hashMap.put("e57_OBJ",sceneNumVoE57Obj);
//        hashMap.put("sx",sceneNumVoSX);


        List<SceneNumVo> groupBySceneSouceV3 = scenePlusService.getGroupBySceneSouceV3(user.getId());
        List<SceneNumVo> groupBySceneSouceV4 = scenePlusService.getGroupBySceneSouceV4(user.getId());
        List<SceneNumVo> groupCooperationSceneNum = sceneCooperationService.getGroupCooperationSceneNum(user.getId());
        Integer count = sceneService.getCountByUserId(user.getId());

        groupBySceneSouceV4.addAll(groupBySceneSouceV3);
        groupBySceneSouceV4.addAll(groupCooperationSceneNum);

        SceneEnum[] values = SceneEnum.values();
        for (SceneEnum sceneEnum : values) {
//            if(sceneEnum.getObj() == 0){
//                SceneNumVo sceneNumVo1 = fdkkLaserService.getLaserSceneNumByUser(token, sceneEnum.getSceneSource().get(0));
//                hashMap.put(sceneEnum.getName(),sceneNumVo1);
//            }
            if(sceneEnum.getName().equals("kk")){
                SceneNumVo sceneNumVo = new SceneNumVo();
                sceneNumVo.setSceneNum(Long.valueOf(count));
                hashMap.put(sceneEnum.getName(),sceneNumVo);
            } else {
                hashMap.put(sceneEnum.getName(),new SceneNumVo());
            }

        }

        for (SceneNumVo vo : groupBySceneSouceV4) {
            SceneEnum sceneEnum = SceneEnum.getBySceneSource(vo.getType(), vo.getIsObj());
            if(sceneEnum == null ){
                continue;
            }
            SceneNumVo sceneNumVo = hashMap.get(sceneEnum.getName());
            sceneNumVo.setSceneNum( sceneNumVo.getSceneNum() + vo.getSceneNum() );
            sceneNumVo.setCooperationSceneNum( sceneNumVo.getCooperationSceneNum() + vo.getCooperationSceneNum() );
            sceneNumVo.setTotalNum(sceneNumVo.getSceneNum() + sceneNumVo.getCooperationSceneNum());
            hashMap.put(sceneEnum.getName(),sceneNumVo);
        }
        return hashMap;
    }


    private SceneNumVo getSceneNumVoByType(List<Integer> sceneSourceList, Long userId){
        SceneNumVo sceneNumVo = new SceneNumVo();
        LambdaQueryWrapper<ScenePro> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ScenePro::getUserId, userId);
        queryWrapper.in(ScenePro::getSceneSource, sceneSourceList);
        queryWrapper.eq(ScenePro::getIsUpgrade, 0);
        Integer sceneNum = Math.toIntExact(this.count(queryWrapper));

        Long count = scenePlusService.getCountByUserId(userId,sceneSourceList);
        sceneNumVo.setCooperationSceneNum(sceneCooperationService.getCooperationSceneNum(userId,sceneSourceList));
        sceneNumVo.setSceneNum(sceneNum + count);
        sceneNumVo.setTotalNum(sceneNumVo.getSceneNum() + sceneNumVo.getCooperationSceneNum());
        return sceneNumVo;
    }
    private SceneNumVo getSceneNumVoByObjType(List<Integer> sceneSourceList, Long userId){
        SceneNumVo sceneNumVo = new SceneNumVo();
        LambdaQueryWrapper<ScenePro> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ScenePro::getUserId, userId);
        queryWrapper.in(ScenePro::getSceneSource, sceneSourceList);
        queryWrapper.eq(ScenePro::getIsUpgrade, 0);
        queryWrapper.eq(ScenePro::getIsObj,1);
        Integer sceneNum = Math.toIntExact(this.count(queryWrapper));
        List<ScenePlus> scenePlusList = scenePlusService.getCountByUserIdAndSceneSource(userId,sceneSourceList,1);

        long plusCount = scenePlusList.size();
        Long cooperNum = sceneCooperationService.getCooperationSceneNum(userId, sceneSourceList);

        sceneNumVo.setCooperationSceneNum(cooperNum);
        sceneNumVo.setSceneNum(sceneNum + plusCount);
        sceneNumVo.setTotalNum(sceneNumVo.getSceneNum() + sceneNumVo.getCooperationSceneNum());
        return sceneNumVo;
    }


    @Override
    public HashMap<Long,GroupByCount> findSceneNumByCameraIds(List<Long> cameraIdList) {
        HashMap<Long,GroupByCount> map = new HashMap<>();
        List<GroupByCount> result = this.getBaseMapper().findSceneProNumByCameraIds(cameraIdList);
        List<GroupByCount> result2 = this.getBaseMapper().findScenePlusNumByCameraIds(cameraIdList);
        result.forEach(entity ->map.put(entity.getId(),entity));
        for (GroupByCount groupByCount : result2) {
            GroupByCount groupByCount1 = map.get(groupByCount.getId());

            if (groupByCount1 != null) {
                if(groupByCount1.getCount() == null){
                    groupByCount1.setCount(0L);
                }
                if(groupByCount.getCount() == null){
                    groupByCount.setCount(0L);
                }
                if(groupByCount1.getSpace() == null){
                    groupByCount1.setSpace(0L);
                }
                if(groupByCount.getSpace() == null){
                    groupByCount.setSpace(0L);
                }
                Long totalCount = groupByCount1.getCount()  + groupByCount.getCount();
                String lastTime = DateUserUtil.getLastTime(groupByCount1.getLastTime(), groupByCount.getLastTime());
                groupByCount.setCount(totalCount);
                groupByCount.setLastTime(lastTime);

                Long totalSpace = groupByCount1.getSpace() + groupByCount.getSpace();
                groupByCount.setSpace(totalSpace);
            }
            map.put(groupByCount.getId(),groupByCount);
        }
        return map;
    }

    public void lockOrUnLockBySpace(Long cameraId){
        CameraDetail cameraDetail = cameraDetailService.getByCameraId(cameraId);
        this.lockOrUnLockBySpace(cameraDetail,cameraId);
    }

    @Autowired
    ThreadPoolConfig threadPoolConfig;
    @Override
    public void lockOrUnLockBySpace(CameraDetail cameraDetail, Long cameraId) {
        threadPoolConfig.taskExecutor().execute(() -> {
            log.info("异步任务执行，当前线程：" + Thread.currentThread().getName());
            List<SimpleSceneVo> voList = this.getSimpleSceneVo(cameraDetail);
            if(voList .size() <=0){
                return;
            }
            CameraType cameraType = cameraTypeService.getByCameraType(cameraDetail.getType());

            Long totalSpace = cameraDetailService.getTotalSpaceByCameraId(cameraDetail);
            Long usedSpace = 0L;

            //获取未被封存的场景容量
            List<Long> spaceList = voList.stream().filter(entity -> entity.getPayStatus() == 1).map(SimpleSceneVo::getSpace).collect(Collectors.toList());
            if("SP".equals(cameraDetail.getUnit())){
                usedSpace = (long) spaceList.size();
            }
            if("GB".equals(cameraDetail.getUnit())){
                for (Long aLong : spaceList) {
                    usedSpace += aLong;
                }
            }
            //计算时间倒序
            List<SimpleSceneVo> sceneVos = voList.stream().sorted(Comparator.comparing(SimpleSceneVo::getCreateTime).reversed()).collect(Collectors.toList());

            if(totalSpace == -1){  //  无限容量 全部解封
                sceneVos =  sceneVos.stream().filter(e -> e.getPayStatus() !=1).collect(Collectors.toList());
                lockOrUnLockScenes(sceneVos,1,cameraType);
                return;
            }

            //按计算完成时间由新到旧封存
            //按计算完成时间由旧到新解封
            //payStatus 1解封，-2封存
            List<SimpleSceneVo> lockedIds = new ArrayList<>();
            if(usedSpace > totalSpace){
                sceneVos = sceneVos.stream().filter(entity -> entity.getPayStatus() ==1).collect(Collectors.toList());
                Long space = getSceneLockedIds(lockedIds, sceneVos, usedSpace - totalSpace,cameraDetail.getUnit());
                log.info("lockOrUnLockBySpace---cameraId:{},totalSpace:{},useSpace{},space:{},payStatus:{}", cameraId,totalSpace,usedSpace,space,-2);
                lockOrUnLockScenes(lockedIds,-2,cameraType);
                return;
            }

            if(usedSpace < totalSpace){  //使用容量小于总容量，解封
                sceneVos = sceneVos.stream().filter(entity -> entity.getPayStatus() !=1).collect(Collectors.toList());
                CollectionUtil.reverse(sceneVos);
                Long space = getSceneUnLockedIds(lockedIds, sceneVos, totalSpace - usedSpace,cameraDetail.getUnit());
                log.info("lockOrUnLockBySpace---cameraId:{},totalSpace:{},useSpace{},space:{},payStatus:{}", cameraId,totalSpace,usedSpace,space,1);
                lockOrUnLockScenes(lockedIds,1,cameraType);
            }
            log.info("异步任务执行，当前线程：" + Thread.currentThread().getName()+"执行完毕");
        });

    }

    private void lockOrUnLockScenes(List<SimpleSceneVo> sceneVos, Integer payStatus,CameraType cameraType){
        List<String> v3NumList = sceneVos.stream().filter(e ->"v3".equals(e.getVersion())).map(SimpleSceneVo::getNum).collect(Collectors.toList());
        List<String> v4NumList = sceneVos.stream().filter(e ->"v4".equals(e.getVersion())).map(SimpleSceneVo::getNum).collect(Collectors.toList());
        lockOrUnLockScenes(v3NumList,v4NumList,payStatus,cameraType.getIsLaser(),null);
    }

    private Long getSceneUnLockedIds(List<SimpleSceneVo> lockedIds ,List<SimpleSceneVo> list,Long beyondSpace,String unit){
        Long space = 0L;
        if (list != null && list.size() > 0){
            for (SimpleSceneVo scenePro : list){
                Long sceneSpace  = scenePro.getSpace()== null ? 0 : scenePro.getSpace();
                if("SP".equals(unit)){
                    sceneSpace = 1L;
                }
                if (space + sceneSpace > beyondSpace){
                    break;
                }
                space += sceneSpace;
                lockedIds.add(scenePro);
            }
        }
        return space;
    }

    private Long getSceneLockedIds(List<SimpleSceneVo> lockedIds ,List<SimpleSceneVo> list,Long beyondSpace,String unit){
        Long space = 0L;
        if (list != null && list.size() > 0){
            for (SimpleSceneVo scenePro : list){
                if(scenePro.getCompanyId()!=null && scenePro.getCompanyId() == 26L && scenePro.getLocation() != null && scenePro.getLocation() ==7){
                    continue;
                }
                Long sceneSpace  = scenePro.getSpace()== null ? 0 : scenePro.getSpace();
                if("SP".equals(unit)){
                    sceneSpace = 1L;
                }
                space += sceneSpace;
                lockedIds.add(scenePro);
                if (space >= beyondSpace){
                    break;
                }
            }
        }
        return space;
    }


    // payStatus 为 -2 封存，为 1 解封
    @Override
    public void lockOrUnLockScenes( List<String> v3NumList,List<String> v4NumList,Integer payStatus,Integer isLaser,List<String> panoNumList) {

        if(!v3NumList.isEmpty()){
            LambdaUpdateWrapper<ScenePro> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(ScenePro::getPayStatus,payStatus)
                    .eq(ScenePro::getIsUpgrade,0)
                    .in(ScenePro::getNum,v3NumList);
            this.update(updateWrapper);
        }
        if(!v4NumList.isEmpty()){
            LambdaUpdateWrapper<ScenePlus> updatePlusWrapper = new LambdaUpdateWrapper<>();
            updatePlusWrapper.set(ScenePlus::getPayStatus,payStatus)
                    .in(ScenePlus::getNum,v4NumList);
            scenePlusService.update(updatePlusWrapper);
        }

        this.updateOssStatus(v3NumList,v4NumList,payStatus);

        List<String> numList = new ArrayList<>();
        numList.addAll(v3NumList);
        numList.addAll(v4NumList);
        if(isLaser == 1){
            //激光系统相机
            //1:场景被删 0:计算中 1计算失败 2计算成功 3封存 4重算中'
            if(!numList.isEmpty()){
                laserService.updateStatus(numList,payStatus);
            }
        }
        if(panoNumList != null && !panoNumList.isEmpty()){
            laserService.updatePanoStatus(numList,payStatus);
        }
    }

    /**
     *  修改oss status.json中 payStatus
     */
    private void updateOssStatus(List<String> v3NumList ,List<String> v4NumList , Integer payStatus) {
        if(!v3NumList.isEmpty()){
            v3NumList.forEach(e ->this.updateOssStatus(String.format(OssPath.v3_statusPath,e),payStatus,e));
        }
        if(!v4NumList.isEmpty()){
            v4NumList.forEach(e ->this.updateOssStatus(String.format(OssPath.v4_statusPath,e),payStatus,e));
        }
    }

    /**
     * 从oss中获取文件，并重写,上传替换
     */
    public void updateOssStatus(String path,Integer payStatus,String num) {
        String localStatusPath = String.format(OssPath.localStatusPath,num);
        try {
            if(!fYunFileService.fileExist(path)){
                return;
            }
            String data = fYunFileService.getFileContent(path);
            if(StringUtils.isBlank(data)){
                return;
            }
            JSONObject jsonObject = JSONObject.parseObject(data);
            jsonObject.put("payStatus",payStatus);
            String json = JSONUtil.toJsonStr(jsonObject);
            FileUtils.writeFile(localStatusPath ,json);
            log.info("updateOssStatus--localPath:{},ossPath:{},payStatus:{}",localStatusPath,path,payStatus);
            fYunFileService.uploadFile(localStatusPath,path);
        }catch (Exception e){
            log.info("updateOssStatus--localPath:{},ossPath:{},payStatus:{}",localStatusPath,path,payStatus,e);
        }finally {
            if(new File(localStatusPath).getParentFile().exists()){
                FileUtil.del( new File(localStatusPath).getParentFile());
            }
        }
    }



    @Override
    public List<ScenePro> getListByCameraId(Long cameraId) {
        LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ScenePro::getCameraId,cameraId)
                .eq(ScenePro::getIsUpgrade,0);
        return this.list(wrapper);
    }

    @Override
    public void bindOrUnCamera(List<Long> cameraIds, Long userId) {
        if(cameraIds.size() >0){
            LambdaUpdateWrapper<ScenePro> wrapper = new LambdaUpdateWrapper<>();
            wrapper.in(ScenePro::getCameraId,cameraIds)
                    .eq(ScenePro::getIsUpgrade,0)
                    .set(ScenePro::getUserId,userId);
            this.update(wrapper);
        }
    }

    @Override
    public List<ScenePro> getListByCameraIds(List<Long> cameraIds) {
        if(cameraIds.size() >0){
            LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(ScenePro::getCameraId,cameraIds)
                    .eq(ScenePro::getIsUpgrade,0);
            return this.list(wrapper);
        }
      return new ArrayList<>();
    }

    @Override
    public List<ScenePro> getListByNums(List<String> numList) {
        if(numList.size() >0){
            LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(ScenePro::getNum,numList)
                    .eq(ScenePro::getIsUpgrade,0);
            return this.list(wrapper);
        }
        return new ArrayList<>();
    }
    @Override
    public Long getCountByUserId(Long userId, List<?> resourceList) {
        if(resourceList.size() >0){
            LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ScenePro::getUserId,userId);
            wrapper.eq(ScenePro::getIsUpgrade,0);
            wrapper.in(ScenePro::getSceneSource,resourceList);
            return this.count(wrapper);
        }
        return 0L;
    }

    @Override
    public Long getCountByUserId(Long id, Integer cameraType) {
        return this.getBaseMapper().getCountByUserId(id,cameraType);
    }

    @Override
    public void deleteByIds(List<Long> sceneIds,Long userId) {
        if(sceneIds.size() >0){
            LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(ScenePro::getId,sceneIds)
                    .eq(ScenePro::getIsUpgrade,0);
            List<ScenePro> proList = this.list(wrapper);

            LambdaQueryWrapper<ScenePlus> plusWr = new LambdaQueryWrapper<>();
            plusWr.in(ScenePlus::getId,sceneIds);
            List<ScenePlus> plusList = scenePlusService.list(plusWr);

            this.deleteByList(proList,plusList,userId,null);
        }

    }


    @Override
    public Object getScenes(String username, RequestScene param) {
        User user = userService.getByUserName(username);
        log.info("搜索条件是："+ param.getSearchKey());
        //type为12表示一键换装的请求，不查询相机数据
        if(StringUtils.isNotEmpty(param.getSearchKey()) && !"11".equals(param.getType())){
            List<Long> userIds = userService.getLikeUserName(param.getSearchKey());
            if(userIds.size() > 0){
                List<String> cooperationList = sceneCooperationService.getNumByUserIds(userIds);
                param.setNumList(cooperationList);
            }
        }
        param.setUserId(user.getId());
        Page<SceneVo> sceneList = sceneService.getSceneList(param);
        for (SceneVo record : sceneList.getRecords()) {
            record.setUserName(username);
            List<SceneCooperation> sceneCooperationEntitys = sceneCooperationService.getByNum(record.getNum(),"mesh");
            if(sceneCooperationEntitys != null && !sceneCooperationEntitys.isEmpty()){
                List<String> userNameList = new ArrayList<>();
                List<Long> userIds = new ArrayList<>();
                for (SceneCooperation sceneCooperationEntity : sceneCooperationEntitys) {
                    User user1 = userService.getById(sceneCooperationEntity.getUserId());
                    if(user1 != null){
                        userIds.add(sceneCooperationEntity.getUserId());
                        userNameList.add(user1.getUserName());
                    }
                }
                record.setCooperationUserNameList(userNameList);
                record.setCooperationUserIdList(userIds);
            }
        }
        return PageInfo.PageInfo(sceneList);
    }

    @Autowired
    UcenterConfig ucenterConfig;
    @Override
    public JSONObject newList(SceneParam param, String username) {
        param.setSourceList(getSceneSource(param.getSceneSource()));
        param.setIsLaser(SceneSourceUtil.isLaser(param.getSourceList()) ?1:0);
        if(StringUtils.isNotBlank(username)){
            User user = userService.getByUserName(username);
            param.setUserId(user.getId());
        }
//        if(!SceneSourceUtil.isLaser(param.getSourceList())){
//            param.setIsObj(0);
//        }
        Page<SceneVo> sceneVoPage = getBaseMapper().pageListAndFolder(new Page<>(param.getPageNum(),param.getPageSize()),param);
        for (SceneVo record : sceneVoPage.getRecords()) {
            if(param.getIsObj()== 0 && SceneSourceUtil.isLaser(record.getSceneSource())){
                if(ucenterConfig.getActive().contains("prod")){
                    record.setWebSite(ucenterConfig.getBasePath() +"/index.html?m="+record.getNum());
                }else {
                    record.setWebSite(ucenterConfig.getBasePath() +"/uat/index.html?m="+record.getNum());
                }
                record.setSceneName(record.getLaserTitle());
            }
        }

        List<SceneVo> folderList = sceneVoPage.getRecords().parallelStream().filter(entity -> entity.getIsFolder() == 1).collect(Collectors.toList());
        Long totalSceneNum = sceneVoPage.getTotal();
        if(folderList.size() >0){
            List<Long> folderIds = folderList.parallelStream().map(SceneVo::getId).collect(Collectors.toList());
            List<Folder> allFolderIds = folderService.getAllFolderIds(folderIds);
            HashMap<Long,Long> map = folderSceneService.getGroupByFolderIds(allFolderIds);
            for (SceneVo vo : sceneVoPage.getRecords()) {
                if(vo.getIsFolder() == 1 && vo.getType()!= null && vo.getType()!= 3){
                    Long sceneNum = map.get(vo.getId()) == null ? 0L : map.get(vo.getId());
                    vo.setSceneNum(sceneNum);
                    vo.setCreateTimeStr(vo.getCreateTime());
                }else if(vo.getIsFolder() == 1 && vo.getType()!= null && vo.getType() == 3){
                    if(param.getUserId()!= null){
                        Integer count = sceneService.getCountByUserId(param.getUserId());
                        vo.setSceneNum(Long.valueOf(count));
                    }
                }
            }
        }
        //设置协作者信息
        if(sceneVoPage.getRecords().size() >0){
            List<String> numList = sceneVoPage.getRecords().parallelStream().map(SceneVo::getNum).collect(Collectors.toList());
            HashMap<String,List<User>> cooMap = sceneCooperationService.getByNumList(numList, param.getIsObj() ==1 ?"mesh":"laser");
            //HashMap<String,List<User>> cooMap = sceneCooperationService.getByNumList(numList,"mesh");
            for (SceneVo vo : sceneVoPage.getRecords()) {
                if (StringUtils.isNotBlank(vo.getNum())) {
                    List<User> userVos = cooMap.get(vo.getNum());
                    if (userVos != null) {
                        List<Long> ids = userVos.stream().map(User::getId).collect(Collectors.toList());
                        List<String> userNameList = userVos.stream().map(User::getUserName).collect(Collectors.toList());
                        vo.setCooperationUserIdList(ids);
                        vo.setCooperationUserNameList(userNameList);
                        if(!ids.isEmpty()){
                            vo.setCooperationUserId(ids.get(0).toString());
                        }
                        if(!userNameList.isEmpty()){
                            vo.setCooperationUserName(userNameList.get(0));
                        }
                    }
                }
            }
        }

        List<SceneVo> sceneList = sceneVoPage.getRecords().parallelStream().filter(entity -> entity.getIsFolder() == 0)
                .peek(vo->{
                    if (ObjectUtils.isEmpty(vo.getStatus())) {
                        return;
                    }
                    if (vo.getStatus().equals(500)) {      //500状态为数据库中手动修改值，当场景本身异常，算法，算不了
                        vo.setStatus(-1);
                    }
                    if (vo.getSceneSource() != null && vo.getSceneSource() != 57 && vo.getStatus().equals(-1)) {       //计算失败，钉钉通知之后，判定是否重算，还是修改为 500
                        vo.setStatus(0);
                    }
                }).collect(Collectors.toList());

        if(sceneList.size() >0){
            folderList.addAll(sceneList);
        }
        sceneVoPage.setRecords(folderList);
        if(param.getHasFolder() == 1){
            if(param.getFolderId() == null ){
                List<String> sourceList = param.getSourceList();
                if(param.getUserId()!= null){
                    totalSceneNum = scenePlusService.getCountByAndIsObj(param.getUserId(),sourceList,param.getIsObj(), param.getIsLaser());
                    if(sourceList.isEmpty() || sourceList.contains("1")){
                        totalSceneNum += sceneService.getCountByUserId(param.getUserId());
                    }
                }
            }else {
                totalSceneNum = folderSceneService.getCountByFolderAndSon(param.getFolderId());
            }
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("pageInfo",PageInfo.PageInfo(sceneVoPage));
        jsonObject.put("sceneNum",totalSceneNum);
        return jsonObject;
    }


    public List<String> getSceneSource(String sceneSource){
        List<String> sceneSourceList = new ArrayList<>();
        if(StringUtils.isNotBlank(sceneSource)){
            switch (sceneSource){
                case "1" : sceneSourceList = Arrays.asList("1","2","12","13","14"); break;  //四维看看
                case "3" : sceneSourceList = Collections.singletonList("3"); break;//四维看见
                case "4" : sceneSourceList = Collections.singletonList("4"); break;//深时场景
                default:
                    if(sceneSource.contains(",")){
                        sceneSource = sceneSource + ",12,13,14";
                        sceneSourceList = Arrays.asList(sceneSource.split(","));
                        break;
                    }
                    sceneSourceList = Collections.singletonList(sceneSource);break;
            }
            return sceneSourceList;
        }
        return sceneSourceList;
    }
    @Override
    public void copyScene(String sceneNum,String userName) throws Exception {
        if(StringUtils.isEmpty(sceneNum)){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3001, LoginConstant.FAILURE_MSG_3001);
        }
        ScenePro scenePro = this.getByNum(sceneNum);
        ScenePlus scenePlus = scenePlusService.getByNum(sceneNum);
        if((scenePro == null || scenePro.getCameraId() == null ) && (scenePlus== null || scenePlus.getCameraId() == null)){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005);
        }
        Long cameraId = scenePro == null ? scenePlus.getCameraId() : scenePro.getCameraId();
        Long userId = scenePro == null ? scenePlus.getUserId() :scenePro.getUserId();
        Integer status = scenePro == null ? scenePlus.getSceneStatus() :scenePro.getStatus();
        // 判断是否有绑定会员权益
        Long count = userIncrementService.getValidCountByCameraId(cameraId);
        if(count <= 0){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3030, LoginConstant.FAILURE_MSG_3030);
        }
        if(userId == null){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5013, SceneConstant.FAILURE_MSG_5013);
        }
        if(status !=-2){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5033, SceneConstant.FAILURE_MSG_5033);
        }
        //只能复制自己的场景
        User user = userService.getByUserName(userName);
        if(user == null || !user.getId().equals(userId) ){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5013, SceneConstant.FAILURE_MSG_5013);
        }
        CameraDetail detailEntity = cameraDetailService.getByCameraId(cameraId);
        if(detailEntity == null){
            throw new BusinessException(CameraConstant.FAILURE_CODE_6029, CameraConstant.FAILURE_MSG_6029);
        }
        UserIncrement userIncrement = userIncrementService.getByCameraId(cameraId);
        if(userIncrement == null || userIncrement.getIsExpired() == 1){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3030, LoginConstant.FAILURE_MSG_3030);
        }
        IncrementType incrementType = incrementTypeService.getById(userIncrement.getIncrementTypeId());
        if(incrementType == null){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3030, LoginConstant.FAILURE_MSG_3030);
        }
        Long space = null;
        if( scenePro != null ){
            space = scenePro.getSpace();
        }
        if( scenePlus != null ){
            ScenePlusExt ext = scenePlusExtService.getByPlusId(scenePlus.getId());
            space = ext.getSpace();
        }
        CameraType cameraType = cameraTypeService.getByCameraType(detailEntity.getType());


        Boolean canSpace = cameraDetailService.checkSpace(detailEntity,incrementType,space,cameraType);

        if(!canSpace){
            throw new BusinessException(CameraConstant.FAILURE_CODE_6008, CameraConstant.FAILURE_MSG_6008);
        }
        copyScene(sceneNum,detailEntity,scenePro,scenePlus,cameraType);

    }

    @Override
    public synchronized void copySceneNoCheck(String sceneNum) throws Exception {
        ScenePro scenePro = this.getByNum(sceneNum);
        ScenePlus scenePlus = scenePlusService.getByNum(sceneNum);
        Long cameraId = scenePro == null ? scenePlus.getCameraId() : scenePro.getCameraId();
        CameraDetail detailEntity = cameraDetailService.getByCameraId(cameraId);
        if(detailEntity == null){
            throw new BusinessException(CameraConstant.FAILURE_CODE_6029, CameraConstant.FAILURE_MSG_6029);
        }
        IncrementType incrementType  = null;
        UserIncrement userIncrement = userIncrementService.getByCameraId(cameraId);
        if(userIncrement != null && userIncrement.getIsExpired() != 1){
             incrementType = incrementTypeService.getById(userIncrement.getIncrementTypeId());
        }
        Long space = null;
        if( scenePro != null ){
            space = scenePro.getSpace();
        }
        if( scenePlus != null ){
            ScenePlusExt ext = scenePlusExtService.getByPlusId(scenePlus.getId());
            space = ext.getSpace();
        }
        CameraType cameraType = cameraTypeService.getByCameraType(detailEntity.getType());

        Boolean canSpace = cameraDetailService.checkSpace(detailEntity,incrementType,space,cameraType);

        if(!canSpace){
            throw new BusinessException(CameraConstant.FAILURE_CODE_6008, CameraConstant.FAILURE_MSG_6008);
        }

        copyScene(sceneNum,detailEntity,scenePro,scenePlus,cameraType);
    }

    @Autowired
    RabbitMqProducer rabbitMqProducer;

    @Value("${queue.scene.copy:ucenter-copy-scene}")
    private String copySceneQueue;

    private void copyScene(String oldNum,CameraDetail detailEntity,ScenePro scenePro,ScenePlus scenePlus,CameraType cameraType) throws Exception {
        String newNum = scene3dNumService.generateSceneNum(detailEntity.getType());
        Long userId = scenePro == null ? scenePlus.getUserId() :scenePro.getUserId();
        sceneCopyLogService.saveByNum(oldNum,newNum,userId);
        HashMap<String,String > map = new HashMap<>();
        map.put("oldNum",oldNum);
        map.put("newNum",newNum);
        rabbitMqProducer.sendByWorkQueue(copySceneQueue,map);
    }

    @Override
    public ScenePro getByNum(String sceneNum) {
        LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ScenePro::getNum,sceneNum);
        wrapper.eq(ScenePro::getIsUpgrade,0);
        List<ScenePro> list = this.list(wrapper);
        if(list!= null && list.size() >0){
            return list.get(0);
        }
        return null;
    }


    @Override
    public Long copyV3Scene(ScenePro scenePro,String newNum,CameraDetail cameraDetail,CameraType cameraType) throws Exception {

        String oldNum = scenePro.getNum();
        Long sceneProId = scenePro.getId();

        scenePro.setNum(newNum);
        scenePro.setId(null);
        scenePro.setSceneName(scenePro.getSceneName() +"(copy)");
        scenePro.setViewCount(0);
        scenePro.setThumb(scenePro.getThumb().replaceAll(oldNum,scenePro.getNum()));
        scenePro.setWebSite(scenePro.getWebSite().replaceAll(oldNum,scenePro.getNum()));
        scenePro.setStatus(0);
        this.save(scenePro);


        ExecutorService executor = ThreadUtil.newSingleExecutor();
        try {


        CompletableFuture.runAsync(() -> {

            String oldDataSource = scenePro.getDataSource();
            String newDataSource = sceneCommonService.getNewDataSource(oldDataSource);

            log.info("sceneCopy--oldNum:{},oldDataSource:{},newNum:{},newDataSource:{}",
                    oldNum,oldDataSource,newNum,newDataSource);

            scenePro.setDataSource(newDataSource);
            this.updateById(scenePro);

            SceneProEdit oldEditScene = sceneProEditService.getByProId(sceneProId);
            oldEditScene.setId(null);
            oldEditScene.setProId(scenePro.getId());
            oldEditScene.setScreencapVoiceSrc(oldEditScene.getScreencapVoiceSrc() == null ? null : oldEditScene.getScreencapVoiceSrc().replace(oldNum, scenePro.getNum()));
            oldEditScene.setScreencapVoiceSound(oldEditScene.getScreencapVoiceSound() == null ? null : oldEditScene.getScreencapVoiceSound().replace(oldNum, scenePro.getNum()));
            oldEditScene.setScreencapVoiceSoundsync(oldEditScene.getScreencapVoiceSoundsync() == null ? null : oldEditScene.getScreencapVoiceSoundsync().replace(oldNum, scenePro.getNum()));
            oldEditScene.setPlayData(oldEditScene.getPlayData() == null ? null : oldEditScene.getPlayData().replace(oldNum, scenePro.getNum()));
            oldEditScene.setScreencapThumb(oldEditScene.getScreencapThumb() == null ? null : oldEditScene.getScreencapThumb().replace(oldNum, scenePro.getNum()));
            oldEditScene.setFloorPlanPng(oldEditScene.getFloorPlanPng() == null ? null : oldEditScene.getFloorPlanPng().replace(oldNum, scenePro.getNum()));
            sceneProEditService.save(oldEditScene);

            if(SceneSourceUtil.isLaser(scenePro.getSceneSource())) {  //深时复制
                laserService.copy(oldNum,newNum,newDataSource,true);
            }

            try {
                //重新生成编辑页基础设置二维码
                sceneCommonService.createNewQrCode(SceneVersionType.V3.code(),oldEditScene.getShareLogo(),newNum,scenePro.getWebSite());
                //copyDataSource
               // cn.hutool.core.io.FileUtil.copyContent(new File(oldDataSource),new File(newDataSource),true);

                String sourceData = String.format(SceneResourcePath.dataPath, oldNum);
                String targetData = String.format(SceneResourcePath.dataPath, scenePro.getNum());
                this.copyOssAndNas(oldNum,scenePro.getNum(),sourceData,targetData);
                //修改 oss status.json ,nas scene.json
                sceneCommonService.updateOssJson(targetData,oldNum,newNum,"status.json");
                sceneCommonService.updateOssJson(targetData,oldNum,newNum,"hot.json");
                sceneCommonService.updateNasSceneJson(targetData,oldNum,newNum,scenePro.getSceneName(),"v3","scene.json");
                sceneCommonService.updateNasSceneJson(targetData,oldNum,newNum,scenePro.getSceneName(),"v3","hot.json");

                String sourceImages = String.format(SceneResourcePath.imagesPath, oldNum);
                String targetImages = String.format(SceneResourcePath.imagesPath, scenePro.getNum());
                this.copyOssAndNas(oldNum,scenePro.getNum(),sourceImages,targetImages);

                String sourceVideo = String.format(SceneResourcePath.videoPath, oldNum);
                String targetVideo = String.format(SceneResourcePath.videoPath, scenePro.getNum());
                this.copyOssAndNas(oldNum,scenePro.getNum(),sourceVideo,targetVideo);

                String sourceVoice = String.format(SceneResourcePath.voicePath, oldNum);
                String targetVoice = String.format(SceneResourcePath.voicePath, scenePro.getNum());
                this.copyOssAndNas(oldNum,scenePro.getNum(),sourceVoice,targetVoice);

                if(SceneSourceUtil.isLaser(scenePro.getSceneSource())){  //深时复制
                    laserService.copy(oldNum,newNum,newDataSource,false);
                }
                scenePro.setStatus(-2);
                this.updateById(scenePro);

                sceneCopyLogService.saveByNum(oldNum,newNum,scenePro.getUserId());
                Boolean checkSpace = cameraDetailService.checkSpace(cameraDetail.getCameraId(),cameraType);
                if(!checkSpace){
                    this.lockOrUnLockScenes(Arrays.asList(scenePro.getNum()),new ArrayList<>(),-2,cameraType.getIsLaser(),null);
                }
                cameraDetailService.addUsedSpace(cameraDetail,scenePro.getSpace());

            }catch ( Exception e){
                log.error("复制场景失败-sceneNum:{},error:{}",oldNum,e);
                scenePro.setStatus(-1);
                this.updateById(scenePro);
                throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400006, ResultCodeMsg.FAILURE_MSG_400006);
            }
        }, executor).whenComplete((reslut, e) -> {
            log.info("copy-success-");
        });
        }catch ( Exception e){
           log.error("copyError",e);
        }
        return scenePro.getId();
    }
    private void copyOssAndNas(String oldNum ,String newNum ,String sourcePath,String targetPath){
        log.info("sceneCopy-ossSource-oldNum:{},newNum:{},sourcePath:{},targetPath:{}",oldNum,newNum,sourcePath,targetPath);
        fYunFileServiceInterface.copyFileInBucket(sourcePath,targetPath);
        File fileData = new File(SceneResourcePath.nasBasePath + sourcePath);
        if(fileData.exists()){
            if(targetPath.contains("images")){
                sceneCommonService.delLink(fileData.getPath());
            }
            cn.hutool.core.io.FileUtil.copyContent(fileData,new File(SceneResourcePath.nasBasePath + targetPath),true);
        }
    }





    @Override
    public void delete(String sceneNum,Long userId,String platform) {
        if(StringUtils.isEmpty(sceneNum)){
            throw  new BusinessException(LoginConstant.FAILURE_CODE_3001,LoginConstant.FAILURE_MSG_3001);
        }
        String[] nums = sceneNum.split(",");
        List<String> numList = Arrays.asList(nums);
        List<ScenePro> proList = this.getListByNums(numList);
        List<ScenePlus> plusList = scenePlusService.getListByNums(numList);
        this.deleteByList(proList,plusList,userId,platform);
    }

    @Override
    public void deleteByList(List<ScenePro> proList,List<ScenePlus> plusList,Long userId,String platform) {
        HashMap<Long ,Long >cameraMap = new HashMap<>();
        List<String> laserNumList = new ArrayList<>();
        List<String> qjkkNumList = new ArrayList<>();

        if(proList.size() >0){
            for (ScenePro scenePro : proList) {
                cameraMap.merge(scenePro.getCameraId(), scenePro.getSpace(), Long::sum);
                sceneDelLogService.saveLog(scenePro.getNum(),userId);
            }
            List<Long> proIds = proList.parallelStream().map(ScenePro::getId).collect(Collectors.toList());
            this.removeByIds(proIds);
            List<String> lNumList = proList.stream().filter(e -> SceneSourceUtil.isLaser(e.getSceneSource())).map(ScenePro::getNum).collect(Collectors.toList());
            if(!lNumList.isEmpty()){
                laserNumList.addAll(lNumList);
            }
            folderSceneService.delBySceneId(proIds);
        }
        if(plusList.size() >0){
            List<Long> plusIds = plusList.parallelStream().map(ScenePlus::getId).collect(Collectors.toList());
            HashMap<Long, ScenePlusExt> plusMap = scenePlusExtService.getByPlusIds(plusIds);

            for (ScenePlus scenePlus : plusList) {
                if(scenePlus.getCameraId()!= null && plusMap.get(scenePlus.getId())!=null){
                    Long space = plusMap.get(scenePlus.getId()).getSpace() == null ? 0 :plusMap.get(scenePlus.getId()).getSpace();
                    cameraMap.merge(scenePlus.getCameraId(), space, Long::sum);
                }
                sceneDelLogService.saveLog(scenePlus.getNum(),userId);
            }
            scenePlusService.removeByIds(plusIds);
            scenePlusExtService.removeByPlusIds(plusIds);
            folderSceneService.delBySceneId(plusIds);

            List<String> lNumList = plusList.stream().filter(e -> SceneSourceUtil.isLaser(e.getSceneSource())).map(ScenePlus::getNum).collect(Collectors.toList());
            if(!lNumList.isEmpty()){
                laserNumList.addAll(lNumList);
            }
            List<String> lNumList2 = plusList.stream().filter(e -> SceneSourceUtil.isQjkk(e.getSceneSource())).map(ScenePlus::getNum).collect(Collectors.toList());
            if(!lNumList2.isEmpty()){
                qjkkNumList.addAll(lNumList2);
            }

        }
        if(!laserNumList.isEmpty()){
            HashMap<String,Object> map = new HashMap<>();
            map.put("numList",laserNumList);
            rabbitMqProducer.sendByWorkQueue(MqQueueUtil.laserDeleteScene,map);
        }
        if(!qjkkNumList.isEmpty()){
            HashMap<String,Object> map = new HashMap<>();
            map.put("numList",qjkkNumList);
            rabbitMqProducer.sendByWorkQueue(MqQueueUtil.qjkkDeleteScene,map);
        }

        //恢复相机使用容量
        if(!cameraMap.isEmpty()){
            cameraDetailService.addUsedSpace(cameraMap);
        }
    }

    @Override
    public ScenePro getByUnicode(String unicode) {
        LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(ScenePro::getDataSource,unicode);
        wrapper.eq(ScenePro::getIsUpgrade,0);
        wrapper.orderByDesc(ScenePro::getCreateTime);
        List<ScenePro> list = this.list(wrapper);
        if(list !=null && list.size() >0){
            return list.get(0);
        }
        return null;
    }

    @Override
    public SceneInfoVo getInfo(String num) {
        if(StringUtils.isEmpty(num)){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3001, LoginConstant.FAILURE_MSG_3001);
        }
        ScenePro scenePro = this.getByNum(num);
        ScenePlus scenePlus = scenePlusService.getByNum(num);
        if(scenePro == null && scenePlus == null){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005);
        }
        if(scenePro!=null && scenePro.getStatus() != 1 && scenePro.getStatus() != -2){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5033, SceneConstant.FAILURE_MSG_5033);
        }
        if(scenePlus!=null && scenePlus.getSceneStatus() != 1 && scenePlus.getSceneStatus() != -2){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5033, SceneConstant.FAILURE_MSG_5033);
        }
        if(scenePro!=null && scenePro.getPayStatus() != 1){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5034, SceneConstant.FAILURE_MSG_5034);
        }
        if(scenePlus!=null && scenePlus.getPayStatus() != 1){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5034, SceneConstant.FAILURE_MSG_5034);
        }
        SceneInfoVo infoVo = new SceneInfoVo();
        String dataSource = null;
        if(scenePro!=null){
            dataSource = scenePro.getDataSource();
            SceneProEdit sceneProEdit = sceneProEditService.getByProId(scenePro.getId());
            if(sceneProEdit !=null){
                BeanUtils.copyProperties(sceneProEdit, infoVo);
            }
            BeanUtils.copyProperties(scenePro,infoVo);
            if(StringUtils.isNotEmpty(scenePro.getGps())){
                infoVo.setGps(JSONObject.parseObject(scenePro.getGps()).toJSONString());
            }
            infoVo.setSceneKey("");
            infoVo.setCreateDate(DateUserUtil.getDate(scenePro.getCreateTime()).getTime());
        }else {
            SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
            ScenePlusExt scenePlusExt = scenePlusExtService.getByPlusId(scenePlus.getId());
            if(sceneEditInfo != null){
                BeanUtils.copyProperties(sceneEditInfo,infoVo);
            }
            if(scenePlusExt !=null){
                BeanUtils.copyProperties(scenePlusExt,infoVo);
            }
            BeanUtils.copyProperties(scenePlus,infoVo);
            infoVo.setSceneName(scenePlus.getTitle());
            infoVo.setStatus(scenePlus.getSceneStatus());
            dataSource = scenePlusExt.getDataSource();
        }

        if(dataSource != null){
            if(!fYunFileService.fileExist(dataSource.replace("/mnt/data","home") +"/data.fdage")){
                infoVo.setResourceDel(1);
            }
        }

        if(StringUtils.isNotEmpty(infoVo.getEntry())){
            infoVo.setEntry(JSONObject.parseObject(infoVo.getEntry()).toJSONString());
        }
        if(StringUtils.isEmpty(infoVo.getSceneKey())){
            infoVo.setIsPublic(0);
        }else {
            infoVo.setIsPublic(1);
        }

        //查询是否有随心装场景
        if(num.contains("vr-")){
            infoVo.setVrNum(null);
            infoVo.setVideosUser(null);
            infoVo.setBgMusicName(null);
            infoVo.setBgMusic(null);
        }
        infoVo.setSceneVer(innerService.getSceneNumVersion(num));
        infoVo.setVersion(infoVo.getSceneVer());
        this.updateViewCount(num);
        return infoVo;
    }

    @Override
    public void updateViewCount(String num) {
        String redisKey = RedisKey.SCENE_VISIT_CNT;
        if(!redisUtil.hHasKey(redisKey,num)){
            Integer count = 0;
            ScenePro pro = this.getByNum(num);
            if(pro !=null){
                count = pro.getViewCount() == null ? 0 : pro.getViewCount();
            }else {
                ScenePlus plus = scenePlusService.getByNum(num);
                if(plus !=null){
                    ScenePlusExt scenePlusExt = scenePlusExtService.getByPlusId(plus.getId());
                    if(scenePlusExt != null){
                        count = scenePlusExt.getViewCount() == null ? 0 :scenePlusExt.getViewCount();
                    }
                }
            }
            redisUtil.hset(redisKey,num,String.valueOf(count));
        }
        redisUtil.hincr(redisKey,num,1);
    }

    @Override
    public void updateDbViewCount(String num, String count) {
        LambdaUpdateWrapper<ScenePro> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ScenePro::getNum,num);
        wrapper.set(ScenePro::getViewCount,count);
        this.update(wrapper);

        ScenePlus plus = scenePlusService.getByNum(num);
        if(plus !=null){
            LambdaUpdateWrapper<ScenePlusExt> exWr = new LambdaUpdateWrapper<>();
            exWr.eq(ScenePlusExt::getPlusId,plus.getId())
                    .set(ScenePlusExt::getViewCount,count);
            scenePlusExtService.update(exWr);
        }
    }

    @Override
    public ScenePro findByFileId(String fileId) {
        LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(ScenePro::getDataSource,fileId);
        List<ScenePro> list = this.list(wrapper);
        if(list !=null && list.size() >0){
            return list.get(0);
        }
        return null;
    }



    @Override
    public List<SimpleSceneVo> getSimpleSceneVo(CameraDetail cameraDetail) {
        List<SimpleSceneVo> voList = new ArrayList<>();
        List<ScenePro> proList = this.getListByCameraId(cameraDetail.getCameraId());
        for (ScenePro scenePro : proList) {
            if(scenePro.getStatus() !=-2){
                continue;
            }
            SimpleSceneVo sceneVo = new SimpleSceneVo();
            sceneVo.setId(scenePro.getId());
            sceneVo.setNum(scenePro.getNum());
            sceneVo.setPayStatus(scenePro.getPayStatus());
            sceneVo.setCreateTime(DateUserUtil.getDate(scenePro.getCreateTime()).getTime());
            sceneVo.setSpace(scenePro.getSpace());
            sceneVo.setVersion("v3");
            sceneVo.setCompanyId(cameraDetail.getCompanyId());
            voList.add(sceneVo);
        }
        List<ScenePlus> plusList = scenePlusService.getListByCameraId(cameraDetail.getCameraId());
        List<Long> plusIds = plusList.stream().map(ScenePlus::getId).collect(Collectors.toList());
        HashMap<Long, ScenePlusExt> plusMap = scenePlusExtService.getByPlusIds(plusIds);
        for (ScenePlus scenePlus : plusList) {
            ScenePlusExt ext = plusMap.get(scenePlus.getId());
            if(ext == null || scenePlus.getSceneStatus() !=-2 ){
                continue;
            }
            SimpleSceneVo sceneVo = new SimpleSceneVo();
            sceneVo.setId(scenePlus.getId());
            sceneVo.setNum(scenePlus.getNum());
            sceneVo.setPayStatus(scenePlus.getPayStatus());
            String time = ext.getAlgorithmTime();
            if(ext.getAlgorithmTime() == null){
                time = ext.getCreateTime();
            }
            sceneVo.setCreateTime(DateUserUtil.getDate(time).getTime());
            sceneVo.setSpace(ext.getSpace());
            sceneVo.setVersion("v4");
            sceneVo.setLocation(ext.getLocation());
            sceneVo.setCompanyId(cameraDetail.getCompanyId());
            voList.add(sceneVo);
        }
        return voList;
    }

    @Override
    public void generateObjFile(String num) {
//        LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(ScenePro::getNum,num).eq(ScenePro::getRecStatus,"A");
//        ScenePro sceneProEntity = this.getOne(wrapper);

        ScenePro sceneProEntity = this.getByNum(num);

        if(ObjectUtils.isEmpty(sceneProEntity)){
            generatePlusObjFile(num);
            return;
        }

        if(sceneProEntity.getSceneSource() != 4 && sceneProEntity.getSceneSource() != 5){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3003, "只能操作激光场景");
        }

        // 拷贝文件
        String path = sceneProEntity.getDataSource();
        String ossPath = path.replace("/mnt/data","home")+"/data.fdage";
        if(!fYunFileService.fileExist(ossPath)){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3037, LoginConstant.FAILURE_MSG_3037);
        }

        // 获取最新的场景名称
        JSONObject sceneInfo = fdkkLaserService.getSceneByNum(sceneProEntity.getNum());
        LambdaUpdateWrapper<ScenePro> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .set(ScenePro::getStatus, 0)
                .set(ScenePro::getIsObj, 1)
                .set(ScenePro::getIsUpgrade, 2)   //   升级中
                .set(ScenePro::getSceneName, sceneInfo.getString("title"))
                .eq(ScenePro::getNum, sceneProEntity.getNum());
        this.update(updateWrapper);

        //同步到scenePlus、scenePlus
        ScenePlus scenePlus = scenePlusService.getByNum(num);
        if(Objects.nonNull(scenePlus)){
            sceneUpgradeMapper.deleteScenePlus(num);
            sceneUpgradeMapper.deleteScenePlusExt(scenePlus.getId());
        }
        sceneUpgradeMapper.transferScenePlus(num);
        scenePlus = scenePlusService.getByNum(num);
        String sceneKind = sceneProEntity.getSceneScheme() == 3 ? SceneKind.FACE.code():SceneKind.TILES.code();
        sceneUpgradeMapper.transferScenePlusExt(num, scenePlus.getId(), sceneKind);

        log.info("开始发送激光场景生成obj mq消息");

        // 发送MQ
        BuildSceneCallMessage mqMsg = new BuildSceneCallMessage();
        mqMsg.setSceneNum(sceneProEntity.getNum());
        mqMsg.setAlgorithm(sceneProEntity.getAlgorithm());
        mqMsg.setBuildType(sceneProEntity.getBuildType());
        mqMsg.setPath(sceneProEntity.getDataSource());
        mqProducer.sendByWorkQueue(queueObjModelingPre,mqMsg);
    }

    public void generatePlusObjFile(String num) {
        ScenePlus scenePlus = scenePlusService.getByNum(num);

        if(ObjectUtils.isEmpty(scenePlus)){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005);
        }

        if(scenePlus.getSceneSource() != 4 && scenePlus.getSceneSource() !=5){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3003, "只能操作激光场景");
        }

        ScenePlusExt scenePlusExt = scenePlusExtService.getByPlusId(scenePlus.getId());

        String ossPath = scenePlusExt.getDataSource().replace("/mnt/data","home")+"/data.fdage";
        if(!fYunFileService.fileExist(ossPath)){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3037, LoginConstant.FAILURE_MSG_3037);

        }


        // 获取最新的场景名称
        JSONObject sceneInfo = fdkkLaserService.getSceneByNum(num);
        LambdaUpdateWrapper<ScenePlus> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .set(ScenePlus::getSceneStatus, 0)
                .set(ScenePlus::getTitle, sceneInfo.getString("title"))
                .eq(ScenePlus::getNum, num);
        scenePlusService.update(updateWrapper);

        LambdaUpdateWrapper<ScenePlusExt> plusExtUpdateWrapper = new LambdaUpdateWrapper<>();
        plusExtUpdateWrapper
                .set(ScenePlusExt::getIsObj, 1)
                .eq(ScenePlusExt::getPlusId, scenePlus.getId());
        scenePlusExtService.update(plusExtUpdateWrapper);

        log.info("开始发送激光场景生成obj mq消息");

        // 发送MQ
        BuildSceneCallMessage mqMsg = new BuildSceneCallMessage();
        mqMsg.setSceneNum(num);
        mqMsg.setAlgorithm(scenePlusExt.getAlgorithm());
        mqMsg.setBuildType(scenePlusExt.getBuildType());
        mqMsg.setPath(scenePlusExt.getDataSource());
        mqProducer.sendByWorkQueue(queueObjModelingPre,mqMsg);
    }

    @Override
    public ResponseScene getSceneDetail(String sceneNum) {
        if(StringUtils.isBlank(sceneNum)){
            return null;
        }
        ResponseScene vo = new ResponseScene();
        Scene sceneEntity = sceneService.getByNum(sceneNum);
        if(sceneEntity != null){
            return getResponseScene(vo, sceneEntity);
        }

        ScenePro sceneProEntity = this.getByNum(sceneNum);
        if(sceneProEntity != null){
            SceneProEdit  sceneProEditEntity = sceneProEditService.getByProId(sceneProEntity.getId());
            return getResponseProScene(vo, sceneProEntity, sceneProEditEntity);
        }
        ScenePlus scenePlus = scenePlusService.getByNum(sceneNum);
        if(scenePlus != null){
            ScenePlusExt ext = scenePlusExtService.getByPlusId(scenePlus.getId());
            SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
            return getResponseProScene(vo, scenePlus, ext,sceneEditInfo);

        }
        return vo;
    }

    private ResponseScene getResponseScene(ResponseScene vo, Scene sceneEntity) {
        if (sceneEntity != null){
            BeanUtils.copyProperties(sceneEntity, vo);

            vo.setThumbImg(sceneEntity.getThumbStatus());
            vo.setCreateTime(new DateTime(sceneEntity.getCreateTime()).toString("yyyy-MM-dd HH:mm"));
            vo.setSceneIndex(sceneEntity.getStyle());
            vo.setHasBGM(sceneEntity.getBgMusic());
            vo.setCameraType(sceneEntity.getSceneScheme());
            vo.setIsPublic(StringUtils.isEmpty(sceneEntity.getSceneKey()) ? 0 : 1);
        }
        return vo;
    }
    private ResponseScene getResponseProScene(ResponseScene vo, ScenePro sceneProEntity, SceneProEdit sceneProEditEntity) {
        if (sceneProEntity != null){
            BeanUtils.copyProperties(sceneProEditEntity, vo);
            BeanUtils.copyProperties(sceneProEntity, vo);
            vo.setCreateTime(DateUserUtil.getMDate(vo.getCreateTime()));
            vo.setCameraType(sceneProEntity.getSceneScheme());

            vo.setThumbImg(sceneProEditEntity.getThumbStatus());
            vo.setHasBGM(sceneProEditEntity.getBgMusic());
            vo.setIsPublic(StringUtils.isEmpty(sceneProEditEntity.getSceneKey()) ? 0 : 1);
        }
        return vo;
    }
    private ResponseScene getResponseProScene(ResponseScene vo, ScenePlus plus, ScenePlusExt ext,SceneEditInfo editInfo) {
        if (plus != null){
            BeanUtils.copyProperties(plus, vo);
            BeanUtils.copyProperties(ext, vo);
            BeanUtils.copyProperties(editInfo, vo);

            vo.setNum(plus.getNum());
            vo.setSceneName(plus.getTitle());
            vo.setCreateTime(DateUserUtil.getMDate(vo.getCreateTime()));
            vo.setCameraType(ext.getSceneScheme());

            vo.setThumbImg(1);
            vo.setHasBGM(editInfo.getMusic());
            vo.setIsPublic(StringUtils.isEmpty(editInfo.getScenePassword()) ? 0 : 1);
        }
        return vo;
    }

    @Override
    public Long getCountByCameraId(Long cameraId,Boolean status) {
        LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ScenePro::getCameraId,cameraId);
        wrapper.eq(ScenePro::getIsUpgrade,0);
        if(status){
            wrapper.eq(ScenePro::getStatus,-2);
        }
        return this.count(wrapper);
    }

    @Override
    public Long getCountByCameraId(Long cameraId) {
        LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ScenePro::getCameraId,cameraId);
        wrapper.eq(ScenePro::getIsUpgrade,0);
        wrapper.in(ScenePro::getStatus,0,-2);
        return this.count(wrapper);
    }

    @Override
    public Long getSpaceSumByCameraId(Long cameraId) {
        return this.getBaseMapper().getSpaceSumByCameraId(cameraId);
    }

    /**
     * 队列名：remove-portrait
     * 载荷：{"num":"xxx"}
     * 表:t_scene_plus增加字段remove_portrait
     */
    @Override
    public void removePortrait(String num) {
        ScenePlus scenePlus = scenePlusService.getByNum(num);
        if(scenePlus == null){
            throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400002, ResultCodeMsg.FAILURE_MSG_400002);
        }
        HashMap<String,String> map = new HashMap<>();
        map.put("num",num);
        rabbitMqProducer.sendByWorkQueue("remove-portrait",map);


    }
}
