vue实现文件上传,前后端

前端封装el-upload组件,父组件传值dialogVisible(用于显示el-dialog),子组件接收,并且关闭的时候返回一个值(用于隐藏el-dialog),最多上传五个文件,文件格式为.jpg\pdf\png

复制代码
<template>
    <div>
       <el-dialog  width="30%"  :visible.sync="dialogShow" append-to-body @close='handleCancle' title="上传发票" class="uploadDialog">
        <!-- list-type="picture" -->
        <el-upload
           ref="upload"
           :auto-upload="false"
           :http-request="uploadFile"
           :on-change="changeFileLength"
           :limit="5"
           :on-exceed="handleExceed"
           action=""
           accept=".pdf,.jpg,.png" 
           multiple>
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">点击上传文件</div>
        </el-upload>
        <!-- 上传时点击的按钮 -->
        <el-button @click="upload" type="success">上传文件</el-button>
      </el-dialog>
    </div>
</template>
<script>
import {  upload } from "@/api/invoice/invoiceManagement";

export default {
    name: "uploadCT",
    props:{
        dialogVisible:{
            type:Boolean,
            default:false,
            require:true,
        }
    },
    watch: {
        dialogVisible: {
            handler(val) {
                this.dialogShow = val
            },
            deep: true, // 深度监听
            immediate: true, // 初次监听即执行  
        },
    },

    data(){
        return{
            // 上传文件的列表
            uploadFiles: [],
            // 上传文件的个数
            filesLength: 0,
            // 上传需要附带的信息
            info:{
                id:"",
                name:"",
            },
            //显示
            dialogShow:this.dialogVisible,
        }
    },

    methods:{
        //超出限制提示
        handleExceed(files, fileList) {
            this.$message.warning(`当前限制选择 5 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
        },
        //关闭
        handleCancle(){
            this.uploadFiles= [];
            // 上传文件的个数
            this.filesLength= 0;
            this.dialogShow = false;
            this.$emit('closeUploadDialog',this.dialogShow);
            this.$refs.upload.clearFiles();
        },
        // 修改当前文件列表长度
        changeFileLength(file, fileList){
            this.filesLength = fileList.length
        },

        // 用户点击上传调用
        async upload(){
            // 触发上传 调用配置 :http-request="uploadFile"
            // 即触发 uploadFile函数
            await this.$refs.upload.submit();
            // 上传完成后执行的操作 ...
            this.$modal.msgSuccess("上传成功");
        },

        // 该函数还是会被调用多次
        // 每次param参数传入一个文件
        uploadFile(param){
            console.log("参数",param);
            // 将文件加入需要上传的文件列表
            this.uploadFiles.push(param.file)
            // 当uploadFiles长度等于用户需要上传的文件数时进行上传
            if (this.uploadFiles.length == this.filesLength){
                // 创建FormData上传
                let fd = new FormData()
                // 将全部文件添加至FormData中
                this.uploadFiles.forEach(file => {
                    fd.append('file', file)
                })
                // 将附加信息添加至FormData
                fd.append("id", this.info.id)
                fd.append("name", this.info.name)
                // 配置请求头
                const config = {
                    headers: {
                        "Content-Type": "multipart/form-data",
                    }
                }
                console.log("参数",fd);
                // 上传文件
                upload(fd).then(res => {
                    /*上传成功处理*/
                    console.log(res);
                    if(res.msg=='上传成功'){
                        this.uploadFiles=[];
                        this.filesLength = 0;
                        this.dialogShow = false;
                        this.$emit('closeUploadDialog',this.dialogShow);
                        this.$refs.upload.clearFiles();

                    }
                }).catch(err => {/*报错处理*/});

            }
        }
    }
}
</script>

后端接收

复制代码
 @PostMapping("/upload")
    public AjaxResult upload(@RequestParam(value = "file") MultipartFile[] file)
    {
        try {
            String localPath = "";
            //1.1获取当前日期,当做本地磁盘的目录
            Date nowDate = DateUtils.getNowDate();
            String format = new SimpleDateFormat("YYYYMMDD").format(nowDate);
            String localPathPrefix = "C:\\"+format;
            for(MultipartFile f:file){
                // 获取文件名
                String fileName = f.getOriginalFilename();
                // 获取文件后缀
                String prefix = fileName.substring(fileName.lastIndexOf("."));
                // 保存文件到本地磁盘
                localPath = localPathPrefix+"\\"+fileName;
                File localFile = new File(localPath);
                if (!localFile.getParentFile().exists()) {
                    localFile.getParentFile().mkdirs();
                }
                //写入到本地磁盘
                f.transferTo(localFile);
                // 获取文件在本地磁盘上的路径
                String filePath = localFile.getAbsolutePath();
                log.info("文件名称:"+fileName+"已经存入本地磁盘,全路径为:"+filePath);

                //上传到文件服务器,自己掉接口

                //上传完成后,删除本地临时磁盘文件
                if (localFile.delete()) {
                    log.info(localFile.getName() + "已经删除");
                } else {
                    log.info("文件删除失败");
                }
            }
            //删除本次磁盘的日期目录
            File file1 = new File(localPathPrefix);
            if (file1.delete()) {
                log.info(file1.getName() + "已经删除");
            } else {
                log.info("文件删除失败");
            }

        }catch (Exception e){
            System.out.println(e);
            return error("上传失败");
        }
        return success("上传成功");
    }

效果展示

相关推荐
kyriewen6 小时前
别再 console.log 了:5 个 Chrome DevTools 调试技巧,用过就回不去了
前端·javascript·面试
IT_陈寒8 小时前
Python搞不定字符串编码?这破玩意坑我两小时!
前端·人工智能·后端
To_OC8 小时前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode
DigitalOcean9 小时前
Laravel 开发者已在 DigitalOcean 上开通超过 10 万台服务器
前端·laravel
星始流年9 小时前
从 Tool 到 Skill——基于 LangChain 的服务端Skill实现
前端·langchain·agent
李惟9 小时前
开源本地通信库,纯客户端 RPC,像聊天一样通信
前端
YAwu1110 小时前
深入解析 React 炫彩鼠标跟随标题组件:从坐标定位到动画性能
前端·react.js
GuWenyue10 小时前
排序效率低?5分钟吃透快速排序,性能飙升至O(nlogn)
前端·javascript·面试
OpenTiny社区10 小时前
🎨 看完 GenUI SDK 源码我悟了!
前端·vue.js·github
叁两10 小时前
前端转型AI Agent该如何学习?(前置篇)
前端·人工智能·node.js