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(); } }