java + vue实现文件上传、下载、删除

5 篇文章 0 订阅
2 篇文章 0 订阅

数据库表结构:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for ies_file
-- ----------------------------
DROP TABLE IF EXISTS `ies_file`;
CREATE TABLE `ies_file`  (
  `id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `size` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `type` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `time` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

上传:

1. vue代码

<template>
    <div>
        <el-row class="action-row">
            <el-col :span="9">
                <el-button type="primary" icon="el-icon-plus" @click="add" size="medium">新增</el-button>
            </el-col>
        </el-row>
            <!-- 列表 -->
        <el-row>
            <table-slot :isShowNum="true" style="height: 700px" :center="'center'" :total="total" :pageSize="page"
                        :pageNum="limit" :columns="column" :list="docs" :pageShow="true"
                        @handleSizeChange="SizeChange" @handleCurrentChange='CurrentChange'>
                <template slot="operation" slot-scope="scope">
                    <el-button @click="downloadFile(scope.row)">下载</el-button>
                    <el-button @click="deleteFile(scope.row)">删除</el-button>
                </template>
            </table-slot>
        </el-row>
            <!-- 新建按钮弹出框 -->
        <el-dialog title="上传附件" :visible.sync="editvisible" :append-to-body="true" width="450px">
            <el-form :model="gtsDocument" :rules="rules" ref="gtsDocument" label-width="120px" label-position="left"
                     size="small" class="edit-form">
                <el-form-item label="上传附件" prop="file">
                    <el-upload ref="upload" action="doUpload" :limit="limitNum" :auto-upload="false"
                               :on-change="fileChange" :on-exceed="exceedFile" :file-list="fileList">
                                   
                        <el-button size="small" plain>选择文件</el-button>
                    </el-upload>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="editvisible = false">取消</el-button>
                <el-button type="primary" @click="save">确定</el-button>
            </div>
        </el-dialog>
    </div>
</template>

依赖:

import tableSlot from "../../components/table.vue"

table.vue

<template>
	<div class="table_info">
		<el-table
			:data="list"
			:border="border"
			:stripe="stripe"
			style="width: 100%"
			tooltip-effect="dark"
			:height="height"
			:size="size"
			@selection-change="handleSelectionChange"
			v-loading="loading"
			element-loading-text="拼命加载中"
			element-loading-spinner="el-icon-loading"
			element-loading-background="rgba(0, 0, 0, 0.5)"
			class="elTable"
			border
		>
		<!-- :default-sort="defaultSort"
			:row-style="rowStyle"
			:cell-style="cellStyle" -->
			<el-table-column type="selection" v-if="isShowSection"></el-table-column>
			<el-table-column v-if="isShowNum" type="index" label="序号" :width="70" :align="center"></el-table-column>
			<el-table-column
				v-for="(item, index) in columns"
				:key="index"
				:prop="item.prop"
				:label="item.label"
				:align="center"
				:width="item.width"
			>
				<template slot-scope="scope">
					<slot v-if="item.slot" :name="item.prop" :row="scope.row"  :scope="scope"/>
					<span v-else>{{ scope.row[item.prop] }}</span>
				</template>
			</el-table-column>
		</el-table>
		<el-pagination
			v-if="pageShow"
			@size-change="handleSizeChange"
			@current-change="handleCurrentChange"
			:current-page.sync="tablePageNum"
			:page-size="pageSize"
			:layout="layout"
			:total="total"
		></el-pagination>
		<!-- 
			:page-sizes="pageSizes"
		 -->
	</div>
</template>

<script>
	export default {
		props: {
			// 勾选框是否显示,true显示,false隐藏
			isShowSection: {
				type: Boolean,
				default: false,
			},
			// 序号列是否显示,true显示,false隐藏
			isShowNum: {
				type: Boolean,
				default: false,
			},
			// 表头
			columns: {
				type: Array,
				default: new Array(),
			},
			// 数据
			list: {
				type: Array,
				default: new Array(),
			},
			// 表格边框
			border: {
				type: Boolean,
				default: false,
			},
			// 表格斑马显示
			stripe: {
				type: Boolean,
				default: false,
			},
			// 分页器是否显示
			pageShow: {
				type: Boolean,
				default: false,
			},
			// 总条数
			total: {
				type: Number,
				default: 0,
			},
			// 显示条数
			pageSize: {
				type: Number,
				default: 10,
			},
			// 当前显示页数
			pageNum: {
				type: Number,
				default: 1,
			},
			layout: {
				type: String,
				default: "total, sizes, prev, pager, next, jumper",
			},
			// pageSizes: {
			// 	type: Array,
			// 	default: new Array(),
			// },
			loading: {
				type: Boolean,
				default: false,
			},
			center: {
				type: String,
				default: "",
			},
			// defaultSort: {
			// 	type: Object,
			// 	default: new Object(),
			// },
			// rowStyle: {
			// 	type: Object,
			// 	default: new Object(),
			// },
			// cellStyle: {
			// 	type: Object,
			// 	default: new Object(),
			// },
			size: {
				type: String,
				default: "",
			},
			height: {
				type: String,
				default: "100%",
			},
		},
		data() {
		    return {
		      // 避免直接修改props
		      tablePageNum: this.pageNum,
		    }
		},
		watch: {
			/* tableData: {
				handler() {},
				deep: true,
			},
			*/
		},
		methods: {
			//每页多少条
			handleSizeChange(val) {
				this.$emit("handleSizeChange", val, true);
			},
			//当前页
			handleCurrentChange(val) {
				this.$emit("handleCurrentChange", val, true);
			},
			handleSelectionChange(val) {
				console.log(val);
			},
		},
	};
</script>

<style lang="scss" scoped>
	.table_info {
		width: 100%;
		height: 100%;
	}
</style>

上传事件:

            // 保存
            save() {
                this.$refs["gtsDocument"].validate(valid => {
                    if (valid) {
                        let formData = new FormData();
                        let file = this.gtsDocument.file;
                        formData.append("file", file);
                        if (!file) {
                            return this.$message.warning('请选择上传附件');
                        }
                        this.$axios.post('/documents/add', formData).then(result => {
                            if (result.status == 200) {
                                if ("ok" == result.data) {
                                    this.editvisible = false;
                                    this.$message.success('数据保存成功');
                                    this.search();
                                    this.$refs.upload.clearFiles();
                                } else {
                                    this.$message.error('保存失败');
                                }
                            }
                        })
                    }
                });
            },

新增按钮点击事件

            // 新增按钮点击事件
            add() {
                this.editvisible = true;
                this.$nextTick(() => {
                    this.isupdate = false;
                    this.$refs.gtsDocument.resetFields();
                });
            },

文件超出个数限制时的校验

            // 文件超出个数限制时的校验
            exceedFile(files, fileList) {
                this.$notify.warning({
                    title: this.$t("com.warning"),
                    message: this.$t("com.onlySelect") + `${this.limitNum} ` + this.$t("com.someFile")
                });
            },

文件状态改变时的事件

            // 文件状态改变时的事件
            fileChange(file, fileList) {
                this.gtsDocument.file = file.raw;
            },

上传后端–Java

配置文件

uploadFile:
  path: D:/home/ecustoms/upload/

Controller层

    @Autowired
    fileService fileService;

    @Value("${uploadFile.path}")
    private String PATH;
    /**
     * @param file    上传附件
     * @return
     */
    @ResponseBody
    @PostMapping("/documents/add")
    public String addAttach(@RequestParam("file") MultipartFile file) throws IOException {
        // 获取文件名称
        String fileName = file.getOriginalFilename();
        if (StringUtils.isBlank(fileName)) {
            return "文件不能为空";
        }
        // 获取文件的大小
        long fileSize = file.getSize();
        if (fileSize > 100 * 1024 * 1024) {
            return "上传文件大小超出限定大小100M";
        }
        String uuid = IdUtils.createUuid();
        // 获取配置路径
        String newPath = PATH + uuid + "\\";
        File newDir = new File(newPath);
        if (!newDir.exists()) {
            newDir.mkdirs(); // 目录不存在的情况下,创建目录
        }
        File newFile = new File(newDir, fileName);
        //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
        file.transferTo(newFile);
        Map<String,String> map = new HashMap<String, String>();
        map.put("id",uuid);
        map.put("name",fileName);
        map.put("size",String.valueOf(fileSize));
        map.put("time",DateUtils.getNowSec());
        String contentType = file.getContentType();
        map.put("type",contentType);
        fileService.insertFile(map);
        return "ok";
    }

service接口

    // 上传文件
    Integer insertFile(Map<String,String> map);

service实现类

    /**
     * 文件上传
     * @param map
     * @return
     */
    @Override
    public Integer insertFile(Map<String,String> map) {
        return fileMapper.insertfile(map);
    }

Mapper接口

    //文件上传
    Integer insertfile(Map<String,String> map);

Mapper–sql

	<insert id="insertfile" parameterType="map">
	INSERT INTO
	    ies_file (id, name, size, type,time)
	VALUES
	    (#{id},#{name},#{size},#{type},#{time})
	</insert>

查询与下载

查询

vue事件

            search() {
                this.listData.page = this.page;
                this.listData.limit = this.limit;
                this.$axios.post('/documents', this.listData).then(result => {
                    if (result.status == 200) {
                        this.docs = result.data.list;
                        this.total = result.data.pageSize;
                    }
                })
            },

data

                page: 1,
                limit: 10,
                total: 0,
                column: [{
                    prop: "name",
                    label: "文件名称",
                    width: "150px"
                }, {
                    prop: "type",
                    label: "类型"
                }, {
                    prop: "time",
                    label: "创建时间"
                }, {
                    prop: "size",
                    label: "大小"
                }, {
                    prop: "operation",
                    label: "操作",
                    width: "200px",
                    slot: true
                }],
                 docs: [],

后端

Controller层

    /**
     * 附件查询
     * @param map
     * @return
     * @throws IOException
     */
    @ResponseBody
    @PostMapping("/documents")
    public PageInfo documents(@RequestBody Map map) throws IOException {
        PageInfo pageInfo = fileService.selectFile(map);
        return pageInfo;
    }

service接口

    //查询文件
    PageInfo selectFile(Map<String,Integer> map);

service实现类

    /**
     * 文件查询
     * @param map
     * @return
     */
    @Override
    public PageInfo selectFile(Map<String,Integer> map) {
        List<file> mapList = fileMapper.selectFile();
        Integer pigeSize = map.get("page");
        Integer pageNum = map.get("limit");
        PageHelper.startPage(pageNum, pigeSize);
        PageInfo pageInfo = new PageInfo(mapList);
        return pageInfo;
    }

Mapper接口

    //文件查询
    List<file> selectFile();

Mapper–sql

	<select id="selectFile" resultType="com.nusp.Entity.file.file">
		SELECT
			id,
			name,
			CONCAT(ROUND(size/1024/1024,2),'M') as size,
			type,
			time
		FROM
			ies_file
		where
			1 = 1
    </select>

下载

vue事件

            downloadFile(row) {
                var objParam = "?id=" + row.id + "&name=" + row.name + "&type=" + row.type;  //地址后面带的参数,根据自己业务来
                window.location.href = 'http://127.0.0.1:9000/api/downloadFile' + objParam;
            },

Controller层

    /**
     * 附件下载
     * @param id
     * @param name
     * @param type
     * @param response
     */
    @ResponseBody
    @GetMapping("/downloadFile")
    public void getSdgsTree (@RequestParam(required = false,value = "id") String id,@RequestParam(required = false,value = "name") String name,@RequestParam(required = false,value = "type") String type,HttpServletResponse response){
        Map map = new HashMap();
        map.put("name",name);
        map.put("id",id);
        map.put("type",type);
        fileService.downloadFile(map,response);
    }

service接口

    //文件下载
    void downloadFile(Map map, HttpServletResponse response);

service实现类

    /**
     * 附件下载
     * @param map
     * @param response
     */
    @Override
    public void downloadFile(Map map, HttpServletResponse response) {
        try {
            String basePath = PATH + "/" + map.get("id") + "/";
            // 1、定义输入流,通过输入流读取文件内容
            FileInputStream fileInputStream = new FileInputStream(new File(basePath + map.get("name")));

            // 2、通过response对象,获取到输出流
            ServletOutputStream outputStream = response.getOutputStream();

            // 3、通过response对象设置响应数据格式(image/jpeg)
            response.setContentType(String.valueOf(map.get("type"))+";charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(String.valueOf(map.get("name")), "utf-8"));
            int len = 0;
            byte[] bytes = new byte[102400];
            while ((len = fileInputStream.read(bytes)) != -1){
                // 4、通过输入流读取文件数据,然后通过上述的输出流写回浏览器
                outputStream.write(bytes,0,len);
                // 刷新
                outputStream.flush();
            }
            // 5、关闭资源
            outputStream.close();
            fileInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

删除

vue事件

            //附件删除
            deleteFile(row) {
                this.$confirm('确定要删除本条数据吗?','提示',{
                    confirmButtonText:'确定',
                    cancelButtonText:'取消',
                    type:'warning'
                }).then(()=>{
                    this.$axios.post('/deleteFile', row).then(result => {
                        this.search();
                    })
                }).catch(() =>{
                    this.$message({
                        type: 'info',
                        message:'已取消删除'
                    });
                });
            },

Controller层

    /**
     * 附件删除
     * @param map
     * @throws IOException
     */
    @ResponseBody
    @PostMapping("/deleteFile")
    public void deleteFile(@RequestBody Map map) throws IOException {
        fileService.deleteFile(map);
    }

service接口

    //文件删除
    void deleteFile(Map map);

service实现类

    /**
     * 附件删除
     * @param map
     */
    @Override
    public void deleteFile(Map map) {
        String newPath = "D:/home/ecustoms/upload/" + map.get("id");
        String filePath = newPath + "/" + map.get("name");
        Path pathss = Paths.get(filePath);
        Path dPass = Paths.get(newPath);
        try {
            Files.delete(pathss);
            Files.delete(dPass);
            fileMapper.deleteFile(map);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Mapper接口

    //文件删除
    void deleteFile(Map map);

Mapper–sql

	<delete id="deleteFile" parameterType="map">
		DELETE FROM ies_file WHERE id = #{id}
	</delete>

完整代码

vue事件

<template>
    <div>
        <el-row class="action-row">
            <el-col :span="9">
                <el-button type="primary" icon="el-icon-plus" @click="add" size="medium">新增</el-button>
            </el-col>
        </el-row>
            <!-- 列表 -->
        <el-row>
            <table-slot :isShowNum="true" style="height: 700px" :center="'center'" :total="total" :pageSize="page"
                        :pageNum="limit" :columns="column" :list="docs" :pageShow="true"
                        @handleSizeChange="SizeChange" @handleCurrentChange='CurrentChange'>
                <template slot="operation" slot-scope="scope">
                    <el-button @click="downloadFile(scope.row)">下载</el-button>
                    <el-button @click="deleteFile(scope.row)">删除</el-button>
                </template>
            </table-slot>
        </el-row>
            <!-- 新建按钮弹出框 -->
        <el-dialog title="上传附件" :visible.sync="editvisible" :append-to-body="true" width="450px">
            <el-form :model="gtsDocument" :rules="rules" ref="gtsDocument" label-width="120px" label-position="left"
                     size="small" class="edit-form">
                <el-form-item label="上传附件" prop="file">
                    <el-upload ref="upload" action="doUpload" :limit="limitNum" :auto-upload="false"
                               :on-change="fileChange" :on-exceed="exceedFile" :file-list="fileList">
                                   
                        <el-button size="small" plain>选择文件</el-button>
                    </el-upload>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="editvisible = false">取消</el-button>
                <el-button type="primary" @click="save">确定</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
    import tableSlot from "../../components/table.vue"

    export default {
        components: {
            tableSlot
        },
        name: "GtsDocument",
        data() {
            return {
                editvisible: false, // 新增弹出框显示标识:默认不显示
                gtsDocument: {
                    // 随附单据表单
                    docType: "",
                    docNo: "",
                    gtsId: "",
                    taskId: "",
                    file: ""
                },
                isupdate: false,
                limitNum: 1,
                fileList: [],
                docs: [],
                loading: false,
                page: 1,
                limit: 10,
                total: 0,
                rules: {},
                listData: {},
                column: [{
                    prop: "name",
                    label: "文件名称",
                    width: "150px"
                }, {
                    prop: "type",
                    label: "类型"
                }, {
                    prop: "time",
                    label: "创建时间"
                }, {
                    prop: "size",
                    label: "大小"
                }, {
                    prop: "operation",
                    label: "操作",
                    width: "200px",
                    slot: true
                }],
            };
        },
        created: function () {
            this.search();
        },
        methods: {
            CurrentChange(val) {
                this.page = val;
                this.search();
            },
            //监听分页状态
            SizeChange(val) {
                this.limit = val;
                this.search();
            },
            search() {
                this.listData.page = this.page;
                this.listData.limit = this.limit;
                this.$axios.post('/documents', this.listData).then(result => {
                    if (result.status == 200) {
                        this.docs = result.data.list;
                        this.total = result.data.pageSize;
                    }
                })
            },
            // 新增按钮点击事件
            add() {
                this.editvisible = true;
                this.$nextTick(() => {
                    this.isupdate = false;
                    this.$refs.gtsDocument.resetFields();
                });
            },
            //附件删除
            deleteFile(row) {
                this.$confirm('确定要删除本条数据吗?','提示',{
                    confirmButtonText:'确定',
                    cancelButtonText:'取消',
                    type:'warning'
                }).then(()=>{
                    this.$axios.post('/deleteFile', row).then(result => {
                        this.search();
                    })
                }).catch(() =>{
                    this.$message({
                        type: 'info',
                        message:'已取消删除'
                    });
                });
            },
            //附件下载
            downloadFile(row) {
                var objParam = "?id=" + row.id + "&name=" + row.name + "&type=" + row.type;  //地址后面带的参数,根据自己业务来
                window.location.href = 'http://127.0.0.1:9000/api/downloadFile' + objParam;
            },
            // 文件超出个数限制时的校验
            exceedFile(files, fileList) {
                this.$notify.warning({
                    title: this.$t("com.warning"),
                    message: this.$t("com.onlySelect") + `${this.limitNum} ` + this.$t("com.someFile")
                });
            },
            // 文件状态改变时的事件
            fileChange(file, fileList) {
                this.gtsDocument.file = file.raw;
            },
            // 保存
            save() {
                this.$refs["gtsDocument"].validate(valid => {
                    if (valid) {
                        let formData = new FormData();
                        let file = this.gtsDocument.file;
                        formData.append("file", file);
                        if (!file) {
                            return this.$message.warning('请选择上传附件');
                        }
                        this.$axios.post('/documents/add', formData).then(result => {
                            if (result.status == 200) {
                                if ("ok" == result.data) {
                                    this.editvisible = false;
                                    this.$message.success('数据保存成功');
                                    this.search();
                                    this.$refs.upload.clearFiles();
                                } else {
                                    this.$message.error('保存失败');
                                }
                            }
                            // this.selectTotal();
                        })
                    }
                });
            },
        }
    };
</script>

<style rel="stylesheet/css">
    .setting-form .el-form-item__label {
          padding-right: 30px;
    }
</style>

Controller层

package com.nusp.Controller.file;

import com.github.pagehelper.PageInfo;
import com.nusp.Entity.Mater.MaterParmas;
import com.nusp.Service.file.fileService;
import com.nusp.Utils.DateUtils;
import com.nusp.Utils.IdUtils;
import com.nusp.Utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Handler;

/**
 * @User: 齐亚硕
 * @Date: 2022/11/28 15:03
 */
@Slf4j
@RestController
public class fileController {
    @Autowired
    fileService fileService;

    @Value("${uploadFile.path}")
    private String PATH;

    /**
     * <p>Description: 附件上传</p>
     * @param file    上传附件
     * @return
     */
    @ResponseBody
    @PostMapping("/documents/add")
    public String addAttach(@RequestParam("file") MultipartFile file) throws IOException {
        // 获取文件名称
        String fileName = file.getOriginalFilename();
        if (StringUtils.isBlank(fileName)) {
            return "文件不能为空";
        }
        // 获取文件的大小
        long fileSize = file.getSize();
        if (fileSize > 100 * 1024 * 1024) {
            return "上传文件大小超出限定大小100M";
        }
        String uuid = IdUtils.createUuid();
        // 获取配置路径
        String newPath = PATH + uuid + "\\";
        File newDir = new File(newPath);
        if (!newDir.exists()) {
            newDir.mkdirs(); // 目录不存在的情况下,创建目录
        }
        File newFile = new File(newDir, fileName);
        //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
        file.transferTo(newFile);
        Map<String,String> map = new HashMap<String, String>();
        map.put("id",uuid);
        map.put("name",fileName);
        map.put("size",String.valueOf(fileSize));
        map.put("time",DateUtils.getNowSec());
        String contentType = file.getContentType();
        map.put("type",contentType);
        fileService.insertFile(map);
        return "ok";
    }

    /**
     * 附件删除
     * @param map
     * @throws IOException
     */
    @ResponseBody
    @PostMapping("/deleteFile")
    public void deleteFile(@RequestBody Map map) throws IOException {
        fileService.deleteFile(map);
    }

    /**
     * 附件查询
     * @param map
     * @return
     * @throws IOException
     */
    @ResponseBody
    @PostMapping("/documents")
    public PageInfo documents(@RequestBody Map map) throws IOException {
        PageInfo pageInfo = fileService.selectFile(map);
        return pageInfo;
    }

    /**
     * 附件下载
     * @param id
     * @param name
     * @param type
     * @param response
     */
    @ResponseBody
    @GetMapping("/downloadFile")
    public void getSdgsTree (@RequestParam(required = false,value = "id") String id,@RequestParam(required = false,value = "name") String name,@RequestParam(required = false,value = "type") String type,HttpServletResponse response){
        Map map = new HashMap();
        map.put("name",name);
        map.put("id",id);
        map.put("type",type);
        fileService.downloadFile(map,response);
    }
}

service接口

package com.nusp.Service.file;

import com.github.pagehelper.PageInfo;

import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @User: 齐亚硕
 * @Date: 2022/11/30
 * @Time: 9:58
 */
public interface fileService {
    // 上传文件
    Integer insertFile(Map<String,String> map);
    //查询文件
    PageInfo selectFile(Map<String,Integer> map);
    //文件下载
    void downloadFile(Map map, HttpServletResponse response);
    //文件删除
    void deleteFile(Map map);
}

service实现类

package com.nusp.Service.file.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.nusp.Entity.Mater.MaterParmas;
import com.nusp.Entity.file.file;
import com.nusp.Mapper.file.fileMapper;
import com.nusp.Service.file.fileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;

/**
 * @User: 齐亚硕
 * @Date: 2022/11/30 9:58
 */
@Service
@Slf4j
public class fileImpl implements fileService {

    @Autowired
    private fileMapper fileMapper;

    @Value("${uploadFile.path}")
    private String PATH;
    /**
     * 文件上传
     * @param map
     * @return
     */
    @Override
    public Integer insertFile(Map<String,String> map) {
        return fileMapper.insertfile(map);
    }

    /**
     * 文件查询
     * @param map
     * @return
     */
    @Override
    public PageInfo selectFile(Map<String,Integer> map) {
        List<file> mapList = fileMapper.selectFile();
        Integer pigeSize = map.get("page");
        Integer pageNum = map.get("limit");
        PageHelper.startPage(pageNum, pigeSize);
        PageInfo pageInfo = new PageInfo(mapList);
        return pageInfo;
    }

    /**
     * 附件下载
     * @param map
     * @param response
     */
    @Override
    public void downloadFile(Map map, HttpServletResponse response) {
        try {
            String basePath = PATH + "/" + map.get("id") + "/";
            // 1、定义输入流,通过输入流读取文件内容
            FileInputStream fileInputStream = new FileInputStream(new File(basePath + map.get("name")));

            // 2、通过response对象,获取到输出流
            ServletOutputStream outputStream = response.getOutputStream();

            // 3、通过response对象设置响应数据格式(image/jpeg)
            response.setContentType(String.valueOf(map.get("type"))+";charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(String.valueOf(map.get("name")), "utf-8"));
            int len = 0;
            byte[] bytes = new byte[102400];
            while ((len = fileInputStream.read(bytes)) != -1){
                // 4、通过输入流读取文件数据,然后通过上述的输出流写回浏览器
                outputStream.write(bytes,0,len);
                // 刷新
                outputStream.flush();
            }
            // 5、关闭资源
            outputStream.close();
            fileInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 附件删除
     * @param map
     */
    @Override
    public void deleteFile(Map map) {
        String newPath = "D:/home/ecustoms/upload/" + map.get("id");
        String filePath = newPath + "/" + map.get("name");
        Path pathss = Paths.get(filePath);
        Path dPass = Paths.get(newPath);
        try {
            Files.delete(pathss);
            Files.delete(dPass);
            fileMapper.deleteFile(map);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Mapper接口

package com.nusp.Mapper.file;

import com.nusp.Entity.file.file;

import java.util.List;
import java.util.Map;

/**
 * @User: 齐亚硕
 * @Date: 2022/11/30
 * @Time: 11:09
 */
public interface fileMapper {

    //文件上传
    Integer insertfile(Map<String,String> map);
    //文件查询
    List<file> selectFile();
    //文件删除
    void deleteFile(Map map);
}

Mapper–sql

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
		PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
		"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nusp.Mapper.file.fileMapper">
	<insert id="insertfile" parameterType="map">
INSERT INTO
    ies_file (id, name, size, type,time)
VALUES
    (#{id},#{name},#{size},#{type},#{time})
</insert>
	<delete id="deleteFile" parameterType="map">
		DELETE FROM ies_file WHERE id = #{id}
	</delete>

	<select id="selectFile" resultType="com.nusp.Entity.file.file">
SELECT
	id,
	name,
	CONCAT(ROUND(size/1024/1024,2),'M') as size,
	type,
	time
FROM
	ies_file
where
	1 = 1
    </select>

</mapper>

完结撒花

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java+Vue+Minio分片上中,获取到分片上预签名地址后,需要通过后台接口上分片。以下是Java+Vue代码实现的步骤: 1.前端通过axios发送请求获取分片上预签名地址,将分片文件按照预签名地址上至Minio。 2.后端接收到前端上的分片文件后,调用Minio的API将分片文件至Minio。 3.后端需要记录每个上的分片文件的信息,包括文件名、分片编号、分片大小等信息。 4.当所有分片文件完成后,后端需要调用Minio的API将所有分片文件合并成一个完整的文件。 以下是Java+Vue代码实现的示例: Java代码: ``` // 上分片文件 @PostMapping("/uploadChunk") public void uploadChunk(@RequestParam("file") MultipartFile file, @RequestParam("fileName") String fileName, @RequestParam("chunkNumber") Integer chunkNumber, @RequestParam("chunkSize") Integer chunkSize, @RequestParam("totalSize") Long totalSize, @RequestParam("identifier") String identifier) throws Exception { // 将分片文件至Minio InputStream inputStream = file.getInputStream(); minioClient.putObject("bucketName", fileName + "/" + chunkNumber, inputStream, new PutObjectOptions(inputStream.available(), -1)); inputStream.close(); // 记录分片文件信息 Chunk chunk = new Chunk(); chunk.setFileName(fileName); chunk.setChunkNumber(chunkNumber); chunk.setChunkSize(chunkSize); chunk.setTotalSize(totalSize); chunk.setIdentifier(identifier); chunkService.saveChunk(chunk); } // 合并分片文件 @PostMapping("/mergeChunks") public void mergeChunks(@RequestParam("fileName") String fileName, @RequestParam("totalChunks") Integer totalChunks, @RequestParam("identifier") String identifier) throws Exception { // 获取所有分片文件的信息 List<Chunk> chunks = chunkService.getChunks(fileName, identifier); // 检查分片文件是否全部上完成 if (chunks.size() != totalChunks) { throw new Exception("分片文件未全部上完成"); } // 将所有分片文件合并成一个完整的文件 List<String> objectNames = new ArrayList<>(); for (Chunk chunk : chunks) { objectNames.add(chunk.getFileName() + "/" + chunk.getChunkNumber()); } minioClient.composeObject("bucketName", fileName, objectNames); // 删除所有分片文件 for (Chunk chunk : chunks) { minioClient.removeObject("bucketName", chunk.getFileName() + "/" + chunk.getChunkNumber()); } // 删除分片文件信息 chunkService.deleteChunks(fileName, identifier); } ``` Vue代码: ``` // 获取分片上预签名地址 async getChunkUploadUrl(file) { const response = await axios.post('/getChunkUploadUrl', { fileName: file.name, fileSize: file.size }); return response.data; } // 上分片文件 async uploadChunk(file, chunkNumber, chunkSize, totalSize, identifier, uploadUrl) { const formData = new FormData(); formData.append('file', file.slice((chunkNumber - 1) * chunkSize, chunkNumber * chunkSize)); formData.append('fileName', file.name); formData.append('chunkNumber', chunkNumber); formData.append('chunkSize', chunkSize); formData.append('totalSize', totalSize); formData.append('identifier', identifier); await axios.post(uploadUrl, formData); } // 合并分片文件 async mergeChunks(file, totalChunks, identifier) { await axios.post('/mergeChunks', { fileName: file.name, totalChunks: totalChunks, identifier: identifier }); } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值