[api] tus 수정
This commit is contained in:
@@ -6,6 +6,7 @@ import com.alist.api.common.utils.SecurityUtil;
|
||||
import com.alist.api.modules.tusFile.dto.*;
|
||||
import com.alist.api.modules.tusFile.form.*;
|
||||
import com.alist.api.modules.tusFile.service.TusFileService;
|
||||
import com.alist.api.modules.tusFile.vo.*;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -43,29 +44,29 @@ public class TusFileController {
|
||||
, description = "업로드 대상 파일 정보를 DB에 등록하고 fileUuid/uploadToken을 발급합니다."
|
||||
)
|
||||
@PostMapping("/upload/init")
|
||||
public ResponseEntity<ApiResponse<FileUploadDto>> tusFileUploadInit(
|
||||
@Valid @RequestBody FileUploadForm fileUploadForm
|
||||
public ResponseEntity<ApiResponse<TusFileUploadInitVo>> tusFileUploadInit(
|
||||
@Valid @RequestBody TusFileUploadInitForm tusFileUploadInitForm
|
||||
) {
|
||||
FileUploadDto fileUploadDto = fileUploadForm.toFileUploadDto();
|
||||
TusFileUploadInitDto tusFileUploadInitDto = tusFileUploadInitForm.toDto();
|
||||
|
||||
Integer userTokenIdx = SecurityUtil.getLoginUserTokenIdx();
|
||||
|
||||
if (userTokenIdx == null) {
|
||||
return ApiResponse.entity(new FileUploadDto(), ApiResponseCode.CODE_401);
|
||||
return ApiResponse.entity(new TusFileUploadInitVo(), ApiResponseCode.CODE_401);
|
||||
}
|
||||
|
||||
Integer userIdx = tusFileService.selectUserIdxByUserTokenIdx(userTokenIdx);
|
||||
|
||||
if (userIdx == null) {
|
||||
return ApiResponse.entity(new FileUploadDto(), ApiResponseCode.CODE_401);
|
||||
return ApiResponse.entity(new TusFileUploadInitVo(), ApiResponseCode.CODE_401);
|
||||
}
|
||||
|
||||
fileUploadDto.setUserIdx(userIdx);
|
||||
fileUploadDto.setUserTokenIdx(userTokenIdx);
|
||||
tusFileUploadInitDto.setUserIdx(userIdx);
|
||||
tusFileUploadInitDto.setUserTokenIdx(userTokenIdx);
|
||||
|
||||
FileUploadDto fileUploadResult = tusFileService.insertFileInit(fileUploadDto);
|
||||
TusFileUploadInitVo tusFileUploadInitVo = tusFileService.insertTusFileUploadInit(tusFileUploadInitDto);
|
||||
|
||||
return ApiResponse.entity(fileUploadResult, ApiResponseCode.CODE_200);
|
||||
return ApiResponse.entity(tusFileUploadInitVo, ApiResponseCode.CODE_200);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
@@ -86,17 +87,17 @@ public class TusFileController {
|
||||
return ApiResponse.entity("", ApiResponseCode.CODE_403);
|
||||
}
|
||||
|
||||
UploadTokenDto uploadTokenDto = new UploadTokenDto();
|
||||
uploadTokenDto.setUploadToken(uploadToken.substring(7).trim());
|
||||
uploadTokenDto.setFileUuid(fileUuid.trim());
|
||||
uploadTokenDto.setUploadMetadataRaw(uploadMetadata);
|
||||
uploadTokenDto.setUploadLengthRaw(uploadLength);
|
||||
TusFileUploadAuthDto tusFileUploadAuthDto = new TusFileUploadAuthDto();
|
||||
tusFileUploadAuthDto.setUploadToken(uploadToken.substring(7).trim());
|
||||
tusFileUploadAuthDto.setFileUuid(fileUuid.trim());
|
||||
tusFileUploadAuthDto.setUploadMetadataRaw(uploadMetadata);
|
||||
tusFileUploadAuthDto.setUploadLengthRaw(uploadLength);
|
||||
|
||||
UploadTokenDto uploadTokenCheck = tusFileService.isUploadTokenCheck(uploadTokenDto);
|
||||
TusFileUploadAuthVo tusFileUploadAuthVo = tusFileService.selectTusFileUploadAuth(tusFileUploadAuthDto);
|
||||
|
||||
if (uploadTokenCheck.getResultCode() == 401) {
|
||||
if (tusFileUploadAuthVo.getResultCode() == 401) {
|
||||
return ApiResponse.entity("", ApiResponseCode.CODE_401);
|
||||
} else if (uploadTokenCheck.getResultCode() == 403) {
|
||||
} else if (tusFileUploadAuthVo.getResultCode() == 403) {
|
||||
return ApiResponse.entity("", ApiResponseCode.CODE_403);
|
||||
}
|
||||
|
||||
@@ -108,14 +109,16 @@ public class TusFileController {
|
||||
, description = "fileUuid 기준으로 Redis/DB 업로드 상태(진행률, 상태값)를 조회합니다."
|
||||
)
|
||||
@PostMapping("/upload/status")
|
||||
public ResponseEntity<ApiResponse<UploadStatusDto>> tusFileUploadStatus(
|
||||
@Valid @RequestBody UploadStatusForm uploadStatusForm
|
||||
public ResponseEntity<ApiResponse<TusFileUploadStatusVo>> tusFileUploadStatus(
|
||||
@Valid @RequestBody TusFileUploadStatusForm tusFileUploadStatusForm
|
||||
) {
|
||||
UploadStatusDto status = tusFileService.getUploadStatus(uploadStatusForm.toUploadStatusDto());
|
||||
if (status == null) {
|
||||
return ApiResponse.entity(new UploadStatusDto(), ApiResponseCode.CODE_2003);
|
||||
TusFileUploadStatusVo tusFileUploadStatusVo = tusFileService.loadTusFileUploadStatus(tusFileUploadStatusForm.toDto());
|
||||
|
||||
if (tusFileUploadStatusVo == null) {
|
||||
return ApiResponse.entity(new TusFileUploadStatusVo(), ApiResponseCode.CODE_2003);
|
||||
}
|
||||
return ApiResponse.entity(status, ApiResponseCode.CODE_200);
|
||||
|
||||
return ApiResponse.entity(tusFileUploadStatusVo, ApiResponseCode.CODE_200);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
@@ -123,11 +126,13 @@ public class TusFileController {
|
||||
, description = "tusd에서 전달되는 pre-create/post-receive/post-finish/post-terminate 이벤트를 반영합니다."
|
||||
)
|
||||
@PostMapping("/hook")
|
||||
public ResponseEntity<ApiResponse<String>> tusFileHook(@RequestBody TusHookForm tusHookForm) {
|
||||
boolean accepted = tusFileService.updateFileUploadStatus(tusHookForm.toTusHookDto());
|
||||
public ResponseEntity<ApiResponse<String>> tusFileHook(@RequestBody TusFileHookForm tusFileHookForm) {
|
||||
TusFileHookDto tusFileHookDto = tusFileHookForm.toDto();
|
||||
|
||||
boolean accepted = tusFileService.updateTusFileHook(tusFileHookDto);
|
||||
|
||||
if (accepted) {
|
||||
tusFileService.saveUploadStatusRedisTusHook(tusHookForm.toTusHookDto());
|
||||
tusFileService.saveTusFileHookStatusRedis(tusFileHookDto);
|
||||
}
|
||||
|
||||
return ApiResponse.entity("", ApiResponseCode.CODE_200);
|
||||
@@ -139,7 +144,7 @@ public class TusFileController {
|
||||
)
|
||||
@PostMapping("/upload/cancel")
|
||||
public ResponseEntity<ApiResponse<String>> tusFileUploadCancel(
|
||||
@Valid @RequestBody UploadCancelForm uploadCancelForm
|
||||
@Valid @RequestBody TusFileUploadCancelForm tusFileUploadCancelForm
|
||||
) {
|
||||
Integer userTokenIdx = SecurityUtil.getLoginUserTokenIdx();
|
||||
|
||||
@@ -147,14 +152,12 @@ public class TusFileController {
|
||||
return ApiResponse.entity("", ApiResponseCode.CODE_401);
|
||||
}
|
||||
|
||||
UploadCancelDto uploadCancelDto = new UploadCancelDto();
|
||||
TusFileUploadCancelDto tusFileUploadCancelDto = tusFileUploadCancelForm.toDto();
|
||||
tusFileUploadCancelDto.setUserTokenIdx(userTokenIdx);
|
||||
|
||||
uploadCancelDto.setFileUuid(uploadCancelForm.getFileUuid().trim());
|
||||
uploadCancelDto.setUserTokenIdx(userTokenIdx);
|
||||
TusFileUploadCancelVo tusFileUploadCancelVo = tusFileService.updateTusFileUploadCancel(tusFileUploadCancelDto);
|
||||
|
||||
boolean canceled = tusFileService.updateUploadCancel(uploadCancelDto);
|
||||
|
||||
if (!canceled) {
|
||||
if (!tusFileUploadCancelVo.isCanceled()) {
|
||||
return ApiResponse.entity("", ApiResponseCode.CODE_2005, "업로드 취소");
|
||||
}
|
||||
|
||||
@@ -163,62 +166,63 @@ public class TusFileController {
|
||||
|
||||
@Operation(
|
||||
summary = "파일 목록 조회"
|
||||
, description = "FILE_MASTER_IDX 기준으로 완료된 파일 목록을 조회합니다.")
|
||||
, description = "FILE_MASTER_IDX 기준으로 완료된 파일 목록을 조회합니다."
|
||||
)
|
||||
@GetMapping("/list/{fileMasterIdx}")
|
||||
public ResponseEntity<ApiResponse<FileDownloadListDto>> tusFileList(
|
||||
public ResponseEntity<ApiResponse<TusFileListVo>> tusFileList(
|
||||
@PathVariable Long fileMasterIdx
|
||||
) {
|
||||
TusFileListDto tusFileListDto = new TusFileListDto();
|
||||
tusFileListDto.setFileMasterIdx(fileMasterIdx);
|
||||
|
||||
FileDownloadDto fileDownloadDto = new FileDownloadDto();
|
||||
fileDownloadDto.setFileMasterIdx(fileMasterIdx);
|
||||
TusFileListVo tusFileListVo = tusFileService.selectTusFileList(tusFileListDto);
|
||||
|
||||
FileDownloadListDto fileDownloadList = tusFileService.selectFileDownloadListByFileMasterIdx(fileDownloadDto);
|
||||
|
||||
if (fileDownloadList.getResultCode() == 401) {
|
||||
return ApiResponse.entity(fileDownloadList, ApiResponseCode.CODE_401);
|
||||
if (tusFileListVo.getResultCode() == 401) {
|
||||
return ApiResponse.entity(tusFileListVo, ApiResponseCode.CODE_401);
|
||||
}
|
||||
|
||||
return ApiResponse.entity(fileDownloadList, ApiResponseCode.CODE_2001, "파일");
|
||||
return ApiResponse.entity(tusFileListVo, ApiResponseCode.CODE_2001, "파일");
|
||||
}
|
||||
|
||||
@Operation(
|
||||
summary = "파일 보기"
|
||||
, description = "권한 확인 후 Nginx X-Accel-Redirect로 파일을 inline 조회합니다.")
|
||||
, description = "권한 확인 후 Nginx X-Accel-Redirect로 파일을 inline 조회합니다."
|
||||
)
|
||||
@GetMapping("/view/{fileUuid}")
|
||||
public ResponseEntity<Resource> tusFileView(
|
||||
@PathVariable String fileUuid
|
||||
, HttpServletRequest request
|
||||
) throws IOException {
|
||||
FileDownloadDto fileDownloadDto = new FileDownloadDto();
|
||||
fileDownloadDto.setFileUuid(fileUuid);
|
||||
fileDownloadDto.setEventType("VIEW");
|
||||
fileDownloadDto.setClientIp(request.getRemoteAddr());
|
||||
fileDownloadDto.setUserAgent(request.getHeader("User-Agent"));
|
||||
fileDownloadDto.setReferer(request.getHeader("Referer"));
|
||||
TusFileViewOrDownloadDto tusFileViewOrDownloadDto = new TusFileViewOrDownloadDto();
|
||||
tusFileViewOrDownloadDto.setFileUuid(fileUuid);
|
||||
tusFileViewOrDownloadDto.setEventType("VIEW");
|
||||
tusFileViewOrDownloadDto.setClientIp(request.getRemoteAddr());
|
||||
tusFileViewOrDownloadDto.setUserAgent(request.getHeader("User-Agent"));
|
||||
tusFileViewOrDownloadDto.setReferer(request.getHeader("Referer"));
|
||||
|
||||
FileDownloadDto target = tusFileService.selectFileViewOrDownload(fileDownloadDto);
|
||||
TusFileViewOrDownloadVo tusFileViewOrDownloadVo = tusFileService.selectTusFileViewOrDownload(tusFileViewOrDownloadDto);
|
||||
|
||||
if (target == null) {
|
||||
if (tusFileViewOrDownloadVo == null) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
Path filePath = tusFileService.resolveStoredFilePath(target.getSavePath());
|
||||
Path filePath = tusFileService.resolveStoredFilePath(tusFileViewOrDownloadVo.getSavePath());
|
||||
|
||||
if (!Files.exists(filePath) || !Files.isRegularFile(filePath)) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
Resource resource = new InputStreamResource(Files.newInputStream(filePath));
|
||||
String contentType = target.getContentType() == null
|
||||
String contentType = tusFileViewOrDownloadVo.getContentType() == null
|
||||
? "application/octet-stream"
|
||||
: target.getContentType();
|
||||
: tusFileViewOrDownloadVo.getContentType();
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.parseMediaType(contentType))
|
||||
.contentLength(Files.size(filePath))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION,
|
||||
ContentDisposition.inline()
|
||||
.filename(target.getOriginName(), StandardCharsets.UTF_8)
|
||||
.filename(tusFileViewOrDownloadVo.getOriginName(), StandardCharsets.UTF_8)
|
||||
.build()
|
||||
.toString())
|
||||
.body(resource);
|
||||
@@ -226,58 +230,59 @@ public class TusFileController {
|
||||
|
||||
@Operation(
|
||||
summary = "파일 다운로드"
|
||||
, description = "권한 확인 후 파일 다운로드 로그를 남기고 redirect 또는 Nginx X-Accel-Redirect로 파일 다운로드 합니다.")
|
||||
, description = "권한 확인 후 파일 다운로드 로그를 남기고 redirect 또는 Nginx X-Accel-Redirect로 파일 다운로드 합니다."
|
||||
)
|
||||
@GetMapping("/download/{fileUuid}")
|
||||
public ResponseEntity<Resource> tusFileDownload(
|
||||
@PathVariable String fileUuid
|
||||
, HttpServletRequest request
|
||||
) throws IOException {
|
||||
FileDownloadDto fileDownloadDto = new FileDownloadDto();
|
||||
fileDownloadDto.setFileUuid(fileUuid);
|
||||
fileDownloadDto.setEventType("DOWNLOAD");
|
||||
fileDownloadDto.setClientIp(request.getRemoteAddr());
|
||||
fileDownloadDto.setUserAgent(request.getHeader("User-Agent"));
|
||||
fileDownloadDto.setReferer(request.getHeader("Referer"));
|
||||
TusFileViewOrDownloadDto tusFileViewOrDownloadDto = new TusFileViewOrDownloadDto();
|
||||
tusFileViewOrDownloadDto.setFileUuid(fileUuid);
|
||||
tusFileViewOrDownloadDto.setEventType("DOWNLOAD");
|
||||
tusFileViewOrDownloadDto.setClientIp(request.getRemoteAddr());
|
||||
tusFileViewOrDownloadDto.setUserAgent(request.getHeader("User-Agent"));
|
||||
tusFileViewOrDownloadDto.setReferer(request.getHeader("Referer"));
|
||||
|
||||
FileDownloadDto target = tusFileService.selectFileViewOrDownload(fileDownloadDto);
|
||||
TusFileViewOrDownloadVo tusFileViewOrDownloadVo = tusFileService.selectTusFileViewOrDownload(tusFileViewOrDownloadDto);
|
||||
|
||||
if (target == null) {
|
||||
if (tusFileViewOrDownloadVo == null) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
Path filePath = tusFileService.resolveStoredFilePath(target.getSavePath());
|
||||
Path filePath = tusFileService.resolveStoredFilePath(tusFileViewOrDownloadVo.getSavePath());
|
||||
|
||||
if (!Files.exists(filePath) || !Files.isRegularFile(filePath)) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
Resource resource = new InputStreamResource(Files.newInputStream(filePath));
|
||||
String contentType = target.getContentType() == null
|
||||
String contentType = tusFileViewOrDownloadVo.getContentType() == null
|
||||
? "application/octet-stream"
|
||||
: target.getContentType();
|
||||
: tusFileViewOrDownloadVo.getContentType();
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.parseMediaType(contentType))
|
||||
.contentLength(Files.size(filePath))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION,
|
||||
ContentDisposition.attachment()
|
||||
.filename(target.getOriginName(), StandardCharsets.UTF_8)
|
||||
.filename(tusFileViewOrDownloadVo.getOriginName(), StandardCharsets.UTF_8)
|
||||
.build()
|
||||
.toString())
|
||||
.body(resource);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
summary = "파일 삭제 처리",
|
||||
description = "fileUuid 기준으로 완료된 파일(STATUS = 3)을 논리 삭제 처리합니다. 실제 파일은 삭제하지 않고 DEL_YN = 'Y'만 반영합니다."
|
||||
summary = "파일 삭제 처리"
|
||||
, description = "fileUuid 기준으로 완료된 파일(STATUS = 3)을 논리 삭제 처리합니다. 실제 파일은 삭제하지 않고 DEL_YN = 'Y'만 반영합니다."
|
||||
)
|
||||
@PostMapping("/delete")
|
||||
public ResponseEntity<ApiResponse<String>> tusFileDelete(
|
||||
@Valid @RequestBody FileDeleteForm fileDeleteForm
|
||||
@Valid @RequestBody TusFileDeleteForm tusFileDeleteForm
|
||||
) {
|
||||
boolean deleted = tusFileService.updateFileDelete(fileDeleteForm.toFileDeleteDto());
|
||||
TusFileDeleteVo tusFileDeleteVo = tusFileService.updateTusFileDelete(tusFileDeleteForm.toDto());
|
||||
|
||||
if (!deleted) {
|
||||
if (!tusFileDeleteVo.isDeleted()) {
|
||||
return ApiResponse.entity("", ApiResponseCode.CODE_2005, "파일 삭제");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package com.alist.api.modules.tusFile.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "파일 다운로드 처리 DTO")
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileDownloadDto {
|
||||
@Schema(description = "파일 상세 PK", example = "1")
|
||||
private Long fileDetailIdx;
|
||||
|
||||
@Schema(description = "파일 마스터 PK", example = "1")
|
||||
private Long fileMasterIdx;
|
||||
|
||||
@Schema(description = "파일 UUID", example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10")
|
||||
private String fileUuid;
|
||||
|
||||
@Schema(description = "원본 파일명", example = "sample.png")
|
||||
private String originName;
|
||||
|
||||
@Schema(description = "Content-Type", example = "image/png")
|
||||
private String contentType;
|
||||
|
||||
@Schema(description = "파일 크기(byte)", example = "102400")
|
||||
private Long sizeBytes;
|
||||
|
||||
private String savePath;
|
||||
private Integer userIdx;
|
||||
private Integer userTokenIdx;
|
||||
private String eventType;
|
||||
private String clientIp;
|
||||
private String userAgent;
|
||||
private String referer;
|
||||
|
||||
@JsonIgnore
|
||||
@Schema(hidden = true)
|
||||
private Integer resultCode;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.alist.api.modules.tusFile.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "TUS 파일 삭제 DTO")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileDeleteDto {
|
||||
@Schema(description = "파일 UUID", example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10")
|
||||
private String fileUuid;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private Integer userTokenIdx;
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@ import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusHookDto {
|
||||
public class TusFileHookDto {
|
||||
private String type;
|
||||
private String uploadId;
|
||||
private Long size;
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.alist.api.modules.tusFile.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "TUS 파일 목록 조회 DTO")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileListDto {
|
||||
@Schema(description = "파일 마스터 PK", example = "1")
|
||||
private Long fileMasterIdx;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private Integer userTokenIdx;
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@ import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileMoveTaskDto {
|
||||
public class TusFileMoveTaskDto {
|
||||
private Long fileDetailIdx;
|
||||
private Long fileMasterIdx;
|
||||
private String fileUuid;
|
||||
+1
-6
@@ -1,6 +1,5 @@
|
||||
package com.alist.api.modules.tusFile.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -8,7 +7,7 @@ import lombok.Setter;
|
||||
@Schema(description = "업로드 인증 토큰 정보")
|
||||
@Getter
|
||||
@Setter
|
||||
public class UploadTokenDto {
|
||||
public class TusFileUploadAuthDto {
|
||||
private Integer userTokenIdx;
|
||||
|
||||
@Schema(description = "파일 UUID", example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10")
|
||||
@@ -28,8 +27,4 @@ public class UploadTokenDto {
|
||||
|
||||
@Schema(description = "Content-Type", example = "image/png")
|
||||
private String contentType;
|
||||
|
||||
@JsonIgnore
|
||||
@Schema(hidden = true)
|
||||
private Integer resultCode;
|
||||
}
|
||||
+4
-1
@@ -5,7 +5,10 @@ import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileDeleteDto {
|
||||
public class TusFileUploadCancelDto {
|
||||
private Integer userTokenIdx;
|
||||
private String fileUuid;
|
||||
|
||||
private Long uploadedBytes;
|
||||
private Long sizeBytes;
|
||||
}
|
||||
+2
-2
@@ -10,7 +10,7 @@ import java.util.List;
|
||||
@Schema(description = "TUS 파일 업로드 초기화 응답")
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileUploadDto {
|
||||
public class TusFileUploadInitDto {
|
||||
@Schema(description = "파일 마스터 PK", example = "1")
|
||||
private Long fileMasterIdx;
|
||||
|
||||
@@ -42,5 +42,5 @@ public class FileUploadDto {
|
||||
private Integer totalCount;
|
||||
|
||||
@Schema(description = "업로드 파일 항목 목록")
|
||||
private List<FileUploadItemDto> itemList;
|
||||
private List<TusFileUploadInitItemDto> itemList;
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ import lombok.Setter;
|
||||
@Schema(description = "TUS 업로드 파일 항목 응답")
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileUploadItemDto {
|
||||
public class TusFileUploadInitItemDto {
|
||||
@Schema(description = "파일 순번", example = "1")
|
||||
private Integer fileSeq;
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileUploadMetaDto {
|
||||
public class TusFileUploadMetaDto {
|
||||
private String fileUuid;
|
||||
private String originName;
|
||||
private Long sizeBytes;
|
||||
+1
-5
@@ -5,10 +5,6 @@ import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class UploadCancelDto {
|
||||
private Integer userTokenIdx;
|
||||
public class TusFileUploadStatusDto {
|
||||
private String fileUuid;
|
||||
|
||||
private Long uploadedBytes;
|
||||
private Long sizeBytes;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.alist.api.modules.tusFile.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "TUS 파일 보기/다운로드 조회 DTO")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileViewOrDownloadDto {
|
||||
@Schema(description = "파일 UUID", example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10")
|
||||
private String fileUuid;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private Integer userTokenIdx;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private String eventType;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private String clientIp;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private String userAgent;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private String referer;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.alist.api.modules.tusFile.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "업로드 상태 조회 응답")
|
||||
@Getter
|
||||
@Setter
|
||||
public class UploadStatusDto {
|
||||
@Schema(description = "파일 UUID", example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10")
|
||||
private String fileUuid;
|
||||
|
||||
@Schema(description = "업로드 상태. PENDING, UPLOADING, DONE, FAILED", example = "UPLOADING")
|
||||
private String status; // PENDING, UPLOADING, DONE, FAILED
|
||||
|
||||
@Schema(description = "업로드 완료 byte", example = "51200")
|
||||
private Long uploadedBytes;
|
||||
|
||||
@Schema(description = "전체 파일 크기 byte", example = "102400")
|
||||
private Long totalBytes;
|
||||
|
||||
@Schema(description = "업로드 진행률", example = "50")
|
||||
private Integer percent;
|
||||
|
||||
@Schema(description = "상태 갱신 시각", example = "2026-05-19T10:30:00")
|
||||
private String updatedAt;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.alist.api.modules.tusFile.form;
|
||||
|
||||
import com.alist.api.modules.tusFile.dto.FileDeleteDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "파일 삭제 요청 폼")
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileDeleteForm {
|
||||
@Schema(
|
||||
description = "파일 UUID",
|
||||
example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotBlank(message = "파일 UUID는 필수입니다.")
|
||||
private String fileUuid;
|
||||
|
||||
public FileDeleteDto toFileDeleteDto() {
|
||||
FileDeleteDto fileDeleteDto = new FileDeleteDto();
|
||||
fileDeleteDto.setFileUuid(fileUuid == null ? null : fileUuid.trim());
|
||||
return fileDeleteDto;
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.alist.api.modules.tusFile.form;
|
||||
|
||||
import com.alist.api.modules.tusFile.dto.FileUploadDto;
|
||||
import com.alist.api.modules.tusFile.dto.FileUploadItemDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "TUS 파일 업로드 초기화 요청 폼")
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileUploadForm {
|
||||
@Schema(
|
||||
description = "파일 카테고리",
|
||||
example = "BOARD",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotBlank(message = "파일 카테고리는 필수입니다.")
|
||||
private String fileCategory;
|
||||
|
||||
@Schema(description = "업로드 폴더 경로. 미전달 시 / 로 처리됩니다.", example = "/board")
|
||||
private String folderPath;
|
||||
|
||||
@Schema(
|
||||
description = "업로드 파일 목록",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotEmpty(message = "업로드 파일 목록은 필수입니다.")
|
||||
@Valid
|
||||
private List<FileUploadItemForm> itemList;
|
||||
|
||||
public FileUploadDto toFileUploadDto() {
|
||||
FileUploadDto fileUploadDto = new FileUploadDto();
|
||||
|
||||
fileUploadDto.setFileCategory(this.fileCategory.trim());
|
||||
fileUploadDto.setFolderPath((this.folderPath == null || this.folderPath.isBlank()) ? "/" : this.folderPath.trim());
|
||||
|
||||
List<FileUploadItemDto> fileUploadItemDtoList = new ArrayList<>();
|
||||
|
||||
int i = 1;
|
||||
for (FileUploadItemForm item : this.itemList) {
|
||||
FileUploadItemDto fileUploadItemDto = new FileUploadItemDto();
|
||||
|
||||
fileUploadItemDto.setFileSeq(i++);
|
||||
fileUploadItemDto.setOriginName(item.getOriginName());
|
||||
fileUploadItemDto.setSizeBytes(item.getSizeBytes());
|
||||
fileUploadItemDto.setContentType(item.getContentType());
|
||||
|
||||
fileUploadItemDtoList.add(fileUploadItemDto);
|
||||
}
|
||||
|
||||
fileUploadDto.setItemList(fileUploadItemDtoList);
|
||||
|
||||
return fileUploadDto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.alist.api.modules.tusFile.form;
|
||||
|
||||
import com.alist.api.modules.tusFile.dto.TusFileDeleteDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "파일 삭제 요청 폼")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileDeleteForm {
|
||||
@Schema(
|
||||
description = "파일 UUID"
|
||||
, example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10"
|
||||
, requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotBlank(message = "파일 UUID는 필수입니다.")
|
||||
private String fileUuid;
|
||||
|
||||
public TusFileDeleteDto toDto() {
|
||||
TusFileDeleteDto tusFileDeleteDto = new TusFileDeleteDto();
|
||||
tusFileDeleteDto.setFileUuid(fileUuid == null ? null : fileUuid.trim());
|
||||
return tusFileDeleteDto;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -10,8 +10,8 @@ import lombok.Setter;
|
||||
@Getter
|
||||
@Setter
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TusHookEventForm {
|
||||
public class TusFileHookEventForm {
|
||||
@Schema(description = "TUS 업로드 정보")
|
||||
@JsonProperty("Upload")
|
||||
private TusHookUploadForm tusHookUploadForm;
|
||||
private TusFileHookUploadForm tusFileHookUploadForm;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.alist.api.modules.tusFile.form;
|
||||
|
||||
import com.alist.api.modules.tusFile.dto.TusFileHookDto;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "TUS 훅 요청 폼")
|
||||
@Getter
|
||||
@Setter
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TusFileHookForm {
|
||||
@Schema(description = "TUS 훅 이벤트 타입", example = "post-finish")
|
||||
@JsonProperty("Type")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "TUS 훅 이벤트 정보")
|
||||
@JsonProperty("Event")
|
||||
private TusFileHookEventForm tusFileHookEventForm;
|
||||
|
||||
public TusFileHookDto toDto() {
|
||||
TusFileHookDto tusFileHookDto = new TusFileHookDto();
|
||||
|
||||
tusFileHookDto.setType(this.type);
|
||||
|
||||
if (this.tusFileHookEventForm == null || this.tusFileHookEventForm.getTusFileHookUploadForm() == null) {
|
||||
return tusFileHookDto;
|
||||
}
|
||||
|
||||
TusFileHookUploadForm upload = this.tusFileHookEventForm.getTusFileHookUploadForm();
|
||||
tusFileHookDto.setUploadId(upload.getId());
|
||||
tusFileHookDto.setSize(upload.getSize());
|
||||
tusFileHookDto.setOffset(upload.getOffset());
|
||||
|
||||
if (upload.getMetaData() != null) {
|
||||
tusFileHookDto.setFileUuid(upload.getMetaData().get("fileUuid"));
|
||||
tusFileHookDto.setFilename(upload.getMetaData().get("filename"));
|
||||
tusFileHookDto.setFiletype(upload.getMetaData().get("filetype"));
|
||||
}
|
||||
|
||||
return tusFileHookDto;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -12,7 +12,7 @@ import java.util.Map;
|
||||
@Getter
|
||||
@Setter
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TusHookUploadForm {
|
||||
public class TusFileHookUploadForm {
|
||||
@Schema(description = "TUS 업로드 ID", example = "018f6f2d7b5c7d499c3a8c0f4f9f9f10")
|
||||
@JsonProperty("ID")
|
||||
private String id;
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.alist.api.modules.tusFile.form;
|
||||
|
||||
import com.alist.api.modules.tusFile.dto.TusFileUploadCancelDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "업로드 취소 요청 폼")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileUploadCancelForm {
|
||||
@Schema(
|
||||
description = "파일 UUID"
|
||||
, example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10"
|
||||
, requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotBlank(message = "파일 UUID는 필수입니다.")
|
||||
private String fileUuid;
|
||||
|
||||
public TusFileUploadCancelDto toDto() {
|
||||
TusFileUploadCancelDto tusFileUploadCancelDto = new TusFileUploadCancelDto();
|
||||
tusFileUploadCancelDto.setFileUuid(this.fileUuid == null ? null : this.fileUuid.trim());
|
||||
return tusFileUploadCancelDto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.alist.api.modules.tusFile.form;
|
||||
|
||||
import com.alist.api.modules.tusFile.dto.TusFileUploadInitDto;
|
||||
import com.alist.api.modules.tusFile.dto.TusFileUploadInitItemDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "TUS 파일 업로드 초기화 요청 폼")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileUploadInitForm {
|
||||
@Schema(
|
||||
description = "파일 카테고리"
|
||||
, example = "BOARD"
|
||||
, requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotBlank(message = "파일 카테고리는 필수입니다.")
|
||||
private String fileCategory;
|
||||
|
||||
@Schema(description = "업로드 폴더 경로. 미전달 시 / 로 처리됩니다.", example = "/board")
|
||||
private String folderPath;
|
||||
|
||||
@Schema(
|
||||
description = "업로드 파일 목록"
|
||||
, requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotEmpty(message = "업로드 파일 목록은 필수입니다.")
|
||||
@Valid
|
||||
private List<TusFileUploadInitItemForm> itemList;
|
||||
|
||||
public TusFileUploadInitDto toDto() {
|
||||
TusFileUploadInitDto tusFileUploadInitDto = new TusFileUploadInitDto();
|
||||
|
||||
tusFileUploadInitDto.setFileCategory(this.fileCategory.trim());
|
||||
tusFileUploadInitDto.setFolderPath((this.folderPath == null || this.folderPath.isBlank()) ? "/" : this.folderPath.trim());
|
||||
|
||||
List<TusFileUploadInitItemDto> tusFileUploadInitItemDtoList = new ArrayList<>();
|
||||
|
||||
int i = 1;
|
||||
for (TusFileUploadInitItemForm item : this.itemList) {
|
||||
TusFileUploadInitItemDto tusFileUploadInitItemDto = new TusFileUploadInitItemDto();
|
||||
|
||||
tusFileUploadInitItemDto.setFileSeq(i++);
|
||||
tusFileUploadInitItemDto.setOriginName(item.getOriginName());
|
||||
tusFileUploadInitItemDto.setSizeBytes(item.getSizeBytes());
|
||||
tusFileUploadInitItemDto.setContentType(item.getContentType());
|
||||
|
||||
tusFileUploadInitItemDtoList.add(tusFileUploadInitItemDto);
|
||||
}
|
||||
|
||||
tusFileUploadInitDto.setItemList(tusFileUploadInitItemDtoList);
|
||||
|
||||
return tusFileUploadInitDto;
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -10,19 +10,19 @@ import lombok.Setter;
|
||||
@Schema(description = "TUS 업로드 파일 항목")
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileUploadItemForm {
|
||||
public class TusFileUploadInitItemForm {
|
||||
@Schema(
|
||||
description = "원본 파일명",
|
||||
example = "sample.png",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
description = "원본 파일명"
|
||||
, example = "sample.png"
|
||||
, requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotBlank(message = "원본 파일명은 필수입니다.")
|
||||
private String originName;
|
||||
|
||||
@Schema(
|
||||
description = "파일 크기(byte)",
|
||||
example = "102400",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
description = "파일 크기(byte)"
|
||||
, example = "102400"
|
||||
, requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotNull(message = "파일 크기는 필수입니다.")
|
||||
@Positive(message = "파일 크기는 0보다 커야 합니다.")
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.alist.api.modules.tusFile.form;
|
||||
|
||||
import com.alist.api.modules.tusFile.dto.TusFileUploadStatusDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "업로드 상태 조회 요청 폼")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileUploadStatusForm {
|
||||
@Schema(
|
||||
description = "파일 UUID"
|
||||
, example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10"
|
||||
, requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotBlank(message = "파일 UUID는 필수입니다.")
|
||||
private String fileUuid;
|
||||
|
||||
public TusFileUploadStatusDto toDto() {
|
||||
TusFileUploadStatusDto tusFileUploadStatusDto = new TusFileUploadStatusDto();
|
||||
tusFileUploadStatusDto.setFileUuid(this.fileUuid == null ? null : this.fileUuid.trim());
|
||||
return tusFileUploadStatusDto;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.alist.api.modules.tusFile.form;
|
||||
|
||||
import com.alist.api.modules.tusFile.dto.TusHookDto;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "TUS 훅 요청 폼")
|
||||
@Getter
|
||||
@Setter
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TusHookForm {
|
||||
@Schema(description = "TUS 훅 이벤트 타입", example = "post-finish")
|
||||
@JsonProperty("Type")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "TUS 훅 이벤트 정보")
|
||||
@JsonProperty("Event")
|
||||
private TusHookEventForm tusHookEventForm;
|
||||
|
||||
public TusHookDto toTusHookDto() {
|
||||
TusHookDto tusHookDto = new TusHookDto();
|
||||
|
||||
tusHookDto.setType(this.type);
|
||||
|
||||
if (this.tusHookEventForm == null || this.tusHookEventForm.getTusHookUploadForm() == null) {
|
||||
return tusHookDto;
|
||||
}
|
||||
|
||||
TusHookUploadForm upload = this.tusHookEventForm.getTusHookUploadForm();
|
||||
tusHookDto.setUploadId(upload.getId());
|
||||
tusHookDto.setSize(upload.getSize());
|
||||
tusHookDto.setOffset(upload.getOffset());
|
||||
|
||||
if (upload.getMetaData() != null) {
|
||||
tusHookDto.setFileUuid(upload.getMetaData().get("fileUuid"));
|
||||
tusHookDto.setFilename(upload.getMetaData().get("filename"));
|
||||
tusHookDto.setFiletype(upload.getMetaData().get("filetype"));
|
||||
}
|
||||
|
||||
return tusHookDto;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.alist.api.modules.tusFile.form;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "업로드 취소 요청 폼")
|
||||
@Getter
|
||||
@Setter
|
||||
public class UploadCancelForm {
|
||||
@Schema(
|
||||
description = "파일 UUID",
|
||||
example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotBlank(message = "파일 UUID는 필수입니다.")
|
||||
private String fileUuid;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.alist.api.modules.tusFile.form;
|
||||
|
||||
import com.alist.api.modules.tusFile.dto.UploadStatusDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "업로드 상태 조회 요청 폼")
|
||||
@Getter
|
||||
@Setter
|
||||
public class UploadStatusForm {
|
||||
@Schema(
|
||||
description = "파일 UUID",
|
||||
example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotBlank(message = "파일 UUID는 필수입니다.")
|
||||
private String fileUuid;
|
||||
|
||||
public UploadStatusDto toUploadStatusDto() {
|
||||
UploadStatusDto uploadStatusDto = new UploadStatusDto();
|
||||
uploadStatusDto.setFileUuid(this.fileUuid == null ? null : this.fileUuid.trim());
|
||||
return uploadStatusDto;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +1,56 @@
|
||||
package com.alist.api.modules.tusFile.mapper;
|
||||
|
||||
import com.alist.api.modules.tusFile.dto.*;
|
||||
import com.alist.api.modules.tusFile.vo.TusFileListItemVo;
|
||||
import com.alist.api.modules.tusFile.vo.TusFileUploadCancelProgressVo;
|
||||
import com.alist.api.modules.tusFile.vo.TusFileViewOrDownloadVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface TusFileMapper {
|
||||
void insertFileMasterInit(FileUploadDto fileUploadDto);
|
||||
void insertTusFileUploadInitMaster(TusFileUploadInitDto tusFileUploadInitDto);
|
||||
|
||||
void insertFileDetailInit(FileUploadItemDto item);
|
||||
void insertTusFileUploadInitDetail(TusFileUploadInitItemDto tusFileUploadInitItemDto);
|
||||
|
||||
int selectFileDetailCountByFileUuidUserToKenIdx(UploadTokenDto uploadTokenDto);
|
||||
int selectTusFileUploadAuthCount(TusFileUploadAuthDto tusFileUploadAuthDto);
|
||||
|
||||
void insertFileUploadEventLog(TusHookDto tusHookDto);
|
||||
void insertTusFileHookEventLog(TusFileHookDto tusFileHookDto);
|
||||
|
||||
void updateFileDetailStatus(TusHookDto tusHookDto);
|
||||
void updateTusFileHookDetailStatus(TusFileHookDto tusFileHookDto);
|
||||
|
||||
void updateFileMasterAggregateByFileUuid(String fileUuid);
|
||||
|
||||
FileUploadMetaDto selectFileUploadMetaByFileUuid(String fileUuid);
|
||||
TusFileUploadMetaDto selectTusFileUploadMeta(String fileUuid);
|
||||
|
||||
void updateTusUploadIdIfNull(FileUploadMetaDto fileUploadMetaDto);
|
||||
void updateTusFileUploadIdIfNull(TusFileUploadMetaDto tusFileUploadMetaDto);
|
||||
|
||||
void updateFileDetailCanceledByFileUuid(String fileUuid);
|
||||
|
||||
int selectFileDetailCountByFileUuidAndUserToKenIdx(UploadCancelDto uploadCancelDto);
|
||||
int selectTusFileUploadCancelCount(TusFileUploadCancelDto tusFileUploadCancelDto);
|
||||
|
||||
int updateFileDetailCanceledByFileUuidAndUserTokenIdx(UploadCancelDto uploadCancelDto);
|
||||
TusFileUploadCancelProgressVo selectTusFileUploadCancelProgress(TusFileUploadCancelDto tusFileUploadCancelDto);
|
||||
|
||||
UploadCancelDto selectUploadProgressByFileUuid(UploadCancelDto uploadCancelDto);
|
||||
TusFileMoveTaskDto selectTusFileMoveTask(String fileUuid);
|
||||
|
||||
FileMoveTaskDto selectMoveTaskByFileUuid(String fileUuid);
|
||||
int updateTusFileMoveSuccess(TusFileMoveTaskDto tusFileMoveTaskDto);
|
||||
|
||||
int updateFileMoveSuccess(FileMoveTaskDto task);
|
||||
int updateTusFileMovePending(TusFileMoveTaskDto tusFileMoveTaskDto);
|
||||
|
||||
int updateFileMovePendingByFileUuid(FileMoveTaskDto task);
|
||||
List<TusFileListItemVo> selectTusFileList(TusFileListDto tusFileListDto);
|
||||
|
||||
List<FileDownloadItemDto> selectFileDownloadListByFileMasterIdx(FileDownloadDto fileDownloadDto);
|
||||
TusFileViewOrDownloadVo selectTusFileViewOrDownload(TusFileViewOrDownloadDto tusFileViewOrDownloadDto);
|
||||
|
||||
FileDownloadDto selectFileDetailByFileUuid(FileDownloadDto fileDownloadDto);
|
||||
void insertTusFileViewOrDownloadEventLog(TusFileViewOrDownloadVo tusFileViewOrDownloadVo);
|
||||
|
||||
void insertFileDownloadEventLog(FileDownloadDto fileDetailInfo);
|
||||
int selectTusFileDeleteTargetCount(TusFileDeleteDto tusFileDeleteDto);
|
||||
|
||||
int selectFileDeleteTargetCount(FileDeleteDto fileDeleteDto);
|
||||
int updateTusFileDetailDelete(TusFileDeleteDto tusFileDeleteDto);
|
||||
|
||||
int updateFileDetailDeleteByFileUuid(FileDeleteDto fileDeleteDto);
|
||||
|
||||
int updateFileMasterDeleteByFileUuid(FileDeleteDto fileDeleteDto);
|
||||
int updateTusFileMasterDelete(TusFileDeleteDto tusFileDeleteDto);
|
||||
|
||||
Integer selectUserIdxByUserTokenIdx(Integer userTokenIdx);
|
||||
|
||||
int updateTusFileUploadCancel(TusFileUploadCancelDto tusFileUploadCancelDto);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.alist.api.common.utils.SecurityUtil;
|
||||
import com.alist.api.config.jwt.JwtTokenProvider;
|
||||
import com.alist.api.modules.tusFile.dto.*;
|
||||
import com.alist.api.modules.tusFile.mapper.TusFileMapper;
|
||||
import com.alist.api.modules.tusFile.vo.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
@@ -19,10 +20,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@@ -57,70 +55,102 @@ public class TusFileService {
|
||||
|
||||
/*파일 초기화 작업*/
|
||||
@Transactional
|
||||
public FileUploadDto insertFileInit(FileUploadDto fileUploadDto) {
|
||||
fileUploadDto.setStatus(0);
|
||||
fileUploadDto.setTotalCount(fileUploadDto.getItemList().size());
|
||||
public TusFileUploadInitVo insertTusFileUploadInit(TusFileUploadInitDto tusFileUploadInitDto) {
|
||||
tusFileUploadInitDto.setStatus(0);
|
||||
tusFileUploadInitDto.setTotalCount(tusFileUploadInitDto.getItemList().size());
|
||||
|
||||
tusFileMapper.insertFileMasterInit(fileUploadDto);
|
||||
fileUploadDto.setTusEndpoint(tusEndpoint);
|
||||
tusFileMapper.insertTusFileUploadInitMaster(tusFileUploadInitDto);
|
||||
tusFileUploadInitDto.setTusEndpoint(tusEndpoint);
|
||||
|
||||
if (fileUploadDto.getItemList() == null || fileUploadDto.getItemList().isEmpty()) {
|
||||
return fileUploadDto;
|
||||
if (tusFileUploadInitDto.getItemList() == null || tusFileUploadInitDto.getItemList().isEmpty()) {
|
||||
return toTusFileUploadInitVo(tusFileUploadInitDto);
|
||||
}
|
||||
|
||||
for (FileUploadItemDto item : fileUploadDto.getItemList()) {
|
||||
item.setFileMasterIdx(fileUploadDto.getFileMasterIdx());
|
||||
item.setFileUuid(UUID.randomUUID().toString());
|
||||
item.setUploadToken(jwtTokenProvider.createUploadToken(fileUploadDto.getUserTokenIdx()));
|
||||
item.setUserIdx(fileUploadDto.getUserIdx());
|
||||
item.setStatus(0); // PENDING
|
||||
tusFileMapper.insertFileDetailInit(item);
|
||||
for (TusFileUploadInitItemDto tusFileUploadInitItemDto : tusFileUploadInitDto.getItemList()) {
|
||||
tusFileUploadInitItemDto.setFileMasterIdx(tusFileUploadInitDto.getFileMasterIdx());
|
||||
tusFileUploadInitItemDto.setFileUuid(UUID.randomUUID().toString());
|
||||
tusFileUploadInitItemDto.setUploadToken(jwtTokenProvider.createUploadToken(tusFileUploadInitDto.getUserTokenIdx()));
|
||||
tusFileUploadInitItemDto.setUserIdx(tusFileUploadInitDto.getUserIdx());
|
||||
tusFileUploadInitItemDto.setStatus(0);
|
||||
|
||||
tusFileMapper.insertTusFileUploadInitDetail(tusFileUploadInitItemDto);
|
||||
}
|
||||
|
||||
return fileUploadDto;
|
||||
return toTusFileUploadInitVo(tusFileUploadInitDto);
|
||||
}
|
||||
|
||||
private TusFileUploadInitVo toTusFileUploadInitVo(TusFileUploadInitDto tusFileUploadInitDto) {
|
||||
TusFileUploadInitVo tusFileUploadInitVo = new TusFileUploadInitVo();
|
||||
|
||||
tusFileUploadInitVo.setFileMasterIdx(tusFileUploadInitDto.getFileMasterIdx());
|
||||
tusFileUploadInitVo.setTusEndpoint(tusFileUploadInitDto.getTusEndpoint());
|
||||
|
||||
List<TusFileUploadInitItemVo> tusFileUploadInitItemVoList = new ArrayList<>();
|
||||
|
||||
if (tusFileUploadInitDto.getItemList() != null) {
|
||||
for (TusFileUploadInitItemDto tusFileUploadInitItemDto : tusFileUploadInitDto.getItemList()) {
|
||||
TusFileUploadInitItemVo tusFileUploadInitItemVo = new TusFileUploadInitItemVo();
|
||||
|
||||
tusFileUploadInitItemVo.setFileSeq(tusFileUploadInitItemDto.getFileSeq());
|
||||
tusFileUploadInitItemVo.setFileUuid(tusFileUploadInitItemDto.getFileUuid());
|
||||
tusFileUploadInitItemVo.setUploadToken(tusFileUploadInitItemDto.getUploadToken());
|
||||
tusFileUploadInitItemVo.setOriginName(tusFileUploadInitItemDto.getOriginName());
|
||||
tusFileUploadInitItemVo.setSizeBytes(tusFileUploadInitItemDto.getSizeBytes());
|
||||
tusFileUploadInitItemVo.setContentType(tusFileUploadInitItemDto.getContentType());
|
||||
|
||||
tusFileUploadInitItemVoList.add(tusFileUploadInitItemVo);
|
||||
}
|
||||
}
|
||||
|
||||
tusFileUploadInitVo.setItemList(tusFileUploadInitItemVoList);
|
||||
|
||||
return tusFileUploadInitVo;
|
||||
}
|
||||
|
||||
/*업로드 권한 체크*/
|
||||
public UploadTokenDto isUploadTokenCheck(UploadTokenDto uploadTokenDto) {
|
||||
if (!jwtTokenProvider.validateToken(uploadTokenDto.getUploadToken())) {
|
||||
uploadTokenDto.setResultCode(401);
|
||||
return uploadTokenDto;
|
||||
public TusFileUploadAuthVo selectTusFileUploadAuth(TusFileUploadAuthDto tusFileUploadAuthDto) {
|
||||
TusFileUploadAuthVo tusFileUploadAuthVo = new TusFileUploadAuthVo();
|
||||
|
||||
if (!jwtTokenProvider.validateToken(tusFileUploadAuthDto.getUploadToken())) {
|
||||
tusFileUploadAuthVo.setResultCode(401);
|
||||
return tusFileUploadAuthVo;
|
||||
}
|
||||
|
||||
if (!jwtTokenProvider.hasUploadScope(uploadTokenDto.getUploadToken())) {
|
||||
uploadTokenDto.setResultCode(403);
|
||||
return uploadTokenDto;
|
||||
if (!jwtTokenProvider.hasUploadScope(tusFileUploadAuthDto.getUploadToken())) {
|
||||
tusFileUploadAuthVo.setResultCode(403);
|
||||
return tusFileUploadAuthVo;
|
||||
}
|
||||
|
||||
try {
|
||||
uploadTokenDto.setUserTokenIdx(Integer.parseInt(jwtTokenProvider.getUserTokenIdx(uploadTokenDto.getUploadToken())));
|
||||
tusFileUploadAuthDto.setUserTokenIdx(Integer.parseInt(jwtTokenProvider.getUserTokenIdx(tusFileUploadAuthDto.getUploadToken())));
|
||||
} catch (NumberFormatException e) {
|
||||
uploadTokenDto.setResultCode(401);
|
||||
return uploadTokenDto;
|
||||
tusFileUploadAuthVo.setResultCode(401);
|
||||
return tusFileUploadAuthVo;
|
||||
}
|
||||
|
||||
applyTusMeta(uploadTokenDto);
|
||||
applyTusMeta(tusFileUploadAuthDto);
|
||||
|
||||
String cacheKey = buildAuthCacheKey(uploadTokenDto);
|
||||
String cacheKey = buildAuthCacheKey(tusFileUploadAuthDto);
|
||||
|
||||
try {
|
||||
String cached = stringRedisTemplate.opsForValue().get(cacheKey);
|
||||
if (cached != null) {
|
||||
try {
|
||||
uploadTokenDto.setResultCode(Integer.parseInt(cached));
|
||||
return uploadTokenDto;
|
||||
tusFileUploadAuthVo.setResultCode(Integer.parseInt(cached));
|
||||
return tusFileUploadAuthVo;
|
||||
} catch (NumberFormatException parseEx) {
|
||||
log.warn("uploadAuth cache parse fail. key={}, value={}", cacheKey, cached);
|
||||
stringRedisTemplate.delete(cacheKey); // 오염 캐시 정리
|
||||
stringRedisTemplate.delete(cacheKey);
|
||||
}
|
||||
}
|
||||
} catch (Exception redisGetEx) {
|
||||
log.warn("uploadAuth cache get fail. fallback DB. key={}", cacheKey, redisGetEx);
|
||||
}
|
||||
|
||||
int isOk = tusFileMapper.selectFileDetailCountByFileUuidUserToKenIdx(uploadTokenDto);
|
||||
int resultCode = (isOk > 0) ? 200 : 403;
|
||||
uploadTokenDto.setResultCode(resultCode);
|
||||
int tusFileUploadAuthCount = tusFileMapper.selectTusFileUploadAuthCount(tusFileUploadAuthDto);
|
||||
int resultCode = (tusFileUploadAuthCount > 0) ? 200 : 403;
|
||||
|
||||
tusFileUploadAuthVo.setResultCode(resultCode);
|
||||
|
||||
try {
|
||||
stringRedisTemplate.opsForValue().set(
|
||||
@@ -132,16 +162,16 @@ public class TusFileService {
|
||||
log.warn("uploadAuth cache set fail. key={}, resultCode={}", cacheKey, resultCode, redisSetEx);
|
||||
}
|
||||
|
||||
return uploadTokenDto;
|
||||
return tusFileUploadAuthVo;
|
||||
}
|
||||
|
||||
private void applyTusMeta(UploadTokenDto dto) {
|
||||
String len = dto.getUploadLengthRaw();
|
||||
private void applyTusMeta(TusFileUploadAuthDto tusFileUploadAuthDto) {
|
||||
String len = tusFileUploadAuthDto.getUploadLengthRaw();
|
||||
if (len != null && !len.isBlank()) {
|
||||
try { dto.setSizeBytes(Long.parseLong(len.trim())); } catch (Exception ignored) {}
|
||||
try { tusFileUploadAuthDto.setSizeBytes(Long.parseLong(len.trim())); } catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
String raw = dto.getUploadMetadataRaw();
|
||||
String raw = tusFileUploadAuthDto.getUploadMetadataRaw();
|
||||
if (raw == null || raw.isBlank()) return;
|
||||
|
||||
for (String part : raw.split(",")) {
|
||||
@@ -158,20 +188,22 @@ public class TusFileService {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("filename".equals(key)) dto.setOriginName(decoded);
|
||||
else if ("filetype".equals(key)) dto.setContentType(decoded);
|
||||
if ("filename".equals(key)) tusFileUploadAuthDto.setOriginName(decoded);
|
||||
else if ("filetype".equals(key)) tusFileUploadAuthDto.setContentType(decoded);
|
||||
}
|
||||
}
|
||||
|
||||
public UploadStatusDto getUploadStatus(UploadStatusDto uploadStatusDto) {
|
||||
String key = buildUploadStatusKey(uploadStatusDto.getFileUuid());
|
||||
public TusFileUploadStatusVo loadTusFileUploadStatus(TusFileUploadStatusDto tusFileUploadStatusDto) {
|
||||
String key = buildUploadStatusKey(tusFileUploadStatusDto.getFileUuid());
|
||||
Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(key);
|
||||
|
||||
if (map.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String fileUuid = (String) map.getOrDefault("fileUuid", uploadStatusDto.getFileUuid());
|
||||
TusFileUploadStatusVo tusFileUploadStatusVo = new TusFileUploadStatusVo();
|
||||
|
||||
String fileUuid = (String) map.getOrDefault("fileUuid", tusFileUploadStatusDto.getFileUuid());
|
||||
String status = (String) map.getOrDefault("status", "PENDING");
|
||||
long uploadedBytes = parseLong(map.get("uploadedBytes"));
|
||||
long totalBytes = parseLong(map.get("totalBytes"));
|
||||
@@ -184,19 +216,19 @@ public class TusFileService {
|
||||
updatedAt = Instant.now().toString();
|
||||
|
||||
saveCanceledStatusRedis(fileUuid, uploadedBytes, totalBytes);
|
||||
fileMapper.updateFileDetailCanceledByFileUuid(fileUuid);
|
||||
fileMapper.updateFileMasterAggregateByFileUuid(fileUuid);
|
||||
tusFileMapper.updateFileDetailCanceledByFileUuid(fileUuid);
|
||||
tusFileMapper.updateFileMasterAggregateByFileUuid(fileUuid);
|
||||
}
|
||||
*/
|
||||
|
||||
uploadStatusDto.setFileUuid(fileUuid);
|
||||
uploadStatusDto.setStatus(status);
|
||||
uploadStatusDto.setUploadedBytes(uploadedBytes);
|
||||
uploadStatusDto.setTotalBytes(totalBytes);
|
||||
uploadStatusDto.setPercent(percent);
|
||||
uploadStatusDto.setUpdatedAt(updatedAt);
|
||||
tusFileUploadStatusVo.setFileUuid(fileUuid);
|
||||
tusFileUploadStatusVo.setStatus(status);
|
||||
tusFileUploadStatusVo.setUploadedBytes(uploadedBytes);
|
||||
tusFileUploadStatusVo.setTotalBytes(totalBytes);
|
||||
tusFileUploadStatusVo.setPercent(percent);
|
||||
tusFileUploadStatusVo.setUpdatedAt(updatedAt);
|
||||
|
||||
return uploadStatusDto;
|
||||
return tusFileUploadStatusVo;
|
||||
}
|
||||
|
||||
private boolean isStaleUploading(String status, String updatedAt) {
|
||||
@@ -222,23 +254,23 @@ public class TusFileService {
|
||||
|
||||
/*db에 상태값 저장*/
|
||||
@Transactional
|
||||
public boolean updateFileUploadStatus(TusHookDto tusHookDto) {
|
||||
if (tusHookDto == null || tusHookDto.getFileUuid() == null || tusHookDto.getFileUuid().isBlank()) {
|
||||
public boolean updateTusFileHook(TusFileHookDto tusFileHookDto) {
|
||||
if (tusFileHookDto == null || tusFileHookDto.getFileUuid() == null || tusFileHookDto.getFileUuid().isBlank()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String fileUuid = tusHookDto.getFileUuid().trim();
|
||||
String type = tusHookDto.getType() == null ? "" : tusHookDto.getType().trim().toLowerCase();
|
||||
String uploadId = tusHookDto.getUploadId() == null ? "" : tusHookDto.getUploadId().trim();
|
||||
long offset = tusHookDto.getOffset() == null ? 0L : tusHookDto.getOffset();
|
||||
long size = tusHookDto.getSize() == null ? 0L : tusHookDto.getSize();
|
||||
String fileUuid = tusFileHookDto.getFileUuid().trim();
|
||||
String type = tusFileHookDto.getType() == null ? "" : tusFileHookDto.getType().trim().toLowerCase();
|
||||
String uploadId = tusFileHookDto.getUploadId() == null ? "" : tusFileHookDto.getUploadId().trim();
|
||||
long offset = tusFileHookDto.getOffset() == null ? 0L : tusFileHookDto.getOffset();
|
||||
long size = tusFileHookDto.getSize() == null ? 0L : tusFileHookDto.getSize();
|
||||
|
||||
tusFileMapper.insertFileUploadEventLog(tusHookDto);
|
||||
tusFileMapper.insertTusFileHookEventLog(tusFileHookDto);
|
||||
|
||||
FileUploadMetaDto fileUploadMetaInfo = tusFileMapper.selectFileUploadMetaByFileUuid(fileUuid);
|
||||
TusFileUploadMetaDto fileUploadMetaInfo = tusFileMapper.selectTusFileUploadMeta(fileUuid);
|
||||
if (fileUploadMetaInfo == null) return true;
|
||||
|
||||
if (isMetadataMismatch(fileUploadMetaInfo, tusHookDto)) {
|
||||
if (isMetadataMismatch(fileUploadMetaInfo, tusFileHookDto)) {
|
||||
tusFileMapper.updateFileDetailCanceledByFileUuid(fileUuid);
|
||||
tusFileMapper.updateFileMasterAggregateByFileUuid(fileUuid);
|
||||
saveCanceledStatusRedis(fileUuid, offset, size);
|
||||
@@ -247,12 +279,12 @@ public class TusFileService {
|
||||
|
||||
if (!uploadId.isBlank()) {
|
||||
if (fileUploadMetaInfo.getTusUploadId() == null || fileUploadMetaInfo.getTusUploadId().isBlank()) {
|
||||
FileUploadMetaDto fileUploadMetaDto = new FileUploadMetaDto();
|
||||
fileUploadMetaDto.setFileUuid(fileUuid);
|
||||
fileUploadMetaDto.setTusUploadId(uploadId);
|
||||
tusFileMapper.updateTusUploadIdIfNull(fileUploadMetaDto);
|
||||
TusFileUploadMetaDto tusFileUploadMetaDto = new TusFileUploadMetaDto();
|
||||
tusFileUploadMetaDto.setFileUuid(fileUuid);
|
||||
tusFileUploadMetaDto.setTusUploadId(uploadId);
|
||||
tusFileMapper.updateTusFileUploadIdIfNull(tusFileUploadMetaDto);
|
||||
|
||||
fileUploadMetaInfo = tusFileMapper.selectFileUploadMetaByFileUuid(fileUuid);
|
||||
fileUploadMetaInfo = tusFileMapper.selectTusFileUploadMeta(fileUuid);
|
||||
}
|
||||
if (fileUploadMetaInfo.getTusUploadId() == null || fileUploadMetaInfo.getTusUploadId().isBlank()
|
||||
|| !fileUploadMetaInfo.getTusUploadId().equals(uploadId)) {
|
||||
@@ -280,8 +312,8 @@ public class TusFileService {
|
||||
return false;
|
||||
}
|
||||
|
||||
tusHookDto.setUploadedBytes(null);
|
||||
tusHookDto.setStatus(1); // UPLOADING
|
||||
tusFileHookDto.setUploadedBytes(null);
|
||||
tusFileHookDto.setStatus(1); // UPLOADING
|
||||
break;
|
||||
|
||||
case "post-receive":
|
||||
@@ -290,13 +322,13 @@ public class TusFileService {
|
||||
return false;
|
||||
}
|
||||
|
||||
tusHookDto.setUploadedBytes(null);
|
||||
tusHookDto.setStatus(1); // UPLOADING
|
||||
tusFileHookDto.setUploadedBytes(null);
|
||||
tusFileHookDto.setStatus(1); // UPLOADING
|
||||
break;
|
||||
|
||||
case "post-finish":
|
||||
tusHookDto.setUploadedBytes(size);
|
||||
tusHookDto.setStatus(3); // DONE
|
||||
tusFileHookDto.setUploadedBytes(size);
|
||||
tusFileHookDto.setStatus(3); // DONE
|
||||
break;
|
||||
|
||||
case "post-terminate":
|
||||
@@ -304,31 +336,31 @@ public class TusFileService {
|
||||
if (currentStatus != null && currentStatus == 3) {
|
||||
return false;
|
||||
}
|
||||
tusHookDto.setUploadedBytes(offset);
|
||||
tusHookDto.setStatus(5); // CANCELED
|
||||
tusFileHookDto.setUploadedBytes(offset);
|
||||
tusFileHookDto.setStatus(5); // CANCELED
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tusHookDto.getStatus() == 1 && currentStatus != null && currentStatus >= 3) {
|
||||
if (tusFileHookDto.getStatus() == 1 && currentStatus != null && currentStatus >= 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean shouldUpdateDetail = !"post-receive".equals(type);
|
||||
|
||||
if (shouldUpdateDetail) {
|
||||
tusFileMapper.updateFileDetailStatus(tusHookDto);
|
||||
tusFileMapper.updateTusFileHookDetailStatus(tusFileHookDto);
|
||||
}
|
||||
|
||||
if ("post-finish".equals(type) || "post-terminate".equals(type)) {
|
||||
tusFileMapper.updateFileMasterAggregateByFileUuid(tusHookDto.getFileUuid());
|
||||
tusFileMapper.updateFileMasterAggregateByFileUuid(tusFileHookDto.getFileUuid());
|
||||
}
|
||||
|
||||
if ("post-finish".equals(type)) {
|
||||
try {
|
||||
tryMoveNowByFileUuid(tusHookDto.getFileUuid());
|
||||
tryMoveNowByFileUuid(tusFileHookDto.getFileUuid());
|
||||
} catch (NoSuchFileException e) {
|
||||
try {
|
||||
Thread.sleep(200);
|
||||
@@ -336,14 +368,14 @@ public class TusFileService {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
try {
|
||||
tryMoveNowByFileUuid(tusHookDto.getFileUuid()); // 1회 재시도
|
||||
tryMoveNowByFileUuid(tusFileHookDto.getFileUuid()); // 1회 재시도
|
||||
} catch (Exception ex) {
|
||||
log.error("Move failed after retry. fileUuid={}", tusHookDto.getFileUuid(), ex);
|
||||
markMovePending(tusHookDto.getFileUuid(), truncateErr(ex.toString()));
|
||||
log.error("Move failed after retry. fileUuid={}", tusFileHookDto.getFileUuid(), ex);
|
||||
markMovePending(tusFileHookDto.getFileUuid(), truncateErr(ex.toString()));
|
||||
}
|
||||
} catch (Exception moveEx) {
|
||||
log.error("Move failed. fileUuid={}", tusHookDto.getFileUuid(), moveEx);
|
||||
markMovePending(tusHookDto.getFileUuid(), truncateErr(moveEx.toString()));
|
||||
log.error("Move failed. fileUuid={}", tusFileHookDto.getFileUuid(), moveEx);
|
||||
markMovePending(tusFileHookDto.getFileUuid(), truncateErr(moveEx.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,7 +384,7 @@ public class TusFileService {
|
||||
|
||||
@Transactional
|
||||
public void tryMoveNowByFileUuid(String fileUuid) throws IOException {
|
||||
FileMoveTaskDto task = tusFileMapper.selectMoveTaskByFileUuid(fileUuid);
|
||||
TusFileMoveTaskDto task = tusFileMapper.selectTusFileMoveTask(fileUuid);
|
||||
if (task == null) return;
|
||||
if (task.getMoveYn() != null && !"N".equalsIgnoreCase(task.getMoveYn())) return;
|
||||
|
||||
@@ -373,15 +405,15 @@ public class TusFileService {
|
||||
task.setSavePath(toSavePath(finalPath));
|
||||
task.setSaveName(finalPath.getFileName().toString());
|
||||
task.setExt(extractExt(task.getSaveName()));
|
||||
tusFileMapper.updateFileMoveSuccess(task);
|
||||
tusFileMapper.updateTusFileMoveSuccess(task);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void markMovePending(String fileUuid, String errMsg) {
|
||||
FileMoveTaskDto task = new FileMoveTaskDto();
|
||||
task.setFileUuid(fileUuid);
|
||||
task.setMoveLastError(errMsg == null ? "move failed" : errMsg);
|
||||
tusFileMapper.updateFileMovePendingByFileUuid(task); // MOVE_YN='N', TRY_COUNT+1, LAST_ERROR
|
||||
TusFileMoveTaskDto tusFileMoveTaskDto = new TusFileMoveTaskDto();
|
||||
tusFileMoveTaskDto.setFileUuid(fileUuid);
|
||||
tusFileMoveTaskDto.setMoveLastError(errMsg == null ? "move failed" : errMsg);
|
||||
tusFileMapper.updateTusFileMovePending(tusFileMoveTaskDto); // MOVE_YN='N', TRY_COUNT+1, LAST_ERROR
|
||||
}
|
||||
|
||||
private String truncateErr(String s) {
|
||||
@@ -389,7 +421,7 @@ public class TusFileService {
|
||||
return s.length() > 500 ? s.substring(0, 500) : s;
|
||||
}
|
||||
|
||||
private Path resolveTmpPath(FileMoveTaskDto task) {
|
||||
private Path resolveTmpPath(TusFileMoveTaskDto task) {
|
||||
// 예: /srv/project/alist/uploads/tmp/{tusUploadId}
|
||||
if (task.getTusUploadId() == null || task.getTusUploadId().isBlank()) {
|
||||
throw new IllegalStateException("tusUploadId is empty");
|
||||
@@ -397,7 +429,7 @@ public class TusFileService {
|
||||
return Paths.get(uploadTmpRoot, task.getTusUploadId());
|
||||
}
|
||||
|
||||
private Path buildFinalPath(FileMoveTaskDto task) {
|
||||
private Path buildFinalPath(TusFileMoveTaskDto task) {
|
||||
String ext = extractExt(task.getOriginName());
|
||||
String fileName = (task.getFileUuid() == null ? UUID.randomUUID().toString() : task.getFileUuid())
|
||||
+ (ext.isBlank() ? "" : "." + ext);
|
||||
@@ -449,15 +481,15 @@ public class TusFileService {
|
||||
}
|
||||
|
||||
/*레이디스에 상태값 저장*/
|
||||
public void saveUploadStatusRedisTusHook(TusHookDto tusHookDto) {
|
||||
if (tusHookDto == null || tusHookDto.getFileUuid() == null || tusHookDto.getFileUuid().isBlank()) {
|
||||
public void saveTusFileHookStatusRedis(TusFileHookDto tusFileHookDto) {
|
||||
if (tusFileHookDto == null || tusFileHookDto.getFileUuid() == null || tusFileHookDto.getFileUuid().isBlank()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String key = buildUploadStatusKey(tusHookDto.getFileUuid().trim());
|
||||
String type = tusHookDto.getType() == null ? "" : tusHookDto.getType().trim().toLowerCase();
|
||||
long total = tusHookDto.getSize() == null ? 0L : tusHookDto.getSize();
|
||||
long uploaded = tusHookDto.getOffset() == null ? 0L : tusHookDto.getOffset();
|
||||
String key = buildUploadStatusKey(tusFileHookDto.getFileUuid().trim());
|
||||
String type = tusFileHookDto.getType() == null ? "" : tusFileHookDto.getType().trim().toLowerCase();
|
||||
long total = tusFileHookDto.getSize() == null ? 0L : tusFileHookDto.getSize();
|
||||
long uploaded = tusFileHookDto.getOffset() == null ? 0L : tusFileHookDto.getOffset();
|
||||
|
||||
String status = "UPLOADING";
|
||||
if ("post-finish".equals(type)) {
|
||||
@@ -472,7 +504,7 @@ public class TusFileService {
|
||||
int percent = (total > 0) ? (int) Math.min(100, (uploaded * 100) / total) : 0;
|
||||
|
||||
HashOperations<String, Object, Object> ops = stringRedisTemplate.opsForHash();
|
||||
ops.put(key, "fileUuid", tusHookDto.getFileUuid());
|
||||
ops.put(key, "fileUuid", tusFileHookDto.getFileUuid());
|
||||
ops.put(key, "status", status);
|
||||
ops.put(key, "uploadedBytes", String.valueOf(uploaded));
|
||||
ops.put(key, "totalBytes", String.valueOf(total));
|
||||
@@ -510,14 +542,14 @@ public class TusFileService {
|
||||
}
|
||||
}
|
||||
|
||||
private String buildAuthCacheKey(UploadTokenDto dto) {
|
||||
String normalizedName = normalize(dto.getOriginName());
|
||||
String normalizedType = normalize(dto.getContentType());
|
||||
String normalizedSize = (dto.getSizeBytes() == null) ? "" : String.valueOf(dto.getSizeBytes());
|
||||
private String buildAuthCacheKey(TusFileUploadAuthDto tusFileUploadAuthDto) {
|
||||
String normalizedName = normalize(tusFileUploadAuthDto.getOriginName());
|
||||
String normalizedType = normalize(tusFileUploadAuthDto.getContentType());
|
||||
String normalizedSize = (tusFileUploadAuthDto.getSizeBytes() == null) ? "" : String.valueOf(tusFileUploadAuthDto.getSizeBytes());
|
||||
|
||||
String raw = String.join("|",
|
||||
normalize(dto.getFileUuid()),
|
||||
dto.getUploadToken() == null ? "" : dto.getUploadToken(),
|
||||
normalize(tusFileUploadAuthDto.getFileUuid()),
|
||||
tusFileUploadAuthDto.getUploadToken() == null ? "" : tusFileUploadAuthDto.getUploadToken(),
|
||||
normalizedName,
|
||||
normalizedType,
|
||||
normalizedSize
|
||||
@@ -545,96 +577,117 @@ public class TusFileService {
|
||||
return (uploadAuthCacheTtlSeconds > 0) ? uploadAuthCacheTtlSeconds : 20L;
|
||||
}
|
||||
|
||||
private boolean isMetadataMismatch(FileUploadMetaDto fileUploadMetaDto, TusHookDto tusHookDto) {
|
||||
if (tusHookDto.getSize() != null && fileUploadMetaDto.getSizeBytes() != null && !tusHookDto.getSize().equals(fileUploadMetaDto.getSizeBytes())) {
|
||||
private boolean isMetadataMismatch(TusFileUploadMetaDto tusFileUploadMetaDto, TusFileHookDto tusFileHookDto) {
|
||||
if (tusFileHookDto.getSize() != null && tusFileUploadMetaDto.getSizeBytes() != null && !tusFileHookDto.getSize().equals(tusFileUploadMetaDto.getSizeBytes())) {
|
||||
return true;
|
||||
}
|
||||
if (tusHookDto.getFilename() != null && !tusHookDto.getFilename().isBlank()
|
||||
&& fileUploadMetaDto.getOriginName() != null && !fileUploadMetaDto.getOriginName().equals(tusHookDto.getFilename())) {
|
||||
if (tusFileHookDto.getFilename() != null && !tusFileHookDto.getFilename().isBlank()
|
||||
&& tusFileUploadMetaDto.getOriginName() != null && !tusFileUploadMetaDto.getOriginName().equals(tusFileHookDto.getFilename())) {
|
||||
return true;
|
||||
}
|
||||
if (tusHookDto.getFiletype() != null && !tusHookDto.getFiletype().isBlank()
|
||||
&& fileUploadMetaDto.getContentType() != null && !fileUploadMetaDto.getContentType().isBlank()
|
||||
&& !fileUploadMetaDto.getContentType().equalsIgnoreCase(tusHookDto.getFiletype())) {
|
||||
if (tusFileHookDto.getFiletype() != null && !tusFileHookDto.getFiletype().isBlank()
|
||||
&& tusFileUploadMetaDto.getContentType() != null && !tusFileUploadMetaDto.getContentType().isBlank()
|
||||
&& !tusFileUploadMetaDto.getContentType().equalsIgnoreCase(tusFileHookDto.getFiletype())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public boolean updateUploadCancel(UploadCancelDto uploadCancelDto) {
|
||||
if (uploadCancelDto.getFileUuid() == null || uploadCancelDto.getFileUuid().isBlank() || uploadCancelDto.getUserTokenIdx() == null) {
|
||||
return false;
|
||||
public TusFileUploadCancelVo updateTusFileUploadCancel(TusFileUploadCancelDto tusFileUploadCancelDto) {
|
||||
TusFileUploadCancelVo tusFileUploadCancelVo = new TusFileUploadCancelVo();
|
||||
|
||||
if (tusFileUploadCancelDto.getFileUuid() == null
|
||||
|| tusFileUploadCancelDto.getFileUuid().isBlank()
|
||||
|| tusFileUploadCancelDto.getUserTokenIdx() == null) {
|
||||
tusFileUploadCancelVo.setCanceled(false);
|
||||
tusFileUploadCancelVo.setResultCode(4003);
|
||||
return tusFileUploadCancelVo;
|
||||
}
|
||||
|
||||
int allowed = tusFileMapper.selectFileDetailCountByFileUuidAndUserToKenIdx(uploadCancelDto);
|
||||
if (allowed <= 0) {
|
||||
return false;
|
||||
int tusFileUploadCancelCount = tusFileMapper.selectTusFileUploadCancelCount(tusFileUploadCancelDto);
|
||||
if (tusFileUploadCancelCount <= 0) {
|
||||
tusFileUploadCancelVo.setCanceled(false);
|
||||
tusFileUploadCancelVo.setResultCode(2003);
|
||||
return tusFileUploadCancelVo;
|
||||
}
|
||||
|
||||
UploadCancelDto progress = tusFileMapper.selectUploadProgressByFileUuid(uploadCancelDto);
|
||||
long uploaded = (progress != null && progress.getUploadedBytes() != null) ? progress.getUploadedBytes() : 0L;
|
||||
long total = (progress != null && progress.getSizeBytes() != null) ? progress.getSizeBytes() : 0L;
|
||||
TusFileUploadCancelProgressVo tusFileUploadCancelProgressVo = tusFileMapper.selectTusFileUploadCancelProgress(tusFileUploadCancelDto);
|
||||
|
||||
int updated = tusFileMapper.updateFileDetailCanceledByFileUuidAndUserTokenIdx(uploadCancelDto);
|
||||
if (updated <= 0) {
|
||||
return false;
|
||||
long uploadedBytes = (tusFileUploadCancelProgressVo != null && tusFileUploadCancelProgressVo.getUploadedBytes() != null)
|
||||
? tusFileUploadCancelProgressVo.getUploadedBytes()
|
||||
: 0L;
|
||||
|
||||
long totalBytes = (tusFileUploadCancelProgressVo != null && tusFileUploadCancelProgressVo.getSizeBytes() != null)
|
||||
? tusFileUploadCancelProgressVo.getSizeBytes()
|
||||
: 0L;
|
||||
|
||||
int updateCount = tusFileMapper.updateTusFileUploadCancel(tusFileUploadCancelDto);
|
||||
if (updateCount <= 0) {
|
||||
tusFileUploadCancelVo.setCanceled(false);
|
||||
tusFileUploadCancelVo.setResultCode(2003);
|
||||
return tusFileUploadCancelVo;
|
||||
}
|
||||
|
||||
tusFileMapper.updateFileMasterAggregateByFileUuid(uploadCancelDto.getFileUuid());
|
||||
saveCanceledStatusRedis(uploadCancelDto.getFileUuid(), uploaded, total); // 필요하면 기존 bytes 조회해서 넣어도 됨
|
||||
return true;
|
||||
tusFileMapper.updateFileMasterAggregateByFileUuid(tusFileUploadCancelDto.getFileUuid());
|
||||
saveCanceledStatusRedis(tusFileUploadCancelDto.getFileUuid(), uploadedBytes, totalBytes);
|
||||
|
||||
tusFileUploadCancelVo.setCanceled(true);
|
||||
tusFileUploadCancelVo.setResultCode(200);
|
||||
return tusFileUploadCancelVo;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public FileDownloadListDto selectFileDownloadListByFileMasterIdx(FileDownloadDto fileDownloadDto) {
|
||||
FileDownloadListDto fileDownloadList = new FileDownloadListDto();
|
||||
public TusFileListVo selectTusFileList(TusFileListDto tusFileListDto) {
|
||||
TusFileListVo tusFileListVo = new TusFileListVo();
|
||||
|
||||
Integer userTokenIdx = SecurityUtil.getLoginUserTokenIdx();
|
||||
if (userTokenIdx == null) {
|
||||
fileDownloadList.setResultCode(401);
|
||||
return fileDownloadList;
|
||||
tusFileListVo.setResultCode(401);
|
||||
return tusFileListVo;
|
||||
}
|
||||
|
||||
fileDownloadDto.setUserTokenIdx(userTokenIdx);
|
||||
tusFileListDto.setUserTokenIdx(userTokenIdx);
|
||||
|
||||
fileDownloadList.setFileMasterIdx(fileDownloadDto.getFileMasterIdx());
|
||||
tusFileListVo.setFileMasterIdx(tusFileListDto.getFileMasterIdx());
|
||||
|
||||
List<FileDownloadItemDto> itemList = tusFileMapper.selectFileDownloadListByFileMasterIdx(fileDownloadDto);
|
||||
List<TusFileListItemVo> tusFileList = tusFileMapper.selectTusFileList(tusFileListDto);
|
||||
|
||||
for (FileDownloadItemDto item : itemList) {
|
||||
for (TusFileListItemVo item : tusFileList) {
|
||||
item.setViewUrl("/tus/file/view/" + item.getFileUuid());
|
||||
item.setDownloadUrl("/tus/file/download/" + item.getFileUuid());
|
||||
}
|
||||
|
||||
fileDownloadList.setItemList(itemList);
|
||||
fileDownloadList.setResultCode(200);
|
||||
tusFileListVo.setItemList(tusFileList);
|
||||
tusFileListVo.setResultCode(200);
|
||||
|
||||
return fileDownloadList;
|
||||
return tusFileListVo;
|
||||
}
|
||||
|
||||
public FileDownloadDto selectFileViewOrDownload(FileDownloadDto fileDownloadDto) {
|
||||
@Transactional
|
||||
public TusFileViewOrDownloadVo selectTusFileViewOrDownload(TusFileViewOrDownloadDto tusFileViewOrDownloadDto) {
|
||||
Integer userTokenIdx = SecurityUtil.getLoginUserTokenIdx();
|
||||
if (userTokenIdx == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
fileDownloadDto.setUserTokenIdx(userTokenIdx);
|
||||
tusFileViewOrDownloadDto.setUserTokenIdx(userTokenIdx);
|
||||
|
||||
FileDownloadDto fileDetailInfo = tusFileMapper.selectFileDetailByFileUuid(fileDownloadDto);
|
||||
TusFileViewOrDownloadVo tusFileViewOrDownloadVo = tusFileMapper.selectTusFileViewOrDownload(tusFileViewOrDownloadDto);
|
||||
|
||||
if (fileDetailInfo == null) {
|
||||
if (tusFileViewOrDownloadVo == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
fileDetailInfo.setUserTokenIdx(fileDownloadDto.getUserTokenIdx());
|
||||
fileDetailInfo.setEventType(fileDownloadDto.getEventType());
|
||||
fileDetailInfo.setClientIp(fileDownloadDto.getClientIp());
|
||||
fileDetailInfo.setUserAgent(fileDownloadDto.getUserAgent());
|
||||
fileDetailInfo.setReferer(fileDownloadDto.getReferer());
|
||||
tusFileViewOrDownloadVo.setUserTokenIdx(tusFileViewOrDownloadDto.getUserTokenIdx());
|
||||
tusFileViewOrDownloadVo.setEventType(tusFileViewOrDownloadDto.getEventType());
|
||||
tusFileViewOrDownloadVo.setClientIp(tusFileViewOrDownloadDto.getClientIp());
|
||||
tusFileViewOrDownloadVo.setUserAgent(tusFileViewOrDownloadDto.getUserAgent());
|
||||
tusFileViewOrDownloadVo.setReferer(tusFileViewOrDownloadDto.getReferer());
|
||||
|
||||
tusFileMapper.insertFileDownloadEventLog(fileDetailInfo);
|
||||
return fileDetailInfo;
|
||||
tusFileMapper.insertTusFileViewOrDownloadEventLog(tusFileViewOrDownloadVo);
|
||||
|
||||
return tusFileViewOrDownloadVo;
|
||||
}
|
||||
|
||||
public Path resolveStoredFilePath(String savePath) {
|
||||
@@ -655,31 +708,46 @@ public class TusFileService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public boolean updateFileDelete(FileDeleteDto fileDeleteDto) {
|
||||
if (fileDeleteDto == null || fileDeleteDto.getFileUuid() == null || fileDeleteDto.getFileUuid().isBlank()) {
|
||||
return false;
|
||||
public TusFileDeleteVo updateTusFileDelete(TusFileDeleteDto tusFileDeleteDto) {
|
||||
TusFileDeleteVo tusFileDeleteVo = new TusFileDeleteVo();
|
||||
|
||||
if (tusFileDeleteDto == null
|
||||
|| tusFileDeleteDto.getFileUuid() == null
|
||||
|| tusFileDeleteDto.getFileUuid().isBlank()) {
|
||||
tusFileDeleteVo.setDeleted(false);
|
||||
tusFileDeleteVo.setResultCode(4003);
|
||||
return tusFileDeleteVo;
|
||||
}
|
||||
|
||||
Integer userTokenIdx = SecurityUtil.getLoginUserTokenIdx();
|
||||
if (userTokenIdx == null) {
|
||||
return false;
|
||||
tusFileDeleteVo.setDeleted(false);
|
||||
tusFileDeleteVo.setResultCode(401);
|
||||
return tusFileDeleteVo;
|
||||
}
|
||||
|
||||
fileDeleteDto.setUserTokenIdx(userTokenIdx);
|
||||
fileDeleteDto.setFileUuid(fileDeleteDto.getFileUuid().trim());
|
||||
tusFileDeleteDto.setUserTokenIdx(userTokenIdx);
|
||||
tusFileDeleteDto.setFileUuid(tusFileDeleteDto.getFileUuid().trim());
|
||||
|
||||
int allowed = tusFileMapper.selectFileDeleteTargetCount(fileDeleteDto);
|
||||
if (allowed <= 0) {
|
||||
return false;
|
||||
int tusFileDeleteTargetCount = tusFileMapper.selectTusFileDeleteTargetCount(tusFileDeleteDto);
|
||||
if (tusFileDeleteTargetCount <= 0) {
|
||||
tusFileDeleteVo.setDeleted(false);
|
||||
tusFileDeleteVo.setResultCode(2003);
|
||||
return tusFileDeleteVo;
|
||||
}
|
||||
|
||||
int detailUpdated = tusFileMapper.updateFileDetailDeleteByFileUuid(fileDeleteDto);
|
||||
if (detailUpdated <= 0) {
|
||||
return false;
|
||||
int tusFileDetailDeleteCount = tusFileMapper.updateTusFileDetailDelete(tusFileDeleteDto);
|
||||
if (tusFileDetailDeleteCount <= 0) {
|
||||
tusFileDeleteVo.setDeleted(false);
|
||||
tusFileDeleteVo.setResultCode(2003);
|
||||
return tusFileDeleteVo;
|
||||
}
|
||||
|
||||
tusFileMapper.updateFileMasterDeleteByFileUuid(fileDeleteDto);
|
||||
return true;
|
||||
tusFileMapper.updateTusFileMasterDelete(tusFileDeleteDto);
|
||||
|
||||
tusFileDeleteVo.setDeleted(true);
|
||||
tusFileDeleteVo.setResultCode(200);
|
||||
return tusFileDeleteVo;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.alist.api.modules.tusFile.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "TUS 파일 삭제 응답")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileDeleteVo {
|
||||
@Schema(description = "파일 삭제 처리 여부", example = "true")
|
||||
private boolean deleted;
|
||||
|
||||
@JsonIgnore
|
||||
@Schema(hidden = true)
|
||||
private Integer resultCode;
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package com.alist.api.modules.tusFile.dto;
|
||||
package com.alist.api.modules.tusFile.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
@@ -7,7 +7,7 @@ import lombok.Setter;
|
||||
@Schema(description = "다운로드 파일 항목")
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileDownloadItemDto {
|
||||
public class TusFileListItemVo {
|
||||
@Schema(description = "파일 상세 PK", example = "1")
|
||||
private Long fileDetailIdx;
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
package com.alist.api.modules.tusFile.dto;
|
||||
package com.alist.api.modules.tusFile.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
@@ -10,12 +10,12 @@ import java.util.List;
|
||||
@Schema(description = "파일 다운로드 목록 응답")
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileDownloadListDto {
|
||||
public class TusFileListVo {
|
||||
@Schema(description = "파일 마스터 PK", example = "1")
|
||||
private Long fileMasterIdx;
|
||||
|
||||
@Schema(description = "다운로드 파일 목록")
|
||||
private List<FileDownloadItemDto> itemList;
|
||||
private List<TusFileListItemVo> itemList;
|
||||
|
||||
@JsonIgnore
|
||||
@Schema(hidden = true)
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.alist.api.modules.tusFile.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "TUS 업로드 권한 검증 응답")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileUploadAuthVo {
|
||||
@JsonIgnore
|
||||
@Schema(hidden = true)
|
||||
private Integer resultCode;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.alist.api.modules.tusFile.vo;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileUploadCancelProgressVo {
|
||||
private String fileUuid;
|
||||
private Long uploadedBytes;
|
||||
private Long sizeBytes;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.alist.api.modules.tusFile.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "TUS 업로드 취소 응답")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileUploadCancelVo {
|
||||
@JsonIgnore
|
||||
@Schema(hidden = true)
|
||||
private boolean canceled;
|
||||
|
||||
@JsonIgnore
|
||||
@Schema(hidden = true)
|
||||
private Integer resultCode;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.alist.api.modules.tusFile.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "TUS 파일 업로드 초기화 파일 항목 응답")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileUploadInitItemVo {
|
||||
@Schema(description = "파일 순번", example = "1")
|
||||
private Integer fileSeq;
|
||||
|
||||
@Schema(description = "파일 UUID", example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10")
|
||||
private String fileUuid;
|
||||
|
||||
@Schema(description = "TUS 업로드 토큰")
|
||||
private String uploadToken;
|
||||
|
||||
@Schema(description = "원본 파일명", example = "sample.png")
|
||||
private String originName;
|
||||
|
||||
@Schema(description = "파일 크기(byte)", example = "102400")
|
||||
private Long sizeBytes;
|
||||
|
||||
@Schema(description = "Content-Type", example = "image/png")
|
||||
private String contentType;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.alist.api.modules.tusFile.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "TUS 파일 업로드 초기화 응답")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileUploadInitVo {
|
||||
@Schema(description = "파일 마스터 PK", example = "1")
|
||||
private Long fileMasterIdx;
|
||||
|
||||
@Schema(description = "TUS 업로드 엔드포인트", example = "https://file-alist.pjt.kr/tus/file/")
|
||||
private String tusEndpoint;
|
||||
|
||||
@Schema(description = "업로드 파일 항목 목록")
|
||||
private List<TusFileUploadInitItemVo> itemList;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.alist.api.modules.tusFile.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "TUS 업로드 상태 조회 응답")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileUploadStatusVo {
|
||||
@Schema(description = "파일 UUID", example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10")
|
||||
private String fileUuid;
|
||||
|
||||
@Schema(description = "업로드 상태. PENDING, UPLOADING, DONE, CANCELED", example = "UPLOADING")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "업로드 완료 byte", example = "51200")
|
||||
private Long uploadedBytes;
|
||||
|
||||
@Schema(description = "전체 파일 크기 byte", example = "102400")
|
||||
private Long totalBytes;
|
||||
|
||||
@Schema(description = "업로드 진행률", example = "50")
|
||||
private Integer percent;
|
||||
|
||||
@Schema(description = "상태 갱신 시각", example = "2026-05-19T10:30:00")
|
||||
private String updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.alist.api.modules.tusFile.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Schema(description = "TUS 파일 보기/다운로드 조회 결과")
|
||||
@Getter
|
||||
@Setter
|
||||
public class TusFileViewOrDownloadVo {
|
||||
@Schema(description = "파일 상세 PK", example = "1")
|
||||
private Long fileDetailIdx;
|
||||
|
||||
@Schema(description = "파일 마스터 PK", example = "1")
|
||||
private Long fileMasterIdx;
|
||||
|
||||
@Schema(description = "파일 UUID", example = "018f6f2d-7b5c-7d49-9c3a-8c0f4f9f9f10")
|
||||
private String fileUuid;
|
||||
|
||||
@Schema(description = "원본 파일명", example = "sample.png")
|
||||
private String originName;
|
||||
|
||||
@Schema(description = "Content-Type", example = "image/png")
|
||||
private String contentType;
|
||||
|
||||
@Schema(description = "파일 크기(byte)", example = "102400")
|
||||
private Long sizeBytes;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private String savePath;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private Integer userIdx;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private Integer userTokenIdx;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private String eventType;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private String clientIp;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private String userAgent;
|
||||
|
||||
@Schema(hidden = true)
|
||||
private String referer;
|
||||
}
|
||||
@@ -2,9 +2,147 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.alist.api.modules.tusFile.mapper.TusFileMapper">
|
||||
<select id="selectTusFileUploadAuthCount" resultType="java.lang.Integer">
|
||||
/*TusFileMapper.selectTusFileUploadAuthCount*/
|
||||
SELECT COUNT(*)
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||
WHERE LFD.DEL_YN = 'N'
|
||||
AND LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.STATUS IN (0,1,2,3)
|
||||
AND (#{sizeBytes} IS NULL OR LFD.SIZE_BYTES = #{sizeBytes})
|
||||
AND (#{originName} IS NULL OR #{originName} = '' OR LFD.ORIGIN_NAME = #{originName})
|
||||
AND (
|
||||
#{contentType} IS NULL OR #{contentType} = ''
|
||||
OR LFD.CONTENT_TYPE IS NULL OR LFD.CONTENT_TYPE = ''
|
||||
OR LOWER(LFD.CONTENT_TYPE) = LOWER(#{contentType})
|
||||
)
|
||||
</select>
|
||||
|
||||
<insert id="insertFileMasterInit" useGeneratedKeys="true" keyProperty="fileMasterIdx">
|
||||
/*FileMapper.insertFileMasterInit*/
|
||||
<select id="selectTusFileUploadMeta" resultType="com.alist.api.modules.tusFile.dto.TusFileUploadMetaDto">
|
||||
/*TusFileMapper.selectTusFileUploadMeta*/
|
||||
SELECT FILE_UUID, ORIGIN_NAME, SIZE_BYTES, CONTENT_TYPE, TUS_UPLOAD_ID, STATUS
|
||||
FROM ALISTLMS.FILE_DETAIL
|
||||
WHERE FILE_UUID = #{fileUuid}
|
||||
AND DEL_YN = 'N'
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectTusFileUploadCancelCount" resultType="java.lang.Integer">
|
||||
/*TusFileMapper.selectTusFileUploadCancelCount*/
|
||||
SELECT COUNT(*)
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||
WHERE LFD.DEL_YN = 'N'
|
||||
AND LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.STATUS IN (0,1,2)
|
||||
</select>
|
||||
|
||||
<select id="selectTusFileUploadCancelProgress" resultType="com.alist.api.modules.tusFile.vo.TusFileUploadCancelProgressVo">
|
||||
/*TusFileMapper.selectTusFileUploadCancelProgress*/
|
||||
SELECT LFD.FILE_UUID
|
||||
, COALESCE(LFD.UPLOADED_BYTES, 0) AS UPLOADED_BYTES
|
||||
, COALESCE(LFD.SIZE_BYTES, 0) AS SIZE_BYTES
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.DEL_YN = 'N'
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectTusFileMoveTask" resultType="com.alist.api.modules.tusFile.dto.TusFileMoveTaskDto">
|
||||
/*TusFileMapper.selectTusFileMoveTask*/
|
||||
SELECT LFD.FILE_DETAIL_IDX
|
||||
, LFD.FILE_MASTER_IDX
|
||||
, LFD.FILE_UUID
|
||||
, LFD.TUS_UPLOAD_ID
|
||||
, LFD.ORIGIN_NAME
|
||||
, LFD.CONTENT_TYPE
|
||||
, LFD.SIZE_BYTES
|
||||
, LFD.UPLOADED_BYTES
|
||||
, LFM.FOLDER_PATH
|
||||
, LFD.SAVE_NAME
|
||||
, LFD.SAVE_PATH
|
||||
, LFD.`EXT`
|
||||
, LFD.MOVE_YN
|
||||
, LFD.MOVE_TRY_COUNT
|
||||
, LFD.MOVE_LAST_ERROR
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.FILE_MASTER LFM ON LFM.FILE_MASTER_IDX = LFD.FILE_MASTER_IDX
|
||||
AND LFM.DEL_YN = 'N'
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
AND LFD.DEL_YN = 'N'
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectTusFileList" resultType="com.alist.api.modules.tusFile.vo.TusFileListItemVo">
|
||||
/*TusFileMapper.selectTusFileList*/
|
||||
SELECT LFD.FILE_DETAIL_IDX
|
||||
, LFD.FILE_MASTER_IDX
|
||||
, LFD.FILE_UUID
|
||||
, LFD.ORIGIN_NAME
|
||||
, LFD.CONTENT_TYPE
|
||||
, LFD.SIZE_BYTES
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.FILE_MASTER LFM ON LFM.FILE_MASTER_IDX = LFD.FILE_MASTER_IDX
|
||||
AND LFM.DEL_YN = 'N'
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFM.USER_IDX
|
||||
WHERE LFD.FILE_MASTER_IDX = #{fileMasterIdx}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.DEL_YN = 'N'
|
||||
AND LFD.STATUS = 3
|
||||
AND LFD.MOVE_YN = 'Y'
|
||||
ORDER BY LFD.FILE_SEQ ASC, LFD.FILE_DETAIL_IDX ASC
|
||||
</select>
|
||||
|
||||
<select id="selectTusFileViewOrDownload" resultType="com.alist.api.modules.tusFile.vo.TusFileViewOrDownloadVo">
|
||||
/*TusFileMapper.selectTusFileViewOrDownload*/
|
||||
SELECT LFD.FILE_DETAIL_IDX
|
||||
, LFD.FILE_MASTER_IDX
|
||||
, LFD.FILE_UUID
|
||||
, LFD.ORIGIN_NAME
|
||||
, LFD.CONTENT_TYPE
|
||||
, LFD.SIZE_BYTES
|
||||
, LFD.SAVE_PATH
|
||||
, LTUT.user_idx
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.FILE_MASTER LFM ON LFM.FILE_MASTER_IDX = LFD.FILE_MASTER_IDX
|
||||
AND LFM.DEL_YN = 'N'
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFM.USER_IDX
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.DEL_YN = 'N'
|
||||
AND LFD.STATUS = 3
|
||||
AND LFD.MOVE_YN = 'Y'
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectTusFileDeleteTargetCount" resultType="java.lang.Integer">
|
||||
/*TusFileMapper.selectTusFileDeleteTargetCount*/
|
||||
SELECT COUNT(*)
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.FILE_MASTER LFM ON LFM.FILE_MASTER_IDX = LFD.FILE_MASTER_IDX
|
||||
AND LFM.DEL_YN = 'N'
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFM.USER_IDX
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.DEL_YN = 'N'
|
||||
AND LFD.STATUS = 3
|
||||
AND LFM.STATUS = 3
|
||||
</select>
|
||||
|
||||
<select id="selectUserIdxByUserTokenIdx" resultType="java.lang.Integer">
|
||||
/*TusFileMapper.selectUserIdxByUserTokenIdx*/
|
||||
SELECT user_idx
|
||||
FROM test_user_token
|
||||
WHERE user_token_idx = #{userTokenIdx}
|
||||
</select>
|
||||
|
||||
<insert id="insertTusFileUploadInitMaster" useGeneratedKeys="true" keyProperty="fileMasterIdx">
|
||||
/*TusFileMapper.insertTusFileUploadInitMaster*/
|
||||
INSERT INTO ALISTLMS.FILE_MASTER (
|
||||
USER_IDX, FILE_CATEGORY, FOLDER_PATH, TOTAL_COUNT, DONE_COUNT, FAIL_COUNT, STATUS, DEL_YN, CREATE_MEMBER, UPDATE_MEMBER
|
||||
) VALUES (
|
||||
@@ -12,8 +150,8 @@
|
||||
)
|
||||
</insert>
|
||||
|
||||
<insert id="insertFileDetailInit">
|
||||
/*FileMapper.insertFileDetailInit*/
|
||||
<insert id="insertTusFileUploadInitDetail">
|
||||
/*TusFileMapper.insertTusFileUploadInitDetail*/
|
||||
INSERT INTO ALISTLMS.FILE_DETAIL (
|
||||
FILE_MASTER_IDX, FILE_SEQ, FILE_UUID, ORIGIN_NAME, CONTENT_TYPE, SIZE_BYTES, UPLOADED_BYTES, TUS_UPLOAD_ID, STATUS, DEL_YN, CREATE_MEMBER, UPDATE_MEMBER
|
||||
) VALUES (
|
||||
@@ -21,13 +159,12 @@
|
||||
)
|
||||
</insert>
|
||||
|
||||
<insert id="insertFileUploadEventLog">
|
||||
/*FileMapper.insertFileUploadEventLog*/
|
||||
<insert id="insertTusFileHookEventLog">
|
||||
/*TusFileMapper.insertTusFileHookEventLog*/
|
||||
INSERT INTO ALISTLMS.FILE_UPLOAD_EVENT_LOG (
|
||||
FILE_DETAIL_IDX, EVENT_TYPE, OFFSET_BYTES, BYTES_WRITTEN, HTTP_STATUS, MESSAGE, RAW_JSON
|
||||
)
|
||||
SELECT
|
||||
LFD.FILE_DETAIL_IDX
|
||||
SELECT LFD.FILE_DETAIL_IDX
|
||||
, #{type}
|
||||
, #{offset}
|
||||
, NULL
|
||||
@@ -38,8 +175,9 @@
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
LIMIT 1
|
||||
</insert>
|
||||
<insert id="insertFileDownloadEventLog">
|
||||
/*FileMapper.insertFileDownloadEventLog*/
|
||||
|
||||
<insert id="insertTusFileViewOrDownloadEventLog">
|
||||
/*TusFileMapper.insertTusFileViewOrDownloadEventLog*/
|
||||
INSERT INTO ALISTLMS.FILE_DOWNLOAD_EVENT_LOG (
|
||||
FILE_MASTER_IDX
|
||||
, FILE_DETAIL_IDX
|
||||
@@ -67,8 +205,8 @@
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="updateFileDetailStatus">
|
||||
/*FileMapper.updateFileDetailStatus*/
|
||||
<update id="updateTusFileHookDetailStatus">
|
||||
/*TusFileMapper.updateTusFileHookDetailStatus*/
|
||||
UPDATE ALISTLMS.FILE_DETAIL
|
||||
<set>
|
||||
<if test="uploadId != null and uploadId != ''">
|
||||
@@ -87,14 +225,13 @@
|
||||
</update>
|
||||
|
||||
<update id="updateFileMasterAggregateByFileUuid">
|
||||
/*FileMapper.updateFileMasterAggregateByFileUuid*/
|
||||
/*TusFileMapper.updateFileMasterAggregateByFileUuid*/
|
||||
UPDATE ALISTLMS.FILE_MASTER LFM
|
||||
JOIN (
|
||||
SELECT
|
||||
LLFD.FILE_MASTER_IDX,
|
||||
COUNT(*) AS total_count,
|
||||
SUM(CASE WHEN LLFD.STATUS = 3 THEN 1 ELSE 0 END) AS done_count,
|
||||
SUM(CASE WHEN LLFD.STATUS IN (4,5) THEN 1 ELSE 0 END) AS fail_count
|
||||
SELECT LLFD.FILE_MASTER_IDX
|
||||
, COUNT(*) AS total_count
|
||||
, SUM(CASE WHEN LLFD.STATUS = 3 THEN 1 ELSE 0 END) AS done_count
|
||||
, SUM(CASE WHEN LLFD.STATUS IN (4,5) THEN 1 ELSE 0 END) AS fail_count
|
||||
FROM ALISTLMS.FILE_DETAIL LLFD
|
||||
WHERE LLFD.FILE_MASTER_IDX = (
|
||||
SELECT FILE_MASTER_IDX
|
||||
@@ -115,8 +252,9 @@
|
||||
END
|
||||
, LFM.UPDATE_DATE = NOW()
|
||||
</update>
|
||||
<update id="updateTusUploadIdIfNull" parameterType="com.alist.api.modules.tusFile.dto.FileUploadMetaDto">
|
||||
/*FileMapper.updateTusUploadIdIfNull*/
|
||||
|
||||
<update id="updateTusFileUploadIdIfNull" parameterType="com.alist.api.modules.tusFile.dto.TusFileUploadMetaDto">
|
||||
/*TusFileMapper.updateTusFileUploadIdIfNull*/
|
||||
UPDATE ALISTLMS.FILE_DETAIL
|
||||
SET TUS_UPLOAD_ID = #{tusUploadId}
|
||||
, UPDATE_DATE = NOW()
|
||||
@@ -124,8 +262,9 @@
|
||||
AND DEL_YN = 'N'
|
||||
AND TUS_UPLOAD_ID IS NULL
|
||||
</update>
|
||||
|
||||
<update id="updateFileDetailCanceledByFileUuid">
|
||||
/*FileMapper.updateFileDetailCanceledByFileUuid*/
|
||||
/*TusFileMapper.updateFileDetailCanceledByFileUuid*/
|
||||
UPDATE ALISTLMS.FILE_DETAIL
|
||||
SET STATUS = 5
|
||||
, UPDATE_DATE = NOW()
|
||||
@@ -133,147 +272,9 @@
|
||||
AND DEL_YN = 'N'
|
||||
AND STATUS IN (0,1,2)
|
||||
</update>
|
||||
<update id="updateFileDetailCanceledByFileUuidAndUserTokenIdx">
|
||||
/*FileMapper.updateFileDetailCanceledByFileUuidAndUserTokenIdx*/
|
||||
UPDATE ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||
ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||
SET LFD.STATUS = 5
|
||||
, LFD.UPDATE_DATE = NOW()
|
||||
WHERE LFD.DEL_YN = 'N'
|
||||
AND LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.STATUS IN (0,1,2)
|
||||
</update>
|
||||
|
||||
<select id="selectFileDetailCountByFileUuidUserToKenIdx" resultType="java.lang.Integer">
|
||||
/*FileMapper.selectFileDetailCountByFileUuidUserToKenIdx*/
|
||||
SELECT COUNT(*)
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||
ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||
WHERE LFD.DEL_YN = 'N'
|
||||
AND LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.STATUS IN (0,1,2,3)
|
||||
AND (#{sizeBytes} IS NULL OR LFD.SIZE_BYTES = #{sizeBytes})
|
||||
AND (#{originName} IS NULL OR #{originName} = '' OR LFD.ORIGIN_NAME = #{originName})
|
||||
AND (
|
||||
#{contentType} IS NULL OR #{contentType} = ''
|
||||
OR LFD.CONTENT_TYPE IS NULL OR LFD.CONTENT_TYPE = ''
|
||||
OR LOWER(LFD.CONTENT_TYPE) = LOWER(#{contentType})
|
||||
)
|
||||
</select>
|
||||
|
||||
<select id="selectFileUploadMetaByFileUuid" resultType="com.alist.api.modules.tusFile.dto.FileUploadMetaDto">
|
||||
/*FileMapper.selectFileUploadMetaByFileUuid*/
|
||||
SELECT FILE_UUID, ORIGIN_NAME, SIZE_BYTES, CONTENT_TYPE, TUS_UPLOAD_ID, STATUS
|
||||
FROM ALISTLMS.FILE_DETAIL
|
||||
WHERE FILE_UUID = #{fileUuid}
|
||||
AND DEL_YN = 'N'
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectFileDetailCountByFileUuidAndUserToKenIdx" resultType="java.lang.Integer">
|
||||
/*FileMapper.selectFileDetailCountByFileUuidAndUserToKenIdx*/
|
||||
SELECT COUNT(*)
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||
ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||
WHERE LFD.DEL_YN = 'N'
|
||||
AND LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.STATUS IN (0,1,2)
|
||||
</select>
|
||||
|
||||
<select id="selectUploadProgressByFileUuid" resultType="com.alist.api.modules.tusFile.dto.UploadCancelDto">
|
||||
/*FileMapper.selectUploadProgressByFileUuid*/
|
||||
SELECT LFD.FILE_UUID
|
||||
, COALESCE(LFD.UPLOADED_BYTES, 0) AS UPLOADED_BYTES
|
||||
, COALESCE(LFD.SIZE_BYTES, 0) AS SIZE_BYTES
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||
ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.DEL_YN = 'N'
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectMoveTaskByFileUuid" resultType="com.alist.api.modules.tusFile.dto.FileMoveTaskDto">
|
||||
/*FileMapper.selectMoveTaskByFileUuid*/
|
||||
SELECT LFD.FILE_DETAIL_IDX
|
||||
, LFD.FILE_MASTER_IDX
|
||||
, LFD.FILE_UUID
|
||||
, LFD.TUS_UPLOAD_ID
|
||||
, LFD.ORIGIN_NAME
|
||||
, LFD.CONTENT_TYPE
|
||||
, LFD.SIZE_BYTES
|
||||
, LFD.UPLOADED_BYTES
|
||||
, LFM.FOLDER_PATH
|
||||
, LFD.SAVE_NAME
|
||||
, LFD.SAVE_PATH
|
||||
, LFD.`EXT`
|
||||
, LFD.MOVE_YN
|
||||
, LFD.MOVE_TRY_COUNT
|
||||
, LFD.MOVE_LAST_ERROR
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.FILE_MASTER LFM
|
||||
ON LFM.FILE_MASTER_IDX = LFD.FILE_MASTER_IDX
|
||||
AND LFM.DEL_YN = 'N'
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
AND LFD.DEL_YN = 'N'
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectFileDownloadListByFileMasterIdx" resultType="com.alist.api.modules.tusFile.dto.FileDownloadItemDto">
|
||||
/*FileMapper.selectFileDownloadListByFileMasterIdx*/
|
||||
SELECT LFD.FILE_DETAIL_IDX
|
||||
, LFD.FILE_MASTER_IDX
|
||||
, LFD.FILE_UUID
|
||||
, LFD.ORIGIN_NAME
|
||||
, LFD.CONTENT_TYPE
|
||||
, LFD.SIZE_BYTES
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.FILE_MASTER LFM
|
||||
ON LFM.FILE_MASTER_IDX = LFD.FILE_MASTER_IDX
|
||||
AND LFM.DEL_YN = 'N'
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||
ON LTUT.user_idx = LFM.USER_IDX
|
||||
WHERE LFD.FILE_MASTER_IDX = #{fileMasterIdx}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.DEL_YN = 'N'
|
||||
AND LFD.STATUS = 3
|
||||
AND LFD.MOVE_YN = 'Y'
|
||||
ORDER BY LFD.FILE_SEQ ASC, LFD.FILE_DETAIL_IDX ASC
|
||||
</select>
|
||||
|
||||
<select id="selectFileDetailByFileUuid" resultType="com.alist.api.modules.tusFile.dto.FileDownloadDto">
|
||||
/*FileMapper.selectFileDetailByFileUuid*/
|
||||
SELECT LFD.FILE_DETAIL_IDX
|
||||
, LFD.FILE_MASTER_IDX
|
||||
, LFD.FILE_UUID
|
||||
, LFD.ORIGIN_NAME
|
||||
, LFD.CONTENT_TYPE
|
||||
, LFD.SIZE_BYTES
|
||||
, LFD.SAVE_PATH
|
||||
, LTUT.user_idx
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.FILE_MASTER LFM
|
||||
ON LFM.FILE_MASTER_IDX = LFD.FILE_MASTER_IDX
|
||||
AND LFM.DEL_YN = 'N'
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||
ON LTUT.user_idx = LFM.USER_IDX
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.DEL_YN = 'N'
|
||||
AND LFD.STATUS = 3
|
||||
AND LFD.MOVE_YN = 'Y'
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<update id="updateFileMoveSuccess" parameterType="com.alist.api.modules.tusFile.dto.FileMoveTaskDto">
|
||||
/*FileMapper.updateFileMoveSuccess*/
|
||||
<update id="updateTusFileMoveSuccess" parameterType="com.alist.api.modules.tusFile.dto.TusFileMoveTaskDto">
|
||||
/*TusFileMapper.updateTusFileMoveSuccess*/
|
||||
UPDATE ALISTLMS.FILE_DETAIL
|
||||
SET SAVE_NAME = #{saveName}
|
||||
, SAVE_PATH = #{savePath}
|
||||
@@ -288,8 +289,8 @@
|
||||
AND DEL_YN = 'N'
|
||||
</update>
|
||||
|
||||
<update id="updateFileMovePendingByFileUuid" parameterType="com.alist.api.modules.tusFile.dto.FileMoveTaskDto">
|
||||
/*FileMapper.updateFileMovePendingByFileUuid*/
|
||||
<update id="updateTusFileMovePending" parameterType="com.alist.api.modules.tusFile.dto.TusFileMoveTaskDto">
|
||||
/*TusFileMapper.updateTusFileMovePending*/
|
||||
UPDATE ALISTLMS.FILE_DETAIL
|
||||
SET MOVE_YN = 'N'
|
||||
, MOVE_TRY_COUNT = COALESCE(MOVE_TRY_COUNT, 0) + 1
|
||||
@@ -300,36 +301,12 @@
|
||||
AND STATUS = 3
|
||||
</update>
|
||||
|
||||
<select id="selectFileDeleteTargetCount" resultType="java.lang.Integer">
|
||||
/*FileMapper.selectFileDeleteTargetCount*/
|
||||
SELECT COUNT(*)
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.FILE_MASTER LFM
|
||||
ON LFM.FILE_MASTER_IDX = LFD.FILE_MASTER_IDX
|
||||
AND LFM.DEL_YN = 'N'
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||
ON LTUT.user_idx = LFM.USER_IDX
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.DEL_YN = 'N'
|
||||
AND LFD.STATUS = 3
|
||||
AND LFM.STATUS = 3
|
||||
</select>
|
||||
<select id="selectUserIdxByUserTokenIdx" resultType="java.lang.Integer">
|
||||
/*FileMapper.selectUserIdxByUserTokenIdx*/
|
||||
SELECT user_idx
|
||||
FROM test_user_token
|
||||
WHERE user_token_idx = #{userTokenIdx}
|
||||
</select>
|
||||
|
||||
<update id="updateFileDetailDeleteByFileUuid">
|
||||
/*FileMapper.updateFileDetailDeleteByFileUuid*/
|
||||
<update id="updateTusFileDetailDelete">
|
||||
/*TusFileMapper.updateTusFileDetailDelete*/
|
||||
UPDATE ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.FILE_MASTER LFM
|
||||
ON LFM.FILE_MASTER_IDX = LFD.FILE_MASTER_IDX
|
||||
INNER JOIN ALISTLMS.FILE_MASTER LFM ON LFM.FILE_MASTER_IDX = LFD.FILE_MASTER_IDX
|
||||
AND LFM.DEL_YN = 'N'
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||
ON LTUT.user_idx = LFM.USER_IDX
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFM.USER_IDX
|
||||
SET LFD.DEL_YN = 'Y'
|
||||
, LFD.UPDATE_DATE = NOW()
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
@@ -339,8 +316,8 @@
|
||||
AND LFM.STATUS = 3
|
||||
</update>
|
||||
|
||||
<update id="updateFileMasterDeleteByFileUuid">
|
||||
/*FileMapper.updateFileMasterDeleteByFileUuid*/
|
||||
<update id="updateTusFileMasterDelete">
|
||||
/*TusFileMapper.updateTusFileMasterDelete*/
|
||||
UPDATE ALISTLMS.FILE_MASTER LFM
|
||||
INNER JOIN (
|
||||
SELECT LFD.FILE_MASTER_IDX
|
||||
@@ -348,8 +325,7 @@
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
AND LFD.DEL_YN = 'Y'
|
||||
LIMIT 1
|
||||
) TARGET
|
||||
ON TARGET.FILE_MASTER_IDX = LFM.FILE_MASTER_IDX
|
||||
) TARGET ON TARGET.FILE_MASTER_IDX = LFM.FILE_MASTER_IDX
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||
ON LTUT.user_idx = LFM.USER_IDX
|
||||
SET LFM.DEL_YN = 'Y'
|
||||
@@ -365,4 +341,16 @@
|
||||
)
|
||||
</update>
|
||||
|
||||
<update id="updateTusFileUploadCancel">
|
||||
/*TusFileMapper.updateTusFileUploadCancel*/
|
||||
UPDATE ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||
SET LFD.STATUS = 5
|
||||
, LFD.UPDATE_DATE = NOW()
|
||||
WHERE LFD.DEL_YN = 'N'
|
||||
AND LFD.FILE_UUID = #{fileUuid}
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.STATUS IN (0,1,2)
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user