效果图
预览:
设计逻辑
数据库表
前端vue
html
<div class="right-pannel">
<div class="data-box">
<!--上传的作业-->
<div style="display: block" id="">
<div class="title clearfix">
<div class="all fl" data-folderid="0">
<a class="here">上传附件(上传项目演示视频应为mp4格式)</a>
</div>
</div>
<div class="container_con">
<!--作业超时提示-->
<el-dialog
title="提示"
:visible.sync="workLateTip"
width="30%">
<span>作业已截止,禁止提交,请联系任课老师</span>
<span slot="footer" class="dialog-footer">
<el-button @click="workLateTip = false">取 消</el-button>
<el-button type="primary" @click="workLateTip = false">确 定</el-button>
</span>
</el-dialog>
<!--展示如下界面-->
<div>
<div class="operation" id="submit-display">
<div class="add-resource-btn fl" @click="choiceImg">
<span class="tips"><i class="iconfont"></i>上传文件</span>
<input type="file" name="file" class="webuploader-element-invisible"
@change="getFile" ref="filElem" id="submitFile">
</div>
<div class="multidelete fl" style="display: none;" id="piliang-delete"
@click="deleteZiYuan"><i
class="iconfont iconshanchu1"></i>批量删除
</div>
</div>
<el-progress id="showProgress" style="display:none;" :stroke-width="16"
:percentage="progressPercent"></el-progress>
<el-table
ref="multipleTable"
:data="tableFileList"
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
prop="submitHomeworkFileName"
label="文件名"
width="350">
</el-table-column>
<el-table-column
prop="submitHomeworkFileSize"
label="大小"
width="150">
</el-table-column>
<el-table-column
prop="submitHomeworkGrade"
label="成绩状态"
width="100">
</el-table-column>
<el-table-column
prop="submitHomeworkCreateTime"
label="上传时间"
width="220">
</el-table-column>
<el-table-column
width="300">
<template slot-scope="scope">
<a @click="preview(scope.row.submitHomeworkFilePath)"
class="homework-operation"
style="margin-left: 50px">预览</a>
<a class="homework-operation"
@click="saveFile(scope.row.submitHomeworkId)">下载</a>
<a @click="deleteOne(scope.row.submitHomeworkId)"
class="homework-operation">删除</a>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</div>
</div>
js代码
//上传本地文件
choiceImg() {
this.$refs.filElem.dispatchEvent(new MouseEvent('click'))
},
getFile() {
const inputFile = this.$refs.filElem.files[0];
//如果大于1G,提示用户
if (inputFile.size > 1048576000) {
this.$message({
message: '上传文件应小于1G',
type: 'error',
duration: 3000
});
return
}
//初始化为0,表示不是项目介绍视频
this.submitWork.submitHomeworkIntroduceVideo = "0"
// console.log(inputFile)
//视频类型:video/mp4
if (inputFile.type === "video/mp4") {
this.$message({
message: '上传视频将作为视频介绍',
type: 'info',
duration: 5000
});
//设置 1,表示标记为项目介绍视频
this.submitWork.submitHomeworkIntroduceVideo = "1"
}
let fileSize = inputFile.size / 1000;
let finalSize = 0;
if (fileSize > 1000) {
finalSize = fileSize / 1000;
this.fileSizeType = "MB"
} else {
finalSize = fileSize;
this.fileSizeType = "KB"
}
this.tempFileSize = finalSize;
this.fileName = inputFile.fileName
this.upload()
},
//上传一个新的资源
upload() {
this.submitWork.homeworkId = sessionStorage.getItem("homeworkId")
this.submitWork.studentId = sessionStorage.getItem("studentId")
this.submitWork.submitHomeworkFileSize = this.tempFileSize + "" + this.fileSizeType
// console.log(this.submitWork)
homeworkApi.submitHomework(this.submitWork)
.then(res => {
this.$message({
message: '作业信息提交成功',
type: 'success'
});
this.addZiYuanDis = false;
//提交作业的id存储在会话中
sessionStorage.setItem("finishWorkId", res.data.submitWork.submitHomeworkId)
//当已经存进数据库之后再进行修改
this.submit();
}).catch(
() => {
this.$message({
message: '作业信息提交失败!请重试!',
type: 'error'
});
}
)
},
//文件提交到本地云端存储
submit() {
var formData = new FormData();
const submitHomeworkId = sessionStorage.getItem("finishWorkId")
let file = this.$refs.filElem.files[0]
formData.append('file', file) // 'file' 这个名字要和后台获取文件的名字一样;
//显示进度条
document.getElementById("showProgress").style.display = "block";
document.getElementById("submit-display").style.display = "none";
let configs = {
headers: {
'Content-Type': 'multipart/form-data',
token: sessionStorage.getItem("token")
},
onUploadProgress: (progressEvent) => {
if (progressEvent.lengthComputable) { //是否存在进度
this.progressPercent = parseInt((progressEvent.loaded / progressEvent.total) * 100)
}
},
}
this.$axios.post('submitHomework/submitHomeworkFile/' + submitHomeworkId, formData, configs)
.then(
res => {
this.$message({
message: '作业上传成功',
type: 'success'
});
document.getElementById("showProgress").style.display = "none";
document.getElementById("submit-display").style.display = "block";
this.getAllZiYuan();
}).catch(error => {
this.$message({
message: '作业上传失败!请重试!',
type: 'error'
});
document.getElementById("showProgress").style.display = "none";
document.getElementById("submit-display").style.display = "block";
})
},
前端思路
分成两部,1.通过前端将文件的基本信息传送到后端进行储存,返回已储存的文件id,2.再将文件发送到后端储存。
储存文件信息
上传文件对象
后端上传下载代码
@RequestMapping("/submitHomeworkFile/{submitHomeworkId}")
public R submitHomeworkFile(@RequestParam("file") MultipartFile multipartFile, @PathVariable long submitHomeworkId, HttpServletRequest req) throws IOException {
System.out.println("id___________________"+submitHomeworkId);
SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
String format = sdf.format(new Date());//时间
// 获得项目在磁盘的地址,如:D:/eclipse-workspace/studyProject/youketangV0.0/youketang_ssm/target/classes//store/2023/02/19/
// String realPath = ResourceUtils.getURL("classpath:").getPath() + "/store" + format;
// /www/wwwroot/resource
String realPath = "D:" + "/store" + format;
// String realPath = "/www/wwwroot/resource" + "/store" + format;
// String realPath = req.getServletContext().getRealPath("/")+"/store"+format;
// getRealPath("/")方法返回的是项目在服务器的绝对路径(C:\Users\29395\AppData\Local\Temp\tomcat-docbase.4782946598994668439.8888\/store/2023/02/19/)
//由于是在temp临时文件,每次重启服务器,都找不到之前的文件url.
File fileDir = new File(realPath);
if (!fileDir.exists()) {
fileDir.mkdirs();
}
if (multipartFile != null) {
String fileName = multipartFile.getOriginalFilename();//获取名字
// 172.17.160.1为服务器的IP地址
// String url = req.getScheme() + "://" + "47.94.255.44" + ":" + req.getServerPort() + "/store" + format + fileName;
String url = req.getScheme() + "://" + "localhost" + ":" + req.getServerPort() + "/store" + format + fileName;
// transferTo(File dest) 将接收到的文件传输到给定的目标文件。
multipartFile.transferTo(new File(realPath, fileName));
String fileReal = fileDir + "//" + fileName;
// System.out.println(fileReal);
SubmitHomework submitHomework = submitHomeworkService.findSubmitHomeworkById(submitHomeworkId);
submitHomework.setSubmitHomeworkFileRealPath(fileReal);
submitHomework.setSubmitHomeworkFilePath(url);
submitHomework.setSubmitHomeworkFileName(multipartFile.getOriginalFilename());
submitHomeworkService.modifySubmitHomework(submitHomework);
return R.ok().data("path", url);
} else {
return R.ok().message("请选中文件");
}
}
@GetMapping("/downloadSubmitHomeworkFile/{submitHomeworkId}")
public void downloadSubmitHomeworkFile(@PathVariable("submitHomeworkId") long submitHomeworkId,
HttpServletResponse response) {
SubmitHomework submitHomework = submitHomeworkService.findSubmitHomeworkById(submitHomeworkId);
String fileRealPath = submitHomework.getSubmitHomeworkFileRealPath();
String fileName = submitHomework.getSubmitHomeworkFileName();
File file = new File(fileRealPath);
byte[] buffer = new byte[1024];
BufferedInputStream bis = null;
OutputStream os = null;
try {
//文件是否存在
if (file.exists()) {
response.setHeader("Access-Control-Allow-Origin", "*"); // 允许所有
//设置响应
response.setContentType("application/octet-stream;charset=UTF-8");
// 将响应头中的Content-Disposition暴露出来,不然前端获取不到
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
// 在响应头中的Content-Disposition里设置文件名称
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
// response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
os = response.getOutputStream();
bis = new BufferedInputStream(new FileInputStream(file));
while (bis.read(buffer) != -1) {
os.write(buffer);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bis != null) {
bis.close();
}
if (os != null) {
os.flush();
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
这个我放在d盘下面,需要修改映射路径
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 访问相对路径
// PS:注意文件路径最后的斜杠(文件分隔符),如果缺少了,就不能够正确的映射到相应的目录
String baseDocumentPath = "file:D:/document/";
String baseStorePath = "file:D:/store/";
// String baseDocumentPath = "file:/www/wwwroot/resource/document/";
// String baseStorePath = "file:/www/wwwroot/resource/store/";
// /www/wwwroot/resource
registry.addResourceHandler("/document
@RestController
@RequestMapping("/submitHomework")
@CrossOrigin
public class SubmitHomeworkController {
@Resource
private SubmitHomeworkService submitHomeworkService;
//根据课程号和人员id获取交的作业
@GetMapping("/getSubmitHomework")
public R getSubmitHomework(@RequestParam long homeworkId, @RequestParam long studentId) {
List<SubmitHomework> submitHomeWork = submitHomeworkService.selectHWByIds(homeworkId, studentId);
return R.ok().data("submitHomeworkList", submitHomeWork);
}
// @ApiOperation(value = "提交作业")
@PostMapping("/submitHomework")
public R submitHomework(@RequestBody SubmitHomework submitHomework) {
SubmitHomework submitWork = submitHomeworkService.increaseSubmitHomework(submitHomework);
return R.ok().data("submitWork", submitWork);
}
// @ApiOperation(value = "根据课程号和用户id获取交的所有作业")
@GetMapping("/getSubmitHomeworkList")
public R getSubmitHomeworkList(@RequestParam long courseId, @RequestParam long studentId) {
List<SubmitHomework> submitHomeworkList = submitHomeworkService.getSubmitHomeworkList(courseId, studentId);
return R.ok().data("submitHomeworkList", submitHomeworkList);
}
// 删除
@PostMapping("/removeSubmitHomework")
@Transactional
public R removeSubmitHomework(@RequestBody long[] submitHomeworkIds) {
boolean removeResult = false;
for (long submitHomeworkId : submitHomeworkIds) {
//通过id获取文件的物理地址,并对其删除。
// 将"\"替换成"/",java将“\”当成转义符。转化为:“C:/Users/29395/AppData/Local/...”
String filePath = this.submitHomeworkService.findFileRealPathById(submitHomeworkId);
if(filePath == null){
// 当路径为空
removeResult = submitHomeworkService.dropSubmitHomeworkById(submitHomeworkId);
}else{
// 不为空的时候
File file = new File(filePath.replace("\\", "/"));
removeResult = submitHomeworkService.dropSubmitHomeworkById(submitHomeworkId) && file.delete() ;
}
}
return removeResult ? R.ok() : R.error().message("删除失败!若视频为项目介绍,请先上传新的视频,才能删除旧视频。");
}
// 根据id获取提交的作业打分
@PostMapping("/markSubmitHomework")
public R markSubmitHomework(@RequestParam long studentId, @RequestParam String grade) {
boolean updateResult = submitHomeworkService.modifyGradeByStudentId(studentId,grade);
return updateResult?R.ok():R.error().message("打分失败!!!");
}
// "打回作业"
@PostMapping("/backSubmitHomework/{studentId}")
public R backSubmitHomework(@PathVariable long studentId) {
boolean updateResult = submitHomeworkService.modifyGradeBackByStudentId(studentId);
return updateResult?R.ok():R.error().message("打回作业失败!!!");
}
@RequestMapping("/submitHomeworkFile/{submitHomeworkId}")
public R submitHomeworkFile(@RequestParam("file") MultipartFile multipartFile, @PathVariable long submitHomeworkId, HttpServletRequest req) throws IOException {
System.out.println("id___________________"+submitHomeworkId);
SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
String format = sdf.format(new Date());//时间
// 获得项目在磁盘的地址,如:D:/eclipse-workspace/studyProject/youketangV0.0/youketang_ssm/target/classes//store/2023/02/19/
// String realPath = ResourceUtils.getURL("classpath:").getPath() + "/store" + format;
// /www/wwwroot/resource
String realPath = "D:" + "/store" + format;
// String realPath = "/www/wwwroot/resource" + "/store" + format;
// String realPath = req.getServletContext().getRealPath("/")+"/store"+format;
// getRealPath("/")方法返回的是项目在服务器的绝对路径(C:\Users\29395\AppData\Local\Temp\tomcat-docbase.4782946598994668439.8888\/store/2023/02/19/)
//由于是在temp临时文件,每次重启服务器,都找不到之前的文件url.
File fileDir = new File(realPath);
if (!fileDir.exists()) {
fileDir.mkdirs();
}
if (multipartFile != null) {
String fileName = multipartFile.getOriginalFilename();//获取名字
// 172.17.160.1为服务器的IP地址
// String url = req.getScheme() + "://" + "47.94.255.44" + ":" + req.getServerPort() + "/store" + format + fileName;
String url = req.getScheme() + "://" + "localhost" + ":" + req.getServerPort() + "/store" + format + fileName;
// transferTo(File dest) 将接收到的文件传输到给定的目标文件。
multipartFile.transferTo(new File(realPath, fileName));
String fileReal = fileDir + "//" + fileName;
// System.out.println(fileReal);
SubmitHomework submitHomework = submitHomeworkService.findSubmitHomeworkById(submitHomeworkId);
submitHomework.setSubmitHomeworkFileRealPath(fileReal);
submitHomework.setSubmitHomeworkFilePath(url);
submitHomework.setSubmitHomeworkFileName(multipartFile.getOriginalFilename());
submitHomeworkService.modifySubmitHomework(submitHomework);
return R.ok().data("path", url);
} else {
return R.ok().message("请选中文件");
}
}
@GetMapping("/downloadSubmitHomeworkFile/{submitHomeworkId}")
public void downloadSubmitHomeworkFile(@PathVariable("submitHomeworkId") long submitHomeworkId,
HttpServletResponse response) {
SubmitHomework submitHomework = submitHomeworkService.findSubmitHomeworkById(submitHomeworkId);
String fileRealPath = submitHomework.getSubmitHomeworkFileRealPath();
String fileName = submitHomework.getSubmitHomeworkFileName();
File file = new File(fileRealPath);
byte[] buffer = new byte[1024];
BufferedInputStream bis = null;
OutputStream os = null;
try {
//文件是否存在
if (file.exists()) {
response.setHeader("Access-Control-Allow-Origin", "*"); // 允许所有
//设置响应
response.setContentType("application/octet-stream;charset=UTF-8");
// 将响应头中的Content-Disposition暴露出来,不然前端获取不到
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
// 在响应头中的Content-Disposition里设置文件名称
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
// response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
os = response.getOutputStream();
bis = new BufferedInputStream(new FileInputStream(file));
while (bis.read(buffer) != -1) {
os.write(buffer);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bis != null) {
bis.close();
}
if (os != null) {
os.flush();
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
CorsConfig.java
package com.wang.youketang.common.config;
import com.wang.youketang.common.interceptor.JWTInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer{
@Override
public void addCorsMappings(CorsRegistry registry) {
// 允许跨域访问的路径 '/**'表示应用的所有方法
registry.addMapping("/**")
.allowedOrigins("*")
// .allowedOrigins("http://172.17.160.1:8080") //ip地址+端口号
// .allowedOrigins("http://172.18.29.108:8080") //前端vue的ip
// .allowedOrigins("http://172.17.160.1:8080") //本机的ip
// 允许跨域访问的来源 '*'表示所有域名来源
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
// 是否允许发送cookie true-允许 false-不允许 默认false。对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json,这个值只能设为true
.allowCredentials(true)
// 预检间隔时间1小时,单位为秒。指定本次预检请求的有效期,在有效期间,不用发出另一条预检请求。
// 浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段
// 浏览器发出CORS非简单请求,会在正式通信之前,增加一次OPTIONS查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
.maxAge(3600)
// 允许跨域请求可携带的header,'*'表所有header头。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定
.allowedHeaders("*");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 访问相对路径
// PS:注意文件路径最后的斜杠(文件分隔符),如果缺少了,就不能够正确的映射到相应的目录
String baseDocumentPath = "file:D:/document/";
String baseStorePath = "file:D:/store/";
// String baseDocumentPath = "file:/www/wwwroot/resource/document/";
// String baseStorePath = "file:/www/wwwroot/resource/store/";
// /www/wwwroot/resource
registry.addResourceHandler("/document/**").addResourceLocations(baseDocumentPath);
registry.addResourceHandler("/store/**").addResourceLocations(baseStorePath);
WebMvcConfigurer.super.addResourceHandlers(registry);
}
//注册拦截器
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JWTInterceptor())
.addPathPatterns("/**") //需要token验证的接口 一般是全部接口
.excludePathPatterns("/student/**","/teacher/**","/document/**","/store/**"); //
}
}
总结
到此这篇关于vue+springboot上传文件、图片、视频及回显到前端的文章就介绍到这了,更多相关vue springboot上传文件及回显内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!