18879852299-202226701057 4 luni în urmă
părinte
comite
1adb3bbbf8

+ 20 - 3
TFPower-app/src/app/app.routes.ts

@@ -1,9 +1,26 @@
-import { Routes } from '@angular/router';
-
+import { Routes,RouterModule } from '@angular/router';
+import { PostPageComponent } from './post-page/post-page.component'; // 导入 PostPage 组件
+import { CommunityPage } from './community/community.page';
+import { SharePageComponent } from './share-page/share-page.component';
+import { NgModule } from '@angular/core';
 export const routes: Routes = [
   {
     path: '',
     loadChildren: () => import('./tabs/tabs.routes').then((m) => m.routes),
   },
-
+  {
+    path: 'community',
+    loadComponent: () => import('./community/community.page').then( m => m.CommunityPage)
+  },
+  { path: '', redirectTo: 'community', pathMatch: 'full' },
+  { path: 'community', component: CommunityPage },
+  { path: 'post-page/:id', component: PostPageComponent }, // 动态详情页面的路由
+  { path: 'share', component: SharePageComponent },
 ];
+
+
+@NgModule({
+  imports: [RouterModule.forRoot(routes)],
+  exports: [RouterModule]
+})
+export class AppRoutingModule { }

+ 25 - 0
TFPower-app/src/app/community/community.page.html

@@ -0,0 +1,25 @@
+<ion-header>
+  <ion-toolbar>
+    <ion-title>发现</ion-title>
+    <ion-buttons slot="end">
+      <ion-button (click)="sharePost()" color="primary">
+        <ion-icon name="add"></ion-icon>
+      </ion-button>
+    </ion-buttons>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+  <div class="spacer"></div>
+  <div class="post-grid">
+    <ion-card *ngFor="let post of posts" (click)="viewPost(post.id)" class="post-card">
+      <ion-card-header>
+        <ion-card-subtitle>{{ post.date | date:'short' }}</ion-card-subtitle>
+      </ion-card-header>
+      <ion-card-content>
+        <img [src]="post.imageUrl" *ngIf="post.imageUrl" alt="动态图片" class="post-image" />
+        <p>{{ post.text }}</p>
+      </ion-card-content>
+    </ion-card>
+  </div>
+</ion-content>

+ 51 - 0
TFPower-app/src/app/community/community.page.scss

@@ -0,0 +1,51 @@
+// .spacer {
+//   height: 50px; /* 设置空白区域的高度 */
+// }
+
+// .post-grid {
+//   display: grid;
+//   grid-template-columns: repeat(2, 1fr); /* 每行两个动态 */
+//   gap: 16px; /* 每个动态之间的间距 */
+//   padding: 6px; /* 页面内边距 */
+// }
+
+// .post-card {
+//   border-radius: 10px;
+//   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+//   cursor: pointer; /* 鼠标悬停时显示为可点击 */
+// }
+
+// .post-image {
+//   width: 100%;
+//   height: auto;
+//   border-radius: 10px;
+//   margin-bottom: 2px;
+// }
+
+.discovery-content {
+  background-color: #f9f9f9; /* 浅色背景 */
+}
+
+.spacer {
+  height: 16px;
+}
+
+.post-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+  gap: 16px; /* 卡片之间的间距 */
+}
+
+.post-card {
+  transition: transform 0.2s;
+  border: 1px solid #ddd; /* 边框 */
+  border-radius: 8px; /* 圆角 */
+}
+
+.post-card:hover {
+  transform: scale(1.05); /* 悬停效果 */
+}
+
+.post-image {
+  border-radius: 8px; /* 图片圆角 */
+}

+ 17 - 0
TFPower-app/src/app/community/community.page.spec.ts

@@ -0,0 +1,17 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { CommunityPage } from './community.page';
+
+describe('CommunityPage', () => {
+  let component: CommunityPage;
+  let fixture: ComponentFixture<CommunityPage>;
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(CommunityPage);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 64 - 0
TFPower-app/src/app/community/community.page.ts

@@ -0,0 +1,64 @@
+import { Component, OnInit } from '@angular/core';
+import { IonAvatar, IonButton, IonCard, IonCardHeader, IonCardSubtitle, IonCardTitle, IonContent, IonHeader, IonIcon, IonInput, IonItem, IonList, IonTitle, IonToolbar, ModalController } from '@ionic/angular/standalone';
+import { FormsModule } from '@angular/forms';
+import { CommonModule } from '@angular/common';
+import { NavigationExtras, Router } from '@angular/router';
+import { PostService } from '../post.service'; // 导入服务
+import { IonButtons } from '@ionic/angular/standalone';
+import { IonCardContent } from '@ionic/angular/standalone';
+import { CloudObject, CloudQuery, CloudUser } from 'src/lib/ncloud';
+import { openUserLoginModal } from 'src/lib/user/modal-user-login/modal-user-login.component';
+
+@Component({
+  selector: 'app-community',
+  templateUrl: './community.page.html',
+  styleUrls: ['./community.page.scss'],
+  standalone: true,
+  imports: [IonHeader,IonToolbar,IonButtons,IonIcon,IonButton,IonContent,IonCard,IonCardHeader,
+    IonItem,IonAvatar,IonCardTitle,IonCardSubtitle,FormsModule,CommonModule,IonCardContent,IonTitle
+    ],
+})
+export class CommunityPage implements OnInit {
+  posts: { id: number; username: string; date: Date; text: string; imageUrl?: string; avatarUrl?: string }[] = [];
+
+  constructor(private router: Router,private postService: PostService,
+    private modalCtrl: ModalController,
+
+  ) {
+  }
+
+  ngOnInit() {
+    this.posts = this.postService.getPosts(); // 从服务中获取动态数据// 这里可以进行数据的初始化或获取
+  }
+
+  // viewPost(postId: number) {
+
+  //   const state: any = {  postId:  postId }; // 你要传递的对象数据
+  //   const navigationExtras: NavigationExtras = {
+  //     state: state
+  //   };
+  //   console.log("state::",state);
+    
+   
+  //   this.router.navigate(['/tabs/post-page', postId]);
+
+  //   // this.router.navigate(['/tabs/post-page', postId]); // 导航到动态详情页面
+  // }
+  viewPost(postId: number) {
+    // 直接导航到动态详情页面
+    this.router.navigate(['/post-page', postId]);
+  }
+  async sharePost() {
+    let currentUser = new CloudUser();
+
+    if (!currentUser?.id) {
+      console.log("用户未登录,请登录后重试");
+      let user = await openUserLoginModal(this.modalCtrl);
+      if (!user?.id) {
+        return
+      }
+      currentUser = user;
+    }
+    this.router.navigate(['/tabs/share-page']); // 导航到分享动态页面
+  }
+}

+ 42 - 0
TFPower-app/src/app/post-page/post-page.component.html

@@ -0,0 +1,42 @@
+<ion-header>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-back-button defaultHref="/tabs/community"></ion-back-button>
+    </ion-buttons>
+    <ion-title>动态详情</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+  <ion-card *ngIf="post">
+    <ion-card-header>
+      <ion-item>
+        <ion-avatar slot="start">
+          <img [src]="post.avatarUrl" *ngIf="post.avatarUrl" alt="用户头像" />
+        </ion-avatar>
+        <ion-card-title>{{ post.username }}</ion-card-title>
+        <ion-card-subtitle>{{ post.date | date:'short' }}</ion-card-subtitle>
+      </ion-item>
+    </ion-card-header>
+    <ion-card-content>
+      <img [src]="post.imageUrl" *ngIf="post.imageUrl" alt="动态图片" class="post-image" />
+      <p>{{ post.text }}</p>
+      <ion-button (click)="likePost()" [color]="liked ? 'danger' : 'light'">
+        <ion-icon name="heart" slot="icon-only"></ion-icon>
+        {{ liked ? '已点赞' : '点赞' }}
+      </ion-button>
+    </ion-card-content>
+    <ion-item>
+      <ion-input [(ngModel)]="newComment" placeholder="写下你的评论..."></ion-input>
+      <ion-button (click)="addComment()" color="primary">
+        <ion-icon slot="icon-only" name="send"></ion-icon>
+      </ion-button>
+    </ion-item>
+    <ion-list>
+      <ion-item *ngFor="let comment of comments">
+        <ion-label>{{ comment.username }}: {{ comment.text }}</ion-label>
+      </ion-item>
+    </ion-list>
+  </ion-card>
+</ion-content>
+

+ 16 - 0
TFPower-app/src/app/post-page/post-page.component.scss

@@ -0,0 +1,16 @@
+.detail-content {
+  background-color: #ffffff; /* 白色背景 */
+}
+
+.post-detail-card {
+  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */
+  border-radius: 12px; /* 圆角 */
+}
+
+.post-image {
+  border-radius: 12px; /* 图片圆角 */
+}
+
+ion-card-header {
+  background-color: #e0f7fa; /* 浅蓝色背景 */
+}

+ 24 - 0
TFPower-app/src/app/post-page/post-page.component.spec.ts

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

+ 87 - 0
TFPower-app/src/app/post-page/post-page.component.ts

@@ -0,0 +1,87 @@
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { IonAvatar, IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonContent, IonHeader, IonInput, IonItem, IonLabel, IonList, IonTitle, IonToolbar } from '@ionic/angular/standalone';
+import { IonBackButton } from '@ionic/angular/standalone';
+import { IonIcon } from '@ionic/angular/standalone';
+import { CommonModule } from '@angular/common';
+import { PostService } from '../post.service'; // 导入服务
+import { FormsModule } from '@angular/forms';
+
+@Component({
+  selector: 'app-post-page',
+  templateUrl: './post-page.component.html',
+  styleUrls: ['./post-page.component.scss'],
+  standalone: true,
+  imports: [IonHeader,IonToolbar,IonButtons,IonBackButton,IonTitle,IonContent,
+    IonCard,IonCardHeader,IonItem,IonAvatar,IonCardTitle,IonCardSubtitle,IonCardContent,
+    IonButton,IonIcon,IonItem,IonInput,IonList,IonLabel,FormsModule,CommonModule
+    ],
+})
+export class PostPageComponent  implements OnInit {
+  post: any;
+  liked: boolean = false;
+  newComment: string = '';
+  comments: { username: string; text: string }[] = [];
+  postId: any;
+
+  constructor(private router: Router,private route: ActivatedRoute,private postService: PostService) {}
+
+  ngOnInit() {
+    // this.loadDaata();
+    // console.log(this.post);
+     // 使用 route.params 订阅参数变化
+      // 获取动态 ID
+      this.route.params.subscribe(params => {
+        const postId = Number(params['id']); // 获取动态 ID
+        if (!isNaN(postId)) {
+          this.post = this.postService.getPostById(postId); // 根据 ID 获取动态内容
+        } else {
+          console.error('Invalid post ID');
+        }
+      });
+  
+      // 这里可以添加逻辑来根据 postId 更新页面内容
+
+    
+
+    // const postId = Number(this.route.snapshot.paramMap.get('id')); // 获取动态 ID
+    // 根据 ID 获取动态内容
+    
+     
+  }
+  // ngDoCheck(){
+  //   this.loadDaata();
+  //   console.log(this.post);
+  // }
+  // async loadDaata(){
+  //   const navigation = this.router.getCurrentNavigation();
+  //   if (navigation && navigation.extras && navigation.extras.state) {
+  //     const state = navigation.extras.state;
+  //     console.log(state['postId']); // 访问传递的对象数据
+  //     const postId=state['postId']
+  //     this.post =await this.postService.getPostById(postId);
+  //      if (postId !== null) {
+  //     this.post =await this.postService.getPostById(postId); // 根据 ID 获取动态内容
+  //   } else {
+  //     console.error('Invalid post ID'); // 处理无效的 ID
+  //   }
+  //   }
+
+  // }
+
+  likePost() {
+    this.liked = !this.liked;
+  }
+
+  addComment() {
+    if (this.newComment.trim()) {
+      const newCommentObj = {
+        username: '当前用户', // 可以替换为实际的用户名
+        text: this.newComment,
+      };
+      this.comments.push(newCommentObj);
+      this.newComment = ''; // 清空输入框
+    }
+  }
+
+}

+ 16 - 0
TFPower-app/src/app/post.service.spec.ts

@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { PostService } from './post.service';
+
+describe('PostService', () => {
+  let service: PostService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(PostService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});

+ 31 - 0
TFPower-app/src/app/post.service.ts

@@ -0,0 +1,31 @@
+import { Injectable } from '@angular/core';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class PostService {
+  private posts: { id: number; username: string; date: Date; text: string; imageUrl?: string;  avatarUrl?: string }[] = [];
+
+  constructor() {
+    // 初始化一些动态数据
+    this.posts = [
+      { id: 1, username: '张宇轩', date: new Date(), text: '今天在健身房看到一位大神,那肌肉块儿,硬得能当铠甲穿了,这是把健身房当家,天天死磕啊!我这弱鸡身材,可得好好向人家学学,争取也能有点型男范儿。', imageUrl: 'https://img1.baidu.com/it/u=1099077011,3018419742&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=1030', avatarUrl: 'https://img1.baidu.com/it/u=1163151343,2692194574&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1735059600&t=fcacaa8573711e655ba8c471ce71115b' },
+      { id: 2, username: '周逸飞', date: new Date(), text: '刚瞅见个兄弟,在力量区一顿操作猛如虎,那杠铃被他玩得团团转。再瞧瞧我这小细胳膊,感觉自己像个 “弱不禁风” 的小鸡仔,不行,我要雄起!', imageUrl: 'https://img2.baidu.com/it/u=928878141,644699362&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=1200', avatarUrl: 'https://img2.baidu.com/it/u=1278365427,821903566&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1735059600&t=fb7d638355023c6485508b537ae83b0d' },
+      { id: 3, username: '李明泽', date: new Date(), text: '有个哥们儿在跑步机上那叫一个飞驰,感觉鞋底都要磨出火星子了。我这跑步没几步就喘的,真是人比人气死人,得赶紧努力了。 “僵硬咒”,必须得好好练练柔韧性了。', imageUrl: 'https://img1.baidu.com/it/u=1351173388,1258342591&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=667', avatarUrl: 'https://img1.baidu.com/it/u=509829497,169179735&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800' },
+      { id: 4, username: '林悦溪', date: new Date(), text: '宝子们,今天看到一个姐妹练出的马甲线,线条清晰得像巧克力格子,我这肚子上的肉肉啊,简直就是 “游泳圈本圈”,我要加油甩肉了。', imageUrl: 'https://img2.baidu.com/it/u=1252124552,1555363643&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1516', avatarUrl: 'https://img2.baidu.com/it/u=1098802303,3156782570&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=522' },
+      { id: 5, username: '苏瑶', date: new Date(), text: '看到有个美女做瑜伽,身体软得像棉花糖,各种高难度动作轻松拿捏。我这硬邦邦的身体,仿佛是被施了 “僵硬咒”,必须得好好练练柔韧性了。', imageUrl: 'https://img2.baidu.com/it/u=3745236023,3943250152&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=667', avatarUrl: 'https://img0.baidu.com/it/u=2803383319,161975459&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500' },
+      { id: 6, username: '陈诗涵', date: new Date(), text: '刚瞧到一位女生健身后的身材,那臀腿线条,紧致得像刚出锅的水煮蛋,再看我这松松垮垮的,哎,不说了,我去练了,誓要和肥肉说拜拜!', imageUrl: 'https://img0.baidu.com/it/u=4084162160,777769259&fm=253&fmt=auto&app=120&f=JPEG?w=518&h=500', avatarUrl: 'https://img2.baidu.com/it/u=3486075952,1831752642&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=516' },
+    ];
+  }
+
+  getPosts() {
+    return this.posts;
+  }
+
+  addPost(post: { id: number; username: string; date: Date; text: string; imageUrl?: string }) {
+    this.posts.push(post);
+  }
+  getPostById(id: number) {
+    return this.posts.find(post => post.id === id); // 根据 ID 查找动态
+  }
+}

+ 57 - 0
TFPower-app/src/app/share-page/share-page.component.html

@@ -0,0 +1,57 @@
+<!-- <ion-header>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-back-button defaultHref="/community"></ion-back-button>
+    </ion-buttons>
+    <ion-title>分享动态</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+  <ion-item>
+    <ion-input [(ngModel)]="newPost.text" placeholder="写下你的动态..."></ion-input>
+  </ion-item>
+  
+  <ion-item>
+    <input type="file" (change)="onFileSelected($event)" accept="image/*" />
+  </ion-item>
+  
+  <ion-item>
+    <ion-button (click)="submitPost()" color="primary">发布</ion-button>
+  </ion-item>
+  
+  <div *ngIf="imagePreview" class="image-preview">
+    <img [src]="imagePreview" alt="Image Preview" />
+  </div>
+</ion-content> -->
+
+<ion-header>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-back-button defaultHref="/community"></ion-back-button>
+    </ion-buttons>
+    <ion-title>分享动态</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content class="share-content">
+  <div class="image-preview-container">
+    <div *ngIf="imagePreview" class="image-preview">
+      <img [src]="imagePreview" alt="Image Preview" />
+    </div>
+  </div>
+
+  <div class="input-container">
+    <ion-item>
+      <ion-input [(ngModel)]="newPost.text" placeholder="写下你的动态..."></ion-input>
+    </ion-item>
+    
+    <ion-item>
+      <input type="file" (change)="onFileSelected($event)" accept="image/*" />
+    </ion-item>
+    
+    <ion-item>
+      <ion-button (click)="submitPost()" color="primary">发布</ion-button>
+    </ion-item>
+  </div>
+</ion-content>

+ 36 - 0
TFPower-app/src/app/share-page/share-page.component.scss

@@ -0,0 +1,36 @@
+// .image-preview {
+//     margin: 16px 0;
+//   }
+  
+//   .image-preview img {
+//     max-width: 100%; /* 确保图片不会超出容器 */
+//     height: auto; /* 保持图片的纵横比 */
+//     border-radius: 8px; /* 可选:添加圆角 */
+//   }
+
+.share-content {
+  background-color: #fff3e0; /* 浅橙色背景 */
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between; /* 使内容分布在顶部和底部 */
+}
+
+.image-preview-container {
+  flex: 1; /* 让预览区域占据剩余空间 */
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-bottom: 16px; /* 底部间距 */
+}
+
+.image-preview {
+  max-width: 100%;
+  height: auto;
+  border-radius: 8px; /* 预览图片圆角 */
+}
+
+.input-container {
+  padding: 16px; /* 内边距 */
+  background-color: #ffffff; /* 白色背景 */
+  border-top: 1px solid #ddd; /* 顶部边框 */
+}

+ 24 - 0
TFPower-app/src/app/share-page/share-page.component.spec.ts

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

+ 53 - 0
TFPower-app/src/app/share-page/share-page.component.ts

@@ -0,0 +1,53 @@
+import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import { PostService } from '../post.service'; // 导入服务
+import { IonBackButton, IonButton, IonButtons, IonContent, IonHeader, IonInput, IonItem, IonTitle, IonToolbar } from '@ionic/angular/standalone';
+import { FormsModule } from '@angular/forms';
+import { CommonModule } from '@angular/common';
+
+@Component({
+  selector: 'app-share-page',
+  templateUrl: './share-page.component.html',
+  styleUrls: ['./share-page.component.scss'],
+  standalone: true,
+  imports: [IonHeader,IonToolbar,IonButtons,IonBackButton,IonContent,IonItem,IonInput,
+    IonButton,FormsModule,CommonModule,IonTitle
+    ],
+})
+export class SharePageComponent  implements OnInit {
+
+  newPost: { text: string } = { text: '' };
+  selectedFile: File | null = null; // 存储选择的文件
+  imagePreview: string | null = null; // 存储图片预览的 URL
+
+  constructor(private router: Router,private postService: PostService) {}
+
+  onFileSelected(event: Event) {
+    const target = event.target as HTMLInputElement;
+    if (target.files && target.files.length > 0) {
+      this.selectedFile = target.files[0]; // 获取选择的文件
+      const reader = new FileReader();
+      reader.onload = () => {
+        this.imagePreview = reader.result as string; // 设置图片预览
+      };
+      reader.readAsDataURL(this.selectedFile); // 读取文件为 Data URL
+    }
+  }
+
+  submitPost() {
+    if (this.newPost.text.trim()) {
+      const newPostObj = {
+        id: Math.floor(Math.random() * 10000), // 生成一个随机 ID,实际应用中可以使用更可靠的方式
+        username: '当前用户', // 可以替换为实际的用户名
+        date: new Date(),
+        text: this.newPost.text,
+        imageUrl: this.imagePreview?this.imagePreview:" ", // 将图片 URL 添加到新动态中
+      };
+      this.postService.addPost(newPostObj); // 使用服务添加新动态
+      this.router.navigate(['/community']); // 发布后返回社区页面
+    }
+  }
+
+  ngOnInit() {}
+
+}

+ 5 - 3
TFPower-app/src/app/tab3/tab3.page.html

@@ -1,4 +1,4 @@
-<ion-header [translucent]="true">
+<!-- <ion-header [translucent]="true">
   <ion-toolbar>
     <ion-title>动态</ion-title>
   </ion-toolbar>
@@ -37,7 +37,7 @@
             {{ post.liked ? '取消点赞' : '点赞' }}
             <!-- <ion-icon slot="start" name="thumbs-up"></ion-icon>
             {{ post.likes.length }} 点赞 -->
-          </ion-button>
+          <!-- </ion-button>
         </div>
         <ion-item>
           <ion-input [(ngModel)]="commentInputs[post.get('objectId')]" placeholder="写评论..."></ion-input>
@@ -57,4 +57,6 @@
       </ion-label>
     </ion-item>
   </ion-list>
-</ion-content>
+</ion-content> --> 
+
+

+ 34 - 34
TFPower-app/src/app/tab3/tab3.page.scss

@@ -1,38 +1,38 @@
-ion-item {
-  margin-bottom: 10px;
-  display: flex;
-  align-items: flex-start; /* 确保头像和内容顶部对齐 */
-}
+// ion-item {
+//   margin-bottom: 10px;
+//   display: flex;
+//   align-items: flex-start; /* 确保头像和内容顶部对齐 */
+// }
 
-ion-avatar {
-  width: 50px;
-  height: 50px;
-}
+// ion-avatar {
+//   width: 50px;
+//   height: 50px;
+// }
 
-h2 {
-  margin: 0;
-  font-size: 1.2em;
-}
+// h2 {
+//   margin: 0;
+//   font-size: 1.2em;
+// }
 
-ion-content {
-  display: flex;
-  flex-direction: column;
-  height: 100%;
-}
-ion-header {
-  z-index: 10;
-}
-.post-input {
-  padding: 10px;
-  background-color: #fff; /* 输入框背景 */
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  z-index: 100;
-}
-.post-list {
-  margin-bottom: 350px; // 留出空间给输入框
-  padding-bottom: 10px; // 确保内容不会被遮挡
-}
+// ion-content {
+//   display: flex;
+//   flex-direction: column;
+//   height: 100%;
+// }
+// ion-header {
+//   z-index: 10;
+// }
+// .post-input {
+//   padding: 10px;
+//   background-color: #fff; /* 输入框背景 */
+//   position: fixed;
+//   bottom: 0;
+//   left: 0;
+//   right: 0;
+//   z-index: 100;
+// }
+// .post-list {
+//   margin-bottom: 350px; // 留出空间给输入框
+//   padding-bottom: 10px; // 确保内容不会被遮挡
+// }
 

+ 14 - 14
TFPower-app/src/app/tab3/tab3.page.spec.ts

@@ -1,18 +1,18 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
+// import { ComponentFixture, TestBed } from '@angular/core/testing';
 
-import { Tab3Page } from './tab3.page';
+// import { Tab3Page } from './tab3.page';
 
-describe('Tab3Page', () => {
-  let component: Tab3Page;
-  let fixture: ComponentFixture<Tab3Page>;
+// describe('Tab3Page', () => {
+//   let component: Tab3Page;
+//   let fixture: ComponentFixture<Tab3Page>;
 
-  beforeEach(async () => {
-    fixture = TestBed.createComponent(Tab3Page);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
+//   beforeEach(async () => {
+//     fixture = TestBed.createComponent(Tab3Page);
+//     component = fixture.componentInstance;
+//     fixture.detectChanges();
+//   });
 
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
+//   it('should create', () => {
+//     expect(component).toBeTruthy();
+//   });
+// });

+ 151 - 148
TFPower-app/src/app/tab3/tab3.page.ts

@@ -1,170 +1,173 @@
-import { Component, OnInit } from '@angular/core';
-import { IonAvatar, IonButton, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonContent, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonTitle, IonToolbar } from '@ionic/angular/standalone';
-import { CloudQuery } from 'src/lib/ncloud';
-import { CloudUser } from 'src/lib/ncloud';
-import { CloudObject } from 'src/lib/ncloud';
-import { CommonModule } from '@angular/common';
-import { FormsModule } from '@angular/forms';
-@Component({
-  selector: 'app-tab3',
-  templateUrl: 'tab3.page.html',
-  styleUrls: ['tab3.page.scss'],
-  standalone: true,
-  imports:[IonHeader,IonToolbar,IonTitle,IonContent,IonCard,IonCardSubtitle
-    ,IonCardHeader,IonCardTitle,IonCardContent,CommonModule,FormsModule,
-    IonList,IonItem,IonAvatar,IonLabel,IonButton
-    ,IonIcon
-  ]
-})
-export class Tab3Page {
-  posts: any[] = [];
-  currentUser: CloudUser | undefined;
-  newPostContent: string = ''; // 用于存储新动态的内容
-  newPostImageUrl: string = ''; // 用于存储新动态的图片 URL(可选)
-  commentInputs: { [key: string]: string } = {}; // 用于存储每个帖子的评论内容
-  // commentsMap: { [key: string]: any[] } = {}; // 用于存储每个帖子的评论列表
+// import { Component, OnInit } from '@angular/core';
+// import { IonAvatar, IonButton, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonContent, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonTitle, IonToolbar } from '@ionic/angular/standalone';
+// import { CloudQuery } from 'src/lib/ncloud';
+// import { CloudUser } from 'src/lib/ncloud';
+// import { CloudObject } from 'src/lib/ncloud';
+// import { CommonModule } from '@angular/common';
+// import { FormsModule } from '@angular/forms';
+// @Component({
+//   selector: 'app-tab3',
+//   templateUrl: 'tab3.page.html',
+//   styleUrls: ['tab3.page.scss'],
+//   standalone: true,
+//   imports:[IonHeader,IonToolbar,IonTitle,IonContent,IonCard,IonCardSubtitle
+//     ,IonCardHeader,IonCardTitle,IonCardContent,CommonModule,FormsModule,
+//     IonList,IonItem,IonAvatar,IonLabel,IonButton
+//     ,IonIcon
+//   ]
+// })
+// export class Tab3Page {
+//   posts: any[] = [];
+//   currentUser: CloudUser | undefined;
+//   newPostContent: string = ''; // 用于存储新动态的内容
+//   newPostImageUrl: string = ''; // 用于存储新动态的图片 URL(可选)
+//   commentInputs: { [key: string]: string } = {}; // 用于存储每个帖子的评论内容
+//   // commentsMap: { [key: string]: any[] } = {}; // 用于存储每个帖子的评论列表
   
-  constructor() {
-    this.currentUser = new CloudUser();
-  }
-
-  async ngOnInit() {
-    this.loadPosts();
-  }
-
-  async loadPosts() {
-    const postQuery = new CloudQuery('Post');
-    postQuery.include("user_id")
-    this.posts = await postQuery.find();
+//   constructor() {
+//     this.currentUser = new CloudUser();
+//   }
+
+//   async ngOnInit() {
+//     this.loadPosts();
+//   }
+
+//   async loadPosts() {
+//     const postQuery = new CloudQuery('Post');
+//     postQuery.include("user_id")
+//     this.posts = await postQuery.find();
     
-    console.log("获取的帖子:", this.posts); // 调试信息
-
-    // 获取用户信息并添加到帖子中
-    for (let post of this.posts) {
-      // 获取该帖子的点赞用户信息
-      console.log(post.id)
-      this.getLikesForPost(post.id) || []; 
-      // console.log("获取的点赞信息:", a); // 调试信息
-      // 获取该帖子的评论信息
-      this.getCommentsForPost(post.id).then(comments=>{
-        post.comments = comments
-      }); // 直接将评论存储到 post 对象中
-      // console.log("获取的评论信息:", post.comments); // 调试信息
+//     console.log("获取的帖子:", this.posts); // 调试信息
+
+//     // 获取用户信息并添加到帖子中
+//     for (let post of this.posts) {
+//       // 获取该帖子的点赞用户信息
+//       console.log(post.id)
+//       let likes=this.getLikesForPost(post.id) || []; 
+//       post.likeCount=likes?.length
+//       // console.log("获取的点赞信息:", a); // 调试信息
+//       // 获取该帖子的评论信息
+//       this.getCommentsForPost(post.id).then(comments=>{
+//         post.comments = comments
+//       }); // 直接将评论存储到 post 对象中
+//       // console.log("获取的评论信息:", post.comments); // 调试信息
      
       
-     // 获取所有评论
-    //  this.commentsMap = {};
-    //  for (let post of this.posts) {
-      //  this.commentsMap[post.objectId] = await this.getCommentsForPost(post.objectId);
-    //  }
+//      // 获取所有评论
+//     //  this.commentsMap = {};
+//     //  for (let post of this.posts) {
+//       //  this.commentsMap[post.objectId] = await this.getCommentsForPost(post.objectId);
+//     //  }
     
-    }
-  }
+//     }
+//   }
   
 
 
 
-// 获取某个帖子的评论
-async getCommentsForPost(postId: string) {
-  const commentsQuery = new CloudQuery('Comments');
-  commentsQuery.include("user_id")
-  commentsQuery.equalTo('post_id', postId );
-  const comments = await commentsQuery.find();
+// // 获取某个帖子的评论
+// async getCommentsForPost(postId: string) {
+//   const commentsQuery = new CloudQuery('Comments');
+//   commentsQuery.include("user_id")
+//   commentsQuery.equalTo('post_id', postId );
+//   const comments = await commentsQuery.find();
 
-  console.log("获取的评论:", comments); // 查看获取的评论
+//   console.log("获取的评论:", comments); // 查看获取的评论
 
-  return comments; // 返回评论的详细信息
-}
+//   return comments; // 返回评论的详细信息
+// }
 
- // 获取某个帖子的点赞用户信息
-async getLikesForPost(postId: string) {
-  const likesQuery = new CloudQuery('Likes');
-  likesQuery.equalTo('post_id', postId );
-  const likes = await likesQuery.find();
-  return likes
-  ; // 返回点赞人的详细信息
-}
+//  // 获取某个帖子的点赞用户信息
+// async getLikesForPost(postId: string) {
+//   const likesQuery = new CloudQuery('Likes');
+//   likesQuery.include("user_id")
+//   likesQuery.equalTo('post_id', postId );
+//   const likes = await likesQuery.find();
+//   return likes
+//   ; // 返回点赞人的详细信息
+// }
 
-async publishPost() {
+// async publishPost() {
 
-    // console.log(this.newPostContent);
+//     // console.log(this.newPostContent);
     
-    if (!this.newPostContent) {
-      console.error("动态内容不能为空");
-      return;
-    }
-
-    // 创建新的帖子对象
-    const post = new CloudObject('Post');
-    post.set({
-      content: this.newPostContent,
-      image_url: this.newPostImageUrl || '', // 如果有图片 URL,则使用
-      user_id:   this.currentUser?.id,
-    });
-
-    await post.save(); // 保存动态
-
-    // 清空输入框
-    this.newPostContent = '';
-    this.newPostImageUrl = '';
-
-    // 重新加载动态列表
-    await this.loadPosts();
-  }
-
-async likePost(postId: string) {
-    if (!postId) {
-      console.error(postId);
-      return;
-      } 
+//     if (!this.newPostContent) {
+//       console.error("动态内容不能为空");
+//       return;
+//     }
+
+//     // 创建新的帖子对象
+//     const post = new CloudObject('Post');
+//     post.set({
+//       content: this.newPostContent,
+//       image_url: this.newPostImageUrl || '', // 如果有图片 URL,则使用
+//       user_id:   this.currentUser?.id,
+//     });
+
+//     await post.save(); // 保存动态
+
+//     // 清空输入框
+//     this.newPostContent = '';
+//     this.newPostImageUrl = '';
+
+//     // 重新加载动态列表
+//     await this.loadPosts();
+//   }
+
+// async likePost(postId: string) {
+//     if (!postId) {
+//       console.error(postId);
+//       return;
+//       } 
     
-       // 创建新的点赞记录
-    const like = new CloudObject('Likes');
-    like.set({
-      post_id:  postId ,
-      user_id: this.currentUser?.id ,
-    });
+//        // 创建新的点赞记录
+//     const like = new CloudObject('Likes');
+//     like.set({
+//       post_id:  postId ,
+//       user_id: this.currentUser?.id ,
+//     });
 
-    await like.save(); // 保存点赞记录
+//     await like.save(); // 保存点赞记录
 
 
-    // 更新本地状态
-    await this.loadPosts(); // 重新加载帖子以更新点赞状态
-  }
+//     // 更新本地状态
+//     await this.loadPosts(); // 重新加载帖子以更新点赞状态
+//   }
 
-async commentOnPost(postId: string, comment: string) {
+// async commentOnPost(postId: string, comment: string) {
 
-    if (!postId || !comment) {
-      console.error("postId or comment is undefined");
-      return;
-  }
+//     if (!postId || !comment) {
+//       console.error("postId or comment is undefined");
+//       return;
+//   }
     
-// 创建新的评论对象
-const commentObj = new CloudObject('Comments');
-commentObj.set({
-  post_id: postId ,
-  user_id:  this.currentUser?.id ,
-  content: comment,
-});
-
-await commentObj.save(); // 保存评论记录
-
-
-    // 更新本地状态
-   await this.loadPosts(); // 重新加载帖子以更新评论
-  }
-
-  // 处理文件选择
-handleFileInput(event: any) {
-    const file = event.target.files[0];
-    if (file) {
-      const reader = new FileReader();
-      reader.onload = (e: any) => {
-        this.newPostImageUrl = e.target.result; // 将图像数据设置为 Base64 格式
-      };
-      reader.readAsDataURL(file); // 读取文件为 Base64
-    }
-  }
-
-
-}
+// // 创建新的评论对象
+// const commentObj = new CloudObject('Comments');
+// commentObj.set({
+//   post_id: postId ,
+//   user_id:  this.currentUser?.id ,
+//   content: comment,
+// });
+
+// await commentObj.save(); // 保存评论记录
+
+
+//     // 更新本地状态
+//    await this.loadPosts(); // 重新加载帖子以更新评论
+//   }
+
+//   // 处理文件选择
+// handleFileInput(event: any) {
+//     const file = event.target.files[0];
+//     if (file) {
+//       const reader = new FileReader();
+//       reader.onload = (e: any) => {
+//         this.newPostImageUrl = e.target.result; // 将图像数据设置为 Base64 格式
+//       };
+//       reader.readAsDataURL(file); // 读取文件为 Base64
+//     }
+//   }
+
+
+// }
+

+ 1 - 1
TFPower-app/src/app/tabs/tabs.page.html

@@ -10,7 +10,7 @@
       <ion-label>运动</ion-label>
     </ion-tab-button>
 
-    <ion-tab-button tab="tab3" href="/tabs/tab3">
+    <ion-tab-button tab="community" href="/tabs/community">
       <ion-icon aria-hidden="true" name="people"></ion-icon>
       <ion-label>社区</ion-label>
     </ion-tab-button>

+ 17 - 2
TFPower-app/src/app/tabs/tabs.routes.ts

@@ -21,10 +21,25 @@ export const routes: Routes = [
         loadComponent: () =>
           import('../tab2/test-page/test-page.component').then((m) => m.TestPageComponent),
       },
+      // {
+      //   path: 'tab3',
+      //   loadComponent: () =>
+      //     import('../tab3/tab3.page').then((m) => m.Tab3Page),
+      // },
       {
-        path: 'tab3',
+        path: 'community',
         loadComponent: () =>
-          import('../tab3/tab3.page').then((m) => m.Tab3Page),
+          import('../community/community.page').then((m) => m.CommunityPage),
+      },
+      {
+        path: 'post-page',
+        loadComponent: () =>
+          import('../post-page/post-page.component').then((m) => m.PostPageComponent),
+      },
+      {
+        path: 'share-page',
+        loadComponent: () =>
+          import('../share-page/share-page.component').then((m) => m.SharePageComponent),
       },
       {
         path: 'tab4',