2025-11-28 13:56:51 +08:00
|
|
|
|
// 当popup页面的DOM内容完全加载后执行
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
|
|
|
|
// 获取页面中的按钮元素
|
2025-11-28 16:35:30 +08:00
|
|
|
|
// const getStudentsBtn = document.getElementById('get-students-btn');
|
2025-11-28 13:56:51 +08:00
|
|
|
|
const getBlacklistBtn = document.getElementById('get-blacklist-btn');
|
|
|
|
|
|
const dataDisplay = document.getElementById('data-display');
|
|
|
|
|
|
|
|
|
|
|
|
// 全局变量存储企业信息
|
|
|
|
|
|
let enterpriseInfo = {
|
|
|
|
|
|
corpId: null,
|
|
|
|
|
|
corpName: null
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取企业信息
|
|
|
|
|
|
* @param {number} tabId - 标签页ID
|
|
|
|
|
|
* @returns {Object} 企业信息 {corpId, corpName}
|
|
|
|
|
|
*/
|
|
|
|
|
|
async function getEnterpriseInfo(tabId) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const enterpriseResult = await chrome.scripting.executeScript({
|
|
|
|
|
|
target: {tabId: tabId},
|
|
|
|
|
|
func: () => {
|
|
|
|
|
|
return fetch('https://work.weixin.qq.com/wework_admin/profile/quotaupdate/log?lang=zh_CN&f=json', {
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
credentials: 'include'
|
|
|
|
|
|
}).then(r => r.json());
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 提取企业信息
|
|
|
|
|
|
const enterpriseData = enterpriseResult[0].result;
|
|
|
|
|
|
if (enterpriseData && enterpriseData.data && enterpriseData.data.basecertinfo) {
|
|
|
|
|
|
const info = {
|
|
|
|
|
|
corpId: enterpriseData.data.basecertinfo.appid,
|
2025-11-28 16:35:30 +08:00
|
|
|
|
corpName: enterpriseData.data.basecertinfo.nickname
|
2025-11-28 13:56:51 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
console.log('企业信息获取成功:', info);
|
|
|
|
|
|
return info;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
throw new Error('无法获取企业信息:响应数据格式异常');
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取企业信息失败:', error);
|
|
|
|
|
|
throw new Error(`获取企业信息失败: ${error.message}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-28 16:35:30 +08:00
|
|
|
|
// // 获取学员列表按钮的点击事件监听器
|
|
|
|
|
|
// getStudentsBtn.addEventListener('click', async () => {
|
|
|
|
|
|
// // 获取当前激活的标签页
|
|
|
|
|
|
// const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
|
|
|
|
|
|
//
|
|
|
|
|
|
// try {
|
|
|
|
|
|
// // 第一步:获取企业信息
|
|
|
|
|
|
// dataDisplay.textContent = '正在获取企业信息...';
|
|
|
|
|
|
// enterpriseInfo = await getEnterpriseInfo(tab.id);
|
|
|
|
|
|
//
|
|
|
|
|
|
// // 第二步:获取所有学员数据
|
|
|
|
|
|
// dataDisplay.textContent = '正在获取学员数据...';
|
|
|
|
|
|
// const allStudentsData = await getAllStudentsData(tab.id);
|
|
|
|
|
|
//
|
|
|
|
|
|
// // 第三步:发送数据到指定接口
|
|
|
|
|
|
// dataDisplay.textContent = '正在发送数据...';
|
|
|
|
|
|
// await sendStudentsData(allStudentsData, enterpriseInfo);
|
|
|
|
|
|
//
|
|
|
|
|
|
// // 完成
|
|
|
|
|
|
// dataDisplay.textContent = `✅ 学员数据处理完成!\n\n企业信息:\nAppID: ${enterpriseInfo.corpId}\n企业名称: ${enterpriseInfo.corpName}\n\n学员数量: ${allStudentsData.length}\n\n数据已成功发送到服务器。`;
|
|
|
|
|
|
//
|
|
|
|
|
|
// } catch (error) {
|
|
|
|
|
|
// console.error('处理失败:', error);
|
|
|
|
|
|
// dataDisplay.textContent = `❌ 处理失败: ${error.message}`;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// });
|
2025-11-28 13:56:51 +08:00
|
|
|
|
|
|
|
|
|
|
// 获取黑名单按钮的点击事件监听器
|
|
|
|
|
|
getBlacklistBtn.addEventListener('click', async () => {
|
|
|
|
|
|
// 获取当前激活的标签页
|
|
|
|
|
|
const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 第一步:获取企业信息
|
|
|
|
|
|
dataDisplay.textContent = '正在获取企业信息...';
|
|
|
|
|
|
enterpriseInfo = await getEnterpriseInfo(tab.id);
|
|
|
|
|
|
|
|
|
|
|
|
// 第二步:获取所有黑名单数据
|
|
|
|
|
|
dataDisplay.textContent = '正在获取黑名单数据...';
|
|
|
|
|
|
const allBlacklistData = await getAllBlacklistData(tab.id);
|
|
|
|
|
|
|
|
|
|
|
|
// 第三步:发送数据到指定接口
|
|
|
|
|
|
dataDisplay.textContent = '正在发送数据...';
|
|
|
|
|
|
await sendBlacklistData(allBlacklistData, enterpriseInfo);
|
|
|
|
|
|
|
|
|
|
|
|
// 完成
|
|
|
|
|
|
dataDisplay.textContent = `✅ 黑名单数据处理完成!\n\n企业信息:\nAppID: ${enterpriseInfo.corpId}\n企业名称: ${enterpriseInfo.corpName}\n\n黑名单数量: ${allBlacklistData.length}\n\n数据已成功发送到服务器。`;
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('处理失败:', error);
|
|
|
|
|
|
dataDisplay.textContent = `❌ 处理失败: ${error.message}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取所有学员数据(处理分页)
|
|
|
|
|
|
* @param {number} tabId - 标签页ID
|
|
|
|
|
|
* @returns {Array} 所有学员数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
async function getAllStudentsData(tabId) {
|
|
|
|
|
|
let allStudents = [];
|
|
|
|
|
|
let lastPageMaxId = '';
|
|
|
|
|
|
let hasMore = true;
|
|
|
|
|
|
let pageCount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
while (hasMore) {
|
|
|
|
|
|
pageCount++;
|
|
|
|
|
|
dataDisplay.textContent = `正在获取学员数据... 第${pageCount}页,已获取${allStudents.length}条`;
|
|
|
|
|
|
|
|
|
|
|
|
// 构建URL编码的请求参数(application/x-www-form-urlencoded)
|
|
|
|
|
|
const params = new URLSearchParams();
|
|
|
|
|
|
|
|
|
|
|
|
params.append('page', pageCount.toString());
|
|
|
|
|
|
params.append('time_since', '1744560000');
|
|
|
|
|
|
params.append('time_before', '1744991999');
|
|
|
|
|
|
params.append('last_page_max_id', lastPageMaxId);
|
|
|
|
|
|
params.append('perpage', '10000'); // 每页100条,可根据实际情况调整
|
|
|
|
|
|
|
|
|
|
|
|
const result = await chrome.scripting.executeScript({
|
|
|
|
|
|
target: {tabId: tabId},
|
|
|
|
|
|
func: (formDataStr) => {
|
|
|
|
|
|
return fetch('https://work.weixin.qq.com/wework_admin/customer/list?lang=zh_CN&f=json', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
headers: {
|
|
|
|
|
|
'Content-Type': 'application/x-www-form-urlencoded', // 关键:设置正确的Content-Type
|
|
|
|
|
|
},
|
|
|
|
|
|
body: formDataStr,
|
|
|
|
|
|
credentials: 'include'
|
|
|
|
|
|
}).then(r => r.json());
|
|
|
|
|
|
},
|
|
|
|
|
|
args: [params.toString()]
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const data = result[0].result;
|
|
|
|
|
|
|
|
|
|
|
|
if (data && data.data) {
|
|
|
|
|
|
// 更新数据解析逻辑:从 data.data.detail_list.items 获取学员数据
|
|
|
|
|
|
if (data.data.detail_list && data.data.detail_list.items && data.data.detail_list.items.length > 0) {
|
|
|
|
|
|
allStudents = allStudents.concat(data.data.detail_list.items);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新分页参数:使用 has_more 判断是否还有更多数据
|
|
|
|
|
|
hasMore = data.data.has_more || false;
|
|
|
|
|
|
lastPageMaxId = data.data.max_id || '';
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`第${pageCount}页学员获取完成,本页${data.data.detail_list?.items?.length || 0}条,总计${allStudents.length}条,has_more: ${hasMore}`);
|
|
|
|
|
|
|
|
|
|
|
|
// 避免请求过快,添加小延迟
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
throw new Error('获取学员数据失败:响应数据格式异常');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log('学员数据获取完成,总计:', allStudents.length, '条');
|
|
|
|
|
|
return allStudents;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取所有黑名单数据(处理分页)
|
|
|
|
|
|
* @param {number} tabId - 标签页ID
|
|
|
|
|
|
* @returns {Array} 所有黑名单数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
async function getAllBlacklistData(tabId) {
|
|
|
|
|
|
let allBlockedCustomers = [];
|
|
|
|
|
|
let lastPageMaxId = '';
|
2025-11-28 16:35:30 +08:00
|
|
|
|
let createTime = '';
|
2025-11-28 13:56:51 +08:00
|
|
|
|
let isEnd = false;
|
|
|
|
|
|
let pageCount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
while (!isEnd) {
|
|
|
|
|
|
pageCount++;
|
|
|
|
|
|
dataDisplay.textContent = `正在获取黑名单数据... 第${pageCount}页,已获取${allBlockedCustomers.length}条`;
|
|
|
|
|
|
|
|
|
|
|
|
// 构建请求URL
|
2025-11-28 16:35:30 +08:00
|
|
|
|
const url = `https://work.weixin.qq.com/wework_admin/groupchat/blockedCustomers?lang=zh_CN&f=json&pageSize=15000&last_page_max_id=${lastPageMaxId}&create_time=${createTime}`;
|
2025-11-28 13:56:51 +08:00
|
|
|
|
|
|
|
|
|
|
const result = await chrome.scripting.executeScript({
|
|
|
|
|
|
target: {tabId: tabId},
|
|
|
|
|
|
func: (requestUrl) => {
|
|
|
|
|
|
return fetch(requestUrl, {
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
credentials: 'include'
|
|
|
|
|
|
}).then(r => r.json());
|
|
|
|
|
|
},
|
|
|
|
|
|
args: [url]
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const data = result[0].result;
|
|
|
|
|
|
|
|
|
|
|
|
if (data && data.data) {
|
|
|
|
|
|
// 添加当前页的黑名单数据到总数组
|
|
|
|
|
|
if (data.data.blockedCustomers && data.data.blockedCustomers.length > 0) {
|
|
|
|
|
|
allBlockedCustomers = allBlockedCustomers.concat(data.data.blockedCustomers);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新分页参数
|
|
|
|
|
|
isEnd = data.data.is_end;
|
|
|
|
|
|
lastPageMaxId = data.data.last_page_max_id || '';
|
2025-11-28 16:35:30 +08:00
|
|
|
|
createTime = data.data.create_time || '';
|
2025-11-28 13:56:51 +08:00
|
|
|
|
|
|
|
|
|
|
console.log(`第${pageCount}页黑名单获取完成,本页${data.data.blockedCustomers?.length || 0}条,总计${allBlockedCustomers.length}条,is_end: ${isEnd}`);
|
|
|
|
|
|
|
|
|
|
|
|
// 避免请求过快,添加小延迟
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
throw new Error('获取黑名单数据失败:响应数据格式异常');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log('黑名单数据获取完成,总计:', allBlockedCustomers.length, '条');
|
|
|
|
|
|
return allBlockedCustomers;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 发送学员数据到指定接口
|
|
|
|
|
|
* @param {Array} studentsData - 学员数据
|
|
|
|
|
|
* @param {Object} enterpriseInfo - 企业信息
|
|
|
|
|
|
*/
|
|
|
|
|
|
async function sendStudentsData(studentsData, enterpriseInfo) {
|
|
|
|
|
|
// 构建要发送的数据
|
|
|
|
|
|
const payload = {
|
|
|
|
|
|
enterpriseInfo: enterpriseInfo,
|
|
|
|
|
|
studentsData: studentsData,
|
|
|
|
|
|
totalCount: studentsData.length,
|
|
|
|
|
|
fetchTime: new Date().toISOString()
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
console.log('准备发送学员数据:', {
|
|
|
|
|
|
enterprise: enterpriseInfo,
|
|
|
|
|
|
count: studentsData.length,
|
|
|
|
|
|
sample: studentsData.slice(0, 2) // 只显示前2条作为示例
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// // TODO: 替换为您的实际接口地址
|
|
|
|
|
|
// const apiEndpoint = 'http://192.168.0.133:7788/wework/students/import';
|
|
|
|
|
|
//
|
|
|
|
|
|
// try {
|
|
|
|
|
|
// const response = await fetch(apiEndpoint, {
|
|
|
|
|
|
// method: 'POST',
|
|
|
|
|
|
// headers: {
|
|
|
|
|
|
// 'Content-Type': 'application/json',
|
|
|
|
|
|
// },
|
|
|
|
|
|
// body: JSON.stringify(payload)
|
|
|
|
|
|
// });
|
|
|
|
|
|
//
|
|
|
|
|
|
// if (!response.ok) {
|
|
|
|
|
|
// throw new Error(`服务器响应错误: ${response.status} ${response.statusText}`);
|
|
|
|
|
|
// }
|
|
|
|
|
|
//
|
|
|
|
|
|
// const result = await response.json();
|
|
|
|
|
|
// console.log('学员数据发送成功:', result);
|
|
|
|
|
|
//
|
|
|
|
|
|
// } catch (error) {
|
|
|
|
|
|
// console.error('发送学员数据失败:', error);
|
|
|
|
|
|
// throw new Error(`发送学员数据失败: ${error.message}`);
|
|
|
|
|
|
// }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 发送黑名单数据到指定接口
|
|
|
|
|
|
* @param {Array} blacklistData - 黑名单数据
|
|
|
|
|
|
* @param {Object} enterpriseInfo - 企业信息
|
|
|
|
|
|
*/
|
|
|
|
|
|
async function sendBlacklistData(blacklistData, enterpriseInfo) {
|
|
|
|
|
|
// 构建要发送的数据
|
|
|
|
|
|
const payload = {
|
|
|
|
|
|
enterpriseInfo: enterpriseInfo,
|
|
|
|
|
|
blacklistData: blacklistData,
|
|
|
|
|
|
totalCount: blacklistData.length,
|
|
|
|
|
|
fetchTime: new Date().toISOString()
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
console.log('准备发送黑名单数据:', {
|
|
|
|
|
|
enterprise: enterpriseInfo,
|
|
|
|
|
|
count: blacklistData.length,
|
|
|
|
|
|
sample: blacklistData.slice(0, 2) // 只显示前2条作为示例
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: 替换为您的实际接口地址
|
2025-11-28 16:35:30 +08:00
|
|
|
|
const apiEndpoint = 'https://scrm.xyzhstackd.com/api/wework/blacklist/import';
|
2025-11-28 13:56:51 +08:00
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const response = await fetch(apiEndpoint, {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
headers: {
|
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
|
},
|
|
|
|
|
|
body: JSON.stringify(payload)
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
|
throw new Error(`服务器响应错误: ${response.status} ${response.statusText}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const result = await response.json();
|
|
|
|
|
|
console.log('黑名单数据发送成功:', result);
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('发送黑名单数据失败:', error);
|
|
|
|
|
|
throw new Error(`发送黑名单数据失败: ${error.message}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|