浏览代码

add poc2.0需求

lihao1 3 年之前
父节点
当前提交
9b4be65bc4
共有 51 个文件被更改,包括 1842 次插入233 次删除
  1. 37 37
      cadengine/src/main/java/cn/sagacloud/android/cadengine/items/DoorItem.kt
  2. 10 1
      cadengine/src/main/java/cn/sagacloud/android/cadengine/items/EquipItem.kt
  3. 1 1
      cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Column.kt
  4. 3 3
      cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Door.kt
  5. 7 0
      cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Point.kt
  6. 1 1
      cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Space.kt
  7. 1 1
      cadengine/src/main/java/cn/sagacloud/android/cadengine/types/VirtualWall.kt
  8. 1 1
      cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Wall.kt
  9. 1 1
      cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Window.kt
  10. 2 1
      demo/src/main/java/com/framework/app/Constants.kt
  11. 3 0
      demo/src/main/java/com/framework/mvvm/model/db/dao/EquipmentDao.kt
  12. 3 0
      demo/src/main/java/com/framework/mvvm/model/db/dao/InfosConfigDao.kt
  13. 6 0
      demo/src/main/java/com/framework/mvvm/model/db/dao/ObjectDao.kt
  14. 7 0
      demo/src/main/java/com/framework/mvvm/model/db/dao/PipeConfigDao.kt
  15. 9 0
      demo/src/main/java/com/framework/mvvm/model/db/dao/PipeDao.kt
  16. 3 0
      demo/src/main/java/com/framework/mvvm/model/db/dao/ProblemEquipDao.kt
  17. 6 0
      demo/src/main/java/com/framework/mvvm/model/db/dao/RelConfigDao.kt
  18. 18 0
      demo/src/main/java/com/framework/mvvm/model/db/dao/RelationDao.kt
  19. 3 0
      demo/src/main/java/com/framework/mvvm/model/db/dao/SystemDao.kt
  20. 2 0
      demo/src/main/java/com/framework/mvvm/model/db/entity/EquipmentEntity.kt
  21. 7 1
      demo/src/main/java/com/framework/mvvm/model/db/entity/ObjectEntity.kt
  22. 5 2
      demo/src/main/java/com/framework/mvvm/model/db/entity/PipeEntity.kt
  23. 1 1
      demo/src/main/java/com/framework/mvvm/model/db/entity/ProblemArchEntity.kt
  24. 5 2
      demo/src/main/java/com/framework/mvvm/model/db/entity/RelationEntity.kt
  25. 96 0
      demo/src/main/java/com/framework/mvvm/model/repository/AdmRepository.kt
  26. 291 12
      demo/src/main/java/com/sybotan/android/demo/activities/EquipDetailActivity.kt
  27. 90 48
      demo/src/main/java/com/sybotan/android/demo/activities/GraphyActivity.kt
  28. 1 1
      demo/src/main/java/com/sybotan/android/demo/activities/PocActivity.kt
  29. 18 5
      demo/src/main/java/com/sybotan/android/demo/activities/SpaceDetailActivity.kt
  30. 33 0
      demo/src/main/java/com/sybotan/android/demo/adapter/EquipListAdapter.java
  31. 3 0
      demo/src/main/java/com/sybotan/android/demo/adapter/PictureAdapter.java
  32. 128 0
      demo/src/main/java/com/sybotan/android/demo/adapter/PipeExpandAdapter.kt
  33. 55 13
      demo/src/main/java/com/sybotan/android/demo/adapter/RelationExpandAdapter.kt
  34. 5 0
      demo/src/main/java/com/sybotan/android/demo/adapter/SelectPopListAdapter.java
  35. 112 4
      demo/src/main/java/com/sybotan/android/demo/adapter/StaticInfoAdapter.java
  36. 2 0
      demo/src/main/java/com/sybotan/android/demo/bean/result/Children.java
  37. 4 3
      demo/src/main/java/com/sybotan/android/demo/retrofit/Constant.java
  38. 39 2
      demo/src/main/java/com/sybotan/android/demo/view/EquipListDialog.java
  39. 1 1
      demo/src/main/java/com/sybotan/android/demo/view/ListItemView.java
  40. 21 5
      demo/src/main/java/com/sybotan/android/demo/view/ObjectRelationDialog.java
  41. 121 0
      demo/src/main/java/com/sybotan/android/demo/view/PipeDialog.java
  42. 641 72
      demo/src/main/java/com/sybotan/android/demo/viewmodel/GraphyVM.kt
  43. 20 2
      demo/src/main/res/layout/activity_equip_detail.xml
  44. 1 1
      demo/src/main/res/layout/activity_graphy.xml
  45. 3 0
      demo/src/main/res/layout/activity_space_detail.xml
  46. 1 1
      demo/src/main/res/layout/child_expand_relation.xml
  47. 3 1
      demo/src/main/res/layout/dialog_object_relation.xml
  48. 3 0
      demo/src/main/res/layout/geometry_info.xml
  49. 0 1
      demo/src/main/res/layout/layout_common_list_item1.xml
  50. 1 1
      demo/src/main/res/layout/view_mtext.xml
  51. 7 7
      sybotan-android-graphy/src/main/java/com/sybotan/android/graphy/SGraphyItem.kt

+ 37 - 37
cadengine/src/main/java/cn/sagacloud/android/cadengine/items/DoorItem.kt

@@ -50,14 +50,14 @@ class DoorItem(private val data: Door, parent: SGraphyItem? = null) : SGraphyIte
                 d = sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y))
 
                 // 角度为
-                val fo = atan2(-data.faceDirection!!.y, data.faceDirection!!.x)
-                // 门朝向角度
-                angle =
-                        if (data.faceDirection!!.x > 0) {
-                            fo
-                        } else {
-                            fo + Math.PI.toFloat()
-                        }
+//                val fo = atan2(-data.faceDirection!!.y, data.faceDirection!!.x)
+//                // 门朝向角度
+//                angle =
+//                        if (data.faceDirection!!.x > 0) {
+//                            fo
+//                        } else {
+//                            fo + Math.PI.toFloat()
+//                        }
 
 ////                val dir = data.faceDirection!!.x * (data.handDirection!!.y - data.faceDirection!!.y) - data.faceDirection!!.y * (data.handDirection!!.x - data.faceDirection!!.x)
 ////                if (dir < 0) {
@@ -65,35 +65,35 @@ class DoorItem(private val data: Door, parent: SGraphyItem? = null) : SGraphyIte
 ////                }
 
                 // 计算旋转点
-                if (abs(data.handDirection!!.x) > abs(data.handDirection!!.y)) {
-                    p = if (data.handDirection!!.x > 0) {
-                        if (p1.x > p2.x) {
-                            p1
-                        } else {
-                            p2
-                        }
-                    } else {
-                        if (p1.x < p2.x) {
-                            p1
-                        } else {
-                            p2
-                        }
-                    }
-                } else {
-                    p = if (data.handDirection!!.y > 0) {
-                        if (p1.y > p2.y) {
-                            p1
-                        } else {
-                            p2
-                        }
-                    } else {
-                        if (p1.y < p2.y) {
-                            p1
-                        } else {
-                            p2
-                        }
-                    }
-                }
+//                if (abs(data.handDirection!!.x) > abs(data.handDirection!!.y)) {
+//                    p = if (data.handDirection!!.x > 0) {
+//                        if (p1.x > p2.x) {
+//                            p1
+//                        } else {
+//                            p2
+//                        }
+//                    } else {
+//                        if (p1.x < p2.x) {
+//                            p1
+//                        } else {
+//                            p2
+//                        }
+//                    }
+//                } else {
+//                    p = if (data.handDirection!!.y > 0) {
+//                        if (p1.y > p2.y) {
+//                            p1
+//                        } else {
+//                            p2
+//                        }
+//                    } else {
+//                        if (p1.y < p2.y) {
+//                            p1
+//                        } else {
+//                            p2
+//                        }
+//                    }
+//                }
             }
         } catch (e: Exception) {
             e.printStackTrace()

+ 10 - 1
cadengine/src/main/java/cn/sagacloud/android/cadengine/items/EquipItem.kt

@@ -36,7 +36,16 @@ class EquipItem(
         if (defaultScale != null) {
             mDefaultScale = defaultScale
         }
-        mBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.equip_blue)
+        //1-蓝 2-绿 3-红
+        if (data.equipState == 1) {
+            mBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.equip_blue)
+        } else if (data.equipState == 2) {
+            mBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.equip_green)
+        } else if (data.equipState == 3) {
+            mBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.equip_red)
+        } else {
+            mBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.equip_blue)
+        }
         /** 新建 */
         //内圈
         mPaint_inner.color = Color.parseColor("#66272727")

+ 1 - 1
cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Column.kt

@@ -15,7 +15,7 @@ class Column {
     /** 房间边界  */
     var roomBoundary: Boolean? = null
     /** 位置  */
-    var location: Place? = null
+//    var location: Place? = null
     /** 模型id(外键)    */
     var modelId: String? = null
     /** 对应Revit模型id */

+ 3 - 3
cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Door.kt

@@ -9,11 +9,11 @@ import android.graphics.PointF
  */
 class Door {
     /** 面朝方向  */
-    var faceDirection: PointF? = null
+//    var faceDirection: PointF? = null
     /** 把手方向  */
-    var handDirection: PointF? = null
+//    var handDirection: PointF? = null
     /** 位置  */
-    var location: Place? = null
+//    var location: Place? = null
     /** 模型id(外键)    */
     var modelId: String? = null
     /** 名称  */

+ 7 - 0
cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Point.kt

@@ -7,6 +7,8 @@ import java.util.ArrayList
  * Date: 2021/6/4
  */
 class Point {
+
+
     //问题id
     var id: String? = null
 
@@ -15,6 +17,7 @@ class Point {
 
     /** Y坐标  */
     var mY = 0f
+    var z: String? = null
 
     var scalePoint = 1.0f
     var remark: String? = null
@@ -24,5 +27,9 @@ class Point {
     var spaceId: String? = null
     var content: String? = null
     var floorId: String? = null
+    var deviceId: String? = null
     var photos: ArrayList<Photos> = ArrayList()
+
+    //1-蓝 2-绿 3-红
+    var equipState: Int? = 0
 }

+ 1 - 1
cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Space.kt

@@ -11,7 +11,7 @@ class Space {
     /** 轮廓线段    */
     var boundarySegments: ArrayList<String>? = null
     /** 位置  */
-    var location: Place? = null
+//    var location: Place? = null
     /** 模型id(外键)    */
     var modelId: String? = null
     /** 名称  */

+ 1 - 1
cadengine/src/main/java/cn/sagacloud/android/cadengine/types/VirtualWall.kt

@@ -9,7 +9,7 @@ import android.graphics.PointF
  */
 class VirtualWall {
     /** 位置  */
-    var location: Place? = null
+//    var location: Place? = null
     /** 模型id(外键)    */
     var modelId: String? = null
     /** 名称  */

+ 1 - 1
cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Wall.kt

@@ -11,7 +11,7 @@ class Wall {
     /** 层id */
     var levelId: String? = null
     /** 位置  */
-    var location: Place? = null
+//    var location: Place? = null
     /** 模型id(外键)    */
     var modelId: String? = null
     /** 名称  */

+ 1 - 1
cadengine/src/main/java/cn/sagacloud/android/cadengine/types/Window.kt

@@ -9,7 +9,7 @@ import android.graphics.PointF
  */
 class Window {
     /** 位置  */
-    var location: PointF? = null
+//    var location: PointF? = null
     /** 模型id(外键)    */
     var modelId: String? = null
     /** 名称  */

+ 2 - 1
demo/src/main/java/com/framework/app/Constants.kt

@@ -3,7 +3,8 @@ package com.framework.app
 /**
  * 测试服务器 IP
  */
-const val testIP = "http://192.168.0.48:8876/"
+//const val testIP = "http://192.168.0.48:8876/"
+const val testIP = "http://82.157.28.170:8876/"
 
 const val tencentIP = "http://82.157.28.170:8876/"
 

+ 3 - 0
demo/src/main/java/com/framework/mvvm/model/db/dao/EquipmentDao.kt

@@ -14,6 +14,9 @@ interface EquipmentDao {
     @Query("select * from equipment where id = :id")
     suspend fun getEquipmentById(id: String): EquipmentEntity
 
+    @Query("select * from equipment where code = :code and valid = 1")
+    suspend fun getEquipmentByCode(code: String): EquipmentEntity
+
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insEquipment(vararg equipment: EquipmentEntity)
 

+ 3 - 0
demo/src/main/java/com/framework/mvvm/model/db/dao/InfosConfigDao.kt

@@ -17,6 +17,9 @@ interface InfosConfigDao {
     @Query("select * from infos_config where obj_type = :type")
     suspend fun getConfigByObjType(type: String): List<InfosConfigEntity>
 
+    @Query("select * from infos_config where obj_type = :type and class_code =:code")
+    suspend fun getConfigByEquipCode(type: String, code: String): List<InfosConfigEntity>
+
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insConfig(vararg config: InfosConfigEntity)
 

+ 6 - 0
demo/src/main/java/com/framework/mvvm/model/db/dao/ObjectDao.kt

@@ -23,6 +23,12 @@ interface ObjectDao {
     @Query("select * from object where building_id = :buildingId")
     suspend fun getObjectByBuildingId(buildingId: String): List<ObjectEntity>
 
+    @Query("select * from object where floor_id = :floorId and obj_type=:type")
+    suspend fun getEquipByFloorId(floorId: String, type: String): List<ObjectEntity>
+
+    @Query("select * from object where class_code = :code")
+    suspend fun getObjectByCode(code: String): List<ObjectEntity>
+
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insObject(vararg obj: ObjectEntity)
 

+ 7 - 0
demo/src/main/java/com/framework/mvvm/model/db/dao/PipeConfigDao.kt

@@ -2,6 +2,7 @@ package com.framework.mvvm.model.db.dao
 
 import androidx.room.*
 import com.framework.mvvm.model.db.entity.PipeConfigEntity
+import com.framework.mvvm.model.db.entity.RelConfigEntity
 
 /**
  * 表 pipe_config Dao
@@ -14,6 +15,12 @@ interface PipeConfigDao {
     @Query("select * from pipe_config where id = :id")
     suspend fun getConfigById(id: String): PipeConfigEntity
 
+    @Query("select * from pipe_config where class_code_from = :code")
+    suspend fun getConfigByCodeFrom(code: String): List<PipeConfigEntity>
+
+    @Query("select * from pipe_config where class_code_to = :code")
+    suspend fun getConfigByCodeTo(code: String): List<PipeConfigEntity>
+
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insConfig(vararg config: PipeConfigEntity)
 

+ 9 - 0
demo/src/main/java/com/framework/mvvm/model/db/dao/PipeDao.kt

@@ -18,6 +18,15 @@ interface PipeDao {
     @Query("select * from pipe where building_id = :id")
     suspend fun getPipeByBuildingId(id: String): List<PipeEntity>
 
+    @Query("select * from pipe where obj_from = :id and pipe_type = :pipeType and valid = 1")
+    suspend fun getPipeByIdFrom(id: String, pipeType: String): List<PipeEntity>
+
+    @Query("select * from pipe where obj_to = :id and pipe_type = :pipeType and valid = 1")
+    suspend fun getPipeByIdTo(id: String, pipeType: String): List<PipeEntity>
+
+    @Query("select * from pipe where floor_id = :floorId and valid = 1")
+    suspend fun getPipeByFloorId(floorId: String): List<PipeEntity>
+
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insPipe(vararg pipe: PipeEntity)
 

+ 3 - 0
demo/src/main/java/com/framework/mvvm/model/db/dao/ProblemEquipDao.kt

@@ -17,6 +17,9 @@ interface ProblemEquipDao {
     @Query("select * from problem_equip where building_id = :id")
     suspend fun getProblemByBuildingId(id: String): List<ProblemEquipEntity>
 
+    @Query("select * from problem_equip where equip_id = :id")
+    suspend fun getProblemByEquipId(id: String): ProblemEquipEntity?
+
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insProblem(vararg problem: ProblemEquipEntity)
 

+ 6 - 0
demo/src/main/java/com/framework/mvvm/model/db/dao/RelConfigDao.kt

@@ -14,6 +14,12 @@ interface RelConfigDao {
     @Query("select * from rel_config where id = :id")
     suspend fun getConfigById(id: String): RelConfigEntity
 
+    @Query("select * from rel_config where class_code_from = :code")
+    suspend fun getConfigByCodeFrom(code: String): List<RelConfigEntity>
+
+    @Query("select * from rel_config where class_code_to = :code")
+    suspend fun getConfigByCodeTo(code: String): List<RelConfigEntity>
+
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insConfig(vararg config: RelConfigEntity)
 

+ 18 - 0
demo/src/main/java/com/framework/mvvm/model/db/dao/RelationDao.kt

@@ -17,6 +17,23 @@ interface RelationDao {
     @Query("select * from relation where building_id = :id")
     suspend fun getRelationByBuildingId(id: String): List<RelationEntity>
 
+    @Query("select * from relation where graph_code = :graphCode and rel_code = :relCode and valid = 1")
+    suspend fun getRelationByCode(graphCode: String, relCode: String): List<RelationEntity>
+
+    @Query("select * from relation where graph_code = :graphCode and rel_code = :relCode and obj_from=:equipId and valid = 1")
+    suspend fun getRelationByCodeFrom(
+        graphCode: String,
+        relCode: String,
+        equipId: String
+    ): List<RelationEntity>
+
+    @Query("select * from relation where graph_code = :graphCode and rel_code = :relCode and obj_to=:equipId and valid = 1")
+    suspend fun getRelationByCodeTo(
+        graphCode: String,
+        relCode: String,
+        equipId: String
+    ): List<RelationEntity>
+
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insRelation(vararg relation: RelationEntity)
 
@@ -28,4 +45,5 @@ interface RelationDao {
 
     @Delete
     suspend fun delRelation(relation: RelationEntity)
+
 }

+ 3 - 0
demo/src/main/java/com/framework/mvvm/model/db/dao/SystemDao.kt

@@ -22,4 +22,7 @@ interface SystemDao {
 
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insSystems(systems: List<SystemEntity>)
+
+    @Query("select * from system where code = :code")
+    suspend fun getSysByCode(code: String): SystemEntity
 }

+ 2 - 0
demo/src/main/java/com/framework/mvvm/model/db/entity/EquipmentEntity.kt

@@ -27,4 +27,6 @@ data class EquipmentEntity(
     @ColumnInfo(name = "alias_code") val aliasCode: String?,      // 编码别名
     @ColumnInfo(name = "alias_name") val aliasName: String?,      // 名称别名
     @ColumnInfo(name = "version") val version: String?,              // 版本
+
+    @ColumnInfo(name = "system_name") var systemName: String?,       // 系统编码
 )

+ 7 - 1
demo/src/main/java/com/framework/mvvm/model/db/entity/ObjectEntity.kt

@@ -37,7 +37,7 @@ data class ObjectEntity(
     @ColumnInfo(name = "client_device") val clientDevice: String?,  // 标识客户端设备
     @ColumnInfo(name = "client_id") val clientId: String?,          // 客户端生成id
     @ColumnInfo(name = "update_app") val updateApp: String?,        // 更新对象的应用
-    @ColumnInfo(name = "upload_flag") val uploadFlag: String?,      // app端上传数据标记
+    @ColumnInfo(name = "upload_flag") var uploadFlag: String?,      // app端上传数据标记
     @ColumnInfo(name = "valid") val valid: Int?,                    // 合法标识: 1 合法, 0 非法
     @ColumnInfo(name = "delivery_state") val deliveryState: Int?,   // BDTP交付状态: 1 已交付, 0 待交付
     @ColumnInfo(name = "d2m_state") val d2mState: Int?,             // 逆向数据的数模同步状态(0:未同步;1:已同步)
@@ -85,3 +85,9 @@ data class StrInfosforBuild(
     val state: String,
     val height: Int,
 )
+
+data class StrInfosforEquip(
+    val location: PointZ,
+    var zRegion: String,
+    var equipCheck: Boolean
+)

+ 5 - 2
demo/src/main/java/com/framework/mvvm/model/db/entity/PipeEntity.kt

@@ -28,9 +28,12 @@ data class PipeEntity(
     @ColumnInfo(name = "creation_time") val creationTime: Long?,      // 创建时间
     @ColumnInfo(name = "modifier") val modifier: String?,             // 修改人
     @ColumnInfo(name = "modified_time") val modifiedTime: Long?,      // 修改时间
-    @ColumnInfo(name = "valid") val valid: Int?,                      // 合法标识
+    @ColumnInfo(name = "valid") var valid: Int?,                      // 合法标识
     @ColumnInfo(name = "upload_flag") val uploadFlag: String?,        // app端上传数据标记
     @ColumnInfo(name = "d2m_state") val d2mState: String?,            // 逆向数据的数模同步状态(0:未同步;1:已同步)
     @ColumnInfo(name = "delivery_state") val deliveryState: String?,  // 交付BDTP状态:1已交付,0待交付
-    @ColumnInfo(name = "state") var state: String? = "0"               // 数据状态:0:未处理,1:已处理 2:已上传
+    @ColumnInfo(name = "state") var state: String? = "0",               // 数据状态:0:未处理,1:已处理 2:已上传
+
+    var objFromLocalId: String?,
+    var objToLocalId: String?
 )

+ 1 - 1
demo/src/main/java/com/framework/mvvm/model/db/entity/ProblemArchEntity.kt

@@ -24,7 +24,7 @@ data class ProblemArchEntity(
     @ColumnInfo(name = "creation_time") val creationTime: String?,  // 创建时间
     @ColumnInfo(name = "modifier") val modifier: String?,           // 修改人
     @ColumnInfo(name = "modified_time") val modifiedTime: String?,  // 修改时间
-    @ColumnInfo(name = "upload_flag") val uploadFlag: String?,      // app端上传数据标记
+    @ColumnInfo(name = "upload_flag") var uploadFlag: String?,      // app端上传数据标记
     @ColumnInfo(name = "valid") val valid: Int?,                    // 1 有效,2 无效
     @ColumnInfo(name = "geom") val geom: String?,                   // 问题记录的几何数据(Json)
     @ColumnInfo(name = "state") var state: String? = "0"             // 数据状态:0:未处理,1:已处理 2:已上传

+ 5 - 2
demo/src/main/java/com/framework/mvvm/model/db/entity/RelationEntity.kt

@@ -35,7 +35,10 @@ data class RelationEntity(
     @ColumnInfo(name = "client_device") val clientDevice: String?,   // 标识客户端设备
     @ColumnInfo(name = "upload_flag") val uploadFlag: String?,       // app端上传数据标记
     @ColumnInfo(name = "delivery_state") val deliveryState: Int?,    // BDTP交付状态: 1 已交付, 0 待交付
-    @ColumnInfo(name = "valid") val valid: Int?,                     // 合法标识: 1 合法, 0 非法
+    @ColumnInfo(name = "valid") var valid: Int?,                     // 合法标识: 1 合法, 0 非法
     @ColumnInfo(name = "d2m_state") val d2mState: Int?,              // 逆向数据的数模同步状态(0:未同步;1:已同步)
-    @ColumnInfo(name = "state") var state: String? = "0"              // 数据状态:0:未处理,1:已处理 2:已上传
+    @ColumnInfo(name = "state") var state: String? = "0",             // 逆向数据的数模同步状态(0:未同步;1:已同步)
+
+    var objFromLocalId: String?,
+    var objToLocalId: String?
 )

+ 96 - 0
demo/src/main/java/com/framework/mvvm/model/repository/AdmRepository.kt

@@ -111,6 +111,102 @@ class AdmRepository(
         return db.spaceDao().insSpace(space)
     }
 
+    suspend fun getEquipByFloorId(id: String): List<ObjectEntity> {
+        return db.objectDao().getEquipByFloorId(id, "equipment")
+    }
+
+    suspend fun getEquipByCode(code: String): EquipmentEntity {
+        return db.equipmentDao().getEquipmentByCode(code)
+    }
+
+    suspend fun getEquipment(): List<EquipmentEntity> {
+        return db.equipmentDao().getEquipments()
+    }
+
+    suspend fun getSysByCode(code: String): SystemEntity {
+        return db.systemDao().getSysByCode(code)
+    }
+
+    suspend fun getEqProblem(equipId: String): ProblemEquipEntity? {
+        return db.problemEquipDao().getProblemByEquipId(equipId)
+    }
+
+    suspend fun getRelConfigByCodeFrom(code: String): List<RelConfigEntity> {
+        return db.relConfigDao().getConfigByCodeFrom(code)
+    }
+
+    suspend fun getRelConfigByCodeTo(code: String): List<RelConfigEntity> {
+        return db.relConfigDao().getConfigByCodeTo(code)
+    }
+
+    suspend fun getPipeConfigByCodeFrom(code: String): List<PipeConfigEntity> {
+        return db.pipeConfigDao().getConfigByCodeFrom(code)
+    }
+
+    suspend fun getPipeConfigByCodeTo(code: String): List<PipeConfigEntity> {
+        return db.pipeConfigDao().getConfigByCodeTo(code)
+    }
+
+    suspend fun getRelByCode(graphCode: String, relCode: String): List<RelationEntity> {
+        return db.relationDao().getRelationByCode(graphCode, relCode)
+    }
+    suspend fun getRelById(id: String): RelationEntity {
+        return db.relationDao().getRelationById(id)
+    }
+
+    suspend fun getRelByCodeFrom(
+        graphCode: String,
+        relCode: String,
+        equipId: String
+    ): List<RelationEntity> {
+        return db.relationDao().getRelationByCodeFrom(graphCode, relCode, equipId)
+    }
+
+    suspend fun getRelByCodeTo(
+        graphCode: String,
+        relCode: String,
+        equipId: String
+    ): List<RelationEntity> {
+        return db.relationDao().getRelationByCodeTo(graphCode, relCode, equipId)
+    }
+
+    suspend fun getPipeByFloorId(floorId: String): List<PipeEntity> {
+        return db.pipeDao().getPipeByFloorId(floorId)
+    }
+    suspend fun getPipeById(id: String): PipeEntity {
+        return db.pipeDao().getPipeById(id)
+    }
+
+    suspend fun getPipeByIdFrom(equipId: String, pipeType: String): List<PipeEntity> {
+        return db.pipeDao().getPipeByIdFrom(equipId, pipeType)
+    }
+
+    suspend fun getPipeByIdTo(equipId: String, pipeType: String): List<PipeEntity> {
+        return db.pipeDao().getPipeByIdTo(equipId, pipeType)
+    }
+
+    suspend fun getObjectByCode(code: String): List<ObjectEntity> {
+        return db.objectDao().getObjectByCode(code)
+    }
+
+    suspend fun getInfosConfigByEquipCode(code: String): List<InfosConfigEntity> {
+        return db.infosConfigDao().getConfigByEquipCode("equipment", code)
+    }
+
+    suspend fun insRelation(relation: RelationEntity) {
+        return db.relationDao().insRelation(relation)
+    }
+
+    suspend fun insPipe(relation: PipeEntity) {
+        return db.pipeDao().insPipe(relation)
+    }
+
+    suspend fun insProblemEquipEntity(problem: ProblemEquipEntity) {
+        return db.problemEquipDao().insProblem(problem)
+    }
+
+
+
     /**
      * 请求框架数据
      */

+ 291 - 12
demo/src/main/java/com/sybotan/android/demo/activities/EquipDetailActivity.kt

@@ -6,10 +6,11 @@ import android.graphics.Color
 import android.os.Bundle
 import android.text.TextUtils
 import android.util.Log
+import android.view.Gravity
 import android.view.MotionEvent
 import android.view.View
-import android.widget.EditText
-import android.widget.ImageView
+import android.widget.*
+import androidx.appcompat.widget.SwitchCompat
 import androidx.core.widget.NestedScrollView
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.LinearLayoutManager
@@ -18,25 +19,36 @@ import com.bumptech.glide.Glide
 import com.sybotan.android.demo.R
 import com.sybotan.android.demo.adapter.StaticInfoAdapter
 import cn.sagacloud.android.cadengine.types.Photos
-import com.framework.mvvm.model.db.entity.Infos
+import com.framework.mvvm.model.db.entity.*
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
 import com.sybotan.android.demo.adapter.PictureAdapter
+import com.sybotan.android.demo.adapter.PipeExpandAdapter
+import com.sybotan.android.demo.adapter.RelationExpandAdapter
+import com.sybotan.android.demo.bean.result.Position
+import com.sybotan.android.demo.bean.result.Z
 import com.sybotan.android.demo.retrofit.Constant
+import com.sybotan.android.demo.tools.*
 import com.sybotan.android.demo.tools.LocalDataOperation.*
-import com.sybotan.android.demo.tools.PictureUtils
-import com.sybotan.android.demo.tools.ToastUtils
-import com.sybotan.android.demo.tools.UploadImage
+import com.sybotan.android.demo.view.*
+import com.sybotan.android.demo.viewmodel.GraphyVM
+import com.sybotan.base.extensions.toBoolean
 import com.yuyh.library.imgsel.ImageLoader
 import com.yuyh.library.imgsel.ImgSelConfig
 import io.reactivex.ObservableEmitter
 import org.json.JSONException
 import org.json.JSONObject
 import java.io.File
+import java.util.*
+import kotlin.collections.ArrayList
 
 /**
  * Created by lihao.
  * Date: 2021/9/27
  */
 class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
+    private var equipEntity: EquipmentEntity? = null
+
     //选择图片
     private val REQUEST_CODE_PIC = 0X102
 
@@ -44,11 +56,39 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
     private lateinit var recycler: RecyclerView
     private lateinit var viewRecycler: RecyclerView
     private lateinit var mtextContent: EditText
+    private lateinit var localName: ListItemView
+    private lateinit var localId: ListItemView
+    private lateinit var location: ListItemView
+    private lateinit var doneSwitch: SwitchCompat
+    private lateinit var height: ListItemView
+    private lateinit var locationWhere: ListItemView
+    private lateinit var equipClass: ListItemView
     private lateinit var root: NestedScrollView
+    private lateinit var btnSubmit: TextView
+    private lateinit var expandLvPipe: ExpandableListView
+    private lateinit var expandLvRelation: ExpandableListView
     private lateinit var pictureAdapter: PictureAdapter
+    private lateinit var groupRelConfigEntity: RelConfigEntity
+    private lateinit var groupPipeConfigEntity: PipeConfigEntity
     var list = ArrayList<Infos>()
     val beans: ArrayList<Photos> = ArrayList()
     private lateinit var staticInfoAdapter: StaticInfoAdapter
+    private var spaceId = ""
+    private var position: Position? = null
+
+    /** 建筑Id */
+    private lateinit var buildingId: String
+
+    /** 楼层Id */
+    private lateinit var floorId: String
+    private lateinit var projectId: String
+    private lateinit var deviceId: String
+    private lateinit var uuid: String
+
+    /** viewModel */
+    lateinit var graphyVM: GraphyVM
+    private lateinit var dialog: EquipListDialog
+    var equips: List<EquipmentEntity> = ArrayList()
 
     // 自定义图片加载器
     private val loader =
@@ -67,19 +107,74 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
     } // Function onCreate()
 
     private fun initView() {
+        val intent = intent
+        val bundle = intent.getBundleExtra("equip")
+        buildingId = bundle?.getString("buildingId")!!
+        floorId = bundle?.getString("floorId")!!
+        spaceId = bundle?.getString("spaceId") ?: ""
+        position = bundle?.getSerializable("position") as? Position
+        projectId = bundle?.getString("projectId")!!
+        deviceId = bundle?.getString("deviceId", "")
+        uuid = IdGenerator.getId(projectId, IdGenerator.EQUIPMENT)
         recycler = findViewById(R.id.recycler)
+        height = findViewById(R.id.height)
+        locationWhere = findViewById(R.id.locationWhere)
+        equipClass = findViewById(R.id.equipClass)
+        location = findViewById(R.id.location)
+        doneSwitch = findViewById(R.id.doneSwitch)
         viewRecycler = findViewById(R.id.viewRecycler)
         mtextContent = findViewById(R.id.mtextContent)
+        localName = findViewById(R.id.localName)
+        localId = findViewById(R.id.localId)
         root = findViewById(R.id.root)
+        btnSubmit = findViewById(R.id.btnSubmit)
+        expandLvPipe = findViewById(R.id.expandLvPipe)
+        expandLvRelation = findViewById(R.id.expandLvRelation)
+        expandLvPipe.setGroupIndicator(null)
+        expandLvPipe.divider = null
+        expandLvRelation.setGroupIndicator(null)
+        expandLvRelation.divider = null
+        localName.setTvLeft("设备名称")
+        localId.setTvLeft("设备编码")
+        localId.setRightIconGone(true)
         recycler.layoutManager = LinearLayoutManager(this)
         viewRecycler.layoutManager = GridLayoutManager(this, 3)
         mtextContent.setOnTouchListener(this)
         val photo = Photos()
         photo.itemType = 1
         beans.add(photo)
-        val pictureAdapter = PictureAdapter(this, beans, "", false, 0, 85)
+        pictureAdapter = PictureAdapter(this, beans, "", false, 0, 85)
         viewRecycler.adapter = pictureAdapter
         pictureAdapter.setOnPicAdd { addPic() }
+        height.setTvRight(position!!.z.offset)
+        locationWhere.setTvRight(position!!.z.region)
+        location.setTvRight("(x=${position!!.x},y=${position!!.y})")
+        equipClass.setOnClickListener {
+            dialog.show()
+        }
+        btnSubmit.setOnClickListener {
+            var localNameString = (localName.getView(R.id.et_right)) as EditText
+            var localIdString = (localId.getView(R.id.et_right)) as EditText
+            if (equipEntity == null) {
+                ToastUtils.showMyToast("请选择设备类")
+                return@setOnClickListener
+            }
+            if (TextUtils.isEmpty(localIdString.text.trim())) {
+                ToastUtils.showMyToast("请输入设备编码")
+                return@setOnClickListener
+            }
+            graphyVM.insEquip(
+                uuid,
+                deviceId,
+                staticInfoAdapter.hashMap,
+                mtextContent.text.toString(),
+                beans,
+                equipEntity!!,
+                localNameString.text.toString(),
+                localIdString.text.toString(),
+                doneSwitch.isChecked, position!!
+            )
+        }
     }
 
     //重写onTouch方法
@@ -107,10 +202,190 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
     }
 
     private fun initData() {
+        dialog = EquipListDialog(this)
+        dialog.setOnSubmit {
+            this.equipEntity = it
+            equipClass.setTvRight(it.systemName + "/" + it.name)
+            graphyVM.getEquipInfosConfig(it)
+            graphyVM.getRelConfig(it, deviceId, uuid)
+
+        }
         staticInfoAdapter = StaticInfoAdapter(this, list)
-        staticInfoAdapter.setOnAddPic { addPic()
-            this.info = it}
+        staticInfoAdapter.setOnAddPic {
+            addPic()
+            this.info = it
+        }
         recycler.adapter = staticInfoAdapter
+        graphyVM = GraphyVM(this.application, { name, params ->
+            when (name) {
+                GraphyVM.EQUIP_CLASS -> {
+                    equips = params as List<EquipmentEntity>
+                    dialog.setList(equips);
+                }
+                GraphyVM.EQUIP_INFO -> {
+                    if (params != null) {
+                        list.clear()
+                        list.addAll(params as ArrayList<Infos>)
+                        staticInfoAdapter.notifyDataSetChanged()
+                    }
+                }
+
+                GraphyVM.SPACE_INFOS -> {
+                    if (params != null) {
+                        staticInfoAdapter.hashMap = params as HashMap<String, Any>?
+                        if (staticInfoAdapter.hashMap != null && staticInfoAdapter.hashMap.get("equipContent") != null) {
+                            mtextContent.setText(
+                                staticInfoAdapter.hashMap.get("equipContent").toString()
+                            )
+                        }
+                        if (staticInfoAdapter.hashMap != null && staticInfoAdapter.hashMap.get("equipCheck") != null) {
+                            val boo = staticInfoAdapter.hashMap.get("equipCheck")
+                            doneSwitch.isChecked = boo!!.toString().equals("true")
+                        }
+                        if (staticInfoAdapter.hashMap != null && staticInfoAdapter.hashMap.get("zRegion") != null) {
+                            val zRegion = staticInfoAdapter.hashMap.get("zRegion")
+                            locationWhere.setTvRight(zRegion.toString())
+                            if (position!!.z == null) {
+                                val z = Z()
+                                z.region = zRegion.toString()
+                                position!!.z = z
+                            } else {
+                                position!!.z.region = zRegion.toString()
+                            }
+                        }
+                        if (staticInfoAdapter.hashMap != null && staticInfoAdapter.hashMap.get("Photos") != null) {
+                            val infoList = Gson().fromJson<List<Photos>>(
+                                staticInfoAdapter.hashMap.get("Photos").toString(),
+                                object : TypeToken<List<Photos?>?>() {}.type
+                            )
+                            beans.addAll(infoList)
+                            pictureAdapter.notifyDataSetChanged()
+
+                        }
+                    }
+                }
+                GraphyVM.Equip_INFOS -> {
+                    var equip = params as ObjectEntity
+                    localId.setEtRight(equip.localId)
+                    val strInfo = Gson().fromJson(equip.strInfos, StrInfosforEquip::class.java)
+                    height.setTvRight(strInfo.location.z.toString())
+                    if (position!!.z == null) {
+                        val z = Z()
+                        z.offset = strInfo.location.z.toString()
+                        position!!.z = z
+                    } else {
+                        position!!.z.offset = strInfo.location.z.toString()
+                    }
+                    for (eq in equips) {
+                        if (equip.classCode.equals(eq.code)) {
+                            this.equipEntity = eq
+                            equipClass.setTvRight(eq.name)
+                            graphyVM.getRelConfig(eq, deviceId, uuid)
+                            break
+                        }
+                    }
+                }
+                GraphyVM.EQUIP_REL -> {
+                    val hashMap = params as HashMap<String, Any>
+                    val parent = hashMap.get("parent") as ArrayList<RelConfigEntity>
+                    val children = hashMap.get("child") as MutableList<List<RelationEntity>>
+                    val relAdapter = RelationExpandAdapter(this, parent, children)
+                    relAdapter.setOnAdd(object : RelationExpandAdapter.AddRel {
+                        override fun onAdd(group: RelConfigEntity) {
+                            this@EquipDetailActivity.groupRelConfigEntity = group
+                            graphyVM.getRelObj(group, equipEntity!!.code!!)
+                        }
+                    })
+                    relAdapter.setOnDelete(object : RelationExpandAdapter.DeleteRel {
+                        override fun ondelete(item: RelationEntity) {
+                            graphyVM.deleteRel(item, equipEntity, deviceId, uuid)
+                        }
+                    })
+                    expandLvRelation.setAdapter(relAdapter)
+                }
+                GraphyVM.REL_OBJECT -> {
+                    val equipObjects = params as List<ObjectEntity>
+                    val pop = SelectListPopupWindow(this)
+                    pop.setList(equipObjects, Constant.TYPE2)
+                    pop.setTitle(true, "单选选择对象")
+                    pop.showAtLocation(root, Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0)
+                    pop.setOnCommit(object : SelectListPopupWindow.Commit {
+                        override fun onCommit(list: java.util.ArrayList<Int>?) {
+                            if (!CommonUtils.IsNull(list)) {
+                                val equip = equipObjects.get(list!!.get(0))
+                                val localIdString = (localId.getView(R.id.et_right)) as EditText
+                                val dialog = ObjectRelationDialog(
+                                    this@EquipDetailActivity,
+                                    localIdString.text.toString(),
+                                    equip,
+                                    groupRelConfigEntity
+                                )
+                                dialog.show()
+                                dialog.setOnSubmit {
+                                    graphyVM.addRel(
+                                        deviceId,
+                                        uuid,
+                                        equipEntity!!,
+                                        equip,
+                                        groupRelConfigEntity
+                                    )
+                                }
+                            }
+                        }
+                    })
+                }
+                GraphyVM.PIPE -> {
+                    val hashMap = params as HashMap<String, Any>
+                    val parent = hashMap.get("parent") as ArrayList<PipeConfigEntity>
+                    val children = hashMap.get("child") as MutableList<List<PipeEntity>>
+                    val pipeAdapter = PipeExpandAdapter(this, parent, children)
+                    pipeAdapter.setOnAdd(object : PipeExpandAdapter.AddRel {
+                        override fun onAdd(group: PipeConfigEntity) {
+                            this@EquipDetailActivity.groupPipeConfigEntity = group
+                            graphyVM.getPipeObj(group, equipEntity!!.code!!)
+                        }
+                    })
+                    expandLvPipe.setAdapter(pipeAdapter)
+                    pipeAdapter.setOnDelete(object : PipeExpandAdapter.DeleteRel {
+                        override fun ondelete(item: PipeEntity) {
+                            graphyVM.deletePipe(item, equipEntity, deviceId, uuid)
+                        }
+                    })
+                }
+                GraphyVM.PIPE_OBJECT -> {
+                    val equipObjects = params as List<ObjectEntity>
+                    val pop = SelectListPopupWindow(this)
+                    pop.setList(equipObjects, Constant.TYPE2)
+                    pop.setTitle(true, "单选选择对象")
+                    pop.showAtLocation(root, Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0)
+                    pop.setOnCommit(object : SelectListPopupWindow.Commit {
+                        override fun onCommit(list: ArrayList<Int>?) {
+                            if (!CommonUtils.IsNull(list)) {
+                                val equip = equipObjects.get(list!!.get(0))
+                                val localIdString = (localId.getView(R.id.et_right)) as EditText
+                                val dialog = PipeDialog(
+                                    this@EquipDetailActivity,
+                                    localIdString.text.toString(),
+                                    equip,
+                                    groupPipeConfigEntity
+                                )
+                                dialog.show()
+                                dialog.setOnSubmit {
+                                    graphyVM.addPipe(
+                                        deviceId,
+                                        uuid,
+                                        equipEntity!!,
+                                        equip,
+                                        groupPipeConfigEntity
+                                    )
+                                }
+                            }
+                        }
+                    })
+                }
+            }
+        }, this, buildingId, floorId, projectId)
+        graphyVM.getEquipment(deviceId)
     }
 
     private fun addPic() {
@@ -168,7 +443,7 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
                                     }
                                     if ("success" == resultString) {
                                         val photos = Photos()
-                                        photos.itemType = 1
+                                        photos.itemType = 0
                                         photos.path = path
                                         photos.key = key
                                         beans.add(photos)
@@ -176,7 +451,7 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
                                 }
                             } else {
                                 val photos = Photos()
-                                photos.itemType = 1
+                                photos.itemType = 0
                                 photos.path = path
                                 photos.key = key
                                 beans.add(photos)
@@ -188,7 +463,11 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
                 DEAL_DATA_NEXT -> {
                     ToastUtils.showMyToast("图片上传完毕")
                     pictureAdapter.notifyDataSetChanged()
-                    staticInfoAdapter.hashMap.put(info.code, beans)
+                    staticInfoAdapter.valueList.clear()
+                    staticInfoAdapter.notifyDataSetChanged()
+//                    if (info != null) {
+//                        staticInfoAdapter.hashMap.put(info.code, beans)
+//                    }
                 }
                 DEAL_DATA_ERROR -> {
                     ToastUtils.showMyToast("图片上传失败")

+ 90 - 48
demo/src/main/java/com/sybotan/android/demo/activities/GraphyActivity.kt

@@ -51,7 +51,6 @@ import cn.sagacloud.android.cadengine.Opt
 import cn.sagacloud.android.cadengine.items.*
 import cn.sagacloud.android.cadengine.types.*
 import cn.sagacloud.android.cadengine.types.Space
-import cn.sagacloud.cadengine.HttpDownloadMap
 import com.afollestad.materialdialogs.MaterialDialog
 import com.arashivision.sdkcamera.camera.InstaCameraManager
 import com.arashivision.sdkcamera.camera.callback.ICameraChangedCallback
@@ -63,7 +62,6 @@ import com.lzy.okgo.OkGo
 import com.lzy.okgo.callback.FileCallback
 import com.lzy.okgo.model.Response
 import com.sybotan.android.demo.R
-import com.sybotan.android.demo.activities.poc.DeviceActivity
 import com.sybotan.android.demo.activities.poc.RelationActivity
 import com.sybotan.android.demo.adapter.PictureAdapter
 import com.sybotan.android.demo.adapter.PipeAdapter
@@ -82,10 +80,7 @@ import com.zbar.lib.CaptureActivity
 import io.reactivex.ObservableEmitter
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.startActivity
 import org.jetbrains.anko.textColor
-import org.jetbrains.anko.uiThread
 import org.json.JSONException
 import org.json.JSONObject
 import org.kodein.di.DI
@@ -264,32 +259,31 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
         InstaCameraManager.getInstance().registerCameraChangedCallback(this)
         graphyView.scene = scene
 
-
         /** 开启异步 */
-        doAsync {
-            val downloadGZIPMap = HttpDownloadMap.downloadGZIPMap(floorMap)
-            downloadGZIPMap?.let {
-                scene.loadData(it)
-            }
-            /** 主线程处理ui */
-            uiThread {
-                /** 适应屏幕大小 */
-                graphyView.fitSceneToView()
-//                graphyView.defaultScale = graphyView.scale
-                /** 限定移动范围不超出屏幕 */
-//                graphyView.moveRange()
-                graphyView.post {
-                    Log.e("viewW", graphyView.width.toString())
-//                    val mapItem = BaseMapItem(this@GraphyActivity, null)
-//                    mapItem.zOrder = 1000000f
-//                    mapItem.isVisible = true
-//                    scene.addItem(mapItem)
-                    mapItem = BaseMapItem(this@GraphyActivity, null)
-                }
-
-                Log.e("viewH", graphyView.measuredHeight.toString())
-            }
-        }
+//        doAsync {
+//            val downloadGZIPMap = HttpDownloadMap.downloadGZIPMap(floorMap)
+//            downloadGZIPMap?.let {
+//                scene.loadData(it)
+//            }
+//            /** 主线程处理ui */
+//            uiThread {
+//                /** 适应屏幕大小 */
+//                graphyView.fitSceneToView()
+////                graphyView.defaultScale = graphyView.scale
+//                /** 限定移动范围不超出屏幕 */
+////                graphyView.moveRange()
+//                graphyView.post {
+//                    Log.e("viewW", graphyView.width.toString())
+////                    val mapItem = BaseMapItem(this@GraphyActivity, null)
+////                    mapItem.zOrder = 1000000f
+////                    mapItem.isVisible = true
+////                    scene.addItem(mapItem)
+//                    mapItem = BaseMapItem(this@GraphyActivity, null)
+//                }
+//
+//                Log.e("viewH", graphyView.measuredHeight.toString())
+//            }
+//        }
         /** 点击监听 */
         initListener()
         /** 图形点击-poc业务 */
@@ -916,10 +910,28 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
                             equipDetail.isEnabled = true
                             equipDelete.isEnabled = true
                             equipDetail.setOnClickListener {
-                                startActivity<EquipDetailActivity>()
+                                val intent =
+                                    Intent(this@GraphyActivity, EquipDetailActivity::class.java)
+                                val bundle = Bundle()
+                                val positon = Position()
+                                positon.x = point.data.mX.toString()
+                                positon.y = point.data.mY.toString()
+                                val z = Z()
+                                val position = gson.fromJson(point.data.position, Z::class.java)
+                                z.offset = position.offset
+                                z.region = position.region
+                                positon.z = z
+                                bundle.putString("spaceId", scene.choseSpace!!.data.id)
+                                bundle.putSerializable("position", positon)
+                                bundle.putString("buildingId", buildingId)
+                                bundle.putString("floorId", floorId)
+                                bundle.putString("deviceId", point.data.deviceId)
+                                bundle.putString("projectId", projectId)
+                                intent.putExtra("equip", bundle)
+                                startActivityForResult(intent, REQUEST_CODE_EQUIP)
                             }
                             equipDelete.setOnClickListener {
-                                point.data.type
+                                graphyVM.insProblemEquip(scene.choseSpace!!, point.data.deviceId!!)
                             }
                             break
                         }
@@ -1047,29 +1059,34 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
                 ToastUtils.showMyToast("请扎点")
                 return@setOnClickListener
             }
+            if (TextUtils.isEmpty(qrcodeEdit.text.trim())) {
+                ToastUtils.showMyToast("请输入高度")
+                return@setOnClickListener
+            }
             val intent = Intent(this@GraphyActivity, CaptureActivity::class.java)
             startActivityForResult(intent, REQUEST_CODE_SCAN)
         }
 
         /** 添加管线下一步 */
         pipeNext.setOnClickListener {
-            for (model in pipeTypeList) {
-                if (model.isCheck) {
-                    graphyVM.addPipe(
-                        model,
-                        scene.pipeLineList,
-                        pipeEdit.text.toString(),
-                        scene.choseSpace
-                    )
-                    break
-                }
-            }
+//            for (model in pipeTypeList) {
+//                if (model.isCheck) {
+//                    graphyVM.addPipe(
+//                        model,
+//                        scene.pipeLineList,
+//                        pipeEdit.text.toString(),
+//                        scene.choseSpace
+//                    )
+//                    break
+//                }
+//            }
         }
 
 
         /** 添加设备 */
         drawEquip.setOnClickListener {
             scene.type = "equip"
+            equipLocation.setText("")
             drawLl.visibility = View.GONE
             equipLl.visibility = View.VISIBLE
 
@@ -1095,6 +1112,10 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
 
         /** 添加设备下一步 */
         equipNext.setOnClickListener {
+            if (TextUtils.isEmpty(equipLocation.text.toString())) {
+                ToastUtils.showMyToast("请扎点")
+                return@setOnClickListener
+            }
             val intent = Intent(this, EquipDetailActivity::class.java)
             val bundle = Bundle()
             val positon = Position()
@@ -1119,6 +1140,9 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
             positon.z = z
             bundle.putString("spaceId", scene.choseSpace!!.data.id)
             bundle.putSerializable("position", positon)
+            bundle.putString("buildingId", buildingId)
+            bundle.putString("floorId", floorId)
+            bundle.putString("projectId", projectId)
             intent.putExtra("equip", bundle)
             startActivityForResult(intent, REQUEST_CODE_EQUIP)
         }
@@ -1167,6 +1191,25 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
     private fun initViewModel() {
         graphyVM = GraphyVM(this.application, BaseViewModelInterface { name, params ->
             when (name) {
+                GraphyVM.MAP_LOAD -> {
+                    val floorDate = FloorData()
+                    val floorOfflineData = gson.fromJson(params.toString(), FloorData::class.java)
+                    floorDate.entityList.addAll(floorOfflineData.entityList)
+                    scene.loadData(floorDate)
+                    /** 适应屏幕大小 */
+                    graphyView.fitSceneToView()
+//                graphyView.defaultScale = graphyView.scale
+                    /** 限定移动范围不超出屏幕 */
+//                graphyView.moveRange()
+                    graphyView.post {
+                        Log.e("viewW", graphyView.width.toString())
+//                    val mapItem = BaseMapItem(this@GraphyActivity, null)
+//                    mapItem.zOrder = 1000000f
+//                    mapItem.isVisible = true
+//                    scene.addItem(mapItem)
+                        mapItem = BaseMapItem(this@GraphyActivity, null)
+                    }
+                }
                 /** 查询空间和任务 */
                 GraphyVM.SPACE_JOB -> {
                     for (item in scene.tunableSpaceList) {
@@ -1424,6 +1467,7 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
                 }
             }
         }, this, buildingId, floorId, projectId)
+        graphyVM.getMap()
         graphyVM.getSpaceJob(from, scene.spaceList)
     }
 
@@ -1547,10 +1591,11 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
                     val point = Point()
                     var position = gson.fromJson(child.position, Position::class.java)
                     point.mX = position.x.toFloat()
-                    point.mY = position.y.toFloat()
+                    point.mY = -position.y.toFloat()
                     point.remark = child.remark
                     point.type = model.type
                     point.position = child.position
+                    point.deviceId = child.deviceId
 
                     graphyHelper.addEquip(point)
                 }
@@ -1582,10 +1627,6 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
         scene.type = "normal"
         modelCheckBox.isChecked = false
         equipLocation.setText("")
-        roof.isChecked = false
-        floor.isChecked = false
-        wall.isChecked = false
-        air.isChecked = false
         scene.point = Point()
     }
 
@@ -1703,6 +1744,7 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
                     drawLl.visibility = View.VISIBLE
                     graphyVM.getSpaceEq(scene.choseSpace)
                 }
+                graphyVM.floorPipe()
             }
             REQUEST_CODE_PIC -> {
                 if (resultCode == RESULT_OK) {

+ 1 - 1
demo/src/main/java/com/sybotan/android/demo/activities/PocActivity.kt

@@ -41,7 +41,6 @@ class PocActivity : AppCompatActivity(), DIAware {
         super.onCreate(savedInstanceState)
         setContentView(R.layout.activity_poc)
         checkStoragePermission()
-        LocalDataOperation.getInstance().offlineSendRequest.uploadImageNew(this)
         downloadBtn = findViewById(R.id.downloadBtn)
         uploadBtn = findViewById(R.id.uploadBtn)
 
@@ -52,6 +51,7 @@ class PocActivity : AppCompatActivity(), DIAware {
         }
 
         uploadBtn.setOnClickListener {
+            LocalDataOperation.getInstance().offlineSendRequest.uploadImageNew(this)
             mVm.uploadBuilding {
                 ToastUtils.showMyToast("建筑数据上传成功")
             }

+ 18 - 5
demo/src/main/java/com/sybotan/android/demo/activities/SpaceDetailActivity.kt

@@ -17,6 +17,8 @@ import com.sybotan.android.demo.adapter.StaticInfoAdapter
 import cn.sagacloud.android.cadengine.types.Photos
 import cn.sagacloud.android.cadengine.types.TunableSpace
 import com.framework.mvvm.model.db.entity.Infos
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
 import com.sybotan.android.demo.retrofit.Constant
 import com.sybotan.android.demo.tools.LocalDataOperation
 import com.sybotan.android.demo.tools.PictureUtils
@@ -29,6 +31,7 @@ import io.reactivex.ObservableEmitter
 import org.json.JSONException
 import org.json.JSONObject
 import java.io.File
+import java.util.HashMap
 
 /**
  * Created by lihao.
@@ -89,6 +92,18 @@ class SpaceDetailActivity : BaseActivity() {
                     list.addAll(params as ArrayList<Infos>)
                     staticInfoAdapter.notifyDataSetChanged()
                 }
+                GraphyVM.SPACE_INFOS -> {
+                    if (params != null) {
+                        staticInfoAdapter.hashMap = params as HashMap<String, Any>?
+                        if (staticInfoAdapter.hashMap != null && staticInfoAdapter.hashMap.get("Photos") != null) {
+                            val infoList = Gson().fromJson<List<Photos>>(
+                                staticInfoAdapter.hashMap.get("Photos").toString(),
+                                object : TypeToken<List<Photos?>?>() {}.type
+                            )
+                            beans.addAll(infoList)
+                        }
+                    }
+                }
             }
         }, this, buildingId, floorId, projectId)
         graphyVM.getInfosConfig(spaceId)
@@ -171,8 +186,6 @@ class SpaceDetailActivity : BaseActivity() {
                                         photos.path = path
                                         photos.key = key
                                         beans.add(photos)
-//                                        viewModel.picPathList.add(photos)
-//                                        viewModel.content.pictures.add(key)
                                     }
                                 }
                             } else {
@@ -182,8 +195,6 @@ class SpaceDetailActivity : BaseActivity() {
                                 photos.path = path
                                 photos.key = key
                                 beans.add(photos)
-//                                viewModel.picPathList.add(photos)
-//                                viewModel.content.pictures.add(key)
                             }
                         }
                     }
@@ -191,7 +202,9 @@ class SpaceDetailActivity : BaseActivity() {
                 }
                 LocalDataOperation.DEAL_DATA_NEXT -> {
                     ToastUtils.showMyToast("图片上传完毕")
-                    staticInfoAdapter.hashMap.put(info.code, beans)
+                    staticInfoAdapter.hashMap.put(info.code, Gson().toJson(beans))
+                    staticInfoAdapter.valueList.remove(info.code)
+                    staticInfoAdapter.notifyDataSetChanged()
                 }
                 LocalDataOperation.DEAL_DATA_ERROR -> {
                     ToastUtils.showMyToast("图片上传失败")

+ 33 - 0
demo/src/main/java/com/sybotan/android/demo/adapter/EquipListAdapter.java

@@ -0,0 +1,33 @@
+package com.sybotan.android.demo.adapter;
+
+import android.content.Context;
+
+import com.framework.mvvm.model.db.entity.EquipmentEntity;
+import com.sybotan.android.demo.R;
+
+import java.util.List;
+
+/**
+ * Created by lihao.
+ * Date: 2021/10/15
+ */
+public class EquipListAdapter extends BaseRecyclerViewAdapter<EquipmentEntity> {
+    public EquipListAdapter(Context context, List<EquipmentEntity> beans) {
+        super(context, beans);
+    }
+
+    @Override
+    protected int getItemLayoutId(int viewType) {
+        return R.layout.item_tree;
+    }
+
+    @Override
+    protected void onBindDataToView(ViewHolder holder, EquipmentEntity entity) {
+        holder.setText(R.id.labelTv, entity.getSystemName() + "/" + entity.getName());
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        return 0;
+    }
+}

+ 3 - 0
demo/src/main/java/com/sybotan/android/demo/adapter/PictureAdapter.java

@@ -12,7 +12,9 @@ import android.widget.ImageView;
 
 import com.sybotan.android.demo.R;
 import com.sybotan.android.demo.activities.LookBigPicActivity;
+
 import cn.sagacloud.android.cadengine.types.Photos;
+
 import com.sybotan.android.demo.retrofit.Constant;
 import com.sybotan.android.demo.tools.CommonUtils;
 import com.sybotan.android.demo.tools.DensityUtils;
@@ -20,6 +22,7 @@ import com.sybotan.android.demo.tools.GlideApp;
 import com.tencent.smtt.sdk.ui.dialog.widget.RoundImageView;
 
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.util.List;

+ 128 - 0
demo/src/main/java/com/sybotan/android/demo/adapter/PipeExpandAdapter.kt

@@ -0,0 +1,128 @@
+package com.sybotan.android.demo.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.BaseExpandableListAdapter
+import android.widget.ImageView
+import android.widget.TextView
+import com.framework.mvvm.model.db.entity.PipeConfigEntity
+import com.framework.mvvm.model.db.entity.PipeEntity
+import com.framework.mvvm.model.db.entity.RelConfigEntity
+import com.framework.mvvm.model.db.entity.RelationEntity
+import com.sybotan.android.demo.R
+import java.lang.StringBuilder
+
+
+class PipeExpandAdapter(
+    context: Context,
+    groups: List<PipeConfigEntity>,
+    items: List<List<PipeEntity>>
+) : BaseExpandableListAdapter() {
+    private var addRel: AddRel? = null
+    private var deleteRel: DeleteRel? = null
+    private var mContext: Context = context
+    private var mGroups: List<PipeConfigEntity> = groups
+    private var mItems: List<List<PipeEntity>> = items
+    private var mLayoutInflater: LayoutInflater = LayoutInflater.from(context)
+
+    override fun getGroupCount(): Int {
+        return mGroups.size
+    }
+
+    override fun getChildrenCount(groupPosition: Int): Int {
+        return mItems[groupPosition].size
+    }
+
+    override fun getGroup(groupPosition: Int): PipeConfigEntity {
+        return mGroups[groupPosition]
+    }
+
+    override fun getChild(groupPosition: Int, childPosition: Int): PipeEntity {
+        return mItems[groupPosition][childPosition]
+    }
+
+    override fun getGroupId(groupPosition: Int): Long {
+        return groupPosition.toLong()
+    }
+
+    override fun getChildId(groupPosition: Int, childPosition: Int): Long {
+        return childPosition.toLong()
+    }
+
+    override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean {
+        return true
+    }
+
+    override fun hasStableIds(): Boolean {
+        return false
+    }
+
+    override fun getGroupView(
+        groupPosition: Int,
+        isExpanded: Boolean,
+        convertView: View?,
+        parent: ViewGroup?
+    ): View {
+        var holder = convertView
+        if (holder == null) {
+            holder = mLayoutInflater.inflate(R.layout.group_expand_relation, parent, false)
+        }
+        val group: PipeConfigEntity = mGroups[groupPosition]
+        val tvGroup = holder?.findViewById(R.id.title) as TextView
+        tvGroup.text = group.pipeType
+        val add = holder?.findViewById(R.id.add) as ImageView
+        add.setOnClickListener {
+            addRel?.onAdd(group)
+        }
+        return holder
+    }
+
+    override fun getChildView(
+        groupPosition: Int,
+        childPosition: Int,
+        isLastChild: Boolean,
+        convertView: View?,
+        parent: ViewGroup?
+    ): View {
+        var holder = convertView
+        if (holder == null) {
+            holder = mLayoutInflater.inflate(R.layout.child_expand_relation, parent, false)
+        }
+        val itemTv = holder?.findViewById(R.id.title) as TextView
+        val item = mItems[groupPosition][childPosition]
+        var sb = StringBuilder()
+        sb.append(item.objFromLocalId)
+        //1:正向from->to;-1:反向to->from;0:无方向
+        if (item.direction == 1) {
+            sb.append("  —>  ")
+        } else if (item.direction == -1) {
+            sb.append("  <—  ")
+        } else if (item.direction == 0) {
+            sb.append("  -—  ")
+        }
+        sb.append(item.objToLocalId)
+        itemTv.text = sb.toString()
+        holder?.findViewById<ImageView>(R.id.delete).setOnClickListener {
+            deleteRel?.ondelete(item)
+        }
+        return holder
+    }
+
+    public interface AddRel {
+        fun onAdd(group: PipeConfigEntity)
+    }
+
+    fun setOnAdd(addRel: AddRel) {
+        this.addRel = addRel
+    }
+
+    public interface DeleteRel {
+        fun ondelete(item: PipeEntity)
+    }
+
+    fun setOnDelete(deleteRel: DeleteRel) {
+        this.deleteRel = deleteRel
+    }
+}

+ 55 - 13
demo/src/main/java/com/sybotan/android/demo/adapter/RelationExpandAdapter.kt

@@ -5,20 +5,24 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.BaseExpandableListAdapter
+import android.widget.ImageView
 import android.widget.TextView
+import com.framework.mvvm.model.db.entity.RelConfigEntity
+import com.framework.mvvm.model.db.entity.RelationEntity
 import com.sybotan.android.demo.R
-import com.sybotan.android.demo.entitiies.Build
-import com.sybotan.android.demo.entitiies.Floor
+import java.lang.StringBuilder
 
 
 class RelationExpandAdapter(
     context: Context,
-    groups: List<Build>,
-    items: List<List<Floor>>
+    groups: List<RelConfigEntity>,
+    items: List<List<RelationEntity>>
 ) : BaseExpandableListAdapter() {
+    private var addRel: AddRel? = null
+    private var deleteRel: DeleteRel? = null
     private var mContext: Context = context
-    private var mGroups: List<Build> = groups
-    private var mItems: List<List<Floor>> = items
+    private var mGroups: List<RelConfigEntity> = groups
+    private var mItems: List<List<RelationEntity>> = items
     private var mLayoutInflater: LayoutInflater = LayoutInflater.from(context)
 
     override fun getGroupCount(): Int {
@@ -29,11 +33,11 @@ class RelationExpandAdapter(
         return mItems[groupPosition].size
     }
 
-    override fun getGroup(groupPosition: Int): Build {
+    override fun getGroup(groupPosition: Int): RelConfigEntity {
         return mGroups[groupPosition]
     }
 
-    override fun getChild(groupPosition: Int, childPosition: Int): Floor {
+    override fun getChild(groupPosition: Int, childPosition: Int): RelationEntity {
         return mItems[groupPosition][childPosition]
     }
 
@@ -53,25 +57,63 @@ class RelationExpandAdapter(
         return false
     }
 
-    override fun getGroupView(groupPosition: Int, isExpanded: Boolean, convertView: View?, parent: ViewGroup?): View {
+    override fun getGroupView(
+        groupPosition: Int,
+        isExpanded: Boolean,
+        convertView: View?,
+        parent: ViewGroup?
+    ): View {
         var holder = convertView
         if (holder == null) {
             holder = mLayoutInflater.inflate(R.layout.group_expand_relation, parent, false)
         }
-        val group: Build = mGroups[groupPosition]
+        val group: RelConfigEntity = mGroups[groupPosition]
         val tvGroup = holder?.findViewById(R.id.title) as TextView
-        tvGroup.text = group.localName
+        tvGroup.text = group.graphName + "/" + group.relName
+        val add = holder?.findViewById(R.id.add) as ImageView
+        add.setOnClickListener {
+            addRel?.onAdd(group)
+        }
         return holder
     }
 
-    override fun getChildView(groupPosition: Int, childPosition: Int, isLastChild: Boolean, convertView: View?, parent: ViewGroup?): View {
+    override fun getChildView(
+        groupPosition: Int,
+        childPosition: Int,
+        isLastChild: Boolean,
+        convertView: View?,
+        parent: ViewGroup?
+    ): View {
         var holder = convertView
         if (holder == null) {
             holder = mLayoutInflater.inflate(R.layout.child_expand_relation, parent, false)
         }
         val itemTv = holder?.findViewById(R.id.title) as TextView
         val item = mItems[groupPosition][childPosition]
-        itemTv.text = item.localName
+        var sb = StringBuilder()
+        sb.append(item.objFromLocalId)
+        sb.append("  —>  ")
+        sb.append(item.objToLocalId)
+        itemTv.text = sb.toString()
+        holder?.findViewById<ImageView>(R.id.delete).setOnClickListener {
+            deleteRel?.ondelete(item)
+        }
         return holder
     }
+
+    public interface AddRel {
+        fun onAdd(group: RelConfigEntity)
+    }
+
+    fun setOnAdd(addRel: AddRel) {
+        this.addRel = addRel
+    }
+
+    public interface DeleteRel {
+        fun ondelete(item: RelationEntity)
+    }
+
+    fun setOnDelete(deleteRel: DeleteRel) {
+        this.deleteRel = deleteRel
+    }
 }

+ 5 - 0
demo/src/main/java/com/sybotan/android/demo/adapter/SelectPopListAdapter.java

@@ -15,6 +15,7 @@ import android.widget.TextView;
 import androidx.recyclerview.widget.RecyclerView;
 
 
+import com.framework.mvvm.model.db.entity.ObjectEntity;
 import com.framework.mvvm.model.db.entity.Options;
 import com.sybotan.android.demo.R;
 import com.sybotan.android.demo.retrofit.Constant;
@@ -56,6 +57,10 @@ public class SelectPopListAdapter extends RecyclerView.Adapter<SelectPopListAdap
             Options options = (Options) item;
             holder.choice_name.setText(options.getTxt());
         }
+        if (type.equals(Constant.TYPE2)) {
+            ObjectEntity options = (ObjectEntity) item;
+            holder.choice_name.setText(options.getLocalId());
+        }
         if (selectPosition > 0 && selectPosition - 1 == position) {
             holder.choice_name.setTextColor(context.getResources().getColor(R.color.blue_2f48b7));
         } else {

+ 112 - 4
demo/src/main/java/com/sybotan/android/demo/adapter/StaticInfoAdapter.java

@@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
 import android.content.Context;
 import android.graphics.Color;
 import android.text.Editable;
+import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.view.Gravity;
 import android.view.MotionEvent;
@@ -18,6 +19,8 @@ import com.bigkoo.pickerview.builder.TimePickerBuilder;
 import com.bigkoo.pickerview.view.TimePickerView;
 import com.framework.mvvm.model.db.entity.Infos;
 import com.framework.mvvm.model.db.entity.Options;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
 import com.sybotan.android.demo.R;
 
 import cn.sagacloud.android.cadengine.types.Photos;
@@ -42,6 +45,7 @@ public class StaticInfoAdapter extends BaseRecyclerViewAdapter<Infos> {
      * text|textarea|radio|checkbox|picker|setpper|switch|date|photo|file
      */
     public HashMap<String, Object> hashMap = new HashMap<>();
+    public ArrayList<String> valueList = new ArrayList<>();
     public static final int TEXT = 1;
     public static final int INT = 2;
     public static final int DOUBLE = 3;
@@ -82,21 +86,81 @@ public class StaticInfoAdapter extends BaseRecyclerViewAdapter<Infos> {
 
     @Override
     protected void onBindDataToView(ViewHolder holder, Infos info) {
+        if (TextUtils.isEmpty(info.getInputType())) {
+            if (!CommonUtils.IsNull(info.getOptions())) {
+                ListItemView enumItemView = holder.getView(R.id.view_enum);
+                enumItemView.setTvLeft(info.getLabel());
+                enumItemView.setTvRight("请选择");
+
+                if (!valueList.contains(info.getCode())) {
+                    if (hashMap != null && hashMap.get(info.getCode()) != null) {
+                        ArrayList<Options> value = new Gson().fromJson((String) hashMap.get(info.getCode()), new TypeToken<List<Options>>() {
+                        }.getType());
+                        StringBuilder sb = new StringBuilder();
+                        for (int i = 0; i < value.size(); i++) {
+                            sb.append(info.getOptions().get(i).getTxt()).append("、");
+                        }
+                        enumItemView.setTvRight(sb.toString());
+                    }
+                }
+                valueList.add(info.getCode());
+
+                enumItemView.getView(R.id.tv_right).setOnClickListener(v -> {
+                    SelectListPopupWindow popupWindow = new SelectListPopupWindow(mContext);
+                    popupWindow.setList(info.getOptions(), Constant.TYPE1);
+                    popupWindow.setOnCommit(new SelectListPopupWindow.Commit() {
+                        @Override
+                        public void onCommit(ArrayList<Integer> list) {
+                            ArrayList<Options> arrayList = new ArrayList<>();
+                            StringBuilder sb = new StringBuilder();
+                            for (int i = 0; i < list.size(); i++) {
+                                sb.append(info.getOptions().get(i).getTxt()).append("、");
+                                arrayList.add(info.getOptions().get(i));
+                            }
+                            hashMap.put(info.getCode(), new Gson().toJson(arrayList));
+                            enumItemView.setTvRight(sb.toString());
+                        }
+                    });
+                    popupWindow.showAtLocation(enumItemView, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
+                });
+            } else {
+                holder.setText(R.id.mtextTitle, info.getLabel());
+                EditText mtextContent2 = holder.getView(R.id.mtextContent);
+                initEditTextTouch(mtextContent2, info);
+            }
+            return;
+        }
         switch (info.getInputType()) {
             case "text":
                 ListItemView textItemView = holder.getView(R.id.view_text);
                 textItemView.setTvLeft(info.getLabel());
                 EditText etRight = textItemView.findViewById(R.id.et_right);
                 initEditTextTouch(etRight, info);
+                break;
             case "textarea":
-                holder.setText(R.id.mtext_title, info.getLabel());
+                holder.setText(R.id.mtextTitle, info.getLabel());
                 EditText mtextContent = holder.getView(R.id.mtextContent);
                 initEditTextTouch(mtextContent, info);
+                break;
             case "radio":
             case "picker":
                 ListItemView enumItemView = holder.getView(R.id.view_enum);
                 enumItemView.setTvLeft(info.getLabel());
                 enumItemView.setTvRight("请选择");
+
+                if (!valueList.contains(info.getCode())) {
+                    if (hashMap != null && hashMap.get(info.getCode()) != null) {
+                        ArrayList<Options> value = new Gson().fromJson((String) hashMap.get(info.getCode()), new TypeToken<List<Options>>() {
+                        }.getType());
+                        StringBuilder sb = new StringBuilder();
+                        for (int i = 0; i < value.size(); i++) {
+                            sb.append(info.getOptions().get(i).getTxt()).append("、");
+                        }
+                        enumItemView.setTvRight(sb.toString());
+                    }
+                }
+                valueList.add(info.getCode());
+
                 enumItemView.getView(R.id.tv_right).setOnClickListener(v -> {
                     SelectListPopupWindow popupWindow = new SelectListPopupWindow(mContext);
                     popupWindow.setList(info.getOptions(), Constant.TYPE1);
@@ -109,23 +173,36 @@ public class StaticInfoAdapter extends BaseRecyclerViewAdapter<Infos> {
                                 sb.append(info.getOptions().get(i).getTxt()).append("、");
                                 arrayList.add(info.getOptions().get(i));
                             }
-                            hashMap.put(info.getCode(), arrayList);
+                            hashMap.put(info.getCode(), new Gson().toJson(arrayList));
                             enumItemView.setTvRight(sb.toString());
                         }
                     });
                     popupWindow.showAtLocation(enumItemView, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
                 });
+                break;
             case "setpper":
 //                return INT;
                 ListItemView intItemView = holder.getView(R.id.view_int);
                 intItemView.setTvLeft(info.getLabel());
                 CommonNumberControl numberControl = (CommonNumberControl) intItemView.getView(R.id.et_right);
                 initEditTextTouch(numberControl.getEditText(), info);
+                break;
             case "photo":
                 List<Photos> beans = new ArrayList<>();
                 Photos photo = new Photos();
                 photo.itemType = 1;
                 beans.add(photo);
+
+                if (!valueList.contains(info.getCode())) {
+                    if (hashMap != null && hashMap.get(info.getCode()) != null) {
+                        ArrayList<Photos> value = new Gson().fromJson((String) hashMap.get(info.getCode()), new TypeToken<List<Photos>>() {
+                        }.getType());
+                        ArrayList<Photos> photos = value;
+                        beans.addAll(photos);
+                    }
+                }
+                valueList.add(info.getCode());
+
                 PictureAdapter pictureAdapter = new PictureAdapter(mContext, beans, "", false, holder.getCurrentPosition(), 85);
                 pictureAdapter.setOnPicAdd(new PictureAdapter.PicAdd() {
                     @Override
@@ -139,6 +216,7 @@ public class StaticInfoAdapter extends BaseRecyclerViewAdapter<Infos> {
                 recycler.setLayoutManager(new GridLayoutManager(mContext, 3));
                 recycler.setAdapter(pictureAdapter);
 //                return PICTURE;
+                break;
             case "date":
 //                return DATE;
                 ListItemView listItemView = holder.getView(R.id.view_date);
@@ -147,12 +225,27 @@ public class StaticInfoAdapter extends BaseRecyclerViewAdapter<Infos> {
                     pvTime.show(true);
                 });
                 initTimePicker();
+                break;
             default:
                 if (!CommonUtils.IsNull(info.getOptions())) {
 //                    return ENUM;
                     ListItemView enumItemView2 = holder.getView(R.id.view_enum);
                     enumItemView2.setTvLeft(info.getLabel());
                     enumItemView2.setTvRight("请选择");
+
+                    if (!valueList.contains(info.getCode())) {
+                        if (hashMap != null && hashMap.get(info.getCode()) != null) {
+                            ArrayList<Options> value = new Gson().fromJson((String) hashMap.get(info.getCode()), new TypeToken<List<Options>>() {
+                            }.getType());
+                            StringBuilder sb = new StringBuilder();
+                            for (int i = 0; i < value.size(); i++) {
+                                sb.append(info.getOptions().get(i).getTxt()).append("、");
+                            }
+                            enumItemView2.setTvRight(sb.toString());
+                        }
+                    }
+                    valueList.add(info.getCode());
+
                     enumItemView2.getView(R.id.tv_right).setOnClickListener(v -> {
                         SelectListPopupWindow popupWindow = new SelectListPopupWindow(mContext);
                         popupWindow.setList(info.getOptions(), Constant.TYPE1);
@@ -165,18 +258,20 @@ public class StaticInfoAdapter extends BaseRecyclerViewAdapter<Infos> {
                                     sb.append(info.getOptions().get(i).getTxt()).append("、");
                                     arrayList.add(info.getOptions().get(i));
                                 }
-                                hashMap.put(info.getCode(), arrayList);
+                                hashMap.put(info.getCode(), new Gson().toJson(arrayList));
                                 enumItemView2.setTvRight(sb.toString());
                             }
                         });
+                        popupWindow.setTitle(false, "");
                         popupWindow.showAtLocation(enumItemView2, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
                     });
                 } else {
 //                    return MTEXT;
-                    holder.setText(R.id.mtext_title, info.getLabel());
+                    holder.setText(R.id.mtextTitle, info.getLabel());
                     EditText mtextContent2 = holder.getView(R.id.mtextContent);
                     initEditTextTouch(mtextContent2, info);
                 }
+                break;
 
         }
 
@@ -207,6 +302,12 @@ public class StaticInfoAdapter extends BaseRecyclerViewAdapter<Infos> {
 
     @SuppressLint("ClickableViewAccessibility")
     private void initEditTextTouch(EditText editText, Infos info) {
+        if (!valueList.contains(info.getCode())) {
+            if (hashMap != null && hashMap.get(info.getCode()) != null) {
+                editText.setText((String) hashMap.get(info.getCode()));
+            }
+        }
+        valueList.add(info.getCode());
         editText.setOnTouchListener((v, event) -> {
             if (MotionEvent.ACTION_DOWN == event.getAction()) {
                 v.getParent().requestDisallowInterceptTouchEvent(true);
@@ -235,6 +336,13 @@ public class StaticInfoAdapter extends BaseRecyclerViewAdapter<Infos> {
 
     @Override
     public int getItemViewType(int position) {
+        if (TextUtils.isEmpty(mBeans.get(position).getInputType())) {
+            if (!CommonUtils.IsNull(mBeans.get(position).getOptions())) {
+                return ENUM;
+            } else {
+                return MTEXT;
+            }
+        }
         switch (mBeans.get(position).getInputType()) {
             case "text":
                 return TEXT;

+ 2 - 0
demo/src/main/java/com/sybotan/android/demo/bean/result/Children.java

@@ -13,4 +13,6 @@ public class Children {
     public String name;
     public String position;
     public String remark;
+    //1-蓝 2-绿 3-红
+    public int type;
 }

+ 4 - 3
demo/src/main/java/com/sybotan/android/demo/retrofit/Constant.java

@@ -12,12 +12,13 @@ public class Constant {
     //服务器地址
     public static final String ServerIP = "http://192.168.0.11:8082/";
     //图片服务器地址
-    public static final String ServerImgIPUp = "http://develop.persagy.com/image-service/common/file_upload?systemId=dataPlatform&secret=9e0891a7a8c8e885&key=";
-    //图片服务器地址下载
-    public static final String ServerImgIPDown = "http://develop.persagy.com/image-service/common/file_get?systemId=dataPlatform&secret=9e0891a7a8c8e885&key=";
+    public static final String ServerImgIPUp = "http://39.105.112.36/image-service/common/file_upload?systemId=dataPlatform&secret=9e0891a7a8c8e885&key=";
+    //图片服务器地址下载http:
+    public static final String ServerImgIPDown = "http://39.105.112.36/image-service/common/file_get?systemId=dataPlatform&secret=9e0891a7a8c8e885&key=";
     //地图服务器地址
     public static final String ServerMapIP = "http://adm.sagacloud.cn/image-service/common/file_get?systemId=revit&key=";
 
 
     public static final String TYPE1 = "String";
+    public static final String TYPE2 = "equip";
 }

+ 39 - 2
demo/src/main/java/com/sybotan/android/demo/view/EquipListDialog.java

@@ -17,7 +17,15 @@ import androidx.annotation.NonNull;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
+import com.framework.mvvm.model.db.entity.EquipmentEntity;
 import com.sybotan.android.demo.R;
+import com.sybotan.android.demo.adapter.BaseRecyclerViewAdapter;
+import com.sybotan.android.demo.adapter.EquipListAdapter;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * 选择设备列表
@@ -27,6 +35,9 @@ public class EquipListDialog extends Dialog {
 
     private Submit submit;
     private EditText searchEdt;
+    public EquipListAdapter adapter;
+    private List<EquipmentEntity> equips = new ArrayList<>();
+    private List<EquipmentEntity> itemList = new ArrayList<>();
 
     public EquipListDialog(@NonNull Context context) {
         super(context, R.style.style_dialog);
@@ -37,18 +48,38 @@ public class EquipListDialog extends Dialog {
     private void init(Context context) {
         findViewById(R.id.search_delete).setOnClickListener(v -> {
             searchEdt.setText("");
+            itemList.clear();
+            itemList.addAll(equips);
+            adapter.notifyDataSetChanged();
         });
         searchEdt = findViewById(R.id.search_edt);
         searchEdt.setOnEditorActionListener((textView, actionId, keyEvent) -> {
             if (actionId == EditorInfo.IME_ACTION_SEARCH) {//修改回车键功能
                 if (!TextUtils.isEmpty(searchEdt.getText().toString().trim())) {
-
+                    itemList.clear();
+                    for (int i = 0; i < equips.size(); i++) {
+                        if ((!TextUtils.isEmpty(equips.get(i).getName()) && equips.get(i).getName().contains(searchEdt.getText().toString())) || (!TextUtils.isEmpty(equips.get(i).getSystemName()) && equips.get(i).getSystemName().contains(searchEdt.getText().toString()))) {
+                            itemList.add(equips.get(i));
+                        }
+                    }
+                    adapter.notifyDataSetChanged();
                 }
             }
             return false;
         });
         RecyclerView recycler = findViewById(R.id.recycler);
         recycler.setLayoutManager(new LinearLayoutManager(context));
+        adapter = new EquipListAdapter(getContext(), itemList);
+        recycler.setAdapter(adapter);
+        adapter.setOnItemClickListener(new BaseRecyclerViewAdapter.OnItemClickListener() {
+            @Override
+            public void onItemClick(BaseRecyclerViewAdapter adapter, View view, int position) {
+                if (submit!=null){
+                    submit.onSubmit(itemList.get(position));
+                    dismiss();
+                }
+            }
+        });
     }
 
     public void setDisplay(Context context) {
@@ -74,9 +105,15 @@ public class EquipListDialog extends Dialog {
         window.setAttributes(wl);
     }
 
+    public void setList(@NotNull List<EquipmentEntity> equips) {
+        this.equips = equips;
+        itemList.addAll(equips);
+        adapter.notifyDataSetChanged();
+    }
+
 
     public interface Submit {
-        void onSubmit();
+        void onSubmit(EquipmentEntity entity);
     }
 
     public void setOnSubmit(Submit submit) {

+ 1 - 1
demo/src/main/java/com/sybotan/android/demo/view/ListItemView.java

@@ -41,7 +41,7 @@ public class ListItemView extends RelativeLayout {
     /**
      * EditText设置最大输入值
      */
-    private int et_max = 1;
+    private int et_max = 10;
     private ImageView mIvMust;
 
     public ListItemView(Context context) {

+ 21 - 5
demo/src/main/java/com/sybotan/android/demo/view/ObjectRelationDialog.java

@@ -12,8 +12,12 @@ import android.widget.TextView;
 
 import androidx.annotation.NonNull;
 
+import com.framework.mvvm.model.db.entity.ObjectEntity;
+import com.framework.mvvm.model.db.entity.RelConfigEntity;
 import com.sybotan.android.demo.R;
 
+import java.util.Objects;
+
 
 /**
  * 设备关系
@@ -24,18 +28,30 @@ public class ObjectRelationDialog extends Dialog implements View.OnClickListener
     private TextView relationTv;
     private Submit submit;
 
-    public ObjectRelationDialog(@NonNull Context context) {
+    public ObjectRelationDialog(@NonNull Context context, String localId, ObjectEntity equip, RelConfigEntity configEntity) {
         super(context, R.style.style_dialog);
         setDisplay(context);
-        init();
+        init(localId, equip, configEntity);
     }
 
-    private void init() {
+    private void init(String localId, ObjectEntity equip, RelConfigEntity configEntity) {
         relationTv = findViewById(R.id.relationTv);
+        TextView leftName = findViewById(R.id.leftName);
+        TextView rightName = findViewById(R.id.rightName);
+        TextView relationTitle = findViewById(R.id.relationTitle);
         findViewById(R.id.toleft).setOnClickListener(this);
         findViewById(R.id.toright).setOnClickListener(this);
         findViewById(R.id.connect).setOnClickListener(this);
-        findViewById(R.id.btn_submit).setOnClickListener(this);
+        findViewById(R.id.btnSubmit).setOnClickListener(this);
+
+        relationTitle.setText(configEntity.getGraphName() + "/" + configEntity.getRelName());
+        leftName.setText(localId);
+        rightName.setText(equip.getLocalId());
+        if (Objects.equals(configEntity.getClassCodeFrom(), equip.getClassCode())) {
+            relationTv.setText("<-");
+        } else {
+            relationTv.setText("->");
+        }
     }
 
     public void setDisplay(Context context) {
@@ -74,7 +90,7 @@ public class ObjectRelationDialog extends Dialog implements View.OnClickListener
             case R.id.connect:
                 relationTv.setText("--");
                 break;
-            case R.id.btn_submit:
+            case R.id.btnSubmit:
                 if (submit != null) {
                     submit.onSubmit();
                 }

+ 121 - 0
demo/src/main/java/com/sybotan/android/demo/view/PipeDialog.java

@@ -0,0 +1,121 @@
+package com.sybotan.android.demo.view;
+
+import android.annotation.SuppressLint;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.view.Gravity;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import com.framework.mvvm.model.db.entity.ObjectEntity;
+import com.framework.mvvm.model.db.entity.PipeConfigEntity;
+import com.framework.mvvm.model.db.entity.RelConfigEntity;
+import com.sybotan.android.demo.R;
+
+import java.util.Objects;
+
+
+/**
+ * 设备关系
+ */
+
+public class PipeDialog extends Dialog implements View.OnClickListener {
+
+    private TextView relationTv;
+    private Submit submit;
+
+    public PipeDialog(@NonNull Context context, String localId, ObjectEntity equip, PipeConfigEntity configEntity) {
+        super(context, R.style.style_dialog);
+        setDisplay(context);
+        init(localId, equip, configEntity);
+    }
+
+    private void init(String localId, ObjectEntity equip, PipeConfigEntity configEntity) {
+        relationTv = findViewById(R.id.relationTv);
+        TextView leftName = findViewById(R.id.leftName);
+        TextView rightName = findViewById(R.id.rightName);
+        TextView relationTitle = findViewById(R.id.relationTitle);
+        findViewById(R.id.toleft).setOnClickListener(this);
+        findViewById(R.id.toright).setOnClickListener(this);
+        findViewById(R.id.connect).setOnClickListener(this);
+        findViewById(R.id.btnSubmit).setOnClickListener(this);
+
+        relationTitle.setText(configEntity.getPipeType());
+
+        if (Objects.equals(configEntity.getClassCodeFrom(), equip.getClassCode())) {
+            leftName.setText(localId);
+            rightName.setText(equip.getLocalId());
+        } else {
+            rightName.setText(localId);
+            leftName.setText(equip.getLocalId());
+        }
+        if (configEntity.getPipeDirection() == 1) {
+            relationTv.setText("->");
+        } else if (configEntity.getPipeDirection() == -1) {
+            relationTv.setText("<-");
+        } else if (configEntity.getPipeDirection() == 0) {
+            relationTv.setText("--");
+        }
+    }
+
+    public void setDisplay(Context context) {
+        setContentView(R.layout.dialog_object_relation);
+        setProperty();
+        setCancelable(true);
+        setCanceledOnTouchOutside(true);
+        setOnCancelListener(new OnCancelListener() {
+            @Override
+            public void onCancel(DialogInterface dialog) {
+                dialog.dismiss();
+            }
+        });
+    }
+
+    public void setProperty() {
+        Window window = getWindow();//得到对话框的窗口.
+        WindowManager.LayoutParams wl = window.getAttributes();
+        wl.x = 0;// 设置对话框的位置.0为中间
+        wl.y = 0;
+        wl.alpha = 1;// 设置对话框的透明度
+        wl.gravity = Gravity.CENTER;
+        window.setAttributes(wl);
+    }
+
+    @SuppressLint("NonConstantResourceId")
+    @Override
+    public void onClick(View v) {
+        switch (v.getId()) {
+            case R.id.toleft:
+                relationTv.setText("->");
+                break;
+            case R.id.toright:
+                relationTv.setText("<-");
+                break;
+            case R.id.connect:
+                relationTv.setText("--");
+                break;
+            case R.id.btnSubmit:
+                if (submit != null) {
+                    submit.onSubmit();
+                }
+                dismiss();
+                break;
+            default:
+                break;
+        }
+    }
+
+    public interface Submit {
+        void onSubmit();
+    }
+
+    public void setOnSubmit(Submit submit) {
+        this.submit = submit;
+    }
+
+}

+ 641 - 72
demo/src/main/java/com/sybotan/android/demo/viewmodel/GraphyVM.kt

@@ -1,5 +1,6 @@
 package com.sybotan.android.demo.viewmodel
 
+import android.app.Activity.RESULT_OK
 import android.app.Application
 import android.graphics.PointF
 import android.text.TextUtils
@@ -7,15 +8,11 @@ import androidx.lifecycle.viewModelScope
 import cn.sagacloud.android.cadengine.items.PointItem
 import cn.sagacloud.android.cadengine.items.SpaceItem
 import cn.sagacloud.android.cadengine.items.TunableSpaceItem
-import cn.sagacloud.android.cadengine.types.Photos
-import cn.sagacloud.android.cadengine.types.Point
-import cn.sagacloud.android.cadengine.types.PointZ
-import cn.sagacloud.android.cadengine.types.TunableSpace
+import cn.sagacloud.android.cadengine.types.*
 import com.framework.mvvm.model.db.entity.*
 import com.framework.mvvm.model.repository.AdmRepository
 import com.sybotan.android.demo.bean.result.ProblemsModel
 import com.google.gson.Gson
-import com.google.gson.JsonObject
 import com.google.gson.reflect.TypeToken
 import com.sybotan.android.demo.activities.BaseActivity
 import com.sybotan.android.demo.bean.request.*
@@ -25,6 +22,9 @@ import com.sybotan.android.demo.bean.result.Z
 import com.sybotan.android.demo.retrofit.BaseObserver
 import com.sybotan.android.demo.retrofit.BaseViewModelInterface
 import com.sybotan.android.demo.retrofit.RetrofitFactory
+import com.sybotan.android.demo.tools.CommonUtils
+import com.sybotan.android.demo.tools.ToastUtils
+import com.sybotan.base.utils.SJsonUtil
 import kotlinx.coroutines.launch
 import org.json.JSONObject
 import org.kodein.di.DI
@@ -34,6 +34,7 @@ import org.kodein.di.instance
 import java.text.SimpleDateFormat
 import java.util.*
 import kotlin.collections.ArrayList
+import kotlin.collections.HashMap
 
 /**
  * Created by lihao.
@@ -152,17 +153,21 @@ class GraphyVM(
             }
 
             var problem = ProblemArchEntity(
-                toString,
-                floorId,
-                projectId,
-                buildingId,
-                "point", "",
-                "",
-                1,
-                content,
-                "",
-                time,
-                "android", time, "0", 1, toJson
+                id = toString,
+                floorId = floorId,
+                projectId = projectId,
+                buildingId = buildingId,
+                geomType = "point", workId = "",
+                problemType = "",
+                problemState = 1,
+                message = content,
+                creator = "",
+                creationTime = time,
+                modifier = "android",
+                modifiedTime = time,
+                uploadFlag = "",
+                valid = 1,
+                geom = toJson
             )
             repo.insProblem(problem)
 
@@ -179,24 +184,24 @@ class GraphyVM(
                     }
 
                     val file = FileEntity(
-                        uuid,
-                        "problem_arch",
-                        photo.key,
-                        "photo",
-                        photo.path,
-                        toString,
-                        "",
-                        "",
-                        order,
-                        projectId,
-                        buildingId,
-                        floorId,
-                        "android",
-                        time,
-                        "",
-                        time,
-                        1,
-                        "0"
+                        id = uuid,
+                        bizType = "problem_arch",
+                        filePath = photo.key,
+                        fileType = "photo",
+                        clientPath = photo.path,
+                        refObjId = toString,
+                        refInfoCode = "",
+                        remark = "",
+                        orderNum = order,
+                        projectId = projectId,
+                        buildingId = buildingId,
+                        floorId = floorId,
+                        creator = "android",
+                        creationTime = time,
+                        modifier = "",
+                        modifiedTime = time,
+                        valid = 1,
+                        uploadFlag = ""
                     )
                     repo.insFile(file)
                 }
@@ -316,7 +321,7 @@ class GraphyVM(
                 modifier = "Android",
                 modifiedTime = time,
                 valid = 1,
-                uploadFlag = "0"
+                uploadFlag = ""
             )
             repo.insQrcode(qrcode)
             mEmitter.SendDircetive(BIND_QECODE, null)
@@ -418,15 +423,78 @@ class GraphyVM(
      * @param choseSpace 选中的空间
      */
     fun getSpaceEq(choseSpace: TunableSpaceItem?) {
-        val bean = ReqSpaceEq()
-        bean.group = true
-        bean.spaceId = choseSpace!!.data.id
-        val observable = RetrofitFactory.getInstance().getSpaceEq(getRequestBody(bean))
-        sendRequest(observable, object : BaseObserver<List<SpaceEqModel>>(mActivity, this) {
-            override fun onSuccess(models: List<SpaceEqModel>) {
-                mEmitter.SendDircetive(SPACE_EQ, models)
+        viewModelScope.launch {
+            var equips = repo.getEquipByFloorId(floorId)
+
+            var models: ArrayList<SpaceEqModel> = ArrayList()
+            for (equip in equips) {
+                var hasParent = false
+                for (model in models) {
+                    if (model.type!!.equals(equip.classCode)) {
+                        hasParent = true
+                        val child = Children()
+                        child.deviceId = equip.id
+                        child.name = equip.name
+                        val strInfo = gson.fromJson(equip.strInfos, StrInfosforEquip::class.java)
+                        val eqProblems = repo.getEqProblem(equip.id)
+                        if (eqProblems != null && !TextUtils.isEmpty(eqProblems.id)) {
+                            child.type = 3
+                        } else if (strInfo.equipCheck) {
+                            child.type = 2
+                        } else {
+                            child.type = 1
+                        }
+                        val position = Position()
+                        position.x = strInfo.location.x.toString()
+                        position.y = strInfo.location.y.toString()
+                        val z = Z()
+                        z.offset = strInfo.location.z.toString()
+                        z.region = strInfo.zRegion
+                        position.z = z
+                        child.position = gson.toJson(position)
+                        model.children.add(child)
+                    }
+                }
+                if (!hasParent) {
+                    val spaceModel = SpaceEqModel()
+                    spaceModel.type = equip.classCode
+                    var equipEntity = repo.getEquipByCode(equip.classCode)
+                    spaceModel.typeName = equipEntity.name
+                    val child = Children()
+                    child.deviceId = equip.id
+                    child.name = equip.name
+                    val strInfo = gson.fromJson(equip.strInfos, StrInfosforEquip::class.java)
+                    val eqProblems = repo.getEqProblem(equip.id)
+                    if (eqProblems != null && !TextUtils.isEmpty(eqProblems.id)) {
+                        child.type = 3
+                    } else if (strInfo.equipCheck) {
+                        child.type = 2
+                    } else {
+                        child.type = 1
+                    }
+                    val position = Position()
+                    position.x = strInfo.location.x.toString()
+                    position.y = strInfo.location.y.toString()
+                    val z = Z()
+                    z.offset = strInfo.location.z.toString()
+                    z.region = strInfo.zRegion
+                    position.z = z
+                    child.position = gson.toJson(position)
+                    spaceModel.children.add(child)
+                    models.add(spaceModel)
+                }
             }
-        }, true)
+            mEmitter.SendDircetive(SPACE_EQ, models)
+        }
+//        val bean = ReqSpaceEq()
+//        bean.group = true
+//        bean.spaceId = choseSpace!!.data.id
+//        val observable = RetrofitFactory.getInstance().getSpaceEq(getRequestBody(bean))
+//        sendRequest(observable, object : BaseObserver<List<SpaceEqModel>>(mActivity, this) {
+//            override fun onSuccess(models: List<SpaceEqModel>) {
+//                mEmitter.SendDircetive(SPACE_EQ, models)
+//            }
+//        }, true)
     }
 
     /**
@@ -450,42 +518,80 @@ class GraphyVM(
      * @param choseSpace    被选中的空间
      */
     fun addPipe(
-        model: PipeListModel,
-        pipeLineList: java.util.ArrayList<PointF>,
-        remark: String,
-        choseSpace: TunableSpaceItem?
+//        model: PipeListModel,
+//        pipeLineList: java.util.ArrayList<PointF>,
+//        remark: String,
+//        choseSpace: TunableSpaceItem?
     ) {
-        val bean = ReqAddPipe()
-        bean.spaceId = choseSpace!!.data.id
-        bean.sys = model.sysCode
-        bean.type = model.code
-        bean.position = pipeLineList
-        bean.remark = remark
-        bean.name = model.name
-        val observable = RetrofitFactory.getInstance().addPipe(getRequestBody(bean))
-        sendRequest(observable, object : BaseObserver<AddPipeModel>(mActivity, this) {
-            override fun onSuccess(models: AddPipeModel) {
-                mEmitter.SendDircetive(ADD_PIPE, null)
-            }
-        }, true)
+//        val bean = ReqAddPipe()
+//        bean.spaceId = choseSpace!!.data.id
+//        bean.sys = model.sysCode
+//        bean.type = model.code
+//        bean.position = pipeLineList
+//        bean.remark = remark
+//        bean.name = model.name
+//        val observable = RetrofitFactory.getInstance().addPipe(getRequestBody(bean))
+//        sendRequest(observable, object : BaseObserver<AddPipeModel>(mActivity, this) {
+//            override fun onSuccess(models: AddPipeModel) {
+//                mEmitter.SendDircetive(ADD_PIPE, null)
+//            }
+//        }, true)
     }
 
     /**
      * 查询楼层下的管道数据
      */
     fun floorPipe() {
-        val bean = ReqFloorPipe()
-        bean.floorId = floorId
-        val observable = RetrofitFactory.getInstance().floorPipe(getRequestBody(bean))
-        sendRequest(
-            observable,
-            object : BaseObserver<java.util.ArrayList<SpacePipeModel>>(mActivity, this) {
-                override fun onSuccess(models: java.util.ArrayList<SpacePipeModel>) {
-                    mEmitter.SendDircetive(SPACE_PIPE, models)
+        viewModelScope.launch {
+            val pipeModels = ArrayList<SpacePipeModel>()
+            val pipes = repo.getPipeByFloorId(floorId)
+            for (pipe in pipes) {
+                var hasParent = false
+                for (model in pipeModels) {
+                    if (model.type!!.equals(pipe.pipeType)) {
+                        val child = ChildrenZ()
+                        val objFrom = repo.getObject(pipe.objFrom!!)
+                        val objTo = repo.getObject(pipe.objTo!!)
+                        val strInfoFrom =
+                            gson.fromJson(objFrom.strInfos, StrInfosforEquip::class.java)
+                        child.position.add(PointF(strInfoFrom.location.x, strInfoFrom.location.y))
+
+                        val strInfoTo = gson.fromJson(objTo.strInfos, StrInfosforEquip::class.java)
+                        child.position.add(PointF(strInfoTo.location.x, strInfoTo.location.y))
+                        model.children.add(child)
+                        hasParent = true
+                    }
+                }
+                if (!hasParent) {
+                    val pipeModel = SpacePipeModel()
+                    pipeModel.typeName = pipe.pipeType
+
+                    val child = ChildrenZ()
+                    val objFrom = repo.getObject(pipe.objFrom!!)
+                    val objTo = repo.getObject(pipe.objTo!!)
+                    val strInfoFrom = gson.fromJson(objFrom.strInfos, StrInfosforEquip::class.java)
+                    child.position.add(PointF(strInfoFrom.location.x, strInfoFrom.location.y))
+
+                    val strInfoTo = gson.fromJson(objTo.strInfos, StrInfosforEquip::class.java)
+                    child.position.add(PointF(strInfoTo.location.x, strInfoTo.location.y))
+                    pipeModel.children.add(child)
+                    pipeModels.add(pipeModel)
                 }
-            },
-            true
-        )
+
+            }
+        }
+//        val bean = ReqFloorPipe()
+//        bean.floorId = floorId
+//        val observable = RetrofitFactory.getInstance().floorPipe(getRequestBody(bean))
+//        sendRequest(
+//            observable,
+//            object : BaseObserver<ArrayList<SpacePipeModel>>(mActivity, this) {
+//                override fun onSuccess(models: java.util.ArrayList<SpacePipeModel>) {
+//                    mEmitter.SendDircetive(SPACE_PIPE, models)
+//                }
+//            },
+//            true
+//        )
     }
 
     fun getInfosConfig(spaceId: String) {
@@ -498,15 +604,34 @@ class GraphyVM(
                 strInfos,
                 object : TypeToken<List<Infos?>?>() {}.type
             )
+            var spaceObject = repo.getObject(spaceId)
+            var infos = spaceObject.infos
+
+            mEmitter.SendDircetive(SPACE_INFOS, jsonObjectToHashMap(infos))
             mEmitter.SendDircetive(SPACE_INFO, infoList)
         }
     }
 
+    fun jsonObjectToHashMap(jsonObj: JSONObject?): HashMap<String, String>? {
+        if (jsonObj == null) {
+            return null
+        }
+        val data = HashMap<String, String>()
+        val it: Iterator<*> = jsonObj.keys()
+        while (it.hasNext()) {
+            val key = it.next().toString()
+            data[key] = jsonObj[key].toString()
+        }
+        System.out.println(data)
+        return data
+    }
+
     fun refreshObject(space: TunableSpace, hashMap: HashMap<String, Any>) {
         viewModelScope.launch {
             var space = repo.getObject(space.id!!)
             space.infos = JSONObject(hashMap as Map<*, *>)
             repo.insObject(space)
+            mActivity.setResult(RESULT_OK)
             mActivity.finish()
 //            var objectEntity = ObjectEntity(
 //                id = space.id!!,
@@ -517,7 +642,440 @@ class GraphyVM(
         }
     }
 
+
+    fun getEquipment(deviceId: String) {
+        viewModelScope.launch {
+            val equips = repo.getEquipment()
+            for (equip in equips) {
+                if (!TextUtils.isEmpty(equip.systemCode)) {
+                    val systemEntity = repo.getSysByCode(equip.systemCode!!)
+                    equip.systemName = systemEntity.name
+                }
+            }
+            mEmitter.SendDircetive(EQUIP_CLASS, equips)
+
+            if (!TextUtils.isEmpty(deviceId)) {
+                var equip = repo.getObject(deviceId)
+                var infos = equip.infos
+                mEmitter.SendDircetive(SPACE_INFOS, jsonObjectToHashMap(infos))
+                mEmitter.SendDircetive(Equip_INFOS, equip)
+            }
+
+
+//            var infoList = gson.fromJson(strInfos, ArrayList<Infos>()::class.java)
+
+        }
+    }
+
+    fun getEquipInfosConfig(equipmentEntity: EquipmentEntity) {
+        viewModelScope.launch {
+            val infosConfig = repo.getInfosConfigByEquipCode(equipmentEntity.code!!)
+            if (CommonUtils.IsNull(infosConfig)) {
+                mEmitter.SendDircetive(EQUIP_INFO, null)
+                return@launch
+            }
+            val strInfos = infosConfig.get(0).strInfos
+            val infoList = gson.fromJson<List<Infos>>(
+                strInfos,
+                object : TypeToken<List<Infos?>?>() {}.type
+            )
+            mEmitter.SendDircetive(EQUIP_INFO, infoList)
+
+        }
+    }
+
+    fun insEquip(
+        uuid: String,
+        deviceId: String?,
+        hashMap: HashMap<String, Any>?,
+        equipContent: String,
+        beans: ArrayList<Photos>,
+        equipEntity: EquipmentEntity,
+        localName: String,
+        localId: String,
+        checked: Boolean,
+        position: Position
+    ) {
+        viewModelScope.launch {
+            hashMap!!.put("equipContent", equipContent)
+            hashMap!!.put("equipPhoto", gson.toJson(beans))
+            hashMap!!.put("equipCheck", checked)
+            val z = PointZ()
+            z.x = position.x.toFloat()
+            z.y = -position.y.toFloat()
+            z.z = position.z.offset.toFloat()
+            hashMap!!.put("location", z)
+            hashMap!!.put("zRegion", position.z.region)
+            if (TextUtils.isEmpty(deviceId)) {
+                val objectEntity = ObjectEntity(
+                    id = uuid,
+                    name = localName,
+                    projectId = projectId,
+                    objType = "equipment",
+                    classCode = equipEntity.code!!,
+                    localId = localId,
+                    localName = localName,
+                    groupCode = "",
+                    grouping = 1,
+                    buildingId = buildingId,
+                    floorId = floorId,
+                    creator = "Android",
+                    createApp = "",
+                    creationTime = SimpleDateFormat("yyyyMMddHHmmss").format(Date(System.currentTimeMillis()))
+                        .toLong(),
+                    modifier = "Android",
+                    modifiedTime = 0,
+                    clientDevice = "",
+                    clientId = uuid,
+                    updateApp = "",
+                    uploadFlag = "",
+                    valid = 1,
+                    deliveryState = null,
+                    d2mState = null,
+                    virtualCodes = null,
+                    infos = JSONObject(hashMap as Map<*, *>),
+                    strInfos = gson.toJson(hashMap),
+                    floorMap = null
+                )
+                repo.insObject(objectEntity)
+            } else {
+                val equip = repo.getObject(deviceId!!)
+                equip.infos = JSONObject(hashMap as Map<*, *>)
+                equip.strInfos = gson.toJson(hashMap)
+                repo.insObject(equip)
+            }
+            //插入文件数据
+            var order = 0
+            for (photo in beans) {
+                if (order != 0) {
+                    var phUuid = ""
+                    if (TextUtils.isEmpty(photo.id)) {
+                        phUuid = UUID.randomUUID().toString().replace("-", "")
+                    } else {
+                        phUuid = photo.id
+                    }
+
+                    val file = FileEntity(
+                        id = phUuid,
+                        bizType = "problem_arch",
+                        filePath = photo.key,
+                        fileType = "photo",
+                        clientPath = photo.path,
+                        refObjId = if (TextUtils.isEmpty(deviceId)) uuid else deviceId,
+                        refInfoCode = "",
+                        remark = "",
+                        orderNum = order,
+                        projectId = projectId,
+                        buildingId = buildingId,
+                        floorId = floorId,
+                        creator = "android",
+                        creationTime = "",
+                        modifier = "",
+                        modifiedTime = null,
+                        valid = 1,
+                        uploadFlag = ""
+                    )
+                    repo.insFile(file)
+                }
+                order++
+            }
+
+            mActivity.finish()
+        }
+    }
+
+    fun getMap() {
+        viewModelScope.launch {
+            val floors = repo.getFloors()
+            for (floor in floors) {
+                if (floor.id.equals(floorId)) {
+                    if (TextUtils.isEmpty(floor.floorMap)) {
+                        ToastUtils.showMyToast("没有地图")
+                        break
+                    }
+                    val floorOfflineData =
+                        SJsonUtil.fromJson(floor.floorMap!!, FloorData::class.java)
+                    mEmitter.SendDircetive(MAP_LOAD, gson.toJson(floorOfflineData))
+                    break
+                }
+            }
+
+        }
+    }
+
+    fun getRelConfig(entity: EquipmentEntity, deviceId: String, uuid: String) {
+        viewModelScope.launch {
+            val equipId = if (TextUtils.isEmpty(deviceId)) uuid else deviceId
+            //获取关系二级列表
+            val configParent = ArrayList<RelConfigEntity>()
+            val relList = mutableListOf<List<RelationEntity>>()
+            val fromList = repo.getRelConfigByCodeFrom(entity.code!!)
+            val toList = repo.getRelConfigByCodeTo(entity.code!!)
+            configParent.addAll(fromList)
+            for (config in fromList) {
+                val relsFrom = repo.getRelByCodeFrom(config.graphCode!!, config.relCode!!, equipId)
+                if (!CommonUtils.IsNull(relsFrom)) {
+                    for (rel in relsFrom) {
+                        val objFrom = repo.getObject(rel.objFrom!!)
+                        val objTo = repo.getObject(rel.objTo!!)
+                        rel.objFromLocalId = objFrom.localId
+                        rel.objToLocalId = objTo.localId
+                    }
+                    relList.add(relsFrom)
+                } else {
+                    relList.add(ArrayList<RelationEntity>())
+                }
+            }
+            configParent.addAll(toList)
+            for (config in toList) {
+                val relsTo = repo.getRelByCodeTo(config.graphCode!!, config.relCode!!, equipId)
+                if (!CommonUtils.IsNull(relsTo)) {
+                    for (rel in relsTo) {
+                        val objFrom = repo.getObject(rel.objFrom!!)
+                        val objTo = repo.getObject(rel.objTo!!)
+                        rel.objFromLocalId = objFrom.localId
+                        rel.objToLocalId = objTo.localId
+                    }
+                    relList.add(relsTo)
+                } else {
+                    relList.add(ArrayList<RelationEntity>())
+                }
+            }
+            val hashMap = HashMap<String, Any>()
+            hashMap.put("parent", configParent)
+            hashMap.put("child", relList)
+            mEmitter.SendDircetive(EQUIP_REL, hashMap)
+
+            //获取管道二级列表
+            val pipeParent = ArrayList<PipeConfigEntity>()
+            val pipeChildren = mutableListOf<List<PipeEntity>>()
+            val pipeFromList = repo.getPipeConfigByCodeFrom(entity.code!!)
+            val pipeToList = repo.getPipeConfigByCodeTo(entity.code!!)
+
+            pipeParent.addAll(pipeFromList)
+            for (config in pipeFromList) {
+                val pipeFrom = repo.getPipeByIdFrom(equipId, config.pipeType!!)
+                if (!CommonUtils.IsNull(pipeFrom)) {
+                    for (rel in pipeFrom) {
+                        val objFrom = repo.getObject(rel.objFrom!!)
+                        val objTo = repo.getObject(rel.objTo!!)
+                        rel.objFromLocalId = objFrom.localId
+                        rel.objToLocalId = objTo.localId
+                    }
+                    pipeChildren.add(pipeFrom)
+                } else {
+                    pipeChildren.add(ArrayList<PipeEntity>())
+                }
+            }
+
+            pipeParent.addAll(pipeToList)
+            for (config in pipeToList) {
+                val pipeFrom = repo.getPipeByIdTo(equipId, config.pipeType!!)
+                if (!CommonUtils.IsNull(pipeFrom)) {
+                    for (rel in pipeFrom) {
+                        val objFrom = repo.getObject(rel.objFrom!!)
+                        val objTo = repo.getObject(rel.objTo!!)
+                        rel.objFromLocalId = objFrom.localId
+                        rel.objToLocalId = objTo.localId
+                    }
+                    pipeChildren.add(pipeFrom)
+                } else {
+                    pipeChildren.add(ArrayList<PipeEntity>())
+                }
+            }
+            val hashMap1 = HashMap<String, Any>()
+            hashMap1.put("parent", pipeParent)
+            hashMap1.put("child", pipeChildren)
+            mEmitter.SendDircetive(PIPE, hashMap1)
+
+        }
+    }
+
+    fun getRelObj(group: RelConfigEntity, code: String) {
+        viewModelScope.launch {
+            val objects: List<ObjectEntity>
+            if (group.classCodeFrom.equals(code)) {
+                objects = repo.getObjectByCode(group.classCodeTo!!)
+            } else {
+                objects = repo.getObjectByCode(group.classCodeFrom!!)
+            }
+            mEmitter.SendDircetive(REL_OBJECT, objects)
+        }
+    }
+
+    fun getPipeObj(group: PipeConfigEntity, code: String) {
+        viewModelScope.launch {
+            val objects: List<ObjectEntity>
+            if (group.classCodeFrom.equals(code)) {
+                objects = repo.getObjectByCode(group.classCodeTo!!)
+            } else {
+                objects = repo.getObjectByCode(group.classCodeFrom!!)
+            }
+            mEmitter.SendDircetive(PIPE_OBJECT, objects)
+        }
+    }
+
+    fun addRel(
+        deviceId: String, uuid: String, equipEntity: EquipmentEntity,
+        equip: ObjectEntity,
+        groupRelConfigEntity: RelConfigEntity
+    ) {
+        viewModelScope.launch {
+            var equipId: String
+            if (TextUtils.isEmpty(deviceId)) {
+                equipId = uuid
+            } else {
+                equipId = deviceId
+            }
+            val objFrom: String
+            val objto: String
+            if (groupRelConfigEntity.classCodeFrom.equals(equipEntity!!.code)) {
+                objFrom = equipId
+                objto = equip.id
+            } else {
+                objto = equipId
+                objFrom = equip.id
+            }
+
+            val relEntity = RelationEntity(
+                id = UUID.randomUUID().toString(),
+                projectId = projectId,
+                buildingId = buildingId,
+                floorId = floorId,
+                graphCode = groupRelConfigEntity.graphCode,
+                graphId = null,
+                groupCode = null,
+                relCode = groupRelConfigEntity.relCode,
+                relValue = null,
+                objFrom = objFrom,
+                objTo = objto,
+                createApp = null,
+                updateApp = null,
+                creator = null,
+                creationTime = null,
+                modifiedTime = null,
+                modifier = null,
+                clientId = null,
+                clientDevice = null,
+                uploadFlag = null,
+                deliveryState = null,
+                valid = 1, d2mState = null, objFromLocalId = null, objToLocalId = null
+            )
+            repo.insRelation(relEntity)
+            getRelConfig(equipEntity, deviceId, uuid)
+        }
+    }
+
+    fun addPipe(
+        deviceId: String, uuid: String, equipEntity: EquipmentEntity,
+        equip: ObjectEntity,
+        groupPipeConfigEntity: PipeConfigEntity
+    ) {
+        viewModelScope.launch {
+            var equipId: String
+            if (TextUtils.isEmpty(deviceId)) {
+                equipId = uuid
+            } else {
+                equipId = deviceId
+            }
+            val objFrom: String
+            val objto: String
+            if (groupPipeConfigEntity.classCodeFrom.equals(equipEntity!!.code)) {
+                objFrom = equipId
+                objto = equip.id
+            } else {
+                objto = equipId
+                objFrom = equip.id
+            }
+
+            val relEntity = PipeEntity(
+                id = UUID.randomUUID().toString(),
+                projectId = projectId,
+                buildingId = buildingId,
+                floorId = floorId,
+
+                objFrom = objFrom,
+                objTo = objto,
+
+                creator = null,
+                creationTime = null,
+                modifiedTime = null,
+                modifier = null,
+                uploadFlag = null,
+                deliveryState = null,
+                valid = 1,
+                d2mState = null,
+                objFromLocalId = null,
+                objToLocalId = null,
+                direction = groupPipeConfigEntity.pipeDirection,
+                typeFrom = "equipment",
+                typeTo = "equipment",
+                pipeType = groupPipeConfigEntity.pipeType,
+                pipeSubType = groupPipeConfigEntity.pipeSubType,
+                route = null,
+                infos = null
+            )
+            repo.insPipe(relEntity)
+            getRelConfig(equipEntity, deviceId, uuid)
+        }
+    }
+
+    fun insProblemEquip(space: TunableSpaceItem, deviceId: String) {
+        viewModelScope.launch {
+            val entity = ProblemEquipEntity(
+                id = UUID.randomUUID().toString(),
+                floorId = floorId,
+                projectId = projectId,
+                buildingId = buildingId,
+                equipId = deviceId,
+                workId = null,
+                problemType = null,
+                problemState = 1,
+                message = null,
+                creator = null,
+                creationTime = null,
+                modifier = null,
+                modifiedTime = null,
+                uploadFlag = null,
+                valid = 1
+            )
+            repo.insProblemEquipEntity(entity)
+        }
+        getSpaceEq(space)
+    }
+
+    fun deleteRel(
+        item: RelationEntity,
+        equipEntity: EquipmentEntity?,
+        deviceId: String,
+        uuid: String
+    ) {
+        viewModelScope.launch {
+            var rel = repo.getRelById(item.id)
+            rel.valid = 0
+            repo.insRelation(rel)
+            getRelConfig(equipEntity!!, deviceId, uuid)
+        }
+    }
+
+    fun deletePipe(
+        item: PipeEntity,
+        equipEntity: EquipmentEntity?,
+        deviceId: String,
+        uuid: String
+    ) {
+        viewModelScope.launch {
+            var rel = repo.getPipeById(item.id)
+            rel.valid = 0
+            repo.insPipe(rel)
+            getRelConfig(equipEntity!!, deviceId, uuid)
+        }
+    }
+
     companion object {
+        const val MAP_LOAD = "MAP_LOAD"
+        const val EQUIP_CLASS = "EQUIP_CLASS"
+
         //
         const val REFRESH_OBJECT = "SPACE_JOB"
 
@@ -554,11 +1112,22 @@ class GraphyVM(
         //添加管线
         const val ADD_PIPE = "ADD_PIPE"
 
-        //查询空间下的管道
+        //查询空间下的管道Equip_INFOS
         const val SPACE_PIPE = "SPACE_PIPE"
 
         //查询空间详情
         const val SPACE_INFO = "SPACE_INFO"
+        const val SPACE_INFOS = "SPACE_INFOS"
+
+
+        //查询设备详情
+        const val EQUIP_INFO = "EQUIP_INFO"
+        const val Equip_INFOS = "Equip_INFOS"
+        const val EQUIP_REL = "EQUIP_REL"
+
+        const val REL_OBJECT = "REL_OBJECT"
+        const val PIPE_OBJECT = "PIPE_OBJECT"
+        const val PIPE = "PIPE"
     }
 
 }

+ 20 - 2
demo/src/main/res/layout/activity_equip_detail.xml

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
     android:id="@+id/root"
+    android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@color/white_ffffff"
     android:orientation="vertical">
@@ -34,17 +34,33 @@
         </RelativeLayout>
 
         <com.sybotan.android.demo.view.ListItemView
+            android:id="@+id/equipClass"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             app:LeftText="设备类"
             app:Type="0" />
 
         <com.sybotan.android.demo.view.ListItemView
+            android:visibility="gone"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             app:LeftText="现场记录"
             app:Type="4" />
 
+        <com.sybotan.android.demo.view.ListItemView
+            android:visibility="gone"
+            android:id="@+id/localName"
+            android:layout_width="match_parent"
+            android:layout_height="44dp"
+            android:layout_marginTop="10dp"
+            app:Type="1" />
+        <com.sybotan.android.demo.view.ListItemView
+            android:id="@+id/localId"
+            android:layout_width="match_parent"
+            android:layout_height="44dp"
+            android:layout_marginTop="10dp"
+            app:Type="1" />
+
         <include layout="@layout/view_mtext" />
 
         <include layout="@layout/view_picture" />
@@ -65,6 +81,7 @@
                 android:textSize="15sp" />
 
             <androidx.appcompat.widget.SwitchCompat
+                android:id="@+id/doneSwitch"
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
                 android:paddingLeft="10dp"
@@ -98,13 +115,14 @@
             android:layout_height="wrap_content" />
 
         <TextView
-            android:id="@+id/btn_submit"
+            android:id="@+id/btnSubmit"
             android:layout_width="match_parent"
             android:layout_height="40dp"
             android:layout_gravity="center"
             android:layout_marginLeft="16dp"
             android:layout_marginTop="20dp"
             android:layout_marginRight="16dp"
+            android:layout_marginBottom="40dp"
             android:background="@drawable/shape_rectangle_green_3"
             android:gravity="center"
             android:text="提交"

+ 1 - 1
demo/src/main/res/layout/activity_graphy.xml

@@ -669,7 +669,7 @@
                 android:layout_height="wrap_content"
                 android:layout_gravity="center_horizontal"
                 android:layout_marginTop="8dp"
-                android:text="(0,0)"
+                android:text=""
                 android:textColor="@color/grey_900"
                 android:textSize="16sp" />
 

+ 3 - 0
demo/src/main/res/layout/activity_space_detail.xml

@@ -34,18 +34,21 @@
         </RelativeLayout>
 
         <com.sybotan.android.demo.view.ListItemView
+            android:visibility="gone"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             app:LeftText="物业分区"
             app:Type="4" />
 
         <com.sybotan.android.demo.view.ListItemView
+            android:visibility="gone"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             app:LeftText="静态属性信息"
             app:Type="4" />
 
         <com.sybotan.android.demo.view.ListItemView
+            android:visibility="gone"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             app:LeftText="空间功能类型"

+ 1 - 1
demo/src/main/res/layout/child_expand_relation.xml

@@ -5,7 +5,7 @@
     android:orientation="horizontal">
 
     <ImageView
-        android:id="@+id/add"
+        android:id="@+id/delete"
         android:layout_width="50dp"
         android:layout_height="40dp"
         android:layout_gravity="center_vertical"

+ 3 - 1
demo/src/main/res/layout/dialog_object_relation.xml

@@ -62,6 +62,7 @@
     </androidx.appcompat.widget.LinearLayoutCompat>
 
     <TextView
+        android:visibility="gone"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="30dp"
@@ -70,6 +71,7 @@
         android:textSize="16sp" />
 
     <androidx.appcompat.widget.LinearLayoutCompat
+        android:visibility="gone"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="19dp"
@@ -118,7 +120,7 @@
     </androidx.appcompat.widget.LinearLayoutCompat>
 
     <TextView
-        android:id="@+id/btn_submit"
+        android:id="@+id/btnSubmit"
         android:layout_width="match_parent"
         android:layout_height="40dp"
         android:layout_gravity="center"

+ 3 - 0
demo/src/main/res/layout/geometry_info.xml

@@ -16,18 +16,21 @@
         android:textStyle="bold" />
 
     <com.sybotan.android.demo.view.ListItemView
+        android:id="@+id/location"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         app:LeftText="中心位置点"
         app:Type="4" />
 
     <com.sybotan.android.demo.view.ListItemView
+        android:id="@+id/height"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         app:LeftText="高度"
         app:Type="4" />
 
     <com.sybotan.android.demo.view.ListItemView
+        android:id="@+id/locationWhere"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         app:LeftText="位置"

+ 0 - 1
demo/src/main/res/layout/layout_common_list_item1.xml

@@ -63,7 +63,6 @@
         android:background="@null"
         android:gravity="right"
         android:hint="请输入"
-        android:inputType="number"
         android:singleLine="true"
         android:textColor="@color/black_272727"
         android:textColorHint="@color/gray_a6a6a6"

+ 1 - 1
demo/src/main/res/layout/view_mtext.xml

@@ -14,7 +14,7 @@
         android:orientation="horizontal">
 
         <TextView
-            android:id="@+id/mtext_title"
+            android:id="@+id/mtextTitle"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="文字记录"

+ 7 - 7
sybotan-android-graphy/src/main/java/com/sybotan/android/graphy/SGraphyItem.kt

@@ -367,7 +367,7 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
      * @return  true包含;false不包含。
      */
     open fun contains(x: Float, y: Float): Boolean {
-        Log.e("boundingRect", boundingRect().contains(x, y).toString())
+//        Log.e("boundingRect", boundingRect().contains(x, y).toString())
         return boundingRect().contains(x, y)
     } // Function ()
 
@@ -508,17 +508,17 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
                 continue
             }
             val ce = toChildMotionEvent(item, e)
-            Log.e("手势view", "${scene?.view?.scale}")
-            Log.e("手势e", "${e.x}, ${e.y}")
-            Log.e("手势ce", "${ce.x}, ${ce.y}")
-            Log.e("手势1scene", (item.contains(ce.x, ce.y)).toString())
+//            Log.e("手势view", "${scene?.view?.scale}")
+//            Log.e("手势e", "${e.x}, ${e.y}")
+//            Log.e("手势ce", "${ce.x}, ${ce.y}")
+//            Log.e("手势1scene", (item.contains(ce.x, ce.y)).toString())
             if (item.contains(ce.x, ce.y)                                   // 如果点在子项目上
                     && item.onSingleTapUp(ce)) {                            // 且子项目处理了事件
-                Log.e("手势4scene", e.toJson())
+//                Log.e("手势4scene", e.toJson())
                 return true
             }
         }
-        Log.e("手势2scene", e.toJson())
+//        Log.e("手势2scene", e.toJson())
         return false
     } // Function onSingleTapUp()