Skip to content

Commit

Permalink
Merge pull request #1 from potenday-project/develop
Browse files Browse the repository at this point in the history
develop -> master merge
  • Loading branch information
HwangHoYoon authored Dec 10, 2023
2 parents b866d8b + db8ec43 commit 9f2df59
Show file tree
Hide file tree
Showing 25 changed files with 632 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ jobs:
docker rm -f be-con || true
docker rmi $(docker images -f "dangling=true" -q) || true
docker pull ${{ secrets.DOCKER_REPO }}/chwipoclovadocker:latest
docker run -v /var/log/service:/var/log/service --name be-con -p 8080:8080 -d ${{ secrets.DOCKER_REPO }}/chwipoclovadocker:latest
docker run -v /var/log/service:/var/log/service -v /var/upload:/var/upload --name be-con -p 8080:8080 -d ${{ secrets.DOCKER_REPO }}/chwipoclovadocker:latest
6 changes: 4 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@ dependencies {
implementation group: 'com.nimbusds', name: 'nimbus-jose-jwt', version: '3.10'

//spring-doc
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.3.0'
implementation group: 'commons-codec', name: 'commons-codec', version: '1.15' // 또는 최신 버전


// fileupload
implementation group: 'commons-io', name: 'commons-io', version: '2.15.1'
implementation group: 'commons-fileupload', name: 'commons-fileupload', version: '1.5'

}

Expand Down
63 changes: 63 additions & 0 deletions src/main/generated/com/chwipoClova/resume/entity/QResume.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.chwipoClova.resume.entity;

import static com.querydsl.core.types.PathMetadataFactory.*;

import com.querydsl.core.types.dsl.*;

import com.querydsl.core.types.PathMetadata;
import javax.annotation.processing.Generated;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.dsl.PathInits;


/**
* QResume is a Querydsl query type for Resume
*/
@Generated("com.querydsl.codegen.DefaultEntitySerializer")
public class QResume extends EntityPathBase<Resume> {

private static final long serialVersionUID = -1144291881L;

private static final PathInits INITS = PathInits.DIRECT2;

public static final QResume resume = new QResume("resume");

public final StringPath fileName = createString("fileName");

public final StringPath filePath = createString("filePath");

public final NumberPath<Long> fileSize = createNumber("fileSize", Long.class);

public final StringPath orginalFileName = createString("orginalFileName");

public final DateTimePath<java.util.Date> regDate = createDateTime("regDate", java.util.Date.class);

public final NumberPath<Long> resumeId = createNumber("resumeId", Long.class);

public final StringPath summary = createString("summary");

public final com.chwipoClova.user.entity.QUser user;

public QResume(String variable) {
this(Resume.class, forVariable(variable), INITS);
}

public QResume(Path<? extends Resume> path) {
this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS));
}

public QResume(PathMetadata metadata) {
this(metadata, PathInits.getFor(metadata, INITS));
}

public QResume(PathMetadata metadata, PathInits inits) {
this(Resume.class, metadata, inits);
}

public QResume(Class<? extends Resume> type, PathMetadata metadata, PathInits inits) {
super(type, metadata, inits);
this.user = inits.isInitialized("user") ? new com.chwipoClova.user.entity.QUser(forProperty("user")) : null;
}

}

6 changes: 6 additions & 0 deletions src/main/java/com/chwipoClova/ChwipoClovaApplication.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.chwipoClova;

import jakarta.servlet.MultipartConfigElement;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class ChwipoClovaApplication {
Expand All @@ -10,4 +12,8 @@ public static void main(String[] args) {
SpringApplication.run(ChwipoClovaApplication.class, args);
}

@Bean
public MultipartConfigElement multipartConfigElement() {
return new MultipartConfigElement("");
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.chwipoClova.common.config;

import com.chwipoClova.common.exception.ExceptionCode;
import com.chwipoClova.common.response.CommonMsgResponse;
import com.chwipoClova.common.response.CommonResponse;
import com.chwipoClova.common.response.MessageCode;
import io.swagger.v3.core.converter.ModelConverters;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.Content;
Expand Down Expand Up @@ -49,8 +51,14 @@ private Schema<?> customizeSchema(String code, Schema<?> objSchema) {
responseMessage = HttpStatus.OK.getReasonPhrase();
} else {
ExceptionCode exceptionCode = ExceptionCode.resolve(code);
responseCode = exceptionCode.getCode();
responseMessage = exceptionCode.getMessage();
if (exceptionCode != null) {
responseCode = exceptionCode.getCode();
responseMessage = exceptionCode.getMessage();
} else {
MessageCode messageCode = MessageCode.resolve(code);
responseCode = messageCode.getCode();
responseMessage = messageCode.getMessage();
}
}
wrapperSchema.addProperties("data", objSchema);
wrapperSchema.addProperty("code", new StringSchema()._default(responseCode));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ public RestTemplate restTemplate() {
return new RestTemplate();
}


}
10 changes: 10 additions & 0 deletions src/main/java/com/chwipoClova/common/config/SwaggerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;

@Configuration
public class SwaggerConfig {
Expand Down Expand Up @@ -43,4 +48,9 @@ private Info apiInfo() {
.description("Springdoc을 사용한 Swagger UI")
.version("1.0.0");
}

@Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,20 @@ public enum ExceptionCode {

SERVER_ERROR(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()), "내부 서버 오류입니다."),



// Custom Exception
SECURITY("600", "로그인이 필요합니다");
SECURITY("800", "로그인이 필요합니다"),

USER_NULL("801", "유저 정보가 올바르지 않습니다."),

FILE_EXT("850", "PDF 파일 형식이 아닙니다."),

FILE_SIZE("851", "파일 업로드 최대 크기는 50M 입니다."),

RESUME_NULL("860", "이력서 정보가 올바르지 않습니다.")

;

private static final ExceptionCode[] VALUES;

Expand Down
24 changes: 23 additions & 1 deletion src/main/java/com/chwipoClova/common/filter/RequestFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import org.springframework.web.util.WebUtils;
Expand All @@ -20,11 +24,29 @@
@Component
public class RequestFilter implements Filter {

@Autowired
private MultipartResolver multipartResolver;


@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {


//chain.doFilter(request, response);
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper((HttpServletRequest) request);

if (multipartResolver.isMultipart((HttpServletRequest) request)) {
// 멀티파트 요청으로부터 MultipartHttpServletRequest 획득
MultipartHttpServletRequest multipartRequest = multipartResolver.resolveMultipart((HttpServletRequest) request);

Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entry : fileMap.entrySet()) {
MultipartFile file = entry.getValue();
// 파일 데이터를 다시 설정
byte[] fileBytes = file.getBytes(); // 파일 데이터 읽기
requestWrapper.setAttribute(entry.getKey(), fileBytes); // 새로운 요청(wrapper)에 파일 데이터 설정
}
}

ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) response);
CustomRequestWrapper customRequestWrapper = new CustomRequestWrapper(requestWrapper);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,74 @@
package com.chwipoClova.resume.controller;

import com.chwipoClova.common.response.CommonResponse;
import com.chwipoClova.resume.request.ResumeDeleteOldReq;
import com.chwipoClova.resume.request.ResumeDeleteReq;
import com.chwipoClova.resume.response.ResumeListRes;
import com.chwipoClova.resume.response.ResumeUploadRes;
import com.chwipoClova.resume.service.ResumeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.service.annotation.DeleteExchange;

import java.util.List;

@Slf4j
@RestController
@RequiredArgsConstructor
@Tag(name = "Resume", description = "이력서 API")
@RequestMapping("resume")
public class ResumeController {

private final ResumeService resumeService;

@Operation(summary = "이력서 업로드", description = "이력서 업로드")
@PostMapping(path = "/resumeUpload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK")
}
)
public ResumeUploadRes resumeUpload(
@Schema(description = "userId", example = "1", name = "userId")
@RequestParam(value = "userId") Long userId,
@RequestPart(value = "file") MultipartFile file
) throws Exception {
return resumeService.resumeUpload(userId, file);
}

@Operation(summary = "이력서 조회", description = "이력서 조회")
@GetMapping(path = "/getResumeList")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK")
}
)
public List<ResumeListRes> getResumeList(@Schema(description = "userId", example = "1", name = "userId") @RequestParam(name = "userId") Long userId) {
return resumeService.selectResumeList(userId);
}

@Operation(summary = "이력서 삭제", description = "이력서 삭제")
@DeleteMapping(path = "/deleteResume")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class)))}
)
public CommonResponse deleteResume(@RequestBody ResumeDeleteReq resumeDeleteReq) {
return resumeService.deleteResume(resumeDeleteReq);
}


@Operation(summary = "오래된 이력서 삭제", description = "오래된 이력서 삭제")
@DeleteMapping(path = "/deleteOldResume")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class)))}
)
public CommonResponse deleteOldResume(@RequestBody ResumeDeleteOldReq resumeDeleteOldReq) {
return resumeService.deleteOldResume(resumeDeleteOldReq);
}

}
65 changes: 65 additions & 0 deletions src/main/java/com/chwipoClova/resume/entity/Resume.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.chwipoClova.resume.entity;

import com.chwipoClova.user.entity.User;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.DynamicInsert;

import java.util.Date;

@Entity(name = "Resume")
@Table(name = "Resume")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties()
@DynamicInsert
@Builder
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "이력서 정보 VO")
public class Resume {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "resumeId")
@Schema(description = "이력서ID")
private Long resumeId;

@Column(name = "fileName")
@Schema(description = "파일이름")
private String fileName;

@Column(name = "filePath")
@Schema(description = "파일경로")
private String filePath;

@Column(name = "fileSize")
@Schema(description = "파일크기")
private Long fileSize;

@Column(name = "orginalFileName")
@Schema(description = "원본파일이름")
private String orginalFileName;

@Column(name = "summary")
@Schema(description = "요약")
private String summary;

@Column(name = "regDate")
@Schema(description = "등록일")
private Date regDate;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "userId")
private User user;

// @PrePersist 메서드 정의 (최초 등록시 호출)
@PrePersist
public void prePersist() {
this.regDate = new Date(); // 현재 날짜와 시간으로 등록일 설정
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.chwipoClova.resume.repository;

import com.chwipoClova.resume.entity.Resume;
import org.springframework.data.jpa.repository.JpaRepository;

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

public interface ResumeRepository extends JpaRepository<Resume, Long> {

List<Resume> findByUserUserIdOrderByRegDate(Long userId);

Optional<Resume> findByUserUserIdAndResumeId(Long userId, Long resumeId);

Optional<Resume> findTop1ByUserUserIdOrderByRegDate(Long userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.chwipoClova.resume.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

@Data
public class ResumeDeleteOldReq {

@Schema(description = "유저 ID", example = "1", name = "userId")
private Long userId;
}
Loading

0 comments on commit 9f2df59

Please sign in to comment.