前端
1.处理modal框
<template>
<n-modal
v-model:show="modalVisible"
preset="card"
:title="title"
class="w-700px"
>
<n-space class="w-full pt-16px" :size="24" justify="end">
<n-button class="w-72px" @click="closeModal">取消</n-button>
<n-button class="w-72px" type="primary" @click="handleSubmit"
>确定</n-button
>
</n-space>
</n-modal>
</template>
<script setup lang="ts">
import { computed } from "vue";
const title = "上传作业"
interface Props {
/** 弹窗可见性 */
visible: boolean;
}
const props = withDefaults(defineProps<Props>(), {
visible: false,
});
interface Emits {
(e: "update:visible", visible: boolean): void;
}
const emit = defineEmits<Emits>();
const modalVisible = computed({
get() {
return props.visible;
},
set(visible) {
emit("update:visible", visible);
},
});
const closeModal = () => {
modalVisible.value = false;
};
const handleSubmit = () => {
window.$message?.success('上传成功')
closeModal()
}
</script>
<style scoped></style>
为方便使用Boolean类型,特设置为函数useBoolean
import { ref } from 'vue';
/**
* boolean组合式函数
* @param initValue 初始值
*/
export default function useBoolean(initValue = false) {
const bool = ref(initValue);
function setBool(value: boolean) {
bool.value = value;
}
function setTrue() {
setBool(true);
}
function setFalse() {
setBool(false);
}
function toggle() {
setBool(!bool.value);
}
return {
bool,
setBool,
setTrue,
setFalse,
toggle
};
}
父组件中导入子组件
<template>
<button @click="upload ">上传文件</button>
<upload-file v-model:visible="uploadVisble"></upload-file>
</n-card>
</template>
<script setup lang="ts">
const { bool: uploadVisble, setTrue: openUploadModal } = useBoolean();
const upload = () => {
openUploadModal()
};
</script>
<style scoped></style>
模态框实现效果
2.导入上传文件组件
大体组件
设置最多可支持多少个文件上传,这里我选择的是一个
<n-upload @before-upload="uploadFile" :max="1">
<n-upload-dragger abstract>
<n-text style="font-size: 16px">
点击或者拖动文件到该区域来上传
</n-text>
</n-upload-dragger>
</n-upload>
<script setup lang="ts">
const uploadFile = (options: { file: UploadFileInfo }) => {
let file = options.file.file
console.log('file',file)
}
</script>
传递数据
这是我需要传给后端的数据
添加jobId
interface Props {
/** 弹窗可见性 */
visible: boolean;
/** 作业Id */
jobId:number
}
const props = withDefaults(defineProps<Props>(), {
visible: false,
jobId:-1
});
父组件中传值
<upload-file v-model:visible="uploadVisble" :job-id="activeJobId"></upload-file>
<script setup lang="ts">
const activeJobId = ref(-1)
const upload = (row: JobDTO.jobList) => {
activeJobId.value = row.pkJId
openUploadModal()
window.$message?.info(`上传文件${row.pkJId}-${row.jName}`);
};
</script>
其他需要的数据和上面一致
3.请求接口
仅需要传入参数
form
即可
export function uploadFile(form:FormData){
return web.post('/job/upload',form)
}
后端
1.定义接数据的类
package com.leo.springbootbackend.pojo.vo;
public class UploadFile {
private String dirName;
private Integer jobId;
private Integer userId;
private Integer classId;
private String userNum;
private String userName;
@Override
public String toString() {
return "UploadFile{" +
"dirName='" + dirName + '\'' +
", jobId=" + jobId +
", userId=" + userId +
", classId=" + classId +
", userNum='" + userNum + '\'' +
", userName='" + userName + '\'' +
'}';
}
public String getDirName() {
return dirName;
}
public void setDirName(String dirName) {
this.dirName = dirName;
}
public Integer getJobId() {
return jobId;
}
public void setJobId(Integer jobId) {
this.jobId = jobId;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public Integer getClassId() {
return classId;
}
public void setClassId(Integer classId) {
this.classId = classId;
}
public String getUserNum() {
return userNum;
}
public void setUserNum(String userNum) {
this.userNum = userNum;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public UploadFile(String dirName, Integer jobId, Integer userId, Integer classId, String userNum, String userName) {
this.dirName = dirName;
this.jobId = jobId;
this.userId = userId;
this.classId = classId;
this.userNum = userNum;
this.userName = userName;
}
}
2.修改后端最大请求空间大小
在resources
->application.yaml
中添加下列配置
spring:
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
3.创建Dao层
void insertJobInfo(UploadFile formData);
4.处理service
接口
void uploadFile(MultipartFile file, UploadFile formData);
实现
@Override
public void uploadFile(MultipartFile uploadFile, UploadFile formData) {
String dirName = formData.getDirName();
String fileName = formData.getUserNum() + " " + formData.getUserName() ;
// 处理后缀
String oldName = uploadFile.getOriginalFilename();
fileName += oldName.substring(oldName.lastIndexOf("."));
File dir = new File(filePath + dirName);
if(!dir.isDirectory()){
dir.mkdirs();
}
// 覆盖
File override = new File(dirName , fileName);
if(override.exists()){
return;
}
try {
uploadFile.transferTo(new File(dir , fileName));
jobDao.insertJobInfo(formData);
} catch (IOException e) {
e.printStackTrace();
}
}
5.添加controller方法
形参
@RequestParam("File") MultipartFile file, UploadFile formData
实现方法
@PostMapping("/upload")
public CommonResult<Object> uploadFile(@RequestParam("File") MultipartFile file, UploadFile formData){
LocalDateTime localDateTime = LocalDateTime.now();
formData.setSubmitTime(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
jobService.uploadFile(file, formData);
return new CommonResult<>(200, "创建成功");
}