Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

session.service.ts 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import { Injectable, OnDestroy } from '@angular/core';
  2. import { HttpClient } from '@angular/common/http';
  3. import { BehaviorSubject, Observable, of, Subscription } from 'rxjs';
  4. import { map, tap } from 'rxjs/operators';
  5. import { Session, SessionCreateRequest, SessionCreateApiResponse, SessionListResponse } from '../models/session.model';
  6. import { AuthService } from './auth.service';
  7. import { EventService } from './event.service';
  8. import { SessionUpdatedEvent } from '../models/event.model';
  9. @Injectable({
  10. providedIn: 'root'
  11. })
  12. export class SessionService implements OnDestroy {
  13. private activeSession = new BehaviorSubject<Session | null>(null);
  14. activeSession$ = this.activeSession.asObservable();
  15. private sessions: Session[] = [];
  16. private sessionsSubject = new BehaviorSubject<Session[]>([]);
  17. sessions$ = this.sessionsSubject.asObservable();
  18. private eventSubscription: Subscription = new Subscription();
  19. constructor(
  20. private http: HttpClient,
  21. private authService: AuthService,
  22. private eventService: EventService
  23. ) {
  24. this.setupEventSubscriptions();
  25. }
  26. // 获取会话列表(需要认证)
  27. getSessions(): Observable<Session[]> {
  28. // 检查用户是否已认证
  29. if (!this.authService.isAuthenticated()) {
  30. console.warn('用户未认证,无法获取会话列表,返回空数组');
  31. return of([]);
  32. }
  33. return this.http.get<SessionListResponse>('/api/session/list').pipe(
  34. map(response => {
  35. if (response.success && response.data) {
  36. this.sessions = response.data;
  37. this.sessionsSubject.next(this.sessions);
  38. return response.data;
  39. } else {
  40. throw new Error(response.message || '获取会话列表失败');
  41. }
  42. }),
  43. tap(sessions => {
  44. // 如果没有活动会话,设置第一个为活动会话
  45. if (sessions.length > 0 && !this.activeSession.value) {
  46. this.setActiveSession(sessions[0]);
  47. }
  48. })
  49. );
  50. }
  51. // 创建新会话
  52. createSession(title: string): Observable<Session> {
  53. // 检查用户是否已认证
  54. if (!this.authService.isAuthenticated()) {
  55. console.error('用户未认证,无法创建会话');
  56. throw new Error('用户未认证,请先登录');
  57. }
  58. const request: SessionCreateRequest = { title };
  59. return this.http.post<SessionCreateApiResponse>('/api/session/create', request).pipe(
  60. map(response => {
  61. console.log('🔍 [SessionService] 创建会话响应:', response);
  62. if (response.success && response.data) {
  63. const sessionData = response.data;
  64. const newSession: Session = {
  65. id: sessionData.id,
  66. title: sessionData.title,
  67. port: sessionData.port,
  68. baseURL: sessionData.baseURL
  69. };
  70. this.sessions.unshift(newSession);
  71. this.sessionsSubject.next([...this.sessions]);
  72. this.setActiveSession(newSession);
  73. return newSession;
  74. } else {
  75. throw new Error(response.message || '创建会话失败');
  76. }
  77. })
  78. );
  79. }
  80. // 设置活动会话
  81. setActiveSession(session: Session | null) {
  82. this.activeSession.next(session);
  83. }
  84. // 获取当前活动会话
  85. getActiveSession(): Session | null {
  86. return this.activeSession.value;
  87. }
  88. // 根据ID获取会话
  89. getSessionById(id: string): Session | undefined {
  90. return this.sessions.find(session => session.id === id);
  91. }
  92. // 加载会话列表(公共方法,供组件调用)
  93. loadSessions(): void {
  94. if (!this.authService.isAuthenticated()) {
  95. console.warn('用户未认证,跳过会话列表加载');
  96. this.sessionsSubject.next([]);
  97. return;
  98. }
  99. this.getSessions().subscribe({
  100. error: (error) => {
  101. console.error('加载会话列表失败:', error);
  102. // 如果API不可用,使用空列表
  103. this.sessionsSubject.next([]);
  104. }
  105. });
  106. }
  107. // 删除会话(如果后端支持)
  108. deleteSession(sessionId: string): Observable<boolean> {
  109. // 注意:后端可能没有删除API,这里只是示例
  110. return of(true).pipe(
  111. tap(() => {
  112. this.sessions = this.sessions.filter(s => s.id !== sessionId);
  113. this.sessionsSubject.next([...this.sessions]);
  114. // 如果删除的是活动会话,清空活动会话
  115. if (this.activeSession.value?.id === sessionId) {
  116. this.setActiveSession(null);
  117. }
  118. })
  119. );
  120. }
  121. // 设置事件订阅
  122. private setupEventSubscriptions() {
  123. // 订阅会话更新事件
  124. this.eventSubscription.add(
  125. this.eventService.sessionUpdated$.subscribe(event => {
  126. this.handleSessionUpdated(event);
  127. })
  128. );
  129. }
  130. // 处理会话更新事件
  131. private handleSessionUpdated(event: SessionUpdatedEvent) {
  132. const sessionInfo = event.properties.info;
  133. console.log('SessionService: 处理会话更新事件', sessionInfo.id, sessionInfo.title);
  134. // 查找现有会话
  135. const existingSessionIndex = this.sessions.findIndex(s => s.id === sessionInfo.id);
  136. if (existingSessionIndex !== -1) {
  137. // 更新现有会话
  138. const updatedSession: Session = {
  139. ...this.sessions[existingSessionIndex],
  140. title: sessionInfo.title,
  141. // 保留其他字段如port、baseURL等
  142. };
  143. this.sessions[existingSessionIndex] = updatedSession;
  144. console.log('SessionService: 更新现有会话', updatedSession.title);
  145. } else {
  146. // 添加新会话到列表开头
  147. const newSession: Session = {
  148. id: sessionInfo.id,
  149. title: sessionInfo.title,
  150. // port和baseURL可能在后端创建会话时提供,这里使用默认值
  151. // 实际使用中,可以从事件或后续API调用中获取
  152. port: 8020, // 默认端口,可根据需要调整
  153. baseURL: `http://localhost:8020`, // 默认baseURL
  154. };
  155. this.sessions.unshift(newSession);
  156. console.log('SessionService: 添加新会话', newSession.title);
  157. }
  158. // 通知订阅者
  159. this.sessionsSubject.next([...this.sessions]);
  160. }
  161. ngOnDestroy() {
  162. this.eventSubscription.unsubscribe();
  163. }
  164. }