// // StatisticsAPI.swift // suixinkan // // Created by Codex on 2026/6/22. // import Foundation import Combine @MainActor /// 数据统计服务协议,抽象汇总和每日明细读取能力以便测试替换。 protocol StatisticsServing { /// 获取统计汇总。 func summary(scenicId: Int, range: String, isScenicAdmin: Bool) async throws -> StatisticsSummaryResponse /// 获取每日统计分页列表。 func dailyList( scenicId: Int, startTime: String, endTime: String, page: Int, pageSize: Int, isScenicAdmin: Bool ) async throws -> DataListPayload } @MainActor /// 数据统计 API,封装摄影师和景区管理员两套统计接口。 final class StatisticsAPI: StatisticsServing { private let client: APIClient /// 初始化数据统计 API,并注入共享网络客户端。 init(client: APIClient) { self.client = client } /// 获取统计汇总。 func summary(scenicId: Int, range: String, isScenicAdmin: Bool) async throws -> StatisticsSummaryResponse { try await client.send( APIRequest( method: .get, path: isScenicAdmin ? "/api/app/scenic-admin/analyse" : "/api/yf-handset-app/photog/analyse/user", queryItems: [ URLQueryItem(name: "scenic_id", value: "\(scenicId)"), URLQueryItem(name: "range", value: range) ] ) ) } /// 获取每日统计分页列表。 func dailyList( scenicId: Int, startTime: String, endTime: String, page: Int = 1, pageSize: Int = 15, isScenicAdmin: Bool ) async throws -> DataListPayload { var query = [ URLQueryItem(name: "scenic_id", value: "\(scenicId)"), URLQueryItem(name: "page", value: "\(max(page, 1))"), URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))") ] if !startTime.isEmpty { query.append(URLQueryItem(name: "start_time", value: startTime)) } if !endTime.isEmpty { query.append(URLQueryItem(name: "end_time", value: endTime)) } return try await client.send( APIRequest( method: .get, path: isScenicAdmin ? "/api/app/scenic-admin/analyse/daily" : "/api/yf-handset-app/photog/analyse/user/daily", queryItems: query ) ) } }