Răsfoiți Sursa

feat: modifiy tab4

cyx 3 luni în urmă
părinte
comite
7d131876b2

+ 12 - 1
TFPower-app/src/app/app.routes.ts

@@ -5,5 +5,16 @@ export const routes: Routes = [
     path: '',
     loadChildren: () => import('./tabs/tabs.routes').then((m) => m.routes),
   },
-
+  {
+    path: 'login-page',
+    loadComponent: () =>
+      import('./page/login-page/login-page.page').then((m) => m.LoginPagePage),
+  },
+  {
+    path: 'register-page',
+    loadComponent: () =>
+      import('./page/register-page/register-page.page').then(
+        (m) => m.RegisterPagePage
+      ),
+  },
 ];

+ 28 - 0
TFPower-app/src/app/page/login-page/login-page.page.html

@@ -0,0 +1,28 @@
+<ion-content [fullscreen]="true">
+  <div class="background">
+    <div class="form-container">
+      <div class="header">登录</div>
+      <!-- 用户名输入框 -->
+      <ion-input [value]="username" placeholder="用户名" type="text" class="input-field"
+        (ionInput)="userInputUsername($event)">
+      </ion-input>
+
+      <!-- 密码输入框 -->
+      <ion-input [value]="password" placeholder="密码" type="password" class="input-field"
+        (ionInput)="userInputPassword($event)">
+      </ion-input>
+
+      <!-- 登录按钮 -->
+      <ion-button expand="full" (click)="login()" class="auth-button">登录</ion-button>
+
+      <div class="reminder">还没有账号?前往 <a (click)="navigateTo('register-page')">注册</a></div>
+
+      <!-- 注册按钮 -->
+      <!-- <ion-button expand="full" (click)="navigateToRegister()" class="auth-button">注册</ion-button> -->
+      <div class="extra-info">
+        <p>版权所有 &copy; 2024</p>
+        <p>隐私政策 | 使用条款</p>
+      </div>
+    </div>
+  </div>
+</ion-content>

+ 85 - 0
TFPower-app/src/app/page/login-page/login-page.page.scss

@@ -0,0 +1,85 @@
+/* 背景样式 */
+.background {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background-image: url("../../../assets/images/background.jpg"); /* 设置背景图片 */
+  background-size: cover;
+  background-position: center;
+  opacity: 0.8;
+}
+
+/* 表单容器样式 */
+.form-container {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  background-color: rgba(255, 255, 255, 0.7); /* 半透明白色背景 */
+  padding: 30px 20px;
+  border-radius: 10px;
+  width: 85%;
+  max-width: 400px;
+  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+}
+/* 输入框样式 */
+.input-field {
+  width: 100%;
+  margin-bottom: 15px;
+  --background: #f7f7f7; /* 输入框背景色 */
+  --border-radius: 4px; /* 圆角 */
+  --padding-start: 10px; /* 输入框内边距 */
+  --box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* 输入框阴影 */
+  --border-color: #4caf50; /* 输入框边框颜色 */
+  --highlight-color-focused: #4caf50;
+}
+
+/* 登录和注册按钮样式 */
+.auth-button {
+  margin-top: 10px;
+  border-radius: 25px; /* 按钮圆角 */
+  font-weight: bold; /* 加粗字体 */
+  text-transform: uppercase; /* 大写字母 */
+  --background: #4caf50; /* 按钮背景色 */
+  --color: white; /* 按钮文本颜色 */
+  --box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); /* 按钮阴影 */
+  --height: 50px; /* 按钮高度 */
+}
+
+.auth-button:hover {
+  --background: #45a049; /* 按钮悬停时颜色变化 */
+}
+
+.auth-button:active {
+  --background: #388e3c; /* 按钮点击时颜色变化 */
+  --box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+}
+.header {
+  text-align: center;
+  font-size: 24px;
+  font-weight: 900;
+  color: #388e3c;
+  margin-bottom: 10px;
+}
+
+.reminder {
+  position: absolute;
+  right: 25px;
+  margin-top: 4px;
+  font-size: 12px;
+  color: #888;
+}
+
+/* 额外信息部分样式 */
+.extra-info {
+  margin-top: 28px;
+  font-size: 12px;
+  color: #888;
+  text-align: center;
+}
+
+.extra-info p {
+  margin: 5px 0;
+}

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

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

+ 90 - 0
TFPower-app/src/app/page/login-page/login-page.page.ts

@@ -0,0 +1,90 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { NavController } from '@ionic/angular';
+import {
+  IonButton,
+  IonContent,
+  IonHeader,
+  IonInput,
+  IonTitle,
+  IonToolbar,
+} from '@ionic/angular/standalone';
+import { Router } from '@angular/router';
+import { CloudUser } from 'src/lib/cyxncloud';
+import { User } from 'src/app/tab4/tab4.page';
+
+@Component({
+  selector: 'app-login-page',
+  templateUrl: './login-page.page.html',
+  styleUrls: ['./login-page.page.scss'],
+  standalone: true,
+  imports: [
+    IonContent,
+    IonHeader,
+    IonTitle,
+    IonToolbar,
+    CommonModule,
+    FormsModule,
+    IonButton,
+    IonInput,
+  ],
+})
+export class LoginPagePage implements OnInit {
+  username: string = '';
+  password: string = '';
+  is_login: boolean = false;
+  currentUser: CloudUser | null = null;
+  user: User = {
+    avatar: 'https://ionicframework.com/docs/img/demos/avatar.svg',
+    username: '请登录',
+    age: 0,
+    sex: '-',
+    email: '-',
+    phoneNumber: '-',
+    fans: 0,
+    likes: 0,
+  };
+
+  constructor(private navCtrl: NavController, private router: Router) {}
+
+  navigateTo(path: string) {
+    this.router.navigate([`/${path}`]);
+  }
+
+  userInputUsername(ev: any) {
+    this.username = ev.detail.value;
+  }
+  userInputPassword(ev: any) {
+    this.password = ev.detail.value;
+  }
+  async login() {
+    if (this.username && this.password) {
+      console.log('用户名:', this.username, '密码:', this.password);
+      this.is_login = true;
+      let user = new CloudUser();
+      this.currentUser = await user.login(this.username, this.password);
+
+      if (this.currentUser) {
+        this.user.avatar = this.currentUser.data.avatar;
+        this.user.username = this.currentUser.data.username;
+        this.user.age = this.currentUser.data.age;
+        this.user.sex = this.currentUser.data.sex;
+        this.user.email = this.currentUser.data.email;
+        this.user.phoneNumber = this.currentUser.data.phoneNumber;
+        this.user.fans = this.currentUser.data.fans;
+        this.user.likes = this.currentUser.data.likes;
+        localStorage.setItem('userData', JSON.stringify(this.currentUser.data));
+        localStorage.setItem('is_login', 'true');
+        console.log('登录成功');
+        this.router.navigate([`/tabs/tab4`]);
+      }
+    }
+  }
+
+  navigateToRegister() {
+    this.navCtrl.navigateForward('/register');
+  }
+
+  ngOnInit() {}
+}

+ 36 - 0
TFPower-app/src/app/page/register-page/register-page.page.html

@@ -0,0 +1,36 @@
+<ion-content [fullscreen]="true">
+  <div class="background">
+    <div class="form-container">
+      <div class="header">注册</div>
+      <!-- 用户名输入框 -->
+
+      <ion-input [value]="username" type="text" placeholder="用户名" class="input-field"
+        (ionInput)="userInputUsername($event)"></ion-input>
+      <!-- 密码输入框 -->
+
+      <ion-input [value]="password" placeholder="密码" type="password" class="input-field"
+        (ionInput)="userInputPassword($event)">
+      </ion-input>
+      <!-- 确认密码输入框 -->
+      <ion-input [value]="confirmPassword" placeholder="确认密码" type="password" class="input-field"
+        (ionInput)="userInputConfirmPassword($event)">
+      </ion-input>
+
+      <!-- 验证 -->
+      <div class="verify"><a (click)="checkPassword()" id="present-alert">验证</a></div>
+      <!-- 登录按钮 -->
+      <ion-button expand="full" (click)="register()" class="auth-button">注册</ion-button>
+      <ion-alert trigger="present-alert" [header]="header" [message]="errormsg" [buttons]="alertButtons"
+        [cssClass]="alertClass"></ion-alert>
+
+      <div class="reminder">已有账号?前往 <a (click)="navigateTo('login-page')">登录</a></div>
+
+      <!-- 注册按钮 -->
+      <!-- <ion-button expand="full" (click)="navigateToRegister()" class="auth-button">注册</ion-button> -->
+      <div class="extra-info">
+        <p>版权所有 &copy; 2024</p>
+        <p>隐私政策 | 使用条款</p>
+      </div>
+    </div>
+  </div>
+</ion-content>

+ 90 - 0
TFPower-app/src/app/page/register-page/register-page.page.scss

@@ -0,0 +1,90 @@
+/* 背景样式 */
+.background {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background-image: url("../../../assets/images/background.jpg"); /* 设置背景图片 */
+  background-size: cover;
+  background-position: center;
+  opacity: 0.8;
+}
+
+/* 表单容器样式 */
+.form-container {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  background-color: rgba(255, 255, 255, 0.7); /* 半透明白色背景 */
+  padding: 30px 20px;
+  border-radius: 10px;
+  width: 85%;
+  max-width: 400px;
+  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+}
+/* 输入框样式 */
+.input-field {
+  width: 100%;
+  margin-bottom: 15px;
+  --background: #f7f7f7; /* 输入框背景色 */
+  --border-radius: 4px; /* 圆角 */
+  --padding-start: 10px; /* 输入框内边距 */
+  --box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* 输入框阴影 */
+  --border-color: #d87b34; /* 输入框边框颜色 */
+  --highlight-color-focused: #d87b34;
+}
+
+/* 登录和注册按钮样式 */
+.auth-button {
+  margin-top: 10px;
+  border-radius: 25px; /* 按钮圆角 */
+  font-weight: bold; /* 加粗字体 */
+  text-transform: uppercase; /* 大写字母 */
+  --background: #d87b34; /* 按钮背景色 */
+  --color: white; /* 按钮文本颜色 */
+  --box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); /* 按钮阴影 */
+  --height: 50px; /* 按钮高度 */
+}
+
+.auth-button:hover {
+  --background: #d87b64; /* 按钮悬停时颜色变化 */
+}
+
+.auth-button:active {
+  --background: #d89b34; /* 按钮点击时颜色变化 */
+  --box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+}
+.header {
+  text-align: center;
+  font-size: 24px;
+  font-weight: 900;
+  color: #d87b34;
+  margin-bottom: 10px;
+}
+.verify {
+  float: right;
+  margin: 5px 3px;
+  font-size: 13px;
+  color: #888;
+}
+.reminder {
+  position: absolute;
+  right: 25px;
+  margin-top: 4px;
+  font-size: 12px;
+  color: #888;
+}
+
+/* 额外信息部分样式 */
+.extra-info {
+  margin-top: 28px;
+  font-size: 12px;
+  color: #888;
+  text-align: center;
+}
+
+.extra-info p {
+  margin: 5px 0;
+}

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

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

+ 108 - 0
TFPower-app/src/app/page/register-page/register-page.page.ts

@@ -0,0 +1,108 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import {
+  IonAlert,
+  IonButton,
+  IonContent,
+  IonHeader,
+  IonInput,
+  IonTitle,
+  IonToolbar,
+} from '@ionic/angular/standalone';
+import { Router } from '@angular/router';
+import { CloudUser } from 'src/lib/cyxncloud';
+
+@Component({
+  selector: 'app-register-page',
+  templateUrl: './register-page.page.html',
+  styleUrls: ['./register-page.page.scss'],
+  standalone: true,
+  imports: [
+    IonContent,
+    IonHeader,
+    IonTitle,
+    IonToolbar,
+    CommonModule,
+    FormsModule,
+    IonButton,
+    IonInput,
+    IonAlert,
+  ],
+})
+export class RegisterPagePage implements OnInit {
+  username: string = '';
+  password: string = '';
+  confirmPassword: string = '';
+  alertButtons = ['确认'];
+  header: string = '';
+  errormsg: string = '';
+  alertClass: string = '';
+
+  constructor(private router: Router) {}
+
+  navigateTo(path: string) {
+    this.router.navigate([`/${path}`]);
+  }
+
+  userInputUsername(ev: any) {
+    this.username = ev.detail.value;
+  }
+  userInputPassword(ev: any) {
+    this.password = ev.detail.value;
+  }
+  userInputConfirmPassword(ev: any) {
+    this.confirmPassword = ev.detail.value;
+  }
+
+  checkPassword(): boolean {
+    // 正则表达式
+    const usernameRegex = /^[a-zA-Z0-9_\u4e00-\u9fa5]{3,}$/; // 用户名:至少3个字符,支持字母、数字、下划线和汉字
+    const passwordRegex = /^[a-zA-Z0-9]{8,}$/; // 密码:至少8个字符,只支持字母、数字
+
+    // 1. 检查用户名、密码和确认密码是否为空
+    if (!this.username || !this.password || !this.confirmPassword) {
+      this.header = '错误信息';
+      this.errormsg = '用户名或密码为空';
+      return false;
+    }
+
+    // 2. 检查用户名是否符合正则
+    if (!usernameRegex.test(this.username)) {
+      this.header = '错误信息';
+      this.errormsg =
+        '用户名必须至少包含 3 个字符,且只能包含字母、数字或下划线';
+      return false;
+    }
+
+    // 3. 检查密码是否符合正则
+    if (!passwordRegex.test(this.password)) {
+      this.header = '错误信息';
+      this.errormsg = '密码必须至少包含 8 个字符,且只能包含字母和数字';
+      return false;
+    }
+
+    // 4. 检查密码与确认密码是否一致
+    if (this.password !== this.confirmPassword) {
+      this.header = '错误信息';
+      this.errormsg = '前后密码不一致';
+      return false;
+    }
+
+    // 5. 如果所有验证通过
+    this.header = '提示信息';
+    this.errormsg = 'ok';
+    return true;
+  }
+
+  async register() {
+    let flag = this.checkPassword();
+
+    if (flag) {
+      let user = new CloudUser();
+      let res = await user.register(this.username, this.password);
+      console.log(res);
+    }
+  }
+  ngOnInit() {}
+}

+ 4 - 3
TFPower-app/src/app/tab4/tab4.page.html

@@ -34,13 +34,14 @@
           </ion-avatar>
         </ion-col>
         <ion-col size="9">
-          <ion-row class="showusername">请登录</ion-row>
+          <ion-row class="showusername" (click)="navigateTo('login-page')">请登录</ion-row>
           <ion-row class="showdesc">暂无信息</ion-row>
         </ion-col>
       </ion-row>
       <ion-card-content>
-        <ion-button expand="full" (click)="login()">登录</ion-button>
-        <ion-button expand="full" (click)="register()">注册</ion-button>
+        <ion-button expand="full" (click)="navigateTo('login-page')">登录</ion-button>
+        <!-- <ion-button expand="full" (click)="login()">登录</ion-button> -->
+        <ion-button expand="full" (click)="navigateTo('register-page')">注册</ion-button>
       </ion-card-content>
 
       }

+ 90 - 0
TFPower-app/src/app/tab4/tab4.page.ts

@@ -1,3 +1,4 @@
+<<<<<<< Updated upstream
 // import { Component } from '@angular/core';
 // import {
 //   IonHeader,
@@ -23,6 +24,34 @@
 //   fans: number;
 //   likes: number;
 // }
+=======
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+import {
+  IonHeader,
+  IonToolbar,
+  IonTitle,
+  IonContent,
+  IonCard,
+  IonCardContent,
+  IonGrid,
+  IonRow,
+  IonCol,
+  IonAvatar,
+  IonButton,
+} from '@ionic/angular/standalone';
+import { CloudUser } from 'src/lib/cyxncloud';
+export interface User {
+  avatar: string;
+  username: string;
+  age: number | null;
+  sex: string;
+  email: string;
+  phoneNumber: string;
+  fans: number;
+  likes: number;
+}
+>>>>>>> Stashed changes
 
 // @Component({
 //   selector: 'app-tab4',
@@ -140,12 +169,42 @@ addIcons({ add })
          IonCardContent,IonCardSubtitle,IonCardTitle,
          IonCardHeader,IonCardSubtitle,IonCard]
 })
+<<<<<<< Updated upstream
 export class Tab4Page implements OnInit {
+=======
+export class Tab4Page {
+  is_login: boolean = false;
+  currentUser: CloudUser | null = null;
+  user: User = {
+    avatar: 'https://ionicframework.com/docs/img/demos/avatar.svg',
+    username: '请登录',
+    age: 0,
+    sex: '-',
+    email: '-',
+    phoneNumber: '-',
+    fans: 0,
+    likes: 0,
+  };
+
+  constructor(private router: Router) {
+    let userCache = localStorage.getItem('userData');
+    if (userCache) {
+      let userData = JSON.parse(userCache);
+      this.user.avatar = userData.avatar;
+      this.user.username = userData.username;
+      this.user.age = userData.age;
+      this.user.sex = userData.sex;
+      this.user.email = userData.email;
+      this.user.phoneNumber = userData.phoneNumber;
+      this.user.fans = userData.fans;
+      this.user.likes = userData.likes;
+>>>>>>> Stashed changes
 
   currentUser:CloudUser|undefined
   constructor(private modalCtrl:ModalController) {
     this.currentUser = new CloudUser();
   }
+<<<<<<< Updated upstream
   ngOnInit() {
     throw new Error('Method not implemented.');
   }
@@ -282,4 +341,35 @@ export class Tab4Page implements OnInit {
     // }
 
 
+=======
+  navigateTo(path: string) {
+    this.router.navigate([`/${path}`]);
+  }
+
+  // async login() {
+  //   this.is_login = true;
+  //   let user = new CloudUser();
+  //   this.currentUser = await user.login('cyx', 'cyx123456');
+  //   if (this.currentUser) {
+  //     console.log(this.currentUser);
+
+  //     this.user.avatar = this.currentUser.data.avatar;
+  //     this.user.username = this.currentUser.data.username;
+  //     this.user.age = this.currentUser.data.age;
+  //     this.user.sex = this.currentUser.data.sex;
+  //     this.user.email = this.currentUser.data.email;
+  //     this.user.phoneNumber = this.currentUser.data.phoneNumber;
+  //     this.user.fans = this.currentUser.data.fans;
+  //     this.user.likes = this.currentUser.data.likes;
+  //     localStorage.setItem('userData', JSON.stringify(this.currentUser.data));
+  //     localStorage.setItem('is_login', 'true');
+  //   }
+  // }
+  async logout() {
+    this.is_login = false;
+    let user = new CloudUser();
+    let flag = await user.logout();
+    localStorage.removeItem('user');
+    localStorage.removeItem('is_login');
+>>>>>>> Stashed changes
   }

BIN
TFPower-app/src/assets/images/background.jpg


+ 10 - 20
TFPower-app/src/lib/cyxncloud.ts

@@ -129,7 +129,7 @@ export class CloudUser {
 
     this.objectId = result.objectId;
     this.sessionToken = result.sessionToken;
-    this.data = result.data;
+    this.data = result;
     return this;
   }
 
@@ -151,31 +151,21 @@ export class CloudUser {
   }
 
   // 用户注册
-  async register(username: string, password: string, phone: string) {
+  async register(username: string, password: string) {
     let url = 'http://1.94.237.145:1338/parsecyx/users';
-    return await fetch(url, {
+    let response = await fetch(url, {
       method: 'POST',
       headers: {
         'X-Parse-Application-Id': 'cyx',
         'Content-Type': 'application/json',
       },
-      body: JSON.stringify({ username, password, phone }),
-    })
-      .then((response) => {
-        if (!response.ok) {
-          throw new Error('Registration failed');
-        }
-        return response.json();
-      })
-      .then((data) => {
-        this.objectId = data.objectId;
-        this.sessionToken = data.sessionToken;
-        this.data = data;
-      })
-      .catch((error) => {
-        console.error('Error registering user:', error);
-        throw error;
-      });
+      body: JSON.stringify({ username, password }),
+    });
+    const result = await response?.json();
+    this.objectId = result.objectId;
+    this.sessionToken = result.sessionToken;
+    this.data = result;
+    return this;
   }
 }
 // module.exports.Query = Query;