// 商品相关接口
//引入封装好的的get请求方法
import { get, post } from '@/core/http/http-client'
import { buildRestPath } from '@/core/config/api-paths'
// 商品图片 CDN 配置
import { buildOssUrl } from '@/core/media/oss-url'
/**
* 商品列表(分页)
* 对接 88live 的 /wanlshop/product/lists 接口
*
*/
export async function pullMallProductPage({
type = 'goods',
page = 1,
search = '',
filter = {},
op = {},
sort = 'weigh',
order = 'asc'
} = {}) {
const params = { type, page, sort, order }
if (search) params.search = search
if (Object.keys(filter).length) params.filter = JSON.stringify(filter)
if (Object.keys(op).length) params.op = JSON.stringify(op)
const { data, raw } = await get(buildRestPath('product/lists'), params)
const body = data || {}
const rows = (Array.isArray(body.data) ? body.data : []).map(item => {
if (!item || item.id == null) return null
return {
id: item.id,
title: item.title || item.name || '',
image: buildOssUrl(item.image),
price: item.price || '0.00',
market_price: item.market_price || '',
sales: Number(item.sales || 0),
shop_id: item.shop_id,
shop: item.shop || null,
comment: Number(item.comment || 0),
praise: Number(item.praise || 0),
isLive: item.isLive || false,
raw: item
}
}).filter(Boolean)
return {
rows,
total: Number(body.total || rows.length),
currentPage: Number(body.current_page || page),
lastPage: Number(body.last_page || 1)
}
}
/**
* 商品筛选条件(品牌/属性/价格区间)
* 对接 88live 的 /wanlshop/product/drawer 接口
*/
export async function pullMallFilterDrawer({ type = 'goods', search = '', category_id = '' } = {}) {
const params = { type }
if (search) params.search = search
if (category_id) params.category_id = category_id
const { data } = await get(buildRestPath('product/drawer'), params)
return {
brand: (data.brand || []).map(item => ({
id: item.id,
name: item.name,
choice: false
})),
attribute: (data.attribute || []).map(item => ({
name: item.name,
value: (item.value || []).map(vo => ({
name: vo.name,
choice: false
})),
fold: false
})),
price: { low: '', high: '' }
}
}
/**
* 商城初始化数据(分类+搜索热词+首页模块)
* 对接 88live 的 /wanlshop/common/init 接口
* 原始调用在 88live/store/modules/common.js 第108行
*/
export async function pullMallInit() {
const { data } = await get(buildRestPath('common/init'))
return {
categoryModules: (data.modulesData?.categoryModules || []).map(item => ({
id: item.id,
name: item.name,
image: buildOssUrl(item.image),
childlist: (item.childlist || []).map(child => ({
id: child.id,
name: child.name,
image: buildOssUrl(child.image)
}))
})),
searchModules: data.modulesData?.searchModules || [],
homeModules: data.modulesData?.homeModules || {}
}
}
/**
* 分类商品列表(含秒杀/拼团/商品)
* 对接 88live 的 /wanlshop/common/category 接口
* 原始调用在 88live/components/wanl-shop/category.vue 第117行
*/
export async function pullMallCategoryGoods({ id, page = 1 } = {}) {
const { data } = await get(buildRestPath('common/category'), { id, page })
const goods = data.goods || {}
return {
goods: (Array.isArray(goods.data) ? goods.data : []).map(item => {
if (!item || item.id == null) return null
return {
id: item.id,
title: item.title || '',
image: buildOssUrl(item.image),
price: item.price || '0.00',
market_price: item.market_price || '',
sales: Number(item.sales || 0),
shop_id: item.shop_id,
shop: item.shop || null,
comment: Number(item.comment || 0),
praise: Number(item.praise || 0),
isLive: item.isLive || false,
raw: item
}
}).filter(Boolean),
currentPage: Number(goods.current_page || page),
lastPage: Number(goods.last_page || 1),
total: Number(goods.total || 0),
seckill: data.seckill || [],
groups: data.groups || []
}
}
/**
* 商品详情
* 对接 88live 的 /wanlshop/product/goods 接口
* 原始调用在 88live/pages/product/goods.vue 第734行
*/
export async function pullMallGoodsDetail({ id } = {}) {
const { data } = await get(buildRestPath('product/goods'), { id })
if (typeof data.images === 'string') {
data.images = data.images.split(',').filter(Boolean).map(img => buildOssUrl(img))
} else if (Array.isArray(data.images)) {
data.images = data.images.map(img => buildOssUrl(img))
}
if (!Array.isArray(data.images) || data.images.length === 0) {
data.images = data.image ? [buildOssUrl(data.image)] : []
}
data.image = buildOssUrl(data.image)
if (data.content) {
data.content = data.content.replace(
/
]*src=['"]([^'"]+)[^>]*>/gi,
(match, capture) => `
`
)
}
if (data.sku && data.sku.length > 0) {
data.sku.forEach(item => {
if (item.thumbnail) item.thumbnail = buildOssUrl(item.thumbnail)
})
const prices = data.sku.map(s => Number(s.price))
const marketPrices = data.sku.map(s => Number(s.market_price))
const minP = Math.min(...prices)
const maxP = Math.max(...prices)
data.interval_price = minP === maxP ? minP.toFixed(2) : `${minP}-${maxP.toFixed(2)}`
data.market_price = Math.max(...marketPrices).toFixed(2)
} else {
data.interval_price = data.price
}
if (data.shop) {
if (data.shop.avatar) data.shop.avatar = buildOssUrl(data.shop.avatar)
}
if (data.shop_recommend && Array.isArray(data.shop_recommend)) {
data.shop_recommend.forEach(item => {
if (item.image) item.image = buildOssUrl(item.image)
})
}
if (data.comment_list) {
if (Array.isArray(data.comment_list.data)) {
data.comment_list.data.forEach(item => {
if (item.user && item.user.avatar) item.user.avatar = buildOssUrl(item.user.avatar)
if (Array.isArray(item.images)) {
item.images = item.images.map(img => buildOssUrl(img))
}
})
}
}
return data
}
/**
* 商品SKU库存查询
* 对接 88live 的 /wanlshop/product/stock 接口
* 原始调用在 88live/pages/product/goods.vue 第811行
*/
export async function pullMallGoodsStock({ sku_id } = {}) {
const { data } = await get(buildRestPath('product/stock'), { sku_id })
return data
}
/**
* 商品收藏/取消收藏
* 对接 88live 的 /wanlshop/product/follow 接口
* 原始调用在 88live/pages/product/goods.vue 第960行
*/
export async function pullMallGoodsFollow({ id } = {}) {
const { data } = await post(buildRestPath('product/follow'), { id })
return data
}
/**
* 热门搜索列表
* 对接 88live 的 /wanlshop/common/searchList 接口
* 原始调用在 88live/pages/page/search.vue 第141行
*/
export async function pullMallSearchList() {
const { data } = await get(buildRestPath('common/searchList'))
return data || []
}
/**
* 实时搜索(关键词建议+分类匹配)
* 对接 88live 的 /wanlshop/common/search 接口
* 原始调用在 88live/pages/page/search.vue 第149行
*/
export async function pullMallSearch({ search = '' } = {}) {
const { data } = await get(buildRestPath('common/search'), { search })
return {
searchList: data.searchList || [],
categoryList: data.categoryList || []
}
}
/**
* 保存搜索关键词
* 对接 88live 的 /wanlshop/common/setSearch 接口
* 原始调用在 88live/pages/page/search.vue 第157行
*/
export async function pullMallSetSearch({ keywords = '' } = {}) {
await get(buildRestPath('common/setSearch'), { keywords })
}
/**
* 猜你喜欢(首页推荐商品列表,分页)
* 对接 88live 的 /wanlshop/product/likes 接口
* 原始调用在 88live/components/wanl-page-likes/wanl-page-likes.vue
* 用于首页 homeModules 中 type=likes 的模块
*/
export async function pullMallLikes({ page = 1 } = {}) {
const { data } = await get(buildRestPath('product/likes'), { page })
return {
rows: (Array.isArray(data.data) ? data.data : []).map(item => {
if (!item || item.id == null) return null
return {
id: item.id,
title: item.title || item.name || '',
image: buildOssUrl(item.image),
price: item.price || '0.00',
market_price: item.market_price || '',
sales: Number(item.sales || 0),
shop_id: item.shop_id,
shop: item.shop || null,
comment: Number(item.comment || 0),
praise: Number(item.praise || 0),
isLive: item.isLive || false,
raw: item
}
}).filter(Boolean),
currentPage: data.current_page || 1,
lastPage: data.last_page || 1
}
}
/**
* 首页指定商品列表(根据商品ID批量查询)
* 对接 88live 的 /wanlshop/page/goods 接口
* 原始调用在 88live/components/wanl-page-goods/wanl-page-goods.vue
* 用于首页 homeModules 中 type=goods 的模块
* ids 参数为逗号分隔的商品ID字符串
*/
export async function pullMallPageGoods({ ids = '' } = {}) {
const { data } = await get(buildRestPath('page/goods'), { ids })
return Array.isArray(data) ? data.map(item => {
if (!item || item.id == null) return null
return {
id: item.id,
title: item.title || item.name || '',
image: buildOssUrl(item.image),
price: item.price || '0.00',
market_price: item.market_price || '',
sales: Number(item.sales || 0),
shop_id: item.shop_id,
shop: item.shop || null,
comment: Number(item.comment || 0),
praise: Number(item.praise || 0),
isLive: item.isLive || false,
raw: item
}
}).filter(Boolean) : []
}
/**
* 优惠券查询(根据商品和价格查询可用优惠券)
* 对接 88live 的 /wanlshop/coupon/query 接口
* 原始调用在 88live/pages/product/goods.vue 第830行
* 当SKU价格变化时重新查询
*/
export async function pullMallCouponQuery({ shop_id, goods_id, shop_category_id, price } = {}) {
const { data } = await post(buildRestPath('coupon/query'), { shop_id, goods_id, shop_category_id, price })
return data || []
}
/**
* 领取优惠券
* 对接 88live 的 /wanlshop/coupon/receive 接口
* 原始调用在 88live/pages/product/goods.vue 第844行
*/
export async function pullMallCouponReceive({ id } = {}) {
const { data } = await post(buildRestPath('coupon/receive'), { id })
return data
}
/**
* 详情页猜你喜欢(带pages=goods参数)
* 对接 88live 的 /wanlshop/product/likes?pages=goods 接口
* 原始调用在 88live/pages/product/goods.vue 第822行
* 和首页猜你喜欢是同一个接口,但多了pages参数
*/
export async function pullMallGoodsLikes({ page = 1 } = {}) {
const { data } = await get(buildRestPath('product/likes'), { pages: 'goods', page })
return {
rows: (Array.isArray(data.data) ? data.data : []).map(item => {
if (!item || item.id == null) return null
return {
id: item.id,
title: item.title || item.name || '',
image: buildOssUrl(item.image),
price: item.price || '0.00',
market_price: item.market_price || '',
sales: Number(item.sales || 0),
shop_id: item.shop_id,
shop: item.shop || null,
comment: Number(item.comment || 0),
praise: Number(item.praise || 0),
isLive: item.isLive || false,
raw: item
}
}).filter(Boolean),
currentPage: data.current_page || 1,
lastPage: data.last_page || 1
}
}
/**
* 商品评论列表
* 对接 88live 的 /wanlshop/product/comment 接口
*/
export async function pullMallProductComment({ id, page = 1, tag = '' } = {}) {
const { data } = await get(buildRestPath('product/comment'), { id, page, tag })
const commentData = data.comment || {}
const statistics = data.statistics || { rate: 0, good: 0, pertinent: 0, poor: 0, figure: 0, total: 0 }
if (Array.isArray(commentData.data)) {
commentData.data.forEach(item => {
if (item.user && item.user.avatar) {
item.user.avatar = buildOssUrl(item.user.avatar)
}
if (Array.isArray(item.images)) {
item.images = item.images.map(img => buildOssUrl(img))
}
})
}
return {
list: Array.isArray(commentData.data) ? commentData.data : [],
total: commentData.total || 0,
currentPage: commentData.current_page || 1,
lastPage: commentData.last_page || 1,
statistics
}
}
/**
* 我的评论列表
* 对接 88live 的 /wanlshop/user/comment 接口
*/
export async function pullMyComments({ page = 1 } = {}) {
const { data } = await get('/wanlshop/user/comment', { page })
const resData = data || {}
const list = Array.isArray(resData.data) ? resData.data : []
return {
list,
currentPage: resData.current_page || 1,
lastPage: resData.last_page || 1,
total: resData.total || 0
}
}