Browse Source

11.30-23:23选择ai教师初步

15270821319 6 months ago
parent
commit
8e81f5facd

+ 51 - 26
AiStudy-app/src/app/tab1/tab1.page.html

@@ -1,36 +1,61 @@
 <ion-header [translucent]="true">
-  <ion-toolbar>
-    <ion-title>AI学习交互</ion-title>
-  </ion-toolbar>
+  <div class="teacher-selector">
+    <ion-button fill="clear" id="select-teacher">
+      <div class="teacher-info">
+        <ion-icon name="person-circle-outline" class="teacher-icon"></ion-icon>
+        <div class="teacher-name">{{ selectedTeacher.name }}</div>
+        <div class="teacher-description">{{ selectedTeacher.description }}</div>
+      </div>
+    </ion-button>
+
+    <ion-modal trigger="select-teacher" [breakpoints]="[0, 0.5]" [initialBreakpoint]="0.5">
+      <ng-template>
+        <ion-content>
+          <ion-list>
+            <ion-item *ngFor="let teacher of teachers" (click)="selectTeacher(teacher)" [class.selected]="teacher.id === selectedTeacher.id">
+              <div class="teacher-list-item">
+                <ion-icon name="person-circle-outline" class="teacher-icon"></ion-icon>
+                <div class="teacher-details">
+                  <div class="teacher-name">{{ teacher.name }}</div>
+                  <div class="teacher-description">{{ teacher.description }}</div>
+                </div>
+              </div>
+            </ion-item>
+          </ion-list>
+        </ion-content>
+      </ng-template>
+    </ion-modal>
+  </div>
 </ion-header>
 
-<ion-content [fullscreen]="true" class="ion-padding">
+<ion-content [fullscreen]="true">
   <div class="chat-container">
-    <!-- 历史消息显示 -->
-    <div *ngFor="let message of messages" 
-         [ngClass]="{'user-message': message.isUser, 'ai-message': !message.isUser}" 
-         class="message-wrapper">
-      <div class="message-bubble">
-        <!-- 使用 markdown 预览组件显示 AI 回复 -->
-        @if(message.isUser) {
-          <div class="message-content">{{ message.content }}</div>
-        } @else {
-          <fm-markdown-preview class="message-content" [content]="message.content"></fm-markdown-preview>
-        }
-        <div class="message-time">
-          {{ message.timestamp | date:'HH:mm' }}
-        </div>
-      </div>
-    </div>
-    
-    <!-- 实时消息预览 -->
-    @if(isLoading && !isComplete) {
-      <div class="ai-message message-wrapper">
+    <div class="chat-content">
+      <!-- 历史消息显示 -->
+      <div *ngFor="let message of messages" 
+           [ngClass]="{'user-message': message.isUser, 'ai-message': !message.isUser}" 
+           class="message-wrapper">
         <div class="message-bubble">
-          <div class="message-content">{{ currentResponse }}</div>
+          @if(message.isUser) {
+            <div class="message-content">{{ message.content }}</div>
+          } @else {
+            <fm-markdown-preview class="message-content" [content]="message.content"></fm-markdown-preview>
+          }
+          <div class="message-time">
+            {{ message.timestamp | date:'HH:mm' }}
+          </div>
         </div>
       </div>
-    }
+      
+      <!-- 实时消息预览 -->
+      @if(isLoading && !isComplete) {
+        <div class="ai-message message-wrapper">
+          <div class="message-bubble">
+            <div class="message-content">{{ currentResponse }}</div>
+          </div>
+        </div>
+      }
+    </div>
   </div>
 </ion-content>
 

+ 81 - 1
AiStudy-app/src/app/tab1/tab1.page.scss

@@ -1,11 +1,19 @@
 .chat-container {
   display: flex;
   flex-direction: column;
-  padding: 10px;
+  padding: 16px;
   padding-bottom: 60px;
   height: 100%;
   overflow-y: auto;
   scroll-behavior: smooth;
+  margin-top: 10px;
+  position: relative;
+}
+
+.chat-content {
+  padding: 16px;
+  padding-bottom: 60px;
+  padding-top: 80px;
 }
 
 .message-wrapper {
@@ -80,3 +88,75 @@ ion-input {
 ion-button {
   margin: 0;
 }
+
+.teacher-selector {
+  background: var(--ion-background-color);
+  padding: 12px;
+  text-align: center;
+  border-bottom: 1px solid var(--ion-color-light-shade);
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  z-index: 1000;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+}
+
+.teacher-info {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  width: 100%;
+}
+
+.teacher-icon {
+  font-size: 28px;
+  margin-bottom: 4px;
+  color: var(--ion-color-primary);
+}
+
+.teacher-name {
+  font-size: 16px;
+  font-weight: 500;
+  color: var(--ion-color-dark);
+  margin-bottom: 2px;
+}
+
+.teacher-description {
+  font-size: 12px;
+  color: var(--ion-color-medium);
+}
+
+.teacher-list-item {
+  display: flex;
+  align-items: center;
+  padding: 12px 0;
+  width: 100%;
+}
+
+.teacher-details {
+  margin-left: 12px;
+}
+
+ion-item.selected {
+  --background: var(--ion-color-light);
+}
+
+ion-content {
+  --padding-top: 0;
+}
+
+ion-button#select-teacher {
+  --background: var(--ion-background-color);
+  --background-hover: var(--ion-background-color);
+  --background-activated: var(--ion-background-color);
+  --box-shadow: none;
+  --border-style: none;
+  --ripple-color: transparent;
+  --padding-start: 16px;
+  --padding-end: 16px;
+  width: 100%;
+  max-width: 300px;
+  margin: 0 auto;
+  height: auto;
+}

+ 55 - 4
AiStudy-app/src/app/tab1/tab1.page.ts

@@ -1,9 +1,9 @@
 import { Component, ViewChild } from '@angular/core';
-import { IonHeader, IonToolbar, IonTitle, IonContent, IonFooter, IonItem, IonTextarea, IonButton, IonIcon } from '@ionic/angular/standalone';
+import { IonHeader, IonToolbar, IonTitle, IonContent, IonFooter, IonItem, IonTextarea, IonButton, IonIcon, IonModal, IonList } from '@ionic/angular/standalone';
 import { FormsModule } from '@angular/forms';
 import { NgClass, NgFor, NgIf, DatePipe } from '@angular/common';
 import { addIcons } from 'ionicons';
-import { send } from 'ionicons/icons';
+import { send, personCircleOutline } from 'ionicons/icons';
 import { FmodeChatCompletion, MarkdownPreviewModule } from 'fmode-ng';
 
 // 定义消息接口
@@ -13,6 +13,14 @@ interface ChatMessage {
   timestamp: Date;
 }
 
+// 定义教师接口
+interface Teacher {
+  id: string;
+  name: string;
+  description: string;
+  systemPrompt: string;
+}
+
 @Component({
   selector: 'app-tab1',
   templateUrl: 'tab1.page.html',
@@ -28,6 +36,8 @@ interface ChatMessage {
     IonTextarea,
     IonButton,
     IonIcon,
+    IonModal,
+    IonList,
     FormsModule,
     NgClass,
     NgFor,
@@ -45,8 +55,49 @@ export class Tab1Page {
   isComplete: boolean = false;
   currentResponse: string = '';
 
+  // 添加教师相关属性
+  teachers: Teacher[] = [
+    {
+      id: 'xiaoai',
+      name: '教师小爱',
+      description: '亲切友善,擅长耐心解答各类问题',
+      systemPrompt: '你是一位亲切友善的教师,擅长耐心解答学生的各类问题。'
+    },
+    {
+      id: 'yan',
+      name: '严教授',
+      description: '一丝不苟,讲解知识逻辑清晰、严谨细致',
+      systemPrompt: '你是一位一丝不苟的教师,讲解知识逻辑清晰、严谨细致。在回答学生的问题时,提供详尽的解释和步骤,确保学生理解每一个细节。'
+    },
+    {
+      id: 'youyou',
+      name: '悠悠老师',
+      description: '风趣幽默,善于用生动例子讲解知识',
+      systemPrompt: '你是一位风趣幽默的教师,善于用生动的语言和有趣的例子讲解知识。通过幽默的表达方式,使用形象化的比喻和生活实例,讲解复杂的概念。'
+    },
+    {
+      id: 'di',
+      name: '迪先生',
+      description: '启发思维,善于引导学生独立思考',
+      systemPrompt: '你是一位启发思维型的教师,善于通过提问和引导帮助学生思考。在回答问题时,可以有时不直接给出答案,而是通过提问和提示,引导学生自己得出结论。'
+    },
+    {
+      id: 'custom',
+      name: '自定义教师',
+      description: '创建您自己的AI教师(开发中)',
+      systemPrompt: ''
+    }
+  ];
+
+  selectedTeacher: Teacher = this.teachers[0]; // 默认选择教师小爱
+
   constructor() {
-    addIcons({ send });
+    addIcons({ send, personCircleOutline });
+  }
+
+  // 添加选择教师的方法
+  selectTeacher(teacher: Teacher) {
+    this.selectedTeacher = teacher;
   }
 
   // 发送消息
@@ -66,7 +117,7 @@ export class Tab1Page {
 
       // 创建 completion 实例
       const completion = new FmodeChatCompletion([
-        { role: "system", content: "你是一个专业的教师,可以帮助用户解答各种学习问题。" },
+        { role: "system", content: this.selectedTeacher.systemPrompt },
         { role: "user", content: this.userInput }
       ]);