Skip to content

Commit

Permalink
Merge branch 'develop_back_core' into fix/group_capsule_open-B-#483
Browse files Browse the repository at this point in the history
  • Loading branch information
seokho-1116 authored Jun 11, 2024
2 parents 82bf626 + ed7fd18 commit a517985
Show file tree
Hide file tree
Showing 36 changed files with 425 additions and 325 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto;
package site.timecapsulearchive.core.domain.capsule.data.dto;

import java.time.ZonedDateTime;
import java.util.function.Function;
import site.timecapsulearchive.core.domain.capsule.data.response.CapsuleBasicInfoResponse;
import site.timecapsulearchive.core.domain.capsule.entity.CapsuleType;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.MyGroupCapsuleResponse;

public record MyGroupCapsuleDto(
public record CapsuleBasicInfoDto(
Long capsuleId,
String skinUrl,
ZonedDateTime dueDate,
Expand All @@ -15,9 +15,9 @@ public record MyGroupCapsuleDto(
CapsuleType capsuleType
) {

public MyGroupCapsuleResponse toResponse(
public CapsuleBasicInfoResponse toResponse(
final Function<String, String> singlePreSignUrlFunction) {
return MyGroupCapsuleResponse.builder()
return CapsuleBasicInfoResponse.builder()
.capsuleId(capsuleId)
.skinUrl(singlePreSignUrlFunction.apply(skinUrl))
.dueDate(dueDate)
Expand All @@ -27,4 +27,4 @@ public MyGroupCapsuleResponse toResponse(
.capsuleType(capsuleType)
.build();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package site.timecapsulearchive.core.domain.capsule.group_capsule.data.response;
package site.timecapsulearchive.core.domain.capsule.data.response;

import io.swagger.v3.oas.annotations.media.Schema;
import java.time.ZonedDateTime;
Expand All @@ -7,8 +7,8 @@
import site.timecapsulearchive.core.global.common.response.ResponseMappingConstant;

@Builder
@Schema(description = "사용자가 만든 그룹 캡슐")
public record MyGroupCapsuleResponse(
@Schema(description = "캡슐 기본 정보")
public record CapsuleBasicInfoResponse(

@Schema(description = "캡슐 아이디")
Long capsuleId,
Expand All @@ -32,7 +32,7 @@ public record MyGroupCapsuleResponse(
CapsuleType capsuleType
) {

public MyGroupCapsuleResponse {
public CapsuleBasicInfoResponse {
if (dueDate != null) {
dueDate = dueDate.withZoneSameInstant(ResponseMappingConstant.ZONE_ID);
}
Expand All @@ -41,4 +41,4 @@ public record MyGroupCapsuleResponse(
createdAt = createdAt.withZoneSameInstant(ResponseMappingConstant.ZONE_ID);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.util.Objects;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import site.timecapsulearchive.core.domain.group.entity.Group;
import site.timecapsulearchive.core.domain.member.entity.Member;
import site.timecapsulearchive.core.global.entity.BaseEntity;

Expand All @@ -39,16 +38,9 @@ public class GroupCapsuleOpen extends BaseEntity {
@JoinColumn(name = "member_id", nullable = false)
private Member member;

@Builder
private GroupCapsuleOpen(Boolean isOpened, Capsule capsule, Member member) {
this.isOpened = Objects.requireNonNull(isOpened);
this.capsule = Objects.requireNonNull(capsule);
this.member = Objects.requireNonNull(member);
}

public static GroupCapsuleOpen createOf(Member member, Capsule capsule, Boolean isOpened) {
return new GroupCapsuleOpen(isOpened, capsule, member);
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "group_id", nullable = false)
private Group group;

public void open() {
this.isOpened = Boolean.TRUE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupMemberCapsuleOpenStatusListResponse;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.reqeust.GroupCapsuleCreateRequest;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.reqeust.GroupCapsuleUpdateRequest;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleDetailResponse;
Expand Down Expand Up @@ -154,6 +155,35 @@ ResponseEntity<ApiSpec<MyGroupCapsuleSliceResponse>> getMyGroupCapsules(
ZonedDateTime createAt
);

@Operation(
summary = "그룹원의 그룹 캡슐 개봉 상태 확인",
description = """
그룹원의 그룹 캡슐 개봉 상태를 확인한다.
""",
security = {@SecurityRequirement(name = "user_token")},
tags = {"group capsule"}
)
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = "처리 완료"
),
@ApiResponse(
responseCode = "404",
description = "그룹 캡슐의 개봉 상태를 찾을 수 없는 경우 예외가 발생한다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
)
})
ResponseEntity<ApiSpec<GroupMemberCapsuleOpenStatusListResponse>> getGroupCapsuleOpenStatus(
Long memberId,

@Parameter(in = ParameterIn.PATH, description = "개봉 상태를 확인할 캡슐 아이디", required = true)
Long capsuleId,

@Parameter(in = ParameterIn.QUERY, description = "생성할 그룹 아이디", required = true)
Long groupId
);

@Operation(
summary = "그룹 캡슐 개봉",
description = """
Expand All @@ -177,7 +207,7 @@ ResponseEntity<ApiSpec<GroupCapsuleOpenStateResponse>> openCapsule(
Long memberId,

@Parameter(in = ParameterIn.PATH, description = "개봉할 그룹 캡슐 아이디", required = true)
@PathVariable("capsule_id") Long capsuleId
Long capsuleId
);

@Operation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import jakarta.validation.Valid;
import java.time.ZonedDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Slice;
import org.springframework.http.ResponseEntity;
Expand All @@ -13,16 +14,19 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import site.timecapsulearchive.core.domain.capsule.data.dto.CapsuleBasicInfoDto;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleDetailDto;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleOpenStateDto;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSummaryDto;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupMemberCapsuleOpenStatusDto;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.MyGroupCapsuleDto;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.reqeust.GroupCapsuleCreateRequest;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.reqeust.GroupCapsuleUpdateRequest;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleDetailResponse;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleOpenStateResponse;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsulePageResponse;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleSummaryResponse;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupMemberCapsuleOpenStatusListResponse;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.MyGroupCapsuleSliceResponse;
import site.timecapsulearchive.core.domain.capsule.group_capsule.facade.GroupCapsuleFacade;
import site.timecapsulearchive.core.domain.capsule.group_capsule.service.GroupCapsuleService;
Expand Down Expand Up @@ -121,7 +125,7 @@ public ResponseEntity<ApiSpec<MyGroupCapsuleSliceResponse>> getMyGroupCapsules(
@RequestParam(defaultValue = "20", value = "size") final int size,
@RequestParam(value = "created_at") final ZonedDateTime createdAt
) {
final Slice<MyGroupCapsuleDto> groupCapsules = groupCapsuleService.findMyGroupCapsuleSlice(
final Slice<CapsuleBasicInfoDto> groupCapsules = groupCapsuleService.findMyGroupCapsuleSlice(
memberId,
size,
createdAt
Expand All @@ -139,6 +143,24 @@ public ResponseEntity<ApiSpec<MyGroupCapsuleSliceResponse>> getMyGroupCapsules(
);
}

@GetMapping(value = "/{capsule_id}/open-status", produces = {"application/json"})
@Override
public ResponseEntity<ApiSpec<GroupMemberCapsuleOpenStatusListResponse>> getGroupCapsuleOpenStatus(
@AuthenticationPrincipal final Long memberId,
@PathVariable("capsule_id") final Long capsuleId,
@RequestParam("group_id") final Long groupId
) {
List<GroupMemberCapsuleOpenStatusDto> groupMemberCapsuleOpenStatus = groupCapsuleService.findGroupMemberCapsuleOpenStatus(
memberId, capsuleId, groupId);

return ResponseEntity.ok(
ApiSpec.success(
SuccessCode.SUCCESS,
GroupMemberCapsuleOpenStatusListResponse.create(groupMemberCapsuleOpenStatus)
)
);
}

@PostMapping("/{capsule_id}/open")
@Override
public ResponseEntity<ApiSpec<GroupCapsuleOpenStateResponse>> openCapsule(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto;

import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupMemberCapsuleOpenStatusResponse;

public record GroupMemberCapsuleOpenStatusDto(
Long memberId,
String nickname,
String profileUrl,
boolean isOpened
) {

public GroupMemberCapsuleOpenStatusResponse toResponse() {
return GroupMemberCapsuleOpenStatusResponse.builder()
.memberId(memberId)
.nickname(nickname)
.profileUrl(profileUrl)
.isOpened(isOpened)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package site.timecapsulearchive.core.domain.capsule.group_capsule.data.response;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupMemberCapsuleOpenStatusDto;

@Schema(description = "그룹원들 캡슐 개봉 상태")
public record GroupMemberCapsuleOpenStatusListResponse(
List<GroupMemberCapsuleOpenStatusResponse> groupMemberCapsuleOpenStatus
) {

public static GroupMemberCapsuleOpenStatusListResponse create(
List<GroupMemberCapsuleOpenStatusDto> groupMemberCapsuleOpenStatus) {
List<GroupMemberCapsuleOpenStatusResponse> groupMemberCapsuleOpenStatusResponses = groupMemberCapsuleOpenStatus.stream()
.map(GroupMemberCapsuleOpenStatusDto::toResponse)
.toList();

return new GroupMemberCapsuleOpenStatusListResponse(groupMemberCapsuleOpenStatusResponses);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package site.timecapsulearchive.core.domain.capsule.group_capsule.data.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;

@Schema(description = "그룹원별 캡슐 개봉 상태")
@Builder
public record GroupMemberCapsuleOpenStatusResponse(

@Schema(description = "회원 아이디")
Long memberId,

@Schema(description = "회원 닉네임")
String nickname,

@Schema(description = "회원 프로필")
String profileUrl,

@Schema(description = "개봉 상태")
boolean isOpened
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@

import java.util.List;
import java.util.function.Function;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.MyGroupCapsuleDto;
import site.timecapsulearchive.core.domain.capsule.data.dto.CapsuleBasicInfoDto;
import site.timecapsulearchive.core.domain.capsule.data.response.CapsuleBasicInfoResponse;

public record MyGroupCapsuleSliceResponse(
List<MyGroupCapsuleResponse> groupCapsules,
List<CapsuleBasicInfoResponse> groupCapsules,
Boolean hasNext
) {

public static MyGroupCapsuleSliceResponse createOf(
final List<MyGroupCapsuleDto> groupCapsules,
final List<CapsuleBasicInfoDto> groupCapsules,
final boolean hasNext,
final Function<String, String> singlePreSignUrlFunction
) {
List<MyGroupCapsuleResponse> groupCapsuleResponses = groupCapsules.stream()
List<CapsuleBasicInfoResponse> groupCapsuleResponses = groupCapsules.stream()
.map(capsule -> capsule.toResponse(singlePreSignUrlFunction))
.toList();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ public void saveGroupCapsule(

final List<Long> groupMemberIds = memberGroupQueryService.findGroupMemberIds(groupId);

groupCapsuleOpenService.bulkSave(groupMemberIds, capsule);
groupCapsuleOpenService.bulkSave(groupId, groupMemberIds, capsule);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package site.timecapsulearchive.core.domain.capsule.group_capsule.repository;

import static site.timecapsulearchive.core.domain.capsule.entity.QGroupCapsuleOpen.groupCapsuleOpen;
import static site.timecapsulearchive.core.domain.member.entity.QMember.member;

import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
Expand All @@ -11,19 +16,26 @@
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import site.timecapsulearchive.core.domain.capsule.entity.Capsule;
import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupMemberCapsuleOpenStatusDto;
import site.timecapsulearchive.core.domain.member.entity.QMember;

@Repository
@RequiredArgsConstructor
public class GroupCapsuleOpenQueryRepository {

private final JdbcTemplate jdbcTemplate;
private final JPAQueryFactory jpaQueryFactory;

public void bulkSave(final List<Long> groupMemberIds, final Capsule capsule) {
public void bulkSave(
final Long groupId,
final List<Long> groupMemberIds,
final Capsule capsule
) {
jdbcTemplate.batchUpdate(
"""
INSERT INTO group_capsule_open (
group_capsule_open_id, is_opened, member_id, capsule_id, created_at, updated_at
) values (?, ? ,? ,? ,?, ?)
group_capsule_open_id, is_opened, member_id, capsule_id, group_id, created_at, updated_at
) values (?, ? ,? ,? ,?, ?, ?)
""",
new BatchPreparedStatementSetter() {
@Override
Expand All @@ -34,8 +46,9 @@ public void setValues(PreparedStatement ps, int i) throws SQLException {
ps.setBoolean(2, isOpened);
ps.setLong(3, groupMemberIds.get(i));
ps.setLong(4, capsule.getId());
ps.setTimestamp(5, Timestamp.valueOf(ZonedDateTime.now().toLocalDateTime()));
ps.setLong(5, groupId);
ps.setTimestamp(6, Timestamp.valueOf(ZonedDateTime.now().toLocalDateTime()));
ps.setTimestamp(7, Timestamp.valueOf(ZonedDateTime.now().toLocalDateTime()));
}

@Override
Expand All @@ -45,4 +58,26 @@ public int getBatchSize() {
}
);
}

public List<GroupMemberCapsuleOpenStatusDto> findGroupMemberCapsuleOpenStatus(
final Long capsuleId,
final Long groupId
) {
return jpaQueryFactory
.select(
Projections.constructor(
GroupMemberCapsuleOpenStatusDto.class,
groupCapsuleOpen.member.id,
groupCapsuleOpen.member.nickname,
groupCapsuleOpen.member.profileUrl,
groupCapsuleOpen.isOpened
)
)
.from(groupCapsuleOpen)
.join(groupCapsuleOpen.member, member)
.where(groupCapsuleOpen.group.id.eq(groupId)
.and(groupCapsuleOpen.capsule.id.eq(capsuleId))
)
.fetch();
}
}
Loading

0 comments on commit a517985

Please sign in to comment.