import { Component, OnInit, signal } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { GroupChatService } from '../services/groupchat.service'; import { ProjectService } from '../services/project.service'; import { WxworkCorp } from 'fmode-ng/core'; import { FmodeObject } from 'fmode-ng/core'; interface GroupChat { id: string; chat_id: string; name: string; project?: string; projectId?: string; memberCount: number; isDisabled?: boolean; createdAt?: Date; } interface Project { id: string; title: string; } @Component({ selector: 'app-groupchats', standalone: true, imports: [CommonModule, FormsModule], templateUrl: './groupchats.html', styleUrls: ['./groupchats.scss'] }) export class GroupChats implements OnInit { groupChats = signal([]); projects = signal([]); loading = signal(false); keyword = signal(''); total = signal(0); showPanel = false; panelMode: 'detail' | 'edit' = 'detail'; currentGroupChat: GroupChat | null = null; formModel: Partial = {}; // 群组详情数据 groupChatDetail: any = null; groupMembers: any[] = []; qrCodeUrl: string = ''; loadingDetail = signal(false); // 企微Corp(需要配置cid) private wecorp: WxworkCorp | null = null; private readonly COMPANY_ID = 'cDL6R1hgSi'; // 映三色帐套 constructor( private groupChatService: GroupChatService, private projectService: ProjectService ) { // 初始化企微Corp this.wecorp = new WxworkCorp(this.COMPANY_ID); } ngOnInit(): void { this.loadGroupChats(); this.loadProjects(); } async loadGroupChats(): Promise { this.loading.set(true); try { const groups = await this.groupChatService.findGroupChats(); const groupList: GroupChat[] = groups.map(g => { const json = this.groupChatService.toJSON(g); return { id: json.objectId, chat_id: json.chat_id || '', name: json.name || '未命名群组', project: json.projectTitle, projectId: json.projectId, memberCount: json.member_list?.length || 0, isDisabled: json.isDisabled || false, createdAt: json.createdAt }; }); this.groupChats.set(groupList); this.total.set(groupList.length); } catch (error) { console.error('加载群组列表失败:', error); } finally { this.loading.set(false); } } async loadProjects(): Promise { try { const projs = await this.projectService.findProjects({ limit: 200 }); this.projects.set( projs.map(p => { const json = this.projectService.toJSON(p); return { id: json.objectId, title: json.title }; }) ); } catch (error) { console.error('加载项目列表失败:', error); } } get filtered() { const kw = this.keyword().trim().toLowerCase(); if (!kw) return this.groupChats(); return this.groupChats().filter(g => g.name.toLowerCase().includes(kw)); } resetFilters() { this.keyword.set(''); } async viewGroupChat(group: GroupChat) { this.currentGroupChat = group; this.panelMode = 'detail'; this.showPanel = true; // 加载群组详情 await this.loadGroupChatDetail(group); } /** * 加载群组详情(从企微获取) */ async loadGroupChatDetail(group: GroupChat) { if (!this.wecorp || !group.chat_id) { console.error('企微Corp未初始化或群组chat_id为空'); return; } this.loadingDetail.set(true); try { // 从企微获取群组详情 const chatInfo: any = await this.wecorp.externalContact.groupChat.get( group.chat_id ); console.log('群组详情:', chatInfo); if (chatInfo && chatInfo.group_chat) { this.groupChatDetail = chatInfo.group_chat; this.groupMembers = chatInfo.group_chat.member_list || []; // 获取入群二维码(如果有) // 注意:入群二维码需要单独调用API获取 // 这里简化处理,实际可能需要根据API文档调整 if (chatInfo.group_chat.qr_code) { this.qrCodeUrl = chatInfo.group_chat.qr_code; } else { this.qrCodeUrl = ''; } } } catch (error) { console.error('加载群组详情失败:', error); alert('加载群组详情失败,可能是企微API调用失败'); } finally { this.loadingDetail.set(false); } } editGroupChat(group: GroupChat) { this.currentGroupChat = group; this.formModel = { ...group }; this.panelMode = 'edit'; this.showPanel = true; } closePanel() { this.showPanel = false; this.currentGroupChat = null; this.formModel = {}; } async updateGroupChat() { if (!this.currentGroupChat) return; try { await this.groupChatService.updateGroupChat(this.currentGroupChat.id, { projectId: this.formModel.projectId || null, isDisabled: this.formModel.isDisabled }); await this.loadGroupChats(); this.closePanel(); } catch (error) { console.error('更新群组失败:', error); alert('更新群组失败,请重试'); } } async toggleGroupChat(group: GroupChat) { const action = group.isDisabled ? '启用' : '禁用'; if (!confirm(`确定要${action}群组 "${group.name}" 吗?`)) { return; } try { await this.groupChatService.toggleGroupChat(group.id, !group.isDisabled); await this.loadGroupChats(); } catch (error) { console.error(`${action}群组失败:`, error); alert(`${action}群组失败,请重试`); } } exportGroupChats() { const header = ['群名称', '企微群ID', '关联项目', '成员数', '状态', '创建时间']; const rows = this.filtered.map(g => [ g.name, g.chat_id, g.project || '未关联', String(g.memberCount), g.isDisabled ? '已禁用' : '正常', g.createdAt instanceof Date ? g.createdAt.toISOString().slice(0, 10) : String(g.createdAt || '') ]); this.downloadCSV('群组列表.csv', [header, ...rows]); } private downloadCSV(filename: string, rows: (string | number)[][]) { const escape = (val: string | number) => { const s = String(val ?? ''); if (/[",\n]/.test(s)) return '"' + s.replace(/"/g, '""') + '"'; return s; }; const csv = rows.map(r => r.map(escape).join(',')).join('\n'); const blob = new Blob(['\ufeff', csv], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); } }