SceneServiceImpl.java 15 KB

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