去除多余的模块和提那家tcp模块
This commit is contained in:
parent
1c3f87ad7a
commit
7975796964
|
|
@ -134,7 +134,7 @@ public class SidebandController extends BaseController {
|
|||
* @return
|
||||
*/
|
||||
@PostMapping("delDevice")
|
||||
@SysLog(title = "边带管理", businessType = OperaType.QUERY, logType = 0, module = "施工管控->边带管理", details = "解除绑定")
|
||||
@SysLog(title = "边带管理", businessType = OperaType.QUERY, module = "施工管控->边带管理", details = "解除绑定")
|
||||
public AjaxResult delDevice(@RequestBody SidebandDeviceVo vo) {
|
||||
return sidebandservice.delDevice(vo);
|
||||
}
|
||||
|
|
@ -145,7 +145,7 @@ public class SidebandController extends BaseController {
|
|||
* @return
|
||||
*/
|
||||
@PostMapping("bindDevice")
|
||||
@SysLog(title = "边带管理", businessType = OperaType.QUERY, logType = 0, module = "施工管控->边带管理", details = "绑定")
|
||||
@SysLog(title = "边带管理", businessType = OperaType.QUERY, module = "施工管控->边带管理", details = "绑定")
|
||||
public AjaxResult bindDevice(@RequestBody BindDeviceVo vo) {
|
||||
int sidebandId = vo.getSidebandId();
|
||||
List<Map<String,Object>> list= vo.getDeviceIds();
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
package com.bonus.mongodb;
|
||||
|
||||
import com.bonus.common.swagger.annotation.EnableCustomSwagger2;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
|
||||
@EnableCustomSwagger2
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
|
||||
public class BonusMongodbApplication {
|
||||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(BonusMongodbApplication.class, args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ MongoDB存储服务模块启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||
" .-------. ____ __ \n" +
|
||||
" | _ _ \\ \\ \\ / / \n" +
|
||||
" | ( ' ) | \\ _. / ' \n" +
|
||||
" |(_ o _) / _( )_ .' \n" +
|
||||
" | (_,_).' __ ___(_ o _)' \n" +
|
||||
" | |\\ \\ | || |(_,_)' \n" +
|
||||
" | | \\ `' /| `-' / \n" +
|
||||
" | | \\ / \\ / \n" +
|
||||
" ''-' `'-' `-..-' ");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
package com.bonus.mongodb.config;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoClients;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.gridfs.GridFSBucket;
|
||||
import com.mongodb.client.gridfs.GridFSBuckets;
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
|
||||
/**
|
||||
* @author coisini
|
||||
* @version 1.0
|
||||
* @Description MongoDB配置类
|
||||
* @date Apr 17, 2022
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "spring.data.mongodb")
|
||||
@Data
|
||||
public class MongoConfig {
|
||||
/**
|
||||
* 数据库配置信息
|
||||
*/
|
||||
private String database;
|
||||
private String host;
|
||||
private Integer port;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
// 移除静态修饰符,避免单例模式
|
||||
private MongoClient mongoClient;
|
||||
|
||||
// 使用@Bean注解,并在方法内部进行异常处理
|
||||
@Bean
|
||||
public MongoClient getMongoClient() {
|
||||
if (mongoClient == null) {
|
||||
try {
|
||||
mongoClient = MongoClients.create(String.format("mongodb://%s:%s@%s:%d/%s", URLEncoder.encode(username, "UTF-8"),URLEncoder.encode(password, "UTF-8"), host, port, database));
|
||||
} catch (Exception e) {
|
||||
// 在实际应用中应该有更详细的异常处理策略,例如记录日志并抛出自定义异常
|
||||
throw new RuntimeException("Failed to create MongoClient", e);
|
||||
}
|
||||
}
|
||||
return mongoClient;
|
||||
}
|
||||
|
||||
// 直接返回MongoDatabase实例,依赖注入会处理实例的获取
|
||||
public MongoDatabase getMongoDatabase() {
|
||||
return getMongoClient().getDatabase(database);
|
||||
}
|
||||
|
||||
// 创建GridFSBucket的@Bean方法,依赖注入MongoDatabase
|
||||
@Bean
|
||||
public GridFSBucket getGridFsBucket() {
|
||||
return GridFSBuckets.create(getMongoDatabase());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
package com.bonus.mongodb.controller;
|
||||
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.mongodb.damain.FileExportVo;
|
||||
import com.bonus.mongodb.service.MongodbService;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/mongodb/")
|
||||
@Slf4j
|
||||
public class MongodbController {
|
||||
|
||||
@Resource
|
||||
private MongodbService mongodbService;
|
||||
|
||||
@ApiOperation(value = "单文件上传")
|
||||
@PostMapping("uploadFile")
|
||||
public R<FileExportVo> uploadFile(MultipartFile file) {
|
||||
try {
|
||||
FileExportVo fileExportVo = mongodbService.uploadFile(file);
|
||||
return R.ok(fileExportVo);
|
||||
} catch (Exception e) {
|
||||
log.error("单文件上传", e);
|
||||
return R.fail();
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "多文件上传")
|
||||
@PostMapping("uploadFiles")
|
||||
public R<List<FileExportVo>> uploadFiles(MultipartFile[] files) {
|
||||
try {
|
||||
List<MultipartFile> multipartFiles = Arrays.asList(files);
|
||||
List<FileExportVo> list = mongodbService.uploadFiles(multipartFiles);
|
||||
return R.ok(list);
|
||||
} catch (Exception e) {
|
||||
log.error("多文件上传", e);
|
||||
return R.fail();
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "文件删除")
|
||||
@PostMapping("delFile")
|
||||
public R<T> delFile(String fileId) {
|
||||
try {
|
||||
mongodbService.removeFile(fileId);
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("文件删除", e);
|
||||
return R.fail();
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取文件base64")
|
||||
@PostMapping("getFileBase64")
|
||||
public R<byte[]> getFileBase64(String fileId) {
|
||||
try {
|
||||
FileExportVo fileExportVo = mongodbService.downloadFile(fileId);
|
||||
return R.ok(fileExportVo.getData());
|
||||
} catch (Exception e) {
|
||||
log.error("获取文件base64", e);
|
||||
return R.fail();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
package com.bonus.mongodb.damain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FileExportVo implements Serializable {
|
||||
|
||||
private String file;
|
||||
|
||||
private String fileId;
|
||||
|
||||
private String fileName;
|
||||
|
||||
private String contentType;
|
||||
|
||||
private String suffix;
|
||||
|
||||
private long fileSize;
|
||||
|
||||
private String sourceId;
|
||||
|
||||
private String id;
|
||||
|
||||
private String fileType;
|
||||
/**
|
||||
* 资源类型
|
||||
*/
|
||||
private String sourceType;
|
||||
|
||||
private String updaetTime;
|
||||
|
||||
private byte[] data;
|
||||
|
||||
public FileExportVo(MongoFile mongoFile) {
|
||||
BeanUtil.copyProperties(mongoFile, this);
|
||||
if (Objects.nonNull(mongoFile.getContent())) {
|
||||
this.data = mongoFile.getContent().getData();
|
||||
}
|
||||
this.fileId = mongoFile.getId();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
package com.bonus.mongodb.damain;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import org.bson.types.Binary;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
@Builder
|
||||
@Data
|
||||
@Document(collection = "files")
|
||||
public class MongoFile {
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@Id
|
||||
public String id;
|
||||
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
public String fileName;
|
||||
|
||||
/**
|
||||
* 文件大小
|
||||
*/
|
||||
public long fileSize;
|
||||
|
||||
/**
|
||||
* 上传时间
|
||||
*/
|
||||
public String uploadDate;
|
||||
|
||||
/**
|
||||
* MD5值
|
||||
*/
|
||||
public String md5;
|
||||
|
||||
/**
|
||||
* 文件内容
|
||||
*/
|
||||
private Binary content;
|
||||
|
||||
/**
|
||||
* 文件类型
|
||||
*/
|
||||
public String contentType;
|
||||
|
||||
/**
|
||||
* 文件后缀名
|
||||
*/
|
||||
public String suffix;
|
||||
|
||||
/**
|
||||
* 文件描述
|
||||
*/
|
||||
public String description;
|
||||
|
||||
/**
|
||||
* 大文件管理GridFS的ID
|
||||
*/
|
||||
private String gridFsId;
|
||||
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
package com.bonus.mongodb.repository;
|
||||
|
||||
import com.bonus.mongodb.damain.MongoFile;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
public interface MongoFileRepository extends MongoRepository<MongoFile, String> {
|
||||
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
package com.bonus.mongodb.service;
|
||||
|
||||
import com.bonus.mongodb.damain.FileExportVo;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface MongodbService {
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param file
|
||||
* @return FileExportVo
|
||||
* @throws Exception
|
||||
* @description
|
||||
* @date 2024/3/11 15:44
|
||||
*/
|
||||
FileExportVo uploadFile(MultipartFile file) throws Exception;
|
||||
|
||||
/**
|
||||
* 多文件上传
|
||||
*
|
||||
* @param files
|
||||
* @return
|
||||
*/
|
||||
List<FileExportVo> uploadFiles(List<MultipartFile> files);
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param fileId
|
||||
* @return
|
||||
*/
|
||||
FileExportVo downloadFile(String fileId);
|
||||
|
||||
/**
|
||||
* 文件删除
|
||||
*
|
||||
* @param fileId
|
||||
*/
|
||||
void removeFile(String fileId);
|
||||
}
|
||||
|
|
@ -1,279 +0,0 @@
|
|||
package com.bonus.mongodb.service.impl;
|
||||
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.bonus.common.core.utils.DateUtils;
|
||||
import com.bonus.mongodb.damain.FileExportVo;
|
||||
import com.bonus.mongodb.damain.MongoFile;
|
||||
import com.bonus.mongodb.repository.MongoFileRepository;
|
||||
import com.bonus.mongodb.service.MongodbService;
|
||||
import com.bonus.mongodb.utils.Md5Util;
|
||||
import com.mongodb.client.gridfs.GridFSBucket;
|
||||
import com.mongodb.client.gridfs.GridFSDownloadStream;
|
||||
import com.mongodb.client.gridfs.model.GridFSFile;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bson.types.Binary;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.gridfs.GridFsResource;
|
||||
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Objects;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class MongodbServiceImpl implements MongodbService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MongodbServiceImpl.class);
|
||||
private final MongoFileRepository mongoFileRepository;
|
||||
private final MongoTemplate mongoTemplate;
|
||||
private final GridFsTemplate gridFsTemplate;
|
||||
private final GridFSBucket gridFSBucket;
|
||||
|
||||
private static final int MAX_SIZE = 16777216;
|
||||
private static final String SUFFIX = ".";
|
||||
|
||||
|
||||
/**
|
||||
* 多文件上传
|
||||
*
|
||||
* @param files
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<FileExportVo> uploadFiles(List<MultipartFile> files) {
|
||||
|
||||
return files.stream().map(file -> {
|
||||
try {
|
||||
return this.uploadFile(file);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public FileExportVo uploadFile(MultipartFile file) throws Exception {
|
||||
if (file.getSize() > MAX_SIZE) {
|
||||
return this.saveGridFsFile(file);
|
||||
} else {
|
||||
return this.saveBinaryFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param fileId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public FileExportVo downloadFile(String fileId) {
|
||||
Optional<MongoFile> option = this.getBinaryFileById(fileId);
|
||||
|
||||
if (option.isPresent()) {
|
||||
MongoFile mongoFile = option.get();
|
||||
if (Objects.isNull(mongoFile.getContent())) {
|
||||
option = this.getGridFsFileById(fileId);
|
||||
}
|
||||
}
|
||||
|
||||
return option.map(FileExportVo::new).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件删除
|
||||
*
|
||||
* @param fileId
|
||||
*/
|
||||
@Override
|
||||
public void removeFile(String fileId) {
|
||||
Optional<MongoFile> option = this.getBinaryFileById(fileId);
|
||||
|
||||
if (option.isPresent()) {
|
||||
if (Objects.nonNull(option.get().getGridFsId())) {
|
||||
this.removeGridFsFile(fileId);
|
||||
} else {
|
||||
this.removeBinaryFile(fileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除Binary文件
|
||||
*
|
||||
* @param fileId
|
||||
*/
|
||||
public void removeBinaryFile(String fileId) {
|
||||
mongoFileRepository.deleteById(fileId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除GridFs文件
|
||||
*
|
||||
* @param fileId
|
||||
*/
|
||||
public void removeGridFsFile(String fileId) {
|
||||
// TODO 根据id查询文件
|
||||
MongoFile mongoFile = mongoTemplate.findById(fileId, MongoFile.class);
|
||||
if (Objects.nonNull(mongoFile)) {
|
||||
// TODO 根据文件ID删除fs.files和fs.chunks中的记录
|
||||
Query deleteFileQuery = new Query().addCriteria(Criteria.where("filename").is(mongoFile.getGridFsId()));
|
||||
gridFsTemplate.delete(deleteFileQuery);
|
||||
// TODO 删除集合mongoFile中的数据
|
||||
Query deleteQuery = new Query(Criteria.where("id").is(fileId));
|
||||
mongoTemplate.remove(deleteQuery, MongoFile.class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存Binary文件(小文件)
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public FileExportVo saveBinaryFile(MultipartFile file) throws Exception {
|
||||
|
||||
String suffix = getFileSuffix(file);
|
||||
MongoFile mongoFile = mongoFileRepository.save(
|
||||
MongoFile.builder()
|
||||
.fileName(file.getOriginalFilename())
|
||||
.fileSize(file.getSize())
|
||||
.content(new Binary(file.getBytes()))
|
||||
.contentType(file.getContentType())
|
||||
.uploadDate(DateUtils.getTime())
|
||||
.suffix(suffix)
|
||||
.md5(Md5Util.getMd5(file.getInputStream()))
|
||||
.build()
|
||||
);
|
||||
|
||||
return new FileExportVo(mongoFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存GridFs文件(大文件)
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public FileExportVo saveGridFsFile(MultipartFile file) throws Exception {
|
||||
String suffix = getFileSuffix(file);
|
||||
|
||||
String gridFsId = this.storeFileToGridFs(file.getInputStream(), file.getContentType());
|
||||
|
||||
MongoFile mongoFile = mongoTemplate.save(
|
||||
MongoFile.builder()
|
||||
.fileName(file.getOriginalFilename())
|
||||
.fileSize(file.getSize())
|
||||
.contentType(file.getContentType())
|
||||
.uploadDate(DateUtils.getTime())
|
||||
.suffix(suffix)
|
||||
.md5(Md5Util.getMd5(file.getInputStream()))
|
||||
.gridFsId(gridFsId)
|
||||
.build()
|
||||
);
|
||||
|
||||
return new FileExportVo(mongoFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件到Mongodb的GridFs中
|
||||
*
|
||||
* @param in
|
||||
* @param contentType
|
||||
* @return
|
||||
*/
|
||||
public String storeFileToGridFs(InputStream in, String contentType) throws IOException {
|
||||
try {
|
||||
String gridFsId = IdUtil.simpleUUID();
|
||||
// TODO 将文件存储进GridFS中
|
||||
gridFsTemplate.store(in, gridFsId, contentType);
|
||||
return gridFsId;
|
||||
}catch (Exception e){
|
||||
log.error("上传文件到Mongodb的GridFs中失败",e);
|
||||
}
|
||||
finally {
|
||||
in.close();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Binary文件
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public Optional<MongoFile> getBinaryFileById(String id) {
|
||||
return mongoFileRepository.findById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Grid文件
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public Optional<MongoFile> getGridFsFileById(String id) {
|
||||
MongoFile mongoFile = mongoTemplate.findById(id, MongoFile.class);
|
||||
if (Objects.nonNull(mongoFile)) {
|
||||
Query gridQuery = new Query().addCriteria(Criteria.where("filename").is(mongoFile.getGridFsId()));
|
||||
try {
|
||||
// TODO 根据id查询文件
|
||||
GridFSFile fsFile = gridFsTemplate.findOne(gridQuery);
|
||||
// TODO 打开流下载对象
|
||||
GridFSDownloadStream in = gridFSBucket.openDownloadStream(fsFile.getObjectId());
|
||||
if (in.getGridFSFile().getLength() > 0) {
|
||||
// TODO 获取流对象
|
||||
GridFsResource resource = new GridFsResource(fsFile, in);
|
||||
// TODO 获取数据
|
||||
mongoFile.setContent(new Binary(IoUtil.readBytes(resource.getInputStream())));
|
||||
return Optional.of(mongoFile);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件后缀
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
private String getFileSuffix(MultipartFile file) {
|
||||
String suffix = "";
|
||||
if (Objects.requireNonNull(file.getOriginalFilename()).contains(SUFFIX)) {
|
||||
suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||
}
|
||||
return suffix;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
package com.bonus.mongodb.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* @author 10488
|
||||
* @version 1.0
|
||||
* @Description MD5工具类
|
||||
* @date Apr 8, 2022
|
||||
*/
|
||||
public class Md5Util {
|
||||
/**
|
||||
* 获取该输入流的MD5值
|
||||
*/
|
||||
public static String getMd5(InputStream is) throws NoSuchAlgorithmException, IOException {
|
||||
StringBuffer md5 = new StringBuffer();
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] dataBytes = new byte[1024];
|
||||
|
||||
int nread = 0;
|
||||
while ((nread = is.read(dataBytes)) != -1) {
|
||||
md.update(dataBytes, 0, nread);
|
||||
}
|
||||
;
|
||||
byte[] mdbytes = md.digest();
|
||||
|
||||
// convert the byte to hex format
|
||||
for (int i = 0; i < mdbytes.length; i++) {
|
||||
md5.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
|
||||
}
|
||||
is.close();
|
||||
return md5.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
# Tomcat
|
||||
server:
|
||||
port: 9206
|
||||
|
||||
# Spring
|
||||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: bonus-mongodb
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: dev
|
||||
cloud:
|
||||
nacos:
|
||||
username: nacos
|
||||
password: nacos
|
||||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: 192.168.0.14:8848
|
||||
namespace: f1fcd3ea-9460-4597-8acd-0f334527017c
|
||||
config:
|
||||
# 配置中心地址
|
||||
server-addr: 192.168.0.14:8848
|
||||
namespace: f1fcd3ea-9460-4597-8acd-0f334527017c
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
shared-configs:
|
||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
<?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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-modules</artifactId>
|
||||
<version>24.6.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>bonus-obs</artifactId>
|
||||
<description>
|
||||
bonus-modules-obs存储服务
|
||||
</description>
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos Config -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Sentinel -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringBoot Actuator -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- FastDFS -->
|
||||
<dependency>
|
||||
<groupId>com.github.tobato</groupId>
|
||||
<artifactId>fastdfs-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Minio -->
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<version>${minio.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- bonus Api System -->
|
||||
<dependency>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-api-system</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- bonus Common Swagger -->
|
||||
<dependency>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-common-swagger</artifactId>
|
||||
</dependency>
|
||||
<!-- huaweicloud obs -->
|
||||
<dependency>
|
||||
<groupId>com.huaweicloud</groupId>
|
||||
<artifactId>esdk-obs-java-bundle</artifactId>
|
||||
<version>3.23.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!--加密依赖包-->
|
||||
<dependency>
|
||||
<groupId>com.github.ulisesbocchio</groupId>
|
||||
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
package com.bonus.obs;
|
||||
|
||||
import com.bonus.common.swagger.annotation.EnableCustomSwagger2;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
|
||||
@EnableCustomSwagger2
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
|
||||
public class BonusObsApplication {
|
||||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(BonusObsApplication.class, args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ obs存储服务模块启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||
" .-------. ____ __ \n" +
|
||||
" | _ _ \\ \\ \\ / / \n" +
|
||||
" | ( ' ) | \\ _. / ' \n" +
|
||||
" |(_ o _) / _( )_ .' \n" +
|
||||
" | (_,_).' __ ___(_ o _)' \n" +
|
||||
" | |\\ \\ | || |(_,_)' \n" +
|
||||
" | | \\ `' /| `-' / \n" +
|
||||
" | | \\ / \\ / \n" +
|
||||
" ''-' `'-' `-..-' ");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
package com.bonus.obs.config;
|
||||
|
||||
import com.obs.services.ObsClient;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "obs")
|
||||
public class ObsConfig {
|
||||
|
||||
private String endpoint;
|
||||
private String ak;
|
||||
private String sk;
|
||||
private String bucket;
|
||||
|
||||
|
||||
|
||||
public String getEndpoint() {
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
public void setEndpoint(String endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
public String getAk() {
|
||||
return ak;
|
||||
}
|
||||
|
||||
public void setAk(String ak) {
|
||||
this.ak = ak;
|
||||
}
|
||||
|
||||
public String getSk() {
|
||||
return sk;
|
||||
}
|
||||
|
||||
public void setSk(String sk) {
|
||||
this.sk = sk;
|
||||
}
|
||||
|
||||
public String getBucket() {
|
||||
return bucket;
|
||||
}
|
||||
|
||||
public void setBucket(String bucket) {
|
||||
this.bucket = bucket;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
package com.bonus.obs.controller;
|
||||
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.common.core.utils.file.FileUtils;
|
||||
import com.bonus.obs.service.ObsService;
|
||||
import com.obs.services.model.DeleteObjectResult;
|
||||
import com.obs.services.model.ObsObject;
|
||||
import com.obs.services.model.PutObjectResult;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/obs")
|
||||
public class ObsController {
|
||||
@Resource
|
||||
private ObsService service;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param param 文件流
|
||||
* @return 文件信息
|
||||
*/
|
||||
@PostMapping("/upload")
|
||||
public R<PutObjectResult> uploadFile(MultipartFile param) {
|
||||
return service.uploadFile(param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件从OBS
|
||||
*
|
||||
* @param objectKey 文件在OBS中的键
|
||||
*/
|
||||
@PostMapping("/delete")
|
||||
public R<DeleteObjectResult> deleteFile(String objectKey) {
|
||||
return service.deleteFile(objectKey);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param objectKey obs文件存储地址
|
||||
*/
|
||||
@GetMapping("/download")
|
||||
public void download(HttpServletResponse response, @RequestParam String objectKey) {
|
||||
R<ObsObject> obsObjectR = service.downloadFile(objectKey);
|
||||
try {
|
||||
if (R.isError(obsObjectR)) {
|
||||
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
||||
return;
|
||||
}
|
||||
if (obsObjectR.getData() == null) {
|
||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
||||
return;
|
||||
}
|
||||
InputStream inputStream = obsObjectR.getData().getObjectContent();
|
||||
String safeFileName = FileUtils.getFileNameFromPath(objectKey);
|
||||
String encodedFileName = URLEncoder.encode(safeFileName, StandardCharsets.UTF_8.toString());
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedFileName + "\"");
|
||||
try (OutputStream outputStream = response.getOutputStream()) {
|
||||
byte[] buffer = new byte[8192];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
outputStream.flush();
|
||||
} catch (IOException e) {
|
||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
||||
} catch (Exception e) {
|
||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
package com.bonus.obs.domain;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* OBS(Object Storage Service)信息类。
|
||||
* 用于封装与OBS对象相关的元数据信息。
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
public class ObsInfo {
|
||||
/**
|
||||
* 对象的名称。
|
||||
* 代表OBS对象的唯一标识。
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 对象在OBS中的存储路径。
|
||||
* 包含桶(bucket)名称和对象在桶内的相对路径。
|
||||
*/
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 对象的大小。
|
||||
* 以字符串形式表示,可能包含单位(如字节、KB、MB等)。
|
||||
*/
|
||||
private String length;
|
||||
|
||||
/**
|
||||
* 对象的文件类型。
|
||||
* 用于标识对象的MIME类型,例如text/plain、image/jpeg等。
|
||||
*/
|
||||
private String fileType;
|
||||
|
||||
/**
|
||||
* 对象所属的桶(bucket)的名称。
|
||||
* 每个桶在OBS中都是唯一的,用于存储对象。
|
||||
*/
|
||||
private String bucketName;
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
package com.bonus.obs.service;
|
||||
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.obs.services.model.DeleteObjectResult;
|
||||
import com.obs.services.model.ObsObject;
|
||||
import com.obs.services.model.PutObjectResult;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface ObsService {
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param file 文件流
|
||||
* @return 文件信息
|
||||
*/
|
||||
R<PutObjectResult> uploadFile(MultipartFile file);
|
||||
|
||||
/**
|
||||
* 删除文件从OBS
|
||||
*
|
||||
* @param objectKey 文件在OBS中的键
|
||||
*/
|
||||
public R<DeleteObjectResult> deleteFile(String objectKey);
|
||||
|
||||
/**
|
||||
* 下载文件从OBS
|
||||
*
|
||||
* @param objectKey 文件在OBS中的键
|
||||
*/
|
||||
public R<ObsObject> downloadFile(String objectKey);
|
||||
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param files 文件流
|
||||
* @return 文件信息
|
||||
*/
|
||||
R<PutObjectResult> uploadFiles(MultipartFile[] files);
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
package com.bonus.obs.service.impl;
|
||||
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.common.core.utils.file.FileUtils;
|
||||
import com.bonus.obs.service.ObsService;
|
||||
import com.bonus.obs.utils.ObsUtils;
|
||||
import com.obs.services.model.DeleteObjectResult;
|
||||
import com.obs.services.model.ObsObject;
|
||||
import com.obs.services.model.PutObjectResult;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
|
||||
@Service
|
||||
public class ObsServiceImpl implements ObsService {
|
||||
@Resource
|
||||
private ObsUtils obsUtils;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param file 文件流
|
||||
* @return 文件信息
|
||||
*/
|
||||
@Override
|
||||
public R<PutObjectResult> uploadFile(MultipartFile file) {
|
||||
try {
|
||||
String objectKey = file.getOriginalFilename();
|
||||
objectKey = FileUtils.generateObjectName(objectKey);
|
||||
return obsUtils.uploadFile(objectKey, FileUtils.multipartFileToFile(file));
|
||||
} catch (Exception e) {
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件从OBS
|
||||
*
|
||||
* @param objectKey 文件在OBS中的键
|
||||
*/
|
||||
@Override
|
||||
public R<DeleteObjectResult> deleteFile(String objectKey) {
|
||||
return obsUtils.deleteFile(objectKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件从OBS
|
||||
*
|
||||
* @param objectKey 文件在OBS中的键
|
||||
*/
|
||||
@Override
|
||||
public R<ObsObject> downloadFile(String objectKey) {
|
||||
return obsUtils.downloadFile(objectKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param files 文件流
|
||||
* @return 文件信息
|
||||
*/
|
||||
@Override
|
||||
public R<PutObjectResult> uploadFiles(MultipartFile[] files) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
package com.bonus.obs.utils;
|
||||
|
||||
import com.bonus.common.core.utils.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class FileUtils {
|
||||
/**
|
||||
* 检查MultipartFile是否有效(不为空且大小不超过5GB)
|
||||
*
|
||||
* @param file MultipartFile对象
|
||||
* @return 文件有效返回true,否则返回false
|
||||
*/
|
||||
public static boolean isValidFile(MultipartFile file) {
|
||||
if (file == null || file.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
// 文件大小限制为5GB
|
||||
long maxSizeInBytes = 5L * 1024 * 1024 * 1024;
|
||||
return file.getSize() <= maxSizeInBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成统一路径的objectName
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return 生成的objectName
|
||||
*/
|
||||
public static String generateObjectName(String fileName) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
|
||||
String datePath = sdf.format(new Date());
|
||||
return "uploads/" + datePath + "/" + fileName;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isValidOssFilePath(String ossFilePath) {
|
||||
// 根据实际情况添加对ossFilePath的校验逻辑,确保其只包含安全的字符
|
||||
return StringUtils.hasText(ossFilePath) && ossFilePath.matches("^[\\w\\d\\-\\_\\.]+$");
|
||||
}
|
||||
|
||||
public static String sanitizeFileName(String fileName) {
|
||||
// 避免文件名注入,移除或替换不安全的字符
|
||||
return fileName.replaceAll("[^a-zA-Z0-9\\.\\-_]", "_");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从文件路径中提取文件名
|
||||
* @param ossFilePath 文件路径
|
||||
* @return 文件名
|
||||
*/
|
||||
public static String getFileNameFromPath(String ossFilePath) {
|
||||
Path path = Paths.get(ossFilePath);
|
||||
return path.getFileName().toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MultipartFile 转 File
|
||||
*
|
||||
* @param multiFile MultipartFile对象
|
||||
* @return 转换后的File对象
|
||||
*/
|
||||
public static File multipartFileToFile(MultipartFile multiFile) {
|
||||
try {
|
||||
String fileName = multiFile.getOriginalFilename();
|
||||
if (fileName == null) {
|
||||
return null;
|
||||
}
|
||||
String prefix = fileName.substring(0, fileName.lastIndexOf("."));
|
||||
String suffix = fileName.substring(fileName.lastIndexOf("."));
|
||||
File file = File.createTempFile(prefix, suffix);
|
||||
multiFile.transferTo(file);
|
||||
return file;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
package com.bonus.obs.utils;
|
||||
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.obs.config.ObsConfig;
|
||||
import com.obs.services.ObsClient;
|
||||
import com.obs.services.model.DeleteObjectResult;
|
||||
import com.obs.services.model.GetObjectRequest;
|
||||
import com.obs.services.model.ObsObject;
|
||||
import com.obs.services.model.PutObjectResult;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@Service
|
||||
public class ObsUtils {
|
||||
|
||||
@Resource
|
||||
private ObsConfig obsConfig;
|
||||
/**
|
||||
* obs 客户端
|
||||
*/
|
||||
private ObsClient obsClient;
|
||||
|
||||
/**
|
||||
* 初始化信息
|
||||
* 构建OSS客户端实例
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
obsClient = new ObsClient(obsConfig.getAk(), obsConfig.getSk(), obsConfig.getEndpoint());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件到OBS
|
||||
*
|
||||
* @param file 要上传的文件
|
||||
* @return 上传结果
|
||||
*/
|
||||
public R<PutObjectResult> uploadFile(String objectKey, File file) {
|
||||
return R.ok(obsClient.putObject(obsConfig.getBucket(), objectKey, file));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件从OBS
|
||||
*
|
||||
* @param objectKey 文件在OBS中的键
|
||||
*/
|
||||
public R<ObsObject> downloadFile(String objectKey) {
|
||||
if (!doesObjectExist(objectKey)) {
|
||||
return R.fail("文件不存在");
|
||||
}
|
||||
return R.ok(obsClient.getObject(new GetObjectRequest(obsConfig.getBucket(), objectKey)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件从OBS
|
||||
*
|
||||
* @param objectKey 文件在OBS中的键
|
||||
*/
|
||||
public R<DeleteObjectResult> deleteFile(String objectKey) {
|
||||
if (!doesObjectExist(objectKey)) {
|
||||
return R.fail("文件不存在");
|
||||
}
|
||||
return R.ok(obsClient.deleteObject(obsConfig.getBucket(), objectKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件是否存在
|
||||
*
|
||||
* @param objectKey 文件在OBS中的键
|
||||
* @return 如果文件存在则返回true,否则返回false
|
||||
*/
|
||||
public boolean doesObjectExist(String objectKey) {
|
||||
try {
|
||||
return obsClient.doesObjectExist(obsConfig.getBucket(), objectKey);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
# Tomcat
|
||||
server:
|
||||
port: 9205
|
||||
|
||||
# Spring
|
||||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: bonus-obs
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: dev
|
||||
cloud:
|
||||
nacos:
|
||||
username: nacos
|
||||
password: nacos
|
||||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: 192.168.0.14:8848
|
||||
namespace: f1fcd3ea-9460-4597-8acd-0f334527017c
|
||||
config:
|
||||
# 配置中心地址
|
||||
server-addr: 192.168.0.14:8848
|
||||
namespace: f1fcd3ea-9460-4597-8acd-0f334527017c
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
shared-configs:
|
||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="logs/bonus-file" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统日志输出 -->
|
||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/info.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>INFO</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/error.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>ERROR</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 系统模块日志级别控制 -->
|
||||
<logger name="com.bonus" level="info" />
|
||||
<!-- Spring日志级别控制 -->
|
||||
<logger name="org.springframework" level="warn" />
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<appender-ref ref="file_info" />
|
||||
<appender-ref ref="file_error" />
|
||||
</root>
|
||||
</configuration>
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
<?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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-modules</artifactId>
|
||||
<version>24.6.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>bonus-oss</artifactId>
|
||||
<description>
|
||||
bonus-modules-oss存储服务
|
||||
</description>
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos Config -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Sentinel -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringBoot Actuator -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- FastDFS -->
|
||||
<dependency>
|
||||
<groupId>com.github.tobato</groupId>
|
||||
<artifactId>fastdfs-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- bonus Common Swagger -->
|
||||
<dependency>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-common-swagger</artifactId>
|
||||
</dependency>
|
||||
<!--阿里云oss 存储-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>3.10.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-common-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!--加密依赖包-->
|
||||
<dependency>
|
||||
<groupId>com.github.ulisesbocchio</groupId>
|
||||
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
package com.bonus.oss;
|
||||
|
||||
import com.bonus.common.swagger.annotation.EnableCustomSwagger2;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
|
||||
@EnableCustomSwagger2
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
|
||||
public class BonusOssApplication {
|
||||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(BonusOssApplication.class, args);
|
||||
System.err.println("(♥◠‿◠)ノ゙ oss存储服务模块启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||
" .-------. ____ __ \n" +
|
||||
" | _ _ \\ \\ \\ / / \n" +
|
||||
" | ( ' ) | \\ _. / ' \n" +
|
||||
" |(_ o _) / _( )_ .' \n" +
|
||||
" | (_,_).' __ ___(_ o _)' \n" +
|
||||
" | |\\ \\ | || |(_,_)' \n" +
|
||||
" | | \\ `' /| `-' / \n" +
|
||||
" | | \\ / \\ / \n" +
|
||||
" ''-' `'-' `-..-' ");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
package com.bonus.oss.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 配置OSS(对象存储服务)的属性类。
|
||||
* 使用@ConfigurationProperties注解将类绑定到配置文件中以oss为前缀的属性上。
|
||||
* 使用@Configuration注解将此类标记为一个配置类,它会被Spring Boot自动检测并用于配置上下文。
|
||||
* 使用@Data注解来自动生成getter和setter方法,简化了属性访问。
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "oss")
|
||||
@Data
|
||||
public class OSSConfig {
|
||||
/**
|
||||
* OSS的访问密钥ID。
|
||||
* 用于身份验证的重要凭证之一。
|
||||
*/
|
||||
private String accessKeyId;
|
||||
|
||||
/**
|
||||
* OSS的访问密钥秘钥。
|
||||
* 用于身份验证的重要凭证之一,应保密。
|
||||
*/
|
||||
private String accessKeySecret;
|
||||
|
||||
/**
|
||||
* OSS的存储桶名称。
|
||||
* 存储桶是OSS中用于存储对象的容器。
|
||||
*/
|
||||
private String bucket;
|
||||
|
||||
/**
|
||||
* OSS的Endpoint。
|
||||
* Endpoint指定了与OSS交互时使用的域名或区域。
|
||||
*/
|
||||
private String endpoint;
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
package com.bonus.oss.controller;
|
||||
|
||||
import com.aliyun.oss.model.OSSObject;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.common.core.utils.StringUtils;
|
||||
import com.bonus.common.core.utils.file.FileUtils;
|
||||
import com.bonus.oss.domain.OssInfo;
|
||||
import com.bonus.oss.service.OssService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/oss")
|
||||
public class OssController {
|
||||
@Resource
|
||||
private OssService ossService;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param file 文件流
|
||||
* @return 文件信息
|
||||
*/
|
||||
@PostMapping("/uploadFile")
|
||||
public R<OssInfo> uploadFile(MultipartFile file) {
|
||||
return ossService.uploadFile(file);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param files 文件流
|
||||
* @return 文件信息
|
||||
*/
|
||||
@PostMapping("/uploadFiles")
|
||||
public R<List<OssInfo>> uploadFiles(MultipartFile[] files) {
|
||||
return ossService.uploadFiles(files);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param objectKey oss文件存储地址
|
||||
*/
|
||||
@GetMapping("/downloadFile")
|
||||
public void downloadFile(HttpServletResponse response, @RequestParam String objectKey) throws UnsupportedEncodingException {
|
||||
R<OSSObject> ossObjectR = ossService.downloadFile(objectKey);
|
||||
if (ossObjectR.getData() == null) {
|
||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
||||
return;
|
||||
}
|
||||
|
||||
OSSObject ossObject = ossObjectR.getData();
|
||||
String safeFileName = FileUtils.getName(objectKey); // 假设这个方法进行了恰当的文件名清理和验证
|
||||
if (!StringUtils.hasText(safeFileName)) {
|
||||
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
||||
return;
|
||||
}
|
||||
|
||||
String encodedFileName = URLEncoder.encode(safeFileName, StandardCharsets.UTF_8.toString());
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedFileName + "\"");
|
||||
|
||||
try (InputStream inputStream = ossObject.getObjectContent();
|
||||
OutputStream outputStream = response.getOutputStream()) {
|
||||
|
||||
byte[] buffer = new byte[8192];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
outputStream.flush();
|
||||
} catch (IOException e) {
|
||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
} catch (IllegalArgumentException e) {
|
||||
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
||||
} catch (Exception e) {
|
||||
// 记录异常信息到日志
|
||||
log.error("文件下载过程中出现未知异常,原因是:", e);
|
||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 文件删除
|
||||
*
|
||||
* @param objectKey 文件路径
|
||||
* @return 删除结果
|
||||
*/
|
||||
@PostMapping("/deleteFile")
|
||||
public R<T> deleteFile(@RequestParam String objectKey) {
|
||||
return ossService.deleteFile(objectKey);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
package com.bonus.oss.domain;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* OssInfo类用于封装OSS(Object Storage Service)对象的相关信息。
|
||||
* 通过此类,可以方便地管理和访问OSS对象的元数据,如名称、路径、大小等。
|
||||
*/
|
||||
@Builder
|
||||
@Data
|
||||
public class OssInfo {
|
||||
/**
|
||||
* 文件或对象的名称。
|
||||
* 用于唯一标识OSS中的一个对象。
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 文件在OSS中的存储路径。
|
||||
* 该路径不包含Bucket名称,仅指对象在Bucket内的相对路径。
|
||||
*/
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 文件或对象的大小。
|
||||
* 以字符串形式表示,单位可能为字节、KB、MB等。
|
||||
*/
|
||||
private String length;
|
||||
|
||||
/**
|
||||
* 文件的类型。
|
||||
* 可以是文件的MIME类型,或者根据文件扩展名推测的类型。
|
||||
*/
|
||||
private String fileType;
|
||||
|
||||
/**
|
||||
* 存储文件的Bucket名称。
|
||||
* Bucket是OSS中用于存储对象的容器,每个对象必须属于某个Bucket。
|
||||
*/
|
||||
private String bucketName;
|
||||
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
package com.bonus.oss.service;
|
||||
|
||||
import com.aliyun.oss.model.OSSObject;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.oss.domain.OssInfo;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface OssService {
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param param 文件流
|
||||
* @return 文件信息
|
||||
*/
|
||||
R<OssInfo> uploadFile(MultipartFile param);
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param objectKey oss文件存储地址
|
||||
* @return OSSObject对象
|
||||
*/
|
||||
R<OSSObject> downloadFile(String objectKey);
|
||||
|
||||
/**
|
||||
* 文件删除
|
||||
*
|
||||
* @param objectKey oss文件存储地址
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<T> deleteFile(String objectKey);
|
||||
/**
|
||||
* 多文件上传
|
||||
*
|
||||
* @param files 文件流
|
||||
* @return 文件信息
|
||||
*/
|
||||
R<List<OssInfo>> uploadFiles(MultipartFile[] files);
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
package com.bonus.oss.service.impl;
|
||||
|
||||
import com.alibaba.nacos.common.utils.UuidUtils;
|
||||
import com.aliyun.oss.model.OSSObject;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.common.core.utils.StringUtils;
|
||||
import com.bonus.common.core.utils.file.FileUtils;
|
||||
import com.bonus.oss.domain.OssInfo;
|
||||
import com.bonus.oss.service.OssService;
|
||||
import com.bonus.oss.utils.OssUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@Service
|
||||
public class OssServiceImpl implements OssService {
|
||||
|
||||
@Resource
|
||||
private OssUtils ossUtils;
|
||||
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param file 文件流
|
||||
* @return 文件信息
|
||||
*/
|
||||
@Override
|
||||
public R<OssInfo> uploadFile(MultipartFile file) {
|
||||
if (ObjectUtils.isEmpty(file)) {
|
||||
return R.fail("File is null.");
|
||||
}
|
||||
try {
|
||||
String originalFilename = Objects.requireNonNull(file.getOriginalFilename(), "文件名不能为空");
|
||||
String extension = originalFilename.substring(originalFilename.lastIndexOf('.'));
|
||||
String objectKey = UuidUtils.generateUuid() + extension;
|
||||
objectKey = FileUtils.generateObjectName(objectKey);
|
||||
return ossUtils.upload(objectKey, FileUtils.multipartFileToFile(file));
|
||||
} catch (Exception e) {
|
||||
return R.fail("File upload failed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param objectKey oss文件存储地址
|
||||
*/
|
||||
@Override
|
||||
public R<OSSObject> downloadFile(String objectKey) {
|
||||
if (ObjectUtils.isEmpty(objectKey)) {
|
||||
return R.fail("objectKey is null.");
|
||||
}
|
||||
return ossUtils.download(objectKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件删除
|
||||
*
|
||||
* @param objectKey oss文件存储地址
|
||||
*/
|
||||
@Override
|
||||
public R<T> deleteFile(String objectKey) {
|
||||
try {
|
||||
if (ObjectUtils.isNotEmpty(objectKey)) {
|
||||
return ossUtils.delete(objectKey);
|
||||
} else {
|
||||
return R.fail("objectKey is null.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return R.fail("File delete failed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 多文件上传
|
||||
*
|
||||
* @param files 文件流
|
||||
* @return 文件信息
|
||||
*/
|
||||
@Override
|
||||
public R<List<OssInfo>> uploadFiles(MultipartFile[] files) {
|
||||
try {
|
||||
List<OssInfo> ossInfos = new ArrayList<>();
|
||||
for (MultipartFile multipartFile : files) {
|
||||
String originalFilename = Objects.requireNonNull(multipartFile.getOriginalFilename(), "文件名不能为空");
|
||||
String extension = originalFilename.substring(originalFilename.lastIndexOf('.'));
|
||||
String objectKey = UuidUtils.generateUuid() + extension;
|
||||
File file = FileUtils.multipartFileToFile(multipartFile);
|
||||
objectKey = FileUtils.generateObjectName(objectKey);
|
||||
ossInfos.add(ossUtils.upload(objectKey, file).getData());
|
||||
}
|
||||
return R.ok(ossInfos, "文件上传成功");
|
||||
} catch (Exception e) {
|
||||
return R.fail("File upload failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
package com.bonus.oss.utils;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.model.OSSObject;
|
||||
import com.aliyun.oss.model.ObjectMetadata;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.common.core.text.Convert;
|
||||
import com.bonus.common.core.utils.file.FileUtils;
|
||||
import com.bonus.oss.config.OSSConfig;
|
||||
import com.bonus.oss.domain.OssInfo;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* OSS存储服务类
|
||||
*/
|
||||
@Service
|
||||
public class OssUtils {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(OssUtils.class);
|
||||
|
||||
@Resource
|
||||
private OSSConfig ossConfig;
|
||||
|
||||
/**
|
||||
* OSS客户端
|
||||
*/
|
||||
private OSS ossClient;
|
||||
|
||||
/**
|
||||
* 初始化OSS客户端
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件到OSS
|
||||
*
|
||||
* @param objectKey 文件在OSS中的键
|
||||
* @param file 要上传的文件
|
||||
* @return 包含上传文件信息的结果对象
|
||||
*/
|
||||
public R<OssInfo> upload(String objectKey, File file) {
|
||||
try {
|
||||
ossClient.putObject(ossConfig.getBucket(), objectKey, file);
|
||||
return R.ok(getInfo(objectKey), "文件上传成功");
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("文件上传失败", e);
|
||||
return R.fail("文件上传失败");
|
||||
} finally {
|
||||
if (!file.delete()) {
|
||||
LOGGER.warn("临时文件删除失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件在OSS中的信息
|
||||
*
|
||||
* @param objectKey 文件路径
|
||||
* @return 文件信息对象
|
||||
*/
|
||||
public OssInfo getInfo(String objectKey) {
|
||||
try {
|
||||
ObjectMetadata objectMetadata = ossClient.getObjectMetadata(ossConfig.getBucket(), objectKey);
|
||||
return OssInfo.builder()
|
||||
.name(FileUtils.getName(objectKey))
|
||||
.bucketName(ossConfig.getBucket())
|
||||
.fileType(objectMetadata.getContentType())
|
||||
.length(Convert.toStr(objectMetadata.getContentLength()))
|
||||
.path(objectKey).build();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("获取文件信息失败", e);
|
||||
return OssInfo.builder().build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从OSS下载文件
|
||||
*
|
||||
* @param objectKey 文件路径
|
||||
* @return OSSObject对象,包含下载的文件
|
||||
*/
|
||||
public R<OSSObject> download(String objectKey) {
|
||||
if (doesObjectExist(ossConfig.getBucket(), objectKey)) {
|
||||
return R.fail("文件不存在");
|
||||
}
|
||||
try {
|
||||
return R.ok(ossClient.getObject(ossConfig.getBucket(), objectKey));
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("文件下载失败", e);
|
||||
return R.fail("文件下载失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除OSS中的文件
|
||||
*
|
||||
* @param objectKey 文件路径
|
||||
* @return 删除操作的结果
|
||||
*/
|
||||
public R<T> delete(String objectKey) {
|
||||
try {
|
||||
if (doesObjectExist(ossConfig.getBucket(), objectKey)) {
|
||||
return R.fail("文件不存在");
|
||||
}
|
||||
ossClient.deleteObject(ossConfig.getBucket(), objectKey);
|
||||
return R.ok(null,"文件删除成功");
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("文件删除失败", e);
|
||||
return R.fail("文件删除失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查OSS中是否存在指定的文件
|
||||
*
|
||||
* @param bucketName Bucket名称
|
||||
* @param objectKey 文件路径
|
||||
* @return 如果文件存在返回true,否则返回false
|
||||
*/
|
||||
private boolean doesObjectExist(String bucketName, String objectKey) {
|
||||
try {
|
||||
return !ossClient.doesObjectExist(bucketName, objectKey);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("判断文件是否存在失败", e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="logs/bonus-file" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统日志输出 -->
|
||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/info.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>INFO</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/error.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>ERROR</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 系统模块日志级别控制 -->
|
||||
<logger name="com.bonus" level="info" />
|
||||
<!-- Spring日志级别控制 -->
|
||||
<logger name="org.springframework" level="warn" />
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<appender-ref ref="file_info" />
|
||||
<appender-ref ref="file_error" />
|
||||
</root>
|
||||
</configuration>
|
||||
|
|
@ -1,21 +1,19 @@
|
|||
<?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"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-modules</artifactId>
|
||||
<version>24.6.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>bonus-mongodb</artifactId>
|
||||
<artifactId>bonus-tcp</artifactId>
|
||||
<description>
|
||||
bonus-tcp 协议模块
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos -->
|
||||
|
|
@ -42,23 +40,35 @@
|
|||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- FastDFS -->
|
||||
<!-- Swagger UI -->
|
||||
<dependency>
|
||||
<groupId>com.github.tobato</groupId>
|
||||
<artifactId>fastdfs-client</artifactId>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>${swagger.fox.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Minio -->
|
||||
<!-- Mysql Connector -->
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<version>${minio.version}</version>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- bonus Api System -->
|
||||
<!-- bonus Common DataSource -->
|
||||
<dependency>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-api-system</artifactId>
|
||||
<artifactId>bonus-common-datasource</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- bonus Common DataScope -->
|
||||
<dependency>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-common-datascope</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- bonus Common Log -->
|
||||
<dependency>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-common-log</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- bonus Common Swagger -->
|
||||
|
|
@ -66,27 +76,33 @@
|
|||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-common-swagger</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.12</version> <!-- 版本号可以根据需要调整 -->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!--加密依赖包-->
|
||||
<dependency>
|
||||
<groupId>com.github.ulisesbocchio</groupId>
|
||||
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-common-entity</artifactId>
|
||||
<version>24.6.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-common-entity</artifactId>
|
||||
<version>24.6.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-common-security</artifactId>
|
||||
<version>24.6.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
@ -105,4 +121,6 @@
|
|||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.bonus.tcp;
|
||||
|
||||
import com.bonus.common.security.annotation.EnableCustomConfig;
|
||||
import com.bonus.common.security.annotation.EnableRyFeignClients;
|
||||
import com.bonus.common.swagger.annotation.EnableCustomSwagger2;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
|
||||
@EnableCustomConfig
|
||||
@EnableCustomSwagger2
|
||||
@EnableRyFeignClients
|
||||
@SpringBootApplication(exclude = MongoAutoConfiguration.class)
|
||||
public class BonusTcpApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(BonusTcpApplication.class, args);
|
||||
System.err.println("(♥◠‿◠)ノ゙ TCP模块启动成功 ლ(´ڡ`ლ)゙");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
Spring Boot Version: ${spring-boot.version}
|
||||
Spring Application Name: ${spring.application.name}
|
||||
_ _
|
||||
(_) | |
|
||||
_ __ _ _ ___ _ _ _ ______ ___ _ _ ___ | |_ ___ _ __ ___
|
||||
| '__|| | | | / _ \ | | | || ||______|/ __|| | | |/ __|| __| / _ \| '_ ` _ \
|
||||
| | | |_| || (_) || |_| || | \__ \| |_| |\__ \| |_ | __/| | | | | |
|
||||
|_| \__,_| \___/ \__, ||_| |___/ \__, ||___/ \__| \___||_| |_| |_|
|
||||
__/ | __/ |
|
||||
|___/ |___/
|
||||
|
|
@ -1,27 +1,27 @@
|
|||
# Tomcat
|
||||
server:
|
||||
port: 9204
|
||||
port: 21997
|
||||
|
||||
# Spring
|
||||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: bonus-oss
|
||||
name: bonus-tcp
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: dev
|
||||
cloud:
|
||||
nacos:
|
||||
username: nacos
|
||||
password: nacos
|
||||
password: Jjsp@nacos2023
|
||||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: 192.168.0.14:8848
|
||||
namespace: f1fcd3ea-9460-4597-8acd-0f334527017c
|
||||
server-addr: 127.0.0.1:8848
|
||||
namespace: ljzhgd
|
||||
config:
|
||||
# 配置中心地址
|
||||
server-addr: 192.168.0.14:8848
|
||||
namespace: f1fcd3ea-9460-4597-8acd-0f334527017c
|
||||
server-addr: 127.0.0.1:8848
|
||||
namespace: ljzhgd
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="logs/bonus-file" />
|
||||
<property name="log.path" value="logs/bonus-system" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
|
|
@ -13,9 +13,9 @@
|
|||
<module>bonus-gen</module>
|
||||
<module>bonus-job</module>
|
||||
<module>bonus-file</module>
|
||||
<module>bonus-oss</module>
|
||||
<module>bonus-app</module>
|
||||
<module>bonus-bracelet</module>
|
||||
<module>bonus-tcp</module>
|
||||
</modules>
|
||||
|
||||
<artifactId>bonus-modules</artifactId>
|
||||
|
|
|
|||
Loading…
Reference in New Issue