Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ public ResponseEntity<ConsultationResponse> getConsultationInfo(
public ResponseEntity<PageResponse<ConsultationResponse>> getAllConsultations(
ConsultationSearchCondition searchCondition,
@PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
ConsultationSearchCondition condition = searchCondition == null
? ConsultationSearchCondition.empty()
: searchCondition;
PageResponse<ConsultationResponse> response = adminConsultationService
.getAllConsultationsBySearchCondition(searchCondition, pageable);
.getAllConsultationsBySearchCondition(condition, pageable);
return ResponseEntity.ok(response);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public interface AdminConsultationControllerDocs {
content = @Content(schema = @Schema(implementation = ConsultationResponse.class)))
ResponseEntity<ConsultationResponse> getConsultationInfo(@Parameter(description = "상담 ID", example = "1") Long consultationId);

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

import java.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;
import redot.redot_server.domain.redot.consultation.entity.ConsultationStatus;
import redot.redot_server.domain.redot.consultation.entity.ConsultationType;

Expand All @@ -8,6 +10,11 @@ public record ConsultationSearchCondition(
String phone,
ConsultationStatus status,
ConsultationType type,
String currentWebsiteUrl
String currentWebsiteUrl,
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate
) {
public static ConsultationSearchCondition empty() {
return new ConsultationSearchCondition(null, null, null, null, null, null, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public record ConsultationUpdateRequest(
String content,
String page,
String currentWebsiteUrl,
@Size(max = 1000, message = "비고는 1000자를 초과할 수 없습니다")
String remark,
@NotNull(message = "상담 상태를 선택해주세요.")
ConsultationStatus status,
@NotNull(message = "상담 타입을 선택해주세요.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import redot.redot_server.domain.admin.dto.request.ConsultationUpdateRequest;
import redot.redot_server.domain.redot.consultation.dto.response.ConsultationResponse;
import redot.redot_server.domain.redot.consultation.entity.Consultation;
import redot.redot_server.domain.redot.consultation.entity.ConsultationStatus;
import redot.redot_server.domain.redot.consultation.exception.ConsultationErrorCode;
import redot.redot_server.domain.redot.consultation.exception.ConsultationException;
import redot.redot_server.domain.redot.consultation.repository.ConsultationRepository;
Expand All @@ -22,16 +23,13 @@ public class AdminConsultationService {
private final ConsultationRepository consultationRepository;

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

@Transactional
public ConsultationResponse updateConsultationInfo(Long consultationId, ConsultationUpdateRequest request) {
Consultation consultation = consultationRepository.findById(consultationId)
.orElseThrow(() -> new ConsultationException(ConsultationErrorCode.CONSULTATION_NOT_FOUND));

Consultation consultation = getConsultation(consultationId);
consultation.update(request);

return ConsultationResponse.fromEntity(consultation);
Expand All @@ -44,4 +42,10 @@ public PageResponse<ConsultationResponse> getAllConsultationsBySearchCondition(
.map(ConsultationResponse::fromEntity);
return PageResponse.from(page);
}

private Consultation getConsultation(Long consultationId) {
return consultationRepository.findById(consultationId)
.orElseThrow(() -> new ConsultationException(ConsultationErrorCode.CONSULTATION_NOT_FOUND));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public record ConsultationResponse(
String content,
String page,
String currentWebsiteUrl,
String remark,
ConsultationStatus status,
ConsultationType type,
LocalDateTime createdAt
Expand All @@ -24,6 +25,7 @@ public static ConsultationResponse fromEntity(Consultation consultation) {
consultation.getContent(),
consultation.getPage(),
consultation.getCurrentWebsiteUrl(),
consultation.getRemark(),
consultation.getStatus(),
consultation.getType(),
consultation.getCreatedAt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public class Consultation extends BaseTimeEntity {

private String page;

@Column(length = 1000)
private String remark;

@Column(nullable = false)
@Enumerated(EnumType.STRING)
private ConsultationStatus status;
Expand All @@ -66,6 +69,7 @@ public void update(ConsultationUpdateRequest request) {
this.content = request.content();
this.currentWebsiteUrl = request.currentWebsiteUrl();
this.page = request.page();
this.remark = request.remark();
this.status = request.status();
this.type = request.type();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
public enum ConsultationStatus {
PENDING,
IN_PROGRESS,
COMPLETED
COMPLETED,
CANCELLED
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.LocalDate;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
Expand All @@ -28,9 +29,11 @@ public Page<Consultation> findAllBySearchCondition(ConsultationSearchCondition c
BooleanExpression[] predicates = new BooleanExpression[]{
emailContains(condition.email()),
phoneContains(condition.phone()),
statusEq(condition.status()),
statusCondition(condition.status()),
typeEq(condition.type()),
currentWebsiteUrlContains(condition.currentWebsiteUrl())
currentWebsiteUrlContains(condition.currentWebsiteUrl()),
createdAtGoe(condition.startDate()),
createdAtLt(condition.endDate())
};

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

private BooleanExpression statusEq(ConsultationStatus status) {
return status == null ? null : consultation.status.eq(status);
private BooleanExpression statusCondition(ConsultationStatus status) {
if (status == null) {
return consultation.status.ne(ConsultationStatus.CANCELLED);
}
return consultation.status.eq(status);
}

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

private BooleanExpression createdAtGoe(LocalDate startDate) {
return startDate == null ? null : consultation.createdAt.goe(startDate.atStartOfDay());
}

private BooleanExpression createdAtLt(LocalDate endDate) {
return endDate == null ? null : consultation.createdAt.lt(endDate.plusDays(1).atStartOfDay());
}

private boolean hasText(String value) {
return value != null && !value.isBlank();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ALTER TABLE consultations
ADD COLUMN IF NOT EXISTS remark VARCHAR(1000);

ALTER TABLE consultations
DROP CONSTRAINT IF EXISTS ck_consultation_status;

ALTER TABLE consultations
ADD CONSTRAINT ck_consultation_status
CHECK (status IN ('PENDING', 'IN_PROGRESS', 'COMPLETED', 'CANCELLED'));