feat: 添加VIP客户数据验证脚本和搜索调试工具
添加verify_vip_data.php脚本用于验证VIP客户数据完整性 创建vip_search_debug.html调试工具用于测试搜索功能
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
<?php
|
||||
// VIP客户数据验证脚本
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
|
||||
// 数据库连接
|
||||
function connectDatabase() {
|
||||
$servername = "localhost";
|
||||
$username = "root";
|
||||
$password = "";
|
||||
$database = "carwash_booking";
|
||||
|
||||
try {
|
||||
$pdo = new PDO("mysql:host=$servername;dbname=$database;charset=utf8", $username, $password);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
return $pdo;
|
||||
} catch(PDOException $e) {
|
||||
die("数据库连接失败: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$pdo = connectDatabase();
|
||||
|
||||
echo "<!DOCTYPE html>
|
||||
<html lang='zh-CN'>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<title>VIP客户数据验证</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 20px; background: #f5f5f5; }
|
||||
.container { max-width: 1200px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
|
||||
h1, h2 { color: #333; }
|
||||
.table { width: 100%; border-collapse: collapse; margin: 20px 0; }
|
||||
.table th, .table td { border: 1px solid #ddd; padding: 12px; text-align: left; }
|
||||
.table th { background-color: #f2f2f2; font-weight: bold; }
|
||||
.table tr:nth-child(even) { background-color: #f9f9f9; }
|
||||
.success { color: #28a745; font-weight: bold; }
|
||||
.error { color: #dc3545; font-weight: bold; }
|
||||
.warning { color: #ffc107; font-weight: bold; }
|
||||
.info { color: #17a2b8; }
|
||||
.query-box { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 15px; margin: 10px 0; }
|
||||
.count-box { background: #e9ecef; border-radius: 4px; padding: 15px; margin: 10px 0; text-align: center; }
|
||||
.count-number { font-size: 24px; font-weight: bold; color: #007bff; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='container'>
|
||||
<h1>🔍 VIP客户数据验证报告</h1>";
|
||||
|
||||
// 1. 检查VIP客户表是否存在
|
||||
echo "<h2>1. 数据库表检查</h2>";
|
||||
try {
|
||||
$stmt = $pdo->query("SHOW TABLES LIKE 'vip_customers'");
|
||||
$tableExists = $stmt->rowCount() > 0;
|
||||
|
||||
if ($tableExists) {
|
||||
echo "<p class='success'>✅ vip_customers 表存在</p>";
|
||||
|
||||
// 获取表结构
|
||||
$stmt = $pdo->query("DESCRIBE vip_customers");
|
||||
$columns = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
echo "<h3>表结构:</h3>";
|
||||
echo "<table class='table'>";
|
||||
echo "<tr><th>字段名</th><th>类型</th><th>是否为空</th><th>键</th><th>默认值</th><th>额外</th></tr>";
|
||||
foreach ($columns as $column) {
|
||||
echo "<tr>";
|
||||
echo "<td>{$column['Field']}</td>";
|
||||
echo "<td>{$column['Type']}</td>";
|
||||
echo "<td>{$column['Null']}</td>";
|
||||
echo "<td>{$column['Key']}</td>";
|
||||
echo "<td>{$column['Default']}</td>";
|
||||
echo "<td>{$column['Extra']}</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
|
||||
} else {
|
||||
echo "<p class='error'>❌ vip_customers 表不存在</p>";
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo "<p class='error'>❌ 表检查失败: " . $e->getMessage() . "</p>";
|
||||
}
|
||||
|
||||
// 2. VIP客户总数统计
|
||||
echo "<h2>2. VIP客户统计</h2>";
|
||||
try {
|
||||
// 总数
|
||||
$stmt = $pdo->query("SELECT COUNT(*) as total FROM vip_customers");
|
||||
$totalResult = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$totalCount = $totalResult['total'];
|
||||
|
||||
echo "<div class='count-box'>";
|
||||
echo "<p>VIP客户总数</p>";
|
||||
echo "<div class='count-number'>$totalCount</div>";
|
||||
echo "</div>";
|
||||
|
||||
// 活跃状态统计
|
||||
$stmt = $pdo->query("SELECT is_active, COUNT(*) as count FROM vip_customers GROUP BY is_active");
|
||||
$activeStats = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
echo "<h3>按状态统计:</h3>";
|
||||
echo "<table class='table'>";
|
||||
echo "<tr><th>状态</th><th>数量</th><th>说明</th></tr>";
|
||||
foreach ($activeStats as $stat) {
|
||||
$status = $stat['is_active'] ? '活跃' : '非活跃';
|
||||
$class = $stat['is_active'] ? 'success' : 'warning';
|
||||
echo "<tr class='$class'>";
|
||||
echo "<td>$status</td>";
|
||||
echo "<td>{$stat['count']}</td>";
|
||||
echo "<td>" . ($stat['is_active'] ? '可搜索' : '不可搜索') . "</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "<p class='error'>❌ 统计查询失败: " . $e->getMessage() . "</p>";
|
||||
}
|
||||
|
||||
// 3. 活跃VIP客户详细数据
|
||||
echo "<h2>3. 活跃VIP客户详细数据</h2>";
|
||||
try {
|
||||
$stmt = $pdo->query("SELECT * FROM vip_customers WHERE is_active = 1 ORDER BY created_at DESC");
|
||||
$vipCustomers = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (count($vipCustomers) > 0) {
|
||||
echo "<p class='success'>✅ 找到 " . count($vipCustomers) . " 个活跃VIP客户</p>";
|
||||
|
||||
echo "<table class='table'>";
|
||||
echo "<tr>";
|
||||
echo "<th>ID</th>";
|
||||
echo "<th>客户姓名</th>";
|
||||
echo "<th>手机号</th>";
|
||||
echo "<th>邮箱</th>";
|
||||
echo "<th>车型</th>";
|
||||
echo "<th>车牌号</th>";
|
||||
echo "<th>注册时间</th>";
|
||||
echo "</tr>";
|
||||
|
||||
foreach ($vipCustomers as $customer) {
|
||||
echo "<tr>";
|
||||
echo "<td>{$customer['id']}</td>";
|
||||
echo "<td><strong>{$customer['customer_name']}</strong></td>";
|
||||
echo "<td>{$customer['phone']}</td>";
|
||||
echo "<td>{$customer['email']}</td>";
|
||||
echo "<td>{$customer['car_model']}</td>";
|
||||
echo "<td>{$customer['car_number']}</td>";
|
||||
echo "<td>{$customer['created_at']}</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
|
||||
// 显示原始JSON数据
|
||||
echo "<h3>原始JSON数据 (API返回格式):</h3>";
|
||||
echo "<div class='query-box'>";
|
||||
echo "<pre>" . json_encode($vipCustomers, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "</pre>";
|
||||
echo "</div>";
|
||||
|
||||
} else {
|
||||
echo "<p class='warning'>⚠️ 没有找到活跃的VIP客户</p>";
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "<p class='error'>❌ 查询VIP客户失败: " . $e->getMessage() . "</p>";
|
||||
}
|
||||
|
||||
// 4. 搜索功能测试
|
||||
echo "<h2>4. 搜索功能测试</h2>";
|
||||
if (isset($vipCustomers) && count($vipCustomers) > 0) {
|
||||
echo "<p>基于实际数据进行搜索测试:</p>";
|
||||
|
||||
// 测试各种搜索词
|
||||
$testQueries = [
|
||||
'姓名首字' => substr($vipCustomers[0]['customer_name'], 0, 1),
|
||||
'姓名中字' => mb_substr($vipCustomers[0]['customer_name'], 1, 1, 'UTF-8'),
|
||||
'手机前3位' => substr($vipCustomers[0]['phone'], 0, 3),
|
||||
'手机后4位' => substr($vipCustomers[0]['phone'], -4),
|
||||
'姓氏' => '张',
|
||||
'号段' => '139'
|
||||
];
|
||||
|
||||
foreach ($testQueries as $description => $query) {
|
||||
echo "<div class='query-box'>";
|
||||
echo "<strong>测试: $description (搜索词: '$query')</strong><br>";
|
||||
|
||||
$results = [];
|
||||
foreach ($vipCustomers as $customer) {
|
||||
$nameMatch = mb_stripos($customer['customer_name'], $query, 0, 'UTF-8') !== false;
|
||||
$phoneMatch = stripos($customer['phone'], $query) !== false;
|
||||
|
||||
if ($nameMatch || $phoneMatch) {
|
||||
$results[] = $customer['customer_name'] . ' (' . $customer['phone'] . ')';
|
||||
}
|
||||
}
|
||||
|
||||
if (count($results) > 0) {
|
||||
echo "<span class='success'>✅ 找到 " . count($results) . " 个结果:</span><br>";
|
||||
foreach ($results as $result) {
|
||||
echo "• $result<br>";
|
||||
}
|
||||
} else {
|
||||
echo "<span class='warning'>⚠️ 未找到匹配结果</span>";
|
||||
}
|
||||
echo "</div>";
|
||||
}
|
||||
|
||||
} else {
|
||||
echo "<p class='warning'>⚠️ 没有VIP客户数据可供测试</p>";
|
||||
}
|
||||
|
||||
// 5. API端点测试
|
||||
echo "<h2>5. API端点测试</h2>";
|
||||
echo "<p>测试 get_vip_customers.php 接口:</p>";
|
||||
|
||||
if (file_exists('get_vip_customers.php')) {
|
||||
echo "<p class='success'>✅ get_vip_customers.php 文件存在</p>";
|
||||
|
||||
// 模拟API调用
|
||||
ob_start();
|
||||
include 'get_vip_customers.php';
|
||||
$apiOutput = ob_get_clean();
|
||||
|
||||
echo "<div class='query-box'>";
|
||||
echo "<strong>API输出:</strong><br>";
|
||||
echo "<pre>" . htmlspecialchars($apiOutput) . "</pre>";
|
||||
echo "</div>";
|
||||
|
||||
// 尝试解析JSON
|
||||
try {
|
||||
$apiData = json_decode($apiOutput, true);
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
echo "<p class='success'>✅ API返回有效JSON数据</p>";
|
||||
echo "<p>数据记录数: " . (is_array($apiData) ? count($apiData) : 'N/A') . "</p>";
|
||||
} else {
|
||||
echo "<p class='error'>❌ API返回无效JSON: " . json_last_error_msg() . "</p>";
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo "<p class='error'>❌ JSON解析失败: " . $e->getMessage() . "</p>";
|
||||
}
|
||||
|
||||
} else {
|
||||
echo "<p class='error'>❌ get_vip_customers.php 文件不存在</p>";
|
||||
}
|
||||
|
||||
echo "</div></body></html>";
|
||||
?>
|
||||
@@ -0,0 +1,490 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>VIP客户搜索调试工具</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Consolas', monospace;
|
||||
margin: 20px;
|
||||
background: #1e1e1e;
|
||||
color: #d4d4d4;
|
||||
}
|
||||
|
||||
.debug-panel {
|
||||
background: #2d2d30;
|
||||
border: 1px solid #3e3e42;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.debug-title {
|
||||
color: #4ec9b0;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 15px;
|
||||
border-bottom: 2px solid #4ec9b0;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.test-button {
|
||||
background: #0078d4;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
margin: 5px;
|
||||
font-family: 'Consolas', monospace;
|
||||
}
|
||||
|
||||
.test-button:hover {
|
||||
background: #106ebe;
|
||||
}
|
||||
|
||||
.test-button.success {
|
||||
background: #107c10;
|
||||
}
|
||||
|
||||
.test-button.error {
|
||||
background: #d83b01;
|
||||
}
|
||||
|
||||
.output {
|
||||
background: #1e1e1e;
|
||||
border: 1px solid #3e3e42;
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
margin: 10px 0;
|
||||
font-family: 'Consolas', monospace;
|
||||
white-space: pre-wrap;
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.output.success {
|
||||
border-left: 4px solid #107c10;
|
||||
}
|
||||
|
||||
.output.error {
|
||||
border-left: 4px solid #d83b01;
|
||||
}
|
||||
|
||||
.output.info {
|
||||
border-left: 4px solid #0078d4;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
background: #3c3c3c;
|
||||
border: 1px solid #5a5a5a;
|
||||
color: #d4d4d4;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
width: 300px;
|
||||
margin: 10px 5px;
|
||||
font-family: 'Consolas', monospace;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.status-loading { background: #ff8c00; }
|
||||
.status-success { background: #107c10; }
|
||||
.status-error { background: #d83b01; }
|
||||
.status-warning { background: #ff8c00; }
|
||||
|
||||
.customer-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 10px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.customer-card {
|
||||
background: #252526;
|
||||
border: 1px solid #3e3e42;
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.customer-name {
|
||||
color: #4ec9b0;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.customer-phone {
|
||||
color: #d4d4d4;
|
||||
font-size: 12px;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.customer-car {
|
||||
color: #9cdcfe;
|
||||
font-size: 11px;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.json-viewer {
|
||||
background: #1e1e1e;
|
||||
border: 1px solid #3e3e42;
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
margin: 10px 0;
|
||||
font-family: 'Consolas', monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="debug-panel">
|
||||
<div class="debug-title">🔧 VIP客户搜索调试工具</div>
|
||||
|
||||
<!-- 数据库连接测试 -->
|
||||
<div>
|
||||
<h3><span class="status-indicator status-loading" id="db-status"></span>数据库连接测试</h3>
|
||||
<button class="test-button" onclick="testDatabaseConnection()">测试数据库连接</button>
|
||||
<div id="db-output" class="output" style="display: none;"></div>
|
||||
</div>
|
||||
|
||||
<!-- VIP数据加载测试 -->
|
||||
<div>
|
||||
<h3><span class="status-indicator status-loading" id="data-status"></span>VIP数据加载测试</h3>
|
||||
<button class="test-button" onclick="testVIPDataLoading()">加载VIP客户数据</button>
|
||||
<div id="data-output" class="output" style="display: none;"></div>
|
||||
<div id="customers-display" style="display: none;"></div>
|
||||
</div>
|
||||
|
||||
<!-- 搜索功能测试 -->
|
||||
<div>
|
||||
<h3><span class="status-indicator status-loading" id="search-status"></span>搜索功能测试</h3>
|
||||
<div style="margin: 10px 0;">
|
||||
<input type="text" id="debug-search-input" class="search-input"
|
||||
placeholder="输入搜索关键词" oninput="testSearch()">
|
||||
<button class="test-button" onclick="testSearch()">搜索</button>
|
||||
<button class="test-button" onclick="clearSearch()">清除</button>
|
||||
</div>
|
||||
<div id="search-output" class="output" style="display: none;"></div>
|
||||
<div id="search-results" class="customer-list" style="display: none;"></div>
|
||||
</div>
|
||||
|
||||
<!-- 完整流程测试 -->
|
||||
<div>
|
||||
<h3><span class="status-indicator status-loading" id="flow-status"></span>完整流程测试</h3>
|
||||
<button class="test-button" onclick="testFullFlow()">运行完整流程测试</button>
|
||||
<div id="flow-output" class="output" style="display: none;"></div>
|
||||
</div>
|
||||
|
||||
<!-- 实时监控 -->
|
||||
<div>
|
||||
<h3><span class="status-indicator status-success" id="monitor-status"></span>实时监控</h3>
|
||||
<div id="monitor-output" class="output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let vipCustomers = [];
|
||||
let debugLog = [];
|
||||
|
||||
// 添加调试日志
|
||||
function addLog(message, type = 'info') {
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
const logMessage = `[${timestamp}] ${message}`;
|
||||
|
||||
debugLog.push(logMessage);
|
||||
updateMonitor();
|
||||
|
||||
console.log(logMessage);
|
||||
}
|
||||
|
||||
// 更新监控显示
|
||||
function updateMonitor() {
|
||||
const monitorOutput = document.getElementById('monitor-output');
|
||||
monitorOutput.textContent = debugLog.join('\n');
|
||||
monitorOutput.scrollTop = monitorOutput.scrollHeight;
|
||||
}
|
||||
|
||||
// 设置状态指示器
|
||||
function setStatus(elementId, status) {
|
||||
const indicator = document.getElementById(elementId);
|
||||
indicator.className = `status-indicator status-${status}`;
|
||||
}
|
||||
|
||||
// 显示输出
|
||||
function showOutput(elementId, content, type = 'info') {
|
||||
const output = document.getElementById(elementId);
|
||||
output.className = `output ${type}`;
|
||||
output.textContent = content;
|
||||
output.style.display = 'block';
|
||||
}
|
||||
|
||||
// 测试数据库连接
|
||||
async function testDatabaseConnection() {
|
||||
addLog('开始测试数据库连接...');
|
||||
setStatus('db-status', 'loading');
|
||||
|
||||
try {
|
||||
const response = await fetch('get_vip_customers.php');
|
||||
addLog(`API响应状态: ${response.status} ${response.statusText}`);
|
||||
addLog(`响应头: ${JSON.stringify([...response.headers.entries()])}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const text = await response.text();
|
||||
addLog(`原始响应: ${text.substring(0, 200)}${text.length > 200 ? '...' : ''}`);
|
||||
|
||||
if (text.trim().startsWith('{') || text.trim().startsWith('[')) {
|
||||
try {
|
||||
const data = JSON.parse(text);
|
||||
addLog('JSON解析成功', 'success');
|
||||
setStatus('db-status', 'success');
|
||||
showOutput('db-output', `数据库连接成功!\n状态码: ${response.status}\n数据格式: ${Array.isArray(data) ? '数组' : '对象'}\n记录数: ${Array.isArray(data) ? data.length : 'N/A'}`, 'success');
|
||||
} catch (e) {
|
||||
addLog(`JSON解析失败: ${e.message}`, 'error');
|
||||
setStatus('db-status', 'error');
|
||||
showOutput('db-output', `JSON解析失败: ${e.message}\n原始内容: ${text}`, 'error');
|
||||
}
|
||||
} else {
|
||||
setStatus('db-status', 'error');
|
||||
showOutput('db-output', `响应不是JSON格式:\n${text}`, 'error');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
addLog(`数据库连接失败: ${error.message}`, 'error');
|
||||
setStatus('db-status', 'error');
|
||||
showOutput('db-output', `数据库连接失败:\n${error.message}`, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 测试VIP数据加载
|
||||
async function testVIPDataLoading() {
|
||||
addLog('开始测试VIP数据加载...');
|
||||
setStatus('data-status', 'loading');
|
||||
|
||||
try {
|
||||
const response = await fetch('get_vip_customers.php');
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const text = await response.text();
|
||||
const data = JSON.parse(text);
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
vipCustomers = data;
|
||||
addLog(`成功加载 ${data.length} 条VIP客户数据`, 'success');
|
||||
setStatus('data-status', 'success');
|
||||
showOutput('data-output', `✅ 数据加载成功!\n总计: ${data.length} 条记录\n\n详细数据:\n${JSON.stringify(data, null, 2)}`, 'success');
|
||||
|
||||
// 显示客户列表
|
||||
displayCustomers(data);
|
||||
|
||||
// 测试搜索功能
|
||||
testSearchLogic();
|
||||
|
||||
} else {
|
||||
setStatus('data-status', 'error');
|
||||
showOutput('data-output', `❌ 数据格式错误: ${JSON.stringify(data)}`, 'error');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
addLog(`VIP数据加载失败: ${error.message}`, 'error');
|
||||
setStatus('data-status', 'error');
|
||||
showOutput('data-output', `❌ 数据加载失败: ${error.message}`, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示客户列表
|
||||
function displayCustomers(customers) {
|
||||
const displayDiv = document.getElementById('customers-display');
|
||||
|
||||
if (customers.length === 0) {
|
||||
displayDiv.innerHTML = '<p>没有找到VIP客户数据</p>';
|
||||
displayDiv.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
|
||||
let html = `<h4>VIP客户列表 (${customers.length}条):</h4><div class="customer-list">`;
|
||||
|
||||
customers.forEach((customer, index) => {
|
||||
html += `
|
||||
<div class="customer-card">
|
||||
<div class="customer-name">${index + 1}. ${customer.customer_name}</div>
|
||||
<div class="customer-phone">📞 ${customer.phone}</div>
|
||||
<div class="customer-car">🚗 ${customer.car_model || '未知'} - ${customer.car_number || '未知'}</div>
|
||||
<div class="customer-email">✉️ ${customer.email || '无邮箱'}</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
html += '</div>';
|
||||
displayDiv.innerHTML = html;
|
||||
displayDiv.style.display = 'block';
|
||||
}
|
||||
|
||||
// 测试搜索逻辑
|
||||
function testSearchLogic() {
|
||||
addLog('测试搜索逻辑...');
|
||||
|
||||
if (vipCustomers.length === 0) {
|
||||
addLog('没有VIP客户数据可搜索', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
// 测试不同搜索词
|
||||
const testTerms = [
|
||||
vipCustomers[0].customer_name.substring(0, 1), // 名字第一个字
|
||||
vipCustomers[0].phone.substring(0, 3), // 电话前3位
|
||||
'张', // 中文名测试
|
||||
'139' // 号段测试
|
||||
];
|
||||
|
||||
testTerms.forEach(term => {
|
||||
const results = searchCustomers(vipCustomers, term);
|
||||
addLog(`搜索"${term}": 找到 ${results.length} 个结果`, results.length > 0 ? 'success' : 'warning');
|
||||
});
|
||||
}
|
||||
|
||||
// 搜索客户
|
||||
function searchCustomers(customers, term) {
|
||||
if (!term || term.trim() === '') return [];
|
||||
|
||||
const searchTerm = term.toLowerCase().trim();
|
||||
|
||||
return customers.filter(customer => {
|
||||
const name = (customer.customer_name || '').toLowerCase();
|
||||
const phone = (customer.phone || '');
|
||||
|
||||
return name.includes(searchTerm) || phone.includes(searchTerm);
|
||||
});
|
||||
}
|
||||
|
||||
// 测试搜索
|
||||
function testSearch() {
|
||||
const searchTerm = document.getElementById('debug-search-input').value.trim();
|
||||
|
||||
if (searchTerm === '') {
|
||||
document.getElementById('search-results').style.display = 'none';
|
||||
document.getElementById('search-output').style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
addLog(`开始搜索: "${searchTerm}"`);
|
||||
setStatus('search-status', 'loading');
|
||||
|
||||
const results = searchCustomers(vipCustomers, searchTerm);
|
||||
|
||||
addLog(`搜索"${searchTerm}"完成,找到 ${results.length} 个结果`);
|
||||
setStatus('search-status', results.length > 0 ? 'success' : 'warning');
|
||||
|
||||
if (results.length === 0) {
|
||||
showOutput('search-output', `❌ 搜索"${searchTerm}"未找到匹配结果\n\nVIP客户总数: ${vipCustomers.length}\n\n可用的搜索测试:\n• 姓名: 张、王、李\n• 手机号: 13900139001、13900139002、13900139003`, 'warning');
|
||||
document.getElementById('search-results').style.display = 'none';
|
||||
} else {
|
||||
showOutput('search-output', `✅ 搜索"${searchTerm}"找到 ${results.length} 个结果:\n\n${results.map(r => `• ${r.customer_name} (${r.phone})`).join('\n')}`, 'success');
|
||||
displaySearchResults(results, searchTerm);
|
||||
}
|
||||
}
|
||||
|
||||
// 显示搜索结果
|
||||
function displaySearchResults(results, searchTerm) {
|
||||
const resultsDiv = document.getElementById('search-results');
|
||||
let html = `<h4>搜索结果 (${results.length}条):</h4>`;
|
||||
|
||||
results.forEach((customer, index) => {
|
||||
// 高亮关键词
|
||||
const highlightName = highlightText(customer.customer_name, searchTerm);
|
||||
const highlightPhone = highlightText(customer.phone, searchTerm);
|
||||
|
||||
html += `
|
||||
<div class="customer-card">
|
||||
<div class="customer-name">${highlightName}</div>
|
||||
<div class="customer-phone">📞 ${highlightPhone}</div>
|
||||
<div class="customer-car">🚗 ${customer.car_model || '未知'} - ${customer.car_number || '未知'}</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
resultsDiv.innerHTML = html;
|
||||
resultsDiv.style.display = 'block';
|
||||
}
|
||||
|
||||
// 高亮文本
|
||||
function highlightText(text, searchTerm) {
|
||||
if (!text || !searchTerm) return text || '';
|
||||
|
||||
const regex = new RegExp(`(${searchTerm})`, 'gi');
|
||||
return text.replace(regex, '<mark style="background: yellow; color: black;">$1</mark>');
|
||||
}
|
||||
|
||||
// 清除搜索
|
||||
function clearSearch() {
|
||||
document.getElementById('debug-search-input').value = '';
|
||||
document.getElementById('search-results').style.display = 'none';
|
||||
document.getElementById('search-output').style.display = 'none';
|
||||
addLog('清除搜索结果');
|
||||
}
|
||||
|
||||
// 测试完整流程
|
||||
async function testFullFlow() {
|
||||
addLog('开始完整流程测试...');
|
||||
setStatus('flow-status', 'loading');
|
||||
|
||||
let steps = [];
|
||||
|
||||
try {
|
||||
// 步骤1: 测试数据库连接
|
||||
steps.push('1. 数据库连接测试');
|
||||
const response = await fetch('get_vip_customers.php');
|
||||
if (!response.ok) throw new Error('数据库连接失败');
|
||||
|
||||
// 步骤2: 加载数据
|
||||
steps.push('2. VIP数据加载测试');
|
||||
const data = JSON.parse(await response.text());
|
||||
if (!Array.isArray(data)) throw new Error('数据格式错误');
|
||||
vipCustomers = data;
|
||||
|
||||
// 步骤3: 搜索测试
|
||||
steps.push('3. 搜索功能测试');
|
||||
const testResults = searchCustomers(vipCustomers, '张');
|
||||
if (testResults.length === 0) throw new Error('搜索功能异常');
|
||||
|
||||
steps.push('4. 数据显示测试');
|
||||
|
||||
setStatus('flow-status', 'success');
|
||||
showOutput('flow-output', `✅ 完整流程测试通过!\n\n执行的步骤:\n${steps.join('\n')}\n\nVIP客户总数: ${vipCustomers.length}\n搜索测试结果: ${testResults.length} 个`, 'success');
|
||||
|
||||
addLog('完整流程测试通过', 'success');
|
||||
|
||||
} catch (error) {
|
||||
setStatus('flow-status', 'error');
|
||||
showOutput('flow-output', `❌ 完整流程测试失败!\n\n已执行步骤:\n${steps.join('\n')}\n\n错误信息: ${error.message}`, 'error');
|
||||
addLog(`完整流程测试失败: ${error.message}`, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载完成后自动运行测试
|
||||
window.addEventListener('load', function() {
|
||||
addLog('VIP搜索调试工具加载完成');
|
||||
|
||||
// 3秒后自动开始测试
|
||||
setTimeout(() => {
|
||||
testDatabaseConnection();
|
||||
setTimeout(() => {
|
||||
testVIPDataLoading();
|
||||
}, 2000);
|
||||
}, 3000);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user