Files
suixinkan_uikit/suixinkan/Features/WildPhotographerReport/API/WildPhotographerReportAPI.swift

259 lines
8.2 KiB
Swift

//
// WildPhotographerReportAPI.swift
// suixinkan
//
import Foundation
/// 举报摄影师服务协议,封装举报类型等后端接口。
@MainActor
protocol WildPhotographerReportServing {
/// 拉取提交举报可选类型。
func reportTypes() async throws -> WildReportTypeListResponse
/// 拉取举报首页须知与规则文案。
func reportCopy() async throws -> WildReportCopyResponse
/// 提交摄影师举报。
func submitReport(_ request: WildReportSubmitRequest) async throws -> WildReportSubmitResponse
/// 为已有举报补充证据。
func supplementReport(_ request: WildReportSupplementRequest) async throws
/// 拉取附近风险地图点位。
func riskMap(_ request: WildReportRiskMapRequest) async throws -> WildReportRiskMapResponse
/// 拉取风险地图单个标记详情。
func markerDetail(_ request: WildReportMarkerDetailRequest) async throws -> WildReportMarkerDetailResponse
/// 拉取我的举报列表。
func reportList(_ request: WildReportListRequest) async throws -> WildReportListResponse
/// 拉取单条举报详情。
func reportDetail(id: Int) async throws -> WildReportDetailData
/// 拉取举报微信小程序分享配置。
func reportShare(id: String) async throws -> WildReportMiniProgramShareData
}
/// 举报摄影师 API,负责和 `photog/report` 相关接口通讯。
@MainActor
final class WildPhotographerReportAPI: WildPhotographerReportServing {
private let client: APIClient
/// 初始化举报摄影师 API。
init(client: APIClient) {
self.client = client
}
/// 拉取提交举报可选类型。
func reportTypes() async throws -> WildReportTypeListResponse {
try await client.send(
APIRequest(method: .get, path: "/api/yf-handset-app/photog/report/types")
)
}
/// 拉取举报首页须知与规则文案。
func reportCopy() async throws -> WildReportCopyResponse {
try await client.send(
APIRequest(method: .get, path: "/api/yf-handset-app/photog/report/copy")
)
}
/// 提交摄影师举报。
func submitReport(_ request: WildReportSubmitRequest) async throws -> WildReportSubmitResponse {
try await client.send(
APIRequest(
method: .post,
path: "/api/yf-handset-app/photog/report/submit",
body: request
)
)
}
/// 为已有举报补充证据。
func supplementReport(_ request: WildReportSupplementRequest) async throws {
let _: EmptyPayload = try await client.send(
APIRequest(
method: .post,
path: "/api/yf-handset-app/photog/report/supplement",
body: request
)
)
}
/// 拉取附近风险地图点位。
func riskMap(_ request: WildReportRiskMapRequest) async throws -> WildReportRiskMapResponse {
try await client.send(
APIRequest(
method: .get,
path: "/api/yf-handset-app/photog/report/risk-map",
queryItems: request.queryItems
)
)
}
/// 拉取风险地图单个标记详情。
func markerDetail(_ request: WildReportMarkerDetailRequest) async throws -> WildReportMarkerDetailResponse {
try await client.send(
APIRequest(
method: .get,
path: "/api/yf-handset-app/photog/report/marker-detail",
queryItems: request.queryItems
)
)
}
/// 拉取我的举报列表。
func reportList(_ request: WildReportListRequest) async throws -> WildReportListResponse {
try await client.send(
APIRequest(
method: .get,
path: "/api/yf-handset-app/photog/report/list",
queryItems: request.queryItems
)
)
}
/// 拉取单条举报详情。
func reportDetail(id: Int) async throws -> WildReportDetailData {
try await client.send(
APIRequest(
method: .get,
path: "/api/yf-handset-app/photog/report/detail",
queryItems: [URLQueryItem(name: "id", value: String(id))]
)
)
}
/// 拉取举报微信小程序分享配置。
func reportShare(id: String) async throws -> WildReportMiniProgramShareData {
try await client.send(
APIRequest(
method: .get,
path: "/api/yf-handset-app/photog/report/share",
queryItems: [URLQueryItem(name: "id", value: id)]
)
)
}
}
/// 补充证据接口请求体。
struct WildReportSupplementRequest: Encodable, Equatable {
let id: Int
let desc: String?
let evidences: [WildReportEvidenceRequest]?
}
/// 附近风险地图接口请求参数。
struct WildReportRiskMapRequest: Encodable, Equatable {
let scenicId: Int
let latitude: Double?
let longitude: Double?
var queryItems: [URLQueryItem] {
var items = [URLQueryItem(name: "scenic_id", value: String(scenicId))]
if let latitude {
items.append(URLQueryItem(name: "latitude", value: String(latitude)))
}
if let longitude {
items.append(URLQueryItem(name: "longitude", value: String(longitude)))
}
return items
}
enum CodingKeys: String, CodingKey {
case scenicId = "scenic_id"
case latitude
case longitude
}
}
/// 风险地图标记详情接口请求参数。
struct WildReportMarkerDetailRequest: Encodable, Equatable {
let scenicId: Int
let markerType: String
let id: Int
let latitude: Double?
let longitude: Double?
var queryItems: [URLQueryItem] {
var items = [
URLQueryItem(name: "scenic_id", value: String(scenicId)),
URLQueryItem(name: "marker_type", value: markerType),
URLQueryItem(name: "id", value: String(id))
]
if let latitude {
items.append(URLQueryItem(name: "latitude", value: String(latitude)))
}
if let longitude {
items.append(URLQueryItem(name: "longitude", value: String(longitude)))
}
return items
}
enum CodingKeys: String, CodingKey {
case scenicId = "scenic_id"
case markerType = "marker_type"
case id
case latitude
case longitude
}
}
/// 提交举报接口请求体。
struct WildReportSubmitRequest: Encodable, Equatable {
let scenicId: Int
let reportType: Int
let desc: String
let storeUserId: Int?
let contactPhone: String?
let locationName: String?
let locationAddress: String?
let lat: Double
let lng: Double
let evidences: [WildReportEvidenceRequest]
let paymentScreenshots: [WildReportEvidenceRequest]
enum CodingKeys: String, CodingKey {
case scenicId = "scenic_id"
case reportType = "report_type"
case desc
case storeUserId = "store_user_id"
case contactPhone = "contact_phone"
case locationName = "location_name"
case locationAddress = "location_address"
case lat
case lng
case evidences
case paymentScreenshots = "payment_screenshots"
}
}
/// 提交举报接口响应体,包含后端生成的举报 ID 和举报编号。
struct WildReportSubmitResponse: Decodable, Equatable {
let id: Int
let complaintNo: String
enum CodingKeys: String, CodingKey {
case id
case complaintNo = "complaint_no"
}
init(id: Int = 0, complaintNo: String = "") {
self.id = id
self.complaintNo = complaintNo
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decodeIfPresent(Int.self, forKey: .id) ?? 0
complaintNo = try container.decodeIfPresent(String.self, forKey: .complaintNo) ?? ""
}
}
/// 提交举报接口中的附件项。
struct WildReportEvidenceRequest: Encodable, Equatable {
let fileURL: String
let fileType: Int
let fileName: String?
enum CodingKeys: String, CodingKey {
case fileURL = "file_url"
case fileType = "file_type"
case fileName = "file_name"
}
}