using System; using System.Collections.Generic; using System.Collections.Concurrent; using System.IO; using System.Linq; using System.Text; using System.Web; using System.Web.Mvc; using Domain; using Service; using Common; using System.Xml; using Newtonsoft.Json; using System.Threading.Tasks; using System.Threading; namespace WebSite.Controllers { public class HostUpdateController : BaseController { private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(HostUpdateController)); private static string get_update_url = System.Configuration.ConfigurationManager.AppSettings["get_update_url"]; private const int AUTHORITY_Host = 30; public IHostUpdateManager HostUpdateManager { get; set; } public IHostUpdateStatusManager HostUpdateStatusManager { get; set; } public IHostManager HostManager { get; set; } public ISysUserManager SysUserManager { get; set; } public IGroupManager GroupManager { get; set; } public ISysHotelManager SysHotelManager { get; set; } public IRoomTypeManager RoomTypeManager { get; set; } public IHostRCUManager HostRCUManager { get; set; } #region Action [Authorize] public ActionResult LoadAllByPage(int page, int rows, string order, string sort) { long total = 0; var list = this.HostUpdateManager.LoadAllByPage(out total, page, rows, order, sort, CurrentHotelID); IList lists = new List(); foreach (HostUpdate h in list) { if (h.FileType == FileType.Config && h.Href.LastIndexOf(".xml") > 0) { XmlDocument doc = new XmlDocument(); string filePath = Tools.GetApplicationPath() + h.Href; try { doc.Load(filePath); XmlElement proNode = doc.DocumentElement; XmlNodeList proGANodes = proNode.GetElementsByTagName("ProjectGroupAddr"); foreach (XmlNode node in proGANodes) { if (node.Attributes["Level"].Value == "2") { HostUpdate item = new HostUpdate(); item.ID = h.ID; item.FileName = h.FileName.Substring(0, h.FileName.Length - 4) + "_" + node.Attributes["Version"].Value + "_" + node.Attributes["Name"].Value + ".cfg"; item.FileType = h.FileType; item.Size = h.Size; item.UploadTime = h.UploadTime; item.Account = h.Account; item.Href = h.Href; item.HotelID = Convert.ToInt16(node.Attributes["ID"].Value); lists.Add(item); } } } catch (Exception ex) { logger.Error(string.Format("解释xml文件({0})失败:{1}", filePath, ex.ToString())); } } else { lists.Add(h); } } var result = new { total = lists.Count, rows = lists }; return Json(result); } /// /// 上传升级包 /// /// /// [Authorize] public ActionResult Upload(HttpPostedFileBase file, FileType fileType) { try { if (file == null || file.ContentLength <= 0) { throw new ApplicationException(HttpContext.InnerLanguage("PleaseSelectTheUpgradePackageFile")); } string ext = System.IO.Path.GetExtension(file.FileName).ToLower(); if (fileType == FileType.Firmware && ext != ".bin") { throw new ApplicationException(HttpContext.InnerLanguage("UploadErrorTheFirmwareFileMustFormat")); } else if (fileType == FileType.Config) { if (ext != ".xml" && ext != ".dat") { throw new ApplicationException(HttpContext.InnerLanguage("UploadErrorTheConfigurationFileMustFormat")); } } //else if (fileType == FileType.ConfigPrj && ext != ".prj") //{ // throw new ApplicationException(HttpContext.InnerLanguage("UploadErrorTheConfigurationFileMustFormat")); //} else if (fileType == FileType.RCUValidate && ext != ".lic") { throw new ApplicationException(HttpContext.InnerLanguage("UploadErrorTheRCUFileMustFormat")); } var sysHotel = SysHotelManager.Get(CurrentHotelID); HostUpdate entity = new HostUpdate { ID = 0, FileType = fileType, FileName = file.FileName, Md5 = Tools.ComputeFileHash(file.InputStream), Size = file.ContentLength, Href = "Uploads/" + sysHotel.Code + "/" + file.FileName, UploadTime = DateTime.Now, Account = this.User.Identity.Name, HotelID = CurrentHotelID }; string filePath = Server.MapPath("~/Uploads/" + sysHotel.Code + "/"); if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } filePath += file.FileName; if (System.IO.File.Exists(filePath)) { throw new ApplicationException(HttpContext.InnerLanguage("TheUpgradePackageHasBeenUploadedPleaseReSelect")); } HostUpdateManager.Save(entity); file.SaveAs(filePath); SaveSystemLog(AUTHORITY_Host, HttpContext.InnerLanguage("UploadUpgradeFile"), "【" + entity.FileName + "】"); return Json(new { IsSuccess = true, Message = HttpContext.InnerLanguage("UploadSuccessful") }); } catch (Exception ex) { SaveSystemLog(AUTHORITY_Host, HttpContext.InnerLanguage("UploadUpgradeFile"), ex.Message, false); return Json(new { IsSuccess = false, Message = HttpUtility.HtmlEncode(ex.Message) }); } } [Authorize] public ActionResult Delete(IList idList) { try { IList updateList = new List(); foreach (int id in idList) { HostUpdate hostUpdate = HostUpdateManager.Get(id); if (hostUpdate != null) { string file = Server.MapPath("~/" + hostUpdate.Href); if (System.IO.File.Exists(file)) { System.IO.File.Delete(file); } updateList.Add(hostUpdate.FileName); } } HostUpdateManager.Delete(idList.Cast().ToList()); SaveSystemLog(AUTHORITY_Host, HttpContext.InnerLanguage("DeleteUpgradeFile"), "【" + String.Join(",", updateList.ToArray()) + "】"); return Json(new { IsSuccess = true, Message = HttpContext.InnerLanguage("DeleteSuccess") }); } catch (Exception ex) { SaveSystemLog(AUTHORITY_Host, HttpContext.InnerLanguage("DeleteUpgradeFile"), ex.Message, false); return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("DeleteFailedBecause") + ex.Message }); } } /// /// 升级主机(C主机):获取升级文件内容,保存到本地 /// /// /// [Authorize] public ActionResult GetUpdatedFile(int roomTypeID) { if (string.IsNullOrEmpty(get_update_url)) { throw new ApplicationException("未配置获取升级包的服务器地址!"); } try { List fileNames = GetUpdateFileByRoomTypeID(roomTypeID); return Json(new { IsSuccess = true, Data = fileNames }); } catch (Exception ex) { logger.Error("获取文件失败", ex); return Json(new { IsSuccess = false, Message = "获取文件失败:" + ex.Message }); } } public static List GetUpdateFileNameByRoomTypeID(int roomTypeID) { //List fileNames = new List(); ConcurrentBag fileNames = new ConcurrentBag(); CountdownEvent count = new CountdownEvent(2); for (int j = 1; j < 3; j++)//1:固件升级bin或hex,2:配置升级dat { Task.Factory.StartNew((state) => { int i = (int)state; string type = (i == 1 ? "固件" : "配置"); string url = string.Format(get_update_url + "?RoomTypeid={0}&DataType={1}", roomTypeID, i); string result = HttpWebRequestHelper.PostWebRequest(url, ""); Domain.HostUpdateApi apiResult = JsonConvert.DeserializeObject(result); string modelName = ""; if (apiResult == null || string.IsNullOrEmpty(apiResult.ModelName)) { modelName = "无"; } else { modelName = apiResult.ModelName; } if (apiResult != null) { if (apiResult.Status) { foreach (HostUpdateApiDataList item in apiResult.datalist) { string fileName = item.Filename;//文件名 fileNames.Add(string.Format("{0}:{1} || {2} || {3}", type, modelName, (string.IsNullOrEmpty(item.LuncherVer) ? "无" : item.LuncherVer), fileName)); } } else { fileNames.Add(type + ":" + apiResult.ErrMsg); } } count.Signal(); }, j); } count.Wait(); return fileNames.ToList(); } public static List GetUpdateFileByRoomTypeID(int roomTypeID) { List fileNames = new List(); for (int i = 1; i < 3; i++)//1:固件升级bin或hex,2:配置升级dat { string type = (i == 1 ? "固件" : "配置"); string url = string.Format(get_update_url + "?RoomTypeid={0}&DataType={1}", roomTypeID, i); string result = HttpWebRequestHelper.PostWebRequest(url, ""); Domain.HostUpdateApi apiResult = JsonConvert.DeserializeObject(result); string modelName = ""; if (apiResult == null || string.IsNullOrEmpty(apiResult.ModelName)) { modelName = "无"; } else { modelName = apiResult.ModelName; } //string modelName = (string.IsNullOrEmpty(apiResult.ModelName) ? "无" : apiResult.ModelName); if (apiResult != null) { if (apiResult.Status) { foreach (HostUpdateApiDataList item in apiResult.datalist) { string fileName = item.Filename;//文件名 byte[] bytes = Convert.FromBase64String(item.data);//升级数据base64 string fileHref = "Uploads/room_type/" + roomTypeID + "/" + fileName; string filePath = Tools.GetApplicationPath() + "Uploads/room_type/" + roomTypeID + "/"; if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } filePath += fileName; if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); } using (FileStream fs = new FileStream(filePath, System.IO.FileMode.Create, System.IO.FileAccess.Write))//写入文件到指定位置 { fs.Write(bytes, 0, bytes.Length); fs.Flush(); } fileNames.Add(string.Format("{0}:{1} || {2} || {3}", type, modelName, (string.IsNullOrEmpty(item.LuncherVer) ? "无" : item.LuncherVer), fileName)); } } else { fileNames.Add(type + ":" + apiResult.ErrMsg); } } } fileNames.Reverse(); return fileNames; } /// /// 升级主机(C主机) /// /// 升级主机ID集合 /// 升级文件名 /// [Authorize] public ActionResult UpdateHostC(IList idList, string fileName) { return this.ShengJI(idList, fileName); } public ActionResult ShengJI(IList idList, string fileName) { try { IList hosts = new List(); foreach (int id in idList) { Host host = HostManager.Get(id); if (host != null) { hosts.Add(host); } } FileType fileType = FileType.Config; switch (fileName.Substring(fileName.Length - 3).ToLower()) { case "bin": case "hex": fileType = FileType.Firmware; break; case "dat": fileType = FileType.Config; break; default: return Json(new { IsSuccess = false, Message = "升级文件不合法!" }); } string fileHref = "Uploads/room_type/" + hosts[hosts.Count - 1].RoomType.ID + "/" + fileName;//升级文件相对路径 string fileMd5 = ""; using (Stream stream = System.IO.File.Open(Tools.GetApplicationPath() + fileHref, FileMode.Open)) { fileMd5 = Tools.ComputeFileHash(stream); stream.Close(); } //HostUpdate hostUpdate = HostUpdateManager.Get(fileMd5, CurrentHotelID); //if (null == hostUpdate) //{ // hostUpdate = new HostUpdate(); // hostUpdate.FileType = fileType; // hostUpdate.FileName = fileName; // hostUpdate.Href = fileHref; // hostUpdate.Md5 = fileMd5; // hostUpdate.Size = 0; // hostUpdate.UploadTime = DateTime.Now; // hostUpdate.Account = this.User.Identity.Name; // hostUpdate.HotelID = CurrentHotelID; // HostUpdateManager.Save(hostUpdate); //} HostManager.UpdateHostC(null, fileType, fileHref, fileMd5, hosts); IList hostNumberList = new List(); foreach (Host h in hosts) { hostNumberList.Add(h.RoomNumber); } string logDetail = String.Format(HttpContext.InnerLanguage("UpdateHostLogDetailFormat"), String.Join(",", hostNumberList.ToArray()), fileHref); SaveSystemLog(AUTHORITY_Host, HttpContext.InnerLanguage("UpdateHost"), logDetail); return Json(new { IsSuccess = true, Message = HttpContext.InnerLanguage("IsUpgrading") }); } catch (Exception ex) { logger.Error(HttpContext.InnerLanguage("ReleaseUpgradeFails"), ex); SaveSystemLog(AUTHORITY_Host, HttpContext.InnerLanguage("UpdateHost"), ex.Message, false); return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("ReleaseUpgradeFailedBecause") + ex.Message }); } } public ActionResult ShengJI_NEW(IList idList, string fileName, IHostManager HostManager1) { try { IList hosts = new List(); foreach (int id in idList) { Host host = HostManager1.Get(id); if (host != null) { hosts.Add(host); } } FileType fileType = FileType.Config; switch (fileName.Substring(fileName.Length - 3).ToLower()) { case "bin": case "hex": fileType = FileType.Firmware; break; case "dat": fileType = FileType.Config; break; default: return Json(new { IsSuccess = false, Message = "升级文件不合法!" }); } string fileHref = "Uploads/room_type/" + hosts[hosts.Count - 1].RoomType.ID + "/" + fileName;//升级文件相对路径 string fileMd5 = ""; using (Stream stream = System.IO.File.Open(Tools.GetApplicationPath() + fileHref, FileMode.Open)) { fileMd5 = Tools.ComputeFileHash(stream); stream.Close(); } HostManager1.UpdateHostC(null, fileType, fileHref, fileMd5, hosts); IList hostNumberList = new List(); foreach (Host h in hosts) { hostNumberList.Add(h.RoomNumber); } return Json(new { IsSuccess = true, Message = "shengji" }); } catch (Exception ex) { logger.Error(ex.Message); logger.Error(ex.StackTrace); return Json(new { IsSuccess = false, Message = ex.Message }); } } /// /// 升级主机 /// /// /// /// [Authorize] public ActionResult UpdateHost(int hostUpdateID, int subGroupID, string hostIDs, bool isTFTP) { try { IList ids = Newtonsoft.Json.JsonConvert.DeserializeObject>(hostIDs); HostUpdate hostUpdate = HostUpdateManager.Get(hostUpdateID); if (hostUpdate == null) { return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("InvalidFirmwareOrConfigurationFiles") }); } FileType fileType = hostUpdate.FileType; string fileHref = hostUpdate.Href; string fileMd5 = hostUpdate.Md5; //通过xml文件解释对应的子群cfg if (hostUpdate.FileType == FileType.Config && hostUpdate.Href.LastIndexOf(".xml") > 0) { XmlDocument doc = new XmlDocument(); doc.Load(Tools.GetApplicationPath() + hostUpdate.Href); XmlElement proNode = doc.DocumentElement; XmlNodeList proGANodes = proNode.GetElementsByTagName("ProjectGroupAddr"); foreach (XmlNode node in proGANodes) { if (Convert.ToInt16(node.Attributes["ID"].Value) == subGroupID) { List> sendDatas = ProtocalData.GetSubgroupSendData(node); fileHref = hostUpdate.Href.Substring(0, hostUpdate.Href.Length - 4) + "_" + node.Attributes["Version"].Value + "_" + node.Attributes["Name"].Value + ".cfg"; string path = Tools.GetApplicationPath() + fileHref; int totalLength = 0;//计算配置文件总字节数,如果不是4的倍数,以0xFF补上 using (System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.Create, System.IO.FileAccess.Write)) { foreach (List sendData in sendDatas) { totalLength += sendData.ToArray().Length; fs.Write(sendData.ToArray(), 0, sendData.ToArray().Length); } totalLength = 4 - (totalLength % 4); for (int i = 0; i < totalLength; i++) { fs.Write((new byte[] { 0xFF }), 0, 1); } } using (Stream stream = System.IO.File.Open(path, FileMode.Open)) { fileMd5 = Tools.ComputeFileHash(stream); } break; } } } IList hosts = new List(); IList hostNumberList = new List(); foreach (int id in ids) { Host host = HostManager.Get(id); if (host != null) { hosts.Add(host); hostNumberList.Add(host.RoomNumber); } } HostManager.UpdateHost(hostUpdate, fileType, fileHref, fileMd5, hosts, isTFTP); string logDetail = String.Format(HttpContext.InnerLanguage("UpdateHostLogDetailFormat"), String.Join(",", hostNumberList.ToArray()), fileHref); SaveSystemLog(AUTHORITY_Host, HttpContext.InnerLanguage("UpdateHost"), logDetail); return Json(new { IsSuccess = true, Message = HttpContext.InnerLanguage("IsUpgrading") }); } catch (Exception ex) { logger.Error(HttpContext.InnerLanguage("ReleaseUpgradeFails"), ex); SaveSystemLog(AUTHORITY_Host, HttpContext.InnerLanguage("UpdateHost"), ex.Message, false); return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("ReleaseUpgradeFailedBecause") + ex.Message }); } } /// /// 获取升级状态 /// /// /// /// [Authorize] public ActionResult UpdateHostStatus(int hostUpdateID) { try { var statusList = HostUpdateStatusManager.LoadAll().Where(r => r.HostUpdate.ID == hostUpdateID).Select(r => new { id = r.ID, hostID = r.Host.ID, status = r.Status }).OrderBy(A => A.hostID); return Json(new { IsSuccess = true, Data = statusList }); } catch (Exception ex) { logger.Error(HttpContext.InnerLanguage("ReleaseUpgradeFails"), ex); return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("ReleaseUpgradeFailedBecause") + ex.Message }); } } [Authorize] public ActionResult LoadGroupTreeWithRoom(int? hostUpdateID) { IList updatedHosts = new List(); if (hostUpdateID.HasValue) { HostUpdate hostUpdate = HostUpdateManager.Get(hostUpdateID); updatedHosts = HostUpdateStatusManager.LoadAllByHostUpdate(hostUpdate).Select(r => r.Host).Distinct().ToList(); } var groupTree = GroupManager.CreateGroupTreeWithRoom(null, updatedHosts, CurrentHotelID); IList result = new List(); result.Add(new { id = 0, text = HttpContext.InnerLanguage("RoomNumber"), iconCls = "tree-node-no-icon", children = groupTree, attributes = new { isHost = false, roomTypeID = 0 } }); return Json(result, JsonRequestBehavior.AllowGet); } [Authorize] public ActionResult LoadRoomType() { var roomTypeList = RoomTypeManager.LoadAll().Where(r => r.HotelID == CurrentHotelID); IList list = new List(); foreach (RoomType rt in roomTypeList) { list.Add(new { id = rt.ID, text = rt.Name, iconCls = "tree-node-no-icon" }); } IList result = new List(); result.Add(new { id = 0, text = HttpContext.InnerLanguage("RoomType"), iconCls = "tree-node-no-icon", children = list }); return Json(result, JsonRequestBehavior.AllowGet); } #endregion } }