feat 添加商品接口对接

This commit is contained in:
lwh 2023-07-14 15:35:04 +08:00
parent 03367933d0
commit 2583b21c3f
12 changed files with 308 additions and 121 deletions

View File

@ -6,13 +6,14 @@
>
<view class="goods-card__main">
<view class="goods-card__thumb" bind:tap="clickThumbHandle">
<t-image
<!-- <t-image
wx:if="{{ !!goods.thumb }}"
t-class="goods-card__img"
src="{{ goods.thumb }}"
mode="aspectFill"
lazy-load
/>
/> -->
<image class="goods-card__img" src="{{goods.thumb}}" mode="aspectFill" />
</view>
<view class="goods-card__body">
<view class="goods-card__upper">
@ -34,6 +35,7 @@
<view class="goods-card__down">
<price
wx:if="{{ goods.price }}"
priceUnit="yuan"
wr-class="spec-for-price"
symbol-class="spec-for-symbol"
symbol="{{currency}}"
@ -41,6 +43,7 @@
/>
<price
wx:if="{{ goods.originPrice && isValidityLinePrice }}"
priceUnit="yuan"
wr-class="goods-card__origin-price"
symbol="{{currency}}"
price="{{goods.originPrice}}"

View File

@ -99,7 +99,7 @@
justify-content: flex-start;
align-items: baseline;
line-height: 32rpx;
margin: 8rpx 0 0 0;
margin: 28rpx 0 0 0;
}
.goods-card__origin-price {

View File

@ -50,7 +50,7 @@ export function getSearchPopular() {
export function getSearchResult() {
return {
saasId: null,
storeId: null,
storeId: null,
pageNum: 1,
pageSize: 30,
totalCount: 1,

View File

@ -33,6 +33,10 @@ Component({
type: Number,
value: 1,
},
quantity: {
type: Number,
value: 0,
},
skuList: {
type: Array,
value: [],

View File

@ -4,15 +4,17 @@
<t-icon name="close" size="36rpx" />
</view>
<view class="popup-sku-header">
<t-image t-class="popup-sku-header__img" src="{{src}}" />
<!-- <t-image t-class="popup-sku-header__img" src="{{src}}" /> -->
<image class="popup-sku-header__img" src="{{src}}" mode="aspectFill"/>
<view class="popup-sku-header__goods-info">
<view class="popup-sku__goods-name">{{title}}</view>
<view class="goods-price-container">
<slot name="goods-price" />
</view>
<view class="goods-inventory">库存 {{ limitMaxCount != 0 ? limitMaxCount : quantity }} 件</view>
<!-- 已选规格 -->
<view class="popup-sku__selected-spec">
<view>选择:</view>
<view wx:if="{{specList.length != 0}}">选择:</view>
<view wx:for="{{specList}}" wx:key="specId">
<view
class="popup-sku__selected-item"
@ -56,7 +58,7 @@
购买数量
<view class="limit-text" wx:if="{{limitBuyInfo}}"> ({{limitBuyInfo}}) </view>
</view>
<t-stepper value="{{buyNum}}" min="{{1}}" max="{{2}}" theme="filled" bind:change="handleBuyNumChange" />
<t-stepper value="{{buyNum}}" min="{{1}}" max="{{limitMaxCount}}" theme="filled" bind:change="handleBuyNumChange" />
</view>
</view>
</view>

View File

@ -49,6 +49,7 @@
color: #333333;
font-size: 26rpx;
line-height: 36rpx;
flex-wrap: wrap;
}
.popup-sku-header
@ -298,3 +299,7 @@
color: #fff;
background-color: #dddddd;
}
.goods-inventory{
color: grey;
}

View File

@ -1,12 +1,18 @@
import Toast from 'tdesign-miniprogram/toast/index';
import { fetchGood } from '../../../services/good/fetchGood';
import { fetchActivityList } from '../../../services/activity/fetchActivityList';
import {
fetchGood
} from '~/services/good/fetchGood';
import {
fetchActivityList
} from '~/services/activity/fetchActivityList';
import {
getGoodsDetailsCommentList,
getGoodsDetailsCommentsCount,
} from '../../../services/good/fetchGoodsDetailsComments';
} from '~/services/good/fetchGoodsDetailsComments';
import { cdnBase } from '../../../config/index';
import {
cdnBase
} from '~/config/index';
const imgPrefix = `${cdnBase}/`;
@ -37,8 +43,7 @@ Page({
recLeftImg,
recRightImg,
details: {},
goodsTabArray: [
{
goodsTabArray: [{
name: '商品',
value: '', // 空字符串代表置顶
},
@ -49,8 +54,7 @@ Page({
],
storeLogo: `${imgPrefix}common/store-logo.png`,
storeName: '云mall标准版旗舰店',
jumpArray: [
{
jumpArray: [{
title: '首页',
url: '/pages/home/home',
iconName: 'home',
@ -76,13 +80,17 @@ Page({
buyType: 0,
outOperateStatus: false, // 是否外层加入购物车
operateType: 0,
selectSkuQuantity: 0,
selectSkuSellsPrice: 0,
selectSkuLinePrice: 0,
maxLinePrice: 0,
minSalePrice: 0,
maxSalePrice: 0,
list: [],
spuId: '',
navigation: { type: 'fraction' },
navigation: {
type: 'fraction'
},
current: 0,
autoplay: true,
duration: 500,
@ -113,29 +121,42 @@ Page({
},
toNav(e) {
const { url } = e.detail;
const {
url
} = e.detail;
wx.switchTab({
url: url,
});
},
showCurImg(e) {
const { index } = e.detail;
const { images } = this.data.details;
const {
index
} = e.detail;
const {
images
} = this.data.details;
wx.previewImage({
current: images[index],
urls: images, // 需要预览的图片http链接列表
});
},
onPageScroll({ scrollTop }) {
onPageScroll({
scrollTop
}) {
const goodsTab = this.selectComponent('#goodsTab');
goodsTab && goodsTab.onScroll(scrollTop);
},
chooseSpecItem(e) {
const { specList } = this.data.details;
const { selectedSku, isAllSelectedSku } = e.detail;
const {
specList
} = this.data.details;
const {
selectedSku,
isAllSelectedSku
} = e.detail;
if (!isAllSelectedSku) {
this.setData({
selectSkuSellsPrice: 0,
@ -148,7 +169,10 @@ Page({
},
getSkuItem(specList, selectedSku) {
const { skuArray, primaryImage } = this.data;
const {
skuArray,
primaryImage
} = this.data;
const selectedSkuValues = this.getSelectedSkuValues(specList, selectedSku);
let selectedAttrStr = ``;
selectedSkuValues.forEach((item) => {
@ -171,16 +195,19 @@ Page({
if (skuItem) {
this.setData({
selectItem: skuItem,
selectSkuSellsPrice: skuItem.price || 0,
selectSkuSellsPrice: skuItem[0]?.priceInfo[0].price || 0,
selectSkuLinePrice: skuItem[0]?.priceInfo[1].price || 0,
selectSkuQuantity: skuItem[0]?.quantity
});
} else {
this.setData({
selectItem: null,
selectSkuSellsPrice: 0,
selectSkuLinePrice: 0,
});
}
this.setData({
specImg: skuItem && skuItem.skuImage ? skuItem.skuImage : primaryImage,
specImg: skuItem && skuItem[0]?.skuImage ? skuItem[0]?.skuImage : primaryImage,
});
},
@ -221,36 +248,52 @@ Page({
},
addCart() {
const { isAllSelectedSku } = this.data;
Toast({
context: this,
selector: '#t-toast',
message: isAllSelectedSku ? '点击加入购物车' : '请选择规格',
icon: '',
duration: 1000,
});
},
gotoBuy(type) {
const { isAllSelectedSku, buyNum } = this.data;
if (!isAllSelectedSku) {
const {
isAllSelectedSku
} = this.data;
const {
specList
} = this.data.details;
if (specList.length != 0) {
Toast({
context: this,
selector: '#t-toast',
message: '请选择规格',
message: isAllSelectedSku ? '点击加入购物车' : '请选择规格',
icon: '',
duration: 1000,
});
return;
}
},
gotoBuy(type) {
console.log(type);
const {
isAllSelectedSku,
buyNum
} = this.data;
const {
specList
} = this.data.details;
if (specList.length != 0) {
if (!isAllSelectedSku) {
Toast({
context: this,
selector: '#t-toast',
message: '请选择规格',
icon: '',
duration: 1000,
});
return;
}
}
this.handlePopupHide();
const query = {
quantity: buyNum,
storeId: '1',
spuId: this.data.spuId,
goodsName: this.data.details.title,
skuId:
type === 1 ? this.data.skuList[0].skuId : this.data.selectItem.skuId,
skuId: type === 1 ? null : this.data.selectItem.skuId,
available: this.data.details.available,
price: this.data.details.minSalePrice,
specInfo: this.data.details.specList?.map((item) => ({
@ -273,8 +316,17 @@ Page({
},
specsConfirm() {
const { buyType } = this.data;
const {
buyType
} = this.data;
const {
specList
} = this.data.details;
if (buyType === 1) {
if (specList.length == 0) {
this.gotoBuy(1);
return;
}
this.gotoBuy();
} else {
this.addCart();
@ -295,7 +347,9 @@ Page({
},
promotionChange(e) {
const { index } = e.detail;
const {
index
} = e.detail;
wx.navigateTo({
url: `/pages/promotion-detail/index?promotion_id=${index}`,
});
@ -320,11 +374,16 @@ Page({
maxLinePrice,
soldNum,
} = details;
// details.desc = details.desc.replace(/\<img/gi, '<img style="width:100%;height:auto" ');
skuList.forEach((item) => {
skuArray.push({
skuId: item.skuId,
quantity: item.stockInfo ? item.stockInfo.stockQuantity : 0,
quantity: item.quantity ? item.quantity : 0,
specInfo: item.specInfo,
priceInfo: item.priceInfo,
skuImage: item.skuImage,
});
});
const promotionArray = [];
@ -354,7 +413,9 @@ Page({
try {
const code = 'Success';
const data = await getGoodsDetailsCommentList();
const { homePageComments } = data;
const {
homePageComments
} = data;
if (code.toUpperCase() === 'SUCCESS') {
const nextState = {
commentsList: homePageComments.map((item) => {
@ -363,9 +424,8 @@ Page({
userName: item.userName || '',
commentScore: item.commentScore,
commentContent: item.commentContent || '用户未填写评价',
userHeadUrl: item.isAnonymity
? this.anonymityAvatar
: item.userHeadUrl || this.anonymityAvatar,
userHeadUrl: item.isAnonymity ?
this.anonymityAvatar : item.userHeadUrl || this.anonymityAvatar,
};
}),
};
@ -378,7 +438,9 @@ Page({
onShareAppMessage() {
// 自定义的返回信息
const { selectedAttrStr } = this.data;
const {
selectedAttrStr
} = this.data;
let shareSubTitle = '';
if (selectedAttrStr.indexOf('件') > -1) {
const count = selectedAttrStr.indexOf('件');
@ -432,7 +494,11 @@ Page({
},
onLoad(query) {
const { spuId } = query;
const {
spuId
} = query;
// const spuId = "1673671239077597184";
this.setData({
spuId: spuId,
});
@ -440,4 +506,4 @@ Page({
this.getCommentsList(spuId);
this.getCommentsStatistics(spuId);
},
});
});

View File

@ -1,6 +1,7 @@
<view class="goods-detail-page">
<view class="goods-head">
<t-swiper
<!-- <video src="{{videoSrc}}" class="video-container" height="750rpx"></video> -->
<!-- <t-swiper
wx:if="{{details.images.length > 0}}"
height="750rpx"
current="{{current}}"
@ -9,7 +10,20 @@
interval="{{interval}}"
navigation="{{navigation}}"
list="{{details.images}}"
></t-swiper>
></t-swiper> -->
<view>
<swiper class="swiper-container" autoplay interval="10000" circular indicator-dots indicator-active-color="#fff">
<!-- 第一个元素是视频 -->
<swiper-item wx:if="{{details.video}}">
<video src="{{details.video}}" autoplay poster="{{details.primaryImage}}" controls style="width: 100%; height: 100%;"></video>
</swiper-item>
<!-- 后续元素是图片 -->
<swiper-item wx:for="{{details.images}}" wx:key="item">
<image src="{{item}}" mode="aspectFill" style="width: 100%; height: 100%;"></image>
</swiper-item>
</swiper>
</view>
<view class="goods-info">
<view class="goods-number">
<view class="goods-price">
@ -17,10 +31,11 @@
wr-class="class-goods-price"
symbol-class="class-goods-symbol"
price="{{minSalePrice}}"
priceUnit="yuan"
type="lighter"
/>
<view class="goods-price-up">起</view>
<price wr-class="class-goods-del" price="{{maxLinePrice}}" type="delthrough" />
<price wr-class="class-goods-del" price="{{maxLinePrice}}" type="delthrough" priceUnit="yuan" />
</view>
<view class="sold-num">已售{{soldNum}}</view>
</view>
@ -92,8 +107,11 @@
<span class="desc-content__title--text">详情介绍</span>
<t-image t-class="img" src="{{recRightImg}}" />
</view>
<view wx:if="{{details.desc.length > 0}}" wx:for="{{details.desc}}" wx:key="index">
<!-- <view wx:if="{{details.desc.length > 0}}" wx:for="{{details.desc}}" wx:key="index">
<t-image t-class="desc-content__img" src="{{item}}" mode="widthFix" />
</view> -->
<view class="desc-content_box">
<rich-text nodes="{{details.desc}}"></rich-text>
</view>
</view>
<view class="goods-bottom-operation">
@ -117,6 +135,8 @@
specList="{{details.specList || []}}"
skuList="{{skuArray}}"
limitBuyInfo="{{details.limitInfo[0].text || ''}}"
limitMaxCount="{{ selectSkuQuantity }}"
quantity="{{ details.spuStockQuantity }}"
bind:closeSpecsPopup="handlePopupHide"
bind:change="chooseSpecItem"
bind:changeNum="changeNum"
@ -131,12 +151,14 @@
<price
wx:if="{{!isAllSelectedSku || (!promotionSubCode && isAllSelectedSku)}}"
price="{{selectSkuSellsPrice ? selectSkuSellsPrice : minSalePrice }}"
priceUnit="yuan"
wr-class="popup-sku__price-num"
symbol-class="popup-sku__price-symbol"
/>
<price
wx:if="{{selectSkuSellsPrice === 0 && minSalePrice !== maxSalePrice && !isAllSelectedSku}}"
price="{{maxSalePrice}}"
wx:if="{{selectSkuLinePrice !== 0}}"
price="{{selectSkuLinePrice ? selectSkuLinePrice : maxLinePrice }}"
priceUnit="yuan"
wr-class="popup-sku__price-del"
type="delthrough"
/>

View File

@ -220,6 +220,16 @@ page {
height: auto;
}
.desc-content_box{
max-width: 100% !important;
}
.desc-content_box img{
width: 100% !important;
max-width: 100% !important;
height: auto;
}
.goods-bottom-operation {
position: fixed;
left: 0;
@ -340,3 +350,13 @@ page {
font-size: 28rpx;
font-weight: 400;
}
.swiper-container{
width: 100%;
height: 750rpx;
}
.swiper-item{
width: 100%;
height: 750rpx;
}

View File

@ -23,7 +23,7 @@ Page({
},
pageNum: 1,
pageSize: 30,
pageSize: 6,
total: 0,
handleFilterChange(e) {
@ -43,10 +43,10 @@ Page({
const { pageNum, pageSize } = this;
const { sorts, overall } = filter;
const params = {
sort: 0, // 0 综合1 价格
// sort: 0, // 0 综合1 价格
pageNum: 1,
pageSize: 30,
keyword: keywords,
pageSize: 6,
// keyword: keywords,
};
if (sorts) {
@ -54,13 +54,13 @@ Page({
params.sortType = sorts === 'desc' ? 1 : 0;
}
if (overall) {
params.sort = 0;
} else {
params.sort = 1;
}
params.minPrice = minVal ? minVal * 100 : 0;
params.maxPrice = maxVal ? maxVal * 100 : undefined;
// if (overall) {
// params.sort = 0;
// } else {
// params.sort = 1;
// }
// params.minPrice = minVal ? minVal * 100 : 0;
// params.maxPrice = maxVal ? maxVal * 100 : undefined;
if (reset) return params;
return {
...params,
@ -82,9 +82,9 @@ Page({
const code = 'Success';
const data = result;
if (code.toUpperCase() === 'SUCCESS') {
const { spuList, totalCount = 0 } = data;
if (totalCount === 0 && reset) {
this.total = totalCount;
const { result, totalNum = 0 } = data;
if (totalNum === 0 && reset) {
this.total = totalNum;
this.setData({
emptyInfo: {
tip: '抱歉,未找到相关商品',
@ -97,10 +97,10 @@ Page({
return;
}
const _goodsList = reset ? spuList : goodsList.concat(spuList);
const _loadMoreStatus = _goodsList.length === totalCount ? 2 : 0;
const _goodsList = reset ? result : goodsList.concat(result);
const _loadMoreStatus = _goodsList.length === totalNum ? 2 : 0;
this.pageNum = params.pageNum || 1;
this.total = totalCount;
this.total = totalNum;
this.setData({
goodsList: _goodsList,
loadMoreStatus: _loadMoreStatus,

View File

@ -1,18 +1,48 @@
import { config } from '../../config/index';
import {
config
} from '../../config/index';
import {
request
} from '../_utils/request';
/** 获取商品详情 */
// function mockFetchGood(ID = 0) {
// const { delay } = require('../_utils/delay');
// const { genGood } = require('../../model/good');
// return delay().then(() => genGood(ID));
// }
/** 获取商品列表 */
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) => {
// resolve('real api');
// });
// }
/** 获取商品列表 */
export function fetchGood(ID = 0) {
if (config.useMock) {
return mockFetchGood(ID);
}
return new Promise((resolve) => {
resolve('real api');
/** 获取商品详情 */
export function fetchGood(ID) {
return new Promise((resolve, reject) => {
request({
url: `GoodsApi/getGoodsDetails`,
data: {SpuId: ID},
method: 'GET',
success: function (res) {
let data = res.data;
// 图片
if (data.images) {
data.primaryImage = data.images.split(',')[0];
data.images = data.images.split(',');
}
if(data.desc){
data.desc = data.desc.replace(/<img([^>]*)style=""([^>]*)>/gi, '<img$1style="max-width:100%;height:auto;"$2>');
}
resolve(data);
},
fail: function (error) {
reject(error);
}
});
});
}
}

View File

@ -1,39 +1,74 @@
/* eslint-disable no-param-reassign */
import { config } from '../../config/index';
import {
request
} from '../_utils/request';
/** 获取商品列表 */
function mockFetchGoodsList(params) {
const { delay } = require('../_utils/delay');
const { getSearchResult } = require('../../model/search');
/** 获取经营类目列表 */
export function fetchGoodsList(params) {
return new Promise((resolve, reject) => {
request({
url: `GoodsApi/getGoodsList`,
data: params,
method: 'GET',
success: function (res) {
let list = res.data;
if (list.result.length) {
list.result.forEach((item) => {
// 图片
if (item.images) {
item.thumb = item.images.split(',')[0];
}
console.log(item.thumb);
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 = [];
// 标签
// if (item.spuTagList) {
// item.tags = item.spuTagList.map((tag) => tag.title);
// } else {
// item.tags = [];
// }
});
}
resolve(list);
},
fail: function (error) {
reject(error);
}
});
}
return delay().then(() => {
return data;
});
}
/** 获取商品列表 */
export function fetchGoodsList(params) {
if (config.useMock) {
return mockFetchGoodsList(params);
}
return new Promise((resolve) => {
resolve('real api');
});
}
// 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) {
// if (config.useMock) {
// return mockFetchGoodsList(params);
// }
// return new Promise((resolve) => {
// resolve('real api');
// });
// }