Some checks failed
Deploy / deploy (push) Has been cancelled
Full-stack web application for Telegram management - Frontend: Vue 3 + Vben Admin - Backend: NestJS - Features: User management, group broadcast, statistics 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
197 lines
7.0 KiB
HTML
197 lines
7.0 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>测试TG账号导出功能</title>
|
||
<meta charset="utf-8">
|
||
<style>
|
||
body {
|
||
font-family: Arial, sans-serif;
|
||
padding: 20px;
|
||
max-width: 800px;
|
||
margin: 0 auto;
|
||
}
|
||
.test-section {
|
||
margin: 20px 0;
|
||
padding: 15px;
|
||
border: 1px solid #ddd;
|
||
border-radius: 5px;
|
||
}
|
||
.test-button {
|
||
padding: 10px 20px;
|
||
margin: 5px;
|
||
background: #4CAF50;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 5px;
|
||
cursor: pointer;
|
||
}
|
||
.test-button:hover {
|
||
background: #45a049;
|
||
}
|
||
#console {
|
||
background: #f5f5f5;
|
||
padding: 10px;
|
||
border-radius: 5px;
|
||
max-height: 300px;
|
||
overflow-y: auto;
|
||
font-family: monospace;
|
||
font-size: 12px;
|
||
}
|
||
.log-entry {
|
||
margin: 2px 0;
|
||
}
|
||
.error { color: red; }
|
||
.success { color: green; }
|
||
.info { color: blue; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>TG账号导出功能测试</h1>
|
||
|
||
<div class="test-section">
|
||
<h2>1. API测试</h2>
|
||
<button class="test-button" onclick="testAPI()">测试后端API</button>
|
||
<button class="test-button" onclick="testExportData()">测试导出数据格式</button>
|
||
</div>
|
||
|
||
<div class="test-section">
|
||
<h2>2. Excel导出测试</h2>
|
||
<button class="test-button" onclick="testExcelExport()">测试Excel导出</button>
|
||
<button class="test-button" onclick="testFullExport()">测试完整导出流程</button>
|
||
</div>
|
||
|
||
<div class="test-section">
|
||
<h2>3. 控制台输出</h2>
|
||
<div id="console"></div>
|
||
<button class="test-button" onclick="clearConsole()">清空控制台</button>
|
||
</div>
|
||
|
||
<script>
|
||
// 日志函数
|
||
function log(message, type = 'info') {
|
||
const console = document.getElementById('console');
|
||
const entry = document.createElement('div');
|
||
entry.className = `log-entry ${type}`;
|
||
entry.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
|
||
console.appendChild(entry);
|
||
console.scrollTop = console.scrollHeight;
|
||
}
|
||
|
||
function clearConsole() {
|
||
document.getElementById('console').innerHTML = '';
|
||
}
|
||
|
||
// 测试API
|
||
async function testAPI() {
|
||
log('开始测试后端API...');
|
||
try {
|
||
const response = await fetch('http://localhost:3000/tgAccount/test-all', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
}
|
||
});
|
||
|
||
if (!response.ok) {
|
||
throw new Error(`HTTP error! status: ${response.status}`);
|
||
}
|
||
|
||
const data = await response.json();
|
||
log(`API响应成功! 获取到 ${data.data.length} 条账号数据`, 'success');
|
||
log(`第一条数据: ${JSON.stringify(data.data[0])}`, 'info');
|
||
return data.data;
|
||
} catch (error) {
|
||
log(`API测试失败: ${error.message}`, 'error');
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 测试导出数据格式
|
||
async function testExportData() {
|
||
log('测试导出数据格式...');
|
||
const data = await testAPI();
|
||
if (!data) return;
|
||
|
||
// 模拟前端的数据处理
|
||
const exportData = data.map(item => ({
|
||
phone: item.phone || '',
|
||
password: item.password || '',
|
||
firstname: item.firstname || '',
|
||
lastname: item.lastname || '',
|
||
usageId: item.usageId || '',
|
||
session: item.session || ''
|
||
}));
|
||
|
||
log(`准备导出的数据格式:`, 'info');
|
||
log(JSON.stringify(exportData[0], null, 2), 'info');
|
||
|
||
return exportData;
|
||
}
|
||
|
||
// 测试Excel导出(不使用XLSX库)
|
||
function testExcelExport() {
|
||
log('测试简单CSV导出...');
|
||
|
||
// 创建测试数据
|
||
const testData = [
|
||
{ phone: '12345678901', password: 'test123', firstname: '张', lastname: '三', usageId: 1, session: 'test_session_1' },
|
||
{ phone: '12345678902', password: 'test456', firstname: '李', lastname: '四', usageId: 2, session: 'test_session_2' }
|
||
];
|
||
|
||
// 转换为CSV
|
||
const headers = ['phone', 'password', 'firstname', 'lastname', 'usageId', 'session'];
|
||
const csvContent = [
|
||
headers.join(','),
|
||
...testData.map(row => headers.map(h => row[h] || '').join(','))
|
||
].join('\n');
|
||
|
||
// 下载CSV
|
||
const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' });
|
||
const link = document.createElement('a');
|
||
link.href = URL.createObjectURL(blob);
|
||
link.download = `test_export_${new Date().getTime()}.csv`;
|
||
link.click();
|
||
|
||
log('CSV文件已生成并下载', 'success');
|
||
}
|
||
|
||
// 测试完整导出流程
|
||
async function testFullExport() {
|
||
log('开始完整导出流程测试...');
|
||
|
||
// 1. 获取数据
|
||
const data = await testExportData();
|
||
if (!data || data.length === 0) {
|
||
log('没有数据可导出', 'error');
|
||
return;
|
||
}
|
||
|
||
// 2. 转换为CSV格式
|
||
const headers = ['手机号', '密码', '姓', '名', '用途ID', 'Session'];
|
||
const headerKeys = ['phone', 'password', 'firstname', 'lastname', 'usageId', 'session'];
|
||
|
||
const csvContent = [
|
||
headers.join(','),
|
||
...data.map(row => headerKeys.map(key => {
|
||
const value = row[key] || '';
|
||
// 如果值包含逗号或引号,需要用引号包裹
|
||
if (value.toString().includes(',') || value.toString().includes('"')) {
|
||
return `"${value.toString().replace(/"/g, '""')}"`;
|
||
}
|
||
return value;
|
||
}).join(','))
|
||
].join('\n');
|
||
|
||
// 3. 下载文件
|
||
const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' });
|
||
const link = document.createElement('a');
|
||
link.href = URL.createObjectURL(blob);
|
||
const fileName = `TG账号导出_${new Date().toLocaleString('zh-CN').replace(/[/:]/g, '-')}.csv`;
|
||
link.download = fileName;
|
||
link.click();
|
||
|
||
log(`成功导出 ${data.length} 条数据到文件: ${fileName}`, 'success');
|
||
}
|
||
</script>
|
||
</body>
|
||
</html> |