Browse Source

个人主页

warrior 3 months ago
parent
commit
7cb83b21fe

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


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

@@ -37,7 +37,7 @@
             </div>
             <div class="id">ID:{{ user?.id }}</div>
           </div>
-          <div class="btn" (click)="toUrl('user/profile')">个人主页</div>
+          <div class="btn" (click)="toUrl('user/profile/'+user?.id)">个人主页</div>
         </div>
         <div class="user-footer">
           <div class="row">1.2W 粉丝</div>

+ 80 - 23
projects/live-app/src/moduls/user/profile/profile.component.html

@@ -1,8 +1,11 @@
 <nav title="主页信息"></nav>
 <ion-content [fullscreen]="true" class="content">
   <div class="bg">
-    <img [src]="profile?.get('cover')" alt="" />
-    <div class="mask"></div>
+    <img
+      [src]="profile?.get('image') || '/img/bg_duf.jpg'"
+      alt=""
+    />
+    <div class="mask" (click)="onShow()"></div>
   </div>
   <div class="header">
     <div class="user-dateil">
@@ -15,36 +18,47 @@
           />
           <div class="top-right-block">
             <div class="top-left-title">{{ profile?.get("name") }}</div>
+            @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>
-              } -->
+            }@else if (user?.get('sex') == '女') {
+            <div class="sex girl">
+              <ion-icon name="male-female-outline"></ion-icon>
+            </div>
+            }@else {
+            <div class="sex">未知</div>
+            }
             <div class="age">
               <img
                 src="https://file-cloud.fmode.cn/Qje9D4bqol/20241109/pctmvt110807052.png"
                 alt=""
               />
-              23
+              {{ profiel?.get("age") || "未知" }}
             </div>
           </div>
         </div>
         <div class="user-status">
-          <span class="id">爱聊ID:1234456</span>
+          <span class="id">爱聊ID:{{ user?.id }}</span>
+          @if (profiel?.get('isCheck')) {
           <span class="tag">·勿扰</span>
+          }@else {
+          <!-- <span class="tag"></span> -->
+          }
         </div>
       </div>
       <div class="user-right">
-        <ion-icon name="heart-circle-sharp"></ion-icon>
+        <ion-icon
+          (click)="onCollection()"
+          name="heart-circle-sharp"
+          [style.color]="isFollow ? '#fe454e' : '#b3b3b3'"
+        ></ion-icon>
       </div>
     </div>
     <div class="user-fans">
-      <span>关注:99</span>
-      <span>粉丝:99</span>
-      <span>送出:99</span>
+      <span>关注:{{ numsObject.follow }}</span>
+      <span>粉丝:{{ numsObject.fans }}</span>
+      <span>送出:{{ numsObject.gift }}</span>
     </div>
     <div class="bar"></div>
   </div>
@@ -71,16 +85,18 @@
         <span class="label">星座:未知</span>
         <span class="label">城市:未知</span>
       </div>
-      <div class="motto">忽悠古人心上过,回首山河已是秋。</div>
+      <div class="motto">{{ profile?.get("remark") }}</div>
     </div>
     <div class="data-row">
       <div class="title-text">ta的社交标签</div>
       <div class="tags">
-        <span class="label tag">可爱</span>
-        <span class="label tag">天真</span>
-        <span class="label tag">漂亮</span>
-        <span class="label tag">萝莉控</span>
-        <span class="label tag">声优</span>
+        @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>
     <div class="data-row">
@@ -98,8 +114,8 @@
     <div class="data-row">
       <div class="title-text">ta的礼物墙</div>
       <div class="gift">
-        @for (item of profile?.get('gifts'); track $index) {
-        <img [src]="item" alt="" />
+        @for (item of giftList; track $index) {
+        <img [src]="item?.get('image')" alt="" />
         }
       </div>
     </div>
@@ -107,7 +123,7 @@
     <div class="data-row">
       <div class="title-text">个人相册</div>
       <div class="album">
-        @for (item of profile?.get('album'); track $index) {
+        @for (item of profile?.get('attachment'); track $index) {
         <img [src]="item" alt="" (click)="onShowImg(item)" />
         }
       </div>
@@ -118,11 +134,52 @@
 <ion-footer class="footer">
   <ion-toolbar class="footer-tool">
     <div class="btns">
+      @if (user?.id == uid) {
+      <div class="round" (click)="onEdit()">
+        <ion-icon name="create-outline"></ion-icon>编辑资料
+      </div>
+      }@else{
+      <div class="gift">
+        <ion-icon name="gift-outline"></ion-icon>
+      </div>
+      @if(profile?.get('idcard')){
+      <div class="round">
+        <ion-icon name="videocam-outline"></ion-icon>直播通话
+      </div>
+      }
       <div class="round">
         <ion-icon name="chatbubble-outline"></ion-icon>私信
       </div>
-      <div class="round"><ion-icon name="gift-outline"></ion-icon>送礼</div>
+      }
     </div>
   </ion-toolbar>
 </ion-footer>
 <app-image-preview [image]="currenImg" #preview></app-image-preview>
+<ion-modal
+  #modal
+  trigger="open-modal"
+  [isOpen]="isOpen"
+  (didDismiss)="isOpen = false"
+  [backdropDismiss]="false"
+>
+  <ng-template>
+    <ion-toolbar>
+      <ion-buttons slot="start">
+        <ion-button (click)="isOpen = false">取消</ion-button>
+      </ion-buttons>
+      <ion-buttons slot="end">
+        <ion-button (click)="upload.onUpload()">确认更换</ion-button>
+      </ion-buttons>
+    </ion-toolbar>
+    <div class="wrapper">
+      <app-upload
+      (onChange)="onSaveBackGround($event)"
+      #upload
+      [maxlenght]="1"
+      [files]="[{url:profile?.get('image')}]"
+      [fileWidth]="300"
+      [fileHeight]="180"
+    ></app-upload>
+    </div>
+  </ng-template>
+</ion-modal>

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

@@ -69,6 +69,7 @@
               padding: 0 8px;
               border-radius: 20px;
               margin: 0 2px;
+              color: white;
               img {
                 width: 14px;
                 height: 14px;
@@ -98,7 +99,7 @@
         flex-shrink: 0;
         ion-icon {
           font-size: 40px;
-          color: #fe454e;
+          // color: #fe454e;
         }
       }
     }
@@ -202,20 +203,44 @@
 .footer {
   .btns {
     display: flex;
-    justify-content: space-around;
+    justify-content: space-evenly;
     .round {
-      // background: #156bfd;
-      padding: 8px 30px;
       border-radius: 20px;
       color: #156bfd;
       font-size: 14px;
       display: flex;
       align-items: center;
       border: 1px solid #156bfd;
+      width: 120px;
+      height: 40px;
+      justify-content: center;
       ion-icon{
         font-size: 20px;
         margin-right: 10px;
       }
     }
+    .gift{
+      border-radius: 50%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      border: 1px solid;
+      width: 40px;
+      height: 40px;
+      color: #fe454e;
+      ion-icon{
+        font-size: 30px;
+      }
+    }
   }
 }
+ion-modal {
+  --height: 50%;
+  --border-radius: 16px;
+  --box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
+}
+.wrapper{
+  height: 100%;
+  display: flex;
+  align-items: center;
+}

+ 169 - 25
projects/live-app/src/moduls/user/profile/profile.component.ts

@@ -1,52 +1,196 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
 import { CommonModule, DatePipe } from '@angular/common';
 import { NavComponent } from '../../../app/components/nav/nav.component';
-import { Router } from '@angular/router';
+import { ActivatedRoute, Router } from '@angular/router';
 import {
   IonicModule,
+  LoadingController,
   ToastController,
 } from '@ionic/angular';
 import * as Parse from 'parse';
 import { ImagePreviewComponent } from '../../../app/components/image-preview/image-preview.component';
+import { AiChatService } from '../../../services/aichart.service';
+import { HttpService } from '../../../services/http.service';
+import { UploadComponent } from '../../../app/components/upload/upload.component';
 
 @Component({
   selector: 'app-profile',
   templateUrl: './profile.component.html',
   styleUrls: ['./profile.component.scss'],
   standalone: true,
-  imports: [IonicModule, DatePipe,NavComponent,CommonModule,ImagePreviewComponent],
+  imports: [
+    IonicModule,
+    DatePipe,
+    NavComponent,
+    CommonModule,
+    ImagePreviewComponent,
+    UploadComponent,
+  ],
   providers: [DatePipe],
 })
 export class ProfileComponent implements OnInit {
-  @ViewChild('preview') preview!:ImagePreviewComponent
-  
-  profile: Parse.Object | any = {
-    get: (e: string) => {
-      let jsonb:any = {
-        'cover': `https://file-cloud.fmode.cn/Qje9D4bqol/20241119/sd1upp041122290.jpg`,
-        'user':Parse.User.current(),
-        'name':'甜心宝贝',
-        'album':['https://file-cloud.fmode.cn/Qje9D4bqol/20241119/sd1upp041122290.jpg','https://file-cloud.fmode.cn/Qje9D4bqol/20241119/sd1upp041122290.jpg','https://file-cloud.fmode.cn/Qje9D4bqol/20241119/sd1upp041122290.jpg','https://file-cloud.fmode.cn/Qje9D4bqol/20241119/sd1upp041122290.jpg',],
-        'gifts':['https://file-cloud.fmode.cn/Qje9D4bqol/20241119/sd1upp041122290.jpg','https://file-cloud.fmode.cn/Qje9D4bqol/20241119/sd1upp041122290.jpg','https://file-cloud.fmode.cn/Qje9D4bqol/20241119/sd1upp041122290.jpg','https://file-cloud.fmode.cn/Qje9D4bqol/20241119/sd1upp041122290.jpg',],
-        '': '',
-      };
-      return jsonb[e];
-    },
-    set: () => {},
-    save: () => {},
-    destroy: () => {}, // 修复:添加方法体
+  // @ViewChild('upload') upload!: UploadComponent;
+  uid: string = '';
+  currentUser?: Parse.Object = Parse.User.current(); //当前登录用户
+  profiel?: Parse.Object; // 用户信息
+  user?: Parse.Object; // 查看用户
+  @ViewChild('preview') preview!: ImagePreviewComponent;
+  profile?: Parse.Object;
+  active: number = 0;
+  currenImg: string = '';
+  numsObject: { fans: number; follow: number; gift: number } = {
+    fans: 0, //粉丝量
+    follow: 0, //关注量
+    gift: 0, //送出礼物
   };
-  active:number = 0;
-  currenImg:string = '';
+  isFollow: boolean = false;
+  giftList: Array<Parse.Object> = []; //礼物
+  isOpen: boolean = false; //打开弹窗
   constructor(
+    private activateRoute: ActivatedRoute,
     private router: Router,
     public toastController: ToastController,
-  ) { }
+    public loadingCtrl: LoadingController,
+    private aiChatServ: AiChatService,
+    private http: HttpService,
+  ) {}
 
   ngOnInit() {
+    this.activateRoute.paramMap.subscribe(async (params) => {
+      let id: any = params.get('id');
+      this.uid = id;
+      this.refresh();
+    });
   }
-  onShowImg(url:string){
-    this.currenImg = url
-    this.preview.show = 'inline-flex'
+  async refresh() {
+    const loading = await this.loadingCtrl.create({
+      message: '加载中',
+    });
+    loading.present();
+    await this.getProfile();
+    await this.getFollwState();
+    let res = await this.aiChatServ.getFansAndFollow(this.uid);
+    this.numsObject.fans = res.data[0].fans;
+    this.numsObject.follow = res.data[0].follow;
+    let res1 = await this.aiChatServ.getGift(this.uid);
+    this.numsObject.gift = res.data[0].gift ?? 0;
+    await this.getLoveRender();
+    loading.dismiss();
+  }
+  async getProfile() {
+    const loading = await this.loadingCtrl.create({
+      message: '加载中',
+    });
+    loading.present();
+    let queryProfile = new Parse.Query('Profile');
+    queryProfile.equalTo('user', this.uid);
+    queryProfile.notEqualTo('isDeleted', true);
+    queryProfile.include('user');
+    let p = await queryProfile.first();
+    this.profile = p;
+    if (this.profile?.id) {
+      this.user = this.profile?.get('user');
+    } else {
+      let queryUser = new Parse.Query('_User');
+      queryUser.equalTo('objectId', this.uid);
+      this.user = await queryUser.first();
+    }
+    console.log(this.user, this.profile);
+    loading.dismiss();
+  }
+  /* 关注状态 */
+  async getFollwState() {
+    let query = new Parse.Query('ProfileRadar');
+    query.equalTo('toUser', this.currentUser?.id);
+    query.equalTo('fromUser', this.uid);
+    query.notEqualTo('isDeleted', true);
+    query.equalTo('name', '关注');
+    let r = await query.first();
+    this.isFollow = r?.id ? true : false;
+  }
+  /* 打赏 */
+  async getLoveRender() {
+    let query = new Parse.Query('LoveRender');
+    query.equalTo('toUser', this.uid);
+    query.notEqualTo('isDeleted', true);
+    query.limit(12);
+    this.giftList = await query.find();
+  }
+  /* 关注 */
+  async onCollection() {
+    let query = new Parse.Query('ProfileRadar');
+    query.equalTo('toUser', this.currentUser?.id);
+    query.equalTo('fromUser', this.uid);
+    // query.notEqualTo('isDeleted', true);
+    query.equalTo('name', '关注');
+    let profileRadar = await query.first();
+    if (!profileRadar?.id) {
+      let radar = Parse.Object.extend('ProfileRadar');
+      profileRadar = new radar();
+      profileRadar?.set('toUser', {
+        __type: 'Pointer',
+        className: '_User',
+        objectId: this.uid,
+      });
+      profileRadar?.set('company', {
+        __type: 'Pointer',
+        className: 'Company',
+        objectId: this.currentUser?.get('company')?.id,
+      });
+      profileRadar?.set('fromUser', this.currentUser?.toPointer());
+      profileRadar?.set('name', '关注');
+    }
+    profileRadar?.set('isDeleted', this.isFollow);
+    await profileRadar?.save();
+    this.isFollow = !this.isFollow;
+  }
+  onShowImg(url: string) {
+    this.currenImg = url;
+    this.preview.show = 'inline-flex';
+  }
+  onShow() {
+    if (this.uid == this.currentUser?.id) this.isOpen = true;
+  }
+
+  /* 更换背景 */
+  async onSaveBackGround(e: any) {
+    let url = e[0]?.url;
+    console.log(url);
+    if(!url){
+      const toast = await this.toastController.create({
+        message: '请上传背景图片',
+        color: 'warning',
+        duration: 1000,
+      });
+      toast.present();
+      return
+    }
+    if (!this.profile?.id) {
+      let obj = Parse.Object.extend('Profile');
+      this.profile = new obj();
+      this.profile?.set('mobile', Parse.User.current()?.get('mobile'));
+      this.profile?.set('user', Parse.User.current()?.toPointer());
+      this.profile?.set('company', {
+        __type: 'Pointer',
+        className: 'Company',
+        objectId: this.aiChatServ.company,
+      });
+    }
+    this.profile?.set('image', url);
+    await this.profile?.save();
+    const toast = await this.toastController.create({
+      message: '保存成功',
+      color: 'success',
+      duration: 1000,
+    });
+    toast.present();
+    this.isOpen = false;
+  }
+  onEdit() {
+    this.router.navigate(['/user/setting'], {
+      queryParams: {
+        id: this.uid,
+      },
+    });
   }
 }

+ 16 - 3
projects/live-app/src/moduls/user/setting/setting.component.html

@@ -25,7 +25,7 @@
           <ion-input
             placeholder="请输入昵称"
             value="{{ formData.nickname }}"
-            (ionChange)="onNickname($event)"
+            (ionChange)="onChange($event,'nickname')"
           ></ion-input>
           <ion-icon name="chevron-forward-outline"></ion-icon>
         </div>
@@ -48,7 +48,7 @@
       <ion-select
         label="性别"
         placeholder=""
-        (ionChange)="onSelect($event)"
+        (ionChange)="onChange($event,'sex')"
         interface="popover"
         placeholder="{{ formData.sex }}"
       >
@@ -63,7 +63,20 @@
           <ion-input
             placeholder="请输入年龄"
             value="{{ formData.age }}"
-            (ionChange)="onInput($event)"
+            (ionChange)="onChange($event,'age')"
+          ></ion-input>
+          <ion-icon name="chevron-forward-outline"></ion-icon>
+        </div>
+      </div>
+    </ion-item>
+    <ion-item>
+      <div class="row">
+        <div>签名</div>
+        <div class="right">
+          <ion-input
+            placeholder="请填写签名"
+            value="{{ formData.remark }}"
+            (ionChange)="onChange($event,'remark')"
           ></ion-input>
           <ion-icon name="chevron-forward-outline"></ion-icon>
         </div>

+ 6 - 12
projects/live-app/src/moduls/user/setting/setting.component.ts

@@ -27,6 +27,7 @@ export class SettingComponent implements OnInit {
     nickname: '',
     sex: '',
     age: '',
+    remark:''
   };
   mobile: string = '';
   loading: any;
@@ -61,21 +62,13 @@ export class SettingComponent implements OnInit {
     this.mobile = user?.get('mobile');
     this.formData.name = this.profile?.get('name') || '';
     this.formData.age = this.profile?.get('birthdate') || '';
+    this.formData.remark = this.profile?.get('remark') || '';
     this.loading.dismiss();
   }
-
-  //筛选
-  onSelect(e: any) {
-    this.formData.sex = e.detail.value;
-  }
-  //年龄
-  onInput(e: any) {
-    this.formData.age = e.detail.value;
-  }
-  //昵称
-  onNickname(e: any) {
-    this.formData.nickname = e.detail.value;
+  onChange(e: any,type:string){
+    this.formData[type] = e.detail.value;
   }
+
   async saveEdit(e: any) {
     this.loading = await this.loadingCtrl.create({
       message: '正在保存修改',
@@ -121,6 +114,7 @@ export class SettingComponent implements OnInit {
       className: 'Company',
       objectId: this.authServ.company,
     });
+    this.profile?.set('remark', this.formData.remark);
     await this.profile?.save();
     this.loading.dismiss();
     this.getProfile();

+ 1 - 1
projects/live-app/src/moduls/user/user.modules.routes.ts

@@ -8,7 +8,7 @@ import { SettingComponent } from './setting/setting.component';
 import { ShareComponent } from './share/share.component';
 const routes: Routes = [
   {
-    path: 'profile',//实名
+    path: 'profile/:id',//实名
     component: ProfileComponent,
   },
   {

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

@@ -1,13 +1,24 @@
 import { Injectable } from '@angular/core';
 import * as Parse from 'parse';
 import { Router } from '@angular/router';
+import { HttpService } from './http.service';
 @Injectable({
   providedIn: 'root',
 })
 export class AiChatService {
   isLoggedIn = false;
-  company:string = 'Qje9D4bqol'
-  constructor(private router: Router) {
+  company: string = 'Qje9D4bqol';
+  constructor(private router: Router, private http: HttpService) {}
+  getFansAndFollow(uid: string): Promise<any> {
+    let sql = `SELECT 
+    (SELECT COUNT(*) FROM "ProfileRadar" WHERE "fromUser" = '${uid}' AND "name" = '关注') AS follow,
+    (SELECT COUNT(*) FROM "ProfileRadar" WHERE "toUser" = '${uid}' AND "name" = '关注') AS fans;`;
+    return this.http.customSQL(sql);
   }
-
-}
+  getGift(uid: string): Promise<any> {
+    let sql = `SELECT SUM("index")
+    FROM "LoveRender"
+    WHERE "fromUser" ='${uid}'`
+    return this.http.customSQL(sql);
+  }
+}

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

@@ -1,7 +1,5 @@
 import { Injectable } from '@angular/core';
 import { HttpClient,HttpHeaders } from '@angular/common/http';
-import { Observable, throwError } from 'rxjs';
-import { catchError } from 'rxjs/operators';
 
 @Injectable({
   providedIn: 'root'