Skip to content

Commit

Permalink
♻️ feat(api): add search term recommend (#327)
Browse files Browse the repository at this point in the history
* ♻️ feat(api): add search term recommend

* ✨ feat(api) : add textcolor vo and dto

* 🐛 fix(api) : add api to text color dto

* ♻️ chore(admin): fix to var

* ♻️ chore(admin): fix to builder pattern

* ♻️ chore(admin): fix to protected
  • Loading branch information
seonghun-dev authored Oct 10, 2023
1 parent b830d26 commit 4da3c11
Show file tree
Hide file tree
Showing 15 changed files with 269 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.depromeet.domains.recommend.search.controller;

import com.depromeet.domains.recommend.search.dto.CreateSearchRecommendDto;
import com.depromeet.domains.recommend.search.service.SearchRecommendService;
import com.depromeet.domains.user.dto.ResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/search-term/recommend")
@RequiredArgsConstructor
public class SearchRecommendController {

private final SearchRecommendService searchRecommendService;
@PostMapping
public ResponseEntity<Integer> addRecommendSearchTerm(
@RequestBody CreateSearchRecommendDto createSearchRecommendDto
) {
var response = searchRecommendService.createSearchRecommendTerm(createSearchRecommendDto);
return ResponseDto.created(response);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.depromeet.domains.recommend.search.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class CreateSearchRecommendDto {
private String title;
private List<TextColorDto> description;
private List<TextColorDto> terms;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.depromeet.domains.recommend.search.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import static lombok.AccessLevel.PROTECTED;

@Getter
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public class TextColorDto {
private String text;
private String color;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.depromeet.domains.recommend.search.repository;

import com.depromeet.recommend.search.SearchRecommendTerm;
import org.springframework.data.jpa.repository.JpaRepository;

public interface SearchRecommendTermRepository extends JpaRepository<SearchRecommendTerm, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.depromeet.domains.recommend.search.service;

import com.depromeet.domains.recommend.search.dto.CreateSearchRecommendDto;
import com.depromeet.domains.recommend.search.repository.SearchRecommendTermRepository;
import com.depromeet.recommend.search.SearchRecommendTerm;
import com.depromeet.recommend.search.TextColorVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class SearchRecommendService {
private final SearchRecommendTermRepository searchRecommendTermRepository;

@Transactional
public int createSearchRecommendTerm(CreateSearchRecommendDto createSearchRecommendDto) {
var title = createSearchRecommendDto.getTitle();
var description = createSearchRecommendDto.getDescription().stream()
.map(textColorDto -> new TextColorVo(textColorDto.getText(), textColorDto.getColor()))
.toList();
var terms = createSearchRecommendDto.getTerms().stream()
.map(textColorDto -> new TextColorVo(textColorDto.getText(), textColorDto.getColor()))
.toList();
var searchRecommendTerm = SearchRecommendTerm.builder().title(title).description(description).terms(terms).build();
var result = searchRecommendTermRepository.save(searchRecommendTerm);
return result.getId().intValue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ public enum ErrorCode {

INVALID_INPUT_EXCEPTION(HttpStatus.BAD_REQUEST, "C-0015", "Nickname must be at least 1 character and not more than 10 characters"),

CAN_NOT_BLOCK_SELF(HttpStatus.BAD_REQUEST, "C-0016", "Can not block myself");
CAN_NOT_BLOCK_SELF(HttpStatus.BAD_REQUEST, "C-0016", "Can not block myself"),

SEARCH_TERM_NOT_FOUND(HttpStatus.NOT_FOUND, "C-0010", "Search Term Not Found");

private final HttpStatus status;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.depromeet.domains.recommend.controller;

import com.depromeet.common.dto.ResponseDto;
import com.depromeet.domains.recommend.dto.response.SearchTermRecommendResponseDto;
import com.depromeet.domains.recommend.service.SearchRecommendService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/search-term/recommend")
@RequiredArgsConstructor
@Tag(name = "SearchRecommend", description = "Search Recommend API")
public class SearchRecommendController {
private final SearchRecommendService searchRecommendService;

@Operation(summary = "Recommend Search Term")
@GetMapping
public ResponseEntity<SearchTermRecommendResponseDto> recommendSearchTerm() {
var response = searchRecommendService.recommendSearchTerm();
return ResponseDto.ok(response);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.depromeet.domains.recommend.dto.response;


import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.List;

@AllArgsConstructor
@Getter
public class SearchTermRecommendResponseDto {
private final List<TextColorDto> description;
private final List<TextColorDto> terms;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.depromeet.domains.recommend.dto.response;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public class TextColorDto {
String text;
String color;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.depromeet.domains.recommend.repository;

import com.depromeet.recommend.search.SearchRecommendTerm;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.Optional;

public interface SearchRecommendTermRepository extends JpaRepository<SearchRecommendTerm, Long> {
@Query(value = "SELECT s FROM SearchRecommendTerm s ORDER BY RAND() LIMIT 1")
Optional<SearchRecommendTerm> getRandomSearchRecommendTerm();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.depromeet.domains.recommend.service;

import com.depromeet.common.error.dto.ErrorCode;
import com.depromeet.common.error.exception.common.BusinessException;
import com.depromeet.domains.recommend.dto.response.SearchTermRecommendResponseDto;
import com.depromeet.domains.recommend.dto.response.TextColorDto;
import com.depromeet.domains.recommend.repository.SearchRecommendTermRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class SearchRecommendService {

private final SearchRecommendTermRepository searchRecommendTermRepository;

public SearchTermRecommendResponseDto recommendSearchTerm() {
var recommendTerm = searchRecommendTermRepository.getRandomSearchRecommendTerm()
.orElseThrow(() -> new BusinessException(ErrorCode.SEARCH_TERM_NOT_FOUND));

var description = recommendTerm.getDescription().stream()
.map((textColorVo) ->
new TextColorDto(textColorVo.getText(), textColorVo.getColor()))
.toList();

var termList = recommendTerm.getTerms().stream()
.map((textColorVo) ->
new TextColorDto(textColorVo.getText(), textColorVo.getColor()))
.toList();

return new SearchTermRecommendResponseDto(description, termList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE search_recommend_term (
search_recommend_term_id BIGINT NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
description JSON NOT NULL,
terms JSON NOT NULL,
PRIMARY KEY (search_recommend_term_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2 changes: 2 additions & 0 deletions backend/streetdrop-domain/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.hibernate:hibernate-spatial:6.2.2.Final'
implementation 'org.locationtech.jts:jts-core'
implementation 'io.hypersistence:hypersistence-utils-hibernate-60:3.5.1'
implementation 'com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations:2.15.2'

implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta"
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.depromeet.recommend.search;

import io.hypersistence.utils.hibernate.type.json.JsonType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Type;

import java.util.List;

import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;

@Getter
@NoArgsConstructor(access = PROTECTED)
@Entity
public class SearchRecommendTerm {

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "search_recommend_term_id")
private Long id;

@Column(nullable = false)
private String title;

@Column(nullable = false, columnDefinition = "json")
@Type(value = JsonType.class)
private List<TextColorVo> description;

@Column(nullable = false, columnDefinition = "json")
@Type(value = JsonType.class)
private List<TextColorVo> terms;

@Column(nullable = false)
private boolean active;

@Builder
public SearchRecommendTerm(String title, List<TextColorVo> description, List<TextColorVo> terms) {
this.title = title;
this.description = description;
this.terms = terms;
this.active = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.depromeet.recommend.search;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import static lombok.AccessLevel.PROTECTED;

@Getter
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor
public class TextColorVo {
private String text;

private String color;
}

0 comments on commit 4da3c11

Please sign in to comment.