文件上传多种方式

105 阅读1分钟
  1. 单文件上传 前端
<template>

<div>

<Button type="primary" @click="click">{{BtnText}}</Button>

<input

type="file"

@change="picUpload($event)"

style="display:none;"

ref="fileid"

accept="image/*"

/>

</div>

</template>

<script>

import { ImageZip } from "../../utils/tools.js";

  


export default {

name: "UploadPhotoBtn",

props: {

uploadParam: {

type: Object

}

},

data() {

return {

BtnText: "图片上传"

};

},

watch: {

UploadPhotoBtn: {

handler() {

if (this.uploadParam.Text) {

this.BtnText = this.uploadParam.Text;

}

},

immediate: true

}

},

methods: {

//1.获取上传图片

picUpload(event) {

const self = this;

let files = event.target.files[0];

//图片压缩

ImageZip(files, function(baseData) {

self.upLoads(baseData);

});

},

//2.上传图片

async upLoads(baseData) {

const self = this;

let formData = new FormData();

formData.append("FileType", this.uploadParam.FileType);

formData.append("file", baseData.blobUrl);

const res = await this.$curl.post("api/ydy/uploadFile", formData);

this.$refs.fileid.value = ""; //上传成功后,清除file值,防止相同图片无法上传。

//3.上传成功后,结果回调给父组件

this.$emit("uploadCallback", res);

},

//点击上传

click() {

this.$refs.fileid.dispatchEvent(new MouseEvent("click")); //触发file方法

}

}

};

</script>

后端

async uploadFile(){

try{

//1.获取文件流

const stream = await this.ctx.getFileStream();

let baseDir = this.config.FileDir; //保存的路径

//2.获取文件后缀类型

const fileExt = stream.filename.substr(stream.filename.lastIndexOf("."));

let FileType = stream.fields.FileType;//业务文件类型

let tag = stream.fields.tag;//tag

// 文件大小

let size = stream._readableState && stream._readableState.length ? stream._readableState.length : 0;

size = this.formatBytes(size);

  


let YearMonth = moment().format("YYYYMM");

let YearMonthDay = moment().format("YYYYMMDD");

if(!FileType){

FileType="AllFile";

};

//3.保存的文件名称:格式为yyyyMMddhhmmss_随机4位数_FileType

let FileName = moment().format("YYYYMMDDHHmmss") + "_" + Math.floor(Math.random() * 10000 + 1000) + "_" + FileType + fileExt;

let FilePath =FileType+"/"+YearMonth+"/"+YearMonthDay+"/";

//4.创建文件保存的路径

const url = path.join(baseDir, FilePath);

if(!fs.existsSync(url)){

url.split(path.sep).reduce((currentPath, folder) => {

currentPath += folder + path.sep;

if (!fs.existsSync(currentPath)) {

fs.mkdirSync(currentPath);

}

return currentPath;

}, "");

};

//4.文件保存

const savepath = path.join(url, FileName);

const writeStream = fs.createWriteStream(savepath);

await awaitWriteStream(stream.pipe(writeStream));

let videoList = [".mp4",".mov",".wmv",".flv",".avi",".avchd",".webm",".mkv"];

if(videoList.includes(fileExt)){

let videoPath = FilePath+FileName;

await this.getVideoPhoto(videoPath);

}

  
  


return {

state:1,

tag: tag||null,

FilePath: FilePath+FileName,

SaveName: FileName,

FileName: stream.filename,

videoPhoto: FilePath+FileName.substr(0,FileName.lastIndexOf("."))+".jpg",

url: '/'+FilePath+FileName,

filePath: '/'+FilePath+FileName,

size: size,

FileType

}

}catch(error){

console.log(error)

// return { state:0,msg:"文件上传失败",error:error.toString()}

return { state:0};

}

}
  1. 多文件上传-单文件传递后端
<template>

<!-- 多文件上传-单文件传递后端 -->

<div>

<Upload style="height:32px" action ref="file" multiple accept=".jpg,.jpeg,.png" :format="[ 'jpg', 'jpeg','png']" :before-upload="handleUpload">

<Button>上传图片</Button>

</Upload>

</div>

</template>

  


<script>

import { ImageZip } from "../../utils/tools.js";

  


export default {

name: "uploadMultiple",

props: {

uploadParam: {

type: Object

}

},

data(){

return{

file:null

}

},

methods:{

handleUpload(file) {

this.file = file;

//图片压缩

const self=this;

ImageZip(this.file, function(baseData) {

self.uploadExcel(baseData);

});

return false;

},

async uploadExcel(baseData) {

let formData = new FormData();

formData.append("FileType", this.uploadParam.FileType);

formData.append("file",baseData.blobUrl);

let res = await this.$curl.post(

"api/ydy/uploadFile",

formData

);

//3.上传成功后,结果回调给父组件

this.$emit("uploadCallback", res);

},

  


},

mounted(){

  


}

}

</script>

  


<style lang="scss" scoped>

  


</style>

后端

async uploadFile(){

try{

//1.获取文件流

const stream = await this.ctx.getFileStream();

let baseDir = this.config.FileDir; //保存的路径

//2.获取文件后缀类型

const fileExt = stream.filename.substr(stream.filename.lastIndexOf("."));

let FileType = stream.fields.FileType;//业务文件类型

let tag = stream.fields.tag;//tag

// 文件大小

let size = stream._readableState && stream._readableState.length ? stream._readableState.length : 0;

size = this.formatBytes(size);

  


let YearMonth = moment().format("YYYYMM");

let YearMonthDay = moment().format("YYYYMMDD");

if(!FileType){

FileType="AllFile";

};

//3.保存的文件名称:格式为yyyyMMddhhmmss_随机4位数_FileType

let FileName = moment().format("YYYYMMDDHHmmss") + "_" + Math.floor(Math.random() * 10000 + 1000) + "_" + FileType + fileExt;

let FilePath =FileType+"/"+YearMonth+"/"+YearMonthDay+"/";

//4.创建文件保存的路径

const url = path.join(baseDir, FilePath);

if(!fs.existsSync(url)){

url.split(path.sep).reduce((currentPath, folder) => {

currentPath += folder + path.sep;

if (!fs.existsSync(currentPath)) {

fs.mkdirSync(currentPath);

}

return currentPath;

}, "");

};

//4.文件保存

const savepath = path.join(url, FileName);

const writeStream = fs.createWriteStream(savepath);

await awaitWriteStream(stream.pipe(writeStream));

let videoList = [".mp4",".mov",".wmv",".flv",".avi",".avchd",".webm",".mkv"];

if(videoList.includes(fileExt)){

let videoPath = FilePath+FileName;

await this.getVideoPhoto(videoPath);

}

  
  


return {

state:1,

tag: tag||null,

FilePath: FilePath+FileName,

SaveName: FileName,

FileName: stream.filename,

videoPhoto: FilePath+FileName.substr(0,FileName.lastIndexOf("."))+".jpg",

url: '/'+FilePath+FileName,

filePath: '/'+FilePath+FileName,

size: size,

FileType

}

}catch(error){

console.log(error)

// return { state:0,msg:"文件上传失败",error:error.toString()}

return { state:0};

}

}

3.多文件上传-多文件传递后端

<template>

<!-- 多文件上传-多文件传递后端 -->

<div>

<Button type="primary" @click="click">上传</Button>

<input

type="file"

multiple="multiple"

@change="picUpload($event)"

style="display:none;"

ref="fileid"

accept="image/*"

/>

</div>

</template>

  


<script>

export default {

name: "uploadMultiple",

props: {

uploadParam: {

type: Object

}

},

data(){

return{

file:null

}

},

methods:{

//点击上传

click() {

this.$refs.fileid.dispatchEvent(new MouseEvent("click")); //触发file方法

},

async picUpload(event){

const files = event.target.files;

let formData = new FormData();

formData.append("FileType", this.uploadParam.FileType);

for (let i = 0; i < files.length; i++) {

const file = files[i];

// 这里可以添加上传逻辑,例如使用FormData上传

formData.append(`file`, file);

}

let res = await this.$curl.post("/api/ydy/uploadMultipleFile", formData, {

Headers: { "Content-Type": "multipart/form-data" }

});

},

async uploadExcel() {

let formData = new FormData();

formData.append("file", this.file);

let res = await this.$curl.post("/api/ydy/uploadMultipleFile", formData, {

Headers: { "Content-Type": "multipart/form-data" }

});

if (res.ok && res.requireMsg) {

this.$Message.warning(`${res.requireMsg}`);

return

}

if (res.ok) {

this.getTableData();

this.$Message.success("导入成功!!!");

}

},

  


},

mounted(){

  


}

}

</script>

  


<style lang="scss" scoped>

  


</style>

后端

async uploadMultipleFile(){

try{

const {ctx} = this

let baseDir = this.config.FileDir; //保存的路径

  


// 获取多个文件提交的数据流,多文件上传专用

const parts =await ctx.multipart({ autoFields:true });

  


let YearMonth = moment().format("YYYYMM");

let YearMonthDay = moment().format("YYYYMMDD");

const files = [];

let stream

while( ( stream = await parts() ) != null )

{

// 判断用户是否选择上传图片

if (!stream.filename)

{

ctx.throw('请选择上传的图片!')

return

}

let FileType=await parts.field;

if(!FileType){

FileType="AllFile";

};

  


// filename 获取上传的文件名 xxx.jpg

const filename = stream.filename.toLowerCase()

// fieldname 获取文件表单提交的字段名称

const fieldname = stream.fieldname

  


const fileExt =filename.substr(filename.lastIndexOf("."));

//3.保存的文件名称:格式为yyyyMMddhhmmss_随机4位数_FileType

let FileName = moment().format("YYYYMMDDHHmmss") + "_" + Math.floor(Math.random() * 10000 + 1000) + "_" + FileType + fileExt;

  


let FilePath =FileType+"/"+YearMonth+"/"+YearMonthDay+"/";

//4.创建文件保存的路径

const url = path.join(baseDir, FilePath);

if(!fs.existsSync(url)){

url.split(path.sep).reduce((currentPath, folder) => {

currentPath += folder + path.sep;

if (!fs.existsSync(currentPath)) {

fs.mkdirSync(currentPath);

}

return currentPath;

}, "");

};

//4.文件保存

const savepath = path.join(url, FileName);

// 创建可写流

const writeStream = fs.createWriteStream(savepath)

// 读取文件 && 写入 && 销毁当前流

await pump(stream, writeStream)

files.push({

[fieldname]: '/'+FilePath+FileName

})

}

return {

files,

fields:parts.field

}

}catch(error){

console.log(error)

return{

}

}

}

调用方法

<uploadMultiple2 :uploadParam="uploadPhotoParam" @uploadCallback="uploadCallback($event)" v-show="uploadPic"></uploadMultiple2>

传递参数

fileParam: {

FileType: "checkStation",

},