未来全栈 hai 4 meses
pai
achega
976ecad506

+ 8 - 4
src/app/app-routing.module.ts

@@ -12,15 +12,19 @@ const routes: Routes = [
   },
   {
     path: 'comments',
-    loadChildren: () => import('./comments/comments.module').then( m => m.CommentsPageModule)
+    loadChildren: () => import('./comments/comments.module').then(m => m.CommentsPageModule)
   },
   {
     path: 'comment-modal',
-    loadChildren: () => import('./comment-modal/comment-modal.module').then( m => m.CommentModalPageModule)
+    loadChildren: () => import('./comment-modal/comment-modal.module').then(m => m.CommentModalPageModule)
   },
   {
     path: 'begin-page',
-    loadChildren: () => import('./begin-page/begin-page.module').then( m => m.BeginPagePageModule)
+    loadChildren: () => import('./begin-page/begin-page.module').then(m => m.BeginPagePageModule)
+  },
+  {
+    path: 'aigc',
+    loadChildren: () => import('../modules/aigc/aigc.module').then(m => m.AigcModule)
   }
 ];
 @NgModule({
@@ -29,4 +33,4 @@ const routes: Routes = [
   ],
   exports: [RouterModule]
 })
-export class AppRoutingModule {}
+export class AppRoutingModule { }

+ 7 - 7
src/app/tab1/tab1.page.html

@@ -7,18 +7,18 @@
   <ion-content class="ion-padding">
     <ion-list>
       <ion-item>
-        <ion-toggle>Receive Push Notifications</ion-toggle>
+        <ion-toggle>禁止评论本人发布的信息</ion-toggle>
       </ion-item>
       <ion-item>
-        <ion-toggle>Receive Emails</ion-toggle>
+        <ion-toggle>生成报告</ion-toggle>
       </ion-item>
       <ion-item>
-        <ion-toggle>Receive Text Messages</ion-toggle>
+        <ion-toggle>消息提醒</ion-toggle>
       </ion-item>
-      <ion-select label="Default label" placeholder="Favorite Fruit">
-        <ion-select-option value="apple">Apple</ion-select-option>
-        <ion-select-option value="banana">Banana</ion-select-option>
-        <ion-select-option value="orange">Orange</ion-select-option>
+      <ion-select label="桌面背景" placeholder="背景类型">
+        <ion-select-option value="白天">白天</ion-select-option>
+        <ion-select-option value="深夜">深夜</ion-select-option>
+        <ion-select-option value="护眼">护眼</ion-select-option>
       </ion-select>
     </ion-list>
   </ion-content>

+ 12 - 0
src/app/tab1/tab1.page.scss

@@ -0,0 +1,12 @@
+ion-header {
+    ion-toolbar {
+
+        ion-icon {
+            margin-left: 1px; /* 将图标推到右侧 */
+            // display: flex;
+            margin-right: 20px;
+            font-size: 1.5rem; /* 设置图标大小 */
+        }
+    }
+
+}

+ 10 - 5
src/app/tab2/tab2.page.html

@@ -1,7 +1,7 @@
 <ion-header [translucent]="true">
   <ion-toolbar>
     <ion-title>
-      智能解答
+      AI解答示例
     </ion-title>
   </ion-toolbar>
 </ion-header>
@@ -10,7 +10,9 @@
   <div class="chat-container">
     <div class="messages">
       <div class="message received">
-        <img src="https://tse3-mm.cn.bing.net/th/id/OIP-C.QGUz1-tWsQhwsa3F6i9nGAHaHa?w=268&h=201&c=7&r=0&o=5&dpr=1.3&pid=1.7" class="avatar1">
+        <img
+          src="https://tse3-mm.cn.bing.net/th/id/OIP-C.QGUz1-tWsQhwsa3F6i9nGAHaHa?w=268&h=201&c=7&r=0&o=5&dpr=1.3&pid=1.7"
+          class="avatar1">
         <div class="message-content">
           <p>你好!有什么问题我可以帮助你解答吗?</p>
         </div>
@@ -20,13 +22,16 @@
         <div class="message-content">
           <p>你好!我想询问关于梦境的信息。</p>
         </div>
-        <img src="https://tse3-mm.cn.bing.net/th/id/OIP-C.QGUz1-tWsQhwsa3F6i9nGAHaHa?w=268&h=201&c=7&r=0&o=5&dpr=1.3&pid=1.7" class="avatar2">
+        <img
+          src="https://tse3-mm.cn.bing.net/th/id/OIP-C.QGUz1-tWsQhwsa3F6i9nGAHaHa?w=268&h=201&c=7&r=0&o=5&dpr=1.3&pid=1.7"
+          class="avatar2">
       </div>
       <!-- 更多聊天消息可以继续添加 -->
     </div>
-    <div class="input-container">
+    <!-- <div class="input-container">
       <ion-input placeholder="输入消息"></ion-input>
       <ion-button expand="block" color="primary">发送</ion-button>
-    </div>
+    </div> -->
   </div>
+  <ion-button expand="block" routerLink="/aigc/chat">使用AI</ion-button>
 </ion-content>

+ 12 - 0
src/modules/aigc/aigc-routing.module.ts

@@ -0,0 +1,12 @@
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+
+const routes: Routes = [
+  {path: 'chat', loadChildren: () => import('./chat/chat.module').then(mod => mod.ChatPageModule)},
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+export class AigcRoutingModule { }

+ 14 - 0
src/modules/aigc/aigc.module.ts

@@ -0,0 +1,14 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { AigcRoutingModule } from './aigc-routing.module';
+
+
+@NgModule({
+  declarations: [],
+  imports: [
+    CommonModule,
+    AigcRoutingModule
+  ]
+})
+export class AigcModule { }

+ 17 - 0
src/modules/aigc/chat/chat-routing.module.ts

@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { ChatPage } from './chat.page';
+
+const routes: Routes = [
+  {
+    path: '',
+    component: ChatPage
+  }
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class ChatPageRoutingModule {}

+ 20 - 0
src/modules/aigc/chat/chat.module.ts

@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { IonicModule } from '@ionic/angular';
+
+import { ChatPageRoutingModule } from './chat-routing.module';
+
+import { ChatPage } from './chat.page';
+
+@NgModule({
+  imports: [
+    CommonModule,
+    FormsModule,
+    IonicModule,
+    ChatPageRoutingModule
+  ],
+  declarations: [ChatPage]
+})
+export class ChatPageModule {}

+ 27 - 0
src/modules/aigc/chat/chat.page.html

@@ -0,0 +1,27 @@
+<ion-header>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-back-button defaultHref="/tabs/tab1"></ion-back-button>
+    </ion-buttons>
+    <ion-title>
+      AI解答
+    </ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+  <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>

+ 0 - 0
src/modules/aigc/chat/chat.page.scss


+ 17 - 0
src/modules/aigc/chat/chat.page.spec.ts

@@ -0,0 +1,17 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ChatPage } from './chat.page';
+
+describe('ChatPage', () => {
+  let component: ChatPage;
+  let fixture: ComponentFixture<ChatPage>;
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ChatPage);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 31 - 0
src/modules/aigc/chat/chat.page.ts

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

+ 99 - 0
src/modules/aigc/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);
+  }
+}
+}
+}