Skip to content

Commit 21ade4b

Browse files
authored
Merge pull request #14 from ddankey/accident
feat: 지반 침하 사고 리스트 및 상세 데이터 저장, 조회 api 구현
2 parents 9bdbe58 + ac7b387 commit 21ade4b

26 files changed

+715
-40
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.ddanguizip.server.domain.accident.controller;
2+
3+
import com.ddanguizip.server.domain.accident.dto.AccidentInfoList;
4+
import com.ddanguizip.server.domain.accident.service.AccidentService;
5+
import com.ddanguizip.server.domain.map.dto.reponse.RiskAreaListRes;
6+
import com.ddanguizip.server.domain.map.dto.reponse.RiskListRes;
7+
import com.ddanguizip.server.domain.map.service.MapService;
8+
import com.ddanguizip.server.global.common.ApplicationResponse;
9+
import com.ddanguizip.server.global.success.SuccessCode;
10+
import lombok.RequiredArgsConstructor;
11+
import org.springframework.data.domain.Pageable;
12+
import org.springframework.data.web.PageableDefault;
13+
import org.springframework.web.bind.annotation.GetMapping;
14+
import org.springframework.web.bind.annotation.RequestMapping;
15+
import org.springframework.web.bind.annotation.RequestParam;
16+
import org.springframework.web.bind.annotation.RestController;
17+
18+
@RestController
19+
@RequestMapping("/api/v1/accident")
20+
@RequiredArgsConstructor
21+
public class AccidentController {
22+
private final AccidentService accidentService;
23+
24+
@GetMapping("")
25+
public ApplicationResponse<AccidentInfoList> search(
26+
@RequestParam(name = "category", defaultValue = "") String category,
27+
@PageableDefault(size = 10,page = 0) Pageable pageable) {
28+
29+
AccidentInfoList accidentInfoList = accidentService.searchAccidentListByCategory(category, pageable);
30+
return ApplicationResponse.success(SuccessCode.SUCCESS,accidentInfoList);
31+
}
32+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.ddanguizip.server.domain.accident.dto;
2+
3+
import com.ddanguizip.server.domain.accident.entity.AccidentDetail;
4+
import lombok.Builder;
5+
6+
@Builder
7+
public record AccidentInfoDetail(
8+
String gu,
9+
String dong,
10+
String addr,
11+
String sagoDetail,
12+
String sinkWidth,
13+
String sinkExtend,
14+
String sinkDepth,
15+
String accidentDate,
16+
String categoryDescription
17+
) {
18+
public static AccidentInfoDetail of(
19+
AccidentDetail accidentDetail,
20+
String categoryDescription
21+
){
22+
return AccidentInfoDetail.builder()
23+
.gu(accidentDetail.getLocation().getGu())
24+
.dong(accidentDetail.getLocation().getDong())
25+
.addr(accidentDetail.getAddr())
26+
.accidentDate(accidentDetail.getSagoDate())
27+
.sagoDetail(accidentDetail.getSagoDetail())
28+
.sinkWidth(accidentDetail.getSinkWidth())
29+
.sinkExtend(accidentDetail.getSinkExtend())
30+
.sinkDepth(accidentDetail.getSinkDepth())
31+
.categoryDescription(categoryDescription)
32+
.build();
33+
}
34+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.ddanguizip.server.domain.accident.dto;
2+
3+
import lombok.Builder;
4+
5+
import java.util.List;
6+
7+
@Builder
8+
public record AccidentInfoList(
9+
List<AccidentInfoDetail> accidentInfoDetailList,
10+
int pageNo,
11+
long pageSize,
12+
long totalSize,
13+
int totalPages
14+
) {
15+
public static AccidentInfoList of(List<AccidentInfoDetail> accidentInfoDetailList,
16+
int pageNo,
17+
long pageSize,
18+
long totalSize,
19+
int totalPages
20+
){
21+
return AccidentInfoList.builder()
22+
.accidentInfoDetailList(accidentInfoDetailList)
23+
.pageSize(pageSize)
24+
.totalPages(totalPages)
25+
.totalSize(totalSize)
26+
.pageNo(pageNo)
27+
.build();
28+
}
29+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.ddanguizip.server.domain.accident.entity;
2+
3+
import com.ddanguizip.server.domain.accident.enumrate.AccidentCategory;
4+
import com.ddanguizip.server.domain.location.entity.Location;
5+
import com.ddanguizip.server.global.common.BaseTimeEntity;
6+
import jakarta.persistence.*;
7+
import lombok.AccessLevel;
8+
import lombok.Builder;
9+
import lombok.Getter;
10+
import lombok.NoArgsConstructor;
11+
12+
@Getter
13+
@Entity
14+
@Table(name = "accidentDetail")
15+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
16+
public class AccidentDetail extends BaseTimeEntity {
17+
@Id
18+
@GeneratedValue(strategy = GenerationType.IDENTITY)
19+
@Column(name = "id", nullable = false, columnDefinition = "bigint")
20+
private Long id;
21+
22+
@Column(nullable = false, length = 40)
23+
private String addr;
24+
25+
@Column(nullable = false, length = 500)
26+
private String sagoDetail;
27+
28+
@Column(nullable = false, length = 20)
29+
private String sagoDate;
30+
31+
@Column(nullable = false, length = 20)
32+
private String sinkWidth;
33+
34+
@Column(nullable = false, length = 20)
35+
private String sinkExtend;
36+
37+
@Column(nullable = false, length = 20)
38+
private String sinkDepth;
39+
40+
@ManyToOne(fetch = FetchType.LAZY, optional = false)
41+
@JoinColumn(name = "location_id")
42+
private Location location;
43+
44+
@OneToOne
45+
@JoinColumn(name = "accident_sageNo", unique = true)
46+
private AccidentSagoNo sageNo;
47+
48+
@Enumerated(EnumType.STRING)
49+
@Column(nullable = false)
50+
private AccidentCategory category;
51+
52+
@Builder
53+
public AccidentDetail(String addr,
54+
String sagoDetail,
55+
String sagoDate,
56+
String sinkWidth,
57+
String sinkExtend,
58+
String sinkDepth,
59+
Location location,
60+
AccidentSagoNo sageNo,
61+
AccidentCategory category) {
62+
this.addr = addr;
63+
this.sagoDetail = sagoDetail;
64+
this.sagoDate = sagoDate;
65+
this.sinkWidth = sinkWidth;
66+
this.sinkExtend = sinkExtend;
67+
this.sinkDepth = sinkDepth;
68+
this.location = location;
69+
this.sageNo = sageNo;
70+
this.category = category;
71+
}
72+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.ddanguizip.server.domain.accident.entity;
2+
3+
import com.ddanguizip.server.global.common.BaseTimeEntity;
4+
import jakarta.persistence.Entity;
5+
import jakarta.persistence.Id;
6+
import jakarta.persistence.Table;
7+
import lombok.*;
8+
9+
@Entity
10+
@Table(name = "accident_sago_no")
11+
@Getter
12+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
13+
@AllArgsConstructor
14+
@Builder
15+
//20250505: 20250504
16+
public class AccidentSagoNo extends BaseTimeEntity {
17+
18+
@Id
19+
private String sagoNo; // sagoNo가 저장될 PK 컬럼
20+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.ddanguizip.server.domain.accident.enumrate;
2+
3+
public enum AccidentCategory {
4+
AGING_INFRA("노후 지하시설물"),
5+
BAD_CONSTRUCTION("시공·복구 불량"),
6+
EXTERNAL_LOAD("외부 하중·진동"),
7+
WEATHER_NATURE("기상·자연 요인"),
8+
CONSTRUCTION_SITE("건축공사장 영향"),
9+
COMPLEX_CAUSE("복합 요인·관리 부재"),
10+
UNKNOWN("원인 불명/조사 중"),
11+
ETC("기타");
12+
13+
private final String description;
14+
15+
AccidentCategory(String description) {
16+
this.description = description;
17+
}
18+
19+
public String getDescription() {
20+
return description;
21+
}
22+
23+
public static boolean existCategory(String category) {
24+
for (AccidentCategory value : AccidentCategory.values()) {
25+
if (value.name().equalsIgnoreCase(category)) {
26+
return true;
27+
}
28+
}
29+
return false;
30+
}
31+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.ddanguizip.server.domain.accident.factory;
2+
3+
import com.ddanguizip.server.domain.accident.entity.AccidentDetail;
4+
import com.ddanguizip.server.domain.accident.entity.AccidentSagoNo;
5+
import com.ddanguizip.server.domain.accident.enumrate.AccidentCategory;
6+
import com.ddanguizip.server.domain.location.entity.GuLocation;
7+
import com.ddanguizip.server.domain.location.entity.Location;
8+
import com.ddanguizip.server.domain.publicData.dto.response.AccidentDetailRes;
9+
import org.springframework.stereotype.Component;
10+
11+
@Component
12+
public class AccidentFactory {
13+
public AccidentSagoNo createAccidentSagoNo(String sagoNo) {
14+
return AccidentSagoNo.builder()
15+
.sagoNo(sagoNo)
16+
.build();
17+
}
18+
19+
public AccidentDetail createAccidentDetail(AccidentDetailRes accidentDetailRes, Location location, AccidentSagoNo sageNo, AccidentCategory accidentCategory) {
20+
return AccidentDetail.builder()
21+
.addr(accidentDetailRes.addr())
22+
.sagoDetail(accidentDetailRes.sagoDetail())
23+
.sagoDate(accidentDetailRes.sagoDate())
24+
.sinkWidth(accidentDetailRes.sinkWidth())
25+
.sinkExtend(accidentDetailRes.sinkExtend())
26+
.sinkDepth(accidentDetailRes.sinkDepth())
27+
.location(location)
28+
.sageNo(sageNo)
29+
.category(accidentCategory)
30+
.build();
31+
}
32+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.ddanguizip.server.domain.accident.repository;
2+
3+
import com.ddanguizip.server.domain.accident.entity.AccidentDetail;
4+
import com.ddanguizip.server.domain.accident.entity.AccidentSagoNo;
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
7+
public interface AccidentDetailRepository extends JpaRepository<AccidentDetail, Long>,AccidentDetailRepositoryCustom {
8+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.ddanguizip.server.domain.accident.repository;
2+
3+
import com.ddanguizip.server.domain.accident.entity.AccidentDetail;
4+
import com.ddanguizip.server.domain.accident.enumrate.AccidentCategory;
5+
import org.springframework.data.domain.Page;
6+
import org.springframework.data.domain.Pageable;
7+
8+
public interface AccidentDetailRepositoryCustom {
9+
/**
10+
* 행궁동 기반 데이터 검색
11+
* @param category category
12+
*/
13+
Page<AccidentDetail> searchList (AccidentCategory category, Pageable pageable);
14+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.ddanguizip.server.domain.accident.repository;
2+
3+
import com.ddanguizip.server.domain.accident.entity.AccidentDetail;
4+
import com.ddanguizip.server.domain.accident.enumrate.AccidentCategory;
5+
import com.querydsl.core.types.dsl.BooleanExpression;
6+
import com.querydsl.jpa.impl.JPAQueryFactory;
7+
import jakarta.persistence.EntityManager;
8+
import org.springframework.data.domain.Page;
9+
import org.springframework.data.domain.PageImpl;
10+
import org.springframework.data.domain.Pageable;
11+
12+
import java.util.List;
13+
14+
import static com.ddanguizip.server.domain.accident.entity.QAccidentDetail.accidentDetail;
15+
16+
public class AccidentDetailRepositoryImpl implements AccidentDetailRepositoryCustom {
17+
private final JPAQueryFactory queryFactory;
18+
19+
public AccidentDetailRepositoryImpl(EntityManager em) {
20+
this.queryFactory = new JPAQueryFactory(em);
21+
}
22+
23+
@Override
24+
public Page<AccidentDetail> searchList(AccidentCategory category, Pageable pageable) {
25+
BooleanExpression filterCondition = categoryEq(category);
26+
27+
List<AccidentDetail> results = queryFactory
28+
.selectFrom(accidentDetail)
29+
.where(filterCondition)
30+
.orderBy(accidentDetail.createdAt.desc())
31+
.offset(pageable.getOffset())
32+
.limit(pageable.getPageSize())
33+
.fetch();
34+
35+
long total = queryFactory
36+
.select(accidentDetail.count())
37+
.from(accidentDetail)
38+
.where(filterCondition)
39+
.fetchOne();
40+
41+
return new PageImpl<>(results, pageable, total);
42+
}
43+
44+
private BooleanExpression categoryEq(AccidentCategory category) {
45+
if (category == null) {
46+
return null;
47+
}
48+
return accidentDetail.category.eq(category);
49+
}
50+
}

0 commit comments

Comments
 (0)