wuweihao преди 4 години
родител
ревизия
40ed13621d
променени са 69 файла, в които са добавени 4630 реда и са изтрити 0 реда
  1. 30 0
      laser/src/main/java/com/fdkankan/indoor/IndoorApplication.java
  2. 16 0
      laser/src/main/java/com/fdkankan/indoor/base/aop/WebControllerLog.java
  3. 127 0
      laser/src/main/java/com/fdkankan/indoor/base/aop/WebLogAspect.java
  4. 95 0
      laser/src/main/java/com/fdkankan/indoor/base/config/Swagger2.java
  5. 71 0
      laser/src/main/java/com/fdkankan/indoor/base/constant/ConfigConstant.java
  6. 35 0
      laser/src/main/java/com/fdkankan/indoor/base/exception/BaseRuntimeException.java
  7. 68 0
      laser/src/main/java/com/fdkankan/indoor/base/model/ViewResult.java
  8. 78 0
      laser/src/main/java/com/fdkankan/indoor/base/util/ConvertUtils.java
  9. 35 0
      laser/src/main/java/com/fdkankan/indoor/base/util/Factors.java
  10. 132 0
      laser/src/main/java/com/fdkankan/indoor/base/util/GisUtils.java
  11. 116 0
      laser/src/main/java/com/fdkankan/indoor/base/util/JsonUtil.java
  12. 275 0
      laser/src/main/java/com/fdkankan/indoor/base/util/JwtUtil.java
  13. 13 0
      laser/src/main/java/com/fdkankan/indoor/base/util/Options.java
  14. 87 0
      laser/src/main/java/com/fdkankan/indoor/base/util/RedisUtil.java
  15. 106 0
      laser/src/main/java/com/fdkankan/indoor/base/util/Result.java
  16. 59 0
      laser/src/main/java/com/fdkankan/indoor/core/controller/FilterController.java
  17. 92 0
      laser/src/main/java/com/fdkankan/indoor/core/controller/JsonDataController.java
  18. 91 0
      laser/src/main/java/com/fdkankan/indoor/core/controller/LoginController.java
  19. 53 0
      laser/src/main/java/com/fdkankan/indoor/core/controller/PoiController.java
  20. 115 0
      laser/src/main/java/com/fdkankan/indoor/core/controller/SiteModelController.java
  21. 28 0
      laser/src/main/java/com/fdkankan/indoor/core/dto/JsonDataDetailDto.java
  22. 20 0
      laser/src/main/java/com/fdkankan/indoor/core/dto/PoiSearchDto.java
  23. 16 0
      laser/src/main/java/com/fdkankan/indoor/core/dto/QueryJsonDataBase.java
  24. 18 0
      laser/src/main/java/com/fdkankan/indoor/core/dto/QueryJsonDataOne.java
  25. 20 0
      laser/src/main/java/com/fdkankan/indoor/core/dto/QueryJsonDataTwo.java
  26. 21 0
      laser/src/main/java/com/fdkankan/indoor/core/dto/SiteModelLatestDto.java
  27. 20 0
      laser/src/main/java/com/fdkankan/indoor/core/dto/SiteModelSearchDto.java
  28. 38 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/BaseEntity.java
  29. 67 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/SysUserEntity.java
  30. 26 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/jsonData/FilterEntity.java
  31. 35 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/jsonData/JsonData.java
  32. 35 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/jsonData/JsonData2.java
  33. 26 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/poi/PoiEntity.java
  34. 18 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/siteModel/Attributes.java
  35. 22 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/siteModel/Polygon.java
  36. 44 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/siteModel/SiteModel.java
  37. 37 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/siteModel/SiteModel2.java
  38. 37 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/tsiteModel/SiteModel.java
  39. 26 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/tsiteModel/TsiteModel.java
  40. 14 0
      laser/src/main/java/com/fdkankan/indoor/core/mapper/SysUserMapper.java
  41. 19 0
      laser/src/main/java/com/fdkankan/indoor/core/service/FilterService.java
  42. 19 0
      laser/src/main/java/com/fdkankan/indoor/core/service/JsonData2Service.java
  43. 16 0
      laser/src/main/java/com/fdkankan/indoor/core/service/JsonDataService.java
  44. 26 0
      laser/src/main/java/com/fdkankan/indoor/core/service/LoginService.java
  45. 14 0
      laser/src/main/java/com/fdkankan/indoor/core/service/PoiService.java
  46. 24 0
      laser/src/main/java/com/fdkankan/indoor/core/service/SiteModel2Service.java
  47. 17 0
      laser/src/main/java/com/fdkankan/indoor/core/service/SiteModelService.java
  48. 11 0
      laser/src/main/java/com/fdkankan/indoor/core/service/SysUserService.java
  49. 11 0
      laser/src/main/java/com/fdkankan/indoor/core/service/TsiteModelService.java
  50. 359 0
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/FilterServiceImpl.java
  51. 332 0
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/JsonData2ServiceImpl.java
  52. 144 0
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/JsonDataServiceImpl.java
  53. 131 0
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/LoginServiceImpl.java
  54. 148 0
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/PoiServiceImpl.java
  55. 440 0
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/SiteModel2ServiceImpl.java
  56. 197 0
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/SiteModelServiceImpl.java
  57. 46 0
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/SysUserServiceImpl.java
  58. 36 0
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/TsiteModelServiceImpl.java
  59. 27 0
      laser/src/main/java/com/fdkankan/indoor/core/vo/AttributesVo.java
  60. 16 0
      laser/src/main/java/com/fdkankan/indoor/core/vo/BaseVo.java
  61. 25 0
      laser/src/main/java/com/fdkankan/indoor/core/vo/GroupsVo.java
  62. 41 0
      laser/src/main/java/com/fdkankan/indoor/core/vo/UserVo.java
  63. 21 0
      laser/src/main/java/com/fdkankan/indoor/test/Demo.java
  64. 16 0
      laser/src/main/resources/application-dev.properties
  65. 13 0
      laser/src/main/resources/application-test.properties
  66. 13 0
      laser/src/main/resources/application.properties
  67. 8 0
      laser/src/main/resources/data/base.json
  68. 156 0
      laser/src/main/resources/logback-spring.xml
  69. 42 0
      laser/src/test/java/com/fdkankan/indoor/core/MongoTest.java

+ 30 - 0
laser/src/main/java/com/fdkankan/indoor/IndoorApplication.java

@@ -0,0 +1,30 @@
+package com.fdkankan.indoor;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * @author Admin
+ *
+ * http://test.4dkankan.com:9294/doc.html
+ *
+ */
+@SpringBootApplication
+@Slf4j
+public class IndoorApplication extends SpringBootServletInitializer {
+
+	@Override
+	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+		return application.sources(IndoorApplication.class);
+	}
+
+	public static void main(String[] args) {
+		SpringApplication.run(IndoorApplication.class, args);
+		log.info("indoor-demo启动");
+	}
+
+}

+ 16 - 0
laser/src/main/java/com/fdkankan/indoor/base/aop/WebControllerLog.java

@@ -0,0 +1,16 @@
+package com.fdkankan.indoor.base.aop;
+
+import java.lang.annotation.*;
+
+/**
+ * Created by Hb_zzZ on 2020/2/27.
+ */
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface WebControllerLog {
+    String description() default "";
+
+    //是否加入数据库
+    boolean addDb() default false;
+}

+ 127 - 0
laser/src/main/java/com/fdkankan/indoor/base/aop/WebLogAspect.java

@@ -0,0 +1,127 @@
+package com.fdkankan.indoor.base.aop;
+
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by owen on 2020/2/25 0025 9:24
+ *
+ * 日志aop
+ */
+@Slf4j
+@Aspect
+@Component
+public class WebLogAspect {
+
+    @Resource
+    private HttpServletRequest request;
+
+
+
+    private long startTime ;
+
+
+//    @Pointcut("execution(* com.gis.*.controller.*.*(..))")//切入点描述 这个是controller包的切入点
+    @Pointcut("execution(* com.fdkankan.indoor.core.controller.*.*(..))")//切入点描述 这个是controller包的切入点
+    public void controllerLog(){}//签名,可以理解成这个切入点的一个名称
+
+    @Before("controllerLog()") //在切入点的方法run之前要干的
+    public void logBeforeController(JoinPoint joinPoint) throws Exception {
+        startTime = System.currentTimeMillis();
+        // 记录下请求内容
+        String remoteAddr = request.getRemoteAddr();
+        log.warn("start : {}, uuid: {}" , request.getRequestURI(), startTime);
+        log.info("request Method:{}, IP:{}" , request.getMethod(),  request.getRemoteAddr());
+        log.info("request Args : {}" , Arrays.toString(joinPoint.getArgs()));
+
+
+
+        Map<String, Object> controllerLog = getControllerLog(joinPoint);
+        if (controllerLog.size() == 0) {
+            return;
+        }
+
+        String description = (String)controllerLog.get("description");
+        boolean addDb = (boolean)controllerLog.get("addDb");
+        log.info("request description:{}, addDb:{}", description, addDb);
+
+
+
+//        // 日志保存db
+//        if (addDb) {
+//            if (StringUtils.isNotBlank(description)) {
+//                // 保存数据库
+//                List<String> detail = getDetail(description);
+//            logService.save(new LogEntity(userId, detail.get(0), detail.get(1), remoteAddr));
+//            }
+//
+//        }
+
+
+        //下面这个getSignature().getDeclaringTypeName()是获取包+类名的   然后后面的joinPoint.getSignature.getName()获取了方法名
+//        log.info("request Class_Method : {}" , joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
+
+
+
+    }
+
+
+    //使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
+    @AfterReturning(returning = "ret", pointcut = "controllerLog()")
+    public void doAfterReturning(Object ret) throws Throwable {
+        // 处理完请求,返回内容
+        log.warn("end:{}, uuid: {},  响应耗时:{} ms", request.getRequestURI(), startTime, (System.currentTimeMillis() - startTime));
+    }
+
+    /**
+     * 获取注解中对方法的描述信息 用于Controller层注解
+     *
+     * @param joinPoint
+     *            切点
+     * @return 方法描述
+     * @throws Exception
+     */
+    private static Map<String, Object> getControllerLog(JoinPoint joinPoint) throws Exception {
+        String targetName = joinPoint.getTarget().getClass().getName();
+        String methodName = joinPoint.getSignature().getName();
+        Object[] arguments = joinPoint.getArgs();
+        Class targetClass = Class.forName(targetName);
+        Method[] methods = targetClass.getMethods();
+        Map<String, Object> result = new HashMap<>();
+        for (Method method : methods) {
+            if (method.getName().equals(methodName)) {
+                Class[] clazzs = method.getParameterTypes();
+                if (clazzs.length == arguments.length) {
+                    WebControllerLog annotation = method.getAnnotation(WebControllerLog.class);
+                    if (annotation != null) {
+                        String description = annotation.description();
+                        boolean addDb = annotation.addDb();
+                        result.put("description", description);
+                        result.put("addDb", addDb);
+                        break;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    private static List<String> getDetail(String str){
+        String[] split = str.split("-");
+        return Arrays.asList(split);
+    }
+
+}

+ 95 - 0
laser/src/main/java/com/fdkankan/indoor/base/config/Swagger2.java

@@ -0,0 +1,95 @@
+package com.fdkankan.indoor.base.config;
+
+import com.fdkankan.indoor.base.constant.ConfigConstant;
+import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
+import com.google.common.collect.Lists;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.SecurityReference;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by owen on 2020/2/18
+ *
+ * 集成Swagger有3步:
+ * 1.pom.xml添加依赖
+ * 2.添加Swagger2.class
+ * 3.Application.class 加上注解@EnableSwagger2 表示开启Swagger
+ * 4.http://localhost:8080/doc.html#/
+ *
+ * 2.9.2 不需要字启动类配置注解
+ */
+@Slf4j
+@Configuration
+@EnableSwagger2
+@EnableKnife4j
+public class Swagger2 {
+
+    @Autowired
+    ConfigConstant configConstant;
+
+    @Bean
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .apiInfo(apiInfo())
+                .select()
+                .apis(RequestHandlerSelectors.basePackage(configConstant.swaggerPackage))
+                .paths(PathSelectors.any())
+                .build()
+                //添加登录认证,可以使用token
+                .securityContexts(securityContexts())
+                .securitySchemes(securitySchemes())
+                ;
+    }
+
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title(configConstant.swaggerTitle)
+                .description(configConstant.swaggerDescription)
+                .version(configConstant.swaggerVersion)
+                .build();
+    }
+
+    private List<ApiKey> securitySchemes() {
+        //设置请求头信息
+        List<ApiKey> result = new ArrayList<>();
+        ApiKey apiKey = new ApiKey("Authorization", "token", "header");
+        result.add(apiKey);
+        return result;
+
+    }
+
+
+    private List<SecurityContext> securityContexts() {
+
+        SecurityContext context = SecurityContext.builder()
+                .securityReferences(defaultAuth())
+                .build();
+
+        return Lists.newArrayList(context);
+
+    }
+
+    private List<SecurityReference> defaultAuth() {
+        List<SecurityReference> result = new ArrayList<>();
+        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
+        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
+        authorizationScopes[0] = authorizationScope;
+        result.add(new SecurityReference("Authorization", authorizationScopes));
+        return result;
+    }
+}

+ 71 - 0
laser/src/main/java/com/fdkankan/indoor/base/constant/ConfigConstant.java

@@ -0,0 +1,71 @@
+package com.fdkankan.indoor.base.constant;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by owen on 2020/12/31 0031 14:22
+ *
+ * 全局动态参数
+ */
+@Component
+public class ConfigConstant {
+
+    /** 服务器文件地址*/
+//    @Value("${server.file.path}")
+//    public  String serverBasePath;
+
+//    @Value("${server.file.allow}")
+//    public String serverFileFallow;
+
+    /**redis token前缀*/
+//    @Value("${redis.prefix}")
+//    public  String redisPrefix;
+
+//    /**允许上传的文件后缀*/
+//    @Value("${file.allow}")
+//    public String fileAllow;
+
+//    @Value("${project.en}")
+//    public String projectEn;
+
+//    @Value("${project.name}")
+//    public String serverDomain;
+
+//    @Value("${oss.point}")
+//    public  String ossPoint;
+//
+//    @Value("${oss.key}")
+//    public  String ossKey;
+//
+//    @Value("${oss.secrecy}")
+//    public  String ossSecrecy;
+//
+//    @Value("${oss.bucket}")
+//    public  String ossBucket;
+//
+//    @Value("${oss.file.path}")
+//    public  String ossBasePath;
+//
+//    @Value("${oss.domain}")
+//    public  String ossDomain;
+
+
+    @Value("${swagger.package}")
+    public  String swaggerPackage;
+
+    @Value("${swagger.title}")
+    public  String swaggerTitle;
+
+    @Value("${swagger.description}")
+    public  String swaggerDescription;
+
+    @Value("${swagger.version}")
+    public  String swaggerVersion;
+
+
+
+
+
+
+}

+ 35 - 0
laser/src/main/java/com/fdkankan/indoor/base/exception/BaseRuntimeException.java

@@ -0,0 +1,35 @@
+package com.fdkankan.indoor.base.exception;
+
+public class BaseRuntimeException extends RuntimeException{
+
+    private static final long serialVersionUID = -1518945670203783450L;
+    private Integer code;
+    private String msg;
+
+    public BaseRuntimeException(String msg){
+        super(msg);
+        this.msg = msg;
+    }
+
+    public BaseRuntimeException(Integer code, String msg){
+        super(msg);
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+}

+ 68 - 0
laser/src/main/java/com/fdkankan/indoor/base/model/ViewResult.java

@@ -0,0 +1,68 @@
+package com.fdkankan.indoor.base.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.http.HttpStatus;
+
+
+/**
+ * @author zhujh
+ */
+@ApiModel
+@Data
+public class ViewResult<T> {
+
+    @ApiModelProperty("返回码")
+    private Integer code;
+
+    @ApiModelProperty("返回说明")
+    private String msg;
+
+    @ApiModelProperty("返回数据")
+    private T data;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public ViewResult(Integer code) {
+        this.code = code;
+    }
+
+    public ViewResult(Integer code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public ViewResult(Integer code, String msg, T data) {
+        this.code = code;
+        this.msg = msg;
+        this.data = data;
+    }
+
+    public static ViewResult success() {
+        return new ViewResult(HttpStatus.OK.value(), "操作成功");
+    }
+
+    public static ViewResult success(Object data) {
+        return new ViewResult(HttpStatus.OK.value(), "成功", data);
+    }
+
+    public static ViewResult success(Integer code, String msg, Object data) {
+        return new ViewResult(code, msg, data);
+    }
+
+    public static ViewResult success(Integer code, String msg) {
+        return new ViewResult(code, msg);
+    }
+
+    public static ViewResult error(String msg) {
+        return new ViewResult(500, msg);
+    }
+
+    public static ViewResult error(Integer code, String msg) {
+        return new ViewResult(code, msg);
+    }
+
+}

+ 78 - 0
laser/src/main/java/com/fdkankan/indoor/base/util/ConvertUtils.java

@@ -0,0 +1,78 @@
+package com.fdkankan.indoor.base.util;
+
+import net.sf.cglib.beans.BeanCopier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * @Description:(对象拷贝 - 性能比较好)   
+ * @author: ma wei long
+ * @date:   2020年6月17日 下午5:07:58
+ */
+public class ConvertUtils {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ConvertUtils.class);
+
+    public static <S, T> T convert(S source, Class<T> dest, Function<T, T> function) {
+        if (source == null) {
+            return null;
+        }
+        try {
+            T result = dest.newInstance();
+            final BeanCopier copier = BeanCopier.create(source.getClass(), dest, false);
+            copier.copy(source, result, null);
+            if (function != null) {
+                function.apply(result);
+            }
+            return result;
+        } catch (Exception e) {
+            LOGGER.error("convert error", e);
+        }
+        return null;
+    }
+
+    public static <S, T> T convert(S source, Class<T> dest) {
+        return convert(source, dest, null);
+    }
+
+    public static <S, T> T convert(S source, T dest) {
+        if (source == null || dest == null) {
+            return null;
+        }
+        T result = dest;
+        final BeanCopier copier = BeanCopier.create(source.getClass(), dest.getClass(), false);
+        copier.copy(source, result, null);
+        return result;
+    }
+
+    public static <S, T> List<T> convertList(List<S> source, Class<T> dest) {
+        return convertList(source, dest, null);
+    }
+
+    public static <S, T> List<T> convertList(List<S> source, Class<T> dest, ConvertCallback<S, T> callback) {
+        if (source == null) {
+            return null;
+        }
+        return source.stream().map(s -> {
+            T result = null;
+            try {
+                result = dest.newInstance();
+                convert(s, result);
+                if (callback != null) {
+                    callback.callback(s, result);
+                }
+            } catch (InstantiationException | IllegalAccessException e) {
+                LOGGER.error("convert error", e);
+            }
+            return result;
+        }).collect(Collectors.toList());
+    }
+
+    public interface ConvertCallback<S, D> {
+        void callback(S source, D dest);
+    }
+}

+ 35 - 0
laser/src/main/java/com/fdkankan/indoor/base/util/Factors.java

@@ -0,0 +1,35 @@
+package com.fdkankan.indoor.base.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Admin
+ */
+public class Factors {
+
+    //地球半径
+    public final static double EARTHRADIUS = 6371008.8;
+
+    public final static Map<String, Double> NAV_ITEM_ADPTER = new HashMap<String, Double>() {
+        {
+            put("centimeters", EARTHRADIUS * 100);
+            put("degrees", EARTHRADIUS / 111325);
+            put("feet", EARTHRADIUS * 3.28084);
+            put("inches", EARTHRADIUS * 39.37);
+            put("kilometers", EARTHRADIUS / 1000);
+            put("meters", EARTHRADIUS);
+            put("miles", EARTHRADIUS / 1609.344);
+            put("millimeters", EARTHRADIUS * 1000);
+            put("nauticalmiles", EARTHRADIUS / 1852);
+            put("radians", 1.0);
+            put("yards", EARTHRADIUS);
+        }
+    };
+
+
+    public static Double getFactorsData(String unit) {
+        return NAV_ITEM_ADPTER.get(unit);
+    }
+
+}

+ 132 - 0
laser/src/main/java/com/fdkankan/indoor/base/util/GisUtils.java

@@ -0,0 +1,132 @@
+package com.fdkankan.indoor.base.util;
+
+import org.junit.Test;
+
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by owen on 2021/7/19 0019 9:37
+ */
+public class GisUtils {
+
+
+    /**
+     * 判断该点是否在区域内
+     * 说明:该点出发的射线模拟为向左射出的水平射线
+     *
+     * @param pointList
+     * @param point
+     * @return
+     */
+    public static Boolean isInArea(List<Point2D.Double> pointList, Point2D.Double point) {
+        Boolean flag = true; //是否在区域内标识
+        Point2D.Double p, p1, p2;
+        Integer across = 0; //穿越次数
+        double precision = 2e-10; //浮点类型计算时候的比较容差
+        p = point;
+
+        for (int i = 0; i < pointList.size(); i++) {
+            p1 = pointList.get(i);
+            int j = (i + 1) >= pointList.size() ? 0 : (i + 1);
+            p2 = pointList.get(j);
+            // 1、判断是否在点上
+            if (p1.equals(p) || p2.equals(p)) {
+                return flag;
+            }
+            // 2、该点是否在两个端点之间
+            if (p.y <= Math.max(p1.y, p2.y) && p.y >= Math.min(p1.y, p2.y)) {
+                // 3、判断该点是否在两点连成的线段上
+                if (p.x <= Math.max(p1.x, p2.x) && p.x >= Math.min(p1.x, p2.x)) {
+                    // 其一:该线段是水平线
+                    if (p1.y == p2.y) {
+                        if (p.y == p1.y) {
+                            return flag;
+                        }
+                    }
+                    // 其二:该线段是垂直线
+                    if (p1.x == p2.x) {
+                        if (p.x == p1.x) {
+                            return flag;
+                        }
+                    }
+                    // 其三:该线段是斜线
+                    double xianShangY = p1.y + (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x);
+                    if (Math.abs(xianShangY - p.y) < precision) {
+                        // 在线上
+                        return flag;
+                    }
+                }
+                // 4、判断两个端点是否越过该点(因为是左水平射线)
+                if (p.x <= Math.min(p1.x, p2.x)) {
+                    continue;
+                }
+               /*
+                    该点位于两个端点之间,判断是否穿过顶点(穿过顶点时,顶点按照在射线上部处理)
+                    穿过顶点时,只有两个端点在射线两侧的才按照穿越处理
+                */
+                if (p1.y != p2.y && p.y != Math.min(p1.y, p2.y)) {
+                    across++;
+                }
+            }
+        }
+        if (across % 2 == 0) {
+            // 偶数,在外部
+            return !flag;
+        }
+        return flag;
+    }
+
+
+
+    public static Boolean rayCasting(List<Point2D.Double> list,Point2D.Double p ) {
+        double px = p.x, py = p.y;
+        boolean flag = false;
+        //
+        for (int i = 0, l = list.size(), j = l - 1; i < l; j = i, i++) {
+            //取出边界的相邻两个点
+            double sx = list.get(i).x,
+                    sy = list.get(i).y,
+                    tx = list.get(j).x,
+                    ty = list.get(j).y;
+            // 点与多边形顶点重合
+            if ((sx == px && sy == py) || (tx == px && ty == py)) {
+                return true;
+            }
+            // 判断线段两端点是否在射线两侧
+            //思路:作p点平行于y轴的射线 作s,t的平行线直线  如果射线穿过线段,则py的值在sy和ty之间
+            if ((sy < py && ty >= py) || (sy >= py && ty < py)) {
+                // 线段上与射线 Y 坐标相同的点的 X 坐标 ,即求射线与线段的交点
+                double x = sx + (py - sy) * (tx - sx) / (ty - sy);
+                // 点在多边形的边上
+                if (x == px) {
+                    return true;
+                }
+                // 射线穿过多边形的边界
+                if (x > px) {
+                    flag = !flag;
+                }
+            }
+        }
+        // 射线穿过多边形边界的次数为奇数时点在多边形内
+        return flag ;
+    }
+
+
+    @Test
+    public void test(){
+        Point2D.Double p = new Point2D.Double(1.0, 2.4);
+        List<Point2D.Double> list = new ArrayList<Point2D.Double>();
+        list.add(new Point2D.Double(1.0, 2.0));
+        list.add(new Point2D.Double(2.0, 3.0));
+        list.add(new Point2D.Double(1.0, 1.0));
+        list.add(new Point2D.Double(3.0, 5.0));
+        list.add(new Point2D.Double(3.0, 2.0));
+        // list为多边形边界,p为一个待测点
+        Boolean flag = rayCasting( list,p);
+        System.out.println(flag);
+
+    }
+
+}

+ 116 - 0
laser/src/main/java/com/fdkankan/indoor/base/util/JsonUtil.java

@@ -0,0 +1,116 @@
+package com.fdkankan.indoor.base.util;
+
+import java.awt.geom.Point2D;
+import java.util.List;
+
+/**
+ * @author Admin
+ */
+public class JsonUtil {
+
+    public static double distance(Double[] coordinates1, Double[] coordinates2, Options options) {
+        double dLat = degreesToRadians(coordinates2[1] - coordinates1[1]);
+        double dLon = degreesToRadians(coordinates2[0] - coordinates1[0]);
+        double lat1 = degreesToRadians(coordinates1[1]);
+        double lat2 = degreesToRadians(coordinates2[1]);
+
+        double a = Math.pow(Math.sin(dLat / 2), 2) +
+                        Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2);
+
+        return radiansToLength(
+                2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)),
+                options.getUnits()
+        );
+    }
+
+
+    public static double degreesToRadians(Double degrees) {
+        if (degrees == null) {
+            return 0.0D;
+        }
+        double radians = degrees % 360;
+        return (radians * Math.PI) / 180;
+    }
+
+    public static double radiansToLength(double radians, String units) {
+        Double factor = Factors.getFactorsData(units);
+        if (factor == null) {
+            throw new RuntimeException(units + " units is invalid");
+        }
+        return radians * factor;
+    }
+
+
+    /**
+     * 判断点是否在多边形内
+     * @param point 检测点
+     * @param pts   多边形的顶点
+     * @return      点在多边形内返回true,否则返回false
+     */
+    public static boolean IsPtInPoly(Point2D.Double point, List<Point2D.Double> pts){
+
+        int N = pts.size();
+        boolean boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
+        int intersectCount = 0;//cross points count of x
+        double precision = 2e-10; //浮点类型计算时候与0比较时候的容差
+        Point2D.Double p1, p2;//neighbour bound vertices
+        Point2D.Double p = point; //当前点
+
+        p1 = pts.get(0);//left vertex
+        for(int i = 1; i <= N; ++i){//check all rays
+            if(p.equals(p1)){
+                return boundOrVertex;//p is an vertex
+            }
+
+            p2 = pts.get(i % N);//right vertex
+            if(p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)){//ray is outside of our interests
+                p1 = p2;
+                continue;//next ray left point
+            }
+
+            if(p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)){//横坐标 内  ray is crossing over by the algorithm (common part of)
+                if(p.y <= Math.max(p1.y, p2.y)){//y下  x is before of ray
+                    if(p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)){//overlies on a horizontal ray  垂线
+                        return boundOrVertex;
+                    }
+
+                    if(p1.y == p2.y){//水平线 ray is vertical
+                        if(p1.y == p.y){//水平线内 overlies on a vertical ray
+                            return boundOrVertex;
+                        }else{//before ray
+                            ++intersectCount;  //交点在上方
+                        }
+                    }else{//cross point on the left side
+                        double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;//两点式化简,交点y坐标 cross point of y
+                        if(Math.abs(p.y - xinters) < precision){//== 0  在线上  overlies on a ray
+                            return boundOrVertex;
+                        }
+
+                        if(p.y < xinters){//before ray
+                            ++intersectCount;  //交点在上方
+                        }
+                    }
+                }
+            }else{//special case when ray is crossing through the vertex
+                if(p.x == p2.x && p.y <= p2.y){//p crossing over p2
+                    Point2D.Double p3 = pts.get((i+1) % N); //next vertex
+                    if(p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)){//p.x lies between p1.x & p3.x
+                        ++intersectCount;
+                    }else{
+                        intersectCount += 2;
+                    }
+                }
+            }
+            p1 = p2;//next ray left point
+        }
+
+        if(intersectCount % 2 == 0){//偶数在多边形外
+            return false;
+        } else { //奇数在多边形内
+            return true;
+        }
+
+    }
+
+
+}

+ 275 - 0
laser/src/main/java/com/fdkankan/indoor/base/util/JwtUtil.java

@@ -0,0 +1,275 @@
+package com.fdkankan.indoor.base.util;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.interfaces.Claim;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import com.fdkankan.indoor.base.exception.BaseRuntimeException;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.JwtBuilder;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import lombok.extern.log4j.Log4j2;
+import org.junit.Test;
+import org.springframework.util.Assert;
+
+import java.util.*;
+
+@Log4j2
+public class JwtUtil {
+
+    //生成签名的时候使用的秘钥secret
+    private static final String SECRET = "XX#$%()(#*!()!KL<><MQLMNQNQJQK&sdfkjsdrow32234545fdf>?N<:{LWPW";
+
+    /**
+     * 用户登录成功后生成Jwt
+     * 使用Hs256算法  私匙使用用户密码
+     *
+     * @param ttlMillis jwt过期时间
+     * @param userName  用户名
+     * @return
+     */
+    public static String createJWT(long ttlMillis, String userName) {
+        //指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
+        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
+
+        //生成JWT的时间
+        long nowMillis = System.currentTimeMillis();
+        Date now = new Date(nowMillis);
+
+        //创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
+        Map<String, Object> claims = new HashMap<String, Object>();
+        claims.put("userName", userName);
+
+        //下面就是在为payload添加各种标准声明和私有声明了
+        //这里其实就是new一个JwtBuilder,设置jwt的body
+        JwtBuilder builder = Jwts.builder()
+                //如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
+                .setClaims(claims)
+                //设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
+                .setId(UUID.randomUUID().toString())
+                //iat: jwt的签发时间
+                .setIssuedAt(now)
+                //代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。
+                .setSubject(userName)
+                //设置签名使用的签名算法和签名使用的秘钥
+                .signWith(signatureAlgorithm, SECRET);
+
+        if (ttlMillis >= 0) {
+            long expMillis = nowMillis + ttlMillis;
+            Date exp = new Date(expMillis);
+            //设置过期时间
+            builder.setExpiration(exp);
+        }/*else{
+            //设置过期时间半小时
+            DateTime expDate = new DateTime().plusMinutes(30);
+            builder.setExpiration(expDate.toDate());
+        }*/
+        return builder.compact();
+    }
+
+
+    /**
+     * Token的解密
+     *
+     * @param token 加密后的token
+     * @return
+     */
+    public static Claims parseJWT(String token) {
+        //得到DefaultJwtParser
+        Claims claims = Jwts.parser()
+                //设置签名的秘钥
+                .setSigningKey(SECRET)
+                //设置需要解析的jwt
+                .parseClaimsJws(token).getBody();
+        return claims;
+    }
+
+    public static String getTokenStringValueByKey(String token, String key) {
+        DecodedJWT jwt = JWT.decode(token);
+        Claim value = jwt.getClaim(key);
+
+        if (value == null) {
+            log.error("token key is null");
+            throw new BaseRuntimeException(5001, "token invalid");
+        }
+        return value.asString();
+    }
+
+
+    /**
+     * 校验token
+     * 在这里可以使用官方的校验,我这里校验的是token中携带的密码于数据库一致的话就校验通过
+     *
+     * @param token
+     * @param userName
+     * @return
+     */
+    public static Boolean isVerify(String token, String userName) {
+
+        //得到DefaultJwtParser
+        Claims claims = Jwts.parser()
+                //设置签名的秘钥
+                .setSigningKey(SECRET)
+                //设置需要解析的jwt
+                .parseClaimsJws(token).getBody();
+
+        return claims.get("userName").equals(userName);
+    }
+
+    /**
+     * 获得token中的信息无需secret解密也能获得
+     *
+     * @return token中包含的用户名
+     */
+    public static String getUsername(String token) {
+        DecodedJWT jwt = JWT.decode(token);
+        Claim userName = jwt.getClaim("userName");
+        Assert.notNull(userName, "token userName is null ");
+        return userName.asString();
+    }
+
+
+    public static List getUserRole(String token) {
+        DecodedJWT jwt = JWT.decode(token);
+        Claim role = jwt.getClaim("role");
+        Assert.notNull(role, "token role is null ");
+        return role.as(List.class);
+    }
+
+
+    public static String createJWT(long ttlMillis, Map<String, Object> paramMap) {
+        //指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
+        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
+
+        String userName = paramMap.get("userName").toString();
+
+        //生成JWT的时间
+        long nowMillis = System.currentTimeMillis();
+        Date now = new Date(nowMillis);
+
+        //创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
+        Map<String, Object> claims = new HashMap<String, Object>();
+        claims.put("userName", userName);
+        claims.put("id", paramMap.get("id"));
+        claims.put("role", paramMap.get("role"));
+        claims.put("manager", paramMap.get("manager"));
+
+        //下面就是在为payload添加各种标准声明和私有声明了
+        //这里其实就是new一个JwtBuilder,设置jwt的body
+        JwtBuilder builder = Jwts.builder()
+                //如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
+                .setClaims(claims)
+                //设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
+                .setId(UUID.randomUUID().toString())
+                //iat: jwt的签发时间
+                .setIssuedAt(now)
+                //代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。
+                .setSubject(userName)
+                //设置签名使用的签名算法和签名使用的秘钥
+                .signWith(signatureAlgorithm, SECRET);
+
+        if (ttlMillis >= 0) {
+            long expMillis = nowMillis + ttlMillis;
+            Date exp = new Date(expMillis);
+            //设置过期时间
+            builder.setExpiration(exp);
+        }/*else{
+            //设置过期时间半小时
+            DateTime expDate = new DateTime().plusMinutes(30);
+            builder.setExpiration(expDate.toDate());
+        }*/
+        return builder.compact();
+    }
+
+    /**
+     * 获取用户id
+     */
+    public static Long getUserId(String token) {
+        DecodedJWT jwt = JWT.decode(token);
+        Claim id = jwt.getClaim("id");
+        Assert.notNull(id, "token id is null ");
+        return id.asLong();
+    }
+
+
+    /**
+     * 管理者 ,0:是, 1:否
+     */
+    public static Boolean getUserManager(String token) {
+        DecodedJWT jwt = JWT.decode(token);
+        Claim id = jwt.getClaim("manager");
+        Assert.notNull(id, "token manager is null ");
+        Integer integer = id.asInt();
+        return integer == 0;
+    }
+
+    public static void main(String[] args) {
+        long nowMillis = System.currentTimeMillis();
+        System.out.println(nowMillis);
+        Date exp = new Date(nowMillis);
+        System.out.println(exp);
+    }
+
+    public static void test2() {
+        String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInJvbGUiOlsiYWRtaW4iLCJyb290Il0sImlkIjoxLCJ1c2VyTmFtZSI6ImFkbWluIiwiaWF0IjoxNTgzODA5MzkzLCJqdGkiOiJkNjZiZTFkYi00MTQ0LTQxMTYtYTNlNi01ZDBjNjhlNTI3ODAifQ.-4AdsVP2RwmPS2grtO4aC8ov9PwkilzaGdThGetBJok";
+        System.out.println(getUserRole(token));
+
+    }
+
+    public static void test3() {
+        HashMap<String, Object> map = new HashMap<>();
+
+        ArrayList<Object> list = new ArrayList<>();
+        list.add("admin");
+        list.add("root");
+
+        map.put("userName", "admin");
+        map.put("id", Long.valueOf("1"));
+        map.put("role", list);
+
+        String token = createJWT(-1, map);
+        System.out.println(token);
+
+        Boolean isVerify = isVerify(token, "admin");
+        System.out.println(isVerify);
+
+    }
+
+    private static void testList() {
+        ArrayList<Object> list = new ArrayList<>();
+        list.add("admin");
+        list.add("root");
+    }
+
+    /**
+     * 检查token是否有效
+     */
+    @Test
+    public void testCheckToken(){
+        String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMzExMjMxMTE3OCIsInVzZXJOYW1lIjoiMTMxMTIzMTExNzgiLCJpYXQiOjE2MTM2MjAzNjcsImp0aSI6IjMyYTAwZDNiLTE2ODctNDUzNi04NmIwLWY4OTMzODQzNzNjMiJ9.5sV47Yf0HU4m6u77jmCziR3KhAGfiL5aUKxo57MImTI";
+        String username = getUsername(token);
+        Long userId = getUserId(token);
+        System.out.println(username);
+        System.out.println("id: " + userId );
+    }
+
+
+    @Test
+    public void testIsVerify(){
+        String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMzExMjMxMTE3OCIsInVzZXJOYW1lIjoiMTMxMTIzMTExNzgiLCJpYXQiOjE2MTM2MjAzNjcsImp0aSI6IjMyYTAwZDNiLTE2ODctNDUzNi04NmIwLWY4OTMzODQzNzNjMiJ9.5sV47Yf0HU4m6u77jmCziR3KhAGfiL5aUKxo57MImTI";
+        String userName = "13112311178";
+        Boolean verify = isVerify(token, userName);
+        System.out.println(verify);
+    }
+
+
+    /**
+     * 解析出来是一个对象
+     */
+    @Test
+    public void testParseJWT(){
+        String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInJvbGUiOlsiYWRtaW4iLCJyb290Il0sImlkIjoxLCJ1c2VyTmFtZSI6ImFkbWluIiwiaWF0IjoxNTgzODA5MzkzLCJqdGkiOiJkNjZiZTFkYi00MTQ0LTQxMTYtYTNlNi01ZDBjNjhlNTI3ODAifQ.-4AdsVP2RwmPS2grtO4aC8ov9PwkilzaGdThGetBJok";
+        System.out.println(parseJWT(token));
+    }
+
+}

+ 13 - 0
laser/src/main/java/com/fdkankan/indoor/base/util/Options.java

@@ -0,0 +1,13 @@
+package com.fdkankan.indoor.base.util;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @author Admin
+ */
+@Data
+@Accessors(chain = true)
+public class Options {
+    private String units;
+}

+ 87 - 0
laser/src/main/java/com/fdkankan/indoor/base/util/RedisUtil.java

@@ -0,0 +1,87 @@
+package com.fdkankan.indoor.base.util;
+
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by owen on 2021/7/9 0009 14:32
+ */
+@Component
+public class RedisUtil {
+
+//    @Autowired
+    @Resource
+    private RedisTemplate<String, Object> redisTemplate;
+
+
+    /**
+     * 普通缓存放入并设置时间
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
+     * @return true成功 false 失败
+     */
+    public boolean set(String key, Object value, long time) {
+        try {
+            if (time > 0) {
+                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+            } else {
+                set(key, value);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 普通缓存放入
+     *
+     * @param key   键
+     * @param value 值
+     * @return true成功 false失败
+     */
+    public boolean set(String key, Object value) {
+        try {
+            redisTemplate.opsForValue().set(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+
+    }
+
+    /**
+     * 删除缓存
+     *
+     * @param key 可以传一个值 或多个
+     */
+    @SuppressWarnings("unchecked")
+    public void del(String... key) {
+        if (key != null && key.length > 0) {
+            if (key.length == 1) {
+                redisTemplate.delete(key[0]);
+            } else {
+                redisTemplate.delete(CollectionUtils.arrayToList(key));
+            }
+        }
+    }
+
+
+    /**
+     * 普通缓存获取
+     *
+     * @param key 键
+     * @return 值
+     */
+    public Object get(String key) {
+        return key == null ? null : redisTemplate.opsForValue().get(key);
+    }
+}

+ 106 - 0
laser/src/main/java/com/fdkankan/indoor/base/util/Result.java

@@ -0,0 +1,106 @@
+package com.fdkankan.indoor.base.util;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 通用返回类
+ *
+ * @author
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Result<T> implements Serializable {
+    private static final long serialVersionUID = -1491499610244557029L;
+    public static final String SUCCESS_MSG = "操作成功";
+    public static int CODE_SUCCESS = 0;
+    public static int CODE_FAILURE = -1;
+    public static String[] NOOP = new String[]{};
+    public static LocalDateTime dataTime = LocalDateTime.now();
+
+    /**
+     * 处理状态:0: 成功, 1: 失败
+     */
+    @ApiModelProperty(value = "处理状态:0: 成功, -1: 失败", name = "code")
+    private int code;
+    /**
+     * 消息
+     */
+    @ApiModelProperty(value = "消息", name = "msg")
+    private String msg;
+    /**
+     * 返回数据
+     */
+    @ApiModelProperty(value = "返回数据", name = "data")
+    private T data;
+
+    @ApiModelProperty(value = "时间戳", name = "timestamp")
+    private LocalDateTime timestamp;
+    /**
+     * 处理成功,并返回数据
+     *
+     * @param data 数据对象
+     * @return data
+     */
+    public static Result success(Object data) {
+        return new Result(CODE_SUCCESS, SUCCESS_MSG, data, dataTime);
+    }
+    /**
+     * 处理成功
+     *
+     * @return data
+     */
+    public static Result success() {
+        return new Result(CODE_SUCCESS, SUCCESS_MSG, NOOP, dataTime);
+    }
+    /**
+     * 处理成功
+     *
+     * @param msg 消息
+     * @return data
+     */
+    public static Result success(String msg) {
+        return new Result(CODE_SUCCESS, msg, NOOP, dataTime);
+    }
+    /**
+     * 处理成功
+     *
+     * @param msg  消息
+     * @param data 数据对象
+     * @return data
+     */
+    public static Result success(String msg, Object data) {
+        return new Result(CODE_SUCCESS, msg, data, dataTime);
+    }
+    /**
+     * 处理失败,并返回数据(一般为错误信息)
+     *
+     * @param code 错误代码
+     * @param msg  消息
+     * @return data
+     */
+    public static Result failure(int code, String msg) {
+        return new Result(code, msg, NOOP , dataTime);
+    }
+    /**
+     * 处理失败
+     *
+     * @param msg 消息
+     * @return data
+     */
+    public static Result failure(String msg) {
+        return failure(CODE_FAILURE, msg);
+    }
+
+    @Override
+    public String toString() {
+        return "JsonResult [code=" + code + ", msg=" + msg + ", data="
+                + data + ", timestamp="+ dataTime + "]";
+    }
+}

+ 59 - 0
laser/src/main/java/com/fdkankan/indoor/core/controller/FilterController.java

@@ -0,0 +1,59 @@
+package com.fdkankan.indoor.core.controller;
+
+import com.fdkankan.indoor.base.aop.WebControllerLog;
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.dto.JsonDataDetailDto;
+import com.fdkankan.indoor.core.dto.QueryJsonDataOne;
+import com.fdkankan.indoor.core.dto.QueryJsonDataTwo;
+import com.fdkankan.indoor.core.entity.jsonData.JsonData;
+import com.fdkankan.indoor.core.service.FilterService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * Created by owen on 2021/7/15 0015 15:58
+ */
+@Slf4j
+@Api(tags = "filter数据接口")
+@RestController
+public class FilterController {
+
+    @Autowired
+    FilterService filterService;
+
+    @WebControllerLog(description = "根据id获取数据")
+    @ApiOperation(value = "根据id获取数据")
+    @GetMapping("indoor/{sceneCode}/api/filter/{id}")
+    public JsonData getDataById(@PathVariable String sceneCode, @PathVariable Integer id) {
+        log.info("sceneCode: {}", sceneCode);
+        Result result = filterService.findById(sceneCode, id);
+        return (JsonData)result.getData();
+    }
+
+
+    @WebControllerLog(description = "filter查询接口")
+    @ApiOperation(value = "filter查询接口")
+    @GetMapping("indoor/{code}/api/filter/filter")
+    public List<JsonData> filter(@PathVariable String code,
+                                 QueryJsonDataOne queryJsonDataOne, QueryJsonDataTwo queryJsonDataTwo, JsonDataDetailDto jsonDataDetailDto) {
+        Result result = filterService.query(code, queryJsonDataOne, queryJsonDataTwo, jsonDataDetailDto);
+
+        return (List<JsonData>)result.getData();
+    }
+
+
+    @WebControllerLog(description = "测试id查询")
+    @ApiOperation(value = "测试id查询")
+    @GetMapping("indoor/{sceneCode}/api/filter1/{id}")
+    public Result getDataById1(@PathVariable String sceneCode, @PathVariable Integer id) {
+        log.info("sceneCode: {}", sceneCode);
+        return filterService.findById1(sceneCode, id);
+    }
+}

+ 92 - 0
laser/src/main/java/com/fdkankan/indoor/core/controller/JsonDataController.java

@@ -0,0 +1,92 @@
+package com.fdkankan.indoor.core.controller;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.fdkankan.indoor.core.dto.JsonDataDetailDto;
+import com.fdkankan.indoor.core.dto.QueryJsonDataBase;
+import com.fdkankan.indoor.core.dto.QueryJsonDataOne;
+import com.fdkankan.indoor.core.dto.QueryJsonDataTwo;
+import com.fdkankan.indoor.core.entity.jsonData.JsonData;
+import com.fdkankan.indoor.core.service.JsonData2Service;
+import com.fdkankan.indoor.core.service.JsonDataService;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.ValidationUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Admin
+ */
+@Slf4j
+@Api(tags = "jsonData数据接口")
+@RestController
+@AllArgsConstructor
+public class JsonDataController {
+
+
+
+    @Autowired
+    JsonData2Service jsonData2Service;
+
+
+
+
+    /**
+     * 测试api
+     * http://127.0.0.1:9294/indoor/test1/api/images/filter?dataset=56&hidden=false&limit=100&sort_by=FILE_ID&sort_order=ASC
+     * @param queryJsonDataOne 坐标参数
+     * @param queryJsonDataTwo 距离参数
+     * @param jsonDataDetailDto 距离参数
+     * @return
+     */
+    @ApiOperation(value = "(正)json数据")
+    @ApiOperationSupport(order = 1)
+    @GetMapping("indoor/{code}/api/images/filter")
+    public List<JsonData> filter(@PathVariable String code,
+                                 QueryJsonDataOne queryJsonDataOne, QueryJsonDataTwo queryJsonDataTwo, JsonDataDetailDto jsonDataDetailDto) {
+        log.info("one: {}", BeanUtil.isEmpty(queryJsonDataOne));
+        log.info("two: {}", BeanUtil.isEmpty(queryJsonDataTwo));
+        if (queryJsonDataOne.getLat() != null || queryJsonDataTwo.getLat_max() != null){
+            QueryJsonDataBase data = switchQueryData(queryJsonDataOne, queryJsonDataTwo);
+            return  jsonData2Service.filterJsonData(code, data);
+        }
+
+        if (jsonDataDetailDto != null){
+            return jsonData2Service.filterJsonDataDetail(code, jsonDataDetailDto);
+        }
+
+        return null;
+    }
+
+
+    @ApiOperation(value = "(正)根据id获取数据")
+    @ApiOperationSupport(order = 1)
+    @GetMapping("indoor/{code}/api/images/{id}")
+    public JsonData getDataById(@PathVariable String code, @PathVariable String id) {
+        log.info("code: {}", code);
+        return jsonData2Service.findById(id, code);
+    }
+
+
+    private QueryJsonDataBase switchQueryData(QueryJsonDataOne queryJsonDataOne, QueryJsonDataTwo queryJsonDataTwo) {
+        QueryJsonDataBase data = new QueryJsonDataBase();
+        if (queryJsonDataOne.getLat() != null && queryJsonDataOne.getLon() != null) {
+            data = queryJsonDataOne;
+        } else if (queryJsonDataTwo.getLat_min() != null && queryJsonDataTwo.getLat_max() != null
+                && queryJsonDataTwo.getLon_min() != null && queryJsonDataTwo.getLon_max() != null) {
+            data = queryJsonDataTwo;
+        }
+        log.info("base data: {}", data.toString());
+        return data;
+    }
+
+
+}

+ 91 - 0
laser/src/main/java/com/fdkankan/indoor/core/controller/LoginController.java

@@ -0,0 +1,91 @@
+package com.fdkankan.indoor.core.controller;
+
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.service.LoginService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Created by owen on 2021/7/19 0019 11:30
+ */
+@Slf4j
+@Api(tags = "api用户相关接口")
+@RestController
+public class LoginController {
+
+    @Autowired
+    LoginService loginService;
+
+    @ApiOperation(value = "登录", notes = "目前部分数据是写死的")
+    @PostMapping("indoor/{sceneCode}/api/auth/token")
+    public Object login(@PathVariable String sceneCode, String username, String password){
+        Result result = loginService.login(username, password);
+        return result.getData();
+    }
+
+    @ApiOperation(value = "groups", notes = "数据目前是写死的")
+    @GetMapping("indoor/{sceneCode}/api/groups")
+    public Object groups(@PathVariable String sceneCode){
+        Result result = loginService.groups(sceneCode);
+        return result.getData();
+    }
+
+    @ApiOperation(value = "license", notes = "数据目前是写死的")
+    @GetMapping("indoor/{sceneCode}/api/license")
+    public Object license(@PathVariable String sceneCode){
+        Result result = loginService.license(sceneCode);
+        return result.getData();
+    }
+
+    @ApiOperation(value = "user", notes = "数据目前是写死的")
+    @GetMapping("indoor/{sceneCode}/api/user")
+    public Object user(@PathVariable String sceneCode){
+        Result result = loginService.user(sceneCode);
+        return result.getData();
+    }
+
+    @ApiOperation(value = "users", notes = "数据目前是写死的")
+    @GetMapping("indoor/{sceneCode}/api/users")
+    public Object users(@PathVariable String sceneCode){
+        Result result = loginService.users(sceneCode);
+        return result.getData();
+    }
+
+
+    @ApiOperation(value = "health", notes = "数据目前是写死的")
+    @GetMapping("indoor/{sceneCode}/status/health")
+    public Object health(@PathVariable String sceneCode){
+        Result result = loginService.health(sceneCode);
+        return result.getData();
+    }
+
+    @ApiOperation(value = "configs", notes = "数据目前是写死的")
+    @GetMapping("indoor/{sceneCode}/api/configs")
+    public Object configs(@PathVariable String sceneCode){
+        Result result = loginService.configs(sceneCode);
+        return result.getData();
+    }
+
+
+    @ApiOperation(value = "poi_type_groups", notes = "数据目前是写死的")
+    @GetMapping("indoor/{sceneCode}/api/poi_type_groups")
+    public Object poiTypeGroups(@PathVariable String sceneCode){
+        Result result = loginService.poiTypeGroups(sceneCode);
+        return result.getData();
+    }
+
+    @ApiOperation(value = "poi_types", notes = "数据目前是写死的")
+    @GetMapping("indoor/{sceneCode}/api/poi_types")
+    public Object poiTypes(@PathVariable String sceneCode){
+        Result result = loginService.poiTypes(sceneCode);
+        return result.getData();
+    }
+
+
+}

+ 53 - 0
laser/src/main/java/com/fdkankan/indoor/core/controller/PoiController.java

@@ -0,0 +1,53 @@
+package com.fdkankan.indoor.core.controller;
+
+import com.fdkankan.indoor.base.aop.WebControllerLog;
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.dto.PoiSearchDto;
+import com.fdkankan.indoor.core.service.PoiService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Created by owen on 2021/7/14 0014 14:17
+ */
+@Slf4j
+@Api(tags = "poi数据接口")
+@RestController
+public class PoiController {
+
+
+    @Autowired
+    PoiService poiService;
+
+    @WebControllerLog(description = "poi数据接口-根据id查询")
+    @ApiOperation(value = "根据id查询", notes = "code:场景码, id:poi.jsons数据里的id")
+    @GetMapping("indoor/{code}/api/pois/{id}")
+    public Object findById(@PathVariable String code, @PathVariable Integer id){
+        Result result = poiService.findBySceneCodeAndId(code, id);
+        return result.getData();
+//        return poiService.findBySceneCodeAndId(code, id);
+
+    }
+
+    /**
+     * http://indoor.popsmart.cn:8084/sxswsw/api/search/poi?from=0&lang=zh&query=%E5%85%A5%E5%8F%A3&size=5
+     * https://testlaser.4dkankan.com/indoor/test1/api/search/poi?from=0&lang=zh&query=%E5%85%A5%E5%8F%A3&size=5
+     * http://127.0.0.1:9294/indoor/test1/api/search/poi?from=0&lang=zh&query=%E5%85%A5%E5%8F%A3&size=5
+     * @param code
+     * @param param
+     * @return
+     */
+    @WebControllerLog(description = "poi数据接口-模糊查询")
+    @ApiOperation(value = "模糊查询", notes = "模糊查询titles, 我们的数据没有matching_title字段")
+    @GetMapping("indoor/{code}/api/search/poi")
+    public Object search(@PathVariable String code, PoiSearchDto param){
+        Result search = poiService.search(code, param);
+        return search.getData();
+
+    }
+}

+ 115 - 0
laser/src/main/java/com/fdkankan/indoor/core/controller/SiteModelController.java

@@ -0,0 +1,115 @@
+package com.fdkankan.indoor.core.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.indoor.base.aop.WebControllerLog;
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.dto.SiteModelSearchDto;
+import com.fdkankan.indoor.core.entity.siteModel.SiteModel;
+import com.fdkankan.indoor.core.service.SiteModel2Service;
+import com.fdkankan.indoor.core.service.TsiteModelService;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author Admin
+ *
+ * http://127.0.0.1:9294/indoor/
+ */
+@Slf4j
+@Api(tags = "SiteModel数据接口")
+@RestController
+@AllArgsConstructor
+public class SiteModelController {
+
+
+    @Autowired
+    SiteModel2Service siteModel2Service;
+
+    @Autowired
+    TsiteModelService tsiteModelService;
+
+
+    /**
+     * http://127.0.0.1:9294/indoor/test1/api/site_model/within?location=120.58645186143931&location=29.991567318555767&location=1.1677126884460454&type=FLOOR
+     * http://127.0.0.1:9294/indoor/test2/api/site_model/within?location=113.595542719717&location=22.366858049261&location=-0.299806&type=FLOOR
+     * @param code
+     * @param location
+     * @param type
+     * @return
+     */
+    @ApiOperation(value = "(正)siteModel数据")
+    @ApiOperationSupport(order = 2)
+    @GetMapping("indoor/{code}/api/site_model/within")
+    //todo
+    public SiteModel within2(@PathVariable String code, Double[] location, String type) {
+        log.info("code: {}", code);
+        return siteModel2Service.withinType(code, location, type);
+    }
+
+
+
+    @ApiOperation(value = "(正)根据id获取数据")
+    @ApiOperationSupport(order = 1)
+    @GetMapping("indoor/{code}/api/site_model/{id}")
+    public SiteModel getDataById(@PathVariable String code, @PathVariable Long id) {
+        log.info("code: {}", code);
+        return siteModel2Service.findById(id, code);
+    }
+
+
+    @WebControllerLog(description = "SiteModel数据接口-获取building数据")
+    @ApiOperation(value = "获取building数据",notes = "参数直接传个json对象")
+    @PostMapping("indoor/{code}/api/site_model/within_polygon")
+    public Result getData(@RequestBody JSONObject param, @PathVariable String code) {
+        return siteModel2Service.getData(param, code);
+//        return Result.success(param);
+    }
+
+
+    /**
+     * 2021-07-16
+     * 参考api: http://indoor.popsmart.cn:8094/zdoblh/api/search/site_model?from=0&lang=zh&query=%E6%88%BF%E9%97%B4&size=5
+     *
+     * 测试:
+     * http://127.0.0.1:9294/indoor/test1/api/search/site_model?from=0&lang=zh&query=%E4%B8%80%E6%A5%BC&size=5
+     * @return
+     */
+    @WebControllerLog(description = "SiteModel查询")
+    @ApiOperation(value = "查询",notes = "参数直接传个json对象")
+    @GetMapping("indoor/{sceneCode}/api/search/site_model")
+    public Object search(@PathVariable String sceneCode, SiteModelSearchDto searchDto) {
+        Result search = siteModel2Service.search(sceneCode, searchDto);
+        return search.getData();
+//        return siteModel2Service.search(sceneCode, searchDto);
+    }
+
+
+    /**
+     * 2021-07-16
+     * 参考: http://indoor.popsmart.cn:8094/zdoblh/api/site_model/closest?location=121.61088492160654&location=29.8770318786046&location=0.6624369924962523&radius=0.01
+     *
+     * 测试api
+     *
+     * http://127.0.0.1:9294/indoor/test2/api/site_model/closest?location=113.595495811839&location=22.3668188213553&location=0.6624369924962523&radius=0.01
+     * location1=x
+     * location2=y
+     * location3=z 这个值目前还没判断
+     * radius: 半径
+     * @return
+     */
+    @WebControllerLog(description = "找最近的点")
+    @ApiOperation(value = "查询",notes = "参数直接传个json对象")
+    @GetMapping("indoor/{sceneCode}/api/site_model/closest")
+    public Object latest(@PathVariable String sceneCode, Double[] location, Double radius) {
+        Result search = siteModel2Service.latest(sceneCode, location, radius);
+        return search.getData();
+//        return siteModel2Service.search(sceneCode, searchDto);
+    }
+
+
+}

+ 28 - 0
laser/src/main/java/com/fdkankan/indoor/core/dto/JsonDataDetailDto.java

@@ -0,0 +1,28 @@
+package com.fdkankan.indoor.core.dto;
+
+import lombok.Data;
+
+/**
+ * Created by owen on 2021/7/15 0015 10:07
+ * JsonData对像查询
+ */
+@Data
+public class JsonDataDetailDto {
+
+    /**对应db dataset_id*/
+    private Integer dataset;
+
+    private Boolean hidden;
+
+    /** 返回数量*/
+    private Integer limit;
+
+    /**对应db site_model_entity_id*/
+    private Integer site_model_entity;
+
+    /**对应db 根据那个字段排序*/
+    private String sort_by;
+
+    /**升序还是降序*/
+    private String sort_order;
+}

+ 20 - 0
laser/src/main/java/com/fdkankan/indoor/core/dto/PoiSearchDto.java

@@ -0,0 +1,20 @@
+package com.fdkankan.indoor.core.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Created by owen on 2021/7/15 0015 11:53
+ */
+@Data
+public class PoiSearchDto {
+
+    @ApiModelProperty(value = "返回数量")
+    private Integer size;
+
+    @ApiModelProperty(value = "模糊查询参数")
+    private String query;
+
+
+
+}

+ 16 - 0
laser/src/main/java/com/fdkankan/indoor/core/dto/QueryJsonDataBase.java

@@ -0,0 +1,16 @@
+package com.fdkankan.indoor.core.dto;
+
+import lombok.Data;
+
+/**
+ * @author Admin
+ */
+@Data
+public class QueryJsonDataBase {
+
+    private String sceneNum;
+    private Integer limit;
+    private Double z;
+    private Long siteModelEntity;
+    private Integer step;
+}

+ 18 - 0
laser/src/main/java/com/fdkankan/indoor/core/dto/QueryJsonDataOne.java

@@ -0,0 +1,18 @@
+package com.fdkankan.indoor.core.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Admin
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class QueryJsonDataOne extends QueryJsonDataBase {
+
+    private Double radius;
+    private Double lat;
+    private Double lon;
+}

+ 20 - 0
laser/src/main/java/com/fdkankan/indoor/core/dto/QueryJsonDataTwo.java

@@ -0,0 +1,20 @@
+package com.fdkankan.indoor.core.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Admin
+ * ddd
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class QueryJsonDataTwo extends QueryJsonDataBase {
+
+    private Double lat_max;
+    private Double lat_min;
+    private Double lon_max;
+    private Double lon_min;
+}

+ 21 - 0
laser/src/main/java/com/fdkankan/indoor/core/dto/SiteModelLatestDto.java

@@ -0,0 +1,21 @@
+package com.fdkankan.indoor.core.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Created by owen on 2021/7/16 0015 11:53
+ * 找最近的点位
+ */
+@Data
+public class SiteModelLatestDto {
+
+    @ApiModelProperty(value = "返回数量")
+    private Integer size;
+
+    @ApiModelProperty(value = "模糊查询参数")
+    private String query;
+
+
+
+}

+ 20 - 0
laser/src/main/java/com/fdkankan/indoor/core/dto/SiteModelSearchDto.java

@@ -0,0 +1,20 @@
+package com.fdkankan.indoor.core.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Created by owen on 2021/7/15 0015 11:53
+ */
+@Data
+public class SiteModelSearchDto {
+
+    @ApiModelProperty(value = "返回数量")
+    private Integer size;
+
+    @ApiModelProperty(value = "模糊查询参数")
+    private String query;
+
+
+
+}

+ 38 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/BaseEntity.java

@@ -0,0 +1,38 @@
+package com.fdkankan.indoor.core.entity;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+//@MappedSuperclass
+public abstract class BaseEntity {
+
+//    @Id
+//    @GeneratedValue(strategy = GenerationType.IDENTITY)
+//    @Column(name = "id")
+    @ApiModelProperty(value = "对象ID")
+    private Integer id;
+
+//    @ApiModelProperty(value = "创建时间")
+//    @Temporal(TemporalType.TIMESTAMP)
+//    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
+//    private LocalDateTime createTime;
+
+//    @ApiModelProperty(value = "修改时间")
+//    @Temporal(TemporalType.TIMESTAMP)
+//    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
+//    private LocalDateTime updateTime;
+//
+//    /**
+//     * 用来批量操作的
+//     * 0代表未删除 , 1代表已经删除,默认写0
+//     * 需要使用对象类型
+//     */
+//    @JsonIgnore
+//    @JSONField(serialize = false)
+//    private Integer isDelete;
+}

+ 67 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/SysUserEntity.java

@@ -0,0 +1,67 @@
+package com.fdkankan.indoor.core.entity;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+
+/**
+ * 用户表
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@Document(collection = "sys_user")
+public class SysUserEntity extends BaseEntity  implements Serializable {
+
+    private static final long serialVersionUID = -853504493430501564L;
+
+    @ApiModelProperty(value = "身份证号(军号)")
+    private String username;
+
+    @JsonIgnore
+//    @JSONField(serialize = false)
+    private String password;
+
+//    @ApiModelProperty(value = "真实姓名")
+//    private String realName;
+//
+//    @ApiModelProperty(value = "昵称")
+//    private String nickName;
+//
+//    @ApiModelProperty(value = "性别 0:男  1:女")
+//    private Integer sex;
+//
+//    @ApiModelProperty(value = "电话")
+//    private String phone;
+//
+//    @ApiModelProperty(value = "单位")
+//    private String unit;
+//
+//    @ApiModelProperty(value = "地址")
+//    private String address;
+//
+////    @ApiModelProperty(value = "超级管理员,1:是, 0:否")
+////    private Integer sysManager;
+//
+//    @ApiModelProperty(value = "状态 0:启用(默认值)  1:禁用")
+//    private Integer isDisable;
+//
+////    @ApiModelProperty(value = "高清图url")
+////    private String img;
+//
+//    @ApiModelProperty(value = "缩略图url")
+//    private String thumb;
+//
+//    @JSONField(serialize = false)
+//    @ApiModelProperty(value = "角色,sys_admin:系统管理员,sys_high:高级管理员, sys_normal:普通管理员, sys_visitor:游客")
+//    private String role;
+
+
+
+}

+ 26 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/jsonData/FilterEntity.java

@@ -0,0 +1,26 @@
+package com.fdkankan.indoor.core.entity.jsonData;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Created by owen on 2021/7/14 0014 14:22
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@Document(collection = "t_filter")
+public class FilterEntity implements Serializable {
+
+    private static final long serialVersionUID = 2974313673840996620L;
+    private Long id;
+
+    private String sceneCode;
+
+    private List<JsonData> data;
+}

+ 35 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/jsonData/JsonData.java

@@ -0,0 +1,35 @@
+package com.fdkankan.indoor.core.entity.jsonData;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+
+/**
+ * @author Admin
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@Document(collection = "json_data")
+public class JsonData implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+    private Double[] location;
+    private Double[] floor_location;
+    private Double[] orientation;
+    private Integer dataset_id;
+    private Double[] dataset_location;
+    private Double[] dataset_floor_location;
+    private Double[] dataset_orientation;
+    private Integer camera_head_id;
+    private String file_path;
+    private String file_id;
+    private Boolean hidden;
+    private Integer site_model_entity_id;
+
+}

+ 35 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/jsonData/JsonData2.java

@@ -0,0 +1,35 @@
+package com.fdkankan.indoor.core.entity.jsonData;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+
+/**
+ * @author Admin
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@Document(collection = "json_data_2")
+public class JsonData2 implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+    private Double[] location;
+    private Double[] floor_location;
+    private Double[] orientation;
+    private Integer dataset_id;
+    private Double[] dataset_location;
+    private Double[] dataset_floor_location;
+    private Double[] dataset_orientation;
+    private Integer camera_head_id;
+    private String file_path;
+    private String file_id;
+    private Boolean hidden;
+    private Integer site_model_entity_id;
+
+}

+ 26 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/poi/PoiEntity.java

@@ -0,0 +1,26 @@
+package com.fdkankan.indoor.core.entity.poi;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Created by owen on 2021/7/14 0014 14:22
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@Document(collection = "t_poi")
+public class PoiEntity implements Serializable {
+    private static final long serialVersionUID = 8758157456020769056L;
+
+    private Long id;
+
+    private String sceneCode;
+
+    private List data;
+}

+ 18 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/siteModel/Attributes.java

@@ -0,0 +1,18 @@
+package com.fdkankan.indoor.core.entity.siteModel;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * @author Admin
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class Attributes implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+}

+ 22 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/siteModel/Polygon.java

@@ -0,0 +1,22 @@
+package com.fdkankan.indoor.core.entity.siteModel;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author Admin
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class Polygon implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String type;
+    private List<List<List<Double>>> coordinates;
+}

+ 44 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/siteModel/SiteModel.java

@@ -0,0 +1,44 @@
+package com.fdkankan.indoor.core.entity.siteModel;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.data.annotation.Transient;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Admin
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@Document(collection = "site_model")
+public class SiteModel implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+    private String type;
+    private String name;
+    private Polygon polygon;
+    private Double z_min;
+    private Double z_max;
+    private List<Double> center;
+    private Map<String, Object> attributes = new HashMap<>();
+    private Double area;
+    private Double volume;
+    private Long geometry_hash;
+    private List<SiteModel> children;
+
+    // 父级id, 后端需要,前端不用
+    @Transient
+    @JsonIgnore
+    private Integer parentId;
+
+}

+ 37 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/siteModel/SiteModel2.java

@@ -0,0 +1,37 @@
+package com.fdkankan.indoor.core.entity.siteModel;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Admin
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@Document(collection = "site_model_2")
+public class SiteModel2 implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+    private String type;
+    private String name;
+    private Polygon polygon;
+    private Double z_min;
+    private Double z_max;
+    private List<Double> center;
+    private Map<String, Object> attributes = new HashMap<>();
+    private Double area;
+    private Double volume;
+    private Long geometry_hash;
+    private List<SiteModel2> children;
+
+}

+ 37 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/tsiteModel/SiteModel.java

@@ -0,0 +1,37 @@
+package com.fdkankan.indoor.core.entity.tsiteModel;
+
+import com.fdkankan.indoor.core.entity.siteModel.Polygon;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Admin
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SiteModel implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String id;
+    private String type;
+    private String name;
+    private Polygon polygon;
+    private Double z_min;
+    private Double z_max;
+    private List<Double> center;
+    private Map<String, Object> attributes = new HashMap<>();
+    private Double area;
+    private Double volume;
+    private Long geometry_hash;
+    private List<SiteModel> children;
+
+}

+ 26 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/tsiteModel/TsiteModel.java

@@ -0,0 +1,26 @@
+package com.fdkankan.indoor.core.entity.tsiteModel;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+
+/**
+ * Created by owen on 2021/7/14 0014 9:27
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@Document(collection = "t_site_model")
+public class TsiteModel  implements Serializable {
+    private static final long serialVersionUID = -1050476893909629046L;
+
+    private String id;
+
+    private String sceneNum;
+
+    private SiteModel data;
+}

+ 14 - 0
laser/src/main/java/com/fdkankan/indoor/core/mapper/SysUserMapper.java

@@ -0,0 +1,14 @@
+package com.fdkankan.indoor.core.mapper;
+
+import com.fdkankan.indoor.core.entity.SysUserEntity;
+import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by owen on 2021/7/19 0019 12:00
+ */
+@Component
+public interface SysUserMapper extends MongoRepository<SysUserEntity, Integer> {
+
+    SysUserEntity findByUsername(String username);
+}

+ 19 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/FilterService.java

@@ -0,0 +1,19 @@
+package com.fdkankan.indoor.core.service;
+
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.dto.JsonDataDetailDto;
+import com.fdkankan.indoor.core.dto.QueryJsonDataOne;
+import com.fdkankan.indoor.core.dto.QueryJsonDataTwo;
+
+/**
+ * Created by owen on 2021/7/15 0015 16:00
+ */
+public interface FilterService {
+
+
+    Result findById(String sceneCode, Integer id);
+
+    Result query(String code, QueryJsonDataOne queryJsonDataOne, QueryJsonDataTwo queryJsonDataTwo, JsonDataDetailDto jsonDataDetailDto);
+
+    Result findById1(String sceneCode, Integer id);
+}

+ 19 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/JsonData2Service.java

@@ -0,0 +1,19 @@
+package com.fdkankan.indoor.core.service;
+
+import com.fdkankan.indoor.core.dto.JsonDataDetailDto;
+import com.fdkankan.indoor.core.dto.QueryJsonDataBase;
+import com.fdkankan.indoor.core.entity.jsonData.JsonData;
+
+import java.util.List;
+
+/**
+ * @author Admin
+ */
+public interface JsonData2Service {
+
+    List<JsonData> filterJsonData(String code, QueryJsonDataBase data);
+
+    JsonData findById(String id, String code);
+
+    List<JsonData> filterJsonDataDetail(String code, JsonDataDetailDto jsonDataDetailDto);
+}

+ 16 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/JsonDataService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.indoor.core.service;
+
+import com.fdkankan.indoor.core.dto.QueryJsonDataBase;
+import com.fdkankan.indoor.core.entity.jsonData.JsonData;
+
+import java.util.List;
+
+/**
+ * @author Admin
+ */
+public interface JsonDataService {
+
+    List<JsonData> filterJsonData( QueryJsonDataBase data);
+
+    JsonData findById(String id, String code);
+}

+ 26 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/LoginService.java

@@ -0,0 +1,26 @@
+package com.fdkankan.indoor.core.service;
+
+import com.fdkankan.indoor.base.util.Result;
+
+/**
+ * Created by owen on 2021/7/19 0019 11:53
+ */
+public interface LoginService {
+    Result login(String username, String password);
+
+    Result groups(String sceneCode);
+
+    Result license(String sceneCode);
+
+    Result health(String sceneCode);
+
+    Result configs(String sceneCode);
+
+    Result user(String sceneCode);
+
+    Result users(String sceneCode);
+
+    Result poiTypeGroups(String sceneCode);
+
+    Result poiTypes(String sceneCode);
+}

+ 14 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/PoiService.java

@@ -0,0 +1,14 @@
+package com.fdkankan.indoor.core.service;
+
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.dto.PoiSearchDto;
+
+/**
+ * Created by owen on 2021/7/14 0014 14:31
+ */
+public interface PoiService {
+
+    Result findBySceneCodeAndId(String code, Integer id);
+
+    Result search(String code, PoiSearchDto param);
+}

+ 24 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/SiteModel2Service.java

@@ -0,0 +1,24 @@
+package com.fdkankan.indoor.core.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.dto.SiteModelSearchDto;
+import com.fdkankan.indoor.core.entity.siteModel.SiteModel;
+
+/**
+ * @author Admin
+ */
+public interface SiteModel2Service {
+
+    SiteModel within(Double[] location, String type);
+
+    SiteModel withinType(String code, Double[] location, String type);
+
+    SiteModel findById(Long id, String code);
+
+    Result getData(JSONObject param, String code);
+
+    Result search(String sceneCode, SiteModelSearchDto searchDto);
+
+    Result latest(String sceneCode, Double[] location, Double radius);
+}

+ 17 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/SiteModelService.java

@@ -0,0 +1,17 @@
+package com.fdkankan.indoor.core.service;
+
+import com.fdkankan.indoor.core.dto.QueryJsonDataBase;
+import com.fdkankan.indoor.core.entity.jsonData.JsonData;
+import com.fdkankan.indoor.core.entity.siteModel.SiteModel;
+
+import java.util.List;
+
+/**
+ * @author Admin
+ */
+public interface SiteModelService {
+
+    SiteModel within(Double[] location, String type);
+
+    SiteModel withinType(String code, Double[] location, String type);
+}

+ 11 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/SysUserService.java

@@ -0,0 +1,11 @@
+package com.fdkankan.indoor.core.service;
+
+import com.fdkankan.indoor.core.entity.SysUserEntity;
+
+/**
+ * Created by owen on 2021/7/19 0019 11:53
+ */
+public interface SysUserService {
+
+    SysUserEntity findByUserName(String username);
+}

+ 11 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/TsiteModelService.java

@@ -0,0 +1,11 @@
+package com.fdkankan.indoor.core.service;
+
+import com.fdkankan.indoor.base.util.Result;
+
+/**
+ * Created by owen on 2021/7/14 0014 9:34
+ */
+public interface TsiteModelService {
+
+    Result withinBySceneNum(String sceneNum, Double[] location, String type);
+}

+ 359 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/impl/FilterServiceImpl.java

@@ -0,0 +1,359 @@
+package com.fdkankan.indoor.core.service.impl;
+
+import com.fdkankan.indoor.base.util.JsonUtil;
+import com.fdkankan.indoor.base.util.Options;
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.dto.JsonDataDetailDto;
+import com.fdkankan.indoor.core.dto.QueryJsonDataBase;
+import com.fdkankan.indoor.core.dto.QueryJsonDataOne;
+import com.fdkankan.indoor.core.dto.QueryJsonDataTwo;
+import com.fdkankan.indoor.core.entity.jsonData.FilterEntity;
+import com.fdkankan.indoor.core.entity.jsonData.JsonData;
+import com.fdkankan.indoor.core.service.FilterService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.aggregation.Aggregation;
+import org.springframework.data.mongodb.core.aggregation.AggregationResults;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Created by owen on 2021/7/15 0015 16:00
+ */
+@Slf4j
+@Service
+public class FilterServiceImpl implements FilterService {
+
+    @Autowired
+    MongoTemplate mongoTemplate;
+
+    @Override
+    public Result findById(String sceneCode, Integer id) {
+        List<JsonData> array = findBySceneCode(sceneCode);
+        List<JsonData> result = array.stream().filter(p -> id==p.getId())
+                .collect(Collectors.toList());
+        if (result.size() == 0) {
+            throw new RuntimeException("此场景没有数据");
+        }
+
+        return Result.success(result.get(0));
+    }
+
+    @Override
+    public Result query(String code, QueryJsonDataOne queryJsonDataOne, QueryJsonDataTwo queryJsonDataTwo, JsonDataDetailDto jsonDataDetailDto) {
+
+        if (queryJsonDataOne.getLat() != null || queryJsonDataTwo.getLat_max() != null){
+            QueryJsonDataBase data = switchQueryData(queryJsonDataOne, queryJsonDataTwo);
+            return  Result.success(filterJsonData(code, data));
+        }
+
+        if (jsonDataDetailDto != null){
+            return  Result.success(filterJsonDataDetail(code, jsonDataDetailDto));
+        }
+        return null;
+    }
+
+    @Override
+    public Result findById1(String sceneCode, Integer id) {
+
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(sceneCode).and("data.file_id").is("00004"));
+
+//        BasicDBObject queryObject = new BasicDBObject();
+//        queryObject.put("data._id",1);
+//
+//        DBObject fields = new BasicDBObject();
+//        fields.put("_id",true);
+//        fields.put("dataset_id",true);
+
+        FilterEntity entity = mongoTemplate.findOne(query, FilterEntity.class);
+        List<JsonData> data = entity.getData();
+
+        return Result.success(data);
+    }
+
+
+    private List<Document> flowGruop(){
+        Criteria criteria = Criteria.where("sceneCode").is("test2");
+        Aggregation agg = Aggregation.newAggregation(
+                Aggregation.match(criteria),
+                Aggregation.group("data").first("data").as("data").count().as("count")
+        );
+
+        AggregationResults<Document> aggregate = mongoTemplate.aggregate(agg, FilterEntity.class, Document.class);
+        return aggregate.getMappedResults();
+    }
+
+
+    /**
+     * 查询细节根据排序
+     * @param code
+     * @param jsonDataDetailDto
+     * @return
+     */
+
+    private List<JsonData> filterJsonDataDetail(String code, JsonDataDetailDto jsonDataDetailDto) {
+        List<JsonData> dbList = findBySceneCode(code);
+
+        Integer datasetId = jsonDataDetailDto.getDataset();
+        Integer siteModelEntityId = jsonDataDetailDto.getSite_model_entity();
+        Integer limit = jsonDataDetailDto.getLimit();
+        limit = limit==null ? 10 : limit;
+        Boolean hidden = jsonDataDetailDto.getHidden();
+        // 对应db 根据那个字段排序
+        String sortOrder = jsonDataDetailDto.getSort_order();
+        sortOrder = sortOrder==null ? null :sortOrder.toLowerCase();
+        // 升序还是降序
+        String sortBy = jsonDataDetailDto.getSort_by();
+        sortBy = sortBy==null ? null :sortBy.toLowerCase();
+
+
+
+        // todo 这里的排序还需要处理一下, 如有异常看了hidden值
+        Stream<JsonData> dataStream = dbList.stream().filter(p -> datasetId == p.getDataset_id().longValue()
+                && siteModelEntityId == p.getSite_model_entity_id().longValue() && !hidden)
+                .limit(limit);
+
+        // 处理排序reversed()降序, 默认是升序
+        if ("desc".equals(sortBy) && "file_id".equals(sortOrder)) {
+            dataStream = dataStream.sorted(Comparator.comparing(JsonData::getFile_id).reversed());
+        } else if ("asc".equals(sortBy) && "file_id".equals(sortOrder)){
+            dataStream =  dataStream.sorted(Comparator.comparing(JsonData::getFile_id));
+        }
+
+        List<JsonData> collect = dataStream.collect(Collectors.toList());
+
+        log.info("返回数据数量: {}", collect.size());
+        return collect;
+    }
+
+    private Boolean getHidden(Boolean hidden, JsonData dbData){
+        Boolean dbHidden = dbData.getHidden();
+        log.info("输入hidden: {}, 匹配结果:{}", hidden.equals(dbHidden));
+        return dbHidden;
+    }
+
+
+    private List<JsonData> filterJsonData(String code, QueryJsonDataBase data) {
+        log.info("code:{}, data:{}", code, data.toString());
+
+        List<JsonData> dbList = findBySceneCode(code);
+
+        List<JsonData> list;
+        if (data instanceof QueryJsonDataOne) {
+            QueryJsonDataOne one = (QueryJsonDataOne) data;
+            list = queryDataOne(one, dbList);
+            log.info("走one");
+        } else if (data instanceof QueryJsonDataTwo) {
+            QueryJsonDataTwo two = (QueryJsonDataTwo) data;
+            list = queryDataTwo(two, dbList);
+            log.info("走two");
+        } else {
+            throw new RuntimeException("没有查询到数据,请检查入参");
+        }
+        return list;
+    }
+
+
+    private List<JsonData> queryDataOne(QueryJsonDataOne queryJsonData, List<JsonData> dbList) {
+        log.info("run queryDataOne");
+
+        List<JsonData> jsonDataList = new ArrayList<>();
+        Long siteModelEntityId = queryJsonData.getSiteModelEntity();
+        if (siteModelEntityId != null) {
+            jsonDataList = dbList.stream().filter(p -> siteModelEntityId == p.getSite_model_entity_id().longValue()).collect(Collectors.toList());
+        }
+
+        if (queryJsonData.getZ() != null) {
+            jsonDataList = dbList.stream().filter(jsonData ->
+                    jsonData.getLocation()[2] >= queryJsonData.getZ() && jsonData.getFloor_location()[2] <= queryJsonData.getZ())
+                    .collect(Collectors.toList());
+        }
+
+        List<JsonData> newJsonData = new ArrayList<>();
+        // radius:半径
+        if (queryJsonData.getRadius() != null) {
+            newJsonData = calcule(queryJsonData, jsonDataList);
+        } else {
+            // 没有半径,算最近的距离
+            newJsonData = calculeMin(queryJsonData, jsonDataList);
+        }
+
+        if (queryJsonData.getLimit() != null) {
+            newJsonData = newJsonData.stream().limit(queryJsonData.getLimit()).collect(Collectors.toList());
+        }
+        return newJsonData;
+    }
+
+    private List<JsonData> queryDataTwo(QueryJsonDataTwo queryJsonData , List<JsonData> dbList) {
+        log.info("run queryDataTwo");
+
+        List<JsonData> jsonDataList = new ArrayList<>();
+        Long siteModelEntityId = queryJsonData.getSiteModelEntity();
+        if (siteModelEntityId != null) {
+            jsonDataList = dbList.stream().filter(p -> siteModelEntityId == p.getSite_model_entity_id().longValue()).collect(Collectors.toList());
+        }
+        jsonDataList = dbList.stream().filter(jsonData ->
+                jsonData.getLocation()[0] >= queryJsonData.getLon_min() && jsonData.getLocation()[0] <= queryJsonData.getLon_max()
+                        && jsonData.getLocation()[1] >= queryJsonData.getLat_min() && jsonData.getLocation()[1] <= queryJsonData.getLat_max())
+                .collect(Collectors.toList());
+
+        List<JsonData> newJsonData = fillNewJsonData(queryJsonData, jsonDataList);
+
+        return newJsonData;
+    }
+
+
+    private List<JsonData> calcule(QueryJsonDataOne queryJsonData, List<JsonData> jsonDataList) {
+        log.info("run calcule");
+        List<JsonData> newJsonData = new ArrayList<>();
+        for (JsonData jsonData : jsonDataList) {
+//            log.info("jsonData: {}", jsonData);
+            Double[] coordinates1 = new Double[2];
+            coordinates1[0] = queryJsonData.getLon();
+            coordinates1[1] = queryJsonData.getLat();
+
+            Double[] coordinates2 = new Double[2];
+            coordinates2[0] = jsonData.getLocation()[0];
+            coordinates2[1] = jsonData.getLocation()[1];
+
+            Double distance = JsonUtil.distance(coordinates1, coordinates2, new Options().setUnits("miles"));
+//            log.info("计算出的距离:{}", distance);
+
+            if (queryJsonData.getRadius() > distance) {
+                newJsonData.add(jsonData);
+            }
+        }
+        return newJsonData;
+    }
+
+    /**
+     * 计算最小距离
+     * @param queryJsonData
+     * @param jsonDataList
+     * @return 获取最小值对象
+     */
+    private List<JsonData> calculeMin(QueryJsonDataOne queryJsonData, List<JsonData> jsonDataList) {
+        log.info("run calculeMin");
+        List<JsonData> newJsonData = new ArrayList<>();
+
+        // 计算距离后的结果接
+        HashMap<Double, JsonData> calResultMap = new HashMap<>();
+
+        int i = 1;
+        Double min = null;
+        for (JsonData jsonData : jsonDataList) {
+            Double[] coordinates1 = new Double[2];
+            coordinates1[0] = queryJsonData.getLon();
+            coordinates1[1] = queryJsonData.getLat();
+
+            Double[] coordinates2 = new Double[2];
+            coordinates2[0] = jsonData.getLocation()[0];
+            coordinates2[1] = jsonData.getLocation()[1];
+
+            Double distance = JsonUtil.distance(coordinates1, coordinates2, new Options().setUnits("miles"));
+//            log.info("计算出的距离:{}", distance);
+            // 默认取第一值
+            if (i==1) {
+                min = distance;
+                calResultMap.put(min, jsonData);
+            }
+
+            if (distance < min) {
+                min = distance;
+                calResultMap.put(min, jsonData);
+            }
+            i++;
+
+        }
+
+        log.info("循环次数:{}, 最小值:{}", i, min);
+        // 获取最小值
+        JsonData minJson = calResultMap.get(min);
+        newJsonData.add(minJson);
+        return newJsonData;
+    }
+
+    /**
+     * 处理step step的值会有影响
+     * 当step=null, 0, 1不做处理
+     * @param queryJsonData
+     * @param jsonDataList
+     * @return
+     */
+    private List<JsonData> fillNewJsonData(QueryJsonDataTwo queryJsonData, List<JsonData> jsonDataList) {
+        List<JsonData> newJsonData = new ArrayList<>();
+        log.info("输入对象数量:{}", jsonDataList.size());
+        Integer inputStep = queryJsonData.getStep();
+        // 当inputStep为空、null、0、1 时返回全部数据
+        if (inputStep == null || inputStep==0 || inputStep==1) {
+            return jsonDataList;
+        }
+
+        /**
+         * 当inputStep大于1, 数量为200, 隔多少步取一个点
+         * 2:100
+         * 3:67
+         * 4:50
+         *
+         */
+        int step = 0;
+        if (inputStep > 1) {
+            for (JsonData jsonData : jsonDataList) {
+                if (step % inputStep == 0 || step == 0) {
+                    newJsonData.add(jsonData);
+                }
+                step++;
+            }
+        }
+        log.info("输出对象数量:{}", newJsonData.size());
+        return newJsonData;
+    }
+
+
+    /**
+     * 根据场景码查询数据
+     * @param sceneCode
+     * @return
+     */
+    private List<JsonData>  findBySceneCode(String sceneCode) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(sceneCode));
+        FilterEntity entity = mongoTemplate.findOne(query, FilterEntity.class);
+        if (entity == null) {
+            throw new RuntimeException("没有此场景数据");
+        }
+        List<JsonData> list = entity.getData();
+        log.info("JsonData数量:{}", list.size());
+        return list;
+    }
+
+
+    /**
+     * 封装基础数据
+     * @param queryJsonDataOne
+     * @param queryJsonDataTwo
+     * @return
+     */
+    private QueryJsonDataBase switchQueryData(QueryJsonDataOne queryJsonDataOne, QueryJsonDataTwo queryJsonDataTwo) {
+        QueryJsonDataBase data = new QueryJsonDataBase();
+        if (queryJsonDataOne.getLat() != null && queryJsonDataOne.getLon() != null) {
+            data = queryJsonDataOne;
+        } else if (queryJsonDataTwo.getLat_min() != null && queryJsonDataTwo.getLat_max() != null
+                && queryJsonDataTwo.getLon_min() != null && queryJsonDataTwo.getLon_max() != null) {
+            data = queryJsonDataTwo;
+        }
+        log.info("base data: {}", data.toString());
+        return data;
+    }
+}

+ 332 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/impl/JsonData2ServiceImpl.java

@@ -0,0 +1,332 @@
+package com.fdkankan.indoor.core.service.impl;
+
+import com.fdkankan.indoor.base.util.JsonUtil;
+import com.fdkankan.indoor.base.util.Options;
+import com.fdkankan.indoor.core.dto.JsonDataDetailDto;
+import com.fdkankan.indoor.core.dto.QueryJsonDataBase;
+import com.fdkankan.indoor.core.dto.QueryJsonDataOne;
+import com.fdkankan.indoor.core.dto.QueryJsonDataTwo;
+import com.fdkankan.indoor.core.entity.jsonData.JsonData;
+import com.fdkankan.indoor.core.entity.jsonData.JsonData2;
+import com.fdkankan.indoor.core.service.JsonData2Service;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Admin
+ */
+
+@Service
+@Slf4j
+@AllArgsConstructor
+public class JsonData2ServiceImpl implements JsonData2Service {
+
+    private final MongoTemplate mongoTemplate;
+
+
+    @Override
+    public List<JsonData> filterJsonData(String code, QueryJsonDataBase data) {
+        log.info("code:{}, data:{}", code, data.toString());
+        List<JsonData> list;
+        if (data instanceof QueryJsonDataOne) {
+            QueryJsonDataOne one = (QueryJsonDataOne) data;
+            list = queryDataOne(one, code);
+            log.info("走one");
+        } else if (data instanceof QueryJsonDataTwo) {
+            QueryJsonDataTwo two = (QueryJsonDataTwo) data;
+            list = queryDataTwo(two, code);
+            log.info("走two");
+        } else {
+            throw new RuntimeException("没有查询到数据,请检查入参");
+        }
+        return list;
+    }
+
+    @Override
+    public JsonData findById(String id, String code) {
+        log.info("id: {}, code:{}", id, code);
+        JsonData result = null;
+        if ("test1".equals(code)){
+            result = mongoTemplate.findById(Long.valueOf(id), JsonData.class);
+        } else {
+            JsonData2 entity2 = mongoTemplate.findById(Long.valueOf(id), JsonData2.class);
+            result = new JsonData();
+            BeanUtils.copyProperties(entity2, result);
+        }
+
+        log.info("entity: {}", result);
+        return result;
+    }
+
+    /**
+     * 查询细节根据排序
+     * @param code
+     * @param jsonDataDetailDto
+     * @return
+     */
+    @Override
+    public List<JsonData> filterJsonDataDetail(String code, JsonDataDetailDto jsonDataDetailDto) {
+
+        List<JsonData> jsonDataList ;
+        Integer limit = jsonDataDetailDto.getLimit();
+        limit = limit==null ? 10: limit;
+
+
+        // 需要处理好and or 的条件
+        Criteria criteria = new Criteria();
+        criteria.andOperator(Criteria.where("dataset_id").is(jsonDataDetailDto.getDataset()),
+                new Criteria().orOperator(
+                Criteria.where("site_model_entity_id").is(jsonDataDetailDto.getSite_model_entity()),
+                Criteria.where("hidden").is(jsonDataDetailDto.getHidden())));
+
+        Query query = new Query();
+        query.addCriteria(criteria);
+        query.limit(limit);
+
+
+        String sort_order = jsonDataDetailDto.getSort_order();
+        if (sort_order != null) {
+            sort_order = sort_order.toLowerCase();
+            if ("desc".equals(sort_order)) {
+                query.with(Sort.by(Sort.Order.desc(jsonDataDetailDto.getSort_by())));
+            } else {
+                query.with(Sort.by(Sort.Order.asc(jsonDataDetailDto.getSort_by())));
+            }
+        }
+
+
+        if ("test1".equals(code)) {
+            log.info("走test1");
+            jsonDataList = mongoTemplate.find(query, JsonData.class);
+
+        } else {
+            log.info("走test2");
+            List<JsonData2> jsonDataList2 = mongoTemplate.find(query, JsonData2.class);
+            jsonDataList = copyList(jsonDataList2);
+            log.info("list转换成功");
+        }
+        log.info("返回数据数量: {}", jsonDataList.size());
+        return jsonDataList;
+    }
+
+    private List<JsonData> queryDataTwo(QueryJsonDataTwo queryJsonData , String code) {
+        log.info("run queryDataTwo");
+
+        Query query = new Query();
+        if (queryJsonData.getSiteModelEntity() != null) {
+            query.addCriteria(Criteria.where("site_model_entity_id").is(queryJsonData.getSiteModelEntity()));
+        }
+
+        List<JsonData> jsonDataList ;
+        if ("test1".equals(code)) {
+            log.info("走test1");
+            jsonDataList = mongoTemplate.find(query, JsonData.class);
+
+        } else {
+            log.info("走test2");
+            List<JsonData2> jsonDataList2 = mongoTemplate.find(query, JsonData2.class);
+//            jsonDataList = ConvertUtils.convertList(jsonDataList2, JsonData.class);
+            jsonDataList = copyList(jsonDataList2);
+            log.info("list转换成功");
+        }
+
+        jsonDataList = jsonDataList.stream().filter(jsonData ->
+                jsonData.getLocation()[0] >= queryJsonData.getLon_min() && jsonData.getLocation()[0] <= queryJsonData.getLon_max()
+                && jsonData.getLocation()[1] >= queryJsonData.getLat_min() && jsonData.getLocation()[1] <= queryJsonData.getLat_max())
+                .collect(Collectors.toList());
+
+        List<JsonData> newJsonData = fillNewJsonData(queryJsonData, jsonDataList);
+
+         return newJsonData;
+    }
+
+
+    /**
+     * 处理step step的值会有影响
+     * 当step=null, 0, 1不做处理
+     * @param queryJsonData
+     * @param jsonDataList
+     * @return
+     */
+    private List<JsonData> fillNewJsonData(QueryJsonDataTwo queryJsonData, List<JsonData> jsonDataList) {
+        List<JsonData> newJsonData = new ArrayList<>();
+        log.info("输入对象数量:{}", jsonDataList.size());
+        Integer inputStep = queryJsonData.getStep();
+        // 当inputStep为空、null、0、1 时返回全部数据
+        if (inputStep == null || inputStep==0 || inputStep==1) {
+            return jsonDataList;
+        }
+
+        /**
+         * 当inputStep大于1, 数量为200, 隔多少步取一个点
+         * 2:100
+         * 3:67
+         * 4:50
+         *
+         */
+        int step = 0;
+        if (inputStep > 1) {
+            for (JsonData jsonData : jsonDataList) {
+                if (step % inputStep == 0 || step == 0) {
+                    newJsonData.add(jsonData);
+                }
+                step++;
+            }
+        }
+        log.info("输出对象数量:{}", newJsonData.size());
+        return newJsonData;
+    }
+
+    private List<JsonData> queryDataOne(QueryJsonDataOne queryJsonData, String code) {
+        log.info("run queryDataOne");
+        List<JsonData> newJsonData = new ArrayList<>();
+        Query query = new Query();
+        if (queryJsonData.getSiteModelEntity() != null) {
+            query.addCriteria(Criteria.where("site_model_entity_id").is(queryJsonData.getSiteModelEntity()));
+        }
+
+        List<JsonData> jsonDataList ;
+        if ("test1".equals(code)) {
+            jsonDataList = mongoTemplate.find(query, JsonData.class);
+            log.info("走test1");
+
+        } else {
+            log.info("走test2");
+            List<JsonData2> jsonDataList2 = mongoTemplate.find(query, JsonData2.class);
+            jsonDataList = copyList(jsonDataList2);
+            log.info("list转换成功, jsonDataList.size: {}", jsonDataList.size());
+        }
+        if (queryJsonData.getZ() != null) {
+            jsonDataList = jsonDataList.stream().filter(jsonData ->
+                    jsonData.getLocation()[2] >= queryJsonData.getZ() && jsonData.getFloor_location()[2] <= queryJsonData.getZ())
+                    .collect(Collectors.toList());
+        }
+        // radius:半径
+        if (queryJsonData.getRadius() != null) {
+            newJsonData = calcule(queryJsonData, jsonDataList);
+        } else {
+            // 没有半径,算最近的距离
+            newJsonData = calculeMin(queryJsonData, jsonDataList);
+        }
+
+        if (queryJsonData.getLimit() != null) {
+            newJsonData = newJsonData.stream().limit(queryJsonData.getLimit()).collect(Collectors.toList());
+        }
+        return newJsonData;
+    }
+
+    private List<JsonData> copyList( List<JsonData2> list){
+        List<JsonData> objects = new ArrayList<>();
+        for (JsonData2 jsonData2 : list) {
+            JsonData jsonData = new JsonData();
+            BeanUtils.copyProperties(jsonData2, jsonData);
+            objects.add(jsonData);
+        }
+        return objects;
+
+    }
+
+    private List<JsonData> calcule(QueryJsonDataOne queryJsonData, List<JsonData> jsonDataList) {
+        log.info("run calcule");
+        List<JsonData> newJsonData = new ArrayList<>();
+        for (JsonData jsonData : jsonDataList) {
+//            log.info("jsonData: {}", jsonData);
+            Double[] coordinates1 = new Double[2];
+            coordinates1[0] = queryJsonData.getLon();
+            coordinates1[1] = queryJsonData.getLat();
+
+            Double[] coordinates2 = new Double[2];
+            coordinates2[0] = jsonData.getLocation()[0];
+            coordinates2[1] = jsonData.getLocation()[1];
+
+            Double distance = JsonUtil.distance(coordinates1, coordinates2, new Options().setUnits("miles"));
+//            log.info("计算出的距离:{}", distance);
+
+            if (queryJsonData.getRadius() > distance) {
+                newJsonData.add(jsonData);
+            }
+        }
+        return newJsonData;
+    }
+
+    /**
+     * 计算最小距离
+     * @param queryJsonData
+     * @param jsonDataList
+     * @return 获取最小值对象
+     */
+    private List<JsonData> calculeMin(QueryJsonDataOne queryJsonData, List<JsonData> jsonDataList) {
+        log.info("run calculeMin");
+        List<JsonData> newJsonData = new ArrayList<>();
+
+        // 计算距离后的结果接
+        HashMap<Double, JsonData> calResultMap = new HashMap<>();
+
+        int i = 1;
+        Double min = null;
+        for (JsonData jsonData : jsonDataList) {
+            Double[] coordinates1 = new Double[2];
+            coordinates1[0] = queryJsonData.getLon();
+            coordinates1[1] = queryJsonData.getLat();
+
+            Double[] coordinates2 = new Double[2];
+            coordinates2[0] = jsonData.getLocation()[0];
+            coordinates2[1] = jsonData.getLocation()[1];
+
+            Double distance = JsonUtil.distance(coordinates1, coordinates2, new Options().setUnits("miles"));
+//            log.info("计算出的距离:{}", distance);
+            // 默认取第一值
+            if (i==1) {
+                min = distance;
+                calResultMap.put(min, jsonData);
+            }
+
+            if (distance < min) {
+                min = distance;
+                calResultMap.put(min, jsonData);
+            }
+            i++;
+
+            }
+
+        log.info("循环次数:{}, 最小值:{}", i, min);
+        // 获取最小值
+        JsonData minJson = calResultMap.get(min);
+        newJsonData.add(minJson);
+        return newJsonData;
+    }
+
+
+    private List<JsonData> calcule2(QueryJsonDataOne queryJsonData, List<JsonData> jsonDataList) {
+        List<JsonData> newJsonData = new ArrayList<>();
+        for (JsonData jsonData : jsonDataList) {
+            Double[] coordinates1 = new Double[2];
+            coordinates1[0] = queryJsonData.getLon();
+            coordinates1[1] = queryJsonData.getLat();
+
+            Double[] coordinates2 = new Double[2];
+            coordinates2[0] = jsonData.getLocation()[0];
+            coordinates2[1] = jsonData.getLocation()[1];
+
+            // todo
+            Double distance = JsonUtil.distance(coordinates1, coordinates2, new Options().setUnits("miles"));
+            if (queryJsonData.getRadius() > distance) {
+                newJsonData.add(jsonData);
+            }
+        }
+        return newJsonData;
+    }
+
+
+}

+ 144 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/impl/JsonDataServiceImpl.java

@@ -0,0 +1,144 @@
+package com.fdkankan.indoor.core.service.impl;
+
+import com.fdkankan.indoor.base.util.JsonUtil;
+import com.fdkankan.indoor.base.util.Options;
+import com.fdkankan.indoor.core.dto.QueryJsonDataBase;
+import com.fdkankan.indoor.core.dto.QueryJsonDataOne;
+import com.fdkankan.indoor.core.dto.QueryJsonDataTwo;
+import com.fdkankan.indoor.core.entity.jsonData.JsonData;
+import com.fdkankan.indoor.core.entity.jsonData.JsonData2;
+import com.fdkankan.indoor.core.service.JsonDataService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Admin
+ */
+@Service
+@Slf4j
+@AllArgsConstructor
+public class JsonDataServiceImpl implements JsonDataService {
+
+    private final MongoTemplate mongoTemplate;
+
+
+    @Override
+    public List<JsonData> filterJsonData( QueryJsonDataBase data) {
+        List<JsonData> list;
+        if (data instanceof QueryJsonDataOne) {
+            QueryJsonDataOne one = (QueryJsonDataOne) data;
+            list = queryDataOne(one);
+        } else if (data instanceof QueryJsonDataTwo) {
+            QueryJsonDataTwo two = (QueryJsonDataTwo) data;
+            list = queryDataTwo(two);
+        } else {
+            throw new RuntimeException("没有查询到数据,请检查入参");
+        }
+        return list;
+    }
+
+    @Override
+    public JsonData findById(String id, String code) {
+        log.info("id: {}, code:{}", id, code);
+        JsonData result = null;
+        if ("test1".equals(code)){
+            result = mongoTemplate.findById(Long.valueOf(id), JsonData.class);
+        } else {
+            JsonData2 entity2 = mongoTemplate.findById(Long.valueOf(id), JsonData2.class);
+            result = new JsonData();
+            BeanUtils.copyProperties(entity2, result);
+        }
+
+        log.info("entity: {}", result);
+        return result;
+    }
+
+    private List<JsonData> queryDataTwo(QueryJsonDataTwo queryJsonData) {
+        Query query = new Query();
+        if (queryJsonData.getSiteModelEntity() != null) {
+            query.addCriteria(Criteria.where("site_model_entity_id").is(queryJsonData.getSiteModelEntity()));
+        }
+
+        List<JsonData> jsonDataList = mongoTemplate.find(query, JsonData.class);
+
+        jsonDataList = jsonDataList.stream().filter(jsonData ->
+                jsonData.getLocation()[0] >= queryJsonData.getLon_min() && jsonData.getLocation()[0] <= queryJsonData.getLon_max()
+                && jsonData.getLocation()[1] >= queryJsonData.getLat_min() && jsonData.getLocation()[1] <= queryJsonData.getLat_max())
+                .collect(Collectors.toList());
+
+        List<JsonData> newJsonData = fillNewJsonData(queryJsonData, jsonDataList);
+
+        return newJsonData;
+    }
+
+    private List<JsonData> fillNewJsonData(QueryJsonDataTwo queryJsonData, List<JsonData> jsonDataList) {
+        List<JsonData> newJsonData = new ArrayList<>();
+        int step = 0;
+        if (queryJsonData.getStep() != null) {
+            for (JsonData jsonData : jsonDataList) {
+                if (step % queryJsonData.getStep() == 0 || step == 0) {
+                    newJsonData.add(jsonData);
+                }
+                step++;
+            }
+        }
+        return newJsonData;
+    }
+
+    private List<JsonData> queryDataOne(QueryJsonDataOne queryJsonData) {
+        List<JsonData> newJsonData = new ArrayList<>();
+        Query query = new Query();
+        if (queryJsonData.getSiteModelEntity() != null) {
+            query.addCriteria(Criteria.where("site_model_entity_id").is(queryJsonData.getSiteModelEntity()));
+        }
+
+        List<JsonData> jsonDataList = mongoTemplate.find(query, JsonData.class);
+        if (queryJsonData.getZ() != null) {
+            jsonDataList = jsonDataList.stream().filter(jsonData ->
+                    jsonData.getLocation()[2] >= queryJsonData.getZ() && jsonData.getFloor_location()[2] <= queryJsonData.getZ())
+                    .collect(Collectors.toList());
+        }
+
+        if (queryJsonData.getRadius() != null) {
+            newJsonData = calcule(queryJsonData, jsonDataList);
+        } else {
+            newJsonData.addAll(jsonDataList);
+        }
+
+        if (queryJsonData.getLimit() != null) {
+            newJsonData = newJsonData.stream().limit(queryJsonData.getLimit()).collect(Collectors.toList());
+        }
+        return newJsonData;
+    }
+
+    private List<JsonData> calcule(QueryJsonDataOne queryJsonData, List<JsonData> jsonDataList) {
+        List<JsonData> newJsonData = new ArrayList<>();
+        for (JsonData jsonData : jsonDataList) {
+            Double[] coordinates1 = new Double[2];
+            coordinates1[0] = queryJsonData.getLon();
+            coordinates1[1] = queryJsonData.getLat();
+
+            Double[] coordinates2 = new Double[2];
+            coordinates2[0] = jsonData.getLocation()[0];
+            coordinates2[1] = jsonData.getLocation()[1];
+
+            // todo
+            Double distance = JsonUtil.distance(coordinates1, coordinates2, new Options().setUnits("miles"));
+            if (queryJsonData.getRadius() > distance) {
+                newJsonData.add(jsonData);
+            }
+        }
+        return newJsonData;
+    }
+
+
+}

+ 131 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/impl/LoginServiceImpl.java

@@ -0,0 +1,131 @@
+package com.fdkankan.indoor.core.service.impl;
+
+import com.fdkankan.indoor.base.util.JwtUtil;
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.entity.SysUserEntity;
+import com.fdkankan.indoor.core.entity.poi.PoiEntity;
+import com.fdkankan.indoor.core.service.LoginService;
+import com.fdkankan.indoor.core.service.SysUserService;
+import com.fdkankan.indoor.core.vo.BaseVo;
+import com.fdkankan.indoor.core.vo.UserVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+
+/**
+ * Created by owen on 2021/7/19 0019 11:53
+ */
+@Slf4j
+@Service
+public class LoginServiceImpl implements LoginService {
+
+    @Autowired
+    SysUserService sysUserService;
+
+    @Autowired
+    MongoTemplate mongoTemplate;
+
+    // 目前是24h
+    private static Integer TOKEN_EXPIRE = 1000 * 60 * 60 * 24;
+
+    @Override
+    public Result login(String username, String password) {
+
+        SysUserEntity dbUser = sysUserService.findByUserName(username);
+        if (dbUser == null) {
+            log.error("用户名不存在: {}", username);
+            throw new RuntimeException("账号或密码错误");
+        }
+        if (!password.equals(dbUser.getPassword())){
+            log.error("密码错误: {}", password);
+            throw new RuntimeException("账号或密码错误");
+        }
+
+        // 创建新token
+        HashMap<String, Object> tokenMap = new HashMap<>();
+        tokenMap.put("userName", username);
+        tokenMap.put("id", dbUser.getId());
+
+        String token = JwtUtil.createJWT(TOKEN_EXPIRE, tokenMap);
+
+        UserVo userVo = new UserVo();
+        userVo.setId(dbUser.getId());
+        userVo.setUsername(dbUser.getUsername());
+
+        HashMap<Object, Object> resultMap = new HashMap<>();
+        resultMap.put("token", token);
+        resultMap.put("principal", userVo);
+
+        log.info("返回结果: {}", userVo);
+        return Result.success(resultMap);
+    }
+
+    @Override
+    public Result groups(String sceneCode) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(sceneCode));
+        BaseVo vo = mongoTemplate.findOne(query, BaseVo.class, "t_group");
+        return Result.success(vo.getData());
+    }
+
+    @Override
+    public Result license(String sceneCode) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(sceneCode));
+        BaseVo vo = mongoTemplate.findOne(query, BaseVo.class, "t_license");
+        return Result.success(vo.getData());
+    }
+
+    @Override
+    public Result health(String sceneCode) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(sceneCode));
+        BaseVo vo = mongoTemplate.findOne(query, BaseVo.class, "t_health");
+        return Result.success(vo.getData());
+    }
+
+    @Override
+    public Result configs(String sceneCode) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(sceneCode));
+        BaseVo vo = mongoTemplate.findOne(query, BaseVo.class, "t_configs");
+        return Result.success(vo.getData());
+    }
+
+    @Override
+    public Result user(String sceneCode) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(sceneCode));
+        BaseVo vo = mongoTemplate.findOne(query, BaseVo.class, "t_user");
+        return Result.success(vo.getData());
+    }
+
+    @Override
+    public Result users(String sceneCode) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(sceneCode));
+        BaseVo vo = mongoTemplate.findOne(query, BaseVo.class, "t_users");
+        return Result.success(vo.getData());
+    }
+
+    @Override
+    public Result poiTypeGroups(String sceneCode) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(sceneCode));
+        BaseVo vo = mongoTemplate.findOne(query, BaseVo.class, "t_poi_type_groups");
+        return Result.success(vo.getData());
+    }
+
+    @Override
+    public Result poiTypes(String sceneCode) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(sceneCode));
+        BaseVo vo = mongoTemplate.findOne(query, BaseVo.class, "t_poi_types");
+        return Result.success(vo.getData());
+    }
+}

+ 148 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/impl/PoiServiceImpl.java

@@ -0,0 +1,148 @@
+package com.fdkankan.indoor.core.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.dto.PoiSearchDto;
+import com.fdkankan.indoor.core.entity.poi.PoiEntity;
+import com.fdkankan.indoor.core.service.PoiService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.IntSummaryStatistics;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created by owen on 2021/7/14 0014 14:31
+ */
+@Slf4j
+@Service
+public class PoiServiceImpl implements PoiService {
+
+    @Autowired
+    MongoTemplate mongoTemplate;
+
+    @Override
+    public Result findBySceneCodeAndId(String code, Integer id) {
+        log.info("code:{}, id:{}", code, id);
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(code));
+        PoiEntity poiEtity = mongoTemplate.findOne(query, PoiEntity.class);
+        if (poiEtity == null) {
+            throw new RuntimeException("没有此场景数据");
+        }
+        Object result = findByDataId(id, poiEtity);
+
+        return Result.success(result);
+    }
+
+    @Override
+    public Result search(String code, PoiSearchDto param) {
+        String query = param.getQuery();
+        JSONArray array = findBySceneCode(code);
+        if (query==null){
+            throw new RuntimeException("查询参数不能为空");
+//            return Result.success(array);
+        }
+
+
+        Integer size = param.getSize();
+        log.info("输入数量:{}", size);
+        size = size==null ? 10 : size;
+
+        // 模糊查询数组的titles字段, filter后面是判断值
+        List titles = array.stream().filter(p ->  getContent(p, query)).limit(size).collect(Collectors.toList());
+
+        log.info("返回数量:{}", titles.size());
+
+        List<Object> objects = ormPoi(titles);
+        return Result.success(objects);
+    }
+
+    // 前端需要, 映射实体
+    private List<Object> ormPoi(List pois){
+
+        List<Object> result = new ArrayList<>();
+        for (Object o : pois) {
+            JSONObject paramJson = JSON.parseObject(o.toString());
+            JSONObject resJson = new JSONObject();
+            resJson.put("id", paramJson.getInteger("id"));
+            resJson.put("icon", paramJson.getString("icon"));
+            resJson.put("location", paramJson.get("location"));
+            resJson.put("site_model_entity_id", paramJson.getInteger("site_model_entity_id"));
+            resJson.put("poi_type_id", paramJson.getInteger("poi_type_id"));
+            resJson.put("title", paramJson.getJSONObject("titles").getString("zh"));
+            resJson.put("matching_title", resJson.getString("title"));
+            resJson.put("matching_description", paramJson.getJSONObject("descriptions").getString("zh"));
+            resJson.put("score", null);
+
+            result.add(resJson);
+        }
+        return result;
+
+    }
+
+
+    private Boolean getContent(Object p, String searchKey){
+        String titles  = JSONObject.parseObject(p.toString()).getString("titles");
+//        log.info("titles: {}, 配备结果:{}", titles, titles.contains(searchKey));
+        return titles.contains(searchKey);
+    }
+
+    /**
+     * 根据场景码查询数据
+     * @param sceneCode
+     * @return
+     */
+    private JSONArray findBySceneCode(String sceneCode) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneCode").is(sceneCode));
+        PoiEntity poiEtity = mongoTemplate.findOne(query, PoiEntity.class);
+        if (poiEtity == null) {
+            throw new RuntimeException("没有此场景数据");
+        }
+        List list = poiEtity.getData();
+        JSONArray array= JSONArray.parseArray(JSON.toJSONString(list));
+        return array;
+    }
+
+    /**
+     *
+     * @param id data数据里的id
+     * @param poiEtity 文档对象
+     * @return
+     */
+    private Object findByDataId(Integer id, PoiEntity poiEtity){
+        List list = poiEtity.getData();
+        JSONArray array= JSONArray.parseArray(JSON.toJSONString(list));
+        for (Object o : array) {
+            JSONObject cheld = JSONObject.parseObject(o.toString());
+            Integer cheldId = cheld.getInteger("id");
+            log.info("cheldId: {}", cheldId);
+            if (id == cheldId){
+                return cheld;
+            }
+        }
+        return null;
+    }
+
+
+    public static void main(String[] args) {
+        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
+
+        IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
+
+        System.out.println("列表中最大的数 : " + stats.getMax());
+        System.out.println("列表中最小的数 : " + stats.getMin());
+        System.out.println("所有数之和 : " + stats.getSum());
+        System.out.println("平均数 : " + stats.getAverage());
+    }
+}

+ 440 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/impl/SiteModel2ServiceImpl.java

@@ -0,0 +1,440 @@
+package com.fdkankan.indoor.core.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.indoor.base.util.ConvertUtils;
+import com.fdkankan.indoor.base.util.GisUtils;
+import com.fdkankan.indoor.base.util.JsonUtil;
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.dto.SiteModelSearchDto;
+import com.fdkankan.indoor.core.entity.siteModel.Polygon;
+import com.fdkankan.indoor.core.entity.siteModel.SiteModel;
+import com.fdkankan.indoor.core.entity.siteModel.SiteModel2;
+import com.fdkankan.indoor.core.service.SiteModel2Service;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.awt.geom.Point2D;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Admin
+ */
+@Service
+@Slf4j
+@AllArgsConstructor
+public class SiteModel2ServiceImpl implements SiteModel2Service {
+
+    private final MongoTemplate mongoTemplate;
+
+
+    @Override
+    public SiteModel within(Double[] location, String type) {
+        List<SiteModel> models = new ArrayList<>();
+
+        SiteModel siteModel = mongoTemplate.findOne(new Query(), SiteModel.class);
+
+        models.add(copyModelNotContainChildren(siteModel));
+        if (!CollectionUtils.isEmpty(siteModel.getChildren())) {
+            organizeModels(siteModel, models);
+        }
+        models = models.stream().filter(mod -> filterModels(mod, location, type)).collect(Collectors.toList());
+        
+        Point2D.Double pointParam = new Point2D.Double(location[0], location[1]);
+        log.info("pointParam: {}", pointParam);
+        SiteModel siteModel1 = models.stream().filter(sm -> getSm(sm, pointParam)).findAny()
+                .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
+        return siteModel1;
+    }
+
+    @Override
+    public SiteModel withinType(String code, Double[] location, String type) {
+        log.info("code: {}", code);
+        log.info("location: {}", location);
+        log.info("code: {}", type);
+
+        // 总对象
+        List<SiteModel> models = new ArrayList<>();
+        SiteModel siteModel = null;
+        if ("test1".equals(code)) {
+             siteModel = mongoTemplate.findOne(new Query(), SiteModel.class, "site_model");
+        } else {
+            siteModel = mongoTemplate.findOne(new Query(), SiteModel.class, "site_model_2");
+        }
+
+        // copy实体对象
+        SiteModel newSiteModel = copyModelNotContainChildren(siteModel);
+        // 做为父节点的低一条
+        models.add(newSiteModel);
+        if (!CollectionUtils.isEmpty(siteModel.getChildren())) {
+            organizeModels2(siteModel, models);
+        }
+
+
+        // 按type封装成对象数组
+        List<SiteModel> resultList = new ArrayList<>();
+        SiteModel result = null;
+
+        Point2D.Double pointParam = new Point2D.Double(location[0], location[1]);
+        log.info("pointParam: {}", pointParam);
+        if ("BUILDING".equals(type)) {
+             resultList =  models.stream().filter(data -> "BUILDING".equals(data.getType())).collect(Collectors.toList());
+            result = resultList.stream().filter(sm -> getSm(sm, pointParam)).findAny()
+                    .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
+        } else if ("FLOOR".equals(type)) {
+            resultList =  models.stream().filter(data -> "FLOOR".equals(data.getType())).collect(Collectors.toList());
+            log.info("resultList.size: {}", resultList.size());
+
+            result = resultList.stream().filter(sm -> getSmByFloor(sm, pointParam)).findAny().orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
+        } else if ("ROOM".equals(type)) {
+            resultList =  models.stream().filter(data -> "ROOM".equals(data.getType())).collect(Collectors.toList());
+            result = resultList.stream().filter(sm -> getSm(sm, pointParam)).findAny()
+                    .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
+            // type为空,返回全部数据
+        } else {
+            resultList =  models.stream().filter(data -> "ROOM".equals(data.getType())).collect(Collectors.toList());
+            result = resultList.stream().filter(sm -> getSm(sm, pointParam)).findAny()
+                    .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
+
+            List<SiteModel> roomChildren = new ArrayList<>();
+            roomChildren.add(result);
+            siteModel.setChildren(roomChildren);
+            result = siteModel;
+        }
+
+        log.info("result: {}", result);
+
+        return result;
+
+    }
+
+    @Override
+    public SiteModel findById(Long id, String code) {
+        SiteModel siteModel= null;
+        if ("test1".equals(code)) {
+            siteModel = mongoTemplate.findById(id, SiteModel.class);
+        } else {
+            SiteModel2 siteMode2 = mongoTemplate.findById(id, SiteModel2.class);
+            siteModel = new SiteModel();
+            BeanUtils.copyProperties(siteMode2, siteModel);
+        }
+        return siteModel;
+    }
+
+    @Override
+    public Result getData(JSONObject param, String code) {
+        String type = param.getString("type");
+        if (!"BUILDING".equals(type)) {
+            throw new RuntimeException("非BUILDING类型");
+        }
+
+        SiteModel siteModel= null;
+        if ("test1".equals(code)) {
+            siteModel = mongoTemplate.findOne(new Query(), SiteModel.class);
+        } else {
+            SiteModel2 siteMode2 = mongoTemplate.findOne(new Query(), SiteModel2.class);
+            siteModel = new SiteModel();
+            BeanUtils.copyProperties(siteMode2, siteModel);
+        }
+        if (siteModel != null) {
+            siteModel.setChildren(new ArrayList<>());
+            return Result.success(siteModel);
+        }
+
+        return Result.success();
+    }
+
+    @Override
+    public Result search(String sceneCode, SiteModelSearchDto searchDto) {
+        SiteModel siteModel = getSceneCode(sceneCode);
+        List<SiteModel> loopModel = getLoopModel(siteModel);
+        String searchKey = searchDto.getQuery();
+        Integer size = searchDto.getSize();
+        size = size==null?10: size;
+        List<SiteModel> collect = loopModel.stream().filter(p -> getContent(p, searchKey)).limit(size).collect(Collectors.toList());
+        log.info("返回collect数量: {}", collect.size());
+
+        // 映射实体名称
+        List<Object> result = ormSiteModel(collect);
+
+        return Result.success(result);
+    }
+
+    @Override
+    public Result latest(String sceneCode, Double[] location, Double radius) {
+        SiteModel siteModel = getSceneCode(sceneCode);
+
+        // 递归为对象
+        List<SiteModel> loopModel = getLoopModel(siteModel);
+
+        // 获取点在多边形的集合
+        List<SiteModel> result = loopModel.stream().filter(p -> pointIsArea(location, p)).collect(Collectors.toList());
+
+        log.info("没有父级的数量:{}", result.size());
+        // 将父级有parenId的对象添加到result
+        addSiteMode(loopModel, result);
+        log.info("添加父级后的数量:{}", result.size());
+
+
+        return Result.success(loopModel);
+    }
+
+    /**
+     * 将父节点添加到结果集
+     * @param loopModel
+     * @param result
+     */
+    private void addSiteMode(List<SiteModel> loopModel, List<SiteModel> result) {
+        Set<SiteModel> parentSiteModel = getParentSiteModel(loopModel, result);
+        for (SiteModel siteModel : parentSiteModel) {
+            result.add(siteModel);
+        }
+    }
+
+    /**
+     * 获取父节点
+     * @param loopModel
+     * @param result
+     * @return
+     */
+    private Set<SiteModel> getParentSiteModel(List<SiteModel> loopModel, List<SiteModel> result){
+        Set<SiteModel>  parent = new HashSet<>();
+        for (SiteModel siteModel : loopModel) {
+            for (SiteModel model : result) {
+                if (model.getParentId() == siteModel.getId()) {
+                    parent.add(siteModel);
+                }
+            }
+        }
+        return parent;
+    }
+
+
+    /**
+     * 输入点是否在多边形内
+     * @param point
+     * @param param
+     * @return
+     */
+    private boolean pointIsArea(Double[] point, SiteModel param){
+        // 获取多边行点
+        Polygon polygon = param.getPolygon();
+        if (polygon == null) {
+            return false;
+        }
+        List<List<List<Double>>> coordinates = polygon.getCoordinates();
+        if (CollectionUtils.isEmpty(coordinates)){
+            return false;
+        }
+        List<List<Double>> lists = coordinates.get(0);
+        if (CollectionUtils.isEmpty(lists)){
+            return false;
+        }
+
+        Point2D.Double pointDouble = new Point2D.Double();
+        pointDouble.setLocation(point[0], point[1]);
+
+
+        List<Point2D.Double> allPoints = lists.stream()
+                .map(points -> new Point2D.Double(points.get(0), points.get(1))).collect(Collectors.toList());
+
+        Boolean inArea = GisUtils.rayCasting(allPoints, pointDouble);
+        log.info("是否在多边型内: {}",  inArea);
+
+        return inArea;
+    }
+
+
+
+
+
+    // 前端需要, 映射实体
+    private List<Object> ormSiteModel(List<SiteModel> collect){
+        List<Object> list = new ArrayList<>();
+        for (SiteModel siteModel : collect) {
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("id", siteModel.getId());
+            jsonObject.put("title", siteModel.getName());
+            jsonObject.put("matching_title", siteModel.getName());
+            jsonObject.put("matching_description", null);
+            list.add(jsonObject);
+        }
+        return list;
+
+    }
+
+    // 模糊匹配
+    private Boolean getContent(SiteModel p, String searchKey){
+        String name = p.getName();
+        log.info("name: {}, 配备结果:{}", name, name.contains(searchKey));
+        return name.contains(searchKey);
+    }
+
+    /**
+     * 根据场景码获取对象
+     * @param sceneCode
+     * @return
+     */
+    private SiteModel getSceneCode(String sceneCode){
+        SiteModel siteModel;
+
+        if ("test1".equals(sceneCode)) {
+            siteModel = mongoTemplate.findOne(new Query(), SiteModel.class, "site_model");
+        } else {
+            siteModel = mongoTemplate.findOne(new Query(), SiteModel.class, "site_model_2");
+        }
+        return siteModel;
+    }
+
+
+
+    private boolean filterModels(SiteModel mod, Double[] location, String type) {
+        if (!StringUtils.isEmpty(type)) {
+            if (mod.getPolygon() == null || !type.equals(mod.getPolygon().getType())) {
+                return false;
+            }
+        }
+
+        if (location != null && location.length == 3) {
+            if (mod.getZ_max() == null || mod.getZ_min() == null) {
+                return false;
+            }
+            if (mod.getZ_max() >= location[2] && mod.getZ_min() <= location[2]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    // 判断的坐标在那个空间位置
+    private boolean getSm(SiteModel model, Point2D.Double pointParam) {
+        if (CollectionUtils.isEmpty(model.getPolygon().getCoordinates())
+                || CollectionUtils.isEmpty(model.getPolygon().getCoordinates().get(0))
+                || CollectionUtils.isEmpty(model.getPolygon().getCoordinates().get(0).get(0))) {
+            return false;
+        }
+
+        List<Point2D.Double> allPoints = model.getPolygon().getCoordinates().get(0).stream()
+                .map(points -> new Point2D.Double(points.get(0), points.get(1))).collect(Collectors.toList());
+        if (JsonUtil.IsPtInPoly(pointParam, allPoints)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * type=FLOOR 时,polygon=null
+     * @param model
+     * @param pointParam
+     * @return
+     */
+    private boolean getSmByFloor(SiteModel model, Point2D.Double pointParam) {
+        Polygon polygon = model.getPolygon();
+        if (polygon == null) {
+            return true;
+        }
+
+        List<Point2D.Double> allPoints = model.getPolygon().getCoordinates().get(0).stream()
+                .map(points -> new Point2D.Double(points.get(0), points.get(1))).collect(Collectors.toList());
+        if (JsonUtil.IsPtInPoly(pointParam, allPoints)) {
+            return true;
+        }
+        return false;
+    }
+
+
+    // 复制数据的作用?
+    private SiteModel copyModelNotContainChildren(SiteModel siteModel) {
+        SiteModel newSiteModel = new SiteModel();
+        BeanUtils.copyProperties(siteModel, newSiteModel);
+        newSiteModel.setChildren(null);
+        return newSiteModel;
+    }
+
+
+    // 递归的作用是?
+    private void organizeModels(SiteModel siteModel, List<SiteModel> models) {
+        List<SiteModel> children = siteModel.getChildren();
+         children = ConvertUtils.convertList(children, SiteModel.class);
+//        copyList(children)
+        log.info("children.size: {}", children.size());
+        for (SiteModel child : children) {
+            models.add(copyModelNotContainChildren(child));
+            if (!CollectionUtils.isEmpty(child.getChildren())) {
+                organizeModels(child, models);
+            }
+        }
+        log.info("models.size: {}", models.size());
+    }
+
+
+    private List<SiteModel> copyList(List<SiteModel2> list){
+        List<SiteModel> objects = new ArrayList<>();
+        for (SiteModel2 data : list) {
+            SiteModel entity = new SiteModel();
+            BeanUtils.copyProperties(data, entity);
+            objects.add(entity);
+        }
+        return objects;
+
+    }
+
+
+    /**
+     * 2021-07-14
+     * 获取原来的对象test1 一共是17条
+     * @param siteModel
+     * @param models 数量回保存到原来的数据
+     */
+    private void organizeModels2(SiteModel siteModel, List<SiteModel> models) {
+        for (SiteModel child : siteModel.getChildren()) {
+            models.add(copyModelNotContainChildren(child));
+            if (!CollectionUtils.isEmpty(child.getChildren())) {
+                organizeModels2(child, models);
+            }
+        }
+//        log.info("models.size: {}", models.size());
+    }
+
+
+    private void organizeModels3(SiteModel siteModel, List<SiteModel> models) {
+        for (SiteModel child : siteModel.getChildren()) {
+            Integer id = siteModel.getId();
+            child.setParentId(id);
+            models.add(copyModelNotContainChildren(child));
+            if (!CollectionUtils.isEmpty(child.getChildren())) {
+                organizeModels3(child, models);
+            }
+        }
+//        log.info("models.size: {}", models.size());
+    }
+
+
+    /**
+     * 2021-07-16
+     * 递归出每一个对象
+     * @param siteModel
+     * @return
+     */
+    private List<SiteModel> getLoopModel(SiteModel siteModel){
+        List<SiteModel> models = new ArrayList<>();
+        // copy实体对象
+        SiteModel newSiteModel = copyModelNotContainChildren(siteModel);
+        // 做为父节点的低一条
+        models.add(newSiteModel);
+        if (!CollectionUtils.isEmpty(siteModel.getChildren())) {
+//            organizeModels2(siteModel, models);
+            organizeModels3(siteModel, models);
+        }
+        log.info("models.size: {}", models.size());
+        return models;
+
+    }
+}

+ 197 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/impl/SiteModelServiceImpl.java

@@ -0,0 +1,197 @@
+package com.fdkankan.indoor.core.service.impl;
+
+import com.fdkankan.indoor.base.util.JsonUtil;
+import com.fdkankan.indoor.core.entity.siteModel.Polygon;
+import com.fdkankan.indoor.core.entity.siteModel.SiteModel;
+import com.fdkankan.indoor.core.service.SiteModelService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Admin
+ */
+@Service
+@Slf4j
+@AllArgsConstructor
+public class SiteModelServiceImpl implements SiteModelService {
+
+    private final MongoTemplate mongoTemplate;
+
+
+    @Override
+    public SiteModel within(Double[] location, String type) {
+        List<SiteModel> models = new ArrayList<>();
+
+        SiteModel siteModel = mongoTemplate.findOne(new Query(), SiteModel.class);
+
+        models.add(copyModelNotContainChildren(siteModel));
+        if (!CollectionUtils.isEmpty(siteModel.getChildren())) {
+            organizeModels(siteModel, models);
+        }
+        models = models.stream().filter(mod -> filterModels(mod, location, type)).collect(Collectors.toList());
+        
+        Point2D.Double pointParam = new Point2D.Double(location[0], location[1]);
+        log.info("pointParam: {}", pointParam);
+        SiteModel siteModel1 = models.stream().filter(sm -> getSm(sm, pointParam)).findAny()
+                .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
+        return siteModel1;
+    }
+
+    @Override
+    public SiteModel withinType(String code, Double[] location, String type) {
+        log.info("code: {}", code);
+        log.info("location: {}", location);
+        log.info("code: {}", type);
+
+
+        List<SiteModel> models = new ArrayList<>();
+
+        SiteModel siteModel = mongoTemplate.findOne(new Query(), SiteModel.class);
+
+        models.add(copyModelNotContainChildren(siteModel));
+        if (!CollectionUtils.isEmpty(siteModel.getChildren())) {
+            organizeModels(siteModel, models);
+        }
+        // 按type封装成对象数组
+//        models = models.stream().filter(mod -> filterModels(mod, location, type)).collect(Collectors.toList());
+//        log.info("models: {}", models);
+
+        List<SiteModel> resultList = new ArrayList<>();
+        SiteModel result = null;
+
+        Point2D.Double pointParam = new Point2D.Double(location[0], location[1]);
+        log.info("pointParam: {}", pointParam);
+        if ("BUILDING".equals(type)) {
+             resultList =  models.stream().filter(data -> "BUILDING".equals(data.getType())).collect(Collectors.toList());
+            result = resultList.stream().filter(sm -> getSm(sm, pointParam)).findAny()
+                    .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
+        } else if ("FLOOR".equals(type)) {
+            resultList =  models.stream().filter(data -> "FLOOR".equals(data.getType())).collect(Collectors.toList());
+            result = resultList.stream().filter(sm -> getSmByFloor(sm, pointParam)).findAny().orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
+        } else if ("ROOM".equals(type)) {
+            resultList =  models.stream().filter(data -> "ROOM".equals(data.getType())).collect(Collectors.toList());
+            result = resultList.stream().filter(sm -> getSm(sm, pointParam)).findAny()
+                    .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
+            // type为空,返回全部数据
+        } else {
+            resultList =  models.stream().filter(data -> "ROOM".equals(data.getType())).collect(Collectors.toList());
+            result = resultList.stream().filter(sm -> getSm(sm, pointParam)).findAny()
+                    .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
+
+//            List<SiteModel> floorChildren = siteModel.getChildren();
+            List<SiteModel> roomChildren = new ArrayList<>();
+            roomChildren.add(result);
+            siteModel.setChildren(roomChildren);
+            result = siteModel;
+
+
+        }
+
+        log.info("result: {}", result);
+
+        return result;
+
+    }
+
+
+    private List<SiteModel> getBuilding(List<SiteModel> param){
+        return null;
+    }
+
+    private List<SiteModel> getFloor(){
+
+        return null;
+    }
+
+    private List<SiteModel> getDoom(){
+
+        return null;
+    }
+
+
+    private boolean filterModels(SiteModel mod, Double[] location, String type) {
+        if (!StringUtils.isEmpty(type)) {
+            if (mod.getPolygon() == null || !type.equals(mod.getPolygon().getType())) {
+                return false;
+            }
+        }
+
+        if (location != null && location.length == 3) {
+            if (mod.getZ_max() == null || mod.getZ_min() == null) {
+                return false;
+            }
+            if (mod.getZ_max() >= location[2] && mod.getZ_min() <= location[2]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    // 判断的作用是?
+    private boolean getSm(SiteModel model, Point2D.Double pointParam) {
+        if (CollectionUtils.isEmpty(model.getPolygon().getCoordinates())
+                || CollectionUtils.isEmpty(model.getPolygon().getCoordinates().get(0))
+                || CollectionUtils.isEmpty(model.getPolygon().getCoordinates().get(0).get(0))) {
+            return false;
+        }
+
+        List<Point2D.Double> allPoints = model.getPolygon().getCoordinates().get(0).stream()
+                .map(points -> new Point2D.Double(points.get(0), points.get(1))).collect(Collectors.toList());
+        if (JsonUtil.IsPtInPoly(pointParam, allPoints)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * type=FLOOR 时,polygon=null
+     * @param model
+     * @param pointParam
+     * @return
+     */
+    private boolean getSmByFloor(SiteModel model, Point2D.Double pointParam) {
+        Polygon polygon = model.getPolygon();
+        if (polygon == null) {
+            return true;
+        }
+
+        List<Point2D.Double> allPoints = model.getPolygon().getCoordinates().get(0).stream()
+                .map(points -> new Point2D.Double(points.get(0), points.get(1))).collect(Collectors.toList());
+        if (JsonUtil.IsPtInPoly(pointParam, allPoints)) {
+            return true;
+        }
+        return false;
+    }
+
+
+    // 复制数据的作用?
+    private SiteModel copyModelNotContainChildren(SiteModel siteModel) {
+        SiteModel newSiteModel = new SiteModel();
+        BeanUtils.copyProperties(siteModel, newSiteModel);
+        newSiteModel.setChildren(null);
+        return newSiteModel;
+    }
+
+
+    // 递归的作用是?
+    private void organizeModels(SiteModel siteModel, List<SiteModel> models) {
+        for (SiteModel child : siteModel.getChildren()) {
+            models.add(copyModelNotContainChildren(child));
+            if (!CollectionUtils.isEmpty(child.getChildren())) {
+                organizeModels(child, models);
+            }
+        }
+    }
+}

+ 46 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/impl/SysUserServiceImpl.java

@@ -0,0 +1,46 @@
+package com.fdkankan.indoor.core.service.impl;
+
+import com.fdkankan.indoor.core.entity.SysUserEntity;
+import com.fdkankan.indoor.core.mapper.SysUserMapper;
+import com.fdkankan.indoor.core.service.SysUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+/**
+ * Created by owen on 2021/7/19 0019 11:53
+ */
+@Slf4j
+@Service
+public class SysUserServiceImpl implements SysUserService {
+
+    @Autowired
+    SysUserMapper sysUserMapper;
+
+    @Override
+    public SysUserEntity findByUserName(String username) {
+        SysUserEntity entity = sysUserMapper.findByUsername(username);
+        return entity;
+    }
+
+
+//    @Override
+//    public SysUserEntity findByUserName(String username) {
+//        log.info("param: {}", username);
+//        SysUserEntity entity = new SysUserEntity();
+//        entity.setUsername(username);
+//        Example<SysUserEntity> example = Example.of(entity);
+//        Optional<SysUserEntity> one = sysUserMapper.findOne(example);
+//        log.info("返回结果: {}", one);
+//        boolean present = one.isPresent();
+//        if (present) {
+//            return one.get();
+//        }
+//
+//        return null;
+//    }
+}

+ 36 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/impl/TsiteModelServiceImpl.java

@@ -0,0 +1,36 @@
+package com.fdkankan.indoor.core.service.impl;
+
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.entity.tsiteModel.TsiteModel;
+import com.fdkankan.indoor.core.service.TsiteModelService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * Created by owen on 2021/7/14 0014 9:35
+ */
+@Slf4j
+@Service
+public class TsiteModelServiceImpl implements TsiteModelService {
+
+    @Autowired
+    MongoTemplate mongoTemplate;
+
+    @Override
+    public Result withinBySceneNum(String sceneNum, Double[] location, String type) {
+        log.info("sceneNum:{}, type:{}", sceneNum, type);
+
+        // 查找对象
+        Query query = new Query();
+        query.addCriteria(Criteria.where("sceneNum").is(sceneNum));
+        TsiteModel entity = mongoTemplate.findOne(query, TsiteModel.class);
+
+
+        return Result.success(entity);
+    }
+}

+ 27 - 0
laser/src/main/java/com/fdkankan/indoor/core/vo/AttributesVo.java

@@ -0,0 +1,27 @@
+package com.fdkankan.indoor.core.vo;
+
+import lombok.Data;
+
+/**
+ * Created by owen on 2021/7/19 0019 16:00
+ * 
+ * 暂时先写死
+ */
+
+@Data
+public class AttributesVo {
+			private Boolean can_edit_site_model_attributes = true;
+            private Boolean can_create_poi_groups = true;
+            private Boolean can_make_public = true;
+            private Boolean can_create_bundles = true;
+            private Boolean can_create_polygons = true;
+            private Boolean can_crop_and_download_point_cloud = true;
+            private Boolean can_create_user_groups = true;
+            private Boolean can_create_pois = true;
+            private Boolean can_create_datasets = true;
+            private Boolean can_view_site_model_attributes = true;
+            private Boolean can_use_measurement_tool = true;
+            private Boolean can_save_measurements = true;
+            private Boolean can_export_poi_audit_records = true;
+    
+}

+ 16 - 0
laser/src/main/java/com/fdkankan/indoor/core/vo/BaseVo.java

@@ -0,0 +1,16 @@
+package com.fdkankan.indoor.core.vo;
+
+import lombok.Data;
+
+/**
+ * Created by owen on 2021/7/19 0019 17:02
+ */
+@Data
+public class BaseVo {
+
+    private Integer id;
+
+    private String sceneCode;
+
+    private Object data;
+}

+ 25 - 0
laser/src/main/java/com/fdkankan/indoor/core/vo/GroupsVo.java

@@ -0,0 +1,25 @@
+package com.fdkankan.indoor.core.vo;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by owen on 2021/7/19 0019 16:40
+ *
+ */
+@Data
+public class GroupsVo {
+
+    private JSONObject security;
+
+    private Integer id;
+
+    private String name;
+
+    private List<String> attributes = new ArrayList<>();
+
+    private List<String> child_groups = new ArrayList<>();
+}

+ 41 - 0
laser/src/main/java/com/fdkankan/indoor/core/vo/UserVo.java

@@ -0,0 +1,41 @@
+package com.fdkankan.indoor.core.vo;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by owen on 2021/7/19 0019 15:57
+ *
+ * 部分数据先写死
+ */
+@Data
+public class UserVo {
+
+    private Integer id;
+
+    @ApiModelProperty(value = "用户名")
+    private String username;
+
+    private Boolean locked = false;
+
+    private String provider = "LOCAL";
+
+    private String first_name;
+
+    private String last_name;
+
+    private String email;
+
+    private AttributesVo attributes;
+
+    private List<Integer> groups = Arrays.asList(0,1,2,3);
+
+    private List<Integer> primary_groups = Arrays.asList(0,1);
+
+    private Integer default_group_read = 0;
+    private Integer default_group_write = 1;
+}

+ 21 - 0
laser/src/main/java/com/fdkankan/indoor/test/Demo.java

@@ -0,0 +1,21 @@
+package com.fdkankan.indoor.test;
+
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.fastjson.JSONArray;
+import org.junit.Test;
+
+/**
+ * Created by owen on 2021/7/15 0015 15:50
+ */
+public class Demo {
+
+
+    @Test
+    public void editFilter(){
+        String path = "F:\\test\\age\\filter.json";
+        String s = FileUtil.readUtf8String(path);
+
+        JSONArray array = JSONArray.parseArray(s);
+        System.out.println(s);
+    }
+}

+ 16 - 0
laser/src/main/resources/application-dev.properties

@@ -0,0 +1,16 @@
+spring.data.mongodb.uri=mongodb://192.168.0.47:27017/json_data
+spring.data.mongodb.username=4dage
+spring.data.mongodb.password=1234
+
+
+# 控制台sql日志输出
+logging.level.org.springframework.data.mongodb.core= DEBUG
+
+logging.file.path=D:/logs/java/indoor/
+
+
+# swagger2 设置全局字体格式为utf-8
+swagger.package=com.fdkankan.indoor.core.controller
+swagger.title=${project.sc}-dev
+swagger.description=${swagger.title}
+swagger.version=1.0

+ 13 - 0
laser/src/main/resources/application-test.properties

@@ -0,0 +1,13 @@
+spring.data.mongodb.uri=mongodb://221.4.210.172:27017/json_data
+spring.data.mongodb.username=4dage
+spring.data.mongodb.password=1234
+
+# \uFFFD\uFFFD\uFFFD\uFFFD\u0328sql\uFFFD\uFFFD\u05BE\uFFFD\uFFFD\uFFFD
+logging.level.org.springframework.data.mongodb.core= DEBUG
+
+logging.file.path=/root/user/java/indoor/
+
+swagger.package=com.fdkankan.indoor.core.controller
+swagger.title=${project.sc}-sit
+swagger.description=${swagger.title}
+swagger.version=1.0

+ 13 - 0
laser/src/main/resources/application.properties

@@ -0,0 +1,13 @@
+server.port=9294
+
+spring.profiles.active=dev
+
+#server.servlet.context-path=/indoor
+
+#log
+logging.config=classpath:logback-spring.xml
+logging.level.com.fdkankan=info
+
+# \uFFFD\uFFFD\u013F\uFFFD\uFFFD\uFFFD\uFFFD
+project.en=age_camera_germany
+project.sc=\u5FB7\u56FD\u8F6C\u53F0\u76F8\u673A

+ 8 - 0
laser/src/main/resources/data/base.json

@@ -0,0 +1,8 @@
+{
+  "_id": 1,
+  "sceneCode": "test2",
+  "data": [
+
+
+  ]
+}

+ 156 - 0
laser/src/main/resources/logback-spring.xml

@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <property name="LOG_MAX_HISTORY" value="180"/>
+    <springProperty scope="context" name="LOG_PATH" source="logging.file.path"/>
+
+    <!-- 控制台输出 -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+            <pattern>${LOG_PATH}/%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+    </appender>
+    <!-- 按照每天生成日志文件:主项目日志 -->
+    <appender name="file.all" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 追加日志到原文件结尾 -->
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 -->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}.%i.log</FileNamePattern>
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{500} - %msg%n</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+    </appender>
+
+    <!--info日志统一输出到这里-->
+    <appender name="file.info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 每小时生成日志文件 -->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/info/console-info.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+        <!-- 此日志文件只记录info级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--错误日志统一输出到这里-->
+    <appender name="file.error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名-->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/error/console-error.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <!--日志文件保留天数-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+        <!-- 此日志文件只记录error级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--warn日志统一输出到这里-->
+    <appender name="file.warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 按小时生成日志-->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/warn/console-warn.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <!--日志文件保留天数-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+        <!-- 此日志文件只记录warn级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>WARN</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--debug级别日志统一输出到这里-->
+    <appender name="file.debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 按小时生成日志-->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/debug/console-debug.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <!--日志文件保留天数-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <!-- 除按日志记录之外,还配置了日志文件不能超过5M,若超过5M,日志文件会以索引0开始,命名日志文件,例如console-debug.2018-08-24-09.1.log -->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+        <!-- 此日志文件只记录debug级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>DEBUG</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY </onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
+    <appender name="file.async" class="ch.qos.logback.classic.AsyncAppender">
+        <discardingThreshold>0</discardingThreshold>
+        <queueSize>256</queueSize>
+        <includeCallerData>true</includeCallerData>
+        <appender-ref ref="file.all" />
+    </appender>
+
+    <!--  日志输出级别 -->
+    <!-- TRACE\DEBUG\INFO\WARN\ERROR\FATAL\OFF -->
+    <root level="INFO">
+        <appender-ref ref="console" />
+        <appender-ref ref="file.async"/>
+        <appender-ref ref="file.error" />
+        <appender-ref ref="file.info" />
+        <appender-ref ref="file.debug" />
+        <appender-ref ref="file.warn" />
+    </root>
+
+</configuration>

+ 42 - 0
laser/src/test/java/com/fdkankan/indoor/core/MongoTest.java

@@ -0,0 +1,42 @@
+package com.fdkankan.indoor.core;
+
+import com.fdkankan.indoor.core.entity.jsonData.JsonData;
+import com.fdkankan.indoor.core.entity.siteModel.SiteModel;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class MongoTest {
+
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    @Test
+    public void queryJsonData() {
+        JsonData s = mongoTemplate.findAll(JsonData.class).get(0);
+        System.out.println(s);
+//        if (userList != null && userList.size() > 0) {
+//            userList.forEach(user -> {
+//                System.out.println(user.toString());
+//            });
+//        }
+    }
+
+    @Test
+    public void querySiteModel() {
+        List<SiteModel> userList = mongoTemplate.findAll(SiteModel.class);
+        if (userList != null && userList.size() > 0) {
+            userList.forEach(user -> {
+                System.out.println(user.toString());
+            });
+        }
+    }
+
+}