fix(vip功能): 修复VIP客户搜索和选择功能的问题

将全局变量改为window.allVIPCustomers确保数据共享
优化搜索功能添加加载状态和错误处理
改进VIP选择后清除搜索结果和输入框
增强客户类型切换时的数据加载和清除逻辑
This commit is contained in:
2025-11-19 12:17:59 +08:00
parent 5619a1882e
commit a8f39ece83
2 changed files with 286 additions and 87 deletions
+150 -87
View File
@@ -549,7 +549,7 @@ $packages_json = json_encode(array_map(function($package) {
console.log('页面初始化完成');
});
let allVIPCustomers = []; // 全局变量存储所有VIP客户数据
window.allVIPCustomers = []; // 改为window全局变量,确保在所有函数中可访问
// 加载VIP客户列表 - 返回Promise以支持异步调用
function loadVIPCustomers() {
@@ -557,56 +557,54 @@ $packages_json = json_encode(array_map(function($package) {
return new Promise((resolve, reject) => {
fetch('get_vip_customers.php')
.then(response => {
console.log('VIP客户API响应状态:', response.status);
console.log('VIP客户API响应头:', response.headers);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
.then(response => {
console.log('VIP客户API响应状态:', response.status);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.text();
})
.then(text => {
console.log('VIP客户API原始响应:', text);
try {
// 先检查是否为空响应
if (!text || text.trim() === '') {
throw new Error('API返回空响应');
}
return response.text();
})
.then(text => {
console.log('VIP客户API原始响应:', text);
const data = JSON.parse(text);
try {
const data = JSON.parse(text);
// 检查是否是错误响应
if (data.error) {
throw new Error(data.message || 'API返回错误');
}
console.log('VIP客户数据解析成功:', data);
// 确保数据是数组格式
if (!Array.isArray(data)) {
throw new Error('API返回数据不是数组格式');
}
allVIPCustomers = data; // 存储所有VIP客户数据
updateVIPSelect(data); // 更新下拉列表
console.log('VIP客户列表加载完成,共', data.length, '条记录');
// 测试搜索功能
if (data.length > 0) {
console.log('测试搜索功能...');
testSearchFunction();
}
resolve(data); // 成功完成Promise
// 检查是否是错误响应
if (data.error) {
throw new Error(data.message || 'API返回错误');
}
console.log('VIP客户数据解析成功:', data);
// 确保数据是数组格式
if (!Array.isArray(data)) {
throw new Error('API返回数据不是数组格式');
}
window.allVIPCustomers = data; // 存储所有VIP客户数据
updateVIPSelect(data); // 更新下拉列表
console.log('VIP客户列表加载完成,共', data.length, '条记录');
resolve(data); // 成功完成Promise
} catch(e) {
console.error('VIP客户数据解析失败:', e);
allVIPCustomers = [];
window.allVIPCustomers = [];
reject(e); // 拒绝Promise
}
})
.catch(error => {
console.error('加载VIP客户列表失败:', error);
allVIPCustomers = [];
window.allVIPCustomers = [];
reject(error); // 拒绝Promise
});
});
@@ -614,12 +612,12 @@ $packages_json = json_encode(array_map(function($package) {
// 测试搜索功能
function testSearchFunction() {
if (allVIPCustomers.length > 0) {
console.log('当前VIP客户:', allVIPCustomers);
if (window.allVIPCustomers.length > 0) {
console.log('当前VIP客户:', window.allVIPCustomers);
// 模拟搜索测试
const testTerm = allVIPCustomers[0].customer_name.substring(0, 1);
const results = allVIPCustomers.filter(vip =>
const testTerm = window.allVIPCustomers[0].customer_name.substring(0, 1);
const results = window.allVIPCustomers.filter(vip =>
vip.customer_name.includes(testTerm) ||
vip.phone.includes(testTerm)
);
@@ -640,20 +638,16 @@ $packages_json = json_encode(array_map(function($package) {
});
}
// VIP客户搜索功能 - 修复数据加载时序问题
// VIP客户搜索功能 - 修复版本
function searchVIPCustomers() {
console.log('开始搜索VIP客户...');
const searchInput = document.getElementById('vip_search');
const searchResultsDiv = document.getElementById('vip_search_results');
const vipSelect = document.getElementById('vip_id');
if (!searchInput) {
console.error('找不到VIP搜索输入框');
return;
}
if (!searchResultsDiv) {
console.error('找不到VIP搜索结果容器');
if (!searchInput || !searchResultsDiv || !vipSelect) {
console.error('找不到必要的DOM元素');
return;
}
@@ -661,46 +655,74 @@ $packages_json = json_encode(array_map(function($package) {
console.log('搜索关键词:', searchTerm);
// 检查数据加载状态
console.log('VIP客户总数:', allVIPCustomers.length);
console.log('VIP客户数据:', allVIPCustomers);
console.log('VIP客户总数:', window.allVIPCustomers.length);
// 始终显示搜索结果容器
searchResultsDiv.style.display = 'block';
// 如果数据还没加载完成,先加载数据
if (allVIPCustomers.length === 0) {
if (window.allVIPCustomers.length === 0) {
console.log('VIP客户数据尚未加载,先加载数据...');
searchResultsDiv.innerHTML = '<div class="loading">正在加载VIP客户数据...</div>';
loadVIPCustomers().then(() => {
console.log('数据加载完成,重新执行搜索');
// 重新调用搜索函数
setTimeout(() => searchVIPCustomers(), 100);
// 数据加载后执行搜索
performSearch(searchTerm);
}).catch(error => {
console.error('加载VIP数据失败:', error);
searchResultsDiv.innerHTML = '<div class="search-error">加载VIP客户数据失败,请重试</div>';
});
return;
} else {
// 直接执行搜索
performSearch(searchTerm);
}
if (searchTerm === '') {
clearSearchResults();
updateVIPSelect(allVIPCustomers);
return;
}
// 模糊搜索:支持姓名和手机号搜索
const filteredCustomers = allVIPCustomers.filter(vip => {
const name = (vip.customer_name || '').toLowerCase();
const phone = (vip.phone || '').toLowerCase();
const term = searchTerm.toLowerCase();
function performSearch(term) {
if (term === '') {
searchResultsDiv.innerHTML = '';
searchResultsDiv.style.display = 'none';
vipSelect.style.display = 'block';
return;
}
const nameMatch = name.includes(term);
const phoneMatch = phone.includes(term);
// 模糊搜索:支持姓名和手机号搜索
const filteredCustomers = window.allVIPCustomers.filter(vip => {
const name = (vip.customer_name || '').toLowerCase();
const phone = (vip.phone || '').toLowerCase();
const searchLower = term.toLowerCase();
return name.includes(searchLower) || phone.includes(searchLower);
});
console.log(`检查VIP客户: ${vip.customer_name} (${vip.phone}) - 匹配结果: 姓名=${nameMatch}, 手机=${phoneMatch}`);
console.log('搜索结果数量:', filteredCustomers.length);
return nameMatch || phoneMatch;
});
console.log('搜索结果:', filteredCustomers);
displaySearchResults(filteredCustomers, searchTerm);
// 隐藏下拉列表
const vipSelect = document.getElementById('vip_id');
if (vipSelect) {
// 显示搜索结果
if (filteredCustomers.length === 0) {
searchResultsDiv.innerHTML = '<div class="no-results">未找到匹配的VIP客户</div>';
} else {
let html = '';
filteredCustomers.forEach(vip => {
const name = vip.customer_name || '';
const phone = vip.phone || '';
const id = vip.id || '';
// 高亮处理
const highlightedName = name.replace(new RegExp(`(${term})`, 'gi'), '<span class="highlight">$1</span>');
const highlightedPhone = phone.replace(new RegExp(`(${term})`, 'gi'), '<span class="highlight">$1</span>');
html += `
<div class="vip-search-item" onclick="selectVIPCustomer('${id}', '${name}', '${phone}')">
<div class="customer-name">${highlightedName}</div>
<div class="customer-phone">${highlightedPhone}</div>
${vip.car_model || vip.car_number ? `<div class="customer-car">${vip.car_model || ''} ${vip.car_number || ''}</div>` : ''}
</div>
`;
});
searchResultsDiv.innerHTML = html;
}
// 隐藏下拉列表
vipSelect.style.display = 'none';
}
}
@@ -733,10 +755,11 @@ $packages_json = json_encode(array_map(function($package) {
const highlightedPhone = highlightSearchTerm(phone, searchTerm);
html += `
<div class="vip-result" onclick="selectVIPCustomer('${id}', '${name}', '${phone}')">
<div class="vip-name">${highlightedName}</div>
<div class="vip-phone">${highlightedPhone}</div>
</div>
<div class="vip-search-item" onclick="selectVIPCustomer('${id}', '${name}', '${phone}')">
<div class="customer-name">${highlightedName}</div>
<div class="customer-phone">${highlightedPhone}</div>
${vip.car_model || vip.car_number ? `<div class="customer-car">${vip.car_model || ''} ${vip.car_number || ''}</div>` : ''}
</div>
`;
});
@@ -774,21 +797,32 @@ $packages_json = json_encode(array_map(function($package) {
}
}
// 选择VIP客户
// 选择VIP客户 - 修复版本
function selectVIPCustomer(customerId, customerName = '', customerPhone = '') {
console.log('选择VIP客户:', customerId, customerName, customerPhone);
// 设置下拉选择值
const vipSelect = document.getElementById('vip_id');
const searchResultsDiv = document.getElementById('vip_search_results');
const searchInput = document.getElementById('vip_search');
if (vipSelect) {
vipSelect.value = customerId;
vipSelect.style.display = 'block';
console.log('已设置VIP选择值:', customerId);
} else {
console.error('找不到VIP选择元素');
}
// 清除搜索状态
clearSearchResults();
if (searchResultsDiv) {
searchResultsDiv.innerHTML = '';
searchResultsDiv.style.display = 'none';
}
if (searchInput) {
searchInput.value = '';
}
// 加载VIP客户信息
loadVIPInfo();
@@ -864,18 +898,47 @@ $packages_json = json_encode(array_map(function($package) {
const vipSelectGroup = document.getElementById('vip_select_group');
const newCustomerFields = document.getElementById('new_customer_fields');
console.log('切换客户类型:', customerType);
if (customerType === 'vip') {
vipSelectGroup.style.display = 'block';
newCustomerFields.style.display = 'none';
// 隐藏新客户字段的必填属性
document.getElementById('customer_name').required = false;
document.getElementById('phone').required = false;
// 确保VIP客户数据已加载
if (window.allVIPCustomers.length === 0) {
console.log('VIP客户数据未加载,开始加载...');
loadVIPCustomers().then(() => {
console.log('VIP客户数据加载完成,可进行搜索和选择');
}).catch(error => {
console.error('加载VIP数据失败:', error);
});
}
} else {
vipSelectGroup.style.display = 'none';
newCustomerFields.style.display = 'flex';
// 显示新客户字段的必填属性
document.getElementById('customer_name').required = true;
document.getElementById('phone').required = true;
// 清除VIP选择
const vipSelect = document.getElementById('vip_id');
if (vipSelect) {
vipSelect.value = '';
}
// 清除搜索结果
const searchResultsDiv = document.getElementById('vip_search_results');
const searchInput = document.getElementById('vip_search');
if (searchResultsDiv) {
searchResultsDiv.innerHTML = '';
searchResultsDiv.style.display = 'none';
}
if (searchInput) {
searchInput.value = '';
}
}
updateSubmitButton();
+136
View File
@@ -0,0 +1,136 @@
<!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: Arial, sans-serif;
margin: 20px;
line-height: 1.6;
}
h1 {
color: #333;
}
h2 {
color: #555;
margin-top: 30px;
}
.test-result {
padding: 15px;
margin: 10px 0;
border-radius: 5px;
}
.success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.warning {
background-color: #fff3cd;
color: #856404;
border: 1px solid #ffeaa7;
}
.error {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.info {
background-color: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
pre {
background-color: #f8f9fa;
padding: 10px;
border-radius: 5px;
overflow-x: auto;
}
.test-area {
border: 1px solid #ddd;
padding: 20px;
border-radius: 5px;
margin-top: 20px;
}
.btn {
padding: 8px 16px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.btn:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<h1>VIP功能修复测试报告</h1>
<div class="test-area">
<h2>修复的问题</h2>
<div class="info test-result">
<ul>
<li>将全局VIP客户数据数组修改为window.allVIPCustomers,确保在所有函数中可访问</li>
<li>改进了searchVIPCustomers函数,添加加载状态、错误处理和空结果提示</li>
<li>优化了selectVIPCustomer函数,直接清除搜索结果和输入框</li>
<li>增强了handleCustomerTypeChange函数,添加数据加载逻辑和清除功能</li>
</ul>
</div>
<h2>JavaScript变量访问修复</h2>
<div class="success test-result">
<p>✅ 全局变量已从<code>let allVIPCustomers = [];</code>修改为<code>window.allVIPCustomers = [];</code></p>
<p>✅ 所有函数中对allVIPCustomers的引用都已更新为window.allVIPCustomers</p>
</div>
<h2>搜索功能优化</h2>
<div class="success test-result">
<p>✅ 搜索结果显示逻辑已优化,添加了车辆信息显示</p>
<p>✅ 添加了空查询和空结果的处理</p>
<p>✅ 实现了搜索关键词高亮功能</p>
</div>
<h2>VIP选择功能修复</h2>
<div class="success test-result">
<p>✅ 修复了选择VIP客户后下拉菜单的更新问题</p>
<p>✅ 实现了搜索结果清除和输入框重置</p>
</div>
<h2>客户类型切换逻辑增强</h2>
<div class="success test-result">
<p>✅ 添加了切换到VIP类型时自动加载数据的逻辑</p>
<p>✅ 改进了切换回普通客户时的清除逻辑</p>
<p>✅ 添加了调试日志以帮助跟踪功能执行</p>
</div>
<h2>如何测试实际功能</h2>
<div class="warning test-result">
<p>由于环境限制无法启动PHP服务器,建议在本地环境中进行以下测试:</p>
<ol>
<li>将修改后的index.php文件部署到支持PHP的服务器上</li>
<li>打开首页,进入预约洗车表单</li>
<li>测试VIP客户类型选择功能</li>
<li>验证VIP客户搜索和模糊匹配功能</li>
<li>确认选择VIP客户后表单正确更新</li>
</ol>
</div>
<h2>修复代码摘要</h2>
<div class="test-result">
<p>修复的核心问题是JavaScript变量作用域问题和事件处理逻辑不完善:</p>
<ul>
<li>使用全局变量window.allVIPCustomers确保数据在所有函数间共享</li>
<li>改进了事件处理流程,确保在适当的时机加载数据和更新UI</li>
<li>添加了完整的错误处理和边界情况处理</li>
<li>优化了用户界面交互,提高用户体验</li>
</ul>
</div>
</div>
<button class="btn" onclick="window.location.href='index.php'">返回首页</button>
</body>
</html>