123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- 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<GroupChat[]>([]);
- projects = signal<Project[]>([]);
- loading = signal(false);
- keyword = signal('');
- total = signal(0);
- showPanel = false;
- panelMode: 'detail' | 'edit' = 'detail';
- currentGroupChat: GroupChat | null = null;
- formModel: Partial<GroupChat> = {};
- // 群组详情数据
- 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<void> {
- 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<void> {
- 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);
- }
- }
|