Skip to content

Commit

Permalink
Merge pull request #71 from EUM-kmu/develop/v5
Browse files Browse the repository at this point in the history
Develop/v5
  • Loading branch information
J-Yong99 authored Apr 21, 2024
2 parents 716598a + 9ddb429 commit 0b3211d
Show file tree
Hide file tree
Showing 21 changed files with 293 additions and 45 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MY_SQL_PASSWORD = root
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<<<<<<< HEAD
HELP.md
.gradle
.env
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
Expand Down
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM eclipse-temurin:17-jdk-alpine
ARG JAR_FILE=./build/libs/*.jar
COPY ${JAR_FILE} /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
11 changes: 9 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ configurations {
repositories {
mavenCentral()
}

ext {
set('springCloudVersion', "2023.0.0")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
Expand All @@ -30,7 +37,7 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
implementation 'org.springframework.security:spring-security-crypto:5.7.1'

implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation "org.mockito:mockito-core:3.3.3"
}
Expand Down
42 changes: 42 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
version: '3'

services:
database:
container_name: mysql_db
image: mysql
restart: unless-stopped
environment:
MYSQL_DATABASE: bank
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: ${MY_SQL_PASSWORD}
TZ: 'Asia/Seoul'
ports:
- "3306:3306"
volumes:
- ./mysql/conf.d:/etc/mysql/conf.d # MySQL 설정 파일 위치
command:
- "mysqld"
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
networks:
- test_network

application:
container_name: docker-compose-test
restart: on-failure
build:
context: .
dockerfile: ./Dockerfile
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql_db:3306/bank
SPRING_DATASOURCE_USERNAME: "root"
SPRING_DATASOURCE_PASSWORD: ${MY_SQL_PASSWORD}
depends_on:
- database
networks:
- test_network

networks:
test_network:
4 changes: 4 additions & 0 deletions src/main/java/com/eum/bank/BankApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
@EnableJpaAuditing
@EnableDiscoveryClient
public class BankApplication {
public static void main(String[] args) {
SpringApplication.run(BankApplication.class, args);
Expand Down
39 changes: 39 additions & 0 deletions src/main/java/com/eum/bank/common/dto/request/DealRequestDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import lombok.Getter;
import lombok.Builder;

import java.util.List;

public class DealRequestDTO {
@Schema(description = "거래 생성 요청")
@Builder
Expand Down Expand Up @@ -101,6 +103,43 @@ public static class ExecuteDeal{
@Schema(description = "비밀번호", example = "1234")
@NotEmpty(message = "비밀번호를 입력해주세요.")
private String password;

// 수신 계좌번호 및 금액 리스트
@Schema(description = "수신 계좌번호 및 금액 리스트")
@NotEmpty(message = "수신 계좌번호 및 금액을 입력해주세요.")
private List<ReceiverAndAmount> receiverAndAmounts;

// 송금 총액
@Schema(description = "송금 총액", example = "10000")
@NotEmpty(message = "송금 총액을 입력해주세요.")
private Long totalAmount;
}

@Getter
public static class ReceiverAndAmount{
// 수신 계좌번호
@Schema(description = "수신 계좌번호", example = "123456789012")
@NotEmpty(message = "수신 계좌번호를 입력해주세요.")
private String receiverAccountNumber;
// 금액
@Schema(description = "금액", example = "10000")
@NotEmpty(message = "금액을 입력해주세요.")
private Long amount;
}

@Getter
public static class RollbackDeal {
// 거래ID
@Schema(description = "거래ID", example = "1")
@NotEmpty(message = "거래ID를 입력해주세요.")
private Long dealId;
// 송금자 계좌번호
@Schema(description = "송금자 계좌번호", example = "123456789012")
@NotEmpty(message = "송금자 계좌번호를 입력해주세요.")
private String senderAccountNumber;
// 비밀번호
@Schema(description = "비밀번호", example = "1234")
@NotEmpty(message = "비밀번호를 입력해주세요.")
private String password;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class AccountResponseDTO {
public static class Create {
@NotEmpty(message = "계좌 번호가 생성되어야 합니다.")
private String accountNumber;

}

// 계좌 조회 응답
Expand Down Expand Up @@ -69,4 +70,10 @@ public static Transfer batchTransfer(Deal deal, String receiverAccountNumber, St
.build();
}
}

@Builder
@Getter
public static class Block {
private String accountNumber;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,17 @@ public class DealResponseDTO {
public static class createDeal {
// 거래 id
private Long dealId;
// 송신자 계좌 번호
private String senderAccountNumber;
// 상태
private String status;
// 예치금
private Long deposit;
// 최대 인원수
private Long maxPeopleNum;
// 실제 모집인원수
private Long realPeopleNum;
// 게시글 ID
private Long postId;
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.eum.bank.common.dto.response;

import com.eum.bank.domain.account.entity.TotalTransferHistory;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

public class TotalTransferHistoryResponseDTO {

// 거래 내역 반환
@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor
public static class GetTotalTransferHistory {
private Long id;
private AccountResponseDTO.AccountInfo senderAccount;
Expand Down
24 changes: 22 additions & 2 deletions src/main/java/com/eum/bank/controller/AccountController.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public ResponseEntity<APIResponse<AccountResponseDTO.AccountInfo>> getAccountInf
@Parameter(description = "비밀번호", required = true)
@RequestParam
String password
) throws IllegalAccessException {
) {

APIResponse<AccountResponseDTO.AccountInfo> response = accountService.getAccount(accountNumber, password);

Expand All @@ -93,11 +93,31 @@ public ResponseEntity<APIResponse<AccountResponseDTO.AccountInfo>> getAccountInf
@PostMapping("/transfer")
public ResponseEntity<APIResponse<TotalTransferHistoryResponseDTO.GetTotalTransferHistory>> transfer(
@Schema(description = "송금 정보", required = true, implementation = AccountRequestDTO.Transfer.class)
@RequestBody AccountRequestDTO.Transfer transfer) throws IllegalAccessException {
@RequestBody AccountRequestDTO.Transfer transfer) {
AccountResponseDTO.Transfer transferResponse = AccountResponseDTO.Transfer.freeTransfer(transfer);

TotalTransferHistoryResponseDTO.GetTotalTransferHistory response = accountService.transfer(transferResponse);
return ResponseEntity.ok(APIResponse.of(SuccessCode.INSERT_SUCCESS, response));
}

// 계좌 동결
@Operation(summary = "계좌 동결", description = "계좌를 동결합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공"),
@ApiResponse(responseCode = "400", description = "요청 형식 혹은 요청 콘텐츠가 올바르지 않을 때,",content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "401", description = "비밀번호 인증 에러 또는 거래상태 비적합",content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "402", description = "금액 부족",content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "403", description = "block된 계좌", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "500", description = "서버 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@PatchMapping("/block")
public ResponseEntity<APIResponse<AccountResponseDTO.Block>> blockAccount(
@Schema(description = "계좌 번호", required = true)
@RequestParam
String accountNumber
) throws IllegalAccessException {
AccountResponseDTO.Block response = accountService.blockAccount(accountNumber);
return ResponseEntity.ok(APIResponse.of(SuccessCode.UPDATE_SUCCESS, response));
}

}
23 changes: 21 additions & 2 deletions src/main/java/com/eum/bank/controller/DealController.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.eum.bank.common.dto.response.DealResponseDTO;
import com.eum.bank.common.dto.response.DealResponseDTO.createDeal;
import com.eum.bank.common.dto.response.TotalTransferHistoryResponseDTO;
import com.eum.bank.common.enums.SuccessCode;
import com.eum.bank.domain.account.entity.Account;
import com.eum.bank.service.AccountService;
import com.eum.bank.service.DealService;
Expand Down Expand Up @@ -104,9 +105,27 @@ public ResponseEntity<APIResponse<DealResponseDTO.createDeal>> cancel(
@ApiResponse(responseCode = "500", description = "서버 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@PostMapping("/execute")
public ResponseEntity<APIResponse<List<TotalTransferHistoryResponseDTO.GetTotalTransferHistory>>> execute(
public ResponseEntity<APIResponse> execute(
@Schema(description = "거래 수행 정보", required = true, implementation = DealRequestDTO.ExecuteDeal.class)
@RequestBody DealRequestDTO.ExecuteDeal execute) {
return ResponseEntity.ok(dealService.executeDeal(execute));
dealService.executeDeal(execute);
return ResponseEntity.ok(APIResponse.of(SuccessCode.UPDATE_SUCCESS));
}

// 거래 상태 모집완료 -> 모집중 변경
@Operation(summary = "거래 상태 변경", description = "거래 상태를 변경합니다. 모집완료 -> 모집중 변경")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공"),
@ApiResponse(responseCode = "400", description = "요청 형식 혹은 요청 콘텐츠가 올바르지 않을 때,",content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "401", description = "비밀번호 인증 에러 또는 거래상태 비적합",content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "403", description = "block된 계좌", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "500", description = "서버 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@PatchMapping("/rollback")
public ResponseEntity<APIResponse> rollback(
@Schema(description = "거래 상태 변경 정보", required = true, implementation = DealRequestDTO.RollbackDeal.class)
@RequestBody DealRequestDTO.RollbackDeal rollback) {
dealService.changeDealToBeforeDeal(rollback);
return ResponseEntity.ok(APIResponse.of(SuccessCode.UPDATE_SUCCESS));
}
}
17 changes: 17 additions & 0 deletions src/main/java/com/eum/bank/controller/HealthCheckController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.eum.bank.controller;

import com.eum.bank.common.APIResponse;
import com.eum.bank.common.enums.SuccessCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HealthCheckController {
@GetMapping()
public ResponseEntity<APIResponse<Long>> healthCheck(){
Long result = 1L;
return ResponseEntity.ok(APIResponse.of(SuccessCode.INSERT_SUCCESS, result));
}

}
4 changes: 2 additions & 2 deletions src/main/java/com/eum/bank/domain/account/entity/Account.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ public static Account initializeAccount(String accountNumber, String password) {
return Account.builder()
.accountNumber(accountNumber)
.password(password)
.totalBudget(0L)
.availableBudget(0L)
.totalBudget(300L)
.availableBudget(300L)
.isBlocked(false)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
public class AccountTransferHistory extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

// 주인 계좌
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
public class TotalTransferHistory extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

// 송신자 계좌
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/eum/bank/domain/deal/entity/Deal.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
public class Deal extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

// 송신자 계좌
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
public class DealReceiver extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

// 거래 ID
Expand Down
19 changes: 18 additions & 1 deletion src/main/java/com/eum/bank/service/AccountService.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public APIResponse<AccountResponseDTO.AccountInfo> getAccount(String accountNumb
* @param amount
*/
public void validatePayment(Account account, Long amount) {
if (account.getAvailableBudget() < amount) {
if (account.getAvailableBudget() < amount && account.getTotalBudget() < amount) {
throw new InsufficientAmountException("Invalid amount");
}
}
Expand Down Expand Up @@ -182,4 +182,21 @@ public void changeAvailableBudget(Account account, Long amount, String transferT

account.setAvailableBudget(account.getAvailableBudget() + amount);
}

/**
* 계좌 동결
* @param accountNumber
* 아직 자세한 로직 없이 계좌번호 받아서 동결 기능
* @return
*/
public AccountResponseDTO.Block blockAccount(String accountNumber) {
Account account = this.validateAccount(accountNumber);

account.setIsBlocked(true);

return AccountResponseDTO.Block.builder()
.accountNumber(account.getAccountNumber())
.build();

}
}
Loading

0 comments on commit 0b3211d

Please sign in to comment.