This commit is contained in:
2023-05-19 17:38:09 +08:00
parent e41797c750
commit 3dc6fb7828
77 changed files with 1000 additions and 256 deletions

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>qiaoba-modules</artifactId>
<groupId>com.qiaoba</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>qiaoba-module-file</artifactId>
<dependencies>
<dependency>
<groupId>com.qiaoba</groupId>
<artifactId>qiaoba-api-file</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,33 @@
package com.qiaoba.module.file.config;
import cn.hutool.core.util.URLUtil;
import com.qiaoba.common.base.constants.BaseConstant;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 配置静态文件资源服务器
*
* @author ailanyin
* @version 1.0
* @since 2022/2/28 0028 上午 9:12
*/
@Configuration
@Getter
@Setter
public class FileConfig implements WebMvcConfigurer {
@Value("${qiaoba.file-upload-path}")
private String uploadPath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(BaseConstant.RESOURCE_PREFIX + "/**")
.addResourceLocations(URLUtil.FILE_URL_PREFIX + uploadPath);
}
}

View File

@ -0,0 +1,41 @@
package com.qiaoba.module.file.controller;
import com.qiaoba.api.file.entity.File;
import com.qiaoba.common.base.result.AjaxResult;
import com.qiaoba.module.file.service.FileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* 文件管理 Web层
*
* @author ailanyin
* @version 1.0
* @since 2023/5/19 9:14
*/
@RestController
@RequestMapping("/file")
@RequiredArgsConstructor
@Tag(name = "文件管理")
public class FileController {
private final FileService fileService;
@PostMapping("/upload")
@Operation(summary = "上传文件")
public AjaxResult upload(MultipartFile file) {
AjaxResult ajax = AjaxResult.success();
ajax.put("url", fileService.upload(file));
ajax.put("fileName", file.getOriginalFilename());
return ajax;
}
@DeleteMapping
@Operation(summary = "删除文件")
public AjaxResult remove(@RequestBody File file) {
return fileService.delete(file.getUrl()) ? AjaxResult.success("文件删除成功") : AjaxResult.error("文件删除失败");
}
}

View File

@ -0,0 +1,13 @@
package com.qiaoba.module.file.service;
import com.qiaoba.api.file.service.FileApiService;
/**
* 文件管理 服务层
*
* @author ailanyin
* @version 1.0
* @since 2023/5/19 9:15
*/
public interface FileService extends FileApiService {
}

View File

@ -0,0 +1,39 @@
package com.qiaoba.module.file.service.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.common.base.constants.BaseConstant;
import com.qiaoba.common.base.exceptions.ServiceException;
import com.qiaoba.module.file.config.FileConfig;
import com.qiaoba.module.file.service.FileService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
/**
* 文件管理 服务层实现
*
* @author ailanyin
* @version 1.0
* @since 2023/5/19 9:15
*/
@Service
@RequiredArgsConstructor
public class FileServiceImpl implements FileService {
private FileConfig fileConfig;
@Override
public String upload(MultipartFile file) {
return com.qiaoba.module.file.utils.FileUtil.upload(file, fileConfig.getUploadPath());
}
@Override
public boolean delete(String path) {
String localPath = fileConfig.getUploadPath() + StrUtil.removePrefix(path, BaseConstant.RESOURCE_PREFIX);
if (FileUtil.isDirectory(localPath)) {
throw new ServiceException("删除路径异常, 请勿非法操作");
}
return FileUtil.del(localPath);
}
}

View File

@ -0,0 +1,130 @@
package com.qiaoba.module.file.utils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.common.base.constants.BaseConstant;
import com.qiaoba.common.base.exceptions.ServiceException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.Date;
/**
* 文件工具类
*
* @author ailanyin
* @version 1.0
* @since 2021/10/25 0025 上午 9:15
*/
public class FileUtil {
private static final String[] DEFAULT_ALLOWED_EXTENSION = {
// 图片
"bmp", "gif", "jpg", "jpeg", "png",
// word excel powerpoint
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
// 压缩文件
"rar", "zip", "gz", "bz2",
// 音频
"mp3", "wav", "wma", "mp2", "flac", "midi", "ra", "ape", "aac", "cda", "mov",
// 视频
"mp4", "avi", "rmvb", "blob",
// pdf
"pdf"};
/**
* @param file 上传的文件
* @return 文件全路径名称
*/
public static String upload(MultipartFile file, String path) {
// 获取文件后缀名
String extension = getExtension(file);
// 判断是否允许上传
isAllowedExtension(extension);
// 重命名文件
String fileName = extractFilename(extension);
// 日期 + 格式 分类
String dir = DateUtil.format(new Date(), "yyyy/MM/dd") + "/" + extension + "/";
path = path + dir;
// 新建文件
File newFile = getAbsoluteFile(fileName, path);
try {
file.transferTo(newFile);
return getPathFileName(fileName, path, dir);
} catch (IOException e) {
e.printStackTrace();
throw new ServiceException("文件上传失败, 请联系管理员处理");
}
}
/**
* 判断文件类型是否是允许上传的类型
*
* @param extension 文件类型
*/
private static void isAllowedExtension(String extension) {
boolean flag = true;
for (String str : DEFAULT_ALLOWED_EXTENSION) {
if (str.equalsIgnoreCase(extension)) {
flag = false;
}
}
if (flag) {
throw new ServiceException("不允许上传该文件类型");
}
}
/**
* 获取文件名的后缀
*
* @param file 表单文件
* @return 后缀名
*/
private static String getExtension(MultipartFile file) {
String fileName = file.getOriginalFilename();
if (StrUtil.isBlank(fileName)) {
throw new ServiceException("上传文件-获取文件后缀名失败");
}
return fileName.substring(fileName.lastIndexOf(".") + 1);
}
/**
* 编码文件名(UUID去除-)
*/
private static String extractFilename(String extension) {
return UUID.fastUUID().toString(true) + "." + extension;
}
/**
* 创建文件
*
* @param fileName 文件名
* @return file
*/
private static File getAbsoluteFile(String fileName, String path) {
File desc = new File(path + File.separator + fileName);
if (!desc.exists()) {
if (!desc.getParentFile().exists()) {
boolean result = desc.getParentFile().mkdirs();
if (!result) {
throw new ServiceException("上传文件-创建父目录失败");
}
}
}
return desc;
}
private static String getPathFileName(String fileName, String path, String dir) {
int dirLastIndex = path.length() + 1;
String currentDir = StringUtils.substring(path, dirLastIndex);
return currentDir + BaseConstant.RESOURCE_PREFIX + "/" + dir + fileName;
}
}

View File

@ -0,0 +1,11 @@
{
"groups": [
],
"properties": [
{
"name": "qiaoba.file-upload-path",
"type": "java.lang.String"
}
],
"hints": []
}

View File

@ -0,0 +1 @@
null not found