Browse Source

存储聊天消息

warrior 4 months ago
parent
commit
53a11bd6e9

+ 1 - 1
projects/live-app/src/app/components/pay-comp/pay-comp.component.html

@@ -42,7 +42,7 @@
         </div>
         </div>
       </div>
       </div>
       <div class="pay-footer">
       <div class="pay-footer">
-        <div class="order-num">订单编号{{orderNum}}</div>
+        <div class="order-num">订单编号{{tradeNo}}</div>
         <div class="pay-btn">去付款</div>
         <div class="pay-btn">去付款</div>
       </div>
       </div>
     </div>
     </div>

+ 2 - 3
projects/live-app/src/app/components/pay-comp/pay-comp.component.ts

@@ -15,10 +15,9 @@ declare var wx: any;
 })
 })
 export class PayCompComponent implements OnInit {
 export class PayCompComponent implements OnInit {
   @Input('price') price!: number;
   @Input('price') price!: number;
-  @Input('orderNum') orderNum: string = 'C20241215050401';
+  @Input('tradeNo') tradeNo: string = 'C20241215050401'; //支付单号
   @Output() onChange: EventEmitter<any> = new EventEmitter<any>();
   @Output() onChange: EventEmitter<any> = new EventEmitter<any>();
-  tradeNo?: string; //支付单号
-  isOpen: boolean = false; //打开弹窗
+  isOpen: boolean = true; //打开弹窗
   checkpay: string = 'wxpay';
   checkpay: string = 'wxpay';
   userAgent?: string; //获取当前浏览器环境
   userAgent?: string; //获取当前浏览器环境
 
 

+ 3 - 1
projects/live-app/src/modules/goods/vip/vip.component.html

@@ -112,4 +112,6 @@
   </div>
   </div>
   }
   }
 </ion-content>
 </ion-content>
-<app-pay-comp #paycomp></app-pay-comp>
+@if (showPay) {
+  <app-pay-comp [tradeNo]="tradeNo" #paycomp [price]="price"></app-pay-comp>
+}

+ 1 - 1
projects/live-app/src/modules/goods/vip/vip.component.scss

@@ -222,7 +222,7 @@
       justify-content: center;
       justify-content: center;
       align-items: center;
       align-items: center;
       .open-pay{
       .open-pay{
-        background-color: #0054e9;
+        background-color: #ff5c64;
         color: #ffffff;
         color: #ffffff;
         padding: 8px 16px;
         padding: 8px 16px;
         border-radius: 4px;
         border-radius: 4px;

+ 12 - 1
projects/live-app/src/modules/goods/vip/vip.component.ts

@@ -7,6 +7,7 @@ import { AuthService } from '../../../services/auth.service';
 import { DatePipe, CommonModule } from '@angular/common';
 import { DatePipe, CommonModule } from '@angular/common';
 import { AgreementComponent } from '../../login/agreement/agreement.component';
 import { AgreementComponent } from '../../login/agreement/agreement.component';
 import { PayCompComponent } from '../../../app/components/pay-comp/pay-comp.component';
 import { PayCompComponent } from '../../../app/components/pay-comp/pay-comp.component';
+import { AccountService } from '../../../services/account.service';
 
 
 @Component({
 @Component({
   selector: 'app-vip',
   selector: 'app-vip',
@@ -32,10 +33,15 @@ export class VipComponent implements OnInit {
   registerAgreement: any;
   registerAgreement: any;
   isCheck: boolean = false;
   isCheck: boolean = false;
   currentGoods?: Parse.Object; //当前选择的会员
   currentGoods?: Parse.Object; //当前选择的会员
+  showPay: boolean = false;
+  price:number = 0;
+  tradeNo: string = ''; //支付单号
+
   constructor(
   constructor(
     private modalController: ModalController,
     private modalController: ModalController,
     private authSer: AuthService,
     private authSer: AuthService,
-    private datePipe: DatePipe
+    private datePipe: DatePipe,
+    private accServ: AccountService,
   ) {}
   ) {}
 
 
   ngOnInit() {
   ngOnInit() {
@@ -76,6 +82,7 @@ export class VipComponent implements OnInit {
     goods.include('services');
     goods.include('services');
     this.goodsList = await goods.find();
     this.goodsList = await goods.find();
     this.currentGoods = this.goodsList[0];
     this.currentGoods = this.goodsList[0];
+    this.price = this.currentGoods?.get('price')
   }
   }
   getAgreement() {
   getAgreement() {
     let Agreement = new Parse.Query('ContractAgreement');
     let Agreement = new Parse.Query('ContractAgreement');
@@ -98,8 +105,12 @@ export class VipComponent implements OnInit {
   }
   }
   onchang(data: Parse.Object) {
   onchang(data: Parse.Object) {
     this.currentGoods = data;
     this.currentGoods = data;
+    this.price = this.currentGoods?.get('price')
   }
   }
   openpay() {
   openpay() {
+    this.showPay = true
+    this.tradeNo = this.accServ.setTradeNo();
+    
     this.paycomp.isOpen = true;
     this.paycomp.isOpen = true;
   }
   }
 }
 }

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

@@ -7,7 +7,9 @@
       ></ion-icon>
       ></ion-icon>
     </ion-buttons>
     </ion-buttons>
     <ion-title class="title">{{
     <ion-title class="title">{{
-      uid !== "global_room" ? targetUser?.get("nickname") || profile?.get("name") : "世界频道"
+      uid !== "global_room"
+        ? targetUser?.get("nickname") || profile?.get("name")
+        : "世界频道"
     }}</ion-title>
     }}</ion-title>
     <ion-buttons slot="end" id="option-trigger">
     <ion-buttons slot="end" id="option-trigger">
       <ion-icon name="ellipsis-horizontal-outline"></ion-icon>
       <ion-icon name="ellipsis-horizontal-outline"></ion-icon>
@@ -46,14 +48,14 @@
   <div #scrollMsg id="scrollMsg" class="scroll">
   <div #scrollMsg id="scrollMsg" class="scroll">
     @for (item of msgServe.messageMapList[uid]; track $index) {
     @for (item of msgServe.messageMapList[uid]; track $index) {
     <div class="clearfix message-box">
     <div class="clearfix message-box">
-      @if ($index == 0 || item.create_time -
-      msgServe.messageMapList[uid][$index-1].create_time > 600) {
+      @if ($index == 0 || item.timestamp -
+      msgServe.messageMapList[uid][$index-1].timestamp > 600) {
       <div class="time-box">
       <div class="time-box">
         @if (item.istoday) {
         @if (item.istoday) {
-        <div class="time">{{ item.timeStamp | date : "HH:mm" }}</div>
+        <div class="time">{{ item.timestamp | date : "HH:mm" }}</div>
         }@else {
         }@else {
         <div class="time">
         <div class="time">
-          {{ item.timeStamp | date : "yyyy年MM月dd日 HH:mm" }}
+          {{ item.timestamp | date : "yyyy年MM月dd日 HH:mm" }}
         </div>
         </div>
         }
         }
       </div>
       </div>
@@ -62,17 +64,24 @@
       <!-- 他人信息 -->
       <!-- 他人信息 -->
       @if (!item.is_self) {
       @if (!item.is_self) {
       <div class="msg-bloak no_self">
       <div class="msg-bloak no_self">
-        <img class="avatar fl" mode="widthFix" src="{{ item.avatar }}" />
+        <img
+          class="avatar fl"
+          (click)="toUrl('user/profile/' + item.publisher)"
+          mode="widthFix"
+          src="{{ item.avatar }}"
+        />
         <!-- 文字消息 msg_type == 1 || text -->
         <!-- 文字消息 msg_type == 1 || text -->
         @if (item.msg_type == 1 || item.msg_type == 'text') {
         @if (item.msg_type == 1 || item.msg_type == 'text') {
-          <div class="msg-card">
-            @if(uid == 'global_room'){
-              <span class="text-item_status">{{ item.name || '新人' }}</span>
-            }
-            <div class="text-item fl text-item_left">
-              <p>{{ item.content }}</p>
-            </div>
+        <div class="msg-card">
+          @if(uid == 'global_room'){
+          <span class="text-item_status">{{
+            item.name || "用户" + item.publisher
+          }}</span>
+          }
+          <div class="text-item fl text-item_left">
+            <p>{{ item.content }}</p>
           </div>
           </div>
+        </div>
         }
         }
         <!-- 图片消息 msg_type == 2 || img -->
         <!-- 图片消息 msg_type == 2 || img -->
         @else if(item.msg_type == 2 || item.msg_type == 'img' || item.msg_type
         @else if(item.msg_type == 2 || item.msg_type == 'img' || item.msg_type
@@ -82,7 +91,6 @@
           [src]="item.content"
           [src]="item.content"
           (click)="predivimg(item.content)"
           (click)="predivimg(item.content)"
         />
         />
-        } @else if (item.msg_type == 3) {
         <div class="text-item fl text-item_left">
         <div class="text-item fl text-item_left">
           <p>{{ item.content }}</p>
           <p>{{ item.content }}</p>
         </div>
         </div>
@@ -127,17 +135,27 @@
       (keydown)="comfirmText($event)"
       (keydown)="comfirmText($event)"
     >
     >
     </ion-input>
     </ion-input>
-    <div class="tools" slot="end">
+    <div
+      [ngClass]="{
+        'tools-maxwid':
+          uid !== 'global_room' && profile?.get('identyType') === 'anchor',
+        tools: true
+      }"
+      slot="end"
+    >
       <ion-icon name="happy-outline" (click)="changeShowEmoji()"></ion-icon>
       <ion-icon name="happy-outline" (click)="changeShowEmoji()"></ion-icon>
+      @if (uid !== 'global_room' && profile?.get("identyType") === 'anchor') {
       <ion-icon name="videocam-outline"></ion-icon>
       <ion-icon name="videocam-outline"></ion-icon>
-      <ion-icon name="gift-outline" (click)="isOpen = true"></ion-icon>
+      } @if (uid !== 'global_room' && profile?.get("identyType") === 'anchor') {
+      <ion-icon name="gift-outline" (click)="gift.openModal()"></ion-icon>
+      }
       <span class="splice">|</span>
       <span class="splice">|</span>
       <!-- <div class="send">发送</div> -->
       <!-- <div class="send">发送</div> -->
       <ion-button
       <ion-button
         class="send"
         class="send"
         fill="outline"
         fill="outline"
         size="small"
         size="small"
-        [disabled]="text.length == 0"
+        [disabled]="text.length == 0 || disabled"
         (click)="comfirmText()"
         (click)="comfirmText()"
         >发送</ion-button
         >发送</ion-button
       >
       >
@@ -166,14 +184,8 @@
   </div>
   </div>
   }
   }
 </ion-footer>
 </ion-footer>
-<ion-modal
-  (click)="isOpen = false"
-  (didDismiss)="dismiss($event)"
-  [isOpen]="isOpen"
-  [initialBreakpoint]="0.5"
-  [breakpoints]="[0, 0.5, 1]"
->
-  <ng-template>
-    <div class="block">敬请期待</div>
-  </ng-template>
-</ion-modal>
+<app-gift-modal
+  #gift
+  (sendEmit)="onSendGift()"
+  [toUid]="this.uid"
+></app-gift-modal>

+ 7 - 1
projects/live-app/src/modules/live/chat/chat.component.scss

@@ -91,7 +91,7 @@
 }
 }
 .footer-tool {
 .footer-tool {
   .tools {
   .tools {
-    width: 160px;
+    // width: 160px;
     display: flex;
     display: flex;
     align-items: center;
     align-items: center;
     justify-content: space-between;
     justify-content: space-between;
@@ -99,6 +99,12 @@
     ion-icon {
     ion-icon {
       font-size: 30px;
       font-size: 30px;
     }
     }
+    .splice {
+      margin: 0 2px;
+    }
+  }
+  .tools-maxwid {
+    width: 160px;
   }
   }
 }
 }
 .emoji-content {
 .emoji-content {

+ 31 - 17
projects/live-app/src/modules/live/chat/chat.component.ts

@@ -1,12 +1,11 @@
-import { DatePipe } from '@angular/common';
+import { DatePipe, CommonModule } from '@angular/common';
 import { HttpClient } from '@angular/common/http';
 import { HttpClient } from '@angular/common/http';
 import { Component, OnInit } from '@angular/core';
 import { Component, OnInit } from '@angular/core';
 import { FormsModule } from '@angular/forms';
 import { FormsModule } from '@angular/forms';
-import { ActivatedRoute } from '@angular/router';
+import { ActivatedRoute, Router } from '@angular/router';
 import {
 import {
   IonicModule,
   IonicModule,
   LoadingController,
   LoadingController,
-  ModalController,
   ScrollDetail,
   ScrollDetail,
   ToastController,
   ToastController,
 } from '@ionic/angular';
 } from '@ionic/angular';
@@ -14,14 +13,20 @@ import {
 // var JIM = JIMServ.JIM;
 // var JIM = JIMServ.JIM;
 // var Events = JIMServ.Events;
 // var Events = JIMServ.Events;
 import * as Parse from 'parse';
 import * as Parse from 'parse';
+import { GiftModalComponent } from '../../../app/components/gift-modal/gift-modal.component';
 import { MessageService } from '../../../services/message.service';
 import { MessageService } from '../../../services/message.service';
-
 @Component({
 @Component({
   selector: 'app-chat',
   selector: 'app-chat',
   templateUrl: './chat.component.html',
   templateUrl: './chat.component.html',
   styleUrls: ['./chat.component.scss'],
   styleUrls: ['./chat.component.scss'],
   standalone: true,
   standalone: true,
-  imports: [IonicModule, FormsModule, DatePipe],
+  imports: [
+    IonicModule,
+    FormsModule,
+    DatePipe,
+    GiftModalComponent,
+    CommonModule,
+  ],
   providers: [DatePipe],
   providers: [DatePipe],
 })
 })
 export class ChatComponent implements OnInit {
 export class ChatComponent implements OnInit {
@@ -34,10 +39,11 @@ export class ChatComponent implements OnInit {
   height: number = 0;
   height: number = 0;
   showEmoji: boolean = false;
   showEmoji: boolean = false;
   emojis: Array<any> = [];
   emojis: Array<any> = [];
-  isOpen: boolean = false;
   timer: any;
   timer: any;
   currentScroll: number = 0; //滚动条位置
   currentScroll: number = 0; //滚动条位置
+  disabled: boolean = false;
   constructor(
   constructor(
+    private router: Router,
     private http: HttpClient,
     private http: HttpClient,
     public datePipe: DatePipe,
     public datePipe: DatePipe,
     public toastController: ToastController,
     public toastController: ToastController,
@@ -78,8 +84,11 @@ export class ChatComponent implements OnInit {
     });
     });
     loading.present();
     loading.present();
     await this.getProfile();
     await this.getProfile();
-    await this.msgServe.initRTM(this.uid)
-    await this.msgServe.subscribeMessage(this.uid,{message:true,presence:true}) //订阅消息
+    await this.msgServe.initRTM(this.uid);
+    await this.msgServe.subscribeMessage(this.uid, {
+      message: true,
+      presence: true,
+    }); //订阅消息
     this.initEmoji();
     this.initEmoji();
     loading.dismiss();
     loading.dismiss();
   }
   }
@@ -104,7 +113,7 @@ export class ChatComponent implements OnInit {
   }
   }
   ngOnDestroy(): void {
   ngOnDestroy(): void {
     this.msgServe.pageFun = () => {};
     this.msgServe.pageFun = () => {};
-    this.msgServe.unsubscribeMessage(this.uid)
+    this.msgServe.unsubscribeMessage(this.uid);
   }
   }
   initEmoji() {
   initEmoji() {
     let emojiChar =
     let emojiChar =
@@ -218,9 +227,7 @@ export class ChatComponent implements OnInit {
         duration: 1500,
         duration: 1500,
       });
       });
       loading.present();
       loading.present();
-      this.timer = setTimeout(() => {
-
-      }, 500);
+      this.timer = setTimeout(() => {}, 500);
     }
     }
   }
   }
   //调起表情
   //调起表情
@@ -242,21 +249,21 @@ export class ChatComponent implements OnInit {
     if (e && e.keyCode != 13) {
     if (e && e.keyCode != 13) {
       return;
       return;
     }
     }
+    this.disabled = true;
     if (this.text == '' && this.text.trim() == '') {
     if (this.text == '' && this.text.trim() == '') {
       this.presentToast('聊天内容不能为空');
       this.presentToast('聊天内容不能为空');
+      this.disabled = false;
       return;
       return;
     }
     }
     this.send({
     this.send({
       msg_type: 'text',
       msg_type: 'text',
       content: this.text,
       content: this.text,
     });
     });
-    this.text = '';
   }
   }
   async send(param: { msg_type: string; content: string }) {
   async send(param: { msg_type: string; content: string }) {
-    this.msgServe.publishMessage(param.content, this.uid);
-  }
-  dismiss(evt: any) {
-    this.isOpen = false;
+    await this.msgServe.publishMessage(param.content, this.uid);
+    this.text = '';
+    this.disabled = false;
   }
   }
   predivimg<T>(value: string) {
   predivimg<T>(value: string) {
     this.showPreView = true;
     this.showPreView = true;
@@ -265,6 +272,10 @@ export class ChatComponent implements OnInit {
   onBack() {
   onBack() {
     history.back();
     history.back();
   }
   }
+  onSendGift() {
+    console.log('点击送出礼物');
+    // this.liveService.get_duration()
+  }
   async presentToast(title: string, time?: number, color?: string) {
   async presentToast(title: string, time?: number, color?: string) {
     const toast = await this.toastController.create({
     const toast = await this.toastController.create({
       message: title,
       message: title,
@@ -273,4 +284,7 @@ export class ChatComponent implements OnInit {
     });
     });
     toast.present();
     toast.present();
   }
   }
+  toUrl(url: string) {
+    this.router.navigateByUrl(url);
+  }
 }
 }

+ 119 - 55
projects/live-app/src/services/message.service.ts

@@ -35,56 +35,51 @@ export class MessageService {
   messageMapList: any = {
   messageMapList: any = {
     global_room: [
     global_room: [
       // 世界频道消息列表
       // 世界频道消息列表
-      {
-        is_self: true,
-        avatar:
-          'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
-        msg_type: 1,
-        content: 'nihao',
-        create_time: new Date(),
-        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.`,
-        create_time: new Date(),
-        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.`,
-        create_time: new Date(),
-        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.`,
-        create_time: new Date(),
-        istoday: true,
-        timeStamp: new Date(),
-      },
-      {
-        is_self: false,
-        avatar:
-          'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
-        msg_type: 1,
-        content: 'nihao',
-        create_time: new Date(),
-        istoday: true,
-        timeStamp: new Date(),
-      },
+      // {
+      //   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(),
+      // },
     ],
     ],
   };
   };
 
 
@@ -329,6 +324,10 @@ export class MessageService {
           console.log('subscribeMessage', res);
           console.log('subscribeMessage', res);
           //订阅成功
           //订阅成功
           this.channelNameList[channelName] = true;
           this.channelNameList[channelName] = true;
+          if (this.messageMapList[channelName]?.length === 0) {
+            this.messageMapList[channelName] = [];
+            this.getHistoryMessage(channelName)
+          }
           this.pageFun?.();
           this.pageFun?.();
           resolve(true);
           resolve(true);
         })
         })
@@ -338,6 +337,25 @@ export class MessageService {
         });
         });
     });
     });
   }
   }
+
+  async getHistoryMessage(channelName: string) {
+    let query = new Parse.Query('MessageLog');
+    query.equalTo('channel', channelName);
+    query.descending('createdAt');
+    query.skip(this.messageMapList[channelName].length);
+    query.limit(50);
+    query.select('content','from_id');
+    let msgList = await query.find();
+    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].push(data)
+    });
+    // this.messageMapList[channelName].unshift(...msgList);
+  }
   /* 取消订阅 */
   /* 取消订阅 */
   unsubscribeMessage(channelName: string) {
   unsubscribeMessage(channelName: string) {
     this.rtmClient
     this.rtmClient
@@ -355,11 +373,30 @@ export class MessageService {
   async showMessage(param: any) {
   async showMessage(param: any) {
     let userData = await this.getUserMetadata(param.publisher);
     let userData = await this.getUserMetadata(param.publisher);
     let is_self = param.publisher == this.userId;
     let is_self = param.publisher == this.userId;
-    console.log(userData);
+    // console.log(userData);
     let message = JSON.parse(param.message);
     let message = JSON.parse(param.message);
     if (!this.messageMapList[param.channelName])
     if (!this.messageMapList[param.channelName])
       this.messageMapList[param.channelName] = [];
       this.messageMapList[param.channelName] = [];
-    this.messageMapList[param.channelName].push({
+    if (is_self) {
+      this.saveMeesage({
+        from_id: this.userId,
+        from_username: Parse.User.current()?.get('nickname') ?? '未知用户',
+        target_id: param.channelName,
+        // target_name: userData.nickname.value ?? '未知用户',
+        channel: param.channelName,
+        content: {
+          avatar:
+            userData.avatar.value ??
+            'https://file-cloud.fmode.cn/DXNgcD6zo6/20221202/j6p8kb034039.png',
+          msg_type: 1,
+          name: userData.nickname.value ?? '未知用户',
+          content: message?.text ?? '',
+          publisher: param.publisher,
+          timestamp: param.timestamp,
+        },
+      });
+    }
+    let data: any = {
       is_self: is_self,
       is_self: is_self,
       avatar:
       avatar:
         userData.avatar.value ??
         userData.avatar.value ??
@@ -367,12 +404,39 @@ export class MessageService {
       msg_type: 1,
       msg_type: 1,
       name: userData.nickname.value ?? '未知用户',
       name: userData.nickname.value ?? '未知用户',
       content: message?.text ?? '',
       content: message?.text ?? '',
-      create_time: new Date(param.timeStamp),
+      publisher: param.publisher,
+      timestamp: new Date(param.timestamp),
       istoday: true,
       istoday: true,
-      timeStamp: new Date(param.timeStamp),
-    });
+    };
+    this.messageMapList[param.channelName].push(data);
     this.pageFun?.();
     this.pageFun?.();
   }
   }
+
+  async saveMeesage(parse: {
+    from_id: string;
+    from_username: string;
+    target_id: string;
+    // target_name: string;
+    channel: string;
+    content: Object;
+  }) {
+    console.log(parse);
+    let obj = Parse.Object.extend('MessageLog');
+    let message = new obj();
+    message.set('from_id', parse.from_id);
+    message.set('from_username', parse.from_username);
+    message.set('target_id', parse.target_id);
+    // message.set('target_name', parse.target_name);
+    message.set('channel', parse.channel);
+    message.set('content', parse.content);
+    message.set('company', {
+      __type: 'Pointer',
+      className: 'Company',
+      objectId: this.company,
+    });
+    await message.save();
+  }
+
   async getUserMetadata(uid: string) {
   async getUserMetadata(uid: string) {
     try {
     try {
       const result = await this.rtmClient?.storage.getUserMetadata({
       const result = await this.rtmClient?.storage.getUserMetadata({