wxwork-sendchatmessage-jssdk-fix.md 11 KB

企业微信发送消息功能修复 - JSSDK注册失败问题

🚨 问题现象

在交付执行阶段点击"发送消息"按钮后,出现以下错误:

❌ [sendChatMessage] JSSDK注册失败
❌ 可能原因:
  1. 企业微信配置错误(corpId, suiteId, agentId)
  2. ticket获取失败
  3. URL签名错误
  4. 网络问题
  
❌ 发送消息到企业微信失败: Error: JSSDK注册失败

结果:虽然控制台显示消息内容,但无法发送到企业微信群聊。


🔍 问题根源

1. WxworkSDKService未初始化

问题stage-delivery.component.ts中虽然注入了DeliveryMessageService,但DeliveryMessageService依赖的WxworkSDKService没有被初始化。

代码分析

// DeliveryMessageService中调用
await this.wxworkService.sendChatMessage({...});
  ↓
// WxworkSDKService.sendChatMessage()中调用
const isRegister = await this.registerCorpWithSuite(['sendChatMessage']);
  ↓
// registerCorpWithSuite()需要先初始化
if (!this.cid || !this.appId) {
  return false; // ❌ 失败:未初始化
}

2. 缺少SDK初始化调用

问题WxworkSDKServiceinitialize(cid, appId)方法从未被调用。

必需的初始化流程

// 1. 设置cid和appId
this.cid = cid;
this.appId = appId;

// 2. 创建WxworkCorp实例
this.wecorp = new WxworkCorp(cid);

// 3. 注册JSSDK
await this.registerCorpWithSuite();

3. appId配置缺失

问题WxworkSDKServicesuiteMap中没有project应用的配置。

原有配置

private suiteMap: any = {
  'crm': {
    suiteId: 'dk2559ba758f33d8f5'
  }
  // ❌ 缺少project应用配置
};

✅ 修复方案

1. 添加SDK服务导入

文件stage-delivery.component.ts

import { WxworkSDKService } from '../../../services/wxwork-sdk.service'; // 🔥 添加

2. 注入SDK服务

文件stage-delivery.component.ts

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

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(已存在,无需修改)

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初始化流程

// 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调用链

// 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配置

调试日志

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:不在聊天会话中

解决方法

// 在企微管理后台 → 应用管理 → 你的应用 → 接口权限
// 开启"发送消息到聊天中"权限

Q3: 如何发送图文消息?

使用news类型

await wxworkSDKService.sendChatMessage({
  msgtype: 'news',
  news: {
    link: 'https://example.com/page',
    title: '标题',
    desc: '描述',
    imgUrl: 'https://example.com/image.jpg'
  }
});

使用image类型

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

无需修改


🚀 部署验证

构建命令

ng build yss-project --base-href=/dev/yss/

部署命令

.\deploy.ps1

验证清单

  • 在企业微信中打开项目详情
  • 控制台显示"企业微信SDK初始化成功"
  • 点击"发送消息"按钮
  • 选择消息内容
  • 控制台显示"消息发送成功"
  • 企业微信群聊中显示消息

🎓 核心教训

1. 服务依赖必须完整初始化

错误做法

// ❌ 只注入服务,不初始化
constructor(private deliveryMessageService: DeliveryMessageService) {}

正确做法

// ✅ 注入所有依赖服务,并在ngOnInit中初始化
constructor(
  private deliveryMessageService: DeliveryMessageService,
  private wxworkSDKService: WxworkSDKService
) {}

async ngOnInit() {
  await this.wxworkSDKService.initialize(cid, appId);
}

2. 企微JSSDK必须在页面加载时注册

时机很重要

  • 正确:在ngOnInit中初始化SDK
  • 错误:在用户点击按钮时才初始化

3. SDK注册是一次性的

优化机制

// 如果URL未变化,直接复用注册状态
if (this.registerUrl === location.href) {
  return true;
}

好处

  • 避免重复注册
  • 提升响应速度
  • 减少ticket请求

修复完成时间:2025-11-30 13:30
修复人员:开发团队
测试状态:✅ 待部署验证
影响范围:交付执行阶段 - 发送消息功能
优先级:🔥 高(核心功能不可用)
问题类型:SDK未初始化