426 lines
14 KiB
JavaScript
426 lines
14 KiB
JavaScript
// 搜索页面逻辑
|
|
const searchPage = {
|
|
// 搜索参数
|
|
keyword: '',
|
|
filters: {
|
|
priceMin: null,
|
|
priceMax: null
|
|
},
|
|
sortBy: 'default',
|
|
sortType: 'desc',
|
|
currentPage: 1,
|
|
itemsPerPage: 20,
|
|
totalCount: 0,
|
|
|
|
// 初始化
|
|
init() {
|
|
console.log('=== 搜索页面初始化 ===');
|
|
|
|
// 从URL获取搜索关键词
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
this.keyword = urlParams.get('q') || '';
|
|
|
|
console.log('搜索关键词:', this.keyword);
|
|
|
|
if (!this.keyword) {
|
|
// 如果没有搜索关键词,跳转回首页
|
|
console.warn('没有搜索关键词,跳转到首页');
|
|
window.location.href = 'index.html';
|
|
return;
|
|
}
|
|
|
|
// 显示搜索关键词
|
|
$('#searchKeyword').text(this.keyword);
|
|
$('#searchInput').val(this.keyword);
|
|
|
|
// 绑定事件
|
|
this.bindEvents();
|
|
|
|
// 执行搜索
|
|
this.search();
|
|
|
|
// 加载购物车数量
|
|
this.loadCartCount();
|
|
},
|
|
|
|
// 绑定事件
|
|
bindEvents() {
|
|
// 排序选择
|
|
$('#sortSelect').on('change', (e) => {
|
|
const value = $(e.target).val();
|
|
this.handleSort(value);
|
|
});
|
|
|
|
// 应用筛选
|
|
$('.apply-filter').on('click', () => {
|
|
this.applyFilters();
|
|
});
|
|
|
|
// 清除筛选
|
|
$('.clear-filter').on('click', () => {
|
|
this.clearFilters();
|
|
});
|
|
|
|
// 价格输入框回车
|
|
$('#priceMin, #priceMax').on('keypress', (e) => {
|
|
if (e.which === 13) {
|
|
this.applyFilters();
|
|
}
|
|
});
|
|
|
|
// 分页按钮
|
|
$(document).on('click', '.page-btn.prev', () => {
|
|
if (this.currentPage > 1) {
|
|
this.currentPage--;
|
|
this.search();
|
|
}
|
|
});
|
|
|
|
$(document).on('click', '.page-btn.next', () => {
|
|
const totalPages = Math.ceil(this.totalCount / this.itemsPerPage);
|
|
if (this.currentPage < totalPages) {
|
|
this.currentPage++;
|
|
this.search();
|
|
}
|
|
});
|
|
|
|
$(document).on('click', '.page-num', (e) => {
|
|
const page = parseInt($(e.target).data('page'));
|
|
if (page && page !== this.currentPage) {
|
|
this.currentPage = page;
|
|
this.search();
|
|
}
|
|
});
|
|
|
|
// 搜索按钮
|
|
$('.search-btn').on('click', () => {
|
|
this.performNewSearch();
|
|
});
|
|
|
|
// 搜索框回车
|
|
$('#searchInput').on('keypress', (e) => {
|
|
if (e.which === 13) {
|
|
this.performNewSearch();
|
|
}
|
|
});
|
|
},
|
|
|
|
// 执行新搜索
|
|
performNewSearch() {
|
|
const newKeyword = $('#searchInput').val().trim();
|
|
if (newKeyword && newKeyword !== this.keyword) {
|
|
window.location.href = `search.html?q=${encodeURIComponent(newKeyword)}`;
|
|
}
|
|
},
|
|
|
|
// 处理排序
|
|
handleSort(sortValue) {
|
|
console.log('排序选择:', sortValue);
|
|
|
|
switch (sortValue) {
|
|
case 'price_asc':
|
|
this.sortBy = 'price';
|
|
this.sortType = 'asc';
|
|
break;
|
|
case 'price_desc':
|
|
this.sortBy = 'price';
|
|
this.sortType = 'desc';
|
|
break;
|
|
case 'sales_desc':
|
|
this.sortBy = 'sales';
|
|
this.sortType = 'desc';
|
|
break;
|
|
default:
|
|
this.sortBy = 'default';
|
|
this.sortType = 'desc';
|
|
}
|
|
|
|
this.currentPage = 1;
|
|
this.search();
|
|
},
|
|
|
|
// 应用筛选
|
|
applyFilters() {
|
|
const minPrice = parseFloat($('#priceMin').val()) || null;
|
|
const maxPrice = parseFloat($('#priceMax').val()) || null;
|
|
|
|
// 验证价格范围
|
|
if (minPrice !== null && maxPrice !== null && minPrice > maxPrice) {
|
|
Toast.show({
|
|
type: 'error',
|
|
message: i18n.t('error_price_range')
|
|
});
|
|
return;
|
|
}
|
|
|
|
this.filters.priceMin = minPrice;
|
|
this.filters.priceMax = maxPrice;
|
|
this.currentPage = 1;
|
|
|
|
console.log('应用筛选:', this.filters);
|
|
this.search();
|
|
},
|
|
|
|
// 清除筛选
|
|
clearFilters() {
|
|
this.filters.priceMin = null;
|
|
this.filters.priceMax = null;
|
|
$('#priceMin').val('');
|
|
$('#priceMax').val('');
|
|
this.currentPage = 1;
|
|
|
|
console.log('清除筛选');
|
|
this.search();
|
|
},
|
|
|
|
// 执行搜索
|
|
search() {
|
|
console.log('执行搜索:', {
|
|
keyword: this.keyword,
|
|
page: this.currentPage,
|
|
filters: this.filters,
|
|
sort: this.sortBy,
|
|
sortType: this.sortType
|
|
});
|
|
|
|
// 显示加载状态
|
|
$('#productGrid').html('<div class="loading">加载中...</div>');
|
|
|
|
// 构建API参数
|
|
const params = {
|
|
keyword: this.keyword,
|
|
page: this.currentPage,
|
|
page_size: this.itemsPerPage
|
|
};
|
|
|
|
// 添加价格筛选参数(元转分)
|
|
if (this.filters.priceMin !== null) {
|
|
params.min_price = Math.round(this.filters.priceMin * 100);
|
|
}
|
|
if (this.filters.priceMax !== null) {
|
|
params.max_price = Math.round(this.filters.priceMax * 100);
|
|
}
|
|
|
|
// 添加排序参数
|
|
if (this.sortBy !== 'default') {
|
|
params.sort_by = this.sortBy;
|
|
params.sort_order = this.sortType;
|
|
}
|
|
|
|
// 调用搜索API
|
|
API.get('/products/search', params)
|
|
.then(data => {
|
|
console.log('搜索结果:', data);
|
|
|
|
if (data && data.list) {
|
|
this.totalCount = data.total || 0;
|
|
this.renderProducts(data.list);
|
|
this.updateProductCount();
|
|
this.renderPagination();
|
|
} else {
|
|
this.totalCount = 0;
|
|
this.renderEmptyState();
|
|
}
|
|
|
|
// 滚动到顶部
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
})
|
|
.catch(error => {
|
|
console.error('搜索失败:', error);
|
|
Toast.show({
|
|
type: 'error',
|
|
message: error.message || i18n.t('error_load_products')
|
|
});
|
|
this.renderEmptyState();
|
|
});
|
|
},
|
|
|
|
// 渲染商品列表 (与product-list.js保持一致)
|
|
renderProducts(products) {
|
|
const lang = i18n.currentLang;
|
|
|
|
if (!products || products.length === 0) {
|
|
this.renderEmptyState();
|
|
return;
|
|
}
|
|
|
|
const productsHtml = products.map(product => {
|
|
const productName = this.getProductName(product, lang) || '未知商品';
|
|
const productImage = product.main_image || 'https://picsum.photos/400/400?random=default';
|
|
|
|
// 价格处理 - 后端API返回的是分,需要转换为元
|
|
const price = (product.price || 0) / 100;
|
|
const originalPrice = product.orig_price ? (product.orig_price / 100) : null;
|
|
const isInStock = product.stock > 0;
|
|
|
|
// 计算折扣
|
|
let discount = 0;
|
|
if (originalPrice && originalPrice > price) {
|
|
discount = Math.round((1 - price / originalPrice) * 100);
|
|
}
|
|
|
|
return `
|
|
<div class="product-card" data-product-id="${product.id}">
|
|
<div class="product-image">
|
|
<a href="product-detail.html?id=${product.id}">
|
|
<img src="${productImage}" alt="${productName}" loading="lazy">
|
|
</a>
|
|
${!isInStock ? '<span class="badge badge-sold-out">' + i18n.t('out_of_stock') + '</span>' : ''}
|
|
${discount > 0 ? `<span class="badge badge-sale">-${discount}%</span>` : ''}
|
|
</div>
|
|
<div class="product-info">
|
|
<h3 class="product-title">
|
|
<a href="product-detail.html?id=${product.id}">${productName}</a>
|
|
</h3>
|
|
<div class="product-price">
|
|
<span class="price-current">¥${price.toFixed(2)}</span>
|
|
${originalPrice ? `<span class="price-original">¥${originalPrice.toFixed(2)}</span>` : ''}
|
|
</div>
|
|
<button class="btn btn-primary add-to-cart-btn" data-product-id="${product.id}" ${!isInStock ? 'disabled' : ''}>
|
|
${isInStock ? '<span>' + i18n.t('add_to_cart') + '</span>' : '<span>' + i18n.t('out_of_stock') + '</span>'}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}).join('');
|
|
|
|
$('#productGrid').html(productsHtml);
|
|
|
|
// 绑定加入购物车事件
|
|
this.bindProductEvents();
|
|
},
|
|
|
|
// 渲染空状态 (与product-list.js保持一致)
|
|
renderEmptyState() {
|
|
$('#productGrid').html(`
|
|
<div class="empty-state">
|
|
<div class="empty-icon">
|
|
<svg width="120" height="120" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<circle cx="60" cy="60" r="50" fill="#F5F5F5"/>
|
|
<path d="M40 50 L50 60 L40 70 M80 50 L70 60 L80 70 M55 45 L65 75" stroke="#CCCCCC" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
|
|
</svg>
|
|
</div>
|
|
<h3 class="empty-title">${i18n.t('search_no_results')}</h3>
|
|
<p class="empty-desc">${i18n.t('search_try_again')}</p>
|
|
<a href="home.html" class="btn btn-primary empty-btn">${i18n.t('browse_all_products')}</a>
|
|
</div>
|
|
`);
|
|
|
|
$('.pagination').hide();
|
|
},
|
|
|
|
// 更新商品计数
|
|
updateProductCount() {
|
|
$('#productCount').text(this.totalCount);
|
|
},
|
|
|
|
// 渲染分页 (与product-list.js保持一致)
|
|
renderPagination() {
|
|
const totalPages = Math.ceil(this.totalCount / this.itemsPerPage);
|
|
|
|
if (totalPages <= 1) {
|
|
$('.pagination').hide();
|
|
return;
|
|
}
|
|
|
|
$('.pagination').show();
|
|
|
|
// 更新上一页按钮状态
|
|
$('.page-btn.prev').prop('disabled', this.currentPage === 1);
|
|
|
|
// 更新下一页按钮状态
|
|
$('.page-btn.next').prop('disabled', this.currentPage === totalPages);
|
|
|
|
// 渲染页码
|
|
let pagesHtml = '';
|
|
const maxPages = 7;
|
|
let startPage = Math.max(1, this.currentPage - Math.floor(maxPages / 2));
|
|
let endPage = Math.min(totalPages, startPage + maxPages - 1);
|
|
|
|
if (endPage - startPage < maxPages - 1) {
|
|
startPage = Math.max(1, endPage - maxPages + 1);
|
|
}
|
|
|
|
if (startPage > 1) {
|
|
pagesHtml += `<button class="page-num" data-page="1">1</button>`;
|
|
if (startPage > 2) {
|
|
pagesHtml += `<span class="page-dots">...</span>`;
|
|
}
|
|
}
|
|
|
|
for (let i = startPage; i <= endPage; i++) {
|
|
pagesHtml += `<button class="page-num ${i === this.currentPage ? 'active' : ''}" data-page="${i}">${i}</button>`;
|
|
}
|
|
|
|
if (endPage < totalPages) {
|
|
if (endPage < totalPages - 1) {
|
|
pagesHtml += `<span class="page-dots">...</span>`;
|
|
}
|
|
pagesHtml += `<button class="page-num" data-page="${totalPages}">${totalPages}</button>`;
|
|
}
|
|
|
|
$('.page-numbers').html(pagesHtml);
|
|
},
|
|
|
|
// 绑定商品事件
|
|
bindProductEvents() {
|
|
$('.add-to-cart-btn').off('click').on('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
const productId = $(e.currentTarget).data('product-id');
|
|
this.addToCart(productId);
|
|
});
|
|
},
|
|
|
|
// 加入购物车
|
|
addToCart(productId) {
|
|
console.log('加入购物车:', productId);
|
|
|
|
// 检查是否登录
|
|
if (!cart.isLoggedIn()) {
|
|
Toast.warning(i18n.t('please_login_first'));
|
|
setTimeout(() => {
|
|
window.location.href = 'login.html?redirect=' + encodeURIComponent(window.location.href);
|
|
}, 1500);
|
|
return;
|
|
}
|
|
|
|
// 调用购物车API
|
|
CartAPI.addToCart(productId, 0, 1)
|
|
.then(() => {
|
|
Toast.success(i18n.t('add_to_cart_success'));
|
|
|
|
// 更新购物车数量
|
|
cart.updateCartCount();
|
|
})
|
|
.catch(error => {
|
|
console.error('加入购物车失败:', error);
|
|
Toast.error(error.message || i18n.t('add_to_cart_failed'));
|
|
});
|
|
},
|
|
|
|
// 加载购物车数量
|
|
loadCartCount() {
|
|
if (cart && typeof cart.updateCartCount === 'function') {
|
|
cart.updateCartCount();
|
|
}
|
|
},
|
|
|
|
// 获取商品名称(多语言)
|
|
getProductName(product, lang) {
|
|
if (lang === 'en-US' && product.name_en) {
|
|
return product.name_en;
|
|
}
|
|
if (lang === 'ja-JP' && product.name_ja) {
|
|
return product.name_ja;
|
|
}
|
|
return product.name || '';
|
|
}
|
|
};
|
|
|
|
// 页面加载完成后初始化
|
|
$(document).ready(function() {
|
|
searchPage.init();
|
|
});
|