Browse Source

update invite

warrior 1 day ago
parent
commit
dcd57606ac

BIN
projects/live-app/public/img/android.png


BIN
projects/live-app/public/img/ios.jpg


+ 4 - 0
projects/live-app/src/app/app.routes.ts

@@ -11,6 +11,10 @@ import { LoginAuthGuard } from '../modules/login/auth.guard';
 
 export const routes: Routes = [
   { path: '', redirectTo:'tabs', pathMatch: "full",}, // 默认跳转到 ''
+  {
+    path: 'invite',
+    loadComponent:()=> import('../modules/login/invite/invite.component').then((mod) => mod.InviteComponent),
+  },
   {
     path: 'login',
     canActivate: mapToCanActivate([LoginAuthGuard]),

+ 14 - 12
projects/live-app/src/app/components/appraise/appraise.component.html

@@ -12,32 +12,34 @@
         [scrollable]="true"
         (ionChange)="segmentChanged($event)"
         layout="icon-bottom"
-        value="negativeTags"
+        value="positiveTags"
         mode="md"
       >
         <ion-segment-button
-          value="negativeTags"
+          value="positiveTags"
           class="tabs"
-          content-id="negativeTags"
+          content-id="positiveTags"
         >
-          <ion-label>无感</ion-label>
+          <ion-label>喜欢</ion-label>
         </ion-segment-button>
         <ion-segment-button
-          value="positiveTags"
+          value="negativeTags"
           class="tabs"
-          content-id="positiveTags"
+          content-id="negativeTags"
         >
-          <ion-label>喜欢</ion-label>
+          <ion-label>无感</ion-label>
         </ion-segment-button>
       </ion-segment>
       <div class="list">
         @for (tag of list; track $index) {
-        <span 
-        (click)="onCheck(tag)"
-        [ngClass]="{
+        <span
+          (click)="onCheck(tag)"
+          [ngClass]="{
           'action': checkTags.has(tag),
-        }">{{ tag }}</span>
-        } 
+        }"
+          >{{ tag }}</span
+        >
+        }
       </div>
     </div>
     <ion-toolbar>

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

@@ -51,7 +51,7 @@ export class AppraiseComponent implements OnInit {
     '有创意',
     '很幽默',
   ];
-  list: Array<string> = this.negativeTags;
+  list: Array<string> = this.positiveTags;
   checkTags = new Set();
   constructor(
     private toastController: ToastController,

+ 126 - 0
projects/live-app/src/modules/login/invite/invite.component.html

@@ -0,0 +1,126 @@
+<!-- 注册账号 -->
+@if (!isRegister) {
+<ion-content fullscreen [style.background-image]="'url(img/poster.png)'">
+  <div class="container" style="background-image: url('')">
+    <div class="logo">
+      <div class="invite-title">
+        <span>{{ this.inviteUser?.get("nickname") }}</span> 邀请你加入hey聊
+      </div>
+      <img *ngIf="app?.get('logo')" [src]="app?.get('logo')" alt="" />
+    </div>
+    <div class="input">
+      <div class="icon">
+        <img src="img/phone.png" alt="" />
+      </div>
+      <ion-input
+        inputmode="tel"
+        pattern="tel"
+        type="tel"
+        [(ngModel)]="registerInfo.mobile"
+        placeholder="请输入手机号"
+      ></ion-input>
+    </div>
+    <div class="input">
+      <div class="icon">
+        <img src="img/security.png" alt="" />
+      </div>
+      <ion-input
+        inputmode="numeric"
+        placeholder="请输入验证码"
+        [(ngModel)]="registerInfo.code"
+      ></ion-input>
+      <div
+        class="captcha"
+        (click)="sendVerifyCode(registerInfo.mobile)"
+        *ngIf="!waitStatus"
+      >
+        获取验证码
+      </div>
+      <div class="captcha" *ngIf="waitStatus">{{ wait }}s</div>
+    </div>
+    <div class="input">
+      <div class="icon">
+        <img src="img/password.png" alt="" />
+      </div>
+      <ion-input
+        [type]="inputType"
+        [(ngModel)]="registerInfo.password"
+        placeholder="6-18位数字,字母或符号组合"
+      >
+      </ion-input>
+      <div class="watch" (click)="togglePassword()">
+        <img
+          src="{{ inputType == 'password' ? 'img/show.png' : 'img/hide.png' }}"
+          alt=""
+        />
+      </div>
+    </div>
+    <div class="input">
+      <div class="icon">
+        <img src="img/password.png" alt="" />
+      </div>
+      <ion-input
+        type="password"
+        [(ngModel)]="registerInfo.confirmPassword"
+        placeholder="请再次输入密码"
+      ></ion-input>
+    </div>
+    <div class="input">
+      <div class="icon">
+        <img src="img/invite.png" alt="" />
+      </div>
+      <ion-input
+        type="text"
+        [(ngModel)]="registerInfo.invite"
+        placeholder="请输入邀请人(选填)"
+      ></ion-input>
+    </div>
+    <div class="submit" style="margin-top: 0" (click)="registerUser()">
+      立即注册
+    </div>
+    <!-- <div class="opts" style="justify-content: flex-end">
+        <div
+          class="forget"
+          style="display: flex; align-items: center; color: #000000"
+          (click)="status = 'login'"
+        >
+          已有账号,去登录
+          <img
+            style="
+              width: 32px;
+              height: 32px;
+              transform: scale(0.5);
+              margin-left: 5px;
+            "
+            src="img/login.png"
+            alt=""
+          />
+        </div>
+      </div> -->
+    <div class="agreement">
+      <ion-checkbox color="primary" [(ngModel)]="agreement"></ion-checkbox>
+      <div class="content">
+        我已阅读且同意<span (click)="showAgreement()"
+          >《{{ registerAgreement?.get("title") }}》</span
+        >
+      </div>
+    </div>
+  </div>
+</ion-content>
+} @else {
+<ion-content class="download">
+  <div class="logo">
+    <img *ngIf="app?.get('logo')" [src]="app?.get('logo')" alt="" />
+  </div>
+  <div class="block">
+    <div class="li" (click)="downImg(app.get('apkUrl'))">
+      <div class="h3">下载</div>
+      <img class="android" src="img/android.png" alt="" />
+    </div>
+    <div class="li" (click)="downImg(app.get('itunesUrl'))">
+      <div class="h3">下载</div>
+      <img class="ios" src="img/ios.jpg" alt="" />
+    </div>
+  </div>
+</ion-content>
+}

+ 228 - 0
projects/live-app/src/modules/login/invite/invite.component.scss

@@ -0,0 +1,228 @@
+ion-header {
+  background-color: transparent;
+
+  ion-toolbar {
+    --border-style: none;
+  }
+}
+ion-content {
+  // --padding-top: 0;
+  --background: #fdfdfd00;
+  font-family: Source Han Sans CN;
+  --keyboard-offset: 0vw;
+  position: relative;
+  // background-image: url("https://file-cloud.fmode.cn/Qje9D4bqol/20241220/b313ov054708770.png") !important;
+  background-repeat: no-repeat;
+  background-position: center top;
+  background-size: 100% 100%;
+  .header {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 11.733vw;
+    background: transparent;
+    display: flex;
+    align-items: center;
+    padding-left: 1.333vw;
+    .title {
+      width: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-size: 4.533vw;
+      font-weight: 600;
+      padding-right: 7.733vw;
+    }
+  }
+  .container {
+    width: 100%;
+    // height: 100%;
+    min-height: 100vh;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    // justify-content: center;
+    // background-image: url('../../../../assetsimg/miner-filecoin/login_meta.png');
+    background-size: 100% 100%;
+    background-repeat: no-repeat;
+    // background-size: cover;
+
+    .input {
+      width: 84vw;
+      height: 10.667vw;
+      background: #f2f1f6;
+      opacity: 0.8;
+      border-radius: 3.2vw;
+      border-bottom: 0.133vw solid #eee;
+      margin-bottom: 5.333vw;
+      display: flex;
+      align-items: center;
+
+      .icon {
+        width: 4.8vw;
+        height: 4.8vw;
+        margin: 0 2.667vw;
+
+        img {
+          width: 100%;
+          height: 100%;
+        }
+      }
+      .watch {
+        width: 5.333vw;
+        height: 4vw;
+        margin: 0 2.667vw;
+        img {
+          width: 100%;
+          height: 100%;
+        }
+      }
+      .captcha {
+        // width: 18.133vw;
+        // height: 6.4vw;
+        border: 0.133vw solid #0113c2;
+        border-radius: 1.067vw;
+        font-size: 3.2vw;
+        font-weight: 400;
+        color: #241aff;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin-right: 2.667vw;
+        text-align: center;
+      }
+    }
+
+    .submit {
+      width: 84vw;
+      height: 10.667vw;
+      background: #fe4f55;
+      border-radius: 3.2vw;
+      font-size: 4.8vw;
+      font-weight: bold;
+      color: #ffffff;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      letter-spacing: 1.333vw;
+      margin-top: 10.667vw;
+    }
+
+    .opts {
+      width: 84vw;
+      height: 8vw;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      margin-top: 4vw;
+      .code {
+        font-size: 3.2vw;
+        font-weight: 400;
+        // color: #FFFFFF;
+      }
+
+      .forget {
+        font-size: 3.2vw;
+        font-weight: 400;
+        // color: #BBBBBB;
+      }
+    }
+
+    .register {
+      width: 84vw;
+      height: 8vw;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-size: 3.2vw;
+      font-weight: 400;
+      // color: #FFFFFE;
+      margin-top: 8vw;
+
+      .icon {
+        width: 8.2051vw;
+        height: 8.2051vw;
+        transform: scale(0.5);
+        margin-left: 1.333vw;
+        img {
+          width: 100%;
+          height: 100%;
+        }
+      }
+    }
+    .agreement {
+      width: 84vw;
+      height: 13.333vw;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-size: 4vw;
+      font-weight: 400;
+      color: #2e2e2e;
+      margin-top: 6.667vw;
+      margin-bottom: 6.667vw;
+      span {
+        color: #3f51b5;
+      }
+      .content {
+        margin-left: 2.667vw;
+        // width: 90%;
+      }
+      ion-checkbox {
+        --background: #108ee9;
+        // --border-color: #fff;
+        // --border-color-checked: #fff;
+        --background-checked: #108ee9;
+      }
+    }
+  }
+}
+input:-webkit-autofill,
+input:-webkit-autofill:hover,
+input:-webkit-autofill:focus,
+input:-webkit-autofill:active {
+  -webkit-transition-delay: 99999s;
+  -webkit-transition: color 99999s ease-out, background-color 99999s ease-out;
+}
+.logo {
+  margin: 60px auto 13.333vw auto;
+  text-align: center;
+  .invite-title {
+    margin: 20px auto;
+    font-size: 14px;
+    span {
+      color: #fe4f55;
+      // font-weight: 700;
+      font-size: 18px;
+    }
+  }
+  img {
+    width: 21.333vw;
+    height: 21.333vw;
+  }
+}
+.block {
+  margin: 30px auto;
+  display: flex;
+  flex-direction: column;
+  .li {
+    width: 300px;
+    margin: auto;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    border: 1px solid;
+    margin-bottom: 20px;
+    padding: 10px;
+    height: 80px;
+    .h3 {
+      font-size: 20px;
+      font-weight: bold;
+    }
+    img {
+      width: 200px;
+      // height: 50px;
+    }
+  }
+}

+ 28 - 0
projects/live-app/src/modules/login/invite/invite.component.spec.ts

@@ -0,0 +1,28 @@
+/* tslint:disable:no-unused-variable */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+
+import { InviteComponent } from './invite.component';
+
+describe('InviteComponent', () => {
+  let component: InviteComponent;
+  let fixture: ComponentFixture<InviteComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ InviteComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(InviteComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 348 - 0
projects/live-app/src/modules/login/invite/invite.component.ts

@@ -0,0 +1,348 @@
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { AuthService } from '../../../services/auth.service';
+import * as Parse from 'parse';
+import { ActivatedRoute } from '@angular/router';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { catchError } from 'rxjs/operators';
+import { AgreementComponent } from '.././agreement/agreement.component';
+
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { CommonModule } from '@angular/common';
+import {
+  ionicStandaloneModules,
+  AlertController,
+  ToastController,
+  ModalController,
+  // LoadingController,
+} from '../../ionic-standalone.modules';
+import { Platform } from '@ionic/angular';
+
+@Component({
+  selector: 'app-invite',
+  templateUrl: './invite.component.html',
+  styleUrls: ['./invite.component.scss'],
+  standalone: true,
+  imports: [
+    CommonModule,
+    FormsModule,
+    ReactiveFormsModule,
+    ...ionicStandaloneModules,
+  ],
+})
+export class InviteComponent implements OnInit {
+  constructor(
+    private toastController: ToastController,
+    public authServ: AuthService,
+    // private router: Router,
+    private activatedRoute: ActivatedRoute,
+    private http: HttpClient,
+    private modalCtrl: ModalController,
+    private alertController: AlertController,
+    // private loadingCtrl: LoadingController
+    private platform: Platform
+  ) {
+    this.company = authServ.company;
+  }
+  inviteUser?:Parse.Object
+  company: string = '';
+  inputType: string = 'password';
+  // 注册
+  agreement: boolean = false;
+  registerAgreement: any;
+  registerInfo: any = {
+    mobile: '',
+    code: '',
+    password: '',
+    confirmPassword: '',
+    invite: '',
+  };
+  isRegister: boolean = false; //是否注册成功
+  app:Parse.Object
+  ngOnInit() {
+    if (this.platform.is('hybrid')) {
+      this.authServ.logout();
+      return;
+    }
+    let invite = localStorage.getItem('invite');
+    console.log('invite:', invite);
+    if (invite) this.registerInfo.invite = invite;
+    this.activatedRoute.paramMap.subscribe(async (param) => {
+      if (invite) {
+        let query = new Parse.Query('User');
+        query.equalTo('invite', invite);
+        query.select('mobile', 'username', 'nickname');
+        this.inviteUser = await query.first();
+      }
+      localStorage.setItem('APP_DEFAULT_COMPANY', 'Qje9D4bqol');
+      localStorage.setItem('company', this.company);
+      if (this.company) {
+        let App = new Parse.Query('App');
+        App.equalTo('company', this.company);
+        this.app = await App.first();
+      }
+      this.getAgreement();
+    });
+  }
+
+  //   获取验证码
+  wait: number = 60;
+  waitStatus: boolean = false;
+  time() {
+    if (this.wait == 0) {
+      this.waitStatus = false;
+      this.wait = 60;
+    } else {
+      this.waitStatus = true;
+      this.wait--;
+      setTimeout(() => {
+        this.time();
+      }, 1000);
+    }
+  }
+
+  //   获取验证码
+  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 (mobile == undefined || !String(mobile).match(a)) {
+      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', {
+        company: this.company,
+        mobile: mobile,
+      })
+      .subscribe((res: any) => {
+        this.waitStatus = true;
+        this.time();
+        this.vcode = res.data.code;
+        this.timer = false;
+      });
+  }
+
+  togglePassword() {
+    if (this.inputType == 'password') {
+      this.inputType = 'text';
+    } else {
+      this.inputType = 'password';
+    }
+  }
+  // 注册账号
+  agree() {
+    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);
+      this.registerAgreement = res;
+    });
+  }
+  async showAgreement() {
+    const modal = await this.modalCtrl.create({
+      component: AgreementComponent,
+      cssClass: 'my-custom-class',
+      componentProps: {
+        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)
+    ) {
+      const toast = await this.toastController.create({
+        message: '请填写正确的手机号',
+        color: 'warning',
+        duration: 1000,
+      });
+      toast.present();
+      return;
+    }
+    if (this.registerInfo.code == undefined || this.registerInfo.code == '') {
+      const toast = await this.toastController.create({
+        message: '请输入验证码',
+        color: 'warning',
+        duration: 1000,
+      });
+      toast.present();
+      return;
+    }
+    if (
+      this.registerInfo.password == undefined ||
+      this.registerInfo.password.trim() == ''
+    ) {
+      const toast = await this.toastController.create({
+        message: '请输入密码',
+        color: 'warning',
+        duration: 1000,
+      });
+      toast.present();
+      return;
+    }
+    if (
+      this.registerInfo.password.length < 6 ||
+      this.registerInfo.password.length.length > 20
+    ) {
+      const toast = await this.toastController.create({
+        message: '密码长度不得小于6位或大于20位',
+        color: 'warning',
+        duration: 1000,
+      });
+      toast.present();
+      return;
+    }
+    if (
+      this.registerInfo.confirmPassword == undefined ||
+      this.registerInfo.confirmPassword.trim() == ''
+    ) {
+      const toast = await this.toastController.create({
+        message: '请确认密码',
+        color: 'warning',
+        duration: 1000,
+      });
+      toast.present();
+      return;
+    }
+    if (
+      this.registerInfo.password.trim() !=
+      this.registerInfo.confirmPassword.trim()
+    ) {
+      const toast = await this.toastController.create({
+        message: '两次输入密码不一致',
+        color: 'warning',
+        duration: 1000,
+      });
+      toast.present();
+      return;
+    }
+    if (!this.agreement) {
+      const alert = await this.alertController.create({
+        cssClass: 'my-custom-class',
+        header: '提示',
+        message: `请先勾选${this.registerAgreement?.get('title')}`,
+        buttons: [
+          {
+            text: '取消',
+            role: 'cancel',
+            cssClass: 'secondary',
+            handler: (blah) => {
+              console.log('Confirm Cancel: blah');
+            },
+          },
+          {
+            text: '同意',
+            handler: () => {
+              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,
+        }
+      : {
+          company: this.company,
+          code: this.registerInfo.code,
+          mobile: this.registerInfo.mobile,
+          password: this.registerInfo.password,
+        };
+    this.http
+      .post(`https://server.fmode.cn/api/auth/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;
+        })
+      )
+      .subscribe(async (res: any) => {
+        console.log(res);
+        if (res && res.code == 200) {
+          const toast = await this.toastController.create({
+            message: res.msg,
+            color: 'success',
+            duration: 1000,
+          });
+          toast.present();
+          const alert = await this.alertController.create({
+            cssClass: 'my-custom-class',
+            header: '注册成功',
+            message: `恭喜你,注册成功`,
+            backdropDismiss: false,
+            buttons: [
+              {
+                text: '确认',
+                handler: () => {
+                  this.registerInfo = {
+                    mobile: '',
+                    code: '',
+                    password: '',
+                    confirmPassword: '',
+                    invite: '',
+                  };
+                  this.isRegister = true
+                },
+              },
+            ],
+          });
+          await alert.present();
+        } else {
+          const toast = await this.toastController.create({
+            // 接口返回的错误,提示用户
+            message: res.mess,
+            color: 'danger',
+            duration: 1000,
+          });
+          toast.present();
+        }
+      });
+  }
+
+  downImg(url:string) {
+    let dlLink: any = document.createElement('a');
+    if ('download' in dlLink) {
+      dlLink.style.visibility = 'hidden';
+      dlLink.href = url;
+      dlLink.download = 'hey聊';
+      document.body.appendChild(dlLink);
+      dlLink.click();
+      document.body.removeChild(dlLink);
+    } else {
+      location.href = url;
+    }
+  }
+}

+ 5 - 11
projects/live-app/src/modules/login/login.component.ts

@@ -47,7 +47,7 @@ export class LoginComponent implements OnInit {
     this.company = authServ.company;
   }
 
-  company: any;
+  company: string = '';
   appName: any;
   logo: any;
   // 显示登陆、注册内容
@@ -83,20 +83,14 @@ export class LoginComponent implements OnInit {
     this.authServ.logout();
     this.activatedRoute.paramMap.subscribe((param) => {
       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);
-      }
-      if (param.get('c')) {
-        this.company = param.get('c');
-      }
+      localStorage.setItem('company', this.company);
       if (this.company) {
-        // localStorage.setItem("company", this.company);
         let App = new Parse.Query('App');
         App.equalTo('company', this.company);
+        App.equalTo('isEnabled',true)
+        App.select('name','logo')
         App.first().then((res) => {
-          console.log(res);
+          // console.log(res);
           if (res && res.id) {
             this.appName = res.get('name');
             this.logo = res.get('logo');

+ 2 - 1
projects/live-app/src/modules/tabs/anthorhome/anthorhome.component.ts

@@ -128,6 +128,7 @@ export class AnthorhomeComponent implements OnInit {
     query.equalTo('company', this.aiServ.company);
     query.descending('index');
     query.equalTo('isEnabled', true);
+    query.equalTo('type', 'home');
     query.notEqualTo('isDeleted', true);
     let banner = await query.find();
     this.banner = banner;
@@ -183,7 +184,7 @@ export class AnthorhomeComponent implements OnInit {
       observer: false, //修改swiper自己或子元素时,自动初始化swiper
       observeParents: true, //修改swiper的父元素时,自动初始化swiper
       autoplay: {
-        delay: 5000,
+        delay: 3000,
       },
       direction: 'vertical',
     });

+ 2 - 1
projects/live-app/src/modules/tabs/home/home.component.ts

@@ -139,6 +139,7 @@ export class HomeComponent implements OnInit {
     query.equalTo('company', this.aiServ.company);
     query.descending('index');
     query.equalTo('isEnabled', true);
+    query.equalTo('type', 'home');
     query.notEqualTo('isDeleted', true);
     let banner = await query.find();
     this.banner = banner;
@@ -174,7 +175,7 @@ export class HomeComponent implements OnInit {
       observer: false, //修改swiper自己或子元素时,自动初始化swiper
       observeParents: true, //修改swiper的父元素时,自动初始化swiper
       autoplay: {
-        delay: 5000,
+        delay: 3000,
       },
       direction: 'vertical',
     });

+ 2 - 2
projects/live-app/src/modules/tabs/my/my.component.html

@@ -61,8 +61,8 @@
           </div>
         </div>
         <div class="user-footer">
-          <div class="row" (click)="toUrl('user/friends')">{{ userObj.fans }} 粉丝</div>
-          <div class="row" (click)="toUrl('user/friends')">{{ userObj.follow }} 关注</div>
+          <div class="row" (click)="toUrl('user/friends')">{{ profile?.get('degreeNumber') || userObj.fans }} 粉丝</div>
+          <div class="row" (click)="toUrl('user/friends')">{{  userObj.follow }} 关注</div>
           <div class="row">{{ userObj.friendly_degree }} 亲密度</div>
         </div>
       </div>

+ 1 - 1
projects/live-app/src/modules/tabs/my/my.component.ts

@@ -108,7 +108,7 @@ export class MyComponent implements OnInit {
     let query = new Parse.Query('Profile');
     query.equalTo('user', user?.id);
     query.notEqualTo('isDeleted', true);
-    query.select('isCheck', 'isCross','birthdate','identyType');
+    query.select('isCheck', 'isCross','birthdate','identyType','degreeNumber');
     this.profile = await query.first();
   }
   getAgreement() {

+ 39 - 59
projects/live-app/src/modules/user/profile/profile.component.html

@@ -8,18 +8,6 @@
     <div class="user-dateil">
       <div class="pendant">
         <div class="top">
-          <!-- <div
-            class="pendant"
-            [style.background-image]="
-              'url(https://file-cloud.fmode.cn/Qje9D4bqol/20241109/vv1tvb032259054.png)'
-            "
-          >
-            <img
-              class="avatar"
-              [src]="profile?.get('user')?.get('avatar')"
-              alt=""
-            />
-          </div> -->
           @if(!loading){
           <app-avatar
             [avatar]="profile?.get('user')?.get('avatar')"
@@ -41,61 +29,52 @@
             }@else {
             <!-- <div class="sex">未知</div> -->
             }
-            <div
-              [ngClass]="{
-                gril: profile?.get('user')?.get('sex') == '女',
-                age: true
-              }"
-            >
-              <img
-                src="https://file-cloud.fmode.cn/Qje9D4bqol/20241109/pctmvt110807052.png"
-                alt=""
-              />
-              {{ profile?.get("birthdate") || "未知" }}
-            </div>
+            @if (profile?.get('identyType') == 'anchor') {
+              <div
+                class="level"
+                [style.background-color]="
+                  aiChatServ.authorLevelColor[
+                    profile?.get('user').get('completionRate')
+                  ]?.color
+                "
+              >
+                LV{{ profile?.get("user").get("completionRate") }}
+              </div>
+              }@else {
+              <div
+                class="level"
+                [style.background-color]="
+                  aiChatServ.userLevelColor[
+                    profile?.get('user').get('achievementCount')
+                  ]?.color
+                "
+              >
+                LV{{ profile?.get("user").get("achievementCount") }}
+              </div>
+              }
           </div>
         </div>
         <div class="user-status">
           <span class="id">爱聊ID:{{ profile?.get("user")?.id }}</span>
-          <!-- @if (profile?.get('isCheck')) {
-          <div class="state">
-            <span class="spot"></span>
-            <span class="tag">勿扰</span>
-          </div>
-          }@else { -->
           <div class="state">
             <span class="spot" [style.background]="state.color"></span>
             <span class="tag">{{ state.val }}</span>
           </div>
-          <!-- } -->
-          <!-- @if (profile?.get('identyType') === 'anchor') {
-          <div class="video-unit">
-            通话:{{ profile?.get("laborCosts") }}钻石/分钟
-          </div>
-          } -->
-          @if (profile?.get('identyType') == 'anchor') {
-          <div
-            class="level"
-            [style.background-color]="
-              aiChatServ.authorLevelColor[
-                profile?.get('user').get('completionRate')
-              ]?.color
-            "
-          >
-            LV{{ profile?.get("user").get("completionRate") }}
-          </div>
-          }@else {
+        
+
           <div
-            class="level"
-            [style.background-color]="
-              aiChatServ.userLevelColor[
-                profile?.get('user').get('achievementCount')
-              ]?.color
-            "
-          >
-            LV{{ profile?.get("user").get("achievementCount") }}
-          </div>
-          }
+          [ngClass]="{
+            gril: profile?.get('user')?.get('sex') == '女',
+            age: true
+          }"
+        >
+          <img
+            src="https://file-cloud.fmode.cn/Qje9D4bqol/20241109/pctmvt110807052.png"
+            alt=""
+          />
+          {{ profile?.get("birthdate") || "未知" }}
+        </div>
+
         </div>
       </div>
       <div class="user-right">
@@ -110,7 +89,7 @@
     </div>
     <div class="user-fans">
       <span>关注:{{ numsObject.follow }}</span>
-      <span>粉丝:{{ numsObject.fans }}</span>
+      <span>粉丝:{{ profile?.get('degreeNumber') || numsObject.fans }}</span>
       <span>送出:{{ numsObject.gift }}</span>
     </div>
     <div class="bar"></div>
@@ -285,6 +264,7 @@
       </ion-buttons>
     </ion-toolbar>
     <div class="wrapper">
+      <div style="margin-bottom: 10px;">建议图片比例 2.5:1</div>
       <app-upload
         (onChange)="onSaveBackGround($event)"
         #upload

+ 31 - 0
projects/live-app/src/modules/user/profile/profile.component.scss

@@ -99,6 +99,14 @@
                 #f5a7ab
               ) !important;
             }
+            .level {
+              margin-left: 1.5385vw;
+              text-align: center;
+              font-size: 3.0769vw;
+              border-radius: 5.1282vw;
+              padding: 0vw 1.5385vw;
+              color: #000;
+            }
           }
         }
         .user-status {
@@ -137,6 +145,28 @@
           .video-unit {
             margin-left: 2.5641vw;
           }
+          .age {
+            background: linear-gradient(to right, #156bfd, #d3e4ff);
+            display: flex;
+            align-items: center;
+            height: 5.1282vw;
+            padding: 0 2.0513vw;
+            border-radius: 5.1282vw;
+            margin: 0 0.5128vw;
+            color: white;
+            img {
+              width: 3.5897vw;
+              height: 3.5897vw;
+              margin-right: 1.0256vw;
+            }
+          }
+          .gril {
+            background: linear-gradient(
+              to right,
+              #fe454e,
+              #f5a7ab
+            ) !important;
+          }
         }
       }
       .user-right {
@@ -378,6 +408,7 @@ ion-modal {
 .wrapper {
   height: 100%;
   display: flex;
+  flex-direction: column;
   align-items: center;
   justify-content: center;
 }

+ 1 - 0
projects/live-app/src/modules/user/share/share.component.scss

@@ -48,6 +48,7 @@
     background: white;
     max-height: 500px;
     overflow-y: scroll;
+    margin-top: 10px;
     .title{
       margin-bottom: 6px;
     }

+ 26 - 5
projects/live-app/src/modules/user/share/share.component.ts

@@ -6,6 +6,7 @@ import * as Parse from 'parse';
 import { ionicStandaloneModules } from '../../ionic-standalone.modules';
 import { Router } from '@angular/router';
 import { CommonModule, DatePipe } from '@angular/common';
+import { AiChatService } from '../../../services/aichart.service';
 
 @Component({
   selector: 'app-share',
@@ -24,14 +25,16 @@ export class ShareComponent implements OnInit {
     'https://file-cloud.fmode.cn/Qje9D4bqol/20241220/qvj1bm054428527.png';
   codeUrl: string = '';
   list:Array<Parse.Object> = []
-
+  url:string = 'https://chat.gdchat.cn' //分享链接
   constructor(
     private toastController: ToastController,
+    private aiServ: AiChatService,
     private router: Router,
     private http: HttpClient
   ) {}
 
-  ngOnInit() {
+  async ngOnInit() {
+    await this.getBanner()
     this.getCode()
     this.getInvite()
   }
@@ -47,12 +50,30 @@ export class ShareComponent implements OnInit {
   ngOnChanges() {
     this.getCode();
   }
+  async getBanner() {
+    let type = 'user'
+    if(Parse.User.current().get('angentLevel')){
+      type = 'union'
+    }else if(this.aiServ.identity){
+      type = 'uanchor'
+    }
+    let query = new Parse.Query('Banner');
+    query.equalTo('company', this.aiServ.company);
+    query.descending('index');
+    query.equalTo('isEnabled', true);
+    query.equalTo('type', type);
+    query.notEqualTo('isDeleted', true);
+    let res = await query.first();
+    if(res?.id){
+      this.bannerUrl = res?.get('image');
+      this.url = res?.get('url');
+    }
+  }
   getCode() {
     console.log('getcode');
     let uid = Parse.User.current()?.id;
-    let qrCodeUrl = `https://chat.gdchat.cn?invite=${uid}`;
     let params = {
-      qrCode: qrCodeUrl,
+      qrCode: this.url + `?invite=${uid}`,
       darkColor: '#ffffff',
       lightColor: '#000000',
     };
@@ -95,7 +116,7 @@ export class ShareComponent implements OnInit {
    */
   async copyText() {
     let uid = Parse.User.current()?.id;
-    let text = `https://chat.gdchat.cn?invite=${uid}`;
+    let text = this.url + `?invite=${uid}`;
     // let oInput = document.createElement("input");
     // oInput.value = text;
     // document.body.appendChild(oInput);