SceneServiceImpl.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. package com.fdkankan.scene.service.impl;
  2. import cn.hutool.core.img.ImgUtil;
  3. import cn.hutool.core.io.FileUtil;
  4. import cn.hutool.core.lang.UUID;
  5. import cn.hutool.core.thread.ThreadUtil;
  6. import cn.hutool.core.util.ObjUtil;
  7. import cn.hutool.core.util.ObjectUtil;
  8. import cn.hutool.core.util.StrUtil;
  9. import com.alibaba.fastjson.JSON;
  10. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  11. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  12. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  13. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  14. import com.fdkankan.common.constant.CommonOperStatus;
  15. import com.fdkankan.common.constant.ErrorCode;
  16. import com.fdkankan.common.constant.SceneConstant;
  17. import com.fdkankan.common.constant.SceneVersionType;
  18. import com.fdkankan.common.exception.BusinessException;
  19. import com.fdkankan.common.util.DateExtUtil;
  20. import com.fdkankan.common.util.FileUtils;
  21. import com.fdkankan.common.util.SnowflakeIdGenerator;
  22. import com.fdkankan.model.constants.ConstantFilePath;
  23. import com.fdkankan.model.constants.UploadFilePath;
  24. import com.fdkankan.redis.constant.RedisKey;
  25. import com.fdkankan.redis.util.RedisUtil;
  26. import com.fdkankan.scene.bean.BodySegmentStatusBean;
  27. import com.fdkankan.scene.config.FdkkLaserConfig;
  28. import com.fdkankan.scene.entity.*;
  29. import com.fdkankan.scene.mapper.ISceneMapper;
  30. import com.fdkankan.scene.oss.OssUtil;
  31. import com.fdkankan.scene.service.*;
  32. import com.fdkankan.scene.util.OssBodySegmentUtil;
  33. import com.fdkankan.scene.vo.SceneParamVO;
  34. import com.fdkankan.web.response.ResultData;
  35. import lombok.extern.slf4j.Slf4j;
  36. import org.apache.commons.lang3.StringUtils;
  37. import org.springframework.beans.factory.annotation.Autowired;
  38. import org.springframework.beans.factory.annotation.Value;
  39. import org.springframework.stereotype.Service;
  40. import org.springframework.web.multipart.MultipartFile;
  41. import javax.imageio.ImageIO;
  42. import java.awt.*;
  43. import java.awt.image.BufferedImage;
  44. import java.io.File;
  45. import java.io.IOException;
  46. import java.math.BigDecimal;
  47. import java.nio.file.FileSystemException;
  48. import java.util.*;
  49. import java.util.List;
  50. import java.util.concurrent.CompletableFuture;
  51. import java.util.concurrent.ExecutorService;
  52. @Slf4j
  53. @Service("sceneService")
  54. public class SceneServiceImpl extends ServiceImpl<ISceneMapper, Scene> implements ISceneService {//extends ServiceImpl<ISceneResourceMapper, SceneResource> implements ISceneResourceService
  55. private static String cloudPointFyunPath = "testdata/%s/data/bundle_%s/building/";
  56. @Value("${queue.bodySegment:body-segment}")
  57. private String queueName;
  58. @Value("${oss.bodySegment.bucket:4dkankan-huadong}")
  59. private String bodySegmentBucket;
  60. @Value("${oss.bodySegment.point:oss-cn-shanghai.aliyuncs.com}")
  61. private String bodySegmentHost;
  62. @Autowired
  63. private OssBodySegmentUtil ossBodySegmentUtil;
  64. @Autowired
  65. private RedisUtil redisUtil;
  66. @Autowired
  67. private OssUtil ossUtil;
  68. @Autowired
  69. private IScenePlusService scenePlusService;
  70. @Autowired
  71. private IScenePlusExtService scenePlusExtService;
  72. @Autowired
  73. private ISceneEditInfoService sceneEditInfoService;
  74. @Autowired
  75. private ISceneEditInfoExtService sceneEditInfoExtService;
  76. @Autowired
  77. private ISceneEditControlsService sceneEditControlsService;
  78. @Autowired
  79. private ISurveillanceService surveillanceService;
  80. @Autowired
  81. private ISceneService sceneService;
  82. @Override
  83. public ResultData uploadBodySegment(MultipartFile file, Integer rotate) throws Exception {
  84. if(!FileUtils.checkFileSizeIsLimit(file.getSize(), 10, "M")){
  85. throw new BusinessException(ErrorCode.FAILURE_CODE_4003, "10M");
  86. }
  87. String uuid = UUID.randomUUID().toString();
  88. String fileName = file.getOriginalFilename();
  89. String extName = fileName.substring(fileName.lastIndexOf("."));
  90. File tempFile = File.createTempFile(uuid, extName);
  91. file.transferTo(tempFile);
  92. //判断是否需要旋转
  93. if(Objects.nonNull(rotate) && rotate != 0){
  94. Image rotateImg = ImgUtil.rotate(ImageIO.read(tempFile), rotate);
  95. File tempRotateFile = File.createTempFile(uuid + "-rotate", extName);
  96. ImgUtil.write(rotateImg, tempRotateFile);
  97. tempFile = tempRotateFile;
  98. }
  99. //校验像素
  100. BufferedImage bufferedImage = ImgUtil.read(tempFile.getPath());
  101. Float scale = 1F;
  102. Float widthScale = 1F;
  103. Float heightScale = 1F;
  104. int width = bufferedImage.getWidth();
  105. int height = bufferedImage.getHeight();
  106. if(width > 2000){
  107. widthScale = new BigDecimal(2000).divide(new BigDecimal(width),5, BigDecimal.ROUND_DOWN).floatValue();
  108. }
  109. if(height > 2000){
  110. heightScale = new BigDecimal(2000).divide(new BigDecimal(height),5, BigDecimal.ROUND_DOWN).floatValue();
  111. }
  112. scale = widthScale > heightScale ? heightScale : widthScale;
  113. ImgUtil.scale(new File(tempFile.getPath()), new File(tempFile.getPath()), scale);
  114. String orgImgOssPath = "body_segment/original/" + tempFile.getName();
  115. ossBodySegmentUtil.uploadOss(tempFile.getPath(), orgImgOssPath);
  116. // fYunFileService.uploadFile(bodySegmentBucket, tempFile.getPath(), orgImgOssPath);
  117. BodySegmentStatusBean bodySegmentStatusBean = BodySegmentStatusBean.builder().uuid(uuid).status(CommonOperStatus.WAITING.code()).build();
  118. redisUtil.set(String.format(RedisKey.SCENE_BODY_SEGMENT, uuid), JSON.toJSONString(bodySegmentStatusBean), RedisKey.CAMERA_EXPIRE_7_TIME);
  119. Map<String, String> map = new HashMap<>();
  120. map.put("uuid", uuid);
  121. map.put("imgUrl", "https://" + bodySegmentBucket + "." + bodySegmentHost + "/" + orgImgOssPath);
  122. // rabbitMqProducer.sendByWorkQueue(queueName, map);
  123. return ResultData.ok(uuid);
  124. }
  125. public static void main(String[] args) throws IOException {
  126. Image rotateImg = ImgUtil.rotate(ImageIO.read(new File("C:\\Users\\dsx\\Desktop\\IMG_0231.HEIC.JPG")), 0);
  127. }
  128. @Override
  129. public void bodySegmentHandler(String imgUrl, String uuid) {
  130. String progress = redisUtil.hget(RedisKey.SCENE_BODY_SEGMENT, uuid);
  131. BodySegmentStatusBean bodySegmentStatusBean = null;
  132. try {
  133. if(StrUtil.isEmpty(progress)){
  134. bodySegmentStatusBean = JSON.parseObject(progress, BodySegmentStatusBean.class);
  135. }
  136. if(Objects.isNull(bodySegmentStatusBean)){
  137. bodySegmentStatusBean = new BodySegmentStatusBean();
  138. bodySegmentStatusBean.setUuid(uuid);
  139. }
  140. String dir = ConstantFilePath.BASE_PATH + "/bodySegment/" +
  141. DateExtUtil.format(Calendar.getInstance().getTime(), DateExtUtil.dateStyle6);
  142. String fileName = uuid + ".png";
  143. String imgPath = dir + "/" + fileName;
  144. ossBodySegmentUtil.extracted(imgUrl, dir, fileName);
  145. if(!FileUtil.exist(imgPath)){
  146. throw new Exception("提取图片失败");
  147. }
  148. String targetOssImgPath = "body_segment/segment/" + uuid + ".png";
  149. // ossUtil.uploadFile(targetOssImgPath, imgPath, false);
  150. bodySegmentStatusBean.setStatus(CommonOperStatus.SUCCESS.code());
  151. // bodySegmentStatusBean.setImageUrl(fYunFileConfig.getHost() + targetOssImgPath);
  152. redisUtil.set(String.format(RedisKey.SCENE_BODY_SEGMENT, uuid), JSON.toJSONString(bodySegmentStatusBean), RedisKey.CAMERA_EXPIRE_7_TIME);
  153. } catch (Exception e) {
  154. bodySegmentStatusBean.setStatus(CommonOperStatus.FAILD.code());
  155. redisUtil.set(String.format(RedisKey.SCENE_BODY_SEGMENT, uuid), JSON.toJSONString(bodySegmentStatusBean), RedisKey.CAMERA_EXPIRE_7_TIME);
  156. }finally {
  157. try {
  158. //免费版qps不能大于2,故休眠一秒
  159. Thread.sleep(1000L);
  160. } catch (InterruptedException e) {
  161. e.printStackTrace();
  162. }
  163. }
  164. }
  165. @Override
  166. public ResultData getBodySegmentStatus(String uuid) {
  167. String progress = redisUtil.get(String.format(RedisKey.SCENE_BODY_SEGMENT, uuid));
  168. if(StrUtil.isEmpty(progress)){
  169. throw new BusinessException(ErrorCode.FAILURE_CODE_5038);
  170. }
  171. BodySegmentStatusBean bodySegmentStatusBean = JSON.parseObject(progress, BodySegmentStatusBean.class);
  172. return ResultData.ok(bodySegmentStatusBean);
  173. }
  174. @Override
  175. public void delete(SceneParamVO param) throws FileSystemException {
  176. String sceneNum = param.getSceneNum();
  177. if(StringUtils.isEmpty(sceneNum)){
  178. throw new BusinessException(ErrorCode.FAILURE_CODE_3001);
  179. }
  180. String[] nums = sceneNum.split(",");
  181. List<String> numList = Arrays.asList(nums);
  182. List<ScenePlus> plusList = scenePlusService.getListByNums(numList);
  183. scenePlusService.deleteByList(plusList, param.getReserve(), param.isReserveSource());
  184. }
  185. @Override
  186. public void copyScene(String newNum, String sceneNum, String userName, String dataSource, String bucket) throws Exception {
  187. if(StrUtil.isEmpty(newNum) || StrUtil.isEmpty(sceneNum)){
  188. throw new BusinessException(ErrorCode.FAILURE_CODE_3001);
  189. }
  190. ScenePlus scenePlus = scenePlusService.getScenePlusByNum(sceneNum);
  191. if(scenePlus== null){
  192. throw new BusinessException(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005);
  193. }
  194. String oldNum = scenePlus.getNum();
  195. Long plusId = scenePlus.getId();
  196. ScenePlusExt plusExt = scenePlusExtService.getScenePlusExtByPlusId(plusId);
  197. String oldBucket = plusExt.getYunFileBucket();
  198. String oldDataSource = plusExt.getDataSource();
  199. if(plusExt == null){
  200. throw new BusinessException(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005);
  201. }
  202. scenePlus.setNum(newNum);
  203. scenePlus.setTitle(scenePlus.getTitle() +"(copy)");
  204. scenePlus.setSceneStatus(0);
  205. scenePlus.setId(null);
  206. scenePlusService.save(scenePlus);
  207. ExecutorService executor = ThreadUtil.newSingleExecutor();
  208. // CompletableFuture.runAsync(() -> {
  209. String newVideos = plusExt.getVideos();
  210. if(StrUtil.isNotEmpty(newVideos)){
  211. newVideos = plusExt.getVideos().replaceAll("/data/data" + oldNum, "/scene_view_data/" + newNum + "/data").replaceAll(oldNum, newNum);
  212. }
  213. plusExt.setId(null);
  214. plusExt.setPlusId(scenePlus.getId());
  215. plusExt.setDataSource(dataSource);
  216. plusExt.setVideos(newVideos);
  217. plusExt.setViewCount(0);
  218. plusExt.setYunFileBucket(bucket);
  219. scenePlusExtService.save(plusExt);
  220. SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(plusId);
  221. Long sceneEditInfoId = sceneEditInfo.getId();
  222. sceneEditInfo.setId(null);
  223. sceneEditInfo.setScenePlusId(scenePlus.getId());
  224. sceneEditInfo.setSceneProId(null);
  225. sceneEditInfo.setTitle(scenePlus.getTitle());
  226. sceneEditInfoService.save(sceneEditInfo);
  227. SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByEditInfoId(sceneEditInfoId);
  228. sceneEditInfoExt.setId(null);
  229. sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId());
  230. sceneEditInfoExt.setScenePlusId(scenePlus.getId());
  231. sceneEditInfoExt.setSceneProId(null);
  232. sceneEditInfoExtService.save(sceneEditInfoExt);
  233. SceneEditControls sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfoId);
  234. sceneEditControls.setId(null);
  235. sceneEditControls.setEditInfoId(sceneEditInfo.getId());
  236. sceneEditControlsService.save(sceneEditControls);
  237. List<Surveillance> list = surveillanceService.list(new LambdaQueryWrapper<Surveillance>().eq(Surveillance::getNum, oldNum));
  238. if (!Objects.isNull(list)) {
  239. list.stream().forEach(item -> {
  240. item.setNum(newNum);
  241. item.setId(null);
  242. surveillanceService.save(item);
  243. });
  244. }
  245. try {
  246. // 拷贝场景编辑资源
  247. String oldEditPath = String.format(UploadFilePath.EDIT_PATH, oldNum);
  248. String newEditPath = String.format(UploadFilePath.EDIT_PATH, newNum);
  249. FileUtil.copyContent(new File(FdkkLaserConfig.getProfile(oldBucket) + File.separator + oldEditPath),
  250. new File(FdkkLaserConfig.getProfile(bucket) + File.separator + newEditPath), true);
  251. // 拷贝场景展示资源
  252. String oldViewPath = String.format(UploadFilePath.VIEW_PATH, oldNum);
  253. String newViewPath = String.format(UploadFilePath.VIEW_PATH, newNum);
  254. FileUtil.copyContent(new File(FdkkLaserConfig.getProfile(oldBucket) + File.separator + oldViewPath),
  255. new File(FdkkLaserConfig.getProfile(bucket) + File.separator + newViewPath), true);
  256. //复制计算目录
  257. FileUtil.copyContent(new File(oldDataSource), new File(dataSource), true);
  258. scenePlus.setSceneStatus(-2);
  259. scenePlusService.updateById(scenePlus);
  260. log.info("复制成功。。。。。");
  261. boolean success = sceneService.updateStatus(newNum,2);
  262. log.info("修改复制后的状态-*{}。。。。。",success);
  263. }catch (Exception e){
  264. log.error("复制场景失败-V4-sceneNum:{},error:{}",oldNum,e);
  265. scenePlus.setSceneStatus(-1);
  266. scenePlusService.updateById(scenePlus);
  267. boolean success = sceneService.updateStatus(newNum,1);
  268. log.info("修改复制后的状态-*{}。。。。。",success);
  269. throw new BusinessException(ErrorCode.SYSTEM_BUSY.code(),"复制失败!");
  270. }
  271. // }, executor).whenComplete((reslut, e) -> {
  272. // log.info("copy-success-");
  273. // });
  274. }
  275. @Override
  276. public Scene getBySceneCode(String sceneCode) {
  277. return this.getOne(new LambdaQueryWrapper<Scene>().eq(Scene::getSceneCode, sceneCode));
  278. }
  279. @Override
  280. public String getDataSource(String num, Integer sceneSource, String dataSource) {
  281. if(StrUtil.isEmpty(dataSource)){
  282. Scene scene = this.getBySceneCode(num);
  283. dataSource = scene.getPath();
  284. }
  285. if( dataSource.contains("web_laserData")){//D:\4DMega\4DKK_PROGRAM_DATA\dvt600001_202206291618176080\web_laserData\laserData
  286. dataSource = dataSource.substring(0, dataSource.indexOf("web_laserData"));
  287. }else{
  288. dataSource = dataSource.concat(File.separator);
  289. }
  290. return dataSource;
  291. }
  292. @Override
  293. public boolean updateStatus(String sceneCode, Integer status) {
  294. LambdaUpdateWrapper<Scene> wrapper = Wrappers.lambdaUpdate();
  295. wrapper.eq(Scene::getSceneCode, sceneCode);
  296. wrapper.set(Scene::getStatus, status);
  297. return update(wrapper);
  298. }
  299. }