Files
biji/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/ImageController.java
黄孟 49eba5ee96 refactor(image): 优化图片上传功能
- 修改后端接口,使用 @RequestPart 注解替代 @RequestParam
- 前端调整图片上传逻辑,直接发送 File 对象
- 简化前端上传成功后的处理流程
2025-08-14 16:19:13 +08:00

140 lines
4.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.test.bijihoudaun.controller;
import cn.hutool.core.util.StrUtil;
import com.test.bijihoudaun.common.response.R;
import com.test.bijihoudaun.entity.Image;
import com.test.bijihoudaun.service.ImageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
@Tag(name = "markdown接口")
@RestController
@RequestMapping("/api/images")
public class ImageController {
@Value("${file.upload-dir}")
private String rootPath;
@Autowired
private ImageService imageService;
@Operation(summary = "上传图片")
@PostMapping
public R<Image> uploadImage(
@RequestPart("file") MultipartFile file,
@RequestParam(value = "userId", required = false) Long userId,
@RequestParam(value = "markdownId", required = false) Long markdownId) {
try {
Image image = imageService.uploadImage(file, userId, markdownId);
return R.success(image);
} catch (IOException e) {
return R.fail();
}
}
@Operation(summary = "根据id删除图片")
@PostMapping("/{id}")
public R<Void> deleteImage(@PathVariable Long id) {
boolean result = imageService.deleteImage(id);
if (result) {
return R.success();
} else {
return R.fail();
}
}
/**
* 在线预览图片、视频、音频、pdf 等浏览器可直接识别的类型)
*/
@GetMapping("/preview/{url}")
@Operation(summary = "在线预览", description = "浏览器直接打开文件流")
public void preview(@PathVariable String url, HttpServletResponse resp) throws IOException {
if (StrUtil.isBlank(url)) {
resp.setStatus(404);
R.fail("文件不存在");
}
File file = new File(rootPath + File.separator + url);
if (!file.exists()) {
resp.setStatus(404);
R.fail("文件不存在");
}
String contentTypeFromFileExtension = getContentTypeFromFileExtension(url);
// 设置正确的 MIME
resp.setContentType(contentTypeFromFileExtension);
// 设置文件长度,支持断点续传
resp.setContentLengthLong(file.length());
// 写出文件流
try (FileInputStream in = new FileInputStream(file)) {
StreamUtils.copy(in, resp.getOutputStream());
}
}
@Operation(summary = "根据url删除图片")
@PostMapping("/deleteByUrl")
public R<Void> deleteImageByUrl(@RequestParam String url) {
boolean result = imageService.deleteImageByUrl(url);
if (result) {
return R.success();
} else {
return R.fail();
}
}
@Operation(summary = "根据url批量删除图片")
@PostMapping("/batch")
public R<Void> deleteImageByUrls(@RequestBody List<String> urls) {
boolean result = imageService.deleteImageByUrls(urls);
if (result) {
return R.success();
} else {
return R.fail();
}
}
/**
* 根据文件扩展名获取内容类型
* @param fileName 文件名
* @return 对应的MIME类型
*/
private String getContentTypeFromFileExtension(String fileName) {
if (StrUtil.isBlank(fileName) || !StrUtil.contains(fileName, '.')) {
return "application/octet-stream";
}
String extension = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
switch (extension) {
case "jpg":
case "jpeg":
return "image/jpeg";
case "png":
return "image/png";
case "gif":
return "image/gif";
case "bmp":
return "image/bmp";
case "webp":
return "image/webp";
case "svg":
return "image/svg+xml";
default:
return "application/octet-stream";
}
}
}