package com.fdkankan.scene.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.*;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.response.ResultData;
import com.fdkankan.common.util.*;
import com.fdkankan.fyun.oss.UploadToOssUtil;
import com.fdkankan.platform.api.dto.Camera;
import com.fdkankan.platform.api.dto.CameraDetail;
import com.fdkankan.platform.api.dto.User;
import com.fdkankan.platform.api.feign.PlatformGoodsClient;
import com.fdkankan.platform.api.feign.PlatformUserClient;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.redis.constant.RedisLockKey;
import com.fdkankan.redis.util.RedisLockUtil;
import com.fdkankan.scene.entity.*;
import com.fdkankan.scene.mapper.ISceneProMapper;
import com.fdkankan.scene.service.*;
import com.fdkankan.scene.vo.*;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
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.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * pro场景表 服务实现类
 * </p>
 *
 * @author dengsixing
 * @since 2021-12-23
 */
@Slf4j
@Service
public class SceneProAppServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro> implements ISceneProAppService {

    @Value("${upload.type}")
    private String type;

    @Value("${oss.prefix.ali}")
    private String prefixAli;

    @Value("${hot.domain.list}")
    private String hotDomainList;

    @Value("${hot.delete}")
    private String hotDelete;

    @Autowired
    ISceneProService sceneProService;
    @Autowired
    @Qualifier("uploadToOssUtil")
    UploadToOssUtil uploadToOssUtil;
    @Autowired
    ISceneProEditService sceneProEditService;
    @Autowired
    RedisLockUtil redisLockUtil;
    @Autowired
    ISceneProEditExtService sceneProEditExtService;
    @Autowired
    private PlatformGoodsClient platformGoodsClient;
    @Autowired
    private PlatformUserClient platformUserClient;
    @Autowired
    private ISceneCooperationService sceneCooperationService;
    @Autowired
    ISceneService sceneService;
    @Autowired
    ISceneProExtService sceneProExtService;
    @Autowired
    IFolderSceneService folderSceneService;

    @Override
    public ResultData saveInitialPage(SceneEditParamVO base) throws Exception {
        if(StringUtils.isEmpty(base.getNum()) || StringUtils.isEmpty(base.getInitialPoint())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(Objects.isNull(scenePro)){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit= sceneProEditService.findByProId(scenePro.getId());

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);


        StringBuffer imagesBuf = new StringBuffer()
                .append("images").append(File.separator)
                .append("images").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());
        StringBuffer imagesBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(imagesBuf.toString());

        String path1 = imagesBuffer.toString() + "thumbBigImg.jpg";
        String path2 = imagesBuffer.toString() + "thumbSmallImg.jpg";

        //生成缩略图
        //按指定大小把图片进行缩和放（会遵循原图高宽比例）
        //此处把图片压成1024×512的缩略图
        Thumbnails.of(path1).size(1024,512).toFile(path2);//变为1024×512

        Map map = new HashMap();
        map.put("entry", JSONObject.parseObject(base.getInitialPoint()));
        map.put("thumbImg", 1);
        map.put("version", sceneProEdit.getVersion()+1);
        FileUtils.writeJsonFile(dataBuffer.toString() + "scene.json", map);

        Map<String,String> uploadMap = new HashMap<String,String>();
        uploadMap.put(imagesBuffer.toString() + "thumbBigImg.jpg", imagesBuf.toString() + "thumbBigImg.jpg");
        uploadMap.put(imagesBuffer.toString() + "thumbFishBigImg.jpg", imagesBuf.toString() + "thumbFishBigImg.jpg");
        uploadMap.put(imagesBuffer.toString() + "thumbSmallImg.jpg", imagesBuf.toString() + "thumbSmallImg.jpg");
        uploadMap.put(imagesBuffer.toString() + "smallPic.jpg", imagesBuf.toString() + "smallPic.jpg");
        uploadMap.put(dataBuffer.toString() + "scene.json", dataBuf.toString() + "scene.json");

        uploadToOssUtil.uploadMulFiles(uploadMap);

        sceneProEdit.setEntry(base.getInitialPoint());
        sceneProEdit.setThumbStatus(1);
        sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        scenePro.setThumb(prefixAli + imagesBuf.toString() + "thumbSmallImg.jpg");
        if("aws".equals(type)){
            scenePro.setThumb(ConstantUrl.PREFIX_AWS + imagesBuf.toString() + "thumbSmallImg.jpg");
        }
        sceneProService.updateById(scenePro);

        return ResultData.ok();
    }

    @Override
    public ResultData saveFloorLogo(SceneEditParamVO base) throws Exception {
        if(StrUtil.isEmpty(base.getNum()) || StrUtil.isEmpty(base.getSize()) ||
                StrUtil.isEmpty(base.getLogoType())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer imagesBuf = new StringBuffer()
                .append("images").append(File.separator)
                .append("images").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());
        StringBuffer imagesBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(imagesBuf.toString());

        Map map = new HashMap();
        map.put("floorLogo", base.getLogoType());
        map.put("floorLogoSize", base.getSize());
        map.put("version", sceneProEdit.getVersion()+1);

        FileUtils.writeJsonFile(dataBuffer.toString() + "scene.json", map);

        sceneProEdit.setFloorLogo(base.getLogoType());
        sceneProEdit.setFloorLogoSize(Integer.parseInt(base.getSize()));
        sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        uploadToOssUtil.upload(imagesBuffer.toString() + "floorLogoImg.png", imagesBuf.toString() + "floorLogoImg.png");
        uploadToOssUtil.upload(dataBuffer.toString() + "scene.json", dataBuf.toString() + "scene.json");
        return ResultData.ok();
    }

    @Override
    @SuppressWarnings("unchecked")
    public ResultData saveHot(SceneEditParamVO base) throws Exception {
        if(StrUtil.isEmpty(base.getType())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if (scenePro == null ) {
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());
        log.info("hotData:" + base.getHotData());
        JSONObject jsonhot = JSONObject.parseObject(base.getHotData());

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);
        StringBuffer imagesBuf = new StringBuffer()
                .append("images").append(File.separator)
                .append("images").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer imagesBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(imagesBuf.toString());
        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());

        String sid = this.getSidFromParams(base, jsonhot);

        JSONArray jsonhots = this.getJsonhots(base, dataBuffer, jsonhot);

        //判断是否需要删除自定义热点样式
        String hotsids = this.deleteCustomStyleHots(base,jsonhots,jsonhot,sid);

        Object[] uploadFileMapAndSceneJson = this.getUploadFileMapAndSceneJson(base,jsonhots, jsonhot, sid, imagesBuf, imagesBuffer, dataBuf, dataBuffer);
        Map<String,String> map = (Map<String, String>) uploadFileMapAndSceneJson[0];
        JSONObject scenejson = (JSONObject) uploadFileMapAndSceneJson[1];

        uploadToOssUtil.uploadMulFiles(map);

        if(!StringUtils.isEmpty(base.getPlayData())){
            sceneProEdit.setPlayData(dataBuf.toString() + "playData.json");
        }
        if(!StringUtils.isEmpty(base.getScreencapThumb())){
            sceneProEdit.setScreencapThumb(dataBuf.toString() + "screencapThumb.json");
        }
        sceneProEdit.setHotsIds(hotsids);
        sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);
        sceneProEditService.updateById(sceneProEdit);

        scenejson.put("version", sceneProEdit.getVersion() + 1);
        FileUtils.writeFile(dataBuffer.toString() + "scene.json", scenejson.toString());

        return ResultData.ok();
    }

    @Override
    public ResultData saveBackgroundMusic(SceneEditParamVO base) throws Exception {
        if(StringUtils.isEmpty(base.getNum()) || StringUtils.isEmpty(base.getMusicName())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());

        Map map = new HashMap();
        map.put("bgMusic", base.getMusicName());
        map.put("version", sceneProEdit.getVersion()+1);

        FileUtils.writeJsonFile(dataBuffer.toString() + "scene.json", map);

        sceneProEdit.setBgMusic(base.getMusicName());
        sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);
        sceneProEditService.updateById(sceneProEdit);

        return ResultData.ok();
    }

    @Override
    public ResultData saveSceneInfo(SceneEditParamVO base) throws Exception{
        if(StringUtils.isEmpty(base.getNum()) || StringUtils.isEmpty(base.getSceneName()) ||
                StringUtils.isEmpty(base.getSceneType()) || StringUtils.isEmpty(base.getSceneDec())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());

        Map map = new HashMap();
        map.put("sceneName", base.getSceneName());
        map.put("sceneDec", base.getSceneDec());
        if(StrUtil.isNotEmpty(base.getSceneType())){
            if(scenePro.getSceneType() == 99){
                map.put("sceneType", scenePro.getSceneType());
            }else {
                scenePro.setSceneType(Integer.parseInt(base.getSceneType()));
                map.put("sceneType", base.getSceneType());
            }
        }

        if(StrUtil.isNotEmpty(base.getSceneKey())) {
            map.put("sceneKey", base.getSceneKey());
            map.put("needKey", 1);
            sceneProEdit.setNeedKey(1);
        }else {
            sceneProEdit.setNeedKey(0);
            map.put("sceneKey", "");
            map.put("needKey", 0);
        }
        map.put("version", sceneProEdit.getVersion()+1);

        FileUtils.writeJsonFile(dataBuffer.toString() + "scene.json", map);

        scenePro.setSceneName(base.getSceneName());
        scenePro.setSceneDec(base.getSceneDec());
        scenePro.setUpdateTime(Calendar.getInstance().getTime());
        this.updateById(scenePro);

        sceneProEdit.setSceneKey(base.getSceneKey());
        sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        return ResultData.ok();
    }

    @Override
    public ResultData saveSceneKey(SceneEditParamVO base) throws Exception{
        if(StringUtils.isEmpty(base.getNum()) || StringUtils.isEmpty(base.getSceneKey())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());


        Map map = new HashMap();
        map.put("sceneKey", base.getSceneKey());
        map.put("needKey", 1);
        map.put("version", sceneProEdit.getVersion()+1);

        FileUtils.writeJsonFile(dataBuffer.toString() + "scene.json", map);

        sceneProEdit.setSceneKey(base.getSceneKey());
        sceneProEdit.setNeedKey(1);
        sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);
        return ResultData.ok();
    }

    @Override
    public ResultData saveTourList(SceneEditParamVO base) throws Exception{
        if(StringUtils.isEmpty(base.getNum()) || StringUtils.isEmpty(base.getTourList())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer imagesBuf = new StringBuffer()
                .append("images").append(File.separator)
                .append("images").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer imagesBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(imagesBuf.toString());
        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());

        Map<String,String> map = new HashMap<String,String>();

        log.info("editForApp/saveTourList：生成tourList.json文件");
        String tourListPath = dataBuffer.toString() + ConstantFileName.TOUR_LIST;
        FileUtils.writeFile(tourListPath, base.getTourList());
        map.put(tourListPath, dataBuf.toString() + ConstantFileName.TOUR_LIST);

        JSONArray tourJsons = JSONArray.parseArray(base.getTourList());

        String path = imagesBuffer.toString() + ConstantFileName.TOURLIST_FOLDER;

        for(int i=0;i<tourJsons.size();++i)
        {
            String fileName = path + File.separator +"guide"+i+".jpg";
            map.put(fileName, imagesBuf.toString() + ConstantFileName.TOURLIST_FOLDER+File.separator+"guide"+i+".jpg");
        }

        File file = new File(dataBuffer.toString() + ConstantFileName.TOURLIST_FOLDER);
        String[] strs = file.list();
        if(strs!=null) {
            int screencapLen = 0;
            for(int i=0;i<strs.length;++i){
                if(strs[i].indexOf(ConstantFileName.SCREEN_CRP_DATAFILE)<=-1)
                    continue;

                map.put(dataBuffer.toString() + ConstantFileName.TOURLIST_FOLDER+File.separator+strs[i], dataBuf.toString() + ConstantFileName.TOURLIST_FOLDER+File.separator+strs[i]);
                ++screencapLen;
            }

            Map<String, Object> jsonMap = new HashMap();
            jsonMap.put("screenCapLen", screencapLen);
            jsonMap.put("version", sceneProEdit.getVersion() + 1);

            FileUtils.writeJsonFile(dataBuffer.toString() + "scene.json", jsonMap);

            sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);
            sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
            sceneProEditService.updateById(sceneProEdit);
        }

        uploadToOssUtil.uploadMulFiles(map);

        return ResultData.ok();
    }

    @Override
    public ResultData uploadPic(String sceneNum, String folderName, MultipartFile file) throws Exception{
        if(StringUtils.isEmpty(sceneNum)){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(sceneNum);
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        if (file.isEmpty() && file.getSize() <= 0) {
            throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
        }

        String lockKey = String.format(RedisLockKey.LOCK_UPLOAD_PRO_PIC, sceneNum);
        Boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_10_MINUTE);

        if(!lock){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5036);
        }

        File targetFile = null;

        try {
            //文件上传的位置可以自定义
            String path = ConstantFilePath.SCENE_PATH+"images"+File.separator+"images"+sceneNum;
            if(StrUtil.isNotEmpty(folderName)) {
                path = path+File.separator + folderName;
            }
            targetFile = new File(path);
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }
            String fileName = file.getOriginalFilename();
            targetFile = new File(path + File.separator + fileName);
            // 保存
            if(targetFile.exists())
            {
                FileUtils.deleteFile(path + File.separator + fileName);
            }
            file.transferTo(targetFile);
        }catch (Exception e){
            log.error("上传图片失败", e);
            throw new BusinessException(ErrorCode.FAILURE_CODE_5037);
        }finally {
            redisLockUtil.unlock(lockKey);
        }

        return ResultData.ok(targetFile.getName());
    }

    @Override
    public ResultData uploadScreencapVoice(String sceneNum, MultipartFile file) throws Exception{
        if(StringUtils.isEmpty(sceneNum)){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(sceneNum);
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        if (file.isEmpty() && file.getSize() <= 0) {
            throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
        }

        String lockKey = String.format(RedisLockKey.LOCK_UPLOAD_PRO_VOICE, sceneNum);
        Boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_30_MINUTE);

        if(!lock){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5036);
        }

        String originalFileName = null;
        try {

            //文件上传的位置可以自定义
            String path = ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+sceneNum;
            File targetFile = new File(path);
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }
            originalFileName = file.getOriginalFilename();
            targetFile = new File(path + File.separator +originalFileName);
            // 保存
            synchronized(this) {
                if(targetFile.exists())
                {
                    FileUtils.deleteFile(path + File.separator + originalFileName);
                }
                file.transferTo(targetFile);
            }
            uploadToOssUtil.upload(path + File.separator +originalFileName, "voice/voice"+sceneNum+"/"+originalFileName);

            Map map = new HashMap();
            map.put("screencapVoiceFileName", originalFileName);
            String voiceSrc = prefixAli + "voice/voice"+sceneNum+"/"+originalFileName;
            if("aws".equals(type)){
                voiceSrc = ConstantUrl.PREFIX_AWS + "voice/voice"+sceneNum+"/"+originalFileName;
            }
            map.put("screencapVoiceSrc", voiceSrc);
            map.put("screencapVoiceType", "file");
            map.put("version", sceneProEdit.getVersion()+1);
            FileUtils.writeJsonFile(ConstantFilePath.SCENE_PATH + "data/data" + sceneNum + "/scene.json", map);

            sceneProEdit.setScreencapVoiceSrc(voiceSrc);
            sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);
            sceneProEdit.setScreencapVoiceType("file");
            sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
            sceneProEditService.updateById(sceneProEdit);

        }catch (Exception e){
            log.error("上传图音频失败", e);
            throw new BusinessException(ErrorCode.FAILURE_CODE_5040);
        }finally {
            redisLockUtil.unlock(lockKey);
        }

        return ResultData.ok(originalFileName);
    }

    @Override
    public ResultData saveScreencapFile(SceneEditParamVO base) throws Exception{
        if(StringUtils.isEmpty(base.getNum()) || StringUtils.isEmpty(base.getIndex()) ||
                StringUtils.isEmpty(base.getCamerasData())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());

        if("1".equals(base.getIndex())){
            File file = new File(dataBuffer.toString() + ConstantFileName.TOURLIST_FOLDER);
            if(file.isDirectory()){
                String[] strs = file.list();
                if(strs!=null){
                    for(int i=0;i<strs.length;++i) {

                        if(strs[i].indexOf(ConstantFileName.SCREEN_CRP_DATAFILE)>-1) {
                            FileUtils.deleteFile(dataBuffer.toString() + ConstantFileName.TOURLIST_FOLDER+File.separator+strs[i]);
                        }
                    }
                }
            } else {
                file.mkdirs();
            }

            Map<String, Object> map = new HashMap<>();
            map.put("screencapLen", "0");
            map.put("version", sceneProEdit.getVersion()+1);
            FileUtils.writeJsonFile(dataBuffer.toString() + "scene.json", map);

            sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);
            sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
            sceneProEditService.updateById(sceneProEdit);
        }

        String filePath = dataBuffer.toString() + ConstantFileName.TOURLIST_FOLDER+File.separator+ConstantFileName.SCREEN_CRP_DATAFILE+base.getIndex()+"json";
        File file = new File(filePath);
        if(!file.exists())
        {
            file.createNewFile();
        }
        FileUtils.writeFile(filePath, base.getCamerasData());

        return ResultData.ok();
    }

    @Override
    public ResultData saveHotVisible(SceneEditParamVO base) throws Exception{
        if(StringUtils.isEmpty(base.getData())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        JSONArray visiblePanos = JSONArray.parseArray(base.getData());

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);
        StringBuffer imagesBuf = new StringBuffer()
                .append("images").append(File.separator)
                .append("images").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer imagesBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(imagesBuf.toString());
        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());

        File file = new File(dataBuffer.toString() + "hot.json");
        if (!file.exists()) {
            throw new BusinessException(ErrorCode.FAILURE_CODE_3018);
        }

        String str = FileUtils.readFile(dataBuffer.toString() + "hot.json");
        JSONArray hots = JSONArray.parseArray(str);
        for (int i = 0; i < hots.size(); ++i) {
            JSONObject hot = hots.getJSONObject(i);
            for (int j = 0; j < visiblePanos.size(); ++j) {
                if (hot.getString("sid").equals(((JSONObject) visiblePanos.get(j)).getString("sid"))) {
                    hot.put("visiblePanos", ((JSONObject) visiblePanos.get(j)).getJSONArray("value"));
                }
            }
        }

        sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        FileUtils.deleteFile(dataBuffer.toString() + "hot.json");
        FileUtils.writeFile(dataBuffer.toString() + "hot.json", hots.toString());

        uploadToOssUtil.upload(dataBuffer.toString() + "hot.json", dataBuf.toString() + "hot.json");

        return ResultData.ok();
    }

    @Override
    public ResultData saveLinkPano(SceneEditParamVO base) throws Exception{
        if(StringUtils.isEmpty(base.getData()) || StringUtils.isEmpty(base.getNum())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        JSONArray inputData = JSONObject.parseArray(base.getData());

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);
        StringBuffer imagesBuf = new StringBuffer()
                .append("images").append(File.separator)
                .append("images").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());

        File directory = new File(dataBuffer.toString());
        if (!directory.exists()) {
            directory.mkdirs();
        }

        JSONArray inputdata =  JSONArray.parseArray(base.getData());

        String modeldataUrl = prefixAli + imagesBuf.toString() + "vision.modeldata?t=" + System.currentTimeMillis();
        if("aws".equals(type)){
            modeldataUrl = ConstantUrl.PREFIX_AWS + imagesBuf.toString() + "vision.modeldata?t=" + System.currentTimeMillis();
        }
        FileUtils.downLoadFromUrl(modeldataUrl, "vision.modeldata", dataBuffer.toString());
        File file = new File(dataBuffer.toString() + "vision.modeldata");
        if(!file.exists()) {
            return ResultData.error(ErrorCode.FAILURE_CODE_5012);
        }
        ConvertUtils.convertVisionModelDataToTxt(dataBuffer.toString() + "vision.modeldata", dataBuffer.toString() + "vision.json");

        String str = FileUtils.readFile(dataBuffer.toString() + "vision.json");
        JSONObject json = JSONObject.parseObject(str);
        JSONArray panos = json.getJSONArray("sweepLocations");
        for (int i = 0; i < panos.size(); ++i) {
            JSONObject pano = panos.getJSONObject(i);
            for (int j = 0; j < inputData.size(); ++j) {
                JSONObject jo = inputData.getJSONObject(j);
                String currentPanoId = jo.getString("panoID");
                JSONArray visibles = jo.getJSONArray("visibles");
                JSONArray visibles3 = jo.getJSONArray("visibles3");
                if (pano.getString("uuid").equals(currentPanoId)) {
                    pano.put("visibles", visibles);
                    pano.put("visibles3", visibles3);
                }
            }
        }
        FileUtils.deleteFile(dataBuffer.toString() + "vision.json");
        FileUtils.deleteFile(dataBuffer.toString() + "vision.modeldata");
        FileUtils.writeFile(dataBuffer.toString() + "vision.json", json.toString());
        ConvertUtils.convertTxtToVisionModelData(dataBuffer.toString() + "vision.json", dataBuffer.toString() + "vision.modeldata");
        uploadToOssUtil.upload(dataBuffer.toString() + "vision.modeldata", imagesBuf.toString() + "vision.modeldata");

        String strsceneInfos = FileUtils.readFile(dataBuffer.toString() + "scene.json");
        JSONObject scenejson = new JSONObject();
        if(strsceneInfos!=null){
            scenejson = JSONObject.parseObject(strsceneInfos);
        }

        scenejson.put("version", scenejson.getIntValue("version") + 1);
        FileUtils.writeFile(dataBuffer.toString() + "scene.json", scenejson.toString());

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());
        if (sceneProEdit == null ) {
            return ResultData.error(ErrorCode.FAILURE_CODE_5005);
        }

        sceneProEdit.setVersion(scenejson.getIntValue("version") + 1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);
        return ResultData.ok();
    }

    @Override
    public ResultData getRecordAudioFromWeixin(SceneEditParamVO base) throws Exception{
        if(StringUtils.isEmpty(base.getNum()) || StringUtils.isEmpty(base.getId())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        String accessToken = WeiXinUtils.getAccessToken();

        InputStream is = null;
        String url = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token="+ accessToken + "&media_id=" + base.getId();
        URL urlGet = new URL(url);
        HttpURLConnection http = (HttpURLConnection) urlGet
                .openConnection();
        http.setRequestMethod("GET"); // 必须是get方式请求
        http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        http.setDoOutput(true);
        http.setDoInput(true);
        System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
        System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
        http.connect();
        // 获取文件转化为byte流
        is = http.getInputStream();
        File dic = new File(ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+base.getNum());
        if(!dic.exists())
        {
            dic.mkdirs();
        }
        File voice = new File(ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+base.getNum()+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr");
        if(voice.exists())
        {
            FileUtils.deleteFile(ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+base.getNum()+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr");
        }
        FileUtils.saveImageToDisk( accessToken,  base.getId(), ConstantFileName.WECHAT_VOICE_NAME, ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+base.getNum()+File.separator, is);

        try
        {
            FileUtils.changeVoiceToMp3(ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+base.getNum()+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr",
                    ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+base.getNum()+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".mp3");
        }
        catch(Exception e)
        {
            StringWriter trace=new StringWriter();
            e.printStackTrace(new PrintWriter(trace));
            log.error("voice:"+ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+base.getNum()+File.separator+ConstantFileName.VOICE_NAME+".amr");
            log.error(trace.toString());
            return ResultData.error(ErrorCode.FAILURE_CODE_5005);
        }
        String originalFileName = ConstantFileName.WECHAT_VOICE_NAME+".mp3";
        uploadToOssUtil.upload(ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+base.getNum()+File.separator +originalFileName, "voice/voice"+base.getNum()+"/"+originalFileName);

        Map map = new HashMap();
        map.put("screencapVoiceSoundsyncFileName", originalFileName);
        String voiceSrc = prefixAli+"voice/voice"+base.getNum()+"/"+originalFileName;
        if("aws".equals(type)){
            voiceSrc = ConstantUrl.PREFIX_AWS+"voice/voice"+base.getNum()+"/"+originalFileName;
        }
        map.put("screencapVoiceSoundsync", voiceSrc);
        log.info("微信上传的音频路径：{}",  voiceSrc);
        map.put("screencapVoiceType", "soundsync");
        map.put("version", sceneProEdit.getVersion()+1);
        FileUtils.writeJsonFile(ConstantFilePath.SCENE_PATH + "data/data" + base.getNum() + "/scene.json", map);

        sceneProEdit.setScreencapVoiceType("soundsync");
        sceneProEdit.setScreencapVoiceSoundsync(voiceSrc);
        sceneProEdit.setVersion(sceneProEdit.getVersion());
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);
        FileUtils.deleteFile(ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+base.getNum()+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr");
        if("aws".equals(type)){
            return ResultData.ok(ConstantUrl.PREFIX_AWS+"voice/voice"+base.getNum()+"/"+originalFileName);
        }
        return ResultData.ok(prefixAli+"voice/voice"+base.getNum()+"/"+originalFileName);
    }

    @Override
    public ResultData getRecordAudioFromWeixinV3(FileParamVO param) throws Exception {
        String sceneNum = param.getNum();
        String id = param.getId();
        String fileName = param.getFileName();
        if(StringUtils.isEmpty(sceneNum) || StringUtils.isEmpty(id)){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(sceneNum);
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        String strsceneInfos = FileUtils.readFile(ConstantFilePath.SCENE_PATH + "data/data" + sceneNum + File.separator + "scene.json");
        JSONObject scenejson = new JSONObject();
        if(strsceneInfos!=null) {
            scenejson = JSONObject.parseObject(strsceneInfos);
        }

        //文件上传的位置可以自定义
        String path = ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+sceneNum;
        log.info("path:" + path);

        this.saveImageToDisk(path, id);

        try
        {
            FileUtils.changeVoiceToMp3(path+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr",
                    path+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".mp3");
        }
        catch(Exception e)
        {
            StringWriter trace=new StringWriter();
            e.printStackTrace(new PrintWriter(trace));
            log.error("voice:"+path+File.separator+ConstantFileName.VOICE_NAME+".amr");
            log.error(trace.toString());
            return ResultData.error(ErrorCode.FAILURE_CODE_5005);
        }
        String originalFileName = ConstantFileName.WECHAT_VOICE_NAME+".mp3";

        //判断分房间模块文件夹是否存在
        String partPath = path + File.separator + "part";
        File partFile = new File(partPath);
        if(!partFile.exists()){
            partFile.mkdirs();
        }
        if(!"1".equals(param.getReplace())){
            return ResultData.ok(this.replaceForWeixinV3(sceneProEdit, scenejson,
                    path, partPath, fileName, originalFileName, sceneNum, param.getTimes()));
        }

        FileUtils.delAllFile(path + File.separator + "part");

        //保存0.mp3文件到part
        FileUtils.changeVoiceToMp3(path+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr",
                partPath+File.separator+fileName);

        FileUtils.copyFile(partPath+File.separator+fileName, path + File.separator + originalFileName, true);

        uploadToOssUtil.upload(path+File.separator +originalFileName, "voice/voice"+sceneNum+"/"+originalFileName);

        String voiceSrc = prefixAli+"voice/voice"+sceneNum+"/"+originalFileName;
        if("aws".equals(this.type)){
            voiceSrc = ConstantUrl.PREFIX_AWS+"voice/voice"+sceneNum+"/"+originalFileName;
        }

        sceneProEdit.setScreencapVoiceType("soundsync");
        sceneProEdit.setScreencapVoiceSoundsync(voiceSrc);
        sceneProEdit.setVersion(scenejson.getIntValue("version")+1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        Map map = new HashMap();
        map.put("screencapVoiceSoundsyncFileName", originalFileName);
        map.put("screencapVoiceSoundsync", voiceSrc);
        map.put("uploadVoiceSoundsync", 1);
        map.put("screencapVoiceType", type);
        map.put("version", scenejson.getIntValue("version")+1);
        FileUtils.writeJsonFile(ConstantFilePath.SCENE_PATH + "data/data" + sceneNum + File.separator + "scene.json", map);
        FileUtils.deleteFile(path+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr");

        return ResultData.ok(voiceSrc);
    }

    @Override
    public ResultData getRecordAudioFromAppV3(FileParamVO param) throws Exception {
        String sceneNum = param.getNum();
        String soundFile = param.getSoundFile();
        String fileName = param.getFileName();
        if(StringUtils.isEmpty(sceneNum) || StringUtils.isEmpty(soundFile)){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(sceneNum);
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        String strsceneInfos = FileUtils.readFile(ConstantFilePath.SCENE_PATH + "data/data" + sceneNum + File.separator + "scene.json");
        JSONObject scenejson = new JSONObject();
        if(strsceneInfos!=null) {
            scenejson = JSONObject.parseObject(strsceneInfos);
        }

        String originalFileName = ConstantFileName.APP_VOICE_NAME+".mp3";

        //文件上传的位置可以自定义
        String path = ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+sceneNum;

        //判断分房间模块文件夹是否存在
        String partPath = path + File.separator + "part";
        File partFile = new File(partPath);
        if(!partFile.exists()){
            partFile.mkdirs();
        }

        if(!"1".equals(param.getReplace())){
            return ResultData.ok(this.replaceForAppV3(sceneProEdit, scenejson,
                    path, partPath, fileName, originalFileName, sceneNum, param.getTimes(), soundFile));
        }

        FileUtils.delAllFile(path + File.separator + "part");
        if("aws".equals(this.type)){
            CreateObjUtil.ossFileCp("voice"+File.separator+"voice"+sceneNum + "/" + soundFile, partPath + File.separator + fileName);
        }else {
            CreateObjUtil.ossUtilCp("voice"+File.separator+"voice"+sceneNum + "/" + soundFile, partPath + File.separator);
            new File(partPath + File.separator + soundFile).renameTo(new File(partPath + File.separator + fileName));
        }

        FileUtils.copyFile(partPath+File.separator+fileName, path + File.separator + originalFileName, true);

        uploadToOssUtil.upload(path+File.separator +originalFileName, "voice/voice"+sceneNum+"/"+originalFileName);

        String voiceSrc = prefixAli+"voice/voice"+sceneNum+"/"+originalFileName;
        if("aws".equals(this.type)){
            voiceSrc = ConstantUrl.PREFIX_AWS+"voice/voice"+sceneNum+"/"+originalFileName;
        }

        sceneProEdit.setScreencapVoiceType("soundsync");
        sceneProEdit.setScreencapVoiceSoundsync(voiceSrc);
        sceneProEdit.setVersion(scenejson.getIntValue("version")+1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        Map map = new HashMap();
        map.put("screencapVoiceSoundsyncFileName", originalFileName);
        map.put("screencapVoiceSoundsync", voiceSrc);
        map.put("uploadVoiceSoundsync", 1);
        map.put("screencapVoiceType", type);
        map.put("version", scenejson.getIntValue("version")+1);
        FileUtils.writeJsonFile(ConstantFilePath.SCENE_PATH + "data/data" + sceneNum + File.separator + "scene.json", map);
        FileUtils.deleteFile(path+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr");

        return ResultData.ok(voiceSrc);
    }

    @Override
    public ResultData deleteRecordAudioPart(FileParamVO param) throws Exception {

        String sceneNum = param.getNum();
        String index = param.getIndex();
        String times = param.getTimes();
        if(StringUtils.isEmpty(sceneNum)){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(sceneNum);
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        //文件上传的位置可以自定义
        String path = ConstantFilePath.SCENE_PATH+"voice"+File.separator+"voice"+sceneNum;
        File targetFile = new File(path);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }

        //默认为app文件名
        String originalFileName = ConstantFileName.APP_VOICE_NAME + ".mp3";
        if("wechat".equals(type)){
            originalFileName = ConstantFileName.WECHAT_VOICE_NAME + ".mp3";
        }
        log.info("上传的音频文件名：" + originalFileName);

        String strsceneInfos = FileUtils.readFile(ConstantFilePath.SCENE_PATH + "data/data" + sceneNum + File.separator + "scene.json");
        JSONObject scenejson = new JSONObject();
        if(strsceneInfos!=null) {
            scenejson = JSONObject.parseObject(strsceneInfos);
        }
        //判断分房间模块文件夹是否存在
        String partPath = path + File.separator + "part";
        File partFile = new File(partPath);
        if(!partFile.exists()){
            partFile.mkdirs();
        }

        //删除指定部分音频文件
        FileUtils.deleteFile(partPath + File.separator + index + ".mp3");

        //获取总音频多少段，每段时长
        String[] time = times.split(",");

        //删除所有音频
        if(StringUtils.isEmpty(times) || time.length == 0){
            this.deleteAudio(sceneProEdit, scenejson, sceneNum);
            return ResultData.ok();
        }

        //修改删除的部分视频后面部分音频名字，如删除1.MP3，则将2.mp3修改成1.mp3，往后以此类推
        if(Integer.parseInt(index) < time.length) {
            for(int i = 0, len = time.length - Integer.parseInt(index); i < len; i++){
                if(new File(partPath + File.separator + (Integer.parseInt(index) + 1 + i) + ".mp3").exists()){
                    FileUtils.copyFile(partPath + File.separator + (Integer.parseInt(index) + 1 + i) + ".mp3",
                            partPath + File.separator + (Integer.parseInt(index) + i) + ".mp3", true);
                }
            }
        }

        //遍历判断音频是否存在，不存在生成空白音效
        for(int i = 0, len = time.length; i < len; i++){
            if(!new File(partPath + File.separator + i + ".mp3").exists()){
                //某部分文件不存在，直接生成一段静音后拼接文件
                CreateObjUtil.createMuteViode(Double.valueOf(time[i]), partPath + File.separator + i + ".mp3");
            }
        }

        //拼接所有音频文件
        if(time.length > 2){
            //若是多部分，两个两个合并，最后合成最终文件
            for(int i = 1, len = time.length; i < len; i++){
                if(i == 1){
                    CreateObjUtil.mergeVideo(partPath + File.separator + (i - 1) + ".mp3", partPath + File.separator + i + ".mp3",
                            partPath + File.separator + i + "muteSound.mp3");
                }else if(i == len - 1){
                    CreateObjUtil.mergeVideo(partPath + File.separator + (i - 1) + "muteSound.mp3", partPath + File.separator + i + ".mp3",
                            path + File.separator + originalFileName);
                }else {
                    CreateObjUtil.mergeVideo(partPath + File.separator + (i - 1) + "muteSound.mp3", partPath + File.separator + i + ".mp3",
                            partPath + File.separator + i + "muteSound.mp3");
                }
            }
        }else if(time.length == 2){
            //若只有两部分，直接合并成最终文件
            CreateObjUtil.mergeVideo(partPath + File.separator + "0.mp3", partPath + File.separator + "1.mp3", path + File.separator + originalFileName);
        }else {
            FileUtils.copyFile(partPath + File.separator + "0.mp3", path + File.separator + originalFileName, true);
        }

        uploadToOssUtil.upload(path+File.separator +originalFileName, "voice/voice"+sceneNum+"/"+originalFileName);

        String voiceSrc = prefixAli+"voice/voice"+sceneNum+"/"+originalFileName;
        if("aws".equals(this.type)){
            voiceSrc = ConstantUrl.PREFIX_AWS+"voice/voice"+sceneNum+"/"+originalFileName;
        }

        Map map = new HashMap();
        map.put("screencapVoiceSoundsyncFileName", originalFileName);
        map.put("screencapVoiceSoundsync", voiceSrc);
        map.put("uploadVoiceSoundsync", 0);
        map.put("screencapVoiceType", "soundsync");
        map.put("version", scenejson.getIntValue("version")+1);
        sceneProEdit.setScreencapVoiceType("soundsync");
        sceneProEdit.setScreencapVoiceSoundsync(voiceSrc);
        sceneProEdit.setVersion(scenejson.getIntValue("version")+1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        FileUtils.writeJsonFile(ConstantFilePath.SCENE_PATH + "data/data" + sceneNum + File.separator + "scene.json", map);

        return ResultData.ok(voiceSrc);
    }

    @Override
    public ResultData uploadFloorJsonAndRebuild(SceneEditParamVO sceneEdit) throws Exception {

        String lockKey = String.format(RedisLockKey.LOCK_UPLOAD_FLOORJSON_REBUILD, sceneEdit.getNum());
        Boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_2_HOUR);
        if(!lock){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5036);
        }

        try {

            long start = System.currentTimeMillis();
            log.info("画墙重建模型开始时间：{}", start);
            if(StringUtils.isEmpty(sceneEdit.getNum())){
                throw new BusinessException(ErrorCode.PARAM_REQUIRED);
            }

            ScenePro scenePro = baseMapper.findByNum(sceneEdit.getNum());
            if(scenePro == null){
                throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
            }

            SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());
            if(sceneProEdit == null){
                throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
            }

            //更新scene.json文件
            String strsceneInfos = FileUtils.readFile(ConstantFilePath.SCENE_PATH + "data" + File.separator + "data" + sceneEdit.getNum() + File.separator + "scene.json");
            JSONObject scenejson = new JSONObject();
            if(strsceneInfos!=null)
            {
                scenejson = JSONObject.parseObject(strsceneInfos);
            }else {
                new File(ConstantFilePath.SCENE_PATH + "data" + File.separator + "data" + sceneEdit.getNum() + File.separator + "scene.json").createNewFile();
            }
            if(!StringUtils.isEmpty(sceneEdit.getSceneData())){
                JSONObject sceneObject = JSONObject.parseObject(sceneEdit.getSceneData());
                Set<String> set =sceneObject.keySet();

                for(String key : set){
                    scenejson.put(key, sceneObject.get(key));
                }
            }
            //保存floor.json前端下次进入需要使用
            if(StringUtils.isEmpty(sceneEdit.getWebFloor())){
                sceneEdit.setWebFloor(sceneEdit.getFloor());
            }

            //上传过模型只更新floor.json
            FileUtils.writeFile(ConstantFilePath.SCENE_PATH+"data"+File.separator+"data"+sceneEdit.getNum() + File.separator + "floor.json",
                    new String(sceneEdit.getWebFloor().getBytes(), "UTF-8"));

            //更新scene.json文件
            if(strsceneInfos!=null)
            {
                scenejson.put("floorEditVer", sceneProEdit.getFloorPublishVer() + 1);
                scenejson.put("floorPublishVer", sceneProEdit.getFloorPublishVer() + 1);
                FileUtils.writeFile(ConstantFilePath.SCENE_PATH+"data"+File.separator+"data"+sceneEdit.getNum()+File.separator+"scene.json", scenejson.toString());
                log.info("写入scene.json文件完成, sceneCode:{}", sceneEdit.getNum());
            }

            //floorEditVer字段增加1
            sceneProEdit.setFloorEditVer(sceneProEdit.getFloorPublishVer() + 1);
            sceneProEdit.setFloorPublishVer(sceneProEdit.getFloorPublishVer() + 1);
            sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
            sceneProEditService.updateById(sceneProEdit);

            uploadToOssUtil.upload(ConstantFilePath.SCENE_PATH+"data"+File.separator+"data"+sceneEdit.getNum() + File.separator + "floor.json",
                    "data"+File.separator+"data"+sceneEdit.getNum() + File.separator + "floor.json");
        }catch (Exception e){
            log.error("画墙重建模型失败...", e);
            throw new BusinessException(ErrorCode.FAILURE_CODE_5039);
        }finally {
            redisLockUtil.unlock(lockKey);
        }

        return ResultData.ok();
    }

    @Override
    public ResultData saveScreencapData(SceneEditParamVO base) throws Exception {
        if(StringUtils.isEmpty(base.getNum())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);
        StringBuffer imagesBuf = new StringBuffer()
                .append("images").append(File.separator)
                .append("images").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());
        StringBuffer imagesBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(imagesBuf.toString());

        String strsceneInfos = FileUtils.readFile(dataBuffer.toString() + "scene.json");
        JSONObject scenejson = new JSONObject();
        if(strsceneInfos!=null) {
            scenejson = JSONObject.parseObject(strsceneInfos);
        }

        //上传七牛
        Map<String,String> map = new HashMap<String,String>();

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        scenejson.put("screencapVoiceSound", "");
        sceneProEdit.setScreencapVoiceSound("");

        if(base.getScreencapVoiceType() != null){
            scenejson.put("screencapVoiceType", base.getScreencapVoiceType());
            sceneProEdit.setScreencapVoiceType(base.getScreencapVoiceType());
        }

        if(!StringUtils.isEmpty(base.getCapData())){
            FileUtils.writeFile(dataBuffer.toString() + "capData.json", new String(base.getCapData().getBytes(), "UTF-8"));
            scenejson.put("capData", dataBuf.toString() + "capData.json");
        }

        if(!StringUtils.isEmpty(base.getFrameData())){
            FileUtils.writeFile(dataBuffer.toString() + "frameData.json", new String(base.getFrameData().getBytes(), "UTF-8"));
            scenejson.put("frameData", dataBuf.toString() + "frameData.json");
        }

        if(!StringUtils.isEmpty(base.getPlayData())){
            FileUtils.writeFile(dataBuffer.toString() + "playData.json", new String(base.getPlayData().getBytes(), "UTF-8"));
            scenejson.put("playData", dataBuf.toString() + "playData.json");
            sceneProEdit.setPlayData(dataBuf.toString() + "playData.json");
            map.put(dataBuffer.toString() + "playData.json", dataBuf.toString() + "playData.json");
        }

        if(!StringUtils.isEmpty(base.getScreencapThumb())){
            FileUtils.writeFile(dataBuffer.toString() + "screencapThumb.json", new String(base.getScreencapThumb().getBytes(), "UTF-8"));
            scenejson.put("screencapThumb", dataBuf.toString() + "screencapThumb.json");
            sceneProEdit.setScreencapThumb(dataBuf.toString() + "screencapThumb.json");
            map.put(dataBuffer.toString() + "screencapThumb.json", dataBuf.toString() + "screencapThumb.json");
        }

        if(!StringUtils.isEmpty(base.getRecordType())){
            scenejson.put("recordType", base.getRecordType());
        }

        if(map.size()>0) {
            uploadToOssUtil.uploadMulFiles(map);
        }
        sceneProEdit.setVersion(scenejson.getIntValue("version") + 1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        log.info("scene.json路径：" + dataBuffer.toString() + "scene.json");
        scenejson.put("version", scenejson.getIntValue("version") + 1);
        FileUtils.writeFile(dataBuffer.toString() + "scene.json", scenejson.toString());

        return ResultData.ok();

    }

    public ResultData saveAllVisi(SceneEditParamVO base) throws Exception {
        if(StrUtil.isEmpty(base.getNum())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(base.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());

        String strsceneInfos = FileUtils.readFile(dataBuffer.toString() + "scene.json");
        JSONObject scenejson = new JSONObject();
        if(strsceneInfos!=null) {
            scenejson = JSONObject.parseObject(strsceneInfos);
        }

        this.updateVisiData(base, sceneProEdit, scenejson);

        sceneProEdit.setVersion(scenejson.getIntValue("version") + 1);
        scenejson.put("version", scenejson.getIntValue("version") + 1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        FileUtils.writeFile(dataBuffer.toString() + "scene.json", scenejson.toString());

        return ResultData.ok();
    }

    @Override
    public ResultData uploadFloorplanPng(String sceneNum, MultipartFile file, String cadInfo) throws Exception {
        if(StringUtils.isEmpty(sceneNum)){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }
        if (file.isEmpty() && file.getSize() <= 0) {
            throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
        }

        ScenePro scenePro = baseMapper.findByNum(sceneNum);
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        String lockKey = String.format(RedisLockKey.LOCK_UPLOAD_FLOORPLAN_PNG, sceneNum);
        Boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_30_MINUTE);
        if(!lock){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5036);
        }

        String fileName = "floorplan.png";
        try {

            StringBuffer dataBuf = new StringBuffer()
                    .append("data").append(File.separator)
                    .append("data").append(scenePro.getNum())
                    .append(File.separator);
            StringBuffer imagesBuf = new StringBuffer()
                    .append("images").append(File.separator)
                    .append("images").append(scenePro.getNum())
                    .append(File.separator);

            StringBuffer imagesBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(imagesBuf.toString());
            StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());

            //文件上传的位置可以自定义
            String path = ConstantFilePath.SCENE_PATH+"images"+File.separator+"images"+sceneNum;
            File targetFile = new File(path);
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }

            targetFile = new File(path + File.separator + fileName);
            // 保存
            if(targetFile.exists())
            {
                FileUtils.deleteFile(path + File.separator + fileName);
            }
            file.transferTo(targetFile);

            SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());
            SceneProEditExt sceneProEditExt = sceneProEditExtService.getOne(
                    new QueryWrapper<SceneProEditExt>().eq("pro_edit_id", sceneProEdit.getId()));

            String floorPlanPng = "images"+File.separator+"images"+sceneNum + File.separator + fileName;
            Map<String, Object> map = new HashMap<>();
            map.put("floorPlanPng", floorPlanPng);
            map.put("uploadFloorPlanPng", 1);
            map.put("version", sceneProEdit.getVersion()+1);

            if(StrUtil.isNotEmpty(cadInfo)){
                map.put("cadInfo", cadInfo);
                sceneProEditExt.setCadInfo(cadInfo);
            }
            sceneProEditExt.setFloorPlanPng(floorPlanPng + "?t=" + System.currentTimeMillis());
            sceneProEditExt.setUpdateTime(Calendar.getInstance().getTime());
            sceneProEditExtService.updateById(sceneProEditExt);

            sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);
            sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
            sceneProEditService.updateById(sceneProEdit);

            FileUtils.writeJsonFile(dataBuffer.toString() + "scene.json", map);
            uploadToOssUtil.upload(ConstantFilePath.SCENE_PATH+floorPlanPng, floorPlanPng);
        }catch (Exception e){
            log.error("上传图片多媒体数据失败...", e);
            throw new BusinessException(ErrorCode.FAILURE_CODE_5041);
        }finally {
            redisLockUtil.unlock(lockKey);
        }

        return ResultData.ok("images"+File.separator+"images"+sceneNum + File.separator + fileName);
    }

    @Override
    public ResultData uploadBgMusic(String sceneNum, String fileName, MultipartFile file) throws Exception {
        if(StringUtils.isEmpty(sceneNum) || StringUtils.isEmpty(fileName)){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(sceneNum);
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());
        SceneProEditExt sceneProEditExt = sceneProEditExtService.getOne(
                new QueryWrapper<SceneProEditExt>().eq("pro_edit_id", sceneProEdit.getId()));

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer imagesBuf = new StringBuffer()
                .append("images").append(File.separator)
                .append("images").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());
        StringBuffer imagesBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(imagesBuf.toString());

        File buMusicFile = new File(imagesBuffer.toString() + fileName);
        if(!buMusicFile.getParentFile().exists()){
            buMusicFile.getParentFile().mkdirs();
        }

        //上传文件
        file.transferTo(buMusicFile);

        uploadToOssUtil.upload(imagesBuffer.toString() + fileName, imagesBuf + fileName);

        String strsceneInfos = FileUtils.readFile(dataBuffer.toString() + "scene.json");
        JSONObject scenejson = new JSONObject();
        if(strsceneInfos!=null) {
            scenejson = JSONObject.parseObject(strsceneInfos);
        }

        sceneProEditExt.setBgMusicName(fileName);
        sceneProEditExt.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditExtService.updateById(sceneProEditExt);

        sceneProEdit.setVersion(scenejson.getIntValue("version") + 1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        scenejson.put("bgMusicName", fileName);
        scenejson.put("uploadBgMusic", 0);
        scenejson.put("version", scenejson.getIntValue("version") + 1);

        FileUtils.writeFile(dataBuffer.toString() + "scene.json", scenejson.toString());

        return ResultData.ok();
    }

    @Override
    public ResultData deleteUploadBgMusic(String sceneNum) throws Exception {
        if(StringUtils.isEmpty(sceneNum)){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = baseMapper.findByNum(sceneNum);
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());
        SceneProEditExt sceneProEditExt = sceneProEditExtService.getOne(
                new QueryWrapper<SceneProEditExt>().eq("pro_edit_id", sceneProEdit.getId()));

        StringBuffer dataBuf = new StringBuffer()
                .append("data").append(File.separator)
                .append("data").append(scenePro.getNum())
                .append(File.separator);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString());

        String strsceneInfos = FileUtils.readFile(dataBuffer.toString() + "scene.json");
        JSONObject scenejson = new JSONObject();
        if(strsceneInfos!=null) {
            scenejson = JSONObject.parseObject(strsceneInfos);
        }

        sceneProEditExt.setBgMusicName("");
        sceneProEditExt.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditExtService.updateById(sceneProEditExt);
        sceneProEdit.setVersion(scenejson.getIntValue("version") + 1);
        sceneProEditService.updateById(sceneProEdit);

        scenejson.put("bgMusicName", "");
        scenejson.put("version", scenejson.getIntValue("version") + 1);
        FileUtils.writeFile(dataBuffer.toString() + "scene.json", scenejson.toString());

        return ResultData.ok();
    }

    private void updateVisiData(SceneEditParamVO base, SceneProEdit sceneProEdit, JSONObject scenejson){
        SceneProEditExt sceneProEditExt = sceneProEditExtService.getOne(
                new QueryWrapper<SceneProEditExt>().eq("pro_edit_id", sceneProEdit.getId()));
        if(!StringUtils.isEmpty(base.getMapVisi())){
            scenejson.put("mapVisi", Integer.parseInt(base.getMapVisi()));
            sceneProEditExt.setMapVisi(Integer.parseInt(base.getMapVisi()));
        }

        if(!StringUtils.isEmpty(base.getTourVisi())){
            scenejson.put("tourVisi", Integer.parseInt(base.getTourVisi()));
            sceneProEditExt.setTourVisi(Integer.parseInt(base.getTourVisi()));
        }
        if(!StringUtils.isEmpty(base.getVrVisi())){
            scenejson.put("vrVisi", Integer.parseInt(base.getVrVisi()));
            sceneProEditExt.setVrVisi(Integer.parseInt(base.getVrVisi()));
        }

        if(!StringUtils.isEmpty(base.getRulerVisi())){
            scenejson.put("rulerVisi", Integer.parseInt(base.getRulerVisi()));
            sceneProEditExt.setRulerVisi(Integer.parseInt(base.getRulerVisi()));
        }
        if(!StringUtils.isEmpty(base.getCadImgVisi())){
            scenejson.put("cadImgVisi", Integer.parseInt(base.getCadImgVisi()));
            sceneProEditExt.setCadImgVisi(Integer.parseInt(base.getCadImgVisi()));
        }

        if(!StringUtils.isEmpty(base.getPanoVisi())){
            scenejson.put("panoVisi", Integer.parseInt(base.getPanoVisi()));
            sceneProEditExt.setPanoVisi(Integer.parseInt(base.getPanoVisi()));
        }

        if(!StringUtils.isEmpty(base.getM2dVisi())){
            scenejson.put("m2dVisi", Integer.parseInt(base.getM2dVisi()));
            sceneProEditExt.setM2dVisi(Integer.parseInt(base.getM2dVisi()));
        }
        if(!StringUtils.isEmpty(base.getM3dVisi())){
            scenejson.put("m3dVisi", Integer.parseInt(base.getM3dVisi()));
            sceneProEditExt.setM3dVisi(Integer.parseInt(base.getM3dVisi()));
        }
        if(!StringUtils.isEmpty(base.getMeasureVisi())){
            scenejson.put("measureVisi", Integer.parseInt(base.getMeasureVisi()));
            sceneProEditExt.setMeasureVisi(Integer.parseInt(base.getMeasureVisi()));
        }

        sceneProEditExt.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditExtService.updateById(sceneProEditExt);
    }

    private void deleteAudio(SceneProEdit sceneProEdit, JSONObject scenejson, String sceneNum) throws Exception {
        sceneProEdit.setScreencapVoiceType("");
        sceneProEdit.setScreencapVoiceSoundsync("");
        sceneProEdit.setVersion(scenejson.getIntValue("version")+1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        Map map = new HashMap();
        map.put("screencapVoiceSoundsyncFileName", "");
        map.put("screencapVoiceSoundsync", "");
        map.put("uploadVoiceSoundsync", 0);
        map.put("screencapVoiceType", "");
        map.put("version", scenejson.getIntValue("version")+1);
        FileUtils.writeJsonFile(ConstantFilePath.SCENE_PATH + "data/data" + sceneNum + File.separator + "scene.json", map);
    }

    private String replaceForAppV3(SceneProEdit sceneProEdit, JSONObject scenejson,
                                   String path, String partPath, String fileName,
                                   String originalFileName, String sceneNum, String times, String soundFile) throws Exception {
        if(new File(partPath+File.separator+fileName).exists()) {
            FileUtils.deleteFile(partPath + File.separator + fileName);
        }

        if("aws".equals(this.type)){
            CreateObjUtil.ossFileCp("voice"+File.separator+"voice"+sceneNum + "/" + soundFile, partPath + File.separator + fileName);
        }else {
            CreateObjUtil.ossUtilCp("voice"+File.separator+"voice"+sceneNum + "/" + soundFile, partPath + File.separator);
            new File(partPath + File.separator + soundFile).renameTo(new File(partPath + File.separator + fileName));
        }

        //获取总音频多少段，每段时长
        String[] time = times.split(",");
        //遍历判断音频是否存在，不存在生成空白音效
        for(int i = 0, len = time.length; i < len; i++){
            if(!new File(partPath + File.separator + i + ".mp3").exists()){
                //某部分文件不存在，直接生成一段静音后拼接文件
                CreateObjUtil.createMuteViode(Double.valueOf(time[i]), partPath + File.separator + i + ".mp3");
            }
        }

        //拼接所有音频文件
        if(time.length > 2){

            //若是多部分，两个两个合并，最后合成最终文件
            for(int i = 1, len = time.length; i < len; i++){
                if(i == 1){
                    CreateObjUtil.mergeVideo(partPath + File.separator + (i - 1) + ".mp3", partPath + File.separator + i + ".mp3",
                            partPath + File.separator + i + "muteSound.mp3");
                }else if(i == len - 1){
                    CreateObjUtil.mergeVideo(partPath + File.separator + (i - 1) + "muteSound.mp3", partPath + File.separator + i + ".mp3",
                            path + File.separator + originalFileName);
                }else {
                    CreateObjUtil.mergeVideo(partPath + File.separator + (i - 1) + "muteSound.mp3", partPath + File.separator + i + ".mp3",
                            partPath + File.separator + i + "muteSound.mp3");
                }
            }
        }else {
            //若只有两部分，直接合并成最终文件
            CreateObjUtil.mergeVideo(partPath + File.separator + "0.mp3", partPath + File.separator + "1.mp3", path + File.separator + originalFileName);
        }

        uploadToOssUtil.upload(path+File.separator +originalFileName, "voice/voice"+sceneNum+"/"+originalFileName);

        String voiceSrc = prefixAli+"voice/voice"+sceneNum+"/"+originalFileName;
        if("aws".equals(this.type)){
            voiceSrc = ConstantUrl.PREFIX_AWS+"voice/voice"+sceneNum+"/"+originalFileName;
        }

        sceneProEdit.setScreencapVoiceType("soundsync");
        sceneProEdit.setScreencapVoiceSoundsync(voiceSrc);
        sceneProEdit.setVersion(scenejson.getIntValue("version")+1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        Map map = new HashMap();
        map.put("screencapVoiceSoundsyncFileName", originalFileName);
        map.put("screencapVoiceSoundsync", voiceSrc);
        map.put("uploadVoiceSoundsync", 1);
        map.put("screencapVoiceType", type);
        map.put("version", scenejson.getIntValue("version")+1);
        FileUtils.writeJsonFile(ConstantFilePath.SCENE_PATH + "data/data" + sceneNum + File.separator + "scene.json", map);
        FileUtils.deleteFile(path+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr");

        return voiceSrc;
    }

    private String replaceForWeixinV3(SceneProEdit sceneProEdit, JSONObject scenejson,
                           String path, String partPath, String fileName,
                           String originalFileName, String sceneNum, String times) throws Exception {
        this.dealVioce(path, partPath, fileName, originalFileName, sceneNum, times);

        String voiceSrc = prefixAli+"voice/voice"+sceneNum+"/"+originalFileName;
        if("aws".equals(this.type)){
            voiceSrc = ConstantUrl.PREFIX_AWS+"voice/voice"+sceneNum+"/"+originalFileName;
        }

        Map map = new HashMap();
        map.put("screencapVoiceSoundsyncFileName", originalFileName);
        map.put("screencapVoiceSoundsync", voiceSrc);
        map.put("uploadVoiceSoundsync", 1);
        map.put("screencapVoiceType", type);
        map.put("version", scenejson.getIntValue("version")+1);

        sceneProEdit.setScreencapVoiceType("soundsync");
        sceneProEdit.setScreencapVoiceSoundsync(voiceSrc);
        sceneProEdit.setVersion(scenejson.getIntValue("version")+1);
        sceneProEdit.setUpdateTime(Calendar.getInstance().getTime());
        sceneProEditService.updateById(sceneProEdit);

        FileUtils.writeJsonFile(ConstantFilePath.SCENE_PATH + "data/data" + sceneNum + File.separator + "scene.json", map);
        FileUtils.deleteFile(path+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr");
        return voiceSrc;
    }

    private void dealVioce(String path, String partPath, String fileName, String originalFileName, String sceneNum, String times) throws Exception {
        if(new File(partPath+File.separator+fileName).exists()) {
            FileUtils.deleteFile(partPath + File.separator + fileName);
        }

        FileUtils.changeVoiceToMp3(path+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr",
                partPath+File.separator+fileName);

        //获取总音频多少段，每段时长
        String[] time = times.split(",");
        //遍历判断音频是否存在，不存在生成空白音效
        for(int i = 0, len = time.length; i < len; i++){
            if(!new File(partPath + File.separator + i + ".mp3").exists()){
                //某部分文件不存在，直接生成一段静音后拼接文件
                CreateObjUtil.createMuteViode(Double.valueOf(time[i]), partPath + File.separator + i + ".mp3");
            }
        }

        //拼接所有音频文件
        if(time.length > 2){
            //若是多部分，两个两个合并，最后合成最终文件
            for(int i = 1, len = time.length; i < len; i++){
                if(i == 1){
//                        FileUtils.deleteFile(partPath + File.separator + i + "muteSound.mp3");

                    CreateObjUtil.mergeVideo(partPath + File.separator + (i - 1) + ".mp3", partPath + File.separator + i + ".mp3",
                            partPath + File.separator + i + "muteSound.mp3");
                }else if(i == len - 1){
                    CreateObjUtil.mergeVideo(partPath + File.separator + (i - 1) + "muteSound.mp3", partPath + File.separator + i + ".mp3",
                            path + File.separator + originalFileName);
                }else {
                    CreateObjUtil.mergeVideo(partPath + File.separator + (i - 1) + "muteSound.mp3", partPath + File.separator + i + ".mp3",
                            partPath + File.separator + i + "muteSound.mp3");
                }
            }
        }else {
            //若只有两部分，直接合并成最终文件
            CreateObjUtil.mergeVideo(partPath + File.separator + "0.mp3", partPath + File.separator + "1.mp3", path + File.separator + originalFileName);
        }

        uploadToOssUtil.upload(path+File.separator +originalFileName, "voice/voice"+sceneNum+"/"+originalFileName);
    }

    private void saveImageToDisk(String path, String id) throws Exception {
        String accessToken = WeiXinUtils.getAccessToken();

        InputStream is = null;
        String url = "https://file.api.weixin.qq.com/cgi-bin/media/get?access_token="+ accessToken + "&media_id=" + id;
        log.info("url:" + url);
        URL urlGet = new URL(url);
        HttpURLConnection http = (HttpURLConnection) urlGet
                .openConnection();
        http.setRequestMethod("GET"); // 必须是get方式请求
        http.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded");
        http.setDoOutput(true);
        http.setDoInput(true);
        System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
        System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
        http.connect();
        // 获取文件转化为byte流
        is = http.getInputStream();
        File dic = new File(path);
        if(!dic.exists())
        {
            dic.mkdirs();
        }
        File voice = new File(path+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr");
        if(voice.exists())
        {
            FileUtils.deleteFile(path+File.separator+ConstantFileName.WECHAT_VOICE_NAME+".amr");
        }
        FileUtils.saveImageToDisk(accessToken, id, ConstantFileName.WECHAT_VOICE_NAME, path+File.separator, is);
    }


    private Object[] getUploadFileMapAndSceneJson(SceneEditParamVO base, JSONArray jsonhots, JSONObject jsonhot, String sid,
                                                  StringBuffer imagesBuf, StringBuffer imagesBuffer,
                                                  StringBuffer dataBuf, StringBuffer dataBuffer) throws Exception {
        Object[] result = new Object[2];
        Map<String,String> map = new HashMap<String,String>();
        if(jsonhot.containsKey("media")) {
            String fileType = jsonhot.getString("media");
            if(fileType.contains("photo")) {
                if("-1".equals(base.getType())) {
                    FileUtils.deleteFile(imagesBuffer.toString() + "hot"+sid+".jpg");
                }
                else {
                    map.put(imagesBuffer.toString() + "hot"+sid+".jpg", imagesBuf.toString() + "hot"+sid+".jpg");
                }
            }
            if(fileType.contains("audio") || fileType.contains("voice")) {
                if("-1".equals(base.getType())) {
                    FileUtils.deleteFile(imagesBuffer.toString() + "hot"+sid+".mp3");
                }
                else {
                    map.put(imagesBuffer.toString() + "hot"+sid+".mp3", imagesBuf.toString() + "hot"+sid+".mp3");
                }
            }
            if(fileType.contains("video")) {
                if("-1".equals(base.getType())) {
                    FileUtils.deleteFile(imagesBuffer.toString() + "hot"+sid+".mp4");
                }
                else
                {
                    map.put(imagesBuffer.toString() + "hot"+sid+".mp4", imagesBuf.toString() + "hot"+sid+".mp4");
                    map.put(imagesBuffer.toString() + "hot"+sid+"-cut.jpg", imagesBuf.toString() + "hot"+sid+"-cut.jpg");
                }
            }
        }

        FileUtils.deleteFile(dataBuffer.toString() + "hot.json");
        File dataPath = new File(dataBuffer.toString());
        if(!dataPath.exists()){
            dataPath.mkdirs();
        }
        FileUtils.writeFile(dataBuffer.toString() + "hot.json", jsonhots.toString());

        map.put(dataBuffer.toString() + "hot.json", dataBuf.toString() + "hot.json");

        String strsceneInfos = FileUtils.readFile(dataBuffer.toString() + "scene.json");
        JSONObject scenejson = new JSONObject();
        if(strsceneInfos!=null){
            scenejson = JSONObject.parseObject(strsceneInfos);
        }

        if(!StringUtils.isEmpty(base.getCapData())){
            FileUtils.writeFile(dataBuffer.toString() + "capData.json", new String(base.getCapData().getBytes(), "UTF-8"));
            scenejson.put("capData", dataBuf.toString() + "capData.json");
        }

        if(!StringUtils.isEmpty(base.getFrameData())){
            FileUtils.writeFile(dataBuffer.toString() + "frameData.json", new String(base.getFrameData().getBytes(), "UTF-8"));
            scenejson.put("frameData", dataBuf.toString() + "frameData.json");
        }

        if(!StringUtils.isEmpty(base.getPlayData())){
            FileUtils.writeFile(dataBuffer.toString() + "playData.json", new String(base.getPlayData().getBytes(), "UTF-8"));
            scenejson.put("playData", dataBuf.toString() + "playData.json");
            map.put(dataBuffer.toString() + "playData.json", dataBuf.toString() + "playData.json");
        }

        if(!StringUtils.isEmpty(base.getScreencapThumb())){
            FileUtils.writeFile(dataBuffer.toString() + "screencapThumb.json", new String(base.getScreencapThumb().getBytes(), "UTF-8"));
            scenejson.put("screencapThumb", dataBuf.toString() + "screencapThumb.json");
            map.put(dataBuffer.toString() + "screencapThumb.json", dataBuf.toString() + "screencapThumb.json");
        }

        if(jsonhots.size()>0){
            scenejson.put("hots", 1);
        }
        else{
            scenejson.put("hots", 0);
        }

        result[0] = map;
        result[1] = scenejson;
        return result;
    }

    private String deleteCustomStyleHots(SceneEditParamVO base, JSONArray jsonhots, JSONObject jsonhot, String sid){
        String hotsids = "";
        String[] styles = null;
        if(StrUtil.isNotEmpty(base.getStyleName())){
            styles = base.getStyleName().split(",");
        }

        for(int i=0;i<jsonhots.size();++i) {
            JSONObject ele = jsonhots.getJSONObject(i);

            //名字对应上就删除
            if(styles != null){
                for(String style : styles){
                    if(style.equals(ele.getString("styleId"))){
                        jsonhots.getJSONObject(i).put("styleId", null);
                        jsonhots.getJSONObject(i).put("style", "default");
                        jsonhots.getJSONObject(i).put("styleImageURL", null);
                    }
                }
            }

            hotsids += ele.getString("sid") +",";
            if(ele.getString("sid").equals(sid)) {
                if("-1".equals(base.getType())) {
                    jsonhots.remove(i);
                    jsonhot = ele;

                    if(!"aws".equals(this.type)){
                        JSONObject paramData = new JSONObject();
                        paramData.put("hotId", sid);
                        JSONObject hotListJson = JSONObject.parseObject(OkHttpUtils.httpGet(hotDomainList));
                        if(hotListJson != null){
                            JSONArray hotListArray = hotListJson.getJSONArray("data");
                            if(hotListArray != null){
                                for(int l = 0, len = hotListArray.size(); l < len; l++){
                                    OkHttpUtils.httpPostJson(hotListArray.getString(l) + hotDelete + "?hotId=" + sid
                                            , paramData.toJSONString());
                                }

                            }
                        }
                    }
                }
                else if("0".equals(base.getType())) {
                    jsonhots.set(i, jsonhot);
                }
            }
        }

        return hotsids;
    }

    private JSONArray getJsonhots(SceneEditParamVO base, StringBuffer dataBuffer, JSONObject jsonhot) throws Exception {
        String str = FileUtils.readFile(dataBuffer.toString() + "hot.json");
        JSONArray jsonhots = null;
        if (StrUtil.isNotEmpty(str)) {
            jsonhots = JSONArray.parseArray(str);
        }else {
            File file = new File(dataBuffer.toString() + "hot.json");
            if(!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
            }
            if(!file.exists()){
                file.createNewFile();
            }
            jsonhots = new JSONArray();
        }
        if(SceneEditType.ADD.code().equals(base.getType())){
            jsonhots.add(jsonhot);
        }

        return jsonhots;
    }

    private String getSidFromParams(SceneEditParamVO base, JSONObject jsonhot){
        String sid = base.getSid();
        //添加或者修改
        if(SceneEditType.ADD.code().equals(base.getType())){
            sid = jsonhot.getString("sid");
            if(StrUtil.isEmpty(sid)){
                throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
            }
        }
        else if(SceneEditType.UPDATE.code().equals(base.getType())){
            sid = jsonhot.getString("sid");
            if(StrUtil.isEmpty(sid)){
                throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
            }
        }
        else if(SceneEditType.DELETE.code().equals(base.getType())){
            if(StrUtil.isEmpty(sid)){
                throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
            }
        }
        return sid;
    }

    @Override
    public Page<SceneVO> getAllSceneByPage(@RequestBody UserParamVO param) {
        if(StrUtil.isEmpty(param.getAppUserName()) && StrUtil.isEmpty(param.getPhoneNum()) ){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        Long cameraId = null;
        Long userId = null;
        Integer cameraType = null;

        //获取相机id
        if(!StrUtil.isEmpty(param.getAppUserName()) && !StrUtil.isEmpty(param.getAppPassword())){
            ResultData<Camera> cameraResult = platformGoodsClient.getByChildNameAndChildPassword(param.getAppUserName(), param.getAppPassword());
            Camera camera = cameraResult.getData();
            if (camera == null) {
                throw new BusinessException(ErrorCode.FAILURE_CODE_3014);
            }
            cameraId = camera.getId();
        }

        //获取该用户id协作者的场景码集合
        List<String> sceneCodeList = null;
        if (StrUtil.isNotEmpty(param.getPhoneNum())) {
            ResultData<User> userResult = platformUserClient.getUserByName(param.getPhoneNum());
            User user = userResult.getData();
            if (user == null) {
                throw new BusinessException(ErrorCode.FAILURE_CODE_3015);
            }
            userId = user.getId();

            List<SceneCooperation> list = sceneCooperationService.list(
                    new LambdaQueryWrapper<SceneCooperation>()
                            .eq(SceneCooperation::getTbStatus, TbStatus.VALID.code())
                            .eq(SceneCooperation::getUserId, userId)
                            .orderByDesc(SceneCooperation::getId));

            if(CollUtil.isNotEmpty(list)){
                sceneCodeList = list.parallelStream().map(co -> {
                    return co.getNum();
                }).collect(Collectors.toList());
            }
        }

        if(param.getCameraType() != null){
            cameraType = param.getCameraType();
        }

        Camera camera = null;
        CameraDetail cameraDetail = null;
        Page<SceneVO> sceneVOPage =
                sceneProService.getAppAllSceneByPage(cameraId, userId, cameraType,
                        param.getPageNum(), param.getPageSize(), param.getOrderBy(),
                        param.getSceneType(), sceneCodeList, param.getSceneName());
        if(sceneVOPage.getCurrent() == 0){
            return sceneVOPage;
        }
        for(SceneVO sceneVO : sceneVOPage.getRecords()){
            // 当计算时，返回给前端的状态为计算中
            if (!ObjectUtils.isEmpty(sceneVO)) {
                if (sceneVO.getStatus() == -1) {
                    sceneVO.setStatus(0);
                } else if (sceneVO.getStatus() == 500) {
                    sceneVO.setStatus(-1);
                }
            }
            //相机id为空是123看房的场景
            if(sceneVO.getCameraId() == null){
                //当场景用户id等于该用户id，为用户场景，其余未协作场景
                if(sceneVO.getUserId().longValue() == userId.longValue()){
                    sceneVO.setSceneSourceType(1);
                }else {
                    sceneVO.setSceneSourceType(2);
                }
            }else {
                ResultData<Camera> cameraResult = platformGoodsClient.getCameraById(sceneVO.getCameraId());
                camera = cameraResult.getData();
                if(Objects.isNull(camera)){
                    continue;
                }
                    sceneVO.setChildName(camera.getChildName());
                    sceneVO.setSnCode(camera.getSnCode());

                ResultData<CameraDetail> cameraDetailResult = platformGoodsClient.getCameraDetailByCameraId(camera.getId());
                cameraDetail = cameraDetailResult.getData();
                if(cameraDetail != null){
                    //相机的userId为空，表示相机的场景
                    if(cameraDetail.getUserId() == null || userId == null){
                        sceneVO.setSceneSourceType(0);
                    }else if(userId != null && cameraDetail.getUserId().longValue() == userId.longValue()){
                        //相机用户id等于该用户id，既为用户的场景
                        sceneVO.setSceneSourceType(1);
                    }else if(cameraId != null && cameraDetail.getCameraId() != null && cameraDetail.getCameraId().longValue() == cameraId.longValue()
                            && cameraDetail.getCooperationUser() == null){
                        //场景相机id等于该相机id
                        sceneVO.setSceneSourceType(0);
                    }else if(cameraId != null && cameraDetail.getCameraId().longValue() == cameraId.longValue()
                            && cameraDetail.getCooperationUser() != null){
                        if(userId != null && cameraDetail.getCooperationUser().longValue() == userId.longValue()){
                            sceneVO.setSceneSourceType(2);
                        }else {
                            sceneVO.setSceneSourceType(0);
                        }
                    }else {
                        //最后不等于则为协作者场景
                        sceneVO.setSceneSourceType(2);
                    }
                }
            }
        }

        return sceneVOPage;
    }

    @Override
    public List<SceneVO> getAllForCameraName(@RequestBody UserParamVO user){
        if(StrUtil.isEmpty(user.getAppUserName()) || StrUtil.isEmpty(user.getAppPassword())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }
        ResultData<Camera> cameraResult = platformGoodsClient.getByChildNameAndChildPassword(user.getAppUserName(), user.getAppPassword());
        Camera camera = cameraResult.getData();
        if (camera == null) {
            throw new BusinessException(ErrorCode.FAILURE_CODE_3014);
        }

        List<ScenePro> list = sceneProService.list(
                new LambdaQueryWrapper<ScenePro>()
                        .eq(ScenePro::getTbStatus, TbStatus.VALID.code())
                        .eq(ScenePro::getCameraId, camera.getId())
                        .ne(ScenePro::getSceneType, SceneType.YJHZXNFY.code())
                        .in(ScenePro::getSceneStatus, SceneStatus.SUCCESS, SceneStatus.NO_DISPLAY).orderByDesc(ScenePro::getId));

        List<SceneVO> sceneList = sceneProService.convert(list);
        for(SceneVO sceneVO : sceneList){
            sceneVO.setChildName(user.getAppUserName());
        }
        return sceneList;
    }

    @Override
    public Long getSceneCount(@RequestBody UserParamVO user) {

        if(StrUtil.isEmpty(user.getAppUserName()) || StrUtil.isEmpty(user.getAppPassword())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }
        ResultData<Camera> CameraResult = platformGoodsClient.getByChildNameAndChildPassword(user.getAppUserName(), user.getAppPassword());
        Camera camera = CameraResult.getData();
        if(camera == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_3014);
        }

        return sceneProService.getSceneCount(camera.getId(), null);
    }

    @Override
    public Integer getSceneStatus(@RequestBody UserParamVO user) {

        if(StrUtil.isEmpty(user.getAppUserName()) || StrUtil.isEmpty(user.getAppPassword())
                || StrUtil.isEmpty(user.getNum())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }
        ResultData<Camera> CameraResult = platformGoodsClient.getByChildNameAndChildPassword(user.getAppUserName(), user.getAppPassword());
        Camera camera = CameraResult.getData();
        if(camera == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_3014);
        }

        ScenePro scene = sceneProService.findBySceneNum(user.getNum());
        if(scene == null){
            scene = sceneProService.findDeleteSceneBySceneNum(user.getNum());
            if(scene == null){
                throw new BusinessException(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005);
            }
            throw new BusinessException(SceneConstant.FAILURE_CODE_5006, SceneConstant.FAILURE_MSG_5006);
        }

        return scene.getSceneStatus();
    }

    @Override
    public Map<String, Object> getSceneStatusByUnicode(@RequestBody UserParamVO user){
        if(StrUtil.isEmpty(user.getAppUserName()) || StrUtil.isEmpty(user.getAppPassword())
                || StrUtil.isEmpty(user.getUnicode())){
            log.info("appUserName:" + user.getAppUserName() + ",appPassword:" + user.getAppPassword() +
                    ",unicode:" + user.getUnicode());
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }
        ResultData<Camera> CameraResult = platformGoodsClient.getByChildNameAndChildPassword(user.getAppUserName(), user.getAppPassword());
        Camera camera = CameraResult.getData();
        if(camera == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_3014);
        }

        SceneProPO sceneProPO = sceneProService.getSceneStatusByUnicode(user.getUnicode(), TbStatus.VALID.code());
        if(sceneProPO == null){
            sceneProPO = sceneProService.getSceneStatusByUnicode(user.getUnicode(), TbStatus.DELETE.code());
            if(sceneProPO == null){
                throw new BusinessException(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005);
            }
            throw new BusinessException(SceneConstant.FAILURE_CODE_5009, SceneConstant.FAILURE_MSG_5009);
        }
        if(sceneProPO.getPayStatus() == -2){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5006, SceneConstant.FAILURE_MSG_5006);
        }
        // 当计算时，返回给前端的状态为计算中
        if (sceneProPO.getSceneStatus() == -1) {
            sceneProPO.setSceneStatus(0);
        } else if (sceneProPO.getSceneStatus() == 500) {
            sceneProPO.setSceneStatus(-1);
        }
        Map<String, Object> map = new HashMap<>();
        //临时将-2改成1，app还没完全更新
        map.put("status", sceneProPO.getSceneStatus() == -2? 1 : sceneProPO.getSceneStatus());
        map.put("webSite", sceneProPO.getWebSite());
        map.put("sceneNum", sceneProPO.getNum());
        map.put("thumb", sceneProPO.getThumb());
        map.put("dataSource", sceneProPO.getDataSource());
        map.put("payStatus", sceneProPO.getPayStatus());
        map.put("recStatus", sceneProPO.getRecStatus());

        return map;
    }

    @Override
    public ResultData deleteForCameraName(@RequestBody UserParamVO user) throws Exception {
        if (user.getCameraId() == null || StrUtil.isEmpty(user.getNum())) {
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }
        ResultData<CameraDetail> detailResult = platformGoodsClient.getCameraDetailByCameraId(user.getCameraId());
        CameraDetail detail = detailResult.getData();
        if (detail == null) {
            throw new BusinessException(CameraConstant.FAILURE_6003);
        }

        ScenePro scenePro = sceneProService.findBySceneNum(user.getNum());
        if(scenePro == null){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005);
        }

        if(scenePro.getCameraId().longValue() != user.getCameraId().longValue()){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5010, SceneConstant.FAILURE_MSG_5010);
        }

        String[] nums = user.getNum().split(",");
        for (String num : nums) {
            SceneVO sceneVO = this.getSceneDetail(num);
            if (sceneVO == null){
                return ResultData.error(ErrorCode.FAILURE_CODE_5005);
            }
            ResultData resultData = this.deleteScene(num);
            if (sceneVO.getSceneScheme() >= 3 && sceneVO.getSpace() != null){

                ResultData<CameraDetail> cameraDetailResultData = platformGoodsClient.updateCameraDetailByCameraIdAndSpace(sceneVO.getCameraId(), -sceneVO.getSpace());
                CameraDetail detail2 = cameraDetailResultData.getData();
                if(detail2 != null){
                    //计算该相机所有扣费成功的场景容量总和
                    List<SceneVO> scenes = this.findScenesByUserIdAndSceneScheme(sceneVO.getCameraId(), "create_time", 1);
                    Long accumulateSpace = new Long("0");
                    for(SceneVO vo : scenes){
                        accumulateSpace = accumulateSpace + vo.getSpace();
                    }
                    //相机总容量 - 所有扣费成功的容量 = 可恢复场景的容量
                    if (detail2.getTotalSpace().compareTo(accumulateSpace) != -1){
                        this.unlockBeyondSpaceScenes(detail2.getTotalSpace() - accumulateSpace, sceneVO.getCameraId());
                    }
                }
            }

            //删除文件夹里面的场景关联
            folderSceneService.deleteBySceneId(sceneVO.getId());
        }


        return ResultData.ok();
    }

    public void lockBeyondSpaceScenes(Long usedSpace, Long totalSpace, Long cameraId) throws Exception{
        Long beyondSpace = usedSpace - totalSpace;
        List<SceneVO> scenes = this.findScenesByUserIdAndSceneScheme(cameraId, "create_time", PayStatus.PAY.code());
        Long accumulateSpace = 0L;
        List<Long> lockedIds = new ArrayList<>();
        if (scenes != null && scenes.size() > 0){
            for (SceneVO responseScene : scenes){
                accumulateSpace = accumulateSpace + responseScene.getSpace();
                if (accumulateSpace.compareTo(beyondSpace) == 1){
                    break;
                }
                lockedIds.add(responseScene.getId());
            }
        }
        lockOrUnlockScenes(lockedIds,true);
    }

    @Override
    public void unlockBeyondSpaceScenes(Long newSpace, Long cameraId) throws Exception{
        List<SceneVO> scenes = this.findScenesByUserIdAndSceneScheme(cameraId, "create_time", PayStatus.NO_CAPACITY.code());
        Long accumulateSpace = new Long("0");
        List<Long> unlockedIds = new ArrayList<>();
        if (scenes != null && scenes.size() > 0){
            for (SceneVO responseScene : scenes){
                if (responseScene.getPayStatus() == -1 || responseScene.getPayStatus() == -2){
                    //newSpace为空的时候，表示无限容量
                    if(newSpace == null){
                        unlockedIds.add(responseScene.getId());
                        continue;
                    }

                    accumulateSpace = accumulateSpace + responseScene.getSpace();
                    if (accumulateSpace.compareTo(newSpace) != 1){
                        unlockedIds.add(responseScene.getId());
                    }else {
                        break;
                    }
                }

            }
        }
        lockOrUnlockScenes(unlockedIds,false);
    }

    public void lockOrUnlockScenes(List<Long> lockedIds,Boolean lock) {
        if (lockedIds == null || lockedIds.size() == 0){
            return;
        }
        Integer payStatus = lock ? -2 : 1;
        for (Long id : lockedIds){
            ScenePro scenePro = sceneProService.getById(id);
            scenePro.setPayStatus(payStatus);
            sceneProService.updateById(scenePro);

            try{
                Map<String, Object> map = new HashMap<>();
                map.put("payStatus", payStatus);
                FileUtils.writeJsonFile(ConstantFilePath.SCENE_PATH + "data/data" + scenePro.getNum() + "/scene.json", map);
                com.alibaba.fastjson.JSONObject statusJson = new com.alibaba.fastjson.JSONObject();

                //临时将-2改成1，app还没完全更新
                statusJson.put("status", scenePro.getSceneStatus() == -2? 1 : scenePro.getSceneStatus());
                statusJson.put("webSite", scenePro.getWebSite());
                statusJson.put("sceneNum", scenePro.getNum());
                statusJson.put("thumb", scenePro.getThumb());
                statusJson.put("payStatus", scenePro.getPayStatus());
                FileUtils.writeFile(ConstantFilePath.SCENE_PATH+"data/data"+scenePro.getNum()+ File.separator+"status.json", statusJson.toString());
                uploadToOssUtil.upload(ConstantFilePath.SCENE_PATH+"data/data"+scenePro.getNum()+File.separator+"status.json",
                        "data/data"+scenePro.getNum()+File.separator+"status.json");

            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }



    public SceneVO getSceneDetail(String sceneNum) throws Exception{
        SceneVO vo = null;
        ScenePO scene = sceneService.findBySceneNum(sceneNum);
        if(scene != null){
            vo = getResponseScene(vo, scene);
            return vo;
        }

        ScenePro scenePro = sceneProService.findBySceneNum(sceneNum);
        SceneProExt sceneProExt = sceneProExtService.findBySceneProId(scenePro.getId());
        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());
        SceneProEditExt sceneProEditExt = sceneProEditExtService.getByProEditId(sceneProEdit.getId());
        vo = getResponseProScene(vo, scenePro, sceneProExt, sceneProEdit, sceneProEditExt);
        return vo;
    }

    private SceneVO getResponseScene(SceneVO vo, ScenePO scene) {
        if (Objects.isNull(scene))
            return vo;
        vo = new SceneVO();
        BeanUtils.copyProperties(scene, vo);
        vo.setThumbImg(scene.getThumbStatus());
        vo.setCreateTime(new DateTime(scene.getCreateTime()).toString("yyyy-MM-dd HH:mm"));
        vo.setSceneIndex(scene.getStyle());
        vo.setHasBGM(scene.getBgMusic());
        vo.setCameraType(scene.getSceneScheme());
        vo.setIsPublic(StringUtils.isEmpty(scene.getSceneKey()) ? 0 : 1);
        return vo;
    }

    private SceneVO getResponseProScene(SceneVO vo, ScenePro scenePro, SceneProExt sceneProExt,
                                        SceneProEdit sceneProEdit, SceneProEditExt sceneProEditExt) {
        if (Objects.isNull(scenePro))
            return vo;
        vo = new SceneVO();
        BeanUtils.copyProperties(sceneProEditExt, vo);
        BeanUtils.copyProperties(sceneProEdit, vo);
        BeanUtils.copyProperties(sceneProExt, vo);
        BeanUtils.copyProperties(scenePro, vo);
        vo.setCreateTime(new DateTime(scenePro.getCreateTime()).toString("yyyy-MM-dd HH:mm"));
        vo.setCameraType(scenePro.getSceneScheme());

        vo.setThumbImg(sceneProEdit.getThumbStatus());
        vo.setHasBGM(sceneProEdit.getBgMusic());
        vo.setIsPublic(StringUtils.isEmpty(sceneProEdit.getSceneKey()) ? 0 : 1);
        return vo;
    }

    @Override
    public ResultData deleteScene(String sceneNum) throws Exception {
        ScenePO scenePo = sceneService.findBySceneNum(sceneNum);
        SceneVO vo = null;
        if(scenePo != null){
            sceneService.update(new LambdaUpdateWrapper<Scene>()
                    .eq(Scene::getId, scenePo.getId())
                    .set(Scene::getTbStatus, TbStatus.DELETE.code())
                    .set(Scene::getUpdateTime, Calendar.getInstance().getTime()));

            vo = getResponseScene(vo, scenePo);
            return ResultData.ok(vo);
        }

        ScenePro scenePro = sceneProService.findBySceneNum(sceneNum);
        SceneProExt sceneProExt = sceneProExtService.findBySceneProId(scenePro.getId());
        scenePro.setTbStatus(TbStatus.DELETE.code());
        scenePro.setUpdateTime(new Date());
        sceneProService.updateById(scenePro);

        JSONObject statusJson = new JSONObject();
        //临时将-2改成1，app还没完全更新
        statusJson.put("status", scenePro.getSceneStatus() == -2? 1 : scenePro.getSceneStatus());
        statusJson.put("webSite", scenePro.getWebSite());
        statusJson.put("sceneNum", scenePro.getNum());
        statusJson.put("thumb", scenePro.getThumb());
        statusJson.put("payStatus", scenePro.getPayStatus());
        statusJson.put("tbStatus", scenePro.getTbStatus());
        FileUtils.writeFile(ConstantFilePath.SCENE_PATH+"data/data"+sceneNum+File.separator+"status.json", statusJson.toString());
        uploadToOssUtil.upload(ConstantFilePath.SCENE_PATH+"data/data"+sceneNum+File.separator+"status.json",
                "data/data"+sceneNum+File.separator+"status.json");

        return ResultData.ok();
    }

    @Override
    public List<SceneVO> findScenesByUserIdAndSceneScheme(Long cameraId, String orderBy, Integer payStatus) {
        List<ScenePro> sceneProList = sceneProService.list(new LambdaQueryWrapper<ScenePro>()
                .eq(ScenePro::getTbStatus, TbStatus.VALID.code())
                .in(ScenePro::getSceneStatus, SceneStatus.SUCCESS.code(), SceneStatus.NO_DISPLAY.code())
                .eq(ScenePro::getCameraId, cameraId)
                .eq(ScenePro::getPayStatus, payStatus).last(orderBy));

        List<Long> idList = sceneProList.stream().map(pro -> {
            return pro.getId();
        }).collect(Collectors.toList());

        List<SceneProExt> sceneProExtList = sceneProExtService.list(new LambdaQueryWrapper<SceneProExt>().in(SceneProExt::getSceneProId, idList));
        Map<Long, SceneProExt> extMap = new HashMap<>();
        sceneProExtList.forEach(ext -> {
            extMap.put(ext.getSceneProId(), ext);
        });

        List<SceneVO> voList = sceneProList.parallelStream().map(pro -> {
            SceneVO vo = new SceneVO();
            SceneProExt sceneProExt = extMap.get(pro.getId());
            BeanUtils.copyProperties(sceneProExt, vo);
            BeanUtils.copyProperties(pro, vo);
            return vo;
        }).collect(Collectors.toList());

        return voList;
    }

    @Override
    public ResultData getScreencapVoice(@RequestBody SceneParamVO scene) throws Exception {
        if (StrUtil.isEmpty(scene.getScreencapMusic()) || StrUtil.isEmpty(scene.getOriginalFileName())
                || StrUtil.isEmpty(scene.getNum())) {
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ScenePro scenePro = sceneProService.findBySceneNum(scene.getNum());
        if(scenePro == null){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
        }

        SceneProEdit sceneProEdit = sceneProEditService.findByProId(scenePro.getId());

        //八目存放新的录音位置
        long time = System.currentTimeMillis();
        Map<String, Object> map = new HashMap();
        map.put("screencapVoiceSoundsyncFileName", scene.getScreencapMusic() + ".mp3");
        map.put("screencapVoiceSoundsync", scene.getOriginalFileName() + "?t=" + time);
        log.info("微信上传的音频路径：" + scene.getOriginalFileName() + "?t=" + time);
        map.put("screencapVoiceType", "soundsync");
        map.put("version", sceneProEdit.getVersion() + 1);

        StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH)
                .append("data").append(File.separator)
                .append("data").append(scene.getNum());
        FileUtils.writeJsonFile(dataBuffer.append(File.separator).append("scene.json").toString(), map);

        sceneProEdit.setScreencapVoiceSoundsync(scene.getOriginalFileName() + "?t=" + time);
        sceneProEdit.setScreencapVoiceType("soundsync");
        sceneProEdit.setVersion(sceneProEdit.getVersion() + 1);

        FileUtils.downLoadFromUrl(scene.getOriginalFileName() + "?t=" + time, scene.getScreencapMusic() + ".mp3",
                ConstantFilePath.SCENE_PATH+ "voice" + File.separator + "voice" + scene.getNum());

        sceneProEditService.updateById(sceneProEdit);
        return ResultData.ok();
    }

    public List<SceneVO> getAllSceneByUserName(UserParamVO user) throws Exception {
        if (StrUtil.isEmpty(user.getPhoneNum())) {
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ResultData<User> userResult = platformUserClient.getUserByName(user.getPhoneNum());
        User ssoUser = userResult.getData();

        if (ssoUser == null) {
            throw new BusinessException(ErrorCode.FAILURE_CODE_3015);
        }

        if(user.getCameraType() == null){
            user.setCameraType(4);
        }
        List<SceneProPO> list = sceneProService.findByUserIdAndCameraType(ssoUser.getId(), user.getCameraType());

        List<SceneVO> sceneList = sceneProService.convert2(list);
        for(SceneVO vo : sceneList){
            ResultData<Camera> cameraResult = platformGoodsClient.getCameraById(vo.getCameraId());
            Camera camera = cameraResult.getData();
            if(camera != null){
                vo.setChildName(camera.getChildName());
            }
        }
        return sceneList;
    }

    @Override
    public ResultData cooperationSceneList(@RequestBody UserParamVO user){
        if (StrUtil.isEmpty(user.getPhoneNum())) {
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        ResultData<User> userResult = platformUserClient.getUserByName(user.getPhoneNum());
        User ssoUser = userResult.getData();

        if (ssoUser == null) {
            throw new BusinessException(ErrorCode.FAILURE_CODE_3015);
        }

        if(user.getCameraType() == null){
            user.setCameraType(4);
        }

        List<SceneCooperation> list = sceneCooperationService.list(
                    new LambdaQueryWrapper<SceneCooperation>()
                            .eq(SceneCooperation::getTbStatus, TbStatus.VALID.code())
                            .eq(SceneCooperation::getUserId, ssoUser.getId())
                            .orderByDesc(SceneCooperation::getId));

        if(list == null || list.size() <= 0){
            return ResultData.ok();
        }

        List<String> sceneCodeList = list.parallelStream().map(sc -> {
            return sc.getNum();
        }).collect(Collectors.toList());

        List<SceneProPO>  sceneProPOList = sceneProService.findBySceneNums(sceneCodeList, user.getCameraType());

        List<SceneVO> sceneVOList = sceneProService.convert2(sceneProPOList);
        for(SceneVO responseScene : sceneVOList){
            ResultData<Camera> cameraResult = platformGoodsClient.getCameraById(responseScene.getCameraId());
            Camera camera = cameraResult.getData();
            if(camera != null){
                responseScene.setChildName(camera.getChildName());
                responseScene.setSnCode(camera.getSnCode());
            }
        }

        return ResultData.ok(sceneVOList);
    }




}
