/// <summary> /// 保存资源文件(存放于OSS上) /// </summary> /// <param name="modelId"></param> /// <param name="resourceFile"></param> /// <returns></returns> internal bool SaveModelResource(int modelId, IFormFile file) { byte[] data = file.ToArray(); ViewModel.ResourceFile resource = new ViewModel.ResourceFile(file, data); if (modelId == 0) { return(this.FaildMessage("模型编号错误")); } if (string.IsNullOrEmpty(resource.Name)) { return(this.FaildMessage("没有上传内容")); } using (DbExecutor db = NewExecutor()) { ViewModel model = new ViewModel() { ID = modelId }.Info(db); if (model == null) { return(this.FaildMessage("模型编号错误")); } if (model.ResourceFiles.ContainsKey(resource.Name)) { model.ResourceFiles[resource.Name] = resource; } else { model.ResourceFiles.Add(resource.Name, resource); } model.Resources = JsonConvert.SerializeObject(model.ResourceFiles); // 上传文件至于OSS if (!OSSAgent.Upload(new OSSSetting(SettingAgent.Instance().GetSetting(SystemSetting.SettingType.CDNOSS)), resource.Path, data, new ObjectMetadata(), out string message)) { return(this.FaildMessage(message)); } return(model.Update(db, t => t.Resources) == 1); } }
/// <summary> /// 解析并且保存安卓文件 /// </summary> /// <returns></returns> private Result SaveApk(IFormFile file) { string localFile = @$ "{Directory.GetCurrentDirectory()}/temp/{DateTime.Now.Ticks}.apk"; using (FileStream fileStream = new FileStream(localFile, FileMode.Create)) { file.CopyTo(fileStream); } string fileMD5 = FileAgent.GetMD5(localFile).Substring(0, 4); byte[] AndroidManifest, resources, iconData; try { using (ZipArchive zip = ZipFile.OpenRead(localFile)) { ZipArchiveEntry entry = zip.GetEntry("AndroidManifest.xml"); AndroidManifest = new byte[entry.Length]; entry.Open().Read(AndroidManifest, 0, AndroidManifest.Length); ZipArchiveEntry ascr = zip.GetEntry("resources.arsc"); resources = new byte[ascr.Length]; ascr.Open().Read(resources, 0, resources.Length); ApkReader apkReader = new ApkReader(); ApkInfo info = apkReader.extractInfo(AndroidManifest, resources); string iconFile = info.iconFileName.Where(t => t.EndsWith(".png")).LastOrDefault(); ZipArchiveEntry iconEntry = zip.GetEntry(iconFile); iconData = new byte[iconEntry.Length]; iconEntry.Open().Read(iconData, 0, iconData.Length); // 上传文件至OSS string version = this.GetVersion(info.versionName); string fileName = $"app/{info.label.ToPinYinAbbr().ToLower()}_{version}_{fileMD5}.apk"; string iconPath = $"app/{Encryption.toMD5(iconData).Substring(0, 16).ToLower()}.png"; string ossMessage; if (!OSSAgent.Upload(_ossSetting, fileName, localFile, out ossMessage)) { return(new Result(false, ossMessage, new { fileName, localFile })); } if (!OSSAgent.Upload(_ossSetting, iconPath, iconData, null, out ossMessage)) { return(new Result(false, ossMessage)); } string configFile = $"app/{DateTime.Now.ToString("yyyyMMHHmmss")}.json"; string json = new { Name = info.label, File = fileName, Version = version, Icon = iconPath, Config = configFile, UpdateAt = DateTime.Now }.ToJson(); if (!OSSAgent.Upload(_ossSetting, configFile, Encoding.UTF8.GetBytes(json), null, out ossMessage)) { return(new Result(false, ossMessage)); } return(new Result(true, fileName, json)); } } catch (Exception ex) { return(new Result(false, ex.Message)); } finally { File.Delete(localFile); } }
/// <summary> /// 发布模型 /// </summary> /// <param name="modelId"></param> /// <returns></returns> internal bool PublishModel(int modelId) { ViewModel model = this.GetModelInfo(modelId); if (model == null) { return(this.FaildMessage("模型错误")); } Language[] languages = SettingAgent.Instance().GetSetting(SystemSetting.SettingType.Language).Split(',').Select(t => t.ToEnum <Language>()).ToArray(); if (languages.Length == 0) { return(this.FaildMessage("没有配置语言包")); } string translateUrl = SettingAgent.Instance().GetSetting(SystemSetting.SettingType.Translate); if (string.IsNullOrEmpty(translateUrl)) { return(this.FaildMessage("没有配置语言包接口地址")); } //#1 找出样式文件中需要替换的资源路径 model.Style = Regex.Replace(model.Style, @"url\((?<Resource>[^\)]+?)\)", t => { string resource = t.Groups["Resource"].Value; if (model.ResourceFiles.ContainsKey(resource)) { return($"url({model.ResourceFiles[resource]})"); } return(t.Value); }); using (DbExecutor db = NewExecutor()) { model.Update(db, t => t.Style); } //#2 发布页面的各个语言版本 { Regex regex = new Regex(@"~.+?~", RegexOptions.Multiline); //#2.1 找出单词 Dictionary <string, bool> words = new Dictionary <string, bool>(); foreach (Match match in regex.Matches(model.Page)) { string word = match.Value; if (!words.ContainsKey(word)) { words.Add(word, true); } } //#2.2 发送到翻译API,获得语言包 Dictionary <string, Dictionary <Language, string> > dic = Translate.Get(words.Select(t => t.Key).ToArray(), translateUrl, languages); foreach (Language language in languages) { int total = 0; int count = 0; string content = regex.Replace(model.Page, t => { total++; if (dic.ContainsKey(t.Value) && dic[t.Value].ContainsKey(language)) { count++; return(dic[t.Value][language]); } return(t.Value.Replace("~", string.Empty)); }); string path = $"html/{ Encryption.toMD5Short(Encryption.toMD5(content)) }.html"; if (!OSSAgent.Upload(new OSSSetting(SettingAgent.Instance().GetSetting(SystemSetting.SettingType.CDNOSS)), path, Encoding.UTF8.GetBytes(content), new ObjectMetadata() { ContentType = "text/html", ContentEncoding = "utf-8", ContentDisposition = "inline", CacheControl = "only-if-cached", ExpirationTime = DateTime.Now.AddYears(1), }, out string message)) { return(this.FaildMessage(message)); } ViewContent viewContent = new ViewContent() { Language = language, ModelID = modelId, Path = path, Translate = total == 0 ? 1M : count / (decimal)total }; this.SaveModelContent(viewContent); } } return(true); }
public override Result Invote() { if (string.IsNullOrEmpty(_path)) { return(new Result(false, "not configured file save path")); } // 是否是需要向前兼容的版本(旧版本如果出错则返回空值) bool isBackward = context.Request.Path.StartsWithSegments("/imageupload.ashx"); string uploadFolder = null; string fileFolder = null; try { // 自定义的后缀名 string type = !this.context.Request.Headers.ContainsKey("x-type") ? null : this.context.Request.Headers["x-type"].ToString(); byte[] data = this.context.GetData(); if (data == null || data.Length < 2) { return(isBackward ? new Result("") : new Result(false, "Content is Empty")); } string fileName = Encryption.toMD5(data).Substring(0, 16).ToLower(); // 相对路径 fileFolder = "upload/" + DateTime.Now.ToString("yyyyMM"); // 绝对路径 uploadFolder = _path + DateTime.Now.ToString("yyyyMM"); if (!Directory.Exists(uploadFolder)) { Directory.CreateDirectory(uploadFolder); } string contentType = FileAgent.GetContentType(data); if (string.IsNullOrEmpty(contentType) && string.IsNullOrEmpty(type)) { return(isBackward ? new Result("") : new Result(false, "文件类型未知")); } string ext = type ?? Regex.Match(contentType, @"/(?<Type>\w+)$").Groups["Type"].Value; if (!fileType.Contains(ext)) { return(isBackward ? new Result("") : new Result(false, $"文件类型{ext}不支持")); } // 需要保存的绝对路径 string filePath = $"{uploadFolder}/{ fileName}.{ ext}"; // 对外输出的相对路径 fileName = $"{fileFolder}/{fileName}.{ext}"; if (!OSSAgent.Upload(_ossSetting, fileName, data, null, out string message)) { return(new Result(false, message)); } if (!File.Exists(filePath)) { File.WriteAllBytes(filePath, data); } if (isBackward) { return(new Result(ContentType.TEXT, $"/{fileName}")); } else { return(new Result(true, "Success", new { fileName = $"/{fileName}" })); } } catch (Exception ex) { if (isBackward) { return(new Result("")); } else { return(new Result(false, $"{ex.Message}\nfileFolder:{fileFolder}\nuploadFolder:{uploadFolder}")); } } }