RuoYi-Vue-Plus (若依上传文件配置、systemApplicationRunner 初始化配置、el实现上传文件及图片组件、阿里云OSS上传文件)

一、AWS

欢迎使用 Amazon Web Services 文档 (amazonaws.cn)icon-default.png?t=N7T8https://docs.amazonaws.cn/zh_cn/?nc2=h_l2_su找到 Amazon S3 

Amazon S3 是云存储标杆,可以支持所有接入 S3的云存储写一

客户端配置

从Amazon S3迁移到OSS后,您仍然可以使用S3 API访问OSS,仅需要对S3的客户端应用进行如下改动:

  1. 获取阿里云账号或RAM用户的AccessKey ID和AccessKey Secret,并在您使用的客户端和SDK中配置您申请的AccessKey ID与AccessKey Secret。

二、配置

ruoyi-oss 模块引入依赖

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-s3</artifactId>
</dependency>

模块解析: 

  1. com.ruoyi.oss.constant.OssConstant  :对象存储常量配置(引入云服务商如下: 阿里 腾讯 七牛云 华为
  2. com.ruoyi.oss.core.OssClient:S3 存储协议 所有兼容S3协议的云厂商均支持,()
  3. com.ruoyi.oss.enumd.AccessPolicyType 桶的访问策略配置
  4. com.ruoyi.oss.enumd.PolicyType  : 文件读写策略
  5. com.ruoyi.oss.factory.OssFactory: 文件上传工厂,用于获取OssClient 实例
  6. com.ruoyi.oss.entity.UploadResult 返回结果类
  7. com.ruoyi.oss.properties.OssProperties  OSS对象存储 配置属性

二、、OssClient   AWS 客户端

类位置: com.ruoyi.oss.core.OssClient

作用; 创建 AmazonS3 上传文件客户端(代码已经上传附件)

sys_oss_config 配置表对应的字段 

1-使用:
上传:只需要调用  OssClient  的 上传方法(如下, 提供字节 路径等参数)
/**
     * <简述>上传方法
     * <详细描述>
     * @author syf
     * @date 2024/5/24 22:58
     * @param data  提供字节流
     * @param path  路径
     * @param contentType 内容类型
     * @return com.ruoyi.oss.entity.UploadResult
     */
    public UploadResult upload(byte[] data, String path, String contentType) {
        return upload(new ByteArrayInputStream(data), path, contentType);
    }

删除:提供全路径

/**
     * <简述>删除方法
     * <详细描述>
     * @author syf
     * @date 2024/5/24 23:14
     * @param path
     */
    public void delete(String path) {
        path = path.replace(getUrl() + "/", "");
        try {
            client.deleteObject(properties.getBucketName(), path);
        } catch (Exception e) {
            throw new OssException("删除文件失败,请检查配置信息:[" + e.getMessage() + "]");
        }
    }
uploadSuffix  :提供字节(或者输入流) 上传文件
getObjectMetadata : 根据完整文件路径,获取文件元数据
 2- OssFactory 客户端工厂
OssClient  实例工厂。提供 有参 和 无参构造2种方式获取客户端

类位置 : com.ruoyi.oss.factory.OssFactory

三、systemApplicationRunner 初始化

实现了 ApplicationRunner  方法,项目启动后 回去执行初始化配置

package com.ruoyi.system.runner;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDictTypeService;
import com.ruoyi.system.service.ISysOssConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

/**
 * 初始化 system 模块对应业务数据
 *
 * @author Lion Li
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class SystemApplicationRunner implements ApplicationRunner {

    private final RuoYiConfig ruoyiConfig;
    private final ISysConfigService configService;
    private final ISysDictTypeService dictTypeService;
    private final ISysOssConfigService ossConfigService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        ossConfigService.init();
        log.info("初始化OSS配置成功");
        if (ruoyiConfig.isCacheLazy()) {
            return;
        }
        configService.loadingConfigCache();
        log.info("加载参数缓存数据成功");
        dictTypeService.loadingDictCache();
        log.info("加载字典缓存数据成功");
    }

}

类位置:com.ruoyi.system.service.impl.SysOssConfigServiceImpl

上传初始化操作:

 加载配置到缓存中,并设置默认值

   @Override
    public void init() {
        List<SysOssConfig> list = baseMapper.selectList();
        // 加载OSS初始化配置
        for (SysOssConfig config : list) {
            String configKey = config.getConfigKey();
            if ("0".equals(config.getStatus())) {
                RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey);
            }
            CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
        }
    }

四、上传文件接口

类位置: com.ruoyi.web.controller.system.SysOssController

 /**
     * 上传OSS对象存储
     *
     * @param file 文件
     */
    @SaCheckPermission("system:oss:upload")
    @Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Map<String, String>> upload(@RequestPart("file") MultipartFile file) {
        if (ObjectUtil.isNull(file)) {
            return R.fail("上传文件不能为空");
        }
        SysOssVo oss = iSysOssService.upload(file);
        Map<String, String> map = new HashMap<>(2);
        map.put("url", oss.getUrl());
        map.put("fileName", oss.getOriginalName());
        map.put("ossId", oss.getOssId().toString());
        return R.ok(map);
    }

五、前端页面上传文件组件定义

1-上传按钮:

路径:src\views\system\oss\index.vue

<el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleFile"
          v-hasPermi="['system:oss:upload']"
        >上传文件</el-button>
      </el-col>
 2-上传对话框:
<!-- 添加或修改OSS对象存储对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="文件名">
          <fileUpload v-model="form.file" v-if="type === 0"/>
          <imageUpload v-model="form.file" v-if="type === 1"/>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
3-定义上传文件组件 fileUpload : 

路径: src\components\FileUpload\index.vue

实现技术:

el-upload  实现该上传属性,具体api查看element官网

<template>
  <div class="upload-file">
    <el-upload
      multiple
      :action="uploadFileUrl"
      :before-upload="handleBeforeUpload"
      :file-list="fileList"
      :limit="limit"
      :on-error="handleUploadError"
      :on-exceed="handleExceed"
      :on-success="handleUploadSuccess"
      :show-file-list="false"
      :headers="headers"
      class="upload-file-uploader"
      ref="fileUpload"
    >
      <!-- 上传按钮 -->
      <el-button size="mini" type="primary">选取文件</el-button>
      <!-- 上传提示 -->
      <div class="el-upload__tip" slot="tip" v-if="showTip">
        请上传
        <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
        <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
        的文件
      </div>
    </el-upload>

    <!-- 文件列表 -->
    <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
      <li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
        <el-link :href="`${file.url}`" :underline="false" target="_blank">
          <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
        </el-link>
        <div class="ele-upload-list__item-content-action">
          <el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
        </div>
      </li>
    </transition-group>
  </div>
</template>

<script>
import { getToken } from "@/utils/auth";
import { listByIds, delOss } from "@/api/system/oss";

export default {
  name: "FileUpload",
  props: {
    // 值
    value: [String, Object, Array],
    // 数量限制
    limit: {
      type: Number,
      default: 5,
    },
    // 大小限制(MB)
    fileSize: {
      type: Number,
      default: 5,
    },
    // 文件类型, 例如['png', 'jpg', 'jpeg']
    fileType: {
      type: Array,
      default: () => ["doc", "xls", "ppt", "txt", "pdf"],
    },
    // 是否显示提示
    isShowTip: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      number: 0,
      uploadList: [],
      baseUrl: process.env.VUE_APP_BASE_API,
      uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传文件服务器地址
      headers: {
        Authorization: "Bearer " + getToken(),
      },
      fileList: [],
    };
  },
  watch: {
    value: {
      //监听    <fileUpload v-model="form.file" v-if="type === 0"/> 中  form.file 值
      async handler(val) {
        if (val) {
          let temp = 1;
          // 首先将值转为数组
          let list;
          if (Array.isArray(val)) {
            list = val;
          } else {
            await listByIds(val).then(res => {
              list = res.data.map(oss => {
                oss = { name: oss.originalName, url: oss.url, ossId: oss.ossId };
                return oss;
              });
            })
          }
          // 然后将数组转为对象数组
          this.fileList = list.map(item => {
            item = { name: item.name, url: item.url, ossId: item.ossId };
            item.uid = item.uid || new Date().getTime() + temp++;
            return item;
          });
        } else {
          this.fileList = [];
          return [];
        }
      },
      deep: true,//深入监听 
      immediate: true//组件初刷立即调用一次
    }
  },
  computed: {
    // 是否显示提示
    showTip() {
      return this.isShowTip && (this.fileType || this.fileSize);
    },
  },
  methods: {
    // 上传前校检格式和大小
    handleBeforeUpload(file) {
      // 校检文件类型
      if (this.fileType) {
        const fileName = file.name.split('.');
        const fileExt = fileName[fileName.length - 1];
        const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
        if (!isTypeOk) {
          this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
          return false;
        }
      }
      // 校检文件大小
      if (this.fileSize) {
        const isLt = file.size / 1024 / 1024 < this.fileSize;
        if (!isLt) {
          this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
          return false;
        }
      }
      this.$modal.loading("正在上传文件,请稍候...");
      this.number++;
      return true;
    },
    // 文件个数超出
    handleExceed() {
      this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
    },
    // 上传失败
    handleUploadError(err) {
      this.$modal.msgError("上传文件失败,请重试");
      this.$modal.closeLoading();
    },
    // 上传成功回调
    handleUploadSuccess(res, file) {
      if (res.code === 200) {
        this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
        this.uploadedSuccessfully();
      } else {
        this.number--;
        this.$modal.closeLoading();
        this.$modal.msgError(res.msg);
        this.$refs.fileUpload.handleRemove(file);
        this.uploadedSuccessfully();
      }
    },
    // 删除文件
    handleDelete(index) {
      let ossId = this.fileList[index].ossId;
      delOss(ossId);
      this.fileList.splice(index, 1);
      this.$emit("input", this.listToString(this.fileList));
    },
    // 上传结束处理
    uploadedSuccessfully() {
      if (this.number > 0 && this.uploadList.length === this.number) {
        this.fileList = this.fileList.concat(this.uploadList);
        this.uploadList = [];
        this.number = 0;
        this.$emit("input", this.listToString(this.fileList));
        this.$modal.closeLoading();
      }
    },
    // 获取文件名称
    getFileName(name) {
      // 如果是url那么取最后的名字 如果不是直接返回
      if (name.lastIndexOf("/") > -1) {
        return name.slice(name.lastIndexOf("/") + 1);
      } else {
        return name;
      }
    },
    // 对象转成指定字符串分隔
    listToString(list, separator) {
      let strs = "";
      separator = separator || ",";
      for (let i in list) {
        strs += list[i].ossId + separator;
      }
      return strs != "" ? strs.substr(0, strs.length - 1) : "";
    },
  },
};
</script>

<style scoped lang="scss">
.upload-file-uploader {
  margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {
  border: 1px solid #e4e7ed;
  line-height: 2;
  margin-bottom: 10px;
  position: relative;
}
.upload-file-list .ele-upload-list__item-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: inherit;
}
.ele-upload-list__item-content-action .el-link {
  margin-right: 10px;
}
</style>

路径: ruoyi-admin/src/main/resources/application.yml

后端上传文件配置:

  # 文件上传
  servlet:
    multipart:
      # 单个文件大小
      max-file-size: 10MB
      # 设置总上传的文件大小
      max-request-size: 20MB
4-组件设置为全局组件:

路径:src\main.js

Vue.component('FileUpload', FileUpload)

六、图片上传组件

路径 : src\components\ImageUpload\index.vue 

功能 :对比上面上传文件,只是多了回显功能,其他一样 

七、阿里云上传文件配置 

1-先开启 阿里云配置

2- 阿里云空控制台搜索oss 服务

3- 右上角进入  accesskey管理

创建用户,并验证。最后配置到系统

使用子账户 key(主账户key泄露比较危险,子账户随时可以关闭)

创建用户,开启api调用。之后手机短信验证

这里复制 key,

 保存上面key

4-创建桶

5-配置上面桶的信息

八、测试阿里云

上传文件报错; 提示没有权限 you have not right access 

   accesskey管理 中设置权限

再次测试上传:成功

九、自定义域名访问文件

绑定域名后就可以用自己的域名来访问图片。

注意:

要在自己域名网站配置CNAME

如果配置https,可以去宝塔或者腾讯登申请免费证书陪配置(否则访问不到文件)

 绑定域名配置在 自定义域名

 

十、腾讯云配置 OSS文件上传

步骤同上面 七 :阿里云配置一样。腾讯云点击左上角搜索 对象存储

唯一不同的注意点:

上传提示错误 :Access Denied. (Service Amazon  s3: Status 403 ;Error code :Access Denied。。。

是域一定要配置 ,阿里云则默认可以为空

        

十一、七牛云配置文件上传

1-开启七牛云配置

 2-找到对象存储

3-新建桶 :(七牛有效期30天)

4-基础配置中查看s3域名 ,复制里面的 Endpoint,到若依文件配置的 访问站点。空间授权(只读 和 读写看下) 

  

5- 测试域名设置为我们的 自定义域名(七牛云免费自带)

 6-右上角秘钥管理设置我们的  AccessKey/SecretKey

测试上传成功

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果想将ruoyi-vue-plus项目中的文件上传至本地,可以按照以下步骤进行操作: 1. 首先,确保你已经成功搭建并运行了ruoyi-vue-plus项目,保证项目正常运行。 2. 在ruoyi-vue-plus项目的前端代码中,找到与文件上传相关的功能模块。通常,文件上传的代码会位于项目的"src/views"目录或者相关子目录中。 3. 打开相关文件,找到文件上传的逻辑代码。一般来说,文件上传功能会使用到Vue的组件和相关的API。你可以通过搜索关键词如"文件上传"、"upload"等来快速定位到相关代码。 4. 配置上传的目标路径。一般情况下,上传的文件会被保存在服务器的某个目录下。你需要查阅ruoyi-vue-plus项目的相关文档或代码,找到文件上传的目标路径配置项,一般是在项目的配置文件中。 5. 修改目标路径为本地路径。将目标路径的配置项修改为你想要保存文件的本地路径。确保该路径是本地文件系统中存在的,并且具备操作权限。 6. 保存修改并重新编译运行ruoyi-vue-plus项目。确保项目启动成功。 7. 现在,当你进行文件上传操作时,文件将会被上传至你所配置的本地路径中。 请注意,将文件上传至本地需要确保你的本地环境拥有足够的存储空间和相关权限。另外,该操作可能会导致项目的其他功能无法正常运行,请谨慎操作,并备份好原先的项目文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值