课堂监控项目策划书 1 жил өмнө
parent
commit
da679011ec

+ 68 - 3
src/app/bookcoach/bookcoach.component.html

@@ -1,3 +1,68 @@
-<p>
-  bookcoach works!
-</p>
+<ion-header>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-back-button defaultHref="/tabs/information"></ion-back-button>
+    </ion-buttons>
+    <ion-title>AI教练问答</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+  <div class="chat-container">
+    <!-- 欢迎消息 -->
+    <div class="welcome-message">
+      <div class="ai-avatar">
+        <img src="assets/tab1.img/zhang.png" alt="AI Coach">
+      </div>
+      <div class="message-content">
+        <h2>您好!我是您的AI篮球教练</h2>
+        <p>我可以为您解答篮球训练相关的问题,提供专业的建议和指导。</p>
+      </div>
+    </div>
+
+    <!-- 聊天记录 -->
+    <div class="chat-messages" #chatContainer>
+      <div *ngFor="let message of messages" 
+           [ngClass]="{'message': true, 'user-message': message.isUser, 'ai-message': !message.isUser}">
+        <div class="message-avatar" *ngIf="!message.isUser">
+          <img src="assets/tab1.img/zhang.png" alt="AI Coach">
+        </div>
+        <div class="message-bubble">
+          <div class="message-text" [innerHTML]="message.content"></div>
+          <div class="message-time">{{message.time | date:'HH:mm'}}</div>
+        </div>
+      </div>
+
+      <!-- 输入提示动画 -->
+      <div class="typing-indicator" *ngIf="isTyping">
+        <div class="dot"></div>
+        <div class="dot"></div>
+        <div class="dot"></div>
+      </div>
+    </div>
+  </div>
+</ion-content>
+
+<!-- 底部输入区域 -->
+<ion-footer>
+  <div class="input-container">
+    <div class="suggestion-chips" *ngIf="showSuggestions">
+      <ion-chip *ngFor="let suggestion of suggestions" (click)="selectSuggestion(suggestion)">
+        <ion-label>{{suggestion}}</ion-label>
+      </ion-chip>
+    </div>
+    <div class="input-wrapper">
+      <ion-textarea
+        #messageInput
+        placeholder="请输入您的问题..."
+        [rows]="1"
+        [autoGrow]="true"
+        [(ngModel)]="newMessage"
+        (keyup.enter)="sendMessage()"
+      ></ion-textarea>
+      <ion-button fill="clear" (click)="sendMessage()" [disabled]="!newMessage.trim()">
+        <ion-icon name="send" slot="icon-only"></ion-icon>
+      </ion-button>
+    </div>
+  </div>
+</ion-footer>

+ 200 - 0
src/app/bookcoach/bookcoach.component.scss

@@ -0,0 +1,200 @@
+.chat-container {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  background: #f5f7fa;
+}
+
+.welcome-message {
+  display: flex;
+  align-items: flex-start;
+  padding: 20px;
+  background: white;
+  margin: 16px;
+  border-radius: 16px;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
+  
+  .ai-avatar {
+    width: 48px;
+    height: 48px;
+    margin-right: 12px;
+    
+    img {
+      width: 100%;
+      height: 100%;
+      border-radius: 50%;
+      object-fit: cover;
+    }
+  }
+  
+  .message-content {
+    flex: 1;
+    
+    h2 {
+      margin: 0 0 8px;
+      font-size: 1.2em;
+      color: #2c3e50;
+    }
+    
+    p {
+      margin: 0;
+      color: #666;
+      font-size: 0.95em;
+      line-height: 1.5;
+    }
+  }
+}
+
+.chat-messages {
+  flex: 1;
+  overflow-y: auto;
+  padding: 16px;
+  
+  .message {
+    display: flex;
+    margin-bottom: 16px;
+    
+    &.user-message {
+      flex-direction: row-reverse;
+      
+      .message-bubble {
+        background: linear-gradient(135deg, #4CAF50, #45b649);
+        color: white;
+        margin-left: auto;
+        
+        .message-time {
+          color: rgba(255, 255, 255, 0.8);
+        }
+      }
+    }
+    
+    &.ai-message {
+      .message-bubble {
+        background: white;
+        color: #2c3e50;
+      }
+    }
+  }
+  
+  .message-avatar {
+    width: 36px;
+    height: 36px;
+    margin: 0 8px;
+    
+    img {
+      width: 100%;
+      height: 100%;
+      border-radius: 50%;
+      object-fit: cover;
+    }
+  }
+  
+  .message-bubble {
+    max-width: 70%;
+    padding: 12px 16px;
+    border-radius: 16px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+    
+    .message-text {
+      font-size: 0.95em;
+      line-height: 1.5;
+      white-space: pre-wrap;
+    }
+    
+    .message-time {
+      font-size: 0.8em;
+      margin-top: 4px;
+      opacity: 0.7;
+      text-align: right;
+    }
+  }
+}
+
+.typing-indicator {
+  display: flex;
+  align-items: center;
+  padding: 12px 16px;
+  background: white;
+  border-radius: 16px;
+  width: fit-content;
+  margin: 8px;
+  
+  .dot {
+    width: 8px;
+    height: 8px;
+    background: #4CAF50;
+    border-radius: 50%;
+    margin: 0 2px;
+    animation: typing 1s infinite ease-in-out;
+    
+    &:nth-child(1) { animation-delay: 0s; }
+    &:nth-child(2) { animation-delay: 0.2s; }
+    &:nth-child(3) { animation-delay: 0.4s; }
+  }
+}
+
+@keyframes typing {
+  0%, 100% { transform: translateY(0); }
+  50% { transform: translateY(-6px); }
+}
+
+.input-container {
+  background: white;
+  padding: 8px 16px;
+  border-top: 1px solid #eee;
+  
+  .suggestion-chips {
+    display: flex;
+    gap: 8px;
+    padding: 8px 0;
+    overflow-x: auto;
+    
+    ion-chip {
+      flex-shrink: 0;
+      background: #f0f2f5;
+      color: #2c3e50;
+      font-size: 0.9em;
+      
+      &:hover {
+        background: #e4e6e9;
+      }
+    }
+  }
+  
+  .input-wrapper {
+    display: flex;
+    align-items: flex-end;
+    gap: 8px;
+    background: #f0f2f5;
+    border-radius: 24px;
+    padding: 8px 16px;
+    
+    ion-textarea {
+      --padding-top: 8px;
+      --padding-bottom: 8px;
+      --padding-start: 0;
+      --padding-end: 0;
+      margin: 0;
+      
+      &::part(native) {
+        margin: 0;
+      }
+    }
+    
+    ion-button {
+      --padding-start: 4px;
+      --padding-end: 4px;
+      height: 36px;
+      margin: 0;
+      
+      ion-icon {
+        color: #4CAF50;
+        font-size: 20px;
+      }
+      
+      &[disabled] ion-icon {
+        color: #999;
+      }
+    }
+  }
+}

+ 85 - 3
src/app/bookcoach/bookcoach.component.ts

@@ -1,15 +1,97 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { IonicModule } from '@ionic/angular';
+import { FormsModule } from '@angular/forms';
+
+interface ChatMessage {
+  content: string;
+  isUser: boolean;
+  time: Date;
+}
 
 @Component({
   selector: 'app-bookcoach',
   templateUrl: './bookcoach.component.html',
   styleUrls: ['./bookcoach.component.scss'],
   standalone: true,
+  imports: [CommonModule, IonicModule, FormsModule]
 })
-export class BookcoachComponent  implements OnInit {
+export class BookcoachComponent implements OnInit {
+  @ViewChild('chatContainer') private chatContainer!: ElementRef;
+  @ViewChild('messageInput') private messageInput!: ElementRef;
+
+  messages: ChatMessage[] = [];
+  newMessage: string = '';
+  isTyping: boolean = false;
+  showSuggestions: boolean = true;
+
+  suggestions: string[] = [
+    '如何提高投篮命中率?',
+    '篮球基础训练有哪些?',
+    '怎样提升防守能力?',
+    '篮球战术布置技巧'
+  ];
 
   constructor() { }
 
-  ngOnInit() {}
+  ngOnInit() {
+    // 可以添加初始欢迎消息
+  }
+
+  sendMessage() {
+    if (this.newMessage.trim()) {
+      // 添加用户消息
+      this.messages.push({
+        content: this.newMessage,
+        isUser: true,
+        time: new Date()
+      });
+
+      // 清空输入框
+      const userMessage = this.newMessage;
+      this.newMessage = '';
+
+      // 显示AI正在输入
+      this.isTyping = true;
+      this.showSuggestions = false;
+
+      // 模拟AI回复
+      setTimeout(() => {
+        this.isTyping = false;
+        this.messages.push({
+          content: this.getAIResponse(userMessage),
+          isUser: false,
+          time: new Date()
+        });
+        this.scrollToBottom();
+      }, 1500);
+
+      this.scrollToBottom();
+    }
+  }
+
+  selectSuggestion(suggestion: string) {
+    this.newMessage = suggestion;
+    this.sendMessage();
+  }
+
+  private scrollToBottom() {
+    setTimeout(() => {
+      if (this.chatContainer) {
+        const element = this.chatContainer.nativeElement;
+        element.scrollTop = element.scrollHeight;
+      }
+    });
+  }
 
+  private getAIResponse(message: string): string {
+    // 这里可以实现实际的AI响应逻辑
+    const responses = [
+      '这是一个很好的问题!让我为您详细解答...',
+      '根据我的经验,您可以尝试以下方法...',
+      '这个问题涉及到几个关键点,首先...',
+      '作为教练,我建议您可以这样做...'
+    ];
+    return responses[Math.floor(Math.random() * responses.length)];
+  }
 }