陈嘉乐
2020-07-10 48ba446936b51fffafa7c3600c0dadc6ac0e8c20
ZigbeeApp/Shared/Phone/UserCenter/CommonBase/Logic/HdlShardLogic.cs
@@ -1,6 +1,9 @@
using Shared.Common;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using ZigBee.Device;
@@ -36,6 +39,11 @@
                m_Current = value;
            }
        }
        /// <summary>
        /// 分享的设备文件(key:设备主键,value:设备文件)
        /// </summary>
        private Dictionary<string, string> dicShardDeviceFile = new Dictionary<string, string>();
        #endregion
        #region ■ 获取分享文件_______________________
@@ -45,24 +53,32 @@
        /// </summary>
        /// <param name="listDistributedMark"></param>
        /// <returns></returns>
        public async Task<List<string>> SetShardFileToLocation(List<string> listDistributedMark)
        private async Task<List<string>> SetShardFileToLocation(List<string> listDistributedMark)
        {
            if (listDistributedMark.Count == 0)
            {
                return new List<string>();
            }
            ProgressBar.SetMaxValue(listDistributedMark.Count);
            int listMarkCount = listDistributedMark.Count;
            List<string> listFile = new List<string>();
            //文件夹
            string strDir = System.IO.Path.Combine(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory);
            foreach (string keys in listDistributedMark)
            //不允许按系统的返回键
            Shared.Common.CommonPage.BackKeyCanClick = false;
            UserCenterResourse.AccountOption.AppCanSignout = false;
            for (int i = 0; i < listDistributedMark.Count; i++)
            {
                var dataPra = new { DistributedMark = keys, HouseDistributedMark = Common.Config.Instance.Home.Id, IsOtherAccountControl = Common.Config.Instance.isAdministrator };
                string keys = listDistributedMark[i];
                var dataPra = new { DistributedMark = keys, HouseDistributedMark = Common.Config.Instance.Home.Id, IsOtherAccountControl = Common.Config.Instance.Home.IsOthreShare };
                var result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeDataShare/GetOneShareData", false, dataPra);
                if (result == null)
                {
                    //允许按系统的返回键
                    Shared.Common.CommonPage.BackKeyCanClick = true;
                    UserCenterResourse.AccountOption.AppCanSignout = true;
                    return null;
                }
                var dataResult = Newtonsoft.Json.JsonConvert.DeserializeObject<GetShardInfoResult>(result);
@@ -71,8 +87,12 @@
                //保存到指定文件夹下
                Global.WriteFileToDirectoryByBytes(strDir, dataResult.ShareName, dataResult.ShareDataBytes);
                //设置进度值
                ProgressBar.SetValue(1);
                ProgressFormBar.Current.SetValue(i + 1, listMarkCount);
            }
            //允许按系统的返回键
            Shared.Common.CommonPage.BackKeyCanClick = true;
            UserCenterResourse.AccountOption.AppCanSignout = true;
            return listFile;
        }
@@ -97,27 +117,28 @@
        /// <summary>
        /// 获取本地全部的共享文件
        /// </summary>
        /// <param name="room">指定只获取指定房间的</param>
        /// <returns></returns>
        public List<string> GetLocalAllShardFile(Common.Room room = null)
        public List<string> GetLocalAllShardFile()
        {
            string path = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory);
            var listFile = HdlAutoBackupLogic.GetFileFromDirectory(path);
            if (room == null)
            return listFile;
        }
        /// <summary>
        /// 文件是否存在
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public bool IsFileExists(string fileName)
        {
            string fullName = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory, fileName);
            if (System.IO.File.Exists(fullName) == false)
            {
                return listFile;
                return false;
            }
            //房间
            var listRoomFile = new List<string>() { room.FileName };
            //场景文件
            listRoomFile.AddRange(room.SceneUIFilePathList);
            //设备文件
            foreach (var uiName in room.DeviceUIFilePathList)
            {
                string deviceName = uiName.Replace("DeviceUI_", string.Empty);
                listRoomFile.Add(deviceName);
            }
            return null;
            return true;
        }
        #endregion
@@ -169,6 +190,20 @@
            Shared.IO.FileUtils.WriteFileByBytes(fullName, byteData);
        }
        /// <summary>
        /// 添加楼层对象到缓存
        /// </summary>
        /// <param name="dic">楼层</param>
        public void AddShardFile(Dictionary<string, string> dic)
        {
            var data = Newtonsoft.Json.JsonConvert.SerializeObject(dic);
            var byteData = System.Text.Encoding.UTF8.GetBytes(data);
            string fullName = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory, DirNameResourse.ShardFloorFile);
            //写入内容
            Shared.IO.FileUtils.WriteFileByBytes(fullName, byteData);
        }
        #endregion
        #region ■ 删除分享文件_______________________
@@ -191,6 +226,7 @@
        /// </summary>
        public void ClearShardDirectory()
        {
            this.dicShardDeviceFile.Clear();
            //创建文件夹
            string strDir = System.IO.Path.Combine(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory);
            Global.CreateEmptyDirectory(strDir, true);
@@ -212,7 +248,7 @@
            }
            //获取主人分享给成员的文件列表
            var infoPra = new { DistributedMark = Config.Instance.Guid, HouseDistributedMark = Common.Config.Instance.Home.Id , IsOtherAccountControl = Common.Config.Instance.isAdministrator };
            var infoPra = new { DistributedMark = Config.Instance.Guid, HouseDistributedMark = Common.Config.Instance.Home.Id, IsOtherAccountControl = Common.Config.Instance.Home.IsOthreShare };
            var listNotShow = new List<string>() { "NotSetAgain" };
            var result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeDataShare/GetShareDataBySubAccount", false, infoPra, listNotShow);
            if (string.IsNullOrEmpty(result) == true)
@@ -249,11 +285,9 @@
            //从云端获取下来文件
            if (listAddMark.Count > 0)
            {
                //强制指定文本附加信息:共享数据同步中
                string msg = Language.StringByID(R.MyInternationalizationString.uShardDataIsSynchronizing);
                //开启进度条
                ProgressBar.Show(msg);
                ProgressBar.SetAppendText(msg);
                //开启进度条 共享数据同步中
                ProgressFormBar.Current.Start();
                ProgressFormBar.Current.SetMsg(Language.StringByID(R.MyInternationalizationString.uShardDataIsSynchronizing));
                //将分享的数据存入本地(获取的是本地没有的)
                this.ClearShardDirectory();
@@ -261,19 +295,21 @@
                if (listDbFile == null)
                {
                    //关闭
                    ProgressBar.Close();
                    ProgressFormBar.Current.Close();
                    return false;
                }
                //生成文件
                foreach (string fileName in listDbFile)
                {
                    var data = this.GetShardFileContent(fileName);
                    Global.WriteFileByBytesByHomeId(fileName, data);
                    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);
                        Config.Instance.Home.AddRoomId(fileName.Replace("Room_", string.Empty).Replace(".json", string.Empty));
                    }
                }
                //清空共享文件夹
@@ -297,11 +333,9 @@
                //只有成员才有这个概念
                return true;
            }
            //强制指定文本附加信息:共享数据同步中
            string msg = Language.StringByID(R.MyInternationalizationString.uShardDataIsSynchronizing);
            //开启进度条
            ProgressBar.Show(msg);
            ProgressBar.SetAppendText(msg);
            //开启进度条  共享数据同步中
            ProgressFormBar.Current.Start();
            ProgressFormBar.Current.SetMsg(Language.StringByID(R.MyInternationalizationString.uShardDataIsSynchronizing));
            if (dicUpdateTime == null)
            {
@@ -314,13 +348,13 @@
            {
                listShardFile = new HashSet<string>();
                //获取主人分享给成员的文件列表
                var infoPra = new { DistributedMark = Config.Instance.Guid, HouseDistributedMark = Common.Config.Instance.Home.Id, IsOtherAccountControl = Common.Config.Instance.isAdministrator };
                var infoPra = new { DistributedMark = Config.Instance.Guid, HouseDistributedMark = Common.Config.Instance.Home.Id, IsOtherAccountControl = Common.Config.Instance.Home.IsOthreShare };
                var listNotShow = new List<string>() { "NotSetAgain" };
                var result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeDataShare/GetShareDataBySubAccount", false, infoPra, listNotShow);
                if (string.IsNullOrEmpty(result) == true)
                {
                    //关闭
                    ProgressBar.Close();
                    ProgressFormBar.Current.Close();
                    return false;
                }
                var listShardData = Newtonsoft.Json.JsonConvert.DeserializeObject<List<GetShardInfoResult>>(result);
@@ -331,17 +365,30 @@
                }
            }
            //清空楼层数据
            Common.Config.Instance.Home.FloorDics.Clear();
            //然后检测本地的文件
            var listLocalFile = Global.FileListByHomeId();
            foreach (string fileName in listLocalFile)
            {
                if (fileName == DirNameResourse.ShardFloorFile)
                {
                    //楼层文件
                    var varData = Global.ReadFileByHomeId(fileName);
                    var dicFloor = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(Encoding.UTF8.GetString(varData));
                    Common.Config.Instance.Home.FloorDics = dicFloor;
                    //暂时不保存,留在最后面才保存
                    Global.DeleteFilebyHomeId(fileName);
                }
                if (listShardFile.Contains(fileName) == true)
                {
                    //本地的这个文件还分享着,没有问题
                    continue;
                }
                //检测本地设备文件,是否存在已经取消了共享了的
                if (fileName.StartsWith(Common.LocalDevice.deviceFirstName) == true)
                if (fileName.StartsWith("Device_") == true)
                {
                    //删除掉这个设备文件
                    Global.DeleteFilebyHomeId(fileName);
@@ -361,10 +408,8 @@
                    //删除掉这个房间文件
                    Global.DeleteFilebyHomeId(fileName);
                    dicUpdateTime.Remove(fileName);
                    if (Config.Instance.Home.RoomFilePathList.Contains(fileName) == true)
                    {
                        Config.Instance.Home.RemoveRoomListFilePath(fileName);
                    }
                    Config.Instance.Home.RemoveRoomId(nowRoom.Id);
                }
                //检测本地场景文件,是否存在已经取消了共享了的
                else if (fileName.StartsWith("Scene_") == true)
@@ -381,12 +426,16 @@
                    dicUpdateTime.Remove(fileName);
                }
            }
            //保存楼层数据
            Common.Config.Instance.Home.Save(false);
            //网关文件非合法性是刷新设备列表的函数里面实现
            //保存全部分享文件的更新日期
            this.SaveAllShardFileAgoUpdateTime(dicUpdateTime);
            //关闭
            ProgressBar.Close();
            ProgressFormBar.Current.Close();
            return true;
        }
@@ -402,7 +451,7 @@
        private Dictionary<string, string> GetAllShardFileAgoUpdateTime()
        {
            var dicTime = new Dictionary<string, string>();
            var data = Global.ReadFileByDirectory(DirNameResourse.LocalMemoryDirectory, DirNameResourse.ShardFileUpdateFile);
            var data = Global.ReadFileByDirectory(DirNameResourse.LocalMemoryDirectory, DirNameResourse.ShardFileUpdateTimeFile);
            if (data == null)
            {
                //目标文件不存在
@@ -420,7 +469,256 @@
        {
            var data = Newtonsoft.Json.JsonConvert.SerializeObject(dicTime);
            var byteData = System.Text.Encoding.UTF8.GetBytes(data);
            Global.WriteFileToDirectoryByBytes(DirNameResourse.LocalMemoryDirectory, DirNameResourse.ShardFileUpdateFile, byteData);
            Global.WriteFileToDirectoryByBytes(DirNameResourse.LocalMemoryDirectory, DirNameResourse.ShardFileUpdateTimeFile, byteData);
        }
        #endregion
        //----------------------------------分割线(数据预备)-------------------------------------------------
        #region ■ 数据预备___________________________
        /// <summary>
        /// 获取成员共享列表然后保存到本地(用完之后最好调用清空 ClearShardDirectory函数清空)
        /// </summary>
        /// <param name="memberShardInfo">
        /// <para>成员的分享数据</para>
        /// <para>如果不知道这是什么东西,就New一个,然后缓存起来,调用其他函数都需要这个东西</para>
        /// <para>New的时候记得对SubAccountDistributedMark赋值,它是成员列表接口返回的SubAccountDistributedMark</para>
        /// </param>
        /// <returns></returns>
        public async Task<bool> GetMemberShardContentListAndSetToLocation(MemberShardInfoData memberShardInfo)
        {
            if (memberShardInfo.Refresh == false)
            {
                //从本地获取成员的分享列表
                this.GetMemberShardContentListFromLocal(memberShardInfo);
                return true;
            }
            memberShardInfo.Refresh = false;
            //正在获取分享数据
            ProgressFormBar.Current.Start();
            ProgressFormBar.Current.SetMsg(Language.StringByID(R.MyInternationalizationString.uShardContentGetting));
            var infoPra = new
            {
                DistributedMark = memberShardInfo.SubAccountDistributedMark,
                HouseDistributedMark = Shared.Common.Config.Instance.HomeId,
                IsOtherAccountControl = Common.Config.Instance.Home.IsOthreShare
            };
            var result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeDataShare/GetShareDataBySubAccount", false, infoPra);
            if (result == null)
            {
                //关闭进度条
                ProgressFormBar.Current.Close();
                return false;
            }
            var listData = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ReceiveShardInfoResult>>(result);
            //先清空共享文件夹
            this.ClearShardDirectory();
            var listMark = new List<string>();
            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)
            {
                //关闭进度条
                ProgressFormBar.Current.Close();
                return false;
            }
            //从本地获取成员的分享列表
            this.GetMemberShardContentListFromLocal(memberShardInfo);
            //关闭进度条
            ProgressFormBar.Current.Close();
            return true;
        }
        /// <summary>
        /// 从本地获取成员的分享列表
        /// </summary>
        /// <param name="memberShardInfo">成员的分享数据的缓存(调用这个函数会刷新这个变量的信息)</param>
        private void GetMemberShardContentListFromLocal(MemberShardInfoData memberShardInfo)
        {
            memberShardInfo.dicShardRoom = new Dictionary<string, Common.Room>();
            this.dicShardDeviceFile.Clear();
            //keys:主键  value:文件名
            var dicDeviceFile = new Dictionary<string, string>();
            //keys:场景id  value:文件名
            var dicSceneFile = new Dictionary<int, string>();
            var listFile = this.GetLocalAllShardFile();
            //先初始化房间
            foreach (string fileName in listFile)
            {
                try
                {
                    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<Common.Room>(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<Dictionary<string, string>>(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;
                        //设备文件
                        dicDeviceFile[mainKeys] = fileName;
                    }
                    else if (fileName.StartsWith("Scene_") == true)
                    {
                        //场景文件
                        dicSceneFile[(Convert.ToInt32(fileName.Replace("Scene_", string.Empty).Replace(".json", string.Empty)))] = fileName;
                    }
                }
                catch (Exception ex) { HdlLogLogic.Current.WriteLog(ex); }
            }
            //检查设备的匹配情况
            foreach (var tempRoom in memberShardInfo.dicShardRoom.Values)
            {
                //检查设备
                for (int i = 0; i < tempRoom.ListDevice.Count; i++)
                {
                    string deviceKeys = tempRoom.ListDevice[i];
                    if (dicDeviceFile.ContainsKey(deviceKeys) == false)
                    {
                        //移除掉这个不对劲的路径
                        tempRoom.ListDevice.RemoveAt(i);
                        i--;
                        continue;
                    }
                    //这个设备文件匹配得到房间
                    dicDeviceFile.Remove(deviceKeys);
                }
                //检查场景
                for (int i = 0; i < tempRoom.ListSceneId.Count; i++)
                {
                    int intId = tempRoom.ListSceneId[i];
                    if (dicSceneFile.ContainsKey(intId) == false)
                    {
                        //移除掉这个不对劲的路径
                        tempRoom.ListSceneId.RemoveAt(i);
                        i--;
                        continue;
                    }
                    var byteData = this.GetShardFileContent(dicSceneFile[intId]);
                    //这个场景文件匹配得到房间
                    dicSceneFile.Remove(intId);
                    if (byteData == null)
                    {
                        //移除掉这个不对劲的路径
                        tempRoom.ListSceneId.RemoveAt(i);
                        i--;
                        continue;
                    }
                    string valueData = System.Text.Encoding.UTF8.GetString(byteData);
                    var tempUi = Newtonsoft.Json.JsonConvert.DeserializeObject<Common.SceneUI>(valueData);
                    //获取场景里面的全部目标(2019.11.05追加操作,有可能那个设备是由场景嵌套来的,所以它有可能不属于任何房间)
                    foreach (var data in tempUi.AdjustTargetList)
                    {
                        //设备
                        if (data.Type == 0)
                        {
                            string mainkey = LocalDevice.Current.GetDeviceMainKeys(data.DeviceAddr, data.Epoint);
                            if (dicShardDeviceFile.ContainsKey(mainkey) == true )
                            {
                                //这个设备文件匹配得到
                                dicDeviceFile.Remove(mainkey);
                            }
                        }
                        if (data.Type == 1)
                        {
                            //这个场景文件匹配得到
                            dicSceneFile.Remove(data.ElseScenesId);
                        }
                    }
                }
            }
            //如果存在匹配不上的文件
            if (dicDeviceFile.Count != 0 || dicSceneFile.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 deviceKeys in dicDeviceFile.Keys)
                {
                    roomTemp.ListDevice.Add(deviceKeys);
                }
                //还原场景对象
                foreach (int intId in dicSceneFile.Keys)
                {
                    roomTemp.ListSceneId.Add(intId);
                }
            }
        }
        #endregion
        #region ■ 获取设备文件名_____________________
        /// <summary>
        /// 获取设备文件名,不存在时,返回空字符串(仅限分享了的设备)
        /// </summary>
        /// <param name="deviceKeys">设备主键</param>
        /// <returns></returns>
        public string GetShardDeviceFileName(string deviceKeys)
        {
            if (this.dicShardDeviceFile.ContainsKey(deviceKeys) == true)
            {
                return this.dicShardDeviceFile[deviceKeys];
            }
            return string.Empty;
        }
        #endregion
@@ -435,10 +733,16 @@
        /// <param name="memberShardInfo">成员的分享数据</param>
        /// <param name="nowRoom">当前的房间对象</param>
        /// <param name="listDevice">选择上传的设备</param>
        /// <param name="listScene">选择上传的场景</param>
        /// <param name="listScene">选择上传的场景(不要获取它里面的绑定列表)</param>
        /// <param name="BarMaxValue">进度条的最大值,如果不为-1,则内部不会自动弹出进度条</param>
        /// <param name="listCheckFile">文件重复上传检测</param>
        public async Task<bool> DoUploadSharedContent(MemberShardInfoData memberShardInfo, Common.Room nowRoom,
            List<CommonDevice> listDevice, List<Common.SceneUI> listScene)
            List<CommonDevice> listDevice, List<Common.SceneUI> listScene, int BarMaxValue = -1, HashSet<string> listCheckFile = null)
        {
            if (listDevice.Count == 0 && listScene.Count == 0)
            {
                return true;
            }
            var listCheck = new HashSet<string>();
            //获取场景里面嵌套的子设备和子场景
@@ -450,68 +754,147 @@
                this.GetSceneDeviceList(SceneTemp, listCheck, listChirdScene, listChirdDevice);
            }
            //这个也是备份
            int BackgroundImageType = 0;
            string BackgroundImage = string.Empty;
            if (memberShardInfo.dicShardRoom.ContainsKey(nowRoom.FileName) == true)
            {
                BackgroundImageType = memberShardInfo.dicShardRoom[nowRoom.FileName].BackgroundImageType;
                BackgroundImage = memberShardInfo.dicShardRoom[nowRoom.FileName].BackgroundImage;
            }
            //防止出现错误,暂时保存两个列表(虽然没那么麻烦,不过既然已经这样写了就这样了)
            var dicBackDevice = new Dictionary<string, List<string>>();
            var dicBackScene = new Dictionary<string, List<string>>();
            var dicBackScene = new Dictionary<string, List<int>>();
            //临时备份房间设备列表
            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);
            var listDelPic = new List<string>();
            var listFile = this.GetUploadListFile(memberShardInfo, nowRoom, listDevice, listScene, listChirdDevice, listChirdScene, listDelPic);
            //打开进度条
            ProgressBar.Show();
            //设置最大值
            ProgressBar.SetMaxValue(listFile.Count);
            //不允许按系统的返回键
            Shared.Common.CommonPage.BackKeyCanClick = false;
            UserCenterResourse.AccountOption.AppCanSignout = false;
            if (BarMaxValue == -1)
            {
                //打开进度条
                ProgressBar.Show();
                //设置最大值
                ProgressBar.SetMaxValue(listFile.Count);
            }
            else
            {
                //设置最大值
                ProgressBar.SetMaxValue(BarMaxValue);
            }
            //上传分享
            var result = await this.DoUploadShardContent(memberShardInfo, nowRoom, listFile);
            //关闭进度条
            ProgressBar.Close();
            var result = await this.DoUploadShardContent(memberShardInfo, listFile, listCheckFile);
            if (result == true)
            {
                //删除指定自定义图片
                result = await this.DoDeleteSharedContent(memberShardInfo, listDelPic);
            }
            if (BarMaxValue == -1)
            {
                //关闭进度条
                ProgressBar.Close();
            }
            //允许按系统的返回键
            Shared.Common.CommonPage.BackKeyCanClick = true;
            UserCenterResourse.AccountOption.AppCanSignout = true;
            if (result == false)
            {
                //恢复原数据
                if (memberShardInfo.TempRoom == null)
                {
                    memberShardInfo.dicShardRoom[nowRoom.FileName].BackgroundImageType = BackgroundImageType;
                    memberShardInfo.dicShardRoom[nowRoom.FileName].BackgroundImage = BackgroundImage;
                }
                this.RecoverRoomDevicelistTemporary(memberShardInfo, dicBackDevice, dicBackScene, listFile);
                return false;
            }
            else
            {
                //覆盖数据
                if (memberShardInfo.TempRoom != null)
                {
                    memberShardInfo.dicShardRoom[nowRoom.FileName] = memberShardInfo.TempRoom;
                }
            }
            memberShardInfo.TempRoom = null;
            return true;
            return result;
        }
        /// <summary>
        /// 获取上传的文件名
        /// </summary>
        /// <param name="roomTemp">需要上传到云端的房间对象</param>
        /// <param name="listDevice">分享的设备列表</param>
        /// <param name="listScene">分享的场景列表</param>
        /// <param name="memberShardInfo">成员的分享数据</param>
        /// <param name="nowRoom">需要上传到云端的房间对象(注意,这个房间是主人的房间对象,而不是虚拟的)</param>
        /// <param name="listDevice">分享的设备列表(注意,这个东西是主人的)</param>
        /// <param name="listScene">分享的场景列表(注意,这个东西是主人的)</param>
        /// <param name="listChirdDevice">场景里面递归获取的设备</param>
        /// <param name="listChirdScene">场景里面递归获取的场景</param>
        /// <param name="listDelPic">需要删除的图片</param>
        /// <returns></returns>
        private List<string> GetUploadListFile(ref Common.Room roomTemp, List<CommonDevice> listDevice, List<Common.SceneUI> listScene,
            List<CommonDevice> listChirdDevice, List<Common.SceneUI> listChirdScene)
        private List<string> GetUploadListFile(MemberShardInfoData memberShardInfo, Common.Room nowRoom, List<CommonDevice> listDevice, List<Common.SceneUI> listScene,
            List<CommonDevice> listChirdDevice, List<Common.SceneUI> listChirdScene, List<string> listDelPic)
        {
            var listFile = new List<string>();
            var listOtaCheck = new List<string>();
            Common.Room roomTemp = null;
            if (memberShardInfo.dicShardRoom.ContainsKey(nowRoom.FileName) == false)
            {
                //克隆一个对象
                roomTemp = HdlRoomLogic.Current.CloneRoomClass(nowRoom);
                memberShardInfo.TempRoom = roomTemp;
                //新分享的房间,如果图片是自定义的,并且这个图片是存在的,则上传图片
                if (roomTemp.BackgroundImageType != 0 && Common.Global.IsExistsByHomeId(roomTemp.BackgroundImage) == true)
                {
                    //自定义的图片,它存在于本地,但是它是全路径
                    listFile.Add(roomTemp.BackgroundImage);
                    this.AddShardFile(roomTemp.BackgroundImage);
                }
            }
            else
            {
                roomTemp = memberShardInfo.dicShardRoom[nowRoom.FileName];
                //如果云端分享的房间的图片和主人的不一样的时候
                if (roomTemp.BackgroundImage != nowRoom.BackgroundImage)
                {
                    if (roomTemp.BackgroundImageType != 0)
                    {
                        //删除自定义图片
                        listDelPic.Add(roomTemp.BackgroundImage);
                    }
                    if (nowRoom.BackgroundImageType != 0 && Common.Global.IsExistsByHomeId(nowRoom.BackgroundImage) == true)
                    {
                        //自定义的图片,它存在于本地,但是它是全路径
                        listFile.Add(nowRoom.BackgroundImage);
                        this.AddShardFile(nowRoom.BackgroundImage);
                    }
                    //变更图片设置
                    roomTemp.BackgroundImageType = nowRoom.BackgroundImageType;
                    roomTemp.BackgroundImage = nowRoom.BackgroundImage;
                }
            }
            foreach (var device in listDevice)
            {
                //设备
                listFile.Add(device.FilePath);
                HdlShardLogic.Current.AddShardFile(device.FilePath);
                this.AddShardFile(device.FilePath);
                //设备的UI
                var deviceUi = $"DeviceUI_{device.FilePath}";
                if (roomTemp.DeviceUIFilePathList.Contains(deviceUi) == false)
                //加点缓存
                string mainKeys = LocalDevice.Current.GetDeviceMainKeys(device);
                this.dicShardDeviceFile[mainKeys] = device.FilePath;
                if (roomTemp.ListDevice.Contains(mainKeys) == false)
                {
                    roomTemp.DeviceUIFilePathList.Add(deviceUi);
                    roomTemp.ListDevice.Add(mainKeys);
                }
            }
            //递归获取的设备不需要加入到房间
@@ -519,44 +902,62 @@
            {
                //设备
                listFile.Add(device.FilePath);
                HdlShardLogic.Current.AddShardFile(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)
                if (secene.IconPathType != 0 && Common.Global.IsExistsByHomeId(secene.IconPath) == true)
                {
                    roomTemp.SceneUIFilePathList.Add(secene.FileName);
                    //自定义的图片,它存在于本地
                    listFile.Add(secene.IconPath);
                    this.AddShardFile(secene.IconPath);
                }
                listFile.Add(secene.FileName);
                this.AddShardFile(secene);
                if (roomTemp.ListSceneId.Contains(secene.Id) == false)
                {
                    roomTemp.ListSceneId.Add(secene.Id);
                }
            }
            //递归获取的场景不需要加入到房间
            foreach (var secene in listChirdScene)
            {
                listFile.Add(secene.FileName);
                HdlShardLogic.Current.AddShardFile(secene);
                this.AddShardFile(secene);
            }
            //房间文件也给过去
            listFile.Add(roomTemp.FileName);
            HdlShardLogic.Current.AddShardFile(roomTemp);
            this.AddShardFile(roomTemp);
            //反正楼层文件很小,一起给过去吧
            if (roomTemp.FloorId != string.Empty)
            {
                memberShardInfo.dicShardFloor[roomTemp.FloorId] = HdlResidenceLogic.Current.GetFloorNameById(roomTemp.FloorId);
            }
            this.AddShardFile(memberShardInfo.dicShardFloor);
            listFile.Add(DirNameResourse.ShardFloorFile);
            return listFile;
        }
        /// <summary>
        /// 从网关获取场景的目标设备列表
        /// 获取场景的目标设备列表(这个不能从分享数据中获取)
        /// </summary>
        /// <param name="scene">场景</param>
        /// <param name="listCheck">重复检测用</param>
        /// <param name="listSceneUI">添加分享的场景列表</param>
        /// <param name="listDevice">添加分享的设备列表</param>
        /// <returns></returns>
        private void GetSceneDeviceList(Common.SceneUI scene, HashSet<string> listCheck, List<Common.SceneUI> listSceneUI, List<CommonDevice> listDevice)
        public void GetSceneDeviceList(Common.SceneUI scene, HashSet<string> listCheck, List<Common.SceneUI> listSceneUI, List<CommonDevice> listDevice)
        {
            foreach (var data in scene.AddSceneMemberDataList)
            foreach (var data in scene.AdjustTargetList)
            {
                //设备
                if (data.Type == 0)
@@ -587,7 +988,7 @@
                    listCheck.Add(mainKeys);
                    //获取场景对象
                    var sceneUi = Room.CurrentRoom.GetSceneUIBySceneId(data.ElseScenesId);
                    var sceneUi = HdlSceneLogic.Current.GetSceneUIBySceneId(data.ElseScenesId);
                    if (sceneUi != null)
                    {
                        listSceneUI.Add(sceneUi);
@@ -604,57 +1005,205 @@
        /// 上传分享(返回云端分享文件的主键:DistributedMark)
        /// </summary>
        /// <param name="memberShardInfo">成员的分享数据</param>
        /// <param name="nowRoom">当前的房间对象</param>
        /// <param name="listFile">上传的文件名</param>
        /// <param name="listCheckFile">重复文件上传检测</param>
        /// <returns></returns>
        private async Task<bool> DoUploadShardContent(MemberShardInfoData memberShardInfo, Common.Room nowRoom, List<string> listFile)
        private async Task<bool> DoUploadShardContent(MemberShardInfoData memberShardInfo, List<string> listFile, HashSet<string> listCheckFile)
        {
            var dicKeys = new Dictionary<string, string>();
            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)
                if (listCheckFile != null)
                {
                    var result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeDataShare/AddShareData", false, info);
                    if (string.IsNullOrEmpty(result) == true)
                    if (listCheckFile.Contains(fileName) == true)
                    {
                        //重复文件不再上传
                        continue;
                    }
                    listCheckFile.Add(fileName);
                }
                if (fileName.EndsWith(".png") == true)
                {
                    //上传图片
                    var result = this.UpLoadBigBackupFileToDB(memberShardInfo, fileName);
                    if (result == null)
                    {
                        return false;
                    }
                    //这里有点特殊,接口是直接返回主键回来的,而不是Jsoin
                    dicKeys[fileName] = result;
                }
                else
                {
                    info.DistributedMark = memberShardInfo.dicAllShardKeys[fileName];
                    var result = await UserCenterLogic.GetResultStatuByRequestHttps("ZigbeeDataShare/EditShareData", false, info);
                    if (result == false)
                    var info = new UploadShardContent();
                    info.SubAccountDistributedMark = memberShardInfo.SubAccountDistributedMark;
                    info.ShareName = fileName;
                    info.ShareDataBytes = HdlShardLogic.Current.GetShardFileContent(fileName);
                    //追加共享
                    if (memberShardInfo.dicAllShardKeys.ContainsKey(fileName) == false)
                    {
                        return false;
                        var result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeDataShare/AddShareData", false, info);
                        if (result == null)
                        {
                            return false;
                        }
                        //这里有点特殊,接口是直接返回主键回来的,而不是Jsoin
                        dicKeys[fileName] = result;
                    }
                    dicKeys[fileName] = info.DistributedMark;
                    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;
        }
        /// <summary>
        /// 上传图片文件到云端
        /// </summary>
        /// <param name="fullDir">文件夹的全路径</param>
        /// <param name="listPicFile">图片文件列表</param>
        /// <returns></returns>
        private string UpLoadBigBackupFileToDB(MemberShardInfoData memberShardInfo, string fileName)
        {
            string fullName = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadShardDirectory, fileName);
            if (System.IO.File.Exists(fullName) == false)
            {
                return null;
            }
            var nvc = new NameValueCollection();
            nvc.Add("ShareName", fileName);
            nvc.Add("HouseDistributedMark", Common.Config.Instance.Home.Id);
            nvc.Add("SubAccountDistributedMark", memberShardInfo.SubAccountDistributedMark);
            nvc.Add("ShareDataBytes", Convert.ToBase64String(this.GetShardFileContent(fileName)));
            //追加共享
            if (memberShardInfo.dicAllShardKeys.ContainsKey(fileName) == false)
            {
                //这里有点特殊,接口是直接返回主键回来的,而不是Jsoin
                var result = this.DoUpLoadBigBackupFileToDB("ZigbeeDataShare/AddShareData", fullName, nvc);
                return result;
            }
            else
            {
                nvc.Add("DistributedMark", memberShardInfo.dicAllShardKeys[fileName]);
                var result = this.DoUpLoadBigBackupFileToDB("ZigbeeDataShare/EditShareData", fullName, nvc);
                if (result == null)
                {
                    return null;
                }
                return memberShardInfo.dicAllShardKeys[fileName];
            }
        }
        /// <summary>
        /// 执行上传大文件
        /// </summary>
        /// <param name="RequestName">请求接口</param>
        /// <param name="fullFileName">文件名字(含路径)</param>
        /// <param name="nvc"></param>
        /// <returns></returns>
        private string DoUpLoadBigBackupFileToDB(string RequestName, string fullFileName, NameValueCollection nvc)
        {
            string paramName = "file";
            string contentType = "application/octet-stream";
            string requestUrl = $"{CommonPage.RequestHttpsHost}/{RequestName}";
            string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
            byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
            var wr = (HttpWebRequest)WebRequest.Create(requestUrl);
            wr.ContentType = "multipart/form-data; boundary=" + boundary;
            wr.Method = "POST";
            wr.KeepAlive = true;
            wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
            wr.Headers.Add(HttpRequestHeader.Authorization, Config.Instance.Token);
            var rs = wr.GetRequestStream();
            string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
            foreach (string key in nvc.Keys)
            {
                rs.Write(boundarybytes, 0, boundarybytes.Length);
                string formitem = string.Format(formdataTemplate, key, nvc[key]);
                byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                rs.Write(formitembytes, 0, formitembytes.Length);
            }
            rs.Write(boundarybytes, 0, boundarybytes.Length);
            string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
            string header = string.Format(headerTemplate, paramName, fullFileName, contentType);
            byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
            rs.Write(headerbytes, 0, headerbytes.Length);
            var fileStream = new FileStream(fullFileName, FileMode.Open, FileAccess.Read);
            byte[] buffer = new byte[4096];
            int bytesRead = 0;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                rs.Write(buffer, 0, bytesRead);
            }
            fileStream.Close();
            byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
            rs.Write(trailer, 0, trailer.Length);
            rs.Close();
            WebResponse wresp = null;
            try
            {
                wresp = wr.GetResponse();
                Stream stream2 = wresp.GetResponseStream();
                StreamReader reader2 = new StreamReader(stream2);
                string result = reader2.ReadToEnd();
                var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Shared.Common.ResponseEntity.ResponsePack>(result);
                bool flage = UserCenterLogic.CheckNotEorrorMsg(data, requestUrl);
                if (flage == true)
                {
                    //编辑的时候,这个东西会是null
                    return data.ResponseData == null ? "1" : data.ResponseData.ToString();
                }
                //Log出力
                IMessageCommon.Current.GetMsgByRequestName(RequestName, data, nvc);
                return null;
            }
            catch
            {
                return null;
            }
            finally
            {
                if (wresp != null)
                {
                    wresp.Close();
                    wresp = null;
                }
                wr = null;
            }
        }
        #endregion
@@ -667,15 +1216,15 @@
        /// <param name="dicBackDevice">空的设备备份列表</param>
        /// <param name="dicBackScene">空的场景备份列表</param>
        private void BackupRoomDevicelistTemporary(MemberShardInfoData memberShardInfo, Dictionary<string, List<string>> dicBackDevice,
            Dictionary<string, List<string>> dicBackScene)
            Dictionary<string, List<int>> dicBackScene)
        {
            foreach (var roomKeys in memberShardInfo.dicShardRoom.Keys)
            {
                dicBackDevice[roomKeys] = new List<string>();
                dicBackScene[roomKeys] = new List<string>();
                dicBackScene[roomKeys] = new List<int>();
                dicBackDevice[roomKeys].AddRange(memberShardInfo.dicShardRoom[roomKeys].DeviceUIFilePathList);
                dicBackScene[roomKeys].AddRange(memberShardInfo.dicShardRoom[roomKeys].SceneUIFilePathList);
                dicBackDevice[roomKeys].AddRange(memberShardInfo.dicShardRoom[roomKeys].ListDevice);
                dicBackScene[roomKeys].AddRange(memberShardInfo.dicShardRoom[roomKeys].ListSceneId);
            }
        }
@@ -687,12 +1236,12 @@
        /// <param name="dicBackScene">临时备份的场景备份列表</param>
        /// <param name="listFile">上传的文件名</param>
        private void RecoverRoomDevicelistTemporary(MemberShardInfoData memberShardInfo, Dictionary<string, List<string>> dicBackDevice,
            Dictionary<string, List<string>> dicBackScene, List<string> listFile)
            Dictionary<string, List<int>> dicBackScene, List<string> listFile)
        {
            foreach (string fileName in listFile)
            {
                //生成的文件全部删除,房间文件的话,下面会重新生成
                HdlShardLogic.Current.DeleteShardFile(fileName);
                this.DeleteShardFile(fileName);
            }
            foreach (var roomKeys in memberShardInfo.dicShardRoom.Keys)
@@ -701,14 +1250,14 @@
                {
                    continue;
                }
                memberShardInfo.dicShardRoom[roomKeys].DeviceUIFilePathList.Clear();
                memberShardInfo.dicShardRoom[roomKeys].DeviceUIFilePathList.AddRange(dicBackDevice[roomKeys]);
                memberShardInfo.dicShardRoom[roomKeys].ListDevice.Clear();
                memberShardInfo.dicShardRoom[roomKeys].ListDevice.AddRange(dicBackDevice[roomKeys]);
                memberShardInfo.dicShardRoom[roomKeys].SceneUIFilePathList.Clear();
                memberShardInfo.dicShardRoom[roomKeys].SceneUIFilePathList.AddRange(dicBackScene[roomKeys]);
                memberShardInfo.dicShardRoom[roomKeys].ListSceneId.Clear();
                memberShardInfo.dicShardRoom[roomKeys].ListSceneId.AddRange(dicBackScene[roomKeys]);
                //覆盖房间文件
                HdlShardLogic.Current.AddShardFile(memberShardInfo.dicShardRoom[roomKeys]);
                this.AddShardFile(memberShardInfo.dicShardRoom[roomKeys]);
            }
        }
@@ -732,36 +1281,32 @@
            var roomTemp = memberShardInfo.dicShardRoom[nowRoom.FileName];
            //防止出错,先备份列表
            var listBackDevice = new List<string>();
            listBackDevice.AddRange(roomTemp.DeviceUIFilePathList);
            var listBackScene = new List<string>();
            listBackScene.AddRange(roomTemp.SceneUIFilePathList);
            listBackDevice.AddRange(roomTemp.ListDevice);
            var listBackScene = new List<int>();
            listBackScene.AddRange(roomTemp.ListSceneId);
            var listMark = new List<string>();
            //要删除的文件名字
            var listDeleteFile = new List<string>();
            //这个是只移除缓存的文件名字
            var listDeleteFileEx = new List<string>();
            //云端的指定房间的共享文件列表
            var dicShardFile = memberShardInfo.dicAllMemberShard[nowRoom.FileName];
            //除了要删除的目标外,还分享的数据
            var listHadShard = this.GetAllShardedFileNameFromDictionary(memberShardInfo, nowRoom, listDevice, listSceneUI);
            var listHadShardKeys = this.GetAllShardedKeysFromDictionary(memberShardInfo, nowRoom, listDevice, listSceneUI);
            //先弄设备
            foreach (var device in listDevice)
            {
                string deviceFileName = device.FilePath;
                string mainKeys = LocalDevice.Current.GetDeviceMainKeys(device);
                //移除路径列表
                roomTemp.DeviceUIFilePathList.Remove($"DeviceUI_{device.FilePath}");
                if (listHadShard.Contains(deviceFileName) == true)
                roomTemp.ListDevice.Remove(mainKeys);
                if (listHadShardKeys.Contains(mainKeys) == true)
                {
                    //其他房间分享有这个设备,所以不删除这个设备的根源文件,只是把房间的设备列表路径移除
                    listDeleteFileEx.Add(deviceFileName);
                    //其他场景分享有这个设备,所以不删除这个设备的根源文件,只是把房间的设备列表路径移除
                    continue;
                }
                //设备主键
                if (dicShardFile.Contains(deviceFileName) == true)
                if (memberShardInfo.dicAllShardKeys.ContainsKey(deviceFileName) == true)
                {
                    listMark.Add(memberShardInfo.dicAllShardKeys[deviceFileName]);
                }
@@ -772,47 +1317,90 @@
            foreach (var sceneUI in listSceneUI)
            {
                //移除缓存
                roomTemp.SceneUIFilePathList.Remove(sceneUI.FileName);
                roomTemp.ListSceneId.Remove(sceneUI.Id);
                //其他场景还嵌套着这个场景,所以不删除这个场景的根源文件,只是把房间的场景列表路径移除
                //但是它绑定的设备目标要删除
                if (listHadShard.Contains(sceneUI.FileName) == true)
                if (listHadShardKeys.Contains(sceneUI.Id.ToString()) == true)
                {
                    listDeleteFileEx.Add(sceneUI.FileName);
                    continue;
                }
                else
                //获取要删除的分享主键
                if (memberShardInfo.dicAllShardKeys.ContainsKey(sceneUI.FileName) == true)
                {
                    //获取要删除的分享主键
                    if (dicShardFile.Contains(sceneUI.FileName) == true)
                    listMark.Add(memberShardInfo.dicAllShardKeys[sceneUI.FileName]);
                }
                listDeleteFile.Add(sceneUI.FileName);
                //删除自定义图片,它存在于本地,但是它是全路径
                if (sceneUI.IconPathType != 0)
                {
                    string[] Arry = sceneUI.IconPath.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
                    string sceneFile = Arry[Arry.Length - 1];
                    listDeleteFile.Add(sceneFile);
                    if (memberShardInfo.dicAllShardKeys.ContainsKey(sceneFile) == true)
                    {
                        listMark.Add(memberShardInfo.dicAllShardKeys[sceneUI.FileName]);
                        listMark.Add(memberShardInfo.dicAllShardKeys[sceneFile]);
                    }
                    listDeleteFile.Add(sceneUI.FileName);
                }
                //执行删除嵌套的设备
                var listTemp = new HashSet<string>();
                this.GetSceneBindFileName(sceneUI, ref listTemp);
                foreach (var fileName in listTemp)
                var dicDeviceKeys = new Dictionary<string, string>();
                var listBindScene = new List<SceneUI>();
                this.GetSceneBindListKeys(sceneUI, ref dicDeviceKeys, ref listBindScene);
                //设备的
                foreach (var myKeys in dicDeviceKeys.Keys)
                {
                    if (listHadShard.Contains(fileName) == true)
                    if (listHadShardKeys.Contains(myKeys) == true)
                    {
                        continue;
                    }
                    //获取要删除的分享主键
                    if (dicShardFile.Contains(fileName) == true)
                    string fileName = dicDeviceKeys[myKeys];
                    if (memberShardInfo.dicAllShardKeys.ContainsKey(fileName) == true)
                    {
                        listMark.Add(memberShardInfo.dicAllShardKeys[fileName]);
                    }
                    listDeleteFile.Add(fileName);
                }
                //场景的
                foreach (var seceUi in listBindScene)
                {
                    if (seceUi.IconPathType != 0)
                    {
                        //删除自定义场景图片,它存在于本地,但是它是全路径
                        string[] Arry = seceUi.IconPath.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
                        string sceneFile = Arry[Arry.Length - 1];
                        listDeleteFile.Add(sceneFile);
                        if (memberShardInfo.dicAllShardKeys.ContainsKey(sceneFile) == true)
                        {
                            listMark.Add(memberShardInfo.dicAllShardKeys[sceneFile]);
                        }
                    }
                }
            }
            //如果这个房间的分享设备和场景全部删除的话,把分享房间文件也一起删除
            if (roomTemp.DeviceUIFilePathList.Count == 0 && roomTemp.SceneUIFilePathList.Count == 0)
            if (roomTemp.ListDevice.Count == 0 && roomTemp.ListSceneId.Count == 0)
            {
                listMark.Add(memberShardInfo.dicAllShardKeys[nowRoom.FileName]);
                //房间删除
                if (memberShardInfo.dicAllShardKeys.ContainsKey(nowRoom.FileName) == true)
                {
                    listMark.Add(memberShardInfo.dicAllShardKeys[nowRoom.FileName]);
                }
                listDeleteFile.Add(nowRoom.FileName);
                if (nowRoom.BackgroundImageType != 0)
                {
                    //删除自定义房间图片,它存在于本地,但是它是全路径
                    string[] Arry = nowRoom.BackgroundImage.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
                    string roomFile = Arry[Arry.Length - 1];
                    listDeleteFile.Add(roomFile);
                    if (memberShardInfo.dicAllShardKeys.ContainsKey(roomFile) == true)
                    {
                        listMark.Add(memberShardInfo.dicAllShardKeys[roomFile]);
                    }
                }
            }
            //执行移除分享数据
@@ -820,28 +1408,38 @@
            //同步房间文件
            if (result == true && listDeleteFile.Contains(roomTemp.FileName) == false)
            {
                //执行上传对象
                //执行上传房间对象
                result = await this.DoUploadRoomObject(memberShardInfo, roomTemp);
            }
            if (result == true)
            //同步楼层数据
            if (result == true && listDeleteFile.Contains(roomTemp.FileName) == true)
            {
                foreach (var exFile in listDeleteFileEx)
                int floorCount = 0;
                foreach (var myRoom in memberShardInfo.dicShardRoom.Values)
                {
                    //只移除缓存,不删除云端
                    if (dicShardFile.Contains(exFile) == true)
                    //2020.03.24追加:不能是自身房间
                    if (myRoom.FloorId == roomTemp.FloorId && myRoom.Id != roomTemp.Id)
                    {
                        dicShardFile.Remove(exFile);
                        floorCount++;
                    }
                }
                if (floorCount == 0)
                {
                    //如果该楼层已经删完房间了,则更新楼层
                    memberShardInfo.dicShardFloor.Remove(roomTemp.FloorId);
                    //执行上传对象
                    result = await this.DoUploadFloorObject(memberShardInfo);
                }
            }
            else
            if (result == false)
            {
                //恢复
                roomTemp.DeviceUIFilePathList.Clear();
                roomTemp.DeviceUIFilePathList.AddRange(listBackDevice);
                roomTemp.ListDevice.Clear();
                roomTemp.ListDevice.AddRange(listBackDevice);
                roomTemp.SceneUIFilePathList.Clear();
                roomTemp.SceneUIFilePathList.AddRange(listBackScene);
                roomTemp.ListSceneId.Clear();
                roomTemp.ListSceneId.AddRange(listBackScene);
            }
            return result;
        }
@@ -889,8 +1487,6 @@
            }
            //关闭进度条
            ProgressBar.Close();
            var dicShard = memberShardInfo.dicAllMemberShard[nowRoom.FileName];
            for (int i = 0; i < listDeleteFile.Count; i++)
            {
                string fileName = listDeleteFile[i];
@@ -898,16 +1494,50 @@
                {
                    //最后一个固定可能是房间文件,直接移除整个对象
                    memberShardInfo.dicShardRoom.Remove(fileName);
                    memberShardInfo.dicAllMemberShard.Remove(fileName);
                }
                else
                {
                    //移除指定文件
                    dicShard.Remove(fileName);
                }
                memberShardInfo.dicAllShardKeys.Remove(fileName);
                HdlShardLogic.Current.DeleteShardFile(fileName);
                this.DeleteShardFile(fileName);
            }
            return true;
        }
        /// <summary>
        /// 执行移除分享数据
        /// </summary>
        /// <param name="memberShardInfo">成员的分享内容</param>
        /// <param name="listDelFile">删除的文件</param>
        /// <returns></returns>
        private async Task<bool> DoDeleteSharedContent(MemberShardInfoData memberShardInfo, List<string> listDelFile)
        {
            if (listDelFile.Count == 0)
            {
                return true;
            }
            var info = new DeleteShardInfo();
            foreach (var fileName in listDelFile)
            {
                if (memberShardInfo.dicAllShardKeys.ContainsKey(fileName) == false)
                {
                    //我也不知道为什么会找不到主键
                    continue;
                }
                info.DistributedMark = memberShardInfo.dicAllShardKeys[fileName];
                //执行删除
                var result = await UserCenterLogic.GetResultStatuByRequestHttps("ZigbeeDataShare/DeleteShareData", false, info);
                if (result == false)
                {
                    return false;
                }
            }
            for (int i = 0; i < listDelFile.Count; i++)
            {
                string fileName = listDelFile[i];
                memberShardInfo.dicAllShardKeys.Remove(fileName);
                this.DeleteShardFile(fileName);
            }
            return true;
        }
@@ -924,6 +1554,10 @@
        /// <returns></returns>
        private async Task<bool> DoUploadRoomObject(MemberShardInfoData memberShardInfo, Common.Room upDateRoom)
        {
            if (upDateRoom.Id == "Other")
            {
                return true;
            }
            var info = new EditorShardContent();
            info.DistributedMark = memberShardInfo.dicAllShardKeys[upDateRoom.FileName];
            info.ShareName = upDateRoom.FileName;
@@ -938,7 +1572,37 @@
                return false;
            }
            //将房间对象序列化到缓存
            HdlShardLogic.Current.AddShardFile(upDateRoom);
            this.AddShardFile(upDateRoom);
            return true;
        }
        #endregion
        #region ■ 上传楼层对象_______________________
        /// <summary>
        /// 上传楼层对象
        /// </summary>
        /// <param name="memberShardInfo">成员的共享内容</param>
        /// <returns></returns>
        private async Task<bool> DoUploadFloorObject(MemberShardInfoData memberShardInfo)
        {
            var info = new EditorShardContent();
            info.DistributedMark = memberShardInfo.dicAllShardKeys[DirNameResourse.ShardFloorFile];
            info.ShareName = DirNameResourse.ShardFloorFile;
            info.SubAccountDistributedMark = memberShardInfo.SubAccountDistributedMark;
            var data = Newtonsoft.Json.JsonConvert.SerializeObject(memberShardInfo.dicShardFloor);
            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;
            }
            //将房间对象序列化到缓存
            this.AddShardFile(memberShardInfo.dicShardFloor);
            return true;
        }
@@ -948,104 +1612,144 @@
        #region ■ 移除共享的一般方法_________________
        /// <summary>
        /// 从缓存字典中获取已经分享了的全部设备文件和场景的文件名字
        /// 从缓存字典中获取已经分享了的全部设备主键和场景的ID
        /// </summary>
        /// <param name="memberShardInfo">成员的分享信息</param>
        /// <param name="nowRoom">当前房间</param>
        /// <param name="listDeleteDevice">要删除的设备列表</param>
        /// <param name="listDeleteScene">要删除的场景列表</param>
        /// <returns></returns>
        private HashSet<string> GetAllShardedFileNameFromDictionary(MemberShardInfoData memberShardInfo, Common.Room nowRoom,
        private HashSet<string> GetAllShardedKeysFromDictionary(MemberShardInfoData memberShardInfo, Common.Room nowRoom,
            List<CommonDevice> listDeleteDevice, List<Common.SceneUI> listDeleteScene)
        {
            //获取全部要删除的文件名字
            var listDeleteFile = new HashSet<string>();
            var dicDeleteDeviceFile = new Dictionary<string, string>();
            foreach (var device in listDeleteDevice)
            {
                listDeleteFile.Add(device.FilePath);
                dicDeleteDeviceFile[LocalDevice.Current.GetDeviceMainKeys(device)] = device.FilePath;
            }
            var dicDeleteSceneFile = new Dictionary<int, string>();
            foreach (var scene in listDeleteScene)
            {
                listDeleteFile.Add(scene.FileName);
                dicDeleteSceneFile[scene.Id] = scene.FileName;
            }
            var listShardFile = new HashSet<string>();
            //获取还处于分享状态的文件
            var listShardKeys = new HashSet<string>();
            //获取还处于分享状态的主键
            foreach (var roomTemp in memberShardInfo.dicShardRoom.Values)
            {
                bool flage = roomTemp.FileName == nowRoom.FileName;
                //设备
                foreach (var deviceUi in roomTemp.DeviceUIFilePathList)
                foreach (var deviceKeys in roomTemp.ListDevice)
                {
                    string deviceFile = deviceUi.Replace("DeviceUI_", string.Empty);
                    if (flage == true && listDeleteFile.Contains(deviceFile) == true)
                    if (dicDeleteDeviceFile.ContainsKey(deviceKeys) == true)
                    {
                        //当前房间的要特殊处理,如果是删除目标,则不添加
                        //因为一个回路只能分配一个区域,所以可以直接判断
                        continue;
                    }
                    if (listShardFile.Contains(deviceFile) == false)
                    if (listShardKeys.Contains(deviceKeys) == false)
                    {
                        listShardFile.Add(deviceFile);
                        //这个文件还分享着
                        listShardKeys.Add(deviceKeys);
                    }
                }
                //场景
                foreach (var scene in roomTemp.SceneUIList)
                foreach (var sceneId in roomTemp.ListSceneId)
                {
                    if (roomTemp.SceneUIFilePathList.Contains(scene.FileName) == false)
                    if (roomTemp.FileName == nowRoom.FileName)
                    {
                        //这个场景已经被删除
                        continue;
                    }
                    if (flage == true && listDeleteFile.Contains(scene.FileName) == true)
                    {
                        //当前房间的要特殊处理,如果是删除目标,则不添加
                        continue;
                    }
                    //获取场景里面的全部目标
                    var listTemp = new HashSet<string>();
                    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)
                        //如果循环到了当前房间
                        if (dicDeleteSceneFile.ContainsKey(sceneId) == true)
                        {
                            listShardFile.Add(file);
                            //如果是删除目标,则不添加
                            continue;
                        }
                    }
                    var byteData = this.GetShardFileContent($"Scene_{sceneId}.json");
                    if (byteData == null)
                    {
                        continue;
                    }
                    string valueData = System.Text.Encoding.UTF8.GetString(byteData);
                    var sceneTemp = Newtonsoft.Json.JsonConvert.DeserializeObject<Common.SceneUI>(valueData);
                    //获取场景里面的全部目标
                    var listTempKeys = new HashSet<string>();
                    //从场景对象里面获取全部的绑定目标的主键(这里面的东西必须从分享数据中获取)
                    this.GetSceneBindListKeys(sceneTemp, ref listTempKeys);
                    if (listShardKeys.Contains(sceneId.ToString()) == false)
                    {
                        //场景自身
                        listShardKeys.Add(sceneId.ToString());
                    }
                    foreach (string myKeys2 in listTempKeys)
                    {
                        if (listShardKeys.Contains(myKeys2) == false)
                        {
                            listShardKeys.Add(myKeys2);
                        }
                    }
                }
            }
            return listShardFile;
            return listShardKeys;
        }
        /// <summary>
        /// 从场景对象里面获取全部的绑定目标的文件名字
        /// 从场景对象里面获取全部的绑定目标的主键(这里面的东西必须从分享数据中获取)
        /// </summary>
        /// <param name="scene">场景</param>
        /// <param name="listFile">文件列表(里面存的是设备UI文件和设备文件和场景文件)</param>
        private void GetSceneBindFileName(Common.SceneUI scene, ref HashSet<string> listFile)
        /// <param name="dicDeviceKeys">设备主键列表(里面没有场景),keys:主键,value:文件名</param>
        /// <param name="listBindScene">绑定的场景对象</param>
        private void GetSceneBindListKeys(Common.SceneUI scene, ref Dictionary<string, string> dicDeviceKeys, ref List<SceneUI> listBindScene)
        {
            foreach (var data in scene.AddSceneMemberDataList)
            foreach (var data in scene.AdjustTargetList)
            {
                //设备
                if (data.Type == 0)
                {
                    var device = Common.LocalDevice.Current.GetDevice(data.DeviceAddr, data.Epoint);
                    if (device != null&& listFile.Contains(device.FilePath) == false)
                    string mainkey = LocalDevice.Current.GetDeviceMainKeys(data.DeviceAddr, data.Epoint);
                    if (dicShardDeviceFile.ContainsKey(mainkey) == true && dicDeviceKeys.ContainsKey(mainkey) == false)
                    {
                        listFile.Add(device.FilePath);
                        dicDeviceKeys[mainkey] = dicShardDeviceFile[mainkey];
                    }
                }
                if (data.Type == 1)
                {
                    var sceneTemp = Room.CurrentRoom.GetSceneUIBySceneId(data.ElseScenesId);
                    if (sceneTemp != null && listFile.Contains(sceneTemp.FileName))
                    var byteData = this.GetShardFileContent($"Scene_{data.ElseScenesId}.json");
                    if (byteData != null)
                    {
                        listFile.Add(sceneTemp.FileName);
                        string valueData = System.Text.Encoding.UTF8.GetString(byteData);
                        var sceneTemp = Newtonsoft.Json.JsonConvert.DeserializeObject<Common.SceneUI>(valueData);
                        listBindScene.Add(sceneTemp);
                    }
                }
            }
        }
        /// <summary>
        /// 从场景对象里面获取全部的绑定目标的主键(这里面的东西必须从分享数据中获取)
        /// </summary>
        /// <param name="scene">场景</param>
        /// <param name="listKeys">主键列表(设备和场景)</param>
        private void GetSceneBindListKeys(Common.SceneUI scene, ref HashSet<string> listKeys)
        {
            foreach (var data in scene.AdjustTargetList)
            {
                //设备
                if (data.Type == 0)
                {
                    string mainkey = LocalDevice.Current.GetDeviceMainKeys(data.DeviceAddr, data.Epoint);
                    if (listKeys.Contains(mainkey) == false)
                    {
                        listKeys.Add(mainkey);
                    }
                }
                if (data.Type == 1)
                {
                    if (listKeys.Contains(data.ElseScenesId.ToString()) == false)
                    {
                        listKeys.Add(data.ElseScenesId.ToString());
                    }
                }
            }
@@ -1124,6 +1828,20 @@
            public string SubAccountDistributedMark = string.Empty;
        }
        /// <summary>
        /// 接收分享数据
        /// </summary>
        private class ReceiveShardInfoResult
        {
            /// <summary>
            /// 文件名字
            /// </summary>
            public string ShareName = string.Empty;
            /// <summary>
            /// 主键
            /// </summary>
            public string DistributedMark = string.Empty;
        }
        #endregion
    }