// // ScenicQueueAPI.swift // suixinkan // // Created by Codex on 2026/6/25. // import Foundation /// 排队管理服务协议,定义列表、动作、设置、二维码和实时 token 能力。 @MainActor protocol ScenicQueueServing: AnyObject { /// scenic排队统计相关逻辑。 func scenicQueueStats(scenicId: Int, scenicSpotId: Int) async throws -> ScenicQueueStatsData /// scenic排队Home相关逻辑。 func scenicQueueHome(scenicId: Int, scenicSpotId: Int, type: Int, page: Int, pageSize: Int) async throws -> ScenicQueueHomeData /// socket令牌相关逻辑。 func socketToken() async throws -> SocketTokenResponse /// scenic排队Call相关逻辑。 func scenicQueueCall(id: Int64) async throws -> ScenicQueueCallData /// scenic排队Pass相关逻辑。 func scenicQueuePass(id: Int64) async throws -> ScenicQueuePassData /// scenic排队Finish相关逻辑。 func scenicQueueFinish(id: Int64) async throws -> ScenicQueueFinishData /// scenic排队RequeueInsertBefore相关逻辑。 func scenicQueueRequeueInsertBefore(recordId: Int64, operatorId: Int) async throws /// scenic排队UserMark相关逻辑。 func scenicQueueUserMark(_ request: ScenicQueueUserMarkRequest) async throws /// scenic排队Setting相关逻辑。 func scenicQueueSetting(scenicId: Int, scenicSpotId: Int?) async throws -> ScenicQueueSettingData /// scenic排队保存Setting相关逻辑。 func scenicQueueSaveSetting(_ request: ScenicQueueSaveSettingRequest) async throws /// scenic排队Shoot排队QRCode相关逻辑。 func scenicQueueShootQueueQRCode(scenicId: Int, scenicSpotId: Int) async throws -> ScenicQueueShootQueueQRCodeData /// scenic排队SettingChangeLog相关逻辑。 func scenicQueueSettingChangeLog(scenicId: Int, scenicSpotId: Int?, page: Int, pageSize: Int) async throws -> ScenicQueueSettingChangeLogData } @MainActor /// 排队管理 API,封装 `/api/app/scenic-queue` 下的排队接口。 final class ScenicQueueAPI { private let client: APIClient /// 初始化排队管理 API,并注入共享网络客户端。 init(client: APIClient) { self.client = client } /// 获取当前打卡点排队统计。 func scenicQueueStats(scenicId: Int, scenicSpotId: Int) async throws -> ScenicQueueStatsData { do { return try await client.send( APIRequest( method: .get, path: "/api/app/scenic-queue/queue-stats", queryItems: [ URLQueryItem(name: "scenic_id", value: String(scenicId)), URLQueryItem(name: "scenic_spot_id", value: String(scenicSpotId)) ] ) ) } catch APIError.emptyData { return ScenicQueueStatsData() } } /// 获取当前打卡点排队列表。 func scenicQueueHome( scenicId: Int, scenicSpotId: Int, type: Int, page: Int = 1, pageSize: Int = 20 ) async throws -> ScenicQueueHomeData { do { return try await client.send( APIRequest( method: .get, path: "/api/app/scenic-queue/home", queryItems: [ URLQueryItem(name: "scenic_id", value: String(scenicId)), URLQueryItem(name: "scenic_spot_id", value: String(scenicSpotId)), URLQueryItem(name: "type", value: String(type)), URLQueryItem(name: "page", value: String(max(page, 1))), URLQueryItem(name: "page_size", value: String(max(pageSize, 1))) ] ) ) } catch APIError.emptyData { return ScenicQueueHomeData() } } /// 获取 WebSocket 订阅 token。 func socketToken() async throws -> SocketTokenResponse { try await client.send(APIRequest(method: .get, path: "/api/app/socket-token")) } /// 叫号。 func scenicQueueCall(id: Int64) async throws -> ScenicQueueCallData { do { return try await client.send( APIRequest(method: .post, path: "/api/app/scenic-queue/call", body: ScenicQueueActionRequest(id: id)) ) } catch APIError.emptyData { return ScenicQueueCallData(id: id) } } /// 标记过号。 func scenicQueuePass(id: Int64) async throws -> ScenicQueuePassData { do { return try await client.send( APIRequest(method: .post, path: "/api/app/scenic-queue/pass", body: ScenicQueueActionRequest(id: id)) ) } catch APIError.emptyData { return ScenicQueuePassData(id: id) } } /// 标记完成。 func scenicQueueFinish(id: Int64) async throws -> ScenicQueueFinishData { do { return try await client.send( APIRequest(method: .post, path: "/api/app/scenic-queue/finish", body: ScenicQueueActionRequest(id: id)) ) } catch APIError.emptyData { return ScenicQueueFinishData(id: id) } } /// 将过号记录重新插回当前排队队列。 func scenicQueueRequeueInsertBefore(recordId: Int64, operatorId: Int) async throws { let _: EmptyPayload = try await client.send( APIRequest( method: .post, path: "/api/app/scenic-queue/requeue-insert-before", body: ScenicQueueRequeueInsertBeforeRequest(recordId: recordId, operatorId: operatorId) ) ) } /// 标记用户身份/限制排队。 func scenicQueueUserMark(_ request: ScenicQueueUserMarkRequest) async throws { let _: EmptyPayload = try await client.send( APIRequest(method: .post, path: "/api/app/scenic-queue/user-mark", body: request) ) } /// 获取排队设置。 func scenicQueueSetting(scenicId: Int, scenicSpotId: Int?) async throws -> ScenicQueueSettingData { var query = [URLQueryItem(name: "scenic_id", value: String(scenicId))] if let scenicSpotId { query.append(URLQueryItem(name: "scenic_spot_id", value: String(scenicSpotId))) } do { return try await client.send( APIRequest(method: .get, path: "/api/app/scenic-queue/setting", queryItems: query) ) } catch APIError.emptyData { return ScenicQueueSettingData() } } /// 保存排队设置。 func scenicQueueSaveSetting(_ request: ScenicQueueSaveSettingRequest) async throws { let _: EmptyPayload = try await client.send( APIRequest(method: .post, path: "/api/app/scenic-queue/save-setting", body: request) ) } /// 获取取号二维码。 func scenicQueueShootQueueQRCode(scenicId: Int, scenicSpotId: Int) async throws -> ScenicQueueShootQueueQRCodeData { try await client.send( APIRequest( method: .get, path: "/api/app/scenic-queue/shoot-queue-qrcode", queryItems: [ URLQueryItem(name: "scenic_id", value: String(scenicId)), URLQueryItem(name: "scenic_spot_id", value: String(scenicSpotId)) ] ) ) } /// 获取排队设置变更日志。 func scenicQueueSettingChangeLog( scenicId: Int, scenicSpotId: Int?, page: Int = 1, pageSize: Int = 20 ) async throws -> ScenicQueueSettingChangeLogData { var query = [ URLQueryItem(name: "scenic_id", value: String(scenicId)), URLQueryItem(name: "page", value: String(max(page, 1))), URLQueryItem(name: "page_size", value: String(max(pageSize, 1))) ] if let scenicSpotId { query.append(URLQueryItem(name: "scenic_spot_id", value: String(scenicSpotId))) } do { return try await client.send( APIRequest(method: .get, path: "/api/app/scenic-queue/setting-change-log", queryItems: query) ) } catch APIError.emptyData { return ScenicQueueSettingChangeLogData() } } } extension ScenicQueueAPI: ScenicQueueServing {}