Files
汉秋 703078352c 从 iOS 17 Observation 迁移至 iOS 16 兼容的 Combine 架构
将最低部署版本降至 iOS 16,以 ObservableObject 替换 @Observable,新增导航与 UI 兼容层,并补充登录冒烟 UI 测试。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 10:16:35 +08:00

375 lines
14 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// AssetsAPI.swift
// suixinkan
//
// Created by Codex on 2026/6/23.
//
import Foundation
import Combine
/// 便 ViewModel
@MainActor
protocol AssetsServing {
///
func cloudFileList(parentFolderId: Int, name: String, type: Int, orderBy: Int, page: Int, pageSize: Int) async throws -> ListPayload<CloudDriveFile>
///
func cloudFolderCreate(_ request: CloudFolderCreateRequest) async throws
/// OSS
func cloudFileUpload(_ request: CloudFileUploadRequest) async throws
///
func cloudFileDelete(_ request: CloudFileDeleteRequest) async throws
///
func cloudFileMove(_ request: CloudFileMoveRequest) async throws
///
func cloudFolderEdit(_ request: CloudFolderModifyRequest) async throws
///
func cloudFileEdit(_ request: CloudFileModifyRequest) async throws
///
func checkCloudUploadPermission() async throws -> CheckCloudUploadResponse
///
func mediaAlbumList(kind: MediaLibraryKind, keyword: String, status: Int?, page: Int, pageSize: Int) async throws -> MediaLibraryListResponse
///
func mediaAlbumDetail(id: Int, kind: MediaLibraryKind) async throws -> MediaLibraryDetail
///
func mediaAlbumOperation(_ request: MediaAlbumOperationRequest) async throws
///
func mediaAlbumDelete(_ request: MediaAlbumDeleteRequest) async throws
///
func mediaAlbumAddTag(_ request: MediaAlbumAddTagRequest) async throws
///
func mediaAlbumUpload(_ request: MediaAlbumUploadRequest) async throws
///
func mediaAlbumEdit(_ request: MediaAlbumEditRequest) async throws
///
func projectList(scenicId: Int, name: String?, page: Int, pageSize: Int) async throws -> ListPayload<PhotographerProjectItem>
///
func albumFolderList(scenicId: Int, page: Int, pageSize: Int, name: String, startTime: String?, endTime: String?) async throws -> ListPayload<AlbumFolderItem>
///
func albumFolderInfo(id: Int) async throws -> AlbumFolderItem
///
func albumFileList(scenicId: Int, folderId: Int, fileType: Int, page: Int, pageSize: Int) async throws -> ListPayload<AlbumFileItem>
///
func addAlbumFolder(scenicId: Int, name: String, remark: String) async throws
///
func editAlbumFolder(folderId: Int, coverFileId: Int?, name: String?, remark: String?) async throws
///
func deleteAlbumFiles(folderId: Int, idList: [Int]) async throws
/// OSS
func albumFileUploadURL(scenicId: Int, fileURL: String, folderId: Int) async throws
}
/// API
@MainActor
final class AssetsAPI: AssetsServing {
private let client: APIClient
/// API
init(client: APIClient) {
self.client = client
}
///
func cloudFileList(
parentFolderId: Int,
name: String = "",
type: Int = 0,
orderBy: Int = 2,
page: Int = 1,
pageSize: Int = 20
) async throws -> ListPayload<CloudDriveFile> {
try await client.send(
APIRequest(
method: .get,
path: "/api/yf-handset-app/photog/cloud-driver/list",
queryItems: [
URLQueryItem(name: "parent_folder_id", value: "\(parentFolderId)"),
URLQueryItem(name: "name", value: name),
URLQueryItem(name: "type", value: "\(type)"),
URLQueryItem(name: "order_by", value: "\(orderBy)"),
URLQueryItem(name: "page", value: "\(max(page, 1))"),
URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))")
]
)
)
}
///
func cloudFolderCreate(_ request: CloudFolderCreateRequest) async throws {
_ = try await client.send(
APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/folder-create", body: request)
) as EmptyPayload
}
/// OSS
func cloudFileUpload(_ request: CloudFileUploadRequest) async throws {
_ = try await client.send(
APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/file-upload", body: request)
) as EmptyPayload
}
///
func cloudFileDelete(_ request: CloudFileDeleteRequest) async throws {
_ = try await client.send(
APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/delete", body: request)
) as EmptyPayload
}
///
func cloudFileMove(_ request: CloudFileMoveRequest) async throws {
_ = try await client.send(
APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/move", body: request)
) as EmptyPayload
}
///
func cloudFolderEdit(_ request: CloudFolderModifyRequest) async throws {
_ = try await client.send(
APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/folder-edit", body: request)
) as EmptyPayload
}
///
func cloudFileEdit(_ request: CloudFileModifyRequest) async throws {
_ = try await client.send(
APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/file-edit", body: request)
) as EmptyPayload
}
///
func checkCloudUploadPermission() async throws -> CheckCloudUploadResponse {
try await client.send(
APIRequest(method: .get, path: "/api/yf-handset-app/photog/cloud-driver/check-upload-permission")
)
}
///
func mediaAlbumList(
kind: MediaLibraryKind = .material,
keyword: String = "",
status: Int? = nil,
page: Int = 1,
pageSize: Int = 10
) async throws -> MediaLibraryListResponse {
var query = [
URLQueryItem(name: "type", value: "\(kind.rawValue)"),
URLQueryItem(name: "keyword", value: keyword),
URLQueryItem(name: "page", value: "\(max(page, 1))"),
URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))")
]
if let status, status >= 0 {
query.append(URLQueryItem(name: "status", value: "\(status)"))
}
return try await client.send(
APIRequest(method: .get, path: "/api/app/media-album/list", queryItems: query)
)
}
///
func mediaAlbumDetail(id: Int, kind: MediaLibraryKind = .material) async throws -> MediaLibraryDetail {
try await client.send(
APIRequest(
method: .get,
path: "/api/app/media-album/detail",
queryItems: [
URLQueryItem(name: "id", value: "\(id)"),
URLQueryItem(name: "type", value: "\(kind.rawValue)")
]
)
)
}
///
func mediaAlbumOperation(_ request: MediaAlbumOperationRequest) async throws {
_ = try await client.send(
APIRequest(method: .post, path: "/api/app/media-album/operation", body: request)
) as EmptyPayload
}
///
func mediaAlbumDelete(_ request: MediaAlbumDeleteRequest) async throws {
_ = try await client.send(
APIRequest(method: .post, path: "/api/app/media-album/delete", body: request)
) as EmptyPayload
}
///
func mediaAlbumAddTag(_ request: MediaAlbumAddTagRequest) async throws {
_ = try await client.send(
APIRequest(method: .post, path: "/api/app/media-album/add-tag", body: request)
) as EmptyPayload
}
///
func mediaAlbumUpload(_ request: MediaAlbumUploadRequest) async throws {
_ = try await client.send(
APIRequest(method: .post, path: "/api/app/media-album/upload", body: request)
) as EmptyPayload
}
///
func mediaAlbumEdit(_ request: MediaAlbumEditRequest) async throws {
_ = try await client.send(
APIRequest(method: .post, path: "/api/app/media-album/edit", body: request)
) as EmptyPayload
}
///
func projectList(
scenicId: Int,
name: String? = nil,
page: Int = 1,
pageSize: Int = 50
) async throws -> ListPayload<PhotographerProjectItem> {
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.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 albumFolderList(
scenicId: Int,
page: Int = 1,
pageSize: Int = 10,
name: String = "",
startTime: String? = nil,
endTime: String? = nil
) async throws -> ListPayload<AlbumFolderItem> {
var query = [
URLQueryItem(name: "scenic_id", value: "\(scenicId)"),
URLQueryItem(name: "page", value: "\(max(page, 1))"),
URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))"),
URLQueryItem(name: "cloud_folder_type", value: "1")
]
if !name.isEmpty {
query.append(URLQueryItem(name: "name", value: name))
}
if let startTime, !startTime.isEmpty {
query.append(URLQueryItem(name: "start_time", value: startTime))
}
if let endTime, !endTime.isEmpty {
query.append(URLQueryItem(name: "end_time", value: endTime))
}
return try await client.send(
APIRequest(method: .get, path: "/api/yf-handset-app/photog/album/folder-list", queryItems: query)
)
}
///
func albumFolderInfo(id: Int) async throws -> AlbumFolderItem {
try await client.send(
APIRequest(
method: .get,
path: "/api/yf-handset-app/photog/album/folder-info",
queryItems: [URLQueryItem(name: "id", value: "\(id)")]
)
)
}
///
func albumFileList(
scenicId: Int,
folderId: Int,
fileType: Int,
page: Int = 1,
pageSize: Int = 20
) async throws -> ListPayload<AlbumFileItem> {
try await client.send(
APIRequest(
method: .get,
path: "/api/yf-handset-app/photog/album/file-list",
queryItems: [
URLQueryItem(name: "scenic_id", value: "\(scenicId)"),
URLQueryItem(name: "folder_id", value: "\(folderId)"),
URLQueryItem(name: "file_type", value: "\(fileType)"),
URLQueryItem(name: "page", value: "\(max(page, 1))"),
URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))")
]
)
)
}
///
func addAlbumFolder(scenicId: Int, name: String, remark: String) async throws {
_ = try await client.send(
APIRequest(
method: .post,
path: "/api/yf-handset-app/photog/album/folder-add",
body: AlbumFolderAddRequest(
scenicId: "\(scenicId)",
name: name,
remark: remark,
cloudFolderType: 1
)
)
) as EmptyPayload
}
///
func editAlbumFolder(folderId: Int, coverFileId: Int? = nil, name: String? = nil, remark: String? = nil) async throws {
_ = try await client.send(
APIRequest(
method: .post,
path: "/api/yf-handset-app/photog/album/folder-edit",
body: AlbumFolderEditRequest(folderId: folderId, coverFileId: coverFileId, name: name, remark: remark)
)
) as EmptyPayload
}
///
func deleteAlbumFiles(folderId: Int, idList: [Int]) async throws {
_ = try await client.send(
APIRequest(
method: .post,
path: "/api/yf-handset-app/photog/album/file-delete",
body: AlbumFileDeleteRequest(idList: idList, folderId: folderId)
)
) as EmptyPayload
}
/// OSS
func albumFileUploadURL(scenicId: Int, fileURL: String, folderId: Int) async throws {
_ = try await client.send(
APIRequest(
method: .post,
path: "/api/yf-handset-app/photog/album/file-upload-url",
queryItems: [
URLQueryItem(name: "scenic_id", value: "\(scenicId)"),
URLQueryItem(name: "file_url", value: fileURL),
URLQueryItem(name: "folder_id", value: "\(folderId)")
]
)
) as EmptyPayload
}
}