parent
43fb3d290f
commit
d8cf5ca419
@ -118,14 +118,6 @@
|
||||
<artifactId>tika-core</artifactId> <!-- 文件客户端:文件类型的识别 -->
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/io.minio/minio -->
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<version>8.5.14</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -1,31 +0,0 @@
|
||||
package com.ensign.crm.module.infra.config;
|
||||
|
||||
import io.minio.MinioClient;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @Description: minio配置
|
||||
* @Date: 29/11/2024 9:57 am
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "minio")
|
||||
public class MinioConfig {
|
||||
private String endpoint;
|
||||
private String accessKey;
|
||||
private String secretKey;
|
||||
private String bucketName;
|
||||
|
||||
@Bean
|
||||
public MinioClient minioClient() {
|
||||
return MinioClient.builder()
|
||||
.endpoint(endpoint)
|
||||
.credentials(accessKey, secretKey)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -100,10 +100,4 @@ public class FileController {
|
||||
return success(BeanUtils.toBean(pageResult, FileRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/upload/minio")
|
||||
@Operation(summary = "上传Minio")
|
||||
public CommonResult<String> uploadMinio(MultipartFile file) {
|
||||
return success(fileService.createMinioFile(file));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
package com.ensign.crm.module.infra.controller.admin.video;
|
||||
|
||||
import com.ensign.crm.framework.common.pojo.CommonResult;
|
||||
import com.ensign.crm.module.infra.service.file.FileService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.security.PermitAll;
|
||||
|
||||
/**
|
||||
* @Description: 播放minio中视频
|
||||
* @Date: 29/11/2024 10:27 am
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/infra/video")
|
||||
@Tag(name = "管理后台 - 视频")
|
||||
public class VideoController {
|
||||
|
||||
@Autowired
|
||||
private FileService fileService;
|
||||
|
||||
@GetMapping("/play")
|
||||
@Operation(summary = "播放视频")
|
||||
@PermitAll // 仅测试
|
||||
public CommonResult<String> play(@RequestParam String bucket, @RequestParam String path) {
|
||||
return CommonResult.success(fileService.readAsVideo(bucket, path));
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ import com.ensign.crm.module.infra.controller.admin.file.vo.file.FileCreateReqVO
|
||||
import com.ensign.crm.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||
import com.ensign.crm.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO;
|
||||
import com.ensign.crm.module.infra.dal.dataobject.file.FileDO;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 文件 Service 接口
|
||||
@ -64,18 +63,4 @@ public interface FileService {
|
||||
*/
|
||||
FilePresignedUrlRespVO getFilePresignedUrl(String path) throws Exception;
|
||||
|
||||
/**
|
||||
* 上传文件至minio
|
||||
* @return 上传后完整路径
|
||||
*/
|
||||
String createMinioFile(MultipartFile file);
|
||||
|
||||
/**
|
||||
* 视频播放
|
||||
*
|
||||
* @param bucket minio桶名
|
||||
* @param path 路径
|
||||
* @return stream
|
||||
*/
|
||||
String readAsVideo(String bucket, String path);
|
||||
}
|
||||
|
@ -5,20 +5,16 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.ensign.crm.framework.common.pojo.PageResult;
|
||||
import com.ensign.crm.framework.common.util.io.FileUtils;
|
||||
import com.ensign.crm.framework.common.util.object.BeanUtils;
|
||||
import com.ensign.crm.module.infra.framework.file.core.client.FileClient;
|
||||
import com.ensign.crm.module.infra.framework.file.core.client.s3.FilePresignedUrlRespDTO;
|
||||
import com.ensign.crm.module.infra.framework.file.core.utils.FileTypeUtils;
|
||||
import com.ensign.crm.module.infra.controller.admin.file.vo.file.FileCreateReqVO;
|
||||
import com.ensign.crm.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||
import com.ensign.crm.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO;
|
||||
import com.ensign.crm.module.infra.dal.dataobject.file.FileDO;
|
||||
import com.ensign.crm.module.infra.dal.mysql.file.FileMapper;
|
||||
import com.ensign.crm.module.infra.framework.file.core.client.FileClient;
|
||||
import com.ensign.crm.module.infra.framework.file.core.client.s3.FilePresignedUrlRespDTO;
|
||||
import com.ensign.crm.module.infra.framework.file.core.utils.FileTypeUtils;
|
||||
import com.ensign.crm.module.infra.utils.MinioUtils;
|
||||
import io.minio.MinioClient;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@ -30,7 +26,6 @@ import static com.ensign.crm.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXIS
|
||||
*
|
||||
* @author ENSIGN
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class FileServiceImpl implements FileService {
|
||||
|
||||
@ -40,12 +35,6 @@ public class FileServiceImpl implements FileService {
|
||||
@Resource
|
||||
private FileMapper fileMapper;
|
||||
|
||||
@Resource
|
||||
private MinioUtils minioUtils;
|
||||
|
||||
@Resource
|
||||
private MinioClient minioClient;
|
||||
|
||||
@Override
|
||||
public PageResult<FileDO> getFilePage(FilePageReqVO pageReqVO) {
|
||||
return fileMapper.selectPage(pageReqVO);
|
||||
@ -125,18 +114,4 @@ public class FileServiceImpl implements FileService {
|
||||
object -> object.setConfigId(fileClient.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createMinioFile(MultipartFile file) {
|
||||
return minioUtils.upload(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readAsVideo(String bucket, String path) {
|
||||
try {
|
||||
return minioUtils.preview(path);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,210 +0,0 @@
|
||||
package com.ensign.crm.module.infra.utils;
|
||||
|
||||
import cn.hutool.core.io.FastByteArrayOutputStream;
|
||||
import com.ensign.crm.module.infra.config.MinioConfig;
|
||||
import io.minio.*;
|
||||
import io.minio.http.Method;
|
||||
import io.minio.messages.Bucket;
|
||||
import io.minio.messages.Item;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: Minio工具
|
||||
* @Date: 29/11/2024 9:58 am
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MinioUtils {
|
||||
|
||||
@Autowired
|
||||
private MinioConfig prop;
|
||||
|
||||
@Resource
|
||||
private MinioClient minioClient;
|
||||
|
||||
/**
|
||||
* 查看存储bucket是否存在
|
||||
* @return boolean
|
||||
*/
|
||||
public Boolean bucketExists(String bucketName) {
|
||||
boolean found;
|
||||
try {
|
||||
found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建存储bucket
|
||||
* @return Boolean
|
||||
*/
|
||||
public Boolean makeBucket(String bucketName) {
|
||||
try {
|
||||
minioClient.makeBucket(MakeBucketArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* 删除存储bucket
|
||||
* @return Boolean
|
||||
*/
|
||||
public Boolean removeBucket(String bucketName) {
|
||||
try {
|
||||
minioClient.removeBucket(RemoveBucketArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* 获取全部bucket
|
||||
*/
|
||||
public List<Bucket> getAllBuckets() {
|
||||
try {
|
||||
return minioClient.listBuckets();
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param file 文件
|
||||
* @return Boolean
|
||||
*/
|
||||
public String upload(MultipartFile file) {
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
if (StringUtils.isBlank(originalFilename)){
|
||||
throw new RuntimeException("文件名为空");
|
||||
}
|
||||
String dateFolder = new SimpleDateFormat("yyyyMMdd").format(new Date());
|
||||
String fileHash;
|
||||
try {
|
||||
fileHash = DigestUtils.md5Hex(file.getInputStream());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("计算文件哈希值失败", e);
|
||||
}
|
||||
String fileExtension = StringUtils.substringAfterLast(originalFilename, ".");
|
||||
String objectName = String.format("/%s/%s.%s", dateFolder, fileHash, fileExtension);
|
||||
try {
|
||||
PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(prop.getBucketName()).object(objectName)
|
||||
.stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
|
||||
minioClient.putObject(objectArgs);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new RuntimeException("上传Minio失败");
|
||||
}
|
||||
return objectName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览图片
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
public String preview(String fileName){
|
||||
// 查看文件地址
|
||||
GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs().builder().bucket(prop.getBucketName()).object(fileName).method(Method.GET).build();
|
||||
try {
|
||||
return minioClient.getPresignedObjectUrl(build);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
* @param fileName 文件名称
|
||||
* @param res response
|
||||
* @return Boolean
|
||||
*/
|
||||
public void download(String fileName, HttpServletResponse res) {
|
||||
GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(prop.getBucketName())
|
||||
.object(fileName).build();
|
||||
try (GetObjectResponse response = minioClient.getObject(objectArgs)){
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()){
|
||||
while ((len=response.read(buf))!=-1){
|
||||
os.write(buf,0,len);
|
||||
}
|
||||
os.flush();
|
||||
byte[] bytes = os.toByteArray();
|
||||
res.setCharacterEncoding("utf-8");
|
||||
res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
|
||||
try (ServletOutputStream stream = res.getOutputStream()){
|
||||
stream.write(bytes);
|
||||
stream.flush();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看文件对象
|
||||
* @return 存储bucket内文件对象信息
|
||||
*/
|
||||
public List<Item> listObjects() {
|
||||
Iterable<Result<Item>> results = minioClient.listObjects(
|
||||
ListObjectsArgs.builder().bucket(prop.getBucketName()).build());
|
||||
List<Item> items = new ArrayList<>();
|
||||
try {
|
||||
for (Result<Item> result : results) {
|
||||
items.add(result.get());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param fileName
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public boolean remove(String fileName){
|
||||
try {
|
||||
minioClient.removeObject( RemoveObjectArgs.builder().bucket(prop.getBucketName()).object(fileName).build());
|
||||
}catch (Exception e){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -249,9 +249,3 @@ justauth:
|
||||
prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
|
||||
timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
|
||||
|
||||
minio:
|
||||
endpoint: http://127.0.0.1:9000
|
||||
bucketName: video
|
||||
accessKey: qTgkym1JPFY53UGEiDP8
|
||||
secretKey: swuXwUczZtLt08Qx6ffDzQEhQVEilGCfmcae7bLh
|
||||
|
||||
|
@ -12,8 +12,8 @@ spring:
|
||||
servlet:
|
||||
# 文件上传相关配置项
|
||||
multipart:
|
||||
max-file-size: 5GB # 单个文件大小
|
||||
max-request-size: 1TB # 设置总上传的文件大小
|
||||
max-file-size: 16MB # 单个文件大小
|
||||
max-request-size: 32MB # 设置总上传的文件大小
|
||||
|
||||
# Jackson 配置项
|
||||
jackson:
|
||||
|
Loading…
Reference in New Issue
Block a user