Browse Source

做了一些数据关联

15179169528 3 months ago
parent
commit
7186e1cafd

+ 1 - 0
202226701045

@@ -0,0 +1 @@
+Subproject commit aecf1d842554820194a6a7087b38cb198450079f

+ 46 - 7
poem-life-app/src/app/page-create/page-create.component.ts

@@ -4,6 +4,7 @@ import { Component, OnInit } from '@angular/core';
 import { IonHeader, IonToolbar, IonTitle, IonContent, IonButton, IonTextarea, IonInput, IonButtons, IonIcon, IonBackButton } from '@ionic/angular/standalone';
 import { FmodeChatCompletion, MarkdownPreviewModule } from 'fmode-ng';
 import { CommonModule } from '@angular/common';
+import { CloudObject, CloudUser } from 'src/lib/ncloud';
 
 @Component({
   selector: 'app-page-create',
@@ -16,14 +17,18 @@ import { CommonModule } from '@angular/common';
 })
 export class PageCreateComponent implements OnInit {
   isComplete: boolean = false;
-  ngOnInit() {}
-
+  error: string | null = null; // 添加错误状态
+  ngOnInit() {this.checkUserLogin()}
+  checkUserLogin() {
+    if (!this.currentUser?.id) {
+      this.router.navigate(['/login']);
+    }
+  }
   content: { title: string } = { title: '诗创' };
-  constructor(private ActivatedRoute: ActivatedRoute, private router: Router) {}
-
-  // goBack() {
-  //   this.router.navigate(['/tabs/tab4']); // 返回到 Tab4
-  // }
+  currentUser: CloudUser|undefined;
+  constructor(private ActivatedRoute: ActivatedRoute, private router: Router) {
+    this.currentUser = new CloudUser();
+  }
 
   style: string = "诗句格式";
   styleInput(ev: any) {
@@ -42,6 +47,11 @@ export class PageCreateComponent implements OnInit {
   responseMsg: any = "";
 
   sendMessage() {
+      if (!this.currentUser?.id) {
+        this.router.navigate(['/login']);
+        return;
+      }
+
     console.log("create");
 
     let PromptTemplate = `
@@ -69,7 +79,36 @@ export class PageCreateComponent implements OnInit {
       this.responseMsg = message.content;
       if (message?.complete) {
         this.isComplete = true;
+        this.saveCreation();
       }
     });
   }
+  saveCreation() {
+    if (!this.currentUser?.id) {
+      this.error = '请先登录';
+      alert('请先登录');
+      return;
+    }
+
+    const creationData = {
+      title: this.content.title,
+      content: this.responseMsg,
+      style: this.style,
+      images: [] // 如果有图片,可以在这里添加
+    };
+
+    const creation = new CloudObject("PL_Creations");
+    creation.set(creationData);
+    creation.set({
+      'user_id': this.currentUser.toPointer()
+    });
+
+    creation.save().then((savedCreation) => {
+      console.log('Creation saved with ID:', savedCreation.id);
+      alert('创作已保存');
+    }).catch((error) => {
+      console.error('Error saving creation:', error);
+      alert('保存创作时出错');
+    });
+  }
 }

+ 51 - 4
poem-life-app/src/app/page-createpic/page-createpic.component.ts

@@ -1,8 +1,10 @@
 import { CommonModule } from '@angular/common';
 import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
 import { IonHeader, IonToolbar, IonTitle, IonContent, IonButtons, IonBackButton } from '@ionic/angular/standalone';
 import { IonInput, IonTextarea, IonButton } from "@ionic/angular/standalone";
 import { DalleOptions, FmodeChatCompletion, ImagineWork, MarkdownPreviewModule } from 'fmode-ng';
+import {  CloudObject, CloudQuery, CloudUser} from 'src/lib/ncloud';
 
 @Component({
   selector: 'app-page-createpic',
@@ -18,15 +20,27 @@ import { DalleOptions, FmodeChatCompletion, ImagineWork, MarkdownPreviewModule }
 export class PageCreatepicComponent implements OnInit {
 
   userPrompt: string = "云想衣裳花想容,春风拂槛露华浓。若非群玉山头见,会向瑶台月下逢";
-  responseMsg: string | undefined; // 添加用于接收生成的消息内容
+  responseMsg: string | undefined; 
   images: Array<string> = [];
   imagineWork: ImagineWork | undefined;
+  currentUser: CloudUser | undefined;
+  error: string | undefined;
 
-  constructor() {
-    this.imagineWork = new ImagineWork(); // 初始化 ImagineWork 实例
+
+  constructor(private router: Router) {
+    this.imagineWork = new ImagineWork();
+    this.currentUser = new CloudUser();
+  }
+
+  ngOnInit() {
+    this.checkUserLogin();
   }
 
-  ngOnInit() {}
+  checkUserLogin() {
+    if (!this.currentUser?.id) { // 使用可选链操作符
+      this.router.navigate(['/tabs/login']);
+    }
+  }
 
   promptInput(ev: any) {
     this.userPrompt = ev.detail.value;
@@ -37,6 +51,12 @@ export class PageCreatepicComponent implements OnInit {
   }
 
   async createImage() {
+
+    if (!this.currentUser?.id) {
+      this.router.navigate(['/tabs/login']);
+      return;
+    }
+
     let PromptTemplate = `
     请您作为一位专业的画家,分析以下古诗中的情感、意象和色彩。请考虑以下要素,并将其转化为视觉艺术的表现:
 
@@ -80,6 +100,33 @@ export class PageCreatepicComponent implements OnInit {
       }
     });
   }
+  saveCreation() {
+    if (!this.currentUser?.id) {
+      this.error = '请先登录';
+      alert('请先登录');
+      return;
+    }
 
+    const creationData = {
+      title: this.content.title,
+      content: this.responseMsg,
+      style: '绘画',
+      images: JSON.stringify(this.images)
+    };
+
+    const creation = new CloudObject("PL_Creations");
+    creation.set(creationData);
+    creation.set({
+      'user_id': this.currentUser.toPointer()
+    });
+
+    creation.save().then((savedCreation) => {
+      console.log('Creation saved with ID:', savedCreation.id);
+      alert('创作已保存');
+    }).catch((error) => {
+      console.error('Error saving creation:', error);
+      alert('保存创作时出错');
+    });
+  }
   content: { title: string } = { title: '画创' };
 }

+ 10 - 0
poem-life-app/src/app/tab1/card-detail/card-detail.page.html

@@ -30,6 +30,16 @@
     <div class="content-text">
       <span [ngStyle]="{'white-space': 'pre-wrap'}">{{ content.get('detail') }}</span>
     </div>
+    <div class="actions">
+      <ion-button (click)="toggleLike()">
+        <ion-icon [name]="content?.get('is_liked') ? 'heart' : 'heart-outline'"></ion-icon>
+        {{ content?.get('is_liked') ? '已喜欢' : '喜欢' }}
+      </ion-button>
+      <ion-button (click)="toggleFavorite()">
+        <ion-icon [name]="content?.get('is_favorite') ? 'bookmark' : 'bookmark-outline'"></ion-icon>
+        {{ content?.get('is_favorite') ? '已收藏' : '收藏' }}
+      </ion-button>
+    </div>
   </div>
 </ion-content>
 

+ 99 - 5
poem-life-app/src/app/tab1/card-detail/card-detail.page.ts

@@ -2,15 +2,15 @@ import { Component, OnInit, } from '@angular/core';
 import { ActivatedRoute, Router } from '@angular/router';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
-import { IonContent, IonHeader,IonItem,IonList, IonThumbnail,IonTitle, IonToolbar,IonFooter, IonButtons,IonButton, IonBackButton} from '@ionic/angular/standalone';
-import { CloudObject, CloudQuery } from 'src/lib/ncloud';
+import { IonContent, IonHeader,IonItem,IonList, IonThumbnail,IonTitle, IonToolbar,IonFooter, IonButtons,IonButton, IonBackButton, IonIcon } from '@ionic/angular/standalone';
+import { CloudObject, CloudQuery, CloudUser } from 'src/lib/ncloud';
 
 @Component({
   selector: 'app-card-detail',
   templateUrl: './card-detail.page.html',
   styleUrls: ['./card-detail.page.scss'],
   standalone: true,
-  imports: [IonContent, IonHeader,IonThumbnail,IonList, IonTitle,IonItem,IonFooter, IonToolbar,IonButtons,IonButton, IonBackButton, CommonModule, FormsModule]
+  imports: [IonIcon, IonContent, IonHeader,IonThumbnail,IonList, IonTitle,IonItem,IonFooter, IonToolbar,IonButtons,IonButton, IonBackButton, CommonModule, FormsModule]
 })
 export class CardDetailPage implements OnInit {
 
@@ -20,8 +20,8 @@ export class CardDetailPage implements OnInit {
   prevContentData: CloudObject | null = null; // 前一篇文章
   nextContentData: CloudObject | null = null; // 后一篇文章
   contentsList: CloudObject[] = []; // 存储相同类型的文章列表
-
-  constructor(private activatedRoute: ActivatedRoute, private router: Router) { }
+  currentUser: CloudUser | undefined;
+  constructor(private activatedRoute: ActivatedRoute, private router: Router) { this.currentUser = new CloudUser();}
 
   ngOnInit() {
     // 获取传递的 ID
@@ -110,4 +110,98 @@ export class CardDetailPage implements OnInit {
   goBack() {
     this.router.navigate(['/tabs/tab1']); // 返回到 Tab1
   }
+
+  async toggleLike() {
+    if (!this.content || !this.currentUser?.id) {
+      this.error = '请先登录';
+      alert('请先登录');
+      return;
+    }
+    try {
+      const contentId = this.content.get('objectId');
+      const userId = this.currentUser.id;
+      let query = new CloudQuery("PL_UserRelation");
+      query.equalTo('user_id', this.currentUser.toPointer());
+      query.equalTo('article_id', this.content.toPointer());
+      const results = await query.find();
+      if (results.length > 0) {
+        const relation = results[0];
+        const isLiked = relation.get('is_liked');
+        relation.set('is_liked', !relation.get('is_liked'));
+
+        relation.set({
+          'is_liked': !isLiked
+        });
+
+        await relation.save();
+
+        this.content.set({
+          'is_liked': !isLiked
+        });
+
+      } else {
+        let newRelation = new CloudObject("PL_UserRelation");
+        newRelation.set({
+          'user_id': this.currentUser.toPointer(),
+          'article_id': this.content.toPointer(),
+          'is_liked': true,
+          'is_favorite': false
+        });
+        await newRelation.save();
+
+        this.content.set({
+          'is_liked': true
+        });
+
+      }
+      //this.content.set({'is_liked':!this.content.get('is_liked')});
+    } catch (err) {
+      this.error = '操作失败';
+      console.error(err);
+    }
+  }
+
+  async toggleFavorite() {
+    if (!this.content || !this.currentUser?.id) {
+      this.error = '请先登录';
+      return;
+    }
+    try {
+      const contentId = this.content.get('objectId');
+      const userId = this.currentUser.id;
+      let query = new CloudQuery("PL_UserRelation");
+      query.equalTo('user_id', this.currentUser.toPointer());
+      query.equalTo('article_id', this.content.toPointer());
+      const results = await query.find();
+      if (results.length > 0) {
+        const relation = results[0];
+
+        const isFavorite = relation.get('is_favorite');
+
+        relation.set({
+          'is_favorite': !isFavorite
+        });
+        await relation.save();
+        this.content.set({
+          'is_favorite': !isFavorite
+        });
+      } else {
+        let newRelation = new CloudObject("PL_UserRelation");
+        newRelation.set({
+          'user_id': this.currentUser.toPointer(),
+          'article_id': this.content.toPointer(),
+          'is_liked': false,
+          'is_favorite': true
+        });
+        await newRelation.save();
+        this.content.set({
+          'is_favorite': true
+        });
+      }
+      //this.content.set({'is_favorite': !this.content.get('is_favorite')});
+    } catch (err) {
+      this.error = '操作失败';
+      console.error(err);
+    }
+  }
 }

+ 4 - 39
poem-life-app/src/app/tab3/tab3.page.html

@@ -66,17 +66,8 @@
 <div class="ion-page" id="main-content">
   <ion-header [translucent]="true">
     <ion-toolbar>
-      <!-- <ion-buttons slot="start">
-        <ion-menu-button></ion-menu-button>
-      </ion-buttons> -->
       <ion-buttons slot="end">
         <ion-menu-button></ion-menu-button>
-        <!-- <ion-button (click)="navigateToLogin()">
-          <ion-icon name="search"></ion-icon>
-        </ion-button> -->
-        <!-- <ion-button (click)="navigateToLogin()">
-          <ion-icon name="ellipsis-horizontal"></ion-icon>
-        </ion-button> -->
       </ion-buttons>
     </ion-toolbar>
   </ion-header>
@@ -87,38 +78,13 @@
     <img src="../../assets/image/01/shige01.jpg" alt="背景图片" />
 
     <div class="profile-card">
-
-      <!-- @if(!currentUser?.id){
-      <div class="avatar-container" *ngIf="!currentUser?.id">
-        <img [src]="profile.avatar" alt="默认头像" class="avatar" />
-      </div>
-    }
-    @if(currentUser?.id){
-    <div class="avatar-container">
-      <img [src]="currentUser.get('avatar')" alt="头像" class="avatar" />
-    </div>
-  } -->
   <div class="avatar-container">
     <img [src]="currentUser?.get('avatar') ?? profile.avatar" alt="头像" class="avatar" />
   </div>
       @if(!currentUser?.id){
-      <!-- <button (click)="fileInput.click()" class="avatar-button">
-        <img src="currentUser.get("avatar")" alt="头像" class="avatar" />
-      </button>
-      <input type="file" #fileInput accept="image/*" (change)="onFileSelected($event)" style="display: none;" /> -->
-      <!-- <button (click)="editName()" class="name-button">
-        <h2>未知的某位网友</h2>
-      </button> -->
       <div><h3>未知的某位网友</h3></div>
     }
     @if(currentUser?.id){
-      <!-- <button (click)="fileInput.click()" class="avatar-button">
-        <img [src]="profile.avatar" alt="头像" class="avatar" />
-      </button>
-      <input type="file" #fileInput accept="image/*" (change)="onFileSelected($event)" style="display: none;" />
-      <button (click)="editName()" class="name-button">
-        <h2>{{ currentUser?.get("realname")}}</h2>
-      </button> -->
       <div (click)="!currentUser?.id ? showAlert() : editUser()"><h3>{{currentUser?.get("username")}}</h3></div>
     }
 
@@ -127,15 +93,14 @@
     <p *ngIf="profile.vipStatus" class="vip-status">
       VIP <button (click)="openVipPage()" class="vip-button">开通VIP&gt;</button>
     </p>
-      <!-- <p>{{ profile.level }}</p> -->
     </div>
 
-    <div class="cards-container" >
+    <!-- <div class="cards-container" >
       <div class="card" *ngFor="let button of profile.buttons">
         <ion-icon [name]="button.icon"></ion-icon>
         <p>{{ button.text }}</p>
       </div>
-    </div>
+    </div> -->
 
 
   </div>
@@ -165,13 +130,13 @@
       </ion-segment-button>
       <ion-segment-button (click)="setActiveTab('document')" [class.active]="activeTab === 'document'">
         <ion-icon name="document-text-outline"></ion-icon>
-        <ion-label>文章</ion-label>
+        <ion-label>故诗</ion-label>
       </ion-segment-button>
     </ion-segment>
   }
   </div>
   <div class="content-container" id="content-container" *ngIf="showTabs && activeTab !== null">
-    <!-- 内容将由updateContent方法动态插入 -->
+
   </div>
 </ion-content>
 </div>

+ 116 - 50
poem-life-app/src/app/tab3/tab3.page.ts

@@ -1,4 +1,4 @@
-import { Component } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
 import { Router } from '@angular/router';
 import { ExploreContainerComponent } from '../explore-container/explore-container.component';
 import { IonicModule } from '@ionic/angular';
@@ -8,7 +8,7 @@ import { bookmarkOutline, cartOutline, documentTextOutline, downloadOutline, ell
 import { EnvironmentInjector, inject } from '@angular/core';
 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 { CloudUser } from 'src/lib/ncloud';
+import { CloudObject, CloudQuery, CloudUser } from 'src/lib/ncloud';
 import { ModalController } from '@ionic/angular/standalone';
 import { AlertController } from '@ionic/angular/standalone'; // 导入所需的模块
 
@@ -19,18 +19,16 @@ import { AlertController } from '@ionic/angular/standalone'; // 导入所需的
   standalone: true,
   imports: [ExploreContainerComponent, IonicModule, CommonModule],
 })
-export class Tab3Page {
+export class Tab3Page implements OnInit{
   profile = {
-    // name: 'X',
-    // level: 'X',
     vipStatus: true,
     avatar: '../../assets/image/07/1.jpg', // 默认头像路径
-    buttons: [
-      { icon: 'time-outline', text: '浏览记录' },
-      { icon: 'download-outline', text: '我的下载' },
-      { icon: 'cart-outline', text: '我的购买' },
-      { icon: 'wallet-outline', text: '我的钱包' }
-    ],
+    // buttons: [
+    //   { icon: 'time-outline', text: '浏览记录' },
+    //   { icon: 'download-outline', text: '我的下载' },
+    //   { icon: 'cart-outline', text: '我的购买' },
+    //   { icon: 'wallet-outline', text: '我的钱包' }
+    // ],
     tabs: [
       { icon: 'images-outline', text: '全部' },
       { icon: 'image-outline', text: '图文' },
@@ -43,7 +41,10 @@ export class Tab3Page {
   public environmentInjector = inject(EnvironmentInjector);
 
   currentUser: CloudUser | undefined;
-
+  // 创建用于存储喜欢或收藏的文章内容的属性
+  favoriteOrLikedContents: Array<CloudObject> = [];
+  error:string|null = null;
+  loading: boolean = false;
   constructor(
     private router: Router,
     private alertController: AlertController,
@@ -59,31 +60,90 @@ export class Tab3Page {
   toggleTabs(action: string) {
     this.showTabs = !this.showTabs;
     if (action === 'like') {
-      this.setActiveTab('all');
+      this.setActiveTab('like'); // 设置为 'like'
     } else if (action === 'collect') {
-      this.setActiveTab('collect'); // 假设有一个收藏选项卡
+      this.setActiveTab('collect'); // 设置为 'collect'
+    }
+  }
+
+  ngOnInit() {
+    // 生命周期
+    this.loadPLContentsList();
+    if(this.currentUser?.id){
+      this.loadFavoriteOrLikedContents(this.currentUser.id);
+    }else {
+      console.log('未登录');
     }
   }
 
+  // 创建用于数据列表存储的属性
+  PLContentsList:Array<CloudObject> = []
+
+  async loadPLContentsList(){
+    let query = new CloudQuery("PL_Contents");
+    this.PLContentsList = await query.find()
+  }
   setActiveTab(tab: string | null) {
     this.activeTab = tab;
     this.updateContent();
   }
 
+  updateContent() {
+    const contentContainer = document.getElementById('content-container');
+    if (!contentContainer) return;
+  
+    if (!this.showTabs || this.activeTab === null) {
+      contentContainer.innerHTML = '';
+      return;
+    }
+  
+    // 第一次筛选:根据 like 和 favorite 进行筛选
+    let filteredContents: CloudObject[] = [];
+    switch (this.activeTab) {
+      case 'like':
+        filteredContents = this.favoriteOrLikedContents.filter(content => content.get('is_liked') === true);
+        break;
+      case 'collect':
+        filteredContents = this.favoriteOrLikedContents.filter(content => content.get('is_favorite') === true);
+        break;
+      default:
+        filteredContents = this.favoriteOrLikedContents;
+    }
+  
+    // 第二次筛选:根据 all、image 和 document 进行进一步的筛选
+    switch (this.activeTab) {
+      case 'all':
+        // 不需要进一步筛选,保持 filteredContents 不变
+        break;
+      case 'image':
+        filteredContents = filteredContents.filter(content => content.get('type') === '图文');
+        break;
+      case 'document':
+        filteredContents = filteredContents.filter(content => content.get('type') === '故诗');
+        break;
+    }
+  
+    // 渲染内容
+    if (filteredContents.length > 0) {
+      contentContainer.innerHTML = filteredContents.map(content => `
+        <div class="content-item">
+          <h2>${content.get('title')}</h2>
+          <p>${content.get('snippet')}</p>
+          <p>类型: ${content.get('type')}</p>
+          <p>发布时间: ${content.get('time')}</p>
+          <img src="${content.get('image')}" alt="${content.get('title')} 图片" />
+        </div>
+      `).join('');
+    } else {
+      contentContainer.innerHTML = `<p>暂时还没有相关内容呢,快去添加吧。</p>`;
+    }
+  }
   navigateToLogin() {
     this.router.navigate(['/tabs/login']);
   }
 
-  // editName() {
-  //   const newName = prompt("请输入新的名字", this.profile.name); // 仅示例
-  //   if (newName) {
-  //     this.profile.name = newName;
-  //   }
-  // }
-
   openVipPage() {
-    // 这里可以添加逻辑来导航到VIP开通页面
-    alert("导航到VIP开通页面");
+    alert("不允许你花钱!!!");
   }
 
   onFileSelected(event: Event) {
@@ -121,7 +181,11 @@ export class Tab3Page {
   }
 
   editUser() {
-    openUserEditModal(this.modalCtrl);
+    if (this.currentUser) {
+      openUserEditModal(this.modalCtrl); // 假设 modalCtrl 内部会处理 currentUser
+    } else {
+      console.error("未登录,无法执行此操作");
+    }
   }
 
   editTags: Array<string> = [];
@@ -149,32 +213,34 @@ export class Tab3Page {
 
     await alert.present(); // 显示提示框
   }
-
-  updateContent() {
-    const contentContainer = document.getElementById('content-container');
-    if (!contentContainer) return;
-
-    switch (this.activeTab) {
-      case 'all':
-        contentContainer.innerHTML = `
-          <h2>全部内容</h2>
-          <p>这里是全部内容的详细信息。</p>
-        `;
-        break;
-      case 'image':
-        contentContainer.innerHTML = `
-          <h2>图文内容</h2>
-          <p>这里是图文内容的详细信息。</p>
-        `;
-        break;
-      case 'document':
-        contentContainer.innerHTML = `
-          <h2>文章内容</h2>
-          <p>这里是文章内容的详细信息。</p>
-        `;
-        break;
-      default:
-        contentContainer.innerHTML = ''; // 默认情况下清空内容
+  async loadFavoriteOrLikedContents(userId: string) {
+    try {
+      this.loading = true;
+      let query = new CloudQuery("PL_UserRelation");
+      query.equalTo('user_id', userId); // 根据用户ID查询
+      const subQuery1 = new CloudQuery("PL_UserRelation");
+      subQuery1.equalTo('is_favorite', true);
+      const subQuery2 = new CloudQuery("PL_UserRelation");
+      subQuery2.equalTo('is_liked', true);
+      query.or(subQuery1, subQuery2); // 查询 is_favorite 或 is_like 为 true 的记录
+      const userRelations = await query.find();
+      console.log('User relations:', userRelations);
+
+      // 获取所有符合条件的 article_id
+      const articleIds = userRelations.map((relation: CloudObject) => relation.get('article_id'));
+
+      // 根据 article_id 查询 PL_Contents 表
+      if (articleIds.length > 0) {
+        let contentQuery = new CloudQuery("PL_Contents");
+        contentQuery.containedIn('objectId', articleIds); // 使用 containedIn 查询多个 article_id
+        this.favoriteOrLikedContents = await contentQuery.find();
+        console.log('Favorite or liked contents:', this.favoriteOrLikedContents);
+      }
+    } catch (err) {
+      this.error = '加载喜欢或收藏的内容时出错';
+      console.error(err);
+    } finally {
+      this.loading = false;
     }
   }
 }

+ 108 - 18
poem-life-app/src/lib/ncloud.ts

@@ -121,6 +121,15 @@ export class CloudQuery {
       this.orderOptions.push(`-${key}`);
   }
 
+  containedIn(key:string,values:any[]){
+    if(!this.whereOptions[key]) this.whereOptions[key]={};
+    this.whereOptions[key]["$in"] = values;
+  }
+    or(...queries: CloudQuery[]){
+        if(!this.whereOptions["$or"]) this.whereOptions["$or"]=[];
+        this.whereOptions["$or"].push(...queries.map(q=>q.whereOptions));
+    }
+
     async get(id: string) {
         const url = `http://dev.fmode.cn:1337/parse/classes/${this.className}/${id}?`;
 
@@ -228,25 +237,27 @@ export class CloudUser extends CloudObject {
             console.error("用户未登录");
             return null;
         }
-
-        const response = await fetch(`http://dev.fmode.cn:1337/parse/users/me`, {
-            headers: {
-                "x-parse-application-id": "dev",
-                "x-parse-session-token": this.sessionToken // 使用sessionToken进行身份验证
-            },
-            method: "GET"
-        });
-
-        const result = await response?.json();
-        if (result?.error) {
-            console.error(result?.error);
-            return null;
-        }
-        return result;
+        return this;
+        // const response = await fetch(`http://dev.fmode.cn:1337/parse/users/me`, {
+        //     headers: {
+        //         "x-parse-application-id": "dev",
+        //         "x-parse-session-token": this.sessionToken // 使用sessionToken进行身份验证
+        //     },
+        //     method: "GET"
+        // });
+
+        // const result = await response?.json();
+        // if (result?.error) {
+        //     console.error(result?.error);
+        //     return null;
+        // }
+        // return result;
     }
 
     /** 登录 */
     async login(username: string, password: string):Promise<CloudUser|null> {
+//
+
         const response = await fetch(`http://dev.fmode.cn:1337/parse/login`, {
             headers: {
                 "x-parse-application-id": "dev",
@@ -279,7 +290,7 @@ export class CloudUser extends CloudObject {
             return;
         }
 
-        const response = await fetch(`http://dev.fmode.cn:1337/parse/logout`, {
+        const response = await fetch(`https://dev.fmode.cn/parse/logout`, {
             headers: {
                 "x-parse-application-id": "dev",
                 "x-parse-session-token": this.sessionToken
@@ -287,18 +298,26 @@ export class CloudUser extends CloudObject {
             method: "POST"
         });
 
-        const result = await response?.json();
+        let result = await response?.json();
+
         if (result?.error) {
             console.error(result?.error);
+            if(result?.error=="Invalid session token"){
+                this.clearUserCache()
+                return true;
+            }
             return false;
         }
 
+        this.clearUserCache()
+        return true;
+    }
+    clearUserCache(){
         // 清除用户信息
         localStorage.removeItem("NCloud/dev/User")
         this.id = null;
         this.sessionToken = null;
         this.data = {};
-        return true;
     }
 
     /** 注册 */
@@ -325,11 +344,82 @@ export class CloudUser extends CloudObject {
         }
 
         // 设置用户信息
+        // 缓存用户信息
+        console.log(result)
+        localStorage.setItem("NCloud/dev/User",JSON.stringify(result))
         this.id = result?.objectId;
         this.sessionToken = result?.sessionToken;
         this.data = result; // 保存用户数据
         return this;
     }
+
+    override async save() {
+        let method = "POST";
+        let url = `https://dev.fmode.cn/parse/users`;
+    
+        // 更新用户信息
+        if (this.id) {
+            url += `/${this.id}`;
+            method = "PUT";
+        }
+    
+        let data:any = JSON.parse(JSON.stringify(this.data))
+        delete data.createdAt
+        delete data.updatedAt
+        delete data.ACL
+        delete data.objectId
+        const body = JSON.stringify(data);
+        let headersOptions:any = {
+            "content-type": "application/json;charset=UTF-8",
+            "x-parse-application-id": "dev",
+            "x-parse-session-token": this.sessionToken, // 添加sessionToken以进行身份验证
+        }
+        const response = await fetch(url, {
+            headers: headersOptions,
+            body: body,
+            method: method,
+            mode: "cors",
+            credentials: "omit"
+        });
+    
+        const result = await response?.json();
+        if (result?.error) {
+            console.error(result?.error);
+        }
+        if (result?.objectId) {
+            this.id = result?.objectId;
+        }
+        localStorage.setItem("NCloud/dev/User",JSON.stringify(this.data))
+        return this;
+    }   
 }
 
 // CloudCard.ts
+export class CloudApi{
+    async fetch(path:string,body:any,options?:{
+        method:string
+        body:any
+    }){
+
+        let reqOpts:any =  {
+            headers: {
+                "x-parse-application-id": "dev",
+                "Content-Type": "application/json"
+            },
+            method: options?.method || "POST",
+            mode: "cors",
+            credentials: "omit"
+        }
+        if(body||options?.body){
+            reqOpts.body = JSON.stringify(body || options?.body);
+            reqOpts.json = true;
+        }
+        let host = `https://dev.fmode.cn`
+        // host = `http://127.0.0.1:1337`
+        let url = `${host}/api/`+path
+        console.log(url,reqOpts)
+        const response = await fetch(url,reqOpts);
+        let json = await response.json();
+        return json
+    }
+}

+ 49 - 15
poem-life-app/src/lib/user/modal-user-edit/modal-user-edit.component.html

@@ -1,29 +1,63 @@
 <!-- 用户登录状态 -->
-<ion-card>
+<ion-card >
   <ion-card-header>
     <ion-card-title>
       用户名:{{currentUser?.get("username")}}
     </ion-card-title>
-    <ion-card-subtitle>请输入您的详细资料</ion-card-subtitle>
+    <ion-card-subtitle >请输入您的详细资料</ion-card-subtitle>
    </ion-card-header>
- <ion-card-content>
 
-   <ion-item>
-     <ion-input [value]="userData['realname']" (ionChange)="userDataChange('realname',$event)" label="姓名" placeholder="请您输入真实姓名"></ion-input>
-   </ion-item>
-   <ion-item>
-     <ion-input type="number" [value]="userData['age']" (ionChange)="userDataChange('age',$event)" label="年龄" placeholder="请您输入年龄"></ion-input>
+ <ion-card-content>
+    <ion-item>
+      <ion-input [value]="userData['realname']" (ionChange)="userDataChange('realname',$event)" label="姓名" placeholder="请您输入真实姓名"></ion-input>
+    </ion-item>
+    <ion-item>
+      <ion-input [value]="userData['username']" (ionChange)="userDataChange('username',$event)" label="昵称" placeholder="请您输入用户网名"></ion-input>
     </ion-item>
-  <ion-item>
-     <ion-input [value]="userData['gender']" (ionChange)="userDataChange('gender',$event)" label="性别" placeholder="请您输入男/女"></ion-input>
+    <ion-item>
+      <ion-input type="number" [value]="userData['age']" (ionChange)="userDataChange('age',$event)" label="年龄" placeholder="请您输入年龄"></ion-input>
+    </ion-item>
+    <ion-item>
+      <ion-input [value]="userData['gender']" (ionChange)="userDataChange('gender',$event)" label="性别" placeholder="请您输入男/女"></ion-input>
     </ion-item>
     <ion-item>
       <ion-input [value]="userData['avatar']" (ionChange)="userDataChange('avatar',$event)" label="头像" placeholder="请您输入头像地址"></ion-input>
-     </ion-item>
+    </ion-item>
+    <ion-item>
+      <ion-input [value]="userData['email']" (ionChange)="userDataChange('email',$event)" label="邮箱" placeholder="请您输入邮箱号"></ion-input>
+    </ion-item>
 
-   <ion-button expand="block" (click)="save()">保存</ion-button>
-   <ion-button expand="block" (click)="cancel()">取消</ion-button>
+   <ion-button expand="block" color="danger" (click)="save()">保存</ion-button>
+   <ion-button expand="block" color="danger" (click)="cancel()">取消</ion-button>
  
 
-</ion-card-content>
-</ion-card>
+  </ion-card-content>
+</ion-card>
+
+
+<!-- 用户登录状态
+<ion-card>
+  <ion-card-header>
+    <ion-card-title>
+      用户名:{{ currentUser?.get("username") }}
+    </ion-card-title>
+    <ion-card-subtitle>请输入您的详细资料</ion-card-subtitle>
+  </ion-card-header>
+  <ion-card-content>
+    <ion-item>
+      <ion-input [value]="userData['realname']" (ionChange)="userDataChange('realname', $event)" label="姓名" placeholder="请您输入真实姓名"></ion-input>
+    </ion-item>
+    <ion-item>
+      <ion-input type="number" [value]="userData['age']" (ionChange)="userDataChange('age', $event)" label="年龄" placeholder="请您输入年龄"></ion-input>
+    </ion-item>
+    <ion-item>
+      <ion-input [value]="userData['gender']" (ionChange)="userDataChange('gender', $event)" label="性别" placeholder="请您输入男/女"></ion-input>
+    </ion-item>
+    <ion-item>
+      <ion-input [value]="userData['avatar']" (ionChange)="userDataChange('avatar', $event)" label="头像" placeholder="请您输入头像地址"></ion-input>
+    </ion-item>
+
+    <ion-button expand="block" (click)="save()">保存</ion-button>
+    <ion-button expand="block" (click)="cancel()">取消</ion-button>
+  </ion-card-content>
+</ion-card> -->