You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
6.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.controller;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.annotation.IgnoreAuth;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.ConfigEntity;
import com.entity.EIException;
import com.service.ConfigService;
import com.utils.R;
/**
* 文件管理系统控制器
* 核心功能:处理文件上传/下载请求,管理系统静态资源
* 安全策略:@IgnoreAuth 使下载接口可公开访问
*/
@RestController
@RequestMapping("file") // 基础访问路径 /file
public class FileController {
@Autowired
private ConfigService configService; // 配置服务(用于存储特殊文件路径)
// ======================== 文件上传接口 ========================
/**
* 文件上传服务
* 路径POST /file/upload
* 参数:
* @RequestParam("file") MultipartFile file - 上传的文件对象
* String type - 文件类型标识(特殊处理标记)
* 流程:
* 1. 空文件校验 → 抛出自定义异常 EIException
* 2. 提取文件后缀名fileExt
* 3. 获取项目static资源目录路径
* 4. 在static下创建upload目录不存在时自动创建
* 5. 生成时间戳文件名(避免重名覆盖)
* 6. 保存文件到服务器
* 7. 特殊类型文件type="1")更新系统配置
* 返回值R.ok().put("file", fileName) 返回新文件名
*/
@RequestMapping("/upload")
@IgnoreAuth // 允许匿名上传(根据需求谨慎设置)
public R upload(@RequestParam("file") MultipartFile file, String type) throws Exception {
// 1. 空文件校验
if (file.isEmpty()) {
throw new EIException("上传文件不能为空");
}
// 2. 提取文件后缀png
String fileExt = file.getOriginalFilename()
.substring(file.getOriginalFilename().lastIndexOf(".") + 1);
// 3. 获取static资源目录
File path = new File(ResourceUtils.getURL("classpath:static").getPath());
if (!path.exists()) path = new File("");
// 4. 创建upload目录
File uploadDir = new File(path, "/upload/");
if (!uploadDir.exists()) uploadDir.mkdirs();
// 5. 构建新文件名(时间戳防重名)
String fileName = new Date().getTime() + "." + fileExt;
File dest = new File(uploadDir, fileName);
// 6. 保存文件
file.transferTo(dest);
/*
* 热部署文件同步(开发环境专用)
* 解除注释并将路径改为本地项目static绝对路径
* 示例FileUtils.copyFile(dest, new File("D:/project/src/main/resources/static/upload/"+fileName));
*/
// 7. 特殊文件类型处理(如人脸文件)
if ("1".equals(type)) {
// 查询或创建faceFile配置项
ConfigEntity faceConfig = configService.selectOne(
new EntityWrapper<ConfigEntity>().eq("name", "faceFile")
);
if (faceConfig == null) {
faceConfig = new ConfigEntity();
faceConfig.setName("faceFile");
faceConfig.setValue(fileName);
configService.insert(faceConfig);
} else {
faceConfig.setValue(fileName);
configService.updateById(faceConfig);
}
}
return R.ok().put("file", fileName);
}
// ======================== 文件下载接口 ========================
/**
* 文件下载服务
* 路径GET /file/download?fileName={文件名}
* 流程:
* 1. 定位static/upload目录
* 2. 检查文件是否存在
* 3. 设置HTTP响应头
* - ContentType: APPLICATION_OCTET_STREAM二进制流
* - Content-Disposition: attachment触发浏览器下载
* 4. 将文件转为字节流返回
* 安全说明:未做权限校验(@IgnoreAuth生产环境需添加安全控制
*/
@IgnoreAuth // 允许匿名下载
@RequestMapping("/download")
public ResponseEntity<byte[]> download(@RequestParam String fileName) {
try {
// 1. 获取static目录路径
File staticDir = new File(ResourceUtils.getURL("classpath:static").getPath());
if (!staticDir.exists()) staticDir = new File("");
// 2. 定位upload目录
File uploadDir = new File(staticDir, "/upload/");
if (!uploadDir.exists()) uploadDir.mkdirs();
// 3. 构建目标文件
File targetFile = new File(uploadDir, fileName);
// 4. 文件存在性检查
if (targetFile.exists()) {
// 5. 设置响应头(触发下载)
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", fileName);
// 6. 返回文件字节流
return new ResponseEntity<>(
FileUtils.readFileToByteArray(targetFile),
headers,
HttpStatus.OK
);
}
} catch (IOException e) {
e.printStackTrace();
}
// 7. 文件不存在或IO错误
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}