/** * 搜索相关API接口 * 酒谷小程序 - 商品搜索功能 * * 当前使用模拟数据,预留真实API接口 * TODO: 替换为真实后端接口地址 */ // 导入模拟数据 import { MOCK_PRODUCTS, MOCK_CATEGORIES, MOCK_ASSETS, API_ENDPOINTS } from '@/mock/mockData.js' /** * 基础API配置 * TODO: 替换为真实API基础地址 */ const API_BASE_URL = 'http://localhost:8080' /** * 热门搜索词模拟数据 * TODO: API替换 - 从后台获取热门搜索词 */ const MOCK_HOT_SEARCH = { success: true, message: '获取成功', data: { hotSearchList: [ '酒谷', '茅台', '红酒', '陈酿', '特酿', '飞天', '波尔多', '珍藏' ] } } /** * 搜索产品接口 * 根据关键词模糊搜索商品 * * @param {Object} params - 搜索参数 * @param {string} params.keyword - 搜索关键词 * @param {string} params.filter - 筛选方式 (default|sales|stock|name) * @param {string} params.sort - 排序方向 (asc|desc) * @param {number} params.page - 页码,默认1 * @param {number} params.pageSize - 每页数量,默认20 * @returns {Promise} 搜索结果 */ export async function searchProducts(params = {}) { try { const { keyword = '', filter = 'default', sort = 'asc', page = 1, pageSize = 20 } = params console.log('🔍 执行商品搜索:', { keyword, filter, sort, page, pageSize }) // TODO: API替换 - 替换为真实API调用 /* const response = await uni.request({ url: `${API_BASE_URL}${API_ENDPOINTS.SEARCH}`, method: 'POST', data: { keyword, filter, sort, page, pageSize }, header: { 'Content-Type': 'application/json', // 如需要认证,添加token // 'Authorization': `Bearer ${getToken()}` } }) return response.data */ // 当前使用模拟数据 return simulateSearchProducts(params) } catch (error) { console.error('❌ 搜索商品失败:', error) throw error } } /** * 获取热门搜索词 * * @returns {Promise} 热门搜索词列表 */ export async function getHotSearch() { try { console.log('🔥 获取热门搜索词') // TODO: API替换 - 替换为真实API调用 /* const response = await uni.request({ url: `${API_BASE_URL}/api/search/hot`, method: 'GET', header: { 'Content-Type': 'application/json' } }) return response.data */ // 当前使用模拟数据 return new Promise((resolve) => { setTimeout(() => { resolve(MOCK_HOT_SEARCH) }, 200) }) } catch (error) { console.error('❌ 获取热门搜索词失败:', error) throw error } } /** * 获取搜索建议 * 根据输入的关键词实时获取搜索建议 * * @param {string} keyword - 输入的关键词 * @returns {Promise} 搜索建议列表 */ export async function getSearchSuggestions(keyword) { try { console.log('💡 获取搜索建议:', keyword) // TODO: API替换 - 替换为真实API调用 /* const response = await uni.request({ url: `${API_BASE_URL}/api/search/suggestions`, method: 'GET', data: { keyword }, header: { 'Content-Type': 'application/json' } }) return response.data */ // 当前使用模拟数据 return simulateSearchSuggestions(keyword) } catch (error) { console.error('❌ 获取搜索建议失败:', error) throw error } } /** * 保存搜索记录到后台 * 用于统计分析和优化搜索体验 * * @param {Object} record - 搜索记录 * @param {string} record.keyword - 搜索关键词 * @param {number} record.resultCount - 搜索结果数量 * @param {string} record.userId - 用户ID(可选) * @returns {Promise} 保存结果 */ export async function saveSearchRecord(record) { try { console.log('📊 保存搜索记录:', record) // TODO: API替换 - 替换为真实API调用 /* const response = await uni.request({ url: `${API_BASE_URL}/api/search/record`, method: 'POST', data: record, header: { 'Content-Type': 'application/json', // 如需要认证,添加token // 'Authorization': `Bearer ${getToken()}` } }) return response.data */ // 模拟成功响应 return { success: true, message: '搜索记录保存成功' } } catch (error) { console.error('❌ 保存搜索记录失败:', error) // 搜索记录保存失败不影响用户体验,静默处理 return { success: false, message: '搜索记录保存失败' } } } // ========== 模拟数据处理函数 ========== /** * 模拟商品搜索功能 * 实现模糊搜索、排序、分页等功能 * * @param {Object} params - 搜索参数 * @returns {Promise} 模拟搜索结果 */ function simulateSearchProducts(params) { return new Promise((resolve) => { setTimeout(() => { const { keyword = '', filter = 'default', sort = 'asc', page = 1, pageSize = 20 } = params try { // 获取所有商品数据并组合分类信息 let allProducts = MOCK_PRODUCTS.data.products .filter(product => product.status === 1) // 只搜索上架商品 .map(product => { // 查找对应分类 const category = MOCK_CATEGORIES.data.categories.find( c => c.id === product.categoryId ) return { ...product, categoryName: category ? category.name : '未分类', imageUrl: MOCK_ASSETS.products[product.assetId] || '' } }) // 关键词搜索 - 模糊匹配商品名称和分类名称 if (keyword) { const lowerKeyword = keyword.toLowerCase() allProducts = allProducts.filter(product => { return product.name.toLowerCase().includes(lowerKeyword) || product.categoryName.toLowerCase().includes(lowerKeyword) }) } // 排序处理 if (filter && filter !== 'default') { allProducts.sort((a, b) => { let compareValue = 0 switch (filter) { case 'sales': compareValue = a.sales - b.sales break case 'stock': compareValue = a.stock - b.stock break case 'name': compareValue = a.name.localeCompare(b.name) break default: compareValue = a.sort - b.sort } return sort === 'desc' ? -compareValue : compareValue }) } // 分页处理 const startIndex = (page - 1) * pageSize const endIndex = startIndex + pageSize const paginatedProducts = allProducts.slice(startIndex, endIndex) const result = { success: true, message: '搜索成功', data: { products: paginatedProducts, pagination: { current: page, pageSize: pageSize, total: allProducts.length, totalPages: Math.ceil(allProducts.length / pageSize) }, searchInfo: { keyword: keyword, filter: filter, sort: sort, resultCount: allProducts.length } } } console.log('✅ 模拟搜索完成:', { keyword, total: allProducts.length, currentPage: paginatedProducts.length }) resolve(result) } catch (error) { console.error('❌ 模拟搜索失败:', error) resolve({ success: false, message: '搜索失败', data: { products: [], pagination: { current: 1, pageSize: pageSize, total: 0, totalPages: 0 } } }) } }, 300) // 模拟网络延迟 }) } /** * 模拟搜索建议功能 * 根据关键词生成搜索建议 * * @param {string} keyword - 搜索关键词 * @returns {Promise} 搜索建议结果 */ function simulateSearchSuggestions(keyword) { return new Promise((resolve) => { setTimeout(() => { try { const suggestions = [] const lowerKeyword = keyword.toLowerCase() // 从商品名称生成建议 MOCK_PRODUCTS.data.products.forEach(product => { if (product.status === 1 && product.name.toLowerCase().includes(lowerKeyword) && !suggestions.includes(product.name)) { suggestions.push(product.name) } }) // 从分类名称生成建议 MOCK_CATEGORIES.data.categories.forEach(category => { if (category.status === 1 && category.name.toLowerCase().includes(lowerKeyword) && !suggestions.includes(category.name)) { suggestions.push(category.name) } }) // 添加一些相关的搜索词 const relatedTerms = ['陈酿', '特酿', '珍藏', '限量版', '经典', '精品'] relatedTerms.forEach(term => { if (term.includes(keyword) && !suggestions.includes(term)) { suggestions.push(term) } }) resolve({ success: true, message: '获取建议成功', data: { suggestions: suggestions.slice(0, 8), // 最多返回8个建议 keyword: keyword } }) } catch (error) { console.error('❌ 模拟搜索建议失败:', error) resolve({ success: false, message: '获取建议失败', data: { suggestions: [], keyword: keyword } }) } }, 150) // 建议响应要快一些 }) } /** * API错误处理 * 统一处理API请求错误 * * @param {Error} error - 错误对象 * @param {string} context - 错误上下文 */ export function handleApiError(error, context = '请求') { console.error(`${context}失败:`, error) let message = '网络异常,请稍后重试' if (error.statusCode) { switch (error.statusCode) { case 400: message = '请求参数错误' break case 401: message = '请先登录' break case 403: message = '没有访问权限' break case 404: message = '请求的资源不存在' break case 500: message = '服务器错误,请稍后重试' break default: message = error.errMsg || '请求失败' } } // 显示错误提示(可选) // uni.showToast({ // title: message, // icon: 'none', // duration: 2000 // }) return { success: false, message: message, error: error } } /** * 获取用户token(如果需要认证) * TODO: 根据实际认证方案实现 */ function getToken() { try { return uni.getStorageSync('userToken') || '' } catch (error) { console.error('获取token失败:', error) return '' } }