Files
chat_app/frontend/web/index.html
2025-12-11 03:53:47 +08:00

547 lines
26 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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>