yucheng hace 3 años
padre
commit
915a8c223a
Se han modificado 100 ficheros con 8742 adiciones y 0 borrados
  1. 14 0
      README.md
  2. 41 0
      build.gradle
  3. 80 0
      labsl/build.gradle
  4. 65 0
      labsl/src/main/kotlin/com/persagy/labsl/LaBSLApp.kt
  5. 17 0
      labsl/src/main/kotlin/com/persagy/labsl/Opts.kt
  6. 127 0
      labsl/src/main/kotlin/com/persagy/labsl/Swagger3Config.kt
  7. 68 0
      labsl/src/main/kotlin/com/persagy/labsl/WebMvcConfg.kt
  8. 37 0
      labsl/src/main/kotlin/com/persagy/labsl/controller/GraphCategoryController.kt
  9. 197 0
      labsl/src/main/kotlin/com/persagy/labsl/controller/GraphController.kt
  10. 76 0
      labsl/src/main/kotlin/com/persagy/labsl/controller/MarkersController.kt
  11. 83 0
      labsl/src/main/kotlin/com/persagy/labsl/controller/NodeController.kt
  12. 76 0
      labsl/src/main/kotlin/com/persagy/labsl/controller/RelationController.kt
  13. 201 0
      labsl/src/main/kotlin/com/persagy/labsl/controller/planar/PlanarGraphController.kt
  14. 38 0
      labsl/src/main/kotlin/com/persagy/labsl/controller/planar/PlanarQbsRuleController.kt
  15. 90 0
      labsl/src/main/kotlin/com/persagy/labsl/controller/planar/QbsFolderController.kt
  16. 46 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/Building.kt
  17. 90 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/Floor.kt
  18. 62 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/ObjExtInfo.kt
  19. 16 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/ObjExtInfoPub.kt
  20. 23 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarElements.kt
  21. 23 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarElementsPub.kt
  22. 128 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarGraph.kt
  23. 126 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarGraphPub.kt
  24. 77 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarMarkers.kt
  25. 20 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarMarkersPub.kt
  26. 58 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarQbsRule.kt
  27. 18 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarQbsRulePub.kt
  28. 96 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarRelation.kt
  29. 15 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarRelationPub.kt
  30. 38 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/QbsFolder.kt
  31. 58 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Anchor.kt
  32. 48 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/AttachObjectIds.kt
  33. 25 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Elements.kt
  34. 115 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Graph.kt
  35. 44 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/GraphCategory.kt
  36. 82 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Markers.kt
  37. 108 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Node.kt
  38. 25 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Pos.kt
  39. 95 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Relation.kt
  40. 21 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Size.kt
  41. 19 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/auxiliary/CategoryCode.kt
  42. 33 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pic/Picture.kt
  43. 16 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/AnchorPub.kt
  44. 49 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/AttachObjectIdsPub.kt
  45. 24 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/ElementsPub.kt
  46. 115 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/GraphPub.kt
  47. 16 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/MarkersPub.kt
  48. 112 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/NodePub.kt
  49. 16 0
      labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/RelationPub.kt
  50. 17 0
      labsl/src/main/kotlin/com/persagy/labsl/models/request/GraphCategoryRequest.kt
  51. 32 0
      labsl/src/main/kotlin/com/persagy/labsl/models/response/SCommonResponse.kt
  52. 12 0
      labsl/src/main/kotlin/com/persagy/labsl/services/AnchorService.kt
  53. 13 0
      labsl/src/main/kotlin/com/persagy/labsl/services/AttachObjectIdsServices.kt
  54. 61 0
      labsl/src/main/kotlin/com/persagy/labsl/services/CustomService.kt
  55. 221 0
      labsl/src/main/kotlin/com/persagy/labsl/services/GraphCategoryService.kt
  56. 1246 0
      labsl/src/main/kotlin/com/persagy/labsl/services/GraphService.kt
  57. 123 0
      labsl/src/main/kotlin/com/persagy/labsl/services/MarkersService.kt
  58. 136 0
      labsl/src/main/kotlin/com/persagy/labsl/services/NodeService.kt
  59. 138 0
      labsl/src/main/kotlin/com/persagy/labsl/services/RelationService.kt
  60. 34 0
      labsl/src/main/kotlin/com/persagy/labsl/services/mappers/CustomMapper.kt
  61. 1311 0
      labsl/src/main/kotlin/com/persagy/labsl/services/planar/PlanarGraphService.kt
  62. 27 0
      labsl/src/main/kotlin/com/persagy/labsl/services/planar/PlanarQbsRuleService.kt
  63. 136 0
      labsl/src/main/kotlin/com/persagy/labsl/services/planar/QbsFolderService.kt
  64. 12 0
      labsl/src/main/kotlin/com/persagy/labsl/services/pub/AnchorPubService.kt
  65. 14 0
      labsl/src/main/kotlin/com/persagy/labsl/services/pub/GraphPubService.kt
  66. 236 0
      labsl/src/main/kotlin/com/persagy/labsl/utils/IdUtils.kt
  67. 20 0
      labsl/src/main/resources/application-dev.yml
  68. 33 0
      labsl/src/main/resources/application-prod.yml
  69. 34 0
      labsl/src/main/resources/application-prod2.yml
  70. 12 0
      labsl/src/main/resources/application-test.yml
  71. 71 0
      labsl/src/main/resources/application.yml
  72. 38 0
      labsl/src/main/resources/logback-spring.xml
  73. 106 0
      meiku/build.gradle
  74. 78 0
      meiku/src/main/kotlin/com/persagy/meiku/MeiKuApp.kt
  75. 149 0
      meiku/src/main/kotlin/com/persagy/meiku/Swagger3Config.kt
  76. 68 0
      meiku/src/main/kotlin/com/persagy/meiku/WebMvcConfg.kt
  77. 72 0
      meiku/src/main/kotlin/com/persagy/meiku/controller/MeiKuAnchorController.kt
  78. 86 0
      meiku/src/main/kotlin/com/persagy/meiku/controller/MeiKuController.kt
  79. 73 0
      meiku/src/main/kotlin/com/persagy/meiku/controller/MeiKuStateController.kt
  80. 135 0
      meiku/src/main/kotlin/com/persagy/meiku/controller/PictureController.kt
  81. 76 0
      meiku/src/main/kotlin/com/persagy/meiku/controller/PipelineController.kt
  82. 61 0
      meiku/src/main/kotlin/com/persagy/meiku/controller/UmlController.kt
  83. 50 0
      meiku/src/main/kotlin/com/persagy/meiku/models/entities/MeiKu.kt
  84. 37 0
      meiku/src/main/kotlin/com/persagy/meiku/models/entities/MeiKuAnchor.kt
  85. 41 0
      meiku/src/main/kotlin/com/persagy/meiku/models/entities/MeiKuState.kt
  86. 31 0
      meiku/src/main/kotlin/com/persagy/meiku/models/entities/ObjectCategory.kt
  87. 43 0
      meiku/src/main/kotlin/com/persagy/meiku/models/entities/PipelineCategory.kt
  88. 25 0
      meiku/src/main/kotlin/com/persagy/meiku/models/entities/Pos.kt
  89. 32 0
      meiku/src/main/kotlin/com/persagy/meiku/models/pic/Picture.kt
  90. 31 0
      meiku/src/main/kotlin/com/persagy/meiku/models/response/SCommonResponse.kt
  91. 30 0
      meiku/src/main/kotlin/com/persagy/meiku/services/MeiKuAnchorService.kt
  92. 225 0
      meiku/src/main/kotlin/com/persagy/meiku/services/MeiKuService.kt
  93. 28 0
      meiku/src/main/kotlin/com/persagy/meiku/services/MeiKuStateService.kt
  94. 65 0
      meiku/src/main/kotlin/com/persagy/meiku/services/PipelineCategoryService.kt
  95. 20 0
      meiku/src/main/kotlin/com/persagy/meiku/services/mapper/CustomSql.kt
  96. 31 0
      meiku/src/main/kotlin/com/persagy/meiku/services/pic/PictureService.kt
  97. 21 0
      meiku/src/main/resources/application-dev.yml
  98. 50 0
      meiku/src/main/resources/application-prod.yml
  99. 34 0
      meiku/src/main/resources/application-prod2.yml
  100. 0 0
      meiku/src/main/resources/application-test.yml

+ 14 - 0
README.md

@@ -0,0 +1,14 @@
+# 数字化交付
+
+数字化交付 后台代码框架及服务
+```
+基于20211018开发基线,将PG数据库切换为MySQL。
+因ADM原GIT不提供编辑权限,因此在此新建仓库管理代码。
+```
+
+## 级联说明
+```
+table  对应关系表   idColumn 对应 本类的id    childIdColumn 级联对象的关系id
+@SCascade(table="floor_outline", idColumn="id", childIdColumn="id",self = false)
+注意 idColumn childIdColumn 非数据表中字段名,是实体类属性
+```

+ 41 - 0
build.gradle

@@ -0,0 +1,41 @@
+group 'com.persagy.server'
+version '2.0.10'
+
+buildscript {
+    repositories {
+        maven{url MAVEN_REPO_PUBLIC_URL}
+        maven{ url "http://maven.aliyun.com/nexus/content/groups/public/"}
+        mavenCentral()
+        jcenter()
+    }
+    dependencies {
+        classpath group: 'org.springframework.boot', name: 'spring-boot-gradle-plugin', version: SPRING_BOOT_VERSION
+        classpath group: 'org.jetbrains.kotlin', name: 'kotlin-gradle-plugin', version: KOTLIN_VERSION
+        classpath group: 'org.jetbrains.dokka', name: 'dokka-gradle-plugin', version: DOKKA_VERSION
+        classpath group: 'com.google.protobuf', name: 'protobuf-gradle-plugin', version: PROTOBUF_GRADLE_VERSION
+        // ssh插件, 用于部署
+        classpath 'org.hidetake:gradle-ssh-plugin:2.10.1'
+    }
+}
+
+allprojects {
+    repositories {
+        maven{ url "http://maven.aliyun.com/nexus/content/groups/public/"}
+        maven{
+            url MAVEN_REPO_PUBLIC_URL
+            credentials {
+                username = NEXUS_USERNAME
+                password = NEXUS_PASSWORD
+            }
+        }
+        maven { url "https://repo.spring.io/milestone" }
+        mavenCentral()
+        jcenter()
+    }
+    tasks.withType(Javadoc) {
+        options{ encoding "UTF-8"
+            charSet "UTF-8"
+            links "http://docs.oracle.com/javase/8/docs/api"
+        }
+    }
+}

+ 80 - 0
labsl/build.gradle

@@ -0,0 +1,80 @@
+group rootProject.group
+version rootProject.version
+
+apply plugin: "kotlin"
+apply plugin: "org.jetbrains.dokka"
+apply plugin: "war"
+apply plugin: 'org.springframework.boot'
+apply plugin: 'io.spring.dependency-management'
+
+sourceCompatibility = JVM_TARGET
+
+compileKotlin {
+    kotlinOptions.jvmTarget = JVM_TARGET
+}
+compileTestKotlin {
+    kotlinOptions.jvmTarget = JVM_TARGET
+}
+
+dependencies {
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // kotlin 依赖
+    compile group: "org.jetbrains.kotlin", name: "kotlin-stdlib-jdk8", version: KOTLIN_VERSION
+    compile group: "org.jetbrains.kotlin", name: "kotlin-reflect", version: KOTLIN_VERSION
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // spring boot 依赖
+    compile group: "org.springframework.boot", name: "spring-boot-starter-web", version: SPRING_BOOT_VERSION
+    compile group: "org.springframework.boot", name: "spring-boot-configuration-processor", version: SPRING_BOOT_VERSION
+    compile group: "org.springframework.boot", name: "spring-boot-starter-actuator", version: SPRING_BOOT_VERSION
+    compile group: "org.springframework.boot", name: "spring-boot-starter-logging", version: SPRING_BOOT_VERSION
+    //消息
+//    compile group: "org.springframework.boot", name: "spring-boot-starter-activemq", version: SPRING_BOOT_VERSION
+    compile group: "org.springframework.boot", name:"spring-boot-starter-tomcat", version: SPRING_BOOT_VERSION
+    // spring boot 缓存
+    compile group:"org.springframework.boot", name:"spring-boot-starter-cache", version: SPRING_BOOT_VERSION
+    // 单元测试
+    compile group:"org.springframework.boot", name:"spring-boot-starter-test", version: SPRING_BOOT_VERSION
+
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // spring cloud 依赖
+//    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka', version: SPRING_CLOUD_VERSION
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // RESTful API 文档生成工具
+    // https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui
+    compile group: 'org.springdoc', name: 'springdoc-openapi-ui', version: SPRING_DOC_VERSION
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // Sybotan依赖
+
+    compile group: "com.persagy", name: "persagy-kotlin-base", version: PERSAGY_KOTLIN_VERSION
+    compile group: "com.persagy", name: "persagy-kotlin-database", version: PERSAGY_KOTLIN_VERSION
+    compile group: "com.persagy", name: "persagy-kotlin-mybatis", version: PERSAGY_KOTLIN_VERSION
+    compile group: "com.persagy", name: "persagy-kotlin-mysql", version: PERSAGY_KOTLIN_VERSION
+    compile group: "com.persagy", name: "persagy-service-base", version: PERSAGY_SERVICE_VERSION
+    compile group: "com.persagy", name: "persagy-service-mybatis", version: PERSAGY_SERVICE_VERSION
+    compile group: "com.persagy", name: "persagy-service-mysql", version: PERSAGY_SERVICE_VERSION
+
+
+    // TestNG 测试框架
+    compile group: "org.testng", name: "testng", version: TESTNG_VERSION
+    // Log 工具
+    compile group: "org.projectlombok", name: "lombok", version: LOMBOK_VERSION
+
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    //Gson
+    compile 'com.google.code.gson:gson:2.8.0'
+
+
+//    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//    // 二维码与条形码
+//    // https://mvnrepository.com/artifact/com.google.zxing/core
+//    compile group: "com.google.zxing", name: "core", version: ZXING_VERSION
+    
+}

+ 65 - 0
labsl/src/main/kotlin/com/persagy/labsl/LaBSLApp.kt

@@ -0,0 +1,65 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *                     :*$@@%$*:                         ;:                ;;    ;;
+ *                   :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                  :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                  =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                  =@*                                  %!              @ $= % %@=   =%@!      %=
+ *             *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *           %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *         ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *         $@*   ;@@@%=!:                *@*
+ *         =@$    ;;;!=%@@@@=!           =@!
+ *          %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           ;%@@$=$@@%*       *@@@$=%@@%;
+ *              ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+package com.persagy.labsl
+
+import org.mybatis.spring.annotation.MapperScan
+import org.slf4j.LoggerFactory
+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.context.annotation.Bean
+import org.springframework.context.annotation.ComponentScan
+
+/**
+ * 应用配置
+ *
+ * @author  Andy
+ */
+@ComponentScan(basePackages = ["com.persagy"])           // 配置组件扫描路径
+@MapperScan("com.persagy")                       // Mapper组件扫描路径
+@SpringBootApplication
+open class LaBSLApp : SpringBootServletInitializer() {
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(LaBSLApp::class.java)
+    }
+
+    /**
+     * 配置应用
+     *
+     * @param   application     应用构建对象
+     */
+    override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
+        return application.sources(LaBSLApp::class.java)
+    }
+
+}
+
+/**
+ * Web应用入口
+ *
+ * @param   args        命令行参数
+ */
+fun main(args: Array<String>) {
+    SpringApplication.run(LaBSLApp::class.java, *args)
+    return
+}

+ 17 - 0
labsl/src/main/kotlin/com/persagy/labsl/Opts.kt

@@ -0,0 +1,17 @@
+package com.persagy.labsl
+
+import com.persagy.service.SPageContext
+
+/**
+ * 常量池
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/11/16 9:23
+ */
+object Opts {
+
+    /** 项目 id */
+    val projectId: String?
+        get() = SPageContext.getHeader("projectId")
+
+}

+ 127 - 0
labsl/src/main/kotlin/com/persagy/labsl/Swagger3Config.kt

@@ -0,0 +1,127 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *                     :*$@@%$*:                         ;:                ;;    ;;
+ *                   :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                  :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                  =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                  =@*                                  %!              @ $= % %@=   =%@!      %=
+ *             *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *           %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *         ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *         $@*   ;@@@%=!:                *@*
+ *         =@$    ;;;!=%@@@@=!           =@!
+ *          %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           ;%@@$=$@@%*       *@@@$=%@@%;
+ *              ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+package com.persagy.labsl
+
+import io.swagger.v3.oas.annotations.enums.ParameterIn
+import io.swagger.v3.oas.models.Components
+import io.swagger.v3.oas.models.OpenAPI
+import io.swagger.v3.oas.models.Operation
+import io.swagger.v3.oas.models.info.Contact
+import io.swagger.v3.oas.models.info.Info
+import io.swagger.v3.oas.models.info.License
+import io.swagger.v3.oas.models.media.StringSchema
+import io.swagger.v3.oas.models.parameters.Parameter
+import io.swagger.v3.oas.models.security.SecurityScheme
+import org.springdoc.core.GroupedOpenApi
+import org.springdoc.core.customizers.OperationCustomizer
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.context.ApplicationContext
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.method.HandlerMethod
+
+
+/**
+ * RESTful API文档生成器Swagger2配置
+ *
+ * @author  PLX
+ */
+@Configuration
+open class Swagger3Config {
+    /** 注入的 ApplicationContext */
+    @Autowired
+    lateinit var applicationContext: ApplicationContext
+
+    /** 标题 */
+    private val title = "蜡笔森林(系统图) API"
+    /** API 版本号 */
+    private val version = "1.0"
+    /** 请求头对象 */
+    val operationCustomizer = GlobalHeaderOperationCustomizer()
+
+    /**
+     * API 信息
+     */
+    @Bean
+    open fun openApi(): OpenAPI {
+        val contact = Contact().name("张维新").email("zhangweixin@sagacloud.cn")
+        return OpenAPI()
+            .components(
+                Components()
+                .addSecuritySchemes("basicScheme", SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
+            .info(
+                Info()
+                .title(title)
+                .version(version)
+                .termsOfService("http://www.persagy.com")
+                .contact(contact)
+                .license(
+                    License()
+                    .name("Apache 2.0")
+                    .url("http://www.persagy.com")))
+    }
+
+
+    @Bean
+    open fun publicApi(): GroupedOpenApi? {
+        return GroupedOpenApi.builder()
+            .group("默认")
+            .pathsToMatch("/**")
+            .addOperationCustomizer(operationCustomizer)
+            .build()
+    }
+
+    /**
+     * 平面图
+     */
+    @Bean
+    open fun planarApi(): GroupedOpenApi? {
+        return GroupedOpenApi.builder()
+            .group("平面图")
+            .pathsToMatch("/planar/**")
+            .addOperationCustomizer(operationCustomizer)
+            .build()
+    }
+
+
+}
+
+/**
+ * 全局参数
+ *
+ * @author  庞利祥 <sybotan@126.com>
+ */
+class GlobalHeaderOperationCustomizer : OperationCustomizer {
+    /**
+     * 接口定义器
+     *
+     * @param   operation       接口
+     * @param   handlerMethod   原接口方法
+     * @return  新定义的接口
+     */
+    override fun customize(operation: Operation, handlerMethod: HandlerMethod): Operation {
+        val projectId = Parameter().`in`(ParameterIn.HEADER.toString())
+            .name("projectId").description("项目 id")
+            .schema(StringSchema()).required(false)
+        operation.addParametersItem(projectId)
+        return operation
+    }
+}

+ 68 - 0
labsl/src/main/kotlin/com/persagy/labsl/WebMvcConfg.kt

@@ -0,0 +1,68 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *                     :*$@@%$*:                         ;:                ;;    ;;
+ *                   :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                  :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                  =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                  =@*                                  %!              @ $= % %@=   =%@!      %=
+ *             *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *           %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *         ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *         $@*   ;@@@%=!:                *@*
+ *         =@$    ;;;!=%@@@@=!           =@!
+ *          %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           ;%@@$=$@@%*       *@@@$=%@@%;
+ *              ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+package com.persagy.labsl
+
+import com.alibaba.fastjson.PropertyNamingStrategy
+import com.persagy.service.interceptors.SPageInterceptor
+import com.persagy.service.json.SJsonHttpMessageConverter
+import org.slf4j.LoggerFactory
+import org.springframework.context.annotation.Configuration
+import org.springframework.http.converter.HttpMessageConverter
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
+
+@Configuration
+open class WebMvcConfg: WebMvcConfigurer {
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(WebMvcConfg::class.java)
+    } // Companion object
+
+    /**
+     * 配置拦截器
+     *
+     * @param   registry        拦截器注册器
+     */
+    override fun addInterceptors(registry : InterceptorRegistry) {
+//        registry.addInterceptor(AccessControlAllowOriginInterceptor()).addPathPatterns("/**")
+
+        registry.addInterceptor(SPageInterceptor()).addPathPatterns("/**")
+        super.addInterceptors(registry)
+
+    } // Function addInterceptors()
+
+    /**
+     * 配置 json 转换使用 FastJson
+     *
+     * @param   converterList       转换器列表
+     */
+    override fun configureMessageConverters(converterList: MutableList<HttpMessageConverter<*>>) {
+        // 先把JackSon的消息转换器删除.
+        converterList.removeIf { item -> item is MappingJackson2HttpMessageConverter }
+
+        val converter = SJsonHttpMessageConverter()
+        // 设置 Json 序列化,属性首字母小写
+        converter.propertyNamingStrategy = PropertyNamingStrategy.CamelCase
+        converterList.add(converter)
+    }
+
+} // Class WebMvcConf()

+ 37 - 0
labsl/src/main/kotlin/com/persagy/labsl/controller/GraphCategoryController.kt

@@ -0,0 +1,37 @@
+package com.persagy.labsl.controller
+
+import com.persagy.labsl.models.entities.tpt.GraphCategory
+import com.persagy.labsl.models.request.GraphCategoryRequest
+import com.persagy.labsl.services.GraphCategoryService
+import com.persagy.service.models.responses.SQueryResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * 类型
+ *
+ * @author wx <zhangweixin@sagacloud.com>
+ * @date  2020/9/15 11:40
+ */
+@Tag(name = "005、系统图类型")
+@RestController
+@RequestMapping("/graph-category")
+class GraphCategoryController {
+
+    /**
+     * 查询系统图类型信息
+     *
+     * @param request   查询条件
+     * @return 查询结果
+     */
+   @Operation(summary = "查询系统图类型信息", description = "类型开关 true  获取所有 false 获取已有图形的类型")
+    @PostMapping(value = ["/query"])
+    fun graphCategoryQuery(@RequestBody request: GraphCategoryRequest): SQueryResponse<GraphCategory> {
+        return GraphCategoryService.graphCategoryQuery(request)
+    }
+
+}

+ 197 - 0
labsl/src/main/kotlin/com/persagy/labsl/controller/GraphController.kt

@@ -0,0 +1,197 @@
+package com.persagy.labsl.controller
+
+import com.persagy.database.SFilter
+import com.persagy.labsl.Opts
+import com.persagy.labsl.models.entities.tpt.Graph
+import com.persagy.labsl.models.entities.tpt.pub.GraphPub
+import com.persagy.labsl.models.response.SCommonResponse
+import com.persagy.labsl.services.GraphService
+import com.persagy.labsl.services.pub.GraphPubService
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.requests.SUpdateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import com.persagy.service.models.responses.SQueryResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.*
+
+/**
+ * 图形
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ */
+@Tag(name = "001、系统图")
+@RestController
+@RequestMapping("/graph")
+class GraphController {
+
+    /**
+     * 创建图
+     *
+     * @param request     待图对象列表
+     * @return 创建完成图对象列表
+     */
+   @Operation(summary ="草稿箱-创建图", description = "id和graphId为必填,图中会包含多个节点,详细节点结构见示例")
+    @PostMapping("/drafts/create")
+    fun create(@RequestBody request: SCreateRequest<Graph>): SCreateResponse<Graph> {
+        return GraphService.draftsCreate(request)
+    } // Function create()
+
+    /**
+     * 提交图形
+     *
+     * @param  graph   待图对象
+     * @return  图对象列表
+     */
+   @Operation(summary = "草稿箱-保存图形", description = "")
+    @PostMapping("/drafts/save")
+    fun save(@RequestBody graph: Graph): SCreateResponse<Graph> {
+        return GraphService.save(graph)
+    } // Function save()
+
+    /**
+     * 发布图形
+     *
+     * @param graph     待发布的图对象
+     * @return 发布结果
+     */
+   @Operation(summary="草稿箱-发布图形", description =" Id 和 GraphId 必须填写")
+    @PostMapping("/drafts/publish")
+    fun pubDrawings(@RequestBody graph: GraphPub): SCreateResponse<GraphPub>{
+        return GraphService.pubDrawings(graph)
+    } // Function pubDrawings()
+
+
+    /**
+     * 图、移至或移出回收站
+     *
+     * @param idList    图例列表
+     * @return 移出结果
+     */
+   @Operation(summary = "草稿箱-移至回收站", description = " Id 和 GraphId 必填")
+    @PostMapping(value = ["/drafts/recycle"])
+    fun recycle(@RequestBody idList: ArrayList<Graph>): SBaseResponse {
+        return GraphService.recycle(idList)
+    } // Function recycle()
+
+    /**
+     * 已发布图形移至回收站
+     *
+     * @param idList    图列表
+     * @return 移出结果
+     */
+   @Operation(summary = "已发布-图形移至回收站", description = "Id 和 GraphId 必填")
+    @PostMapping(value = ["/pub/recycle"])
+    fun recyclePub(@RequestBody idList: ArrayList<Graph>): SBaseResponse{
+        return GraphService.recyclePub(idList)
+    } // Function recyclePub()
+
+    /**
+     * 更新图形信息
+     *
+     * @param request   更新的内容对象
+     * @return 更新的结果
+     */
+   @Operation(summary = "草稿箱-更新图形信息", description = "Id 和 GraphId 必填")
+    @PostMapping(value = ["/drafts/update"])
+    fun update(@RequestBody request: SUpdateRequest<Graph>): SBaseResponse {
+        return GraphService.draftsUpdate(request)
+    } // Function update()
+
+    /**
+     * 查询图形信息
+     *
+     * @param  request  查询条件
+     * @return 查询结果
+     */
+   @Operation(summary = "草稿箱-查询图形信息", description = "state 1(草稿箱),state 4(回收站) ,Id 和 GraphId 必填")
+    @PostMapping(value = ["/drafts/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<Graph> {
+        return GraphService.pageQuery(request, arrayListOf(SFilter.eq("projectId",Opts.projectId!!)))
+    } // Function query()
+
+    /**
+     * 草稿箱 - 读取图形所有节点
+     *
+     * @param graph  图例对象
+     * @return 查询结果
+     */
+   @Operation(summary = "草稿箱-查询图形以及所有节点信息", description = "Id 和 GraphId 必填")
+    @PostMapping(value = ["/drafts/read"])
+    fun readDrafts(@RequestBody graph: Graph): SCommonResponse<Graph> {
+        return GraphService.readDrafts(graph)
+    } // Fun readDrafts()
+
+    /**
+     * 已发布 - 读取图形所有节点
+     *
+     * @param graph  图例对象】
+     * @return 查询结果
+     */
+   @Operation(summary = "已发布-查询图形以及所有节点信息", description = "Id 和 GraphId 必填")
+    @PostMapping(value = ["/pub/read"])
+    fun readPub(@RequestBody graph: GraphPub): SCommonResponse<GraphPub> {
+        return GraphService.readPub(graph)
+    } // Fun readPub()
+
+    /**
+     * 已发布图形查询
+     *
+     * @param request  查询条件
+     * @return 查询结果
+     */
+   @Operation(summary = "已发布-查询图形信息", description = "Id 和 GraphId 必填")
+    @PostMapping(value = ["/pub/query"])
+    fun querPub(@RequestBody request: SQueryRequest): SQueryResponse<GraphPub> {
+        return GraphPubService.pageQuery(request, arrayListOf(SFilter.eq("projectId",Opts.projectId!!)))
+    } // Function querPub()
+
+    /**
+     * 更新图形信息
+     *
+     * @param request  更新的内容对象
+     * @return 更新的结果
+     */
+   @Operation(summary = "已发布-更新图形信息", description = "")
+    @PostMapping(value = ["/pub/update"])
+    fun updatePub(@RequestBody request: SUpdateRequest<GraphPub>): SBaseResponse {
+        return GraphService.pubUpdate(request)
+    } // Function update()
+
+    /**
+     * 回收站- 恢复图形
+     *
+     * @param graph  图对象
+     * @return 恢复结果
+     */
+   @Operation(summary = "回收站- 恢复图形", description = "Id 和 GraphId 必填 ")
+    @PostMapping(value = ["recycle/recovery"])
+    fun recovery(@RequestBody graph: Graph): SBaseResponse{
+    return GraphService.recovery(graph)
+    } // Fun recovery()
+
+    /**
+     * 根据id删除图形
+     *
+     * @param idList      图对象数组
+     * @return 删除的结果信息
+     */
+   @Operation(summary = "回收站-根据id删除图形信息,删除草稿箱图形", description = "Id 和 GraphId 必填 ")
+    @PostMapping(value = ["recycle/delete"])
+    fun delete(@RequestBody idList: ArrayList<Graph>): SBaseResponse {
+        return GraphService.deleteByKeysList(idList)
+    } // Function delete()
+
+
+//    /**
+//     * 根据标签查询已发布图形
+//     */
+//    @Operation(summary = "已发布-根据标签查询已发布图形", description = "")
+//    @PostMapping(value = ["/pub/label"])
+//    fun labelPub(@RequestParam label: String): SQueryResponse<GraphPub>{
+//        return GraphService.containLabelPub(label)
+//    }
+
+} // Class GraphController

+ 76 - 0
labsl/src/main/kotlin/com/persagy/labsl/controller/MarkersController.kt

@@ -0,0 +1,76 @@
+package com.persagy.labsl.controller
+
+import com.persagy.labsl.models.entities.tpt.Markers
+import com.persagy.labsl.services.MarkersService
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.requests.SUpdateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import com.persagy.service.models.responses.SQueryResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * 文本注释,图上的图片说明
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ */
+@Tag(name = "003、系统图内标识信息,文本注释,图上的图片说明- 系统图下子对象")
+@RestController
+@RequestMapping("/marker")
+class MarkersController {
+
+    /**
+     * 注释说明
+     *
+     * @param request   待创建注释说明对象列表
+     * @return  创建完成注释说明对象列表
+     */
+   @Operation(summary="注释说明创建", description ="id 为系统图的图对象id,graphId 为系统图的图 id ,markerId 为当前标识的id,id 和 graphId 必须填为某一个系统图中的 id,markerId 是当前要创建的对象id不传会自动生成(32位uuid)")
+    @PostMapping("/create")
+    fun create(@RequestBody request: SCreateRequest<Markers>): SCreateResponse<Markers> {
+        return MarkersService.creates(request)
+    }
+
+    /**
+     * 根据id删除图注释说明
+     *
+     * @param idList    id数组
+     * @return  删除的结果信息
+     */
+   @Operation(summary = "根据批量删除标识信息对象", description = "创建中有介绍id的说明请查看,删除时必须传入 id、graphId、markerId 才能确认删除的是当前的标识对象")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<Markers>): SBaseResponse {
+        return MarkersService.deletes(idList)
+    }
+
+    /**
+     * 更新注释说明信息
+     *
+     * @param request   更新的内容对象
+     * @return 更新的结果
+     */
+   @Operation(summary = "批量更新标识信息", description = "创建中有介绍id的说明请查看,id、graphId、markerId 为必填信息点,参考创建后的对象信息点,修改哪个信息点直接写在对象里面即可,详细的使用方式参考 web 端接口使用规范")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<Markers>): SBaseResponse {
+        return MarkersService.updateList(request)
+    }
+
+    /**
+     * 查询注释说明信息
+     *
+     * @param request   查询条件
+     * @return 查询结果
+     */
+   @Operation(summary = "查询标识信息", description = "创建中有介绍id的说明请查看,注意 id、graphId、markerId 的区别,示例 查询某一个标识信息:filters = id ='值';graphId='值';markerId='值'    (其他的组合方式详见后端开发文档 web 端接口使用规范)")
+    @PostMapping(value = ["/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<Markers> {
+        return MarkersService.pageQuery(request)
+    }
+
+}

+ 83 - 0
labsl/src/main/kotlin/com/persagy/labsl/controller/NodeController.kt

@@ -0,0 +1,83 @@
+package com.persagy.labsl.controller
+
+import com.persagy.labsl.models.entities.tpt.Node
+import com.persagy.labsl.services.NodeService
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.requests.SUpdateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import com.persagy.service.models.responses.SQueryResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.slf4j.LoggerFactory
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * 图例节点
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ */
+@Tag(name = "002、系统图设备节点,与数据中台设备实例对应关系(绑定信息点在该设备上进行)- 系统图下子对象")
+@RestController
+@RequestMapping("/node")
+class NodeController {
+    companion object {
+        /** 日志 */
+        private val logger = LoggerFactory.getLogger(NodeController::class.java)
+
+
+    } // Companion object
+
+    /**
+     * 图例节点
+     *
+     * @param request   待创建图对象列表
+     * @return  创建完成图例节点对象列表
+     */
+   @Operation(summary="创建设备节点", description ="id 为系统图的图对象id,graphId 为系统图的图id ,nodeId 为当前节点的id,id 和 graphId 必须填为某一个系统图中的 id,nodeId 是当前要创建的对象id不传会自动生成(32位uuid)")
+    @PostMapping("/create")
+    fun create(@RequestBody request: SCreateRequest<Node>): SCreateResponse<Node> {
+        return NodeService.creates(request)
+    } // Function create()
+
+    /**
+     * 根据id删除图例节点
+     *
+     * @param idList  id数组
+     * @return 删除的结果信息
+     */
+   @Operation(summary = "根据id删除图例节点信息", description = "创建中有介绍id的说明请查看,删除时必须传入 id、graphId、nodeId 才能确认删除的是当前的设备节点")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<Node>): SBaseResponse {
+        return NodeService.deletes(idList)
+    } // Function delete()
+
+    /**
+     * 更新图例节点信息
+     *
+     * @param  request   更新的内容对象
+     * @return 更新的结果
+     */
+   @Operation(summary = "更新图例节点信息", description = "创建中有介绍 id 的说明请查看,id、graphId、nodeId 为必填信息点,参考创建后的对象信息点,然后修改了哪个信息点传哪个信息点,详细的使用方式参考 web 端接口使用规范")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<Node>): SBaseResponse {
+        return NodeService.updateList(request)
+    } // Function update()
+
+    /**
+     * 查询图例节点信息
+     *
+     * @param  request 查询条件
+     * @return 查询结果
+     */
+   @Operation(summary = "查询图例节点信息", description = "创建中有介绍 id 的说明请查看,注意 id、graphId、nodeId 的区别,示例 查询某一个对象:filters = id ='值';graphId='值';nodeId='值' (其他的组合方式详见后端开发文档 web 端接口使用规范)")
+    @PostMapping(value = ["/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<Node> {
+        return NodeService.pageQuery(request)
+    } // Function query()
+
+} // Class NodeController

+ 76 - 0
labsl/src/main/kotlin/com/persagy/labsl/controller/RelationController.kt

@@ -0,0 +1,76 @@
+package com.persagy.labsl.controller
+
+import com.persagy.labsl.models.entities.tpt.Relation
+import com.persagy.labsl.services.RelationService
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.requests.SUpdateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import com.persagy.service.models.responses.SQueryResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * 管线对象
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ */
+@Tag(name = "004、系统图管线信息(对应中台中的关系)- 系统图下子对象")
+@RestController
+@RequestMapping("/relation")
+class RelationController {
+
+    /**
+     * 管线创建
+     *
+     * @param request    待创建管线对象列表
+     * @return  创建完成图例节点对象列表
+     */
+   @Operation(summary="管线创建", description ="id 为系统图的图对象id,graphId 为系统图的图id ,relationId 为当前管线对象的id,id 和 graphId 必须填为某一个系统图中的id,relationId 是当前要创建的对象 id 不传会自动生成(32位uuid)")
+    @PostMapping("/create")
+    fun create(@RequestBody request: SCreateRequest<Relation>): SCreateResponse<Relation> {
+        return RelationService.creates(request)
+    }
+
+    /**
+     * 根据id删除管线
+     *
+     * @param  idList    id数组
+     * @return 删除的结果信息
+     */
+   @Operation(summary = "根据id删除管线信息", description = "创建中有介绍id的说明请查看,删除时必须传入 id、graphId、relationId 才能确认删除的是当前的标识对象")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<Relation>): SBaseResponse {
+        return RelationService.deletes(idList)
+    }
+
+    /**
+     * 更新管线信息
+     *
+     * @param  request   更新的内容对象
+     * @return 更新的结果
+     */
+   @Operation(summary = "更新管线信息", description = "创建中有介绍id的说明请查看,id、graphId、relationId 为必填信息点,参考创建后的对象信息点,修改哪个信息点直接写在对象里面即可,详细的使用方式参考 web 端接口使用规范")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<Relation>): SBaseResponse {
+        return RelationService.updateList(request)
+    }
+
+    /**
+     * 查询管线信息
+     *
+     * @param  request     查询条件
+     * @return  查询结果
+     */
+   @Operation(summary = "查询管线信息", description = "创建中有介绍id的说明请查看,注意 id、graphId、relationId 的区别,示例 查询某一个对象:filters = id ='值';graphId='值';relationId='值' (其他的组合方式详见后端开发文档 web 端接口使用规范)")
+    @PostMapping(value = ["/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<Relation> {
+        return RelationService.pageQuery(request)
+    }
+
+}

+ 201 - 0
labsl/src/main/kotlin/com/persagy/labsl/controller/planar/PlanarGraphController.kt

@@ -0,0 +1,201 @@
+package com.persagy.labsl.controller.planar
+
+import com.persagy.labsl.models.entities.pbs.PlanarGraph
+import com.persagy.labsl.models.entities.pbs.PlanarGraphPub
+import com.persagy.labsl.models.entities.pbs.Building
+import com.persagy.labsl.models.response.SCommonResponse
+import com.persagy.labsl.services.planar.PlanarGraphService
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.requests.SUpdateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import com.persagy.service.models.responses.SQueryResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * 图形
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ */
+@Tag(name = "002、平面图")
+@RestController
+@RequestMapping("/planar/graph")
+class PlanarGraphController {
+
+    /**
+     * 创建平面图
+     *
+     * @param planarGraph     待创建对象列表
+     * @return 创建完成图对象列表
+     */
+    @Operation(summary ="-未发布-单个图形创建", description = "id和graphId为必填,图中会包含多个节点,详细节点结构见示例")
+    @PostMapping("/drafts/create")
+    fun create(@RequestBody planarGraph: PlanarGraph): SCreateResponse<PlanarGraph> {
+        return PlanarGraphService.create(planarGraph)
+    }
+
+    /**
+     * 提交图形
+     *
+     * @param  graph   待图对象
+     * @return  图对象列表
+     */
+   @Operation(summary = "未发布-保存图形", description = "")
+    @PostMapping("/drafts/save")
+    fun save(@RequestBody graph: PlanarGraph): SCreateResponse<PlanarGraph> {
+        return PlanarGraphService.save(graph)
+    } // Function save()
+
+    /**
+     * 发布图形
+     *
+     * @param graph     待发布的图对象
+     * @return 发布结果
+     */
+    @Operation(summary="未发布-发布图形", description =" Id 和 GraphId 必须填写")
+    @PostMapping("/drafts/publish")
+    fun pubDrawings(@RequestBody graph: PlanarGraphPub): SCreateResponse<PlanarGraphPub>{
+        return PlanarGraphService.pubDrawings(graph)
+    }
+
+
+    /**
+     * 图、移至或移出回收站
+     *
+     * @param idList    图例列表
+     * @return 移出结果
+     */
+    @Operation(summary = "未发布-移至回收站", description = " Id 和 GraphId 必填")
+    @PostMapping(value = ["/drafts/recycle"])
+    fun recycle(@RequestBody idList: ArrayList<PlanarGraph>): SBaseResponse {
+        return PlanarGraphService.recycle(idList)
+    }
+
+    /**
+     * 已发布图形移至回收站
+     *
+     * @param idList    图列表
+     * @return 移出结果
+     */
+    @Operation(summary = "已发布-图形移至回收站", description = "Id 和 GraphId 必填")
+    @PostMapping(value = ["/pub/recycle"])
+    fun recyclePub(@RequestBody idList: ArrayList<PlanarGraph>): SBaseResponse{
+        return PlanarGraphService.recyclePub(idList)
+    }
+
+    /**
+     * 更新图形信息
+     *
+     * @param request   更新的内容对象
+     * @return 更新的结果
+     */
+    @Operation(summary = "未发布-更新图形信息", description = "Id 和 GraphId 必填")
+    @PostMapping(value = ["/drafts/update"])
+    fun updates(@RequestBody request: SUpdateRequest<PlanarGraph>): SBaseResponse {
+        return PlanarGraphService.draftsUpdate(request)
+    }
+
+    /**
+     * 查询图形信息    *********************************************************************************************************
+     *
+     * @param  request  查询条件
+     * @return 查询结果
+     */
+    @Operation(summary = "未发布-查询图形信息", description = "state Draft(未发布),state Recyle(回收站) ,Id 和 GraphId 必填")
+    @PostMapping(value = ["/drafts/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<Building> {
+        return PlanarGraphService.pageQuerysDrafts(request)
+    }
+
+    /**
+     * 未发布 - 读取图形所有节点
+     *
+     * @param graph  图例对象
+     * @return 查询结果
+     */
+   @Operation(summary = "未发布-查询图形以及所有节点信息", description = "Id 和 GraphId 必填")
+    @PostMapping(value = ["/drafts/read"])
+    fun readDrafts(@RequestBody graph: PlanarGraph): SCommonResponse<PlanarGraph> {
+        return PlanarGraphService.readDrafts(graph)
+    } // Fun readDrafts()
+
+    /**
+     * 已发布 - 读取图形所有节点
+     *
+     * @param graph  图例对象
+     * @return 查询结果
+     */
+   @Operation(summary = "已发布-查询图形以及所有节点信息", description = "Id 和 GraphId 必填")
+    @PostMapping(value = ["/pub/read"])
+    fun readPub(@RequestBody graph: PlanarGraphPub): SCommonResponse<PlanarGraphPub> {
+        return PlanarGraphService.readPub(graph)
+    } // Fun readPub()
+
+    /**
+     * 已发布图形查询   *****************************************************
+     *
+     * @param request  查询条件
+     * @return 查询结果
+     */
+    @Operation(summary = "已发布-查询图形信息", description = "Id 和 GraphId 必填")
+    @PostMapping(value = ["/pub/query"])
+    fun querPub(@RequestBody request: SQueryRequest): SQueryResponse<Building> {
+        return PlanarGraphService.pageQuerysPub(request)
+    }
+
+    /**
+     * 更新图形信息
+     *
+     * @param request  更新的内容对象
+     * @return 更新的结果
+     */
+    @Operation(summary = "已发布-更新图形信息", description = "")
+    @PostMapping(value = ["/pub/update"])
+    fun updatePub(@RequestBody request: SUpdateRequest<PlanarGraphPub>): SBaseResponse {
+        return PlanarGraphService.pubUpdate(request)
+    }
+
+    /**
+     * 已发布图形查询
+     *
+     * @param request  更新的内容对象
+     * @return 更新的结果
+     */
+    @Operation(summary = "已发布-更新图形信息-根据文件夹或建筑楼层查询图形数据", description = "根据文件夹或建筑楼层查询图形数据")
+    @PostMapping(value = ["/pub/flbd/query"])
+    fun querPubs(@RequestBody request: SQueryRequest): SQueryResponse<PlanarGraphPub> {
+        return PlanarGraphService.planarGraphPubService.pageQuery(request)
+    }
+
+
+
+    /**
+     * 回收站- 恢复图形
+     *
+     * @param graph  图对象
+     * @return 恢复结果
+     */
+   @Operation(summary = "回收站- 恢复图形", description = "Id 和 GraphId 必填 ")
+    @PostMapping(value = ["recycle/recovery"])
+    fun recovery(@RequestBody graph: PlanarGraph): SBaseResponse{
+    return PlanarGraphService.recovery(graph)
+    }
+
+    /**
+     * 根据id删除图形
+     *
+     * @param idList      图对象数组
+     * @return 删除的结果信息
+     */
+    @Operation(summary = "回收站-根据id删除图形信息,删除图形", description = "Id 和 GraphId 必填 ")
+    @PostMapping(value = ["recycle/delete"])
+    fun delete(@RequestBody idList: ArrayList<PlanarGraph>): SBaseResponse {
+        return PlanarGraphService.deleteByKeysList(idList)
+    }
+
+}

+ 38 - 0
labsl/src/main/kotlin/com/persagy/labsl/controller/planar/PlanarQbsRuleController.kt

@@ -0,0 +1,38 @@
+package com.persagy.labsl.controller.planar
+
+import com.persagy.labsl.models.entities.pbs.PlanarQbsRule
+import com.persagy.labsl.services.planar.PlanarQbsRuleService
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.responses.SCreateResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * 规则
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/12/13 9:30
+ */
+@Tag(name = "003、平面图 - 规则")
+@RestController
+@RequestMapping("/planar/rule")
+class PlanarQbsRuleController {
+
+    /**
+     * 创建规则
+     *
+     * @param request     待创建对象列表
+     * @return 创建完成规则对象列表
+     */
+    @Operation(summary ="创建规则", description = "id和graphId为必填,图中会包含多个节点,详细节点结构见示例")
+    @PostMapping("/create")
+    fun create(@RequestBody request: SCreateRequest<PlanarQbsRule>): SCreateResponse<PlanarQbsRule> {
+        return PlanarQbsRuleService.createList(request)
+    }
+
+
+}

+ 90 - 0
labsl/src/main/kotlin/com/persagy/labsl/controller/planar/QbsFolderController.kt

@@ -0,0 +1,90 @@
+package com.persagy.labsl.controller.planar
+
+import com.persagy.database.SFilter
+import com.persagy.labsl.Opts
+import com.persagy.labsl.models.entities.pbs.QbsFolder
+import com.persagy.labsl.services.planar.QbsFolderService
+import com.persagy.service.models.requests.SCountRequest
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.requests.SUpdateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCountResponse
+import com.persagy.service.models.responses.SCreateResponse
+import com.persagy.service.models.responses.SQueryResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * 平面图 - 文件夹
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/12/1 15:32
+ */
+@Tag(name = "001、文件夹")
+@RestController
+@RequestMapping("/planar/folder")
+class QbsFolderController {
+
+    /**
+     * 创建文件夹
+     *
+     * @param request    对象列表
+     * @return 创建完成对象列表
+     */
+    @Operation(summary ="创建文件夹", description = "name 不可以为空,不可以与已存在文件夹名称重复")
+    @PostMapping("/create")
+    fun create(@RequestBody request: SCreateRequest<QbsFolder>): SCreateResponse<QbsFolder> {
+        return QbsFolderService.creates(request)
+    }
+
+    /**
+     * 根据id删除文件夹
+     *
+     * @param idList   文件夹对象数组
+     * @return 删除的结果信息
+     */
+    @Operation(summary = "根据id删除文件夹", description = "id  必填 ")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<QbsFolder>): SBaseResponse {
+        return QbsFolderService.deletes(idList)
+    }
+
+    /**
+     * 更新信息
+     *
+     * @param request   更新的内容对象
+     * @return 更新的结果
+     */
+    @Operation(summary = "更新文件夹信息", description = "id 必填")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<QbsFolder>): SBaseResponse {
+        return QbsFolderService.updates(request)
+    }
+
+    /**
+     * 文件夹查询
+     *
+     * @param request  查询条件
+     * @return 查询结果
+     */
+    @Operation(summary = "文件夹查询", description = "")
+    @PostMapping(value = ["/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<QbsFolder> {
+        return QbsFolderService.pageQuery(request, arrayListOf(SFilter.eq("projectId", Opts.projectId!!)))
+    }
+
+    /**
+     * 根据条件查询统计数量
+     */
+    @Operation(summary = "根据条件查询统计数量", description = "")
+    @PostMapping(value = ["/count"])
+    fun count(@RequestBody request: SCountRequest): SCountResponse {
+        return QbsFolderService.count(request,arrayListOf(SFilter.eq("projectId", Opts.projectId!!)))
+    }
+
+}

+ 46 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/Building.kt

@@ -0,0 +1,46 @@
+package com.persagy.labsl.models.entities.pbs
+
+import io.swagger.v3.oas.annotations.media.Schema
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/12/2 19:08
+ */
+@Schema(description = "建筑信息实体类")
+@Table(name = "public.building")
+class Building {
+
+    /** 建筑体ID */
+    @Schema(description = "建筑体ID")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 建筑体名称 */
+    @Schema(description = "建筑体名称")
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 建筑本地编码 */
+    @Schema(description = "建筑本地编码")
+    @Column(name = "local_id")
+    var localId: String? = null
+
+    /** 建筑本地名称 */
+    @Schema(description = "建筑本地名称")
+    @Column(name = "local_name")
+    var localName: String? = null
+
+    /** 项目id */
+    @Schema(description = "项目id")
+    @Column(name = "project_id")
+    var projectId: String? = null
+
+    @Schema(description = "楼层列表")
+    var floorList: ArrayList<Floor>? = null
+
+}

+ 90 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/Floor.kt

@@ -0,0 +1,90 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+package com.persagy.labsl.models.entities.pbs
+
+import com.persagy.labsl.models.entities.pbs.PlanarGraph
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 楼层信息实体类
+ *
+ * @author  张维新
+ */
+@Schema(name = "楼层信息实体类")
+@Table(name = "floor")
+open class Floor : Serializable {
+
+    /** 楼层ID */
+    @Schema(description = "楼层ID")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 楼层名称 */
+    @Schema(description = "楼层名称")
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 楼层本地编码 */
+    @Schema(description = "楼层本地编码")
+    @Column(name = "local_id")
+    var localId: String? = null
+
+    /** 楼层本地名称 */
+    @Schema(description = "楼层本地名称")
+    @Column(name = "local_name")
+    var localName: String? = null
+
+    /** 项目id */
+    @Schema(description = "项目id")
+    @Column(name = "project_id")
+    var projectId: String? = null
+
+    /** 建筑id */
+    @Schema(description = "建筑id")
+    @Column(name = "building_id")
+    var buildingId: String? = null
+
+    /** 楼层顺序码 */
+    @Schema(description = "楼层顺序码")
+    @Column(name = "sequence_id")
+    var floorSequenceId: Int? = null
+
+    /** 信息点 */
+    @Schema(description = "信息点")
+    @Column(name = "infos")
+    var infos: HashMap<String,Any?>? = null
+
+
+    @Schema(description = "草稿图列表")
+    var planarGraphList: ArrayList<Any?>? = null
+
+}

+ 62 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/ObjExtInfo.kt

@@ -0,0 +1,62 @@
+package com.persagy.labsl.models.entities.pbs
+
+import com.persagy.labsl.models.entities.tpt.Pos
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 对象信息
+ *
+ * @author wx
+ */
+@Schema(description = "对象信息")
+@Table(name = "qibaishi_gallery.qbs_obj_ext_info")
+open class ObjExtInfo : SBaseEntity(), Serializable {
+
+    /** 系统图对象id */
+    @Schema(description = "系统图对象id",required = true )
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 系统图 id */
+    @Schema(description = "系统图 id",required = true)
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 节点id */
+    @Schema(description = "节点id",required = true )
+    @Id
+    @Column(name = "info_id")
+    var ObjExtInfoId: String? = null
+
+    /** 节点名称 */
+    @Schema(description = "图例节点名称",required = true )
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 节点类型(image / zone) */
+    @Schema(description = "节点类型(image / zone)")
+    @Column(name = "type")
+    var type: String? = null
+
+    /** 位置信息 */
+    @Schema(description = "位置信息")
+    @Column(name = "pos")
+    var pos: Pos? = null
+
+    @Schema(description = "应用自定义")
+    @Column(name = "properties")
+    var properties : HashMap<String,Any?>? = null
+
+    @Schema(description = "对象 id 列表 ")
+    @Column(name = "attach_object_ids")
+    var attachObjectIds: ArrayList<String>? = null
+
+
+}

+ 16 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/ObjExtInfoPub.kt

@@ -0,0 +1,16 @@
+package com.persagy.labsl.models.entities.pbs
+
+
+import io.swagger.v3.oas.annotations.media.Schema
+import javax.persistence.Table
+
+/**
+ * 对象信息
+ *
+ * @author wx
+ */
+@Schema(description = "对象信息")
+@Table(name = "qibaishi_gallery.qbs_obj_ext_info_pub")
+open class ObjExtInfoPub : ObjExtInfo() {
+
+}

+ 23 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarElements.kt

@@ -0,0 +1,23 @@
+package com.persagy.labsl.models.entities.pbs
+
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.validation.Valid
+
+/**
+ * 系统图展示所需数据
+ *
+ * @author wx
+ */
+class PlanarElements : Serializable {
+
+    @Schema(description = "图例节点")
+    @Valid
+    var objExtInfo : ArrayList<ObjExtInfo>? = null
+
+    @Schema(description = "文本注释,图上的图片说明")
+    var markers : ArrayList<PlanarMarkers>? = null
+
+    @Schema(description = "管线对象")
+    var relations : ArrayList<PlanarRelation>? = null
+}

+ 23 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarElementsPub.kt

@@ -0,0 +1,23 @@
+package com.persagy.labsl.models.entities.pbs
+
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.validation.Valid
+
+/**
+ * 系统图展示所需数据
+ *
+ * @author wx
+ */
+class PlanarElementsPub : Serializable {
+
+    @Schema(description = "图例节点")
+    @Valid
+    var objExtInfo : ArrayList<ObjExtInfoPub>? = null
+
+    @Schema(description = "文本注释,图上的图片说明")
+    var markers : ArrayList<PlanarMarkersPub>? = null
+
+    @Schema(description = "管线对象")
+    var relations : ArrayList<PlanarRelationPub>? = null
+}

+ 128 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarGraph.kt

@@ -0,0 +1,128 @@
+package com.persagy.labsl.models.entities.pbs
+
+import com.persagy.labsl.models.entities.tpt.Elements
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import java.util.*
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+import javax.validation.constraints.NotNull
+import kotlin.collections.HashMap
+
+/**
+ * 系统图
+ *
+ * @author wx  <zhangweixin@sagacloud.cn>
+ */
+@Schema(description = "平面图")
+@Table(name = "qibaishi_gallery.qbs_graph")
+open class PlanarGraph : SBaseEntity(), Serializable {
+
+    /** 图编码 id */
+    @Schema(description = "图编码 id", required = true)
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 图id */
+    @Schema(description = "图id", required = true)
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 图名称 */
+    @Schema(description = "图名称", required = true)
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 文件夹 id */
+    @Schema(description = "文件夹 id" )
+    @Column(name = "folder_id")
+    var folderId: String? = null
+
+    /** 文件夹名称 */
+    @Schema(description = "文件夹名称" )
+    var folderName: String? = null
+
+    /** 项目 id */
+    @Schema(description = "项目 id",required = true )
+    @Column(name = "project_id")
+    var projectId: String? = null
+
+    /** 建筑 id */
+    @Schema(description = "建筑 id")
+    @Column(name = "building_id")
+    var buildingId: String? = null
+
+    /** 楼层 id */
+    @Schema(description = "楼层 id")
+    @Column(name = "floor_id")
+    var floorId: String? = null
+
+    /** 说明 */
+    @Schema(description = "说明")
+    @Column(name = "note")
+    var note: String? = null
+
+    /** 版本号 */
+    @Schema(description = "版本号")
+    @Column(name = "version")
+    var version: String? = null
+
+    /** 移至回收站时间 */
+    @Schema(description = "移至回收站时间",example = "2020-09-20 08:30:00")
+    @Column(name = "del_time")
+    var delTime: Date? = null
+
+    /** 内部版本号 */
+    @Schema(description = "内部版本号")
+    @Column(name = "tag_version")
+    var tagVersion: Int? = null
+
+    /** 图片Key */
+    @Schema(description = "图片Key")
+    @Column(name = "pic")
+    var pic: String? = null
+
+    /** 图状态(Draft: 未发布, WaitCheck: 待审核, Checked: 审核完成, Recyle: 回收站, Publish: 发布) */
+    @Schema(description = "图状态(Draft: 未发布, WaitCheck: 待审核, Checked: 审核完成, Recyle: 回收站, Publish: 发布)")
+    @Column(name = "state")
+    var state: String? = null
+
+    /** 页面尺寸 */
+    @Schema(description = "页面尺寸")
+    @Column(name = "page_size")
+    var pageSize: HashMap<String,Any?>? = null
+
+    /** 标签 */
+    @Schema(description = "标签")
+    @Column(name = "label")
+    var label: ArrayList<String>? = null
+
+    /** 用户 */
+    @Schema(description = "用户")
+    @Column(name = "user")
+    var user: String? = null
+
+    /** 风格 */
+    @Schema(description = "风格")
+    @Column(name = "style")
+    var style: HashMap<String,Any?>? = null
+
+    /** 隐藏的实例ID( 设备,空间 在物理世界的ID) */
+    @Schema(description = "隐藏的实例ID( 设备,空间 在物理世界的ID)")
+    @Column(name = "hide_list")
+    var hideList: ArrayList<String>? = null
+
+    /** 规则列表 */
+    @Schema(description = "规则列表)")
+    var ruleList: ArrayList<PlanarQbsRule>? = null
+
+    @Schema(description = "系统图展示所需数据")
+    open var elements: PlanarElements? = null
+
+
+
+}

+ 126 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarGraphPub.kt

@@ -0,0 +1,126 @@
+package com.persagy.labsl.models.entities.pbs
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import java.util.*
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+import javax.validation.constraints.NotNull
+import kotlin.collections.HashMap
+
+/**
+ * 平面图,已发布
+ *
+ * @author wx  <zhangweixin@sagacloud.cn>
+ */
+@Schema(description = "平面图 - 已发布")
+@Table(name = "qibaishi_gallery.qbs_graph_pub")
+open class PlanarGraphPub : SBaseEntity(), Serializable {
+
+    /** 图编码 id */
+    @Schema(description = "图编码 id", required = true)
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 图id */
+    @Schema(description = "图id", required = true)
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 图名称 */
+    @Schema(description = "图名称", required = true)
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 文件夹 id */
+    @Schema(description = "文件夹 id" )
+    @Column(name = "folder_id")
+    var folderId: String? = null
+
+    /** 文件夹名称 */
+    @Schema(description = "文件夹名称" )
+    var folderName: String? = null
+
+    /** 项目 id */
+    @Schema(description = "项目 id",required = true )
+    @Column(name = "project_id")
+    var projectId: String? = null
+
+    /** 建筑 id */
+    @Schema(description = "建筑 id")
+    @Column(name = "building_id")
+    var buildingId: String? = null
+
+    /** 楼层 id */
+    @Schema(description = "楼层 id")
+    @Column(name = "floor_id")
+    var floorId: String? = null
+
+    /** 说明 */
+    @Schema(description = "说明")
+    @Column(name = "note")
+    var note: String? = null
+
+    /** 版本号 */
+    @Schema(description = "版本号")
+    @Column(name = "version")
+    var version: String? = null
+
+    /** 移至回收站时间 */
+    @Schema(description = "移至回收站时间",example = "2020-09-20 08:30:00")
+    @Column(name = "del_time")
+    var delTime: Date? = null
+
+    /** 内部版本号 */
+    @Schema(description = "内部版本号")
+    @Column(name = "tag_version")
+    var tagVersion: Int? = null
+
+    /** 图片Key */
+    @Schema(description = "图片Key")
+    @Column(name = "pic")
+    var pic: String? = null
+
+    /** 图状态(Draft: 未发布, WaitCheck: 待审核, Checked: 审核完成, Recyle: 回收站, Publish: 发布) */
+    @Schema(description = "图状态(Draft: 未发布, WaitCheck: 待审核, Checked: 审核完成, Recyle: 回收站, Publish: 发布)")
+    @Column(name = "state")
+    var state: String? = null
+
+    /** 页面尺寸 */
+    @Schema(description = "页面尺寸")
+    @Column(name = "page_size")
+    var pageSize: HashMap<String,Any?>? = null
+
+    /** 标签 */
+    @Schema(description = "标签")
+    @Column(name = "label")
+    var label: ArrayList<String>? = null
+
+    /** 用户 */
+    @Schema(description = "用户")
+    @Column(name = "user")
+    var user: String? = null
+
+    /** 风格 */
+    @Schema(description = "风格")
+    @Column(name = "style")
+    var style: HashMap<String,Any?>? = null
+
+    /** 隐藏的实例ID( 设备,空间 在物理世界的ID) */
+    @Schema(description = "隐藏的实例ID( 设备,空间 在物理世界的ID)")
+    @Column(name = "hide_list")
+    var hideList: ArrayList<String>? = null
+
+    /** 规则列表 */
+    @Schema(description = "规则列表)")
+    var ruleList: ArrayList<PlanarQbsRulePub>? = null
+
+    @Schema(description = "系统图展示所需数据")
+    open var elements: PlanarElementsPub? = null
+
+
+}

+ 77 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarMarkers.kt

@@ -0,0 +1,77 @@
+package com.persagy.labsl.models.entities.pbs
+
+import com.persagy.labsl.models.entities.tpt.Pos
+import com.persagy.labsl.models.entities.tpt.Size
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 文本注释,图上的图片说明
+ *
+ * @author wx
+ */
+@Schema(description = "文本注释,图上的图片说明")
+@Table(name = "qibaishi_gallery.qbs_marker")
+open class PlanarMarkers : SBaseEntity(), Serializable {
+
+    /** 图对象id */
+    @Schema(description = "图对象id" ,required = true)
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 标识id */
+    @Schema(description = "标识id",required = true )
+    @Id
+    @Column(name = "marker_id")
+    var markerId: String? = null
+
+    /** 标识名称 */
+    @Schema(description = "标识名称" ,required = true)
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 图标(Image),线类型(Line),文本(Text) */
+    @Schema(description = "图标(Image),线类型(Line),文本(Text)")
+    @Column(name = "type")
+    var type: String? = null
+
+    /** 位置信息 */
+    @Schema(description = "位置信息")
+    @Column(name = "pos")
+    var pos: Pos? = null
+
+    /** 缩放 */
+    @Schema(description = "缩放")
+    @Column(name = "scale")
+    var scale: Pos? = null
+
+    /** 旋转 */
+    @Schema(description = "旋转")
+    @Column(name = "rotate")
+    var rotate: Pos? = null
+
+    /** 大小 */
+    @Schema(description = "大小")
+    @Column(name = "size")
+    var size: Size? = null
+
+    @Schema(description = "应用自定义")
+    @Column(name = "properties")
+    var properties : HashMap<String,Any?>? = null
+
+    /** 图id */
+    @Schema(description = "图id" ,required = true)
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    @Schema(description = "线的绘图样式")
+    @Column(name = "style")
+    var style : HashMap<String,Any?>? = null
+
+} // Class Markers

+ 20 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarMarkersPub.kt

@@ -0,0 +1,20 @@
+package com.persagy.labsl.models.entities.pbs
+
+import com.persagy.labsl.models.entities.tpt.Pos
+import com.persagy.labsl.models.entities.tpt.Size
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 文本注释,图上的图片说明
+ *
+ * @author wx
+ */
+@Schema(description = "文本注释,图上的图片说明")
+@Table(name = "qibaishi_gallery.qbs_marker_pub")
+open class PlanarMarkersPub : PlanarMarkers() {
+}

+ 58 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarQbsRule.kt

@@ -0,0 +1,58 @@
+package com.persagy.labsl.models.entities.pbs
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 规则
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/12/13 9:20
+ */
+@Schema(description = "规则")
+@Table(name = "qibaishi_gallery.qbs_rule")
+open class PlanarQbsRule : SBaseEntity() {
+
+
+    /** 图对象id */
+    @Schema(description = "图对象id" )
+    @Id
+    @Column(name = "id",unique = false,insertable = false)
+    var id: Long? = null
+
+    /** 图编码 */
+    @Schema(description = "图编码" ,required = true)
+    @Id
+    @Column(name = "graph_coding")
+    var graphCoding: String? = null
+
+    /** 图 id */
+    @Schema(description = "图 id" ,required = true)
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** (equip: 设备, equipGroup: 设备组, zone: 空间) */
+    @Schema(description = "(equip: 设备, equipGroup: 设备组, zone: 空间)" ,required = true)
+    @Column(name = "return_type")
+    var returnType: String? = null
+
+    /** query: 查询, delete: 删除 */
+    @Schema(description = "query: 查询, delete: 删除" ,required = true)
+    @Column(name = "commond")
+    var commond: String? = null
+
+    /** 查询参数 */
+    @Schema(description = "查询参数" ,required = true)
+    @Column(name = "params")
+    var params: HashMap<String,Any?>? = null
+
+    /** 说明 */
+    @Schema(description = "说明" )
+    @Column(name = "note")
+    var note: String? = null
+
+}

+ 18 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarQbsRulePub.kt

@@ -0,0 +1,18 @@
+package com.persagy.labsl.models.entities.pbs
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 规则
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/12/13 9:20
+ */
+@Schema(description = "规则")
+@Table(name = "qibaishi_gallery.qbs_rule_pub")
+class PlanarQbsRulePub : PlanarQbsRule() {
+}

+ 96 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarRelation.kt

@@ -0,0 +1,96 @@
+package com.persagy.labsl.models.entities.pbs
+
+import com.persagy.labsl.models.entities.tpt.Pos
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 管线对象
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ */
+@Schema(description = "管线对象")
+@Table(name = "qibaishi_gallery.qbs_relation")
+open class PlanarRelation : SBaseEntity(), Serializable {
+
+    /** 系统图对象id */
+    @Schema(description = "系统图对象id",required = true )
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 关系id */
+    @Schema(description = "关系id",required = true )
+    @Id
+    @Column(name = "relation_id")
+    var relationId: String? = null
+
+    /** 关系名称 */
+    @Schema(description = "关系名称",required = true)
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 图元id */
+    @Schema(description = "图元id")
+    @Column(name = "graph_element_id")
+    var graphElementId: String? = null
+
+    /** 关联节点1_id */
+    @Schema(description = "关联节点1_id")
+    @Column(name = "node1_id")
+    var node1Id: String? = null
+
+    /** 关联节点2_id */
+    @Schema(description = "关联节点2_id")
+    @Column(name = "node2_id")
+    var node2Id: String? = null
+
+    /** 关联锚点1_id */
+    @Schema(description = "关联锚点1_id")
+    @Column(name = "anchor1_id")
+    var anchor1Id: String? = null
+
+    /** 关联锚点2_id */
+    @Schema(description = "关联锚点2_id")
+    @Column(name = "anchor2_id")
+    var anchor2Id: String? = null
+
+    /** 方向(0:无向,1:节点1到节点2,2:节点2到节点1) */
+    @Schema(description = "方向(0:无向,1:节点1到节点2,2:节点2到节点1)")
+    @Column(name = "dir")
+    var dir: Int? = null
+
+    /** 直线(Line),水平垂直 */
+    @Schema(description = "直线(Line),水平垂直")
+    @Column(name = "line_type")
+    var lineType: String? = null
+
+    /** 线的顶点坐标 */
+    @Schema(description = "线的顶点坐标")
+    @Column(name = "point_list")
+    var pointList: ArrayList<Pos>? = null
+
+    @Schema(description = "线的绘图样式")
+    @Column(name = "style")
+    var style : HashMap<String,Any?>? = null
+
+    @Schema(description = "自定义属性")
+    @Column(name = "properties")
+    var properties : HashMap<String,Any?>? = null
+
+    /** 系统图 id */
+    @Schema(description = "系统图 id",required = true)
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 图状态(1一般,2待审核,3审核完成,0发布) */
+    @Schema(description = "图状态(1一般,2待审核,3审核完成,4回收站 ,0发布)")
+    @Column(name = "state")
+    var state: Int? = 1
+
+}

+ 15 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/PlanarRelationPub.kt

@@ -0,0 +1,15 @@
+package com.persagy.labsl.models.entities.pbs
+
+import io.swagger.v3.oas.annotations.media.Schema
+import javax.persistence.Table
+
+/**
+ * 管线对象
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ */
+@Schema(description = "管线对象")
+@Table(name = "qibaishi_gallery.qbs_relation_pub")
+open class PlanarRelationPub : PlanarRelation() {
+
+}

+ 38 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/pbs/QbsFolder.kt

@@ -0,0 +1,38 @@
+package com.persagy.labsl.models.entities.pbs
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+import javax.validation.constraints.NotNull
+
+/**
+ * 文件夹
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/12/1 15:11
+ */
+@Schema(description = "平面图 - 文件夹")
+@Table(name = "qibaishi_gallery.qbs_folder")
+class QbsFolder: Serializable, SBaseEntity() {
+
+    /** 文件夹 id */
+    @Schema(description = "文件夹 id")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 文件夹名称 */
+    @Schema(description = "文件夹名称")
+    @Column(name = "name")
+    @NotNull(message = "文件夹名称不可以为空")
+    var name: String? = null
+
+    /** 项目 id */
+    @Schema(description = "项目 id")
+    @Column(name = "project_id")
+    var projectId: String? = null
+
+}

+ 58 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Anchor.kt

@@ -0,0 +1,58 @@
+package com.persagy.labsl.models.entities.tpt
+
+import com.persagy.labsl.models.entities.tpt.Pos
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 锚点
+ *
+ * @author wx
+ */
+@Schema(description = "锚点")
+@Table(name = "labsl.anchor")
+open class Anchor : SBaseEntity(), Serializable {
+
+    /** 全局id */
+    @Schema(description = "全局id")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 锚点id */
+    @Schema(description = "锚点id")
+    @Id
+    @Column(name = "anchor_id")
+    var anchorId: String? = null
+
+    /** 图id */
+    @Schema(description = "图id")
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 图例节点 */
+    @Schema(description = "图例节点")
+    @Column(name = "node_id")
+    var nodeId: String? = null
+
+    /** 锚点的坐标 */
+    @Schema(description = "锚点的坐标")
+    @Column(name = "pos")
+    var pos: Pos? = null
+
+    /** 项目id */
+    @Schema(description = "项目id")
+    @Column(name = "project_id")
+    var projectId: String? = null
+
+    /** 图状态(1一般,2待审核,3审核完成,0发布) */
+    @Schema(description = "图状态(1一般,2待审核,3审核完成,4回收站 ,0发布)")
+    @Column(name = "state")
+    var state: Int? = 1
+
+} // Class Anchor

+ 48 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/AttachObjectIds.kt

@@ -0,0 +1,48 @@
+package com.persagy.labsl.models.entities.tpt
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 图例节点与对象的关系
+ *
+ * @author  wx
+ * @date  2020/9/17 16:35
+ */
+@Schema(description = "图例节点与对象的关系")
+@Table(name = "labsl.attach_object_ids")
+class AttachObjectIds : SBaseEntity(), Serializable {
+
+    /** 全局id */
+    @Schema(description = "全局id")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 图例节点id */
+    @Schema(description = "图例节点id",required = true )
+    @Id
+    @Column(name = "node_id")
+    var nodeId: String? = null
+
+    /** 对象id */
+    @Schema(description = "对象id",required = true )
+    @Id
+    @Column(name = "object_id")
+    var objectId: String? = null
+
+    /** 图id */
+    @Schema(description = "图id")
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 图状态(1一般,2待审核,3审核完成,0发布) */
+    @Schema(description = "图状态(1一般,2待审核,3审核完成,4回收站 ,0发布)")
+    @Column(name = "state")
+    var state: Int? = 1
+
+} // Class AttachObjectIds

+ 25 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Elements.kt

@@ -0,0 +1,25 @@
+package com.persagy.labsl.models.entities.tpt
+
+import com.persagy.labsl.models.entities.tpt.Relation
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.validation.Valid
+
+/**
+ * 系统图展示所需数据
+ *
+ * @author wx
+ */
+class Elements : Serializable {
+
+    @Schema(description = "图例节点")
+    @Valid
+    var nodes : ArrayList<Node>? = null
+
+    @Schema(description = "文本注释,图上的图片说明")
+    var markers : ArrayList<Markers>? = null
+
+    @Schema(description = "管线对象")
+    var relations : ArrayList<Relation>? = null
+
+} // Class Elements

+ 115 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Graph.kt

@@ -0,0 +1,115 @@
+package com.persagy.labsl.models.entities.tpt
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import java.util.*
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 系统图
+ *
+ * @author wx  <zhangweixin@sagacloud.cn>
+ */
+@Schema(description = "系统图")
+@Table(name = "labsl.graph")
+open class Graph : SBaseEntity(), Serializable {
+
+    /** 图对象id */
+    @Schema(description = "图对象id", required = true)
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 图id */
+    @Schema(description = "图id", required = true)
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 图名称 */
+    @Schema(description = "图名称", required = true)
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 图分类id */
+    @Schema(description = "图分类id",required = true )
+    @Column(name = "category_id")
+    var categoryId: String? = null
+
+    /** 项目id */
+    @Schema(description = "项目id",required = true )
+    @Column(name = "project_id")
+    var projectId: String? = null
+
+    /** 建筑id */
+    @Schema(description = "建筑id")
+    @Column(name = "building_id")
+    var buildingId: String? = null
+
+    /** 楼层id */
+    @Schema(description = "楼层id")
+    @Column(name = "floor_id")
+    var floorId: String? = null
+
+    /** 说明 */
+    @Schema(description = "说明")
+    @Column(name = "note")
+    var note: String? = null
+
+    /** 背景色 */
+    @Schema(description = "背景色")
+    @Column(name = "view_background")
+    var viewBackground: String? = null
+
+    /** 版本号 */
+    @Schema(description = "版本号")
+    @Column(name = "version")
+    var version: String? = null
+
+    @Schema(description = "系统图展示所需数据")
+    open var elements: Elements? = null
+
+    /** 移至回收站时间 */
+    @Schema(description = "移至回收站时间",example = "2020-09-20 08:30:00")
+    @Column(name = "del_time")
+    var delTime: Date? = null
+
+    /** 是否移至回收站 */
+    @Schema(description = "是否移至回收站 , false 正常,true 以至回收站")
+    @Column(name = "is_available")
+    var isAvailable: Boolean? = false
+
+    /** 内部版本号 */
+    @Schema(description = "内部版本号")
+    @Column(name = "tag_version")
+    var tagVersion: Int? = null
+
+//    /** 内部版本号 */
+//    @Schema(description = "是否发布(true 发布、false 未发布)")
+//    @Column(name = "is_pub")
+//    var isPub: Boolean = false
+
+    /** 图片Key */
+    @Schema(description = "图片Key")
+    @Column(name = "pic")
+    var pic: String? = null
+
+    /** 图状态(1一般,2待审核,3审核完成,0发布) */
+    @Schema(description = "图状态(1一般,2待审核,3审核完成,4回收站 ,0发布)")
+    @Column(name = "state")
+    var state: Int? = 1
+
+    /** 页面尺寸 */
+    @Schema(description = "页面尺寸")
+    @Column(name = "page_size")
+    var pageSize: HashMap<String,Any?>? = null
+
+    /** 标签 */
+    @Schema(description = " 标签 ")
+    @Column(name = "label")
+    var label: ArrayList<String>? = null
+
+} // Class Graph

+ 44 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/GraphCategory.kt

@@ -0,0 +1,44 @@
+package com.persagy.labsl.models.entities.tpt
+
+import com.alibaba.fastjson.annotation.JSONField
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 图分类
+ *
+ * @author  wx
+ * @date  2020/9/15 11:33
+ */
+@Schema(description = "图分类")
+@Table(name = "labsl.graph_category")
+class GraphCategory : SBaseEntity(), Serializable {
+
+    /** 分类编码Code */
+    @Schema(description = "分类编码Code")
+    @Id
+    @Column(name = "id")
+    @JSONField(name = "code")
+    var id: String? = null
+
+    /** 分类名称 */
+    @Schema(description = "分类名称")
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 上级节点 */
+    @Schema(description = "上级节点")
+    @Column(name = "parent_id")
+    var parentId: String? = null
+
+    @Schema(description = "子节点列表")
+    var categoryList: ArrayList<GraphCategory>? = null
+
+    @JSONField(name = "categoryList",serialize = false)
+    var sign: Boolean = false
+
+} //  Class GraphCategory

+ 82 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Markers.kt

@@ -0,0 +1,82 @@
+package com.persagy.labsl.models.entities.tpt
+
+import com.persagy.labsl.models.entities.tpt.Pos
+import com.persagy.labsl.models.entities.tpt.Size
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 文本注释,图上的图片说明
+ *
+ * @author wx
+ */
+@Schema(description = "文本注释,图上的图片说明")
+@Table(name = "labsl.marker")
+open class Markers : SBaseEntity(), Serializable {
+
+    /** 图对象id */
+    @Schema(description = "图对象id" ,required = true)
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 标识id */
+    @Schema(description = "标识id",required = true )
+    @Id
+    @Column(name = "marker_id")
+    var markerId: String? = null
+
+    /** 标识名称 */
+    @Schema(description = "标识名称" ,required = true)
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 图标(Image),线类型(Line),文本(Text) */
+    @Schema(description = "图标(Image),线类型(Line),文本(Text)")
+    @Column(name = "type")
+    var type: String? = null
+
+    /** 位置信息 */
+    @Schema(description = "位置信息")
+    @Column(name = "pos")
+    var pos: Pos? = null
+
+    /** 缩放 */
+    @Schema(description = "缩放")
+    @Column(name = "scale")
+    var scale: Pos? = null
+
+    /** 旋转 */
+    @Schema(description = "旋转")
+    @Column(name = "rotate")
+    var rotate: Pos? = null
+
+    /** 大小 */
+    @Schema(description = "大小")
+    @Column(name = "size")
+    var size: Size? = null
+
+    @Schema(description = "应用自定义")
+    @Column(name = "properties")
+    var properties : HashMap<String,Any?>? = null
+
+    /** 图id */
+    @Schema(description = "图id" ,required = true)
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 图状态(1一般,2待审核,3审核完成,0发布) */
+    @Schema(description = "图状态(1一般,2待审核,3审核完成,4回收站 ,0发布)")
+    @Column(name = "state")
+    var state: Int? = 1
+
+    @Schema(description = "线的绘图样式")
+    @Column(name = "style")
+    var style : HashMap<String,Any?>? = null
+
+} // Class Markers

+ 108 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Node.kt

@@ -0,0 +1,108 @@
+package com.persagy.labsl.models.entities.tpt
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 设备节点
+ *
+ * @author wx
+ */
+@Schema(description = "设备节点")
+@Table(name = "labsl.node")
+open class Node : SBaseEntity(), Serializable {
+
+    /** 系统图对象id */
+    @Schema(description = "系统图对象id",required = true )
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 节点id */
+    @Schema(description = "节点id",required = true )
+    @Id
+    @Column(name = "node_id")
+    var nodeId: String? = null
+
+    /** 节点名称 */
+    @Schema(description = "图例节点名称",required = true )
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 图例类型 None/Line/Zone/Image:非图例/线条/区域类型/图标 */
+    @Schema(description = "图例类型 None/Line/Zone/Image:非图例/线条/区域类型/图标")
+    @Column(name = "graph_element_type")
+    var graphElementType: String? = null
+
+    /** 图元ID */
+    @Schema(description = "图元ID")
+    @Column(name = "graph_element_id")
+    var graphElementId: String? = null
+
+//    /** 图例数量 */
+//    @Schema(description = "图例数量")
+//    @Column(name = "num")
+//    var num: Int? = null
+
+    /** 节点类型(image / zone) */
+    @Schema(description = "节点类型(image / zone)")
+    @Column(name = "type")
+    var type: String? = null
+
+    /** 位置信息 */
+    @Schema(description = "位置信息")
+    @Column(name = "pos")
+    var pos: Pos? = null
+
+    /** 缩放 */
+    @Schema(description = "缩放")
+    @Column(name = "scale")
+    var scale: Pos? = null
+
+    /** 旋转 */
+    @Schema(description = "旋转")
+    @Column(name = "rotate")
+    var rotate: Pos? = null
+
+    /** 大小 */
+    @Schema(description = "大小")
+    @Column(name = "size")
+    var size: Size? = null
+
+    /** 轮廓线 */
+    @Schema(description = "轮廓线")
+    @Column(name = "outline")
+    var outline: ArrayList<ArrayList<Pos>>? = null
+
+    @Schema(description = "应用自定义")
+    @Column(name = "properties")
+    var properties : HashMap<String,Any?>? = null
+
+    /** 系统图 id */
+    @Schema(description = "系统图 id",required = true)
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 锚点列表 */
+    @Schema(description = "锚点列表")
+    var anchorList: ArrayList<Anchor>? = null
+
+    @Schema(description = "对象 id 列表 ")
+    @Column(name = "attach_object_ids")
+    var attachObjectIds: ArrayList<String>? = null
+
+    /** 图状态(1一般,2待审核,3审核完成,0发布) */
+    @Schema(description = "图状态(1一般,2待审核,3审核完成,4回收站 ,0发布)")
+    @Column(name = "state")
+    var state: Int? = 1
+
+    @Schema(description = "线的绘图样式")
+    @Column(name = "style")
+    var style : HashMap<String,Any?>? = null
+
+} // Class node

+ 25 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Pos.kt

@@ -0,0 +1,25 @@
+package com.persagy.labsl.models.entities.tpt
+
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+
+/**
+ * 位置信息
+ *
+ * @author wx
+ */
+class Pos : Serializable {
+
+    /** X坐标 */
+    @Schema(description = "X坐标")
+    var x: Double? = null
+
+    /** Y坐标 */
+    @Schema(description = "Y坐标")
+    var y: Double? = null
+
+    /** Z坐标 */
+    @Schema(description = "Z坐标")
+    var z: Double? = null
+
+} // Class Pos

+ 95 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Relation.kt

@@ -0,0 +1,95 @@
+package com.persagy.labsl.models.entities.tpt
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 管线对象
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ */
+@Schema(description = "管线对象")
+@Table(name = "labsl.relation")
+open class Relation : SBaseEntity(), Serializable {
+
+    /** 系统图对象id */
+    @Schema(description = "系统图对象id",required = true )
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 关系id */
+    @Schema(description = "关系id",required = true )
+    @Id
+    @Column(name = "relation_id")
+    var relationId: String? = null
+
+    /** 关系名称 */
+    @Schema(description = "关系名称",required = true)
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 图元id */
+    @Schema(description = "图元id")
+    @Column(name = "graph_element_id")
+    var graphElementId: String? = null
+
+    /** 关联节点1_id */
+    @Schema(description = "关联节点1_id")
+    @Column(name = "node1_id")
+    var node1Id: String? = null
+
+    /** 关联节点2_id */
+    @Schema(description = "关联节点2_id")
+    @Column(name = "node2_id")
+    var node2Id: String? = null
+
+    /** 关联锚点1_id */
+    @Schema(description = "关联锚点1_id")
+    @Column(name = "anchor1_id")
+    var anchor1Id: String? = null
+
+    /** 关联锚点2_id */
+    @Schema(description = "关联锚点2_id")
+    @Column(name = "anchor2_id")
+    var anchor2Id: String? = null
+
+    /** 方向(0:无向,1:节点1到节点2,2:节点2到节点1) */
+    @Schema(description = "方向(0:无向,1:节点1到节点2,2:节点2到节点1)")
+    @Column(name = "dir")
+    var dir: Int? = null
+
+    /** 直线(Line),水平垂直 */
+    @Schema(description = "直线(Line),水平垂直")
+    @Column(name = "line_type")
+    var lineType: String? = null
+
+    /** 线的顶点坐标 */
+    @Schema(description = "线的顶点坐标")
+    @Column(name = "point_list")
+    var pointList: ArrayList<Pos>? = null
+
+    @Schema(description = "线的绘图样式")
+    @Column(name = "style")
+    var style : HashMap<String,Any?>? = null
+
+    @Schema(description = "自定义属性")
+    @Column(name = "properties")
+    var properties : HashMap<String,Any?>? = null
+
+    /** 系统图 id */
+    @Schema(description = "系统图 id",required = true)
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 图状态(1一般,2待审核,3审核完成,0发布) */
+    @Schema(description = "图状态(1一般,2待审核,3审核完成,4回收站 ,0发布)")
+    @Column(name = "state")
+    var state: Int? = 1
+
+} // Class Relation

+ 21 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/Size.kt

@@ -0,0 +1,21 @@
+package com.persagy.labsl.models.entities.tpt
+
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+
+/**
+ * 大小
+ *
+ * @author wx
+ */
+class Size : Serializable {
+
+    /** Width宽 */
+    @Schema(description = "Width宽")
+    var width: Double? = null
+
+    /** Height高 */
+    @Schema(description = "Height高")
+    var height: Double? = null
+
+} // Class Size

+ 19 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/auxiliary/CategoryCode.kt

@@ -0,0 +1,19 @@
+package com.persagy.labsl.models.entities.auxiliary
+
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Table
+
+/**
+ * 图类型
+ *
+ * @author  wx
+ * @date  2020/9/17 12:05
+ */
+@Schema(description = "类型")
+class CategoryCode : Serializable {
+    /** 类型 id */
+    @Schema(description = "类型 id")
+    var categoryId: String? = null
+
+} // Class CategoryCode

+ 33 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pic/Picture.kt

@@ -0,0 +1,33 @@
+package com.persagy.labsl.models.entities.tpt.pic
+
+import com.alibaba.fastjson.annotation.JSONField
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 图片实体
+ *
+ * @author  wx
+ */
+@Schema(description = "图片实体")
+@Table(name = "labsl_pic.picture")
+open class Picture : SBaseEntity(), Serializable {
+
+    private val serialVersionUID = 1L
+    /** id */
+    @Schema(description = "id")
+    @Id
+    @Column(name = "id")
+    @JSONField(name = "Id")
+    var id: String? = null
+
+    /** 图片 */
+    @Schema(description = "图片")
+    @JSONField(name = "Pic")
+    @Column(name = "pic")
+    var pic: ByteArray? = null
+}

+ 16 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/AnchorPub.kt

@@ -0,0 +1,16 @@
+package com.persagy.labsl.models.entities.tpt.pub
+
+import com.persagy.labsl.models.entities.tpt.Anchor
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Table
+
+/**
+ * 锚点
+ *
+ * @author wx
+ */
+@Schema(description = "锚点")
+@Table(name = "labsl.anchor_pub")
+class AnchorPub : Anchor(), Serializable
+

+ 49 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/AttachObjectIdsPub.kt

@@ -0,0 +1,49 @@
+package com.persagy.labsl.models.entities.pub
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 图例节点与对象的关系
+ *
+ * @author  wx
+ * @date  2020/9/17 16:35
+ */
+@Schema(description = "图例节点与对象的关系")
+@Table(name = "labsl.attach_object_ids_pub")
+class AttachObjectIdsPub : SBaseEntity(), Serializable {
+
+    /** 全局id */
+    @Schema(description = "全局id")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 图例节点id */
+    @Schema(description = "图例节点id",required = true )
+    @Id
+    @Column(name = "node_id")
+    var nodeId: String? = null
+
+    /** 对象id */
+    @Schema(description = "对象id",required = true )
+    @Id
+    @Column(name = "object_id")
+    var objectId: String? = null
+
+    /** 图id */
+    @Schema(description = "图id")
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 图状态(1一般,2待审核,3审核完成,0发布) */
+    @Schema(description = "图状态(1一般,2待审核,3审核完成,4回收站 ,0发布)")
+    @Column(name = "state")
+    var state: Int? = 1
+
+
+} // Class AttachObjectIds

+ 24 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/ElementsPub.kt

@@ -0,0 +1,24 @@
+package com.persagy.labsl.models.entities.tpt.pub
+
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.validation.Valid
+
+/**
+ * 系统图展示所需数据
+ *
+ * @author wx
+ */
+class ElementsPub : Serializable {
+
+    @Schema(description = "图例节点")
+    @Valid
+    var nodes : ArrayList<NodePub>? = null
+
+    @Schema(description = "文本注释,图上的图片说明")
+    var markers : ArrayList<MarkersPub>? = null
+
+    @Schema(description = "管线对象")
+    var relations : ArrayList<RelationPub>? = null
+
+} // Class Elements

+ 115 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/GraphPub.kt

@@ -0,0 +1,115 @@
+package com.persagy.labsl.models.entities.tpt.pub
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import java.util.*
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 图例
+ *
+ * @author wx
+ */
+@Schema(description = "图例")
+@Table(name = "labsl.graph_pub")
+class GraphPub : SBaseEntity(), Serializable {
+
+    /** 全局id */
+    @Schema(description = "全局id" )
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 图类型id */
+    @Schema(description = "图类型id",required = true )
+    @Id
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 图名称 */
+    @Schema(description = "图名称")
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 图分类id */
+    @Schema(description = "图分类id")
+    @Column(name = "category_id")
+    var categoryId: String? = null
+
+    /** 项目id */
+    @Schema(description = "项目id")
+    @Column(name = "project_id")
+    var projectId: String? = null
+
+    /** 建筑id */
+    @Schema(description = "建筑id")
+    @Column(name = "building_id")
+    var buildingId: String? = null
+
+    /** 楼层id */
+    @Schema(description = "楼层id")
+    @Column(name = "floor_id")
+    var floorId: String? = null
+
+    /** 说明 */
+    @Schema(description = "说明")
+    @Column(name = "note")
+    var note: String? = null
+
+    /** 背景色 */
+    @Schema(description = "背景色")
+    @Column(name = "view_background")
+    var viewBackground: String? = null
+
+    /** 版本号 */
+    @Schema(description = "版本号")
+    @Column(name = "version")
+    var version: String? = null
+
+    @Schema(description = "系统图展示所需数据")
+    var elements: ElementsPub? = null
+
+    /** 移至回收站时间 */
+    @Schema(description = "移至回收站时间")
+    @Column(name = "del_time")
+    var delTime: Date? = null
+
+    /** 移至回收站时间 */
+    @Schema(description = "移至回收站时间 , false 正常,true 以至回收站")
+    @Column(name = "is_available")
+    var isAvailable: Boolean? = false
+
+    /** 内部版本号 */
+    @Schema(description = "内部版本号")
+    @Column(name = "tag_version")
+    var tagVersion: Int? = null
+
+//    /** 内部版本号 */
+//    @Schema(description = "是否发布(true 发布、false 未发布)")
+//    @Column(name = "is_pub")
+//    var isPub: Boolean = false
+
+    /** 图片Key */
+    @Schema(description = "图片Key")
+    @Column(name = "pic")
+    var pic: String? = null
+
+    /** 图状态(1一般,2待审核,3审核完成,0发布) */
+    @Schema(description = "图状态(1一般,2待审核,3审核完成,0发布)")
+    @Column(name = "state")
+    var state: Int? = null
+
+    /** 页面尺寸 */
+    @Schema(description = "页面尺寸")
+    @Column(name = "page_size")
+    var pageSize: HashMap<String, Any?>? = null
+
+    /** 标签 */
+    @Schema(description = " 标签 ")
+    @Column(name = "label")
+    var label: ArrayList<String>? = null
+
+} // Class Graph

+ 16 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/MarkersPub.kt

@@ -0,0 +1,16 @@
+package com.persagy.labsl.models.entities.tpt.pub
+
+import com.persagy.labsl.models.entities.tpt.Markers
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Table
+
+/**
+ * 文本注释,图上的图片说明
+ *
+ * @author wx
+ */
+@Schema(description = "文本注释,图上的图片说明")
+@Table(name = "labsl.marker_pub")
+class MarkersPub : Markers(), Serializable
+

+ 112 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/NodePub.kt

@@ -0,0 +1,112 @@
+package com.persagy.labsl.models.entities.tpt.pub
+
+import com.persagy.labsl.models.entities.tpt.Pos
+import com.persagy.labsl.models.entities.tpt.Size
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 图例节点
+ *
+ * @author wx
+ */
+@Schema(description = "图例节点")
+@Table(name = "labsl.node_pub")
+class NodePub : SBaseEntity(), Serializable {
+
+    /** 全局id */
+    @Schema(description = "全局id" )
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 图例节点id */
+    @Schema(description = "图例节点id",required = true )
+    @Id
+    @Column(name = "node_id")
+    var nodeId: String? = null
+
+    /** 图例节点名称 */
+    @Schema(description = "图例节点名称")
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 图例类型 None/Line/Zone/Image:非图例/线条/区域类型/图标 */
+    @Schema(description = "图例类型 None/Line/Zone/Image:非图例/线条/区域类型/图标")
+    @Column(name = "graph_element_type")
+    var graphElementType: String? = null
+
+    /** 图元ID */
+    @Schema(description = "图元ID")
+    @Column(name = "graph_element_id")
+    var graphElementId: String? = null
+
+    /** 图例数量 */
+    @Schema(description = "图例数量")
+    @Column(name = "num")
+    var num: Int? = null
+
+    /** 节点类型(image / zone) */
+    @Schema(description = "节点类型(image / zone)")
+    @Column(name = "type")
+    var type: String? = null
+
+    /** 位置信息 */
+    @Schema(description = "位置信息")
+    @Column(name = "pos")
+    var pos: Pos? = null
+
+    /** 缩放 */
+    @Schema(description = "缩放")
+    @Column(name = "scale")
+    var scale: Pos? = null
+
+    /** 旋转 */
+    @Schema(description = "旋转")
+    @Column(name = "rolate")
+    var rolate: Pos? = null
+
+    /** 大小 */
+    @Schema(description = "大小")
+    @Column(name = "size")
+    var size: Size? = null
+
+    /** 轮廓线 */
+    @Schema(description = "轮廓线")
+    @Column(name = "outline")
+    var outline: ArrayList<ArrayList<Pos>>? = null
+
+    @Schema(description = "应用自定义")
+    @Column(name = "properties")
+    var properties : HashMap<String,Any?>? = null
+
+    /** 图id */
+    @Schema(description = "图id")
+    @Column(name = "graph_id")
+    var graphId: String? = null
+
+    /** 锚点列表 */
+    @Schema(description = "锚点列表")
+    var anchorList: ArrayList<AnchorPub>? = null
+
+    @Schema(description = "对象 id 列表 ")
+    @Column(name = "attach_object_ids")
+    var attachObjectIds: ArrayList<String>? = null
+
+//    @Schema(description = "图例节点与对象的关系")
+//    var attachObjectIds: ArrayList<AttachObjectIdsPub>? = null
+
+    /** 图状态(1一般,2待审核,3审核完成,0发布) */
+    @Schema(description = "图状态(1一般,2待审核,3审核完成,0发布)")
+    @Column(name = "state")
+    var state: Int? = null
+
+    @Schema(description = "线的绘图样式")
+    @Column(name = "style")
+    var style : HashMap<String,Any?>? = null
+
+} // Class

+ 16 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/entities/tpt/pub/RelationPub.kt

@@ -0,0 +1,16 @@
+package com.persagy.labsl.models.entities.tpt.pub
+
+import com.persagy.labsl.models.entities.tpt.Relation
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Table
+
+/**
+ * 管线对象
+ *
+ * @author wx
+ */
+@Schema(description = "管线对象")
+@Table(name = "labsl.relation_pub")
+class RelationPub : Relation(), Serializable
+

+ 17 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/request/GraphCategoryRequest.kt

@@ -0,0 +1,17 @@
+package com.persagy.labsl.models.request
+
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+
+/**
+ * 系统图类型
+ * @author  wx
+ * @date  2020/9/17 10:42
+ */
+class GraphCategoryRequest : Serializable {
+
+    /** 类型开关 true  获取所有 false 获取已有图形的类型 */
+    @Schema(description = "类型开关 true  获取所有 false 获取已有图形的类型")
+    var switch: Boolean = true
+
+} // Class GraphCategoryRequest

+ 32 - 0
labsl/src/main/kotlin/com/persagy/labsl/models/response/SCommonResponse.kt

@@ -0,0 +1,32 @@
+package com.persagy.labsl.models.response
+
+import com.persagy.service.models.enums.SResponseType
+import io.swagger.v3.oas.annotations.media.Schema
+
+/**
+ * 返回体
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/6/9 14:56
+ */
+open class SCommonResponse<ENTITY: Any>(result: SResponseType? = SResponseType.success, message: String? = null) {
+
+    /** 结果 */
+    @Schema(description = "结果")
+    var result: SResponseType? = SResponseType.failure
+    /** 消息 */
+    @Schema(description = "消息")
+    var message: String? = ""
+
+    /** 结果 */
+    @Schema(description = "结果")
+    var content: ENTITY? = null
+
+    /** 初始化 */
+    init {
+        this.result = result
+        this.message = message
+    } // init()
+
+
+}

+ 12 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/AnchorService.kt

@@ -0,0 +1,12 @@
+package com.persagy.labsl.services
+
+import com.persagy.labsl.models.entities.tpt.Anchor
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+
+/**
+ * 锚点服务
+ *
+ * @author wx
+ */
+object AnchorService  : SObjectService<Anchor>(SMybatisDao(Anchor::class.java))

+ 13 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/AttachObjectIdsServices.kt

@@ -0,0 +1,13 @@
+package com.persagy.labsl.services
+
+import com.persagy.labsl.models.entities.tpt.AttachObjectIds
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+
+/**
+ * 图例节点与对象的关系服务
+ *
+ * @author  wx
+ * @date  2020/9/17 17:02
+ */
+object AttachObjectIdsServices : SObjectService<AttachObjectIds>(SMybatisDao(AttachObjectIds::class.java))

+ 61 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/CustomService.kt

@@ -0,0 +1,61 @@
+package com.persagy.labsl.services
+
+import com.persagy.labsl.models.entities.auxiliary.CategoryCode
+import com.persagy.labsl.models.entities.tpt.Graph
+import com.persagy.labsl.models.entities.tpt.pub.GraphPub
+import com.persagy.labsl.services.mappers.CustomMapper
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Service
+
+/**
+ * 自定义SQL 服务
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/9/17 12:09
+ */
+@Service
+class CustomService {
+
+    /** 实例化 mapper 对象 */
+    @Autowired
+    lateinit var customMapper: CustomMapper
+
+    /**
+     * 草稿箱 已有类型
+     *
+     * @param projectId     项目id
+     * @return 类型列表
+     */
+    fun draftsCategory(projectId: String): ArrayList<CategoryCode>?{
+        return customMapper.calcAffected(projectId)
+    }
+
+    /**
+     * 已发布 类型
+     *
+     * @param projectId     项目id
+     * @return 类型列表
+     */
+    fun pubCategory(projectId: String): ArrayList<CategoryCode>?{
+        return customMapper.pubCategory(projectId)
+    }
+
+    /**
+     * 查询标签,已发布
+     *
+     * @param label
+     */
+    fun containLabelPub(projectId: String ,label: String): ArrayList<GraphPub>? {
+        return customMapper.containLabelPub(projectId,label)
+    }
+
+    /**
+     * 查询标签,未发布
+     *
+     * @param label
+     */
+    fun containLabel(projectId: String ,label: String): ArrayList<Graph>? {
+        return customMapper.containLabel(projectId,label)
+    }
+
+}

+ 221 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/GraphCategoryService.kt

@@ -0,0 +1,221 @@
+package com.persagy.labsl.services
+
+import com.persagy.database.SFilter
+import com.persagy.labsl.Opts
+import com.persagy.labsl.models.entities.tpt.GraphCategory
+import com.persagy.labsl.models.request.GraphCategoryRequest
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+import com.persagy.service.models.enums.SResponseType
+import com.persagy.service.models.responses.SQueryResponse
+import com.persagy.service.utils.SSpringContextUtil
+
+/**
+ * 分类服务
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/9/15 11:38
+ */
+object GraphCategoryService : SObjectService<GraphCategory>(SMybatisDao(GraphCategory::class.java)) {
+
+    /** 自定义sql */
+    private val customMapper by lazy {
+        SSpringContextUtil.getBean(CustomService::class.java) as CustomService
+    }
+
+    /**
+     * 系统图分类查询
+     *
+     * @param request   查询条件对象
+     * @return 查询结果
+     */
+    fun graphCategoryQuery(request: GraphCategoryRequest): SQueryResponse<GraphCategory> {
+        /** 返回结果 */
+        val sQueryResponse = SQueryResponse<GraphCategory>()
+        return try {
+            /** true 获取所有图类型,false 获取已有图类型 */
+            if (request.switch) {
+                /** 查询图类型的父节点 */
+                val graphCategoryList = select(SFilter.isNull("parentId")).exec()
+                /** 遍历父节点图类型 */
+                for (graphCategory in graphCategoryList) {
+                    /** 递归获取子节点 */
+                    val treeClimate = treeClimate(graphCategory.id!!, true)
+                    /** 子节点列表不可以为空 */
+                    if (treeClimate.size > 0) {
+                        /** 赋值子节点列表 */
+                        graphCategory.categoryList = treeClimate
+                    }
+                }
+                /** 列表赋值 */
+                sQueryResponse.content = graphCategoryList
+                /** 列表长度 */
+                sQueryResponse.total = graphCategoryList.size.toLong()
+                /** 反馈标志 */
+                sQueryResponse.result = SResponseType.success
+                /** 返回的对象 */
+                sQueryResponse
+            } else {
+                /** 草稿箱类型统计 */
+                val calcAffectedList = customMapper.draftsCategory(Opts.projectId!!)
+                /** 已发布类型统计 */
+                val pubCategoryList = customMapper.pubCategory(Opts.projectId!!)
+                /** 类型数组 */
+                val set = HashSet<String>()
+                /** 草稿箱或已发布不可以为空 */
+                if (!pubCategoryList.isNullOrEmpty() || !calcAffectedList.isNullOrEmpty()) {
+                    /** 已发布类型不可以为空 */
+                    if (!pubCategoryList.isNullOrEmpty()) {
+                        /** 遍历已发布类型 */
+                        for (pubCategory in pubCategoryList) {
+                            set.add(pubCategory.categoryId!!)
+                        }
+                    }
+
+                    /** 草稿箱已发布类型不可以为空 */
+                    if (!calcAffectedList.isNullOrEmpty()) {
+                        /** 遍历草稿箱类型 */
+                        for (calcAffected in calcAffectedList) {
+                            set.add(calcAffected.categoryId!!)
+                        }
+                    }
+
+                    /** 查询主分类 */
+                    val graphCategoryList = select(SFilter.isNull("parentId")).exec()
+                    /** 遍历主分类 */
+                    for (graphCategory in graphCategoryList) {
+                        /** 递归查询子分类 */
+                        val treeClimate = treeClimate(graphCategory.id!!, true)
+                        /** 子分类数量大于0 */
+                        if (treeClimate.size > 0) {
+                            /** 子分类列表赋值 */
+                            graphCategory.categoryList = treeClimate
+                        }
+                    }
+
+                    /** 遍历分类列表 */
+                    for (id in set) {
+                        /** 遍历分类列表 */
+                        for (graphCategory in graphCategoryList) {
+                            /** 相等的做标记 */
+                            if (graphCategory.id == id) {
+                                graphCategory.sign = true
+                            }
+                            /** 子分类不为空 */
+                            if (!graphCategory.categoryList.isNullOrEmpty()) {
+                                val categoryList = graphCategory.categoryList!!
+                                /** 遍历分类 */
+                                for (category in categoryList) {
+                                    /** 相等的做标记 */
+                                    if (category.id == id) {
+                                        category.sign = true
+                                        graphCategory.sign = true
+                                    }
+                                    /** 分类列表不为空 */
+                                    if (!category.categoryList.isNullOrEmpty()) {
+                                        val categoryList1 = category.categoryList!!
+                                        /** 遍历列表 */
+                                        for (category2 in categoryList1) {
+                                            /** id相等的做标记 */
+                                            if (category2.id == id) {
+                                                category2.sign = true
+                                                category.sign = true
+                                                graphCategory.sign = true
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    val iterator = graphCategoryList.iterator()
+                    /** 遍历分类 */
+                    while (iterator.hasNext()) {
+                        val next = iterator.next()
+                        /** 标记为true */
+                        if (next.sign) {
+                            /** 列表不为空 */
+                            if (!next.categoryList.isNullOrEmpty()) {
+                                val iterator1 = next.categoryList!!.iterator()
+                                /** 遍历子列表 */
+                                while (iterator1.hasNext()) {
+                                    val next1 = iterator1.next()
+                                    /** 标记为 true */
+                                    if (next1.sign) {
+                                        if (!next1.categoryList.isNullOrEmpty()) {
+                                            val iterator2 = next1.categoryList!!.iterator()
+                                            /** 遍历子列表 */
+                                            while (iterator2.hasNext()) {
+                                                val next2 = iterator2.next()
+                                                /** 标记为 true 删除 */
+                                                if (!next2.sign) {
+                                                    /** 删除 */
+                                                    iterator2.remove()
+                                                }
+                                            }
+                                        }
+                                    } else {
+                                        /** 删除 */
+                                        iterator1.remove()
+                                    }
+                                }
+                            }
+                        } else {
+                            /** 删除 */
+                            iterator.remove()
+                        }
+                    }
+
+                    /** 赋值分类列表 */
+                    sQueryResponse.content = graphCategoryList
+                    /** 列表长度 */
+                    sQueryResponse.total = graphCategoryList.size.toLong()
+                } else {
+                    /** 赋值分类列表 */
+                    sQueryResponse.content = ArrayList()
+                }
+                /** 返回标记 */
+                sQueryResponse.result = SResponseType.success
+                /** 返回对象 */
+                sQueryResponse
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+            sQueryResponse.result = SResponseType.failure
+            sQueryResponse.message = e.message!!
+            sQueryResponse
+        }
+    }
+
+    /**
+     * 气候区 递归查询
+     *
+     * @param  parent        外键关系值
+     * @param  hasChildren  是否进行递归查询
+     * @return 类型列表
+     */
+    private fun treeClimate(parent: String, hasChildren: Boolean = true): ArrayList<GraphCategory> {
+        /** 父指针为空的分类 */
+        val content = select("parentId" to parent).exec()
+        /** 是否查询子列表 */
+        if (hasChildren) {
+            /** 遍历父指针 */
+            for (item in content) {
+                try {
+                    /** 调用本方法 */
+                    val children = treeClimate(item.id!!)
+                    /** 子列表大于0 */
+                    if (children.size > 0) {
+                        /** 赋值 */
+                        item.categoryList = children
+                    }
+                } catch (e: Exception) {
+                    // DO NOTHING
+                }
+            }
+        }
+        return content
+    }
+
+}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1246 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/GraphService.kt


+ 123 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/MarkersService.kt

@@ -0,0 +1,123 @@
+package com.persagy.labsl.services
+
+import com.persagy.database.SFilter
+import com.persagy.labsl.models.entities.tpt.Markers
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+import com.persagy.service.models.enums.SResponseType
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import org.springframework.web.bind.annotation.RequestBody
+import java.util.*
+
+/**
+ * 文本注释,图上的图片说明
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ */
+object MarkersService : SObjectService<Markers>(SMybatisDao(
+    Markers::class.java)) {
+    /**
+     * 创建说明
+     *
+     * @param request   创建的对象列表
+     * @return 返回结果
+     */
+    fun creates(request: SCreateRequest<Markers>): SCreateResponse<Markers> {
+        /** 返回结果对象 */
+        val sCreateResponse = SCreateResponse<Markers>()
+        /** 返回结果中的状态 */
+        sCreateResponse.result = SResponseType.failure
+        return try {
+            /** 列表不可以为空 */
+            if (!request.content.isNullOrEmpty()) {
+                /** 遍历标记列表 */
+                for (markers in request.content) {
+                    /** 判断必传字段不可以为空 */
+                    if (markers.id.isNullOrEmpty() || markers.graphId.isNullOrEmpty() || markers.name.isNullOrEmpty()) {
+                        sCreateResponse.message = "注意必填字段不可以为空如 id、graphId、name"
+                        return sCreateResponse
+                    }
+                    /** 查询 id 和 graphId 是否存在,是否可以定位一个系统图 */
+                    val graphList =
+                        GraphService.select(SFilter.eq("id", markers.id!!), SFilter.eq("graphId", markers.graphId!!))
+                            .exec()
+                    /** 图 id 和 graphId 不存在*/
+                    if (graphList.size == 0) {
+                        sCreateResponse.message = "请检查 id 和 graphId 是否为已有系统图中的 id"
+                        return sCreateResponse
+                    }
+                }
+
+                /** 遍历标记列表 */
+                for (markers in request.content) {
+                    /** 判断标记id是否没有,为空赋值 */
+                    if (markers.markerId.isNullOrEmpty()) {
+                        markers.markerId = UUID.randomUUID().toString().replace("-", "")
+                    }
+
+                    /** 插入数据 */
+                    insert(markers)
+                }
+                /** 对象列表 */
+                sCreateResponse.entityList = request.content
+                /** 状态 */
+                sCreateResponse.result = SResponseType.success
+                /** 对象 */
+                sCreateResponse
+            } else {
+                /** 描述 */
+                sCreateResponse.message = "不可以传空列表"
+                /** 对象 */
+                return sCreateResponse
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+            sCreateResponse.message = e.message!!
+            sCreateResponse
+        }
+    }
+
+    /**
+     * 批量删除标识信息
+     *
+     * @param idList    标识信息对象列表
+     * @return 返回结果
+     */
+    fun deletes(@RequestBody idList: ArrayList<Markers>): SBaseResponse {
+        /** 返回结果对象 */
+        val sBaseResponse = SBaseResponse()
+        /** 返回结果状态 */
+        sBaseResponse.result = SResponseType.failure
+        return try {
+            /** 列表不可以为空 */
+            if (!idList.isNullOrEmpty()) {
+                /** 遍历标签信息列表 */
+                for (markers in idList) {
+                    /** 校验必填信息点 */
+                    if (markers.id.isNullOrEmpty() || markers.markerId.isNullOrEmpty()) {
+                        sBaseResponse.message = "注意接口说明必填字段"
+                        return sBaseResponse
+                    }
+                }
+
+                /** 遍历标签信息列表 */
+                for (markers in idList) {
+                    /** 删除对象 */
+                    delete(SFilter.eq("id",markers.id!!),SFilter.eq("markerId",markers.markerId!!))
+                }
+
+                /** 返回结果状态 */
+                sBaseResponse.result = SResponseType.success
+            }
+            /** 返回结果对象 */
+            sBaseResponse
+        } catch (e: Exception) {
+            e.printStackTrace()
+            /** 返回结果,状态、以及报错信息 */
+            SBaseResponse(SResponseType.failure,e.message!!)
+        }
+    }
+
+}

+ 136 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/NodeService.kt

@@ -0,0 +1,136 @@
+package com.persagy.labsl.services
+
+import com.persagy.database.SFilter
+import com.persagy.labsl.models.entities.tpt.Node
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+import com.persagy.service.models.enums.SResponseType
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import org.springframework.web.bind.annotation.RequestBody
+import java.util.*
+
+/**
+ * 图例节点服务
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ */
+object NodeService : SObjectService<Node>(SMybatisDao(
+    Node::class.java)) {
+    /**
+     * 创建之前
+     *
+     * @param entity    图例节点
+     * @return 是否处理
+     */
+    override fun onCreateBefore(entity: Node): Boolean {
+        /** id 赋值 */
+        entity.id = UUID.randomUUID().toString().replace("-", "")
+        return super.onCreateBefore(entity)
+    }
+
+    /**
+     * 创建设备节点
+     *
+     * @param request   创建设备节点对象列表
+     * @return 返回结果
+     */
+    fun creates(request: SCreateRequest<Node>): SCreateResponse<Node> {
+        /** 返回结果对象 */
+        val sCreateResponse = SCreateResponse<Node>()
+        /** 返回结果中的状态 */
+        sCreateResponse.result = SResponseType.failure
+        return try {
+            /** 列表不可以为空 */
+            if (!request.content.isNullOrEmpty()) {
+                /** 遍历标记列表 */
+                for (node in request.content) {
+                    /** 判断必传字段不可以为空 */
+                    if (node.id.isNullOrEmpty() || node.graphId.isNullOrEmpty() || node.name.isNullOrEmpty()) {
+                        sCreateResponse.message = "注意必填字段不可以为空如 id、graphId、name"
+                        return sCreateResponse
+                    }
+                    /** 查询 id 和 graphId 是否存在,是否可以定位一个系统图 */
+                    val graphList =
+                        GraphService.select(SFilter.eq("id", node.id!!), SFilter.eq("graphId", node.graphId!!))
+                            .exec()
+                    /** 图 id 和 graphId 不存在*/
+                    if (graphList.size == 0) {
+                        sCreateResponse.message = "请检查 id 和 graphId 是否为已有系统图中的 id"
+                        return sCreateResponse
+                    }
+                }
+
+                /** 遍历标记列表 */
+                for (node in request.content) {
+                    /** 判断标记id是否没有,为空赋值 */
+                    if (node.nodeId.isNullOrEmpty()) {
+                        node.nodeId = UUID.randomUUID().toString().replace("-", "")
+                    }
+
+                    /** 插入数据 */
+                   insert(node)
+                }
+                /** 对象列表 */
+                sCreateResponse.entityList = request.content
+                /** 标志 */
+                sCreateResponse.result = SResponseType.success
+                /** 对象 */
+                sCreateResponse
+            } else {
+                /** 描述 */
+                sCreateResponse.message = "不可以传空列表"
+                /** 对象 */
+                return sCreateResponse
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+            sCreateResponse.message = e.message!!
+            sCreateResponse
+        }
+    }
+
+    /**
+     * 批量删除设备节点
+     *
+     * @param idList    设备节点对象列表
+     * @return 返回结果
+     */
+    fun deletes(@RequestBody idList: ArrayList<Node>): SBaseResponse {
+        /** 返回结果对象 */
+        val sBaseResponse = SBaseResponse()
+        /** 返回结果状态 */
+        sBaseResponse.result = SResponseType.failure
+        return try {
+            /** 列表不可以为空 */
+            if (!idList.isNullOrEmpty()) {
+                /** 遍历设备节点列表 */
+                for (node in idList) {
+                    /** 校验必填信息点 */
+                    if (node.id.isNullOrEmpty() || node.nodeId.isNullOrEmpty()) {
+                        sBaseResponse.message = "注意接口说明必填字段"
+                        return sBaseResponse
+                    }
+                }
+
+                /** 遍历设备节点列表 */
+                for (node in idList) {
+                    /** 删除对象 */
+                    delete(SFilter.eq("id", node.id!!), SFilter.eq("nodeId", node.nodeId!!))
+                }
+
+                /** 返回结果状态 */
+                sBaseResponse.result = SResponseType.success
+            }
+            /** 返回结果对象 */
+            sBaseResponse
+        } catch (e: Exception) {
+            e.printStackTrace()
+            /** 返回结果,状态、以及报错信息 */
+            SBaseResponse(SResponseType.failure,e.message!!)
+        }
+    }
+
+
+}

+ 138 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/RelationService.kt

@@ -0,0 +1,138 @@
+package com.persagy.labsl.services
+
+import com.persagy.database.SFilter
+import com.persagy.labsl.models.entities.tpt.Relation
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+import com.persagy.service.models.enums.SResponseType
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import org.springframework.web.bind.annotation.RequestBody
+import java.util.*
+
+/**
+ * 管线对象
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ */
+object RelationService : SObjectService<Relation>(SMybatisDao(
+    Relation::class.java)){
+    /**
+     * 创建之前的操作
+     *
+     * @param entity    管线对象
+     * @return 是否处理
+     */
+    override fun onCreateBefore(entity: Relation): Boolean {
+        /** id 赋值 */
+        entity.id = UUID.randomUUID().toString().replace("-", "")
+        return super.onCreateBefore(entity)
+    } //
+
+
+    /**
+     * 创建管线对象
+     *
+     * @param request   创建管线对象列表
+     * @return 返回结果
+     */
+    fun creates(request: SCreateRequest<Relation>): SCreateResponse<Relation> {
+        /** 返回结果对象 */
+        val sCreateResponse = SCreateResponse<Relation>()
+        /** 返回结果中的状态 */
+        sCreateResponse.result = SResponseType.failure
+        return try {
+
+            /** 列表不可以为空 */
+            if (!request.content.isNullOrEmpty()) {
+                /** 遍历管线列表 */
+                for (relation in request.content) {
+                    /** 判断必传字段不可以为空 */
+                    if (relation.id.isNullOrEmpty() || relation.graphId.isNullOrEmpty() || relation.name.isNullOrEmpty()) {
+                        sCreateResponse.message = "注意必填字段不可以为空如 id、graphId、name"
+                        return sCreateResponse
+                    }
+                    /** 查询 id 和 graphId 是否存在,是否可以定位一个系统图 */
+                    val graphList =
+                        GraphService.select(SFilter.eq("id", relation.id!!), SFilter.eq("graphId", relation.graphId!!))
+                            .exec()
+                    /** 图 id 和 graphId 不存在*/
+                    if (graphList.size == 0) {
+                        sCreateResponse.message = "请检查 id 和 graphId 是否为已有系统图中的 id"
+                        return sCreateResponse
+                    }
+                }
+
+                /** 遍历管线列表 */
+                for (relation in request.content) {
+                    /** 判断标记id是否没有,为空赋值 */
+                    if (relation.relationId.isNullOrEmpty()) {
+                        relation.relationId = UUID.randomUUID().toString().replace("-", "")
+                    }
+
+                    /** 插入数据 */
+                    insert(relation)
+                }
+                /** 对象列表 */
+                sCreateResponse.entityList = request.content
+                /** 状态 */
+                sCreateResponse.result = SResponseType.success
+                /** 对象 */
+                sCreateResponse
+            } else {
+                /** 描述 */
+                sCreateResponse.message = "不可以传空列表"
+                /** 对象 */
+                return sCreateResponse
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+            sCreateResponse.message = e.message!!
+            sCreateResponse
+        }
+    }
+
+    /**
+     * 批量删除管线信息
+     *
+     * @param idList    管线对象列表
+     * @return 返回结果
+     */
+    fun deletes(@RequestBody idList: ArrayList<Relation>): SBaseResponse {
+        /** 返回结果对象 */
+        val sBaseResponse = SBaseResponse()
+        /** 返回结果状态 */
+        sBaseResponse.result = SResponseType.failure
+        return try {
+            /** 列表不可以为空 */
+            if (!idList.isNullOrEmpty()) {
+                /** 遍历管线信息列表 */
+                for (relation in idList) {
+                    /** 校验必填信息点 */
+                    if (relation.id.isNullOrEmpty() || relation.relationId.isNullOrEmpty()) {
+                        sBaseResponse.message = "注意接口说明必填字段"
+                        return sBaseResponse
+                    }
+                }
+
+                /** 遍历管线信息列表 */
+                for (relation in idList) {
+                    /** 删除对象 */
+                    delete(SFilter.eq("id", relation.id!!), SFilter.eq("relationId", relation.relationId!!))
+                }
+
+                /** 返回结果状态 */
+                sBaseResponse.result = SResponseType.success
+            }
+            /** 返回结果对象 */
+            sBaseResponse
+        } catch (e: Exception) {
+            e.printStackTrace()
+            /** 返回结果,状态、以及报错信息 */
+            SBaseResponse(SResponseType.failure,e.message!!)
+        }
+    }
+
+
+}

+ 34 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/mappers/CustomMapper.kt

@@ -0,0 +1,34 @@
+package com.persagy.labsl.services.mappers
+
+import com.persagy.labsl.models.entities.auxiliary.CategoryCode
+import com.persagy.labsl.models.entities.tpt.Graph
+import com.persagy.labsl.models.entities.tpt.pub.GraphPub
+import org.apache.ibatis.annotations.Mapper
+import org.apache.ibatis.annotations.Param
+import org.apache.ibatis.annotations.Select
+import org.springframework.stereotype.Repository
+
+/**
+ * 自定义SQL
+ *
+ * @author  wx
+ * @date  2020/9/17 12:01
+ */
+@Repository
+@Mapper
+interface CustomMapper {
+    /** 未发布 */
+    @Select("SELECT category_id as categoryId FROM labsl.graph  WHERE project_id = #{projectId} AND state =1 GROUP BY category_id")
+    fun calcAffected(@Param("projectId") projectId: String) : ArrayList<CategoryCode>?
+
+    /** 已发布 */
+    @Select("SELECT category_id as categoryId FROM labsl.graph_pub  WHERE project_id = #{projectId} AND state =0 GROUP BY category_id")
+    fun pubCategory(@Param("projectId") projectId: String) : ArrayList<CategoryCode>?
+
+    @Select("SELECT * FROM graph WHERE project_id = #{projectId} and label::text like  '%#{label}%'")
+    fun containLabel(@Param("projectId") projectId: String,@Param("label") label: String): ArrayList<Graph>?
+
+    @Select("SELECT * FROM graph_pub WHERE project_id = #{projectId} and label::text like  '%#{label}%'")
+    fun containLabelPub(@Param("projectId") projectId: String,@Param("label") label: String): ArrayList<GraphPub>?
+
+} // Interface CustomMapper

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1311 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/planar/PlanarGraphService.kt


+ 27 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/planar/PlanarQbsRuleService.kt

@@ -0,0 +1,27 @@
+package com.persagy.labsl.services.planar
+
+import com.persagy.labsl.models.entities.pbs.PlanarQbsRule
+import com.persagy.labsl.utils.IdUtils
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+
+/**
+ * 规则
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/12/13 9:34
+ */
+object PlanarQbsRuleService : SObjectService<PlanarQbsRule>(SMybatisDao(PlanarQbsRule::class.java)) {
+
+
+    override fun onCreateBefore(entity: PlanarQbsRule): Boolean {
+//        if (entity.id.isNullOrEmpty()) {
+//            entity.id = IdUtils.uuidCreate()
+//        }
+
+        return super.onCreateBefore(entity)
+    }
+
+
+
+}

+ 136 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/planar/QbsFolderService.kt

@@ -0,0 +1,136 @@
+package com.persagy.labsl.services.planar
+
+import com.persagy.database.SFilter
+import com.persagy.labsl.Opts
+import com.persagy.labsl.models.entities.pbs.PlanarGraphPub
+import com.persagy.labsl.models.entities.pbs.QbsFolder
+import com.persagy.labsl.utils.IdUtils
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+import com.persagy.service.models.enums.SResponseType
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SUpdateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+
+/**
+ * 文件夹服务
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/12/1 15:37
+ */
+object QbsFolderService : SObjectService<QbsFolder>(SMybatisDao(QbsFolder::class.java)) {
+
+    /** 已发布 */
+    val planarGraphPubService = SObjectService(SMybatisDao(PlanarGraphPub::class.java))
+
+    /**
+     * 创建文件夹
+     *
+     * @param request   对象列表
+     * @return 对象列表
+     */
+    fun creates(request: SCreateRequest<QbsFolder>): SCreateResponse<QbsFolder> {
+        val sCreateResponse = SCreateResponse<QbsFolder>()
+        try {
+            if (!request.content.isNullOrEmpty()) {
+                    for (content in request.content){
+                        val execList = select(SFilter.eq("projectId", Opts.projectId!!),SFilter.eq("name", content.name!!)).exec()
+                        if (execList.size>0){
+                            sCreateResponse.result = SResponseType.failure
+                            sCreateResponse.message ="文件夹名称已存在"
+                            return sCreateResponse
+                        }
+                        content.projectId = Opts.projectId
+                        content.id = IdUtils.uuidCreate()
+                        insert(content)
+
+                    }
+                sCreateResponse.entityList = request.content
+                sCreateResponse.result = SResponseType.success
+                } else {
+                sCreateResponse.result = SResponseType.failure
+                sCreateResponse.message ="创建内容不可以为空"
+                }
+        } catch (e: Exception) {
+            e.printStackTrace()
+            sCreateResponse.result = SResponseType.failure
+        }
+        return sCreateResponse
+    }
+
+    /**
+     * 删除
+     */
+    fun deletes(idList: ArrayList<QbsFolder>): SBaseResponse {
+        val sBaseResponse = SBaseResponse()
+        if (idList.size>0) {
+            try {
+                for (qbsFolder in idList) {
+                    val planarGraphList = PlanarGraphService.select(
+                        SFilter.eq("folderId", qbsFolder.id!!),
+                        SFilter.eq("projectId", Opts.projectId!!),
+                        SFilter.eq("state", "Draft")
+                    ).exec()
+                    val planarGraphPubList = planarGraphPubService.select(
+                        SFilter.eq("folderId", qbsFolder.id!!),
+                        SFilter.eq("projectId", Opts.projectId!!),
+                        SFilter.eq("state", "Publish")
+                    ).exec()
+                    if (planarGraphList.size>0||planarGraphPubList.size>0) {
+                        sBaseResponse.message = "文件夹有内容,禁止删除"
+                        sBaseResponse.result = SResponseType.failure
+                        return sBaseResponse
+                    }
+                }
+
+                for (qbsFolder in idList) {
+                    val delete = delete(qbsFolder)
+                    if (delete) {
+                        PlanarGraphService.delete(
+                            SFilter.eq("id", qbsFolder.id!!),
+                            SFilter.eq("projectId", Opts.projectId!!),
+                            SFilter.eq("state", "Recyle")
+                        )
+                    }
+                }
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+            sBaseResponse.result =SResponseType.success
+        } else {
+            sBaseResponse.result = SResponseType.failure
+        }
+        return sBaseResponse
+    }
+
+    /**
+     * 修改文件夹信息
+     *
+     * @param request   对象列表
+     * @return 返回修改标记对象
+     */
+    fun updates(request: SUpdateRequest<QbsFolder>): SBaseResponse {
+        val sBaseResponse = SBaseResponse()
+        if (!request.content.isNullOrEmpty()) {
+           for (content in request.content!!) {
+               val execList = select(SFilter.eq("projectId", Opts.projectId!!),SFilter.not(SFilter.eq("id",content.id!!)),SFilter.eq("name", content.name!!)).exec()
+               if (execList.size>0) {
+                   sBaseResponse.result = SResponseType.failure
+                   sBaseResponse.message = "文件夹名已存在"
+                   return sBaseResponse
+               }
+               if (!content.projectId.isNullOrEmpty()) {
+                   content.projectId = Opts.projectId
+               }
+               update(content)
+           }
+            sBaseResponse.result = SResponseType.success
+        } else {
+            sBaseResponse.result = SResponseType.failure
+        }
+        return  sBaseResponse
+    }
+
+
+}

+ 12 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/pub/AnchorPubService.kt

@@ -0,0 +1,12 @@
+package com.persagy.labsl.services.pub
+
+import com.persagy.labsl.models.entities.tpt.pub.AnchorPub
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+
+/**
+ * 锚点服务
+ *
+ * @author wx
+ */
+object AnchorPubService  : SObjectService<AnchorPub>(SMybatisDao(AnchorPub::class.java))

+ 14 - 0
labsl/src/main/kotlin/com/persagy/labsl/services/pub/GraphPubService.kt

@@ -0,0 +1,14 @@
+package com.persagy.labsl.services.pub
+
+import com.persagy.labsl.models.entities.tpt.pub.GraphPub
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+
+/**
+ * 已发布图
+ *
+ * @author  wx
+ * @date  2020/9/14 18:15
+ */
+object GraphPubService : SObjectService<GraphPub>(SMybatisDao(
+    GraphPub::class.java))

+ 236 - 0
labsl/src/main/kotlin/com/persagy/labsl/utils/IdUtils.kt

@@ -0,0 +1,236 @@
+package com.persagy.labsl.utils
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+
+/**
+ * id生成帮助类
+ *
+ * @author 张维新
+ */
+object IdUtils {
+
+    /**
+     * 生成项目id
+     *
+     * @param   code    城市六位编码
+     * @param   num     城市存在建筑的数量
+     * @return          返回项目id
+     */
+    fun projectIdCreate(code: String, num: Int): String {
+        try {
+            if (num + 1 > 9999) {
+                throw  SecurityException("建筑数量已超出最大值")
+            }
+            val nums = num + 1
+            val genId = String.format("%1$4s", nums).replace(' ', '0')
+            val sb = StringBuilder()
+            val appendId = sb.append("Pj").append(code).append(genId)
+
+            return appendId.toString()
+        } catch (e: Throwable) {
+            e.printStackTrace()
+        }
+        throw  SecurityException("id生成失败")
+    } // Function ProjectId
+
+    /**
+     * 生成建筑Id
+     *
+     * @param   projectId   项目id
+     * @return              建筑id
+     */
+    fun buildIdCreate(projectId: String): String {
+        val bdid = projectId.replace("Pj", "Bd")
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val buildId = sb.append(bdid).append(uuId)
+        return buildId.toString()
+    } // Function buildIdCreate
+
+    /**
+     * 生成楼层Id
+     *
+     * @param   projectId   项目id
+     * @return              楼层id
+     */
+    fun floorIdCreate(projectId: String): String {
+        val bdid = projectId.replace("Pj", "Fl")
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val floorId = sb.append(bdid).append(uuId)
+        return floorId.toString()
+    } // Function floorIdCreate
+
+    /**
+     * 生成空间Id
+     *
+     * @param   projectId   项目id
+     * @return              空间id
+     */
+    fun spaceIdCreate(projectId: String): String {
+        val bdid = projectId.replace("Pj", "Sp")
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val spaceId = sb.append(bdid).append(uuId)
+        return spaceId.toString()
+    } // Function spaceIdCreate
+
+    /**
+     * 生成元空间Id
+     *
+     * @param   projectId   项目id
+     * @return              元空间id
+     */
+    fun iSpaceIdCreate(projectId: String): String {
+        val bdid = projectId.replace("Pj", "Si")
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val siId = sb.append(bdid).append(uuId)
+        return siId.toString()
+    } // Function iSpaceIdCreate
+
+    /**
+     * 生成系统Id
+     *
+     * @param   projectId   项目id
+     * @return              系统id
+     */
+    fun systemIdCreate(projectId: String): String {
+        val bdid = projectId.replace("Pj", "Sy")
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val systemId = sb.append(bdid).append(uuId)
+        return systemId.toString()
+    } // Function systemIdCreate
+
+    /**
+     * 生成设备Id
+     *
+     * @param   projectId   项目id
+     * @return              设备id
+     */
+    fun equipmentIdCreate(projectId: String): String {
+        val bdid = projectId.replace("Pj", "Eq")
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val eqId = sb.append(bdid).append(uuId)
+        return eqId.toString()
+    } // Function equipmentIdCreate
+
+    /**
+     * 生成设备部件Id
+     *
+     * @param   projectId   项目id
+     * @return              设备部件id
+     */
+    fun equipmentComponentIdCreate(projectId: String): String {
+        val bdid = projectId.replace("Pj", "Ec")
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val ecId = sb.append(bdid).append(uuId)
+        return ecId.toString()
+    } // Function equipmentComponentIdCreate
+
+    /**
+     * 生成设施Id
+     *
+     * @param   projectId   项目id
+     * @return              设施id
+     */
+    fun structureIdCreate(projectId: String): String {
+        val bdid = projectId.replace("Pj", "St")
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val stId = sb.append(bdid).append(uuId)
+        return stId.toString()
+    } // Function structureIdCreate
+
+    /**
+     * 生成设施部件Id
+     *
+     * @param   projectId   项目id
+     * @return              设施部件id
+     */
+    fun structureComponentIdCreate(projectId: String): String {
+        val bdid = projectId.replace("Pj", "Sc")
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val scId = sb.append(bdid).append(uuId)
+        return scId.toString()
+    } // Function structureComponentIdCreate
+
+    /**
+     * 生成资产编码Id
+     *
+     * @param   projectId   项目id
+     * @return              设备资产编码id
+     */
+    fun peIdCreate(projectId: String): String {
+        val bdid = "Pe"
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val peId = sb.append(bdid).append(uuId)
+        return peId.toString()
+    } // Function peIdCreate
+
+    /**
+     * 生成竖井Id
+     *
+     * @param   projectId   项目id
+     * @return              竖井id
+     */
+    fun shaftIdCreate(projectId: String): String {
+        val bdid = projectId.replace("Pj", "Sh")
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val shId = sb.append(bdid).append(uuId)
+        return shId.toString()
+    } // Function shaftIdCreate
+
+    /**
+     * 生成租户Id
+     *
+     * @param   projectId   项目id
+     * @return              租户id
+     */
+    fun tenantIdCreate(projectId: String): String {
+        val bdid = projectId.replace("Pj", "VOTn")
+        val sb = StringBuilder()
+        val uuid = UUID.randomUUID().toString()
+        val uuId = uuid.replace("-", "")
+        val shId = sb.append(bdid).append(uuId)
+        return shId.toString()
+    } // Function shaftIdCreate
+
+    /**
+     * 生成uuid
+     *
+     * @return              uuid
+     */
+    fun uuidCreate(): String {
+        val uuid = UUID.randomUUID().toString()
+        return uuid.replace("-", "")
+    } // Function uuidCreate
+
+
+    fun time():String {
+        val df = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") //设置日期格式
+        println(df.format(Date())) // new Date()为获取当前系统时间
+        return df.format(Date())
+    }
+
+
+} // Object IdUtils

+ 20 - 0
labsl/src/main/resources/application-dev.yml

@@ -0,0 +1,20 @@
+server:
+  port: 8084
+
+spring:
+  datasource:
+#    url:                                jdbc:postgresql://172.16.44.234:5432/datacenter
+#    username:                           postgres
+#    password:                           123456
+#    url:                                jdbc:postgresql://192.168.64.15:5432/datacenter
+#   username:                           postgres
+#   password:                           123qwe!@#
+    type:                               com.alibaba.druid.pool.DruidDataSource
+    driver-class-name:                  org.postgresql.Driver
+    url:                                jdbc:postgresql://8.140.129.63:5432/datacenter
+    username:                           postgres
+#    password:                           persagy_2020qwe!@#
+    password:                           cGVyc2FneV8yMDIwcXdlIUAj
+
+#  activemq:
+#    broker-url:                         tcp://172.16.42.210:61616

+ 33 - 0
labsl/src/main/resources/application-prod.yml

@@ -0,0 +1,33 @@
+server:
+  port: 8834
+#
+#spring:
+#  datasource:
+#
+#    url:                                jdbc:postgresql://v49201.db.redstar.pro:5432/datacenter
+#    username:                           postgres
+#    password:                           123456
+#
+#
+## spring-cloud相关配置
+#eureka:
+#  client:                                   #客户端注册进eureka服务列表内
+#    service-url:
+#      defaultZone:                       http://frame:123456@172.16.46.33:9931/integrated-eureka/eureka/,http://frame:123456@172.16.46.34:9931/integrated-eureka/eureka/
+#      #      defaultZone:                          http://admin:1qaz2wsx@127.0.0.1:8888/eureka/ #增加密码
+#      enable-self-preservation: false # 设为false,关闭自我保护
+#      eviction-interval-timer-in-ms: 5000 # 清理间隔(单位毫秒,默认是60*1000)启用主动失效,
+#  instance:
+#    #不加的话我看过eureka注册界面,是以docker容器的container id注册过去的,譬如container id为abcde,
+#    #那么当访问该微服务时,eureka以http://abcde/xxx,去访问的,当然是访问不到该服务.
+#    #配置下面的选项后,就会以内网ip加端口去访问就能访问到了。
+#    prefer-ip-address: true
+#    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
+
+spring:
+  datasource:
+    #    url:                                jdbc:postgresql://datacenter:5432/datacenter
+    url:                                jdbc:postgresql://192.168.0.72:5432/datacenter
+    #    url:                                jdbc:postgresql://192.168.64.14:5432/datacenterlabsl
+    username:                           postgres
+    password:                           cGVyc2FneV8yMDIwcXdlIUAj

+ 34 - 0
labsl/src/main/resources/application-prod2.yml

@@ -0,0 +1,34 @@
+server:
+  port: 8080
+
+spring:
+  datasource:
+#    url:                                jdbc:postgresql://172.17.11.228:5432/datacenterlabsl
+#    url:                                jdbc:postgresql://192.168.64.14:5432/datacenterlabsl
+#    username:                           postgres
+##    password:                           123qwe!@#
+#    password:                           cGVyc2FneV8yMDIwcXdlIUAj
+
+#  datasource:
+    url:                                jdbc:postgresql://172.17.100.16:5432/datacenter
+    username:                           postgres
+#    password:                           persagy_2020qwe!@#
+    password:                           cGVyc2FneV8yMDIwcXdlIUAj
+
+
+# spring-cloud相关配置
+eureka:
+  client:                                   #客户端注册进eureka服务列表内
+    service-url:
+      #      defaultZone:                          http://192.168.64.18:9931/eureka
+      defaultZone:                                http://frame:123456@39.102.43.179:9931/eureka/
+      #      defaultZone:                                http://frame:123456@192.168.64.18:9931/eureka
+      #      defaultZone:                          http://admin:1qaz2wsx@127.0.0.1:8888/eureka/ #增加密码
+      enable-self-preservation: false # 设为false,关闭自我保护
+      eviction-interval-timer-in-ms: 5000 # 清理间隔(单位毫秒,默认是60*1000)启用主动失效,
+  instance:
+    #不加的话我看过eureka注册界面,是以docker容器的container id注册过去的,譬如container id为abcde,
+    #那么当访问该微服务时,eureka以http://abcde/xxx,去访问的,当然是访问不到该服务.
+    #配置下面的选项后,就会以内网ip加端口去访问就能访问到了。
+    prefer-ip-address: true
+    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

+ 12 - 0
labsl/src/main/resources/application-test.yml

@@ -0,0 +1,12 @@
+server:
+  port: 8087
+
+spring:
+  datasource:
+#    url:                                jdbc:postgresql://datacenter:5432/datacenter
+    url:                                jdbc:postgresql://192.168.0.72:5432/datacenter
+#    url:                                jdbc:postgresql://192.168.64.14:5432/datacenterlabsl
+    username:                           postgres
+    password:                           cGVyc2FneV8yMDIwcXdlIUAj
+
+

+ 71 - 0
labsl/src/main/resources/application.yml

@@ -0,0 +1,71 @@
+###############################################################################################################
+# spring-cloud相关配置
+eureka:
+  client:                                   #客户端注册进eureka服务列表内
+    service-url:
+      defaultZone:                          http://eureka-service:8761/eureka
+#启用监控
+management:
+  endpoints:
+    web:
+      exposure:
+        include:
+          - "*"  # 开放所有端点health,info,metrics,通过actuator/+端点名就可以获取相应的信息。默认打开health和info
+  endpoint:
+    health:
+      #未开启actuator/health时,我们获取到的信息是{"status":"UP"},status的值还有可能是 DOWN。开启后打印详细信息
+      show-details:                       always
+###############################################################################################################
+
+spring:
+  servlet:
+    multipart:
+      enabled: true
+      max-file-size: 10000MB
+      max-request-size: 10000MB
+
+  application:
+    name:                               labsl
+  mvc:
+    favicon:
+      enabled:                          true
+
+  jmx:
+    default-domain:                     labsl
+
+  datasource:
+    name:                               labsl
+    type:                               com.alibaba.druid.pool.DruidDataSource
+    driver-class-name:                  org.postgresql.Driver
+    url:                                jdbc:postgresql://192.168.64.14:5432/datacenterlabsl
+    username:                           postgres
+    password:                           cGVyc2FneV8yMDIwcXdlIUAj
+
+  jackson:
+    date-format:                        yyyy-MM-dd HH:mm:ss
+    time-zone:                          Asia/Shanghai
+    default-property-inclusion:         non_null
+    # 首字母大写
+#    property-naming-strategy:           com.fasterxml.jackson.databind.PropertyNamingStrategy.PascalCaseStrategy
+    # 以下划线分隔全小写的单词
+    property-naming-strategy:           com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy
+    mapper:
+      # 属性按字母顺序输出
+     sort_properties_alphabetically:   true
+
+# spring-doc 配置
+springdoc:
+  # springdoc 扫描的包,多个包之间使用逗号分隔
+  packagesToScan:                           com.persagy.labsl
+  swagger-ui:
+    # API 组排序方式:asc 升序,desc 降序
+    groups-order:                           asc
+    # 标识排序方式:alpha 按字母升序排列
+    tags-sorter:                            alpha
+    # API 接口排序方式:alpha 按字母升序排列,method 按方法的定义顺序。
+    operations-sorter:                      alpha
+
+mybatis:
+  typeAliasesPackage:                   cn.sagacloud.server.datacenter.entities
+
+

+ 38 - 0
labsl/src/main/resources/logback-spring.xml

@@ -0,0 +1,38 @@
+<!--
+  ~ *********************************************************************************************************************
+  ~
+  ~                     :*$@@%$*:                         ;:                ;;    ;;
+  ~                   :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+  ~                  :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+  ~                  =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+  ~                  =@*                                  %!              @ $= % %@=   =%@!      %=
+  ~             *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+  ~           %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+  ~         ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+  ~         $@*   ;@@@%=!:                *@*
+  ~         =@$    ;;;!=%@@@@=!           =@!
+  ~          %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+  ~           ;%@@$=$@@%*       *@@@$=%@@%;
+  ~              ::;::             ::;::                                              All rights reserved.
+  ~
+  ~ *********************************************************************************************************************
+  -->
+
+<configuration scan="true" debug="false">
+    <contextName>scanbuilding</contextName>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{10}) - %cyan(%msg%n)</pattern>
+        </encoder>
+    </appender>
+
+    <!-- 定义cn.sagacloud包的日志级别 -->
+    <logger name="com.persagy" level="debug" additivity="false">
+        <appender-ref ref="STDOUT"/>
+    </logger>
+
+    <!-- 定义日志级别 -->
+    <root level="ERROR">
+        <appender-ref ref="STDOUT" />
+    </root>
+</configuration>

+ 106 - 0
meiku/build.gradle

@@ -0,0 +1,106 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *                     :*$@@%$*:                         ;:                ;;    ;;
+ *                   :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                  :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                  =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                  =@*                                  %!              @ $= % %@=   =%@!      %=
+ *             *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *           %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *         ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *         $@*   ;@@@%=!:                *@*             
+ *         =@$    ;;;!=%@@@@=!           =@!      
+ *          %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           ;%@@$=$@@%*       *@@@$=%@@%;                              
+ *              ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+group rootProject.group
+version rootProject.version
+
+apply plugin: "kotlin"
+apply plugin: "org.jetbrains.dokka"
+apply plugin: "war"
+apply plugin: 'org.springframework.boot'
+apply plugin: 'io.spring.dependency-management'
+
+sourceCompatibility = JVM_TARGET
+
+compileKotlin {
+    kotlinOptions.jvmTarget = JVM_TARGET
+}
+compileTestKotlin {
+    kotlinOptions.jvmTarget = JVM_TARGET
+}
+
+dependencies {
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // kotlin 依赖
+    compile group: "org.jetbrains.kotlin", name: "kotlin-stdlib-jdk8", version: KOTLIN_VERSION
+    compile group: "org.jetbrains.kotlin", name: "kotlin-reflect", version: KOTLIN_VERSION
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // spring boot 依赖
+    compile group: "org.springframework.boot", name: "spring-boot-starter-web", version: SPRING_BOOT_VERSION
+    compile group: "org.springframework.boot", name: "spring-boot-configuration-processor", version: SPRING_BOOT_VERSION
+    compile group: "org.springframework.boot", name: "spring-boot-starter-actuator", version: SPRING_BOOT_VERSION
+    compile group: "org.springframework.boot", name: "spring-boot-starter-logging", version: SPRING_BOOT_VERSION
+    //消息
+//    compile group: "org.springframework.boot", name: "spring-boot-starter-activemq", version: SPRING_BOOT_VERSION
+    providedCompile group: "org.springframework.boot", name:"spring-boot-starter-tomcat", version: SPRING_BOOT_VERSION
+    // spring boot 缓存
+    compile group:"org.springframework.boot", name:"spring-boot-starter-cache", version: SPRING_BOOT_VERSION
+    // 单元测试
+    compile group:"org.springframework.boot", name:"spring-boot-starter-test", version: SPRING_BOOT_VERSION
+
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // spring cloud 依赖
+//    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka', version: SPRING_CLOUD_VERSION
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // MySQL
+    // https://mvnrepository.com/artifact/mysql/mysql-connector-java
+//    compile group: 'mysql', name: 'mysql-connector-java', version: MYSQL_VERSION
+
+//    // PostgreSQL
+//    //https://mvnrepository.com/artifact/org.postgresql/postgresql
+//    compile group: 'org.postgresql',    name: 'postgresql',     version: POSTGRESQL_VERSION
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // RESTful API 文档生成工具
+    // https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui
+    compile group: 'org.springdoc', name: 'springdoc-openapi-ui', version: SPRING_DOC_VERSION
+//     https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-common
+    compile group: "org.springdoc", name: "springdoc-openapi-common", version: SPRING_DOC_VERSION
+    // PlantUML
+    // https://mvnrepository.com/artifact/com.credibledoc/plantuml-core
+    compile group: "com.credibledoc", name: "plantuml-core", version: PLANTUML_VERSION
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // persagy依赖
+    compile group: "com.persagy", name: "persagy-kotlin-base", version: PERSAGY_KOTLIN_VERSION
+    compile group: "com.persagy", name: "persagy-kotlin-database", version: PERSAGY_KOTLIN_VERSION
+    compile group: "com.persagy", name: "persagy-kotlin-mybatis", version: PERSAGY_KOTLIN_VERSION
+    compile group: "com.persagy", name: "persagy-kotlin-mysql", version: PERSAGY_KOTLIN_VERSION
+    compile group: "com.persagy", name: "persagy-service-base", version: PERSAGY_SERVICE_VERSION
+    compile group: "com.persagy", name: "persagy-service-mybatis", version: PERSAGY_SERVICE_VERSION
+
+    // TestNG 测试框架
+    compile group: "org.testng", name: "testng", version: TESTNG_VERSION
+    // Log 工具
+    compile group: "org.projectlombok", name: "lombok", version: LOMBOK_VERSION
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    //Gson
+    compile 'com.google.code.gson:gson:2.8.0'
+
+//    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//    // 二维码与条形码
+//    // https://mvnrepository.com/artifact/com.google.zxing/core
+//    compile group: "com.google.zxing", name: "core", version: ZXING_VERSION
+    
+}

+ 78 - 0
meiku/src/main/kotlin/com/persagy/meiku/MeiKuApp.kt

@@ -0,0 +1,78 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *                     :*$@@%$*:                         ;:                ;;    ;;
+ *                   :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                  :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                  =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                  =@*                                  %!              @ $= % %@=   =%@!      %=
+ *             *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *           %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *         ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *         $@*   ;@@@%=!:                *@*
+ *         =@$    ;;;!=%@@@@=!           =@!
+ *          %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           ;%@@$=$@@%*       *@@@$=%@@%;
+ *              ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+package com.persagy.meiku
+
+import org.mybatis.spring.annotation.MapperScan
+import org.slf4j.LoggerFactory
+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.context.annotation.ComponentScan
+
+
+/**
+ * 应用配置
+ *
+ * @author  Andy
+ */
+@ComponentScan(basePackages = ["com.persagy", "com.persagy.meiku"])           // 配置组件扫描路径
+@MapperScan("com.persagy", "com.persagy.meiku")                       // Mapper组件扫描路径
+@SpringBootApplication
+open class MeiKuApp : SpringBootServletInitializer() {
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(MeiKuApp::class.java)
+    } // Companion object
+
+    /**
+     * 配置应用
+     *
+     * @param   application     应用构建对象
+     */
+    override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
+        return application.sources(MeiKuApp::class.java)
+    } // Function configure
+
+//    /**
+//     * 配置FastJson
+//     *
+//     * @return  HttpMessageConverters
+//     */
+//    @Bean
+//    @Suppress("MoveLambdaOutsideParentheses")
+//    open fun jsonHttpMessageConverters(): SJsonHttpMessageConverter {
+//        val fastConverter = SJsonHttpMessageConverter()
+//        fastConverter.propertyNamingStrategy = com.alibaba.fastjson.PropertyNamingStrategy.CamelCase
+//        return fastConverter
+//    } // Function fastJsonHttpMessageConverters()
+
+} // Class Application
+
+/**
+ * Web应用入口
+ *
+ * @param   args        命令行参数
+ */
+fun main(args: Array<String>) {
+    SpringApplication.run(MeiKuApp::class.java, *args)
+    return
+} // Function main()

+ 149 - 0
meiku/src/main/kotlin/com/persagy/meiku/Swagger3Config.kt

@@ -0,0 +1,149 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *                     :*$@@%$*:                         ;:                ;;    ;;
+ *                   :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                  :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                  =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                  =@*                                  %!              @ $= % %@=   =%@!      %=
+ *             *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *           %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *         ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *         $@*   ;@@@%=!:                *@*
+ *         =@$    ;;;!=%@@@@=!           =@!
+ *          %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           ;%@@$=$@@%*       *@@@$=%@@%;
+ *              ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+package com.persagy.meiku
+
+import io.swagger.v3.oas.annotations.enums.ParameterIn
+import io.swagger.v3.oas.models.Components
+import io.swagger.v3.oas.models.OpenAPI
+import io.swagger.v3.oas.models.Operation
+import io.swagger.v3.oas.models.info.Contact
+import io.swagger.v3.oas.models.info.Info
+import io.swagger.v3.oas.models.info.License
+import io.swagger.v3.oas.models.media.StringSchema
+import io.swagger.v3.oas.models.parameters.Parameter
+import io.swagger.v3.oas.models.security.SecurityScheme
+import org.springdoc.core.GroupedOpenApi
+import org.springdoc.core.customizers.OperationCustomizer
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.context.ApplicationContext
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.method.HandlerMethod
+
+
+/**
+ * RESTful API文档生成器Swagger2配置
+ *
+ * @author  PLX
+ */
+@Configuration
+open class Swagger3Config {
+    /** 注入的 ApplicationContext */
+    @Autowired
+    lateinit var applicationContext: ApplicationContext
+
+    /** 标题 */
+    private val title = "美库(图例库) API"
+    /** API 版本号 */
+    private val version = "1.0"
+
+    val operationCustomizer = GlobalHeaderOperationCustomizer()
+
+
+
+    /**
+     * API 信息
+     */
+    @Bean
+    open fun openApi(): OpenAPI {
+        val contact = Contact().name("张维新").email("zhangweixin@sagacloud.cn")
+        return OpenAPI()
+            .components(
+                Components()
+                .addSecuritySchemes("basicScheme", SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
+            .info(
+                Info()
+                .title(title)
+                .version(version)
+                .termsOfService("http://www.persagy.com")
+                .contact(contact)
+                .license(
+                    License()
+                    .name("Apache 2.0")
+                    .url("http://www.persagy.com")))
+    }
+
+
+    @Bean
+    open fun publicApi(): GroupedOpenApi? {
+        return GroupedOpenApi.builder()
+            .group("默认")
+            .pathsToMatch("/**")
+            .addOperationCustomizer(operationCustomizer)
+            .build()
+    }
+
+
+    @Bean
+    open fun umlApi(): GroupedOpenApi? {
+        return GroupedOpenApi.builder()
+            .group("uml")
+            .pathsToMatch("/uml/**")
+            .build()
+    }
+
+//    /**
+//     * 字典 API 组
+//     */
+//    @Bean
+//    open fun dictApiGroup(): GroupedOpenApi {
+//        return GroupedOpenApi.builder().group("asf").pathsToMatch("")
+//            .build()
+//
+//    }
+
+//    /**
+//     * 对象 API 组
+//     */
+//    @Bean
+//    open fun objectApiGroup(): GroupedOpenApi {
+//        return GroupedOpenApi.builder()
+//            .group("对象")
+//            .pathsToMatch("/object/**")
+//            .addOperationCustomizer(operationCustomizer)
+//            .build()
+//    }
+
+
+
+} // Class Swagger2Config
+
+/**
+ * 全局参数
+ *
+ * @author  庞利祥 <sybotan@126.com>
+ */
+class GlobalHeaderOperationCustomizer : OperationCustomizer {
+    /**
+     * 接口定义器
+     *
+     * @param   operation       接口
+     * @param   handlerMethod   原接口方法
+     * @return  新定义的接口
+     */
+    override fun customize(operation: Operation, handlerMethod: HandlerMethod): Operation {
+        val projectId = Parameter().`in`(ParameterIn.HEADER.toString())
+            .name("projectId").description("项目 id")
+            .schema(StringSchema()).required(false)
+        operation.addParametersItem(projectId)
+        return operation
+    }
+}

+ 68 - 0
meiku/src/main/kotlin/com/persagy/meiku/WebMvcConfg.kt

@@ -0,0 +1,68 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *                     :*$@@%$*:                         ;:                ;;    ;;
+ *                   :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                  :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                  =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                  =@*                                  %!              @ $= % %@=   =%@!      %=
+ *             *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *           %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *         ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *         $@*   ;@@@%=!:                *@*
+ *         =@$    ;;;!=%@@@@=!           =@!
+ *          %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           ;%@@$=$@@%*       *@@@$=%@@%;
+ *              ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+package com.persagy.meiku
+
+//import com.persagy.service.interceptors.SPageInterceptor
+import com.alibaba.fastjson.PropertyNamingStrategy
+import com.persagy.service.interceptors.SPageInterceptor
+import com.persagy.service.json.SJsonHttpMessageConverter
+import org.slf4j.LoggerFactory
+import org.springframework.context.annotation.Configuration
+import org.springframework.http.converter.HttpMessageConverter
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
+
+@Configuration
+open class WebMvcConfg: WebMvcConfigurer {
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(WebMvcConfg::class.java)
+    } // Companion object
+
+    /**
+     * 配置拦截器
+     *
+     * @param   registry        拦截器注册器
+     */
+    override fun addInterceptors(registry : InterceptorRegistry) {
+        //registry.addInterceptor(AccessControlAllowOriginInterceptor()).addPathPatterns("/**")
+        registry.addInterceptor(SPageInterceptor()).addPathPatterns("/**")
+        super.addInterceptors(registry)
+
+    } // Function addInterceptors()
+
+    /**
+     * 配置 json 转换使用 FastJson
+     *
+     * @param   converterList       转换器列表
+     */
+    override fun configureMessageConverters(converterList: MutableList<HttpMessageConverter<*>>) {
+        // 先把JackSon的消息转换器删除.
+        converterList.removeIf { item -> item is MappingJackson2HttpMessageConverter }
+
+        val converter = SJsonHttpMessageConverter()
+        // 设置 Json 序列化,属性首字母小写
+        converter.propertyNamingStrategy = PropertyNamingStrategy.CamelCase
+        converterList.add(converter)
+    }
+} // Class WebMvcConf()

+ 72 - 0
meiku/src/main/kotlin/com/persagy/meiku/controller/MeiKuAnchorController.kt

@@ -0,0 +1,72 @@
+package com.persagy.meiku.controller
+
+import com.persagy.meiku.models.entities.MeiKuAnchor
+import com.persagy.meiku.services.MeiKuAnchorService
+import com.persagy.service.models.requests.SCountRequest
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.requests.SUpdateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCountResponse
+import com.persagy.service.models.responses.SCreateResponse
+import com.persagy.service.models.responses.SQueryResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * 锚点
+ *
+ * @author  wx
+ * @date  2020/9/21 14:50
+ */
+@Tag(name = "002、锚点")
+@RestController
+@RequestMapping("/anchor")
+class MeiKuAnchorController {
+
+    /**
+     * 创建图例
+     */
+    @Operation(summary = "创建锚点-批量", description= "")
+    @PostMapping("/create")
+    fun create(@RequestBody request: SCreateRequest<MeiKuAnchor>): SCreateResponse<MeiKuAnchor> {
+        return MeiKuAnchorService.createList(request)
+    }
+
+    /**
+     * 更新锚点
+     */
+    @Operation(summary = "锚点修改-批量", description = "")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<MeiKuAnchor>): SBaseResponse {
+        return MeiKuAnchorService.updateList(request)
+    }
+
+    /**
+     * 根据id删除锚点
+     */
+    @Operation(summary = "锚点删除", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<MeiKuAnchor>): SBaseResponse {
+        return MeiKuAnchorService.deleteByKeysList(idList)
+    }
+
+    /**
+     * 查询锚点信息
+     */
+    @Operation(summary = "查询锚点-批量", description = "")
+    @PostMapping(value = ["/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<MeiKuAnchor> {
+        return MeiKuAnchorService.pageQuery(request)
+    }
+
+    @Operation(summary = "查询锚点统计", description = "")
+    @PostMapping(value = ["/count"])
+    fun count(@RequestBody request: SCountRequest): SCountResponse {
+        return MeiKuAnchorService.count(request)
+    }
+}

+ 86 - 0
meiku/src/main/kotlin/com/persagy/meiku/controller/MeiKuController.kt

@@ -0,0 +1,86 @@
+package com.persagy.meiku.controller
+
+import com.persagy.meiku.models.entities.MeiKu
+import com.persagy.meiku.models.response.SCommonResponse
+import com.persagy.meiku.services.MeiKuService
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.requests.SUpdateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import com.persagy.service.models.responses.SQueryResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * 图例库接口类
+ *
+ * @author  wx
+ * @date  2020/9/18 21:53
+ */
+@Tag(name = "001、图例库")
+@RestController
+@RequestMapping("/legend")
+class MeiKuController {
+
+    /**
+     * 创建图例
+     */
+    @Operation(summary= "创建图例-批量", description = "不包含状态和锚点")
+    @PostMapping("/create")
+    fun create(@RequestBody request: SCreateRequest<MeiKu>): SCreateResponse<MeiKu> {
+        return MeiKuService.createList(request)
+    }
+
+    /**
+     * 创建图例-单个
+     */
+    @Operation(summary="创建图例-单个", description ="包含状态和锚点")
+    @PostMapping("/save")
+    fun save(@RequestBody meiku: MeiKu): SCreateResponse<MeiKu> {
+        return MeiKuService.save(meiku)
+    }
+
+    /**
+     * 更新图例
+     */
+    @Operation(summary = "图例修改-批量", description = "不包含状态和锚点")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<MeiKu>): SBaseResponse {
+        return MeiKuService.updateList(request)
+    }
+
+    @Operation(summary = "图例修改-单个", description = "包含状态和锚点")
+    @PostMapping(value = ["/revise"])
+    fun revise(@RequestBody meiku: MeiKu): SBaseResponse{
+        return MeiKuService.revise(meiku)
+    }
+
+    /**
+     * 根据id删除图形
+     */
+    @Operation(summary = "图例删除", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<MeiKu>): SBaseResponse {
+        return MeiKuService.deleteByKeysList(idList)
+    }
+
+    /**
+     * 查询图形信息
+     */
+    @Operation(summary = "查询图例-批量", description = " 类型:category   级联:锚点(anchorList)状态:(state)  ")
+    @PostMapping(value = ["/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<MeiKu> {
+        return MeiKuService.pageQuery(request)
+    }
+
+    @Operation(summary = "查询图例-单量", description = "包含状态和锚点")
+    @PostMapping(value = ["/read"])
+    fun read(@RequestBody meiku: MeiKu): SCommonResponse<MeiKu> {
+        return  MeiKuService.read(meiku)
+    }
+}

+ 73 - 0
meiku/src/main/kotlin/com/persagy/meiku/controller/MeiKuStateController.kt

@@ -0,0 +1,73 @@
+package com.persagy.meiku.controller
+
+import com.persagy.meiku.models.entities.MeiKuState
+import com.persagy.meiku.services.MeiKuStateService
+import com.persagy.service.models.requests.SCountRequest
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.requests.SUpdateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCountResponse
+import com.persagy.service.models.responses.SCreateResponse
+import com.persagy.service.models.responses.SQueryResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * 状态
+ *
+ * @author  wx
+ * @date  2020/9/21 14:50
+ */
+@Tag(name = "003、状态")
+@RestController
+@RequestMapping("/state")
+class MeiKuStateController {
+
+    /**
+     * 创建图例
+     */
+    @Operation(summary="创建状态-批量", description = "")
+    @PostMapping("/create")
+    fun create(@RequestBody request: SCreateRequest<MeiKuState>): SCreateResponse<MeiKuState> {
+        return MeiKuStateService.createList(request)
+    }
+
+    /**
+     * 更新状态
+     */
+    @Operation(summary = "状态修改-批量", description = "")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<MeiKuState>): SBaseResponse {
+        return MeiKuStateService.updateList(request)
+    }
+
+    /**
+     * 根据id删除状态
+     */
+    @Operation(summary = "状态删除", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<MeiKuState>): SBaseResponse {
+        return MeiKuStateService.deleteByKeysList(idList)
+    }
+
+    /**
+     * 查询状态信息
+     */
+    @Operation(summary = "查询状态-批量", description = "")
+    @PostMapping(value = ["/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<MeiKuState> {
+        return MeiKuStateService.pageQuery(request)
+    }
+
+    @Operation(summary = "查询状态统计", description = "")
+    @PostMapping(value = ["/count"])
+    fun count(@RequestBody request: SCountRequest): SCountResponse {
+        return MeiKuStateService.count(request)
+    }
+
+}

+ 135 - 0
meiku/src/main/kotlin/com/persagy/meiku/controller/PictureController.kt

@@ -0,0 +1,135 @@
+package com.persagy.meiku.controller
+
+import com.persagy.base.extensions.toJson
+import com.persagy.database.SFilter
+import com.persagy.meiku.models.pic.Picture
+import com.persagy.meiku.services.pic.PictureService
+import com.persagy.service.models.enums.SResponseType
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import lombok.extern.slf4j.Slf4j
+import org.slf4j.LoggerFactory
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.web.bind.annotation.*
+import org.springframework.web.multipart.MultipartFile
+import java.io.IOException
+import java.util.*
+import javax.servlet.ServletOutputStream
+import javax.servlet.http.HttpServletResponse
+
+/**
+ * 图片接口
+ *
+ * @author wx
+ */
+@Tag(name = "006、图片接口")
+@RestController
+@RequestMapping("/picture")
+@Slf4j
+class PictureController {
+
+    companion object {
+        /** 日志 */
+        private val logger = LoggerFactory.getLogger(PictureController::class.java)
+    } // Companion object
+
+    /**
+     * 上传图片
+     *
+     * @param   file         图片文件
+     * @param   uid          图片id
+     * @return              创建结果信息
+     */
+   @Operation(summary = "上传图片", description = "")
+    @PostMapping(value = ["/upload"])
+    fun create(@RequestParam(value = "file", required = true) file: MultipartFile, @RequestParam(required = false) id: String?): SCreateResponse<String> {
+        var response = SCreateResponse<String>()
+        try {
+            val picture = Picture()
+            if(id.isNullOrEmpty()){
+                picture.id = UUID.randomUUID().toString().replace("-","")
+            }else{
+                PictureService.delete(SFilter.eq("id",id!!))
+                picture.id = id
+            }
+            picture.pic = file.bytes
+            logger.debug("name:"+file.name)
+            logger.debug("长度:"+file.size)
+            PictureService.insert(picture)
+            response.result = SResponseType.success
+            response.entityList = arrayListOf(picture.id!!)
+        } catch (e: Exception) {
+            response.result = SResponseType.failure
+            response.message = e.message.toString()
+            e.printStackTrace()
+        }
+        return response
+    } // Function create()
+
+    /**
+     * 根据id删除图片
+     *
+     * @param   idList      id数组
+     * @return              删除的结果信息
+     */
+    @Operation(summary = "根据id删除图片信息", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<Picture>): SBaseResponse {
+        return PictureService.deleteByKeysList(idList)
+    } // Function delete()
+
+    /**
+     * 查询图片信息
+     *
+     * @param   id             查询条件id
+     * @return                 查询结果
+     */
+    @Operation(summary = "查询图片信息", description = "")
+    @GetMapping(value = ["/query/{id}"])
+    fun query(@RequestParam id: String,response: HttpServletResponse) {
+//        val picture = PictureService.select(SFilter.eq("id", id)).entity()
+        val picture = PictureService.customSql.loadPic(id)
+        if(picture!=null){
+            response.contentType = "image/svg+xml;charset=UTF-8"
+            response.addHeader("Accept-Ranges","bytes")
+            // 将图像输出到Servlet输出流中
+            val sos: ServletOutputStream
+            try {
+                response.setContentLength(picture.pic!!.size);
+                sos = response.outputStream
+                sos.write(picture.pic!!)
+                sos.close()
+                response.flushBuffer()
+            } catch (e: IOException) {
+                e.printStackTrace()
+            }
+        }else{
+            throw RuntimeException("图片不存在")
+        }
+        logger.debug(picture?.toJson())
+
+    } // Function query()
+
+    /**
+     * 查询图片信息
+     *
+     * @param   request        查询条件
+     * @return                 查询结果
+     */
+    @Operation(summary = "查询图片信息", description = "")
+    @GetMapping(value = ["/query01/{id}"])
+    fun querys(@PathVariable("id") id: String): ResponseEntity<ByteArray> {
+        val picture = PictureService.customSql.loadPic(id)
+        if(picture!=null){
+            val buffer: ByteArray = Base64.getMimeDecoder().decode(picture.pic!!)
+            return ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(buffer)
+        }else{
+            throw RuntimeException("图片不存在")
+        }
+
+    } // Function query()
+
+} //

+ 76 - 0
meiku/src/main/kotlin/com/persagy/meiku/controller/PipelineController.kt

@@ -0,0 +1,76 @@
+package com.persagy.meiku.controller
+
+import com.persagy.meiku.models.entities.PipelineCategory
+import com.persagy.meiku.services.PipelineCategoryService
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.requests.SUpdateRequest
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import com.persagy.service.models.responses.SQueryResponse
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * 管线接口
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/11/5 10:12
+ */
+@Tag(name = "005、管线类型")
+@RestController
+@RequestMapping("/pipeline")
+class PipelineController {
+
+    /**
+     * 管线
+     *
+     * @param request   待创建管线
+     * @return  创建完成管线
+     */
+    @Operation(summary="创建管线", description ="id 为 32 位 uuid")
+    @PostMapping("/create")
+    fun create(@RequestBody request: SCreateRequest<PipelineCategory>): SCreateResponse<PipelineCategory> {
+        return PipelineCategoryService.createList(request)
+    }
+
+    /**
+     * 根据id删除管线
+     *
+     * @param idList  id数组
+     * @return 删除的结果信息
+     */
+    @Operation(summary = "根据id删除管线", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<PipelineCategory>): SBaseResponse {
+        return PipelineCategoryService.deleteByKeysList(idList)
+    }
+
+    /**
+     * 更新管线
+     *
+     * @param  request   更新的内容对象
+     * @return 更新的结果
+     */
+    @Operation(summary = "更新管线", description = "")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<PipelineCategory>): SBaseResponse {
+        return PipelineCategoryService.updateList(request)
+    }
+
+    /**
+     * 查询管线
+     *
+     * @return 查询结果
+     */
+    @Operation(summary = "查询管线", description = "")
+    @PostMapping(value = ["/query"])
+    fun query(): SQueryResponse<PipelineCategory> {
+        return PipelineCategoryService.categoryQuery()
+    }
+
+}

+ 61 - 0
meiku/src/main/kotlin/com/persagy/meiku/controller/UmlController.kt

@@ -0,0 +1,61 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *               iFHS7.
+ *              ;BBMBMBMc                  rZMBMBR              BMB
+ *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+ *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+ *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+ *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+ *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+ *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+ *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+ *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+ *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+ *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+ *         i0BM: SWKHKGO  MBDv
+ *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2020.  斯伯坦机器人
+ *              ,  XMW  ..
+ *                  r                                                                     All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+package com.persagy.meiku.controller
+
+import com.credibledoc.plantuml.svggenerator.SvgGeneratorService
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.Parameter
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.springframework.web.bind.annotation.*
+import javax.servlet.http.HttpServletResponse
+
+/**
+ * UML 接口
+ *
+ * @author  庞利祥 <sybotan@126.com>
+ */
+@Tag(name = "Uml", description = "UML 图")
+@RestController
+@RequestMapping("/uml/")
+open class UmlController {
+    /**
+     * 获得图像
+     *
+     * @param   plantUml        内容
+     * @param   response        http 应答消息体
+     */
+    @Operation(summary = "UML 的 svg 图")
+    @PostMapping(value = ["/svg"])
+    fun svg(
+            @Parameter(description = "PlantUML 描述")
+            @RequestBody plantUml: String,
+            response: HttpServletResponse) {
+        val svg = SvgGeneratorService.getInstance().generateSvgFromPlantUml(plantUml)
+        response.setHeader("Pragma", "no-cache")
+        response.setHeader("Cache-Control", "no-cache")
+        response.setDateHeader("Expires", 0)
+        response.contentType = "image/svg+xml"
+        response.outputStream.write(svg.toByteArray())
+    }
+}

+ 50 - 0
meiku/src/main/kotlin/com/persagy/meiku/models/entities/MeiKu.kt

@@ -0,0 +1,50 @@
+package com.persagy.meiku.models.entities
+
+import com.persagy.service.models.SBaseEntity
+import com.persagy.service.models.annotations.SCascade
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 图库-美库
+ * @author  wx
+ * @date  2020/9/21 10:45
+ */
+@Schema(description = "锚点")
+@Table(name = "labsl_meiku.meiku")
+class MeiKu : Serializable, SBaseEntity() {
+
+    /** 图id */
+    @Schema(description = "图id")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 分类 */
+    @Schema(description = "分类")
+    @Column(name = "category")
+    var category: String? = null
+
+    /** 品牌 */
+    @Schema(description = "品牌")
+    @Column(name = "brand")
+    var brand: String? = null
+
+    /** 型号 */
+    @Schema(description = "型号")
+    @Column(name = "specification")
+    var specification: String? = null
+
+    /** 锚点列表 */
+    @Schema(description = "锚点列表")
+    @SCascade(table="labsl_meiku.meiku_anchor", idColumn="meiku_id", childIdColumn="id")
+    var anchorList: ArrayList<MeiKuAnchor>? = null
+
+    @Schema(description = "状态")
+    @SCascade(table="labsl_meiku.meiku_state", idColumn="meiku_id", childIdColumn="id")
+    var state: ArrayList<MeiKuState>? = null
+
+} // Class MeiKu

+ 37 - 0
meiku/src/main/kotlin/com/persagy/meiku/models/entities/MeiKuAnchor.kt

@@ -0,0 +1,37 @@
+package com.persagy.meiku.models.entities
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 锚点
+ *
+ * @author  wx
+ * @date  2020/9/21 10:52
+ */
+@Schema(description = "锚点")
+@Table(name = "labsl_meiku.meiku_anchor")
+class MeiKuAnchor: Serializable, SBaseEntity() {
+
+    /** 锚点id */
+    @Schema(description = "锚点id")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 图id */
+    @Schema(description = "图id")
+    @Id
+    @Column(name = "meiku_id")
+    var meiKuId: String? = null
+
+    /** 锚点坐标 */
+    @Schema(description = "锚点坐标")
+    @Column(name = "pos")
+    var pos: Pos? = null
+
+} // Class MeiKuAnchor

+ 41 - 0
meiku/src/main/kotlin/com/persagy/meiku/models/entities/MeiKuState.kt

@@ -0,0 +1,41 @@
+package com.persagy.meiku.models.entities
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 状态
+ * @author  wx
+ * @date  2020/9/21 11:08
+ */
+@Schema(description = "锚点")
+@Table(name = "labsl_meiku.meiku_state")
+class MeiKuState: Serializable, SBaseEntity() {
+
+    /** 状态id */
+    @Schema(description = "状态id")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 图id */
+    @Schema(description = "图id")
+    @Id
+    @Column(name = "meiku_id")
+    var meiKuId: String? = null
+
+    /** 状态内容 */
+    @Schema(description = "状态内容")
+    @Column(name = "state")
+    var state: String? = null
+
+    /** 图片key */
+    @Schema(description = "图片key")
+    @Column(name = "pic")
+    var pic: String? = null
+
+} // class MeiKuState

+ 31 - 0
meiku/src/main/kotlin/com/persagy/meiku/models/entities/ObjectCategory.kt

@@ -0,0 +1,31 @@
+package com.persagy.meiku.models.entities
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 对象类型
+ *
+ * @author  wx
+ * @date  2020/9/21 11:13
+ */
+@Schema(description = "对象类型")
+@Table(name = "labsl_meiku.object_category")
+class ObjectCategory: Serializable, SBaseEntity() {
+
+    /** 图id */
+    @Schema(description = "图id")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 名称 */
+    @Schema(description = "名称")
+    @Column(name = "name")
+    var name: String? = null
+
+} // Class ObjectCategory

+ 43 - 0
meiku/src/main/kotlin/com/persagy/meiku/models/entities/PipelineCategory.kt

@@ -0,0 +1,43 @@
+package com.persagy.meiku.models.entities
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 管线类型
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/11/5 10:12
+ */
+@Schema(description = "管线类型")
+@Table(name = "labsl_meiku.pipeline_category")
+class PipelineCategory: SBaseEntity(), Serializable {
+
+    /** 类型 id */
+    @Schema(description = "类型 id")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 名称 */
+    @Schema(description = "名称")
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 名称 */
+    @Schema(description = "名称")
+    @Column(name = "parent_id")
+    var parentId: String? = null
+
+    /** 颜色 */
+    @Schema(description = "颜色")
+    @Column(name = "color")
+    var color: String? = null
+
+    @Schema(description = "子节点列表")
+    var categoryList: ArrayList<PipelineCategory>? = null
+}

+ 25 - 0
meiku/src/main/kotlin/com/persagy/meiku/models/entities/Pos.kt

@@ -0,0 +1,25 @@
+package com.persagy.meiku.models.entities
+
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+
+/**
+ * 位置信息
+ *
+ * @author wx
+ */
+class Pos : Serializable {
+
+    /** X坐标 */
+    @Schema(description = "X坐标")
+    var x: Double? = null
+
+    /** Y坐标 */
+    @Schema(description = "Y坐标")
+    var y: Double? = null
+
+    /** Z坐标 */
+    @Schema(description = "Z坐标")
+    var z: Double? = null
+
+} // Class Pos

+ 32 - 0
meiku/src/main/kotlin/com/persagy/meiku/models/pic/Picture.kt

@@ -0,0 +1,32 @@
+package com.persagy.meiku.models.pic
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+import java.io.Serializable
+import javax.persistence.Column
+import javax.persistence.Id
+import javax.persistence.Table
+
+/**
+ * 图片实体
+ *
+ * @author  wx
+ */
+@Schema(description = "图片实体")
+@Table(name = "labsl_meiku.picture")
+open class Picture : SBaseEntity(), Serializable {
+
+    private val serialVersionUID = 1L
+    /** id */
+    @Schema(description = "id")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 图片 */
+    @Schema(description = "图片")
+    @Column(name = "pic")
+    var pic: ByteArray? = null
+
+
+}

+ 31 - 0
meiku/src/main/kotlin/com/persagy/meiku/models/response/SCommonResponse.kt

@@ -0,0 +1,31 @@
+package com.persagy.meiku.models.response
+
+import com.persagy.service.models.enums.SResponseType
+import io.swagger.v3.oas.annotations.media.Schema
+
+/**
+ * 返回体
+ * @author  蔡云飞
+ * @date  2020/6/9 14:56
+ */
+open class SCommonResponse<ENTITY: Any>(result: SResponseType? = SResponseType.success, message: String? = null) {
+
+    /** 结果 */
+    @Schema(description = "结果")
+    var result: SResponseType? = SResponseType.failure
+    /** 消息 */
+    @Schema(description = "消息")
+    var message: String? = ""
+
+    /** 结果 */
+    @Schema(description = "结果")
+    var content: ENTITY? = null
+
+    /** 初始化 */
+    init {
+        this.result = result
+        this.message = message
+    } // init()
+
+
+}

+ 30 - 0
meiku/src/main/kotlin/com/persagy/meiku/services/MeiKuAnchorService.kt

@@ -0,0 +1,30 @@
+package com.persagy.meiku.services
+
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.meiku.models.entities.MeiKuAnchor
+import com.persagy.service.SObjectService
+import java.util.*
+
+/**
+ * 锚点服务
+ *
+ * @author  wx
+ * @date  2020/9/21 11:31
+ */
+object MeiKuAnchorService: SObjectService<MeiKuAnchor>(SMybatisDao(MeiKuAnchor::class.java)) {
+
+    /**
+     * 创建之前操作
+     *
+     * @param entity    锚点对象
+     * @return 是否执行
+     */
+    override fun onCreateBefore(entity: MeiKuAnchor): Boolean {
+        /** id 为空赋值 */
+        if (entity.id.isNullOrEmpty()){
+            entity.id = UUID.randomUUID().toString().replace("-", "")
+        }
+        return super.onCreateBefore(entity)
+    }
+
+}

+ 225 - 0
meiku/src/main/kotlin/com/persagy/meiku/services/MeiKuService.kt

@@ -0,0 +1,225 @@
+package com.persagy.meiku.services
+
+import com.persagy.database.SFilter
+import com.persagy.meiku.models.entities.MeiKu
+import com.persagy.meiku.models.response.SCommonResponse
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+import com.persagy.service.models.enums.SResponseType
+import com.persagy.service.models.responses.SBaseResponse
+import com.persagy.service.models.responses.SCreateResponse
+import java.util.*
+
+/**
+ *
+ * @author  wx
+ * @date  2020/9/21 11:21
+ */
+object MeiKuService : SObjectService<MeiKu>(SMybatisDao(MeiKu::class.java)) {
+
+    /**
+     * 创建之前操作
+     *
+     * @param entity    图例对象
+     * @return 是否执行
+     */
+    override fun onCreateBefore(entity: MeiKu): Boolean {
+        /** id 为空,赋值  */
+        if (entity.id.isNullOrEmpty()) {
+            entity.id = UUID.randomUUID().toString().replace("-", "")
+        }
+        return super.onCreateBefore(entity)
+    }
+
+    /**
+     * 保存
+     *
+     * @param meiKu     图例对象
+     * @return 返回结果
+     */
+    fun save(meiKu: MeiKu): SCreateResponse<MeiKu> {
+        /** 返回对象 */
+        val sCreateResponse = SCreateResponse<MeiKu>()
+        return try {
+            /** id 为空赋值 */
+            if (meiKu.id.isNullOrEmpty()) {
+                meiKu.id = UUID.randomUUID().toString().replace("-", "")
+            }
+            /** 插入数据 */
+            val insert = insert(meiKu)
+            /** 锚点列表不为空 */
+            if (!meiKu.anchorList.isNullOrEmpty()) {
+                /** 遍历列表 */
+                for (anchor in meiKu.anchorList!!) {
+                    /** 图例 id */
+                    anchor.meiKuId = meiKu.id
+                    /** 锚点 id 为空赋值 */
+                    if (anchor.id.isNullOrEmpty()) {
+                        anchor.id = UUID.randomUUID().toString().replace("-", "")
+                    }
+                    /** 插入锚点数据 */
+                    val insert1 = MeiKuAnchorService.insert(anchor)
+                }
+            }
+
+            /** 状态 */
+            if (!meiKu.state .isNullOrEmpty()) {
+                val stateList = meiKu.state
+                /** 遍历状态 */
+                for (state in stateList!!){
+                    /** 图例 id */
+                    state!!.meiKuId = meiKu.id
+                    /** 状态 id 为空赋值 */
+                    if (state!!.id.isNullOrEmpty()) {
+                        state!!.id = UUID.randomUUID().toString().replace("-", "")
+                    }
+
+                    /** 插入数据 */
+                    MeiKuStateService.insert(state)
+                }
+            }
+            /** 对象列表 */
+            sCreateResponse.entityList = arrayListOf(meiKu)
+            /** 标志 */
+            sCreateResponse.result = SResponseType.success
+            /** 对象 */
+            sCreateResponse
+        } catch (e: Exception) {
+            e.printStackTrace()
+            sCreateResponse.result = SResponseType.failure
+            sCreateResponse
+        }
+    }
+
+    /**
+     * 单个对象修改,包括下面节点
+     *
+     * @param meiKu     图例对象
+     * @return 返回结果
+     */
+    fun revise(meiKu: MeiKu): SBaseResponse {
+        /** 返回对象 */
+        val sBaseResponse = SBaseResponse()
+        return try {
+            /** 图例id不为空 */
+            if (!meiKu.id.isNullOrEmpty()) {
+                /** 删除图例 */
+                delete(SFilter.eq("id", meiKu.id!!))
+                /** 删除锚点 */
+                MeiKuAnchorService.delete(SFilter.eq("id", meiKu.id!!))
+                /** 删除状态 */
+                MeiKuStateService.delete(SFilter.eq("id", meiKu.id!!))
+                /** 插入数据 */
+                val insert = insert(meiKu)
+                /** 锚点列表不为空 */
+                if (!meiKu.anchorList.isNullOrEmpty()){
+                    /** 遍历 */
+                    for (anchor in meiKu.anchorList!!) {
+                        /** 图例 id */
+                        anchor.meiKuId = meiKu.id
+                        /** 锚点 id 为空赋值 */
+                        if (anchor.id.isNullOrEmpty()) {
+                            anchor.id = UUID.randomUUID().toString().replace("-", "")
+                        }
+                        /** 插入 */
+                        val insert1 = MeiKuAnchorService.insert(anchor)
+                    }
+                }
+                /** 标志不为空 */
+                if (!meiKu.state.isNullOrEmpty()) {
+                    val stateList = meiKu.state
+                    /** 遍历列表 */
+                    for (state in stateList!!){
+
+                        state!!.meiKuId = meiKu.id
+                        /** 标志 id 为空赋值 */
+                        if (state!!.id.isNullOrEmpty()) {
+                            state!!.id = UUID.randomUUID().toString().replace("-", "")
+                        }
+                        /** 插入数据 */
+                        val insert1 = MeiKuStateService.insert(state)
+                    }
+                }
+                /** 状态 */
+                sBaseResponse.result = SResponseType.success
+            } else {
+                /** 状态 */
+                sBaseResponse.result = SResponseType.failure
+            }
+
+            /** 对象 */
+            sBaseResponse
+        } catch (e: Exception) {
+            e.printStackTrace()
+            sBaseResponse.result = SResponseType.failure
+            sBaseResponse.message = e.message.toString()
+            sBaseResponse
+        }
+    }
+
+    /**
+     * 清除节点
+     */
+    override fun onDeleteSuccess(entityList: ArrayList<MeiKu>) {
+        /** 遍历清除的图例 */
+        for (entity in entityList){
+            /** 清除图例下的锚点 */
+            MeiKuAnchorService.delete(SFilter.eq("id", entity.id!!))
+            /** 清除图例下的状态 */
+            MeiKuStateService.delete(SFilter.eq("id", entity.id!!))
+        }
+        super.onDeleteSuccess(entityList)
+    }
+
+    /**
+     * 读取图下面所有节点
+     *
+     * @param meiKu     图例对象
+     * @return 返回结果
+     */
+    fun read(meiKu: MeiKu): SCommonResponse<MeiKu> {
+        /** 返回对象 */
+        val sQueryResponse = SCommonResponse<MeiKu>()
+        return try {
+            /** 图例 id 不可以为空 */
+            if (!meiKu.id.isNullOrEmpty()){
+                /** 查询图例 */
+                val entity = select(SFilter.eq("id", meiKu.id!!)).entity()
+                /** 图例对象不为空 */
+                if (entity!=null){
+                    /** 锚点查询 */
+                    val meiKuAnchorList = MeiKuAnchorService.select(SFilter.eq("id", meiKu.id!!)).exec()
+                    if (meiKuAnchorList.size>0){
+                        entity.anchorList = meiKuAnchorList
+                    }
+
+                    /** 状态查询 */
+                    val meiKuState = MeiKuStateService.select(SFilter.eq("id", meiKu.id!!)).exec()
+                    if (!meiKuState.isNullOrEmpty()){
+                        entity.state = meiKuState
+                    }
+
+                    /** 对象赋值 */
+                    sQueryResponse.content = entity
+                    /** 状态 */
+                    sQueryResponse.result = SResponseType.success
+                }else{
+                    /** 状态 */
+                    sQueryResponse.result = SResponseType.failure
+                }
+            }else{
+                /** 状态 */
+                sQueryResponse.result = SResponseType.failure
+            }
+
+            /** 返回的对象 */
+            sQueryResponse
+        } catch (e: Exception) {
+            e.printStackTrace()
+            sQueryResponse.result = SResponseType.failure
+            sQueryResponse.message = e.message.toString()
+            sQueryResponse
+        }
+    }
+
+}

+ 28 - 0
meiku/src/main/kotlin/com/persagy/meiku/services/MeiKuStateService.kt

@@ -0,0 +1,28 @@
+package com.persagy.meiku.services
+
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.meiku.models.entities.MeiKuState
+import com.persagy.service.SObjectService
+import java.util.*
+
+/**
+ * 状态
+ *
+ * @author  wx
+ * @date  2020/9/21 11:35
+ */
+object MeiKuStateService : SObjectService<MeiKuState>(SMybatisDao(MeiKuState::class.java)) {
+    /**
+     * 创建之前操作
+     *
+     * @param entity    状态对象
+     * @return 是否执行
+     */
+    override fun onCreateBefore(entity: MeiKuState): Boolean {
+        /** id 为空赋值 */
+        if (entity.id.isNullOrEmpty()){
+            entity.id = UUID.randomUUID().toString().replace("-", "")
+        }
+        return super.onCreateBefore(entity)
+    }
+}

+ 65 - 0
meiku/src/main/kotlin/com/persagy/meiku/services/PipelineCategoryService.kt

@@ -0,0 +1,65 @@
+package com.persagy.meiku.services
+
+import com.persagy.database.SFilter
+import com.persagy.meiku.models.entities.MeiKuAnchor
+import com.persagy.meiku.models.entities.PipelineCategory
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+import com.persagy.service.models.enums.SResponseType
+import com.persagy.service.models.responses.SQueryResponse
+import java.util.*
+
+/**
+ * 管线服务
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/11/5 10:17
+ */
+object PipelineCategoryService: SObjectService<PipelineCategory>(SMybatisDao(PipelineCategory::class.java)) {
+
+    /**
+     * 查询管线类型
+     *
+     * @return 返回结果
+     */
+    fun categoryQuery(): SQueryResponse<PipelineCategory>  {
+        return try {
+            /** 返回对象 */
+            val sQueryResponse = SQueryResponse<PipelineCategory>()
+            /** 查询一级节点 */
+            val pipelineCategoryList = select(SFilter.isNull("parentId")).exec()
+            /** 遍历节点 */
+            for (pipelineCategory in pipelineCategoryList){
+                /** 查询子节点 */
+                pipelineCategory.categoryList = select(SFilter.eq("parentId",pipelineCategory.id!!)).exec()
+            }
+
+            /** 类型列表 */
+            sQueryResponse.content = pipelineCategoryList
+            /** 类型长度 */
+            sQueryResponse.total = pipelineCategoryList.size.toLong()
+            /** 类型标志 */
+            sQueryResponse.result = SResponseType.success
+            /** 返回的对象 */
+            sQueryResponse
+        } catch (e: Exception) {
+            e.printStackTrace()
+            SQueryResponse(SResponseType.failure,e.message!!)
+        }
+    }
+
+    /**
+     * 创建之前操作
+     *
+     * @param entity    管线类型对象
+     * @return 是否执行
+     */
+    override fun onCreateBefore(entity: PipelineCategory): Boolean {
+        /** id 为空赋值 */
+        if (entity.id.isNullOrEmpty()){
+            entity.id = UUID.randomUUID().toString().replace("-", "")
+        }
+        return super.onCreateBefore(entity)
+    }
+
+}

+ 20 - 0
meiku/src/main/kotlin/com/persagy/meiku/services/mapper/CustomSql.kt

@@ -0,0 +1,20 @@
+package com.persagy.meiku.services.mapper
+
+import com.persagy.meiku.models.pic.Picture
+import org.apache.ibatis.annotations.Mapper
+import org.apache.ibatis.annotations.Param
+import org.apache.ibatis.annotations.Select
+import org.springframework.stereotype.Repository
+
+/**
+ *
+ * @author wx  <zhangweixin@sagacloud.com>
+ * @date  2020/11/2 17:36
+ */
+@Mapper
+@Repository
+interface CustomSql {
+
+    @Select("SELECT * FROM labsl_meiku.picture WHERE id = #{id}")
+    fun loadPic(@Param("id") id: String): Picture?
+}

+ 31 - 0
meiku/src/main/kotlin/com/persagy/meiku/services/pic/PictureService.kt

@@ -0,0 +1,31 @@
+package com.persagy.meiku.services.pic
+
+import com.persagy.meiku.models.pic.Picture
+import com.persagy.meiku.services.mapper.CustomSql
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+import com.persagy.service.utils.SSpringContextUtil
+import java.util.*
+
+/**
+ *
+ * @author  wx
+ * @date  2020/9/9 16:28
+ */
+object PictureService :  SObjectService<Picture>(SMybatisDao(Picture::class.java)) {
+
+    /** MQ消息对象 */
+    val customSql by lazy {
+        SSpringContextUtil.getBean(CustomSql::class.java) as CustomSql
+    }
+
+    override fun onCreateBefore(entity: Picture): Boolean {
+        entity.id = UUID.randomUUID().toString().replace("-","")
+        return super.onCreateBefore(entity)
+    } // Fun
+
+
+
+
+
+} // Object PictureService

+ 21 - 0
meiku/src/main/resources/application-dev.yml

@@ -0,0 +1,21 @@
+server:
+  port: 8083
+
+spring:
+  datasource:
+#   url:                                jdbc:postgresql://60.205.177.43:5432/datacenter
+#   username:                           postgres
+#   password:                           123qwe!@#
+   url:                                jdbc:postgresql://39.102.40.239:5432/datacenterlabsl
+   username:                           postgres
+#   password:                           persagy_2020qwe!@#
+   password:                           cGVyc2FneV8yMDIwcXdlIUAj
+
+
+  activemq:
+    broker-url:                         tcp://172.16.42.210:61616
+
+
+
+# persagy_2020labsl%#$
+# cGVyc2FneV8yMDIwbGFic2wlIyQ=

+ 50 - 0
meiku/src/main/resources/application-prod.yml

@@ -0,0 +1,50 @@
+server:
+  port: 8834
+
+#spring:
+#  datasource:
+##    url:                                jdbc:postgresql://v49201.db.redstar.pro:5432/datacenter
+##    username:                           postgres
+##    password:                           123456
+#    url:                                jdbc:postgresql://8.140.129.63:5432/datacenter
+#    username:                           postgres
+#    password:                           cGVyc2FneV8yMDIwcXdlIUAj
+#
+## spring-cloud相关配置
+##eureka:
+##  client:                                   #客户端注册进eureka服务列表内
+##    service-url:
+##
+##      defaultZone:                      http://frame:123456@172.16.46.33:9931/integrated-eureka/eureka/,http://frame:123456@172.16.46.34:9931/integrated-eureka/eureka/
+##      enable-self-preservation: false # 设为false,关闭自我保护
+##      eviction-interval-timer-in-ms: 5000 # 清理间隔(单位毫秒,默认是60*1000)启用主动失效,
+##  instance:
+##    #不加的话我看过eureka注册界面,是以docker容器的container id注册过去的,譬如container id为abcde,
+##    #那么当访问该微服务时,eureka以http://abcde/xxx,去访问的,当然是访问不到该服务.
+##    #配置下面的选项后,就会以内网ip加端口去访问就能访问到了。
+##    prefer-ip-address: true
+##    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
+#
+## spring-cloud相关配置
+#eureka:
+#  client:                                   #客户端注册进eureka服务列表内
+#    service-url:
+#      #      defaultZone:                          http://192.168.64.18:9931/eureka
+#      defaultZone:                                http://frame:123456@39.102.43.179:9931/eureka/
+#      #      defaultZone:                                http://frame:123456@192.168.64.18:9931/eureka
+#      #      defaultZone:                          http://admin:1qaz2wsx@127.0.0.1:8888/eureka/ #增加密码
+#      enable-self-preservation: false # 设为false,关闭自我保护
+#      eviction-interval-timer-in-ms: 5000 # 清理间隔(单位毫秒,默认是60*1000)启用主动失效,
+#  instance:
+#    #不加的话我看过eureka注册界面,是以docker容器的container id注册过去的,譬如container id为abcde,
+#    #那么当访问该微服务时,eureka以http://abcde/xxx,去访问的,当然是访问不到该服务.
+#    #配置下面的选项后,就会以内网ip加端口去访问就能访问到了。
+#    prefer-ip-address: true
+#    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
+
+spring:
+  datasource:
+#    url:                                jdbc:postgresql://datacenter:5432/datacenterlabsl
+    url:                                jdbc:postgresql://192.168.0.72:5432/datacenter
+    username:                           postgres
+    password:                           cGVyc2FneV8yMDIwcXdlIUAj

+ 34 - 0
meiku/src/main/resources/application-prod2.yml

@@ -0,0 +1,34 @@
+server:
+  port: 8080
+
+spring:
+  datasource:
+    url:                                jdbc:postgresql://172.17.11.228:5432/datacenterlabsl
+##    url:                                jdbc:postgresql://192.168.64.14:5432/datacenterlabsl
+#    username:                           postgres
+##    password:                           123qwe!@#
+#    password:                           cGVyc2FneV8yMDIwcXdlIUAj
+
+#  datasource:
+#    url:                                jdbc:postgresql://172.17.100.16:5432/datacenterlabsl
+    username:                           postgres
+#    password:                           persagy_2020qwe!@#
+    password:                           cGVyc2FneV8yMDIwcXdlIUAj
+
+
+# spring-cloud相关配置
+eureka:
+  client:                                   #客户端注册进eureka服务列表内
+    service-url:
+      #      defaultZone:                          http://192.168.64.18:9931/eureka
+      defaultZone:                                http://frame:123456@39.102.43.179:9931/eureka/
+      #      defaultZone:                                http://frame:123456@192.168.64.18:9931/eureka
+      #      defaultZone:                          http://admin:1qaz2wsx@127.0.0.1:8888/eureka/ #增加密码
+      enable-self-preservation: false # 设为false,关闭自我保护
+      eviction-interval-timer-in-ms: 5000 # 清理间隔(单位毫秒,默认是60*1000)启用主动失效,
+  instance:
+    #不加的话我看过eureka注册界面,是以docker容器的container id注册过去的,譬如container id为abcde,
+    #那么当访问该微服务时,eureka以http://abcde/xxx,去访问的,当然是访问不到该服务.
+    #配置下面的选项后,就会以内网ip加端口去访问就能访问到了。
+    prefer-ip-address: true
+    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

+ 0 - 0
meiku/src/main/resources/application-test.yml


Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio