import { Injectable, OnDestroy, Injector } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { BehaviorSubject, Observable, of, Subscription } from 'rxjs'; import { map, tap } from 'rxjs/operators'; import { Session, SessionCreateRequest, SessionCreateApiResponse, SessionListResponse, ProjectCreateRequest, ProjectCreateApiResponse } from '../models/session.model'; import { AuthService } from './auth.service'; import { EventService } from './event.service'; import { SessionUpdatedEvent } from '../models/event.model'; @Injectable({ providedIn: 'root' }) export class SessionService implements OnDestroy { private activeSession = new BehaviorSubject(null); activeSession$ = this.activeSession.asObservable(); private sessions: Session[] = []; private sessionsSubject = new BehaviorSubject([]); sessions$ = this.sessionsSubject.asObservable(); private eventSubscription: Subscription = new Subscription(); private injector: Injector; private _eventService: EventService | null = null; constructor( private http: HttpClient, private authService: AuthService, injector: Injector ) { this.injector = injector; // 延迟设置事件订阅,在EventService可用时进行 setTimeout(() => this.setupEventSubscriptions(), 0); } private get eventService(): EventService | null { if (!this._eventService) { try { this._eventService = this.injector.get(EventService, null); } catch (error) { console.warn('无法获取EventService:', error); return null; } } return this._eventService; } // 获取会话列表(需要认证)- 使用新API端点 getSessions(): Observable { // 检查用户是否已认证 if (!this.authService.isAuthenticated()) { console.warn('用户未认证,无法获取会话列表,返回空数组'); return of([]); } return this.http.get('/api/sessions').pipe( map(response => { console.log('🔍 [SessionService] 获取会话列表响应:', response); if (response.success && response.data) { // 处理嵌套的 sessions 字段(后端返回 { data: { sessions: [], ...pagination } }) let sessionsArray: any[] = []; if (response.data.sessions && Array.isArray(response.data.sessions)) { // 新格式:response.data.sessions 是数组 sessionsArray = response.data.sessions; console.log('🔍 [SessionService] 从嵌套 sessions 字段获取数据,数量:', sessionsArray.length); } else if (Array.isArray(response.data)) { // 兼容旧格式:response.data 直接是数组 sessionsArray = response.data; console.log('🔍 [SessionService] 从 data 字段直接获取数组,数量:', sessionsArray.length); } else { console.warn('🔍 [SessionService] 无法识别响应数据格式,使用空数组'); sessionsArray = []; } // 确保每个会话都有 project_id 字段(向后兼容) const sessions = sessionsArray.map(session => ({ ...session, project_id: session.project_id || session.id // 如果没有 project_id,使用 id 作为默认 })); this.sessions = sessions; this.sessionsSubject.next(this.sessions); console.log('🔍 [SessionService] 会话列表处理完成,数量:', sessions.length); return sessions; } else { console.error('🔍 [SessionService] 获取会话列表失败:', response.message); throw new Error(response.message || '获取会话列表失败'); } }), tap(sessions => { // 如果没有活动会话,设置第一个为活动会话 if (sessions.length > 0 && !this.activeSession.value) { this.setActiveSession(sessions[0]); } }) ); } // 创建新会话(向后兼容,建议使用createProject) createSession(title: string, menuItemId: string): Observable { console.warn('createSession已过时,请使用createProject方法'); // 尝试使用默认智能体创建项目 const defaultAgent = 'report'; // 默认智能体 return this.createProject({ title, agent_name: defaultAgent, description: `由旧会话创建,菜单项: ${menuItemId}` }); } // 创建新项目 createProject(request: ProjectCreateRequest): Observable { // 检查用户是否已认证 if (!this.authService.isAuthenticated()) { console.error('用户未认证,无法创建项目'); throw new Error('用户未认证,请先登录'); } // 生成项目ID(如果未提供) const projectRequest = { ...request, project_id: request.project_id || `proj_${crypto.randomUUID()}` }; return this.http.post('/api/session/create', projectRequest).pipe( map(response => { console.log('🔍 [SessionService] 创建项目响应:', response); if (response.success && response.data) { const sessionData = response.data; // 确保有project_id字段 const newSession: Session = { ...sessionData, project_id: sessionData.project_id || projectRequest.project_id }; this.sessions.unshift(newSession); this.sessionsSubject.next([...this.sessions]); this.setActiveSession(newSession); return newSession; } else { throw new Error(response.message || '创建项目失败'); } }) ); } // 设置活动会话 setActiveSession(session: Session | null) { this.activeSession.next(session); } // 获取当前活动会话 getActiveSession(): Session | null { return this.activeSession.value; } // 根据ID获取会话 getSessionById(id: string): Session | undefined { return this.sessions.find(session => session.id === id); } // 加载会话列表(公共方法,供组件调用) loadSessions(): void { if (!this.authService.isAuthenticated()) { console.warn('用户未认证,跳过会话列表加载'); this.sessionsSubject.next([]); return; } console.log('🔍 [SessionService] 开始加载会话列表...'); this.getSessions().subscribe({ next: (sessions) => { console.log('🔍 [SessionService] 会话列表加载成功,数量:', sessions.length); }, error: (error) => { console.error('🔍 [SessionService] 加载会话列表失败:', error); // 如果API不可用,使用空列表 this.sessionsSubject.next([]); } }); } // 删除会话(如果后端支持) deleteSession(sessionId: string): Observable { // 注意:后端可能没有删除API,这里只是示例 return of(true).pipe( tap(() => { this.sessions = this.sessions.filter(s => s.id !== sessionId); this.sessionsSubject.next([...this.sessions]); // 如果删除的是活动会话,清空活动会话 if (this.activeSession.value?.id === sessionId) { this.setActiveSession(null); } }) ); } // 设置事件订阅 private setupEventSubscriptions() { const eventService = this.eventService; if (!eventService) { console.warn('EventService不可用,跳过事件订阅设置'); return; } // 订阅会话更新事件 this.eventSubscription.add( eventService.sessionUpdated$.subscribe(event => { this.handleSessionUpdated(event); }) ); } // 处理会话更新事件 private handleSessionUpdated(event: SessionUpdatedEvent) { const sessionInfo = event.properties.info; console.log('SessionService: 处理会话更新事件', sessionInfo.id, sessionInfo.title); // 查找现有会话 const existingSessionIndex = this.sessions.findIndex(s => s.id === sessionInfo.id); if (existingSessionIndex !== -1) { // 更新现有会话 const updatedSession: Session = { ...this.sessions[existingSessionIndex], title: sessionInfo.title, agent_name: sessionInfo.agent_name || this.sessions[existingSessionIndex].agent_name, description: sessionInfo.description || this.sessions[existingSessionIndex].description, status: sessionInfo.status || this.sessions[existingSessionIndex].status, // 保留其他字段 }; this.sessions[existingSessionIndex] = updatedSession; console.log('SessionService: 更新现有会话', updatedSession.title); } else { // 添加新会话到列表开头 const newSession: Session = { id: sessionInfo.id, project_id: sessionInfo.project_id || sessionInfo.projectID || sessionInfo.id, title: sessionInfo.title, agent_name: sessionInfo.agent_name || 'report', description: sessionInfo.description || '', status: sessionInfo.status || 'requirement_document', // port和baseURL可能在后端创建会话时提供,这里使用默认值 // 实际使用中,可以从事件或后续API调用中获取 port: 8020, // 默认端口,可根据需要调整 baseURL: `http://localhost:8020`, // 默认baseURL }; this.sessions.unshift(newSession); console.log('SessionService: 添加新会话', newSession.title); } // 通知订阅者 this.sessionsSubject.next([...this.sessions]); } ngOnDestroy() { this.eventSubscription.unsubscribe(); } }