浏览代码

add poc2.0修复bug

lihao1 3 年之前
父节点
当前提交
b75a41f0d8
共有 18 个文件被更改,包括 800 次插入406 次删除
  1. 1 1
      demo/src/main/java/com/framework/mvvm/model/db/dao/ObjectDao.kt
  2. 1 0
      demo/src/main/java/com/framework/mvvm/model/db/entity/RelConfigEntity.kt
  3. 50 51
      demo/src/main/java/com/sybotan/android/demo/activities/EquipDetailActivity.kt
  4. 129 0
      demo/src/main/java/com/sybotan/android/demo/adapter/PersonalSelectSingleAdapter.java
  5. 13 13
      demo/src/main/java/com/sybotan/android/demo/adapter/PipeExpandAdapter.kt
  6. 9 8
      demo/src/main/java/com/sybotan/android/demo/adapter/RelationExpandAdapter.kt
  7. 2 2
      demo/src/main/java/com/sybotan/android/demo/adapter/SelectPopListAdapter.java
  8. 18 2
      demo/src/main/java/com/sybotan/android/demo/bean/PipeConfigEntityPackClass.java
  9. 18 0
      demo/src/main/java/com/sybotan/android/demo/bean/RelConfigEntityPackClass.java
  10. 12 0
      demo/src/main/java/com/sybotan/android/demo/bean/RelationPackClass.java
  11. 1 1
      demo/src/main/java/com/sybotan/android/demo/view/ListItemView.java
  12. 27 11
      demo/src/main/java/com/sybotan/android/demo/view/ObjectRelationDialog.java
  13. 34 14
      demo/src/main/java/com/sybotan/android/demo/view/PipeDialog.java
  14. 216 0
      demo/src/main/java/com/sybotan/android/demo/view/SelectListSinglePopupWindow.java
  15. 213 291
      demo/src/main/java/com/sybotan/android/demo/viewmodel/GraphyVM.kt
  16. 21 11
      demo/src/main/res/layout/dialog_object_relation.xml
  17. 4 1
      demo/src/main/res/layout/layout_common_list_item.xml
  18. 31 0
      demo/src/main/res/layout/personal_select_text_single_item.xml

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

@@ -11,7 +11,7 @@ interface ObjectDao {
     @Query("select * from object")
     suspend fun getObjects(): List<ObjectEntity>
 
-    @Query("select * from object where id = :id and valid = 1")
+    @Query("select * from object where id = :id")
     suspend fun getObjectById(id: String): ObjectEntity?
 
     @Query("select * from object where obj_type = :objType and valid = 1")

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

@@ -20,4 +20,5 @@ data class RelConfigEntity(
     @ColumnInfo(name = "graph_name") val graphName: String?,           // 关系的图类型名称
     @ColumnInfo(name = "rel_code") val relCode: String?,               // 关系的边类型代码
     @ColumnInfo(name = "rel_name") val relName: String?,               // 关系的边类型代码
+    @ColumnInfo(name = "direction") val direction: String?,               // 关系方向(fixed|optional|none)
 )

+ 50 - 51
demo/src/main/java/com/sybotan/android/demo/activities/EquipDetailActivity.kt

@@ -27,6 +27,7 @@ import com.sybotan.android.demo.adapter.PipeExpandAdapter
 import com.sybotan.android.demo.adapter.RelationExpandAdapter
 import com.sybotan.android.demo.bean.PipeConfigEntityPackClass
 import com.sybotan.android.demo.bean.RelConfigEntityPackClass
+import com.sybotan.android.demo.bean.RelationPackClass
 import com.sybotan.android.demo.bean.result.Position
 import com.sybotan.android.demo.bean.result.Z
 import com.sybotan.android.demo.retrofit.Constant
@@ -34,7 +35,6 @@ import com.sybotan.android.demo.tools.*
 import com.sybotan.android.demo.tools.LocalDataOperation.*
 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 com.yuyh.library.imgsel.utils.LogUtils
@@ -71,8 +71,8 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
     private lateinit var expandLvPipe: SuperExpandableListView
     private lateinit var expandLvRelation: SuperExpandableListView
     private lateinit var pictureAdapter: PictureAdapter
-    private lateinit var groupRelConfigEntity: RelConfigEntity
-    private lateinit var groupPipeConfigEntity: PipeConfigEntity
+    private lateinit var groupRelConfigEntity: RelConfigEntityPackClass
+    private lateinit var groupPipeConfigEntity: PipeConfigEntityPackClass
     var list = ArrayList<Infos>()
     val beans: ArrayList<Photos> = ArrayList()
     private lateinit var staticInfoAdapter: StaticInfoAdapter
@@ -301,13 +301,13 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
                 GraphyVM.EQUIP_REL -> {
                     val hashMap = params as HashMap<String, Any>
                     val parent = hashMap.get("parent") as ArrayList<RelConfigEntityPackClass>
-                    val children = hashMap.get("child") as MutableList<List<RelationEntity>>
+                    val children = hashMap.get("child") as MutableList<List<RelationPackClass>>
                     val relAdapter =
                         RelationExpandAdapter(this@EquipDetailActivity, parent, children)
                     relAdapter.setOnAdd(object : RelationExpandAdapter.AddRel {
                         override fun onAdd(group: RelConfigEntityPackClass) {
-                            this@EquipDetailActivity.groupRelConfigEntity = group.entity
-                            graphyVM.getRelObj(group.entity, equipEntity!!.code!!)
+                            this@EquipDetailActivity.groupRelConfigEntity = group
+                            graphyVM.getRelObj(group, equipEntity!!.code!!)
                         }
                     })
                     relAdapter.setOnDelete(object : RelationExpandAdapter.DeleteRel {
@@ -322,34 +322,34 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
                 }
                 GraphyVM.REL_OBJECT -> {
                     val equipObjects = params as List<ObjectEntity>
-                    val pop = SelectListPopupWindow(this)
+                    val pop = SelectListSinglePopupWindow(this@EquipDetailActivity)
                     pop.setList(equipObjects, Constant.TYPE2)
-                    pop.setTitle(true, "单选选择对象")
+                    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(),
+                    pop.setOnItemClickListener {
+                        if (!CommonUtils.IsNull(list)) {
+                            val equip = equipObjects.get(it)
+                            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
+                                    groupRelConfigEntity.entity,
+                                    it
                                 )
-                                dialog.show()
-                                dialog.setOnSubmit {
-                                    graphyVM.addRel(
-                                        deviceId,
-                                        uuid,
-                                        equipEntity!!,
-                                        equip,
-                                        groupRelConfigEntity
-                                    )
-                                }
                             }
                         }
-                    })
+                    }
+
                 }
                 GraphyVM.PIPE -> {
                     val hashMap = params as HashMap<String, Any>
@@ -357,7 +357,7 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
                     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) {
+                        override fun onAdd(group: PipeConfigEntityPackClass) {
                             this@EquipDetailActivity.groupPipeConfigEntity = group
                             graphyVM.getPipeObj(group, equipEntity!!.code!!)
                         }
@@ -374,34 +374,33 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
                 }
                 GraphyVM.PIPE_OBJECT -> {
                     val equipObjects = params as List<ObjectEntity>
-                    val pop = SelectListPopupWindow(this)
+                    val pop = SelectListSinglePopupWindow(this)
                     pop.setList(equipObjects, Constant.TYPE2)
-                    pop.setTitle(true, "单选选择对象")
+                    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(),
+                    pop.setOnItemClickListener {
+                        if (!CommonUtils.IsNull(list)) {
+                            val equip = equipObjects.get(it)
+                            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
+                                    groupPipeConfigEntity.entity,
+                                    it
                                 )
-                                dialog.show()
-                                dialog.setOnSubmit {
-                                    graphyVM.addPipe(
-                                        deviceId,
-                                        uuid,
-                                        equipEntity!!,
-                                        equip,
-                                        groupPipeConfigEntity
-                                    )
-                                }
                             }
                         }
-                    })
+                    }
                 }
             }
         }, this, buildingId, floorId, projectId)

+ 129 - 0
demo/src/main/java/com/sybotan/android/demo/adapter/PersonalSelectSingleAdapter.java

@@ -0,0 +1,129 @@
+package com.sybotan.android.demo.adapter;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CompoundButton;
+import android.widget.LinearLayout;
+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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by cunwen on 16/6/21.
+ */
+public class PersonalSelectSingleAdapter extends RecyclerView.Adapter<PersonalSelectSingleAdapter.BuildViewHolder> {
+    private List<?> items = new ArrayList<>();
+    private Context context;
+    private int selectPosition;
+    private String type;
+    private boolean isRed;
+    private int redPosition;
+    private Boolean flag;
+
+    public void setItems(List<?> items, Context context, int position, String type) {
+        this.items = items;
+        this.context = context;
+        this.selectPosition = position;
+        this.type = type;
+    }
+
+
+    @Override
+    public BuildViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        View mRootView = LayoutInflater.from(parent.getContext())
+                .inflate(R.layout.personal_select_text_single_item, parent, false);
+        return new BuildViewHolder(mRootView);
+    }
+
+    @Override
+    public void onBindViewHolder(final BuildViewHolder holder, final int position) {
+        final Object item = items.get(position);
+        if (type.equals(Constant.TYPE1)) {
+            Options options = (Options) item;
+            holder.choice_name.setText(options.getTxt());
+        }
+        if (type.equals(Constant.TYPE2)) {
+            ObjectEntity options = (ObjectEntity) item;
+            if (TextUtils.isEmpty(options.getLocalId())) {
+                holder.choice_name.setText(options.getClassCode() + ":" + options.getLocalName());
+            } else {
+                holder.choice_name.setText(options.getClassCode() + ":" + options.getLocalId());
+            }
+        }
+        if (selectPosition > 0 && selectPosition - 1 == position) {
+            holder.choice_name.setTextColor(context.getResources().getColor(R.color.blue_2f48b7));
+        } else {
+            holder.choice_name.setTextColor(context.getResources().getColor(R.color.black_272727));
+        }
+        if (isRed && position == redPosition) {
+            holder.choice_name.setTextColor(context.getResources().getColor(R.color.red_D44D44));
+        } else if (isRed) {
+            holder.choice_name.setTextColor(context.getResources().getColor(R.color.black_272727));
+        }
+        holder.choice_layout.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mOnItemClickListener != null) {
+                    mOnItemClickListener.onItemClick(holder.choice_layout, position);
+                }
+            }
+        });
+//        if (flag) {
+//            holder.choice_name.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
+//        } else {
+        holder.choice_name.setGravity(Gravity.CENTER);
+//        }
+    }
+
+    @Override
+    public int getItemCount() {
+        return items.size();
+    }
+
+    public void setRedText(int i, boolean isRed) {
+        this.isRed = true;
+        this.redPosition = i;
+        notifyDataSetChanged();
+    }
+
+    public void setFlag(Boolean flag) {
+        this.flag = flag;
+        notifyDataSetChanged();
+    }
+
+
+    static class BuildViewHolder extends BaseViewHolder {
+        TextView choice_name;
+        LinearLayout choice_layout;
+
+        public BuildViewHolder(View mRootView) {
+            super(mRootView);
+            choice_name = (TextView) mRootView.findViewById(R.id.choice_name);
+            choice_layout = (LinearLayout) mRootView.findViewById(R.id.choice_layout);
+
+        }
+    }
+
+    private OnRecyclerViewItemClickListener mOnItemClickListener = null;
+
+    public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {
+        this.mOnItemClickListener = listener;
+    }
+
+    public interface OnRecyclerViewItemClickListener {
+        void onItemClick(View view, int position);
+    }
+}

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

@@ -73,21 +73,21 @@ class PipeExpandAdapter(
         val group: PipeConfigEntityPackClass = mGroups[groupPosition]
         val tvGroup = holder?.findViewById(R.id.title) as TextView
         //1:正向from->to;-1:反向to->from;0:无方向
-        var sb = StringBuilder()
-        sb.append(group.fromName)
-        if (group.entity.pipeDirection == 1) {
-            sb.append("  —>  ")
-        } else if (group.entity.pipeDirection == -1) {
-            sb.append("  <—  ")
-        } else if (group.entity.pipeDirection == 0) {
-            sb.append("  ——  ")
-        }
-        sb.append(group.toName)
+//        var sb = StringBuilder()
+//        sb.append(group.fromName)
+//        if (group.entity.pipeDirection == 1) {
+//            sb.append("  —>  ")
+//        } else if (group.entity.pipeDirection == -1) {
+//            sb.append("  <—  ")
+//        } else if (group.entity.pipeDirection == 0) {
+//            sb.append("  ——  ")
+//        }
+//        sb.append(group.toName)
         tvGroup.text =
-            group.entity.pipeSubType + "--" + group.entity.pipeType + "\n" + sb.toString()
+            group.entity.pipeSubType + "--" + group.entity.pipeType
         val add = holder?.findViewById(R.id.add) as ImageView
         add.setOnClickListener {
-            addRel?.onAdd(group.entity)
+            addRel?.onAdd(group)
         }
         return holder
     }
@@ -124,7 +124,7 @@ class PipeExpandAdapter(
     }
 
     public interface AddRel {
-        fun onAdd(group: PipeConfigEntity)
+        fun onAdd(group: PipeConfigEntityPackClass)
     }
 
     fun setOnAdd(addRel: AddRel) {

+ 9 - 8
demo/src/main/java/com/sybotan/android/demo/adapter/RelationExpandAdapter.kt

@@ -11,6 +11,7 @@ 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.bean.RelConfigEntityPackClass
+import com.sybotan.android.demo.bean.RelationPackClass
 import com.yuyh.library.imgsel.utils.LogUtils
 import java.lang.StringBuilder
 
@@ -18,13 +19,13 @@ import java.lang.StringBuilder
 class RelationExpandAdapter(
     context: Context,
     groups: List<RelConfigEntityPackClass>,
-    items: MutableList<List<RelationEntity>>
+    items: MutableList<List<RelationPackClass>>
 ) : BaseExpandableListAdapter() {
     private var addRel: AddRel? = null
     private var deleteRel: DeleteRel? = null
     private var mContext: Context = context
     private var mGroups: List<RelConfigEntityPackClass> = groups
-    private var mItems: List<List<RelationEntity>> = items
+    private var mItems: List<List<RelationPackClass>> = items
     private var mLayoutInflater: LayoutInflater = LayoutInflater.from(context)
 
     override fun getGroupCount(): Int {
@@ -39,7 +40,7 @@ class RelationExpandAdapter(
         return mGroups[groupPosition]
     }
 
-    override fun getChild(groupPosition: Int, childPosition: Int): RelationEntity {
+    override fun getChild(groupPosition: Int, childPosition: Int): RelationPackClass {
         return mItems[groupPosition][childPosition]
     }
 
@@ -72,7 +73,7 @@ class RelationExpandAdapter(
         val group: RelConfigEntityPackClass = mGroups[groupPosition]
         val tvGroup = holder?.findViewById(R.id.title) as TextView
         tvGroup.text =
-            group.entity.graphName + "/" + group.entity.relName + "\n" + group.fromName + "  ->  " + group.toName
+            group.entity.graphName + "/" + group.entity.relName
         val add = holder?.findViewById(R.id.add) as ImageView
         add.setOnClickListener {
             addRel?.onAdd(group)
@@ -94,12 +95,12 @@ class RelationExpandAdapter(
         val itemTv = holder?.findViewById(R.id.title) as TextView
         val item = mItems[groupPosition][childPosition]
         var sb = StringBuilder()
-        sb.append(item.objFromLocalId)
+        sb.append(item.entity.objFromLocalId)
         sb.append("  —>  ")
-        sb.append(item.objToLocalId)
+        sb.append(item.entity.objToLocalId)
         itemTv.text = sb.toString()
-        holder?.findViewById<ImageView>(R.id.delete).setOnClickListener {
-            deleteRel?.ondelete(item)
+        holder.findViewById<ImageView>(R.id.delete).setOnClickListener {
+            deleteRel?.ondelete(item.entity)
         }
         return holder
     }

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

@@ -62,9 +62,9 @@ public class SelectPopListAdapter extends RecyclerView.Adapter<SelectPopListAdap
         if (type.equals(Constant.TYPE2)) {
             ObjectEntity options = (ObjectEntity) item;
             if (TextUtils.isEmpty(options.getLocalId())) {
-                holder.choice_name.setText(options.getLocalName());
+                holder.choice_name.setText(options.getClassCode() + ":" + options.getLocalName());
             } else {
-                holder.choice_name.setText(options.getLocalId());
+                holder.choice_name.setText(options.getClassCode() + ":" + options.getLocalId());
             }
         }
         if (selectPosition > 0 && selectPosition - 1 == position) {

+ 18 - 2
demo/src/main/java/com/sybotan/android/demo/bean/PipeConfigEntityPackClass.java

@@ -3,12 +3,28 @@ package com.sybotan.android.demo.bean;
 import com.framework.mvvm.model.db.entity.PipeConfigEntity;
 import com.framework.mvvm.model.db.entity.RelConfigEntity;
 
+import java.util.ArrayList;
+import java.util.Objects;
+
 /**
  * Created by lihao.
  * Date: 2021/10/18
  */
 public class PipeConfigEntityPackClass {
     public PipeConfigEntity entity;
-    public String fromName;
-    public String toName;
+    public ArrayList<TargetPipeType> targetTypes = new ArrayList<>();
+
+    public boolean samePipeConfig(PipeConfigEntity cfg) {
+        return Objects.equals(entity.getPipeType(), cfg.getPipeType()) && Objects.equals(entity.getPipeSubType(), cfg.getPipeSubType());
+    }
+
+    public static class TargetPipeType {
+        public boolean canFrom;
+        public boolean canTo;
+        public boolean canConnect;
+        public String srcCode;
+        public String pipeType;
+        public String pipeSubType;
+        public String targetCode;
+    }
 }

+ 18 - 0
demo/src/main/java/com/sybotan/android/demo/bean/RelConfigEntityPackClass.java

@@ -2,6 +2,9 @@ package com.sybotan.android.demo.bean;
 
 import com.framework.mvvm.model.db.entity.RelConfigEntity;
 
+import java.util.ArrayList;
+import java.util.Objects;
+
 /**
  * Created by lihao.
  * Date: 2021/10/18
@@ -10,4 +13,19 @@ public class RelConfigEntityPackClass {
     public RelConfigEntity entity;
     public String fromName;
     public String toName;
+    public ArrayList<TargetRelType> targetTypes = new ArrayList<>();
+
+    public boolean sameRelConfig(RelConfigEntity cfg) {
+        return Objects.equals(entity.getGraphCode(), cfg.getGraphCode()) && Objects.equals(entity.getRelCode(), cfg.getRelCode());
+    }
+
+    public static class TargetRelType {
+        public boolean canFrom;
+        public boolean canTo;
+        public boolean connect;
+        public String srcCode;
+        public String graphCode;
+        public String relCode;
+        public String targetCode;
+    }
 }

+ 12 - 0
demo/src/main/java/com/sybotan/android/demo/bean/RelationPackClass.java

@@ -0,0 +1,12 @@
+package com.sybotan.android.demo.bean;
+
+import com.framework.mvvm.model.db.entity.RelationEntity;
+
+/**
+ * Created by lihao.
+ * Date: 2021/10/21
+ */
+public class RelationPackClass {
+    public RelationEntity entity;
+    public RelConfigEntityPackClass.TargetRelType targetPipeType;
+}

+ 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 = 10;
+    private int et_max = 50;
     private ImageView mIvMust;
 
     public ListItemView(Context context) {

+ 27 - 11
demo/src/main/java/com/sybotan/android/demo/view/ObjectRelationDialog.java

@@ -16,6 +16,8 @@ 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 com.sybotan.android.demo.bean.RelConfigEntityPackClass;
+import com.sybotan.android.demo.tools.ToastUtils;
 
 import java.util.Objects;
 
@@ -27,35 +29,45 @@ import java.util.Objects;
 public class ObjectRelationDialog extends Dialog implements View.OnClickListener {
 
     private TextView relationTv;
+    private TextView toleft;
+    private TextView toright;
     private Submit submit;
 
-    public ObjectRelationDialog(@NonNull Context context, String localId, ObjectEntity equip, RelConfigEntity configEntity) {
+    public ObjectRelationDialog(@NonNull Context context, String localId, ObjectEntity equip, RelConfigEntityPackClass configEntity) {
         super(context, R.style.style_dialog);
         setDisplay(context);
         init(localId, equip, configEntity);
     }
 
-    private void init(String localId, ObjectEntity equip, RelConfigEntity configEntity) {
+    private void init(String localId, ObjectEntity equip, RelConfigEntityPackClass 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);
+        toleft = findViewById(R.id.toleft);
+        toright = findViewById(R.id.toright);
         findViewById(R.id.connect).setOnClickListener(this);
         findViewById(R.id.btnSubmit).setOnClickListener(this);
 
-        relationTitle.setText(configEntity.getGraphName() + "/" + configEntity.getRelName());
+        relationTitle.setText(configEntity.entity.getGraphName() + "/" + configEntity.entity.getRelName());
         leftName.setText(localId);
         if (TextUtils.isEmpty(equip.getLocalId())) {
             rightName.setText(equip.getLocalName());
         } else {
             rightName.setText(equip.getLocalId());
         }
-        if (Objects.equals(configEntity.getClassCodeFrom(), equip.getClassCode())) {
-            relationTv.setText("<-");
-        } else {
-            relationTv.setText("->");
+        for (RelConfigEntityPackClass.TargetRelType type : configEntity.targetTypes) {
+            if (type.targetCode.equals(equip.getClassCode())) {
+                if (type.canFrom) {
+                    toleft.setVisibility(View.VISIBLE);
+                }
+                if (type.canTo) {
+                    toright.setVisibility(View.VISIBLE);
+                }
+                break;
+            }
         }
     }
 
@@ -87,17 +99,21 @@ public class ObjectRelationDialog extends Dialog implements View.OnClickListener
     public void onClick(View v) {
         switch (v.getId()) {
             case R.id.toleft:
-                relationTv.setText("->");
+                relationTv.setText("<-");
                 break;
             case R.id.toright:
-                relationTv.setText("<-");
+                relationTv.setText("->");
                 break;
             case R.id.connect:
                 relationTv.setText("--");
                 break;
             case R.id.btnSubmit:
+                if (TextUtils.isEmpty(relationTv.getText().toString().trim())) {
+                    ToastUtils.showMyToast("请选择方向");
+                    return;
+                }
                 if (submit != null) {
-                    submit.onSubmit();
+                    submit.onSubmit(relationTv.getText().toString().equals("->"));
                 }
                 dismiss();
                 break;
@@ -107,7 +123,7 @@ public class ObjectRelationDialog extends Dialog implements View.OnClickListener
     }
 
     public interface Submit {
-        void onSubmit();
+        void onSubmit(boolean equals);
     }
 
     public void setOnSubmit(Submit submit) {

+ 34 - 14
demo/src/main/java/com/sybotan/android/demo/view/PipeDialog.java

@@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
 import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.text.TextUtils;
 import android.view.Gravity;
 import android.view.View;
 import android.view.Window;
@@ -16,6 +17,8 @@ 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 com.sybotan.android.demo.bean.PipeConfigEntityPackClass;
+import com.sybotan.android.demo.tools.ToastUtils;
 
 import java.util.Objects;
 
@@ -28,14 +31,17 @@ public class PipeDialog extends Dialog implements View.OnClickListener {
 
     private TextView relationTv;
     private Submit submit;
+    private TextView toleft;
+    private TextView toright;
+    private TextView connect;
 
-    public PipeDialog(@NonNull Context context, String localId, ObjectEntity equip, PipeConfigEntity configEntity) {
+    public PipeDialog(@NonNull Context context, String localId, ObjectEntity equip, PipeConfigEntityPackClass configEntity) {
         super(context, R.style.style_dialog);
         setDisplay(context);
         init(localId, equip, configEntity);
     }
 
-    private void init(String localId, ObjectEntity equip, PipeConfigEntity configEntity) {
+    private void init(String localId, ObjectEntity equip, PipeConfigEntityPackClass configEntity) {
         relationTv = findViewById(R.id.relationTv);
         TextView leftName = findViewById(R.id.leftName);
         TextView rightName = findViewById(R.id.rightName);
@@ -44,22 +50,32 @@ public class PipeDialog extends Dialog implements View.OnClickListener {
         findViewById(R.id.toright).setOnClickListener(this);
         findViewById(R.id.connect).setOnClickListener(this);
         findViewById(R.id.btnSubmit).setOnClickListener(this);
+        toleft = findViewById(R.id.toleft);
+        toright = findViewById(R.id.toright);
+        connect = findViewById(R.id.connect);
 
-        relationTitle.setText(configEntity.getPipeType());
+        relationTitle.setText(configEntity.entity.getPipeType());
 
-        if (Objects.equals(configEntity.getClassCodeFrom(), equip.getClassCode())) {
+        if (Objects.equals(configEntity.entity.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("--");
+        for (PipeConfigEntityPackClass.TargetPipeType type : configEntity.targetTypes) {
+            if (type.targetCode.equals(equip.getClassCode())) {
+                if (type.canFrom) {
+                    toleft.setVisibility(View.VISIBLE);
+                }
+                if (type.canTo) {
+                    toright.setVisibility(View.VISIBLE);
+                }
+                if (type.canConnect) {
+                    connect.setVisibility(View.VISIBLE);
+                }
+                break;
+            }
         }
     }
 
@@ -91,17 +107,21 @@ public class PipeDialog extends Dialog implements View.OnClickListener {
     public void onClick(View v) {
         switch (v.getId()) {
             case R.id.toleft:
-                relationTv.setText("->");
+                relationTv.setText("<-");
                 break;
             case R.id.toright:
-                relationTv.setText("<-");
+                relationTv.setText("->");
                 break;
             case R.id.connect:
                 relationTv.setText("--");
                 break;
             case R.id.btnSubmit:
+                if (TextUtils.isEmpty(relationTv.getText().toString().trim())){
+                    ToastUtils.showMyToast("请选择方向");
+                    return;
+                }
                 if (submit != null) {
-                    submit.onSubmit();
+                    submit.onSubmit(relationTv.getText().toString());
                 }
                 dismiss();
                 break;
@@ -111,7 +131,7 @@ public class PipeDialog extends Dialog implements View.OnClickListener {
     }
 
     public interface Submit {
-        void onSubmit();
+        void onSubmit(String s);
     }
 
     public void setOnSubmit(Submit submit) {

+ 216 - 0
demo/src/main/java/com/sybotan/android/demo/view/SelectListSinglePopupWindow.java

@@ -0,0 +1,216 @@
+package com.sybotan.android.demo.view;
+
+/**
+ * Created by cunwen on 16/3/25.
+ */
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.drawable.ColorDrawable;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnTouchListener;
+import android.view.ViewGroup.LayoutParams;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.Button;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+
+import com.sybotan.android.demo.R;
+import com.sybotan.android.demo.activities.BaseActivity;
+import com.sybotan.android.demo.adapter.PersonalSelectSingleAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class SelectListSinglePopupWindow extends PopupWindow {
+    DisplayMetrics dm;
+
+    private TextView title;
+    private Button btn1, btn_cancel;
+    private RecyclerView recyclerview;
+    private View mMenuView;
+
+
+    private Context context;
+    private static final long DISMISSDELAYED = 2000;
+
+    private Animation inAnim;
+    private Animation outAnim;
+
+    PersonalSelectSingleAdapter adapter;
+    public ArrayList<String> list = new ArrayList<String>();
+    public int position = -1;
+
+    public SelectListSinglePopupWindow(Context context) {
+        super(context);
+        this.context = context;
+
+        dm = new DisplayMetrics();
+        ((BaseActivity)context).getWindowManager().getDefaultDisplay().getMetrics(dm);
+
+        LayoutInflater inflater = (LayoutInflater) context
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        mMenuView = inflater.inflate(R.layout.dialog_list_choice, null);
+        title = (TextView) mMenuView.findViewById(R.id.title);
+        btn1 = (Button) mMenuView.findViewById(R.id.btn1);
+        btn1.setVisibility(View.GONE);
+        btn_cancel = (Button) mMenuView.findViewById(R.id.btn_cancel);
+        //取消按钮
+        btn_cancel.setOnClickListener(new OnClickListener() {
+
+            public void onClick(View v) {
+                //销毁弹出框
+                dismiss();
+                mMenuView.startAnimation(outAnim);
+            }
+        });
+        //设置按钮监听
+//        btn1.setOnClickListener(itemsOnClick);
+        btn1.setTag(0);
+
+        recyclerview = (RecyclerView) mMenuView.findViewById(R.id.recyclerview);
+
+        recyclerview.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
+        recyclerview.setFocusable(false);
+        recyclerview.setVerticalScrollBarEnabled(true);
+        recyclerview.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
+        adapter = new PersonalSelectSingleAdapter();
+        adapter.setOnItemClickListener(new PersonalSelectSingleAdapter.OnRecyclerViewItemClickListener() {
+            @Override
+            public void onItemClick(View view, int position) {
+                if (mOnItemClickListener != null) {
+                    mOnItemClickListener.onItemClick(position);
+                }
+                dismiss();
+            }
+        });
+        recyclerview.setAdapter(adapter);
+
+
+        //设置SelectPicPopupWindow的View
+        this.setContentView(mMenuView);
+        //设置SelectPicPopupWindow弹出窗体的宽
+        this.setWidth(LayoutParams.MATCH_PARENT);
+        //设置SelectPicPopupWindow弹出窗体的高
+        this.setHeight(LayoutParams.WRAP_CONTENT);
+        //设置SelectPicPopupWindow弹出窗体可点击
+        this.setFocusable(true);
+        //设置SelectPicPopupWindow弹出窗体动画效果
+//        this.setAnimationStyle(R.style.AnimBottom);
+        //实例化一个ColorDrawable颜色为半透明
+//        ColorDrawable dw = new ColorDrawable(0xb0000000);
+        //设置SelectPicPopupWindow弹出窗体的背景
+
+        //mMenuView添加OnTouchListener监听判断获取触屏位置如果在选择框外面则销毁弹出框
+        mMenuView.setOnTouchListener(new OnTouchListener() {
+
+            public boolean onTouch(View v, MotionEvent event) {
+
+                int height = mMenuView.findViewById(R.id.pop_layout).getTop();
+                int y = (int) event.getY();
+                if (event.getAction() == MotionEvent.ACTION_UP) {
+                    if (y < height) {
+                        dismiss();
+                    }
+                }
+                return true;
+            }
+        });
+
+
+
+    }
+
+    public void setBtn(Boolean flag, String textBtn1) {
+        if (flag) {
+            btn1.setVisibility(View.VISIBLE);
+            btn1.setText(textBtn1);
+        } else {
+            btn1.setVisibility(View.GONE);
+        }
+    }
+
+    public void setBtnbottom(Boolean flag, String textBtn1) {
+        if (flag) {
+            btn_cancel.setVisibility(View.VISIBLE);
+            btn_cancel.setText(textBtn1);
+        } else {
+            btn_cancel.setVisibility(View.GONE);
+        }
+    }
+
+    public void setTitle(Boolean flag, String text) {
+        adapter.setFlag(flag);
+        if (flag) {
+            title.setVisibility(View.VISIBLE);
+            title.setText(text);
+            btn1.setGravity(Gravity.START);
+        } else {
+            title.setVisibility(View.GONE);
+            btn1.setGravity(Gravity.CENTER);
+        }
+    }
+
+    public void setList(List<?> list, String type) {
+        adapter.setItems(list, context, position, type);
+        LayoutParams mParams1 = recyclerview.getLayoutParams();
+        mParams1.height = (int) (55 * (list.size() >= 6 ? 6 : list.size()) * dm.density);
+        recyclerview.setLayoutParams(mParams1);
+        recyclerview.setVerticalScrollBarEnabled(true);
+        recyclerview.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
+        adapter.notifyDataSetChanged();
+    }
+
+
+    private int gravity = Gravity.BOTTOM;
+
+
+    Animation.AnimationListener outAnimListener = new Animation.AnimationListener() {
+        @Override
+        public void onAnimationStart(Animation animation) {
+
+        }
+
+        @Override
+        public void onAnimationEnd(Animation animation) {
+            dismissImmediately();
+        }
+
+        @Override
+        public void onAnimationRepeat(Animation animation) {
+
+        }
+    };
+
+    public void dismissImmediately() {
+        dismiss();
+        context = null;
+    }
+
+
+    private SelectListPopupWindow.OnRecyclerViewItemClickListener mOnItemClickListener = null;
+
+    public void setOnItemClickListener(SelectListPopupWindow.OnRecyclerViewItemClickListener listener) {
+        this.mOnItemClickListener = listener;
+    }
+
+    public void setRedText(int i) {
+        adapter.setRedText(i, true);
+    }
+
+    public interface OnRecyclerViewItemClickListener {
+        void onItemClick(int position);
+    }
+
+}

+ 213 - 291
demo/src/main/java/com/sybotan/android/demo/viewmodel/GraphyVM.kt

@@ -35,9 +35,7 @@ import java.text.SimpleDateFormat
 import java.util.*
 import kotlin.collections.ArrayList
 import kotlin.collections.HashMap
-import com.alibaba.fastjson.JSON
 import com.sybotan.android.demo.bean.*
-import io.reactivex.Observable
 
 
 /**
@@ -831,325 +829,241 @@ class GraphyVM(
             val equipId = if (TextUtils.isEmpty(deviceId)) uuid else deviceId
             //获取关系二级列表
             val configParent = ArrayList<RelConfigEntityPackClass>()
-            val relList = mutableListOf<List<RelationEntity>>()
+            val relList = mutableListOf<List<RelationPackClass>>()
             val fromList = repo.getRelConfigByCodeFrom(entity.code!!)
             val toList = repo.getRelConfigByCodeTo(entity.code!!)
-            for (config in fromList) {
-                val relsFrom = repo.getRelByCodeFrom(config.graphCode!!, config.relCode!!, equipId)
-                if (!CommonUtils.IsNull(relsFrom)) {
-                    var relRealFrom = ArrayList<RelationEntity>()
-                    relRealFrom.addAll(relsFrom)
-                    val iterator = relRealFrom.iterator()
-                    while (iterator.hasNext()) {
-                        val rel = iterator.next()
-                        val objFrom = repo.getObject(rel.objFrom!!)
-                        val objTo = repo.getObject(rel.objTo!!)
-                        if (objFrom == null) {
-                            rel.objFromLocalId = "该设备"
-                            if (!entity.code.equals(config.classCodeFrom)) {
-//                                relRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        } else {
-                            if (TextUtils.isEmpty(objFrom.localId)) {
-                                rel.objFromLocalId = objFrom.localName
-                            } else {
-                                rel.objFromLocalId = objFrom.localId
-                            }
-                            if (!objFrom.classCode.equals(config.classCodeFrom)) {
-//                                relRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        }
-                        if (objTo == null) {
-                            rel.objToLocalId = "该设备"
-                            if (!entity.code.equals(config.classCodeTo)) {
-//                                relRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        } else {
-                            if (TextUtils.isEmpty(objTo.localId)) {
-                                rel.objToLocalId = objTo.localName
-                            } else {
-                                rel.objToLocalId = objTo.localId
-                            }
-                            if (!objTo.classCode.equals(config.classCodeTo)) {
-//                                relRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        }
+            loadCfgs(entity.code, fromList, true, configParent)
+            loadCfgs(entity.code, toList, true, configParent)
+            for (parent in configParent) {
+                var rel = ArrayList<RelationPackClass>()
+                for (child in parent.targetTypes) {
+                    if (child.canFrom) {
+                        val to = repo.getRelByCodeTo(
+                            parent.entity.graphCode!!,
+                            parent.entity.relCode!!,
+                            equipId
+                        )
+                        loadRelation(to, child, parent, rel)
                     }
-                    for (rel in relRealFrom) {
 
+                    if (child.canTo) {
+                        val from = repo.getRelByCodeFrom(
+                            parent.entity.graphCode!!,
+                            parent.entity.relCode!!,
+                            equipId
+                        )
+                        loadRelation(from, child, parent, rel)
                     }
-                    relList.add(relRealFrom)
-                } else {
-                    relList.add(ArrayList<RelationEntity>())
                 }
-                val pack = RelConfigEntityPackClass()
-                pack.entity = config
-                if (config.objTypeFrom.equals("equipment")) {
-                    val equipmentFrom = repo.getEquipByCode(config.classCodeFrom!!)
-                    pack.fromName = equipmentFrom?.name
-                } else {
-                    val equipmentFrom = repo.getSysByCode(config.classCodeFrom!!)
-                    pack.fromName = equipmentFrom?.name
+                relList.add(rel)
+            }
+            val hashMap = HashMap<String, Any>()
+            hashMap.put("parent", configParent)
+            hashMap.put("child", relList)
+            mEmitter.SendDircetive(EQUIP_REL, hashMap)
 
+            //获取管道二级列表
+            val pipeParent = ArrayList<PipeConfigEntityPackClass>()
+            val pipeChildren = mutableListOf<List<PipeEntity>>()
+            val pipeFromList = repo.getPipeConfigByCodeFrom(entity.code)
+            val pipeToList = repo.getPipeConfigByCodeTo(entity.code)
+            loadPipeCfgs(entity.code, pipeFromList, true, pipeParent)
+            loadPipeCfgs(entity.code, pipeToList, true, pipeParent)
+            val floorPipes = repo.getPipeByFloorId(floorId)
+            for (parent in pipeParent) {
+                var pipes = ArrayList<PipeEntity>()
+                for (floorPipe in floorPipes) {
+                    if ((floorPipe.objFrom.equals(deviceId) || floorPipe.objTo.equals(deviceId)) && floorPipe.pipeType.equals(
+                            parent.entity.pipeType
+                        ) && floorPipe.pipeSubType.equals(parent.entity.pipeSubType)
+                    ) {
+                        bindPipeName(floorPipe)
+                        pipes.add(floorPipe)
+                    }
                 }
-                if (config.objTypeTo.equals("equipment")) {
-                    val equipmentTo = repo.getEquipByCode(config.classCodeTo!!)
-                    pack.toName = equipmentTo?.name
-                } else {
-                    val equipmentTo = repo.getSysByCode(config.classCodeTo!!)
-                    pack.toName = equipmentTo?.name
-                }
-                configParent.add(pack)
+                pipeChildren.add(pipes)
             }
+            val hashMap1 = HashMap<String, Any>()
+            hashMap1.put("parent", pipeParent)
+            hashMap1.put("child", pipeChildren)
+            mEmitter.SendDircetive(PIPE, hashMap1)
 
+        }
+    }
 
-            for (config in toList) {
-                val relsTo = repo.getRelByCodeTo(config.graphCode!!, config.relCode!!, equipId)
-                if (!CommonUtils.IsNull(relsTo)) {
-                    var relRealTo = ArrayList<RelationEntity>()
-                    relRealTo.addAll(relsTo)
-                    val iterator = relRealTo.iterator()
-                    while (iterator.hasNext()) {
-                        val rel = iterator.next()
-                        val objFrom = repo.getObject(rel.objFrom!!)
-                        val objTo = repo.getObject(rel.objTo!!)
-                        if (objFrom == null) {
-                            rel.objFromLocalId = "该设备"
-                            if (!entity.code.equals(config.classCodeFrom)) {
-//                                relRealTo.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        } else {
-                            if (TextUtils.isEmpty(objFrom.localId)) {
-                                rel.objFromLocalId = objFrom.localName
-                            } else {
-                                rel.objFromLocalId = objFrom.localId
-                            }
-                            if (!objFrom.classCode.equals(config.classCodeFrom)) {
-//                                relRealTo.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        }
-                        if (objTo == null) {
-                            rel.objToLocalId = "该设备"
-                            if (!entity.code.equals(config.classCodeTo)) {
-//                                relRealTo.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        } else {
-                            if (TextUtils.isEmpty(objTo.localId)) {
-                                rel.objToLocalId = objTo.localName
-                            } else {
-                                rel.objToLocalId = objTo.localId
-                            }
-                            if (!objTo.classCode.equals(config.classCodeTo)) {
-//                                relRealTo.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        }
-                    }
+    private suspend fun bindPipeName(floorPipe: PipeEntity) {
+        val from = repo.getObject(floorPipe.objFrom!!)
+        floorPipe.objFromLocalId =
+            if (from!!.id.startsWith("Eq")) from!!.localId else from!!.localName
+        val to = repo.getObject(floorPipe.objTo!!)
+        floorPipe.objToLocalId =
+            if (to!!.id.startsWith("Eq")) to!!.localId else to!!.localName
+    }
 
-                    relList.add(relRealTo)
-                } else {
-                    relList.add(ArrayList<RelationEntity>())
+    private fun loadPipeCfgs(
+        srcCode: String,
+        cfgs: List<PipeConfigEntity>,
+        targetAsTo: Boolean,
+        groups: ArrayList<PipeConfigEntityPackClass>
+    ) {
+        for (cfg in cfgs) {
+            var group: PipeConfigEntityPackClass? = null
+            for (g in groups) {
+                if (g.samePipeConfig(cfg)) {
+                    group = g
+                    break
                 }
-                val pack = RelConfigEntityPackClass()
-                pack.entity = config
-                if (config.objTypeFrom.equals("equipment")) {
-                    val equipmentFrom = repo.getEquipByCode(config.classCodeFrom!!)
-                    pack.fromName = equipmentFrom?.name
-                } else {
-                    val equipmentFrom = repo.getSysByCode(config.classCodeFrom!!)
-                    pack.fromName = equipmentFrom?.name
+            }
+            if (group == null) {
+                group = PipeConfigEntityPackClass()
+                group.entity = cfg
+                groups.add(group)
+            }
+            val cfgTarget = if (targetAsTo) cfg.classCodeTo else cfg.classCodeFrom
 
+            var targetType: PipeConfigEntityPackClass.TargetPipeType? = null
+            for (t in group.targetTypes) {
+                if (t.targetCode.equals(cfgTarget)) {
+                    targetType = t
+                    break
                 }
-                if (config.objTypeTo.equals("equipment")) {
-                    val equipmentTo = repo.getEquipByCode(config.classCodeTo!!)
-                    pack.toName = equipmentTo?.name
+            }
+            if (targetType == null) {
+                targetType = PipeConfigEntityPackClass.TargetPipeType()
+                targetType.srcCode = srcCode
+                targetType.pipeType = group.entity.pipeType
+                targetType.pipeSubType = group.entity.pipeSubType
+                targetType.targetCode = cfgTarget
+                group.targetTypes.add(targetType)
+            }
+            if (cfg.pipeDirection == 1) {
+                if (targetAsTo) {
+                    targetType.canTo = true
                 } else {
-                    val equipmentTo = repo.getSysByCode(config.classCodeTo!!)
-                    pack.toName = equipmentTo?.name
+                    targetType.canFrom = true
                 }
-                configParent.add(pack)
-
-            }
-            val hashMap = HashMap<String, Any>()
-            hashMap.put("parent", configParent)
-            hashMap.put("child", relList)
-            mEmitter.SendDircetive(EQUIP_REL, hashMap)
-
-            //获取管道二级列表
-            val pipeParent = ArrayList<PipeConfigEntityPackClass>()
-            val pipeChildren = mutableListOf<List<PipeEntity>>()
-            val pipeFromList = repo.getPipeConfigByCodeFrom(entity.code!!)
-            val pipeToList = repo.getPipeConfigByCodeTo(entity.code!!)
-
-
-            for (config in pipeFromList) {
-                val pipeFrom =
-                    repo.getPipeByIdFrom(equipId, config.pipeType!!, config.pipeSubType!!)
-                if (!CommonUtils.IsNull(pipeFrom)) {
-                    var pipeRealFrom = ArrayList<PipeEntity>()
-                    pipeRealFrom.addAll(pipeFrom)
-                    val iterator = pipeRealFrom.iterator()
-                    while (iterator.hasNext()) {
-                        val rel = iterator.next()
-                        val objFrom = repo.getObject(rel.objFrom!!)
-                        val objTo = repo.getObject(rel.objTo!!)
-                        if (objFrom == null) {
-                            rel.objFromLocalId = "该设备"
-                            if (!entity.code.equals(config.classCodeFrom)) {
-//                                pipeRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        } else {
-                            if (TextUtils.isEmpty(objFrom.localId)) {
-                                rel.objFromLocalId = objFrom.localName
-                            } else {
-                                rel.objFromLocalId = objFrom.localId
-                            }
-                            if (!objFrom.classCode.equals(config.classCodeFrom)) {
-//                                pipeRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        }
-                        if (objTo == null) {
-                            rel.objToLocalId = "该设备"
-                            if (!entity.code.equals(config.classCodeTo)) {
-//                                pipeRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        } else {
-                            if (TextUtils.isEmpty(objTo.localId)) {
-                                rel.objToLocalId = objTo.localName
-                            } else {
-                                rel.objToLocalId = objTo.localId
-                            }
-                            if (!objTo.classCode.equals(config.classCodeTo)) {
-//                                pipeRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        }
-                    }
-                    pipeChildren.add(pipeRealFrom)
+            } else if (cfg.pipeDirection == -1) {
+                if (targetAsTo) {
+                    targetType.canFrom = true
                 } else {
-                    pipeChildren.add(ArrayList<PipeEntity>())
+                    targetType.canTo = true
                 }
-                val pack = PipeConfigEntityPackClass()
-                pack.entity = config
-                val equipmentFrom = repo.getEquipByCode(config.classCodeFrom!!)
-                pack.fromName = equipmentFrom?.name
-                val equipmentTo = repo.getEquipByCode(config.classCodeTo!!)
-                pack.toName = equipmentTo?.name
-                pipeParent.add(pack)
+            } else if (cfg.pipeDirection == 0) {
+                targetType.canConnect = true
             }
+        }
+    }
 
+    private suspend fun loadRelation(
+        to: List<RelationEntity>,
+        child: RelConfigEntityPackClass.TargetRelType,
+        parent: RelConfigEntityPackClass,
+        rel: ArrayList<RelationPackClass>
+    ) {
+        bindRelationEntityName(to)
+        if (!CommonUtils.IsNull(to)) {
+            for (t in to) {
+                if (child.targetCode.equals(parent.entity.classCodeTo)) {
+                    val pack = RelationPackClass()
+                    pack.entity = t
+                    pack.targetPipeType = child
+                    rel.add(pack)
+                }
+            }
+        }
+    }
 
-            for (config in pipeToList) {
-                val pipeFrom = repo.getPipeByIdTo(equipId, config.pipeType!!, config.pipeSubType!!)
-                if (!CommonUtils.IsNull(pipeFrom)) {
-                    var pipeRealFrom = ArrayList<PipeEntity>()
-                    pipeRealFrom.addAll(pipeFrom)
-                    val iterator = pipeRealFrom.iterator()
-                    while (iterator.hasNext()) {
-                        val rel = iterator.next()
-                        val objFrom = repo.getObject(rel.objFrom!!)
-                        val objTo = repo.getObject(rel.objTo!!)
-                        if (objFrom == null) {
-                            rel.objFromLocalId = "该设备"
-                            if (!entity.code.equals(config.classCodeFrom)) {
-//                                pipeRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        } else {
-                            if (TextUtils.isEmpty(objFrom.localId)) {
-                                rel.objFromLocalId = objFrom.localName
-                            } else {
-                                rel.objFromLocalId = objFrom.localId
-                            }
-                            if (!objFrom.classCode.equals(config.classCodeFrom)) {
-//                                pipeRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        }
-                        if (objTo == null) {
-                            rel.objToLocalId = "该设备"
-                            if (!entity.code.equals(config.classCodeTo)) {
-//                                pipeRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        } else {
-                            if (TextUtils.isEmpty(objTo.localId)) {
-                                rel.objToLocalId = objTo.localName
-                            } else {
-                                rel.objToLocalId = objTo.localId
-                            }
-                            if (!objTo.classCode.equals(config.classCodeTo)) {
-//                                pipeRealFrom.remove(rel)
-                                iterator.remove()
-                                continue
-                            }
-                        }
-                    }
+    private suspend fun bindRelationEntityName(
+        entitys: List<RelationEntity>
+    ) {
+        for (rel in entitys) {
+            val from = repo.getObject(rel.objFrom!!)
+            rel.objFromLocalId =
+                if (from!!.id.startsWith("Eq")) from!!.localId else from!!.localName
+            val to = repo.getObject(rel.objTo!!)
+            rel.objToLocalId =
+                if (to!!.id.startsWith("Eq")) to!!.localId else to!!.localName
+        }
+    }
 
-                    pipeChildren.add(pipeRealFrom)
-                } else {
-                    pipeChildren.add(ArrayList<PipeEntity>())
+    private fun loadCfgs(
+        srcCode: String,
+        cfgs: List<RelConfigEntity>,
+        targetAsTo: Boolean,
+        groups: ArrayList<RelConfigEntityPackClass>
+    ) {
+        for (cfg in cfgs) {
+            var group: RelConfigEntityPackClass? = null
+            for (g in groups) {
+                if (g.sameRelConfig(cfg)) {
+                    group = g
+                    break
                 }
-                val pack = PipeConfigEntityPackClass()
-                pack.entity = config
-                val equipmentFrom = repo.getEquipByCode(config.classCodeFrom!!)
-                pack.fromName = equipmentFrom?.name
-                val equipmentTo = repo.getEquipByCode(config.classCodeTo!!)
-                pack.toName = equipmentTo?.name
-                pipeParent.add(pack)
             }
-            val hashMap1 = HashMap<String, Any>()
-            hashMap1.put("parent", pipeParent)
-            hashMap1.put("child", pipeChildren)
-            mEmitter.SendDircetive(PIPE, hashMap1)
+            if (group == null) {
+                group = RelConfigEntityPackClass()
+                group.entity = cfg
+                groups.add(group)
+            }
+            val cfgTarget = if (targetAsTo) cfg.classCodeTo else cfg.classCodeFrom
+            var tartgetType: RelConfigEntityPackClass.TargetRelType? = null
+            for (t in group.targetTypes) {
+                if (t.targetCode.equals(cfgTarget)) {
+                    tartgetType = t
+                    break
+                }
+            }
+            if (tartgetType == null) {
+                tartgetType = RelConfigEntityPackClass.TargetRelType()
+                tartgetType.srcCode = srcCode
+                tartgetType.graphCode = group.entity.graphCode
+                tartgetType.relCode = group.entity.relCode
+                tartgetType.targetCode = cfgTarget
+                group.targetTypes.add(tartgetType)
+            }
+            if (targetAsTo) {
+                tartgetType.canTo = true
+            } else {
+                tartgetType.canFrom = true
+            }
+
+            if ("fixed".equals(cfg.direction)) {
+                if (targetAsTo)
+                    tartgetType.canTo = true
+                else
+                    tartgetType.canFrom = true
+            } else if ("optional".equals(cfg.direction)) {
+                tartgetType.canTo = true
+                tartgetType.canFrom = true
+            } else {
+                tartgetType.canFrom = true
+                // !targetCanBeTo && !targetCanBeFrom 表示无方向选择
+            }
 
         }
     }
 
-    fun getRelObj(group: RelConfigEntity, code: String) {
+    fun getRelObj(group: RelConfigEntityPackClass, code: String) {
         viewModelScope.launch {
-            val objects: List<ObjectEntity>
-            if (group.classCodeFrom.equals(code)) {
-                objects = repo.getObjectByCode(group.classCodeTo!!)
-            } else {
-                objects = repo.getObjectByCode(group.classCodeFrom!!)
+            val objects: ArrayList<ObjectEntity> = ArrayList()
+            for (type in group.targetTypes) {
+                val objs = repo.getObjectByCode(type.targetCode!!)
+                if (!CommonUtils.IsNull(objs)) {
+                    objects.addAll(objs)
+                }
             }
             mEmitter.SendDircetive(REL_OBJECT, objects)
         }
     }
 
-    fun getPipeObj(group: PipeConfigEntity, code: String) {
+    fun getPipeObj(group: PipeConfigEntityPackClass, code: String) {
         viewModelScope.launch {
-            val objects: List<ObjectEntity>
-            if (group.classCodeFrom.equals(code)) {
-                objects = repo.getObjectByCode(group.classCodeTo!!)
-            } else {
-                objects = repo.getObjectByCode(group.classCodeFrom!!)
+            val objects: ArrayList<ObjectEntity> = ArrayList()
+            for (type in group.targetTypes) {
+                val objs = repo.getObjectByCode(type.targetCode!!)
+                if (!CommonUtils.IsNull(objs)) {
+                    objects.addAll(objs)
+                }
             }
             mEmitter.SendDircetive(PIPE_OBJECT, objects)
         }
@@ -1158,7 +1072,8 @@ class GraphyVM(
     fun addRel(
         deviceId: String, uuid: String, equipEntity: EquipmentEntity,
         equip: ObjectEntity,
-        groupRelConfigEntity: RelConfigEntity
+        groupRelConfigEntity: RelConfigEntity,
+        eq: Boolean
     ) {
         viewModelScope.launch {
             var equipId: String
@@ -1169,7 +1084,7 @@ class GraphyVM(
             }
             val objFrom: String
             val objto: String
-            if (groupRelConfigEntity.classCodeFrom.equals(equipEntity!!.code)) {
+            if (eq) {
                 objFrom = equipId
                 objto = equip.id
             } else {
@@ -1209,7 +1124,8 @@ class GraphyVM(
     fun addPipe(
         deviceId: String, uuid: String, equipEntity: EquipmentEntity,
         equip: ObjectEntity,
-        groupPipeConfigEntity: PipeConfigEntity
+        groupPipeConfigEntity: PipeConfigEntity,
+        direction: String
     ) {
         viewModelScope.launch {
             var equipId: String
@@ -1227,16 +1143,22 @@ class GraphyVM(
                 objto = equipId
                 objFrom = equip.id
             }
+            var pipeDirection: Int
+            if (direction.equals("->")) {
+                pipeDirection = 1
+            } else if (direction.equals("<-")) {
+                pipeDirection = -1
+            } else {
+                pipeDirection = 0
+            }
 
             val relEntity = PipeEntity(
                 id = UUID.randomUUID().toString(),
                 projectId = projectId,
                 buildingId = buildingId,
                 floorId = floorId,
-
                 objFrom = objFrom,
                 objTo = objto,
-
                 creator = null,
                 creationTime = "",
                 modifiedTime = "",
@@ -1247,7 +1169,7 @@ class GraphyVM(
                 d2mState = null,
                 objFromLocalId = null,
                 objToLocalId = null,
-                direction = groupPipeConfigEntity.pipeDirection,
+                direction = pipeDirection,
                 typeFrom = "equipment",
                 typeTo = "equipment",
                 pipeType = groupPipeConfigEntity.pipeType,

+ 21 - 11
demo/src/main/res/layout/dialog_object_relation.xml

@@ -49,7 +49,7 @@
             android:paddingBottom="7dp"
             android:textColor="@color/gray_272727"
             android:textSize="16sp"
-            tools:text="->" />
+            tools:text="" />
 
         <TextView
             android:id="@+id/rightName"
@@ -62,22 +62,28 @@
     </androidx.appcompat.widget.LinearLayoutCompat>
 
     <TextView
-        android:visibility="gone"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="30dp"
         android:text="选择方向"
         android:textColor="@color/gray_272727"
-        android:textSize="16sp" />
+        android:textSize="16sp"
+        android:visibility="gone" />
 
     <androidx.appcompat.widget.LinearLayoutCompat
-        android:visibility="gone"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="19dp"
         android:orientation="horizontal">
 
         <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="可选择的方向:"
+            android:textColor="@color/black_272727"
+            android:textSize="16sp" />
+
+        <TextView
             android:id="@+id/toright"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -86,37 +92,41 @@
             android:paddingTop="7dp"
             android:paddingRight="20dp"
             android:paddingBottom="7dp"
+            android:text="@string/toright"
             android:textColor="@color/gray_272727"
             android:textSize="16sp"
-            tools:text="@string/toright" />
+            android:visibility="gone" />
 
         <TextView
-            android:id="@+id/toleft"
+            android:id="@+id/connect"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginLeft="50dp"
+            android:layout_marginLeft="20dp"
             android:background="@color/gray_f5f6f7"
             android:paddingLeft="20dp"
             android:paddingTop="7dp"
             android:paddingRight="20dp"
             android:paddingBottom="7dp"
+            android:text="--"
             android:textColor="@color/gray_272727"
             android:textSize="16sp"
-            tools:text="@string/toleft" />
+            android:visibility="gone" />
 
         <TextView
-            android:id="@+id/connect"
+            android:id="@+id/toleft"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginLeft="50dp"
+            android:layout_marginLeft="20dp"
             android:background="@color/gray_f5f6f7"
             android:paddingLeft="20dp"
             android:paddingTop="7dp"
             android:paddingRight="20dp"
             android:paddingBottom="7dp"
+            android:text="@string/toleft"
             android:textColor="@color/gray_272727"
             android:textSize="16sp"
-            tools:text="--" />
+            android:visibility="gone" />
+
     </androidx.appcompat.widget.LinearLayoutCompat>
 
     <TextView

+ 4 - 1
demo/src/main/res/layout/layout_common_list_item.xml

@@ -6,6 +6,7 @@
     android:background="@color/white_ffffff">
 
     <RelativeLayout
+        android:id="@+id/rl"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_centerVertical="true"
@@ -46,12 +47,14 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_centerVertical="true"
+        android:layout_marginLeft="10dp"
         android:layout_marginRight="4dp"
         android:layout_toLeftOf="@id/iv_right"
+        android:layout_toRightOf="@+id/rl"
         android:ellipsize="end"
         android:gravity="end"
         android:hint="请选择"
-        android:singleLine="true"
+        android:text=""
         android:textColor="@color/black_272727"
         android:textColorHint="@color/gray_4D272727"
         android:textSize="15sp"

+ 31 - 0
demo/src/main/res/layout/personal_select_text_single_item.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/choice_layout"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@color/white_ffffff"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="55dp"
+        android:layout_gravity="center"
+        android:background="@drawable/common_line_ffffff_single_16"
+        android:orientation="horizontal">
+
+        <TextView
+            android:id="@+id/choice_name"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginLeft="16dp"
+            android:layout_marginRight="16dp"
+            android:gravity="center_vertical"
+            android:singleLine="true"
+            android:text="维修"
+            android:textColor="@color/gray_272727"
+            android:textSize="16sp" />
+
+    </LinearLayout>
+
+
+</LinearLayout>