コード例 #1
0
ファイル: PicTextEditor.cs プロジェクト: Cyenoch/Coolapk-UWP
        /// <summary>
        /// 上传图片和生成结构体
        /// </summary>
        /// <returns></returns>
        public async Task <IList <MessageRawStructBase> > UploadAndGenerateStructModel()
        {
            var list = new List <MessageRawStructBase>();
            // 寻找还未上传的图片node
            var waitForUpload = NodeList.Where(node => node is ImageNode).Where(node => !UploadedImg.ContainsKey((node as ImageNode).HashMd5)).Select(node => node as ImageNode).ToList();
            // 生成上传所需的信息
            var fragments = new List <UploadFileFragment>();

            foreach (var node in waitForUpload)
            {
                if (fragments.Any(_n => _n.Md5.Equals(node.HashMd5)))
                {
                    break;
                }
                var img = await BitmapDecoder.CreateAsync(await node.File.OpenAsync(FileAccessMode.Read));

                fragments.Add(new UploadFileFragment {
                    Resolution = $"{img.PixelWidth}x{img.PixelHeight}",
                    Name       = node.HashMd5 + node.File.FileType,
                    Md5        = node.HashMd5
                });
            }

            if (fragments.Count > 0)
            {
                var dialog = new ContentDialog()
                {
                    Title = "正在上传..."
                };
                _ = dialog.ShowAsync();
                try {
                    // 从酷安获取STS
                    var r = await App.AppViewModel.CoolapkApis.OssUploadPicturePrepare(new OssUploadPicturePrepareBody {
                        UploadFileFragmentsSource = fragments
                    });

                    var data = r.Data;
                    // 对每个需要上传的文件执行真正的上传操作

                    dialog.Content = "正在生成上传任务...";



                    // 生成tasks
                    var tasks = data.FileInfo.Select(async info => {
                        var imgNode = waitForUpload.Find(node => node.HashMd5 == info.Md5);
                        using (var fs = await imgNode.File.OpenStreamForReadAsync()) {
                            var response = CoolapkApiHelper.OssUpload(data.UploadPrepareInfo, info, fs, imgNode.File.ContentType,
                                                                      (OssUploadPicturePrepareResultFileInfo fileInfo, object sender, StreamTransferProgressArgs args) => {
                                _ = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
                                    dialog.Content = $"{data.FileInfo.IndexOf(info) + 1}/{data.FileInfo.Count} 上传进度 {args.PercentDone}%";
                                });
                            });
                            // 添加到已上传的图片的列表防止重复上传
                            UploadedImg.Add(imgNode.HashMd5, response.Data.Url);
                            _ = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
                                dialog.Content = $"{data.FileInfo.IndexOf(info) + 1}/{data.FileInfo.Count} 上传完成!";
                            });
                        }
                    }).ToArray();

                    // 逐个执行
                    await Task.WhenAll(tasks);

                    _ = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
                        dialog.Title   = "上传完成";
                        dialog.Content = "所有上传任务完成";
                        dialog.Hide();
                    });

                    //
                } catch (OssException err) {
                    //throw new Exception($"某张图片上传失败: {err.HResult}:{err.ErrorCode} -> {err.Message}");
                    dialog.Title   = "上传失败";
                    dialog.Content = ($"某张图片上传失败: {err.HResult}:{err.ErrorCode} -> {err.Message}");
                } catch (Exception err) {
                    //throw new Exception("上传图片上传失败: " + err.Message);
                    dialog.Title   = "上传失败";
                    dialog.Content = ("上传图片上传失败: " + err.Message);
                } finally {
                    dialog.PrimaryButtonText = "关闭";
                }
            }

            // 遍历NodeList生成RawStruct
            foreach (var node in NodeList)
            {
                switch (node)
                {
                case TextNode textNode:
                    list.Add(new MessageRawStructText {
                        Type = "text", Message = textNode.Text
                    });
                    break;

                case ImageNode imageNode:
                    // 从已上传的图片中获取链接
                    string uploadedUrl = UploadedImg[imageNode.HashMd5];
                    list.Add(new MessageRawStructImage {
                        Type = "image", Description = imageNode.IntroText, Url = uploadedUrl
                    });
                    break;
                }
            }
            return(list);
        }