using Shared.Common;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
namespace Shared.Phone.UserCenter
{
///
/// 备份业务的逻辑
///
public class HdlBackupLogic
{
#region ■ 变量声明___________________________
///
/// 备份业务的逻辑
///
private static HdlBackupLogic m_Current = null;
///
/// 备份业务的逻辑
///
public static HdlBackupLogic Current
{
get
{
if (m_Current == null)
{
m_Current = new HdlBackupLogic();
}
return m_Current;
}
}
#endregion
#region ■ 获取备份名字列表___________________
///
/// 从云端获取备份数据的名字列表
///
/// 0:App手动备份 1: App 自动备份 2:网关手动备份 3:网关自动备份
/// 网关的唯一Id,获取网关备份需要
/// 是否获取功能备份
///
public List GetBackupListNameFromDB(int ZigbeeBackupType = 0, string ZigbeeUniqueId = null, bool getOptionBackup = false)
{
//备份名字很少的内存,可以直接一次性全部取完
var pra = new GetBackupListPra();
pra.BackupType = ZigbeeBackupType;
pra.GatewayUniqueId = ZigbeeUniqueId;
pra.PageSetting.Page = 1;
pra.PageSetting.PageSize = 99999;
//获取控制主人账号的Token
pra.LoginAccessToken = UserCenterLogic.GetConnectMainToken();
//访问接口
string result = UserCenterLogic.GetResponseDataByRequestHttps("App/GetHomeDataBackupPagger", true, pra);
if (string.IsNullOrEmpty(result) == true)
{
return null;
}
var data = Newtonsoft.Json.JsonConvert.DeserializeObject(result);
var list = new List();
foreach (var data2 in data.PageData)
{
if (ZigbeeUniqueId != null && data2.GatewayUniqueId != ZigbeeUniqueId)
{
continue;
}
if (getOptionBackup == false && data2.BackupName == DirNameResourse.OptionBackupName)
{
//不获取功能备份
continue;
}
list.Add(data2);
}
return list;
}
///
/// 从云端获取备份的文件,然后存入本地指定的临时文件夹
/// 返回文件夹名字(里面存放着全部的文件),返回null时,代表失败
///
/// BackupClassId
/// 当前获取是否为网关自动备份
/// ZigbeeUniqueId 网关的唯一Id(当IsGatewayBackup=true时,此参数必须提供
///
public string GetBackFileFromDBAndSetToLocation(string BackupClassId, bool IsGatewayAutoBackup = false, string ZigbeeUniqueId = null)
{
//不允许按系统的返回键
Shared.Common.CommonPage.BackKeyCanClick = false;
UserCenterResourse.AccountOption.AppCanSignout = false;
//首先先创建一个临时文件夹,存在文件则清空
string newDir = System.IO.Path.Combine(DirNameResourse.LocalMemoryDirectory, DirNameResourse.DownLoadBackupTempDirectory);
Global.CreateEmptyDirectory(newDir, true);
//获取这个备份下面有多少个文件
List listFile = GetBackFileIDFromDB(BackupClassId, IsGatewayAutoBackup, ZigbeeUniqueId);
if (listFile == null)
{
//关闭进度条
ProgressFormBar.Current.Close();
//允许按系统的返回键
Shared.Common.CommonPage.BackKeyCanClick = true;
UserCenterResourse.AccountOption.AppCanSignout = true;
return null;
}
var pra = new LoadBackInfoPra();
pra.BackupClassId = BackupClassId;
pra.IsGatewayAutoBackup = IsGatewayAutoBackup;
pra.GatewayUniqueId = ZigbeeUniqueId;
//获取控制主人账号的Token
pra.LoginAccessToken = UserCenterLogic.GetConnectMainToken();
//一个个的下载文件
int listFileCount = listFile.Count;
for (int i = 0; i < listFile.Count; i++)
{
string fileName = listFile[i];
//账号已经退出
if (HdlCheckLogic.Current.IsAccountLoginOut() == true)
{
//关闭进度条
ProgressFormBar.Current.Close();
//允许按系统的返回键
Shared.Common.CommonPage.BackKeyCanClick = true;
UserCenterResourse.AccountOption.AppCanSignout = true;
return null;
}
//★设置需要获取的文件名字★
pra.BackupFileName = fileName;
var result = UserCenterLogic.GetByteResponseDataByRequestHttps("App/DownloadSomeDataBackup", true, pra, null, true);
if (result == null)
{
//关闭进度条
ProgressFormBar.Current.Close();
//允许按系统的返回键
Shared.Common.CommonPage.BackKeyCanClick = true;
UserCenterResourse.AccountOption.AppCanSignout = true;
return null;
}
//将输入写入本地的临时文件夹
Global.WriteFileToDirectoryByBytes(newDir, fileName, result);
//设置进度值
ProgressFormBar.Current.SetValue(i + 1, listFileCount);
}
//关闭进度条
ProgressFormBar.Current.Close();
//允许按系统的返回键
Shared.Common.CommonPage.BackKeyCanClick = true;
UserCenterResourse.AccountOption.AppCanSignout = true;
return newDir;
}
///
/// 从云端获取全部的备份文件的名字
///
/// BackupClassId
/// 当前获取是否为网关自动备份
/// ZigbeeUniqueId 网关的唯一Id(当IsGatewayBackup=true时,此参数必须提供
///
private List GetBackFileIDFromDB(string BackupClassId, bool IsGatewayAutoBackup, string ZigbeeUniqueId)
{
var pra = new LoadBackInfoPra();
pra.BackupClassId = BackupClassId;
pra.PageSetting.PageSize = 999999;
pra.PageSetting.Page = 1;
pra.IsGatewayAutoBackup = IsGatewayAutoBackup;
pra.GatewayUniqueId = ZigbeeUniqueId;
//获取控制主人账号的Token
pra.LoginAccessToken = UserCenterLogic.GetConnectMainToken();
//首先先获取云端有什么文件
string result = UserCenterLogic.GetResponseDataByRequestHttps("App/GetHomeDataBackupUploadListPagger", true, pra);
if (string.IsNullOrEmpty(result) == true)
{
return null;
}
var fileListData = Newtonsoft.Json.JsonConvert.DeserializeObject(result);
//获取文件名字
List listFileName = new List();
foreach (LoadBackupFileNameInfo file in fileListData.PageData)
{
listFileName.Add(file.BackupFileName);
}
return listFileName;
}
#endregion
#region ■ 创建备份___________________________
///
/// 创建一个备份名字(成功时返回备份的主键ID,失败时返回null)
///
/// 备份名字
/// 手动备份类型(0:App手动备份,2:网关手动备份)
/// 网关的唯一Id,当ManualBackupType=2时,此值不能为空!
///
public string CreatNewBackupNameToDB(string backupName, int ManualBackupType = 0, string ZigbeeUniqueId = null)
{
var pra = new AddBackUpNamePra();
pra.BackupName = backupName;
pra.ManualBackupType = ManualBackupType;
pra.GatewayUniqueId = ZigbeeUniqueId;
//获取控制主人账号的Token
pra.LoginAccessToken = UserCenterLogic.GetConnectMainToken();
var result = UserCenterLogic.GetResponseDataByRequestHttps("App/AddHomeAppGatewayName", true, pra);
if (string.IsNullOrEmpty(result) == true)
{
return null;
}
var data = Newtonsoft.Json.JsonConvert.DeserializeObject(result);
return data.BackupClassId;
}
#endregion
#region ■ 上传备份___________________________
///
/// 上传本地所有文件到云端(函数内部有进度条)
///
/// 备份主键ID
/// 手动备份类型(0:App手动备份,2:网关手动备份)
/// 指定上传的是哪个文件夹的文件(全路径),不指定时,上传的是本地路径下的文件
/// 是否设置显示进度条
///
public bool UpLoadBackupFileToDB(string BackupClassId, int ManualBackupType = 0, string upPath = "", bool showBar = true)
{
List listAllFile = null;
//文件夹的全路径
string fullDir = string.Empty;
if (upPath == string.Empty)
{
//获取本地文件
listAllFile = Global.FileListByHomeId();
fullDir = UserCenterLogic.CombinePath();
}
else
{
listAllFile = HdlAutoBackupLogic.GetFileFromDirectory(upPath);
fullDir = upPath;
}
if (listAllFile.Count == 0)
{
return true;
}
//普通文件,可以一次性上传多个的
List listNormalFile = new List();
//图片文件,这个东西很大,需要独立出来
List listPicFile = new List();
foreach (string fileName in listAllFile)
{
if (fileName.EndsWith(".png") == true)
{
//图片文件
listPicFile.Add(fileName);
continue;
}
listNormalFile.Add(fileName);
}
//开启进度条
int listFileCount = listAllFile.Count;
if (showBar == true)
{
//开启进度条 正在上传备份文件
ProgressFormBar.Current.Start();
ProgressFormBar.Current.SetMsg(Language.StringByID(R.MyInternationalizationString.uBackupFileUploading));
}
//不允许按系统的返回键
Shared.Common.CommonPage.BackKeyCanClick = false;
UserCenterResourse.AccountOption.AppCanSignout = false;
//你说为什么这里不分一个函数出来(理论上是分函数出来的)
//是因为如果分函数的话,会出现双重异步,导致主线程的进度条的百分比永远定死0%
for (int i = 0; i < listNormalFile.Count; i++)
{
string file = listNormalFile[i];
//账号已经退出
if (HdlCheckLogic.Current.IsAccountLoginOut() == true)
{
//关闭进度条
ProgressFormBar.Current.Close();
//允许按系统的返回键
Shared.Common.CommonPage.BackKeyCanClick = true;
UserCenterResourse.AccountOption.AppCanSignout = true;
return false;
}
//判断是否是应该上传的文件
if (IsNotUpLoadFile(file) == true && upPath == string.Empty)
{
continue;
}
//整理数据
var datainfo = new FileInfoData();
datainfo.BackupFileName = file;
string fullFileName = System.IO.Path.Combine(fullDir, file);
datainfo.BackupFileContent = Shared.IO.FileUtils.ReadFile(fullFileName);
var list = new List();
list.Add(datainfo);
//执行上传
bool falge = DoUpLoadInfoToDB(BackupClassId, list, ManualBackupType);
if (falge == false)
{
//关闭进度条
ProgressFormBar.Current.Close();
//允许按系统的返回键
Shared.Common.CommonPage.BackKeyCanClick = true;
UserCenterResourse.AccountOption.AppCanSignout = true;
return false;
}
//设置进度值
ProgressFormBar.Current.SetValue(i + 1, listFileCount);
}
for (int i = 0; i < listPicFile.Count; i++)
{
string file = listPicFile[i];
//账号已经退出
if (HdlCheckLogic.Current.IsAccountLoginOut() == true)
{
//关闭进度条
ProgressFormBar.Current.Close();
//允许按系统的返回键
Shared.Common.CommonPage.BackKeyCanClick = true;
UserCenterResourse.AccountOption.AppCanSignout = true;
return false;
}
var listPic = new List();
listPic.Add(file);
//上传本地图片文件到云端
bool result = UpLoadBigBackupFileToDB(fullDir, listPic, BackupClassId, ManualBackupType);
if (result == false)
{
//关闭进度条
ProgressFormBar.Current.Close();
//允许按系统的返回键
Shared.Common.CommonPage.BackKeyCanClick = true;
UserCenterResourse.AccountOption.AppCanSignout = true;
return false;
}
//设置进度值
ProgressFormBar.Current.SetValue(i + 1 + listNormalFile.Count, listFileCount);
}
//进度条关闭
ProgressFormBar.Current.Close();
//允许按系统的返回键
Shared.Common.CommonPage.BackKeyCanClick = true;
UserCenterResourse.AccountOption.AppCanSignout = true;
return true;
}
///
/// 执行上传到云端
///
/// 备份主键ID
/// 上传的数据
/// 手动备份类型(0:App手动备份,2:网关手动备份)
///
private bool DoUpLoadInfoToDB(string BackupClassId, List listData, int ManualBackupType = 0)
{
var upData = new UpLoadDataPra();
upData.ManualBackupType = ManualBackupType;
upData.BackupClassId = BackupClassId;
upData.UploadSubFileLists = listData;
//获取控制主人账号的Token
upData.LoginAccessToken = UserCenterLogic.GetConnectMainToken();
bool falge = UserCenterLogic.GetResultStatuByRequestHttps("App/UploadHomeAppGatewaySubFiles", true, upData, null, true);
if (falge == false)
{
return false;
}
return true;
}
///
/// 上传本地图片文件到云端
///
/// 文件夹的全路径
/// 图片文件列表
/// 备份主键ID
/// 手动备份类型(0:App手动备份,2:网关手动备份)
///
private bool UpLoadBigBackupFileToDB(string fullDir, List listPicFile, string BackupClassId, int ManualBackupType = 0)
{
foreach (string fileName in listPicFile)
{
string fullName = System.IO.Path.Combine(fullDir, fileName);
NameValueCollection nvc = new NameValueCollection();
nvc.Add("RequestVersion", Common.CommonPage.RequestVersion);
nvc.Add("LoginAccessToken", UserCenterLogic.GetConnectMainToken());
nvc.Add("HomeId", Shared.Common.Config.Instance.Home.Id);
nvc.Add("BackupClassId", BackupClassId);
nvc.Add("ManualBackupType", ManualBackupType.ToString());
nvc.Add("IsOtherAccountCtrl", Common.Config.Instance.Home.IsOthreShare.ToString());
string base64 = GetBase64Text(fullName);
nvc.Add("UploadSubFileLists[0].BackupFileName", fileName);
nvc.Add("UploadSubFileLists[0].BackupFileContent", base64);
bool result = UpLoadBigBackupFileToDB("App/UploadHomeAppGatewaySubFiles", fullName, nvc);
if (result == false)
{
return false;
}
}
return true;
}
///
/// 上传大文件
///
/// 请求接口
/// 文件名字(含路径)
///
///
private bool UpLoadBigBackupFileToDB(string RequestName, string fullFileName, NameValueCollection nvc)
{
string paramName = "file";
string contentType = "application/octet-stream";
string requestUrl = string.Empty;
//启用管理员权限
if (Config.Instance.Home.IsOthreShare == true)
{
requestUrl = $"{Config.Instance.AdminRequestBaseUrl}/{RequestName}";
}
else
{
requestUrl = $"{CommonPage.RequestHttpsHost}/{RequestName}";
}
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(requestUrl);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.KeepAlive = true;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
Stream 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);
FileStream 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(result);
return UserCenterLogic.CheckNotEorrorMsg(data, requestUrl);
}
catch
{
return false;
}
finally
{
if (wresp != null)
{
wresp.Close();
wresp = null;
}
wr = null;
}
}
#endregion
#region ■ 上传Log备份________________________
///
/// 上传Log备份(隐匿功能)
///
///
public bool UpLoadLogBackup()
{
string upPath = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.LogDirectory);
if (HdlAutoBackupLogic.GetFileFromDirectory(upPath).Count == 0)
{
//没有Log文件
return true;
}
ProgressFormBar.Current.Start();
ProgressFormBar.Current.SetMsg("正在上传Log文件");
//从云端获取数据
var pageData = HdlBackupLogic.Current.GetBackupListNameFromDB(0, null, true);
if (pageData == null)
{
ProgressFormBar.Current.Close();
return false;
}
string backId = string.Empty;
for (int i = 0; i < pageData.Count; i++)
{
if (pageData[i].BackupName == DirNameResourse.OptionBackupName)
{
//获取功能备份的ID
backId = pageData[i].Id;
break;
}
}
if (backId == string.Empty)
{
//创建新的备份
backId = HdlBackupLogic.Current.CreatNewBackupNameToDB(DirNameResourse.OptionBackupName);
if (backId == null)
{
ProgressFormBar.Current.Close();
return false;
}
}
//上传Log文件
bool result = this.UpLoadBackupFileToDB(backId, 0, upPath, false);
if (result == true)
{
try
{
var listAllFile = HdlAutoBackupLogic.GetFileFromDirectory(upPath);
if (listAllFile.Count > 10)
{
listAllFile.Sort();
while (listAllFile.Count >= 10)
{
System.IO.File.Delete(listAllFile[0]);
listAllFile.RemoveAt(0);
}
}
}
catch { }
}
ProgressFormBar.Current.Close();
HdlThreadLogic.Current.RunMain(() =>
{
var contr = new ShowMsgControl(ShowMsgType.Tip, "Log上传成功");
contr.Show();
});
return result;
}
#endregion
#region ■ 读取隐匿功能配置___________________
///
/// 读取隐匿功能配置(不要在意返回值)
///
///
public bool LoadHideOption()
{
//先初始化
UserCenterResourse.HideOption = new HideOptionInfo();
if (UserCenterResourse.UserInfo.AuthorityNo != 1 && UserCenterResourse.UserInfo.AuthorityNo != 2)
{
return true;
}
//无视错误
IMessageCommon.Current.IgnoreError = true;
//从云端获取数据
var pageData = this.GetBackupListNameFromDB(0, null, true);
if (pageData == null)
{
//恢复
IMessageCommon.Current.IgnoreError = false;
return false;
}
string backId = string.Empty;
for (int i = 0; i < pageData.Count; i++)
{
if (pageData[i].BackupName == DirNameResourse.OptionBackupName)
{
//获取功能备份的ID
backId = pageData[i].Id;
break;
}
}
if (backId == string.Empty)
{
//没有功能配置
IMessageCommon.Current.IgnoreError = false;
return true;
}
//获取这个备份下面有多少个文件
List listFile = GetBackFileIDFromDB(backId, false, null);
if (listFile == null)
{
//恢复
IMessageCommon.Current.IgnoreError = false;
return false;
}
if (listFile.Count == 0)
{
//恢复
IMessageCommon.Current.IgnoreError = false;
return true;
}
//检测
string checkKeys = UserCenterLogic.EncryptPassword(UserCenterResourse.FileEncryptKey, DirNameResourse.ShowOptionMenuFile + UserCenterResourse.UserInfo.Account);
if (listFile.Contains(checkKeys) == true)
{
//显示主页隐藏菜单(Debug用)
UserCenterResourse.HideOption.CenterHideMenu = 1;
}
checkKeys = UserCenterLogic.EncryptPassword(UserCenterResourse.FileEncryptKey, DirNameResourse.DetailedLogFile + UserCenterResourse.UserInfo.Account);
if (listFile.Contains(checkKeys) == true)
{
//出力详细Log(Debug用)
UserCenterResourse.HideOption.DetailedLog = 1;
}
checkKeys = UserCenterLogic.EncryptPassword(UserCenterResourse.FileEncryptKey, DirNameResourse.DeviceHistoryFile + UserCenterResourse.UserInfo.Account);
if (listFile.Contains(checkKeys) == true)
{
//显示设备历史版本(Debug用)
UserCenterResourse.HideOption.DeviceHistory = 1;
}
//恢复
IMessageCommon.Current.IgnoreError = false;
return true;
}
#endregion
#region ■ 读取备份___________________________
///
/// 读取APP备份文档(函数内部有进度条)
///
///
public bool LoadAppBackupInfo(string BackupClassId)
{
//打开进度条 正在获取备份文件列表
ProgressFormBar.Current.Start();
ProgressFormBar.Current.SetMsg(Language.StringByID(R.MyInternationalizationString.uBackupFileListGetting));
//从云端获取备份的文件,然后存入本地的临时文件夹
string tempDirectory = GetBackFileFromDBAndSetToLocation(BackupClassId);
if (tempDirectory == null)
{
//关闭进度条
ProgressFormBar.Current.Close();
return false;
}
//关闭进度条
ProgressFormBar.Current.Close();
//如果读取到的文件完全没有问题,则清理本地的文件
UserCenterLogic.DeleteAllLocationFile(false);
//没有错误的话,则移动到当前住宅文件夹下面
Global.MoveDirectoryFileToHomeDirectory(tempDirectory, true);
//删除全部的自动备份的本地文件(此函数用于读取自动备份的时候使用)
HdlAutoBackupLogic.DeleteAllAutoBackupFile();
//刷新本地缓存
UserCenterLogic.RefreshAllMemory();
return true;
}
#endregion
#region ■ 删除备份___________________________
///
/// 删除云端备份
///
/// 备份的主键
///
public bool DeleteDbBackupData(string BackupClassId)
{
var Pra = new LoadBackInfoPra();
Pra.BackupClassId = BackupClassId;
//获取控制主人账号的Token
Pra.LoginAccessToken = UserCenterLogic.GetConnectMainToken();
bool success = UserCenterLogic.GetResultStatuByRequestHttps("App/DelHomeAppGatewayName", true, Pra);
return success;
}
#endregion
#region ■ 一般方法___________________________
///
/// 判断是否是应该上传的文件
///
///
///
public bool IsNotUpLoadFile(string file)
{
if (file == "Config.json")
{
//不能覆盖Config文件
return true;
}
return false;
}
///
/// 将文件转为Base64字符串
///
///
///
private string GetBase64Text(string fileName)
{
string path = Config.Instance.FullPath;
string fullName = System.IO.Path.Combine(path, fileName);
FileStream fs = File.OpenRead(fullName);
byte[] buff = new byte[fs.Length];
fs.Read(buff, 0, buff.Length);
fs.Close();
string base64 = Convert.ToBase64String(buff);
return base64;
}
#endregion
}
}