SpringCloud Alibaba-OSS

一:SpringCloud Alibaba-OSS

云存储

优点:即开即用,无需维护,按量收费
在这里插入图片描述

1.简介

对象存储服务(Object Storage Service,OSS)是一种海量、安全、低成本、高可靠的云存储 服务,适合存放任意类型的文件。容量和处理能力弹性扩展,多种存储类型供选择,全面优 化存储成本。

2.基本概念

1)存储空间(Bucket)
存储空间是用户用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间。存储空间具有各种配置属性,包括地域、访问权限、存储类型等。用户可以根据实际需求,创建不同类型的存储空间来存储不同的数据。

  • 同一个存储空间的内部是扁平的,没有文件系统的目录等概念,所有的对象都直接隶属于其对应的存储空间。
  • 每个用户可以拥有多个存储空间。
  • 存储空间的名称在OSS范围内必须是全局唯一的,一旦创建之后无法修改名称。
  • 存储空间内部的对象数目没有限制。

存储空间的命名规范如下:

  • 只能包括小写字母、数字和短划线(-)。
  • 必须以小写字母或者数字开头和结尾。
  • 长度必须在3~63字符之间。

2)对象(Object)
对象是OSS存储数据的基本单元,也被称为OSS的文件。和传统的文件系统不同,对象没有文件目录层级结构的关系。对象由元信息(Object Meta),用户数据(Data)和文件名(Key)组成,并且由存储空间内部唯一的Key来标识。对象元信息是一组键值对,表示了对象的一些属性,比如最后修改时间、大小等信息,同时用户也可以在元信息中存储一些自定义的信息。
对象的生命周期是从上传成功到被删除为止。在整个生命周期内,除通过追加方式上传的Object可以通过继续追加上传写入数据外,其他方式上传的Object内容无法编辑,您可以通过重复上传同名的对象来覆盖之前的对象。
对象的命名规范如下:

  • 使用UTF-8编码。
  • 长度必须在1~1023字符之间。
  • 不能以正斜线(/)或者反斜线(\)开头。

说明 对象名称需要区分大小写。如无特殊说明,本文档中的对象、文件称谓等同于Object。
3)ObjectKey
在各语言SDK中,ObjectKey、Key以及ObjectName是同一概念,均表示对Object执行相关操作时需要填写的Object名称。例如向某一存储空间上传Object时,ObjectKey表示上传的Object所在存储空间的完整名称,即包含文件后缀在内的完整路径,如填写为abc/efg/123.jpg。

4)Region(地域)
Region表示OSS的数据中心所在物理位置。用户可以根据费用、请求来源等选择合适的地域创建Bucket。一般来说,距离用户更近的Region访问速度更快。详情请参见OSS已经开通的Region。

Region是在创建Bucket的时候指定的,一旦指定之后就不允许更改。该Bucket下所有的Object都存储在对应的数据中心,目前不支持Object级别的Region设置。

5)Endpoint(访问域名)
Endpoint表示OSS对外服务的访问域名。OSS以HTTP RESTful API的形式对外提供服务,当访问不同的Region的时候,需要不同的域名。通过内网和外网访问同一个Region所需要的Endpoint也是不同的。例如杭州Region的外网Endpoint是oss-cn-hangzhou.aliyuncs.com,内网Endpoint是oss-cn-hangzhou-internal.aliyuncs.com。具体的内容请参见各个Region对应的Endpoint。

6)AccessKey(访问密钥)
AccessKey简称AK,指的是访问身份验证中用到的AccessKeyId和AccessKeySecret。OSS通过使用AccessKeyId和AccessKeySecret对称加密的方法来验证某个请求的发送者身份。AccessKeyId用于标识用户;AccessKeySecret是用户用于加密签名字符串和OSS用来验证签名字符串的密钥,必须保密。对于OSS来说,AccessKey的来源有:

  • Bucket的拥有者申请的AccessKey。
  • 被Bucket的拥有者通过RAM授权给第三方请求者的AccessKey。
  • 被Bucket的拥有者通过STS授权给第三方请求者的AccessKey。
    更多AccessKey介绍请参见获取AccessKey。
    在这里插入图片描述

3.使用步骤

1)开通阿里云对象存储服务
在这里插入图片描述
在这里插入图片描述

2)创建一个Bucket
在这里插入图片描述
在这里插入图片描述
3)上传方式

  • 普通上传
    在这里插入图片描述
    缺点:需要通过本地服务器才能上传到阿里云服务器,占用本地空间
  • 服务端签名后直传
    在这里插入图片描述
    特点:在本地服务器配置好阿里云账号和密码生成一个密钥,同时带上上传的文件,传递到云服务器。阿里云验证以后就可以进行上传。可以不让文件先过服务器,提高效率。所以我们使用这种方式。

4.代码实现

方式一:使用阿里云
1)安装SDK,复制到gulimail-product的pom文件中

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.5.0</version>
</dependency>

2)如果使用的是Java 9及以上的版本,则需要添加jaxb相关依赖。添加jaxb相关依赖示例代码如下:

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.3</version>
</dependency>

3)上传文件流-复制到test文件中测试

    @Test
    public void testUpload() throws FileNotFoundException {
        String endpoint = "666666666";
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "nicai";
        String accessKeySecret = "hahahahah";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "gulimail-sysg";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "9fd2d359e5ba952fe2e112476fd3a83.jpg";
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
        String filePath= "E:\\个人资料\\images\\9fd2d359e5ba952fe2e112476fd3a83.jpg";
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        InputStream inputStream = new FileInputStream(filePath);
        // 创建PutObject请求。
        ossClient.putObject(bucketName, objectName, inputStream);
        //关闭OSSClient
        ossClient.shutdown();
        System.out.println("上传完成");
    }
  • endpoint 在阿里云首页自行复制
    在这里插入图片描述
  • accessKeyId和accessKeySecret需要我们开通子账户
    在这里插入图片描述
    注:记得添加权限
  • bucketName你存储空间的名字——gulimail-sysg
  • objectName对象的名字——上传文件名称

方式二:使用SpringCloud Alibaba组件
1)引入 SpringCloud Alibaba-OSS
在gulimail-commom的pom文件中引入

<dependency> 
   <groupId>com.alibaba.cloud</groupId> 
   <artifactId>spring-cloud-alicloud-oss</artifactId> 
</dependency>

2)在application.yml中配置阿里云 oss 相关的账号信息

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://127.0.0.1:3306/gulimail_pms?serverTimezone=GMT%2B8
    driver-class-name: com.mysql.jdbc.Driver
  cloud:
    #nacos地址
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    #阿里云的子系统用户名和密码
    alicloud:
      access-key: wobugaosuni
      secret-key: jiushibugaosuni
      oss:
        endpoint: zijiqufuzhi

3)在test注入OSSClient对象

    @Autowired
    private OSSClient ossClient;
    @Test
    public void testUpload() throws FileNotFoundException {
        String bucketName = "gulimail-sysg";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "9fd2d359e5ba952fe2e112476fd3a83.jpg";
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
        String filePath = "E:\\个人资料\\images\\9fd2d359e5ba952fe2e112476fd3a83.jpg";
        // 创建OSSClient实例。
        //OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        InputStream inputStream = new FileInputStream(filePath);
        // 创建PutObject请求。
        ossClient.putObject(bucketName, objectName, inputStream);
        //关闭OSSClient
        ossClient.shutdown();
        System.out.println("上传完成");
    }

4)步骤总结

  • 1.引入oss-stater
  • 2.配置key,endpoint相关信息
  • 3.使用OSSClient 进行相关操作

二 :第三方服务之gulimail-third-party

随后的开发中会有很多第三方服务进行使用,例如发短信,对象存储,查物流等,所以我们新建一个微服务来整合第三方功能。

1.新建gulimail-third-party服务,用来当作第三方服务

在这里插入图片描述

2.修改pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.sysg.gulimail</groupId>
    <artifactId>gulimail-third-party</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gulimail-third-party</name>
    <description>第三方服务</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.RC1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.sysg.gulimail</groupId>
            <artifactId>gulimail-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>
</project>

注:将common的oss依赖删除掉,否则会依赖冲突

3.新建bootstrap.properties文件,配置nacos

#应用名称
spring.application.name=gulimail-third-party
#注册发现中心地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
#配置命名空间
spring.cloud.nacos.config.namespace=942d733c-14da-46ab-b70b-fe848b663f92

#拓展配置
#data-id
spring.cloud.nacos.config.ext-config[0].data-id=oss.yml
##分组
spring.cloud.nacos.config.ext-config[0].group=DEFAULT_GROUP
##动态刷新
spring.cloud.nacos.config.ext-config[0].refresh=true

4.在nacos配置中心添加gulimail-third-party相关配置

1)点击命名空间,新增
在这里插入图片描述
2)查看命名空间的ID,复制到bootstrap.properties中
3)在配置列表新增oss.yml
在这里插入图片描述
4)在src/main/resources新建application.yml文件

#数据源
spring:
  cloud:
    #nacos地址
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    #阿里云的子系统用户名和密码
    alicloud:
      access-key: dqjdoqwhdoqwdwdwd
      secret-key: vkdwvoiwnvowenvwvvv
      oss:
        endpoint: oss-cn-chengdu.aliyuncs.com
  #服务的名称,用于让nacos知道那个服务正在被调用
  application:
    name: gulimail-third-party
#端口
server:
  port: 30000

注:在gulimail-third-party的pom文件中排除掉mybatis相关依赖

 <dependency>
        <groupId>com.sysg.gulimail</groupId>
        <artifactId>gulimail-common</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <exclusions>
            <exclusion>
                <groupId>com.baomidou</groupId>
                <artifactId>com.baomidou:mybatis-plus-boot-starter:3.5.1</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

5)在其主启动类添加@EnableDiscoveryClient注解,开启服务的注册发现功能

package com.sysg.gulimail.thirdparty;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class GulimailThirdPartyApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimailThirdPartyApplication.class, args);
    }

}

三:OSS获取服务端签名

1.在application.yml文件添加配置

#数据源
spring:
  cloud:
    #nacos地址
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    #阿里云的子系统用户名和密码
    alicloud:
      access-key: LTAI1515155tFkaa8MBcscs5R71KtoZ5dh
      secret-key: disccwClqm4csmFQIZtf4cc7fqYKz5
      oss:
        endpoint: oss-cn-chengdu.aliyuncs.com
        bucket: gulimail-sysg
  #服务的名称,用于让nacos知道那个服务正在被调用
  application:
    name: gulimail-third-party
#端口
server:
  port: 30000

2.新建OssController

package com.sysg.gulimail.thirdparty.controller;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 对象存储
 * @author 77916
 */
@RestController
public class OssController {

    @Autowired
    private OSS ossClient;
    /**
     * 动态获取application.yml中的endpoint
     */
    @Value("${spring.cloud.alicloud.oss.endpoint}")
    private String endpoint;
    /**
     * 动态获取application.yml中的bucket
     */
    @Value("${spring.cloud.alicloud.oss.bucket}")
    private String bucket;
    /**
     * 动态获取application.yml中的accessId
     */
    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;
    /**
     * 获取签名的方法
     * @ResponseBody-将返回的数据转化为json,传递给浏览器
     */
    @RequestMapping("/oss/policy")
    public R policy(){
        // 填写Host名称,格式为https://bucketname.endpoint。"https://examplebucket.oss-cn-hangzhou.aliyuncs.com";
        String host = "https://" + bucket + "." + endpoint;
        // 设置上传回调URL,即回调服务器地址,用于处理应用服务器与OSS之间的通信。OSS会在文件上传完成后,把文件上传信息通过此回调URL发送给应用服务器。
        //String callbackUrl = "https://192.168.0.0:8888";
        // 设置上传到OSS文件的前缀,可置空此项。置空后,文件将上传至Bucket的根目录下。此时我们用日期作为文件夹名称
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String date = format.format(new Date());
        String dir = date + "/";
        Map<String, String> respMap = null;
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            // PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
            PolicyConditions policyConds = new PolicyConditions();
            //"content-length-range"
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            //PolicyConditions.COND_KEY--key
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);
            respMap = new LinkedHashMap<String, String>();
            respMap.put("accessid", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
            // respMap.put("expire", formatISO8601Date(expiration));
        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return R.ok().put("data", respMap);
    }
}

3.发送请求测试接口

http://localhost:30000/oss/policy

在这里插入图片描述
总结:以后要上传文件,我们就需要浏览器访问这个接口获取数据,然后将获取的数据和文件一起传输到云存储空间。

4.配置网关

http://localhost:88/api/thirdparty/oss/policy

1)编辑gulimail-gateway的application.yml文件,添加路由配置

spring:
  cloud:
    gateway:
      routes:
        - id: product_route
          uri: lb://gulimail-product
          predicates:
            - Path=/api/product/**
          filters:
            - RewritePath=/api/(?<segment>.*),/$\{segment}

        - id: third_party_route
          uri: lb://gulimail-third-party
          predicates:
            - Path=/api/thirdparty/**
          filters:
            - RewritePath=/api/thirdparty/(?<segment>.*),/$\{segment}

2)重启gulimail-gateway项目
在这里插入图片描述

四:前端项目实现文件上传功能

1.新建multiUpload.vue文件实现多文件上传

<template>
  <div>
    <el-upload
      action="http://gulimail-sysg.oss-cn-chengdu.aliyuncs.com"
      :data="dataObj"
      list-type="picture-card"
      :file-list="fileList"
      :before-upload="beforeUpload"
      :on-remove="handleRemove"
      :on-success="handleUploadSuccess"
      :on-preview="handlePreview"
      :limit="maxCount"
      :on-exceed="handleExceed"
    >
      <i class="el-icon-plus"></i>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt />
    </el-dialog>
  </div>
</template>
<script>
import { policy } from "./policy";
import { getUUID } from '@/utils'
export default {
  name: "multiUpload",
  props: {
    //图片属性数组
    value: Array,
    //最大上传图片数量
    maxCount: {
      type: Number,
      default: 30
    }
  },
  data() {
    return {
      dataObj: {
        policy: "",
        signature: "",
        key: "",
        ossaccessKeyId: "",
        dir: "",
        host: "",
        uuid: ""
      },
      dialogVisible: false,
      dialogImageUrl: null
    };
  },
  computed: {
    fileList() {
      let fileList = [];
      for (let i = 0; i < this.value.length; i++) {
        fileList.push({ url: this.value[i] });
      }

      return fileList;
    }
  },
  mounted() {},
  methods: {
    emitInput(fileList) {
      let value = [];
      for (let i = 0; i < fileList.length; i++) {
        value.push(fileList[i].url);
      }
      this.$emit("input", value);
    },
    handleRemove(file, fileList) {
      this.emitInput(fileList);
    },
    handlePreview(file) {
      this.dialogVisible = true;
      this.dialogImageUrl = file.url;
    },
    beforeUpload(file) {
      let _self = this;
      return new Promise((resolve, reject) => {
        policy()
          .then(response => {
            console.log("这是什么${filename}");
            _self.dataObj.policy = response.data.policy;
            _self.dataObj.signature = response.data.signature;
            _self.dataObj.ossaccessKeyId = response.data.accessid;
            _self.dataObj.key = response.data.dir + "/"+getUUID()+"_${filename}";
            _self.dataObj.dir = response.data.dir;
            _self.dataObj.host = response.data.host;
            resolve(true);
          })
          .catch(err => {
            console.log("出错了...",err)
            reject(false);
          });
      });
    },
    handleUploadSuccess(res, file) {
      this.fileList.push({
        name: file.name,
        // url: this.dataObj.host + "/" + this.dataObj.dir + "/" + file.name; 替换${filename}为真正的文件名
        url: this.dataObj.host + "/" + this.dataObj.key.replace("${filename}",file.name)
      });
      this.emitInput(this.fileList);
    },
    handleExceed(files, fileList) {
      this.$message({
        message: "最多只能上传" + this.maxCount + "张图片",
        type: "warning",
        duration: 1000
      });
    }
  }
};
</script>
<style>
</style>

2.新建singleUpload.vue文件实现多文件上传

<template> 
  <div>
    <el-upload
      action="http://gulimail-sysg.oss-cn-chengdu.aliyuncs.com"
      :data="dataObj"
      list-type="picture"
      :multiple="false" :show-file-list="showFileList"
      :file-list="fileList"
      :before-upload="beforeUpload"
      :on-remove="handleRemove"
      :on-success="handleUploadSuccess"
      :on-preview="handlePreview">
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过10MB</div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="fileList[0].url" alt="">
    </el-dialog>
  </div>
</template>
<script>
   import {policy} from './policy'
   import { getUUID } from '@/utils'

  export default {
    name: 'singleUpload',
    props: {
      value: String
    },
    computed: {
      imageUrl() {
        return this.value;
      },
      imageName() {
        if (this.value != null && this.value !== '') {
          return this.value.substr(this.value.lastIndexOf("/") + 1);
        } else {
          return null;
        }
      },
      fileList() {
        return [{
          name: this.imageName,
          url: this.imageUrl
        }]
      },
      showFileList: {
        get: function () {
          return this.value !== null && this.value !== ''&& this.value!==undefined;
        },
        set: function (newValue) {
        }
      }
    },
    data() {
      return {
        dataObj: {
          policy: '',
          signature: '',
          key: '',
          ossaccessKeyId: '',
          dir: '',
          host: '',
          // callback:'',
        },
        dialogVisible: false
      };
    },
    methods: {
      emitInput(val) {
        this.$emit('input', val)
      },
      handleRemove(file, fileList) {
        this.emitInput('');
      },
      handlePreview(file) {
        this.dialogVisible = true;
      },
      beforeUpload(file) {
        let _self = this;
        return new Promise((resolve, reject) => {
          policy().then(response => {
            _self.dataObj.policy = response.data.policy;
            _self.dataObj.signature = response.data.signature;
            _self.dataObj.ossaccessKeyId = response.data.accessid;
            _self.dataObj.key = response.data.dir + getUUID()+'_${filename}';
            _self.dataObj.dir = response.data.dir;
            _self.dataObj.host = response.data.host;
            resolve(true)
          }).catch(err => {
            reject(false)
          })
        })
      },
      handleUploadSuccess(res, file) {
        console.log("上传成功...")
        this.showFileList = true;
        this.fileList.pop();
        this.fileList.push({name: file.name, url: this.dataObj.host + '/' + this.dataObj.key.replace("${filename}",file.name) });
        this.emitInput(this.fileList[0].url);
      }
    }
  }
</script>
<style>
</style>

3.新建policy.js返回密钥

import http from "@/utils/httpRequest.js";
export function policy() {
  return new Promise((resolve, reject) => {
    http({
      url: http.adornUrl("/thirdparty/oss/policy"),
      method: "get",
      params: http.adornParams({})
    }).then(({ data }) => {
      resolve(data);
    });
  });
}

注:这三个文件统一放在upload文件夹里面,将upload放在src\components下
在这里插入图片描述

4.引入文件上传组件

1)在brand-add-or-update.vue页面,引入文件上传组件

import SingleUpload from "@/components/upload/singleUpload"
  • SingleUpload 为引入文件取得别名
  • @/为src下的所有文件

2)在品牌logo地址的el-form-item标签中引入SingleUpload标签

<template>
  <el-dialog
    :title="!dataForm.brandId ? '新增' : '修改'"
    :close-on-click-modal="false"
    :visible.sync="visible"
  >
    <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()"
      label-width="120px"
    >
      <el-form-item label="品牌名" prop="name">
        <el-input v-model="dataForm.name" placeholder="品牌名"></el-input>
      </el-form-item>
      <el-form-item label="品牌logo地址" prop="logo">
        <!-- <el-input v-model="dataForm.logo" placeholder="品牌logo地址"></el-input> -->
        <SingleUpload v-model="dataForm.logo" ></SingleUpload>
      </el-form-item>
      <el-form-item label="介绍" prop="descript">
        <el-input v-model="dataForm.descript" placeholder="介绍"></el-input>
      </el-form-item>
      <el-form-item label="显示状态" prop="showStatus">
        <el-switch
          v-model="dataForm.showStatus"
          active-color="#13ce66"
          inactive-color="#ff4949"
        >
        </el-switch>
      </el-form-item>
      <el-form-item label="检索首字母" prop="firstLetter">
        <el-input
          v-model="dataForm.firstLetter"
          placeholder="检索首字母"
        ></el-input>
      </el-form-item>
      <el-form-item label="排序" prop="sort">
        <el-input v-model="dataForm.sort" placeholder="排序"></el-input>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="visible = false">取消</el-button>
      <el-button type="primary" @click="dataFormSubmit()">确定</el-button>
    </span>
  </el-dialog>
</template>

<script>
import SingleUpload from "@/components/upload/singleUpload"
export default {
  /**
   * 组件引入
   */
  components: { 
    //引入SingleUpload组件
    SingleUpload:SingleUpload
  },
  data() {
    return {
      visible: false,
      dataForm: {
        brandId: 0,
        name: "",
        logo: "",
        descript: "",
        showStatus: "",
        firstLetter: "",
        sort: ""
      },
      dataRule: {
        name: [{ required: true, message: "品牌名不能为空", trigger: "blur" }],
        logo: [
          { required: true, message: "品牌logo地址不能为空", trigger: "blur" }
        ],
        descript: [
          { required: true, message: "介绍不能为空", trigger: "blur" }
        ],
        showStatus: [
          {
            required: true,
            message: "显示状态[0-不显示;1-显示]不能为空",
            trigger: "blur"
          }
        ],
        firstLetter: [
          { required: true, message: "检索首字母不能为空", trigger: "blur" }
        ],
        sort: [{ required: true, message: "排序不能为空", trigger: "blur" }]
      }
    };
  },
  methods: {
    init(id) {
      this.dataForm.brandId = id || 0;
      this.visible = true;
      this.$nextTick(() => {
        this.$refs["dataForm"].resetFields();
        if (this.dataForm.brandId) {
          this.$http({
            url: this.$http.adornUrl(
              `/product/brand/info/${this.dataForm.brandId}`
            ),
            method: "get",
            params: this.$http.adornParams()
          }).then(({ data }) => {
            if (data && data.code === 0) {
              this.dataForm.name = data.brand.name;
              this.dataForm.logo = data.brand.logo;
              this.dataForm.descript = data.brand.descript;
              this.dataForm.showStatus = data.brand.showStatus;
              this.dataForm.firstLetter = data.brand.firstLetter;
              this.dataForm.sort = data.brand.sort;
            }
          });
        }
      });
    },
    // 表单提交
    dataFormSubmit() {
      this.$refs["dataForm"].validate(valid => {
        if (valid) {
          this.$http({
            url: this.$http.adornUrl(
              `/product/brand/${!this.dataForm.brandId ? "save" : "update"}`
            ),
            method: "post",
            data: this.$http.adornData({
              brandId: this.dataForm.brandId || undefined,
              name: this.dataForm.name,
              logo: this.dataForm.logo,
              descript: this.dataForm.descript,
              showStatus: this.dataForm.showStatus,
              firstLetter: this.dataForm.firstLetter,
              sort: this.dataForm.sort
            })
          }).then(({ data }) => {
            if (data && data.code === 0) {
              this.$message({
                message: "操作成功",
                type: "success",
                duration: 1500,
                onClose: () => {
                  this.visible = false;
                  this.$emit("refreshDataList");
                }
              });
            } else {
              this.$message.error(data.msg);
            }
          });
        }
      });
    }
  }
};
</script>

注:的SingleUpload为import中起的名字
3)将上传文件修改为可以跨域访问
在这里插入图片描述

  • 首先进入阿里云
    在这里插入图片描述
  • 点击跨域访问设置
    在这里插入图片描述
  • 然后点击文件上传
    在这里插入图片描述
  • 进入阿里云查看是否上传成功
    在这里插入图片描述
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
对于启动报错的问题,根据您提供的引用内容,您可能需要检查以下几个方面来解决问题: 1. 首先,您需要确保您的pom.xml文件中已经正确引入了依赖项spring-cloud-starter-alicloud-oss。请检查您的pom.xml文件,确认是否有以下配置: ``` <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alicloud-oss</artifactId> </dependency> ``` 确保该依赖项的配置正确并且没有拼写错误。 2. 其次,您还需要检查您的版本信息是否匹配。根据引用中的信息,您可能需要确保您的版本信息如下: ``` spring boot: 2.6.6 spring cloud: 2021.0.1 spring cloud alibaba: 2021.0.1.0 aliyun-spring-boot-dependencies: 1.0.0 ``` 请检查您的版本信息并确认与您的依赖项配置一致。 3. 此外,根据引用和引用的信息,您还需要检查您是否在公共项目gulimall-common中引入了aliyun-oss-spring-boot-starter依赖项。请检查您的gulimall-common项目的pom.xml文件,确认是否有以下配置: ``` <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>aliyun-oss-spring-boot-starter</artifactId> </dependency> ``` 确保该依赖项的配置正确并且没有拼写错误。 综上所述,如果您的spring-cloud-starter-alicloud-oss启动报错,您可以检查pom.xml文件中的依赖项配置、版本信息以及公共项目中的依赖项配置,确保它们正确无误。希望这些信息对您有帮助。如果问题仍然存在,请参考阿里云官方文档或相关资源进行更深入的排查。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【个人记录】阿里云OSS简化依赖[spring-cloud-starter-alicloud-oss]](https://blog.csdn.net/ykx____h/article/details/108918474)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Spring Boot 项目导入 aliyun oss starter 依赖后启动报错的解决方案](https://blog.csdn.net/weixin_48084293/article/details/124075055)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随意石光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值