Skip to content

Commit

Permalink
Merge pull request #102 from WooRibound/feature/#101-enterprise-jobpo…
Browse files Browse the repository at this point in the history
…sting

[update] #101 - 기업회원 공고 등록 API 수정
  • Loading branch information
2oo1s authored Nov 18, 2024
2 parents 3b01498 + 9b1fe24 commit c99de97
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.wooribound.domain.userapply.dto.ApplicantResultReqDTO;
import com.wooribound.global.util.AuthenticateUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

Expand All @@ -23,9 +24,9 @@ public class EnterpriseJobPostingController {
private final AuthenticateUtil authenticateUtil;

// 1. 공고 등록
@PostMapping("/register")
public String createJobPosting(Authentication authentication, @RequestBody JobPostingReqDTO jobPostingReqDTO) {
return enterpriseJobPostingFacade.createJobPosting(authentication, jobPostingReqDTO);
@PostMapping(value = "/register", consumes = {"multipart/form-data"})
public ResponseEntity createJobPosting(Authentication authentication, @ModelAttribute JobPostingReqDTO jobPostingReqDTO) {
return ResponseEntity.ok().body(enterpriseJobPostingFacade.createJobPosting(authentication, jobPostingReqDTO));
}

// 2. 내 기업 공고 목록 조회
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
package com.wooribound.api.corporate.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;

@Builder
@Getter
@Setter
@AllArgsConstructor
@Data
public class JobPostingReqDTO {
// private String entId;
private String postImg;
private MultipartFile postImg;
private String postTitle;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startDate;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endDate;
// TODO: Figma, 프론트 직무선택 컴포넌트 추가하기 [공고등록 화면]
private String jobName;
private Long jobId;



Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/wooribound/domain/job/JobRepository.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.wooribound.domain.job;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface JobRepository extends JpaRepository<Job,Long> {
Job findByJobName(String jobName);

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@
)
public class JobPosting {
@Id
@GeneratedValue(
strategy = GenerationType.AUTO,
generator = "job_posting_seq_generator"
)
@Column(name = "post_id")
private Long postId;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface JobPostingRepository extends JpaRepository<JobPosting, Long> {
Expand Down Expand Up @@ -91,4 +92,8 @@ List<JobPostingProjection> findJobPostingsNew(@Param("exJobs") List<String> exJo
"WHERE wh.job.jobId = :jobId " +
"ORDER BY w.jobPoint DESC")
List<WbUser> findApplicantRecommendation(@Param("jobId") int jobId);


@Query("SELECT MAX(jp.postId) FROM JobPosting jp")
Optional<Long> getMaxJobPostingId();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.wooribound.domain.jobposting.Service;

import com.amazonaws.services.s3.AmazonS3Client;
import com.wooribound.api.corporate.dto.ApplicantsDTO;
import com.wooribound.api.corporate.dto.JobPostingReqDTO;
import com.wooribound.domain.enterprise.Enterprise;
Expand All @@ -19,43 +20,60 @@
import com.wooribound.global.constant.ApplyResult;
import com.wooribound.global.constant.YN;
import com.wooribound.global.util.RedisUtil;
import com.wooribound.global.util.S3Util;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class EntJobPostingServiceImpl implements EntJobPostingService {
@Value("${aws.s3.jobPosting.folder}")
String jobPostingFolderName;

private final S3Util s3Util;

private static final Logger logger = LogManager.getLogger(EntJobPostingServiceImpl.class);
private final JobPostingRepository jobPostingRepository;
private final JobRepository jobRepository;
private final EnterpriseRepository enterpriseRepository;
private final UserApplyRepository userApplyRepository;
private final NotificationRepository notificationRepository;
private final RedisUtil redisUtil;

// 1. 공고 등록
@Override
public String createJobPosting(String entId, JobPostingReqDTO jobPostingReqDTO) {

Enterprise enterprise = enterpriseRepository.findById(entId).orElse(null);
Job job = jobRepository.findByJobName(jobPostingReqDTO.getJobName());

Optional<Job> byIdJob = jobRepository.findById(jobPostingReqDTO.getJobId());
if (byIdJob.isEmpty()) {
throw new EntityNotFoundException();
}

Long jobPostingId = 1L;
Optional<Long> maxJobPostingId = jobPostingRepository.getMaxJobPostingId();
if (maxJobPostingId.isPresent()) {
jobPostingId = maxJobPostingId.get() + 1;
}

String imageURL = s3Util.uploadFile(jobPostingReqDTO.getPostImg(), jobPostingFolderName);

JobPosting jobPosting = JobPosting.builder()
.postId(jobPostingId)
.enterprise(enterprise)
.job(job)
.job(byIdJob.get())
.postTitle(jobPostingReqDTO.getPostTitle())
.postImg(jobPostingReqDTO.getPostImg())
.postImg(imageURL)
.startDate(jobPostingReqDTO.getStartDate())
.endDate(jobPostingReqDTO.getEndDate())
.isDeleted(YN.N)
.build();

jobPostingRepository.save(jobPosting);
Expand Down Expand Up @@ -204,4 +222,5 @@ public List<ApplicantsDTO> getApplicantRecommendation(int jobId) {
}).collect(Collectors.toList());

}

}
38 changes: 9 additions & 29 deletions src/main/java/com/wooribound/domain/resume/ResumeServiceImpl.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.wooribound.domain.resume;

import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.wooribound.domain.resume.dto.ResumeDTO;
import com.wooribound.domain.resume.dto.ResumeDetailDTO;
import com.wooribound.domain.wbuser.WbUser;
Expand All @@ -11,17 +9,15 @@
import com.wooribound.domain.workhistory.WorkHistoryRepository;
import com.wooribound.global.exception.NotEntityException;
import com.wooribound.global.util.AuthenticateUtil;
import com.wooribound.global.util.S3Util;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
Expand All @@ -30,10 +26,10 @@
@Service
public class ResumeServiceImpl implements ResumeService {

@Value("${cloud.aws.s3.bucketName}")
private String bucket;
@Value("${aws.s3.wbUser.folder}")
String wbUserFolderName;

private final AmazonS3Client amazonS3Client;
private final S3Util s3Util;
private final AuthenticateUtil authenticateUtil;
private final ResumeRepository resumeRepository;
private final WbUserRepository wbUserRepository;
Expand Down Expand Up @@ -77,29 +73,22 @@ public ResumeDTO registerResume(Authentication authentication, MultipartFile use
String userId = authenticateUtil.CheckWbUserAuthAndGetUserId(authentication);

Optional<WbUser> byIdWbUser = wbUserRepository.findById(userId);

if (byIdWbUser.isEmpty()) {
throw new NotEntityException();
}

long resumeId = 1L;
Optional<Long> maxResumeId = resumeRepository.getMaxResumeId();

if (maxResumeId.isPresent()) {
resumeId = maxResumeId.get() + 1;
}

String uploadFileName = createFileName(userImg.getOriginalFilename());

ObjectMetadata metadata= new ObjectMetadata();
metadata.setContentType(userImg.getContentType());
metadata.setContentLength(userImg.getSize());
amazonS3Client.putObject(bucket,uploadFileName,userImg.getInputStream(),metadata);
String fileURL = s3Util.uploadFile(userImg, wbUserFolderName);

Resume resume = Resume.builder()
.resumeId(resumeId)
.wbUser(byIdWbUser.get())
.userImg(amazonS3Client.getUrl(bucket, uploadFileName).toString())
.userImg(fileURL)
.resumeEmail(resumeEmail)
.userIntro(userIntro)
.build();
Expand Down Expand Up @@ -135,21 +124,12 @@ public ResumeDTO updateResume(Authentication authentication, MultipartFile userI

if (userImg != null) {
// s3에서 파일 삭제
String url = byIdResume.get().getUserImg();
String encodedFileName = url.substring(url.lastIndexOf("/") + 1);
String deleteFileName = URLDecoder.decode(encodedFileName, StandardCharsets.UTF_8);

amazonS3Client.deleteObject(new DeleteObjectRequest(bucket, deleteFileName));
s3Util.deleteFile(byIdResume.get().getUserImg(), wbUserFolderName);

// s3에 새로운 파일 업로드
String uploadFileName = createFileName(userImg.getOriginalFilename());
ObjectMetadata metadata= new ObjectMetadata();
metadata.setContentType(userImg.getContentType());
metadata.setContentLength(userImg.getSize());

amazonS3Client.putObject(bucket,uploadFileName,userImg.getInputStream(),metadata);
String fileURL = s3Util.uploadFile(userImg, wbUserFolderName);

resume.setUserImg(amazonS3Client.getUrl(bucket, uploadFileName).toString());
resume.setUserImg(fileURL);
}

resume.setResumeEmail(resumeEmail);
Expand Down
69 changes: 69 additions & 0 deletions src/main/java/com/wooribound/global/util/S3Util.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.wooribound.global.util;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

@RequiredArgsConstructor
@Component
public class S3Util {

@Value("${cloud.aws.s3.bucketName}")
private String bucket;

private final AmazonS3Client amazonS3Client;

// S3에 파일 업로드
public String uploadFile(MultipartFile multipartFile, String s3FolderName) {
try {
String uploadFileName = createFileName(multipartFile.getOriginalFilename());

ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(multipartFile.getContentType());
metadata.setContentLength(multipartFile.getSize());

amazonS3Client.putObject(bucket + s3FolderName, uploadFileName, multipartFile.getInputStream(), metadata);

return amazonS3Client.getUrl(bucket + s3FolderName, uploadFileName).toString();

} catch (AmazonServiceException e) {
e.printStackTrace();
throw new RuntimeException("S3에 파일 업로드 중 오류가 발생했습니다", e);
} catch (SdkClientException e) {
e.printStackTrace();
throw new RuntimeException("클라이언트 오류가 S3에 업로드 중 발생했습니다", e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("파일 입력 중 오류가 발생했습니다", e);
}

}

public void deleteFile(String fileURL, String s3FolderName) {
try {
String encodedFileName = fileURL.substring(fileURL.lastIndexOf("/") + 1);
String deleteFileName = URLDecoder.decode(encodedFileName, StandardCharsets.UTF_8);

amazonS3Client.deleteObject(new DeleteObjectRequest(bucket + s3FolderName, deleteFileName));
} catch (AmazonServiceException e) {
e.printStackTrace();
throw new RuntimeException("S3에서 파일 삭제 중 오류가 발생했습니다", e);
}
}

// 파일 이름 생성 메소드
private String createFileName(String fileName) {
return UUID.randomUUID().toString().concat(fileName);
}
}
2 changes: 2 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ cloud.aws.credentials.secretKey=${AWS_SECRET_KEY}
cloud.aws.s3.bucketName=${AWS_BUCKET_NAME}
cloud.aws.region.static=${AWS_REGION}
cloud.aws.stack.auto-=false
aws.s3.wbUser.folder=${S3_WBUSER_FOLDER}
aws.s3.jobPosting.folder=${S3_JOB_POSTING_FOLDER}

0 comments on commit c99de97

Please sign in to comment.