新增资产模块,包含云存储与媒体库流程

为云端与素材管理页面接入首页路由,将共享云存储模型迁入 Assets 模块,并补充 API/ViewModel 测试。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-23 16:10:20 +08:00
parent ffb16eca29
commit cac22fcc56
15 changed files with 3431 additions and 75 deletions

View File

@ -0,0 +1,212 @@
//
// AssetsAPI.swift
// suixinkan
//
// Created by Codex on 2026/6/23.
//
import Foundation
import Observation
/// 便 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) 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
}
/// API
@MainActor
@Observable
final class AssetsAPI: AssetsServing {
@ObservationIgnored 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) async throws -> MediaLibraryDetail {
try await client.send(
APIRequest(
method: .get,
path: "/api/app/media-album/detail",
queryItems: [URLQueryItem(name: "id", value: "\(id)")]
)
)
}
///
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
}
}