Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
tlsaudwl committed Jun 9, 2024
2 parents 908cee4 + c0624a9 commit 997c25a
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 107 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
package com.project.hana_piece.account.controller;

import com.project.hana_piece.account.dto.AccountAutoDebitAdjustGetResponse;
import com.project.hana_piece.account.dto.AccountAutoDebitAdjustUpsertRequest;
import com.project.hana_piece.account.dto.AccountGetResponse;
import com.project.hana_piece.account.dto.AccountMonthTransactionGetResponse;
import com.project.hana_piece.account.dto.AccountSalaryGetResponse;
import com.project.hana_piece.account.dto.AccountSavingGetResponse;
import com.project.hana_piece.account.dto.AccountTransactionGetResponse;
import com.project.hana_piece.account.dto.AccountTypeRegRequest;
import com.project.hana_piece.account.dto.AccountUpsertResponse;
import com.project.hana_piece.account.dto.UserGoalAccountGetResponse;
import com.project.hana_piece.account.dto.*;
import com.project.hana_piece.account.service.AccountService;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -90,6 +81,12 @@ public ResponseEntity<List<AccountAutoDebitAdjustGetResponse>> findAccountAutoDe
return ResponseEntity.ok(response);
}

@GetMapping("/auto-debit/suggestions/{type}")
public ResponseEntity<AccountAutoDebitSuggestGetResponse> findAccountAutoDebitSuggest(@AuthenticationPrincipal Long userId, @PathVariable String type){
AccountAutoDebitSuggestGetResponse response = accountService.findAccountAutoDebitSuggest(userId, type);
return ResponseEntity.ok(response);
}

@PostMapping("/auto-debit/adjust")
public ResponseEntity<Void> updateAccountAutoDebitAdjust(@RequestBody AccountAutoDebitAdjustUpsertRequest request) {
accountService.updateAccountAutoDebitAdjust(request);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.project.hana_piece.account.dto;


public record AccountAutoDebitSuggestGetResponse (int life, int reserve, int saving){
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
package com.project.hana_piece.account.service;

import static com.project.hana_piece.account.domain.AccountType.*;
import static com.project.hana_piece.account.domain.AccountType.isParkingAccountType;
import static com.project.hana_piece.account.util.AccountNumberGenerator.generateAccountNumber;

import com.project.hana_piece.account.domain.Account;
import com.project.hana_piece.account.domain.AccountAutoDebit;
import com.project.hana_piece.account.domain.AccountPaymentType;
import com.project.hana_piece.account.domain.AccountTransaction;
import com.project.hana_piece.account.domain.AccountTransactionType;
import com.project.hana_piece.account.domain.AccountType;
import com.project.hana_piece.account.dto.AccountAutoDebitAdjustGetResponse;
import com.project.hana_piece.account.dto.AccountAutoDebitAdjustUpsertRequest;
import com.project.hana_piece.account.dto.AccountDailyTransactionGetResponse;
import com.project.hana_piece.account.dto.AccountGetResponse;
import com.project.hana_piece.account.dto.AccountMonthTransactionGetResponse;
import com.project.hana_piece.account.dto.AccountSalaryGetResponse;
import com.project.hana_piece.account.dto.AccountSavingGetResponse;
import com.project.hana_piece.account.dto.AccountTransactionGetResponse;
import com.project.hana_piece.account.dto.AccountTypeRegRequest;
import com.project.hana_piece.account.dto.AccountUpsertResponse;
import com.project.hana_piece.account.dto.UserGoalAccountGetResponse;
import com.google.gson.JsonObject;
import com.project.hana_piece.account.domain.*;
import com.project.hana_piece.account.dto.*;
import com.project.hana_piece.account.exception.AccountAutoDebitNotFoundException;
import com.project.hana_piece.account.exception.AccountInvalidException;
import com.project.hana_piece.account.exception.AccountNotFoundException;
Expand All @@ -31,23 +13,29 @@
import com.project.hana_piece.account.repository.AccountTransactionRepository;
import com.project.hana_piece.account.repository.AccountTransactionRepositoryCustom;
import com.project.hana_piece.common.exception.ValueInvalidException;
import com.project.hana_piece.common.util.JsonUtil;
import com.project.hana_piece.goal.domain.UserGoal;
import com.project.hana_piece.goal.exception.UserGoalNotFoundException;
import com.project.hana_piece.goal.repository.UserGoalRepository;
import com.project.hana_piece.user.domain.User;
import com.project.hana_piece.user.exception.UserInvalidException;
import com.project.hana_piece.user.exception.UserNotFoundException;
import com.project.hana_piece.user.repository.UserRepository;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.reactive.function.client.WebClient;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.project.hana_piece.account.domain.AccountType.*;
import static com.project.hana_piece.account.util.AccountNumberGenerator.generateAccountNumber;

@Service
@RequiredArgsConstructor
Expand All @@ -62,6 +50,8 @@ public class AccountService {
private final UserRepository userRepository;
private final UserGoalRepository userGoalRepository;

private final JsonUtil jsonUtil;

public AccountUpsertResponse saveAccount(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new UserNotFoundException(userId));
Expand Down Expand Up @@ -227,6 +217,35 @@ public List<AccountAutoDebitAdjustGetResponse> findAccountAutoDebitAdjust(Long u
return autoDebitAccountList.stream().map(AccountAutoDebitAdjustGetResponse::fromProjection).toList();
}

public AccountAutoDebitSuggestGetResponse findAccountAutoDebitSuggest(Long userId, String type){
WebClient webClient = WebClient.builder()
.baseUrl("http://54.180.220.88:5000")
.build();

String endpoint = "";
if(type.equals("init")){
endpoint = "/first_calc/"+userId;
} else if(type.equals("lux")){
endpoint = "/second_calc/"+userId+"/lux";
} else if(type.equals("save")){
endpoint = "/second_calc/"+userId+"/save";
}

String responseBody = webClient.get()
.uri(endpoint)
.retrieve()
.bodyToMono(String.class)
.block();

JsonObject jsonObject = jsonUtil.toJson(responseBody);
JsonObject resultData = jsonUtil.extractProperty(jsonObject, "result_data", JsonObject.class);
int life = jsonUtil.extractProperty(resultData, "life", Integer.class);
int reserve = jsonUtil.extractProperty(resultData, "reserve", Integer.class);
int saving = jsonUtil.extractProperty(resultData, "saving", Integer.class);

return new AccountAutoDebitSuggestGetResponse(life, reserve, saving);
}

public void updateAccountAutoDebitAdjust(AccountAutoDebitAdjustUpsertRequest request) {
Long savingId = request.savingAccountAutoDebitId();
Long lifeId = request.lifeAccountAutoDebitId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static com.project.hana_piece.ai.vo.GeminiResponseField.TEXT;

import com.google.gson.JsonObject;
import com.project.hana_piece.account.service.AccountService;
import com.project.hana_piece.ai.dto.GeminiCallRequest;
import com.project.hana_piece.ai.dto.GeminiCallResponse;
import com.project.hana_piece.ai.exception.GeminiNetworkIOException;
Expand All @@ -11,6 +12,8 @@
import com.project.hana_piece.common.exception.ValueInvalidException;
import com.project.hana_piece.common.util.JsonUtil;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
Expand All @@ -26,6 +29,7 @@
@RequiredArgsConstructor
public class AiServiceImpl implements AiService{

private static final Logger logger = LoggerFactory.getLogger(AiServiceImpl.class);
private final JsonUtil jsonUtil;

@Value("${ai.gemini.base-url}")
Expand All @@ -51,6 +55,7 @@ public GeminiCallResponse callGenerativeLanguageApi(GeminiPrompt geminiPrompt) {
try {
GeminiCallRequest geminiCallRequest = GeminiCallRequest.fromPrompt(geminiPrompt);
String requestBody = jsonUtil.toJsonString(geminiCallRequest);
logger.info("[Gemini AI Prompt] - " + geminiPrompt.getTotalPrompt());

String geminiApiResponseString = webClient.post()
.contentType(MediaType.APPLICATION_JSON)
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/com/project/hana_piece/ai/vo/GeminiPrompt.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ public synchronized String getTotalPrompt() {
@Builder
public GeminiPrompt(String requests, String constraints, String responseFormat,
String exampleData) {
this.requests = "Requests: " + requests + "\n";
this.constraints = "Constraints: " + constraints + "\n";
this.responseFormat = "ResponseFormat: " + responseFormat + "\n";
this.exampleData = "ExampleData: "+ exampleData + "\n";
this.requests = "[Requests] " + requests + "\n";
this.constraints = "[Constraints] " + constraints + "\n";
this.responseFormat = "[ResponseFormat] " + responseFormat + "\n";
this.exampleData = "[ExampleData] "+ exampleData + "\n";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
public UrlBasedCorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// TODO CORS 설정 변경 필요
config.addAllowedOrigin("http://localhost:5173");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import com.project.hana_piece.ai.service.AiService;
import com.project.hana_piece.ai.vo.GeminiPrompt;
import com.project.hana_piece.goal.domain.Apartment;
import com.project.hana_piece.goal.domain.UserGoal;
import com.project.hana_piece.goal.dto.ApartmentGetResponse;
import com.project.hana_piece.goal.dto.ApartmentPricePredictRequest;
import com.project.hana_piece.goal.dto.ApartmentPricePredictResponse;
import com.project.hana_piece.goal.repository.ApartmentRepository;
import com.project.hana_piece.product.domain.EnrolledProduct;
import com.project.hana_piece.product.domain.Product;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

Expand All @@ -28,15 +31,34 @@ public List<ApartmentGetResponse> getAllApartments() {
}

public ApartmentPricePredictResponse predictApartmentPrice(ApartmentPricePredictRequest request) {
GeminiPrompt geminiPrompt = buildPromptMessage(request);


String prompt = String.format("%d개월 뒤 가장 최근 거래가가 %d억인 %s %s %d평의 가격을 선형 회귀 모델을 이용해 오차범위 50퍼센트 가격 이내에서 중간 시나리오로 최대한 정확히 예측해서 %d 형식으로 가격만 알려줘",
request.duration(), request.price(), request.region(), request.apartmentNm(), request.area(), request.price());

GeminiPrompt geminiPrompt = GeminiPrompt.builder().requests(prompt).build();
GeminiCallResponse response = aiService.callGenerativeLanguageApi(geminiPrompt);

long messageLong = Long.parseLong(response.message());
long messageLong = Long.parseLong(response.message().trim());
return new ApartmentPricePredictResponse(messageLong);
}

private GeminiPrompt buildPromptMessage(ApartmentPricePredictRequest dto) {
StringBuilder requests = new StringBuilder();
requests.append("아래 정보를 바탕으로 미래의 아파트 가격을 예측해줘\n")
.append("최근 거래가: " + dto.price() + "원\n")
.append("지역: " + dto.area() + "\n")
.append("아파트 이름: " + dto.apartmentNm() + "\n")
.append("평수: " + dto.area() + "평\n")
.append("예측 대상 미래: " + dto.duration() + "개월 후"+"\n");

StringBuilder constraints = new StringBuilder();
constraints.append("선형 회귀 모델을 이용해 오차범위 50퍼센트 가격 이내에서 중간 시나리오로 최대한 정확히 예측해줘\n")
.append("짧은 기간에는 비용에 큰 차이가 없도록 해줘\n")
.append("대한민국의 경제 상황과 국내 정세와 부동산 상황을 파악해서 합리적인 가격을 예측해줘\n");

String responseFormat = "한국 화폐 단위인 원 단위로 가격(숫자)만 공백없이 응답해줘";

return GeminiPrompt.builder()
.requests(requests.toString())
.constraints(constraints.toString())
.responseFormat(responseFormat)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.util.List;

public interface EnrolledProductRepository extends JpaRepository<EnrolledProduct, Long> {
List<EnrolledProduct> findByUserGoalUserGoalId(Long userGoalId);
List<EnrolledProduct> findByUserGoalUserGoalId(Long userId);

boolean existsByProductAndUserGoal(Product product, UserGoal userGoal);
}
Loading

0 comments on commit 997c25a

Please sign in to comment.