FelixTDT před 4 měsíci
rodič
revize
2d9c06314b
39 změnil soubory, kde provedl 1320 přidání a 132 odebrání
  1. 8 4
      src/app/app-routing.module.ts
  2. 17 0
      src/app/home - 副本/home-routing.module.ts
  3. 20 0
      src/app/home - 副本/home.module.ts
  4. 46 0
      src/app/home - 副本/home.page.html
  5. 0 0
      src/app/home - 副本/home.page.scss
  6. 17 0
      src/app/home - 副本/home.page.spec.ts
  7. 36 0
      src/app/home - 副本/home.page.ts
  8. 8 1
      src/app/home/home.page.html
  9. 56 25
      src/app/home/home.page.ts
  10. 21 0
      src/app/services/post.services.ts
  11. 33 0
      src/app/tab2/tab2.page.ts
  12. 32 13
      src/app/tab3/tab3.page.ts
  13. binární
      src/assets/images/123456.png
  14. 1 0
      src/environments/environment.ts
  15. 26 0
      src/modules/create-post/create-post.page.html
  16. 87 0
      src/modules/create-post/create-post.page.ts
  17. 17 0
      src/modules/post-create/post-create-routing.module.ts
  18. 20 0
      src/modules/post-create/post-create.module.ts
  19. 25 0
      src/modules/post-create/post-create.page.html
  20. 0 0
      src/modules/post-create/post-create.page.scss
  21. 17 0
      src/modules/post-create/post-create.page.spec.ts
  22. 104 0
      src/modules/post-create/post-create.page.ts
  23. 17 0
      src/modules/post-detail - 副本/post-detail-routing.module.ts
  24. 20 0
      src/modules/post-detail - 副本/post-detail.module.ts
  25. 75 0
      src/modules/post-detail - 副本/post-detail.page.html
  26. 14 0
      src/modules/post-detail - 副本/post-detail.page.scss
  27. 17 0
      src/modules/post-detail - 副本/post-detail.page.spec.ts
  28. 45 0
      src/modules/post-detail - 副本/post-detail.page.ts
  29. 46 10
      src/modules/post-detail/post-detail.page.html
  30. 260 19
      src/modules/post-detail/post-detail.page.ts
  31. 1 0
      src/modules/study/case-js-module/case-parse/case-parse.page.ts
  32. 2 2
      src/modules/user/README.md
  33. 17 0
      src/modules/user/login - 副本/login-routing.module.ts
  34. 20 0
      src/modules/user/login - 副本/login.module.ts
  35. 33 0
      src/modules/user/login - 副本/login.page.html
  36. 0 0
      src/modules/user/login - 副本/login.page.scss
  37. 17 0
      src/modules/user/login - 副本/login.page.spec.ts
  38. 93 0
      src/modules/user/login - 副本/login.page.ts
  39. 52 58
      src/modules/user/login/login.page.ts

+ 8 - 4
src/app/app-routing.module.ts

@@ -10,10 +10,10 @@ const routes: Routes = [
     path: 'user',
     loadChildren: () => import('../modules/user/user.module').then(m => m.UserModule)
   },
-  // {
-  //   path: 'home',
-  //   loadChildren: () => import('./home/home.module').then( m => m.HomePageModule)
-  // }
+  {
+    path: 'home',
+    loadChildren: () => import('./home/home.module').then( m => m.HomePageModule)
+  },
   {
     path: 'login',
     loadChildren: () => import('../modules/user/login/login.module').then(m => m.LoginPageModule)
@@ -26,6 +26,10 @@ const routes: Routes = [
     path: 'post-detail/:id',
     loadChildren: () => import('../modules/post-detail/post-detail.module').then( m => m.PostDetailPageModule)
   },
+  {
+    path: 'post-create',
+    loadChildren: () => import('../modules/post-create/post-create.module').then(m => m.PostCreatePageModule)
+  }
 ];
 @NgModule({
   imports: [

+ 17 - 0
src/app/home - 副本/home-routing.module.ts

@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { HomePage } from './home.page';
+
+const routes: Routes = [
+  {
+    path: '',
+    component: HomePage
+  }
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class HomePageRoutingModule {}

+ 20 - 0
src/app/home - 副本/home.module.ts

@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { IonicModule } from '@ionic/angular';
+
+import { HomePageRoutingModule } from './home-routing.module';
+
+import { HomePage } from './home.page';
+
+@NgModule({
+  imports: [
+    CommonModule,
+    FormsModule,
+    IonicModule,
+    HomePageRoutingModule
+  ],
+  declarations: [HomePage]
+})
+export class HomePageModule {}

+ 46 - 0
src/app/home - 副本/home.page.html

@@ -0,0 +1,46 @@
+<ion-header>
+  <ion-toolbar>
+    <ion-title>推荐</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+  <!-- 顶部导航栏 -->
+  <ion-segment value="recommendations">
+    <ion-segment-button value="recommendations">
+      <ion-label>推荐</ion-label>
+    </ion-segment-button>
+    <ion-segment-button value="following">
+      <ion-label>关注</ion-label>
+    </ion-segment-button>
+    <ion-segment-button value="hot">
+      <ion-label>热门</ion-label>
+    </ion-segment-button>
+  </ion-segment>
+
+  <!-- 搜索框 -->
+  <ion-searchbar placeholder="搜索"></ion-searchbar>
+
+  <!-- 内容卡片 -->
+  <ion-card *ngFor="let item of items" (click)="goToPostDetail(item.id)">
+    <ion-card-header>
+      <ion-card-title>{{ item.title }}</ion-card-title>
+      <ion-card-subtitle>{{ item.author }}</ion-card-subtitle>
+    </ion-card-header>
+    <ion-card-content>
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4">
+            <img [src]="item.image" />
+          </ion-col>
+          <ion-col size="8">
+            <p>{{ item.description }}</p>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-card-content>
+    <ion-item lines="none">
+      <ion-label>{{ item.footer }}</ion-label>
+    </ion-item>
+  </ion-card>
+</ion-content>

+ 0 - 0
src/app/home - 副本/home.page.scss


+ 17 - 0
src/app/home - 副本/home.page.spec.ts

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

+ 36 - 0
src/app/home - 副本/home.page.ts

@@ -0,0 +1,36 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+
+@Component({
+  selector: 'app-home',
+  templateUrl: 'home.page.html',
+  styleUrls: ['home.page.scss']
+})
+export class HomePage {
+
+  items = [
+    {
+      id: 1,
+      title: "是什么让“牢大”科比,成了中文互联网最热门的流量密码?",
+      author: "BB姬",
+      image: "assets/images/kobe.jpg",
+      description: "本文首发于微信公众号“BB姬”(bibiji300)真新镇小茂|文 2015年,网络游戏主播李赣组织孙笑川等人,成...",
+      footer: "4076 赞同 · 1696 收藏"
+    },
+    {
+      id: 2,
+      title: "汪汪:姜萍事件很快就会有结果,做点分析预测",
+      author: "科学声音",
+      image: "assets/images/jiangping.jpg",
+      description: "阿里达摩院在6.21发布了决赛通知,确认姜萍参赛。今天是6.24,姜萍考试结束,我觉得我可以写点东西了。前...",
+      footer: "1049 赞同 · 469 评论"
+    }
+  ];
+  constructor(private router: Router) {} // 确保 Router 被正确引入
+
+  // constructor() {}
+
+  goToPostDetail(id: number) {
+    this.router.navigate(['/post-detail', id]);
+  }
+}

+ 8 - 1
src/app/home/home.page.html

@@ -25,7 +25,7 @@
   <ion-card *ngFor="let item of items" (click)="goToPostDetail(item.id)">
     <ion-card-header>
       <ion-card-title>{{ item.title }}</ion-card-title>
-      <ion-card-subtitle>{{ item.author }}</ion-card-subtitle>
+      <ion-card-subtitle>{{ item.author.username }}</ion-card-subtitle>
     </ion-card-header>
     <ion-card-content>
       <ion-grid>
@@ -44,3 +44,10 @@
     </ion-item>
   </ion-card>
 </ion-content>
+
+<!-- 悬浮加号按钮 -->
+<ion-fab vertical="bottom" horizontal="end" slot="fixed">
+  <ion-fab-button (click)="createPost()">
+    <ion-icon name="add"></ion-icon>
+  </ion-fab-button>
+</ion-fab>

+ 56 - 25
src/app/home/home.page.ts

@@ -1,36 +1,67 @@
-import { Component } from '@angular/core';
-import { Router } from '@angular/router';
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import * as Parse from 'parse';
 
 @Component({
   selector: 'app-home',
   templateUrl: 'home.page.html',
   styleUrls: ['home.page.scss']
 })
-export class HomePage {
-
-  items = [
-    {
-      id: 1,
-      title: "是什么让“牢大”科比,成了中文互联网最热门的流量密码?",
-      author: "BB姬",
-      image: "assets/images/kobe.jpg",
-      description: "本文首发于微信公众号“BB姬”(bibiji300)真新镇小茂|文 2015年,网络游戏主播李赣组织孙笑川等人,成...",
-      footer: "4076 赞同 · 1696 收藏"
-    },
-    {
-      id: 2,
-      title: "汪汪:姜萍事件很快就会有结果,做点分析预测",
-      author: "科学声音",
-      image: "assets/images/jiangping.jpg",
-      description: "阿里达摩院在6.21发布了决赛通知,确认姜萍参赛。今天是6.24,姜萍考试结束,我觉得我可以写点东西了。前...",
-      footer: "1049 赞同 · 469 评论"
-    }
-  ];
-  constructor(private router: Router) {} // 确保 Router 被正确引入
+export class HomePage implements OnInit {
+
+  items: any[] = [];
+  newPostId: string = '';
+
+  constructor(private router: Router, private route: ActivatedRoute) {
+    // 初始化 Parse
+  }
 
-  // constructor() {}
+  ngOnInit() {
+    this.route.queryParams.subscribe(params => {
+      if (params["postId"]) {
+        this.newPostId = params["postId"];
+      }
+    });
+    this.fetchPosts();
+  }
+
+  ionViewWillEnter() {
+    this.fetchPosts(); // 确保每次进入首页时都会加载最新的帖子
+  }
 
-  goToPostDetail(id: number) {
+  async fetchPosts() {
+    const Post = Parse.Object.extend("Post240709");
+    const query = new Parse.Query(Post);
+
+    try {
+      const results = await query.find();
+      this.items = results.map(post => ({
+        id: post.id,
+        title: post.get('title'),
+        author: post.get('author'),
+        image: post.get('image'),
+        description: post.get('description'),
+        footer: `${post.get('likes')} 赞同 · ${post.get('comments')} 评论`
+      }));
+      if (this.newPostId) {
+        const newPost = this.items.find(post => post.id === this.newPostId);
+        if (newPost) {
+          // 可以在这里高亮新发布的帖子或者滚动到新发布的帖子位置
+          console.log('New post published:', newPost);
+        }
+        this.newPostId = ''; // 重置 newPostId
+      }
+    } catch (error) {
+      console.error("Error while fetching posts", error);
+    }
+  }
+
+  goToPostDetail(id: string) {
     this.router.navigate(['/post-detail', id]);
   }
+
+  createPost() {
+    this.router.navigate(['/post-create']);
+  }
+  
 }

+ 21 - 0
src/app/services/post.services.ts

@@ -0,0 +1,21 @@
+import { Injectable } from '@angular/core';
+import Parse from 'parse';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class PostService {
+  async getPost(postId: string): Promise<any> {
+    const query = new Parse.Query('Posts');
+    query.equalTo('objectId', postId);
+    const post = await query.first();
+    return post ? post.toJSON() : null;
+  }
+
+  async getComments(postId: string): Promise<any[]> {
+    const query = new Parse.Query('Comment');
+    query.equalTo('post', new Parse.Object('Posts', { id: postId }));
+    const comments = await query.find();
+    return comments.map(comment => comment.toJSON());
+  }
+}

+ 33 - 0
src/app/tab2/tab2.page.ts

@@ -1,4 +1,6 @@
 import { Component } from '@angular/core';  
+import * as Parse from 'parse';
+
   
 @Component({  
   selector: 'app-tab2',  
@@ -7,7 +9,37 @@ import { Component } from '@angular/core';
 })  
 export class Tab2Page {  
   selectedSegment: string = 'invitations';  
+  async generateTestData() {
+    const currentUser = Parse.User.current();
+    if (!currentUser) {
+      console.error('No user logged in. Please log in to create test data.');
+      return;
+    }
   
+    const fixedImageUrl = 'assets/images/kobe.jpg';
+    const randomNews = [
+      "是什么让“牢大”科比,成了中文互联网最热门的流量密码?\n本文首发于微信公众号“BB姬”(bibiji300)真新镇小茂|文 2015年,网络游戏主播李赣组织孙笑川等人,成...",
+      "汪汪:姜萍事件很快就会有结果,做点分析预测\n阿里达摩院在6.21发布了决赛通知,确认姜萍参赛。今天是6.24,姜萍考试结束,我觉得我可以写点东西了。前..."
+    ];
+  
+    for (let i = 0; i < 3; i++) {
+      const Post240709 = Parse.Object.extend('Post240709');
+      const post = new Post240709();
+  
+      post.set('author', {username:currentUser.getUsername(),avatarUrl:'https://pics0.baidu.com/feed/2cf5e0fe9925bc31187a4ea7cc89c7bfcb13704a.jpeg'});
+      post.set('content', randomNews[Math.floor(Math.random() * randomNews.length)]);
+      post.set('image', fixedImageUrl);
+      post.set('title', `测试帖子${i + 1}`);
+      post.set('likes', Math.floor(Math.random() * 1000)); // 随机生成 0-999 的赞同数
+  
+      try {
+        await post.save();
+        console.log(`Test post ${i + 1} created successfully.`);
+      } catch (error) {
+        console.error('Error while creating test post:', error);
+      }
+    }
+  }
   invitationMessages = [  
     { inviter: { username: 'Alice' }, question: 'How to use Ionic v7?', time: new Date() },  
     // 更多邀请消息...  
@@ -25,5 +57,6 @@ export class Tab2Page {
   
   segmentChanged(event: CustomEvent) {  
     this.selectedSegment = event.detail.value;  
+    this.generateTestData();
   }  
 }

+ 32 - 13
src/app/tab3/tab3.page.ts

@@ -1,29 +1,48 @@
-import { Component } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
 import { NavController } from '@ionic/angular';
+import * as Parse from 'parse';
 
 @Component({
   selector: 'app-tab3',
   templateUrl: './tab3.page.html',
   styleUrls: ['./tab3.page.scss'],
 })
-export class Tab3Page {
-  userInfo: any = {
-    username: 'Faraday',
-    nickname: '点击查看个人主页',
-    avatarUrl: '/assets/images/avatar.png',
-    followers: 10086,
-    following: 129,
-    favorites: 7,
-    recentViews: 2917
-  };
+export class Tab3Page implements OnInit {
+  userInfo: any = {};
 
   constructor(private navCtrl: NavController) {}
-  //编辑资料
+
+  ngOnInit() {
+    this.loadUserInfo();
+  }
+
+  async loadUserInfo() {
+    const currentUser = Parse.User.current();
+    if (currentUser) {
+      const query = new Parse.Query('_User');
+      try {
+        const user = await query.get(currentUser.id);
+        this.userInfo = {
+          username: user.get('username'),
+          nickname: user.get('nickname') || '点击查看个人主页',
+          avatarUrl: user.get('avatarUrl') || '/assets/images/avatar.png',
+          followers: user.get('followers') || 0,
+          following: user.get('following') || 0,
+          favorites: user.get('favorites') || 0,
+          recentViews: user.get('recentViews') || 0
+        };
+      } catch (error) {
+        console.error('Error while fetching user data', error);
+      }
+    } else {
+      this.navigateToLogin();
+    }
+  }
+
   navigateToEditInfo() {
     this.navCtrl.navigateForward('/edit-info');
   }
 
-  //新增,登录
   navigateToLogin() {
     this.navCtrl.navigateForward('/login');
   }

binární
src/assets/images/123456.png


+ 1 - 0
src/environments/environment.ts

@@ -4,6 +4,7 @@
 
 export const environment = {
   production: false
+
 };
 
 /*

+ 26 - 0
src/modules/create-post/create-post.page.html

@@ -0,0 +1,26 @@
+<ion-header>
+    <ion-toolbar>
+      <ion-buttons slot="start">
+        <ion-back-button defaultHref="/home"></ion-back-button>
+      </ion-buttons>
+      <ion-title>创建帖子</ion-title>
+    </ion-toolbar>
+  </ion-header>
+  
+  <ion-content>
+    <ion-item>
+      <ion-label position="floating">标题</ion-label>
+      <ion-input [(ngModel)]="title"></ion-input>
+    </ion-item>
+  
+    <ion-item>
+      <ion-label position="floating">正文</ion-label>
+      <ion-textarea [(ngModel)]="content"></ion-textarea>
+    </ion-item>
+  
+    <ion-button expand="block" (click)="uploadImage()">上传图片</ion-button>
+    <ion-img [src]="image" *ngIf="image"></ion-img>
+  
+    <ion-button expand="block" (click)="submitPost()">发布</ion-button>
+  </ion-content>
+  

+ 87 - 0
src/modules/create-post/create-post.page.ts

@@ -0,0 +1,87 @@
+import { Component } from '@angular/core';
+import { NavController, AlertController } from '@ionic/angular';
+import Parse from 'parse';
+
+@Component({
+  selector: 'app-create-post',
+  templateUrl: './create-post.page.html',
+  styleUrls: ['./create-post.page.scss'],
+})
+export class CreatePostPage {
+  title: string = '';
+  content: string = '';
+  image: string = '';
+
+  constructor(private navCtrl: NavController, private alertCtrl: AlertController) {}
+
+  async uploadImage() {
+    // 实现上传图片的逻辑
+    const alert = await this.alertCtrl.create({
+      header: '上传图片',
+      inputs: [
+        {
+          name: 'imageUrl',
+          type: 'url',
+          placeholder: '输入图片URL'
+        }
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel'
+        },
+        {
+          text: '上传',
+          handler: (data) => {
+            this.image = data.imageUrl;
+          }
+        }
+      ]
+    });
+
+    await alert.present();
+  }
+
+  async submitPost() {
+    if (!this.title || !this.content) {
+      const alert = await this.alertCtrl.create({
+        header: '错误',
+        message: '标题和正文不能为空',
+        buttons: ['确定']
+      });
+      await alert.present();
+      return;
+    }
+
+    const currentUser = Parse.User.current();
+    if (!currentUser) {
+      const alert = await this.alertCtrl.create({
+        header: '错误',
+        message: '请先登录',
+        buttons: ['确定']
+      });
+      await alert.present();
+      return;
+    }
+
+    const Post240709 = Parse.Object.extend('Post240709');
+    const post = new Post240709();
+    post.set('title', this.title);  
+    post.set('content', this.content);
+    post.set('imageUrl', this.image);
+    post.set('author', currentUser);
+
+    try {
+      await post.save();
+      this.navCtrl.navigateBack('/home');
+    } catch (error) {
+      console.error('Error while creating post:', error);
+      const alert = await this.alertCtrl.create({
+        header: '错误',
+        message: '发布失败,请重试',
+        buttons: ['确定']
+      });
+      await alert.present();
+    }
+  }
+}

+ 17 - 0
src/modules/post-create/post-create-routing.module.ts

@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { PostCreatePage } from './post-create.page';
+
+const routes: Routes = [
+  {
+    path: '',
+    component: PostCreatePage
+  }
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class PostCreatePageRoutingModule {}

+ 20 - 0
src/modules/post-create/post-create.module.ts

@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { IonicModule } from '@ionic/angular';
+
+import { PostCreatePageRoutingModule } from './post-create-routing.module';
+
+import { PostCreatePage } from './post-create.page';
+
+@NgModule({
+  imports: [
+    CommonModule,
+    FormsModule,
+    IonicModule,
+    PostCreatePageRoutingModule
+  ],
+  declarations: [PostCreatePage]
+})
+export class PostCreatePageModule {}

+ 25 - 0
src/modules/post-create/post-create.page.html

@@ -0,0 +1,25 @@
+<ion-header>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-back-button defaultHref="/home"></ion-back-button>
+    </ion-buttons>
+    <ion-title>创建帖子</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+  <ion-item>
+    <ion-label position="floating">标题</ion-label>
+    <ion-input [(ngModel)]="title"></ion-input>
+  </ion-item>
+
+  <ion-item>
+    <ion-label position="floating">正文</ion-label>
+    <ion-textarea [(ngModel)]="content"></ion-textarea>
+  </ion-item>
+
+  <ion-button expand="block" (click)="uploadImage()">上传图片</ion-button>
+  <ion-img [src]="image" *ngIf="image"></ion-img>
+
+  <ion-button expand="block" (click)="submitPost()">发布</ion-button>
+</ion-content>

+ 0 - 0
src/modules/post-create/post-create.page.scss


+ 17 - 0
src/modules/post-create/post-create.page.spec.ts

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

+ 104 - 0
src/modules/post-create/post-create.page.ts

@@ -0,0 +1,104 @@
+import { Component } from '@angular/core';
+import { NavController, AlertController } from '@ionic/angular';
+import Parse from 'parse';
+
+@Component({
+  selector: 'app-post-create',
+  templateUrl: './post-create.page.html',
+  styleUrls: ['./post-create.page.scss'],
+})
+export class PostCreatePage {
+  title: string = '';
+  content: string = '';
+  image: string = '';
+
+  constructor(private navCtrl: NavController, private alertCtrl: AlertController) {}
+
+  async uploadImage() {
+    // 实现上传图片的逻辑
+    const alert = await this.alertCtrl.create({
+      header: '上传图片',
+      inputs: [
+        {
+          name: 'imageUrl',
+          type: 'url',
+          placeholder: '输入图片URL'
+        }
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel'
+        },
+        {
+          text: '上传',
+          handler: (data) => {
+            this.image = data.imageUrl;
+          }
+        }
+      ]
+    });
+
+    await alert.present();
+  }
+
+  async submitPost() {
+    if (!this.title || !this.content) {
+      const alert = await this.alertCtrl.create({
+        header: '错误',
+        message: '标题和正文不能为空',
+        buttons: ['确定']
+      });
+      await alert.present();
+      return;
+    }
+    
+    const currentUser = Parse.User.current();
+
+    if (!currentUser) {
+      const alert = await this.alertCtrl.create({
+        header: '错误',
+        message: '请先登录',
+        buttons: ['确定']
+      });
+      await alert.present();
+      return;
+    }
+
+    // 获取用户的 username 和 avatarUrl
+    const authorInfo = {
+      username: currentUser.get('username'),
+      avatarUrl: currentUser.get('avatarUrl') || 'assets/images/default-avatar.jpg' // 默认头像路径
+    };
+
+    const Post240709 = Parse.Object.extend('Post240709');
+    const post = new Post240709();
+    post.set('title', this.title);
+    post.set('content', this.content);
+    post.set('imageUrl', this.image);
+    post.set('author', authorInfo); // 设置 author 字段为包含 username 和 avatarUrl 的对象
+
+    try {
+      const savedPost = await post.save();
+      const successAlert = await this.alertCtrl.create({
+        header: '成功',
+        message: '发布成功',
+        buttons: ['确认']
+      });
+      await successAlert.present();
+  
+      // // 延迟一段时间后返回首页
+      // setTimeout(() => {
+      //   this.navCtrl.navigateBack('/home');
+      // }, 1000); // 1秒后返回首页,可以根据需求调整延迟时间
+    } catch (error) {
+      console.error('Error while creating post:', error);
+      const alert = await this.alertCtrl.create({
+        header: '错误',
+        message: '发布失败,请重试',
+        buttons: ['确定']
+      });
+      await alert.present();
+    }
+  }
+}

+ 17 - 0
src/modules/post-detail - 副本/post-detail-routing.module.ts

@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { PostDetailPage } from './post-detail.page';
+
+const routes: Routes = [
+  {
+    path: '',
+    component: PostDetailPage
+  }
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class PostDetailPageRoutingModule {}

+ 20 - 0
src/modules/post-detail - 副本/post-detail.module.ts

@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { IonicModule } from '@ionic/angular';
+
+import { PostDetailPageRoutingModule } from './post-detail-routing.module';
+
+import { PostDetailPage } from './post-detail.page';
+
+@NgModule({
+  imports: [
+    CommonModule,
+    FormsModule,
+    IonicModule,
+    PostDetailPageRoutingModule
+  ],
+  declarations: [PostDetailPage]
+})
+export class PostDetailPageModule {}

+ 75 - 0
src/modules/post-detail - 副本/post-detail.page.html

@@ -0,0 +1,75 @@
+<ion-header>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-back-button defaultHref="/home"></ion-back-button>
+    </ion-buttons>
+    <ion-title>帖子详情</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+  <!-- 内容区 -->
+  <ion-card>
+    <ion-card-header>
+      <ion-item lines="none">
+        <ion-avatar slot="start">
+          <img [src]="post.authorAvatar" />
+        </ion-avatar>
+        <ion-label>
+          <h2>{{ post.author }}</h2>
+          <p>{{ post.time }}</p>
+        </ion-label>
+      </ion-item>
+    </ion-card-header>
+    <ion-card-content>
+      <h2>{{ post.title }}</h2>
+      <img [src]="post.image" *ngIf="post.image" />
+      <p>{{ post.content }}</p>
+    </ion-card-content>
+    <ion-item lines="none">
+      <ion-button fill="clear" slot="start">
+        <ion-icon name="thumbs-up"></ion-icon>
+        <ion-label>点赞</ion-label>
+      </ion-button>
+      <ion-button fill="clear" slot="end">
+        <ion-icon name="share-social"></ion-icon>
+        <ion-label>分享</ion-label>
+      </ion-button>
+    </ion-item>
+  </ion-card>
+
+  <!-- 评论区 -->
+  <ion-segment value="all">
+    <ion-segment-button value="all">
+      <ion-label>全部回复</ion-label>
+    </ion-segment-button>
+    <ion-segment-button value="author">
+      <ion-label>只看楼主</ion-label>
+    </ion-segment-button>
+  </ion-segment>
+
+  <ion-segment value="popular" (ionChange)="sortComments($event)">
+    <ion-segment-button value="popular">
+      <ion-label>热门</ion-label>
+    </ion-segment-button>
+    <ion-segment-button value="asc">
+      <ion-label>时间正序</ion-label>
+    </ion-segment-button>
+    <ion-segment-button value="desc">
+      <ion-label>时间倒序</ion-label>
+    </ion-segment-button>
+  </ion-segment>
+
+  <ion-list>
+    <ion-item *ngFor="let comment of comments">
+      <ion-avatar slot="start">
+        <img [src]="comment.avatar" />
+      </ion-avatar>
+      <ion-label>
+        <h2>{{ comment.author }}</h2>
+        <p>{{ comment.content }}</p>
+        <p>{{ comment.time }}</p>
+      </ion-label>
+    </ion-item>
+  </ion-list>
+</ion-content>

+ 14 - 0
src/modules/post-detail - 副本/post-detail.page.scss

@@ -0,0 +1,14 @@
+ion-avatar img {
+    width: 100%;
+    height: auto;
+  }
+  
+  ion-card h2 {
+    margin: 0;
+    font-size: 1.2em;
+  }
+  
+  ion-card p {
+    margin: 0.5em 0;
+  }
+  

+ 17 - 0
src/modules/post-detail - 副本/post-detail.page.spec.ts

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

+ 45 - 0
src/modules/post-detail - 副本/post-detail.page.ts

@@ -0,0 +1,45 @@
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
+
+@Component({
+  selector: 'app-post-detail',
+  templateUrl: './post-detail.page.html',
+  styleUrls: ['./post-detail.page.scss'],
+})
+export class PostDetailPage implements OnInit {
+  post: any;
+  comments: any[]= [];
+
+  constructor(private route: ActivatedRoute) {}
+
+  ngOnInit() {
+    const postId = this.route.snapshot.paramMap.get('id');
+    // 模拟获取数据,根据实际情况从服务器或本地获取数据
+    this.post = {
+      id: postId,
+      author: '发帖人',
+      authorAvatar: '发帖人头像URL',
+      time: '发帖时间',
+      title: `标题${postId}`,
+      content: `内容${postId}`,
+      image: `图片URL${postId}`
+    };
+
+    this.comments = [
+      { id: 1, author: '用户1', avatar: '用户1头像URL', content: '评论内容1', time: '评论时间1', likes: 10 },
+      { id: 2, author: '用户2', avatar: '用户2头像URL', content: '评论内容2', time: '评论时间2', likes: 5 },
+      // 添加更多评论数据
+    ];
+  }
+
+  sortComments(event: any) {
+    const value = event.detail.value;
+    if (value === 'popular') {
+      this.comments.sort((a, b) => b.likes - a.likes); // 按点赞数排序
+    } else if (value === 'asc') {
+      this.comments.sort((a, b) => new Date(a.time).getTime() - new Date(b.time).getTime()); // 时间正序
+    } else if (value === 'desc') {
+      this.comments.sort((a, b) => new Date(b.time).getTime() - new Date(a.time).getTime()); // 时间倒序
+    }
+  }
+}

+ 46 - 10
src/modules/post-detail/post-detail.page.html

@@ -12,12 +12,12 @@
   <ion-card>
     <ion-card-header>
       <ion-item lines="none">
-        <ion-avatar slot="start">
+        <ion-avatar slot="start" (click)="generateTestComments()">
           <img [src]="post.authorAvatar" />
         </ion-avatar>
         <ion-label>
           <h2>{{ post.author }}</h2>
-          <p>{{ post.time }}</p>
+          <p>{{ post.time | date: 'short' }}</p>
         </ion-label>
       </ion-item>
     </ion-card-header>
@@ -27,14 +27,18 @@
       <p>{{ post.content }}</p>
     </ion-card-content>
     <ion-item lines="none">
-      <ion-button fill="clear" slot="start">
+      <ion-button fill="clear" slot="start" (click)="togglePostLike()">
         <ion-icon name="thumbs-up"></ion-icon>
-        <ion-label>点赞</ion-label>
+        <ion-label>{{ post.likes }} 点赞</ion-label>
       </ion-button>
-      <ion-button fill="clear" slot="end">
+      <ion-button fill="clear" slot="end" (click)="sharePost()">
         <ion-icon name="share-social"></ion-icon>
         <ion-label>分享</ion-label>
       </ion-button>
+      <ion-button fill="clear" slot="end" (click)="replyToPost()">
+        <ion-icon name="chatbubble-ellipses"></ion-icon>
+        <ion-label>回复</ion-label>
+      </ion-button>
     </ion-item>
   </ion-card>
 
@@ -56,20 +60,52 @@
       <ion-label>时间正序</ion-label>
     </ion-segment-button>
     <ion-segment-button value="desc">
-      <ion-label>时间倒序</ion-label>
-    </ion-segment-button>
+      <ion-label>时间倒序</ion-label></ion-segment-button>
   </ion-segment>
 
   <ion-list>
-    <ion-item *ngFor="let comment of comments">
+    <ion-item *ngFor="let comment of comments" (click)="replyToComment(comment)">
       <ion-avatar slot="start">
-        <img [src]="comment.avatar" />
+        <img [src]="comment.authorAvatar" />
       </ion-avatar>
       <ion-label>
         <h2>{{ comment.author }}</h2>
         <p>{{ comment.content }}</p>
-        <p>{{ comment.time }}</p>
+        <p>{{ comment.time | date: 'short' }}</p>
+        <p>楼层: {{ comment.floor }} | 点赞: {{ comment.likes }}</p>
+        <ion-item *ngFor="let reply of comment.replies" lines="none">
+          <ion-label>
+            <small>{{ reply.author }}: {{ reply.content }} - {{ reply.time | date: 'short' }}</small>
+          </ion-label>
+          <ion-button fill="clear" slot="end" (click)="toggleLike(reply)">
+            <ion-icon name="thumbs-up"></ion-icon>
+            <ion-label>{{ reply.likes }}</ion-label>
+          </ion-button>
+          <ion-button fill="clear" slot="end" (click)="replyToComment(reply)">
+            <ion-icon name="chatbubble-ellipses"></ion-icon>
+            <ion-label>回复</ion-label>
+          </ion-button>
+        </ion-item>
       </ion-label>
+      <ion-button fill="clear" slot="end" (click)="toggleLike(comment)">
+        <ion-icon name="thumbs-up"></ion-icon>
+        <ion-label>{{ comment.likes }}</ion-label>
+      </ion-button>
     </ion-item>
   </ion-list>
 </ion-content>
+
+<!-- 分享二维码模态框 -->
+<ion-modal #shareModal>
+  <ion-header>
+    <ion-toolbar>
+      <ion-title>分享帖子</ion-title>
+      <ion-buttons slot="end">
+        <ion-button (click)="shareModal.dismiss()">关闭</ion-button>
+      </ion-buttons>
+    </ion-toolbar>
+  </ion-header>
+  <ion-content>
+    <ion-img src="assets/images/123456.png"></ion-img>
+  </ion-content>
+</ion-modal>

+ 260 - 19
src/modules/post-detail/post-detail.page.ts

@@ -1,5 +1,7 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, ViewChild } from '@angular/core';
 import { ActivatedRoute } from '@angular/router';
+import { AlertController, ModalController } from '@ionic/angular';
+import Parse from 'parse';
 
 @Component({
   selector: 'app-post-detail',
@@ -8,28 +10,84 @@ import { ActivatedRoute } from '@angular/router';
 })
 export class PostDetailPage implements OnInit {
   post: any;
-  comments: any[]= [];
+  comments: any[] = [];
+  @ViewChild('shareModal', { static: true }) shareModal: any;
 
-  constructor(private route: ActivatedRoute) {}
+  constructor(
+    private route: ActivatedRoute,
+    private alertCtrl: AlertController,
+    private modalCtrl: ModalController
+  ) {}
 
   ngOnInit() {
     const postId = this.route.snapshot.paramMap.get('id');
-    // 模拟获取数据,根据实际情况从服务器或本地获取数据
-    this.post = {
-      id: postId,
-      author: '发帖人',
-      authorAvatar: '发帖人头像URL',
-      time: '发帖时间',
-      title: `标题${postId}`,
-      content: `内容${postId}`,
-      image: `图片URL${postId}`
-    };
-
-    this.comments = [
-      { id: 1, author: '用户1', avatar: '用户1头像URL', content: '评论内容1', time: '评论时间1', likes: 10 },
-      { id: 2, author: '用户2', avatar: '用户2头像URL', content: '评论内容2', time: '评论时间2', likes: 5 },
-      // 添加更多评论数据
-    ];
+    if (postId !== null) {
+      this.loadPost(postId);
+      this.loadComments(postId);
+    }
+  }
+
+  async loadPost(postId: string) {
+    const query = new Parse.Query('Post240709');
+    query.include('author');
+    try {
+      const post = await query.get(postId);
+      console.log(post);
+      this.post = {
+        id: post.id,
+        author: post.get('author').username,
+        authorAvatar: post.get('author').avatarUrl,
+        time: post.createdAt,
+        title: post.get('title'),
+        content: post.get('content'),
+        image: post.get('imageUrl'),
+        likes: post.get('likes') || 0
+      };
+    } catch (error) {
+      console.error('Error loading post:', error);
+    }
+  }
+
+  async loadComments(postId: string) {
+    const query = new Parse.Query('Comment240709');
+    query.equalTo('post', {
+      __type: 'Pointer',
+      className: 'Post240709',
+      objectId: postId
+    });
+    query.include('author');
+    query.ascending('createdAt');
+    try {
+      const comments = await query.find();
+      this.comments = await Promise.all(
+        comments.map(async (comment, index) => {
+          const repliesQuery = new Parse.Query('Comment240709');
+          repliesQuery.equalTo('parentComment', comment);
+          repliesQuery.include('author');
+          repliesQuery.ascending('createdAt');
+          const replies = await repliesQuery.find();
+          return {
+            id: comment.id,
+            author: comment.get('author').get("username"),
+            authorAvatar: comment.get('author').get("avatarUrl"),
+            content: comment.get('content'),
+            time: comment.createdAt,
+            likes: comment.get('likes'),
+            floor: index + 1,
+            replies: replies.map(reply => ({
+              id: reply.id,
+              author: reply.get('author').get("username"),
+              authorAvatar: reply.get('author').get("avatarUrl"),
+              content: reply.get('content'),
+              time: reply.createdAt,
+              likes: reply.get('likes')
+            }))
+          };
+        })
+      );
+    } catch (error) {
+      console.error('Error loading comments:', error);
+    }
   }
 
   sortComments(event: any) {
@@ -42,4 +100,187 @@ export class PostDetailPage implements OnInit {
       this.comments.sort((a, b) => new Date(b.time).getTime() - new Date(a.time).getTime()); // 时间倒序
     }
   }
+
+  async toggleLike(comment: any) {
+    comment.likes = comment.likes + 1; // 赞同数+1
+    const query = new Parse.Query('Comment240709');
+    try {
+      const parseComment = await query.get(comment.id);
+      parseComment.increment('likes');
+      await parseComment.save();
+    } catch (error) {
+      console.error('Error while updating like count:', error);
+    }
+  }
+
+  async togglePostLike() {
+    this.post.likes = this.post.likes + 1; // 赞同数+1
+    const query = new Parse.Query('Post240709');
+    try {
+      const parsePost = await query.get(this.post.id);
+      parsePost.increment('likes');
+      await parsePost.save();
+    } catch (error) {
+      console.error('Error while updating like count:', error);
+    }
+  }
+
+  async replyToComment(comment: any) {
+    const alert = await this.alertCtrl.create({
+      header: '回复',
+      inputs: [
+        {
+          name: 'reply',
+          type: 'text',
+          placeholder: '输入您的回复'
+        }
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel',
+          cssClass: 'secondary'
+        },
+        {
+          text: '回复',
+          handler: async (data) => {
+            await this.submitReply(comment.id, data.reply);
+          }
+        }
+      ]
+    });
+
+    await alert.present();
+  }
+
+  async replyToPost() {
+    const alert = await this.alertCtrl.create({
+      header: '回复帖子',
+      inputs: [
+        {
+          name: 'reply',
+          type: 'text',
+          placeholder: '输入您的回复'
+        }
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel',
+          cssClass: 'secondary'
+        },
+        {
+          text: '回复',
+          handler: async (data) => {
+            await this.submitPostReply(data.reply);
+          }
+        }
+      ]
+    });
+
+    await alert.present();
+  }
+
+  async submitReply(commentId: string, content: string) {
+    const currentUser = Parse.User.current();
+    if (!currentUser) {
+      console.error('No user logged in. Please log in to reply.');
+      return;
+    }
+
+    const Comment240709 = Parse.Object.extend('Comment240709');
+    const comment = new Comment240709();
+
+    comment.set('author', currentUser);
+    comment.set('content', content);
+    comment.set('parentComment', {
+      __type: 'Pointer',
+      className: 'Comment240709',
+      objectId: commentId
+    });
+
+    try {
+      await comment.save();
+      console.log('Reply saved successfully.');
+      this.loadComments(this.post.id); // Reload comments to show the new reply
+    } catch (error) {
+      console.error('Error while saving reply:', error);
+    }
+  }
+
+  async submitPostReply(content: string) {
+    const currentUser = Parse.User.current();
+    if (!currentUser) {
+      console.error('No user logged in. Please log in to reply.');
+      return;
+    }
+
+    const Comment240709 = Parse.Object.extend('Comment240709');
+    const comment = new Comment240709();
+
+    comment.set('author', currentUser);
+    comment.set('content', content);
+    comment.set('post', {
+      __type: 'Pointer',
+      className: 'Post240709',
+      objectId: this.post.id
+    });
+
+    try {
+      await comment.save();
+      console.log('Reply to post saved successfully.');
+      this.loadComments(this.post.id); // Reload comments to show the new reply
+    } catch (error) {
+      console.error('Error while saving reply:', error);
+    }
+  }
+
+  sharePost() {
+    this.shareModal.present();
+  }
+
+  async generateTestComments() {
+    const currentUser = Parse.User.current();
+    if (!currentUser) {
+      console.error('No user logged in. Please log in to create test comments.');
+      return;
+    }
+
+    const hotPhrases = [
+      '这个可以有',
+      '我觉得可以',
+      '前排围观',
+      '沙发',
+      '楼主威武',
+      '说得好',
+      '赞同楼上',
+      '有理有据',
+      '请继续',
+      '哈哈哈哈'
+    ];
+
+    const Comment240709 = Parse.Object.extend('Comment240709');
+
+    for (let i = 0; i < 5; i++) {
+      const comment = new Comment240709();
+      comment.set('author', currentUser);
+      comment.set('content', hotPhrases[Math.floor(Math.random() * hotPhrases.length)]);
+      comment.set('post', {
+        __type: 'Pointer',
+        className: 'Post240709',
+        objectId: this.post.id
+      });
+      comment.set('likes', Math.floor(Math.random() * 100));
+      comment.set('floor', this.comments.length + i + 1);
+
+      try {
+        await comment.save();
+        console.log('Test comment saved successfully.');
+      } catch (error) {
+        console.error('Error while saving test comment:', error);
+      }
+    }
+
+    this.loadComments(this.post.id); // Reload comments to show the new test comments
+  }
 }

+ 1 - 0
src/modules/study/case-js-module/case-parse/case-parse.page.ts

@@ -5,6 +5,7 @@ import Parse from "parse";
 Parse.initialize("dev"); // 设置applicationId
 Parse.serverURL = "http://web2023.fmode.cn:9999/parse"; // 设置serverURL
 
+
 @Component({
   selector: 'app-case-parse',
   templateUrl: './case-parse.page.html',

+ 2 - 2
src/modules/user/README.md

@@ -46,8 +46,8 @@ npm i -D @types/parse
 ``` ts
 // 引用Parse JS SDK
 import Parse from "parse";
-Parse.initialize("dev"); // 设置applicationId
-Parse.serverURL = "http://web2023.fmode.cn:9999/parse"; // 设置serverURL
+Parse.initialize("my-server"); // 设置applicationId
+Parse.serverURL = "http://localhost:45632/parse"; // 设置serverURL
 ```
 
 # 复制user整个模块目录

+ 17 - 0
src/modules/user/login - 副本/login-routing.module.ts

@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { LoginPage } from './login.page';
+
+const routes: Routes = [
+  {
+    path: '',
+    component: LoginPage
+  }
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class LoginPageRoutingModule {}

+ 20 - 0
src/modules/user/login - 副本/login.module.ts

@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { IonicModule } from '@ionic/angular';
+
+import { LoginPageRoutingModule } from './login-routing.module';
+
+import { LoginPage } from './login.page';
+
+@NgModule({
+  imports: [
+    CommonModule,
+    FormsModule,
+    IonicModule,
+    LoginPageRoutingModule
+  ],
+  declarations: [LoginPage]
+})
+export class LoginPageModule {}

+ 33 - 0
src/modules/user/login - 副本/login.page.html

@@ -0,0 +1,33 @@
+<ion-header [translucent]="true">
+  <ion-toolbar>
+    <ion-title>登录/注册</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content [fullscreen]="true">
+
+  <ion-card>
+    <ion-card-header>
+      <ion-card-title>登录/注册</ion-card-title>
+    </ion-card-header>
+  
+    <ion-card-content>
+
+      <ion-list [inset]="true">
+        <ion-item>
+          <ion-input [(ngModel)]="username" label="账号" placeholder="请输入用户名"></ion-input>
+        </ion-item>
+        <ion-item>
+          <ion-input [(ngModel)]="password" label="密码" type="password" placeholder="请输入密码"></ion-input>
+        </ion-item>
+      </ion-list>
+     
+    </ion-card-content>
+  
+    <ion-button (click)="login()" fill="clear">登录</ion-button>
+    <ion-button (click)="register()" fill="clear">注册</ion-button>
+  </ion-card>
+
+  <!-- 新增路由返回逻辑,执行back函数 -->
+  <ion-button expand="block" (click)="back()">返回</ion-button>
+</ion-content>

+ 0 - 0
src/modules/user/login - 副本/login.page.scss


+ 17 - 0
src/modules/user/login - 副本/login.page.spec.ts

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

+ 93 - 0
src/modules/user/login - 副本/login.page.ts

@@ -0,0 +1,93 @@
+import { Component, OnInit } from '@angular/core';
+import { AlertController, NavController } from '@ionic/angular';
+import * as Parse from "parse"
+// 引用Router服务
+@Component({
+  selector: 'app-login',
+  templateUrl: './login.page.html',
+  styleUrls: ['./login.page.scss'],
+})
+export class LoginPage implements OnInit {
+
+  username:string = ""
+  password:string = ""
+  constructor(
+    // 新增:Router服务,用于路由跳转
+    private navCtrl:NavController,
+    private alertController:AlertController
+  ) { }
+
+  ngOnInit() {
+  }
+
+  async login(){
+    let user
+    try {
+      user = await Parse.User.logIn(this.username,this.password)
+    } catch (error:any) {
+      let message:string = ""
+      // 新增提示词详情,根据Parse.User.login方法返回的不同英文提示词,增加对应的中文内容转换
+      if(error?.message.indexOf("is required")>-1){
+        message = "必须输入账号或邮箱"
+      }
+      if(error?.message.indexOf("Invalid username")>-1){
+        message = "账号或密码错误,请检查"
+      }
+      this.presentAlert({
+        header:"登录失败",
+        subHeader:"状态码:"+error.code,
+        message:message || error.message
+      })
+    }
+    console.log(user)
+    if(user?.id){
+      this.navCtrl.back()
+    }
+  }
+  async register(){
+    let user = new Parse.User()
+    user.set("username",this.username)
+    user.set("password",this.password)
+    try {
+        let result = await user.signUp();
+        console.log(result)
+        if(result?.id){
+          this.navCtrl.back()
+        }
+        // Hooray! Let them use the app now.
+    } catch (error:any) {
+        // 新增提示词详情,根据Parse.User.signUp方法返回的不同英文提示词,增加对应的中文内容转换
+        let message:string = ""
+        if(error?.message.indexOf("already exists")>-1){
+          message = "该账号已存在请修改后重试"
+        }
+        if(error?.message.indexOf("empty")>-1){
+          message = "账号不能为空请输入后重试"
+        }
+        this.presentAlert({
+          header:"注册失败",
+          subHeader:"状态码:"+error.code,
+          message:message || error.message
+        })
+    }
+  }
+
+  async presentAlert(options:{header:string,subHeader:string,message:string}) {
+    const alert = await this.alertController.create({
+      header: options?.header,
+      subHeader: options?.subHeader,
+      message: options?.message,
+      buttons: ['好的'],
+    });
+
+    await alert.present();
+  }
+
+  /**
+   * 返回上级页面函数
+   * @desc
+   */
+  back(){
+    this.navCtrl.back()
+  }
+}

+ 52 - 58
src/modules/user/login/login.page.ts

@@ -1,78 +1,75 @@
 import { Component, OnInit } from '@angular/core';
 import { AlertController, NavController } from '@ionic/angular';
-import * as Parse from "parse"
-// 引用Router服务
+import * as Parse from "parse";
+
 @Component({
   selector: 'app-login',
   templateUrl: './login.page.html',
   styleUrls: ['./login.page.scss'],
 })
 export class LoginPage implements OnInit {
+  username: string = "";
+  password: string = "";
 
-  username:string = ""
-  password:string = ""
   constructor(
-    // 新增:Router服务,用于路由跳转
-    private navCtrl:NavController,
-    private alertController:AlertController
-  ) { }
+    private navCtrl: NavController,
+    private alertController: AlertController
+  ) {}
 
-  ngOnInit() {
-  }
+  ngOnInit() {}
 
-  async login(){
-    let user
+  async login() {
+    let user;
+    this.navCtrl.back();
     try {
-      user = await Parse.User.logIn(this.username,this.password)
-    } catch (error:any) {
-      let message:string = ""
-      // 新增提示词详情,根据Parse.User.login方法返回的不同英文提示词,增加对应的中文内容转换
-      if(error?.message.indexOf("is required")>-1){
-        message = "必须输入账号或邮箱"
+      user = await Parse.User.logIn(this.username, this.password);
+    } catch (error: any) {
+      let message: string = "";
+      if (error?.message.indexOf("is required") > -1) {
+        message = "必须输入账号或邮箱";
       }
-      if(error?.message.indexOf("Invalid username")>-1){
-        message = "账号或密码错误,请检查"
+      if (error?.message.indexOf("Invalid username") > -1) {
+        message = "账号或密码错误,请检查";
       }
       this.presentAlert({
-        header:"登录失败",
-        subHeader:"状态码:"+error.code,
-        message:message || error.message
-      })
+        header: "登录失败",
+        subHeader: "状态码:" + error.code,
+        message: message || error.message
+      });
     }
-    console.log(user)
-    if(user?.id){
-      this.navCtrl.back()
+    console.log(user);
+    if (user?.id) {
+      this.navCtrl.back();
     }
   }
-  async register(){
-    let user = new Parse.User()
-    user.set("username",this.username)
-    user.set("password",this.password)
+
+  async register() {
+    let user = new Parse.User();
+    user.set("username", this.username);
+    user.set("password", this.password);
     try {
-        let result = await user.signUp();
-        console.log(result)
-        if(result?.id){
-          this.navCtrl.back()
-        }
-        // Hooray! Let them use the app now.
-    } catch (error:any) {
-        // 新增提示词详情,根据Parse.User.signUp方法返回的不同英文提示词,增加对应的中文内容转换
-        let message:string = ""
-        if(error?.message.indexOf("already exists")>-1){
-          message = "该账号已存在请修改后重试"
-        }
-        if(error?.message.indexOf("empty")>-1){
-          message = "账号不能为空请输入后重试"
-        }
-        this.presentAlert({
-          header:"注册失败",
-          subHeader:"状态码:"+error.code,
-          message:message || error.message
-        })
+      let result = await user.signUp();
+      console.log(result);
+      if (result?.id) {
+        this.navCtrl.back();
+      }
+    } catch (error: any) {
+      let message: string = "";
+      if (error?.message.indexOf("already exists") > -1) {
+        message = "该账号已存在请修改后重试";
+      }
+      if (error?.message.indexOf("empty") > -1) {
+        message = "账号不能为空请输入后重试";
+      }
+      this.presentAlert({
+        header: "注册失败",
+        subHeader: "状态码:" + error.code,
+        message: message || error.message
+      });
     }
   }
 
-  async presentAlert(options:{header:string,subHeader:string,message:string}) {
+  async presentAlert(options: { header: string, subHeader: string, message: string }) {
     const alert = await this.alertController.create({
       header: options?.header,
       subHeader: options?.subHeader,
@@ -83,11 +80,8 @@ export class LoginPage implements OnInit {
     await alert.present();
   }
 
-  /**
-   * 返回上级页面函数
-   * @desc
-   */
-  back(){
-    this.navCtrl.back()
+  back() {
+    this.navCtrl.back();
   }
+
 }