فهرست منبع

Merge branch 'project-jp' into project-xiaoan

# Conflicts:
#	src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java
#	src/main/java/com/fdkankan/scene/service/impl/ScenePlusServiceImpl.java
#	src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java
#	src/main/java/com/fdkankan/scene/service/impl/SceneServiceImpl.java
dsx 2 سال پیش
والد
کامیت
140c2c1ed6
63فایلهای تغییر یافته به همراه2641 افزوده شده و 466 حذف شده
  1. 6 0
      pom.xml
  2. 43 31
      src/main/java/com/fdkankan/scene/Interceptor/CheckPermitAspect.java
  3. 22 0
      src/main/java/com/fdkankan/scene/bean/BodySegmentStatusBean.java
  4. 7 8
      src/main/java/com/fdkankan/scene/bean/SceneJsonBean.java
  5. 21 0
      src/main/java/com/fdkankan/scene/controller/RoleController.java
  6. 21 0
      src/main/java/com/fdkankan/scene/controller/SceneAsynOperLogController.java
  7. 29 6
      src/main/java/com/fdkankan/scene/controller/SceneController.java
  8. 30 1
      src/main/java/com/fdkankan/scene/controller/SceneEditController.java
  9. 150 0
      src/main/java/com/fdkankan/scene/controller/SceneMarkShapeController.java
  10. 4 3
      src/main/java/com/fdkankan/scene/controller/TestController.java
  11. 21 0
      src/main/java/com/fdkankan/scene/controller/UserRoleController.java
  12. 4 4
      src/main/java/com/fdkankan/scene/entity/Company.java
  13. 72 0
      src/main/java/com/fdkankan/scene/entity/Role.java
  14. 105 0
      src/main/java/com/fdkankan/scene/entity/SceneAsynOperLog.java
  15. 26 0
      src/main/java/com/fdkankan/scene/entity/SceneEditControls.java
  16. 74 0
      src/main/java/com/fdkankan/scene/entity/SceneMarkShape.java
  17. 6 0
      src/main/java/com/fdkankan/scene/entity/ScenePlus.java
  18. 6 0
      src/main/java/com/fdkankan/scene/entity/ScenePlusExt.java
  19. 6 0
      src/main/java/com/fdkankan/scene/entity/User.java
  20. 63 0
      src/main/java/com/fdkankan/scene/entity/UserRole.java
  21. 3 3
      src/main/java/com/fdkankan/scene/generate/AutoGenerate.java
  22. 33 0
      src/main/java/com/fdkankan/scene/httpclient/MyClient.java
  23. 26 5
      src/main/java/com/fdkankan/scene/listener/RabbitMqListener.java
  24. 18 0
      src/main/java/com/fdkankan/scene/mapper/IRoleMapper.java
  25. 18 0
      src/main/java/com/fdkankan/scene/mapper/ISceneAsynOperLogMapper.java
  26. 18 0
      src/main/java/com/fdkankan/scene/mapper/IUserRoleMapper.java
  27. 16 0
      src/main/java/com/fdkankan/scene/mapper/MarkShapeMapper.java
  28. 27 0
      src/main/java/com/fdkankan/scene/schedule/ScheduleJob.java
  29. 16 0
      src/main/java/com/fdkankan/scene/service/IRoleService.java
  30. 24 0
      src/main/java/com/fdkankan/scene/service/ISceneAsynOperLogService.java
  31. 2 1
      src/main/java/com/fdkankan/scene/service/ISceneEditInfoService.java
  32. 2 0
      src/main/java/com/fdkankan/scene/service/ISceneEditService.java
  33. 30 0
      src/main/java/com/fdkankan/scene/service/ISceneMarkShapeService.java
  34. 16 0
      src/main/java/com/fdkankan/scene/service/ISceneService.java
  35. 16 0
      src/main/java/com/fdkankan/scene/service/IUserRoleService.java
  36. 20 0
      src/main/java/com/fdkankan/scene/service/impl/RoleServiceImpl.java
  37. 118 0
      src/main/java/com/fdkankan/scene/service/impl/SceneAsynOperLogServiceImpl.java
  38. 285 109
      src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java
  39. 23 105
      src/main/java/com/fdkankan/scene/service/impl/SceneEditServiceImpl.java
  40. 181 0
      src/main/java/com/fdkankan/scene/service/impl/SceneMarkShapeServiceImpl.java
  41. 2 2
      src/main/java/com/fdkankan/scene/service/impl/ScenePlusServiceImpl.java
  42. 252 138
      src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java
  43. 169 0
      src/main/java/com/fdkankan/scene/service/impl/SceneServiceImpl.java
  44. 20 0
      src/main/java/com/fdkankan/scene/service/impl/UserRoleServiceImpl.java
  45. 121 0
      src/main/java/com/fdkankan/scene/util/ConverxyUtil.java
  46. 98 0
      src/main/java/com/fdkankan/scene/util/OssBodySegmentUtil.java
  47. 97 0
      src/main/java/com/fdkankan/scene/util/test.java
  48. 20 0
      src/main/java/com/fdkankan/scene/vo/SaveFiltersParamVO.java
  49. 35 0
      src/main/java/com/fdkankan/scene/vo/SceneAsynOperLogParamVO.java
  50. 24 0
      src/main/java/com/fdkankan/scene/vo/SceneEditControlsParamVO.java
  51. 21 0
      src/main/java/com/fdkankan/scene/vo/SceneEditControlsVO.java
  52. 11 0
      src/main/java/com/fdkankan/scene/vo/SceneInfoVO.java
  53. 39 0
      src/main/java/com/fdkankan/scene/vo/SceneMarkShapeDetectParamVO.java
  54. 36 0
      src/main/java/com/fdkankan/scene/vo/SceneMarkShapeParamVO.java
  55. 46 0
      src/main/java/com/fdkankan/scene/vo/SceneMarkShapeReDetectParamVO.java
  56. 2 0
      src/main/java/com/fdkankan/scene/vo/UploadPanoramaVO.java
  57. 13 50
      src/main/resources/bootstrap-prod-eur.yml
  58. 4 0
      src/main/resources/bootstrap-prod.yml
  59. 4 0
      src/main/resources/bootstrap-test-eur.yml
  60. 4 0
      src/main/resources/bootstrap-test.yml
  61. 5 0
      src/main/resources/mapper/scene/RoleMapper.xml
  62. 5 0
      src/main/resources/mapper/scene/SceneAsynOperLogMapper.xml
  63. 5 0
      src/main/resources/mapper/scene/UserRoleMapper.xml

+ 6 - 0
pom.xml

@@ -146,6 +146,12 @@
             <version>6.8.1</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>imageseg20191230</artifactId>
+            <version>1.0.5</version>
+        </dependency>
+
     </dependencies>
 
     <dependencyManagement>

+ 43 - 31
src/main/java/com/fdkankan/scene/Interceptor/CheckPermitAspect.java

@@ -1,21 +1,24 @@
 package com.fdkankan.scene.Interceptor;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fdkankan.common.constant.CommonStatus;
 import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.common.constant.SceneStatus;
 import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.util.RedisUtil;
-import com.fdkankan.scene.entity.SceneCooperation;
-import com.fdkankan.scene.entity.ScenePlus;
-import com.fdkankan.scene.service.ISceneCooperationService;
-import com.fdkankan.scene.service.IScenePlusService;
+import com.fdkankan.scene.entity.*;
+import com.fdkankan.scene.service.*;
 import com.fdkankan.web.user.SSOLoginHelper;
 import com.fdkankan.web.user.SSOUser;
 import com.fdkankan.web.util.WebUtil;
 import java.io.IOException;
+import java.util.List;
 import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
 import javax.servlet.http.HttpServletRequest;
 import lombok.extern.log4j.Log4j2;
 import org.aspectj.lang.JoinPoint;
@@ -42,6 +45,14 @@ public class CheckPermitAspect {
 	private IScenePlusService scenePlusService;
 	@Autowired
 	private ISceneCooperationService sceneCooperationService;
+	@Autowired
+	private IRoleService roleService;
+	@Autowired
+	private IUserRoleService userRoleService;
+	@Autowired
+	private IUserService userService;
+	@Autowired
+	private ICameraDetailService cameraDetailService;
 
 
 	@Pointcut("@annotation(com.fdkankan.scene.annotation.CheckPermit)")
@@ -68,48 +79,49 @@ public class CheckPermitAspect {
 			throw new BusinessException(ErrorCode.PARAM_REQUIRED);
 		}
 
-        ScenePlus scenePlus= scenePlusService.getScenePlusByNum(num);
+		ScenePlus scenePlus= scenePlusService.getScenePlusByNum(num);
 		if(Objects.isNull(scenePlus)){
 			throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
 		}
 		//如果是计算中或者计算出错,返回计算中
 		if(SceneStatus.wait.code().equals(scenePlus.getSceneStatus())
-			|| SceneStatus.FAILD.code().equals(scenePlus.getSceneStatus())){
+				|| SceneStatus.FAILD.code().equals(scenePlus.getSceneStatus())){
 			throw new BusinessException(ErrorCode.FAILURE_CODE_5033);
 		}
 
-		//判断是否相机登录,是否场景的相机id和相机登录的相机id是否相等,如果都满足,则放行,否则判定为用户登录
-		if(Objects.nonNull(user.getCameraLogin())
-			&& CommonStatus.YES.code().byteValue() == user.getCameraLogin().intValue()){
-			if(scenePlus.getCameraId().equals(user.getCameraId())){
-				return;
-			}else{
-				throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
-			}
+		//如果上面场景用户与当前用户不匹配,需要校验当前用户是否拥有某些角色,从而可以访问此场景
+		List<UserRole> list = userRoleService.list(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, user.getId()));
+		Set<Long> roleIdSet = null;
+		if(CollUtil.isNotEmpty(list)){
+			roleIdSet = list.stream().map(ur -> ur.getRoleId()).collect(Collectors.toSet());
 		}
-
-		//走到这里代表是用户账号密码登录,如果查到的场景的userid是空,证明相机解绑了,需要返回无权操作
-		if(Objects.isNull(scenePlus.getUserId())){
+		if(CollUtil.isEmpty(roleIdSet)){
 			throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
 		}
+		//平台管理员拥有最高权限
+		if(roleIdSet.contains(5L)){
+			return;
+		}
 
-        if(scenePlus.getUserId().equals(user.getId())){
-            return;
-        }
+		//判断是否有公司管理者权限,有则放开
+		if(roleIdSet.contains(6L)){
+			//当前登录用户user
+			User currentUser = userService.getById(user.getId());
+			CameraDetail cameraDetail = cameraDetailService.findByCameraId(scenePlus.getCameraId());
+			if(Objects.isNull(currentUser) || Objects.isNull(currentUser.getCompanyId())
+					|| Objects.isNull(cameraDetail) || Objects.isNull(cameraDetail.getCompanyId())
+					|| !currentUser.getCompanyId().equals(cameraDetail.getCompanyId())){
+				throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
+			}else{
+				return;
+			}
+		}
 
-        //如果不是用户自己的场景,判断是否有协作权限
-        Long userId = null;
-		SceneCooperation sceneCooperation = sceneCooperationService.getByNum(num);
-		if(Objects.nonNull(sceneCooperation)){
-			userId = sceneCooperation.getUserId();
+		//校验场景用户是否与当前登录用户相同,相同则跳出
+		if(Objects.isNull(scenePlus.getUserId()) || !scenePlus.getUserId().equals(user.getId())){
+			throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
 		}
 
-		if(Objects.isNull(userId)){
-            throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
-        }
-        if(!userId.equals(user.getId())){
-            throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
-        }
 	}
 
 }

+ 22 - 0
src/main/java/com/fdkankan/scene/bean/BodySegmentStatusBean.java

@@ -0,0 +1,22 @@
+package com.fdkankan.scene.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BodySegmentStatusBean {
+
+    private String uuid;
+
+    private Integer status;
+
+    private String imageUrl;
+
+
+
+}

+ 7 - 8
src/main/java/com/fdkankan/scene/bean/SceneJsonBean.java

@@ -3,14 +3,13 @@ package com.fdkankan.scene.bean;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.scene.vo.SceneEditControlsVO;
+import java.util.Date;
+import java.util.List;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-import java.util.Date;
-import java.util.List;
-
 /**
  * <p>
  * scene.json实体类
@@ -92,11 +91,6 @@ public class SceneJsonBean {
      */
     private Integer linkVersion;
 
-//    /**
-//     * 户型图文件路径集合
-//     */
-//    private String[] floorPlanPaths;
-
     /**
      * 是否上传了户型图(0-否,1-是)
      */
@@ -123,6 +117,11 @@ public class SceneJsonBean {
     private String sceneKind;
 
     /**
+     * 算法模型类型(dam,3dtiles)
+     */
+    private String modelKind;
+
+    /**
      * 空间视频数据
      */
     private String boxVideos;

+ 21 - 0
src/main/java/com/fdkankan/scene/controller/RoleController.java

@@ -0,0 +1,21 @@
+package com.fdkankan.scene.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 角色表 前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2023-01-03
+ */
+@RestController
+@RequestMapping("/scene/role")
+public class RoleController {
+
+}
+

+ 21 - 0
src/main/java/com/fdkankan/scene/controller/SceneAsynOperLogController.java

@@ -0,0 +1,21 @@
+package com.fdkankan.scene.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2022-12-07
+ */
+@RestController
+@RequestMapping("/scene/sceneAsynOperLog")
+public class SceneAsynOperLogController {
+
+}
+

+ 29 - 6
src/main/java/com/fdkankan/scene/controller/SceneController.java

@@ -2,6 +2,8 @@ package com.fdkankan.scene.controller;
 
 
 import com.fdkankan.common.constant.SceneInfoReqType;
+import com.fdkankan.scene.annotation.CheckPermit;
+import com.fdkankan.scene.service.ISceneService;
 import com.fdkankan.web.response.ResultData;
 import com.fdkankan.scene.service.ISceneEditInfoService;
 import com.fdkankan.scene.service.IScenePlusService;
@@ -12,11 +14,8 @@ import com.fdkankan.scene.vo.SceneInfoVO;
 import com.fdkankan.web.controller.BaseController;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * <p>
@@ -34,6 +33,8 @@ public class SceneController extends BaseController {
     private ISceneEditInfoService sceneEditInfoService;
     @Autowired
     private IScenePlusService scenePlusService;
+    @Autowired
+    private ISceneService sceneService;
 
     /**
      * <p>
@@ -70,7 +71,6 @@ public class SceneController extends BaseController {
      * </p>
      * @author dengsixing
      * @date 2022/8/1
-     * @param param
      * @return com.fdkankan.web.response.ResultData
      **/
     @GetMapping(value = "/downLoadZSData")
@@ -78,5 +78,28 @@ public class SceneController extends BaseController {
         return scenePlusService.downLoadZSData(sceneNum);
     }
 
+    /**
+     * 上传人体抠图原图
+     * @param num
+     * @param file
+     * @return
+     * @throws Exception
+     */
+    @PostMapping(value = "/uploadBodySegment")
+    public ResultData uploadBodySegment(@RequestParam("file") MultipartFile file,
+                                        @RequestParam(value = "rotate", required = false) Integer rotate) throws Exception {
+        return sceneService.uploadBodySegment(file, rotate);
+    }
+
+    /**
+     * 获取人体抠图提取状态
+     * @return ResultData
+     * @throws Exception
+     */
+    @PostMapping(value = "/getBodySegmentStatus")
+    public ResultData getBodySegmentStatus(@RequestParam(value = "serialNum") String uuid) throws Exception {
+        return sceneService.getBodySegmentStatus(uuid);
+    }
+
 }
 

+ 30 - 1
src/main/java/com/fdkankan/scene/controller/SceneEditController.java

@@ -5,8 +5,10 @@ import com.fdkankan.common.constant.SceneInfoReqType;
 import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.model.utils.CreateHouseJsonUtil;
 import com.fdkankan.scene.annotation.CheckPermit;
+import com.fdkankan.scene.entity.SceneAsynOperLog;
 import com.fdkankan.scene.service.IBoxModelService;
 import com.fdkankan.scene.service.IDownloadTourVideoService;
+import com.fdkankan.scene.service.ISceneAsynOperLogService;
 import com.fdkankan.scene.service.ISceneEditInfoService;
 import com.fdkankan.scene.service.ISceneEditService;
 import com.fdkankan.scene.service.IScenePlusService;
@@ -31,9 +33,11 @@ import com.fdkankan.scene.vo.FileNameAndDataParamVO;
 import com.fdkankan.scene.vo.FileParamVO;
 import com.fdkankan.scene.vo.LocalesParamVO;
 import com.fdkankan.scene.vo.RenameCadParamVO;
+import com.fdkankan.scene.vo.SaveFiltersParamVO;
 import com.fdkankan.scene.vo.SaveLinkPanParamVO;
 import com.fdkankan.scene.vo.SaveTagsParamVO;
 import com.fdkankan.scene.vo.SaveTagsVisibleParamVO;
+import com.fdkankan.scene.vo.SceneAsynOperLogParamVO;
 import com.fdkankan.scene.vo.SceneAuthVO;
 import com.fdkankan.scene.vo.SceneEditInfoParamVO;
 import com.fdkankan.scene.vo.SceneEditInfoVO;
@@ -84,6 +88,8 @@ public class SceneEditController extends BaseController {
     private IBoxModelService boxModelService;
     @Autowired
     private IScenePlusService scenePlusService;
+    @Autowired
+    private ISceneAsynOperLogService sceneAsynOperLogService;
 
     /**
      * <p>
@@ -755,7 +761,7 @@ public class SceneEditController extends BaseController {
      */
     @CheckPermit
     @PostMapping(value = "/filter/save")
-    public ResultData saveFilter(@RequestBody @Validated BaseDataParamVO param) throws Exception{
+    public ResultData saveFilter(@RequestBody @Validated SaveFiltersParamVO param) throws Exception{
         return sceneEditInfoService.saveFilter(param);
     }
 
@@ -857,5 +863,28 @@ public class SceneEditController extends BaseController {
         return scenePlusService.uploadShareLogo(num, file);
     }
 
+    /**
+     * <p>
+     删除空间模型
+     * </p>
+     * @author dengsixing
+     * @date 2022/10/19
+     * @param param
+     * @return com.fdkankan.common.response.ResultData
+     **/
+    @CheckPermit
+    @PostMapping("/getAsynOperLog")
+    public ResultData getAsynOperLog(@RequestBody @Validated SceneAsynOperLogParamVO param){
+        return sceneAsynOperLogService.getAsynOperLog(param);
+    }
+
+    /**
+     * 获取编辑器版本信息
+     * @return
+     */
+    @GetMapping("/getServiceUpTip")
+    public ResultData getServiceUpTip(){
+        return sceneEditService.getServiceUpTip();
+    }
 
 }

+ 150 - 0
src/main/java/com/fdkankan/scene/controller/SceneMarkShapeController.java

@@ -0,0 +1,150 @@
+package com.fdkankan.scene.controller;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import com.fdkankan.scene.entity.SceneMarkShape;
+import com.fdkankan.scene.entity.ScenePlus;
+import com.fdkankan.scene.entity.ScenePlusExt;
+import com.fdkankan.scene.service.ISceneMarkShapeService;
+import com.fdkankan.scene.service.IScenePlusExtService;
+import com.fdkankan.scene.service.IScenePlusService;
+import com.fdkankan.scene.vo.SceneMarkShapeDetectParamVO;
+import com.fdkankan.scene.vo.SceneMarkShapeParamVO;
+import com.fdkankan.scene.vo.SceneMarkShapeReDetectParamVO;
+import com.fdkankan.web.controller.BaseController;
+import com.fdkankan.web.response.ResultData;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 初始化接口
+ *
+ * @author fdkk
+ */
+@RestController
+@RequestMapping("/service/scene/sceneMarkShape")
+@Slf4j
+public class SceneMarkShapeController extends BaseController
+{
+    @Value("${queue.scene.yolov5-detect-queue}")
+    private String yolov5DetectQueue;
+    @Autowired
+    private ISceneMarkShapeService sceneMarkShapeService;
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+    @Value("${fyun.host}")
+    private String ossUrlPrefix;
+    @Autowired
+    private RabbitMqProducer rabbitMqProducer;
+    @Value("${main.url}")
+    private String mainUrl;
+
+
+    /**
+     * 获取场景全景图路径连接
+     */
+    @PostMapping("/getPanorama")
+    public ResultData getPanorama(@RequestBody @Validated  SceneMarkShapeParamVO param) {
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
+        if(ObjectUtil.isNotNull(scenePlus)) {
+            ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+            if (ObjectUtil.isNotNull(scenePlus)) {
+                String publicUserPath = String.format(UploadFilePath.scene_result_data_path, param.getNum());
+                List<String> panoramaList = fYunFileService.listRemoteFiles(scenePlusExt.getYunFileBucket(), publicUserPath + "caches/images/");
+                List<String> panoramaListUrl = panoramaList.stream().filter(f -> FileUtil.extName(f).equals("jpg")).map(s -> ossUrlPrefix + s).collect(Collectors.toList());
+                return ResultData.ok(panoramaListUrl);
+            }
+        }
+        return ResultData.ok("场景数据不存在");
+    }
+    /**
+     * 根据场景码和图片名称获取数据
+     */
+    @PostMapping("/getInfo")
+    public ResultData getInfo(@RequestBody @Validated  SceneMarkShapeParamVO param) {
+        SceneMarkShape res=  sceneMarkShapeService.findByNumAndImagePath(param.getNum(),param.getImagePath());
+        return ResultData.ok(res);
+    }
+    /**
+     * 将需要推理的场景推入到队列
+     */
+    @PostMapping("/detectScene")
+    public ResultData detect(@RequestBody @Validated SceneMarkShapeDetectParamVO param) {
+        param.setWebSite(mainUrl);
+        rabbitMqProducer.sendByWorkQueue(yolov5DetectQueue, param);
+        return ResultData.ok();
+    }
+    /**
+     * 将需要训练的场景推入到队列
+     */
+    @PostMapping("/trainScene")
+    public ResultData trainScene(@RequestBody @Validated SceneMarkShapeReDetectParamVO param) {
+        sceneMarkShapeService.trainScene(param);
+        return ResultData.ok();
+    }
+    /**
+     * 将需要重新推理的场景推入到队列
+     */
+    @PostMapping("/editReDetectStatus")
+    public ResultData editReDetectStatus(@RequestBody @Validated SceneMarkShapeParamVO param) {
+        sceneMarkShapeService.editTrainStatus(param);
+        return ResultData.ok();
+    }
+    /**
+     * 保存或者修改
+     */
+    @PostMapping("/saveOrEdit")
+    public ResultData save(@RequestParam(value = "num") String num,@RequestParam("file") MultipartFile file) throws IOException {
+        sceneMarkShapeService.saveFileToDB(file,num);
+        return ResultData.ok();
+    }
+    /**
+     * 保存或者修改JSON
+     */
+    @PostMapping("/saveOrEditJson")
+    public ResultData saveOrEditJson(@RequestBody SceneMarkShape param) {
+        SceneMarkShape shape = sceneMarkShapeService.findByNumAndImagePath(param.getNum(), param.getImagePath());
+        if (ObjectUtil.isNotNull(shape)){
+            param.setId(shape.getId());
+            param.setUpdateTime(new Date());
+            return ResultData.ok(sceneMarkShapeService.updateById(param));
+        }else {
+            param.setCreateTime(new Date());
+            return ResultData.ok(sceneMarkShapeService.save(param));
+        }
+    }
+    /**
+     * 保存或者修改JSON
+     */
+    @PostMapping("/editLabel")
+    public ResultData editLabel(@RequestParam(value = "num") String num,@RequestParam(value = "imgPath") String imgPath,@RequestParam("file") MultipartFile file) throws IOException {
+        log.info("进入editLabel---num{},imgPath{}",num,imgPath);
+        return sceneMarkShapeService.editLabelByFile(num, imgPath, file);
+    }
+    /**
+     * 保存或者修改JSON
+     */
+    @PostMapping("/testquery")
+    public ResultData testquery()   {
+        Map<String, List<SceneMarkShape>> res=new HashMap<>();
+        res.put("findByReTrainStatus",sceneMarkShapeService.findByReTrainStatus(1));
+        res.put("findByToTrainStatus",sceneMarkShapeService.findByToTrainStatus(0));
+        return ResultData.ok(res);
+    }
+}

+ 4 - 3
src/main/java/com/fdkankan/scene/controller/TestController.java

@@ -1,5 +1,6 @@
 package com.fdkankan.scene.controller;
 
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import com.fdkankan.web.response.ResultData;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -21,12 +22,12 @@ public class TestController {
 
     @Autowired
     private RabbitMqProducer rabbitMqProducer;
+    @Autowired
+    private FYunFileServiceInterface fYunFileService;
 
     @GetMapping("/test")
     public ResultData test(){
-        for (int i = 0; i < 100; i++){
-            rabbitMqProducer.sendByWorkQueue("test_dsx", "{\"name\":123}");
-        }
+        fYunFileService.deleteFolder("testUp");
         return ResultData.ok();
     }
 

+ 21 - 0
src/main/java/com/fdkankan/scene/controller/UserRoleController.java

@@ -0,0 +1,21 @@
+package com.fdkankan.scene.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 用户角色关系表 前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2023-01-03
+ */
+@RestController
+@RequestMapping("/scene/userRole")
+public class UserRoleController {
+
+}
+

+ 4 - 4
src/main/java/com/fdkankan/scene/entity/Company.java

@@ -89,8 +89,8 @@ public class Company implements Serializable {
     @TableLogic(value = "A", delval = "I")
     private String recStatus;
 
-    @TableField("calculate_flexibility")
-    private Boolean calculateFlexibility;
+//    @TableField("calculate_flexibility")
+//    private Boolean calculateFlexibility;
 
     /**
      * 数据同步类型
@@ -98,8 +98,8 @@ public class Company implements Serializable {
     @TableField("data_sync")
     private String dataSync;
 
-    @TableField("company_desc")
-    private String companyDesc;
+//    @TableField("company_desc")
+//    private String companyDesc;
 
 
 }

+ 72 - 0
src/main/java/com/fdkankan/scene/entity/Role.java

@@ -0,0 +1,72 @@
+package com.fdkankan.scene.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 角色表
+ * </p>
+ *
+ * @author 
+ * @since 2023-01-03
+ */
+@Getter
+@Setter
+@TableName("t_role")
+public class Role implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 角色描述
+     */
+    @TableField("role_desc")
+    private String roleDesc;
+
+    /**
+     * 角色名
+     */
+    @TableField("role_name")
+    private String roleName;
+
+    /**
+     * 角色key
+     */
+    @TableField("role_key")
+    private String roleKey;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * 记录的状态,A: 生效,I: 禁用
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+
+}

+ 105 - 0
src/main/java/com/fdkankan/scene/entity/SceneAsynOperLog.java

@@ -0,0 +1,105 @@
+package com.fdkankan.scene.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author 
+ * @since 2022-12-07
+ */
+@Getter
+@Setter
+@TableName("t_scene_asyn_oper_log")
+public class SceneAsynOperLog implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 场景码
+     */
+    @TableField("num")
+    private String num;
+
+    /**
+     * 操作类型(upload-上传,download-下载)
+     */
+    @TableField("oper_type")
+    private String operType;
+
+    /**
+     * 模块名称
+     */
+    @TableField("module")
+    private String module;
+
+    /**
+     * 功能
+     */
+    @TableField("func")
+    private String func;
+
+    /**
+     * 版本号
+     */
+    @TableField("version")
+    private Integer version;
+
+    /**
+     * 状态(0-处理中,1-处理完成,2-处理失败)
+     */
+    @TableField("state")
+    private Integer state;
+
+    /**
+     * 下载链接
+     */
+    @TableField("url")
+    private String url;
+
+    /**
+     * 是否需要弹窗(0-否,1-是)
+     */
+    @TableField("pop")
+    private Integer pop;
+
+    /**
+     * 扩展信息
+     */
+    @TableField("ext_data")
+    private String extData;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * 状态(A-有效,I-无效)
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+
+}

+ 26 - 0
src/main/java/com/fdkankan/scene/entity/SceneEditControls.java

@@ -88,6 +88,32 @@ public class SceneEditControls implements Serializable {
     @TableField("show_rule")
     private Integer showRule;
 
+
+    /**
+     * 是否展示标尺(0-不需要,1-需要)
+     */
+    @TableField("show_scale")
+    private Integer showScale;
+
+    /**
+     * 是否展示分享场景(0-不需要,1-需要)
+     */
+    @TableField("show_share")
+    private Integer showShare;
+
+    /**
+     * 是否展示分享热点(0-不需要,1-需要)
+     */
+    @TableField("show_tagshare")
+    private Integer showTagshare;
+
+    /**
+     * 是否展示合照开关(0-不需要,1-需要)
+     */
+    @TableField("show_capture")
+    private Integer showCapture;
+
+
     /**
      * 创建时间
      */

+ 74 - 0
src/main/java/com/fdkankan/scene/entity/SceneMarkShape.java

@@ -0,0 +1,74 @@
+package com.fdkankan.scene.entity;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * 场景标记多边形识别数据
+ * </p>
+ *
+ * @author Xiewj
+ * @date 2023/3/30
+ */
+@Data
+@TableName(value = "t_scene_mark_shape",autoResultMap = true)
+@Accessors(chain = true)
+public class SceneMarkShape implements Serializable {
+
+      /**
+       * 主键
+       */
+      @TableId(value = "id", type = IdType.AUTO)
+      private Long id;
+
+      @TableField("version")
+      private String version;
+      @TableField(typeHandler = FastjsonTypeHandler.class, value = "flag")
+      private JSONObject flag;
+
+      @TableField(typeHandler = FastjsonTypeHandler.class, value = "shapes")
+      private List<JSONObject> shapes;
+
+      @TableField("image_path")
+      private String imagePath;
+      @TableField("image_height")
+      private Integer imageHeight;
+      @TableField("image_width")
+      private Integer imageWidth;
+      @TableField("num")
+      private String num;
+      /**
+       * 0不需要 1需要
+       */
+      @TableField("re_train")
+      private Integer reTrain;
+      /**
+       * 0需要训练 1已经训练过
+       */
+      @TableField("to_train")
+      private Integer toTrain;
+
+      @TableField("create_time")
+      private Date createTime;
+
+      @TableField("update_time")
+      private Date updateTime;
+
+      /**
+       * 记录的状态,A: 生效,I: 禁用
+       */
+      @TableField("rec_status")
+      @TableLogic(value = "A", delval = "I")
+      private String recStatus;
+
+}

+ 6 - 0
src/main/java/com/fdkankan/scene/entity/ScenePlus.java

@@ -95,6 +95,12 @@ public class ScenePlus implements Serializable {
     private Integer recommend;
 
     /**
+     * 是否有housetype文件(0-否,1-是)
+     */
+    @TableField("house_type")
+    private Integer houseType;
+
+    /**
      * 创建时间
      */
     @TableField("create_time")

+ 6 - 0
src/main/java/com/fdkankan/scene/entity/ScenePlusExt.java

@@ -125,6 +125,12 @@ public class ScenePlusExt implements Serializable {
     private String sceneKind;
 
     /**
+     * 算法模型类型(dam,3dtiles)
+     */
+    @TableField("model_kind")
+    private String modelKind;
+
+    /**
      * 算法计算完成时间
      */
     @TableField("algorithm_time")

+ 6 - 0
src/main/java/com/fdkankan/scene/entity/User.java

@@ -137,5 +137,11 @@ public class User implements Serializable {
     @TableField("update_time")
     private Date updateTime;
 
+    /**
+     * 公司id
+     */
+    @TableField("company_id")
+    private Long companyId;
+
 
 }

+ 63 - 0
src/main/java/com/fdkankan/scene/entity/UserRole.java

@@ -0,0 +1,63 @@
+package com.fdkankan.scene.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 用户角色关系表
+ * </p>
+ *
+ * @author 
+ * @since 2023-01-03
+ */
+@Getter
+@Setter
+@TableName("t_user_role")
+public class UserRole implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 用户表id
+     */
+    @TableField("user_id")
+    private Long userId;
+
+    /**
+     * 角色表id
+     */
+    @TableField("role_id")
+    private Long roleId;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 记录的状态,A: 生效,I: 禁用
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+    /**
+     * 更新时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+
+}

+ 3 - 3
src/main/java/com/fdkankan/scene/generate/AutoGenerate.java

@@ -18,7 +18,7 @@ public class AutoGenerate {
         String path =System.getProperty("user.dir");
 
         generate(path,"scene", getTables(new String[]{
-                "t_scene_clean"
+                "t_user_role","t_role"
         }));
 
 //        generate(path,"goods", getTables(new String[]{
@@ -46,8 +46,8 @@ public class AutoGenerate {
 
 
     public static void  generate(String path,String moduleName,  List<String> tables){
-        FastAutoGenerator.create("jdbc:mysql://rm-wz90w10465iiwwv098o.mysql.rds.aliyuncs.com/4dkankan_v4",
-            "root","D2719bd0cae1a005")
+        FastAutoGenerator.create("jdbc:mysql://120.77.76.141:13306/4dkankan_v4",
+            "root","JK20220120%JIK")
                 .globalConfig(builder -> {
                     builder.author("")               //作者
                             .outputDir(path+"\\src\\main\\java")    //输出路径(写到java目录)

+ 33 - 0
src/main/java/com/fdkankan/scene/httpclient/MyClient.java

@@ -0,0 +1,33 @@
+package com.fdkankan.scene.httpclient;
+
+
+import com.dtflys.forest.annotation.Get;
+import com.dtflys.forest.annotation.Var;
+import com.dtflys.forest.callback.OnProgress;
+import com.dtflys.forest.extensions.DownloadFile;
+import com.fdkankan.web.response.ResultData;
+
+import java.io.File;
+
+public interface MyClient {
+
+    /**
+     * 在方法上加上@DownloadFile注解
+     * dir属性表示文件下载到哪个目录
+     * filename属性表示文件下载成功后以什么名字保存,如果不填,这默认从URL中取得文件名
+     * OnProgress参数为监听上传进度的回调函数
+     */
+    @Get(url = "{url}")
+    @DownloadFile(dir = "{dir}", filename = "{filename}")
+    File downloadFile(@Var("url") String url, @Var("dir") String dir, @Var("filename")String filename);
+
+    /**
+     * 在方法上加上@DownloadFile注解
+     * dir属性表示文件下载到哪个目录
+     * filename属性表示文件下载成功后以什么名字保存,如果不填,这默认从URL中取得文件名
+     * OnProgress参数为监听上传进度的回调函数
+     */
+    @Get(url = "${url}?${params}")
+    ResultData get(@Var("url") String url, @Var("params") String params);
+
+}

+ 26 - 5
src/main/java/com/fdkankan/scene/listener/RabbitMqListener.java

@@ -1,8 +1,10 @@
 package com.fdkankan.scene.listener;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.scene.entity.DownloadTourVideo;
 import com.fdkankan.scene.service.IDownloadTourVideoService;
+import com.fdkankan.scene.service.ISceneService;
 import com.rabbitmq.client.Channel;
 import java.nio.charset.StandardCharsets;
 import lombok.extern.slf4j.Slf4j;
@@ -28,11 +30,13 @@ public class RabbitMqListener {
     @Value("${queue.scene.transfer-tour-video}")
     private String downloadTourVideoQueue;
 
+    @Value("${queue.bodySegment:body-segment}")
+    private String bodySegmentQueueName;
+
     @Autowired
     private IDownloadTourVideoService downloadTourVideoService;
-
-
-
+    @Autowired
+    private ISceneService sceneService;
 
     /**
      * 开启了手动确认模式,如果没有手动确认,消费者不会重试,当服务重启时会再次消费,因为rabbitmq认为你还没有处理完你的业务
@@ -59,6 +63,25 @@ public class RabbitMqListener {
      * concurrency = "3"    设置消费线程数,每个线程每次只拉取一条消息消费
      */
     @RabbitListener(
+            queuesToDeclare = @Queue("${queue.bodySegment}"),
+            concurrency = "${maxThread.bodySegment}"
+    )
+    public void bodySegment(Channel channel, Message message) throws Exception {
+        String messageId = message.getMessageProperties().getMessageId();
+        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+        log.info("开始消费消息,id:{},queue:{},content:{}", messageId, bodySegmentQueueName, msg);
+        JSONObject jsonObject = JSON.parseObject(msg);
+        sceneService.bodySegmentHandler(jsonObject.getString("imgUrl"), jsonObject.getString("uuid"));
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+        log.info("结束消费消息,id:{}", messageId);
+    }
+
+    /**
+     * 开启了手动确认模式,如果没有手动确认,消费者不会重试,当服务重启时会再次消费,因为rabbitmq认为你还没有处理完你的业务
+     * queuesToDeclare = @Queue("${queue.modeling.modeling-test}"),  如果队列不不存在会自动创建队列
+     * concurrency = "3"    设置消费线程数,每个线程每次只拉取一条消息消费
+     */
+    @RabbitListener(
         queuesToDeclare = @Queue("test_dsx")
     )
     public void test(Channel channel, Message message) throws Exception {
@@ -72,6 +95,4 @@ public class RabbitMqListener {
     }
 
 
-
-
 }

+ 18 - 0
src/main/java/com/fdkankan/scene/mapper/IRoleMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.scene.mapper;
+
+import com.fdkankan.scene.entity.Role;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 角色表 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-01-03
+ */
+@Mapper
+public interface IRoleMapper extends BaseMapper<Role> {
+
+}

+ 18 - 0
src/main/java/com/fdkankan/scene/mapper/ISceneAsynOperLogMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.scene.mapper;
+
+import com.fdkankan.scene.entity.SceneAsynOperLog;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2022-12-07
+ */
+@Mapper
+public interface ISceneAsynOperLogMapper extends BaseMapper<SceneAsynOperLog> {
+
+}

+ 18 - 0
src/main/java/com/fdkankan/scene/mapper/IUserRoleMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.scene.mapper;
+
+import com.fdkankan.scene.entity.UserRole;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 用户角色关系表 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-01-03
+ */
+@Mapper
+public interface IUserRoleMapper extends BaseMapper<UserRole> {
+
+}

+ 16 - 0
src/main/java/com/fdkankan/scene/mapper/MarkShapeMapper.java

@@ -0,0 +1,16 @@
+package com.fdkankan.scene.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.scene.entity.SceneMarkShape;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Xiewj
+ * @date 2021/11/22
+ */
+@Mapper
+@Component("MarkShapeMapper")
+public interface MarkShapeMapper extends BaseMapper<SceneMarkShape> {
+}
+

+ 27 - 0
src/main/java/com/fdkankan/scene/schedule/ScheduleJob.java

@@ -0,0 +1,27 @@
+package com.fdkankan.scene.schedule;
+
+import com.fdkankan.scene.service.ISceneAsynOperLogService;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@RefreshScope
+@Log4j2
+@Component
+public class ScheduleJob {
+
+    @Autowired
+    private ISceneAsynOperLogService sceneAsynOperLogService;
+
+    /**
+     * 每天凌晨一点执行
+     */
+    @Scheduled(cron="0 0 1 * * ?")
+    public void cleanDownloadPanorama() {
+        log.info("定时清除全景图压缩包开始");
+        sceneAsynOperLogService.cleanDownloadPanorama();
+        log.info("定时清除全景图压缩包完毕");
+    }
+}

+ 16 - 0
src/main/java/com/fdkankan/scene/service/IRoleService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.scene.service;
+
+import com.fdkankan.scene.entity.Role;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 角色表 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-01-03
+ */
+public interface IRoleService extends IService<Role> {
+
+}

+ 24 - 0
src/main/java/com/fdkankan/scene/service/ISceneAsynOperLogService.java

@@ -0,0 +1,24 @@
+package com.fdkankan.scene.service;
+
+import com.fdkankan.scene.entity.SceneAsynOperLog;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.scene.vo.SceneAsynOperLogParamVO;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author 
+ * @since 2022-12-07
+ */
+public interface ISceneAsynOperLogService extends IService<SceneAsynOperLog> {
+
+    ResultData getAsynOperLog(SceneAsynOperLogParamVO param);
+
+    void cleanDownloadPanorama();
+
+}

+ 2 - 1
src/main/java/com/fdkankan/scene/service/ISceneEditInfoService.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fdkankan.scene.annotation.CheckPermit;
 import com.fdkankan.scene.vo.BaseSceneParamVO;
+import com.fdkankan.scene.vo.SaveFiltersParamVO;
 import com.fdkankan.scene.vo.SurveillanceParamVO;
 import com.fdkankan.web.response.ResultData;
 import com.fdkankan.scene.entity.SceneEditInfo;
@@ -109,7 +110,7 @@ public interface ISceneEditInfoService extends IService<SceneEditInfo> {
 
     ResultData deleteWaterMark(BaseFileParamVO param) throws Exception;
 
-    ResultData saveFilter(BaseDataParamVO param) throws Exception;
+    ResultData saveFilter(SaveFiltersParamVO param) throws Exception;
 
     ResultData listFilter(BaseSceneParamVO param) throws Exception;
 

+ 2 - 0
src/main/java/com/fdkankan/scene/service/ISceneEditService.java

@@ -26,4 +26,6 @@ public interface ISceneEditService {
 
     ResultData deleteTour(BaseSceneParamVO param) throws Exception;
 
+    ResultData getServiceUpTip();
+
 }

+ 30 - 0
src/main/java/com/fdkankan/scene/service/ISceneMarkShapeService.java

@@ -0,0 +1,30 @@
+package com.fdkankan.scene.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.scene.entity.SceneMarkShape;
+import com.fdkankan.scene.vo.SceneMarkShapeParamVO;
+import com.fdkankan.scene.vo.SceneMarkShapeReDetectParamVO;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Created by Xiewj on 2021/11/23 0026 10:14
+ */
+public interface ISceneMarkShapeService extends IService<SceneMarkShape> {
+    void saveFileToDB(MultipartFile inPath, String num) throws IOException;
+
+    SceneMarkShape findByNumAndImagePath(String num, String imagePath);
+
+    ResultData editLabelByFile(String num, String imgPath, MultipartFile file) throws IOException;
+
+    void trainScene(SceneMarkShapeReDetectParamVO param);
+
+    List<SceneMarkShape> findByReTrainStatus(Integer reTrain);
+    List<SceneMarkShape> findByToTrainStatus(Integer toTrain);
+
+    void editTrainStatus(SceneMarkShapeParamVO param);
+}

+ 16 - 0
src/main/java/com/fdkankan/scene/service/ISceneService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.scene.service;
+
+import com.fdkankan.scene.bean.BodySegmentStatusBean;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+public interface ISceneService {
+
+    ResultData uploadBodySegment(MultipartFile file,Integer rotate) throws Exception;
+
+    void bodySegmentHandler(String imgUrl, String uuid);
+
+    ResultData getBodySegmentStatus(String uuid);
+
+}

+ 16 - 0
src/main/java/com/fdkankan/scene/service/IUserRoleService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.scene.service;
+
+import com.fdkankan.scene.entity.UserRole;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 用户角色关系表 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-01-03
+ */
+public interface IUserRoleService extends IService<UserRole> {
+
+}

+ 20 - 0
src/main/java/com/fdkankan/scene/service/impl/RoleServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fdkankan.scene.service.impl;
+
+import com.fdkankan.scene.entity.Role;
+import com.fdkankan.scene.mapper.IRoleMapper;
+import com.fdkankan.scene.service.IRoleService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 角色表 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2023-01-03
+ */
+@Service
+public class RoleServiceImpl extends ServiceImpl<IRoleMapper, Role> implements IRoleService {
+
+}

+ 118 - 0
src/main/java/com/fdkankan/scene/service/impl/SceneAsynOperLogServiceImpl.java

@@ -0,0 +1,118 @@
+package com.fdkankan.scene.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.fdkankan.common.constant.CommonOperStatus;
+import com.fdkankan.common.constant.CommonStatus;
+import com.fdkankan.common.constant.SceneAsynFuncType;
+import com.fdkankan.common.constant.SceneAsynModuleType;
+import com.fdkankan.common.constant.SceneAsynOperType;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.scene.entity.SceneAsynOperLog;
+import com.fdkankan.scene.mapper.ISceneAsynOperLogMapper;
+import com.fdkankan.scene.service.ISceneAsynOperLogService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.scene.vo.SceneAsynOperLogParamVO;
+import com.fdkankan.web.response.ResultData;
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.List;
+import java.util.stream.Collectors;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2022-12-07
+ */
+@Slf4j
+@Service
+public class SceneAsynOperLogServiceImpl extends ServiceImpl<ISceneAsynOperLogMapper, SceneAsynOperLog> implements ISceneAsynOperLogService {
+
+    @Autowired
+    private FYunFileServiceInterface fYunFileService;
+
+
+    @Override
+    public ResultData getAsynOperLog(SceneAsynOperLogParamVO param) {
+
+        LambdaQueryWrapper<SceneAsynOperLog> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(SceneAsynOperLog::getNum, param.getNum());
+        if(StrUtil.isNotEmpty(param.getOperType())){
+            queryWrapper.eq(SceneAsynOperLog::getOperType, param.getOperType());
+        }
+        if(StrUtil.isNotEmpty(param.getModule())){
+            queryWrapper.eq(SceneAsynOperLog::getModule, param.getModule());
+        }
+        if(StrUtil.isNotEmpty(param.getFunc())){
+            queryWrapper.eq(SceneAsynOperLog::getFunc, param.getFunc());
+        }
+
+        //需要弹窗的异步操作列表
+        List<SceneAsynOperLog> list = this.list(queryWrapper);
+
+        //如果列表中有需要弹窗并且处理完毕的,需要把这些数据改为不需要弹窗了,因为前端请求到之后就会弹出提示,下次不需要弹窗了
+        if(CollUtil.isNotEmpty(list)){
+            List<Long> idList = list.stream().filter(log -> {
+                if(!log.getState().equals(CommonOperStatus.WAITING.code())){
+                    return true;
+                }
+                return false;
+            }).map(log->log.getId()).collect(Collectors.toList());
+            if(CollUtil.isNotEmpty(idList)){
+                this.update(new LambdaUpdateWrapper<SceneAsynOperLog>()
+                    .set(SceneAsynOperLog::getPop, CommonStatus.NO.code())
+                    .in(SceneAsynOperLog::getId, idList));
+            }
+        }
+
+        return ResultData.ok(list);
+    }
+
+    @Override
+    public void cleanDownloadPanorama() {
+
+        List<SceneAsynOperLog> downloadList = this.list(
+            new LambdaQueryWrapper<SceneAsynOperLog>()
+                .eq(SceneAsynOperLog::getOperType, SceneAsynOperType.DOWNLOAD.code())
+                .eq(SceneAsynOperLog::getModule, SceneAsynModuleType.UPLOAD_DOWNLOAD.code())
+                .eq(SceneAsynOperLog::getFunc, SceneAsynFuncType.PANORAMIC_IMAGE.code()));
+        if(CollUtil.isEmpty(downloadList)){
+            return;
+        }
+        DateTime preMonth = DateUtil.offsetMonth(Calendar.getInstance().getTime(), -1);
+        List<SceneAsynOperLog> deleteList = downloadList.parallelStream().filter(log -> {
+            if (log.getCreateTime().before(preMonth)) {
+                return Boolean.TRUE;
+            }
+            return false;
+        }).collect(Collectors.toList());
+        if(CollUtil.isEmpty(deleteList)){
+            return;
+        }
+
+        //删除数据库记录
+        List<Long> deleteIdList = deleteList.parallelStream().map(item -> item.getId()).collect(Collectors.toList());
+        this.removeByIds(deleteIdList);
+
+        deleteList.parallelStream().forEach(item -> {
+            if(StrUtil.isNotEmpty(item.getUrl())){
+                try {
+                    fYunFileService.deleteFile(item.getUrl());
+                } catch (IOException e) {
+                    log.warn("删除oss全景图下载压缩包失败,key:{}", item.getUrl());
+                }
+            }
+        });
+
+    }
+}

+ 285 - 109
src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java

@@ -1,4 +1,12 @@
 package com.fdkankan.scene.service.impl;
+import cn.hutool.core.net.multipart.UploadFile;
+import cn.hutool.core.util.CharsetUtil;
+import com.fdkankan.common.constant.*;
+import com.fdkankan.common.util.FileSizeUtil;
+import com.fdkankan.common.util.MD5;
+import com.fdkankan.scene.vo.SaveFiltersParamVO;
+import io.opencensus.metrics.LongGauge;
+import java.util.Date;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
@@ -12,13 +20,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fdkankan.common.constant.CommonStatus;
-import com.fdkankan.common.constant.ErrorCode;
-import com.fdkankan.common.constant.FileBizType;
-import com.fdkankan.common.constant.OperationType;
-import com.fdkankan.common.constant.SceneFrom;
-import com.fdkankan.common.constant.SceneInfoReqType;
-import com.fdkankan.common.constant.ServerCode;
 import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.common.util.FileMd5Util;
 import com.fdkankan.common.util.FileUtils;
@@ -44,6 +45,7 @@ import com.fdkankan.scene.bean.VertexBean;
 import com.fdkankan.scene.bean.WallBean;
 import com.fdkankan.scene.entity.CameraDetail;
 import com.fdkankan.scene.entity.Company;
+import com.fdkankan.scene.entity.SceneAsynOperLog;
 import com.fdkankan.scene.entity.SceneDataDownload;
 import com.fdkankan.scene.entity.SceneEditControls;
 import com.fdkankan.scene.entity.SceneEditInfo;
@@ -53,6 +55,7 @@ import com.fdkankan.scene.entity.ScenePlusExt;
 import com.fdkankan.scene.mapper.ISceneEditInfoMapper;
 import com.fdkankan.scene.service.ICameraDetailService;
 import com.fdkankan.scene.service.ICompanyService;
+import com.fdkankan.scene.service.ISceneAsynOperLogService;
 import com.fdkankan.scene.service.ISceneDataDownloadService;
 import com.fdkankan.scene.service.ISceneEditControlsService;
 import com.fdkankan.scene.service.ISceneEditInfoExtService;
@@ -103,6 +106,7 @@ import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 import javax.annotation.Resource;
@@ -162,6 +166,8 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
     private ICompanyService companyService;
     @Autowired
     private ISurveillanceService surveillanceService;
+    @Autowired
+    private ISceneAsynOperLogService sceneAsynOperLogService;
 
     @Transactional
     @Override
@@ -272,6 +278,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         sceneJson.setSceneResolution(scenePlusExt.getSceneResolution());
         sceneJson.setSceneFrom(scenePlusExt.getSceneFrom());
         sceneJson.setSceneKind(scenePlusExt.getSceneKind());
+        sceneJson.setModelKind(scenePlusExt.getModelKind());
         if(StrUtil.isNotEmpty(scenePlusExt.getVideos())){
             sceneJson.setVideos(scenePlusExt.getVideos());
         }
@@ -304,7 +311,10 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
 
         //删除发布数据中的user目录
         String publicUserPath = String.format(UploadFilePath.USER_VIEW_PATH, num);
-        fYunFileService.deleteFile(bucket, publicUserPath);
+        List<String> userViewFileList = fYunFileService.listRemoteFiles(bucket, publicUserPath);
+        if(CollUtil.isNotEmpty(userViewFileList)){
+            fYunFileService.deleteFolder(bucket, publicUserPath);
+        }
 
         //复制编辑目录到发布目录
         String editPath = String.format(UploadFilePath.USER_EDIT_PATH, param.getNum());
@@ -323,11 +333,18 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
 
         scenePlus.setTitle(sceneEditInfo.getTitle());
         scenePlus.setDescription(sceneEditInfo.getDescription());
+        scenePlus.setHouseType(this.existsHouseType(bucket, num));
         scenePlusService.updateById(scenePlus);
 
         return ResultData.ok();
     }
 
+    private int existsHouseType(String bucket, String num){
+        String houseTypePath = String.format(UploadFilePath.USER_VIEW_PATH, num) + "houseType.json";
+        boolean exist = fYunFileService.fileExist(bucket, houseTypePath);
+        return exist ? CommonStatus.YES.code().intValue() : CommonStatus.NO.code().intValue();
+    }
+
     private void publicSurveillance(String num, Integer surveillances, String bucket) throws IOException {
         String surveillanceJsonPath = String.format(UploadFilePath.USER_EDIT_PATH, num) + "surveillance.json";
         if(surveillances == CommonStatus.NO.code().intValue()){
@@ -358,6 +375,11 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         String userEditPath = String.format(UploadFilePath.USER_EDIT_PATH, num);
         String imgViewPath = String.format(UploadFilePath.IMG_VIEW_PATH, num);
 
+        //清除发布目录中的场景关联图片
+        if(fYunFileService.fileExist(bucket,imgViewPath + "panorama")){
+            fYunFileService.deleteFolder(bucket,imgViewPath + "panorama");
+        }
+
         //生成links.json并上传到发布目录
         String linkPanKey = String.format(RedisKey.SCENE_LINKPAN_DATA, num);
         Map<String, String> linkPanMap = redisUtil.hmget(linkPanKey);
@@ -372,7 +394,6 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         fYunFileService.uploadFile(bucket, linkPanArr.toString().getBytes(), linkScenePath);
 
         //拷贝编辑目录到发布目录
-        fYunFileService.deleteFile(bucket,imgViewPath + "panorama");
         fYunFileService.copyFileBetweenBucket(bucket, imgEditPath + "panorama", bucket, imgViewPath + "panorama");
 
     }
@@ -400,7 +421,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
 
         String hotJsonPath = String.format(UploadFilePath.USER_EDIT_PATH, sceneNum) + "hot.json";
         fYunFileService.uploadFile(bucket, tags.toString().getBytes(), hotJsonPath);
-        this.saveTagsToSceneEditInfo(sceneNum, sceneEditInfo);
+//        this.saveTagsToSceneEditInfo(sceneNum, sceneEditInfo);
 
     }
 
@@ -458,10 +479,12 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         sceneInfoVO.setSceneResolution(scenePlusExt.getSceneResolution());
         sceneInfoVO.setSceneFrom(scenePlusExt.getSceneFrom());
         sceneInfoVO.setSceneKind(scenePlusExt.getSceneKind());
+        sceneInfoVO.setModelKind(scenePlusExt.getModelKind());
         sceneInfoVO.setVideos(scenePlusExt.getVideos());
-        if(CommonStatus.YES.code().equals(sceneEditInfoExt.getMosaic())){
+        if(CommonStatus.YES.code().intValue() == sceneEditInfoExt.getMosaic()){
             sceneInfoVO.setMosaicList(this.getMosaicList(num));
         }
+        sceneInfoVO.setSpace(FileSizeUtil.convert(scenePlusExt.getSpace(), FileSizeUnitType.MB.code()));
 
         this.SortBoxVideos(sceneInfoVO);
 
@@ -605,7 +628,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         //处理户型图数据
         //上传floorplan_user.json文件
         FileUtils.writeFile(localDataPath + "floorplan_user.json", floorJsonData);
-        fYunFileService.uploadFile(bucket, localDataPath + "floorplan_user.json", editUserPath + "floorplan_user.json");
+        fYunFileService.uploadFile(bucket, localDataPath + "floorplan_user.json", editUserPath + "floorplan.json");
 
         //写入数据库
         Byte floorPlanUser = null;
@@ -664,20 +687,24 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         String path = scenePlusExt.getDataSource();
 
         //户型图上传
-        String  userEditPath = UploadFilePath.USER_EDIT_PATH + "floor-cad-%s.%s";
-        String floorCadPath = path + "/results/floorplan_cad";
-        List<String> floorCadList = FileUtils.getFileList(floorCadPath);
-        if(CollUtil.isNotEmpty(floorCadList)){
-            floorCadList.stream().forEach(str->{
-                String substring = str.substring(str.lastIndexOf(File.separator) + 1);
-                String[] arr = substring.split("floor");
-                String[] arr2 = arr[1].split("\\.");
-                fYunFileService.uploadFile(bucket, str, String.format(userEditPath, num, arr2[0], arr2[1]));
-            });
-        }
+        String ossResultPath = String.format(UploadFilePath.scene_result_data_path, num);
+        String floorplanCadPath = ossResultPath + "floorplan_cad/";
+        fYunFileService.copyFileBetweenBucket(bucket, floorplanCadPath, bucket, String.format(UploadFilePath.USER_EDIT_PATH, num));
+
+//        String  userEditPath = UploadFilePath.USER_EDIT_PATH + "floor-cad-%s.%s";
+//        String floorCadPath = path + "/results/floorplan_cad";
+//        List<String> floorCadList = FileUtils.getFileList(floorCadPath);
+//        if(CollUtil.isNotEmpty(floorCadList)){
+//            floorCadList.stream().forEach(str->{
+//                String substring = str.substring(str.lastIndexOf(File.separator) + 1);
+//                String[] arr = substring.split("floor");
+//                String[] arr2 = arr[1].split("\\.");
+//                fYunFileService.uploadFile(bucket, str, String.format(userEditPath, num, arr2[0], arr2[1]));
+//            });
+//        }
 
         //根据floorplan_cad.json生成houseType.json
-        this.uploadHouseTypeJson(num, bucket);
+//        this.uploadHouseTypeJson(num, bucket);
 
         SceneEditInfo sceneEditInfoDb = this.getByScenePlusId(scenePlus.getId());
         SceneEditInfoExt sceneEditInfoExt = null;
@@ -715,6 +742,10 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         result.put("version", "2.1");
 
         String floorplanCadPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "floorplan_cad.json";
+        if(!fYunFileService.fileExist(bucket, floorplanCadPath)){
+            log.warn("生成houseType.json失败,原因:floorplan_cad.json文件不存在,num:{}", num);
+            return;
+        }
         String floorcadStr = fYunFileService.getFileContent(bucket, floorplanCadPath);
 
         JSONObject floorcadObj = JSON.parseObject(floorcadStr);
@@ -897,9 +928,11 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         String sceneJson = redisUtil.get(key);
         if(StrUtil.isNotEmpty(sceneJson)){
             SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
-            sceneJsonBean.setVersion(version);
+            if(Objects.nonNull(version)){
+                sceneJsonBean.setVersion(version);
+            }
             if(Objects.nonNull(imgVersion)){
-                sceneJsonBean.setImgVersion(imgVersion + 1);
+                sceneJsonBean.setImgVersion(imgVersion);
             }
             redisUtil.set(key, JSON.toJSONString(sceneJsonBean));
         }
@@ -909,9 +942,11 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         sceneJson= fYunFileService.getFileContent(bucket, sceneJsonPath);
         if(StrUtil.isNotEmpty(sceneJson)){
             SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
-            sceneJsonBean.setVersion(version);
+            if(Objects.nonNull(version)){
+                sceneJsonBean.setVersion(version);
+            }
             if(Objects.nonNull(imgVersion)){
-                sceneJsonBean.setImgVersion(imgVersion + 1);
+                sceneJsonBean.setImgVersion(imgVersion);
             }
             fYunFileService.uploadFile(bucket, JSON.toJSONString(sceneJsonBean).getBytes(StandardCharsets.UTF_8), sceneJsonPath);
         }
@@ -929,6 +964,19 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         if(scenePlus == null){
             throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
         }
+
+        //查询是否存在等待中的异步操作记录,如果存在,抛出业务异常,终止操作
+        this.checkSceneAsynOper(num, null, SceneAsynModuleType.UPLOAD_DOWNLOAD.code() , SceneAsynFuncType.PANORAMIC_IMAGE.code());
+
+        //清除全景图异步操作记录,防止再次下载的时候请求到旧的压缩包
+        sceneAsynOperLogService.remove(
+            new LambdaQueryWrapper<SceneAsynOperLog>()
+            .eq(SceneAsynOperLog::getNum, num)
+            .eq(SceneAsynOperLog::getModule, SceneAsynModuleType.UPLOAD_DOWNLOAD.code())
+            .eq(SceneAsynOperLog::getFunc, SceneAsynFuncType.PANORAMIC_IMAGE.code())
+        );
+
+
         ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
         String bucket = scenePlusExt.getYunFileBucket();
 
@@ -943,7 +991,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         String zipTargetFilePath = targetImagesPath + file.getOriginalFilename();
 
         //判断全景图缓存是否存在,如果不存在,从计算目录中拷贝到缓存目录
-        this.cachePanorama(path, num);
+//        this.cachePanorama(path, num);
 
         //先删除本地文件
         FileUtils.deleteDirectory(targetImagesPath);
@@ -954,9 +1002,14 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         file.transferTo(targetFile);
 
         //如果是压缩包上传,需要解压缩
+        int async = CommonStatus.NO.code();
         if(file.getOriginalFilename().endsWith(".zip")){
+
+            //标记为异步处理
+            async = CommonStatus.YES.code();
+
             //解压zip包
-            ZipUtil.unzip(zipTargetFilePath,targetImagesPath);
+            ZipUtil.unzip(zipTargetFilePath,targetImagesPath, CharsetUtil.CHARSET_GBK);
             //删除压缩包
             FileUtils.delFile(zipTargetFilePath);
         }
@@ -990,11 +1043,13 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         }
 
         //比对图片列表,不存在的要返回名称集合
-        String visionPath = path + "/results/vision.txt";
+        String ossVisionPath = String.format(UploadFilePath.IMG_VIEW_PATH, num) + "vision.txt";
+        String visionPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, num) + "vision.txt";
+        fYunFileService.downloadFile(ossVisionPath, visionPath);
         List<String> panoramaImageList = SceneUtil.getPanoramaImageList(visionPath);
         List<String> notExistFileList = uploadFileList.stream().filter(filePath -> {
             filePath = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
-            if(panoramaImageList.contains(filePath)){
+            if(CollUtil.isEmpty(panoramaImageList) || panoramaImageList.contains(filePath)){
                 return false;
             }
             return true;
@@ -1015,7 +1070,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
                     return filePath.substring(filePath.lastIndexOf(File.separator) + 1);
                 }).collect(Collectors.toList());
             }
-            return ResultData.ok(new UploadPanoramaVO(0, notExistFileList));
+            return ResultData.ok(new UploadPanoramaVO(0,0, notExistFileList));
         }
 
         //上传
@@ -1026,8 +1081,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         CreateObjUtil.convertVisionmodeldataToTxt(target + File.separator + "extras" + File.separator + "vision.modeldata",
             target + File.separator + "extras" + File.separator + "vision.txt");
 
-        FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
-        FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
+        String ossResultPath = String.format(UploadFilePath.scene_result_data_path, num);
+        fYunFileService.downloadFile(bucket, ossResultPath + "data.json", target + File.separator+"data.json");
+        fYunFileService.downloadFile(bucket, ossResultPath + "project.json", target + File.separator+"project.json");
 
         //data.json增加extras为执行重建算法
         String data = FileUtils.readFile(target + File.separator+"data.json");
@@ -1061,11 +1117,74 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         if(new File(target + File.separator + "results").exists()){
             FileUtils.delAllFile(target + File.separator + "results");
         }
-        if(FYunTypeEnum.AWS.code().equals(fyunType)){
-            //亚马逊保持旧方式,超链接capture
-            CreateObjUtil.createSoftConnection(path + File.separator + "capture", target + File.separator + "capture");
-        }
+
         fYunFileService.downloadFile(ConstantFilePath.OSS_PREFIX + path.replace(ConstantFilePath.BUILD_MODEL_PATH, "") + "/data.fdage", target + File.separator + "capture/data.fdage");
+
+        //如果部分成功,则需要返回成功数量和失败列表
+        if(CollUtil.isNotEmpty(notExistFileList)){
+            notExistFileList = notExistFileList.stream().map(filePath -> {
+                return filePath.substring(filePath.lastIndexOf(File.separator) + 1);
+            }).collect(Collectors.toList());
+        }
+
+        UploadPanoramaVO uploadPanoramaVO = new UploadPanoramaVO();
+        uploadPanoramaVO.setAsyn(async);
+        if(async == CommonStatus.YES.code().intValue()){
+            List<String> finalUploadFileList = uploadFileList;
+            List<String> finalNotExistFileList = notExistFileList;
+            CompletableFuture.runAsync(() -> {
+                SceneAsynOperLog sceneAsynOperLog = new SceneAsynOperLog();
+                sceneAsynOperLog.setNum(num);
+                sceneAsynOperLog.setOperType(SceneAsynOperType.UPLOAD.code());
+                sceneAsynOperLog.setModule(SceneAsynModuleType.UPLOAD_DOWNLOAD.code());
+                sceneAsynOperLog.setFunc(SceneAsynFuncType.PANORAMIC_IMAGE.code());
+                if(CollUtil.isNotEmpty(finalNotExistFileList)){
+                    Map<String, Object> extData = new HashMap<>();
+                    extData.put("successCnt", finalUploadFileList.size());
+                    extData.put("failList", finalNotExistFileList);
+                    sceneAsynOperLog.setExtData(JSON.toJSONString(extData));
+                }
+                sceneAsynOperLogService.save(sceneAsynOperLog);
+                try {
+                    this.uploadPanoramaHandler(num,bucket,target,imgViewPath, finalUploadFileList,targetImagesPath);
+                    sceneAsynOperLog.setState(CommonOperStatus.SUCCESS.code());
+                } catch (Exception e) {
+                    log.error("上传全景图报错,num:" + num, e);
+                    sceneAsynOperLog.setState(CommonOperStatus.FAILD.code());
+                }
+                sceneAsynOperLogService.updateById(sceneAsynOperLog);
+            });
+        }else{
+            this.uploadPanoramaHandler(num,bucket,target,imgViewPath,uploadFileList,targetImagesPath);
+            if(CollUtil.isNotEmpty(notExistFileList)){
+                uploadPanoramaVO.setSuccessCnt(uploadFileList.size());
+                uploadPanoramaVO.setFailList(notExistFileList);
+            }
+        }
+        return ResultData.ok(uploadPanoramaVO);
+    }
+
+    private void checkSceneAsynOper(String num, String operType, String module, String function){
+        LambdaQueryWrapper<SceneAsynOperLog> queryWrapper =
+            new LambdaQueryWrapper<SceneAsynOperLog>()
+                .eq(SceneAsynOperLog::getNum,num)
+                .eq(SceneAsynOperLog::getState, CommonOperStatus.WAITING.code());
+        if(StrUtil.isNotEmpty(operType)){
+            queryWrapper.eq(SceneAsynOperLog::getOperType, operType);
+        }
+        if(StrUtil.isNotEmpty(module)){
+            queryWrapper.eq(SceneAsynOperLog::getModule, module);
+        }
+        if(StrUtil.isNotEmpty(function)){
+            queryWrapper.eq(SceneAsynOperLog::getFunc, function);
+        }
+        List<SceneAsynOperLog> waittingLogList = sceneAsynOperLogService.list(queryWrapper);
+        if(CollUtil.isNotEmpty(waittingLogList)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5066);
+        }
+    }
+
+    public void uploadPanoramaHandler(String num, String bucket, String target, String imgViewPath, List<String> uploadFileList, String targetImagesPath) throws Exception {
         CreateObjUtil.build3dModel(target , "1");
 
         String uploadJsonPath= target + File.separator + "results" +File.separator+"upload.json";
@@ -1084,6 +1203,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         if(array == null){
             throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
         }
+        Map<String, String> map = new HashMap<>();
         JSONObject fileJson = null;
         String fileName = "";
         for(int i = 0, len = array.size(); i < len; i++) {
@@ -1123,31 +1243,23 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
                 continue;
             }
         }
-        if(map.size()>0) {
-            fYunFileService.uploadMulFiles(bucket, map);
-        }
 
-        //拷贝修改后的全景图到缓存目录
-        String cachedImagesPath = String.format(ConstantFilePath.SCENE_CACHE_IMAGES, num);
+        //用户上传的全景图上传到ossresult目录
+        String ossCachesImagesPath = String.format(UploadFilePath.scene_result_data_path, num) + "caches/images/";
         uploadFileList.stream().forEach(srcPath->{
-            cn.hutool.core.io.FileUtil.copy(srcPath, srcPath.replace(targetImagesPath, cachedImagesPath), true);
+            map.put(srcPath, srcPath.replace(targetImagesPath, ossCachesImagesPath));
         });
 
+        if(map.size()>0) {
+            fYunFileService.uploadMulFiles(bucket, map);
+        }
+
         //更新数据库版本号
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
         SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
         this.upgradeVersionAndImgVersionById(sceneEditInfo.getId());
         //更新scenejson缓存和oss文件版本号
         this.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1, bucket);
-
-        //如果部分成功,则需要返回成功数量和失败列表
-        if(CollUtil.isNotEmpty(notExistFileList)){
-            notExistFileList = notExistFileList.stream().map(filePath -> {
-                return filePath.substring(filePath.lastIndexOf(File.separator) + 1);
-            }).collect(Collectors.toList());
-            return ResultData.ok(new UploadPanoramaVO(uploadFileList.size(), notExistFileList));
-        }
-
-        return ResultData.ok();
     }
 
 
@@ -1162,6 +1274,10 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         if(Objects.isNull(scenePlus)){
             throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
         }
+
+        //查询是否存在等待中的异步操作记录,如果存在,抛出业务异常,终止操作
+        this.checkSceneAsynOper(num,null, SceneAsynModuleType.UPLOAD_DOWNLOAD.code() , SceneAsynFuncType.PANORAMIC_IMAGE.code());
+
         ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
         String bucket = scenePlusExt.getYunFileBucket();
         String path = scenePlusExt.getDataSource();
@@ -1174,47 +1290,96 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         String cacheImageFormat = "downloads/scene/%s/caches/images/";
 
         //判断全景图缓存是否存在,如果不存在,从计算目录中拷贝到缓存目录
-        this.cachePanorama(scenePlusExt.getDataSource(), num);
+//        this.cachePanorama(scenePlusExt.getDataSource(), num);
+
+        //根据vision.txt获取到有效的全景图名称
+        String ossVisionPath = String.format(UploadFilePath.IMG_VIEW_PATH, num) + "vision.txt";
+        String visionPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, num) + "vision.txt";
+        fYunFileService.downloadFile(ossVisionPath, visionPath);
+        List<String> panoramaImageList = SceneUtil.getPanoramaImageList(visionPath);
+        if(CollUtil.isEmpty(panoramaImageList)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
+        }
+
+        Map<String, Object> map = new HashMap<>();
 
-        String url = null;
-        String downloadName = null;
+        //标记是否是异步操作,默认是同步操作
         //如果入参文件名不为空,则是单个文件下载,不需要打包
+        String ossResultPath = String.format(UploadFilePath.scene_result_data_path, num) + "caches/images/";
         if(StrUtil.isNotEmpty(fileName)){
             //如果是单张图片,直接提供oss url
-            String localFilePath = localImagesPath + fileName;
-            String ossFilePath = imgCachePath + fileName;
-            if(!cn.hutool.core.io.FileUtil.exist(localFilePath)){
+//            if(!fYunFileService.fileExist(bucket, ossResultPath + fileName)){
+//                throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
+//            }
+            if(!panoramaImageList.contains(fileName)){
                 throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
             }
-            fYunFileService.uploadFile(bucket, localFilePath, ossFilePath);
-            url = ossUrlPrefix + ossFilePath;
-            downloadName = fileName;
+            String url = ossUrlPrefix + ossResultPath + fileName;
+            String downloadName = fileName;
+            map.put("asyn", CommonStatus.NO.code());
+            map.put("fileUrl", url + "?t=" + System.currentTimeMillis());
+            map.put("fileName", downloadName);
+            return ResultData.ok(map);
         }else{
-            if(!cn.hutool.core.io.FileUtil.exist(localImagesPath)
-                || cn.hutool.core.io.FileUtil.isDirEmpty(new File(localImagesPath))){
-                throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
-            }
+            //清除旧的下载记录
+            sceneAsynOperLogService.remove(
+                new LambdaQueryWrapper<SceneAsynOperLog>()
+                    .eq(SceneAsynOperLog::getNum, num)
+                    .eq(SceneAsynOperLog::getOperType, SceneAsynOperType.DOWNLOAD.code())
+                    .eq(SceneAsynOperLog::getModule, SceneAsynModuleType.UPLOAD_DOWNLOAD.code())
+                    .eq(SceneAsynOperLog::getFunc, SceneAsynFuncType.PANORAMIC_IMAGE.code()));
+
+            //开始异步执行下载全景图压缩包操作
+            CompletableFuture.runAsync(() -> {
+                SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
+                SceneAsynOperLog sceneAsynOperLog = new SceneAsynOperLog();
+                sceneAsynOperLog.setNum(num);
+                sceneAsynOperLog.setOperType(SceneAsynOperType.DOWNLOAD.code());
+                sceneAsynOperLog.setModule(SceneAsynModuleType.UPLOAD_DOWNLOAD.code());
+                sceneAsynOperLog.setFunc(SceneAsynFuncType.PANORAMIC_IMAGE.code());
+                sceneAsynOperLog.setVersion(sceneEditInfo.getImgVersion());
+                sceneAsynOperLogService.save(sceneAsynOperLog);
+                try {
+
+                    //下载到本地目录
+                    FileUtil.del(localImagesPath);
+                    fYunFileService.downloadFileByCommand(bucket, localImagesPath, ossResultPath);
+                    //移除非必须文件
+                    List<String> fileNames = FileUtil.listFileNames(localImagesPath);
+                    fileNames.stream().forEach(name->{
+                        if(!panoramaImageList.contains(name)){
+                            FileUtil.del(localImagesPath + name);
+                        }
+                    });
+
+                    String downloadName = num + "_images.zip";
+                    long start = Calendar.getInstance().getTimeInMillis();
+                    //打包
+                    String zipPath = cachePath + downloadName;
+                    ZipUtil.zip(localImagesPath, zipPath);
+                    long end1 = Calendar.getInstance().getTimeInMillis();
+                    log.info("打包耗时:" + (end1 - start));
+                    //上传压缩包
+                    fYunFileService.uploadFileByCommand(bucket, zipPath, String.format(cacheFormat, num) + downloadName);
+                    String url = String.format(cacheFormat, num) + downloadName;
+                    long end2 = Calendar.getInstance().getTimeInMillis();
+                    log.info("上传耗时:" + (end2 - end1));
+                    //删除本地压缩包
+                    FileUtils.deleteFile(zipPath);
+                    //删除本地目录
+                    FileUtils.deleteDirectory(localImagesPath);
+                    sceneAsynOperLog.setState(CommonOperStatus.SUCCESS.code());
+                    sceneAsynOperLog.setUrl(url);
+                }catch (Exception e){
+                    sceneAsynOperLog.setState(CommonOperStatus.FAILD.code());
+                    log.error("下载全景图压缩包失败,num:" + num, e);
+                }
+                sceneAsynOperLogService.saveOrUpdate(sceneAsynOperLog);
+            });
 
-            downloadName = num + "_images.zip";
-            long start = Calendar.getInstance().getTimeInMillis();
-            //打包
-            String zipPath = cachePath + downloadName;
-            ZipUtil.zip(localImagesPath, zipPath);
-            long end1 = Calendar.getInstance().getTimeInMillis();
-            log.info("打包耗时:" + (end1 - start));
-            //上传压缩包
-            fYunFileService.uploadFileByCommand(bucket, zipPath, String.format(cacheFormat, num) + downloadName);
-            url = ossUrlPrefix + String.format(cacheFormat, num) + downloadName;
-            long end2 = Calendar.getInstance().getTimeInMillis();
-            log.info("上传耗时:" + (end2 - end1));
-            //删除本地压缩包
-//            FileUtils.deleteFile(zipPath);
+            map.put("asyn", CommonStatus.YES.code());
+            return ResultData.ok(map);
         }
-
-        Map<String, Object> map = new HashMap<>();
-        map.put("fileUrl", url + "?t=" + System.currentTimeMillis());
-        map.put("fileName", downloadName);
-        return ResultData.ok(map);
     }
 
     private void cachePanorama(String dataSource, String num){
@@ -1425,8 +1590,8 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
             fYunFileService.uploadFile(bucket, target + File.separator + "extras/video/" + videoName.replace("mp4", "flv"),videosViewPath + videoName.replace("mp4", "flv"));
 
             //覆盖原始视频资源
-            FileUtils.copyFile(target + File.separator + "extras/video/" + videoName,
-                path + File.separator + "caches/videos/" + videoName, true);
+//            FileUtils.copyFile(target + File.separator + "extras/video/" + videoName,
+//                path + File.separator + "caches/videos/" + videoName, true);
 
         }
         FileUtils.deleteDirectory(target + File.separator + "extras/video/");
@@ -1498,15 +1663,20 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
             if(new File(target + File.separator + "results").exists()){
                 FileUtils.delAllFile(target + File.separator + "results");
             }
+
             //创建文件夹,并link文件夹
             new File(target + File.separator + "caches").mkdirs();
-            CreateObjUtil.createSoftConnection(path + File.separator + "capture", target + File.separator + "capture");
+            fYunFileService.downloadFileByCommand(target + File.separator + "capture", SceneUtil.getHomePath(path));
+//            CreateObjUtil.createSoftConnection(path + File.separator + "capture", target + File.separator + "capture");
             if(new File(path + File.separator + "caches" + File.separator + "images").exists()){
                 CreateObjUtil.createSoftConnection(path + File.separator + "caches" + File.separator + "images", target + File.separator + "caches" + File.separator + "images");
             }
 
-            FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
-            FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
+            String ossResultPath = String.format(UploadFilePath.scene_result_data_path, num);
+            fYunFileService.downloadFile(bucket, ossResultPath + "data.json", target + File.separator+"data.json");
+            fYunFileService.downloadFile(bucket, ossResultPath + "project.json", target + File.separator+"project.json");
+//            FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
+//            FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
 
             //data.json增加extras为执行重建算法
             String project = FileUtils.readFile(target + File.separator+"project.json");
@@ -1779,7 +1949,6 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
         String bucket = scenePlusExt.getYunFileBucket();
 
-        String localDataPath = String.format(ConstantFilePath.DATABUFFER_FORMAT, num);
         String localImagesPath = String.format(ConstantFilePath.IMAGESBUFFER_FORMAT, num);
         String path = scenePlusExt.getDataSource();
         String target = localImagesPath + "panorama/" + sid;
@@ -1794,8 +1963,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         file.transferTo(targetFile);
 
         //调用算法切全景图
-        FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
-        FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
+        String ossResultPath = String.format(UploadFilePath.scene_result_data_path, num);
+        fYunFileService.downloadFile(bucket, ossResultPath + "data.json", target + File.separator+"data.json");
+        fYunFileService.downloadFile(bucket, ossResultPath + "project.json", target + File.separator+"project.json");
         JSONObject visionJson = new JSONObject();
         JSONArray visionArray = new JSONArray();
         visionJson.put("uuid", sid);
@@ -1804,9 +1974,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         visionArray.add(visionJson);
         JSONObject vision = new JSONObject();
         vision.put("sweepLocations", visionArray);
-        cn.hutool.core.io.FileUtil.writeString(vision.toString(),
-            target + "/extras" + File.separator + "vision.txt",
-            StandardCharsets.UTF_8);
+        cn.hutool.core.io.FileUtil.writeString(vision.toString(), target + "/extras" + File.separator + "vision.txt", StandardCharsets.UTF_8);
 
         //data.json增加extras为执行重建算法
         String type = "4k";
@@ -1834,8 +2002,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
             }
             dataJson.put("skybox_type", skyboxType);
 
-            cn.hutool.core.io.FileUtil.writeString(dataJson.toString(),
-                target + File.separator+"data.json", StandardCharsets.UTF_8);
+            cn.hutool.core.io.FileUtil.writeString(dataJson.toString(), target + File.separator+"data.json", StandardCharsets.UTF_8);
         }
 
         //创建文件夹软连接并且复制data.json和project.json
@@ -1850,10 +2017,6 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
             cn.hutool.core.io.FileUtil.del(resultPath);
         }
         //下载data.fdage
-        if(FYunTypeEnum.AWS.code().equals(this.fyunType)){
-            //亚马逊保持旧方式,超链接capture
-            CreateObjUtil.createSoftConnection(path + File.separator + "capture", capturePath);
-        }
         fYunFileService.downloadFile(ConstantFilePath.OSS_PREFIX + path.replace(ConstantFilePath.BUILD_MODEL_PATH, "") + "/data.fdage", capturePath + "/data.fdage");
         CreateObjUtil.build3dModel(target , "1");
 
@@ -1983,14 +2146,19 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         List<String> deletDataList = redisUtil.hMultiGet(key, deleteSidList);
         if(CollUtil.isEmpty(deletDataList))
             return;
+        List<String> thumbNameList = deleteSidList.stream().map(sid -> {
+            String linkPan = redisUtil.hget(key, sid);
+            JSONObject linkPanObj = JSON.parseObject(linkPan);
+            return FileUtil.getPrefix(linkPanObj.getString("thumb"));
+        }).collect(Collectors.toList());
 
         //从redis中移除热点数据
         redisUtil.hdel(key, deleteSidList.toArray());
 
         //删除oss文件
         String imgEditPath = String.format(UploadFilePath.IMG_EDIT_PATH, num);
-        deleteSidList.stream().forEach(sid->{
-            fYunFileService.deleteFolder(bucket, imgEditPath + "panorama_edit/" + sid);
+        thumbNameList.stream().forEach(thumbName->{
+            fYunFileService.deleteFolder(bucket, imgEditPath + "panorama/" + thumbName);
         });
 
     }
@@ -2405,8 +2573,8 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
                 boxVideosJson.add(boxVideo);
             }
 
-            boxVideosJson.clear();
-            boxVideosJson.add(boxVideo);
+//            boxVideosJson.clear();
+//            boxVideosJson.add(boxVideo);
 
         }
         if(boxVideosJson.size() != 0){
@@ -2600,7 +2768,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
     }
 
     @Override
-    public ResultData saveFilter(BaseDataParamVO param) throws Exception {
+    public ResultData saveFilter(SaveFiltersParamVO param) throws Exception {
 
         ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
         if(Objects.isNull(scenePlus)){
@@ -2621,11 +2789,19 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         //写本地文件,作为备份
         this.writeFilter(param.getNum());
 
+        //如果页面选择恢复默认,filters字段值为否
+        if(Objects.nonNull(param.getReset()) && param.getReset() == CommonStatus.YES.code().intValue()){
+            filters = CommonStatus.NO.code();
+        }
+
         //更新数据库
         SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
         sceneEditInfoExt.setFilters(filters);
         sceneEditInfoExtService.updateById(sceneEditInfoExt);
 
+        //更新版本号
+        this.upgradeVersionById(sceneEditInfoExt.getEditInfoId());
+
         return ResultData.ok();
 
     }

+ 23 - 105
src/main/java/com/fdkankan/scene/service/impl/SceneEditServiceImpl.java

@@ -11,6 +11,7 @@ import com.fdkankan.common.constant.CommonStatus;
 import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.model.constants.UploadFilePath;
 import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.scene.httpclient.MyClient;
 import com.fdkankan.web.response.ResultData;
 import com.fdkankan.common.util.DateExtUtil;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
@@ -67,6 +68,12 @@ import org.springframework.util.ObjectUtils;
 @RefreshScope
 public class SceneEditServiceImpl implements ISceneEditService {
 
+    @Value("${4dkk.manageService.basePath}")
+    private String manageServiceUrl;
+
+    @Value("${4dkk.manageService.api.getServiceUpTip}")
+    private String getServiceUpTipApi;
+
     @Autowired
     ISceneProService sceneProService;
     @Autowired
@@ -97,12 +104,13 @@ public class SceneEditServiceImpl implements ISceneEditService {
     @Value("${scene.expired.month:#{null}}")
     private Integer expiredMonth;
 
+    @Autowired
+    private MyClient myClient;
+
     @Override
     public SceneAuthVO getAuth(String num, SSOUser ssoUser){
 
         // 解密获得username,用于和数据库进行对比
-        String username = ssoUser.getUserName();
-
         ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
         if(Objects.isNull(scenePlus)){
             throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
@@ -111,15 +119,8 @@ public class SceneEditServiceImpl implements ISceneEditService {
 
         SceneAuthVO sceneAuthVO = new SceneAuthVO();
 
-        List<SceneResource> exclude = new ArrayList<>();
-        SceneResource excludeEntity = new SceneResource();
-        excludeEntity.setKeyWord("data");
-        exclude.add(excludeEntity);
-
-        Camera camera = cameraService.findByChildName(username);
-        sceneAuthVO.setExclude(exclude);
+        sceneAuthVO.setExclude(new ArrayList<>());
         sceneAuthVO.setInclude(new ArrayList<>());
-        sceneAuthVO.setCompany(null);
 
         //判断本地资源是否已本删除,如果已删除,前端根据字段值为true提示用户不能使用某些功能,需要重算
         Date algorithmTime = scenePlusExt.getAlgorithmTime() == null ? scenePlus.getCreateTime() : scenePlusExt.getAlgorithmTime();
@@ -128,106 +129,12 @@ public class SceneEditServiceImpl implements ISceneEditService {
         }
 
         //判断该场景是否属于增值权益
-        boolean isVip = false;
+        boolean isVip = true;
         //获取该相机是否有权益
         boolean isExpired  = false;
-        Camera sceneCamera = cameraService.getById(scenePlus.getCameraId());
-        if(sceneCamera != null){
-            UserIncrement userIncrementEntity = userIncrementService.findByCameraId(sceneCamera.getId());
-
-            if(userIncrementEntity != null){
-                if( userIncrementEntity.getIsExpired().intValue() == 0){
-                    isVip = true;
-                }
-                if(userIncrementEntity.getIsExpired().intValue() == 1){
-                    isExpired  = true;
-                }
-            }else{
-                try {
-                    Date date = DateUtil.parse("2021-09-09 00:00:00", DateExtUtil.dateStyle);
-
-                    //非07批次的放开
-                    String pc = sceneCamera.getSnCode().substring(0,2);
-                    if(!pc.equals("07") ){
-                        if(sceneCamera.getCreateTime()!=null && date.after(sceneCamera.getCreateTime())){
-                            isVip = true;
-                            isExpired  = false;
-                        }
-                    }
-                }catch (Exception e){
-                    e.printStackTrace();
-                }
-            }
-        }
-
         sceneAuthVO.setIsExpired(isExpired);
         sceneAuthVO.setIsVip(isVip);
 
-        //判断过期时间
-        Date date = DateUtil.parse(expectedTime, DateExtUtil.dateStyle);
-
-        if(camera != null){
-            if(!scenePlus.getCameraId().equals(camera.getId())){
-                throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
-            }
-
-            CameraDetail cameraDetailEntity = cameraDetailService.findByCameraId(camera.getId());
-            if(cameraDetailEntity.getCompanyId() != null){
-                if(cameraDetailEntity.getCompanyId().longValue() == 1 || cameraDetailEntity.getCompanyId().longValue() == 14){
-                    sceneAuthVO.setExclude(new ArrayList<>());
-                    sceneAuthVO.setCompany(cameraDetailEntity.getCompanyId());
-                }
-            }
-            return sceneAuthVO;
-        }
-
-        User user = userService.findByUserName(username);
-        if("18750226207".equals(username)){
-            log.info("18750226207该账号默认超级管理员,可以操作所有场景");
-        }
-        else if(user == null || scenePlus.getUserId() == null || user.getId().longValue() != scenePlus.getUserId().longValue()){
-            log.info("user:" + user.getId() + ",scene:" + scenePlus.getUserId());
-
-            List<SceneCooperation> list =
-                sceneCooperationService.list(
-                    new LambdaQueryWrapper<SceneCooperation>()
-                        .eq(SceneCooperation::getSceneNum, num));
-            if(list != null && list.size() > 0){
-                if(list.get(0).getUserId().longValue() != user.getId().longValue()){
-                    throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
-                }
-            }else {
-                throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
-            }
-        }
-
-        if(scenePlus.getCameraId() != null){
-            camera = cameraService.getById(scenePlus.getCameraId());
-            if(camera != null){
-                CameraDetail cameraDetail = cameraDetailService.findByCameraId(camera.getId());
-                if(cameraDetail.getCompanyId() != null){
-                    if(cameraDetail.getCompanyId().longValue() == 1 || cameraDetail.getCompanyId().longValue() == 14){
-                        sceneAuthVO.setExclude(new ArrayList<>());
-                        sceneAuthVO.setCompany(cameraDetail.getCompanyId());
-                    }
-                }
-            }
-        }
-
-        //权限控制完后判断若是协作账号,获取协作权限
-        SceneCooperation sceneCooperation = sceneCooperationService.getByNum(num);
-        //若数据为空表示可操作全部资源
-        if(sceneCooperation == null || sceneCooperation.getUserId().longValue() != ssoUser.getId().longValue()){
-            return sceneAuthVO;
-        }
-
-        if(scenePlus.getUserId()!= null && sceneCooperation.getUserId()!= null &&
-            scenePlus.getUserId().equals(sceneCooperation.getUserId())){
-            return sceneAuthVO;
-        }
-
-        sceneAuthVO.setInclude(sceneResourceService.findByCooperationId(sceneCooperation.getId()));
-
         return sceneAuthVO;
     }
 
@@ -309,4 +216,15 @@ public class SceneEditServiceImpl implements ISceneEditService {
         return ResultData.ok();
     }
 
+    @Override
+    public ResultData getServiceUpTip() {
+        try {
+            String url = this.manageServiceUrl.concat(this.getServiceUpTipApi);
+            String params = "type=" + 0;
+            ResultData resultData = myClient.get(url, params);
+            return ResultData.ok(resultData.getData());
+        }catch (Exception e){
+            return ResultData.ok();
+        }
+    }
 }

+ 181 - 0
src/main/java/com/fdkankan/scene/service/impl/SceneMarkShapeServiceImpl.java

@@ -0,0 +1,181 @@
+package com.fdkankan.scene.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.UUID;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+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.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import com.fdkankan.scene.entity.SceneMarkShape;
+import com.fdkankan.scene.mapper.MarkShapeMapper;
+import com.fdkankan.scene.service.ISceneMarkShapeService;
+import com.fdkankan.scene.util.ConverxyUtil;
+import com.fdkankan.scene.vo.SceneMarkShapeParamVO;
+import com.fdkankan.scene.vo.SceneMarkShapeReDetectParamVO;
+import com.fdkankan.web.response.ResultData;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * Created by Xiewj on 2021/11/23 0026 10:14
+ */
+@Slf4j
+@Service
+public class SceneMarkShapeServiceImpl extends ServiceImpl<MarkShapeMapper, SceneMarkShape> implements ISceneMarkShapeService {
+    @Autowired
+    private RabbitMqProducer rabbitMqProducer;
+    @Value("${queue.scene.yolov5-train-queue}")
+    private String yolov5TrainQueue;
+    @Value("${main.url}")
+    private String mainUrl;
+
+    @Override
+    public void editTrainStatus(SceneMarkShapeParamVO param) {
+        SceneMarkShape byNumAndImagePath = findByNumAndImagePath(param.getNum(), param.getImagePath());
+        if (ObjectUtil.isNotNull(byNumAndImagePath)){
+            byNumAndImagePath.setReTrain(0);
+            byNumAndImagePath.setToTrain(1);
+            updateById(byNumAndImagePath);
+        }
+    }
+
+    @Override
+    public List<SceneMarkShape> findByReTrainStatus(Integer reTrain){
+        LambdaQueryWrapper<SceneMarkShape> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(SceneMarkShape::getReTrain,reTrain);
+        return list(wrapper);
+    }
+
+    @Override
+    public List<SceneMarkShape> findByToTrainStatus(Integer toTrain) {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.select("DISTINCT num")
+                .eq("to_train",toTrain) ;
+        return getBaseMapper().selectList(queryWrapper);
+    }
+
+    @Override
+    public void trainScene(SceneMarkShapeReDetectParamVO param) {
+        //查询需要重新训练的图片
+        List<SceneMarkShape> reDetectStatuList = findByReTrainStatus(1);
+        for (SceneMarkShape shape : reDetectStatuList) {
+            SceneMarkShapeReDetectParamVO paramVO=new SceneMarkShapeReDetectParamVO();
+            paramVO.setWebSite(mainUrl);
+            if (StrUtil.isNotEmpty(param.getSaveDir())){
+                paramVO.setSaveDir(param.getSaveDir());
+            }
+            paramVO.setNum(shape.getNum());
+            paramVO.setImagePath(shape.getImagePath());
+            paramVO.setDetectType(1);
+            rabbitMqProducer.sendByWorkQueue(yolov5TrainQueue,paramVO);
+        }
+        //查询需要进入训练的场景
+        List<SceneMarkShape> byToDetectStatus = findByToTrainStatus(0);
+        for (SceneMarkShape shape : byToDetectStatus) {
+            SceneMarkShapeReDetectParamVO paramVO=new SceneMarkShapeReDetectParamVO();
+            paramVO.setWebSite(mainUrl);
+            if (StrUtil.isNotEmpty(param.getSaveDir())){
+                paramVO.setSaveDir(param.getSaveDir());
+            }
+            paramVO.setNum(shape.getNum());
+            paramVO.setDetectType(2);
+            rabbitMqProducer.sendByWorkQueue(yolov5TrainQueue,paramVO);
+        }
+    }
+
+    @Override
+    public ResultData editLabelByFile(String num, String imgPath, MultipartFile file) throws IOException {
+
+        SceneMarkShape shape = findByNumAndImagePath(num, imgPath);
+        if (ObjectUtil.isNotNull(shape)){
+            String uuid = UUID.randomUUID().toString();
+            String fileName = file.getOriginalFilename();
+            String extName = FileUtil.extName(fileName);
+            String tempFileName = uuid + "." + extName;
+            String srcPath = ConstantFilePath.SCENE_V4_PATH + num + "/markShapes/" + tempFileName;
+            File tempFile = new File(srcPath);
+            if(!tempFile.getParentFile().exists()){
+                tempFile.getParentFile().mkdirs();
+            }
+            file.transferTo(tempFile);
+
+            List<String> s = FileUtil.readUtf8Lines(tempFile);
+            List<JSONObject> shapeJsons=new ArrayList<>();
+            //转换labelimg标注处理的结果
+            log.info("转换labelimg标注处理的结果开始");
+            for (String s1 : s) {
+                int[] ints = ConverxyUtil.centerWh2xyxy(s1, 4096,2048);
+                String[] s2 = s1.split(" ");
+                JSONObject shapeJson=new JSONObject();
+                shapeJson.put("bbox",ints);
+                shapeJson.put("color",ConverxyUtil.getColor(s2[0]));
+                shapeJson.put("label",s1);
+                shapeJson.put("category",ConverxyUtil.getLabelVal(s2[0]));
+                shapeJson.put("score",0);
+                shapeJsons.add(shapeJson);
+            }
+            log.info("转换labelimg标注处理的结果结束,{}",shapeJsons);
+            shape.setShapes(shapeJsons);
+            shape.setReTrain(1);
+            shape.setUpdateTime(new Date());
+            updateById(shape);
+            return ResultData.ok(shape);
+        }else {
+            return ResultData.error(ErrorCode.NOT_RECORD);
+        }
+    }
+
+    @Override
+    public SceneMarkShape findByNumAndImagePath(String num, String imagePath) {
+        LambdaQueryWrapper<SceneMarkShape> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(SceneMarkShape::getNum,num);
+        wrapper.eq(SceneMarkShape::getImagePath,imagePath);
+        return getOne(wrapper);
+    }
+
+    @Override
+    public void saveFileToDB(MultipartFile file, String num) throws IOException {
+        String uuid = UUID.randomUUID().toString();
+        String fileName = file.getOriginalFilename();
+        String extName = cn.hutool.core.io.FileUtil.extName(fileName);
+        String tempFileName = uuid + "." + extName;
+        String srcPath = ConstantFilePath.SCENE_V4_PATH + num + "/markShapes/" + tempFileName;
+        File tempFile = new File(srcPath);
+        if(!tempFile.getParentFile().exists()){
+            tempFile.getParentFile().mkdirs();
+        }
+        file.transferTo(tempFile);
+        String s = FileUtil.readUtf8String(tempFile);
+        JSONObject jsonObject = JSONObject.parseObject(s);
+        tempFile.delete();
+        SceneMarkShape sceneMarkShape= JSON.toJavaObject(jsonObject,SceneMarkShape.class);
+        sceneMarkShape.setNum(num);
+        SceneMarkShape shape = findByNumAndImagePath(sceneMarkShape.getNum(), sceneMarkShape.getImagePath());
+        if (ObjectUtil.isNotNull(shape)){
+            log.info("shape-替换id修改---{}",sceneMarkShape);
+            sceneMarkShape.setId(shape.getId());
+            updateById(sceneMarkShape);
+        }else {
+            log.info("新增-替换id修改---{}",sceneMarkShape);
+            log.info("MarkShapeMapper---{}",sceneMarkShape);
+            save(sceneMarkShape);
+        }
+    }
+}

+ 2 - 2
src/main/java/com/fdkankan/scene/service/impl/ScenePlusServiceImpl.java

@@ -222,8 +222,8 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
         String outPathEn = ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+num+"_en.png";
 
         String webSize = "/" + sceneProNewUrl + num;
-        QrCodeUtil.generate(webSize, QrConfig.create().setImg(logoPath), FileUtil.file(outPathZh));
-        QrCodeUtil.generate(webSize + "&lang=en", QrConfig.create().setImg(logoPath), FileUtil.file(outPathEn));
+        QrCodeUtil.generate(webSize, QrConfig.create().setImg(logoPath).setWidth(512).setHeight(512), FileUtil.file(outPathZh));
+        QrCodeUtil.generate(webSize + "&lang=en", QrConfig.create().setImg(logoPath).setWidth(512).setHeight(512), FileUtil.file(outPathEn));
         //上传logo图片
         String ossLogoPath = String.format(UploadFilePath.DOWNLOADS_QRCODE, num) + "shareLogo" + extName;
         fYunFileService.uploadFile(scenePlusExt.getYunFileBucket(), logoPath, ossLogoPath);

+ 252 - 138
src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java

@@ -2,6 +2,7 @@ package com.fdkankan.scene.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.RuntimeUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.ZipUtil;
 import com.alibaba.fastjson.JSON;
@@ -10,12 +11,9 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fdkankan.common.constant.CommonStatus;
+import com.fdkankan.common.constant.*;
 import com.fdkankan.model.constants.ConstantFileName;
 import com.fdkankan.model.constants.ConstantFilePath;
-import com.fdkankan.common.constant.ErrorCode;
-import com.fdkankan.common.constant.FileBizType;
-import com.fdkankan.common.constant.ServerCode;
 import com.fdkankan.model.constants.UploadFilePath;
 import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.web.response.ResultData;
@@ -56,15 +54,9 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
 import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Set;
 import java.util.stream.Collectors;
 import lombok.extern.slf4j.Slf4j;
 import org.redisson.Redisson;
@@ -199,11 +191,15 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         if (scenePlus == null)
             throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
         ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+        String bucket = scenePlusExt.getYunFileBucket();
 
         List<String> deleteSidList = param.getSidList();
 
         //处理删除状态数据
-        this.deleteHotData(param.getNum(), deleteSidList, scenePlusExt.getYunFileBucket());
+        this.deleteHotData(param.getNum(), deleteSidList, bucket);
+
+        //删除导览中的热点数据
+        this.deleteHotDataFromTourJson(param.getNum(), param.getSidList(), bucket);
 
         //写入本地文件,作为备份
         this.writeHotJson(param.getNum());
@@ -216,6 +212,31 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         return ResultData.ok();
     }
 
+    private void deleteHotDataFromTourJson(String num, List<String> sidList, String bucket){
+        String key = String.format(UploadFilePath.USER_EDIT_PATH, num) + "tour.json";
+        String tourJson = fYunFileService.getFileContent(bucket, key);
+        if(StrUtil.isEmpty(tourJson)){
+            return;
+        }
+        JSONArray jsonArray = JSON.parseArray(tourJson);
+        if(CollUtil.isEmpty(jsonArray)){
+            return;
+        }
+        jsonArray.stream().forEach(tour->{
+            JSONObject obj = (JSONObject) tour;
+            JSONArray itemArra = obj.getJSONArray("list");
+            itemArra.stream().forEach(item->{
+                JSONObject itemObj = (JSONObject) item;
+                String tagId = itemObj.getString("tagId");
+                if(tagId != null && sidList.contains(tagId)){
+                    itemObj.remove("tagId");
+                }
+            });
+        });
+        fYunFileService.uploadFile(bucket, jsonArray.toJSONString().getBytes(StandardCharsets.UTF_8), key);
+
+    }
+
     @Override
     public ResultData deleteIcons(DeleteHotIconParamVO param) throws Exception {
 
@@ -628,14 +649,11 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
             editInfo.setScenePlusId(scenePlus.getId());
             sceneEditInfoService.save(editInfo);
         }else{
-            sceneEditInfoService.upgradeVersionById(editInfo.getId());
+            sceneEditInfoService.upgradeVersionAndImgVersionById(editInfo.getId());
             //更新scenejson缓存和oss文件版本号
-            sceneEditInfoService.upgradeSceneJsonVersion(param.getNum(), editInfo.getVersion() + 1, null, bucket);
+            sceneEditInfoService.upgradeSceneJsonVersion(param.getNum(), editInfo.getVersion() + 1, editInfo.getImgVersion() + 1, bucket);
         }
 
-        //更新scene.json版本号
-//        sceneEditInfoService.upgradeVersionToSceneJson(param.getNum());
-
         return ResultData.ok();
     }
 
@@ -662,29 +680,12 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
         String bucket = scenePlusExt.getYunFileBucket();
 
-        //文件上传的位置可以自定义
-        String path = scenePlusExt.getDataSource() + "_obj2txt";
-        String zipPath = path + "/zip/";
-        String filePath =  path + "/extras/";
-        String resultPath = path + "/results/";
-
-        //压缩文件处理:解压缩,解压缩后复制等操作
-        this.objAndImgFileHandler(resultPath, filePath, zipPath, file);
-
-        //创建data.json
-        this.writeDataJson(path);
-
-        //调用算法,不同的类型调用不同的算法
-        if("V2".equals(scenePlusExt.getBuildType())){
-            CreateObjUtil.objToTxt(path , "1");
-        }
-        if("V3".equals(scenePlusExt.getBuildType())){
-            CreateObjUtil.build3dModel(path , "1");
+        if(ModelKind.THREE_D_TILE.code().equals(scenePlusExt.getModelKind())){
+            this.buildModel43dtiles(num, bucket, scenePlusExt.getDataSource(), file);
+        }else{
+            this.buildModel4Dam(num, bucket, scenePlusExt.getDataSource(), scenePlusExt.getBuildType(), file);
         }
 
-        //算法计算完后,生成压缩文件,上传到oss
-        this.uploadFileofterRebuildPanoram(path, num, bucket);
-
         //更新版本信息
         SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
         if(Objects.isNull(sceneEditInfo)){
@@ -704,12 +705,144 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
                     .set(SceneEditInfo::getIsUploadObj, CommonStatus.YES.code())
                     .eq(SceneEditInfo::getId, sceneEditInfo.getId()));
 
-            sceneEditInfoService.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1, bucket);        }
+            sceneEditInfoService.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1, bucket);
+        }
 
         return ResultData.ok();
     }
 
-    private void uploadFileofterRebuildPanoram(String path, String sceneNum, String bucket) throws Exception {
+    /**
+     * 老算法(dam)上传模型逻辑
+     * @param num
+     * @param bucket
+     * @param dataSource
+     * @param buildType
+     * @throws Exception
+     */
+    private void buildModel4Dam(String num, String bucket, String dataSource, String buildType, MultipartFile file) throws Exception {
+        //文件上传的位置可以自定义
+        String path = dataSource + "_obj2txt";
+        String zipPath = path + "/zip/";
+        String filePath =  path + "/extras/";
+        String resultPath = path + "/results/";
+
+        //压缩文件处理:解压缩,解压缩后复制等操作
+        this.objAndImgFileHandler(resultPath, filePath, zipPath, file);
+
+        //创建data.json
+        this.writeDataJson(path);
+
+        //调用算法,不同的类型调用不同的算法
+        if("V2".equals(buildType)){
+            CreateObjUtil.objToTxt(path , "1");
+        }
+        if("V3".equals(buildType)){
+            CreateObjUtil.build3dModel(path , "1");
+        }
+
+        //算法计算完后,生成压缩文件,上传到oss
+        this.uploadFileofterRebuildPanoram(path, filePath, num, bucket);
+    }
+
+    /**
+     * 新算法(3dtiles)上传模型逻辑
+     * @param num
+     * @param bucket
+     * @param dataSource
+     * @throws Exception
+     */
+    private void buildModel43dtiles(String num, String bucket, String dataSource, MultipartFile file) throws Exception {
+        //文件上传的位置可以自定义
+        String path = dataSource + "_obj2Tiles" + File.separator;
+        String meshPath = path  + "mesh";
+        String zipPath = path + "zip" + File.separator;
+        String zipFilePath = zipPath + file.getOriginalFilename();
+
+
+        //压缩文件处理:解压缩,解压缩后复制等操作
+        FileUtil.del(path);
+        FileUtil.mkdir(zipPath);
+        File zipFile = new File(zipFilePath);
+        file.transferTo(zipFile);
+        ZipUtil.unzip(zipFilePath, meshPath);
+
+        //检测文件
+        String floorsJsonPath = meshPath + File.separator + "floors.json";
+        if(!FileUtil.exist(floorsJsonPath)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5068);
+        }
+        String floorsJsonStr = FileUtil.readUtf8String(floorsJsonPath);
+        JSONObject floorsJsonObj = JSON.parseObject(floorsJsonStr);
+        JSONArray floorArr = floorsJsonObj.getJSONArray("floors");
+        if(CollUtil.isEmpty(floorArr)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5069);
+        }
+        Set<String> floorNameSet = new HashSet<>();
+        floorArr.stream().forEach(item->{
+            JSONObject itemObj = (JSONObject) item;
+            //楼层目录是否存在
+            String name = itemObj.getString("name");
+            if(StrUtil.isEmpty(name) || !FileUtil.exist(meshPath + File.separator + name)){
+                throw new BusinessException(ErrorCode.FAILURE_CODE_5070);
+            }
+            //检测obj文件是否存在
+            String objPath = itemObj.getString("objPath");
+            if(StrUtil.isEmpty(objPath) || !FileUtil.exist(path + objPath)){
+                throw new BusinessException(ErrorCode.FAILURE_CODE_5070);
+            }
+            if(floorNameSet.contains(name)){
+                throw new BusinessException(ErrorCode.FAILURE_CODE_5069);
+            }
+            floorNameSet.add(name);
+        });
+
+        //读取oss上的floors.jsoon用于校验用户上传的模型楼层数是否一一对应
+        String ossFloorsJson = fYunFileService.getFileContent(bucket, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh/floors.json");
+        JSONObject orginFloorsJsonObj = JSON.parseObject(ossFloorsJson);
+        JSONArray orginFloorArr = orginFloorsJsonObj.getJSONArray("floors");
+        Set<String> orginFloorNameSet = orginFloorArr.stream().map(item -> {
+            JSONObject itemObj = (JSONObject) item;
+            return itemObj.getString("name");
+        }).collect(Collectors.toSet());
+        if(floorNameSet.size() != orginFloorNameSet.size()){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5070);
+        }
+        orginFloorNameSet.stream().forEach(orginName->{
+            if(!floorNameSet.contains(orginName)){
+                throw new BusinessException(ErrorCode.FAILURE_CODE_5070);
+            }
+        });
+
+
+        //调用算法
+        String command = "bash /home/ubuntu/bin/Obj2Tiles.sh " + path;
+        log.info("上传3dtiles模型开始, num:{}, targetPath:{}", num, path);
+//        RuntimeUtil.exec(command);
+        CreateObjUtil.callshell(command);
+        log.info("上传3dtiles模型结束, num:{}, targetPath:{}", num, path);
+
+        //检测计算结果
+        String tilesPath = path + "3dtiles";
+        String tilesetJsonPath = tilesPath + File.separator + "tileset.json";
+        boolean success = ComputerUtil.checkComputeCompleted(tilesetJsonPath, maxCheckTimes, waitTime);
+        if(!success){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
+        }
+
+        //删除logs
+        FileUtil.del(tilesPath + File.separator + "logs");
+
+        //算法计算完后,生成压缩文件,上传到oss
+        //上传3dtiles
+        fYunFileService.deleteFolder(bucket, String.format(UploadFilePath.IMG_VIEW_PATH, num) + "3dtiles");
+        fYunFileService.uploadFileByCommand(bucket, tilesPath, String.format(UploadFilePath.IMG_VIEW_PATH, num) + "3dtiles");
+        //上传mesh
+        fYunFileService.deleteFolder(bucket, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh");
+        fYunFileService.uploadFileByCommand(bucket, meshPath, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh");
+
+    }
+
+    private void uploadFileofterRebuildPanoram(String path, String filePath, String sceneNum, String bucket) throws Exception {
         //因为共享目录有延迟,这里循环检测算法是否计算完毕3次,每次隔五秒
         String uploadJsonPath = path + File.separator + "results" +File.separator+"upload.json";
         boolean exist = ComputerUtil.checkComputeCompleted(uploadJsonPath, maxCheckTimes, waitTime);
@@ -744,12 +877,24 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
             }
         }
 
-        CreateObjUtil.convertTxtToDam( path + File.separator + "results" +File.separator+"modeldata.txt", path + File.separator + "results" +File.separator+ ConstantFileName.modelUUID+"_50k.dam");
-        CreateObjUtil.convertDamToLzma(path + File.separator + "results");
-        CreateObjUtil.convertTxtToDam( path + File.separator + "results" +File.separator+"modeldata.txt", path + File.separator + "results" + File.separator+ConstantFileName.modelUUID+"_50k.dam");
-        map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam.lzma", imgViewPath +ConstantFileName.modelUUID+"_50k.dam.lzma");
+        String damPath = path + File.separator + "results" +File.separator+ ConstantFileName.modelUUID+"_50k.dam";
+        CreateObjUtil.convertTxtToDam( path + File.separator + "results" +File.separator+"modeldata.txt", damPath);
+        boolean existDam = ComputerUtil.checkComputeCompleted(damPath, 5, 2);
+        if(!existDam){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
+        }
+//        CreateObjUtil.convertDamToLzma(path + File.separator + "results");
+//        CreateObjUtil.convertTxtToDam( path + File.separator + "results" +File.separator+"modeldata.txt", path + File.separator + "results" + File.separator+ConstantFileName.modelUUID+"_50k.dam");
+//        map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam.lzma", imgViewPath +ConstantFileName.modelUUID+"_50k.dam.lzma");
         map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam", imgViewPath+ConstantFileName.modelUUID+"_50k.dam");
 
+        String ossMeshPath = String.format(UploadFilePath.DATA_VIEW_PATH, sceneNum) + "mesh";
+        //删除oss中的mesh
+        fYunFileService.deleteFolder(bucket, ossMeshPath);
+        //上传obj相关文件
+        List<String> fileNames = FileUtil.listFileNames(filePath);
+        fileNames.stream().forEach(name->map.put(filePath + name, ossMeshPath + File.separator + name));
+
         fYunFileService.uploadMulFiles(bucket, map);
     }
 
@@ -874,105 +1019,77 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
 
         SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
 
+        if(ModelKind.THREE_D_TILE.code().equals(scenePlusExt.getModelKind())){
+            return this.downloadModel43dtiles(num, bucket, scenePlusExt, sceneEditInfo);
+        }
+
+        return this.downloadModel4Dam(num, bucket);
+    }
+
+    @Override
+    public ScenePro getByNum(String num) {
+        return this.getOne(new LambdaQueryWrapper<ScenePro>().eq(ScenePro::getNum, num));
+    }
+
+    private ResultData downloadModel43dtiles(String num, String bucket, ScenePlusExt scenePlusExt, SceneEditInfo sceneEditInfo){
+
+        //下载mesh到本地
+        String meshOssPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh/";
+        String meshLocalPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, num) + "mesh";
+        String zipName = num + "_mesh.zip";
+        String zipFilePath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, num) + zipName;
+        //下载
+        fYunFileService.downloadFileByCommand(bucket, meshLocalPath, meshOssPath);
+        //打包
+        ZipUtil.zip(meshLocalPath,zipFilePath);
+        //上传压缩包
+        fYunFileService.uploadFile(bucket, zipFilePath, "downloads/extras/" + zipName);
+        //删除本地文件
+        FileUtil.del(meshLocalPath);
+        FileUtil.del(zipFilePath);
+        String url = ossUrlPrefix + "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
+        return ResultData.ok(url);
+    }
+
+    public static void main(String[] args) {
+
+        ZipUtil.zip("C:\\Users\\dsx\\Desktop\\新建文件夹\\temp\\mesh\\aaa\\mesh", "C:\\Users\\dsx\\Desktop\\新建文件夹\\temp\\mesh\\aaa\\mesh\\mesh.zip");
+        System.out.println(123);
+    }
+
+
+    private ResultData downloadModel4Dam(String num, String bucket){
         String localImagePath = String.format(ConstantFilePath.IMAGESBUFFER_FORMAT, num);
         if(!new File(localImagePath).exists()){
             new File(localImagePath).mkdirs();
         }
 
-
-        String newData =  scenePlusExt.getDataSource() + "_obj2txt/extras";
-        String newResultData = scenePlusExt.getDataSource() + "_obj2txt/results/upload.json";
         String zipName = num + "_extras.zip";
         String zipPath = localImagePath + zipName;
-        //如果用户上传过模型,就打包上传到oss,直接返回
-        if(CommonStatus.YES.code().equals(sceneEditInfo.getIsUploadObj())
-            && new File(newData).exists()
-            && new File(newResultData).exists()){
-            //打包
-            ZipUtil.zip(newData, zipPath);
-            //上传压缩包
-            fYunFileService.uploadFile(bucket, zipPath, "downloads/extras/" + zipName);
-            String url = ossUrlPrefix + "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
-            return ResultData.ok(url);
-        }
 
-
-        String buildType = scenePlusExt.getBuildType();
-        if("V3".equals(buildType)){
-            String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
-            //V3版本去oss下载2048模型
-            String meshPath =  String.format(ConstantFilePath.DATABUFFER_FORMAT, num) + "mesh";
-            FileUtils.deleteDirectory(meshPath);
-            fYunFileService.downloadFileByCommand(bucket, meshPath, dataViewPath + "mesh");
-            log.info("meshPath="+meshPath);
-            if(!new File(meshPath).exists()){
-                throw new BusinessException(ErrorCode.FAILURE_CODE_7006);
-            }
-            log.info(new File(meshPath).listFiles().toString());
-            if(new File(meshPath).listFiles().length > 0){
-                for(File file : new File(meshPath).listFiles()){
-                    if(file.isDirectory()){
-                        for (File item : file.listFiles()) {
-                            if(item.getName().endsWith(".obj") && !"output.house.obj".equals(item.getName()) &&
-                                !"mesh.obj".equals(item.getName())){
-                                item.delete();
-                            }
-                            if(item.getName().endsWith(".mtl") && !"output.house.mtl".equals(item.getName()) &&
-                                !"mesh.mtl".equals(item.getName())){
-                                item.delete();
-                            }
-                        }
-                        continue;
-                    }
-                    if(file.getName().endsWith(".obj") && !"output.house.obj".equals(file.getName()) &&
-                            !"mesh.obj".equals(file.getName())){
-                        file.delete();
+        String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
+        //V3版本去oss下载2048模型
+        String meshPath =  String.format(ConstantFilePath.DATABUFFER_FORMAT, num) + "mesh";
+        FileUtils.deleteDirectory(meshPath);
+        fYunFileService.downloadFileByCommand(bucket, meshPath, dataViewPath + "mesh");
+        log.info("meshPath="+meshPath);
+        if(!new File(meshPath).exists() || new File(meshPath).listFiles().length < 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7006);
+        }
+        for(File file : new File(meshPath).listFiles()){
+            if(file.isDirectory()){
+                for (File item : file.listFiles()) {
+                    if(item.getName().endsWith(".obj") && !"output.house.obj".equals(item.getName()) &&
+                            !"mesh.obj".equals(item.getName())){
+                        item.delete();
                     }
-                    if(file.getName().endsWith(".mtl") && !"output.house.mtl".equals(file.getName()) &&
-                            !"mesh.mtl".equals(file.getName())){
-                        file.delete();
+                    if(item.getName().endsWith(".mtl") && !"output.house.mtl".equals(item.getName()) &&
+                            !"mesh.mtl".equals(item.getName())){
+                        item.delete();
                     }
                 }
-                //打包
-                ZipUtil.zip(meshPath, zipPath);
-                //上传压缩包
-                fYunFileService.uploadFile(bucket, zipPath, "downloads/extras/" + zipName);
-                String url = ossUrlPrefix + "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
-                FileUtil.del(zipPath);
-                return ResultData.ok(url);
-            }
-        }
-
-        //V2版本在本地获取模型资源
-        //修改过的资源
-        String editData =  scenePlusExt.getDataSource() + "_edit/caches/tex";
-        String results = scenePlusExt.getDataSource() + "_edit/results";
-        if (new File(editData).exists() && new File(results).exists()){
-            for(File file : new File(editData).listFiles()){
-                if(file.getName().endsWith(".obj") && !"output.house.obj".equals(file.getName()) &&
-                        !"mesh.obj".equals(file.getName())){
-                    file.delete();
-                }
-                if(file.getName().endsWith(".mtl") && !"output.house.mtl".equals(file.getName()) &&
-                        !"mesh.mtl".equals(file.getName())){
-                    file.delete();
-                }
+                continue;
             }
-
-            ZipUtil.zip(editData, zipPath);
-            //上传压缩包
-            fYunFileService.uploadFile(bucket, zipPath, "downloads/extras/" + zipName);
-            String url = ossUrlPrefix + "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
-            return ResultData.ok(url);
-        }
-
-        //没上传过返回源资源
-        String dataPath = scenePlusExt.getDataSource() + "/caches/tex";
-        File dataFile = new File(dataPath);
-        if(!dataFile.exists()){
-            throw new BusinessException(ErrorCode.FAILURE_CODE_3018);
-        }
-        for(File file : dataFile.listFiles()){
             if(file.getName().endsWith(".obj") && !"output.house.obj".equals(file.getName()) &&
                     !"mesh.obj".equals(file.getName())){
                 file.delete();
@@ -982,16 +1099,13 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
                 file.delete();
             }
         }
-
-        ZipUtil.zip(dataPath, zipPath);
+        //打包
+        ZipUtil.zip(meshPath, zipPath);
         //上传压缩包
         fYunFileService.uploadFile(bucket, zipPath, "downloads/extras/" + zipName);
         String url = ossUrlPrefix + "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
+        FileUtil.del(zipPath);
         return ResultData.ok(url);
     }
 
-    @Override
-    public ScenePro getByNum(String num) {
-        return this.getOne(new LambdaQueryWrapper<ScenePro>().eq(ScenePro::getNum, num));
-    }
 }

+ 169 - 0
src/main/java/com/fdkankan/scene/service/impl/SceneServiceImpl.java

@@ -0,0 +1,169 @@
+package com.fdkankan.scene.service.impl;
+
+import cn.hutool.core.img.ImgUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.UUID;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.fdkankan.common.constant.CommonOperStatus;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.util.DateExtUtil;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.fyun.config.FYunFileConfig;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.scene.bean.BodySegmentStatusBean;
+import com.fdkankan.scene.service.ISceneService;
+import com.fdkankan.scene.util.OssBodySegmentUtil;
+import com.fdkankan.web.response.ResultData;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+import sun.rmi.runtime.Log;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+@Slf4j
+@Service("sceneService")
+public class SceneServiceImpl implements ISceneService {
+
+    @Value("${queue.bodySegment:body-segment}")
+    private String queueName;
+    @Value("${oss.bodySegment.bucket:4dkankan-huadong}")
+    private String bodySegmentBucket;
+    @Value("${oss.bodySegment.point:oss-cn-shanghai.aliyuncs.com}")
+    private String bodySegmentHost;
+
+    @Autowired
+    private OssBodySegmentUtil ossBodySegmentUtil;
+    @Autowired
+    private RedisUtil redisUtil;
+    @Autowired
+    private RabbitMqProducer rabbitMqProducer;
+    @Autowired
+    private FYunFileServiceInterface fYunFileService;
+    @Autowired
+    public FYunFileConfig fYunFileConfig;
+
+    @Override
+    public ResultData uploadBodySegment(MultipartFile file, Integer rotate) throws Exception {
+
+        if(!FileUtils.checkFileSizeIsLimit(file.getSize(), 10, "M")){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_4003, "10M");
+        }
+
+        String uuid = UUID.randomUUID().toString();
+
+        String fileName = file.getOriginalFilename();
+        String extName = fileName.substring(fileName.lastIndexOf("."));
+        File tempFile = File.createTempFile(uuid, extName);
+        file.transferTo(tempFile);
+
+        //判断是否需要旋转
+        if(Objects.nonNull(rotate)){
+            Image rotateImg = ImgUtil.rotate(ImageIO.read(tempFile), rotate);
+            File tempRotateFile = File.createTempFile(uuid + "-rotate", extName);
+            ImgUtil.write(rotateImg, tempRotateFile);
+            tempFile = tempRotateFile;
+        }
+
+        //校验像素
+        BufferedImage bufferedImage = ImgUtil.read(tempFile.getPath());
+        Float scale = 1F;
+        Float widthScale = 1F;
+        Float heightScale = 1F;
+        int width = bufferedImage.getWidth();
+        int height = bufferedImage.getHeight();
+        if(width > 2000){
+            widthScale = new BigDecimal(2000).divide(new BigDecimal(width),5, BigDecimal.ROUND_DOWN).floatValue();
+        }
+        if(height > 2000){
+            heightScale = new BigDecimal(2000).divide(new BigDecimal(height),5, BigDecimal.ROUND_DOWN).floatValue();
+        }
+        scale = widthScale > heightScale ? heightScale : widthScale;
+        ImgUtil.scale(new File(tempFile.getPath()), new File(tempFile.getPath()), scale);
+
+        String orgImgOssPath = "body_segment/original/" + tempFile.getName();
+        ossBodySegmentUtil.uploadOss(tempFile.getPath(), orgImgOssPath);
+//        fYunFileService.uploadFile(bodySegmentBucket, tempFile.getPath(), orgImgOssPath);
+
+        BodySegmentStatusBean bodySegmentStatusBean = BodySegmentStatusBean.builder().uuid(uuid).status(CommonOperStatus.WAITING.code()).build();
+        redisUtil.set(String.format(RedisKey.SCENE_BODY_SEGMENT, uuid), JSON.toJSONString(bodySegmentStatusBean), RedisKey.CAMERA_EXPIRE_7_TIME);
+
+        Map<String, String> map = new HashMap<>();
+        map.put("uuid", uuid);
+        map.put("imgUrl", "https://" +  bodySegmentBucket + "." + bodySegmentHost + "/" + orgImgOssPath);
+        rabbitMqProducer.sendByWorkQueue(queueName, map);
+
+        return ResultData.ok(uuid);
+    }
+
+    public static void main(String[] args) throws IOException {
+        Image rotateImg = ImgUtil.rotate(ImageIO.read(FileUtil.file("C:\\Users\\dsx\\Desktop\\IMG_6633.HEIC.JPG")), 90);
+        ImgUtil.write(rotateImg, FileUtil.file("C:\\Users\\dsx\\Desktop\\IMG_6633.HEIC_2.JPG"));
+    }
+
+    @Override
+    public void bodySegmentHandler(String imgUrl, String uuid) {
+        String progress = redisUtil.hget(RedisKey.SCENE_BODY_SEGMENT, uuid);
+        BodySegmentStatusBean bodySegmentStatusBean = null;
+        try {
+            if(StrUtil.isEmpty(progress)){
+                bodySegmentStatusBean = JSON.parseObject(progress, BodySegmentStatusBean.class);
+            }
+            if(Objects.isNull(bodySegmentStatusBean)){
+                bodySegmentStatusBean = new BodySegmentStatusBean();
+                bodySegmentStatusBean.setUuid(uuid);
+            }
+            String dir = ConstantFilePath.BASE_PATH + "/bodySegment/" +
+                    DateExtUtil.format(Calendar.getInstance().getTime(), DateExtUtil.dateStyle6);
+            String fileName = uuid + ".png";
+            String imgPath = dir + "/" + fileName;
+            ossBodySegmentUtil.extracted(imgUrl, dir, fileName);
+            if(!FileUtil.exist(imgPath)){
+                throw new Exception("提取图片失败");
+            }
+            String targetOssImgPath = "body_segment/segment/" + uuid + ".png";
+            fYunFileService.uploadFile(imgPath, targetOssImgPath);
+            bodySegmentStatusBean.setStatus(CommonOperStatus.SUCCESS.code());
+            bodySegmentStatusBean.setImageUrl(fYunFileConfig.getHost() + targetOssImgPath);
+            redisUtil.set(String.format(RedisKey.SCENE_BODY_SEGMENT, uuid), JSON.toJSONString(bodySegmentStatusBean), RedisKey.CAMERA_EXPIRE_7_TIME);
+        } catch (Exception e) {
+            bodySegmentStatusBean.setStatus(CommonOperStatus.FAILD.code());
+            redisUtil.set(String.format(RedisKey.SCENE_BODY_SEGMENT, uuid), JSON.toJSONString(bodySegmentStatusBean), RedisKey.CAMERA_EXPIRE_7_TIME);
+        }finally {
+            try {
+                //免费版qps不能大于2,故休眠一秒
+                Thread.sleep(1000L);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Override
+    public ResultData getBodySegmentStatus(String uuid) {
+
+        String progress = redisUtil.get(String.format(RedisKey.SCENE_BODY_SEGMENT, uuid));
+        if(StrUtil.isEmpty(progress)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5038);
+        }
+        BodySegmentStatusBean bodySegmentStatusBean = JSON.parseObject(progress, BodySegmentStatusBean.class);
+        return ResultData.ok(bodySegmentStatusBean);
+    }
+}

+ 20 - 0
src/main/java/com/fdkankan/scene/service/impl/UserRoleServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fdkankan.scene.service.impl;
+
+import com.fdkankan.scene.entity.UserRole;
+import com.fdkankan.scene.mapper.IUserRoleMapper;
+import com.fdkankan.scene.service.IUserRoleService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 用户角色关系表 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2023-01-03
+ */
+@Service
+public class UserRoleServiceImpl extends ServiceImpl<IUserRoleMapper, UserRole> implements IUserRoleService {
+
+}

+ 121 - 0
src/main/java/com/fdkankan/scene/util/ConverxyUtil.java

@@ -0,0 +1,121 @@
+package com.fdkankan.scene.util;
+
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.fastjson.JSONObject;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Xiewj
+ * @date 2023/4/11
+ */
+public class ConverxyUtil {
+   static Map<String,String> label=new HashMap<>();
+   static Map<String,int[]> color=new HashMap<>();
+
+   static void init() {
+      label.put("0","cabinet");
+      label.put("1","air");
+      label.put("2","battery");
+
+      color.put("0",new int[]{56,56,255});
+      color.put("1",new int[]{151,157,255});
+      color.put("2",new int[]{31,112,255});
+   }
+   public static String getLabelVal(String key) {
+      if (label.size()==0){
+         init();
+      }
+      //标签类型初始化
+     return label.get(key);
+   }
+   public static int[] getColor(String key) {
+      if (color.size()==0){
+         init();
+      }
+      //标签类型初始化
+      return color.get(key);
+   }
+      // 将中心宽高格式转换为左上角点和右下角点格式
+   /**
+    * 将xywh格式的目标框转换为xyxy格式
+    * @param xywh xywh格式的目标框,格式为"x,y,w,h"
+    * @return xyxy格式的目标框,格式为"x1,y1,x2,y2"
+    */
+   public static int[] centerWh2xyxy(String xywh,int w1,int h1){
+      String[] values = xywh.split(" ");
+      if (values.length<4){
+         return null;
+      }
+      float x = Float.parseFloat(values[1]);
+      float y = Float.parseFloat(values[2]);
+      float w = Float.parseFloat(values[3]);
+      float h = Float.parseFloat(values[4]);
+      int[] xyxy = new int[4];
+      xyxy[0] = (int) ((x - w / 2) * w1); // x1
+      xyxy[1] = (int) ((y - h / 2)* h1); // y1
+      xyxy[2] = (int) ((x + w / 2)* w1); // x2
+      xyxy[3] = (int) ((y+ h / 2)* h1); // y2
+      return xyxy;
+   }
+
+   // 将左上角点和右下角点格式转换为中心宽高格式
+   public static double[] xyxy2centerWh(int x1, int y1, int x2, int y2,int w1,int h1){
+
+      double[] centerWh = new double[4];
+      BigDecimal dx1=BigDecimal.valueOf(x1);
+      BigDecimal  dy1=BigDecimal.valueOf(y1);
+      BigDecimal  dx2=BigDecimal.valueOf(x2);
+      BigDecimal dy2= BigDecimal.valueOf(y2);
+      BigDecimal  dw1=BigDecimal.valueOf(w1);
+      BigDecimal  dh1=BigDecimal.valueOf(h1);
+
+
+      centerWh[0] =((dx1.add(dx2)).divide(BigDecimal.valueOf(2))).divide(dw1).doubleValue(); // centerX
+      centerWh[1] = ((dy1.add(dy2)).divide(BigDecimal.valueOf(2))).divide(dh1).doubleValue(); // centerX
+      centerWh[2] = dx2.subtract(dx1).divide(dw1).doubleValue(); // width
+      centerWh[3] =  dy2.subtract(dy1).divide(dh1).doubleValue(); // width
+
+      return centerWh;
+   }
+   public static void main(String[] args) {
+      // 中心宽高格式转换为左上角点和右下角点格式
+//      int[] xyxy = ConverxyUtil.centerWh2xyxy("0.215149 0.557373 0.067749 0.329590",8192,4096);
+//
+//      System.out.println("x1=" + xyxy[0] + ", y1=" + xyxy[1] + ", x2=" + xyxy[2] + ", y2=" + xyxy[3]);
+//
+//      // 左上角点和右下角点格式转换为中心宽高格式
+//      double[] centerWh = ConverxyUtil.xyxy2centerWh(xyxy[0], xyxy[1], xyxy[2], xyxy[3],8192,4096);
+//      System.out.println("centerX=" + centerWh[0] + ", centerY=" + centerWh[1] + ", width=" + centerWh[2] + ", height=" + centerWh[3]);
+//      int[] xyxy1 = ConverxyUtil.centerWh2xyxy("0.21514892578125 0.5572509765625 0.0677490234375 0.329833984375",8192,4096);
+//      System.out.println("x1=" + xyxy1[0] + ", y1=" + xyxy1[1] + ", x2=" + xyxy1[2] + ", y2=" + xyxy1[3]);
+//
+////      Object labelVal = ConverxyUtil.getLabelVal("1");
+////      System.out.println(labelVal);
+
+      File tempFile=new File("C:\\Users\\4DAGE\\Downloads\\KK-UR4UGMSHEK3\\images\\0.txt");
+      List<String> s = FileUtil.readUtf8Lines(tempFile);
+
+
+      List<JSONObject> shapeJsons=new ArrayList<>();
+      //转换labelimg标注处理的结果
+      for (String s1 : s) {
+         int[] ints = ConverxyUtil.centerWh2xyxy(s1, 4096,2048);
+         String[] s2 = s1.split(" ");
+         JSONObject shapeJson=new JSONObject();
+         shapeJson.put("bbox",ints);
+         shapeJson.put("color",ConverxyUtil.getColor(s2[0]));
+         shapeJson.put("label",s1);
+         shapeJson.put("category",ConverxyUtil.getLabelVal(s2[0]));
+         shapeJson.put("score",0);
+         shapeJsons.add(shapeJson);
+      }
+      System.out.println(shapeJsons);
+   }
+}

+ 98 - 0
src/main/java/com/fdkankan/scene/util/OssBodySegmentUtil.java

@@ -0,0 +1,98 @@
+package com.fdkankan.scene.util;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.http.HttpUtil;
+import com.aliyun.imageseg20191230.models.SegmentBodyResponse;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.tea.TeaException;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.scene.httpclient.MyClient;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.File;
+
+@Slf4j
+@Component
+@RefreshScope
+public class OssBodySegmentUtil {
+
+    @Value("${oss.bodySegment.point:oss-cn-shanghai.aliyuncs.com}")
+    private String endPoint;
+
+    @Value("${oss.bodySegment.imagesegPoint:imageseg.cn-shanghai.aliyuncs.com}")
+    private String imagesegEndPoint;
+
+    @Value("${fyun.key}")
+    private String accessKeyId;
+
+    @Value("${fyun.secret}")
+    private String accessKeySecret;
+
+    @Value("${oss.bodySegment.bucket:4dkankan-huadong}")
+    private String bucket;
+
+    @Resource
+    private MyClient myClient;
+
+    public void uploadOss(String filePath, String key){
+        OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
+        try {
+            File file = new File(filePath);
+            if (!file.exists()) {
+                log.error("要上传的文件不存在:" + filePath);
+                return;
+            }
+            ossClient.putObject(bucket, key, new File(filePath));
+        } catch (Exception e) {
+            log.error(e.toString() + filePath);
+        } finally {
+            ossClient.shutdown();
+        }
+    }
+
+    public void extracted(String imageUrl, String dir, String fileName) throws Exception {
+        try {
+            com.aliyun.imageseg20191230.Client client = this.createClient();
+            com.aliyun.imageseg20191230.models.SegmentBodyRequest segmentBodyRequest =
+                    new com.aliyun.imageseg20191230.models.SegmentBodyRequest().setImageURL(imageUrl);
+            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
+            // 复制代码运行请自行打印 API 的返回值
+            SegmentBodyResponse segmentBodyResponse = client.segmentBodyWithOptions(segmentBodyRequest, runtime);
+            String imageURL = segmentBodyResponse.getBody().getData().getImageURL();
+            log.info("人体抠图imageURL:{}", imageURL);
+            myClient.downloadFile(imageURL, dir, fileName);
+        }catch (Exception e){
+            log.error("人体抠图失败,imageUrl:" + imageUrl, e);
+            myClient.downloadFile(imageUrl, dir, fileName);
+        }
+
+    }
+
+    public static void main(String[] args) {
+        FileUtils.downLoadFromUrl("http://vibktprfx-prod-prod-damo-eas-cn-shanghai.oss-cn-shanghai.aliyuncs.com/segment-body/2023-02-24/5d44fe44-308c-44c3-8e1d-2d4cbe601f86/image.png?Expires=1677208715&OSSAccessKeyId=LTAI4FoLmvQ9urWXgSRpDvh1&Signature=4ZyzaOz6W1nBD9s3KQuFN10c%2BPw%3D",
+                "1.png","D:\\test");
+    }
+
+    /**
+     * 使用AK&SK初始化账号Client
+     * @return Client
+     * @throws Exception
+     */
+    public com.aliyun.imageseg20191230.Client createClient() throws Exception {
+        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
+                // 必填,您的 AccessKey ID
+                .setAccessKeyId(accessKeyId)
+                // 必填,您的 AccessKey Secret
+                .setAccessKeySecret(accessKeySecret);
+        // 访问的域名
+        config.endpoint = this.imagesegEndPoint;
+        return new com.aliyun.imageseg20191230.Client(config);
+    }
+
+}

+ 97 - 0
src/main/java/com/fdkankan/scene/util/test.java

@@ -0,0 +1,97 @@
+package com.fdkankan.scene.util;
+// This file is auto-generated, don't edit it. Thanks.
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.thread.ThreadUtil;
+import cn.hutool.http.HttpUtil;
+import com.aliyun.imageseg20191230.Client;
+import com.aliyun.imageseg20191230.models.SegmentBodyResponse;
+import com.aliyun.tea.TeaException;
+import com.aliyun.teautil.Common;
+
+import java.io.File;
+
+public class test {
+
+    /**
+     * 使用AK&SK初始化账号Client
+     *
+     * @param accessKeyId
+     * @param accessKeySecret
+     * @return Client
+     * @throws Exception
+     */
+    public static com.aliyun.imageseg20191230.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
+        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
+                // 必填,您的 AccessKey ID
+                .setAccessKeyId(accessKeyId)
+                // 必填,您的 AccessKey Secret
+                .setAccessKeySecret(accessKeySecret);
+        // 访问的域名
+        config.endpoint = "imageseg.cn-shanghai.aliyuncs.com";
+        return new com.aliyun.imageseg20191230.Client(config);
+    }
+
+    public static void main(String[] args_) throws Exception {
+
+        java.util.List<String> args = java.util.Arrays.asList(args_);
+        // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html
+        com.aliyun.imageseg20191230.Client client = test.createClient("LTAIUrvuHqj8pvry", "JLOVl0k8Ke0aaM8nLMMiUAZ3EiiqI4");
+        ThreadUtil.execAsync(() -> {
+            extracted(client, "https://4dkankan-huadong.oss-cn-shanghai.aliyuncs.com/segment/1.jpg", "1");
+
+        });
+        ThreadUtil.execAsync(() -> {
+            extracted(client, "https://4dkankan-huadong.oss-cn-shanghai.aliyuncs.com/segment/2.jpg", "2");
+
+        });
+        ThreadUtil.sleep(1000);
+        ThreadUtil.execAsync(() -> {
+            extracted(client, "https://4dkankan-huadong.oss-cn-shanghai.aliyuncs.com/segment/3.jpg", "3");
+
+        });
+        ThreadUtil.execAsync(() -> {
+            extracted(client, "https://4dkankan-huadong.oss-cn-shanghai.aliyuncs.com/segment/4.webp", "4");
+
+        });
+//      ThreadUtil.sleep(2000);
+//      ThreadUtil.sleep(3000);
+
+//      ThreadUtil.sleep(4000);
+
+
+    }
+
+    private static void extracted(Client client, String imageUrl, String imgName) {
+
+        com.aliyun.imageseg20191230.models.SegmentBodyRequest segmentBodyRequest = new com.aliyun.imageseg20191230.models.SegmentBodyRequest()
+                .setImageURL(imageUrl);
+        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
+        try {
+            // 复制代码运行请自行打印 API 的返回值
+            long stime = System.currentTimeMillis();
+            System.out.println("开始-----------" + imgName);
+            SegmentBodyResponse segmentBodyResponse = client.segmentBodyWithOptions(segmentBodyRequest, runtime);
+            String imageURL = segmentBodyResponse.getBody().getData().getImageURL();
+            long etime = System.currentTimeMillis();
+            System.out.printf("执行时长:%d 毫秒.----%s", (etime - stime), imgName);
+            File file = FileUtil.file("C:\\Users\\4DAGE\\Downloads\\抠像测试\\抠像测试\\1\\" + imgName + ".png");
+            if (FileUtil.exist(file)) {
+                FileUtil.del(file);
+            }
+            System.out.println(imageURL);
+            ThreadUtil.sleep(1000);
+            HttpUtil.downloadFile(imageURL, FileUtil.file(file));
+        } catch (TeaException error) {
+            // 如有需要,请打印 error
+            String s = Common.assertAsString(error.message);
+            System.out.println("错误1" + s);
+        } catch (Exception _error) {
+            TeaException error = new TeaException(_error.getMessage(), _error);
+            // 如有需要,请打印 error
+            String s = Common.assertAsString(error.message);
+            System.out.println("错误2" + s);
+
+        }
+    }
+}

+ 20 - 0
src/main/java/com/fdkankan/scene/vo/SaveFiltersParamVO.java

@@ -0,0 +1,20 @@
+package com.fdkankan.scene.vo;
+
+import javax.validation.constraints.NotBlank;
+import lombok.Data;
+
+/**
+ * <p>
+ * 通用data类型参数类
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/10
+ **/
+@Data
+public class SaveFiltersParamVO extends BaseDataParamVO{
+
+    //是否恢复默认(0-否,1-是)
+    private Integer reset;
+
+}

+ 35 - 0
src/main/java/com/fdkankan/scene/vo/SceneAsynOperLogParamVO.java

@@ -0,0 +1,35 @@
+package com.fdkankan.scene.vo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/12/7
+ **/
+@Data
+public class SceneAsynOperLogParamVO extends BaseSceneParamVO{
+
+    /**
+    * 操作类型(upload-上传,download-下载)
+    */
+    private String operType;
+
+    /**
+     * 模块名称
+     */
+    private String module;
+
+    /**
+     * 功能
+     */
+    private String func;
+
+
+}

+ 24 - 0
src/main/java/com/fdkankan/scene/vo/SceneEditControlsParamVO.java

@@ -1,5 +1,6 @@
 package com.fdkankan.scene.vo;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -76,5 +77,28 @@ public class SceneEditControlsParamVO implements Serializable {
      */
     private Integer showRule;
 
+    /**
+     * 是否展示标尺(0-不需要,1-需要)
+     */
+    private Integer showScale;
+
+    /**
+     * 是否展示分享场景(0-不需要,1-需要)
+     */
+    private Integer showShare;
+
+    /**
+     * 是否展示分享热点(0-不需要,1-需要)
+     */
+    private Integer showTagshare;
+
+    /**
+     * 是否展示合照开关(0-不需要,1-需要)
+     */
+    private Integer showCapture;
+
+
+
+
 
 }

+ 21 - 0
src/main/java/com/fdkankan/scene/vo/SceneEditControlsVO.java

@@ -1,5 +1,6 @@
 package com.fdkankan.scene.vo;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -66,5 +67,25 @@ public class SceneEditControlsVO implements Serializable {
      */
     private Integer showRule;
 
+    /**
+     * 是否展示标尺(0-不需要,1-需要)
+     */
+    private Integer showScale;
+
+    /**
+     * 是否展示分享场景(0-不需要,1-需要)
+     */
+    private Integer showShare;
+
+    /**
+     * 是否展示分享热点(0-不需要,1-需要)
+     */
+    private Integer showTagshare;
+
+    /**
+     * 是否展示合照开关(0-不需要,1-需要)
+     */
+    private Integer showCapture;
+
 
 }

+ 11 - 0
src/main/java/com/fdkankan/scene/vo/SceneInfoVO.java

@@ -2,6 +2,7 @@ package com.fdkankan.scene.vo;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableField;
 import java.util.List;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -135,6 +136,11 @@ public class SceneInfoVO {
     private String sceneKind;
 
     /**
+     * 算法模型类型(dam,3dtiles)
+     */
+    private String modelKind;
+
+    /**
      * 空间视频数据
      */
     private String boxVideos;
@@ -223,5 +229,10 @@ public class SceneInfoVO {
      */
     private Integer surveillances;
 
+    /**
+     * 场景容量 单位 MB
+     */
+    private Integer space;
+
 
 }

+ 39 - 0
src/main/java/com/fdkankan/scene/vo/SceneMarkShapeDetectParamVO.java

@@ -0,0 +1,39 @@
+package com.fdkankan.scene.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/1/19
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SceneMarkShapeDetectParamVO {
+
+    /**
+     * 场景码
+     */
+    @NotBlank(message = "场景码不能为空")
+    private String num;
+
+    /**
+     *  推送域名
+     */
+    private String webSite;
+
+    /**
+     *  保存路径。可以为空,不为空可以查看结果
+     */
+    private String saveDir="";
+}

+ 36 - 0
src/main/java/com/fdkankan/scene/vo/SceneMarkShapeParamVO.java

@@ -0,0 +1,36 @@
+package com.fdkankan.scene.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/1/19
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SceneMarkShapeParamVO {
+
+    /**
+     * 场景码
+     */
+    @NotBlank(message = "场景码不能为空")
+    private String num;
+
+    /**
+     * 图片名称路径
+     */
+    private String imagePath;
+
+
+}

+ 46 - 0
src/main/java/com/fdkankan/scene/vo/SceneMarkShapeReDetectParamVO.java

@@ -0,0 +1,46 @@
+package com.fdkankan.scene.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/1/19
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SceneMarkShapeReDetectParamVO {
+
+    /**
+     * 场景码
+     */
+    private String num;
+
+    /**
+     *  推送域名
+     */
+    private String webSite;
+    /**
+     *  图片名称
+     */
+    private String imagePath;
+
+    /**
+     *  保存路径。可以为空,不为空可以查看结果
+     */
+    private String saveDir="";
+
+    /**
+     *  1,场景的单张图片重新进入训练  2,整个场景的推理进入训练
+     */
+    private Integer detectType;
+
+}

+ 2 - 0
src/main/java/com/fdkankan/scene/vo/UploadPanoramaVO.java

@@ -20,6 +20,8 @@ import lombok.NoArgsConstructor;
 @AllArgsConstructor
 public class UploadPanoramaVO {
 
+    private int asyn;
+
     private Integer successCnt;
 
     private List<String> failList;

+ 13 - 50
src/main/resources/bootstrap-prod-eur.yml

@@ -3,14 +3,11 @@ spring:
     name: 4dkankan-center-scene
   cloud:
     nacos:
+      server-addr: 172.31.42.151:8848
+      namespace: 4dkankan-v4-prod-eur
       config:
-        server-addr: 172.31.42.151:8848
         file-extension: yaml
-        namespace: 4dkankan-pro-eur
-        extension-configs:
-          - data-id: 4dkankan-center-scene.yaml
-            group: DEFAULT_GROUP
-            refresh: true
+        namespace: ${spring.cloud.nacos.namespace}
         shared-configs:
           - data-id: common-db-config.yaml
             group: DEFAULT_GROUP
@@ -20,54 +17,20 @@ spring:
             group: DEFAULT_GROUP
             refresh: true
 
-          - data-id: other-config.yaml
+          - data-id: common-config.yaml
             group: DEFAULT_GROUP
             refresh: true
 
-          - data-id: common-upload-config.yaml
+          - data-id: common-fyun-config.yaml
             group: DEFAULT_GROUP
             refresh: true
-      discovery:
-        server-addr: 172.31.42.151:8848
-        namespace: 4dkankan-pro-eur
-    sentinel:
-      transport:
-        dashboard: 172.31.42.151:8888
-#        dashboard: localhost:8888
-        heartbeat-interval-ms: 500
-        port: 8719
-      eager: true #取消sentinel控制台懒加载
-      #sentinel配置持久化nacos
-      datasource:
-        #流控规则
-        flow:
-          nacos:
-            server-addr: ${spring.cloud.nacos.config.server-addr}
-            dataId: ${spring.application.name}-flow-rules
-            groupId: SENTINEL_GROUP
-            namespace: 4dkankan-pro
-            rule-type: flow
-        #熔断规则
-        degrade:
-          nacos:
-            server-addr: ${spring.cloud.nacos.config.server-addr}
-            dataId: ${spring.application.name}-degrade-rules
-            groupId: SENTINEL_GROUP
-            namespace: 4dkankan-pro
-            rule-type: degrade
-#      log:
-#        dir: ./logs # 默认值${home}/logs/csp/
-#        switch-pid: true # 日志带上线程id
-
-#开启feign熔断降级,如果没有开启,feign调用链路不会显示再sentinel控制中
-#feign:
-#  sentinel:
-#    enabled: true
-
-feign:
-  httpclient:
-    connection-timeout: 200000
-
-
 
+          - data-id: common-rabbitmq-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
 
+          - data-id: forest-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
+      discovery:
+        namespace: ${spring.cloud.nacos.namespace}

+ 4 - 0
src/main/resources/bootstrap-prod.yml

@@ -28,6 +28,10 @@ spring:
           - data-id: common-rabbitmq-config.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: forest-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         namespace: ${spring.cloud.nacos.namespace}
 

+ 4 - 0
src/main/resources/bootstrap-test-eur.yml

@@ -28,6 +28,10 @@ spring:
           - data-id: common-rabbitmq-config.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: forest-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         namespace: ${spring.cloud.nacos.namespace}
 

+ 4 - 0
src/main/resources/bootstrap-test.yml

@@ -28,6 +28,10 @@ spring:
           - data-id: common-rabbitmq-config.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: forest-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         namespace: ${spring.cloud.nacos.namespace}
 

+ 5 - 0
src/main/resources/mapper/scene/RoleMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.scene.mapper.IRoleMapper">
+
+</mapper>

+ 5 - 0
src/main/resources/mapper/scene/SceneAsynOperLogMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.scene.mapper.ISceneAsynOperLogMapper">
+
+</mapper>

+ 5 - 0
src/main/resources/mapper/scene/UserRoleMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.scene.mapper.IUserRoleMapper">
+
+</mapper>