Skip to content

Commit 9d5d475

Browse files
authored
Merge pull request #271 from DevKor-github/fix/vote
장소에 콘센트 투표 저장 추가
2 parents 2b7cda6 + 15c2db0 commit 9d5d475

9 files changed

Lines changed: 131 additions & 14 deletions

File tree

src/main/java/devkor/com/teamcback/domain/course/scheduler/CourseScheduler.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@
1010
import devkor.com.teamcback.global.redis.RedisLockUtil;
1111
import lombok.RequiredArgsConstructor;
1212
import lombok.extern.slf4j.Slf4j;
13-
import org.springframework.boot.context.event.ApplicationReadyEvent;
14-
import org.springframework.context.event.EventListener;
1513
import org.springframework.stereotype.Component;
16-
import org.springframework.transaction.annotation.Transactional;
1714

1815
import java.util.List;
1916

@@ -29,11 +26,11 @@ public class CourseScheduler {
2926
//@EventListener(ApplicationReadyEvent.class)
3027
//@Transactional
3128
public void updateCourseDetails() {
32-
redisLockUtil.executeWithLock("course_lock", 1, 300, () -> {
29+
redisLockUtil.executeWithLock("course_lock", 1, 5000, () -> {
3330

3431
log.info("강의 장소 업데이트");
3532

36-
List<CourseDetail> courseDetails = courseDetailRepository.findLimitByPlaceIdIsNull(500);
33+
List<CourseDetail> courseDetails = courseDetailRepository.findLimitByPlaceIdIsNull(1000);
3734

3835
for (CourseDetail courseDetail : courseDetails) {
3936
String placeName = courseDetail.getPlaceName();

src/main/java/devkor/com/teamcback/domain/place/service/AdminPlaceService.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
import devkor.com.teamcback.domain.place.repository.PlaceRepository;
1111
import devkor.com.teamcback.domain.routes.entity.Node;
1212
import devkor.com.teamcback.domain.routes.repository.NodeRepository;
13+
import devkor.com.teamcback.domain.vote.entity.Vote;
14+
import devkor.com.teamcback.domain.vote.entity.VoteStatus;
15+
import devkor.com.teamcback.domain.vote.repository.VoteRepository;
1316
import devkor.com.teamcback.global.exception.exception.GlobalException;
1417
import lombok.RequiredArgsConstructor;
1518
import org.springframework.stereotype.Service;
@@ -27,6 +30,7 @@ public class AdminPlaceService {
2730
private final PlaceRepository placeRepository;
2831
private final NodeRepository nodeRepository;
2932
private final FileUtil fileUtil;
33+
private final VoteRepository voteRepository;
3034

3135
// 건물 id와 층에 해당하는 장소 리스트 조회
3236
@Transactional(readOnly = true)
@@ -55,6 +59,10 @@ public CreatePlaceRes createPlace(CreatePlaceReq req) {
5559
Building building = findBuilding(req.getBuildingId());
5660
Node node = findNode(req.getNodeId());
5761
Place place = placeRepository.save(new Place(req, building, node));
62+
63+
// vote 추가
64+
voteRepository.save(new Vote(1L, place.getId(), VoteStatus.OPEN));
65+
5866
return new CreatePlaceRes(place);
5967
}
6068

@@ -72,6 +80,10 @@ public ModifyPlaceRes modifyPlace(Long placeId, ModifyPlaceReq req) {
7280
@Transactional
7381
public DeletePlaceRes deletePlace(Long facilityId) {
7482
Place place = findPlace(facilityId);
83+
84+
// 투표 삭제
85+
voteRepository.deleteByPlaceId(place.getId());
86+
7587
placeRepository.delete(place);
7688

7789
return new DeletePlaceRes();

src/main/java/devkor/com/teamcback/domain/vote/controller/AdminVoteController.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package devkor.com.teamcback.domain.vote.controller;
22

33
import devkor.com.teamcback.domain.vote.dto.response.ChangeVoteStatusRes;
4+
import devkor.com.teamcback.domain.vote.dto.response.CreatePlaceVoteRes;
45
import devkor.com.teamcback.domain.vote.dto.response.GetVoteRes;
56
import devkor.com.teamcback.domain.vote.entity.VoteStatus;
67
import devkor.com.teamcback.domain.vote.service.VoteService;
@@ -15,6 +16,8 @@
1516
import lombok.RequiredArgsConstructor;
1617
import org.springframework.web.bind.annotation.*;
1718

19+
import java.util.List;
20+
1821
@RestController
1922
@RequiredArgsConstructor
2023
@RequestMapping("/api/admin/votes")
@@ -59,4 +62,38 @@ public CommonResponse<CursorPageRes<GetVoteRes>> getVoteList(
5962
) {
6063
return CommonResponse.success(voteService.getVoteList(status, lastVoteId, size));
6164
}
65+
66+
/**
67+
* 득표 수 많은 투표 조회
68+
*/
69+
@Operation(summary = "득표 수 많은 투표 조회", description = "득표 수 20 이상인 투표 조회")
70+
@ApiResponses(value = {
71+
@ApiResponse(responseCode = "200", description = "정상 처리 되었습니다."),
72+
@ApiResponse(responseCode = "404", description = "Not Found",
73+
content = @Content(schema = @Schema(implementation = CommonResponse.class))),
74+
})
75+
@GetMapping("/major")
76+
public CommonResponse<List<GetVoteRes>> getMajorVoteList(
77+
@Parameter(description = "투표 상태", example = "REFLECTED")
78+
@RequestParam(name = "status", required = false) VoteStatus status
79+
) {
80+
return CommonResponse.success(voteService.getMajorVoteList(status));
81+
}
82+
83+
/**
84+
* 장소에 투표 생성(일괄)
85+
*/
86+
@Operation(summary = "장소에 투표 생성(일괄)", description = "생성 원하는 투표 주제 id 입력")
87+
@ApiResponses(value = {
88+
@ApiResponse(responseCode = "200", description = "정상 처리 되었습니다."),
89+
@ApiResponse(responseCode = "404", description = "Not Found",
90+
content = @Content(schema = @Schema(implementation = CommonResponse.class))),
91+
})
92+
@PostMapping("/topics/{voteTopicId}")
93+
public CommonResponse<CreatePlaceVoteRes> createPlaceVote(
94+
@Parameter(description = "투표 주제 ID", example = "1")
95+
@PathVariable(name = "voteTopicId") Long voteTopicId) {
96+
return CommonResponse.success(voteService.createPlaceVote(voteTopicId));
97+
}
98+
6299
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package devkor.com.teamcback.domain.vote.dto.response;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import io.swagger.v3.oas.annotations.media.Schema;
5+
6+
@Schema(description = "투표 생성 완료")
7+
@JsonIgnoreProperties
8+
public class CreatePlaceVoteRes {
9+
}

src/main/java/devkor/com/teamcback/domain/vote/entity/Vote.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ public class Vote extends BaseEntity {
3030
@Enumerated(EnumType.STRING)
3131
private VoteStatus status;
3232

33+
public Vote(Long voteTopicId, Long placeId, VoteStatus voteStatus) {
34+
this.voteTopicId = voteTopicId;
35+
this.placeId = placeId;
36+
this.status = voteStatus;
37+
}
38+
3339
public void checkStatus() {
3440
if(this.status == CLOSED) throw new GlobalException(CLOSED_VOTE);
3541
}

src/main/java/devkor/com/teamcback/domain/vote/repository/CustomVoteRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,6 @@ public interface CustomVoteRepository {
1515
List<GetVoteOptionRes> getVoteOptionByVoteId(Long voteId);
1616

1717
List<GetVoteOptionRes> getVoteOptionByVoteIdOrderByCount(Long voteId);
18+
19+
List<Vote> findMajorVote(VoteStatus status, int count);
1820
}

src/main/java/devkor/com/teamcback/domain/vote/repository/CustomVoteRepositoryImpl.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22

33
import com.querydsl.core.BooleanBuilder;
44
import com.querydsl.core.types.dsl.BooleanExpression;
5+
import com.querydsl.jpa.JPAExpressions;
56
import com.querydsl.jpa.impl.JPAQueryFactory;
67

7-
import static devkor.com.teamcback.domain.place.entity.QPlace.place;
88
import static devkor.com.teamcback.domain.vote.entity.QVoteOption.voteOption;
99
import static devkor.com.teamcback.domain.vote.entity.QVoteRecord.voteRecord;
1010
import static devkor.com.teamcback.domain.vote.entity.QVote.vote;
1111

12-
import devkor.com.teamcback.domain.place.entity.Place;
13-
import devkor.com.teamcback.domain.place.entity.PlaceType;
1412
import devkor.com.teamcback.domain.vote.dto.response.GetVoteOptionRes;
1513
import devkor.com.teamcback.domain.vote.dto.response.QGetVoteOptionRes;
1614
import devkor.com.teamcback.domain.vote.entity.Vote;
@@ -126,6 +124,21 @@ public List<GetVoteOptionRes> getVoteOptionByVoteIdOrderByCount(Long voteId) {
126124
.fetch();
127125
}
128126

127+
@Override
128+
public List<Vote> findMajorVote(VoteStatus status, int count){
129+
return jpaQueryFactory
130+
.selectFrom(vote)
131+
.where(vote.id.in(
132+
JPAExpressions
133+
.select(voteRecord.voteId)
134+
.from(voteRecord)
135+
.groupBy(voteRecord.voteId)
136+
.having(voteRecord.id.count().goe(count))
137+
).and(vote.status.eq(status)))
138+
.fetch();
139+
140+
}
141+
129142
private BooleanExpression gtVoteCursor(Long lastVoteId) {
130143
if (lastVoteId== null) return null;
131144
return vote.id.gt(lastVoteId);

src/main/java/devkor/com/teamcback/domain/vote/repository/VoteRepository.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
public interface VoteRepository extends JpaRepository<Vote, Long> {
1313
Optional<Vote> findByVoteTopicIdAndPlaceId(Long voteTopicId, Long placeId);
1414

15-
@Query("SELECT v FROM Vote v WHERE v.status IS NULL OR v.status = :status")
16-
List<Vote> findAllByStatus(@Param("status")VoteStatus status);
15+
void deleteByPlaceId(Long id);
16+
17+
List<Vote> findByVoteTopicId(Long voteTopicId);
1718
}

src/main/java/devkor/com/teamcback/domain/vote/service/VoteService.java

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
import devkor.com.teamcback.domain.place.entity.Place;
44
import devkor.com.teamcback.domain.place.repository.PlaceRepository;
55
import devkor.com.teamcback.domain.vote.dto.request.SaveVoteRecordReq;
6-
import devkor.com.teamcback.domain.vote.dto.response.ChangeVoteStatusRes;
7-
import devkor.com.teamcback.domain.vote.dto.response.GetVoteOptionRes;
8-
import devkor.com.teamcback.domain.vote.dto.response.GetVoteRes;
9-
import devkor.com.teamcback.domain.vote.dto.response.SaveVoteRecordRes;
6+
import devkor.com.teamcback.domain.vote.dto.response.*;
107
import devkor.com.teamcback.domain.vote.entity.*;
118
import devkor.com.teamcback.domain.vote.repository.VoteOptionRepository;
129
import devkor.com.teamcback.domain.vote.repository.VoteRecordRepository;
@@ -22,6 +19,7 @@
2219
import java.util.*;
2320

2421
import static devkor.com.teamcback.domain.vote.entity.VoteStatus.CLOSED;
22+
import static devkor.com.teamcback.domain.vote.entity.VoteStatus.OPEN;
2523
import static devkor.com.teamcback.global.response.ResultCode.*;
2624

2725
@Service
@@ -131,6 +129,30 @@ public CursorPageRes<GetVoteRes> getVoteList(VoteStatus status, Long lastVoteId,
131129
return new CursorPageRes<>(resList, hasNext, lastCursorId);
132130
}
133131

132+
/**
133+
* 득표 수 많은 투표 조회
134+
*/
135+
public List<GetVoteRes> getMajorVoteList(VoteStatus status) {
136+
List<GetVoteRes> resList = new ArrayList<>();
137+
138+
List<Vote> voteList = voteOptionRepository.findMajorVote(status, 20);
139+
140+
for(Vote vote : voteList) {
141+
// 투표 주제
142+
VoteTopic voteTopic = findVoteTopic(vote.getVoteTopicId());
143+
144+
// 투표 장소
145+
Place place = findPlace(vote.getPlaceId());
146+
147+
// 투표 항목, 현황
148+
List<GetVoteOptionRes> voteOptionList = voteOptionRepository.getVoteOptionByVoteId(vote.getId());
149+
150+
resList.add(new GetVoteRes(vote.getId(), vote.getStatus().toString(), voteTopic.getId(), voteTopic.getTopic(), place.getId(), place.getName(), voteOptionList));
151+
}
152+
153+
return resList;
154+
}
155+
134156
/**
135157
* 투표 상태 변경
136158
*/
@@ -144,6 +166,24 @@ public ChangeVoteStatusRes changeVoteStatus(Long voteId, VoteStatus status) {
144166
return new ChangeVoteStatusRes();
145167
}
146168

169+
/**
170+
* 장소에 투표 생성(일괄)
171+
*/
172+
@Transactional
173+
public CreatePlaceVoteRes createPlaceVote(Long voteTopicId) {
174+
// 해당 투표를 가지고 있는 장소 id
175+
List<Long> placeIdsOfVote = voteRepository.findByVoteTopicId(voteTopicId).stream().map(Vote::getPlaceId).toList();
176+
177+
List<Place> places = placeRepository.findAll();
178+
for(Place place : places) {
179+
if(!placeIdsOfVote.contains(place.getId())) {
180+
voteRepository.save(new Vote(voteTopicId, place.getId(), OPEN));
181+
}
182+
}
183+
184+
return new CreatePlaceVoteRes();
185+
}
186+
147187
private Vote findVote(Long voteTopicId, Long placeId) {
148188
return voteRepository.findByVoteTopicIdAndPlaceId(voteTopicId, placeId).orElseThrow(() -> new GlobalException(NOT_FOUND_VOTE));
149189
}

0 commit comments

Comments
 (0)