新增凭证管理

This commit is contained in:
2026-08-12 12:42:07 +08:00
parent 7f31952bff
commit 4ad3108c4d
28 changed files with 732 additions and 2 deletions
@@ -13,11 +13,14 @@ import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.mp.support.Query;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.file.pojo.dto.FileTaskCreateDTO;
import org.springblade.file.pojo.dto.FileTaskUpdateDTO;
import org.springblade.file.pojo.dto.IdsDTO;
import org.springblade.file.pojo.vo.FileTaskUpdateVO;
import org.springblade.file.service.IFileTaskService;
import org.springblade.file.service.IFileService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -35,6 +38,7 @@ import org.springframework.web.bind.annotation.*;
public class FileTaskController extends BladeController {
private final IFileTaskService fileTaskService;
private final IFileService fileService;
@GetMapping("/queryFileTask")
@Operation(summary = "根据文件的MD5值查询文件任务", description = "文件的MD5值检查分段,参数名:md5")
@@ -43,6 +47,24 @@ public class FileTaskController extends BladeController {
return R.data(fileTask);
}
@GetMapping("/file-url")
@Operation(summary = "获取已完成上传任务文件地址")
public R<String> fileUrl(@RequestParam Long id) {
org.springblade.file.pojo.entity.FileTask task = fileTaskService.getById(id);
if (task == null || !org.springblade.file.pojo.enums.FileTaskStatus.COMPLETED.getCode().equals(task.getStatus())) {
return R.fail("文件尚未上传完成");
}
return R.data(fileService.getFileUrl(task.getObjectKey(), null));
}
@GetMapping("/list")
@Operation(summary = "上传任务分页")
public R<IPage<FileTaskUpdateVO>> list(Query query, @RequestParam(required = false) String businessType,
@RequestParam(required = false) String businessId, @RequestParam(required = false) String attachmentName,
@RequestParam(required = false) String status) {
return R.data(fileTaskService.selectPage(query, businessType, businessId, attachmentName, status));
}
@ApiLog("上传任务-创建文件任务")
@PostMapping("/createFileTask")
@Operation(summary = "创建文件任务", description = "创建文件任务")
@@ -26,6 +26,8 @@
package org.springblade.file.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.support.Query;
import org.springblade.file.pojo.dto.FileTaskCreateDTO;
import org.springblade.file.pojo.dto.FileTaskUpdateDTO;
import org.springblade.file.pojo.entity.FileTask;
@@ -91,4 +93,6 @@ public interface IFileTaskService extends IService<FileTask> {
* @return
*/
boolean updatePaused(List<Long> param);
IPage<FileTaskUpdateVO> selectPage(Query query, String businessType, String businessId, String attachmentName, String status);
}
@@ -28,12 +28,15 @@ package org.springblade.file.service.impl;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.file.config.ObsProperties;
import org.springblade.file.convert.FileTaskConvert;
import org.springblade.file.listener.FileUploadedEvent;
@@ -125,6 +128,8 @@ public class FileTaskServiceImpl extends ServiceImpl<FileTaskMapper, FileTask> i
addParam.setUploadId(uploadId);
// 正在上传
addParam.setStatus(FileTaskStatus.UPLOADING.getCode());
// 兼容历史表未配置 is_deleted 默认值的场景。
addParam.setIsDeleted(0);
this.save(addParam);
return addParam.getId();
@@ -317,6 +322,17 @@ public class FileTaskServiceImpl extends ServiceImpl<FileTaskMapper, FileTask> i
);
}
@Override
public IPage<FileTaskUpdateVO> selectPage(org.springblade.core.mp.support.Query query, String businessType, String businessId, String attachmentName, String status) {
IPage<FileTask> page = page(Condition.getPage(query), Wrappers.<FileTask>lambdaQuery()
.eq(StringUtil.isNotBlank(businessType), FileTask::getBusinessType, businessType)
.eq(StringUtil.isNotBlank(businessId), FileTask::getBusinessId, businessId)
.like(StringUtil.isNotBlank(attachmentName), FileTask::getAttachmentName, attachmentName)
.eq(StringUtil.isNotBlank(status), FileTask::getStatus, status)
.eq(FileTask::getCreateUser, AuthUtil.getUserId()).orderByDesc(FileTask::getCreateTime));
return page.convert(this::getFileTaskUpdateVO);
}
/**
* 查询文件任务
* @param id
@@ -28,7 +28,10 @@ package org.springblade.file.service.impl;
import io.minio.GetObjectArgs;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.ComposeObjectArgs;
import io.minio.ComposeSource;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.UploadObjectArgs;
import io.minio.http.Method;
import lombok.RequiredArgsConstructor;
@@ -43,7 +46,10 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* MinIO文件存储
@@ -59,6 +65,44 @@ public class MinioFileServiceImpl extends AbstractFileService {
private final FileStorageProperties.StoreProperties properties;
private final MinioClient minioClient;
@Override
public String initiateMultipartUpload(String objectKey) {
return UUID.randomUUID().toString();
}
@Override
public String getUploadPartUrl(String objectKey, String uploadId, Integer partNumber, Long expires) {
try {
return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.PUT).bucket(properties.getBucketName()).object(partObjectKey(objectKey, uploadId, partNumber))
.expiry(Math.toIntExact(resolveExpires(expires))).build());
} catch (Exception exception) {
log.error("MinIO获取分片上传链接异常 objectKey:{}", objectKey, exception);
throw new ServiceException("获取分片上传链接异常");
}
}
@Override
public void completeMultipartUpload(String objectKey, String uploadId, List<org.springblade.file.pojo.vo.PartEtagVO> partEtags) {
try {
List<ComposeSource> sources = new ArrayList<>();
for (org.springblade.file.pojo.vo.PartEtagVO part : partEtags) {
sources.add(ComposeSource.builder().bucket(properties.getBucketName()).object(partObjectKey(objectKey, uploadId, part.getPartNumber())).build());
}
minioClient.composeObject(ComposeObjectArgs.builder().bucket(properties.getBucketName()).object(resolveObjectKey(objectKey)).sources(sources).build());
for (org.springblade.file.pojo.vo.PartEtagVO part : partEtags) {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(properties.getBucketName()).object(partObjectKey(objectKey, uploadId, part.getPartNumber())).build());
}
} catch (Exception exception) {
log.error("MinIO合并分片异常 objectKey{}", objectKey, exception);
throw new ServiceException("MinIO合并分片异常");
}
}
private String partObjectKey(String objectKey, String uploadId, Integer partNumber) {
return resolveObjectKey(".multipart/" + uploadId + "/" + objectKey + ".part-" + partNumber);
}
@Override
public void uploadFile(String objectKey, InputStream inputStream) {
try {