Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…nto feature/member-security-#20
  • Loading branch information
HiSeungmin committed Jan 8, 2025
2 parents 945264c + 5c9486c commit c60b7c2
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import com.seveneleven.devlens.domain.admin.service.CompanyReadService;
import com.seveneleven.devlens.domain.admin.service.CompanyUpdateService;
import com.seveneleven.devlens.global.response.APIResponse;
import com.seveneleven.devlens.global.response.SuccessCode;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

Expand All @@ -25,58 +27,68 @@ public class CompanyController {
목적 : 회사 생성하여 db에 저장
*/
@PostMapping("/new")
public APIResponse<CompanyDto.CompanyResponse> createCompany(
public ResponseEntity<APIResponse<CompanyDto.CompanyResponse>> createCompany(
@Valid @RequestBody CompanyDto.CompanyRequest companyRequest
) {
var company = companyCreateService.createCompany(companyRequest);
return APIResponse.success(company);
return ResponseEntity
.status(SuccessCode.CREATED.getStatus())
.body(APIResponse.success(SuccessCode.CREATED, company));
}

/*
함수명 : readCompany
목적 : 회사 상세 정보 조회
*/
@GetMapping("/list/{companyId}")
public APIResponse<CompanyDto.CompanyResponse> readCompany(
public ResponseEntity<APIResponse<CompanyDto.CompanyResponse>> readCompany(
@PathVariable Long companyId
) {
var company = companyReadService.getCompanyResponse(companyId);
return APIResponse.success(company);
return ResponseEntity
.status(SuccessCode.OK.getStatus())
.body(APIResponse.success(SuccessCode.OK, company));
}

/*
함수명 : readCompanyList
목적 : 회사 목록 조회
*/
@GetMapping("/list")
public APIResponse<PaginatedResponse<CompanyDto.CompanyResponse>> readCompanyList(
public ResponseEntity<APIResponse<PaginatedResponse<CompanyDto.CompanyResponse>>> readCompanyList(
@RequestParam(value = "page", required = true) Integer page
) {
PaginatedResponse<CompanyDto.CompanyResponse> response = companyReadService.getListOfCompanies(page);
return APIResponse.success(response);
return ResponseEntity
.status(SuccessCode.OK.getStatus())
.body(APIResponse.success(SuccessCode.OK, response));
}

/*
함수명 : updateCompany
목적 : 회사 상세 정보 수정
*/
@PutMapping("/list/{id}")
public APIResponse<CompanyDto.CompanyResponse> updateCompany(
public ResponseEntity<APIResponse<CompanyDto.CompanyResponse>> updateCompany(
@PathVariable Long id,
@RequestBody CompanyDto.CompanyRequest companyRequest
) {
return APIResponse.success(companyUpdateService.updateCompany(id, companyRequest));
return ResponseEntity
.status(SuccessCode.UPDATED.getStatus())
.body(APIResponse.success(SuccessCode.UPDATED, companyUpdateService.updateCompany(id, companyRequest)));
}

/*
함수명 : deleteCompany
목적 : 회사 상세 정보 삭제
*/
@DeleteMapping("/{id}")
public APIResponse<String> deleteCompany(
public ResponseEntity<APIResponse<Object>> deleteCompany(
@PathVariable Long id
) {
companyUpdateService.deleteCompany(id);
return APIResponse.success();
return ResponseEntity
.status(SuccessCode.DELETED.getStatus())
.body(APIResponse.success(SuccessCode.DELETED));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,12 @@ public void removeDepartment(Department department) {
this.departments.remove(department);
department.setCompany(null);
}

//회사 대표 이미지 여부 변환 메서드
public void addRepresentativeImage(){
this.representativeImageExists = YN.Y;
}
public void removeRepresentativeImage(){
this.representativeImageExists = YN.N;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.seveneleven.devlens.domain.project.dto.GetProjectList;
import com.seveneleven.devlens.global.response.APIResponse;
import com.seveneleven.devlens.global.response.SuccessCode;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -33,6 +34,6 @@ public APIResponse<GetProjectList.Response> getMyProject() {

GetProjectList.Response response = new GetProjectList.Response(myProjects, companyProjects);

return APIResponse.success(response);
return APIResponse.success(SuccessCode.OK, response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.seveneleven.devlens.domain.project.dto.*;
import com.seveneleven.devlens.global.entity.YesNo;
import com.seveneleven.devlens.global.response.APIResponse;
import com.seveneleven.devlens.global.response.SuccessCode;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

Expand Down Expand Up @@ -42,7 +43,7 @@ public APIResponse<GetProjectChecklist.Response> getProjectChecklist(
checklists
);

return APIResponse.success(response);
return APIResponse.success(SuccessCode.OK, response);
}

/**
Expand All @@ -61,7 +62,7 @@ public APIResponse<PostProjectChecklist.Response> postProjectChecklist(
YesNo.NO
);

return APIResponse.success(response);
return APIResponse.success(SuccessCode.CREATED, response);
}

/**
Expand All @@ -79,7 +80,7 @@ public APIResponse<PutProjectChecklist.Response> putProjectChecklist(
YesNo.YES // isChecked
);

return APIResponse.success(response);
return APIResponse.success(SuccessCode.UPDATED, response);
}

/**
Expand All @@ -95,7 +96,7 @@ public APIResponse<DeleteProjectChecklist.Response> deleteProjectChecklist(
YesNo.YES // checklistStatus
);

return APIResponse.success(response);
return APIResponse.success(SuccessCode.DELETED, response);
}

/**
Expand All @@ -118,7 +119,7 @@ public APIResponse<PostProjectChecklistApplication.Response> postProjectChecklis
YesNo.NO // hasLink
);

return APIResponse.success(response);
return APIResponse.success(SuccessCode.CREATED, response);
}

/**
Expand All @@ -137,7 +138,7 @@ public APIResponse<PostProjectChecklistAccept.Response> postProjectChecklistAcce
85.5 // checkRate (mocked as 85.5%)
);

return APIResponse.success(response);
return APIResponse.success(SuccessCode.CREATED, response);
}

/**
Expand All @@ -159,6 +160,6 @@ public APIResponse<PostProjectChecklistReject.Response> postProjectChecklistReje
YesNo.NO // hasLink (mocked as NO)
);

return APIResponse.success(response);
return APIResponse.success(SuccessCode.CREATED, response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.seveneleven.devlens.domain.project.dto.GetProjectStep;
import com.seveneleven.devlens.global.entity.YesNo;
import com.seveneleven.devlens.global.response.APIResponse;
import com.seveneleven.devlens.global.response.SuccessCode;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageImpl;
import org.springframework.web.bind.annotation.GetMapping;
Expand Down Expand Up @@ -64,7 +65,7 @@ public APIResponse<GetProjectDetail.Response> getProjectDetail(
new PageImpl<>(checklistApplications) // checklistApplicationList
);

return APIResponse.success(response);
return APIResponse.success(SuccessCode.OK, response);
}

/**
Expand Down Expand Up @@ -114,6 +115,6 @@ public APIResponse<GetProjectStep.Response> getProjectStep(
)
);

return APIResponse.success(new GetProjectStep.Response(projectId,steps));
return APIResponse.success(SuccessCode.OK, new GetProjectStep.Response(projectId,steps));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,4 @@ public static <T> APIResponse<T> fail(ErrorCode code){
public static <T> APIResponse<T> fail(ErrorCode code, String message) {
return new APIResponse<>(code.getStatusCode(), message, null);
}

//생성
public static <T> APIResponse<T> create(T data) {
return new APIResponse<>(SuccessCode.CREATED.getStatusCode(), SuccessCode.CREATED.getMessage(), data);
}

public static <T> APIResponse<T> create(int code, String message, T data) {
return new APIResponse<>(code, message, data);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.seveneleven.devlens.global.util.file.Service;

import com.seveneleven.devlens.domain.admin.db.CompanyRepository;
import com.seveneleven.devlens.domain.member.entity.Company;
import com.seveneleven.devlens.global.exception.BusinessException;
import com.seveneleven.devlens.global.response.APIResponse;
import com.seveneleven.devlens.global.response.ErrorCode;
import com.seveneleven.devlens.global.util.file.dto.FileMetadataDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

@Service
@RequiredArgsConstructor
public class CompanyFileService {
private final FileService fileService;
private final CompanyRepository companyRepository;

/**
* 1. 회사 로고 이미지 등록
* @auth admin, super(해당 회사 대표회원)
* @param file 업로드할 로고 이미지 파일
* @param companyId 해당 회사 id
* @param uploaderId 업로드 수행자 id
* @return APIResponse S3에 저장된 파일의 메타데이터 response
*/

@Transactional
public APIResponse uploadLogoImage(MultipartFile file, Long companyId, Long uploaderId) throws Exception{
//1. 회사 id로 존재여부 판별
Company companyEntity = companyRepository.findById(companyId)
.orElseThrow(() -> new BusinessException(ErrorCode.COMPANY_IS_NOT_FOUND));

//TODO) 2. 수행자 권한 판별 validation - admin판별, super의 회사 판별

//3. S3파일 업로드, 메타데이터 테이블 저장
APIResponse uploadResponse = fileService.uploadFile(file, "COMPANY_LOGO_IMAGE", companyId);

//4. 회사 대표 이미지 유무 칸을 Y로 변경한다.
companyEntity.addRepresentativeImage();
companyRepository.save(companyEntity);

//5. 반환
return uploadResponse;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@ public class FileService {
/**
* 1. 파일 업로드
* @param file 업로드할 파일
* @param uploaderId 업로더 id
* @param fileCategory 파일 카테고리
* @param referenceId 파일 참조 ID
* @return FileMetadataDto 업로드한 파일 메타데이터
*/
@Transactional
public APIResponse uploadFile(MultipartFile file, Long uploaderId, String fileCategory, Long referenceId) throws Exception {
public APIResponse uploadFile(MultipartFile file, String fileCategory, Long referenceId) throws Exception {

//1. 파일 검증
FileValidator.validateFile(file, fileCategory);
Expand All @@ -43,7 +42,7 @@ public APIResponse uploadFile(MultipartFile file, Long uploaderId, String fileCa
//UUID 생성
String uniqueFileName = s3ClientService.generateUniqueFileName(originalFilename);
//S3 키 생성
String s3Key = s3ClientService.generateS3Key(uploaderId, fileCategory, uniqueFileName);
String s3Key = s3ClientService.generateS3Key(fileCategory, referenceId, uniqueFileName);

//3. S3 업로드 및 FileMetadata 데이터 생성
String filePath = null;
Expand All @@ -64,12 +63,11 @@ public APIResponse uploadFile(MultipartFile file, Long uploaderId, String fileCa
FileMetadata savedMetadata = fileMetadataRepository.save(fileMetadata);

//DTO로 변환 후 반환
return APIResponse.create(FileMetadataDto.toDto(savedMetadata));
return APIResponse.success(FileMetadataDto.toDto(savedMetadata));

} catch (Exception e){
//저장 실패시 S3에서 삭제
s3ClientService.deleteFile(s3Key);

throw new BusinessException(e.getMessage(), ErrorCode.FILE_UPLOAD_FAIL_ERROR);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ public String generateUniqueFileName(String originalFileName) {

/**
* S3 키 생성
* 키 = S3 저장시 파일 경로
* 키 = S3 저장시 파일 경로 (파일카테고리/참조ID/uuid파일명)
*
*/
public String generateS3Key(Long uploaderId, String category, String fileName) {
public String generateS3Key(String category, Long referenceId, String fileName) {
return new StringBuilder()
.append(uploaderId)
.append("/")
.append(category)
.append("/")
.append(referenceId)
.append("/")
.append(fileName)
.toString();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.seveneleven.devlens.global.util.file.controller;

import com.seveneleven.devlens.global.response.APIResponse;
import com.seveneleven.devlens.global.util.file.Service.CompanyFileService;
import com.seveneleven.devlens.global.util.file.Service.FileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
Expand All @@ -14,29 +15,35 @@
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping("/api/files")
@RequestMapping("/api/company/files")
@RequiredArgsConstructor
public class FileController {
private final FileService fileService;
public class CompanyFileController {
private final CompanyFileService companyFileService;

/**
* 1. 파일 업로드
* @param file 업로드할 파일
* 1. 회사 로고 이미지 업로드
* @param file 업로드할 이미지 파일
* @return 업로드된 파일 메타데이터, 성공 메시지
*/
@PostMapping(value = "/upload", consumes = "multipart/form-data")
@PostMapping(value = "", consumes = "multipart/form-data")
@Operation(
summary = "Upload a file",
description = "Upload a file to the server",
description = "Upload a image for company logo",
responses = {
@ApiResponse(responseCode = "200", description = "File uploaded successfully"),
@ApiResponse(responseCode = "400", description = "Invalid file upload request")
}
)
public ResponseEntity<Object> uploadFile(@RequestParam("file")
@Schema(type = "string", format = "binary", description = "File to upload") MultipartFile file) throws Exception {
APIResponse uploadResponse = fileService.uploadFile(file, 1L, "POST_ATTACHMENT", 1L);
@Schema(type = "string", format = "binary", description = "File to upload") MultipartFile file,
@RequestParam("company")
@Schema(type = "Long", description = "Company to upload") Long companyId) throws Exception {
//TODO) 토큰에서 uploader 정보 가져오기
Long uploaderId = 1L;

return ResponseEntity.status(uploadResponse.getCode()).body(uploadResponse.getData());
APIResponse uploadResponse = companyFileService.uploadLogoImage(file, companyId, uploaderId);

return ResponseEntity.status(uploadResponse.getCode()).body(uploadResponse);
}

}
Loading

0 comments on commit c60b7c2

Please sign in to comment.