<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>客户管理系统</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
}
:root {
--primary: #4361ee;
--primary-dark: #3a56d4;
--secondary: #f72585;
--success: #06d6a0;
--warning: #ffd166;
--danger: #ef476f;
--info: #118ab2;
--light: #f8f9fa;
--dark: #212529;
--gray: #6c757d;
--light-gray: #e9ecef;
--border-radius: 10px;
--shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
--transition: all 0.3s ease;
}
body {
background: linear-gradient(135deg, #f0f4f8 0%, #e2e8f0 100%);
color: var(--dark);
line-height: 1.6;
padding: 20px;
min-height: 100vh;
}
.container {
max-width: 1400px;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 25px;
}
header {
text-align: center;
padding: 30px;
background: linear-gradient(120deg, var(--primary), #3a0ca3);
color: white;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
}
header h1 {
font-size: 2.8rem;
margin-bottom: 10px;
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
}
header p {
font-size: 1.2rem;
max-width: 800px;
margin: 0 auto;
opacity: 0.9;
}
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 25px;
margin-bottom: 10px;
}
.card {
background: white;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
overflow: hidden;
transition: var(--transition);
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}
.card-header {
background: linear-gradient(120deg, var(--info), var(--primary));
color: white;
padding: 18px 25px;
display: flex;
align-items: center;
justify-content: space-between;
}
.card-header h2 {
font-size: 1.4rem;
display: flex;
align-items: center;
gap: 10px;
}
.card-body {
padding: 25px;
}
/* 搜索区域样式 */
.search-box {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.search-group {
flex: 1;
min-width: 250px;
}
.search-group label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: var(--gray);
}
.search-input {
width: 100%;
padding: 12px 15px;
border: 1px solid var(--light-gray);
border-radius: var(--border-radius);
font-size: 1rem;
transition: var(--transition);
}
.search-input:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.2);
}
.search-btn {
padding: 12px 25px;
background: var(--primary);
color: white;
border: none;
border-radius: var(--border-radius);
cursor: pointer;
font-weight: 600;
transition: var(--transition);
display: flex;
align-items: center;
gap: 8px;
}
.search-btn:hover {
background: var(--primary-dark);
}
/* 功能区样式 */
.action-bar {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.action-btn {
padding: 12px 20px;
background: white;
color: var(--dark);
border: 1px solid var(--light-gray);
border-radius: var(--border-radius);
cursor: pointer;
font-weight: 500;
transition: var(--transition);
display: flex;
align-items: center;
gap: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
}
.action-btn:hover {
background: var(--light);
transform: translateY(-2px);
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}
.btn-primary {
background: var(--primary);
color: white;
border-color: var(--primary);
}
.btn-primary:hover {
background: var(--primary-dark);
}
.btn-success {
background: var(--success);
color: white;
border-color: var(--success);
}
.btn-danger {
background: var(--danger);
color: white;
border-color: var(--danger);
}
.btn-warning {
background: var(--warning);
color: var(--dark);
border-color: var(--warning);
}
/* 表格区域样式 */
.table-container {
overflow-x: auto;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
background: white;
}
.data-table {
width: 100%;
border-collapse: collapse;
min-width: 1000px;
}
.data-table th {
background: var(--primary);
color: white;
text-align: left;
padding: 16px 15px;
font-weight: 600;
cursor: pointer;
position: relative;
}
.data-table th:hover {
background: var(--primary-dark);
}
.data-table th i {
margin-left: 5px;
opacity: 0.7;
}
.data-table td {
padding: 14px 15px;
border-bottom: 1px solid var(--light-gray);
vertical-align: middle;
}
.data-table tr:last-child td {
border-bottom: none;
}
.data-table tr:hover td {
background: rgba(67, 97, 238, 0.03);
}
.data-table .selected-row td {
background: rgba(6, 214, 160, 0.1) !important;
}
.status {
padding: 6px 12px;
border-radius: 20px;
font-size: 0.85rem;
font-weight: 500;
display: inline-block;
}
.status-active {
background: rgba(6, 214, 160, 0.15);
color: #06a17a;
}
.status-inactive {
background: rgba(239, 71, 111, 0.15);
color: #d62f55;
}
.highlight {
background-color: #fff9c4;
padding: 0 2px;
font-weight: 600;
}
.action-cell {
display: flex;
gap: 10px;
}
.action-icon {
width: 36px;
height: 36px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: var(--transition);
}
.action-icon:hover {
transform: scale(1.1);
}
.edit-icon {
background: rgba(17, 138, 178, 0.15);
color: var(--info);
}
.delete-icon {
background: rgba(239, 71, 111, 0.15);
color: var(--danger);
}
.checkbox-cell {
width: 50px;
text-align: center;
}
/* 分页区域样式 */
.pagination {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
background: white;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
}
.pagination-info {
color: var(--gray);
font-size: 0.95rem;
}
.pagination-controls {
display: flex;
gap: 8px;
}
.page-btn {
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: white;
border: 1px solid var(--light-gray);
cursor: pointer;
transition: var(--transition);
}
.page-btn:hover, .page-btn.active {
background: var(--primary);
color: white;
border-color: var(--primary);
}
/* 模态框样式 */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
}
.modal-overlay.show {
opacity: 1;
visibility: visible;
}
.modal {
background: white;
border-radius: var(--border-radius);
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2);
width: 100%;
max-width: 600px;
transform: translateY(-30px);
transition: transform 0.3s ease;
}
.modal-overlay.show .modal {
transform: translateY(0);
}
.modal-header {
padding: 20px 25px;
border-bottom: 1px solid var(--light-gray);
display: flex;
align-items: center;
justify-content: space-between;
}
.modal-header h3 {
font-size: 1.5rem;
color: var(--primary);
display: flex;
align-items: center;
gap: 10px;
}
.modal-body {
padding: 25px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: var(--gray);
}
.form-control {
width: 100%;
padding: 12px 15px;
border: 1px solid var(--light-gray);
border-radius: var(--border-radius);
font-size: 1rem;
transition: var(--transition);
}
.form-control:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.2);
}
.modal-footer {
padding: 20px 25px;
border-top: 1px solid var(--light-gray);
display: flex;
justify-content: flex-end;
gap: 15px;
}
/* 响应式设计 */
@media (max-width: 992px) {
.dashboard {
grid-template-columns: 1fr;
}
.card-header h2 {
font-size: 1.3rem;
}
header h1 {
font-size: 2.2rem;
}
}
@media (max-width: 768px) {
.action-bar {
flex-direction: column;
}
.action-bar .action-btn {
width: 100%;
justify-content: center;
}
.search-box {
flex-direction: column;
}
.pagination {
flex-direction: column;
gap: 15px;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1><i class="fas fa-users-cog"></i> 客户管理系统</h1>
<p>高效管理客户信息,支持增删改查、批量操作、高级搜索和分页功能</p>
</header>
<!-- 搜索区域 -->
<div class="card">
<div class="card-header">
<h2><i class="fas fa-search"></i> 搜索区域</h2>
</div>
<div class="card-body">
<div class="search-box">
<div class="search-group">
<label for="searchName"><i class="fas fa-user"></i> 客户姓名</label>
<input type="text" id="searchName" class="search-input" placeholder="输入客户姓名...">
</div>
<div class="search-group">
<label for="searchPhone"><i class="fas fa-phone"></i> 联系电话</label>
<input type="text" id="searchPhone" class="search-input" placeholder="输入联系电话...">
</div>
<div class="search-group">
<label for="searchEmail"><i class="fas fa-envelope"></i> 电子邮箱</label>
<input type="text" id="searchEmail" class="search-input" placeholder="输入电子邮箱...">
</div>
<div class="search-group" style="align-self: flex-end;">
<button class="search-btn" id="searchButton">
<i class="fas fa-search"></i> 搜索客户
</button>
</div>
</div>
</div>
</div>
<!-- 功能区 -->
<div class="card">
<div class="card-header">
<h2><i class="fas fa-tools"></i> 功能区</h2>
</div>
<div class="card-body">
<div class="action-bar">
<button class="action-btn btn-primary" id="addCustomerBtn">
<i class="fas fa-user-plus"></i> 新增客户
</button>
<button class="action-btn btn-success" id="exportBtn">
<i class="fas fa-file-export"></i> 导出数据
</button>
<button class="action-btn btn-warning" id="batchEditBtn">
<i class="fas fa-edit"></i> 批量编辑
</button>
<button class="action-btn btn-danger" id="batchDeleteBtn">
<i class="fas fa-trash-alt"></i> 批量删除
</button>
<button class="action-btn" id="refreshBtn">
<i class="fas fa-sync-alt"></i> 刷新数据
</button>
</div>
</div>
</div>
<!-- 列表区 -->
<div class="card">
<div class="card-header">
<h2><i class="fas fa-list"></i> 客户列表</h2>
<div class="pagination-info" id="listInfo">显示 0 条记录中的 0 条</div>
</div>
<div class="table-container">
<table class="data-table">
<thead>
<tr>
<th class="checkbox-cell"><input type="checkbox" id="selectAll"></th>
<th data-sort="id">ID <i class="fas fa-sort"></i></th>
<th data-sort="name">客户姓名 <i class="fas fa-sort"></i></th>
<th data-sort="phone">联系电话 <i class="fas fa-sort"></i></th>
<th data-sort="email">电子邮箱 <i class="fas fa-sort"></i></th>
<th data-sort="company">公司名称 <i class="fas fa-sort"></i></th>
<th data-sort="status">状态 <i class="fas fa-sort"></i></th>
<th data-sort="createDate">创建日期 <i class="fas fa-sort"></i></th>
<th>操作</th>
</tr>
</thead>
<tbody id="customerTableBody">
<!-- 客户数据将通过JavaScript动态生成 -->
</tbody>
</table>
</div>
</div>
<!-- 分页区 -->
<div class="pagination">
<div class="pagination-info" id="paginationInfo">第 0 页,共 0 页,0 条记录</div>
<div class="pagination-controls" id="paginationControls">
<!-- 分页按钮将通过JavaScript动态生成 -->
</div>
</div>
</div>
<!-- 新增/编辑客户模态框 -->
<div class="modal-overlay" id="customerModal">
<div class="modal">
<div class="modal-header">
<h3><i class="fas fa-user-edit"></i> <span id="modalTitle">新增客户</span></h3>
<button class="action-icon edit-icon" id="closeModal">
<i class="fas fa-times"></i>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="customerName">客户姓名 *</label>
<input type="text" id="customerName" class="form-control" placeholder="请输入客户姓名">
</div>
<div class="form-group">
<label for="customerPhone">联系电话 *</label>
<input type="text" id="customerPhone" class="form-control" placeholder="请输入联系电话">
</div>
<div class="form-group">
<label for="customerEmail">电子邮箱 *</label>
<input type="email" id="customerEmail" class="form-control" placeholder="请输入电子邮箱">
</div>
<div class="form-group">
<label for="customerCompany">公司名称</label>
<input type="text" id="customerCompany" class="form-control" placeholder="请输入公司名称">
</div>
<div class="form-group">
<label for="customerAddress">联系地址</label>
<input type="text" id="customerAddress" class="form-control" placeholder="请输入联系地址">
</div>
<div class="form-group">
<label for="customerStatus">客户状态</label>
<select id="customerStatus" class="form-control">
<option value="active">活跃客户</option>
<option value="inactive">非活跃客户</option>
</select>
</div>
</div>
<div class="modal-footer">
<button class="action-btn" id="cancelBtn">取消</button>
<button class="action-btn btn-primary" id="saveCustomerBtn">保存客户</button>
</div>
</div>
</div>
<script>
// 模拟客户数据
const generateCustomers = () => {
const names = ['张伟', '王芳', '李明', '刘洋', '陈静', '赵强', '杨艳', '周杰', '黄丽', '吴刚'];
const companies = ['科技有限公司', '贸易有限公司', '集团股份有限公司', '电子商务公司', '咨询服务公司'];
const domains = ['gmail.com', 'qq.com', '163.com', 'hotmail.com', 'outlook.com'];
const customers = [];
for (let i = 1; i <= 125; i++) {
const firstName = names[Math.floor(Math.random() * names.length)];
const lastName = names[Math.floor(Math.random() * names.length)];
const company = `${lastName}${companies[Math.floor(Math.random() * companies.length)]}`;
const domain = domains[Math.floor(Math.random() * domains.length)];
customers.push({
id: i,
name: `${firstName}${lastName}`,
phone: `13${Math.floor(Math.random() * 100000000).toString().padStart(8, '0')}`,
email: `${firstName.toLowerCase()}${lastName.toLowerCase()}@${domain}`,
company: company,
address: `北京市朝阳区第${i}号`,
status: Math.random() > 0.3 ? 'active' : 'inactive',
createDate: `2023-${Math.floor(Math.random() * 12 + 1).toString().padStart(2, '0')}-${Math.floor(Math.random() * 28 + 1).toString().padStart(2, '0')}`
});
}
return customers;
};
// 初始化数据
let allCustomers = generateCustomers();
let filteredCustomers = [...allCustomers];
let currentPage = 1;
const pageSize = 10;
let currentSort = { field: 'id', direction: 'asc' };
let searchTerm = '';
let editingCustomerId = null;
// DOM元素
const customerTableBody = document.getElementById('customerTableBody');
const paginationInfo = document.getElementById('paginationInfo');
const paginationControls = document.getElementById('paginationControls');
const listInfo = document.getElementById('listInfo');
const customerModal = document.getElementById('customerModal');
const modalTitle = document.getElementById('modalTitle');
const selectAllCheckbox = document.getElementById('selectAll');
// 渲染客户表格
const renderCustomerTable = () => {
const startIndex = (currentPage - 1) * pageSize;
const endIndex = Math.min(startIndex + pageSize, filteredCustomers.length);
const currentPageCustomers = filteredCustomers.slice(startIndex, endIndex);
customerTableBody.innerHTML = '';
if (currentPageCustomers.length === 0) {
customerTableBody.innerHTML = `
<tr>
<td colspan="9" style="text-align: center; padding: 40px; color: var(--gray);">
<i class="fas fa-inbox" style="font-size: 3rem; margin-bottom: 15px; opacity: 0.5;"></i>
<h3>未找到客户记录</h3>
<p>请尝试修改搜索条件或添加新客户</p>
</td>
</tr>
`;
return;
}
currentPageCustomers.forEach(customer => {
const tr = document.createElement('tr');
tr.dataset.id = customer.id;
// 高亮显示搜索关键词
const highlightText = (text) => {
if (!searchTerm) return text;
const lowerText = text.toLowerCase();
const lowerSearchTerm = searchTerm.toLowerCase();
const startIndex = lowerText.indexOf(lowerSearchTerm);
if (startIndex === -1) return text;
const endIndex = startIndex + searchTerm.length;
return `${text.substring(0, startIndex)}<span class="highlight">${text.substring(startIndex, endIndex)}</span>${text.substring(endIndex)}`;
};
tr.innerHTML = `
<td class="checkbox-cell"><input type="checkbox" class="row-checkbox" data-id="${customer.id}"></td>
<td>${customer.id}</td>
<td>${highlightText(customer.name)}</td>
<td>${highlightText(customer.phone)}</td>
<td>${highlightText(customer.email)}</td>
<td>${customer.company}</td>
<td><span class="status ${customer.status === 'active' ? 'status-active' : 'status-inactive'}">${customer.status === 'active' ? '活跃' : '非活跃'}</span></td>
<td>${customer.createDate}</td>
<td class="action-cell">
<div class="action-icon edit-icon" data-id="${customer.id}">
<i class="fas fa-edit"></i>
</div>
<div class="action-icon delete-icon" data-id="${customer.id}">
<i class="fas fa-trash-alt"></i>
</div>
</td>
`;
customerTableBody.appendChild(tr);
});
};
// 渲染分页控件
const renderPagination = () => {
const totalPages = Math.ceil(filteredCustomers.length / pageSize);
// 更新分页信息
const start = (currentPage - 1) * pageSize + 1;
const end = Math.min(currentPage * pageSize, filteredCustomers.length);
paginationInfo.textContent = `第 ${currentPage} 页,共 ${totalPages} 页,${filteredCustomers.length} 条记录`;
listInfo.textContent = `显示 ${start} 到 ${end} 条记录,共 ${filteredCustomers.length} 条`;
// 更新分页按钮
paginationControls.innerHTML = '';
// 上一页按钮
const prevButton = document.createElement('button');
prevButton.className = 'page-btn';
prevButton.innerHTML = '<i class="fas fa-chevron-left"></i>';
prevButton.disabled = currentPage === 1;
prevButton.addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
renderCustomerTable();
renderPagination();
}
});
paginationControls.appendChild(prevButton);
// 页码按钮
const startPage = Math.max(1, currentPage - 2);
const endPage = Math.min(totalPages, startPage + 4);
for (let i = startPage; i <= endPage; i++) {
const pageButton = document.createElement('button');
pageButton.className = `page-btn ${i === currentPage ? 'active' : ''}`;
pageButton.textContent = i;
pageButton.addEventListener('click', () => {
currentPage = i;
renderCustomerTable();
renderPagination();
});
paginationControls.appendChild(pageButton);
}
// 下一页按钮
const nextButton = document.createElement('button');
nextButton.className = 'page-btn';
nextButton.innerHTML = '<i class="fas fa-chevron-right"></i>';
nextButton.disabled = currentPage === totalPages;
nextButton.addEventListener('click', () => {
if (currentPage < totalPages) {
currentPage++;
renderCustomerTable();
renderPagination();
}
});
paginationControls.appendChild(nextButton);
};
// 排序功能
const sortCustomers = (field) => {
if (currentSort.field === field) {
currentSort.direction = currentSort.direction === 'asc' ? 'desc' : 'asc';
} else {
currentSort.field = field;
currentSort.direction = 'asc';
}
filteredCustomers.sort((a, b) => {
if (a[field] < b[field]) return currentSort.direction === 'asc' ? -1 : 1;
if (a[field] > b[field]) return currentSort.direction === 'asc' ? 1 : -1;
return 0;
});
currentPage = 1;
renderCustomerTable();
renderPagination();
};
// 搜索功能
const searchCustomers = () => {
const nameSearch = document.getElementById('searchName').value.toLowerCase();
const phoneSearch = document.getElementById('searchPhone').value.toLowerCase();
const emailSearch = document.getElementById('searchEmail').value.toLowerCase();
searchTerm = nameSearch || phoneSearch || emailSearch;
filteredCustomers = allCustomers.filter(customer => {
const nameMatch = customer.name.toLowerCase().includes(nameSearch);
const phoneMatch = customer.phone.toLowerCase().includes(phoneSearch);
const emailMatch = customer.email.toLowerCase().includes(emailSearch);
return nameMatch && phoneMatch && emailMatch;
});
currentPage = 1;
renderCustomerTable();
renderPagination();
};
// 打开新增客户模态框
const openAddCustomerModal = () => {
editingCustomerId = null;
modalTitle.textContent = '新增客户';
document.getElementById('customerName').value = '';
document.getElementById('customerPhone').value = '';
document.getElementById('customerEmail').value = '';
document.getElementById('customerCompany').value = '';
document.getElementById('customerAddress').value = '';
document.getElementById('customerStatus').value = 'active';
customerModal.classList.add('show');
};
// 打开编辑客户模态框
const openEditCustomerModal = (id) => {
const customer = allCustomers.find(c => c.id === id);
if (!customer) return;
editingCustomerId = id;
modalTitle.textContent = '编辑客户';
document.getElementById('customerName').value = customer.name;
document.getElementById('customerPhone').value = customer.phone;
document.getElementById('customerEmail').value = customer.email;
document.getElementById('customerCompany').value = customer.company;
document.getElementById('customerAddress').value = customer.address;
document.getElementById('customerStatus').value = customer.status;
customerModal.classList.add('show');
};
// 保存客户
const saveCustomer = () => {
const name = document.getElementById('customerName').value.trim();
const phone = document.getElementById('customerPhone').value.trim();
const email = document.getElementById('customerEmail').value.trim();
const company = document.getElementById('customerCompany').value.trim();
const address = document.getElementById('customerAddress').value.trim();
const status = document.getElementById('customerStatus').value;
if (!name || !phone || !email) {
alert('请填写必填字段:客户姓名、联系电话和电子邮箱');
return;
}
// 检查邮箱是否已存在
const emailExists = allCustomers.some(c =>
c.email.toLowerCase() === email.toLowerCase() &&
(!editingCustomerId || c.id !== editingCustomerId)
);
if (emailExists) {
alert('该电子邮箱已被使用,请使用其他邮箱');
return;
}
if (editingCustomerId) {
// 更新现有客户
const index = allCustomers.findIndex(c => c.id === editingCustomerId);
if (index !== -1) {
allCustomers[index] = {
...allCustomers[index],
name,
phone,
email,
company,
address,
status
};
}
} else {
// 新增客户
const newId = Math.max(...allCustomers.map(c => c.id)) + 1;
const newCustomer = {
id: newId,
name,
phone,
email,
company,
address,
status,
createDate: new Date().toISOString().split('T')[0]
};
allCustomers.unshift(newCustomer);
}
customerModal.classList.remove('show');
searchCustomers();
};
// 删除客户
const deleteCustomer = (id) => {
if (confirm('确定要删除此客户吗?此操作不可恢复。')) {
allCustomers = allCustomers.filter(customer => customer.id !== id);
searchCustomers();
}
};
// 批量删除客户
const deleteSelectedCustomers = () => {
const selectedCheckboxes = document.querySelectorAll('.row-checkbox:checked');
if (selectedCheckboxes.length === 0) {
alert('请至少选择一个客户进行删除');
return;
}
if (confirm(`确定要删除选中的 ${selectedCheckboxes.length} 个客户吗?此操作不可恢复。`)) {
const selectedIds = Array.from(selectedCheckboxes).map(checkbox => parseInt(checkbox.dataset.id));
allCustomers = allCustomers.filter(customer => !selectedIds.includes(customer.id));
searchCustomers();
selectAllCheckbox.checked = false;
}
};
// 全选/取消全选
const toggleSelectAll = () => {
const rowCheckboxes = document.querySelectorAll('.row-checkbox');
rowCheckboxes.forEach(checkbox => {
checkbox.checked = selectAllCheckbox.checked;
});
};
// 初始化事件监听
document.getElementById('searchButton').addEventListener('click', searchCustomers);
document.getElementById('addCustomerBtn').addEventListener('click', openAddCustomerModal);
document.getElementById('batchDeleteBtn').addEventListener('click', deleteSelectedCustomers);
document.getElementById('refreshBtn').addEventListener('click', () => {
document.getElementById('searchName').value = '';
document.getElementById('searchPhone').value = '';
document.getElementById('searchEmail').value = '';
searchTerm = '';
currentPage = 1;
filteredCustomers = [...allCustomers];
renderCustomerTable();
renderPagination();
});
document.getElementById('closeModal').addEventListener('click', () => {
customerModal.classList.remove('show');
});
document.getElementById('cancelBtn').addEventListener('click', () => {
customerModal.classList.remove('show');
});
document.getElementById('saveCustomerBtn').addEventListener('click', saveCustomer);
selectAllCheckbox.addEventListener('change', toggleSelectAll);
// 表格排序
document.querySelectorAll('.data-table th[data-sort]').forEach(th => {
th.addEventListener('click', () => {
sortCustomers(th.dataset.sort);
});
});
// 事件委托处理编辑和删除操作
document.addEventListener('click', (e) => {
if (e.target.closest('.edit-icon')) {
const customerId = parseInt(e.target.closest('.edit-icon').dataset.id);
openEditCustomerModal(customerId);
}
if (e.target.closest('.delete-icon')) {
const customerId = parseInt(e.target.closest('.delete-icon').dataset.id);
deleteCustomer(customerId);
}
});
// 初始化页面
document.addEventListener('DOMContentLoaded', () => {
renderCustomerTable();
renderPagination();
// 模拟一些搜索关键词
document.getElementById('searchName').value = '张';
searchCustomers();
});
</script>
</body>
</html>