Browse Source

新增我的

warrior 4 months ago
parent
commit
b3a05834bd
26 changed files with 692 additions and 351 deletions
  1. 10 0
      angular.json
  2. BIN
      projects/live-app/public/img/live.gif
  3. 1 1
      projects/live-app/src/app/app.component.html
  4. 1 1
      projects/live-app/src/app/app.component.ts
  5. 3 3
      projects/live-app/src/app/app.routes.ts
  6. 0 7
      projects/live-app/src/app/components/totas/totas.component.html
  7. 0 16
      projects/live-app/src/app/components/totas/totas.component.scss
  8. 0 34
      projects/live-app/src/app/components/totas/totas.component.ts
  9. 0 67
      projects/live-app/src/moduls/home/home/home.component.scss
  10. 1 2
      projects/live-app/src/moduls/login/login.component.html
  11. 4 3
      projects/live-app/src/moduls/login/login.component.scss
  12. 251 191
      projects/live-app/src/moduls/login/login.component.ts
  13. 41 3
      projects/live-app/src/moduls/tabs/home/home.component.html
  14. 148 0
      projects/live-app/src/moduls/tabs/home/home.component.scss
  15. 0 0
      projects/live-app/src/moduls/tabs/home/home.component.spec.ts
  16. 19 4
      projects/live-app/src/moduls/tabs/home/home.component.ts
  17. 57 0
      projects/live-app/src/moduls/tabs/my/my.component.html
  18. 102 0
      projects/live-app/src/moduls/tabs/my/my.component.scss
  19. 6 6
      projects/live-app/src/moduls/tabs/my/my.component.spec.ts
  20. 21 0
      projects/live-app/src/moduls/tabs/my/my.component.ts
  21. 6 1
      projects/live-app/src/moduls/tabs/tabs.modules.routes.ts
  22. 7 7
      projects/live-app/src/moduls/tabs/tabs/tabs.component.html
  23. 0 0
      projects/live-app/src/moduls/tabs/tabs/tabs.component.scss
  24. 0 0
      projects/live-app/src/moduls/tabs/tabs/tabs.component.spec.ts
  25. 3 4
      projects/live-app/src/moduls/tabs/tabs/tabs.component.ts
  26. 11 1
      projects/live-app/src/styles.scss

+ 10 - 0
angular.json

@@ -88,6 +88,16 @@
               {
                 "glob": "**/*",
                 "input": "public"
+              },
+              {
+                "glob": "**/*",
+                "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/",
+                "output": "/assets/"
+              },
+              {
+                "glob": "**/*",
+                "input": "./node_modules/material-icons/iconfont/",
+                "output": "/assets/material-icons/"
               }
             ],
             "styles": [

BIN
projects/live-app/public/img/live.gif


+ 1 - 1
projects/live-app/src/app/app.component.html

@@ -1,3 +1,3 @@
 <ion-app>
-  <router-outlet></router-outlet>
+  <ion-router-outlet></ion-router-outlet>
 </ion-app>

+ 1 - 1
projects/live-app/src/app/app.component.ts

@@ -5,7 +5,7 @@ import Parse from 'parse';
 @Component({
   selector: 'app-root',
   standalone: true,
-  imports: [RouterOutlet, IonicModule],
+  imports: [IonicModule],
   templateUrl: './app.component.html',
   styleUrl: './app.component.scss',
 })

+ 3 - 3
projects/live-app/src/app/app.routes.ts

@@ -1,9 +1,9 @@
 import { Routes,mapToCanActivate } from '@angular/router';
-import { TabsComponent } from '../moduls/home/tabs/tabs.component';
+import { TabsComponent } from '../moduls/tabs/tabs/tabs.component';
 import { AuthGuard } from '../services/auth.guard';
 
 export const routes: Routes = [
-  { path: '', redirectTo:'login', pathMatch: "full",}, // 默认跳转到 ''
+  { path: '', redirectTo:'tabs', pathMatch: "full",}, // 默认跳转到 ''
   {
     path: 'login',
     loadComponent:()=> import('../moduls/login/login.component').then((mod) => mod.LoginComponent),
@@ -12,6 +12,6 @@ export const routes: Routes = [
     path: 'tabs', //教材评审组成员
     component: TabsComponent,
     canActivate: mapToCanActivate([AuthGuard]),
-    loadChildren: () =>import('../moduls/home/home.module').then((mod) => mod.HomeRoutingModule),
+    loadChildren: () =>import('../moduls/tabs/tabs.modules.routes').then((mod) => mod.TabsRoutingModule),
   },
 ];

+ 0 - 7
projects/live-app/src/app/components/totas/totas.component.html

@@ -1,7 +0,0 @@
-<ion-toast
-  [class]="type"
-  [isOpen]="isToastOpen"
-  [message]="message"
-  [duration]="1500"
-  (didDismiss)="closeTotas()"
-></ion-toast>

+ 0 - 16
projects/live-app/src/app/components/totas/totas.component.scss

@@ -1,16 +0,0 @@
-.warning {
-  --background: #ffc409;
-  --color: #fff;
-}
-.success{
-  --background: #2dd55b;
-  --color: #fff;
-}
-.danger{
-  --background: #c5000f;
-  --color: #fff;
-}
-.tertiary{
-  --background: #6030ff;
-  --color: #fff;
-}

+ 0 - 34
projects/live-app/src/app/components/totas/totas.component.ts

@@ -1,34 +0,0 @@
-import { Component, Input, OnInit } from '@angular/core';
-import { IonicModule } from '@ionic/angular';
-
-@Component({
-  standalone: true,
-  imports: [IonicModule],
-  selector: 'app-totas',
-  templateUrl: './totas.component.html',
-  styleUrls: ['./totas.component.scss']
-})
-export class TotasComponent implements OnInit {
-  isToastOpen:boolean = false
-
-  @Input('type') type:string = 'undefined' //通知类型
-  @Input('message') message:string = '暂无通知'//通知内容
-  @Input('duration') duration:number = 1500//通知内容
-  
-  openTotas(message:string,type?:string,duration?:number){
-    this.isToastOpen = false
-    this.message = message
-    this.type = type || 'undefined'
-    this.duration = duration || 1500
-    this.isToastOpen = true
-  }
-  closeTotas(){
-    this.isToastOpen = false
-    this.message = ''
-  }
-  constructor() { }
-
-  ngOnInit() {
-  }
-
-}

+ 0 - 67
projects/live-app/src/moduls/home/home/home.component.scss

@@ -1,67 +0,0 @@
-.content {
-  .header {
-    padding: 10px;
-    background: #fd6f6a;
-    height: 150px;
-    border-radius: 0 0 50px 50px;
-    .top {
-      display: flex;
-      .search {
-        --background: #353c4d;
-        --cancel-button-color: #cccccc;
-        --color: #cccccc;
-      }
-      ion-segment {
-        justify-content: start;
-        padding: 0 3.2vw;
-        position: sticky;
-        top: 0;
-        background: #fd6f6a;
-      }
-      ion-segment-button {
-        color: white;
-        --indicator-color: white;
-      }
-      .more {
-        width: 100px;
-        margin: 0 10px;
-        display: flex;
-        align-items: center;
-        justify-content: space-around;
-        img {
-          width: 20px;
-          height: 20px;
-        }
-      }
-    }
-  }
-  .banner {
-    height: 160px;
-    width: calc(100% - 20px);
-    padding: 10px;
-    margin-top: -100px;
-    img {
-      width: 100%;
-      height: 150px;
-      object-fit: cover;
-    }
-  }
-}
-.swiper {
-  width: 100%;
-  height: 160px;
-  .swiper-slide {
-    text-align: center;
-    font-size: 18px;
-    background: #fff;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    img {
-      display: block;
-      width: 100%;
-      height: 100%;
-      object-fit: cover;
-    }
-  }
-}

+ 1 - 2
projects/live-app/src/moduls/login/login.component.html

@@ -1,4 +1,3 @@
-<app-totas></app-totas>
 <!-- 登录 -->
 <ion-content fullscreen scroll-y="false" *ngIf="status == 'login'">
   <div class="container">
@@ -242,7 +241,7 @@
       <ion-checkbox color="primary" [(ngModel)]="agreement"></ion-checkbox>
       <div class="content">
         注册即代表同意<span (click)="showAgreement()"
-          >《原科线上平台用户服务及隐私协议》</span
+          >《爱聊线上平台用户服务及隐私协议》</span
         >
       </div>
     </div>

+ 4 - 3
projects/live-app/src/moduls/login/login.component.scss

@@ -86,7 +86,7 @@ ion-content {
       }
       .captcha {
         // width: 18.133vw;
-        height: 6.4vw;
+        // height: 6.4vw;
         border: 0.133vw solid #0113c2;
         border-radius: 1.067vw;
         font-size: 3.2vw;
@@ -96,6 +96,7 @@ ion-content {
         align-items: center;
         justify-content: center;
         margin-right: 2.667vw;
+        text-align: center;
       }
     }
 
@@ -176,8 +177,8 @@ ion-content {
       }
       ion-checkbox {
         --background: #108ee9;
-        --border-color: #fff;
-        --border-color-checked: #fff;
+        // --border-color: #fff;
+        // --border-color-checked: #fff;
         --background-checked: #108ee9;
       }
     }

+ 251 - 191
projects/live-app/src/moduls/login/login.component.ts

@@ -1,25 +1,27 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
 import { LoginModule } from './login.module';
-import { AuthService } from "../../services/auth.service";
-import { AlertController, ModalController, ToastController } from "@ionic/angular";
-import * as Parse from "parse";
-import { Router, ActivatedRoute } from "@angular/router";
+import { AuthService } from '../../services/auth.service';
+import {
+  AlertController,
+  ModalController,
+  ToastController,
+} from '@ionic/angular';
+import * as Parse from 'parse';
+import { Router, ActivatedRoute } from '@angular/router';
 import { HttpClient, HttpHeaders } from '@angular/common/http';
-import { catchError } from "rxjs/operators";
-import { AgreementComponent } from "./agreement/agreement.component"
-import { TotasComponent } from '../../app/components/totas/totas.component';
+import { catchError } from 'rxjs/operators';
+import { AgreementComponent } from './agreement/agreement.component';
 @Component({
   standalone: true,
-  imports: [LoginModule,AgreementComponent,TotasComponent],
+  imports: [LoginModule],
   selector: 'app-login',
   templateUrl: './login.component.html',
-  styleUrls: ['./login.component.scss']
+  styleUrls: ['./login.component.scss'],
 })
 export class LoginComponent implements OnInit {
-  @ViewChild(TotasComponent) totas: TotasComponent | undefined;
   user: { username?: string; password?: string } = {
-    username: "",
-    password: "",
+    username: '',
+    password: '',
   };
   currentUser: any;
   constructor(
@@ -31,28 +33,28 @@ export class LoginComponent implements OnInit {
     private modalController: ModalController,
     private alertController: AlertController
   ) {
-    this.company = authServ.company
+    this.company = authServ.company;
   }
-  
+
   company: any;
   appName: any;
   logo: any;
   // 显示登陆、注册内容
-  status: string = "login";
-  type: string = "password";
+  status: string = 'login';
+  type: string = 'password';
   loginInfo: any = {
     mobile: '',
     password: '',
-    code: ''
-  }
+    code: '',
+  };
   // 忘记密码
   reset: any = {
     mobile: '',
     code: '',
     password: '',
-    confirmPassword: ''
-  }
-  inputType: string = 'password'
+    confirmPassword: '',
+  };
+  inputType: string = 'password';
   // 注册
   agreement: boolean = false;
   registerAgreement: any;
@@ -61,43 +63,42 @@ export class LoginComponent implements OnInit {
     code: '',
     password: '',
     confirmPassword: '',
-    invite: ''
-  }
+    invite: '',
+  };
   ngOnInit() {
-    this.authServ.logout()
+    this.authServ.logout();
     this.activatedRoute.paramMap.subscribe((param) => {
-      localStorage.setItem("APP_DEFAULT_COMPANY", "Qje9D4bqol");
-      let APP_DEFAULT_COMPANY = localStorage.getItem("APP_DEFAULT_COMPANY");
+      localStorage.setItem('APP_DEFAULT_COMPANY', 'Qje9D4bqol');
+      let APP_DEFAULT_COMPANY = localStorage.getItem('APP_DEFAULT_COMPANY');
       if (APP_DEFAULT_COMPANY) {
         this.company = APP_DEFAULT_COMPANY;
-        localStorage.setItem("company", this.company);
+        localStorage.setItem('company', this.company);
       }
-      if (param.get("c")) {
-        this.company = param.get("c");
+      if (param.get('c')) {
+        this.company = param.get('c');
       }
       if (this.company) {
         // localStorage.setItem("company", this.company);
-        let App = new Parse.Query("App");
-        App.equalTo("company", this.company);
+        let App = new Parse.Query('App');
+        App.equalTo('company', this.company);
         App.first().then((res) => {
           console.log(res);
           if (res && res.id) {
-            this.appName = res.get("name");
-            this.logo = res.get("logo");
+            this.appName = res.get('name');
+            this.logo = res.get('logo');
           }
         });
       }
-      this.getAgreement()
-      let Company = new Parse.Query("Company");
+      this.getAgreement();
+      let Company = new Parse.Query('Company');
       Company.get(this.company).then((res) => {
-        console.log(res, res.get("tabsOption"));
-        let value = res.get("tabsOption");
-        localStorage.setItem("tabsOption", JSON.stringify(value));
+        console.log(res, res.get('tabsOption'));
+        let value = res.get('tabsOption');
+        localStorage.setItem('tabsOption', JSON.stringify(value));
       });
     });
   }
 
-
   //   获取验证码
   wait: number = 60;
   waitStatus: boolean = false;
@@ -114,73 +115,72 @@ export class LoginComponent implements OnInit {
     }
   }
 
-
   //   获取验证码
-  vcode: string = ''
-  mobile: string = ''
-  loginToken: string = ""
-  async sendVerifyCode(mobile:string) {
-    if (mobile == undefined) {
-      const toast = await this.toastController.create({
-        message: "请输入手机号",
-        color: "primary",
-        duration: 1000,
-      });
-      toast.present();
+  vcode: string = '';
+  mobile: string = '';
+  loginToken: string = '';
+  timer: boolean = false;
+  async sendVerifyCode(mobile: string) {
+    if (this.timer) {
       return;
     }
+    this.timer = true;
     let a = /^1[3456789]\d{9}$/;
-    if (!String(mobile).match(a)) {
+    if (mobile == undefined || !String(mobile).match(a)) {
       const toast = await this.toastController.create({
-        message: "请填写正确手机号",
-        duration: 1000,
+        message: '请填写正确手机号',
+        color: 'warning',
+        duration: 100000,
       });
       toast.present();
+      this.timer = false;
       return;
     }
-    if(this.status == 'login'){
-      let query = new Parse.Query('_User')
-      query.equalTo('company',this.company)
-      query.equalTo('mobile',mobile)
-      query.select('objectId')
-      let r = await query.first()
-      if(!r?.id){
-        this.totas?.openTotas('用户手机号不存在,请先注册','warning')
-        // const toast = await this.toastController.create({
-        //   message: "用户手机号不存在,请先注册",
-        //   duration: 1000,
-        // });
-        // toast.present();
-        return
+    if (this.status == 'login') {
+      let query = new Parse.Query('_User');
+      query.equalTo('company', this.company);
+      query.equalTo('mobile', mobile);
+      query.select('objectId');
+      let r = await query.first();
+      if (!r?.id) {
+        const toast = await this.toastController.create({
+          message: '用户手机号不存在,请先注册',
+          color: 'warning',
+          duration: 1000,
+        });
+        toast.present();
+        this.timer = false;
+        return;
       }
     }
     this.http
-      .post("https://server.fmode.cn/api/apig/message", {
+      .post('https://server.fmode.cn/api/apig/message', {
         company: this.company,
         mobile: mobile,
       })
       .subscribe((res: any) => {
         this.waitStatus = true;
         this.time();
-        this.vcode = res.data.code
-      })
+        this.vcode = res.data.code;
+        this.timer = false;
+      });
   }
 
   changeType() {
-    let type = this.type
+    let type = this.type;
     if (type == 'password') {
-      this.type = 'code'
+      this.type = 'code';
     } else {
-      this.type = 'password'
+      this.type = 'password';
     }
   }
 
   async login() {
-    console.log(this.loginInfo)
+    console.log(this.loginInfo);
     if (this.loginInfo.mobile == undefined || this.loginInfo.mobile == '') {
       const toast = await this.toastController.create({
-        message: "请输入手机号",
-        color: "primary",
+        message: '请输入手机号',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
@@ -189,7 +189,8 @@ export class LoginComponent implements OnInit {
     let a = /^1[3456789]\d{9}$/;
     if (!String(this.loginInfo.mobile).match(a)) {
       const toast = await this.toastController.create({
-        message: "请填写正确手机号",
+        message: '请填写正确手机号',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
@@ -198,66 +199,77 @@ export class LoginComponent implements OnInit {
     if (this.type == 'password') {
       if (this.loginInfo.password == '' || this.loginInfo.password.trim == '') {
         const toast = await this.toastController.create({
-          message: "请填密码",
+          message: '请填写密码',
+          color: 'warning',
           duration: 1000,
         });
         toast.present();
         return;
       }
-      this.authServ.authMobile(this.loginInfo.mobile,this.loginInfo.password,this.loginInfo.mobile).then(data=>{
-        console.log(data);
-      }).catch(async err=>{
-        const toast = await this.toastController.create({
-          message: err,
-          duration: 1000,
+      this.authServ
+        .authMobile(
+          this.loginInfo.mobile,
+          this.loginInfo.password,
+          this.loginInfo.mobile
+        )
+        .then((data) => {
+          console.log(data);
+        })
+        .catch(async (err) => {
+          const toast = await this.toastController.create({
+            message: err,
+            color: 'danger',
+            duration: 1000,
+          });
+          toast.present();
         });
-        toast.present();
-      })
     } else if (this.type == 'code') {
       if (!this.loginInfo.code) {
         const toast = await this.toastController.create({
-          message: "请填写有效验证码",
+          message: '请填写有效验证码',
+          color: 'warning',
           duration: 1000,
         });
         toast.present();
         return;
       }
-      this.authServ.authMobile(this.loginInfo.mobile,undefined,this.loginInfo.mobile,this.loginInfo.code).then(data=>{
-        console.log(data);
-      }).catch(async err=>{
-        const toast = await this.toastController.create({
-          message: err,
-          duration: 1000,
+      this.authServ
+        .authMobile(
+          this.loginInfo.mobile,
+          undefined,
+          this.loginInfo.mobile,
+          this.loginInfo.code
+        )
+        .then((data) => {
+          console.log(data);
+        })
+        .catch(async (err) => {
+          const toast = await this.toastController.create({
+            message: err,
+            color: 'danger',
+            duration: 1000,
+          });
+          toast.present();
         });
-        toast.present();
-      })
     }
   }
   // 忘记密码部分逻辑
   back() {
-    this.status = 'login'
+    this.status = 'login';
   }
   togglePassword() {
     if (this.inputType == 'password') {
-      this.inputType = 'text'
+      this.inputType = 'text';
     } else {
-      this.inputType = 'password'
+      this.inputType = 'password';
     }
   }
   async resetPassword() {
-    if (this.reset.mobile == undefined) {
-      const toast = await this.toastController.create({
-        message: "请输入手机号",
-        color: "primary",
-        duration: 1000,
-      });
-      toast.present();
-      return;
-    }
     let a = /^1[3456789]\d{9}$/;
-    if (!String(this.reset.mobile).match(a)) {
+    if (this.reset.mobile == undefined || !String(this.reset.mobile).match(a)) {
       const toast = await this.toastController.create({
-        message: "请填写正确手机号",
+        message: '请输入手机号',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
@@ -265,31 +277,41 @@ export class LoginComponent implements OnInit {
     }
     if (this.reset.code == undefined || this.reset.code == '') {
       const toast = await this.toastController.create({
-        message: "请输入验证码",
+        message: '请输入验证码',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
       return;
     }
-    if (this.reset.password == undefined || this.reset.password.trim() == "") {
+    if (this.reset.password == undefined || this.reset.password.trim() == '') {
       const toast = await this.toastController.create({
-        message: "请输入密码",
+        message: '请输入密码',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
       return;
     }
-    if (this.reset.password.length < 6 || this.reset.password.length.length > 20) {
+    if (
+      this.reset.password.length < 6 ||
+      this.reset.password.length.length > 20
+    ) {
       const toast = await this.toastController.create({
-        message: "密码长度不得小于6位或大于20位",
+        message: '密码长度不得小于6位或大于20位',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
       return;
     }
-    if (this.reset.confirmPassword == undefined || this.reset.confirmPassword.trim() == "") {
+    if (
+      this.reset.confirmPassword == undefined ||
+      this.reset.confirmPassword.trim() == ''
+    ) {
       const toast = await this.toastController.create({
-        message: "请确认密码",
+        message: '请确认密码',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
@@ -297,79 +319,93 @@ export class LoginComponent implements OnInit {
     }
     if (this.reset.password.trim() != this.reset.confirmPassword.trim()) {
       const toast = await this.toastController.create({
-        message: "两次输入密码不一致",
+        message: '两次输入密码不一致',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
       return;
     }
     let headers: HttpHeaders = new HttpHeaders({});
-    headers.append("Content-Type", "application/json");
-    headers.set('Access-Control-Allow-Origin', '*')
+    headers.append('Content-Type', 'application/json');
+    headers.set('Access-Control-Allow-Origin', '*');
     this.http
-      .post(`https://server.fmode.cn/api/reset_password`, {
-        company: this.company,
-        code: this.reset.code,
-        mobile: this.reset.mobile,
-        password: this.reset.password
-      }, { headers }).pipe(
-        catchError(async (e) => { // 显示报错
+      .post(
+        `https://server.fmode.cn/api/reset_password`,
+        {
+          company: this.company,
+          code: this.reset.code,
+          mobile: this.reset.mobile,
+          password: this.reset.password,
+        },
+        { headers }
+      )
+      .pipe(
+        catchError(async (e) => {
+          // 显示报错
           const toast = await this.toastController.create({
             message: e.message,
+            color: 'danger',
             duration: 1000,
           });
           toast.present();
-          console.log(e)
-          return
+          console.log(e);
+          return;
         })
-      ).subscribe(async (res: any) => {
-        console.log(res)
+      )
+      .subscribe(async (res: any) => {
+        console.log(res);
         if (res && res.code == 200) {
           const toast = await this.toastController.create({
-            message: "密码重置成功",
-            color: "success",
+            message: '密码重置成功',
+            color: 'success',
             duration: 1000,
           });
           toast.present();
         } else {
-          const toast = await this.toastController.create({ // 接口返回的错误,提示用户
+          const toast = await this.toastController.create({
+            // 接口返回的错误,提示用户
             message: res.mess,
+            color: 'danger',
             duration: 1000,
           });
           toast.present();
         }
-      })
+      });
   }
   // 注册账号
   agree() {
-    this.agreement = !this.agreement
+    this.agreement = !this.agreement;
   }
   getAgreement() {
-    let Agreement = new Parse.Query("ContractAgreement")
-    Agreement.equalTo("company", this.company)
-    Agreement.equalTo("type", "register")
-    Agreement.first().then(res => {
-      console.log(res)
-      let item = res && res.toJSON()
-      this.registerAgreement = item
-    })
+    let Agreement = new Parse.Query('ContractAgreement');
+    Agreement.equalTo('company', this.company);
+    Agreement.equalTo('type', 'register');
+    Agreement.first().then((res) => {
+      console.log(res);
+      let item = res && res.toJSON();
+      this.registerAgreement = item;
+    });
   }
   async showAgreement() {
     const modal = await this.modalController.create({
       component: AgreementComponent,
       cssClass: 'my-custom-class',
       componentProps: {
-        "agreement": this.registerAgreement
-      }
+        agreement: this.registerAgreement,
+      },
     });
     return await modal.present();
   }
   async registerUser() {
     let a = /^1[3456789]\d{9}$/;
-    if (this.registerInfo.mobile == undefined || !String(this.registerInfo.mobile).match(a)) {
+    if (
+      this.registerInfo.mobile == undefined ||
+      !String(this.registerInfo.mobile).match(a)
+    ) {
       const toast = await this.toastController.create({
-        message: "请填写正确的手机号",
-        color: "primary",
+        message: '请填写正确的手机号',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
@@ -377,39 +413,56 @@ export class LoginComponent implements OnInit {
     }
     if (this.registerInfo.code == undefined || this.registerInfo.code == '') {
       const toast = await this.toastController.create({
-        message: "请输入验证码",
+        message: '请输入验证码',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
       return;
     }
-    if (this.registerInfo.password == undefined || this.registerInfo.password.trim() == "") {
+    if (
+      this.registerInfo.password == undefined ||
+      this.registerInfo.password.trim() == ''
+    ) {
       const toast = await this.toastController.create({
-        message: "请输入密码",
+        message: '请输入密码',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
       return;
     }
-    if (this.registerInfo.password.length < 6 || this.registerInfo.password.length.length > 20) {
+    if (
+      this.registerInfo.password.length < 6 ||
+      this.registerInfo.password.length.length > 20
+    ) {
       const toast = await this.toastController.create({
-        message: "密码长度不得小于6位或大于20位",
+        message: '密码长度不得小于6位或大于20位',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
       return;
     }
-    if (this.registerInfo.confirmPassword == undefined || this.registerInfo.confirmPassword.trim() == "") {
+    if (
+      this.registerInfo.confirmPassword == undefined ||
+      this.registerInfo.confirmPassword.trim() == ''
+    ) {
       const toast = await this.toastController.create({
-        message: "请确认密码",
+        message: '请确认密码',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
       return;
     }
-    if (this.registerInfo.password.trim() != this.registerInfo.confirmPassword.trim()) {
+    if (
+      this.registerInfo.password.trim() !=
+      this.registerInfo.confirmPassword.trim()
+    ) {
       const toast = await this.toastController.create({
-        message: "两次输入密码不一致",
+        message: '两次输入密码不一致',
+        color: 'warning',
         duration: 1000,
       });
       toast.present();
@@ -427,49 +480,54 @@ export class LoginComponent implements OnInit {
             cssClass: 'secondary',
             handler: (blah) => {
               console.log('Confirm Cancel: blah');
-            }
-          }, {
+            },
+          },
+          {
             text: '同意',
             handler: () => {
-              this.agreement = true
-            }
-          }
-        ]
+              this.agreement = true;
+            },
+          },
+        ],
       });
       await alert.present();
-      return
-    }
-    let data = this.registerInfo.invite ? {
-      company: this.company,
-      code: this.registerInfo.code,
-      mobile: this.registerInfo.mobile,
-      password: this.registerInfo.password,
-      invite: this.registerInfo.invite
+      return;
     }
-      :
-      {
-        company: this.company,
-        code: this.registerInfo.code,
-        mobile: this.registerInfo.mobile,
-        password: this.registerInfo.password
-      }
+    let data = this.registerInfo.invite
+      ? {
+          company: this.company,
+          code: this.registerInfo.code,
+          mobile: this.registerInfo.mobile,
+          password: this.registerInfo.password,
+          invite: this.registerInfo.invite,
+        }
+      : {
+          company: this.company,
+          code: this.registerInfo.code,
+          mobile: this.registerInfo.mobile,
+          password: this.registerInfo.password,
+        };
     this.http
-      .post(`https://server.fmode.cn/api/register`, data).pipe(
-        catchError(async (e) => { // 显示报错
+      .post(`https://server.fmode.cn/api/register`, data)
+      .pipe(
+        catchError(async (e) => {
+          // 显示报错
           const toast = await this.toastController.create({
             message: e.message,
+            color: 'danger',
             duration: 1000,
           });
           toast.present();
-          console.log(e)
-          return
+          console.log(e);
+          return;
         })
-      ).subscribe(async (res: any) => {
-        console.log(res)
+      )
+      .subscribe(async (res: any) => {
+        console.log(res);
         if (res && res.code == 200) {
           const toast = await this.toastController.create({
             message: res.msg,
-            color: "success",
+            color: 'success',
             duration: 1000,
           });
           toast.present();
@@ -478,16 +536,18 @@ export class LoginComponent implements OnInit {
             code: '',
             password: '',
             confirmPassword: '',
-            invite: ''
-          }
-          this.status = 'login'
+            invite: '',
+          };
+          this.status = 'login';
         } else {
-          const toast = await this.toastController.create({ // 接口返回的错误,提示用户
+          const toast = await this.toastController.create({
+            // 接口返回的错误,提示用户
             message: res.mess,
+            color: 'danger',
             duration: 1000,
           });
           toast.present();
         }
-      })
+      });
   }
 }

+ 41 - 3
projects/live-app/src/moduls/home/home/home.component.html → projects/live-app/src/moduls/tabs/home/home.component.html

@@ -21,10 +21,10 @@
           <ion-label>三星</ion-label>
         </ion-segment-button>
         <ion-segment-button value="star4" class="tabs">
-          <ion-label>星</ion-label>
+          <ion-label>星</ion-label>
         </ion-segment-button>
         <ion-segment-button value="star6" class="tabs">
-          <ion-label>星</ion-label>
+          <ion-label>星</ion-label>
         </ion-segment-button>
       </ion-segment>
       <div class="more">
@@ -44,10 +44,48 @@
     <div class="swiper mySwiper">
       <div class="swiper-wrapper">
         @for (item of banner; track $index) {
-        <div class="swiper-slide"> <img [src]="item?.get('image')" alt="" /></div>
+        <div class="swiper-slide">
+          <img [src]="item?.get('image')" alt="" />
+        </div>
         }
       </div>
       <div class="swiper-pagination"></div>
     </div>
   </div>
+  <div class="room-list">
+    @for (item of roomList; track $index) {
+    <div
+      class="list-row"
+      [style.background-image]="'url(' + item?.get('cover') + ')'"
+    >
+      <div class="title-tag">在线聊天</div>
+      <div class="live-tag">
+        <!-- <span></span>  -->
+        <img src="/img/live.gif" alt="">
+        直播中</div>
+      <div class="room-footer">
+        <div class="user">
+          {{
+            item?.get("user")?.get("nickname") ||
+              item?.get("user")?.get("mobile")
+          }}
+        </div>
+        <div class="desc">{{ item?.get("title") }}</div>
+        <div class="city-block">
+          <div class="row-li">
+            <ion-icon name="location-outline"></ion-icon>
+            江西
+          </div>
+          <div class="row-li" style="margin-left: 4px;">
+            <img
+              src="https://file-cloud.fmode.cn/Qje9D4bqol/20241109/pctmvt110807052.png"
+              alt=""
+            />
+            22
+          </div>
+        </div>
+      </div>
+    </div>
+    }
+  </div>
 </ion-content>

+ 148 - 0
projects/live-app/src/moduls/tabs/home/home.component.scss

@@ -0,0 +1,148 @@
+.content {
+  --padding-bottom: 100px;
+  .header {
+    padding: 10px;
+    background: #fd6f6a;
+    height: 150px;
+    border-radius: 0 0 50px 50px;
+    .top {
+      display: flex;
+      .search {
+        --background: #353c4d;
+        --cancel-button-color: #cccccc;
+        --color: #cccccc;
+      }
+      ion-segment {
+        justify-content: start;
+        padding: 0 3.2vw;
+        position: sticky;
+        top: 0;
+        background: #fd6f6a;
+      }
+      ion-segment-button {
+        color: white;
+        --indicator-color: white;
+      }
+      .more {
+        width: 100px;
+        margin: 0 10px;
+        display: flex;
+        align-items: center;
+        justify-content: space-around;
+        img {
+          width: 20px;
+          height: 20px;
+        }
+      }
+    }
+  }
+  .banner {
+    height: 180px;
+    // width: calc(100% - 20px);
+    padding: 10px;
+    margin-top: -80px;
+    img {
+      width: 100%;
+      height: 150px;
+      object-fit: cover;
+    }
+  }
+  .swiper {
+    width: 100%;
+    height: 160px;
+    .swiper-slide {
+      text-align: center;
+      font-size: 18px;
+      background: #fff;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      img {
+        display: block;
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+      }
+    }
+  }
+  .room-list {
+    display: grid;
+    grid-template-columns: repeat(2, 180px);
+    // grid-column-gap: 10px;
+    grid-row-gap: 10px;
+    padding: 10px;
+    justify-content: space-between;
+    font-size: 14px;
+    .list-row {
+      // width: 180px;
+      height: 250px;
+      background-size: 100% 100%;
+      position: relative;
+      color: white;
+      border-radius: 10px;
+      .title-tag {
+        background: linear-gradient(to bottom right, #9367fe, #d55bd9);
+        position: absolute;
+        top: 0;
+        left: 0;
+        border-radius: 10px 0;
+        padding: 4px 8px;
+      }
+      .live-tag {
+        position: absolute;
+        top: 4px;
+        right: 10px;
+        border-radius: 20px;
+        padding: 4px 10px;
+        font-size: 10px;
+        background: #1414147a;
+        display: flex;
+        align-items: center;
+        justify-content: space-evenly;
+        span {
+          height: 4px;
+          width: 4px;
+          border-radius: 50%;
+          background-color: #83f1dd;
+          margin-right: 4px;
+        }
+        img {
+          width: 12px;
+          height: 14px;
+        }
+      }
+      .room-footer {
+        position: absolute;
+        bottom: 0;
+        width: calc(100%);
+        padding: 4px 10px 10px;
+        max-height: 100px;
+        background: linear-gradient(to bottom, #ffffff00, #434343);
+        border-radius: 0 0 10px 10px;
+        .user {
+          font-size: 16px;
+        }
+        .desc {
+          margin: 4px 0;
+        }
+        .city-block {
+          display: flex;
+          background: linear-gradient(to right, #ff92e3f0, #ff6a93);
+          display: inline-flex;
+          padding: 2px 6px;
+          border-radius: 20px;
+          align-items: center;
+          .row-li {
+            display: flex;
+            align-content: center;
+            img {
+              width: 12px;
+              height: 12px;
+              margin-right: 2px;
+            }
+          }
+        }
+      }
+    }
+  }
+}

+ 0 - 0
projects/live-app/src/moduls/home/home/home.component.spec.ts → projects/live-app/src/moduls/tabs/home/home.component.spec.ts


+ 19 - 4
projects/live-app/src/moduls/home/home/home.component.ts → projects/live-app/src/moduls/tabs/home/home.component.ts

@@ -16,6 +16,7 @@ import { Swiper } from 'swiper';
 export class HomeComponent implements OnInit {
   active: String = 'recommend';
   banner: Array<Parse.Object> = [];
+  roomList:Array<Parse.Object> = []
   pageSwiper: Swiper | undefined | any;
 
   constructor(private router: Router, public authServ: AuthService) {}
@@ -24,15 +25,21 @@ export class HomeComponent implements OnInit {
     this.refresh();
   }
   async refresh() {
+    await this.getBanner()
+    await this.getRoom()
+    setTimeout(() => {
+      this.initSwiperTimeEvent()
+    }, 0);
+  }
+  async getBanner(){
     let query = new Parse.Query('Banner');
     query.equalTo('company', this.authServ.company);
     query.descending('index');
     query.equalTo('isEnabled', true);
+    query.notEqualTo('isDeleted', true);
     let banner = await query.find();
     this.banner = banner;
-    setTimeout(() => {
-      this.initSwiperTimeEvent()
-    }, 0);
+
   }
   initSwiperTimeEvent() {
     // 初始化轮播图
@@ -48,9 +55,17 @@ export class HomeComponent implements OnInit {
       },
     });
     swiper.on('slideChange', function (event:any) {
-      console.log(event);
+      // console.log(event);
     });
   }
+  async getRoom(){
+    let query = new Parse.Query('Room');
+    query.equalTo('company', this.authServ.company);
+    query.equalTo('state',true);
+    query.notEqualTo('isDeleted', true);
+    let r = await query.find()
+    this.roomList = r
+  }
   segmentChanged(e: any) {
     let { value } = e.detail;
     this.active = value;

+ 57 - 0
projects/live-app/src/moduls/tabs/my/my.component.html

@@ -0,0 +1,57 @@
+<ion-content class="content">
+  <div class="header">
+    <div class="user-dateil">
+      <div
+        class="pendant"
+        [style.background-image]="
+          'url(https://file-cloud.fmode.cn/Qje9D4bqol/20241109/vv1tvb032259054.png)'
+        "
+      >
+        <img [src]="user?.get('avatar')" alt="" class="avatar" />
+      </div>
+      <div class="user-right">
+        <div class="user-name">
+          {{
+            user?.get("nickname") ||
+              user?.get("mobile") ||
+              user?.get("username")
+          }}
+        </div>
+        <div class="user-block">
+          <div class="tags">
+            <!-- @if (user?.get('sex') == '男') { -->
+            <div class="sex">
+              <ion-icon name="male-outline"></ion-icon>
+            </div>
+            <!-- }@else if (user?.get('sex') == '女') {
+            <div class="sex girl">
+              <ion-icon name="male-female-outline"></ion-icon>
+            </div>
+            } -->
+            <div class="age">
+              <img
+                src="https://file-cloud.fmode.cn/Qje9D4bqol/20241109/pctmvt110807052.png"
+                alt=""
+              />
+              23
+            </div>
+            <div class="id">ID:{{ user?.id }}</div>
+          </div>
+          <div class="btn">个人主页</div>
+        </div>
+        <div class="user-footer">
+          <div class="row">1.2W 粉丝</div>
+          <div class="row">105 关注</div>
+          <div class="row">1546 亲密度</div>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="ad">
+    <div class="text">爱聊 <span>VIP</span></div>
+    <p>开通爱聊VIP,解锁海量专属主播聊天。</p>
+    <div class="btn">立即开通</div>
+  </div>
+  <div class="tool">
+  </div>
+</ion-content>

+ 102 - 0
projects/live-app/src/moduls/tabs/my/my.component.scss

@@ -0,0 +1,102 @@
+.content {
+  --padding-bottom: 100px;
+  .header {
+    padding: 10px;
+    background: #fd6f6a;
+    height: 130px;
+    border-radius: 0 0 50px 50px;
+    .user-dateil {
+      display: flex;
+      align-items: center;
+      color: white;
+      font-size: 14px;
+      padding: 10px;
+      .pendant {
+        width: 80px;
+        height: 80px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        background-size: 100% 100%;
+        .avatar {
+          width: 60px;
+          height: 60px;
+          // margin-right: 10px;
+        }
+      }
+
+      .user-right {
+        flex: 1;
+        .user-name {
+          font-weight: 400;
+          font-size: 16px;
+        }
+        .user-block {
+          display: flex;
+          // padding: 0 20px 0 0;
+          justify-content: space-between;
+          margin: 6px 0;
+          font-size: 12px;
+          .tags {
+            display: flex;
+            .sex {
+              border-radius: 50%;
+              width: 20px;
+              height: 20px;
+              display: flex;
+              align-items: center;
+              justify-content: center;
+              box-shadow: rgba(0, 0, 0, 0.15) 0px 15px 25px,
+                rgba(0, 0, 0, 0.05) 0px 5px 10px;
+              background: linear-gradient(to right, #156bfd, #91baff);
+            }
+            .girl {
+              background: linear-gradient(to right, #fe454e, #f5a7ab);
+            }
+            .age {
+              background: linear-gradient(to right, #156bfd, #d3e4ff);
+              display: flex;
+              align-items: center;
+              height: 20px;
+              padding: 0 8px;
+              border-radius: 20px;
+              margin: 0 2px;
+              img {
+                width: 14px;
+                height: 14px;
+                margin-right: 4px;
+              }
+            }
+            .id {
+              background: linear-gradient(to right, #d76f12, #ffffff9c);
+              padding: 0 8px;
+              border-radius: 20px;
+              height: 20px;
+            }
+          }
+          .btn {
+            padding: 2px 10px;
+            background: white;
+            color: #fd7f76;
+            border-radius: 20px;
+            font-size: 14px;
+          }
+        }
+        .user-footer {
+          padding: 0 20px 0 0;
+          display: flex;
+          justify-content: space-between;
+          font-size: 12px;
+        }
+      }
+    }
+  }
+  .ad{
+    display: flex;
+    padding: 10px;
+    font-size: 14px;
+    .text{
+      display: flex;
+    }
+  }
+}

+ 6 - 6
projects/live-app/src/app/components/totas/totas.component.spec.ts → projects/live-app/src/moduls/tabs/my/my.component.spec.ts

@@ -3,21 +3,21 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
 import { By } from '@angular/platform-browser';
 import { DebugElement } from '@angular/core';
 
-import { TotasComponent } from './totas.component';
+import { MyComponent } from './my.component';
 
-describe('TotasComponent', () => {
-  let component: TotasComponent;
-  let fixture: ComponentFixture<TotasComponent>;
+describe('MyComponent', () => {
+  let component: MyComponent;
+  let fixture: ComponentFixture<MyComponent>;
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      declarations: [ TotasComponent ]
+      declarations: [ MyComponent ]
     })
     .compileComponents();
   }));
 
   beforeEach(() => {
-    fixture = TestBed.createComponent(TotasComponent);
+    fixture = TestBed.createComponent(MyComponent);
     component = fixture.componentInstance;
     fixture.detectChanges();
   });

+ 21 - 0
projects/live-app/src/moduls/tabs/my/my.component.ts

@@ -0,0 +1,21 @@
+import { Component, OnInit } from '@angular/core';
+import { IonicModule } from '@ionic/angular';
+
+import * as Parse from 'parse';
+
+@Component({
+  selector: 'app-my',
+  templateUrl: './my.component.html',
+  styleUrls: ['./my.component.scss'],
+  standalone: true,
+  imports: [IonicModule],
+})
+export class MyComponent implements OnInit {
+  user?:Parse.Object = Parse.User.current()
+  constructor() { }
+
+  ngOnInit() {
+    console.log(this.user);
+  }
+
+}

+ 6 - 1
projects/live-app/src/moduls/home/home.module.ts → projects/live-app/src/moduls/tabs/tabs.modules.routes.ts

@@ -1,6 +1,7 @@
 import { NgModule } from '@angular/core';
 import { RouterModule, Routes } from '@angular/router';
 import { HomeComponent } from './home/home.component';
+import { MyComponent } from './my/my.component';
 const routes: Routes = [
   {
     path: '',
@@ -11,9 +12,13 @@ const routes: Routes = [
     path: 'home', //首页
     component: HomeComponent,
   },
+  {
+    path: 'my', //我的
+    component: MyComponent,
+  },
 ]
 @NgModule({
   imports: [RouterModule.forChild(routes)],
   exports: [RouterModule],
 })
-export class HomeRoutingModule { }
+export class TabsRoutingModule { }

+ 7 - 7
projects/live-app/src/moduls/home/tabs/tabs.component.html → projects/live-app/src/moduls/tabs/tabs/tabs.component.html

@@ -23,23 +23,23 @@
       <ion-label>首页</ion-label>
     </ion-tab-button>
 
-    <ion-tab-button tab="center">
-      <ion-icon name="ban-outline"></ion-icon>
+    <ion-tab-button tab="notice">
+      <ion-icon name="notice-outline"></ion-icon>
       <ion-label>消息</ion-label>
     </ion-tab-button>
 
-    <ion-tab-button tab="center">
-      <ion-icon name="ban-outline"></ion-icon>
+    <ion-tab-button tab="live">
+      <ion-icon name="live-outline"></ion-icon>
       <ion-label>直播</ion-label>
     </ion-tab-button>
 
-    <ion-tab-button tab="center">
-      <ion-icon name="ban-outline"></ion-icon>
+    <ion-tab-button tab="order">
+      <ion-icon name="order-outline"></ion-icon>
       <ion-label>排名</ion-label>
     </ion-tab-button>
 
     <ion-tab-button tab="my">
-      <ion-icon name="person"></ion-icon>
+      <ion-icon name="my-outline"></ion-icon>
       <ion-label>我的</ion-label>
     </ion-tab-button>
   </ion-tab-bar>

+ 0 - 0
projects/live-app/src/moduls/home/tabs/tabs.component.scss → projects/live-app/src/moduls/tabs/tabs/tabs.component.scss


+ 0 - 0
projects/live-app/src/moduls/home/tabs/tabs.component.spec.ts → projects/live-app/src/moduls/tabs/tabs/tabs.component.spec.ts


+ 3 - 4
projects/live-app/src/moduls/home/tabs/tabs.component.ts → projects/live-app/src/moduls/tabs/tabs/tabs.component.ts

@@ -14,7 +14,7 @@ import { AlertController } from '@ionic/angular';
   templateUrl: 'tabs.component.html',
   styleUrls: ['tabs.component.scss'],
   standalone: true,
-  imports: [RouterOutlet, IonicModule],
+  imports: [IonicModule],
 })
 export class TabsComponent implements OnInit {
   @Input('tabsOption') tabsOption: any = {};
@@ -58,7 +58,7 @@ export class TabsComponent implements OnInit {
     },
   ];
   show: any;
-  active: number = 0;
+  active: number = Number(localStorage.getItem('active')) || 0;
 
   public ngOnInit() {
     this.presentAlert();
@@ -108,6 +108,7 @@ export class TabsComponent implements OnInit {
       return;
     }
     this.active = index;
+    localStorage.setItem('active',String(this.active))
     if (('temp' + route).indexOf('http') > 0) {
       window.location.href = route;
       console.log('temp' + route);
@@ -124,8 +125,6 @@ export class TabsComponent implements OnInit {
         // 此时路由为数组第一个
         route = r.split(';')[0];
       }
-      console.log(route);
-
       this.router.navigate([route, params]);
     }
     this.allowNavi = false;

+ 11 - 1
projects/live-app/src/styles.scss

@@ -13,4 +13,14 @@ body{
   height: 100%;
   max-height: 100%;
   font-size: 16px;
-}
+}
+@import "@ionic/angular/css/core.css";
+@import "@ionic/angular/css/normalize.css";
+@import "@ionic/angular/css/structure.css";
+@import "@ionic/angular/css/typography.css";
+@import "@ionic/angular/css/display.css";
+@import "@ionic/angular/css/padding.css";
+@import "@ionic/angular/css/float-elements.css";
+@import "@ionic/angular/css/text-alignment.css";
+@import "@ionic/angular/css/text-transformation.css";
+@import "@ionic/angular/css/flex-utils.css";