Skip to content
Open
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
@@ -0,0 +1,80 @@
package swyp_11.ssubom.domain.topic.controller;

import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import swyp_11.ssubom.domain.topic.dto.*;
import swyp_11.ssubom.domain.topic.entity.Status;
import swyp_11.ssubom.domain.topic.entity.Topic;
import swyp_11.ssubom.domain.topic.service.TopicAIService;
import swyp_11.ssubom.domain.topic.service.TopicGenerationService;
import swyp_11.ssubom.domain.topic.service.TopicService;
import swyp_11.ssubom.global.response.ApiResponse;

import java.time.LocalDate;
import java.util.List;

@Tag(name = "Admin 페이지전용 ", description = " topic 관련 admin API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/admin")
public class AdminController {
private final TopicService topicService;
private final TopicGenerationService topicGenerationService;

@PostMapping("/topic/generation")
public ApiResponse<Void> topicGeneration(){
topicGenerationService.generateTopics();
return ApiResponse.success(null,"AD0001","관리자 질문 자동 생성 성공");
}

@PostMapping("/topic/generation/{categoryId}")
public ApiResponse<TodayTopicResponseDto> createTopic(@PathVariable Long categoryId, @RequestBody TopicCreationRequest request) {
Topic savedTopic = topicService.generateTopicForCategory(
categoryId,
request.getTopicName(),
request.getTopicType()
);
TodayTopicResponseDto dto = TodayTopicResponseDto.fromTopic(savedTopic);
return ApiResponse.success(dto,"AD0002","관리자 질문 생성 성공");
}

@PatchMapping("/topic/{topicId}")
public ApiResponse<TodayTopicResponseDto> updateTopic(@PathVariable Long topicId, @RequestBody TopicUpdateRequest request) {
Topic savedTopic = topicService.updateTopic(topicId, request);
TodayTopicResponseDto dto = TodayTopicResponseDto.fromTopic(savedTopic);
return ApiResponse.success(dto,"AD0003","관리자 질문 수정 성공");
}

@DeleteMapping("/topic/{topicId}")
public ApiResponse<Void> deleteTopic(@PathVariable Long topicId) {
topicService.deleteTopic(topicId);
return ApiResponse.success(null);
}


@GetMapping("/topics")
public ApiResponse<AdminTopicListResponse> getAdminTopics(@RequestParam(required = false ,defaultValue = "ALL") String mode , @RequestParam(required = false)Long categoryId) {
return ApiResponse.success(topicService.getAdminTopics(mode,categoryId),"AD0004","관리자 질문 조회 성공");

}

@PatchMapping("/topic/{topicId}/status")
public ApiResponse<Void> updateTopicStatus(@PathVariable Long topicId, @RequestParam Status status){
topicService.updateTopicStatus(topicId,status);
return ApiResponse.success(null,"AD0005","질문 상태 변경 성공");
}

@PatchMapping("/topics/{topicId}/reservation")
public ApiResponse<Void> updateReservation(
@PathVariable Long topicId,
@RequestParam(required = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
LocalDate usedAt
) {
topicService.updateReservation(topicId, usedAt);
return ApiResponse.success(null, "AD0006", "예약 변경 성공");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import swyp_11.ssubom.domain.topic.dto.HomeResponse;
import swyp_11.ssubom.domain.topic.dto.TodayTopicResponseDto;
import swyp_11.ssubom.domain.topic.dto.TopicListResponse;
import swyp_11.ssubom.domain.topic.dto.*;
import swyp_11.ssubom.domain.topic.entity.Topic;
import swyp_11.ssubom.domain.topic.service.TopicGenerationService;
import swyp_11.ssubom.domain.topic.service.TopicService;
import swyp_11.ssubom.domain.user.dto.CustomOAuth2User;
import swyp_11.ssubom.global.error.BusinessException;
Expand All @@ -26,7 +26,7 @@
@RequiredArgsConstructor
public class CategoryController {
private final TopicService topicService;

private final TopicGenerationService topicGenerationService;
@Operation(
summary = "카테고리 오늘의 질문 조회 API",
description = """
Expand Down Expand Up @@ -83,4 +83,6 @@ public ResponseEntity<ApiResponse<HomeResponse>> getHome(@AuthenticationPrincipa
);
return ResponseEntity.ok(response);
}


}
35 changes: 35 additions & 0 deletions src/main/java/swyp_11/ssubom/domain/topic/dto/AdminTopicDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package swyp_11.ssubom.domain.topic.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import swyp_11.ssubom.domain.topic.entity.Status;
import swyp_11.ssubom.domain.topic.entity.Topic;
import swyp_11.ssubom.domain.topic.entity.TopicType;

import java.time.LocalDate;

@Getter
@Builder
@AllArgsConstructor
public class AdminTopicDto {
private Long categoryId;
private String categoryName;
private Long topicId;
private String topicName;
private TopicType topicType;
private Status topicStatus;
private LocalDate usedAt;

public static AdminTopicDto from(Topic topic){
return AdminTopicDto.builder()
.categoryId(topic.getCategory().getId())
.categoryName(topic.getCategory().getName())
.topicId(topic.getId())
.topicName(topic.getName())
.topicType(topic.getTopicType())
.topicStatus(topic.getTopicStatus())
.usedAt(topic.getUsedAt())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package swyp_11.ssubom.domain.topic.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import swyp_11.ssubom.domain.topic.entity.Topic;
import swyp_11.ssubom.domain.topic.entity.TopicType;

import java.util.List;


@Getter
@Builder
public class AdminTopicListResponse {
private long totalCount;
private List<AdminTopicDto> topics;

public static AdminTopicListResponse of(List<AdminTopicDto> topics) {
return AdminTopicListResponse.builder()
.totalCount(topics.size())
.topics(topics)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package swyp_11.ssubom.domain.topic.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Getter
public class EmbeddingApiResponseDto {
private Status status;
private Result result;

@Getter
@NoArgsConstructor
public static class Status {
String code;
String message;
}

@Getter
@NoArgsConstructor
public static class Result {
private List<Double> embedding;
private Integer inputTokens;
}

public boolean isSuccess() {
return status !=null && "20000".equals(status.getCode());
}

public List<Double> getVector(){
return (result != null) ? result.getEmbedding() : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,14 @@ public static TodayTopicResponseDto of(String categoryName, String topicName,Lon
.topicType(topicType)
.build();
}

public static TodayTopicResponseDto fromTopic(Topic savedTopic) {
return TodayTopicResponseDto.builder()
.categoryName(savedTopic.getCategory().getName())
.topicName(savedTopic.getName())
.categoryId(savedTopic.getCategory().getId())
.topicId(savedTopic.getId())
.topicType(savedTopic.getTopicType())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package swyp_11.ssubom.domain.topic.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import swyp_11.ssubom.domain.topic.entity.TopicType;

@AllArgsConstructor
@Getter
public class TopicCreationRequest {
String topicName;
TopicType topicType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package swyp_11.ssubom.domain.topic.dto;

public record TopicGenerationResponse(
String topicName,
String topicType
){}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package swyp_11.ssubom.domain.topic.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Getter;
import swyp_11.ssubom.domain.topic.entity.TopicType;

import java.time.LocalDate;

@AllArgsConstructor
@Getter
public class TopicUpdateRequest { //
String topicName;
TopicType topicType;
Long categoryId;
}
5 changes: 5 additions & 0 deletions src/main/java/swyp_11/ssubom/domain/topic/entity/Status.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package swyp_11.ssubom.domain.topic.entity;

public enum Status {
PENDING,APPROVED
}
63 changes: 63 additions & 0 deletions src/main/java/swyp_11/ssubom/domain/topic/entity/Topic.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import swyp_11.ssubom.domain.common.BaseTimeEntity;

import java.time.LocalDate;
import java.util.List;

@Getter
@Entity
Expand Down Expand Up @@ -36,8 +37,70 @@ public class Topic extends BaseTimeEntity {
@Column(name = "topic_type", length = 20, nullable = false)
private TopicType topicType;

@Column(name = "embedding_json", columnDefinition = "TEXT")
private String embeddingJson;

@Enumerated(EnumType.STRING)
@Column(name = "topic_status")
private Status topicStatus;

@Transient
private List<Double> embedding;

public void use(LocalDate today) {
this.isUsed = true;
this.usedAt = today;
}

public void setCategory(Category category) {
this.category = category;
}

public void setTopicStatus(Status newStatus){
this.topicStatus=newStatus;
}
public void updateNameAndType(String topicName, TopicType topicType ) {
if (topicName != null) {
this.name = topicName;
}
if (topicType != null) {
this.topicType = topicType;
}
}

public void reserveAt(LocalDate date) {
this.usedAt = date;
}

public static Topic create(Category category, String topicName,TopicType topicType,List<Double> embedding) {
Topic topic = new Topic();
topic.category = category;
topic.name = topicName;
topic.topicType = topicType;
topic.embedding = embedding;
topic.topicStatus=Status.PENDING;
topic.embeddingJson = toJson(embedding);
topic.isUsed = false;
topic.usedAt = null;
return topic;
}
private static String toJson(List<Double> embedding) {
try {
return new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(embedding);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public List<Double> getEmbedding() {
if (embedding == null && embeddingJson != null) {
try {
embedding = new com.fasterxml.jackson.databind.ObjectMapper()
.readValue(embeddingJson, new com.fasterxml.jackson.core.type.TypeReference<List<Double>>() {});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return embedding;
}
}
Loading