xulisong пре 6 година
родитељ
комит
9bc4078a42
100 измењених фајлова са 3088 додато и 684 уклоњено
  1. 1 1
      MBI/FirmLib/Com.FirmLib.UI/Manufacturer/WinProductType.xaml.cs
  2. 1 1
      MBI/FirmLib/Com.FirmLib.UI/Seller/WinSellerInfo.xaml.cs
  3. 1 1
      MBI/FirmLib/Com.FirmLib/Bll/ProjectBll.cs
  4. 10 1
      MBI/FirmLib/Com.FirmLib/Com.FirmLib.csproj
  5. BIN
      MBI/MBIResource/DataCheck/垃圾数据检查结果输出-模版.xlsx
  6. BIN
      MBI/MBIResource/DataCheck/模型检查结果输出格式-模版.xlsx
  7. 23 0
      MBI/MBIResource/DataDictionary/ComponentCodeToInputType.xml
  8. 8 0
      MBI/MBIResource/Services/Services.xml
  9. 46 4
      MBI/Menu/SAGABIM.xml
  10. BIN
      MBI/RibbonImage/系统清单.png
  11. BIN
      MBI/RibbonImage/系统清单16.png
  12. BIN
      MBI/RibbonImage/设备清单.png
  13. BIN
      MBI/RibbonImage/设备清单16.png
  14. BIN
      MBI/RibbonImage/资产清单.png
  15. BIN
      MBI/RibbonImage/资产清单16.png
  16. 74 0
      MBI/SAGA.DotNetUtils/Extend/JObjectExt.cs
  17. 313 0
      MBI/SAGA.DotNetUtils/NPOI/ExcelExtension.cs
  18. 15 26
      MBI/SAGA.DotNetUtils/NPOI/NPOIHelper.cs
  19. 4 0
      MBI/SAGA.DotNetUtils/SAGA.DotNetUtils.csproj
  20. 191 0
      MBI/SAGA.DotNetUtils/Serializer/SerializerByXml.cs
  21. 33 0
      MBI/SAGA.DotNetUtils/Service/IServiceLocator.cs
  22. 48 0
      MBI/SAGA.DotNetUtils/Service/ServiceConfigItem.cs
  23. 152 0
      MBI/SAGA.DotNetUtils/Service/ServiceLocator.cs
  24. 3 0
      MBI/SAGA.MBI/App.xaml.cs
  25. 4 4
      MBI/SAGA.MBI/Calc/CalcContext.cs
  26. 4 4
      MBI/SAGA.MBI/Calc/ObjectCalc.cs
  27. 1 1
      MBI/SAGA.MBI/Common/CacheAspect.cs
  28. 1 1
      MBI/SAGA.MBI/Common/MBIConst.cs
  29. 29 24
      MBI/SAGA.MBI/DataArrange/DalCommon.cs
  30. 48 1
      MBI/SAGA.MBI/DataArrange/DalEquip.cs
  31. 62 0
      MBI/SAGA.MBI/DataArrange/DalInfoCode.cs
  32. 3 3
      MBI/SAGA.MBI/DataArrange/DalModeFileManange.cs
  33. 76 7
      MBI/SAGA.MBI/DataArrange/DalSpace.cs
  34. 5 4
      MBI/SAGA.MBI/DataArrange/DalVisionOperate.cs
  35. 12 10
      MBI/SAGA.MBI/Extend/ElementExtend.cs
  36. 0 251
      MBI/SAGA.MBI/FileStream/FileOperateBase.cs
  37. 3 2
      MBI/SAGA.MBI/FileStream/ProjectDirOperate.cs
  38. 57 75
      MBI/SAGA.MBI/Html5Command.cs
  39. 47 4
      MBI/SAGA.MBI/JsonConvert/CommonConvert.cs
  40. 7 105
      MBI/SAGA.MBI/JsonConvert/PEPCodeConvert.cs
  41. 2 2
      MBI/SAGA.MBI/JsonConvert/SpaceConvert.cs
  42. 101 0
      MBI/SAGA.MBI/Model/Global_Relation_Defination.cs
  43. 25 0
      MBI/SAGA.MBI/Model/GraphRelationType.cs
  44. 99 0
      MBI/SAGA.MBI/Model/MBSpace.cs
  45. 3 5
      MBI/SAGA.MBI/Model/MSpace.cs
  46. 1 1
      MBI/SAGA.MBI/Model/MRevitEquipBase.cs
  47. 15 0
      MBI/SAGA.MBI/Model/PropertyDefineTb.cs
  48. 2 2
      MBI/SAGA.MBI/Model/RltBeaconinElementSp.cs
  49. 2 2
      MBI/SAGA.MBI/Model/RltEquipInSpace.cs
  50. 20 11
      MBI/SAGA.MBI/RequestData/CommonRequest.cs
  51. 36 0
      MBI/SAGA.MBI/RequestData/EquipmentRequest.cs
  52. 1 0
      MBI/SAGA.MBI/RequestData/MatchFMRequest.cs
  53. 5 40
      MBI/SAGA.MBI/RequestData/PEPCodeRequest.cs
  54. 21 0
      MBI/SAGA.MBI/RequestData/RelationRequest.cs
  55. 50 0
      MBI/SAGA.MBI/RequestData/SpaceRequest.cs
  56. 15 4
      MBI/SAGA.MBI/RevitReference/RVTNoModeDutyOperate.cs
  57. 18 2
      MBI/SAGA.MBI/SAGA.MBI.csproj
  58. 28 0
      MBI/SAGA.MBI/Service/InputService.cs
  59. 33 0
      MBI/SAGA.MBI/ToolCommand.cs
  60. 2 0
      MBI/SAGA.MBI/ToolsData/CheckBase/CheckOperation.cs
  61. 3 2
      MBI/SAGA.MBI/ToolsData/CheckBase/DCNPOIExtend.cs
  62. 5 0
      MBI/SAGA.MBI/ToolsData/CheckBase/ICheckBase.cs
  63. 2 2
      MBI/SAGA.MBI/ToolsData/CheckEquipCategory.cs
  64. 1 1
      MBI/SAGA.MBI/ToolsData/CorrectLossDuty.cs
  65. 15 2
      MBI/SAGA.MBI/ToolsData/DataCheck/DataCheckBase.cs
  66. 32 16
      MBI/SAGA.MBI/ToolsData/DataCheck/MissDutyOrModeCheck.cs
  67. 1 1
      MBI/SAGA.MBI/ToolsData/DataCheck/QRCodeContextCheck.cs
  68. 207 0
      MBI/SAGA.MBI/ToolsData/DataCheck/SpaceEquipFloorCheck.cs
  69. 31 0
      MBI/SAGA.MBI/ToolsData/DataCheck/SpaceEquipFloorCheckResult.cs
  70. 9 3
      MBI/SAGA.MBI/ToolsData/DataCheck/WinDataCheckSetting.xaml
  71. 15 0
      MBI/SAGA.MBI/ToolsData/DataCheck/WinDataCheckSetting.xaml.cs
  72. 70 1
      MBI/SAGA.MBI/ToolsData/ModeCheck/DataCheckRule.cs
  73. 3 1
      MBI/SAGA.MBI/ToolsData/ModeCheck/DocumentQueue.cs
  74. 206 0
      MBI/SAGA.MBI/ToolsData/ModeCheck/EquipReferSystemCheck.cs
  75. 37 0
      MBI/SAGA.MBI/ToolsData/ModeCheck/EquipReferSystemCheckResult.cs
  76. 3 1
      MBI/SAGA.MBI/ToolsData/ModeCheck/EquipmentPartRefEqCheckResult.cs
  77. 26 22
      MBI/SAGA.MBI/ToolsData/ModeCheck/FamilyNameCheck.cs
  78. 15 2
      MBI/SAGA.MBI/ToolsData/ModeCheck/ModeCheckBase.cs
  79. 8 2
      MBI/SAGA.MBI/ToolsData/ModeCheck/WinModeCheckSetting.xaml
  80. 17 0
      MBI/SAGA.MBI/ToolsData/ModeCheck/WinModeCheckSetting.xaml.cs
  81. 2 1
      MBI/SAGA.MBI/ToolsData/UpdateFileVision.cs
  82. 1 1
      MBI/SAGA.MBI/ToolsData/UpdateRelationEquipinSpace.cs
  83. 317 0
      MBI/SAGA.MBI/ToolsData/VerticalPipeAlign.cs
  84. 91 0
      MBI/SAGA.MBI/ToolsData/WinSelectCheckFloors.xaml
  85. 146 0
      MBI/SAGA.MBI/ToolsData/WinSelectCheckFloors.xaml.cs
  86. 4 4
      MBI/SAGA.MBI/WinView/BeModingDutyList/WinFMMergeTip4.xaml
  87. 4 3
      MBI/SAGA.MBI/WinView/Login/UcMFMFloorUp.xaml
  88. 3 2
      MBI/SAGA.MBI/WinView/ModeInfoMaintenance/PWGInstace.cs
  89. 1 0
      MBI/SAGA.MBI/WinView/ModeInfoMaintenance/WinMatchFMTip_FMNoBimId.xaml.cs
  90. 1 1
      MBI/SAGA.MBI/WinView/ModeInfoMaintenance/WinModeInfoMaintenance.xaml.cs
  91. 1 1
      MBI/SAGA.MBI/WinView/ModeInfoMaintenance/WinModeInfoMaintenanceForSpace.xaml.cs
  92. 3 3
      MBI/SAGA.MBI/WinView/Space/FloorSpaceContext.cs
  93. 1 1
      MBI/SAGA.MBI/WinView/Space/ServerSpace.cs
  94. 2 2
      MBI/SAGA.MBI/WinView/Space/SpaceManager.cs
  95. 5 5
      MBI/SAGA.MBI/WinView/Space/WinCreateSpace.xaml.cs
  96. 4 4
      MBI/SAGA.MBI/WinView/Space/WinCreateSpaceWeb.xaml.cs
  97. 1 0
      MBI/SAGA.RevitUtils/ExtendInterface/RevitEventsBingding.cs
  98. 34 0
      MBI/SAGA.RevitUtils/ExtendInterface/ServiceSetting.cs
  99. 0 1
      MBI/SAGA.RevitUtils/Extends/ExternalApplication.cs
  100. 0 0
      MBI/SAGA.RevitUtils/MEP/PipeExtend.cs

+ 1 - 1
MBI/FirmLib/Com.FirmLib.UI/Manufacturer/WinProductType.xaml.cs

@@ -44,7 +44,7 @@ namespace Com.FirmLib.UI.Manufacturer
             columns.ForEach(c =>
             {
                 DataGridDragCopyOptions.SetCanColumnDragCopy(c, true);
-                c.Width = c.Header.ToString().Length * 16 + 10;
+                c.Width = c.Header.ToString().Length * 16 +40;
                 c.MinWidth = 80;
             });
         }

+ 1 - 1
MBI/FirmLib/Com.FirmLib.UI/Seller/WinSellerInfo.xaml.cs

@@ -125,7 +125,7 @@ namespace Com.FirmLib.UI.Seller
             columns.ForEach(c =>
             {
                 //DataGridDragCopyOptions.SetCanColumnDragCopy(c, true);
-                c.Width = c.Header.ToString().Length * 16+10;
+                c.Width = c.Header.ToString().Length * 16+40;
                 c.IsReadOnly = true;
                 c.MinWidth = 80;
             });

+ 1 - 1
MBI/FirmLib/Com.FirmLib/Bll/ProjectBll.cs

@@ -67,7 +67,7 @@ namespace Com.FirmLib.Bll
         {
             string tempUrlExtension = BaseEndUri() + @"/project/sync";
             JObject jObject = new JObject();
-            JArray jArray = new JArray(projectId);
+            JArray jArray = new JArray();
             jArray.Add(projectId);
             jObject.Add("project", jArray);
             var result = PostJsonAsync(new Uri(tempUrlExtension, UriKind.RelativeOrAbsolute), jObject);

+ 10 - 1
MBI/FirmLib/Com.FirmLib/Com.FirmLib.csproj

@@ -131,7 +131,16 @@
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
   </ItemGroup>
-  <ItemGroup />
+  <ItemGroup>
+    <ProjectReference Include="..\..\SAGA.DotNetUtils\SAGA.DotNetUtils.csproj">
+      <Project>{07B73C98-DCB0-4782-81FA-F50A30B563AB}</Project>
+      <Name>SAGA.DotNetUtils</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\SAGA.RevitUtils\SAGA.RevitUtils.csproj">
+      <Project>{D6201677-B7E4-495A-81AB-33C5837121E6}</Project>
+      <Name>SAGA.RevitUtils</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

BIN
MBI/MBIResource/DataCheck/垃圾数据检查结果输出-模版.xlsx


BIN
MBI/MBIResource/DataCheck/模型检查结果输出格式-模版.xlsx


+ 23 - 0
MBI/MBIResource/DataDictionary/ComponentCodeToInputType.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ArrayOfComponentCodeToInputType xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <ComponentCodeToInputType>
+    <ComponentCode>A1</ComponentCode>
+    <InputType>TextBox_Double_A1</InputType>
+  </ComponentCodeToInputType>
+  <ComponentCodeToInputType>
+    <ComponentCode>A2</ComponentCode>
+    <InputType>Textbox_DoubleUnit_A2</InputType>
+  </ComponentCodeToInputType>
+  <ComponentCodeToInputType>
+    <ComponentCode>B1</ComponentCode>
+    <InputType>TextBox_String_B1</InputType>
+  </ComponentCodeToInputType>
+  <ComponentCodeToInputType>
+    <ComponentCode>C5</ComponentCode>
+    <InputType>DataTime_Date_C5</InputType>
+  </ComponentCodeToInputType>
+  <ComponentCodeToInputType>
+    <ComponentCode>D1</ComponentCode>
+    <InputType>Enum_D1</InputType>
+  </ComponentCodeToInputType>
+</ArrayOfComponentCodeToInputType>

+ 8 - 0
MBI/MBIResource/Services/Services.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Services>
+  <ServiceConfigItem>
+    <Name></Name>
+    <ClassName>SAGA.MBI.Service.InputService</ClassName>
+    <DllPath>SAGA.MBI.exe</DllPath>
+   </ServiceConfigItem>
+</Services>

+ 46 - 4
MBI/Menu/SAGABIM.xml

@@ -129,11 +129,11 @@
       <MenuTab>MCJPC_W</MenuTab>
       <Modules>TSRP</Modules>
     </Button>
-   <Button ButtonStyles="Separator">
+    <Button ButtonStyles="Separator">
       <MenuTab>MCJPC_W</MenuTab>
       <Modules>TSRP</Modules>
     </Button>
-<Button ButtonStyles="Large">
+    <Button ButtonStyles="Large">
       <ButtonName>SAGA.MBI.SyncLocalNameCommand</ButtonName>
       <ButtonText>同步本地名称信息点</ButtonText>
       <ImageName>6、模型信息点维护</ImageName>
@@ -189,8 +189,20 @@
       <Modules>TSRP</Modules>
     </Button>
   </Panel>
- 
-
+  <Panel PanelName="设备台账" GroupFlag="True" GroupImage="" RevitVer="R14,R15,R16,R17" ButtonStyles="Large">
+    <Button ButtonStyles="Large">
+      <ButtonName>SAGA.MBI.EquipmentListCommand</ButtonName>
+      <ButtonText>设备清单</ButtonText>
+      <ImageName>设备清单</ImageName>
+      <DllName>..\OutputDll\SAGA.MBI.exe</DllName>
+      <ClassName>SAGA.MBI.EquipmentListCommand</ClassName>
+      <ToolTip>设备清单</ToolTip>
+      <LongDescription>设备清单</LongDescription>
+      <ToolTipImage></ToolTipImage>
+      <MenuTab>Space_W</MenuTab>
+      <Modules>Space</Modules>
+    </Button>
+  </Panel>
   <Panel PanelName="业务空间管理" GroupFlag="True" GroupImage="" RevitVer="R14,R15,R16,R17" ButtonStyles="Large">
     <Button ButtonStyles="Large">
       <ButtonName>SAGA.MBI.SpaceListCommand</ButtonName>
@@ -205,6 +217,21 @@
       <Modules>Space</Modules>
     </Button>
   </Panel>
+
+  <Panel PanelName="系统管理" GroupFlag="True" GroupImage="" RevitVer="R14,R15,R16,R17" ButtonStyles="Large">
+    <Button ButtonStyles="Large">
+      <ButtonName>SAGA.MBI.SystemListCommand</ButtonName>
+      <ButtonText>系统清单</ButtonText>
+      <ImageName>系统清单</ImageName>
+      <DllName>..\OutputDll\SAGA.MBI.exe</DllName>
+      <ClassName>SAGA.MBI.SystemListCommand</ClassName>
+      <ToolTip>系统清单</ToolTip>
+      <LongDescription>系统清单</LongDescription>
+      <ToolTipImage></ToolTipImage>
+      <MenuTab>Space_W</MenuTab>
+      <Modules>Space</Modules>
+    </Button>
+  </Panel>
   <!--厂商库-->
   <Panel PanelName="厂商资料库" GroupFlag="True" GroupImage="" RevitVer="R14,R15,R16,R17" ButtonStyles="Large">
     <Button ButtonStyles="Large">
@@ -258,6 +285,21 @@
       <Modules>CSZLK</Modules>
     </Button>
   </Panel>
+
+  <Panel PanelName="资产台账" GroupFlag="True" GroupImage="" RevitVer="R14,R15,R16,R17" ButtonStyles="Large">
+    <Button ButtonStyles="Large">
+      <ButtonName>SAGA.MBI.AssetListCommand</ButtonName>
+      <ButtonText>资产清单</ButtonText>
+      <ImageName>资产清单</ImageName>
+      <DllName>..\OutputDll\SAGA.MBI.exe</DllName>
+      <ClassName>SAGA.MBI.AssetListCommand</ClassName>
+      <ToolTip>资产清单</ToolTip>
+      <LongDescription>资产清单</LongDescription>
+      <ToolTipImage></ToolTipImage>
+      <MenuTab>ZCGL_W</MenuTab>
+      <Modules>ZCGL</Modules>
+    </Button>
+  </Panel>
   <Panel PanelName="扫楼业务" GroupFlag="True" GroupImage="" RevitVer="R14,R15,R16,R17" ButtonStyles="Large">
     <Button ButtonStyles="Large">
       <ButtonName>SAGA.MBI.ScanDataCommand</ButtonName>

BIN
MBI/RibbonImage/系统清单.png


BIN
MBI/RibbonImage/系统清单16.png


BIN
MBI/RibbonImage/设备清单.png


BIN
MBI/RibbonImage/设备清单16.png


BIN
MBI/RibbonImage/资产清单.png


BIN
MBI/RibbonImage/资产清单16.png


+ 74 - 0
MBI/SAGA.DotNetUtils/Extend/JObjectExt.cs

@@ -5,7 +5,9 @@
  * ==============================================================================*/
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Linq;
+using System.Reflection;
 using System.Text;
 using System.Threading.Tasks;
 using Newtonsoft.Json.Linq;
@@ -45,6 +47,78 @@ namespace SAGA.DotNetUtils.Extend
             }
             return value;
         }
+        /// <summary>
+        /// JObject 转化为实体类
+        /// 通过Description标记
+        /// </summary>
+        /// <param name="jObject"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public static Object ConvertToInstance(this JObject jObject, Type type)
+        {
+            var obj = type.Assembly.CreateInstance(type.FullName);
+            try
+            {
+                var properties = obj.GetType().GetProperties();
+
+                foreach (var propertyInfo in properties)
+                {
+                    var descriptionAttribute = propertyInfo.GetCustomAttribute<DescriptionAttribute>();
+                    if (descriptionAttribute == null) continue;
+                    var description = descriptionAttribute.Description;
+                    var jToken = jObject[description];
+                    if (jToken == null) continue;
+                    var ptype = propertyInfo.PropertyType;
+                    
+                    if (propertyInfo.PropertyType == typeof(string))
+                    {//String类型
+                        var str = jToken.Value<string>();
+                        propertyInfo.SetValue(obj, str);
+                    }
+                    else if (propertyInfo.PropertyType.IsGenericType)
+                    {//集合Content
+                        Type genericType = ptype.GetGenericArguments().First();
+                        //创建集合
+                        object genericList = CreateGeneric(typeof(List<>), genericType);
+                        if (genericList != null)
+                        {
+                            var addMethods = genericList.GetType().GetMethods().FirstOrDefault(t => t.Name == "Add");
+                            if (addMethods != null)
+                            {
+                                foreach (JObject jItem in (JArray)jToken)
+                                {//集合赋值
+                                    var subObj = ConvertToInstance(jItem, genericType);
+                                    addMethods.Invoke(genericList, new object[] { subObj });
+                                }
+                            }
+
+                            propertyInfo.SetValue(obj, genericList);
+                        }
+
+
+                    }
+
+                }
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e);
+            }
+
+            return obj;
+        }
+        /// <summary>
+        /// 初始化集合
+        /// </summary>
+        /// <param name="generic"></param>
+        /// <param name="innerType"></param>
+        /// <param name="args"></param>
+        /// <returns></returns>
+        public static object CreateGeneric(Type generic, Type innerType, params object[] args)
+        {
+            Type specificType = generic.MakeGenericType(new System.Type[] { innerType });
+            return Activator.CreateInstance(specificType, args);
+        }
         public static JObject Merge(this JObject jObject, JObject jObject2)
         {
             JObject result = new JObject();

+ 313 - 0
MBI/SAGA.DotNetUtils/NPOI/ExcelExtension.cs

@@ -0,0 +1,313 @@
+/* ==============================================================================
+ * 功能描述:ExcelExtension  
+ * 创 建 者:Garrett
+ * 创建日期:2019/1/14 10:16:40
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using NPOI.SS.UserModel;
+using NPOI.SS.Util;
+
+namespace SAGA.DotNetUtils.NPOI
+{
+    /// <summary>
+    /// 表示单元格的维度,通常用于表达合并单元格的维度
+    /// </summary>
+    public struct Dimension
+    {
+        /// <summary>
+        /// 含有数据的单元格(通常表示合并单元格的第一个跨度行第一个跨度列),该字段可能为null
+        /// </summary>
+        public ICell DataCell;
+
+        /// <summary>
+        /// 行跨度(跨越了多少行)
+        /// </summary>
+        public int RowSpan;
+
+        /// <summary>
+        /// 列跨度(跨越了多少列)
+        /// </summary>
+        public int ColumnSpan;
+
+        /// <summary>
+        /// 合并单元格的起始行索引
+        /// </summary>
+        public int FirstRowIndex;
+
+        /// <summary>
+        /// 合并单元格的结束行索引
+        /// </summary>
+        public int LastRowIndex;
+
+        /// <summary>
+        /// 合并单元格的起始列索引
+        /// </summary>
+        public int FirstColumnIndex;
+
+        /// <summary>
+        /// 合并单元格的结束列索引
+        /// </summary>
+        public int LastColumnIndex;
+    }
+
+    public static class ExcelExtension
+    {
+        /// <summary>
+        /// 判断指定行列所在的单元格是否为合并单元格,并且输出该单元格的维度
+        /// </summary>
+        /// <param name="sheet">Excel工作表</param>
+        /// <param name="rowIndex">行索引,从0开始</param>
+        /// <param name="columnIndex">列索引,从0开始</param>
+        /// <param name="dimension">单元格维度</param>
+        /// <returns>返回是否为合并单元格的布尔(Boolean)值</returns>
+        public static bool IsMergeCell(this ISheet sheet, int rowIndex, int columnIndex, out Dimension dimension)
+        {
+            dimension = new Dimension
+            {
+                DataCell = null,
+                RowSpan = 1,
+                ColumnSpan = 1,
+                FirstRowIndex = rowIndex,
+                LastRowIndex = rowIndex,
+                FirstColumnIndex = columnIndex,
+                LastColumnIndex = columnIndex
+            };
+
+            for (int i = 0; i < sheet.NumMergedRegions; i++)
+            {
+                CellRangeAddress range = sheet.GetMergedRegion(i);
+                sheet.IsMergedRegion(range);
+
+                //这种算法只有当指定行列索引刚好是合并单元格的第一个跨度行第一个跨度列时才能取得合并单元格的跨度
+                //if (range.FirstRow == rowIndex && range.FirstColumn == columnIndex)
+                //{
+                //    dimension.DataCell = sheet.GetRow(range.FirstRow).GetCell(range.FirstColumn);
+                //    dimension.RowSpan = range.LastRow - range.FirstRow + 1;
+                //    dimension.ColumnSpan = range.LastColumn - range.FirstColumn + 1;
+                //    dimension.FirstRowIndex = range.FirstRow;
+                //    dimension.LastRowIndex = range.LastRow;
+                //    dimension.FirstColumnIndex = range.FirstColumn;
+                //    dimension.LastColumnIndex = range.LastColumn;
+                //    break;
+                //}
+
+                if ((rowIndex >= range.FirstRow && range.LastRow >= rowIndex) && (columnIndex >= range.FirstColumn && range.LastColumn >= columnIndex))
+                {
+                    dimension.DataCell = sheet.GetRow(range.FirstRow).GetCell(range.FirstColumn);
+                    dimension.RowSpan = range.LastRow - range.FirstRow + 1;
+                    dimension.ColumnSpan = range.LastColumn - range.FirstColumn + 1;
+                    dimension.FirstRowIndex = range.FirstRow;
+                    dimension.LastRowIndex = range.LastRow;
+                    dimension.FirstColumnIndex = range.FirstColumn;
+                    dimension.LastColumnIndex = range.LastColumn;
+                    break;
+                }
+            }
+
+            bool result;
+            if (rowIndex >= 0 && sheet.LastRowNum > rowIndex)
+            {
+                IRow row = sheet.GetRow(rowIndex);
+                if (columnIndex >= 0 && row.LastCellNum > columnIndex)
+                {
+                    ICell cell = row.GetCell(columnIndex);
+                    result = cell.IsMergedCell;
+
+                    if (dimension.DataCell == null)
+                    {
+                        dimension.DataCell = cell;
+                    }
+                }
+                else
+                {
+                    result = false;
+                }
+            }
+            else
+            {
+                result = false;
+            }
+
+            return result;
+        }
+
+        /// <summary>
+        /// 判断指定行列所在的单元格是否为合并单元格,并且输出该单元格的行列跨度
+        /// </summary>
+        /// <param name="sheet">Excel工作表</param>
+        /// <param name="rowIndex">行索引,从0开始</param>
+        /// <param name="columnIndex">列索引,从0开始</param>
+        /// <param name="rowSpan">行跨度,返回值最小为1,同时表示没有行合并</param>
+        /// <param name="columnSpan">列跨度,返回值最小为1,同时表示没有列合并</param>
+        /// <returns>返回是否为合并单元格的布尔(Boolean)值</returns>
+        public static bool IsMergeCell(this ISheet sheet, int rowIndex, int columnIndex, out int rowSpan, out int columnSpan)
+        {
+            Dimension dimension;
+            bool result = sheet.IsMergeCell(rowIndex, columnIndex, out dimension);
+
+            rowSpan = dimension.RowSpan;
+            columnSpan = dimension.ColumnSpan;
+
+            return result;
+        }
+
+        /// <summary>
+        /// 判断指定单元格是否为合并单元格,并且输出该单元格的维度
+        /// </summary>
+        /// <param name="cell">单元格</param>
+        /// <param name="dimension">单元格维度</param>
+        /// <returns>返回是否为合并单元格的布尔(Boolean)值</returns>
+        public static bool IsMergeCell(this ICell cell, out Dimension dimension)
+        {
+            return cell.Sheet.IsMergeCell(cell.RowIndex, cell.ColumnIndex, out dimension);
+        }
+
+        /// <summary>
+        /// 判断指定单元格是否为合并单元格,并且输出该单元格的行列跨度
+        /// </summary>
+        /// <param name="cell">单元格</param>
+        /// <param name="rowSpan">行跨度,返回值最小为1,同时表示没有行合并</param>
+        /// <param name="columnSpan">列跨度,返回值最小为1,同时表示没有列合并</param>
+        /// <returns>返回是否为合并单元格的布尔(Boolean)值</returns>
+        public static bool IsMergeCell(this ICell cell, out int rowSpan, out int columnSpan)
+        {
+            return cell.Sheet.IsMergeCell(cell.RowIndex, cell.ColumnIndex, out rowSpan, out columnSpan);
+        }
+
+        /// <summary>
+        /// 返回上一个跨度行,如果rowIndex为第一行,则返回null
+        /// </summary>
+        /// <param name="sheet">Excel工作表</param>
+        /// <param name="rowIndex">行索引,从0开始</param>
+        /// <param name="columnIndex">列索引,从0开始</param>
+        /// <returns>返回上一个跨度行</returns>
+        public static IRow PrevSpanRow(this ISheet sheet, int rowIndex, int columnIndex)
+        {
+            return sheet.FuncSheet(rowIndex, columnIndex, (currentDimension, isMerge) =>
+            {
+                //上一个单元格维度
+                Dimension prevDimension;
+                sheet.IsMergeCell(currentDimension.FirstRowIndex - 1, columnIndex, out prevDimension);
+                return prevDimension.DataCell.Row;
+            });
+        }
+
+        /// <summary>
+        /// 返回下一个跨度行,如果rowIndex为最后一行,则返回null
+        /// </summary>
+        /// <param name="sheet">Excel工作表</param>
+        /// <param name="rowIndex">行索引,从0开始</param>
+        /// <param name="columnIndex">列索引,从0开始</param>
+        /// <returns>返回下一个跨度行</returns>
+        public static IRow NextSpanRow(this ISheet sheet, int rowIndex, int columnIndex)
+        {
+            return sheet.FuncSheet(rowIndex, columnIndex, (currentDimension, isMerge) =>
+                isMerge ? sheet.GetRow(currentDimension.FirstRowIndex + currentDimension.RowSpan) : sheet.GetRow(rowIndex));
+        }
+
+        /// <summary>
+        /// 返回上一个跨度行,如果row为第一行,则返回null
+        /// </summary>
+        /// <param name="row">行</param>
+        /// <returns>返回上一个跨度行</returns>
+        public static IRow PrevSpanRow(this IRow row)
+        {
+            return row.Sheet.PrevSpanRow(row.RowNum, row.FirstCellNum);
+        }
+
+        /// <summary>
+        /// 返回下一个跨度行,如果row为最后一行,则返回null
+        /// </summary>
+        /// <param name="row">行</param>
+        /// <returns>返回下一个跨度行</returns>
+        public static IRow NextSpanRow(this IRow row)
+        {
+            return row.Sheet.NextSpanRow(row.RowNum, row.FirstCellNum);
+        }
+
+        /// <summary>
+        /// 返回上一个跨度列,如果columnIndex为第一列,则返回null
+        /// </summary>
+        /// <param name="row">行</param>
+        /// <param name="columnIndex">列索引,从0开始</param>
+        /// <returns>返回上一个跨度列</returns>
+        public static ICell PrevSpanCell(this IRow row, int columnIndex)
+        {
+            return row.Sheet.FuncSheet(row.RowNum, columnIndex, (currentDimension, isMerge) =>
+            {
+                //上一个单元格维度
+                Dimension prevDimension;
+                row.Sheet.IsMergeCell(row.RowNum, currentDimension.FirstColumnIndex - 1, out prevDimension);
+                return prevDimension.DataCell;
+            });
+        }
+
+        /// <summary>
+        /// 返回下一个跨度列,如果columnIndex为最后一列,则返回null
+        /// </summary>
+        /// <param name="row">行</param>
+        /// <param name="columnIndex">列索引,从0开始</param>
+        /// <returns>返回下一个跨度列</returns>
+        public static ICell NextSpanCell(this IRow row, int columnIndex)
+        {
+            return row.Sheet.FuncSheet(row.RowNum, columnIndex, (currentDimension, isMerge) =>
+                row.GetCell(currentDimension.FirstColumnIndex + currentDimension.ColumnSpan));
+        }
+
+        /// <summary>
+        /// 返回上一个跨度列,如果cell为第一列,则返回null
+        /// </summary>
+        /// <param name="cell">单元格</param>
+        /// <returns>返回上一个跨度列</returns>
+        public static ICell PrevSpanCell(this ICell cell)
+        {
+            return cell.Row.PrevSpanCell(cell.ColumnIndex);
+        }
+
+        /// <summary>
+        /// 返回下一个跨度列,如果columnIndex为最后一列,则返回null
+        /// </summary>
+        /// <param name="cell">单元格</param>
+        /// <returns>返回下一个跨度列</returns>
+        public static ICell NextSpanCell(this ICell cell)
+        {
+            return cell.Row.NextSpanCell(cell.ColumnIndex);
+        }
+
+        /// <summary>
+        /// 返回指定行索引所在的合并单元格(区域)中的第一行(通常是含有数据的行)
+        /// </summary>
+        /// <param name="sheet">Excel工作表</param>
+        /// <param name="rowIndex">行索引,从0开始</param>
+        /// <returns>返回指定列索引所在的合并单元格(区域)中的第一行</returns>
+        public static IRow GetDataRow(this ISheet sheet, int rowIndex)
+        {
+            return sheet.FuncSheet(rowIndex, 0, (currentDimension, isMerge) => sheet.GetRow(currentDimension.FirstRowIndex));
+        }
+
+        /// <summary>
+        /// 返回指定列索引所在的合并单元格(区域)中的第一行第一列(通常是含有数据的单元格)
+        /// </summary>
+        /// <param name="row">行</param>
+        /// <param name="columnIndex">列索引</param>
+        /// <returns>返回指定列索引所在的合并单元格(区域)中的第一行第一列</returns>
+        public static ICell GetDataCell(this IRow row, int columnIndex)
+        {
+            return row.Sheet.FuncSheet(row.RowNum, columnIndex, (currentDimension, isMerge) => currentDimension.DataCell);
+        }
+
+        private static T FuncSheet<T>(this ISheet sheet, int rowIndex, int columnIndex, Func<Dimension, bool, T> func)
+        {
+            //当前单元格维度
+            Dimension currentDimension;
+            //是否为合并单元格
+            bool isMerge = sheet.IsMergeCell(rowIndex, columnIndex, out currentDimension);
+
+            return func(currentDimension, isMerge);
+        }
+    }
+}

+ 15 - 26
MBI/SAGA.DotNetUtils/NPOI/NPOIHelper.cs

@@ -9,7 +9,6 @@ using NPOI.HSSF.UserModel;
 using NPOI.SS.UserModel;
 using NPOI.SS.Util;
 using NPOI.XSSF.UserModel;
-using SAGA.DotNetUtils.NPOI;
 using SAGA.DotNetUtils.Extend;
 
 namespace SAGA.DotNetUtils.NPOI
@@ -241,7 +240,7 @@ namespace SAGA.DotNetUtils.NPOI
 
             IRow headerRow = sheet.GetRow(0);
             if (headerRow == null) return dt;
-            if (headerRow.Cells.Count==0)
+            if (headerRow.Cells.Count == 0)
             {
                 headerRow = sheet.GetRow(1);
             }
@@ -256,7 +255,7 @@ namespace SAGA.DotNetUtils.NPOI
             for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++)
             {
                 IRow row = sheet.GetRow(i);
-                if(row==null)continue;
+                if (row == null) continue;
                 DataRow dataRow = dt.NewRow();
 
                 for (int j = row.FirstCellNum; j < cellCount; j++)
@@ -325,7 +324,7 @@ namespace SAGA.DotNetUtils.NPOI
                 ISheet sheet = sheetInfo.SheetName == "" ? workbook.GetSheetAt(0) : workbook.GetSheet(sheetInfo.SheetName);
 
                 IRow row;
-               // List<int> showIndex = new List<int> { 1, 2, 3, 4 };
+                // List<int> showIndex = new List<int> { 1, 2, 3, 4 };
 
                 for (int i = sheetInfo.RowStartIndex; i < sheet.LastRowNum; i++)
                 {
@@ -342,6 +341,7 @@ namespace SAGA.DotNetUtils.NPOI
         }
         /// <summary>
         /// C#反射遍历对象属性
+        /// 
         /// </summary>
         /// <typeparam name="T">对象类型</typeparam>
         /// <param name="model">对象</param>
@@ -353,34 +353,23 @@ namespace SAGA.DotNetUtils.NPOI
             foreach (PropertyInfo item in PropertyList)
             {
                 var index = item.GetCustomAttribute<CellIndexAttribute>()?.Index;
-                ICell cell = row.GetCell(index ?? 0);
-                if (cell == null)
+                string value = "";
+                //有cellindex标记的才赋值
+                if (index !=null)
                 {
-                    item.SetValue(model, "");
-                    continue;
-                }
-                if (cell.IsMergedCell)
-                {
-                    //row.Sheet.
-                    var sheet = row.Sheet;
-                    for (int i = 0; i < sheet.NumMergedRegions; i++)
+                    int i = (int) index;
+                    value = row.GetCell(i)?.StringCellValue;
+                    //如果读取到的值为null,则判断是否为合并单元格,读取合并单元格的值
+                    if (value.IsNullOrEmpty())
                     {
-                        var range = sheet.GetMergedRegion(i);
-                        if (range.IsInRange(cell.RowIndex, cell.ColumnIndex))
-                        {
-                            var useRow = row.Sheet.GetRow(range.FirstRow);
-                            item.SetValue(model, useRow.GetCell(range.FirstColumn) + "");
-                            break;
-                        }
-                    }                  
+                        value = row.GetDataCell(i)?.StringCellValue;
+                    }
+                    item.SetValue(model, value);
                 }
-                else
-                {
-                    item.SetValue(model, row.GetCell(index ?? 0) + "");
-                }             
             }
             return model;
         }
+
     }
     public class SheetInfoAttribute : Attribute
     {

+ 4 - 0
MBI/SAGA.DotNetUtils/SAGA.DotNetUtils.csproj

@@ -291,6 +291,7 @@
     <Compile Include="Logger\SystemLogger.cs" />
     <Compile Include="Logger\WriteHandler.cs" />
     <Compile Include="MBI\OutReachConst.cs" />
+    <Compile Include="NPOI\ExcelExtension.cs" />
     <Compile Include="NPOI\NPOIHelper.cs" />
     <Compile Include="Others\AppBaseInfo.cs" />
     <Compile Include="Others\ApplicationDecrypt.cs" />
@@ -335,6 +336,9 @@
     <Compile Include="PropertyGrid\XProp.cs" />
     <Compile Include="PropertyGrid\XPropDescriptor.cs" />
     <Compile Include="PropertyGrid\XProps.cs" />
+    <Compile Include="Service\IServiceLocator.cs" />
+    <Compile Include="Service\ServiceConfigItem.cs" />
+    <Compile Include="Service\ServiceLocator.cs" />
     <Compile Include="Utilities\CompressUtil.cs" />
     <Compile Include="Utilities\FileUp.cs" />
     <Compile Include="Utilities\IniOperator.cs" />

+ 191 - 0
MBI/SAGA.DotNetUtils/Serializer/SerializerByXml.cs

@@ -4,11 +4,13 @@
  * 创建日期:2018/4/3 17:23:34
  * ==============================================================================*/
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using System.Windows;
 using System.Xml.Serialization;
 
 namespace SAGA.DotNetUtils.Serializer
@@ -35,5 +37,194 @@ namespace SAGA.DotNetUtils.Serializer
                 return (T)serializer.Deserialize(stream);// 反序列化得到新的对象  
             }
         }
+        /// <summary>
+        /// 序列化成xml字符串
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns>序列化后的字符串</returns>
+        public static string Serialize(object obj)
+        {
+            string str = "";
+            XmlSerializer xs = new XmlSerializer(obj.GetType());
+            using (MemoryStream ms = new MemoryStream())
+            {
+                try
+                {
+                    System.Xml.XmlTextWriter xtw = new System.Xml.XmlTextWriter(ms, System.Text.Encoding.UTF8);
+                    xtw.Formatting = System.Xml.Formatting.Indented;
+                    xs.Serialize(xtw, obj);
+                    ms.Seek(0, SeekOrigin.Begin);
+                    using (StreamReader sr = new StreamReader(ms))
+                    {
+                        try
+                        {
+                            str = sr.ReadToEnd();
+                            xtw.Close();
+                            ms.Close();
+                        }
+                        catch (Exception e)
+                        {
+                            Console.WriteLine(e);
+                        }
+                        finally
+                        {
+                            xtw.Close();
+                            sr.Close();
+                        }
+
+                    }
+                }
+                catch (Exception e)
+                {
+                    Console.WriteLine(e);
+                }
+                finally
+                {
+                    ms.Close();
+                }
+
+            }
+            return str;
+        }
+        /// <summary>
+        /// 序列化并保存
+        /// 类必须标记为可序列化[Serializable]
+        /// </summary>
+        public static void SerializeAndSave(string filePath, string fileName, object obj)
+        {
+            string path = Path.Combine(filePath, fileName);
+
+            if (!Directory.Exists(filePath))
+                Directory.CreateDirectory(filePath);
+
+            using (System.IO.FileStream fs = new System.IO.FileStream(path, FileMode.OpenOrCreate))
+            {
+                fs.SetLength(0);
+                using (StreamWriter sw = new StreamWriter(fs))
+                {
+                    try
+                    {
+                        fs.Position = 0;
+                        var jsonData = Serialize(obj);
+                        //var jsonData = Newtonsoft_Common.SerializeObjToJson(new Serialization<T>(floorSequences));
+                        sw.Write(jsonData);
+                        //BinaryFormatter bf = new BinaryFormatter();
+                        //bf.Serialize(fs, floorSequences); //复制到流中
+                        //MessageBox.Show("保存成功!");
+                        //上传数据
+                    }
+                    catch (Exception ex)
+                    {
+                        MessageBox.Show("保存失败!!!" + ex.ToString());
+                    }
+                    finally
+                    {
+                        sw.Flush();
+                        sw.Close();
+                        fs.Close();
+                    }
+                }
+            }
+        }
+        /// <summary>
+        /// 反序列化方法
+        /// </summary>
+        /// <typeparam name="T">反序列化对象类型</typeparam>
+        /// <param name="xml">反序列化字符串或者xml文件路径</param>
+        /// <returns></returns>
+        public static T Desrialize<T>(string path)
+        {
+            T obj = default(T);
+            XmlSerializer xs = new XmlSerializer(typeof(T));
+            TextReader tr = null;
+            try
+            {
+
+                if (!File.Exists(path))
+                {
+                    tr = new StringReader(path);
+                }
+                else
+                {
+                    tr = new StreamReader(path);
+                }
+                using (tr)
+                {
+                    obj = (T)xs.Deserialize(tr);
+                }
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e);
+            }
+            finally
+            {
+                tr?.Close();
+            }
+            return obj;
+        }
+        /// <summary>
+        /// 反序列化
+        /// </summary>
+        /// <returns></returns>
+        public static T Deserialize<T>(string filePath, string fileName)
+        {
+            T floorSequences = default(T);
+            string path = Path.Combine(filePath, fileName);
+            if (!File.Exists(path))
+                return floorSequences;
+            try
+            {
+                var obj = Desrialize<T>(path);
+                floorSequences = obj;
+                //var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<List<T>>(jsonData);
+            }
+            catch (Exception ex)
+            {
+                //MessageBox.Show("读取失败!!!"+ex.ToString());
+
+            }
+            finally
+            {
+            }
+            return floorSequences;
+        }
+        /// <summary>
+        /// 反序列化
+        /// </summary>
+        /// <returns></returns>
+        public static List<T> DeserializeList<T>(string filePath, string fileName)
+        {
+            List<T> floorSequences = new List<T>();
+            string path = Path.Combine(filePath, fileName);
+            if (!File.Exists(path))
+                return floorSequences;
+            using (StreamReader sr = new StreamReader(path, Encoding.Default))
+            {
+
+                try
+                {
+                    var obj = Desrialize<List<T>>(path);
+                    //var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<List<T>>(jsonData);
+
+                    var objs = (IEnumerable)obj;
+                    if (objs != null)
+                        floorSequences = objs.Cast<T>().ToList();
+                }
+                catch (Exception ex)
+                {
+                    //MessageBox.Show("读取失败!!!"+ex.ToString());
+
+                }
+                finally
+                {
+                    sr.Close();
+                }
+            }
+            return floorSequences;
+        }
+        
+     
+
     }
 }

+ 33 - 0
MBI/SAGA.DotNetUtils/Service/IServiceLocator.cs

@@ -0,0 +1,33 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:IServiceLocatior
+ * 作者:xulisong
+ * 创建时间: 2019/1/18 9:02:46
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.DotNetUtils.Service
+{
+    public interface IServiceLocator
+    {
+        T GetService<T>() where T : class;
+        object GetService(string serviceName);
+        T GetService<T>(string serviceName) where T : class;
+
+        void RemoveService<T>() where T : class;
+        void Remove(string serviceName);
+        void Remove<T>(string serviceName) where T : class;
+
+        string Register<T>(T service) where T : class;
+        void Register(string serviceName,object service);
+        void Register<T>(string serviceName,T service) where T : class;
+
+        void LoadServices(string configFile);
+        void LoadServices(string configFile, Func<string, string> dllPathSelector);
+    }
+}

+ 48 - 0
MBI/SAGA.DotNetUtils/Service/ServiceConfigItem.cs

@@ -0,0 +1,48 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:ServiceConfigItem
+ * 作者:xulisong
+ * 创建时间: 2019/1/18 9:04:17
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SAGA.DotNetUtils.Service
+{
+    public class ServiceConfigItem
+    {
+        /// <summary>
+        /// 服务名称
+        /// </summary>
+        public string Name { get; set; }
+        /// <summary>
+        /// 引用类名称
+        /// </summary>
+        public string ClassName { get; set; }
+        /// <summary>
+        /// Dll路径
+        /// </summary>
+        public string DllPath { get; set; }
+    }
+
+    [XmlRoot("Services")]
+    public class ServiceConfigItems : List<ServiceConfigItem>
+    {
+        public static ServiceConfigItems Load(string fileName)
+        {
+            XmlSerializer xml = new XmlSerializer(typeof(ServiceConfigItems), new List<Type>(){typeof(ServiceConfigItem) }.ToArray());
+            XmlDocument doc = new XmlDocument();
+            doc.Load(fileName);
+            XmlReader reader = new XmlNodeReader(doc);
+            reader = XmlReader.Create(reader, new XmlReaderSettings() { IgnoreComments = true, ConformanceLevel = ConformanceLevel.Document, CheckCharacters = false });
+            ServiceConfigItems newObject = xml.Deserialize(reader) as ServiceConfigItems;
+            return newObject;
+        }
+    }
+}

+ 152 - 0
MBI/SAGA.DotNetUtils/Service/ServiceLocator.cs

@@ -0,0 +1,152 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:ServiceLocator
+ * 作者:xulisong
+ * 创建时间: 2019/1/18 9:03:07
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.DotNetUtils.Service
+{
+    public class ServiceLocator : IServiceLocator
+    {
+        private static IServiceLocator m_Current;
+        public static IServiceLocator Current
+        {
+            get
+            {
+                if (m_Current == null)
+                {
+                    m_Current = new ServiceLocator();
+                }
+                return m_Current;
+            }
+        }
+        private ServiceLocator()
+        {
+            m_Services = new Dictionary<string, object>();
+        }
+
+        #region 私有方法
+        private void CheckName(string name)
+        {
+            if (string.IsNullOrWhiteSpace(name))
+                throw new ArgumentException(nameof(name) + "不能为null或空字符串");
+        }
+        private string CreateKey()
+        {
+            return Guid.NewGuid().ToString("N");
+        } 
+        #endregion
+        private readonly Dictionary<string, object> m_Services;
+        public T GetService<T>() where T :class
+        {
+            foreach (var service in m_Services)
+            {
+                var use = service.Value as T;
+                if (use != null)
+                    return use;
+            }
+            return null;
+        }
+
+        public object GetService(string serviceName)
+        {
+            CheckName(serviceName);
+            m_Services.TryGetValue(serviceName, out object result);
+            return result;
+        }
+
+        public T GetService<T>(string serviceName) where T : class
+        {
+            CheckName(serviceName);
+            return GetService(serviceName) as T;
+        }    
+        public string Register<T>(T service) where T : class
+        {
+            var key = CreateKey();
+            this.m_Services[key] = service;
+            return key;
+        }
+        public void Register(string serviceName, object service)
+        {
+            CheckName(serviceName);
+            this.m_Services[serviceName] = service;
+        }
+        public void Register<T>(string serviceName, T service) where T : class
+        {
+            CheckName(serviceName);
+            this.m_Services[serviceName] = service;
+        }
+        public void Remove(string serviceName)
+        {
+            CheckName(serviceName);
+            m_Services.Remove(serviceName);
+        }
+        public void Remove<T>(string serviceName) where T : class
+        {
+            CheckName(serviceName);
+            m_Services.Remove(serviceName);
+        }
+        public void RemoveService<T>() where T : class
+        {
+            string useKey = string.Empty;
+            bool has = false;
+            foreach (var service in m_Services)
+            {
+                var use = service.Value as T;
+                if (use != null)
+                {
+                    useKey = service.Key;
+                    has = true;
+                    break;
+                }
+            }
+            if (has)
+            {
+                m_Services.Remove(useKey);
+            }         
+        }
+
+
+        public void LoadServices(string configFile, Func<string, string> dllPathSelector)
+        {
+            List<ServiceConfigItem> serviceItems = ServiceConfigItems.Load(configFile);
+            foreach (var serviceConfigItem in serviceItems)
+            {
+                try
+                {
+                    string serviceName = serviceConfigItem.Name.Trim();
+                    if (string.IsNullOrWhiteSpace(serviceName))
+                    {
+                        serviceName = CreateKey();
+                    }
+                    string childPath = serviceConfigItem.DllPath.Trim();
+                    var path = dllPathSelector(childPath);
+                    if (File.Exists(path))
+                    {
+                        Assembly tempAsembly = Assembly.LoadFrom(path);
+                        m_Services[serviceName] = (tempAsembly.CreateInstance(serviceConfigItem.ClassName.Trim()));
+                    }
+                }
+                catch (Exception ex)
+                {
+                    Debug.Write(ex.Message);
+                }
+            }
+        }
+        public void LoadServices(string configFile)
+        {
+            string baseDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+            LoadServices(configFile, (childPath) => Path.Combine(baseDirectory, childPath));
+        }
+    }
+}

+ 3 - 0
MBI/SAGA.MBI/App.xaml.cs

@@ -12,6 +12,8 @@ using System.Windows;
 using CEFSharpWpf;
 using SAGA.DotNetUtils;
 using SAGA.DotNetUtils.Others;
+using SAGA.MBI.DataArrange;
+using SAGA.MBI.Model;
 using SAGA.MBI.WinView.Login;
 
 namespace SAGA.MBI
@@ -24,6 +26,7 @@ namespace SAGA.MBI
         [STAThread]
         static void Main()
         {
+
             WinLogin win = new WinLogin();
             Application myAp = new Application();
             myAp.ShutdownMode = ShutdownMode.OnExplicitShutdown;

+ 4 - 4
MBI/SAGA.MBI/Calc/CalcContext.cs

@@ -44,7 +44,7 @@ namespace SAGA.MBI.Calc
         public string FloorId { get { return MFloor.Id; } }
         public Document RevitDoc { get; set; }
         [InitAttribute]
-        public ObservableCollection<MSpace> MSpaces { get; set; }
+        public ObservableCollection<MISpace> MSpaces { get; set; }
         [InitAttribute]
         public ObservableCollection<MEquipment> MEquipments { get; set; }
         [InitAttribute]
@@ -91,9 +91,9 @@ namespace SAGA.MBI.Calc
             try
             {
                 //修改空间
-                DalCommon.BatchUpdate(MSpaces);
+                DalSpace.BatchUpdate(MSpaces);
                 //修改设备
-                DalCommon.BatchUpdate(MEquipments);
+                DalEquip.BatchUpdate(MEquipments);
                 //修改部件
                 DalCommon.BatchUpdate(MEquipmentParts);
                 //修改设备所在空间关系
@@ -155,7 +155,7 @@ namespace SAGA.MBI.Calc
             {
                 this.MEquipmentParts.Add(part);
             }
-            else if (mode is MSpace space)
+            else if (mode is MISpace space)
             {
                 this.MSpaces.Add(space);
             }

+ 4 - 4
MBI/SAGA.MBI/Calc/ObjectCalc.cs

@@ -60,7 +60,7 @@ namespace SAGA.MBI.Calc
             foreach (Space space in spaces)
             {
                 if(!space.IsSpace())continue;
-                MSpace mspace = DalSpace.GetSpace(space);
+                MISpace mspace = DalSpace.GetSpace(space);
                 if(mspace==null)continue;
                 mspace.Operator = DocumentChangedOperator.Add;
                 context.MSpaces.Add(mspace);
@@ -87,7 +87,7 @@ namespace SAGA.MBI.Calc
                     var space = fi.GetReferenceSpace();
                     if (space == null) continue;
                     string spaceId = space.GetCloudBIMId();
-                    MSpace mSpace = context.MSpaces.FirstOrDefault(t => t.BimID == spaceId);
+                    MISpace mSpace = context.MSpaces.FirstOrDefault(t => t.BimID == spaceId);
                     if (mSpace != null)
                     {
                         //设备所在空间添加添加一组关系
@@ -107,7 +107,7 @@ namespace SAGA.MBI.Calc
                     var space = fi.GetReferenceSpace();
                     if (space == null) continue;
                     string spaceId = space.GetCloudBIMId();
-                    MSpace mSpace = context.MSpaces.FirstOrDefault(t => t.BimID == spaceId);
+                    MISpace mSpace = context.MSpaces.FirstOrDefault(t => t.BimID == spaceId);
                     if (mSpace != null)
                     {
                         context.RltBeaconinElementSps.Add(new RltBeaconinElementSp(mSpace, mode) { Operator = DocumentChangedOperator.Add });
@@ -130,7 +130,7 @@ namespace SAGA.MBI.Calc
                     var space = fi.GetReferenceSpace();
                     if (space == null) continue;
                     string spaceId = space.GetCloudBIMId();
-                    MSpace mSpace = context.MSpaces.FirstOrDefault(t => t.BimID == spaceId);
+                    MISpace mSpace = context.MSpaces.FirstOrDefault(t => t.BimID == spaceId);
                     if (mSpace != null)
                     {
                         //设备所在空间添加添加一组关系

+ 1 - 1
MBI/SAGA.MBI/Common/CacheAspect.cs

@@ -27,7 +27,7 @@ namespace SAGA.MBI.Common
                     context.Proceed();
                     return context.ReturnValue;
                 },
-                new TimeSpan(12, 30, 0));//30分钟过期
+                new TimeSpan(12, 30, 0));//12小时30分钟过期
             context.ReturnValue = result;
         }
     }

+ 1 - 1
MBI/SAGA.MBI/Common/MBIConst.cs

@@ -28,8 +28,8 @@ namespace SAGA.MBI.Common
 
         public static readonly string MBIImagePath = AppBaseInfo.ImagePath;
         public static readonly string MBIResourcePath = Path.Combine(AppBaseInfo.AppRunPath, "MBIResource");
+        public static readonly string MBIDataDictionaryPath = Path.Combine(MBIResourcePath, "DataDictionary");
         public static readonly string EmptyFilePath = Path.Combine(MBIResourcePath, "EmptyFile\\EmptyProject.rvt");
-        public static readonly string ChangesRelationship = Path.Combine(MBIResourcePath, "EmptyFile\\EmptyProject.rvt");
         public static readonly string BeaconFamilyFilePath = Path.Combine(AppBaseInfo.FamilyPath, "Beacon.rfa");
         public static readonly string SpaceTagFamilyFilePath = Path.Combine(AppBaseInfo.FamilyPath, "空间标记.rfa");
 

+ 29 - 24
MBI/SAGA.MBI/DataArrange/DalCommon.cs

@@ -30,7 +30,7 @@ namespace SAGA.MBI.DataArrange
     /// </summary>
     public class DalCommon
     {
-       
+
         /// <summary>
         /// 获取设备的信息,同时根据bimid,请求云平台id
         /// </summary>
@@ -69,7 +69,7 @@ namespace SAGA.MBI.DataArrange
                 }
             }
 
-            return equipment?? GetDefaultEquipBase(elem);
+            return equipment ?? GetDefaultEquipBase(elem);
         }
         /// <summary>
         /// 获取设备的信息,不请求云平台id
@@ -123,7 +123,7 @@ namespace SAGA.MBI.DataArrange
         public static MRevitEquipBase GetDefaultEquipBase(Element elem)
         {
             if (elem == null) return null;
-            MRevitEquipBaseNull mode =new MRevitEquipBaseNull();
+            MRevitEquipBaseNull mode = new MRevitEquipBaseNull();
             mode.BimID = elem.Id.ToString();
             var family = elem.GetFamily();
             if (family != null)
@@ -163,7 +163,7 @@ namespace SAGA.MBI.DataArrange
         /// <param name="id">岗位id</param>
         /// <param name="bimid"></param>
         /// <returns></returns>
-        public static bool UpdateBimId(string id,string bimid)
+        public static bool UpdateBimId(string id, string bimid)
         {
             //保留,清除BIMID
             JObject jObject = new JObject();
@@ -175,21 +175,26 @@ namespace SAGA.MBI.DataArrange
         /// <summary>
         /// 获取云平台所有revit相关的数据
         /// </summary>
-        public static List<MRevitEquipBase> DownLoadCouldData(string floorId, string[] type=null)
+        public static List<MRevitEquipBase> DownLoadCouldData(string floorId, string[] type = null)
         {
             List<MRevitEquipBase> list = new List<MRevitEquipBase>();
             if (type == null)
-                type = new[] {"Eq", "Ec", "VOBc", "Si"};
-            var typelist = type.ToList();
-            string spacetype = "Si";
-            //空间
-            if (typelist.Contains(spacetype))
+                type = new[] { "Eq", "Ec", "VOBc", "Si" };
+            var goodhandTypes = new[] { "Eq", "Ec", "VOBc" };
+
+            var bygoodhandQuerys = type.Where(t => goodhandTypes.Contains(t)).ToArray();
+            if (bygoodhandQuerys.Any())
             {
-                list.AddRange(SpaceConvert.GetFloorSpaceInfos(floorId));
-                typelist.Remove(spacetype);
+                //通过goodhand后台查询的数据,设备,部件,信标
+                list.AddRange(CommonConvert.FloorQuery_GoodHand(floorId, bygoodhandQuerys));
             }
-            //其它
-            list.AddRange(CommonConvert.FloorQuery(floorId, typelist?.ToArray()));
+            var bySubsetQuerys = type.Where(t => !goodhandTypes.Contains(t)).ToArray();
+            if (bySubsetQuerys.Any())
+            {
+                //通过subset_query查询的数据,空间,业务空间
+                list.AddRange(CommonConvert.FloorQuery_SubSet(floorId,bySubsetQuerys));
+            }
+
             return list;
         }
         /// <summary>
@@ -279,7 +284,7 @@ namespace SAGA.MBI.DataArrange
         {
             string buildingId = DalProjectTree.GetBuildingIdByFloor(floorId);
             return CommonConvert.QueryOutsideObject(null, buildingId, "", RelationConst.EquipinFloorGraphId,
-                RelationConst.EquipinFloorRelationType, -1, new[] {"Eq", "Ec"});
+                RelationConst.EquipinFloorRelationType, -1, new[] { "Eq", "Ec" });
         }
 
         /// <summary>
@@ -288,7 +293,7 @@ namespace SAGA.MBI.DataArrange
         /// <param name="datas"></param>
         public static void BatchUpdate(IEnumerable<MRevitEquipBase> datas)
         {
-            var criterias=new JArray();
+            var criterias = new JArray();
             foreach (MRevitEquipBase data in datas)
             {
                 if (data.Operator == DocumentChangedOperator.Modified)
@@ -380,14 +385,14 @@ namespace SAGA.MBI.DataArrange
                     {
                         list.Add(jobjItem);
                     }
-                }           
+                }
                 #endregion
                 typelist.Remove(spacetype);
             }
             //其它
             if (typelist.Any())
             {
-                var json = CommonRequest.FloorQuery(floorId, type);
+                var json = CommonRequest.FloorQuery_GoodHand(floorId, type);
                 #region 获取除空间外的数据
                 if (json.IsRequestHasItem())
                 {
@@ -396,9 +401,9 @@ namespace SAGA.MBI.DataArrange
                     {
                         list.Add(jobjItem);
                     }
-                } 
+                }
                 #endregion
-            }           
+            }
             return list;
         }
 
@@ -411,7 +416,7 @@ namespace SAGA.MBI.DataArrange
         {
             try
             {
-                var result =CommonRequest.QueryObjectById(id);
+                var result = CommonRequest.QueryObjectById(id);
                 if (!result.IsRequestHasItem())
                 {
                     return null;
@@ -426,7 +431,7 @@ namespace SAGA.MBI.DataArrange
             }
         }
 
-        private static List<MRevitEquipBase> m_AllRevitObjects=null;
+        private static List<MRevitEquipBase> m_AllRevitObjects = null;
         /// <summary>
         /// 在缓存中通过bimid查找
         /// 如果查找不到,重新加载缓存
@@ -440,7 +445,7 @@ namespace SAGA.MBI.DataArrange
             {
                 rbase = m_AllRevitObjects?.FirstOrDefault(t => t.BimID == bimId);
             }
-            if (rbase==null)
+            if (rbase == null)
             {
                 string floorId = bimId.GetFloorId();
                 string buildingId = DalProjectTree.GetBuildingIdByFloor(floorId);
@@ -456,7 +461,7 @@ namespace SAGA.MBI.DataArrange
         /// <returns></returns>
         public static List<MRevitEquipBase> GetAllDutys(string buildingId)
         {
-            return CommonConvert.CacheAllData(buildingId); 
+            return CommonConvert.CacheAllData(buildingId);
         }
 
         /// <summary>

+ 48 - 1
MBI/SAGA.MBI/DataArrange/DalEquip.cs

@@ -9,11 +9,15 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using Autodesk.Revit.DB;
+using DevExpress.Xpf.Bars;
+using Newtonsoft.Json.Linq;
+using SAGA.DotNetUtils;
 using SAGA.DotNetUtils.Extend;
 using SAGA.DotNetUtils.Logger;
 using SAGA.MBI.Common;
 using SAGA.MBI.JsonConvert;
 using SAGA.MBI.Model;
+using SAGA.MBI.RequestData;
 using SAGA.MBI.Tools;
 using SAGA.RevitUtils.Extends;
 
@@ -69,6 +73,49 @@ namespace SAGA.MBI.DataArrange
             return mode;
         }
 
-       
+        /// <summary>
+        /// 批量更新Infos
+        /// </summary>
+        /// <param name="datas"></param>
+        public static void BatchUpdate(IEnumerable<MRevitEquipBase> datas)
+        {
+            var addJArray = new JArray();
+            var delJArray = new JArray();
+            var updateJArray = new JArray();
+            foreach (MRevitEquipBase mode in datas)
+            {
+                switch (mode.Operator)
+                {
+                    case DocumentChangedOperator.Add:
+                        JObject addJObject = new JObject();
+                        addJObject.Add("floor_id", mode.FloorId);
+                        addJObject.Add("building_id", DalProjectTree.GetBuildingIdByFloor(mode.FloorId));
+                        addJObject.Add("equipment_category", mode.EquipClassCode);
+                        addJObject.Add("infos", mode.GetInfosJObject());
+                        addJArray.Add(addJObject);
+                        break;
+                    case DocumentChangedOperator.Delete:
+                        JObject delJObject=new JObject();
+                        delJObject.Add("id",mode.Id);
+                        delJArray.Add(delJObject);
+                        break;
+                    case DocumentChangedOperator.Modified:
+                        JObject criteria = CommonConvert.GetUpdateInfosJObject(mode.Id, mode.GetInfosJObject());
+                        updateJArray.Add(criteria);
+                        break;
+                    case DocumentChangedOperator.None:
+                        break;
+                    default:
+                        mode.AddorUpdateObject();
+                        break;
+                }
+            }
+            if (addJArray.Count > 0)
+                EquipmentRequest.BatchAdd(addJArray);
+            if (delJArray.Count > 0)
+                EquipmentRequest.BatchDel(delJArray);
+            if (updateJArray.Count > 0)
+                CommonRequest.BatchUpdate(updateJArray);
+        }
     }
 }

+ 62 - 0
MBI/SAGA.MBI/DataArrange/DalInfoCode.cs

@@ -0,0 +1,62 @@
+/* ==============================================================================
+ * 功能描述:组件编码
+ * 创 建 者:Garrett
+ * 创建日期:2019/1/17 10:11:41
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SAGA.DotNetUtils.Serializer;
+using SAGA.MBI.Common;
+using SAGA.MBI.FileStream;
+using SAGA.MBI.Model;
+
+namespace SAGA.MBI.DataArrange
+{
+    /// <summary>
+    /// DalEquipCode
+    /// </summary>
+    class DalInfoCode
+    {
+        /// <summary>
+        /// 初始化组件对照表
+        /// </summary>
+        public static void Init()
+        {
+            var codes=new List<ComponentCodeToInputType>();
+            codes.Add(new ComponentCodeToInputType(){ComponentCode = "A1",InputType = "TextBox_Double_A1" });
+            codes.Add(new ComponentCodeToInputType() { ComponentCode = "A2", InputType = "Textbox_DoubleUnit_A2" });
+            codes.Add(new ComponentCodeToInputType() { ComponentCode = "B1", InputType = "TextBox_String_B1" });
+            codes.Add(new ComponentCodeToInputType() { ComponentCode = "C5", InputType = "DataTime_Date_C5" });
+            codes.Add(new ComponentCodeToInputType() { ComponentCode = "D1", InputType = "Enum_D1" });
+            string path = MBIConst.MBIDataDictionaryPath;
+            string fileName = "ComponentCodeToInputType.xml";
+            SerializerByXml.SerializeAndSave(path, fileName, codes);
+        }
+        /// <summary>
+        /// 读取组件对照表
+        /// </summary>
+        /// <returns></returns>
+        [CacheAspect]
+        public static List<ComponentCodeToInputType> Read()
+        {
+            string path = MBIConst.MBIDataDictionaryPath;
+            string fileName = "ComponentCodeToInputType.xml";
+            return SerializerByXml.DeserializeList<ComponentCodeToInputType>(path, fileName);
+        }
+
+        /// <summary>
+        /// 由组件编码获取Revit输入类型
+        /// </summary>
+        /// <param name="componentCode"></param>
+        /// <returns></returns>
+        public static string GetInputType(string componentCode)
+        {
+            var codes = Read();
+            var item = codes.FirstOrDefault(t => t.ComponentCode == componentCode);
+            return item?.InputType;
+        }
+    }
+}

+ 3 - 3
MBI/SAGA.MBI/DataArrange/DalModeFileManange.cs

@@ -257,7 +257,7 @@ namespace SAGA.MBI.DataArrange
             if (isExceptSpace)
             {
                 var spaces = oldContext.MSpaces.Except(newContext.MSpaces,
-                    new CommonEqualComparer<MSpace>((a, b) => { return a.BimID == b.BimID; }));
+                    new CommonEqualComparer<MISpace>((a, b) => { return a.BimID == b.BimID; }));
                 context.MSpaces.AddRange(spaces);
             }
             else
@@ -290,7 +290,7 @@ namespace SAGA.MBI.DataArrange
             if (isExceptSpace)
             {
                 var spaces = oldContext.MSpaces.Intersect(newContext.MSpaces,
-                    new CommonEqualComparer<MSpace>((a, b) => { return a.BimID == b.BimID; }));
+                    new CommonEqualComparer<MISpace>((a, b) => { return a.BimID == b.BimID; }));
                 context.MSpaces.AddRange(spaces);
             }
             else
@@ -322,7 +322,7 @@ namespace SAGA.MBI.DataArrange
             if (isExceptSpace)
             {
                 var spaces = newContext.MSpaces.Except(oldContext.MSpaces,
-                    new CommonEqualComparer<MSpace>((a, b) => { return a.BimID == b.BimID; }));
+                    new CommonEqualComparer<MISpace>((a, b) => { return a.BimID == b.BimID; }));
                 context.MSpaces.AddRange(spaces);
                 //处理设备所在空间
                 context.RltEquipInSpaces.AddRange(newContext.RltEquipInSpaces.Where(t => context.MEquipments.Select(tt => tt.BimID).Contains((t)?.MEquipment.BimID)));

+ 76 - 7
MBI/SAGA.MBI/DataArrange/DalSpace.cs

@@ -14,9 +14,11 @@ using SAGA.MBI.JsonConvert;
 using SAGA.MBI.Model;
 using Autodesk.Revit.DB;
 using Autodesk.Revit.DB.Mechanical;
+using Newtonsoft.Json.Linq;
 using SAGA.DotNetUtils.Extend;
 using SAGA.DotNetUtils.Logger;
 using SAGA.MBI.Common;
+using SAGA.MBI.RequestData;
 using SAGA.MBI.Tools;
 using SAGA.RevitUtils.Extends;
 
@@ -33,10 +35,10 @@ namespace SAGA.MBI.DataArrange
         /// </summary>
         /// <param name="elem"></param>
         /// <returns></returns>
-        public static MSpace GetSpaceQueryId(Element elem)
+        public static MISpace GetSpaceQueryId(Element elem)
         {
             if (!elem.IsSpace()) return null;
-            MSpace mspace = GetSpace(elem);
+            MISpace mspace = GetSpace(elem);
             if (mspace == null) return null;
             //可能需要读取其它数据
             SpaceConvert.QuerySpaceInfo(mspace);
@@ -48,13 +50,13 @@ namespace SAGA.MBI.DataArrange
         /// </summary>
         /// <param name="elem"></param>
         /// <returns></returns>
-        public static MSpace GetSpace(Element elem)
+        public static MISpace GetSpace(Element elem)
         {
             if (!elem.IsSpace()) return null;
             Space space = elem as Space;
             string floorId = elem.Document.PathName.GetFileName();
             var bimId= space.GetCloudBIMId();
-            MSpace mspace = new MSpace(floorId,bimId);
+            MISpace mspace = new MISpace(floorId,bimId);
             //可能需要读取其它数据
             mspace.LocalName = GetSpaceDefaultName(space);
             //mspace.PlanePath = CommonTool.ConvertSpaceEdgesToStr(space.GetPlaneVertexes());
@@ -84,12 +86,79 @@ namespace SAGA.MBI.DataArrange
         /// </summary>
         /// <param name="id"></param>
         /// <returns></returns>
-        public static MSpace GetMSpace(string equipId)
+        public static MISpace GetMSpace(string equipId)
         {
-            MSpace mSpace = null;
+            MISpace mSpace = null;
             var spaceId = RelationConvert.GetSpaceByRelationElementInSpace(equipId);
-            mSpace = DalCommon.QueryObjectById(spaceId) as MSpace;
+            mSpace = DalCommon.QueryObjectById(spaceId) as MISpace;
             return mSpace;
         }
+
+        /// <summary>
+        /// 获取业务空间的类型
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public static List<GraphRelationType> GetBusinessSpaceTypes()
+        {
+            List<GraphRelationType> list = new List<GraphRelationType>();
+            var json = SpaceRequest.GetBusinessSpaceTypes();
+            if (!json.IsRequestHasItem()) return list;
+            JObject jObject = JObject.Parse(json);
+            foreach (JObject jobjItem in jObject["Content"])
+            {
+                GraphRelationType item=new GraphRelationType();
+                item.Name = jobjItem.GetValueEx("name");
+                item.Code = jobjItem.GetValueEx("code");
+                item.Rel_Type = jobjItem.GetValueEx("rel_type");
+                list.Add(item);
+            }
+            return list;
+        }
+
+        /// <summary>
+        /// 批量更新Infos
+        /// </summary>
+        /// <param name="datas"></param>
+        public static void BatchUpdate(IEnumerable<MRevitEquipBase> datas)
+        {
+            var addJArray = new JArray();
+            var delJArray = new JArray();
+            var updateJArray = new JArray();
+            foreach (MRevitEquipBase mode in datas)
+            {
+                switch (mode.Operator)
+                {
+                    case DocumentChangedOperator.Add:
+                        JObject addJObject = new JObject();
+                        addJObject.Add("floor_id", mode.FloorId);
+                        addJObject.Add("building_id", DalProjectTree.GetBuildingIdByFloor(mode.FloorId));
+                        addJObject.Add("infos", mode.GetInfosJObject());
+                        addJArray.Add(addJObject);
+                        break;
+                    //case DocumentChangedOperator.Delete:
+                    //    JObject delJObject = new JObject();
+                    //    delJObject.Add("id", mode.Id);
+                    //    delJArray.Add(delJObject);
+                    //    break;
+                    case DocumentChangedOperator.Modified:
+                        JObject criteria = CommonConvert.GetUpdateInfosJObject(mode.Id, mode.GetInfosJObject());
+                        updateJArray.Add(criteria);
+                        break;
+                    case DocumentChangedOperator.None:
+                        break;
+                    default:
+                        mode.AddorUpdateObject();
+                        break;
+                }
+            }
+            if (addJArray.Count > 0)
+                SpaceRequest.BatchAdd(addJArray);
+            if (delJArray.Count > 0)
+                SpaceRequest.BatchDel(delJArray);
+            if (updateJArray.Count > 0)
+                CommonRequest.BatchUpdate(updateJArray);
+        }
     }
 }
+

+ 5 - 4
MBI/SAGA.MBI/DataArrange/DalVisionOperate.cs

@@ -14,6 +14,7 @@ using SAGA.DotNetUtils.Encrypt;
 using SAGA.DotNetUtils.Extend;
 using SAGA.DotNetUtils.Logger;
 using SAGA.DotNetUtils.Others;
+using SAGA.DotNetUtils.Serializer;
 using SAGA.MBI.Common;
 using SAGA.MBI.FileStream;
 using SAGA.MBI.JsonConvert;
@@ -42,7 +43,7 @@ namespace SAGA.MBI.DataArrange
             get
             {
                 if (m_LocalVisions == null)
-                    m_LocalVisions = FileOperateBase.DeserializeList<RevitFileVision>(LocalVisionFilePath, FileVisionName);
+                    m_LocalVisions = SerializerByXml.DeserializeList<RevitFileVision>(LocalVisionFilePath, FileVisionName);
                 return m_LocalVisions;
             }
         }
@@ -212,7 +213,7 @@ namespace SAGA.MBI.DataArrange
             string path = Path.Combine(LocalVisionFilePath, FileVisionName);
             //保存FileVision文件到工作区
             if (!File.Exists(path))
-                FileOperateBase.Serialize(LocalVisionFilePath, FileVisionName, LocalVisions);
+                SerializerByXml.SerializeAndSave(LocalVisionFilePath, FileVisionName, LocalVisions);
         }
         /// <summary>
         /// 保存版本配置文件到本地
@@ -223,7 +224,7 @@ namespace SAGA.MBI.DataArrange
             lvision.Vision = cvision.Vision;
             lvision.MD5Code = cvision.MD5Code;
             //保存FileVision文件到工作区
-            FileOperateBase.Serialize(LocalVisionFilePath, FileVisionName, LocalVisions);
+            SerializerByXml.SerializeAndSave(LocalVisionFilePath, FileVisionName, LocalVisions);
         }
         /// <summary>
         /// 删除本层的版本数据
@@ -233,7 +234,7 @@ namespace SAGA.MBI.DataArrange
         {
             LocalVisions.RemoveAll(t => t.FileName == floorid);
             //保存FileVision文件到工作区
-            FileOperateBase.Serialize(LocalVisionFilePath, FileVisionName, LocalVisions);
+            SerializerByXml.SerializeAndSave(LocalVisionFilePath, FileVisionName, LocalVisions);
             FloorVisionConvert.Delete(floorid);
         }
     }

+ 12 - 10
MBI/SAGA.MBI/Extend/ElementExtend.cs

@@ -109,16 +109,18 @@ namespace SAGA.MBI.Tools
         /// <returns></returns>
         public static XYZ GetLocationPointMBIXYZ(this Element element)
         {
-            //定位点不可靠,未来可能会更改为Box的中心点
-            XYZ bimXyz = element.GetLocationPoint();
-            if (element is FamilyInstance fi)
-            {
-                var family = fi.GetFamily();
-                if (family.IsInPlace)
-                {
-                    bimXyz = fi.GetBoxCenter();
-                }
-            }
+            ////定位点不可靠,未来可能会更改为Box的中心点
+            //XYZ bimXyz = element.GetLocationPoint();
+            //if (element is FamilyInstance fi)
+            //{
+            //    var family = fi.GetFamily();
+            //    if (family.IsInPlace)
+            //    {
+            //        bimXyz = fi.GetBoxCenter();
+            //    }
+            //}
+            //定位点改为Box中心点 
+            XYZ bimXyz = element.GetBoxCenter();
 
             return bimXyz;
         }

+ 0 - 251
MBI/SAGA.MBI/FileStream/FileOperateBase.cs

@@ -1,251 +0,0 @@
-/* ==============================================================================
- * 功能描述:Class1  
- * 创 建 者:Garrett
- * 创建日期:2018/3/24 16:03:19
- * ==============================================================================*/
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.Serialization.Formatters.Binary;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows.Forms;
-using System.Xml.Serialization;
-using SAGA.DotNetUtils;
-using SAGA.MBI.Common;
-using SAGA.MBI.Model;
-using SAGA.MBI.RequestData;
-
-namespace SAGA.MBI.FileStream
-{
-    /// <summary>
-    /// Class1
-    /// </summary>
-    public class FileOperateBase
-    {
-        /// <summary>
-        /// 序列化并保存
-        /// 类必须标记为可序列化[Serializable]
-        /// </summary>
-        public static void Serialize(string filePath, string fileName, object floorSequences)
-        {
-            string path = Path.Combine(filePath, fileName);
-
-            if (!Directory.Exists(filePath))
-                Directory.CreateDirectory(filePath);
-
-            using (System.IO.FileStream fs = new System.IO.FileStream(path, FileMode.OpenOrCreate))
-            {
-                fs.SetLength(0);
-                using (StreamWriter sw = new StreamWriter(fs))
-                {
-                    try
-                    {
-                        fs.Position = 0;
-                        var jsonData = Serialize(floorSequences);
-                        //var jsonData = Newtonsoft_Common.SerializeObjToJson(new Serialization<T>(floorSequences));
-                        sw.Write(jsonData);
-                        //BinaryFormatter bf = new BinaryFormatter();
-                        //bf.Serialize(fs, floorSequences); //复制到流中
-                        //MessageBox.Show("保存成功!");
-                        //上传数据
-                    }
-                    catch (Exception ex)
-                    {
-                        MessageBox.Show("保存失败!!!" + ex.ToString());
-                    }
-                    finally
-                    {
-                        sw.Flush();
-                        sw.Close();
-                        fs.Close();
-                    }
-                }
-            }
-
-        }
-        /// <summary>
-        /// 序列化并保存-并上传
-        /// </summary>
-        public static void SerializeAndUpLoad<T>(string filePath, string fileName, List<T> floorSequences)
-        {
-            try
-            {
-                Serialize(filePath, fileName, floorSequences);
-                UpLoadFileRequest.UpLoadRevitFile(filePath, fileName);
-            }
-            catch (Exception ex)
-            {
-                MessageBox.Show("读取失败!!!" + ex.ToString());
-            }
-        }
-        /// <summary>
-        /// 反序列化
-        /// </summary>
-        /// <returns></returns>
-        public static T Deserialize<T>(string filePath, string fileName)
-        {
-            T floorSequences = default(T);
-            string path = Path.Combine(filePath, fileName);
-            if (!File.Exists(path))
-                return floorSequences;
-            try
-            {
-                var obj = Desrialize<T>(path);
-                floorSequences = obj;
-                //var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<List<T>>(jsonData);
-            }
-            catch (Exception ex)
-            {
-                //MessageBox.Show("读取失败!!!"+ex.ToString());
-
-            }
-            finally
-            {
-            }
-            return floorSequences;
-        }
-        /// <summary>
-        /// 反序列化
-        /// </summary>
-        /// <returns></returns>
-        public static List<T> DeserializeList<T>(string filePath, string fileName)
-        {
-            List<T> floorSequences = new List<T>();
-            string path = Path.Combine(filePath, fileName);
-            if (!File.Exists(path))
-                return floorSequences;
-            using (StreamReader sr = new StreamReader(path, Encoding.Default))
-            {
-
-                try
-                {
-                    var obj = Desrialize<List<T>>(path);
-                    //var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<List<T>>(jsonData);
-
-                    var objs = (IEnumerable)obj;
-                    if (objs != null)
-                        floorSequences = objs.Cast<T>().ToList();
-                }
-                catch (Exception ex)
-                {
-                    //MessageBox.Show("读取失败!!!"+ex.ToString());
-
-                }
-                finally
-                {
-                    sr.Close();
-                }
-            }
-            return floorSequences;
-        }
-        /// <summary>
-        /// 下载并反序列化
-        /// </summary>
-        /// <returns></returns>
-        public static List<T> DeserializeAndDownLoad<T>(string filePath, string fileName)
-        {
-            List<T> floorSequences = new List<T>();
-            try
-            {
-                UpLoadFileRequest.DownLoadRevitFile(filePath, fileName);
-                return DeserializeList<T>(filePath, fileName);
-            }
-            catch (Exception ex)
-            {
-                MessageBox.Show("读取失败!!!" + ex.ToString());
-            }
-            return floorSequences;
-        }
-        /// <summary>
-        /// 序列化成xml字符串
-        /// </summary>
-        /// <param name="obj"></param>
-        /// <returns>序列化后的字符串</returns>
-        public static string Serialize(object obj)
-        {
-            string str = "";
-            XmlSerializer xs = new XmlSerializer(obj.GetType());
-            using (MemoryStream ms = new MemoryStream())
-            {
-                try
-                {
-                    System.Xml.XmlTextWriter xtw = new System.Xml.XmlTextWriter(ms, System.Text.Encoding.UTF8);
-                    xtw.Formatting = System.Xml.Formatting.Indented;
-                    xs.Serialize(xtw, obj);
-                    ms.Seek(0, SeekOrigin.Begin);
-                    using (StreamReader sr = new StreamReader(ms))
-                    {
-                        try
-                        {
-                            str = sr.ReadToEnd();
-                            xtw.Close();
-                            ms.Close();
-                        }
-                        catch (Exception e)
-                        {
-                            Console.WriteLine(e);
-                        }
-                        finally
-                        {
-                            xtw.Close();
-                            sr.Close();
-                        }
-
-                    }
-                }
-                catch (Exception e)
-                {
-                    Console.WriteLine(e);
-                }
-                finally
-                {
-                    ms.Close();
-                }
-
-            }
-            return str;
-        }
-        /// <summary>
-        /// 反序列化方法
-        /// </summary>
-        /// <typeparam name="T">反序列化对象类型</typeparam>
-        /// <param name="xml">反序列化字符串或者xml文件路径</param>
-        /// <returns></returns>
-        public static T Desrialize<T>(string xml)
-        {
-            T obj = default(T);
-            XmlSerializer xs = new XmlSerializer(typeof(T));
-            TextReader tr = null;
-            try
-            {
-
-                if (!File.Exists(xml))
-                {
-                    tr = new StringReader(xml);
-                }
-                else
-                {
-                    tr = new StreamReader(xml);
-                }
-                using (tr)
-                {
-                    obj = (T)xs.Deserialize(tr);
-                }
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine(e);
-            }
-            finally
-            {
-                tr?.Close();
-            }
-            return obj;
-        }
-
-    }
-}

+ 3 - 2
MBI/SAGA.MBI/FileStream/ProjectDirOperate.cs

@@ -11,6 +11,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using SAGA.DotNetUtils;
+using SAGA.DotNetUtils.Serializer;
 using SAGA.MBI.Common;
 using SAGA.MBI.JsonConvert;
 using SAGA.MBI.Model;
@@ -167,7 +168,7 @@ namespace SAGA.MBI.FileStream
         {
             string filePath = MBIConst.MBITempSettingPath;
             string fileName = MBIConst.ManageCur;
-            FileOperateBase.Serialize(filePath, fileName, MBIControl.ManageInfo);
+            SerializerByXml.SerializeAndSave(filePath, fileName, MBIControl.ManageInfo);
         }
         /// <summary>
         /// 从本地读取当前管理员信息
@@ -177,7 +178,7 @@ namespace SAGA.MBI.FileStream
         {
             string filePath = MBIConst.MBITempSettingPath;
             string fileName = MBIConst.ManageCur;
-            ManageInfo project = FileOperateBase.Deserialize<ManageInfo>(filePath, fileName);
+            ManageInfo project = SerializerByXml.Deserialize<ManageInfo>(filePath, fileName);
             return project;
         }
 

+ 57 - 75
MBI/SAGA.MBI/Html5Command.cs

@@ -4,42 +4,52 @@
  * 创建日期:2018/3/27 11:42:20
  * ==============================================================================*/
 
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text.RegularExpressions;
-using System.Windows;
 using Autodesk.Revit.Attributes;
 using Autodesk.Revit.DB;
-using Autodesk.Revit.DB.ExtensibleStorage;
-using Autodesk.Revit.DB.Mechanical;
 using Autodesk.Revit.UI;
 using CEFSharpWpf;
-using SAGA.DotNetUtils;
-using SAGA.DotNetUtils.Extend;
-using SAGA.DotNetUtils.Logger;
 using SAGA.MBI.Common;
-using SAGA.MBI.DataArrange;
-using SAGA.MBI.Login;
-using SAGA.MBI.Model;
-using SAGA.MBI.Tools;
-using SAGA.MBI.WinView;
-using SAGA.MBI.WinView.BeModingDutyList;
-using SAGA.MBI.WinView.Login;
-using SAGA.MBI.WinView.ModeInfoMaintenance;
-using SAGA.MBI.WinView.PositionBeaconModeling;
-using SAGA.MBI.WinView.Space;
-using SAGA.MBI.WinView.Upload;
 using SAGA.RevitUtils;
 using SAGA.RevitUtils.Extends;
-using SAGA.RevitUtils.Windows;
-using Application = Autodesk.Revit.Creation.Application;
-using Visibility = System.Windows.Visibility;
+using System;
 
 namespace SAGA.MBI
 {
+    #region 资产及扫楼数据整理
+    /// <summary>
+    /// 资产清单
+    /// </summary>
+    [Transaction(TransactionMode.Manual)]
+    [Regeneration(RegenerationOption.Manual)]
+    [Journaling(JournalingMode.UsingCommandData)]
+    public class AssetListCommand : ExternalCommand
+    {
+        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
+        {
+            try
+            {
+                //http://192.168.20.86:8091/#/assetsList?projId=Pj1101080001&secret=123&userId=*****
+                string url = $"{MBIConst.Html5ScanLocalHost}assetsList?projId={MBIControl.ProjectCur.Id}&secret={MBIConst.ProjectSecret}&userId={MBIControl.ManageInfo.Person_Id}";
+                var win = WinBrowser.Instance;
+                win.Show(url, "资产清单");
+                win.Height = 854;
+                win.Width = 1530;
+                win.Left = 320;
+                win.Top = 190;
+            }
+            catch (Exception e)
+            {
+                MessageShow.Show(e);
+                return Result.Cancelled;
+            }
+            return Result.Succeeded;
+        }
 
+        public override bool IsCommandAvailable(UIApplication applicationData, CategorySet selectedCategories)
+        {
+            return true;
+        }
+    }
     /// <summary>
     /// 扫楼日志页
     /// </summary>
@@ -55,7 +65,7 @@ namespace SAGA.MBI
                 //win.ShowDialog();
 
                 string url = $"{MBIConst.Html5ScanLocalHost}buildLog?projId={MBIControl.ProjectCur.Id}&userId={MBIControl.ManageInfo.Person_Id}";
-                
+
                 var win = WinBrowser.Instance;
                 win.Show(url, "扫楼日志");
                 win.Height = 854;
@@ -220,8 +230,7 @@ namespace SAGA.MBI
         {
             try
             {
-                string url = $"{MBIConst.Html5ScanLocalHost}buildFamily?projId={MBIControl.ProjectCur.Id}&userId={MBIControl.ManageInfo.Person_Id}";
-
+                string url = $"{MBIConst.Html5ScanLocalHost}buildFamily?projId={MBIControl.ProjectCur.Id}&userId={MBIControl.ManageInfo.Person_Id}&secret={MBIControl.ProjectCur.Password}";
                 var win = WinBrowser.Instance;
                 win.Show(url, "扫楼设置App信息点");
                 win.Height = 854;
@@ -246,6 +255,9 @@ namespace SAGA.MBI
             return true;
         }
     }
+    #endregion
+
+
 
     /// <summary>
     /// 楼层平面图管理
@@ -286,14 +298,15 @@ namespace SAGA.MBI
             return true;
         }
     }
-
+    #region 设备空间台账
+    
     /// <summary>
     /// 业务空间清单
     /// </summary>
     [Transaction(TransactionMode.Manual)]
     [Regeneration(RegenerationOption.Manual)]
     [Journaling(JournalingMode.UsingCommandData)]
-    public class SpaceListCommand : ExternalCommand, IExternalCommandAvailability
+    public class SpaceListCommand : ExternalCommand
     {
         public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
         {
@@ -321,28 +334,27 @@ namespace SAGA.MBI
         /// Onlys show the dialog when a document is open, as Dockable dialogs are only available
         /// when a document is open.
         /// </summary>
-        public bool IsCommandAvailable(UIApplication applicationData, CategorySet selectedCategories)
+        public override bool IsCommandAvailable(UIApplication applicationData, CategorySet selectedCategories)
         {
             return true;
         }
     }
-
     /// <summary>
-    /// 资产管理
+    /// 设备清单
     /// </summary>
     [Transaction(TransactionMode.Manual)]
     [Regeneration(RegenerationOption.Manual)]
     [Journaling(JournalingMode.UsingCommandData)]
-    public class AssetManagerCommand : ExternalCommand
+    public class EquipmentListCommand : ExternalCommand
     {
         public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
         {
             try
             {
-                //http://192.168.20.86:8091/#/assetsList?projId=Pj1101080001&secret=123
-                string url = $"{MBIConst.Html5ScanLocalHost}assetsList?projId={MBIControl.ProjectCur.Id}&secret={MBIConst.ProjectSecret}";
+                //http://192.168.20.86:8091/#/deviceList?projId=Pj1101080001&secret=123&userId=*****
+                string url = $"{MBIConst.Html5ScanLocalHost}deviceList?projId={MBIControl.ProjectCur.Id}&secret={MBIConst.ProjectSecret}&userId={MBIControl.ManageInfo.Person_Id}";
                 var win = WinBrowser.Instance;
-                win.Show(url, "资产管理");
+                win.Show(url, "设备清单");
                 win.Height = 854;
                 win.Width = 1530;
                 win.Left = 320;
@@ -363,21 +375,21 @@ namespace SAGA.MBI
     }
 
     /// <summary>
-    /// 设备管理
+    /// 系统清单
     /// </summary>
     [Transaction(TransactionMode.Manual)]
     [Regeneration(RegenerationOption.Manual)]
     [Journaling(JournalingMode.UsingCommandData)]
-    public class EquipmentManagerCommand : ExternalCommand
+    public class SystemListCommand : ExternalCommand
     {
         public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
         {
             try
             {
-                //http://192.168.20.86:8091/#/deviceList?projId=Pj1101080001&secret=123
-                string url = $"{MBIConst.Html5ScanLocalHost}deviceList?projId={MBIControl.ProjectCur.Id}&secret={MBIConst.ProjectSecret}";
+                //http://192.168.20.86:8091/#/systemList?projId=Pj1101080001&secret=123&userId=*****
+                string url = $"{MBIConst.Html5ScanLocalHost}systemList?projId={MBIControl.ProjectCur.Id}&secret={MBIConst.ProjectSecret}&userId={MBIControl.ManageInfo.Person_Id}";
                 var win = WinBrowser.Instance;
-                win.Show(url, "资产管理");
+                win.Show(url, "系统清单");
                 win.Height = 854;
                 win.Width = 1530;
                 win.Left = 320;
@@ -396,39 +408,9 @@ namespace SAGA.MBI
             return true;
         }
     }
+    #endregion
 
-    /// <summary>
-    /// 系统管理
-    /// </summary>
-    [Transaction(TransactionMode.Manual)]
-    [Regeneration(RegenerationOption.Manual)]
-    [Journaling(JournalingMode.UsingCommandData)]
-    public class SystemManagerCommand : ExternalCommand
-    {
-        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
-        {
-            try
-            {
-                //http://192.168.20.86:8091/#/systemList?projId=Pj1101080001&secret=123
-                string url = $"{MBIConst.Html5ScanLocalHost}systemList?projId={MBIControl.ProjectCur.Id}&secret={MBIConst.ProjectSecret}";
-                var win = WinBrowser.Instance;
-                win.Show(url, "资产管理");
-                win.Height = 854;
-                win.Width = 1530;
-                win.Left = 320;
-                win.Top = 190;
-            }
-            catch (Exception e)
-            {
-                MessageShow.Show(e);
-                return Result.Cancelled;
-            }
-            return Result.Succeeded;
-        }
+   
 
-        public override bool IsCommandAvailable(UIApplication applicationData, CategorySet selectedCategories)
-        {
-            return true;
-        }
-    }
+  
 }

+ 47 - 4
MBI/SAGA.MBI/JsonConvert/CommonConvert.cs

@@ -66,13 +66,52 @@ namespace SAGA.MBI.RequestData
             return list;
         }
         /// <summary>
-        /// 查询楼层下的设备/部件/信标
+        /// 查询楼层下的设备/部件/信标,
+        /// "Eq", "Ec", "VOBc"
         /// </summary>
         /// <returns></returns>
-        public static List<MRevitEquipBase> FloorQuery(string floorId, string[] type)
+        public static List<MRevitEquipBase> FloorQuery_GoodHand(string floorId, string[] type)
         {
             List<MRevitEquipBase> list = new List<MRevitEquipBase>();
-            var json = CommonRequest.FloorQuery(floorId, type);
+            var json = CommonRequest.FloorQuery_GoodHand(floorId, type);
+            if (!json.IsRequestHasItem()) return list;
+            JObject jObject = JObject.Parse(json);
+            foreach (JObject jobjItem in jObject["Content"])
+            {
+                var mode = JsonToEquipBase(floorId, jobjItem);
+                if (mode != null)
+                    list.Add(mode);
+            }
+            return list;
+        }
+        /// <summary>
+        /// 查询楼层下的空间,业务空间,
+        /// "Eq", "Ec", "VOBc"
+        /// </summary>
+        /// <returns></returns>
+        public static List<MRevitEquipBase> FloorQuery_SubSet(string floorId, string[] type)
+        {
+            List<MRevitEquipBase> list = new List<MRevitEquipBase>();
+            var json = CommonRequest.QueryObjectByInfos(floorId,new JObject(), type);
+            if (!json.IsRequestHasItem()) return list;
+            JObject jObject = JObject.Parse(json);
+            foreach (JObject jobjItem in jObject["Content"])
+            {
+                var mode = JsonToEquipBase(floorId, jobjItem);
+                if (mode != null)
+                    list.Add(mode);
+            }
+            return list;
+        }
+        /// <summary>
+        /// 查询楼层下的空间,业务空间,
+        /// "Eq", "Ec", "VOBc"
+        /// </summary>
+        /// <returns></returns>
+        public static List<MRevitEquipBase> FloorQuery_SubSet(string floorId,JObject infoObject, string[] type)
+        {
+            List<MRevitEquipBase> list = new List<MRevitEquipBase>();
+            var json = CommonRequest.QueryObjectByInfos(floorId, infoObject, type);
             if (!json.IsRequestHasItem()) return list;
             JObject jObject = JObject.Parse(json);
             foreach (JObject jobjItem in jObject["Content"])
@@ -125,7 +164,11 @@ namespace SAGA.MBI.RequestData
                 }
                 else if (id.StartsWith("Si"))
                 {
-                    mode = new MSpace(floorId, bimId);
+                    mode = new MISpace(floorId, bimId);
+                }
+                else if (id.StartsWith("Sp"))
+                {
+                    mode = new MBSpace(floorId, bimId);
                 }
                 else if (id.StartsWith("VOBc"))
                 {

+ 7 - 105
MBI/SAGA.MBI/JsonConvert/PEPCodeConvert.cs

@@ -12,6 +12,7 @@ using Newtonsoft.Json.Linq;
 using SAGA.DotNetUtils.Extend;
 using SAGA.DotNetUtils.Http;
 using SAGA.MBI.Common;
+using SAGA.MBI.DataArrange;
 using SAGA.MBI.Model;
 using SAGA.MBI.RequestData;
 using SAGA.MBI.Tools;
@@ -36,7 +37,7 @@ namespace SAGA.MBI.JsonConvert
             if (tb == null)
             {
                 //暂时只处理独有的信息点
-                tb = code==MBIConst.SpaceCode? DataPlatFormSpaceInfos(code) : DataPlatFormSysOrEqInfos(code);
+                tb =  DataPlatFormSysOrEqInfos(code);
                 tbs.Add(tb);
             }
             return tb;
@@ -50,73 +51,8 @@ namespace SAGA.MBI.JsonConvert
             PropertyDefineTb tb = new PropertyDefineTb(code);
             try
             {
-                //控制是否显示
-                var json = PEPCodeRequest.SaasSysOrEqInfos(code);
-                if (json.IsSuccessRequest())
-                {
-                    JObject jObject = JObject.Parse(json);
-                    foreach (JObject subj in jObject["Content"])
-                    {
-                        PropertyDefineItem item = new PropertyDefineItem();
-                        item.Category = (string)subj["firstTag"];
-                        item.SubCategory = (string)subj["secondTag"];
-                        item.Name = (string)subj["info_point_code"];
-                        item.CodeName = (string)subj["infopoint_code"];
-                        item.Unit = (string)subj["unit"];
-                        item.Type = (string)subj["dataType"];
-                        item.InputType = (string)subj["base_cmpt_code"]; 
-                        item.EnumSource = subj.GetValueEx("dataSource");
-                        item.Remark = (string)subj["note"];
-                        item.Classification = (string)subj["classification"];
-                        item.IsShow = (string)subj["is_mapped"]=="1";
-                        item.CollectionCmptCode = (string)subj["collection_cmpt_code"];
-                        tb.PropertyDefineItems.Add(item);
-                    }
-                }
-                ////获取自定义信息点
-                string json2 = PEPCodeRequest.UserDefineSysOrEqInfos(code);
-
-                if (json2.IsSuccessRequest())
-                {
-                    JObject jObject = JObject.Parse(json2);
-                    foreach (JObject subj in jObject["Content"])
-                    {
-                        PropertyDefineItem item = new PropertyDefineItem();
-                        item.Category = (string)subj["firstTag"];
-                        item.SubCategory = (string)subj["secondTag"];
-                        item.Name = (string)subj["infoPointName"];
-                        item.CodeName = (string)subj["infoPointCode"];
-                        item.Unit = (string)subj["unit"];
-                        item.Type = (string)subj["dataType"];
-                        item.InputType = (string)subj["inputMode"];
-                        item.EnumSource = subj.GetValueEx("dataSource");
-                        item.Remark = (string)subj["note"];
-                        item.IsShow = true;
-                        tb.PropertyDefineItems.Add(item);
-                    }
-                }
-            }
-            catch (Exception e)
-            {
-                MessageShow.Show(e);
-            }
-
-            return tb;
-        }
-
-        /// <summary>
-        /// 数据平台系统和设备的完整信息点
-        /// </summary>
-        /// <returns></returns>
-        public static PropertyDefineTb DataPlatFormSpaceInfos(string code)
-        {
-            PropertyDefineTb tb = new PropertyDefineTb(code);
-            try
-            {
-                var componentRels = SaasQueryAllComponentRel();
-                //获取所有的属性
-                string json = PEPCodeRequest.InfocodeComplex_query(code,true);
-
+                //控制是否显示,包含自定义信息点
+                var json = PEPCodeRequest.InfoCodeQuery(code);
                 if (json.IsSuccessRequest())
                 {
                     JObject jObject = JObject.Parse(json);
@@ -129,13 +65,12 @@ namespace SAGA.MBI.JsonConvert
                         item.CodeName = (string)subj["infoPointCode"];
                         item.Unit = (string)subj["unit"];
                         item.Type = (string)subj["dataType"];
-                        item.InputType = (string)subj["inputMode"];
+                        item.InputType = (string)subj["inputMode"]; 
                         item.EnumSource = subj.GetValueEx("dataSource");
                         item.Remark = (string)subj["note"];
                         item.Classification = (string)subj["classification"];
-                        var relItem = componentRels.FirstOrDefault(t => t.BaseCmptCode == item.InputType);
-                        item.CollectionCmptCode = relItem?.GodHandCmptCode;
-                        item.IsShow = relItem!=null;
+                        item.IsShow = (bool)subj["visible"];
+                        item.CollectionCmptCode = DalInfoCode.GetInputType(item.InputType);
                         tb.PropertyDefineItems.Add(item);
                     }
                 }
@@ -147,38 +82,5 @@ namespace SAGA.MBI.JsonConvert
 
             return tb;
         }
-
-        /// <summary>
-        /// Saas平台,查询所有组件关系信息
-        /// </summary>
-        /// <returns></returns>
-        public static List<RltComponentRel> SaasQueryAllComponentRel()
-        {
-            List<RltComponentRel> list=new List<RltComponentRel>();
-            try
-            {
-                string json = PEPCodeRequest.SaasQueryAllComponentRel();
-                if (json.IsSuccessRequest())
-                {
-                    JObject jObject = JObject.Parse(json);
-                    foreach (JObject subj in jObject["Content"])
-                    {
-                        RltComponentRel item = new RltComponentRel();
-                        item.CmptRelationId = subj.GetValueEx("cmpt_relation_id");
-                        item.BaseCmptCode = subj.GetValueEx("base_cmpt_code");
-                        item.GodHandCmptCode = subj.GetValueEx("god_hand_cmpt_code");
-
-                        list.Add(item);
-                    }
-                }
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine(e);
-                throw;
-            }
-         
-            return list;
-        }
     }
 }

+ 2 - 2
MBI/SAGA.MBI/JsonConvert/SpaceConvert.cs

@@ -29,7 +29,7 @@ namespace SAGA.MBI.JsonConvert
         /// <param name="buildingId"></param>
         /// <param name="infos"></param>
         /// <returns></returns>
-        public static bool AddSpace(MSpace mode)
+        public static bool AddSpace(MISpace mode)
         {
             string floorId = mode.FloorId;
             JObject infos = mode.GetInfosJObject();
@@ -61,7 +61,7 @@ namespace SAGA.MBI.JsonConvert
         /// </summary>
         /// <param name="beacon"></param>
         /// <returns></returns>
-        public static bool QuerySpaceInfo(MSpace mode)
+        public static bool QuerySpaceInfo(MISpace mode)
         {
             string floorId = mode.FloorId;
             string bimId = mode.BimID;

+ 101 - 0
MBI/SAGA.MBI/Model/Global_Relation_Defination.cs

@@ -0,0 +1,101 @@
+/* ==============================================================================
+ * 功能描述:Global_Relation_Defination  
+ * 创 建 者:Garrett
+ * 创建日期:2019/1/21 10:04:23
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json.Linq;
+using SAGA.DotNetUtils.Extend;
+using SAGA.MBI.RequestData;
+
+namespace SAGA.MBI.Model
+{
+    /// <summary>
+    /// Global_Relation_Defination
+    /// </summary>
+    public class Global_Relation_Defination
+    {
+        private static Global_Relation_Defination m_Instance;
+        public static Global_Relation_Defination Instance
+        {
+            get
+            {
+                if (m_Instance == null)
+                {
+                    string json = RelationRequest.GetGlobalRelationDefination();
+                    JObject jObject = JObject.Parse(json);
+                    m_Instance =
+                        jObject.ConvertToInstance(typeof(Global_Relation_Defination)) as Global_Relation_Defination;
+                }
+
+                return m_Instance;
+            }
+        }
+
+        [Description("Content")]
+        public List<Relation_Graph_Defination> Content { get; set; }
+        /// <summary>
+        /// 查找图类型的定义
+        /// </summary>
+        /// <param name="graph_Type"></param>
+        /// <returns></returns>
+        public Relation_Graph_Defination FindGraphDefination(string graph_Type)
+        {
+            return Content?.FirstOrDefault(t => t.Graph_Type == graph_Type);
+        }
+        /// <summary>
+        /// 查找关系类型的定义
+        /// </summary>
+        /// <param name="graph_Type"></param>
+        /// <param name="descrption"></param>
+        /// <returns></returns>
+        public Relation_Type_Defination FindTypeDefination(string graph_Type, string descrption)
+        {
+            var graphModel = FindGraphDefination(graph_Type);
+
+            return graphModel?.Content?.FirstOrDefault(t=>t.Description== descrption);
+        }
+
+        
+    }
+    
+    /// <summary>
+    /// 图类型的定义
+    /// </summary>
+    public class Relation_Graph_Defination
+    {
+        public Relation_Graph_Defination()
+        {
+            Content=new List<Relation_Type_Defination>();
+        }
+        [Description("graph_type")]
+        public string Graph_Type { get; set; }
+        [Description("graph_name")]
+        public string Graph_Name { get; set; }
+        [Description("Content")]
+        public List<Relation_Type_Defination> Content { get; set; }
+    }
+    /// <summary>
+    /// 关系类型的定义
+    /// </summary>
+    public class Relation_Type_Defination
+    {
+        [Description("rel_name")]
+        public string Rel_Name { get; set; }
+        [Description("directional")]
+        public string Directional { get; set; }
+        [Description("target_objs")]
+        public string Target_Objs { get; set; }
+        [Description("rel_type")]
+        public string Rel_Type { get; set; }
+        [Description("description")]
+        public string Description { get; set; }
+
+    }
+}

+ 25 - 0
MBI/SAGA.MBI/Model/GraphRelationType.cs

@@ -0,0 +1,25 @@
+/* ==============================================================================
+ * 功能描述:图关系类型
+ * 创 建 者:Garrett
+ * 创建日期:2019/1/15 17:19:04
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.MBI.Model
+{
+    /// <summary>
+    /// BusinessSpaceType
+    /// </summary>
+    public class GraphRelationType
+    {
+        public string Name { get; set; }
+
+        public string Code { get; set; }
+
+        public string Rel_Type { get; set; }
+    }
+}

+ 99 - 0
MBI/SAGA.MBI/Model/MBSpace.cs

@@ -0,0 +1,99 @@
+/* ==============================================================================
+ * 功能描述:业务空间
+ * 创 建 者:Garrett
+ * 创建日期:2018/3/30 10:17:05
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json.Linq;
+using SAGA.DotNetUtils;
+using SAGA.DotNetUtils.Logger;
+using SAGA.DotNetUtils.WPF;
+using SAGA.MBI.Common;
+using SAGA.MBI.JsonConvert;
+using SAGA.MBI.RequestData;
+using SAGA.MBI.WinView.ModeInfoMaintenance;
+using WPG.Data;
+using WPG.UserControls;
+
+namespace SAGA.MBI.Model
+{
+    /// <summary>
+    /// MSpace
+    /// </summary>
+    public class MBSpace : MRevitEquipBase
+    {
+        public MBSpace(string floorId, string bimMId)
+        {
+            FloorId = floorId;
+            BimID = bimMId;
+        }
+
+        #region AttachProperty
+        
+
+        #endregion
+
+        #region CloudProperty
+
+        private string m_Name;
+        [Description("RoomName")]
+        public string Name
+        {
+            get { return m_Name; }
+            set
+            {
+                m_Name = value;
+                NotifyPropertyChanged("Name");
+            }
+        }
+        private string m_LocalId;
+        [Description("RoomLocalID")]
+        public string LocalId
+        {
+            get { return m_LocalId; }
+            set
+            {
+                m_LocalId = value;
+                NotifyPropertyChanged("LocalId");
+            }
+        }
+
+        private string m_LocalName;
+        [Description("RoomLocalName")]
+        public string LocalName
+        {
+            get { return m_LocalName; }
+            set
+            {
+                m_LocalName = value;
+                NotifyPropertyChanged("LocalName");
+            }
+        }
+        #endregion CloudProperty
+
+
+
+        #region Method
+
+        public override string ToString()
+        {
+            string result = this.LocalName;
+            if (result.IsNotNullEmpty())
+                return result;
+            result = this.Name;
+            if (result.IsNotNullEmpty())
+                return result;
+            return "未知";
+        }
+        
+
+        #endregion
+
+
+    }
+}

+ 3 - 5
MBI/SAGA.MBI/Model/MSpace.cs

@@ -1,5 +1,5 @@
 /* ==============================================================================
- * 功能描述:MSpace  
+ * 功能描述:元空间
  * 创 建 者:Garrett
  * 创建日期:2018/3/30 10:17:05
  * ==============================================================================*/
@@ -25,9 +25,9 @@ namespace SAGA.MBI.Model
     /// <summary>
     /// MSpace
     /// </summary>
-    public class MSpace : MRevitEquipBase
+    public class MISpace : MRevitEquipBase
     {
-        public MSpace(string floorId, string bimMId)
+        public MISpace(string floorId, string bimMId)
         {
             FloorId = floorId;
             BimID = bimMId;
@@ -113,8 +113,6 @@ namespace SAGA.MBI.Model
         public override CompositeItem SetFixedProperty()
         {
             CompositeItem item = new PropertyCollection();
-            string code = this.EquipClassCode;
-            PropertyDefineTb pdtb = PEPCodeConvert.GetPropertyDefineTb(code);
 
             Property property = new Property(this);
             //属性窗格用到的信息

+ 1 - 1
MBI/SAGA.MBI/Model/MRevitEquipBase.cs

@@ -69,7 +69,7 @@ namespace SAGA.MBI.Model
         /// <summary>
         /// 设备所在元空间
         /// </summary>
-        public MSpace MSpace { get; set; }
+        public MISpace MSpace { get; set; }
         //是否上传
         public bool HasUpload { get; set; }
         //设备族名称

+ 15 - 0
MBI/SAGA.MBI/Model/PropertyDefineTb.cs

@@ -206,4 +206,19 @@ namespace SAGA.MBI.Model
         #endregion
 
     }
+    /// <summary>
+    /// 组件编码对应Revit的输入方式
+    /// </summary>
+    public class ComponentCodeToInputType
+    {
+        /// <summary>
+        /// 组件编码
+        /// </summary>
+        public string ComponentCode { get; set; }
+        /// <summary>
+        /// Revit组件类型
+        /// </summary>
+        public string InputType { get; set; }
+    }
+
 }

+ 2 - 2
MBI/SAGA.MBI/Model/RltBeaconinElementSp.cs

@@ -25,7 +25,7 @@ namespace SAGA.MBI.Model
     /// </summary>
     public class RltBeaconinElementSp : MGraphRelationBase
     {
-        public RltBeaconinElementSp(MSpace mSpace, MRevitEquipBase beacon) : this(beacon?.Id, mSpace?.Id)
+        public RltBeaconinElementSp(MISpace mSpace, MRevitEquipBase beacon) : this(beacon?.Id, mSpace?.Id)
         {
             MSpace = mSpace;
             MBeacon = beacon;
@@ -50,7 +50,7 @@ namespace SAGA.MBI.Model
         /// <summary>
         /// 空间
         /// </summary>
-        public MSpace MSpace { get; set; }
+        public MISpace MSpace { get; set; }
         /// <summary>
         /// 信标
         /// </summary>

+ 2 - 2
MBI/SAGA.MBI/Model/RltEquipInSpace.cs

@@ -22,7 +22,7 @@ namespace SAGA.MBI.Model
     /// </summary>
     public class RltEquipInSpace : MGraphRelationBase
     {
-        public RltEquipInSpace(MSpace mSpace, MRevitEquipBase mEquipment) : this(mEquipment?.Id, mSpace?.Id)
+        public RltEquipInSpace(MISpace mSpace, MRevitEquipBase mEquipment) : this(mEquipment?.Id, mSpace?.Id)
         {
             MSpace = mSpace;
             MEquipment = mEquipment;
@@ -37,7 +37,7 @@ namespace SAGA.MBI.Model
         /// <summary>
         /// 空间Id
         /// </summary>
-        public MSpace MSpace { get; set; }
+        public MISpace MSpace { get; set; }
         /// <summary>
         /// 设备Id
         /// </summary>

+ 20 - 11
MBI/SAGA.MBI/RequestData/CommonRequest.cs

@@ -58,20 +58,28 @@ namespace SAGA.MBI.RequestData
         /// <returns></returns>
         public static string QueryObjectByInfos(string floorId, JObject infoJObject, string[] type = null)
         {
-            if (infoJObject.Count == 0) return "";
             string url = MBIConst.DataPlatformLocalHost + $"data-platform-3/fast/object/in_query?secret={MBIControl.ProjectCur.Password}&projectId={MBIControl.ProjectCur.Id}";
 
-            string buildingId = DalProjectTree.GetBuildingIdByFloor(floorId);
 
             if (type == null)
             {
-                type = new string[] { "Eq", "Ec", "Si", "Sp", "VOBc" };
+                type = new string[] { "Eq", "Ec", "Si", "VOBc" };
             }
             infoJObject.Add("type", new JArray(type));
-
-            //信标加BuildingId查不出来
-            if (buildingId.IsNotNullEmpty() && type.FirstOrDefault(t => Regex.IsMatch(t, "VO.*")) == null)
+            if (type.FirstOrDefault(t => Regex.IsMatch(t, "VO.*")) != null)
+            {
+                //信标加BuildingId查不出来
+            }
+            else if (type.FirstOrDefault(t => new[] { "Eq", "Ec" }.Contains(t)) != null)
+            {
+                //设备需要加buildingId
+                string buildingId = DalProjectTree.GetBuildingIdByFloor(floorId);
                 infoJObject.Add("id", buildingId);
+            }
+            else
+            {
+                infoJObject.Add("id", floorId);
+            }
             JObject updateJObject = new JObject();
             updateJObject.Add("criteria", infoJObject);
             updateJObject.Add("customInfo", true);
@@ -190,7 +198,7 @@ namespace SAGA.MBI.RequestData
         /// 查询楼层下的设备/部件/信标
         /// </summary>
         /// <returns></returns>
-        public static string FloorQuery(string floorId, string[] type)
+        public static string FloorQuery_GoodHand(string floorId, string[] type)
         {
             if (floorId.IsNullOrEmpty() || type.IsNullOrEmptyExt()) return String.Empty;
 
@@ -211,7 +219,7 @@ namespace SAGA.MBI.RequestData
         /// <returns></returns>
         public static string CacheEqEc(string buildingId)
         {
-            return SubsetQuery(buildingId, new JArray() {"Eq", "Ec"});
+            return SubsetQuery(buildingId, new JArray() { "Eq", "Ec" });
         }
         /// <summary>
         /// 缓存所有的Revit数据
@@ -220,7 +228,7 @@ namespace SAGA.MBI.RequestData
         /// <returns></returns>
         public static string CacheAllData(string buildingId)
         {
-            return SubsetQuery(buildingId, new JArray() { "Eq", "Ec","Si" });
+            return SubsetQuery(buildingId, new JArray() { "Eq", "Ec", "Si" });
         }
         /// <summary>
         /// 查询某个object下指定类型的objects (查询项目下的所有类型, 建筑下的设备, 系统, 楼层, 空间. 查询楼层中的空间, 非关系表查询)
@@ -318,7 +326,7 @@ namespace SAGA.MBI.RequestData
         public static string BatchUpdate(JArray criterias)
         {
             string url = MBIConst.DataPlatformLocalHost + $"data-platform-3/object/batch_update?secret={MBIControl.ProjectCur.Password}&projectId={MBIControl.ProjectCur.Id}";
-            
+
             JObject updateJObject = new JObject();
             updateJObject.Add("criterias", criterias);
 
@@ -328,6 +336,7 @@ namespace SAGA.MBI.RequestData
             return request;
         }
 
-      
+       
+
     }
 }

+ 36 - 0
MBI/SAGA.MBI/RequestData/EquipmentRequest.cs

@@ -64,5 +64,41 @@ namespace SAGA.MBI.RequestData
             string request = client.PostRequest();
             return request;
         }
+
+        /// <summary>
+        /// 批量增加设备
+        /// </summary>
+        /// <param name="criterias"></param>
+        /// <returns></returns>
+        public static string BatchAdd(JArray criterias)
+        {
+            string url = MBIConst.DataPlatformLocalHost + $"data-platform-3/equipment/batch/create?secret={MBIControl.ProjectCur.Password}&projectId={MBIControl.ProjectCur.Id}";
+
+            JObject updateJObject = new JObject();
+            updateJObject.Add("criterias", criterias);
+
+            string postData = updateJObject.ToString();
+            RestClient client = new RestClient(url, HttpVerb.POST, postData);
+            string request = client.PostRequest();
+            return request;
+        }
+
+        /// <summary>
+        /// 批量删除
+        /// </summary>
+        /// <param name="criterias"></param>
+        /// <returns></returns>
+        public static string BatchDel(JArray criterias)
+        {
+            string url = MBIConst.DataPlatformLocalHost + $"data-platform-3/equipment/batch/delete?secret={MBIControl.ProjectCur.Password}&projectId={MBIControl.ProjectCur.Id}";
+
+            JObject updateJObject = new JObject();
+            updateJObject.Add("criterias", criterias);
+
+            string postData = updateJObject.ToString();
+            RestClient client = new RestClient(url, HttpVerb.POST, postData);
+            string request = client.PostRequest();
+            return request;
+        }
     }
 }

+ 1 - 0
MBI/SAGA.MBI/RequestData/MatchFMRequest.cs

@@ -45,6 +45,7 @@ namespace SAGA.MBI.RequestData
             JObject fmJObject=new JObject();
             fmJObject.Add("BimId", equipment.BimID);
             fmJObject.Add("BuildId", DalProjectTree.GetBuildingIdByFloor(equipment.FloorId));
+            fmJObject.Add("CodeType", 1);
             fmJObject.Add("EquipmentId", equipment.Id);
             fmJObject.Add("Family", equipment.Family.Code);
             fmJObject.Add("FamilyName", equipment.Family.Name);

+ 5 - 40
MBI/SAGA.MBI/RequestData/PEPCodeRequest.cs

@@ -50,50 +50,15 @@ namespace SAGA.MBI.RequestData
         /// <param name="buildingId"></param>
         /// <param name="infos"></param>
         /// <returns></returns>
-        public static string SaasSysOrEqInfos(string code, string type = "equip")
+        public static string InfoCodeQuery(string code)
         {
-            string url = MBIConst.SaasLocalHost + $"saas-manage3/app/restTemplateService/queryObjectPropertyMapping2";
+            string url = MBIConst.ScanBuildingLocalHost + $"service/dict/infocode_query";
 
             string app_type = "godhand";
             JObject idJObject = new JObject();
-            idJObject.Add("user_id", MBIControl.ManageInfo.Person_Id);
-            idJObject.Add("code", code);
-            idJObject.Add("type", type);
-            idJObject.Add("app_type", app_type);
-            //获取所有的信息点
-            idJObject.Add("is_all", "1");
-
-            string postData = idJObject.ToString();
-            RestClient client = new RestClient(url, HttpVerb.POST, postData);
-            string request = client.PostRequest();
-            return request;
-        }
-
-        /// <summary>
-        /// 查询带有自定义信息点的综合查询方法
-        /// </summary>
-        /// <returns></returns>
-        public static string InfocodeComplex_query(string code,bool combine=false)
-        {
-            string url = MBIConst.DataPlatformLocalHost + $"data-platform-3/infocode/query_property?projectId={MBIControl.ProjectCur.Id}&type={code}&combine={combine}&enrich=true";
-
-            RestClient client = new RestClient(url, HttpVerb.GET);
-            string request = client.PostRequest();
-            return request;
-        }
-
-        /// <summary>
-        /// Saas平台,查询所有组件关系信息
-        /// </summary>
-        /// <param name="buildingId"></param>
-        /// <param name="infos"></param>
-        /// <returns></returns>
-        public static string SaasQueryAllComponentRel()
-        {
-            string url = MBIConst.SaasLocalHost + $"saas-manage3/restComponentService/queryAllComponentRel";
-            
-            JObject idJObject = new JObject();
-            idJObject.Add("user_id", MBIControl.ManageInfo.Person_Id);
+            idJObject.Add("ProjId", MBIControl.ProjectCur.Id);
+            idJObject.Add("Code", code);
+            idJObject.Add("AppType", "revit");
 
             string postData = idJObject.ToString();
             RestClient client = new RestClient(url, HttpVerb.POST, postData);

+ 21 - 0
MBI/SAGA.MBI/RequestData/RelationRequest.cs

@@ -236,5 +236,26 @@ namespace SAGA.MBI.RequestData
             }
             return null;
         }
+
+        /// <summary>
+        /// 全局图类型关系类型定义
+        /// </summary>
+        /// <returns></returns>
+        public static string GetGlobalRelationDefination()
+        {
+            try
+            {
+                string url = MBIConst.DataPlatformLocalHost + $"data-platform-3/dict/query/global_relation_defination";
+                
+                RestClient client = new RestClient(url, HttpVerb.GET);
+                string request = client.PostRequest();
+                return request;
+            }
+            catch (Exception e)
+            {
+                MessageShowBase.Show(e);
+            }
+            return null;
+        }
     }
 }

+ 50 - 0
MBI/SAGA.MBI/RequestData/SpaceRequest.cs

@@ -70,5 +70,55 @@ namespace SAGA.MBI.RequestData
             string request = CommonRequest.SubsetQuery(floorId,new JArray("Si"));
             return request;
         }
+
+        /// <summary>
+        /// 获取业务空间的类型
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public static string GetBusinessSpaceTypes()
+        {
+            string url = MBIConst.DataPlatformLocalHost + $"data-platform-3/infocode/business_space_type/query";
+            
+            RestClient client = new RestClient(url, HttpVerb.GET);
+            string request = client.PostRequest();
+            return request;
+        }
+
+        /// <summary>
+        /// 批量增加
+        /// </summary>
+        /// <param name="criterias"></param>
+        /// <returns></returns>
+        public static string BatchAdd(JArray criterias)
+        {
+            string url = MBIConst.DataPlatformLocalHost + $"data-platform-3/ispace/batch/create?secret={MBIControl.ProjectCur.Password}&projectId={MBIControl.ProjectCur.Id}";
+
+            JObject updateJObject = new JObject();
+            updateJObject.Add("criterias", criterias);
+
+            string postData = updateJObject.ToString();
+            RestClient client = new RestClient(url, HttpVerb.POST, postData);
+            string request = client.PostRequest();
+            return request;
+        }
+
+        /// <summary>
+        /// 批量删除
+        /// </summary>
+        /// <param name="criterias"></param>
+        /// <returns></returns>
+        public static string BatchDel(JArray criterias)
+        {
+            string url = MBIConst.DataPlatformLocalHost + $"data-platform-3/ispace/batch/delete?secret={MBIControl.ProjectCur.Password}&projectId={MBIControl.ProjectCur.Id}";
+
+            JObject updateJObject = new JObject();
+            updateJObject.Add("criterias", criterias);
+
+            string postData = updateJObject.ToString();
+            RestClient client = new RestClient(url, HttpVerb.POST, postData);
+            string request = client.PostRequest();
+            return request;
+        }
     }
 }

+ 15 - 4
MBI/SAGA.MBI/RevitReference/RVTNoModeDutyOperate.cs

@@ -50,20 +50,31 @@ namespace SAGA.MBI.RevitReference
                             if (fs == null)
                             {
                                 MessageShowBase.Infomation($"没有找到编码{mode.MEquipBase.EquipClassCode}类型的族,请手动载入后再操作。");
-                                return Result.Cancelled; }
+                                return Result.Cancelled;
+                            }
                             if (IsBasePointFamily(fs))
                             {
                                 //使用BIMLocation中的坐标,mm转为英寸
                                 XYZ xyz = mode.MEquipBase.Location.ToXyz();
-                                xyz = xyz==null ? XYZ.Zero : xyz.ConvertToApi();
+                                xyz = xyz == null ? XYZ.Zero : xyz.ConvertToApi();
                                 var level = GetCurFloorLevel(doc);
                                 //传标高,z值设置为零
-                                xyz=xyz.NewZ(0);
+                                xyz = xyz.NewZ(0);
                                 fi = doc.Create.NewFamilyInstance(xyz, fs, level, StructuralType.NonStructural);
-                                mode.MEquipBase.SaveDutyBIMRelation(doc.PathName.GetFileName(),fi.Id.ToString());
+                                //假如定位点和中心点不一致,平移设备,将设备中心点移到定位点上
+                                doc.Regenerate();
+                                XYZ centerXyz = fi.GetLocationPointMBIXYZ().NewZ(0);
+                                if (!centerXyz.IsEqual2(xyz))
+                                {
+                                    XYZ vector = xyz - centerXyz;
+                                    doc.MoveElement(fi.Id, vector);
+                                }
+
                                 trans.Commit();
                                 if (fi != null)
                                 {
+                                    //本地数据库保存岗位和BimId的关系
+                                    mode.MEquipBase.SaveDutyBIMRelation(doc.PathName.GetFileName(), fi.Id.ToString());
                                     mode.BimId = fi.Id.ToString();
                                     afterAction?.Invoke(fi);
                                 }

+ 18 - 2
MBI/SAGA.MBI/SAGA.MBI.csproj

@@ -243,6 +243,7 @@
     <Compile Include="CmbData\ProvinceCityVm.cs" />
     <Compile Include="Common\CacheAspect.cs" />
     <Compile Include="Common\WaitingView.cs" />
+    <Compile Include="DataArrange\DalInfoCode.cs" />
     <Compile Include="Html5Command.cs" />
     <Compile Include="Command.cs" />
     <Compile Include="Common\MBIAssistHelper.cs" />
@@ -273,12 +274,18 @@
     <Compile Include="ModeInfoEdit\WinPointInfoMerge.xaml.cs">
       <DependentUpon>WinPointInfoMerge.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Model\Global_Relation_Defination.cs" />
+    <Compile Include="Model\GraphRelationType.cs" />
+    <Compile Include="Model\MBSpace.cs" />
     <Compile Include="Model\MQRCode.cs" />
     <Compile Include="RequestData\QRCodeRequest.cs" />
     <Compile Include="RevitModelHandle\ParameterDefinitionFactory.cs" />
     <Compile Include="RevitModelHandle\ParameterUtil.cs" />
     <Compile Include="RevitModelHandle\RevitParameterUpdate.cs" />
     <Compile Include="RevitReference\RVTNoModeDutyOperate.cs" />
+    <Compile Include="Service\InputService.cs" />
+    <Compile Include="ToolsData\DataCheck\SpaceEquipFloorCheck.cs" />
+    <Compile Include="ToolsData\DataCheck\SpaceEquipFloorCheckResult.cs" />
     <Compile Include="ToolsData\DelZeroSpace.cs" />
     <Compile Include="ToolsData\CheckBase\CheckOperation.cs" />
     <Compile Include="ToolsData\CheckBase\CheckType.cs" />
@@ -300,6 +307,8 @@
     <Compile Include="ToolsData\DataCheck\WinDataCheckSetting.xaml.cs">
       <DependentUpon>WinDataCheckSetting.xaml</DependentUpon>
     </Compile>
+    <Compile Include="ToolsData\ModeCheck\EquipReferSystemCheck.cs" />
+    <Compile Include="ToolsData\ModeCheck\EquipReferSystemCheckResult.cs" />
     <Compile Include="ToolsData\ModeCheck\ModeCheckBase.cs" />
     <Compile Include="ToolsData\ModeCheck\DataCheckRule.cs" />
     <Compile Include="ToolsData\CheckBase\DCElementType.cs" />
@@ -347,11 +356,14 @@
     <Compile Include="ToolsData\IToolCommand.cs" />
     <Compile Include="ToolsData\ExportAllDuty.cs" />
     <Compile Include="ToolsData\UpdateRelationEquipinSpace.cs" />
+    <Compile Include="ToolsData\VerticalPipeAlign.cs" />
+    <Compile Include="ToolsData\WinSelectCheckFloors.xaml.cs">
+      <DependentUpon>WinSelectCheckFloors.xaml</DependentUpon>
+    </Compile>
     <Compile Include="WinView\BeModingDutyList\MEquipNoMode.cs" />
     <Compile Include="WinView\BeModingDutyList\VMBeModeDutyList.cs" />
     <Compile Include="Extend\MRevitEquipBaseExtend.cs" />
     <Compile Include="Extension\MEquipmentExtension.cs" />
-    <Compile Include="FileStream\FileOperateBase.cs" />
     <Compile Include="FileStream\FloorFileOperate.cs" />
     <Compile Include="FileStream\FloorSequence.cs" />
     <Compile Include="FileStream\ProjectDirOperate.cs" />
@@ -499,7 +511,7 @@
     <Compile Include="Model\MEquipmentFamily.cs" />
     <Compile Include="JsonConvert\EquipmentConvert.cs" />
     <Compile Include="Model\MServiceAttachment.cs" />
-    <Compile Include="Model\MSpace.cs" />
+    <Compile Include="Model\MISpace.cs" />
     <Compile Include="Model\PropertyDefineTb.cs" />
     <Compile Include="Model\RltEquipInSpace.cs" />
     <Compile Include="RequestData\CloudImageRequest.cs" />
@@ -704,6 +716,10 @@
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
     </Page>
+    <Page Include="ToolsData\WinSelectCheckFloors.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
     <Page Include="WinView\BeModingDutyList\WinBeModeDutyList.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

+ 28 - 0
MBI/SAGA.MBI/Service/InputService.cs

@@ -0,0 +1,28 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:InputService
+ * 作者:xulisong
+ * 创建时间: 2019/1/18 10:50:48
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SAGA.MBI.DataArrange;
+using SAGA.RevitUtils.Service;
+
+namespace SAGA.MBI.Service
+{
+    /// <summary>
+    /// 输入服务限定
+    /// </summary>
+    public class InputService : IInputService
+    {
+        public string GetInputCode(string originalCode)
+        {
+           return DalInfoCode.GetInputType(originalCode);
+        }
+    }
+}

+ 33 - 0
MBI/SAGA.MBI/ToolCommand.cs

@@ -34,6 +34,39 @@ namespace SAGA.MBI
 
     #region 工具
     /// <summary>
+    /// 立管对齐
+    /// </summary>
+    [Transaction(TransactionMode.Manual)]
+    [Regeneration(RegenerationOption.Manual)]
+    public class VerticalPipeAlginCommand : ExternalCommand
+    {
+        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
+        {
+            try
+            {
+                int count = 0;
+                WinSelectCheckFloors win =new WinSelectCheckFloors();
+                if (win.ShowDialog() == true)
+                {
+                    VerticalPipeAlign.Instance.Execute();
+                    VerticalPipeAlign.Instance.ShowResult();
+                }
+
+            }
+            catch (Exception e)
+            {
+                MessageShow.Show(e);
+                return Result.Cancelled;
+            }
+            return Result.Succeeded;
+        }
+
+        public override bool IsCommandAvailable(UIApplication applicationData, CategorySet selectedCategories)
+        {
+            return true;
+        }
+    }
+    /// <summary>
     /// 批量删除无用的空间
     /// </summary>
     [Transaction(TransactionMode.Manual)]

+ 2 - 0
MBI/SAGA.MBI/ToolsData/CheckBase/CheckOperation.cs

@@ -62,6 +62,7 @@ namespace SAGA.MBI.ToolsData.CheckBase
             list.Add(new ConnectorCheck());
             list.Add(new SystemCheck());
             list.Add(new EquipmentInSpaceCheck());
+            list.Add(new EquipReferSystemCheck());
             list.ForEach(t =>
             {
                 t.SetBaseCheck(checkBase);
@@ -81,6 +82,7 @@ namespace SAGA.MBI.ToolsData.CheckBase
             list.Add(new QRCodeContextCheck());
             list.Add(new MissDutyOrMode());
             list.Add(new BIMDuplicationCheck());
+            list.Add(new SpaceEquipFloorCheck());
             list.ForEach(t =>
             {
                 t.RIsChecked = true;

+ 3 - 2
MBI/SAGA.MBI/ToolsData/CheckBase/DCNPOIExtend.cs

@@ -25,8 +25,9 @@ namespace SAGA.MBI.ToolsData.CheckBase
         /// <param name="style"></param>
         public static void AddCell(this IRow row, int column, string str, DataCheckNPOIStyle style = DataCheckNPOIStyle.Content, bool hasStyle = false)
         {
-
-            ICell cell00 = row.CreateCell(column);
+            ICell cell00 = row.GetCell(column);
+            if (cell00 == null)
+                cell00 = row.CreateCell(column);
             if (hasStyle)
                 cell00.CellStyle = DCNPOIExtend.GetCellStyle(row.Sheet.Workbook, style);
             cell00.SetCellType(NPOI.SS.UserModel.CellType.String);

+ 5 - 0
MBI/SAGA.MBI/ToolsData/CheckBase/ICheckBase.cs

@@ -24,6 +24,11 @@ namespace SAGA.MBI.ToolsData.CheckBase
         bool RIsChecked { get; set; }
 
         /// <summary>
+        /// 是否强制勾选
+        /// </summary>
+        bool RIsReadOnly { get; set; }
+
+        /// <summary>
         /// 是否通过较验
         /// </summary>
         bool IsRight { get; set; }

+ 2 - 2
MBI/SAGA.MBI/ToolsData/CheckEquipCategory.cs

@@ -124,7 +124,7 @@ namespace SAGA.MBI.ToolsData
                     var space = fi.GetReferenceSpace();
                     if (space == null) continue;
                     string spaceId = space.GetCloudBIMId();
-                    MSpace mSpace = addContext.MSpaces.FirstOrDefault(t => t.BimID == spaceId);
+                    MISpace mSpace = addContext.MSpaces.FirstOrDefault(t => t.BimID == spaceId);
                     if (mSpace == null)
                     {
                         mSpace = DalSpace.GetSpace(space);
@@ -157,7 +157,7 @@ namespace SAGA.MBI.ToolsData
                     var space = fi.GetReferenceSpace();
                     if (space == null) continue;
                     string spaceId = space.GetCloudBIMId();
-                    MSpace mSpace = addContext.MSpaces.FirstOrDefault(t => t.BimID == spaceId);
+                    MISpace mSpace = addContext.MSpaces.FirstOrDefault(t => t.BimID == spaceId);
                     if (mSpace == null)
                     {
                         mSpace = DalSpace.GetSpace(space);

+ 1 - 1
MBI/SAGA.MBI/ToolsData/CorrectLossDuty.cs

@@ -103,7 +103,7 @@ namespace SAGA.MBI.ToolsData
             try
             {
                 //修改设备
-                DalCommon.BatchUpdate(context.MEquipments);
+                DalEquip.BatchUpdate(context.MEquipments);
                 //修改部件
                 DalCommon.BatchUpdate(context.MEquipmentParts);
             }

+ 15 - 2
MBI/SAGA.MBI/ToolsData/DataCheck/DataCheckBase.cs

@@ -6,6 +6,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Linq;
 using NPOI.SS.UserModel;
 using SAGA.DotNetUtils.Others;
@@ -17,7 +18,7 @@ namespace SAGA.MBI.ToolsData.DataCheck
     /// <summary>
     /// CheckBase
     /// </summary>
-    public class DataCheckBase: ICheckBase
+    public class DataCheckBase: ICheckBase,INotifyPropertyChanged
     {
         public string Name { get; set; }
         public CheckContext Context { get; set; }
@@ -108,12 +109,24 @@ namespace SAGA.MBI.ToolsData.DataCheck
         /// 是否强制勾选
         /// </summary>
         public bool RIsReadOnly { get; set; }
+        private bool m_RIsChecked;
         /// <summary>
         /// 是否选中
         /// </summary>
-        public bool RIsChecked { get; set; }
+        public bool RIsChecked
+        {
+            get { return m_RIsChecked; }
+            set
+            {
+                m_RIsChecked = value;
+                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(RIsChecked)));
+            }
+        }
 
         private List<string> m_SpecificationSheet=new List<string>();
+
+        public event PropertyChangedEventHandler PropertyChanged;
+
         /// <summary>
         /// 关联规范项
         /// </summary>

+ 32 - 16
MBI/SAGA.MBI/ToolsData/DataCheck/MissDutyOrModeCheck.cs

@@ -14,6 +14,7 @@ using Autodesk.Revit.DB.Mechanical;
 using Newtonsoft.Json.Linq;
 using NPOI.SS.UserModel;
 using SAGA.DotNetUtils.Extend;
+using SAGA.DotNetUtils.Logger;
 using SAGA.DotNetUtils.Others;
 using SAGA.MBI.Calc;
 using SAGA.MBI.DataArrange;
@@ -54,7 +55,7 @@ namespace SAGA.MBI.ToolsData.DataCheck
         /// </summary>
         /// <returns></returns>
         private bool GetCheckResult()
-        {            
+        {
             bool result = true;
             var floors = DalProjectTree.GetSelectedFloors(true);
             foreach (var mfloor in floors)
@@ -71,8 +72,8 @@ namespace SAGA.MBI.ToolsData.DataCheck
             try
             {
                 var tuple = CorrectLossDuty.GetCheckResult(mFloor);
-                list.AddRange(GetCheckResult(tuple.Item1,true));
-                list.AddRange(GetCheckResult(tuple.Item2,false));
+                list.AddRange(GetCheckResult(tuple.Item1, true));
+                list.AddRange(GetCheckResult(tuple.Item2, false));
             }
             catch (Exception e)
             {
@@ -80,16 +81,20 @@ namespace SAGA.MBI.ToolsData.DataCheck
             return list;
         }
 
-        private List<MissDutyOrModeCheckResult> GetCheckResult(CalcContext calcContext,bool isadd)
+        private List<MissDutyOrModeCheckResult> GetCheckResult(CalcContext calcContext, bool isadd)
         {
             List<MissDutyOrModeCheckResult> list = new List<MissDutyOrModeCheckResult>();
             try
             {
+                IEnumerable<IGrouping<string, DocumentChangedLogMode>> logsGroupByBimId=null;
                 //if (isadd)
-                //{
-                //    calcContext.OpenDocument();
-                //}
-                Action<List<MRevitEquipBase>, List<MissDutyOrModeCheckResult>, DCElementType> convetAction = (dutys, l,type) =>
+                {
+                    //检测有日志文件,才上传
+                    var logs = DalLogOperate.GetLogs(calcContext.MFloor.Id);
+                    //按id分组后的日志
+                    logsGroupByBimId = logs.GroupBy(t => t.Id);
+                }
+                Action<List<MRevitEquipBase>, List<MissDutyOrModeCheckResult>, DCElementType> convetAction = (dutys, l, type) =>
                 {
                     foreach (var duty in dutys)
                     {
@@ -97,24 +102,35 @@ namespace SAGA.MBI.ToolsData.DataCheck
                         result.FloorName = calcContext.MFloor.ToString();
                         result.IsRight = false;
                         result.Type = type;
+                        result.BIMID = duty.BimID.GetBIMID().ToString();
                         if (isadd)
                         {
-                            result.BIMID = duty.BimID.GetBIMID().ToString();
-                            result.RMessage = "无岗位,在模型中有可识别构件";
+                            result.RMessage = "模型中有可识别构件,但物理世界未找到对应岗位";
+                            
                         }
                         else
                         {
                             result.DutyId = duty.Id;
                             result.DutyName = duty.ToString();
-                            result.RMessage = "有岗位,在模型中找不到对应构件";
+                            result.RMessage = "岗位bimID有值,但在模型中未找到的对应构件";
+                        }
+                        //判断是否为没有上传模型引起的
+                        var logs = logsGroupByBimId?.FirstOrDefault(t => t.Key == result.BIMID);
+                        if (logs != null)
+                        {
+                            DocumentChangedLogMode log = DalLogOperate.CombineLogs(logs.ToList());
+                            if (log != null)
+                            {
+                                result.RMessage = "未上传模型";
+                            }
                         }
                         l.Add(result);
                     }
                 };
-                convetAction(calcContext.MEquipments.ToList<MRevitEquipBase>(), list,DCElementType.Equipment);
-                convetAction(calcContext.MEquipmentParts.ToList<MRevitEquipBase>(), list,DCElementType.EuipmentPart);
-                convetAction(calcContext.MBeacons.ToList<MRevitEquipBase>(), list,DCElementType.Beacon);
-                convetAction(calcContext.MSpaces.ToList<MRevitEquipBase>(), list,DCElementType.Space);
+                convetAction(calcContext.MEquipments.ToList<MRevitEquipBase>(), list, DCElementType.Equipment);
+                convetAction(calcContext.MEquipmentParts.ToList<MRevitEquipBase>(), list, DCElementType.EuipmentPart);
+                convetAction(calcContext.MBeacons.ToList<MRevitEquipBase>(), list, DCElementType.Beacon);
+                convetAction(calcContext.MSpaces.ToList<MRevitEquipBase>(), list, DCElementType.Space);
             }
             catch (Exception e)
             {
@@ -144,7 +160,7 @@ namespace SAGA.MBI.ToolsData.DataCheck
 
                 #region 添加数据
                 int index = 3;
-                
+
                 foreach (MissDutyOrModeCheckResult result in Results)
                 {
                     //数量过多,只显示有问题的

+ 1 - 1
MBI/SAGA.MBI/ToolsData/DataCheck/QRCodeContextCheck.cs

@@ -33,7 +33,7 @@ namespace SAGA.MBI.ToolsData.DataCheck
     {
         public QRCodeContextCheck()
         {
-            Name = "二维码内容错误";
+            Name = "物理世界中资产岗位关系与二维码中存的关系一致性检查";
         }
         [DataCheckProcessAspect]
         public override bool Check()

+ 207 - 0
MBI/SAGA.MBI/ToolsData/DataCheck/SpaceEquipFloorCheck.cs

@@ -0,0 +1,207 @@
+/* ==============================================================================
+ * 功能描述:业务空间所在楼层与设备所在楼层一致性检查
+ * 创 建 者:Garrett
+ * 创建日期:2018/10/23 15:08:55
+ * ==============================================================================*/
+
+using Newtonsoft.Json.Linq;
+using NPOI.SS.UserModel;
+using SAGA.DotNetUtils.Others;
+using SAGA.MBI.DataArrange;
+using SAGA.MBI.Model;
+using SAGA.MBI.RequestData;
+using SAGA.MBI.ToolsData.CheckBase;
+using SAGA.MBI.ToolsData.ModeCheck;
+using SAGA.RevitUtils.MEP;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+
+namespace SAGA.MBI.ToolsData.DataCheck
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    class SpaceEquipFloorCheck : DataCheckBase
+    {
+        public SpaceEquipFloorCheck()
+        {
+            Name = "与业务空间有所在关系的设备的实际位置和业务空间位置不一致检查";
+        }
+        [DataCheckProcessAspect]
+        public override bool Check()
+        {
+            IsRight = GetCheckResult();
+            return IsRight;
+        }
+
+        public override void Correct()
+        {
+            throw new NotImplementedException();
+        }
+
+        #region CheckMethod
+
+        private List<GraphRelationType> m_BusinessSpaceTypes;
+        /// <summary>
+        /// 对比信息点是否一致
+        /// </summary>
+        /// <returns></returns>
+        private bool GetCheckResult()
+        {
+            bool result = true;
+            m_BusinessSpaceTypes = DalSpace.GetBusinessSpaceTypes();
+            var floors = DalProjectTree.GetSelectedFloors(true);
+            foreach (var mfloor in floors)
+            {
+                Results.AddRange(GetCheckResult(mfloor));
+            }
+            return Results.All(t => t.IsRight);
+        }
+        private List<SpaceEquipFloorCheckResult> GetCheckResult(MFloor mFloor)
+        {
+            List<SpaceEquipFloorCheckResult> list = new List<SpaceEquipFloorCheckResult>();
+
+            try
+            {
+                //本层下的设备和部件 
+                var equips = DalCommon.DownLoadCouldData(mFloor.Id, new[] { "Eq", "Ec" });
+                //本层下的业务空间
+                foreach (GraphRelationType businessSpaceType in m_BusinessSpaceTypes)
+                {
+                    list.AddRange(GetCheckResult(equips,businessSpaceType,mFloor));
+                }
+            }
+            catch (Exception e)
+            {
+            }
+            return list;
+        }
+        private List<SpaceEquipFloorCheckResult> GetCheckResult(List<MRevitEquipBase> equipsA, GraphRelationType businessSpaceType, MFloor mFloor)
+        {
+            List<SpaceEquipFloorCheckResult> list = new List<SpaceEquipFloorCheckResult>();
+            try
+            {
+                //楼层下的业务空间
+                var spacesB = DalCommon.DownLoadCouldData(mFloor.Id, new[] { businessSpaceType.Code });
+                if (!spacesB.Any()) return list;
+                #region 业务空间下的设备
+
+                JObject jObject = new JObject();
+                JArray jArray = new JArray();
+                string graph = "EquipinSpace";
+                string graphType = GetEquipInSpaceGraphType(graph, businessSpaceType.Code);
+                foreach (MRevitEquipBase space in spacesB)
+                {
+                    JObject graphJObject = new JObject();
+                    
+                    graphJObject.Add("graphType", graph);
+                    graphJObject.Add("relType", graphType);
+                    graphJObject.Add("side", "fromId");
+                    graphJObject.Add("toId", space.Id);
+                    jArray.Add(graphJObject);
+                }
+                jObject.Add("include", jArray);
+                var equipsC = CommonConvert.FloorQuery_SubSet(mFloor.Id, jObject, new[] { "Eq" });
+
+                #endregion
+                //不在业务空间中的设备
+                var equipsD = equipsC.Except(equipsA, new CommonEqualComparer<MRevitEquipBase>((a, b) => a.Id == b.Id));
+                foreach (MRevitEquipBase equipBase in equipsD)
+                {
+                    SpaceEquipFloorCheckResult mode = new SpaceEquipFloorCheckResult();
+                    mode.SpaceType = businessSpaceType.Name;
+                    var space = QuerySpaceByEquipId(businessSpaceType, equipBase.Id,mFloor.Id);
+                    mode.SpaceName = space?.ToString();
+                    mode.SpaceId = space?.Id;
+                    mode.SpaceFloorName = mFloor.ToString();
+                    mode.EquipName = equipBase.ToString();
+                    mode.EquipId = equipBase.Id;
+                    mode.EquipFloorName = DalProjectTree.GetFloorNameByFloorId(equipBase.FloorId);
+                    mode.IsRight = false;
+                    mode.RMessage = "业务空间所在楼层与该空间内设备的所在楼层信息不一致。";
+                    list.Add(mode);
+
+                }
+            }
+            catch (Exception e)
+            {
+                return list;
+            }
+            return list;
+        }
+        /// <summary>
+        /// 由设备id,查询业务空间
+        /// </summary>
+        /// <param name="businessSpaceType"></param>
+        /// <param name="equipId">与空间有EquipinSpace关联的设备</param>
+        /// <param name="floorId"></param>
+        /// <returns></returns>
+        private MRevitEquipBase QuerySpaceByEquipId( GraphRelationType businessSpaceType, string equipId,string floorId)
+        {
+            JObject jObject = new JObject();
+            JArray jArray = new JArray();
+            JObject graphJObject = new JObject();
+            graphJObject.Add("graphType", businessSpaceType.Code);
+            graphJObject.Add("relType", businessSpaceType.Rel_Type);
+            graphJObject.Add("side", "fromId");
+            graphJObject.Add("fromId", equipId);
+            jArray.Add(graphJObject);
+            jObject.Add("include", jArray);
+            var items = CommonConvert.FloorQuery_SubSet(floorId, jObject, new[] { businessSpaceType.Code });
+            return items.FirstOrDefault();
+        }
+
+        private string GetEquipInSpaceGraphType(string graph, string description)
+        {
+            return Global_Relation_Defination.Instance.FindTypeDefination(graph, description)?.Rel_Type;
+        }
+
+        #endregion
+
+        //[DataCheckProcessAspect]
+        public override void Export()
+        {
+            //   Check();
+            try
+            {
+                IWorkbook book = DCRExport.GetWorkbook();
+                //ISheet sheet = book.CreateSheet(Name);
+                ISheet sheet = book.GetSheet(Name);
+
+                #region 添加数据
+                int index = 3;
+                //添加 共检查XXX条数据,未通过检查的如下 提示
+                IRow rowTip = sheet.CreateRow(index - 1);
+                rowTip.AddCell(0, $"总检查{Results.Count}条数据,未通过检查的如下", DataCheckNPOIStyle.Title);
+
+                foreach (SpaceEquipFloorCheckResult result in Results)
+                {
+                    //数量过多,只显示有问题的
+                    if (result.IsRight) continue;
+                    index++;
+                    IRow rowN = sheet.CreateRow(index);
+                    DataCheckNPOIStyle style = result.IsRight ? DataCheckNPOIStyle.Content : DataCheckNPOIStyle.Error;
+                    int i = 0;
+                    rowN.AddCell(i++, result.SpaceType, style);
+                    rowN.AddCell(i++, result.SpaceName, style);
+                    rowN.AddCell(i++, result.SpaceId, style);
+                    rowN.AddCell(i++, result.SpaceFloorName, style);
+                    rowN.AddCell(i++, result.EquipName, style);
+                    rowN.AddCell(i++, result.EquipId, style);
+                    rowN.AddCell(i++, result.EquipFloorName, style);
+                    string rowN4 = result.IsRight ? "通过" : "不通过";
+                    rowN.AddCell(i++, rowN4, style);
+                    rowN.AddCell(i++, result.RMessage, style);
+                }
+                #endregion
+
+            }
+            catch (Exception e)
+            {
+                MessageShowBase.Show(e);
+            }
+        }
+    }
+}

+ 31 - 0
MBI/SAGA.MBI/ToolsData/DataCheck/SpaceEquipFloorCheckResult.cs

@@ -0,0 +1,31 @@
+/* ==============================================================================
+ * 功能描述:业务空间所在楼层与设备所在楼层一致性检查结果
+ * 创 建 者:Garrett
+ * 创建日期:2018/10/23 15:13:17
+ * ==============================================================================*/
+
+using SAGA.MBI.ToolsData.ModeCheck;
+
+namespace SAGA.MBI.ToolsData.DataCheck
+{
+    /// <summary>
+    /// UnitCheckResult
+    /// </summary>
+    class SpaceEquipFloorCheckResult : DataCheckResultBase
+    {
+        //业务空间类型
+        public string SpaceType { get; set; }
+        //业务空间本地名称
+        public string SpaceName { get; set; }
+        //业务空间Id
+        public string SpaceId { get; set; }
+        //业务空间所在楼层名称
+        public string SpaceFloorName { get; set; }
+        //业务空间中的设备Id
+        public string EquipId { get; set; }
+        //业务空间中的设备名称
+        public string EquipName { get; set; }
+        //设备所在楼层名称
+        public string EquipFloorName { get; set; }
+    }
+}

+ 9 - 3
MBI/SAGA.MBI/ToolsData/DataCheck/WinDataCheckSetting.xaml

@@ -65,14 +65,20 @@
                     </TreeView>
                 </GroupBox>
             </Grid>
-            <Grid Grid.Column="1">
-                <GroupBox Header="请选择检查项">
+            <Grid Grid.Column="1"><!--Header=""-->
+                <GroupBox >
+                    <GroupBox.Header>
+                        <WrapPanel>
+                            <TextBlock Text="请选择检查"></TextBlock>
+                            <TextBlock Text="项 "  MouseDown="CheckItemInverse_OnMouseDown"></TextBlock>
+                        </WrapPanel>
+                    </GroupBox.Header>
                     <ListBox  x:Name="myListbox" >
                         <!--ItemsSource="{Binding Path=CheckList}"-->
                         <ListBox.ItemTemplate>
                             <DataTemplate>
                                 <WrapPanel  >
-                                    <CheckBox IsChecked="{Binding Path=RIsChecked,UpdateSourceTrigger=PropertyChanged}" 
+                                    <CheckBox IsChecked="{Binding Path=RIsChecked,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" 
                                       IsEnabled="{Binding Path=RIsReadOnly,Converter={StaticResource BoolInverseConverter}}"
                                       VerticalContentAlignment="Center"></CheckBox>
                                     <Label Content="{Binding Path=Name}"></Label>

+ 15 - 0
MBI/SAGA.MBI/ToolsData/DataCheck/WinDataCheckSetting.xaml.cs

@@ -6,6 +6,7 @@ using System.Globalization;
 using System.Linq;
 using System.Windows;
 using System.Windows.Data;
+using System.Windows.Input;
 using SAGA.DotNetUtils.Extend;
 using SAGA.MBI.Common;
 using SAGA.MBI.DataArrange;
@@ -135,6 +136,20 @@ namespace SAGA.MBI.ToolsData.DataCheck
             return context;
         }
 
+        private void CheckItemInverse_OnMouseDown(object sender, MouseButtonEventArgs e)
+        {
+            var items = myListbox.ItemsSource as List<ICheckBase>;
+            if (items != null)
+            {
+                foreach (ICheckBase checkBase in items)
+                {
+                    if (!checkBase.RIsReadOnly)
+                    {
+                        checkBase.RIsChecked = !checkBase.RIsChecked;
+                    }
+                }
+            }
+        }
     }
     public class FloorRadioButtonVisibleConverter : IMultiValueConverter
     {

+ 70 - 1
MBI/SAGA.MBI/ToolsData/ModeCheck/DataCheckRule.cs

@@ -8,7 +8,9 @@ using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Text;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
+using SAGA.DotNetUtils;
 using SAGA.DotNetUtils.NPOI;
 using SAGA.MBI.Common;
 using SAGA.Models;
@@ -52,6 +54,22 @@ namespace SAGA.MBI.ToolsData.ModeCheck
                 .ConvertExcelSheetToModel<DCR_MEPSystem>(DCRExport.MCRPath);
             return list;
         }
+        /// <summary>
+        /// 获取设备关联的系统类型
+        /// </summary>
+        /// <returns></returns>
+        public static List<DCR_EquipReferSystem> GetEquipReferSystems()
+        {
+            var list = NPOIHelper
+                .ConvertExcelSheetToModel<DCR_SystemReferEquip>(DCRExport.MCRPath);
+            List<Tuple<string, string>> tuples = new List<Tuple<string, string>>();
+            //将集合转化为:系统名称-设备名称
+            list.ForEach(t => t.Equips.ForEach(tt => tuples.Add(new Tuple<string, string>(t.SystemName, tt))));
+            //将集合转化为:设备名称-多个系统名称
+            var newList = tuples.GroupBy(t => t.Item2).Select(tt => new DCR_EquipReferSystem()
+            { EquipName = tt.Key, Systems = tt.Select(t => t.Item1).ToList() }).ToList();
+            return newList;
+        }
     }
     /// <summary>
     /// 参考-可识别的系统名称
@@ -74,7 +92,7 @@ namespace SAGA.MBI.ToolsData.ModeCheck
     /// <summary>
     /// 设备类是否有连接件
     /// </summary>
-    [SheetInfo(SheetName = "参考-连接件对照表", RowStartIndex = 0)]
+    [SheetInfo(SheetName = "参考-连接件对照表", RowStartIndex = 1)]
     public class DCR_Connector
     {
         [CellIndex(4)]
@@ -95,4 +113,55 @@ namespace SAGA.MBI.ToolsData.ModeCheck
         [CellIndex(9)]
         public string PipeConnector { get; set; }
     }
+    /// <summary>
+    /// 参考-管网与相关设备
+    /// </summary>
+    [SheetInfo(SheetName = "参考-管网及相关设备", RowStartIndex = 3)]
+    public class DCR_SystemReferEquip
+    {
+        [CellIndex(4)]
+        public string SystemName { get; set; }
+        [CellIndex(5)]
+        public string ReferEquipName { get; set; }
+
+        private List<string> m_Equips;
+
+        public List<string> Equips
+        {
+            get
+            {
+                if (m_Equips == null)
+                    m_Equips = ConverToList(ReferEquipName);
+                return m_Equips;
+            }
+        }
+
+        public List<string> ConverToList(string str)
+        {
+            var list = new List<string>();
+            if (str.IsNotNullEmpty())
+            {
+                Regex regex = new Regex(@"^[A-Z]{4}");
+                list = str.Split(new[] { ',', ',' })
+                    .Where(t => Regex.IsMatch(t, @"^[A-Z]{4}\s*-\s*\S*"))
+                    .Select(tt => regex.Match(tt).Value).ToList();
+            }
+
+            return list;
+        }
+    }
+    /// <summary>
+    /// 设备关联的系统
+    /// </summary>
+    public class DCR_EquipReferSystem
+    {
+        /// <summary>
+        /// 设备名称
+        /// </summary>
+        public string EquipName { get; set; }
+        /// <summary>
+        /// 系统名称
+        /// </summary>
+        public List<string> Systems { get; set; }
+    }
 }

+ 3 - 1
MBI/SAGA.MBI/ToolsData/ModeCheck/DocumentQueue.cs

@@ -1,5 +1,7 @@
 /* ==============================================================================
- * 功能描述:Document队列
+ * 功能描述:Document队列,
+ * 1,按使用频率,使用频率低的优先关闭。使用频率如何统计;
+ * 2,按文件大小,小文件优化关闭。
  * 创 建 者:Garrett
  * 创建日期:2018/11/16 9:34:39
  * ==============================================================================*/

+ 206 - 0
MBI/SAGA.MBI/ToolsData/ModeCheck/EquipReferSystemCheck.cs

@@ -0,0 +1,206 @@
+/* ==============================================================================
+ * 功能描述:管网及相关设备检查检查
+ * 创 建 者:Garrett
+ * 创建日期:2018/10/23 15:08:55
+ * ==============================================================================*/
+using Autodesk.Revit.DB;
+using NPOI.SS.UserModel;
+using SAGA.DotNetUtils.Logger;
+using SAGA.DotNetUtils.Others;
+using SAGA.MBI.Tools;
+using SAGA.MBI.ToolsData.CheckBase;
+using SAGA.RevitUtils.Extends;
+using SAGA.RevitUtils.MEP;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace SAGA.MBI.ToolsData.ModeCheck
+{
+    /// <summary>
+    /// UnitCheck
+    /// </summary>
+    class EquipReferSystemCheck : ModeCheckBase
+    {
+        public EquipReferSystemCheck()
+        {
+            Name = "管网及相关设备检查";
+            RSPecificationSheet.Add("参考-管网及相关设备");
+        }
+        [DataCheckProcessAspect]
+        public override bool Check()
+        {
+            if (!RBase.IsRight)
+            {
+                IsRight = RBase.IsRight;
+                return IsRight;
+            }
+            IsRight = GetCheckResult();
+            return IsRight;
+        }
+
+        public override void Correct()
+        {
+            throw new NotImplementedException();
+        }
+
+        private List<DCR_EquipReferSystem> m_EquipReferSystems;
+        private bool GetCheckResult()
+        {
+            bool unitResult = true;
+            m_EquipReferSystems = DataCheckRule.GetEquipReferSystems();
+            foreach (SagaSignCheckResult signResult in RBase.Results)
+            {
+                var list = Check(signResult);
+                Results.AddRange(list);
+            }
+            return Results.All(t => t.IsRight);
+
+        }
+        /// <summary>
+        /// 获取所有的设备或者部件
+        /// </summary>
+        /// <param name="document"></param>
+        /// <returns></returns>
+        private List<ModeCheckResultBase> Check(SagaSignCheckResult signResult)
+        {
+            List<ModeCheckResultBase> list = new List<ModeCheckResultBase>();
+            var familyInstances = signResult.RDocument.GetFamilyInstances();
+
+            foreach (FamilyInstance fi in familyInstances)
+            {
+                if (fi.IsEquipment() || fi.IsEquipmentPart())
+                {
+                    var result = GetCheckResult(fi);
+                    if (result == null) continue;
+                    result.RBase = signResult;
+                    list.Add(result);
+                }
+            }
+            return list;
+        }
+
+        /// <summary>
+        /// 获取检测结果
+        /// </summary>
+        /// <param name="fi"></param>
+        /// <returns></returns>
+        private ModeCheckResultBase GetCheckResult(FamilyInstance fi)
+        {
+            var result = new EquipReferSystemCheckResult();
+            var code = fi.GetFamilyCode();
+            var referSystems = GetReferSystems(code);
+            if (referSystems.Count == 0) return null;
+
+            result.FamilyName = fi.GetFamily().Name;
+            result.Id = fi.Id.ToString();
+
+            var tuple = CheckConType(fi, referSystems);
+            result.IsRight = !tuple.Item2.Any();
+            result.PassConnectorsName += string.Join("、", tuple.Item1.ToArray());
+            result.UnPassConnectorsName += string.Join("、", tuple.Item2.ToArray());
+            if (!result.IsRight)
+            {
+                result.RMessage = $"连接件所连接的管道系统与规范不一致,请检查";
+            }
+            return result;
+        }
+        /// <summary>
+        /// 可以与设备连接的系统
+        /// </summary>
+        /// <param name="code"></param>
+        /// <returns></returns>
+        private List<string> GetReferSystems(string code)
+        {
+            var item = m_EquipReferSystems.FirstOrDefault(t => t.EquipName == code)?.Systems ?? new List<string>();
+
+            return item;
+        }
+
+        /// <summary>
+        /// 检查连接件连接的管道系统是否符合规范
+        /// </summary>
+        /// <param name="result"></param>
+        /// <param name="domain"></param>
+        private Tuple<List<string>,List<string>> CheckConType(FamilyInstance fi, List<string> referSystems)
+        {
+            List<string> passList=new List<string>();
+            List<string> unpassList=new List<string>();
+
+            var connectors = fi.GetAllConnectors();
+            foreach (Connector connector in connectors)
+            {
+                try
+                {
+                    var mepSystem = connector.MEPSystem;
+                    if (mepSystem == null) continue;
+                    var elementId = mepSystem.GetTypeId();
+                    var type = fi.Document.GetElement(elementId);
+                    if (!referSystems.Contains(type.Name))
+                    {
+                        unpassList.Add(mepSystem.Name);
+                    }
+                    else
+                    {
+                        passList.Add(mepSystem.Name);
+                    }
+                }
+                catch (Exception e)
+                {
+                   Log4Net.Info($"读取连接件系统错误。Id:{fi.Id},Path:{fi.Document.PathName}");
+                }
+            }
+
+            return new Tuple<List<string>, List<string>>(passList, unpassList);
+        }
+        
+
+
+        //[DataCheckProcessAspect]
+        public override void Export()
+        {
+            //   Check();
+            try
+            {
+                IWorkbook book = DCRExport.GetWorkbook();
+                //ISheet sheet = book.CreateSheet(Name);
+                ISheet sheet = book.GetSheet(Name);
+
+                #region 添加数据
+                int index = 3;
+                //添加 共检查XXX条数据,未通过检查的如下 提示
+                IRow rowTip = sheet.CreateRow(index - 1);
+                rowTip.AddCell(0, $"总检查{Results.Count}条数据,未通过检查的如下", DataCheckNPOIStyle.Title);
+
+                foreach (EquipReferSystemCheckResult result in Results)
+                {
+                    SagaSignCheckResult rbase = result.RBase as SagaSignCheckResult;
+                    if (rbase == null)
+                        continue;
+                    //数量多过,只显示有问题的
+                    if (result.IsRight) continue;
+                    index++;
+                    IRow rowN = sheet.CreateRow(index);
+                    DataCheckNPOIStyle style = result.IsRight ? DataCheckNPOIStyle.Content : DataCheckNPOIStyle.Error;
+                    int i = 0;
+                    rowN.AddCell(i++, rbase.RFloorName, style);
+                    rowN.AddCell(i++, rbase.RFileName, style);
+                    rowN.AddCell(i++, rbase.RPath, style);
+                    rowN.AddCell(i++, result.FamilyName, style);
+                    rowN.AddCell(i++, result.Id, style);
+                    rowN.AddCell(i++, result.PassConnectorsName, style);
+                    rowN.AddCell(i++, result.UnPassConnectorsName, style);
+                    string rowN4 = result.IsRight ? "通过" : "不通过";
+                    rowN.AddCell(i++, rowN4, style);
+                    rowN.AddCell(i++, result.RMessage, style);
+                }
+                #endregion
+
+            }
+            catch (Exception e)
+            {
+                MessageShowBase.Show(e);
+            }
+        }
+    }
+}

+ 37 - 0
MBI/SAGA.MBI/ToolsData/ModeCheck/EquipReferSystemCheckResult.cs

@@ -0,0 +1,37 @@
+/* ==============================================================================
+ * 功能描述:管网及相关设备检查检查结果
+ * 创 建 者:Garrett
+ * 创建日期:2018/10/23 15:13:17
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Autodesk.Revit.DB;
+using SAGA.MBI.ToolsData.CheckBase;
+
+namespace SAGA.MBI.ToolsData.ModeCheck
+{
+    /// <summary>
+    /// UnitCheckResult
+    /// </summary>
+    class EquipReferSystemCheckResult : ModeCheckResultBase
+    {
+        public string FamilyName { get; set; }
+
+        public string Id { get; set; }
+        /// <summary>
+        /// 通过的连接件系统名称
+        /// </summary>
+        public string PassConnectorsName { get; set; }
+        /// <summary>
+        /// 不通过的连接件系统名称
+        /// </summary>
+        public string UnPassConnectorsName { get; set; }
+        public override void Export()
+        {
+            base.Export();
+        }
+    }
+}

+ 3 - 1
MBI/SAGA.MBI/ToolsData/ModeCheck/EquipmentPartRefEqCheckResult.cs

@@ -18,9 +18,11 @@ namespace SAGA.MBI.ToolsData.ModeCheck
     class EquipmentPartRefEqCheckResult : ModeCheckResultBase
     {
 
+        public string Id { get; set; }
         public string FamilyName { get; set; }
+        public string CenterXYZ { get; set; }
+        public string LocationXYZ { get; set; }
 
-        public string Id { get; set; }
         public override void Export()
         {
             base.Export();

+ 26 - 22
MBI/SAGA.MBI/ToolsData/ModeCheck/FamilyNameCheck.cs

@@ -54,6 +54,7 @@ namespace SAGA.MBI.ToolsData.ModeCheck
         {
             bool unitResult = true;
             var ccategories = DataCheckRule.GetCodeCheckCategories();
+            var list = new List<FamilyNameCheckResult>();
             foreach (SagaSignCheckResult signResult in RBase.Results)
             {
                 var document = signResult.RDocument;
@@ -78,7 +79,7 @@ namespace SAGA.MBI.ToolsData.ModeCheck
                                 result.RBase = signResult;
                                 //由于数量太多,只显示族名称
                                 result.Id = "-";
-                                Results.Add(result);
+                                list.Add(result);
                                 //foreach (var tempElem in subElements)
                                 //{
                                 //    var tempResult = result?.Clone();
@@ -96,6 +97,8 @@ namespace SAGA.MBI.ToolsData.ModeCheck
 
                 }
             }
+            //按族名称,对楼层进行合并显示
+            GroupByFamilyName(list);
             return Results.All(t => t.IsRight);
         }
         /// <summary>
@@ -131,6 +134,26 @@ namespace SAGA.MBI.ToolsData.ModeCheck
             }
             return result;
         }
+
+
+        private void GroupByFamilyName(List<FamilyNameCheckResult> modes)
+        {
+            var groupByFamilyName = modes.GroupBy(t => t.FamilyName);
+            foreach (IGrouping<string, FamilyNameCheckResult> grouping in groupByFamilyName)
+            {
+                var item = grouping.ToList().FirstOrDefault();
+                if (item == null) continue;
+
+                FamilyNameCheckResult mode = new FamilyNameCheckResult();
+                mode.FamilyName = grouping.Key;
+                mode.Type = item.Type;
+                mode.IsRight = item.IsRight;
+                if (!mode.IsRight)
+                    mode.RMessage =
+                        $"使用到该设备族的楼层:{string.Join("、", grouping.Select(t => ((SagaSignCheckResult) t.RBase).RFloorName).ToArray())}";
+                Results.Add(mode);
+            }
+        }
         //[DataCheckProcessAspect]
         public override void Export()
         {
@@ -144,33 +167,14 @@ namespace SAGA.MBI.ToolsData.ModeCheck
 
                 #region 添加数据
                 int index = 3;
-                //添加 共检查XXX条数据,未通过检查的如下 提示
-                IRow rowTip = sheet.CreateRow(index - 1);
-                rowTip.AddCell(0, $"总检查{Results.Count}条数据,未通过检查的如下", DataCheckNPOIStyle.Title);
-                //IRow row4 = sheet.CreateRow(index);
-                //row4.HeightInPoints = 15;
-
-                //row4.AddCell(0, "楼层本地名称", DataCheckNPOIStyle.Title);
-                //row4.AddCell(1, "文件名", DataCheckNPOIStyle.Title);
-                //row4.AddCell(2, "文件地址", DataCheckNPOIStyle.Title);
-                //row4.AddCell(3, "族名称", DataCheckNPOIStyle.Title);
-                //row4.AddCell(4, "类型", DataCheckNPOIStyle.Title);
-                //row4.AddCell(5, "ID", DataCheckNPOIStyle.Title);
-                //row4.AddCell(6, "通过", DataCheckNPOIStyle.Title);
-                //row4.AddCell(7, "备注(失败原因)", DataCheckNPOIStyle.Title);
                 foreach (FamilyNameCheckResult result in Results)
                 {
-                    SagaSignCheckResult rbase = result.RBase as SagaSignCheckResult;
-                    if (rbase == null)
-                        continue;
-                    if (result.IsRight) continue;
+                    //全部显示
+                    //if (result.IsRight) continue;
                     index++;
                     IRow rowN = sheet.CreateRow(index);
                     DataCheckNPOIStyle style = result.IsRight ? DataCheckNPOIStyle.Content : DataCheckNPOIStyle.Error;
                     int c = 0;
-                    rowN.AddCell(c++, rbase.RFloorName, style);
-                    rowN.AddCell(c++, rbase.RFileName, style);
-                    rowN.AddCell(c++, rbase.RPath, style);
                     rowN.AddCell(c++, result.FamilyName, style);
                     rowN.AddCell(c++, result.Type.GetDescription(), style);
                     string rowN4 = result.IsRight ? "通过" : "不通过";

+ 15 - 2
MBI/SAGA.MBI/ToolsData/ModeCheck/ModeCheckBase.cs

@@ -6,6 +6,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Linq;
 using NPOI.SS.UserModel;
 using SAGA.DotNetUtils.Others;
@@ -16,7 +17,7 @@ namespace SAGA.MBI.ToolsData.ModeCheck
     /// <summary>
     /// CheckBase
     /// </summary>
-    public class ModeCheckBase:ICheckBase
+    public class ModeCheckBase:ICheckBase,INotifyPropertyChanged
     {
 
         public CheckContext Context { get; set; }
@@ -113,12 +114,24 @@ namespace SAGA.MBI.ToolsData.ModeCheck
         /// 是否强制勾选
         /// </summary>
         public bool RIsReadOnly { get; set; }
+
+        private bool m_RIsChecked;
         /// <summary>
         /// 是否选中
         /// </summary>
-        public bool RIsChecked { get; set; }
+        public bool RIsChecked
+        {
+            get { return m_RIsChecked;}
+            set
+            {
+                m_RIsChecked = value;
+                PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(nameof(RIsChecked)));
+            } }
 
         private List<string> m_SpecificationSheet=new List<string>();
+
+        public event PropertyChangedEventHandler PropertyChanged;
+
         /// <summary>
         /// 关联规范项
         /// </summary>

+ 8 - 2
MBI/SAGA.MBI/ToolsData/ModeCheck/WinModeCheckSetting.xaml

@@ -58,8 +58,14 @@
                 </GroupBox>
             </Grid>
             <Grid Grid.Column="1">
-                <GroupBox Header="请选择检查项">
-                    <ListBox  x:Name="myListbox" >
+                <GroupBox >
+                    <GroupBox.Header>
+                        <WrapPanel>
+                            <TextBlock Text="请选择检查"></TextBlock>
+                            <TextBlock Text="项 "  MouseDown="CheckItemInverse_OnMouseDown"></TextBlock>
+                        </WrapPanel>
+                    </GroupBox.Header>
+                        <ListBox  x:Name="myListbox" >
                         <!--ItemsSource="{Binding Path=CheckList}"-->
                         <ListBox.ItemTemplate>
                             <DataTemplate>

+ 17 - 0
MBI/SAGA.MBI/ToolsData/ModeCheck/WinModeCheckSetting.xaml.cs

@@ -7,6 +7,7 @@ using System.Linq;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
+using System.Windows.Input;
 using SAGA.DotNetUtils.Extend;
 using SAGA.MBI.Common;
 using SAGA.MBI.DataArrange;
@@ -225,6 +226,22 @@ namespace SAGA.MBI.ToolsData.ModeCheck
                 }
             }
         }
+
+
+        private void CheckItemInverse_OnMouseDown(object sender, MouseButtonEventArgs e)
+        {
+            var items = myListbox.ItemsSource as List<ICheckBase>;
+            if (items != null)
+            {
+                foreach (ICheckBase checkBase in items)
+                {
+                    if (!checkBase.RIsReadOnly)
+                    {
+                        checkBase.RIsChecked = !checkBase.RIsChecked;
+                    }
+                }
+            }
+        }
     }
 }
 

+ 2 - 1
MBI/SAGA.MBI/ToolsData/UpdateFileVision.cs

@@ -9,6 +9,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using SAGA.DotNetUtils.Extend;
+using SAGA.DotNetUtils.Serializer;
 using SAGA.MBI.Common;
 using SAGA.MBI.DataArrange;
 using SAGA.MBI.FileStream;
@@ -26,7 +27,7 @@ namespace SAGA.MBI.ToolsData
         /// </summary>
         public static void Operate()
         {
-            var sequences = FileOperateBase.DeserializeList<RevitFileVision>(MBIControl.ProjectBasePath, "FileVision.json");
+            var sequences = SerializerByXml.DeserializeList<RevitFileVision>(MBIControl.ProjectBasePath, "FileVision.json");
             foreach (RevitFileVision fileVision in sequences)
             {
                 fileVision.FileName = CloudRevitNameToFloorId(fileVision.FileName);

+ 1 - 1
MBI/SAGA.MBI/ToolsData/UpdateRelationEquipinSpace.cs

@@ -131,7 +131,7 @@ namespace SAGA.MBI.ToolsData
            
         }
 
-        private static string GetMSpace(Document doc,string bimid,List<MSpace> spaces)
+        private static string GetMSpace(Document doc,string bimid,List<MISpace> spaces)
         {
             FamilyInstance fi = doc.GetElement(bimid.GetBIMID()) as FamilyInstance;
             if (fi == null) return null;

+ 317 - 0
MBI/SAGA.MBI/ToolsData/VerticalPipeAlign.cs

@@ -0,0 +1,317 @@
+/* ==============================================================================
+ * 功能描述:立管对齐
+ * 创 建 者:Garrett
+ * 创建日期:2019/1/21 16:22:40
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Plumbing;
+using SAGA.DotNetUtils.Data;
+using SAGA.DotNetUtils.Extend;
+using SAGA.DotNetUtils.Others;
+using SAGA.MBI.DataArrange;
+using SAGA.MBI.Model;
+using SAGA.MBI.Tools;
+using SAGA.RevitUtils.Extends;
+using SAGA.RevitUtils.MEP;
+
+namespace SAGA.MBI.ToolsData
+{
+    /// <summary>
+    /// VerticalPipeAlign
+    /// </summary>
+    public class VerticalPipeAlign : SingleInstance<VerticalPipeAlign>
+    {
+        public void Execute()
+        {
+            m_ErrorLogs = new List<string>();
+            List<MFloor> floors = DalProjectTree.GetSelectedFloors();
+            //两层两层对齐,从上到下依次对齐
+            for (int i = 1; i < floors.Count; i++)
+            {
+                MFloor m0 = floors[i - 1];
+                MFloor m1 = floors[i];
+                if (BeginAlign(m0, m1))
+                    break;
+            }
+
+        }
+        /// <summary>
+        /// Doc0和Doc1对齐
+        /// </summary>
+        /// <param name="doc0"></param>
+        /// <param name="doc1"></param>
+        private bool BeginAlign(MFloor m0, MFloor m1)
+        {
+            string m0Name = m0.ToString();
+            string m1Name = m1.ToString();
+
+            Document doc0 = ExternalDataWrapper.Current.App.OpenDocumentFile(m0.FullPath);
+            Document doc1 = ExternalDataWrapper.Current.App.OpenDocumentFile(m1.FullPath);
+            string path0 = doc0.PathName;
+            string path1 = doc1.PathName;
+
+            var verticalPipes = GetAllVerticalPipe(doc0);
+            verticalPipes.AddRange(GetAllVerticalPipe(doc1));
+
+            double z = GetBaseLevel(doc0);
+            var groupByNote = verticalPipes.GroupBy(t => t.Note);
+            foreach (IGrouping<string, VPipe> grouping in groupByNote)
+            {
+                //不是成对的,不处理
+                if (grouping.Count() < 2) continue;
+                var basePipe = grouping.FirstOrDefault(t => t.FloorName == path0);
+                var referPipe = grouping.FirstOrDefault(t => t.FloorName == path1);
+                if (basePipe != null && referPipe != null)
+                {
+                    using (Transaction trans = new Transaction(doc1, "立管对齐"))
+                    {
+                        trans.Start();
+                        try
+                        {
+                            FailureHandlingOptions options = trans.GetFailureHandlingOptions();
+                            VerticalPipeAlignFailuresPreProcessor failureProcessor = new VerticalPipeAlignFailuresPreProcessor();
+                            options.SetFailuresPreprocessor(failureProcessor);
+                            trans.SetFailureHandlingOptions(options);
+
+                            MoveReferPipe(basePipe.Pipe, referPipe.Pipe);
+                            //ExtendPipe(grouping.Where(t => t.FloorName == path0).Select(t => t.Pipe).ToList(), z, true);
+                            ExtendPipe(grouping.Where(t => t.FloorName == path1).Select(t => t.Pipe).ToList(), z, false);
+                            trans.Commit();
+                            if (failureProcessor.HasError)
+                            {
+                                string msg =
+                                    $"对齐时发生异常:{failureProcessor.FailureMessage}\r\n楼层:{m1Name} Id:{referPipe.Pipe.Id};参考楼层:{m0Name} Id:{basePipe.Pipe.Id}";
+                                AppendErrorLogs(msg);
+                            }
+                        }
+                        catch (Exception e)
+                        {
+                            trans.RollBack();
+                            string msg =
+                                $"楼层:{m1Name} Id:{referPipe.Pipe.Id} 对齐时发生异常,请检查!参考楼层:{m0Name} Id:{basePipe.Pipe.Id}";
+                            AppendErrorLogs(msg);
+                        }
+                    }
+                    using (Transaction trans = new Transaction(doc0, "延长立管"))
+                    {
+                        trans.Start();
+                        try
+                        {
+                            ExtendPipe(grouping.Where(t => t.FloorName == path0).Select(t => t.Pipe).ToList(), z, true);
+                            trans.Commit();
+                        }
+                        catch (Exception e)
+                        {
+                            trans.RollBack();
+                            string msg =
+                                $"楼层:{m0Name} Id:{basePipe.Pipe.Id} 延长立管时发生异常,请检查!";
+                            AppendErrorLogs(msg);
+                        }
+                    }
+                }
+            }
+
+            doc0.CloseDoc();
+            doc1.CloseDoc();
+
+            return ErrorLogs.Count > 0;
+        }
+        private List<string> m_ErrorLogs = new List<string>();
+
+        private List<string> ErrorLogs
+        {
+            get { return m_ErrorLogs; }
+        }
+
+        private void AppendErrorLogs(string msg)
+        {
+            ErrorLogs.Add(msg);
+        }
+
+        public void ShowResult()
+        {
+            if (ErrorLogs.Count == 0)
+                ErrorLogs.Add("对齐操作成功");
+            MessageShowBase.Infomation(ErrorLogs);
+        }
+        /// <summary>
+        /// 延长立管
+        /// </summary>
+        /// <param name="pipes"></param>
+        /// <param name="z"></param>
+        /// <param name="isTop"></param>
+        private void ExtendPipe(List<Pipe> pipes, double z, bool isTop = true)
+        {
+            foreach (Pipe pipe in pipes)
+            {
+                var connectors = pipe.GetConnectors();
+                var connectort = connectors.FirstOrDefault(t => t.CoordinateSystem.BasisZ.IsEqual(XYZ.BasisZ));
+                var connectorb = connectors.FirstOrDefault(t => t.CoordinateSystem.BasisZ.IsEqual(-XYZ.BasisZ));
+                if (connectort == null || connectorb == null) continue;
+                var xyzt = connectort?.Origin;
+                var xyzb = connectorb?.Origin;
+                if (xyzb == null || xyzt == null) continue;
+                if (isTop)
+                {
+                    //底部连接的不延长
+                    if (connectorb.IsConnected)
+                        continue;
+                    xyzb = xyzb.NewZ(z);
+                }
+                else
+                {
+                    if (connectort.IsConnected)
+                        continue;
+                    xyzt = xyzt.NewZ(z);
+                }
+                pipe.UpdateLocation(xyzb, xyzt);
+            }
+        }
+
+        /// <summary>
+        /// 对齐
+        /// </summary>
+        /// <param name="pipe0"></param>
+        /// <param name="pipe1"></param>
+        private void MoveReferPipe(Pipe pipe0, Pipe pipe1)
+        {
+
+            var baseOrigin = (pipe0.GetCurve() as Line)?.Origin;
+            if (baseOrigin == null) return;
+            var referOrigin = (pipe1.GetCurve() as Line)?.Origin;
+            if (referOrigin == null) return;
+            pipe1.MoveWithSub((baseOrigin - referOrigin).NewZ());
+        }
+
+        /// <summary>
+        /// 获取所有的立管
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <returns></returns>
+        private List<VPipe> GetAllVerticalPipe(Document doc)
+        {
+            var pipes = doc.GetElements<Pipe>();
+
+            var verticalPipes = pipes.Where(t => t.GetParameterString("注释") != null && Regex.IsMatch(t.GetParameterString("注释"), @"start-.*")).Select(tt => new VPipe() { Pipe = tt, FloorName = doc.PathName, Note = tt.GetParameterString("注释") }).ToList();
+
+            return verticalPipes;
+        }
+
+        #region 延长立管
+
+        private double GetBaseLevel(Document doc)
+        {
+            var sagaPlans = doc.GetElements<ViewPlan>()
+                .Where(t => t.ViewType == ViewType.FloorPlan && t.Name.Contains("-saga"));
+            //只有一个saga标记
+            var sagaPlan = sagaPlans.FirstOrDefault();
+            double hb = sagaPlan.GenLevel.Elevation;
+            return hb;
+        }
+        private Tuple<double, double> GetCurFloorLevel(Document doc)
+        {
+            var sagaPlans = doc.GetElements<ViewPlan>()
+                .Where(t => t.ViewType == ViewType.FloorPlan && t.Name.Contains("-saga"));
+            //只有一个saga标记
+            var sagaPlan = sagaPlans.FirstOrDefault();
+            double hb = sagaPlan.GenLevel.Elevation;
+            double ht = 0;
+            double hj = 0;
+            //设置楼层底部高度
+            var curLevelName = sagaPlan.GenLevel.Name;
+            //设置楼层顶部高度
+            if (curLevelName == "RF" || curLevelName == "RFM")
+            {
+                ht = double.MaxValue;
+                hj = double.MaxValue;
+            }
+            else
+            {
+                var levels = doc.GetLevels();
+                var mbiLevels = levels.Where(t => Regex.IsMatch(t.Name, @"([BF][1-9]\d*M?|RFM?)"));
+                var topLevel = mbiLevels.FirstOrDefault(t => t.Elevation.IsThan(hb));
+                if (topLevel == null)
+                {
+                    throw new Exception($"标高编码不合法:{curLevelName}不应该是顶层,缺少标高RF或标高RF标注的位置不正确");
+                }
+
+                double nextL = topLevel.Elevation;
+                string tempTopLevelName = topLevel.Name;
+                //如果是夹层,获取夹层的上一层
+                if (Regex.IsMatch(tempTopLevelName, @"([BF][1-9]\d*M|RFM)"))
+                {
+                    hj = nextL;
+                    topLevel = mbiLevels.FirstOrDefault(t => t.Elevation.IsThan(nextL));
+                    if (topLevel == null)
+                    {
+                        throw new Exception($"标高编码不合法:{tempTopLevelName}不应该是顶层,缺少标高RF或标高RF标注的位置不正确");
+                    }
+                    else
+                    {
+                        ht = topLevel.Elevation;
+                    }
+                }
+                else
+                {
+                    hj = nextL;
+                    ht = nextL;
+                }
+
+            }
+            return null;
+        }
+        #endregion
+
+    }
+    public class VPipe
+    {
+        public Pipe Pipe { get; set; }
+
+        public string FloorName { get; set; }
+
+        public string Note { get; set; }
+    }
+    public class VerticalPipeAlignFailuresPreProcessor : IFailuresPreprocessor
+    {
+        private string _failureMessage;
+        private bool _hasError;
+        public string FailureMessage
+        {
+            get { return _failureMessage; }
+            set { _failureMessage = value; }
+        }
+        public bool HasError
+        {
+            get { return _hasError; }
+            set { _hasError = value; }
+        }
+        public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
+        {
+            var failures = failuresAccessor.GetFailureMessages();
+            if (failures.Count == 0)
+                return FailureProcessingResult.Continue;
+
+            foreach (var failure in failures)
+            {
+                if (failure.GetSeverity() == FailureSeverity.Error)
+                {
+                    _failureMessage = failure.GetDescriptionText(); // get the failure description
+                    _hasError = true;
+                    return FailureProcessingResult.ProceedWithRollBack;
+                }
+                if (failure.GetSeverity() == FailureSeverity.Warning)
+                {
+                    failuresAccessor.DeleteWarning(failure);
+                }
+            }
+
+            return FailureProcessingResult.Continue;
+        }
+    }
+}

+ 91 - 0
MBI/SAGA.MBI/ToolsData/WinSelectCheckFloors.xaml

@@ -0,0 +1,91 @@
+<Window x:Class="SAGA.MBI.ToolsData.ModeCheck.WinSelectCheckFloors"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:SAGA.MBI.ToolsData.ModeCheck"
+             xmlns:common="clr-namespace:SAGA.MBI.Common"
+             xmlns:converter="clr-namespace:SAGA.DotNetUtils.WPF.Converter;assembly=SAGA.DotNetUtils"
+             xmlns:userControl="clr-namespace:SAGA.DotNetUtils.WPF.UserControl;assembly=SAGA.DotNetUtils"
+             xmlns:checkBase="clr-namespace:SAGA.MBI.ToolsData.CheckBase"
+             xmlns:dataCheck="clr-namespace:SAGA.MBI.ToolsData.DataCheck"
+             mc:Ignorable="d"  Title="选择楼层" WindowStartupLocation="CenterScreen"
+             Height="587" Width="400">
+    <Window.Resources>
+        <converter:BoolToInverserConverter x:Key="BoolInverseConverter"></converter:BoolToInverserConverter>
+        <converter:StringToImageConverter x:Key="StringToImageConverter"></converter:StringToImageConverter>
+    </Window.Resources>
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="40"></RowDefinition>
+            <RowDefinition Height="*"></RowDefinition>
+            <RowDefinition Height="40"></RowDefinition>
+        </Grid.RowDefinitions>
+        <Grid Grid.Row="0">
+            <WrapPanel VerticalAlignment="Center">
+                <Label Margin="5,0,0,0" Content="当前项目:" FontSize="15"></Label>
+                <Label Content="{x:Static common:MBIControl.ProjectCur}" FontSize="15"></Label>
+            </WrapPanel>
+        </Grid>
+        <Grid Grid.Row="1">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="*"></ColumnDefinition>
+            </Grid.ColumnDefinitions>
+            <Grid Grid.Column="0">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="*"></RowDefinition>
+                </Grid.RowDefinitions>
+                <GroupBox Grid.Row="0" Header="请选择需要检查的建筑">
+                    <TreeView ItemsSource="{Binding Path=ProjectList}">
+                        <TreeView.ItemTemplate>
+                            <HierarchicalDataTemplate ItemsSource="{Binding Path=Children}">
+                                <WrapPanel>
+                                    <CheckBox IsChecked="{Binding Path=IsSelected,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
+                                              Width="Auto" VerticalContentAlignment="Center" 
+                                              Click="TreeItem_Click">
+                                    </CheckBox>
+                                    <Label Content="{Binding Path=Item.TvItemName}"></Label>
+                                </WrapPanel>
+                            </HierarchicalDataTemplate>
+                        </TreeView.ItemTemplate>
+                        <TreeView.ItemContainerStyle>
+                            <Style TargetType="{x:Type TreeViewItem}">
+                                <Setter Property="IsExpanded" Value="True" />
+                            </Style>
+                        </TreeView.ItemContainerStyle>
+                    </TreeView>
+                </GroupBox>
+            </Grid>
+        </Grid>
+        <Grid Grid.Row="2">
+            <Grid.RowDefinitions>
+                <RowDefinition></RowDefinition>
+            </Grid.RowDefinitions>
+            <Grid Grid.Row="0">
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition></ColumnDefinition>
+                    <ColumnDefinition></ColumnDefinition>
+                </Grid.ColumnDefinitions>
+                <Button Grid.Column="0" Width="100" Height="25" Content="确定" HorizontalAlignment="Right" Margin="0,0,20,0" VerticalAlignment="Center" Click="ButtonNext_OnClick" IsDefault="True"></Button>
+                <Button Grid.Column="1" Width="100" Height="25" Content="取消" HorizontalAlignment="Left" Margin="20,0,0,0" VerticalAlignment="Center" IsCancel="True"  Background="White"></Button>
+
+            </Grid>
+        </Grid>
+
+    </Grid>
+</Window>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 146 - 0
MBI/SAGA.MBI/ToolsData/WinSelectCheckFloors.xaml.cs

@@ -0,0 +1,146 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Input;
+using SAGA.DotNetUtils.Extend;
+using SAGA.MBI.Common;
+using SAGA.MBI.DataArrange;
+using SAGA.MBI.Model;
+using SAGA.MBI.ToolsData.CheckBase;
+
+namespace SAGA.MBI.ToolsData.ModeCheck
+{
+    /// <summary>
+    /// WinModeCheckSetting.xaml 的交互逻辑
+    /// </summary>
+    public partial class WinSelectCheckFloors : INotifyPropertyChanged
+    {
+        private CheckType m_CheckType;
+        public WinSelectCheckFloors()
+        {
+            InitializeComponent();
+            Init();
+            this.DataContext = this;
+
+        }
+
+        private void Init()
+        {
+            ProjectList = MBIControl.ProjectTree.Children;
+            if (ProjectList.FirstOrDefault() != null)
+                SetTreeItemState(ProjectList.FirstOrDefault(), false);
+        }
+
+
+        #region BindingProperty
+
+        private ObservableCollection<TreeNodeItem> m_ProjectList;
+
+        public ObservableCollection<TreeNodeItem> ProjectList
+        {
+            get { return m_ProjectList; }
+            set { m_ProjectList = value; }
+        }
+        
+        public event PropertyChangedEventHandler PropertyChanged;
+        #endregion
+
+
+        #region Action
+
+        
+        private void ButtonNext_OnClick(object sender, RoutedEventArgs e)
+        {
+            if (CanExecute())
+            {
+                this.DialogResult = true;
+            }
+        }
+
+        private bool CanExecute()
+        {
+            bool result = DalProjectTree.GetSelectedBuilding()?.Id != null; ;
+            if (!result)
+            {
+                MessageBox.Show("请选择需要检查的建筑");
+                if (ProjectList.FirstOrDefault() != null)
+                    SetTreeItemState(ProjectList.FirstOrDefault(), true);
+            }
+
+
+            return result;
+        }
+        #endregion
+       
+
+        private void TreeItem_Click(object sender, RoutedEventArgs e)
+        {
+            if (sender is CheckBox chk)
+            {
+                bool state = chk.IsChecked == true;
+                if (chk.DataContext is TreeNodeItem node)
+                {
+                    SetTreeItemState(node, state);
+                }
+            }
+        }
+        /// <summary>
+        /// 设置节点状态
+        /// </summary>
+        /// <param name="node"></param>
+        /// <param name="state"></param>
+        private void SetTreeItemState(TreeNodeItem node, bool state)
+        {
+            node.IsSelected = state;
+            SetChildrenState(node, state);
+            SetParentState(node, state);
+        }
+        /// <summary>
+        /// 设置子节点状态
+        /// </summary>
+        /// <param name="node"></param>
+        /// <param name="state"></param>
+        private void SetChildrenState(TreeNodeItem node, bool state)
+        {
+            foreach (TreeNodeItem child in node.Children)
+            {
+                child.IsSelected = state;
+            }
+        }
+        /// <summary>
+        /// 设置父节点状态
+        /// </summary>
+        /// <param name="node"></param>
+        /// <param name="state"></param>
+        private void SetParentState(TreeNodeItem node, bool state)
+        {
+            if (node.Parent != null)
+            {
+                if (node.Parent.Item is MProject)
+                {
+                    if (state)
+                    {
+                        foreach (var child in node.Parent.Children)
+                        {
+                            if (child != node)
+                            {
+                                child.IsSelected = false;
+                                SetChildrenState(child, false);
+                            }
+                        }
+                    }
+                }
+                node.Parent.IsSelected = node.Parent.Children.Any(t => t.IsSelected);
+                SetParentState(node.Parent, state);
+            }
+
+        }
+    }
+}
+

+ 4 - 4
MBI/SAGA.MBI/WinView/BeModingDutyList/WinFMMergeTip4.xaml

@@ -17,16 +17,16 @@
             请确认需要保留与哪个资产的关联关系?
         </TextBlock>
         <StackPanel Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
-            <WrapPanel >
-                <RadioButton x:Name="rdo1" IsChecked="True"></RadioButton>
+            <WrapPanel Margin="5">
+                <RadioButton x:Name="rdo1" IsChecked="True" GroupName="hh"></RadioButton>
                 <TextBlock  HorizontalAlignment="Center" VerticalAlignment="Center">
                     <Hyperlink Click="Hyperlink_OnClick">
                         <TextBlock Text="点击查看资产详情"></TextBlock>
                     </Hyperlink>
                 </TextBlock>
             </WrapPanel>
-            <WrapPanel >
-                <RadioButton x:Name="rdo2"></RadioButton>
+            <WrapPanel Margin="5">
+                <RadioButton x:Name="rdo2" GroupName="hh"></RadioButton>
                 <TextBlock  HorizontalAlignment="Center" VerticalAlignment="Center">
                     <Hyperlink Click="Hyperlink2_OnClick">
                         <TextBlock Text="点击查看资产详情"></TextBlock>

+ 4 - 3
MBI/SAGA.MBI/WinView/Login/UcMFMFloorUp.xaml

@@ -27,9 +27,10 @@
             <Grid.RowDefinitions>
                 <RowDefinition Height="*"/>
                 <RowDefinition Height="50"/>
-            </Grid.RowDefinitions> <Label FontSize="25" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" >
-                <TextBlock Text="{Binding Path=PathDisplay,UpdateSourceTrigger=PropertyChanged}" TextWrapping="WrapWithOverflow"></TextBlock>
-            </Label>
+            </Grid.RowDefinitions>
+            <TextBox FontSize="25" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center"  BorderThickness="0"
+                       Text="{Binding Path=PathDisplay,UpdateSourceTrigger=PropertyChanged}" TextWrapping="WrapWithOverflow">
+            </TextBox>
             <WrapPanel VerticalAlignment="Center" HorizontalAlignment="Right" Grid.Row="1" Height="30" Margin="0,0,30,0"
                        Visibility="{Binding Path=FloorLock.LockState,Converter={StaticResource LockStateToVisibleConverter},ConverterParameter={x:Static model:MFloorLockState.LockBySelf} }">
                 <Button Click="ButtonBase_OnClick">

+ 3 - 2
MBI/SAGA.MBI/WinView/ModeInfoMaintenance/PWGInstace.cs

@@ -47,8 +47,9 @@ namespace SAGA.MBI.WinView.ModeInfoMaintenance
             PropertyDefineTb pdtb = PEPCodeConvert.GetPropertyDefineTb(code);
             foreach (var pdItem in pdtb.PropertyDefineItems)
             {
-                if (!pdItem.IsShow) continue;
-                if (equipment is MSpace)
+                //此时默认都显示,后期会添加选择控制,只显示推荐还是全部显示
+                //if (!pdItem.IsShow) continue;
+                if (equipment is MISpace)
                 {
                     //空间
                     var list = new List<string>() { "RoomID", "RoomName", "RoomLocalID", "RoomLocalName", "BIMID" };

+ 1 - 0
MBI/SAGA.MBI/WinView/ModeInfoMaintenance/WinMatchFMTip_FMNoBimId.xaml.cs

@@ -119,6 +119,7 @@ namespace SAGA.MBI.WinView.ModeInfoMaintenance
         private int GetNullItemsCount()
         {
             var source = InfoGrid.ItemsSource;
+            if (source == null) return 0;
             var items = new List<ItemProperty>();
             foreach (ItemProperty item in source)
             {

+ 1 - 1
MBI/SAGA.MBI/WinView/ModeInfoMaintenance/WinModeInfoMaintenance.xaml.cs

@@ -93,7 +93,7 @@ namespace SAGA.MBI.WinView.ModeInfoMaintenance
                 CompositeItem item = NullPWGInstace.GetUnknownBeaconItems(EquipmentInfo);
                 myWPG.Instance = item;
             }
-            else if (EquipmentInfo is MSpace space)
+            else if (EquipmentInfo is MISpace space)
             {
                 space.Name = "元空间";
                 GridNone.Visibility = Visibility.Visible;

+ 1 - 1
MBI/SAGA.MBI/WinView/ModeInfoMaintenance/WinModeInfoMaintenanceForSpace.xaml.cs

@@ -100,7 +100,7 @@ namespace SAGA.MBI.WinView.ModeInfoMaintenance
                 CompositeItem item = NullPWGInstace.GetUnknownBeaconItems(EquipmentInfo);
                 myWPG.Instance = item;
             }
-            else if (EquipmentInfo is MSpace space) {
+            else if (EquipmentInfo is MISpace space) {
                 space.Name = "元空间";
                 GridNone.Visibility = Visibility.Visible;
                 CompositeItem item = NullPWGInstace.GetUnknownSpaceItems(EquipmentInfo?.BimID);

+ 3 - 3
MBI/SAGA.MBI/WinView/Space/FloorSpaceContext.cs

@@ -60,12 +60,12 @@ namespace SAGA.MBI.WinView
         /// <summary>
         /// 物理世界存在元空间
         /// </summary>
-        public List<MSpace> ServerSpaces { get;private set; }
-        public  List<MSpace> GetPhysicalSpaces(List<string> elementIds)
+        public List<MISpace> ServerSpaces { get;private set; }
+        public  List<MISpace> GetPhysicalSpaces(List<string> elementIds)
         {
             if (ServerSpaces == null)
             {
-                    ServerSpaces = SpaceConvert.GetFloorSpaceInfos(this.Floor?.Id).OfType<MSpace>().ToList();
+                    ServerSpaces = SpaceConvert.GetFloorSpaceInfos(this.Floor?.Id).OfType<MISpace>().ToList();
             }
             var   spaces= ServerSpaces.Where(s => elementIds.Exists(id => id.ToString() == s.BimID.Split(':')[1])).ToList();      
             return spaces;

+ 1 - 1
MBI/SAGA.MBI/WinView/Space/ServerSpace.cs

@@ -21,7 +21,7 @@ namespace SAGA.MBI.WinView.Space {
             set => SetProperty(ref this.m_Name, value);
         }
 
-        public MSpace Space { get; set ; }
+        public MISpace Space { get; set ; }
         //是否选中
 
         private bool m_ischecked;

+ 2 - 2
MBI/SAGA.MBI/WinView/Space/SpaceManager.cs

@@ -40,7 +40,7 @@ namespace SAGA.MBI.WinView
         /// </summary>
         /// <param name="space"></param>
         /// <returns></returns>
-        public static string GetElementId(MSpace space)
+        public static string GetElementId(MISpace space)
         {
             return space.BimID.Split(':')[1];
         }
@@ -214,7 +214,7 @@ namespace SAGA.MBI.WinView
                     var groupName = $"待合并元空间组{index}";
                     foreach (var mRevitEquipBase in spacesServerInfo)
                     {
-                        if (mRevitEquipBase is MSpace space)
+                        if (mRevitEquipBase is MISpace space)
                         {
                             serverSpaces.Add(new ServerSpace()
                             {

+ 5 - 5
MBI/SAGA.MBI/WinView/Space/WinCreateSpace.xaml.cs

@@ -876,7 +876,7 @@ namespace SAGA.MBI.WinView.Space
                         this.canvas.Children.Clear();
                         //添加默认提示
                         CanvasDefaultTips();
-                        lbSpaces.ItemsSource = new ObservableCollection<MSpace>();
+                        lbSpaces.ItemsSource = new ObservableCollection<MISpace>();
                         WinModeInfoMaintenance.GetWindow().Hide();
                     }
                     else
@@ -942,11 +942,11 @@ namespace SAGA.MBI.WinView.Space
             var datas = CurrentContext.GetPhysicalSpaces(spaces.Select(t => t.Id.IntegerValue.ToString()).ToList());
 
             var localSpace = spaces.Where(t => !datas.Any(s => s.BimID.Split(':')[1] == t.Id.ToString()))
-                .Select(t => new MSpace("", $"{Guid.NewGuid()}:{t.Id.ToString()}") { Name = t.Name });
+                .Select(t => new MISpace("", $"{Guid.NewGuid()}:{t.Id.ToString()}") { Name = t.Name });
             datas.AddRange(localSpace);
             //List<string> dd;
             //dd.AddRange();
-            lbSpaces.ItemsSource = new ObservableCollection<MSpace>(datas);
+            lbSpaces.ItemsSource = new ObservableCollection<MISpace>(datas);
         }
 
         
@@ -1009,7 +1009,7 @@ namespace SAGA.MBI.WinView.Space
             {
                 #region 核心代码
                 if (lbSpaces.SelectedItems.Count == 0) return;
-                var space = lbSpaces.SelectedItems[0] as MSpace;
+                var space = lbSpaces.SelectedItems[0] as MISpace;
                 var bimId = space.BimID.Split(':')[1];
                 foreach (var polyline in this.canvas.Children.OfType<WPolyline>())
                 {
@@ -1120,7 +1120,7 @@ namespace SAGA.MBI.WinView.Space
                     //反选右侧树
                     for (int i = 0; i < lbSpaces.Items.Count; i++)
                     {
-                        var showSpace = lbSpaces.Items[i] as MSpace;
+                        var showSpace = lbSpaces.Items[i] as MISpace;
                         var spaceId = showSpace.BimID.Split(':')[1];
                         if (spaceId == space.Id.ToString())
                         {

+ 4 - 4
MBI/SAGA.MBI/WinView/Space/WinCreateSpaceWeb.xaml.cs

@@ -97,7 +97,7 @@ namespace SAGA.MBI.WinView.Space
             try
             {
                 if (lbSpaces.SelectedItems.Count == 0) return;
-                var space = lbSpaces.SelectedItems[0] as MSpace;
+                var space = lbSpaces.SelectedItems[0] as MISpace;
                 var bimId = space.BimID.Split(':')[1];
                 //发送js填充命令
                 var strJs = $"getData('{bimId.ToString()}')";
@@ -170,7 +170,7 @@ namespace SAGA.MBI.WinView.Space
         private void ClearFloorData()
         {
             WinModeInfoMaintenance.GetWindow().Hide();
-            this.lbSpaces.ItemsSource = new ObservableCollection<MSpace>(); ;
+            this.lbSpaces.ItemsSource = new ObservableCollection<MISpace>(); ;
         }
         /// <summary>
         /// 设置窗口楼层相关数据
@@ -180,9 +180,9 @@ namespace SAGA.MBI.WinView.Space
             var spaces = CurrentContext.Document.GetElements<SpatialElement>().Where(s => s is Autodesk.Revit.DB.Mechanical.Space && s.Area > 0).ToList();
             var datas = CurrentContext.GetPhysicalSpaces(spaces.Select(t => t.Id.IntegerValue.ToString()).ToList());
             var localSpace = spaces.Where(t => !datas.Any(s => s.BimID.Split(':')[1] == t.Id.ToString()))
-                .Select(t => new MSpace("", $"{Guid.NewGuid()}:{t.Id.ToString()}") { Name = t.Name});
+                .Select(t => new MISpace("", $"{Guid.NewGuid()}:{t.Id.ToString()}") { Name = t.Name});
             datas.AddRange(localSpace);
-            lbSpaces.ItemsSource = new ObservableCollection<MSpace>(datas);
+            lbSpaces.ItemsSource = new ObservableCollection<MISpace>(datas);
         }
 
         #endregion

+ 1 - 0
MBI/SAGA.RevitUtils/ExtendInterface/RevitEventsBingding.cs

@@ -21,6 +21,7 @@ namespace SAGA.RevitUtils
             CurrentApp = application;
             application.ControlledApplication.DocumentSaved += Application_DocumentSaved;
             AddUpdater();
+            ServiceSetting.LoadServices();
         }
         public static void RemoveEvents(UIControlledApplication application)
         {

+ 34 - 0
MBI/SAGA.RevitUtils/ExtendInterface/ServiceSetting.cs

@@ -0,0 +1,34 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:ServiceSetting
+ * 作者:xulisong
+ * 创建时间: 2019/1/18 11:05:09
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml;
+using SAGA.DotNetUtils;
+using SAGA.DotNetUtils.Service;
+
+namespace SAGA.RevitUtils.ExtendInterface
+{
+    public class ServiceSetting
+    {
+        /// <summary>
+        /// 加载默认服务
+        /// </summary>
+        public static void LoadServices()
+        {
+            string fileName = Path.Combine(AppBaseInfo.AppRunPath, @"MBIResource\Services\Services.xml");
+            if (File.Exists(fileName))
+            {
+                ServiceLocator.Current.LoadServices(fileName);
+            }
+        }
+    }
+}

+ 0 - 1
MBI/SAGA.RevitUtils/Extends/ExternalApplication.cs

@@ -55,7 +55,6 @@ namespace SAGA.RevitUtils.Extends
                 //´«µÝDocumentChangedʼþ
                 TszDocChanged(sender, e);
             }
-          System.Diagnostics.Debug.WriteLine($"{DateTime.Now}±»ÐÞ¸ÄÁË£¡");
         }
 
         /// <summary>

+ 0 - 0
MBI/SAGA.RevitUtils/MEP/PipeExtend.cs


Неке датотеке нису приказане због велике количине промена