feat(ios): 知识库详情页 - toolbar 按钮 + 删除功能

- + 和删除按钮移入导航栏 toolbar,与系统返回按钮同行
- 新增删除确认弹窗(alert with destructive action)
- LibraryDetailViewModel 新增 deleteKnowledgeBase 方法
- 删除成功后 toast + 自动返回列表

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wangdl 2026-05-27 21:33:36 +08:00
parent f90f90ee41
commit e80f8af79b
2 changed files with 47 additions and 8 deletions

View File

@ -39,15 +39,13 @@ struct CreateLibraryPage: View {
struct LibraryDetailPage: View {
let knowledgeBaseId: String
@Environment(\.dismiss) private var dismiss
@StateObject private var viewModel = LibraryDetailViewModel()
@State private var showDeleteConfirm = false
@State private var isDeleting = false
var body: some View {
ZStack { Color.zxBg0.ignoresSafeArea(); VStack(spacing: 0) {
HStack { Spacer()
NavigationLink(value: Route.addKnowledge(knowledgeBaseId: knowledgeBaseId)) {
Image(systemName: "plus").font(.system(size: 18)).foregroundColor(.white)
.frame(width: 36, height: 36).background(ZXGradient.brand).clipShape(RoundedRectangle(cornerRadius: 10))
}
}.padding(.horizontal, 20).padding(.top, 8).padding(.bottom, 8)
ScrollView { VStack(spacing: 12) {
if viewModel.isLoading && viewModel.items.isEmpty {
VStack(spacing: 12) { ZXLoadingView(size: 36, lineWidth: 3); Text("加载中…").font(.system(size: 13)).foregroundColor(Color.zxF04) }
@ -67,9 +65,41 @@ struct LibraryDetailPage: View {
}.padding(.horizontal, 20).padding(.bottom, 80) }
.scrollIndicators(.hidden)
.zxPullToRefresh { await viewModel.refresh(knowledgeBaseId: knowledgeBaseId) } }
}.navigationBarTitleDisplayMode(.inline).toolbarBackground(.hidden, for: .navigationBar)
.task { await viewModel.loadItems(knowledgeBaseId: knowledgeBaseId) }
}
.navigationBarTitleDisplayMode(.inline).toolbarBackground(.hidden, for: .navigationBar)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
NavigationLink(value: Route.addKnowledge(knowledgeBaseId: knowledgeBaseId)) {
Image(systemName: "plus").font(.system(size: 16, weight: .semibold))
.foregroundColor(Color.zxPrimary)
}
}
ToolbarItem(placement: .topBarTrailing) {
Button {
showDeleteConfirm = true
} label: {
Image(systemName: "trash").font(.system(size: 16))
.foregroundColor(Color.zxCoral)
}
}
}
.alert("删除知识库", isPresented: $showDeleteConfirm) {
Button("取消", role: .cancel) {}
Button("删除", role: .destructive) {
isDeleting = true
Task {
await viewModel.deleteKnowledgeBase(id: knowledgeBaseId)
await MainActor.run {
isDeleting = false
dismiss()
}
}
}
} message: {
Text("删除后将无法恢复,包括其中的所有知识点。确定要删除吗?")
}
.task { await viewModel.loadItems(knowledgeBaseId: knowledgeBaseId) }
}
}
struct ZXCardRow: View { let icon: String; let title: String; let desc: String; let status: String; let c: Color
var body: some View { HStack(spacing: 12) { Image(systemName: icon).font(.system(size: 18)).foregroundColor(c).frame(width: 40, height: 40).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 10)); VStack(alignment: .leading, spacing: 2) { Text(title).font(.system(size: 14, weight: .semibold)).foregroundColor(Color.zxF0); Text(desc).font(.system(size: 11)).foregroundColor(Color.zxF03) }; Spacer(); Text(status).font(.system(size: 10, weight: .semibold)).foregroundColor(c).padding(.horizontal, 8).padding(.vertical, 2).background(c.opacity(0.12)).clipShape(Capsule()) }

View File

@ -129,6 +129,15 @@ class LibraryDetailViewModel: ObservableObject {
} 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(