wangdl 695518b276 fix: #16 sortOption 接入后端排序 API
- KnowledgeItemService.list 加 sortBy/order 参数
- loadItems/refresh/loadMore 加 sortBy/order 参数
- sortOption onChange 触发重新加载
- sortParams 映射函数: 0→默认, 1→fileSize, 2→createdAt, 3→updatedAt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:07:33 +08:00

185 lines
6.6 KiB
Swift

import Combine
import Foundation
@MainActor
class LibraryViewModel: ObservableObject {
@Published var knowledgeBases: [KnowledgeBase] = []
@Published var isLoading = false
@Published var isRefreshing = false
@Published var isLoadingMore = false
@Published var errorMessage: String?
@Published var hasMore = true
private var currentPage = 1
private let pageSize = 20
var currentFilter: LibraryFilter = .all
enum LibraryFilter: String, CaseIterable { case all = "全部", mine = "我的", subscribed = "已订阅", official = "官方" }
func loadKnowledgeBases() async {
isLoading = true; errorMessage = nil; currentPage = 1
do {
knowledgeBases = try await fetchKBs(page: 1)
hasMore = knowledgeBases.count >= pageSize
} catch { if knowledgeBases.isEmpty { errorMessage = "加载知识库失败" } }
isLoading = false
}
func refresh() async {
isRefreshing = true; currentPage = 1
do { knowledgeBases = try await fetchKBs(page: 1); hasMore = knowledgeBases.count >= pageSize } catch {}
isRefreshing = false
}
func loadMore() async {
guard !isLoadingMore, hasMore else { return }
isLoadingMore = true; currentPage += 1
do {
let more = try await fetchKBs(page: currentPage)
knowledgeBases.append(contentsOf: more); hasMore = more.count >= pageSize
} catch { currentPage -= 1 }
isLoadingMore = false
}
func createKnowledgeBase(title: String, description: String?) async -> KnowledgeBase? {
do {
let kb = try await KnowledgeBaseService.shared.create(title: title, description: description)
knowledgeBases.insert(kb, at: 0)
ZXToastManager.shared.success("知识库已创建")
return kb
} catch {
ZXToastManager.shared.error("创建失败")
return nil
}
}
func deleteKnowledgeBase(id: String) async {
do {
_ = try await KnowledgeBaseService.shared.delete(id: id)
knowledgeBases.removeAll { $0.id == id }
ZXToastManager.shared.success("已删除")
} catch { ZXToastManager.shared.error("删除失败") }
}
func togglePin(id: String) async {
do {
let _: GenericSuccessResponse? = try? await APIClient.shared.request("/knowledge-bases/\(id)/pin", method: "POST")
await loadKnowledgeBases()
} catch {}
}
private func fetchKBs(page: Int) async throws -> [KnowledgeBase] {
switch currentFilter {
case .all: return try await KnowledgeBaseService.shared.list(page: page, limit: pageSize)
case .mine: return try await KnowledgeBaseService.shared.list(page: page, limit: pageSize) // default is user's own
case .subscribed: return try await KnowledgeBaseService.shared.listSubscribed(page: page, limit: pageSize)
case .official: return [] // TODO: when backend supports ownerType=official
}
}
}
@MainActor
class LibraryDetailViewModel: ObservableObject {
@Published var items: [KnowledgeItem] = []
@Published var knowledgeBase: KnowledgeBase?
@Published var isLoading = false
@Published var isRefreshing = false
@Published var isLoadingMore = false
@Published var errorMessage: String?
@Published var hasMore = true
private var currentPage = 1
private let pageSize = 20
func loadItems(knowledgeBaseId: String, sortBy: String? = nil, order: String? = nil) async {
isLoading = true
errorMessage = nil
currentPage = 1
do {
async let kb = try? KnowledgeBaseService.shared.detail(id: knowledgeBaseId)
async let list = try? KnowledgeItemService.shared.list(knowledgeBaseId: knowledgeBaseId, sortBy: sortBy, order: order)
let (kbResult, listResult) = await (kb, list)
knowledgeBase = kbResult
items = listResult ?? []
hasMore = items.count >= pageSize
} catch {
if items.isEmpty { errorMessage = "加载知识点失败" }
}
isLoading = false
}
func refresh(knowledgeBaseId: String, sortBy: String? = nil, order: String? = nil) async {
isRefreshing = true
currentPage = 1
do {
items = try await KnowledgeItemService.shared.list(knowledgeBaseId: knowledgeBaseId, sortBy: sortBy, order: order)
hasMore = items.count >= pageSize
} catch {}
isRefreshing = false
}
func loadMore(knowledgeBaseId: String, sortBy: String? = nil, order: String? = nil) async {
guard !isLoadingMore, hasMore else { return }
isLoadingMore = true
currentPage += 1
do {
let more = try await KnowledgeItemService.shared.list(knowledgeBaseId: knowledgeBaseId, sortBy: sortBy, order: order)
items.append(contentsOf: more)
hasMore = more.count >= pageSize
} catch {
currentPage -= 1
}
isLoadingMore = false
}
func loadKnowledgeBase(id: String) async {
do {
knowledgeBase = try await KnowledgeBaseService.shared.detail(id: id)
} catch {}
}
func deleteKnowledgeBase(id: String) async {
do {
_ = try await KnowledgeBaseService.shared.delete(id: id)
ZXToastManager.shared.success("知识库已删除")
} catch {
ZXToastManager.shared.error("删除失败")
}
}
func addItem(knowledgeBaseId: String, title: String, content: String?) async -> KnowledgeItem? {
do {
let item = try await KnowledgeItemService.shared.create(
knowledgeBaseId: knowledgeBaseId, title: title, content: content
)
items.append(item)
ZXToastManager.shared.success("知识点已添加")
return item
} catch {
ZXToastManager.shared.error("添加失败")
return nil
}
}
func deleteItem(id: String) async {
do {
try await KnowledgeItemService.shared.delete(id: id)
items.removeAll { $0.id == id }
ZXToastManager.shared.success("知识点已删除")
} catch {
ZXToastManager.shared.error("删除失败")
}
}
func batchDeleteItems(ids: [String]) async {
do {
let resp = try await KnowledgeItemService.shared.batchDelete(ids: ids)
items.removeAll { ids.contains($0.id) }
ZXToastManager.shared.success(resp.message ?? "已删除")
} catch {
ZXToastManager.shared.error("批量删除失败")
}
}
}