diff --git a/AIStudyApp/AIStudyApp/Features/AI/AIChatPage.swift b/AIStudyApp/AIStudyApp/Features/AI/AIChatPage.swift index 3748843..ce78956 100644 --- a/AIStudyApp/AIStudyApp/Features/AI/AIChatPage.swift +++ b/AIStudyApp/AIStudyApp/Features/AI/AIChatPage.swift @@ -77,6 +77,34 @@ struct AIChatPage: View { } } } + .sheet(isPresented: $showSessions) { + VStack(spacing: 0) { + RoundedRectangle(cornerRadius: 3).fill(Color.zxF03).frame(width: 36, height: 5).padding(.top, 12).padding(.bottom, 16) + Text("对话列表").font(.system(size: 16, weight: .semibold)).foregroundColor(Color.zxF0).padding(.bottom, 16) + if sessions.isEmpty { + Text("暂无历史对话").font(.system(size: 14)).foregroundColor(Color.zxF04).padding(.top, 40) + } else { + ScrollView { + VStack(spacing: 0) { + ForEach(sessions) { s in + Button { + showSessions = false + Task { await vm.loadSession(s.id) } + } label: { + HStack { + Text(s.title ?? "对话").font(.system(size: 14)).foregroundColor(Color.zxF0) + Spacer() + Text(s.updatedAt?.prefix(10).description ?? "").font(.system(size: 11)).foregroundColor(Color.zxF04) + }.padding(.horizontal, 20).padding(.vertical, 14) + }.foregroundColor(.primary) + } + } + } + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity).background(Color.zxBg0) + .presentationDetents([.medium, .large]) + } .task { await vm.load() } } diff --git a/AIStudyApp/AIStudyApp/Features/AI/AIChatViewModel.swift b/AIStudyApp/AIStudyApp/Features/AI/AIChatViewModel.swift index b8f2b9f..38f06fb 100644 --- a/AIStudyApp/AIStudyApp/Features/AI/AIChatViewModel.swift +++ b/AIStudyApp/AIStudyApp/Features/AI/AIChatViewModel.swift @@ -85,7 +85,17 @@ final class AIChatViewModel: ObservableObject { } } - func setKnowledgeBase(_ id: String) { - knowledgeBaseId = id + func setKnowledgeBase(_ id: String) { knowledgeBaseId = id } + + func loadSession(_ id: String) async { + sessionId = id + isCreatingSession = true + do { + let msgs: [ChatMessage] = try await RagChatService.shared.getMessages(sessionId: id) + messages = msgs.map { m in + AIMessage(role: m.role == "user" ? .user : .ai, content: m.content, citations: m.citations) + } + } catch { sessionError = "加载对话失败" } + isCreatingSession = false } } diff --git a/AIStudyApp/AIStudyApp/Features/Profile/NotificationListView.swift b/AIStudyApp/AIStudyApp/Features/Profile/NotificationListView.swift index 06d47a1..b3faa67 100644 --- a/AIStudyApp/AIStudyApp/Features/Profile/NotificationListView.swift +++ b/AIStudyApp/AIStudyApp/Features/Profile/NotificationListView.swift @@ -83,12 +83,17 @@ struct NotificationListView: View { private func isToday(_ dateStr: String?) -> Bool { guard let d = dateStr else { return false } - let today = ISO8601DateFormatter().string(from: Date()) - return d.prefix(10) == today.prefix(10) + let f = DateFormatter(); f.dateFormat = "yyyy-MM-dd" + let today = f.string(from: Date()) + return d.prefix(10) == today } private func isThisWeek(_ dateStr: String?) -> Bool { - guard let d = dateStr, let date = ISO8601DateFormatter().date(from: String(d.prefix(19)) + "Z") else { return false } + guard let d = dateStr else { return false } + // Backend returns ISO 8601 or MySQL datetime + let clean = d.prefix(19).replacingOccurrences(of: "T", with: " ") + let f = DateFormatter(); f.dateFormat = "yyyy-MM-dd HH:mm:ss" + guard let date = f.date(from: String(clean)) else { return false } return Date().timeIntervalSince(date) < 7 * 86400 } }