| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 | import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core';import { CommonModule } from '@angular/common';import { WxworkCorp } from 'fmode-ng/core';import { FmodeObject } from 'fmode-ng/parse';// 群聊消息interface ChatMessage {  id: string;  sender: string;  senderName: string;  content: string;  time: Date;  isCustomer: boolean;  needsReply: boolean;  // 是否需要回复  replyTime?: Date;     // 回复时间}/** * 群聊信息汇总组件 *  * 功能: * 1. 展示群聊中客户的历史消息 * 2. 一键筛选客户消息 * 3. 未回复消息提示(超过10分钟) * 4. 群聊介绍文案自动发送 */@Component({  selector: 'app-group-chat-summary',  standalone: true,  imports: [CommonModule],  templateUrl: './group-chat-summary.component.html',  styleUrls: ['./group-chat-summary.component.scss']})export class GroupChatSummaryComponent implements OnInit, OnChanges {  @Input() groupChat: FmodeObject | null = null;  @Input() contact: FmodeObject | null = null;  @Input() cid: string = '';  // 群聊消息  messages: ChatMessage[] = [];  customerMessages: ChatMessage[] = [];  // 客户消息  unreadMessages: ChatMessage[] = [];     // 未回复消息    // UI状态  loading: boolean = false;  showOnlyCustomer: boolean = false;      // 只看客户消息  showOnlyUnread: boolean = false;        // 只看未回复  collapsed: boolean = true;              // 折叠状态    // 统计  totalMessages: number = 0;  customerMessageCount: number = 0;  unreadCount: number = 0;    // 群聊介绍  groupIntro: string = '';  introSent: boolean = false;  // 企微SDK  wecorp: WxworkCorp | null = null;  constructor() {}  ngOnInit() {    this.initWxwork();    this.loadGroupIntro();  }  ngOnChanges(changes: SimpleChanges) {    if (changes['groupChat'] && this.groupChat) {      this.loadChatMessages();    }  }  /**   * 初始化企微SDK   */  async initWxwork() {    if (this.cid) {      try {        // @ts-ignore        this.wecorp = new WxworkCorp(this.cid);      } catch (err) {        console.error('初始化企微SDK失败:', err);      }    }  }  /**   * 加载群介绍文案   */  loadGroupIntro() {    // 默认群介绍文案    this.groupIntro = `欢迎加入映三色设计服务群!👋我是您的专属设计顾问,很高兴为您服务。📋 服务流程:1️⃣ 需求沟通 - 了解您的设计需求2️⃣ 方案设计 - 提供专业设计方案3️⃣ 方案优化 - 根据您的反馈调整4️⃣ 交付执行 - 完成设计并交付⏰ 服务时间:工作日 9:00-18:00📞 紧急联系:请直接拨打客服电话有任何问题随时在群里@我,我会及时回复您!💙    `.trim();        // 检查是否已发送    this.checkIntroSent();  }  /**   * 检查群介绍是否已发送   */  async checkIntroSent() {    if (!this.groupChat) return;        const data = this.groupChat.get('data') || {};    this.introSent = data.introSent || false;  }  /**   * 发送群介绍   */  async sendGroupIntro() {    if (!this.groupChat || !this.wecorp) {      window?.fmode?.alert('群聊信息不完整,无法发送');      return;    }    try {      const chatId = this.groupChat.get('chat_id');      if (!chatId) {        window?.fmode?.alert('群聊ID不存在');        return;      }      // 调用企微API发送消息      await this.wecorp.appchat.send({        chatid: chatId,        msgtype: 'text',        text: {          content: this.groupIntro        }      });      // 标记已发送      const data = this.groupChat.get('data') || {};      data.introSent = true;      data.introSentAt = new Date();      this.groupChat.set('data', data);      await this.groupChat.save();      this.introSent = true;      window?.fmode?.alert('群介绍已发送!');    } catch (err: any) {      console.error('发送群介绍失败:', err);      window?.fmode?.alert('发送失败: ' + (err.message || '未知错误'));    }  }  /**   * 加载群聊消息   */  async loadChatMessages() {    if (!this.groupChat) return;    this.loading = true;        try {      // 从 groupChat.data 获取聊天记录      const data = this.groupChat.get('data') || {};      const chatHistory = data.chatHistory || [];            // 转换为消息对象      this.messages = chatHistory.map((msg: any) => ({        id: msg.msgid || Math.random().toString(36).substr(2, 9),        sender: msg.from,        senderName: msg.fromName || msg.from,        content: this.extractMessageContent(msg),        time: new Date(msg.msgtime * 1000),        isCustomer: this.isCustomerMessage(msg.from),        needsReply: this.checkNeedsReply(msg),        replyTime: msg.replyTime ? new Date(msg.replyTime) : undefined      })).filter((msg: ChatMessage) => msg.content); // 过滤空消息            // 统计      this.totalMessages = this.messages.length;      this.customerMessages = this.messages.filter(m => m.isCustomer);      this.customerMessageCount = this.customerMessages.length;            // 检查未回复消息      this.checkUnreadMessages();            console.log(`✅ 加载了 ${this.totalMessages} 条消息,客户消息 ${this.customerMessageCount} 条`);    } catch (err) {      console.error('加载群聊消息失败:', err);    } finally {      this.loading = false;    }  }  /**   * 提取消息内容   */  extractMessageContent(msg: any): string {    if (msg.msgtype === 'text' && msg.text) {      return msg.text.content || '';    } else if (msg.msgtype === 'image') {      return '[图片]';    } else if (msg.msgtype === 'file') {      return '[文件]';    } else if (msg.msgtype === 'voice') {      return '[语音]';    } else if (msg.msgtype === 'video') {      return '[视频]';    }    return '';  }  /**   * 判断是否为客户消息   */  isCustomerMessage(sender: string): boolean {    // 企微外部联系人ID通常以 wm 或 wo 开头    return sender.startsWith('wm') || sender.startsWith('wo');  }  /**   * 检查是否需要回复   */  checkNeedsReply(msg: any): boolean {    // 如果是客户消息且没有回复时间    if (this.isCustomerMessage(msg.from) && !msg.replyTime) {      const msgTime = new Date(msg.msgtime * 1000);      const now = new Date();      const diff = now.getTime() - msgTime.getTime();            // 超过10分钟未回复      return diff > 10 * 60 * 1000;    }    return false;  }  /**   * 检查未回复消息   */  checkUnreadMessages() {    this.unreadMessages = this.customerMessages.filter(msg => {      const now = new Date();      const diff = now.getTime() - msg.time.getTime();      return diff > 10 * 60 * 1000 && !msg.replyTime;    });        this.unreadCount = this.unreadMessages.length;        // 如果有超过10分钟未回复的消息,发送通知    if (this.unreadCount > 0) {      this.sendUnreadNotification();    }  }  /**   * 发送未回复通知   */  async sendUnreadNotification() {    // 这里可以调用企微API发送应用消息通知    console.log(`⚠️ 有 ${this.unreadCount} 条消息超过10分钟未回复`);        // TODO: 实现企微应用消息推送    // 需要后端配合实现推送到技术人员手机  }  /**   * 切换折叠状态   */  toggleCollapse() {    this.collapsed = !this.collapsed;  }  /**   * 只看客户消息   */  toggleCustomerFilter() {    this.showOnlyCustomer = !this.showOnlyCustomer;    this.showOnlyUnread = false;  }  /**   * 只看未回复   */  toggleUnreadFilter() {    this.showOnlyUnread = !this.showOnlyUnread;    this.showOnlyCustomer = false;  }  /**   * 获取显示的消息列表   */  getDisplayMessages(): ChatMessage[] {    if (this.showOnlyUnread) {      return this.unreadMessages;    } else if (this.showOnlyCustomer) {      return this.customerMessages;    }    return this.messages;  }  /**   * 打开企微群聊   */  async openGroupChat() {    if (!this.groupChat) return;        try {      const chatId = this.groupChat.get('chat_id');      if (chatId && this.wecorp) {        // 使用企微SDK打开群聊        // @ts-ignore - WxworkCorp API        await this.wecorp.openChat?.(chatId);      } else {        window?.fmode?.alert('群聊ID不存在');      }    } catch (err) {      console.error('打开群聊失败:', err);      window?.fmode?.alert('打开群聊失败');    }  }  /**   * 格式化时间   */  formatTime(date: Date): string {    if (!date) return '';        const now = new Date();    const diff = now.getTime() - date.getTime();        // 小于1分钟    if (diff < 60 * 1000) {      return '刚刚';    }        // 小于1小时    if (diff < 60 * 60 * 1000) {      const minutes = Math.floor(diff / (60 * 1000));      return `${minutes}分钟前`;    }        // 小于24小时    if (diff < 24 * 60 * 60 * 1000) {      const hours = Math.floor(diff / (60 * 60 * 1000));      return `${hours}小时前`;    }        // 超过24小时    const month = date.getMonth() + 1;    const day = date.getDate();    const hour = date.getHours();    const minute = date.getMinutes();    return `${month}/${day} ${hour}:${minute.toString().padStart(2, '0')}`;  }  /**   * 获取未回复时长   */  getUnreadDuration(date: Date): string {    const now = new Date();    const diff = now.getTime() - date.getTime();    const minutes = Math.floor(diff / (60 * 1000));        if (minutes < 60) {      return `${minutes}分钟`;    } else {      const hours = Math.floor(minutes / 60);      return `${hours}小时`;    }  }  /**   * 获取当前时间戳   */  getCurrentTime(): number {    return Date.now();  }}
 |