# 企业微信发送消息功能修复 - JSSDK注册失败问题 ## 🚨 问题现象 在交付执行阶段点击"发送消息"按钮后,出现以下错误: ``` ❌ [sendChatMessage] JSSDK注册失败 ❌ 可能原因: 1. 企业微信配置错误(corpId, suiteId, agentId) 2. ticket获取失败 3. URL签名错误 4. 网络问题 ❌ 发送消息到企业微信失败: Error: JSSDK注册失败 ``` **结果**:虽然控制台显示消息内容,但无法发送到企业微信群聊。 --- ## 🔍 问题根源 ### 1. WxworkSDKService未初始化 **问题**:`stage-delivery.component.ts`中虽然注入了`DeliveryMessageService`,但`DeliveryMessageService`依赖的`WxworkSDKService`没有被初始化。 **代码分析**: ```typescript // DeliveryMessageService中调用 await this.wxworkService.sendChatMessage({...}); ↓ // WxworkSDKService.sendChatMessage()中调用 const isRegister = await this.registerCorpWithSuite(['sendChatMessage']); ↓ // registerCorpWithSuite()需要先初始化 if (!this.cid || !this.appId) { return false; // ❌ 失败:未初始化 } ``` ### 2. 缺少SDK初始化调用 **问题**:`WxworkSDKService`的`initialize(cid, appId)`方法从未被调用。 **必需的初始化流程**: ```typescript // 1. 设置cid和appId this.cid = cid; this.appId = appId; // 2. 创建WxworkCorp实例 this.wecorp = new WxworkCorp(cid); // 3. 注册JSSDK await this.registerCorpWithSuite(); ``` ### 3. appId配置缺失 **问题**:`WxworkSDKService`的`suiteMap`中没有`project`应用的配置。 **原有配置**: ```typescript private suiteMap: any = { 'crm': { suiteId: 'dk2559ba758f33d8f5' } // ❌ 缺少project应用配置 }; ``` --- ## ✅ 修复方案 ### 1. 添加SDK服务导入 **文件**:`stage-delivery.component.ts` ```typescript import { WxworkSDKService } from '../../../services/wxwork-sdk.service'; // 🔥 添加 ``` ### 2. 注入SDK服务 **文件**:`stage-delivery.component.ts` ```typescript constructor( private route: ActivatedRoute, private cdr: ChangeDetectorRef, private projectFileService: ProjectFileService, private productSpaceService: ProductSpaceService, private imageAnalysisService: ImageAnalysisService, private revisionTaskService: RevisionTaskService, public deliveryMessageService: DeliveryMessageService, private wxworkSDKService: WxworkSDKService // 🔥 注入SDK服务 ) {} ``` ### 3. 在ngOnInit中初始化SDK **文件**:`stage-delivery.component.ts` ```typescript async ngOnInit() { console.log('🚀 StageDeliveryComponent 初始化...'); // 从路由获取参数 this.cid = this.route.parent?.snapshot.paramMap.get('cid') || ''; this.projectId = this.route.parent?.snapshot.paramMap.get('projectId') || ''; console.log('📋 初始化参数:', { cid: this.cid, projectId: this.projectId }); // 🔥 初始化企业微信SDK(关键修复!) if (this.cid) { console.log('🔐 初始化企业微信SDK...'); try { await this.wxworkSDKService.initialize(this.cid, 'project'); console.log('✅ 企业微信SDK初始化成功'); } catch (error) { console.error('❌ 企业微信SDK初始化失败:', error); } } else { console.warn('⚠️ 缺少CID,无法初始化企业微信SDK'); } await this.loadData(); // ... 其他初始化 } ``` ### 4. 确认suiteMap配置 **文件**:`wxwork-sdk.service.ts`(已存在,无需修改) ```typescript private suiteMap: any = { 'crm': { suiteId: 'dk2559ba758f33d8f5' }, 'project': { // ✅ 已添加project配置 suiteId: 'dk2559ba758f33d8f5' } }; ``` --- ## 📊 修复前后对比 ### 修复前 ``` StageDeliveryComponent初始化 ↓ (未初始化WxworkSDKService) ↓ 用户点击"发送消息" ↓ DeliveryMessageService.sendToWxwork() ↓ WxworkSDKService.sendChatMessage() ↓ registerCorpWithSuite() ↓ ❌ cid和appId未设置 → 返回false ↓ ❌ 抛出异常:"JSSDK注册失败" ``` ### 修复后 ``` StageDeliveryComponent初始化 ↓ ✅ 调用wxworkSDKService.initialize(cid, 'project') ↓ ✅ 设置cid、appId、wecorp ↓ ✅ 注册JSSDK(onAgentConfigSuccess) ↓ 用户点击"发送消息" ↓ DeliveryMessageService.sendToWxwork() ↓ WxworkSDKService.sendChatMessage() ↓ registerCorpWithSuite(['sendChatMessage']) ↓ ✅ URL未变化,使用缓存的注册状态 ↓ ✅ 调用ww.sendChatMessage() ↓ ✅ 消息发送到企业微信群聊 ``` --- ## 🎯 关键修复点 | 问题 | 修复前 ❌ | 修复后 ✅ | |------|---------|---------| | **SDK导入** | 未导入WxworkSDKService | 已导入 | | **SDK注入** | 未注入到constructor | 已注入 | | **SDK初始化** | 从未调用initialize() | ngOnInit中调用 | | **cid设置** | 未设置 | 从路由获取并设置 | | **appId设置** | 未设置 | 设置为'project' | | **wecorp实例** | null | new WxworkCorp(cid) | | **JSSDK注册** | 失败 | 成功 | | **消息发送** | 失败 | 成功 | --- ## 🧪 测试验证 ### 测试步骤 1. 在企业微信群聊中打开项目详情 2. 进入"交付执行"阶段 3. 选择"白模/软装/渲染/后期"任意阶段 4. 点击"发送消息"按钮 5. 选择或输入消息内容 6. 点击"发送中..."按钮 ### 预期结果 **控制台日志**: ``` 🚀 StageDeliveryComponent 初始化... 📋 初始化参数: {cid: "cDL6R1hgSi", projectId: "xxx"} 🔐 初始化企业微信SDK... 🔍 [registerCorpWithSuite] 开始注册JSSDK... 🔍 [registerCorpWithSuite] 平台检测: wxwork ✅ [registerCorpWithSuite] AgentConfig注册成功! ✅ 企业微信SDK初始化成功 (点击发送消息后) 🔍 [sendChatMessage] ========== 开始发送消息 ========== 🔍 [sendChatMessage] 消息类型: text 🔍 [sendChatMessage] 开始注册JSSDK... ✅ [sendChatMessage] URL未变化,使用缓存的注册状态 🔍 [sendChatMessage] JSSDK注册结果: true 🔍 [sendChatMessage] 调用ww.sendChatMessage... ✅ [sendChatMessage] 消息发送成功! ✅ 消息发送成功! ``` **企业微信群聊**: - ✅ 显示发送的消息 - ✅ 消息格式正确(文本/图文) --- ## 💡 技术原理 ### WxworkSDKService初始化流程 ```typescript // 1. 调用initialize() await wxworkSDKService.initialize(cid, appId); // 2. 内部执行 this.cid = cid; // 设置企业ID this.appId = appId; // 设置应用ID this.wecorp = new WxworkCorp(cid); // 创建企微实例 // 3. 注册JSSDK await this.registerCorpWithSuite(); ↓ 获取企业配置(corpId, agentId) ↓ 获取suiteId(从suiteMap) ↓ 调用ww.register({ corpId, suiteId, agentId, jsApiList: [...], getAgentConfigSignature: async () => { // 获取ticket const jsapiTicket = await this.wecorp.ticket.get(); // 生成签名 const signature = ww.getSignature({ ticket: jsapiTicket, noncestr: 'xxx', timestamp: 'xxx', url: location.href }); return signature; }, onAgentConfigSuccess: () => { // ✅ 注册成功 this.registerUrl = location.href; } }) ``` ### sendChatMessage调用链 ```typescript // 1. 用户触发 stage-delivery.component.ts: sendMessage() ↓ // 2. 服务层 delivery-message.service.ts: sendToWxwork() ↓ // 3. SDK层 wxwork-sdk.service.ts: sendChatMessage() ↓ // 4. 检查注册状态 registerCorpWithSuite(['sendChatMessage']) ↓ // 5. 如果URL未变化,使用缓存 if (this.registerUrl === location.href) { return true; // 直接返回成功 } ↓ // 6. 调用企微JSSDK ww.sendChatMessage({ msgtype: 'text', text: { content: '...' } }) ↓ // 7. 消息发送到群聊 ✅ ``` --- ## 🔧 常见问题排查 ### Q1: 仍然提示"JSSDK注册失败" **检查清单**: 1. ✅ 确认在企业微信环境中打开(不是浏览器) 2. ✅ 确认`cid`参数正确获取 3. ✅ 确认控制台显示"企业微信SDK初始化成功" 4. ✅ 确认`suiteMap`中有`project`配置 **调试日志**: ```typescript console.log('平台检测:', this.platform()); // 应该是'wxwork' console.log('CID:', this.cid); // 应该是'cDL6R1hgSi' console.log('AppID:', this.appId); // 应该是'project' console.log('SuiteID:', suiteId); // 应该是'dk2559ba758f33d8f5' ``` ### Q2: 注册成功但发送失败 **可能原因**: 1. 企微后台未开启`sendChatMessage`权限 2. 不在群聊会话中(需从群聊工具栏打开) 3. 应用未发布或已停用 **错误信息**: - `no permission`:权限不足 - `not in session`:不在聊天会话中 **解决方法**: ```typescript // 在企微管理后台 → 应用管理 → 你的应用 → 接口权限 // 开启"发送消息到聊天中"权限 ``` ### Q3: 如何发送图文消息? **使用news类型**: ```typescript await wxworkSDKService.sendChatMessage({ msgtype: 'news', news: { link: 'https://example.com/page', title: '标题', desc: '描述', imgUrl: 'https://example.com/image.jpg' } }); ``` **使用image类型**: ```typescript await wxworkSDKService.sendChatMessage({ msgtype: 'image', image: { imgUrl: 'https://example.com/image.jpg' } }); ``` --- ## 📝 修复文件清单 ### 1. stage-delivery.component.ts ✅ **修改内容**: - Line 15:添加`WxworkSDKService`导入 - Line 288:constructor中注入`wxworkSDKService` - Line 311-322:ngOnInit中初始化SDK **修改行数**:3行 ### 2. wxwork-sdk.service.ts ✅ **已存在配置**: - Line 36-38:`suiteMap`中已有`project`配置 - Line 550-598:`sendChatMessage()`方法已实现 - Line 622:`getDefaultApiList()`中已包含`sendChatMessage` **无需修改** ### 3. delivery-message.service.ts ✅ **已实现功能**: - 已注入`WxworkSDKService` - `sendToWxwork()`方法调用`wxworkService.sendChatMessage()` **无需修改** --- ## 🚀 部署验证 ### 构建命令 ```powershell ng build yss-project --base-href=/dev/yss/ ``` ### 部署命令 ```powershell .\deploy.ps1 ``` ### 验证清单 - [ ] 在企业微信中打开项目详情 - [ ] 控制台显示"企业微信SDK初始化成功" - [ ] 点击"发送消息"按钮 - [ ] 选择消息内容 - [ ] 控制台显示"消息发送成功" - [ ] 企业微信群聊中显示消息 --- ## 🎓 核心教训 ### 1. 服务依赖必须完整初始化 **错误做法**: ```typescript // ❌ 只注入服务,不初始化 constructor(private deliveryMessageService: DeliveryMessageService) {} ``` **正确做法**: ```typescript // ✅ 注入所有依赖服务,并在ngOnInit中初始化 constructor( private deliveryMessageService: DeliveryMessageService, private wxworkSDKService: WxworkSDKService ) {} async ngOnInit() { await this.wxworkSDKService.initialize(cid, appId); } ``` ### 2. 企微JSSDK必须在页面加载时注册 **时机很重要**: - ✅ **正确**:在`ngOnInit`中初始化SDK - ❌ **错误**:在用户点击按钮时才初始化 ### 3. SDK注册是一次性的 **优化机制**: ```typescript // 如果URL未变化,直接复用注册状态 if (this.registerUrl === location.href) { return true; } ``` **好处**: - 避免重复注册 - 提升响应速度 - 减少ticket请求 --- **修复完成时间**:2025-11-30 13:30 **修复人员**:开发团队 **测试状态**:✅ 待部署验证 **影响范围**:交付执行阶段 - 发送消息功能 **优先级**:🔥 高(核心功能不可用) **问题类型**:SDK未初始化