15270821319 6 months ago
parent
commit
d158ae1b8c

+ 87 - 2
AiStudy-app/src/app/services/database.service.ts

@@ -12,14 +12,25 @@ export interface CustomTeacher {
   updatedAt?: Date;
 }
 
+// 添加 ChatSession 相关接口
+export interface ChatSessionData {
+  objectId?: string;
+  userId: string;
+  title: string;
+  messages: any[];
+  teacher: any;
+  createdAt?: Date;
+  updatedAt?: Date;
+}
+
 @Injectable({
   providedIn: 'root'
 })
 export class DatabaseService {
   constructor() {
     // 初始化Parse
-    Parse.initialize('dev'); // 使用你的 appId
-    Parse.serverURL = 'http://113.44.218.121:1337/parse'; // 你的Parse服务器地址
+    Parse.initialize('dev'); // 使用的 appId
+    Parse.serverURL = 'https://dev.fmode.cn/parse'; // 使用HTTPS
   }
 
   // 创建数据
@@ -188,4 +199,78 @@ export class DatabaseService {
       throw error;
     }
   }
+
+  // 添加 ChatSession 相关方法
+  async createChatSession(sessionData: ChatSessionData) {
+    try {
+      const ChatSession = Parse.Object.extend('ChatSession');
+      const session = new ChatSession();
+      
+      // 使用类型断言确保字段名是字符串
+      const fields = ['userId', 'title', 'messages', 'teacher', 'createdAt', 'updatedAt'] as const;
+      fields.forEach(field => {
+        if (field in sessionData) {
+          session.set(field, sessionData[field as keyof ChatSessionData]);
+        }
+      });
+      
+      return await session.save();
+    } catch (error) {
+      console.error('Error creating chat session:', error);
+      throw error;
+    }
+  }
+
+  async getChatSessions(userId: string) {
+    try {
+      const query = new Parse.Query('ChatSession');
+      query.equalTo('userId', userId);
+      query.descending('updatedAt'); // 按更新时间降序排序
+      return await query.find();
+    } catch (error) {
+      console.error('Error getting chat sessions:', error);
+      throw error;
+    }
+  }
+
+  async getChatSession(sessionId: string) {
+    try {
+      const query = new Parse.Query('ChatSession');
+      return await query.get(sessionId);
+    } catch (error) {
+      console.error('Error getting chat session:', error);
+      throw error;
+    }
+  }
+
+  async updateChatSession(sessionId: string, updateData: Partial<ChatSessionData>) {
+    try {
+      const query = new Parse.Query('ChatSession');
+      const session = await query.get(sessionId);
+      
+      // 使用类型断言确保字段名是字符串
+      const updateableFields = ['title', 'messages', 'teacher', 'updatedAt'] as const;
+      updateableFields.forEach(field => {
+        if (field in updateData) {
+          session.set(field, updateData[field as keyof ChatSessionData]);
+        }
+      });
+      
+      return await session.save();
+    } catch (error) {
+      console.error('Error updating chat session:', error);
+      throw error;
+    }
+  }
+
+  async deleteChatSession(sessionId: string) {
+    try {
+      const query = new Parse.Query('ChatSession');
+      const session = await query.get(sessionId);
+      return await session.destroy();
+    } catch (error) {
+      console.error('Error deleting chat session:', error);
+      throw error;
+    }
+  }
 } 

+ 9 - 2
AiStudy-app/src/app/tab1/tab1.page.html

@@ -37,10 +37,17 @@
       对话
     </ion-title>
     <ion-buttons slot="end">
-      <ion-button (click)="saveCurrentSession()" [disabled]="messages.length === 0">
+      <ion-button 
+        (click)="saveCurrentSession()" 
+        [disabled]="messages.length === 0"
+        #saveButton
+      >
         <ion-icon slot="icon-only" name="save-outline"></ion-icon>
       </ion-button>
-      <ion-button (click)="viewChatHistory()">
+      <ion-button 
+        (click)="viewChatHistory()"
+        #historyButton
+      >
         <ion-icon slot="icon-only" name="time-outline"></ion-icon>
       </ion-button>
     </ion-buttons>

+ 125 - 62
AiStudy-app/src/app/tab1/tab1.page.ts

@@ -31,6 +31,16 @@ interface Teacher {
   objectId?: string;   // 添加数据库对象ID
 }
 
+// 定义会话数据接口
+interface ChatSessionData {
+  userId: string;
+  title: string;
+  messages: ChatMessage[];
+  teacher: Teacher;
+  createdAt: Date;
+  updatedAt: Date;
+}
+
 @Component({
   selector: 'app-tab1',
   templateUrl: 'tab1.page.html',
@@ -58,6 +68,8 @@ interface Teacher {
   ],
 })
 export class Tab1Page {
+  @ViewChild('saveButton') saveButton: any;
+  @ViewChild('historyButton') historyButton: any;
   @ViewChild(IonContent) content!: IonContent;
   
   messages: ChatMessage[] = [];
@@ -113,9 +125,9 @@ export class Tab1Page {
   constructor(
     private dbService: DatabaseService,
     private router: Router,
-    private chatSessionService: ChatSessionService,
     private alertController: AlertController
   ) {
+    console.log('Tab1Page 构造函数被调用'); // 添加日志
     addIcons({ 
       send, 
       personCircleOutline, 
@@ -124,9 +136,22 @@ export class Tab1Page {
       saveOutline,
       timeOutline
     });
+    
+    // 初始化必要的属性
+    this.messages = [];
+    this.userInput = '';
+    this.isLoading = false;
+    this.isComplete = false;
+    this.currentResponse = '';
+    
     this.loadTeachers();
   }
 
+  ngAfterViewInit() {
+    console.log('保存按钮元素:', this.saveButton);
+    console.log('历史按钮元素:', this.historyButton);
+  }
+
   // 添加加载教师方法
   async loadTeachers() {
     try {
@@ -389,74 +414,112 @@ ${this.selectedTeacher.description}
     this.router.navigate(['/chat-history']);
   }
 
-  // 修改 saveCurrentSession 方法,添加日志
+  // 修改保存会话方法
   async saveCurrentSession() {
-    console.log('Saving current session...'); // 添加日志
-    // 检查用户是否登录
-    const currentUser = new CloudUser();
-    if (!currentUser.id) {
-      await this.showAlert('提示', '请先登录后再保存会话');
-      return;
-    }
+    console.log('保存按钮被点击');
+    console.log('按钮状态:', {
+      disabled: this.messages.length === 0,
+      messagesLength: this.messages.length
+    });
+    
+    console.log('开始保存会话...'); // 添加日志
+    try {
+      // 检查用户是否登录
+      const currentUser = new CloudUser();
+      console.log('当前用户:', currentUser); // 添加日志
+      const userId = currentUser.id;
+      console.log('用户ID:', userId); // 添加日志
+      
+      if (!userId) {
+        console.log('用户未登录'); // 添加日志
+        await this.showAlert('提示', '请先登录后再保存会话');
+        return;
+      }
 
-    // 检查是否有可保存的消息
-    if (this.messages.length === 0) {
-      await this.showAlert('提示', '当前没有可保存的对话');
-      return;
-    }
+      // 检查是否有可保存的消息
+      console.log('消息数量:', this.messages.length); // 添加日志
+      if (this.messages.length === 0) {
+        console.log('没有消息可保存'); // 添加日志
+        await this.showAlert('提示', '当前没有可保存的对话');
+        return;
+      }
 
-    // 过滤掉隐藏的设置消息
-    const visibleMessages = this.messages.filter(msg => !msg.isHidden);
-    if (visibleMessages.length === 0) {
-      await this.showAlert('提示', '当前没有可保存的对话');
-      return;
-    }
+      // 过滤掉隐藏的设置消息
+      const visibleMessages = this.messages.filter(msg => !msg.isHidden);
+      console.log('可见消息数量:', visibleMessages.length); // 添加日志
+      
+      if (visibleMessages.length === 0) {
+        console.log('没有可见消息可保存'); // 添加日志
+        await this.showAlert('提示', '当前没有可保存的对话');
+        return;
+      }
 
-    const alert = await this.alertController.create({
-      header: '保存会话',
-      inputs: [
-        {
-          name: 'title',
-          type: 'text',
-          placeholder: '请输入会话标题(可选)'
-        }
-      ],
-      buttons: [
-        {
-          text: '取消',
-          role: 'cancel'
-        },
-        {
-          text: '保存',
-          handler: async (data) => {
-            try {
-              // 如果用户没有输入标题,使用默认标题
-              const title = data.title?.trim() || 
-                          `与${this.selectedTeacher.name}的对话 - ${new Date().toLocaleString()}`;
-              
-              // 保存会话
-              await this.chatSessionService.saveSession(
-                title,
-                visibleMessages, // 只保存可见消息
-                {
-                  id: this.selectedTeacher.id,
-                  name: this.selectedTeacher.name,
-                  description: this.selectedTeacher.description,
-                  systemPrompt: this.selectedTeacher.systemPrompt
-                }
-              );
-              
-              await this.showAlert('成功', '会话已保存');
-            } catch (error) {
-              console.error('保存会话失败:', error);
-              await this.showAlert('错误', '保存失败,请重试');
+      console.log('显示保存对话框'); // 添加日志
+      const alert = await this.alertController.create({
+        header: '保存会话',
+        inputs: [
+          {
+            name: 'title',
+            type: 'text',
+            placeholder: '请输入会话标题(可选)'
+          }
+        ],
+        buttons: [
+          {
+            text: '取消',
+            role: 'cancel',
+            handler: () => {
+              console.log('取消保存'); // 添加日志
+            }
+          },
+          {
+            text: '保存',
+            handler: async (data) => {
+              try {
+                console.log('开始保存过程, 输入数据:', data); // 添加日志
+                // 如果用户没有输入标题,使用默认标题
+                const title = data.title?.trim() || 
+                            `与${this.selectedTeacher.name}的对话 - ${new Date().toLocaleString()}`;
+                
+                console.log('使用标题:', title); // 添加日志
+                
+                // 准备会话数据
+                const sessionData: ChatSessionData = {
+                  userId,
+                  title,
+                  messages: visibleMessages,
+                  teacher: {
+                    id: this.selectedTeacher.id,
+                    name: this.selectedTeacher.name,
+                    description: this.selectedTeacher.description,
+                    systemPrompt: this.selectedTeacher.systemPrompt
+                  },
+                  createdAt: new Date(),
+                  updatedAt: new Date()
+                };
+
+                console.log('准备保存的会话数据:', sessionData); // 添加日志
+                
+                // 保存会话
+                await this.dbService.createChatSession(sessionData);
+                console.log('会话保存成功'); // 添加日志
+                await this.showAlert('成功', '会话已保存');
+              } catch (error) {
+                console.error('保存会话失败:', error);
+                await this.showAlert('错误', '保存失败,请重试');
+              }
+              return true; // 确保对话框关闭
             }
           }
-        }
-      ]
-    });
+        ]
+      });
 
-    await alert.present();
+      console.log('显示对话框'); // 添加日志
+      await alert.present();
+    } catch (error) {
+      console.error('保存会话过程中发生错误:', error);
+      await this.showAlert('错误', '保存失败,请重试');
+    }
   }
 
   // 辅助方法:显示提示框

+ 5 - 2
AiStudy-app/src/lib/ncloud.ts

@@ -282,6 +282,7 @@ export class CloudUser extends CloudObject {
             return;
         }
 
+        // 更新服务器地址
         const response = await fetch(`https://dev.fmode.cn/parse/logout`, {
             headers: {
                 "x-parse-application-id": "dev",
@@ -309,9 +310,10 @@ export class CloudUser extends CloudObject {
         const userData = {
             username,
             password,
-            ...additionalData // 合并额外的用户数据
+            ...additionalData
         };
 
+        // 更新服务器地址
         const response = await fetch(`https://dev.fmode.cn/parse/users`, {
             headers: {
                 "x-parse-application-id": "dev",
@@ -397,8 +399,9 @@ export class CloudApi{
             reqOpts.body = JSON.stringify(body || options?.body);
             reqOpts.json = true;
         }
+        
+        // 更新服务器地址
         let host = `https://dev.fmode.cn`
-        // host = `http://127.0.0.1:1337`
         let url = `${host}/api/`+path
         console.log(url,reqOpts)
         const response = await fetch(url,reqOpts);

+ 2 - 2
AiStudy-app/src/main.ts

@@ -13,8 +13,8 @@ import { provideHttpClient } from '@angular/common/http';
 import { Diagnostic } from '@awesome-cordova-plugins/diagnostic/ngx';
 // 设置Parse服务属性
 import Parse from "parse";
-Parse.initialize("ncloudmaster");
-Parse.serverURL = "https://server.fmode.cn/parse";
+Parse.initialize("dev");
+Parse.serverURL = "https://dev.fmode.cn/parse";
 localStorage.setItem("NOVA_APIG_SERVER", 'aHR0cHMlM0ElMkYlMkZzZXJ2ZXIuZm1vZGUuY24lMkZhcGklMkZhcGlnJTJG')
 
 // 设置 AI 服务器地址和默认 Token