fix: make source items tappable in 资料来源 tab

Wraps each KnowledgeSource row in NavigationLink to MaterialDetailView.
Previously sources were display-only with no tap action.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wangdl 2026-06-18 21:27:10 +08:00
parent 1c0a625192
commit bb9c9afb4d

View File

@ -260,12 +260,20 @@ struct LibraryDetailPage: View {
Text("暂无资料来源").font(.system(size: 14)).foregroundColor(Color.zxF03).padding(.top, 40) Text("暂无资料来源").font(.system(size: 14)).foregroundColor(Color.zxF03).padding(.top, 40)
} else { } else {
ForEach(sources) { src in ForEach(sources) { src in
NavigationLink(value: Route.materialDetail(
knowledgeBaseId: knowledgeBaseId,
fileName: src.originalFilename ?? src.title ?? "未命名",
fileType: materialTypeFromMime(src.mimeType),
fileSize: 0,
filePath: "",
uploadDate: src.createdAt
)) {
HStack(spacing: 12) { HStack(spacing: 12) {
Image(systemName: src.type == "file" ? "doc" : "link") Image(systemName: src.type == "file" ? "doc" : "link")
.font(.system(size: 18)).foregroundColor(Color.zxPurple) .font(.system(size: 18)).foregroundColor(Color.zxPurple)
.frame(width: 36, height: 36) .frame(width: 36, height: 36)
VStack(alignment: .leading, spacing: 2) { VStack(alignment: .leading, spacing: 2) {
Text(src.title ?? src.originalFilename ?? "未命名") Text(src.originalFilename ?? src.title ?? "未命名")
.font(.system(size: 15, weight: .medium)).foregroundColor(Color.zxF0).lineLimit(1) .font(.system(size: 15, weight: .medium)).foregroundColor(Color.zxF0).lineLimit(1)
if let len = src.textLength, len > 0 { if let len = src.textLength, len > 0 {
Text("\(len)") Text("\(len)")
@ -296,6 +304,7 @@ struct LibraryDetailPage: View {
} }
} }
} }
}
.padding(.horizontal, 20).padding(.bottom, 80) .padding(.horizontal, 20).padding(.bottom, 80)
} }
.scrollIndicators(.hidden) .scrollIndicators(.hidden)
@ -1065,6 +1074,10 @@ struct KnowledgeDetailPage: View {
_vm = StateObject(wrappedValue: KnowledgeDetailViewModel(item: item)) _vm = StateObject(wrappedValue: KnowledgeDetailViewModel(item: item))
} }
@State private var navigateToReader = false
@State private var readerPath: String = ""
@State private var readerType: MaterialType = .text
var body: some View { var body: some View {
Group { Group {
switch vm.loadState { switch vm.loadState {
@ -1477,6 +1490,18 @@ struct EditKnowledgePage: View {
// MARK: - Helpers // MARK: - Helpers
private func materialTypeFromMime(_ mime: String?) -> MaterialType {
guard let m = mime?.lowercased() else { return .markdown }
if m.contains("pdf") { return .pdf }
if m.contains("epub") { return .epub }
if m.contains("word") || m.contains("docx") || m.contains("doc") { return .word }
if m.contains("excel") || m.contains("xlsx") { return .excel }
if m.contains("powerpoint") || m.contains("pptx") { return .powerPoint }
if m.contains("image") { return .image }
if m.contains("text/plain") { return .text }
return .markdown
}
private func writeTempFile(content: String, itemId: String) throws -> String { private func writeTempFile(content: String, itemId: String) throws -> String {
let dir = FileManager.default.temporaryDirectory let dir = FileManager.default.temporaryDirectory
let url = dir.appendingPathComponent("kd_text_\(itemId).md") let url = dir.appendingPathComponent("kd_text_\(itemId).md")