Skip to content

Commit 87c0a35

Browse files
authored
Merge pull request #62 from Sportize/feat/facility-info
[Feat] Admin 매칭 취소 API 추가 및 구장·매칭 상세 정보 필드 확장
2 parents 49c2144 + 454fce5 commit 87c0a35

File tree

18 files changed

+237
-13
lines changed

18 files changed

+237
-13
lines changed

src/main/java/com/be/sportizebe/domain/admin/controller/AdminController.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ public ResponseEntity<BaseResponse<MatchResponse>> createMatch(
6666
.body(BaseResponse.success("매칭 생성 성공", response));
6767
}
6868

69+
@Operation(summary = "매칭 취소 (관리자 전용)", description = "매칭을 취소 상태로 변경합니다. 이미 시작/종료된 매칭은 취소할 수 없습니다.")
70+
@PatchMapping("/matches/{matchId}/cancel")
71+
public ResponseEntity<BaseResponse<Void>> cancelMatch(
72+
@PathVariable Long matchId
73+
) {
74+
adminService.cancelMatch(matchId);
75+
return ResponseEntity.ok(BaseResponse.success("매칭 취소 성공", null));
76+
}
77+
6978
@Operation(summary = "매칭 삭제 (관리자 전용)", description = "매칭을 강제 삭제합니다.")
7079
@DeleteMapping("/matches/{matchId}")
7180
public ResponseEntity<BaseResponse<Void>> deleteMatch(

src/main/java/com/be/sportizebe/domain/admin/service/AdminService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ public interface AdminService {
1616

1717
MatchResponse createMatch(Long adminId, MatchCreateRequest request); // 매칭 생성
1818

19+
void cancelMatch(Long matchId); // 매칭 취소
20+
1921
void deleteMatch(Long matchId); // 매칭 삭제
2022
}

src/main/java/com/be/sportizebe/domain/admin/service/AdminServiceImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ public MatchResponse createMatch(Long adminId, MatchCreateRequest request) {
4343
return matchService.createMatch(adminId, request);
4444
}
4545

46+
@Override
47+
@Transactional
48+
public void cancelMatch(Long matchId) {
49+
matchService.cancelMatch(matchId);
50+
}
51+
4652
@Override
4753
@Transactional
4854
public void deleteMatch(Long matchId) {

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

0 commit comments

Comments
 (0)