package com.fdkankan.modeling.receiver; import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.fdkankan.common.util.ComputerUtil; import com.fdkankan.common.util.UploadToOssUtil; import com.fdkankan.modeling.constants.RedisKey; import com.fdkankan.modeling.constants.SysConstants; import com.fdkankan.modeling.entity.SceneFileBuild; import com.fdkankan.modeling.entity.ScenePro; import com.fdkankan.modeling.entity.SceneProExt; import com.fdkankan.modeling.feign.UserFeign; import com.fdkankan.modeling.push.PushMessageConfig; import com.fdkankan.modeling.service.ISceneFileBuildService; import com.fdkankan.modeling.service.ISceneProExtService; import com.fdkankan.modeling.service.ISceneProService; import com.fdkankan.modeling.service.ISceneService; import com.fdkankan.modeling.utils.DingDingUtils; import com.fdkankan.modeling.utils.PushMsgUtil; import com.fdkankan.mq.message.BuildSceneMqMessage; import com.fdkankan.platform.api.vo.User; import com.fdkankan.redis.util.RedisUtil; import com.fdkankan.utils.constant.ConstantFilePath; import com.fdkankan.utils.constant.ConstantUrl; import com.fdkankan.utils.utils.CreateObjUtil; import com.fdkankan.utils.utils.FileUtil; import com.fdkankan.utils.utils.FileUtils; import com.taobao.api.ApiException; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.StringUtils; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; import org.apache.rocketmq.common.message.MessageExt; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; import java.io.*; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.*; import static com.fdkankan.modeling.push.PushMessageConfig.*; @Log4j2 @Component public class BuildSceneReceiver implements MessageListenerConcurrently { @Autowired private ISceneService sceneService; @Autowired private ISceneProService sceneProService; @Autowired private UserFeign userFeign; @Autowired private ISceneFileBuildService sceneFileBuildService; @Autowired private ISceneProExtService sceneProExtService; @Autowired RedisUtil redisUtil; @Autowired RedisTemplate redisTemplate; private RestTemplate restTemplate = new RestTemplate(); @Value("${4dkk.laserService.host}") private String laserHost; @Value("${oss.type}") private String ossType; @Value("${prefix.ali}") private String prefixAli; @Resource private UploadToOssUtil uploadToOssUtil; @Override public ConsumeConcurrentlyStatus consumeMessage(List msgExt, ConsumeConcurrentlyContext consumeConcurrentlyContext) { if (CollectionUtils.isEmpty(msgExt)) { log.error("消息内容为空,退出构建,当前服务器id:{}", SysConstants.hostName); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } MessageExt messageExt = msgExt.get(0); BuildSceneMqMessage message = JSONObject.parseObject(messageExt.getBody(), BuildSceneMqMessage.class); log.info("开始处理消息,消息队列:{},消息内容:{}", consumeConcurrentlyContext.getMessageQueue().getTopic(), JSONObject.toJSONString(message)); process(message); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } public void process(BuildSceneMqMessage message) { final ExecutorService exec = Executors.newFixedThreadPool(1); Callable call = (Callable) () -> { //开始执行耗时操作 try { String key = RedisKey.SCENE_BUILDING + message.getSceneNum(); // 获取缓存锁,防止重复消费 Long building = redisUtil.incr(key, 1); if (building.compareTo(1L) != 0) { log.error("场景正在构建中,退出构建,当前服务器id:{},参数:{}", SysConstants.hostName, JSONObject.toJSONString(message)); } else { redisTemplate.expire(key, Duration.of(SysConstants.modelTimeOut, ChronoUnit.HOURS)); } //休眠2秒等待数据入库 Thread.sleep(2000L); try { FileUtils.writeFile("/opt/hosts/running.txt", DateUtil.formatDateTime(new Date())); String tomcatLog = "scenenum:" + message.getSceneNum() + "\ntime:" + DateUtil.formatDateTime(new Date()) + " action:create hostname:" + SysConstants.hostName; //打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件 FileWriter writer = new FileWriter("/mnt/elastic_log/tomcat" + "_" + message.getSceneNum() + ".log", true); writer.write(tomcatLog); writer.close(); } catch (Exception e) { e.printStackTrace(); } buildScene(message); redisUtil.del(key); try { FileUtils.deleteFile("/opt/hosts/running.txt"); String tomcatLog = "scenenum:" + message.getSceneNum() + "\ntime:" + DateUtil.formatDateTime(new Date()) + " action:delete hostname:" + SysConstants.hostName; //打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件 FileWriter writer = new FileWriter("/mnt/elastic_log/tomcat" + "_" + message.getSceneNum() + "log", true); writer.write(tomcatLog); writer.close(); } catch (Exception e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); sceneService.updateStatus(message.getSceneNum(), -1); BuildSceneReceiver.this.handFail("计算失败", message); } log.info("场景生成好了***"); return "success"; }; Future future = exec.submit(call); try { future.get(SysConstants.modelTimeOut, TimeUnit.HOURS); //任务处理超时时间设为 24个小时 } catch (TimeoutException ex) { ex.printStackTrace(); StringWriter trace=new StringWriter(); ex.printStackTrace(new PrintWriter(trace)); log.error("超时了"); log.error(trace.toString()); FileUtils.deleteFile("/opt/hosts/running.txt"); future.cancel(true); handFail("计算超时",message); } catch (Exception e) { e.printStackTrace(); StringWriter trace=new StringWriter(); e.printStackTrace(new PrintWriter(trace)); log.error(trace.toString()); FileUtils.deleteFile("/opt/hosts/running.txt"); future.cancel(true); handFail("计算失败",message); } } private void buildScene(BuildSceneMqMessage message){ String projectNum = null; SceneFileBuild sceneFileBuildEntity = null; ScenePro scene = null; SceneProExt sceneProExt = null; try{ if(StringUtils.equals(message.getIsStandardization(),"1")){ //表示标定算法 ComputerUtil.computerCalibration(message.getPath()); return; } String unicode = message.getUnicode(); String path = message.getPath(); String prefix = message.getPrefix(); String imgsName = message.getImgsName(); projectNum = message.getSceneNum(); String userName = message.getUserName(); //不同的相机不同的方法 String cameraType = message.getCameraType(); String algorithm = message.getAlgorithm(); String fileId = message.getFileId(); String cameraName = message.getCameraName(); //0表示有4k图,1表示没有 String resolution = message.getResolution(); //判断调用V2还是V3版本的算法 String buildType = ObjectUtils.isEmpty(message.getBuildType()) ? "V2" : message.getBuildType(); log.info("执行数据库操作--前"); sceneFileBuildEntity = sceneFileBuildService.findByFileId(fileId); log.info("执行数据库操作--后"); Map dataMap = ComputerUtil.getTypeString(cameraType, algorithm, resolution); String splitType = dataMap.get("splitType"); String skyboxType = dataMap.get("skyboxType"); String dataDescribe = dataMap.get("dataDescribe"); log.info("用的算法是:"+algorithm); log.info("用的相机是:"+ (Integer.parseInt(cameraType) < 4 ? "单球目" : "双球目(八目)")); Map map = new HashMap<>(); //该场景使用的容量 Long space = 0L; //支付状态 int payStatus = 0; //4表示硬件部研发的双球目相机,其余为旧版本相机 if(Integer.parseInt(cameraType) < 3){ for(int i = 0;i<5;++i){ try{ FileUtils.downLoadFromUrl(prefix+imgsName+"?m="+new Date().getTime(), imgsName, path + File.separator + "capture"); FileUtils.decompress(path + File.separator + "capture" +File.separator+imgsName, path + File.separator + "capture") ; break; } catch(Exception e){ e.printStackTrace(); StringWriter trace=new StringWriter(); e.printStackTrace(new PrintWriter(trace)); log.error(trace.toString()); if(i<4) { FileUtils.deleteFile(path + File.separator + "capture" +File.separator+imgsName); FileUtils.delFolder(path + File.separator + "capture" +File.separator+"images"); } Thread.sleep(10000); } } FileUtils.deleteFile(path + File.separator + "capture" +File.separator+"zip.Zip"); String data = FileUtils.readFile(path + File.separator + "capture" +File.separator+"data.fdage"); JSONObject dataJson = new JSONObject(); if(data!=null){ dataJson = JSONObject.parseObject(data); if(dataJson.containsKey("imgs")){ splitType = "SPLIT_V4"; } } //生成project.json和data.json供算法部使用 ComputerUtil.createJson(path, splitType, skyboxType, dataDescribe, projectNum, path); //计算模型并返回需要上传oss的文件集合 map = ComputerUtil.computer(projectNum, path, buildType); uploadToOssUtil.uploadMulFiles(map); log.info("双目上完oss结束修改数据:"+projectNum); sceneService.updateTime(projectNum, space, payStatus); } else { //休眠1秒,否则可能获取不到场景资源 Thread.sleep(1000); scene = sceneProService.findBySceneNum(projectNum); sceneProExt = sceneProExtService.getBySceneProId(scene.getId()); if(scene == null){ log.info(projectNum + ":场景不存在"); handFail("场景不存在",message); return; } long start = System.currentTimeMillis(); //cameraType=5为新版本双目, cameraType=6为小红屋新版本双目 if(Integer.parseInt(cameraType) == 5 || Integer.parseInt(cameraType) == 6){ path = ConstantFilePath.BUILD_MODEL_PATH + unicode; //下载zip包,并解压 FileUtils.downLoadFromUrl(prefix + "/" + imgsName + "?m=" + System.currentTimeMillis(), imgsName, path + File.separator + "capture"); FileUtils.decompress(path + File.separator + "capture" + File.separator + imgsName, path + File.separator + "capture") ; FileUtil.delFile(path + File.separator + "capture" + File.separator + imgsName); }else if(Integer.parseInt(cameraType) == 14 ) { CreateObjUtil.ossUtilCp(ConstantFilePath.OSS_PREFIX + cameraName.replace("4DKKPRO_", "") .replace("-fdage", "").toLowerCase() + File.separator + fileId + File.separator + unicode + File.separator, ConstantFilePath.BUILD_MODEL_LASER_PATH + cameraName.replace("4DKKPRO_", "") .replace("-fdage", "").toLowerCase() + File.separator + fileId + File.separator + unicode + File.separator + "capture"); path = ConstantFilePath.BUILD_MODEL_LASER_PATH + cameraName.replace("4DKKPRO_", "").replace("-fdage", "").toLowerCase() + File.separator + fileId + File.separator + unicode; } else if(Integer.parseInt(cameraType) >= 4 ) { CreateObjUtil.ossUtilCp(ConstantFilePath.OSS_PREFIX + cameraName.replace("4DKKPRO_", "") .replace("-fdage", "").toLowerCase() + File.separator + fileId + File.separator + unicode + File.separator, ConstantFilePath.BUILD_MODEL_PATH + cameraName.replace("4DKKPRO_", "") .replace("-fdage", "").toLowerCase() + File.separator + fileId + File.separator + unicode + File.separator + "capture"); path = ConstantFilePath.BUILD_MODEL_PATH + cameraName.replace("4DKKPRO_", "").replace("-fdage", "").toLowerCase() + File.separator + fileId + File.separator + unicode; } String data = FileUtils.readFile(path + File.separator + "capture" +File.separator+"data.fdage"); //获取data.fdage的内容 JSONObject dataJson = new JSONObject(); if(data!=null){ dataJson = JSONObject.parseObject(data); } //判断是否计算过资源,若计算过删除缓存 File caches = new File(path + File.separator + "caches"); if(caches.exists()){ for(File deleteFile : caches.listFiles()){ if(new File(path + "_images").exists()){ if(deleteFile.isDirectory()){ FileUtils.delAllFile(deleteFile.getAbsolutePath()); }else { FileUtils.deleteFile(deleteFile.getAbsolutePath()); } } else if(!deleteFile.getAbsolutePath().contains("images")){ if(deleteFile.isDirectory()){ FileUtils.delAllFile(deleteFile.getAbsolutePath()); }else { FileUtils.deleteFile(deleteFile.getAbsolutePath()); } } } } if(new File(path + File.separator + "results").exists()){ FileUtils.delAllFile(path + File.separator + "results"); } //生成project.json和data.json供算法部使用 log.info("path:" + path); if(dataJson.containsKey("videoVersion") && StringUtils.isNotEmpty(dataJson.getString("videoVersion")) && Integer.parseInt(dataJson.getString("videoVersion")) < 4){ //v2版本使用4k算法 skyboxType = "SKYBOX_V6"; } ComputerUtil.createJson(path, splitType, skyboxType, dataDescribe, projectNum, path); //计算模型并返回需要上传oss的文件集合 map = ComputerUtil.computer(projectNum, path, buildType); if(Integer.parseInt(cameraType) == 5 || Integer.parseInt(cameraType) == 6){ map.put(path + File.separator + "capture/stitch_params.txt", "data/data" + projectNum + "/stitch_params.txt"); } map.put(path + File.separator + "capture/Up.xml", "data/data" + projectNum + "/Up.xml"); map.put(path + File.separator + "capture/Up2.xml", "data/data" + projectNum + "/Up2.xml"); if(Integer.parseInt(cameraType) == 13){ //转台相机 map.put(path + File.separator + "capture/Up.txt", "data/data" + projectNum + "/Up.txt"); map.put(path + File.separator + "capture/Up2.txt", "data/data" + projectNum + "/Up2.txt"); } uploadToOssUtil.uploadMulFiles(map); payStatus = 1; File spaceFile = null; for (String key : map.keySet()) { spaceFile = new File(key); if(spaceFile.exists()){ space += spaceFile.length(); } } log.info("八目上完oss结束修改数据:"+projectNum); //获取upload中的video视频名称 String uploadData = FileUtils.readFile(path + File.separator + "results" +File.separator+"upload.json"); com.alibaba.fastjson.JSONObject uploadJson = null; JSONArray array = null; if(uploadData!=null) { uploadJson = com.alibaba.fastjson.JSONObject.parseObject(uploadData); array = uploadJson.getJSONArray("upload"); } com.alibaba.fastjson.JSONObject fileJson = null; String fileName = ""; //读取videos_hdr_param.json, 保存点位视频的value Map videoMap = new HashMap<>(); String videosHdr = FileUtils.readFile(path + File.separator + "results/videos/videos_hdr_param.json"); JSONArray videoArray = null; if(StringUtils.isNotEmpty(videosHdr)){ videoArray = com.alibaba.fastjson.JSONObject.parseObject(videosHdr).getJSONArray("hdr_param"); } if(videoArray != null){ for(int i = 0, len = videoArray.size(); i < len; i++) { videoMap.put(videoArray.getJSONObject(i).getString("name"), videoArray.getJSONObject(i).getString("value")); if(videoArray.getJSONObject(i).containsKey("fov")){ videoMap.put(videoArray.getJSONObject(i).getString("name") + "_fov", videoArray.getJSONObject(i).getString("fov")); } } } //计算ts文件的大小,并拼接成json格式 JSONArray jsonArray = new JSONArray(); com.alibaba.fastjson.JSONObject videoJson = null; com.alibaba.fastjson.JSONObject videosJson = new com.alibaba.fastjson.JSONObject(); long videoSize = 0L; for(int i = 0, len = array.size(); i < len; i++) { fileJson = array.getJSONObject(i); fileName = fileJson.getString("file"); if(fileJson.getIntValue("clazz") == 11 && fileName.contains(".mp4") && !fileName.contains("-ios.mp4")){ videoJson = new com.alibaba.fastjson.JSONObject(); videoJson.put("id", fileName.substring( 0, fileName.lastIndexOf(".")).replace("videos/", "")); //如果ts文件存在,就计算ts大小 if(new File(path + File.separator + "results" +File.separator+ fileName.replace(".mp4", ".ts")).exists()){ videoSize = new File(path + File.separator + "results" +File.separator+ fileName.replace(".mp4", ".ts")).length(); videoJson.put("tsSize", videoSize); } if(videoMap.containsKey(videoJson.get("id"))){ videoJson.put("value", videoMap.get(videoJson.get("id"))); } if(videoMap.containsKey(videoJson.get("id") + "_fov")){ videoJson.put("blend_fov", videoMap.get(videoJson.get("id") + "_fov")); }else { videoJson.put("blend_fov", 7); } jsonArray.add(videoJson); } } videosJson.put("data", jsonArray); if(dataJson.containsKey("videoVersion") && StringUtils.isNotEmpty(dataJson.getString("videoVersion")) && Integer.parseInt(dataJson.getString("videoVersion")) >= 4){ videosJson.put("version", 3); if("oss".equals(ossType)){ videosJson.put("upPath", prefixAli + "data/data" + projectNum + "/Up.xml"); } if("s3".equals(ossType)){ videosJson.put("upPath", ConstantUrl.PREFIX_AWS + "data/data" + projectNum + "/Up.xml"); } if(Integer.parseInt(cameraType) == 13){ //转台相机 videosJson.put("upPath", videosJson.getString("upPath").replace(".xml", ".txt")); } }else { videosJson.put("version", 1); if("oss".equals(ossType)){ videosJson.put("upPath", prefixAli + "data/data" + projectNum + "/Up2.xml"); } if("s3".equals(ossType)){ videosJson.put("upPath", ConstantUrl.PREFIX_AWS + "data/data" + projectNum + "/Up2.xml"); } if(Integer.parseInt(cameraType) == 13){ //转台相机 videosJson.put("upPath", videosJson.getString("upPath").replace(".xml", ".txt")); } } if(Integer.parseInt(cameraType) == 5 || Integer.parseInt(cameraType) == 6){ videosJson.put("version", 1); if("oss".equals(ossType)){ videosJson.put("upPath", prefixAli + "data/data" + projectNum + "/stitch_params.txt"); } if("s3".equals(ossType)){ videosJson.put("upPath", ConstantUrl.PREFIX_AWS + "data/data" + projectNum + "/stitch_params.txt"); } } long computeTime = (System.currentTimeMillis() - start) / 1000; sceneProService.updateTime(projectNum, space, payStatus, videosJson.toJSONString(), computeTime); //更新scene.json里面的video数据 StringBuffer dataBuf = new StringBuffer() .append("data").append(File.separator) .append("data").append(projectNum) .append(File.separator); StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString()); String strsceneInfos = FileUtils.readFile(dataBuffer.toString() + "scene.json"); com.alibaba.fastjson.JSONObject scenejson = new com.alibaba.fastjson.JSONObject(); if(strsceneInfos!=null){ scenejson = com.alibaba.fastjson.JSONObject.parseObject(strsceneInfos); } scenejson.put("videos", videosJson.toJSONString()); FileUtils.writeFile(dataBuffer.toString() + "scene.json", scenejson.toString()); User userEntity = userFeign.findByUserName(userName); if(userEntity == null){ userFeign.updateUserUsedSpaceBySceneNum(null, projectNum); }else { userFeign.updateUserUsedSpaceBySceneNum(userEntity.getId(), projectNum); } if (sceneFileBuildEntity != null){ sceneFileBuildEntity.setBuildStatus(3); sceneFileBuildService.updateById(sceneFileBuildEntity); } //根据data.fdage推送计算完成的消息 log.info("推送消息,渠道是 {}, 手机token是 {}", dataJson.get("pushChannel"), dataJson.get("pushToken")); if(dataJson.containsKey("pushChannel") && dataJson.containsKey("pushToken")){ try{ if(!"s3".equals(ossType)){ PushMessageConfig demo = null; if(dataJson.getIntValue("pushChannel") == 0){ if(Integer.parseInt(cameraType) == 10 || Integer.parseInt(cameraType) == 13){ //ios log.info("IOS_KEY:{}, IOS_SECRET:{}", IOS_KEY_Z, IOS_SECRET_Z); demo = new PushMessageConfig(IOS_KEY_Z, IOS_SECRET_Z); demo.sendIOSUnicast(dataJson.getString("pushToken"), "四维看看Minion", scene.getSceneName() + "计算完成", "您上传的" + scene.getSceneName() + "计算完成,点击查看", scene.getWebSite()); }else { //ios log.info("IOS_KEY:{}, IOS_SECRET:{}", IOS_KEY, IOS_SECRET); demo = new PushMessageConfig(IOS_KEY, IOS_SECRET); demo.sendIOSUnicast(dataJson.getString("pushToken"), "四维看看Pro", scene.getSceneName() + "计算完成", "您上传的" + scene.getSceneName() + "计算完成,点击查看", scene.getWebSite()); } }else { if(Integer.parseInt(cameraType) == 10 || Integer.parseInt(cameraType) == 13){ //ios //安卓 log.info("ANDROID_KEY:{}, ANDROID_SECRET:{}", ANDROID_KEY_Z, ANDROID_SECRET_Z); demo = new PushMessageConfig(ANDROID_KEY_Z, ANDROID_SECRET_Z); demo.sendAndroidUnicast2(dataJson.getString("pushToken"), "四维看看Minion", scene.getSceneName() + "计算完成", "您上传的" + scene.getSceneName() + "计算完成,点击查看", scene.getWebSite()); }else { //安卓 log.info("ANDROID_KEY:{}, ANDROID_SECRET:{}", ANDROID_KEY, ANDROID_SECRET); demo = new PushMessageConfig(ANDROID_KEY, ANDROID_SECRET); demo.sendAndroidUnicast(dataJson.getString("pushToken"), "四维看看Pro", scene.getSceneName() + "计算完成", "您上传的" + scene.getSceneName() + "计算完成,点击查看", scene.getWebSite()); } } }else { PushMsgUtil.googlePushMsg(dataJson.getString("pushToken"), scene.getSceneName() + "计算完成", "您上传的" + scene.getSceneName() + "计算完成,点击查看", scene.getWebSite()); } log.info("消息推送结束!"); }catch (Exception e){ log.info("推送消息失败:"); e.printStackTrace(); } } //计算成功 激光转台相机推送 log.info("激光转台相机 同步 请求 "); if(Integer.parseInt(cameraType) == 14){ try { String title = ""; if(StringUtils.isNotEmpty(scene.getSceneName())){ title = scene.getSceneName(); } String dataSource = sceneProExt.getDataSource(); String jgPath = dataSource; //创建目录 if(dataSource.lastIndexOf("/")!=-1){ jgPath = jgPath + "_laserData"; }else{ jgPath = jgPath.substring(0,jgPath.length()-1) + "_laserData"; } FileUtils.createDir(jgPath+"/extras"); log.info("生成 激光相机目录 " + jgPath); //生成data.json JSONObject jgDataJson = new JSONObject(); jgDataJson.put("split_type", "SPLIT_V15"); jgDataJson.put("skybox_type", "SKYBOX_V5"); jgDataJson.put("extras", null); FileUtils.writeFile(jgPath + File.separator + "data.json", jgDataJson.toString()); CreateObjUtil.cpfile(dataSource + "/results/laserData/cover", jgPath+"/extras/"); CreateObjUtil.cplaserfile(dataSource + "/results/laserData", jgPath+File.separator); //激光相机 String url = laserHost+"/indoor/{sceneCode}/api/init?path=" + jgPath + File.separator + "laserData" + "&title="+ title + "&childName=" + cameraName + "&createTime=" + scene.getCreateTime() + "&snCode="+ cameraName; if(scene.getUserId()!=null){ url = url + "&userId=" + scene.getUserId(); } if(StringUtils.isNotEmpty(userName)){ url = url + "&phone=" + userName; } url = url.replace("{sceneCode}",scene.getSceneCode()); log.info("激光转台相机 同步 :" + url); com.alibaba.fastjson.JSONObject hotListJson = com.alibaba.fastjson.JSONObject.parseObject(restTemplate.getForObject(url,String.class)); log.info("激光转台相机 同步结束 :" + hotListJson); }catch (Exception e){ e.printStackTrace(); handFail("激光转台相机同步失败",message); } } } CreateObjUtil.deleteFile(path.replace(ConstantFilePath.BUILD_MODEL_PATH, "/") + "/capture"); } catch(Exception e){ log.error("计算大场景失败"+projectNum); sceneService.updateStatus(projectNum, -1); if (sceneFileBuildEntity != null){ sceneFileBuildEntity.setBuildStatus(-1); sceneFileBuildService.updateById(sceneFileBuildEntity); } e.printStackTrace(); StringWriter trace=new StringWriter(); e.printStackTrace(new PrintWriter(trace)); log.error(trace.toString()); handFail("计算失败",message); }finally { try{ scene = sceneProService.findBySceneNum(projectNum); if(scene != null){ com.alibaba.fastjson.JSONObject statusJson = new com.alibaba.fastjson.JSONObject(); //临时将-2改成1,app还没完全更新 int status = sceneProExt.getSceneStatus(); if(status == -2){ status = 1; }else if(status == -1){ // 失败状态不予显示到客户端 status = 0; } statusJson.put("status", status); statusJson.put("webSite", scene.getWebSite()); statusJson.put("sceneNum", scene.getSceneCode()); statusJson.put("thumb", scene.getThumb()); statusJson.put("payStatus", sceneProExt.getPayStatus()); FileUtils.writeFile(ConstantFilePath.SCENE_PATH+"data/data"+projectNum+File.separator+"status.json", statusJson.toString()); uploadToOssUtil.upload(ConstantFilePath.SCENE_PATH+"data/data"+projectNum+File.separator+"status.json", "data/data"+projectNum+File.separator+"status.json"); //上送日志 uploadToOssUtil.upload(sceneProExt.getDataSource()+File.separator+"console.log", "build_log/"+scene.getSceneCode()+File.separator+"console.log"); } }catch (Exception e){ e.printStackTrace(); } } } private void handFail(String reason,BuildSceneMqMessage message){ String serverPath = message.getPath().substring(0,message.getPath().lastIndexOf("/")+1).concat(message.getPrefix()); handFail(reason,serverPath,message.getSceneNum()); } private void handFail(String reason,String serverPath,String num){ // 释放缓存锁 redisTemplate.delete(RedisKey.SCENE_BUILDING + num); CompletableFuture.runAsync(() -> { try { DingDingUtils.sendMsgToDingRobot(reason,serverPath,num); } catch (ApiException | UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException apiException) { apiException.printStackTrace(); } }); } }