|
@@ -1,17 +1,20 @@
|
|
import { Component, OnInit } from '@angular/core';
|
|
import { Component, OnInit } from '@angular/core';
|
|
import { IonicModule } from '@ionic/angular';
|
|
import { IonicModule } from '@ionic/angular';
|
|
import { FormsModule } from '@angular/forms';
|
|
import { FormsModule } from '@angular/forms';
|
|
-import { CommonModule } from '@angular/common'; // 导入 CommonModule
|
|
|
|
|
|
+import { CommonModule } from '@angular/common';
|
|
import { TagInputComponent } from '../tag-input/tag-input.component';
|
|
import { TagInputComponent } from '../tag-input/tag-input.component';
|
|
import { addIcons } from 'ionicons';
|
|
import { addIcons } from 'ionicons';
|
|
import { barbellOutline, personOutline, square, alarmOutline } from 'ionicons/icons';
|
|
import { barbellOutline, personOutline, square, alarmOutline } from 'ionicons/icons';
|
|
|
|
+import { FmodeChatCompletion, MarkdownPreviewModule } from 'fmode-ng';
|
|
|
|
|
|
@Component({
|
|
@Component({
|
|
selector: 'app-test-page',
|
|
selector: 'app-test-page',
|
|
templateUrl: './test-page.component.html',
|
|
templateUrl: './test-page.component.html',
|
|
styleUrls: ['./test-page.component.scss'],
|
|
styleUrls: ['./test-page.component.scss'],
|
|
standalone: true,
|
|
standalone: true,
|
|
- imports: [IonicModule, FormsModule, CommonModule, TagInputComponent] // 添加 CommonModule
|
|
|
|
|
|
+ imports: [IonicModule, FormsModule, CommonModule, TagInputComponent,
|
|
|
|
+ // 引入fm-markdown-preview组件模块
|
|
|
|
+ MarkdownPreviewModule] // 添加 CommonModule
|
|
})
|
|
})
|
|
export class TestPageComponent implements OnInit {
|
|
export class TestPageComponent implements OnInit {
|
|
selectedTags: string[] = [];
|
|
selectedTags: string[] = [];
|
|
@@ -61,10 +64,10 @@ export class TestPageComponent implements OnInit {
|
|
}
|
|
}
|
|
|
|
|
|
async generatePlan() {
|
|
async generatePlan() {
|
|
- this.isGenerating = true; // 开始生成计划时禁用按钮
|
|
|
|
|
|
+
|
|
this.generatedPlan = ''; // 清空之前的结果
|
|
this.generatedPlan = ''; // 清空之前的结果
|
|
this.messageList = []; // 清空旧的消息列表,避免重复内容
|
|
this.messageList = []; // 清空旧的消息列表,避免重复内容
|
|
-
|
|
|
|
|
|
+ this.isGenerating = true;
|
|
console.log('生成健身计划', {
|
|
console.log('生成健身计划', {
|
|
tags: this.selectedTags,
|
|
tags: this.selectedTags,
|
|
exercisePreference: this.exercisePreference,
|
|
exercisePreference: this.exercisePreference,
|
|
@@ -78,72 +81,80 @@ export class TestPageComponent implements OnInit {
|
|
let prompt = `您作为一名专业的健身计划定制大师,请帮我根据以下情况制定健身计划(健身计划请给每天的运动标上序号)。关键词:${this.selectedTags.join(",")},目标描述:${this.goalDescription},运动偏好:${this.exercisePreference},
|
|
let prompt = `您作为一名专业的健身计划定制大师,请帮我根据以下情况制定健身计划(健身计划请给每天的运动标上序号)。关键词:${this.selectedTags.join(",")},目标描述:${this.goalDescription},运动偏好:${this.exercisePreference},
|
|
健身频率一周:${this.workoutFrequency},身高:${this.height}cm,体重:${this.weight}kg,年龄:${this.age}`;
|
|
健身频率一周:${this.workoutFrequency},身高:${this.height}cm,体重:${this.weight}kg,年龄:${this.age}`;
|
|
|
|
|
|
- let TOKEN = `r:E4KpGvTEto-131588121831732778669`;
|
|
|
|
- localStorage.setItem("token", TOKEN);
|
|
|
|
|
|
+ // let TOKEN = `r:E4KpGvTEto-131588121831732778669`;
|
|
|
|
+ // localStorage.setItem("token", TOKEN);
|
|
|
|
|
|
- let messageList: any = [
|
|
|
|
- { role: "system", content: `开始生成健身计划:${new Date().toDateString()}` },
|
|
|
|
|
|
+ let messageList = new FmodeChatCompletion([
|
|
|
|
+ { role: "system", content: '' },
|
|
{ role: "user", content: prompt }
|
|
{ role: "user", content: prompt }
|
|
- ];
|
|
|
|
-
|
|
|
|
- let bodyJson = {
|
|
|
|
- "token": `Bearer ${TOKEN}`,
|
|
|
|
- "messages": messageList,
|
|
|
|
- "model": "fmode-4.5-128k",
|
|
|
|
- "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"
|
|
|
|
- },
|
|
|
|
- "body": JSON.stringify(bodyJson),
|
|
|
|
- "method": "POST",
|
|
|
|
- "mode": "cors",
|
|
|
|
- "credentials": "omit"
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- let reader = response.body?.getReader();
|
|
|
|
- if (!reader) {
|
|
|
|
- throw new Error("Failed to get the response reader.");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- let buffer = "";
|
|
|
|
- const decoder = new TextDecoder(); // 定义 TextDecoder
|
|
|
|
- while (true) {
|
|
|
|
- let { done, value } = await reader.read();
|
|
|
|
- if (done) break;
|
|
|
|
-
|
|
|
|
- let data = decoder.decode(value);
|
|
|
|
- buffer += data; // 保留数据流中的内容
|
|
|
|
-
|
|
|
|
- let messages = buffer.split("\n");
|
|
|
|
- buffer = messages.pop() || ""; // 保留未处理的部分
|
|
|
|
-
|
|
|
|
- messages.forEach(message => {
|
|
|
|
- let dataText: string = message.split("data: ")[1];
|
|
|
|
- if (dataText && dataText.startsWith("{")) {
|
|
|
|
- try {
|
|
|
|
- let json = JSON.parse(dataText);
|
|
|
|
- let content = json?.choices?.[0]?.delta?.content;
|
|
|
|
- if (content) {
|
|
|
|
- console.log(content);
|
|
|
|
- this.generatedPlan += content; // 追加内容
|
|
|
|
- }
|
|
|
|
- } catch (err) {
|
|
|
|
- console.error('生成计划失败:', err);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- this.isGenerating = false; // 生成结束后恢复按钮
|
|
|
|
|
|
+ ]);
|
|
|
|
+ messageList.sendCompletion().subscribe((message: any) => {
|
|
|
|
+ // 打印消息体
|
|
|
|
+ console.log(message.content)
|
|
|
|
+ // 赋值消息内容给组件内属性
|
|
|
|
+ this.generatedPlan = message.content
|
|
|
|
+ if (message?.complete) { // 判断message为完成状态,则设置isComplete为完成
|
|
|
|
+ this.isGenerating = false
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ // let bodyJson = {
|
|
|
|
+ // "token": `Bearer ${TOKEN}`,
|
|
|
|
+ // "messages": messageList,
|
|
|
|
+ // "model": "fmode-4.5-128k",
|
|
|
|
+ // "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"
|
|
|
|
+ // },
|
|
|
|
+ // "body": JSON.stringify(bodyJson),
|
|
|
|
+ // "method": "POST",
|
|
|
|
+ // "mode": "cors",
|
|
|
|
+ // "credentials": "omit"
|
|
|
|
+ // });
|
|
|
|
+
|
|
|
|
+ // let reader = response.body?.getReader();
|
|
|
|
+ // if (!reader) {
|
|
|
|
+ // throw new Error("Failed to get the response reader.");
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ // let buffer = "";
|
|
|
|
+ // const decoder = new TextDecoder(); // 定义 TextDecoder
|
|
|
|
+ // while (true) {
|
|
|
|
+ // let { done, value } = await reader.read();
|
|
|
|
+ // if (done) break;
|
|
|
|
+
|
|
|
|
+ // let data = decoder.decode(value);
|
|
|
|
+ // buffer += data; // 保留数据流中的内容
|
|
|
|
+
|
|
|
|
+ // let messages = buffer.split("\n");
|
|
|
|
+ // buffer = messages.pop() || ""; // 保留未处理的部分
|
|
|
|
+
|
|
|
|
+ // messages.forEach(message => {
|
|
|
|
+ // let dataText: string = message.split("data: ")[1];
|
|
|
|
+ // if (dataText && dataText.startsWith("{")) {
|
|
|
|
+ // try {
|
|
|
|
+ // let json = JSON.parse(dataText);
|
|
|
|
+ // let content = json?.choices?.[0]?.delta?.content;
|
|
|
|
+ // if (content) {
|
|
|
|
+ // console.log(content);
|
|
|
|
+ // this.generatedPlan += content;
|
|
|
|
+ // }
|
|
|
|
+ // } catch (err) {
|
|
|
|
+ // console.error('生成计划失败:', err);
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+ // });
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ // this.isGenerating = false; // 生成结束后恢复按钮
|
|
}
|
|
}
|
|
}
|
|
}
|