001project_wildgrowth/ios/WildGrowth/WildGrowth/NoteService.swift

211 lines
7.3 KiB
Swift
Raw 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.

import Foundation
class NoteService {
static let shared = NoteService()
private let apiClient = APIClient.shared
private init() {}
// MARK: -
func createNote(_ request: CreateNoteRequest) async throws -> Note {
// Codable
let encoder = JSONEncoder()
guard let jsonData = try? encoder.encode(request),
let bodyDict = try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any] else {
throw APIError.serverError("请求体编码失败")
}
let response: NoteResponse = try await apiClient.request(
endpoint: "/api/notes",
method: "POST",
body: bodyDict,
requiresAuth: true
)
guard response.success else {
throw APIError.serverError("创建笔记失败")
}
return response.data
}
// MARK: -
func getNotes(
courseId: String? = nil,
nodeId: String? = nil,
notebookId: String? = nil, // Phase 3:
type: NoteType? = nil,
page: Int = 1,
limit: Int = 20
) async throws -> (notes: [Note], total: Int) {
//
var queryComponents: [String] = []
if let courseId = courseId {
queryComponents.append("course_id=\(courseId.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? courseId)")
}
if let nodeId = nodeId {
queryComponents.append("node_id=\(nodeId.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? nodeId)")
}
// Phase 3:
if let notebookId = notebookId {
queryComponents.append("notebook_id=\(notebookId.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? notebookId)")
}
if let type = type {
queryComponents.append("type=\(type.rawValue)")
}
queryComponents.append("page=\(page)")
queryComponents.append("limit=\(limit)")
let queryString = queryComponents.isEmpty ? "" : "?\(queryComponents.joined(separator: "&"))"
let response: NoteListResponse = try await apiClient.request(
endpoint: "/api/notes\(queryString)",
method: "GET",
requiresAuth: true
)
guard response.success else {
throw APIError.serverError("获取笔记列表失败")
}
return (response.data.notes, response.data.total)
}
// MARK: - Phase 3:
func getNotesByNotebook(notebookId: String, page: Int = 1, limit: Int = 50) async throws -> (notes: [Note], total: Int) {
return try await getNotes(notebookId: notebookId, page: page, limit: limit)
}
// MARK: - Phase 3:
func updateNoteHierarchy(noteId: String, parentId: String?, order: Int?, level: Int?) async throws -> Note {
let request = UpdateNoteRequest(
parentId: parentId,
order: order,
level: level,
content: nil,
quotedText: nil,
startIndex: nil,
length: nil,
style: nil
)
return try await updateNote(noteId: noteId, request: request)
}
// MARK: - Phase 3:
enum MoveDirection {
case up //
case down //
case indent //
case outdent //
}
func moveNote(noteId: String, direction: MoveDirection) async throws -> Note {
//
let currentNote = try await getNote(noteId: noteId)
//
var newParentId: String? = currentNote.parentId
var newOrder: Int = currentNote.order
var newLevel: Int = currentNote.level
switch direction {
case .up:
// order - 1
newOrder = max(0, currentNote.order - 1)
case .down:
// order + 1
newOrder = currentNote.order + 1
case .indent:
//
//
//
if currentNote.level < 2 {
newLevel = currentNote.level + 1
// TODO:
}
case .outdent:
//
if let parentId = currentNote.parentId {
//
let parentNote = try await getNote(noteId: parentId)
newParentId = parentNote.parentId
newLevel = max(0, currentNote.level - 1)
// TODO: order
}
}
return try await updateNoteHierarchy(
noteId: noteId,
parentId: newParentId,
order: newOrder,
level: newLevel
)
}
// MARK: -
func getNote(noteId: String) async throws -> Note {
let response: NoteResponse = try await apiClient.request(
endpoint: "/api/notes/\(noteId)",
method: "GET",
requiresAuth: true
)
guard response.success else {
throw APIError.serverError("获取笔记失败")
}
return response.data
}
// MARK: -
func getNotesForNode(nodeId: String) async throws -> [Note] {
let response: NoteListResponse = try await apiClient.request(
endpoint: "/api/lessons/\(nodeId)/notes",
method: "GET",
requiresAuth: true
)
guard response.success else {
throw APIError.serverError("获取节点笔记失败")
}
return response.data.notes
}
// MARK: -
func updateNote(noteId: String, request: UpdateNoteRequest) async throws -> Note {
// Codable
let encoder = JSONEncoder()
guard let jsonData = try? encoder.encode(request),
let bodyDict = try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any] else {
throw APIError.serverError("请求体编码失败")
}
let response: NoteResponse = try await apiClient.request(
endpoint: "/api/notes/\(noteId)",
method: "PUT",
body: bodyDict,
requiresAuth: true
)
guard response.success else {
throw APIError.serverError("更新笔记失败")
}
return response.data
}
// MARK: -
func deleteNote(noteId: String) async throws {
let _: EmptyResponse = try await apiClient.request(
endpoint: "/api/notes/\(noteId)",
method: "DELETE",
requiresAuth: true
)
}
}