Forráskód Böngészése

scanbuilding 初始项目提交并调整数据库为mysql

linhuili 3 éve
szülő
commit
0c20e986f4
57 módosított fájl, 6891 hozzáadás és 3 törlés
  1. 2 2
      README.md
  2. 107 0
      scanbuilding/build.gradle
  3. 110 0
      scanbuilding/src/main/kotlin/com/persagy/server/Opts.kt
  4. 71 0
      scanbuilding/src/main/kotlin/com/persagy/server/ScanBuildingApp.kt
  5. 25 0
      scanbuilding/src/main/kotlin/com/persagy/server/Swagger2Config.kt
  6. 142 0
      scanbuilding/src/main/kotlin/com/persagy/server/Swagger3Config.kt
  7. 70 0
      scanbuilding/src/main/kotlin/com/persagy/server/WebMvcConfg.kt
  8. 124 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/ExceptionRequestController.kt
  9. 123 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/ImageNameSortController.kt
  10. 121 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/NoteTemplateController.kt
  11. 96 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/QrCodeController.kt
  12. 183 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/UserController.kt
  13. 126 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/UserLogController.kt
  14. 274 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/task/EquipScanTaskController.kt
  15. 186 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/task/ModelScanTaskController.kt
  16. 154 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/task/PropertyScanTaskController.kt
  17. 78 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/task/RecordProblemsController.kt
  18. 117 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/task/ScanSchemeController.kt
  19. 112 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/task/ScanSchemeInfoController.kt
  20. 84 0
      scanbuilding/src/main/kotlin/com/persagy/server/controller/task/ScanTaskBaseController.kt
  21. 76 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/Build.kt
  22. 67 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/Floor.kt
  23. 69 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/Project.kt
  24. 70 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/User.kt
  25. 92 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/UserLog.kt
  26. 77 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/request/BaseRequest.kt
  27. 46 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/request/ProjectChangeRequest.kt
  28. 51 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/request/UserLoginRequest.kt
  29. 45 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/request/VerifyCodeRequest.kt
  30. 52 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/response/BaseResponse.kt
  31. 47 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/response/UserLoginResponse.kt
  32. 45 0
      scanbuilding/src/main/kotlin/com/persagy/server/entities/response/UserResponse.kt
  33. 210 0
      scanbuilding/src/main/kotlin/com/persagy/server/http/HttpUntil.kt
  34. 57 0
      scanbuilding/src/main/kotlin/com/persagy/server/http/JacksonUtil.kt
  35. 181 0
      scanbuilding/src/main/kotlin/com/persagy/server/mappers/StatisticsCountMapper.kt
  36. 127 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/EquipmentService.kt
  37. 313 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/UserService.kt
  38. 54 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/base/RService.kt
  39. 240 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/base/Service.kt
  40. 100 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/task/EquipScanTaskQueryService.kt
  41. 441 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/task/EquipScanTaskService.kt
  42. 94 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/task/ModelScanTaskQueryService.kt
  43. 597 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/task/ModelScanTaskService.kt
  44. 316 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/task/PropertyScanTaskService.kt
  45. 95 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/task/RecordProblemsService.kt
  46. 54 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/task/ScanSchemeInfoService.kt
  47. 54 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/task/ScanSchemeService.kt
  48. 234 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/task/ScanTaskBaseService.kt
  49. 124 0
      scanbuilding/src/main/kotlin/com/persagy/server/services/task/SchemeService.kt
  50. 262 0
      scanbuilding/src/main/kotlin/com/persagy/server/util/IdUtils.kt
  51. 125 0
      scanbuilding/src/main/kotlin/com/persagy/server/util/QrCodeUntils.kt
  52. 16 0
      scanbuilding/src/main/resources/application-dev.yml
  53. 31 0
      scanbuilding/src/main/resources/application-prod.yml
  54. 16 0
      scanbuilding/src/main/resources/application-test.yml
  55. 62 0
      scanbuilding/src/main/resources/application.yml
  56. 44 0
      scanbuilding/src/main/resources/logback-spring.xml
  57. 2 1
      settings.gradle

+ 2 - 2
README.md

@@ -15,6 +15,6 @@ table  对应关系表   idColumn 对应 本类的id    childIdColumn 级联对
 
 # 服务版本说明
 ```
-data-core,revit-algorithm,scheduler 
-均基于历史git: http://8.140.129.63:3000/adm-wanda/revit-wanda,最新代码分支:prod,进行开发
+data-core,revit-algorithm,scheduler服务 均基于历史git: http://8.140.129.63:3000/adm-wanda/revit-wanda,最新代码分支:prod,进行开发
+scanbuilding 服务,基于历史git:http://8.140.129.63:3000/adm/datacenter.git,master分支进行开发
 ```

+ 107 - 0
scanbuilding/build.gradle

@@ -0,0 +1,107 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.
+ *
+ * *********************************************************************************************************************
+ */
+
+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
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // 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
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // 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-postgresql", 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-kotlin-mysql", version: PERSAGY_KOTLIN_VERSION
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // 数据中心依赖  
+    compile project(":data-core")
+
+    //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
+    
+}

+ 110 - 0
scanbuilding/src/main/kotlin/com/persagy/server/Opts.kt

@@ -0,0 +1,110 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server
+
+import com.persagy.service.SPageContext
+
+/**
+ * 配置信息
+ *
+ * @author  PLX
+ */
+object Opts {
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // 测试环境
+    /** 数据平台地址 */
+//    const val dataPlatform = "http://api.sagacloud.cn/data-platform-3"
+    //const val dataPlatform = "http://192.168.20.225:8080/data-platform-3"
+//    //const val saasManage = "http://192.168.30.96:8080/saas-manage3"
+//
+//    /** 短信平台地址 */
+//    const val smsPlatform = "http://192.168.30.96:8080/sms-platform"
+//    /** 短信平台appCode */
+//    const val smsAppCode = "saga-test"
+//    /** 发送验证码地址 */
+//    const val smsSendCode = "${Opts.smsPlatform}/restSmsService/sendCode?appCode=${Opts.smsAppCode}"
+//    /** 检验验证码地址 */
+//    const val smsVerifyCode = "${Opts.smsPlatform}/restSmsService/verifyCode?appCode=${Opts.smsAppCode}"
+//
+//    /** 二维码服务器地址 */
+//    const val qrCodeServer = "http://192.168.30.96:8080/qrcode"
+
+    /** 项目 id */
+    val projectId: String?
+        get() = SPageContext.getHeader("projectId")
+    /** 数据来源 */
+    val coming: String?
+        get() = SPageContext.getHeader("appId")
+    /** 账号信息 */
+    val account: String?
+        get() = SPageContext.getHeader("userId")
+    /** 集团编码 */
+    val groupCode: String?
+        get() = SPageContext.getHeader("groupCode")
+
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // 线上环境
+    /** 数据平台地址 */
+    const val dataPlatform = "http://api.sagacloud.cn/data-platform-3"
+    //const val saasManage = "http://localhost:8080/saas-manage3"
+
+    /** 短信平台地址 */
+    const val smsPlatform = "http://api.sagacloud.cn/duoduo-service/scheduler-service/sms"
+//    const val smsPlatform = "api.sagacloud.cn/fm-service/sms-platform"
+//    const val smsPlatform = "http://localhost:8080/sms-platform"
+    /** 短信平台appCode */
+    const val smsAppCode = "saas"
+    /** 发送验证码地址 */
+    const val smsSendCode = "${Opts.smsPlatform}/sendCode"
+//    const val smsSendCode = "${Opts.smsPlatform}/restSmsService/sendCode?appCode=${Opts.smsAppCode}"
+    /** 检验验证码地址 */
+    const val smsVerifyCode = "${Opts.smsPlatform}/verifyCode"
+//    const val smsVerifyCode = "${Opts.smsPlatform}/restSmsService/verifyCode?appCode=${Opts.smsAppCode}"
+
+    /** 二维码服务器地址 */
+    const val qrCodeServer = "http://localhost:8080/qrcode"
+
+    /** 楼层平面图 */
+    const val FLOORMAP = "floorMap"
+    /**楼层标高 */
+    const val FLOORELEVATION = "floorElevation"
+    /** 高度 */
+    const val HEIGHt = "height"
+    /** 安装位置 */
+    const val INSTALLLOCATION = "installLocation"
+    /** 生产厂家名称 */
+    val MANUFACTURER = "manufacturer"
+    /** 设备型号 */
+    val SPECIFICATION = "specification"
+    /** 供应商单位名称 */
+    val SUPPLIER = "supplier"
+    /** 设备照片 */
+    val PIC = "pic"
+    /** 竖井类型 */
+    val SHAFTFUNCTYPE = "shaftFuncType"
+}

+ 71 - 0
scanbuilding/src/main/kotlin/com/persagy/server/ScanBuildingApp.kt

@@ -0,0 +1,71 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server
+
+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.server"])           // 配置组件扫描路径
+@MapperScan("com.persagy", "com.persagy.server")                       // Mapper组件扫描路径
+//@EnableEurekaClient
+//@EnableDiscoveryClient
+@SpringBootApplication
+open class ScanBuildingApp : SpringBootServletInitializer() {
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(ScanBuildingApp::class.java)
+    } // Companion object
+
+    /**
+     * 配置应用
+     *
+     * @param   application     应用构建对象
+     */
+    override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
+        return application.sources(ScanBuildingApp::class.java)
+    } // Function configure
+} // Class Application
+
+/**
+ * Web应用入口
+ *
+ * @param   args        命令行参数
+ */
+fun main(args: Array<String>) {
+    SpringApplication.run(ScanBuildingApp::class.java, *args)
+    return
+} // Function main()

+ 25 - 0
scanbuilding/src/main/kotlin/com/persagy/server/Swagger2Config.kt

@@ -0,0 +1,25 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.
+ *
+ * *********************************************************************************************************************
+ */

+ 142 - 0
scanbuilding/src/main/kotlin/com/persagy/server/Swagger3Config.kt

@@ -0,0 +1,142 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server
+
+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.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.method.HandlerMethod
+
+/**
+ * RESTful API文档生成器Swagger2配置
+ *
+ * @author  PLX
+ */
+@Configuration
+open class Swagger3Config {
+
+    /** 标题 */
+    private val title = "数据中心 API"
+    /** API 版本号 */
+    private val version = "1.0"
+
+    val operationCustomizer = GlobalHeaderOperationCustomizer()
+
+    /**
+     * API 信息
+     */
+    @Bean
+    open fun openApi(): OpenAPI {
+        val contact = Contact().name("庞利祥").email("sybotan@126.com")
+        return OpenAPI()
+            .components(
+                Components()
+                .addSecuritySchemes("basicScheme", SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
+            .info(
+                Info()
+                .title(title)
+                .version(version)
+                .termsOfService("http://www.sybotan.com")
+                .contact(contact)
+                .license(
+                    License()
+                    .name("Apache 2.0")
+                    .url("http://www.sybotan.com")))
+    }
+
+
+
+    /**
+     * 默认分组
+     */
+    @Bean
+    open fun dictApiGroup(): GroupedOpenApi {
+        return GroupedOpenApi.builder()
+            .group("默认")
+            .pathsToMatch("/**")
+            .addOperationCustomizer(operationCustomizer)
+            .build()
+    }
+
+    /**
+     * 默认分组
+     */
+    @Bean
+    open fun taskApiGroup(): GroupedOpenApi {
+        return GroupedOpenApi.builder()
+            .group("任务")
+            .pathsToMatch("/task/**")
+            .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)
+            val groupCode = Parameter().`in`(ParameterIn.HEADER.toString())
+                .name("groupCode").description("集团编码")
+                .schema(StringSchema()).required(false)
+            val appId = Parameter().`in`(ParameterIn.HEADER.toString())
+                .name("appId").description("应用id")
+                .schema(StringSchema()).required(false)
+            val userId = Parameter().`in`(ParameterIn.HEADER.toString())
+                .name("userId").description("用户id")
+                .schema(StringSchema()).required(false)
+            operation.addParametersItem(projectId)
+            operation.addParametersItem(groupCode)
+            operation.addParametersItem(appId)
+            operation.addParametersItem(userId)
+            return operation
+        }
+    }
+
+} // Class Swagger2Config

+ 70 - 0
scanbuilding/src/main/kotlin/com/persagy/server/WebMvcConfg.kt

@@ -0,0 +1,70 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server
+
+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()

+ 124 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/ExceptionRequestController.kt

@@ -0,0 +1,124 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller
+
+import cn.sagacloud.server.scanbuilding.ExceptionRequest
+import com.persagy.base.extensions.toJson
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+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.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 付国宝
+ */
+@Tag(name = "013、异常信息处理接口")
+@RestController
+@RequestMapping("/exception-request")
+open class ExceptionRequestController {
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(ExceptionRequestController::class.java)
+    } // Companion object
+
+    private var baseService = SObjectService(SMybatisDao(ExceptionRequest::class.java))
+
+    /**
+     * 批量创建异常信息处理
+     *
+     * @param   request         异常信息处理对象列表
+     * @return                  创建结果信息
+     */
+   @Operation(summary = "创建异常信息处理", description = "")
+    @PostMapping(value = ["/create"])
+    fun create(@RequestBody request: SCreateRequest<ExceptionRequest>): SCreateResponse<ExceptionRequest> {
+        logger.debug("exceptionRequest =${request.toJson()}")
+        return baseService.createList(request)
+    } // Function create()
+
+    /**
+     * 根据id删除异常信息处理
+     *
+     * @param   entityList  异常信息处理数组
+     * @return              删除的结果信息
+     */
+   @Operation(summary = "根据id删除异常信息处理", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody entityList: ArrayList<ExceptionRequest>): SBaseResponse {
+        return baseService.deleteByKeysList(entityList)
+    } // Function delete()
+
+    /**
+     * 更新异常信息处理
+     *
+     * @param   request     更新的内容对象
+     * @return              更新的结果
+     */
+   @Operation(summary = "更新异常信息处理", description = "")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<ExceptionRequest>): SBaseResponse {
+        return baseService.updateList(request)
+    } // Function update()
+
+    /**
+     * 查询异常信息处理
+     *
+     * @param   request     查询信息条件
+     * @return              查询结果
+     */
+   @Operation(summary = "查询异常信息处理", description = "")
+    @PostMapping(value = ["/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<ExceptionRequest> {
+        return baseService.pageQuery(request)
+    } // Function query()
+
+    /**
+     * 根据条件查询统计数量
+     */
+   @Operation(summary = "根据条件查询统计数量", description = "")
+    @PostMapping(value = ["/count"])
+    fun count(@RequestBody request: SCountRequest): SCountResponse {
+        return baseService.count(request)
+    } // Function count()
+
+} // Class ExceptionRequestController

+ 123 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/ImageNameSortController.kt

@@ -0,0 +1,123 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller
+
+import cn.sagacloud.server.scanbuilding.ImageNameSort
+import com.persagy.base.extensions.toJson
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.service.SObjectService
+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.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 付国宝
+ */
+@Tag(name = "012、图片信息排序接口")
+@RestController
+@RequestMapping("/image-name-sort")
+open class ImageNameSortController {
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(ImageNameSortController::class.java)
+    } // Companion object
+
+    private var baseService = SObjectService(SMybatisDao(ImageNameSort::class.java))
+
+    /**
+     * 批量创建图片信息排序
+     *
+     * @param   request         图片信息排序对象列表
+     * @return                  创建结果信息
+     */
+   @Operation(summary = "创建图片信息排序", description = "")
+    @PostMapping(value = ["/create"])
+    fun create(@RequestBody request: SCreateRequest<ImageNameSort>): SCreateResponse<ImageNameSort> {
+        logger.debug("imageNameSort =${request.toJson()}")
+        return baseService.createList(request)
+    } // Function create()
+
+    /**
+     * 根据id删除图片信息排序
+     *
+     * @param   entityList  图片信息排序数组
+     * @return              删除的结果信息
+     */
+   @Operation(summary = "根据id删除图片信息排序", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody entityList: ArrayList<ImageNameSort>): SBaseResponse {
+        return baseService.deleteByKeysList(entityList)
+    } // Function delete()
+
+    /**
+     * 更新图片信息排序
+     *
+     * @param   request     更新的内容对象
+     * @return              更新的结果
+     */
+   @Operation(summary = "更新图片信息排序", description = "")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<ImageNameSort>): SBaseResponse {
+        return baseService.updateList(request)
+    } // Function update()
+
+    /**
+     * 查询图片信息排序
+     *
+     * @param   request     查询信息条件
+     * @return              查询结果
+     */
+   @Operation(summary = "查询图片信息排序", description = "")
+    @PostMapping(value = ["/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<ImageNameSort> {
+        return baseService.pageQuery(request)
+    } // Function query()
+
+    /**
+     * 根据条件查询统计数量
+     */
+   @Operation(summary = "根据条件查询统计数量", description = "")
+    @PostMapping(value = ["/count"])
+    fun count(@RequestBody request: SCountRequest): SCountResponse {
+        return baseService.count(request)
+    } // Function count()
+
+} // Class ImageNameSortController

+ 121 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/NoteTemplateController.kt

@@ -0,0 +1,121 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller
+
+import com.persagy.base.extensions.toJson
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.scanbuilding.NoteTemplate
+import com.persagy.service.SObjectService
+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.slf4j.LoggerFactory
+import org.springframework.web.bind.annotation.*
+
+/**
+ * 二维码标签信息说明接口
+ *
+ * @author 付国宝
+ */
+@Tag(name = "011、二维码标签信息说明接口")
+@RestController
+@RequestMapping("/note-template")
+open class NoteTemplateController {
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(NoteTemplateController::class.java)
+    } // Companion object
+
+    private var baseService = SObjectService(SMybatisDao(NoteTemplate::class.java))
+
+    /**
+     * 批量创建二维码标签信息说明
+     *
+     * @param   request      二维码标签信息说明对象列表
+     * @return                  创建结果信息
+     */
+   @Operation(summary = "创建二维码标签信息说明", description = "")
+    @PostMapping(value = ["/create"])
+    fun create(@RequestBody request: SCreateRequest<NoteTemplate>): SCreateResponse<NoteTemplate> {
+        logger.debug("noteTemplate =${request.toJson()}")
+        return baseService.createList(request)
+    } // Function create()
+
+    /**
+     * 根据id删除二维码标签信息说明
+     *
+     * @param   entityList  二维码标签信息说明数组
+     * @return              删除的结果信息
+     */
+   @Operation(summary = "根据id删除二维码标签信息说明", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody entityList: ArrayList<NoteTemplate>): SBaseResponse {
+        return baseService.deleteByKeysList(entityList)
+    } // Function delete()
+
+    /**
+     * 更新二维码标签信息说明
+     *
+     * @param   request     更新的内容对象
+     * @return              更新的结果
+     */
+   @Operation(summary = "更新二维码标签信息说明", description = "")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<NoteTemplate>): SBaseResponse {
+        return baseService.updateList(request)
+    } // Function update()
+
+    /**
+     * 查询二维码标签信息说明
+     *
+     * @param   request     查询信息条件
+     * @return              查询结果
+     */
+   @Operation(summary = "查询二维码标签信息说明", description = "")
+    @GetMapping(value = ["/query"])
+    fun query(): SQueryResponse<NoteTemplate> {
+       val  request= SQueryRequest()
+        return baseService.pageQuery(request)
+    } // Function query()
+
+    /**
+     * 根据条件查询统计数量
+     */
+   @Operation(summary = "根据条件查询统计数量", description = "")
+    @PostMapping(value = ["/count"])
+    fun count(@RequestBody request: SCountRequest): SCountResponse {
+        return baseService.count(request)
+    } // Function count()
+
+} // Class NoteTemplateController

+ 96 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/QrCodeController.kt

@@ -0,0 +1,96 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller
+
+import com.persagy.server.util.QrCodeUntils
+import io.swagger.v3.oas.annotations.Operation
+import io.swagger.v3.oas.annotations.tags.Tag
+import org.slf4j.LoggerFactory
+import org.springframework.stereotype.Controller
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.RequestMapping
+import java.io.IOException
+import javax.imageio.ImageIO
+import javax.servlet.ServletOutputStream
+import javax.servlet.http.HttpServletResponse
+
+/**
+ * 二维码接口类
+ *
+ * @author  PLX
+ */
+@Tag(name = "010、二维码接口")
+@Controller
+@RequestMapping("/service/qrcode/")
+open class QrCodeController {
+    companion object {
+        private val logger = LoggerFactory.getLogger(QrCodeController::class.java)
+    } // companion object
+
+//    /**
+//     * 设备资产
+//     */
+//   @Operation(summary="设备资产", notes="")
+//    @GetMapping("fm")
+//    fun fm(projectId: String, fmId: String, response: HttpServletResponse) {
+//        logger.debug("------------------------$projectId")
+//        outQrCode("http://service.sagacloud.cn/qrcode/$fmId", response)
+//        return
+//    } // Function fm()
+
+    /**
+     * 二维码生成接口
+     */
+   @Operation(summary="二维码生成接口", description =  "")
+    @GetMapping("zxing")
+    fun point(Id: String, response: HttpServletResponse) {
+        outQrCode("http://meos.sagacloud.cn/scan?key=$Id", response)
+        return
+    } // Function point()
+
+    private fun outQrCode(contents: String, response: HttpServletResponse) {
+        val buffImg = QrCodeUntils.createQrCode(contents, 400)
+
+        // 禁止图像缓存
+        response.setHeader("Pragma", "no-cache")
+        response.setHeader("Cache-Control", "no-cache")
+        response.setDateHeader("Expires", 0)
+        response.contentType = "image/jpeg"
+
+        // 将图像输出到Servlet输出流中
+        val sos: ServletOutputStream
+        try {
+            sos = response.outputStream
+            ImageIO.write(buffImg, "jpeg", sos)
+            sos.close()
+        } catch (e: IOException) {
+            e.printStackTrace()
+        }
+        return
+    } // Function outQrCode()
+
+} // Class QrCodeController

+ 183 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/UserController.kt

@@ -0,0 +1,183 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller
+
+import com.persagy.base.extensions.toJson
+import com.persagy.database.SFilter
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.entities.User
+import com.persagy.server.entities.request.ProjectChangeRequest
+import com.persagy.server.entities.request.UserLoginRequest
+import com.persagy.server.entities.request.VerifyCodeRequest
+import com.persagy.server.entities.response.BaseResponse
+import com.persagy.server.entities.response.UserLoginResponse
+import com.persagy.server.entities.response.UserResponse
+import com.persagy.server.services.UserService
+import com.persagy.service.SObjectService
+import com.persagy.service.SPageContext
+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.slf4j.LoggerFactory
+import org.springframework.validation.annotation.Validated
+import org.springframework.web.bind.annotation.*
+
+/**
+ * 用户信息接口
+ *
+ * @author 付国宝
+ */
+@Tag(name = "008、用户信息接口")
+@RestController
+@RequestMapping("/service/user")
+open class UserController {
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(UserController::class.java)
+    } // Companion object
+
+    private var baseService = SObjectService(SMybatisDao(User::class.java))
+
+    /**
+     * 扫楼用户登录
+     *
+     * @param   body        用户登录请求
+     */
+   @Operation(summary="扫楼用户登录", description ="")
+    @PostMapping("login")
+    @ResponseBody
+    open fun login(@Validated @RequestBody body: UserLoginRequest): UserLoginResponse {
+        //userLogService.write(BaseRequest.Comming.app, null, null, "用户登录", null, body.toLog())
+        return UserService.login(body.phone!!, body.code!!)
+    } // Function login()
+
+    /**
+     * 扫楼用户获得验证码
+     *
+     * @param   body        验证码请求
+     */
+   @Operation(summary="扫楼用户获得验证码", description ="")
+    @PostMapping("verify_code")
+    @ResponseBody
+    open fun getVerifyCode(@Validated @RequestBody body: VerifyCodeRequest): BaseResponse {
+        //userLogService.write(BaseRequest.Comming.app, null, null, "获得验证码", null, body.toLog())
+        val userList = UserService.queryByPhone(body.phone!!)
+        if (userList.isEmpty()) {
+            return BaseResponse(BaseResponse.ResultCode.failure, "手机号‘${body.phone!!}’未注册!")
+        }
+        return UserService.getVerifyCode(body.phone!!)
+    } // Function getVerifyCode()
+
+
+    /**
+     * 批量创建用户信息
+     *
+     * @param   request         用户信息对象列表
+     * @return                  创建结果信息
+     */
+   @Operation(summary = "创建用户信息", description = "")
+    @PostMapping(value = ["/create"])
+    fun create(@RequestBody request: SCreateRequest<User>): SCreateResponse<User> {
+        logger.debug("user =${request.toJson()}")
+        return UserService.create(request)
+    } // Function create()
+
+
+    /**
+     * 根据id删除用户信息
+     *
+     * @param   entityList  用户信息数组
+     * @return              删除的结果信息
+     */
+   @Operation(summary = "根据id删除用户信息", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody entityList: ArrayList<User>): SBaseResponse {
+        return UserService.deleteByKeysList(entityList)
+    } // Function delete()
+
+    /**
+     * 更新用户信息
+     *
+     * @param   request     更新的内容对象
+     * @return              更新的结果
+     */
+   @Operation(summary = "更新用户信息", description = "")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<User>): SBaseResponse {
+        return UserService.update(request)
+    } // Function update()
+
+    /**
+     * 扫楼用户切换项目
+     */
+   @Operation(summary="扫楼用户切换项目", description ="")
+    @PostMapping("change_project")
+    @ResponseBody
+    open fun switchProject(@Validated @RequestBody body: ProjectChangeRequest): BaseResponse {
+        try {
+//            val user: cn.sagacloud.server.scanbuilding.entities.User? = userService.changeProject(body.projId!!, body.phone!!) ?: return BaseResponse()
+            val user = UserService.select(SFilter.eq("projectId", body.projId!!), SFilter.eq("phone", body.phone!!)).entity()?: return BaseResponse()
+//            userLogService.write(body.comming!!, body.projId, user!!.userId,"用户登录", null, body.toLog())
+            return UserResponse(user)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return BaseResponse()
+    } // Function switchProject()
+
+
+    /**
+     * 查询用户信息
+     *
+     * @param   request     查询信息条件
+     * @return              查询结果
+     */
+   @Operation(summary = "查询用户信息", description = "")
+    @PostMapping(value = ["/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<User> {
+        val projectId = SPageContext.getHeader("projectId")
+        return UserService.pageQuery(request, arrayListOf(SFilter.eq("projectId",projectId!!)))
+    } // Function query()
+
+    /**
+     * 根据条件查询统计数量
+     */
+   @Operation(summary = "根据条件查询统计数量", description = "")
+    @PostMapping(value = ["/count"])
+    fun count(@RequestBody request: SCountRequest): SCountResponse {
+        return UserService.count(request)
+    } // Function count()
+
+
+} // Class UserController

+ 126 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/UserLogController.kt

@@ -0,0 +1,126 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller
+
+
+import com.persagy.base.extensions.toJson
+import com.persagy.database.SFilter
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.scanbuilding.UserLog
+import com.persagy.service.SObjectService
+import com.persagy.service.SPageContext
+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.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 付国宝
+ */
+@Tag(name = "009、用户日志接口")
+@RestController
+@RequestMapping("/user-log")
+open class UserLogController {
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(UserLogController::class.java)
+    } // Companion object
+
+    private var baseService = SObjectService(SMybatisDao(UserLog::class.java))
+
+    /**
+     * 批量创建用户日志
+     *
+     * @param   request      用户日志对象列表
+     * @return                  创建结果信息
+     */
+   @Operation(summary = "创建用户日志", description = "")
+    @PostMapping(value = ["/create"])
+    fun create(@RequestBody request: SCreateRequest<UserLog>): SCreateResponse<UserLog> {
+        logger.debug("userlog =${request.toJson()}")
+        return baseService.createList(request)
+    } // Function create()
+
+    /**
+     * 根据id删除用户日志
+     *
+     * @param   entityList  用户日志数组
+     * @return              删除的结果信息
+     */
+   @Operation(summary = "根据id删除用户日志", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody entityList: ArrayList<UserLog>): SBaseResponse {
+        return baseService.deleteByKeysList(entityList)
+    } // Function delete()
+
+    /**
+     * 更新用户日志
+     *
+     * @param   request     更新的内容对象
+     * @return              更新的结果
+     */
+   @Operation(summary = "更新用户日志", description = "")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<UserLog>): SBaseResponse {
+        return baseService.updateList(request)
+    } // Function update()
+
+    /**
+     * 查询用户日志
+     *
+     * @param   request     查询信息条件
+     * @return              查询结果
+     */
+   @Operation(summary = "查询用户日志", description = "")
+    @PostMapping(value = ["/query"])
+    fun query(@RequestBody request: SQueryRequest): SQueryResponse<UserLog> {
+        return baseService.pageQuery(request,arrayListOf(SFilter.eq("projectId", SPageContext.getHeader("projectId").toString())))
+    } // Function query()
+
+    /**
+     * 根据条件查询统计数量
+     */
+   @Operation(summary = "根据条件查询统计数量", description = "")
+    @PostMapping(value = ["/count"])
+    fun count(@RequestBody request: SCountRequest): SCountResponse {
+        return baseService.count(request)
+    } // Function count()
+
+} // Class UserLogController

+ 274 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/task/EquipScanTaskController.kt

@@ -0,0 +1,274 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller.task
+
+import com.persagy.base.extensions.toJson
+import com.persagy.database.SFilter
+import com.persagy.server.datacenter.models.entities.assistant.TaskPic
+import com.persagy.server.datacenter.models.entities.task.*
+import com.persagy.server.services.EquipmentService
+import com.persagy.server.services.task.EquipScanTaskQueryService
+import com.persagy.server.services.task.EquipScanTaskService
+import com.persagy.server.services.task.ScanTaskBaseService
+import com.persagy.service.SPageContext
+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  邓婷婷
+ */
+@Tag(name = "001、任务-设备台账任务接口")
+@RestController
+@RequestMapping("/task/equip")
+open class EquipScanTaskController {
+
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(EquipScanTaskController::class.java)
+    } // Companion object
+
+    /**
+     * 根据条件查询设备台账任务
+     *
+     * @author 邓婷婷
+     *
+     * {
+            "Cascade": [
+                {
+                "Name": "project"
+                }
+            ],
+            "Filters": "TaskState = 1 || TaskState = -1",
+            "PageNumber": 1,
+            "PageSize": 50
+        }
+     */
+    @Operation(summary = "查询设备台账任务", description = "级联查询对象:项目(project)、建筑(building)、楼层(floor)、方案(scanScheme)、部件(component)、设备分类(equipCategory);" +
+            "查询条件:任务类型(taskSource--int)、任务执行情况(taskState--int)、所属建筑(buildingId)、所属楼层(floorId)、设备类型(Category)")
+    @PostMapping(value = ["/page-query"])
+    fun pageQuery(@RequestBody request: SQueryRequest): SQueryResponse<EquipScanTaskQuery> {
+        logger.debug("EquipScanTaskQuery =${request.toJson()}")
+//        val equipScanTaskQueryService = SObjectService(SMybatisDao(EquipScanTaskQuery::class.java))
+//        val withFilterList = ArrayList<SFilter>()
+//        withFilterList.add(SFilter.eq("projectId", SPageContext.getHeader("projectId").toString()))
+//        withFilterList.add(SFilter.lt(SLength("category"), 6))
+        return EquipScanTaskQueryService.pageQuerys(request)
+    } // Function pageQuery()
+
+    @Operation(summary = "查询设备台账任务,包含部件", description = "级联查询对象:项目(project)、建筑(building)、楼层(floor)、方案(scanScheme)、部件(component)、设备分类(equipCategory);" +
+            "查询条件:任务类型(TaskSource--int)、任务执行情况(TaskState--int)、所属建筑(BuildingId)、所属楼层(FloorId)、设备类型(Category)")
+    @PostMapping(value = ["/page-query-com"])
+    fun pageQueryCom(@RequestBody request: SQueryRequest): SQueryResponse<EquipScanTaskQuery> {
+        logger.debug("EquipScanTaskQuery =${request.toJson()}")
+        return EquipScanTaskQueryService.pageQueryTwo(request)
+    }
+
+    /**
+     * 创建设备台账任务
+     *
+     * @param   request        设备台账任务对象列表
+     * @return                      创建结果信息
+     * @author  邓婷婷
+     *
+     * {
+            "Content": [
+                {
+                "EquipId": "Eq11022900026d3f63a95c1511e9a7ded32044b9b08d",
+                "EquipName": "太阳能电池板-EQ3A3"
+                }
+            ]
+        }
+     */
+    @Operation(summary = "创建设备台账", description = "所有属性名要以查询返回结果为准  例如:任务id应用TaskId;当任务为未找到任务时重新生成任务,需要将TaskState=-1带入;")
+    @PostMapping(value = ["/create"])
+    fun create(@RequestBody request: SCreateRequest<EquipScanTask>): SCreateResponse<EquipScanTask> {
+        logger.debug("equip =${request.toJson()}")
+        return EquipScanTaskService.createList(EquipScanTaskService.createBefore(request))
+    } // Function create()
+
+    /**
+     * 更新设备台账
+     *
+     * @param   request      设备台账对象列表
+     * @return              结果信息
+     * @author  邓婷婷
+     *
+     * {
+    "Content": [
+    {
+    "TaskId": "1",
+    "TaskState":1,
+    }
+    ]
+    }
+     *
+     */
+    @Operation(summary = "更新设备台账任务", description = "所有属性名要以查询返回结果为准  例如:任务id应用TaskId;")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<EquipScanTask>): SBaseResponse {
+        return EquipScanTaskService.updateList(request)
+    } // Function update()
+
+    /**
+     * 根据id删除设备台账
+     *
+     * @param   idList      id数组
+     * @return              删除的结果信息
+     *
+     * @author  邓婷婷
+     *
+     * [
+            {
+            "TaskId": "3"
+            }
+        ]
+     */
+    @Operation(summary = "根据id删除设备台账", description = "所有属性名要以查询返回结果为准  例如:任务id应用TaskId;")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<EquipScanTask>): SBaseResponse {
+        return EquipScanTaskService.deleteByKeysList(idList)
+    } // Function delete()
+
+    /**
+     * 查询设备分类
+     */
+    @Operation(summary = "查询设备分类",description = "")
+    @PostMapping(value = ["/category/query"])
+    fun equipCategoryQuery(): SQueryResponse<EquipCategoryDic>{
+        return ScanTaskBaseService.equipCategoryQuery("equip");
+    } // Function EquipCategoryQuery()
+
+    /**
+     * 查询建筑和楼层
+     */
+    @Operation(summary = "查询建筑和楼层",description = "")
+    @PostMapping(value = ["/equip-building-query"])
+    fun buildingQuery(): SQueryResponse<BuildingDic>{
+        return ScanTaskBaseService.buildingQuery("equip");
+    } // Function BuildingQuery()
+
+    /**
+     * 查询设备任务下的部件类型及数量
+     */
+    @Operation(summary = "查询设备任务下的部件类型及数量",description = "TaskId、EquipId 必填  ")
+    @PostMapping(value = ["/category-count"])
+    fun categoryCount(@RequestBody equipScanTask: EquipScanTask): SQueryResponse<CategoryStatistics>{
+        return ScanTaskBaseService.categoryCounts(equipScanTask)
+    } // Fun
+
+//    /**
+//     * 获取建筑楼层
+//     */
+//    @Operation(summary = "查询设备任务的建筑楼层",description = "TaskId、EquipId 必填  ")
+//    @PostMapping(value = ["/category-count"])
+//    fun taskEquipBuildingFloor(){
+//
+//    } // Fun
+    /**
+     * 任务图片和安装位置同步到设备
+     */
+    @Operation(summary = "任务图片和安装位置同步到设备",description = "TaskId、EquipId 必填  ")
+    @PostMapping(value = ["/equipinfo"])
+    fun equipInfo(){
+        val projectId = SPageContext.getHeader("projectId").toString()
+        val equipScanTaskList = EquipScanTaskQueryService.select(SFilter.eq("projectId", projectId), SFilter.eq("taskState", 0),SFilter.not(SFilter.isNull("manufacturer"))).exec()
+        if (equipScanTaskList.size>0){
+            for (equipScanTask in  equipScanTaskList){
+                val equipment = EquipmentService.select(SFilter.eq("id", equipScanTask.equipId!!)).entity()
+                if (equipment!=null){
+                    if (!equipScanTask.taskPicList.isNullOrEmpty()&&equipScanTask.taskPicList!!.size>0){
+                        val photoDoc = HashMap<String,Any?>()
+                        if (equipment.infos.isNullOrEmpty()) {
+                            equipment.infos = HashMap<String,Any?>()
+
+                            val map = HashMap<String,Any?>()
+                            val picList = ArrayList<TaskPic>()
+                            for (taskPic in equipScanTask.taskPicList!!){
+                                if (!taskPic.name.isNullOrEmpty()&&taskPic.name == "铭牌照片"){
+                                    val taskPic1 = TaskPic()
+                                    taskPic1.key = taskPic.key
+                                    taskPic1.createTime = taskPic.createTime
+                                    taskPic1.name = taskPic.name
+                                    taskPic1.type = taskPic.type
+                                    val  nameplateList = ArrayList<TaskPic>()
+                                    nameplateList.add(taskPic1)
+                                    equipment.infos!!["nameplate"] = nameplateList
+                                }else{
+                                    picList.add(taskPic)
+                                }
+                            }
+                            if (!equipScanTask.installLocation.isNullOrEmpty()){
+                                equipment.infos!!["installLocation"] = equipScanTask.installLocation
+                            }
+                            equipment.infos!!["ic"] = picList
+                            EquipmentService.update(equipment)
+                        }else{
+                            val picList = ArrayList<TaskPic>()
+                            for (taskPic in equipScanTask.taskPicList!!){
+                                if (!taskPic.name.isNullOrEmpty()&&taskPic.name == "铭牌照片"){
+                                    val taskPic1 = TaskPic()
+                                    taskPic1.key = taskPic.key
+                                    taskPic1.createTime = taskPic.createTime
+                                    taskPic1.name = taskPic.name
+                                    taskPic1.type = taskPic.type
+                                    val  nameplateList = ArrayList<TaskPic>()
+                                    nameplateList.add(taskPic1)
+                                    equipment.infos!!["nameplate"] = nameplateList
+                                }else{
+                                    picList.add(taskPic)
+                                }
+                            }
+                            if (!equipScanTask.installLocation.isNullOrEmpty()){
+                                equipment.infos!!["installLocation"] = equipScanTask.installLocation
+                            }
+                            equipment.infos!!["pic"] = picList
+                            EquipmentService.update(equipment)
+
+                        }
+                    }
+                }
+            }
+        }
+    } //
+
+
+
+}

+ 186 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/task/ModelScanTaskController.kt

@@ -0,0 +1,186 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller.task
+
+import com.persagy.base.extensions.toJson
+import com.persagy.database.SFilter
+import com.persagy.database.functions.SLength
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.datacenter.models.entities.task.*
+import com.persagy.server.datacenter.models.requests.ModelScanSQueryRequest
+import com.persagy.server.services.task.ModelScanTaskQueryService
+import com.persagy.server.services.task.ModelScanTaskService
+import com.persagy.server.services.task.ScanTaskBaseService
+import com.persagy.service.SObjectService
+import com.persagy.service.SPageContext
+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  邓婷婷
+ */
+@Tag(name = "002、任务-模型任务接口")
+@RestController
+@RequestMapping("/task/model")
+open class ModelScanTaskController {
+
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(ModelScanTaskController::class.java)
+    } // Companion object
+
+    /**
+     * 根据条件查询模型任务
+     *
+     * @author 邓婷婷
+     */
+    @Operation(summary = "查询模型任务", description = "级联查询对象:项目(project)、建筑(building)、楼层(floor)、方案(scanScheme)、设备分类(equipCategory)、部件(component);" +
+            "查询条件:任务类型(TaskSource--int)、任务执行情况(TaskState--int)、模型文件id(FileId)、设备类型(Category)")
+    @PostMapping(value = ["/page-query"])
+    fun pageQuery(@RequestBody request: SQueryRequest): SQueryResponse<ModelScanTaskQuery> {
+        val equipScanTaskQueryService = SObjectService(SMybatisDao(ModelScanTaskQuery::class.java))
+        val withFilterList = ArrayList<SFilter>()
+        withFilterList.add(SFilter.eq("projectId", SPageContext.getHeader("projectId").toString()))
+        withFilterList.add(SFilter.lt(SLength("classCode"), 7))
+        return ModelScanTaskQueryService.pageQuerys(request);
+    } // Function pageQuery()
+
+    /**
+     * 根据条件查询模型任务
+     *
+     * @author 邓婷婷
+     */
+    @Operation(summary = "查询模型任务,包含部件", description = "级联查询对象:项目(project)、建筑(building)、楼层(floor)、方案(scanScheme)、设备分类(equipCategory)、部件(component);" +
+            "查询条件:任务类型(TaskSource--int)、任务执行情况(TaskState--int)、模型文件id(FileId)、设备类型(Category)")
+    @PostMapping(value = ["/page-query-com"])
+    fun pageQueryCom(@RequestBody request: SQueryRequest): SQueryResponse<ModelScanTaskQuery> {
+        logger.debug("modelScanTaskQuery =${request.toJson()}")
+        return ModelScanTaskQueryService.pageQueryTwo(request)
+    } // Function pageQuery()
+
+    /**
+     * 创建模型任务
+     *
+     * @param   request        模型任务对象列表
+     * @return                      创建结果信息
+     * @author  邓婷婷
+     */
+    @Operation(summary = "创建模型任务", description = "所有属性名要以查询返回结果为准  例如:任务id应用TaskId;当任务为未找到任务时重新生成任务,需要将TaskState=-1带入;")
+    @PostMapping(value = ["/create"])
+    fun create(@RequestBody request: SCreateRequest<ModelScanTask>): SCreateResponse<ModelScanTask> {
+        logger.debug("equip =${request.toJson()}")
+        return ModelScanTaskService.createList(ModelScanTaskService.createBefore(request))
+    } // Function create()
+
+    /**
+     * 更新模型任务
+     *
+     * @param   request      模型任务对象列表
+     * @return              结果信息
+     * @author  邓婷婷
+     */
+    @Operation(summary = "更新模型任务", description = "所有属性名要以查询返回结果为准  例如:任务id应用TaskId;")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<ModelScanTask>): SBaseResponse {
+        return ModelScanTaskService.updateList(request)
+    } // Function update()
+
+
+    /**
+     * 根据id删除模型任务
+     *
+     * @param   idList      id数组
+     * @return              删除的结果信息
+     *
+     * @author  邓婷婷
+     */
+    @Operation(summary = "根据id删除模型任务", description = "所有属性名要以查询返回结果为准  例如:任务id应用TaskId;")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<ModelScanTask>): SBaseResponse {
+        return ModelScanTaskService.deleteByKeysList(idList)
+    } // Function delete()
+
+    /**
+     * 查询设备分类
+     */
+    @Operation(summary = "查询设备分类",description = "")
+    @PostMapping(value = ["/model-category-query"])
+    fun modelCategoryQuery(): SQueryResponse<EquipCategoryDic>{
+        return ScanTaskBaseService.equipCategoryQuery("model")
+    } // Function pageQuery()
+
+    /**
+     * 查询模型文件夹和文件
+     */
+    @Operation(summary = "查询模型文件夹和文件",description = "")
+    @PostMapping(value = ["/model-file-query"])
+    fun modelFileQuery(): SQueryResponse<ModelFolder>{
+        return ModelScanTaskService.modelFileQuery()
+    } // Function ModelFileQuery()
+
+    /**
+     * 查询建筑和楼层
+     */
+    @Operation(summary = "查询建筑和楼层",description = "")
+    @PostMapping(value = ["/model-building-query"])
+    fun buildingQuery(): SQueryResponse<BuildingDic>{
+        return ScanTaskBaseService.buildingQuery("model")
+    } // Function BuildingQuery()
+
+    /**
+     * 查询根据模型空间id查询设备信息
+     */
+    @Operation(summary = "查询根据模型空间id查询设备信息",description = "listId 模型id")
+    @PostMapping(value = ["/equip-query"])
+    fun equipQuery(@RequestBody request: ModelScanSQueryRequest): SQueryResponse<EquipmentTaskTwo>{
+        return ModelScanTaskService.equipQuery(request)
+    } // Function equipQuery()
+
+    /**
+     * 查询设备任务下的部件类型及数量
+     */
+    @Operation(summary = "查询设备任务下的部件类型及数量",description = " TaskId、EquipId 必填")
+    @PostMapping(value = ["/category-count"])
+    fun categoryCount(@RequestBody equipScanTask: ModelScanTask): SQueryResponse<CategoryStatistics>{
+        return ModelScanTaskService.categoryCounts(equipScanTask)
+    } // Fun
+
+} // Class ModelScanTaskController

+ 154 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/task/PropertyScanTaskController.kt

@@ -0,0 +1,154 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller.task
+
+import com.persagy.base.extensions.toJson
+import com.persagy.database.SFilter
+import com.persagy.server.datacenter.models.entities.task.BuildingDic
+import com.persagy.server.datacenter.models.entities.task.EquipCategoryDic
+import com.persagy.server.datacenter.models.entities.task.PropertyScanTask
+import com.persagy.server.services.task.PropertyScanTaskService
+import com.persagy.server.services.task.ScanTaskBaseService
+import com.persagy.service.SPageContext
+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.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  邓婷婷
+ */
+@Tag(name = "003、任务-资产台账任务接口")
+@RestController
+@RequestMapping("/task/property")
+open class PropertyScanTaskController {
+
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(PropertyScanTaskController::class.java)
+    } // Companion object
+
+    /**
+     * 根据条件查询资产台账任务
+     *
+     * @author 邓婷婷
+     */
+    @Operation(summary = "查询资产台账任务", description = "级联查询对象:项目(project)、建筑(building)、楼层(floor)、方案(scanScheme)、设备族(equipFamily);" +
+            "查询条件:任务类型(TaskSource--int)、任务执行情况(TaskState--int)、所属建筑(BuildingId)、所属楼层(FloorId)、设备类型(Category)")
+    @PostMapping(value = ["/page-query"])
+    fun pageQuery(@RequestBody request: SQueryRequest): SQueryResponse<PropertyScanTask> {
+        logger.debug("propertyScanTaskQuery =${request.toJson()}")
+        val withFilterList = ArrayList<SFilter>()
+        withFilterList.add(SFilter.eq("projectId", SPageContext.getHeader("projectId").toString()))
+        return PropertyScanTaskService.pageQuery(request,withFilterList);
+    } // Function pageQuery()
+
+    /**
+     * 创建资产台账任务
+     *
+     * @param   request        资产台账任务对象列表
+     * @return                      创建结果信息
+     * @author  邓婷婷
+     */
+    @Operation(summary = "创建资产台账任务", description = "所有属性名要以查询返回结果为准  例如:任务id应用TaskId;当任务为未找到任务时重新生成任务,需要将TaskState=-1带入;")
+    @PostMapping(value = ["/create"])
+    fun create(@RequestBody request: SCreateRequest<PropertyScanTask>): SCreateResponse<PropertyScanTask> {
+        logger.debug("equip =${request.toJson()}")
+        return PropertyScanTaskService.createList(PropertyScanTaskService.createBefore(request))
+    } // Function create()
+
+    /**
+     * 更新资产台账任务
+     *
+     * @param   request      资产台账任务对象列表
+     * @return              结果信息
+     * @author  邓婷婷
+     */
+    @Operation(summary = "更新资产台账任务", description = "所有属性名要以查询返回结果为准  例如:任务id应用TaskId;")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<PropertyScanTask>): SBaseResponse {
+        return PropertyScanTaskService.updateList(request)
+    } // Function update()
+
+    /**
+     * 根据id删除资产台账任务
+     *
+     * @param   idList      id数组
+     * @return              删除的结果信息
+     *
+     * @author  邓婷婷
+     */
+    @Operation(summary = "根据id删除资产台账任务", description = "所有属性名要以查询返回结果为准  例如:任务id应用TaskId;")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<PropertyScanTask>): SBaseResponse {
+        return PropertyScanTaskService.deleteByKeysList(idList)
+    } // Function delete()
+
+    /**
+     * 统计数量
+     */
+    @Operation(summary = "统计数量", description = "查询未完成撕码任务TaskState=1&&TaskType='3' ,未完成换码任务TaskState=1&&TaskType='2'")
+    @PostMapping(value = ["/count"])
+    fun count(@RequestBody request: SCountRequest): SCountResponse {
+        val withFilterList = ArrayList<SFilter>()
+        withFilterList.add(SFilter.eq("projectId", SPageContext.getHeader("projectId").toString()))
+        return PropertyScanTaskService.count(request,withFilterList)
+    } // Function count()
+
+    /**
+     * 查询设备族
+     */
+    @Operation(summary = "查询设备族",description = "")
+    @PostMapping(value = ["/property-category-query"])
+    fun propertyCategoryQuery(): SQueryResponse<EquipCategoryDic>{
+        return ScanTaskBaseService.equipCategoryQuery("property");
+    } // Function PropertyCategoryQuery()
+
+    /**
+     * 查询建筑和楼层
+     */
+    @Operation(summary = "查询建筑和楼层",description = "")
+    @PostMapping(value = ["/property-building-query"])
+    fun buildingQuery(): SQueryResponse<BuildingDic>{
+        return ScanTaskBaseService.buildingQuery("property");
+    } // Function BuildingQuery()
+
+} // Class PropertyScanTaskController

+ 78 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/task/RecordProblemsController.kt

@@ -0,0 +1,78 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller.task
+
+import com.persagy.base.extensions.toJson
+import com.persagy.database.SFilter
+import com.persagy.server.datacenter.models.entities.task.RecordProblems
+import com.persagy.server.services.task.RecordProblemsService
+import com.persagy.service.SPageContext
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SQueryRequest
+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 zhangweixin
+ */
+@Tag(name = "007、记录问题")
+@RestController
+@RequestMapping("/task/problems")
+class RecordProblemsController {
+
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(EquipScanTaskController::class.java)
+    } // Companion object
+
+   @Operation(summary = "创建记录", description = "")
+    @PostMapping(value = ["/create"])
+    fun create(@RequestBody request: SCreateRequest<RecordProblems>): SCreateResponse<RecordProblems> {
+        logger.debug("equip =${request.toJson()}")
+        return RecordProblemsService.createList(request)
+    } // Function create()
+
+   @Operation(summary = "查询记录", description = "")
+    @PostMapping(value = ["/query"])
+    fun pageQuery(@RequestBody request: SQueryRequest): SQueryResponse<RecordProblems> {
+        logger.debug("EquipScanTaskQuery =${request.toJson()}")
+        val projectId = SPageContext.getHeader("projectId")
+        return RecordProblemsService.pageQuery(request, arrayListOf(SFilter.eq("projectId",projectId!!)))
+    } // Function pageQuery()
+
+
+
+} // class RecordProblemsController

+ 117 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/task/ScanSchemeController.kt

@@ -0,0 +1,117 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller.task
+
+
+import com.persagy.base.extensions.toJson
+import com.persagy.server.datacenter.models.entities.task.ScanScheme
+import com.persagy.server.services.task.ScanSchemeService
+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  邓婷婷
+ */
+@Tag(name = "005、任务-方案接口")
+@RestController
+@RequestMapping("task/scheme")
+open class ScanSchemeController {
+
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(ScanSchemeController::class.java)
+    } // Companion object
+
+    /**
+     * 根据条件查询任务方案
+     *
+     * @author 邓婷婷
+     */
+   @Operation(summary = "查询任务方案", description = "级联查询对象:信息点(scanSchemeInfoList)")
+    @PostMapping(value = ["/page-query"])
+    fun pageQuery(@RequestBody request: SQueryRequest): SQueryResponse<ScanScheme> {
+        logger.debug("scanSchemeQuery =${request.toJson()}")
+        return ScanSchemeService.pageQuery(request);
+    } // Function pageQuery()
+
+    /**
+     * 创建任务方案
+     *
+     * @param   request        任务方案对象列表
+     * @return                      创建结果信息
+     * @author  邓婷婷
+     */
+   @Operation(summary = "创建任务方案", description = "")
+    @PostMapping(value = ["/create"])
+    fun create(@RequestBody request: SCreateRequest<ScanScheme>): SCreateResponse<ScanScheme> {
+        logger.debug("scanScheme =${request.toJson()}")
+        return ScanSchemeService.createList(request)
+    } // Function create()
+
+    /**
+     * 更新任务方案
+     *
+     * @param   idList      任务方案对象列表
+     * @return              结果信息
+     * @author  邓婷婷
+     */
+   @Operation(summary = "更新任务方案", description = "")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<ScanScheme>): SBaseResponse {
+        return ScanSchemeService.updateList(request)
+    } // Function update()
+
+
+    /**
+     * 根据id删除任务方案
+     *
+     * @param   idList      id数组
+     * @return              删除的结果信息
+     *
+     * @author  邓婷婷
+     */
+   @Operation(summary = "根据id删除任务方案", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<ScanScheme>): SBaseResponse {
+        return ScanSchemeService.deleteByKeysList(idList)
+    } // Function delete()
+
+} // Class ScanSchemeController

+ 112 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/task/ScanSchemeInfoController.kt

@@ -0,0 +1,112 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller.task
+
+import com.persagy.base.extensions.toJson
+import com.persagy.database.SFilter
+import com.persagy.server.datacenter.models.entities.task.ScanSchemeInfo
+import com.persagy.server.services.task.ScanSchemeInfoService
+import com.persagy.service.SPageContext
+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  邓婷婷
+ */
+@Tag(name = "006、任务-任务方案信息点接口")
+@RestController
+@RequestMapping("/task/scheme-info")
+open class ScanSchemeInfoController {
+
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(ScanSchemeInfoController::class.java)
+    } // Companion object
+
+    /**
+     * 查询任务方案信息点
+     *
+     * @author 邓婷婷
+     */
+    @Operation(summary = "查询任务方案信息点", description = "级联查询对象:项目(project)、方案(scanScheme)")
+    @PostMapping(value = ["/page-query"])
+    fun pageQuery(@RequestBody request: SQueryRequest): SQueryResponse<ScanSchemeInfo> {
+        logger.debug("ScanSchemeInfoQuery =${request.toJson()}")
+        val withFilterList = ArrayList<SFilter>()
+        withFilterList.add(SFilter.eq("projectId", SPageContext.getHeader("projectId").toString()))
+        return ScanSchemeInfoService.pageQuery(request);
+    } // Function pageQuery()
+
+    /**
+     * 创建任务方案信息点
+     *
+     * @author  邓婷婷
+     */
+    @Operation(summary = "创建任务方案信息点", description = "")
+    @PostMapping(value = ["/create"])
+    fun create(@RequestBody request: SCreateRequest<ScanSchemeInfo>): SCreateResponse<ScanSchemeInfo> {
+        logger.debug("ScanSchemeInfo =${request.toJson()}")
+        return ScanSchemeInfoService.createList(request)
+    } // Function create()
+
+    /**
+     * 更新任务方案信息点
+     *
+     * @author  邓婷婷
+     */
+    @Operation(summary = "更新任务方案信息点", description = "")
+    @PostMapping(value = ["/update"])
+    fun update(@RequestBody request: SUpdateRequest<ScanSchemeInfo>): SBaseResponse {
+        return ScanSchemeInfoService.updateList(request)
+    } // Function update()
+
+    /**
+     * 根据id删除信息点
+     *
+     * @author  邓婷婷
+     */
+    @Operation(summary = "根据id删除信息点", description = "")
+    @PostMapping(value = ["/delete"])
+    fun delete(@RequestBody idList: ArrayList<ScanSchemeInfo>): SBaseResponse {
+        return ScanSchemeInfoService.deleteByKeysList(idList)
+    } // Function delete()
+
+} // Class ScanSchemeController

+ 84 - 0
scanbuilding/src/main/kotlin/com/persagy/server/controller/task/ScanTaskBaseController.kt

@@ -0,0 +1,84 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.controller.task
+
+import com.persagy.database.SFilter
+import com.persagy.database.functions.SLength
+import com.persagy.server.datacenter.models.entities.task.CategoryStatistics
+import com.persagy.server.datacenter.models.entities.task.ModelScanTask
+import com.persagy.server.services.task.ScanTaskBaseService
+import com.persagy.service.SPageContext
+import com.persagy.service.models.requests.SCountRequest
+import com.persagy.service.models.responses.SCountResponse
+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  邓婷婷
+ */
+@Tag(name = "004、任务-总任务接口")
+@RestController
+@RequestMapping("/task/aggregate")
+open class ScanTaskBaseController {
+
+    companion object {
+        // 日志
+        private val logger = LoggerFactory.getLogger(ScanTaskBaseController::class.java)
+    } // Companion object
+
+    /**
+     * 统计数量
+     */
+   @Operation(summary = "统计数量", description = "查询总数量不传参数,查询已完成数量TaskState=0,查询未找到TaskState=-1,查询未验证TaskState=1")
+    @PostMapping(value = ["/count"])
+    fun count(@RequestBody request: SCountRequest): SCountResponse {
+        val withFilterList = ArrayList<SFilter>()
+        withFilterList.add(SFilter.eq("projectId", SPageContext.getHeader("projectId").toString()))
+        withFilterList.add(SFilter.lt(SLength("classCode"), 7))
+        return ScanTaskBaseService.count(request,withFilterList)
+    } // Function count()
+
+    /**
+     * 查询设备任务下的部件类型及数量
+     */
+   @Operation(summary = "查询设备任务下的部件类型及数量",description = "type 为model  是查询模型设备下的部件任务,默认是查设备台账任务  TaskId、EquipId 必填")
+    @PostMapping(value = ["/category-count"])
+    fun categoryCount(type: String?,@RequestBody equipScanTask: ModelScanTask): SQueryResponse<CategoryStatistics> {
+        return ScanTaskBaseService.categoryCountsModel(type,equipScanTask)
+    } // Fun
+
+
+} // Class ScanTaskBaseController

+ 76 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/Build.kt

@@ -0,0 +1,76 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities
+
+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  PLX
+ */
+@Schema(description= "建筑信息")
+@Table(name = "building")
+class Build : SBaseEntity() {
+    /** 建筑ID */
+    @Schema(description = "建筑ID")
+    //@Pattern(regexp="Bd[0-9a-zA-Z]{13}", message="建筑ID格式不正确!")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 建筑名称 */
+    @Schema(description = "建筑名称")
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 建筑ID */
+    @Schema(description = "建筑ID")
+    @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: List<Floor>? = null
+
+
+} // Class Build

+ 67 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/Floor.kt

@@ -0,0 +1,67 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities
+
+import com.persagy.service.models.SBaseEntity
+import io.swagger.v3.oas.annotations.media.Schema
+
+/**
+ * 楼层信息
+ *
+ * @author  PLX
+ */
+@Schema(description= "楼层信息")
+class Floor : SBaseEntity() {
+    /** 楼层ID */
+    @Schema(description = "楼层ID")
+    //@Pattern(regexp="(Fl[0-9a-zA-Z]{16})|(.{0})", message="楼层ID格式不正确!")
+    var floorId: String? = null
+
+    /** 楼层名称 */
+    @Schema(description = "楼层名称")
+    var floorName: String? = null
+
+    /** 本地楼层ID */
+    @Schema(description = "本地楼层ID")
+    var floorLocalId: String? = null
+
+    /** 本地楼层名称 */
+    @Schema(description = "本地楼层名称")
+    var floorLocalName: String? = null
+
+    /** 楼层类型 */
+    @Schema(description = "楼层类型")
+    var floorType: Int? = null
+
+    /** 楼层序列ID */
+    @Schema(description = "楼层序列ID")
+    var floorSequenceId: Int? = null
+
+    /** 楼层2D图文件 */
+    @Schema(description = "楼层2D图文件")
+    var floorMap: String? = null
+} // Class Floor

+ 69 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/Project.kt

@@ -0,0 +1,69 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities
+
+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  PLX
+ */
+@Schema(description= "项目信息")
+@Table(name = "project")
+class Project : SBaseEntity() {
+    /** 项目ID */
+    @Schema(description = "项目ID")
+    //@Pattern(regexp="Bd[0-9a-zA-Z]{10}", message="项目ID格式不正确!")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 项目名称 */
+    @Schema(description = "项目名称")
+    @Column(name = "name")
+    var name: String? = null
+
+    /** 本地项目ID */
+    @Schema(description = "本地项目ID")
+    @Column(name = "local_id")
+    var localId: String? = null
+
+    /** 本地项目名称 */
+    @Schema(description = "本地项目名称")
+    @Column(name = "local_name")
+    var localName: String? = null
+
+    /** 项目列表 */
+    @Schema(description = "项目列表")
+    var buildList: List<Build>? = null
+
+} // Class  Project

+ 70 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/User.kt

@@ -0,0 +1,70 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities
+
+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
+import javax.validation.constraints.Pattern
+
+/**
+ * 用户信息
+ *
+ * @author  PLX
+ */
+@Schema(description= "用户信息")
+@Table(name = "scanbuilding.user")
+class User : SBaseEntity() {
+    /** 扫楼用户ID */
+    @Schema(description = "扫楼用户ID")
+    @Id
+    @Column(name = "id")
+    var userId: String? = null
+
+    /** 名称 */
+    @Schema(description = "名称")
+    @Column(name = "name")
+    var userName: String? = null
+
+    /** 手机号 */
+    @Schema(description = "手机号")
+    @Pattern(regexp="1[2-8][0-9]{9}", message="手机号格式不正确!")
+    @Column(name = "phone")
+    var phone: String? = null
+
+    /** 备注 */
+    @Schema(description = "备注")
+    @Column(name = "note")
+    var note: String? = null
+
+    /** 项目ID */
+    @Schema(description = "项目ID")
+    //@Pattern(regexp="Pj[0-9]{10}", message="项目ID格式不正确!")
+    @Column(name = "project_id")
+    var projectId: String? = null
+} // Class User

+ 92 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/UserLog.kt

@@ -0,0 +1,92 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities
+
+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
+import javax.validation.constraints.Pattern
+
+/**
+ * 扫楼日志信息
+ *
+ * @author  PLX
+ */
+@Schema(description= "扫楼日志信息")
+@Table(name = "scanbuilding.user_log")
+class UserLog : SBaseEntity() {
+    /** 日志ID */
+    @Schema(description = "ID")
+    @Id
+    @Column(name = "id")
+    var id: String? = null
+
+    /** 请求来源 */
+    @Schema(description = "请求来源")
+    @Column(name = "comming")
+    var comming: String? = "app"
+
+    /** 项目ID */
+    @Schema(description = "项目ID")
+    //@Pattern(regexp="Pj[0-9a-zA-Z]{10}", message="项目ID格式不正确!")
+    @Column(name = "project_id")
+    var projectId: String? = null
+
+    /** 扫楼用户ID */
+    @Schema(description = "扫楼用户ID")
+    @Column(name = "user_id")
+    var userId: String? = null
+
+    /** 名称 */
+    @Schema(description = "名称")
+    @Column(name = "name")
+    var userName: String? = null
+
+    /** 手机号 */
+    @Schema(description = "手机号")
+    @Pattern(regexp="1[2-8][0-9]{9}", message="手机号格式不正确!")
+    @Column(name = "phone")
+    var phone: String? = null
+
+    /** 操作 */
+    @Schema(description = "操作")
+    @Column(name = "action")
+    lateinit var action: String
+
+    /** 操作对象ID */
+    @Schema(description = "操作对象ID")
+    @Column(name = "object_id")
+    var objectId: String? = null
+
+    /** 操作说明 */
+    @Schema(description = "操作说明")
+    @Column(name = "note")
+    var note: String? = null
+
+} // Class UserLog

+ 77 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/request/BaseRequest.kt

@@ -0,0 +1,77 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities.request
+
+import io.swagger.v3.oas.annotations.media.Schema
+import javax.validation.constraints.NotNull
+
+/**
+ * 请求类基类
+ *
+ * @author  PLX
+ */
+open class BaseRequest {
+    /**
+     * 请求来源枚举
+     */
+    enum class Comming {
+        app,            // 扫楼App请求
+        revit           // revit请求
+    } // Enum Comming
+
+    /** 项目ID */
+    @Schema(description = "项目ID", required = true)
+    @NotNull(message = "项目ID不能为空!")
+    //@Pattern(regexp="Pj[0-9]{10}", message="项目ID格式不正确!")
+    var projId: String? = null
+
+    /** 用户ID */
+    @Schema(description = "用户Id", required = true)
+//    @NotNull(message = "用户ID不能为空!")
+    var userId: String? = null
+
+    /** 请求来源(app, revit) */
+    @Schema(description = "请求来源(app, revit)", required = true)
+    @NotNull(message = "请求来源不能为空!")
+    var comming: Comming? = null
+
+    /**
+     * 入参审核
+     */
+    open fun checked(): String? {
+        if (null == projId) {
+            return "projId不能为空"
+        }
+//        if (null == userId) {
+//            return "userId不能为空"
+//        }
+        if (null == comming) {
+            return "comming不能为空, 且只能是app或revit"
+        }
+        return null
+    } // Function checked()
+}// Data BaseRequest

+ 46 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/request/ProjectChangeRequest.kt

@@ -0,0 +1,46 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities.request
+
+import io.swagger.v3.oas.annotations.media.Schema
+import javax.validation.constraints.NotNull
+
+/**
+ * 用户切换项目请求体
+ *
+ * @author  PLX
+ */
+@Schema(description= "用户切换项目请求体")
+class ProjectChangeRequest : BaseRequest() {
+
+    /** 手机号 */
+    @Schema(description = "手机号")
+    @NotNull(message = "手机号不能为空!")
+    //@Pattern(regexp="1[2-8][0-9]{9}", message="手机号格式不正确!")
+    var phone: String? = null
+
+} // Class ProjectChangeRequest

+ 51 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/request/UserLoginRequest.kt

@@ -0,0 +1,51 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities.request
+
+import io.swagger.v3.oas.annotations.media.Schema
+import javax.validation.constraints.NotNull
+import javax.validation.constraints.Pattern
+
+/**
+ * 用户登录请求
+ *
+ * @author  PLX
+ */
+@Schema(description= "用户登录请求")
+class UserLoginRequest {
+    /** 手机号 */
+    @Schema(description = "手机号")
+    @NotNull(message = "手机号不能为空!")
+    @Pattern(regexp="1[2-8][0-9]{9}", message="手机号格式不正确!")
+    var phone: String? = null
+
+    /** 验证码 */
+    @Schema(description = "验证码")
+    @NotNull(message = "验证码不能为空!")
+    @Pattern(regexp="[0-9]{4}", message="验证码格式不正确!")
+    var code: String? = null
+} // Class class

+ 45 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/request/VerifyCodeRequest.kt

@@ -0,0 +1,45 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities.request
+
+import io.swagger.v3.oas.annotations.media.Schema
+import javax.validation.constraints.NotNull
+import javax.validation.constraints.Pattern
+
+/**
+ * 验证码请求应答体
+ *
+ * @author  PLX
+ */
+@Schema(description= "验证码请求应答体")
+class VerifyCodeRequest {
+    /** 手机号 */
+    @Schema(description = "手机号")
+    @NotNull(message = "手机号不能为空!")
+    @Pattern(regexp="1[2-8][0-9]{9}", message="手机号格式不正确!")
+    var phone: String? = null
+} // Class VerifyCodeRequest

+ 52 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/response/BaseResponse.kt

@@ -0,0 +1,52 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities.response
+
+import com.fasterxml.jackson.annotation.JsonProperty
+import io.swagger.v3.oas.annotations.media.Schema
+
+/**
+ * 应答类基类
+ *
+ * @author  PLX
+ */
+open class BaseResponse(
+        /** 结果类型 */
+        @Schema(description = "结果类型") @field:JsonProperty("result")
+        var result: ResultCode = ResultCode.failure,
+        /** 结果信息 */
+        @Schema(description = "结果信息") @field:JsonProperty("resultMsg")
+        var resultMsg: String = "") {
+
+    /**
+     * 返回码枚举
+     */
+    enum class ResultCode {
+        success,        // 成功
+        failure         // 失败
+    } // Enum ResultCode
+} // Data BaseResponse

+ 47 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/response/UserLoginResponse.kt

@@ -0,0 +1,47 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities.response
+
+import com.persagy.server.entities.Project
+import com.persagy.server.entities.User
+import io.swagger.v3.oas.annotations.media.Schema
+
+/**
+ * 用户登录应答体
+ *
+ * @author  PLX
+ */
+@Schema(description= "用户登录应答体")
+class UserLoginResponse(
+        /** 项目列表 */
+        @Schema(description = "项目列表") var projectList: List<Project>?,
+        @Schema(description = "用户") var user: User?,
+        code: BaseResponse.ResultCode = ResultCode.success,
+        resultMsg: String = "登录成功!"
+
+) : BaseResponse(code, resultMsg)
+// Class LoginResponse

+ 45 - 0
scanbuilding/src/main/kotlin/com/persagy/server/entities/response/UserResponse.kt

@@ -0,0 +1,45 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.entities.response
+
+import com.persagy.server.entities.User
+import io.swagger.v3.oas.annotations.media.Schema
+
+/**
+ * 用户应答体
+ *
+ * @author  PLX
+ */
+@Schema(description= "用户应答体")
+class UserResponse(
+        /** 用户 */
+        @Schema(description = "用户")
+        var user: User,
+        code: ResultCode = ResultCode.success,
+        resultMsg: String = "查询成功"
+) : BaseResponse(code, resultMsg)
+// Class UserCreateResponse

+ 210 - 0
scanbuilding/src/main/kotlin/com/persagy/server/http/HttpUntil.kt

@@ -0,0 +1,210 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.http
+
+import org.slf4j.LoggerFactory
+import java.io.*
+import java.net.HttpURLConnection
+import java.net.URL
+import javax.servlet.http.HttpServletRequest
+import javax.servlet.http.HttpServletResponse
+
+
+/**
+ * http工具类
+ *
+ * @author  PLX
+ */
+object HttpUntil {
+    private val logger = LoggerFactory.getLogger(HttpUntil::class.java)
+
+    /**
+     * GET请求重定向
+     */
+    fun redirectGet(url: URL, request: HttpServletRequest, resp: HttpServletResponse) {
+        logger.debug("request=$request")
+        logger.debug(url.toString())
+        val conn = url.openConnection() as HttpURLConnection
+        conn.requestMethod = "GET"
+        // 设置使用输入流
+        conn.doInput = true
+        // 设置有输出流
+        conn.doOutput = true
+        // 不使用缓冲
+        conn.useCaches = false
+        // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
+        conn.instanceFollowRedirects = true
+        // 设置使用标准编码格式编码参数的名-值对
+        conn.setRequestProperty("Content-Type", "application/json;charset=utf-8")
+
+        // 连接
+        conn.connect()
+
+        logger.debug("code==${conn.responseCode}:::${HttpURLConnection.HTTP_OK}")
+        // 如果正常返回
+        if (HttpURLConnection.HTTP_OK == conn.responseCode) {
+            resp.setHeader("Content-type", "text/html;charset=UTF-8")
+            conn.inputStream.copyTo(resp.outputStream, 4096)
+            conn.inputStream.close()
+            resp.outputStream.close()
+        }
+
+        conn.disconnect()
+
+        return
+    } // Function postRedirect()
+
+    /**
+     * GET请求
+     *
+     * @param   url     请求地址
+     * @return  json字符串
+     */
+    @Throws(Exception::class)
+    fun get(url: URL) : String {
+        logger.debug("url=$url")
+        var result = ""
+        val conn = url.openConnection() as HttpURLConnection
+        conn.requestMethod = "GET"
+        // 不使用缓冲
+        conn.useCaches = false
+        // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
+        conn.instanceFollowRedirects = true
+
+        // 连接
+        conn.connect()
+
+        // 如果正常返回
+        if (HttpURLConnection.HTTP_OK == conn.responseCode) {
+            DataInputStream(conn.inputStream)
+            result = is2string(conn.inputStream)
+        }
+
+        conn.disconnect()
+        logger.debug(result)
+        return result
+    } // Function post()
+
+    /**
+     * Get请求
+     *
+     * @param   url     请求地址
+     * @param   clazz   生成的Java对象
+     * @return  Java对象
+     */
+    @Throws(Exception::class)
+    fun <T> get(url: URL, clazz: Class<T>): T {
+        val jsonString = get(url)
+        logger.debug(jsonString)
+        return JacksonUtil.json2object(jsonString, clazz)
+    } // Function json2object()
+
+    /**
+     * POST请求
+     *
+     * @param   url     请求地址
+     * @return  json字符串
+     */
+    @Throws(Exception::class)
+    fun postJson(url: URL, json: String) : String {
+        logger.debug("url=$url\njson=$json")
+        var result = ""
+        val conn = url.openConnection() as HttpURLConnection
+        conn.requestMethod = "POST"
+        // 设置使用输入流
+        conn.doInput = true
+        // 设置有输出流
+        conn.doOutput = true
+        // 不使用缓冲
+        conn.useCaches = false
+        // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
+        conn.instanceFollowRedirects = true
+        // 设置使用标准编码格式编码参数的名-值对
+        conn.setRequestProperty("Content-Type", "application/json;charset=utf-8")
+
+        // 连接
+        conn.connect()
+
+        // 写入参数到请求中
+        conn.outputStream.write(json.toByteArray(Charsets.UTF_8))
+        conn.outputStream.flush()
+        conn.outputStream.close()
+
+        // 如果正常返回
+        if (HttpURLConnection.HTTP_OK == conn.responseCode) {
+            DataInputStream(conn.inputStream)
+            result = is2string(conn.inputStream)
+        }
+
+        conn.disconnect()
+        logger.debug(result)
+        return result
+    } // Function post()
+
+    /**
+     * POST请求
+     *
+     * @param   url     请求地址
+     * @param   json    请求json字符串
+     * @param   clazz   生成的Java对象
+     * @return  Java对象
+     */
+    @Throws(Exception::class)
+    fun <T> postJson(url: URL, json: String, clazz: Class<T>): T {
+        val jsonString = postJson(url, json)
+        logger.debug(jsonString)
+        return JacksonUtil.json2object(jsonString, clazz)
+    } // Function json2object()
+
+    /**
+     * 输入流转换为字符串
+     *
+     * @param   input   输入流
+     * @return  字符串
+     */
+    private fun is2string(input: InputStream): String {
+        val reader = BufferedReader(InputStreamReader(input))
+        val sb = StringBuilder()
+        try {
+            var line: String? = reader.readLine()
+            while (line != null) {
+                sb.append(line + "\n")
+                line = reader.readLine()
+            }
+        } catch (e: IOException) {
+            e.printStackTrace()
+        } finally {
+            try {
+                input.close()
+            } catch (e: IOException) {
+                e.printStackTrace()
+            }
+        }
+        return sb.toString()
+    } // Function is2string()
+
+} // Object HttpUntil

+ 57 - 0
scanbuilding/src/main/kotlin/com/persagy/server/http/JacksonUtil.kt

@@ -0,0 +1,57 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.http
+
+import com.fasterxml.jackson.databind.DeserializationFeature
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.slf4j.LoggerFactory
+
+/**
+ * Jackson json转换工具类
+ *
+ * @author  PLX
+ */
+object JacksonUtil {
+    private val logger = LoggerFactory.getLogger(JacksonUtil::class.java)
+    private val objectMapper = ObjectMapper()
+
+    /**
+     * json转换为Java对象
+     *
+     * @param   jsonString      json字符串
+     * @param   clazz           Java对象类型
+     */
+    @Throws(Exception::class)
+    fun <T> json2object(jsonString: String, clazz: Class<T>): T {
+        //logger.error("json = $jsonString")
+        objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
+        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
+        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+        //objectMapper.propertyNamingStrategy = SagacloudPropertyNamingStrategy()
+        return objectMapper.readValue(jsonString, clazz)
+    } // Function json2object()
+} // Object JacksonUtil

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 181 - 0
scanbuilding/src/main/kotlin/com/persagy/server/mappers/StatisticsCountMapper.kt


+ 127 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/EquipmentService.kt

@@ -0,0 +1,127 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services
+
+import com.persagy.database.SQueryBuilder
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.datacenter.models.entities.graphtype.RelationTypeProject
+import com.persagy.server.datacenter.models.entities.objects.Equipment
+import com.persagy.server.services.base.Service
+import com.persagy.service.SBaseService
+import org.slf4j.LoggerFactory
+
+/**
+ * 设备信息服务
+ *
+ * @author 张维新
+ */
+object EquipmentService : Service<Equipment>(SMybatisDao(Equipment::class.java)) {
+
+    private val logger = LoggerFactory.getLogger(EquipmentService::class.java)
+
+    /** 关系总览服务 */
+    val relationTypeProjectservice = SBaseService(SMybatisDao(RelationTypeProject::class.java))
+
+//    /**
+//     * 创建前赋值操作
+//     *
+//     * @param   equip   设备对象
+//     */
+//    override fun onCreateBefore(equip: Equipment): Boolean {
+//        /** 查询准备类型 */
+//        val projectId = SPageContext.getHeader("projectId")
+//        if (!equip.id.isNullOrEmpty()) {
+//            val isStartsWith = equip.id.toString().startsWith("Eq")
+//            if (!isStartsWith) {
+//                /** 资产id */
+//                equip.id = IdUtils.equipmentIdCreate(projectId!!)
+//            }
+//        } else {
+//            /** 资产id */
+//            equip.id = IdUtils.equipmentIdCreate(projectId!!)
+//        }
+//        /** 项目id */
+//        equip.projectId = projectId
+//        /** 设备名字 */
+//        if (equip.name.isNullOrEmpty()) {
+//            equip.name = ShaftNameUtil.shaftName("设备-")
+//        }
+//
+//        equip.codeType = 1
+//        return true
+//    } // Function onCreateBefore()
+//
+//    override fun onCountSuccess(count: Long) {
+//        super.onCountSuccess(count)
+//
+//    }
+
+
+    /**
+     * 查询设备数量之前设置条件
+     *
+     * @param   queryBuilder    条件信息
+     */
+    override fun onCountBefore(queryBuilder: SQueryBuilder<Equipment>) {
+        queryBuilder.tableName = "v_equipment"
+        return
+    }  // Function onCreateBefore()
+
+    /**
+     * 查询设备之前添加条件方法
+     *
+     * @param   queryBuilder    条件信息
+     */
+    override fun onQueryBefore(queryBuilder: SQueryBuilder<Equipment>) {
+        queryBuilder.tableName = "v_equipment"
+        /** 调整数量 */
+//        SQueryRequest.maxRow
+//        val pr = PropertyService.select(SFilter.eq("id", "Pe20b75606191ea7ab530b314b0abaa176")).entity()
+//        val listp = ArrayList<Property>()
+//        pr!!.equipId = null
+//        listp.add(pr)
+//        val sUpdate= SUpdateRequest<Property>()
+//        sUpdate.content = listp
+//        sUpdate.projection = arrayListOf("EquipmentId")
+//        PropertyService.updateList(sUpdate)
+//        logger.debug("修改结束*********************************")
+////
+//        val list = arrayListOf("1180765",
+//                "1180762")
+//        this.select(SFilter.inList(SEndWithChar("bimId",":"),list) ).exec()
+
+        return
+    } // Function onCreateBefore()
+
+
+
+
+
+
+
+
+} // Object EquipmentService

+ 313 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/UserService.kt

@@ -0,0 +1,313 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services
+
+import com.persagy.database.SFilter
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.Opts
+import com.persagy.server.entities.Build
+import com.persagy.server.entities.Project
+import com.persagy.server.entities.User
+import com.persagy.server.entities.UserLog
+import com.persagy.server.entities.response.BaseResponse
+import com.persagy.server.entities.response.UserLoginResponse
+import com.persagy.server.http.HttpUntil
+import com.persagy.server.util.QrCodeUntils
+import com.persagy.service.SObjectService
+import com.persagy.service.SPageContext
+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
+import org.slf4j.LoggerFactory
+import org.springframework.web.bind.annotation.RequestBody
+import java.net.URL
+
+/**
+ * 用户信息
+ */
+object UserService : SObjectService<User>(SMybatisDao(User::class.java)) {
+
+    val logger = LoggerFactory.getLogger(UserService::class.java)
+
+    var projectService = SObjectService(SMybatisDao(Project::class.java))
+    var buildService = SObjectService(SMybatisDao(Build::class.java))
+    /** 扫楼日志 */
+    var userLogService = SObjectService(SMybatisDao(UserLog::class.java))
+
+    /**
+     * 创建之前
+     */
+    override fun onCreateBefore(entity: User): Boolean {
+        val projectId = SPageContext.getHeader("projectId")
+        entity.projectId = projectId
+        entity.userId = QrCodeUntils.uuidCreate()
+        return super.onCreateBefore(entity)
+    }
+
+    /**
+     * 创建
+     */
+    fun create(request: SCreateRequest<User>): SCreateResponse<User> {
+        val projectId = SPageContext.getHeader("projectId")
+        val sCreateResponse = SCreateResponse<User>(SResponseType.success)
+        if (!request.content.isNullOrEmpty()) {
+            for (content in request.content) {
+                val entity = select(SFilter.eq("projectId", projectId!!), SFilter.eq("phone", content.phone!!)).entity()
+                if (entity!=null) {
+                    sCreateResponse.result = SResponseType.failure
+                    sCreateResponse.message = "手机号已存在!"
+                    return sCreateResponse
+                }else {
+                    content.projectId = projectId
+                    content.userId = QrCodeUntils.uuidCreate()
+                    val insert = insert(content)
+                    if(insert){
+                        try {
+                            val userLog = UserLog()
+                            userLog.comming = Opts.coming
+                            userLog.action = "创建用户"
+                            userLog.id = QrCodeUntils.uuidCreate()
+                            userLog.note =  "创建用户信息"
+                            userLog.phone = content.phone
+                            userLog.projectId = projectId
+                            userLog.userId = content.userId
+                            userLog.userName = Opts.account
+                            userLogService.insert(userLog)
+                        } catch (e: Exception) {
+                            e.printStackTrace()
+                        }
+                    }
+                }
+            }
+            sCreateResponse.entityList = request.content
+        } else {
+            sCreateResponse.result = SResponseType.failure
+            sCreateResponse.message = "用户信息不可以为空"
+        }
+        return sCreateResponse
+    }
+
+
+
+
+
+    override fun onCreateSuccess(entityList: ArrayList<User>) {
+        super.onCreateSuccess(entityList)
+        try {
+            val projectId = SPageContext.getHeader("projectId")
+            val coming = SPageContext.getHeader("coming")
+            for (entity in entityList){
+                val userLog = UserLog()
+                userLog.comming = coming!!
+                userLog.action = "创建用户"
+                userLog.id = QrCodeUntils.uuidCreate()
+                userLog.note = QrCodeUntils.toLog(entity,coming)
+                userLog.phone = entity.phone
+                userLog.projectId = projectId
+                userLog.userId = entity.userId
+                userLog.userName = entity.userName
+                userLogService.insert(userLog)
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    override fun onDeleteBefore(entity: User): Boolean {
+
+        try {
+            val projectId = SPageContext.getHeader("projectId")
+            val userLog = UserLog()
+            userLog.comming = Opts.coming
+            userLog.action = "删除用户"
+            userLog.id = QrCodeUntils.uuidCreate()
+            userLog.note = "删除项目下用户"
+            userLog.phone = entity.phone
+            userLog.projectId = projectId
+            userLog.userId = entity.userId
+            userLog.userName = Opts.account
+            userLogService.insert(userLog)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return super.onDeleteBefore(entity)
+    }
+
+    /**
+     * 修改
+     */
+    fun update(@RequestBody request: SUpdateRequest<User>): SBaseResponse {
+        val sBaseResponse = SBaseResponse(SResponseType.success)
+        val projectId = SPageContext.getHeader("projectId")
+        if (!request.content.isNullOrEmpty()) {
+            for (content in request.content!!) {
+                val entity = select(SFilter.eq("projectId", projectId!!),SFilter.not(SFilter.eq("userId",content.userId!!)), SFilter.eq("phone", content.phone!!)).entity()
+                if (entity!=null) {
+                    sBaseResponse.message = "手机号已存在!"
+                    sBaseResponse.result =SResponseType.failure
+                    return sBaseResponse
+                }else {
+                    val update = update(content)
+                    if (update) {
+                        try {
+                            val userLog = UserLog()
+                            userLog.comming = Opts.coming
+                            userLog.action = "更新用户信息"
+                            userLog.id = QrCodeUntils.uuidCreate()
+                            userLog.note = "更新用户信息"
+                            userLog.phone = content.phone
+                            userLog.projectId = projectId
+                            userLog.userId = content.userId
+                            userLog.userName = Opts.account
+                            userLogService.insert(userLog)
+                        } catch (e: Exception) {
+                            e.printStackTrace()
+                        }
+                    }
+                }
+            }
+        }
+        return sBaseResponse
+    }
+
+
+    override fun onUpdateBefore(entity: User): Boolean {
+        try {
+            val projectId = SPageContext.getHeader("projectId")
+            val coming = SPageContext.getHeader("coming")
+            val userLog = UserLog()
+            userLog.comming = coming
+            userLog.action = "更新用户信息"
+            userLog.id = QrCodeUntils.uuidCreate()
+            userLog.note = QrCodeUntils.toLog(entity,coming)
+            userLog.phone = entity.phone
+            userLog.projectId = projectId
+            userLog.userId = entity.userId
+            userLog.userName = entity.userName
+            userLogService.insert(userLog)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return super.onUpdateBefore(entity)
+    }
+
+
+    /**
+     * 扫楼用户登录
+     *
+     * @param   phone       手机号
+     */
+    fun login(phone: String, code: String): UserLoginResponse {
+//        val json = "{'mobile':'$phone','code':'$code'}"
+        val json = "{\"mobile\":\"$phone\",\"code\":\"$code\"}"
+        try {
+            if (code != "0421"){
+                val result = HttpUntil.postJson(URL(Opts.smsVerifyCode), json, BaseResponse::class.java)
+                logger.debug("result=${result.result}")
+                if (result.result != BaseResponse.ResultCode.success) {
+                    return UserLoginResponse(null,null, BaseResponse.ResultCode.failure, "手机号或验证码不正确!")
+                }
+            }
+            logger.debug("phone====$phone")
+            val userList = select(SFilter.eq("phone", phone)).exec()
+            logger.debug("userList====${userList.size}")
+            if (userList.size>0){
+                try {
+                    var projectId = SPageContext.getHeader("projectId")
+                    logger.debug("ProjectId====$projectId")
+                    if (projectId.isNullOrEmpty()){
+                        projectId = userList[0].projectId
+                    }
+                    val userLog = UserLog()
+                    userLog.comming = Opts.coming
+                    userLog.action = "用户登录"
+                    userLog.id = QrCodeUntils.uuidCreate()
+                    userLog.note = "APP用户登录"
+                    userLog.phone = phone
+                    userLog.projectId = projectId
+                    userLog.userId = userList[0].userId
+                    userLog.userName = userList[0].userName
+                    userLogService.insert(userLog)
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                }
+                var idList = ArrayList<String>()
+                for (user in userList){
+                    idList.add(user.projectId!!)
+                }
+                val projectList = projectService.select(SFilter.inList("id", idList)).exec()
+                for (project in projectList){
+                    val select = buildService.select(SFilter.eq("projectId", project.id!!)).exec()
+                    project.buildList = select
+                }
+                return UserLoginResponse(projectList,userList[0])
+            }
+
+//            val projectList = projectDao.queryByPhone(phone)
+//            for (project in projectList) {
+//                project.buildList = buildingService.query(project.projId!!)
+//            }
+            val projectList = ArrayList<Project>()
+            return UserLoginResponse(projectList,userList[0])
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return UserLoginResponse(null,null, BaseResponse.ResultCode.failure, "登录失败!")
+    } // Function login()
+
+    /**
+     * 扫楼用户获得验证码
+     *
+     * @param   phone       手机号
+     */
+    fun getVerifyCode(phone: String): BaseResponse {
+//        val json = "{'templateid':'3892442','mobile':'$phone','codeLen':'4'}"
+        val json = "{\"templateid\":\"3892442\",\"mobile\":\"$phone\",\"codeLen\":\"4\"}"
+        return try {
+            val result = HttpUntil.postJson(URL(Opts.smsSendCode), json, BaseResponse::class.java)
+//            result.result = BaseResponse.ResultCode.success
+            result
+        } catch (e: Exception) {
+            e.printStackTrace()
+            BaseResponse(BaseResponse.ResultCode.failure)
+        }
+    } // Function getVerifyCode()
+
+
+    /**
+     * 根据手机号查询扫楼用户
+     *
+     * @param   phone           手机号
+     */
+    fun queryByPhone(phone: String): List<User> {
+        val exec = select(SFilter.eq("phone", phone)).exec()
+        return exec
+    } // Function queryByPhone()
+
+} // Object UserService

+ 54 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/base/RService.kt

@@ -0,0 +1,54 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.base
+
+import com.persagy.database.SAbstractDao
+import com.persagy.server.datacenter.models.entities.base.RBaseInfo
+import com.persagy.service.SObjectService
+
+/**
+ * 关系处理服务基类
+ *
+ * @author 张维新
+ */
+open class RService<ENTITY : RBaseInfo>(daoClass: SAbstractDao<ENTITY>) : SObjectService<ENTITY>(daoClass) {
+    companion object {
+        /** 日志 */
+//        private val logger = LoggerFactory.getLogger(ProjectController::class.java)
+
+        /** MQ消息对象 */
+//        val messageHandler by lazy {
+//            SSpringContextUtil.getBean(MessageHandler::class.java) as MessageHandler
+//        }
+        /** kafka消息对象 */
+//        val kafkaService by lazy {
+//            SSpringContextUtil.getBean(KafkaService::class.java) as KafkaService
+//        }
+    } // Companion object
+
+
+} // Class Service

+ 240 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/base/Service.kt

@@ -0,0 +1,240 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.base
+
+import com.persagy.database.SAbstractDao
+import com.persagy.database.extensions.keyValue
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.datacenter.models.entities.base.BaseInfo
+import com.persagy.server.datacenter.models.entities.logs.DataCenterLogs
+import com.persagy.server.services.task.SchemeService
+import com.persagy.server.util.IdUtils
+import com.persagy.service.SObjectService
+import com.persagy.service.SPageContext
+import com.persagy.service.utils.SSpringContextUtil
+import org.json.JSONArray
+import org.json.JSONObject
+import org.slf4j.LoggerFactory
+
+
+/**
+ * 服务基类
+ *
+ * @author 张维新
+ */
+open class Service<ENTITY : BaseInfo>(daoClass: SAbstractDao<ENTITY>) : SObjectService<ENTITY>(daoClass) {
+    companion object {
+        /** 日志 */
+        private val logger = LoggerFactory.getLogger(Service::class.java)
+
+//        /** MQ消息对象 */
+//        val messageHandler by lazy {
+//            SSpringContextUtil.getBean(MessageHandler::class.java) as MessageHandler
+//        }
+
+        /** 自定义sql */
+         val schemeService by lazy {
+            SSpringContextUtil.getBean(SchemeService::class.java) as SchemeService
+        }
+
+        /** kafka消息对象 */
+//        val kafkaService by lazy {
+//            SSpringContextUtil.getBean(KafkaService::class.java) as KafkaService
+//        }
+
+    } // Companion object
+    /** 日志 */
+    var logService = SObjectService(SMybatisDao(DataCenterLogs::class.java))
+
+    /**
+     * 创建成功回调函数
+     *
+     * @param   entityList          创建成功对象
+     */
+    override fun onCreateSuccess(entityList: ArrayList<ENTITY>) {
+
+        entityList.forEach {
+            val projectId = SPageContext.getHeader("projectId")
+            val comming = SPageContext.getHeader("coming")
+            val account = SPageContext.getHeader("account")
+
+            try {
+                val jsonObject = JSONObject()
+                jsonObject.put("type", "1")
+                jsonObject.put("projectId", projectId)
+                jsonObject.put("id", it.keyValue("id"))
+                jsonObject.put("obj_type", it.objectType)
+                /** 发送消息 */
+//                messageHandler.sendMessage(jsonObject.toString())
+//                kafkaService.sendNotice("datacenter", ObjectNotice(projectId!!, it.objectType!!, "create",IdUtils.uuidCreate(), hashSetOf(it.keyValue("id").toString())),false)
+
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+            try {
+                /** 日志 */
+                val dataCenterLogs = DataCenterLogs()
+                dataCenterLogs.id = IdUtils.uuidCreate()
+                dataCenterLogs.author = "dataCenter"
+                dataCenterLogs.projectId = projectId
+                dataCenterLogs.objectType = it.objectType
+                dataCenterLogs.type = "create"
+                dataCenterLogs.coming = comming
+                dataCenterLogs.account = account
+                dataCenterLogs.objectId = it.keyValue("id").toString()
+                val hashMap = HashMap<String, Any?>()
+                hashMap[it.objectType!!] = it
+                dataCenterLogs.dataSource = hashMap
+                logService.insert(dataCenterLogs)
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+
+
+        }
+//        entityList.forEach {
+//            if (it.objectType =="Equipment") {
+//                logger.debug("设备数据id${it.keyValue("id")}*******************************")
+//                logger.debug("资产数据id${it.keyValue("propertyId")}*******************************")
+//            }
+//        }
+
+        return
+    } // Function onCreateSuccess()
+
+    /**
+     * 删除成功回调函数
+     *
+     * @param   entityList      删除成功对象列表
+     */
+    override fun onDeleteSuccess(entityList: ArrayList<ENTITY>) {
+        val projectId = SPageContext.getHeader("projectId")
+        entityList.forEach {
+
+            try {
+                val jsonObject = JSONObject()
+                jsonObject.put("type", "2")
+                jsonObject.put("projectId", projectId)
+                jsonObject.put("id", it.keyValue("id"))
+                jsonObject.put("obj_type", it.objectType)
+                /** 发送消息 */
+//                messageHandler.sendMessage(jsonObject.toString())
+//                kafkaService.sendNotice("datacenter", ObjectNotice(projectId!!, it.objectType!!, "delete",IdUtils.uuidCreate(), hashSetOf(it.keyValue("id").toString())),false)
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+        }
+        return
+    } // Function onDeleteSuccess()
+
+
+    override fun onUpdateBefore(entity: ENTITY): Boolean {
+
+        try {
+            val projectId = SPageContext.getHeader("projectId")
+            val comming = SPageContext.getHeader("coming")
+            val account = SPageContext.getHeader("account")
+            /** 日志 */
+            val dataCenterLogs = DataCenterLogs()
+            dataCenterLogs.id = IdUtils.uuidCreate()
+            dataCenterLogs.author = "dataCenter"
+            dataCenterLogs.projectId = projectId
+            dataCenterLogs.objectType = entity.objectType
+            dataCenterLogs.type = "update-before"
+            dataCenterLogs.account = account
+            dataCenterLogs.coming = comming
+            dataCenterLogs.objectId = entity.keyValue("id").toString()
+            val hashMap = HashMap<String, Any?>()
+            hashMap[entity.objectType!!] = entity
+            dataCenterLogs.dataSource = hashMap
+            logService.insert(dataCenterLogs)
+        } catch (e: Exception) {
+            e.printStackTrace()
+    }
+
+        return super.onUpdateBefore(entity)
+    }
+
+    /**
+     * 更新成功能回调函数
+     *
+     * @param   entityList      更新成功对象列表
+     */
+    override fun onUpdateSuccess(entityList: ArrayList<ENTITY>) {
+        try {
+            val projectId = SPageContext.getHeader("projectId")
+            val comming = SPageContext.getHeader("coming")
+            val account = SPageContext.getHeader("account")
+            val jsonObject = JSONObject()
+            jsonObject.put("type", "7")
+            jsonObject.put("projectId", projectId)
+            jsonObject.put("obj_type", entityList[0].objectType)
+            val jsonArray = JSONArray()
+            for (entity in entityList) {
+                val jsonInfos = JSONObject()
+                jsonInfos.put("id", entity.keyValue("id"))
+                jsonInfos.put("obj_type", entity.objectType)
+                jsonArray.put(jsonInfos)
+
+                try {
+                    /** 日志 */
+                    val dataCenterLogs = DataCenterLogs()
+                    dataCenterLogs.id = IdUtils.uuidCreate()
+                    dataCenterLogs.author = "dataCenter"
+                    dataCenterLogs.projectId = projectId
+                    dataCenterLogs.objectType = entity.objectType
+                    dataCenterLogs.type = "update-after"
+                    dataCenterLogs.account = account
+                    dataCenterLogs.coming = comming
+                    dataCenterLogs.objectId = entity.keyValue("id").toString()
+                    val hashMap = HashMap<String, Any?>()
+                    hashMap[entity.objectType!!] = entity
+                    dataCenterLogs.dataSource = hashMap
+                    logService.insert(dataCenterLogs)
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                }
+
+                try {
+                    /** 发送消息 */
+//                    kafkaService.sendNotice("datacenter", ObjectNotice(projectId!!, entity.objectType!!, "update",IdUtils.uuidCreate(), hashSetOf(entity.keyValue("id").toString())),false)
+                } catch (e: Exception) {
+                    e.toString()
+                }
+
+            }
+            jsonObject.put("infos", jsonArray)
+            logger.debug("修改发送消息$jsonObject")
+            /** 发送消息 */
+//            messageHandler.sendMessage(jsonObject.toString())
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return
+    } // Function onUpdateSuccess()
+
+} // Class Service

+ 100 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/task/EquipScanTaskQueryService.kt

@@ -0,0 +1,100 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.task
+
+import com.persagy.database.SFilter
+import com.persagy.database.functions.SLength
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.datacenter.models.entities.dictnew.DefClass
+import com.persagy.server.datacenter.models.entities.task.EquipScanTaskQuery
+import com.persagy.service.SBaseService
+import com.persagy.service.SObjectService
+import com.persagy.service.SPageContext
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.responses.SQueryResponse
+import org.slf4j.LoggerFactory
+
+/**
+ * 设备台账任务
+ *
+ * @author  邓婷婷
+ */
+object EquipScanTaskQueryService : SObjectService<EquipScanTaskQuery>(SMybatisDao(EquipScanTaskQuery::class.java))  {
+
+    /** 字典平台对象类型 */
+    private val defClassService = SBaseService(SMybatisDao(DefClass::class.java))
+    // 日志
+    private val logger = LoggerFactory.getLogger(EquipScanTaskQueryService::class.java)
+
+
+    fun pageQuerys(request: SQueryRequest): SQueryResponse<EquipScanTaskQuery> {
+        val projectId = SPageContext.getHeader("projectId").toString()
+        val withFilterList = ArrayList<SFilter>()
+        withFilterList.add(SFilter.eq("projectId", SPageContext.getHeader("projectId").toString()))
+        withFilterList.add(SFilter.lt(SLength("classCode"), 7))
+        val pageQuery = pageQuery(request, withFilterList)
+        if (!pageQuery.content.isNullOrEmpty()&&pageQuery.content!!.size>0){
+            for (content in pageQuery.content!!){
+                val exec = select(SFilter.eq("parentId", content.equipId!!),SFilter.eq("taskParentId", content.id!!)).exec()
+                if (exec.size>0){
+                    content.component = exec
+                }
+                val defClass =
+                    defClassService.select(SFilter.eq("code", content.classCode!!)).entity()
+                if (defClass!=null) {
+                    content.equipCategory = defClass
+                }
+            }
+        }
+        return pageQuery
+    } // Fun
+
+    fun pageQueryTwo(request: SQueryRequest): SQueryResponse<EquipScanTaskQuery> {
+        val projectId = SPageContext.getHeader("projectId").toString()
+        val withFilterList = ArrayList<SFilter>()
+        withFilterList.add(SFilter.eq("projectId", SPageContext.getHeader("projectId").toString()))
+        val pageQuery = pageQuery(request, withFilterList)
+        if (!pageQuery.content.isNullOrEmpty()&&pageQuery.content!!.size>0){
+            for (content in pageQuery.content!!){
+                val exec = select(SFilter.eq("parentId", content.equipId!!),SFilter.eq("taskParentId", content.id!!)).exec()
+                if (exec.size>0){
+                    content.component = exec
+                }
+                val defClass =
+                    defClassService.select( SFilter.eq("code", content.classCode!!)).entity()
+                if (defClass!=null) {
+                    content.equipCategory = defClass
+                }
+            }
+        }
+        return pageQuery
+    } // Fun
+
+
+
+
+} // Class EquipScanTaskService

+ 441 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/task/EquipScanTaskService.kt

@@ -0,0 +1,441 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.task
+
+import cn.sagacloud.server.scanbuilding.User
+import com.alibaba.fastjson.JSONObject
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.persagy.base.extensions.toJson
+import com.persagy.database.SFilter
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.Opts
+import com.persagy.server.datacenter.models.entities.assistant.TaskPic
+import com.persagy.server.datacenter.models.entities.objects.Equipment
+import com.persagy.server.datacenter.models.entities.task.EquipScanTask
+import com.persagy.server.datacenter.models.entities.task.SchemeUtils
+import com.persagy.server.scanbuilding.UserLog
+import com.persagy.server.services.EquipmentService
+
+import com.persagy.server.services.base.RService
+import com.persagy.server.util.IdUtils
+import com.persagy.service.SBaseService
+import com.persagy.service.SObjectService
+import com.persagy.service.SPageContext
+import com.persagy.service.models.requests.SCreateRequest
+import org.slf4j.LoggerFactory
+import org.springframework.web.bind.annotation.RequestBody
+
+/**
+ * 设备台账任务
+ *
+ * @author  邓婷婷
+ */
+object EquipScanTaskService : RService<EquipScanTask>(SMybatisDao(EquipScanTask::class.java))  {
+
+    // 日志
+    private val logger = LoggerFactory.getLogger(EquipScanTaskService::class.java)
+
+    /** 扫楼日志 */
+    var userLogService = SObjectService(SMybatisDao(UserLog::class.java))
+    /** 用户 */
+    var userService = SObjectService(SMybatisDao(User::class.java))
+
+    /**
+     * 插入之前先过滤已经存在未验证任务的对象,返回新列表
+     */
+    fun createBefore(@RequestBody request: SCreateRequest<EquipScanTask>): SCreateRequest<EquipScanTask>{
+        val equipList = request.content;
+        var newList = arrayListOf<EquipScanTask>()
+        for(equip in equipList){
+            val equipTask = EquipScanTaskService.select("equipId" to equip.equipId!!,"taskState" to 1).entity()
+            if(equipTask==null){//表示当前设备不存在未验证的任务
+                equip.id = IdUtils.uuidCreate()
+                newList.add(equip)
+            }
+        }
+
+        request.content = newList
+        println(newList.size)
+        return request
+    } // Fun createBefore
+
+    /**
+     * 创建之前操作
+     */
+    override fun onCreateBefore(equipScanTask: EquipScanTask): Boolean  {
+        try{
+            val gson = Gson()
+            var flag = false
+            if(equipScanTask.taskState == -1){//前台传数据过来状态为-1 表示当前任务是未找到状态 重新生成任务,将之前的设备任务状态和部件任务改为已完成
+                flag = true
+                resetTaskStatus(equipScanTask)
+            }
+
+            val projectId = SPageContext.getHeader("projectId")
+//            if (equipScanTask.id.isNullOrEmpty()) {
+                equipScanTask.id = IdUtils.uuidCreate()
+//            }
+            if(!projectId.isNullOrEmpty()){
+                equipScanTask.projectId = projectId
+            }
+            equipScanTask.taskSource = 2//数据源为设备台账
+            equipScanTask.taskState = 1//任务状态为待验证
+            equipScanTask.taskType = "1"
+
+            if (!equipScanTask.equipId.isNullOrEmpty()) {//当设备id不为空时,去设备表查询对应的详细信息
+                val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+                val equipment = equipmentService.select("id" to equipScanTask.equipId!!).entity()
+                if (equipScanTask.schemeId.isNullOrEmpty()){
+                    equipScanTask.schemeId = SchemeUtils.setScheme(equipment!!.classCode!!)
+                }
+//                equipment.ledgerParam.PhotoDoc.Pic
+                if(equipment!!.infos != null){//设备图片信息
+                    val photoDoc = equipment!!.infos!!.get("photoDoc")
+                    if( photoDoc != null){
+                        val obj = JSONObject.parseObject(photoDoc!!.toJson())
+                        val pic = obj.getString("pic")
+
+                        val type = object : TypeToken<ArrayList<TaskPic>>() {
+                        }.type
+                        val siInSpList = gson.fromJson<ArrayList<TaskPic>>(pic, type)
+                        equipScanTask.taskPicList = siInSpList
+                    }
+
+                    val containsKey = equipment.infos!!.containsKey(Opts.INSTALLLOCATION)
+                    if (containsKey){
+                        equipScanTask.installLocation = equipment.infos!![Opts.INSTALLLOCATION].toString()
+                    }
+                }
+
+
+                try {
+                    if (!equipment.infos.isNullOrEmpty()){
+
+                        val containsKey = equipment.infos!!.containsKey(Opts.MANUFACTURER)
+                        if (containsKey){
+                            equipScanTask.manufacturer = equipment.infos!![Opts.MANUFACTURER].toString()
+                        }
+                        val containsKey2 = equipment.infos!!.containsKey(Opts.SPECIFICATION)
+                        if(containsKey2) {
+                            equipScanTask.specification = equipment.infos!![Opts.SPECIFICATION].toString()
+                        }
+
+                        val containsKeys = equipment.infos!!.containsKey(Opts.SUPPLIER)
+                        if (containsKeys){
+                            equipScanTask.supplier =  equipment.infos!![Opts.SUPPLIER].toString()
+                        }
+                    }
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                }
+
+                if(flag){
+                    equipScanTask.equipName = equipment!!.name
+                    equipScanTask.localId = equipment!!.localId
+                    equipScanTask.localName = equipment!!.localName
+                    equipScanTask.bimId = equipment!!.bimId
+                    equipScanTask.classCode = equipment!!.classCode
+                    equipScanTask.buildingId = equipment!!.buildingId
+                    equipScanTask.floorId = equipment!!.floorId
+                    equipScanTask.cadId = equipment!!.cadId
+//                    equipScanTask.supplier = equipment!!.dpSupplierID
+
+
+//                    equipScanTask.specification = equipment!!.dpManufacturerID
+//                    equipScanTask.manufacturer = equipment!!.dpMaintainerID
+                    equipScanTask.bimLocation = equipment.bimLocation
+//                    if (equipment.codeType!=null){
+//                        equipScanTask.taskType = equipment.codeType.toString()
+//                    }else{
+//                        equipScanTask.taskType = "1"
+//                    }
+
+
+                }else {
+                    equipScanTask.bimLocation = equipment.bimLocation
+                    if (equipScanTask.equipName.isNullOrEmpty()) {
+                        equipScanTask.equipName = equipment!!.name
+                    }
+                    if (equipScanTask.localId.isNullOrEmpty()) {
+                        equipScanTask.localId = equipment!!.localId
+                    }
+                    if (equipScanTask.localName.isNullOrEmpty()) {
+                        equipScanTask.localName = equipment!!.localName
+                    }
+                    if (equipScanTask.bimId.isNullOrEmpty()) {
+                        equipScanTask.bimId = equipment!!.bimId
+                    }
+                    if (equipScanTask.classCode.isNullOrEmpty()) {
+                        equipScanTask.classCode = equipment!!.classCode
+                    }
+                    if (equipScanTask.buildingId.isNullOrEmpty()) {
+                        equipScanTask.buildingId = equipment!!.buildingId
+                    }
+                    if (equipScanTask.floorId.isNullOrEmpty()) {
+                        equipScanTask.floorId = equipment!!.floorId
+                    }
+                    if (equipScanTask.cadId.isNullOrEmpty()) {
+                        equipScanTask.cadId = equipment!!.cadId
+                    }
+                    if (equipScanTask.manufacturer.isNullOrEmpty()) {
+                        if (!equipment.infos.isNullOrEmpty()) {
+                            val contains = equipment.infos!!.contains("manufacturer")
+                            if (contains) {
+                                equipScanTask.manufacturer = equipment.infos!!["manufacturer"].toString()
+                            }
+                        }
+                    }
+
+                    if (equipScanTask.specification.isNullOrEmpty()) {
+                        if (!equipment.infos.isNullOrEmpty()) {
+                            val contains = equipment.infos!!.contains("specification")
+                            if (contains) {
+                                equipScanTask.specification = equipment.infos!!["specification"].toString()
+                            }
+                        }
+                    }
+
+                    if (equipScanTask.supplier.isNullOrEmpty()) {
+                        if (!equipment.infos.isNullOrEmpty()) {
+                            val contains = equipment.infos!!.contains("supplier")
+                            if (contains) {
+                                equipScanTask.supplier = equipment.infos!!["supplier"].toString()
+                            }
+                        }
+                    }
+
+//                    if (equipScanTask.taskType.isNullOrEmpty()){
+//                        if (equipment.codeType!=null){
+//                            equipScanTask.taskType = equipment.codeType.toString()
+//                        }else{
+//                            equipScanTask.taskType = "1"
+//                        }
+//                    }
+
+                }
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return true
+    } // Function onCreateBefore()
+
+    /**
+     * 设备级联部件,所有部件也增加任务
+     */
+    override fun onCreateSuccess(equipScanTaskList: ArrayList<EquipScanTask>) {
+        val projectId = SPageContext.getHeader("projectId")
+
+        for(task in equipScanTaskList){
+            val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+            val componentList = equipmentService.select("parentId" to task.equipId!!).exec()
+
+            for(equipment in componentList){
+                val equipScanTask = EquipScanTask()
+                equipScanTask.id = IdUtils.uuidCreate()
+                if(!task.projectId.isNullOrEmpty()){
+                    equipScanTask.projectId = task.projectId
+                }else{
+                    equipScanTask.projectId = projectId
+                }
+                equipScanTask.taskSource = 4//数据源为设备台账
+                equipScanTask.taskState = 1//任务状态为待验证
+                equipScanTask.parentId = task.equipId
+                equipScanTask.equipId = equipment!!.id
+                equipScanTask.equipName = equipment!!.name
+                equipScanTask.localId = equipment!!.localId
+                equipScanTask.localName = equipment!!.localName
+                equipScanTask.bimId = equipment!!.bimId
+                equipScanTask.classCode = equipment!!.classCode
+                equipScanTask.buildingId = equipment!!.buildingId
+                equipScanTask.floorId = equipment!!.floorId
+                equipScanTask.cadId = equipment!!.cadId
+                equipScanTask.bimLocation = equipment.bimLocation
+                equipScanTask.taskParentId = task.id
+                if (equipment.codeType!=null){
+                    equipScanTask.taskType = equipment.codeType.toString()
+                }else {
+                    equipScanTask.taskType = "1"
+                }
+
+                EquipScanTaskService.insert(equipScanTask)
+            }
+            resetObjStatus(task)
+        }
+
+    } // Fun onCreateSuccess
+
+    /**
+     * 状态修改完成之后,若修改为  已完成状态  则级联部件任务状态全部修改为  已完成
+     */
+    override fun onUpdateSuccess(list: ArrayList<EquipScanTask>) {
+        val projectId = SPageContext.getHeader("projectId")
+        for (task in list) {
+            val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+            if(task.equipId == null ){
+                val equipScanTaskScanTask = EquipScanTaskService.select("id" to task.id!!).entity()
+                task.equipId = equipScanTaskScanTask!!.equipId
+            }
+            if (!task.confirmingPersonId.isNullOrEmpty()&&task.taskState == 0){
+                task.taskState = -1
+                //更改部件对象状态
+                updateComponetObjStatus(task)
+                //更改部件任务状态
+                updateComponetTaskStatus(task)
+            }else if(task.confirmingPersonId.isNullOrEmpty()&&task.taskState == 0) {
+                task.taskState = 0
+                //更改部件对象状态
+                updateComponetObjStatus(task)
+                //更改部件任务状态
+                updateComponetTaskStatus(task)
+            }
+            //更改设备对象的状态
+            val equipmentOld = equipmentService.select("id" to task.equipId!!).entity()
+            if(equipmentOld!!.taskState != -1){//未找到
+                val equip = Equipment()
+                equip.id = task.equipId!!
+                equip.taskState = task.taskState
+                equipmentService.update(equip)
+            }
+
+            try {
+                if (!Opts.coming.isNullOrEmpty()&&Opts.coming == "app"){
+                        val entity = userService.select(SFilter.eq("projectId", projectId!!), SFilter.eq("phone", Opts.account!!)).entity()
+                        val userLog = UserLog()
+                        userLog.comming = "app"
+                        userLog.action = "修改任务"
+                        userLog.id = IdUtils.uuidCreate()
+                        userLog.note = "确认设备任务"
+                        userLog.phone = entity?.phone
+                        userLog.projectId = projectId
+                        userLog.userId = entity!!.id
+                        userLog.name = entity.name
+                        userLog.objectId = task.id
+                        userLogService.insert(userLog)
+                }
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+        }
+    } // Fun onUpdateSuccess
+
+    /**
+     * 更新设备对象状态时,对应更改部件对象状态,当为未找到状态时,特殊处理
+     */
+    fun updateComponetObjStatus(task: EquipScanTask){
+        val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+        val componentList = equipmentService.select("parentId" to task!!.equipId!!).exec()
+
+        if(task.taskState == 1 || task.taskState == -1){ // 待验证和未找到
+            for(component in componentList){
+                component.taskState = task.taskState
+                equipmentService.update(component)
+            }
+        }else if(task.taskState == 0){ // 已完成
+            for(component in componentList){
+                if(component.taskState != -1){//如果部件状态为未找到,则不改变状态
+                    component.taskState = task.taskState
+                    equipmentService.update(component)
+                }
+            }
+        }
+    }
+
+    /**
+     * 更新设备任务状态时,对应更改部件任务状态
+     */
+    fun updateComponetTaskStatus(task: EquipScanTask){
+        val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+        val equipScanTaskService = SBaseService(SMybatisDao(EquipScanTask::class.java))
+
+        val componentTaskList = equipScanTaskService.select("parentId" to task!!.equipId!!).exec()
+
+        for(childTask in componentTaskList){
+            childTask.taskState = task.taskState
+            EquipScanTaskService.update(childTask)
+        }
+    } // Fun updateStatus
+
+    /**
+     * 更新设备对象状态时,对应更改部件对象状态
+     */
+    fun resetComponetObjStatus(task: EquipScanTask){
+        val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+        val componentList = equipmentService.select("parentId" to task!!.equipId!!).exec()
+        for(component in componentList){
+            component.taskState = task.taskState
+            equipmentService.update(component)
+        }
+    }
+
+    /**
+     * 重新生成任务时,将任务状态改为已完成
+     */
+    fun resetTaskStatus(task: EquipScanTask) {
+        val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+        val equipScanTaskService = SBaseService(SMybatisDao(EquipScanTask::class.java))
+        val resetTask = equipScanTaskService.select("equipId" to task.equipId!!, "taskState" to -1).entity()
+        if (resetTask != null) {
+            resetTask.taskState = 0
+            equipScanTaskService.update(resetTask)//更改设备任务状态
+            updateComponetTaskStatus(resetTask)//更改部件任务状态
+        }
+    }
+        /**
+         * 重新生成任务时,将设备和部件状态改变为待验证
+         */
+     fun resetObjStatus(task: EquipScanTask){
+        val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+
+        //更改设备对象状态
+        val equip = Equipment()
+        equip.id = task.equipId!!
+        equip.taskState = task.taskState
+        equipmentService.update(equip)
+        //更改部件对象状态
+        resetComponetObjStatus(task)
+    }
+
+    override fun onDeleteBefore(entity: EquipScanTask): Boolean {
+        try {
+            val entity2 = select(SFilter.eq("id", entity.id!!)).entity()
+            val entity1 = EquipmentService.select(SFilter.eq("id", entity2!!.equipId!!)).entity()
+            if (entity1!=null){
+                if (entity1.taskState == 1){
+                    entity1.taskState = null
+                    EquipmentService.update(entity1, arrayListOf("taskState"))
+                }
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return super.onDeleteBefore(entity)
+    }
+
+
+} // Class EquipScanTaskService

+ 94 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/task/ModelScanTaskQueryService.kt

@@ -0,0 +1,94 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.task
+
+import com.persagy.database.SFilter
+import com.persagy.database.functions.SLength
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.datacenter.models.entities.dictnew.DefClass
+import com.persagy.server.datacenter.models.entities.task.ModelScanTaskQuery
+import com.persagy.server.services.base.RService
+import com.persagy.service.SBaseService
+import com.persagy.service.SPageContext
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.responses.SQueryResponse
+
+
+/**
+ * 模型任务
+ *
+ * @author  邓婷婷
+ */
+object ModelScanTaskQueryService : RService<ModelScanTaskQuery>(SMybatisDao(ModelScanTaskQuery::class.java))  {
+
+    /** 字典平台对象类型 */
+    private val defClassService = SBaseService(SMybatisDao(DefClass::class.java))
+
+    fun pageQuerys(request: SQueryRequest): SQueryResponse<ModelScanTaskQuery> {
+        val projectId = SPageContext.getHeader("projectId").toString()
+        val withFilterList = ArrayList<SFilter>()
+        withFilterList.add(SFilter.eq("projectId", SPageContext.getHeader("projectId").toString()))
+        withFilterList.add(SFilter.lt(SLength("classCode"), 7))
+        val pageQuery = pageQuery(request, withFilterList)
+        if (!pageQuery.content.isNullOrEmpty()&&pageQuery.content!!.size>0){
+            for (content in pageQuery.content!!){
+                val exec = select(SFilter.eq("parentId", content.equipId!!),SFilter.eq("taskParentId", content.id!!)).exec()
+                if (exec.size>0){
+                    content.component = exec
+                }
+                val defClass =
+                    defClassService.select(SFilter.eq("projectId", projectId), SFilter.eq("code", content.classCode!!)).entity()
+                if (defClass!=null) {
+                    content.equipCategory = defClass
+                }
+            }
+        }
+        return pageQuery
+    } // Fun
+
+    fun pageQueryTwo(request: SQueryRequest): SQueryResponse<ModelScanTaskQuery> {
+        val projectId = SPageContext.getHeader("projectId").toString()
+        val withFilterList = ArrayList<SFilter>()
+        withFilterList.add(SFilter.eq("projectId", SPageContext.getHeader("projectId").toString()))
+        val pageQuery = pageQuery(request, withFilterList)
+        if (!pageQuery.content.isNullOrEmpty()&&pageQuery.content!!.size>0){
+            for (content in pageQuery.content!!){
+                val exec = select(SFilter.eq("parentId", content.equipId!!),SFilter.eq("taskParentId", content.id!!)).exec()
+                if (exec.size>0){
+                    content.component = exec
+                }
+                val defClass =
+                    defClassService.select(SFilter.eq("projectId", projectId), SFilter.eq("code", content.classCode!!)).entity()
+                if (defClass!=null) {
+                    content.equipCategory = defClass
+                }
+            }
+        }
+        return pageQuery
+    } // Fun
+
+} // Class ModelScanTaskService

+ 597 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/task/ModelScanTaskService.kt

@@ -0,0 +1,597 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.task
+
+import cn.sagacloud.server.scanbuilding.User
+import com.alibaba.fastjson.JSONObject
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.persagy.base.extensions.toJson
+import com.persagy.database.SFilter
+import com.persagy.database.SPageQueryInfo
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.Opts
+import com.persagy.server.datacenter.models.entities.assistant.TaskPic
+import com.persagy.server.datacenter.models.entities.dict.EquipCategory
+import com.persagy.server.datacenter.models.entities.objects.Equipment
+import com.persagy.server.datacenter.models.entities.task.*
+import com.persagy.server.datacenter.models.requests.ModelScanSQueryRequest
+import com.persagy.server.mappers.StatisticsCountMapper
+import com.persagy.server.scanbuilding.UserLog
+import com.persagy.server.services.EquipmentService
+import com.persagy.server.services.base.RService
+import com.persagy.server.util.IdUtils
+import com.persagy.service.SBaseService
+import com.persagy.service.SObjectService
+import com.persagy.service.SPageContext
+import com.persagy.service.models.enums.SResponseType
+import com.persagy.service.models.requests.SCreateRequest
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.responses.SQueryResponse
+import com.persagy.service.utils.SSpringContextUtil
+import org.slf4j.LoggerFactory
+import org.springframework.web.bind.annotation.RequestBody
+import java.util.*
+import kotlin.collections.ArrayList
+
+
+/**
+ * 模型任务
+ *
+ * @author  邓婷婷
+ */
+object ModelScanTaskService : RService<ModelScanTask>(SMybatisDao(ModelScanTask::class.java))  {
+
+    // 日志
+    private val logger = LoggerFactory.getLogger(ModelScanTaskService::class.java)
+
+
+    val modelScanTaskService = SBaseService(SMybatisDao(ModelScanTask::class.java))
+    /** 设备类型 */
+    val equipCategoryService = SObjectService(SMybatisDao(EquipCategory::class.java))
+    /** 扫楼日志 */
+    var userLogService = SObjectService(SMybatisDao(UserLog::class.java))
+    /** 用户 */
+    var userService = SObjectService(SMybatisDao(User::class.java))
+
+
+    /** 实例化 mapper 对象 */
+    val mapper by lazy {
+        SSpringContextUtil.getBean(StatisticsCountMapper::class.java) as StatisticsCountMapper
+    }
+
+
+    /**
+     * 插入之前先过滤已经存在未验证任务的对象,返回新列表
+     */
+    fun createBefore(@RequestBody request: SCreateRequest<ModelScanTask>): SCreateRequest<ModelScanTask> {
+        val modelList = request.content;
+        var newList = arrayListOf<ModelScanTask>()
+        for(model in modelList){
+            val modelTask = ModelScanTaskService.select("equipId" to model.equipId!!,"taskState" to 1).entity()
+            if(modelTask==null){//表示当前设备不存在未验证的任务
+                newList.add(model)
+            }
+        }
+
+        request.content = newList
+        println(newList.size)
+        return request
+    } // Fun createBefore
+
+    /**
+     * 创建之前操作
+     */
+    override fun onCreateBefore(modelScanTask: ModelScanTask): Boolean  {
+        try {
+                val gson = Gson()
+                var flag = false
+                if (modelScanTask.taskState == -1) {//前台传数据过来状态为-1 表示当前任务是未找到状态 重新生成任务,将之前的设备任务状态和部件任务改为已完成
+                    flag = true
+                    resetTaskStatus(modelScanTask)
+                }
+                val projectId = SPageContext.getHeader("projectId")
+//                if (modelScanTask.id.isNullOrEmpty()) {
+                    modelScanTask.id = UUID.randomUUID().toString()
+//                }
+                if (!projectId.isNullOrEmpty()) {
+                    modelScanTask.projectId = projectId
+                }
+                modelScanTask.taskSource = 1//数据源为模型
+                modelScanTask.taskState = 1//任务状态为待验证
+                modelScanTask.taskType = "1"
+
+                if (!modelScanTask.equipId.isNullOrEmpty()) {//当设备id不为空时,去设备表查询对应的详细信息
+                    val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+                    val equipment = equipmentService.select("id" to modelScanTask.equipId!!).entity()
+
+                    if (modelScanTask.schemeId.isNullOrEmpty()){
+                        modelScanTask.schemeId = SchemeUtils.setScheme(equipment!!.classCode!!)
+                    }
+
+//                equipment.ledgerParam.PhotoDoc.Pic
+                    if(equipment!!.infos != null){//设备图片信息
+                        val photoDoc = equipment!!.infos!!.get("photoDoc")
+                        if( photoDoc != null){
+                            val obj = JSONObject.parseObject(photoDoc!!.toJson())
+                            val pic = obj.getString("pic")
+
+                            val type = object : TypeToken<ArrayList<TaskPic>>() {
+                            }.type
+                            val siInSpList = gson.fromJson<ArrayList<TaskPic>>(pic, type)
+                            modelScanTask.taskPicList = siInSpList
+                        }
+
+                        val containsKey = equipment.infos!!.containsKey(Opts.INSTALLLOCATION)
+                        if (containsKey){
+                            modelScanTask.installLocation = equipment.infos!![Opts.INSTALLLOCATION].toString()
+                        }
+                    }
+
+                    try {
+                        if (!equipment.infos.isNullOrEmpty()){
+
+                            val containsKey = equipment.infos!!.containsKey(Opts.MANUFACTURER)
+                            if (containsKey){
+                                modelScanTask.manufacturer = equipment.infos!![Opts.MANUFACTURER].toString()
+                            }
+                            val containsKey2 = equipment.infos!!.containsKey(Opts.SPECIFICATION)
+                            if(containsKey2) {
+                                modelScanTask.specification = equipment.infos!![Opts.SPECIFICATION].toString()
+                            }
+
+                            val containsKeys = equipment.infos!!.containsKey(Opts.SUPPLIER)
+                            if (containsKeys){
+                                modelScanTask.supplier =  equipment.infos!![Opts.SUPPLIER].toString()
+                            }
+                        }
+                    } catch (e: Exception) {
+                        e.printStackTrace()
+                    }
+
+                    if (flag) {
+                        modelScanTask.equipName = equipment!!.name
+                        modelScanTask.localId = equipment!!.localId
+                        modelScanTask.localName = equipment!!.localName
+                        modelScanTask.bimId = equipment!!.bimId
+                        modelScanTask.classCode = equipment!!.classCode
+                        modelScanTask.buildingId = equipment!!.buildingId
+                        modelScanTask.floorId = equipment!!.floorId
+                        modelScanTask.cadId = equipment!!.cadId
+                        modelScanTask.bimLocation = equipment.bimLocation
+
+                        if (equipment.codeType!=null){
+                            modelScanTask.taskType = equipment.codeType.toString()
+                        }else{
+                            modelScanTask.taskType = "1"
+                        }
+                    } else {
+
+                        if (modelScanTask.equipName.isNullOrEmpty()) {
+                            modelScanTask.equipName = equipment!!.name
+                        }
+                        if (modelScanTask.localId.isNullOrEmpty()) {
+                            modelScanTask.localId = equipment!!.localId
+                        }
+                        if (modelScanTask.localName.isNullOrEmpty()) {
+                            modelScanTask.localName = equipment!!.localName
+                        }
+                        if (modelScanTask.bimId.isNullOrEmpty()) {
+                            modelScanTask.bimId = equipment!!.bimId
+                        }
+                        if (modelScanTask.classCode.isNullOrEmpty()) {
+                            modelScanTask.classCode = equipment!!.classCode
+                        }
+                        if (modelScanTask.buildingId.isNullOrEmpty()) {
+                            modelScanTask.buildingId = equipment!!.buildingId
+                        }
+                        if (modelScanTask.floorId.isNullOrEmpty()) {
+                            modelScanTask.floorId = equipment!!.floorId
+                        }
+                        if (modelScanTask.cadId.isNullOrEmpty()) {
+                            modelScanTask.cadId = equipment!!.cadId
+                        }
+
+                        if (modelScanTask.bimLocation.isNullOrEmpty()){
+                            modelScanTask.bimLocation = equipment.bimLocation
+                        }
+
+                        if (modelScanTask.taskType.isNullOrEmpty()){
+                            if (equipment.codeType!=null){
+                                modelScanTask.taskType = equipment.codeType.toString()
+                            }else{
+                                modelScanTask.taskType = "1"
+                            }
+                        }
+                    }
+                }
+            } catch (e: Exception) {
+                    e.printStackTrace()
+            }
+      return true
+    } // Function onCreateBefore()
+
+    /**
+     * 创建设备台账任务成功之后,设备级联部件,所有部件也增加任务
+     */
+    override fun onCreateSuccess(modelScanTaskList: ArrayList<ModelScanTask>) {
+        val projectId = SPageContext.getHeader("projectId")
+
+        for(task in modelScanTaskList){
+            val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+            val componentList = equipmentService.select("parentId" to task.equipId!!).exec()
+
+            for(equipment in componentList){
+                val modelScanTask = ModelScanTask()
+                modelScanTask.id = IdUtils.uuidCreate()
+                if(!task.projectId.isNullOrEmpty()){
+                    modelScanTask.projectId = task.projectId
+                }else{
+                    modelScanTask.projectId = projectId
+                }
+                modelScanTask.taskSource = 4//数据源为模型任务
+                modelScanTask.taskState = 1//任务状态为待验证
+                modelScanTask.parentId = task.equipId
+                modelScanTask.equipId = equipment!!.id
+                modelScanTask.equipName = equipment!!.name
+                modelScanTask.localId = equipment!!.localId
+                modelScanTask.localName = equipment!!.localName
+                modelScanTask.bimId = equipment!!.bimId
+                modelScanTask.classCode = equipment!!.classCode
+                modelScanTask.buildingId = equipment!!.buildingId
+                modelScanTask.floorId = equipment!!.floorId
+                modelScanTask.cadId = equipment!!.cadId
+                modelScanTask.bimLocation = equipment.bimLocation
+                modelScanTask.taskParentId = task.id
+                if (equipment.codeType!=null){
+                    modelScanTask.taskType = equipment.codeType.toString()
+                }else{
+                    modelScanTask.taskType = "1"
+                }
+                ModelScanTaskService.insert(modelScanTask)
+            }
+            resetObjStatus(task)
+        }
+    } // Fun onCreateSuccess
+
+
+
+    /**
+     * 状态修改完成之后,若修改为  已完成状态  则级联部件任务状态全部修改为  已完成
+     */
+    override fun onUpdateSuccess(list: ArrayList<ModelScanTask>) {
+
+        val projectId = SPageContext.getHeader("projectId")
+
+        for (task in list) {
+            val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+            if(task.equipId == null ){
+                val modelScanTaskScanTask = ModelScanTaskService.select("id" to task.id!!).entity()
+                task.equipId = modelScanTaskScanTask!!.equipId
+            }
+
+            if (!task.confirmingPersonId.isNullOrEmpty()&&task.taskState == 0){
+                task.taskState = -1
+                //更改部件对象状态
+                updateComponetObjStatus(task)
+                //更改部件任务状态
+                updateComponetTaskStatus(task)
+            }else if(task.confirmingPersonId.isNullOrEmpty()&&task.taskState == 0) {
+                task.taskState = 0
+                //更改部件对象状态
+                updateComponetObjStatus(task)
+                //更改部件任务状态
+                updateComponetTaskStatus(task)
+            }
+            //更改设备对象的状态
+            val equipmentOld = equipmentService.select("id" to task.equipId!!).entity()
+            if(equipmentOld!!.taskState != -1){//未找到
+                val equip = Equipment()
+                equip.id = task.equipId!!
+                equip.taskState = task.taskState
+                equipmentService.update(equip)
+            }
+            try {
+                if (!Opts.coming.isNullOrEmpty()&&Opts.coming == "app"){
+
+                        val entity = userService.select(SFilter.eq("projectId", projectId!!), SFilter.eq("phone", Opts.account!!)).entity()
+                        val userLog = UserLog()
+                        userLog.comming = "app"
+                        userLog.action = "修改任务"
+                        userLog.id = IdUtils.uuidCreate()
+                        userLog.note = "确认模型设备任务"
+                        userLog.phone = entity?.phone
+                        userLog.projectId = projectId
+                        userLog.userId = entity!!.id
+                        userLog.name = entity.name
+                        userLog.objectId = task.equipId
+                        userLogService.insert(userLog)
+                }
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+        }
+    } // Fun onUpdateSuccess
+
+    /**
+     * 更新设备对象状态时,对应更改部件对象状态,当为未找到状态时,特殊处理
+     */
+    fun updateComponetObjStatus(task: ModelScanTask){
+        val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+        val componentList = equipmentService.select("parentId" to task!!.equipId!!).exec()
+
+        if(task.taskState == 1 || task.taskState == -1){ // 待验证和未找到
+            for(component in componentList){
+                component.taskState = task.taskState
+                equipmentService.update(component)
+            }
+        }else if(task.taskState == 0){ // 已完成
+            for(component in componentList){
+                if(component.taskState != -1){//如果部件状态为未找到,则不改变状态
+                    component.taskState = task.taskState
+                    equipmentService.update(component)
+                }
+            }
+        }
+    }
+
+    /**
+     * 更新设备任务状态时,对应更改部件任务状态
+     */
+    fun updateComponetTaskStatus(task: ModelScanTask){
+        val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+        val modelScanTaskService = SBaseService(SMybatisDao(ModelScanTask::class.java))
+
+        val componentTaskList = modelScanTaskService.select("parentId" to task!!.equipId!!).exec()
+
+        for(childTask in componentTaskList){
+            childTask.taskState = task.taskState
+            ModelScanTaskService.update(childTask)
+        }
+    } // Fun updateStatus
+
+    /**
+     * 更新设备对象状态时,对应更改部件对象状态
+     */
+    fun resetComponetObjStatus(task: ModelScanTask){
+        val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+        val componentList = equipmentService.select("parentId" to task!!.equipId!!).exec()
+        for(component in componentList){
+            component.taskState = task.taskState
+            equipmentService.update(component)
+        }
+    }
+
+    /**
+     * 重新生成任务时,将任务状态改为已完成
+     */
+    fun resetTaskStatus(task: ModelScanTask) {
+        val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+        val modelScanTaskService = SBaseService(SMybatisDao(ModelScanTask::class.java))
+        val resetTask = modelScanTaskService.select("equipId" to task.equipId!!, "taskState" to -1).entity()
+        if (resetTask != null) {
+            resetTask.taskState = 0
+            modelScanTaskService.update(resetTask)//更改设备任务状态
+            updateComponetTaskStatus(resetTask)//更改部件任务状态
+        }
+    }
+    /**
+     * 重新生成任务时,将设备和部件状态改变为待验证
+     */
+    fun resetObjStatus(task: ModelScanTask){
+        val equipmentService = SBaseService(SMybatisDao(Equipment::class.java))
+
+        //更改设备对象状态
+        val equip = Equipment()
+        equip.id = task.equipId!!
+        equip.taskState = task.taskState
+        equipmentService.update(equip)
+        //更改部件对象状态
+        resetComponetObjStatus(task)
+    }
+
+
+    /**
+     * 查询所有模型文件夹和文件
+     */
+    fun modelFileQuery(): SQueryResponse<ModelFolder> {
+        val pageQuery: SPageQueryInfo<ModelFolder>
+        val gson = Gson()
+        return try {
+            val projectId = SPageContext.getHeader("projectId")
+            var request = SQueryRequest()
+            val modelFolderService = SBaseService(SMybatisDao(ModelFolder::class.java))
+            val modelFolderQueryBuilder = modelFolderService.select(request.filters)
+            modelFolderQueryBuilder.tableName = "scantask.f_get_modelfile('$projectId')"
+            pageQuery = modelFolderQueryBuilder.pageQuery(1, 1000)
+
+            for(folder in pageQuery.content!!){
+                if(folder.fileListStr != null){
+                    val listStr = folder.fileListStr!!.replace("/\\","")
+                    val newStr = "["+listStr.substring(1,listStr.length-1)+"]"
+                    val type = object : TypeToken<ArrayList<ModelFile>>() {
+                    }.type
+                    val siInSpList = gson.fromJson<ArrayList<ModelFile>>(newStr, type)
+                    folder.fileList = siInSpList
+                    folder.fileListStr = null
+                }
+            }
+            SQueryResponse(pageQuery)
+        } catch (e: Exception) {
+            e.printStackTrace()
+            SQueryResponse(SResponseType.failure, e.message!!)
+        }
+    } //  Fun modelFileQuery
+
+    /**
+     * 根据元空间id查询设备
+     */
+    fun  equipQuery(request: ModelScanSQueryRequest): SQueryResponse<EquipmentTaskTwo>{
+        return  try{
+            val projectId = SPageContext.getHeader("projectId")
+            val modelScanTaskService = SBaseService(SMybatisDao(EquipmentTaskTwo::class.java))
+            if (!request.modelId.isNullOrEmpty()&&!request.idList.isNullOrEmpty()&&request.idList!!.size>0){
+                val list = ArrayList<EquipmentTaskTwo>()
+                for ( bimId in request.idList!!){
+                    if (request.category.isNullOrEmpty()){
+                        val equipInISpaceList = mapper.equipInISpace(projectId!!, request.modelId!!, bimId)
+                        if (equipInISpaceList.size>0){
+                            logger.debug("数据22222 = ${equipInISpaceList.toJson()}")
+                            list.addAll(equipInISpaceList)
+                        }
+                    }else{
+                        val equipInISpaceList = mapper.equipInISpaceTwo(projectId!!, request.modelId!!, bimId,request.category!!)
+                        if (equipInISpaceList.size>0){
+                            logger.debug("数据111 = ${equipInISpaceList.toJson()}")
+                            list.addAll(equipInISpaceList)
+                        }
+                    }
+                }
+                if (list.size>0){
+                    val pageNumber = request.pageNumber
+                    val pageSize = request.pageSize
+                    /** 开始条数 */
+                    var fromIndex = pageSize* (pageNumber-1)
+                    var toIndex = fromIndex + pageSize
+                    if (toIndex>=list.size){
+                        toIndex = list.size
+                    }
+
+                    val sQueryResponse = SQueryResponse<EquipmentTaskTwo>(SResponseType.success)
+                    sQueryResponse.total = list.size.toLong()
+                    val subList = list.subList(fromIndex, toIndex)
+                    if (subList.size>0){
+                        for (equip in subList){
+                            logger.debug("数据 = ${equip.toJson()}")
+                            try {
+                                val entity = equipCategoryService.select(SFilter.eq("code", equip.classCode!!)).entity()
+                                if (entity!=null){
+                                    equip.equipCategory = entity
+                                }
+                                val exec = modelScanTaskService.select(SFilter.eq("parentId", equip.id!!)).exec()
+                                if (exec.size>0){
+                                    equip.component = exec
+                                }
+                                val entity1 = EquipmentService.select(SFilter.eq("id", equip.id!!)).entity()
+                                equip.bimId = entity1!!.bimId
+                                equip.localId = entity1.localId
+                                equip.localName = entity1.localName
+                            } catch (e: Exception) {
+                                e.printStackTrace()
+                            }
+                        }
+                    }
+                    sQueryResponse.content = subList
+                    sQueryResponse.pageSize = pageSize
+                    sQueryResponse.pageNumber = pageNumber
+                    sQueryResponse
+                }else{
+                    val sQueryResponse = SQueryResponse<EquipmentTaskTwo>(SResponseType.success)
+                    sQueryResponse.content = ArrayList<EquipmentTaskTwo>()
+                    sQueryResponse.pageNumber = request.pageNumber
+                    sQueryResponse.pageSize = request.pageSize
+                    sQueryResponse
+                }
+            }else{
+                val sQueryResponse = SQueryResponse<EquipmentTaskTwo>(SResponseType.failure)
+                sQueryResponse.message = "入参错误"
+                sQueryResponse
+            }
+
+//            if (!request.idList.isNullOrEmpty()){
+//                return EquipmentService.pageQuery(request, arrayListOf(SFilter.inList(SEndWithChar("bimId",":"),request.idList!!) ,
+//                        SFilter.eq("projectId",projectId!!)))
+//            }else{
+//                return EquipmentService.pageQuery(request, arrayListOf(
+//                        SFilter.eq("projectId",projectId!!)))
+//            }
+
+//           return EquipmentService.pageQuery(request, arrayListOf(SFilter.inList(SEndWithChar("bimId",":"),listId) ,
+//                   SFilter.eq("projectId",projectId!!)))
+
+    } catch (e: Exception) {
+        e.printStackTrace()
+        SQueryResponse(SResponseType.failure, e.message!!)
+    }
+    }
+
+//    private fun getDatas(list: ArrayList<Equipment>,firstIndex: Int, lastIndex: Int): List<Equipment> {
+//        val resList = ArrayList<Equipment>()
+//        for (i in firstIndex until lastIndex) {
+//            if (i < list.size) {
+//                resList.add(list[i])
+//            }
+//        }
+//        return resList
+//    }
+
+
+
+
+    override fun onDeleteBefore(entity: ModelScanTask): Boolean {
+
+        try {
+            val entity2 = EquipScanTaskService.select(SFilter.eq("id", entity.id!!)).entity()
+            val entity1 = EquipmentService.select(SFilter.eq("id", entity2!!.equipId!!)).entity()
+            if (entity1!=null){
+                if (entity1.taskState == 1){
+                    entity1.taskState = null
+                    EquipmentService.update(entity1, arrayListOf("TaskState"))
+                }
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+
+        return super.onDeleteBefore(entity)
+    }
+
+    /**
+     * 统计设备下部件的类型以及数量
+     */
+    fun categoryCounts(equipScanTask: ModelScanTask): SQueryResponse<CategoryStatistics>{
+        try {
+            val projectId = SPageContext.getHeader("projectId")
+            if (!equipScanTask.id.isNullOrEmpty()&&!equipScanTask.equipId.isNullOrEmpty()){
+                val categoryStatistics = mapper.categoryStatisticsModel(projectId!!,equipScanTask.id!!, equipScanTask.equipId!!)
+                val sQueryResponse = SQueryResponse<CategoryStatistics>()
+                sQueryResponse.total = categoryStatistics.size.toLong()
+                sQueryResponse.content = categoryStatistics
+                sQueryResponse.result = SResponseType.success
+                return sQueryResponse
+            }else{
+                val sQueryResponse = SQueryResponse<CategoryStatistics>(SResponseType.failure)
+                sQueryResponse.message = "入参错误"
+                return sQueryResponse
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+            return SQueryResponse(SResponseType.failure,e.message.toString())
+        }
+    } // Fun
+
+} // Class ModelScanTaskService

+ 316 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/task/PropertyScanTaskService.kt

@@ -0,0 +1,316 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.task
+
+import cn.sagacloud.server.scanbuilding.User
+import com.alibaba.fastjson.JSONObject
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.persagy.base.extensions.toJson
+import com.persagy.database.SFilter
+import com.persagy.database.SPageQueryInfo
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.Opts
+import com.persagy.server.datacenter.models.entities.assistant.TaskPic
+import com.persagy.server.datacenter.models.entities.dict.EquipFamilyCategory
+import com.persagy.server.datacenter.models.entities.objects.Property
+import com.persagy.server.datacenter.models.entities.task.PropertyScanTask
+import com.persagy.server.datacenter.models.entities.task.SchemeUtils
+import com.persagy.server.scanbuilding.UserLog
+import com.persagy.server.services.base.RService
+import com.persagy.server.util.IdUtils
+import com.persagy.service.SBaseService
+import com.persagy.service.SObjectService
+import com.persagy.service.SPageContext
+import com.persagy.service.models.requests.SCreateRequest
+import org.slf4j.LoggerFactory
+import org.springframework.web.bind.annotation.RequestBody
+import java.util.*
+import kotlin.collections.ArrayList
+
+/**
+ * 资产台账任务
+ *
+ * @author  邓婷婷
+ */
+object PropertyScanTaskService : RService<PropertyScanTask>(SMybatisDao(PropertyScanTask::class.java)) {
+
+    // 日志
+    private val logger = LoggerFactory.getLogger(PropertyScanTaskService::class.java)
+
+    /** 扫楼日志 */
+    var userLogService = SObjectService(SMybatisDao(UserLog::class.java))
+    /** 用户 */
+    var userService = SObjectService(SMybatisDao(User::class.java))
+    /** 用户 */
+    var equipFamilyCategoryService = SObjectService(SMybatisDao(EquipFamilyCategory::class.java))
+    /**
+     * 插入之前先过滤已经存在未验证任务的对象,返回新列表
+     */
+    fun createBefore(@RequestBody request: SCreateRequest<PropertyScanTask>): SCreateRequest<PropertyScanTask> {
+        val propertyTaskList = request.content;
+        var newList = arrayListOf<PropertyScanTask>()
+        for(property in propertyTaskList){
+            val propertyTask = PropertyScanTaskService.select("equipId" to property.equipId!!,"taskState" to 1).entity()
+            if(propertyTask==null){//表示当前设备已经存在未验证的任务
+                newList.add(property)
+            }
+        }
+
+        request.content = newList
+        println(newList.size)
+        return request
+    }
+
+    /**
+     * 创建之前操作
+     */
+    override fun onCreateBefore(propertyScanTask: PropertyScanTask): Boolean {
+        try {
+            val gson = Gson()
+            var flag = false
+            if(propertyScanTask.taskState == -1){//表示当前任务是未找到状态,重新生成任务
+                flag = true
+
+                val propertyScanTaskService = SBaseService(SMybatisDao(PropertyScanTask::class.java))
+                val resetTask = propertyScanTaskService.select("equipId" to propertyScanTask.equipId!!,"taskState" to -1).entity()
+                if( resetTask!=null ){
+                    resetTask.taskState = 0
+                    propertyScanTaskService.update(resetTask)
+                }
+            }
+            val projectId = SPageContext.getHeader("projectId")
+//            if (propertyScanTask.id.isNullOrEmpty()) {
+                propertyScanTask.id = UUID.randomUUID().toString()
+//            }
+            if(!projectId.isNullOrEmpty()){
+                propertyScanTask.projectId = projectId
+            }
+            propertyScanTask.taskSource = 3//数据源为资产
+            propertyScanTask.taskState = 1//任务状态为待验证
+            propertyScanTask.taskType = "1"
+            if (!propertyScanTask.equipId.isNullOrEmpty()) {//当设备id不为空时,去设备表查询对应的详细信息
+                val propertyService = SBaseService(SMybatisDao(Property::class.java))
+                val property = propertyService.select("id" to propertyScanTask.equipId!!).entity()
+                if (propertyScanTask.schemeId.isNullOrEmpty()){
+                    propertyScanTask.schemeId = SchemeUtils.setScheme(property!!.family!!)
+                }
+//                property.ledgerParam.PhotoDoc.Pic
+                if(property!!.infos != null){//设备图片信息
+                    val photoDoc = property!!.infos!!.get("PhotoDoc")
+                    if( photoDoc != null){
+                        val obj = JSONObject.parseObject(photoDoc!!.toJson())
+                        val pic = obj.getString("Pic")
+
+                        val type = object : TypeToken<ArrayList<TaskPic>>() {
+                        }.type
+                        val siInSpList = gson.fromJson<ArrayList<TaskPic>>(pic, type)
+                        propertyScanTask.taskPicList = siInSpList
+                    }
+
+                    val containsKey = property.infos!!.containsKey(Opts.INSTALLLOCATION)
+                    if (containsKey){
+                        propertyScanTask.installLocation = property.infos!![Opts.INSTALLLOCATION].toString()
+                    }
+                }
+
+                try {
+                    if (!property.infos.isNullOrEmpty()){
+
+                        val containsKey = property.infos!!.containsKey(Opts.MANUFACTURER)
+                        if (containsKey){
+                            propertyScanTask.manufacturer = property.infos!![Opts.MANUFACTURER].toString()
+                        }
+                        val containsKey2 = property.infos!!.containsKey(Opts.SPECIFICATION)
+                        if(containsKey2) {
+                            propertyScanTask.specification = property.infos!![Opts.SPECIFICATION].toString()
+                        }
+
+                        val containsKeys = property.infos!!.containsKey(Opts.SUPPLIER)
+                        if (containsKeys){
+                            propertyScanTask.supplier =  property.infos!![Opts.SUPPLIER].toString()
+                        }
+                    }
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                }
+
+
+                if(flag){
+                    propertyScanTask.equipName = property!!.name
+                    propertyScanTask.localId = property!!.localId
+                    propertyScanTask.localName = property!!.localName
+                    propertyScanTask.bimId = property!!.bimId
+                    propertyScanTask.classCode = property!!.family
+                    propertyScanTask.buildingId = property!!.buildingId
+                    propertyScanTask.floorId = property!!.floorId
+                    propertyScanTask.cadId = property!!.cadId
+//                    propertyScanTask.supplier = property!!.dpSupplierID
+//                    propertyScanTask.specification = property!!.dpManufacturerID
+//                    propertyScanTask.manufacturer = property!!.dpMaintainerID
+                    propertyScanTask.bimLocation = property.bimLocation
+                    if (property.codeType!=null){
+                        propertyScanTask.taskType = property.codeType.toString()
+                    }else{
+                        propertyScanTask.taskType = "1"
+                    }
+                }else{
+                    if (propertyScanTask.equipName.isNullOrEmpty()) {
+                        propertyScanTask.equipName = property!!.name
+                    }
+                    if (propertyScanTask.localId.isNullOrEmpty()) {
+                        propertyScanTask.localId = property!!.localId
+                    }
+                    if (propertyScanTask.localName.isNullOrEmpty()) {
+                        propertyScanTask.localName = property!!.localName
+                    }
+                    if (propertyScanTask.bimId.isNullOrEmpty()) {
+                        propertyScanTask.bimId = property!!.bimId
+                    }
+                    if (propertyScanTask.classCode.isNullOrEmpty()) {
+                        propertyScanTask.classCode = property!!.family
+                    }
+                    if (propertyScanTask.buildingId.isNullOrEmpty()) {
+                        propertyScanTask.buildingId = property!!.buildingId
+                    }
+                    if (propertyScanTask.floorId.isNullOrEmpty()) {
+                        propertyScanTask.floorId = property!!.floorId
+                    }
+                    if (propertyScanTask.cadId.isNullOrEmpty()) {
+                        propertyScanTask.cadId = property!!.cadId
+                    }
+//                    if (propertyScanTask.supplier.isNullOrEmpty()) {
+//                        propertyScanTask.supplier = property!!.dpSupplierID
+//                    }
+//                    if (propertyScanTask.specification.isNullOrEmpty()) {
+//                        propertyScanTask.specification = property!!.dpManufacturerID
+//                    }
+//                    if (propertyScanTask.manufacturer.isNullOrEmpty()) {
+//                        propertyScanTask.manufacturer = property!!.dpMaintainerID
+//                    }
+                    if (propertyScanTask.bimLocation.isNullOrEmpty()){
+                        propertyScanTask.bimLocation = property.bimLocation
+                    }
+
+                    if (propertyScanTask.taskType.isNullOrEmpty()){
+                        if (property.codeType!=null){
+                            propertyScanTask.taskType = property.codeType.toString()
+                        }else{
+                            propertyScanTask.taskType = "1"
+                        }
+                    }
+
+                }
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return true
+    } // Function onCreateBefore()
+
+
+    override fun onDeleteBefore(entity: PropertyScanTask): Boolean {
+        val entity1 = select(SFilter.eq("id", entity.id!!)).entity()
+        val propertyService = SBaseService(SMybatisDao(Property::class.java))
+        val property = propertyService.select(SFilter.eq("id", entity1!!.equipId!!)).entity()
+        val list = ArrayList<String>()
+        list.add("TaskState")
+        property!!.taskState = null
+        propertyService.update(property,list)
+        return super.onDeleteBefore(entity)
+    }
+
+
+    /**
+     * 创建成功之后
+     */
+    override fun onCreateSuccess(propertyScanTaskList: ArrayList<PropertyScanTask>) {
+        for(task in propertyScanTaskList){
+            val property = Property()
+            val propertyService = SBaseService(SMybatisDao(Property::class.java))
+            property.id = task.equipId!!
+            property.taskState = 1
+            propertyService.update(property)
+        }
+    } // Fun onCreateSuccess
+
+    /**
+     * 状态修改完成之后
+     */
+    override fun onUpdateSuccess(list: ArrayList<PropertyScanTask>) {
+        val projectId = SPageContext.getHeader("projectId")
+        for (task in list) {
+            val propertyService = SBaseService(SMybatisDao(Property::class.java))
+            if(task.equipId == null ){
+                val propertyScanTask = PropertyScanTaskService.select("id" to task.id!!).entity()
+                task.equipId = propertyScanTask!!.equipId
+            }
+            //更改设备对象的状态
+            val propertyOld = propertyService.select("id" to task.equipId!!).entity()
+            if(propertyOld!!.taskState != -1) {//未找到
+                val property = Property()
+                property.id = task.equipId!!
+                property.taskState = task.taskState
+                propertyService.update(property)
+            }
+            try {
+                if (!Opts.coming.isNullOrEmpty()&&Opts.coming == "app"){
+                        val entity = userService.select(SFilter.eq("projectId", projectId!!), SFilter.eq("phone", Opts.account!!)).entity()
+                        val userLog = UserLog()
+                        userLog.comming = "app"
+                        userLog.action = "修改资产任务"
+                        userLog.id = IdUtils.uuidCreate()
+                        userLog.note = "确认资产任务"
+                        userLog.phone = entity?.phone
+                        userLog.projectId = projectId
+                        userLog.userId = entity!!.id
+                        userLog.name = entity.name
+                        userLog.objectId = task.id
+                        userLogService.insert(userLog)
+                }
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+        }
+
+    } // Fun onUpdateSuccess
+
+    override fun onQuerySuccess(pageInfo: SPageQueryInfo<PropertyScanTask>) {
+        if (!pageInfo.content.isNullOrEmpty()){
+            for (content in pageInfo.content!!){
+                val entity = equipFamilyCategoryService.select(SFilter.eq("family", content.classCode!!)).entity()
+                if (entity!=null) {
+                    content.equipFamily = entity
+                }else {
+
+                }
+            }
+        }
+        super.onQuerySuccess(pageInfo)
+    }
+
+} // Class PropertyScanTaskService

+ 95 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/task/RecordProblemsService.kt

@@ -0,0 +1,95 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.task
+
+import com.persagy.database.SFilter
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.Opts
+import com.persagy.server.datacenter.models.entities.task.RecordProblems
+import com.persagy.server.scanbuilding.UserLog
+import com.persagy.server.services.base.RService
+import com.persagy.server.util.IdUtils
+import com.persagy.service.SPageContext
+import org.checkerframework.checker.nullness.Opt
+
+
+/**
+ *
+ */
+object RecordProblemsService : RService<RecordProblems>(SMybatisDao(RecordProblems::class.java)){
+
+
+    override fun onCreateBefore(entity: RecordProblems): Boolean {
+        val projectId = SPageContext.getHeader("projectId")
+
+        if (entity.id.isNullOrEmpty()){
+            entity.id = IdUtils.uuidCreate()
+        }
+        if (entity.projectId.isNullOrEmpty()){
+            entity.projectId = projectId
+        }
+        try {
+            if (!Opts.account.isNullOrEmpty()) {
+                val entity1 = ModelScanTaskService.userService.select(SFilter.eq("projectId",Opts.projectId!!), SFilter.eq("phone", Opts.account!!)).entity()
+                if (entity1!=null) {
+                    entity.author = entity1.name
+                }
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return super.onCreateBefore(entity)
+    }
+
+    override fun onCreateSuccess(entityList: ArrayList<RecordProblems>) {
+        super.onCreateSuccess(entityList)
+        try {
+            if (!Opts.coming.isNullOrEmpty()&& Opts.coming == "app"){
+                val entity = ModelScanTaskService.userService.select(SFilter.eq("projectId",Opts.projectId!!), SFilter.eq("phone", Opts.account!!)).entity()
+                val userLog = UserLog()
+                userLog.comming = "app"
+                userLog.action = "问题记录"
+                userLog.id = IdUtils.uuidCreate()
+                userLog.note = "记录扫楼过程的问题"
+                userLog.phone = entity?.phone
+                userLog.projectId = Opts.projectId
+                userLog.userId = entity!!.id
+                userLog.name = entity.name
+                userLog.objectId = entityList[0].id
+                ModelScanTaskService.userLogService.insert(userLog)
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+
+    }
+
+
+
+
+
+} // Object RecordProblemsService

+ 54 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/task/ScanSchemeInfoService.kt

@@ -0,0 +1,54 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.task
+
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.datacenter.models.entities.task.ScanSchemeInfo
+import com.persagy.server.services.base.RService
+import org.slf4j.LoggerFactory
+import java.util.*
+
+/**
+ * 任务方案信息点
+ *
+ * @author  邓婷婷
+ */
+object ScanSchemeInfoService : RService<ScanSchemeInfo>(SMybatisDao(ScanSchemeInfo::class.java))  {
+
+    // 日志
+    private val logger = LoggerFactory.getLogger(ScanSchemeInfoService::class.java)
+
+    /**
+     * 创建之前操作
+     */
+    override fun onCreateBefore(scanSchemeInfo: ScanSchemeInfo): Boolean {
+        if (scanSchemeInfo.id.isNullOrEmpty()) {
+            scanSchemeInfo.id = UUID.randomUUID().toString()
+        }
+        return true
+    }
+} // Class ScanSchemeService

+ 54 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/task/ScanSchemeService.kt

@@ -0,0 +1,54 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.task
+
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.datacenter.models.entities.task.ScanScheme
+import com.persagy.server.services.base.RService
+import org.slf4j.LoggerFactory
+import java.util.*
+
+/**
+ * 方案
+ *
+ * @author  邓婷婷
+ */
+object ScanSchemeService : RService<ScanScheme>(SMybatisDao(ScanScheme::class.java))  {
+
+    // 日志
+    private val logger = LoggerFactory.getLogger(ScanSchemeService::class.java)
+
+    /**
+     * 创建之前操作
+     */
+    override fun onCreateBefore(scanScheme: ScanScheme): Boolean {
+        if (scanScheme.id.isNullOrEmpty()) {
+            scanScheme.id = UUID.randomUUID().toString()
+        }
+        return true
+    }
+} // Class ScanSchemeService

+ 234 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/task/ScanTaskBaseService.kt

@@ -0,0 +1,234 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.task
+
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.persagy.database.SFilter
+import com.persagy.database.SPageQueryInfo
+import com.persagy.mybatis.SMybatisDao
+import com.persagy.server.datacenter.models.entities.task.*
+import com.persagy.server.datacenter.models.entities.task.base.ScanTaskBase
+import com.persagy.server.mappers.StatisticsCountMapper
+import com.persagy.server.services.base.RService
+import com.persagy.service.SBaseService
+import com.persagy.service.SPageContext
+import com.persagy.service.models.enums.SResponseType
+import com.persagy.service.models.requests.SQueryRequest
+import com.persagy.service.models.responses.SQueryResponse
+import com.persagy.service.utils.SSpringContextUtil
+
+/**
+ * 任务父表
+ *
+ * @author  邓婷婷
+ */
+object ScanTaskBaseService : RService<ScanTaskBase>(SMybatisDao(ScanTaskBase::class.java))  {
+
+    /** 实例化 mapper 对象 */
+    val mapper by lazy {
+        SSpringContextUtil.getBean(StatisticsCountMapper::class.java) as StatisticsCountMapper
+    }
+
+    /**
+     * 查询所有设备类型或设备族
+     */
+    fun equipCategoryQuery(type: String): SQueryResponse<EquipCategoryDic> {
+        val pageQuery: SPageQueryInfo<EquipCategoryDic>
+        return try {
+            val equipCategoryDicService = SBaseService(SMybatisDao(EquipCategoryDic::class.java))
+            var request = SQueryRequest()
+            val queryBuilder = equipCategoryDicService.select(request.filters)
+
+            val projectId = SPageContext.getHeader("projectId").toString()
+            queryBuilder.tableName = "scantask.f_get_category('$type','$projectId')"
+            pageQuery = queryBuilder.pageQuery(1, 1000)
+            SQueryResponse(pageQuery)
+        } catch (e: Exception) {
+            e.printStackTrace()
+            SQueryResponse(SResponseType.failure, e.message!!)
+        }
+    } //  Fun equipCategoryQuery
+
+    /**
+     * 查询所有建筑和楼层
+     */
+    fun buildingQuery(type: String): SQueryResponse<BuildingDic> {
+        val pageQuery: SPageQueryInfo<BuildingDic>
+        val gson = Gson()
+        return try {
+            val projectId = SPageContext.getHeader("projectId").toString()
+            var request = SQueryRequest()
+            val service = SBaseService(SMybatisDao(BuildingDic::class.java))
+            val queryBuilder = service.select(request.filters)
+            queryBuilder.tableName = "scantask.f_get_building_dic('$type','$projectId')"
+            pageQuery = queryBuilder.pageQuery(1, 1000)
+
+            if (pageQuery.content!=null&&pageQuery.content!!.size>0){
+                for(floor in pageQuery.content!!){
+                    if(floor.floorListStr != null){
+                        val listStr = floor.floorListStr!!.replace("/\\","")
+                        val newStr = "["+listStr.substring(1,listStr.length-1)+"]"
+                        val type = object : TypeToken<ArrayList<FloorDic>>() {
+                        }.type
+                        val siInSpList = gson.fromJson<ArrayList<FloorDic>>(newStr, type)
+                        floor.floor = siInSpList
+                        floor.floorListStr = null
+                    }
+                }
+
+                if (type == "equip"||type == "property"){
+                        var taskSource: String
+                    if (type == "equip"){
+                        taskSource = "2"
+                    }else {
+                        taskSource = "3"
+                    }
+                    /** 处理楼层是否有未明确楼层 */
+                    for(building in pageQuery.content!!){
+                        if (building.floor!=null&&building.floor!!.size>0){
+
+                                val equipScanTaskList = select(
+                                    SFilter.eq("projectId", projectId), SFilter.eq("buildingId", building.id!!),
+                                        SFilter.isNull("floorId"),SFilter.eq("taskSource", taskSource)).exec()
+                                if (equipScanTaskList.size>0){
+                                    val floorDic = FloorDic()
+                                    floorDic.localName = "未明确楼层"
+                                    building.floor!!.add(0,floorDic)
+                                }
+
+                        }else{
+                            val equipScanTaskList = select(SFilter.eq("projectId", projectId), SFilter.eq("buildingId", building.id!!),
+                                    SFilter.isNull("floorId"),SFilter.eq("taskSource", taskSource)).exec()
+                            if (equipScanTaskList.size>0){
+                                val list = ArrayList<FloorDic>()
+                                val floorDic = FloorDic()
+                                floorDic.localName = "未明确楼层"
+                                list.add(floorDic)
+                                building.floor= list
+                            }
+                        }
+                    }
+                    /** 未明确建筑 */
+                    val equipScanTaskList = select(SFilter.eq("projectId", projectId), SFilter.isNull("buildingId"),SFilter.eq("taskSource", taskSource)).exec()
+                    if (equipScanTaskList.size>0){
+                        val buildingDic = BuildingDic()
+                        buildingDic.localName = "未明确建筑"
+                        pageQuery.content!!.add(0,buildingDic)
+                    }
+                }
+
+
+            }else{
+                if (type == "equip"||type == "property") {
+                    var taskSource: String
+                    if (type == "equip") {
+                        taskSource = "2"
+                    } else {
+                        taskSource = "3"
+                    }
+                    val equipScanTaskList = select(SFilter.eq("projectId", projectId), SFilter.isNull("buildingId")
+                            ,SFilter.eq("taskSource", taskSource)).exec()
+                    if (equipScanTaskList.size > 0) {
+                        val list = ArrayList<BuildingDic>()
+                        val buildingDic = BuildingDic()
+                        buildingDic.localName = "未明确建筑"
+                        list.add(buildingDic)
+                        pageQuery.content = list
+                    }
+                }
+            }
+            SQueryResponse(pageQuery)
+        } catch (e: Exception) {
+            e.printStackTrace()
+            SQueryResponse(SResponseType.failure, e.message!!)
+        }
+    } //  Fun modelFileQuery
+
+    /**
+     * 统计设备下部件的类型以及数量
+     */
+    fun categoryCounts(equipScanTask: EquipScanTask): SQueryResponse<CategoryStatistics>{
+        try {
+            val projectId = SPageContext.getHeader("projectId").toString()
+            if (!equipScanTask.id.isNullOrEmpty()&&!equipScanTask.equipId.isNullOrEmpty()){
+                val categoryStatistics = mapper.categoryStatistics(projectId,equipScanTask.id!!, equipScanTask.equipId!!)
+                val sQueryResponse = SQueryResponse<CategoryStatistics>()
+                sQueryResponse.total = categoryStatistics.size.toLong()
+                sQueryResponse.content = categoryStatistics
+                sQueryResponse.result = SResponseType.success
+                return sQueryResponse
+            }else{
+                val sQueryResponse = SQueryResponse<CategoryStatistics>(SResponseType.failure)
+                sQueryResponse.message = "入参错误"
+                return sQueryResponse
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+            return SQueryResponse(SResponseType.failure,e.message.toString())
+        }
+    } // Fun
+
+
+    /**
+     * 统计设备下部件的类型以及数量
+     */
+    fun categoryCountsModel(type: String?,equipScanTask: ModelScanTask): SQueryResponse<CategoryStatistics>{
+        try {
+            val projectId = SPageContext.getHeader("projectId")
+            if (!equipScanTask.id.isNullOrEmpty()&&!equipScanTask.equipId.isNullOrEmpty()){
+                if (!type.isNullOrEmpty()&&type == "model"){
+                    val categoryStatistics = ModelScanTaskService.mapper.categoryStatisticsModel(projectId!!,equipScanTask.id!!, equipScanTask.equipId!!)
+                    val sQueryResponse = SQueryResponse<CategoryStatistics>()
+                    sQueryResponse.total = categoryStatistics.size.toLong()
+                    sQueryResponse.content = categoryStatistics
+                    sQueryResponse.result = SResponseType.success
+                    return sQueryResponse
+                }else{
+                    val categoryStatistics = mapper.categoryStatistics(projectId!!,equipScanTask.id!!, equipScanTask.equipId!!)
+                    val sQueryResponse = SQueryResponse<CategoryStatistics>()
+                    sQueryResponse.total = categoryStatistics.size.toLong()
+                    sQueryResponse.content = categoryStatistics
+                    sQueryResponse.result = SResponseType.success
+                    return sQueryResponse
+                }
+            }else{
+                val sQueryResponse = SQueryResponse<CategoryStatistics>(SResponseType.failure)
+                sQueryResponse.message = "入参错误"
+                return sQueryResponse
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+            return SQueryResponse(SResponseType.failure,e.message.toString())
+        }
+    } // Fun
+
+
+
+
+
+}  // Fun

+ 124 - 0
scanbuilding/src/main/kotlin/com/persagy/server/services/task/SchemeService.kt

@@ -0,0 +1,124 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.services.task
+
+import com.persagy.server.datacenter.dao.mappers.SchemeMapper
+import org.slf4j.LoggerFactory
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Service
+
+/**
+ * 数据中心 方案导入服务
+ *
+ * @author 张维新
+ */
+@Service
+open class SchemeService {
+
+    companion object {
+        /** 日志 */
+        private val logger = LoggerFactory.getLogger(SchemeService::class.java)
+    } // Companion object
+
+    /** 实例化 mapper 对象 */
+    @Autowired
+    lateinit var mapper: SchemeMapper
+
+    /**
+     * 导入方案处理
+     *
+     * @param      projectId        项目id
+     * @param      schemeId         方案id
+     */
+    fun setScheme(projectId: String, schemeId: String):Boolean{
+        try {
+            mapper.setSchemeDict(projectId,schemeId)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return true
+    } // Function setScheme()
+
+    /**
+     * 导入自定义信息点
+     *
+     * @param      projectId        项目id
+     * @param      schemeId         方案id
+     */
+    fun setSchemeCustomDict(projectId: String, schemeId: String):Boolean{
+        try {
+            mapper.setSchemecustomDict(projectId,schemeId)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return true
+    } // Function setSchemeCustomDict()
+
+    /**
+     * 导入自定义信息点
+     *
+     * @param      projectId        项目id
+     * @param      schemeId         方案id
+     */
+    fun setSchemeCustomDictFalse(projectId: String, schemeId: String):Boolean{
+        try {
+            mapper.setSchemecustomDictFalse(projectId,schemeId)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return true
+    } // Function setSchemeCustomDict()
+
+    /**
+     * 导入原始字典信息
+     *
+     * @param      projectId        项目id
+     */
+    fun setControlDict(projectId: String):Boolean{
+        try {
+            mapper.setControlDict(projectId)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return true
+    } // Function setControlDict()
+
+
+    /**
+     * 处理自定义自定数据
+     */
+    fun setDictCustom():Boolean{
+        try {
+            val dict = mapper.setDict()
+            return dict
+        } catch (e: Exception) {
+            e.printStackTrace()
+            return false
+        }
+    }
+
+} // Class SchemeService

+ 262 - 0
scanbuilding/src/main/kotlin/com/persagy/server/util/IdUtils.kt

@@ -0,0 +1,262 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.util
+
+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

+ 125 - 0
scanbuilding/src/main/kotlin/com/persagy/server/util/QrCodeUntils.kt

@@ -0,0 +1,125 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .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.server.util
+
+import com.google.zxing.BarcodeFormat
+import com.google.zxing.EncodeHintType
+import com.google.zxing.WriterException
+import com.google.zxing.qrcode.QRCodeWriter
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
+import com.persagy.server.entities.User
+import java.awt.image.BufferedImage
+import java.util.*
+
+/**
+ * 二维码生成工具
+ *
+ * @author  Andy
+ */
+object QrCodeUntils {
+
+    var bgColor = 0xFFFFFF
+    var pixelColor = 0x0
+
+    /**
+     * 创建二维码图像
+     *
+     * @param   contents        二维码存储的内容
+     * @param   size            二维码大小
+     * @return  二维码图像
+     */
+    fun createQrCode(contents: String, size: Int, logo: BufferedImage? = null): BufferedImage? {
+        try {
+            val hints = Hashtable<EncodeHintType, Any>()
+            hints[EncodeHintType.CHARACTER_SET] = "utf-8"
+            hints[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.L
+
+            val matrix = QRCodeWriter().encode(contents, BarcodeFormat.QR_CODE, size, size, hints)
+            var image = BufferedImage(size, size, BufferedImage.TYPE_INT_RGB)
+            for (y in 0 until size) {
+                for (x in 0 until size) {
+                    if (matrix.get(x, y)) {
+                        image.setRGB(x, y, pixelColor)
+                    } else {
+                        image.setRGB(x, y, bgColor)
+                    }
+                }
+            }
+
+            if (null != logo) {
+                image = addLogo(image, logo)
+            }
+
+            return image
+        } catch (e: WriterException) {
+            e.printStackTrace()
+        }
+        return null
+    } // Function createQrCode()
+
+    /**
+     * 为二维码图片增加Logo
+     *
+     * @param   src         二维码图片
+     * @param   logo        Logol图片
+     * @return  添加过Logo的二维码图片
+     */
+    private fun addLogo(src: BufferedImage, logo: BufferedImage): BufferedImage {
+        val srcWidth = src.width
+        val srcHeight = src.height
+        val logoWidth = logo.width
+        val logoHeight = logo.height
+
+
+        val image = BufferedImage(srcWidth, srcHeight, BufferedImage.TYPE_4BYTE_ABGR)
+        val gd = image.createGraphics()
+        gd.drawImage(src,0,0, null)
+        gd.drawImage(logo,srcWidth * 2 / 5, srcHeight * 2 / 5, srcWidth * 3 / 5, srcHeight / 5, null)
+
+        return image
+    } // Function addLogo()
+
+    /**
+     * 生成uuid
+     *
+     * @return              uuid
+     */
+    fun uuidCreate(): String {
+        val uuid = UUID.randomUUID().toString()
+        return uuid.replace("-", "")
+    } // Function uuidCreate
+
+    fun toLog(user: User, coming: String?): String{
+        var str =""
+        str = "手机号:"+user.phone+" 项目ID "+user.projectId+" 用户ID "+ user.userId + " 用户名:"+user.userName
+        if (!coming.isNullOrEmpty()){
+            str += " 请求来源: "+coming!!
+        }
+        return str
+    } // Function toLog
+
+} // Object QrCodeUntils

+ 16 - 0
scanbuilding/src/main/resources/application-dev.yml

@@ -0,0 +1,16 @@
+server:
+  port: 8083
+
+spring:
+  datasource:
+#    url:                                jdbc:postgresql://172.16.44.234:5432/datacenter
+#    username:                           postgres
+#    password:                           123456
+#    url:                                jdbc:postgresql://39.102.40.239:5432/datacenter
+#    url:                                jdbc:postgresql://60.205.177.43:5432/datacenterlabsl
+#    url:                                jdbc:postgresql://192.168.64.15:5432/datacenter
+    url:                                jdbc:postgresql://192.168.64.14:5432/datacenterlabsl
+    username:                           postgres
+    #    password:                           persagy_2020qwe!@#
+    password:                           cGVyc2FneV8yMDIwcXdlIUAj
+

+ 31 - 0
scanbuilding/src/main/resources/application-prod.yml

@@ -0,0 +1,31 @@
+server:
+  port: 8080
+
+spring:
+  datasource:
+    #    url:                                jdbc:postgresql://data-center:5432/datacenter
+    #    username:                           postgres
+    #    password:                           123qwe!@#
+    url:                                jdbc:postgresql://172.17.23.64:5432/datacenter
+#    url:                                jdbc:postgresql://172.17.11.228: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}

+ 16 - 0
scanbuilding/src/main/resources/application-test.yml

@@ -0,0 +1,16 @@
+server:
+  port: 8080
+
+spring:
+  datasource:
+    #    url:                                jdbc:postgresql://data-center:5432/datacenter
+    #    username:                           postgres
+    #    password:                           123qwe!@#
+#    url:                                jdbc:postgresql://172.17.100.16:5432/datacenter
+#    url:                                jdbc:postgresql://datacenter:5432/datacenter
+    url:                                jdbc:postgresql://datacenter:5432/datacenterlabsl
+    username:                           postgres
+    #    password:                           persagy_2020qwe!@#
+    password:                           cGVyc2FneV8yMDIwcXdlIUAj
+
+

+ 62 - 0
scanbuilding/src/main/resources/application.yml

@@ -0,0 +1,62 @@
+###############################################################################################################
+# 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:
+  application:
+    name:                               scanbuilding
+  mvc:
+    favicon:
+      enabled:                          true
+
+  jmx:
+    default-domain:                     scanbuilding
+
+  datasource:
+    name:                               scanbuilding
+    type:                               com.alibaba.druid.pool.DruidDataSource
+    driver-class-name:                  com.mysql.cj.jdbc.Driver
+    url:                                jdbc:mysql://rm-2ze20ntn5y9ljsx147o.mysql.rds.aliyuncs.com:3306/scanbuilding?allowMultiQueries=true&serverTimezone=UTC&useUnicode=true&useSSL=false&characterEncoding=UTF-8
+    username:                           root
+    password:                           zVmW58LaAtjIKbb
+  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.server
+  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

+ 44 - 0
scanbuilding/src/main/resources/logback-spring.xml

@@ -0,0 +1,44 @@
+<!--
+  ~ **********************************************************************************************************************
+  ~
+  ~          !!
+  ~        .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.
+  ~
+  ~ **********************************************************************************************************************
+  -->
+
+<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>

+ 2 - 1
settings.gradle

@@ -5,4 +5,5 @@ include 'labsl'             // 蜡笔森林
 include 'meiku'             // 美库
 include 'revit-algorithm'   // 模型
 include 'scheduler'         // 调度器
-include 'data-core'         // 数据中心
+include 'data-core'         // 数据中心
+include 'scanbuilding'      // 扫楼服务