# 企业微信群聊与联系人管理 ## 概述 本文档介绍如何在企业微信聊天窗口的工具栏入口页面中,获取当前会话的群组信息或联系人信息,并同步到 Parse Server 的 `GroupChat` 和 `Contact` 表中。 ## 引用方式 ```typescript import { WxworkSDK, WxworkCorp } from 'fmode-ng/core'; import { FmodeParse, FmodeObject } from 'fmode-ng/parse'; import { WxworkAuthGuard } from 'fmode-ng'; ``` ## 核心功能 ### 1. 获取当前聊天上下文 使用 `WxworkSDK.getCurrentChat()` 方法获取当前企微窗口的会话信息。 ### 2. 同步群组信息 使用 `WxworkSDK.syncGroupChat()` 方法同步群聊信息到 `GroupChat` 表。 ### 3. 同步联系人信息 使用 `WxworkSDK.syncContact()` 方法同步外部联系人信息到 `Contact` 表。 ### 4. ⭐ 统一获取方法(推荐) 使用 `WxworkSDK.getCurrentChatObject()` 一次性获取当前会话对象(群聊或联系人)。 ## WxworkSDK 核心方法 ### getCurrentChat() - 获取当前会话上下文 ```typescript /** * 获取当前企微窗口的会话信息 * @returns WxworkCurrentChat 对象 */ async getCurrentChat(): Promise interface WxworkCurrentChat { type: "chatId" | "userId"; // 会话类型 id?: string; // 群聊ID或用户ID group?: any; // 群聊详细信息 contact?: any; // 联系人详细信息 follow_user?: any; // 跟进人信息 } ``` **使用场景**: - 从企微聊天栏工具进入页面时,自动识别当前会话 - 支持群聊和单聊两种场景 ### syncGroupChat() - 同步群组信息 ```typescript /** * 同步群聊信息到 GroupChat 表 * @param groupInfo 企微群聊信息 * @returns GroupChat Parse Object */ async syncGroupChat(groupInfo: any): Promise ``` **功能**: - 根据 `chat_id` 查询或创建 GroupChat 记录 - 自动生成入群链接 (`joinUrl`) 和入群二维码 (`joinQrcode`) - 同步群聊基本信息(名称、群主、公告等) - 同步成员列表 (`member_list`) 和成员版本 (`member_version`) - 仅在数据变化时保存,避免不必要的数据库写入 ### syncContact() - 同步联系人信息 ```typescript /** * 同步外部联系人信息到 Contact 表 * @param contactInfo 企微外部联系人信息(包含 external_contact 和 follow_user) * @returns Contact Parse Object */ async syncContact(contactInfo: any): Promise ``` **功能**: - 根据 `external_userid` 和 `company` 查询或创建 Contact 记录 - **独立字段**: `name`(姓名)、`mobile`(手机号)、`external_userid`(外部用户ID) - **data 字段**: 其他所有信息统一存储在 `data` Object 类型字段中 - 包含完整的企微联系人信息和 `follow_user` 跟进人列表 - 仅在数据变化时保存,避免不必要的数据库写入 **参数兼容**: ```typescript // 方式1:传入完整的 contactInfo(推荐) const contactInfo = await wecorp.externalContact.get(externalUserId); await wxwork.syncContact(contactInfo); // 方式2:只传入 external_contact await wxwork.syncContact(contactInfo.external_contact); ``` ### ⭐ getCurrentChatObject() - 统一获取方法(推荐) ```typescript /** * 获取当前聊天对象(群聊或联系人) * @returns { GroupChat?, Contact?, currentChat } */ async getCurrentChatObject(): Promise<{ GroupChat?: FmodeObject, Contact?: FmodeObject, currentChat: WxworkCurrentChat | null }> ``` **功能**: - 一次调用同时获取会话上下文和对应的 Parse Object - 自动识别群聊或联系人场景 - 自动调用 `syncGroupChat` 或 `syncContact` 同步数据 - 返回结果包含 `GroupChat` 或 `Contact`,用户自主判断后续逻辑 **返回值**: - `GroupChat`: 群聊对象(群聊场景下存在) - `Contact`: 联系人对象(单聊场景下存在) - `currentChat`: 原始会话上下文 **使用示例**: ```typescript const { GroupChat, Contact, currentChat } = await wxwork.getCurrentChatObject(); if (GroupChat) { // 群聊场景 console.log("群名:", GroupChat.get("name")); console.log("成员数:", GroupChat.get("member_list").length); } else if (Contact) { // 联系人场景 console.log("姓名:", Contact.get("name")); console.log("企业:", Contact.get("data").corp_name); } ``` ## 数据范式 ### GroupChat 表(群聊) | 字段 | 类型 | 说明 | |------|------|------| | chat_id | String | 企微群聊ID(唯一标识) | | name | String | 群聊名称 | | owner | String | 群主 userid | | notice | String | 群公告 | | member_list | Array | 群成员列表 | | member_version | String | 成员版本号(用于判断成员变化) | | joinUrl | String | 入群链接(scene=1) | | joinQrcode | String | 入群二维码链接(scene=2) | | createdAt | Date | 创建时间 | | updatedAt | Date | 更新时间 | **member_list 结构**: ```json [ { "userid": "zhangsan", "type": 1, "join_time": 1605171726, "join_scene": 1, "invitor": { "userid": "lisi" } } ] ``` ### Contact 表(联系人) | 字段 | 类型 | 说明 | |------|------|------| | external_userid | String | 外部联系人ID(唯一标识) | | company | Pointer | 所属企业 | | name | String | 联系人姓名 | | mobile | String | 手机号 | | data | Object | 完整的企微联系人信息(包含所有字段) | | createdAt | Date | 创建时间 | | updatedAt | Date | 更新时间 | **⭐ 数据结构说明**: - **独立字段**:仅 `name`(姓名)、`mobile`(手机号)、`external_userid`(外部用户ID)为独立字段 - **data 字段**:其他所有企微联系人信息统一存储在 `data` Object 类型字段中 **data 字段包含的信息**: ```json { "external_userid": "wmxxx", "name": "张三", "avatar": "http://...", "type": 1, "gender": 1, "unionid": "oxxx", "position": "产品经理", "corp_name": "ABC公司", "corp_full_name": "ABC科技有限公司", "external_profile": { "external_attr": [ { "type": 0, "name": "职位", "text": { "value": "产品经理" } } ] }, "follow_user": [ { "userid": "zhangsan", "remark": "备注名", "description": "描述", "createtime": 1605171726, "tags": [ { "group_name": "标签组", "tag_name": "标签名", "type": 1 } ], "remark_corp_name": "备注企业名称", "remark_mobiles": ["13800138000"] } ] } ``` **访问 data 字段示例**: ```typescript const contact = await wxwork.syncContact(contactInfo); // 独立字段直接访问 const name = contact.get("name"); const mobile = contact.get("mobile"); // data 字段内容需通过 .get("data") 访问 const data = contact.get("data"); const corpName = data.corp_name; const avatar = data.avatar; const followUsers = data.follow_user; ``` ## 页面开发示例 ### 示例1:群聊消息发送页面 从聊天栏工具入口,自动识别当前群聊并发送消息。 ```typescript import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { WxworkSDK, WxworkCorp, WxworkCurrentChat } from 'fmode-ng/core'; import { FmodeParse, FmodeObject } from 'fmode-ng/parse'; const Parse = FmodeParse.with("nova"); export class PageGroupMessageComponent implements OnInit { cid: string = ''; gid: string = ''; chatId: string = ''; wework: WxworkSDK; wecorp: WxworkCorp; currentChat: WxworkCurrentChat | null = null; groupChat: FmodeObject | null = null; constructor(private route: ActivatedRoute) {} async ngOnInit() { this.route.paramMap.subscribe(async params => { this.cid = params.get('cid') || ''; this.gid = params.get('gid') || ''; if (this.cid) { this.wework = new WxworkSDK({ cid: this.cid, appId: 'crm' }); this.wecorp = new WxworkCorp(this.cid); await this.loadGroupChat(); } }); } /** * 加载群聊信息 */ async loadGroupChat() { try { if (this.gid) { // 方式1:通过路由参数 gid 加载 let query = new Parse.Query("GroupChat"); this.groupChat = await query.get(this.gid); this.chatId = this.groupChat.get("chat_id"); // 从企微API获取最新群聊信息 let chatInfo = await this.wecorp.externalContact.groupChat.get(this.chatId); this.currentChat = { id: chatInfo?.chat_id, type: "chatId", group: chatInfo?.group_chat || chatInfo }; } else { // 方式2:从当前企微窗口获取上下文 this.currentChat = await this.wework.getCurrentChat(); if (this.currentChat?.group) { this.chatId = this.currentChat.id || ''; // ⭐ 同步群聊信息到 Parse Server this.groupChat = await this.wework.syncGroupChat(this.currentChat.group); this.gid = this.groupChat.id; } } console.log("群聊ID:", this.chatId); console.log("群聊名称:", this.groupChat?.get("name")); console.log("群成员数:", this.groupChat?.get("member_list")?.length); } catch (error) { console.error('加载群聊失败:', error); } } /** * 发送文本消息 */ async sendTextMessage() { if (!this.chatId) { alert('请先加载群聊信息'); return; } const content = "这是一条测试消息"; const result = await this.wecorp.appchat.sendText(this.chatId, content); if (result?.errcode === 0) { console.log('发送成功'); } else { console.error('发送失败:', result?.errmsg); } } } ``` ### 示例2:联系人详情页面 从联系人侧边栏工具入口,自动识别当前联系人并显示详情。 ```typescript import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { WxworkSDK, WxworkCorp, WxworkCurrentChat } from 'fmode-ng/core'; import { FmodeParse, FmodeObject } from 'fmode-ng/parse'; const Parse = FmodeParse.with("nova"); export class PageContactDetailComponent implements OnInit { cid: string = ''; contactId: string = ''; externalUserId: string = ''; wework: WxworkSDK; wecorp: WxworkCorp; currentChat: WxworkCurrentChat | null = null; contact: FmodeObject | null = null; constructor(private route: ActivatedRoute) {} async ngOnInit() { this.route.paramMap.subscribe(async params => { this.cid = params.get('cid') || ''; this.contactId = params.get('contactId') || ''; if (this.cid) { this.wework = new WxworkSDK({ cid: this.cid, appId: 'crm' }); this.wecorp = new WxworkCorp(this.cid); await this.loadContact(); } }); } /** * 加载联系人信息 */ async loadContact() { try { if (this.contactId) { // 方式1:通过路由参数 contactId 加载 let query = new Parse.Query("Contact"); this.contact = await query.get(this.contactId); this.externalUserId = this.contact.get("external_userid"); } else { // 方式2:从当前企微窗口获取上下文 this.currentChat = await this.wework.getCurrentChat(); if (this.currentChat?.contact) { this.externalUserId = this.currentChat.id || ''; // 获取完整的联系人信息 const contactInfo = await this.wecorp.externalContact.get(this.externalUserId); // ⭐ 同步联系人信息到 Parse Server this.contact = await this.wework.syncContact(contactInfo.external_contact); this.contactId = this.contact.id; } } console.log("联系人ID:", this.externalUserId); console.log("联系人姓名:", this.contact?.get("name")); // ⭐ 访问 data 字段中的信息 const data = this.contact?.get("data"); console.log("所属企业:", data?.corp_name); console.log("跟进人:", data?.follow_user); } catch (error) { console.error('加载联系人失败:', error); } } /** * 更新联系人备注 */ async updateRemark(remark: string) { if (!this.contact) return; this.contact.set("remark", remark); await this.contact.save(); console.log('备注更新成功'); } } ``` ### 示例3:⭐ 使用 getCurrentChatObject() 的最简模板(推荐) 适用于快速开发企微工具栏页面,使用统一方法一次性获取会话对象。 ```typescript import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { WxworkSDK, WxworkCorp } from 'fmode-ng/core'; import { FmodeObject } from 'fmode-ng/parse'; export class MyToolComponent implements OnInit { cid: string = ''; wework: WxworkSDK; wecorp: WxworkCorp; groupChat: FmodeObject | null = null; contact: FmodeObject | null = null; constructor(private route: ActivatedRoute) {} async ngOnInit() { this.cid = this.route.snapshot.paramMap.get('cid') || ''; this.wework = new WxworkSDK({ cid: this.cid, appId: 'crm' }); this.wecorp = new WxworkCorp(this.cid); // ⭐ 一次性获取当前会话对象 const { GroupChat, Contact } = await this.wework.getCurrentChatObject(); if (GroupChat) { // 群聊场景 this.groupChat = GroupChat; console.log("当前群聊:", GroupChat.get("name")); console.log("成员数:", GroupChat.get("member_list").length); } else if (Contact) { // 联系人场景 this.contact = Contact; console.log("当前联系人:", Contact.get("name")); // ⭐ 访问 data 字段 const data = Contact.get("data"); console.log("企业:", data.corp_name); console.log("跟进人:", data.follow_user); } // 开始业务逻辑... } } ``` ### 示例4:传统方式(兼容旧代码) 使用 getCurrentChat() 分步处理的方式。 ```typescript import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { WxworkSDK, WxworkCorp, WxworkCurrentChat } from 'fmode-ng/core'; import { FmodeObject } from 'fmode-ng/parse'; export class MyToolComponent implements OnInit { cid: string = ''; wework: WxworkSDK; wecorp: WxworkCorp; currentChat: WxworkCurrentChat | null = null; // 群聊或联系人 Parse Object chatObject: FmodeObject | null = null; constructor(private route: ActivatedRoute) {} async ngOnInit() { this.cid = this.route.snapshot.paramMap.get('cid') || ''; this.wework = new WxworkSDK({ cid: this.cid, appId: 'crm' }); this.wecorp = new WxworkCorp(this.cid); // 获取当前会话 this.currentChat = await this.wework.getCurrentChat(); if (this.currentChat?.type === "chatId") { // 群聊场景 this.chatObject = await this.wework.syncGroupChat(this.currentChat.group); console.log("当前群聊:", this.chatObject.get("name")); } else if (this.currentChat?.type === "userId") { // 单聊场景 const contactInfo = await this.wecorp.externalContact.get(this.currentChat.id); this.chatObject = await this.wework.syncContact(contactInfo); console.log("当前联系人:", this.chatObject.get("name")); } // 开始业务逻辑... } } ``` ### 示例5:⭐ 完整的聊天上下文页面(page-chat-context) 这是一个完整的演示页面,展示了如何同时获取和展示员工信息及聊天上下文(群聊或联系人)。 **路由配置**: - `chat/:cid/context` - `chat/:cid/:appId/context` **页面功能**: 1. 显示当前登录员工信息(Profile/UserSocial) 2. 显示当前聊天上下文(群聊或联系人) 3. 根据场景展示不同的信息卡片 **核心代码**: ```typescript import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { WxworkSDK, WxworkCorp, WxworkCurrentChat } from 'fmode-ng/core'; import { FmodeParse, FmodeObject } from 'fmode-ng/parse'; const Parse = FmodeParse.with("nova"); @Component({ selector: 'app-page-chat-context', standalone: true, templateUrl: './page-chat-context.component.html' }) export class PageChatContextComponent implements OnInit { cid: string = ''; appId: string = ''; loading: boolean = true; wxwork: WxworkSDK | null = null; wecorp: WxworkCorp | null = null; // 当前登录的员工信息 currentUser: FmodeObject | null = null; // 当前会话信息 currentChat: WxworkCurrentChat | null = null; chatType: 'group' | 'contact' | 'none' = 'none'; // 群聊或联系人对象 groupChat: FmodeObject | null = null; contact: FmodeObject | null = null; constructor(private route: ActivatedRoute) {} async ngOnInit() { this.route.paramMap.subscribe(async params => { this.cid = params.get('cid') || ''; this.appId = params.get('appId') || 'crm'; if (!this.cid) { alert('缺少企业ID参数'); return; } await this.loadData(); }); } async loadData() { try { this.loading = true; // 初始化 SDK this.wxwork = new WxworkSDK({ cid: this.cid, appId: this.appId }); this.wecorp = new WxworkCorp(this.cid); // 1️⃣ 加载当前登录员工信息(由 WxworkAuthGuard 自动登录) this.currentUser = await this.wxwork.getCurrentUser(); // 2️⃣ 加载当前聊天对象(群聊或联系人) const chatObject = await this.wxwork.getCurrentChatObject(); this.currentChat = chatObject.currentChat; if (chatObject.GroupChat) { this.chatType = 'group'; this.groupChat = chatObject.GroupChat; } else if (chatObject.Contact) { this.chatType = 'contact'; this.contact = chatObject.Contact; } } catch (error) { console.error('加载数据失败:', error); alert('加载失败: ' + error); } finally { this.loading = false; } } // Helper: 获取当前员工姓名 getCurrentUserName(): string { if (!this.currentUser) return '未知'; return this.currentUser.get('name') || this.currentUser.get('userid') || '未知'; } // Helper: 获取当前员工类型 getCurrentUserType(): string { if (!this.currentUser) return ''; return this.currentUser.className === 'Profile' ? '企业员工' : '外部用户'; } // Helper: 获取联系人详细数据 getContactData(): any { return this.contact?.get('data') || {}; } // Helper: 获取联系人企业信息 getContactCorpName(): string { const data = this.getContactData(); return data.corp_name || data.corp_full_name || '未知'; } // Helper: 获取联系人头像 getContactAvatar(): string { const data = this.getContactData(); return data.avatar || ''; } // Helper: 获取跟进人列表 getFollowUsers(): any[] { const data = this.getContactData(); return data.follow_user || []; } // Helper: 获取群成员列表 getGroupMembers(): any[] { const memberList = this.groupChat?.get('member_list'); return Array.isArray(memberList) ? memberList : []; } } ``` **模板示例(HTML)**: ```html

加载中...

当前员工

姓名

{{ getCurrentUserName() }}

类型

{{ getCurrentUserType() }}

群聊信息

群名

{{ groupChat.get('name') }}

成员数

{{ getGroupMembers().length }}

群主

{{ groupChat.get('owner') }}

联系人信息

{{ contact.get('name') }}

{{ getContactCorpName() }}

手机号

{{ contact.get('mobile') || '未绑定' }}

企业信息

企业

{{ getContactCorpName() }}

职位

{{ getContactData().position || '未知' }}

跟进人

``` **关键特性**: 1. **统一方法调用**:使用 `getCurrentChatObject()` 一次性获取会话对象 2. **自动场景识别**:根据返回的 `GroupChat` 或 `Contact` 自动判断场景 3. **data 字段访问**:通过 `getContactData()` 统一访问 Contact.data 中的信息 4. **Helper 方法**:封装数据访问逻辑,简化模板代码 5. **响应式设计**:适配移动端和桌面端 **访问链接示例**: - 脑控科技: https://app.fmode.cn/dev/crm/chat/E4KpGvTEto/context - 映三色: https://app.fmode.cn/dev/crm/chat/cDL6R1hgSi/crm/context ## 入口场景识别 企微工具栏入口有多种场景,可通过 `entry` 字段判断: ```typescript const context = await this.wework.getContext(); switch (context.entry) { case "group_chat_tools": // 群聊侧边栏工具 console.log("从群聊工具栏进入"); break; case "single_chat_tools": // 单聊侧边栏工具 console.log("从单聊工具栏进入"); break; case "contact_profile": // 联系人详情页 console.log("从联系人详情进入"); break; case "normal": // 普通应用首页 console.log("从应用首页进入"); break; } ``` ## 常见应用场景 ### 场景1:群发消息工具 ```typescript async broadcastMessage(message: string) { // 获取当前群聊 const currentChat = await this.wework.getCurrentChat(); if (currentChat?.type === "chatId") { const groupChat = await this.wework.syncGroupChat(currentChat.group); const chatId = groupChat.get("chat_id"); // 发送消息 await this.wecorp.appchat.sendText(chatId, message); console.log("消息已发送到群聊:", groupChat.get("name")); } } ``` ### 场景2:群成员管理 ```typescript async listGroupMembers() { const currentChat = await this.wework.getCurrentChat(); if (currentChat?.type === "chatId") { const groupChat = await this.wework.syncGroupChat(currentChat.group); const memberList = groupChat.get("member_list"); console.log("群成员总数:", memberList.length); memberList.forEach(member => { console.log("成员:", member.userid, "加入时间:", member.join_time); }); } } ``` ### 场景3:添加客户标签 ```typescript async addTagToContact(tagIds: string[]) { // ⭐ 使用统一方法 const { Contact } = await this.wework.getCurrentChatObject(); if (Contact) { const externalUserId = Contact.get("external_userid"); // ⭐ 从 data 字段获取跟进人 const data = Contact.get("data"); const userid = data.follow_user[0].userid; // 调用企微API添加标签 await this.wecorp.externalContact.markTag({ userid: userid, external_userid: externalUserId, add_tag: tagIds }); console.log("标签已添加到联系人:", Contact.get("name")); } } ``` ### 场景4:查看客户跟进记录 ```typescript async showFollowHistory() { // ⭐ 使用统一方法 const { Contact } = await this.wework.getCurrentChatObject(); if (Contact) { // ⭐ 从 data 字段获取跟进人列表 const data = Contact.get("data"); const followUsers = data.follow_user || []; followUsers.forEach(follow => { console.log("跟进人:", follow.userid); console.log("备注:", follow.remark); console.log("描述:", follow.description); console.log("添加时间:", new Date(follow.createtime * 1000)); }); } } ``` ## 数据同步最佳实践 ### 1. 按需同步 ```typescript // ✅ 推荐:仅在需要时同步 async loadGroupChat() { const currentChat = await this.wework.getCurrentChat(); if (currentChat?.group) { // syncGroupChat 会自动判断是否需要保存 const groupChat = await this.wework.syncGroupChat(currentChat.group); return groupChat; } } // ❌ 不推荐:频繁无意义的同步 setInterval(async () => { const currentChat = await this.wework.getCurrentChat(); await this.wework.syncGroupChat(currentChat.group); // 浪费资源 }, 1000); ``` ### 2. 错误处理 ```typescript async loadContact() { try { const currentChat = await this.wework.getCurrentChat(); if (currentChat?.contact) { const contactInfo = await this.wecorp.externalContact.get(currentChat.id); const contact = await this.wework.syncContact(contactInfo.external_contact); return contact; } else { console.warn("当前不在联系人会话中"); return null; } } catch (error) { console.error("加载联系人失败:", error); // 友好提示 if (error.code === 84061) { alert("无权限访问该联系人信息"); } else { alert("加载失败,请重试"); } return null; } } ``` ### 3. 缓存策略 ```typescript export class MyComponent { private cachedGroupChat: FmodeObject | null = null; private cacheTime: number = 0; private CACHE_DURATION = 5 * 60 * 1000; // 5分钟缓存 async getGroupChat(): Promise { const now = Date.now(); // 使用缓存 if (this.cachedGroupChat && (now - this.cacheTime < this.CACHE_DURATION)) { return this.cachedGroupChat; } // 重新加载 const currentChat = await this.wework.getCurrentChat(); this.cachedGroupChat = await this.wework.syncGroupChat(currentChat.group); this.cacheTime = now; return this.cachedGroupChat; } } ``` ## 权限说明 ### 需要的企微权限 1. **获取客户详情** - `externalcontact:get` 2. **获取客户群详情** - `externalcontact_groupchat:get` 3. **发送应用消息** - `appchat:send` 4. **企业客户标签管理** - `externalcontact_tag:manage` ### 权限检查 ```typescript async checkPermissions() { try { // 尝试获取当前会话 const currentChat = await this.wework.getCurrentChat(); if (!currentChat) { console.error("无法获取会话信息,可能缺少权限"); return false; } return true; } catch (error) { console.error("权限检查失败:", error); return false; } } ``` ## 调试技巧 ### 1. 使用 wxdebug 进行调试 `wxdebug` 是专门为企微开发设计的调试工具,会在控制台输出并弹窗显示调试信息。 ```typescript import { wxdebug } from 'fmode-ng/social'; // 调试单个值 const currentChat = await this.wework.getCurrentChat(); wxdebug('当前会话信息', currentChat); // 调试多个值 wxdebug('步骤1', '初始化完成', { cid: this.cid }); // 调试 Parse Object const groupChat = await this.wxwork.syncGroupChat(currentChat.group); wxdebug('群聊同步完成', groupChat.toJSON()); ``` **推荐调试流程**(参考 page-chat-context): ```typescript async loadData() { this.wxwork = new WxworkSDK({ cid: this.cid, appId: this.appId }); wxdebug('1. SDK初始化完成', { cid: this.cid }); try { this.currentChat = await this.wxwork.getCurrentChat(); wxdebug('2. getCurrentChat返回', this.currentChat); } catch (err) { wxdebug('2. getCurrentChat失败', err); } if (this.currentChat?.type === "chatId" && this.currentChat?.group) { wxdebug('3. 检测到群聊场景', this.currentChat.group); this.groupChat = await this.wxwork.syncGroupChat(this.currentChat.group); wxdebug('4. 群聊同步完成', this.groupChat?.toJSON()); } } ``` ### 2. 查看当前会话信息 ```typescript const currentChat = await this.wework.getCurrentChat(); console.log("会话类型:", currentChat.type); console.log("会话ID:", currentChat.id); console.log("详细信息:", currentChat); ``` ### 3. 查看同步后的数据 ```typescript const groupChat = await this.wxwork.syncGroupChat(currentChat.group); console.log("GroupChat Parse Object:", groupChat.toJSON()); ``` ### 4. 模拟不同入口场景 在开发环境可以通过路由参数模拟: ``` # 群聊场景 /demo/:cid/group/:gid/message # 联系人场景 /crm/:cid/contact/:contactId/detail # 聊天上下文演示 /chat/:cid/context ``` ## 注意事项 1. **getCurrentChat() 依赖企微环境** - 必须在企微客户端内使用 - 需要先调用 `registerCorpWithSuite()` 注册 JSAPI 2. **syncGroupChat() 会生成入群方式** - 首次同步会调用企微API生成入群链接和二维码 - 可能需要一定时间,建议显示加载状态 3. **syncContact() 包含跟进人信息** - `follow_user` 数组可能为空或包含多个跟进人 - 跟进人信息包含备注、标签等敏感数据 4. **数据同步是增量的** - `syncGroupChat` 和 `syncContact` 只在数据变化时保存 - 避免频繁调用,建议根据业务需要同步 ## 总结 通过 `getCurrentChat()`、`syncGroupChat()` 和 `syncContact()` 三个核心方法,可以轻松实现企微工具栏页面的开发: ✅ **一行获取上下文** - `await this.wework.getCurrentChat()` ✅ **自动同步数据** - `syncGroupChat()` / `syncContact()` ✅ **统一数据格式** - Parse Server 标准化存储 ✅ **支持离线查询** - 数据持久化到 Parse 开发企微工具栏功能时,只需关注业务逻辑,数据同步由 SDK 自动处理!