Skip to content

Commit

Permalink
✨ feat: add admin music recommend view (#429)
Browse files Browse the repository at this point in the history
  • Loading branch information
seonghun-dev authored Jan 22, 2024
1 parent 0b24776 commit eecc7aa
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import com.depromeet.domains.recommend.search.service.SearchRecommendService;
import com.depromeet.domains.user.dto.ResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
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;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/search-term/recommend")
Expand All @@ -24,4 +24,13 @@ public ResponseEntity<Integer> addRecommendSearchTerm(
return ResponseDto.created(response);
}

@GetMapping
public ResponseEntity<?> getRecommendSearchTerm(
@PageableDefault(size = 20, page = 0, sort = "search_recommend_term_id",
direction = Sort.Direction.DESC) Pageable pageable
) {
var response = searchRecommendService.getRecommendSearchTerm(pageable);
return ResponseDto.ok(response);
}

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

import com.depromeet.common.dto.PageMetaData;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class SearchRecommendAllResponseDto {
private List<SearchRecommendResponseDto> data;
private PageMetaData meta;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
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 SearchRecommendResponseDto {
private Long id;
private String title;
private List<TextColorDto> description;
private List<TextColorDto> terms;
private boolean active;

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package com.depromeet.domains.recommend.search.repository;

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

public interface SearchRecommendTermRepository extends JpaRepository<SearchRecommendTerm, Long> {

@Query(value = "SELECT * FROM search_recommend_term",
nativeQuery = true,
countQuery = "SELECT count(s) FROM search_recommend_term s")
Page<SearchRecommendTerm> findAll(Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package com.depromeet.domains.recommend.search.service;

import com.depromeet.common.dto.PageMetaData;
import com.depromeet.domains.recommend.search.dto.CreateSearchRecommendDto;
import com.depromeet.domains.recommend.search.dto.SearchRecommendAllResponseDto;
import com.depromeet.domains.recommend.search.dto.SearchRecommendResponseDto;
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.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
public class SearchRecommendService {
Expand All @@ -26,4 +32,35 @@ public int createSearchRecommendTerm(CreateSearchRecommendDto createSearchRecomm
var result = searchRecommendTermRepository.save(searchRecommendTerm);
return result.getId().intValue();
}

@Transactional(readOnly = true)
public SearchRecommendAllResponseDto getRecommendSearchTerm(Pageable pageable) {
var searchRecommendTerms = searchRecommendTermRepository.findAll(pageable);
PageMetaData pageMetaData = new PageMetaData(
searchRecommendTerms.getNumber(),
searchRecommendTerms.getSize(),
(int) searchRecommendTerms.getTotalElements(),
searchRecommendTerms.getTotalPages()
);

List<SearchRecommendResponseDto> searchRecommendResponseDtos = searchRecommendTerms
.stream()
.map(
s -> new SearchRecommendResponseDto(
s.getId(),
s.getTitle(),
s.getDescription().stream().map(
textColorVo -> new com.depromeet.domains.recommend.search.dto.TextColorDto(textColorVo.getText(), textColorVo.getColor())
).toList(),
s.getTerms().stream().map(
textColorVo -> new com.depromeet.domains.recommend.search.dto.TextColorDto(textColorVo.getText(), textColorVo.getColor())
).toList(),
s.isActive()
)
)
.toList();

return new SearchRecommendAllResponseDto(searchRecommendResponseDtos, pageMetaData);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {axiosAuthInstance} from "../../AxiosInstance";


const RecommendApi = {
getMusicKeywordRecommend: (page, size) => {
return axiosAuthInstance.get('/search-term/recommend', {
params: {
page: page,
size: size
}
})
}
}

export default RecommendApi;
Original file line number Diff line number Diff line change
@@ -1,11 +1,56 @@
import React, {useState} from "react"
import React, {useEffect, useState} from "react"
import {Button, Modal, Table, Tag} from 'antd';
import MusicRecommendEventCreate from "./MusicRecommendEventCreate";
import BasicLayout from "../../../../layout/BasicLayout";
import RecommendApi from "../../../../api/domain/music/RecommendApi";


function MusicRecommend() {
const [data, setData] = useState([]);
const [isModalOpen, setIsModalOpen] = useState(false);
const [tableParams, setTableParams] = useState({
pagination: {
current: 1,
pageSize: 30
},
});

useEffect(() => {
fetchData();
}, [JSON.stringify(tableParams)]);

const fetchData = async () => {
const response = await RecommendApi.getMusicKeywordRecommend(tableParams.pagination.current - 1, tableParams.pagination.pageSize);
setData(response.data['data']);
setTableParams({
...tableParams,
pagination: {
...tableParams.pagination,
total: response.data['meta']['totalElements'],
},
});
}

const descriptionRender = (text) => {
return text.map((item, index) => {
const textColor = item.color === 'RecommendTitleHighLight' ? '#1677ff' : 'black';
const textBold = item.color === 'RecommendTitleHighLight' ? 'bold' : 'normal';
return (
<span key={index} style={{color: textColor, fontWeight: textBold,}}>
{item.text}
</span>
);
});
}

const termsRender = (text) => {
return text.map((item, index) => {
const textColor = item.color === 'RecommendKeywordHighLight' ? 'blue' : 'default';
return (
<Tag key={index} bordered={false} color={textColor}>{item.text}</Tag>
);
});
}

const showModal = () => {
setIsModalOpen(true);
Expand All @@ -23,71 +68,38 @@ function MusicRecommend() {
const columns = [

{
title: '이벤트 명',
dataIndex: 'eventName',
},
{
title: '이벤트 문구',
dataIndex: 'eventText',
title: 'ID',
dataIndex: 'id',
},
{
title: '범위',
dataIndex: 'eventRange',
redner: (text) => <Tag color="gray">{text}</Tag>
title: '제목',
dataIndex: 'title',
},
{
title: '타입',
dataIndex: 'eventType',
redner: (text) => <Tag color="gray">{text}</Tag>
title: '노출되는 설명',
dataIndex: 'description',
render: (text) => descriptionRender(text)
},
{
title: '작성자',
dataIndex: 'writer',
title: '추천 검색어',
dataIndex: 'terms',
render: (text) => termsRender(text)
},
{
title: '이벤트 태그',
dataIndex: 'eventTag',
render: (text) => text.map((genre) => <Tag color="blue" key={genre}>{genre}</Tag>)
},
{
title: '상세보기',
render: () => <Button type="primary" size='small'>상세보기</Button>
}
]
title: '활성화',
dataIndex: 'active',
render: (text) => {
if (text === true) {
return <Tag color="green">활성화</Tag>
} else {
return <Tag color="red">비활성화</Tag>
}

const songs = [
{
key: '1',
eventName: '날씨 관련 이벤트',
eventText: '날씨가 청량하고 맑다면?',
writer: '성훈',
eventRange: '전체',
eventType: '기본',
eventTag: [
'Aespa',
'(여자)아이들',
'Spicy',
'벚꽃 엔딩',
'...'
]
},
{
key: '2',
eventName: '한강 이벤트 이벤트',
eventText: '지금 한강에 있다면?',
writer: '성훈',
eventRange: '그룹',
eventType: '위치',
eventTag: [
'Beautiful',
'한강',
'봄날',
'빈지노',
'...'
]
}
}
]


return (
<>
<BasicLayout>
Expand All @@ -98,7 +110,7 @@ function MusicRecommend() {
style={{marginTop: '20px', marginBottom: '10px', float: 'right'}}
onClick={showModal}>생성하기</Button>
</div>
<Table columns={columns} dataSource={songs}/>
<Table columns={columns} dataSource={data}/>

<Modal title="음악 추천 이벤트 등록" open={isModalOpen} onOk={handleOk} onCancel={handleCancel} okText='등록'
cancelText='취소'>
Expand Down

0 comments on commit eecc7aa

Please sign in to comment.