Skip to content

Commit 454fce5

Browse files
안훈기안훈기
authored andcommitted
✨ Feat: SportsFacility 구장정보 필드 및 MatchRoom 매칭 정보 필드 추가
1 parent b848a8a commit 454fce5

File tree

11 files changed

+188
-10
lines changed

11 files changed

+188
-10
lines changed

src/main/java/com/be/sportizebe/domain/facility/dto/request/FacilityCreateRequest.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.be.sportizebe.domain.facility.dto.request;
22

33
import com.be.sportizebe.domain.facility.entity.FacilityType;
4+
import com.be.sportizebe.domain.facility.entity.ParkingType;
45
import io.swagger.v3.oas.annotations.media.Schema;
56
import jakarta.validation.constraints.NotBlank;
67
import jakarta.validation.constraints.NotNull;
@@ -24,7 +25,28 @@ public record FacilityCreateRequest(
2425

2526
@Schema(description = "시설 종목 타입", example = "SOCCER")
2627
@NotNull
27-
FacilityType facilityType
28+
FacilityType facilityType,
29+
30+
@Schema(description = "화장실 유무", example = "true")
31+
boolean hasToilet,
32+
33+
@Schema(description = "자판기 유무", example = "false")
34+
boolean hasVendingMachine,
35+
36+
@Schema(description = "샤워실 유무", example = "true")
37+
boolean hasShower,
38+
39+
@Schema(description = "주차 유형 (NONE/FREE/PAID)", example = "FREE")
40+
ParkingType parkingType,
41+
42+
@Schema(description = "구장 가로 크기 (m)", example = "40")
43+
Integer widthMeter,
44+
45+
@Schema(description = "구장 세로 크기 (m)", example = "20")
46+
Integer heightMeter,
47+
48+
@Schema(description = "휠체어 접근 가능 여부", example = "true")
49+
boolean wheelchairAccessible
2850

2951
) {
3052
}

src/main/java/com/be/sportizebe/domain/facility/dto/request/FacilityUpdateRequest.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.be.sportizebe.domain.facility.dto.request;
22

33
import com.be.sportizebe.domain.facility.entity.FacilityType;
4+
import com.be.sportizebe.domain.facility.entity.ParkingType;
45
import io.swagger.v3.oas.annotations.media.Schema;
56

67
@Schema(description = "체육시설 수정 요청 (null 필드는 수정하지 않음)")
@@ -19,6 +20,27 @@ public record FacilityUpdateRequest(
1920
String thumbnailUrl,
2021

2122
@Schema(description = "시설 종목 타입", example = "SOCCER")
22-
FacilityType facilityType
23+
FacilityType facilityType,
24+
25+
@Schema(description = "화장실 유무", example = "true")
26+
Boolean hasToilet,
27+
28+
@Schema(description = "자판기 유무", example = "false")
29+
Boolean hasVendingMachine,
30+
31+
@Schema(description = "샤워실 유무", example = "true")
32+
Boolean hasShower,
33+
34+
@Schema(description = "주차 유형 (NONE/FREE/PAID)", example = "FREE")
35+
ParkingType parkingType,
36+
37+
@Schema(description = "구장 가로 크기 (m)", example = "40")
38+
Integer widthMeter,
39+
40+
@Schema(description = "구장 세로 크기 (m)", example = "20")
41+
Integer heightMeter,
42+
43+
@Schema(description = "휠체어 접근 가능 여부", example = "true")
44+
Boolean wheelchairAccessible
2345

2446
) {}

src/main/java/com/be/sportizebe/domain/facility/dto/response/FacilityResponse.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.be.sportizebe.domain.facility.dto.response;
22

33
import com.be.sportizebe.domain.facility.entity.FacilityType;
4+
import com.be.sportizebe.domain.facility.entity.ParkingType;
45
import io.swagger.v3.oas.annotations.media.Schema;
56

67
@Schema(description = "체육시설 단건 조회 응답")
@@ -28,7 +29,28 @@ public record FacilityResponse(
2829
double lat,
2930

3031
@Schema(description = "경도", example = "126.982")
31-
double lng
32+
double lng,
33+
34+
@Schema(description = "화장실 유무", example = "true")
35+
boolean hasToilet,
36+
37+
@Schema(description = "자판기 유무", example = "false")
38+
boolean hasVendingMachine,
39+
40+
@Schema(description = "샤워실 유무", example = "true")
41+
boolean hasShower,
42+
43+
@Schema(description = "주차 유형 (NONE/FREE/PAID)", example = "FREE")
44+
ParkingType parkingType,
45+
46+
@Schema(description = "구장 가로 크기 (m)", example = "40")
47+
Integer widthMeter,
48+
49+
@Schema(description = "구장 세로 크기 (m)", example = "20")
50+
Integer heightMeter,
51+
52+
@Schema(description = "휠체어 접근 가능 여부", example = "true")
53+
boolean wheelchairAccessible
3254

3355
) {
3456
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.be.sportizebe.domain.facility.entity;
2+
3+
public enum ParkingType {
4+
NONE, // 주차장 없음
5+
FREE, // 무료 주차
6+
PAID // 유료 주차
7+
}

src/main/java/com/be/sportizebe/domain/facility/entity/SportsFacility.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class SportsFacility extends BaseTimeEntity {
2525
@Column(columnDefinition = "text")
2626
private String introduce;
2727

28-
// 리소스 부담 생각해서 일단 썸네일 이미지 1장으로만 구현하는 방식
28+
// 리소스 부담 생각해서 일단 썸네일 이미지 1/치장으로만 구현하는 방식
2929
private String thumbnailUrl;
3030

3131
@Enumerated(EnumType.STRING)
@@ -35,6 +35,27 @@ public class SportsFacility extends BaseTimeEntity {
3535
@Column(columnDefinition = "geography(Point, 4326)", nullable = false)
3636
private Point location;
3737

38+
// 편의시설
39+
@Column(nullable = false)
40+
private boolean hasToilet;
41+
42+
@Column(nullable = false)
43+
private boolean hasVendingMachine;
44+
45+
@Column(nullable = false)
46+
private boolean hasShower;
47+
48+
@Enumerated(EnumType.STRING)
49+
@Column(nullable = false, length = 10)
50+
private ParkingType parkingType;
51+
52+
// 구장 크기 (미터)
53+
private Integer widthMeter;
54+
private Integer heightMeter;
55+
56+
@Column(nullable = false)
57+
private boolean wheelchairAccessible;
58+
3859
// 변경 메서드(Dirty Checking용)
3960
public void changeInfo(String facilityName, String introduce, String thumbnailUrl, FacilityType facilityType) {
4061
if (facilityName != null) this.facilityName = facilityName;
@@ -43,6 +64,18 @@ public void changeInfo(String facilityName, String introduce, String thumbnailUr
4364
if (facilityType != null) this.facilityType = facilityType;
4465
}
4566

67+
public void changeAmenity(Boolean hasToilet, Boolean hasVendingMachine, Boolean hasShower,
68+
ParkingType parkingType, Integer widthMeter, Integer heightMeter,
69+
Boolean wheelchairAccessible) {
70+
if (hasToilet != null) this.hasToilet = hasToilet;
71+
if (hasVendingMachine != null) this.hasVendingMachine = hasVendingMachine;
72+
if (hasShower != null) this.hasShower = hasShower;
73+
if (parkingType != null) this.parkingType = parkingType;
74+
if (widthMeter != null) this.widthMeter = widthMeter;
75+
if (heightMeter != null) this.heightMeter = heightMeter;
76+
if (wheelchairAccessible != null) this.wheelchairAccessible = wheelchairAccessible;
77+
}
78+
4679
public void changeAddress(String address) {
4780
this.address = address;
4881
}

src/main/java/com/be/sportizebe/domain/facility/mapper/FacilityMapper.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,14 @@ static FacilityResponse toFacilityResponse(SportsFacility sf) {
4242
sf.getThumbnailUrl(),
4343
sf.getFacilityType(),
4444
lat,
45-
lng
45+
lng,
46+
sf.isHasToilet(),
47+
sf.isHasVendingMachine(),
48+
sf.isHasShower(),
49+
sf.getParkingType(),
50+
sf.getWidthMeter(),
51+
sf.getHeightMeter(),
52+
sf.isWheelchairAccessible()
4653
);
4754
}
4855
}

src/main/java/com/be/sportizebe/domain/facility/service/SportsFacilityServiceImpl.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.be.sportizebe.domain.facility.dto.response.FacilityMarkerResponse;
88
import com.be.sportizebe.domain.facility.dto.response.FacilityNearResponse;
99
import com.be.sportizebe.domain.facility.dto.response.FacilityResponse;
10+
import com.be.sportizebe.domain.facility.entity.ParkingType;
1011
import com.be.sportizebe.domain.facility.entity.SportsFacility;
1112
import com.be.sportizebe.domain.facility.mapper.FacilityMapper;
1213
import com.be.sportizebe.domain.facility.repository.SportsFacilityRepository;
@@ -81,6 +82,13 @@ public FacilityResponse create(FacilityCreateRequest request) {
8182
.thumbnailUrl(request.thumbnailUrl())
8283
.facilityType(request.facilityType())
8384
.location(point)
85+
.hasToilet(request.hasToilet())
86+
.hasVendingMachine(request.hasVendingMachine())
87+
.hasShower(request.hasShower())
88+
.parkingType(request.parkingType() != null ? request.parkingType() : ParkingType.NONE)
89+
.widthMeter(request.widthMeter())
90+
.heightMeter(request.heightMeter())
91+
.wheelchairAccessible(request.wheelchairAccessible())
8492
.build();
8593

8694
SportsFacility saved = sportsFacilityRepository.save(facility);
@@ -106,6 +114,16 @@ public FacilityResponse update(Long facilityId, FacilityUpdateRequest request) {
106114
request.facilityType()
107115
);
108116

117+
facility.changeAmenity(
118+
request.hasToilet(),
119+
request.hasVendingMachine(),
120+
request.hasShower(),
121+
request.parkingType(),
122+
request.widthMeter(),
123+
request.heightMeter(),
124+
request.wheelchairAccessible()
125+
);
126+
109127
return FacilityMapper.toFacilityResponse(facility);
110128
}
111129

src/main/java/com/be/sportizebe/domain/match/dto/request/MatchCreateRequest.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.be.sportizebe.domain.match.dto.request;
22

33
import com.be.sportizebe.common.enums.SportType;
4+
import com.be.sportizebe.domain.match.entity.UniformPolicy;
45
import io.swagger.v3.oas.annotations.media.Schema;
56
import jakarta.validation.constraints.Future;
67
import jakarta.validation.constraints.Max;
@@ -32,6 +33,16 @@ public record MatchCreateRequest(
3233
@Schema(description = "매칭 시작 일시", example = "2026-03-07T14:00:00")
3334
@NotNull(message = "매칭 시작 일시는 필수입니다.")
3435
@Future(message = "매칭 시작 일시는 현재 시간 이후여야 합니다.")
35-
LocalDateTime scheduledAt
36+
LocalDateTime scheduledAt,
37+
38+
@Schema(description = "유니폼 정책 (BRING_OWN: 흰/검 지참, VEST_PROVIDED: 조끼 제공)", example = "BRING_OWN")
39+
UniformPolicy uniformPolicy,
40+
41+
@Schema(description = "몇 파전 (미입력 시 2파전)", example = "2")
42+
@Min(value = 2, message = "파전 수는 2 이상이어야 합니다.")
43+
Integer numberOfTeams,
44+
45+
@Schema(description = "남/녀 혼성 허용 여부", example = "false")
46+
boolean mixedGender
3647

3748
) {}

src/main/java/com/be/sportizebe/domain/match/dto/response/MatchDetailResponse.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.be.sportizebe.domain.match.entity.MatchParticipantStatus;
44
import com.be.sportizebe.domain.match.entity.MatchRoom;
5+
import com.be.sportizebe.domain.match.entity.UniformPolicy;
56
import com.be.sportizebe.common.enums.SportType;
67
import com.be.sportizebe.domain.user.entity.User;
78
import io.swagger.v3.oas.annotations.media.Schema;
@@ -34,7 +35,16 @@ public record MatchDetailResponse(
3435
boolean joined,
3536

3637
@Schema(description = "매칭 시작 일시", example = "2026-03-07T14:00:00")
37-
LocalDateTime scheduledAt
38+
LocalDateTime scheduledAt,
39+
40+
@Schema(description = "유니폼 정책 (BRING_OWN: 흰/검 지참, VEST_PROVIDED: 조끼 제공)", example = "BRING_OWN")
41+
UniformPolicy uniformPolicy,
42+
43+
@Schema(description = "몇 파전", example = "2")
44+
int numberOfTeams,
45+
46+
@Schema(description = "남/녀 혼성 허용 여부", example = "false")
47+
boolean mixedGender
3848

3949
) {
4050
public static MatchDetailResponse of(
@@ -58,7 +68,10 @@ public static MatchDetailResponse of(
5868
participantIds.size(),
5969
participantIds,
6070
joined,
61-
matchRoom.getScheduledAt()
71+
matchRoom.getScheduledAt(),
72+
matchRoom.getUniformPolicy(),
73+
matchRoom.getNumberOfTeams(),
74+
matchRoom.isMixedGender()
6275
);
6376
}
6477
}

src/main/java/com/be/sportizebe/domain/match/entity/MatchRoom.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ public class MatchRoom extends BaseTimeEntity {
4949
@Column(nullable = false)
5050
private LocalDateTime scheduledAt; // 매칭 시작 일시
5151

52+
@Enumerated(EnumType.STRING)
53+
@Column(length = 20)
54+
private UniformPolicy uniformPolicy; // 흰/검 지참 or 조끼 제공
55+
56+
@Column(nullable = false)
57+
@Builder.Default
58+
private int numberOfTeams = 2; // 몇 파전 (default: 2파전)
59+
60+
@Column(nullable = false)
61+
private boolean mixedGender; // 남/녀 혼성 허용 여부
5262

5363
@OneToMany(mappedBy = "matchRoom", cascade = CascadeType.ALL, orphanRemoval = true)
5464
@Builder.Default
@@ -59,7 +69,7 @@ public boolean isFull() {
5969
}
6070

6171
public static MatchRoom create(MatchCreateRequest request) {
62-
return MatchRoom.builder()
72+
MatchRoom.MatchRoomBuilder builder = MatchRoom.builder()
6373
.sportsName(request.sportsName())
6474
.facilityId(request.facilityId())
6575
.curMembers(0)
@@ -68,7 +78,14 @@ public static MatchRoom create(MatchCreateRequest request) {
6878
.durationMinutes(request.durationMinutes())
6979
.entryFee(request.entryFee())
7080
.scheduledAt(request.scheduledAt())
71-
.build();
81+
.uniformPolicy(request.uniformPolicy())
82+
.mixedGender(request.mixedGender());
83+
84+
if (request.numberOfTeams() != null) {
85+
builder.numberOfTeams(request.numberOfTeams());
86+
}
87+
88+
return builder.build();
7289
}
7390
public void join() {
7491
this.curMembers++;

0 commit comments

Comments
 (0)