feat(vip): 增强VIP客户数据加载的健壮性和错误处理
- 添加多URL尝试机制,优先使用绝对路径 - 改进JSON解析错误处理,包括格式修复尝试 - 支持嵌套数据结构解析 - 增加详细的调试日志和状态更新 - 添加测试页面用于诊断VIP数据加载问题
This commit is contained in:
@@ -735,9 +735,30 @@ $packages_json = json_encode(array_map(function($package) {
|
||||
console.log('开始加载VIP客户列表...');
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch('get_vip_customers.php')
|
||||
// 定义多个可能的API路径,优先使用绝对路径
|
||||
const apiUrls = [
|
||||
'/carwashorder/carwash_order/get_vip_customers.php', // 推荐的绝对路径
|
||||
'get_vip_customers.php', // 原始相对路径
|
||||
'./get_vip_customers.php' // 另一种相对路径
|
||||
];
|
||||
|
||||
let currentAttempt = 0;
|
||||
|
||||
function tryNextUrl() {
|
||||
if (currentAttempt >= apiUrls.length) {
|
||||
const errorMsg = '所有URL尝试失败,请检查API路径是否正确';
|
||||
console.error(errorMsg);
|
||||
updateDebugStatus(errorMsg, 'error');
|
||||
reject(new Error(errorMsg));
|
||||
return;
|
||||
}
|
||||
|
||||
const currentUrl = apiUrls[currentAttempt];
|
||||
console.log(`尝试加载VIP数据 (${currentAttempt + 1}/${apiUrls.length}): ${currentUrl}`);
|
||||
|
||||
fetch(currentUrl)
|
||||
.then(response => {
|
||||
console.log('VIP客户API响应状态:', response.status);
|
||||
console.log(`URL ${currentUrl} 响应状态: ${response.status} ${response.statusText}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
@@ -746,7 +767,12 @@ $packages_json = json_encode(array_map(function($package) {
|
||||
return response.text();
|
||||
})
|
||||
.then(text => {
|
||||
console.log('VIP客户API原始响应:', text);
|
||||
console.log(`URL ${currentUrl} 原始响应文本长度: ${text.length} 字符`);
|
||||
|
||||
// 显示部分原始响应以便调试
|
||||
if (text.length > 0) {
|
||||
console.log('原始响应前100字符:', text.substring(0, Math.min(100, text.length)));
|
||||
}
|
||||
|
||||
try {
|
||||
// 先检查是否为空响应
|
||||
@@ -754,27 +780,88 @@ $packages_json = json_encode(array_map(function($package) {
|
||||
throw new Error('API返回空响应');
|
||||
}
|
||||
|
||||
const data = JSON.parse(text);
|
||||
// 检查是否包含HTML标签(可能是错误页面)
|
||||
if (text.includes('<html') || text.includes('<body') || text.includes('</html>')) {
|
||||
throw new Error('响应包含HTML内容而非JSON');
|
||||
}
|
||||
|
||||
// 尝试解析JSON
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(text);
|
||||
} catch (parseError) {
|
||||
// 尝试修复常见的JSON格式问题
|
||||
console.warn('JSON解析失败,尝试修复格式...');
|
||||
|
||||
// 移除可能的BOM字符
|
||||
const cleanText = text.replace(/^\uFEFF/, '');
|
||||
// 移除可能的多余逗号
|
||||
const fixedText = cleanText.replace(/,\s*}/g, '}').replace(/,\s*\]/g, ']');
|
||||
|
||||
if (fixedText !== text) {
|
||||
console.log('使用修复后的文本重新解析');
|
||||
try {
|
||||
data = JSON.parse(fixedText);
|
||||
console.log('修复后解析成功!');
|
||||
} catch (fixError) {
|
||||
// 如果修复失败,继续尝试下一个URL
|
||||
currentAttempt++;
|
||||
tryNextUrl();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// 如果没有修复,继续尝试下一个URL
|
||||
currentAttempt++;
|
||||
tryNextUrl();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否是错误响应
|
||||
if (data.error) {
|
||||
throw new Error(data.message || 'API返回错误');
|
||||
// 如果API返回错误,继续尝试下一个URL
|
||||
currentAttempt++;
|
||||
tryNextUrl();
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('VIP客户数据解析成功:', data);
|
||||
console.log('VIP客户数据解析成功:', typeof data);
|
||||
|
||||
// 确保数据是数组格式
|
||||
// 处理可能的嵌套数据结构
|
||||
let finalData = data;
|
||||
if (!Array.isArray(data)) {
|
||||
throw new Error('API返回数据不是数组格式');
|
||||
console.log('数据不是数组,检查是否有嵌套结构...');
|
||||
if (data && data.customers && Array.isArray(data.customers)) {
|
||||
console.log('发现嵌套的customers数组');
|
||||
finalData = data.customers;
|
||||
} else if (data && data.vip_customers && Array.isArray(data.vip_customers)) {
|
||||
console.log('发现嵌套的vip_customers数组');
|
||||
finalData = data.vip_customers;
|
||||
} else {
|
||||
// 格式不符合预期,继续尝试下一个URL
|
||||
currentAttempt++;
|
||||
tryNextUrl();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
window.allVIPCustomers = data; // 存储所有VIP客户数据
|
||||
updateVIPSelect(data); // 更新下拉列表
|
||||
console.log('最终VIP数据类型检查:', Array.isArray(finalData));
|
||||
console.log('VIP客户数量:', finalData.length);
|
||||
|
||||
console.log('VIP客户列表加载完成,共', data.length, '条记录');
|
||||
// 存储VIP客户数据
|
||||
window.allVIPCustomers = finalData;
|
||||
updateVIPSelect(finalData); // 更新下拉列表
|
||||
|
||||
// 更新调试面板状态和数据预览
|
||||
updateDebugStatus('加载成功,共 ' + data.length + ' 条记录');
|
||||
// 更新调试面板状态
|
||||
updateDebugStatus('加载成功,共 ' + finalData.length + ' 条记录', 'success');
|
||||
|
||||
// 显示前几个VIP客户信息(如果有的话)
|
||||
if (finalData.length > 0) {
|
||||
console.log('前3个VIP客户信息:');
|
||||
finalData.slice(0, 3).forEach((vip, index) => {
|
||||
console.log(`${index + 1}. ${vip.customer_name || '未知'} - ${vip.phone || '未知'}`);
|
||||
});
|
||||
}
|
||||
|
||||
// 在调试面板中显示部分数据预览
|
||||
const historyElem = document.getElementById('debug-search-history');
|
||||
@@ -783,14 +870,14 @@ $packages_json = json_encode(array_map(function($package) {
|
||||
previewEntry.style.cssText = 'border-bottom: 1px solid #eee; padding: 5px 0; color: #444;';
|
||||
previewEntry.innerHTML = `
|
||||
<div style="font-weight: bold;">📋 VIP数据预览:</div>
|
||||
<div>加载了 ${data.length} 个VIP客户</div>
|
||||
<div>加载了 ${finalData.length} 个VIP客户</div>
|
||||
`;
|
||||
|
||||
// 显示前3个VIP客户作为预览
|
||||
if (data.length > 0) {
|
||||
if (finalData.length > 0) {
|
||||
let previewHtml = '<div style="margin-top: 5px; font-size: 11px;">';
|
||||
data.slice(0, 3).forEach((vip, idx) => {
|
||||
previewHtml += `${idx + 1}. ${vip.customer_name}: ${vip.phone}<br>`;
|
||||
finalData.slice(0, 3).forEach((vip, idx) => {
|
||||
previewHtml += `${idx + 1}. ${vip.customer_name || '未知'}: ${vip.phone || '未知'}<br>`;
|
||||
});
|
||||
previewHtml += '</div>';
|
||||
previewEntry.innerHTML += previewHtml;
|
||||
@@ -800,21 +887,25 @@ $packages_json = json_encode(array_map(function($package) {
|
||||
historyElem.appendChild(previewEntry);
|
||||
}
|
||||
|
||||
resolve(data); // 成功完成Promise
|
||||
|
||||
// 成功完成,resolve Promise(使用处理后的finalData)
|
||||
resolve(finalData);
|
||||
} catch(e) {
|
||||
console.error('VIP客户数据解析失败:', e);
|
||||
window.allVIPCustomers = [];
|
||||
updateDebugStatus('解析失败: ' + e.message);
|
||||
reject(e); // 拒绝Promise
|
||||
console.error('VIP客户数据处理过程中发生异常:', e);
|
||||
// 继续尝试下一个URL
|
||||
currentAttempt++;
|
||||
tryNextUrl();
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('加载VIP客户列表失败:', error);
|
||||
updateDebugStatus('加载失败: ' + error.message);
|
||||
window.allVIPCustomers = [];
|
||||
reject(error); // 拒绝Promise
|
||||
console.error(`URL ${currentUrl} 请求失败:`, error.message);
|
||||
// 继续尝试下一个URL
|
||||
currentAttempt++;
|
||||
tryNextUrl();
|
||||
});
|
||||
}
|
||||
|
||||
// 开始尝试第一个URL
|
||||
tryNextUrl();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,571 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>VIP客户AJAX请求测试</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
color: #333;
|
||||
}
|
||||
h1, h2, h3 {
|
||||
color: #2c3e50;
|
||||
}
|
||||
.container {
|
||||
background: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.test-button {
|
||||
background: #3498db;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.test-button:hover {
|
||||
background: #2980b9;
|
||||
}
|
||||
.info-box {
|
||||
background: #e8f4fc;
|
||||
border-left: 4px solid #3498db;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
.success-box {
|
||||
background: #e8f8f5;
|
||||
border-left: 4px solid #27ae60;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
.error-box {
|
||||
background: #ffeaea;
|
||||
border-left: 4px solid #e74c3c;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
.warning-box {
|
||||
background: #fff8e1;
|
||||
border-left: 4px solid #ffc107;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
.code-box {
|
||||
background: #f5f5f5;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
overflow-x: auto;
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.log-box {
|
||||
background: #2c3e50;
|
||||
color: #ecf0f1;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
font-family: monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
.log-info { color: #3498db; }
|
||||
.log-success { color: #27ae60; }
|
||||
.log-error { color: #e74c3c; }
|
||||
.log-warning { color: #f39c12; }
|
||||
label {
|
||||
display: block;
|
||||
margin: 10px 0 5px;
|
||||
}
|
||||
input[type="text"] {
|
||||
padding: 8px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.result-box {
|
||||
margin-top: 20px;
|
||||
padding: 15px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>VIP客户AJAX请求测试</h1>
|
||||
|
||||
<div class="container">
|
||||
<h2>测试设置</h2>
|
||||
<div class="info-box">
|
||||
<p>这个页面将使用不同的方法测试VIP客户数据加载,帮助诊断为什么在主应用中显示"数据库中VIP客户数: 0"。</p>
|
||||
</div>
|
||||
|
||||
<label for="api-url">API URL路径:</label>
|
||||
<input type="text" id="api-url" value="get_vip_customers.php" placeholder="输入API的URL路径">
|
||||
|
||||
<button class="test-button" onclick="testFetch()">测试使用fetch()加载</button>
|
||||
<button class="test-button" onclick="testXHR()">测试使用XMLHttpRequest加载</button>
|
||||
<button class="test-button" onclick="testDirectLink()">直接访问API链接</button>
|
||||
<button class="test-button" onclick="testRelativePaths()">测试所有相对路径</button>
|
||||
<button class="test-button" onclick="testInNewContext()">在新上下文中测试</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>测试结果</h2>
|
||||
<div id="result" class="result-box">
|
||||
<p>点击上方按钮开始测试...</p>
|
||||
</div>
|
||||
|
||||
<h3>调试日志</h3>
|
||||
<div id="log" class="log-box">
|
||||
[系统] 就绪
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>环境信息</h2>
|
||||
<p>当前页面URL: <span id="current-url"></span></p>
|
||||
<p>当前路径: <span id="current-path"></span></p>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>常见问题解决方案</h2>
|
||||
|
||||
<h3>1. 路径问题</h3>
|
||||
<div class="info-box">
|
||||
<p>如果测试显示路径问题,可以尝试以下修复:</p>
|
||||
<pre class="code-box">// 修改index.php中的fetch调用
|
||||
fetch('/carwashorder/carwash_order/get_vip_customers.php') // 使用绝对路径</pre>
|
||||
</div>
|
||||
|
||||
<h3>2. JSON解析问题</h3>
|
||||
<div class="info-box">
|
||||
<p>如果JSON解析失败,可以修改错误处理以捕获更多信息:</p>
|
||||
<pre class="code-box">// 在loadVIPCustomers函数中添加更详细的错误处理
|
||||
try {
|
||||
const data = JSON.parse(text);
|
||||
console.log('解析成功:', data);
|
||||
} catch (parseError) {
|
||||
console.error('JSON解析失败:', parseError);
|
||||
console.error('原始响应文本:', text);
|
||||
// 尝试诊断文本内容
|
||||
if (text.includes('<')) {
|
||||
console.error('响应可能包含HTML内容而非纯JSON');
|
||||
}
|
||||
}</pre>
|
||||
</div>
|
||||
|
||||
<h3>3. 网络请求被阻止</h3>
|
||||
<div class="info-box">
|
||||
<p>检查浏览器控制台中的网络请求,确认请求是否被阻止或重定向。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 显示环境信息
|
||||
document.getElementById('current-url').textContent = window.location.href;
|
||||
document.getElementById('current-path').textContent = window.location.pathname;
|
||||
|
||||
// 日志函数
|
||||
function log(type, message) {
|
||||
const logBox = document.getElementById('log');
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
const logClass = 'log-' + type;
|
||||
logBox.innerHTML += `\n[${timestamp}] <span class="${logClass}">${message}</span>`;
|
||||
logBox.scrollTop = logBox.scrollHeight;
|
||||
}
|
||||
|
||||
// 显示结果
|
||||
function showResult(title, content, type = 'info') {
|
||||
const resultBox = document.getElementById('result');
|
||||
let boxClass = '';
|
||||
let titleColor = '#3498db';
|
||||
|
||||
switch(type) {
|
||||
case 'success':
|
||||
boxClass = 'success-box';
|
||||
titleColor = '#27ae60';
|
||||
break;
|
||||
case 'error':
|
||||
boxClass = 'error-box';
|
||||
titleColor = '#e74c3c';
|
||||
break;
|
||||
case 'warning':
|
||||
boxClass = 'warning-box';
|
||||
titleColor = '#f39c12';
|
||||
break;
|
||||
default:
|
||||
boxClass = 'info-box';
|
||||
}
|
||||
|
||||
resultBox.innerHTML = `
|
||||
<div class="${boxClass}">
|
||||
<h3 style="margin-top: 0; color: ${titleColor};">${title}</h3>
|
||||
<div>${content}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// 测试fetch请求
|
||||
function testFetch() {
|
||||
const apiUrl = document.getElementById('api-url').value;
|
||||
log('info', `开始使用fetch()测试URL: ${apiUrl}`);
|
||||
showResult('测试进行中', '正在发送fetch请求...');
|
||||
|
||||
fetch(apiUrl)
|
||||
.then(response => {
|
||||
log('info', `响应状态: ${response.status} ${response.statusText}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP错误! 状态: ${response.status}`);
|
||||
}
|
||||
|
||||
return response.text();
|
||||
})
|
||||
.then(text => {
|
||||
log('info', '接收到响应文本');
|
||||
log('info', `响应文本长度: ${text.length} 字符`);
|
||||
|
||||
// 显示原始响应的前500个字符
|
||||
const preview = text.length > 500 ? text.substring(0, 500) + '...' : text;
|
||||
|
||||
try {
|
||||
const data = JSON.parse(text);
|
||||
log('success', 'JSON解析成功');
|
||||
|
||||
let resultContent = `
|
||||
<p><strong>原始响应预览:</strong></p>
|
||||
<pre class="code-box">${preview}</pre>
|
||||
<p><strong>解析结果:</strong></p>
|
||||
`;
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
resultContent += `
|
||||
<p>返回的是数组,包含 <strong>${data.length}</strong> 个VIP客户</p>
|
||||
`;
|
||||
|
||||
if (data.length > 0) {
|
||||
resultContent += `
|
||||
<p><strong>第一个VIP客户:</strong></p>
|
||||
<pre class="code-box">${JSON.stringify(data[0], null, 2)}</pre>
|
||||
`;
|
||||
}
|
||||
} else if (typeof data === 'object' && data !== null) {
|
||||
resultContent += `
|
||||
<p>返回的是对象</p>
|
||||
<pre class="code-box">${JSON.stringify(data, null, 2)}</pre>
|
||||
`;
|
||||
} else {
|
||||
resultContent += `
|
||||
<p>返回的数据类型: ${typeof data}</p>
|
||||
`;
|
||||
}
|
||||
|
||||
showResult('fetch请求成功', resultContent, 'success');
|
||||
|
||||
} catch (parseError) {
|
||||
log('error', `JSON解析失败: ${parseError.message}`);
|
||||
|
||||
// 检查是否包含HTML标签
|
||||
const hasHtml = text.includes('<');
|
||||
const hasError = text.includes('error') || text.includes('Error');
|
||||
|
||||
let diagnosticInfo = '';
|
||||
if (hasHtml) {
|
||||
diagnosticInfo += '<p><strong>警告:</strong> 响应中可能包含HTML内容而非纯JSON</p>';
|
||||
}
|
||||
if (hasError) {
|
||||
diagnosticInfo += '<p><strong>警告:</strong> 响应中可能包含错误信息</p>';
|
||||
}
|
||||
|
||||
showResult('fetch请求成功但JSON解析失败', `
|
||||
<p><strong>原始响应:</strong></p>
|
||||
<pre class="code-box">${preview}</pre>
|
||||
<p><strong>错误信息:</strong> ${parseError.message}</p>
|
||||
${diagnosticInfo}
|
||||
`, 'error');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
log('error', `fetch请求失败: ${error.message}`);
|
||||
showResult('fetch请求失败', `
|
||||
<p><strong>错误信息:</strong> ${error.message}</p>
|
||||
<p>请检查URL路径是否正确或服务器是否正常运行。</p>
|
||||
`, 'error');
|
||||
});
|
||||
}
|
||||
|
||||
// 测试XMLHttpRequest
|
||||
function testXHR() {
|
||||
const apiUrl = document.getElementById('api-url').value;
|
||||
log('info', `开始使用XMLHttpRequest测试URL: ${apiUrl}`);
|
||||
showResult('测试进行中', '正在发送XHR请求...');
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
log('info', `XHR响应状态: ${xhr.status} ${xhr.statusText}`);
|
||||
|
||||
if (xhr.status === 200) {
|
||||
const text = xhr.responseText;
|
||||
log('info', `XHR响应文本长度: ${text.length} 字符`);
|
||||
|
||||
const preview = text.length > 500 ? text.substring(0, 500) + '...' : text;
|
||||
|
||||
try {
|
||||
const data = JSON.parse(text);
|
||||
log('success', 'XHR JSON解析成功');
|
||||
|
||||
let resultContent = `
|
||||
<p><strong>原始响应预览:</strong></p>
|
||||
<pre class="code-box">${preview}</pre>
|
||||
<p><strong>解析结果:</strong></p>
|
||||
`;
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
resultContent += `
|
||||
<p>返回的是数组,包含 <strong>${data.length}</strong> 个VIP客户</p>
|
||||
`;
|
||||
} else if (typeof data === 'object' && data !== null) {
|
||||
resultContent += `
|
||||
<p>返回的是对象</p>
|
||||
<pre class="code-box">${JSON.stringify(data, null, 2)}</pre>
|
||||
`;
|
||||
}
|
||||
|
||||
showResult('XHR请求成功', resultContent, 'success');
|
||||
|
||||
} catch (parseError) {
|
||||
log('error', `XHR JSON解析失败: ${parseError.message}`);
|
||||
showResult('XHR请求成功但JSON解析失败', `
|
||||
<p><strong>原始响应:</strong></p>
|
||||
<pre class="code-box">${preview}</pre>
|
||||
<p><strong>错误信息:</strong> ${parseError.message}</p>
|
||||
`, 'error');
|
||||
}
|
||||
} else {
|
||||
log('error', `XHR请求失败: 状态 ${xhr.status}`);
|
||||
showResult('XHR请求失败', `
|
||||
<p><strong>错误状态:</strong> ${xhr.status} ${xhr.statusText}</p>
|
||||
<p><strong>响应文本:</strong></p>
|
||||
<pre class="code-box">${xhr.responseText}</pre>
|
||||
`, 'error');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
xhr.onerror = function() {
|
||||
log('error', 'XHR网络错误');
|
||||
showResult('XHR网络错误', `
|
||||
<p>无法建立网络连接。请检查URL是否正确或服务器是否正常运行。</p>
|
||||
`, 'error');
|
||||
};
|
||||
|
||||
xhr.open('GET', apiUrl, true);
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
// 直接访问API链接
|
||||
function testDirectLink() {
|
||||
const apiUrl = document.getElementById('api-url').value;
|
||||
window.open(apiUrl, '_blank');
|
||||
log('info', `已在新窗口打开API链接: ${apiUrl}`);
|
||||
showResult('API直接访问', `
|
||||
<p>已在新窗口打开API链接。请查看新窗口中的响应内容,确认是否返回了有效的JSON数据。</p>
|
||||
`, 'info');
|
||||
}
|
||||
|
||||
// 测试所有可能的相对路径
|
||||
function testRelativePaths() {
|
||||
const pathsToTest = [
|
||||
'get_vip_customers.php',
|
||||
'./get_vip_customers.php',
|
||||
'../carwash_order/get_vip_customers.php',
|
||||
'/carwashorder/carwash_order/get_vip_customers.php'
|
||||
];
|
||||
|
||||
log('info', '开始测试多个可能的相对路径');
|
||||
showResult('路径测试进行中', `正在测试 ${pathsToTest.length} 个可能的路径...`);
|
||||
|
||||
let results = [];
|
||||
let completedTests = 0;
|
||||
|
||||
pathsToTest.forEach((path, index) => {
|
||||
setTimeout(() => {
|
||||
fetch(path)
|
||||
.then(response => response.ok ? response.text() : Promise.reject(response.status))
|
||||
.then(text => {
|
||||
try {
|
||||
const data = JSON.parse(text);
|
||||
results.push({
|
||||
path: path,
|
||||
status: 'success',
|
||||
count: Array.isArray(data) ? data.length : null,
|
||||
error: null
|
||||
});
|
||||
log('success', `路径 ${path} 测试成功`);
|
||||
} catch (e) {
|
||||
results.push({
|
||||
path: path,
|
||||
status: 'parse-error',
|
||||
count: null,
|
||||
error: e.message
|
||||
});
|
||||
log('warning', `路径 ${path} 返回数据但解析失败: ${e.message}`);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
results.push({
|
||||
path: path,
|
||||
status: 'error',
|
||||
count: null,
|
||||
error: typeof error === 'number' ? `HTTP ${error}` : error.message
|
||||
});
|
||||
log('error', `路径 ${path} 测试失败: ${error}`);
|
||||
})
|
||||
.finally(() => {
|
||||
completedTests++;
|
||||
if (completedTests === pathsToTest.length) {
|
||||
displayPathResults(results);
|
||||
}
|
||||
});
|
||||
}, index * 500); // 错开请求,避免同时发送
|
||||
});
|
||||
}
|
||||
|
||||
// 显示路径测试结果
|
||||
function displayPathResults(results) {
|
||||
let html = '<h4>路径测试结果</h4><table border="1" cellpadding="5" cellspacing="0" width="100%"><tr><th>路径</th><th>状态</th><th>VIP客户数量</th><th>错误信息</th></tr>';
|
||||
|
||||
results.forEach(result => {
|
||||
let statusColor = '#e74c3c';
|
||||
let statusText = '失败';
|
||||
|
||||
if (result.status === 'success') {
|
||||
statusColor = '#27ae60';
|
||||
statusText = '成功';
|
||||
} else if (result.status === 'parse-error') {
|
||||
statusColor = '#f39c12';
|
||||
statusText = '数据解析失败';
|
||||
}
|
||||
|
||||
html += `<tr>
|
||||
<td>${result.path}</td>
|
||||
<td style="color: ${statusColor};">${statusText}</td>
|
||||
<td>${result.count !== null ? result.count : '-'}</td>
|
||||
<td>${result.error || '-'}</td>
|
||||
</tr>`;
|
||||
});
|
||||
|
||||
html += '</table>';
|
||||
|
||||
// 找出成功的路径
|
||||
const successPaths = results.filter(r => r.status === 'success');
|
||||
if (successPaths.length > 0) {
|
||||
html += '<div class="success-box" style="margin-top: 10px;">
|
||||
<p><strong>推荐路径:</strong></p>
|
||||
<ul>
|
||||
' + successPaths.map(p => `<li>${p.path}</li>`).join('') + '
|
||||
</ul>
|
||||
</div>';
|
||||
}
|
||||
|
||||
showResult('路径测试完成', html, 'info');
|
||||
}
|
||||
|
||||
// 在新上下文中测试(模拟主应用环境)
|
||||
function testInNewContext() {
|
||||
log('info', '在新上下文中测试,模拟主应用环境');
|
||||
showResult('新上下文测试', '请查看浏览器控制台的详细日志...', 'info');
|
||||
|
||||
// 模拟主应用的加载环境
|
||||
console.log('===== 开始模拟主应用环境 =====');
|
||||
|
||||
// 创建一个测试的window对象
|
||||
const testContext = {};
|
||||
|
||||
// 模拟loadVIPCustomers函数
|
||||
function simulateLoadVIPCustomers() {
|
||||
console.log('模拟loadVIPCustomers调用...');
|
||||
|
||||
return fetch(document.getElementById('api-url').value)
|
||||
.then(response => {
|
||||
console.log('模拟响应状态:', response.status);
|
||||
return response.text();
|
||||
})
|
||||
.then(text => {
|
||||
console.log('模拟响应文本:', text);
|
||||
|
||||
try {
|
||||
const data = JSON.parse(text);
|
||||
testContext.allVIPCustomers = data;
|
||||
console.log('模拟数据存储成功:', testContext.allVIPCustomers);
|
||||
console.log('VIP客户数量:', Array.isArray(data) ? data.length : '非数组');
|
||||
|
||||
// 模拟匹配逻辑
|
||||
simulateCheckPhoneForVIP('18699627661');
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
console.error('模拟JSON解析失败:', e);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('模拟加载失败:', error);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
// 模拟checkPhoneForVIP函数
|
||||
function simulateCheckPhoneForVIP(phone) {
|
||||
console.log('\n模拟checkPhoneForVIP调用,搜索手机号:', phone);
|
||||
|
||||
if (!testContext.allVIPCustomers) {
|
||||
console.error('错误: VIP数据未加载');
|
||||
return null;
|
||||
}
|
||||
|
||||
// 标准化手机号
|
||||
const normalizedPhone = phone.replace(/\D/g, '');
|
||||
console.log('标准化后的手机号:', normalizedPhone);
|
||||
console.log('VIP客户总数:', Array.isArray(testContext.allVIPCustomers) ? testContext.allVIPCustomers.length : '非数组');
|
||||
|
||||
// 简单匹配逻辑
|
||||
if (Array.isArray(testContext.allVIPCustomers)) {
|
||||
const matched = testContext.allVIPCustomers.find(vip =>
|
||||
vip.phone === phone ||
|
||||
vip.phone.replace(/\D/g, '') === normalizedPhone
|
||||
);
|
||||
|
||||
if (matched) {
|
||||
console.log('找到匹配的VIP客户:', matched.customer_name, matched.phone);
|
||||
} else {
|
||||
console.log('未找到匹配的VIP客户');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 执行测试
|
||||
simulateLoadVIPCustomers().then(() => {
|
||||
console.log('===== 模拟测试完成 =====');
|
||||
showResult('新上下文测试完成', `
|
||||
<p>请查看浏览器控制台中的详细测试日志。</p>
|
||||
<p>该测试模拟了主应用中加载VIP数据和搜索的完整过程。</p>
|
||||
`, 'success');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user