Skip to content

Commit df9838b

Browse files
authored
Deploy / Merge to Main(#125)
Deploy / Merge to Main
2 parents 425c5a9 + f38587e commit df9838b

10 files changed

Lines changed: 60 additions & 14 deletions

File tree

src/main/java/redot/redot_server/domain/admin/controller/AdminConsultationController.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,11 @@ public ResponseEntity<ConsultationResponse> getConsultationInfo(
3838
public ResponseEntity<PageResponse<ConsultationResponse>> getAllConsultations(
3939
ConsultationSearchCondition searchCondition,
4040
@PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
41+
ConsultationSearchCondition condition = searchCondition == null
42+
? ConsultationSearchCondition.empty()
43+
: searchCondition;
4144
PageResponse<ConsultationResponse> response = adminConsultationService
42-
.getAllConsultationsBySearchCondition(searchCondition, pageable);
45+
.getAllConsultationsBySearchCondition(condition, pageable);
4346
return ResponseEntity.ok(response);
4447
}
4548

src/main/java/redot/redot_server/domain/admin/controller/docs/AdminConsultationControllerDocs.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public interface AdminConsultationControllerDocs {
2222
content = @Content(schema = @Schema(implementation = ConsultationResponse.class)))
2323
ResponseEntity<ConsultationResponse> getConsultationInfo(@Parameter(description = "상담 ID", example = "1") Long consultationId);
2424

25-
@Operation(summary = "상담 목록 조회", description = "`email`, `phone`, `status`, `type`, `currentWebsiteUrl` 검색 조건을 조합해 조회하며 `sort=createdAt,desc` 와 같은 Pageable 쿼리 파라미터를 사용합니다.")
25+
@Operation(summary = "상담 목록 조회", description = "`email`, `phone`, `status`, `type`, `currentWebsiteUrl`, `startDate`, `endDate` 검색 조건을 조합해 조회하며 `sort=createdAt,desc` 와 같은 Pageable 쿼리 파라미터를 사용합니다. `status` 파라미터를 생략하면 CANCELLED 상태 상담은 응답에서 제외됩니다.")
2626
@ApiResponse(responseCode = "200", description = "조회 성공",
2727
content = @Content(schema = @Schema(implementation = PageResponse.class)))
2828
ResponseEntity<PageResponse<ConsultationResponse>> getAllConsultations(
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package redot.redot_server.domain.admin.dto;
22

3+
import java.time.LocalDate;
4+
import org.springframework.format.annotation.DateTimeFormat;
35
import redot.redot_server.domain.redot.consultation.entity.ConsultationStatus;
46
import redot.redot_server.domain.redot.consultation.entity.ConsultationType;
57

@@ -8,6 +10,11 @@ public record ConsultationSearchCondition(
810
String phone,
911
ConsultationStatus status,
1012
ConsultationType type,
11-
String currentWebsiteUrl
13+
String currentWebsiteUrl,
14+
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
15+
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate
1216
) {
17+
public static ConsultationSearchCondition empty() {
18+
return new ConsultationSearchCondition(null, null, null, null, null, null, null);
19+
}
1320
}

src/main/java/redot/redot_server/domain/admin/dto/request/ConsultationUpdateRequest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public record ConsultationUpdateRequest(
1717
String content,
1818
String page,
1919
String currentWebsiteUrl,
20+
@Size(max = 1000, message = "비고는 1000자를 초과할 수 없습니다")
21+
String remark,
2022
@NotNull(message = "상담 상태를 선택해주세요.")
2123
ConsultationStatus status,
2224
@NotNull(message = "상담 타입을 선택해주세요.")

src/main/java/redot/redot_server/domain/admin/service/AdminConsultationService.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import redot.redot_server.domain.admin.dto.request.ConsultationUpdateRequest;
1010
import redot.redot_server.domain.redot.consultation.dto.response.ConsultationResponse;
1111
import redot.redot_server.domain.redot.consultation.entity.Consultation;
12+
import redot.redot_server.domain.redot.consultation.entity.ConsultationStatus;
1213
import redot.redot_server.domain.redot.consultation.exception.ConsultationErrorCode;
1314
import redot.redot_server.domain.redot.consultation.exception.ConsultationException;
1415
import redot.redot_server.domain.redot.consultation.repository.ConsultationRepository;
@@ -22,16 +23,13 @@ public class AdminConsultationService {
2223
private final ConsultationRepository consultationRepository;
2324

2425
public ConsultationResponse getConsultationInfo(Long consultationId) {
25-
return consultationRepository.findById(consultationId)
26-
.map(ConsultationResponse::fromEntity)
27-
.orElseThrow(() -> new ConsultationException(ConsultationErrorCode.CONSULTATION_NOT_FOUND));
26+
Consultation consultation = getConsultation(consultationId);
27+
return ConsultationResponse.fromEntity(consultation);
2828
}
2929

3030
@Transactional
3131
public ConsultationResponse updateConsultationInfo(Long consultationId, ConsultationUpdateRequest request) {
32-
Consultation consultation = consultationRepository.findById(consultationId)
33-
.orElseThrow(() -> new ConsultationException(ConsultationErrorCode.CONSULTATION_NOT_FOUND));
34-
32+
Consultation consultation = getConsultation(consultationId);
3533
consultation.update(request);
3634

3735
return ConsultationResponse.fromEntity(consultation);
@@ -44,4 +42,10 @@ public PageResponse<ConsultationResponse> getAllConsultationsBySearchCondition(
4442
.map(ConsultationResponse::fromEntity);
4543
return PageResponse.from(page);
4644
}
45+
46+
private Consultation getConsultation(Long consultationId) {
47+
return consultationRepository.findById(consultationId)
48+
.orElseThrow(() -> new ConsultationException(ConsultationErrorCode.CONSULTATION_NOT_FOUND));
49+
}
50+
4751
}

src/main/java/redot/redot_server/domain/redot/consultation/dto/response/ConsultationResponse.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public record ConsultationResponse(
1212
String content,
1313
String page,
1414
String currentWebsiteUrl,
15+
String remark,
1516
ConsultationStatus status,
1617
ConsultationType type,
1718
LocalDateTime createdAt
@@ -24,6 +25,7 @@ public static ConsultationResponse fromEntity(Consultation consultation) {
2425
consultation.getContent(),
2526
consultation.getPage(),
2627
consultation.getCurrentWebsiteUrl(),
28+
consultation.getRemark(),
2729
consultation.getStatus(),
2830
consultation.getType(),
2931
consultation.getCreatedAt()

src/main/java/redot/redot_server/domain/redot/consultation/entity/Consultation.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public class Consultation extends BaseTimeEntity {
4040

4141
private String page;
4242

43+
@Column(length = 1000)
44+
private String remark;
45+
4346
@Column(nullable = false)
4447
@Enumerated(EnumType.STRING)
4548
private ConsultationStatus status;
@@ -66,6 +69,7 @@ public void update(ConsultationUpdateRequest request) {
6669
this.content = request.content();
6770
this.currentWebsiteUrl = request.currentWebsiteUrl();
6871
this.page = request.page();
72+
this.remark = request.remark();
6973
this.status = request.status();
7074
this.type = request.type();
7175
}

src/main/java/redot/redot_server/domain/redot/consultation/entity/ConsultationStatus.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
public enum ConsultationStatus {
44
PENDING,
55
IN_PROGRESS,
6-
COMPLETED
6+
COMPLETED,
7+
CANCELLED
78
}

src/main/java/redot/redot_server/domain/redot/consultation/repository/ConsultationRepositoryImpl.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.querydsl.core.types.OrderSpecifier;
66
import com.querydsl.core.types.dsl.BooleanExpression;
77
import com.querydsl.jpa.impl.JPAQueryFactory;
8+
import java.time.LocalDate;
89
import java.util.List;
910
import lombok.RequiredArgsConstructor;
1011
import org.springframework.data.domain.Page;
@@ -28,9 +29,11 @@ public Page<Consultation> findAllBySearchCondition(ConsultationSearchCondition c
2829
BooleanExpression[] predicates = new BooleanExpression[]{
2930
emailContains(condition.email()),
3031
phoneContains(condition.phone()),
31-
statusEq(condition.status()),
32+
statusCondition(condition.status()),
3233
typeEq(condition.type()),
33-
currentWebsiteUrlContains(condition.currentWebsiteUrl())
34+
currentWebsiteUrlContains(condition.currentWebsiteUrl()),
35+
createdAtGoe(condition.startDate()),
36+
createdAtLt(condition.endDate())
3437
};
3538

3639
List<Consultation> content = queryFactory.selectFrom(consultation)
@@ -70,14 +73,25 @@ private BooleanExpression currentWebsiteUrlContains(String url) {
7073
return hasText(url) ? consultation.currentWebsiteUrl.containsIgnoreCase(url) : null;
7174
}
7275

73-
private BooleanExpression statusEq(ConsultationStatus status) {
74-
return status == null ? null : consultation.status.eq(status);
76+
private BooleanExpression statusCondition(ConsultationStatus status) {
77+
if (status == null) {
78+
return consultation.status.ne(ConsultationStatus.CANCELLED);
79+
}
80+
return consultation.status.eq(status);
7581
}
7682

7783
private BooleanExpression typeEq(ConsultationType type) {
7884
return type == null ? null : consultation.type.eq(type);
7985
}
8086

87+
private BooleanExpression createdAtGoe(LocalDate startDate) {
88+
return startDate == null ? null : consultation.createdAt.goe(startDate.atStartOfDay());
89+
}
90+
91+
private BooleanExpression createdAtLt(LocalDate endDate) {
92+
return endDate == null ? null : consultation.createdAt.lt(endDate.plusDays(1).atStartOfDay());
93+
}
94+
8195
private boolean hasText(String value) {
8296
return value != null && !value.isBlank();
8397
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
ALTER TABLE consultations
2+
ADD COLUMN IF NOT EXISTS remark VARCHAR(1000);
3+
4+
ALTER TABLE consultations
5+
DROP CONSTRAINT IF EXISTS ck_consultation_status;
6+
7+
ALTER TABLE consultations
8+
ADD CONSTRAINT ck_consultation_status
9+
CHECK (status IN ('PENDING', 'IN_PROGRESS', 'COMPLETED', 'CANCELLED'));

0 commit comments

Comments
 (0)