123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- /**
- * 搜索相关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 ''
- }
- }
|