Jelajahi Sumber

Merge branch 'main'

lzy 1 tahun lalu
induk
melakukan
679f504a4e
2 mengubah file dengan 154 tambahan dan 28 penghapusan
  1. 10 8
      FilmDraw-app/src/app/tab2/tab2.page.html
  2. 144 20
      FilmDraw-app/src/app/tab2/tab2.page.ts

+ 10 - 8
FilmDraw-app/src/app/tab2/tab2.page.html

@@ -34,9 +34,9 @@
             </ion-label>
           }
         </ion-item>
-        <ion-button (click)="goToPage()">
+        <!-- <ion-button (click)="goToPage()">
           生成用户画像
-        </ion-button>
+        </ion-button> -->
         </ion-card-content>
       </ion-card>
     </section>
@@ -62,15 +62,17 @@
           <ion-card-title>为您推荐</ion-card-title>
         </ion-card-header>
         <ion-card-content>
+          <ion-button (click)="sendMessage()" expand="block">推荐生成</ion-button>
           <ion-list>
-            <ion-item *ngFor="let movie of recommendedMovies">
-              <ion-thumbnail slot="start">
+            <ion-item *ngFor="let film of filmList">
+              <!-- <ion-thumbnail slot="start">
                 <img [src]="movie.coverImage" alt="{{ movie.title }} 封面">
-              </ion-thumbnail>
+              </ion-thumbnail> -->
               <ion-label>
-                <h2>{{ movie.title }}</h2>
-                <p>评分: {{ movie.rating }}</p>
-                <p>{{ movie.description }}</p>
+                <h2>{{ film.get('title') }}</h2>
+                <p>题材: {{ film.get('genre') }}</p>
+                <p>评分: {{ film.get('grade') }}</p>
+                <p>{{ film.get('desc') }}</p>
               </ion-label>
             </ion-item>
           </ion-list>

+ 144 - 20
FilmDraw-app/src/app/tab2/tab2.page.ts

@@ -7,9 +7,14 @@ import { IonHeader, IonToolbar, IonTitle, IonContent,
 import { ExploreContainerComponent } from '../explore-container/explore-container.component';
 import { CommonModule } from '@angular/common';
 import { Router } from '@angular/router';
-import { CloudObject, CloudUser } from 'src/lib/ncloud';
+import { CloudObject, CloudUser, CloudQuery } from 'src/lib/ncloud';
 import { openUserLoginModal } from 'src/lib/user/modal-user-login/modal-user-login.component';
+import { FmodeChatCompletion, MarkdownPreviewModule } from 'fmode-ng';
 
+interface DialogueItem {
+  role: string;
+  content: string;
+}
 @Component({
   selector: 'app-tab2',
   templateUrl: 'tab2.page.html',
@@ -42,24 +47,143 @@ export class Tab2Page {
     private modalCtrl:ModalController,
     private router: Router) {}
   
-  goToPage(){
-    this.router.navigate(['/tabs/AIimagery'])
-  }
-
-  recommendedMovies = [
-    {
-      title: '某某剧名1',
-      rating: '9.0',
-      description: '这是一部精彩的剧集,讲述了...',
-      coverImage: 'assets/movie1.jpg',
-    },
-    {
-      title: '某某剧名2',
-      rating: '8.5',
-      description: '这部剧集以其独特的视角吸引了观众...',
-      coverImage: 'assets/movie2.jpg',
-    },
-    // 其他推荐影视剧...
-  ];
+    filmList:Array<CloudObject> = []
+    async loadFilmList(){
+      let query = new CloudQuery("FilmRecommendation");
+      this.filmList = await query.find()
+    }
 
+    async ngOnInit() {
+      await this.ChatList();
+      this.loadFilmList()
+    }
+  
+    responseMsg: any = "";
+    isComplete: boolean = false; // 定义完成状态属性,用来标记是否补全完成
+    chatList: Array<CloudObject> = [];
+  
+    async ChatList() {
+      const currentUser = new CloudUser();
+      await currentUser.current(); // 确保用户信息已加载
+      const userId = currentUser.id; // 获取当前用户的 ObjectId
+  
+      let query = new CloudQuery("FilmChat");
+      query.equalTo("user", currentUser.toPointer()); // 只获取当前用户的记录
+  
+      this.chatList = await query.find();
+  
+      this.chatList.forEach(chat => {
+        const dialogueArray = chat.get('dialogue');
+        if (dialogueArray && dialogueArray.length > 0) {
+          const userIndex = dialogueArray.findIndex((item: DialogueItem) => item.role === 'user');
+          if (userIndex !== -1) {
+            dialogueArray.splice(userIndex, 1); // 移除第一条 user 内容
+          }
+        }
+      });
+    }
+    
+    sendMessage() {
+      console.log("create");
+    
+      let dialogues = this.chatList.map(chat => {
+        const dialogueArray = chat.get('dialogue');
+        return dialogueArray.map((item: DialogueItem) => `${item.role}: ${item.content}`).join('\n');
+      }).join('\n');
+    
+      let PromptTemplate = `
+      请根据以下的用户聊天记录生成该用户的影视剧推荐列表。
+    
+      ${dialogues}
+    
+      请生成推荐列表,包括剧名、题材、评分和描述。
+      严格按照下面的格式生成:
+      剧名:
+      题材:
+      评分:
+      描述:
+      `;
+    
+      let completion = new FmodeChatCompletion([
+        { role: "system", content: "" },
+        { role: "user", content: PromptTemplate }
+      ]);
+    
+      completion.sendCompletion().subscribe(async (message: any) => {
+        console.log(message.content);
+        this.responseMsg = message.content;
+    
+        if (message?.complete) {
+          this.isComplete = true;
+    
+          // 假设 message.content 是自然语言文本而不是 JSON
+          try {
+            // 这里假设 AI 返回的内容是以某种格式列出推荐
+            // 例如,"推荐1: 剧名1, 题材1, 评分1, 描述1\n推荐2: 剧名2, 题材2, 评分2, 描述2"
+            
+            const recommendations = this.parseRecommendations(message.content);
+            
+            // 获取当前用户的 ObjectId
+            const currentUser = new CloudUser();
+            await currentUser.current(); // 确保用户信息已加载
+    
+            // 遍历推荐列表并保存到 FilmRecommendation 表
+            for (const rec of recommendations) {
+              const recommendation = new CloudObject("FilmRecommendation");
+              recommendation.set({
+                user: currentUser.toPointer(), // 设置用户指针
+                title: rec.title,
+                genre: rec.genre,
+                grade: rec.grade,
+                desc: rec.desc
+              });
+    
+              try {
+                await recommendation.save(); // 保存推荐到数据库
+                console.log('推荐已保存:', recommendation);
+              } catch (error) {
+                console.error('保存推荐失败:', error);
+              }
+            }
+          } catch (error) {
+            console.error('解析推荐内容失败:', error);
+          }
+        }
+      });
+    }
+    
+    // 解析推荐内容的辅助方法
+    private parseRecommendations(content: string): Array<{ title: string, genre: string, grade: string, desc: string }> {
+    const recommendations: Array<{ title: string, genre: string, grade: string, desc: string }> = [];
+      
+      // 按照空行分割每条推荐
+      const blocks = content.split('\n\n');
+      for (const block of blocks) {
+        const lines = block.split('\n').map(line => line.trim()).filter(line => line.length > 0);
+        
+        if (lines.length >= 4) {
+          const titleLine = lines[0];
+          const genreLine = lines[1];
+          const gradeLine = lines[2];
+          const descLine = lines[3];
+    
+          // 提取信息并去掉前缀和冒号
+          const title = titleLine.replace(/.*?剧名:\s*《(.*?)》$/, '$1').trim(); // 提取剧名
+          const genre = genreLine.replace(/.*?题材:\s*/, '').trim(); // 提取题材
+          const grade = gradeLine.replace(/.*?评分:\s*/, '').trim(); // 提取评分
+          const desc = descLine.replace(/.*?描述:\s*/, '').trim(); // 提取描述
+    
+          recommendations.push({
+            title: title,
+            genre: genre,
+            grade: grade,
+            desc: desc
+          });
+        } else {
+          console.warn('推荐内容格式不正确:', block); // 打印格式不正确的块
+        }
+      }
+      
+      return recommendations;
+    }
 }