二十三 、 文件上传
1、前端实现
<template>
<a-avatar :size="100">
<template #icon>
<img :src="userStore.userInfo.avatar+'?' + new Date().getTime()" alt="">
</template>
</a-avatar>
<a-upload
name="file"
:file-list="fileList"
:showUploadList="false"
:beforeUpload="beforeUpload"
:onChange="handleChange"
:multiple="false"
accept=".png,.jpg"
>
<a-button class="mt-4">
上传头像
</a-button>
</a-upload>
</template>
<script setup lang="ts">
import type { UnwrapRef } from 'vue';
import { updateUserAvatarApi } from '~/api/file/file.ts';
const { t } = useI18n()
const fileList = ref([]);
async function beforeUpload(file){
var fileName = file.name.substring(file.name.lastIndexOf('.') + 1)
if (fileName!='png' && fileName!='jpg') {
message.error('文件类型必须是png或jpg!')
return false
}
var fileSize=file.size;
if(fileSize > 3*1024*1024){
message.error("图片大小不能大于3M");
return false
}
try {
const formData = new FormData();
formData.append('file', file);
const response = await updateUserAvatarApi(formData);
if(response.data.code==1){
fileList.value=[];
userStore.userInfo.avatar=response.data.data;
message.success('头像上传成功');
}else{
message.error('头像上传失败,请重试');
}
} catch (error) {
message.error(error);
}
return false;
}
function handleChange(info) {
fileList.value = info.fileList.slice(-1);
}
</script>
export function updateUserAvatarApi(param: any) {
return usePost<FileUrl>('/upload/uploadUserAvater', param, {
token: true,
customDev: true,
loading: false,
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
export interface FileUrl {
data: string
}
2、后端实现
@Slf4j
@Configuration
public class ResourConfigure implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String osName=System.getProperty("os.name");
String fileUploadResources="/static/**";
String win="win";
if(osName.toLowerCase().startsWith(win)){
ApplicationHome applicationHome=new ApplicationHome(this.getClass());
String pre="file:"+applicationHome.getDir().getParentFile().getParentFile()+ "\\src\\main\\resources\\static\\";
registry.addResourceHandler(fileUploadResources)
.addResourceLocations(pre);
}else {
ApplicationHome applicationHome=new ApplicationHome(this.getClass());
String pre="file:"+applicationHome.getDir().getParentFile().getParentFile()+ "/src/main/resources/static/";
registry.addResourceHandler(fileUploadResources)
.addResourceLocations(pre);
}
}
}
server.port=8080
server.address=localhost
server.servlet.context-path=/
spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.max-request-size=5MB
@Component
public class FileUpload {
@Value("${server.servlet.context-path}")
private String contextPath;
@Value("${server.port}")
private String serverPort;
@Value("${server.address}")
private String serverAddress;
@Autowired
private ServletContext servletContext;
public String uploadFile(MultipartFile file, String folder) {
String originalFilename = file.getOriginalFilename();
if (originalFilename == null || originalFilename.isEmpty()) {
throw new IllegalArgumentException("文件名不能为空");
}
String ext = "." + originalFilename.substring(originalFilename.lastIndexOf('.') + 1);
String uuid = UUID.randomUUID().toString().replace("-", "");
String fileName = uuid + ext;
String pre = getResourcePath(folder);
String filePath = pre + fileName;
try {
file.transferTo(new File(filePath));
return getAccessPath(folder, fileName);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String uploadFile(MultipartFile file, String folder, String fileName) {
String originalFilename = file.getOriginalFilename();
if (originalFilename == null || originalFilename.isEmpty()) {
throw new IllegalArgumentException("文件名不能为空");
}
String ext = "." + originalFilename.substring(originalFilename.lastIndexOf('.') + 1);
fileName = fileName + ext;
String pre = getResourcePath(folder);
String filePath = pre + fileName;
try {
file.transferTo(new File(filePath));
return getAccessPath(folder, fileName);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String getResourcePath(String folder) {
String osName = System.getProperty("os.name");
String win = "win";
String projectRoot = System.getProperty("user.dir");
String staticPath;
if (osName.toLowerCase().startsWith(win)) {
staticPath = projectRoot + "\\src\\main\\resources\\static\\" + folder + "\\";
} else {
staticPath = projectRoot + "/src/main/resources/static/" + folder + "/";
}
File dir = new File(staticPath);
if (!dir.exists()) {
dir.mkdirs();
}
return staticPath;
}
private String getAccessPath(String folder, String fileName) {
return "http://" + serverAddress + ":" + serverPort + contextPath + "static/" + folder + "/" + fileName;
}
}
public class FileUploadFolder {
public static final String USER_AVATER_FOLDER = "user_avatar";
public static final String ACTIVITY_FOLDER = "activity";
}
@Tag(name="文件上传接口")
@RestController
@RequestMapping("/upload")
@Slf4j
public class UploadController {
@Autowired
private UserService userService;
@Operation(summary = "修改用户头像")
@PostMapping("/uploadUserAvater")
public ResponseResult uploadUserAvater(@RequestParam("file") MultipartFile file){
if(file.isEmpty()){
return ResponseResult.error("头像为空,请重新选择");
}
String imgUrl = userService.uploadUserAvater(file);
if(imgUrl==null){
return ResponseResult.error("头像上传失败");
}
return ResponseResult.success(imgUrl);
}
}
@Slf4j
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private final UserMapper userMapper;
@Autowired
private FileUpload fileUpload;
@Override
public String uploadUserAvater(MultipartFile file) {
Long uid = Long.parseLong(StpUtil.getLoginId().toString());
UserInfo userInfo = userMapper.getUserById(uid);
String imgUrl= fileUpload.uploadFile(file, FileUploadFolder.USER_AVATER_FOLDER,userInfo.getUsername());
if(imgUrl!=null) {
userInfo.setAvatar(imgUrl);
userMapper.updateById(userInfo);
log.info("头像上传成功:" + imgUrl);
return imgUrl;
}
return null;
}
}
3、测试与效果

