[파일 업로드] tusHook 작업

- 멀티업로드 변경
This commit is contained in:
2026-03-06 16:34:13 +09:00
parent c57b80b950
commit 5311c816d2
12 changed files with 240 additions and 50 deletions
@@ -1,7 +1,9 @@
package com.alist.api.common.modules.file; package com.alist.api.common.modules.file;
import com.alist.api.common.modules.file.dto.FileUploadDto;
import com.alist.api.common.modules.file.dto.UploadStatusDto; import com.alist.api.common.modules.file.dto.UploadStatusDto;
import com.alist.api.common.modules.file.dto.UploadTokenDto; import com.alist.api.common.modules.file.dto.UploadTokenDto;
import com.alist.api.common.modules.file.form.FileUploadForm;
import com.alist.api.common.modules.file.form.TusHookForm; import com.alist.api.common.modules.file.form.TusHookForm;
import com.alist.api.common.modules.file.form.UploadStatusForm; import com.alist.api.common.modules.file.form.UploadStatusForm;
import com.alist.api.common.response.ApiResponse; import com.alist.api.common.response.ApiResponse;
@@ -18,8 +20,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Map;
@Slf4j @Slf4j
@Tag(name = "99. 파일 관리", description = "파일 관리") @Tag(name = "99. 파일 관리", description = "파일 관리")
@RestController @RestController
@@ -32,46 +32,51 @@ public class FileController {
} }
@Operation( @Operation(
summary = "파일 업로드 시작", summary = "파일 업로드 준비(db 입력 및 업로드 토큰 생성)",
description = "업로드 토큰 획득 및 업로드 정보 db 기록" description = "업로드 토큰 생성 파일 업로드 준비"
) )
@PostMapping("/uploadStart") @PostMapping("/uploadInit")
public ResponseEntity<ApiResponse<UploadStartDto>> uploadStart( public ResponseEntity<ApiResponse<FileUploadDto>> uploadInit(
@Valid @RequestBody UploadStartForm uploadStartForm @Valid @RequestBody FileUploadForm fileUploadForm
, HttpServletRequest request , HttpServletRequest request
) { ) {
FileUploadDto fileUploadDto = fileUploadForm.fileUploadDto();
HttpSession session = request.getSession(false); HttpSession session = request.getSession(false);
Integer userTokenIdx = (session == null) ? null : (Integer) session.getAttribute("userTokenIdx"); Integer userTokenIdx = (session == null) ? null : (Integer) session.getAttribute("userTokenIdx");
Integer userIdx = (session == null) ? null : (Integer) session.getAttribute("userIdx"); Integer userIdx = (session == null) ? null : (Integer) session.getAttribute("userIdx");
if (userTokenIdx == null || userIdx == null) { if (userTokenIdx == null || userIdx == null) {
return ApiResponse.entity(new UploadStartDto(), ApiResponseCode.CODE_401); return ApiResponse.entity(new FileUploadDto(), ApiResponseCode.CODE_401);
} }
UploadStartDto uploadInitDto = fileService.insertFileMasterUpload(userIdx, userTokenIdx, uploadStartForm.uploadStartDto()); fileUploadDto.setUserIdx(userIdx);
fileUploadDto.setUserTokenIdx(userTokenIdx);
return ApiResponse.entity(uploadInitDto, ApiResponseCode.CODE_200); FileUploadDto fileUploadResult = fileService.insertFileInit(fileUploadDto);
return ApiResponse.entity(fileUploadResult, ApiResponseCode.CODE_200);
} }
@Operation( @Operation(
summary = "업로드 권한 체크", summary = "업로드 권한 체크",
description = "업로드 토큰 발급 후 실제 업로드 권한이 있는지 확인 과정입니다." description = "업로드 토큰 발급 후 실제 업로드 권한이 있는지 확인 과정입니다."
) )
@GetMapping("/uploadAuthCheck") @GetMapping("/uploadAuth")
public ResponseEntity<ApiResponse<String>> uploadAuthCheck( public ResponseEntity<ApiResponse<String>> uploadAuth(
@RequestHeader(value = "Authorization", required = false) String uploadToken @RequestHeader(value = "Authorization", required = false) String uploadToken
, @RequestHeader(value = "X-File-Master-Key", required = false) String fileMasterKey , @RequestHeader(value = "x-File-Uuid", required = false) String fileUuid
) { ) {
if (uploadToken == null || !uploadToken.startsWith("Bearer ")) { if (uploadToken == null || !uploadToken.startsWith("Bearer ")) {
return ApiResponse.entity("", ApiResponseCode.CODE_401); return ApiResponse.entity("", ApiResponseCode.CODE_401);
} }
if (fileMasterKey == null || fileMasterKey.isBlank()) { if (fileUuid == null || fileUuid.isBlank()) {
return ApiResponse.entity("", ApiResponseCode.CODE_403); return ApiResponse.entity("", ApiResponseCode.CODE_403);
} }
UploadTokenDto uploadTokenDto = new UploadTokenDto(); UploadTokenDto uploadTokenDto = new UploadTokenDto();
uploadTokenDto.setUploadToken(uploadToken.substring(7).trim()); uploadTokenDto.setUploadToken(uploadToken.substring(7).trim());
uploadTokenDto.setFileMasterKey(fileMasterKey.trim()); uploadTokenDto.setFileUuid(fileUuid.trim());
UploadTokenDto uploadTokenCheck = fileService.isUploadTokenCheck(uploadTokenDto); UploadTokenDto uploadTokenCheck = fileService.isUploadTokenCheck(uploadTokenDto);
@@ -107,7 +112,7 @@ public class FileController {
log.info("[tusHookDto] type={}", tusHookForm.tusHookDto().getType()); log.info("[tusHookDto] type={}", tusHookForm.tusHookDto().getType());
log.info("[tusHookDto] uploadId={}", tusHookForm.tusHookDto().getUploadId()); log.info("[tusHookDto] uploadId={}", tusHookForm.tusHookDto().getUploadId());
log.info("[tusHookDto] size={}", tusHookForm.tusHookDto().getSize()); log.info("[tusHookDto] size={}", tusHookForm.tusHookDto().getSize());
log.info("[tusHookDto] fileMasterKey={}", tusHookForm.tusHookDto().getFileMasterKey()); log.info("[tusHookDto] fileUuid={}", tusHookForm.tusHookDto().getFileUuid());
log.info("[tusHookDto] filename={}", tusHookForm.tusHookDto().getFilename()); log.info("[tusHookDto] filename={}", tusHookForm.tusHookDto().getFilename());
log.info("[tusHookDto] filetype={}", tusHookForm.tusHookDto().getFiletype()); log.info("[tusHookDto] filetype={}", tusHookForm.tusHookDto().getFiletype());
@@ -0,0 +1,29 @@
package com.alist.api.common.modules.file.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class FileUploadDto {
private Long fileMasterIdx;
private String tusEndpoint;
@JsonIgnore
private String fileCategory;
@JsonIgnore
private String folderPath;
@JsonIgnore
private Integer userTokenIdx;
@JsonIgnore
private Integer userIdx;
@JsonIgnore
private Integer status;
@JsonIgnore
private Integer totalCount;
private List<FileUploadItemDto> itemList;
}
@@ -0,0 +1,23 @@
package com.alist.api.common.modules.file.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class FileUploadItemDto {
private Integer fileSeq;
private String fileUuid;
private String uploadToken;
private String originName;
private Long sizeBytes;
private String contentType;
@JsonIgnore
private Long fileMasterIdx;
@JsonIgnore
private Integer userIdx;
@JsonIgnore
private Integer status;
}
@@ -10,7 +10,7 @@ public class TusHookDto {
private String uploadId; private String uploadId;
private Long size; private Long size;
private Long offset; private Long offset;
private String fileMasterKey; private String fileUuid;
private String filename; private String filename;
private String filetype; private String filetype;
} }
@@ -8,7 +8,7 @@ import lombok.Setter;
@Setter @Setter
public class UploadTokenDto { public class UploadTokenDto {
private Integer userTokenIdx; private Integer userTokenIdx;
private String fileMasterKey; private String fileUuid;
private String uploadToken; private String uploadToken;
@JsonIgnore @JsonIgnore
@@ -0,0 +1,50 @@
package com.alist.api.common.modules.file.form;
import com.alist.api.common.modules.file.dto.FileUploadDto;
import com.alist.api.common.modules.file.dto.FileUploadItemDto;
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;
@Getter
@Setter
public class FileUploadForm {
@NotBlank
private String fileCategory;
private String folderPath;
@NotEmpty
@Valid
private List<FileUploadItemForm> itemList;
public FileUploadDto fileUploadDto() {
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,21 @@
package com.alist.api.common.modules.file.form;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class FileUploadItemForm {
@NotBlank
private String originName;
@NotNull
@Positive
private Long sizeBytes;
private String contentType;
}
@@ -31,7 +31,7 @@ public class TusHookForm {
tusHookDto.setOffset(upload.getOffset()); tusHookDto.setOffset(upload.getOffset());
if (upload.getMetaData() != null) { if (upload.getMetaData() != null) {
tusHookDto.setFileMasterKey(upload.getMetaData().get("fileMasterKey")); tusHookDto.setFileUuid(upload.getMetaData().get("fileUuid"));
tusHookDto.setFilename(upload.getMetaData().get("filename")); tusHookDto.setFilename(upload.getMetaData().get("filename"));
tusHookDto.setFiletype(upload.getMetaData().get("filetype")); tusHookDto.setFiletype(upload.getMetaData().get("filetype"));
} }
@@ -7,12 +7,12 @@ import lombok.Setter;
@Setter @Setter
@Getter @Getter
public class UploadTokenForm { public class UploadTokenForm {
private String fileMasterKey; private String fileUuid;
private String uploadToken; private String uploadToken;
public UploadTokenDto uploadTokenDto() { public UploadTokenDto uploadTokenDto() {
UploadTokenDto uploadTokenDto = new UploadTokenDto(); UploadTokenDto uploadTokenDto = new UploadTokenDto();
uploadTokenDto.setFileMasterKey(this.fileMasterKey); uploadTokenDto.setFileUuid(this.fileUuid);
uploadTokenDto.setUploadToken(this.uploadToken); uploadTokenDto.setUploadToken(this.uploadToken);
return uploadTokenDto; return uploadTokenDto;
@@ -1,5 +1,7 @@
package com.alist.api.common.modules.file.mapper; package com.alist.api.common.modules.file.mapper;
import com.alist.api.common.modules.file.dto.FileUploadDto;
import com.alist.api.common.modules.file.dto.FileUploadItemDto;
import com.alist.api.common.modules.file.dto.UploadStartDto; import com.alist.api.common.modules.file.dto.UploadStartDto;
import com.alist.api.common.modules.file.dto.UploadTokenDto; import com.alist.api.common.modules.file.dto.UploadTokenDto;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@@ -9,4 +11,10 @@ public interface FileMapper {
void insertFileMasterUpload(UploadStartDto uploadStartDto); void insertFileMasterUpload(UploadStartDto uploadStartDto);
int selectFileMasterCountByFileMasterKeyAndDelYnAndStatus(UploadTokenDto uploadTokenDto); int selectFileMasterCountByFileMasterKeyAndDelYnAndStatus(UploadTokenDto uploadTokenDto);
void insertFileMasterInit(FileUploadDto fileUploadDto);
void insertFileDetailInit(FileUploadItemDto item);
int selectFileDetailCountByFileUuidUserToKenIdx(UploadTokenDto uploadTokenDto);
} }
@@ -1,9 +1,6 @@
package com.alist.api.common.modules.file.service; package com.alist.api.common.modules.file.service;
import com.alist.api.common.modules.file.dto.TusHookDto; import com.alist.api.common.modules.file.dto.*;
import com.alist.api.common.modules.file.dto.UploadStartDto;
import com.alist.api.common.modules.file.dto.UploadStatusDto;
import com.alist.api.common.modules.file.dto.UploadTokenDto;
import com.alist.api.common.modules.file.mapper.FileMapper; import com.alist.api.common.modules.file.mapper.FileMapper;
import com.alist.api.config.jwt.JwtTokenProvider; import com.alist.api.config.jwt.JwtTokenProvider;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -11,6 +8,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
@@ -43,20 +41,32 @@ public class FileService {
this.stringRedisTemplate = stringRedisTemplate; this.stringRedisTemplate = stringRedisTemplate;
} }
public UploadStartDto insertFileMasterUpload(Integer userIdx, Integer userTokenIdx, UploadStartDto uploadStartDto) { /*파일 초기화 작업*/
uploadStartDto.setFileMasterKey(UUID.randomUUID().toString()); @Transactional
uploadStartDto.setUserIdx(userIdx); public FileUploadDto insertFileInit(FileUploadDto fileUploadDto) {
uploadStartDto.setStatus(1); fileUploadDto.setStatus(0);
uploadStartDto.setFolderPath(uploadStartDto.getFolderPath() == null ? "/" : uploadStartDto.getFolderPath()); fileUploadDto.setTotalCount(fileUploadDto.getItemList().size());
fileMapper.insertFileMasterUpload(uploadStartDto); fileMapper.insertFileMasterInit(fileUploadDto);
fileUploadDto.setTusEndpoint(tusEndpoint);
uploadStartDto.setUploadToken(jwtTokenProvider.createUploadToken(userTokenIdx)); if (fileUploadDto.getItemList() == null || fileUploadDto.getItemList().isEmpty()) {
uploadStartDto.setTusEndpoint(tusEndpoint); return fileUploadDto;
}
return uploadStartDto; 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
fileMapper.insertFileDetailInit(item);
}
return fileUploadDto;
} }
/*업로드 권한 체크*/
public UploadTokenDto isUploadTokenCheck(UploadTokenDto uploadTokenDto) { public UploadTokenDto isUploadTokenCheck(UploadTokenDto uploadTokenDto) {
if (!jwtTokenProvider.validateToken(uploadTokenDto.getUploadToken())) { if (!jwtTokenProvider.validateToken(uploadTokenDto.getUploadToken())) {
uploadTokenDto.setResultCode(401); uploadTokenDto.setResultCode(401);
@@ -75,7 +85,7 @@ public class FileService {
return uploadTokenDto; return uploadTokenDto;
} }
String cacheKey = buildAuthCacheKey(uploadTokenDto.getFileMasterKey(), uploadTokenDto.getUploadToken()); String cacheKey = buildAuthCacheKey(uploadTokenDto.getFileUuid(), uploadTokenDto.getUploadToken());
try { try {
String cached = stringRedisTemplate.opsForValue().get(cacheKey); String cached = stringRedisTemplate.opsForValue().get(cacheKey);
@@ -92,7 +102,7 @@ public class FileService {
log.warn("uploadAuth cache get fail. fallback DB. key={}", cacheKey, redisGetEx); log.warn("uploadAuth cache get fail. fallback DB. key={}", cacheKey, redisGetEx);
} }
int isOk = fileMapper.selectFileMasterCountByFileMasterKeyAndDelYnAndStatus(uploadTokenDto); int isOk = fileMapper.selectFileDetailCountByFileUuidUserToKenIdx(uploadTokenDto);
int resultCode = (isOk > 0) ? 200 : 403; int resultCode = (isOk > 0) ? 200 : 403;
uploadTokenDto.setResultCode(resultCode); uploadTokenDto.setResultCode(resultCode);
@@ -109,6 +119,20 @@ public class FileService {
return uploadTokenDto; return uploadTokenDto;
} }
public UploadStartDto insertFileMasterUpload(Integer userIdx, Integer userTokenIdx, UploadStartDto uploadStartDto) {
uploadStartDto.setFileMasterKey(UUID.randomUUID().toString());
uploadStartDto.setUserIdx(userIdx);
uploadStartDto.setStatus(1);
uploadStartDto.setFolderPath(uploadStartDto.getFolderPath() == null ? "/" : uploadStartDto.getFolderPath());
fileMapper.insertFileMasterUpload(uploadStartDto);
uploadStartDto.setUploadToken(jwtTokenProvider.createUploadToken(userTokenIdx));
uploadStartDto.setTusEndpoint(tusEndpoint);
return uploadStartDto;
}
public UploadStatusDto getUploadStatus(UploadStatusDto uploadStatusDto) { public UploadStatusDto getUploadStatus(UploadStatusDto uploadStatusDto) {
String key = buildUploadStatusKey(uploadStatusDto.getFileMasterKey()); String key = buildUploadStatusKey(uploadStatusDto.getFileMasterKey());
Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(key); Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(key);
@@ -129,11 +153,11 @@ public class FileService {
} }
public void saveUploadStatusFromTusHook(TusHookDto tusHookDto) { public void saveUploadStatusFromTusHook(TusHookDto tusHookDto) {
if (tusHookDto == null || tusHookDto.getFileMasterKey() == null || tusHookDto.getFileMasterKey().isBlank()) { if (tusHookDto == null || tusHookDto.getFileUuid() == null || tusHookDto.getFileUuid().isBlank()) {
return; return;
} }
String key = buildUploadStatusKey(tusHookDto.getFileMasterKey().trim()); String key = buildUploadStatusKey(tusHookDto.getFileUuid().trim());
String type = tusHookDto.getType() == null ? "" : tusHookDto.getType().trim().toLowerCase(); String type = tusHookDto.getType() == null ? "" : tusHookDto.getType().trim().toLowerCase();
long total = tusHookDto.getSize() == null ? 0L : tusHookDto.getSize(); long total = tusHookDto.getSize() == null ? 0L : tusHookDto.getSize();
long uploaded = tusHookDto.getOffset() == null ? 0L : tusHookDto.getOffset(); long uploaded = tusHookDto.getOffset() == null ? 0L : tusHookDto.getOffset();
@@ -151,7 +175,7 @@ public class FileService {
int percent = (total > 0) ? (int) Math.min(100, (uploaded * 100) / total) : 0; int percent = (total > 0) ? (int) Math.min(100, (uploaded * 100) / total) : 0;
HashOperations<String, Object, Object> ops = stringRedisTemplate.opsForHash(); HashOperations<String, Object, Object> ops = stringRedisTemplate.opsForHash();
ops.put(key, "fileMasterKey", tusHookDto.getFileMasterKey()); ops.put(key, "fileUuid", tusHookDto.getFileUuid());
ops.put(key, "status", status); ops.put(key, "status", status);
ops.put(key, "uploadedBytes", String.valueOf(uploaded)); ops.put(key, "uploadedBytes", String.valueOf(uploaded));
ops.put(key, "totalBytes", String.valueOf(total)); ops.put(key, "totalBytes", String.valueOf(total));
@@ -166,8 +190,8 @@ public class FileService {
} }
private String buildUploadStatusKey(String fileMasterKey) { private String buildUploadStatusKey(String fileUuid) {
return "upload:alist:status:" + fileMasterKey; return "upload:alist:status:" + fileUuid;
} }
private long parseLong(Object value) { private long parseLong(Object value) {
@@ -179,8 +203,8 @@ public class FileService {
} }
} }
private String buildAuthCacheKey(String fileMasterKey, String uploadToken) { private String buildAuthCacheKey(String fileUuid, String uploadToken) {
return "upload:alist:auth:" + fileMasterKey + ":" + sha256(uploadToken); return "upload:alist:auth:" + fileUuid + ":" + sha256(uploadToken);
} }
private String sha256(String value) { private String sha256(String value) {
@@ -193,15 +217,15 @@ public class FileService {
} }
} }
private void evictUploadAuthCacheByFileMasterKey(String fileMasterKey) { private void evictUploadAuthCacheByFileMasterKey(String fileUuid) {
try { try {
String pattern = "upload:alist:auth:" + fileMasterKey + ":*"; String pattern = "upload:alist:auth:" + fileUuid + ":*";
var keys = stringRedisTemplate.keys(pattern); var keys = stringRedisTemplate.keys(pattern);
if (!keys.isEmpty()) { if (!keys.isEmpty()) {
stringRedisTemplate.delete(keys); stringRedisTemplate.delete(keys);
} }
} catch (Exception e) { } catch (Exception e) {
log.warn("uploadAuth cache evict fail. fileMasterKey={}", fileMasterKey, e); log.warn("uploadAuth cache evict fail. fileUuid={}", fileUuid, e);
} }
} }
@@ -2,23 +2,53 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.alist.api.common.modules.file.mapper.FileMapper"> <mapper namespace="com.alist.api.common.modules.file.mapper.FileMapper">
<insert id="insertFileMasterInit" useGeneratedKeys="true" keyProperty="fileMasterIdx">
/*FileMapper.insertFileMasterInit*/
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 (
#{userIdx}, #{fileCategory}, #{folderPath}, #{totalCount}, 0, 0, #{status}, 'N', #{userIdx}, #{userIdx}
)
</insert>
<insert id="insertFileDetailInit">
/*FileMapper.insertFileDetailInit*/
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 (
#{fileMasterIdx}, #{fileSeq}, #{fileUuid}, #{originName}, #{contentType}, #{sizeBytes}, 0, NULL, #{status}, 'N', #{userIdx}, #{userIdx}
)
</insert>
<insert id="insertFileMasterUpload"> <insert id="insertFileMasterUpload">
/*FileMapper.insertFileMasterUpload*/ /*FileMapper.insertFileMasterUpload*/
INSERT INTO ALISTLMS.FILE_MASTER ( INSERT INTO ALISTLMS.FILE_MASTER2 (
FILE_MASTER_KEY, USER_IDX, FILE_CATEGORY, FOLDER_PATH, STATUS, CREATE_MEMBER, UPDATE_MEMBER FILE_MASTER_KEY, USER_IDX, FILE_CATEGORY, FOLDER_PATH, STATUS, CREATE_MEMBER, UPDATE_MEMBER
) values ( ) values (
#{fileMasterKey}, #{userIdx}, #{fileCategory}, #{folderPath}, #{status}, #{userIdx}, #{userIdx} #{fileMasterKey}, #{userIdx}, #{fileCategory}, #{folderPath}, #{status}, #{userIdx}, #{userIdx}
) )
</insert> </insert>
<select id="selectFileMasterCountByFileMasterKeyAndDelYnAndStatus" resultType="int"> <select id="selectFileMasterCountByFileMasterKeyAndDelYnAndStatus" resultType="int">
/*FileMapper.selectFileMasterCountByFileMasterKeyAndDelYnAndStatus*/ /*FileMapper.selectFileMasterCountByFileMasterKeyAndDelYnAndStatus*/
SELECT COUNT(*) SELECT COUNT(*)
FROM ALISTLMS.FILE_MASTER 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
AND LTUT.user_token_idx = #{userTokenIdx} AND LTUT.user_token_idx = #{userTokenIdx}
</select> </select>
<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 LFD.STATUS IN (0,1,2,3) <!-- 정책에 맞게 조정 -->
AND LTUT.user_token_idx = #{userTokenIdx}
</select>
</mapper> </mapper>