Initial commit
This commit is contained in:
20
miniprogram/services/good/comments/fetchCommentDetail.js
Normal file
20
miniprogram/services/good/comments/fetchCommentDetail.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import { config } from '../../../config/index';
|
||||
import { queryCommentDetail } from '../../../model/comments/queryDetail';
|
||||
/** 获取商品评价数据 */
|
||||
function mockQueryCommentDetail(params) {
|
||||
const { delay } = require('../../_utils/delay');
|
||||
const data = queryCommentDetail(params);
|
||||
return delay().then(() => {
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取评价详情 */
|
||||
export function getCommentDetail(params) {
|
||||
if (config.useMock) {
|
||||
return mockQueryCommentDetail(params);
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
resolve('real api');
|
||||
});
|
||||
}
|
||||
141
miniprogram/services/good/favorite.js
Normal file
141
miniprogram/services/good/favorite.js
Normal file
@@ -0,0 +1,141 @@
|
||||
import { config } from '../../config/index';
|
||||
|
||||
/**
|
||||
* 检查商品是否已收藏
|
||||
* @param {number} productId 商品ID
|
||||
* @returns {Promise<boolean>} 是否已收藏
|
||||
*/
|
||||
export function checkIsFavorite(productId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 获取用户token
|
||||
const token = wx.getStorageSync('token') || wx.getStorageSync('jwt_token');
|
||||
if (!token) {
|
||||
console.log('用户未登录,默认未收藏');
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
wx.request({
|
||||
url: `${config.apiBase}/products/${productId}/favorite/status`,
|
||||
method: 'GET',
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200 && (res.data?.code === 200 || res.data?.success === true || res.data?.code === 'Success')) {
|
||||
try {
|
||||
const payload = res.data || {};
|
||||
const data = payload.data || payload;
|
||||
const isFavorite = (
|
||||
data.is_favorite ??
|
||||
data.isFavorite ??
|
||||
data.favorite ??
|
||||
data.favorited ??
|
||||
false
|
||||
);
|
||||
resolve(Boolean(isFavorite));
|
||||
} catch (e) {
|
||||
console.error('解析收藏状态失败:', e, res);
|
||||
resolve(false);
|
||||
}
|
||||
} else {
|
||||
console.error('检查收藏状态失败:', res);
|
||||
resolve(false);
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('检查收藏状态请求失败:', error);
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品到收藏
|
||||
* @param {number} productId 商品ID
|
||||
* @returns {Promise<boolean>} 操作是否成功
|
||||
*/
|
||||
export function addToFavorite(productId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 获取用户token
|
||||
const token = wx.getStorageSync('token') || wx.getStorageSync('jwt_token');
|
||||
if (!token) {
|
||||
reject(new Error('用户未登录'));
|
||||
return;
|
||||
}
|
||||
|
||||
wx.request({
|
||||
url: `${config.apiBase}/products/${productId}/favorite`,
|
||||
method: 'POST',
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
success: (res) => {
|
||||
if ((res.statusCode === 200 || res.statusCode === 201) && (res.data?.code === 200 || res.data?.success === true)) {
|
||||
resolve(true);
|
||||
} else {
|
||||
console.error('添加收藏失败:', res);
|
||||
reject(new Error(res.data.message || '收藏失败'));
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('添加收藏请求失败:', error);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消收藏商品
|
||||
* @param {number} productId 商品ID
|
||||
* @returns {Promise<boolean>} 操作是否成功
|
||||
*/
|
||||
export function removeFromFavorite(productId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 获取用户token
|
||||
const token = wx.getStorageSync('token') || wx.getStorageSync('jwt_token');
|
||||
if (!token) {
|
||||
reject(new Error('用户未登录'));
|
||||
return;
|
||||
}
|
||||
|
||||
wx.request({
|
||||
url: `${config.apiBase}/products/${productId}/favorite`,
|
||||
method: 'DELETE',
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
success: (res) => {
|
||||
if ((res.statusCode === 200 || res.statusCode === 204) && (res.data?.code === 200 || res.data?.success === true)) {
|
||||
resolve(true);
|
||||
} else {
|
||||
console.error('取消收藏失败:', res);
|
||||
reject(new Error(res.data.message || '取消收藏失败'));
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('取消收藏请求失败:', error);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换收藏状态
|
||||
* @param {number} productId 商品ID
|
||||
* @param {boolean} currentStatus 当前收藏状态
|
||||
* @returns {Promise<boolean>} 新的收藏状态
|
||||
*/
|
||||
export function toggleFavorite(productId, currentStatus) {
|
||||
if (currentStatus) {
|
||||
return removeFromFavorite(productId).then(() => false);
|
||||
} else {
|
||||
return addToFavorite(productId).then(() => true);
|
||||
}
|
||||
}
|
||||
77
miniprogram/services/good/fetchCategoryList.js
Normal file
77
miniprogram/services/good/fetchCategoryList.js
Normal file
@@ -0,0 +1,77 @@
|
||||
import { config } from '../../config/index';
|
||||
|
||||
/** 获取商品列表 */
|
||||
function mockFetchGoodCategory() {
|
||||
const { delay } = require('../_utils/delay');
|
||||
const { getCategoryList } = require('../../model/category');
|
||||
return delay().then(() => getCategoryList());
|
||||
}
|
||||
|
||||
/** 将后端分类数据转换为前端需要的格式 */
|
||||
function transformCategoryData(categories) {
|
||||
if (!categories || !Array.isArray(categories)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 递归转换分类数据
|
||||
function transformCategory(category) {
|
||||
const transformed = {
|
||||
groupId: category.groupId || category.id.toString(),
|
||||
name: category.name,
|
||||
thumbnail: category.thumbnail || category.icon || 'https://tdesign.gtimg.com/miniprogram/template/retail/category/category-default.png',
|
||||
};
|
||||
|
||||
// 为每个一级分类添加"全部"按钮
|
||||
const allButton = {
|
||||
groupId: `${category.id}_all`,
|
||||
name: '全部',
|
||||
thumbnail: 'https://tdesign.gtimg.com/miniprogram/template/retail/category/category-all.png',
|
||||
categoryId: category.id.toString(),
|
||||
categoryName: category.name,
|
||||
isAll: true
|
||||
};
|
||||
|
||||
// 如果有子分类,添加"全部"按钮并处理子分类
|
||||
if (category.children && Array.isArray(category.children) && category.children.length > 0) {
|
||||
transformed.children = [allButton, ...category.children.map(child => transformCategory(child))];
|
||||
} else {
|
||||
// 如果没有子分类,只显示"全部"按钮
|
||||
transformed.children = [allButton];
|
||||
}
|
||||
|
||||
return transformed;
|
||||
}
|
||||
|
||||
return categories.map(category => transformCategory(category));
|
||||
}
|
||||
|
||||
/** 获取分类列表 */
|
||||
export function getCategoryList() {
|
||||
if (config.useMock) {
|
||||
return mockFetchGoodCategory();
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.request({
|
||||
url: `${config.apiBase}/products/categories`,
|
||||
method: 'GET',
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200 && res.data.code === 200) {
|
||||
console.log('原始分类数据:', res.data.data);
|
||||
const transformedData = transformCategoryData(res.data.data);
|
||||
console.log('转换后的分类数据:', transformedData);
|
||||
resolve(transformedData);
|
||||
} else {
|
||||
console.error('获取分类失败:', res.data);
|
||||
// 失败时返回空数组,避免页面崩溃
|
||||
resolve([]);
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('分类请求失败:', err);
|
||||
// 失败时返回空数组,避免页面崩溃
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
93
miniprogram/services/good/fetchGood.js
Normal file
93
miniprogram/services/good/fetchGood.js
Normal file
@@ -0,0 +1,93 @@
|
||||
import { config } from '../../config/index';
|
||||
|
||||
/** 获取商品列表 */
|
||||
function mockFetchGood(ID = 0) {
|
||||
const { delay } = require('../_utils/delay');
|
||||
const { genGood } = require('../../model/good');
|
||||
return delay().then(() => genGood(ID));
|
||||
}
|
||||
|
||||
/** 获取商品详情 */
|
||||
export function fetchGood(ID = 0) {
|
||||
if (config.useMock) {
|
||||
return mockFetchGood(ID);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.request({
|
||||
url: `${config.apiBase}/frontend/products/${ID}/detail`,
|
||||
method: 'GET',
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200 && res.data.code === 200) {
|
||||
// 转换后端数据格式为前端期望的格式
|
||||
const product = res.data.data;
|
||||
|
||||
// 计算价格范围
|
||||
let minPrice = parseInt(product.minSalePrice) || 0;
|
||||
let maxPrice = parseInt(product.maxSalePrice) || 0;
|
||||
let minOriginPrice = parseInt(product.minLinePrice) || 0;
|
||||
let maxOriginPrice = parseInt(product.maxLinePrice) || 0;
|
||||
|
||||
if (product.skuList && product.skuList.length > 0) {
|
||||
const prices = product.skuList.map(sku => {
|
||||
const priceInfo = sku.priceInfo && sku.priceInfo.length > 0 ? sku.priceInfo[0] : null;
|
||||
return priceInfo ? parseInt(priceInfo.price) : 0; // 直接使用分为单位
|
||||
});
|
||||
const originPrices = product.skuList.map(sku => {
|
||||
const priceInfo = sku.priceInfo && sku.priceInfo.length > 0 ? sku.priceInfo[0] : null;
|
||||
return priceInfo ? parseInt(priceInfo.originPrice || priceInfo.price) : 0; // 直接使用分为单位
|
||||
});
|
||||
minPrice = Math.min(...prices);
|
||||
maxPrice = Math.max(...prices);
|
||||
minOriginPrice = Math.min(...originPrices);
|
||||
maxOriginPrice = Math.max(...originPrices);
|
||||
}
|
||||
|
||||
const result = {
|
||||
// 基础信息:优先读取后端前端化字段,其次回退旧字段
|
||||
spuId: product.spuId || product.id,
|
||||
title: product.title || product.name,
|
||||
price: minPrice,
|
||||
originPrice: minOriginPrice,
|
||||
minSalePrice: minPrice,
|
||||
maxSalePrice: maxPrice,
|
||||
maxLinePrice: maxOriginPrice,
|
||||
primaryImage: product.primaryImage || product.main_image,
|
||||
images: (product.images && product.images.length ? product.images : (product.primaryImage || product.main_image ? [product.primaryImage || product.main_image] : [])),
|
||||
video: product.video || null,
|
||||
// 详情描述:仅返回图片列表,支持后端返回字符串单图的情况
|
||||
desc: (Array.isArray(product.desc) && product.desc.length)
|
||||
? product.desc
|
||||
: ((typeof product.desc === 'string' && product.desc.trim())
|
||||
? [product.desc.trim()]
|
||||
: ((Array.isArray(product.detail_images) && product.detail_images.length)
|
||||
? product.detail_images
|
||||
: [])),
|
||||
// 文本描述:单独提供文本字段作为兜底
|
||||
descriptionText: product.description || '',
|
||||
details: product.details,
|
||||
brand: product.brand,
|
||||
category: product.category,
|
||||
isPutOnSale: product.isPutOnSale ?? 1, // 1表示上架,0表示下架
|
||||
isStock: (product.spuStockQuantity ?? product.stock ?? 0) > 0,
|
||||
stockNum: product.spuStockQuantity ?? product.stock ?? 0,
|
||||
spuStockQuantity: product.spuStockQuantity ?? product.stock ?? 0,
|
||||
soldNum: product.soldNum ?? product.sold_count ?? 0,
|
||||
spuTagList: product.spuTagList ?? product.tags ?? [],
|
||||
limitInfo: product.limitInfo ?? [],
|
||||
specList: product.specList || [],
|
||||
skuList: product.skuList || [],
|
||||
etitle: product.etitle || product.name,
|
||||
available: product.available ?? ((product.spuStockQuantity ?? product.stock ?? 0) > 0 ? 1 : 0)
|
||||
};
|
||||
resolve(result);
|
||||
} else {
|
||||
reject(new Error(res.data.message || '获取商品详情失败'));
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
70
miniprogram/services/good/fetchGoods.js
Normal file
70
miniprogram/services/good/fetchGoods.js
Normal file
@@ -0,0 +1,70 @@
|
||||
import { config } from '../../config/index';
|
||||
|
||||
/** 获取商品列表 */
|
||||
function mockFetchGoodsList(pageIndex = 1, pageSize = 20) {
|
||||
const { delay } = require('../_utils/delay');
|
||||
const { getGoodsList } = require('../../model/goods');
|
||||
return delay().then(() =>
|
||||
getGoodsList(pageIndex, pageSize).map((item) => {
|
||||
return {
|
||||
spuId: item.spuId,
|
||||
thumb: item.primaryImage,
|
||||
title: item.title,
|
||||
price: item.minSalePrice,
|
||||
originPrice: item.maxLinePrice,
|
||||
tags: item.spuTagList.map((tag) => tag.title),
|
||||
};
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/** 获取商品列表 */
|
||||
export function fetchGoodsList(pageIndex = 1, pageSize = 20, categoryId = null) {
|
||||
if (config.useMock) {
|
||||
return mockFetchGoodsList(pageIndex, pageSize);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const requestData = {
|
||||
page: pageIndex,
|
||||
limit: pageSize,
|
||||
};
|
||||
|
||||
// 如果有分类ID,添加到请求参数中
|
||||
if (categoryId) {
|
||||
requestData.category_id = categoryId;
|
||||
}
|
||||
|
||||
wx.request({
|
||||
url: `${config.apiBase}/products`,
|
||||
method: 'GET',
|
||||
data: requestData,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200 && res.data.code === 200) {
|
||||
// 转换API数据格式为小程序期望的格式
|
||||
const products = res.data.data?.list || [];
|
||||
const goodsList = products.map((item) => {
|
||||
return {
|
||||
spuId: item.id,
|
||||
thumb: item.main_image,
|
||||
title: item.name,
|
||||
price: item.price,
|
||||
originPrice: item.orig_price || item.price,
|
||||
tags: [], // API暂时没有标签数据
|
||||
stock: item.stock || 0, // 添加库存信息
|
||||
isStock: item.stock > 0, // 添加库存状态
|
||||
};
|
||||
});
|
||||
resolve(goodsList);
|
||||
} else {
|
||||
console.error('获取商品列表失败:', res.data);
|
||||
resolve([]);
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('商品列表请求失败:', err);
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
134
miniprogram/services/good/fetchGoodsDetailsComments.js
Normal file
134
miniprogram/services/good/fetchGoodsDetailsComments.js
Normal file
@@ -0,0 +1,134 @@
|
||||
import { config } from '../../config/index';
|
||||
|
||||
/** 获取商品详情页评论数 */
|
||||
function mockFetchGoodDetailsCommentsCount(spuId = 0) {
|
||||
const { delay } = require('../_utils/delay');
|
||||
const {
|
||||
getGoodsDetailsCommentsCount,
|
||||
} = require('../../model/detailsComments');
|
||||
return delay().then(() => getGoodsDetailsCommentsCount(spuId));
|
||||
}
|
||||
|
||||
/** 获取商品详情页评论数 */
|
||||
export function getGoodsDetailsCommentsCount(spuId = 0) {
|
||||
if (config.useMock) {
|
||||
return mockFetchGoodDetailsCommentsCount(spuId);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.request({
|
||||
url: `${config.apiBase}/products/${spuId}/reviews/count`,
|
||||
method: 'GET',
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
// 转换后端数据格式为前端需要的格式
|
||||
const data = {
|
||||
commentCount: res.data.data.total || 0,
|
||||
goodRate: res.data.data.good_rate || '100',
|
||||
badCount: res.data.data.bad_count || 0,
|
||||
goodCount: res.data.data.good_count || 0,
|
||||
middleCount: res.data.data.middle_count || 0,
|
||||
hasImageCount: res.data.data.has_image_count || 0,
|
||||
};
|
||||
resolve(data);
|
||||
} else {
|
||||
console.error('获取评论统计失败:', res);
|
||||
// 失败时返回默认数据
|
||||
resolve({
|
||||
commentCount: 0,
|
||||
goodRate: '100',
|
||||
badCount: 0,
|
||||
goodCount: 0,
|
||||
middleCount: 0,
|
||||
hasImageCount: 0,
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('获取评论统计请求失败:', error);
|
||||
// 网络错误时返回默认数据
|
||||
resolve({
|
||||
commentCount: 0,
|
||||
goodRate: '100',
|
||||
badCount: 0,
|
||||
goodCount: 0,
|
||||
middleCount: 0,
|
||||
hasImageCount: 0,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取商品详情页评论 */
|
||||
function mockFetchGoodDetailsCommentList(spuId = 0) {
|
||||
const { delay } = require('../_utils/delay');
|
||||
const { getGoodsDetailsComments } = require('../../model/detailsComments');
|
||||
return delay().then(() => getGoodsDetailsComments(spuId));
|
||||
}
|
||||
|
||||
/** 获取商品详情页评论 */
|
||||
export function getGoodsDetailsCommentList(spuId = 0, page = 1, limit = 10) {
|
||||
if (config.useMock) {
|
||||
return mockFetchGoodDetailsCommentList(spuId);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.request({
|
||||
url: `${config.apiBase}/products/${spuId}/reviews`,
|
||||
method: 'GET',
|
||||
data: {
|
||||
page: page,
|
||||
limit: limit,
|
||||
},
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
// 转换后端数据格式为前端需要的格式
|
||||
const reviews = res.data.data.list || [];
|
||||
const transformedData = reviews.map(review => ({
|
||||
spuId: review.product_id?.toString() || spuId.toString(),
|
||||
skuId: review.sku_id?.toString() || '0',
|
||||
specInfo: review.spec_info || '',
|
||||
commentContent: review.content || '',
|
||||
commentResources: review.images ? review.images.map(img => ({
|
||||
src: img,
|
||||
type: 'image'
|
||||
})) : [],
|
||||
commentScore: review.rating || 5,
|
||||
uid: review.user_id?.toString() || '',
|
||||
userName: review.user_name || '匿名用户',
|
||||
userHeadUrl: review.user_avatar || 'https://tdesign.gtimg.com/miniprogram/template/retail/avatar/avatar1.png',
|
||||
isAnonymity: review.is_anonymous || false,
|
||||
commentTime: review.created_at ? new Date(review.created_at).getTime().toString() : Date.now().toString(),
|
||||
isAutoComment: false,
|
||||
sellerReply: review.reply || '',
|
||||
goodsDetailInfo: review.spec_info || '',
|
||||
}));
|
||||
|
||||
resolve({
|
||||
homePageComments: transformedData
|
||||
});
|
||||
} else {
|
||||
console.error('获取评论列表失败:', res);
|
||||
// 失败时返回空数组
|
||||
resolve({
|
||||
homePageComments: []
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('获取评论列表请求失败:', error);
|
||||
// 网络错误时返回空数组
|
||||
resolve({
|
||||
homePageComments: []
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
146
miniprogram/services/good/fetchGoodsList.js
Normal file
146
miniprogram/services/good/fetchGoodsList.js
Normal file
@@ -0,0 +1,146 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import { config } from '../../config/index';
|
||||
|
||||
/** 获取商品列表 */
|
||||
function mockFetchGoodsList(params) {
|
||||
const { delay } = require('../_utils/delay');
|
||||
const { getSearchResult } = require('../../model/search');
|
||||
|
||||
const data = getSearchResult(params);
|
||||
|
||||
if (data.spuList.length) {
|
||||
data.spuList.forEach((item) => {
|
||||
item.spuId = item.spuId;
|
||||
item.thumb = item.primaryImage;
|
||||
item.title = item.title;
|
||||
item.price = item.minSalePrice;
|
||||
item.originPrice = item.maxLinePrice;
|
||||
item.desc = '';
|
||||
if (item.spuTagList) {
|
||||
item.tags = item.spuTagList.map((tag) => tag.title);
|
||||
} else {
|
||||
item.tags = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
return delay().then(() => {
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取商品列表 */
|
||||
export function fetchGoodsList(params) {
|
||||
console.log('[API] fetchGoodsList 开始调用:', {
|
||||
inputParams: params,
|
||||
useMock: config.useMock,
|
||||
timestamp: new Date().toLocaleString()
|
||||
});
|
||||
|
||||
if (config.useMock) {
|
||||
console.log('[API] 使用Mock数据');
|
||||
return mockFetchGoodsList(params);
|
||||
}
|
||||
|
||||
const requestData = {
|
||||
page: params.pageNum || 1,
|
||||
page_size: params.pageSize || 20,
|
||||
category_id: params.category_id,
|
||||
keyword: params.keyword,
|
||||
min_price: params.minPrice,
|
||||
max_price: params.maxPrice,
|
||||
sort: params.sort,
|
||||
sortType: params.sortType
|
||||
};
|
||||
|
||||
// 过滤无效参数,避免传递 'undefined' 等值
|
||||
Object.keys(requestData).forEach((key) => {
|
||||
const val = requestData[key];
|
||||
if (
|
||||
val === undefined ||
|
||||
val === null ||
|
||||
(typeof val === 'string' && (val.trim() === '' || val.trim().toLowerCase() === 'undefined'))
|
||||
) {
|
||||
delete requestData[key];
|
||||
}
|
||||
});
|
||||
|
||||
console.log('[API] 发送请求到后端:', {
|
||||
url: `${config.apiBase}/products`,
|
||||
method: 'GET',
|
||||
requestData: requestData,
|
||||
sortInfo: {
|
||||
hasSort: !!params.sort,
|
||||
sortType: params.sortType,
|
||||
sortText: params.sortType === 1 ? '价格从高到低' : params.sortType === 0 ? '价格从低到高' : '默认排序'
|
||||
},
|
||||
timestamp: new Date().toLocaleString()
|
||||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.request({
|
||||
url: `${config.apiBase}/products`,
|
||||
method: 'GET',
|
||||
data: requestData,
|
||||
success: (res) => {
|
||||
console.log('[API] 收到后端响应:', {
|
||||
statusCode: res.statusCode,
|
||||
dataCode: res.data?.code,
|
||||
dataMessage: res.data?.message,
|
||||
totalCount: res.data?.data?.total,
|
||||
listLength: res.data?.data?.list?.length,
|
||||
timestamp: new Date().toLocaleString()
|
||||
});
|
||||
|
||||
if (res.statusCode === 200 && res.data.code === 200) {
|
||||
// 转换后端数据格式为前端期望的格式
|
||||
const products = res.data.data.list.map(item => ({
|
||||
spuId: item.id.toString(),
|
||||
thumb: item.main_image,
|
||||
title: item.name,
|
||||
price: item.price,
|
||||
originPrice: item.orig_price,
|
||||
desc: item.description,
|
||||
tags: item.tags || [],
|
||||
isStock: item.stock > 0
|
||||
}));
|
||||
|
||||
const result = {
|
||||
spuList: products,
|
||||
totalCount: res.data.data.total,
|
||||
pageNum: res.data.data.page,
|
||||
pageSize: res.data.data.page_size
|
||||
};
|
||||
|
||||
console.log('[API] 数据转换完成:', {
|
||||
productsCount: products.length,
|
||||
totalCount: result.totalCount,
|
||||
pageNum: result.pageNum,
|
||||
pageSize: result.pageSize,
|
||||
firstProduct: products[0] ? {
|
||||
title: products[0].title,
|
||||
price: products[0].price
|
||||
} : null,
|
||||
timestamp: new Date().toLocaleString()
|
||||
});
|
||||
|
||||
resolve(result);
|
||||
} else {
|
||||
console.error('[API] 请求失败:', {
|
||||
statusCode: res.statusCode,
|
||||
dataCode: res.data?.code,
|
||||
message: res.data?.message || '获取商品列表失败',
|
||||
timestamp: new Date().toLocaleString()
|
||||
});
|
||||
reject(new Error(res.data.message || '获取商品列表失败'));
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('[API] 网络请求失败:', {
|
||||
error: err,
|
||||
timestamp: new Date().toLocaleString()
|
||||
});
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
35
miniprogram/services/good/fetchSearchHistory.js
Normal file
35
miniprogram/services/good/fetchSearchHistory.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import { config } from '../../config/index';
|
||||
|
||||
/** 获取搜索历史 */
|
||||
function mockSearchHistory() {
|
||||
const { delay } = require('../_utils/delay');
|
||||
const { getSearchHistory } = require('../../model/search');
|
||||
return delay().then(() => getSearchHistory());
|
||||
}
|
||||
|
||||
/** 获取搜索历史 */
|
||||
export function getSearchHistory() {
|
||||
if (config.useMock) {
|
||||
return mockSearchHistory();
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
resolve('real api');
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取搜索历史 */
|
||||
function mockSearchPopular() {
|
||||
const { delay } = require('../_utils/delay');
|
||||
const { getSearchPopular } = require('../../model/search');
|
||||
return delay().then(() => getSearchPopular());
|
||||
}
|
||||
|
||||
/** 获取搜索历史 */
|
||||
export function getSearchPopular() {
|
||||
if (config.useMock) {
|
||||
return mockSearchPopular();
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
resolve('real api');
|
||||
});
|
||||
}
|
||||
133
miniprogram/services/good/fetchSearchResult.js
Normal file
133
miniprogram/services/good/fetchSearchResult.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import { config } from '../../config/index';
|
||||
|
||||
/** 获取搜索结果 - Mock数据 */
|
||||
function mockSearchResult(params) {
|
||||
const { delay } = require('../_utils/delay');
|
||||
const { getSearchResult } = require('../../model/search');
|
||||
|
||||
const data = getSearchResult(params);
|
||||
|
||||
if (data.spuList.length) {
|
||||
data.spuList.forEach((item) => {
|
||||
item.spuId = item.spuId;
|
||||
item.thumb = item.primaryImage;
|
||||
item.title = item.title;
|
||||
item.price = item.minSalePrice;
|
||||
item.originPrice = item.maxLinePrice;
|
||||
if (item.spuTagList) {
|
||||
item.tags = item.spuTagList.map((tag) => ({ title: tag.title }));
|
||||
} else {
|
||||
item.tags = [];
|
||||
}
|
||||
// 添加库存状态字段 - Mock数据
|
||||
item.isStock = item.spuStockQuantity > 0;
|
||||
item.stock = item.spuStockQuantity || 0;
|
||||
});
|
||||
}
|
||||
return delay().then(() => {
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
/** 调用真实的搜索API */
|
||||
function realSearchResult(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 构建请求参数
|
||||
const requestParams = {
|
||||
keyword: params.keyword || '',
|
||||
page: params.pageNum || 1,
|
||||
page_size: params.pageSize || 30,
|
||||
};
|
||||
|
||||
// 添加排序参数
|
||||
if (params.sort === 1) {
|
||||
requestParams.sort_by = 'price';
|
||||
requestParams.sort_order = params.sortType === 1 ? 'desc' : 'asc';
|
||||
}
|
||||
|
||||
// 添加价格筛选
|
||||
if (params.minPrice && params.minPrice > 0) {
|
||||
requestParams.min_price = params.minPrice;
|
||||
}
|
||||
if (params.maxPrice && params.maxPrice > 0) {
|
||||
requestParams.max_price = params.maxPrice;
|
||||
}
|
||||
|
||||
// 构建查询字符串
|
||||
const queryString = Object.keys(requestParams)
|
||||
.filter(key => requestParams[key] !== undefined && requestParams[key] !== '')
|
||||
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(requestParams[key])}`)
|
||||
.join('&');
|
||||
|
||||
const url = `${config.apiBase}/products/search?${queryString}`;
|
||||
|
||||
console.log('🔍 搜索API请求:', {
|
||||
url,
|
||||
params: requestParams,
|
||||
originalParams: params
|
||||
});
|
||||
|
||||
wx.request({
|
||||
url,
|
||||
method: 'GET',
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('🔍 搜索API响应:', res);
|
||||
|
||||
if (res.statusCode === 200 && res.data && res.data.code === 200) {
|
||||
const { data: responseData } = res.data;
|
||||
|
||||
console.log('🔍 后端响应数据结构:', responseData);
|
||||
|
||||
// 转换后端数据格式为前端期望的格式
|
||||
const result = {
|
||||
saasId: null,
|
||||
storeId: null,
|
||||
pageNum: responseData.page || params.pageNum || 1,
|
||||
pageSize: responseData.page_size || params.pageSize || 30,
|
||||
totalCount: responseData.total || 0,
|
||||
spuList: (responseData.list || []).map(item => ({
|
||||
spuId: item.id,
|
||||
title: item.name,
|
||||
primaryImage: item.main_image || item.image || '',
|
||||
thumb: item.main_image || item.image || '',
|
||||
minSalePrice: item.price || 0,
|
||||
maxLinePrice: item.original_price || item.price || 0,
|
||||
price: item.price || 0,
|
||||
originPrice: item.original_price || item.price || 0,
|
||||
spuTagList: (item.tags || []).map(tag => ({ title: tag })),
|
||||
tags: (item.tags || []).map(tag => ({ title: tag })),
|
||||
// 添加库存状态字段
|
||||
isStock: item.stock > 0,
|
||||
stock: item.stock || 0,
|
||||
// 保留原始数据以备后用
|
||||
_originalData: item
|
||||
})),
|
||||
algId: 0,
|
||||
};
|
||||
|
||||
console.log('🔍 转换后的搜索结果:', result);
|
||||
resolve(result);
|
||||
} else {
|
||||
console.error('🔍 搜索API错误响应:', res);
|
||||
reject(new Error(res.data?.message || '搜索请求失败'));
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('🔍 搜索API请求失败:', error);
|
||||
reject(new Error('网络请求失败,请检查网络连接'));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取搜索结果 */
|
||||
export function getSearchResult(params) {
|
||||
if (config.useMock) {
|
||||
return mockSearchResult(params);
|
||||
}
|
||||
return realSearchResult(params);
|
||||
}
|
||||
Reference in New Issue
Block a user