【功能优化】商城:调整满减送的数据返回

pull/105/MERGE
YunaiV 2024-09-21 14:30:27 +08:00
parent e727974806
commit 3dad154ca0
5 changed files with 1987 additions and 1815 deletions

View File

@ -7,7 +7,7 @@
<view class="type-text ss-flex ss-row-center">满减</view> <view class="type-text ss-flex ss-row-center">满减</view>
<view class="ss-flex-1"> <view class="ss-flex-1">
<view class="tip-content" v-for="item in state.activityInfo.rules" :key="item"> <view class="tip-content" v-for="item in state.activityInfo.rules" :key="item">
{{ item.description[1] }} {{ item.description }}
</view> </view>
</view> </view>
<image class="activity-left-image" src="/static/activity-left.png" /> <image class="activity-left-image" src="/static/activity-left.png" />

View File

@ -7,15 +7,33 @@
<!-- 骨架屏 --> <!-- 骨架屏 -->
<detailSkeleton v-if="state.skeletonLoading" /> <detailSkeleton v-if="state.skeletonLoading" />
<!-- 下架/售罄提醒 --> <!-- 下架/售罄提醒 -->
<s-empty v-else-if="state.goodsInfo === null" text="商品不存在或已下架" icon="/static/soldout-empty.png" showAction <s-empty
actionText="再逛逛" actionUrl="/pages/goods/list" /> v-else-if="state.goodsInfo === null"
text="商品不存在或已下架"
icon="/static/soldout-empty.png"
showAction
actionText="再逛逛"
actionUrl="/pages/goods/list"
/>
<block v-else> <block v-else>
<view class="detail-swiper-selector"> <view class="detail-swiper-selector">
<!-- 商品轮播图 --> <!-- 商品轮播图 -->
<su-swiper class="ss-m-b-14" isPreview :list="formatGoodsSwiper(state.goodsInfo.sliderPicUrls)" <su-swiper
otStyle="tag" imageMode="widthFix" dotCur="bg-mask-40" :seizeHeight="750" /> class="ss-m-b-14"
isPreview
:list="formatGoodsSwiper(state.goodsInfo.sliderPicUrls)"
otStyle="tag"
imageMode="widthFix"
dotCur="bg-mask-40"
:seizeHeight="750"
/>
<!-- 限时折扣/会员价的优惠信息 --> <!-- 限时折扣/会员价的优惠信息 -->
<view class="discount" v-if="state.settlementSku && state.settlementSku.id && state.settlementSku.promotionPrice"> <view
class="discount"
v-if="
state.settlementSku && state.settlementSku.id && state.settlementSku.promotionPrice
"
>
<image class="disImg" :src="sheep.$url.static('/static/img/shop/goods/dis.png')" /> <image class="disImg" :src="sheep.$url.static('/static/img/shop/goods/dis.png')" />
<view class="discountCont"> <view class="discountCont">
<view class="disContT"> <view class="disContT">
@ -42,9 +60,16 @@
</view> </view>
<view class="disContB2" v-if="state.settlementSku.promotionEndTime > 0"> <view class="disContB2" v-if="state.settlementSku.promotionEndTime > 0">
距结束仅剩 距结束仅剩
<countDown :tipText="' '" :bgColor="bgColor" :dayText="':'" :hourText="':'" <countDown
:minuteText="':'" :secondText="' '" :tipText="' '"
:datatime="state.settlementSku.promotionEndTime / 1000" :isDay="false" /> :bgColor="bgColor"
:dayText="':'"
:hourText="':'"
:minuteText="':'"
:secondText="' '"
:datatime="state.settlementSku.promotionEndTime / 1000"
:isDay="false"
/>
</view> </view>
</view> </view>
</view> </view>
@ -52,8 +77,10 @@
<!-- 价格+标题 --> <!-- 价格+标题 -->
<view class="title-card detail-card ss-p-y-30 ss-p-x-20"> <view class="title-card detail-card ss-p-y-30 ss-p-x-20">
<!-- 没有限时折扣/会员价的优惠信息时展示的价格信息 --> <!-- 没有限时折扣/会员价的优惠信息时展示的价格信息 -->
<view class="ss-flex ss-row-between ss-col-center ss-m-b-26" <view
v-if="!(state.settlementSku.promotionPrice)"> class="ss-flex ss-row-between ss-col-center ss-m-b-26"
v-if="!state.settlementSku.promotionPrice"
>
<view class="price-box ss-flex ss-col-bottom"> <view class="price-box ss-flex ss-col-bottom">
<view class="price-text ss-m-r-16"> <view class="price-text ss-m-r-16">
{{ fen2yuan(state.selectedSku.price || state.goodsInfo.price) }} {{ fen2yuan(state.selectedSku.price || state.goodsInfo.price) }}
@ -67,32 +94,41 @@
</view> </view>
</view> </view>
<view class="discounts-box ss-flex ss-row-between ss-m-b-28"> <view class="discounts-box ss-flex ss-row-between ss-m-b-28">
<!-- 查看满减送的描述 --> <!-- 查看优惠劵的描述 -->
<div class="tag-content"> <view
<view class="tag-box ss-flex">
<!-- <view
class="tag ss-m-r-10" class="tag ss-m-r-10"
v-for="coupon in state.couponInfo.slice(0, 1)" v-for="coupon in state.couponInfo.slice(0, 1)"
:key="coupon.id" :key="coupon.id"
@tap="onOpenActivity" @tap="onOpenActivity"
> >
222 []{{ fen2yuanSimple(coupon.usePrice) }}{{
</view> --> coupon.discountType === 1
<view v-if="state.rewardActivity && state.rewardActivity.id > 0" ? '减' + fen2yuanSimple(coupon.discountPrice) + '元'
class="tag ss-m-r-10" @tap="onOpenActivity"> : '打' + formatDiscountPercent(coupon.discountPercent) + '折'
<text v-if="(state.rewardActivity.ruleDescriptions[0])[4]"> </text> }}
{{(state.rewardActivity.ruleDescriptions[0])[1]}}
</view> </view>
<view v-if="state.rewardActivity && state.rewardActivity.id > 0" <!-- 查看满减送的描述 -->
class="tag ss-m-r-10" @tap="onOpenActivity"> <div class="tag-content">
<text v-if="(state.rewardActivity.ruleDescriptions[0])[1]"></text> <view class="tag-box ss-flex">
{{(state.rewardActivity.ruleDescriptions[0])[1]}} <!-- 最多打印 3 所以需要扣除优惠劵已打印的 -->
<view
v-for="item in getRewardActivityRuleItemDescriptions(
state.rewardActivity,
).slice(0, 3 - state.couponInfo.slice(0, 1).length)"
:key="item"
class="tag ss-m-r-10"
@tap="onOpenActivity"
>
<text>{{ item }}</text>
</view> </view>
</view> </view>
</div> </div>
<!-- 领取优惠劵的按钮 --> <!-- 领取优惠劵的按钮 -->
<view class="get-coupon-box ss-flex ss-col-center ss-m-l-20" @tap="onOpenActivity" <view
v-if="state.couponInfo.length"> class="get-coupon-box ss-flex ss-col-center ss-m-l-20"
@tap="onOpenActivity"
v-if="state.couponInfo.length"
>
<view class="discounts-title ss-m-r-8">领券</view> <view class="discounts-title ss-m-r-8">领券</view>
<text class="cicon-forward"></text> <text class="cicon-forward"></text>
</view> </view>
@ -103,30 +139,51 @@
<!-- 功能卡片 --> <!-- 功能卡片 -->
<view class="detail-cell-card detail-card ss-flex-col"> <view class="detail-cell-card detail-card ss-flex-col">
<detail-cell-sku v-model="state.selectedSku.goods_sku_text" :sku="state.selectedSku" <detail-cell-sku
@tap="state.showSelectSku = true" /> v-model="state.selectedSku.goods_sku_text"
:sku="state.selectedSku"
@tap="state.showSelectSku = true"
/>
</view> </view>
<!-- 规格与数量弹框 --> <!-- 规格与数量弹框 -->
<s-select-sku :goodsInfo="state.goodsInfo" :show="state.showSelectSku" @addCart="onAddCart" <s-select-sku
@buy="onBuy" @change="onSkuChange" @close="state.showSelectSku = false" /> :goodsInfo="state.goodsInfo"
:show="state.showSelectSku"
@addCart="onAddCart"
@buy="onBuy"
@change="onSkuChange"
@close="state.showSelectSku = false"
/>
</view> </view>
<!-- 评价 --> <!-- 评价 -->
<detail-comment-card class="detail-comment-selector" :goodsId="state.goodsId" /> <detail-comment-card class="detail-comment-selector" :goodsId="state.goodsId" />
<!-- 详情 --> <!-- 详情 -->
<detail-content-card class="detail-content-selector" :content="state.goodsInfo.description" /> <detail-content-card
class="detail-content-selector"
:content="state.goodsInfo.description"
/>
<!-- 活动跳转拼团/秒杀/砍价活动 --> <!-- 活动跳转拼团/秒杀/砍价活动 -->
<detail-activity-tip v-if="state.activityList.length > 0" :activity-list="state.activityList" /> <detail-activity-tip
v-if="state.activityList.length > 0"
:activity-list="state.activityList"
/>
<!-- 详情 tabbar --> <!-- 详情 tabbar -->
<detail-tabbar v-model="state.goodsInfo"> <detail-tabbar v-model="state.goodsInfo">
<view class="buy-box ss-flex ss-col-center ss-p-r-20" v-if="state.goodsInfo.stock > 0"> <view class="buy-box ss-flex ss-col-center ss-p-r-20" v-if="state.goodsInfo.stock > 0">
<button class="ss-reset-button add-btn ui-Shadow-Main" @tap="state.showSelectSku = true"> <button
class="ss-reset-button add-btn ui-Shadow-Main"
@tap="state.showSelectSku = true"
>
加入购物车 加入购物车
</button> </button>
<button class="ss-reset-button buy-btn ui-Shadow-Main" @tap="state.showSelectSku = true"> <button
class="ss-reset-button buy-btn ui-Shadow-Main"
@tap="state.showSelectSku = true"
>
立即购买 立即购买
</button> </button>
</view> </view>
@ -136,24 +193,20 @@
</detail-tabbar> </detail-tabbar>
<!-- 满减送/限时折扣活动弹窗 --> <!-- 满减送/限时折扣活动弹窗 -->
<s-activity-pop v-model="state" :show="state.showActivityModel" @close="state.showActivityModel = false" <s-activity-pop
@get="onTakeCoupon" /> v-model="state"
:show="state.showActivityModel"
@close="state.showActivityModel = false"
@get="onTakeCoupon"
/>
</block> </block>
</s-layout> </s-layout>
</view> </view>
</template> </template>
<script setup> <script setup>
import { import { reactive, computed, ref, toRaw } from 'vue';
reactive, import { onLoad, onPageScroll } from '@dcloudio/uni-app';
computed,
ref,
toRaw
} from 'vue';
import {
onLoad,
onPageScroll
} from '@dcloudio/uni-app';
import sheep from '@/sheep'; import sheep from '@/sheep';
import CouponApi from '@/sheep/api/promotion/coupon'; import CouponApi from '@/sheep/api/promotion/coupon';
import ActivityApi from '@/sheep/api/promotion/activity'; import ActivityApi from '@/sheep/api/promotion/activity';
@ -162,7 +215,10 @@
import { import {
formatSales, formatSales,
formatGoodsSwiper, formatGoodsSwiper,
fen2yuan fen2yuan,
fen2yuanSimple,
formatDiscountPercent,
getRewardActivityRuleItemDescriptions,
} from '@/sheep/hooks/useGoods'; } from '@/sheep/hooks/useGoods';
import detailNavbar from './components/detail/detail-navbar.vue'; import detailNavbar from './components/detail/detail-navbar.vue';
import detailCellSku from './components/detail/detail-cell-sku.vue'; import detailCellSku from './components/detail/detail-cell-sku.vue';
@ -171,14 +227,13 @@
import detailCommentCard from './components/detail/detail-comment-card.vue'; import detailCommentCard from './components/detail/detail-comment-card.vue';
import detailContentCard from './components/detail/detail-content-card.vue'; import detailContentCard from './components/detail/detail-content-card.vue';
import detailActivityTip from './components/detail/detail-activity-tip.vue'; import detailActivityTip from './components/detail/detail-activity-tip.vue';
import { import { isEmpty } from 'lodash-es';
isEmpty
} from 'lodash-es';
import SpuApi from '@/sheep/api/product/spu'; import SpuApi from '@/sheep/api/product/spu';
onPageScroll(() => {}); onPageScroll(() => {});
import countDown from '@/sheep/components/countDown/index.vue'; import countDown from '@/sheep/components/countDown/index.vue';
import OrderApi from '@/sheep/api/trade/order'; import OrderApi from '@/sheep/api/trade/order';
import activity from '@/sheep/api/promotion/activity';
const bgColor = { const bgColor = {
bgColor: '#E93323', bgColor: '#E93323',
@ -225,11 +280,13 @@
} }
sheep.$router.go('/pages/order/confirm', { sheep.$router.go('/pages/order/confirm', {
data: JSON.stringify({ data: JSON.stringify({
items: [{ items: [
{
skuId: e.id, skuId: e.id,
count: e.goods_num, count: e.goods_num,
categoryId: state.goodsInfo.categoryId, categoryId: state.goodsInfo.categoryId,
}, ], },
],
}), }),
}); });
} }
@ -241,9 +298,7 @@
// //
async function onTakeCoupon(id) { async function onTakeCoupon(id) {
const { const { code } = await CouponApi.takeCoupon(id);
code
} = await CouponApi.takeCoupon(id);
if (code !== 0) { if (code !== 0) {
return; return;
} }
@ -257,7 +312,8 @@
const shareInfo = computed(() => { const shareInfo = computed(() => {
if (isEmpty(state.goodsInfo)) return {}; if (isEmpty(state.goodsInfo)) return {};
return sheep.$platform.share.getShareInfo({ return sheep.$platform.share.getShareInfo(
{
title: state.goodsInfo.name, title: state.goodsInfo.name,
image: sheep.$url.cdn(state.goodsInfo.picUrl), image: sheep.$url.cdn(state.goodsInfo.picUrl),
desc: state.goodsInfo.introduction, desc: state.goodsInfo.introduction,
@ -265,30 +321,26 @@
page: '2', page: '2',
query: state.goodsInfo.id, query: state.goodsInfo.id,
}, },
}, { },
{
type: 'goods', // type: 'goods', //
title: state.goodsInfo.name, // title: state.goodsInfo.name, //
image: sheep.$url.cdn(state.goodsInfo.picUrl), // image: sheep.$url.cdn(state.goodsInfo.picUrl), //
price: fen2yuan(state.goodsInfo.price), // price: fen2yuan(state.goodsInfo.price), //
original_price: fen2yuan(state.goodsInfo.marketPrice), // original_price: fen2yuan(state.goodsInfo.marketPrice), //
}, ); },
);
}); });
async function getCoupon() { async function getCoupon() {
const { const { code, data } = await CouponApi.getCouponTemplateList(state.goodsId, 2, 10);
code,
data
} = await CouponApi.getCouponTemplateList(state.goodsId, 2, 10);
if (code === 0) { if (code === 0) {
state.couponInfo = data; state.couponInfo = data;
} }
} }
async function getSettlementByIds(ids) { async function getSettlementByIds(ids) {
let { let { data, code } = await OrderApi.getSettlementProduct(ids);
data,
code
} = await OrderApi.getSettlementProduct(ids);
if (code !== 0 || data.length !== 1) { if (code !== 0 || data.length !== 1) {
return; return;
} }
@ -315,22 +367,20 @@
if (data.rewardActivity) { if (data.rewardActivity) {
state.rewardActivity = data.rewardActivity; state.rewardActivity = data.rewardActivity;
// //
getActivityTime(state.rewardActivity.id) getActivityTime(state.rewardActivity.id);
} }
} }
// //
async function getActivityTime(id) { async function getActivityTime(id) {
const { const { code, data } = await RewardActivityApi.getRewardActivity(id);
code,
data
} = await RewardActivityApi.getRewardActivity(id);
if (code === 0) { if (code === 0) {
// console.log(' ', data) // console.log(' ', data)
state.rewardActivity.startTime = data.startTime state.rewardActivity.startTime = data.startTime;
state.rewardActivity.endTime = data.endTime state.rewardActivity.endTime = data.endTime;
} }
} }
onLoad((options) => { onLoad((options) => {
// //
if (!options.id) { if (!options.id) {

View File

@ -5,13 +5,25 @@
<view class="title ss-m-t-16 ss-m-l-20 ss-flex">优惠</view> <view class="title ss-m-t-16 ss-m-l-20 ss-flex">优惠</view>
<view v-if="state.rewardActivity && state.rewardActivity.id > 0"> <view v-if="state.rewardActivity && state.rewardActivity.id > 0">
<view class="titleLi">促销</view> <view class="titleLi">促销</view>
<scroll-view class="model-content" scroll-y :scroll-with-animation="false" :enable-back-to-top="true"> <scroll-view
<view class="actBox" v-for="(item, index) in state.handeActivity" :key="index"> class="model-content"
<view class="boxCont ss-flex ss-col-top ss-m-b-40" @tap="onGoodsList(state.rewardActivity)"> scroll-y
:scroll-with-animation="false"
:enable-back-to-top="true"
>
<view
class="actBox"
v-for="(item, index) in getRewardActivityRuleGroupDescriptions(state.rewardActivity)"
:key="index"
>
<view
class="boxCont ss-flex ss-col-top ss-m-b-40"
@tap="onGoodsList(state.rewardActivity)"
>
<view class="model-content-tag ss-flex ss-row-center">{{ item.name }}</view> <view class="model-content-tag ss-flex ss-row-center">{{ item.name }}</view>
<view class="model-content-title"> <view class="model-content-title">
<view class="contBu"> <view class="contBu">
<text v-for="(items,indexs) in item.value" :key="indexs">{{ items }};</text> {{ item.values.join(';') }}
</view> </view>
<view class="ss-m-b-24 cotBu-txt"> <view class="ss-m-b-24 cotBu-txt">
{{ sheep.$helper.timeFormat(state.rewardActivity.startTime, 'yyyy.mm.dd') }} {{ sheep.$helper.timeFormat(state.rewardActivity.startTime, 'yyyy.mm.dd') }}
@ -25,7 +37,13 @@
</scroll-view> </scroll-view>
</view> </view>
<view class="titleLi">可领优惠券</view> <view class="titleLi">可领优惠券</view>
<scroll-view class="model-content" scroll-y :scroll-with-animation="false" :enable-back-to-top="true" v-if="state.couponInfo.length"> <scroll-view
class="model-content"
scroll-y
:scroll-with-animation="false"
:enable-back-to-top="true"
v-if="state.couponInfo.length"
>
<view class="actBox" v-for="item in state.couponInfo" :key="item.id"> <view class="actBox" v-for="item in state.couponInfo" :key="item.id">
<view class="boxCont ss-flex ss-col-top ss-m-b-40"> <view class="boxCont ss-flex ss-col-top ss-m-b-40">
<view class="model-content-tag2"> <view class="model-content-tag2">
@ -50,26 +68,15 @@
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
<view class="nullBox" v-else> <view class="nullBox" v-else> </view>
暂无可领优惠券
</view>
</view> </view>
</su-popup> </su-popup>
</template> </template>
<script setup> <script setup>
import sheep from '@/sheep'; import sheep from '@/sheep';
import { import { getRewardActivityRuleGroupDescriptions } from '@/sheep/hooks/useGoods';
handeleData import { computed, reactive, watch, ref } from 'vue';
} from '@/sheep/hooks/useGoods'; import { fen2yuan } from '@/sheep/hooks/useGoods';
import {
computed,
reactive,
watch,
ref
} from 'vue';
import {
fen2yuan
} from '@/sheep/hooks/useGoods';
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: Object, type: Object,
@ -85,10 +92,7 @@
rewardActivity: computed(() => props.modelValue.rewardActivity), rewardActivity: computed(() => props.modelValue.rewardActivity),
couponInfo: computed(() => props.modelValue.couponInfo), couponInfo: computed(() => props.modelValue.couponInfo),
}); });
// setTimeout(()=>{
// console.log('',state.rewardActivity.ruleDescriptions)
// console.log('',handeleData(props.modelValue.rewardActivity.ruleDescriptions))
// },5000)
// //
const getBuy = (id) => { const getBuy = (id) => {
emits('get', id); emits('get', id);
@ -99,14 +103,6 @@
activityId: e.id, activityId: e.id,
}); });
} }
//
let flag = ref(true)
watch(state, (newValue, oldValue) => {
if (flag.value) {
flag.value = false
state.handeActivity = handeleData(state.rewardActivity.ruleDescriptions)
}
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.model-box { .model-box {

View File

@ -2,29 +2,43 @@
<template> <template>
<view class="ss-goods-wrap"> <view class="ss-goods-wrap">
<!-- xs卡片横向紧凑型一行放两个图片左内容右边 --> <!-- xs卡片横向紧凑型一行放两个图片左内容右边 -->
<view v-if="size === 'xs'" class="xs-goods-card ss-flex ss-col-stretch" :style="[elStyles]" @tap="onClick"> <view
v-if="size === 'xs'"
class="xs-goods-card ss-flex ss-col-stretch"
:style="[elStyles]"
@tap="onClick"
>
<view v-if="tagStyle.show" class="tag-icon-box"> <view v-if="tagStyle.show" class="tag-icon-box">
<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image> <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
</view> </view>
<image class="xs-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFit" /> <image class="xs-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFit" />
<view v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show" <view
class="xs-goods-content ss-flex-col ss-row-around"> v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show"
<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="xs-goods-title ss-line-1" class="xs-goods-content ss-flex-col ss-row-around"
:style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]"> >
<view
v-if="goodsFields.title?.show || goodsFields.name?.show"
class="xs-goods-title ss-line-1"
:style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]"
>
{{ data.title || data.name }} {{ data.title || data.name }}
</view> </view>
<!-- 活动信息 --> <!-- 活动信息 -->
<view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity"> <view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity">
<view class="card" v-if="discountText">{{ discountText }}</view> <view class="card" v-if="discountText">{{ discountText }}</view>
<view class="card2" v-if="data.rewardActivity"> <view
{{ (data.rewardActivity.ruleDescriptions[0])[1] }} class="card2"
</view> v-for="item in getRewardActivityRuleItemDescriptions(data.rewardActivity).slice(0, 1)"
<view class="card2" v-if="data.rewardActivity && (data.rewardActivity.ruleDescriptions[0])[3]"> :key="item"
{{ (data.rewardActivity.ruleDescriptions[0])[3] }} >
{{ item }}
</view> </view>
</view> </view>
<view v-if="goodsFields.price?.show" class="xs-goods-price font-OPPOSANS" <view
:style="[{ color: goodsFields.price.color }]"> v-if="goodsFields.price?.show"
class="xs-goods-price font-OPPOSANS"
:style="[{ color: goodsFields.price.color }]"
>
<text class="price-unit ss-font-24">{{ priceUnit }}</text> <text class="price-unit ss-font-24">{{ priceUnit }}</text>
<!-- 活动价格 --> <!-- 活动价格 -->
<text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text> <text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text>
@ -40,26 +54,39 @@
<view v-if="tagStyle.show" class="tag-icon-box"> <view v-if="tagStyle.show" class="tag-icon-box">
<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image> <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
</view> </view>
<image class="sm-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill"></image> <image
class="sm-img-box"
:src="sheep.$url.cdn(data.image || data.picUrl)"
mode="aspectFill"
></image>
<view v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show" <view
class="sm-goods-content" :style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]"> v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show"
<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="sm-goods-content"
class="sm-goods-title ss-line-1 ss-m-b-16"> :style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]"
>
<view
v-if="goodsFields.title?.show || goodsFields.name?.show"
class="sm-goods-title ss-line-1 ss-m-b-16"
>
{{ data.title || data.name }} {{ data.title || data.name }}
</view> </view>
<!-- 活动信息 --> <!-- 活动信息 -->
<view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity"> <view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity">
<view class="card" v-if="discountText">{{ discountText }}</view> <view class="card" v-if="discountText">{{ discountText }}</view>
<view class="card2" v-if="data.rewardActivity"> <view
{{ (data.rewardActivity.ruleDescriptions[0])[1] }} class="card2"
</view> v-for="item in getRewardActivityRuleItemDescriptions(data.rewardActivity).slice(0, 1)"
<view class="card2" v-if="data.rewardActivity && (data.rewardActivity.ruleDescriptions[0])[3]"> :key="item"
{{ (data.rewardActivity.ruleDescriptions[0])[3] }} >
{{ item }}
</view> </view>
</view> </view>
<view v-if="goodsFields.price?.show" class="sm-goods-price font-OPPOSANS" <view
:style="[{ color: goodsFields.price.color }]"> v-if="goodsFields.price?.show"
class="sm-goods-price font-OPPOSANS"
:style="[{ color: goodsFields.price.color }]"
>
<text class="price-unit ss-font-24">{{ priceUnit }}</text> <text class="price-unit ss-font-24">{{ priceUnit }}</text>
<!-- 活动价格 --> <!-- 活动价格 -->
<text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text> <text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text>
@ -76,19 +103,31 @@
<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)" /> <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)" />
</view> </view>
<image class="md-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="widthFix" /> <image class="md-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="widthFix" />
<view class="md-goods-content ss-flex-col ss-row-around ss-p-b-20 ss-p-t-20 ss-p-x-16" :id="elId"> <view
<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="md-goods-title ss-line-1" class="md-goods-content ss-flex-col ss-row-around ss-p-b-20 ss-p-t-20 ss-p-x-16"
:style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]"> :id="elId"
>
<view
v-if="goodsFields.title?.show || goodsFields.name?.show"
class="md-goods-title ss-line-1"
:style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]"
>
{{ data.title || data.name }} {{ data.title || data.name }}
</view> </view>
<view v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show" <view
v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
class="md-goods-subtitle ss-m-t-16 ss-line-1" class="md-goods-subtitle ss-m-t-16 ss-line-1"
:style="[{ color: subTitleColor, background: subTitleBackground }]"> :style="[{ color: subTitleColor, background: subTitleBackground }]"
>
{{ data.subtitle || data.introduction }} {{ data.subtitle || data.introduction }}
</view> </view>
<slot name="activity"> <slot name="activity">
<view v-if="data.promos?.length" class="tag-box ss-flex-wrap ss-flex ss-col-center"> <view v-if="data.promos?.length" class="tag-box ss-flex-wrap ss-flex ss-col-center">
<view class="activity-tag ss-m-r-10 ss-m-t-16" v-for="item in data.promos" :key="item.id"> <view
class="activity-tag ss-m-r-10 ss-m-t-16"
v-for="item in data.promos"
:key="item.id"
>
{{ item.title }} {{ item.title }}
</view> </view>
</view> </view>
@ -96,16 +135,20 @@
<!-- 活动信息 --> <!-- 活动信息 -->
<view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity"> <view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity">
<view class="card" v-if="discountText">{{ discountText }}</view> <view class="card" v-if="discountText">{{ discountText }}</view>
<view class="card2" v-if="data.rewardActivity"> <view
{{ (data.rewardActivity.ruleDescriptions[0])[1] }} class="card2"
</view> v-for="item in getRewardActivityRuleItemDescriptions(data.rewardActivity).slice(0, 1)"
<view class="card2" v-if="data.rewardActivity && (data.rewardActivity.ruleDescriptions[0])[3]"> :key="item"
{{ (data.rewardActivity.ruleDescriptions[0])[3] }} >
{{ item }}
</view> </view>
</view> </view>
<view class="ss-flex ss-col-bottom"> <view class="ss-flex ss-col-bottom">
<view v-if="goodsFields.price?.show" class="md-goods-price ss-m-t-16 font-OPPOSANS ss-m-r-10" <view
:style="[{ color: goodsFields.price.color }]"> v-if="goodsFields.price?.show"
class="md-goods-price ss-m-t-16 font-OPPOSANS ss-m-r-10"
:style="[{ color: goodsFields.price.color }]"
>
<text class="price-unit ss-font-24">{{ priceUnit }}</text> <text class="price-unit ss-font-24">{{ priceUnit }}</text>
<!-- 活动价格 --> <!-- 活动价格 -->
<text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text> <text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text>
@ -113,10 +156,14 @@
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }} {{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</text> </text>
</view> </view>
<view v-if=" <view
v-if="
(goodsFields.original_price?.show || goodsFields.marketPrice?.show) && (goodsFields.original_price?.show || goodsFields.marketPrice?.show) &&
(data.original_price > 0 || data.marketPrice > 0) (data.original_price > 0 || data.marketPrice > 0)
" class="goods-origin-price ss-m-t-16 font-OPPOSANS ss-flex" :style="[{ color: originPriceColor }]"> "
class="goods-origin-price ss-m-t-16 font-OPPOSANS ss-flex"
: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> <view class="ss-m-l-8">{{ fen2yuan(data.marketPrice) }}</view>
</view> </view>
@ -135,7 +182,12 @@
</view> </view>
<!-- lg卡片横向型一行放一个图片左内容右边 --> <!-- lg卡片横向型一行放一个图片左内容右边 -->
<view v-if="size === 'lg'" class="lg-goods-card ss-flex ss-col-stretch" :style="[elStyles]" @tap="onClick"> <view
v-if="size === 'lg'"
class="lg-goods-card ss-flex ss-col-stretch"
:style="[elStyles]"
@tap="onClick"
>
<view v-if="tagStyle.show" class="tag-icon-box"> <view v-if="tagStyle.show" class="tag-icon-box">
<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image> <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
</view> </view>
@ -143,16 +195,25 @@
<view v-if="grouponTag" class="groupon-tag ss-flex ss-row-center"> <view v-if="grouponTag" class="groupon-tag ss-flex ss-row-center">
<view class="tag-icon">拼团</view> <view class="tag-icon">拼团</view>
</view> </view>
<image class="lg-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill" /> <image
class="lg-img-box"
:src="sheep.$url.cdn(data.image || data.picUrl)"
mode="aspectFill"
/>
<view class="lg-goods-content ss-flex-1 ss-flex-col ss-row-between ss-p-b-10 ss-p-t-20"> <view class="lg-goods-content ss-flex-1 ss-flex-col ss-row-between ss-p-b-10 ss-p-t-20">
<view> <view>
<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="lg-goods-title ss-line-2" <view
:style="[{ color: titleColor }]"> v-if="goodsFields.title?.show || goodsFields.name?.show"
class="lg-goods-title ss-line-2"
:style="[{ color: titleColor }]"
>
{{ data.title || data.name }} {{ data.title || data.name }}
</view> </view>
<view v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show" <view
v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
class="lg-goods-subtitle ss-m-t-10 ss-line-1" class="lg-goods-subtitle ss-m-t-10 ss-line-1"
:style="[{ color: subTitleColor, background: subTitleBackground }]"> :style="[{ color: subTitleColor, background: subTitleBackground }]"
>
{{ data.subtitle || data.introduction }} {{ data.subtitle || data.introduction }}
</view> </view>
</view> </view>
@ -167,24 +228,31 @@
<!-- 活动信息 --> <!-- 活动信息 -->
<view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity"> <view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity">
<view class="card" v-if="discountText">{{ discountText }}</view> <view class="card" v-if="discountText">{{ discountText }}</view>
<view class="card2" v-if="data.rewardActivity"> <view
{{ (data.rewardActivity.ruleDescriptions[0])[1] }} class="card2"
</view> v-for="item in getRewardActivityRuleItemDescriptions(data.rewardActivity).slice(0, 1)"
<view class="card2" v-if="data.rewardActivity && (data.rewardActivity.ruleDescriptions[0])[3]"> :key="item"
{{ (data.rewardActivity.ruleDescriptions[0])[3] }} >
{{ item }}
</view> </view>
</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 v-if="goodsFields.price?.show" <view
v-if="goodsFields.price?.show"
class="lg-goods-price ss-m-r-12 ss-flex ss-col-bottom font-OPPOSANS" class="lg-goods-price ss-m-r-12 ss-flex ss-col-bottom font-OPPOSANS"
:style="[{ color: goodsFields.price.color }]"> :style="[{ color: goodsFields.price.color }]"
>
<text class="ss-font-24">{{ priceUnit }}</text> <text class="ss-font-24">{{ priceUnit }}</text>
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }} {{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</view> </view>
<view v-if=" <view
v-if="
(goodsFields.original_price?.show || goodsFields.marketPrice?.show) && (goodsFields.original_price?.show || goodsFields.marketPrice?.show) &&
(data.original_price > 0 || data.marketPrice > 0) (data.original_price > 0 || data.marketPrice > 0)
" class="goods-origin-price ss-flex ss-col-bottom font-OPPOSANS" :style="[{ color: originPriceColor }]"> "
class="goods-origin-price ss-flex ss-col-bottom font-OPPOSANS"
:style="[{ color: originPriceColor }]"
>
<text class="price-unit ss-font-20">{{ priceUnit }}</text> <text class="price-unit ss-font-20">{{ priceUnit }}</text>
<!-- 活动价格 --> <!-- 活动价格 -->
<text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text> <text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text>
@ -209,23 +277,36 @@
<view v-if="tagStyle.show" class="tag-icon-box"> <view v-if="tagStyle.show" class="tag-icon-box">
<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)" /> <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)" />
</view> </view>
<image class="sl-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill" /> <image
class="sl-img-box"
:src="sheep.$url.cdn(data.image || data.picUrl)"
mode="aspectFill"
/>
<view class="sl-goods-content"> <view class="sl-goods-content">
<view> <view>
<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="sl-goods-title ss-line-1" <view
:style="[{ color: titleColor }]"> v-if="goodsFields.title?.show || goodsFields.name?.show"
class="sl-goods-title ss-line-1"
:style="[{ color: titleColor }]"
>
{{ data.title || data.name }} {{ data.title || data.name }}
</view> </view>
<view v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show" <view
v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
class="sl-goods-subtitle ss-m-t-16" class="sl-goods-subtitle ss-m-t-16"
:style="[{ color: subTitleColor, background: subTitleBackground }]"> :style="[{ color: subTitleColor, background: subTitleBackground }]"
>
{{ data.subtitle || data.introduction }} {{ data.subtitle || data.introduction }}
</view> </view>
</view> </view>
<view> <view>
<slot name="activity"> <slot name="activity">
<view v-if="data.promos?.length" class="tag-box ss-flex ss-col-center ss-flex-wrap"> <view v-if="data.promos?.length" class="tag-box ss-flex ss-col-center ss-flex-wrap">
<view class="activity-tag ss-m-r-10 ss-m-t-16" v-for="item in data.promos" :key="item.id"> <view
class="activity-tag ss-m-r-10 ss-m-t-16"
v-for="item in data.promos"
:key="item.id"
>
{{ item.title }} {{ item.title }}
</view> </view>
</view> </view>
@ -233,11 +314,12 @@
<!-- 活动信息 --> <!-- 活动信息 -->
<view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity"> <view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity">
<view class="card" v-if="discountText">{{ discountText }}</view> <view class="card" v-if="discountText">{{ discountText }}</view>
<view class="card2" v-if="data.rewardActivity"> <view
{{ (data.rewardActivity.ruleDescriptions[0])[1] }} class="card2"
</view> v-for="item in getRewardActivityRuleItemDescriptions(data.rewardActivity).slice(0, 1)"
<view class="card2" v-if="data.rewardActivity && (data.rewardActivity.ruleDescriptions[0])[3]"> :key="item"
{{ (data.rewardActivity.ruleDescriptions[0])[3] }} >
{{ item }}
</view> </view>
</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">
@ -249,10 +331,14 @@
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }} {{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</text> </text>
</view> </view>
<view v-if=" <view
v-if="
(goodsFields.original_price?.show || goodsFields.marketPrice?.show) && (goodsFields.original_price?.show || goodsFields.marketPrice?.show) &&
(data.original_price > 0 || data.marketPrice > 0) (data.original_price > 0 || data.marketPrice > 0)
" class="goods-origin-price ss-m-t-16 font-OPPOSANS ss-flex" :style="[{ color: originPriceColor }]"> "
class="goods-origin-price ss-m-t-16 font-OPPOSANS ss-flex"
: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> <view class="ss-m-l-8">{{ fen2yuan(data.marketPrice) }}</view>
</view> </view>
@ -299,23 +385,15 @@
* @event {Function()} click - 点击卡片 * @event {Function()} click - 点击卡片
* *
*/ */
import { import { computed, getCurrentInstance, onMounted, nextTick } from 'vue';
computed,
getCurrentInstance,
onMounted,
nextTick
} from 'vue';
import sheep from '@/sheep'; import sheep from '@/sheep';
import { import {
fen2yuan, fen2yuan,
formatSales formatSales,
getRewardActivityRuleItemDescriptions,
} from '@/sheep/hooks/useGoods'; } from '@/sheep/hooks/useGoods';
import { import { formatStock } from '@/sheep/hooks/useGoods';
formatStock import { isArray } from 'lodash-es';
} from '@/sheep/hooks/useGoods';
import {
isArray
} from 'lodash-es';
// //
const props = defineProps({ const props = defineProps({
@ -458,9 +536,7 @@
}; };
// //
const { const { proxy } = getCurrentInstance();
proxy
} = getCurrentInstance();
const elId = `sheep_${Math.ceil(Math.random() * 10e5).toString(36)}`; const elId = `sheep_${Math.ceil(Math.random() * 10e5).toString(36)}`;
function getGoodsPriceCardWH() { function getGoodsPriceCardWH() {

View File

@ -1,11 +1,7 @@
import { import { ref } from 'vue';
ref
} from 'vue';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import $url from '@/sheep/url'; import $url from '@/sheep/url';
import { import { formatDate } from '@/sheep/util';
formatDate
} from '@/sheep/util';
/** /**
* 格式化销量 * 格式化销量
@ -343,6 +339,27 @@ export function fen2yuan(price) {
return (price / 100.0).toFixed(2); return (price / 100.0).toFixed(2);
} }
/**
* 将分转成元
*
* 如果没有小数点则不展示小数点部分
*
* @param price 例如说 100
* @returns {string} 例如说 1
*/
export function fen2yuanSimple(price) {
return fen2yuan(price).replace(/\.?0+$/, '');
}
/**
* 将折扣百分比转化为打x者 x 部分
*
* @param discountPercent
*/
export function formatDiscountPercent(discountPercent) {
return (discountPercent / 10.0).toFixed(1).replace(/\.?0+$/, '');
}
/** /**
* 从商品 SKU 数组中转换出商品属性的数组 * 从商品 SKU 数组中转换出商品属性的数组
* *
@ -411,39 +428,72 @@ export function appendSettlementProduct(spus, settlementInfos) {
} }
} }
//处理促销信息 // 获得满减送活动的规则描述group
export function handeleData(array) { export function getRewardActivityRuleGroupDescriptions(activity) {
const array2 = ref([{ if (!activity || !activity.rules || activity.rules.length === 0) {
name: '满减', return [];
value: [] }
}, const result = [
{ { name: '满减', values: [] },
name: '赠品', { name: '赠品', values: [] },
value: [] { name: '包邮', values: [] },
}, ];
{ activity.rules.forEach((rule) => {
name: '包邮', const conditionTypeStr =
value: [] activity.conditionType === 10 ? `${fen2yuanSimple(rule.limit)}` : `${rule.limit}`;
// 满减
if (rule.limit) {
result[0].values.push(`${conditionTypeStr}${fen2yuanSimple(rule.discountPrice)}`);
}
// 赠品
if (rule.point || (rule.giveCouponTemplateCounts && rule.giveCouponTemplateCounts.length > 0)) {
let tips = [];
if (rule.point) {
tips.push(`${rule.point} 积分`);
}
if (rule.giveCouponTemplateCounts && rule.giveCouponTemplateCounts.length > 0) {
tips.push(`${rule.giveCouponTemplateCounts.length} 张优惠券`);
}
result[1].values.push(`${conditionTypeStr} ${tips.join('、')}`);
}
// 包邮
if (rule.freeDelivery) {
result[2].values.push(`${conditionTypeStr} 包邮`);
}
});
// 移除 values 为空的元素
result.forEach((item) => {
if (item.values.length === 0) {
result.splice(result.indexOf(item), 1);
}
});
return result;
} }
]);
array.forEach(item => { // 获得满减送活动的规则描述item
Object.entries(item).forEach(([key, value]) => { export function getRewardActivityRuleItemDescriptions(activity) {
const type = parseInt(key); if (!activity || !activity.rules || activity.rules.length === 0) {
switch (type) { return [];
case 1: }
array2.value[0].value.push(value); // 满减 const result = [];
break; activity.rules.forEach((rule) => {
case 2: const conditionTypeStr =
array2.value[1].value.push(value); // 满送 activity.conditionType === 10 ? `${fen2yuanSimple(rule.limit)}` : `${rule.limit}`;
break; // 满减
case 3: if (rule.limit) {
array2.value[2].value.push(value); // 包邮 result.push(`${conditionTypeStr}${fen2yuanSimple(rule.discountPrice)}`);
break; }
default: // 赠品
break; if (rule.point) {
result.push(`${conditionTypeStr}${rule.point}积分`);
}
if (rule.giveCouponTemplateCounts && rule.giveCouponTemplateCounts.length > 0) {
result.push(`${conditionTypeStr}${rule.giveCouponTemplateCounts.length}张优惠券`);
}
// 包邮
if (rule.freeDelivery) {
result.push(`${conditionTypeStr}包邮`);
} }
}); });
}); return result;
return array2
} }