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:
parent
f90f90ee41
commit
e80f8af79b
@ -39,15 +39,13 @@ struct CreateLibraryPage: View {
|
|||||||
|
|
||||||
struct LibraryDetailPage: View {
|
struct LibraryDetailPage: View {
|
||||||
let knowledgeBaseId: String
|
let knowledgeBaseId: String
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
@StateObject private var viewModel = LibraryDetailViewModel()
|
@StateObject private var viewModel = LibraryDetailViewModel()
|
||||||
|
@State private var showDeleteConfirm = false
|
||||||
|
@State private var isDeleting = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack { Color.zxBg0.ignoresSafeArea(); VStack(spacing: 0) {
|
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) {
|
ScrollView { VStack(spacing: 12) {
|
||||||
if viewModel.isLoading && viewModel.items.isEmpty {
|
if viewModel.isLoading && viewModel.items.isEmpty {
|
||||||
VStack(spacing: 12) { ZXLoadingView(size: 36, lineWidth: 3); Text("加载中…").font(.system(size: 13)).foregroundColor(Color.zxF04) }
|
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) }
|
}.padding(.horizontal, 20).padding(.bottom, 80) }
|
||||||
.scrollIndicators(.hidden)
|
.scrollIndicators(.hidden)
|
||||||
.zxPullToRefresh { await viewModel.refresh(knowledgeBaseId: knowledgeBaseId) } }
|
.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
|
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()) }
|
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()) }
|
||||||
|
|||||||
@ -129,6 +129,15 @@ class LibraryDetailViewModel: ObservableObject {
|
|||||||
} catch {}
|
} 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? {
|
func addItem(knowledgeBaseId: String, title: String, content: String?) async -> KnowledgeItem? {
|
||||||
do {
|
do {
|
||||||
let item = try await KnowledgeItemService.shared.create(
|
let item = try await KnowledgeItemService.shared.create(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user