DalUploadFloor.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. /* ==============================================================================
  2. * 功能描述:上传或下载楼层文件
  3. * 创 建 者:Garrett
  4. * 创建日期:2018/3/30 18:16:55
  5. * ==============================================================================*/
  6. using Autodesk.Revit.DB;
  7. using Autodesk.Revit.DB.Mechanical;
  8. using SAGA.DotNetUtils;
  9. using SAGA.DotNetUtils.Extend;
  10. using SAGA.DotNetUtils.Logger;
  11. using SAGA.MBI.Calc;
  12. using SAGA.MBI.Common;
  13. using SAGA.MBI.Extend;
  14. using SAGA.MBI.Model;
  15. using SAGA.MBI.RequestData;
  16. using SAGA.MBI.Tools;
  17. using SAGA.MBI.WinView.Upload;
  18. using SAGA.RevitUtils;
  19. using SAGA.RevitUtils.Extends;
  20. using System;
  21. using System.Collections.Generic;
  22. using System.Collections.ObjectModel;
  23. using System.IO;
  24. using System.Linq;
  25. using System.Reflection;
  26. using SAGA.MBI.FileStream;
  27. using SAGA.MBI.WinView.TraceView;
  28. using SAGA.RevitUtils.MEP;
  29. namespace SAGA.MBI.DataArrange
  30. {
  31. /// <summary>
  32. /// DalUploadFloor
  33. /// </summary>
  34. public class DalUploadFloor
  35. {
  36. /// <summary>
  37. /// 检测是否需要下载模型,如果需要下载
  38. /// 下载前关闭打开的模型;
  39. /// 开始下载
  40. /// </summary>
  41. public static void CheckAndBeginDownLoadFile()
  42. {
  43. Log4Net.Debug("开始:检测是否需要下载模型,如果需要下载");
  44. if (!IsAllFloorClosed()) return;
  45. Log4Net.Debug("中间:检测下载模型,如果需要下载");
  46. BeginDownLoadFile();
  47. Log4Net.Debug("结束:检测是否需要下载模型,如果需要下载");
  48. }
  49. /// <summary>
  50. /// 对比文件,开始下载
  51. /// </summary>
  52. public static bool BeginDownLoadFile()
  53. {
  54. List<Tuple<string, int, string>> tuples = DalVisionOperate.GetNeedDownLoadFiles();
  55. int i = 0, j = 0;
  56. int count = tuples.Count;
  57. foreach (var tuple in tuples)
  58. {
  59. i++;
  60. if (UpLoadFileRequest.DownLoadFileAsync(tuple, count, i))
  61. {
  62. //下载成功-更新LocalFileVision文件
  63. string floorid = tuple.Item1.GetFileName();
  64. DalVisionOperate.SaveLocalVision(floorid, DalVisionOperate.GetCloudFileVision(floorid));
  65. //下载成功清除本机本层的日志数据,其它用户的日志上传成功的时候才清除日志
  66. ProjectLogManager.ClearFile(tuple.Item1);
  67. //更新拓扑计算结果版本
  68. GplotWatch.RefreshAll(DateTime.Now);
  69. j++;
  70. }
  71. else
  72. {
  73. break;
  74. }
  75. }
  76. if (count >= 1)
  77. //下载完成提示窗体;文件服务器缺少文件,会出现进度条无法关闭的情况;
  78. UpLoadFileRequest.CloseDownloadWin(count == j, hasTip: true);
  79. return i == j;
  80. }
  81. /// <summary>
  82. /// 重新下载模型文件
  83. /// </summary>
  84. /// <param name="floor"></param>
  85. /// <returns></returns>
  86. public static bool? ReDownLoadFile(MFloor floor, ref string msg)
  87. {
  88. string fullPath = floor.FullPath;
  89. bool? downloadstate;
  90. if (DalVisionOperate.IsFileChanged(fullPath, floor.ToString()))
  91. {
  92. Tuple<string, int, string> tuple = new Tuple<string, int, string>(fullPath, 2, floor.ToString());
  93. //模型文件有改动,备份并下载
  94. downloadstate = UpLoadFileRequest.DownLoadFileAsync(tuple, 1, 1);
  95. msg = downloadstate == true ? "模型文件更新成功" : "模型文件更新失败";
  96. string floorid = floor.Id;
  97. DalVisionOperate.SaveLocalVision(floorid, DalVisionOperate.GetCloudFileVision(floorid));
  98. //下载成功清除本机本层的日志数据,其它用户的日志上传成功的时候才清除日志
  99. ProjectLogManager.ClearFile(tuple.Item1);
  100. GplotWatch.RefreshAll(DateTime.Now);
  101. }
  102. else
  103. {
  104. //模型文件没有改动
  105. msg = "本地已是最新模型文件,无需更新;";
  106. downloadstate = null;
  107. }
  108. return downloadstate;
  109. }
  110. /// <summary>
  111. /// 获取有模型文件的楼层
  112. /// </summary>
  113. /// <param name="type"></param>
  114. /// <returns></returns>
  115. public static ObservableCollection<UploadFloor> GetHasFileFloors()
  116. {
  117. ObservableCollection<UploadFloor> ufloors = new ObservableCollection<UploadFloor>();
  118. List<MFloor> mfloors = DalProjectTree.GetAllFloors();
  119. foreach (var mFloor in mfloors)
  120. {
  121. UploadFloor ufloor = new UploadFloor();
  122. ufloor.BuildingName = mFloor.BuildingId;
  123. ufloor.FloorName = mFloor.ToString();
  124. ufloor.FloorPath = Path.Combine(mFloor.RelativePath, mFloor.RevitName + ".rvt");
  125. if (!mFloor.IsMissFile)
  126. {
  127. ufloor.MFloor = mFloor;
  128. ufloors.Add(ufloor);
  129. }
  130. }
  131. return ufloors;
  132. }
  133. /// <summary>
  134. /// 检查是否可以上传楼层
  135. /// 上传模型之前需要关闭所有模型文件
  136. /// </summary>
  137. public static bool IsAllFloorClosed()
  138. {
  139. //打开空文件并激活
  140. var placeholderFile = MBIConst.EmptyFilePath;
  141. var uiApp = ExternalDataWrapper.Current.UiApp;
  142. var docs = uiApp.Application.Documents;
  143. if (docs.IsEmpty) return true;
  144. var allFloors = GetHasFileFloors();
  145. //首先判断ActiveUIDocument是否为当前项目下的楼层
  146. if (uiApp.ActiveUIDocument == null) return true;
  147. Action replaceActiveDoc = () =>
  148. {
  149. string activeName = uiApp.ActiveUIDocument.Document.PathName;
  150. var floor = allFloors.FirstOrDefault(t => t.MFloor.FullPath == activeName);
  151. if (floor == null)
  152. {
  153. //不用打开空模型
  154. }
  155. else
  156. {
  157. //打开空模型
  158. uiApp.OpenAndActivateDocument(placeholderFile);
  159. }
  160. };
  161. List<Document> modifyFloors = new List<Document>();
  162. List<Document> nomodifyFloors = new List<Document>();
  163. //获取没有更改的楼层,同时获取更改的楼层
  164. foreach (Document doc in docs)
  165. {
  166. string activeName = doc.PathName;
  167. var floor = allFloors.FirstOrDefault(t => t.MFloor.FullPath == activeName);
  168. if (floor != null)
  169. {
  170. if (doc.IsModified)
  171. modifyFloors.Add(doc);
  172. else
  173. {
  174. nomodifyFloors.Add(doc);
  175. }
  176. }
  177. }
  178. //如果有更改的楼层,弹出确认框,待用户确认后,保存
  179. if (modifyFloors.Count > 0)
  180. {
  181. //弹出保存提示框
  182. WinUploadSaveFileConfirm win = new WinUploadSaveFileConfirm();
  183. if (win.ShowDialog() != true) return false;
  184. replaceActiveDoc();
  185. foreach (Document doc in modifyFloors)
  186. {
  187. doc.Close(true);
  188. }
  189. }
  190. {
  191. replaceActiveDoc();
  192. //关闭没有更改的楼层,
  193. foreach (Document doc in nomodifyFloors)
  194. {
  195. doc.Close(false);
  196. }
  197. }
  198. return true;
  199. }
  200. /// <summary>
  201. /// 是否需要更新模型文件
  202. /// </summary>
  203. /// <returns></returns>
  204. public static bool IsNeedUpdataFile()
  205. {
  206. bool result = true;
  207. var allFloors = GetHasFileFloors();
  208. //获取MD5改变的文件
  209. var modifyFloors = new ObservableCollection<UploadFloor>(allFloors
  210. .Where(t => DalVisionOperate.IsModifyFileOverdue(t.MFloor.FullPath, t.MFloor.ToString())).ToList());
  211. if (modifyFloors.Count > 0)
  212. {
  213. WinUploadTipFileOverdue win = new WinUploadTipFileOverdue();
  214. win.UploadFloors = modifyFloors;
  215. win.ShowDialog();
  216. }
  217. return modifyFloors.Count > 0;
  218. }
  219. /// <summary>
  220. /// 准备需要上传的楼层及拓扑关系
  221. /// </summary>
  222. public static VMUploadModeManage PrepareUploadFloors()
  223. {
  224. Log4Net.Info("PrepareUpload Start");
  225. string currentFloor = string.Empty;
  226. VMUploadModeManage vm = new VMUploadModeManage();
  227. try
  228. {
  229. //获取有模型文件的楼层
  230. var allFloors = GetHasFileFloors();
  231. //获取MD5改变的文件
  232. var modifyFloors = new ObservableCollection<UploadFloor>(allFloors
  233. .Where(t => DalVisionOperate.IsFileChanged(t.MFloor.FullPath, t.MFloor.ToString())).ToList());
  234. //获取所有的拓扑图类型
  235. var topologyGriphs = GetAllTopologyGriphs();
  236. foreach (UploadFloor uploadFloor in modifyFloors)
  237. {
  238. if (uploadFloor == null) continue;
  239. currentFloor = uploadFloor.MFloor.ToString();
  240. try
  241. {
  242. #region 日志影响拓扑图
  243. foreach (var topologyGriph in topologyGriphs)
  244. {
  245. uploadFloor.ReferGriphs.Add(topologyGriph);
  246. }
  247. #endregion
  248. uploadFloor.IsUpload = true;
  249. }
  250. catch (Exception e)
  251. {
  252. throw;
  253. }
  254. finally
  255. {
  256. }
  257. }
  258. vm.UploadFloors = modifyFloors;
  259. vm.MTopologyGriphs = PrepareMTopologyGriphs(modifyFloors);
  260. }
  261. catch (Exception e)
  262. {
  263. MessageShow.Show(e, strMessage: $"楼层 { currentFloor ?? string.Empty} 打开异常或网络异常,请检查后再进行操作!\r\n");
  264. vm = null;
  265. }
  266. Log4Net.Info("PrepareUpload Start");
  267. return vm;
  268. }
  269. /// <summary>
  270. /// 对 删除并保留岗位日志 进行的操作
  271. /// </summary>
  272. /// <param name="mode"></param>
  273. private static void OperateDelSaveDutyLog(MRevitEquipBase mode)
  274. {
  275. if (mode != null)
  276. {
  277. mode.Operator = DocumentChangedOperator.DeleteSaveDuty;
  278. }
  279. }
  280. /// <summary>
  281. /// 处理增加日志
  282. /// </summary>
  283. private static void OperateModifyLog(MRevitEquipBase mode, Element elem, CalcContext context)
  284. {
  285. //如果为空间并且周长为零,删除云平台的空间数据
  286. if (JudgeDeleteOperate(mode, elem)) return;
  287. var revitmode = DalCommon.GetEquipmentBase(elem);
  288. //不知什么原因,日志就显示add,但物理世界存在这条信息
  289. if (mode != null)
  290. {
  291. IsEquipClassCodeChanged(mode, elem, revitmode, context);
  292. }
  293. else
  294. {
  295. if (revitmode.IsNullOrDefaultEquip())
  296. {//不能识别的设备,部件,信标,空间
  297. }
  298. else
  299. {
  300. //请求Duty,Bim数据库中的id
  301. var dutyId = revitmode.GetDutyBIMRelationByBIM()?.DutyId;
  302. if (dutyId.IsNullOrEmpty())
  303. {//本地数据库不存在此岗位
  304. revitmode.Operator = DocumentChangedOperator.Add;
  305. context.Add(revitmode);
  306. }
  307. else
  308. {
  309. var cloudmode = CommonConvert.QueryObjectById(dutyId);
  310. if (cloudmode == null)
  311. {
  312. revitmode.Operator = DocumentChangedOperator.Add;
  313. context.Add(revitmode);
  314. }
  315. else
  316. {
  317. //待建模型清单新建的设备
  318. cloudmode.BimID = revitmode.BimID;
  319. IsEquipClassCodeChanged(cloudmode, elem, revitmode, context);
  320. context.Add(cloudmode);
  321. }
  322. }
  323. }
  324. }
  325. }
  326. /// <summary>
  327. /// 判断设备类编码是否更改
  328. /// 如果发生更改,把之前的删除。
  329. /// 重建岗位。
  330. /// </summary>
  331. /// <param name="mode"></param>
  332. /// <param name="tempmode"></param>
  333. /// <param name="context"></param>
  334. /// <returns></returns>
  335. private static bool IsEquipClassCodeChanged(MRevitEquipBase mode, Element elem, MRevitEquipBase tempmode, CalcContext context)
  336. {
  337. bool result = false;
  338. if (tempmode.IsNullOrDefaultEquip())
  339. {
  340. //本地编码不可识别,删除服务器数据
  341. //xls 新编码和旧编码一致,则不处理数据
  342. if (EquipmentCodeMap.GetOriginCode(mode.EquipClassCode) == EquipmentCodeMap.GetOriginCode(tempmode.EquipClassCode))
  343. {
  344. mode.Operator = DocumentChangedOperator.Modified;
  345. mode.ReadRevitParamter(elem);
  346. }
  347. else
  348. {
  349. mode.Operator = DocumentChangedOperator.Delete;
  350. }
  351. }
  352. else
  353. {
  354. //如果设备族四位或六位改了,需要将岗位删除,重建岗位
  355. //string code1 = EquipmentCodeMap.GetOriginCode(mode.EquipClassCode);
  356. //(tempmode.EquipClassCode 这个的取法上上一个不一样
  357. // string code2 = EquipmentCodeMap.GetOriginCode(tempmode.EquipClassCode);
  358. if (EquipmentCodeMap.GetOriginCode(mode.EquipClassCode) != EquipmentCodeMap.GetOriginCode(tempmode.EquipClassCode))
  359. {
  360. SetSavePropertyValue(tempmode, mode);
  361. mode.Operator = DocumentChangedOperator.Delete;
  362. tempmode.Operator = DocumentChangedOperator.Add;
  363. context.Add(tempmode);
  364. result = true;
  365. }
  366. else
  367. {
  368. mode.Operator = DocumentChangedOperator.Modified;
  369. mode.ReadRevitParamter(elem);
  370. }
  371. }
  372. return result;
  373. }
  374. /// <summary>
  375. /// 编码更改时保留的信息点
  376. /// </summary>
  377. /// <param name="mode"></param>
  378. /// <param name="oldmode"></param>
  379. public static void SetSavePropertyValue(MRevitEquipBase mode, MRevitEquipBase oldmode)
  380. {
  381. string[] saveProperties = new[] { "LocalId", "LocalName" };
  382. var oldProperties = oldmode.GetType().GetProperties();
  383. foreach (PropertyInfo property in oldProperties)
  384. {
  385. string name = property.Name;
  386. if (saveProperties.Contains(name))
  387. {
  388. object value = property.GetValue(oldmode);
  389. if (value != null)
  390. {
  391. property.SetValue(mode, value);
  392. }
  393. }
  394. }
  395. }
  396. /// <summary>
  397. /// 1,处理是无用的空间,周长为零
  398. /// 2,对象被删除
  399. /// </summary>
  400. /// <param name="elem"></param>
  401. /// <returns></returns>
  402. private static bool JudgeDeleteOperate(MRevitEquipBase mode, Element elem)
  403. {
  404. bool result = false;
  405. if (mode != null)
  406. {
  407. if (elem == null)
  408. {
  409. mode.Operator = DocumentChangedOperator.Delete;
  410. result = true;
  411. }
  412. else if (elem is Space space)
  413. {
  414. if (space.IsDeleteSpace())
  415. {
  416. //如果是无用空间,直接删除云平台对应数据
  417. mode.Operator = DocumentChangedOperator.Delete;
  418. result = true;
  419. }
  420. }
  421. }
  422. return result;
  423. }
  424. /// <summary>
  425. /// 准备需要显示的拓扑图(全集)
  426. /// </summary>
  427. /// <param name="uploadFloors"></param>
  428. /// <returns></returns>
  429. public static ObservableCollection<MTopologyGriph> PrepareMTopologyGriphs(ObservableCollection<UploadFloor> uploadFloors)
  430. {
  431. ObservableCollection<MTopologyGriph> list = new ObservableCollection<MTopologyGriph>();
  432. foreach (var uploadFloor in uploadFloors)
  433. {
  434. foreach (MTopologyGriph griph in uploadFloor.ReferGriphs)
  435. {
  436. var tempgriph = list.FirstOrDefault(t => t.Name == griph.Name);
  437. if (tempgriph == null)
  438. list.Add(griph);
  439. }
  440. }
  441. return list;
  442. }
  443. /// <summary>
  444. /// 获取所有的拓扑图类型
  445. /// </summary>
  446. /// <returns></returns>
  447. public static List<MTopologyGriph> GetAllTopologyGriphs()
  448. {
  449. List<MTopologyGriph> list = new List<MTopologyGriph>();
  450. list.Add(new MTopologyGriph() { Name = "空调冷冻水环路" });
  451. list.Add(new MTopologyGriph() { Name = "空调冷却水环路" });
  452. list.Add(new MTopologyGriph() { Name = "新风管网" });
  453. list.Add(new MTopologyGriph() { Name = "空调风管网" });
  454. list.Add(new MTopologyGriph() { Name = "光照辐射关系" });
  455. list.Add(new MTopologyGriph() { Name = "空间邻接关系" });
  456. list.Add(new MTopologyGriph() { Name = "建筑交通关系" });
  457. list.Add(new MTopologyGriph() { Name = "空间流通网络" });
  458. return list;
  459. }
  460. /// <summary>
  461. /// 判断物理世界岗位与本地岗位是否一致
  462. /// 依据1:BimID
  463. /// --暂时不使用,依据2:CADID
  464. /// </summary>
  465. /// <param name="cduty"></param>
  466. /// <param name="lduty"></param>
  467. /// <returns></returns>
  468. public static bool IsEqualCloudDuty2LocalDuty(MRevitEquipBase cduty,MRevitEquipBase lduty)
  469. {
  470. string lbimId = lduty.BimID;
  471. string cbimId = cduty.BimID;
  472. bool result = false;
  473. do
  474. {
  475. result = lbimId == cbimId;
  476. result = !cbimId.IsOnlyDutyNoModelBIMID() && result;
  477. break;
  478. //本地的bimid一定是完整的。
  479. //有对应的bimId,或者bimId的格式正确。
  480. if (result||!cbimId.IsOnlyDutyNoModelBIMID())
  481. {
  482. break;
  483. }
  484. string lcadId, ccadId;
  485. //bimId格式不正确,判断CADID
  486. //设备
  487. if (lduty is MEquipment lequip && cduty is MEquipment cequip)
  488. {
  489. lcadId = lequip.CADID;
  490. ccadId = cequip.CADID;
  491. result = lcadId.IsNotNullEmpty() && lcadId == ccadId;
  492. break;
  493. }
  494. //部件
  495. if (lduty is MEquipmentPart lpart && cduty is MEquipmentPart cpart)
  496. {
  497. lcadId = lpart.CADID;
  498. ccadId = cpart.CADID;
  499. result = lcadId.IsNotNullEmpty() && lcadId == ccadId;
  500. break;
  501. }
  502. } while (false);
  503. return result;
  504. }
  505. /// <summary>
  506. /// 判断物理世界岗位与本地岗位是否一致
  507. /// 依据1:BimID
  508. /// 依据2:CADID
  509. /// </summary>
  510. /// <param name="cduty"></param>
  511. /// <param name="lduty"></param>
  512. /// <returns></returns>
  513. public static bool IsEqualDutyByCADID(MRevitEquipBase cduty, MRevitEquipBase lduty)
  514. {
  515. bool result = false;
  516. do
  517. {
  518. if (!cduty.BimID.IsOnlyDutyNoModelBIMID())
  519. {
  520. result = false;
  521. break;
  522. }
  523. string lcadId, ccadId;
  524. //bimId格式不正确,判断CADID
  525. //设备
  526. if (lduty is MEquipment lequip && cduty is MEquipment cequip)
  527. {
  528. lcadId = lequip.CADID;
  529. ccadId = cequip.CADID;
  530. result = lcadId.IsNotNullEmpty() && lcadId == ccadId;
  531. break;
  532. }
  533. //部件
  534. if (lduty is MEquipmentPart lpart && cduty is MEquipmentPart cpart)
  535. {
  536. lcadId = lpart.CADID;
  537. ccadId = cpart.CADID;
  538. result = lcadId.IsNotNullEmpty() && lcadId == ccadId;
  539. break;
  540. }
  541. } while (false);
  542. return result;
  543. }
  544. /// <summary>
  545. /// 新旧文件对比过后,需要添加的数据
  546. /// </summary>
  547. public static void WrapperContext(CalcContext cloudContext, CalcContext localContext)
  548. {
  549. var cloudDutys = cloudContext.GetAllDutys();
  550. var localDutys = localContext.GetAllDutys();
  551. //设置初始状态
  552. cloudContext.SetState(DocumentChangedOperator.None);
  553. localContext.SetState(DocumentChangedOperator.None);
  554. #region Modify Add
  555. foreach (var lduty in localDutys)
  556. {
  557. var cdutys = cloudDutys.Where(t=> IsEqualCloudDuty2LocalDuty(t,lduty)).ToList();
  558. var cdutysByCADID= cloudDutys.Where(t => IsEqualDutyByCADID(t, lduty)).ToList();
  559. MRevitEquipBase cduty = null;
  560. //如果对应多个岗位,仅保留信息点多的岗位,删除其它岗位
  561. if (cdutys.Any()||cdutysByCADID.Count==1)
  562. {
  563. //如果通过CADID只找到一个,当做对应岗位处理。
  564. cdutys.AddRange(cdutysByCADID);
  565. if (cdutys.Count() > 1)
  566. {//信息点的个数从大到小排序
  567. cdutys.Sort((x, y) => { return -x.CloundJObject.Count.CompareTo(y.CloundJObject.Count); });
  568. //删除多余的岗位
  569. for (int i = 1; i < cdutys.Count; i++)
  570. {
  571. cdutys[i].Operator = DocumentChangedOperator.Delete;
  572. }
  573. }
  574. }
  575. else
  576. {
  577. //通过CADID找到多个,也当做新增处理 190823 tjc
  578. //请求Duty,Bim数据库中的id,待建模型清单产生的
  579. var dutyId = lduty.GetDutyBIMRelationByBIM()?.DutyId;
  580. if (dutyId.IsNotNullEmpty())
  581. {
  582. cdutys = cloudDutys.Where(t => t.Id == dutyId).ToList();
  583. if (!cdutys.Any())
  584. {
  585. //去跟据id物理世界查找
  586. var tempcduty = DalCommon.QueryObjectById(dutyId);
  587. if (tempcduty != null)
  588. {
  589. cdutys.Add(tempcduty);
  590. //添加设备所在楼层
  591. localContext.UnGroupDatas.Add(new RltEquipinFloor(dutyId,cloudContext.FloorId){Operator = DocumentChangedOperator.Add});
  592. }
  593. }
  594. }
  595. else
  596. {
  597. lduty.Id = dutyId;
  598. }
  599. }
  600. cduty = cdutys.FirstOrDefault();
  601. if (cduty == null)
  602. {
  603. //找不到物理世界对应的岗位,即为添加
  604. lduty.Operator = DocumentChangedOperator.Add;
  605. }
  606. else
  607. {
  608. //判断族编码是否更改
  609. if (EquipmentCodeMap.GetOriginCode(lduty.EquipClassCode) !=
  610. EquipmentCodeMap.GetOriginCode(cduty.EquipClassCode))
  611. {
  612. //族编码更改。删除旧岗位,创建新岗位
  613. cduty.Operator = DocumentChangedOperator.Delete;
  614. lduty.Operator = DocumentChangedOperator.Add;
  615. }
  616. else
  617. {
  618. lduty.Id = cduty.Id;
  619. lduty.Operator = DocumentChangedOperator.Modified;
  620. //后续物理世界Modified转化为None
  621. cduty.Operator = DocumentChangedOperator.Modified;
  622. }
  623. }
  624. //处理设备所在空间的关系
  625. OperateBaseRelation(localContext, lduty);
  626. }
  627. #endregion
  628. #region Delete
  629. //CloudDuty,有两种操作,更新和删除。更新等价于None
  630. foreach (var duty in cloudDutys)
  631. {
  632. //物理世界修改,不做处理或台账转过来的岗位
  633. if (duty.BimID.IsOnlyDutyNoModelBIMID() || duty.Operator == DocumentChangedOperator.Modified)
  634. {
  635. duty.Operator = DocumentChangedOperator.None;
  636. continue;
  637. }
  638. duty.Operator = DocumentChangedOperator.Delete;
  639. DelServiceRelation(cloudContext, duty);
  640. //删除时,会删除所在空间和所在楼层的关系
  641. }
  642. #endregion
  643. }
  644. /// <summary>
  645. /// 删除服务器基本关系
  646. /// </summary>
  647. private static void DelServiceRelation(CalcContext localContext, MRevitEquipBase mode)
  648. {
  649. if (mode.Operator != DocumentChangedOperator.Delete) return;
  650. #region EquipInSpace,Beacon
  651. var equiprelations = localContext.RltEquipInSpaces;
  652. var beaconrelations = localContext.RltBeaconinElementSps;
  653. if (mode is MBSpace)
  654. {
  655. var equipRelation = new RltEquipInSpace(null, mode.Id) { Operator = DocumentChangedOperator.Delete };
  656. equiprelations.Add(equipRelation);
  657. var beaconRelation = new RltBeaconinElementSp(null, mode.Id) { Operator = DocumentChangedOperator.Delete };
  658. beaconrelations.Add(beaconRelation);
  659. }
  660. else if (mode is MBeacon)
  661. {
  662. var beaconRelation = new RltBeaconinElementSp(mode.Id, null) { Operator = DocumentChangedOperator.Delete };
  663. beaconrelations.Add(beaconRelation);
  664. }
  665. else
  666. {
  667. var equipRelation = new RltEquipInSpace(mode.Id, null) { Operator = DocumentChangedOperator.Delete };
  668. equiprelations.Add(equipRelation);
  669. }
  670. #endregion
  671. }
  672. /// <summary>
  673. /// 处理基本关系
  674. /// </summary>
  675. private static void OperateBaseRelation(CalcContext localContext, MRevitEquipBase mode)
  676. {
  677. string bimid = mode.BimID;
  678. #region EquipInSpace,Beacon
  679. var equiprelations = localContext.RltEquipInSpaces;
  680. var beaconrelations = localContext.RltBeaconinElementSps;
  681. List<RltEquipInSpace> tempEquipRelations = new List<RltEquipInSpace>();
  682. List<RltBeaconinElementSp> tempBeaconRelations = new List<RltBeaconinElementSp>();
  683. if (mode is MBSpace)
  684. {
  685. tempEquipRelations = equiprelations.Where(t => t.MSpace.BimID == bimid).ToList();
  686. tempBeaconRelations = beaconrelations.Where(t => t.MSpace.BimID == bimid).ToList();
  687. }
  688. else if (mode is MBeacon)
  689. {
  690. tempBeaconRelations = beaconrelations.Where(t => t.MBeacon.BimID == bimid).ToList();
  691. }
  692. else
  693. {
  694. tempEquipRelations = equiprelations.Where(t => t.MEquipment.BimID == bimid).ToList();
  695. }
  696. switch (mode.Operator)
  697. {
  698. case DocumentChangedOperator.Add:
  699. tempEquipRelations.ForEach(t => t.Operator = DocumentChangedOperator.Add);
  700. tempBeaconRelations.ForEach(t => t.Operator = DocumentChangedOperator.Add);
  701. break;
  702. case DocumentChangedOperator.Delete:
  703. tempEquipRelations.ForEach(t => t.Operator = DocumentChangedOperator.Delete);
  704. tempBeaconRelations.ForEach(t => t.Operator = DocumentChangedOperator.Delete);
  705. break;
  706. case DocumentChangedOperator.Modified:
  707. tempEquipRelations.ForEach(t => t.Operator = DocumentChangedOperator.Delete);
  708. tempEquipRelations.ForEach(t => equiprelations.Add(new RltEquipInSpace(t.MSpace, t.MEquipment) { Operator = DocumentChangedOperator.Add }));
  709. tempBeaconRelations.ForEach(t => t.Operator = DocumentChangedOperator.Delete);
  710. tempBeaconRelations.ForEach(t => beaconrelations.Add(new RltBeaconinElementSp(t.MSpace, t.MBeacon) { Operator = DocumentChangedOperator.Add }));
  711. break;
  712. default:
  713. break;
  714. }
  715. #endregion
  716. }
  717. /// <summary>
  718. /// 上传岗位和基本关系数据操作
  719. /// </summary>
  720. /// <param name="floor"></param>
  721. public static void UploadDataOperate(MFloor floor)
  722. {
  723. LoadingOperation.Update();
  724. CalcContext serviceContext = DalCommon.DownLoadFloorDataByBIMFloorInfo(floor);
  725. LoadingOperation.Update();
  726. CalcContext localContext = ObjectCalc.Calc(floor);
  727. LoadingOperation.Update();
  728. WrapperContext(serviceContext, localContext);
  729. LoadingOperation.Update();
  730. serviceContext.Upload();
  731. UploadReportUtil.SendReport(serviceContext,localContext);
  732. LoadingOperation.Update();
  733. localContext.Upload();
  734. }
  735. /// <summary>
  736. /// 上传或下载完成之后的操作
  737. /// </summary>
  738. public static void AfterUploadOperate(MFloor floor, bool isunlock = true)
  739. {
  740. //请除Duty和BIMID的关系
  741. MBIAssistHelper.DeleteFloorRelation(floor.Id);
  742. if (isunlock)
  743. //解锁
  744. DalLock.UnLockFloor(floor.Id, false);
  745. //上传成功后清除日志数据
  746. ProjectLogManager.ClearFiles(floor.Id);
  747. //删除备份文件
  748. FloorFileOperate.Del000BakFile(floor.FullPath);
  749. }
  750. }
  751. }