Selaa lähdekoodia

完善了所有功能

何何何 1 vuosi sitten
vanhempi
commit
cbe2488710

+ 2 - 0
paint-app/src/app/app.routes.ts

@@ -1,8 +1,10 @@
 import { Routes } from '@angular/router';
+import { VideoPageComponent } from './video-page/video-page.component';
 
 export const routes: Routes = [
   {
     path: '',
     loadChildren: () => import('./tabs/tabs.routes').then((m) => m.routes),
   },
+  { path: 'tabs/video-page/:id', component: VideoPageComponent },
 ];

+ 40 - 7
paint-app/src/app/tab1/tab1.page.ts

@@ -4,10 +4,10 @@ import { ExploreContainerComponent } from '../explore-container/explore-containe
 import { EditRatingStarComponent } from '../edit-rating-star/edit-rating-star.component';
 import { Router } from '@angular/router';
 import { IonButton} from '@ionic/angular/standalone';
+import { AlertController } from '@ionic/angular/standalone'; 
 
-
-import { CloudObject, CloudQuery } from 'src/lib/ncloud';
-
+import { CloudObject, CloudQuery ,CloudUser} from 'src/lib/ncloud';
+import { ModalController } from '@ionic/angular/standalone';
 
 
 import { IonIcon, IonItem, IonLabel, IonList, IonListHeader, IonSkeletonText, IonThumbnail } from '@ionic/angular/standalone';
@@ -29,19 +29,52 @@ export class Tab1Page {
   // //星星打分
   // currentScore: number = 0; // 初始分值
 
-  constructor(private router: Router){}
+  constructor(private router: Router,private alertController: AlertController,
+    private modalCtrl:ModalController){}
 
   goTestPage(){
-    this.router.navigate(['/tabs/test'])
+     let currentUser = new CloudUser();
+    let userPrompt = ``
+    if(!currentUser?.id){
+      console.log("用户未登录,请登录后重试"); 
+       this.showAlert();
+    }else{
+     this.router.navigate(['/tabs/test'])
+    }
   }
   goTestPage1(){
-    this.router.navigate(['/tabs/page-idea'])
+    let currentUser = new CloudUser();
+    let userPrompt = ``
+    if(!currentUser?.id){
+      console.log("用户未登录,请登录后重试"); 
+       this.showAlert();
+    }else{
+     this.router.navigate(['/tabs/page-idea'])
+    }
+   
   }
   goTestPage2(){
-    this.router.navigate(['/tabs/picture'])
+    let currentUser = new CloudUser();
+    let userPrompt = ``
+    if(!currentUser?.id){
+      console.log("用户未登录,请登录后重试"); 
+       this.showAlert();
+    }else{
+      this.router.navigate(['/tabs/picture'])
+    }
+    
   }
   // handleScoreChange(newScore: number) {
   //   this.currentScore = newScore;
   //   console.log('新分值:', newScore); // 处理分值变化
   // }
+      async showAlert() {
+        const alert = await this.alertController.create({
+          header: '提示', // 提示框的标题
+          message: '请先登录以查看个人信息。', // 提示框的消息
+          buttons: ['确定'], // 按钮文本,用户点击后关闭提示框
+        });
+      
+        await alert.present(); // 显示提示框
+      }
 }

+ 23 - 32
paint-app/src/app/tab2/tab2.page.html

@@ -32,65 +32,53 @@
             <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.value5)">水彩画</p>&nbsp;&nbsp;&nbsp;
+              <p (click)="onTextClick1(this.value6)">抽象画</p>&nbsp;&nbsp;&nbsp;
+              <p (click)="onTextClick1(this.value7)">素描</p>&nbsp;&nbsp;&nbsp;
               <p (click)="onTextClick1(this.value4)">壁画</p>
             </dd>
         </dl>
      
     </div>
 
-      
+      <!-- (click)="navigateToDetail()" -->
       <div class="image-container">
         <div class="container">
-          <div *ngFor="let paint of paintList" class="image-wrapper" (click)="navigateToDetail()">
+          <div *ngFor="let paint of paintList" class="image-wrapper" >
               <img [src]="paint.get('picture')" [alt]="paint.get('name')" />
               <div class="description-box">
                   <div class="text1"><p>《{{ paint.get('name') }}》——{{ paint.get('artist') }}</p></div>
+                  <div class="text2"><p>{{ paint.get('history') }}——{{ paint.get('range') }}</p></div>
                   <div class="text2"><p>{{ paint.get('introduction') }}</p></div>
               </div>
           </div>
       </div>
     </div>
+
+
     </ion-segment-content>
     <ion-segment-content id="second">
       <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/v-picture/teach1.png" alt="戏宇宙 第3季" style="width: 179px; height: 185px; margin-right: 20px;">
+                <!-- <div class="page2-program" style="display: flex; align-items: center; position: relative;">
+                  <img src="../../assets/icon/v-picture/teach1.png" alt="戏宇宙 第3季" style="width: 179px; height: 185px; margin-right: 20px;">
                     <div class="page2-text1">
                         <p class="page2-text">2024年11月20日 · 七天就能从小白到大佬!少走99%的弯路!存下吧!很难找全的!共计99条视频,包括:萌新必看零基础绘画教程。</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/v-picture/teach2.png" alt="戏宇宙 第3季" style="width: 179px; height: 185px; margin-right: 20px;">
-                    <div class="page2-text1">
-                        <p class="page2-text">释放你的创造力,跟随我们的绘画教学视频,轻松掌握绘画技巧!无论你是初学者还是有经验的画家,我们的绘画课程都能帮助你提升艺术水平!</p>  
-                        <p style="font-size: 12px; color: #999;">评分: 9.0分</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/v-picture/teach3.png" alt="戏宇宙 第3季" style="width: 179px; height: 185px; margin-right: 20px;">
-                    <div class="page2-text1">
-                        <p class="page2-text">从基础到进阶,带你一步步探索绘画的魅力,开启你的艺术之旅!让每一笔都充满灵感,加入我们的绘画教学视频,创造属于你的艺术作品!</p>  
-                        <p style="font-size: 12px; color: #999;">评分: 8.9分</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/v-picture/teach4.png" alt="戏宇宙 第3季" style="width: 179px; height: 185px; margin-right: 20px;">
-                    <div class="page2-text1">
-                        <p class="page2-text">掌握绘画技巧,提升艺术修养,订阅我们的绘画教学视频,让创意飞扬!</p>  
-                        <p style="font-size: 12px; color: #999;">评分: 8.6分</p>  
-                        <p style="font-size: 12px; color: #999;">类型: 教育</p>   
-                        <button class="page2-watch-button" style="position: absolute; bottom: 0; right: 0;">看正片</button>    
+                        <button class="page2-watch-button" (click)="gopage()" style="position: absolute; bottom: 0; right: 0;">看正片</button>    
                     </div>
+                </div> -->
+                <div *ngFor="let video of videoList" class="page2-program" style="display: flex; align-items: center; position: relative;">
+                  <img [src]="video.get('url')" [alt]="video.get('name')" style="width: 179px; height: 185px; margin-right: 20px;"/>
+                  <div class="page2-text1">
+                    <p class="page2-text">{{video.get('introduce')}}</p>  
+                    <p style="font-size: 12px; color: #999;">评分: {{video.get('score')}}分</p>  
+                    <p style="font-size: 12px; color: #999;">类型: {{video.get('type')}}{{video.get('name')}}</p>   
+                    <button class="page2-watch-button" (click)="gopage(video.get('name'))" style="position: absolute; bottom: 0; right: 0;">看正片</button>    
                 </div>
+              </div>    
             </section>  
         </main>  
     </div>  
@@ -98,6 +86,9 @@
     </ion-segment-content>
 
   </ion-segment-view>
+
+
+
   <!-- <ion-card>
     <ion-card-header>
       <ion-card-title>油彩画 <ion-button>查看更多</ion-button></ion-card-title>

+ 2 - 2
paint-app/src/app/tab2/tab2.page.scss

@@ -62,7 +62,7 @@ ion-segment-button ion-label {
   gap: 20px;               /* 图片间距,可以根据需要调整 */
 }
 .image-wrapper {
-  width: 100%; /* 每列宽度为50%,减去间距 */
+  width: 50%; /* 每列宽度为50%,减去间距 */
   margin: 5px; /* 设置间距 */
   box-sizing: border-box; /* 包括内边距和边框在内的宽度计算 */
   display: flex; /* 使用Flexbox布局 */
@@ -99,7 +99,7 @@ ion-segment-button ion-label {
   margin: 0; /* 去掉默认外边距 */
 }
 .text2 {
-  width: 90%; /* 每列宽度为50%,减去间距 */
+  width: 50%; /* 每列宽度为50%,减去间距 */
   overflow: hidden; /* 隐藏超出部分 */
   white-space: nowrap; /* 不换行 */
   text-overflow: ellipsis; /* 使用省略号表示超出部分 */

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

@@ -20,25 +20,42 @@ export class Tab2Page{
   value0: string='';
   value3: string = '油画';
   value4: string = '壁画';
+  value5: string = '水彩画';
+  value6: string = '抽象画';
+  value7: string = '素描';
   nowvalue:string='';
-   constructor(private router: Router){}
+  constructor(private router: Router){}
 
    navigateToDetail(){
     this.router.navigate(['/tabs/detail-page'])
   }
-
+  gopage(objectId: string){
+    console.log('objectId:', objectId); // 调试输出
+    if (objectId) {
+      this.router.navigate(['/tabs/video-page', objectId]);
+    } else {
+      console.error('objectId is null or undefined');
+    }
+  }
   ngOnInit() {
       // 生命周期:页面加载后,运行医生列表加载函数
       this.loadpaintList()
+      this.loadvideoList()
     }
   
     // 创建用于数据列表存储的属性
     paintList:Array<CloudObject> = []
+    videoList:Array<CloudObject> = []
     
     async loadpaintList(){
       let query = new CloudQuery("paint");
       this.paintList = await query.find()
     }
+    async loadvideoList(){
+      let query = new CloudQuery("pvideo");
+      this.videoList = await query.find()
+    }
+
     async onTextClick(text:string){
       let query = new CloudQuery("paint");
       this.nowvalue=text;

+ 4 - 22
paint-app/src/app/tab3/tab3.page.html

@@ -130,26 +130,8 @@
     </div>
   </div>
 
-  <div style="margin-top: 60px;width: 100%;padding-left: 20px;"><p class="left-align">更多服务:</p></div>
-  <div class="icon-container">
-    <div class="icon-item">
-      <ion-icon name="folder-outline"></ion-icon>
-      <span>离线缓存</span>
-    </div>
-    <div class="icon-item">
-      <ion-icon name="time-outline"></ion-icon>
-      <span>历史记录</span>
-    </div>
-    <div class="icon-item">
-      <ion-icon name="star-outline"></ion-icon>
-      <span>我的收藏</span>
-    </div>
-    <div class="icon-item">
-      <ion-icon name="heart-outline"></ion-icon>
-      <span>我的喜欢</span>
-    </div>
-  </div>
-  <div class="icon-container">
+  <!-- <div style="margin-top: 60px;width: 100%;padding-left: 20px;"><p class="left-align">更多服务:</p></div> -->
+  <!-- <div class="icon-container">
     <div class="icon-item">
       <ion-icon name="folder-outline"></ion-icon>
       <span>离线缓存</span>
@@ -166,13 +148,13 @@
       <ion-icon name="heart-outline"></ion-icon>
       <span>我的喜欢</span>
     </div>
-  </div>
+  </div> -->
   <div style="margin-top: 60px;width: 100%;">
     <div style="width: 100%;padding-left: 20px;"><p class="left-align">更多服务:</p></div>
   <ion-list lines="none">
     <ion-item (click)="!currentUser?.id ? showAlert() : editUser()">
       <ion-icon slot="start" name="person-outline" style="font-size: 20px;"></ion-icon>
-      <ion-label>个人信息</ion-label>
+      <ion-label>编辑信息</ion-label>
       <ion-icon slot="end" name="chevron-forward-outline" style="color: lightgray;"></ion-icon>
     </ion-item>
     <ion-item>

+ 33 - 0
paint-app/src/app/tab4/tab4.component.html

@@ -0,0 +1,33 @@
+<ion-header [translucent]="true">
+   <ion-toolbar>
+    <ion-title>
+     社区交流
+    </ion-title>
+   </ion-toolbar>
+  </ion-header> 
+  
+  <ion-content>
+    <ion-item>
+      <ion-input (ionChange)="DataChange('content',$event)" label="评论" placeholder="请您输入评论"></ion-input>
+      <ion-button expand="block" (click)="click()">保存</ion-button>
+    </ion-item>
+
+   <div class="artwork-container">
+    <ion-card *ngFor="let comment of commentList" class="artwork-card">
+     <!-- <img [src]="artwork.image" alt="Artwork" class="artwork-image" /> -->
+     <ion-card-header>
+      <ion-card-title>{{ comment.get('username')||"未知名" }}</ion-card-title>
+      <!--<ion-card-subtitle>创作工具: {{ artwork.tools }}</ion-card-subtitle> -->
+     </ion-card-header>
+     <ion-card-content>
+      <p>{{comment.get('content')}}</p>
+      <p>{{comment.get('createdAt')}}</p>
+      <!-- <p><strong>创作过程:</strong> {{ artwork.process }}</p> --> 
+     </ion-card-content>
+     <div class="card-footer">
+      <!-- <ion-button expand="full" color="primary">点赞 <ion-icon name="thumbs-up-outline"></ion-icon></ion-button>
+      <ion-button expand="full" color="secondary">评论 <ion-icon name="chatbubble-outline"></ion-icon></ion-button> -->
+     </div>
+    </ion-card>
+   </div>
+  </ion-content>

+ 91 - 0
paint-app/src/app/tab4/tab4.component.scss

@@ -0,0 +1,91 @@
+ion-header {
+      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); /* 添加阴影效果 */
+     }
+     
+     ion-toolbar {
+      --background: transparent; /* 透明背景 */
+     }
+     
+     ion-title {
+      font-weight: bold; /* 加粗 */
+     }
+     
+     /* 内容容器样式 */
+     .artwork-container {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      padding: 16px; /* 添加内边距 */
+     }
+     
+     .artwork-card {
+      width: 100%; /* 卡片宽度 */
+      max-width: 500px; /* 最大宽度 */
+      margin: 20px 0; /* 上下间距 */
+      border-radius: 16px; /* 圆角 */
+      box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2); /* 增强阴影效果 */
+      transition: transform 0.3s, box-shadow 0.3s; /* 动画效果 */
+      overflow: hidden; /* 防止内容溢出 */
+      background: #ffffff; /* 白色背景 */
+     }
+     
+     .artwork-card:hover {
+      transform: translateY(-5px); /* 悬停时上移效果 */
+      box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3); /* 悬停时增强阴影效果 */
+     }
+     
+     /* 卡片图片样式 */
+     .artwork-image {
+      width: 100%; /* 使图片自适应卡片宽度 */
+      height: auto; /* 保持图片比例 */
+      border-top-left-radius: 16px; /* 圆角 */
+      border-top-right-radius: 16px; /* 圆角 */
+     }
+     
+     /* 卡片头部样式 */
+     ion-card-header {
+      color: #fff; /* 白色文字 */
+      padding: 16px; /* 内边距 */
+     }
+     
+     ion-card-title {
+      font-size: 1.8em; /* 增大标题字体 */
+      font-weight: bold; /* 加粗 */
+     }
+     
+     ion-card-subtitle {
+      font-size: 1.1em; /* 子标题字体 */
+      color: #e0e0e0; /* 淡灰色 */
+     }
+     
+     /* 卡片内容样式 */
+     ion-card-content {
+      padding: 16px; /* 内边距 */
+     }
+     
+     ion-card-content p {
+      margin: 8px 0; /* 段落上下间距 */
+      line-height: 1.6; /* 行高 */
+      color: #333; /* 深灰色文字 */
+     }
+     
+     /* 卡片底部按钮样式 */
+     .card-footer {
+      display: flex;
+      flex-direction: column;
+     }
+     
+     ion-button {
+      margin: 8px 0; /* 按钮外间距 */
+      border-radius: 25px; /* 圆角按钮 */
+      font-weight: bold; /* 加粗 */
+      background: linear-gradient(135deg, #ff6b6b, #f7b733); /* 渐变背景 */
+      color: white; /* 白色文字 */
+      transition: background 0.3s, transform 0.3s; /* 动画效果 */
+     }
+     
+     ion-button:hover {
+      transform: scale(1.05); /* 悬停时放大 */
+      background: linear-gradient(135deg, #ff4d4d, #f7a633); /* 悬停时变色 */
+     }
+    

+ 22 - 0
paint-app/src/app/tab4/tab4.component.spec.ts

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

+ 81 - 0
paint-app/src/app/tab4/tab4.component.ts

@@ -0,0 +1,81 @@
+import { Component } from '@angular/core';
+import { CommonModule } from '@angular/common'; // 确保导入 CommonModule
+import { IonHeader, IonToolbar, IonTitle, IonContent, IonCard, IonCardHeader, IonCardTitle, IonCardSubtitle, IonCardContent, IonButton, IonIcon, IonItem, IonInput } from '@ionic/angular/standalone'; // 导入 IonButton 和 IonIcon
+import { FormsModule, ReactiveFormsModule } from '@angular/forms'; // 导入 FormsModule
+import { CloudObject ,CloudQuery} from 'src/lib/ncloud';
+import { ModalController } from '@ionic/angular/standalone';
+import { AlertController } from '@ionic/angular/standalone'; 
+import {  CloudUser } from 'src/lib/ncloud';
+@Component({
+  selector: 'app-tab4',
+  templateUrl: './tab4.component.html',
+  styleUrls: ['./tab4.component.scss'],
+  standalone: true,
+  imports: [CommonModule, IonHeader, IonToolbar, IonTitle,FormsModule,IonItem,
+     IonContent, IonCard, IonCardHeader, IonCardTitle, IonCardSubtitle,ReactiveFormsModule,
+      IonCardContent, IonButton, IonIcon,IonInput] // 添加 IonButton 和 IonIcon
+})
+export class Tab4Component{
+ 
+     currentcomment: CloudObject | undefined; // 用于存储输入的评论
+     currentUser: CloudUser | undefined;
+     commentData: any = {};
+     // 处理用户数据变化的方法
+DataChange(key: string, ev: any) {
+  
+  // 从事件中获取输入的值
+  let value = ev?.detail?.value;
+  console.log(key);
+  console.log(value);
+  // 如果输入值存在,则将其存储到 userData 对象中
+  if (value) {
+    this.commentData[key] = value;
+    this.commentData['username']=this.currentUser?.get("username");
+  }
+}
+// 组件构造函数
+constructor(private alertController: AlertController,
+  private modalCtrl:ModalController) {
+  // 初始化当前用户为一个新的 CloudUser 实例
+  this.currentcomment = new CloudObject('pdiscuss');
+  this.currentUser = new CloudUser();
+}
+async save() {
+  // 将更新后的 userData 设置到 currentUser 对象中
+  this.currentcomment?.set(this.commentData);
+  
+  // 保存 currentUser 的数据
+  await this.currentcomment?.save();
+  
+}
+ngOnInit() {
+      // 生命周期:页面加载后,运行医生列表加载函数
+      this.loadcommmentList()
+    }
+  
+    // 创建用于数据列表存储的属性
+    commentList:Array<CloudObject> = []
+    async loadcommmentList(){
+      let query = new CloudQuery("pdiscuss");
+      this.commentList = await query.find()
+    }
+
+    async showAlert() {
+      const alert = await this.alertController.create({
+        header: '提示', // 提示框的标题
+        message: '请先登录以查看个人信息。', // 提示框的消息
+        buttons: ['确定'], // 按钮文本,用户点击后关闭提示框
+      });
+    
+      await alert.present(); // 显示提示框
+    }
+    click(){ 
+      if(!this.currentUser?.id){
+        console.log("用户未登录,请登录后重试"); 
+         this.showAlert();
+      }else{
+    this.save();
+      this.loadcommmentList();
+      }
+    }
+}

+ 11 - 2
paint-app/src/app/tabs/tabs.page.html

@@ -1,18 +1,27 @@
 <ion-tabs>
   <ion-tab-bar slot="bottom">
+
     <ion-tab-button tab="tab1" href="/tabs/tab1">
       <ion-icon aria-hidden="true" name="podium"></ion-icon>
       <ion-label>创作</ion-label>
     </ion-tab-button>
 
     <ion-tab-button tab="tab2" href="/tabs/tab2">
+      <ion-icon aria-hidden="true" name="speedometer"></ion-icon>
+      <ion-label>素材</ion-label>
+    </ion-tab-button>
+
+    <ion-tab-button tab="tab4" href="/paint-app/src/app/tab4/tab4.component.html">
       <ion-icon aria-hidden="true" name="aperture"></ion-icon>
-      <ion-label>发现</ion-label>
+      <ion-label>社区</ion-label>
     </ion-tab-button>
 
     <ion-tab-button tab="tab3" href="/tabs/tab3">
       <ion-icon aria-hidden="true" name="person"></ion-icon>
       <ion-label>我的</ion-label>
     </ion-tab-button>
-  </ion-tab-bar>
+
+</ion-tab-bar>
+ 
+
 </ion-tabs>

+ 2 - 2
paint-app/src/app/tabs/tabs.page.ts

@@ -2,7 +2,7 @@ import { Component, EnvironmentInjector, inject } from '@angular/core';
 import { IonicModule } from '@ionic/angular';
 import { IonTabs, IonTabBar, IonTabButton, IonIcon, IonLabel } from '@ionic/angular/standalone';
 import { addIcons } from 'ionicons';
-import { podium, aperture, person, compass } from 'ionicons/icons';
+import { podium, aperture, person, compass,speedometer } from 'ionicons/icons';
 addIcons({compass,person})
 
 @Component({
@@ -16,6 +16,6 @@ export class TabsPage {
   public environmentInjector = inject(EnvironmentInjector);
 
   constructor() {
-    addIcons({ podium, aperture, person });
+    addIcons({ podium, aperture, person ,speedometer});
   }
 }

+ 10 - 0
paint-app/src/app/tabs/tabs.routes.ts

@@ -21,6 +21,11 @@ export const routes: Routes = [
         loadComponent: () =>
           import('../tab3/tab3.page').then((m) => m.Tab3Page),
       },
+      {
+        path: 'tab4',
+        loadComponent: () =>
+          import('../tab4/tab4.component').then((m) => m.Tab4Component),
+      },
       {
         path: 'test',
         loadComponent: () =>
@@ -51,6 +56,11 @@ export const routes: Routes = [
         loadComponent: () =>
           import('../detail-page/detail-page.component').then((m) => m.DetailPageComponent),
       },
+      {
+        path: 'video-page',
+        loadComponent: () =>
+          import('../video-page/video-page.component').then((m) => m.VideoPageComponent),
+      },
       {
         path: '',
         redirectTo: '/tabs/tab1',

+ 65 - 41
paint-app/src/app/test2-page/test2-page.component.html

@@ -1,45 +1,69 @@
+<ion-header>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-button (click)="gopage()">
+        <ion-icon name="settings">返回</ion-icon>
+      </ion-button>
+    </ion-buttons>
+    <ion-title>视频</ion-title>
+  </ion-toolbar>
+</ion-header>
+
 <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>  
+  <div class="vido-type">
+    <video id="video" controls>
+        <source src="../../assets/6月26日(1).mp4" type="video/mp4">
+        您的浏览器不支持视频标签。
+    </video>
+    </div>
+    <!-- <div class="controls">
+        <button onclick="skip(-10)"><<<</button>
+        <button onclick="playOrPause()">暂停</button>     
+        <button onclick="skip(10)">>>></button>
+    </div> -->
 
+    <div class="art-content">
+        <!-- 评价选择 -->
+        <p class="switch-head-line">
+            <span class="mr chooseActive" eval_data='1'>评论</span>
+        </p>
+        <!-- 评价选择 -->
+        
+        <ul id="user_evaluate">
+            <li class="evaluate_li">
+                 <span class="img">
+                    <img src="images/tou2.jpg" alt="头像" />
+                </span>
+                <span class="info">
+                    <h4>爱吃馒头的宝宝</h4>
+                    <p>又是一部迪士尼的经典公主系列电影,刚开始小时候的妹妹真是萌翻了。不得不说这部电影在美国火爆了,本人在的高中,看过的人都激动得很,每天都在唱:Do you wanna build a snow man?~~</p>
+                    <p class="time">2019-04-28</p>
+                    <div class="reply_info">回复: <input type="text" id="name" name="name"></div>
+                </span>
+            </li>
+            <li class="evaluate_li">
+                <span class="img">
+                   <img src="images/tou1.jpg" alt="头像" />
+               </span>
+               <span class="info">
+                   <h4>爱你的我</h4>
+                   <p>我觉得之所以现在很多人再说不好,是因为对2的期待值过高。 不可否认,由于冰1的成功,加上6年时间的准备以及后期的有力宣传,确实抱有非常高的期待值。但是因文化差异等因素,有些部分确实会不那么让人喜欢。 [比如我个人就不太喜欢太多唱歌] 但实际上冰雪奇缘2依然是一部较优秀的作品。</p>
+                   <p class="time">2019-04-28</p>
+                   <div class="reply_info"> 回复:<input type="text" id="name" name="name"></div>
+               </span>
+           </li>
+           <li class="evaluate_li">
+            <span class="img">
+               <img src="images/tou3.jpg" alt="头像" />
+           </span>
+           <span class="info">
+               <h4>我是路人帅</h4>
+               <p>我最喜欢迪士尼音乐剧了,唱歌是用另一种方式推动剧情,角色用音乐的方式诉说或者对话,这样有童话色彩。是不是把所有唱歌的词直接改成角色正常的说话,电影就很好看了? 还有,音乐剧电影中,角色唱过的旋律后面还会再次唱,这是使电影的音乐更和谐,两段音乐呼应,会更美妙,几乎每个音乐剧都有,特别是迪士尼的经典影片,后面重复的音乐在音乐剧中叫Reprise,是音乐剧表现的普遍手法。</p>
+               <p class="time">2019-04-28</p>
+               <div class="reply_info"> 回复:<input type="text" id="name" name="name"></div>
+           </span>
+       </li>
+        </ul>
+    </div>
 </ion-content>
 

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

@@ -1,112 +1,166 @@
-* {  
-    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;
-    }
+/* 基础样式 */
+.navbar {
+    background-color: #ffe7df;
+    height: auto; /* 高度自适应 */
+    padding: 10px 20px; /* 减小内边距以适应小屏幕 */
+    display: flex;
+    flex-direction: column; /* 垂直排列 */
+    align-items: center; /* 居中对齐 */
+}
+
+.logo {
+    font-size: 24px; /* 调整字体大小 */
+    font-weight: bold;
+    color: #232c53;
+}
+
+.navbar ul {
+    list-style-type: none;
+    margin: 0;
+    padding: 0;
+    display: flex;
+    flex-wrap: wrap; /* 允许换行 */
+    justify-content: center; /* 居中对齐 */
+}
+
+.navbar li {
+    margin: 5px; /* 调整间距 */
+}
+
+.navbar li a {
+    color: #777b91;
+    text-decoration: none;
+    padding: 5px; /* 减小内边距 */
+}
+
+.navbar li a:hover {
+    color: #141e46;
+}
+
+.search-box {
+    width: 100%; /* 适应屏幕宽度 */
+    margin-top: 10px; /* 添加顶部间距 */
+}
+
+.search-box input {
+    width: calc(100% - 20px); /* 减去内边距 */
+    height: 30px;
+    border: none;
+    padding: 5px 10px;
+    border-radius: 6px;
+    background-color: #eff6f8;
+}
+
+.buttons {
+    display: flex;
+    flex-direction: column; /* 垂直排列按钮 */
+    align-items: center; /* 居中对齐 */
+    margin-top: 10px; /* 添加顶部间距 */
+}
+
+.buttons button {
+    margin: 5px 0; /* 垂直间距 */
+    padding: 5px 10px;
+    border: none;
+    cursor: pointer;
+}
+
+.login {
+    color: #232c53;
+    background-color: #fff;
+}
+
+.register {
+    color: #fff;
+    background-color: #232c53;
+    border-radius: 10px;
+}
+
+/* 视频容器的样式 */
+.vido-type {
+    width: 100%; /* 适应屏幕宽度 */
+    max-width: 414px; /* 最大宽度 */
+    height: auto; /* 高度自适应 */
+    margin: 10px auto; /* 居中 */
+}
+
+/* 视频元素本身的样式 */
+video {
+    width: 100%; /* 让视频填满其容器的宽度 */
+    height: auto; /* 高度自适应 */
+}
+
+/* 控制条容器的样式 */
+.controls {
+    bottom: 20px; /* 控制条距离容器底部20像素 */
+    width: 100%; /* 适应屏幕宽度 */
+    text-align: center; /* 控制条内容居中对齐 */
+    background-color: black; /* 控制条容器的背景颜色为黑色 */
+    margin: 0 auto; /* 外边距: 0(上下),自动(左右居中) */
+}
+
+/* 控制按钮的样式 */
+.controls button {
+    margin: 0 5px; /* 外边距: 0(上下),5像素(左右 - 按钮之间的间距) */
+    background-color: black; /* 按钮的背景颜色为黑色 */
+    color: rgb(0, 136, 255); /* 设置按钮文字颜色(RGB值为蓝色) */
+}
+
+/* 内容区域样式 */
+.art-content {
+    width: 100%; /* 适应屏幕宽度 */
+    max-width: 414px; /* 最大宽度 */
+    background-color: #fff;
+    padding: 10px; /* 减小内边距 */
+    margin: 0 auto; /* 居中 */
+}
+
+ul#user_evaluate li {
+    border-top: 2px dashed #eee;
+    padding: 15px 0; /* 减小内边距 */
+    list-style: none;
+}
+
+li.evaluate_li span {
+    display: inline-block;
+    vertical-align: top;
+}
+
+li.evaluate_li span.img img {
+    width: 40px; /* 调整头像大小 */
+    height: 40px; /* 调整头像大小 */
+    border-radius: 50%;
+    margin-right: 15px; /* 调整间距 */
+}
+
+li.evaluate_li span.info {
+    width: calc(100% - 60px); /* 适应宽度 */
+    display: inline-block;
+    vertical-align: top;
+}
+
+li.evaluate_li span.info h4 {
+    font-size: 10px; /* 调整字体大小 */
+    color: #999;
+}
+
+li.evaluate_li span.info p.time {
+    font-size: 10px; /* 调整字体大小 */
+    color: #999;
+}
+
+li.evaluate_li span.info div.reply_info {
+    margin-top: 10px; /* 调整间距 */
+    padding: 10px; /* 减小内边距 */
+    background: #f8f8f8;
+    font-size: 10px; /* 调整字体大小 */
+    color: #999;
+}
+
+input[type="text"] {
+    background: #f8f8f8;
+    color: #999;
+    border-color: #f8f8f8;
+    width: calc(100% - 20px); /* 适应宽度 */
+    padding: 5px; /* 添加内边距 */
+}

+ 10 - 48
paint-app/src/app/test2-page/test2-page.component.ts

@@ -1,62 +1,24 @@
 import { Component } from '@angular/core';
 import { Router } from '@angular/router';
-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';
+import { IonHeader, IonToolbar, IonTitle, IonContent, IonCard, IonCardContent, IonButton, IonCardHeader, IonCardTitle, IonCardSubtitle, ModalController, IonImg, IonIcon, IonButtons } from '@ionic/angular/standalone';
+import {settings} from 'ionicons/icons';
+addIcons({settings})
+import { addIcons } from 'ionicons';
+
 
 @Component({
   selector: 'app-test2-page',
   templateUrl: './test2-page.component.html',
   styleUrls: ['./test2-page.component.scss'],
   standalone: true,
-  imports: [IonHeader, IonToolbar, IonTitle, IonContent, 
+  imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonButtons,
     IonCard,IonCardContent,IonButton,IonCardHeader,IonCardTitle,IonCardSubtitle,IonImg
-  ],
+  ,IonIcon],
 })
 export class Test2PageComponent  {
-  currentUser:CloudUser|undefined
-  constructor(
-    private router: Router,
-    private modalCtrl:ModalController) {
-    this.currentUser = new CloudUser();
-  }
-  async login(){
-    // 弹出登录窗口
-    let user = await openUserLoginModal(this.modalCtrl);
-    if(user?.id){
-      this.currentUser = user
-    }
-  }
-  async signup(){
-    // 弹出注册窗口
-    let user = await openUserLoginModal(this.modalCtrl,"signup");
-    if(user?.id){
-      this.currentUser = user
-    }
-  }
-  logout(){
-    this.currentUser?.logout();
-  }
+  constructor(private router: Router){}
 
-  editUser(){
-    openUserEditModal(this.modalCtrl)
+  gopage(){
+    this.router.navigate(['/tabs/tab2'])
   }
-
-  editTags:Array<String>=[]
-   async setTagsValue(ev:any){
-    let currentUser = new CloudUser();
-    let userPrompt = ``
-    if(!currentUser?.id){
-      console.log("用户未登录,请登录后重试");
-      let user = await openUserLoginModal(this.modalCtrl);
-      if(!user?.id){
-        return
-      }
-      currentUser = user;
-    }
-  //console.log("setTagsValue",ev);
-  this.editTags=ev;
-}
-
 }

+ 80 - 0
paint-app/src/app/video-page/video-page.component.html

@@ -0,0 +1,80 @@
+<ion-header>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-button (click)="gopage()">
+        <ion-icon name="chevron-back">
+        </ion-icon>返回
+      </ion-button>
+    </ion-buttons>
+    <ion-title>视频</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content> 
+  <div class="vido-type">
+    <video id="video" controls>
+        <source src="../../assets/6月26日(1).mp4" type="video/mp4">
+        您的浏览器不支持视频标签。
+    </video>
+    </div>
+    <div class="art-content">
+        <!-- 评价选择 -->
+        <p class="switch-head-line">
+            <span class="mr chooseActive" eval_data='1'>评论</span>
+        </p>
+        <!-- 评价选择 -->
+        
+        <ul id="user_evaluate">
+
+            <li *ngFor="let comment of commentList" class="evaluate_li">
+                 <span class="img">
+                    <img src="../../assets/icon/tou1.jpg" style="width: 50px;
+                    height:50px;
+                    border-radius: 50%;
+                    margin-right:30px;"alt="头像" />
+                </span>
+                <span class="info">
+                    <h4>{{comment.get('user')?.get('username') || '不知名的网友'}}</h4>
+                    <p>{{comment.get('subtance')}}</p>
+                    <p class="time">{{comment.get('updatedAt')}}</p>
+                    <!-- <div class="reply_info">回复: <input type="text" id="name" name="name"></div> -->
+                </span>
+            </li>
+
+
+            <!-- <div *ngFor="let comment of commentList" class="image-wrapper" (click)="navigateToDetail()">
+                <img [src]="paint.get('picture')" [alt]="paint.get('name')" />
+                <div class="description-box">
+                    <div class="text1"><p>《{{ paint.get('name') }}》——{{ paint.get('artist') }}</p></div>
+                    <div class="text2"><p>{{ paint.get('introduction') }}</p></div>
+                </div>
+            </div>
+
+
+
+            <li class="evaluate_li">
+                <span class="img">
+                   <img src="images/tou1.jpg" alt="头像" />
+               </span>
+               <span class="info">
+                   <h4>爱你的我</h4>
+                   <p>我觉得之所以现在很多人再说不好,是因为对2的期待值过高。 不可否认,由于冰1的成功,加上6年时间的准备以及后期的有力宣传,确实抱有非常高的期待值。但是因文化差异等因素,有些部分确实会不那么让人喜欢。 [比如我个人就不太喜欢太多唱歌] 但实际上冰雪奇缘2依然是一部较优秀的作品。</p>
+                   <p class="time">2019-04-28</p>
+                   <div class="reply_info"> 回复:<input type="text" id="name" name="name"></div>
+               </span>
+           </li>
+           <li class="evaluate_li">
+            <span class="img">
+               <img src="images/tou3.jpg" alt="头像" />
+           </span>
+           <span class="info">
+               <h4>我是路人帅</h4>
+               <p>我最喜欢迪士尼音乐剧了,唱歌是用另一种方式推动剧情,角色用音乐的方式诉说或者对话,这样有童话色彩。是不是把所有唱歌的词直接改成角色正常的说话,电影就很好看了? 还有,音乐剧电影中,角色唱过的旋律后面还会再次唱,这是使电影的音乐更和谐,两段音乐呼应,会更美妙,几乎每个音乐剧都有,特别是迪士尼的经典影片,后面重复的音乐在音乐剧中叫Reprise,是音乐剧表现的普遍手法。</p>
+               <p class="time">2019-04-28</p>
+               <div class="reply_info"> 回复:<input type="text" id="name" name="name"></div>
+           </span>
+       </li> -->
+        </ul>
+    </div>
+</ion-content>
+

+ 0 - 0
paint-app/src/app/video-page/video-page.component.scss


+ 22 - 0
paint-app/src/app/video-page/video-page.component.spec.ts

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

+ 51 - 0
paint-app/src/app/video-page/video-page.component.ts

@@ -0,0 +1,51 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+import { IonHeader, IonToolbar, IonTitle, IonContent, IonCard, IonCardContent, IonButton, IonCardHeader, IonCardTitle, IonCardSubtitle, ModalController, IonImg, IonIcon, IonButtons } from '@ionic/angular/standalone';
+import {chevronBack} from 'ionicons/icons';
+addIcons({chevronBack})
+import { addIcons } from 'ionicons';
+import { CloudObject, CloudQuery } from 'src/lib/ncloud';
+import { ActivatedRoute } from '@angular/router';
+import { CommonModule } from '@angular/common';
+@Component({
+  selector: 'app-video-page',
+  templateUrl: './video-page.component.html',
+  styleUrls: ['./video-page.component.scss'],
+  standalone: true,
+  imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonButtons,CommonModule,
+    IonCard,IonCardContent,IonButton,IonCardHeader,IonCardTitle,IonCardSubtitle,IonImg
+  ,IonIcon],
+})
+export class VideoPageComponent{
+
+  constructor(private router: Router,
+            private route: ActivatedRoute
+  ){}
+
+  gopage(){
+    this.router.navigate(['/tabs/tab2'])
+    
+  }
+  commentList:Array<CloudObject> = []
+  videoId: string=''; // 用于存储传递的参数
+  ngOnInit() {
+    this.route.params.subscribe(params => {
+      this.videoId = params['id'];
+      console.log('接收到的参数:', this.videoId);
+      // 根据 videoId 加载视频数据
+    });
+    this.loadcommentList()
+  }
+
+      async loadcommentList(){
+      let query = new CloudQuery("pcomment");
+      await query.equalTo("videoname",this.videoId)
+      this.commentList = await query.find()
+      if (this.commentList && this.commentList.length > 0) {
+        console.log('有评论列表');
+      }
+      else{
+        console.log('无评论列表');
+      }
+      }
+}

BIN
paint-app/src/assets/6月26日(1).mp4


+ 3 - 1
paint-app/src/lib/ncloud.ts

@@ -1,4 +1,5 @@
 // CloudObject.ts
+//CloudObject 是表示数据库中单个对象的类。每个 CloudObject 实例对应数据库中的一条记录。
 export class CloudObject {
     className: string;
     id: string | null = null;
@@ -79,7 +80,8 @@ export class CloudObject {
     }
 }
 
-// CloudQuery.ts
+// CloudQuery.ts\
+//CloudQuery 是用于查询数据库中多个对象的类。它允许你构建查询条件并获取符合条件的多个记录。
 export class CloudQuery {
     className: string; // 存储类名
     whereOptions: Record<string, any> = {}; // 存储查询条件的对象,初始为空对象

+ 4 - 0
paint-app/src/lib/user/modal-user-edit/modal-user-edit.component.html

@@ -8,6 +8,10 @@
    </ion-card-header>
  <ion-card-content>
 
+  <!-- [value]="userData['realname']":
+这是 Angular 的属性绑定语法。它将 userData 对象中的 realname 属性的值绑定到输入框的 value 属性。
+当 userData['realname'] 的值发生变化时,输入框的显示内容也会自动更新。
+(ionChange)="userDataChange('realname', $event)": -->
    <ion-item>
      <ion-input [value]="userData['realname']" (ionChange)="userDataChange('realname',$event)" label="姓名" placeholder="请您输入真实姓名"></ion-input>
    </ion-item>

+ 52 - 25
paint-app/src/lib/user/modal-user-edit/modal-user-edit.component.ts

@@ -16,36 +16,63 @@ import { CloudUser } from 'src/lib/ncloud';
 })
 export class ModalUserEditComponent  implements OnInit {
 
-  currentUser:CloudUser|undefined
-  userData:any = {}
-  userDataChange(key:string,ev:any){
-    let value = ev?.detail?.value
-    if(value){
-      this.userData[key] = value
-    }
-  }
-  constructor(private modalCtrl:ModalController) { 
-    this.currentUser = new CloudUser();
-    this.userData = this.currentUser.data;
+  // 定义当前用户的类型,可能是 CloudUser 或者 undefined
+currentUser: CloudUser | undefined;
+
+// 存储用户数据的对象
+userData: any = {};
+
+// 处理用户数据变化的方法
+userDataChange(key: string, ev: any) {
+  
+  // 从事件中获取输入的值
+  let value = ev?.detail?.value;
+  
+  // 如果输入值存在,则将其存储到 userData 对象中
+  if (value) {
+    this.userData[key] = value;
   }
+}
 
-  ngOnInit() {}
+// 组件构造函数
+constructor(private modalCtrl: ModalController) {
+  // 初始化当前用户为一个新的 CloudUser 实例
+  this.currentUser = new CloudUser();
+  
+  // 将 currentUser 的数据赋值给 userData
+  this.userData = this.currentUser.data;
+}
 
-  async save(){
-    Object.keys(this.userData).forEach(key=>{
-      if(key=="age"){
-        this.userData[key] = Number(this.userData[key])
-      }
-    })
+// 组件初始化生命周期钩子
+ngOnInit() {
+  // 此处可以添加初始化逻辑
+}
 
-    this.currentUser?.set(this.userData)
-    await this.currentUser?.save()
-    this.modalCtrl.dismiss(this.currentUser,"confirm")
-  }
-  cancel(){
-    this.modalCtrl.dismiss(null,"cancel")
+// 保存用户数据的方法
+async save() {
+  // 遍历 userData 对象的所有键
+  Object.keys(this.userData).forEach(key => {
+    // 如果键是 "age",将其值转换为数字
+    if (key == "age") {
+      this.userData[key] = Number(this.userData[key]);
+    }
+  });
 
-  }
+  // 将更新后的 userData 设置到 currentUser 对象中
+  this.currentUser?.set(this.userData);
+  
+  // 保存 currentUser 的数据
+  await this.currentUser?.save();
+  
+  // 关闭模态框并返回 currentUser 作为确认结果
+  this.modalCtrl.dismiss(this.currentUser, "confirm");
+}
+
+// 取消操作的方法
+cancel() {
+  // 关闭模态框并返回 null 作为取消结果
+  this.modalCtrl.dismiss(null, "cancel");
+}
 }
 // 导出一个异步函数,用于打开用户编辑模态框并返回编辑后的用户信息
 export async function openUserEditModal(modalCtrl: ModalController): Promise<CloudUser | null> {