import SwiftUI import Foundation // 搜索历史记录管理器(保持不变) class SearchHistoryManager { static let shared = SearchHistoryManager() private let userDefaultsKey = "search_history" private let maxHistoryCount = 50 var history: [String] { UserDefaults.standard.array(forKey: userDefaultsKey) as? [String] ?? [] } func addHistory(_ query: String) { var newHistory = history if let index = newHistory.firstIndex(of: query) { newHistory.remove(at: index) } newHistory.insert(query, at: 0) if newHistory.count > maxHistoryCount { newHistory = Array(newHistory.prefix(maxHistoryCount)) } UserDefaults.standard.set(newHistory, forKey: userDefaultsKey) } func removeHistory(_ query: String) { var newHistory = history if let index = newHistory.firstIndex(of: query) { newHistory.remove(at: index) UserDefaults.standard.set(newHistory, forKey: userDefaultsKey) } } func clearAllHistory() { UserDefaults.standard.removeObject(forKey: userDefaultsKey) } } // 修改后的搜索视图(实现数字ID直接导航) struct SearchView: View { @State private var searchQuery: String = "" @State private var searchResults: [AlbumItem] = [] @State private var isSearching: Bool = false @State private var showAlert: Bool = false @State private var alertMessage: String = "" @State private var searchHistory: [String] = [] // 添加导航路径状态,用于编程式导航 @State private var navigationPath = NavigationPath() var body: some View { // 使用带路径的NavigationStack以支持编程式导航 NavigationStack(path: $navigationPath) { Form { Section(header: Text("Jetson Media")) { HStack { TextField("输入搜索内容或ID", text: $searchQuery) .textFieldStyle(RoundedBorderTextFieldStyle()) .onChange(of: searchQuery) { if $0.isEmpty { loadHistory() } } Button(action: performSearch) { if isSearching { ProgressView() } else { Image(systemName: "magnifyingglass") } } .disabled(searchQuery.isEmpty || isSearching) } } // 搜索历史区域(保持不变) if searchQuery.isEmpty && !searchHistory.isEmpty { Section(header: HStack { Text("搜索历史") Spacer() Button("清除全部") { SearchHistoryManager.shared.clearAllHistory() loadHistory() } .foregroundColor(.red) .font(.subheadline) }) { ForEach(searchHistory, id: \.self) { query in HStack { Text(query) .foregroundColor(.primary) .frame(maxWidth: .infinity, alignment: .leading) .onTapGesture { searchQuery = query performSearch() } Button(action: { SearchHistoryManager.shared.removeHistory(query) loadHistory() }) { Image(systemName: "xmark.circle.fill") .foregroundColor(.gray) } .buttonStyle(PlainButtonStyle()) } } } } // 搜索结果区域(保持不变) if !searchResults.isEmpty { Section(header: Text("搜索结果")) { ForEach(searchResults, id: \.album_id) { item in NavigationLink(destination: PhotoView(albumId: item.album_id)) { VStack(alignment: .leading) { Text(item.title) .font(.headline) Text("ID: \(item.album_id)") .font(.subheadline) .foregroundColor(.gray) } } } } } } .navigationTitle("搜索") .onAppear { loadHistory() } // 定义导航目的地 .navigationDestination(for: Int.self) { albumId in PhotoView(albumId: String(albumId)) } } .alert(isPresented: $showAlert) { Alert(title: Text("提示"), message: Text(alertMessage), dismissButton: .default(Text("确定"))) } } private func loadHistory() { searchHistory = SearchHistoryManager.shared.history } private func performSearch() { guard !searchQuery.isEmpty else { return } // 首先检查搜索内容是否为数字 if let albumId = Int(searchQuery) { // 如果是数字,直接导航到对应的ID页面 SearchHistoryManager.shared.addHistory(searchQuery) loadHistory() navigationPath.append(albumId) return } // 如果不是数字,执行正常搜索流程 SearchHistoryManager.shared.addHistory(searchQuery) loadHistory() isSearching = true searchResults = [] let encodedQuery = searchQuery.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? searchQuery let urlString = Config.shared.apiURL( path: "\(Config.Path.search)?search_query=\(encodedQuery)&page=1" ) guard let url = URL(string: urlString) else { showAlert(message: "无效的URL") isSearching = false return } let task = URLSession.shared.dataTask(with: url) { data, response, error in DispatchQueue.main.async { self.isSearching = false if let error = error { self.showAlert(message: "搜索失败: \(error.localizedDescription)") return } guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { self.showAlert(message: "服务器返回错误") return } guard let data = data else { self.showAlert(message: "没有接收到数据") return } do { let decoder = JSONDecoder() self.searchResults = try decoder.decode([AlbumItem].self, from: data) } catch { print("解码错误: \(error)") self.showAlert(message: "解析数据失败: \(error.localizedDescription)") } } } task.resume() } private func showAlert(message: String) { alertMessage = message showAlert = true } }