数据库搜索 找到 14 个产品
Product Status:
Operating Temperature:
Mounting Type:
Package / Case:
Type:
Capacitance @ Frequency:
Supplier Device Package:
Unidirectional Channels:
Bidirectional Channels:
Voltage - Reverse Standoff (Typ):
Voltage - Breakdown (Min):
Voltage - Clamping (Max) @ Ipp:
Current - Peak Pulse (10/1000µs):
Power - Peak Pulse:
Power Line Protection:
14 条记录
// 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, selectedProducts: new Set() // 选中的产品ID }; // DOM元素引用 this.elements = {}; // 防抖定时器 this.debounceTimer = null; // 初始化 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; // 设置默认价格范围 this.state.filters.price_max = this.config.max_price || this.options.maxPrice; } 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' }, max_price: this.options.maxPrice }; this.state.filters.price_max = this.options.maxPrice; } } /** 渲染主界面 */ renderUI() { const container = document.querySelector(this.options.container); if (!container) { throw new Error(`容器元素 ${this.options.container} 未找到`); } container.innerHTML = this.generateHTML(); // 保存DOM元素引用 this.cacheElements(); // 渲染属性过滤器 this.renderAttributeFilters(); } /** 生成HTML内容 */ generateHTML() { return `
价格范围 (¥)
-
最小库存
产品属性
已选择 0 个产品
图片 产品型号 品牌 分类 价格 (¥) 库存 状态 操作
`; } /** 生成排序选项 */ generateSortOptions() { return this.config.sort_options.map(option => `` ).join(''); } /** 生成分页大小选项 */ generatePageSizeOptions() { return this.config.page_sizes.map(size => `` ).join(''); } /** 缓存DOM元素引用 */ cacheElements() { this.elements = { container: document.querySelector(this.options.container), searchInput: document.querySelector(`${this.options.container} .search-input`), searchBtn: document.querySelector(`${this.options.container} .search-btn`), sortSelect: document.querySelector(`${this.options.container} .sort-select`), pageSizeSelect: document.querySelector(`${this.options.container} .page-size-select`), priceMin: document.querySelector(`${this.options.container} .price-min`), priceMax: document.querySelector(`${this.options.container} .price-max`), stockMin: document.querySelector(`${this.options.container} .stock-min`), attributeFilters: document.querySelector(`${this.options.container} .attribute-filters`), resetFilters: document.querySelector(`${this.options.container} .reset-filters`), applyFilters: document.querySelector(`${this.options.container} .apply-filters`), productsTbody: document.querySelector(`${this.options.container} #products-tbody`), loadingState: document.querySelector(`${this.options.container} .loading-state`), emptyState: document.querySelector(`${this.options.container} .empty-state`), selectAll: document.querySelector(`${this.options.container} .select-all`), selectedCount: document.querySelector(`${this.options.container} #selected-count`), compareBtn: document.querySelector(`${this.options.container} .compare-products`), exportBtn: document.querySelector(`${this.options.container} .export-selected`), pagination: document.querySelector(`${this.options.container} #pagination`), startRecord: document.querySelector(`${this.options.container} #start-record`), endRecord: document.querySelector(`${this.options.container} #end-record`), totalRecords: document.querySelector(`${this.options.container} #total-records`), resetSearch: document.querySelector(`${this.options.container} .reset-search`) }; } /** 渲染属性过滤器 */ renderAttributeFilters() { if (!this.config.attributes || !this.elements.attributeFilters) return; const attributesHTML = this.config.attributes.map(attr => `
${attr.values.map(value => ` `).join('')}
`).join(''); this.elements.attributeFilters.innerHTML = attributesHTML; } /** 绑定事件 */ bindEvents() { // 搜索相关事件 this.elements.searchInput.addEventListener('input', this.debounce(() => { this.state.keyword = this.elements.searchInput.value.trim(); this.state.page = 1; this.search(); }, this.options.debounceDelay)); this.elements.searchBtn.addEventListener('click', () => { this.state.keyword = this.elements.searchInput.value.trim(); this.state.page = 1; this.search(); }); // 排序和分页大小变化 this.elements.sortSelect.addEventListener('change', () => { this.state.sort = this.elements.sortSelect.value; this.state.page = 1; this.search(); }); this.elements.pageSizeSelect.addEventListener('change', () => { this.options.pageSize = parseInt(this.elements.pageSizeSelect.value); this.state.page = 1; this.search(); }); // 过滤器事件 this.elements.applyFilters.addEventListener('click', () => { this.updateFiltersFromUI(); this.state.page = 1; this.search(); }); this.elements.resetFilters.addEventListener('click', () => { this.resetFilters(); this.search(); }); // 选择相关事件 this.elements.selectAll.addEventListener('change', (e) => { this.toggleSelectAll(e.target.checked); }); // 重置搜索 this.elements.resetSearch?.addEventListener('click', () => { this.resetFilters(); this.elements.searchInput.value = ''; this.state.keyword = ''; this.search(); }); // 键盘事件 this.elements.searchInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { this.state.keyword = this.elements.searchInput.value.trim(); this.state.page = 1; this.search(); } }); } /** 防抖函数 */ debounce(func, delay) { return (...args) => { clearTimeout(this.debounceTimer); this.debounceTimer = setTimeout(() => func.apply(this, args), delay); }; } /** 从UI更新过滤器状态 */ updateFiltersFromUI() { // 价格范围 this.state.filters.price_min = parseInt(this.elements.priceMin.value) || 0; this.state.filters.price_max = parseInt(this.elements.priceMax.value) || this.options.maxPrice; // 库存 this.state.filters.stock_min = parseInt(this.elements.stockMin.value) || 0; // 属性过滤器 const attributeElements = this.elements.attributeFilters.querySelectorAll('.attribute-filter'); this.state.filters.attributes = {}; attributeElements.forEach(attrEl => { const attrId = attrEl.dataset.attrId; const checkedValues = Array.from(attrEl.querySelectorAll('input:checked')) .map(input => input.value); if (checkedValues.length > 0) { this.state.filters.attributes[attrId] = checkedValues; } }); } /** 重置过滤器 */ resetFilters() { this.state.filters = { attributes: {}, price_min: 0, price_max: this.config.max_price || this.options.maxPrice, stock_min: 0 }; // 更新UI this.elements.priceMin.value = ''; this.elements.priceMax.value = this.state.filters.price_max; this.elements.stockMin.value = ''; // 重置属性复选框 const checkboxes = this.elements.attributeFilters.querySelectorAll('input[type="checkbox"]'); checkboxes.forEach(checkbox => checkbox.checked = false); } /** 执行搜索 */ async search() { if (this.state.loading) return; this.setStateLoading(true); try { const searchParams = this.buildSearchParams(); const response = await fetch(this.options.apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(searchParams) }); const result = await response.json(); if (result.code === 200) { this.renderProducts(result.data.products || []); this.updatePagination(result.data.total || 0); this.updateSelectionUI(); } else { throw new Error(result.message || '搜索失败'); } } catch (error) { console.error('搜索失败:', error); this.showError('搜索失败,请稍后重试'); this.renderProducts([]); } finally { this.setStateLoading(false); } } /** 构建搜索参数 */ buildSearchParams() { return { keyword: this.state.keyword, filters: this.state.filters, page: this.state.page, page_size: this.options.pageSize, sort: this.state.sort }; } /** 设置加载状态 */ setStateLoading(loading) { this.state.loading = loading; if (loading) { this.elements.loadingState.style.display = 'block'; this.elements.productsTbody.innerHTML = ''; this.elements.emptyState.style.display = 'none'; } else { this.elements.loadingState.style.display = 'none'; } } /** 渲染产品列表 */ renderProducts(products) { if (products.length === 0) { this.elements.emptyState.style.display = 'block'; this.elements.productsTbody.innerHTML = ''; return; } this.elements.emptyState.style.display = 'none'; const productsHTML = products.map(product => ` ${this.options.showImages && product.image ? `${product.model}` : '
无图
'} ${this.escapeHtml(product.model)} ${this.escapeHtml(product.brand)} ${this.escapeHtml(product.category)} ¥${product.price} ${product.stock} ${product.status === 1 ? '有货' : '缺货'} `).join(''); this.elements.productsTbody.innerHTML = productsHTML; // 绑定产品行事件 this.bindProductEvents(); } /** 绑定产品行事件 */ bindProductEvents() { // 复选框选择 const checkboxes = this.elements.productsTbody.querySelectorAll('.product-checkbox'); checkboxes.forEach(checkbox => { checkbox.addEventListener('change', (e) => { this.toggleProductSelection(e.target.value, e.target.checked); }); }); // 详情按钮 const detailBtns = this.elements.productsTbody.querySelectorAll('.view-detail'); detailBtns.forEach(btn => { btn.addEventListener('click', (e) => { const productId = e.target.dataset.id; this.viewProductDetail(productId); }); }); // 加入询价按钮 const cartBtns = this.elements.productsTbody.querySelectorAll('.add-to-cart'); cartBtns.forEach(btn => { btn.addEventListener('click', (e) => { const productId = e.target.dataset.id; this.addToInquiry(productId); }); }); } /** 切换产品选择状态 */ toggleProductSelection(productId, selected) { if (selected) { this.state.selectedProducts.add(productId); } else { this.state.selectedProducts.delete(productId); this.elements.selectAll.checked = false; } this.updateSelectionUI(); // 更新行样式 const row = this.elements.productsTbody.querySelector(`tr[data-product-id="${productId}"]`); if (row) { row.classList.toggle('selected', selected); } } /** 全选/取消全选 */ toggleSelectAll(selectAll) { const checkboxes = this.elements.productsTbody.querySelectorAll('.product-checkbox'); checkboxes.forEach(checkbox => { checkbox.checked = selectAll; this.toggleProductSelection(checkbox.value, selectAll); }); } /** 更新选择状态UI */ updateSelectionUI() { const selectedCount = this.state.selectedProducts.size; this.elements.selectedCount.textContent = `已选择 ${selectedCount} 个产品`; // 更新按钮状态 this.elements.compareBtn.disabled = selectedCount === 0; this.elements.exportBtn.disabled = selectedCount === 0; // 更新全选复选框状态 const totalProducts = this.elements.productsTbody.querySelectorAll('.product-checkbox').length; this.elements.selectAll.checked = selectedCount > 0 && selectedCount === totalProducts; this.elements.selectAll.indeterminate = selectedCount > 0 && selectedCount < totalProducts; } /** 更新分页 */ updatePagination(total) { this.state.total = total; this.state.totalPages = Math.ceil(total / this.options.pageSize); // 更新记录信息 const startRecord = total === 0 ? 0 : (this.state.page - 1) * this.options.pageSize + 1; const endRecord = Math.min(this.state.page * this.options.pageSize, total); this.elements.startRecord.textContent = startRecord; this.elements.endRecord.textContent = endRecord; this.elements.totalRecords.textContent = total; // 渲染分页按钮 this.renderPaginationButtons(); } /** 渲染分页按钮 */ renderPaginationButtons() { if (this.state.totalPages <= 1) { this.elements.pagination.innerHTML = ''; return; } let paginationHTML = ''; const currentPage = this.state.page; const totalPages = this.state.totalPages; // 上一页 paginationHTML += `
  • 上一页
  • `; // 页码按钮 const showPages = 5; // 显示的页码数量 let startPage = Math.max(1, currentPage - Math.floor(showPages / 2)); let endPage = Math.min(totalPages, startPage + showPages - 1); if (endPage - startPage + 1 < showPages) { startPage = Math.max(1, endPage - showPages + 1); } for (let i = startPage; i <= endPage; i++) { paginationHTML += `
  • ${i}
  • `; } // 下一页 paginationHTML += `
  • 下一页
  • `; this.elements.pagination.innerHTML = paginationHTML; // 绑定分页事件 this.bindPaginationEvents(); } /** 绑定分页事件 */ bindPaginationEvents() { const pageLinks = this.elements.pagination.querySelectorAll('.page-link'); pageLinks.forEach(link => { link.addEventListener('click', (e) => { e.preventDefault(); const page = parseInt(e.target.dataset.page); if (page >= 1 && page <= this.state.totalPages && page !== this.state.page) { this.state.page = page; this.search(); } }); }); } /** 查看产品详情 */ viewProductDetail(productId) { // 这里可以跳转到产品详情页或打开模态框 console.log('查看产品详情:', productId); // window.open(`/product/detail/${productId}`, '_blank'); } /** 加入询价单 */ addToInquiry(productId) { // 这里可以实现加入询价单的逻辑 console.log('加入询价单:', productId); this.showSuccess('产品已加入询价单'); } /** 显示成功消息 */ showSuccess(message) { // 可以使用Toast或其他UI组件 alert(`成功: ${message}`); } /** 显示错误消息 */ showError(message) { // 可以使用Toast或其他UI组件 alert(`错误: ${message}`); } /** HTML转义 */ escapeHtml(unsafe) { if (!unsafe) return ''; return unsafe .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } /** 获取选中的产品ID */ getSelectedProducts() { return Array.from(this.state.selectedProducts); } /** 清空选中状态 */ clearSelection() { this.state.selectedProducts.clear(); this.updateSelectionUI(); // 更新所有复选框 const checkboxes = this.elements.productsTbody.querySelectorAll('.product-checkbox'); checkboxes.forEach(checkbox => checkbox.checked = false); // 更新行样式 const rows = this.elements.productsTbody.querySelectorAll('tr'); rows.forEach(row => row.classList.remove('selected')); } /** 销毁实例 */ destroy() { // 清理事件监听器和其他资源 clearTimeout(this.debounceTimer); // 可以根据需要添加更多清理逻辑 } } // CSS样式(可以放在单独的CSS文件中) const selectionTableStyles = ` .selection-table-container { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } .selection-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding: 15px; background: #f8f9fa; border-radius: 5px; } .search-section { flex: 1; max-width: 400px; } .filter-panel { background: white; border: 1px solid #dee2e6; border-radius: 5px; padding: 15px; margin-bottom: 20px; } .filter-section { margin-bottom: 15px; } .filter-section h6 { margin-bottom: 8px; color: #495057; font-weight: 600; } .price-filter { display: flex; align-items: center; gap: 10px; } .price-filter input { width: 100px; } .attribute-values { display: flex; flex-wrap: wrap; gap: 10px; } .attribute-value-checkbox { display: flex; align-items: center; margin-right: 15px; } .attribute-value-checkbox input { margin-right: 5px; } .filter-actions { display: flex; gap: 10px; margin-top: 15px; } .products-table-section { background: white; border-radius: 5px; } .table-header { display: flex; justify-content: space-between; align-items: center; padding: 15px; border-bottom: 1px solid #dee2e6; } .product-image { width: 50px; height: 50px; object-fit: contain; } .no-image { width: 50px; height: 50px; background: #f8f9fa; display: flex; align-items: center; justify-content: center; color: #6c757d; font-size: 12px; } .status-badge { padding: 3px 8px; border-radius: 3px; font-size: 12px; } .status-badge.in-stock { background: #d4edda; color: #155724; } .status-badge.out-of-stock { background: #f8d7da; color: #721c24; } .low-stock { color: #dc3545; font-weight: bold; } tr.selected { background-color: #e3f2fd !important; } .loading-state, .empty-state { text-align: center; padding: 40px; color: #6c757d; } .pagination-container { display: flex; justify-content: space-between; align-items: center; padding: 15px; border-top: 1px solid #dee2e6; } @media (max-width: 768px) { .selection-toolbar { flex-direction: column; gap: 15px; } .search-section { max-width: 100%; } .table-header { flex-direction: column; gap: 10px; align-items: flex-start; } .pagination-container { flex-direction: column; gap: 15px; } } `; // 将样式添加到页面 if (!document.querySelector('#selection-table-styles')) { const styleEl = document.createElement('style'); styleEl.id = 'selection-table-styles'; styleEl.textContent = selectionTableStyles; document.head.appendChild(styleEl); } // 导出类 if (typeof module !== 'undefined' && module.exports) { module.exports = SelectionTable; } else { window.SelectionTable = SelectionTable; }