using Shared.Common; using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using ZigBee.Device; namespace Shared.Phone.UserCenter { /// /// 分享的逻辑 /// public class HdlShardLogic { #region ■ 变量声明___________________________ /// /// 分享的逻辑 /// private static HdlShardLogic m_Current = null; /// /// 分享的逻辑 /// public static HdlShardLogic Current { get { if (m_Current == null) { m_Current = new HdlShardLogic(); } return m_Current; } set { m_Current = value; } } /// /// 分享的设备文件(key:设备主键,value:设备文件) /// private Dictionary dicShardDeviceFile = new Dictionary(); #endregion #region ■ 获取分享文件_______________________ /// /// 将分享的数据存入本地,返回的是文件名字(异常时返回null),调用 GetShardFileContent 可以获取文件内的内容 /// /// /// public async Task> SetShardFileToLocation(List listDistributedMark) { if (listDistributedMark.Count == 0) { return new List(); } ProgressBar.SetMaxValue(listDistributedMark.Count); List listFile = new List(); //文件夹 string strDir = System.IO.Path.Combine(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory); foreach (string keys in listDistributedMark) { var dataPra = new { DistributedMark = keys, HouseDistributedMark = Common.Config.Instance.Home.Id, IsOtherAccountControl = Common.Config.Instance.isAdministrator }; var result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeDataShare/GetOneShareData", false, dataPra); if (result == null) { return null; } var dataResult = Newtonsoft.Json.JsonConvert.DeserializeObject(result); //文件名字 listFile.Add(dataResult.ShareName); //保存到指定文件夹下 Global.WriteFileToDirectoryByBytes(strDir, dataResult.ShareName, dataResult.ShareDataBytes); //设置进度值 ProgressBar.SetValue(1); } return listFile; } /// /// 获取分享文件的内容 /// /// 文件名称(不是全路径) /// public byte[] GetShardFileContent(string fileName) { string fullName = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory, fileName); if (System.IO.File.Exists(fullName) == false) { return null; } string path = System.IO.Path.Combine(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory); var varByte = Global.ReadFileByDirectory(path, fileName); return varByte; } /// /// 获取本地全部的共享文件 /// /// 指定只获取指定房间的 /// public List GetLocalAllShardFile(Common.Room room = null) { string path = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory); var listFile = HdlAutoBackupLogic.GetFileFromDirectory(path); if (room == null) { return listFile; } //房间 var listRoomFile = new List() { room.FileName }; //场景文件 listRoomFile.AddRange(room.SceneUIFilePathList); //设备文件 foreach (var uiName in room.DeviceUIFilePathList) { string deviceName = uiName.Replace("DeviceUI_", string.Empty); listRoomFile.Add(deviceName); } return null; } #endregion #region ■ 添加分享文件_______________________ /// /// 添加分享文件到缓存 /// /// 原根目录下的文件名 public void AddShardFile(string fileName) { if (Global.IsExistsByHomeId(fileName) == false) { return; } string oldName = UserCenterLogic.CombinePath(fileName); string newName = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory, fileName); System.IO.File.Copy(oldName, newName, true); } /// /// 添加房间对象到缓存 /// /// 房间对象 public void AddShardFile(Common.Room room) { room.IsSharedRoom = true; var data = Newtonsoft.Json.JsonConvert.SerializeObject(room); var byteData = System.Text.Encoding.UTF8.GetBytes(data); string fullName = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory, room.FileName); //写入内容 Shared.IO.FileUtils.WriteFileByBytes(fullName, byteData); } /// /// 添加场景对象到缓存 /// /// 场景 public void AddShardFile(Common.SceneUI scene) { scene.IsSharedScene = true; var data = Newtonsoft.Json.JsonConvert.SerializeObject(scene); var byteData = System.Text.Encoding.UTF8.GetBytes(data); string fullName = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory, scene.FileName); //写入内容 Shared.IO.FileUtils.WriteFileByBytes(fullName, byteData); } #endregion #region ■ 删除分享文件_______________________ /// /// 添加分享文件到缓存 /// /// 指定文件名字 public void DeleteShardFile(string fileName) { fileName = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory, fileName); if (System.IO.File.Exists(fileName) == true) { System.IO.File.Delete(fileName); } } /// /// 清空共享文件夹 /// public void ClearShardDirectory() { this.dicShardDeviceFile.Clear(); //创建文件夹 string strDir = System.IO.Path.Combine(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory); Global.CreateEmptyDirectory(strDir, true); } #endregion #region ■ 同步服务器的分享内容_______________ /// /// 同步服务器的分享内容(里面只负责把东西存入本地) /// public async Task SynchronizeDbSharedContent() { if (UserCenterResourse.UserInfo.AuthorityNo != 3) { //只有成员才有这个概念 return true; } //获取主人分享给成员的文件列表 var infoPra = new { DistributedMark = Config.Instance.Guid, HouseDistributedMark = Common.Config.Instance.Home.Id , IsOtherAccountControl = Common.Config.Instance.isAdministrator }; var listNotShow = new List() { "NotSetAgain" }; var result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeDataShare/GetShareDataBySubAccount", false, infoPra, listNotShow); if (string.IsNullOrEmpty(result) == true) { return false; } var listShardInfo = Newtonsoft.Json.JsonConvert.DeserializeObject>(result); //主键 var listAddMark = new List(); //检测取消了共享的操作使用 var listShardFile = new HashSet(); //获取前回共享文件的更新日期(keys:文件名字,value:更新日期) var dicUpdateTime = this.GetAllShardFileAgoUpdateTime(); //先看看这分享数据里面有什么鬼 foreach (var info in listShardInfo) { string updateTime = info.TimeSpan; string fileName = info.ShareName; listShardFile.Add(fileName); //如果本地没有,或者更新日期大于前回更新日期的时候 if (Global.IsExistsByHomeId(fileName) == false || dicUpdateTime.ContainsKey(fileName) == false || updateTime.CompareTo(dicUpdateTime[fileName]) > 0) { listAddMark.Add(info.DistributedMark); //更新日更新 dicUpdateTime[fileName] = updateTime; } } //从云端获取下来文件 if (listAddMark.Count > 0) { //强制指定文本附加信息:共享数据同步中 string msg = Language.StringByID(R.MyInternationalizationString.uShardDataIsSynchronizing); //开启进度条 ProgressBar.Show(msg); ProgressBar.SetAppendText(msg); //将分享的数据存入本地(获取的是本地没有的) this.ClearShardDirectory(); var listDbFile = await this.SetShardFileToLocation(listAddMark); if (listDbFile == null) { //关闭 ProgressBar.Close(); return false; } //生成文件 foreach (string fileName in listDbFile) { var oldPath = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory, fileName); var newPath = System.IO.Path.Combine(Config.Instance.FullPath, fileName); System.IO.File.Copy(oldPath, newPath, true); if (fileName.StartsWith("Room_") == true) { //房间文件特殊处理 Config.Instance.Home.AddRoomListFilePath(fileName); } } //清空共享文件夹 this.ClearShardDirectory(); } //同步服务器的取消了的分享内容 return await this.SynchronizeDeleteSharedContent(listShardFile, dicUpdateTime); } /// /// 同步服务器的取消了的分享内容 /// /// 云端上面分享的文件,为Null时从新获取 /// 分享文件的更新时间,为Null时从新获取 /// public async Task SynchronizeDeleteSharedContent(HashSet listShardFile = null, Dictionary dicUpdateTime = null) { if (UserCenterResourse.UserInfo.AuthorityNo != 3) { //只有成员才有这个概念 return true; } //强制指定文本附加信息:共享数据同步中 string msg = Language.StringByID(R.MyInternationalizationString.uShardDataIsSynchronizing); //开启进度条 ProgressBar.Show(msg); ProgressBar.SetAppendText(msg); if (dicUpdateTime == null) { //获取前回共享文件的更新日期(keys: 文件名字, value: 更新日期) dicUpdateTime = this.GetAllShardFileAgoUpdateTime(); } //重新获取 if (listShardFile == null) { listShardFile = new HashSet(); //获取主人分享给成员的文件列表 var infoPra = new { DistributedMark = Config.Instance.Guid, HouseDistributedMark = Common.Config.Instance.Home.Id, IsOtherAccountControl = Common.Config.Instance.isAdministrator }; var listNotShow = new List() { "NotSetAgain" }; var result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeDataShare/GetShareDataBySubAccount", false, infoPra, listNotShow); if (string.IsNullOrEmpty(result) == true) { //关闭 ProgressBar.Close(); return false; } var listShardData = Newtonsoft.Json.JsonConvert.DeserializeObject>(result); //先看看这分享数据里面有什么鬼 foreach (var info in listShardData) { listShardFile.Add(info.ShareName); } } //然后检测本地的文件 var listLocalFile = Global.FileListByHomeId(); foreach (string fileName in listLocalFile) { if (fileName == DirNameResourse.ShardFloorFile) { //楼层文件 var varData = Global.ReadFileByHomeId(fileName); var dicFloor = Newtonsoft.Json.JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(varData)); Common.Config.Instance.Home.FloorDics = dicFloor; Common.Config.Instance.Home.Save(false); Global.DeleteFilebyHomeId(fileName); } if (listShardFile.Contains(fileName) == true) { //本地的这个文件还分享着,没有问题 continue; } //检测本地设备文件,是否存在已经取消了共享了的 if (fileName.StartsWith("Device_") == true) { //删除掉这个设备文件 Global.DeleteFilebyHomeId(fileName); dicUpdateTime.Remove(fileName); } //检测本地房间文件,是否存在已经取消了共享了的 else if (fileName.StartsWith("Room_") == true) { var roomData = Global.ReadFileByHomeId(fileName); var nowRoom = Newtonsoft.Json.JsonConvert.DeserializeObject(Encoding.UTF8.GetString(roomData)); if (nowRoom.IsSharedRoom == false) { //这个房间是他自己创建的 continue; } //删除掉这个房间文件 Global.DeleteFilebyHomeId(fileName); dicUpdateTime.Remove(fileName); if (Config.Instance.Home.RoomFilePathList.Contains(fileName) == true) { Config.Instance.Home.RemoveRoomListFilePath(fileName); } } //检测本地场景文件,是否存在已经取消了共享了的 else if (fileName.StartsWith("Scene_") == true) { var sceneData = Global.ReadFileByHomeId(fileName); var nowScene = Newtonsoft.Json.JsonConvert.DeserializeObject(Encoding.UTF8.GetString(sceneData)); if (nowScene.IsSharedScene == false) { //这个场景是他自己创建的 continue; } //删除掉这个场景文件 Global.DeleteFilebyHomeId(fileName); dicUpdateTime.Remove(fileName); } } //网关文件非合法性是刷新设备列表的函数里面实现 //保存全部分享文件的更新日期 this.SaveAllShardFileAgoUpdateTime(dicUpdateTime); //关闭 ProgressBar.Close(); return true; } #endregion #region ■ 同步内容更新时间___________________ /// /// 获取全部分享文件的前回更新日期 /// /// private Dictionary GetAllShardFileAgoUpdateTime() { var dicTime = new Dictionary(); var data = Global.ReadFileByDirectory(DirNameResourse.LocalMemoryDirectory, DirNameResourse.ShardFileUpdateFile); if (data == null) { //目标文件不存在 return dicTime; } dicTime = Newtonsoft.Json.JsonConvert.DeserializeObject>(System.Text.Encoding.UTF8.GetString(data)); return dicTime; } /// /// 保存全部分享文件的更新日期 /// /// private void SaveAllShardFileAgoUpdateTime(Dictionary dicTime) { var data = Newtonsoft.Json.JsonConvert.SerializeObject(dicTime); var byteData = System.Text.Encoding.UTF8.GetBytes(data); Global.WriteFileToDirectoryByBytes(DirNameResourse.LocalMemoryDirectory, DirNameResourse.ShardFileUpdateFile, byteData); } #endregion //----------------------------------分割线(数据预备)------------------------------------------------- #region ■ 数据预备___________________________ /// /// 获取成员共享列表然后保存到本地(用完之后最好调用清空 ClearShardDirectory函数清空) /// /// 成员列表接口返回的SubAccountDistributedMark /// /// 成员的分享数据 /// 如果不知道这是什么东西,就New一个,然后缓存起来,调用其他函数都需要这个东西 /// New的时候记得对SubAccountDistributedMark赋值,它是成员列表接口返回的SubAccountDistributedMark /// /// public async Task GetMemberShardContentListAndSetToLocation(MemberShardInfoData memberShardInfo) { if (memberShardInfo.Refresh == false) { //从本地获取成员的分享列表 this.GetMemberShardContentListFromLocal(memberShardInfo); return true; } memberShardInfo.Refresh = false; //打开进度条 ProgressBar.Show(); var infoPra = new { DistributedMark = memberShardInfo.SubAccountDistributedMark, HouseDistributedMark = Shared.Common.Config.Instance.HomeId, IsOtherAccountControl = Common.Config.Instance.isAdministrator }; var result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeDataShare/GetShareDataBySubAccount", false, infoPra); if (result == null) { //关闭进度条 ProgressBar.Close(); return false; } var listData = Newtonsoft.Json.JsonConvert.DeserializeObject>(result); //先清空共享文件夹 this.ClearShardDirectory(); var listMark = new List(); foreach (var data in listData) { //性能优化:如果本地拥有这个文件的话,直接使用那个文件 string fileName = data.ShareName; //记录起它的主键 memberShardInfo.dicAllShardKeys[fileName] = data.DistributedMark; if (fileName.StartsWith("Room_") == true || fileName.StartsWith("Scene_") == true) { //房间文件和场景文件需要重新反序列化 listMark.Add(data.DistributedMark); continue; } if (Shared.Common.Global.IsExistsByHomeId(fileName) == true) { //其他文件的话,如果本地存在,则以本地文件为准 this.AddShardFile(fileName); continue; } listMark.Add(data.DistributedMark); } //将分享的数据存入本地,返回的是文件名字(异常时返回null) var listFile = await this.SetShardFileToLocation(listMark); if (listFile == null) { //关闭进度条 ProgressBar.Close(); return false; } //从本地获取成员的分享列表 this.GetMemberShardContentListFromLocal(memberShardInfo); //关闭进度条 ProgressBar.Close(); return true; } /// /// 从本地获取成员的分享列表 /// /// 成员的分享数据的缓存(调用这个函数会刷新这个变量的信息) private void GetMemberShardContentListFromLocal(MemberShardInfoData memberShardInfo) { memberShardInfo.dicShardRoom = new Dictionary(); this.dicShardDeviceFile.Clear(); var listDeviceFile = new HashSet(); var listSceneFile = new HashSet(); var listFile = this.GetLocalAllShardFile(); //先初始化房间 foreach (string fileName in listFile) { if (fileName.StartsWith("Room_") == true) { //房间文件 var byteData = this.GetShardFileContent(fileName); if (byteData != null) { string valueData = System.Text.Encoding.UTF8.GetString(byteData); var roomTemp = Newtonsoft.Json.JsonConvert.DeserializeObject(valueData); memberShardInfo.dicShardRoom[fileName] = roomTemp; } } else if (fileName == DirNameResourse.ShardFloorFile) { //楼层文件 var byteData = this.GetShardFileContent(fileName); if (byteData != null) { string valueData = System.Text.Encoding.UTF8.GetString(byteData); memberShardInfo.dicShardFloor = Newtonsoft.Json.JsonConvert.DeserializeObject>(valueData); } } else if (fileName.StartsWith("Device_") == true) { string[] Arry = fileName.Split(new string[] { "_" }, StringSplitOptions.RemoveEmptyEntries); string mainKeys = Common.LocalDevice.Current.GetDeviceMainKeys(Arry[2], Convert.ToInt32(Arry[3])); this.dicShardDeviceFile[mainKeys] = fileName; //设备文件 listDeviceFile.Add(fileName); } else if (fileName.StartsWith("Scene_") == true) { //场景文件 listSceneFile.Add(fileName); } } //设置房间里面设备的UI对象(因为这个东西是反序列化出来的,设备UI对象是不序列化对象) foreach (var tempRoom in memberShardInfo.dicShardRoom.Values) { //还原设备对象 tempRoom.DeviceUIList.Clear(); for (int i = 0; i < tempRoom.DeviceUIFilePathList.Count; i++) { string deviceFile = tempRoom.DeviceUIFilePathList[i]; //这个设备文件匹配得到房间 listDeviceFile.Remove(deviceFile); if (this.IsFileExists(deviceFile) == false) { //移除掉这个不对劲的路径 tempRoom.DeviceUIFilePathList.RemoveAt(i); i--; continue; } tempRoom.DeviceUIList.Add(Common.LocalDevice.Current.GetDeviceUI(deviceFile)); } //还原场景对象 tempRoom.SceneUIList.Clear(); for (int i = 0; i < tempRoom.SceneUIFilePathList.Count; i++) { string uiPath = tempRoom.SceneUIFilePathList[i]; //这个场景文件匹配得到房间 listSceneFile.Remove(uiPath); var byteData = this.GetShardFileContent(uiPath); if (byteData == null) { //移除掉这个不对劲的路径 tempRoom.SceneUIFilePathList.RemoveAt(i); i--; continue; } string valueData = System.Text.Encoding.UTF8.GetString(byteData); var tempUi = Newtonsoft.Json.JsonConvert.DeserializeObject(valueData); tempRoom.SceneUIList.Add(tempUi); //获取场景里面的全部目标(2019.11.05追加操作,有可能那个设备是由场景嵌套来的,所以它有可能不属于任何房间) foreach (var data in tempUi.AddSceneMemberDataList) { //设备 if (data.Type == 0) { string mainkey = LocalDevice.Current.GetDeviceMainKeys(data.DeviceAddr, data.Epoint); if (dicShardDeviceFile.ContainsKey(mainkey) == true ) { //这个设备文件匹配得到 listDeviceFile.Remove(dicShardDeviceFile[mainkey]); } } if (data.Type == 1) { var temp = new SceneUI(); temp.Id = data.ElseScenesId; //这个场景文件匹配得到 listSceneFile.Remove(temp.FileName); } } } } //如果存在匹配不上的文件 if (listDeviceFile.Count != 0 || listSceneFile.Count != 0) { //创建一个临时房间来存储 var roomTemp = new Room(); roomTemp.Id = "Other"; roomTemp.FloorId = "Other"; memberShardInfo.dicShardRoom[roomTemp.FileName] = roomTemp; roomTemp.Name = Language.StringByID(R.MyInternationalizationString.uUnallocated); //还原设备对象 foreach (string deviceFile in listDeviceFile) { roomTemp.DeviceUIFilePathList.Add(deviceFile); roomTemp.DeviceUIList.Add(Common.LocalDevice.Current.GetDeviceUI(deviceFile)); } //还原场景对象 foreach (string uiPath in listSceneFile) { var byteData = this.GetShardFileContent(uiPath); string valueData = System.Text.Encoding.UTF8.GetString(byteData); var tempUi = Newtonsoft.Json.JsonConvert.DeserializeObject(valueData); roomTemp.SceneUIList.Add(tempUi); } } } #endregion //----------------------------------分割线(上传新的分享)--------------------------------------------- #region ■ 执行上传新的分享___________________ /// /// 执行上传新的分享 /// /// 成员的分享数据 /// 当前的房间对象 /// 选择上传的设备 /// 选择上传的场景 public async Task DoUploadSharedContent(MemberShardInfoData memberShardInfo, Common.Room nowRoom, List listDevice, List listScene) { var listCheck = new HashSet(); //获取场景里面嵌套的子设备和子场景 var listChirdDevice = new List(); var listChirdScene = new List(); foreach (var SceneTemp in listScene) { //从缓存获取场景的执行目标 this.GetSceneDeviceList(SceneTemp, listCheck, listChirdScene, listChirdDevice); } //防止出现错误,暂时保存两个列表(虽然没那么麻烦,不过既然已经这样写了就这样了) var dicBackDevice = new Dictionary>(); var dicBackScene = new Dictionary>(); //临时备份房间设备列表 this.BackupRoomDevicelistTemporary(memberShardInfo, dicBackDevice, dicBackScene); Common.Room roomTemp = null; if (memberShardInfo.dicShardRoom.ContainsKey(nowRoom.FileName) == false) { //克隆一个对象 roomTemp = nowRoom.CloneRoomClass(); memberShardInfo.dicShardRoom[nowRoom.FileName] = roomTemp; } roomTemp = memberShardInfo.dicShardRoom[nowRoom.FileName]; //获取上传的文件,然后将文件复制到指定文件夹 var listFile = this.GetUploadListFile(ref roomTemp, listDevice, listScene, listChirdDevice, listChirdScene); //打开进度条 ProgressBar.Show(); //设置最大值 ProgressBar.SetMaxValue(listFile.Count); //上传分享 var result = await this.DoUploadShardContent(memberShardInfo, nowRoom, listFile); //关闭进度条 ProgressBar.Close(); if (result == false) { //恢复原数据 this.RecoverRoomDevicelistTemporary(memberShardInfo, dicBackDevice, dicBackScene, listFile); return false; } return true; } /// /// 获取上传的文件名 /// /// 需要上传到云端的房间对象 /// 分享的设备列表 /// 分享的场景列表 /// 场景里面递归获取的设备 /// 场景里面递归获取的场景 /// private List GetUploadListFile(ref Common.Room roomTemp, List listDevice, List listScene, List listChirdDevice, List listChirdScene) { var listFile = new List(); var listOtaCheck = new List(); foreach (var device in listDevice) { //设备 listFile.Add(device.FilePath); HdlShardLogic.Current.AddShardFile(device.FilePath); //加点缓存 this.dicShardDeviceFile[LocalDevice.Current.GetDeviceMainKeys(device)] = device.FilePath; //设备的UI var deviceUi = device.FilePath; if (roomTemp.DeviceUIFilePathList.Contains(deviceUi) == false) { roomTemp.DeviceUIFilePathList.Add(deviceUi); } } //递归获取的设备不需要加入到房间 foreach (var device in listChirdDevice) { //设备 listFile.Add(device.FilePath); this.AddShardFile(device.FilePath); //加点缓存 this.dicShardDeviceFile[LocalDevice.Current.GetDeviceMainKeys(device)] = device.FilePath; } //场景 foreach (var secene in listScene) { listFile.Add(secene.FileName); HdlShardLogic.Current.AddShardFile(secene); if (roomTemp.SceneUIFilePathList.Contains(secene.FileName) == false) { roomTemp.SceneUIFilePathList.Add(secene.FileName); } } //递归获取的场景不需要加入到房间 foreach (var secene in listChirdScene) { listFile.Add(secene.FileName); HdlShardLogic.Current.AddShardFile(secene); } //房间文件也给过去 listFile.Add(roomTemp.FileName); HdlShardLogic.Current.AddShardFile(roomTemp); return listFile; } /// /// 获取场景的目标设备列表(这个不能从分享数据中获取) /// /// 场景 /// 重复检测用 /// 添加分享的场景列表 /// 添加分享的设备列表 /// private void GetSceneDeviceList(Common.SceneUI scene, HashSet listCheck, List listSceneUI, List listDevice) { foreach (var data in scene.AddSceneMemberDataList) { //设备 if (data.Type == 0) { string mainKeys = Common.LocalDevice.Current.GetDeviceMainKeys(data.DeviceAddr, data.Epoint); if (listCheck.Contains(mainKeys) == true) { //不重复添加 continue; } listCheck.Add(mainKeys); var device = Common.LocalDevice.Current.GetDevice(data.DeviceAddr, data.Epoint); if (device != null) { listDevice.Add(device); } } //场景 else if (data.Type == 1) { string mainKeys = data.ElseScenesId.ToString(); if (listCheck.Contains(mainKeys) == true) { //不重复添加 continue; } listCheck.Add(mainKeys); //获取场景对象 var sceneUi = Room.CurrentRoom.GetSceneUIBySceneId(data.ElseScenesId); if (sceneUi != null) { listSceneUI.Add(sceneUi); } } } } #endregion #region ■ 上传新的分享_______________________ /// /// 上传分享(返回云端分享文件的主键:DistributedMark) /// /// 成员的分享数据 /// 当前的房间对象 /// 上传的文件名 /// private async Task DoUploadShardContent(MemberShardInfoData memberShardInfo, Common.Room nowRoom, List listFile) { var dicKeys = new Dictionary(); for (int i = 0; i < listFile.Count; i++) { string fileName = listFile[i]; var info = new UploadShardContent(); info.SubAccountDistributedMark = memberShardInfo.SubAccountDistributedMark; info.ShareName = fileName; info.ShareDataBytes = HdlShardLogic.Current.GetShardFileContent(fileName); //追加共享 if (memberShardInfo.dicAllShardKeys.ContainsKey(fileName) == false) { var result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeDataShare/AddShareData", false, info); if (string.IsNullOrEmpty(result) == true) { return false; } //这里有点特殊,接口是直接返回主键回来的,而不是Jsoin dicKeys[fileName] = result; } else { info.DistributedMark = memberShardInfo.dicAllShardKeys[fileName]; var result = await UserCenterLogic.GetResultStatuByRequestHttps("ZigbeeDataShare/EditShareData", false, info); if (result == false) { return false; } dicKeys[fileName] = info.DistributedMark; } //设置进度值 ProgressBar.SetValue(1); } //如果没有错误,则添加临时缓存 var listShard = memberShardInfo.dicAllMemberShard[nowRoom.FileName]; foreach (var keys in dicKeys.Keys) { if (listShard.Contains(keys) == false) { listShard.Add(keys); } memberShardInfo.dicAllShardKeys[keys] = dicKeys[keys]; } return true; } #endregion #region ■ 临时备份房间设备列表_______________ /// /// 临时备份房间设备列表 /// /// 成员的分享数据 /// 空的设备备份列表 /// 空的场景备份列表 private void BackupRoomDevicelistTemporary(MemberShardInfoData memberShardInfo, Dictionary> dicBackDevice, Dictionary> dicBackScene) { foreach (var roomKeys in memberShardInfo.dicShardRoom.Keys) { dicBackDevice[roomKeys] = new List(); dicBackScene[roomKeys] = new List(); dicBackDevice[roomKeys].AddRange(memberShardInfo.dicShardRoom[roomKeys].DeviceUIFilePathList); dicBackScene[roomKeys].AddRange(memberShardInfo.dicShardRoom[roomKeys].SceneUIFilePathList); } } /// /// 还原临时备份的房间设备列表 /// /// 成员的分享数据 /// 临时备份的设备备份列表 /// 临时备份的场景备份列表 /// 上传的文件名 private void RecoverRoomDevicelistTemporary(MemberShardInfoData memberShardInfo, Dictionary> dicBackDevice, Dictionary> dicBackScene, List listFile) { foreach (string fileName in listFile) { //生成的文件全部删除,房间文件的话,下面会重新生成 HdlShardLogic.Current.DeleteShardFile(fileName); } foreach (var roomKeys in memberShardInfo.dicShardRoom.Keys) { if (dicBackDevice.ContainsKey(roomKeys) == false) { continue; } memberShardInfo.dicShardRoom[roomKeys].DeviceUIFilePathList.Clear(); memberShardInfo.dicShardRoom[roomKeys].DeviceUIFilePathList.AddRange(dicBackDevice[roomKeys]); memberShardInfo.dicShardRoom[roomKeys].SceneUIFilePathList.Clear(); memberShardInfo.dicShardRoom[roomKeys].SceneUIFilePathList.AddRange(dicBackScene[roomKeys]); //覆盖房间文件 HdlShardLogic.Current.AddShardFile(memberShardInfo.dicShardRoom[roomKeys]); } } #endregion //----------------------------------分割线(删除指定分享)--------------------------------------------- #region ■ 移除指定分享内容___________________ /// /// 移除指定分享内容 /// /// 成员的分享信息 /// 当前房间 /// 要取消的设备 /// 要取消的场景 /// public async Task DoDeleteSharedContent(MemberShardInfoData memberShardInfo, Common.Room nowRoom, List listDevice, List listSceneUI) { var roomTemp = memberShardInfo.dicShardRoom[nowRoom.FileName]; //防止出错,先备份列表 var listBackDevice = new List(); listBackDevice.AddRange(roomTemp.DeviceUIFilePathList); var listBackScene = new List(); listBackScene.AddRange(roomTemp.SceneUIFilePathList); var listMark = new List(); //要删除的文件名字 var listDeleteFile = new List(); //这个是只移除缓存的文件名字 var listDeleteFileEx = new List(); //云端的指定房间的共享文件列表 var dicShardFile = memberShardInfo.dicAllMemberShard[nowRoom.FileName]; //除了要删除的目标外,还分享的数据 var listHadShard = this.GetAllShardedFileNameFromDictionary(memberShardInfo, nowRoom, listDevice, listSceneUI); //先弄设备 foreach (var device in listDevice) { string deviceFileName = device.FilePath; //移除路径列表 roomTemp.DeviceUIFilePathList.Remove(device.FilePath); if (listHadShard.Contains(deviceFileName) == true) { //其他房间分享有这个设备,所以不删除这个设备的根源文件,只是把房间的设备列表路径移除 listDeleteFileEx.Add(deviceFileName); continue; } //设备主键 if (dicShardFile.Contains(deviceFileName) == true) { listMark.Add(memberShardInfo.dicAllShardKeys[deviceFileName]); } listDeleteFile.Add(device.FilePath); } //再弄场景 foreach (var sceneUI in listSceneUI) { //移除缓存 roomTemp.SceneUIFilePathList.Remove(sceneUI.FileName); //其他场景还嵌套着这个场景,所以不删除这个场景的根源文件,只是把房间的场景列表路径移除 //但是它绑定的设备目标要删除 if (listHadShard.Contains(sceneUI.FileName) == true) { listDeleteFileEx.Add(sceneUI.FileName); } else { //获取要删除的分享主键 if (dicShardFile.Contains(sceneUI.FileName) == true) { listMark.Add(memberShardInfo.dicAllShardKeys[sceneUI.FileName]); } listDeleteFile.Add(sceneUI.FileName); } //执行删除嵌套的设备 var listTemp = new HashSet(); this.GetSceneBindFileName(sceneUI, ref listTemp); foreach (var fileName in listTemp) { if (listHadShard.Contains(fileName) == true) { continue; } //获取要删除的分享主键 if (dicShardFile.Contains(fileName) == true) { listMark.Add(memberShardInfo.dicAllShardKeys[fileName]); } listDeleteFile.Add(fileName); } } //如果这个房间的分享设备和场景全部删除的话,把分享房间文件也一起删除 if (roomTemp.DeviceUIFilePathList.Count == 0 && roomTemp.SceneUIFilePathList.Count == 0) { listMark.Add(memberShardInfo.dicAllShardKeys[nowRoom.FileName]); listDeleteFile.Add(nowRoom.FileName); } //执行移除分享数据 var result = await this.DoDeleteSharedContent(memberShardInfo, nowRoom, listMark, listDeleteFile); //同步房间文件 if (result == true && listDeleteFile.Contains(roomTemp.FileName) == false) { //执行上传对象 result = await this.DoUploadRoomObject(memberShardInfo, roomTemp); } if (result == true) { foreach (var exFile in listDeleteFileEx) { //只移除缓存,不删除云端 if (dicShardFile.Contains(exFile) == true) { dicShardFile.Remove(exFile); } } } else { //恢复 roomTemp.DeviceUIFilePathList.Clear(); roomTemp.DeviceUIFilePathList.AddRange(listBackDevice); roomTemp.SceneUIFilePathList.Clear(); roomTemp.SceneUIFilePathList.AddRange(listBackScene); } return result; } #endregion #region ■ 执行移除分享数据___________________ /// /// 执行移除分享数据 /// /// 成员的分享内容 /// 当前房间 /// 要移除的主键 /// 要删除的文件(房间文件需要删除的话,必须放在最后) /// private async Task DoDeleteSharedContent(MemberShardInfoData memberShardInfo, Common.Room nowRoom, List listMark, List listDeleteFile) { if (listMark.Count == 0) { //有可能只删除一个回路,而这个回路是分配到多个房间的 return true; } var info = new DeleteShardInfo(); //开启进度条 ProgressBar.Show(); var listCheck = new HashSet(); foreach (var markKeys in listMark) { //里面似乎有可能会出现重复 if (listCheck.Contains(markKeys) == true) { continue; } listCheck.Add(markKeys); info.DistributedMark = markKeys; //执行删除 var result = await UserCenterLogic.GetResultStatuByRequestHttps("ZigbeeDataShare/DeleteShareData", false, info); if (result == false) { //关闭进度条 ProgressBar.Close(); return false; } } //关闭进度条 ProgressBar.Close(); for (int i = 0; i < listDeleteFile.Count; i++) { string fileName = listDeleteFile[i]; if (i == listDeleteFile.Count - 1 && fileName.StartsWith("Room_") == true) { //最后一个固定可能是房间文件,直接移除整个对象 memberShardInfo.dicShardRoom.Remove(fileName); memberShardInfo.dicAllMemberShard.Remove(fileName); } else { //移除指定文件 dicShard.Remove(fileName); } memberShardInfo.dicAllShardKeys.Remove(fileName); HdlShardLogic.Current.DeleteShardFile(fileName); } return true; } #endregion #region ■ 上传房间对象_______________________ /// /// 上传房间对象 /// /// 成员的共享内容 /// 需要上传到云端的房间对象 /// private async Task DoUploadRoomObject(MemberShardInfoData memberShardInfo, Common.Room upDateRoom) { var info = new EditorShardContent(); info.DistributedMark = memberShardInfo.dicAllShardKeys[upDateRoom.FileName]; info.ShareName = upDateRoom.FileName; info.SubAccountDistributedMark = memberShardInfo.SubAccountDistributedMark; var data = Newtonsoft.Json.JsonConvert.SerializeObject(upDateRoom); var byteData = System.Text.Encoding.UTF8.GetBytes(data); info.ShareDataBytes = byteData; var result = await UserCenterLogic.GetResultStatuByRequestHttps("ZigbeeDataShare/EditShareData", false, info); if (result == false) { return false; } //将房间对象序列化到缓存 HdlShardLogic.Current.AddShardFile(upDateRoom); return true; } #endregion #region ■ 移除共享的一般方法_________________ /// /// 从缓存字典中获取已经分享了的全部设备文件和场景的文件名字 /// /// 成员的分享信息 /// 当前房间 /// 要删除的设备列表 /// 要删除的场景列表 /// private HashSet GetAllShardedFileNameFromDictionary(MemberShardInfoData memberShardInfo, Common.Room nowRoom, List listDeleteDevice, List listDeleteScene) { //获取全部要删除的文件名字 var listDeleteFile = new HashSet(); foreach (var device in listDeleteDevice) { listDeleteFile.Add(device.FilePath); } foreach (var scene in listDeleteScene) { listDeleteFile.Add(scene.FileName); } var listShardFile = new HashSet(); //获取还处于分享状态的文件 foreach (var roomTemp in memberShardInfo.dicShardRoom.Values) { bool flage = roomTemp.FileName == nowRoom.FileName; //设备 foreach (var deviceUi in roomTemp.DeviceUIFilePathList) { string deviceFile = deviceUi; if (listDeleteFile.Contains(deviceFile) == true) { //当前房间的要特殊处理,如果是删除目标,则不添加 continue; } if (listShardFile.Contains(deviceFile) == false) { listShardFile.Add(deviceFile); } } //场景 foreach (var scene in roomTemp.SceneUIList) { if (roomTemp.SceneUIFilePathList.Contains(scene.FileName) == false) { //这个场景已经被删除 continue; } if (flage == true && listDeleteFile.Contains(scene.FileName) == true) { //当前房间的要特殊处理,如果是删除目标,则不添加 continue; } //获取场景里面的全部目标 var listTemp = new HashSet(); this.GetSceneBindFileName(scene, ref listTemp); if (listShardFile.Contains(scene.FileName) == false) { //场景自身的文件 listShardFile.Add(scene.FileName); } foreach (string file in listTemp) { if (listShardFile.Contains(file) == false) { listShardFile.Add(file); } } } } return listShardFile; } /// /// 从场景对象里面获取全部的绑定目标的文件名字(这里面的东西必须从分享数据中获取) /// /// 场景 /// 文件列表(里面存的是设备UI文件和设备文件和场景文件) private void GetSceneBindFileName(Common.SceneUI scene, ref HashSet listFile) { foreach (var data in scene.AddSceneMemberDataList) { //设备 if (data.Type == 0) { string mainkey = LocalDevice.Current.GetDeviceMainKeys(data.DeviceAddr, data.Epoint); if (dicShardDeviceFile.ContainsKey(mainkey) == true && listFile.Contains(dicShardDeviceFile[mainkey]) == false) { listFile.Add(dicShardDeviceFile[mainkey]); } } if (data.Type == 1) { var sceneTemp = Room.CurrentRoom.GetSceneUIBySceneId(data.ElseScenesId); if (sceneTemp != null && listFile.Contains(sceneTemp.FileName)) { string valueData = System.Text.Encoding.UTF8.GetString(byteData); var roomTemp = Newtonsoft.Json.JsonConvert.DeserializeObject(valueData); dicBindScene[roomTemp.FileName] = roomTemp; if (listFile.Contains(roomTemp.FileName) == false) { listFile.Add(roomTemp.FileName); } } } } } #endregion #region ■ 结构体类___________________________ /// /// 上传分享的内容 /// private class UploadShardContent : IfacePraCommon { /// /// 分享数据的主键 /// public string DistributedMark = string.Empty; /// /// 分享名字 /// public string ShareName = string.Empty; /// /// 住宅ID /// public string HouseDistributedMark = Common.Config.Instance.Home.Id; /// /// 子账号的guid /// public string SubAccountDistributedMark = string.Empty; /// /// 分享内容 /// public byte[] ShareDataBytes = null; } /// /// 删除共享的内容 /// private class DeleteShardInfo : IfacePraCommon { /// /// 共享数据的唯一标识 /// public string DistributedMark = null; /// /// 住宅ID /// public string HouseDistributedMark = Common.Config.Instance.Home.Id; } /// /// 编辑共享内容 /// private class EditorShardContent : IfacePraCommon { /// /// 主键 /// public string DistributedMark = string.Empty; /// /// 分享名字 /// public string ShareName = string.Empty; /// /// 住宅ID /// public string HouseDistributedMark = Common.Config.Instance.Home.Id; /// /// 分享内容 /// public byte[] ShareDataBytes = null; /// /// 子账号的Guid /// public string SubAccountDistributedMark = string.Empty; } #endregion } }