VMMatchFM.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. /* ==============================================================================
  2. * 功能描述:VMMatchFM
  3. * 创 建 者:Garrett
  4. * 创建日期:2018/4/20 17:38:45
  5. * ==============================================================================*/
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.Linq;
  10. using System.Windows;
  11. using System.Windows.Controls;
  12. using Autodesk.Revit.DB;
  13. using Newtonsoft.Json.Linq;
  14. using SAGA.DotNetUtils;
  15. using SAGA.DotNetUtils.Extend;
  16. using SAGA.DotNetUtils.Logger;
  17. using SAGA.DotNetUtils.WPF;
  18. using SAGA.MBI.Common;
  19. using SAGA.MBI.DataArrange;
  20. using SAGA.MBI.JsonConvert;
  21. using SAGA.MBI.ModeInfoEdit;
  22. using SAGA.MBI.Model;
  23. using SAGA.MBI.Tools;
  24. using SAGA.MBI.WinView.Upload;
  25. using SAGA.RevitUtils.MEP;
  26. using SAGA.MBI.RequestData;
  27. using SAGA.RevitUtils.Extends;
  28. using WPfPointInfo.InfoProperty;
  29. namespace SAGA.MBI.WinView.ModeInfoMaintenance
  30. {
  31. /// <summary>
  32. /// VMMatchFM
  33. /// </summary>
  34. public class VMMatchFM : BaseViewModelStub
  35. {
  36. public MRevitEquipBase MEquipment { get; set; }
  37. private string m_FloorId { get; set; }
  38. private string m_FloorName { get; set; }
  39. public VMMatchFM(MRevitEquipBase equipment)
  40. {
  41. MEquipment = equipment;
  42. m_FloorId = equipment.FloorId;
  43. m_FloorName = DalProjectTree.GetFloorNameByFloorId(m_FloorId);
  44. MatchFmWay = MatchFmWay.Recommend;
  45. SwitchFmData();
  46. IsUpdate = true;
  47. }
  48. private bool m_IsUpdate;
  49. public bool IsUpdate
  50. {
  51. get { return m_IsUpdate; }
  52. set
  53. {
  54. m_IsUpdate = value;
  55. NotifyPropertyChanged("IsUpdate");
  56. }
  57. }
  58. private List<MEquipFM> m_AllEquipFms;
  59. public List<MEquipFM> AllEquipFms
  60. {
  61. get
  62. {
  63. if (m_AllEquipFms == null)
  64. {
  65. var floorId = MEquipment.FloorId;
  66. var buildingId = DalProjectTree.GetBuildingIdByFloor(floorId);
  67. if (buildingId != null)
  68. m_AllEquipFms = MatchFMConvert.GetAllEquipFmFromScanBuilding(buildingId);
  69. }
  70. return m_AllEquipFms;
  71. }
  72. }
  73. private MatchFmWay m_MatchFmWay;
  74. public MatchFmWay MatchFmWay
  75. {
  76. get { return m_MatchFmWay; }
  77. set
  78. {
  79. m_MatchFmWay = value;
  80. //NotifyPropertyChanged("MatchFmWay");
  81. SwitchFmData();
  82. }
  83. }
  84. private BaseFMData m_FMData;
  85. public BaseFMData FMData
  86. {
  87. get { return m_FMData; }
  88. set
  89. {
  90. m_FMData = value;
  91. NotifyPropertyChanged("FMData");
  92. }
  93. }
  94. [Command]
  95. public void CreateRelation(object param)
  96. {
  97. #region 判断
  98. MatchOperateType operate0;
  99. CheckDutyHasFM(out operate0);
  100. if (operate0 == MatchOperateType.Cancel)
  101. {
  102. CloseWindow(param);
  103. return;
  104. }
  105. List<ItemProperty> combineInfos;
  106. MatchOperateType operate1;
  107. CheckFMHasDuty(out operate1, out combineInfos);
  108. if (operate1 == MatchOperateType.Cancel)
  109. {
  110. return;
  111. }
  112. MatchOperateType operate2;
  113. CheckFMFamily(out operate2);
  114. if (operate2 == MatchOperateType.Cancel)
  115. {
  116. return;
  117. }
  118. #endregion
  119. #region 开始处理
  120. if (operate0 == MatchOperateType.FMIsGarbage)
  121. {
  122. MatchFMConvert.DeleteEquipFM(MEquipment.FMID);
  123. }
  124. switch (operate1)
  125. {
  126. case MatchOperateType.FMNoDuty:
  127. case MatchOperateType.FMHasDutyHasBim:
  128. case MatchOperateType.FMHasDutyNoBim1:
  129. MatchFMConvert.CreateRelationFMWithId(MEquipment, FMData.FmCur);
  130. break;
  131. case MatchOperateType.FMHasDutyNoBim2:
  132. MatchFMConvert.CreateRelationFMWithId(MEquipment, FMData.FmCur);
  133. DalCommon.Delete(FMData.FmCur.EquipmentId);
  134. break;
  135. case MatchOperateType.FMHasDutyNoBim3:
  136. var oldDutyId = FMData.FmCur.EquipmentId;
  137. var newDutyId = MEquipment.Id;
  138. //取消1,2步.由于选择保留资产和资产的岗位关系--由于要清空“ctm-Location”信息点,所以还是更新一下
  139. //使用旧岗位id,更新对应资产的关系
  140. MEquipment.Id = oldDutyId;
  141. MatchFMConvert.CreateRelationFMWithId(MEquipment, FMData.FmCur);
  142. //3 更新此模型计算的各种关系中的岗位id
  143. //更新设备所在空间 用旧id,替换新id,中的关系
  144. RelationConvert.UpdateEquipInSpaceRelation(newDutyId, oldDutyId);
  145. //4,将当前模型BIMID添加到选中资产关联的原岗位上
  146. DalCommon.UpdateBimId(oldDutyId, MEquipment.BimID);
  147. //5 按用户设定维护原岗位信息点
  148. #region 合并信息点
  149. JObject jo = new JObject();
  150. //合并信息点
  151. foreach (var itemProperty in combineInfos)
  152. {
  153. if (itemProperty.Value == null)
  154. continue;
  155. if (itemProperty.Instance is EquipmentCombineItem combine)
  156. {
  157. jo.Add(combine.Definition.CodeName, CommonTool.GetPropertyJArray(itemProperty.Value.ToString()));
  158. }
  159. }
  160. CommonConvert.UpdateInfosSigle(oldDutyId, jo);
  161. #endregion
  162. //6,删除模型对应的新岗位
  163. //1,2替换为旧的id,这里替换回来
  164. MEquipment.Id = newDutyId;
  165. MEquipment.DelObject();
  166. break;
  167. }
  168. #endregion
  169. CloseWindow(param);
  170. }
  171. public bool CanCreateRelation(object param)
  172. {
  173. return FMData?.FmCur != null;
  174. }
  175. /// <summary>
  176. /// 关闭窗体
  177. /// </summary>
  178. /// <param name="param"></param>
  179. private void CloseWindow(object param)
  180. {
  181. var win = param as Window;
  182. if (win != null)
  183. win.DialogResult = true;
  184. }
  185. /// <summary>
  186. /// 当前岗位是否已经指定有资产
  187. /// 如果岗位已匹配资产与当前资产相同,返回true
  188. /// </summary>
  189. /// <returns></returns>
  190. private bool CheckDutyHasFM(out MatchOperateType operate)
  191. {
  192. bool result = false;
  193. operate = MatchOperateType.Continue;
  194. //判断岗位是否已经关联其它资产
  195. if (MEquipment.FMID.IsNotNullEmpty())
  196. {
  197. //判断选中资产跟原有资产是否为同一个资产
  198. if (FMData.FmCur.Id == MEquipment.FMID)
  199. {
  200. operate = MatchOperateType.Cancel;
  201. return result;
  202. }
  203. //判断原资产是否通过扫楼验证
  204. var dutyFm = MatchFMConvert.GetFMInfoByFMId(MEquipment.FMID);
  205. if (dutyFm.CodeType == -1)
  206. {
  207. //未验证
  208. WinMatchFMTip_DutyMatched win = new WinMatchFMTip_DutyMatched(dutyFm);
  209. win.ShowDialog();
  210. switch (win.State)
  211. {
  212. case 0:
  213. operate = MatchOperateType.Cancel;
  214. break;
  215. case 1:
  216. operate = MatchOperateType.Continue;
  217. break;
  218. case 2:
  219. //选择资产属于垃圾数据
  220. operate = MatchOperateType.FMIsGarbage;
  221. break;
  222. }
  223. }
  224. else
  225. {
  226. //已验证
  227. result = false;
  228. }
  229. }
  230. return result;
  231. }
  232. /// <summary>
  233. /// 检查选择的资产是否跟岗位进行过关联
  234. /// </summary>
  235. /// <returns></returns>
  236. private bool CheckFMHasDuty(out MatchOperateType operate, out List<ItemProperty> combineInfos)
  237. {
  238. bool result = false;
  239. operate = MatchOperateType.Continue;
  240. combineInfos = new List<ItemProperty>();
  241. var fmmode = FMData.FmCur;
  242. if (fmmode.EquipmentId.IsNotNullEmpty())
  243. {//已关联
  244. //判断是否有bimid
  245. if (fmmode.BimID.IsOnlyDutyNoModelBIMID())
  246. {
  247. //无bimid
  248. WinMatchFMTip_FMNoBimId win = new WinMatchFMTip_FMNoBimId(MEquipment.Id, fmmode.EquipmentId);
  249. if (win.ShowDialog() == true)
  250. {
  251. operate = win.Operate;
  252. combineInfos = win.GetCombineInfos();
  253. }
  254. else
  255. {
  256. operate = MatchOperateType.Cancel;
  257. }
  258. }
  259. else
  260. {
  261. //有Bimid
  262. WinMatchFMTip_FMMatched win = new WinMatchFMTip_FMMatched(fmmode.EquipmentId);
  263. operate = win.ShowDialog() == true ? MatchOperateType.FMHasDutyHasBim : MatchOperateType.Cancel;
  264. }
  265. }
  266. else
  267. {//未关联
  268. operate = MatchOperateType.FMNoDuty;
  269. }
  270. return result;
  271. }
  272. /// <summary>
  273. /// 检查选择的资产族类型是否跟岗位的族类型相匹配
  274. /// </summary>
  275. /// <param name="operate"></param>
  276. /// <returns></returns>
  277. private bool CheckFMFamily(out MatchOperateType operate)
  278. {
  279. bool result = false;
  280. operate = MatchOperateType.Cancel;
  281. if (FMData.FmCur.FamilyCode != MEquipment.Family.Code)
  282. {
  283. WinMatchFMTip_FamilyChanged win = new WinMatchFMTip_FamilyChanged();
  284. if (win.ShowDialog() == true)
  285. operate = MatchOperateType.Continue;
  286. }
  287. else
  288. {
  289. operate = MatchOperateType.Continue;
  290. }
  291. return result;
  292. }
  293. private BaseFMData m_FMDataRecommend;
  294. private BaseFMData m_FMDataEquipLocation;
  295. private BaseFMData m_FMDataEquipFamily;
  296. private void SwitchFmData()
  297. {
  298. switch (MatchFmWay)
  299. {
  300. case MatchFmWay.Recommend:
  301. if (m_FMDataRecommend == null)
  302. m_FMDataRecommend = new RecommendFMData(AllEquipFms, MEquipment, m_FloorName);
  303. FMData = m_FMDataRecommend;
  304. break;
  305. case MatchFmWay.EquipLocation:
  306. if (m_FMDataEquipLocation == null)
  307. m_FMDataEquipLocation = new EquipLocationFMData(AllEquipFms, MEquipment.FloorId, m_FloorName);
  308. FMData = m_FMDataEquipLocation;
  309. break;
  310. case MatchFmWay.EquipFamily:
  311. if (m_FMDataEquipFamily == null)
  312. m_FMDataEquipFamily = new EquipFamilyFMData(AllEquipFms, MEquipment.FloorId, m_FloorName);
  313. FMData = m_FMDataEquipFamily;
  314. break;
  315. }
  316. }
  317. }
  318. public enum MatchOperateType
  319. {
  320. Cancel = 0,
  321. Continue,
  322. //此资产属于垃圾数据
  323. FMIsGarbage,
  324. //资产有岗位,Bimid不存在 Path3
  325. FMHasDutyNoBim1,
  326. FMHasDutyNoBim2,
  327. FMHasDutyNoBim3,
  328. //资产有岗位,Bimid存在 Path2
  329. FMHasDutyHasBim,
  330. //资产没有关联岗位 Path1
  331. FMNoDuty,
  332. }
  333. public enum MatchFmWay
  334. {
  335. Recommend,
  336. EquipLocation,
  337. EquipFamily
  338. }
  339. public class BaseFMData : BaseViewModelStub
  340. {
  341. private MEquipFM m_FMCur;
  342. public MEquipFM FmCur
  343. {
  344. get { return m_FMCur; }
  345. set
  346. {
  347. m_FMCur = value;
  348. NotifyPropertyChanged("FmCur");
  349. }
  350. }
  351. /// <summary>
  352. /// 当前楼层的楼层名称
  353. /// </summary>
  354. public string FloorName { get; set; }
  355. }
  356. /// <summary>
  357. /// 由近到远进行排序
  358. /// </summary>
  359. public class RecommendByDistanceComparer : IComparer<MEquipFM>
  360. {
  361. private XYZ origin;
  362. public RecommendByDistanceComparer(XYZ origin)
  363. {
  364. this.origin = origin;
  365. }
  366. public int Compare(MEquipFM x, MEquipFM y)
  367. {
  368. XYZ xXyz = x.Location.ToXyz();
  369. XYZ yXyz = y.Location.ToXyz();
  370. if (xXyz == null)
  371. xXyz = new XYZ(x.X, x.Y, origin.Z);
  372. if (yXyz == null)
  373. yXyz = new XYZ(y.X, y.Y, origin.Z);
  374. int result = origin.FindDistance2(xXyz).CompareTo(origin.FindDistance2(yXyz));
  375. if (result == 0)
  376. result = origin.DistanceTo(xXyz).CompareTo(origin.DistanceTo(yXyz));
  377. return result;
  378. }
  379. }
  380. /// <summary>
  381. /// 推荐
  382. /// </summary>
  383. public class RecommendFMData : BaseFMData
  384. {
  385. private ObservableCollection<MEquipFM> m_FMList;
  386. public ObservableCollection<MEquipFM> FMList
  387. {
  388. get { return m_FMList; }
  389. set
  390. {
  391. m_FMList = value;
  392. NotifyPropertyChanged("FMList");
  393. }
  394. }
  395. //所在空间Id,避免为Null时重复请求
  396. private string m_EquipSpaceId;
  397. public RecommendFMData(List<MEquipFM> list, MRevitEquipBase equip, string floorName)
  398. {
  399. FloorName = floorName;
  400. FMList = new ObservableCollection<MEquipFM>();
  401. //1,首先按方案1过滤
  402. //1.a,如果有值,过滤没有关联岗位的。
  403. //1.b,1.a有值,推荐1.a;没有值,推荐1;
  404. //2,1没有值,按方案2过滤
  405. m_EquipSpaceId = equip.MSpace?.Id;
  406. var tempList = list.Where(t => IsMathPlan1(t, equip)).ToList();
  407. if (tempList.Any())
  408. {
  409. List<MEquipFM> plan1List = new List<MEquipFM>();
  410. var nodutyList = tempList.Where(t => t.EquipmentId.IsNullOrEmpty()).ToList();
  411. if (nodutyList.Any())
  412. {
  413. plan1List.AddRange(nodutyList);
  414. }
  415. else
  416. {
  417. plan1List.AddRange(tempList);
  418. }
  419. //按距离由近到远排序
  420. plan1List.Sort(new RecommendByDistanceComparer(equip.Location.ToXyz()));
  421. foreach (MEquipFM fm in plan1List)
  422. {
  423. FMList.Add(fm);
  424. }
  425. }
  426. else
  427. {
  428. foreach (var item in list)
  429. {
  430. if (IsMathPlan2(item, equip))
  431. FMList.Add(item);
  432. }
  433. }
  434. }
  435. /// <summary>
  436. /// 推荐方案1,
  437. /// 同一空间
  438. /// 同设备族and距离近
  439. /// </summary>
  440. /// <param name="equipFm"></param>
  441. /// <param name="equip"></param>
  442. /// <returns></returns>
  443. private bool IsMathPlan1(MEquipFM equipFm, MRevitEquipBase equip)
  444. {
  445. List<Func<MEquipFM, MRevitEquipBase, bool>> funcs = new List<Func<MEquipFM, MRevitEquipBase, bool>>();
  446. funcs.Add(IsSameSpace);
  447. funcs.Add(IsSameFamilyCode);
  448. funcs.Add(IsLocationNear);
  449. bool result = funcs.All(t => t(equipFm, equip));
  450. return result;
  451. }
  452. /// <summary>
  453. /// 推荐方案2,同设备族and没有与其它岗位关联,
  454. /// 同一楼层or点位同一楼层or安装位置同一楼层or本地名称或本地编码不为null,且相等
  455. /// </summary>
  456. /// <param name="equipFm"></param>
  457. /// <param name="equip"></param>
  458. /// <returns></returns>
  459. private bool IsMathPlan2(MEquipFM equipFm, MRevitEquipBase equip)
  460. {
  461. bool result = false;
  462. List<Func<MEquipFM, MRevitEquipBase, bool>> funcs = new List<Func<MEquipFM, MRevitEquipBase, bool>>();
  463. funcs.Add(IsSameFloor);
  464. funcs.Add(IsSamePointFloor);
  465. funcs.Add(IsSameInstallLocation);
  466. funcs.Add(IsSameLocalNameOrId);
  467. while (true)
  468. {
  469. //不推荐已经绑定过的
  470. if (equipFm.EquipmentId.IsNotNullEmpty())
  471. break;
  472. if (equipFm.FamilyCode != equip.Family.Code)
  473. break;
  474. result = funcs.Any(t => t(equipFm, equip));
  475. break;
  476. }
  477. return result;
  478. }
  479. #region 推荐方法
  480. /// <summary>
  481. /// 同一空间中
  482. /// </summary>
  483. /// <param name="equipFm"></param>
  484. /// <param name="equip"></param>
  485. /// <returns></returns>
  486. private bool IsSameSpace(MEquipFM equipFm, MRevitEquipBase equip)
  487. {
  488. bool result = false;
  489. string fmSpaceId = equipFm.SpaceId;
  490. string equipSpaceId = m_EquipSpaceId;
  491. if (fmSpaceId.IsNotNullEmpty() && equipSpaceId.IsNotNullEmpty())
  492. {
  493. result = fmSpaceId == equipSpaceId;
  494. }
  495. return result;
  496. }
  497. /// <summary>
  498. /// 同一种设备族
  499. /// </summary>
  500. /// <param name="equipFm"></param>
  501. /// <param name="equip"></param>
  502. /// <returns></returns>
  503. private bool IsSameFamilyCode(MEquipFM equipFm, MRevitEquipBase equip)
  504. {
  505. return (equipFm.FamilyCode == equip.Family.Code);
  506. }
  507. /// <summary>
  508. /// 资产和模型为同一层
  509. /// </summary>
  510. /// <param name="equipFm"></param>
  511. /// <param name="equip"></param>
  512. /// <returns></returns>
  513. private bool IsSameFloor(MEquipFM equipFm, MRevitEquipBase equip)
  514. {
  515. bool result = false;
  516. string floorId = equip.FloorId;
  517. if (equipFm.FloorId == floorId)
  518. {
  519. result = true;
  520. }
  521. return result;
  522. }
  523. /// <summary>
  524. /// 点位标签的现场位置和模型为同一层
  525. /// </summary>
  526. /// <param name="equipFm"></param>
  527. /// <param name="equip"></param>
  528. /// <returns></returns>
  529. private bool IsSamePointFloor(MEquipFM equipFm, MRevitEquipBase equip)
  530. {
  531. bool result = false;
  532. string floorId = equip.FloorId;
  533. if (equipFm.PointFloorId == floorId)
  534. {
  535. result = true;
  536. }
  537. return result;
  538. }
  539. /// <summary>
  540. /// 安装位置包含楼层名
  541. /// </summary>
  542. /// <param name="equipFm"></param>
  543. /// <param name="equip"></param>
  544. /// <returns></returns>
  545. private bool IsSameInstallLocation(MEquipFM equipFm, MRevitEquipBase equip)
  546. {
  547. bool result = false;
  548. if (equipFm.InstallLocation.IsNotNullEmpty())
  549. {
  550. if (equipFm.InstallLocation.Contains(FloorName))
  551. {
  552. result = true;
  553. }
  554. }
  555. return result;
  556. }
  557. /// <summary>
  558. /// (物理世界设备本地名称==资产本地名称 and 不为空) or (物理世界设备本地编码==资产本地编码 and 不为空)
  559. /// </summary>
  560. /// <param name="equipFm"></param>
  561. /// <param name="equip"></param>
  562. /// <returns></returns>
  563. private bool IsSameLocalNameOrId(MEquipFM equipFm, MRevitEquipBase equip)
  564. {
  565. bool result = false;
  566. var localName = "";
  567. var localId = "";
  568. if (equip is MEquipment equipment)
  569. {
  570. localName = equipment.LocalName;
  571. localId = equipment.LocalId;
  572. }
  573. else if (equip is MEquipmentPart part)
  574. {
  575. localName = part.LocalName;
  576. localId = part.LocalId;
  577. }
  578. if (equipFm.LocalName.IsNotNullEmpty() && (equipFm.LocalName == localName))
  579. {
  580. result = true;
  581. }
  582. if (equipFm.LocalId.IsNotNullEmpty() && (equipFm.LocalId == localId))
  583. {
  584. result = true;
  585. }
  586. return result;
  587. }
  588. /// <summary>
  589. /// 坐标是否相近
  590. /// </summary>
  591. /// <param name="equipFm"></param>
  592. /// <param name="equip"></param>
  593. /// <returns></returns>
  594. private bool IsLocationNear(MEquipFM equipFm, MRevitEquipBase equip)
  595. {
  596. //推荐坐标的冗余值
  597. double redundancy = 2000d;
  598. //Z设置为0,平面范围内
  599. XYZ fmXyz = equipFm.Location.ToXyz().NewZ();
  600. XYZ dutyXyz = equip.Location.ToXyz().NewZ();
  601. bool result = false;
  602. if (fmXyz != null && dutyXyz != null)
  603. {
  604. //单位mm
  605. result = fmXyz.DistanceTo(dutyXyz).IsLess(redundancy);
  606. }
  607. else if (fmXyz == null && dutyXyz != null)
  608. {
  609. //取不到Location,使用X,Y中的值,进行比较,忽略Z
  610. fmXyz = new XYZ(equipFm.X, equipFm.Y, 0);
  611. result = fmXyz.FindDistance2(dutyXyz).IsLess(redundancy);
  612. }
  613. return result;
  614. }
  615. #endregion
  616. }
  617. public class EquipLocationFMData : BaseFMData
  618. {
  619. public EquipLocationFMData(List<MEquipFM> list, string floorid, string floorName)
  620. {
  621. BuildingName = DalProjectTree.GetBuildingByFloor(floorid).ToString();
  622. FMDicList = new Dictionary<string, ObservableCollection<MEquipFM>>();
  623. var groupByfloors = list.GroupBy(t => t.FloorName);
  624. IGrouping<string, MEquipFM> floorNullItem = null;
  625. foreach (IGrouping<string, MEquipFM> groupByfloor in groupByfloors)
  626. {
  627. if (groupByfloor.Key == "无法确定楼层")
  628. {
  629. floorNullItem = groupByfloor;
  630. continue;
  631. }
  632. var groupList = groupByfloor.ToList();
  633. //无信标排序放在后面
  634. groupList.Sort(new CommonComparer<MEquipFM>((a, b) =>
  635. {
  636. return b.PointId
  637. .CompareTo(a.PointId);
  638. }));
  639. FMDicList.Add(groupByfloor.Key, new ObservableCollection<MEquipFM>(groupList));
  640. }
  641. //将无法确定楼层项移动到最后
  642. if (floorNullItem != null)
  643. FMDicList.Add(floorNullItem.Key, new ObservableCollection<MEquipFM>(floorNullItem.ToList()));
  644. FMDicCur = FMDicList.FirstOrDefault(t => t.Key == floorName);
  645. if (FMDicCur.Key.IsNullOrEmpty())
  646. FMDicCur = FMDicList.FirstOrDefault();
  647. }
  648. private Dictionary<string, ObservableCollection<MEquipFM>> m_FMDicList;
  649. public Dictionary<string, ObservableCollection<MEquipFM>> FMDicList
  650. {
  651. get { return m_FMDicList; }
  652. set
  653. {
  654. m_FMDicList = value;
  655. NotifyPropertyChanged("FMDicList");
  656. }
  657. }
  658. private KeyValuePair<string, ObservableCollection<MEquipFM>> m_FMDicCur;
  659. public KeyValuePair<string, ObservableCollection<MEquipFM>> FMDicCur
  660. {
  661. get { return m_FMDicCur; }
  662. set
  663. {
  664. m_FMDicCur = value;
  665. NotifyPropertyChanged("FMDicCur");
  666. }
  667. }
  668. private string m_BuildingName;
  669. public string BuildingName
  670. {
  671. get { return m_BuildingName; }
  672. set { m_BuildingName = value; }
  673. }
  674. }
  675. public class EquipFamilyFMData : BaseFMData
  676. {
  677. public EquipFamilyFMData(List<MEquipFM> list, string floorid, string floorName)
  678. {
  679. BuildingName = DalProjectTree.GetBuildingByFloor(floorid).ToString();
  680. FMDicList = new Dictionary<string, ObservableCollection<MEquipFM>>();
  681. FMDicList.Add("全部楼层", new ObservableCollection<MEquipFM>(list));
  682. var groupByfloors = list.GroupBy(t => t.FloorName);
  683. IGrouping<string, MEquipFM> floorNullItem = null;
  684. foreach (IGrouping<string, MEquipFM> groupByfloor in groupByfloors)
  685. {
  686. if (groupByfloor.Key == "无法确定楼层")
  687. {
  688. floorNullItem = groupByfloor;
  689. continue;
  690. }
  691. FMDicList.Add(groupByfloor.Key, new ObservableCollection<MEquipFM>(groupByfloor.ToList()));
  692. }
  693. //将无法确定楼层项移动到最后
  694. if (floorNullItem != null)
  695. FMDicList.Add(floorNullItem.Key, new ObservableCollection<MEquipFM>(floorNullItem.ToList()));
  696. FMDicCur = FMDicList.FirstOrDefault(t => t.Key == floorName);
  697. if (FMDicCur.Key.IsNullOrEmpty())
  698. FMDicCur = FMDicList.FirstOrDefault();
  699. }
  700. private Dictionary<string, ObservableCollection<MEquipFM>> m_FMDicList;
  701. public Dictionary<string, ObservableCollection<MEquipFM>> FMDicList
  702. {
  703. get { return m_FMDicList; }
  704. set
  705. {
  706. m_FMDicList = value;
  707. NotifyPropertyChanged("FMDicList");
  708. }
  709. }
  710. private KeyValuePair<string, ObservableCollection<MEquipFM>> m_FMDicCur;
  711. public KeyValuePair<string, ObservableCollection<MEquipFM>> FMDicCur
  712. {
  713. get { return m_FMDicCur; }
  714. set
  715. {
  716. m_FMDicCur = value;
  717. NotifyPropertyChanged("FMDicCur");
  718. }
  719. }
  720. private string m_BuildingName;
  721. public string BuildingName
  722. {
  723. get { return m_BuildingName; }
  724. set { m_BuildingName = value; }
  725. }
  726. }
  727. }