wangdl 9aa9fd76c7 fix(ios): 知识库页面优化 - 去掉中间创建按钮,右上角+改为创建
- 移除列表中部的虚线"创建新知识库"按钮
- 右上角+按钮从 libraryImport 改为 libraryCreate
- 空状态提示更新

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 21:24:44 +08:00

87 lines
6.5 KiB
Swift

//
// LibraryHomeView.swift - Page 7
//
import SwiftUI
struct LibraryHomeView: View {
@StateObject private var viewModel = LibraryViewModel()
@State private var s = ""
var body: some View {
ZStack { ZXGradient.page.ignoresSafeArea()
VStack(spacing: 0) {
HStack { Text("知识库").font(.system(size: 22, weight: .heavy)).foregroundColor(Color.zxF0).tracking(-0.5); Spacer()
NavigationLink(value: Route.librarySearch) {
Image(systemName: "magnifyingglass").font(.system(size: 18)).foregroundColor(Color.zxF05)
.frame(width: 36, height: 36).background(Color(hex:"#FFFFFF",opacity:0.05))
.clipShape(RoundedRectangle(cornerRadius: 10))
.overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.zxBorder008, lineWidth: 1))
}
.accessibilityLabel("搜索知识库")
NavigationLink(value: Route.libraryCreate) {
Image(systemName: "plus").font(.system(size: 18)).foregroundColor(.white)
.frame(width: 36, height: 36).background(ZXGradient.brand)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
.accessibilityLabel("创建新知识库")
}
.padding(.horizontal, 20).padding(.top, 8).padding(.bottom, 12)
HStack(spacing: 8) { Image(systemName: "magnifyingglass").font(.system(size: 16)).foregroundColor(Color.zxF03); TextField("搜索知识库或知识点…", text: $s).font(.system(size: 14)).tint(Color.zxPurple).accessibilityLabel("搜索知识库") }
.padding(.horizontal, 14).frame(height: 44).background(Color.zxFill004).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)).clipShape(RoundedRectangle(cornerRadius: 14)).padding(.horizontal, 20).padding(.bottom, 16)
.accessibilityHint("输入关键词搜索知识库或知识点")
ScrollView { VStack(spacing: 12) {
if viewModel.isLoading && viewModel.knowledgeBases.isEmpty {
VStack(spacing: 12) { ZXLoadingView(size: 36, lineWidth: 3); Text("加载中…").font(.system(size: 13)).foregroundColor(Color.zxF04) }
.frame(maxWidth: .infinity).padding(.top, 80)
}
ForEach(viewModel.knowledgeBases) { kb in
NavigationLink(value: Route.libraryDetail(knowledgeBaseId: kb.id)) {
ZLibraryCard(icon: "books.vertical.fill", name: kb.title, desc: kb.description ?? "", color: Color.zxPurple, items: kb.itemCount ?? 0, mastery: 50, tags: [], last: lastStudiedText(kb.lastStudiedAt))
}
}
if viewModel.knowledgeBases.isEmpty && !viewModel.isLoading {
Text("还没有知识库,点击右上角 + 创建").font(.system(size: 14)).foregroundColor(Color.zxF04).padding(.top, 60)
}
if viewModel.hasMore {
ZXLoadMoreFooter { await viewModel.loadMore() }
}
}.padding(.horizontal, 20).padding(.bottom, 120) }
.scrollIndicators(.hidden)
.zxPullToRefresh { await viewModel.refresh() }
}
}
.task { await viewModel.loadKnowledgeBases() }
.navigationDestination(for: Route.self) { $0.destination }
}
private func lastStudiedText(_ iso: String?) -> String {
guard let iso else { return "未学习" }
return iso.prefix(10).description
}
}
struct ZLibraryCard: View { let icon: String; let name: String; let desc: String; let color: Color; let items: Int; let mastery: Int; let tags: [String]; let last: String
var body: some View { VStack(spacing: 0) { Rectangle().fill(ZXGradient.progressBar).frame(height: 3); HStack(spacing: 12) { Image(systemName: icon).font(.system(size: 20)).foregroundColor(color).frame(width: 44, height: 44).background(color.opacity(0.12)).clipShape(RoundedRectangle(cornerRadius: 13)).overlay(RoundedRectangle(cornerRadius: 13).stroke(color.opacity(0.3), lineWidth: 1)); VStack(alignment: .leading, spacing: 2) { Text(name).font(.system(size: 16, weight: .bold)).foregroundColor(Color.zxF0); Text(desc).font(.system(size: 12)).foregroundColor(Color.zxF04); Text("掌握 \(mastery)%").font(.system(size: 11)).foregroundColor(Color.zxF04) }; Spacer() }.padding(16); HStack { HStack(spacing: 4) { Image(systemName: "clock").font(.system(size: 10)); Text("\(items) 项 · \(last)").font(.system(size: 11)) }.foregroundColor(Color.zxF03); Spacer(); ForEach(tags.prefix(2), id: \.self) { t in Text(t).font(.system(size: 10, weight: .medium)).foregroundColor(Color.zxPurple).padding(.horizontal, 7).padding(.vertical, 2).background(Color(hex: "#7C6EFA", opacity: 0.08)).clipShape(Capsule()) } }.padding(.horizontal, 16).padding(.bottom, 12) }
.background(Color.zxFill003).clipShape(RoundedRectangle(cornerRadius: 20)).overlay(RoundedRectangle(cornerRadius: 20).stroke(Color.zxBorder006, lineWidth: 1)) }
}
struct LibrarySearchView: View {
@State private var query = ""
var body: some View {
ZStack { Color.zxBg0.ignoresSafeArea()
VStack(spacing: 0) {
HStack(spacing: 8) { Image(systemName: "magnifyingglass").font(.system(size: 16)).foregroundColor(Color.zxF03); TextField("搜索知识库或知识点…", text: $query).font(.system(size: 14)).tint(Color.zxPurple) }
.padding(.horizontal, 14).frame(height: 44).background(Color.zxFill004).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)).clipShape(RoundedRectangle(cornerRadius: 14))
.padding(.horizontal, 20).padding(.top, 8).padding(.bottom, 16)
ScrollView { VStack(spacing: 12) {
if query.isEmpty {
VStack(spacing: 12) {
Image(systemName: "magnifyingglass").font(.system(size: 36)).foregroundColor(Color.zxF03)
Text("搜索知识点、知识库或标签").font(.system(size: 13)).foregroundColor(Color.zxF03)
}.padding(.top, 80)
}
}.padding(.horizontal, 20) }.scrollIndicators(.hidden)
}
}.navigationBarTitleDisplayMode(.inline).toolbarBackground(.hidden, for: .navigationBar)
}
}