// // TravelAlbumAPI.swift // suixinkan // import Foundation @MainActor /// 旅拍相册服务协议,抽象相册列表、创建、详情与素材接口。 protocol TravelAlbumServing { /// 拉取可绑定订单。 func availableOrders() async throws -> [TravelAlbumAvailableOrder] /// 创建旅拍相册。 func create(_ request: TravelAlbumCreateRequest) async throws -> TravelAlbumCreateResponse /// 拉取旅拍相册列表。 func list(page: Int, pageSize: Int) async throws -> TravelAlbumListResponse /// 拉取旅拍相册详情。 func info(id: Int) async throws -> TravelAlbum /// 拉取旅拍相册素材列表。 func materialList( userEquityTravelId: Int, page: Int, pageSize: Int, orderBy: Int, isPurchased: Int? ) async throws -> TravelAlbumListResponse /// 上传并登记旅拍相册素材。 func uploadMaterial(_ request: TravelAlbumUploadMaterialRequest) async throws -> TravelAlbumMaterial /// 拉取相册内已登记素材的客户端照片 ID。 func materialClientPhotoIds(userEquityTravelId: Int) async throws -> TravelAlbumMaterialClientPhotoIDsResponse /// 删除旅拍相册。 func deleteAlbum(id: Int) async throws /// 删除旅拍相册素材。 func deleteMaterial(id: Int) async throws /// 拉取相册小程序码。 func mpCode(id: Int) async throws -> TravelAlbumMpCodeResponse } @MainActor /// 旅拍相册 API,封装 Android `photog/travel-album` 接口组。 final class TravelAlbumAPI: TravelAlbumServing { private let client: APIClient private let basePath = "/api/yf-handset-app/photog/travel-album" /// 初始化旅拍相册 API。 init(client: APIClient) { self.client = client } /// 拉取可绑定订单。 func availableOrders() async throws -> [TravelAlbumAvailableOrder] { try await client.send(APIRequest(method: .get, path: "\(basePath)/available-order")) } /// 创建旅拍相册。 func create(_ request: TravelAlbumCreateRequest) async throws -> TravelAlbumCreateResponse { try await client.send(APIRequest(method: .post, path: "\(basePath)/create", body: request)) } /// 拉取旅拍相册列表。 func list(page: Int = 1, pageSize: Int = 20) async throws -> TravelAlbumListResponse { try await client.send( APIRequest( method: .get, path: "\(basePath)/list", queryItems: [ URLQueryItem(name: "page", value: String(max(page, 1))), URLQueryItem(name: "page_size", value: String(max(pageSize, 1))), ] ) ) } /// 拉取旅拍相册详情。 func info(id: Int) async throws -> TravelAlbum { try await client.send( APIRequest( method: .get, path: "\(basePath)/info", queryItems: [URLQueryItem(name: "id", value: String(id))] ) ) } /// 拉取旅拍相册素材列表。 func materialList( userEquityTravelId: Int, page: Int = 1, pageSize: Int = 20, orderBy: Int = 2, isPurchased: Int? = nil ) async throws -> TravelAlbumListResponse { var items = [ URLQueryItem(name: "user_equity_travel_id", value: String(userEquityTravelId)), URLQueryItem(name: "page", value: String(max(page, 1))), URLQueryItem(name: "page_size", value: String(max(pageSize, 1))), URLQueryItem(name: "order_by", value: String(orderBy)), ] if let isPurchased { items.append(URLQueryItem(name: "is_purchased", value: String(isPurchased))) } return try await client.send( APIRequest(method: .get, path: "\(basePath)/material-list", queryItems: items) ) } /// 上传并登记旅拍相册素材。 func uploadMaterial(_ request: TravelAlbumUploadMaterialRequest) async throws -> TravelAlbumMaterial { try await client.send(APIRequest(method: .post, path: "\(basePath)/upload-material", body: request)) } /// 拉取相册内已登记素材的客户端照片 ID。 func materialClientPhotoIds(userEquityTravelId: Int) async throws -> TravelAlbumMaterialClientPhotoIDsResponse { try await client.send( APIRequest( method: .get, path: "\(basePath)/material-client-photo-ids", queryItems: [ URLQueryItem(name: "user_equity_travel_id", value: String(userEquityTravelId)), ] ) ) } /// 删除旅拍相册。 func deleteAlbum(id: Int) async throws { let _: EmptyPayload = try await client.send( APIRequest(method: .post, path: "\(basePath)/delete", body: TravelAlbumIDRequest(id: id)) ) } /// 删除旅拍相册素材。 func deleteMaterial(id: Int) async throws { let _: EmptyPayload = try await client.send( APIRequest(method: .post, path: "\(basePath)/delete-material", body: TravelAlbumIDRequest(id: id)) ) } /// 拉取相册小程序码。 func mpCode(id: Int) async throws -> TravelAlbumMpCodeResponse { try await client.send( APIRequest( method: .get, path: "\(basePath)/mp-code", queryItems: [URLQueryItem(name: "id", value: String(id))] ) ) } } /// 旅拍相册 ID 请求体。 private struct TravelAlbumIDRequest: Encodable, Sendable { let id: Int }