添加用户消息记录接口;
This commit is contained in:
546
frontend/web/index.html
Normal file
546
frontend/web/index.html
Normal file
@@ -0,0 +1,546 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>企业微信 JSSDK 测试</title>
|
||||
<!-- 引入企业微信 JSSDK -->
|
||||
<script src="https://wwcdn.weixin.qq.com/node/open/js/wecom-jssdk-2.3.3.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>企业微信 JSSDK 测试页面</h1>
|
||||
<p>此页面用于测试企业微信 JSSDK 是否加载成功。</p>
|
||||
<p>如果 JSSDK 加载成功,将会显示 SDK 版本号。</p>
|
||||
|
||||
<h2>Access Token(自动获取)</h2>
|
||||
<div>
|
||||
<p style="color: #666; font-style: italic;">页面加载时自动获取Access Token...</p>
|
||||
<div id="tokenResult" style="margin-top: 20px; padding: 10px; border: 1px solid #ccc; border-radius: 5px; background-color: #f9f9f9;">
|
||||
<h3>Access Token 结果:</h3>
|
||||
<pre id="tokenData">获取中...</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>JSAPI Ticket(自动获取)</h2>
|
||||
<div>
|
||||
<p style="color: #666; font-style: italic;">页面加载时自动获取JSAPI Ticket...</p>
|
||||
<div id="ticketResult" style="margin-top: 20px; padding: 10px; border: 1px solid #ccc; border-radius: 5px; background-color: #f9f9f9;">
|
||||
<h3>JSAPI Ticket 结果:</h3>
|
||||
<pre id="ticketData">获取中...</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>获取页面场景</h2>
|
||||
<div>
|
||||
<button id="getContextBtn">获取页面场景</button>
|
||||
<div id="contextResult" style="margin-top: 20px; padding: 10px; border: 1px solid #ccc; border-radius: 5px; background-color: #f9f9f9; display: none;">
|
||||
<h3>页面场景结果:</h3>
|
||||
<pre id="contextData"></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>获取当前客户ID</h2>
|
||||
<div>
|
||||
<button id="getCustomerBtn">获取当前客户ID</button>
|
||||
<div id="customerResult" style="margin-top: 20px; padding: 10px; border: 1px solid #ccc; border-radius: 5px; background-color: #f9f9f9; display: none;">
|
||||
<h3>当前客户ID结果:</h3>
|
||||
<pre id="customerData"></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>发送消息到当前会话</h2>
|
||||
<div>
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label for="messageContent" style="display: block; margin-bottom: 5px; font-weight: bold;">消息内容:</label>
|
||||
<textarea id="messageContent" rows="4" style="width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 5px; font-family: monospace;" placeholder="请输入要发送的消息内容...">你好,这是一条测试消息!</textarea>
|
||||
</div>
|
||||
<button id="sendMessageBtn">发送消息到当前会话</button>
|
||||
<div id="messageResult" style="margin-top: 20px; padding: 10px; border: 1px solid #ccc; border-radius: 5px; background-color: #f9f9f9; display: none;">
|
||||
<h3>消息发送结果:</h3>
|
||||
<pre id="messageData"></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 测试代码 -->
|
||||
<script>
|
||||
// 函数定义
|
||||
async function getConfigSignature(url) {
|
||||
// 根据 url 生成企业签名
|
||||
// 生成方法参考 https://developer.work.weixin.qq.com/document/14924
|
||||
// 暂时返回简单实现,主要关注应用签名
|
||||
const timestamp = Math.floor(Date.now() / 1000);
|
||||
const nonceStr = Math.random().toString(36).substring(2, 15);
|
||||
return { timestamp, nonceStr, signature: 'temp_signature' };
|
||||
}
|
||||
|
||||
async function getAgentConfigSignature(url) {
|
||||
// 根据 url 生成应用签名
|
||||
// 注意:企业微信要求url必须是调用JSAPI页面的完整URL,不包含#及其后面部分
|
||||
try {
|
||||
// 清理URL,移除#及其后面的部分
|
||||
const cleanUrl = url.split('#')[0];
|
||||
console.log('生成签名,原始URL:', url, '清理后URL:', cleanUrl);
|
||||
|
||||
// 使用线上地址
|
||||
const apiBaseUrl = 'http://mp.yizhezhe.com';
|
||||
const apiUrl = `${apiBaseUrl}/api/auth/signature`;
|
||||
console.log('调用签名API:', apiUrl);
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
url: cleanUrl,
|
||||
timestamp: Math.floor(Date.now() / 1000),
|
||||
nonceStr: Math.random().toString(36).substring(2, 15)
|
||||
})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
console.log('签名生成成功:', result.data);
|
||||
console.log('签名详情:', {
|
||||
url: cleanUrl,
|
||||
timestamp: result.data.timestamp,
|
||||
nonceStr: result.data.nonceStr,
|
||||
signature: result.data.signature
|
||||
});
|
||||
return result.data;
|
||||
} else {
|
||||
console.error('签名生成失败:', result.message);
|
||||
throw new Error(result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('调用签名API失败:', error);
|
||||
// 返回一个简单的签名用于测试
|
||||
const timestamp = Math.floor(Date.now() / 1000);
|
||||
const nonceStr = Math.random().toString(36).substring(2, 15);
|
||||
return { timestamp, nonceStr, signature: 'error_signature' };
|
||||
}
|
||||
}
|
||||
|
||||
// 自动获取 Access Token 函数
|
||||
async function autoFetchAccessToken() {
|
||||
console.log('开始自动获取 Access Token...');
|
||||
const tokenDataElement = document.getElementById('tokenData');
|
||||
const tokenResultElement = document.getElementById('tokenResult');
|
||||
|
||||
try {
|
||||
// 更新状态
|
||||
tokenDataElement.textContent = '正在获取...';
|
||||
tokenDataElement.style.color = '#666';
|
||||
|
||||
// 获取 access_token 的 API 端点
|
||||
const apiUrl = 'http://mp.yizhezhe.com/api/auth/token';
|
||||
|
||||
console.log('正在调用 API:', apiUrl);
|
||||
|
||||
// 使用 fetch 调用 API
|
||||
const response = await fetch(apiUrl);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP 错误: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
console.log('Access Token 获取成功:', data);
|
||||
|
||||
// 更新页面显示
|
||||
if (data.success === true) {
|
||||
tokenDataElement.textContent = JSON.stringify(data, null, 2);
|
||||
tokenDataElement.style.color = '#333';
|
||||
console.log(`Access Token 获取成功!${data.message}`);
|
||||
console.log('Access Token 数据:', JSON.stringify(data, null, 2));
|
||||
|
||||
// 添加成功样式
|
||||
tokenResultElement.style.borderColor = '#4CAF50';
|
||||
tokenResultElement.style.backgroundColor = '#f8fff8';
|
||||
} else {
|
||||
tokenDataElement.textContent = `获取失败: ${data.message}\n\n返回数据: ${JSON.stringify(data, null, 2)}`;
|
||||
tokenDataElement.style.color = '#d32f2f';
|
||||
console.error(`获取 Access Token 失败: ${data.message}`);
|
||||
|
||||
// 添加错误样式
|
||||
tokenResultElement.style.borderColor = '#f44336';
|
||||
tokenResultElement.style.backgroundColor = '#fff8f8';
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('获取 Access Token 失败:', error);
|
||||
console.error('错误详情:', error.message);
|
||||
|
||||
// 更新页面显示错误
|
||||
tokenDataElement.textContent = `错误: ${error.message}\n\n请检查网络连接或后端服务状态。`;
|
||||
tokenDataElement.style.color = '#d32f2f';
|
||||
|
||||
// 添加错误样式
|
||||
tokenResultElement.style.borderColor = '#f44336';
|
||||
tokenResultElement.style.backgroundColor = '#fff8f8';
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 自动获取 JSAPI Ticket 函数
|
||||
async function autoFetchJsapiTicket() {
|
||||
console.log('开始自动获取 JSAPI Ticket...');
|
||||
const ticketDataElement = document.getElementById('ticketData');
|
||||
const ticketResultElement = document.getElementById('ticketResult');
|
||||
|
||||
try {
|
||||
// 更新状态
|
||||
ticketDataElement.textContent = '正在获取...';
|
||||
ticketDataElement.style.color = '#666';
|
||||
|
||||
// 获取 jsapi_ticket 的 API 端点 - 使用线上地址
|
||||
const apiUrl = 'http://mp.yizhezhe.com/api/auth/ticket';
|
||||
|
||||
console.log('正在调用 API:', apiUrl);
|
||||
|
||||
// 使用 fetch 调用 API
|
||||
const response = await fetch(apiUrl);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP 错误: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
console.log('JSAPI Ticket 获取成功:', data);
|
||||
|
||||
// 更新页面显示
|
||||
if (data.success === true) {
|
||||
ticketDataElement.textContent = JSON.stringify(data, null, 2);
|
||||
ticketDataElement.style.color = '#333';
|
||||
console.log(`JSAPI Ticket 获取成功!${data.message}`);
|
||||
console.log('JSAPI Ticket 数据:', JSON.stringify(data, null, 2));
|
||||
|
||||
// 添加成功样式
|
||||
ticketResultElement.style.borderColor = '#4CAF50';
|
||||
ticketResultElement.style.backgroundColor = '#f8fff8';
|
||||
} else {
|
||||
ticketDataElement.textContent = `获取失败: ${data.message}\n\n返回数据: ${JSON.stringify(data, null, 2)}`;
|
||||
ticketDataElement.style.color = '#d32f2f';
|
||||
console.error(`获取 JSAPI Ticket 失败: ${data.message}`);
|
||||
|
||||
// 添加错误样式
|
||||
ticketResultElement.style.borderColor = '#f44336';
|
||||
ticketResultElement.style.backgroundColor = '#fff8f8';
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('获取 JSAPI Ticket 失败:', error);
|
||||
console.error('错误详情:', error.message);
|
||||
|
||||
// 更新页面显示错误
|
||||
ticketDataElement.textContent = `错误: ${error.message}\n\n请检查网络连接或后端服务状态。`;
|
||||
ticketDataElement.style.color = '#d32f2f';
|
||||
|
||||
// 添加错误样式
|
||||
ticketResultElement.style.borderColor = '#f44336';
|
||||
ticketResultElement.style.backgroundColor = '#fff8f8';
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// DOMContentLoaded 事件处理
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('DOMContentLoaded: 开始初始化页面...');
|
||||
|
||||
// 1. 检查并注册 JSSDK
|
||||
console.log('检查 JSSDK...');
|
||||
if (typeof ww !== 'undefined') {
|
||||
console.log('企业微信 JSSDK 版本:', ww.SDK_VERSION);
|
||||
console.log('JSSDK 对象已加载:', ww);
|
||||
|
||||
// 注册 JSSDK(不等待回调,让 JSSDK 自行处理)
|
||||
console.log('开始注册 JSSDK...');
|
||||
ww.register({
|
||||
corpId: 'ww45bb49a9d651b2bb', // 必填,当前用户企业所属企业ID,从.env文件获取
|
||||
agentId: 1000061, // 必填,当前应用的AgentID,从.env文件获取
|
||||
jsApiList: ['getContext', 'getCurExternalContact', 'sendChatMessage'], // 必填,需要使用的JSAPI列表
|
||||
getConfigSignature, // 必填,根据url生成企业签名的回调函数
|
||||
getAgentConfigSignature // 必填,根据url生成应用签名的回调函数
|
||||
// 不设置 success 和 fail 回调,让按钮直接调用接口
|
||||
});
|
||||
|
||||
console.log('JSSDK 注册调用完成');
|
||||
|
||||
// 2. 自动获取 Access Token 和 JSAPI Ticket
|
||||
console.log('开始自动获取认证信息...');
|
||||
autoFetchAccessToken();
|
||||
autoFetchJsapiTicket();
|
||||
} else {
|
||||
console.error('错误: 企业微信 JSSDK 未加载成功!');
|
||||
console.error('请检查网络或刷新页面。');
|
||||
}
|
||||
|
||||
// 获取页面场景功能
|
||||
const getContextBtn = document.getElementById('getContextBtn');
|
||||
const contextResult = document.getElementById('contextResult');
|
||||
const contextData = document.getElementById('contextData');
|
||||
|
||||
if (getContextBtn) {
|
||||
console.log('找到获取页面场景按钮,绑定点击事件');
|
||||
// 初始时直接启用按钮
|
||||
getContextBtn.disabled = false;
|
||||
getContextBtn.textContent = '获取页面场景';
|
||||
|
||||
getContextBtn.addEventListener('click', function() {
|
||||
console.log('点击获取页面场景按钮');
|
||||
|
||||
// 直接调用,不检查注册状态
|
||||
getContextBtn.disabled = true;
|
||||
getContextBtn.textContent = '获取中...';
|
||||
|
||||
console.log('直接调用 ww.getContext()...');
|
||||
console.log('检查 ww 对象:', typeof ww);
|
||||
console.log('检查 ww.getContext:', typeof ww.getContext);
|
||||
|
||||
if (typeof ww === 'undefined') {
|
||||
alert('错误: ww 对象未定义,JSSDK 未加载成功!');
|
||||
getContextBtn.disabled = false;
|
||||
getContextBtn.textContent = '获取页面场景';
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof ww.getContext !== 'function') {
|
||||
alert('错误: ww.getContext 不是函数,请检查 jsApiList 是否包含 getContext');
|
||||
getContextBtn.disabled = false;
|
||||
getContextBtn.textContent = '获取页面场景';
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用企业微信 JSSDK 的 getContext 方法
|
||||
ww.getContext({
|
||||
success: function(res) {
|
||||
console.log('获取页面场景成功:', res);
|
||||
|
||||
// 显示结果
|
||||
contextData.textContent = JSON.stringify(res, null, 2);
|
||||
contextResult.style.display = 'block';
|
||||
|
||||
// 解析场景信息
|
||||
let sceneInfo = '未知场景';
|
||||
if (res.entry) {
|
||||
sceneInfo = `入口: ${res.entry}`;
|
||||
}
|
||||
if (res.scene) {
|
||||
sceneInfo += `, 场景: ${res.scene}`;
|
||||
}
|
||||
if (res.chatId) {
|
||||
sceneInfo += `, 聊天ID: ${res.chatId}`;
|
||||
}
|
||||
|
||||
alert(`获取页面场景成功!\n${sceneInfo}`);
|
||||
},
|
||||
fail: function(err) {
|
||||
console.error('获取页面场景失败:', err);
|
||||
contextData.textContent = `错误: ${JSON.stringify(err, null, 2)}`;
|
||||
contextResult.style.display = 'block';
|
||||
alert('获取页面场景失败: ' + (err.errMsg || '未知错误'));
|
||||
},
|
||||
complete: function() {
|
||||
console.log('getContext 调用完成');
|
||||
getContextBtn.disabled = false;
|
||||
getContextBtn.textContent = '获取页面场景';
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.error('未找到获取页面场景按钮!');
|
||||
}
|
||||
|
||||
// 获取当前客户ID功能
|
||||
const getCustomerBtn = document.getElementById('getCustomerBtn');
|
||||
const customerResult = document.getElementById('customerResult');
|
||||
const customerData = document.getElementById('customerData');
|
||||
|
||||
if (getCustomerBtn) {
|
||||
console.log('找到获取当前客户ID按钮,绑定点击事件');
|
||||
// 初始时直接启用按钮
|
||||
getCustomerBtn.disabled = false;
|
||||
getCustomerBtn.textContent = '获取当前客户ID';
|
||||
|
||||
getCustomerBtn.addEventListener('click', function() {
|
||||
console.log('点击获取当前客户ID按钮');
|
||||
|
||||
// 直接调用,不检查注册状态
|
||||
getCustomerBtn.disabled = true;
|
||||
getCustomerBtn.textContent = '获取中...';
|
||||
|
||||
console.log('准备调用 ww.getCurExternalContact()...');
|
||||
console.log('检查 ww 对象:', typeof ww);
|
||||
console.log('检查 ww.getCurExternalContact:', typeof ww.getCurExternalContact);
|
||||
|
||||
if (typeof ww === 'undefined') {
|
||||
alert('错误: ww 对象未定义,JSSDK 未加载成功!');
|
||||
getCustomerBtn.disabled = false;
|
||||
getCustomerBtn.textContent = '获取当前客户ID';
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof ww.getCurExternalContact !== 'function') {
|
||||
alert('错误: ww.getCurExternalContact 不是函数,请检查 jsApiList 是否包含 getCurExternalContact');
|
||||
getCustomerBtn.disabled = false;
|
||||
getCustomerBtn.textContent = '获取当前客户ID';
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用企业微信 JSSDK 的 getCurExternalContact 方法
|
||||
ww.getCurExternalContact({
|
||||
success: function(res) {
|
||||
console.log('获取当前客户ID成功:', res);
|
||||
|
||||
// 显示结果
|
||||
customerData.textContent = JSON.stringify(res, null, 2);
|
||||
customerResult.style.display = 'block';
|
||||
|
||||
// 解析客户信息
|
||||
let customerInfo = '未知客户';
|
||||
if (res.externalUserId) {
|
||||
customerInfo = `客户ID: ${res.externalUserId}`;
|
||||
}
|
||||
if (res.nickname) {
|
||||
customerInfo += `, 昵称: ${res.nickname}`;
|
||||
}
|
||||
if (res.avatar) {
|
||||
customerInfo += `, 有头像`;
|
||||
}
|
||||
if (res.corpName) {
|
||||
customerInfo += `, 企业: ${res.corpName}`;
|
||||
}
|
||||
|
||||
alert(`获取当前客户ID成功!\n${customerInfo}`);
|
||||
},
|
||||
fail: function(err) {
|
||||
console.error('获取当前客户ID失败:', err);
|
||||
customerData.textContent = `错误: ${JSON.stringify(err, null, 2)}`;
|
||||
customerResult.style.display = 'block';
|
||||
alert('获取当前客户ID失败: ' + (err.errMsg || '未知错误'));
|
||||
},
|
||||
cancel: function() {
|
||||
console.log('用户取消了获取当前客户ID操作');
|
||||
alert('用户取消了获取当前客户ID操作');
|
||||
getCustomerBtn.disabled = false;
|
||||
getCustomerBtn.textContent = '获取当前客户ID';
|
||||
},
|
||||
complete: function() {
|
||||
console.log('getCurExternalContact 调用完成');
|
||||
getCustomerBtn.disabled = false;
|
||||
getCustomerBtn.textContent = '获取当前客户ID';
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.error('未找到获取当前客户ID按钮!');
|
||||
}
|
||||
|
||||
// 发送消息到当前会话功能
|
||||
const sendMessageBtn = document.getElementById('sendMessageBtn');
|
||||
const messageResult = document.getElementById('messageResult');
|
||||
const messageData = document.getElementById('messageData');
|
||||
const messageContent = document.getElementById('messageContent');
|
||||
|
||||
if (sendMessageBtn) {
|
||||
console.log('找到发送消息按钮,绑定点击事件');
|
||||
// 初始时直接启用按钮
|
||||
sendMessageBtn.disabled = false;
|
||||
sendMessageBtn.textContent = '发送消息到当前会话';
|
||||
|
||||
sendMessageBtn.addEventListener('click', function() {
|
||||
console.log('点击发送消息按钮');
|
||||
|
||||
// 获取消息内容
|
||||
const content = messageContent.value.trim();
|
||||
if (!content) {
|
||||
alert('错误: 消息内容不能为空!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 直接调用,不检查注册状态
|
||||
sendMessageBtn.disabled = true;
|
||||
sendMessageBtn.textContent = '发送中...';
|
||||
|
||||
console.log('准备调用 ww.sendChatMessage()...');
|
||||
console.log('检查 ww 对象:', typeof ww);
|
||||
console.log('检查 ww.sendChatMessage:', typeof ww.sendChatMessage);
|
||||
console.log('消息内容:', content);
|
||||
|
||||
if (typeof ww === 'undefined') {
|
||||
alert('错误: ww 对象未定义,JSSDK 未加载成功!');
|
||||
sendMessageBtn.disabled = false;
|
||||
sendMessageBtn.textContent = '发送消息到当前会话';
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof ww.sendChatMessage !== 'function') {
|
||||
alert('错误: ww.sendChatMessage 不是函数,请检查 jsApiList 是否包含 sendChatMessage');
|
||||
sendMessageBtn.disabled = false;
|
||||
sendMessageBtn.textContent = '发送消息到当前会话';
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用企业微信 JSSDK 的 sendChatMessage 方法
|
||||
ww.sendChatMessage({
|
||||
msgtype: 'text',
|
||||
text: {
|
||||
content: content
|
||||
},
|
||||
success: function(res) {
|
||||
console.log('发送消息成功:', res);
|
||||
|
||||
// 显示结果
|
||||
messageData.textContent = JSON.stringify(res, null, 2);
|
||||
messageResult.style.display = 'block';
|
||||
|
||||
// 解析发送结果
|
||||
let resultInfo = '消息发送成功!';
|
||||
if (res.errCode === 0) {
|
||||
resultInfo = `消息发送成功!\n错误码: ${res.errCode}, 错误信息: ${res.errMsg || '无'}`;
|
||||
} else {
|
||||
resultInfo = `消息发送失败!\n错误码: ${res.errCode}, 错误信息: ${res.errMsg || '未知错误'}`;
|
||||
}
|
||||
|
||||
alert(resultInfo);
|
||||
},
|
||||
fail: function(err) {
|
||||
console.error('发送消息失败:', err);
|
||||
messageData.textContent = `错误: ${JSON.stringify(err, null, 2)}`;
|
||||
messageResult.style.display = 'block';
|
||||
alert('发送消息失败: ' + (err.errMsg || '未知错误'));
|
||||
},
|
||||
cancel: function() {
|
||||
console.log('用户取消了发送消息操作');
|
||||
alert('用户取消了发送消息操作');
|
||||
sendMessageBtn.disabled = false;
|
||||
sendMessageBtn.textContent = '发送消息到当前会话';
|
||||
},
|
||||
complete: function() {
|
||||
console.log('sendChatMessage 调用完成');
|
||||
sendMessageBtn.disabled = false;
|
||||
sendMessageBtn.textContent = '发送消息到当前会话';
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.error('未找到发送消息按钮!');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<footer>
|
||||
<p>企业微信 JSSDK 测试 - 开发环境</p>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user