Skip to content

Commit

Permalink
Merge pull request #40 from Modagbul/feat/소모임
Browse files Browse the repository at this point in the history
Feat/소모임
  • Loading branch information
seungueonn authored Oct 22, 2023
2 parents ef1d274 + 84c04c8 commit db0b634
Show file tree
Hide file tree
Showing 26 changed files with 381 additions and 62 deletions.
4 changes: 4 additions & 0 deletions src/docs/asciidoc/Team-API.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ operation::team-controller-test/sign-in_team[snippets='http-request,path-paramet
=== Team 소모임 조회
operation::team-controller-test/get_team[snippets='http-request,http-response,response-fields']

[[Team-목표보드-조회]]
=== Team 목표보드_소모임 단건_조회
operation::team-controller-test/get_team_detail[snippets='http-request,path-parameters,http-response,response-fields']

[[Team-소모임-수정]]
=== Team 소모임 수정
operation::team-controller-test/update_team[snippets='http-request,path-parameters,http-response,request-fields,response-fields']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
import com.moing.backend.domain.board.application.dto.response.GetAllBoardResponse;

public interface BoardCustomRepository {
GetAllBoardResponse findBoardAll(Long teamId, Long boardId);
GetAllBoardResponse findBoardAll(Long teamId, Long memberId);
Integer findUnReadBoardNum(Long teamId, Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
import static com.moing.backend.domain.board.domain.entity.QBoard.board;
import static com.moing.backend.domain.boardRead.domain.entity.QBoardRead.boardRead;

public class BoardCustomRepositoryImpl implements BoardCustomRepository {
private final JPAQueryFactory queryFactory;
public class BoardCustomRepositoryImpl implements BoardCustomRepository {

private final JPAQueryFactory queryFactory;
public BoardCustomRepositoryImpl(EntityManager em) {
this.queryFactory = new JPAQueryFactory(em);
}
Expand Down Expand Up @@ -65,4 +65,22 @@ public GetAllBoardResponse findBoardAll(Long teamId, Long memberId) {

return new GetAllBoardResponse(noticeBlocks.size(), noticeBlocks, regularBlocks.size(), regularBlocks);
}

@Override
public Integer findUnReadBoardNum(Long teamId, Long memberId) {
// 전체 게시글 수
Long allBoards = queryFactory
.selectFrom(board)
.where(board.team.teamId.eq(teamId))
.fetchCount();

// 멤버가 읽은 게시글 수
Long readBoards = queryFactory
.selectFrom(boardRead)
.where(boardRead.member.memberId.eq(memberId))
.where(boardRead.board.team.teamId.eq(teamId))
.fetchCount();

return Math.toIntExact(allBoards - readBoards);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ public Board getBoard(Long boardId){
public GetAllBoardResponse getBoardAll(Long teamId, Long memberId){
return boardRepository.findBoardAll(teamId, memberId);
}

public Integer getUnReadBoardNum(Long teamId, Long memberId){
return boardRepository.findUnReadBoardNum(teamId, memberId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class Member extends BaseTimeEntity {
@Column(nullable = false, unique = true)
private String email;

private String profileImage; //없으면 undef
private String profileImage;

@Column(length = 10)
@Enumerated(EnumType.STRING)
Expand Down Expand Up @@ -156,11 +156,4 @@ public Member(LocalDate birthDate, String email, String fcmToken, Gender gender,
this.socialId = socialId;
}

public void deleteTeamMember(){
List<TeamMember> teamMemberList=this.getTeamMembers();
for(TeamMember teamMember:teamMemberList){
teamMember.deleteMember();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@
@NoArgsConstructor
public class DeleteTeamResponse {
private Long teamId;
private String teamName;
private Integer numOfMember;
private Long duration; //걸린시간(단위:날짜)
private Long numOfMission;
private Integer levelOfFire; //불꽃 레벨
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.moing.backend.domain.team.application.dto.response;

import com.moing.backend.domain.team.domain.constant.Category;
import com.querydsl.core.annotations.QueryProjection;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

@Getter
@Builder
@AllArgsConstructor
public class GetTeamDetailResponse {
private Integer boardNum; //안 읽은 게시글
private TeamInfo teamInfo;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
Expand All @@ -24,23 +25,29 @@ public class TeamBlock {
private Integer numOfMember;
private String category;
private String startDate;
private LocalDateTime deletionTime;

@QueryProjection
public TeamBlock(Long teamId, LocalDateTime approvalTime, Integer levelOfFire, String teamName, Integer numOfMember, Category category){
public TeamBlock(Long teamId, LocalDateTime approvalTime, Integer levelOfFire, String teamName, Integer numOfMember, Category category, LocalDateTime deletionTime){
this.teamId=teamId;
this.duration=calculateDuration(approvalTime);
this.levelOfFire=levelOfFire;
this.teamName=teamName;
this.numOfMember=numOfMember;
this.category=category.getMessage();
this.startDate=approvalTime.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy.MM.dd"));
this.deletionTime=deletionTime;
}

private Long calculateDuration(LocalDateTime approvalTime) {
public Long calculateDuration(LocalDateTime approvalTime) {
ZoneId seoulZoneId = ZoneId.of("Asia/Seoul");
LocalDateTime currentSeoulTime = LocalDateTime.now(seoulZoneId).withSecond(0).withNano(0);
LocalDateTime adjustedApprovalTime = approvalTime.withSecond(0).withNano(0);
return ChronoUnit.DAYS.between(adjustedApprovalTime, currentSeoulTime);
LocalDateTime currentDateTime = LocalDateTime.now(seoulZoneId);

long hoursBetween = ChronoUnit.HOURS.between(approvalTime, currentDateTime);
long daysBetween = hoursBetween / 24;

return daysBetween;
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.moing.backend.domain.team.application.dto.response;

import com.moing.backend.domain.team.domain.constant.Category;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@AllArgsConstructor
@Getter
@Builder
public class TeamInfo {
private Boolean isDeleted;
private LocalDateTime deletionTime;
private String teamName; //소모임 이름
private Integer numOfMember; //소모임원 수
private Category category; //카테고리
private String introduction; //소개
private List<TeamMemberInfo> teamMemberInfoList = new ArrayList<>(); //소모임원 정보
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.moing.backend.domain.team.application.dto.response;

import com.querydsl.core.annotations.QueryProjection;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Getter
@AllArgsConstructor
@Builder
public class TeamMemberInfo {
private Long memberId;
private String nickName;
private String profileImage;
private String introduction;
private Boolean isLeader;

@QueryProjection
public TeamMemberInfo(Long memberId, String nickName, String profileImage, String introduction, Long leaderId){
this.memberId=memberId;
this.nickName=nickName;
this.profileImage=profileImage;
this.introduction=introduction;
this.isLeader=memberId.equals(leaderId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@

import com.moing.backend.domain.member.domain.entity.Member;
import com.moing.backend.domain.team.application.dto.request.CreateTeamRequest;
import com.moing.backend.domain.team.application.dto.response.DeleteTeamResponse;
import com.moing.backend.domain.team.application.dto.response.GetTeamDetailResponse;
import com.moing.backend.domain.team.application.dto.response.TeamInfo;
import com.moing.backend.domain.team.application.dto.response.TeamMemberInfo;
import com.moing.backend.domain.team.domain.constant.ApprovalStatus;
import com.moing.backend.domain.team.domain.constant.Category;
import com.moing.backend.domain.team.domain.entity.Team;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.List;

@Component
public class TeamMapper {

Expand All @@ -23,4 +33,34 @@ public Team createTeam(CreateTeamRequest createTeamRequest, Member member) {
.levelOfFire(1)
.build();
}

public GetTeamDetailResponse toTeamDetailResponse(Team team, Integer boardNum, List<TeamMemberInfo> teamMemberInfoList) {
TeamInfo teamInfo = new TeamInfo(team.isDeleted(), team.getDeletionTime(), team.getName(), teamMemberInfoList.size(), team.getCategory(), team.getIntroduction(), teamMemberInfoList);
return GetTeamDetailResponse.builder()
.boardNum(boardNum)
.teamInfo(teamInfo)
.build();
}

public DeleteTeamResponse toDeleteTeamResponse(Long numOfMission, Team team){
return DeleteTeamResponse.builder()
.teamId(team.getTeamId())
.teamName(team.getName())
.numOfMember(team.getNumOfMember())
.levelOfFire(team.getLevelOfFire())
.duration(calculateDuration(team.getApprovalTime()))
.numOfMission(numOfMission)
.build();
}

public Long calculateDuration(LocalDateTime approvalTime) {
ZoneId seoulZoneId = ZoneId.of("Asia/Seoul");
LocalDateTime currentDateTime = LocalDateTime.now(seoulZoneId);

long hoursBetween = ChronoUnit.HOURS.between(approvalTime, currentDateTime);
long daysBetween = hoursBetween / 24;

return daysBetween;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.Objects;

@Service
@Transactional
@RequiredArgsConstructor
public class CheckLeaderUserCase {
public boolean isTeamLeader(Member member, Team team) {
if (member.getMemberId() == team.getLeaderId()) {
return true;
} else {
return false;
}
return Objects.equals(member.getMemberId(), team.getLeaderId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import com.moing.backend.domain.member.domain.entity.Member;
import com.moing.backend.domain.member.domain.service.MemberGetService;
import com.moing.backend.domain.mission.domain.service.MissionQueryService;
import com.moing.backend.domain.team.application.dto.response.DeleteTeamResponse;
import com.moing.backend.domain.team.application.mapper.TeamMapper;
import com.moing.backend.domain.team.domain.entity.Team;
import com.moing.backend.domain.team.domain.service.TeamGetService;
import com.moing.backend.domain.team.exception.NotAuthByTeamException;
import com.moing.backend.domain.teamMember.domain.entity.TeamMember;
import com.moing.backend.domain.teamMember.domain.service.TeamMemberGetService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

Expand All @@ -21,18 +21,18 @@ public class DisbandTeamUserCase {
private final MemberGetService memberGetService;
private final TeamGetService teamGetService;
private final CheckLeaderUserCase checkLeaderUserCase;
private final TeamMemberGetService teamMemberGetService;
private final MissionQueryService missionQueryService;
private final TeamMapper teamMapper;

public DeleteTeamResponse disbandTeam(String socialId, Long teamId) {
Member member = memberGetService.getMemberBySocialId(socialId);
Team team = teamGetService.getTeamByTeamId(teamId);

if (checkLeaderUserCase.isTeamLeader(member, team)) {
//TODO: 팀의 모든 멤버 isDeleted true 해주환
team.deleteTeam();
} else {
throw new NotAuthByTeamException();
}
return new DeleteTeamResponse(team.getTeamId());
return teamMapper.toDeleteTeamResponse(missionQueryService.findMissionsCountByTeam(team.getTeamId()), team);
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
package com.moing.backend.domain.team.application.service;

import com.moing.backend.domain.board.domain.service.BoardGetService;
import com.moing.backend.domain.member.domain.entity.Member;
import com.moing.backend.domain.member.domain.service.MemberGetService;
import com.moing.backend.domain.team.application.dto.response.GetTeamDetailResponse;
import com.moing.backend.domain.team.application.dto.response.GetTeamResponse;
import com.moing.backend.domain.team.application.dto.response.TeamMemberInfo;
import com.moing.backend.domain.team.application.mapper.TeamMapper;
import com.moing.backend.domain.team.domain.entity.Team;
import com.moing.backend.domain.team.domain.service.TeamGetService;
import com.moing.backend.domain.teamMember.domain.service.TeamMemberGetService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.List;

@Service
@Transactional
@RequiredArgsConstructor
public class GetTeamUserCase {
private final MemberGetService memberGetService;
private final TeamGetService teamGetService;
private final BoardGetService boardGetService;
private final TeamMemberGetService teamMemberGetService;
private final TeamMapper teamMapper;

public GetTeamResponse getTeam(String socialId) {
Member member = memberGetService.getMemberBySocialId(socialId);
return teamGetService.getTeamByMember(member);
}

public GetTeamDetailResponse getTeamDetailResponse(String socialId, Long teamId) {
Member member = memberGetService.getMemberBySocialId(socialId);
Integer boardNum = boardGetService.getUnReadBoardNum(teamId, member.getMemberId());
List<TeamMemberInfo> teamMemberInfoList = teamMemberGetService.getTeamMemberInfo(teamId);
Team team = teamGetService.getTeamByTeamId(teamId);
return teamMapper.toTeamDetailResponse(team, boardNum, teamMemberInfoList);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.moing.backend.domain.member.domain.entity.Member;
import com.moing.backend.domain.member.domain.service.MemberGetService;
import com.moing.backend.domain.mission.domain.service.MissionQueryService;
import com.moing.backend.domain.team.application.dto.response.DeleteTeamResponse;
import com.moing.backend.domain.team.application.mapper.TeamMapper;
import com.moing.backend.domain.team.domain.entity.Team;
import com.moing.backend.domain.team.domain.service.TeamGetService;
import com.moing.backend.domain.teamMember.domain.entity.TeamMember;
Expand All @@ -20,12 +22,14 @@ public class WithdrawTeamUserCase {
private final TeamMemberGetService teamMemberGetService;
private final MemberGetService memberGetService;
private final TeamGetService teamGetService;
private final MissionQueryService missionQueryService;
private final TeamMapper teamMapper;

public DeleteTeamResponse withdrawTeam(String socialId, Long teamId) {
Member member = memberGetService.getMemberBySocialId(socialId);
Team team = teamGetService.getTeamByTeamId(teamId);
TeamMember teamMember = teamMemberGetService.getTeamMember(member, team);
teamMember.deleteMember();
return new DeleteTeamResponse(team.getTeamId());
teamMember.deleteMember(team);
return teamMapper.toDeleteTeamResponse(missionQueryService.findMissionsCountByTeam(team.getTeamId()),team);
}
}
Loading

0 comments on commit db0b634

Please sign in to comment.