DalModeFileManange.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /* ==============================================================================
  2. * 功能描述:DalModeFileManange
  3. * 创 建 者:Garrett
  4. * 创建日期:2018/3/13 17:09:05
  5. * ==============================================================================*/
  6. using System;
  7. using System.Collections.Generic;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using System.Windows.Markup;
  13. using Autodesk.Revit.DB;
  14. using Autodesk.Revit.DB.Events;
  15. using Autodesk.Revit.UI;
  16. using DevExpress.Xpf.CodeView;
  17. using SAGA.DotNetUtils;
  18. using SAGA.DotNetUtils.Extend;
  19. using SAGA.DotNetUtils.Logger;
  20. using SAGA.DotNetUtils.Others;
  21. using SAGA.MBI.Calc;
  22. using SAGA.MBI.Common;
  23. using SAGA.MBI.Interaction;
  24. using SAGA.MBI.JsonConvert;
  25. using SAGA.MBI.Login;
  26. using SAGA.MBI.Model;
  27. using SAGA.MBI.RequestData;
  28. using SAGA.MBI.Tools;
  29. using SAGA.MBI.WinView.Login;
  30. using SAGA.MBI.WinView.TraceView;
  31. using SAGA.RevitUtils.Log;
  32. using SAGA.RevitUtils.MEP;
  33. using SAGA.RevitUtils.Windows;
  34. namespace SAGA.MBI.DataArrange
  35. {
  36. /// <summary>
  37. /// DalModeFileManange
  38. /// </summary>
  39. public class DalModeFileManange
  40. {
  41. /// <summary>
  42. /// 获取整颗树
  43. /// </summary>
  44. /// <param name="id"></param>
  45. /// <returns></returns>
  46. public static TreeNodeItem GetAllModeFiles()
  47. {
  48. Log4Net.Debug("开始:获取整颗树");
  49. MProject project = MBIControl.ProjectCur;
  50. var projectId = project.Id;
  51. TreeNodeItem treeNode0 = new TreeNodeItem(project);
  52. treeNode0.ImageStr = MBIConst.MBIImagePath + "/folder.png";
  53. List<MBuilding> buildings = ModeFileConvert.GetProjectBuildings(projectId);
  54. foreach (MBuilding building in buildings)
  55. {
  56. building.RelativePath = Path.Combine(project.RelativePath, building.Id);
  57. TreeNodeItem treeNode00 = new TreeNodeItem(building);
  58. treeNode00.ImageStr = MBIConst.MBIImagePath + "/folder.png";
  59. treeNode0.AddChild(treeNode00);
  60. List<MFloor> floors = ModeFileConvert.GetBuildingFloors(building.Id);
  61. foreach (MFloor floor in floors)
  62. {
  63. string fileName = "";
  64. floor.RelativePath = Path.Combine(building.RelativePath, fileName);
  65. TreeNodeItem treeNode000 = new TreeNodeItem(floor);
  66. treeNode000.ImageStr = MBIConst.MBIImagePath + "/page.png";
  67. treeNode00.AddChild(treeNode000);
  68. }
  69. SortTreeItem(treeNode00);
  70. }
  71. Log4Net.Debug("结束:获取整颗树");
  72. return treeNode0;
  73. }
  74. /// <summary>
  75. /// 获取缺少模型的Tree
  76. /// </summary>
  77. /// <param name="isMissFile">True 缺少模型;False 不缺少;null全部</param>
  78. /// <returns></returns>
  79. public static List<TreeNodeItem> GetMissFileFloors(bool isMissFile = true)
  80. {
  81. List<TreeNodeItem> trees = new List<TreeNodeItem>();
  82. foreach (TreeNodeItem buildingTree in MBIControl.ProjectTree.Children)
  83. {
  84. if (buildingTree.Item is MBuilding building)
  85. {
  86. TreeNodeItem tempbuildingTree = new TreeNodeItem(building);
  87. tempbuildingTree.ImageStr = MBIConst.MBIImagePath + "/folder.png";
  88. foreach (TreeNodeItem floorTree in buildingTree.Children)
  89. {
  90. if (floorTree.Item is MFloor floor)
  91. {
  92. if (isMissFile == null || isMissFile == floor.IsMissFile)
  93. {
  94. TreeNodeItem tempfloorTree = new TreeNodeItem(floor);
  95. tempfloorTree.ImageStr = MBIConst.MBIImagePath + "/page.png";
  96. tempbuildingTree.AddChild(tempfloorTree);
  97. }
  98. }
  99. }
  100. if (tempbuildingTree.Children.Count != 0)
  101. {
  102. trees.Add(tempbuildingTree);
  103. }
  104. DalModeFileManange.SortTreeItem(tempbuildingTree);
  105. }
  106. }
  107. return trees;
  108. }
  109. /// <summary>
  110. /// 对Tree进行排序
  111. /// </summary>
  112. /// <param name="parentItem"></param>
  113. public static void SortTreeItem(TreeNodeItem parentItem)
  114. {
  115. if (parentItem.Item is MBuilding)
  116. {
  117. var list = parentItem.Children.ToList();
  118. list.Sort(new TNMFloorComparer());
  119. parentItem.Children = new System.Collections.ObjectModel.ObservableCollection<TreeNodeItem>(list);
  120. }
  121. }
  122. /// <summary>
  123. /// 获取树结点下的楼层
  124. /// </summary>
  125. /// <param name="treeItem"></param>
  126. /// <param name="floors"></param>
  127. public static List<MFloor> GetAllFloors(TreeNodeItem treeItem)
  128. {
  129. List<MFloor> floors = new List<MFloor>();
  130. GetAllFloors(treeItem, floors);
  131. return floors;
  132. }
  133. /// <summary>
  134. /// 获取树结点下的楼层
  135. /// </summary>
  136. /// <param name="treeItem"></param>
  137. /// <param name="floors"></param>
  138. private static void GetAllFloors(TreeNodeItem treeItem, List<MFloor> floors)
  139. {
  140. foreach (var item in treeItem.Children)
  141. {
  142. var mode = item.Item;
  143. if (mode is MFloor floor)
  144. floors.Add(floor);
  145. else
  146. {
  147. GetAllFloors(item, floors);
  148. }
  149. }
  150. }
  151. /// <summary>
  152. /// 由楼层id获取Floor的前一个树节点
  153. /// 楼层的上一层 现行规则为:获取当前层的上一层,当前层楼层序列号为1,上一层序列号为5,直接返回序列号为5的楼层
  154. /// </summary>
  155. /// <param name="id"></param>
  156. /// <returns></returns>
  157. public static TreeNodeItem GetUpperFloorTreeById(string id)
  158. {
  159. TreeNodeItem tree = null;
  160. foreach (TreeNodeItem buildingTree in MBIControl.ProjectTree.Children)
  161. {
  162. TreeNodeItem parenttree = null;
  163. foreach (TreeNodeItem floorTree in buildingTree.Children)
  164. {
  165. if (floorTree.Item is MFloor floor)
  166. {
  167. if (floor.Id == id)
  168. {
  169. tree = floorTree;
  170. break;
  171. }
  172. }
  173. parenttree = floorTree;
  174. }
  175. if (tree != null)
  176. {
  177. tree = parenttree;
  178. break;
  179. }
  180. }
  181. return tree;
  182. }
  183. private static Dictionary<string, TreeNodeItem> m_ProjectTreeDic = new Dictionary<string, TreeNodeItem>();
  184. /// <summary>
  185. /// 刷新字典
  186. /// </summary>
  187. private static void ReLoadProjectTreeDic()
  188. {
  189. m_ProjectTreeDic.Clear();
  190. foreach (TreeNodeItem buildingTree in MBIControl.ProjectTree.Children)
  191. {
  192. if (buildingTree.Item is MBuilding building)
  193. {
  194. m_ProjectTreeDic.Add(building.Id, buildingTree);
  195. foreach (TreeNodeItem floorTree in buildingTree.Children)
  196. {
  197. if (floorTree.Item is MFloor floor)
  198. {
  199. m_ProjectTreeDic.Add(floor.Id, floorTree);
  200. }
  201. }
  202. }
  203. }
  204. }
  205. /// <summary>
  206. /// 由楼层id获取Building树节点
  207. /// </summary>
  208. /// <param name="id"></param>
  209. /// <returns></returns>
  210. public static TreeNodeItem GetBuildingItemByFloorId(string floorId)
  211. {
  212. TreeNodeItem tree = GetFloorTreeById(floorId);
  213. return tree?.Parent;
  214. }
  215. /// <summary>
  216. /// 由楼层id获取Floor树节点
  217. /// </summary>
  218. /// <param name="id"></param>
  219. /// <returns></returns>
  220. public static TreeNodeItem GetFloorTreeById(string id)
  221. {
  222. TreeNodeItem tree =m_ProjectTreeDic.GetValue(id);
  223. if (tree == null)
  224. {
  225. ReLoadProjectTreeDic();
  226. tree = m_ProjectTreeDic.GetValue(id);
  227. }
  228. return tree;
  229. }
  230. /// <summary>
  231. /// 新旧文件对比过后,需要删除的数据
  232. /// </summary>
  233. public static CalcContext GetDelContext(CalcContext oldContext, CalcContext newContext, bool isExceptSpace = false)
  234. {
  235. CalcContext context = new CalcContext(newContext.MFloor);
  236. var equips = oldContext.MEquipments.Except(newContext.MEquipments,
  237. new CommonEqualComparer<MEquipment>((a, b) => { return a.BimID == b.BimID; }));
  238. context.MEquipments.AddRange(equips);
  239. var equipParts = oldContext.MEquipmentParts.Except(newContext.MEquipmentParts,
  240. new CommonEqualComparer<MEquipmentPart>((a, b) =>
  241. {
  242. return a.BimID == b.BimID;
  243. }));
  244. context.MEquipmentParts.AddRange(equipParts);
  245. var beacons = oldContext.MBeacons.Except(newContext.MBeacons,
  246. new CommonEqualComparer<MBeacon>((a, b) => { return a.BimID == b.BimID; }));
  247. context.MBeacons.AddRange(beacons);
  248. //模型文件替换后,元空间重新上传,之前的不保留
  249. if (isExceptSpace)
  250. {
  251. var spaces = oldContext.MSpaces.Except(newContext.MSpaces,
  252. new CommonEqualComparer<MISpace>((a, b) => { return a.BimID == b.BimID; }));
  253. context.MSpaces.AddRange(spaces);
  254. }
  255. else
  256. {
  257. context.MSpaces.AddRange(oldContext.MSpaces);
  258. }
  259. return context;
  260. }
  261. /// <summary>
  262. /// 新旧文件对比过后,需要更新的数据
  263. /// </summary>
  264. public static CalcContext GetModifyContext(CalcContext oldContext, CalcContext newContext, bool isExceptSpace = false)
  265. {
  266. CalcContext context = new CalcContext(newContext.MFloor);
  267. var equips = oldContext.MEquipments.Intersect(newContext.MEquipments,
  268. new CommonEqualComparer<MEquipment>((a, b) => { return a.BimID == b.BimID; }));
  269. context.MEquipments.AddRange(equips);
  270. var equipParts = oldContext.MEquipmentParts.Intersect(newContext.MEquipmentParts,
  271. new CommonEqualComparer<MEquipmentPart>((a, b) =>
  272. {
  273. return a.BimID == b.BimID;
  274. }));
  275. context.MEquipmentParts.AddRange(equipParts);
  276. var beacons = oldContext.MBeacons.Intersect(newContext.MBeacons,
  277. new CommonEqualComparer<MBeacon>((a, b) => { return a.BimID == b.BimID; }));
  278. context.MBeacons.AddRange(beacons);
  279. //模型文件替换后,元空间重新上传,之前的不保留
  280. if (isExceptSpace)
  281. {
  282. var spaces = oldContext.MSpaces.Intersect(newContext.MSpaces,
  283. new CommonEqualComparer<MISpace>((a, b) => { return a.BimID == b.BimID; }));
  284. context.MSpaces.AddRange(spaces);
  285. }
  286. else
  287. {
  288. context.MSpaces.AddRange(oldContext.MSpaces);
  289. }
  290. return context;
  291. }
  292. /// <summary>
  293. /// 新旧文件对比过后,需要添加的数据
  294. /// </summary>
  295. public static CalcContext GetAddContext(CalcContext oldContext, CalcContext newContext, bool isExceptSpace = false)
  296. {
  297. CalcContext context = new CalcContext(newContext.MFloor);
  298. var equips = newContext.MEquipments.Except(oldContext.MEquipments,
  299. new CommonEqualComparer<MEquipment>((a, b) => { return a.BimID == b.BimID; }));
  300. context.MEquipments.AddRange(equips);
  301. var equipParts = newContext.MEquipmentParts.Except(oldContext.MEquipmentParts,
  302. new CommonEqualComparer<MEquipmentPart>((a, b) =>
  303. {
  304. return a.BimID == b.BimID;
  305. }));
  306. context.MEquipmentParts.AddRange(equipParts);
  307. var beacons = newContext.MBeacons.Except(oldContext.MBeacons,
  308. new CommonEqualComparer<MBeacon>((a, b) => { return a.BimID == b.BimID; }));
  309. context.MBeacons.AddRange(beacons);
  310. //模型文件替换后,元空间重新上传,之前的不保留
  311. if (isExceptSpace)
  312. {
  313. var spaces = newContext.MSpaces.Except(oldContext.MSpaces,
  314. new CommonEqualComparer<MISpace>((a, b) => { return a.BimID == b.BimID; }));
  315. context.MSpaces.AddRange(spaces);
  316. //处理设备所在空间
  317. context.RltEquipInSpaces.AddRange(newContext.RltEquipInSpaces.Where(t => context.MEquipments.Select(tt => tt.BimID).Contains((t)?.MEquipment.BimID)));
  318. context.RltEquipInSpaces.AddRange(newContext.RltEquipInSpaces.Where(t => context.MEquipmentParts.Select(tt => tt.BimID).Contains((t)?.MEquipment.BimID)));
  319. context.RltEquipInSpaces.AddRange(newContext.RltEquipInSpaces.Where(t => context.MSpaces.Select(tt => tt.BimID).Contains((t)?.MSpace.BimID)));
  320. context.RltBeaconinElementSps.AddRange(newContext.RltBeaconinElementSps.Where(t => context.MBeacons.Select(tt => tt.BimID).Contains((t)?.MBeacon.BimID)));
  321. }
  322. else
  323. {
  324. context.MSpaces.AddRange(newContext.MSpaces);
  325. context.RltEquipInSpaces.AddRange(newContext.RltEquipInSpaces);
  326. }
  327. return context;
  328. }
  329. /// <summary>
  330. /// 对将要显示的数据进行装饰
  331. /// 查询贴码类型
  332. /// </summary>
  333. /// <param name="context"></param>
  334. public static void WrapperContextFmInfo(CalcContext context)
  335. {
  336. foreach (var equip in context.MEquipments)
  337. {
  338. string fmid = equip.FMID;
  339. equip.HasFM = fmid.IsNotNullEmpty();
  340. //查询贴码类型
  341. MEquipFM fmmode = MatchFMConvert.GetFMInfoByFMId(fmid);
  342. equip.HasFMChecked = fmmode != null && fmmode.CodeType != -1;
  343. }
  344. foreach (var equip in context.MEquipmentParts)
  345. {
  346. string fmid = equip.FMID;
  347. equip.HasFM = fmid.IsNotNullEmpty();
  348. //查询贴码类型
  349. MEquipFM fmmode = MatchFMConvert.GetFMInfoByFMId(fmid);
  350. equip.HasFMChecked = fmmode != null && fmmode.CodeType != -1;
  351. }
  352. //信标默认都是已经贴码验证过的
  353. foreach (var equip in context.MBeacons)
  354. {
  355. equip.HasFM = true;
  356. equip.HasFMChecked = true;
  357. }
  358. }
  359. /// <summary>
  360. /// 有需要删除的岗位
  361. /// </summary>
  362. /// <param name="context"></param>
  363. /// <returns></returns>
  364. public static bool HasDutyItem(CalcContext context)
  365. {
  366. bool result = false;
  367. result = context.MEquipments.IsNotNullEmptyExt() || context.MEquipmentParts.IsNotNullEmptyExt() || context.MBeacons.IsNotNullEmptyExt();
  368. //如果有需要删除的岗位,对需要显示的数据进行装饰
  369. if (result)
  370. WrapperContextFmInfo(context);
  371. return result;
  372. }
  373. /// <summary>
  374. /// 上传楼层数据,删除所有数据,重新上传
  375. /// </summary>
  376. /// <param name="mode"></param>
  377. /// <returns></returns>
  378. public static bool UploadDataByDelAllThenReUpload(MFloor floor)
  379. {
  380. //删除旧数据
  381. bool result = DalCommon.DelFloorCloudData(floor.Id);
  382. if (!result) return !result;
  383. //计算并上传
  384. CalcContext context = ObjectCalc.Calc(floor);
  385. result = context.Upload();
  386. return result;
  387. }
  388. /// <summary>
  389. /// 上传楼层数据,新旧数据对比,多余的提示用户选择删除
  390. /// </summary>
  391. /// <param name="mode"></param>
  392. /// <returns></returns>
  393. public static bool UploadDataByIntersectOldAndNew(MFloor floor)
  394. {
  395. bool result = true;
  396. try
  397. {
  398. //Traceloger.Show();
  399. Traceloger.Log("从物理世界下载旧数据");
  400. var oldContext = DalCommon.DownLoadCouldData(floor);
  401. Traceloger.Log("从新模型计算新数据");
  402. var newContext = ObjectCalc.Calc(floor);
  403. //分组
  404. Traceloger.Log("获取要被删除的数据");
  405. var bedelContext = GetDelContext(oldContext, newContext);
  406. Traceloger.Log("获取新增加的数据");
  407. var beaddContext = GetAddContext(oldContext, newContext);
  408. Traceloger.Log("获取修改的数据");
  409. var bemodifyContext = GetModifyContext(oldContext, newContext);
  410. if (HasDutyItem(bedelContext))
  411. {
  412. VmSelectSaveDuty viewmode = new VmSelectSaveDuty();
  413. viewmode.DelContext = bedelContext;
  414. WinSelectSaveDuty win = new WinSelectSaveDuty();
  415. win.DataContext = viewmode;
  416. win.ShowDialog();
  417. }
  418. GenerateLog(bedelContext, beaddContext, bemodifyContext);
  419. //Traceloger.Log("执行删除数据操作");
  420. ////删除
  421. //bedelContext.Del();
  422. //Traceloger.Log("执行上传新数据操作");
  423. ////添加
  424. //beaddContext.Upload();
  425. //Traceloger.Close();
  426. }
  427. catch (Exception e)
  428. {
  429. MessageShowBase.Show(e);
  430. result = false;
  431. }
  432. return result;
  433. }
  434. /// <summary>
  435. /// 生成日志文件
  436. /// </summary>
  437. /// <param name="delContext"></param>
  438. /// <param name="addContext"></param>
  439. /// <param name="modifyContext"></param>
  440. public static void GenerateLog(CalcContext delContext, CalcContext addContext, CalcContext modifyContext)
  441. {
  442. try
  443. {
  444. addContext.OpenDocument();
  445. //删除临时日志,此时临时日志应该是空的,不用删除
  446. delContext.WriteToTempLogFile(DocumentChangedOperator.Delete);
  447. //为了取出Family,Type,Category
  448. modifyContext.RevitDoc = addContext.RevitDoc;
  449. modifyContext.WriteToTempLogFile(DocumentChangedOperator.Modified);
  450. addContext.WriteToTempLogFile(DocumentChangedOperator.Add);
  451. //清除旧的日志
  452. ProjectLogManager.ClearFiles(addContext.FloorId);
  453. #region 写入到日志中
  454. #region 将保存日志项目参数写入项目
  455. using (Transaction trans = new Transaction(addContext.RevitDoc, "日志"))
  456. {
  457. trans.Start();
  458. try
  459. {
  460. var newFileKey = ProjectLogManager.CreateLogFileKey(addContext.RevitDoc);
  461. DocumentLogManager.SetLogFileKey(addContext.RevitDoc, newFileKey);
  462. trans.Commit();
  463. }
  464. catch (Exception e)
  465. {
  466. MessageShowBase.Show(e);
  467. trans.RollBack();
  468. }
  469. }
  470. #endregion
  471. //其中包含Save,提交日志文件到服务器
  472. addContext.RevitDoc.CloseDoc();
  473. #endregion
  474. }
  475. catch (Exception e)
  476. {
  477. MessageShowBase.Show(e);
  478. }
  479. }
  480. }
  481. }