Initial commit: Telegram Management System
Some checks failed
Deploy / deploy (push) Has been cancelled
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>
This commit is contained in:
291
backend/complete_demo.js
Normal file
291
backend/complete_demo.js
Normal file
@@ -0,0 +1,291 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* 完整演示新姓名管理系统的所有功能
|
||||
*/
|
||||
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
async function completeDemo() {
|
||||
console.log('🎭 完整演示新姓名管理系统功能...\n');
|
||||
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
try {
|
||||
browser = await chromium.launch({
|
||||
headless: false,
|
||||
slowMo: 2000, // 更慢,便于观察
|
||||
devtools: false
|
||||
});
|
||||
|
||||
const context = await browser.newContext({
|
||||
viewport: { width: 1600, height: 1000 }
|
||||
});
|
||||
|
||||
page = await context.newPage();
|
||||
|
||||
// 监听所有API调用
|
||||
page.on('request', request => {
|
||||
const url = request.url();
|
||||
if (url.includes('/nameTemplate/') || url.includes('/firstname/') || url.includes('/lastname/')) {
|
||||
console.log(`🔗 ${request.method()} ${url}`);
|
||||
}
|
||||
});
|
||||
|
||||
page.on('response', response => {
|
||||
const url = response.url();
|
||||
if (url.includes('/nameTemplate/') || url.includes('/firstname/') || url.includes('/lastname/')) {
|
||||
console.log(`📡 ${response.status()} ${url}`);
|
||||
}
|
||||
});
|
||||
|
||||
// ==================== 第1步:登录 ====================
|
||||
console.log('🚀 第1步:登录系统...');
|
||||
await page.goto('http://localhost:8891');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
await page.fill('input[type="text"]', 'admin');
|
||||
await page.fill('input[type="password"]', '111111');
|
||||
await page.click('button:has-text("登录")');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
console.log('✅ 登录成功');
|
||||
await page.screenshot({ path: 'demo_01_login.png', fullPage: true });
|
||||
|
||||
// ==================== 第2步:直接访问姓名管理页面 ====================
|
||||
console.log('\n📍 第2步:直接访问姓名管理页面...');
|
||||
await page.goto('http://localhost:8891/#/nameManage/firstnameList');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(3000); // 等待数据加载
|
||||
|
||||
console.log('✅ 进入姓名管理页面');
|
||||
await page.screenshot({ path: 'demo_02_name_page.png', fullPage: true });
|
||||
|
||||
// ==================== 第3步:展示新API功能 ====================
|
||||
console.log('\n🔧 第3步:演示新开发的API接口...');
|
||||
|
||||
// 调用无需认证的新API
|
||||
console.log('📡 调用 supportedOptions API...');
|
||||
const apiResult1 = await page.evaluate(async () => {
|
||||
const response = await fetch('http://localhost:3000/nameTemplate/supportedOptions');
|
||||
const data = await response.json();
|
||||
return data;
|
||||
});
|
||||
|
||||
console.log('✅ 新API支持的选项:');
|
||||
console.log(` 🌐 平台: ${apiResult1.data.platforms.join(', ')}`);
|
||||
console.log(` 🌍 文化: ${apiResult1.data.cultures.join(', ')}`);
|
||||
console.log(` 👤 性别: ${apiResult1.data.genders.join(', ')}`);
|
||||
console.log(` 📊 数据源: ${apiResult1.data.sources.join(', ')}`);
|
||||
|
||||
console.log('\n📡 调用 generatorStatus API...');
|
||||
const apiResult2 = await page.evaluate(async () => {
|
||||
const response = await fetch('http://localhost:3000/nameTemplate/generatorStatus');
|
||||
const data = await response.json();
|
||||
return data;
|
||||
});
|
||||
|
||||
console.log('✅ 4层级生成器状态:');
|
||||
Object.entries(apiResult2.data).forEach(([name, info]) => {
|
||||
console.log(` ${info.available ? '✅' : '❌'} ${name}: ${info.description} (优先级: ${info.priority})`);
|
||||
});
|
||||
|
||||
// ==================== 第4步:测试现有数据显示 ====================
|
||||
console.log('\n📋 第4步:检查现有姓名数据...');
|
||||
|
||||
const tableInfo = await page.evaluate(() => {
|
||||
const table = document.querySelector('table');
|
||||
if (!table) return { hasTable: false };
|
||||
|
||||
const rows = table.querySelectorAll('tbody tr');
|
||||
const headers = Array.from(table.querySelectorAll('thead th')).map(th => th.textContent?.trim());
|
||||
|
||||
return {
|
||||
hasTable: true,
|
||||
rowCount: rows.length,
|
||||
headers: headers,
|
||||
sampleData: Array.from(rows).slice(0, 3).map(row =>
|
||||
Array.from(row.cells).map(cell => cell.textContent?.trim())
|
||||
)
|
||||
};
|
||||
});
|
||||
|
||||
if (tableInfo.hasTable) {
|
||||
console.log(`✅ 找到数据表格:`);
|
||||
console.log(` 📊 数据行数: ${tableInfo.rowCount}`);
|
||||
console.log(` 📋 表格列: ${tableInfo.headers.join(' | ')}`);
|
||||
|
||||
if (tableInfo.sampleData.length > 0) {
|
||||
console.log(' 📝 样本数据:');
|
||||
tableInfo.sampleData.forEach((row, index) => {
|
||||
console.log(` ${index + 1}. ${row.join(' | ')}`);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.log('❌ 未找到数据表格');
|
||||
}
|
||||
|
||||
// ==================== 第5步:测试添加功能 ====================
|
||||
console.log('\n➕ 第5步:演示添加新姓名功能...');
|
||||
|
||||
const addButton = await page.locator('button:has-text("添加")');
|
||||
if (await addButton.isVisible()) {
|
||||
console.log('✅ 找到添加按钮');
|
||||
await addButton.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('🖱️ 点击添加按钮');
|
||||
await page.screenshot({ path: 'demo_03_add_modal.png', fullPage: true });
|
||||
|
||||
// 检查弹窗内容
|
||||
const modalInfo = await page.evaluate(() => {
|
||||
const modal = document.querySelector('.ivu-modal, .modal, [class*="modal"]');
|
||||
if (!modal) return { hasModal: false };
|
||||
|
||||
const inputs = modal.querySelectorAll('input');
|
||||
const buttons = modal.querySelectorAll('button');
|
||||
|
||||
return {
|
||||
hasModal: true,
|
||||
title: modal.querySelector('.ivu-modal-header, .modal-header')?.textContent?.trim(),
|
||||
inputCount: inputs.length,
|
||||
inputPlaceholders: Array.from(inputs).map(input => input.placeholder || input.type),
|
||||
buttons: Array.from(buttons).map(btn => btn.textContent?.trim())
|
||||
};
|
||||
});
|
||||
|
||||
if (modalInfo.hasModal) {
|
||||
console.log('✅ 添加弹窗打开:');
|
||||
console.log(` 📝 标题: ${modalInfo.title}`);
|
||||
console.log(` 📝 输入框: ${modalInfo.inputPlaceholders.join(', ')}`);
|
||||
console.log(` 🔘 按钮: ${modalInfo.buttons.join(', ')}`);
|
||||
|
||||
// 填写测试数据
|
||||
const nameInput = await page.locator('input[placeholder*="姓"]').first();
|
||||
if (await nameInput.isVisible()) {
|
||||
await nameInput.fill('演示姓氏');
|
||||
console.log('✏️ 填写测试数据: 演示姓氏');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.screenshot({ path: 'demo_04_filled_form.png', fullPage: true });
|
||||
|
||||
// 不实际提交,点击取消
|
||||
const cancelButton = await page.locator('button:has-text("取消")');
|
||||
if (await cancelButton.isVisible()) {
|
||||
await cancelButton.click();
|
||||
console.log('❌ 取消添加(演示完成)');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 第6步:测试搜索功能 ====================
|
||||
console.log('\n🔍 第6步:演示搜索功能...');
|
||||
|
||||
const searchInput = await page.locator('input[placeholder*="姓"]').first();
|
||||
if (await searchInput.isVisible()) {
|
||||
await searchInput.fill('李');
|
||||
console.log('🔍 输入搜索关键词: 李');
|
||||
|
||||
const searchButton = await page.locator('button:has-text("搜索")');
|
||||
if (await searchButton.isVisible()) {
|
||||
await searchButton.click();
|
||||
await page.waitForTimeout(2000);
|
||||
console.log('🔍 执行搜索');
|
||||
|
||||
await page.screenshot({ path: 'demo_05_search.png', fullPage: true });
|
||||
|
||||
// 清空搜索
|
||||
await searchInput.clear();
|
||||
await searchButton.click();
|
||||
await page.waitForTimeout(1000);
|
||||
console.log('🧹 清空搜索');
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 第7步:访问名字管理页面 ====================
|
||||
console.log('\n📍 第7步:切换到名字管理页面...');
|
||||
await page.goto('http://localhost:8891/#/nameManage/lastnameList');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
console.log('✅ 进入名字管理页面');
|
||||
await page.screenshot({ path: 'demo_06_lastname_page.png', fullPage: true });
|
||||
|
||||
// ==================== 第8步:测试新API调用(需要认证) ====================
|
||||
console.log('\n🔐 第8步:尝试调用需要认证的API...');
|
||||
|
||||
// 通过浏览器的网络请求来测试(会自动带上认证信息)
|
||||
const authApiTest = await page.evaluate(async () => {
|
||||
try {
|
||||
// 尝试获取模板列表
|
||||
const response = await fetch('/nameTemplate/list', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
|
||||
return {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
data: response.status === 200 ? await response.json() : null
|
||||
};
|
||||
} catch (error) {
|
||||
return { error: error.message };
|
||||
}
|
||||
});
|
||||
|
||||
if (authApiTest.status === 200) {
|
||||
console.log('✅ 认证API调用成功');
|
||||
console.log(` 📊 返回数据: ${JSON.stringify(authApiTest.data).substring(0, 100)}...`);
|
||||
} else {
|
||||
console.log(`⚠️ 认证API需要token: ${authApiTest.status} ${authApiTest.statusText}`);
|
||||
}
|
||||
|
||||
// ==================== 第9步:最终展示 ====================
|
||||
console.log('\n🎉 第9步:功能展示总结...');
|
||||
|
||||
await page.screenshot({ path: 'demo_07_final.png', fullPage: true });
|
||||
|
||||
console.log('\n🏆 新姓名管理系统演示完成!');
|
||||
console.log('\n📂 生成的演示截图:');
|
||||
console.log(' demo_01_login.png - 系统登录');
|
||||
console.log(' demo_02_name_page.png - 姓氏管理页面');
|
||||
console.log(' demo_03_add_modal.png - 添加功能弹窗');
|
||||
console.log(' demo_04_filled_form.png - 表单填写');
|
||||
console.log(' demo_05_search.png - 搜索功能');
|
||||
console.log(' demo_06_lastname_page.png - 名字管理页面');
|
||||
console.log(' demo_07_final.png - 最终展示');
|
||||
|
||||
console.log('\n✨ 新功能特点总结:');
|
||||
console.log(' 🔧 新API架构: /nameTemplate/* 替代旧的 /firstname/* 和 /lastname/*');
|
||||
console.log(' 🌐 多平台支持: 8个主流通讯平台');
|
||||
console.log(' 🌍 多文化支持: 14种文化和语言');
|
||||
console.log(' 🎯 4层级生成: AI → 规则 → 模板 → 算法');
|
||||
console.log(' 🔐 智能认证: 公共API无需认证,管理API需要认证');
|
||||
console.log(' 📊 前端集成: Vue组件正确调用新API');
|
||||
|
||||
console.log('\n⏰ 浏览器将保持打开15秒供最后观察...');
|
||||
await page.waitForTimeout(15000);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 演示失败:', error.message);
|
||||
if (page) {
|
||||
await page.screenshot({ path: 'demo_error.png', fullPage: true });
|
||||
}
|
||||
} finally {
|
||||
if (browser) {
|
||||
await browser.close();
|
||||
}
|
||||
console.log('🏁 演示结束');
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
completeDemo().catch(console.error);
|
||||
}
|
||||
|
||||
module.exports = completeDemo;
|
||||
Reference in New Issue
Block a user