feat(files): complete v2 upload sessions

This commit is contained in:
yoyuzh
2026-04-08 15:18:09 +08:00
parent 7ddef9bddb
commit 35b0691188
7 changed files with 129 additions and 1 deletions

View File

@@ -53,6 +53,13 @@ public class UploadSessionV2Controller {
return ApiV2Response.success(toResponse(uploadSessionService.cancelOwnedSession(user, sessionId)));
}
@PostMapping("/{sessionId}/complete")
public ApiV2Response<UploadSessionV2Response> completeSession(@AuthenticationPrincipal UserDetails userDetails,
@PathVariable String sessionId) {
User user = userDetailsService.loadDomainUser(userDetails.getUsername());
return ApiV2Response.success(toResponse(uploadSessionService.completeOwnedSession(user, sessionId)));
}
private UploadSessionV2Response toResponse(UploadSession session) {
return new UploadSessionV2Response(
session.getSessionId(),

View File

@@ -21,22 +21,26 @@ public class UploadSessionService {
private final UploadSessionRepository uploadSessionRepository;
private final StoredFileRepository storedFileRepository;
private final FileService fileService;
private final long maxFileSize;
private final Clock clock;
@Autowired
public UploadSessionService(UploadSessionRepository uploadSessionRepository,
StoredFileRepository storedFileRepository,
FileService fileService,
FileStorageProperties properties) {
this(uploadSessionRepository, storedFileRepository, properties, Clock.systemUTC());
this(uploadSessionRepository, storedFileRepository, fileService, properties, Clock.systemUTC());
}
UploadSessionService(UploadSessionRepository uploadSessionRepository,
StoredFileRepository storedFileRepository,
FileService fileService,
FileStorageProperties properties,
Clock clock) {
this.uploadSessionRepository = uploadSessionRepository;
this.storedFileRepository = storedFileRepository;
this.fileService = fileService;
this.maxFileSize = properties.getMaxFileSize();
this.clock = clock;
}
@@ -83,6 +87,46 @@ public class UploadSessionService {
return uploadSessionRepository.save(session);
}
@Transactional
public UploadSession completeOwnedSession(User user, String sessionId) {
UploadSession session = getOwnedSession(user, sessionId);
if (session.getStatus() == UploadSessionStatus.COMPLETED) {
return session;
}
if (session.getStatus() == UploadSessionStatus.CANCELLED || session.getStatus() == UploadSessionStatus.FAILED) {
throw new BusinessException(ErrorCode.UNKNOWN, "上传会话不能完成");
}
LocalDateTime now = LocalDateTime.ofInstant(clock.instant(), clock.getZone());
if (session.getExpiresAt().isBefore(now)) {
session.setStatus(UploadSessionStatus.EXPIRED);
session.setUpdatedAt(now);
uploadSessionRepository.save(session);
throw new BusinessException(ErrorCode.UNKNOWN, "上传会话已过期");
}
session.setStatus(UploadSessionStatus.COMPLETING);
session.setUpdatedAt(now);
uploadSessionRepository.save(session);
try {
fileService.completeUpload(user, new CompleteUploadRequest(
session.getTargetPath(),
session.getFilename(),
session.getObjectKey(),
session.getContentType(),
session.getSize()
));
session.setStatus(UploadSessionStatus.COMPLETED);
session.setUpdatedAt(now);
return uploadSessionRepository.save(session);
} catch (RuntimeException ex) {
session.setStatus(UploadSessionStatus.FAILED);
session.setUpdatedAt(now);
uploadSessionRepository.save(session);
throw ex;
}
}
private void validateTarget(User user, String normalizedPath, String filename, long size) {
long effectiveMaxUploadSize = Math.min(maxFileSize, user.getMaxUploadSizeBytes());
if (size > effectiveMaxUploadSize) {