Skip to content

Commit 885a272

Browse files
authored
Feat: 제보하기 로직 구현, 제보 히스토리 로직 구현 (#T3-204)
* feat: NetworkService 로직 수정 - request 생성로직 수정. body에 jsonData 뿐 아니라, rawdata도 들어갈 수 있도록 수정 (s3 업로드 위함) - response body가 empty여도 error를 throw 하지 않도록 수정 * feat: 제보하기 로직 구현 * refactor: 제보하기 수정된 디자인 적용 * feat: 제보하기 필터링 로직 구현 * feat: 제보히스토리 -> 제보상세 플로우 미비사항 구현 - 진행상황 collectionView cell에 진행상황 별 갯수 표시 - ReportEntity id 값을 옵셔널로 변경 - ReportDetail 날짜 포멧 변경 * fix: 제보하기 로직 수정 * refactor: 코드래빗 리뷰 반영
1 parent da2ae77 commit 885a272

File tree

43 files changed

+723
-71
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+723
-71
lines changed

Projects/DataSource/Sources/Common/DataSourceDependencyAssembler.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,9 @@ public struct DataSourceDependencyAssembler: DependencyAssemblerProtocol {
4848
DIContainer.shared.register(type: ReportRepositoryProtocol.self) { _ in
4949
return ReportRepository()
5050
}
51+
52+
DIContainer.shared.register(type: FileRepositoryProtocol.self) { _ in
53+
return FileRepository()
54+
}
5155
}
5256
}

Projects/DataSource/Sources/Common/Enum/Endpoint.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// Created by 최정인 on 6/21/25.
66
//
77

8+
import Foundation
9+
810
public protocol Endpoint {
911
var baseURL: String { get }
1012
var path: String { get }
@@ -13,4 +15,11 @@ public protocol Endpoint {
1315
var queryParameters: [String: String] { get }
1416
var bodyParameters: [String: Any] { get }
1517
var isAuthorized: Bool { get }
18+
var bodyType: EndpointBodyType { get }
19+
var bodyData: Data? { get }
20+
}
21+
22+
extension Endpoint {
23+
var bodyType: EndpointBodyType { return .json }
24+
var bodyData: Data? { return nil }
1625
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//
2+
// EndpointBodyType.swift
3+
// DataSource
4+
//
5+
// Created by 이동현 on 11/22/25.
6+
//
7+
8+
public enum EndpointBodyType {
9+
case json
10+
case rawData
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//
2+
// FilePresignedConditionDTO.swift
3+
// DataSource
4+
//
5+
// Created by 이동현 on 11/22/25.
6+
//
7+
8+
struct FilePresignedConditionDTO: Codable {
9+
let prefix: String?
10+
let fileName: String
11+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// FilePresignedDTO.swift
3+
// DataSource
4+
//
5+
// Created by 이동현 on 11/22/25.
6+
//
7+
8+
struct FilePresignedDTO: Decodable {
9+
let file1: String?
10+
let file2: String?
11+
let file3: String?
12+
13+
enum CodingKeys: String, CodingKey {
14+
case file1 = "additionalProp1"
15+
case file2 = "additionalProp2"
16+
case file3 = "additionalProp3"
17+
}
18+
}

Projects/DataSource/Sources/DTO/ReportDTO.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,32 @@
77

88
import Domain
99

10-
struct ReportDTO: Decodable {
10+
struct ReportDTO: Codable {
1111
let reportId: Int?
1212
let reportDate: String?
1313
let reportTitle: String
1414
let reportContent: String?
1515
let reportLocation: String
16-
let reportStatus: String
16+
let reportStatus: String?
1717
let reportCategory: String
1818
let reportImageUrl: String?
1919
let reportImageUrls: [String]?
2020
let latitude: Double?
2121
let longitude: Double?
2222

2323
func toReportEntity() throws -> ReportEntity {
24-
guard let reportId else { throw NetworkError.decodingError }
2524
return ReportEntity(
2625
id: reportId,
2726
title: reportTitle,
2827
date: reportDate,
2928
type: ReportType(rawValue: reportCategory) ?? .transportation,
30-
progress: ReportProgress(rawValue: reportStatus) ?? .received,
29+
progress: ReportProgress(rawValue: reportStatus ?? "") ?? .received,
3130
content: reportContent,
3231
location: LocationEntity(
3332
longitude: longitude,
3433
latitude: latitude,
3534
address: reportLocation),
35+
thumbnailURL: reportImageUrl,
3636
photoUrls: reportImageUrls ?? [])
3737
}
3838

@@ -43,12 +43,13 @@ struct ReportDTO: Decodable {
4343
title: reportTitle,
4444
date: date,
4545
type: ReportType(rawValue: reportCategory) ?? .transportation,
46-
progress: ReportProgress(rawValue: reportStatus) ?? .received,
46+
progress: ReportProgress(rawValue: reportStatus ?? "") ?? .received,
4747
content: reportContent,
4848
location: LocationEntity(
4949
longitude: longitude,
5050
latitude: latitude,
5151
address: reportLocation),
52+
thumbnailURL: reportImageUrl,
5253
photoUrls: reportImageUrls ?? [])
5354
}
5455
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//
2+
// FilePresignedEndpoint.swift
3+
// DataSource
4+
//
5+
// Created by 이동현 on 11/22/25.
6+
//
7+
8+
import Foundation
9+
10+
enum FilePresignedEndpoint {
11+
case fetchPresignedURL(presignedConditions: [FilePresignedConditionDTO])
12+
}
13+
14+
extension FilePresignedEndpoint: Endpoint {
15+
var baseURL: String {
16+
switch self {
17+
case .fetchPresignedURL:
18+
return AppProperties.baseURL + "/api/v2/files"
19+
}
20+
}
21+
22+
var path: String {
23+
switch self {
24+
case .fetchPresignedURL:
25+
return baseURL + "/presigned-urls"
26+
}
27+
}
28+
29+
var method: HTTPMethod {
30+
switch self {
31+
case .fetchPresignedURL: .post
32+
}
33+
}
34+
35+
var headers: [String : String] {
36+
let headers: [String: String] = [
37+
"Content-Type": "application/json",
38+
"accept": "*/*"
39+
]
40+
return headers
41+
}
42+
43+
var queryParameters: [String : String] {
44+
return [:]
45+
}
46+
47+
var bodyParameters: [String : Any] {
48+
switch self {
49+
case .fetchPresignedURL(let presignedConditions):
50+
return [:]
51+
}
52+
}
53+
54+
var isAuthorized: Bool {
55+
return true
56+
}
57+
58+
var bodyType: EndpointBodyType {
59+
return .rawData
60+
}
61+
62+
var bodyData: Data? {
63+
switch self {
64+
case .fetchPresignedURL(let presignedConditions):
65+
return try? JSONEncoder().encode(presignedConditions)
66+
}
67+
}
68+
}

Projects/DataSource/Sources/Endpoint/ReportEndpoint.swift

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,19 @@
66
//
77

88
enum ReportEndpoint {
9+
case register(report: ReportDTO)
910
case fetchReports
1011
case fetchReportDetail(reportId: Int)
1112
}
1213

1314
extension ReportEndpoint: Endpoint {
1415
var baseURL: String {
15-
switch self {
16-
case .fetchReports, .fetchReportDetail:
17-
return AppProperties.baseURL + "/api/v2/reports"
18-
}
16+
return AppProperties.baseURL + "/api/v2/reports"
1917
}
2018

2119
var path: String {
2220
switch self {
23-
case .fetchReports:
21+
case .register, .fetchReports:
2422
return baseURL
2523
case .fetchReportDetail(let reportId):
2624
return "\(baseURL)/\(reportId)"
@@ -29,8 +27,10 @@ extension ReportEndpoint: Endpoint {
2927

3028
var method: HTTPMethod {
3129
switch self {
30+
case.register:
31+
return .post
3232
case .fetchReports, .fetchReportDetail:
33-
.get
33+
return .get
3434
}
3535
}
3636

@@ -47,7 +47,12 @@ extension ReportEndpoint: Endpoint {
4747
}
4848

4949
var bodyParameters: [String : Any] {
50-
return [:]
50+
switch self {
51+
case .register(let report):
52+
return report.dictionary
53+
case .fetchReports, .fetchReportDetail:
54+
return [:]
55+
}
5156
}
5257

5358
var isAuthorized: Bool {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//
2+
// S3UploadEndpoint.swift
3+
// DataSource
4+
//
5+
// Created by 이동현 on 11/22/25.
6+
//
7+
8+
import Foundation
9+
10+
enum S3Endpoint {
11+
case uploadImage(uploadURL: String, data: Data)
12+
}
13+
14+
extension S3Endpoint: Endpoint {
15+
var baseURL: String {
16+
return ""
17+
}
18+
19+
var path: String {
20+
switch self {
21+
case .uploadImage(let uploadURL, _):
22+
return uploadURL
23+
}
24+
}
25+
26+
var method: HTTPMethod {
27+
switch self {
28+
case .uploadImage:
29+
return .put
30+
}
31+
}
32+
33+
var headers: [String : String] {
34+
switch self {
35+
case .uploadImage:
36+
return [:]
37+
}
38+
}
39+
40+
var queryParameters: [String : String] {
41+
42+
return [:]
43+
}
44+
45+
var bodyParameters: [String : Any] {
46+
return [:]
47+
}
48+
49+
var isAuthorized: Bool {
50+
return false
51+
}
52+
53+
var bodyType: EndpointBodyType {
54+
return .rawData
55+
}
56+
57+
var bodyData: Data? {
58+
switch self {
59+
case .uploadImage(_, let data):
60+
return data
61+
}
62+
}
63+
}

Projects/DataSource/Sources/NetworkService/Extension/Endpoint+.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@ extension Endpoint {
1212
var request = try URLRequest(urlString: path, queryParameters: queryParameters)
1313
request.httpMethod = method.rawValue
1414
request.makeHeaders(headers: headers)
15-
try request.makeBodyParameter(with: bodyParameters)
15+
switch bodyType {
16+
case .json:
17+
try request.makeBodyParameter(with: bodyParameters)
18+
case .rawData:
19+
if let data = bodyData {
20+
request.httpBody = data
21+
}
22+
}
1623
request.cachePolicy = .reloadIgnoringLocalCacheData
1724
return request
1825
}

0 commit comments

Comments
 (0)