数据库搜索 找到 7 个产品
7 条记录
// selection-table.js - 完整实现 class SelectionTable { constructor(options) { // 默认配置 this.options = Object.assign({ apiUrl: '/product/selection/search', configUrl: '/product/selection/config', container: '#selection-table', pageSize: 50, debounceDelay: 300, maxPrice: 10000, // 最大价格限制 showImages: true // 是否显示产品图片 }, options); // 状态管理 this.state = { keyword: '', filters: { attributes: {}, price_min: 0, price_max: 0, stock_min: 0 }, page: 1, sort: 'relevance', loading: false, total: 0, totalPages: 0 }; // DOM元素引用 this.elements = {}; // 初始化 this.init(); } /** * 初始化选型表 */ async init() { try { // 加载配置 await this.loadConfig(); // 渲染UI this.renderUI(); // 绑定事件 this.bindEvents(); // 执行初始搜索 await this.search(); } catch (error) { console.error('选型表初始化失败:', error); this.showError('选型表初始化失败,请刷新页面重试'); } } /** * 加载配置信息 */ async loadConfig() { try { const response = await fetch(this.options.configUrl); const result = await response.json(); if (result.code === 200) { this.config = result.data; } else { throw new Error(result.message || '配置加载失败'); } } catch (error) { console.error('加载配置失败:', error); // 使用默认配置 this.config = { attributes: [], sort_options: [ { value: 'relevance', label: '相关性' }, { value: 'price_asc', label: '价格从低到高' }, { value: 'price_desc', label: '价格从高到低' }, { value: 'stock_desc', label: '库存从多到少' }, { value: 'newest', label: '最新上架' } ], page_sizes: [20, 50, 100], defaults: { page_size: 50, sort: 'relevance' } }; } } /** * 渲染主界面 */ renderUI() { const container = document.querySelector(this.options.container); if (!container) { throw new Error(`容器元素 ${this.options.container} 未找到`); } container.innerHTML = this.generateHTML(); // 保存DOM元素引用 this.cacheElements(); } /** * 生成HTML内容 */ generateHTML() { return `
-

选型属性筛选

${this.renderAttributeFilters()}
找到 0 个产品
产品图片 型号 品牌 描述 价格 库存 操作
1 页,共 0
已选产品 (0)
`; } /** * 缓存DOM元素引用 */ cacheElements() { this.elements = { container: document.querySelector(this.options.container), keywordInput: document.querySelector('.keyword-input'), searchBtn: document.querySelector('.search-btn'), clearBtn: document.querySelector('.clear-btn'), priceMin: document.querySelector('.price-min'), priceMax: document.querySelector('.price-max'), stockMin: document.querySelector('.stock-min'), sortSelect: document.querySelector('.sort-select'), pageSizeSelect: document.querySelector('.page-size-select'), productsGrid: document.querySelector('.products-grid .products-container'), productsList: document.querySelector('.products-list tbody'), pagination: document.querySelector('.pagination-container'), loadingSection: document.querySelector('.loading-section'), errorSection: document.querySelector('.error-section'), emptySection: document.querySelector('.empty-section'), totalCount: document.querySelector('.total-count'), currentPage: document.querySelector('.current-page'), totalPages: document.querySelector('.total-pages'), searchTime: document.querySelector('.search-time'), timeValue: document.querySelector('.time-value') }; } /** * 渲染属性筛选器 */ renderAttributeFilters() { if (!this.config || !this.config.attributes) { return '
暂无属性筛选配置
'; } return this.config.attributes.map(attr => `
${attr.type === 'range' ? this.renderRangeAttribute(attr) : this.renderOptionsAttribute(attr)}
`).join(''); } /** * 渲染范围类型属性 */ renderRangeAttribute(attr) { return `
${attr.unit ? `${attr.unit}` : ''}
`; } /** * 渲染选项类型属性 */ renderOptionsAttribute(attr) { if (!attr.options || attr.options.length === 0) { return '
暂无选项
'; } const optionsHTML = attr.options.map(option => ` `).join(''); return `
${optionsHTML}
`; } /** * 渲染排序选项 */ renderSortOptions() { if (!this.config || !this.config.sort_options) { return ` `; } return this.config.sort_options.map(option => ` `).join(''); } /** * 渲染分页大小选项 */ renderPageSizeOptions() { const sizes = this.config?.page_sizes || [20, 50, 100]; return sizes.map(size => ` `).join(''); } /** * 绑定事件监听器 */ bindEvents() { // 搜索相关事件 this.bindSearchEvents(); // 筛选相关事件 this.bindFilterEvents(); // 分页和排序事件 this.bindControlEvents(); // 视图切换事件 this.bindViewEvents(); } /** * 绑定搜索事件 */ bindSearchEvents() { const { keywordInput, searchBtn, clearBtn } = this.elements; // 关键词输入防抖搜索 keywordInput.addEventListener('input', this.debounce(() => { this.state.keyword = keywordInput.value.trim(); this.state.page = 1; this.search(); }, this.options.debounceDelay)); // 搜索按钮点击 searchBtn.addEventListener('click', () => { this.state.keyword = keywordInput.value.trim(); this.state.page = 1; this.search(); }); // 回车键搜索 keywordInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { this.state.keyword = keywordInput.value.trim(); this.state.page = 1; this.search(); } }); // 清除搜索 clearBtn.addEventListener('click', () => { keywordInput.value = ''; this.state.keyword = ''; this.state.page = 1; this.search(); }); } /** * 绑定筛选事件 */ bindFilterEvents() { // 价格范围筛选 this.elements.priceMin.addEventListener('input', this.debounce(() => { this.state.filters.price_min = parseFloat(this.elements.priceMin.value) || 0; this.state.page = 1; this.search(); }, 500)); this.elements.priceMax.addEventListener('input', this.debounce(() => { this.state.filters.price_max = parseFloat(this.elements.priceMax.value) || 0; this.state.page = 1; this.search(); }, 500)); // 库存筛选 this.elements.stockMin.addEventListener('input', this.debounce(() => { this.state.filters.stock_min = parseInt(this.elements.stockMin.value) || 0; this.state.page = 1; this.search(); }, 500)); // 属性筛选 document.querySelectorAll('.attribute-option').forEach(option => { option.addEventListener('change', () => { this.updateAttributeFilters(); this.state.page = 1; this.search(); }); }); // 属性组展开/收起 document.querySelectorAll('.attribute-toggle').forEach(toggle => { toggle.addEventListener('click', (e) => { const group = e.target.closest('.attribute-filter-group'); const options = group.querySelector('.attribute-options'); const icon = group.querySelector('.attribute-toggle i'); options.classList.toggle('collapsed'); icon.classList.toggle('fa-chevron-down'); icon.classList.toggle('fa-chevron-up'); }); }); } /** * 绑定控制事件 */ bindControlEvents() { // 排序变化 this.elements.sortSelect.addEventListener('change', (e) => { this.state.sort = e.target.value; this.state.page = 1; this.search(); }); // 分页大小变化 this.elements.pageSizeSelect.addEventListener('change', (e) => { this.options.pageSize = parseInt(e.target.value); this.state.page = 1; this.search(); }); } /** * 绑定视图事件 */ bindViewEvents() { // 视图切换 document.querySelectorAll('.view-btn').forEach(btn => { btn.addEventListener('click', (e) => { // 移除所有激活状态 document.querySelectorAll('.view-btn').forEach(b => b.classList.remove('active')); document.querySelectorAll('.view-content').forEach(c => c.classList.remove('active')); // 激活当前视图 e.target.classList.add('active'); const viewType = e.target.classList.contains('grid-view') ? 'grid' : 'list'; document.querySelector(`.products-${viewType}`).classList.add('active'); }); }); } /** * 更新属性筛选状态 */ updateAttributeFilters() { this.state.filters.attributes = {}; document.querySelectorAll('.attribute-filter-group').forEach(group => { const attributeKey = group.dataset.attribute; const selectedOptions = this.getSelectedAttributeOptions(group); if (selectedOptions.length > 0) { this.state.filters.attributes[attributeKey] = selectedOptions; } }); } /** * 获取选中的属性选项 */ getSelectedAttributeOptions(group) { const checkboxes = group.querySelectorAll('input[type="checkbox"]:checked'); const radios = group.querySelectorAll('input[type="radio"]:checked'); const selected = []; checkboxes.forEach(cb => selected.push(cb.value)); radios.forEach(radio => selected.push(radio.value)); return selected; } /** * 执行搜索 */ async search() { if (this.state.loading) return; this.state.loading = true; this.showLoading(); this.hideError(); this.hideEmpty(); const startTime = Date.now(); try { // 构建请求参数 const params = this.buildSearchParams(); // 发送搜索请求 const response = await fetch(`${this.options.apiUrl}?${params}`); const result = await response.json(); const searchTime = (Date.now() - startTime) / 1000; if (result.code === 200) { this.handleSearchSuccess(result.data, searchTime); } else { this.handleSearchError(result.message); } } catch (error) { this.handleSearchError('网络请求失败,请检查网络连接'); console.error('搜索错误:', error); } finally { this.state.loading = false; this.hideLoading(); } } /** * 构建搜索参数 */ buildSearchParams() { const params = new URLSearchParams({ keyword: this.state.keyword, page: this.state.page, page_size: this.options.pageSize, sort: this.state.sort }); // 添加基础过滤器 if (this.state.filters.price_min > 0) { params.append('price_min', this.state.filters.price_min); } if (this.state.filters.price_max > 0) { params.append('price_max', this.state.filters.price_max); } if (this.state.filters.stock_min > 0) { params.append('stock_min', this.state.filters.stock_min); } // 添加属性过滤器 if (Object.keys(this.state.filters.attributes).length > 0) { params.append('attributes', JSON.stringify(this.state.filters.attributes)); } return params; } /** * 处理搜索成功 */ handleSearchSuccess(data, searchTime) { this.state.total = data.summary?.total || 0; this.state.totalPages = Math.ceil(this.state.total / this.options.pageSize); // 更新UI this.updateSummary(data.summary, searchTime); this.renderProducts(data.products); this.renderPagination(); // 显示/隐藏空结果提示 if (this.state.total === 0) { this.showEmpty(); } else { this.hideEmpty(); } // 更新属性计数 this.updateAttributeCounts(data.summary?.attributes_summary); } /** * 处理搜索错误 */ handleSearchError(message) { this.showError(message); this.elements.productsGrid.innerHTML = ''; this.elements.productsList.innerHTML = ''; this.elements.pagination.innerHTML = ''; this.updateSummary({ total: 0 }, 0); } /** * 更新摘要信息 */ updateSummary(summary, searchTime) { this.elements.totalCount.textContent = summary.total?.toLocaleString() || '0'; this.elements.currentPage.textContent = this.state.page; this.elements.totalPages.textContent = this.state.totalPages; if (searchTime > 0) { this.elements.timeValue.textContent = searchTime.toFixed(2); this.elements.searchTime.style.display = 'inline'; } else { this.elements.searchTime.style.display = 'none'; } } /** * 渲染产品列表 */ renderProducts(products) { this.renderGridView(products); this.renderListView(products); } /** * 渲染网格视图 */ renderGridView(products) { if (!products || products.length === 0) { this.elements.productsGrid.innerHTML = ''; return; } const productsHTML = products.map(product => this.generateProductCard(product)).join(''); this.elements.productsGrid.innerHTML = productsHTML; // 绑定产品卡片事件 this.bindProductEvents(); } /** * 渲染列表视图 */ renderListView(products) { if (!products || products.length === 0) { this.elements.productsList.innerHTML = ''; return; } const rowsHTML = products.map(product => this.generateProductRow(product)).join(''); this.elements.productsList.innerHTML = rowsHTML; // 绑定产品行事件 this.bindProductEvents(); } /** * 生成产品卡片HTML */ generateProductCard(product) { return `
${product.part}

${product.part}

${product.brand}
${product.description || '暂无描述'}
${this.renderProductAttributes(product.attributes)}
¥${(product.price || 0).toFixed(2)}
库存: ${product.stock || 0}
`; } /** * 生成产品行HTML */ generateProductRow(product) { return ` ${product.part} ${product.part} ${product.brand} ${product.description || '暂无描述'} ¥${(product.price || 0).toFixed(2)} ${product.stock || 0} `; } /** * 渲染产品属性 */ renderProductAttributes(attributes) { if (!attributes || Object.keys(attributes).length === 0) { return '
暂无属性信息
'; } return Object.entries(attributes).map(([key, value]) => `
${key}: ${value}
`).join(''); } /** * 绑定产品事件 */ bindProductEvents() { // 加入询价按钮 document.querySelectorAll('.add-to-cart').forEach(btn => { btn.addEventListener('click', (e) => { const productId = e.target.dataset.id; this.addToInquiry(productId); }); }); // 查看详情按钮 document.querySelectorAll('.view-details').forEach(btn => { btn.addEventListener('click', (e) => { const productId = e.target.dataset.id; this.viewProductDetails(productId); }); }); // 加入对比按钮 document.querySelectorAll('.compare-add-btn, .compare-add').forEach(btn => { btn.addEventListener('click', (e) => { const productId = e.target.closest('button').dataset.id; this.addToComparison(productId); }); }); } /** * 渲染分页 */ renderPagination() { if (this.state.totalPages <= 1) { this.elements.pagination.innerHTML = ''; return; } const paginationHTML = this.generatePaginationHTML(); this.elements.pagination.innerHTML = paginationHTML; // 绑定分页事件 this.bindPaginationEvents(); } /** * 生成分页HTML */ generatePaginationHTML() { const currentPage = this.state.page; const totalPages = this.state.totalPages; const pages = []; // 总是显示第一页 pages.push(this.generatePageItem(1, currentPage === 1)); // 计算显示的页码范围 let startPage = Math.max(2, currentPage - 2); let endPage = Math.min(totalPages - 1, currentPage + 2); // 添加省略号 if (startPage > 2) { pages.push('...'); } // 添加中间页码 for (let i = startPage; i <= endPage; i++) { pages.push(this.generatePageItem(i, i === currentPage)); } // 添加末尾省略号 if (endPage < totalPages - 1) { pages.push('...'); } // 总是显示最后一页 if (totalPages > 1) { pages.push(this.generatePageItem(totalPages, currentPage === totalPages)); } // 添加上一页/下一页 const prevDisabled = currentPage === 1 ? 'disabled' : ''; const nextDisabled = currentPage === totalPages ? 'disabled' : ''; return `
${pages.join('')}
`; } /** * 生成页码项 */ generatePageItem(page, isActive) { const activeClass = isActive ? 'active' : ''; return ``; } /** * 绑定分页事件 */ bindPaginationEvents() { // 页码点击 document.querySelectorAll('.page-number').forEach(btn => { btn.addEventListener('click', (e) => { const page = parseInt(e.target.dataset.page); this.goToPage(page); }); }); // 上一页/下一页 document.querySelector('.prev-page').addEventListener('click', () => { if (this.state.page > 1) { this.goToPage(this.state.page - 1); } }); document.querySelector('.next-page').addEventListener('click', () => { if (this.state.page < this.state.totalPages) { this.goToPage(this.state.page + 1); } }); } /** * 跳转到指定页面 */ goToPage(page) { this.state.page = page; this.search(); // 滚动到顶部 this.elements.container.scrollIntoView({ behavior: 'smooth' }); } /** * 更新属性计数 */ updateAttributeCounts(attributeSummary) { if (!attributeSummary) return; Object.entries(attributeSummary).forEach(([attrKey, values]) => { Object.entries(values).forEach(([value, count]) => { const countElement = document.querySelector( `.attribute-option[value="${value}"] + .option-count` ); if (countElement) { countElement.textContent = `(${count})`; countElement.style.display = 'inline'; } }); }); } /** * 加入询价车 */ addToInquiry(productId) { // 这里可以集成现有的询价车功能 console.log('加入询价:', productId); this.showMessage('产品已加入询价车', 'success'); } /** * 查看产品详情 */ viewProductDetails(productId) { // 跳转到产品详情页 window.open(`/product/detail/${productId}`, '_blank'); } /** * 加入对比 */ addToComparison(productId) { // 实现产品对比功能 console.log('加入对比:', productId); this.showMessage('产品已加入对比', 'success'); } /** * 显示加载状态 */ showLoading() { this.elements.loadingSection.style.display = 'block'; this.elements.productsGrid.style.opacity = '0.5'; } /** * 隐藏加载状态 */ hideLoading() { this.elements.loadingSection.style.display = 'none'; this.elements.productsGrid.style.opacity = '1'; } /** * 显示错误信息 */ showError(message) { this.elements.errorSection.style.display = 'block'; this.elements.errorSection.querySelector('.error-text').textContent = message; } /** * 隐藏错误信息 */ hideError() { this.elements.errorSection.style.display = 'none'; } /** * 显示空结果 */ showEmpty() { this.elements.emptySection.style.display = 'block'; } /** * 隐藏空结果 */ hideEmpty() { this.elements.emptySection.style.display = 'none'; } /** * 显示消息提示 */ showMessage(message, type = 'info') { // 实现消息提示功能 const messageDiv = document.createElement('div'); messageDiv.className = `message message-${type}`; messageDiv.innerHTML = ` ${message} `; document.body.appendChild(messageDiv); setTimeout(() => { messageDiv.remove(); }, 3000); } /** * 防抖函数 */ debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } /** * 销毁实例 */ destroy() { // 清理事件监听器 // 这里可以根据需要添加具体的清理逻辑 console.log('SelectionTable实例已销毁'); } } // 导出到全局作用域 window.SelectionTable = SelectionTable;