曾鑫 2 月之前
父节点
当前提交
695cf4896b

+ 1 - 1
src/app/tab2/tab2.page.html

@@ -21,7 +21,7 @@
 
 
   <ion-card>
   <ion-card>
     <img alt="Silhouette of mountains" src="https://ts1.cn.mm.bing.net/th/id/R-C.3acd8f3a8a52b0fde3ccbc43e93ae477?rik=AEeBT0urPAlQSQ&riu=http%3a%2f%2fnwzimg.wezhan.cn%2fcontents%2fsitefiles2043%2f10215998%2fimages%2f20555491.jpg&ehk=NfkxF8xNAl5kG%2fcdDtRLWkXuqh5UHqoZFYIB7bdcKcc%3d&risl=&pid=ImgRaw&r=0" />
     <img alt="Silhouette of mountains" src="https://ts1.cn.mm.bing.net/th/id/R-C.3acd8f3a8a52b0fde3ccbc43e93ae477?rik=AEeBT0urPAlQSQ&riu=http%3a%2f%2fnwzimg.wezhan.cn%2fcontents%2fsitefiles2043%2f10215998%2fimages%2f20555491.jpg&ehk=NfkxF8xNAl5kG%2fcdDtRLWkXuqh5UHqoZFYIB7bdcKcc%3d&risl=&pid=ImgRaw&r=0" />
-    <ion-button expand="block" routerLink="/topic/chat">更多话题</ion-button>
+    <ion-button expand="block" color="light" routerLink="/topic/chat">更多话题</ion-button>
   </ion-card>
   </ion-card>
 
 
 </ion-content>
 </ion-content>

+ 16 - 1
src/modules/topic/chat/chat.page.html

@@ -6,6 +6,21 @@
 
 
 <ion-content [fullscreen]="true">
 <ion-content [fullscreen]="true">
   <ion-button fill="clear" routerLink="/tabs/tab2">〈</ion-button>
   <ion-button fill="clear" routerLink="/tabs/tab2">〈</ion-button>
-  
+
+
+  <ion-item>
+    <ion-input placeholder="输入消息" [(ngModel)]="userInput"></ion-input>
+  </ion-item>
+
+  <ion-button expand="block" (click)="sendMessage()">发送</ion-button>
+
+  <ion-card *ngFor="let message of messageList">
+    <ion-card-header>
+      {{message?.role}}
+    </ion-card-header>
+    <ion-card-content>
+      {{ message?.content }}
+    </ion-card-content>
+  </ion-card>
 
 
 </ion-content>
 </ion-content>

+ 22 - 1
src/modules/topic/chat/chat.page.ts

@@ -1,16 +1,37 @@
 import { Component, OnInit } from '@angular/core';
 import { Component, OnInit } from '@angular/core';
 import { Route, Router } from '@angular/router';
 import { Route, Router } from '@angular/router';
 
 
+import { TestChatCompletion, TestChatMessage } from './class-chat-completion';
+
 @Component({
 @Component({
   selector: 'app-chat',
   selector: 'app-chat',
   templateUrl: './chat.page.html',
   templateUrl: './chat.page.html',
   styleUrls: ['./chat.page.scss'],
   styleUrls: ['./chat.page.scss'],
 })
 })
 export class ChatPage implements OnInit {
 export class ChatPage implements OnInit {
+  messageList:Array<TestChatMessage> = []
+  userInput:string = ""
+
+  completion:TestChatCompletion
 
 
-  constructor() { }
+  constructor() {
+    
+    this.completion = new TestChatCompletion(this.messageList)
+    
+   }
 
 
   ngOnInit() {
   ngOnInit() {
   }
   }
 
 
+sendMessage(){
+  this.messageList.push({
+    role:"user",
+    content: this.userInput
+  })
+  this.userInput = ""
+  this.completion.createCompletionByStream()
+
+}
+
+
 }
 }

+ 99 - 0
src/modules/topic/chat/class-chat-completion.ts

@@ -0,0 +1,99 @@
+export interface TestChatMessage{
+    role:string
+    content:string
+}
+export class TestChatCompletion{
+messageList:Array<TestChatMessage>
+constructor(messageList:Array<TestChatMessage>){
+    this.messageList = messageList
+}
+async createCompletionByStream() {
+
+let token = localStorage.getItem("token");
+let bodyJson = {
+  "token": `Bearer ${token}`,
+  "messages": this.messageList,
+  "model": "gpt-3.5-turbo",
+  "temperature": 0.5,
+  "presence_penalty": 0,
+  "frequency_penalty": 0,
+  "top_p": 1,
+  "stream":true
+};
+
+let response = await fetch("https://test.fmode.cn/api/apig/aigc/gpt/v1/chat/completions", {
+  "headers": {
+    "accept": "text/event-stream",
+    "sec-fetch-dest": "empty",
+    "sec-fetch-mode": "cors",
+    "sec-fetch-site": "same-site"
+  },
+  "referrer": "https://ai.fmode.cn/",
+  "referrerPolicy": "strict-origin-when-cross-origin",
+  "body": JSON.stringify(bodyJson),
+  "method": "POST",
+  "mode": "cors",
+  "credentials": "omit"
+});
+
+let messageAiReply = ""
+let messageIndex = this.messageList.length
+let reader = response.body?.getReader();
+if (!reader) {
+  throw new Error("Failed to get the response reader.");
+}
+
+let decoder = new TextDecoder();
+let buffer = "";
+
+while (true) {
+  let { done, value } = await reader.read();
+  if (done) {
+    break;
+  }
+
+  buffer += decoder.decode(value);
+
+  // Split the buffer by newlines to get individual messages
+  let messages = buffer.split("\n");
+
+  // Process each message
+  for (let i = 0; i < messages.length - 1; i++) {
+    let message = messages[i];
+
+    // Process the message as needed
+    /**
+     * data: {"id":"chatcmpl-y2PLKqPDnwAFJIj2L5aqdH5TWK9Yv","object":"chat.completion.chunk","created":1696770162,"model":"gpt-3.5-turbo-0613","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
+     * data: {"id":"chatcmpl-y2PLKqPDnwAFJIj2L5aqdH5TWK9Yv","object":"chat.completion.chunk","created":1696770162,"model":"gpt-3.5-turbo-0613","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
+     * data: [DONE]
+     */
+    let dataText = message.replace("data:\ ","")
+    if(dataText.startsWith("{")){
+      try{
+        let dataJson = JSON.parse(dataText)
+        console.log(dataJson)
+        messageAiReply += dataJson?.choices?.[0]?.delta?.content || ""
+        this.messageList[messageIndex] = {
+          role:"assistant",
+          content:messageAiReply
+        }
+      }catch(err){}
+    }
+    if(dataText.startsWith("[")){
+      console.log(message)
+      console.log("完成")
+      this.messageList[messageIndex] = {
+        role:"assistant",
+        content:messageAiReply
+      }
+      messageAiReply = ""
+    }
+    // Parse the message as JSON
+    // let data = JSON.parse(message);
+
+    // Clear the processed message from the buffer
+    buffer = buffer.slice(message.length + 1);
+  }
+}
+}
+}