Browse Source

初始化订阅聊天消息

warrior 2 months ago
parent
commit
7952a4cdcf

+ 8 - 8
projects/live-app/src/modules/live/chat/chat.component.html

@@ -7,8 +7,8 @@
       ></ion-icon>
     </ion-buttons>
     <ion-title class="title">{{
-      uid !== "global_room"
-        ? targetUser?.get("nickname") || profile?.get("name")
+      uid
+        ? targetUser?.get("nickname") || targetUser?.get("name") || '用户' + targetUser?.id
         : "世界频道"
     }}</ion-title>
     <ion-buttons slot="end" id="option-trigger">
@@ -46,10 +46,10 @@
   </ion-popover>
 
   <div #scrollMsg id="scrollMsg" class="scroll">
-    @for (item of msgServe.messageMapList[uid]; track $index) {
+    @for (item of msgServe.messageMapList[channle]; track $index) {
     <div class="clearfix message-box">
       @if ($index == 0 || item.timestamp -
-      msgServe.messageMapList[uid][$index-1].timestamp > 600) {
+      msgServe.messageMapList[channle][$index-1].timestamp > 600) {
       <div class="time-box">
         @if (item.istoday) {
         <div class="time">{{ item.timestamp | showDate}}</div>
@@ -73,7 +73,7 @@
         <!-- 文字消息 msg_type == 1 || text -->
         @if (item.msg_type == 1 || item.msg_type == 'text') {
         <div class="msg-card">
-          @if(uid == 'global_room'){
+          @if(channle == 'global_room'){
           <span class="text-item_status">{{
             item.name || "用户" + item.publisher
           }}</span>
@@ -138,15 +138,15 @@
     <div
       [ngClass]="{
         'tools-maxwid':
-          uid !== 'global_room' && profile?.get('identyType') === 'anchor',
+          uid && profile?.get('identyType') === 'anchor',
         tools: true
       }"
       slot="end"
     >
       <ion-icon name="happy-outline" (click)="changeShowEmoji()"></ion-icon>
-      @if (uid !== 'global_room' && profile?.get("identyType") === 'anchor') {
+      @if (uid && profile?.get("identyType") === 'anchor') {
       <ion-icon name="videocam-outline"></ion-icon>
-      } @if (uid !== 'global_room' && profile?.get("identyType") === 'anchor') {
+      } @if (uid && profile?.get("identyType") === 'anchor') {
       <ion-icon name="gift-outline" (click)="gift.openModal()"></ion-icon>
       }
       <span class="splice">|</span>

+ 16 - 8
projects/live-app/src/modules/live/chat/chat.component.ts

@@ -33,6 +33,7 @@ import { MessageService } from '../../../services/message.service';
   // providers: [DatePipe],
 })
 export class ChatComponent implements OnInit {
+  channle:string = ''
   uid: string = '';
   profile?: Parse.Object; // 对方身份
   targetUser?: Parse.Object; // 对方用户
@@ -61,8 +62,13 @@ export class ChatComponent implements OnInit {
   ngOnInit() {
     this.activateRoute.paramMap.subscribe(async (params) => {
       let id: any = params.get('id');
-      this.uid = id;
-      if (!this.uid) {
+      this.channle = id
+      if(id !== 'global_room'){
+        const us = id.split('-')
+        const current = Parse.User.current()?.id!
+        this.uid = us.find((item:string)=> item !== current)
+      }
+      if (!this.channle) {
         history.back();
         return;
       }
@@ -87,17 +93,17 @@ export class ChatComponent implements OnInit {
     });
     loading.present();
     await this.getProfile();
-    await this.msgServe.initRTM(this.uid);
-    await this.msgServe.subscribeMessage(this.uid, {
+    await this.msgServe.initRTM();
+    await this.msgServe.subscribeMessage(this.channle, {
       message: true,
-      presence: true,
+      // presence: true,
     }); //订阅消息
     this.initEmoji();
     loading.dismiss();
   }
   /* 获取用户信息 */
   async getProfile() {
-    if (this.uid === 'all') {
+    if (!this.uid) {
       return;
     }
     let queryProfile = new Parse.Query('Profile');
@@ -116,7 +122,9 @@ export class ChatComponent implements OnInit {
   }
   ngOnDestroy(): void {
     this.msgServe.pageFun = () => {};
-    this.msgServe.unsubscribeMessage(this.uid);
+    if(!this.uid){
+      this.msgServe.unsubscribeMessage(this.channle);
+    }
   }
   initEmoji() {
     let emojiChar =
@@ -264,7 +272,7 @@ export class ChatComponent implements OnInit {
     });
   }
   async send(param: { msg_type: string; content: string }) {
-    await this.msgServe.publishMessage(param.content, this.uid);
+    await this.msgServe.publishMessage(param.content, this.channle);
     this.text = '';
     this.disabled = false;
   }

+ 1 - 0
projects/live-app/src/modules/live/link-page/link-page.component.scss

@@ -123,6 +123,7 @@
         color: white;
         padding: 6px;
         margin-bottom: 10px;
+        font-size: 12px;
         span {
           color: #ffc409;
         }

+ 23 - 6
projects/live-app/src/modules/tabs/notice/notice.component.html

@@ -57,10 +57,27 @@
               </div>
             </div>
           </ion-item>
-          @for (item of noticeList; track $index) {
+          <ion-item
+          class="li"
+          (click)="toUrl('/live/chat')"
+          (touchstart)="startPress()"
+          (mousemove)="stopPress()"
+        >
+          <ion-avatar slot="start">
+            <img src="img/notice.png" alt="avatar" />
+          </ion-avatar>
+          <div class="li-right">
+            <div class="name">
+              系统消息
+              <!-- <span class="time">{{ item.createdAt | showDate }}</span> -->
+            </div>
+            <div class="message-content">{{ "暂无" }}</div>
+          </div>
+        </ion-item>
+          @for (item of friends; track $index) {
           <ion-item
             class="li"
-            (click)="toUrl('/live/chat')"
+            (click)="toUrl('/live/chat/'+item.channel)"
             (touchstart)="startPress()"
             (mousemove)="stopPress()"
           >
@@ -69,10 +86,10 @@
             </ion-avatar>
             <div class="li-right">
               <div class="name">
-                系统消息
-                <span class="time">{{ item.createdAt | showDate }}</span>
+                {{item.nickname || item.name || '用户' + item.uid}}
+                <span class="time">{{ item?.createdAt | showDate }}</span>
               </div>
-              <div class="message-content">{{ item.content || "暂无" }}</div>
+              <div class="message-content">{{msgServe.messageMapList[item.channel]?.slice(-1)[0]?.content || "暂无" }}</div>
             </div>
           </ion-item>
           }
@@ -87,7 +104,7 @@
             <ion-avatar slot="start">
               <img [src]="item?.avatar" alt="avatar" />
             </ion-avatar>
-            <ion-label>{{ item?.name || item?.nickname }}</ion-label>
+            <ion-label>{{ item.nickname || item.name || '用户' + item.uid }}</ion-label>
           </ion-item>
           }
         </ion-list>

+ 5 - 12
projects/live-app/src/modules/tabs/notice/notice.component.ts

@@ -5,7 +5,7 @@ import { InfiniteScrollCustomEvent } from '@ionic/angular';
 import { Router } from '@angular/router';
 import { AiChatService } from '../../../services/aichart.service';
 import { SharedModule } from '../../shared.module';
-// import { MessageService } from '../../../services/message.service';
+import { MessageService } from '../../../services/message.service';
 @Component({
   selector: 'app-notice',
   templateUrl: './notice.component.html',
@@ -15,14 +15,7 @@ import { SharedModule } from '../../shared.module';
 })
 export class NoticeComponent implements OnInit {
   active: string = 'notice';
-  noticeList: Array<any> = [
-    {
-      avatar: '/img/notice.png',
-      name: '系统消息',
-      content: '',
-      createdAt: new Date(),
-    },
-  ];
+  noticeList: Array<any> = [];
   alertButtons = [
     {
       text: '取消',
@@ -47,7 +40,7 @@ export class NoticeComponent implements OnInit {
   constructor(
     private router: Router,
     private aiSer: AiChatService,
-    // public msgServe: MessageService
+    public msgServe: MessageService
   ) {}
 
   ngOnInit() {
@@ -58,8 +51,8 @@ export class NoticeComponent implements OnInit {
     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);
+    // let resChat = await this.aiSer.getLinkUsers(uid);
+    // resChat?.data && this.noticeList.push(...resChat.data);
   }
   segmentChanged(e: any) {
     let { value } = e.detail;

+ 2 - 2
projects/live-app/src/modules/user/profile/profile.component.ts

@@ -98,7 +98,7 @@ export class ProfileComponent implements OnInit {
       let id: any = params.get('id');
       this.uid = id;
       await this.refresh();
-      this.userStatus = await this.connectTask.getState(this.uid, this.uid);
+      // this.userStatus = await this.connectTask.getState(this.uid, this.uid);
     });
   }
   ngOnDestroy(): void {
@@ -321,7 +321,7 @@ export class ProfileComponent implements OnInit {
     toast.present();
     if (event) {
       this.isLiveing = true;
-      this.userStatus = await this.connectTask.getState(this.uid, this.uid);
+      // this.userStatus = await this.connectTask.getState(this.uid, this.uid);
       this.router.navigate(['live/link-room/' + this.room?.id]);
     }
   }

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

@@ -11,6 +11,9 @@ registerLocaleData(localeZh);
 @Injectable()
 export class ShowDatePipe implements PipeTransform {
   transform(date: Date, locale: string = 'zh-CN'): string {
+    if (!date) {
+      return '';
+    }
     const now = new Date();
     const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
     const yesterday = new Date(today);

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

@@ -59,7 +59,7 @@ export class AiChatService {
     return data.data;
   }
   getFriends(uid: string): Promise<any> {
-    let sql = `SELECT u.avatar,u.nickname,u.name,u."objectId" AS uid,f."channel"
+    let sql = `SELECT u.avatar,u.nickname,u."objectId" AS uid,f."channel"
      FROM 
       (SELECT (CASE WHEN "friend" = '${uid}' THEN "user" ELSE "friend" END) fid,"channel"
       FROM "Friends"

+ 28 - 14
projects/live-app/src/services/connectTask.service.ts

@@ -1,6 +1,7 @@
 import { Injectable } from '@angular/core';
 import { MessageService } from './message.service';
 import * as Parse from 'parse';
+import { AiChatService } from './aichart.service';
 @Injectable({
   providedIn: 'root',
 })
@@ -9,13 +10,14 @@ export class ConnectTaskService {
   msChannelName: string = 'user_connect_room'; // 主播在线上报频道
   onlineUserList = new Set(); // 在线用户列表
   isSubscribe: boolean = false;
-  constructor(private msgSer: MessageService) {}
+  constructor(private msgSer: MessageService, private aiSer: AiChatService) {}
 
   async init() {
     // 初始化消息服务,所有用户静默登录
-    await this.msgSer.initRTM(this.msChannelName);
+    await this.msgSer.initRTM();
     await this.anchorOnline();
     this.getOnlieUserList(this.msChannelName, 'MESSAGE');
+    this.conncetChannels()
   }
   reset() {
     this.onlineUserList = new Set();
@@ -23,11 +25,11 @@ export class ConnectTaskService {
   }
   /* 主播上线 */
   async anchorOnline() {
-    let profile
-    try{
+    let profile;
+    try {
       profile = JSON.parse(localStorage.getItem('profile') || '');
-    }catch(err){
-      console.log("profile err",err)
+    } catch (err) {
+      console.log('profile err', err);
     }
     const uid = Parse.User.current()?.id!;
     if (profile?.identyType == 'anchor' && !this.isSubscribe) {
@@ -40,15 +42,27 @@ export class ConnectTaskService {
       // }
       // if (!nowChannes.includes(uid)) {
       await this.msgSer.setConnectState(uid, 'ONLINE'); //默认在线状态
-      await this.msgSer.subscribeMessage(uid, {//开启并订阅自己的聊天频道
+      await this.msgSer.subscribeMessage(uid, {
+        //开启并订阅自己的聊天频道
         message: true,
         presence: true,
-      }); 
+      });
       // }
       this.isSubscribe = true;
     }
   }
 
+  /* 订阅好友频道 */
+  async conncetChannels() {
+    let uid: any = Parse.User.current()?.id;
+    let resultFriends = await this.aiSer.getFriends(uid);
+    resultFriends?.data?.forEach(async (item: any) => {
+      let channelName = item.channel;
+      await this.msgSer.subscribeMessage(channelName, {
+        message: true,
+      });
+    });
+  }
   /* 获取用户当前所在频道 */
   async getWhereNow(userId: string): Promise<Array<string>> {
     let channes: Array<string> = [];
@@ -112,19 +126,19 @@ export class ConnectTaskService {
       );
       // console.log(result);
       // 如果 nextPage 存在,下一次调用 whoNow 时,需将 nextPage 的值填入 whoNowOptions 的 page 字段
-      
-      let totalOccupancy = result?.totalOccupancy
-      let occupants = result?.occupants
-      let nextPage = result?.nextPage
+
+      let totalOccupancy = result?.totalOccupancy;
+      let occupants = result?.occupants;
+      let nextPage = result?.nextPage;
       occupants?.forEach((userInfo: any) => {
         const { states, userId, statesCount } = userInfo;
         this.onlineUserList.add(userId);
       });
-      console.log('获取在线用户列表:',this.onlineUserList);
+      console.log('获取在线用户列表:', this.onlineUserList);
       if (nextPage) this.getOnlieUserList(channelName, nextPage, channelType);
     } catch (status: any) {
       // const { operation, reason, errorCode } = status;
-      console.error("getOnlieUserList err",status)
+      console.error('getOnlieUserList err', status);
       // console.error(
       //   `${operation} failed, ErrorCode: ${errorCode}, due to: ${reason}.`
       // );

+ 21 - 66
projects/live-app/src/services/message.service.ts

@@ -32,59 +32,10 @@ export class MessageService {
     public toastController: ToastController,
     private http: HttpService
   ) {}
-  messageMapList: any = {
-    global_room: [
-      // 世界频道消息列表
-      // {
-      //   is_self: true,
-      //   avatar:
-      //     'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
-      //   msg_type: 1,
-      //   content: 'nihao',
-      //   istoday: true,
-      //   timestamp: new Date(),
-      // },
-      // {
-      //   is_self: true,
-      //   avatar:
-      //     'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
-      //   msg_type: 1,
-      //   content: `Use the pipe name to trace where the pipe is declared and used. To resolve this error: If the pipe is local to the NgModule, give it a unique name in the pipe's decorator and declared it in the NgModule. If the pipe is standalone or is declared in another NgModule, add it to the imports field of the standalone component or the current NgModule.`,
-      //   istoday: true,
-      //   timestamp: new Date(),
-      // },
-      // {
-      //   is_self: true,
-      //   avatar:
-      //     'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
-      //   msg_type: 1,
-      //   content: `Use the pipe name to trace where the pipe is declared and used. To resolve this error: If the pipe is local to the NgModule, give it a unique name in the pipe's decorator and declared it in the NgModule. If the pipe is standalone or is declared in another NgModule, add it to the imports field of the standalone component or the current NgModule.`,
-      //   istoday: true,
-      //   timestamp: new Date(),
-      // },
-      // {
-      //   is_self: true,
-      //   avatar:
-      //     'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
-      //   msg_type: 1,
-      //   content: `Use the pipe name to trace where the pipe is declared and used. To resolve this error: If the pipe is local to the NgModule, give it a unique name in the pipe's decorator and declared it in the NgModule. If the pipe is standalone or is declared in another NgModule, add it to the imports field of the standalone component or the current NgModule.`,
-      //   istoday: true,
-      //   timestamp: new Date(),
-      // },
-      // {
-      //   is_self: false,
-      //   avatar:
-      //     'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
-      //   msg_type: 1,
-      //   content: 'nihao',
-      //   istoday: true,
-      //   timestamp: new Date(),
-      // },
-    ],
-  };
+  messageMapList: any = {};
 
   /* 获取token */
-  async getToken(channel?: string) {
+  async getToken() {
     this.userId = Parse.User.current()?.id!;
     //获取频道token记录
     let uid = Parse.User.current()?.id;
@@ -106,12 +57,12 @@ export class MessageService {
     }
   }
 
-  async initRTM(channelName: string) {
+  async initRTM() {
     // let states = ['CONNECTED', 'CONNECTING'];
     if (this.options.connectState) return;
-    await this.getToken(channelName);
-    // const rtmConfig = { logLevel: 'debug' };
-    this.rtmClient = new AgoraRTM.RTM(this.appid, this.userId);
+    await this.getToken();
+    const rtmConfig = { logLevel: 'debug' };
+    this.rtmClient = new AgoraRTM.RTM(this.appid, this.userId,rtmConfig);
     this.joinReady();
     await this.loginRTM();
     // this.subscribeMessage(channelName);
@@ -123,7 +74,7 @@ export class MessageService {
    *@'REFUSEINVITATION_' + uid: 拒绝通话邀请
    *@'RESPONSEINVITOIN_' + uid: 接受邀请
    */
-  joinReady(channelName?: string) {
+  joinReady() {
     this.rtmClient?.addEventListener('message', async (event: any) => {
       console.log('接收到一条消息:', event);
       let states = [
@@ -135,8 +86,10 @@ export class MessageService {
       const message = JSON.parse(event.message);
       let is_self = event.publisher == this.userId;
       console.log('自己发出的消息:', is_self, message.text);
-      if (!is_self && states.includes(message.text)) {
-        this.callPresence(message.text, event.publisher, event.channelName);
+      if (states.includes(message.text)) {
+        if (!is_self) {
+          this.callPresence(message.text, event.publisher, event.channelName);
+        }
         return;
       }
       this.showMessage(event);
@@ -165,7 +118,8 @@ export class MessageService {
       Mode: mode,
     };
     try {
-      await this.rtmClient?.presence.setState(channelName, channelType, states);
+      let res = await this.rtmClient?.presence.setState(channelName, channelType, states);
+      console.log('频道状态发生更改:',res);
     } catch (err: any) {
       console.log(err);
     }
@@ -265,7 +219,7 @@ export class MessageService {
   //     console.error('join channel failed: ', status);
   //   }
   // }
-  async loginRTM(channelName?: string) {
+  async loginRTM() {
     try {
       await this.rtmClient?.login({
         token: this.options.token,
@@ -277,7 +231,7 @@ export class MessageService {
         const metadata = [
           {
             key: 'nickname',
-            value: user?.get('nickname'),
+            value: user?.get('nickname') || user?.get('name') || user?.id,
           },
           {
             key: 'avatar',
@@ -324,9 +278,9 @@ export class MessageService {
           console.log('subscribeMessage', res);
           //订阅成功
           this.channelNameList[channelName] = true;
-          if (this.messageMapList[channelName]?.length === 0) {
+          if (!this.messageMapList[channelName]) {
             this.messageMapList[channelName] = [];
-            this.getHistoryMessage(channelName)
+            this.getHistoryMessage(channelName);
           }
           this.pageFun?.();
           resolve(true);
@@ -344,15 +298,16 @@ export class MessageService {
     query.descending('createdAt');
     query.skip(this.messageMapList[channelName].length);
     query.limit(50);
-    query.select('content','from_id');
+    query.select('content', 'from_id');
     let msgList = await query.find();
+    console.log('历史消息:', msgList);
     msgList.forEach((item: any) => {
       let is_self = item?.get('from_id') == this.userId;
       let data: any = item?.get('content');
       data['is_self'] = is_self;
       data['istoday'] = true;
-      data['timestamp'] = new Date(data.timestamp)
-      this.messageMapList[channelName].unshift(data)
+      data['timestamp'] = new Date(data.timestamp);
+      this.messageMapList[channelName].unshift(data);
     });
     // this.messageMapList[channelName].unshift(...msgList);
   }