├── .gitignore
├── .idea
├── .gitignore
├── misc.xml
├── modules.xml
└── vcs.xml
├── KH_HomeWork.iml
├── README.md
└── src
├── Ticket
├── AdminMenu.java
├── Concert.java
├── ConcertDataManager.java
├── ConcertFileManager.java
├── ConcertManager.java
├── Main.java
├── ReservationManager.java
├── SeatManager.java
├── TicketingService.java
├── User.java
├── UserManager.java
└── UserMenu.java
└── resource
├── concert_data.txt
├── reservation_data.txt
└── user_data.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | ### IntelliJ IDEA ###
2 | out/
3 | !**/src/main/**/out/
4 | !**/src/test/**/out/
5 |
6 | ### Eclipse ###
7 | .apt_generated
8 | .classpath
9 | .factorypath
10 | .project
11 | .settings
12 | .springBeans
13 | .sts4-cache
14 | bin/
15 | !**/src/main/**/bin/
16 | !**/src/test/**/bin/
17 |
18 | ### NetBeans ###
19 | /nbproject/private/
20 | /nbbuild/
21 | /dist/
22 | /nbdist/
23 | /.nb-gradle/
24 |
25 | ### VS Code ###
26 | .vscode/
27 |
28 | ### Mac OS ###
29 | .DS_Store
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/KH_HomeWork.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 콘서트 예메 Mini Project
2 | Java, File I/O
3 |
4 |
5 | ## 🖥️ 프로젝트 소개
6 | Java 객체지향의 개념과 파일 입출력을 공부하기 위해 만든 미니 프로젝트입니다.
7 |
8 |
9 | ## 🕰️ 개발 기간
10 | * 25.04.28일 - 22.04.30일
11 |
12 |
13 | ### ⚙️ 개발 환경
14 | - `Java 21`
15 | - **IDE** : IntelliJ
16 | - Java File I/O
17 |
18 | ## 📌 주요 기능
19 | #### 회원가입 및 로그인
20 | - 전화번호, ID 중복 방지
21 | - 일반 회원, 관리자 계정 분리
22 |
23 | #### 관리자 페이지
24 | - 회원 정보 조회
25 | - 콘서트 추가, 삭제, 정보 변경
26 |
27 | #### 콘서트 예매
28 | - 콘서트 목록 출력 및 에매
29 | - 좌석 선택 좌석 선택시 Array로 구현한 User Interface 제공
30 | - 예매 완료
31 |
32 | ## 실행 영상
33 | [](https://youtu.be/J0O3uLjEI48)
34 |
--------------------------------------------------------------------------------
/src/Ticket/AdminMenu.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.FileReader;
5 | import java.io.IOException;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.Scanner;
9 |
10 | public class AdminMenu {
11 |
12 | public static void run(Scanner scanner) {
13 | while (true) {
14 | System.out.println("\n===== 관리자 메뉴 =====");
15 | System.out.println("1. 회원 정보 출력");
16 | System.out.println("2. 콘서트 목록 수정");
17 | System.out.println("0. 프로그램 종료");
18 | System.out.print("메뉴 선택: ");
19 |
20 | String input = scanner.nextLine();
21 |
22 | switch (input) {
23 | case "1":
24 | displayUserList(scanner);
25 | break;
26 | case "2":
27 | ConcertManager.concertMenuManagement(scanner);
28 | break;
29 | case "0":
30 | System.out.println("프로그램을 종료합니다.");
31 | System.exit(0);
32 | default:
33 | System.out.println("잘못된 입력입니다. 다시 선택해주세요.");
34 | }
35 | }
36 | }
37 |
38 | private static void displayUserList(Scanner scanner) {
39 | System.out.println("=========회원정보 호출=========");
40 | List userList = new ArrayList<>();
41 |
42 | try (BufferedReader reader = new BufferedReader(new FileReader("src/resource/user_data.txt"))) {
43 | String line;
44 | while ((line = reader.readLine()) != null) {
45 | String[] parts = line.split(",", -1); // 빈 문자열도 포함
46 | userList.add(parts);
47 | }
48 | } catch (IOException e) {
49 | System.out.println("회원 정보를 불러오는 중 오류가 발생했습니다.");
50 | return;
51 | }
52 |
53 | int totalUsers = userList.size();
54 | int pageSize = 5;
55 | int totalPages = (int) Math.ceil(totalUsers / (double) pageSize);
56 |
57 | while (true) {
58 | System.out.println("\n총 회원 수: " + totalUsers + "명 / 총 페이지: " + totalPages + "페이지");
59 | System.out.print("확인할 페이지 번호 입력 (0 입력 시 관리자 메뉴로 이동): ");
60 | String input = scanner.nextLine();
61 |
62 | if (input.equals("0")) {
63 | break;
64 | }
65 |
66 | int page;
67 | try {
68 | page = Integer.parseInt(input);
69 | if (page < 1 || page > totalPages) {
70 | System.out.println("잘못된 페이지 번호입니다.");
71 | continue;
72 | }
73 | } catch (NumberFormatException e) {
74 | System.out.println("숫자를 입력해주세요.");
75 | continue;
76 | }
77 |
78 | int start = (page - 1) * pageSize;
79 | int end = Math.min(start + pageSize, totalUsers);
80 |
81 | System.out.println("\n===== 회원 정보 (" + page + "페이지) =====");
82 | for (int i = start; i < end; i++) {
83 | String[] user = userList.get(i);
84 | String name = user[0];
85 | String id = user[1];
86 | String maskedPw = "*".repeat(user[2].length());
87 | String phone = user[3];
88 | String concert = user.length > 4 ? user[4] : "";
89 | String seat = user.length > 5 ? user[5] : "";
90 |
91 | System.out.printf("[%d] 이름: %s | 아이디: %s | 비밀번호: %s | 전화번호: %s | 예매 공연: %s | 좌석: %s\n",
92 | i + 1, name, id, maskedPw, phone, concert, seat);
93 | }
94 | }
95 | }
96 |
97 |
98 | private static void displayConcertReport() {
99 | List concertList = new ArrayList<>();
100 |
101 | try (BufferedReader reader = new BufferedReader(new FileReader("src/resource/concert_data.txt"))) {
102 | String line;
103 | while ((line = reader.readLine()) != null) {
104 | String[] parts = line.split(",", -1);
105 | concertList.add(parts);
106 | }
107 | } catch (IOException e) {
108 | System.out.println("콘서트 정보를 불러오는 중 오류가 발생했습니다.");
109 | return;
110 | }
111 |
112 | System.out.println("\n================================ 콘서트 매출 보고서 ================================");
113 |
114 | // 최대 길이에 맞춰 포맷 지정
115 | String headerFormat = "| %-3s | %-14s | %-10s | %-7s | %-6s | %-11s |";
116 | String rowFormat = "| %-4d | %-16s | %-11s | %-9d | %-7d | %,12d원 |";
117 |
118 | // 헤더 출력
119 | System.out.printf(headerFormat, "번호", "콘서트 이름", "날짜", "잔여 좌석", "총 좌석", "총 판매 금액");
120 | System.out.println("\n|------|------------------|-------------|-----------|---------|---------------|");
121 |
122 | int index = 1;
123 | for (String[] concert : concertList) {
124 | String name = concert[0];
125 | String date = concert[1];
126 | int price = Integer.parseInt(concert[2]);
127 | int totalSeats = Integer.parseInt(concert[3]);
128 | int remainingSeats = Integer.parseInt(concert[4]);
129 | int totalSales = Integer.parseInt(concert[5]);
130 |
131 | // 데이터 출력
132 | System.out.printf(rowFormat, index++, name, date, remainingSeats, totalSeats, totalSales);
133 | System.out.println();
134 | }
135 |
136 | System.out.println("===============================================================================\n");
137 | }
138 |
139 | }
--------------------------------------------------------------------------------
/src/Ticket/Concert.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | import java.util.HashMap;
4 | import java.util.List;
5 | import java.util.ArrayList;
6 | import java.util.Map;
7 |
8 | public class Concert {
9 | private String name;
10 | private String date;
11 | private int price;
12 | private int totalSeats;
13 | private int remainingSeats;
14 | private List reservedSeats;
15 |
16 |
17 | public Concert(String name, String date, int price, int totalSeats, int remainingSeats, List reservedSeats) {
18 | this.name = name;
19 | this.date = date;
20 | this.price = price;
21 | this.totalSeats = totalSeats;
22 | this.remainingSeats = remainingSeats;
23 | this.reservedSeats = new ArrayList<>(reservedSeats); // 복사본 생성
24 | }
25 | private Map seatMap = new HashMap<>();
26 | // ⭐ Concert.java에 추가
27 |
28 | // 좌석 상태를 출력하는 메서드
29 | public void showSeatMap() {
30 | System.out.println("\n----- 좌석 현황 -----");
31 | for (String seat : seatMap.keySet()) {
32 | String status = seatMap.get(seat) ? "[예약됨]" : "[비어있음]";
33 | System.out.printf("%s %s\t", seat, status);
34 | }
35 | System.out.println("\n----------------------");
36 | }
37 |
38 | // 좌석 유효성 검사 (좌석 이름이 seatMap에 존재하는지)
39 | public boolean isValidSeat(String seat) {
40 | return seatMap.containsKey(seat);
41 | }
42 |
43 | // 해당 좌석이 이미 예약되었는지 확인
44 | public boolean isSeatReserved(String seat) {
45 | return seatMap.getOrDefault(seat, false);
46 | }
47 |
48 | // 좌석을 예약 처리 (비어있는 좌석이면 true로 설정)
49 | public void reserveSeat(String seat) {
50 | if (seatMap.containsKey(seat) && !seatMap.get(seat)) {
51 | seatMap.put(seat, true);
52 | }
53 | }
54 |
55 | public String getDate() {
56 | return date;
57 | }
58 |
59 | public void setDate(String date) {
60 | this.date = date;
61 | }
62 |
63 | public String getName() {
64 | return name;
65 | }
66 |
67 | public void setName(String name) {
68 | this.name = name;
69 | }
70 |
71 | public int getPrice() {
72 | return price;
73 | }
74 |
75 | public void setPrice(int price) {
76 | this.price = price;
77 | }
78 |
79 | public int getRemainingSeats() {
80 | return remainingSeats;
81 | }
82 |
83 | public void setRemainingSeats(int remainingSeats) {
84 | this.remainingSeats = remainingSeats;
85 | }
86 |
87 | public List getReservedSeats() {
88 | return reservedSeats;
89 | }
90 |
91 | public void setReservedSeats(List reservedSeats) {
92 | this.reservedSeats = reservedSeats;
93 | }
94 |
95 | public int getTotalSeats() {
96 | return totalSeats;
97 | }
98 |
99 | public void setTotalSeats(int totalSeats) {
100 | this.totalSeats = totalSeats;
101 | }
102 | // 생성자, getter/setter 생략
103 | }
--------------------------------------------------------------------------------
/src/Ticket/ConcertDataManager.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | import java.io.*;
4 | import java.util.*;
5 | import java.util.ArrayList;
6 |
7 | public class ConcertDataManager {
8 |
9 | private static final String CONCERT_FILE_PATH = "src/resource/concert_data.txt";
10 |
11 | // 콘서트 리스트 반환
12 | public static List loadConcertData() {
13 | List concertList = new ArrayList<>();
14 |
15 | try (BufferedReader reader = new BufferedReader(new FileReader(CONCERT_FILE_PATH))) {
16 | String line;
17 | while ((line = reader.readLine()) != null) {
18 | if (line.trim().isEmpty()) continue; // 빈 줄은 무시
19 |
20 | String[] parts = line.split("/");
21 | if (parts.length < 6) {
22 | System.out.println("잘못된 형식의 데이터: " + line);
23 | continue;
24 | }
25 |
26 | String name = parts[0];
27 | String date = parts[1];
28 | int price = Integer.parseInt(parts[2]);
29 | int totalSeats = Integer.parseInt(parts[3]);
30 | int remainingSeats = Integer.parseInt(parts[4]);
31 |
32 | List reservedSeats = new ArrayList<>();
33 | if (!parts[5].isEmpty()) {
34 | reservedSeats = Arrays.asList(parts[5].split(","));
35 | }
36 |
37 | Concert concert = new Concert(name, date, price, totalSeats, remainingSeats, reservedSeats);
38 | concertList.add(concert);
39 | }
40 | } catch (FileNotFoundException e) {
41 | System.out.println("콘서트 데이터 파일을 찾을 수 없습니다.");
42 | } catch (IOException e) {
43 | System.out.println("콘서트 데이터 파일 읽기 오류가 발생했습니다.");
44 | }
45 |
46 | return concertList;
47 | }
48 | }
--------------------------------------------------------------------------------
/src/Ticket/ConcertFileManager.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | import java.io.*;
4 | import java.util.ArrayList;
5 | import java.util.Arrays;
6 | import java.util.List;
7 |
8 | import static Ticket.UserManager.FILE_PATH;
9 |
10 | public class ConcertFileManager {
11 | private static final String CONCERT_FILE_PATH = "src/resource/concert_data.txt"; // 콘서트 정보 파일 경로
12 |
13 | public static List loadConcerts() {
14 | List concertList = new ArrayList<>();
15 |
16 | try (BufferedReader reader = new BufferedReader(new FileReader(CONCERT_FILE_PATH))) {
17 | String line;
18 | while ((line = reader.readLine()) != null) {
19 | String[] parts = line.split(",");
20 |
21 | if (parts.length >= 5) {
22 | String name = parts[0];
23 | String date = parts[1];
24 | int price = Integer.parseInt(parts[2]);
25 | int totalSeats = Integer.parseInt(parts[3]);
26 | int remainingSeats = Integer.parseInt(parts[4]);
27 |
28 | List reservedSeats = new ArrayList<>();
29 | if (parts.length > 5) {
30 | reservedSeats = Arrays.asList(parts[5].split("\\|"));
31 | // 예약된 좌석은 '|' 기준으로 구분
32 | }
33 |
34 | Concert concert = new Concert(name, date, price, totalSeats, remainingSeats, reservedSeats);
35 | concertList.add(concert);
36 | }
37 | }
38 | } catch (IOException e) {
39 | System.out.println("[오류] 콘서트 정보를 불러오는 중 문제가 발생했습니다: " + e.getMessage());
40 | }
41 |
42 | return concertList;
43 | }
44 | public static void saveConcerts(List concertList) {
45 | try (BufferedWriter bw = new BufferedWriter(new FileWriter(CONCERT_FILE_PATH))) {
46 | for (Concert c : concertList) {
47 | bw.write(c.getName() + "," + c.getDate() + "," + c.getPrice() + "," +
48 | c.getTotalSeats() + "," + c.getRemainingSeats() + "," +
49 | String.join("|", c.getReservedSeats()));
50 | bw.newLine();
51 | }
52 | } catch (IOException e) {
53 | System.out.println("[오류] 콘서트 파일 저장 실패: " + e.getMessage());
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/Ticket/ConcertManager.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | import java.io.*;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import java.util.Scanner;
7 |
8 | public class ConcertManager {
9 | Scanner scanner = new Scanner(System.in);
10 | public static void concertMenuManagement(Scanner scanner) {
11 | while (true) {
12 | System.out.println("\n==== 콘서트 목록 관리 ====");
13 | System.out.println("1. 콘서트 추가");
14 | System.out.println("2. 콘서트 삭제");
15 | System.out.println("3. 기존 콘서트 정보 수정");
16 | System.out.println("0. 뒤로가기");
17 | System.out.print(">> 선택: ");
18 |
19 | String input = scanner.nextLine();
20 | switch (input) {
21 | case "1":
22 | addConcert(scanner);
23 | break;
24 | case "2":
25 | deleteConcert(scanner);
26 | break;
27 | case "3":
28 | modifyConcert(scanner);
29 | break;
30 | case "0":
31 | return;
32 | default:
33 | System.out.println("잘못된 입력입니다.");
34 | }
35 | }
36 | }
37 |
38 | private static void addConcert(Scanner scanner) {
39 | System.out.println("\n==== 콘서트 추가 ====");
40 |
41 | System.out.print("콘서트 이름: ");
42 | String name = scanner.nextLine();
43 |
44 | System.out.print("콘서트 날짜 (예: 2025-06-15): ");
45 | String date = scanner.nextLine();
46 |
47 | System.out.print("콘서트 가격: ");
48 | int price = Integer.parseInt(scanner.nextLine());
49 |
50 | int totalSeats;
51 | while (true) {
52 | System.out.print("총 좌석 수 (10의 배수로 입력): ");
53 | totalSeats = Integer.parseInt(scanner.nextLine());
54 | if (totalSeats % 10 == 0) {
55 | break;
56 | } else {
57 | System.out.println("(주의)총 좌석 수는 반드시 10의 배수여야 합니다. 다시 입력해주세요.");
58 | }
59 | }
60 |
61 | int remainingSeats = totalSeats;
62 | int totalSales = 0;
63 |
64 | String concertData = String.format("%s,%s,%d,%d,%d,%d",
65 | name, date, price, totalSeats, remainingSeats, totalSales);
66 |
67 | try (BufferedWriter writer = new BufferedWriter(new FileWriter("src/resource/concert_data.txt", true))) {
68 | writer.write(concertData);
69 | writer.newLine();
70 | System.out.println("콘서트가 성공적으로 추가되었습니다.");
71 | } catch (IOException e) {
72 | System.out.println("콘서트 저장 중 오류 발생: " + e.getMessage());
73 | }
74 | }
75 |
76 | private static void deleteConcert(Scanner scanner) {
77 | List concertList = new ArrayList<>();
78 |
79 | try (BufferedReader reader = new BufferedReader(new FileReader("src/resource/concert_data.txt"))) {
80 | String line;
81 | while ((line = reader.readLine()) != null) {
82 | concertList.add(line);
83 | }
84 | } catch (IOException e) {
85 | System.out.println("콘서트 파일을 읽는 도중 오류가 발생했습니다.");
86 | return;
87 | }
88 |
89 | if (concertList.isEmpty()) {
90 | System.out.println("현재 등록된 콘서트가 없습니다.");
91 | return;
92 | }
93 |
94 | System.out.println("\n==== 삭제할 콘서트를 선택하세요 ====");
95 | for (int i = 0; i < concertList.size(); i++) {
96 | String[] parts = concertList.get(i).split(",");
97 | System.out.printf("%d. %s | 날짜: %s | 가격: %s원\n", i + 1, parts[0], parts[1], parts[2]);
98 | }
99 |
100 | System.out.print("삭제할 콘서트 번호 (0: 취소): ");
101 | String input = scanner.nextLine();
102 |
103 | try {
104 | int index = Integer.parseInt(input) - 1;
105 |
106 | if (index == -1) {
107 | System.out.println("삭제를 취소합니다.");
108 | return;
109 | }
110 |
111 | if (index < 0 || index >= concertList.size()) {
112 | System.out.println("잘못된 번호입니다.");
113 | return;
114 | }
115 |
116 | String removedConcert = concertList.remove(index);
117 |
118 | // 삭제 후 파일에 다시 저장
119 | try (BufferedWriter writer = new BufferedWriter(new FileWriter("src/resource/concert_data.txt"))) {
120 | for (String concert : concertList) {
121 | writer.write(concert);
122 | writer.newLine();
123 | }
124 | }
125 |
126 | System.out.println("콘서트가 성공적으로 삭제되었습니다: " + removedConcert.split(",")[0]);
127 |
128 | } catch (NumberFormatException e) {
129 | System.out.println("숫자로 입력해주세요.");
130 | } catch (IOException e) {
131 | System.out.println("파일 저장 중 오류가 발생했습니다.");
132 | }
133 | }
134 |
135 | public static void modifyConcert(Scanner scanner) {
136 | List concertList = new ArrayList<>();
137 |
138 | try (BufferedReader reader = new BufferedReader(new FileReader("src/resource/concert_data.txt"))) {
139 | String line;
140 | while ((line = reader.readLine()) != null) {
141 | concertList.add(line);
142 | }
143 | } catch (IOException e) {
144 | System.out.println("콘서트 파일을 읽는 중 오류 발생!");
145 | return;
146 | }
147 |
148 | if (concertList.isEmpty()) {
149 | System.out.println("등록된 콘서트가 없습니다.");
150 | return;
151 | }
152 |
153 | // 콘서트 목록 출력
154 | System.out.println("\n=== 수정할 콘서트를 선택하세요 ===");
155 | for (int i = 0; i < concertList.size(); i++) {
156 | String[] parts = concertList.get(i).split(",");
157 | System.out.printf("%d. %s | 날짜: %s | 가격: %s원\n", i + 1, parts[0], parts[1], parts[2]);
158 | }
159 |
160 | System.out.print("수정할 콘서트 번호 (0: 취소): ");
161 | String input = scanner.nextLine();
162 |
163 | try {
164 | int index = Integer.parseInt(input) - 1;
165 |
166 | if (index == -1) {
167 | System.out.println("수정을 취소합니다.");
168 | return;
169 | }
170 |
171 | if (index < 0 || index >= concertList.size()) {
172 | System.out.println("잘못된 번호입니다.");
173 | return;
174 | }
175 |
176 | String[] parts = concertList.get(index).split(",");
177 |
178 | System.out.println("\n수정할 항목을 선택하세요:");
179 | System.out.println("1. 콘서트 이름");
180 | System.out.println("2. 콘서트 날짜");
181 | System.out.println("3. 콘서트 가격");
182 | System.out.println("4. 총 좌석 수 (10의 배수만 입력 가능)");
183 | System.out.print("항목 번호: ");
184 | String fieldInput = scanner.nextLine();
185 |
186 | switch (fieldInput) {
187 | case "1":
188 | System.out.print("새 콘서트 이름: ");
189 | parts[0] = scanner.nextLine();
190 | break;
191 | case "2":
192 | System.out.print("새 콘서트 날짜 (예: 2025-06-20): ");
193 | parts[1] = scanner.nextLine();
194 | break;
195 | case "3":
196 | System.out.print("새 콘서트 가격: ");
197 | parts[2] = scanner.nextLine();
198 | break;
199 | case "4":
200 | System.out.print("새 총 좌석 수 (10의 배수): ");
201 | int newTotal = Integer.parseInt(scanner.nextLine());
202 | if (newTotal % 10 != 0) {
203 | System.out.println("총 좌석 수는 10의 배수여야 합니다!");
204 | return;
205 | }
206 | int reserved = Integer.parseInt(parts[3]) - Integer.parseInt(parts[4]);
207 | parts[3] = String.valueOf(newTotal);
208 | parts[4] = String.valueOf(newTotal - reserved); // 잔여좌석 수 업데이트
209 | break;
210 | default:
211 | System.out.println("잘못된 입력입니다.");
212 | return;
213 | }
214 |
215 | // 수정된 콘서트 정보 반영
216 | concertList.set(index, String.join(",", parts));
217 |
218 | try (BufferedWriter writer = new BufferedWriter(new FileWriter("src/resource/concert_data.txt"))) {
219 | for (String concert : concertList) {
220 | writer.write(concert);
221 | writer.newLine();
222 | }
223 | }
224 |
225 | System.out.println("콘서트 정보가 성공적으로 수정되었습니다.");
226 |
227 | } catch (NumberFormatException e) {
228 | System.out.println("숫자 형식이 올바르지 않습니다.");
229 | } catch (IOException e) {
230 | System.out.println("파일 저장 중 오류가 발생했습니다.");
231 | }
232 | }
233 | }
--------------------------------------------------------------------------------
/src/Ticket/Main.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | import java.util.Scanner;
4 |
5 | public class Main {
6 | public static void main(String[] args) {
7 | Scanner scanner = new Scanner(System.in);
8 | UserManager userManager = new UserManager();
9 |
10 | while (true) {
11 | System.out.println("\n==== 콘서트 예매 시스템 ====");
12 | System.out.println("1. 로그인");
13 | System.out.println("2. 회원가입");
14 | System.out.println("0. 종료");
15 | System.out.print("선택: ");
16 |
17 | String choice = scanner.nextLine();
18 |
19 | switch (choice) {
20 | case "1":
21 | if (userManager.login(scanner)) {
22 | System.out.println("---------");
23 | System.out.println("로그인 성공!");
24 | System.out.println("---------");
25 |
26 | // 관리자 전용 메뉴 진입
27 | if (UserManager.getLoggedInUser().getUsername().equals("admin")) {
28 | AdminMenu.run(scanner);
29 | } else {
30 | UserMenu.run(scanner, UserManager.getLoggedInUser());
31 | }
32 |
33 | } else {
34 | System.out.println("로그인 실패. 다시 시도해주세요.");
35 | }
36 | break;
37 |
38 | case "2":
39 | userManager.signUp(scanner);
40 | // 회원가입 완료 후 로그인 메뉴로 돌아가기 때문에 while 루프 유지
41 | break;
42 |
43 | case "0":
44 | System.out.println("프로그램을 종료합니다.");
45 | return;
46 |
47 | default:
48 | System.out.println("잘못된 입력입니다. 다시 선택해주세요.");
49 | }
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/Ticket/ReservationManager.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | import java.io.*;
4 | import java.util.*;
5 |
6 | public class ReservationManager {
7 | private static final String FILE_PATH = "resource/reservation_data.txt";
8 |
9 |
10 | Scanner scanner = new Scanner(System.in);
11 | public static void showAvailableConcerts(Scanner scanner, List concertList) {
12 | System.out.println("\n================= 예매 가능 콘서트 목록 =================");
13 | int index = 1;
14 | Map selectableConcerts = new HashMap<>();
15 |
16 | for (Concert concert : concertList) {
17 | if (concert.getRemainingSeats() > 0) {
18 | System.out.printf("%d. 콘서트명: %s | 날짜: %s | 가격: %,d원 | 잔여 좌석: %d석\n",
19 | index, concert.getName(), concert.getDate(), concert.getPrice(), concert.getRemainingSeats());
20 | selectableConcerts.put(index, concert);
21 | index++;
22 | }
23 | }
24 |
25 | if (selectableConcerts.isEmpty()) {
26 | System.out.println("현재 예매 가능한 콘서트가 없습니다.");
27 | return;
28 | }
29 |
30 | System.out.println("0. 뒤로가기");
31 | System.out.println("========================================================");
32 | System.out.print("예매할 콘서트 번호를 입력하세요: ");
33 |
34 | int choice;
35 | try {
36 | choice = Integer.parseInt(scanner.nextLine());
37 | } catch (NumberFormatException e) {
38 | System.out.println("잘못된 입력입니다. 숫자를 입력해주세요.");
39 | return;
40 | }
41 |
42 | if (choice == 0) {
43 | return;
44 | } else if (selectableConcerts.containsKey(choice)) {
45 | Concert selectedConcert = selectableConcerts.get(choice);
46 | // 다음 단계: 좌석 예매 페이지로 이동
47 | reserveSeat(scanner, selectedConcert);
48 | } else {
49 | System.out.println("잘못된 번호입니다.");
50 | }
51 | }
52 | public static void saveUserReservation(String userId, Concert concert, String seat) {
53 | try {
54 | // ⭐ 디렉토리 먼저 체크하고 없으면 생성
55 | File resourceDir = new File("src/resource");
56 | if (!resourceDir.exists()) {
57 | resourceDir.mkdirs(); // 폴더 생성
58 | }
59 |
60 | File file = new File("src/resource/reservation_data.txt");
61 | if (!file.exists()) {
62 | file.createNewFile(); // 파일 생성
63 | }
64 |
65 | System.out.println("[디버그] 예약 저장 시도: " + userId + "," + concert.getName() + "," + seat);
66 |
67 | BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));
68 | bw.write(userId + "," + concert.getName() + "," + concert.getDate() + "," +
69 | concert.getPrice() + "," + seat);
70 | bw.newLine();
71 | bw.close();
72 |
73 | System.out.println("[디버그] 예약 저장 성공!");
74 |
75 | } catch (IOException e) {
76 | System.out.println("[오류] 예약 정보 저장 실패: " + e.getMessage());
77 | e.printStackTrace(); // 예외 전체 출력
78 | }
79 | }
80 |
81 | public static void showUserReservation(String userId) {
82 | boolean found = false;
83 | System.out.println("\n===== 나의 예매 정보 =====");
84 |
85 | try (BufferedReader br = new BufferedReader(new FileReader(FILE_PATH))) {
86 | String line;
87 | while ((line = br.readLine()) != null) {
88 | String[] parts = line.split(",");
89 | if (parts.length == 5 && parts[0].equals(userId)) { // ⭐ userId로 예약 찾기
90 | System.out.println("공연명 : " + parts[1]);
91 | System.out.println("날짜 : " + parts[2]);
92 | System.out.printf("가격 : %,d원\n", Integer.parseInt(parts[3]));
93 | System.out.println("좌석 : " + parts[4]);
94 | System.out.println("-----------------------------");
95 | found = true;
96 | }
97 | }
98 | } catch (IOException e) {
99 | System.out.println("[오류] 예약 정보 로드 실패: " + e.getMessage());
100 | }
101 |
102 | if (!found) {
103 | System.out.println("[알림] 현재 예매한 내역이 없습니다.");
104 | }
105 | }
106 |
107 | public static void reserveSeat(Scanner scanner, Concert concert) {
108 | System.out.println("\n================= 좌석 선택 =================");
109 | concert.showSeatMap(); // 콘서트 객체에 좌석 보여주는 메서드가 있어야 함
110 |
111 | System.out.print("예약할 좌석을 입력하세요 (예: A1): ");
112 | String seat = scanner.nextLine().toUpperCase();
113 |
114 | if (!concert.isValidSeat(seat)) { // 좌석 유효성 검사
115 | System.out.println("[오류] 존재하지 않는 좌석입니다.");
116 | return;
117 | }
118 |
119 | if (concert.isSeatReserved(seat)) { // 이미 예약된 좌석
120 | System.out.println("[오류] 이미 예약된 좌석입니다.");
121 | return;
122 | }
123 |
124 | // 실제 예약
125 | concert.reserveSeat(seat);
126 |
127 | // 파일에 저장
128 | User user = UserManager.getLoggedInUser();
129 | if (user == null) {
130 | System.out.println("[오류] 로그인 정보가 없습니다. 다시 로그인 해주세요.");
131 | return;
132 | }
133 |
134 | saveUserReservation(user.getUsername(), concert, seat); // 기존 메서드 사용
135 | updateUserReservation(user.getUsername(), concert, seat); // ⭐ 추가할 user_data 업데이트
136 |
137 | System.out.println("[성공] 좌석 예약이 완료되었습니다!");
138 | }
139 | // ⭐ ReservationManager.java에 추가
140 | public static void updateUserReservation(String userId, Concert concert, String seat) {
141 | File userDataFile = new File("src/resource/user_data.txt");
142 | List updatedLines = new ArrayList<>();
143 |
144 | try (BufferedReader reader = new BufferedReader(new FileReader(userDataFile))) {
145 | String line;
146 | while ((line = reader.readLine()) != null) {
147 | String[] parts = line.split(",");
148 | if (parts.length >= 2 && parts[0].equals(userId)) {
149 | // 기존 정보에 예매 정보 추가
150 | StringBuilder updatedLine = new StringBuilder(line);
151 | updatedLine.append(",").append(concert.getName()).append("-").append(seat);
152 | updatedLines.add(updatedLine.toString());
153 | } else {
154 | updatedLines.add(line);
155 | }
156 | }
157 | } catch (IOException e) {
158 | System.out.println("[오류] 유저 데이터 읽기 실패: " + e.getMessage());
159 | e.printStackTrace();
160 | }
161 |
162 | try (BufferedWriter writer = new BufferedWriter(new FileWriter(userDataFile))) {
163 | for (String updatedLine : updatedLines) {
164 | writer.write(updatedLine);
165 | writer.newLine();
166 | }
167 | } catch (IOException e) {
168 | System.out.println("[오류] 유저 데이터 저장 실패: " + e.getMessage());
169 | e.printStackTrace();
170 | }
171 | }
172 |
173 | }
--------------------------------------------------------------------------------
/src/Ticket/SeatManager.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | import java.util.List;
4 |
5 | public class SeatManager {
6 |
7 | public static void printSeatMatrix(Concert concert) {
8 | List reserved = concert.getReservedSeats();
9 | int totalSeats = concert.getTotalSeats();
10 |
11 | int rows = (totalSeats + 9) / 10; // 10개씩 나누기
12 | char rowChar = 'A';
13 |
14 | for (int i = 0; i < rows; i++) {
15 | System.out.printf("%c ", rowChar);
16 | for (int j = 1; j <= 10; j++) {
17 | int seatNumber = i * 10 + j;
18 | if (seatNumber > totalSeats) break;
19 |
20 | String seatCode = rowChar + String.valueOf(j);
21 | if (reserved.contains(seatCode)) {
22 | System.out.print("[X] ");
23 | } else {
24 | System.out.printf("[%d] ", j);
25 | }
26 | }
27 | System.out.println();
28 | rowChar++;
29 | }
30 | }
31 |
32 | public static boolean isValidSeat(String seatCode, int totalSeats) {
33 | if (seatCode.length() < 2) return false;
34 |
35 | char row = seatCode.charAt(0);
36 | String colStr = seatCode.substring(1);
37 |
38 | if (!colStr.matches("\\d+")) return false;
39 |
40 | int col = Integer.parseInt(colStr);
41 |
42 | int maxRow = (totalSeats + 9) / 10;
43 | char lastRow = (char) ('A' + maxRow - 1);
44 |
45 | if (row < 'A' || row > lastRow) return false;
46 | if (col < 1 || col > 10) return false;
47 |
48 | int seatNumber = (row - 'A') * 10 + col;
49 | return seatNumber <= totalSeats;
50 | }
51 | }
--------------------------------------------------------------------------------
/src/Ticket/TicketingService.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.FileReader;
5 | import java.io.IOException;
6 |
7 | public class TicketingService {
8 |
9 | private static final String RESERVATION_FILE_PATH = "src/resource/reservation_data.txt";
10 |
11 | public static void printTicketInfo(String userId) {
12 | boolean found = false;
13 |
14 | try (BufferedReader br = new BufferedReader(new FileReader(RESERVATION_FILE_PATH))) {
15 | String line;
16 | while ((line = br.readLine()) != null) {
17 | String[] parts = line.split(",");
18 |
19 | if (parts[0].equals(userId)) {
20 | String concertName = parts[1];
21 | String concertDate = parts[2];
22 | int price = Integer.parseInt(parts[3]);
23 | String seat = parts[4];
24 |
25 | System.out.println("\n=============================");
26 | System.out.println("| Concert Ticket |");
27 | System.out.println("|-----------------------------|");
28 | System.out.printf("| 공연명 : %-18s |\n", concertName);
29 | System.out.printf("| 날짜 : %-18s |\n", concertDate);
30 | System.out.printf("| 좌석 : %-18s |\n", seat);
31 | System.out.printf("| 가격 : %,15d원 |\n", price);
32 | System.out.println("|-----------------------------|");
33 | System.out.println("| Have a Nice Day |");
34 | System.out.println("===============================\n");
35 |
36 | found = true;
37 | }
38 | }
39 |
40 | if (!found) {
41 | System.out.println("[알림] 예매한 공연이 없습니다.");
42 | }
43 | } catch (IOException e) {
44 | System.out.println("[오류] 예매 정보 불러오기 실패: " + e.getMessage());
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/src/Ticket/User.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | public class User {
4 | private String name;
5 | private String username;
6 | private String password;
7 | private String phone;
8 | private String reservedConcertName;
9 | private String reservedSeat;
10 |
11 | public User(String name, String username, String password, String phone) {
12 | this.name = name;
13 | this.username = username;
14 | this.password = password;
15 | this.phone = phone;
16 | this.reservedConcertName = "";
17 | this.reservedSeat = "";
18 | }
19 | public User(String name, String id, String password, String phone, String reservedConcertName, String reservedSeat) {
20 | this.name = name;
21 | this.username = id;
22 | this.password = password;
23 | this.phone = phone;
24 | this.reservedConcertName = reservedConcertName;
25 | this.reservedSeat = reservedSeat;
26 | }
27 |
28 | public String getName() { return name; }
29 | public String getUsername() { return username; }
30 | public String getPassword() { return password; }
31 | public String getPhone() { return phone; }
32 | public String getReservedSeat() { return reservedSeat; }
33 | public void setReservedSeat(String reservedSeat) { this.reservedSeat = reservedSeat; }
34 | public void setReservedConcertName(String reservedConcertName) { this.reservedConcertName = reservedConcertName; }
35 | public String toDataString() {
36 | return String.join(",", name, username, password, phone, reservedConcertName, reservedSeat);
37 | }
38 |
39 | public String toFileString() {
40 | return name + "," + username + "," + password + "," + phone;
41 | }
42 | public String toCSV() {
43 | return String.join(",", name, username, password, phone);
44 | }
45 |
46 |
47 |
48 | }
--------------------------------------------------------------------------------
/src/Ticket/UserManager.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | import java.io.*;
4 | import java.util.*;
5 |
6 | public class UserManager {
7 | static final String FILE_PATH = "src/resource/user_data.txt";
8 | static final String CONCERT_FILE_PATH = "src/resource/concert_data.txt";
9 | private List users = new ArrayList<>();
10 | private static User loggedInUser = null;
11 |
12 | public void addUser(User user) {
13 | users.add(user);
14 | }
15 |
16 | public User findUserById(String id) {
17 | for (User user : users) {
18 | if (user.getUsername().equals(id)) {
19 | return user;
20 | }
21 | }
22 | return null;
23 | }
24 |
25 | public boolean authenticate(String id, String password) {
26 | User user = findUserById(id);
27 | if (user != null && user.getPassword().equals(password)) {
28 | loggedInUser = user; // ⭐ [추가] 로그인 성공 시 저장
29 | return true;
30 | }
31 | return false;
32 | }
33 |
34 | public static User getLoggedInUser() { // ⭐ [추가] 로그인한 유저를 가져오기 위한 메서드
35 | return loggedInUser;
36 | }
37 |
38 | public static void logout() { // ⭐ [추가] 로그아웃 처리
39 | loggedInUser = null;
40 | }
41 |
42 | public List getUsers() {
43 | return users;
44 | }
45 |
46 |
47 | public UserManager() {
48 | loadUsers();
49 | }
50 |
51 | private void loadUsers() {
52 | try (BufferedReader br = new BufferedReader(new FileReader(FILE_PATH))) {
53 | String line;
54 | while ((line = br.readLine()) != null) {
55 | String[] data = line.split(",");
56 | if (data.length == 4) {
57 | users.add(new User(data[0], data[1], data[2], data[3]));
58 | }
59 | }
60 | } catch (IOException e) {
61 | System.out.println("회원 정보 파일을 불러오는 중 오류 발생: " + e.getMessage());
62 | }
63 | }
64 |
65 | void saveUsers() {
66 | try (BufferedWriter bw = new BufferedWriter(new FileWriter(FILE_PATH))) {
67 | for (User user : users) {
68 | bw.write(user.toCSV());
69 | bw.newLine();
70 | }
71 | } catch (IOException e) {
72 | System.out.println("회원 정보 저장 중 오류 발생: " + e.getMessage());
73 | }
74 | }
75 |
76 |
77 | public void signUp(Scanner scanner) {
78 | System.out.println("\n=== 회원가입 ===");
79 |
80 | System.out.print("이름: ");
81 | String name = scanner.nextLine();
82 |
83 | System.out.print("아이디: ");
84 | String id = scanner.nextLine();
85 |
86 | if (isIdDuplicate(id)) {
87 | System.out.println("이미 존재하는 아이디입니다.");
88 | return;
89 | }
90 |
91 | System.out.print("비밀번호: ");
92 | String password = scanner.nextLine();
93 |
94 | System.out.print("전화번호: ");
95 | String phone = scanner.nextLine();
96 |
97 | if (isPhoneDuplicate(phone)) {
98 | System.out.println("이미 등록된 전화번호입니다.");
99 | return;
100 | }
101 |
102 | User newUser = new User(name, id, password, phone);
103 | users.add(newUser);
104 | saveUsers();
105 | System.out.println("=======================================");
106 | System.out.println("회원가입이 완료되었습니다! 로그인 메뉴로 돌아갑니다.");
107 | System.out.println("=======================================");
108 | }
109 |
110 |
111 | public boolean login(Scanner scanner) {
112 | System.out.println("\n=== 로그인 ===");
113 |
114 | System.out.print("아이디: ");
115 | String id = scanner.nextLine();
116 |
117 | System.out.print("비밀번호: ");
118 | String password = scanner.nextLine();
119 |
120 | for (User user : users) {
121 | if (user.getUsername().equals(id) && user.getPassword().equals(password)) {
122 | loggedInUser = user;
123 | return true;
124 | }
125 | }
126 |
127 | return false;
128 | }
129 |
130 | public void saveUsers(List userList) {
131 | try (BufferedWriter bw = new BufferedWriter(new FileWriter(FILE_PATH))) {
132 | for (User user : userList) {
133 | bw.write(user.toDataString());
134 | bw.newLine();
135 | }
136 | } catch (IOException e) {
137 | e.printStackTrace();
138 | }
139 | }
140 |
141 | private boolean isIdDuplicate(String id) {
142 | return users.stream().anyMatch(user -> user.getUsername().equals(id));
143 | }
144 |
145 | private boolean isPhoneDuplicate(String phone) {
146 | return users.stream().anyMatch(user -> user.getPhone().equals(phone));
147 | }
148 | }
--------------------------------------------------------------------------------
/src/Ticket/UserMenu.java:
--------------------------------------------------------------------------------
1 | package Ticket;
2 |
3 | import java.util.List;
4 | import java.util.Scanner;
5 |
6 | public class UserMenu {
7 | // UserMenu.java 클래스 내부
8 | private static UserManager userManager = new UserManager();
9 | Scanner scanner = new Scanner(System.in);
10 | public static void run(Scanner scanner, User currentUser) {
11 | while (true) {
12 | System.out.println("\n==== 사용자 메뉴 ====");
13 | System.out.println("1. 콘서트 예매");
14 | System.out.println("2. 프로그램 종료");
15 | System.out.print("메뉴 선택: ");
16 |
17 | String choice = scanner.nextLine();
18 |
19 | switch (choice) {
20 | case "1":
21 | reserveConcert();
22 | break;
23 | case "2":
24 | System.out.println("프로그램을 종료합니다.");
25 | System.exit(0);
26 | default:
27 | System.out.println("올바른 번호를 입력해주세요.");
28 | }
29 | }
30 | }
31 | public static void displaySeatMatrix(Concert concert) {
32 | int totalSeats = concert.getTotalSeats();
33 | List reservedSeats = concert.getReservedSeats();
34 |
35 | char row = 'A';
36 | int seatNumber = 1;
37 | System.out.println("======================================================");
38 |
39 | for (int i = 0; i < totalSeats; i++) {
40 | String seatLabel = row + String.valueOf(seatNumber);
41 |
42 | if (reservedSeats.contains(seatLabel)) {
43 | System.out.printf("[XX] ");
44 | } else {
45 | System.out.printf("[%2s] ", seatLabel);
46 | }
47 |
48 | seatNumber++;
49 |
50 | if (seatNumber > 10) {
51 | seatNumber = 1;
52 | row++;
53 | System.out.println();
54 | }
55 | }
56 | System.out.println("=============================================================");
57 | System.out.println(); // 마지막 줄 줄바꿈
58 | }
59 | private static void reserveConcert() {
60 | User currentUser = UserManager.getLoggedInUser();
61 | List concertList = ConcertFileManager.loadConcerts();
62 | Scanner sc = new Scanner(System.in);
63 | if (concertList.isEmpty()) {
64 | System.out.println("[알림] 현재 예매 가능한 콘서트가 없습니다.");
65 | return;
66 | }
67 |
68 | System.out.println("\n=== 예매 가능한 콘서트 목록 ===");
69 |
70 | int index = 1;
71 | for (Concert concert : concertList) {
72 | if (concert.getRemainingSeats() > 0) {
73 | System.out.printf("%d. %s | 날짜: %s | 가격: %,d원 | 잔여 좌석: %d석\n",
74 | index++, concert.getName(), concert.getDate(), concert.getPrice(), concert.getRemainingSeats());
75 | }
76 | }
77 |
78 | if (index == 1) {
79 | System.out.println("[알림] 현재 예매 가능한 콘서트가 없습니다.");
80 | return;
81 | }
82 |
83 | System.out.print("\n예매할 콘서트 번호를 선택하세요 (취소: 0): ");
84 | int select = Integer.parseInt(sc.nextLine());
85 |
86 | if (select == 0) {
87 | System.out.println("이전 메뉴로 돌아갑니다.");
88 | return;
89 | }
90 |
91 | if (select < 1 || select >= index) {
92 | System.out.println("[오류] 올바른 번호를 입력해주세요.");
93 | return;
94 | }
95 |
96 | // 선택한 콘서트 정보 가져오기
97 | Concert selectedConcert = concertList.get(select - 1);
98 |
99 | // 좌석 매트릭스 출력
100 | System.out.println("\n=== 좌석 선택 페이지 ===");
101 | UserMenu.displaySeatMatrix(selectedConcert);
102 |
103 | // 좌석 선택
104 | System.out.print("\n예약할 좌석 번호를 입력하세요 (예: A1): ");
105 | String seatInput = sc.nextLine().toUpperCase();
106 |
107 | if (selectedConcert.getReservedSeats().contains(seatInput)) {
108 | System.out.println("[오류] 이미 예약된 좌석입니다. 다시 시도하세요.");
109 | return;
110 | }
111 |
112 | if (!SeatManager.isValidSeat(seatInput, selectedConcert.getTotalSeats())) {
113 | System.out.println("[오류] 존재하지 않는 좌석입니다. 다시 시도하세요.");
114 | return;
115 | }
116 |
117 | // 예약 처리
118 | selectedConcert.getReservedSeats().add(seatInput);
119 | selectedConcert.setRemainingSeats(selectedConcert.getRemainingSeats() - 1);
120 |
121 | // 콘서트 파일 업데이트
122 | ConcertFileManager.saveConcerts(concertList);
123 |
124 | // 사용자 예약 정보 저장
125 |
126 | if (currentUser != null) {
127 | currentUser.setReservedConcertName(selectedConcert.getName());
128 | currentUser.setReservedSeat(seatInput);
129 | userManager.saveUsers(); // 변경된 사용자 정보 저장
130 | } else {
131 | System.out.println("[오류] 로그인 정보가 없습니다. 다시 로그인 해주세요.");
132 | }
133 |
134 | System.out.println("[성공] 예약이 완료되었습니다!");
135 | }
136 | }
--------------------------------------------------------------------------------
/src/resource/concert_data.txt:
--------------------------------------------------------------------------------
1 | moondial,2025-05-24,100000,120,118,0|L1|L10
2 | Tommy Emmanuel,2025-03-24,70000,250,247,0|Y3|Y10|Y1
3 | Java,2024-02-24,20000,30,24,0|C10|A1|A2|B1|B2|A6
4 | aa,123123,40000,30,30,0
5 |
--------------------------------------------------------------------------------
/src/resource/reservation_data.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Trajectory-SH/kh-project-java-01/5c838ada446a970b9611216aaff893ac3c7ca274/src/resource/reservation_data.txt
--------------------------------------------------------------------------------
/src/resource/user_data.txt:
--------------------------------------------------------------------------------
1 | 전수환,1,1,1
2 | 전수환,admin,1234,020-23123-12312
3 | 전수환,2,2,2
4 | 지환,1234,1234,01046055372
5 | 123,123,123,123
6 | 전수환,121,121,121
7 | 이이,122,122,122
8 | 333,333,333,333
9 | 자자,a,a,12
10 |
--------------------------------------------------------------------------------