// // ProjectAPI.swift // suixinkan // // Created by Codex on 2026/6/24. // import Foundation import Observation /// 项目服务协议,抽象摄影师项目和店铺项目接口以便 ViewModel 测试替换。 @MainActor protocol ProjectServing { /// 获取摄影师项目列表。 func projectList(scenicId: Int, name: String?, page: Int, pageSize: Int) async throws -> ListPayload /// 获取摄影师项目详情。 func projectDetail(id: Int) async throws -> PhotographerProjectDetailResponse /// 创建摄影师项目。 func createProject(_ request: ProjectCreateRequest) async throws /// 编辑摄影师项目。 func editProject(_ request: ProjectCreateRequest) async throws /// 删除摄影师项目。 func deleteProject(id: Int) async throws /// 获取店铺项目可管理景区。 func storeManagerScenicList(userId: String) async throws -> ListPayload /// 获取店铺项目列表。 func storeManagerProjectList(userId: String?, page: Int, pageSize: Int) async throws -> ListPayload /// 获取店铺项目详情。 func storeManagerProjectDetail(id: Int) async throws -> PhotographerProjectDetailResponse /// 创建店铺多点位项目。 func storeManagerCreate(_ request: StoreManagerCreateRequest) async throws /// 创建店铺押金项目。 func storeManagerOfflineCreate(_ request: StoreManagerOfflineCreateRequest) async throws /// 更新店铺多点位项目。 func storeManagerUpdate(_ request: StoreManagerUpdateRequest) async throws /// 更新店铺押金项目。 func storeManagerOfflineUpdate(_ request: StoreManagerOfflineUpdateRequest) async throws /// 删除店铺项目。 func storeManagerDeleteProject(id: Int) async throws /// 获取全部门店,用于店铺押金项目选择门店。 func storeAll() async throws -> ListPayload } /// 项目 API,封装项目管理、店铺项目管理相关接口。 @MainActor @Observable final class ProjectAPI: ProjectServing { @ObservationIgnored private let client: APIClient /// 初始化项目 API,并注入共享网络客户端。 init(client: APIClient) { self.client = client } /// 获取摄影师项目列表。 func projectList(scenicId: Int, name: String? = nil, page: Int = 1, pageSize: Int = 10) async throws -> ListPayload { var query = [ URLQueryItem(name: "scenic_id", value: "\(scenicId)"), URLQueryItem(name: "page", value: "\(max(page, 1))"), URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))") ] if let name = name?.trimmingCharacters(in: .whitespacesAndNewlines), !name.isEmpty { query.append(URLQueryItem(name: "name", value: name)) } return try await client.send( APIRequest(method: .get, path: "/api/yf-handset-app/photog/project/list", queryItems: query) ) } /// 获取摄影师项目详情。 func projectDetail(id: Int) async throws -> PhotographerProjectDetailResponse { try await client.send( APIRequest( method: .get, path: "/api/yf-handset-app/photog/project/info-view", queryItems: [URLQueryItem(name: "id", value: "\(id)")] ) ) } /// 创建摄影师项目。 func createProject(_ request: ProjectCreateRequest) async throws { _ = try await client.send( APIRequest(method: .post, path: "/api/yf-handset-app/photog/project/create", body: request) ) as EmptyPayload } /// 编辑摄影师项目。 func editProject(_ request: ProjectCreateRequest) async throws { _ = try await client.send( APIRequest(method: .post, path: "/api/yf-handset-app/photog/project/edit", body: request) ) as EmptyPayload } /// 删除摄影师项目。 func deleteProject(id: Int) async throws { _ = try await client.send( APIRequest(method: .post, path: "/api/yf-handset-app/photog/project/delete", body: ProjectDeleteRequest(id: id)) ) as EmptyPayload } /// 获取店铺项目可管理景区。 func storeManagerScenicList(userId: String) async throws -> ListPayload { try await client.send( APIRequest( method: .get, path: "/api/app/store-manager/scenic-list", queryItems: [URLQueryItem(name: "user_id", value: userId)] ) ) } /// 获取店铺项目列表。 func storeManagerProjectList(userId: String?, page: Int = 1, pageSize: Int = 20) async throws -> ListPayload { var query = [ URLQueryItem(name: "page", value: "\(max(page, 1))"), URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))") ] if let userId = userId?.trimmingCharacters(in: .whitespacesAndNewlines), !userId.isEmpty { query.append(URLQueryItem(name: "user_id", value: userId)) } return try await client.send( APIRequest(method: .get, path: "/api/app/store-manager/list", queryItems: query) ) } /// 获取店铺项目详情。 func storeManagerProjectDetail(id: Int) async throws -> PhotographerProjectDetailResponse { try await client.send( APIRequest(method: .get, path: "/api/app/store-manager/detail", queryItems: [URLQueryItem(name: "id", value: "\(id)")]) ) } /// 创建店铺多点位项目。 func storeManagerCreate(_ request: StoreManagerCreateRequest) async throws { _ = try await client.send(APIRequest(method: .post, path: "/api/app/store-manager/create", body: request)) as EmptyPayload } /// 创建店铺押金项目。 func storeManagerOfflineCreate(_ request: StoreManagerOfflineCreateRequest) async throws { _ = try await client.send(APIRequest(method: .post, path: "/api/app/store-manager/offline-create", body: request)) as EmptyPayload } /// 更新店铺多点位项目。 func storeManagerUpdate(_ request: StoreManagerUpdateRequest) async throws { _ = try await client.send(APIRequest(method: .post, path: "/api/app/store-manager/update", body: request)) as EmptyPayload } /// 更新店铺押金项目。 func storeManagerOfflineUpdate(_ request: StoreManagerOfflineUpdateRequest) async throws { _ = try await client.send(APIRequest(method: .post, path: "/api/app/store-manager/offline-update", body: request)) as EmptyPayload } /// 删除店铺项目。 func storeManagerDeleteProject(id: Int) async throws { _ = try await client.send( APIRequest(method: .post, path: "/api/app/store-manager/delete", body: ProjectDeleteRequest(id: id)) ) as EmptyPayload } /// 获取全部门店。 func storeAll() async throws -> ListPayload { try await client.send(APIRequest(method: .get, path: "/api/app/store/all")) } }