[파일 업로드] tusHook 작업
- 파일 이동작업
This commit is contained in:
@@ -21,7 +21,10 @@ import org.springframework.http.ResponseEntity;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Tag(name = "99. 파일 관리", description = "파일 관리")
|
@Tag(
|
||||||
|
name = "99. TUS 업로드",
|
||||||
|
description = "TUS 기반 파일 업로드 초기화, 권한 검증, 상태 조회, 훅 처리, 취소 API"
|
||||||
|
)
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/files")
|
@RequestMapping("/files")
|
||||||
public class FileController {
|
public class FileController {
|
||||||
@@ -32,8 +35,8 @@ public class FileController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "파일 업로드 준비(db 입력 및 업로드 토큰 생성)",
|
summary = "파일 업로드 초기화",
|
||||||
description = "업로드 토큰 생성 및 파일 업로드 준비"
|
description = "업로드 대상 파일 정보를 DB에 등록하고 fileUuid/uploadToken을 발급합니다."
|
||||||
)
|
)
|
||||||
@PostMapping("/uploadInit")
|
@PostMapping("/uploadInit")
|
||||||
public ResponseEntity<ApiResponse<FileUploadDto>> uploadInit(
|
public ResponseEntity<ApiResponse<FileUploadDto>> uploadInit(
|
||||||
@@ -59,8 +62,8 @@ public class FileController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "업로드 권한 체크",
|
summary = "업로드 권한 검증",
|
||||||
description = "업로드 토큰 발급 후 실제 업로드 권한이 있는지 확인 과정입니다."
|
description = "Bearer 업로드 토큰과 fileUuid(및 TUS 메타데이터)를 검증해 업로드 가능 여부를 확인합니다."
|
||||||
)
|
)
|
||||||
@GetMapping("/uploadAuth")
|
@GetMapping("/uploadAuth")
|
||||||
public ResponseEntity<ApiResponse<String>> uploadAuth(
|
public ResponseEntity<ApiResponse<String>> uploadAuth(
|
||||||
@@ -93,6 +96,10 @@ public class FileController {
|
|||||||
return ApiResponse.entity("", ApiResponseCode.CODE_200);
|
return ApiResponse.entity("", ApiResponseCode.CODE_200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "업로드 상태 조회",
|
||||||
|
description = "fileUuid 기준으로 Redis/DB 업로드 상태(진행률, 상태값)를 조회합니다."
|
||||||
|
)
|
||||||
@PostMapping("/uploadStatus")
|
@PostMapping("/uploadStatus")
|
||||||
public ResponseEntity<ApiResponse<UploadStatusDto>> uploadStatus(
|
public ResponseEntity<ApiResponse<UploadStatusDto>> uploadStatus(
|
||||||
@Valid @RequestBody UploadStatusForm uploadStatusForm
|
@Valid @RequestBody UploadStatusForm uploadStatusForm
|
||||||
@@ -104,6 +111,10 @@ public class FileController {
|
|||||||
return ApiResponse.entity(status, ApiResponseCode.CODE_200);
|
return ApiResponse.entity(status, ApiResponseCode.CODE_200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "TUS 훅 수신",
|
||||||
|
description = "tusd에서 전달되는 pre-create/post-receive/post-finish/post-terminate 이벤트를 반영합니다."
|
||||||
|
)
|
||||||
@PostMapping("/tusHook")
|
@PostMapping("/tusHook")
|
||||||
public ResponseEntity<ApiResponse<String>> tusHook(@RequestBody TusHookForm tusHookForm) {
|
public ResponseEntity<ApiResponse<String>> tusHook(@RequestBody TusHookForm tusHookForm) {
|
||||||
boolean accepted = fileService.updateFileUploadStatus(tusHookForm.tusHookDto());
|
boolean accepted = fileService.updateFileUploadStatus(tusHookForm.tusHookDto());
|
||||||
@@ -115,6 +126,10 @@ public class FileController {
|
|||||||
return ApiResponse.entity("", ApiResponseCode.CODE_200);
|
return ApiResponse.entity("", ApiResponseCode.CODE_200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "업로드 취소",
|
||||||
|
description = "현재 로그인 사용자의 fileUuid 업로드를 취소(CANCELED) 처리합니다."
|
||||||
|
)
|
||||||
@PostMapping("/uploadCancel")
|
@PostMapping("/uploadCancel")
|
||||||
public ResponseEntity<ApiResponse<String>> uploadCancel(
|
public ResponseEntity<ApiResponse<String>> uploadCancel(
|
||||||
@Valid @RequestBody UploadCancelForm uploadCancelForm
|
@Valid @RequestBody UploadCancelForm uploadCancelForm
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.alist.api.common.modules.file.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class FileMoveTaskDto {
|
||||||
|
private Long fileDetailIdx;
|
||||||
|
private Long fileMasterIdx;
|
||||||
|
private String fileUuid;
|
||||||
|
private String tusUploadId;
|
||||||
|
private String originName;
|
||||||
|
private String contentType;
|
||||||
|
private Long sizeBytes;
|
||||||
|
private Long uploadedBytes;
|
||||||
|
|
||||||
|
private String saveName;
|
||||||
|
private String savePath;
|
||||||
|
private String ext;
|
||||||
|
|
||||||
|
private String moveYn;
|
||||||
|
private Integer moveTryCount;
|
||||||
|
private String moveLastError;
|
||||||
|
private String moveLockOwner;
|
||||||
|
}
|
||||||
@@ -32,4 +32,10 @@ public interface FileMapper {
|
|||||||
int updateFileDetailCanceledByFileUuidAndUserTokenIdx(UploadCancelDto uploadCancelDto);
|
int updateFileDetailCanceledByFileUuidAndUserTokenIdx(UploadCancelDto uploadCancelDto);
|
||||||
|
|
||||||
UploadCancelDto selectUploadProgressByFileUuid(UploadCancelDto uploadCancelDto);
|
UploadCancelDto selectUploadProgressByFileUuid(UploadCancelDto uploadCancelDto);
|
||||||
|
|
||||||
|
FileMoveTaskDto selectMoveTaskByFileUuid(String fileUuid);
|
||||||
|
|
||||||
|
int updateFileMoveSuccess(FileMoveTaskDto task);
|
||||||
|
|
||||||
|
int updateFileMovePendingByFileUuid(FileMoveTaskDto task);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,14 @@ import org.springframework.data.redis.core.StringRedisTemplate;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.*;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.HexFormat;
|
import java.util.HexFormat;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -34,6 +37,12 @@ public class FileService {
|
|||||||
@Value("${file.upload.interrupt-seconds:30}")
|
@Value("${file.upload.interrupt-seconds:30}")
|
||||||
private long uploadInterruptSeconds;
|
private long uploadInterruptSeconds;
|
||||||
|
|
||||||
|
@Value("${file.upload.tmp-root}")
|
||||||
|
private String uploadTmpRoot;
|
||||||
|
|
||||||
|
@Value("${file.upload.final-root}")
|
||||||
|
private String uploadFinalRoot;
|
||||||
|
|
||||||
private final FileMapper fileMapper;
|
private final FileMapper fileMapper;
|
||||||
private final JwtTokenProvider jwtTokenProvider;
|
private final JwtTokenProvider jwtTokenProvider;
|
||||||
private final StringRedisTemplate stringRedisTemplate;
|
private final StringRedisTemplate stringRedisTemplate;
|
||||||
@@ -306,9 +315,95 @@ public class FileService {
|
|||||||
fileMapper.updateFileMasterAggregateByFileUuid(tusHookDto.getFileUuid());
|
fileMapper.updateFileMasterAggregateByFileUuid(tusHookDto.getFileUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ("post-finish".equals(type)) {
|
||||||
|
try {
|
||||||
|
// 1회 빠른 이동 시도 (성공하면 MOVE_YN=Y)
|
||||||
|
tryMoveNowByFileUuid(tusHookDto.getFileUuid());
|
||||||
|
} catch (Exception moveEx) {
|
||||||
|
// 실패하면 큐 처리 대상으로 남기기 (MOVE_YN=N, 에러 기록)
|
||||||
|
markMovePending(tusHookDto.getFileUuid(), truncateErr(moveEx.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void tryMoveNowByFileUuid(String fileUuid) throws IOException {
|
||||||
|
FileMoveTaskDto task = fileMapper.selectMoveTaskByFileUuid(fileUuid);
|
||||||
|
if (task == null) return;
|
||||||
|
if (!"N".equalsIgnoreCase(task.getMoveYn())) return;
|
||||||
|
|
||||||
|
// 임시 경로 계산 (운영 경로 규칙에 맞게 구현)
|
||||||
|
Path tmpPath = resolveTmpPath(task); // ex) /uploads/tmp/{tusUploadId}
|
||||||
|
Path finalPath = buildFinalPath(task); // ex) /uploads/{yyyy}/{MM}/{uuid}.{ext}
|
||||||
|
|
||||||
|
Files.createDirectories(finalPath.getParent());
|
||||||
|
|
||||||
|
try {
|
||||||
|
Files.move(tmpPath, finalPath, StandardCopyOption.ATOMIC_MOVE);
|
||||||
|
} catch (AtomicMoveNotSupportedException ex) {
|
||||||
|
// cross-device 대비 fallback
|
||||||
|
Files.copy(tmpPath, finalPath, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
Files.deleteIfExists(tmpPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
task.setSavePath(toSavePath(finalPath)); // DB 저장용 상대경로
|
||||||
|
task.setSaveName(finalPath.getFileName().toString());
|
||||||
|
task.setExt(extractExt(task.getSaveName()));
|
||||||
|
|
||||||
|
fileMapper.updateFileMoveSuccess(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void markMovePending(String fileUuid, String errMsg) {
|
||||||
|
FileMoveTaskDto task = new FileMoveTaskDto();
|
||||||
|
task.setFileUuid(fileUuid);
|
||||||
|
task.setMoveLastError(errMsg == null ? "move failed" : errMsg);
|
||||||
|
fileMapper.updateFileMovePendingByFileUuid(task); // MOVE_YN='N', TRY_COUNT+1, LAST_ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
private String truncateErr(String s) {
|
||||||
|
if (s == null) return "unknown";
|
||||||
|
return s.length() > 500 ? s.substring(0, 500) : s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path resolveTmpPath(FileMoveTaskDto task) {
|
||||||
|
// 예: /srv/project/alist/uploads/tmp/{tusUploadId}
|
||||||
|
if (task.getTusUploadId() == null || task.getTusUploadId().isBlank()) {
|
||||||
|
throw new IllegalStateException("tusUploadId is empty");
|
||||||
|
}
|
||||||
|
return Paths.get(uploadTmpRoot, task.getTusUploadId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path buildFinalPath(FileMoveTaskDto task) {
|
||||||
|
String ext = extractExt(task.getOriginName());
|
||||||
|
String fileName = (task.getFileUuid() == null ? UUID.randomUUID().toString() : task.getFileUuid())
|
||||||
|
+ (ext.isBlank() ? "" : "." + ext);
|
||||||
|
|
||||||
|
LocalDate now = LocalDate.now();
|
||||||
|
return Paths.get(uploadFinalRoot,
|
||||||
|
String.valueOf(now.getYear()),
|
||||||
|
String.format("%02d", now.getMonthValue()),
|
||||||
|
String.format("%02d", now.getDayOfMonth()),
|
||||||
|
fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toSavePath(Path finalPath) {
|
||||||
|
// DB 저장용 상대경로(운영 규칙에 맞게 조정)
|
||||||
|
// 예: /2026/03/09/xxx.zip
|
||||||
|
Path root = Paths.get(uploadFinalRoot);
|
||||||
|
Path rel = root.relativize(finalPath);
|
||||||
|
return "/" + rel.toString().replace("\\", "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractExt(String name) {
|
||||||
|
if (name == null) return "";
|
||||||
|
int idx = name.lastIndexOf('.');
|
||||||
|
if (idx < 0 || idx == name.length() - 1) return "";
|
||||||
|
return name.substring(idx + 1).trim().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
/*레이디스에 상태값 저장*/
|
/*레이디스에 상태값 저장*/
|
||||||
public void saveUploadStatusRedisTusHook(TusHookDto tusHookDto) {
|
public void saveUploadStatusRedisTusHook(TusHookDto tusHookDto) {
|
||||||
if (tusHookDto == null || tusHookDto.getFileUuid() == null || tusHookDto.getFileUuid().isBlank()) {
|
if (tusHookDto == null || tusHookDto.getFileUuid() == null || tusHookDto.getFileUuid().isBlank()) {
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ file:
|
|||||||
upload:
|
upload:
|
||||||
tus-endpoint: https://file-alist.pjt.kr/tus/files/
|
tus-endpoint: https://file-alist.pjt.kr/tus/files/
|
||||||
public-base-url: https://file-alist.pjt.kr
|
public-base-url: https://file-alist.pjt.kr
|
||||||
|
tmp-root: /srv/project/alist/uploads/tmp
|
||||||
|
final-root: /srv/project/alist/uploads
|
||||||
interrupt-seconds: 30
|
interrupt-seconds: 30
|
||||||
auth-cache:
|
auth-cache:
|
||||||
ttl-seconds: 20
|
ttl-seconds: 20
|
||||||
|
|||||||
@@ -85,16 +85,16 @@
|
|||||||
)
|
)
|
||||||
AND LLFD.DEL_YN = 'N'
|
AND LLFD.DEL_YN = 'N'
|
||||||
) A ON A.FILE_MASTER_IDX = LFM.FILE_MASTER_IDX
|
) A ON A.FILE_MASTER_IDX = LFM.FILE_MASTER_IDX
|
||||||
SET LFM.TOTAL_COUNT = A.total_count,
|
SET LFM.TOTAL_COUNT = A.total_count
|
||||||
LFM.DONE_COUNT = A.done_count,
|
, LFM.DONE_COUNT = A.done_count
|
||||||
LFM.FAIL_COUNT = A.fail_count,
|
, LFM.FAIL_COUNT = A.fail_count
|
||||||
LFM.STATUS = CASE
|
, LFM.STATUS = CASE
|
||||||
WHEN A.done_count = A.total_count THEN 3
|
WHEN A.done_count = A.total_count THEN 3
|
||||||
WHEN A.done_count = 0 AND A.fail_count = A.total_count THEN 4
|
WHEN A.done_count = 0 AND A.fail_count = A.total_count THEN 4
|
||||||
WHEN A.done_count > 0 AND A.fail_count > 0 THEN 5
|
WHEN A.done_count > 0 AND A.fail_count > 0 THEN 5
|
||||||
ELSE 1
|
ELSE 1
|
||||||
END,
|
END
|
||||||
LFM.UPDATE_DATE = NOW()
|
, LFM.UPDATE_DATE = NOW()
|
||||||
</update>
|
</update>
|
||||||
<update id="updateTusUploadIdIfNull" parameterType="com.alist.api.common.modules.file.dto.FileUploadMetaDto">
|
<update id="updateTusUploadIdIfNull" parameterType="com.alist.api.common.modules.file.dto.FileUploadMetaDto">
|
||||||
/*FileMapper.updateTusUploadIdIfNull*/
|
/*FileMapper.updateTusUploadIdIfNull*/
|
||||||
@@ -108,8 +108,8 @@
|
|||||||
<update id="updateFileDetailCanceledByFileUuid">
|
<update id="updateFileDetailCanceledByFileUuid">
|
||||||
/*FileMapper.updateFileDetailCanceledByFileUuid*/
|
/*FileMapper.updateFileDetailCanceledByFileUuid*/
|
||||||
UPDATE ALISTLMS.FILE_DETAIL
|
UPDATE ALISTLMS.FILE_DETAIL
|
||||||
SET STATUS = 5,
|
SET STATUS = 5
|
||||||
UPDATE_DATE = NOW()
|
, UPDATE_DATE = NOW()
|
||||||
WHERE FILE_UUID = #{fileUuid}
|
WHERE FILE_UUID = #{fileUuid}
|
||||||
AND DEL_YN = 'N'
|
AND DEL_YN = 'N'
|
||||||
AND STATUS IN (0,1,2)
|
AND STATUS IN (0,1,2)
|
||||||
@@ -117,9 +117,10 @@
|
|||||||
<update id="updateFileDetailCanceledByFileUuidAndUserTokenIdx">
|
<update id="updateFileDetailCanceledByFileUuidAndUserTokenIdx">
|
||||||
/*FileMapper.updateFileDetailCanceledByFileUuidAndUserTokenIdx*/
|
/*FileMapper.updateFileDetailCanceledByFileUuidAndUserTokenIdx*/
|
||||||
UPDATE ALISTLMS.FILE_DETAIL LFD
|
UPDATE ALISTLMS.FILE_DETAIL LFD
|
||||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFD.CREATE_MEMBER
|
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||||
SET LFD.STATUS = 5,
|
ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||||
LFD.UPDATE_DATE = NOW()
|
SET LFD.STATUS = 5
|
||||||
|
, LFD.UPDATE_DATE = NOW()
|
||||||
WHERE LFD.DEL_YN = 'N'
|
WHERE LFD.DEL_YN = 'N'
|
||||||
AND LFD.FILE_UUID = #{fileUuid}
|
AND LFD.FILE_UUID = #{fileUuid}
|
||||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||||
@@ -130,7 +131,8 @@
|
|||||||
/*FileMapper.selectFileMasterCountByFileMasterKeyAndDelYnAndStatus*/
|
/*FileMapper.selectFileMasterCountByFileMasterKeyAndDelYnAndStatus*/
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM ALISTLMS.FILE_MASTER2 LFM
|
FROM ALISTLMS.FILE_MASTER2 LFM
|
||||||
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
|
||||||
WHERE LFM.DEL_YN = 'N'
|
WHERE LFM.DEL_YN = 'N'
|
||||||
AND LFM.FILE_MASTER_KEY = #{fileMasterKey}
|
AND LFM.FILE_MASTER_KEY = #{fileMasterKey}
|
||||||
AND LFM.STATUS = 1
|
AND LFM.STATUS = 1
|
||||||
@@ -141,7 +143,8 @@
|
|||||||
/*FileMapper.selectFileDetailCountByFileUuidUserToKenIdx*/
|
/*FileMapper.selectFileDetailCountByFileUuidUserToKenIdx*/
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM ALISTLMS.FILE_DETAIL LFD
|
FROM ALISTLMS.FILE_DETAIL LFD
|
||||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFD.CREATE_MEMBER
|
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||||
|
ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||||
WHERE LFD.DEL_YN = 'N'
|
WHERE LFD.DEL_YN = 'N'
|
||||||
AND LFD.FILE_UUID = #{fileUuid}
|
AND LFD.FILE_UUID = #{fileUuid}
|
||||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||||
@@ -168,12 +171,14 @@
|
|||||||
/*FileMapper.selectFileDetailCountByFileUuidAndUserToKenIdx*/
|
/*FileMapper.selectFileDetailCountByFileUuidAndUserToKenIdx*/
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM ALISTLMS.FILE_DETAIL LFD
|
FROM ALISTLMS.FILE_DETAIL LFD
|
||||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFD.CREATE_MEMBER
|
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||||
|
ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||||
WHERE LFD.DEL_YN = 'N'
|
WHERE LFD.DEL_YN = 'N'
|
||||||
AND LFD.FILE_UUID = #{fileUuid}
|
AND LFD.FILE_UUID = #{fileUuid}
|
||||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||||
AND LFD.STATUS IN (0,1,2)
|
AND LFD.STATUS IN (0,1,2)
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectUploadProgressByFileUuid" resultType="com.alist.api.common.modules.file.dto.UploadCancelDto">
|
<select id="selectUploadProgressByFileUuid" resultType="com.alist.api.common.modules.file.dto.UploadCancelDto">
|
||||||
/*FileMapper.selectUploadProgressByFileUuid*/
|
/*FileMapper.selectUploadProgressByFileUuid*/
|
||||||
SELECT LFD.FILE_UUID
|
SELECT LFD.FILE_UUID
|
||||||
@@ -187,4 +192,43 @@
|
|||||||
AND LFD.DEL_YN = 'N'
|
AND LFD.DEL_YN = 'N'
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectMoveTaskByFileUuid" resultType="com.alist.api.common.modules.file.dto.FileMoveTaskDto">
|
||||||
|
/*FileMapper.selectMoveTaskByFileUuid*/
|
||||||
|
SELECT FILE_DETAIL_IDX, FILE_MASTER_IDX, FILE_UUID, TUS_UPLOAD_ID,
|
||||||
|
ORIGIN_NAME, CONTENT_TYPE, SIZE_BYTES, UPLOADED_BYTES,
|
||||||
|
SAVE_NAME, SAVE_PATH, `EXT`, MOVE_YN, MOVE_TRY_COUNT, MOVE_LAST_ERROR
|
||||||
|
FROM ALISTLMS.FILE_DETAIL
|
||||||
|
WHERE FILE_UUID = #{fileUuid}
|
||||||
|
AND DEL_YN = 'N'
|
||||||
|
LIMIT 1
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<update id="updateFileMoveSuccess" parameterType="com.alist.api.common.modules.file.dto.FileMoveTaskDto">
|
||||||
|
/*FileMapper.updateFileMoveSuccess*/
|
||||||
|
UPDATE ALISTLMS.FILE_DETAIL
|
||||||
|
SET SAVE_NAME = #{saveName}
|
||||||
|
, SAVE_PATH = #{savePath}
|
||||||
|
, `EXT` = #{ext}
|
||||||
|
, MOVE_YN = 'Y'
|
||||||
|
, MOVE_DATE = NOW()
|
||||||
|
, MOVE_LAST_ERROR = NULL
|
||||||
|
, MOVE_LOCK_AT = NULL
|
||||||
|
, MOVE_LOCK_OWNER = NULL
|
||||||
|
, UPDATE_DATE = NOW()
|
||||||
|
WHERE FILE_DETAIL_IDX = #{fileDetailIdx}
|
||||||
|
AND DEL_YN = 'N'
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="updateFileMovePendingByFileUuid" parameterType="com.alist.api.common.modules.file.dto.FileMoveTaskDto">
|
||||||
|
/*FileMapper.updateFileMovePendingByFileUuid*/
|
||||||
|
UPDATE ALISTLMS.FILE_DETAIL
|
||||||
|
SET MOVE_YN = 'N'
|
||||||
|
, MOVE_TRY_COUNT = COALESCE(MOVE_TRY_COUNT, 0) + 1
|
||||||
|
, MOVE_LAST_ERROR = #{moveLastError}
|
||||||
|
, UPDATE_DATE = NOW()
|
||||||
|
WHERE FILE_UUID = #{fileUuid}
|
||||||
|
AND DEL_YN = 'N'
|
||||||
|
AND STATUS = 3
|
||||||
|
</update>
|
||||||
</mapper>
|
</mapper>
|
||||||
Reference in New Issue
Block a user