/** * 首页数据接口服务 * * 注意:目前使用模拟数据,后端接口开发完成后需要替换 * * 替换步骤: * 1. 将 import 模拟数据改为真实的网络请求 * 2. 修改返回的 Promise 为实际的 uni.request 调用 * 3. 添加错误处理和网络异常处理 * 4. 调整数据结构映射(如果后端返回结构与前端需要的不一致) */ import { MOCK_HOMEPAGE_DATA, MOCK_BANNER_CONFIG, MOCK_CATEGORIES, MOCK_PRODUCTS, MOCK_ASSETS, API_ENDPOINTS } from '@/mock/mockData.js' /** * 获取首页数据 * TODO: 替换为真实API调用 * * 真实接口示例: * export const getHomepageData = () => { * return uni.request({ * url: API_ENDPOINTS.HOMEPAGE, * method: 'GET', * header: { * 'Authorization': 'Bearer ' + getToken() * } * }) * } */ export const getHomepageData = () => { return new Promise((resolve) => { // 模拟网络延迟 setTimeout(() => { console.log('📡 [API调用] 获取首页数据 - 当前为模拟数据') resolve(MOCK_HOMEPAGE_DATA) }, 300) }) } /** * 获取轮播图配置 * TODO: 替换为真实API调用 */ export const getBannerConfig = () => { return new Promise((resolve) => { setTimeout(() => { console.log('📡 [API调用] 获取轮播图配置 - 当前为模拟数据') // 组合轮播图数据和素材URL const banners = MOCK_BANNER_CONFIG.data.banners.map(banner => ({ ...banner, imageUrl: MOCK_ASSETS.banners[banner.assetId] })) resolve({ success: true, data: { banners } }) }, 200) }) } /** * 获取商品分类数据 * TODO: 替换为真实API调用 */ export const getCategories = () => { return new Promise((resolve) => { setTimeout(() => { console.log('📡 [API调用] 获取商品分类 - 当前为模拟数据') resolve(MOCK_CATEGORIES) }, 150) }) } /** * 获取分类下的商品列表 * TODO: 替换为真实API调用 * * @param {string} categoryId - 分类ID * @param {number} page - 页码 * @param {number} limit - 每页数量 */ export const getCategoryProducts = (categoryId, page = 1, limit = 3) => { return new Promise((resolve) => { setTimeout(() => { console.log(`📡 [API调用] 获取分类商品 - categoryId: ${categoryId}, 当前为模拟数据`) // 过滤并组合商品数据 const products = MOCK_PRODUCTS.data.products .filter(product => product.categoryId === categoryId && product.status === 1) .sort((a, b) => a.sort - b.sort) .slice((page - 1) * limit, page * limit) .map(product => ({ ...product, imageUrl: MOCK_ASSETS.products[product.assetId] })) resolve({ success: true, data: { products, pagination: { page, limit, total: MOCK_PRODUCTS.data.products.filter(p => p.categoryId === categoryId).length } } }) }, 200) }) } /** * 获取商品详情 * TODO: 替换为真实API调用 * * @param {string} productId - 商品ID */ export const getProductDetail = (productId) => { return new Promise((resolve, reject) => { setTimeout(() => { console.log(`📡 [API调用] 获取商品详情 - productId: ${productId}, 当前为模拟数据`) const product = MOCK_PRODUCTS.data.products.find(p => p.id === productId) if (product) { resolve({ success: true, data: { ...product, imageUrl: MOCK_ASSETS.products[product.assetId] } }) } else { reject({ success: false, message: '商品不存在' }) } }, 250) }) } /** * 获取素材资源URL * TODO: 替换为真实API调用 * * @param {string} assetId - 素材ID * @param {string} type - 素材类型 banners/products */ export const getAssetUrl = (assetId, type = 'products') => { return new Promise((resolve) => { setTimeout(() => { console.log(`📡 [API调用] 获取素材URL - assetId: ${assetId}, type: ${type}, 当前为模拟数据`) const url = MOCK_ASSETS[type] && MOCK_ASSETS[type][assetId] ? MOCK_ASSETS[type][assetId] : null resolve({ success: !!url, data: { url } }) }, 100) }) } /** * 搜索商品 * TODO: 替换为真实API调用 * * @param {string} keyword - 搜索关键词 * @param {number} page - 页码 * @param {number} limit - 每页数量 */ export const searchProducts = (keyword, page = 1, limit = 10) => { return new Promise((resolve) => { setTimeout(() => { console.log(`📡 [API调用] 搜索商品 - keyword: ${keyword}, 当前为模拟数据`) // 模拟搜索逻辑 const products = MOCK_PRODUCTS.data.products .filter(product => product.status === 1 && product.name.toLowerCase().includes(keyword.toLowerCase()) ) .slice((page - 1) * limit, page * limit) .map(product => ({ ...product, imageUrl: MOCK_ASSETS.products[product.assetId] })) resolve({ success: true, data: { products, keyword, pagination: { page, limit, total: MOCK_PRODUCTS.data.products.filter(p => p.status === 1 && p.name.toLowerCase().includes(keyword.toLowerCase()) ).length } } }) }, 400) }) } /** * 通用错误处理 * TODO: 根据实际后端错误码进行调整 */ export const handleApiError = (error) => { console.error('API请求错误:', error) // 模拟错误处理逻辑 if (error.statusCode) { switch (error.statusCode) { case 401: uni.showToast({ title: '请先登录', icon: 'none' }) // 跳转到登录页 break case 403: uni.showToast({ title: '权限不足', icon: 'none' }) break case 404: uni.showToast({ title: '请求的资源不存在', icon: 'none' }) break case 500: uni.showToast({ title: '服务器错误', icon: 'none' }) break default: uni.showToast({ title: '网络错误,请稍后重试', icon: 'none' }) } } else { uni.showToast({ title: '网络连接失败', icon: 'none' }) } }