64 Commits 9f88bf1235 ... 13aa0ed00b

Author SHA1 Message Date
  dengsixing 13aa0ed00b 此文件用于计算服务检测是否挂上nas 1 day ago
  dengsixing 1e4c43f4af Merge remote-tracking branch 'origin/release' into project-jp 1 day ago
  dengsixing d317025051 Merge branch 'release-floorplanai' into release 1 week ago
  dengsixing 7900b927de 1111 2 weeks ago
  dengsixing 0aca23cdf8 1111 2 weeks ago
  dengsixing a154cc27de 平面图ai识别 3 weeks ago
  dengsixing a9f8bea370 鉴权 1 month ago
  dengsixing 40e57f22d0 生成obj接口 1 month ago
  dengsixing 279897d1dd 内部接口鉴权 1 month ago
  dengsixing cf75806369 内部接口鉴权 1 month ago
  dengsixing 42bee09309 内部接口鉴权 1 month ago
  dengsixing fd11e1fbaf 内部接口鉴权 1 month ago
  dengsixing 13ee92f714 内部接口鉴权 1 month ago
  dengsixing dc07217055 内部接口鉴权 1 month ago
  dengsixing 30e7abdcb5 内部接口鉴权 1 month ago
  dengsixing 117eee39a3 内部接口鉴权 1 month ago
  dengsixing 68db471d4d 生成obj接口迁移 1 month ago
  dengsixing 5b8e806b1e 内部接口鉴权 1 month ago
  dengsixing 8e0d279a69 内部接口鉴权 1 month ago
  dengsixing ac68315fab 内部接口鉴权 1 month ago
  dengsixing fdd439145b 内部接口鉴权 1 month ago
  dengsixing 294f7fd7cb 内部接口鉴权 1 month ago
  dengsixing d9c938cd20 旧版相机入库数据兼容 3 months ago
  dengsixing 4fd539fa15 旧版相机入库数据兼容 3 months ago
  dengsixing 3b137997d0 平面图ai识别 3 months ago
  dengsixing 15e3d443d6 平面图ai识别 3 months ago
  dengsixing 852dd8f106 平面图ai识别 3 months ago
  dengsixing aad5626ac8 Merge remote-tracking branch 'origin/feature-生成obj判断点位校准文件版本' into release 4 months ago
  dengsixing 4ad187f37b Merge branch 'release-mg-v2.9.0' into release 4 months ago
  dengsixing 2675c70be2 111 4 months ago
  dengsixing f88d5c592a Merge branch 'release-e57' into release 4 months ago
  dengsixing 91079dc706 mg-v2.9.0 4 months ago
  dengsixing e64829bd60 2025-04-01,刘强再次要求,vision_edit_version > 1.0 可以下载vision_edit.txt进行计算 4 months ago
  dengsixing b8db244032 2025-04-01,刘强再次要求,vision_edit_version > 1.0 可以下载vision_edit.txt进行计算 4 months ago
  dengsixing 671d83912b mgv2.9.0 4 months ago
  dengsixing c5c86b2c70 mgv2.9.0 4 months ago
  dengsixing a6c8577eed Merge branch 'release-v4.14.0' into release 4 months ago
  dengsixing a0e83ffc9e 计算优先级 按钮显示问题 4 months ago
  dengsixing f636fce561 计算优先级 按钮显示问题 4 months ago
  dengsixing 2779606dab 计算优先级 按钮显示问题 4 months ago
  dengsixing f00a076381 管理后台v2.9.0 4 months ago
  dengsixing 79cb2e1b3c 管理后台v2.9.0 4 months ago
  dengsixing 7576c6022d 看看相机固件存在bug,通知计算时会重复调两次通知计算,所以这里加个判断,直接返回成功 4 months ago
  dengsixing 7502baeacb e57改名重算,名称不变 5 months ago
  dengsixing a90c84f904 v4.14.0 5 months ago
  dengsixing afede0bb7e Merge branch 'release-e57' into release 5 months ago
  dengsixing 856c479df9 Merge branch 'release-e57' into release 5 months ago
  dengsixing 9bd4b1daf3 111 5 months ago
  dengsixing b00b782dd2 111 5 months ago
  dengsixing 6b33a966c4 Merge branch 'release-文保v1.5.0' into release 5 months ago
  dengsixing 5329d0ca04 恢复企业id=26的判断 5 months ago
  dengsixing fde05f53e0 去掉企业id=26的判断 5 months ago
  dengsixing 89104df677 v4.14.0 5 months ago
  dengsixing c8c0ce271f v4.14.0 ai识别加上异常捕捉,识别报异常不影响场景计算结果 5 months ago
  dengsixing bccd879cfa v4.14.0 删除e57临时文件 5 months ago
  dengsixing e2b2ec2e2d Merge branch 'release' into release-v4.14.0 5 months ago
  dengsixing f4bbc04cb0 v4.14.0 ai 5 months ago
  dengsixing 186197918d v4.14.0 ai 5 months ago
  dengsixing 40ea846452 v4.14.0 ai 5 months ago
  dengsixing 58b0eb1e32 v4.14.0 增加ai识别逻辑 5 months ago
  dengsixing 743b2a1630 v4.14.0 增加ai识别逻辑 5 months ago
  dengsixing b509963ada v4.14.0 增加ai识别逻辑 5 months ago
  dengsixing 99a2e2b984 文保vrv1.5.0需求,文保vr全景场景默认不封村 5 months ago
  dengsixing 4f05e3f7a4 生成obj改造,下载点位校准文件,刘强版本大改,要求只有包含字段vision_edit_version且vision_edit_version的值是1.0时,才下载vision_edit.txt文件进行计算,其他情况不保留 8 months ago
54 changed files with 1624 additions and 100 deletions
  1. 57 0
      httpclient/FdkankanMiniClient.java
  2. 33 0
      httpclient/MyClient.java
  3. 12 0
      pom.xml
  4. 51 0
      src/main/java/com/fdkankan/contro/Interceptor/LogProxy.java
  5. 95 0
      src/main/java/com/fdkankan/contro/Interceptor/SignVerificationAspect.java
  6. 6 0
      src/main/java/com/fdkankan/contro/ModelingControlApplication.java
  7. 10 0
      src/main/java/com/fdkankan/contro/annotation/SignVerification.java
  8. 5 2
      src/main/java/com/fdkankan/contro/bean/SceneJsonBean.java
  9. 3 0
      src/main/java/com/fdkankan/contro/bean/SyncLaserResultBean.java
  10. 30 0
      src/main/java/com/fdkankan/contro/constant/DetectType.java
  11. 5 23
      src/main/java/com/fdkankan/contro/controller/InnerController.java
  12. 27 8
      src/main/java/com/fdkankan/contro/controller/SceneFileController.java
  13. 19 2
      src/main/java/com/fdkankan/contro/controller/TestController.java
  14. 4 1
      src/main/java/com/fdkankan/contro/entity/Company.java
  15. 2 5
      src/main/java/com/fdkankan/contro/entity/MqSendLog.java
  16. 12 0
      src/main/java/com/fdkankan/contro/entity/SceneEditControls.java
  17. 78 0
      src/main/java/com/fdkankan/contro/entity/SceneMarkShape.java
  18. 5 4
      src/main/java/com/fdkankan/contro/entity/ScenePlus.java
  19. 20 3
      src/main/java/com/fdkankan/contro/entity/ScenePlusExt.java
  20. 61 0
      src/main/java/com/fdkankan/contro/entity/SceneShapeEnum.java
  21. 23 0
      src/main/java/com/fdkankan/contro/httpclient/LaserAddressSource.java
  22. 19 0
      src/main/java/com/fdkankan/contro/httpclient/LaserClient.java
  23. 18 0
      src/main/java/com/fdkankan/contro/httpclient/MyClient.java
  24. 27 0
      src/main/java/com/fdkankan/contro/mapper/ISceneUpgradeMapper.java
  25. 20 0
      src/main/java/com/fdkankan/contro/mapper/MarkShapeMapper.java
  26. 16 0
      src/main/java/com/fdkankan/contro/mapper/SceneShapeEnumMapper.java
  27. 1 1
      src/main/java/com/fdkankan/contro/mq/listener/AbstrackBuildSceneListener.java
  28. 1 1
      src/main/java/com/fdkankan/contro/mq/listener/BuildE57Listener.java
  29. 1 1
      src/main/java/com/fdkankan/contro/mq/listener/BuildReverseE57Listener.java
  30. 2 2
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildIntermitSceneServiceImpl.java
  31. 2 2
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildLiguangServiceImpl.java
  32. 26 2
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildObjServiceImpl.java
  33. 3 1
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildReverseE57SceneServiceImpl.java
  34. 35 15
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildSceneServiceImpl.java
  35. 1 1
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildV3SceneServiceImpl.java
  36. 13 0
      src/main/java/com/fdkankan/contro/service/IAiService.java
  37. 15 3
      src/main/java/com/fdkankan/contro/service/ICommonService.java
  38. 22 0
      src/main/java/com/fdkankan/contro/service/ISceneMarkShapeService.java
  39. 1 1
      src/main/java/com/fdkankan/contro/service/ISceneProService.java
  40. 16 0
      src/main/java/com/fdkankan/contro/service/SceneShapeEnumService.java
  41. 144 0
      src/main/java/com/fdkankan/contro/service/impl/AiServiceImpl.java
  42. 185 15
      src/main/java/com/fdkankan/contro/service/impl/CommonServiceImpl.java
  43. 3 0
      src/main/java/com/fdkankan/contro/service/impl/IFdkkLaserServiceImpl.java
  44. 2 2
      src/main/java/com/fdkankan/contro/service/impl/InnerServiceImpl.java
  45. 33 1
      src/main/java/com/fdkankan/contro/service/impl/SceneFileBuildServiceImpl.java
  46. 99 0
      src/main/java/com/fdkankan/contro/service/impl/SceneMarkShapeServiceImpl.java
  47. 155 4
      src/main/java/com/fdkankan/contro/service/impl/SceneProServiceImpl.java
  48. 24 0
      src/main/java/com/fdkankan/contro/service/impl/SceneShapeEnumServiceImpl.java
  49. 11 0
      src/main/java/com/fdkankan/contro/vo/SceneEditControlsVO.java
  50. 40 0
      src/main/java/com/fdkankan/contro/vo/SceneParam.java
  51. 5 0
      src/main/resources/bootstrap-dev.yml
  52. 4 0
      src/main/resources/bootstrap-pro.yml
  53. 4 0
      src/main/resources/bootstrap-test.yml
  54. 118 0
      src/main/resources/mapper/contro/SceneUpgradeMapper.xml

+ 57 - 0
httpclient/FdkankanMiniClient.java

@@ -0,0 +1,57 @@
+//package com.fdkankan.scene.httpclient;
+//
+//import com.dtflys.forest.annotation.Get;
+//import com.dtflys.forest.annotation.Header;
+//import com.dtflys.forest.annotation.Post;
+//import com.dtflys.forest.annotation.Retry;
+//import com.dtflys.forest.annotation.Success;
+//import com.dtflys.forest.annotation.Var;
+//import com.dtflys.forest.callback.OnError;
+//import com.dtflys.forest.callback.OnSuccess;
+//import com.fdkankan.common.response.Result;
+//import java.util.Map;
+//import com.fdkankan.scene.bean.CameraBean;
+//import com.fdkankan.scene.bean.UserIncrementBean;
+//import com.fdkankan.scene.callback.FdkkMiniReqSuccessCondition;
+//
+///**
+// * <p>
+// * TODO
+// * </p>
+// *
+// * @author dengsixing
+// * @since 2022/4/24
+// **/
+//@Success(condition = FdkkMiniReqSuccessCondition.class)
+//public interface FdkankanMiniClient {
+//
+//    @Get(url="{url}"
+////        ,interceptor = TLogForestInterceptor.class    加这个拦截器,打印的tlog日志会详细一些,包括头信息等等
+//    )
+//    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+//    Result<String> getDataSyncType(@Var("url") String url, OnSuccess<Result> onSuccess, OnError onError);
+//
+//    @Get("{url}")
+//    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+//    Result<UserIncrementBean> getUserIncrementByCameraId(@Var("url") String url, OnSuccess<Result> onSuccess, OnError onError);
+//
+//    @Get("{url}")
+//    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+//    Result<CameraBean> getCameraByCameraId(@Var("url") String url, OnSuccess<Result> onSuccess, OnError onError);
+//
+////    @Get(url="{url}")
+////    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+////    Result<SceneProV3> getSceneProByNum(@Var("url") String url, OnSuccess<Result> onSuccess, OnError onError);
+//
+//    @Post(url="{url}")
+//    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+//    Result<Map<String, Object>> getIsLogin(@Var("url") String url, @Header("token") String token, OnSuccess<Result> onSuccess, OnError onError);
+//
+////    @Post(
+////        url = "${url}",
+////        contentType = "application/json"
+////    )
+////    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+////    Result upgradeToV4ResultSync(@Var("url") String url, @Body RequestSceneProV4 param, OnSuccess<Result> onSuccess, OnError onError);
+//
+//}

+ 33 - 0
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);
+
+}

+ 12 - 0
pom.xml

@@ -194,6 +194,18 @@
       <version>2.17.0</version>
     </dependency>
 
+    <dependency>
+      <groupId>com.fdkankan</groupId>
+      <artifactId>4dkankan-utils-sign</artifactId>
+      <version>3.0.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.dtflys.forest</groupId>
+      <artifactId>forest-spring-boot-starter</artifactId>
+      <version>1.5.19</version>
+    </dependency>
+
   </dependencies>
   <build>
     <finalName>${artifactId}</finalName>

+ 51 - 0
src/main/java/com/fdkankan/contro/Interceptor/LogProxy.java

@@ -0,0 +1,51 @@
+//package com.fdkankan.contro.Interceptor;
+//
+//import com.alibaba.fastjson.JSON;
+//import lombok.extern.slf4j.Slf4j;
+//import org.aspectj.lang.JoinPoint;
+//import org.aspectj.lang.annotation.AfterReturning;
+//import org.aspectj.lang.annotation.AfterThrowing;
+//import org.aspectj.lang.annotation.Aspect;
+//import org.springframework.stereotype.Component;
+//import org.springframework.web.multipart.MultipartFile;
+//
+//import java.util.Arrays;
+//import java.util.List;
+//
+//@Slf4j
+//@Aspect
+//@Component
+//public class LogProxy {
+//
+//	@AfterReturning(value = "execution(* com.fdkankan.contro.controller.*.*(..))", returning = "result")
+//	public void afterMethod(JoinPoint point, Object result){
+//		String methodName = point.getSignature().getName();
+//		List<Object> args = (List<Object>) Arrays.asList(point.getArgs()).stream().filter(v -> {
+//			if(v instanceof MultipartFile){
+//				return false;
+//			}
+//			if(v instanceof String && ((String) v).startsWith("data:image/png;base64")){
+//				return false;
+//			}
+//			return true;
+//		});
+//		System.out.println("连接点方法为:" + methodName + ",参数为:" + JSON.toJSONString(args) + ",目标方法执行结果为:" + JSON.toJSONString(result));
+//	}
+//
+//	@AfterThrowing(value = "execution(* com.fdkankan.kz.pms.controller.*.*.*(..))")
+//	public void afterThrowing(JoinPoint point){
+//		String methodName = point.getSignature().getName();
+//		List<Object> args = (List<Object>) Arrays.asList(point.getArgs()).stream().filter(v -> {
+//			if(v instanceof MultipartFile){
+//				return false;
+//			}
+//			if(v instanceof String && ((String) v).startsWith("data:image/png;base64")){
+//				return false;
+//			}
+//			return true;
+//		});
+//		System.out.println("连接点方法为:" + methodName + ",参数为:" + JSON.toJSONString(args));
+//	}
+//
+//
+//}

+ 95 - 0
src/main/java/com/fdkankan/contro/Interceptor/SignVerificationAspect.java

@@ -0,0 +1,95 @@
+package com.fdkankan.contro.Interceptor;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.constant.ServerCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.contro.common.Result;
+import com.fdkankan.contro.httpclient.MyClient;
+import com.fdkankan.sign.RsaUtils;
+import com.fdkankan.sign.SignUtils;
+import lombok.extern.log4j.Log4j2;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+@Log4j2
+@Aspect
+@Component
+@Order(101)
+public class SignVerificationAspect {
+
+	private static final String GET_PRIVATEKEY_API = "/ucenter/_inner/pdsfsdfsrvateddsfeky/";
+
+	@Value("${ucenter.publicKey}")
+	private String publicKey;
+	@Value("${ucenter.appId}")
+	private String ucenterAppId;
+
+	@Value("${4dkk.fdService.basePath}")
+	private String fdServiceBasePath;
+
+	@Resource
+	private MyClient myClient;
+
+	/**
+	 * 前置通知 用于判断用户协作场景是否有协作权限
+	 *
+	 * @param joinPoint
+	 *            切点
+	 * @throws IOException
+	 */
+	@Before("@annotation(com.fdkankan.contro.annotation.SignVerification)")
+	public void doBefore(JoinPoint joinPoint) throws Exception {
+		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+		String XUA = request.getHeader("X-UA");
+		if(StrUtil.isNotEmpty(XUA)){
+			return;
+		}
+
+		String sign = request.getHeader("sign");
+		String appId = request.getHeader("appId");
+		if(StrUtil.isEmpty(sign) || StrUtil.isEmpty(appId)){
+			throw new BusinessException(ErrorCode.AUTH_FAIL);
+		}
+
+		//通过appid查询私钥
+		JSONObject playload = new JSONObject();
+		playload.put("appId", ucenterAppId);
+		playload.put("timestamp", System.currentTimeMillis());
+		String ucenterSign = RsaUtils.encipher(playload.toJSONString(), publicKey);
+		Map<String, String> headerMap = new HashMap<>();
+		headerMap.put("sign", ucenterSign);
+		headerMap.put("appId", ucenterAppId);
+		String url = fdServiceBasePath + GET_PRIVATEKEY_API + appId;
+		Result result = myClient.get(url, headerMap);
+		if(result.getCode() != ServerCode.SUCCESS.code()){
+			throw new RuntimeException("系统异常");
+		}
+		JSONObject data = (JSONObject) result.getData();
+		if(Objects.isNull(data)){
+			throw new BusinessException(ErrorCode.AUTH_FAIL);
+		}
+		String privateKey = data.getString("privateKey");
+
+		//签名解密
+		if(!SignUtils.checkSign(sign, appId, privateKey)){
+			throw new BusinessException(ErrorCode.AUTH_FAIL);
+		}
+	}
+
+}

+ 6 - 0
src/main/java/com/fdkankan/contro/ModelingControlApplication.java

@@ -1,5 +1,7 @@
 package com.fdkankan.contro;
 
+import cn.hutool.core.io.FileUtil;
+import com.dtflys.forest.springboot.annotation.ForestScan;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -22,9 +24,13 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @EnableAsync
 @MapperScan("com.fdkankan.**.mapper")
 @EnableDiscoveryClient
+@ForestScan(basePackages = "com.fdkankan.contro.httpclient")
 public class ModelingControlApplication {
     public static void main(String[] args) {
         SpringApplication.run(ModelingControlApplication.class, args);
+        String checkFilePath = "/mnt/dont_delete/nas_check.txt";
+        FileUtil.mkParentDirs(checkFilePath);
+        FileUtil.writeUtf8String("此文件用于计算服务检测是否挂上nas", "");
     }
 }
 

+ 10 - 0
src/main/java/com/fdkankan/contro/annotation/SignVerification.java

@@ -0,0 +1,10 @@
+package com.fdkankan.contro.annotation;
+
+import java.lang.annotation.*;
+
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface SignVerification {
+    String description() default "";
+}

+ 5 - 2
src/main/java/com/fdkankan/contro/bean/SceneJsonBean.java

@@ -1,15 +1,14 @@
 package com.fdkankan.contro.bean;
 
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.fdkankan.contro.vo.SceneEditControlsVO;
-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>
@@ -221,5 +220,9 @@ public class SceneJsonBean {
 
     private Integer sceneDraw;
 
+    private Integer hasRecognition;
+
+    private Integer hasFloorplanAi;
+
 
 }

+ 3 - 0
src/main/java/com/fdkankan/contro/bean/SyncLaserResultBean.java

@@ -18,9 +18,12 @@ public class SyncLaserResultBean {
     private Integer sceneStatus;
     private Date createTime;
     private Integer shootCount;
+    private Integer slamCount;
     private Integer payStatus;
     private Integer mixture;
     private String version;
 
 
+
+
 }

+ 30 - 0
src/main/java/com/fdkankan/contro/constant/DetectType.java

@@ -0,0 +1,30 @@
+package com.fdkankan.contro.constant;
+
+/**
+ * 用户状态
+ *
+ * @author fdkk
+ */
+public enum DetectType
+{
+    PANO(1, "全景图识别"), PLAN(2, "平面图识别");
+
+    private final Integer code;
+    private final String info;
+
+    DetectType(Integer code, String info)
+    {
+        this.code = code;
+        this.info = info;
+    }
+
+    public Integer getCode()
+    {
+        return code;
+    }
+
+    public String getInfo()
+    {
+        return info;
+    }
+}

+ 5 - 23
src/main/java/com/fdkankan/contro/controller/InnerController.java

@@ -1,32 +1,13 @@
 package com.fdkankan.contro.controller;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.fdkankan.common.constant.ErrorCode;
-import com.fdkankan.common.constant.ModelingBuildStatus;
-import com.fdkankan.common.exception.BusinessException;
-import com.fdkankan.contro.service.IAppCameraFailLogService;
+import com.fdkankan.contro.annotation.SignVerification;
 import com.fdkankan.contro.service.IInnerService;
-import com.fdkankan.contro.service.ISceneFileBuildService;
-import com.fdkankan.contro.service.ISceneUploadCountService;
-import com.fdkankan.contro.vo.ReportFailLogVO;
-import com.fdkankan.contro.vo.ResponseSceneFile;
-import com.fdkankan.contro.vo.SceneUploadCountParamVO;
-import com.fdkankan.fyun.face.FYunFileServiceInterface;
-import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
 import com.fdkankan.web.response.ResultData;
 import lombok.extern.log4j.Log4j2;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-
-import javax.validation.Valid;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * 场景文件上传模块
@@ -39,6 +20,7 @@ public class InnerController {
     @Autowired
     private IInnerService innerService;
 
+    @SignVerification
     @GetMapping("uploadArtificialResult")
     public ResultData uploadArtificialResult(String num) throws Exception {
         innerService.uploadArtificialResult(num);

+ 27 - 8
src/main/java/com/fdkankan/contro/controller/SceneFileController.java

@@ -6,13 +6,12 @@ import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.common.constant.SceneSource;
 import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.contro.annotation.SignVerification;
 import com.fdkankan.contro.entity.ScenePlus;
-import com.fdkankan.contro.service.IAppCameraFailLogService;
-import com.fdkankan.contro.service.ISceneFileBuildService;
-import com.fdkankan.contro.service.IScenePlusService;
-import com.fdkankan.contro.service.ISceneUploadCountService;
+import com.fdkankan.contro.service.*;
 import com.fdkankan.contro.vo.ReportFailLogVO;
 import com.fdkankan.contro.vo.ResponseSceneFile;
+import com.fdkankan.contro.vo.SceneParam;
 import com.fdkankan.contro.vo.SceneUploadCountParamVO;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.web.response.ResultData;
@@ -36,17 +35,16 @@ public class SceneFileController{
 
     @Autowired
     private ISceneFileBuildService sceneFileBuildService;
-
     @Resource
     private FYunFileServiceInterface fYunFileService;
-
     @Autowired
     private ISceneUploadCountService sceneUploadCountService;
-
     @Autowired
     private IAppCameraFailLogService appCameraFailLogService;
     @Autowired
     private IScenePlusService scenePlusService;
+    @Autowired
+    ISceneProService sceneProService;
 
 
     /**
@@ -88,11 +86,14 @@ public class SceneFileController{
      * @param params
      * @return
      */
+    @SignVerification
     @PostMapping("reverseScene")
     public ResultData reverseScene(@RequestBody JSONObject params) throws Exception {
         return sceneFileBuildService.reverseScene(params);
     }
 
+
+    @SignVerification
     @GetMapping("rebuildScene")
     public ResultData rebuildScene(@RequestParam(value = "num") String num,
                                    @RequestParam(value = "force",defaultValue = "false") Boolean force ,
@@ -145,7 +146,7 @@ public class SceneFileController{
         return map;
     }
 
-
+    @SignVerification
     @GetMapping("copyDataAndBuild")
     public ResultData copyDataAndBuild(@RequestParam(value = "dataSource") String dataSource,@RequestParam(value = "sceneVer") String sceneVer,
                                        @RequestParam(value = "sourceBucket") String sourceBucket) throws Exception {
@@ -157,12 +158,14 @@ public class SceneFileController{
      * @param param
      * @return
      */
+    @SignVerification
     @PostMapping("/increSceneUploadCount")
     public ResultData increSceneUploadCount(@RequestBody @Valid SceneUploadCountParamVO param){
         sceneUploadCountService.increSceneUploadCount(param);
         return ResultData.ok();
     }
 
+    @SignVerification
     @PostMapping("/reportFailLog")
     public ResultData reportFailLog(@RequestBody @Valid ReportFailLogVO param){
         appCameraFailLogService.reportFailLog(param);
@@ -173,9 +176,25 @@ public class SceneFileController{
      * 计算理光相机格式场景
      * @return
      */
+    @SignVerification
     @PostMapping("uploadLiguang")
     public ResultData uploadLiguang(String num, String snCode, String ossPath) throws Exception {
         return sceneFileBuildService.uploadLiguang(num, snCode, ossPath);
     }
 
+    /**
+     *
+     * 激光场景生成obj文件
+     */
+    @SignVerification
+    @PostMapping(value = "/generateObjFile")
+    public ResultData generateObjFile(@RequestBody SceneParam requestScene) throws Exception{
+        String num = requestScene.getSceneNum();
+        if (StringUtils.isEmpty(num)) {
+            throw new BusinessException(ErrorCode.FAILURE_CODE_3001);
+        }
+        sceneProService.generateObjFile(num);
+        return ResultData.ok();
+    }
+
 }

+ 19 - 2
src/main/java/com/fdkankan/contro/controller/TestController.java

@@ -1,5 +1,10 @@
 package com.fdkankan.contro.controller;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.contro.entity.Camera;
+import com.fdkankan.contro.service.ICameraService;
 import com.fdkankan.contro.service.ICommonService;
 import com.fdkankan.contro.service.IScene3dNumService;
 import com.fdkankan.web.response.ResultData;
@@ -9,6 +14,8 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.Objects;
+
 /**
  * <p>
  * TODO
@@ -27,10 +34,20 @@ public class TestController {
     private ICommonService commonService;
     @Value("${4dkk.laserService.bucket}")
     private String bucket;
+    @Autowired
+    private ICameraService cameraService;
 
     @GetMapping("/test")
-    public ResultData test(String num) throws Exception {
-        return ResultData.ok(bucket);
+    public ResultData test(String mac) throws Exception {
+        Camera camera = cameraService.getBySnCode(mac);
+        if(Objects.isNull(camera)){
+            camera = cameraService.getOne(new LambdaQueryWrapper<Camera>()
+                    .like(Camera::getChildName, mac)
+                    .or().like(Camera::getSnCode, mac)
+                    .or().like(Camera::getWifiName, mac));
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7010);
+        }
+        return ResultData.ok(camera);
     }
 
 }

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

@@ -13,7 +13,7 @@ import java.util.Date;
  * 客户企业logo信息
  * </p>
  *
- * @author 
+ * @author
  * @since 2021-12-24
  */
 @Getter
@@ -107,4 +107,7 @@ public class Company implements Serializable {
     @TableLogic("A")
     private String recStatus;
 
+    @TableField("can_up_website")
+    private Integer canUpWebsite;
+
 }

+ 2 - 5
src/main/java/com/fdkankan/contro/entity/MqSendLog.java

@@ -11,10 +11,10 @@ import lombok.Setter;
 
 /**
  * <p>
- * 
+ *
  * </p>
  *
- * @author 
+ * @author
  * @since 2024-03-27
  */
 @Getter
@@ -42,9 +42,6 @@ public class MqSendLog implements Serializable {
     @TableField("num")
     private String num;
 
-    @TableField("es_name")
-    private String esName;
-
     /**
      * 0未发送,1已发送
      */

+ 12 - 0
src/main/java/com/fdkankan/contro/entity/SceneEditControls.java

@@ -143,6 +143,18 @@ public class SceneEditControls implements Serializable {
     @TableField("show_texture")
     private Integer showTexture;
 
+    /**
+     * 是否显示ai识别
+     */
+    @TableField("show_ai")
+    private Integer showAi;
+
+    /**
+     * 是否显示点云跳转按钮
+     */
+    @TableField("show_laser")
+    private Integer showLaser;
+
 
 
 

+ 78 - 0
src/main/java/com/fdkankan/contro/entity/SceneMarkShape.java

@@ -0,0 +1,78 @@
+package com.fdkankan.contro.entity;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
+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;
+
+      /**
+       * 推理类型 1,全景图识别 2,平面图识别
+       */
+      @TableField("type")
+      private Integer type;
+
+}

+ 5 - 4
src/main/java/com/fdkankan/contro/entity/ScenePlus.java

@@ -122,9 +122,10 @@ public class ScenePlus implements Serializable {
     @TableField("source_id")
     private Long sourceId;
 
-    @TableField("laser_title")
-    private String laserTitle;
-
-
+    /**
+     * 是否有平面图i识别
+     */
+    @TableField("has_floorplan_ai")
+    private Integer hasFloorplanAi;
 
 }

+ 20 - 3
src/main/java/com/fdkankan/contro/entity/ScenePlusExt.java

@@ -12,10 +12,10 @@ import lombok.Setter;
 
 /**
  * <p>
- * 
+ *
  * </p>
  *
- * @author 
+ * @author
  * @since 2022-03-16
  */
 @Getter
@@ -140,7 +140,13 @@ public class ScenePlusExt implements Serializable {
      * 计算耗时
      */
     @TableField("compute_time")
-    private String computeTime;
+    private Long computeTime;
+
+    /**
+     * 计算耗时
+     */
+    @TableField("mesh_compute_time")
+    private Long meshComputeTime;
 
     /**
      * 点位视频
@@ -187,4 +193,15 @@ public class ScenePlusExt implements Serializable {
      */
     @TableField("is_obj")
     private int isObj;
+
+    @TableField("has_recognition")
+    private Integer hasRecognition;
+
+
+
+    /**
+     * 帧数
+     */
+    @TableField("slam_count")
+    private int slamCount;
 }

+ 61 - 0
src/main/java/com/fdkankan/contro/entity/SceneShapeEnum.java

@@ -0,0 +1,61 @@
+package com.fdkankan.contro.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * 标注框模型表
+ *
+ * @author Xiewj
+ * @since 2023-11-09 11:53
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("t_scene_shape_enum")
+public class SceneShapeEnum {
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 属性名
+     */
+    private String name;
+
+    /**
+     * 类名
+     */
+    private String className;
+
+    /**
+     * 资源类型ID
+     */
+    private String resourceId;
+
+    /**
+     * 设备类型ID
+     */
+    private String typeId;
+
+    /**
+     * 记录的状态,A: 生效,I: 禁用
+     */
+    private String recStatus;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+}

+ 23 - 0
src/main/java/com/fdkankan/contro/httpclient/LaserAddressSource.java

@@ -0,0 +1,23 @@
+package com.fdkankan.contro.httpclient;
+
+import com.dtflys.forest.callback.AddressSource;
+import com.dtflys.forest.http.ForestAddress;
+import com.dtflys.forest.http.ForestRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class LaserAddressSource implements AddressSource {
+
+    @Value("${4dkk.laserService.basePath}")
+    private String basePath;
+
+
+    @Override
+    public ForestAddress getAddress(ForestRequest forestRequest) {
+        log.info("------------basePath:{}--------------", basePath);
+        return new ForestAddress("","",null,basePath);
+    }
+}

+ 19 - 0
src/main/java/com/fdkankan/contro/httpclient/LaserClient.java

@@ -0,0 +1,19 @@
+package com.fdkankan.contro.httpclient;
+
+import com.dtflys.forest.annotation.Address;
+import com.dtflys.forest.annotation.Get;
+import com.dtflys.forest.annotation.Var;
+import com.fdkankan.contro.common.Result;
+
+/**
+ * 获取,调用激光服务
+ */
+@Address(source = LaserAddressSource.class)
+public interface LaserClient {
+
+
+//    @Get("/laser/init/${0}")
+    @Get(url = "${url}")
+    Result getSceneByNum(@Var("url") String url);
+
+}

+ 18 - 0
src/main/java/com/fdkankan/contro/httpclient/MyClient.java

@@ -0,0 +1,18 @@
+package com.fdkankan.contro.httpclient;
+
+
+import com.dtflys.forest.annotation.Get;
+import com.dtflys.forest.annotation.Header;
+import com.dtflys.forest.annotation.Var;
+import com.fdkankan.contro.common.Result;
+
+import java.util.Map;
+
+public interface MyClient {
+
+    @Get(url = "${url}")
+    Result get(@Var("url") String url, @Header Map<String, String> headerMap);
+
+
+
+}

+ 27 - 0
src/main/java/com/fdkankan/contro/mapper/ISceneUpgradeMapper.java

@@ -0,0 +1,27 @@
+package com.fdkankan.contro.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ * 文件夹表 Mapper 接口
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2021-12-24
+ */
+@Mapper
+public interface ISceneUpgradeMapper {
+
+    public void transferScenePlus(String num);
+
+    public void transferScenePlusExt(@Param("num") String num, @Param("scenePlusId") Long scenePlusId, @Param("sceneKind") String sceneKind);
+
+    public void deleteScenePlus(String num);
+
+    public void deleteScenePlusExt(Long scenePlusId);
+
+
+
+}

+ 20 - 0
src/main/java/com/fdkankan/contro/mapper/MarkShapeMapper.java

@@ -0,0 +1,20 @@
+package com.fdkankan.contro.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.contro.entity.SceneMarkShape;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Xiewj
+ * @date 2021/11/22
+ */
+@Mapper
+public interface MarkShapeMapper extends BaseMapper<SceneMarkShape> {
+
+}
+

+ 16 - 0
src/main/java/com/fdkankan/contro/mapper/SceneShapeEnumMapper.java

@@ -0,0 +1,16 @@
+package com.fdkankan.contro.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.contro.entity.SceneShapeEnum;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Component;
+
+/**
+* 标注框模型表 Mapper
+*
+* @author Xiewj
+* @since 2023-11-09 11:53
+*/
+@Mapper
+public interface SceneShapeEnumMapper extends BaseMapper<SceneShapeEnum> {
+}

+ 1 - 1
src/main/java/com/fdkankan/contro/mq/listener/AbstrackBuildSceneListener.java

@@ -60,7 +60,7 @@ public class AbstrackBuildSceneListener implements IBuildSceneListener {
             sceneBuildProcessLogService.clearSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueName, bizType);
             sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueName, CommonOperStatus.WAITING.code(), null, bizType);
             buildSceneService.buildScenePre(buildSceneMessage);
-            commonService.saveMqSendLog(num, buildSceneMessage);
+            commonService.saveMqSendLog(num, buildSceneMessage, 0);
             sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueName, CommonOperStatus.SUCCESS.code(), null, bizType);
         }catch (Exception e){
             log.error("场景计算前置处理出错,num=" + num, e);

+ 1 - 1
src/main/java/com/fdkankan/contro/mq/listener/BuildE57Listener.java

@@ -79,7 +79,7 @@ public class BuildE57Listener{
             sceneBuildProcessLogService.clearSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, "e57");
             sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, CommonOperStatus.WAITING.code(), null, "e57");
             buildSceneService.buildScenePre(buildSceneMessage);
-            commonService.saveMqSendLog(num, buildSceneMessage);
+            commonService.saveMqSendLog(num, buildSceneMessage, 0);
             sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, CommonOperStatus.SUCCESS.code(), null,"e57");
         }catch (Exception e){
             log.error("e57计算前置处理出错,num=" + num, e);

+ 1 - 1
src/main/java/com/fdkankan/contro/mq/listener/BuildReverseE57Listener.java

@@ -78,7 +78,7 @@ public class BuildReverseE57Listener {
             sceneBuildProcessLogService.clearSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, "reverseE57");
             sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, CommonOperStatus.WAITING.code(), null, "reverseE57");
             buildSceneService.buildScenePre(buildSceneMessage);
-            commonService.saveMqSendLog(num, buildSceneMessage);
+            commonService.saveMqSendLog(num, buildSceneMessage, 0);
             sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, CommonOperStatus.SUCCESS.code(), null, "reverseE57");
         }catch (Exception e){
             log.error("上传e57计算前置处理出错,num=" + num, e);

+ 2 - 2
src/main/java/com/fdkankan/contro/mq/service/impl/BuildIntermitSceneServiceImpl.java

@@ -202,7 +202,7 @@ public class BuildIntermitSceneServiceImpl implements IBuildSceneService {
             }
 
             //如果相机容量不足,需要把场景的paystatus改为容量不足状态
-            scenePlus.setPayStatus(commonService.getPayStatus(scenePlus.getCameraId(), space));
+            scenePlus.setPayStatus(commonService.getPayStatus(scenePlus.getCameraId(), space, fdageData));
 
             this.uploadStatusJson(scenePlus, scenePlusExt);
 
@@ -285,7 +285,7 @@ public class BuildIntermitSceneServiceImpl implements IBuildSceneService {
     private void updateDbPlus(int sceneSource,Long space,String videosJson, Long computeTime,boolean isObj,ScenePlusExt scenePlusExt){
 
         scenePlusExt.setSpace(space);
-        scenePlusExt.setComputeTime(computeTime.toString());
+        scenePlusExt.setComputeTime(computeTime);
         scenePlusExt.setAlgorithmTime(new Date());
         scenePlusExt.setVideos(videosJson);
         scenePlusExt.setIsObj(isObj ? 1 : 0);

+ 2 - 2
src/main/java/com/fdkankan/contro/mq/service/impl/BuildLiguangServiceImpl.java

@@ -283,7 +283,7 @@ public class BuildLiguangServiceImpl implements IBuildSceneService {
 
             //更新场景主表
             //如果相机容量不足,需要把场景的paystatus改为容量不足状态
-            scenePlus.setPayStatus(commonService.getPayStatus(scenePlus.getCameraId(), space));
+            scenePlus.setPayStatus(commonService.getPayStatus(scenePlus.getCameraId(), space, null));
             //统计原始资源大小
             scenePlusExt.setOrigSpace(FileUtil.size(new File(path.concat(File.separator).concat("capture"))));
 
@@ -481,7 +481,7 @@ public class BuildLiguangServiceImpl implements IBuildSceneService {
     private void updateDbPlus(int sceneSource,Long space,String videosJson, Long computeTime,boolean isObj,ScenePlusExt scenePlusExt){
 
         scenePlusExt.setSpace(space);
-        scenePlusExt.setComputeTime(computeTime.toString());
+        scenePlusExt.setComputeTime(computeTime);
         scenePlusExt.setAlgorithmTime(new Date());
         scenePlusExt.setVideos(videosJson);
         scenePlusExt.setIsObj(isObj ? 1 : 0);

+ 26 - 2
src/main/java/com/fdkankan/contro/mq/service/impl/BuildObjServiceImpl.java

@@ -33,6 +33,7 @@ import org.springframework.util.ObjectUtils;
 
 import javax.annotation.Resource;
 import java.io.File;
+import java.math.BigDecimal;
 import java.util.*;
 
 /**
@@ -170,8 +171,25 @@ public class BuildObjServiceImpl implements IBuildSceneService {
         String ossResultPath = String.format(UploadFilePath.scene_result_data_path, message.getSceneNum());
         fYunFileService.downloadFileByCommand(path + "/caches/images/", ossResultPath + "caches/images/");
 
-        //下载点位校准文件
-        fYunFileService.downloadFileByCommand(path + "/extras/", ossResultPath + "extras/");
+        //下载点位校准文件,刘强版本大改,要求只有包含字段vision_edit_version且vision_edit_version的值是1.0时,才下载vision_edit.txt文件进行计算,其他情况不保留
+        //2025-04-01,刘强再次要求,vision_edit_version >= 1.0 可以下载vision_edit.txt进行计算
+        if(fYunFileService.fileExist(ossResultPath + "extras/" + "vision_edit.txt")){
+            String fileContent = fYunFileService.getFileContent(ossResultPath + "extras/" + "vision_edit.txt");
+            JSONObject jsonObject = JSON.parseObject(fileContent);
+            if(jsonObject.containsKey("vision_edit_version")){
+                BigDecimal visionEditVersion = jsonObject.getBigDecimal("vision_edit_version");
+                if(visionEditVersion.compareTo(new BigDecimal("1.0")) != -1){
+                    fYunFileService.downloadFile(ossResultPath + "extras/vision_edit.txt", path + "/extras/vision_edit.txt");
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        JSONObject o = new JSONObject();
+        o.put("vision_edit_version", "1.1");
+
+        System.out.println(o.getBigDecimal("vision_edit_version"));
     }
 
     @Override
@@ -189,6 +207,11 @@ public class BuildObjServiceImpl implements IBuildSceneService {
 
             if (!message.getBuildSuccess()) {
                 log.error("生成OBJ场景计算失败!");
+
+                scenePlusService.update(new LambdaUpdateWrapper<ScenePlus>()
+                        .set(ScenePlus::getSceneStatus, SceneStatus.FAILD.code())
+                        .eq(ScenePlus::getNum, projectNum));
+
                 // 发送钉钉消息,计算失败
                 buildSceneDTService.handModelFail("生成OBJ场景计算失败!", message.getPath(), message.getBuildContext().get("sceneNum").toString(), message.getHostName());
                 return;
@@ -285,6 +308,7 @@ public class BuildObjServiceImpl implements IBuildSceneService {
                 //计算容量
                 Long space = commonService.getSpace(projectNum);
                 scenePlusExt.setSpace(space);
+                scenePlusExt.setMeshComputeTime(message.getComputeTime());
 
                 Object[] editInfoArr = commonService.updateEditInfo(scenePlus);
                 SceneEditInfo sceneEditInfo = (SceneEditInfo)editInfoArr[0];

+ 3 - 1
src/main/java/com/fdkankan/contro/mq/service/impl/BuildReverseE57SceneServiceImpl.java

@@ -106,6 +106,8 @@ public class BuildReverseE57SceneServiceImpl implements IBuildSceneService {
                 String path = (String)message.getExt().get("path");
                 //复制原始资源到home目录
                 fYunFileService.copyFileInBucket(path, homeKey);
+                //删除临时文件
+                fYunFileService.deleteFile(path);
                 key = homeKey;
             }else{
                 key = homeKey;
@@ -325,7 +327,7 @@ public class BuildReverseE57SceneServiceImpl implements IBuildSceneService {
     private void updateDbPlus(int sceneSource,Long space,String videosJson, Long computeTime,Integer isObj,ScenePlusExt scenePlusExt){
 
         scenePlusExt.setSpace(space);
-        scenePlusExt.setComputeTime(computeTime.toString());
+        scenePlusExt.setComputeTime(computeTime);
         scenePlusExt.setAlgorithmTime(new Date());
         scenePlusExt.setVideos(videosJson);
         scenePlusExt.setIsObj(isObj);

+ 35 - 15
src/main/java/com/fdkankan/contro/mq/service/impl/BuildSceneServiceImpl.java

@@ -2,9 +2,7 @@ package com.fdkankan.contro.mq.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.thread.ThreadUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.hutool.core.util.ZipUtil;
 import cn.hutool.extra.qrcode.QrCodeUtil;
 import cn.hutool.extra.qrcode.QrConfig;
 import cn.hutool.http.ContentType;
@@ -12,7 +10,6 @@ import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.fdkankan.common.constant.*;
 import com.fdkankan.common.util.FileUtils;
@@ -39,7 +36,6 @@ import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import com.fdkankan.redis.util.RedisUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpHeaders;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -49,10 +45,8 @@ import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
 import java.io.File;
 import java.io.IOException;
-import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.Map.Entry;
-import java.util.stream.Collectors;
 
 
 /**
@@ -136,6 +130,8 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
     private ISceneColdStorageService sceneColdStorageService;
     @Autowired
     private IWbService wbService;
+    @Autowired
+    private IAiService aiService;
 
 
     @Override
@@ -309,6 +305,17 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             //生成floorpan.json
             commonService.uploadFloorplanJson(sceneCode, path);
 
+            //江门需求,算法识别平面图
+            commonService.uploadFloorplanAi(sceneCode, path);
+
+            LinkedHashMap<Integer, Boolean> detFloorplan = message.getDetFloorplan();
+            boolean hasFloorplanAi = commonService.detFloorPlanAi(sceneCode, path, detFloorplan);
+            if(hasFloorplanAi){
+                scenePlus.setHasFloorplanAi(CommonStatus.YES.code().intValue());
+            }else{
+                scenePlus.setHasFloorplanAi(CommonStatus.NO.code().intValue());
+            }
+
             //重置异步操作记录
             commonService.removeSceneAsynOperLog(sceneCode);
 
@@ -325,15 +332,17 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             //容量统计
             Long space = commonService.getSpace(sceneCode);
 
+            //ai识别
+            aiService.detectScenePano(scenePlus, scenePlusExt, path);
+
             //写入数据库
-            this.updateDbPlus(scenePlus.getSceneSource(), space, videosJson.toJSONString(), message.getComputeTime(),isObj,scenePlusExt);
+            this.updateDbPlus(scenePlus, scenePlusExt, space, videosJson.toJSONString(), message.getComputeTime(),isObj);
 
             Object[] editInfoArr = commonService.updateEditInfo(scenePlus);
             SceneEditInfo sceneEditInfo = (SceneEditInfo)editInfoArr[0];
             SceneEditInfoExt sceneEditInfoExt = (SceneEditInfoExt)editInfoArr[1];
             SceneEditControls sceneEditControls = (SceneEditControls)editInfoArr[2];
 
-            //更新场景主表
             //如果相机容量不足,需要把场景的paystatus改为容量不足状态
 //            scenePlus.setPayStatus(commonService.getPayStatus(scenePlus.getCameraId(), space));
             //统计原始资源大小
@@ -347,6 +356,7 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
                         .sceneStatus(2)
                         .createTime(scenePlus.getCreateTime())
                         .shootCount(scenePlusExt.getShootCount())
+                        .slamCount(scenePlusExt.getSlamCount())
                         .payStatus(scenePlus.getPayStatus())
                         .mixture(scenePlusExt.getMixture())
                         .version(SceneVersionType.V4.code()).build());
@@ -563,10 +573,10 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
         }
     }
 
-    private void updateDbPlus(int sceneSource,Long space,String videosJson, Long computeTime,boolean isObj,ScenePlusExt scenePlusExt){
+    private void updateDbPlus(ScenePlus scenePlus,ScenePlusExt scenePlusExt, Long space,String videosJson, Long computeTime,boolean isObj){
 
         scenePlusExt.setSpace(space);
-        scenePlusExt.setComputeTime(computeTime.toString());
+        scenePlusExt.setComputeTime(computeTime);
         scenePlusExt.setAlgorithmTime(new Date());
         scenePlusExt.setVideos(videosJson);
         scenePlusExt.setIsObj(isObj ? 1 : 0);
@@ -575,7 +585,7 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             scenePlusExt.setSceneScheme(3);
         }
 
-        switch (SceneSource.get(sceneSource)){
+        switch (SceneSource.get(scenePlus.getSceneSource())){
             case BM:
                 scenePlusExt.setSceneResolution(SceneResolution.two_K.code());
                 scenePlusExt.setSceneFrom(SceneFrom.PRO.code());
@@ -603,10 +613,20 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
 //        scenePlusExt.setModelKind(modelKind);
 
         //统计点位数量
-        Map<String, Integer> result = this.getShootCount(scenePlusExt);
-        Integer shootCount = result.get("shootCount");
-        Integer mixture = result.get("mixture");
-        scenePlusExt.setShootCount(shootCount);
+        Integer shootCount = commonService.getShootCount(scenePlus.getNum());
+        if(Objects.nonNull(shootCount)){
+            scenePlusExt.setShootCount(shootCount);
+        }
+        Integer slamCount = commonService.getSlamCount(scenePlus.getNum());
+        if(Objects.nonNull(slamCount)){
+            scenePlusExt.setSlamCount(slamCount);
+        }
+        int mixture = CommonStatus.NO.code();
+        //如果点位数量和帧数都不为空,就是混合模式
+        if(Objects.nonNull(scenePlusExt.getShootCount()) && scenePlusExt.getShootCount() > 0
+                && Objects.nonNull(scenePlusExt.getSlamCount()) && scenePlusExt.getSlamCount() > 0){
+            mixture = CommonStatus.YES.code();
+        }
         scenePlusExt.setMixture(mixture);
 
         scenePlusExtService.updateById(scenePlusExt);

+ 1 - 1
src/main/java/com/fdkankan/contro/mq/service/impl/BuildV3SceneServiceImpl.java

@@ -239,7 +239,7 @@ public class BuildV3SceneServiceImpl implements IBuildSceneService {
 
             scenePro.setPayStatus(PayStatus.PAY.code());
             //如果相机容量不足,需要把场景的paystatus改为容量不足状态
-            scenePro.setPayStatus(commonService.getPayStatus(scenePro.getCameraId(), space));
+            scenePro.setPayStatus(commonService.getPayStatus(scenePro.getCameraId(), space, fdageData));
             sceneProService.update(
                     new LambdaUpdateWrapper<ScenePro>()
                             .set(ScenePro::getPayStatus, scenePro.getPayStatus())

+ 13 - 0
src/main/java/com/fdkankan/contro/service/IAiService.java

@@ -0,0 +1,13 @@
+package com.fdkankan.contro.service;
+
+import com.fdkankan.contro.entity.SceneMarkShape;
+import com.fdkankan.contro.entity.ScenePlus;
+import com.fdkankan.contro.entity.ScenePlusExt;
+
+public interface IAiService {
+
+    void detectScenePano(ScenePlus scenePlus, ScenePlusExt scenePlusExt, String path);
+
+    SceneMarkShape readDetectJson(String jsonPath);
+
+}

+ 15 - 3
src/main/java/com/fdkankan/contro/service/ICommonService.java

@@ -2,9 +2,10 @@ package com.fdkankan.contro.service;
 
 import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.contro.entity.*;
-import com.fdkankan.contro.vo.ScenePlusVO;
 import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
 
+import java.io.IOException;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
 
@@ -34,7 +35,7 @@ public interface ICommonService {
 
     String getOssOrignPath(String path);
 
-    int getPayStatus(Long cameraId, Long space);
+    int getPayStatus(Long cameraId, Long space, JSONObject dataFdageJson);
 
     void uploadStatusJson(String num, Integer sceneStatus, String webSite, String thumb, Integer payStatus, String uploadPath);
 
@@ -47,7 +48,7 @@ public interface ICommonService {
     void writeSceneJson(String num, SceneEditInfo sceneEditInfo, SceneEditInfoExt sceneEditInfoExt,
                         SceneEditControls sceneEditControls, ScenePlus scenePlus, ScenePlusExt scenePlusExt, Company company);
 
-    void saveMqSendLog(String num, BuildSceneCallMessage message);
+    void saveMqSendLog(String num, BuildSceneCallMessage message, Integer status);
 
     void sendUpdateSceneStatusMqToQueues(Map<String, Object> content);
 
@@ -58,4 +59,15 @@ public interface ICommonService {
     JSONObject getFdageData(String path);
 
     Map<String, String> getUploadFiles(ScenePlus scenePlus,String path,Integer cameraType,JSONObject fdageData) throws Exception;
+
+    boolean checkIsSpVr(JSONObject dataFdageJson, CameraDetail cameraDetail);
+
+    Integer getShootCount(String num);
+
+    Integer getSlamCount(String num);
+
+    void uploadFloorplanAi(String num, String path) throws IOException;
+
+    boolean detFloorPlanAi(String num, String path, LinkedHashMap<Integer, Boolean> detFloorplan) throws IOException;
+
 }

+ 22 - 0
src/main/java/com/fdkankan/contro/service/ISceneMarkShapeService.java

@@ -0,0 +1,22 @@
+package com.fdkankan.contro.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.contro.entity.SceneMarkShape;
+
+import java.util.List;
+
+/**
+ * Created by Xiewj on 2021/11/23 0026 10:14
+ */
+public interface ISceneMarkShapeService extends IService<SceneMarkShape> {
+
+    SceneMarkShape readDetectJson(String jsonPath);
+
+    List<SceneMarkShape> readDetectJsonStr(String num,String context);
+
+    SceneMarkShape findByNumAndImagePathAndType(String num, String imagePath,Integer type);
+
+    List<SceneMarkShape> findByNumAndType(String num, Integer type);
+
+}

+ 1 - 1
src/main/java/com/fdkankan/contro/service/ISceneProService.java

@@ -18,5 +18,5 @@ public interface ISceneProService extends IService<ScenePro> {
     Long sumUsedSpaceByCameraId(Long cameraId, String spaceTypeStr);
 
 
-
+    void generateObjFile(String num);
 }

+ 16 - 0
src/main/java/com/fdkankan/contro/service/SceneShapeEnumService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.contro.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.contro.entity.SceneShapeEnum;
+
+/**
+ * 标注框模型表 服务类接口
+ *
+ * @author Xiewj
+ * @since 2023-11-09 11:53
+ */
+public interface SceneShapeEnumService extends IService<SceneShapeEnum> {
+
+      SceneShapeEnum findByClassName(String className);
+}

+ 144 - 0
src/main/java/com/fdkankan/contro/service/impl/AiServiceImpl.java

@@ -0,0 +1,144 @@
+package com.fdkankan.contro.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.CommonStatus;
+import com.fdkankan.contro.constant.DetectType;
+import com.fdkankan.contro.entity.SceneMarkShape;
+import com.fdkankan.contro.entity.ScenePlus;
+import com.fdkankan.contro.entity.ScenePlusExt;
+import com.fdkankan.contro.entity.SceneShapeEnum;
+import com.fdkankan.contro.service.*;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.model.utils.ComputerUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class AiServiceImpl implements IAiService {
+
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+    @Autowired
+    private SceneShapeEnumService sceneShapeEnumService;
+    @Autowired
+    private ISceneMarkShapeService sceneMarkShapeService;
+
+    @Override
+    public void detectScenePano(ScenePlus scenePlus, ScenePlusExt scenePlusExt, String path) {
+        try {
+            String resultsPath = path + File.separator + "results" + File.separator;
+            String highPath = resultsPath + "high" + File.separator;
+            String aiWorkPath = highPath + "ai" + File.separator;
+            List<File> highImgs = FileUtil.loopFiles(highPath);
+            if(CollUtil.isEmpty(highImgs)){
+                return;
+            }
+
+            for (File file : highImgs) {
+                String absolutePath = file.getAbsolutePath();
+                try {
+                    String name = FileUtil.getName(absolutePath);
+                    String prefix = FileUtil.getPrefix(name);
+                    String outPath = aiWorkPath + prefix + File.separator;
+                    String detectPath = outPath + "detect.json";
+                    String cutImagesPath = outPath + "cut_images";
+                    if(!ComputerUtil.checkComputeCompleted(detectPath, 5, 200)){
+                        continue;
+                    }
+                    SceneMarkShape sceneMarkShape = readDetectJson(detectPath);
+                    if (ObjectUtil.isNotNull(sceneMarkShape)){
+                        sceneMarkShape.setNum(scenePlus.getNum());
+                        SceneMarkShape shape = sceneMarkShapeService.findByNumAndImagePathAndType(scenePlus.getNum(), sceneMarkShape.getImagePath(), DetectType.PANO.getCode());
+                        if (ObjectUtil.isNotNull(shape)){
+                            sceneMarkShape.setId(shape.getId());
+                            sceneMarkShape.setUpdateTime(new Date());
+                            sceneMarkShapeService.updateById(sceneMarkShape);
+                        }else {
+                            sceneMarkShape.setCreateTime(new Date());
+                            sceneMarkShape.setType(DetectType.PANO.getCode());
+                            sceneMarkShapeService.save(sceneMarkShape);
+                        }
+                    }
+                    if (FileUtil.exist(cutImagesPath)){
+                        //上传这个文件夹所有的文件
+                        List<File> files = FileUtil.loopFiles(cutImagesPath);
+                        String keyPath =  String.format(UploadFilePath.IMG_VIEW_PATH, scenePlus.getNum()) + "cut_images/";
+                        files.forEach(v -> fYunFileService.uploadFile(v.getAbsolutePath(),keyPath+v.getName()));
+                    }
+
+                }catch (Exception e){
+                    log.error("ai识别报错,inPath:{}", absolutePath, e);
+                }
+            }
+
+            //生成ai.json
+            List<SceneMarkShape> sceneMarkShapes = sceneMarkShapeService.findByNumAndType(scenePlus.getNum(), DetectType.PANO.getCode());
+            if(CollUtil.isNotEmpty(sceneMarkShapes)){
+                for (SceneMarkShape sceneMarkShape : sceneMarkShapes) {
+                    if (ObjectUtil.isNotEmpty(sceneMarkShape.getShapes())){
+                        for (JSONObject shape : sceneMarkShape.getShapes()) {
+                            String category = shape.getString("category");
+                            SceneShapeEnum sceneShapeEnum = sceneShapeEnumService.findByClassName(category);
+                            if (ObjectUtil.isNotNull(sceneShapeEnum)){
+                                shape.put("name",sceneShapeEnum.getName());
+                            }
+                            if (category.contains("Tag_")){
+                                shape.put("category","Tag");
+                            }
+                        }
+                    }
+                }
+
+                String ajJsonKey = String.format(UploadFilePath.IMG_VIEW_PATH, scenePlus.getNum()) + "ai.json";
+                fYunFileService.uploadFile(JSON.toJSONString(sceneMarkShapes).getBytes(StandardCharsets.UTF_8), ajJsonKey);
+
+                scenePlusExt.setHasRecognition(CommonStatus.YES.code().intValue());
+            }
+        }catch (Exception e){
+            log.error("ai识别出错,num:{}", scenePlus.getNum());
+        }
+    }
+
+    @Override
+    public SceneMarkShape readDetectJson(String jsonPath) {
+        String strings = FileUtil.readString(jsonPath, "UTF-8");
+        JSONObject bbbb = JSONObject.parseObject(strings);
+        SceneMarkShape parse = JSONObject.toJavaObject(bbbb, SceneMarkShape.class);
+        System.out.println(parse);
+        if (ObjectUtil.isNull(parse.getShapes())){
+            return null;
+        }
+        List<JSONObject> shapes = parse.getShapes();
+        for (JSONObject shape : shapes) {
+            shape.remove("name");
+            SceneShapeEnum category = sceneShapeEnumService.findByClassName(shape.getString("category"));
+            if (ObjectUtil.isNull(category)){
+                SceneShapeEnum sceneShapeEnum = new SceneShapeEnum();
+                sceneShapeEnum.setName(shape.getString("name"));
+                sceneShapeEnum.setClassName(shape.getString("category"));
+                sceneShapeEnumService.save(sceneShapeEnum);
+            }
+        }
+        return parse;
+    }
+
+}

+ 185 - 15
src/main/java/com/fdkankan/contro/service/impl/CommonServiceImpl.java

@@ -3,25 +3,24 @@ package com.fdkankan.contro.service.impl;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.ZipUtil;
 import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.fdkankan.common.constant.*;
-import com.fdkankan.common.util.FileUtils;
-import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.common.constant.*;
 import com.fdkankan.common.util.FileUtils;
 import com.fdkankan.contro.bean.SceneJsonBean;
+import com.fdkankan.contro.constant.DetectType;
 import com.fdkankan.contro.entity.*;
 import com.fdkankan.contro.factory.UserEditData.UserEditDataHandler;
 import com.fdkankan.contro.factory.UserEditData.UserEditDataHandlerFactory;
-import com.fdkankan.contro.service.ICommonService;
 import com.fdkankan.contro.service.*;
 import com.fdkankan.contro.vo.SceneEditControlsVO;
-import com.fdkankan.contro.vo.ScenePlusVO;
 import com.fdkankan.fyun.config.FYunFileConfig;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.model.constants.ConstantFileName;
@@ -29,6 +28,7 @@ import com.fdkankan.model.constants.ConstantFilePath;
 import com.fdkankan.model.constants.UploadFilePath;
 import com.fdkankan.model.utils.CreateObjUtil;
 import com.fdkankan.model.utils.FloorPlanUserUtil;
+import com.fdkankan.model.utils.SceneUtil;
 import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
 import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import com.fdkankan.redis.constant.RedisKey;
@@ -45,13 +45,8 @@ import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
 import java.io.File;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.security.GeneralSecurityException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.Objects;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -119,6 +114,10 @@ public class CommonServiceImpl implements ICommonService {
     private RabbitMqProducer rabbitMqProducer;
     @Autowired
     private ISceneInfoSyncMqConfigService sceneInfoSyncMqConfigService;
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+    @Autowired
+    private ISceneMarkShapeService sceneMarkShapeService;
 
     @Override
     public void uploadBuildResultData(String num, String dataSource, String version) {
@@ -459,6 +458,8 @@ public class CommonServiceImpl implements ICommonService {
         sceneJson.setModelKind(scenePlusExt.getModelKind());
         sceneJson.setVideos(scenePlusExt.getVideos());
         sceneJson.setPayStatus(scenePlus.getPayStatus());
+        sceneJson.setHasRecognition(scenePlusExt.getHasRecognition());
+        sceneJson.setHasFloorplanAi(scenePlus.getHasFloorplanAi());
         if(StrUtil.isNotEmpty(oldSceneJson)){
             SceneJsonBean oldSceneJsonBean = JSON.parseObject(oldSceneJson, SceneJsonBean.class);
             List<JSONObject> mosaicList = JSON.parseObject(oldSceneJson, SceneJsonBean.class).getMosaicList();
@@ -513,11 +514,19 @@ public class CommonServiceImpl implements ICommonService {
     }
 
     @Override
-    public void saveMqSendLog(String num, BuildSceneCallMessage message) {
-        MqSendLog mqSendLog = new MqSendLog();
+    public void saveMqSendLog(String num, BuildSceneCallMessage message, Integer status) {
+        MqSendLog mqSendLog = null;
+        if(status != null || status != -1){//-1代表未进入到计算前置处理器,计算调度器不能进行调度
+            mqSendLog = mqSendLogService.getOne(new LambdaQueryWrapper<MqSendLog>().eq(MqSendLog::getNum, num).eq(MqSendLog::getStatus, -1));
+        }
+        if(mqSendLog == null){
+            mqSendLog = new MqSendLog();
+        }
+
         mqSendLog.setNum(num);
         mqSendLog.setContent(JSON.toJSONString(message));
-        mqSendLogService.save(mqSendLog);
+        mqSendLog.setStatus(status);
+        mqSendLogService.saveOrUpdate(mqSendLog);
     }
 
     @Override
@@ -766,4 +775,165 @@ public class CommonServiceImpl implements ICommonService {
         return map;
 
     }
+
+    @Override
+    public boolean checkIsSpVr(JSONObject dataFdageJson, CameraDetail cameraDetail) {
+        if(Objects.isNull(cameraDetail)
+                || Objects.isNull(cameraDetail.getCompanyId())
+                || Objects.isNull(dataFdageJson)
+                || Objects.isNull(dataFdageJson.getInteger("location"))){
+            return false;
+        }
+        Integer location = dataFdageJson.getInteger("location");
+        Long companyId = cameraDetail.getCompanyId();
+        if(companyId == 26 && location == 7){
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Integer getShootCount(String num) {
+
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+
+        Integer shootCount = null;
+        String homePath = SceneUtil.getHomePath(scenePlusExt.getDataSource());
+        JSONObject dataFdageObj = JSON.parseObject(fYunFileService.getFileContent(homePath.concat("data.fdage")));
+        if(Objects.nonNull(dataFdageObj)){
+            JSONArray points = dataFdageObj.getJSONArray("points");
+            if(CollUtil.isNotEmpty(points)){
+                shootCount = points.size();
+            }
+        }
+
+        return shootCount;
+    }
+
+    @Override
+    public Integer getSlamCount(String num) {
+
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+
+        Integer slamCount = null;
+        String homePath = SceneUtil.getHomePath(scenePlusExt.getDataSource());
+        if(Objects.nonNull(scenePlusExt.getLocation()) && scenePlusExt.getLocation() == 6){
+            String slamDataStr = fYunFileService.getFileContent(homePath.concat("slam_data.json"));
+            JSONObject slamDataObj = JSON.parseObject(slamDataStr);
+            if(Objects.nonNull(slamDataObj)){
+                JSONArray viewsInfo = slamDataObj.getJSONArray("views_info");
+                if(CollUtil.isNotEmpty(viewsInfo)){
+                    slamCount = viewsInfo.stream().mapToInt(info -> {
+                        return  ((JSONObject) info).getJSONArray("list_pose").size();
+                    }).sum();
+                }
+            }
+        }
+
+        return slamCount;
+    }
+
+    @Override
+    public void uploadFloorplanAi(String num, String path) throws IOException {
+        String floorplanPath = path + "/results/floorplan/";
+        List<File> files = FileUtil.loopFiles(floorplanPath);
+        String ossPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "floorplan/";
+        if(CollUtil.isNotEmpty(files)){
+            for (File file : files) {
+                fYunFileService.uploadFile(file.getAbsolutePath(), file.getAbsolutePath().replace(floorplanPath, ossPath));
+            }
+        }
+    }
+
+    @Override
+    public boolean detFloorPlanAi(String num, String path, LinkedHashMap<Integer, Boolean> detFloorplan) throws IOException {
+
+        try {
+            String aiJsonKey = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "floorplan/ai.json";
+            String aiEntireJsonKey = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "floorplan/ai-entire.json";
+            //先清空历史数据,因为数据格式改动很多个版本,已经无法按照规律进行过滤删除,所以这里先删除历史数据,而后再根据算法生成去插入数据
+            sceneMarkShapeService.remove(new LambdaQueryWrapper<SceneMarkShape>().eq(SceneMarkShape::getNum, num).eq(SceneMarkShape::getType, DetectType.PLAN.getCode()));
+            if(fYunFileService.fileExist(aiJsonKey)){
+                fYunFileService.deleteFile(aiJsonKey);
+            }
+            if(CollUtil.isEmpty(detFloorplan)){
+                return false;
+            }
+            boolean hasFloorplanAi = false;
+            String workDir = path + "/detFloorplan/";
+            for (Integer subgroup : detFloorplan.keySet()) {
+                Boolean yes = detFloorplan.get(subgroup);
+                SceneMarkShape sceneMarkShape = null;
+                if(yes){
+                    String detectPath = workDir + subgroup + "/detect.json";
+                    sceneMarkShape = sceneMarkShapeService.readDetectJson(detectPath);
+                }
+                if (ObjUtil.isNull(sceneMarkShape)){
+                    sceneMarkShape = new SceneMarkShape();
+                    String infoJsonPath = path + "/results/floorplan/info.json";
+                    JSONObject infoObj = JSON.parseObject(FileUtil.readUtf8String(infoJsonPath));
+                    JSONArray floors = infoObj.getJSONArray("floors");
+                    for (Object floor : floors) {
+                        JSONObject floorObj = (JSONObject)floor;
+                        Integer group = floorObj.getInteger("subgroup");
+                        if(!subgroup.equals(group)){
+                            continue;
+                        }
+                        JSONObject resolution = floorObj.getJSONObject("resolution");
+                        sceneMarkShape.setImageWidth(resolution.getInteger("width"));
+                        sceneMarkShape.setImageHeight(resolution.getInteger("height"));
+                    }
+                }
+                if(Objects.isNull(sceneMarkShape.getShapes())){
+                    sceneMarkShape.setShapes(new ArrayList<>());
+                }
+                sceneMarkShape.setNum(num);
+                sceneMarkShape.setCreateTime(new Date());
+                sceneMarkShape.setType(DetectType.PLAN.getCode());
+                sceneMarkShapeService.save(sceneMarkShape);
+                if(CollUtil.isNotEmpty(sceneMarkShape.getShapes())){
+                    hasFloorplanAi = true;
+                }
+            }
+
+            List<SceneMarkShape> sceneMarkShapes = sceneMarkShapeService.findByNumAndType(num, DetectType.PLAN.getCode());
+            for (SceneMarkShape ms : sceneMarkShapes) {
+                if (ObjectUtil.isNotEmpty(ms.getShapes())){
+                    for (JSONObject s : ms.getShapes()) {
+                        String category = s.getString("category");
+                        if (category.contains("Tag_")){
+                            s.put("category","Tag");
+                        }
+                    }
+                }
+            }
+            //先上传一份带门窗的,完整的,绘图功能要用
+            fYunFileService.uploadFile(JSON.toJSONString(sceneMarkShapes).getBytes(StandardCharsets.UTF_8), aiEntireJsonKey);
+
+            //上传一份过滤掉门窗的,徐总要求过滤
+            for (SceneMarkShape sceneMarkShape : sceneMarkShapes) {
+                //徐总要求去掉门窗(因为门窗不属于家具)
+                List<JSONObject> shapes = sceneMarkShape.getShapes().stream().filter(v -> {
+                    String category = v.getString("category");
+                    if (StrUtil.isNotEmpty(category) && (category.contains("Door") || category.contains("Window"))) {
+                        return false;
+                    }
+                    return true;
+                }).collect(Collectors.toList());
+                sceneMarkShape.setShapes(shapes);
+            }
+            fYunFileService.uploadFile(JSON.toJSONString(sceneMarkShapes).getBytes(StandardCharsets.UTF_8), aiJsonKey);
+
+            return hasFloorplanAi;
+        }catch (Exception e){
+            log.error("平面图ai识别处理报错", e);
+            return false;
+        }finally {
+//            FileUtil.del(workDir);
+        }
+    }
+
+
 }

+ 3 - 0
src/main/java/com/fdkankan/contro/service/impl/IFdkkLaserServiceImpl.java

@@ -72,10 +72,12 @@ public class IFdkkLaserServiceImpl implements IFdkkLaserService {
             Integer sceneStatus = laserResultBean.getSceneStatus();
             Date createTime = laserResultBean.getCreateTime();
             Integer shootCount = laserResultBean.getShootCount();
+            Integer slamCount = laserResultBean.getSlamCount();
             Integer payStatus = laserResultBean.getPayStatus();
             Boolean mixture = laserResultBean.getMixture() == CommonStatus.NO.code().intValue() ? false : true;
             String version = SceneVersionType.V4.code();
 
+
             String jgPath = dataSource;
             //创建目录
             if (dataSource.lastIndexOf("/") != -1) {
@@ -115,6 +117,7 @@ public class IFdkkLaserServiceImpl implements IFdkkLaserService {
             params.put("algorithmTime", DateUtil.date2String(Calendar.getInstance().getTime(), null));
             params.put("path", jgPath + File.separator + "laserData");
             params.put("shootCount", shootCount);
+            params.put("slamCount", slamCount);
             params.put("payStatus", payStatus);
             params.put("mixture", mixture);
             rabbitMqProducer.sendByWorkQueue(updateScene, params);

+ 2 - 2
src/main/java/com/fdkankan/contro/service/impl/InnerServiceImpl.java

@@ -141,7 +141,7 @@ public class InnerServiceImpl implements IInnerService {
 
         //更新场景主表
         //如果相机容量不足,需要把场景的paystatus改为容量不足状态
-        scenePlus.setPayStatus(commonService.getPayStatus(scenePlus.getCameraId(), space));
+        scenePlus.setPayStatus(commonService.getPayStatus(scenePlus.getCameraId(), space, fdageData));
         //统计原始资源大小
         scenePlusExt.setOrigSpace(FileUtil.size(new File(path.concat(File.separator).concat("capture"))));
 
@@ -253,7 +253,7 @@ public class InnerServiceImpl implements IInnerService {
     private void updateDbPlus(int sceneSource,Long space,String videosJson, Long computeTime,boolean isObj,ScenePlusExt scenePlusExt){
 
         scenePlusExt.setSpace(space);
-        scenePlusExt.setComputeTime(computeTime.toString());
+        scenePlusExt.setComputeTime(computeTime);
         scenePlusExt.setAlgorithmTime(new Date());
         scenePlusExt.setVideos(videosJson);
         scenePlusExt.setIsObj(isObj ? 1 : 0);

+ 33 - 1
src/main/java/com/fdkankan/contro/service/impl/SceneFileBuildServiceImpl.java

@@ -252,6 +252,31 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
             throw new BusinessException(ErrorCode.FAILURE_CODE_5047);
         }
 
+        Camera camera = cameraService.getBySnCode(mac);
+        if(Objects.isNull(camera)){
+            camera = cameraService.getOne(new LambdaQueryWrapper<Camera>()
+                    .like(Camera::getChildName, mac)
+                    .or().like(Camera::getSnCode, mac)
+                    .or().like(Camera::getWifiName, mac));
+            if(Objects.isNull(camera)){
+                throw new BusinessException(ErrorCode.FAILURE_CODE_7010);
+            }
+        }
+        CameraDetail cameraDetail = cameraDetailService.getByCameraId(camera.getId());
+        if(Objects.isNull(cameraDetail)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7010);
+        }
+        Long companyId = cameraDetail.getCompanyId();
+        if(Objects.nonNull(companyId)){
+            Company company = companyService.getById(companyId);
+            if(Objects.nonNull(company)){
+                Integer canUpWebsite = company.getCanUpWebsite();
+                if(Objects.nonNull(canUpWebsite) && canUpWebsite == CommonStatus.NO.code().intValue()){
+                    throw new BusinessException(ErrorCode.FAILURE_CODE_4006);
+                }
+            }
+        }
+
         log.info("mac:{} 准备上传文件,folderName:{}", mac, folderName);
         ResponseSceneFile responseSceneFile = new ResponseSceneFile();
 
@@ -383,7 +408,8 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
         }
 
         //如果是相机计算容量的模式是场景个数模式,则需要拦截计算
-        if(rebuild == CommonStatus.NO.code()){//新场景需要校验容量是否超出限制
+        //文保系统v1.5.0增加需求,文保vr场景默认不封存(条件companyI=26&&location=7)
+        if(rebuild == CommonStatus.NO.code() && !commonService.checkIsSpVr(jsonObject, cameraDetail)){//新场景需要校验容量是否超出限制
             boolean exceedSpace = exceedSpaceSceneService.cehckExceedSpace(sceneNum, cameraDetail, cameraName, fileId, unicode);
             if(exceedSpace){
                 ScenePlusVO scenePlusVO = new ScenePlusVO();
@@ -1387,6 +1413,9 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
         }
         message.getExt().put("keepTitle", 1);
 
+        //提前发送调度器任务,用于管理后台页面及时刷新出“计算优先级”按钮
+        commonService.saveMqSendLog(num, new BuildSceneCallMessage(), -1);
+
         String ossOrignPath = commonService.getOssOrignPath(path);
         String ossPath = fYunFileService.getFileContent(ossOrignPath + "custom.txt");
         if(StrUtil.isNotEmpty(ossPath) && ossPath.contains("MKT862")){
@@ -1479,6 +1508,9 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
                 .set(ScenePlus::getSceneStatus, SceneStatus.wait.code())
                 .eq(ScenePlus::getNum, num));
 
+        //提前发送调度器任务,用于管理后台页面及时刷新出“计算优先级”按钮
+        commonService.saveMqSendLog(num, new BuildSceneCallMessage(), -1);
+
         HashMap<String, Object> params = new HashMap<>();
         params.put("num", num);
         params.put("rebuild", 1);

+ 99 - 0
src/main/java/com/fdkankan/contro/service/impl/SceneMarkShapeServiceImpl.java

@@ -0,0 +1,99 @@
+package com.fdkankan.contro.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.contro.constant.DetectType;
+import com.fdkankan.contro.entity.SceneMarkShape;
+import com.fdkankan.contro.entity.SceneShapeEnum;
+import com.fdkankan.contro.mapper.MarkShapeMapper;
+import com.fdkankan.contro.service.ISceneMarkShapeService;
+import com.fdkankan.contro.service.SceneShapeEnumService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+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 SceneShapeEnumService sceneShapeEnumService;
+
+    @Override
+    public SceneMarkShape readDetectJson(String jsonPath) {
+        String strings = FileUtil.readString(jsonPath, "UTF-8");
+        JSONObject bbbb = JSONObject.parseObject(strings);
+        SceneMarkShape parse = JSONObject.toJavaObject(bbbb, SceneMarkShape.class);
+        if (ObjectUtil.isNull(parse.getShapes())){
+            return null;
+        }
+        List<JSONObject> shapes = parse.getShapes();
+        for (JSONObject shape : shapes) {
+            SceneShapeEnum category = sceneShapeEnumService.findByClassName(shape.getString("category"));
+            if (ObjectUtil.isNull(category)){
+                SceneShapeEnum sceneShapeEnum = new SceneShapeEnum();
+                //删除数字shape.getString("name")
+                String nameWithoutNumbers = shape.getString("name").replaceAll("\\d+", "");
+                sceneShapeEnum.setName(nameWithoutNumbers);
+                sceneShapeEnum.setClassName(shape.getString("category"));
+                sceneShapeEnumService.save(sceneShapeEnum);
+            }
+        }
+        return parse;
+    }
+
+
+    @Override
+    public List<SceneMarkShape> readDetectJsonStr(String num,String context) {
+        JSONObject bbbb = JSONObject.parseObject(context);
+        JSONArray imgBoxsList = bbbb.getJSONArray("imgBoxsList");
+        List<SceneMarkShape> list = new ArrayList<>();
+        for (Object o : imgBoxsList) {
+            SceneMarkShape parse = JSONObject.toJavaObject(JSONObject.parseObject(String.valueOf(o)), SceneMarkShape.class);
+            System.out.println(parse);
+            if (ObjectUtil.isNull(parse.getShapes())){
+                return null;
+            }
+            parse.setType(DetectType.PANO.getCode());
+            parse.setNum(num);
+            List<JSONObject> shapes = parse.getShapes();
+            for (JSONObject shape : shapes) {
+                shape.remove("name");
+            }
+            list.add(parse);
+        }
+
+        return list;
+    }
+
+    @Override
+    public SceneMarkShape findByNumAndImagePathAndType(String num, String imagePath, Integer type) {
+        LambdaQueryWrapper<SceneMarkShape> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(SceneMarkShape::getNum,num);
+        wrapper.eq(SceneMarkShape::getImagePath,imagePath);
+        wrapper.eq(SceneMarkShape::getType,type);
+        return getOne(wrapper);
+    }
+
+    @Override
+    public List<SceneMarkShape> findByNumAndType(String num, Integer type) {
+        LambdaQueryWrapper<SceneMarkShape> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(SceneMarkShape::getNum,num);
+        wrapper.eq(SceneMarkShape::getType,type);
+        return this.list(wrapper);
+    }
+
+
+}

+ 155 - 4
src/main/java/com/fdkankan/contro/service/impl/SceneProServiceImpl.java

@@ -1,18 +1,33 @@
 package com.fdkankan.contro.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+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.PayStatus;
-import com.fdkankan.common.constant.SceneStatus;
-import com.fdkankan.common.constant.SpaceType;
+import com.fdkankan.common.constant.*;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.contro.common.Result;
+import com.fdkankan.contro.entity.ScenePlus;
+import com.fdkankan.contro.entity.ScenePlusExt;
 import com.fdkankan.contro.entity.ScenePro;
+import com.fdkankan.contro.httpclient.LaserClient;
 import com.fdkankan.contro.mapper.ISceneProMapper;
+import com.fdkankan.contro.mapper.ISceneUpgradeMapper;
+import com.fdkankan.contro.service.IScenePlusExtService;
+import com.fdkankan.contro.service.IScenePlusService;
 import com.fdkankan.contro.service.ISceneProService;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
 
+import javax.annotation.Resource;
 import java.util.List;
 import java.util.Objects;
 
@@ -28,6 +43,25 @@ import java.util.Objects;
 @Service
 public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro> implements ISceneProService {
 
+    private static final String GET_LASER_INIT_API = "/laser/init/@num@";
+    @Value("${4dkk.laserService.basePath}")
+    private String laserBasePath;
+
+    @Value("${queue.modeling.obj.modeling-pre}")
+    private String queueObjModelingPre;
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+    @Resource
+    private LaserClient laserClient;
+    @Autowired
+    private ISceneUpgradeMapper sceneUpgradeMapper;
+    @Resource
+    private RabbitMqProducer mqProducer;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+
     @Override
     public ScenePro getByNum(String num) {
         return this.getOne(new LambdaQueryWrapper<ScenePro>().eq(ScenePro::getNum, num));
@@ -58,4 +92,121 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         }
         return 0L;
     }
+
+    @Override
+    public void generateObjFile(String num) {
+        ScenePro sceneProEntity = this.getByNum(num);
+
+        if(ObjectUtils.isEmpty(sceneProEntity) || sceneProEntity.getIsUpgrade() == 1){
+            generatePlusObjFile(num);
+            return;
+        }
+
+        if(sceneProEntity.getSceneSource() != 4 && sceneProEntity.getSceneSource() != 5){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_3003, "只能操作激光场景");
+        }
+
+        // 拷贝文件
+        String path = sceneProEntity.getDataSource();
+        String ossPath = path.replace("/mnt/data","home")+"/data.fdage";
+        if(!fYunFileService.fileExist(ossPath)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_3037);
+        }
+
+        // 获取最新的场景名称
+        String url = laserBasePath + GET_LASER_INIT_API.replace("@num@", num);
+        Result laserSceneByNum = laserClient.getSceneByNum(url);
+        if(laserSceneByNum.getCode() != HttpStatus.OK.value()){
+            throw new RuntimeException("获取激光转台场景失败!");
+        }
+        JSONObject sceneInfo = JSONObject.parseObject(JSONObject.toJSONString(laserSceneByNum.getData()));
+        LambdaUpdateWrapper<ScenePro> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper
+                .set(ScenePro::getStatus, 0)
+                .set(ScenePro::getIsObj, 1)
+                .set(ScenePro::getIsUpgrade, 2)   //   升级中
+                .set(ScenePro::getSceneName, sceneInfo.getString("title"))
+                .eq(ScenePro::getNum, sceneProEntity.getNum());
+        this.update(updateWrapper);
+
+        //同步到scenePlus、scenePlus
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        if(Objects.nonNull(scenePlus)){
+            sceneUpgradeMapper.deleteScenePlus(num);
+            sceneUpgradeMapper.deleteScenePlusExt(scenePlus.getId());
+        }
+        sceneUpgradeMapper.transferScenePlus(num);
+        scenePlus = scenePlusService.getScenePlusByNum(num);
+        String sceneKind = sceneProEntity.getSceneScheme() == 3 ? SceneKind.FACE.code():SceneKind.TILES.code();
+        sceneUpgradeMapper.transferScenePlusExt(num, scenePlus.getId(), sceneKind);
+
+        log.info("开始发送激光场景生成obj mq消息");
+
+        // 发送MQ
+        BuildSceneCallMessage mqMsg = new BuildSceneCallMessage();
+        mqMsg.setSceneNum(sceneProEntity.getNum());
+        mqMsg.setAlgorithm(sceneProEntity.getAlgorithm());
+        mqMsg.setBuildType(sceneProEntity.getBuildType());
+        mqMsg.setPath(sceneProEntity.getDataSource());
+        mqProducer.sendByWorkQueue(queueObjModelingPre,mqMsg);
+    }
+
+    public void generatePlusObjFile(String num) {
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+
+        if(ObjectUtils.isEmpty(scenePlus)){
+            throw new BusinessException(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005);
+        }
+
+        if(scenePlus.getSceneSource() != 4 && scenePlus.getSceneSource() !=5){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_3003, "只能操作激光场景");
+        }
+
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+
+        String ossPath = scenePlusExt.getDataSource().replace("/mnt/data","home")+"/data.fdage";
+        if(!fYunFileService.fileExist(ossPath)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_3037);
+
+        }
+
+        // 获取最新的场景名称
+        String url = laserBasePath + GET_LASER_INIT_API.replace("@num@", num);
+        Result laserSceneByNum = laserClient.getSceneByNum(url);
+        if(laserSceneByNum.getCode() != HttpStatus.OK.value()){
+            throw new RuntimeException("获取激光转台场景失败!");
+        }
+        JSONObject sceneInfo = JSONObject.parseObject(JSONObject.toJSONString(laserSceneByNum.getData()));
+        LambdaUpdateWrapper<ScenePlus> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper
+                .set(ScenePlus::getSceneStatus, 0)
+                .set(ScenePlus::getTitle, sceneInfo.getString("title"))
+                .eq(ScenePlus::getNum, num);
+        scenePlusService.update(updateWrapper);
+
+        LambdaUpdateWrapper<ScenePlusExt> plusExtUpdateWrapper = new LambdaUpdateWrapper<>();
+        plusExtUpdateWrapper
+                .set(ScenePlusExt::getIsObj, 1)
+                .eq(ScenePlusExt::getPlusId, scenePlus.getId());
+        scenePlusExtService.update(plusExtUpdateWrapper);
+
+        log.info("开始发送激光场景生成obj mq消息");
+
+        // 发送MQ
+        BuildSceneCallMessage mqMsg = new BuildSceneCallMessage();
+        mqMsg.setSceneNum(num);
+        mqMsg.setAlgorithm(scenePlusExt.getAlgorithm());
+        mqMsg.setBuildType(scenePlusExt.getBuildType());
+        mqMsg.setPath(scenePlusExt.getDataSource());
+        mqProducer.sendByWorkQueue(queueObjModelingPre,mqMsg);
+    }
+
+    public JSONObject getSceneByNum(String num) {
+        Result result = laserClient.getSceneByNum(num);
+        if(result.getCode() != HttpStatus.OK.value()){
+            log.error("获取激光转台场景失败!");
+            return null;
+        }
+        return JSONObject.parseObject(JSONObject.toJSONString(result.getData()));
+    }
 }

+ 24 - 0
src/main/java/com/fdkankan/contro/service/impl/SceneShapeEnumServiceImpl.java

@@ -0,0 +1,24 @@
+package com.fdkankan.contro.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.contro.entity.SceneShapeEnum;
+import com.fdkankan.contro.mapper.SceneShapeEnumMapper;
+import com.fdkankan.contro.service.SceneShapeEnumService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 标注框模型表 服务实现类
+ *
+ * @author Xiewj
+ * @since 2023-11-09 11:53
+ */
+@Service
+public class SceneShapeEnumServiceImpl extends ServiceImpl<SceneShapeEnumMapper, SceneShapeEnum> implements SceneShapeEnumService {
+    @Override
+    public SceneShapeEnum findByClassName(String className) {
+        return this.getOne(new LambdaQueryWrapper<SceneShapeEnum>().eq(SceneShapeEnum::getClassName, className));
+    }
+
+
+}

+ 11 - 0
src/main/java/com/fdkankan/contro/vo/SceneEditControlsVO.java

@@ -1,5 +1,6 @@
 package com.fdkankan.contro.vo;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -83,5 +84,15 @@ public class SceneEditControlsVO implements Serializable {
      */
     private Integer showTexture;
 
+    /**
+     * 是否显示ai识别
+     */
+    private Integer showAi;
+
+    /**
+     * 是否显示点云跳转按钮
+     */
+    private Integer showLaser;
+
 
 }

+ 40 - 0
src/main/java/com/fdkankan/contro/vo/SceneParam.java

@@ -0,0 +1,40 @@
+package com.fdkankan.contro.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class SceneParam{
+    private String sceneSource;
+    private Long folderId;
+    private Integer folderType;
+    private Long userId;
+    private List<String> sourceList;
+    private List<String> numList;
+    private Integer hasFolder =1;   // 0 不包含文件夹,1包含
+
+    private String sceneName;       //场景名称
+    private String snCode;          //相机snCode
+    private List<String> snCodes;
+
+    private String userName;        //协作者名称
+
+    private String sceneNum;
+
+    private Integer type;
+
+    private Integer haveVoid;
+    private Integer status;
+
+    private Integer isObj;
+
+    private String startTime;
+    private String endTime;
+    private String num;
+
+    private String searchKey;
+    private Integer cameraId;
+    private Integer location;
+    private String platform;
+}

+ 5 - 0
src/main/resources/bootstrap-dev.yml

@@ -33,6 +33,11 @@ spring:
           - data-id: common-scaling.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: forest-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
+
       discovery:
         server-addr: ${spring.cloud.nacos.config.server-addr}
         namespace: ${spring.cloud.nacos.config.namespace}

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

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

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

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

+ 118 - 0
src/main/resources/mapper/contro/SceneUpgradeMapper.xml

@@ -0,0 +1,118 @@
+<?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.contro.mapper.ISceneUpgradeMapper">
+
+  <insert id="transferScenePlus" parameterType="java.lang.String">
+    INSERT INTO t_scene_plus (
+    `num`,
+    `user_id`,
+    `camera_id`,
+    `phone_id`,
+    `title`,
+    `description`,
+    `scene_status`,
+    `scene_source`,
+    `pay_status`,
+    `scene_type`,
+    `recommend`,
+    `create_time`,
+    `update_time`,
+    `rec_status`
+  )
+  SELECT
+    p.`num`,
+    p.`user_id`,
+    p.`camera_id`,
+    p.`phone_id`,
+    p.`scene_name`,
+    p.`scene_dec`,
+    p.`status`,
+    p.`scene_source`,
+    p.`pay_status`,
+    p.`scene_type`,
+    p.`recommend`,
+    p.`create_time`,
+    p.`update_time`,
+     p.rec_status
+  FROM
+    t_scene_pro p
+  WHERE p.num = #{num};
+  </insert>
+
+  <insert id="transferScenePlusExt">
+    INSERT INTO t_scene_plus_ext (
+    plus_id,
+    data_source,
+    web_site,
+    thumb,
+    scene_scheme,
+    SPACE,
+    ecs,
+    shoot_count,
+    view_count,
+    gps,
+    ALGORITHM,
+    firmware_version,
+    build_type,
+    create_time,
+    update_time,
+    rec_status,
+    scene_resolution,
+    scene_from,
+    scene_kind,
+    model_kind,
+    videos,
+    algorithm_time,
+    is_obj
+  )
+  SELECT
+    #{scenePlusId},
+    p.`data_source`,
+    p.`web_site`,
+    p.`thumb`,
+    p.`scene_scheme`,
+    p.`space`,
+    p.`ecs`,
+    p.`shoot_count`,
+    p.`view_count`,
+    p.`gps`,
+    p.`algorithm`,
+    p.`firmware_version`,
+    p.`build_type`,
+    p.`create_time`,
+    p.`update_time`,
+    p.rec_status ,
+    CASE
+      WHEN p.scene_source = 1 THEN '2k'
+      WHEN p.scene_source = 2 THEN '1k'
+      WHEN p.scene_source = 3 THEN '4k'
+      WHEN p.scene_source = 4 THEN '4k'
+      ELSE NULL
+     END AS scene_resolution,
+    CASE
+      WHEN p.scene_source = 1 THEN 'pro'
+      WHEN p.scene_source = 2 THEN 'lite'
+      WHEN p.scene_source = 3 THEN 'minion'
+      WHEN p.scene_source = 4 THEN 'laser'
+      ELSE NULL
+     END AS scene_from,
+    #{sceneKind} scene_kind,
+    'dam',
+    p.videos,
+    p.`create_time`,
+    p.is_obj
+  FROM
+    t_scene_pro p
+  WHERE p.num = #{num}
+  </insert>
+
+
+  <delete id="deleteScenePlus" parameterType="java.lang.String">
+    delete from t_scene_plus where num = #{num}
+  </delete>
+
+  <delete id="deleteScenePlusExt" parameterType="java.lang.Long">
+    delete from t_scene_plus_ext where plus_id = #{scenePlusId}
+  </delete>
+
+</mapper>