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
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,19 @@
* 규칙 3: 모든 원시값과 문자열을 포장한다.
* 규칙 5: 줄여쓰지 않는다(축약 금지).
* 규칙 8: 일급 콜렉션을 쓴다.

## Step4
* repo : https://github.com/trytocloud/java-lotto/tree/step4
* pr : https://github.com/code-squad/java-lotto/pull/63

### 요구사항
* 콘솔 UI 대신 웹 UI를 적용한다.
* 웹 UI를 적용할 HTML 템플릿은 fork한 저장소의 src/main/resources 디렉토리의 templates 디렉토리에 있다.
* 메인 페이지는 index.html 페이지에서 시작한다.

### 프로그래밍 요구사항
* 웹 UI를 적용할 때 기존 코드를 수정하지 않아야 한다.
* UI에 의존하지 않도록 구현하려면 어떻게 구현하는 것이 좋을 것인지 해결 방법을 찾는다.

### 참고 자료
* MUSTACHE MANUAL : https://mustache.github.io/mustache.5.html
2 changes: 1 addition & 1 deletion src/main/java/lotto/LottoGame.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ private LottoGame() {
private void start() {
int ticketTotalPrice = inputView.requestToInputTicketTotalPrice();
int manualTicketCount = inputView.requestToInputCountOfManualTicket();

LottoManualTicketRequest lottoManualTicketRequest = inputView.requestToInputManualTickets(manualTicketCount);

LottoCustomerTicket lottoCustomerTicket = LottoStore.buyLottoTicket(ticketTotalPrice, lottoManualTicketRequest);
resultView.printTickets(lottoCustomerTicket);

Expand Down
8 changes: 6 additions & 2 deletions src/main/java/lotto/LottoStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lotto.domain.LottoManualTicketRequest;
import lotto.domain.LottoTicket;
import lotto.util.TicketNumberParser;
import spark.utils.StringUtils;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -49,15 +50,18 @@ public static int countRandomTicket(int ticketTotalPrice, int manualTicketCount)
public static LottoCustomerTicket buyExplicitTickets(LottoManualTicketRequest lottoManualTicketRequest) {
List<LottoTicket> tickets = new ArrayList<>();
for (String plainTicket : lottoManualTicketRequest.getTicketRequests()) {
if (StringUtils.isEmpty(plainTicket)) {
continue;
}
tickets.add(buyExplicitTicket(plainTicket));
}
return new LottoCustomerTicket(tickets);
}

public static LottoCustomerTicket buyLottoTicket(int ticketTotalPrice, LottoManualTicketRequest lottoManualTicketRequest) {
int randomTotalCount = LottoStore.countRandomTicket(ticketTotalPrice, lottoManualTicketRequest.getTicketRequests().size());
LottoCustomerTicket randomTickets = LottoStore.buyRandomTickets(randomTotalCount);
LottoCustomerTicket explicitTickets = LottoStore.buyExplicitTickets(lottoManualTicketRequest);
int randomTotalCount = LottoStore.countRandomTicket(ticketTotalPrice, explicitTickets.getTickets().size());
LottoCustomerTicket randomTickets = LottoStore.buyRandomTickets(randomTotalCount);
return new LottoCustomerTicket(randomTickets, explicitTickets);
}
}
4 changes: 2 additions & 2 deletions src/main/java/lotto/WinningLotto.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ private void validateDuplicatedNumbers() {
set.add(bonusNumber);

if (set.size() != LottoConstants.NUMBER_COUNT + 1) {
throw new IllegalArgumentException("successNumbers=" + successNumbers.toString()
throw new IllegalArgumentException("numbers are duplicated. successNumbers=" + successNumbers.toString()
+ ", bonusNumber=" + bonusNumber);
}
}

private void validateCountOfLottoNumbers() {
if (successNumbers.size() != LottoConstants.NUMBER_COUNT) {
throw new IllegalArgumentException("successNumbers=" + successNumbers.toString());
throw new IllegalArgumentException("successNumbers is invalid. successNumbers=" + successNumbers.toString());
}
}

Expand Down
77 changes: 77 additions & 0 deletions src/main/java/lotto/controller/LottoGameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package lotto.controller;
import static spark.Spark.*;

import java.util.HashMap;
import java.util.Map;

import lotto.LottoStore;
import lotto.WinningLotto;
import lotto.domain.LottoCustomerTicket;
import lotto.domain.LottoManualTicketRequest;
import lotto.domain.LottoResult;
import spark.ModelAndView;
import spark.Request;
import spark.template.handlebars.HandlebarsTemplateEngine;

public class LottoGameController {
private static final String indexPath = "/index.html";
public static void main(String[] args) {
port(8080);

get("/index", (req, res) -> {
Map<String, Object> model = new HashMap<>();
model.put("errorMessage", "");
return render(model, indexPath);
});

post("/buyLotto", (req, res) -> {
Map<String, Object> model = new HashMap<>();
try {
LottoCustomerTicket lottoCustomerTicket = makeLottoCustomerTicket(req.queryParams("inputMoney"), req.queryParams("manualNumber"));

model.put("countMessage", lottoCustomerTicket.showCountMessage());
model.put("ticketMessage", lottoCustomerTicket.showTicketMessages());
model.put("lottoCustomerTicket", lottoCustomerTicket);
model.put("lottoCustomerTicketStr", lottoCustomerTicket.toString());
} catch (Exception e) {
model.put("errorMessage", "아까 발생한 오류는.. " + e.getMessage());
e.printStackTrace();
return render(model, indexPath);
}
return render(model, "/show.html");
});

post("/matchLotto", (req, res) -> {
Map<String, Object> model = new HashMap<>();
try {
WinningLotto winningLotto = new WinningLotto(req.queryParams("winningNumber"), req.queryParams("bonusNumber"));
LottoResult lottoResult = makeLottoResult(req, winningLotto);

model.put("profitRatioResultMessage", lottoResult.showProfitRatioResultMessage());
model.put("resultMessages", lottoResult.showResultMessages());
} catch (Exception e) {
model.put("errorMessage", "아까 발생한 오류는.. " + e.getMessage());
e.printStackTrace();
return render(model, indexPath);
}
return render(model, "/result.html");
});

}

private static LottoResult makeLottoResult(Request req, WinningLotto winningLotto) {
LottoManualTicketRequest lottoManualTicketRequest = new LottoManualTicketRequest(req.queryParams("lottoCustomerTicketStr"));
LottoCustomerTicket lottoCustomerTicket = LottoStore.buyExplicitTickets(lottoManualTicketRequest);
return lottoCustomerTicket.matchTickets(winningLotto);
}

private static LottoCustomerTicket makeLottoCustomerTicket(String inputMoneyStr, String manualNumberStr) {
LottoManualTicketRequest lottoManualTicketRequest = new LottoManualTicketRequest(manualNumberStr);
int ticketTotalPrice = Integer.parseInt(inputMoneyStr);
return LottoStore.buyLottoTicket(ticketTotalPrice, lottoManualTicketRequest);
}

private static String render(Map<String, Object> model, String templatePath) {
return new HandlebarsTemplateEngine().render(new ModelAndView(model, templatePath));
}
}
2 changes: 2 additions & 0 deletions src/main/java/lotto/domain/LottoConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ public class LottoConstants {
public static final int LAST_NUMBER = 45;
public static final int NUMBER_COUNT = 6;
public static final int UNIT_PRICE = 1000;
public static final String NEW_LINE = "\r\n";

}
17 changes: 12 additions & 5 deletions src/main/java/lotto/domain/LottoCustomerTicket.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

import lotto.WinningLotto;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

public class LottoCustomerTicket {
private List<LottoTicket> tickets;
Expand All @@ -26,7 +23,7 @@ public LottoCustomerTicket(LottoCustomerTicket customerRandomTickets, LottoCusto
this.randomTicketCount = randomTickets.size();
this.explicitTicketCount = explicitTickets.size();
}

public LottoResult matchTickets(WinningLotto winningLotto) {
Map<LottoPrize, Integer> lottoPrizeResults = new HashMap<>();
for (LottoPrize lottoPrize : LottoPrize.values()) {
Expand Down Expand Up @@ -55,4 +52,14 @@ public List<String> showTicketMessages() {
public List<LottoTicket> getTickets() {
return tickets;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (LottoTicket ticket : tickets) {
sb.append(ticket.toPlainString());
sb.append(LottoConstants.NEW_LINE);
}
return sb.toString();
}
}
5 changes: 5 additions & 0 deletions src/main/java/lotto/domain/LottoManualTicketRequest.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package lotto.domain;

import java.util.Arrays;
import java.util.List;

public class LottoManualTicketRequest {
private List<String> ticketRequests;

public LottoManualTicketRequest(String ticketRequestsWithNewLine) {
this.ticketRequests = Arrays.asList(ticketRequestsWithNewLine.split(LottoConstants.NEW_LINE));
}

public LottoManualTicketRequest(List<String> ticketRequests) {
this.ticketRequests = ticketRequests;
}
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/lotto/domain/LottoNumber.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ public static LottoNumber of(int number) {
}

public static LottoNumber of(String numberString) {
return new LottoNumber(Integer.parseInt(numberString));
try {
return new LottoNumber(Integer.parseInt(numberString));
} catch (NumberFormatException e) {
throw new IllegalArgumentException("LottoNumber is invalid, LottoNumber=" + numberString, e);
}
}

private void validate(int number) {
Expand Down
15 changes: 14 additions & 1 deletion src/main/java/lotto/domain/LottoResult.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package lotto.domain;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class LottoResult {
Expand Down Expand Up @@ -40,10 +42,21 @@ private BigInteger calculateTotalProfit() {
return totalProfit;
}

public List<String> showResultMessages() {
List<String> messages = new ArrayList<>();
for (LottoPrize lottoPrize : LottoPrize.values()) {
if (LottoPrize.NONE.equals(lottoPrize)) {
continue;
}
messages.add(showResultMessage(lottoPrize));
}
return messages;
}

public String showResultMessage(LottoPrize prize) {
return prize.showMessage() +
"- " +
lottoPrizeResults.get(prize) +
lottoPrizeResults.getOrDefault(prize, 0) +
"개";
}

Expand Down
16 changes: 12 additions & 4 deletions src/main/java/lotto/domain/LottoTicket.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@ public class LottoTicket {

public LottoTicket(List<LottoNumber> numbers) {
this.numbers = numbers;

if (numbers.size() != LottoConstants.NUMBER_COUNT) {
throw new IllegalArgumentException("the count of lotto number is wrong, count=" + numbers.size());
}
}

@Override
public String toString() {
return "[" +
numbers.stream()
.sorted()
.map(Object::toString)
.collect(Collectors.joining(", "))
toPlainString()
+ "]";
}

public String toPlainString() {
return numbers.stream()
.sorted()
.map(Object::toString)
.collect(Collectors.joining(", "));
}

public boolean match(LottoNumber successNumber) {
return numbers.contains(successNumber);
}
Expand Down
7 changes: 4 additions & 3 deletions src/main/resources/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,18 @@
<div class="col-md-4">
<form class="form-lottoGame" method="post" action="/buyLotto">
<h2 class="text-center">로또 게임</h2>
<h5 class="text-center">{{errorMessage}}</h5>
<div class="input-group">
<div class="input-group-addon">₩</div>
<input type="number" id="inputMoney" class="form-control"
name="inputMoney" placeholder="금액 입력" required autofocus>
</div>
<div class="form-show-div" class="form-group">
<h2>수동 구매 번호</h2>
예) 1,2,3,4,5,6(한 라인에 6개를 입력해주세요.)
예) 1, 2, 3, 4, 5, 6(한 라인에 6개를 입력해주세요.)
<textarea class="form-control" rows="3" name="manualNumber"
placeholder="1,2,3,4,5,6
1,2,3,4,5,6"></textarea>
placeholder="1, 2, 3, 4, 5, 6
1, 2, 3, 4, 5, 6"></textarea>
</div>
<div class="submit-button">
<button class="btn btn-lg btn-primary btn-block" type="submit">로또
Expand Down
17 changes: 5 additions & 12 deletions src/main/resources/templates/result.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
</head>
<body>

<form class="form-result" action="/">
<form class="form-result" action="/index">
<div class="submit-button">
<button class="btn btn-lg btn-primary btn-block" type="submit">다시
하기</button>
Expand All @@ -72,24 +72,17 @@
<th><h3 class="text-center">당첨 통계</h3></th>
</thead>
<tbody>
{{#resultMessages}}
<tr>
<th>3개 일치 (5000원)- 3개</th>
</tr>
<tr>
<th>4개 일치 (50000원)- 1개</th>
</tr>
<tr>
<th>5개 일치 (1500000원)- 0개</th>
</tr>
<tr>
<th>5개 일치, 보너스 볼 일치(30000000원)- 0개</th>
<th>{{this}}</th>
</tr>
{{/resultMessages}}
<tr>
<th>6개 일치 (2000000000원)- 0개</th>
</tr>
</tbody>
<tfoot>
<th><h4 class="text-center">총 수익률은 20%입니다.</h4></th>
<th><h4 class="text-center">{{profitRatioResultMessage}}</h4></th>
</tfoot>
</table>
</pre>
Expand Down
Loading