Sfoglia il codice sorgente

page2的功能完善

何何何 1 anno fa
parent
commit
6eda210da8

+ 17 - 4
paint-app/src/app/page-idea/page-idea.component.html

@@ -1,21 +1,34 @@
 <ion-content>
 
-  <h1>科室</h1>
+  <!-- <h1>科室</h1>
   <ion-input  [value]="keshi" (ionInput)="keshiInput($event)"></ion-input>
 
-  <!-- 文本域:生成提示词 -->
   <h1>症状的描述</h1>
   <ion-textarea [value]="userPrompt" (ionInput)="promptInput($event)" placeholder="文本提示词" autoGrow="true"></ion-textarea>
   
-  <!-- 按钮:执行消息生成函数 -->
   <ion-button (click)="sendMessage()" expand="block">初步诊断</ion-button>
+
+  @if(!isComplete){
+    <div>{{responseMsg}}</div>
+  }
+  @if(isComplete){
+    <fm-markdown-preview class="content-style" [content]="responseMsg"></fm-markdown-preview>
+  } -->
+
+  <h1>绘画风格</h1>
+  <ion-input [value]="artStyle" (ionInput)="artStyleInput($event)"></ion-input>
   
+  <!-- 文本域:生成提示词 -->
+  <h1>绘画需求的描述</h1>
+  <ion-textarea [value]="userPrompt" (ionInput)="promptInput($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>
   }

+ 113 - 38
paint-app/src/app/page-idea/page-idea.component.ts

@@ -2,6 +2,7 @@ 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';
+import { ChangeDetectorRef } from '@angular/core'
 
 @Component({
   selector: 'page-idea',
@@ -14,44 +15,118 @@ import { FmodeChatCompletion,MarkdownPreviewModule } from 'fmode-ng';
   ],
 })
 export class PageIdeaComponent  implements OnInit {
+  // constructor() {}
+  // ngOnInit() {}
+  
+  // // 用户输入提示词,初始值为"门诊"
+  // keshi: string = "门诊";
+  
+  // // 处理用户输入的科室信息
+  // keshiInput(ev: any) {
+  //   this.keshi = ev.detail.value; // 将用户输入的值赋给keshi属性
+  // }
+  
+  // // 用户输入提示词,初始值为"请描述您的症状"
+  // userPrompt: string = "请描述您的症状";
+  
+  // // 处理用户输入的症状描述
+  // promptInput(ev: any) {
+  //   this.userPrompt = ev.detail.value; // 将用户输入的值赋给userPrompt属性
+  // }
+  
+  // // 属性:组件内用于展示消息内容的变量
+  // responseMsg: any = "";
+  
+  // // 方法:实例化completion对象,传入消息数组,并订阅生成的可观察对象。
+  // isComplete: boolean = false; // 定义完成状态属性,用来标记是否补全完成
+  
+  // // 发送消息并生成诊断
+  // sendMessage() {
+  //   console.log("create"); // 打印创建消息的日志
+  
+  //   // 创建提示模板,包含用户输入的科室和症状描述
+  //   let PromptTemplate = `
+  //     您作为一名专业的${this.keshi}医生,请您根据用户描述的症状,给出初步的诊断,并给出一些建议。
+  //     以下是用户的口述:${this.userPrompt}
+  //   `;
+  
+  //   // 实例化FmodeChatCompletion对象,传入系统和用户的消息
+  //   let completion = new FmodeChatCompletion([
+  //     { role: "system", content: "" }, // 系统角色消息,内容为空
+  //     { role: "user", content: PromptTemplate } // 用户角色消息,内容为PromptTemplate
+  //   ]);
+  
+  //   // 发送消息并订阅响应
+  //   completion.sendCompletion().subscribe((message: any) => {
+  //     // 打印返回的消息内容
+  //     console.log(message.content);
+  //     // 将返回的消息内容赋值给组件内的responseMsg属性
+  //     this.responseMsg = message.content;
+      
+  //     // 判断消息是否完成,如果完成则设置isComplete为true
+  //     if (message?.complete) {
+  //       this.isComplete = true;
+  //     }
+  //   });
+  // }
+constructor(private cdr: ChangeDetectorRef) {} // 注入 ChangeDetectorRef
+ngOnInit() {}
 
-  constructor() {}
-  ngOnInit(){}
-  // 用户输入提示词
-  keshi:string = "门诊"
-  keshiInput(ev:any){
-    this.keshi = ev.detail.value;
-  }
-  // 用户输入提示词
-  userPrompt:string = "请描述您的症状"
-  promptInput(ev:any){
-    this.userPrompt = ev.detail.value;
-  }
-  // 属性:组件内用于展示消息内容的变量
-  responseMsg:any = ""
-  // 方法:实例化completion对象,传入消息数组,并订阅生成的可观察对象。
-  isComplete:boolean = false; // 定义完成状态属性,用来标记是否补全完成
-  sendMessage(){
-    console.log("create")
-
-    let PromptTemplate = `
-    您作为一名专业的${this.keshi}医生,请您根据用户描述的症状,给出初步的诊断,并给出一些建议。
-    以下是用户的口述:${this.userPrompt}
-    `
-
-    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
-      }
-    })
-  }
+// 用户输入提示词,初始值为"素描"
+artStyle: string = "素描"; // 用户选择的绘画风格
 
+// 处理用户输入的绘画风格信息
+artStyleInput(ev: any) {
+  this.artStyle = ev.detail.value; // 将用户输入的值赋给artStyle属性
+}
+
+// 用户输入提示词,初始值为"请描述您的绘画需求"
+userPrompt: string = "请描述您的绘画需求"; // 用户描述绘画需求的提示信息
+
+// 处理用户输入的绘画需求描述
+promptInput(ev: any) {
+  this.userPrompt = ev.detail.value; // 将用户输入的值赋给userPrompt属性
+}
+
+// 属性:组件内用于展示绘画建议内容的变量
+responseMsg: any = "";
+
+// 方法:实例化completion对象,传入消息数组,并订阅生成的可观察对象。
+isComplete: boolean = false; // 定义完成状态属性,用来标记是否补全完成
+
+// 发送消息并生成绘画建议
+sendMessage() {
+  console.log("create"); // 打印创建消息的日志
+
+  this.responseMsg = ""; // 在生成新的文本之前清空之前的文本
+  // 创建提示模板,包含用户输入的绘画风格和需求描述
+  let PromptTemplate = `
+    您作为一名专业的绘画老师,请您根据用户描述的绘画需求,给出一些绘画建议。
+    以下是用户的描述:${this.userPrompt}
+    用户选择的绘画风格是:${this.artStyle}
+  `;
+
+  // 实例化FmodeChatCompletion对象,传入系统和用户的消息
+  let completion = new FmodeChatCompletion([
+    { role: "system", content: "" }, // 系统角色消息,内容为空
+    { role: "user", content: PromptTemplate } // 用户角色消息,内容为PromptTemplate
+  ]);
+
+  // 发送消息并订阅响应
+  completion.sendCompletion().subscribe((message: any) => {
+    // 打印返回的消息内容
+    console.log(message.content);
+    // 将返回的消息内容赋值给组件内的responseMsg属性
+    this.responseMsg = message.content;
+
+    this.cdr.detectChanges();
+    // 判断消息是否完成,如果完成则设置isComplete为true
+    if (message?.complete) {
+      this.isComplete = true;
+    }
+  });
+}
+overrideText() {
+  this.responseMsg = "这是覆盖后的新文本"; // 设置为新的文本
+}
 }

+ 35 - 5
paint-app/src/app/picture/picture.component.html

@@ -7,20 +7,19 @@
 </ion-header>
 
 <ion-content [fullscreen]="true">
-  <!-- 生成提示词 -->
-  <ion-textarea [value]="userPrompt" (ionInput)="promptInput($event)" placeholder="古诗文填写" autoGrow="true"></ion-textarea>
+
+  <!-- <ion-textarea [value]="userPrompt" (ionInput)="promptInput($event)" placeholder="古诗文填写" autoGrow="true"></ion-textarea>
   <ion-button (click)="createImage()" expand="block">生成意境</ion-button>
-  <!-- 意境画面提示词 -->
   <div>
     {{PictureDescResult}}
   </div>
-  <!-- 生成结果 -->
+
   @if(images.length) {
     @for(imageUrl of images;track imageUrl){
       <img [src]="imageUrl" alt="" srcset="">
     }
   }
-  <!-- 生成状态 -->
+
   @if(!images.length){
     @if(imagineWork){
       <h1>生成中</h1>
@@ -28,6 +27,37 @@
     @if(!imagineWork){
       <h1>未开始</h1>
     }
+  } -->
+<!-- 生成提示词 -->
+<ion-item>
+  <ion-textarea 
+    [value]="userPrompt" 
+    (ionInput)="promptInput($event)" 
+    placeholder="在这里输入您的绘画想法" 
+    autoGrow="true">
+  </ion-textarea>
+</ion-item>
+
+<ion-button (click)="createImage()" expand="block">生成意境</ion-button>
+
+<!-- 意境画面提示词 -->
+<div>
+  <h2>画面描述:</h2>
+  <p>{{ PictureDescResult }}</p>
+</div>
+
+@if(images.length) {
+  @for(imageUrl of images;track imageUrl){
+    <img [src]="imageUrl" alt="" srcset="">
   }
+}
 
+@if(!images.length){
+  @if(imagineWork){
+    <h1>生成中</h1>
+  }
+  @if(!imagineWork){
+    <h1>未开始</h1>
+  }
+}
 </ion-content>

+ 98 - 40
paint-app/src/app/picture/picture.component.ts

@@ -1,5 +1,5 @@
 import { Component, OnInit } from '@angular/core';
-import { IonHeader, IonToolbar, IonTitle, IonContent } from '@ionic/angular/standalone';
+import { IonHeader, IonToolbar, IonTitle, IonContent, IonItem } from '@ionic/angular/standalone';
 import { IonTextarea, IonButton,IonInput } from "@ionic/angular/standalone";
 import { DalleOptions, ImagineWork, FmodeChatCompletion } from 'fmode-ng';
 
@@ -12,59 +12,117 @@ import { DalleOptions, ImagineWork, FmodeChatCompletion } from 'fmode-ng';
     IonHeader, IonToolbar, IonTitle, IonContent, 
     IonButton,
     IonInput,
-    IonTextarea
+    IonTextarea,IonItem
   ],
 })
 export class PictureComponent  implements OnInit {
  
-  userPrompt:string = "犬吠水声中,桃花带露浓。\n树深时见鹿,溪午不闻钟。"
-  promptInput(ev:any){
-    this.userPrompt = ev.detail.value;
+  // userPrompt:string = "犬吠水声中,桃花带露浓。\n树深时见鹿,溪午不闻钟。"
+  // promptInput(ev:any){
+  //   this.userPrompt = ev.detail.value;
+  // }
+  // imagineWork:ImagineWork|undefined
+  // images:Array<string> = []
+  // constructor(
+  // ){
+  //   // 示例任务,自己生成图片后请存储新的ID
+  //   this.imagineWork = new ImagineWork("");
+  //   this.imagineWork.fetchTask().then(work=>{
+  //     this.images = this.imagineWork?.images || [];
+  //   })
+  // }
+
+  // PictureDescResult:string = `` // 画面描述结果
+  // async createImage(){
+  //   this.imagineWork = new ImagineWork();
+  //   // 文本生成
+  //   let PromptTemplate = `您是一名专业的美术画家,请您根据古诗文的内容,将其描述的画面、场景、人物、物品等用最简短的语言表达,直接写出画面,并且以中国的古风意境为主
+  //   诗文如下:
+  //   ${this.userPrompt}
+  //   `
+  //   let completion = new FmodeChatCompletion([
+  //     {role:"system",content:""},
+  //     {role:"user",content:PromptTemplate}
+  //   ])
+  //   completion.sendCompletion().subscribe((message:any)=>{
+  //     // 打印消息体
+  //     console.log(message.content)
+  //     // 赋值消息内容给组件内属性
+  //     this.PictureDescResult = message.content
+  //     if(message?.complete){ // 判断message为完成状态,则设置isComplete为完成
+  //       // 图片生成
+  //       let PicturePrompt = `${this.PictureDescResult}\n风格:中国古风。画面不带任何文字。突出色彩。`
+  //       let options:DalleOptions = {prompt:PicturePrompt}
+  //       this.imagineWork?.draw(options).subscribe(work=>{
+  //           console.log("imagineWork",work?.toJSON())
+  //           console.log("images",work?.get("images"))
+  //           if(work?.get("images")?.length){
+  //             this.images = work?.get("images");
+  //           }
+  //       })
+  //     }
+  //   })
+
+    
+  // }
+  // ngOnInit() {}
+  userPrompt: string = "请描述您的绘画想法"; // 用户输入的绘画想法
+  promptInput(ev: any) {
+    this.userPrompt = ev.detail.value; // 更新用户输入的绘画想法
   }
-  imagineWork:ImagineWork|undefined
-  images:Array<string> = []
-  constructor(
-  ){
-    // 示例任务,自己生成图片后请存储新的ID
+  
+  imagineWork: ImagineWork | undefined; // 用于处理图像生成的实例
+  images: Array<string> = []; // 存储生成的图像数组
+  
+  constructor() {
+    // 初始化ImagineWork实例并获取初始任务
     this.imagineWork = new ImagineWork("");
-    this.imagineWork.fetchTask().then(work=>{
-      this.images = this.imagineWork?.images || [];
-    })
+    this.imagineWork.fetchTask().then(work => {
+      this.images = this.imagineWork?.images || []; // 获取已有图像
+    });
   }
-
-  PictureDescResult:string = `` // 画面描述结果
-  async createImage(){
-    this.imagineWork = new ImagineWork();
+  
+  PictureDescResult: string = ""; // 存储画面描述结果
+  
+  async createImage() {
+    this.imagineWork = new ImagineWork(); // 创建新的ImagineWork实例
     // 文本生成
-    let PromptTemplate = `您是一名专业的美术画家,请您根据古诗文的内容,将其描述的画面、场景、人物、物品等用最简短的语言表达,直接写出画面,并且以中国的古风意境为主
-    诗文如下:
+    let PromptTemplate = `您是一名专业的美术画家,请您根据用户的绘画想法,将其描述的画面、场景、人物、物品等用最简短的语言表达,直接写出画面,并且以中国的古风意境为主
+    用户的绘画想法如下:
     ${this.userPrompt}
-    `
+    `;
+  
     let completion = new FmodeChatCompletion([
-      {role:"system",content:""},
-      {role:"user",content:PromptTemplate}
-    ])
-    completion.sendCompletion().subscribe((message:any)=>{
+      { role: "system", content: "" },
+      { role: "user", content: PromptTemplate }
+    ]);
+  
+    // 发送请求并处理响应
+    completion.sendCompletion().subscribe((message: any) => {
       // 打印消息体
-      console.log(message.content)
+      console.log(message.content);
       // 赋值消息内容给组件内属性
-      this.PictureDescResult = message.content
-      if(message?.complete){ // 判断message为完成状态,则设置isComplete为完成
+      this.PictureDescResult = message.content;
+      
+      // 判断消息是否完成
+      if (message?.complete) {
         // 图片生成
-        let PicturePrompt = `${this.PictureDescResult}\n风格:中国古风。画面不带任何文字。突出色彩。`
-        let options:DalleOptions = {prompt:PicturePrompt}
-        this.imagineWork?.draw(options).subscribe(work=>{
-            console.log("imagineWork",work?.toJSON())
-            console.log("images",work?.get("images"))
-            if(work?.get("images")?.length){
-              this.images = work?.get("images");
-            }
-        })
+        let PicturePrompt = `${this.PictureDescResult}\n风格:中国古风。画面不带任何文字。突出色彩。`;
+        let options: DalleOptions = { prompt: PicturePrompt };
+        
+        // 生成图像
+        this.imagineWork?.draw(options).subscribe(work => {
+          console.log("imagineWork", work?.toJSON());
+          console.log("images", work?.get("images"));
+          
+          // 更新生成的图像
+          if (work?.get("images")?.length) {
+            this.images = work?.get("images");
+          }
+        });
       }
-    })
-
-    
+    });
   }
+  
   ngOnInit() {}
-
 }

+ 1 - 1
paint-app/src/app/tab1/tab1.page.ts

@@ -35,7 +35,7 @@ export class Tab1Page {
     this.router.navigate(['/tabs/test'])
   }
   goTestPage1(){
-    this.router.navigate(['/tabs/idea'])
+    this.router.navigate(['/tabs/page-idea'])
   }
   goTestPage2(){
     this.router.navigate(['/tabs/picture'])

+ 66 - 8
paint-app/src/app/tab2/tab2.page.html

@@ -9,18 +9,36 @@
 <ion-content [fullscreen]="true">
   <ion-segment>
     <ion-segment-button value="first" content-id="first">
-      <ion-label>外国名画</ion-label>
+      <ion-label>绘画素材</ion-label>
     </ion-segment-button>
     <ion-segment-button value="second" content-id="second">
-      <ion-label>名家作品</ion-label>
-    </ion-segment-button>
-    <ion-segment-button value="third" content-id="third">
       <ion-label>视频教学</ion-label>
     </ion-segment-button>
   </ion-segment>
   <ion-segment-view>
     <ion-segment-content id="first">
 
+      <div class="tradSearch">
+        <dl class="srhGroup clear">
+            <dt>历史</dt>
+            <dd class="horizontal-links">
+              <p (click)="onTextClick(this.value0)">全部</p>&nbsp;&nbsp;&nbsp;
+              <p (click)="onTextClick(this.value1)">现代艺术</p>&nbsp;&nbsp;&nbsp;
+              <p (click)="onTextClick(this.value2)">当代艺术</p>
+            </dd>
+        </dl>
+        <dl class="srhGroup clear">
+            <dt>类型</dt>
+            <dd class="horizontal-links">
+              <p (click)="onTextClick1(this.value0)">全部</p>&nbsp;&nbsp;&nbsp;
+              <p (click)="onTextClick1(this.value3)">油画</p>&nbsp;&nbsp;&nbsp;
+              <p (click)="onTextClick1(this.value4)">壁画</p>
+            </dd>
+        </dl>
+     
+    </div>
+
+      
       <div class="image-container">
         <div class="container">
           <div *ngFor="let paint of paintList" class="image-wrapper" (click)="navigateToDetail()">
@@ -34,11 +52,51 @@
     </div>
     </ion-segment-content>
     <ion-segment-content id="second">
-     
-    </ion-segment-content>
-    <ion-segment-content id="third">
-      
+      <div class="page2-container">  
+        <main>  
+            <section class="page2-rankings"> 
+                <div class="page2-program" style="display: flex; align-items: center; position: relative;">
+                    <img src="../../assets/icon/tou1.jpg" alt="戏宇宙 第3季" style="width: 179px; height: 185px; margin-right: 20px;">
+                    <div class="page2-text1">
+                        <p class="page2-text">2024年11月20日 · 七天就能从小白到大佬!少走99%的弯路!存下吧!很难找全的!共计99条视频,包括:萌新必看零基础绘画教程、【procreate大纲】大纲介绍、【软件使用】软件首页等,UP主更多精彩视频,请关 …</p>  
+                        <p style="font-size: 12px; color: #999;">评分: 9.8分</p>  
+                        <p style="font-size: 12px; color: #999;">类型: 综艺·文化</p>   
+                        <button class="page2-watch-button" style="position: absolute; bottom: 0; right: 0;">看正片</button>    
+                    </div>
+                </div>
+                <div class="page2-program" style="display: flex; align-items: center; position: relative;">
+                    <img src="../../assets/icon/tou1.jpg" alt="戏宇宙 第3季" style="width: 179px; height: 185px; margin-right: 20px;">
+                    <div class="page2-text1">
+                        <p class="page2-text">2024年11月20日 · 七天就能从小白到大佬!少走99%的弯路!存下吧!很难找全的!共计99条视频,包括:萌新必看零基础绘画教程、【procreate大纲】大纲介绍、【软件使用】软件首页等,UP主更多精彩视频,请关 …</p>  
+                        <p style="font-size: 12px; color: #999;">评分: 9.8分</p>  
+                        <p style="font-size: 12px; color: #999;">类型: 综艺·文化</p>   
+                        <button class="page2-watch-button" style="position: absolute; bottom: 0; right: 0;">看正片</button>    
+                    </div>
+                </div>
+                <div class="page2-program" style="display: flex; align-items: center; position: relative;">
+                    <img src="../../assets/icon/tou1.jpg" alt="戏宇宙 第3季" style="width: 179px; height: 185px; margin-right: 20px;">
+                    <div class="page2-text1">
+                        <p class="page2-text">2024年11月20日 · 七天就能从小白到大佬!少走99%的弯路!存下吧!很难找全的!共计99条视频,包括:萌新必看零基础绘画教程、【procreate大纲】大纲介绍、【软件使用】软件首页等,UP主更多精彩视频,请关 …</p>  
+                        <p style="font-size: 12px; color: #999;">评分: 9.8分</p>  
+                        <p style="font-size: 12px; color: #999;">类型: 综艺·文化</p>   
+                        <button class="page2-watch-button" style="position: absolute; bottom: 0; right: 0;">看正片</button>    
+                    </div>
+                </div>
+                <div class="page2-program" style="display: flex; align-items: center; position: relative;">
+                    <img src="../../assets/icon/tou1.jpg" alt="戏宇宙 第3季" style="width: 179px; height: 185px; margin-right: 20px;">
+                    <div class="page2-text1">
+                        <p class="page2-text">2024年11月20日 · 七天就能从小白到大佬!少走99%的弯路!存下吧!很难找全的!共计99条视频,包括:萌新必看零基础绘画教程、【procreate大纲】大纲介绍、【软件使用】软件首页等,UP主更多精彩视频,请关 …</p>  
+                        <p style="font-size: 12px; color: #999;">评分: 9.8分</p>  
+                        <p style="font-size: 12px; color: #999;">类型: 综艺·文化</p>   
+                        <button class="page2-watch-button" style="position: absolute; bottom: 0; right: 0;">看正片</button>    
+                    </div>
+                </div>
+            </section>  
+        </main>  
+    </div>  
+
     </ion-segment-content>
+
   </ion-segment-view>
   <!-- <ion-card>
     <ion-card-header>

+ 137 - 4
paint-app/src/app/tab2/tab2.page.scss

@@ -5,13 +5,55 @@ ion-segment-button ion-label {
 // ion-segment-view {
 //   height: 150px;
 // }
-ion-segment-content:nth-of-type(2) {
-  background: lightblue;
+// ion-segment-content:nth-of-type(2) {
+//   background: lightblue;
+// }
+// ion-segment-content:nth-of-type(3) {
+//   background: lightgreen;
+// }
+/* 容器样式 */
+/* 容器样式 */
+.tradSearch {
+  max-width: 800px; /* 设置最大宽度 */
+  margin: 20px auto; /* 居中显示 */
+  background-color: #f9f9f9; /* 背景颜色 */
+  border-radius: 8px; /* 圆角 */
+  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 阴影效果 */
 }
-ion-segment-content:nth-of-type(3) {
-  background: lightgreen;
+
+/* 搜索组样式 */
+
+/* 每个搜索组的标题样式 */
+.srhGroup dt {
+  font-size: 1.2em; /* 字体大小 */
+  font-weight: bold; /* 加粗 */
+  margin-bottom: 10px; /* 下边距 */
+  color: #333; /* 颜色 */
 }
 
+/* 每个搜索项的样式 */
+.srhGroup dd {
+  margin: 5px 0; /* 上下边距 */
+}
+
+/* 横向链接样式 */
+.horizontal-links {
+  display: flex; /* 使用Flexbox布局 */
+  flex-wrap: wrap; /* 允许换行 */
+}
+
+.horizontal-links a {
+  margin-right: 10px; /* 链接之间的间距 */
+}
+
+/* 清除浮动 */
+.clear::after {
+  content: "";
+  display: table;
+  clear: both;
+}
+
+
 
 /* 容器的样式 */
 .image-container {
@@ -73,4 +115,95 @@ ion-segment-content:nth-of-type(3) {
 .text2 {
   font-size: 12px; /* 可根据需要调整字体大小 */
   color: #666; /* 设置颜色 */
+}
+
+.page2-container {
+    display: flex; /* 使用Flexbox布局 */
+    flex-wrap: wrap; /* 允许换行 */
+    justify-content: space-between; /* 在主轴上均匀分配空间 */
+}
+
+.page2-text1 {
+    overflow: hidden; /* 隐藏超出部分 */
+    white-space: nowrap; /* 不换行 */
+    text-overflow: ellipsis; /* 使用省略号表示超出部分 */
+    max-width: 100%; /* 最大宽度为100% */
+    font-size: 14px; /* 字体大小 */
+    margin: 0; /* 去掉默认外边距 */
+}
+
+.page2-text1 {
+    font-weight: bold; /* 加粗文本 */
+}
+
+.page2-text2 {
+    width: 90%; /* 每列宽度为50%,减去间距 */
+    overflow: hidden; /* 隐藏超出部分 */
+    white-space: nowrap; /* 不换行 */
+    text-overflow: ellipsis; /* 使用省略号表示超出部分 */
+    max-width: 100%; /* 最大宽度为100% */
+    font-size: 14px; /* 字体大小 */
+    margin: 0 auto; /* 去掉默认外边距 */
+}
+
+.page2-text2 {
+    font-size: 12px; /* 可根据需要调整字体大小 */
+    color: #666; /* 设置颜色 */
+}
+
+.page2-container {  
+    max-width: 800px;  
+    margin: 0 auto;  
+    padding: 20px;  
+}  
+main {  
+    margin-top: 20px;  
+}  
+
+.page2-rankings {  
+    background-color: #fff;  
+    border-radius: 8px;  
+    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);  
+    padding: 15px;  
+}  
+
+.page2-program { 
+    height: 185px; 
+    margin-bottom: 20px;  
+    padding: 15px;  
+    border-bottom: 1px solid #e0e0e0;  
+}  
+
+.page2-program:last-child {  
+    border-bottom: none;  
+}  
+
+p {  
+    margin-bottom: 5px;  
+}  
+
+.page2-watch-button {  
+    background-color: #4CAF50;  
+    color: white;  
+    border: none;  
+    padding: 10px 15px;  
+    border-radius: 5px;  
+    cursor: pointer;  
+    transition: background-color 0.3s;  
+}  
+
+.page2-watch-button:hover {  
+    background-color: #45a049;  
+}  
+
+.page2-text {
+    display: -webkit-box;
+    -webkit-line-clamp: 3;
+    -webkit-box-orient: vertical;
+    overflow: hidden;
+    white-space: normal;
+}
+
+.page2-text1 {
+    height: 185px;
 }

+ 24 - 2
paint-app/src/app/tab2/tab2.page.ts

@@ -15,8 +15,12 @@ import { CloudObject, CloudQuery } from 'src/lib/ncloud';
   ,IonSegment,IonSegmentContent,IonSegmentView,IonLabel,IonSegmentButton,CommonModule]
 })
 export class Tab2Page{
- 
-
+  value1: string = '现代艺术';
+  value2: string = '当代艺术';
+  value0: string='';
+  value3: string = '油画';
+  value4: string = '壁画';
+  nowvalue:string='';
    constructor(private router: Router){}
 
    navigateToDetail(){
@@ -35,4 +39,22 @@ export class Tab2Page{
       let query = new CloudQuery("paint");
       this.paintList = await query.find()
     }
+    async onTextClick(text:string){
+      let query = new CloudQuery("paint");
+      this.nowvalue=text;
+      if(text!==''){
+      await query.equalTo("history",text)
+    }
+      this.paintList = await query.find()
+    }
+    async onTextClick1(text:string){
+      let query = new CloudQuery("paint");
+      if(text!==''){
+      await query.equalTo("range",text)
+    }
+    if(this.nowvalue!==''){
+      await query.equalTo("history",this.nowvalue)
+    }
+      this.paintList = await query.find()
+    }
 }

+ 45 - 27
paint-app/src/app/test2-page/test2-page.component.html

@@ -1,27 +1,45 @@
-<!-- 用户登录状态 -->
-<ion-card>
-  <!-- 未登录 -->
-   @if(!currentUser?.id){
-     <ion-card-header>
-       <ion-card-title>请登录</ion-card-title>
-       <ion-card-subtitle>暂无信息</ion-card-subtitle>
-      </ion-card-header>
-    }
-      <!-- 未登录 -->
-   @if(currentUser?.id){
-    <ion-card-header>
-      <ion-card-title>{{currentUser?.get("username")}} {{currentUser?.get("realname")}}</ion-card-title>
-      <ion-card-subtitle>性别:{{currentUser?.get("gender")||"-"}} 年龄:{{currentUser?.get("age")||"-"}}</ion-card-subtitle>
-    </ion-card-header>
-    }
-    <ion-card-content>
-    @if(!currentUser?.id){
-      <ion-button expand="block" (click)="signup()">注册</ion-button>
-      <ion-button expand="block" (click)="login()">登录</ion-button>
-    }
-   @if(currentUser?.id){
-    <ion-button expand="block" (click)="editUser()">编辑资料</ion-button>
-    <ion-button expand="block" (click)="logout()" color="light">登出</ion-button>
-  }
-  </ion-card-content>
-</ion-card>
+<ion-content> 
+    <div class="container">  
+        <main>  
+            <section class="rankings"> 
+               
+              <div class="program" style="display: flex; align-items: center;position: relative;">
+                <img src="../../assets/icon/tou1.jpg" alt="戏宇宙 第3季" style="width: 179px; ; height: 185px; margin-right: 20px;">
+                <div class="text1">
+                    <p class="text">2024年11月20日 · 七天就能从小白到大佬!少走99%的弯路!存下吧!很难找全的!共计99条视频,包括:萌新必看零基础绘画教程、【procreate大纲】大纲介绍、【软件使用】软件首页等,UP主更多精彩视频,请关 …</p>  
+                    <p style="font-size: 12px; color: #999;">评分: 9.8分</p>  
+                    <p style="font-size: 12px; color: #999;">类型: 综艺·文化</p>   
+                    <button class="watch-button" style="position: absolute; bottom: 0; right: 0;">看正片</button>    
+                </div>
+              </div>
+              <div class="program" style="display: flex; align-items: center;position: relative;">
+                <img src="../../assets/icon/tou1.jpg" alt="戏宇宙 第3季" style="width: 179px; ; height: 185px; margin-right: 20px;">
+                <div class="text1">
+                    <p class="text">2024年11月20日 · 七天就能从小白到大佬!少走99%的弯路!存下吧!很难找全的!共计99条视频,包括:萌新必看零基础绘画教程、【procreate大纲】大纲介绍、【软件使用】软件首页等,UP主更多精彩视频,请关 …</p>  
+                    <p style="font-size: 12px; color: #999;">评分: 9.8分</p>  
+                    <p style="font-size: 12px; color: #999;">类型: 综艺·文化</p>   
+                    <button class="watch-button" style="position: absolute; bottom: 0; right: 0;">看正片</button>    
+                </div>
+              </div><div class="program" style="display: flex; align-items: center;position: relative;">
+                <img src="../../assets/icon/tou1.jpg" alt="戏宇宙 第3季" style="width: 179px; ; height: 185px; margin-right: 20px;">
+                <div class="text1">
+                    <p class="text">2024年11月20日 · 七天就能从小白到大佬!少走99%的弯路!存下吧!很难找全的!共计99条视频,包括:萌新必看零基础绘画教程、【procreate大纲】大纲介绍、【软件使用】软件首页等,UP主更多精彩视频,请关 …</p>  
+                    <p style="font-size: 12px; color: #999;">评分: 9.8分</p>  
+                    <p style="font-size: 12px; color: #999;">类型: 综艺·文化</p>   
+                    <button class="watch-button" style="position: absolute; bottom: 0; right: 0;">看正片</button>    
+                </div>
+              </div><div class="program" style="display: flex; align-items: center;position: relative;">
+                <img src="../../assets/icon/tou1.jpg" alt="戏宇宙 第3季" style="width: 179px; ; height: 185px; margin-right: 20px;">
+                <div class="text1">
+                    <p class="text">2024年11月20日 · 七天就能从小白到大佬!少走99%的弯路!存下吧!很难找全的!共计99条视频,包括:萌新必看零基础绘画教程、【procreate大纲】大纲介绍、【软件使用】软件首页等,UP主更多精彩视频,请关 …</p>  
+                    <p style="font-size: 12px; color: #999;">评分: 9.8分</p>  
+                    <p style="font-size: 12px; color: #999;">类型: 综艺·文化</p>   
+                    <button class="watch-button" style="position: absolute; bottom: 0; right: 0;">看正片</button>    
+                </div>
+              </div>
+            </section>  
+        </main>  
+    </div>  
+
+</ion-content>
+

+ 112 - 0
paint-app/src/app/test2-page/test2-page.component.scss

@@ -0,0 +1,112 @@
+* {  
+    margin: 0;  
+    padding: 0;  
+    box-sizing: border-box;  
+}  
+
+body {  
+    font-family: Arial, sans-serif;  
+    background-color: #f9f9f9;  
+    color: #333;  
+}  
+
+.container {  
+    max-width: 800px;  
+    margin: 0 auto;  
+    padding: 20px;  
+}  
+
+header {  
+    background-color: #4CAF50;  
+    color: white;  
+    padding: 15px;  
+    text-align: center;  
+}  
+
+nav ul {  
+    list-style-type: none;  
+}  
+
+nav ul li {  
+    display: inline;  
+    margin: 0 10px;  
+}  
+
+nav a {  
+    color: white;  
+    text-decoration: none;  
+}  
+
+nav a:hover {  
+    text-decoration: underline;  
+}  
+
+main {  
+    margin-top: 20px;  
+}  
+
+.rankings {  
+    background-color: #fff;  
+    border-radius: 8px;  
+    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);  
+    padding: 15px;  
+}  
+// .ima1{
+//     float: left;
+//     width: 120px;
+//     height: 100%;
+//     object-fit: cover; /* 保持照片比例 */  
+//     border-radius: 8px; /* 圆角 */  
+//     box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); /* 阴影 */
+// }
+.program { 
+    height: 185px; 
+    margin-bottom: 20px;  
+    padding: 15px;  
+    border-bottom: 1px solid #e0e0e0;  
+}  
+
+.program:last-child {  
+    border-bottom: none;  
+}  
+
+h2 {  
+    font-size: 1.5em;  
+    margin-bottom: 10px;  
+}  
+
+p {  
+    margin-bottom: 5px;  
+}  
+
+.watch-button {  
+    background-color: #4CAF50;  
+    color: white;  
+    border: none;  
+    padding: 10px 15px;  
+    border-radius: 5px;  
+    cursor: pointer;  
+    transition: background-color 0.3s;  
+}  
+
+.watch-button:hover {  
+    background-color: #45a049;  
+}  
+
+footer {  
+    text-align: center;  
+    margin-top: 20px;  
+    font-size: 0.8em;  
+    color: #777;  
+}
+.text{
+display: -webkit-box;
+-webkit-line-clamp: 3;
+-webkit-box-orient: vertical;
+overflow: hidden;
+white-space: normal;
+}
+
+.text1{
+  height: 185px;
+    }

+ 2 - 2
paint-app/src/app/test2-page/test2-page.component.ts

@@ -1,6 +1,6 @@
 import { Component } from '@angular/core';
 import { Router } from '@angular/router';
-import { IonHeader, IonToolbar, IonTitle, IonContent, IonCard, IonCardContent, IonButton, IonCardHeader, IonCardTitle, IonCardSubtitle, ModalController } from '@ionic/angular/standalone';
+import { IonHeader, IonToolbar, IonTitle, IonContent, IonCard, IonCardContent, IonButton, IonCardHeader, IonCardTitle, IonCardSubtitle, ModalController, IonImg } from '@ionic/angular/standalone';
 import { CloudUser } from 'src/lib/ncloud';
 import { openUserEditModal } from 'src/lib/user/modal-user-edit/modal-user-edit.component';
 import { openUserLoginModal } from 'src/lib/user/modal-user-login/modal-user-login.component';
@@ -11,7 +11,7 @@ import { openUserLoginModal } from 'src/lib/user/modal-user-login/modal-user-log
   styleUrls: ['./test2-page.component.scss'],
   standalone: true,
   imports: [IonHeader, IonToolbar, IonTitle, IonContent, 
-    IonCard,IonCardContent,IonButton,IonCardHeader,IonCardTitle,IonCardSubtitle
+    IonCard,IonCardContent,IonButton,IonCardHeader,IonCardTitle,IonCardSubtitle,IonImg
   ],
 })
 export class Test2PageComponent  {

+ 37 - 13
paint-app/src/lib/ncloud.ts

@@ -81,34 +81,49 @@ export class CloudObject {
 
 // CloudQuery.ts
 export class CloudQuery {
-    className: string;
-    whereOptions: Record<string, any> = {};
+    className: string; // 存储类名
+    whereOptions: Record<string, any> = {}; // 存储查询条件的对象,初始为空对象
 
+    // 构造函数,接受一个类名作为参数
     constructor(className: string) {
-        this.className = className;
+        this.className = className; // 初始化类名
     }
 
+    // 方法:添加大于条件
     greaterThan(key: string, value: any) {
+        // 如果该键不存在,则初始化为空对象
         if (!this.whereOptions[key]) this.whereOptions[key] = {};
+        // 设置大于条件
         this.whereOptions[key]["$gt"] = value;
     }
 
+    // 方法:添加大于等于条件
     greaterThanAndEqualTo(key: string, value: any) {
+        // 如果该键不存在,则初始化为空对象
         if (!this.whereOptions[key]) this.whereOptions[key] = {};
+        // 设置大于等于条件
         this.whereOptions[key]["$gte"] = value;
     }
 
+    // 方法:添加小于条件
     lessThan(key: string, value: any) {
+        // 如果该键不存在,则初始化为空对象
         if (!this.whereOptions[key]) this.whereOptions[key] = {};
+        // 设置小于条件
         this.whereOptions[key]["$lt"] = value;
     }
 
+    // 方法:添加小于等于条件
     lessThanAndEqualTo(key: string, value: any) {
+        // 如果该键不存在,则初始化为空对象
         if (!this.whereOptions[key]) this.whereOptions[key] = {};
+        // 设置小于等于条件
         this.whereOptions[key]["$lte"] = value;
     }
 
+    // 方法:添加等于条件
     equalTo(key: string, value: any) {
+        // 直接设置等于条件
         this.whereOptions[key] = value;
     }
 
@@ -131,30 +146,39 @@ export class CloudQuery {
     }
 
     async find() {
+        // 构建请求的基础 URL,包含类名
         let url = `http://dev.fmode.cn:1337/parse/classes/${this.className}?`;
-
+    
+        // 检查是否有查询条件,如果有,则将其序列化为 JSON 字符串
         if (Object.keys(this.whereOptions).length) {
             const whereStr = JSON.stringify(this.whereOptions);
+            // 将查询条件添加到 URL 中
             url += `where=${whereStr}`;
         }
-
+    
+        // 使用 fetch API 发送 GET 请求
         const response = await fetch(url, {
             headers: {
+                // 如果服务器返回的内容没有变化,则使用此请求头
                 "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
+                // 设置 Parse 应用的 ID
                 "x-parse-application-id": "dev"
             },
-            body: null,
-            method: "GET",
-            mode: "cors",
-            credentials: "omit"
+            body: null, // GET 请求不需要请求体
+            method: "GET", // 请求方法为 GET
+            mode: "cors", // 跨域请求模式
+            credentials: "omit" // 不携带凭据(如 Cookies)
         });
-
+    
+        // 解析响应为 JSON 格式
         const json = await response?.json();
-        let list = json?.results || []
-        let objList = list.map((item:any)=>this.dataToObj(item))
+        // 从结果中提取数据,默认为空数组
+        let list = json?.results || [];
+        // 将获取的原始数据转换为对象列表
+        let objList = list.map((item: any) => this.dataToObj(item));
+        // 返回转换后的对象列表,如果没有数据则返回空数组
         return objList || [];
     }
-
     async first() {
         let url = `http://dev.fmode.cn:1337/parse/classes/${this.className}?`;