码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 基于SqlSugar的开发框架循序渐进介绍(26)-- 实现本地上传、FTP上传、阿里云OSS上传三者合一处理


    在前面介绍的随笔《基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传》中介绍过在文件上传处理的过程中,整合了本地文件上传和基于FTP方式的上传文件的处理整合。本篇随笔继续介绍文件上传的处理,基于选项模式【Options】方式整合基于阿里云OSS对象存储的处理方式。

    1、选项模式【Options】的处理

    文件上传处理应该由程序进行配置,决定使用那种方式,那么这里面我们为了弹性化处理, 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传的配置参数信息。

    微软引入选项模式,它是用于配置框架服务使用的设置. 选项模式由Microsoft.Extensions.OptionsNuGet包实现,除了ASP.NET Core应用,它还适用于任何类型的应用程序,如果需要了解,微软的文档详细解释了选项模式。

    选项模式的限制之一是你只能解析(注入) IOptions  并在依赖注入配置完成(即所有模块的ConfigureServices方法完成)后获取选项值。如果你正在开发一个模块,可能需要让开发者能够设置一些选项,并在依赖注入注册阶段使用这些选项. 你可能需要根据选项值配置其他服务或更改依赖注入的注册代码。IOptions<>是单例,因此一旦生成了,除非通过代码的方式更改,它的值是不会更新的。

     之前介绍过的文件上传处理,

    一个是本地文件处理,一个是FTP文件处理,它们选择那种方式,依赖于配置参数的信息,如下示意图所示。

    当我们增加了对象存储OSS方式后,可以扩展下这个图示如下所示。

    在本地文件处理过程中,如果是Web API方式调用服务层,那么就在Web API所在的文件系统中,如果是Winform界面直接调用服务层,那么就是在当前系统中处理文件,这种方式可以有效的管理我们的文件信息。

    在FTP文件处理过程中,则是根据选项参数的信息,调用FluentFTP类库进行文件的上传操作。

    在OSS对象存储处理过程中,我们一般基于阿里云、腾讯云等这些云服务OSS的处理方式,一般它们会提供相应开发语言的SDK,我们引用并进行整合即可。

    基于选项模式,根据我们的处理方式,我们定义一个对象,用于承载上传参数的信息,如下代码所示。

    复制代码
        /// 
        /// 文件上传处理的选项信息
        /// 
        public class UploadSettingOptions
        {
            /// 
            /// 可指定的存储物理地址,如C:\\Attachment,如果没有配置项AttachmentBasePath,则默认一个相对目录。
            /// 
            public string AttachmentBasePath { get; set; }
    
            /// 
            /// 指定附件上传的方式,如ftp为FTP方式,为空则为普通方式
            /// 
            public string AttachmentUploadType { get; set; }
    
    
            /// 
            /// FTP上传配置
            /// 
            public FtpProviderOptions FtpProvider { get; set; }
    
            /// 
            /// OSS存储的配置
            /// 
            public OSSProviderOptions OSSProvider { get; set; }
        }
    复制代码

    其中本地介绍OSS存储处理的配置选项对象如下所示。

    复制代码
        /// 
        /// OSS对象存储配置选项
        /// 
        public sealed class OSSProviderOptions
        {
            /// 
            /// 指定提供商
            /// 
            public OSSProvider Provider { get; set; }
            /// 
            /// 终结点
            /// 
            public string Endpoint { get; set; }
            public string AccessKey { get; set; }
            public string SecretKey { get; set; }
            public string Region { get; set; }
            public bool IsEnableHttps { get; set; } = true;
            public bool IsEnableCache { get; set; }
            public string Bucket { get; set; }
        }
    复制代码

    对应WebAPI的appSettngs.json文件配置项内容如下:

     

    2、阿里云的OSS存储设置处理

    对于阿里云的OSS来说,对应的AccesKey和SecretKey自己可以通过查看账户的信息可以获取到。

    我们开始需要添加一个Bucket节点,用来存放相关的文件,并且需要开启对应的权限,如下所示。

    一旦正式允许可以上传文件,那么文件存储在对应的Bucket项目中,如下所示。

     准备好这些前期工作后,我们如果需要在WebAPI端进行OSS存储的处理,可以利用阿里云的OSS 的SDK进行处理即可,如下所示。

     SDK的常规使用很简单,我们可以参考它的aliyun-oss-csharp-sdk 案例来上传处理即可。

    例如它的上传文件的处理代码如下所示:

        OssClient client = new OssClient(endpoint, accessKeyId, accessKeySecret); 
        client.PutObject(bucketName, key, filePathToUpload);

    在文件处理的通用上传处理函数里面,我们根据配置内容选择不同的上传模式。

    复制代码
            /// 
            /// 上传文件(根据配置文件选择合适的上传方式)
            /// 
            /// 文件信息(包含流数据)
            /// 
            public async Task Upload(FileUploadInfo info)
            {
                var uploadType = this._options.AttachmentUploadType;
    
                if (string.IsNullOrEmpty(uploadType))
                {
                    return await this.UploadByNormal(info);
                }
                else if (uploadType.Equals("ftp", StringComparison.OrdinalIgnoreCase))
                {
                    return await this.UploadByFTP(info);
                }
                else if(uploadType.Equals("oss", StringComparison.OrdinalIgnoreCase))
                {
                    return await this.UploadByOSS(info);
                }
                else
                {
                    throw new ArgumentException("AttachmentUploadType配置指定了无效的值, 请置空, 填写ftp或者填写oss。");
                }
            }
    复制代码

    由于本篇主要介绍OSS的对象存储方式,因此我们来看看对应的OSS上传处理的操作。

    和其他上传(如FTP上传)方式类似,我们也是构建对应的信息后调用OSS的SDK处理即可,如下代码所示。

    复制代码
    /// 
    /// 使用阿里云的OSS服务上传文件
    /// 
    /// 
    /// 
    public async Task UploadByOSS(FileUploadInfo info)
    {
        var result = new CommonResult();
        var ossOptions = this._options.OSSProvider;
        if(ossOptions != null)
        {
            //上传获得的相对路径
            string category = info.Category;
            if (string.IsNullOrEmpty(category))
            {
                category = "Photo";
            }
    
            //OSS的文件路径不能以正斜线(/)或者反斜线(\)字符开头。
            //确定日期时间目录(格式:yyyy-MM),不存在则创建
            string savePath = string.Format("{0}-{1:D2}/{2}", DateTime.Now.Year, DateTime.Now.Month, category);
            var ext = FileUtil.GetExtension(info.FileName);
            var finalName = string.Format("{0}{1}", Guid.NewGuid().ToString(), ext);//FileUtil.GetFileName(file);
    
            var filePath = string.Concat(savePath, "/", finalName);
            var stream = FileUtil.BytesToStream(info.FileData);
    
            //使用阿里云的OSS服务上传文件
            var client = new OssClient(ossOptions.Endpoint, ossOptions.AccessKey, ossOptions.SecretKey);
            client.PutObject(ossOptions.Bucket, filePath, stream);
    
            //基础路径和部分路径
            info.BasePath = $"{(ossOptions.IsEnableHttps ? "https" : "http")}://{ossOptions.Bucket}.{ossOptions.Endpoint}";
            info.SavePath = filePath;
            info.AddTime = DateTime.Now;
    
    
            result.Success = await base.InsertAsync(info);
            if (result.Success)
            {
                //记录返回值, Data1为具体的URL路径
                //生成外链地址 方便前端预览
                result.Data1 = info.BasePath.UriCombine(savePath);
                result.Data2 = savePath;
            }
            else
            {
                result.ErrorMessage = "数据写入数据库出错。";
            }
        }
        else
        {
            result.ErrorMessage = "OSS配置信息不正确或没有启用";
        }
    
        return result;
    }
    复制代码

    最终我们上传的文件列表如上图所示。

     

    3、在Vue3+ElementPlus+Vite的前端项目上测试前端上传文件的处理

    我们在一个前端的编辑器 @wangeditor 上整合图片上传的处理来展示这个OSS对象保存的操作。案例需要前端项目安装对应的插件,如下所示。

     前端页面引用插件对象的代码如下所示

        
    class="wangeditor"> "border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" /> "height: 500px; overflow-y: hidden" v-model="valueHtml" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" />

    在脚本代码中引入对象的样式和对象。

    复制代码
    <script setup lang="ts">
    import '@wangeditor/editor/dist/css/style.css'; // 引入 css
    import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
    
    
    defineOptions({
      name: 'Editor'
    });
    
    const mode = 'default';
    // 编辑器实例,必须用 shallowRef
    const editorRef = shallowRef();
    复制代码

    为了配置上传图片文件的处理操作,我们需要根据编辑器的介绍,以及我们WebAPI端的处理函数定义,在脚本部分中增加对应的配置信息,如下代码所示

    复制代码
    const editorConfig = {
      placeholder: '请输入内容...',
      MENU_CONF: {
        // 配置默认字号
        // 配置上传图片
        uploadImage: {
          // 上传图片请求接口路径
          server: '/api/FileUpload/PostUpload',
          // 后端接收的文件名称
          fieldName: 'multipartFile',
          maxFileSize: 10 * 1024 * 1024, // 上传图片10M
          // 上传的图片类型
          allowedFileTypes: ['image/*'],
          // 自定义增加 http  header
          headers: {
            Authorization: 'Bearer ' + getAccessToken()
          },
          // 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
          meta: {
            guid: '',
            folder: '文档图片'
          },
          // 将 meta 拼接到 url 参数中,默认 false
          metaWithUrl: false,
          // 小于该值就插入 base64 格式(而不上传),默认为 0
          base64LimitSize: 10 * 1024, // 10MB
          // 自定义上传图片返回格式【后端返回的格式】
          customInsert(res: any, insertFn: InsertFnType) {
            console.log(res);
            if (!res.success) {
              ElMessage.error('上传文件失败,' + res.error);
              return;
            }
            // 从 res 中找到 url alt href ,然后插入图片 ,根据后端实际返回的字段来
            var result = res.result as Array;
            if (result.length > 0) {
              console.log(result[0]);
              insertFn(result[0].url, result[0].name, result[0].url);
            }
          },
          // 单个文件上传成功之后
          onSuccess(file: File, res: any) {
            if (res.success) {
              ElMessage.success(`${file.name} 上传成功`);
              return;
            } else {
              ElMessage.warning(`${file.name} 上传出了点异常`);
              return;
            }
          },
          // 单个文件上传失败
          onFailed(file: File, res: any) {
            console.log(res);
            ElMessage.error(`${file.name} 上传失败`);
          },
          // 上传错误,或者触发 timeout 超时
          onError(file: File, err: any, res: any) {
            console.log(err, res);
            ElMessage.error(`${file.name} 上传出错`);
          }
        }
      }
    };
    复制代码

    其中主要的就是需要增加授权的令牌头部信息,以及对应上传需要用到的参数,还有就是返回的接口对象里面,需要根据Web API的定义,然后转换为本地识别的类别进行展示即可,如定义的 customInsert 函数。

     

     文件上传成功后,可以看到在编辑器中插入了对应的图片文件,图片地址指向的是阿里云OSS的路径。

    在数据库的文件记录中,我们可以看到对应的路径信息,如下所示。

    如果我们需要在项目中实现业务的图片上传功能,如下界面所示的效果。

    可以参考随笔《基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用》介绍内容进行自定义上传文件的处理即可。

    <el-form-item label="资料文档">
         <my-upload v-model="viewForm.attachGUID" :data="{ guid: viewForm.attachGUID, folder: '用户图片' }"   disabled />
     el-form-item>

     

    以上就是我们针对不同的上传方式处理的操作,对于OSS的文件上传,我们通过整合阿里云的OSS的SDK,直接调用进行处理即可,非常方便,对于其他类似的平台,也可以针对它们提供的SDK进行扩展即可。

     

    SqlSugar开发框架介绍:https://www.iqidi.com/Framework/sugarIndex.htm 

    系列文章:

    《基于SqlSugar的开发框架的循序渐进介绍(1)--框架基础类的设计和使用》

    《基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理》

    《基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发》

    《基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理 》

    《基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转》

    《基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口 》

    《基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传》

     《基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录》

    《基于SqlSugar的开发框架循序渐进介绍(9)-- 结合Winform控件实现字段的权限控制》

    《基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理》

    《基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结》

    《基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理》

    《基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用》

    《基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用》

     《基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成》

    《基于SqlSugar的开发框架循序渐进介绍(16)-- 工作流模块的功能介绍》

    《基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理》

     《基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面》

    《基于SqlSugar的开发框架循序渐进介绍(19)-- 基于UniApp+Vue的移动前端的功能介绍》

    《基于SqlSugar的开发框架循序渐进介绍(20)-- 在基于UniApp+Vue的移动端实现多条件查询的处理》

    《基于SqlSugar的开发框架循序渐进介绍(21)-- 在工作流列表页面中增加一些转义信息的输出,在后端进行内容转换》

     《基于SqlSugar的开发框架循序渐进介绍(22)-- Vue3+TypeScript的前端工作流模块中实现统一的表单编辑和表单详情查看处理 》

    《基于SqlSugar的开发框架循序渐进介绍(23)-- Winform端管理系统中平滑增加对Web API对接的需求》

    《基于SqlSugar的开发框架循序渐进介绍(24)-- 使用Serialize.Linq对Lambda表达式进行序列化和反序列化 》

     基于SqlSugar的开发框架循序渐进介绍(25)-- 基于SignalR实现多端的消息通讯

    基于SqlSugar的开发框架循序渐进介绍(26)-- 实现本地上传、FTP上传、阿里云OSS上传三者合一处理

     

  • 相关阅读:
    自动驾驶感知算法实战6——目标分类详解(ResNet、VGG、GoogLeNet等)
    python第三方库-字符串编码工具 chardet 的使用(python3经典编程案例)
    spdk 建立的用户态页表
    如何给注册中心锦上添花?
    vue3 斗兽棋游戏
    网络安全(黑客)—2024自学
    【区分vue2和vue3下的elementUI和elementUI Plus的container组件,介绍如何安装,属性,事件,方法等以及使用案例】
    卷积神经网络的关键技术,卷积神经网络参数优化
    axios 封装
    C语言学习笔记(十八)
  • 原文地址:https://www.cnblogs.com/wuhuacong/p/17302362.html
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号