【功能完善】商品列表,展示满减送、限时折扣的信息

This commit is contained in:
YunaiV
2024-09-16 09:16:16 +08:00
parent f03fcf1373
commit b741a1d148
3 changed files with 163 additions and 51 deletions
+18 -16
View File
@@ -118,7 +118,7 @@
</template> </template>
<script setup> <script setup>
import { reactive,ref } from 'vue'; import { reactive, ref } from 'vue';
import { onLoad, onReachBottom } from '@dcloudio/uni-app'; import { onLoad, onReachBottom } from '@dcloudio/uni-app';
import sheep from '@/sheep'; import sheep from '@/sheep';
import _ from 'lodash-es'; import _ from 'lodash-es';
@@ -278,13 +278,13 @@
return; return;
} }
// 使用 map 提取每个对象的 id 属性 // 使用 map 提取每个对象的 id 属性
const ids = data.list.map(item => item.id); const ids = data.list.map((item) => item.id);
// 使用 join 方法将 id 数组连接成一个用逗号分隔的字符串 // 使用 join 方法将 id 数组连接成一个用逗号分隔的字符串
const idsString = ids.join(','); const idsString = ids.join(',');
// 获取结算信息 // 获取结算信息
settleData.value = await getSettlementByIds(idsString) settleData.value = await getSettlementByIds(idsString);
// 处理获得的数据 // 处理获得的数据
const ms = enrichDataWithSkus(data.list,settleData.value) const ms = enrichDataWithSkus(data.list, settleData.value);
state.pagination.list = _.concat(state.pagination.list, ms); state.pagination.list = _.concat(state.pagination.list, ms);
state.pagination.total = data.total; state.pagination.total = data.total;
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore'; state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
@@ -301,7 +301,7 @@
} }
//获取结算信息 //获取结算信息
const settleData = ref() const settleData = ref();
async function getSettlementByIds(ids) { async function getSettlementByIds(ids) {
const { data } = await SpuApi.getSettlementProduct(ids); const { data } = await SpuApi.getSettlementProduct(ids);
return data; return data;
@@ -310,10 +310,10 @@
//计算展示价格的函数 //计算展示价格的函数
function enrichDataWithSkus(data, array) { function enrichDataWithSkus(data, array) {
// 创建一个映射,以 id 为键,存储 data 数组中的对象 // 创建一个映射,以 id 为键,存储 data 数组中的对象
const dataMap = new Map(data.map(item => [item.id, { ...item }])); const dataMap = new Map(data.map((item) => [item.id, { ...item }]));
// 遍历 array 数组 // 遍历 array 数组
array.forEach(item => { array.forEach((item) => {
// 初始化 discountPrice 和 vipPrice 为 null // 初始化 discountPrice 和 vipPrice 为 null
let discountPrice = null; let discountPrice = null;
let vipPrice = null; let vipPrice = null;
@@ -321,13 +321,14 @@
let foundType6 = false; let foundType6 = false;
// 遍历 skus 数组,寻找 type 为 4 和 6 的首个条目 // 遍历 skus 数组,寻找 type 为 4 和 6 的首个条目
item.skus.forEach(sku => { item.skus.forEach((sku) => {
if (!foundType4 && sku.type === 4) { debugger;
discountPrice = sku.price; if (!foundType4 && sku.promotionType === 4) {
discountPrice = sku.payPrice;
foundType4 = true; foundType4 = true;
} }
if (!foundType6 && sku.type === 6) { if (!foundType6 && sku.promotionType === 6) {
vipPrice = sku.price; vipPrice = sku.payPrice;
foundType6 = true; foundType6 = true;
} }
@@ -338,10 +339,11 @@
}); });
// 更新 dataMap 中对应的对象 // 更新 dataMap 中对应的对象
if (dataMap.has(item.id)) { if (dataMap.has(item.spuId)) {
dataMap.get(item.id).discountPrice = discountPrice; debugger;
dataMap.get(item.id).vipPrice = vipPrice; dataMap.get(item.spuId).discountPrice = discountPrice;
dataMap.get(item.id).reward = item.reward; dataMap.get(item.spuId).vipPrice = vipPrice;
dataMap.get(item.spuId).reward = item.rewardActivity;
} }
}); });
+3 -3
View File
@@ -14,11 +14,11 @@ const SpuApi = {
}); });
}, },
// 获得商品结算信息 // 获得商品结算信息
getSettlementProduct: (ids) => { getSettlementProduct: (spuIds) => {
return request({ return request({
url: '/trade/order/settlementProduct', url: '/trade/order/settlement-product',
method: 'GET', method: 'GET',
params: { ids }, params: { spuIds },
custom: { custom: {
showLoading: false, showLoading: false,
showError: false, showError: false,
@@ -27,13 +27,23 @@
> >
{{ data.title || data.name }} {{ data.title || data.name }}
</view> </view>
<!-- 这里是新加的会员价和限时优惠 -->
<view class="iconBox" v-if="data.discountPrice || data.vipPrice || data.reward">
<view class="card" v-if="iconShow">{{ iconShow }}</view>
<view class="card2" v-if="data.reward">{{ data.reward.ruleDescriptions[0] }}</view>
</view>
<!-- 这里是新加的会员价和限时优惠结束 -->
<view <view
v-if="goodsFields.price?.show" v-if="goodsFields.price?.show"
class="xs-goods-price font-OPPOSANS" class="xs-goods-price font-OPPOSANS"
:style="[{ color: goodsFields.price.color }]" :style="[{ color: goodsFields.price.color }]"
> >
<text class="price-unit ss-font-24">{{ priceUnit }}</text> <text class="price-unit ss-font-24">{{ priceUnit }}</text>
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }} <text v-if="iconShow == '限时优惠'">{{ fen2yuan(data.discountPrice) }}</text>
<text v-else-if="iconShow == '会员价'">{{ fen2yuan(data.vipPrice) }}</text>
<text v-else>{{
isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price)
}}</text>
</view> </view>
</view> </view>
</view> </view>
@@ -60,13 +70,23 @@
> >
{{ data.title || data.name }} {{ data.title || data.name }}
</view> </view>
<!-- 这里是新加的会员价和限时优惠 -->
<view class="iconBox" v-if="data.discountPrice || data.vipPrice || data.reward">
<view class="card" v-if="iconShow">{{ iconShow }}</view>
<view class="card2" v-if="data.reward">{{ data.reward.ruleDescriptions[0] }}</view>
</view>
<!-- 这里是新加的会员价和限时优惠结束 -->
<view <view
v-if="goodsFields.price?.show" v-if="goodsFields.price?.show"
class="sm-goods-price font-OPPOSANS" class="sm-goods-price font-OPPOSANS"
:style="[{ color: goodsFields.price.color }]" :style="[{ color: goodsFields.price.color }]"
> >
<text class="price-unit ss-font-24">{{ priceUnit }}</text> <text class="price-unit ss-font-24">{{ priceUnit }}</text>
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }} <text v-if="iconShow == '限时优惠'">{{ fen2yuan(data.discountPrice) }}</text>
<text v-else-if="iconShow == '会员价'">{{ fen2yuan(data.vipPrice) }}</text>
<text v-else>{{
isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price)
}}</text>
</view> </view>
</view> </view>
</view> </view>
@@ -110,6 +130,12 @@
</view> </view>
</view> </view>
</slot> </slot>
<!-- 这里是新加的会员价和限时优惠 -->
<view class="iconBox" v-if="data.discountPrice || data.vipPrice || data.reward">
<view class="card" v-if="iconShow">{{ iconShow }}</view>
<view class="card2" v-if="data.reward">{{ data.reward.ruleDescriptions[0] }}</view>
</view>
<!-- 这里是新加的会员价和限时优惠结束 -->
<view class="ss-flex ss-col-bottom"> <view class="ss-flex ss-col-bottom">
<view <view
v-if="goodsFields.price?.show" v-if="goodsFields.price?.show"
@@ -117,7 +143,11 @@
:style="[{ color: goodsFields.price.color }]" :style="[{ color: goodsFields.price.color }]"
> >
<text class="price-unit ss-font-24">{{ priceUnit }}</text> <text class="price-unit ss-font-24">{{ priceUnit }}</text>
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }} <text v-if="iconShow == '限时优惠'">{{ fen2yuan(data.discountPrice) }}</text>
<text v-else-if="iconShow == '会员价'">{{ fen2yuan(data.vipPrice) }}</text>
<text v-else>{{
isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price)
}}</text>
</view> </view>
<view <view
@@ -189,6 +219,12 @@
</view> </view>
</view> </view>
</slot> </slot>
<!-- 这里是新加的会员价和限时优惠 -->
<view class="iconBox" v-if="data.discountPrice || data.vipPrice || data.reward">
<view class="card" v-if="iconShow">{{ iconShow }}</view>
<view class="card2" v-if="data.reward">{{ data.reward.ruleDescriptions[0] }}</view>
</view>
<!-- 这里是新加的会员价和限时优惠结束 -->
<view class="ss-flex ss-col-bottom ss-m-t-10"> <view class="ss-flex ss-col-bottom ss-m-t-10">
<view <view
v-if="goodsFields.price?.show" v-if="goodsFields.price?.show"
@@ -207,7 +243,11 @@
:style="[{ color: originPriceColor }]" :style="[{ color: originPriceColor }]"
> >
<text class="price-unit ss-font-20">{{ priceUnit }}</text> <text class="price-unit ss-font-20">{{ priceUnit }}</text>
<view class="ss-m-l-8">{{ fen2yuan(data.marketPrice) }}</view> <text v-if="iconShow == '限时优惠'">{{ fen2yuan(data.discountPrice) }}</text>
<text v-else-if="iconShow == '会员价'">{{ fen2yuan(data.vipPrice) }}</text>
<text v-else>{{
isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price)
}}</text>
</view> </view>
</view> </view>
<view class="ss-m-t-8 ss-flex ss-col-center ss-flex-wrap"> <view class="ss-m-t-8 ss-flex ss-col-center ss-flex-wrap">
@@ -262,10 +302,20 @@
</view> </view>
</view> </view>
</slot> </slot>
<!-- 这里是新加的会员价和限时优惠 -->
<view class="iconBox" v-if="data.discountPrice || data.vipPrice || data.reward">
<view class="card" v-if="iconShow">{{ iconShow }}</view>
<view class="card2" v-if="data.reward">{{ data.reward.ruleDescriptions[0] }}</view>
</view>
<!-- 这里是新加的会员价和限时优惠结束 -->
<view v-if="goodsFields.price?.show" class="ss-flex ss-col-bottom font-OPPOSANS"> <view v-if="goodsFields.price?.show" class="ss-flex ss-col-bottom font-OPPOSANS">
<view class="sl-goods-price ss-m-r-12" :style="[{ color: goodsFields.price.color }]"> <view class="sl-goods-price ss-m-r-12" :style="[{ color: goodsFields.price.color }]">
<text class="price-unit ss-font-24">{{ priceUnit }}</text> <text class="price-unit ss-font-24">{{ priceUnit }}</text>
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }} <text v-if="iconShow == '限时优惠'">{{ fen2yuan(data.discountPrice) }}</text>
<text v-else-if="iconShow == '会员价'">{{ fen2yuan(data.vipPrice) }}</text>
<text v-else>{{
isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price)
}}</text>
</view> </view>
<view <view
v-if=" v-if="
@@ -297,36 +347,36 @@
* 商品卡片 * 商品卡片
* *
* @property {Array} size = [xs | sm | md | lg | sl ] - 列表数据 * @property {Array} size = [xs | sm | md | lg | sl ] - 列表数据
* @property {String} tag - md及以上才有 * @property {String} tag - md及以上才有
* @property {String} img - 图片 * @property {String} img - 图片
* @property {String} background - 背景色 * @property {String} background - 背景色
* @property {String} topRadius - 上圆角 * @property {String} topRadius - 上圆角
* @property {String} bottomRadius - 下圆角 * @property {String} bottomRadius - 下圆角
* @property {String} title - 标题 * @property {String} title - 标题
* @property {String} titleColor - 标题颜色 * @property {String} titleColor - 标题颜色
* @property {Number} titleWidth = 0 - 标题宽度,默认0,单位rpx * @property {Number} titleWidth = 0 - 标题宽度,默认0,单位rpx
* @property {String} subTitle - 副标题 * @property {String} subTitle - 副标题
* @property {String} subTitleColor - 副标题颜色 * @property {String} subTitleColor - 副标题颜色
* @property {String} subTitleBackground - 副标题背景 * @property {String} subTitleBackground - 副标题背景
* @property {String | Number} price - 价格 * @property {String | Number} price - 价格
* @property {String} priceColor - 价格颜色 * @property {String} priceColor - 价格颜色
* @property {String | Number} originPrice - 原价/划线价 * @property {String | Number} originPrice - 原价/划线价
* @property {String} originPriceColor - 原价颜色 * @property {String} originPriceColor - 原价颜色
* @property {String | Number} sales - 销售数量 * @property {String | Number} sales - 销售数量
* @property {String} salesColor - 销售数量颜色 * @property {String} salesColor - 销售数量颜色
* *
* @slots activity - 活动插槽 * @slots activity - 活动插槽
* @slots cart - 购物车插槽,默认包含文字,背景色,文字颜色 || 图片 || 行为 * @slots cart - 购物车插槽,默认包含文字,背景色,文字颜色 || 图片 || 行为
* *
* @event {Function()} click - 点击卡片 * @event {Function()} click - 点击卡片
* *
*/ */
import { computed, reactive, getCurrentInstance, onMounted, nextTick } from 'vue'; import { computed, reactive, getCurrentInstance, onMounted, nextTick, ref } from 'vue';
import sheep from '@/sheep'; import sheep from '@/sheep';
import { fen2yuan, formatSales } from '@/sheep/hooks/useGoods'; import { fen2yuan, formatSales } from '@/sheep/hooks/useGoods';
import { formatStock } from '@/sheep/hooks/useGoods'; import { formatStock } from '@/sheep/hooks/useGoods';
import goodsCollectVue from '@/pages/user/goods-collect.vue';
import { isArray } from 'lodash-es'; import { isArray } from 'lodash-es';
// 数据 // 数据
const state = reactive({}); const state = reactive({});
@@ -337,17 +387,29 @@
default() { default() {
return { return {
// 商品价格 // 商品价格
price: { show: true }, price: {
show: true,
},
// 库存 // 库存
stock: { show: true }, stock: {
show: true,
},
// 商品名称 // 商品名称
name: { show: true }, name: {
show: true,
},
// 商品介绍 // 商品介绍
introduction: { show: true }, introduction: {
show: true,
},
// 市场价 // 市场价
marketPrice: { show: true }, marketPrice: {
show: true,
},
// 销量 // 销量
salesCount: { show: true }, salesCount: {
show: true,
},
}; };
}, },
}, },
@@ -416,7 +478,26 @@
default: false, default: false,
}, },
}); });
//判断限时优惠和会员价标签内容暂时导致页面出错,又舍不得丢,等着把新的数据整合到商品信息中,也用起来
const iconShow = handle();
function handle() {
debugger;
if (props.data.discountPrice === null && props.data.vipPrice === null) {
// 如果两个值都为 null,则不展示任何内容
return '';
} else if (props.data.discountPrice === null) {
// 如果 discountPrice 为 null,展示 vipPrice
return '会员价';
} else if (props.data.vipPrice === null) {
// 如果 vipPrice 为 null,展示 discountPrice
return '限时优惠';
} else if (props.data.discountPrice < props.data.vipPrice) {
return '限时优惠';
} else if (props.data.discountPrice > props.data.vipPrice) {
return '会员价';
}
}
// 组件样式 // 组件样式
const elStyles = computed(() => { const elStyles = computed(() => {
return { return {
@@ -454,7 +535,10 @@
function getGoodsPriceCardWH() { function getGoodsPriceCardWH() {
if (props.size === 'md') { if (props.size === 'md') {
const view = uni.createSelectorQuery().in(proxy); const view = uni.createSelectorQuery().in(proxy);
view.select(`#${elId}`).fields({ size: true, scrollOffset: true }); view.select(`#${elId}`).fields({
size: true,
scrollOffset: true,
});
view.exec((data) => { view.exec((data) => {
let totalHeight = 0; let totalHeight = 0;
const goodsPriceCard = data[0]; const goodsPriceCard = data[0];
@@ -469,7 +553,6 @@
}); });
} }
} }
onMounted(() => { onMounted(() => {
nextTick(() => { nextTick(() => {
getGoodsPriceCardWH(); getGoodsPriceCardWH();
@@ -763,4 +846,31 @@
color: #ffffff; color: #ffffff;
} }
} }
.card {
width: fit-content;
height: fit-content;
padding: 2rpx 10rpx;
background-color: red;
color: #ffffff;
font-size: 24rpx;
}
.card2 {
width: fit-content;
height: fit-content;
padding: 2rpx 10rpx;
background-color: rgb(255, 242, 241);
color: #ff2621;
font-size: 24rpx;
margin-left: 5rpx;
}
.iconBox {
width: 100%;
height: fit-content;
margin-top: 10rpx;
display: flex;
justify-content: flex-start;
}
</style> </style>