當(dāng)前位置:首頁 > IT技術(shù) > Web編程 > 正文

Vue Bootstrap OSS 實現(xiàn)文件上傳
2022-09-06 22:56:22


Vue Bootstrap OSS 實現(xiàn)文件上傳_vue.js


Vue Bootstrap OSS 實現(xiàn)文件上傳_文件上傳_02

Vue Bootstrap OSS 實現(xiàn)文件上傳_文件上傳_03

公司實現(xiàn)文件上傳技術(shù)選型采用后端SpringBoot/Cloud,前端vue Bootstrap ,阿里云OSS作為文件存儲,文件上傳功能單獨抽取封裝文件上傳組件,可供所有的文件的操作。

后端框架

版本

SpringBoot

2.5.6

Spring-Cloud

2020.0.4

mysql

8.0.26

pagehelper

1.3.1

Mybatis

2.2.0

Redis

5.0

Fastjson

1.2.78

前端框架

版本

Vue

2.6.11

axios

0.24.0

vue-router

3.5.3

Bootstrap

4.6.2

文章目錄

一、前端部分
1. 講師頁面

講師頁面作為文件上傳父頁面

<div class="form-group">
<label class="col-sm-2 control-label">頭像</label>
<div class="col-sm-10">
<file v-bind:input-id="'image-upload'"
v-bind:text="'上傳頭像'"
v-bind:suffixs="['jpg', 'jpeg', 'png']"
v-bind:use="FILE_USE.TEACHER.key"
v-bind:after-upload="afterUpload"></file>
<div v-show="teacher.image" class="row">
<div class="col-md-4">
<img v-bind:src="teacher.image" class="img-responsive">
</div>
</div>

</div>
</div>
2. js部分
<script>
import File from "../../components/file";
export default {
components: {Pagination, BigFile,File},
name: "business-teacher",
data: function () {
return {
teacher: {},
teachers: [],
FILE_USE: FILE_USE,
}
},

methods: {
/**
* 點擊【新增】
*/
add() {
let _this = this;
_this.teacher = {};
$("#form-modal").modal("show");
},

/**
* 點擊【編輯】
*/
edit(teacher) {
let _this = this;
_this.teacher = $.extend({}, teacher);
$("#form-modal").modal("show");
},

/**
* 列表查詢
*/
list(page) {
let _this = this;
Loading.show();
_this.$api.post(process.env.VUE_APP_SERVER + '/business/admin/teacher/list', {
page: page,
size: _this.$refs.pagination.size,
}).then((response) => {
Loading.hide();
let resp = response.data;
_this.teachers = resp.content.list;
_this.$refs.pagination.render(page, resp.content.total);

})
},

/**
* 點擊【保存】
*/
save() {
let _this = this;

// 保存校驗
if (1 != 1
|| !Validator.require(_this.teacher.name, "姓名")
|| !Validator.length(_this.teacher.name, "姓名", 1, 50)
|| !Validator.length(_this.teacher.nickname, "昵稱", 1, 50)
|| !Validator.length(_this.teacher.image, "頭像", 1, 100)
|| !Validator.length(_this.teacher.position, "職位", 1, 50)
|| !Validator.length(_this.teacher.motto, "座右銘", 1, 50)
|| !Validator.length(_this.teacher.intro, "簡介", 1, 500)
) {
return;
}

Loading.show();
_this.$api.post(process.env.VUE_APP_SERVER + '/business/admin/teacher/save', _this.teacher).then((response) => {
Loading.hide();
let resp = response.data;
if (resp.success) {
$("#form-modal").modal("hide");
_this.list(1);
Toast.success("保存成功!");
} else {
Toast.warning(resp.message)
}
})
},
afterUpload(resp) {
let _this = this
let image = resp.content.path;
_this.teacher.image = image
}
}
}
</script>
3. 文件上傳組件
<template>
<div>
<button type="button" v-on:click="selectFile()" class="btn btn-white btn-default btn-round">
<i class="ace-icon fa fa-upload"></i>
{{text}}
</button>
<input class="hidden" type="file" ref="file" v-on:change="uploadFile()" v-bind:id="inputId+'-input'">
</div>a
</template>

<script>
export default {
name: 'file',
props: {
text: {
default: "上傳文件"
},
inputId: {
default: "file-upload"
},
suffixs: {
default: []
},
use: {
default: ""
},
afterUpload: {
type: Function,
default: null
},
},
data: function () {
return {
}
},
methods: {
uploadFile () {
let _this = this;
let formData = new window.FormData();
let file = _this.$refs.file.files[0];

// 判斷文件格式
let suffixs = _this.suffixs;
let fileName = file.name;
let suffix = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length).toLowerCase();
let validateSuffix = false;
for (let i = 0; i < suffixs.length; i++) {
if (suffixs[i].toLowerCase() === suffix) {
validateSuffix = true;
break;
}
}
if (!validateSuffix) {
Toast.warning("文件格式不正確!只支持上傳:" + suffixs.join(","));
$("#" + _this.inputId + "-input").val("");
return;
}

// key:"file"必須和后端controller參數(shù)名一致
formData.append('file', file);
formData.append('use', _this.use);
Loading.show()
_this.$api.post(process.env.VUE_APP_SERVER + '/file/admin/oss-simple', formData).then((response) => {
Loading.hide()

let resp = response.data
console.log("上傳文件成功:", resp)

//回調(diào)父組件函數(shù)
_this.afterUpload(resp)

//解決 同一個文件上傳2次或者大于3次,不會發(fā)生變化
$("#" + _this.inputId + "-input").val("");
})
},

selectFile() {
let _this = this
// console.log("_this.inputId",_this.inputId)
$("#" + _this.inputId + "-input").trigger("click");
}
},
}
</script>

<style scoped>
</style>
二、阿里云OSS

官網(wǎng):??https://www.aliyun.com??

2.1. 注冊阿里云

??https://account.aliyun.com/register/register.htm??

Vue Bootstrap OSS 實現(xiàn)文件上傳_文件上傳_04

2.2. 開通OSS

Vue Bootstrap OSS 實現(xiàn)文件上傳_文件上傳_05


Vue Bootstrap OSS 實現(xiàn)文件上傳_vue.js_06

2.3. 進(jìn)入管控臺

Vue Bootstrap OSS 實現(xiàn)文件上傳_vue.js_07


Vue Bootstrap OSS 實現(xiàn)文件上傳_bootstrap_08

2.4. 創(chuàng)建 Bucket

Vue Bootstrap OSS 實現(xiàn)文件上傳_vue.js_09

讀寫權(quán)限選擇【公共讀】,意思是都可以或者有權(quán)限看,沒其他特殊請求,其他的保持默認(rèn),點擊確定即可

Vue Bootstrap OSS 實現(xiàn)文件上傳_vue.js_10


Vue Bootstrap OSS 實現(xiàn)文件上傳_spring boot_11

2.5. 創(chuàng)建OSS用戶

Vue Bootstrap OSS 實現(xiàn)文件上傳_spring_12


或者

Vue Bootstrap OSS 實現(xiàn)文件上傳_文件上傳_13


Vue Bootstrap OSS 實現(xiàn)文件上傳_spring_14


Vue Bootstrap OSS 實現(xiàn)文件上傳_vue.js_15

2.6. OSS權(quán)限

Vue Bootstrap OSS 實現(xiàn)文件上傳_spring boot_16


Vue Bootstrap OSS 實現(xiàn)文件上傳_spring_17

三、OSS Client開發(fā)文檔

??https://www.aliyun.com/product/oss??

3.1. OSS Client SDK

開發(fā)語言java,簡單文上傳

Vue Bootstrap OSS 實現(xiàn)文件上傳_文件上傳_18


Vue Bootstrap OSS 實現(xiàn)文件上傳_vue.js_19

3.2. 概述

Vue Bootstrap OSS 實現(xiàn)文件上傳_vue.js_20

3.3. SDK Client

這里就是官網(wǎng)提供的java語言的SDK Client

Vue Bootstrap OSS 實現(xiàn)文件上傳_spring boot_21

四、后端部分

??https://help.aliyun.com/document_detail/32009.html??

4.1.依賴引入

Vue Bootstrap OSS 實現(xiàn)文件上傳_vue.js_22

<!-- OSS Java SDK -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
4.2. 配置
# 應(yīng)用名稱
spring.application.name=file
# 應(yīng)用端口
server.port=9003
# 注冊到eureka
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

# 請求訪問前綴
server.servlet.context-path=/file

# 本地存儲靜態(tài)文件路徑
file.path=D:/file/imooc/course/
# 訪問靜態(tài)文件路徑(用于文件回顯或者文件下載)
file.domain=http://127.0.0.1:9000/file/f/

# 文件大?。ㄈ绻罱ù笮〕^此配置的大小或拋出異常)
spring.servlet.multipart.max-file-size=50MB
# 請求大小
spring.servlet.multipart.max-request-size=50MB


# OSS 配置
oss.accessKeyId=xxx
oss.accessKeySecret=xxx
oss.endpoint=http://oss-cn-beijing.aliyuncs.com
oss.ossDomain=http://bucket名稱.oss-cn-beijing.aliyuncs.com/
oss.bucket=xxx
  • oss.endpoint 和oss.ossDomain獲取方式
  • Vue Bootstrap OSS 實現(xiàn)文件上傳_vue.js_23

  • bucket 獲取方式
  • Vue Bootstrap OSS 實現(xiàn)文件上傳_文件上傳_24

  • oss.accessKeyId和oss.accessKeySecret獲取方式

Vue Bootstrap OSS 實現(xiàn)文件上傳_spring_25


Vue Bootstrap OSS 實現(xiàn)文件上傳_spring_26


Vue Bootstrap OSS 實現(xiàn)文件上傳_文件上傳_27

4.3. api接口
package com.course.file.controller;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.AppendObjectRequest;
import com.aliyun.oss.model.AppendObjectResult;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.vod.model.v20170321.GetMezzanineInfoResponse;
import com.course.server.dto.FileDto;
import com.course.server.dto.ResponseDto;
import com.course.server.enums.FileUseEnum;
import com.course.server.service.FileService;
import com.course.server.util.Base64ToMultipartFile;
import com.course.server.util.UuidUtil;
import com.course.server.util.VodUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;

@RequestMapping("/admin")
@RestController
public class OssController {
public static final Logger LOG = LoggerFactory.getLogger(OssController.class);
public static final String BUSINESS_NAME = "文件上傳";

@Value("${oss.accessKeyId}")
private String accessKeyId;

@Value("${oss.accessKeySecret}")
private String accessKeySecret;

@Value("${oss.endpoint}")
private String endpoint;

@Value("${oss.bucket}")
private String bucket;

@Value("${oss.ossDomain}")
private String ossDomain;


/**
* oss簡單上傳
*
* @param file
* @param use
* @return
* @throws Exception
*/
@PostMapping("/oss-simple")
public ResponseDto fileUpload(@RequestParam MultipartFile file, String use) throws Exception {
LOG.info("上傳文件開始");

//接收前端的歸屬文件類型 COURSE("C", "課程"), TEACHER("T", "講師");
FileUseEnum useEnum = FileUseEnum.getByCode(use);

// 為了支持一個文件上傳多次,展示歷史的不同版本,因此上傳文件前,統(tǒng)一添加文件前綴,下載時,統(tǒng)一截取文件沒那個前8位處理
String key = UuidUtil.getShortUuid();
//獲取文件名
String fileName = file.getOriginalFilename();
//獲取按照文件類型存儲的目錄
String dir = useEnum.name().toLowerCase();
//文件存儲目錄拼接 /teacher/1.jpeg
String path = dir + "/" + key + fileName;

// 創(chuàng)建OSSClient實例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// 創(chuàng)建PutObjectRequest對象。
//String content = "Hello OSS";
// <yourObjectName>表示上傳文件到OSS時需要指定包含文件后綴在內(nèi)的完整路徑,例如abc/efg/123.jpg。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, path, new ByteArrayInputStream(file.getBytes()));

// 如果需要上傳時設(shè)置存儲類型與訪問權(quán)限,請參考以下示例代碼。
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// metadata.setObjectAcl(CannedAccessControlList.Private);
// putObjectRequest.setMetadata(metadata);

// 上傳字符串
ossClient.putObject(putObjectRequest);
// 關(guān)閉OSSClient
ossClient.shutdown();;

ResponseDto responseDto = new ResponseDto();
FileDto fileDto = new FileDto();
fileDto.setPath(ossDomain + path);
responseDto.setContent(fileDto);

return responseDto;
}
}


本文摘自 :https://blog.51cto.com/g

開通會員,享受整站包年服務(wù)立即開通 >