Explorar el Código

update 首页切换

warrior hace 4 meses
padre
commit
0ce2e080c6

BIN
projects/live-app/public/img/通知广播.png


+ 80 - 0
projects/live-app/src/app/components/gift-modal/gift-modal.component.html

@@ -0,0 +1,80 @@
+<ion-modal
+  #modal
+  [isOpen]="isOpenGift"
+  [initialBreakpoint]="1"
+  [breakpoints]="[0, 1]"
+  (didDismiss)="isOpenGift = false"
+  class="gift-modal"
+>
+  <ng-template>
+    <div class="gift-region">
+      <ion-toolbar>
+        <div class="gift-tabs">
+          @for (item of tabs; track $index) {
+          <div
+            [style.color]="activeTab == item.val ? '#000' : '#6b6b6b'"
+            class="tab"
+            (click)="selectTab(item.val)"
+          >
+            {{ item.name }}
+          </div>
+          }
+        </div>
+      </ion-toolbar>
+      <div class="gift-content">
+        <div class="gift-list">
+          @for (item of giftList; track $index) {
+          <div
+            [ngClass]="{
+              'gift-item-acitve': currentGift?.id == item?.id,
+              'gift-item': true
+            }"
+            (click)="currentGift = item"
+          >
+            <div class="img">
+              <img [src]="item.imgUrl" alt="" />
+            </div>
+            <div class="info">
+              <div class="name">{{ item.name }}</div>
+              <div class="price">
+                <img class="credit" src="img/credit.png" alt="" />{{
+                  item.price
+                }}
+              </div>
+            </div>
+          </div>
+          }
+        </div>
+      </div>
+      <div class="gift-footer">
+        <div class="left">
+          <img src="img/credit.png" alt="" class="credit" />
+          <span class="credit-num">{{ wallet.balance }}</span>
+        </div>
+        <div class="btns">
+          @if (currentGift?.id) {
+          <div class="chang-gift">
+            {{ currentGift?.name }} {{ currentGift?.price }}/个
+          </div>
+          }
+          <input
+            [(ngModel)]="giftCount"
+            min="1"
+            type="number"
+            class="input-num"
+            (blur)="onChange()"
+            [disabled]="!currentGift?.id"
+          />
+          <div class="btn-item" (click)="sendGift()">
+            <span>赠送</span>
+          </div>
+        </div>
+      </div>
+    </div>
+  </ng-template>
+</ion-modal>
+@if (isShowGiftModal) {
+<div class="modal-gift-img">
+  <img [src]="currentGift?.imgUrl" alt="" />
+</div>
+}

+ 151 - 0
projects/live-app/src/app/components/gift-modal/gift-modal.component.scss

@@ -0,0 +1,151 @@
+.gift-modal {
+  --height: 400px;
+}
+.gift-region {
+  position: relative;
+  .gift-tabs {
+    display: flex;
+    font-size: 14px;
+    font-weight: bold;
+    padding: 0 10px;
+    .tab {
+      margin-right: 10px;
+    }
+  }
+  .gift-content {
+    overflow-y: scroll;
+    padding-bottom: 100px;
+    height: 356px;
+    .gift-list {
+      display: grid;
+      grid-template-columns: repeat(4, 1fr);
+      grid-gap: 10px;
+      padding: 6px;
+      .gift-item {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        border-radius: 10px;
+        border: 1px solid #fff;
+        font-size: 14px;
+        .img {
+          width: 40px;
+          height: 40px;
+          border-radius: 10px;
+        }
+        .info {
+          text-align: center;
+          .name {
+            margin: 6px 0;
+          }
+          .price {
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            color: #6b6b6b;
+            font-family: PingFang SC;
+            font-size: 12px;
+            .credit {
+              width: 10px;
+              height: 10px;
+            }
+          }
+        }
+      }
+      .gift-item-acitve {
+        border: 1px solid #fc3651 !important;
+      }
+    }
+  }
+  .gift-footer {
+    position: absolute;
+    bottom: 0;
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    height: 80px;
+    padding: 20px;
+    padding-bottom: 20px;
+    background: linear-gradient(
+      rgb(255 255 255 / 31%),
+      rgb(255 255 255 / 86%),
+      #ffffff,
+      #fdfdfd
+    );
+    align-items: flex-end;
+    .left {
+      display: flex;
+      align-items: center;
+      font-size: 12px;
+      .credit {
+        width: 10px;
+        height: 10px;
+        margin-right: 6px;
+      }
+    }
+    .btns {
+      display: flex;
+      align-items: center;
+      .chang-gift {
+        font-size: 14px;
+      }
+      .input-num {
+        width: 50px;
+        height: 24px;
+        margin-right: 10px;
+        border-radius: 6px;
+        border: 1px solid #dcdcdc;
+      }
+      .btn-item {
+        background-color: #fc3651;
+        color: white;
+        padding: 4px 16px;
+        border-radius: 16px;
+        font-size: 14px;
+      }
+    }
+  }
+}
+.modal-gift-img {
+  position: fixed;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: #000000b0;
+  z-index: 999;
+  img{
+    animation: scaleUp 5s ease-in-out forwards; /* 使用scaleUp动画,持续3秒 */
+    position: absolute;
+    bottom: 0;
+  }
+}
+@keyframes scaleUp {
+  0% {
+    transform: scale(0.1); /* 从0.1倍大小开始 */
+  }
+  50%{
+    transform: scale(0.1);
+    bottom: 400px;
+  }
+  60% {
+    transform: scale(0.8);
+    bottom: 400px;
+  }
+  70% {
+    transform: scale(0.2);
+    bottom: 400px;
+  }
+  90%{
+    transform: scale(1.2); /* 放大到原始大小 */
+    bottom: 400px;
+  }
+  100% {
+    transform: scale(1.2); /* 放大到原始大小 */
+    bottom: 400px;
+  }
+}

+ 28 - 0
projects/live-app/src/app/components/gift-modal/gift-modal.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 { GiftModalComponent } from './gift-modal.component';
+
+describe('GiftModalComponent', () => {
+  let component: GiftModalComponent;
+  let fixture: ComponentFixture<GiftModalComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ GiftModalComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(GiftModalComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 119 - 0
projects/live-app/src/app/components/gift-modal/gift-modal.component.ts

@@ -0,0 +1,119 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import {
+  AlertController,
+  IonicModule,
+  LoadingController,
+} from '@ionic/angular';
+import { AiChatService } from '../../../services/aichart.service';
+import { LiveService } from '../../../services/live.service';
+import * as Parse from 'parse';
+@Component({
+  selector: 'app-gift-modal',
+  templateUrl: './gift-modal.component.html',
+  styleUrls: ['./gift-modal.component.scss'],
+  standalone: true,
+  imports: [IonicModule, CommonModule, FormsModule],
+})
+export class GiftModalComponent implements OnInit {
+  @Input('toUid') toUid!: string; // 接收礼物的uid
+
+  isOpenGift: boolean = false; // 是否显示礼物弹窗
+  giftList: Array<any> = [];
+  tabs: Array<any> = [
+    {
+      name: '礼物',
+      val: 'all',
+    },
+    {
+      name: '专属礼物',
+      val: 'vip',
+    },
+    {
+      name: '守护',
+      val: 'guard',
+    },
+  ];
+  activeTab: string = 'all';
+  currentGift: any; //当前礼物
+  giftCount: number = 1;
+  wallet: any = { balance: 0 };
+  isShowGiftModal: boolean = false; // 是否显示礼物动效弹窗
+  times: any;
+  @Output() sendEmit: EventEmitter<any> = new EventEmitter<any>();
+
+  constructor(
+    private aiServ: AiChatService,
+    private alertController: AlertController,
+    public liveService: LiveService,
+    private loadingCtrl: LoadingController
+  ) {}
+
+  async ngOnInit() {
+    this.giftList = await this.aiServ.getGift();
+  }
+  async openModal() {
+    let uid: any = Parse.User.current()?.id;
+    this.wallet = await this.aiServ.getWallet(uid);
+    this.isOpenGift = true;
+  }
+  async selectTab(val: string) {
+    if (this.activeTab === val) return;
+    this.giftList = await this.aiServ.getGift(val == 'all' ? '' : val);
+    this.activeTab = val;
+    this.currentGift = null;
+  }
+  onChange() {
+    this.giftCount = this.giftCount < 1 ? 1 : Math.floor(this.giftCount);
+    console.log(this.giftCount);
+  }
+
+  async sendGift() {
+    let _this = this
+    if (!this.currentGift?.id || this.giftCount < 1) return;
+    const alert = await this.alertController.create({
+      cssClass: 'my-custom-class',
+      header: '送出礼物',
+      message: `确定送出${this.giftCount}件${this.currentGift.name}吗`,
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel',
+          cssClass: 'secondary',
+          handler: (blah) => {},
+        },
+        {
+          text: '确定',
+          handler: async () => {
+            const loading = await _this.loadingCtrl.create({
+              message: '送出礼物中...',
+            });
+            loading.present();
+            _this.aiServ
+              .putGift(_this.toUid, _this.currentGift.id, _this.giftCount)
+              .then((data) => {
+                console.log(data);
+                // _this.liveService.get_duration();
+                _this.sendEmit.emit(); //触发父组件的sendEmit事件
+                loading.dismiss();
+                _this.isOpenGift = false;
+                _this.isShowGiftModal = true;
+                setTimeout(() => {
+                  _this.isShowGiftModal = false;
+                  console.log(_this.isShowGiftModal);
+                  console.log('5s后关闭');
+                }, 5000);
+              })
+              .catch((err) => {
+                _this.isOpenGift = false;
+                loading.dismiss();
+                console.error(err);
+              });
+          },
+        },
+      ],
+    });
+    await alert.present();
+  }
+}

+ 13 - 87
projects/live-app/src/moduls/live/link-page/link-page.component.html

@@ -31,13 +31,13 @@
   >
     <div class="row" style="justify-content: center">
       @if(liveService.connection_state === 'connected'){
-        <div class="tips">
-          剩余通话时长
-          <span
-            [style.color]="liveService.countdown > 120 ? '#ffc409' : '#ff2636'"
-            >{{ liveService.countdown | secondsToTime }}</span
-          >
-        </div>
+      <div class="tips">
+        剩余通话时长
+        <span
+          [style.color]="liveService.countdown > 120 ? '#ffc409' : '#ff2636'"
+          >{{ liveService.countdown | secondsToTime }}</span
+        >
+      </div>
       }
     </div>
     @if (!liveService.isAnchor) {
@@ -105,85 +105,11 @@
       </div>
     </div>
   </div>
-  <ion-modal
-    #modal
-    [isOpen]="showGiftModal"
-    [initialBreakpoint]="1"
-    [breakpoints]="[0, 1]"
-    (didDismiss)="showGiftModal = false"
-    class="gift-modal"
-  >
-    <ng-template>
-      <div class="gift-region">
-        <ion-toolbar>
-          <div class="gift-tabs">
-            @for (item of tabs; track $index) {
-            <div
-              [style.color]="activeTab == item.val ? '#000' : '#6b6b6b'"
-              class="tab"
-              (click)="selectTab(item.val)"
-            >
-              {{ item.name }}
-            </div>
-            }
-          </div>
-        </ion-toolbar>
-        <div class="gift-content">
-          <div class="gift-list">
-            @for (item of giftList; track $index) {
-            <div
-              [ngClass]="{
-                'gift-item-acitve': currentGift?.id == item?.id,
-                'gift-item': true
-              }"
-              (click)="currentGift = item"
-            >
-              <div class="img">
-                <img [src]="item.imgUrl" alt="" />
-              </div>
-              <div class="info">
-                <div class="name">{{ item.name }}</div>
-                <div class="price">
-                  <img class="credit" src="img/credit.png" alt="" />{{
-                    item.price
-                  }}
-                </div>
-              </div>
-            </div>
-            }
-          </div>
-        </div>
-        <div class="gift-footer">
-          <div class="left">
-            <img src="img/credit.png" alt="" class="credit" />
-            <span class="credit-num">{{ wallet.balance }}</span>
-          </div>
-          <div class="btns">
-            @if (currentGift?.id) {
-            <div class="chang-gift">
-              {{ currentGift?.name }} {{ currentGift?.price }}/个
-            </div>
-            }
-            <input
-              [(ngModel)]="giftCount" 
-              min="1"
-              type="number"
-              class="input-num"
-              (blur)="onChange()"
-              [disabled]="!currentGift?.id"
-            />
-            <div class="btn-item" (click)="sendGift()">
-              <span>赠送</span>
-            </div>
-          </div>
-        </div>
-      </div>
-    </ng-template>
-  </ion-modal>
 </ion-content>
-@if (isShowGiftModal) {
-  <div class="modal-gift-img">
-    <img [src]="currentGift?.imgUrl" alt="" />
-  </div>
+@if (this.room?.id) {
+<app-gift-modal
+  #gift
+  (sendEmit)="onSendGift()"
+  [toUid]="this.room?.get('user').id"
+></app-gift-modal>
 }
-

+ 1 - 150
projects/live-app/src/moduls/live/link-page/link-page.component.scss

@@ -129,153 +129,4 @@
       }
     }
   }
-}
-.gift-modal {
-  --height: 400px;
-}
-.gift-region {
-  position: relative;
-  .gift-tabs {
-    display: flex;
-    font-size: 14px;
-    font-weight: bold;
-    padding: 0 10px;
-    .tab {
-      margin-right: 10px;
-    }
-  }
-  .gift-content {
-    overflow-y: scroll;
-    padding-bottom: 100px;
-    height: 356px;
-    .gift-list {
-      display: grid;
-      grid-template-columns: repeat(4, 1fr);
-      grid-gap: 10px;
-      padding: 6px;
-      .gift-item {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        align-items: center;
-        border-radius: 10px;
-        border: 1px solid #fff;
-        font-size: 14px;
-        .img {
-          width: 40px;
-          height: 40px;
-          border-radius: 10px;
-        }
-        .info {
-          text-align: center;
-          .name {
-            margin: 6px 0;
-          }
-          .price {
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            color: #6b6b6b;
-            font-family: PingFang SC;
-            font-size: 12px;
-            .credit {
-              width: 10px;
-              height: 10px;
-            }
-          }
-        }
-      }
-      .gift-item-acitve {
-        border: 1px solid #fc3651 !important;
-      }
-    }
-  }
-  .gift-footer {
-    position: absolute;
-    bottom: 0;
-    width: 100%;
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    height: 80px;
-    padding: 20px;
-    padding-bottom: 20px;
-    background: linear-gradient(
-      rgb(255 255 255 / 31%),
-      rgb(255 255 255 / 86%),
-      #ffffff,
-      #fdfdfd
-    );
-    align-items: flex-end;
-    .left {
-      display: flex;
-      align-items: center;
-      font-size: 12px;
-      .credit {
-        width: 10px;
-        height: 10px;
-        margin-right: 6px;
-      }
-    }
-    .btns {
-      display: flex;
-      align-items: center;
-      .chang-gift {
-        font-size: 14px;
-      }
-      .input-num {
-        width: 50px;
-        height: 24px;
-        margin-right: 10px;
-        border-radius: 6px;
-        border: 1px solid #dcdcdc;
-      }
-      .btn-item {
-        background-color: #fc3651;
-        color: white;
-        padding: 4px 16px;
-        border-radius: 16px;
-        font-size: 14px;
-      }
-    }
-  }
-}
-.modal-gift-img {
-  position: fixed;
-  width: 100%;
-  height: 100%;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  background: #000000b0;
-  img{
-    animation: scaleUp 5s ease-in-out forwards; /* 使用scaleUp动画,持续3秒 */
-    position: absolute;
-    bottom: 0;
-  }
-}
-@keyframes scaleUp {
-  0% {
-    transform: scale(0.1); /* 从0.1倍大小开始 */
-  }
-  50%{
-    transform: scale(0.1);
-    bottom: 400px;
-  }
-  60% {
-    transform: scale(0.8);
-    bottom: 400px;
-  }
-  70% {
-    transform: scale(0.2);
-    bottom: 400px;
-  }
-  90%{
-    transform: scale(1.2); /* 放大到原始大小 */
-    bottom: 400px;
-  }
-  100% {
-    transform: scale(1.2); /* 放大到原始大小 */
-    bottom: 400px;
-  }
-}
+}

+ 11 - 86
projects/live-app/src/moduls/live/link-page/link-page.component.ts

@@ -6,7 +6,6 @@ import {
   AlertController,
   IonicModule,
   LoadingController,
-  ModalController,
   ToastController,
 } from '@ionic/angular';
 import { ActivatedRoute } from '@angular/router';
@@ -14,6 +13,7 @@ import { LiveComponent } from '../../../app/components/live/live.component';
 import { LiveService } from '../../../services/live.service';
 import { SharedModule } from '../../shared.module';
 import { AiChatService } from '../../../services/aichart.service';
+import { GiftModalComponent } from '../../../app/components/gift-modal/gift-modal.component';
 @Component({
   selector: 'app-link-page',
   templateUrl: './link-page.component.html',
@@ -25,6 +25,7 @@ import { AiChatService } from '../../../services/aichart.service';
     LiveComponent,
     CommonModule,
     SharedModule,
+    GiftModalComponent,
   ],
 })
 export class LinkPageComponent implements OnInit {
@@ -34,28 +35,8 @@ export class LinkPageComponent implements OnInit {
   room?: Parse.Object;
   isFollow: boolean = false;
   showTool: boolean = true; // 是否显示工具栏
-  showGiftModal: boolean = false; // 是否显示礼物弹窗
-  giftList: Array<any> = [];
-  tabs: Array<any> = [
-    {
-      name: '礼物',
-      val: 'all',
-    },
-    {
-      name: '专属礼物',
-      val: 'vip',
-    },
-    {
-      name: '守护',
-      val: 'guard',
-    },
-  ];
-  activeTab: string = 'all';
-  currentGift: any; //当前礼物
-  giftCount: number = 1;
-  wallet: any = { balance: 0 };
-  isShowGiftModal: boolean = false; // 是否显示礼物动效弹窗
-  times: any;
+  @ViewChild('gift') gift!: GiftModalComponent;
+
   constructor(
     public toastController: ToastController,
     private loadingCtrl: LoadingController,
@@ -81,9 +62,7 @@ export class LinkPageComponent implements OnInit {
       message: '加载中',
     });
     loading.present();
-    this.getRoom();
-    this.giftList = await this.aiServ.getGift();
-    console.log(this.giftList);
+    await this.getRoom();
     loading.dismiss();
   }
   async getRoom() {
@@ -105,12 +84,6 @@ export class LinkPageComponent implements OnInit {
     let r = await query.first();
     this.isFollow = r?.id ? true : false;
   }
-  async selectTab(val: string) {
-    if (this.activeTab === val) return;
-    this.giftList = await this.aiServ.getGift(val == 'all' ? '' : val);
-    this.activeTab = val;
-    this.currentGift = null;
-  }
   /* 关注 */
   async onCollection() {
     let query = new Parse.Query('ProfileRadar');
@@ -153,60 +126,13 @@ export class LinkPageComponent implements OnInit {
         this.liveService.muteAudio();
         break;
       case 'gift':
-        let uid: any = Parse.User.current()?.id;
-        this.wallet = await this.aiServ.getWallet(uid);
-        this.showGiftModal = true;
+        this.gift.openModal();
         break;
     }
   }
-  async sendGift() {
-    if (!this.currentGift?.id || this.giftCount < 1) return;
-    const alert = await this.alertController.create({
-      cssClass: 'my-custom-class',
-      header: '送出礼物',
-      message: `确定送出${this.giftCount}件${this.currentGift.name}吗`,
-      buttons: [
-        {
-          text: '取消',
-          role: 'cancel',
-          cssClass: 'secondary',
-          handler: (blah) => {},
-        },
-        {
-          text: '确定',
-          handler: async () => {
-            const loading = await this.loadingCtrl.create({
-              message: '送出礼物中...',
-            });
-            loading.present();
-            let fid = this.room?.get('user').id;
-            this.aiServ
-              .putGift(fid, this.currentGift.id, this.giftCount)
-              .then((data) => {
-                console.log(data);
-                this.liveService.get_duration()
-                loading.dismiss();
-                this.showGiftModal = false;
-                this.isShowGiftModal = true;
-                setTimeout(() => {
-                  this.isShowGiftModal = false;
-                }, 5000);
-              })
-              .catch((err) => {
-                this.showGiftModal = false;
-                loading.dismiss();
-                console.error(err);
-              });
-          },
-        },
-      ],
-    });
-    await alert.present();
-  }
-
-  onChange() {
-    this.giftCount = this.giftCount < 1 ? 1 : Math.floor(this.giftCount);
-    console.log(this.giftCount);
+  onSendGift() {
+    console.log('点击送出礼物');
+    // this.liveService.get_duration()
   }
   /* 结束直播 */
   async endCall(e: any) {
@@ -219,8 +145,7 @@ export class LinkPageComponent implements OnInit {
         {
           text: '取消',
           role: 'cancel',
-          handler: (blah) => {
-          },
+          handler: (blah) => {},
         },
         {
           text: '确定',
@@ -234,7 +159,7 @@ export class LinkPageComponent implements OnInit {
     });
     await alert.present();
   }
-  async onReport(e: any){
+  async onReport(e: any) {
     e.cancelBubble = true;
     const alert = await this.alertController.create({
       cssClass: 'my-custom-class',

+ 39 - 13
projects/live-app/src/moduls/tabs/home/home.component.html

@@ -9,7 +9,11 @@
         mode="md"
       >
         @for (item of options; track $index) {
-        <ion-segment-button (click)="getRoom(item?.value)" [value]="item?.value" class="tabs">
+        <ion-segment-button
+          (click)="getRoom(item?.value)"
+          [value]="item?.value"
+          class="tabs"
+        >
           <ion-label>{{ item?.label }}</ion-label>
         </ion-segment-button>
         }
@@ -21,13 +25,6 @@
     </div>
   </div>
   <div class="banner">
-    <!-- <swiper-container (swiper)="onSwiper($event)" class="swiper" [delay]="1000" [speed]="500" [loop]="true">
-      @for (item of banner; track $index) {
-      <swiper-slide>
-        <img [src]="item?.get('image')" alt="" />
-      </swiper-slide>
-      }
-    </swiper-container> -->
     <div class="swiper mySwiper">
       <div class="swiper-wrapper">
         @for (item of banner; track $index) {
@@ -39,6 +36,38 @@
       <div class="swiper-pagination"></div>
     </div>
   </div>
+  <div class="notice">
+    <img src="/img/通知广播.png" alt="" class="notice-icon" />
+    <div class="swiper swiper-notice">
+      <div class="swiper-wrapper">
+        @for (item of notices; track $index) {
+        <div class="swiper-slide notice-item" (click)="presentAlert(item)">
+          <div class="notice-item-title">
+            <div class="notice-item-text">
+              {{ item?.title }}
+            </div>
+          </div>
+          <div class="notice-item-content">
+            {{ item?.content }}
+          </div>
+        </div>
+        }
+      </div>
+    </div>
+  </div>
+  <div class="bar">
+    <ion-select
+      label="主播列表"
+      [placeholder]="sex"
+      cancelText="关闭"
+      okText="确定"
+      (ionChange)="onChangeSex($event)"
+    >
+      <ion-select-option value="all">全部</ion-select-option>
+      <ion-select-option value="女">女主播</ion-select-option>
+      <ion-select-option value="男">男主播</ion-select-option>
+    </ion-select>
+  </div>
   <div class="room-list">
     @for (item of roomList; track $index) {
     <div
@@ -54,10 +83,7 @@
       </div>
       <div class="room-footer">
         <div class="user">
-          {{
-            item?.nickname ||
-              item?.mobile
-          }}
+          {{ item?.nickname || item?.mobile }}
         </div>
         <div class="desc">{{ item?.title }}</div>
         <div class="city-block">
@@ -70,7 +96,7 @@
               src="https://file-cloud.fmode.cn/Qje9D4bqol/20241109/pctmvt110807052.png"
               alt=""
             />
-            {{item.birthdate}}
+            {{ item.birthdate }}
           </div>
         </div>
       </div>

+ 40 - 2
projects/live-app/src/moduls/tabs/home/home.component.scss

@@ -2,7 +2,7 @@
   --padding-bottom: 100px;
   --background: #f8f8f8;
   .header {
-    padding:20px 10px 10px;
+    padding: 20px 10px 10px;
     height: 160px;
     // border-radius: 0 0 50px 50px;
     background-image: url(/img/bg.png);
@@ -67,6 +67,44 @@
       }
     }
   }
+  .notice {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    border-bottom: 1px solid #dbdbdb;
+    padding: 10px;
+    .notice-icon {
+      width: 20px;
+      height: 20px;
+    }
+    .swiper-notice {
+      width: 100%;
+      height: 20px;
+    }
+    .swiper-wrapper {
+      flex: 1;
+      height: 20px;
+
+      .swiper-slide {
+        display: flex;
+        font-size: 14px;
+        background: #ffffff00;
+        .notice-item-title {
+          flex-shrink: 0;
+        }
+        .notice-item-content {
+          display: -webkit-box; //对象作为弹性伸缩盒子模型显示
+          overflow: hidden; //溢出隐藏
+          -webkit-box-orient: vertical; //设置伸缩盒子对象的子元素的排列方式
+          -webkit-line-clamp: 1; //设置 块元素包含的文本行数
+        }
+      }
+    }
+  }
+  .bar{
+    padding:0 10px;
+    font-size: 14px;
+  }
   .room-list {
     display: grid;
     grid-template-columns: repeat(2, 180px);
@@ -156,4 +194,4 @@ ion-modal {
 
 ion-picker {
   margin-bottom: var(--ion-safe-area-bottom);
-}
+}

+ 78 - 22
projects/live-app/src/moduls/tabs/home/home.component.ts

@@ -1,8 +1,11 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
 import * as Parse from 'parse';
-import { IonicModule } from '@ionic/angular';
+import {
+  AlertController,
+  IonicModule,
+  LoadingController,
+} from '@ionic/angular';
 import { Router } from '@angular/router';
-import { AuthService } from '../../../services/auth.service';
 import { Swiper } from 'swiper';
 import { AiChatService } from '../../../services/aichart.service';
 
@@ -59,10 +62,39 @@ export class HomeComponent implements OnInit {
   banner: Array<Parse.Object> = [];
   roomList: Array<any> = [];
   pageSwiper: Swiper | undefined | any;
-
+  notices: Array<any> = [
+    {
+      title: '【公告】',
+      content:
+        '欢迎来到直播间,请遵守直播规则,禁止一切违法直播行为,否则封号处理。',
+      time: '2022-06-01',
+    },
+    {
+      title: '【公告】',
+      content:
+        '欢迎来到直播间,请遵守直播规则,禁止一切违法直播行为,否则封号处理。',
+      time: '2022-06-01',
+    },
+    {
+      title: '【公告】',
+      content:
+        '欢迎来到直播间,请遵守直播规则,禁止一切违法直播行为,否则封号处理。',
+      time: '2022-06-01',
+    },
+  ];
+  viewAnchor: string = localStorage.getItem('viewSex') || '女';
+  get sex(): string {
+    const map: any = {
+      all: '全部',
+      男: '男主播',
+      女: '女主播',
+    };
+    return map[this.viewAnchor];
+  }
   constructor(
+    private loadingCtrl: LoadingController,
+    private alertController: AlertController,
     private router: Router,
-    public authServ: AuthService,
     private aiServ: AiChatService
   ) {}
 
@@ -78,7 +110,7 @@ export class HomeComponent implements OnInit {
   }
   async getBanner() {
     let query = new Parse.Query('Banner');
-    query.equalTo('company', this.authServ.company);
+    query.equalTo('company', this.aiServ.company);
     query.descending('index');
     query.equalTo('isEnabled', true);
     query.notEqualTo('isDeleted', true);
@@ -92,7 +124,7 @@ export class HomeComponent implements OnInit {
       observer: false, //修改swiper自己或子元素时,自动初始化swiper
       observeParents: true, //修改swiper的父元素时,自动初始化swiper
       autoplay: {
-        delay: 1500,
+        delay: 3000,
       },
       pagination: {
         el: '.swiper-pagination',
@@ -101,42 +133,60 @@ export class HomeComponent implements OnInit {
     swiper.on('slideChange', function (event: any) {
       // console.log(event);
     });
+
+    let swiperNot = new Swiper('.swiper-notice', {
+      loop: true, // 循环模式选项
+      observer: false, //修改swiper自己或子元素时,自动初始化swiper
+      observeParents: true, //修改swiper的父元素时,自动初始化swiper
+      autoplay: {
+        delay: 5000,
+      },
+      direction: 'vertical',
+    });
   }
   async getRoom(type?: string) {
+    const loading = await this.loadingCtrl.create({
+      message: '正在加载',
+    });
+    loading.present();
     let data: Array<any> = [];
     if (!type) type = this.currentValue;
-    console.log(type);
     let uid = Parse.User.current()?.id;
+    let sex = this.viewAnchor == 'all' ? null : this.viewAnchor;
     switch (type) {
       case 'follow':
-        data = await this.aiServ.getRooms({ uid: uid, follow: true });
+        data = await this.aiServ.getRooms({ uid: uid, follow: true, sex });
         break;
       case 'recommend':
-        data = await this.aiServ.getRooms({ uid: uid, recommend: true });
+        data = await this.aiServ.getRooms({ uid: uid, recommend: true, sex });
         break;
       case 'news':
-        data = await this.aiServ.getRooms({ uid: uid });
+        data = await this.aiServ.getRooms({ uid: uid, sex });
         break;
       case '三星':
-        data = await this.aiServ.getRooms({ uid: uid, star: '三星' });
+        data = await this.aiServ.getRooms({ uid: uid, star: '三星', sex });
         break;
       case '四星':
-        data = await this.aiServ.getRooms({ uid: uid, star: '四星' });
+        data = await this.aiServ.getRooms({ uid: uid, star: '四星', sex });
         break;
       case '五星':
-        data = await this.aiServ.getRooms({ uid: uid, star: '五星' });
+        data = await this.aiServ.getRooms({ uid: uid, star: '五星', sex });
         break;
       default:
         break;
     }
     this.roomList = data;
     console.log(data);
-    // 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;
+    loading.dismiss();
+  }
+  async presentAlert(item: any) {
+    const alert = await this.alertController.create({
+      header: item.title || '消息通知',
+      message:
+        item.content || 'A message should be a short, complete sentence.',
+      buttons: ['关闭'],
+    });
+    await alert.present();
   }
   segmentChanged(e: any) {
     let { value } = e.detail;
@@ -148,10 +198,10 @@ export class HomeComponent implements OnInit {
   /* 关闭弹窗回调 */
   onDidDismiss(event: CustomEvent) {
     this.isOpen = false;
-    console.log(this.currentValue);
+    // console.log(this.currentValue);
   }
   cancel(type: string, value?: string) {
-    console.log(type, value);
+    // console.log(type, value);
     if (type == 'cancel') {
       this.currentValue = this.oldCurrentValue;
     } else {
@@ -159,7 +209,13 @@ export class HomeComponent implements OnInit {
     }
     this.isOpen = false;
     this.modal.dismiss();
-    this.getRoom()
+    this.getRoom();
+  }
+  onChangeSex(e: any) {
+    // console.log(e.detail.value);
+    localStorage.setItem('viewSex', e.detail.value);
+    this.viewAnchor = e.detail.value;
+    this.getRoom();
   }
   search() {
     this.router.navigate(['live/search']);

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

@@ -40,9 +40,9 @@
           <div class="btn" (click)="toUrl('user/profile/'+user?.id)">个人主页</div>
         </div>
         <div class="user-footer">
-          <div class="row">1.2W 粉丝</div>
-          <div class="row">105 关注</div>
-          <div class="row">1546 亲密度</div>
+          <div class="row">{{userObj.fans}} 粉丝</div>
+          <div class="row">{{userObj.follow}} 关注</div>
+          <div class="row">{{userObj.friendly_degree}} 亲密度</div>
         </div>
       </div>
     </div>

+ 23 - 10
projects/live-app/src/moduls/tabs/my/my.component.ts

@@ -10,6 +10,7 @@ import { AgreementComponent } from '../../login/agreement/agreement.component';
 import { AlertController, ModalController } from '@ionic/angular';
 import { Router } from '@angular/router';
 import { AuthService } from '../../../services/auth.service';
+import { AiChatService } from '../../../services/aichart.service';
 @Component({
   selector: 'app-my',
   templateUrl: './my.component.html',
@@ -19,14 +20,15 @@ import { AuthService } from '../../../services/auth.service';
 })
 export class MyComponent implements OnInit {
   profile?: Parse.Object; //身份信息
-  user?: Parse.Object = Parse.User.current();
+  user: Parse.Object = Parse.User.current()!;
   constructor(
     public loadingCtrl: LoadingController,
     private modalController: ModalController,
     private alertController: AlertController,
     public authServ: AuthService,
     public toastController: ToastController,
-    private router: Router
+    private router: Router,
+    private aiServ: AiChatService
   ) {}
   tools: Array<{ icon: string; title: string; path: string }> = [
     {
@@ -53,9 +55,21 @@ export class MyComponent implements OnInit {
   registerAgreement: any; //用户协议
   liveAgreement: any; //直播协议
   company: string | null = localStorage?.getItem('company');
+  userObj: any = {
+    fans: 0,
+    follow: 0,
+    friendly_degree: 0,
+  };
   ngOnInit() {
+    this.refresh();
+  }
+  async refresh() {
     this.getProfile();
     this.getAgreement();
+    const data = await this.aiServ.getFansAndFollow(this.user.id);
+    console.log(data);
+    const { fans, follow } = data.data[0]
+    this.userObj = { fans, follow, friendly_degree: 0 }
   }
   // 获取用户信息
   async getProfile() {
@@ -63,7 +77,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');
+    query.select('isCheck', 'isCross');
     this.profile = await query.first();
   }
   getAgreement() {
@@ -131,8 +145,8 @@ export class MyComponent implements OnInit {
     }
   }
   /* 进入直播间 */
-  async goRoom(){
-    if(!this.profile?.get('isCross')){
+  async goRoom() {
+    if (!this.profile?.get('isCross')) {
       const alert = await this.alertController.create({
         header: '提示',
         message: '你还未认证主播身份,请认证后再进入直播间',
@@ -141,21 +155,20 @@ export class MyComponent implements OnInit {
             text: '取消',
             role: 'cancel',
             cssClass: 'secondary',
-            handler: (blah) => {
-            },
+            handler: (blah) => {},
           },
           {
             text: '去认证',
             handler: () => {
               console.log('Confirm Cancel: blah');
-              this.toUrl('/user/auchor')
+              this.toUrl('/user/auchor');
             },
           },
         ],
       });
       await alert.present();
-    }else{
-      this.toUrl('/live/room-manage')
+    } else {
+      this.toUrl('/live/room-manage');
     }
   }
   /* 退出登录 */

+ 16 - 18
projects/live-app/src/moduls/user/profile/profile.component.html

@@ -1,10 +1,7 @@
 <nav title="主页信息"></nav>
 <ion-content [fullscreen]="true" class="content">
   <div class="bg">
-    <img
-      [src]="profile?.get('image') || '/img/bg_duf.jpg'"
-      alt=""
-    />
+    <img [src]="profile?.get('image') || '/img/bg_duf.jpg'" alt="" />
     <div class="mask" (click)="onShow()"></div>
   </div>
   <div class="header">
@@ -92,10 +89,6 @@
       <div class="tags">
         @for (t of profile?.get('tag'); track $index) {
         <span class="label tag">{{ t }}</span>
-        <!-- <span class="label tag">天真</span>
-          <span class="label tag">漂亮</span>
-          <span class="label tag">萝莉控</span>
-          <span class="label tag">声优</span> -->
         }
       </div>
     </div>
@@ -139,7 +132,7 @@
         <ion-icon name="create-outline"></ion-icon>编辑资料
       </div>
       }@else{
-      <div class="gift">
+      <div class="gift" (click)="gift.openModal()">
         <ion-icon name="gift-outline"></ion-icon>
       </div>
       @if(profile?.get('idcard')){
@@ -173,14 +166,19 @@
     </ion-toolbar>
     <div class="wrapper">
       <app-upload
-      (onChange)="onSaveBackGround($event)"
-      #upload
-      [maxlenght]="1"
-      [files]="[{url:profile?.get('image')}]"
-      [boxWidth]="320"
-      [fileWidth]="300"
-      [fileHeight]="180"
-    ></app-upload>
+        (onChange)="onSaveBackGround($event)"
+        #upload
+        [maxlenght]="1"
+        [files]="[{ url: profile?.get('image') }]"
+        [boxWidth]="320"
+        [fileWidth]="300"
+        [fileHeight]="180"
+      ></app-upload>
     </div>
   </ng-template>
-</ion-modal>
+</ion-modal>
+<app-gift-modal
+  #gift
+  (sendEmit)="onSendGift()"
+  [toUid]="this.uid"
+></app-gift-modal>

+ 1 - 1
projects/live-app/src/moduls/user/profile/profile.component.scss

@@ -13,7 +13,7 @@
     img {
       width: 100%;
       height: 100%;
-      object-fit: cover;
+      object-fit: contain;
     }
     .mask {
       position: absolute;

+ 10 - 1
projects/live-app/src/moduls/user/profile/profile.component.ts

@@ -1,5 +1,6 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
 import { CommonModule, DatePipe } from '@angular/common';
+import { FormsModule } from '@angular/forms';
 import { NavComponent } from '../../../app/components/nav/nav.component';
 import { ActivatedRoute, Router } from '@angular/router';
 import {
@@ -13,6 +14,7 @@ import { ImagePreviewComponent } from '../../../app/components/image-preview/ima
 import { AiChatService } from '../../../services/aichart.service';
 import { HttpService } from '../../../services/http.service';
 import { UploadComponent } from '../../../app/components/upload/upload.component';
+import { GiftModalComponent } from '../../../app/components/gift-modal/gift-modal.component';
 
 @Component({
   selector: 'app-profile',
@@ -21,11 +23,13 @@ import { UploadComponent } from '../../../app/components/upload/upload.component
   standalone: true,
   imports: [
     IonicModule,
-    DatePipe,
+    FormsModule,
+    // DatePipe,
     NavComponent,
     CommonModule,
     ImagePreviewComponent,
     UploadComponent,
+    GiftModalComponent,
   ],
   providers: [DatePipe],
 })
@@ -48,6 +52,7 @@ export class ProfileComponent implements OnInit {
   giftList: any[] = []; //礼物
   isOpen: boolean = false; //打开弹窗
   room?: Parse.Object;
+  @ViewChild('gift') gift!: GiftModalComponent;
 
   constructor(
     private activateRoute: ActivatedRoute,
@@ -221,4 +226,8 @@ export class ProfileComponent implements OnInit {
     });
     await alert.present();
   }
+  onSendGift() {
+    console.log('点击送出礼物');
+    // this.liveService.get_duration()
+  }
 }

+ 0 - 1
projects/live-app/src/moduls/user/setting/setting.component.html

@@ -47,7 +47,6 @@
     <ion-item>
       <ion-select
         label="性别"
-        placeholder=""
         (ionChange)="onChange($event,'sex')"
         interface="popover"
         placeholder="{{ formData.sex }}"

+ 2 - 2
projects/live-app/src/services/aichart.service.ts

@@ -95,14 +95,14 @@ export class AiChatService {
 
   /* 赠送礼物 */
   async putGift(
-    fromUid: string,
+    toUid: string,
     gid: string,
     giftCount?: number
   ): Promise<any> {
     let baseurl = 'https://server.fmode.cn/api/ailiao/save_gift';
     let reqBody = {
       fromUid: Parse.User.current()?.id,
-      toUid: fromUid,
+      toUid: toUid,
       gid: gid,
       index: giftCount ?? 1,
     };