Browse Source

对接数据

warrior 1 day ago
parent
commit
d4ece49da6

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


+ 4 - 3
projects/live-app/src/moduls/live/chat/chat.component.html

@@ -6,7 +6,7 @@
         style="width: 6.4vw; height: 6.4vw; color: #000000"
       ></ion-icon>
     </ion-buttons>
-    <ion-title class="title">{{ targetUser.name }}</ion-title>
+    <ion-title class="title">{{ targetUser?.get('nickname') }}</ion-title>
     <ion-buttons slot="end" id="click-trigger">
       <ion-icon name="ellipsis-horizontal-outline"></ion-icon>
     </ion-buttons>
@@ -19,6 +19,7 @@
   (ionScroll)="handleScroll($any($event))"
   (ionScrollEnd)="handleScrollEnd()"
   class="ion-padding"
+  (click)="changeShowEmoji(true)"
 >
   <ion-popover
     trigger="click-trigger"
@@ -136,7 +137,7 @@
     </div>
   </ion-toolbar>
   <div [style.height]="height + 'px'"></div>
-  @if (showEmoji ||showMore) {
+  @if (showEmoji) {
   <div class="b-1px-b"></div>
   } @if (showEmoji) {
   <div class="emoji-content">
@@ -166,6 +167,6 @@
   [breakpoints]="[0, 0.5, 1]"
 >
   <ng-template>
-    <div class="block">Block of Content</div>
+    <div class="block">敬请期待</div>
   </ng-template>
 </ion-modal>

+ 42 - 9
projects/live-app/src/moduls/live/chat/chat.component.ts

@@ -2,6 +2,7 @@ import { DatePipe } from '@angular/common';
 import { HttpClient } from '@angular/common/http';
 import { Component, OnInit } from '@angular/core';
 import { FormsModule } from '@angular/forms';
+import { ActivatedRoute } from '@angular/router';
 import {
   IonicModule,
   LoadingController,
@@ -23,10 +24,10 @@ import * as Parse from 'parse';
   providers: [DatePipe],
 })
 export class ChatComponent implements OnInit {
-  targetUser: any = {
-    name: '紫霞仙子',
-    avatar: '',
-  };
+  uid: string = '';
+  profile?: Parse.Object; // 对方身份
+  targetUser?: Parse.Object;// 对方用户
+ 
   text: string = '';
   list: any = {
     data: [
@@ -82,7 +83,6 @@ export class ChatComponent implements OnInit {
   viewImg: string = '';
   height: number = 0;
   showEmoji: boolean = false;
-  showMore: boolean = false;
   emojis: Array<any> = [];
   isOpen: boolean = false;
   currentScroll: number = 0; //滚动条位置
@@ -91,11 +91,45 @@ export class ChatComponent implements OnInit {
     public datePipe: DatePipe,
     private modalController: ModalController,
     public toastController: ToastController,
-    private loadingCtrl: LoadingController
+    private loadingCtrl: LoadingController,
+    private activateRoute: ActivatedRoute,
   ) {}
 
   ngOnInit() {
+    this.activateRoute.paramMap.subscribe(async (params) => {
+      let id: any = params.get('id');
+      this.uid = id;
+      if(!this.uid){
+        history.back();
+        return
+      }
+      this.refresh();
+    });
+  }
+  async refresh() {
+    const loading = await this.loadingCtrl.create({
+      message: '加载中',
+    });
+    loading.present();
+    await this.getProfile()
     this.initEmoji();
+    loading.dismiss();
+  }
+  /* 获取用户信息 */
+  async getProfile(){
+    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.targetUser = this.profile?.get('user');
+    } else {
+      let queryUser = new Parse.Query('_User');
+      queryUser.equalTo('objectId', this.uid);
+      this.targetUser = await queryUser.first();
+    }
   }
   initEmoji() {
     let emojiChar =
@@ -212,10 +246,9 @@ export class ChatComponent implements OnInit {
     }
   }
   //调起表情
-  changeShowEmoji() {
-    this.showEmoji = !this.showEmoji;
+  changeShowEmoji(isClose?:boolean) {
+    this.showEmoji = isClose ? false : !this.showEmoji;
     this.height = 0;
-    this.showMore = false;
   }
   //添加表情
   emojiChoose(value: any) {

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

@@ -4,7 +4,7 @@ import { ChatComponent } from './chat/chat.component';
 import { SearchComponent } from './search/search.component';
 const routes: Routes = [
   {
-    path: 'chat',//聊天
+    path: 'chat/:id',//聊天
     component: ChatComponent,
   },
   {

+ 11 - 0
projects/live-app/src/moduls/shared.module.ts

@@ -0,0 +1,11 @@
+// shared.module.ts
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { ShowDatePipe } from '../pipes/show-date'
+
+@NgModule({
+  imports: [CommonModule],
+  declarations: [ShowDatePipe],
+  exports: [ShowDatePipe],
+})
+export class SharedModule { }

+ 13 - 9
projects/live-app/src/moduls/tabs/notice/notice.component.html

@@ -55,9 +55,9 @@
             <div class="li-right">
               <div class="name">
                 系统消息
-                <span class="time">20:20:18</span>
+                <span class="time">{{ item.createdAt | showDate }}</span>
               </div>
-              <div class="message-content">12554444444</div>
+              <div class="message-content">{{ item.content || "暂无" }}</div>
             </div>
             <!-- </div> -->
           </ion-item>
@@ -69,15 +69,12 @@
     <ion-segment-content id="friends">
       <div class="notice-list" (touchmove)="onMousemove($event)">
         <ion-list>
-          @for (item of noticeList; track $index) {
-          <ion-item>
+          @for (item of friends; track $index) {
+          <ion-item (click)="toUrl('/live/chat/' + item?.uid)">
             <ion-avatar slot="start">
-              <img
-                [src]="'https://picsum.photos/80/80?random=' + $index"
-                alt="avatar"
-              />
+              <img [src]="item?.avatar" alt="avatar" />
             </ion-avatar>
-            <ion-label>{{ item.name }}</ion-label>
+            <ion-label>{{ item?.name || item?.nickname }}</ion-label>
           </ion-item>
           }
         </ion-list>
@@ -85,3 +82,10 @@
     </ion-segment-content>
   </ion-segment-view>
 </ion-content>
+<ion-alert
+  [backdropDismiss]="false"
+  [isOpen]="showModal"
+  trigger="present-alert"
+  header="删除与ta的聊天记录"
+  [buttons]="alertButtons"
+></ion-alert>

+ 34 - 15
projects/live-app/src/moduls/tabs/notice/notice.component.ts

@@ -3,48 +3,64 @@ import { IonicModule } from '@ionic/angular';
 import * as Parse from 'parse';
 import { InfiniteScrollCustomEvent } from '@ionic/angular';
 import { Router } from '@angular/router';
+import { AiChatService } from '../../../services/aichart.service';
+import { SharedModule } from '../../shared.module';
 @Component({
   selector: 'app-notice',
   templateUrl: './notice.component.html',
   styleUrls: ['./notice.component.scss'],
   standalone: true,
-  imports: [IonicModule],
+  imports: [IonicModule,SharedModule],
 })
 export class NoticeComponent implements OnInit {
   active: string = 'notice';
   noticeList: Array<any> = [
     {
-      avatar: Parse.User.current()?.get('avatar'),
+      avatar: '/img/notice.png',
       name: '系统消息',
       content: '',
       createdAt: new Date(),
     },
+  ];
+  alertButtons = [
     {
-      avatar: Parse.User.current()?.get('avatar'),
-      name: '系统消息',
-      content: '',
-      createdAt: new Date(),
+      text: '取消',
+      role: 'cancel',
+      handler: () => {
+        console.log('Alert canceled');
+      },
     },
     {
-      avatar: Parse.User.current()?.get('avatar'),
-      name: '系统消息',
-      content: '',
-      createdAt: new Date(),
+      text: '确认',
+      role: 'confirm',
+      handler: () => {
+        console.log('Alert confirmed');
+      },
     },
   ];
-  friends: Array<Object> = [];
+  friends: Array<any> = [];
   times: number = 0;
   timer: any;
   showModal: boolean = false; //是否长按弹窗
   currentObject: any; //当前选择对象
-  constructor(private router: Router) {}
+  constructor(private router: Router, private aiSer:AiChatService) {}
 
-  ngOnInit() {}
+  ngOnInit() {
+    this.refresh()
+  }
+  async refresh(){
+    let uid:any = Parse.User.current()?.id
+    let resultFriends = await this.aiSer.getFriends(uid)
+    this.friends = resultFriends['data']
+    console.log(this.friends);
+    let resChat = await this.aiSer.getLinkUsers(uid)
+    resChat?.data && this.noticeList.push(...resChat.data)
+  }
   segmentChanged(e: any) {
     let { value } = e.detail;
     this.active = value;
   }
-
+  /* 手指按下 */
   startPress() {
     this.showModal = false;
     if (this.times >= 500) {
@@ -58,11 +74,13 @@ export class NoticeComponent implements OnInit {
       this.startPress();
     }, 500);
   }
+  /* 触摸屏幕并移动,取消长按事件 */
   onMousemove(e: any) {
     clearTimeout(this.timer);
-    this.showModal = false;
+    // this.showModal = false;
     this.times = 0;
   }
+  /* 手指抬起 */
   stopPress() {
     clearTimeout(this.timer);
     this.times = 0;
@@ -73,6 +91,7 @@ export class NoticeComponent implements OnInit {
       (ev as InfiniteScrollCustomEvent).target.complete();
     }, 500);
   }
+
   toUrl(url: string) {
     if (this.showModal) return;
     this.router.navigate([url]);

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

@@ -177,6 +177,7 @@
       #upload
       [maxlenght]="1"
       [files]="[{url:profile?.get('image')}]"
+      [boxWidth]="320"
       [fileWidth]="300"
       [fileHeight]="180"
     ></app-upload>

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

@@ -236,6 +236,7 @@
 }
 ion-modal {
   --height: 50%;
+  --width: 350px;
   --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);
 }
@@ -243,4 +244,5 @@ ion-modal {
   height: 100%;
   display: flex;
   align-items: center;
+  justify-content: center;
 }

+ 33 - 0
projects/live-app/src/pipes/show-date.ts

@@ -0,0 +1,33 @@
+import { Injectable, Pipe, PipeTransform } from '@angular/core';
+import { formatDate } from '@angular/common';
+import { registerLocaleData } from '@angular/common';
+import localeZh from '@angular/common/locales/zh';
+
+registerLocaleData(localeZh);
+
+@Pipe({
+  name: 'showDate'
+})
+@Injectable()
+export class ShowDatePipe implements PipeTransform {
+  transform(date: Date, locale: string = 'zh-CN'): string {
+    const now = new Date();
+    const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
+    const yesterday = new Date(today);
+    yesterday.setDate(yesterday.getDate() - 1);
+    const beforeYesterday = new Date(yesterday);
+    beforeYesterday.setDate(beforeYesterday.getDate() - 1);
+
+    const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());
+
+    if (dateOnly.toISOString() === today.toISOString()) {
+      return formatDate(date, 'HH:mm', locale);
+    } else if (dateOnly.toISOString() === yesterday.toISOString()) {
+      return `昨天 ${formatDate(date, 'HH:mm', locale)}`;
+    } else if (dateOnly.toISOString() === beforeYesterday.toISOString()) {
+      return `前天 ${formatDate(date, 'HH:mm', locale)}`;
+    } else {
+      return formatDate(date, 'yyyy-MM-dd HH:mm', locale);
+    }
+  }
+}

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

@@ -8,7 +8,10 @@ import { HttpService } from './http.service';
 export class AiChatService {
   isLoggedIn = false;
   company: string = 'Qje9D4bqol';
-  constructor(private router: Router, private http: HttpService) {}
+  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,
@@ -18,7 +21,41 @@ export class AiChatService {
   getGift(uid: string): Promise<any> {
     let sql = `SELECT SUM("index")
     FROM "LoveRender"
-    WHERE "fromUser" ='${uid}'`
+    WHERE "fromUser" ='${uid}'`;
     return this.http.customSQL(sql);
   }
+  getFriends(uid: string): Promise<any> {
+    let sql = `SELECT u.avatar,u.nickname,u.name,u."objectId" AS uid FROM 
+    (SELECT (CASE WHEN "friend" = '${uid}' THEN "user" ELSE "friend" END) fid
+    FROM "Friends"
+    WHERE "friend" = '${uid}'
+    OR "user" = '${uid}'
+    GROUP BY fid) AS f
+    LEFT JOIN "_User" AS u
+    ON u."objectId" = f.fid
+    `;
+    return this.http.customSQL(sql);
+  }
+  async getLinkUsers(uid: string): Promise<any> {
+    // let date = this.datePipe.transform(new Date(), 'yyyy-MM-dd');
+    let sql = `SELECT * FROM (
+          SELECT row_number() over(partition by tbl."user" order by tbl."createdAt" desc) as "idx",tbl.user, tbl."createdAt", --tbl.content, tbl.appkey,
+          us.avatar,us.nickname,us.mobile,
+          (CASE WHEN DATE(tbl."createdAt") >= now() THEN true ELSE false END) as istoday
+          FROM ( (SELECT * , content:: json ->> 'target_id' AS user 
+            FROM "MessageLog" AS msglog
+            WHERE jsonb_contains(content, '{"from_id": "${uid}"}')
+            ORDER BY msglog."createdAt" DESC)
+            UNION 
+            (SELECT * ,content:: json ->> 'from_id' AS user 
+            FROM "MessageLog" AS msglog 
+            WHERE jsonb_contains(content, '{"target_id": "${uid}"}')
+            )) AS tbl
+            LEFT JOIN "_User" as us
+            ON us."objectId" = tbl.user
+          )as ntbl
+          WHERE ntbl."idx"=1
+        ORDER BY ntbl."createdAt" DESC`;
+    let res = await this.http.customSQL(sql);
+  }
 }