lzy 1 år sedan
förälder
incheckning
e8ad3d76cd

+ 4 - 1
FilmDraw-app/angular.json

@@ -126,7 +126,10 @@
     }
   },
   "cli": {
-    "schematicCollections": ["@ionic/angular-toolkit"]
+    "schematicCollections": [
+      "@ionic/angular-toolkit"
+    ],
+    "analytics": "354ce029-7007-4b17-9145-3b8dfa38ccf5"
   },
   "schematics": {
     "@ionic/angular-toolkit:component": {

+ 36 - 0
FilmDraw-app/src/app/page-airecommend/page-airecommend.component.html

@@ -0,0 +1,36 @@
+<ion-content>
+
+  <h1>AI智能推荐</h1>
+  
+  <h2>类型</h2>
+  <ion-input  [value]="type" (ionInput)="typeInput($event)"></ion-input>
+
+  <h2>风格</h2>
+  <ion-input  [value]="style" (ionInput)="styleInput($event)"></ion-input>
+
+  <h2>最近看过</h2>
+  <ion-input  [value]="last" (ionInput)="lastInput($event)"></ion-input>
+  
+  <h2>您的年龄段</h2>
+  <ion-input  [value]="age" (ionInput)="ageInput($event)"></ion-input>
+  
+  <h2>您的性别</h2>
+  <ion-input  [value]="sex" (ionInput)="sexInput($event)"></ion-input>
+  
+  <h2>故事情节偏好</h2>
+  <ion-textarea [value]="detail" (ionInput)="detailInput($event)" placeholder="剧情走向,男女主性格等" autoGrow="true"></ion-textarea>
+  
+  <!-- 按钮:执行消息生成函数 -->
+  <ion-button (click)="sendMessage()" expand="block">推荐生成</ion-button>
+  
+  <!-- 展示:返回消息内容 -->
+  <!-- 消息传输过程中,实时预览 -->
+  @if(!isComplete){
+    <div>{{responseMsg}}</div>
+  }
+  <!-- 消息传输完成后,实时预览Markdown格式 -->
+  @if(isComplete){
+    <fm-markdown-preview class="content-style" [content]="responseMsg"></fm-markdown-preview>
+  }
+  
+</ion-content>

+ 80 - 0
FilmDraw-app/src/app/page-airecommend/page-airecommend.component.scss

@@ -0,0 +1,80 @@
+/* 设置页面的背景颜色 */
+ion-content {
+    --background: #f0f8ff; /* 浅蓝色背景 */
+    padding: 16px; /* 内容内边距 */
+    font-family: 'Comic Sans MS', cursive, sans-serif; /* 可爱的字体 */
+    position: relative; /* 允许绝对定位的子元素 */
+  }
+  
+  h1 {
+    font-size: 30px; /* 标题字体大小 */
+    color: #d85144; /* 可爱的粉色 */
+    // margin-bottom: 12px; /* 标题底部间距 */
+    // text-align: left; /* 左对齐 */
+    // text-shadow: 1px 1px 2px rgba(255, 105, 180, 0.5); /* 文字阴影 */
+  }
+  
+  /* 标题样式 */
+  h2 {
+    font-size: 26px; /* 标题字体大小 */
+    color: #ff6f61; /* 可爱的粉色 */
+    margin-bottom: 12px; /* 标题底部间距 */
+    text-align: left; /* 左对齐 */
+    // text-shadow: 1px 1px 2px rgba(255, 105, 180, 0.5); /* 文字阴影 */
+  }
+  
+  /* 输入框和文本区域样式 */
+  ion-input,
+  ion-textarea {
+    background-color: #ffffff; /* 白色背景 */
+    border: 2px solid #ff6f61; /* 粗虚线边框,粉色 */
+    border-radius: 12px; /* 圆角 */
+    padding: 12px; /* 内边距 */
+    font-size: 16px; /* 字体大小 */
+    margin-bottom: 20px; /* 输入框底部间距 */
+    transition: border-color 0.3s ease; /* 动画效果 */
+  }
+  
+  /* 输入框聚焦时的样式 */
+  ion-input:focus,
+  ion-textarea:focus {
+    border-color: #007bff; /* 聚焦时的边框颜色,蓝色 */
+    // box-shadow: 0 0 10px rgba(0, 123, 255, 0.5); /* 聚焦时的阴影效果 */
+  }
+  
+  /* 按钮样式 */
+  ion-button {
+    background-color: #007bff; /* 按钮背景色,蓝色 */
+    color: white; /* 按钮字体颜色 */
+    border-radius: 20px; /* 按钮圆角 */
+    font-size: 18px; /* 按钮字体大小 */
+    transition: background-color 0.3s ease, transform 0.2s; /* 动画效果 */
+  }
+  
+  /* 按钮悬停样式 */
+  ion-button:hover {
+    background-color: #0056b3; /* 悬停时的按钮背景色,深蓝色 */
+    transform: scale(1.05); /* 悬停时放大按钮 */
+  }
+  
+  /* 消息展示区域样式 */
+  div {
+    background-color: #ffe4e1; /* 浅粉色背景 */
+    border-radius: 12px; /* 圆角 */
+    padding: 12px; /* 内边距 */
+    margin-top: 20px; /* 顶部间距 */
+    font-size: 16px; /* 字体大小 */
+    color: #333; /* 字体颜色 */
+    //border-left: 5px solid #ff6f61; /* 左侧边框,粉色 */
+    // box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */
+  }
+  
+  /* Markdown 预览样式 */
+  fm-markdown-preview {
+    background-color: #ffffff; /* 白色背景 */
+    border-radius: 12px; /* 圆角 */
+    padding: 12px; /* 内边距 */
+    margin-top: 20px; /* 顶部间距 */
+    // box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */
+    // border: 2px #ff6f61; /* 虚线边框,粉色 */
+  }

+ 22 - 0
FilmDraw-app/src/app/page-airecommend/page-airecommend.component.spec.ts

@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+
+import { PageAirecommendComponent } from './page-airecommend.component';
+
+describe('PageAirecommendComponent', () => {
+  let component: PageAirecommendComponent;
+  let fixture: ComponentFixture<PageAirecommendComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      imports: [PageAirecommendComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(PageAirecommendComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 86 - 0
FilmDraw-app/src/app/page-airecommend/page-airecommend.component.ts

@@ -0,0 +1,86 @@
+import { Component, OnInit } from '@angular/core';
+import { IonHeader, IonToolbar, IonTitle, IonContent, IonButton, IonTextarea, IonInput } from '@ionic/angular/standalone';
+/** 引用:从fmode-ng库引用FmodeChatCompletion类 */
+import { FmodeChatCompletion,MarkdownPreviewModule } from 'fmode-ng';
+
+@Component({
+  selector: 'app-page-airecommend',
+  templateUrl: './page-airecommend.component.html',
+  styleUrls: ['./page-airecommend.component.scss'],
+  standalone: true,
+  imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonButton,IonTextarea,IonInput,
+    // 引入fm-markdown-preview组件模块
+    MarkdownPreviewModule
+  ],
+})
+export class PageAirecommendComponent  implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {}
+
+  // 用户输入提示词
+  type:string = "电视剧"
+  typeInput(ev:any){
+    this.type = ev.detail.value;
+  }
+   // 用户输入提示词
+   style:string = "古装"
+   styleInput(ev:any){
+     this.style = ev.detail.value;
+   }
+   // 用户输入提示词
+   last:string = "大梦归离"
+   lastInput(ev:any){
+     this.last = ev.detail.value;
+   }
+   // 用户输入提示词
+   age:string = "20-25"
+   ageInput(ev:any){
+     this.age = ev.detail.value;
+   }
+   // 用户输入提示词
+   sex:string = "女"
+   sexInput(ev:any){
+     this.sex = ev.detail.value;
+   }
+  // 用户输入提示词
+  detail:string = "请描述您期望的故事情节"
+  detailInput(ev:any){
+    this.detail = ev.detail.value;
+  }
+  // 属性:组件内用于展示消息内容的变量
+  responseMsg:any = ""
+  // 方法:实例化completion对象,传入消息数组,并订阅生成的可观察对象。
+  isComplete:boolean = false; // 定义完成状态属性,用来标记是否补全完成
+  sendMessage(){
+    console.log("create")
+
+    let PromptTemplate = `
+    请根据以下用户描述生成推荐的影视剧作品列表。用户的偏好和兴趣如下:
+
+    1. 用户喜欢的影视类型(如:电影、电视剧):${this.type}
+    1. 用户喜欢的影视风格(如:动作、喜剧、爱情、科幻、悬疑等):${this.style}
+    3. 用户对故事情节的偏好(如:喜欢紧张刺激的情节,或者温馨感人的故事):${this.detail}
+    4. 用户的观看历史(例如:最近观看过的影视剧):${this.last}
+    5. 用户的性别:${this.sex}
+    6. 用户的年龄段:${this.age}
+    
+    请根据以上信息,生成一份推荐的影视剧作品列表,包括每部作品的标题、类型、评分、简短描述和封面图像链接。
+    `
+    
+    let completion = new FmodeChatCompletion([
+      {role:"system",content:""},
+      {role:"user",content:PromptTemplate}
+    ])
+    completion.sendCompletion().subscribe((message:any)=>{
+      // 打印消息体
+      console.log(message.content)
+      // 赋值消息内容给组件内属性
+      this.responseMsg = message.content
+      if(message?.complete){ // 判断message为完成状态,则设置isComplete为完成
+        this.isComplete = true
+      }
+    })
+  }
+}

+ 8 - 6
FilmDraw-app/src/app/tab1/tab1.page.html

@@ -1,11 +1,13 @@
 <ion-header [translucent]="true">
   <ion-toolbar>
-    <ion-title size="large">圈子</ion-title>
-    <ion-buttons slot="end">
-      
-        <ion-searchbar show-clear-button="always" value="Always Show"></ion-searchbar>
-      
-    </ion-buttons>
+    <ion-item lines="none">
+      <!-- 图片 -->
+        <ion-avatar slot="start" class="image-container">
+            <img src="/assets/img/1.png" alt="Your Image" class="header-image">
+      </ion-avatar>
+      <!-- 搜索框 -->
+      <ion-searchbar slot="end" expand="with-icon"></ion-searchbar>
+    </ion-item>
   </ion-toolbar>
 </ion-header>
 

+ 7 - 0
FilmDraw-app/src/app/tab1/tab1.page.scss

@@ -11,6 +11,13 @@ ion-title {
   margin-top: 5px;
 }
 
+/* 设置搜索框的样式 */
+   ion-searchbar {
+     padding: 10px; /* 内边距 */
+     border-radius: 4px; /* 圆角 */
+     font-size: 16px; /* 字体大小 */
+    }
+
 ion-buttons {
   margin-right: 16px; // 右侧边距,可以根据需要调整
   margin-top: 10px; // 设置按钮与上方内容的间距

+ 9 - 2
FilmDraw-app/src/app/tab1/tab1.page.ts

@@ -2,7 +2,7 @@ import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
 import { 
   IonHeader, IonToolbar, IonTitle, IonContent, 
   IonButton, IonButtons, IonIcon, IonCard, IonCardHeader, IonCardTitle, IonCardContent,
-  IonItem, IonLabel, IonList, IonInput, IonTextarea, IonAvatar  } from '@ionic/angular/standalone';
+  IonItem, IonLabel, IonList, IonInput, IonTextarea, IonAvatar, IonSearchbar} from '@ionic/angular/standalone';
 import { ExploreContainerComponent } from '../explore-container/explore-container.component';
 import { CommonModule } from '@angular/common';
 
@@ -18,11 +18,18 @@ import { CommonModule } from '@angular/common';
     IonButton, IonButtons, IonIcon, 
 
     IonCard, IonCardHeader, IonCardTitle, IonCardContent,
-    IonList, IonItem, IonLabel, IonAvatar, IonInput, IonTextarea,
+    IonList, IonItem, IonLabel, IonAvatar, IonInput, IonTextarea,IonSearchbar
   ],
   schemas: [CUSTOM_ELEMENTS_SCHEMA], 
 })
 export class Tab1Page {
+  
+  onSearch(event: any) {
+        const searchTerm = event.target.value; // 获取用户输入的搜索内容
+        console.log('搜索内容:', searchTerm);
+        // 在这里添加搜索逻辑,例如过滤列表或导航到搜索结果页面
+      }
+  
   topics = [
     { title: '年度最佳剧集', participants: 120, popularity: '⭐⭐⭐⭐⭐' },
     { title: '经典电影回顾', participants: 80, popularity: '⭐⭐⭐⭐' },

+ 2 - 2
FilmDraw-app/src/app/tab2/tab2.page.html

@@ -40,8 +40,8 @@
           <ion-card-title>AI智能推荐</ion-card-title>
         </ion-card-header>
         <ion-card-content>
-          <ion-button expand="full" routerLink="/recommend">
-            <ion-icon slot="start" name="bulb-outline"></ion-icon>
+          <ion-button expand="full" color="primary" size="large" (click)="goToPage()">
+            <!-- <ion-icon slot="start" name="bulb-outline"></ion-icon> -->
             AI推荐
           </ion-button>
         </ion-card-content>

+ 8 - 0
FilmDraw-app/src/app/tab2/tab2.page.ts

@@ -5,6 +5,7 @@ import { IonHeader, IonToolbar, IonTitle, IonContent,
   IonIcon, IonButton} from '@ionic/angular/standalone';
 import { ExploreContainerComponent } from '../explore-container/explore-container.component';
 import { CommonModule } from '@angular/common';
+import { Router } from '@angular/router';
 
 @Component({
   selector: 'app-tab2',
@@ -24,6 +25,13 @@ export class Tab2Page {
   username: string = '用户A'; // 用户名
   userTags: string[] = ['喜剧迷', '动作片爱好者']; // 用户个性化标签
   
+  constructor(private router: Router) {}
+  
+  goToPage(){
+    this.router.navigate(['/tabs/airecommend'])
+  }
+
+
   recommendedMovies = [
     {
       title: '某某剧名1',

+ 5 - 0
FilmDraw-app/src/app/tabs/tabs.routes.ts

@@ -26,6 +26,11 @@ export const routes: Routes = [
         loadComponent: () =>
           import('../tab4/tab4.page').then((m) => m.Tab4Page),
       },
+      {
+        path: 'airecommend',
+        loadComponent: () =>
+          import('../page-airecommend/page-airecommend.component').then((m) => m.PageAirecommendComponent),
+      },
       {
         path: '',
         redirectTo: '/tabs/tab1',

BIN
FilmDraw-app/src/assets/img/1.png