Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into be/fix/#259
Browse files Browse the repository at this point in the history
  • Loading branch information
YunJuwon0825 committed Feb 23, 2025
2 parents 3f3772c + fc7bcc0 commit 4f239c5
Show file tree
Hide file tree
Showing 16 changed files with 275 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public CommonResponse<List<PageableResumeResponse>> searchResumes(@RequestParam(
@RequestParam(name = "size") int size) {
//ResumeService를 통해 페이지네이션된 이력서 목록을 가져옵니다.
final Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Order.desc("createdAt")));
Page<Resume> resumes = resumeService.getResumePage(pageable);
Slice<Resume> resumes = resumeService.getResumePage(pageable);

List<PageableResumeResponse> resumeResponses = resumes.stream()
.map(ResumeConverter::toPageableResumeResponse)
Expand Down Expand Up @@ -151,4 +151,18 @@ public CommonResponse<?> deleteResume(@PathVariable("resume_id") Long resumeId)
resumeService.softDeleteResume(user, resumeId);
return CommonResponse.of(SuccessCode.RESUME_SOFT_DELETED, null);
}

@Operation(summary = "이력서 조회순으로 조회")
@GetMapping("/resumes/view")
public CommonResponse<List<PageableResumeResponse>> searchResumesByView(@RequestParam(name = "page") int page,
@RequestParam(name = "size") int size) {
final Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Order.desc("viewCount")));
Slice<Resume> resumeList = resumeService.getResumePage(pageable);

List<PageableResumeResponse> pageableResumeResponse = resumeList.stream()
.map(ResumeConverter::toPageableResumeResponse)
.collect(Collectors.toList());

return CommonResponse.of(SuccessCode.OK, pageableResumeResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public static PageableResumeResponse toPageableResumeResponse(Resume resume) {
.resumeId(resume.getId())
.resumeName(resume.getName())
.userName(resume.getUser().getUsername())
.viewCount(resume.getViewCount())
.resumeName(resume.getName())
.position(resume.getPosition().getValue())
.career(resume.getCareer())
Expand Down Expand Up @@ -54,6 +55,7 @@ public static ResumeDetailResponse toResumeDetailResponse(Resume resume, List<Fe
public static ResumeResponse toResumeResponse(Resume resume) {
return ResumeResponse.builder()
.resumeId(resume.getId())
.viewCount(resume.getViewCount())
.resumeName(resume.getName())
.userName(resume.getUser().getUsername())
.resumeName(resume.getName())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -58,6 +59,10 @@ public class Resume extends BaseEntity {
// 이후 버전(더 최신 버전)
private Long laterResumeId;

// 조회수
@Column(name = "view_count")
private Long viewCount;

@Builder.Default
@OneToMany(mappedBy = "resume", cascade = CascadeType.ALL)
private List<ResumeTechStack> resumeTechStacks = new ArrayList<>();
Expand All @@ -77,6 +82,14 @@ public Resume(User user, String name, int career, Position position, ResumePdf r
this.career = career;
this.position = position;
this.resumePdf = resumePdf;
this.viewCount = 0L;
}

@PrePersist
public void prePersist() {
if (this.viewCount == null) {
this.viewCount = 0L;
}
}

public void addResumeTechStack(ResumeTechStack resumeTechStack) {
Expand All @@ -94,4 +107,8 @@ public void addResumePdf(ResumePdf resumePdf) {
public void updateLaterResumeId(Long id) {
this.laterResumeId = id;
}

public void increaseViewCount() {
this.viewCount++;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class ResumePdf {

@Embedded
@AttributeOverrides({
@AttributeOverride(name = "pdfUrl", column = @Column(name = "resume_pdf_url")),
@AttributeOverride(name = "pdfUrl", column = @Column(name = "resume_pdf_url", length = 1000)),
@AttributeOverride(name = "pdfName", column = @Column(name = "resume_pdf_name")),
@AttributeOverride(name = "pdfUUID", column = @Column(name = "resume_pdf_uuid"))
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ public class PageableResumeResponse {
private List<String> companyNames;
private int totalPage;
private int currentPage;
private Long viewCount;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ public class ResumeResponse {
private final String position;
private final List<String> techStackNames;
private List<String> companyNames;
private Long viewCount;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.techeer.backend.api.user.domain.User;
import java.util.List;
import java.util.Optional;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -24,4 +25,6 @@ public interface ResumeRepository extends JpaRepository<Resume, Long>, ResumeRep
Resume findFirstByUserOrderByCreatedAtDesc(User user);

Slice<Resume> findResumeByUser(User user);

Slice<Resume> findResumesByDeletedAtIsNull(Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import com.techeer.backend.api.resume.exception.ResumeNotFoundException;
import com.techeer.backend.api.resume.repository.ResumeRepository;
import com.techeer.backend.api.user.domain.User;
import com.techeer.backend.global.error.ErrorCode;
import com.techeer.backend.global.error.exception.BusinessException;
import java.util.List;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,6 +13,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


@Service
Expand All @@ -29,9 +28,14 @@ public Resume saveResume(Resume resume) {
}

// 이력서 개별 조회
@Transactional
public Resume getResume(Long resumeId) {
return resumeRepository.findById(resumeId)
Resume resume = resumeRepository.findById(resumeId)
.orElseThrow(ResumeNotFoundException::new);

// 이력서 조회수 증가
resume.increaseViewCount();
return resume;
}

// 유저 이름으로 이력서 조회
Expand All @@ -45,18 +49,9 @@ public Page<Resume> searchByTages(ResumeSearchRequest req, Pageable pageable) {
}


public Page<Resume> getResumePage(Pageable pageable) {
public Slice<Resume> getResumePage(Pageable pageable) {
// 페이지네이션을 적용하여 레포지토리에서 데이터를 가져옴
Page<Resume> resumes = resumeRepository.findAll(pageable);

// 첫 번째 Resume 객체를 가져옴 (예시로 첫 번째 요소를 변환)
Resume resume = resumes.getContent().isEmpty() ? null : resumes.getContent().get(0);

// Resume가 없을 경우 빈 결과를 처리
if (resume == null) {
throw new BusinessException(ErrorCode.RESUME_NOT_FOUND);
}

Slice<Resume> resumes = resumeRepository.findResumesByDeletedAtIsNull(pageable);
return resumes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,17 @@
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.core.StringRedisTemplate;

@Configuration
public class RedisConfig {
@Value("${REDIS_PORT}")
@Value("${spring.data.redis.port}")
private int redisPort;

@Value("${REDIS_HOST}")
@Value("${spring.data.redis.host}")
private String redisHost;

@Value("${REDIS_PASSWORD}")
@Value("${spring.data.redis.password}")
private String redisPassword;

@Bean
Expand All @@ -30,17 +29,7 @@ public RedisConnectionFactory redisConnectionFactory() {
}

@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, String> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);

// 키와 값의 직렬화 방식 설정
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new StringRedisSerializer());

template.afterPropertiesSet();
return template;
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.techeer.backend.global.redis;

import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
public class RedisConnectionChecker {

private final RedisConnectionFactory redisConnectionFactory;

@PostConstruct
public void checkRedisConnection() {
try {
redisConnectionFactory.getConnection().ping();
log.info("✅ Redis 연결 성공!");
} catch (Exception e) {
log.error("❌ Redis 연결 실패!", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

@Service
Expand All @@ -17,22 +17,21 @@ public class RedisService {
@Value("${jwt.refresh.expiration}")
private Long refreshTokenExpirationPeriod;

private final RedisTemplate<String, String> redisTemplate;
private final StringRedisTemplate stringRedisTemplate;

public String refreshTokenGet(String refreshToken) {
return redisTemplate.opsForValue().get("refreshToken:"+refreshToken);
return stringRedisTemplate.opsForValue().get("refreshToken:" + refreshToken);
}

public void cacheRefreshToken(String refreshToken) {
String key = "refreshToken:" + refreshToken;
log.info("refresh token cache key: {}", key);
// 리프레시 토큰을 Redis에 저장 (예: 7일 만료)
redisTemplate.opsForValue().set(key, refreshToken, Duration.ofMillis(refreshTokenExpirationPeriod));
stringRedisTemplate.opsForValue().set(key, refreshToken, Duration.ofMillis(refreshTokenExpirationPeriod));
}

public void deleteCacheRefreshToken(String refreshToken) {
String key = "refreshToken:" + refreshToken;
log.info("refresh token cache key: {}", key);
redisTemplate.delete(key);
stringRedisTemplate.delete(key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public String uploadPdf(MultipartFile multipartFile) {
String s3PdfName = UUID.randomUUID().toString().substring(0, 10) + "_" + originalFileName;
String s3Key = "resume/" + s3PdfName;
String fileUrl = uploadToS3(multipartFile, s3Key);
log.info("resume_pdf_url length: {}", fileUrl.length());
return fileUrl;
}

Expand Down
5 changes: 5 additions & 0 deletions backend/src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
spring:
servlet:
multipart:
max-file-size: 100MB
max-request-size: 200MB

application:
name: backend

Expand Down
Loading

0 comments on commit 4f239c5

Please sign in to comment.